diff --git a/bsp/Infineon/libraries/HAL_Drivers/drv_spi.c b/bsp/Infineon/libraries/HAL_Drivers/drv_spi.c index cdd1cfa357..0d3c3f2cac 100644 --- a/bsp/Infineon/libraries/HAL_Drivers/drv_spi.c +++ b/bsp/Infineon/libraries/HAL_Drivers/drv_spi.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2022-07-18 Rbb666 first version + * 2023-03-30 Rbb666 update spi driver */ #include @@ -21,52 +22,46 @@ #endif /* DRV_DEBUG */ #include -struct ifx_sw_spi_cs -{ - rt_uint32_t pin; -}; - #ifdef BSP_USING_SPI0 static struct rt_spi_bus spi_bus0; #endif #ifdef BSP_USING_SPI3 static struct rt_spi_bus spi_bus3; #endif - #ifdef BSP_USING_SPI6 static struct rt_spi_bus spi_bus6; #endif -static struct ifx_spi spi_bus_obj[] = + +static struct ifx_spi_handle spi_bus_obj[] = { - #if defined(BSP_USING_SPI0) +#if defined(BSP_USING_SPI0) { .bus_name = "spi0", - .spi_bus = &spi_bus0, .sck_pin = GET_PIN(0, 4), .miso_pin = GET_PIN(0, 3), .mosi_pin = GET_PIN(0, 2), }, - #endif - #if defined(BSP_USING_SPI3) +#endif +#if defined(BSP_USING_SPI3) { .bus_name = "spi3", - .spi_bus = &spi_bus3, .sck_pin = GET_PIN(6, 2), .miso_pin = GET_PIN(6, 1), .mosi_pin = GET_PIN(6, 0), }, - #endif - #if defined(BSP_USING_SPI6) +#endif +#if defined(BSP_USING_SPI6) { .bus_name = "spi6", - .spi_bus = &spi_bus6, .sck_pin = GET_PIN(12, 2), .miso_pin = GET_PIN(12, 1), .mosi_pin = GET_PIN(12, 0), }, - #endif +#endif }; +static struct ifx_spi spi_config[sizeof(spi_bus_obj) / sizeof(spi_bus_obj[0])] = {0}; + /* private rt-thread spi ops function */ static rt_err_t spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration); static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message); @@ -77,39 +72,69 @@ static struct rt_spi_ops ifx_spi_ops = .xfer = spixfer, }; -static void ifx_spi_init(struct ifx_spi *ifx_spi) +static void spi_interrupt_callback(void *arg, cyhal_spi_event_t event) { - int result = RT_EOK; + struct ifx_spi *spi_drv = (struct ifx_spi *)arg; - result = cyhal_spi_init(ifx_spi->spi_obj, ifx_spi->mosi_pin, ifx_spi->miso_pin, ifx_spi->sck_pin, - NC, NULL, ifx_spi->spi_obj->data_bits, ifx_spi->spi_obj->mode, false); + rt_interrupt_enter(); - RT_ASSERT(result == RT_EOK); + if ((event & CYHAL_SPI_IRQ_DONE) != 0u) + { + /* Transmission is complete. Handle Event */ + rt_completion_done(&spi_drv->cpt); + } - rt_kprintf("[%s] Freq:[%d]HZ\n", ifx_spi->bus_name, ifx_spi->freq); + rt_interrupt_leave(); +} - result = cyhal_spi_set_frequency(ifx_spi->spi_obj, ifx_spi->freq); +static void ifx_spi_init(struct ifx_spi *spi_device) +{ + RT_ASSERT(spi_device != RT_NULL); - RT_ASSERT(result != CYHAL_SPI_RSLT_CLOCK_ERROR); + rt_err_t result = RT_EOK; + + result = cyhal_spi_init(spi_device->spi_handle_t->spi_obj, spi_device->spi_handle_t->mosi_pin, spi_device->spi_handle_t->miso_pin, + spi_device->spi_handle_t->sck_pin, NC, NULL, spi_device->spi_handle_t->spi_obj->data_bits, + spi_device->spi_handle_t->spi_obj->mode, false); + + if (result != RT_EOK) + { + LOG_E("spi%s init fail", spi_device->spi_handle_t->bus_name); + return; + } + + LOG_I("[%s] freq:[%d]HZ\n", spi_device->spi_handle_t->bus_name, spi_device->spi_handle_t->freq); + + result = cyhal_spi_set_frequency(spi_device->spi_handle_t->spi_obj, spi_device->spi_handle_t->freq); + if (result == CYHAL_SPI_RSLT_CLOCK_ERROR) + { + LOG_E("%s set frequency fail", spi_device->spi_handle_t->bus_name); + return; + } + + /* Register a callback function to be called when the interrupt fires */ + cyhal_spi_register_callback(spi_device->spi_handle_t->spi_obj, spi_interrupt_callback, spi_device); + + /* Enable the events that will trigger the call back function */ + cyhal_spi_enable_event(spi_device->spi_handle_t->spi_obj, CYHAL_SPI_IRQ_DONE, 4, true); } static rt_err_t spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration) { - struct rt_spi_bus *spi_bus = (struct rt_spi_bus *)device->bus; - struct ifx_spi *spi_device = (struct ifx_spi *)spi_bus->parent.user_data; - RT_ASSERT(device != RT_NULL); RT_ASSERT(configuration != RT_NULL); + struct ifx_spi *spi_device = rt_container_of(device->bus, struct ifx_spi, spi_bus); + /* data_width */ if (configuration->data_width <= 8) { - spi_device->spi_obj->data_bits = 8; + spi_device->spi_handle_t->spi_obj->data_bits = 8; } else if (configuration->data_width <= 16) { - spi_device->spi_obj->data_bits = 16; + spi_device->spi_handle_t->spi_obj->data_bits = 16; } else { @@ -118,27 +143,26 @@ static rt_err_t spi_configure(struct rt_spi_device *device, uint32_t max_hz; max_hz = configuration->max_hz; - - spi_device->freq = max_hz; + spi_device->spi_handle_t->freq = max_hz; /* MSB or LSB */ switch (configuration->mode & RT_SPI_MODE_3) { - case RT_SPI_MODE_0: - spi_device->spi_obj->mode = CYHAL_SPI_MODE_00_MSB; - break; + case RT_SPI_MODE_0: + spi_device->spi_handle_t->spi_obj->mode = CYHAL_SPI_MODE_00_MSB; + break; - case RT_SPI_MODE_1: - spi_device->spi_obj->mode = CYHAL_SPI_MODE_01_MSB; - break; + case RT_SPI_MODE_1: + spi_device->spi_handle_t->spi_obj->mode = CYHAL_SPI_MODE_01_MSB; + break; - case RT_SPI_MODE_2: - spi_device->spi_obj->mode = CYHAL_SPI_MODE_10_MSB; - break; + case RT_SPI_MODE_2: + spi_device->spi_handle_t->spi_obj->mode = CYHAL_SPI_MODE_10_MSB; + break; - case RT_SPI_MODE_3: - spi_device->spi_obj->mode = CYHAL_SPI_MODE_11_MSB; - break; + case RT_SPI_MODE_3: + spi_device->spi_handle_t->spi_obj->mode = CYHAL_SPI_MODE_11_MSB; + break; } ifx_spi_init(spi_device); @@ -151,11 +175,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m RT_ASSERT(device != NULL); RT_ASSERT(message != NULL); - struct rt_spi_bus *spi_bus = (struct rt_spi_bus *)device->bus; - struct ifx_spi *spi_device = (struct ifx_spi *)spi_bus->parent.user_data; - - struct rt_spi_configuration *config = &device->config; - struct ifx_sw_spi_cs *cs = device->parent.user_data; + struct ifx_spi *spi_device = rt_container_of(device->bus, struct ifx_spi, spi_bus); /* take CS */ if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE)) @@ -171,18 +191,21 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m if (message->send_buf == RT_NULL && message->recv_buf != RT_NULL) { /**< receive message */ - result = cyhal_spi_transfer(spi_device->spi_obj, RT_NULL, 0x00, message->recv_buf, message->length, 0x00); + result = cyhal_spi_transfer(spi_device->spi_handle_t->spi_obj, RT_NULL, 0x00, message->recv_buf, message->length, 0x00); } else if (message->send_buf != RT_NULL && message->recv_buf == RT_NULL) { /**< send message */ - result = cyhal_spi_transfer(spi_device->spi_obj, message->send_buf, message->length, RT_NULL, 0x00, 0x00); + result = cyhal_spi_transfer(spi_device->spi_handle_t->spi_obj, message->send_buf, message->length, RT_NULL, 0x00, 0x00); } else if (message->send_buf != RT_NULL && message->recv_buf != RT_NULL) { /**< send and receive message */ - result = cyhal_spi_transfer(spi_device->spi_obj, message->send_buf, message->length, message->recv_buf, message->length, 0x00); + result = cyhal_spi_transfer(spi_device->spi_handle_t->spi_obj, message->send_buf, message->length, message->recv_buf, message->length, 0x00); } + + /* blocking the thread,and the other tasks can run */ + rt_completion_wait(&spi_device->cpt, RT_WAITING_FOREVER); } if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS) && (device->cs_pin != PIN_NONE)) @@ -196,7 +219,10 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m return message->length; } -rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, uint16_t cs_gpio_pin) +/** + * Attach the spi device to SPI bus, this function must be used after initialization. + */ +rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin) { RT_ASSERT(bus_name != RT_NULL); RT_ASSERT(device_name != RT_NULL); @@ -204,24 +230,19 @@ rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_err_t result; struct rt_spi_device *spi_device; - /* attach the device to spi bus */ + /* attach the device to spi bus*/ spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device)); RT_ASSERT(spi_device != RT_NULL); - struct ifx_sw_spi_cs *cs_pin = (struct ifx_sw_spi_cs *)rt_malloc(sizeof(struct ifx_sw_spi_cs)); - RT_ASSERT(cs_pin != RT_NULL); - cs_pin->pin = cs_gpio_pin; - - if (cs_pin->pin != 0x00) + result = rt_spi_bus_attach_device_cspin(spi_device, device_name, bus_name, cs_pin, RT_NULL); + if (result != RT_EOK) { - /* initialize the cs pin & select the slave*/ - cyhal_gpio_init(cs_pin->pin, CYHAL_GPIO_DIR_OUTPUT, CYHAL_GPIO_DRIVE_STRONG, 1); - cyhal_gpio_write(cs_pin->pin, PIN_HIGH); + LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result); } - result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin); + RT_ASSERT(result == RT_EOK); - RT_ASSERT(spi_device != RT_NULL); + LOG_D("%s attach to %s done", device_name, bus_name); return result; } @@ -230,23 +251,26 @@ int rt_hw_spi_init(void) { int result = RT_EOK; - for (int i = 0; i < sizeof(spi_bus_obj) / sizeof(spi_bus_obj[0]); i++) + for (int spi_index = 0; spi_index < sizeof(spi_bus_obj) / sizeof(spi_bus_obj[0]); spi_index++) { - spi_bus_obj[i].spi_obj = rt_malloc(sizeof(cyhal_spi_t)); + spi_bus_obj[spi_index].spi_obj = rt_malloc(sizeof(cyhal_spi_t)); + RT_ASSERT(spi_bus_obj[spi_index].spi_obj != RT_NULL); - RT_ASSERT(spi_bus_obj[i].spi_obj != RT_NULL); + spi_config[spi_index].spi_handle_t = &spi_bus_obj[spi_index]; - spi_bus_obj[i].spi_bus->parent.user_data = (void *)&spi_bus_obj[i]; - - result = rt_spi_bus_register(spi_bus_obj[i].spi_bus, spi_bus_obj[i].bus_name, &ifx_spi_ops); - - RT_ASSERT(result == RT_EOK); - - LOG_D("%s bus init done", spi_bus_obj[i].bus_name); + rt_err_t err = rt_spi_bus_register(&spi_config[spi_index].spi_bus, spi_bus_obj[spi_index].bus_name, &ifx_spi_ops); + if (RT_EOK != err) + { + LOG_E("%s bus register failed.", spi_config[spi_index].spi_handle_t->bus_name); + return -RT_ERROR; + } LOG_D("MOSI PIN:[%d], MISO PIN[%d], CLK PIN[%d]\n", - spi_bus_obj[i].mosi_pin, spi_bus_obj[i].miso_pin, - spi_bus_obj[i].sck_pin); + spi_bus_obj[spi_index].mosi_pin, spi_bus_obj[spi_index].miso_pin, + spi_bus_obj[spi_index].sck_pin); + + /* initialize completion object */ + rt_completion_init(&spi_config[spi_index].cpt); } return result; diff --git a/bsp/Infineon/libraries/HAL_Drivers/drv_spi.h b/bsp/Infineon/libraries/HAL_Drivers/drv_spi.h index 0d8c757584..ffcf87b3a5 100644 --- a/bsp/Infineon/libraries/HAL_Drivers/drv_spi.h +++ b/bsp/Infineon/libraries/HAL_Drivers/drv_spi.h @@ -16,13 +16,9 @@ #include "drv_gpio.h" -#define SPI_FREQ_HZ (10000000UL) - -/* gd32 spi dirver class */ -struct ifx_spi +struct ifx_spi_handle { - char *bus_name; - struct rt_spi_bus *spi_bus; + const char *bus_name; cyhal_spi_t *spi_obj; uint16_t sck_pin; @@ -31,6 +27,18 @@ struct ifx_spi uint32_t freq; }; -rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, uint16_t cs_gpio_pin); +/* ifx spi dirver class */ +struct ifx_spi +{ + rt_uint32_t cs_pin; + + struct ifx_spi_handle *spi_handle_t; + struct rt_spi_configuration *rt_spi_cfg_t; + struct rt_spi_bus spi_bus; + + struct rt_completion cpt; +}; + +rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin); #endif diff --git a/bsp/Infineon/psoc6-evaluationkit-062S2/board/board.h b/bsp/Infineon/psoc6-evaluationkit-062S2/board/board.h index 946531a579..f21be3c40e 100644 --- a/bsp/Infineon/psoc6-evaluationkit-062S2/board/board.h +++ b/bsp/Infineon/psoc6-evaluationkit-062S2/board/board.h @@ -40,7 +40,7 @@ #define IFX_EFLASH_END_ADDRESS ((uint32_t)(IFX_EFLASH_START_ADRESS + IFX_EFLASH_SIZE)) /*SRAM CONFIG*/ -#define IFX_SRAM_SIZE (1014) +#define IFX_SRAM_SIZE (1013) #define IFX_SRAM_END (0x08002000 + IFX_SRAM_SIZE * 1024) #ifdef __ARMCC_VERSION