w800 LSPI 接收数据不正确

发布于 2022-09-23 15:05:56

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

查看更多

关注者
0
被浏览
2.1k
1 个回答
isme
isme 认证专家 2022-09-26
冰镇大西瓜

我实际测试了一下,用两个W80X芯片,一个当主一个当从,是可以通讯的,需要注意的是接线一一对应关系。

      主 从
MOSI PB5 PB5
CLK  PB2 PB2
MISO PB3 PB3
CS   PB4 PB4

image.png

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览