Hi,
I choose the SSP1 controller, and LPC4327 as master mode. I think set the SPI clockrate 21 Mhz has met the spec.
I show the open and read function as below:
int _open(uint32_t clk_rate, uint32_t addr)
{
_dma_tx_ch_num = dma_register_channel(_dma_tx_completed_isr);
_dma_rx_ch_num = dma_register_channel(_dma_rx_completed_isr);
Board_SSP_Init(LPC_SSP1);
Chip_SSP_Init(LPC_SSP1);
Chip_SSP_SetFormat(LPC_SSP1, SSP_BITS_8, SSP_FRAMEFORMAT_SPI, SSP_CLOCK_CPHA0_CPOL0);
Chip_SSP_SetMaster(LPC_SSP1, 1);
Chip_SSP_SetBitRate(LPC_SSP1, clk_rate);
Chip_SSP_Enable(LPC_SSP1);
_cs_enable(false);
printf("SPI master is open.\n");
return 0;
}
int _read(uint8_t addr, void* data, size_t size)
{
uint8_t buf[0x80];
int cnt;
if (size == 0)
return 0;
if (IS_BIT_CLR(LPC_SSP1->CR1, SSP_CR1_SSP_EN)) {
printf("[SPI:%s] The device is not open.\n", __func__);
return -1;
}
if (addr + size > sizeof(buf)) {
printf("[SPI:%s] Too large data size: %u\n", __func__, size);
return -1;
}
/* Fill the address to the buffer. */
for (cnt = 0; cnt < size; cnt++)
buf[cnt] = addr + cnt;
/* Prepare DMA transfers. */
DMA_TransferDescriptor_t dma_tx_desc;
DMA_TransferDescriptor_t dma_tx_desc_dummy;
if (SUCCESS != Chip_GPDMA_PrepareDescriptor(LPC_GPDMA, &dma_tx_desc,
(uint32_t)buf, GPDMA_CONN_SSP1_Tx, size,
GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA, &dma_tx_desc_dummy)) {
printf("[SPI:%s] Fail to prepare the DMA descriptor.\n", __func__);
return -1;
}
if (SUCCESS != Chip_GPDMA_PrepareDescriptor(LPC_GPDMA, &dma_tx_desc_dummy,
(uint32_t)buf, GPDMA_CONN_SSP1_Tx, 1,
GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA, NULL)) {
printf("[SPI:%s] Fail to prepare the DMA descriptor.\n", __func__);
return -1;
}
DMA_TransferDescriptor_t dma_rx_desc_dummy;
DMA_TransferDescriptor_t dma_rx_desc;
if (SUCCESS != Chip_GPDMA_PrepareDescriptor(LPC_GPDMA, &dma_rx_desc_dummy,
GPDMA_CONN_SSP1_Rx, (uint32_t)buf, 1,
GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA, &dma_rx_desc)) {
printf("[SPI:%s] Fail to prepare the DMA descriptor.\n", __func__);
return -1;
}
if (SUCCESS != Chip_GPDMA_PrepareDescriptor(LPC_GPDMA, &dma_rx_desc,
GPDMA_CONN_SSP1_Rx, (uint32_t)data, size,
GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA, NULL)) {
printf("[SPI:%s] Fail to prepare the DMA descriptor.\n", __func__);
return -1;
}
/* Start DMA transfers. */
_is_dma_tx_completed = false;
_is_dma_rx_completed = false;
cnt = -1;
_cs_enable(true);
Chip_SSP_DMA_Enable(LPC_SSP1);
if (SUCCESS != Chip_GPDMA_SGTransfer(LPC_GPDMA, _dma_tx_ch_num,
(uint32_t)buf, GPDMA_CONN_SSP1_Tx,
&dma_tx_desc, GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA)) {
printf("[SPI:%s] Fail to start the DMA transfer.\n", __func__);
goto _disable_ssp_dma;
}
if (SUCCESS != Chip_GPDMA_SGTransfer(LPC_GPDMA, _dma_rx_ch_num,
GPDMA_CONN_SSP1_Rx, (uint32_t)buf,
&dma_rx_desc_dummy, GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA)) {
printf("[SPI:%s] Fail to start the DMA transfer.\n", __func__);
goto _disable_ssp_dma;
}
/* Wait DMA transfers completed. */
while (!_is_dma_tx_completed || !_is_dma_rx_completed);
cnt = size;
_disable_ssp_dma:
Chip_SSP_DMA_Disable(LPC_SSP1);
_cs_enable(false);
return cnt;
}
Actually, I have tried to use polling mode instead of DMA. But the data still shift 1 bit.