Arduino IDE 개발환에서 RP2040의 SPI 전송률 테스트 하면 데이터 전송 간격이 1.2us 정도로 측정 된다.(RP2040 SPI테스트 참고)
고속의 데이터 전송을 위해서는 DMA가 필요한데 RP2040에서 SPI DMA 테스트를 진행 해 보자.
DMA 초기화 함수
#include "hardware/dma.h"
int32_t dma_tx_channel;
dma_channel_config dma_tx_config;
#define SPI_X spi0
bool initDMA(bool ctrl_cs)
{
//ctrl_cs = ctrl_cs; // stop unused parameter warning
dma_tx_channel = dma_claim_unused_channel(false);
if (dma_tx_channel < 0) return false;
dma_tx_config = dma_channel_get_default_config(dma_tx_channel);
channel_config_set_transfer_data_size(&dma_tx_config, DMA_SIZE_8);
channel_config_set_dreq(&dma_tx_config, spi_get_index(SPI_X) ? DREQ_SPI1_TX : DREQ_SPI0_TX);
//DMA_Enabled = true;
return true;
}
RP2040 SPI DMA 테스트 코드
void setup()
{
Serial.begin(115200);
Serial.println("RP2040 SPI DMA Test..");
pinMode(PIN_OUT, OUTPUT);
digitalWrite(PIN_OUT, 1);
delay(2000);
SPI.begin();
initDMA(1);
SPI.beginTransaction(SPISettings(31250000, MSBFIRST, SPI_MODE0));
}
unsigned char buf[2] = {1,2};
void loop() {
digitalWrite(PIN_OUT, 1);
//SPI.transfer(buf, sizeof(buf));
//SPI.transfer(buf, sizeof(buf));
dma_channel_configure(dma_tx_channel, &dma_tx_config, &spi_get_hw(SPI_X)->dr, (uint8_t*)buf, sizeof(buf), true);
digitalWrite(PIN_OUT, 0);
delay(10);
}
DMA를 사용하면 SPI 전송 간격이 90ns 정도로 10배 이상 빨라지는 것을 확인 할 수 있다.
DMA 전송시 지연시간을 측정해 보기 위해 dmaWait() 함수를 추가 하고 두번 전송하는 코드를 작성해 보자.
void dmaWait(void)
{
while (dma_channel_is_busy(dma_tx_channel));
#if !defined (RP2040_PIO_INTERFACE)
// For SPI must also wait for FIFO to flush and reset format
while (spi_get_hw(SPI_X)->sr & SPI_SSPSR_BSY_BITS) {};
hw_write_masked(&spi_get_hw(SPI_X)->cr0, (16 - 1) << SPI_SSPCR0_DSS_LSB, SPI_SSPCR0_DSS_BITS);
#endif
}
unsigned char buf[2] = {1,2};
void loop() {
digitalWrite(PIN_OUT, 1);
//SPI.transfer(buf, sizeof(buf));
//SPI.transfer(buf, sizeof(buf));
dmaWait();
dma_channel_configure(dma_tx_channel, &dma_tx_config, &spi_get_hw(SPI_X)->dr, (uint8_t*)buf, sizeof(buf), true);
dmaWait();
dma_channel_configure(dma_tx_channel, &dma_tx_config, &spi_get_hw(SPI_X)->dr, (uint8_t*)buf, sizeof(buf), true);
digitalWrite(PIN_OUT, 0);
delay(10);
}
테스트 결과 DMA 전송간 지연시간도 500ns정도로 측정이 된다.
반응형