본문 바로가기

RaspberryPi/RP2040

[RP2040_W5500] RP2040 C++ SDK 환경에서 SPI DMA 성능 측정, Arduino 개발환경과 속도 비교

RP2040 을 SDK에서 구동하면 Aduino 개발환경에서 보다 속도가 빨라지는데 SPI DMA 테스트도  RP2040 C/C++ SDK로 테스트 해보자.

Aduino IDE에서 SPI 테스트 했던 코드로 SPI 속도를 측정해 보자.

 

 

SDK에서 제공하는 SPI 예제를 이용하여 기본 테스트를 해 볼수 있다.

#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "hardware/spi.h"

int main() {
    stdio_init_all();

    printf("Hello, MPU9250! Reading raw data from registers via SPI...\n");

    // This example will use SPI0 at 0.5MHz.
    spi_init(SPI_PORT, 33000 * 1000);
    
    gpio_set_function(PIN_MISO, GPIO_FUNC_SPI);
    gpio_set_function(PIN_SCK, GPIO_FUNC_SPI);
    gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI);
    
    // Make the SPI pins available to picotool
    bi_decl(bi_3pins_with_func(PIN_MISO, PIN_MOSI, PIN_SCK, GPIO_FUNC_SPI));


	while(1)
	{
		spi_write_blocking(spi_default, txbuf, 2);	
		spi_write_blocking(spi_default, txbuf, 2);
		sleep_ms(10);
	}
}

 

SDK에서 SPI 기본 예제를 구동하면 SPI 전송 지연시간이 60ns 정도 이고 블록간 지연시간도 780ns 로 Arduino 환경에서 보다 많이 빨라 졌다.

 

 

블록전송 함수를 이용해도 속도를 높일 수 있지만 좀더 속도를 높이기 위해 SPI DMA를 이용하여 테스트 해 보자.

 

SPI DMA 전송 함수

static void spi_write_buf(uint8_t *pBuf, uint16_t len)
{
	while (dma_channel_is_busy(dma_tx));
    dma_channel_configure(dma_tx, &dma_conf,
                          &spi_get_hw(spi_default)->dr, // write address
                          pBuf, // read address
                          len, // element count (each element is of size transfer_data_size)
                          true); // don't start yet	
}

 

 

RP2040 C/C++ SDK에서 SPI DMA 테스트 예제 코드

#include <stdio.h>
#include <string.h>
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "hardware/spi.h"

#include "hardware/dma.h"

int main() {
    stdio_init_all();

    printf("RP2040 SPI DMA Test\n");

    // This example will use SPI0 at 0.5MHz.
    spi_init(SPI_PORT, 33000 * 1000);
    
    gpio_set_function(PIN_MISO, GPIO_FUNC_SPI);
    gpio_set_function(PIN_SCK, GPIO_FUNC_SPI);
    gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI);
    
    // Make the SPI pins available to picotool
    bi_decl(bi_3pins_with_func(PIN_MISO, PIN_MOSI, PIN_SCK, GPIO_FUNC_SPI));

    const uint dma_tx = dma_claim_unused_channel(true);


    printf("Configure TX DMA\n");
    dma_channel_config c = dma_channel_get_default_config(dma_tx);
    channel_config_set_transfer_data_size(&c, DMA_SIZE_8);
    channel_config_set_dreq(&c, spi_get_dreq(spi_default, true));
    dma_channel_configure(dma_tx, &c,
                          &spi_get_hw(spi_default)->dr, // write address
                          txbuf, // read address
                          TEST_SIZE, // element count (each element is of size transfer_data_size)
                          false); // don't start yet
	
    dma_start_channel_mask((1u << dma_tx));                          
                          
	while(1)
	{
		spi_write_buf(spi_default, txbuf, 2);	
		spi_write_buf(spi_default, txbuf, 2);
		sleep_ms(10);
	}
}

 

 

SPI DMA 테스트 결과 SPI전송 지연은 64ns정도로 측정이 되고 블록간 지연시간도 120ns로 빨라지는 것을 확인 할 수 있다.

 

반응형