mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2025-02-21 01:07:18 +08:00
[bsp/n32g45x] drv_spi.c中添加超时检测避免卡死 (#5820)
* 为spi添加超时检测,避免卡死。提取公共部份,避免代码复制。
This commit is contained in:
parent
a0f8d43744
commit
cbd062ca25
@ -6,6 +6,7 @@
|
|||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2022-03-06 BalanceTWK first version
|
* 2022-03-06 BalanceTWK first version
|
||||||
|
* 2022-04-16 wolfJane fix spixfer, add time out check
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <board.h>
|
#include <board.h>
|
||||||
@ -22,6 +23,8 @@
|
|||||||
#define LOG_TAG "drv.spi"
|
#define LOG_TAG "drv.spi"
|
||||||
#include <drv_log.h>
|
#include <drv_log.h>
|
||||||
|
|
||||||
|
#define SPI_TIME_OUT (1000)
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
#ifdef BSP_USING_SPI1
|
#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);
|
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)
|
static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
|
||||||
{
|
{
|
||||||
rt_size_t message_length;
|
rt_size_t send_length;
|
||||||
rt_size_t i = 0;
|
|
||||||
rt_uint8_t *recv_buf;
|
rt_uint8_t *recv_buf;
|
||||||
const rt_uint8_t *send_buf;
|
const rt_uint8_t *send_buf;
|
||||||
|
rt_err_t stat = RT_EOK;
|
||||||
|
|
||||||
|
/* Check Direction parameter */
|
||||||
RT_ASSERT(device != RT_NULL);
|
RT_ASSERT(device != RT_NULL);
|
||||||
RT_ASSERT(device->bus != RT_NULL);
|
RT_ASSERT(device->bus != RT_NULL);
|
||||||
RT_ASSERT(device->bus->parent.user_data != 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 (message->cs_take && !(device->config.mode & RT_SPI_NO_CS))
|
||||||
{
|
{
|
||||||
if (device->config.mode & RT_SPI_CS_HIGH)
|
if (device->config.mode & RT_SPI_CS_HIGH)
|
||||||
|
{
|
||||||
GPIO_SetBits(cs->module, cs->pin);
|
GPIO_SetBits(cs->module, cs->pin);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
GPIO_ResetBits(cs->module, cs->pin);
|
GPIO_ResetBits(cs->module, cs->pin);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
message_length = message->length;
|
send_length = message->length;
|
||||||
recv_buf = message->recv_buf;
|
recv_buf = message->recv_buf;
|
||||||
send_buf = message->send_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)
|
if (message->send_buf && message->recv_buf)
|
||||||
{
|
{
|
||||||
LOG_D("%s:%d", __FUNCTION__, __LINE__);
|
LOG_D("%s:%d", __FUNCTION__, __LINE__);
|
||||||
|
stat = RT_EIO;
|
||||||
}
|
}
|
||||||
else if (message->send_buf)
|
else if (message->send_buf)
|
||||||
{
|
{
|
||||||
while (message_length--)
|
stat = _spi_recv(spi_handle,
|
||||||
{
|
(uint8_t *)send_buf,
|
||||||
while (SPI_I2S_GetStatus(spi_handle, SPI_I2S_TE_FLAG) == RESET);
|
RT_NULL,
|
||||||
SPI_I2S_TransmitData(spi_handle, send_buf[i++]);
|
send_length,
|
||||||
while (SPI_I2S_GetStatus(spi_handle, SPI_I2S_RNE_FLAG) == RESET);
|
SPI_TIME_OUT);
|
||||||
SPI_I2S_ReceiveData(spi_handle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (message_length--)
|
rt_memset(recv_buf, 0xff, send_length);
|
||||||
{
|
stat = _spi_recv(spi_handle,
|
||||||
while (SPI_I2S_GetStatus(spi_handle, SPI_I2S_TE_FLAG) == RESET);
|
(uint8_t *)recv_buf,
|
||||||
SPI_I2S_TransmitData(spi_handle, 0xff);
|
(uint8_t *)recv_buf,
|
||||||
while (SPI_I2S_GetStatus(spi_handle, SPI_I2S_RNE_FLAG) == RESET);
|
send_length,
|
||||||
recv_buf[i++] = (rt_uint8_t)SPI_I2S_ReceiveData(spi_handle);
|
SPI_TIME_OUT);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS))
|
if (message->cs_release && !(device->config.mode & RT_SPI_NO_CS))
|
||||||
{
|
{
|
||||||
if (device->config.mode & RT_SPI_CS_HIGH)
|
if (device->config.mode & RT_SPI_CS_HIGH)
|
||||||
|
{
|
||||||
GPIO_ResetBits(cs->module, cs->pin);
|
GPIO_ResetBits(cs->module, cs->pin);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
GPIO_SetBits(cs->module, cs->pin);
|
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 =
|
static const struct rt_spi_ops n32_spi_ops =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user