数据接收的长度是正确的, 但是数据全部是 0, 用逻辑分析仪测出来的时序是对的, MOSI 也没有被拉低, 但是出来的数据一直是 0, LSPI_SLAVE_CLK-- WM_IO_PB_02, LSPI_SLAVE_CS-- WM_IO_PB_04, LSPI_SLAVE_MOSI-- WM_IO_PB_03, 具体代码如下:
static struct dma_descriptor desc[2];
void SpiSlaveInit (uint8_t *buf, uint32_t len)
{
uint32_t temp = 0;
// io cfg
wm_spi_ck_config (LSPI_SLAVE_CLK) ;
wm_spi_cs_config (LSPI_SLAVE_CS) ;
wm_spi_di_config (LSPI_SLAVE_MOSI) ;
// open peripheral clock
tls_reg_write32 (HR_CLK_BASE_ADDR, (tls_reg_read32 (HR_CLK_BASE_ADDR) | (1 7) | (1 8) ) ) ; // spi clk | dma clk
// int spi
tls_reg_write32 (HR_SPI_CHCFG_REG, (1 22) ) ; // clear rx fifo
tls_reg_write32 (HR_SPI_SPICFG_REG, ( (0 3) | (0 2) | (0 1) | (0 0) ) ) ; // little endian | slave | cpha | cpol
tls_reg_write32 (HR_SPI_MODECFG_REG, ( (0 6) | (1 1) ) ) ; // rxtrigger level | rxdma on
tls_reg_write32 (HR_SPI_INT_MASK_REG, 0xFF) ; // int msk
tls_reg_write32 (HR_SPI_INT_STATUS_REG, 0xFF) ; // clear int flag
// int dma
tls_reg_write32 (HR_DMA_INT_MASK, (tls_reg_read32 (HR_DMA_INT_MASK) & ~ (0x02 (SPI_SLAVE_RX_DMA_CH * 2) ) ) ) ; // enable done int
tls_reg_write32 (HR_DMA_INT_SRC, (tls_reg_read32 (HR_DMA_INT_SRC) | (0x02 (SPI_SLAVE_RX_DMA_CH * 2) ) ) ) ; // clear done int flag
DMA_MODE_REG (SPI_SLAVE_RX_DMA_CH) = ( (1 6) | (4 2) | (1 1) | (1 0) ) ; // link en | spi rx req | link mode | hard mdoe
temp = ( ( (len / 2) 8) | (0 7) | (2 5) | (1 3) | (0 1) ) ; // len | burst size | word | dest inc | src not inc
desc[0]. valid = (1 31) ;
desc[0]. src_addr = HR_SPI_RXDATA_REG;
desc[0]. dest_addr = (uint32_t) buf;
desc[0]. dma_ctrl = (temp 1) ;
desc[0]. next = &desc[1];
desc[1]. valid = (1 31) ;
desc[1]. src_addr = HR_SPI_RXDATA_REG;
desc[1]. dest_addr = (uint32_t) (buf + len / 2) ;
desc[1]. dma_ctrl = (temp 1) ;
desc[1]. next = NULL; //&desc[0];
DMA_DESC_ADDR_REG (SPI_SLAVE_RX_DMA_CH) = (uint32_t) & (desc[0]) ;
tls_irq_enable (DMA_Channel0_IRQn) ;
DMA_CHNLCTRL_REG (SPI_SLAVE_RX_DMA_CH) = (1 0) ; // dma on
tls_reg_write32 (HR_SPI_CHCFG_REG, tls_reg_read32 (HR_SPI_CHCFG_REG) | (1 20) ) ; // rx on
}
__attribute__ ( (weak) ) void SpiDmaRxHalfCplt (uint8_t *buf, uint32_t len)
{
printf ("\r\nhalf irq\r\n") ;
printf ("len: %d\r\n", len) ;
for (size_t i = 0; i len; i++)
{
printf ("0X%02X ", buf[i]) ;
}
printf ("\r\nexti half irq\r\n") ;
}
__attribute__ ( (weak) ) void SpiDmaRxCplt (uint8_t *buf, uint32_t len)
{
printf ("\r\nfull irq\r\n") ;
printf ("len: %d\r\n", len) ;
for (size_t i = 0; i len; i++)
{
printf ("0X%02X ", buf[i]) ;
}
printf ("\r\nexti full irq\r\n") ;
}
ATTRIBUTE_ISR void DMA_Channel0_IRQHandler (void)
{
// csi_kernel_intrpt_enter () ;
tls_reg_write32 (HR_DMA_INT_SRC, (0x02 (SPI_SLAVE_RX_DMA_CH * 2) ) ) ;
if (desc[0]. valid == 0)
{
desc[0]. valid = (1 31) ;
SpiDmaRxHalfCplt ( (uint8_t *) (desc[0]. dest_addr) , (desc[0]. dma_ctrl 7) ) ;
}
else if (desc[1]. valid == 0)
{
desc[1]. valid = (1 31) ;
SpiDmaRxCplt ( (uint8_t *) (desc[1]. dest_addr) , (desc[1]. dma_ctrl 7) ) ;
}
// csi_kernel_intrpt_exit () ;
}
把 wm_spi_di_config 改成 wm_spi_do_config 就可以了
@isme 我这边改了 GPIO 复用引脚之后, 又不行了
@nzttj 我刚刚试了可以呀.
@isme 可以看一下你从机部分的代码吗?
@nzttj 也就改了 GPIO 复用引脚, 其他一样啊.
@isme 用的是我上面贴的代码吗?
@isme 我这边出来的数据全是 0
@isme 已解决, sdk 在开始的时候默认初始化了 LSPI 并且设置了对应的 IO 口, 把 SDK 部分的 LSPI 初始化屏蔽了就可以了
@nzttj
spi_slave. h
spi_slave. c