Skip to content

Commit 160a771

Browse files
authored
Merge pull request #9647 from lrusinowicz/sequana_spi_fixes
FUTURE_SEQUANA: SPI HAL fixes
2 parents 10bb66a + 2f6684b commit 160a771

File tree

7 files changed

+268
-1837
lines changed

7 files changed

+268
-1837
lines changed

targets/TARGET_Cypress/TARGET_PSOC6_FUTURE/TARGET_CY8C63XX/TARGET_MCU_PSOC6_M4/hex/psoc63_m0_ble_controller_1.01.hex

Lines changed: 0 additions & 1655 deletions
This file was deleted.

targets/TARGET_Cypress/TARGET_PSOC6_FUTURE/TARGET_CY8C63XX/TARGET_MCU_PSOC6_M4/hex/psoc63_m0_default_1.02.hex

Lines changed: 0 additions & 146 deletions
This file was deleted.

targets/TARGET_Cypress/TARGET_PSOC6_FUTURE/TARGET_CY8C63XX/TARGET_MCU_PSOC6_M4/hex/psoc63_m0_default_1.03.hex

Lines changed: 146 additions & 0 deletions
Large diffs are not rendered by default.

targets/TARGET_Cypress/TARGET_PSOC6_FUTURE/objects.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,8 @@ struct port_s {
5353
uint32_t mask;
5454
PinDirection direction;
5555
PinMode mode;
56-
// __IO uint32_t *reg_in;
57-
// __IO uint32_t *reg_out;
5856
};
5957

60-
// struct analogin_s {
61-
// ADCName adc;
62-
// PinName pin;
63-
// uint32_t channel;
64-
// };
65-
6658
#if DEVICE_SERIAL
6759
#include "cy_scb_uart.h"
6860

@@ -107,6 +99,7 @@ struct spi_s {
10799
uint32_t div_num;
108100
cy_en_divider_types_t div_type;
109101
uint32_t clk_frequency;
102+
uint32_t clk_delay;
110103
cy_en_scb_spi_mode_t ms_mode;
111104
cy_en_scb_spi_sclk_mode_t clk_mode;
112105
uint8_t data_bits;

targets/TARGET_Cypress/TARGET_PSOC6_FUTURE/pinmap.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,21 @@ void pin_function(PinName pin, int function)
2626
if (pin != NC) {
2727
GPIO_PRT_Type *port = Cy_GPIO_PortToAddr(CY_PORT(pin));
2828
uint32_t mode = gpio_get_cy_drive_mode(CY_PIN_DIRECTION(function), CY_PIN_MODE(function));
29+
uint32_t state = Cy_GPIO_ReadOut(port, CY_PIN(pin));
2930

30-
Cy_GPIO_Pin_FastInit(port, CY_PIN(pin), mode, 1, CY_PIN_HSIOM(function));
3131
// Force output to enable pulls.
3232
switch (mode) {
3333
case CY_GPIO_DM_PULLUP:
34-
Cy_GPIO_Write(port, CY_PIN(pin), 1);
34+
state = 1;
3535
break;
3636
case CY_GPIO_DM_PULLDOWN:
37-
Cy_GPIO_Write(port, CY_PIN(pin), 0);
37+
state = 0;
3838
break;
3939
default:
4040
/* do nothing */
4141
break;
4242
}
43+
Cy_GPIO_Pin_FastInit(port, CY_PIN(pin), mode, state, CY_PIN_HSIOM(function));
4344
}
4445
}
4546

targets/TARGET_Cypress/TARGET_PSOC6_FUTURE/spi_api.c

Lines changed: 116 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@ static IRQn_Type spi_irq_allocate_channel(spi_obj_t *obj)
8787
#endif // M0
8888
}
8989

90-
static void spi_irq_release_channel(IRQn_Type channel, uint32_t spi_id)
90+
static void spi_irq_release_channel(spi_obj_t *obj)
9191
{
9292
#if defined (TARGET_MCU_PSOC6_M0)
93-
cy_m0_nvic_release_channel(channel, CY_SERIAL_IRQN_ID + spi_id);
93+
cy_m0_nvic_release_channel(obj->irqn, CY_SERIAL_IRQN_ID + obj->spi_id);
9494
#endif //M0
9595
}
9696

@@ -130,6 +130,14 @@ static int allocate_divider(spi_obj_t *obj)
130130
return (obj->div_num == CY_INVALID_DIVIDER)? -1 : 0;
131131
}
132132

133+
static void free_divider(spi_obj_t *obj)
134+
{
135+
if (obj->div_num != CY_INVALID_DIVIDER) {
136+
cy_clk_free_divider(obj->div_type, obj->div_num);
137+
obj->div_num = CY_INVALID_DIVIDER;
138+
}
139+
}
140+
133141

134142
/*
135143
* Initializes spi clock for the required speed
@@ -149,6 +157,8 @@ static cy_en_sysclk_status_t spi_init_clock(spi_obj_t *obj, uint32_t frequency)
149157
// Set up proper frequency; round up the divider so the frequency is not higher than specified.
150158
div_value = (CY_CLK_PERICLK_FREQ_HZ + frequency *(SPI_OVERSAMPLE - 1)) / frequency / SPI_OVERSAMPLE;
151159
obj->clk_frequency = CY_CLK_PERICLK_FREQ_HZ / div_value / SPI_OVERSAMPLE;
160+
// Delay (in us) required for serialized read operation == 1.5 clocks, min 1us.
161+
obj->clk_delay = (1500000UL - 1 + obj->clk_frequency) / obj->clk_frequency;
152162
Cy_SysClk_PeriphDisableDivider(obj->div_type, obj->div_num);
153163
if (Cy_SysClk_PeriphSetDivider(obj->div_type, obj->div_num, div_value) != CY_SYSCLK_SUCCESS) {
154164
obj->div_num = CY_INVALID_DIVIDER;
@@ -165,48 +175,77 @@ static cy_en_sysclk_status_t spi_init_clock(spi_obj_t *obj, uint32_t frequency)
165175
return CY_SYSCLK_SUCCESS;
166176
}
167177

178+
/*
179+
* Sets up i/o connections for spi.
180+
*/
181+
static void spi_set_pins(spi_obj_t *obj)
182+
{
183+
if (obj->pin_mosi != NC) {
184+
pin_function(obj->pin_mosi, pinmap_function(obj->pin_mosi, PinMap_SPI_MOSI));
185+
}
186+
if (obj->pin_miso != NC) {
187+
pin_function(obj->pin_miso, pinmap_function(obj->pin_miso, PinMap_SPI_MISO));
188+
}
189+
if (obj->pin_ssel != NC) {
190+
pin_function(obj->pin_ssel, pinmap_function(obj->pin_ssel, PinMap_SPI_SSEL));
191+
}
192+
pin_function(obj->pin_sclk, pinmap_function(obj->pin_sclk, PinMap_SPI_SCLK));
193+
// Pin configuration in PinMap defaults to Master mode; revert for Slave.
194+
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);
199+
}
200+
}
201+
202+
/*
203+
* Sets i/o output pins into safe mode while re-configuring peripheral.
204+
*/
205+
static void spi_default_pins(spi_obj_t *obj)
206+
{
207+
208+
if (obj->ms_mode == CY_SCB_SPI_MASTER) {
209+
pin_function(obj->pin_sclk, CY_PIN_FUNCTION(HSIOM_SEL_GPIO, 0, PullDown, PIN_OUTPUT));
210+
if (obj->pin_mosi != NC) {
211+
pin_function(obj->pin_mosi, CY_PIN_FUNCTION(HSIOM_SEL_GPIO, 0, PullUp, PIN_OUTPUT));
212+
}
213+
if (obj->pin_ssel != NC) {
214+
pin_function(obj->pin_ssel, CY_PIN_FUNCTION(HSIOM_SEL_GPIO, 0, PullUp, PIN_OUTPUT));
215+
}
216+
} else {
217+
if (obj->pin_miso != NC) {
218+
pin_function(obj->pin_miso, CY_PIN_FUNCTION(HSIOM_SEL_GPIO, 0, PullUp, PIN_OUTPUT));
219+
}
220+
}
221+
}
222+
168223
/*
169224
* Initializes i/o pins for spi.
170225
*/
171226
static void spi_init_pins(spi_obj_t *obj)
172227
{
173228
bool conflict = false;
174229
conflict = cy_reserve_io_pin(obj->pin_sclk);
175-
if (!conflict) {
176-
pin_function(obj->pin_sclk, pinmap_function(obj->pin_sclk, PinMap_SPI_SCLK));
177-
}
178230
if (obj->pin_mosi != NC) {
179-
if (!cy_reserve_io_pin(obj->pin_mosi)) {
180-
pin_function(obj->pin_mosi, pinmap_function(obj->pin_mosi, PinMap_SPI_MOSI));
181-
} else {
231+
if (cy_reserve_io_pin(obj->pin_mosi)) {
182232
conflict = true;
183233
}
184234
}
185235
if (obj->pin_miso != NC) {
186-
if (!cy_reserve_io_pin(obj->pin_miso)) {
187-
pin_function(obj->pin_miso, pinmap_function(obj->pin_miso, PinMap_SPI_MISO));
188-
} else {
236+
if (cy_reserve_io_pin(obj->pin_miso)) {
189237
conflict = true;
190238
}
191239
}
192240
if (obj->pin_ssel != NC) {
193-
if (!cy_reserve_io_pin(obj->pin_ssel)) {
194-
pin_function(obj->pin_ssel, pinmap_function(obj->pin_ssel, PinMap_SPI_SSEL));
195-
} else {
241+
if (cy_reserve_io_pin(obj->pin_ssel)) {
196242
conflict = true;
197243
}
198244
}
199245
if (conflict) {
200246
error("SPI pin reservation conflict.");
201247
}
202-
203-
// Pin configuration in PinMap defaults to Master mode; revert for Slave.
204-
if (obj->ms_mode == CY_SCB_SPI_SLAVE) {
205-
pin_mode(obj->pin_sclk, PullNone);
206-
pin_mode(obj->pin_mosi, PullNone);
207-
pin_mode(obj->pin_miso, PushPull);
208-
pin_mode(obj->pin_ssel, PullNone);
209-
}
248+
spi_set_pins(obj);
210249
}
211250

212251
/*
@@ -282,8 +321,8 @@ void spi_init(spi_t *obj_in, PinName mosi, PinName miso, PinName sclk, PinName s
282321
obj->rx_buffer_size = 0;
283322
#endif // DEVICE_SPI_ASYNCH
284323
spi_init_clock(obj, SPI_DEFAULT_SPEED);
285-
spi_init_pins(obj);
286324
spi_init_peripheral(obj);
325+
spi_init_pins(obj);
287326
#if DEVICE_SLEEP && DEVICE_LOWPOWERTIMER
288327
obj->pm_callback_handler.callback = spi_pm_callback;
289328
obj->pm_callback_handler.type = CY_SYSPM_DEEPSLEEP;
@@ -300,27 +339,73 @@ void spi_init(spi_t *obj_in, PinName mosi, PinName miso, PinName sclk, PinName s
300339
}
301340
}
302341

342+
343+
void spi_free(spi_t *obj_in)
344+
{
345+
spi_obj_t *obj = OBJ_P(obj_in);
346+
347+
spi_default_pins(obj);
348+
Cy_SCB_SPI_Disable(obj->base, &obj->context);
349+
Cy_SCB_SPI_DeInit (obj->base);
350+
351+
#if DEVICE_SLEEP && DEVICE_LOWPOWERTIMER
352+
Cy_SysPm_UnregisterCallback(&obj->pm_callback_handler);
353+
#endif // DEVICE_SLEEP && DEVICE_LOWPOWERTIMER
354+
355+
#if DEVICE_SPI_ASYNCH
356+
if (obj->irqn != unconnected_IRQn) {
357+
NVIC_DisableIRQ(obj->irqn);
358+
spi_irq_release_channel(obj);
359+
360+
obj->irqn = unconnected_IRQn;
361+
}
362+
#endif // DEVICE_SPI_ASYNCH
363+
364+
if (obj->pin_sclk != NC) {
365+
cy_free_io_pin(obj->pin_sclk);
366+
obj->pin_sclk = NC;
367+
}
368+
if (obj->pin_mosi != NC) {
369+
cy_free_io_pin(obj->pin_mosi);
370+
obj->pin_mosi = NC;
371+
}
372+
if (obj->pin_miso != NC) {
373+
cy_free_io_pin(obj->pin_miso);
374+
obj->pin_miso = NC;
375+
}
376+
if (obj->pin_ssel != NC) {
377+
cy_free_io_pin(obj->pin_ssel);
378+
obj->pin_ssel = NC;
379+
}
380+
381+
free_divider(obj);
382+
}
383+
384+
303385
void spi_format(spi_t *obj_in, int bits, int mode, int slave)
304386
{
305387
spi_obj_t *obj = OBJ_P(obj_in);
306388
cy_en_scb_spi_mode_t new_mode = slave? CY_SCB_SPI_SLAVE : CY_SCB_SPI_MASTER;
307389
if ((bits < 4) || (bits > 16)) return;
390+
spi_default_pins(obj);
308391
Cy_SCB_SPI_Disable(obj->base, &obj->context);
309392
obj->data_bits = bits;
310393
obj->clk_mode = (cy_en_scb_spi_sclk_mode_t)(mode & 0x3);
311394
if (obj->ms_mode != new_mode) {
312395
obj->ms_mode = new_mode;
313-
spi_init_pins(obj);
314396
}
315397
spi_init_peripheral(obj);
398+
spi_set_pins(obj);
316399
}
317400

318401
void spi_frequency(spi_t *obj_in, int hz)
319402
{
320403
spi_obj_t *obj = OBJ_P(obj_in);
404+
spi_default_pins(obj);
321405
Cy_SCB_SPI_Disable(obj->base, &obj->context);
322406
spi_init_clock(obj, hz);
323407
Cy_SCB_SPI_Enable(obj->base);
408+
spi_set_pins(obj);
324409
}
325410

326411
int spi_master_write(spi_t *obj_in, int value)
@@ -335,6 +420,10 @@ int spi_master_write(spi_t *obj_in, int value)
335420
while (!Cy_SCB_SPI_IsTxComplete(obj->base)) {
336421
// wait for the transmission to complete
337422
}
423+
// Wait until RX FIFO is filled from the serial register.
424+
while (Cy_SCB_SPI_GetNumInRxFifo(obj->base) == 0) {
425+
/* busy loop */
426+
}
338427
return Cy_SCB_SPI_Read(obj->base);
339428
} else {
340429
return (int)CY_SCB_SPI_RX_NO_DATA;
@@ -387,6 +476,9 @@ int spi_master_block_write(spi_t *obj_in, const char *tx_buffer, int tx_length,
387476
++rx_count;
388477
}
389478
}
479+
// Delay at least 1.5 clock cycle, so that FIFO is filled with the last char
480+
// and SCLK returns to idle state.
481+
Cy_SysLib_DelayUs(obj->clk_delay);
390482
// Read any remaining bytes from the fifo.
391483
while (rx_count < rx_length) {
392484
*rx_buffer++ = (char)Cy_SCB_SPI_Read(obj->base);

targets/targets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7955,7 +7955,7 @@
79557955
"device_has_remove": ["TRNG", "CRC"],
79567956
"macros_add": ["CY8C6347BZI_BLD53"],
79577957
"detect_code": ["6000"],
7958-
"hex_filename": "psoc63_m0_default_1.02.hex",
7958+
"hex_filename": "psoc63_m0_default_1.03.hex",
79597959
"post_binary_hook": {
79607960
"function": "PSOC6Code.complete"
79617961
},

0 commit comments

Comments
 (0)