From 3cda65e41a49d4aabf3b2004ba2839009235d75e Mon Sep 17 00:00:00 2001
From: Florian Sylvestre <fsylvestre@baylibre.com>
Date: Thu, 2 Mar 2023 13:01:42 +0100
Subject: [PATCH 13/27] Add initial iccom porting from Toppers ATK Autosar
 version.

---
 examples/renesas/iccom/build.sh               |  17 ++
 .../iccom/cs_plus_rcar_download_all.py        |  37 +++
 examples/renesas/iccom/goto_reset.py          |   9 +
 examples/renesas/iccom/iccom.c                | 221 ++++++++++++++++++
 examples/renesas/iccom/iccom.h                |  10 +
 examples/renesas/iccom/iccom.oil              |  59 +++++
 examples/renesas/iccom/iccom_commands.h       |  84 +++++++
 examples/renesas/iccom/iccom_ll.c             | 159 +++++++++++++
 examples/renesas/iccom/iccom_ll.h             |  39 ++++
 9 files changed, 635 insertions(+)
 create mode 100644 examples/renesas/iccom/build.sh
 create mode 100644 examples/renesas/iccom/cs_plus_rcar_download_all.py
 create mode 100644 examples/renesas/iccom/goto_reset.py
 create mode 100644 examples/renesas/iccom/iccom.c
 create mode 100644 examples/renesas/iccom/iccom.h
 create mode 100644 examples/renesas/iccom/iccom.oil
 create mode 100644 examples/renesas/iccom/iccom_commands.h
 create mode 100644 examples/renesas/iccom/iccom_ll.c
 create mode 100644 examples/renesas/iccom/iccom_ll.h

diff --git a/examples/renesas/iccom/build.sh b/examples/renesas/iccom/build.sh
new file mode 100644
index 0000000..148095f
--- /dev/null
+++ b/examples/renesas/iccom/build.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+#stop on errors
+set -e
+
+if [[ ! -d "_build" ]]
+then
+    mkdir _build
+fi
+
+echo "*** Run Goil ***"
+goil --target=renesas/g4mh --templates=../../../goil/templates/ iccom.oil
+cd _build
+echo "*** Run CMake ***"
+cmake -G "Unix Makefiles" -D CMAKE_TOOLCHAIN_FILE=../iccom/compiler.cmake ..
+echo "*** Run Make ***"
+make
diff --git a/examples/renesas/iccom/cs_plus_rcar_download_all.py b/examples/renesas/iccom/cs_plus_rcar_download_all.py
new file mode 100644
index 0000000..9de4d4e
--- /dev/null
+++ b/examples/renesas/iccom/cs_plus_rcar_download_all.py
@@ -0,0 +1,37 @@
+﻿
+import time
+ClearConsole()
+print "1PE_ATK2"
+print "Resetting debugger"
+debugger.Reset()
+time.sleep(2)
+print "SYSCTRL 0x0003"
+debugger.Register.SetValue("SYSCTRL.BOOTCTRL", 0x0003)
+time.sleep(2)
+print "CPU Stop"
+debugger.Stop()
+time.sleep(2)
+print "HBG_CS 0x00000003"
+debugger.Register.SetValue("HBG_CS0.HBGPROT0", 0x00000003)
+debugger.Register.SetValue("HBG_CS1.HBGPROT0", 0x00000003)
+debugger.Register.SetValue("HBG_CS2.HBGPROT0", 0x00000003)
+#time.sleep(1)
+print "CSRM 0x12B9B0A0"
+debugger.Register.SetValue("CSRM0.CSRM0CSIFCODE", 0x12B9B0A0)
+debugger.Register.SetValue("CSRM1.CSRM1CSIFCODE", 0x12B9B0A0)
+debugger.Register.SetValue("CSRM2.CSRM2CSIFCODE", 0x12B9B0A0)
+#time.sleep(1)
+print "Download Trampoline/Hello_world"
+debugger.Download.LoadModule("_build/iccom_exe.abs", downloadOption = DownloadOption.SymbolOnly, append = False, flashErase = False, vendorType = VendorType.Auto)
+print "Download Trampoline/Hello_world (RUN)"
+debugger.Download.Hex("_build/iccom_exe.run", offset = 0xF0000000, append = True, flashErase = False)
+print "CSRM 0x12B9B0A1"
+debugger.Register.SetValue("CSRM0.CSRM0CSIFCODE", 0x12B9B0A1)
+debugger.Register.SetValue("CSRM1.CSRM1CSIFCODE", 0x12B9B0A1)
+debugger.Register.SetValue("CSRM2.CSRM2CSIFCODE", 0x12B9B0A1)
+#time.sleep(1)
+print "Set Reset PC"
+debugger.Register.SetValue("PC", 0x200)
+#time.sleep(1)
+print "Starting G4"
+debugger.Go()
diff --git a/examples/renesas/iccom/goto_reset.py b/examples/renesas/iccom/goto_reset.py
new file mode 100644
index 0000000..d8b9137
--- /dev/null
+++ b/examples/renesas/iccom/goto_reset.py
@@ -0,0 +1,9 @@
+﻿import time
+ClearConsole()
+
+debugger.Stop()
+time.sleep(2)
+
+print "Set Reset PC"
+debugger.Register.SetValue("PC", 0x200)
+
diff --git a/examples/renesas/iccom/iccom.c b/examples/renesas/iccom/iccom.c
new file mode 100644
index 0000000..9592b0d
--- /dev/null
+++ b/examples/renesas/iccom/iccom.c
@@ -0,0 +1,221 @@
+#include "tpl_os.h"
+#include "iccom.h"
+#include "iccom_ll.h"
+//#include "qspi_flash_writer.h"
+#include "iccom_commands.h"
+//#include "tpl_app_config.h"
+//#include "tpl_as_counter_kernel.h"
+
+#define APP_Task_iccom_START_SEC_CODE
+#include "tpl_memmap.h"
+
+#include "iccom_commands.h"
+
+extern volatile VAR(uint32, OS_VAR) tpl_time_counter;
+
+//DeclareCounter(Hardware_Counter);
+//DeclareCounter(Software_Counter);
+//DeclareCounter(SystemCounter);
+//DeclareCounter(0);
+
+
+/* ICCOM protocol */
+enum ICCOM_MSG {
+    ICCOM_MSG_INVALID,
+    ICCOM_MSG_INIT,
+    ICCOM_MSG_DATA,
+    ICCOM_MSG_ACK
+};
+
+#define ICCOM_BUF_MAX_SIZE		2048
+#define TIMER_TICK_INTERVAL_NS		(125U)
+#define TIMER_TICKS_PER_MS			(1000000U/TIMER_TICK_INTERVAL_NS)
+#define HOST_INT_CLEAR_TIMEOUT_MS		(500U*TIMER_TICKS_PER_MS)
+
+uint8 iccom_initalized = 0;
+uint8 rx_buffer[ICCOM_BUF_MAX_SIZE];
+uint8 tx_buffer[ICCOM_BUF_MAX_SIZE];
+
+static void iccom_notify_tx_data(size_t message)
+{
+	iccom_set_out_msg_reg((uint32)message);
+	iccom_set_out_ctrl_reg(ICCOM_HW_CONTROL_INIT);
+	iccom_set_out_ctrl_reg(ICCOM_CTRL_DATA | ICCOM_CTRL_BUFF_UPPER | ICCOM_CTRL_INT);
+}
+
+static void iccom_send_rx_data_ack(uint32 message)
+{
+	iccom_set_out_msg_reg(message);
+	iccom_set_out_ctrl_reg(ICCOM_CTRL_ACK | ICCOM_CTRL_BUFF_BOTTOM | ICCOM_CTRL_INT);
+}
+
+static void iccom_send_initialization_ack(void)
+{
+	iccom_set_out_ctrl_reg(ICCOM_CTRL_INIT_COMPLETED | ICCOM_CTRL_INT);
+}
+
+/*
+ * delay comme sur l'arduino
+ */
+//FUNC(void, OS_CODE) delay(CONST(uint32, AUTOMATIC) howMuch)
+//{
+//  CONST(uint32, AUTOMATIC) start = tpl_time_counter;
+//  while (tpl_time_counter - start < howMuch);
+//}
+
+static sint32 iccom_wait_for_out_interrupt_clear(uint32_t timeout_ms)
+{
+	uint32 out_ctrl_reg;
+	TickType start_val, curr_val;
+
+	//JN what is this MAIN_HW_COUNTER?
+	//GetCounterValue(MAIN_HW_COUNTER, &start_val);
+	//GetCounterValue(Hardware_Counter, &start_val);
+	//GetCounterValue(Software_Counter, &start_val);
+	//GetCounterValue(SystemCounter, &start_val);
+	//GetCounterValue(0, &start_val);
+	//GetCounterValue(Software_Counter1, &start_val);
+	start_val = tpl_time_counter;
+	do {
+		iccom_get_out_ctrl_reg(&out_ctrl_reg);
+		//JN
+		//GetCounterValue(MAIN_HW_COUNTER, &curr_val);
+		//GetCounterValue(Hardware_Counter, &curr_val);
+		curr_val = tpl_time_counter;
+		// If the host processor doesn't clear the interrupt before the timeout
+		// then it's likely that the host application stopped/crashed and this
+		// clear will never happen. So we clear it on our side and return an
+		// error
+		if (curr_val - start_val > timeout_ms) {
+			iccom_set_out_ctrl_reg(ICCOM_HW_CONTROL_INIT);
+			return -1;
+		}
+	} while (out_ctrl_reg & ICCOM_CTRL_INT);
+
+	return 0;
+}
+
+static void iccom_send(uint8* data, size_t size)
+{
+	iccom_cta_write(data, size);
+	iccom_notify_tx_data(size);
+}
+
+static void iccom_handle_rx_msg(size_t size)
+{
+	struct command_header* in_pkt;
+	sint32 ret;
+	
+	iccom_cta_read(rx_buffer, size);
+	iccom_send_rx_data_ack((uint32)size);
+	ret = iccom_wait_for_out_interrupt_clear(HOST_INT_CLEAR_TIMEOUT_MS);
+	if (ret < 0) {
+		// In case of timeout then there's no reason to process the answer
+		// further since the host processor will not care about this 
+		goto Exit;
+	}
+
+	// Casting to the most simple structure in order to get the "cmd_id".
+	// Later the proper casting will be done
+	in_pkt = (struct command_header*) rx_buffer;
+	switch (in_pkt->cmd_id) {
+		case READ_FLASH_ID: {
+			//struct read_flash_id_command* cmd_pkt = (struct read_flash_id_command*) rx_buffer;
+			struct simple_reply_uint32 reply_pkt;
+			//uint32 chip_id = flash_read_chip_id();
+			reply_pkt.cmd_id = 0;
+			reply_pkt.ret_val = 0xB0CAD0;
+			iccom_send((uint8*)&reply_pkt, sizeof(struct simple_reply_uint32));
+			break;
+		}
+		//case READ_CHUNK: {
+		//	struct read_chunk_command* cmd_pkt = (struct read_chunk_command*) rx_buffer;
+		//	struct read_chunk_reply* reply_pkt = (struct read_chunk_reply*) tx_buffer;
+		//	reply_pkt->cmd_id = cmd_pkt->cmd_id;
+		//	reply_pkt->ret_val = flash_read_chunk(cmd_pkt->start_address,
+		//								cmd_pkt->size, reply_pkt->data);
+		//	iccom_send((uint8*)reply_pkt, sizeof(struct read_chunk_reply));
+		//	break;
+		//}
+		default:
+			break;
+	}
+Exit:
+	;
+}
+
+static void iccom_handle_ack_received(void)
+{
+	iccom_set_in_ctrl_reg(ICCOM_HW_CONTROL_INIT);
+}
+
+enum ICCOM_MSG iccom_get_msg_type(uint32 control)
+{
+	if (control & ICCOM_CTRL_INIT_COMPLETED)
+		return ICCOM_MSG_INIT;
+	if (control & ICCOM_CTRL_DATA)
+		return ICCOM_MSG_DATA;
+	else
+		return ICCOM_MSG_ACK;
+}
+
+void iccom_init(void)
+{
+	/* Initialize the HW first*/
+	iccom_ll_init();
+	/* clear control register */
+	iccom_set_out_ctrl_reg(ICCOM_HW_CONTROL_INIT);
+	/* clear message register */
+	iccom_set_out_msg_reg(0x00000000UL);
+}
+
+FUNC(int, OS_APPL_CODE) main(void)
+{
+	iccom_init();
+	StartOS(OSDEFAULTAPPMODE);
+	return 0;
+}
+
+TASK(iccom) {
+}
+
+ISR(iccomInt)
+{
+	uint32 target_control = 0;
+	uint32 target_message = 0;
+	size_t rx_size = 0;
+
+	iccom_get_in_ctrl_reg(&target_control);
+	iccom_get_in_msg_reg(&target_message);
+
+	switch (iccom_get_msg_type(target_control)) {
+	case ICCOM_MSG_DATA:
+		rx_size = (size_t)target_message;
+		if (rx_size > ICCOM_BUF_MAX_SIZE)
+			rx_size = ICCOM_BUF_MAX_SIZE;
+		iccom_handle_rx_msg(rx_size);
+		break;
+	case ICCOM_MSG_ACK:
+		iccom_handle_ack_received();
+		break;
+	case ICCOM_MSG_INIT:
+		iccom_set_out_ctrl_reg(ICCOM_HW_CONTROL_INIT);
+		iccom_set_out_msg_reg(0x00000000UL);
+		iccom_initalized = 1;
+		iccom_send_initialization_ack();
+		break;
+	default:
+		// Unexpected message. Do we need to do something here?
+		break;
+	}
+
+	CallTerminateISR2();
+}
+
+ISR(iccomIntClear)
+{
+    iccom_clear_interrupt();
+}
+
+#define APP_Task_iccom_STOP_SEC_CODE
+#include "tpl_memmap.h"
diff --git a/examples/renesas/iccom/iccom.h b/examples/renesas/iccom/iccom.h
new file mode 100644
index 0000000..5f8b132
--- /dev/null
+++ b/examples/renesas/iccom/iccom.h
@@ -0,0 +1,10 @@
+#ifndef __ICCOM_H__
+#define __ICCOM_H__
+
+#include "iccom_ll.h"
+//#include <Platform_Types.h>
+#include <tpl_os_std_types.h>
+
+void iccom_init(void);
+
+#endif //__ICCOM_H__
diff --git a/examples/renesas/iccom/iccom.oil b/examples/renesas/iccom/iccom.oil
new file mode 100644
index 0000000..d5d1193
--- /dev/null
+++ b/examples/renesas/iccom/iccom.oil
@@ -0,0 +1,59 @@
+OIL_VERSION = "4.2";
+
+IMPLEMENTATION trampoline {
+  TASK {
+    UINT32 STACKSIZE = 2048 ;
+  } ;
+
+  ISR {
+    UINT32 STACKSIZE = 2048 ;
+  } ;
+};
+
+CPU iccom {
+  OS config {
+    STATUS = EXTENDED;
+    PAINT_STACK = TRUE;
+    PAINT_REGISTERS = TRUE;
+    
+    BUILD = TRUE {
+      TRAMPOLINE_BASE_PATH = "../../../";
+      APP_SRC = "iccom.c";
+      APP_SRC = "iccom_ll.c"; 
+      APP_NAME = "iccom_exe";
+      LDFLAGS="-debug -nocompress -NOOPtimize -memory=high -nologo -SHow=ALL";
+      CFLAGS="-Xcpu=g4mh -g -g_line -Xfxu=off -Xasm_path=.";
+      LINKER = "rlink";
+      SYSTEM = CMAKE;
+    };
+    SYSTEM_CALL = TRUE;
+  };
+
+  APPMODE std {};
+
+  TASK iccom {
+    PRIORITY = 1;
+    AUTOSTART = FALSE;
+    ACTIVATION = 1;
+    SCHEDULE = FULL;
+  };
+
+  ISR iccomIntClear {
+    CATEGORY = 1;
+    PRIORITY = 1;
+    SOURCE = iccomInt;
+  };
+  
+  ISR iccomInt {
+    CATEGORY = 2; //FSY unsupported
+    PRIORITY = 1;
+    SOURCE = iccomInt; //SysTick;
+  };
+
+  COUNTER SystemCounter {
+    SOURCE = SysTick;
+    MAXALLOWEDVALUE = 10000;
+    TICKSPERBASE = 1;
+    MINCYCLE = 1;
+  };
+};
diff --git a/examples/renesas/iccom/iccom_commands.h b/examples/renesas/iccom/iccom_commands.h
new file mode 100644
index 0000000..49fabb9
--- /dev/null
+++ b/examples/renesas/iccom/iccom_commands.h
@@ -0,0 +1,84 @@
+/*
+ * This header file is shared between Linux and G4 and it includes all the
+ * known iccom commands and replies
+ */
+
+#ifndef __ICCOM_COMMANDS_H__
+#define __ICCOM_COMMANDS_H__
+
+/*
+ * CC-RH has different types compared to Linux, but since this file is shared
+ * it should compile on both systems
+ */
+//#ifdef __rh850__
+	typedef uint8	uint8_t;
+	typedef uint16	uint16_t;
+	typedef uint32	uint32_t;
+	typedef sint32	int32_t;
+//#endif
+
+enum iccom_command {
+	READ_FLASH_ID = 0,
+	ERASE_AREA,
+	FLASH_CHUNK,
+	READ_CHUNK,
+};
+
+#define FLASH_PAGE_SIZE			0x100	// 256 bytes
+#define FLASH_PAGE_SIZE_MASK	0xFFFFFF00U
+
+// this is the common header shared between all commands
+#define CMD_HEADER		\
+		uint8_t cmd_id;
+
+#pragma pack(1)
+struct command_header {
+	CMD_HEADER
+};
+
+#pragma pack(1)
+struct simple_reply_int32 {
+	CMD_HEADER
+	int32_t ret_val;
+};
+#pragma pack(1)
+struct simple_reply_uint32 {
+	CMD_HEADER
+	uint32_t ret_val;
+};
+
+#pragma pack(1)
+struct read_flash_id_command {
+	CMD_HEADER
+};
+
+#pragma pack(1)
+struct erase_area_command {
+	CMD_HEADER
+	uint32_t start_address;
+	uint32_t size;
+};
+
+#pragma pack(1)
+struct flash_chunk_command {
+	CMD_HEADER
+	uint32_t start_address;
+	uint32_t size;
+	uint8_t data[FLASH_PAGE_SIZE];
+};
+
+#pragma pack(1)
+struct read_chunk_command {
+	CMD_HEADER
+	uint32_t start_address;
+	uint32_t size;
+};
+
+#pragma pack(1)
+struct read_chunk_reply {
+	CMD_HEADER
+	int32_t ret_val;
+	uint8_t data[FLASH_PAGE_SIZE];
+};
+
+#endif //__ICCOM_COMMANDS_H__
diff --git a/examples/renesas/iccom/iccom_ll.c b/examples/renesas/iccom/iccom_ll.c
new file mode 100644
index 0000000..ccbda1e
--- /dev/null
+++ b/examples/renesas/iccom/iccom_ll.c
@@ -0,0 +1,159 @@
+#include "iccom_ll.h"
+#include "iodefine.h"
+#include <string.h>
+//#include "Compiler.h"
+#include "tpl_compiler.h"
+
+uint32 ICCOM_CTA_MEMORY_CH0 = 0x47FC7000;
+uint32 ICCOM_CTA_MEMORY_CH1 = 0x47FC8000;
+
+void iccom_ll_init(void)
+{
+	volatile uint32 val = 0;
+
+	/* Enable access to the bus */
+	MCCR_SELB1.STBY_CTRL.UINT32 = 0x00000001;
+	do {
+		val = MCCR_SELB1.STBY_CTRL.UINT32;
+	} while (val != 0x00000001);
+
+	/* Disable MFIS write protection */
+	MFIS0.MFISWPCNTR = 0xACCE0001;
+	do {
+		val = MFIS0.MFISWPCNTR;
+	} while (val != 0x00000001);
+
+	// Enable interrupt EEIC 80 and set its priority to 0
+	INTC2.EIC80.BIT.EIP80 = 0x0;
+	INTC2.EIC80.BIT.EIMK80 = 0x0;
+}
+
+static void iccom_lock(ICCOM_CHANNEL channel)
+{
+	/* nothing at the moment */
+}
+
+static void iccom_unlock(ICCOM_CHANNEL channel)
+{
+	/* nothing at the moment */
+}
+
+/**
+ * Set MFIS CPU communication control register [i] G4MH[k] core to Cortex-A55
+ * CPU core(MFISAM[k]EICR[i])(i=0-7)(k=0-1).
+ *
+ * Support only CPU 0 to G4MH 0
+ */
+void iccom_set_out_ctrl_reg(uint32 val)
+{
+	MFIS0.MFISAM0EICR0 = val;
+}
+
+/**
+ * Get MFIS CPU communication control register [i] G4MH[k] core to Cortex-A55
+ * CPU core(MFISAM[k]EICR[i])(i=0-7)(k=0-1).
+ *
+ * Support only CPU 0 to G4MH 0
+ */
+void iccom_get_out_ctrl_reg(uint32 *pval)
+{
+	volatile uint32 reg = 0;
+	reg = MFIS0.MFISAM0EICR0;
+
+	if (NULL_PTR != pval) {
+		*pval = reg;
+	}
+}
+
+/**
+ * Clear the interruption bit
+ *
+ * MFIS CPU communication control register [i] Cortex-A55 CPU core to G4MH[k]
+ * core(MFISAM[k]IICR[i])(i=0-7)(k=0-1)
+ *
+ * Support only CPU 0 to G4MH 0
+ */
+void iccom_clear_interrupt(void)
+{
+	volatile uint32 reg = 0;
+	reg = MFIS0.MFISAM0IICR0;
+	reg &= ~(ICCOM_CTRL_INT);
+	MFIS0.MFISAM0IICR0 = reg;
+}
+
+/**
+ * Get MFIS CPU communication control register [i] Cortex-A55 CPU core to G4MH[k]
+ * core(MFISAM[k]IICR[i])(i=0-7)(k=0-1)
+ *
+ * Support only CPU 0 to G4MH 0
+ */
+void iccom_get_in_ctrl_reg(uint32 *pval)
+{
+	volatile uint32 reg = 0;
+	reg = MFIS0.MFISAM0IICR0;
+
+	if (NULL_PTR != pval) {
+		*pval = reg;
+	}
+}
+
+void iccom_set_in_ctrl_reg(uint32 val)
+{
+	MFIS0.MFISAM0IICR0 = val;
+}
+
+/**
+ * Set MFIS CPU communication message register [i] G4MH[k] core to Cortex-A55
+ * CPU core(MFISAM[k]EMBR[i])(i=0-7)(k=0-1)
+ *
+ * Support only CPU 0 to G4MH 0
+ */
+void iccom_set_out_msg_reg(uint32 val)
+{
+	MFIS0.MFISAM0EMBR0 = val;
+}
+
+/**
+ * Get MFIS CPU communication message register [i] Cortex-A55 CPU core to
+ * G4MH[k] core(MFISAM[k]IMBR[i])(i=0-7)(k=0-1)
+ *
+ * Support only CPU 0 to G4MH 0
+ */
+void iccom_get_in_msg_reg(uint32 *pval)
+{
+	volatile uint32 reg = 0;
+	reg = MFIS0.MFISAM0IMBR0;
+
+	if (NULL_PTR != pval) {
+		*pval = reg;
+	}
+}
+
+void iccom_clear_interrupt_locked(void)
+{
+	iccom_lock(ICCOM_CHANNEL_0);
+
+	iccom_clear_interrupt();
+
+	iccom_unlock(ICCOM_CHANNEL_0);
+}
+
+void iccom_cta_write(uint8 * buff, size_t size)
+{
+	void* ctaPtr = (void*)ICCOM_CTA_MEMORY_CH1;
+
+	if (buff == NULL_PTR)
+		return;
+
+	memcpy(ctaPtr, buff, size);
+}
+
+void iccom_cta_read(uint8 * buff, size_t size)
+{
+	void* ctaPtr = (void*)ICCOM_CTA_MEMORY_CH0;
+
+	if (buff == NULL)
+		return;
+
+	memcpy(buff, ctaPtr, size);
+}
diff --git a/examples/renesas/iccom/iccom_ll.h b/examples/renesas/iccom/iccom_ll.h
new file mode 100644
index 0000000..24179ce
--- /dev/null
+++ b/examples/renesas/iccom/iccom_ll.h
@@ -0,0 +1,39 @@
+#ifndef __ICCOM_LL_H__
+#define __ICCOM_LL_H__
+
+//#include <Platform_Types.h>
+#include <tpl_os_std_types.h>
+#include <stddef.h>
+
+static const uint32 ICCOM_HW_CONTROL_INIT = 0x00000000UL;
+
+// IMPORTANT: Keep these masks aligned between CA55 and G4MH
+#define ICCOM_CTRL_INT				(0x00000001U)
+#define ICCOM_CTRL_BUFF_UPPER		(0x00000002U)
+#define ICCOM_CTRL_BUFF_BOTTOM		(0x00000004U)
+#define ICCOM_CTRL_DATA				(0x00000008U)
+#define ICCOM_CTRL_ACK				(0x00000010U)
+#define ICCOM_CTRL_INIT_COMPLETED	(0x00000020U)
+
+typedef enum {
+    ICCOM_CHANNEL_0 = 0,
+} ICCOM_CHANNEL;
+
+/* MFIS HW */
+void iccom_ll_init(void);
+
+void iccom_set_out_ctrl_reg(uint32 val);
+void iccom_get_out_ctrl_reg(uint32 *pval);
+void iccom_set_in_ctrl_reg(uint32 val);
+void iccom_get_in_ctrl_reg(uint32 *pval);
+
+void iccom_set_out_msg_reg(uint32 val);
+void iccom_get_in_msg_reg(uint32 *pval);
+
+void iccom_clear_interrupt(void);
+void iccom_clear_interrupt_locked(void);
+
+void iccom_cta_read(uint8 * buff, size_t size);
+void iccom_cta_write(uint8 * buff, size_t size);
+
+#endif //__ICCOM_LL_H__
-- 
2.34.1

