diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..214adf0
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,12 @@
+BasedOnStyle: Google
+IndentWidth: 4
+AlignConsecutiveMacros: Consecutive
+AlignConsecutiveDeclarations: Consecutive
+AlignConsecutiveAssignments: Consecutive
+AllowShortFunctionsOnASingleLine: None
+BreakBeforeBraces: Custom
+BraceWrapping:
+ AfterEnum: false
+ AfterStruct: false
+ SplitEmptyFunction: false
+ColumnLimit: 120
\ No newline at end of file
diff --git a/.drone.yml b/.drone.yml
new file mode 100644
index 0000000..94e5a4b
--- /dev/null
+++ b/.drone.yml
@@ -0,0 +1,17 @@
+---
+kind: pipeline
+type: docker
+name: Build
+
+steps:
+ - name: Submodules
+ image: alpine/git
+ commands:
+ - git submodule update --init --recursive
+
+ - name: Build
+ image: "git.minori.work/embedded_sdk/embedded-builder-arm:12.2.mpacbti-rel1"
+ commands:
+ - mkdir build && cd build
+ - cmake -DCMAKE_TOOLCHAIN_FILE=arm-none-eabi.cmake ..
+ - make
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2da6168
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+/cmake-build-*
+/build
+/board/*.bak
+/.vscode
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 57526d9..5d4d26e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.10)
-project(mpyate_template)
+project(mpyate_firmware)
enable_language(CXX)
enable_language(ASM)
@@ -43,6 +43,8 @@ set(TARGET_SOURCES
"board/clock_config.c"
"board/peripherals.c"
"board/pin_mux.c"
+ "src/app_i2c_if.c"
+ "src/app_reg_if.c"
"src/main.c"
)
diff --git a/LPC804.mex b/LPC804.mex
index 64f48c0..9010032 100644
--- a/LPC804.mex
+++ b/LPC804.mex
@@ -159,6 +159,43 @@
+
+ Configures pin routing and optionally pin electrical features.
+
+ true
+ core0
+ true
+
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SDK b/SDK
new file mode 160000
index 0000000..e468131
--- /dev/null
+++ b/SDK
@@ -0,0 +1 @@
+Subproject commit e46813114663364b03f7507d3926852fe55b2b58
diff --git a/board/pin_mux.c b/board/pin_mux.c
index f9b6a30..08bd069 100644
--- a/board/pin_mux.c
+++ b/board/pin_mux.c
@@ -36,6 +36,7 @@ void BOARD_InitBootPins(void)
BOARD_InitLEDPins();
BOARD_InitADCPins();
BOARD_InitDACPins();
+ BOARD_InitI2CPins();
}
/* clang-format off */
@@ -204,6 +205,58 @@ void BOARD_InitDACPins(void)
/* Disable clock for switch matrix. */
CLOCK_DisableClock(kCLOCK_Swm);
}
+
+/* clang-format off */
+/*
+ * TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
+BOARD_InitI2CPins:
+- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'}
+- pin_list:
+ - {pin_num: '18', peripheral: I2C0, signal: SCL, pin_signal: PIO0_9/ADC_4, mode: inactive}
+ - {pin_num: '17', peripheral: I2C0, signal: SDA, pin_signal: PIO0_1/ADC_0/ACMP_I2/CLKIN, mode: inactive}
+ * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
+ */
+/* clang-format on */
+
+/* FUNCTION ************************************************************************************************************
+ *
+ * Function Name : BOARD_InitI2CPins
+ * Description : Configures pin routing and optionally pin electrical features.
+ *
+ * END ****************************************************************************************************************/
+/* Function assigned for the Cortex-M0P */
+void BOARD_InitI2CPins(void)
+{
+ /* Enables clock for IOCON.: enable */
+ CLOCK_EnableClock(kCLOCK_Iocon);
+ /* Enables clock for switch matrix.: enable */
+ CLOCK_EnableClock(kCLOCK_Swm);
+
+ IOCON->PIO[11] = ((IOCON->PIO[11] &
+ /* Mask bits to zero which are setting */
+ (~(IOCON_PIO_MODE_MASK)))
+
+ /* Selects function mode (on-chip pull-up/pull-down resistor control).: Inactive. Inactive (no
+ * pull-down/pull-up resistor enabled). */
+ | IOCON_PIO_MODE(PIO0_1_MODE_INACTIVE));
+
+ IOCON->PIO[13] = ((IOCON->PIO[13] &
+ /* Mask bits to zero which are setting */
+ (~(IOCON_PIO_MODE_MASK)))
+
+ /* Selects function mode (on-chip pull-up/pull-down resistor control).: Inactive. Inactive (no
+ * pull-down/pull-up resistor enabled). */
+ | IOCON_PIO_MODE(PIO0_9_MODE_INACTIVE));
+
+ /* I2C0_SDA connect to P0_1 */
+ SWM_SetMovablePinSelect(SWM0, kSWM_I2C0_SDA, kSWM_PortPin_P0_1);
+
+ /* I2C0_SCL connect to P0_9 */
+ SWM_SetMovablePinSelect(SWM0, kSWM_I2C0_SCL, kSWM_PortPin_P0_9);
+
+ /* Disable clock for switch matrix. */
+ CLOCK_DisableClock(kCLOCK_Swm);
+}
/***********************************************************************************************************************
* EOF
**********************************************************************************************************************/
diff --git a/board/pin_mux.h b/board/pin_mux.h
index b68c333..57457d9 100644
--- a/board/pin_mux.h
+++ b/board/pin_mux.h
@@ -92,6 +92,27 @@ void BOARD_InitADCPins(void); /* Function assigned for the Cortex-M0P */
*/
void BOARD_InitDACPins(void); /* Function assigned for the Cortex-M0P */
+/*!
+ * @brief
+ * Selects function mode (on-chip pull-up/pull-down resistor control).
+ * : Inactive.
+ * Inactive (no pull-down/pull-up resistor enabled).
+ */
+#define PIO0_1_MODE_INACTIVE 0x00u
+/*!
+ * @brief
+ * Selects function mode (on-chip pull-up/pull-down resistor control).
+ * : Inactive.
+ * Inactive (no pull-down/pull-up resistor enabled).
+ */
+#define PIO0_9_MODE_INACTIVE 0x00u
+
+/*!
+ * @brief Configures pin routing and optionally pin electrical features.
+ *
+ */
+void BOARD_InitI2CPins(void); /* Function assigned for the Cortex-M0P */
+
#if defined(__cplusplus)
}
#endif
diff --git a/include/app_i2c_if.h b/include/app_i2c_if.h
new file mode 100644
index 0000000..d252147
--- /dev/null
+++ b/include/app_i2c_if.h
@@ -0,0 +1,6 @@
+#ifndef APP_I2C_IF_H
+#define APP_I2C_IF_H
+
+int app_i2c_if_init(void);
+
+#endif // APP_I2C_IF_H
diff --git a/include/app_reg_if.h b/include/app_reg_if.h
new file mode 100644
index 0000000..312930a
--- /dev/null
+++ b/include/app_reg_if.h
@@ -0,0 +1,12 @@
+#ifndef APP_REG_IF_H
+#define APP_REG_IF_H
+
+#include
+#include
+
+#define APP_REG_IF_REG_ID 0xFFU
+
+uint16_t app_reg_if_read(uint8_t reg);
+void app_reg_if_write(uint8_t reg, uint16_t data, bool check_attr);
+
+#endif // APP_REG_IF_H
diff --git a/src/app_i2c_if.c b/src/app_i2c_if.c
new file mode 100644
index 0000000..ec8ee4f
--- /dev/null
+++ b/src/app_i2c_if.c
@@ -0,0 +1,132 @@
+/* Board */
+#include "pin_mux.h"
+
+/* SDK drivers */
+#include "fsl_clock.h"
+#include "fsl_common.h"
+#include "fsl_common_arm.h"
+#include "fsl_gpio.h"
+
+/* App */
+#include "app_i2c_if.h"
+#include "app_reg_if.h"
+
+#define APP_I2C_INSTANCE I2C0
+#define APP_I2C_ADDR (0x28U)
+
+#define APP_I2C_WRITE_LEN (3)
+#define APP_I2C_READ_LEN (2)
+
+uint8_t s_app_i2c_write_ptr;
+uint8_t s_app_i2c_write_buffer[APP_I2C_WRITE_LEN];
+
+uint8_t s_app_i2c_read_ptr;
+uint8_t s_app_i2c_read_reg_addr;
+uint8_t s_app_i2c_read_buffer[APP_I2C_READ_LEN];
+
+int app_i2c_if_init(void) {
+ CLOCK_Select(kI2C0_Clk_From_MainClk);
+ CLOCK_EnableClock(kCLOCK_I2c0);
+
+ RESET_PeripheralReset(kI2C0_RST_N_SHIFT_RSTn);
+
+ APP_I2C_INSTANCE->CLKDIV = 7U;
+
+ APP_I2C_INSTANCE->SLVADR[0] = I2C_SLVADR_SLVADR(APP_I2C_ADDR); // Use slave address 0
+ APP_I2C_INSTANCE->SLVQUAL0 = 0UL; // Use the address as-is
+
+ APP_I2C_INSTANCE->INTENCLR =
+ I2C_INTENCLR_MSTPENDINGCLR(1) | I2C_INTENCLR_MSTARBLOSSCLR(1) | I2C_INTENCLR_MSTSTSTPERRCLR(1) |
+ I2C_INTENCLR_SLVPENDINGCLR(1) | I2C_INTENCLR_SLVNOTSTRCLR(1) | I2C_INTENCLR_SLVDESELCLR(1) |
+ I2C_INTENCLR_MONRDYCLR(1) | I2C_INTENCLR_MONIDLECLR(1) | I2C_INTENCLR_EVENTTIMEOUTCLR(1) |
+ I2C_INTENCLR_SCLTIMEOUTCLR(1); // Disable all interrupts
+
+ APP_I2C_INSTANCE->STAT = I2C_STAT_MSTARBLOSS(1) | I2C_STAT_MSTSTSTPERR(1) | I2C_STAT_SLVDESEL(1) |
+ I2C_STAT_MONOV(1) | I2C_STAT_MONIDLE(1) | I2C_STAT_EVENTTIMEOUT(1) |
+ I2C_STAT_SCLTIMEOUT(1); // Clear all interrupt flags
+
+ APP_I2C_INSTANCE->INTENSET = I2C_INTENSET_SLVPENDINGEN(1) | I2C_INTENSET_SLVDESELEN(1); // Enable slave interrupts
+
+ APP_I2C_INSTANCE->CFG = I2C_CFG_SLVEN(1); // Enable Slave mode
+
+ s_app_i2c_write_ptr = 0U;
+ s_app_i2c_read_ptr = 0U;
+
+ NVIC_SetPriority(I2C0_IRQn, 0);
+ EnableIRQ(I2C0_IRQn);
+
+ return 0;
+}
+
+void I2C0_IRQHandler(void) {
+ GPIO_PinWrite(BOARD_INITLEDPINS_LED_B_GPIO, BOARD_INITLEDPINS_LED_B_PORT, BOARD_INITLEDPINS_LED_B_PIN, 0U);
+ uint32_t flags = APP_I2C_INSTANCE->STAT;
+
+ /* Clear interrupt flags */
+ APP_I2C_INSTANCE->STAT |= flags;
+ /* Slave requires software servicing */
+ if (flags & I2C_STAT_SLVPENDING_MASK) {
+ uint32_t slave_state = (flags & I2C_STAT_SLVSTATE_MASK);
+
+ if (slave_state == I2C_STAT_SLVSTATE(0)) {
+ /* A new address cycle has started, slave is selected with address match */
+
+ /* Ack the address */
+ APP_I2C_INSTANCE->SLVCTL = I2C_SLVCTL_SLVCONTINUE(1);
+ } else if (slave_state == I2C_STAT_SLVSTATE(1)) {
+ /* Data is ready to be read out */
+ if (s_app_i2c_write_ptr == APP_I2C_WRITE_LEN) {
+ /* Master sent too much data, Nack. */
+ APP_I2C_INSTANCE->SLVCTL = I2C_SLVCTL_SLVNACK(1);
+ } else {
+ s_app_i2c_write_buffer[s_app_i2c_write_ptr] = APP_I2C_INSTANCE->SLVDAT;
+ s_app_i2c_write_ptr++;
+
+ APP_I2C_INSTANCE->SLVCTL = I2C_SLVCTL_SLVCONTINUE(1);
+ }
+ } else if (slave_state == I2C_STAT_SLVSTATE(2)) {
+ /* Data needs to be written to host */
+
+ if (s_app_i2c_write_ptr < APP_I2C_READ_LEN) {
+ if (s_app_i2c_read_ptr == 0U) {
+ /* First read, read register to buffer */
+ uint16_t reg_data = app_reg_if_read(s_app_i2c_read_reg_addr);
+
+ s_app_i2c_read_buffer[0] = reg_data & 0xFFU;
+ s_app_i2c_read_buffer[1] = (reg_data >> 8U) & 0xFFU;
+ }
+
+ APP_I2C_INSTANCE->SLVDAT = s_app_i2c_read_buffer[s_app_i2c_read_ptr];
+ s_app_i2c_read_ptr++;
+ } else {
+ /* Max length reached, start a new register read with self-increased address */
+ s_app_i2c_read_reg_addr++;
+ s_app_i2c_read_ptr = 0U;
+
+ uint16_t reg_data = app_reg_if_read(s_app_i2c_read_reg_addr);
+
+ s_app_i2c_read_buffer[0] = reg_data & 0xFFU;
+ s_app_i2c_read_buffer[1] = (reg_data >> 8U) & 0xFFU;
+
+ APP_I2C_INSTANCE->SLVDAT = s_app_i2c_read_buffer[s_app_i2c_read_ptr];
+ s_app_i2c_read_ptr++;
+ }
+
+ APP_I2C_INSTANCE->SLVCTL = I2C_SLVCTL_SLVCONTINUE(1);
+ }
+ }
+
+ if (flags & I2C_STAT_SLVDESEL_MASK) {
+ /* Slave is de-selected due to another address cycle or STOP event */
+
+ if (s_app_i2c_write_ptr == APP_I2C_WRITE_LEN) {
+ /* Complete write, write register. */
+ } else if (s_app_i2c_write_ptr == 1) {
+ /* Select register to read */
+ s_app_i2c_read_reg_addr = s_app_i2c_write_buffer[0];
+ }
+
+ s_app_i2c_write_ptr = 0U;
+ s_app_i2c_read_ptr = 0U;
+ }
+}
\ No newline at end of file
diff --git a/src/app_reg_if.c b/src/app_reg_if.c
new file mode 100644
index 0000000..b34f04c
--- /dev/null
+++ b/src/app_reg_if.c
@@ -0,0 +1,19 @@
+#include "app_reg_if.h"
+
+#define APP_REG_IF_ATTR_RO (1U << 0U)
+
+uint16_t app_reg_if_read(uint8_t reg) {
+ switch (reg) {
+ case APP_REG_IF_REG_ID:
+ return 0xEACE;
+ default:
+ return 0x0000;
+ }
+}
+
+void app_reg_if_write(uint8_t reg, uint16_t data, bool check_attr) {
+ switch (reg) {
+ default:
+ break;
+ }
+}
diff --git a/src/main.c b/src/main.c
index c4bd367..400b861 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,15 +1,19 @@
+/* Board */
#include "board.h"
#include "clock_config.h"
-#include "fsl_debug_console.h"
#include "pin_mux.h"
+/* App */
+#include "app_i2c_if.h"
+
int main(void) {
BOARD_InitBootPins();
BOARD_InitBootClocks();
+ app_i2c_if_init();
+
for (;;) {
- GPIO_PortToggle(BOARD_INITLEDPINS_LED_R_GPIO, BOARD_INITLEDPINS_LED_R_PORT,
- BOARD_INITLEDPINS_LED_R_GPIO_PIN_MASK);
+ GPIO_PortToggle(BOARD_INITLEDPINS_LED_R_GPIO, BOARD_INITLEDPINS_LED_R_PORT, BOARD_INITLEDPINS_LED_R_PIN_MASK);
SDK_DelayAtLeastUs(500 * 1000, CLOCK_GetCoreSysClkFreq());
}
}