generated from Embedded_Projects/MPyATE_Template
132 lines
4.7 KiB
C
132 lines
4.7 KiB
C
/* 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;
|
|
}
|
|
} |