Browse Source

[Infineon]Update spi driver

Rbb666 2 years ago
parent
commit
8552d061c2

+ 99 - 75
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 <drv_spi.h>
@@ -21,52 +22,46 @@
 #endif /* DRV_DEBUG */
 #include <rtdbg.h>
 
-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_interrupt_leave();
+}
+
+static void ifx_spi_init(struct ifx_spi *spi_device)
+{
+    RT_ASSERT(spi_device != RT_NULL);
+
+    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);
 
-    rt_kprintf("[%s] Freq:[%d]HZ\n", ifx_spi->bus_name, ifx_spi->freq);
+    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;
+    }
 
-    result = cyhal_spi_set_frequency(ifx_spi->spi_obj, ifx_spi->freq);
+    /* 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);
 
-    RT_ASSERT(result != CYHAL_SPI_RSLT_CLOCK_ERROR);
+    /* 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));
-
-        RT_ASSERT(spi_bus_obj[i].spi_obj != RT_NULL);
+        spi_bus_obj[spi_index].spi_obj = rt_malloc(sizeof(cyhal_spi_t));
+        RT_ASSERT(spi_bus_obj[spi_index].spi_obj != RT_NULL);
 
-        spi_bus_obj[i].spi_bus->parent.user_data = (void *)&spi_bus_obj[i];
+        spi_config[spi_index].spi_handle_t = &spi_bus_obj[spi_index];
 
-        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;

+ 15 - 7
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

+ 1 - 1
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