Skip to content

Commit 734072f

Browse files
authored
Merge pull request #11599 from lrusinowicz/spi_fixes
FUTURE_SEQUANA: SPI HAL API fixes
2 parents 8ff5cf9 + a690bf3 commit 734072f

File tree

1 file changed

+65
-18
lines changed
  • targets/TARGET_Cypress/TARGET_PSOC6_FUTURE

1 file changed

+65
-18
lines changed

targets/TARGET_Cypress/TARGET_PSOC6_FUTURE/spi_api.c

Lines changed: 65 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -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)
226238
static 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

492539
int spi_slave_receive(spi_t *obj_in)

0 commit comments

Comments
 (0)