|
@@ -11,7 +11,15 @@
|
|
|
******************************************************************************/
|
|
|
#include <rtconfig.h>
|
|
|
|
|
|
-#if defined(BSP_USING_SPI) || defined(BSP_USING_QSPI)
|
|
|
+#if defined(BSP_USING_SPI)
|
|
|
+
|
|
|
+#define LOG_TAG "drv.spi"
|
|
|
+#define DBG_ENABLE
|
|
|
+#define DBG_SECTION_NAME LOG_TAG
|
|
|
+#define DBG_LEVEL DBG_INFO
|
|
|
+#define DBG_COLOR
|
|
|
+#include <rtdbg.h>
|
|
|
+
|
|
|
#include <rthw.h>
|
|
|
#include <rtdevice.h>
|
|
|
#include <rtdef.h>
|
|
@@ -22,7 +30,7 @@
|
|
|
/* Private define ---------------------------------------------------------------*/
|
|
|
|
|
|
#ifndef NU_SPI_USE_PDMA_MIN_THRESHOLD
|
|
|
- #define NU_SPI_USE_PDMA_MIN_THRESHOLD 128
|
|
|
+ #define NU_SPI_USE_PDMA_MIN_THRESHOLD (128)
|
|
|
#endif
|
|
|
|
|
|
enum
|
|
@@ -52,9 +60,8 @@ static int nu_spi_register_bus(struct nu_spi *spi_bus, const char *name);
|
|
|
static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_message *message);
|
|
|
static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration);
|
|
|
|
|
|
-#if defined(BSP_USING_SPI_PDMA) || defined(BSP_USING_QSPI_PDMA)
|
|
|
+#if defined(BSP_USING_SPI_PDMA)
|
|
|
static void nu_pdma_spi_rx_cb(void *pvUserData, uint32_t u32EventFilter);
|
|
|
- static void nu_pdma_spi_tx_cb(void *pvUserData, uint32_t u32EventFilter);
|
|
|
static rt_err_t nu_pdma_spi_rx_config(struct nu_spi *spi_bus, uint8_t *pu8Buf, int32_t i32RcvLen, uint8_t bytes_per_word);
|
|
|
static rt_err_t nu_pdma_spi_tx_config(struct nu_spi *spi_bus, const uint8_t *pu8Buf, int32_t i32SndLen, uint8_t bytes_per_word);
|
|
|
static rt_size_t nu_spi_pdma_transmit(struct nu_spi *spi_bus, const uint8_t *send_addr, uint8_t *recv_addr, int length, uint8_t bytes_per_word);
|
|
@@ -63,10 +70,6 @@ static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device, struct rt_spi
|
|
|
void nu_spi_transfer(struct nu_spi *spi_bus, uint8_t *tx, uint8_t *rx, int length, uint8_t bytes_per_word);
|
|
|
void nu_spi_drain_rxfifo(SPI_T *spi_base);
|
|
|
|
|
|
-#if defined(BSP_USING_SPI_PDMA) || defined(BSP_USING_QSPI_PDMA)
|
|
|
- rt_err_t nu_hw_spi_pdma_allocate(struct nu_spi *spi_bus);
|
|
|
-#endif
|
|
|
-
|
|
|
/* Private variables ------------------------------------------------------------*/
|
|
|
static struct rt_spi_ops nu_spi_poll_ops =
|
|
|
{
|
|
@@ -193,7 +196,7 @@ static rt_err_t nu_spi_bus_configure(struct rt_spi_device *device,
|
|
|
u32BusClock = SPI_SetBusClock(spi_bus->spi_base, configuration->max_hz);
|
|
|
if (configuration->max_hz > u32BusClock)
|
|
|
{
|
|
|
- rt_kprintf("%s clock max frequency is %dHz (!= %dHz)\n", spi_bus->name, u32BusClock, configuration->max_hz);
|
|
|
+ LOG_W("%s clock max frequency is %dHz (!= %dHz)\n", spi_bus->name, u32BusClock, configuration->max_hz);
|
|
|
configuration->max_hz = u32BusClock;
|
|
|
}
|
|
|
|
|
@@ -235,21 +238,14 @@ exit_nu_spi_bus_configure:
|
|
|
return -(ret);
|
|
|
}
|
|
|
|
|
|
-#if defined(BSP_USING_SPI_PDMA) || defined(BSP_USING_QSPI_PDMA)
|
|
|
+#if defined(BSP_USING_SPI_PDMA)
|
|
|
static void nu_pdma_spi_rx_cb(void *pvUserData, uint32_t u32EventFilter)
|
|
|
{
|
|
|
- struct nu_spi *spi_bus;
|
|
|
- spi_bus = (struct nu_spi *)pvUserData;
|
|
|
+ struct nu_spi *spi_bus = (struct nu_spi *)pvUserData;
|
|
|
|
|
|
RT_ASSERT(spi_bus != RT_NULL);
|
|
|
|
|
|
- /* Get base address of spi register */
|
|
|
- SPI_T *spi_base = spi_bus->spi_base;
|
|
|
-
|
|
|
- if (u32EventFilter & NU_PDMA_EVENT_TRANSFER_DONE)
|
|
|
- {
|
|
|
- SPI_DISABLE_RX_PDMA(spi_base); // Stop DMA TX transfer
|
|
|
- }
|
|
|
+ rt_sem_release(spi_bus->m_psSemBus);
|
|
|
}
|
|
|
static rt_err_t nu_pdma_spi_rx_config(struct nu_spi *spi_bus, uint8_t *pu8Buf, int32_t i32RcvLen, uint8_t bytes_per_word)
|
|
|
{
|
|
@@ -299,24 +295,6 @@ exit_nu_pdma_spi_rx_config:
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
-static void nu_pdma_spi_tx_cb(void *pvUserData, uint32_t u32EventFilter)
|
|
|
-{
|
|
|
- struct nu_spi *spi_bus;
|
|
|
- spi_bus = (struct nu_spi *)pvUserData;
|
|
|
-
|
|
|
- RT_ASSERT(spi_bus != RT_NULL);
|
|
|
-
|
|
|
- /* Get base address of spi register */
|
|
|
- SPI_T *spi_base = spi_bus->spi_base;
|
|
|
-
|
|
|
- if (u32EventFilter & NU_PDMA_EVENT_TRANSFER_DONE)
|
|
|
- {
|
|
|
- SPI_DISABLE_TX_PDMA(spi_base); // Stop DMA TX transfer
|
|
|
- }
|
|
|
- rt_sem_release(spi_bus->m_psSemBus);
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
static rt_err_t nu_pdma_spi_tx_config(struct nu_spi *spi_bus, const uint8_t *pu8Buf, int32_t i32SndLen, uint8_t bytes_per_word)
|
|
|
{
|
|
|
rt_err_t result = RT_EOK;
|
|
@@ -328,15 +306,6 @@ static rt_err_t nu_pdma_spi_tx_config(struct nu_spi *spi_bus, const uint8_t *pu8
|
|
|
|
|
|
rt_uint8_t spi_pdma_tx_chid = spi_bus->pdma_chanid_tx;
|
|
|
|
|
|
- result = nu_pdma_callback_register(spi_pdma_tx_chid,
|
|
|
- nu_pdma_spi_tx_cb,
|
|
|
- (void *)spi_bus,
|
|
|
- NU_PDMA_EVENT_TRANSFER_DONE);
|
|
|
- if (result != RT_EOK)
|
|
|
- {
|
|
|
- goto exit_nu_pdma_spi_tx_config;
|
|
|
- }
|
|
|
-
|
|
|
if (pu8Buf == RT_NULL)
|
|
|
{
|
|
|
spi_bus->dummy = 0;
|
|
@@ -382,14 +351,14 @@ static rt_size_t nu_spi_pdma_transmit(struct nu_spi *spi_bus, const uint8_t *sen
|
|
|
result = nu_pdma_spi_tx_config(spi_bus, send_addr, length, bytes_per_word);
|
|
|
RT_ASSERT(result == RT_EOK);
|
|
|
|
|
|
- /* Trigger TX/RX at the same time. */
|
|
|
- SPI_TRIGGER_TX_PDMA(spi_base);
|
|
|
- SPI_TRIGGER_RX_PDMA(spi_base);
|
|
|
+ /* Trigger TX/RX PDMA transfer. */
|
|
|
+ SPI_TRIGGER_TX_RX_PDMA(spi_base);
|
|
|
|
|
|
- /* Wait PDMA transfer done */
|
|
|
+ /* Wait RX-PDMA transfer done */
|
|
|
rt_sem_take(spi_bus->m_psSemBus, RT_WAITING_FOREVER);
|
|
|
|
|
|
- while (SPI_IS_BUSY(spi_base));
|
|
|
+ /* Stop TX/RX DMA transfer. */
|
|
|
+ SPI_DISABLE_TX_RX_PDMA(spi_base);
|
|
|
|
|
|
return result;
|
|
|
}
|
|
@@ -416,7 +385,7 @@ exit_nu_hw_spi_pdma_allocate:
|
|
|
|
|
|
return -(RT_ERROR);
|
|
|
}
|
|
|
-#endif /* #if defined(BSP_USING_SPI_PDMA) || defined(BSP_USING_QSPI_PDMA) */
|
|
|
+#endif /* #if defined(BSP_USING_SPI_PDMA) */
|
|
|
|
|
|
void nu_spi_drain_rxfifo(SPI_T *spi_base)
|
|
|
{
|
|
@@ -432,11 +401,11 @@ void nu_spi_drain_rxfifo(SPI_T *spi_base)
|
|
|
static int nu_spi_read(SPI_T *spi_base, uint8_t *recv_addr, uint8_t bytes_per_word)
|
|
|
{
|
|
|
int size = 0;
|
|
|
- uint32_t val;
|
|
|
|
|
|
// Read RX data
|
|
|
if (!SPI_GET_RX_FIFO_EMPTY_FLAG(spi_base))
|
|
|
{
|
|
|
+ uint32_t val;
|
|
|
// Read data from SPI RX FIFO
|
|
|
switch (bytes_per_word)
|
|
|
{
|
|
@@ -455,6 +424,9 @@ static int nu_spi_read(SPI_T *spi_base, uint8_t *recv_addr, uint8_t bytes_per_wo
|
|
|
case 1:
|
|
|
*recv_addr = SPI_READ_RX(spi_base);
|
|
|
break;
|
|
|
+ default:
|
|
|
+ LOG_E("Data length is not supported.\n");
|
|
|
+ break;
|
|
|
}
|
|
|
size = bytes_per_word;
|
|
|
}
|
|
@@ -481,6 +453,9 @@ static int nu_spi_write(SPI_T *spi_base, const uint8_t *send_addr, uint8_t bytes
|
|
|
case 1:
|
|
|
SPI_WRITE_TX(spi_base, *((uint8_t *)send_addr));
|
|
|
break;
|
|
|
+ default:
|
|
|
+ LOG_E("Data length is not supported.\n");
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
return bytes_per_word;
|
|
@@ -534,7 +509,7 @@ static void nu_spi_transmission_with_poll(struct nu_spi *spi_bus,
|
|
|
}
|
|
|
} // else
|
|
|
|
|
|
- /* Wait RX or drian RX-FIFO */
|
|
|
+ /* Wait RX or drain RX-FIFO */
|
|
|
if (recv_addr)
|
|
|
{
|
|
|
// Wait SPI transmission done
|
|
@@ -565,8 +540,8 @@ void nu_spi_transfer(struct nu_spi *spi_bus, uint8_t *tx, uint8_t *rx, int lengt
|
|
|
#if defined(BSP_USING_SPI_PDMA)
|
|
|
/* DMA transfer constrains */
|
|
|
if ((spi_bus->pdma_chanid_rx >= 0) &&
|
|
|
- (!(uint32_t)tx % bytes_per_word) &&
|
|
|
- (!(uint32_t)rx % bytes_per_word) &&
|
|
|
+ !((uint32_t)tx % bytes_per_word) &&
|
|
|
+ !((uint32_t)rx % bytes_per_word) &&
|
|
|
(bytes_per_word != 3) &&
|
|
|
(length >= NU_SPI_USE_PDMA_MIN_THRESHOLD))
|
|
|
nu_spi_pdma_transmit(spi_bus, tx, rx, length, bytes_per_word);
|
|
@@ -594,7 +569,7 @@ static rt_uint32_t nu_spi_bus_xfer(struct rt_spi_device *device, struct rt_spi_m
|
|
|
if ((message->length % bytes_per_word) != 0)
|
|
|
{
|
|
|
/* Say bye. */
|
|
|
- rt_kprintf("%s: error payload length(%d%%%d != 0).\n", spi_bus->name, message->length, bytes_per_word);
|
|
|
+ LOG_E("%s: error payload length(%d%%%d != 0).\n", spi_bus->name, message->length, bytes_per_word);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -653,7 +628,7 @@ static int rt_hw_spi_init(void)
|
|
|
{
|
|
|
if (nu_hw_spi_pdma_allocate(&nu_spi_arr[i]) != RT_EOK)
|
|
|
{
|
|
|
- rt_kprintf("Failed to allocate DMA channels for %s. We will use poll-mode for this bus.\n", nu_spi_arr[i].name);
|
|
|
+ LOG_W("Failed to allocate DMA channels for %s. We will use poll-mode for this bus.\n", nu_spi_arr[i].name);
|
|
|
}
|
|
|
}
|
|
|
#endif
|