@@ -939,6 +939,33 @@ static inline int datasize_to_transfer_bitshift(uint32_t DataSize)
939
939
}
940
940
}
941
941
942
+ static inline int spi_get_word_from_buffer (const void * buffer , int bitshift )
943
+ {
944
+ if (bitshift == 1 ) {
945
+ return * ((uint16_t * )buffer );
946
+ #ifdef HAS_32BIT_SPI_TRANSFERS
947
+ } else if (bitshift == 2 ) {
948
+ return * ((uint32_t * )buffer );
949
+ #endif /* HAS_32BIT_SPI_TRANSFERS */
950
+ } else {
951
+ return * ((uint8_t * )buffer );
952
+ }
953
+ }
954
+
955
+ static inline void spi_put_word_to_buffer (void * buffer , int bitshift , int data )
956
+ {
957
+ if (bitshift == 1 ) {
958
+ * ((uint16_t * )buffer ) = data ;
959
+ #ifdef HAS_32BIT_SPI_TRANSFERS
960
+ } else if (bitshift == 2 ) {
961
+ * ((uint32_t * )buffer ) = data ;
962
+ #endif /* HAS_32BIT_SPI_TRANSFERS */
963
+ } else {
964
+ * ((uint8_t * )buffer ) = data ;
965
+ }
966
+ }
967
+
968
+
942
969
/**
943
970
* Check if SPI master interface is writable.
944
971
*
@@ -1057,6 +1084,7 @@ static int spi_master_one_wire_transfer(spi_t *obj, const char *tx_buffer, int t
1057
1084
SPI_HandleTypeDef * handle = & (spiobj -> handle );
1058
1085
const int bitshift = datasize_to_transfer_bitshift (handle -> Init .DataSize );
1059
1086
MBED_ASSERT (bitshift >= 0 );
1087
+ const int word_size = 0x01 << bitshift ;
1060
1088
1061
1089
/* Ensure that spi is disabled */
1062
1090
LL_SPI_Disable (SPI_INST (obj ));
@@ -1066,17 +1094,17 @@ static int spi_master_one_wire_transfer(spi_t *obj, const char *tx_buffer, int t
1066
1094
LL_SPI_SetTransferDirection (SPI_INST (obj ), LL_SPI_HALF_DUPLEX_TX );
1067
1095
#if defined(SPI_IP_VERSION_V2 )
1068
1096
/* Set transaction size */
1069
- LL_SPI_SetTransferSize (SPI_INST (obj ), tx_length );
1097
+ LL_SPI_SetTransferSize (SPI_INST (obj ), tx_length >> bitshift );
1070
1098
#endif /* SPI_IP_VERSION_V2 */
1071
1099
LL_SPI_Enable (SPI_INST (obj ));
1072
1100
#if defined(SPI_IP_VERSION_V2 )
1073
1101
/* Master transfer start */
1074
1102
LL_SPI_StartMasterTransfer (SPI_INST (obj ));
1075
1103
#endif /* SPI_IP_VERSION_V2 */
1076
1104
1077
- for (int i = 0 ; i < tx_length ; i ++ ) {
1105
+ for (int i = 0 ; i < tx_length ; i += word_size ) {
1078
1106
msp_wait_writable (obj );
1079
- msp_write_data (obj , tx_buffer [ i ] , bitshift );
1107
+ msp_write_data (obj , spi_get_word_from_buffer ( tx_buffer + i , bitshift ) , bitshift );
1080
1108
}
1081
1109
1082
1110
/* Wait end of transaction */
@@ -1098,14 +1126,14 @@ static int spi_master_one_wire_transfer(spi_t *obj, const char *tx_buffer, int t
1098
1126
LL_SPI_SetTransferDirection (SPI_INST (obj ), LL_SPI_HALF_DUPLEX_RX );
1099
1127
#if defined(SPI_IP_VERSION_V2 )
1100
1128
/* Set transaction size and run SPI */
1101
- LL_SPI_SetTransferSize (SPI_INST (obj ), rx_length );
1129
+ LL_SPI_SetTransferSize (SPI_INST (obj ), rx_length >> bitshift );
1102
1130
LL_SPI_Enable (SPI_INST (obj ));
1103
1131
LL_SPI_StartMasterTransfer (SPI_INST (obj ));
1104
1132
1105
1133
/* Receive data */
1106
- for (int i = 0 ; i < rx_length ; i ++ ) {
1134
+ for (int i = 0 ; i < rx_length ; i += word_size ) {
1107
1135
msp_wait_readable (obj );
1108
- rx_buffer [ i ] = msp_read_data (obj , bitshift );
1136
+ spi_put_word_to_buffer ( rx_buffer + i , bitshift , msp_read_data (obj , bitshift ) );
1109
1137
}
1110
1138
1111
1139
/* Stop SPI */
@@ -1134,7 +1162,7 @@ static int spi_master_one_wire_transfer(spi_t *obj, const char *tx_buffer, int t
1134
1162
/* get estimation about one SPI clock cycle */
1135
1163
uint32_t baudrate_period_ns = 1000000000 / spi_get_baudrate (obj );
1136
1164
1137
- for (int i = 0 ; i < rx_length ; i ++ ) {
1165
+ for (int i = 0 ; i < rx_length ; i += word_size ) {
1138
1166
core_util_critical_section_enter ();
1139
1167
LL_SPI_Enable (SPI_INST (obj ));
1140
1168
/* Wait single SPI clock cycle. */
@@ -1143,7 +1171,7 @@ static int spi_master_one_wire_transfer(spi_t *obj, const char *tx_buffer, int t
1143
1171
core_util_critical_section_exit ();
1144
1172
1145
1173
msp_wait_readable (obj );
1146
- rx_buffer [ i ] = msp_read_data (obj , bitshift );
1174
+ spi_put_word_to_buffer ( rx_buffer + i , bitshift , msp_read_data (obj , bitshift ) );
1147
1175
}
1148
1176
1149
1177
#endif /* SPI_IP_VERSION_V2 */
@@ -1198,13 +1226,25 @@ int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length,
1198
1226
{
1199
1227
struct spi_s * spiobj = SPI_S (obj );
1200
1228
SPI_HandleTypeDef * handle = & (spiobj -> handle );
1229
+ const int bitshift = datasize_to_transfer_bitshift (handle -> Init .DataSize );
1230
+ /* check buffer sizes are multiple of spi word size */
1231
+ MBED_ASSERT (tx_length >> bitshift << bitshift == tx_length );
1232
+ MBED_ASSERT (rx_length >> bitshift << bitshift == rx_length );
1201
1233
int total = (tx_length > rx_length ) ? tx_length : rx_length ;
1234
+
1202
1235
if (handle -> Init .Direction == SPI_DIRECTION_2LINES ) {
1203
- for (int i = 0 ; i < total ; i ++ ) {
1204
- char out = (i < tx_length ) ? tx_buffer [i ] : write_fill ;
1205
- char in = spi_master_write (obj , out );
1236
+ int write_fill_frame = write_fill ;
1237
+ /* extend fill symbols for 16/32 bit modes */
1238
+ for (int i = 0 ; i < bitshift ; i ++ ) {
1239
+ write_fill_frame = (write_fill_frame << 8 ) | write_fill ;
1240
+ }
1241
+
1242
+ const int word_size = 0x01 << bitshift ;
1243
+ for (int i = 0 ; i < total ; i += word_size ) {
1244
+ int out = (i < tx_length ) ? spi_get_word_from_buffer (tx_buffer + i , bitshift ) : write_fill_frame ;
1245
+ int in = spi_master_write (obj , out );
1206
1246
if (i < rx_length ) {
1207
- rx_buffer [ i ] = in ;
1247
+ spi_put_word_to_buffer ( rx_buffer + i , bitshift , in ) ;
1208
1248
}
1209
1249
}
1210
1250
} else {
@@ -1349,6 +1389,11 @@ static int spi_master_start_asynch_transfer(spi_t *obj, transfer_type_t transfer
1349
1389
1350
1390
// enable the right hal transfer
1351
1391
int rc = 0 ;
1392
+ #if defined(SPI_IP_VERSION_V2 )
1393
+ // HAL SPI API assumes that SPI disabled between transfers and
1394
+ // doesn't work properly if SPI is enabled.
1395
+ LL_SPI_Disable (SPI_INST (obj ));
1396
+ #endif
1352
1397
switch (transfer_type ) {
1353
1398
case SPI_TRANSFER_TYPE_TXRX :
1354
1399
rc = HAL_SPI_TransmitReceive_IT (handle , (uint8_t * )tx , (uint8_t * )rx , words );
@@ -1367,6 +1412,12 @@ static int spi_master_start_asynch_transfer(spi_t *obj, transfer_type_t transfer
1367
1412
}
1368
1413
1369
1414
if (rc ) {
1415
+ #if defined(SPI_IP_VERSION_V2 )
1416
+ // enable SPI back in case of error
1417
+ if (handle -> Init .Direction != SPI_DIRECTION_1LINE ) {
1418
+ LL_SPI_Enable (SPI_INST (obj ));
1419
+ }
1420
+ #endif
1370
1421
DEBUG_PRINTF ("SPI: RC=%u\n" , rc );
1371
1422
length = 0 ;
1372
1423
}
@@ -1466,6 +1517,16 @@ inline uint32_t spi_irq_handler_asynch(spi_t *obj)
1466
1517
*/
1467
1518
spi_flush_rx (obj );
1468
1519
}
1520
+ #else
1521
+ // reset transfer size
1522
+ LL_SPI_SetTransferSize (SPI_INST (obj ), 0 );
1523
+
1524
+ // HAL_SPI_TransmitReceive_IT/HAL_SPI_Transmit_IT/HAL_SPI_Receive_IT
1525
+ // function disable SPI after transfer. So we need enabled it back,
1526
+ // otherwise spi_master_block_write/spi_master_write won't work in 4-wire mode.
1527
+ if (handle -> Init .Direction != SPI_DIRECTION_1LINE ) {
1528
+ LL_SPI_Enable (SPI_INST (obj ));
1529
+ }
1469
1530
#endif /* SPI_IP_VERSION_V2 */
1470
1531
}
1471
1532
0 commit comments