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

撰寫答案

請登錄後再發布答案,點擊登錄

發布
問題

分享
好友

手機
浏覽

掃碼手機浏覽