@@ -33,6 +33,7 @@ LOG_MODULE_REGISTER(spi_telink);
3333#define CHIP_SELECT_COUNT 3u
3434#define SPI_WORD_SIZE 8u
3535#define SPI_WR_RD_CHUNK_SIZE_MAX 16u
36+ #define SPI_ERROR_TIMEOUT 1000000u
3637
3738/* SPI configuration structure */
3839struct spi_tlx_cfg {
@@ -204,7 +205,7 @@ _attribute_ram_code_sec_ static void spi_tlx_rx(uint8_t peripheral_id, struct sp
204205}
205206
206207/* SPI transceive internal */
207- _attribute_ram_code_sec_ static void spi_tlx_txrx (const struct device * dev , uint32_t len )
208+ _attribute_ram_code_sec_ static void spi_tlx_txrx_multibufs (const struct device * dev , uint32_t len )
208209{
209210 unsigned int chunk_size = SPI_WR_RD_CHUNK_SIZE_MAX ;
210211 struct spi_tlx_cfg * cfg = SPI_CFG (dev );
@@ -248,13 +249,50 @@ _attribute_ram_code_sec_ static void spi_tlx_txrx(const struct device *dev, uint
248249 BM_SET (reg_spi_status (cfg -> peripheral_id ), FLD_SPI_RXF_CLR_LEVEL );
249250#endif
250251 }
252+ }
253+
254+ static bool spi_tlx_is_simple_buf (size_t count , const uint8_t * buf , size_t len , uint32_t total_len )
255+ {
256+ return (count == 1 ) && (buf != NULL ) && (len == total_len );
257+ }
258+
259+ /* SPI transceive internal */
260+ _attribute_ram_code_sec_ static void spi_tlx_txrx (const struct device * dev , uint32_t len )
261+ {
262+ int err = 0 ;
263+ struct spi_tlx_cfg * cfg = SPI_CFG (dev );
264+ struct spi_context * ctx = & SPI_DATA (dev )-> ctx ;
265+
266+ bool simple_tx = spi_tlx_is_simple_buf (ctx -> tx_count , ctx -> tx_buf , ctx -> tx_len , len );
267+ bool simple_rx = spi_tlx_is_simple_buf (ctx -> rx_count , ctx -> rx_buf , ctx -> rx_len , len );
268+
269+ if (simple_tx && simple_rx ) {
270+ /* fast path: full duplex, vendor-proven chunking + offset compensation */
271+ spi_master_write_read_full_duplex (cfg -> peripheral_id ,
272+ (uint8_t * )ctx -> tx_buf , ctx -> rx_buf , len );
273+ spi_context_update_tx (ctx , 1 , len );
274+ spi_context_update_rx (ctx , 1 , len );
275+ } else if (simple_tx && !spi_context_rx_on (ctx )) {
276+ /* fast path: write only */
277+ spi_master_write (cfg -> peripheral_id , (uint8_t * )ctx -> tx_buf , len );
278+ spi_context_update_tx (ctx , 1 , len );
279+ } else if (simple_rx && !spi_context_tx_on (ctx )) {
280+ /* fast path: read only */
281+ spi_master_read (cfg -> peripheral_id , ctx -> rx_buf , len );
282+ spi_context_update_rx (ctx , 1 , len );
283+ } else {
284+ /* fallback: scatter-gather / dummy-fill / discard case */
285+ spi_tlx_txrx_multibufs (dev , len );
286+ }
251287
252- /* wait fot SPI is ready */
253- while (spi_is_busy (cfg -> peripheral_id )) {
254- };
288+ if (!WAIT_FOR (!spi_is_busy (cfg -> peripheral_id ), SPI_ERROR_TIMEOUT , NULL )) {
289+ LOG_ERR ("SPI is busy timeout" );
290+ spi_hw_fsm_reset (cfg -> peripheral_id );
291+ err = - ETIMEDOUT ;
292+ }
255293
256294 /* context complete */
257- spi_context_complete (ctx , dev , 0 );
295+ spi_context_complete (ctx , dev , err );
258296}
259297
260298/* Check for supported configuration */
@@ -301,7 +339,7 @@ static bool spi_tlx_is_config_supported(const struct spi_config *config,
301339 /* check for slave configuration */
302340 if (SPI_OP_MODE_GET (config -> operation ) == SPI_OP_MODE_SLAVE ) {
303341 LOG_ERR ("SPI Slave is not implemented" );
304- return - ENOTSUP ;
342+ return false ;
305343 }
306344
307345 return true;
@@ -398,6 +436,8 @@ static int spi_tlx_init(const struct device *dev)
398436
399437 spi_context_unlock_unconditionally (& data -> ctx );
400438
439+ spi_set_error_timeout (SPI_ERROR_TIMEOUT );
440+
401441 return 0 ;
402442}
403443
@@ -409,14 +449,15 @@ static int spi_tlx_transceive(const struct device *dev, const struct spi_config
409449 struct spi_tlx_data * data = SPI_DATA (dev );
410450 uint32_t txrx_len = spi_tlx_get_txrx_len (tx_bufs , rx_bufs );
411451
452+ /* context setup */
453+ spi_context_lock (& data -> ctx , false, NULL , NULL , config );
454+
412455 /* set configuration */
413456 status = spi_tlx_config (dev , config );
414457 if (status ) {
415458 return status ;
416459 }
417460
418- /* context setup */
419- spi_context_lock (& data -> ctx , false, NULL , NULL , config );
420461 spi_context_buffers_setup (& data -> ctx , tx_bufs , rx_bufs , 1 );
421462
422463 /* if cs is defined: software cs control, set active true */
0 commit comments