/**
Projeto: Cópia de Dados com DMA no Raspberry Pi Pico
Autor: Adaptado do GitHub do Raspberry Pi Pico SDK.
Baseado em exemplo oficial disponível no GitHub do Raspberry Pi Pico SDK.
Objetivo:
Este programa demonstra o uso do DMA (Direct Memory Access) no Raspberry Pi Pico
para copiar dados de um buffer de origem (`src`) para um buffer de destino (`dst`)
sem utilizar a CPU diretamente durante a cópia. O buffer de origem recebe o dado a
a partir de uma entrada via monitor serial e esse dado é transmitido entre regiões
de memória por meio do DMA. O dado de destino é utilizado para acionar o LED RGB
*/
#include <stdio.h> // Função necessárias para entrada e saída serial
#include "pico/stdlib.h" // Funções padrão do SDK Pico
#include "hardware/dma.h" // Controle do periférico DMA
#include <string.h> // Para strlen()
// Definições dos pinos dos LEDs
#define RED_PIN 13
#define GREEN_PIN 11
#define BLUE_PIN 12
// Buffers de entrada e destino
char src[2]; // Buffer onde scanf armazena o texto digitado
char dst[2]; // Buffer de destino da cópia via DMA
// Função auxiliar para acender LEDs
void set_led_color(bool r, bool g, bool b) {
gpio_put(RED_PIN, r);
gpio_put(GREEN_PIN, g);
gpio_put(BLUE_PIN, b);
}
void main() {
stdio_init_all(); // Inicializa a interface de saída padrão (ex: USB serial)
sleep_ms(2000); // Estabilização do USB
// Inicializa os pinos dos LEDs
gpio_init(RED_PIN);
gpio_set_dir(RED_PIN, GPIO_OUT);
gpio_init(GREEN_PIN);
gpio_set_dir(GREEN_PIN, GPIO_OUT);
gpio_init(BLUE_PIN);
gpio_set_dir(BLUE_PIN, GPIO_OUT);
set_led_color(false, false, false); // LEDs inicialmente apagados
// Solicita um canal DMA livre (ou entra em pânico se não houver nenhum)
int chan = dma_claim_unused_channel(true);
// Configura o canal DMA:
// - Transferência de 8 bits (1 byte)
// - Incrementa os endereços de leitura e escrita
dma_channel_config c = dma_channel_get_default_config(chan);
channel_config_set_transfer_data_size(&c, DMA_SIZE_8); // Cada transferência terá 8 bits
channel_config_set_read_increment(&c, true); // Avança o ponteiro de leitura (src)
channel_config_set_write_increment(&c, true); // Avança o ponteiro de escrita (dst)
while (true) {
// Lê comando via teclado
printf("Digite uma letra (r = red, g = green, b = blue, w = white, o = off): ");
scanf(" %c", src); // Armazena entrada no buffer src
// Inicia a transferência de dados do src para o dst
dma_channel_configure(
chan, // Canal DMA utilizado
&c, // Configurações aplicadas
dst, // Endereço de destino (RAM)
src, // Endereço de origem (RAM)
count_of(src), // Quantidade de bytes a copiar
true // Inicia a transferência imediatamente
);
// Aguarda até que a transferência DMA seja concluída
dma_channel_wait_for_finish_blocking(chan);
// Compara o conteúdo copiado no buffer dst
switch (dst[0]) {
case 'r':
set_led_color(true, false, false);
break;
case 'g':
set_led_color(false, true, false);
break;
case 'b':
set_led_color(false, false, true);
break;
case 'o':
set_led_color(false, false, false);
break;
case 'w':
set_led_color(true, true, true);
break;
default:
printf("Comando inválido: %c\n", dst[0]);
break;
}
printf("Caractere recebido via DMA: %c\n", dst[0]);
sleep_ms(300);
}
}Loading
pi-pico-w
pi-pico-w