@@ -47,6 +47,9 @@ static volatile bool g_SlaveCompletionFlag = false;
4747static volatile bool g_SlaveRxFlag = false;
4848static uint8_t address_match = 0 ;
4949static uint32_t transferredCount = 0 ;
50+ static const uint8_t g_slave_busy_error_buff [] = {gErrorResponse_c , gErrorBusy_c };
51+ static uint8_t g_slave_TX_buff_ready = 0 ;
52+ static uint8_t g_slave_busy = 0 ;
5053
5154static i2cWriteCallback_t pfWriteCommsCallback = NULL ;
5255static i2cReadCallback_t pfReadCommsCallback = NULL ;
@@ -73,6 +76,8 @@ static void i2c_write_flash_callback(uint8_t* pData, uint8_t size);
7376static void i2c_read_flash_callback (uint8_t * pData , uint8_t size );
7477
7578static void i2c_slave_callback (I2C_Type * base , i2c_slave_transfer_t * xfer , void * userData ) {
79+ i2cCommand_t i2cResponse = {0 };
80+
7681 switch (xfer -> event )
7782 {
7883 /* Address match event */
@@ -86,21 +91,31 @@ static void i2c_slave_callback(I2C_Type *base, i2c_slave_transfer_t *xfer, void
8691 /* Transmit request */
8792 case kI2C_SlaveTransmitEvent :
8893 /* Update information for transmit process */
89- xfer -> data = g_slave_TX_buff ;
90- xfer -> dataSize = I2C_DATA_LENGTH ;
94+ // Send response if the buffer is ready, otherwise send busy error
95+ if (g_slave_TX_buff_ready ) {
96+ xfer -> data = g_slave_TX_buff ;
97+ xfer -> dataSize = I2C_DATA_LENGTH ;
98+ } else {
99+ xfer -> data = (uint8_t * )g_slave_busy_error_buff ;
100+ xfer -> dataSize = sizeof (g_slave_busy_error_buff );
101+ g_slave_busy = 1 ;
102+ }
91103 g_SlaveRxFlag = false;
92104 break ;
93105
94106 /* Receive request */
95107 case kI2C_SlaveReceiveEvent :
96108 /* Update information for received process */
109+ // We don't need to clear g_slave_RX_buff because we also have the
110+ // transferredCount to know what data is valid
111+ xfer -> data = g_slave_RX_buff ;
112+ xfer -> dataSize = I2C_DATA_LENGTH ;
113+
97114 // Hack: Default driver can't differentiate between RX or TX on
98115 // completion event, so we set a flag here. Can't process more
99116 // than I2C_DATA_LENGTH bytes on RX
100- memset (& g_slave_RX_buff , 0 , sizeof (g_slave_RX_buff ));
101- xfer -> data = g_slave_RX_buff ;
102- xfer -> dataSize = I2C_DATA_LENGTH ;
103117 g_SlaveRxFlag = true;
118+
104119 break ;
105120
106121 /* Transfer done */
@@ -115,9 +130,20 @@ static void i2c_slave_callback(I2C_Type *base, i2c_slave_transfer_t *xfer, void
115130
116131 // Ignore NOP cmd in I2C Write
117132 if (!(g_SlaveRxFlag && g_slave_RX_buff [0 ] == 0x00 )) {
118- main_board_event ();
133+ // Only process events if the busy error was not read
134+ if (!g_slave_busy ) {
135+ main_board_event ();
136+ } else {
137+ g_slave_busy = 0 ;
138+ }
119139 }
120140
141+ // Buffer with response is not ready after an I2C Write inside the IRQ
142+ // It will be ready when the task attends the I2C event
143+ if (g_SlaveRxFlag ) {
144+ g_slave_TX_buff_ready = 0 ;
145+ }
146+
121147 i2c_allow_sleep = false;
122148 break ;
123149
@@ -130,6 +156,7 @@ static void i2c_slave_callback(I2C_Type *base, i2c_slave_transfer_t *xfer, void
130156void board_custom_event () {
131157
132158 if (g_SlaveRxFlag ) {
159+ i2c_clearBuffer ();
133160 if (pfWriteCommsCallback && address_match == I2C_SLAVE_NRF_KL_COMMS ) {
134161 pfWriteCommsCallback (& g_slave_RX_buff [0 ], transferredCount );
135162 }
@@ -259,6 +286,7 @@ void i2c_fillBuffer (uint8_t* data, uint32_t position, uint32_t size) {
259286 for (uint32_t i = 0 ; i < size ; i ++ ) {
260287 g_slave_TX_buff [position + i ] = data [i ];
261288 }
289+ g_slave_TX_buff_ready = 1 ;
262290}
263291
264292static void i2c_write_comms_callback (uint8_t * pData , uint8_t size ) {
@@ -276,7 +304,7 @@ static void i2c_write_comms_callback(uint8_t* pData, uint8_t size) {
276304 memcpy (& i2cResponse .cmdData .readRspCmd .data , & board_id_hex , sizeof (board_id_hex ));
277305 break ;
278306 case gI2CProtocolVersion_c : {
279- uint16_t i2c_version = 1 ;
307+ uint16_t i2c_version = 2 ;
280308 i2cResponse .cmdData .readRspCmd .dataSize = sizeof (i2c_version );
281309 memcpy (& i2cResponse .cmdData .readRspCmd .data , & i2c_version , sizeof (i2c_version ));
282310 }
@@ -413,8 +441,6 @@ static void i2c_read_comms_callback(uint8_t* pData, uint8_t size) {
413441 break ;
414442 }
415443
416- i2c_clearBuffer ();
417-
418444 // Release COMBINED_SENSOR_INT
419445 PORT_SetPinMux (COMBINED_SENSOR_INT_PORT , COMBINED_SENSOR_INT_PIN , kPORT_PinDisabledOrAnalog );
420446}
@@ -478,8 +504,6 @@ static void i2c_write_flash_callback(uint8_t* pData, uint8_t size) {
478504 uint32_t address = storage_address + FLASH_STORAGE_ADDRESS ;
479505 uint32_t length = __REV (pI2cCommand -> cmdData .write .length );
480506 uint32_t data = (uint32_t ) pI2cCommand -> cmdData .write .data ;
481-
482- i2c_clearBuffer ();
483507
484508 switch (pI2cCommand -> cmdId ) {
485509 case gFlashDataWrite_c :
@@ -606,6 +630,44 @@ static void i2c_write_flash_callback(uint8_t* pData, uint8_t size) {
606630 i2c_fillBuffer ((uint8_t * ) pI2cCommand , 0 , 1 );
607631 }
608632 break ;
633+ case gFlashCfgEncWindow_c :
634+ if (size == 1 ) {
635+ /* If size is 1 (only cmd id), this means it's a read */
636+ uint32_t tempFileEncWindowStart = __REV (gflashConfig .fileEncWindowStart );
637+ uint32_t tempFileEncWindowEnd = __REV (gflashConfig .fileEncWindowEnd );
638+ i2c_fillBuffer ((uint8_t * ) pI2cCommand , 0 , 1 );
639+ i2c_fillBuffer ((uint8_t * ) & tempFileEncWindowStart , 1 , sizeof (gflashConfig .fileEncWindowStart ));
640+ i2c_fillBuffer ((uint8_t * ) & tempFileEncWindowEnd , 5 , sizeof (gflashConfig .fileEncWindowEnd ));
641+ } else if (size == 9 ) {
642+ /* If size is 9 (cmd id + 8B data), this means it's a write */
643+ uint32_t tempFileEncWindowStart = pI2cCommand -> cmdData .data [0 ] << 24 |
644+ pI2cCommand -> cmdData .data [1 ] << 16 |
645+ pI2cCommand -> cmdData .data [2 ] << 8 |
646+ pI2cCommand -> cmdData .data [3 ] << 0 ;
647+ uint32_t tempFileEncWindowEnd = pI2cCommand -> cmdData .data [4 ] << 24 |
648+ pI2cCommand -> cmdData .data [5 ] << 16 |
649+ pI2cCommand -> cmdData .data [6 ] << 8 |
650+ pI2cCommand -> cmdData .data [7 ] << 0 ;
651+
652+ /* Validate encoding window */
653+ if (tempFileEncWindowStart <= tempFileEncWindowEnd ) {
654+ gflashConfig .fileEncWindowStart = tempFileEncWindowStart ;
655+ tempFileEncWindowStart = __REV (gflashConfig .fileEncWindowStart );
656+ gflashConfig .fileEncWindowEnd = tempFileEncWindowEnd ;
657+ tempFileEncWindowEnd = __REV (gflashConfig .fileEncWindowEnd );
658+
659+ i2c_fillBuffer ((uint8_t * ) pI2cCommand , 0 , 1 );
660+ i2c_fillBuffer ((uint8_t * ) & tempFileEncWindowStart , 1 , sizeof (gflashConfig .fileEncWindowStart ));
661+ i2c_fillBuffer ((uint8_t * ) & tempFileEncWindowEnd , 5 , sizeof (gflashConfig .fileEncWindowEnd ));
662+ } else {
663+ pI2cCommand -> cmdId = gFlashError_c ;
664+ i2c_fillBuffer ((uint8_t * ) pI2cCommand , 0 , 1 );
665+ }
666+ } else {
667+ pI2cCommand -> cmdId = gFlashError_c ;
668+ i2c_fillBuffer ((uint8_t * ) pI2cCommand , 0 , 1 );
669+ }
670+ break ;
609671 case gFlashCfgFileVisible_c :
610672 if (size == 1 ) {
611673 /* If size is 1 (only cmd id), this means it's a read */
@@ -649,6 +711,8 @@ static void i2c_write_flash_callback(uint8_t* pData, uint8_t size) {
649711 memcpy (gflashConfig .fileName , FLASH_CFG_FILENAME , 11 );
650712 gflashConfig .fileSize = FLASH_CFG_FILESIZE ;
651713 gflashConfig .fileVisible = FLASH_CFG_FILEVISIBLE ;
714+ gflashConfig .fileEncWindowStart = 0 ;
715+ gflashConfig .fileEncWindowEnd = 0 ;
652716 }
653717 i2c_fillBuffer ((uint8_t * ) pI2cCommand , 0 , 1 );
654718 break ;
@@ -676,8 +740,6 @@ static void i2c_write_flash_callback(uint8_t* pData, uint8_t size) {
676740}
677741
678742static void i2c_read_flash_callback (uint8_t * pData , uint8_t size ) {
679- i2c_clearBuffer ();
680-
681743 // Release COMBINED_SENSOR_INT
682744 PORT_SetPinMux (COMBINED_SENSOR_INT_PORT , COMBINED_SENSOR_INT_PIN , kPORT_PinDisabledOrAnalog );
683745}
0 commit comments