@@ -160,7 +160,7 @@ static cy_en_sysclk_status_t spi_init_clock(spi_obj_t *obj, uint32_t frequency)
160
160
// Delay (in us) required for serialized read operation == 1.5 clocks, min 1us.
161
161
obj -> clk_delay = (1500000UL - 1 + obj -> clk_frequency ) / obj -> clk_frequency ;
162
162
Cy_SysClk_PeriphDisableDivider (obj -> div_type , obj -> div_num );
163
- if (Cy_SysClk_PeriphSetDivider (obj -> div_type , obj -> div_num , div_value ) != CY_SYSCLK_SUCCESS ) {
163
+ if (Cy_SysClk_PeriphSetDivider (obj -> div_type , obj -> div_num , div_value - 1 ) != CY_SYSCLK_SUCCESS ) {
164
164
obj -> div_num = CY_INVALID_DIVIDER ;
165
165
}
166
166
Cy_SysClk_PeriphEnableDivider (obj -> div_type , obj -> div_num );
@@ -189,13 +189,23 @@ static void spi_set_pins(spi_obj_t *obj)
189
189
if (obj -> pin_ssel != NC ) {
190
190
pin_function (obj -> pin_ssel , pinmap_function (obj -> pin_ssel , PinMap_SPI_SSEL ));
191
191
}
192
- pin_function (obj -> pin_sclk , pinmap_function (obj -> pin_sclk , PinMap_SPI_SCLK ));
192
+ if (obj -> pin_sclk != NC ) {
193
+ pin_function (obj -> pin_sclk , pinmap_function (obj -> pin_sclk , PinMap_SPI_SCLK ));
194
+ }
193
195
// Pin configuration in PinMap defaults to Master mode; revert for Slave.
194
196
if (obj -> ms_mode == CY_SCB_SPI_SLAVE ) {
195
- pin_mode (obj -> pin_sclk , PullNone );
196
- pin_mode (obj -> pin_mosi , PullNone );
197
- pin_mode (obj -> pin_miso , PushPull );
198
- pin_mode (obj -> pin_ssel , PullNone );
197
+ if (obj -> pin_sclk != NC ) {
198
+ pin_mode (obj -> pin_sclk , PullNone );
199
+ }
200
+ if (obj -> pin_mosi != NC ) {
201
+ pin_mode (obj -> pin_mosi , PullNone );
202
+ }
203
+ if (obj -> pin_miso != NC ) {
204
+ pin_mode (obj -> pin_miso , PushPull );
205
+ }
206
+ if (obj -> pin_ssel != NC ) {
207
+ pin_mode (obj -> pin_ssel , PullNone );
208
+ }
199
209
}
200
210
}
201
211
@@ -206,7 +216,9 @@ static void spi_default_pins(spi_obj_t *obj)
206
216
{
207
217
208
218
if (obj -> ms_mode == CY_SCB_SPI_MASTER ) {
209
- pin_function (obj -> pin_sclk , CY_PIN_FUNCTION (HSIOM_SEL_GPIO , 0 , PullDown , PIN_OUTPUT ));
219
+ if (obj -> pin_sclk != NC ) {
220
+ pin_function (obj -> pin_sclk , CY_PIN_FUNCTION (HSIOM_SEL_GPIO , 0 , PullDown , PIN_OUTPUT ));
221
+ }
210
222
if (obj -> pin_mosi != NC ) {
211
223
pin_function (obj -> pin_mosi , CY_PIN_FUNCTION (HSIOM_SEL_GPIO , 0 , PullUp , PIN_OUTPUT ));
212
224
}
@@ -226,7 +238,11 @@ static void spi_default_pins(spi_obj_t *obj)
226
238
static void spi_init_pins (spi_obj_t * obj )
227
239
{
228
240
bool conflict = false;
229
- conflict = cy_reserve_io_pin (obj -> pin_sclk );
241
+ if (obj -> pin_sclk != NC ) {
242
+ if (cy_reserve_io_pin (obj -> pin_sclk )) {
243
+ conflict = true;
244
+ }
245
+ }
230
246
if (obj -> pin_mosi != NC ) {
231
247
if (cy_reserve_io_pin (obj -> pin_mosi )) {
232
248
conflict = true;
@@ -436,43 +452,70 @@ int spi_master_block_write(spi_t *obj_in, const char *tx_buffer, int tx_length,
436
452
int trans_length = 0 ;
437
453
int rx_count = 0 ;
438
454
int tx_count = 0 ;
439
- uint8_t tx_byte = (uint8_t )write_fill ;
455
+ uint16_t tx_data = (uint8_t )write_fill ;
456
+ uint16_t write_fill16 = (tx_data << 8 ) | tx_data ;
457
+ const uint16_t * tx_buffer16 = (const uint16_t * )tx_buffer ;
458
+ uint16_t * rx_buffer16 = (uint16_t * )rx_buffer ;
440
459
441
460
if (obj -> ms_mode != CY_SCB_SPI_MASTER ) {
442
461
return 0 ;
443
462
}
444
463
464
+ // If single transfer (data bits) is larger than byte, then writing must be performed
465
+ // in words.
466
+ bool word_transfer = !Cy_SCB_IsTxDataWidthByte (obj -> base );
467
+ if (word_transfer ) {
468
+ tx_length /= 2 ;
469
+ rx_length /= 2 ;
470
+ tx_data = write_fill16 ;
471
+ }
445
472
// Make sure no leftovers from previous transactions.
446
473
Cy_SCB_SPI_ClearRxFifo (obj -> base );
447
- // Calculate transaction length,
474
+ // Calculate transaction length.
448
475
trans_length = (tx_length > rx_length )? tx_length : rx_length ;
449
476
// get first byte to transmit.
450
477
if (tx_count < tx_length ) {
451
- tx_byte = * tx_buffer ++ ;
478
+ if (word_transfer ) {
479
+ tx_data = * tx_buffer16 ++ ;
480
+ } else {
481
+ tx_data = * tx_buffer ++ ;
482
+ }
452
483
}
453
484
// Send required number of bytes.
454
485
while (tx_count < trans_length ) {
455
- if (Cy_SCB_SPI_Write (obj -> base , tx_byte )) {
486
+ if (Cy_SCB_SPI_Write (obj -> base , tx_data )) {
456
487
++ tx_count ;
457
488
// Get next byte to transfer.
458
489
if (tx_count < tx_length ) {
459
- tx_byte = * tx_buffer ++ ;
490
+ if (word_transfer ) {
491
+ tx_data = * tx_buffer16 ++ ;
492
+ } else {
493
+ tx_data = * tx_buffer ++ ;
494
+ }
460
495
} else {
461
- tx_byte = ( uint8_t ) write_fill ;
496
+ tx_data = write_fill16 ;
462
497
}
463
498
}
464
499
// If we have bytes to receive check the rx fifo.
465
500
if (rx_count < rx_length ) {
466
501
if (Cy_SCB_SPI_GetNumInRxFifo (obj -> base ) > 0 ) {
467
- * rx_buffer ++ = (char )Cy_SCB_SPI_Read (obj -> base );
502
+ if (word_transfer ) {
503
+ * rx_buffer16 ++ = (uint16_t )Cy_SCB_SPI_Read (obj -> base );
504
+ } else {
505
+ * rx_buffer ++ = (char )Cy_SCB_SPI_Read (obj -> base );
506
+ }
468
507
++ rx_count ;
469
508
}
470
509
}
471
510
}
472
511
// Wait for tx fifo to empty while reading received bytes.
473
512
while (!Cy_SCB_SPI_IsTxComplete (obj -> base )) {
474
513
if ((rx_count < rx_length ) && (Cy_SCB_SPI_GetNumInRxFifo (obj -> base ) > 0 )) {
475
- * rx_buffer ++ = (char )Cy_SCB_SPI_Read (obj -> base );
514
+ if (word_transfer ) {
515
+ * rx_buffer16 ++ = (uint16_t )Cy_SCB_SPI_Read (obj -> base );
516
+ } else {
517
+ * rx_buffer ++ = (char )Cy_SCB_SPI_Read (obj -> base );
518
+ }
476
519
++ rx_count ;
477
520
}
478
521
}
@@ -481,12 +524,16 @@ int spi_master_block_write(spi_t *obj_in, const char *tx_buffer, int tx_length,
481
524
Cy_SysLib_DelayUs (obj -> clk_delay );
482
525
// Read any remaining bytes from the fifo.
483
526
while (rx_count < rx_length ) {
484
- * rx_buffer ++ = (char )Cy_SCB_SPI_Read (obj -> base );
527
+ if (word_transfer ) {
528
+ * rx_buffer16 ++ = (uint16_t )Cy_SCB_SPI_Read (obj -> base );
529
+ } else {
530
+ * rx_buffer ++ = (char )Cy_SCB_SPI_Read (obj -> base );
531
+ }
485
532
++ rx_count ;
486
533
}
487
534
// Clean up if we have read less bytes than available.
488
535
Cy_SCB_SPI_ClearRxFifo (obj -> base );
489
- return trans_length ;
536
+ return word_transfer ? trans_length * 2 : trans_length ;
490
537
}
491
538
492
539
int spi_slave_receive (spi_t * obj_in )
0 commit comments