66 * Change Logs:
77 * Date Author Notes
88 * 2022-07-18 Rbb666 first version
9+ * 2023-03-30 Rbb666 update spi driver
910 */
1011
1112#include <drv_spi.h>
2122#endif /* DRV_DEBUG */
2223#include <rtdbg.h>
2324
24- struct ifx_sw_spi_cs
25- {
26- rt_uint32_t pin ;
27- };
28-
2925#ifdef BSP_USING_SPI0
3026 static struct rt_spi_bus spi_bus0 ;
3127#endif
3228#ifdef BSP_USING_SPI3
3329 static struct rt_spi_bus spi_bus3 ;
3430#endif
35-
3631#ifdef BSP_USING_SPI6
3732 static struct rt_spi_bus spi_bus6 ;
3833#endif
39- static struct ifx_spi spi_bus_obj [] =
34+
35+ static struct ifx_spi_handle spi_bus_obj [] =
4036{
41- #if defined(BSP_USING_SPI0 )
37+ #if defined(BSP_USING_SPI0 )
4238 {
4339 .bus_name = "spi0" ,
44- .spi_bus = & spi_bus0 ,
4540 .sck_pin = GET_PIN (0 , 4 ),
4641 .miso_pin = GET_PIN (0 , 3 ),
4742 .mosi_pin = GET_PIN (0 , 2 ),
4843 },
49- #endif
50- #if defined(BSP_USING_SPI3 )
44+ #endif
45+ #if defined(BSP_USING_SPI3 )
5146 {
5247 .bus_name = "spi3" ,
53- .spi_bus = & spi_bus3 ,
5448 .sck_pin = GET_PIN (6 , 2 ),
5549 .miso_pin = GET_PIN (6 , 1 ),
5650 .mosi_pin = GET_PIN (6 , 0 ),
5751 },
58- #endif
59- #if defined(BSP_USING_SPI6 )
52+ #endif
53+ #if defined(BSP_USING_SPI6 )
6054 {
6155 .bus_name = "spi6" ,
62- .spi_bus = & spi_bus6 ,
6356 .sck_pin = GET_PIN (12 , 2 ),
6457 .miso_pin = GET_PIN (12 , 1 ),
6558 .mosi_pin = GET_PIN (12 , 0 ),
6659 },
67- #endif
60+ #endif
6861};
6962
63+ static struct ifx_spi spi_config [sizeof (spi_bus_obj ) / sizeof (spi_bus_obj [0 ])] = {0 };
64+
7065/* private rt-thread spi ops function */
7166static rt_err_t spi_configure (struct rt_spi_device * device , struct rt_spi_configuration * configuration );
7267static 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 =
7772 .xfer = spixfer ,
7873};
7974
80- static void ifx_spi_init ( struct ifx_spi * ifx_spi )
75+ static void spi_interrupt_callback ( void * arg , cyhal_spi_event_t event )
8176{
82- int result = RT_EOK ;
77+ struct ifx_spi * spi_drv = ( struct ifx_spi * ) arg ;
8378
84- result = cyhal_spi_init (ifx_spi -> spi_obj , ifx_spi -> mosi_pin , ifx_spi -> miso_pin , ifx_spi -> sck_pin ,
85- NC , NULL , ifx_spi -> spi_obj -> data_bits , ifx_spi -> spi_obj -> mode , false);
79+ rt_interrupt_enter ();
8680
87- RT_ASSERT (result == RT_EOK );
81+ if ((event & CYHAL_SPI_IRQ_DONE ) != 0u )
82+ {
83+ /* Transmission is complete. Handle Event */
84+ rt_completion_done (& spi_drv -> cpt );
85+ }
86+
87+ rt_interrupt_leave ();
88+ }
89+
90+ static void ifx_spi_init (struct ifx_spi * spi_device )
91+ {
92+ RT_ASSERT (spi_device != RT_NULL );
93+
94+ rt_err_t result = RT_EOK ;
95+
96+ 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 ,
97+ spi_device -> spi_handle_t -> sck_pin , NC , NULL , spi_device -> spi_handle_t -> spi_obj -> data_bits ,
98+ spi_device -> spi_handle_t -> spi_obj -> mode , false);
8899
89- rt_kprintf ("[%s] Freq:[%d]HZ\n" , ifx_spi -> bus_name , ifx_spi -> freq );
100+ if (result != RT_EOK )
101+ {
102+ LOG_E ("spi%s init fail" , spi_device -> spi_handle_t -> bus_name );
103+ return ;
104+ }
105+
106+ LOG_I ("[%s] freq:[%d]HZ\n" , spi_device -> spi_handle_t -> bus_name , spi_device -> spi_handle_t -> freq );
107+
108+ result = cyhal_spi_set_frequency (spi_device -> spi_handle_t -> spi_obj , spi_device -> spi_handle_t -> freq );
109+ if (result == CYHAL_SPI_RSLT_CLOCK_ERROR )
110+ {
111+ LOG_E ("%s set frequency fail" , spi_device -> spi_handle_t -> bus_name );
112+ return ;
113+ }
90114
91- result = cyhal_spi_set_frequency (ifx_spi -> spi_obj , ifx_spi -> freq );
115+ /* Register a callback function to be called when the interrupt fires */
116+ cyhal_spi_register_callback (spi_device -> spi_handle_t -> spi_obj , spi_interrupt_callback , spi_device );
92117
93- RT_ASSERT (result != CYHAL_SPI_RSLT_CLOCK_ERROR );
118+ /* Enable the events that will trigger the call back function */
119+ cyhal_spi_enable_event (spi_device -> spi_handle_t -> spi_obj , CYHAL_SPI_IRQ_DONE , 4 , true);
94120}
95121
96122static rt_err_t spi_configure (struct rt_spi_device * device ,
97123 struct rt_spi_configuration * configuration )
98124{
99- struct rt_spi_bus * spi_bus = (struct rt_spi_bus * )device -> bus ;
100- struct ifx_spi * spi_device = (struct ifx_spi * )spi_bus -> parent .user_data ;
101-
102125 RT_ASSERT (device != RT_NULL );
103126 RT_ASSERT (configuration != RT_NULL );
104127
128+ struct ifx_spi * spi_device = rt_container_of (device -> bus , struct ifx_spi , spi_bus );
129+
105130 /* data_width */
106131 if (configuration -> data_width <= 8 )
107132 {
108- spi_device -> spi_obj -> data_bits = 8 ;
133+ spi_device -> spi_handle_t -> spi_obj -> data_bits = 8 ;
109134 }
110135 else if (configuration -> data_width <= 16 )
111136 {
112- spi_device -> spi_obj -> data_bits = 16 ;
137+ spi_device -> spi_handle_t -> spi_obj -> data_bits = 16 ;
113138 }
114139 else
115140 {
@@ -118,27 +143,26 @@ static rt_err_t spi_configure(struct rt_spi_device *device,
118143
119144 uint32_t max_hz ;
120145 max_hz = configuration -> max_hz ;
121-
122- spi_device -> freq = max_hz ;
146+ spi_device -> spi_handle_t -> freq = max_hz ;
123147
124148 /* MSB or LSB */
125149 switch (configuration -> mode & RT_SPI_MODE_3 )
126150 {
127- case RT_SPI_MODE_0 :
128- spi_device -> spi_obj -> mode = CYHAL_SPI_MODE_00_MSB ;
129- break ;
151+ case RT_SPI_MODE_0 :
152+ spi_device -> spi_handle_t -> spi_obj -> mode = CYHAL_SPI_MODE_00_MSB ;
153+ break ;
130154
131- case RT_SPI_MODE_1 :
132- spi_device -> spi_obj -> mode = CYHAL_SPI_MODE_01_MSB ;
133- break ;
155+ case RT_SPI_MODE_1 :
156+ spi_device -> spi_handle_t -> spi_obj -> mode = CYHAL_SPI_MODE_01_MSB ;
157+ break ;
134158
135- case RT_SPI_MODE_2 :
136- spi_device -> spi_obj -> mode = CYHAL_SPI_MODE_10_MSB ;
137- break ;
159+ case RT_SPI_MODE_2 :
160+ spi_device -> spi_handle_t -> spi_obj -> mode = CYHAL_SPI_MODE_10_MSB ;
161+ break ;
138162
139- case RT_SPI_MODE_3 :
140- spi_device -> spi_obj -> mode = CYHAL_SPI_MODE_11_MSB ;
141- break ;
163+ case RT_SPI_MODE_3 :
164+ spi_device -> spi_handle_t -> spi_obj -> mode = CYHAL_SPI_MODE_11_MSB ;
165+ break ;
142166 }
143167
144168 ifx_spi_init (spi_device );
@@ -151,11 +175,7 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
151175 RT_ASSERT (device != NULL );
152176 RT_ASSERT (message != NULL );
153177
154- struct rt_spi_bus * spi_bus = (struct rt_spi_bus * )device -> bus ;
155- struct ifx_spi * spi_device = (struct ifx_spi * )spi_bus -> parent .user_data ;
156-
157- struct rt_spi_configuration * config = & device -> config ;
158- struct ifx_sw_spi_cs * cs = device -> parent .user_data ;
178+ struct ifx_spi * spi_device = rt_container_of (device -> bus , struct ifx_spi , spi_bus );
159179
160180 /* take CS */
161181 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
171191 if (message -> send_buf == RT_NULL && message -> recv_buf != RT_NULL )
172192 {
173193 /**< receive message */
174- result = cyhal_spi_transfer (spi_device -> spi_obj , RT_NULL , 0x00 , message -> recv_buf , message -> length , 0x00 );
194+ result = cyhal_spi_transfer (spi_device -> spi_handle_t -> spi_obj , RT_NULL , 0x00 , message -> recv_buf , message -> length , 0x00 );
175195 }
176196 else if (message -> send_buf != RT_NULL && message -> recv_buf == RT_NULL )
177197 {
178198 /**< send message */
179- result = cyhal_spi_transfer (spi_device -> spi_obj , message -> send_buf , message -> length , RT_NULL , 0x00 , 0x00 );
199+ result = cyhal_spi_transfer (spi_device -> spi_handle_t -> spi_obj , message -> send_buf , message -> length , RT_NULL , 0x00 , 0x00 );
180200 }
181201 else if (message -> send_buf != RT_NULL && message -> recv_buf != RT_NULL )
182202 {
183203 /**< send and receive message */
184- result = cyhal_spi_transfer (spi_device -> spi_obj , message -> send_buf , message -> length , message -> recv_buf , message -> length , 0x00 );
204+ result = cyhal_spi_transfer (spi_device -> spi_handle_t -> spi_obj , message -> send_buf , message -> length , message -> recv_buf , message -> length , 0x00 );
185205 }
206+
207+ /* blocking the thread,and the other tasks can run */
208+ rt_completion_wait (& spi_device -> cpt , RT_WAITING_FOREVER );
186209 }
187210
188211 if (message -> cs_release && !(device -> config .mode & RT_SPI_NO_CS ) && (device -> cs_pin != PIN_NONE ))
@@ -196,32 +219,30 @@ static rt_ssize_t spixfer(struct rt_spi_device *device, struct rt_spi_message *m
196219 return message -> length ;
197220}
198221
199- rt_err_t rt_hw_spi_device_attach (const char * bus_name , const char * device_name , uint16_t cs_gpio_pin )
222+ /**
223+ * Attach the spi device to SPI bus, this function must be used after initialization.
224+ */
225+ rt_err_t rt_hw_spi_device_attach (const char * bus_name , const char * device_name , rt_base_t cs_pin )
200226{
201227 RT_ASSERT (bus_name != RT_NULL );
202228 RT_ASSERT (device_name != RT_NULL );
203229
204230 rt_err_t result ;
205231 struct rt_spi_device * spi_device ;
206232
207- /* attach the device to spi bus */
233+ /* attach the device to spi bus*/
208234 spi_device = (struct rt_spi_device * )rt_malloc (sizeof (struct rt_spi_device ));
209235 RT_ASSERT (spi_device != RT_NULL );
210- struct ifx_sw_spi_cs * cs_pin = (struct ifx_sw_spi_cs * )rt_malloc (sizeof (struct ifx_sw_spi_cs ));
211- RT_ASSERT (cs_pin != RT_NULL );
212-
213- cs_pin -> pin = cs_gpio_pin ;
214236
215- if (cs_pin -> pin != 0x00 )
237+ result = rt_spi_bus_attach_device_cspin (spi_device , device_name , bus_name , cs_pin , RT_NULL );
238+ if (result != RT_EOK )
216239 {
217- /* initialize the cs pin & select the slave*/
218- cyhal_gpio_init (cs_pin -> pin , CYHAL_GPIO_DIR_OUTPUT , CYHAL_GPIO_DRIVE_STRONG , 1 );
219- cyhal_gpio_write (cs_pin -> pin , PIN_HIGH );
240+ LOG_E ("%s attach to %s faild, %d\n" , device_name , bus_name , result );
220241 }
221242
222- result = rt_spi_bus_attach_device ( spi_device , device_name , bus_name , ( void * ) cs_pin );
243+ RT_ASSERT ( result == RT_EOK );
223244
224- RT_ASSERT ( spi_device != RT_NULL );
245+ LOG_D ( "%s attach to %s done" , device_name , bus_name );
225246
226247 return result ;
227248}
@@ -230,23 +251,26 @@ int rt_hw_spi_init(void)
230251{
231252 int result = RT_EOK ;
232253
233- for (int i = 0 ; i < sizeof (spi_bus_obj ) / sizeof (spi_bus_obj [0 ]); i ++ )
254+ for (int spi_index = 0 ; spi_index < sizeof (spi_bus_obj ) / sizeof (spi_bus_obj [0 ]); spi_index ++ )
234255 {
235- spi_bus_obj [i ].spi_obj = rt_malloc (sizeof (cyhal_spi_t ));
236-
237- RT_ASSERT (spi_bus_obj [i ].spi_obj != RT_NULL );
256+ spi_bus_obj [spi_index ].spi_obj = rt_malloc (sizeof (cyhal_spi_t ));
257+ RT_ASSERT (spi_bus_obj [spi_index ].spi_obj != RT_NULL );
238258
239- spi_bus_obj [ i ]. spi_bus -> parent . user_data = ( void * ) & spi_bus_obj [i ];
259+ spi_config [ spi_index ]. spi_handle_t = & spi_bus_obj [spi_index ];
240260
241- result = rt_spi_bus_register (spi_bus_obj [i ].spi_bus , spi_bus_obj [i ].bus_name , & ifx_spi_ops );
242-
243- RT_ASSERT (result == RT_EOK );
244-
245- LOG_D ("%s bus init done" , spi_bus_obj [i ].bus_name );
261+ rt_err_t err = rt_spi_bus_register (& spi_config [spi_index ].spi_bus , spi_bus_obj [spi_index ].bus_name , & ifx_spi_ops );
262+ if (RT_EOK != err )
263+ {
264+ LOG_E ("%s bus register failed." , spi_config [spi_index ].spi_handle_t -> bus_name );
265+ return - RT_ERROR ;
266+ }
246267
247268 LOG_D ("MOSI PIN:[%d], MISO PIN[%d], CLK PIN[%d]\n" ,
248- spi_bus_obj [i ].mosi_pin , spi_bus_obj [i ].miso_pin ,
249- spi_bus_obj [i ].sck_pin );
269+ spi_bus_obj [spi_index ].mosi_pin , spi_bus_obj [spi_index ].miso_pin ,
270+ spi_bus_obj [spi_index ].sck_pin );
271+
272+ /* initialize completion object */
273+ rt_completion_init (& spi_config [spi_index ].cpt );
250274 }
251275
252276 return result ;
0 commit comments