From cbd062ca2542f2b0c58d13e57d4a2cfe23b0f443 Mon Sep 17 00:00:00 2001 From: wolfJane <37776317+wolfJane@users.noreply.github.com> Date: Wed, 20 Apr 2022 10:28:29 +0800 Subject: [PATCH] =?UTF-8?q?[bsp/n32g45x]=20drv=5Fspi.c=E4=B8=AD=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E8=B6=85=E6=97=B6=E6=A3=80=E6=B5=8B=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E5=8D=A1=E6=AD=BB=20(#5820)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 为spi添加超时检测,避免卡死。提取公共部份,避免代码复制。 --- bsp/n32g452xx/Libraries/rt_drivers/drv_spi.c | 95 ++++++++++++++++---- 1 file changed, 76 insertions(+), 19 deletions(-) diff --git a/bsp/n32g452xx/Libraries/rt_drivers/drv_spi.c b/bsp/n32g452xx/Libraries/rt_drivers/drv_spi.c index 9692f4bbf7..2d2e381f18 100644 --- a/bsp/n32g452xx/Libraries/rt_drivers/drv_spi.c +++ b/bsp/n32g452xx/Libraries/rt_drivers/drv_spi.c @@ -6,6 +6,7 @@ * Change Logs: * Date Author Notes * 2022-03-06 BalanceTWK first version + * 2022-04-16 wolfJane fix spixfer, add time out check */ #include @@ -22,6 +23,8 @@ #define LOG_TAG "drv.spi" #include +#define SPI_TIME_OUT (1000) + enum { #ifdef BSP_USING_SPI1 @@ -235,13 +238,57 @@ static rt_err_t spi_configure(struct rt_spi_device *device, return n32_spi_init(spi_drv, configuration); } +static int _spi_recv(SPI_Module *hspi, + uint8_t *tx_buff, + uint8_t *rx_buff, + uint32_t length, + uint32_t timeout) +{ + /* Init tickstart for timeout management*/ + uint32_t tickstart = rt_tick_get(); + uint8_t dat = 0; + + if ((tx_buff == RT_NULL) && (rx_buff == RT_NULL) || (length == 0)) + { + return RT_EIO; + } + + while (length--) + { + while (SPI_I2S_GetStatus(hspi, SPI_I2S_TE_FLAG) == RESET) + { + if ((rt_tick_get() - tickstart) > timeout) + { + return RT_ETIMEOUT; + } + } + SPI_I2S_TransmitData(hspi, *tx_buff++); + + while (SPI_I2S_GetStatus(hspi, SPI_I2S_RNE_FLAG) == RESET) + { + if ((rt_tick_get() - tickstart) > timeout) + { + return RT_ETIMEOUT; + } + } + dat = SPI_I2S_ReceiveData(hspi); + + if (rx_buff) + { + *rx_buff++ = dat; + } + } + return RT_EOK; +} + static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message) { - rt_size_t message_length; - rt_size_t i = 0; + rt_size_t send_length; rt_uint8_t *recv_buf; const rt_uint8_t *send_buf; + rt_err_t stat = RT_EOK; + /* Check Direction parameter */ RT_ASSERT(device != RT_NULL); RT_ASSERT(device->bus != RT_NULL); RT_ASSERT(device->bus->parent.user_data != RT_NULL); @@ -254,12 +301,16 @@ static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message * if (message->cs_take && !(device->config.mode & RT_SPI_NO_CS)) { if (device->config.mode & RT_SPI_CS_HIGH) + { GPIO_SetBits(cs->module, cs->pin); + } else + { GPIO_ResetBits(cs->module, cs->pin); + } } - message_length = message->length; + send_length = message->length; recv_buf = message->recv_buf; send_buf = message->send_buf; @@ -267,38 +318,44 @@ static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message * if (message->send_buf && message->recv_buf) { LOG_D("%s:%d", __FUNCTION__, __LINE__); + stat = RT_EIO; } else if (message->send_buf) { - while (message_length--) - { - while (SPI_I2S_GetStatus(spi_handle, SPI_I2S_TE_FLAG) == RESET); - SPI_I2S_TransmitData(spi_handle, send_buf[i++]); - while (SPI_I2S_GetStatus(spi_handle, SPI_I2S_RNE_FLAG) == RESET); - SPI_I2S_ReceiveData(spi_handle); - } + stat = _spi_recv(spi_handle, + (uint8_t *)send_buf, + RT_NULL, + send_length, + SPI_TIME_OUT); } else { - while (message_length--) - { - while (SPI_I2S_GetStatus(spi_handle, SPI_I2S_TE_FLAG) == RESET); - SPI_I2S_TransmitData(spi_handle, 0xff); - while (SPI_I2S_GetStatus(spi_handle, SPI_I2S_RNE_FLAG) == RESET); - recv_buf[i++] = (rt_uint8_t)SPI_I2S_ReceiveData(spi_handle); - } + rt_memset(recv_buf, 0xff, send_length); + stat = _spi_recv(spi_handle, + (uint8_t *)recv_buf, + (uint8_t *)recv_buf, + send_length, + SPI_TIME_OUT); } - if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS)) { if (device->config.mode & RT_SPI_CS_HIGH) + { GPIO_ResetBits(cs->module, cs->pin); + } else + { GPIO_SetBits(cs->module, cs->pin); + } } - return message->length; + if (stat != RT_EOK) + { + send_length = 0; + } + + return send_length; } static const struct rt_spi_ops n32_spi_ops =