@@ -48,6 +48,16 @@ void spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap) {
48
48
}
49
49
}
50
50
51
+ SPIName spi_get_peripheral_name (PinName mosi , PinName miso , PinName sclk )
52
+ {
53
+ SPIName spi_mosi = (SPIName )pinmap_peripheral (mosi , PinMap_SPI_MOSI );
54
+ SPIName spi_miso = (SPIName )pinmap_peripheral (miso , PinMap_SPI_MISO );
55
+ SPIName spi_sclk = (SPIName )pinmap_peripheral (sclk , PinMap_SPI_SCLK );
56
+ SPIName spi_data = (SPIName )pinmap_merge (spi_mosi , spi_miso );
57
+ SPIName spi_periph = (SPIName )pinmap_merge (spi_sclk , spi_data );
58
+ return spi_periph ;
59
+ }
60
+
51
61
void spi_init (spi_t * obj , PinName mosi , PinName miso , PinName sclk , PinName ssel ) {
52
62
spi_pinmap_t pinmap ;
53
63
pinmap .mosi_pin = mosi ;
@@ -56,14 +66,10 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
56
66
pinmap .ssel_pin = ssel ;
57
67
58
68
// determine the SPI to use
59
- SPIName spi_mosi = (SPIName )pinmap_peripheral (mosi , PinMap_SPI_MOSI );
60
- SPIName spi_miso = (SPIName )pinmap_peripheral (miso , PinMap_SPI_MISO );
61
- SPIName spi_sclk = (SPIName )pinmap_peripheral (sclk , PinMap_SPI_SCLK );
62
- SPIName spi_ssel = (SPIName )pinmap_peripheral (ssel , PinMap_SPI_SSEL );
63
- SPIName spi_data = (SPIName )pinmap_merge (spi_mosi , spi_miso );
64
- SPIName spi_cntl = (SPIName )pinmap_merge (spi_sclk , spi_ssel );
65
- pinmap .peripheral = pinmap_merge (spi_data , spi_cntl );
66
- MBED_ASSERT ((int )obj -> spi != NC );
69
+ SPIName spi_mosi_miso_sclk_periph = spi_get_peripheral_name (mosi , miso , sclk );
70
+ SPIName spi_ssel_periph = (SPIName )pinmap_peripheral (ssel , PinMap_SPI_SSEL );
71
+ pinmap .peripheral = pinmap_merge (spi_mosi_miso_sclk_periph , spi_ssel_periph );
72
+ MBED_ASSERT (pinmap .peripheral != NC );
67
73
68
74
// Get pin functions
69
75
pinmap .mosi_function = pinmap_find_function (mosi , PinMap_SPI_MOSI );
@@ -80,6 +86,7 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) {
80
86
ssp_disable (obj );
81
87
MBED_ASSERT (((bits >= 4 ) && (bits <= 16 )) && (mode >= 0 && mode <= 3 ));
82
88
89
+ obj -> bits_per_word = bits ;
83
90
int polarity = (mode & 0x2 ) ? 1 : 0 ;
84
91
int phase = (mode & 0x1 ) ? 1 : 0 ;
85
92
@@ -186,11 +193,39 @@ int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length,
186
193
char * rx_buffer , int rx_length , char write_fill ) {
187
194
int total = (tx_length > rx_length ) ? tx_length : rx_length ;
188
195
189
- for (int i = 0 ; i < total ; i ++ ) {
190
- char out = (i < tx_length ) ? tx_buffer [i ] : write_fill ;
191
- char in = spi_master_write (obj , out );
192
- if (i < rx_length ) {
193
- rx_buffer [i ] = in ;
196
+ if (obj -> bits_per_word > 8 ) {
197
+ // 2 bytes per write/read operation
198
+ MBED_ASSERT (tx_length % 2 == 0 );
199
+ MBED_ASSERT (rx_length % 2 == 0 );
200
+
201
+ // Extend write fill value to 16 bits
202
+ const uint16_t write_fill_u16 = (((uint16_t )write_fill ) << 8 ) | write_fill ;
203
+
204
+ // Access input and output arrays as 16-bit words.
205
+ // This might do unaligned access, but that's OK for integers on Cortex-M3
206
+ uint16_t const * const tx_buffer_u16 = (uint16_t const * )tx_buffer ;
207
+ uint16_t * const rx_buffer_u16 = (uint16_t * )rx_buffer ;
208
+
209
+ const int tx_length_u16 = tx_length / 2 ;
210
+ const int rx_length_u16 = rx_length / 2 ;
211
+
212
+ for (int i = 0 ; i < total / 2 ; i ++ ) {
213
+ uint16_t out = (i < tx_length_u16 ) ? tx_buffer_u16 [i ] : write_fill_u16 ;
214
+ uint16_t in = spi_master_write (obj , out );
215
+ if (i < rx_length_u16 ) {
216
+ rx_buffer_u16 [i ] = in ;
217
+ printf ("rx_buffer_u16[%d] <= 0x%hx\n" , i , in );
218
+ }
219
+ }
220
+ }
221
+ else {
222
+ // 1 byte per read/write operation
223
+ for (int i = 0 ; i < total ; i ++ ) {
224
+ uint16_t out = (i < tx_length ) ? tx_buffer [i ] : write_fill ;
225
+ uint16_t in = spi_master_write (obj , out );
226
+ if (i < rx_length ) {
227
+ rx_buffer [i ] = in ;
228
+ }
194
229
}
195
230
}
196
231
0 commit comments