@@ -366,6 +366,7 @@ typedef enum {
366366 SPI_BUS_FLASH ,
367367 SPI_BUS_DISCARD ,
368368 SPI_BUS_ERROR ,
369+ SPI_BUS_DISCARD_PACKET ,
369370} OtSpiBusState ;
370371
371372typedef enum {
@@ -601,6 +602,7 @@ static const char *BUS_STATE_NAMES[] = {
601602 STATE_NAME_ENTRY (SPI_BUS_FLASH ),
602603 STATE_NAME_ENTRY (SPI_BUS_DISCARD ),
603604 STATE_NAME_ENTRY (SPI_BUS_ERROR ),
605+ STATE_NAME_ENTRY (SPI_BUS_DISCARD_PACKET ),
604606};
605607
606608static const char * FLASH_STATE_NAMES [] = {
@@ -1924,6 +1926,12 @@ static void ot_spi_device_chr_handle_header(OtSPIDeviceState *s)
19241926 return ;
19251927 }
19261928
1929+ /* discard the packet if we're within a failed transaction */
1930+ if (s -> bus .state == SPI_BUS_DISCARD_PACKET ) {
1931+ BUS_CHANGE_STATE (s , DISCARD );
1932+ return ;
1933+ }
1934+
19271935 switch (ot_spi_device_get_mode (s )) {
19281936 case CTRL_MODE_FLASH :
19291937 BUS_CHANGE_STATE (s , FLASH );
@@ -1984,6 +1992,7 @@ static int ot_spi_device_chr_can_receive(void *opaque)
19841992 unsigned length ;
19851993
19861994 switch (bus -> state ) {
1995+ case SPI_BUS_DISCARD_PACKET :
19871996 case SPI_BUS_IDLE :
19881997 length = fifo8_num_free (& bus -> chr_fifo );
19891998 break ;
@@ -2013,6 +2022,7 @@ static void ot_spi_device_chr_receive(void *opaque, const uint8_t *buf,
20132022
20142023 switch (bus -> state ) {
20152024 case SPI_BUS_IDLE :
2025+ case SPI_BUS_DISCARD_PACKET :
20162026 g_assert (size <= fifo8_num_free (& bus -> chr_fifo ));
20172027 while (size -- ) {
20182028 fifo8_push (& bus -> chr_fifo , * buf ++ );
@@ -2034,12 +2044,31 @@ static void ot_spi_device_chr_receive(void *opaque, const uint8_t *buf,
20342044 break ;
20352045 }
20362046
2037- if (!bus -> byte_count ) {
2038- if (bus -> release ) {
2039- ot_spi_device_release (s );
2040- } else {
2047+ if (bus -> byte_count ) {
2048+ /* there is more to process in this state */
2049+ return ;
2050+ }
2051+
2052+ if (bus -> release ) {
2053+ /* final packet in transaction, release CS */
2054+ ot_spi_device_release (s );
2055+ return ;
2056+ }
2057+
2058+ /* more packets to process in transaction, prepare to receive another header */
2059+ switch (bus -> state ) {
2060+ case SPI_BUS_IDLE :
2061+ case SPI_BUS_FLASH :
2062+ case SPI_BUS_DISCARD_PACKET :
20412063 BUS_CHANGE_STATE (s , IDLE );
2042- }
2064+ break ;
2065+ case SPI_BUS_DISCARD :
2066+ case SPI_BUS_ERROR :
2067+ BUS_CHANGE_STATE (s , DISCARD_PACKET );
2068+ break ;
2069+ default :
2070+ g_assert_not_reached ();
2071+ break ;
20432072 }
20442073}
20452074
0 commit comments