@@ -47,6 +47,9 @@ static volatile bool g_SlaveCompletionFlag = false;
47
47
static volatile bool g_SlaveRxFlag = false;
48
48
static uint8_t address_match = 0 ;
49
49
static 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 ;
50
53
51
54
static i2cWriteCallback_t pfWriteCommsCallback = NULL ;
52
55
static i2cReadCallback_t pfReadCommsCallback = NULL ;
@@ -73,6 +76,8 @@ static void i2c_write_flash_callback(uint8_t* pData, uint8_t size);
73
76
static void i2c_read_flash_callback (uint8_t * pData , uint8_t size );
74
77
75
78
static void i2c_slave_callback (I2C_Type * base , i2c_slave_transfer_t * xfer , void * userData ) {
79
+ i2cCommand_t i2cResponse = {0 };
80
+
76
81
switch (xfer -> event )
77
82
{
78
83
/* Address match event */
@@ -86,21 +91,31 @@ static void i2c_slave_callback(I2C_Type *base, i2c_slave_transfer_t *xfer, void
86
91
/* Transmit request */
87
92
case kI2C_SlaveTransmitEvent :
88
93
/* 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
+ }
91
103
g_SlaveRxFlag = false;
92
104
break ;
93
105
94
106
/* Receive request */
95
107
case kI2C_SlaveReceiveEvent :
96
108
/* 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
+
97
114
// Hack: Default driver can't differentiate between RX or TX on
98
115
// completion event, so we set a flag here. Can't process more
99
116
// 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 ;
103
117
g_SlaveRxFlag = true;
118
+
104
119
break ;
105
120
106
121
/* Transfer done */
@@ -115,9 +130,20 @@ static void i2c_slave_callback(I2C_Type *base, i2c_slave_transfer_t *xfer, void
115
130
116
131
// Ignore NOP cmd in I2C Write
117
132
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
+ }
119
139
}
120
140
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
+
121
147
i2c_allow_sleep = false;
122
148
break ;
123
149
@@ -130,6 +156,7 @@ static void i2c_slave_callback(I2C_Type *base, i2c_slave_transfer_t *xfer, void
130
156
void board_custom_event () {
131
157
132
158
if (g_SlaveRxFlag ) {
159
+ i2c_clearBuffer ();
133
160
if (pfWriteCommsCallback && address_match == I2C_SLAVE_NRF_KL_COMMS ) {
134
161
pfWriteCommsCallback (& g_slave_RX_buff [0 ], transferredCount );
135
162
}
@@ -259,6 +286,7 @@ void i2c_fillBuffer (uint8_t* data, uint32_t position, uint32_t size) {
259
286
for (uint32_t i = 0 ; i < size ; i ++ ) {
260
287
g_slave_TX_buff [position + i ] = data [i ];
261
288
}
289
+ g_slave_TX_buff_ready = 1 ;
262
290
}
263
291
264
292
static 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) {
276
304
memcpy (& i2cResponse .cmdData .readRspCmd .data , & board_id_hex , sizeof (board_id_hex ));
277
305
break ;
278
306
case gI2CProtocolVersion_c : {
279
- uint16_t i2c_version = 1 ;
307
+ uint16_t i2c_version = 2 ;
280
308
i2cResponse .cmdData .readRspCmd .dataSize = sizeof (i2c_version );
281
309
memcpy (& i2cResponse .cmdData .readRspCmd .data , & i2c_version , sizeof (i2c_version ));
282
310
}
@@ -413,8 +441,6 @@ static void i2c_read_comms_callback(uint8_t* pData, uint8_t size) {
413
441
break ;
414
442
}
415
443
416
- i2c_clearBuffer ();
417
-
418
444
// Release COMBINED_SENSOR_INT
419
445
PORT_SetPinMux (COMBINED_SENSOR_INT_PORT , COMBINED_SENSOR_INT_PIN , kPORT_PinDisabledOrAnalog );
420
446
}
@@ -478,8 +504,6 @@ static void i2c_write_flash_callback(uint8_t* pData, uint8_t size) {
478
504
uint32_t address = storage_address + FLASH_STORAGE_ADDRESS ;
479
505
uint32_t length = __REV (pI2cCommand -> cmdData .write .length );
480
506
uint32_t data = (uint32_t ) pI2cCommand -> cmdData .write .data ;
481
-
482
- i2c_clearBuffer ();
483
507
484
508
switch (pI2cCommand -> cmdId ) {
485
509
case gFlashDataWrite_c :
@@ -606,6 +630,44 @@ static void i2c_write_flash_callback(uint8_t* pData, uint8_t size) {
606
630
i2c_fillBuffer ((uint8_t * ) pI2cCommand , 0 , 1 );
607
631
}
608
632
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 ;
609
671
case gFlashCfgFileVisible_c :
610
672
if (size == 1 ) {
611
673
/* 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) {
649
711
memcpy (gflashConfig .fileName , FLASH_CFG_FILENAME , 11 );
650
712
gflashConfig .fileSize = FLASH_CFG_FILESIZE ;
651
713
gflashConfig .fileVisible = FLASH_CFG_FILEVISIBLE ;
714
+ gflashConfig .fileEncWindowStart = 0 ;
715
+ gflashConfig .fileEncWindowEnd = 0 ;
652
716
}
653
717
i2c_fillBuffer ((uint8_t * ) pI2cCommand , 0 , 1 );
654
718
break ;
@@ -676,8 +740,6 @@ static void i2c_write_flash_callback(uint8_t* pData, uint8_t size) {
676
740
}
677
741
678
742
static void i2c_read_flash_callback (uint8_t * pData , uint8_t size ) {
679
- i2c_clearBuffer ();
680
-
681
743
// Release COMBINED_SENSOR_INT
682
744
PORT_SetPinMux (COMBINED_SENSOR_INT_PORT , COMBINED_SENSOR_INT_PIN , kPORT_PinDisabledOrAnalog );
683
745
}
0 commit comments