@@ -160,7 +160,7 @@ static cy_en_sysclk_status_t spi_init_clock(spi_obj_t *obj, uint32_t frequency)
160160 // Delay (in us) required for serialized read operation == 1.5 clocks, min 1us.
161161 obj -> clk_delay = (1500000UL - 1 + obj -> clk_frequency ) / obj -> clk_frequency ;
162162 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 ) {
164164 obj -> div_num = CY_INVALID_DIVIDER ;
165165 }
166166 Cy_SysClk_PeriphEnableDivider (obj -> div_type , obj -> div_num );
@@ -189,13 +189,23 @@ static void spi_set_pins(spi_obj_t *obj)
189189 if (obj -> pin_ssel != NC ) {
190190 pin_function (obj -> pin_ssel , pinmap_function (obj -> pin_ssel , PinMap_SPI_SSEL ));
191191 }
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+ }
193195 // Pin configuration in PinMap defaults to Master mode; revert for Slave.
194196 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+ }
199209 }
200210}
201211
@@ -206,7 +216,9 @@ static void spi_default_pins(spi_obj_t *obj)
206216{
207217
208218 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+ }
210222 if (obj -> pin_mosi != NC ) {
211223 pin_function (obj -> pin_mosi , CY_PIN_FUNCTION (HSIOM_SEL_GPIO , 0 , PullUp , PIN_OUTPUT ));
212224 }
@@ -226,7 +238,11 @@ static void spi_default_pins(spi_obj_t *obj)
226238static void spi_init_pins (spi_obj_t * obj )
227239{
228240 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+ }
230246 if (obj -> pin_mosi != NC ) {
231247 if (cy_reserve_io_pin (obj -> pin_mosi )) {
232248 conflict = true;
@@ -436,43 +452,70 @@ int spi_master_block_write(spi_t *obj_in, const char *tx_buffer, int tx_length,
436452 int trans_length = 0 ;
437453 int rx_count = 0 ;
438454 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 ;
440459
441460 if (obj -> ms_mode != CY_SCB_SPI_MASTER ) {
442461 return 0 ;
443462 }
444463
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+ }
445472 // Make sure no leftovers from previous transactions.
446473 Cy_SCB_SPI_ClearRxFifo (obj -> base );
447- // Calculate transaction length,
474+ // Calculate transaction length.
448475 trans_length = (tx_length > rx_length )? tx_length : rx_length ;
449476 // get first byte to transmit.
450477 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+ }
452483 }
453484 // Send required number of bytes.
454485 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 )) {
456487 ++ tx_count ;
457488 // Get next byte to transfer.
458489 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+ }
460495 } else {
461- tx_byte = ( uint8_t ) write_fill ;
496+ tx_data = write_fill16 ;
462497 }
463498 }
464499 // If we have bytes to receive check the rx fifo.
465500 if (rx_count < rx_length ) {
466501 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+ }
468507 ++ rx_count ;
469508 }
470509 }
471510 }
472511 // Wait for tx fifo to empty while reading received bytes.
473512 while (!Cy_SCB_SPI_IsTxComplete (obj -> base )) {
474513 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+ }
476519 ++ rx_count ;
477520 }
478521 }
@@ -481,12 +524,16 @@ int spi_master_block_write(spi_t *obj_in, const char *tx_buffer, int tx_length,
481524 Cy_SysLib_DelayUs (obj -> clk_delay );
482525 // Read any remaining bytes from the fifo.
483526 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+ }
485532 ++ rx_count ;
486533 }
487534 // Clean up if we have read less bytes than available.
488535 Cy_SCB_SPI_ClearRxFifo (obj -> base );
489- return trans_length ;
536+ return word_transfer ? trans_length * 2 : trans_length ;
490537}
491538
492539int spi_slave_receive (spi_t * obj_in )
0 commit comments