数据接收的长度是正确的,但是数据全部是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