私はしばらくの間、コンピューターからSTM32L100C-DISCO
オーバー USART にデータのブロックを送信しようとしてきました。パフォーマンス上の理由から、これは DMA を使用して行われます。しかし、これまでのところ、私はそれを機能させることができませんでした。何が間違っているのかわからないので、ここで質問したいと思います。
私はlibopencm3を使用していますが、残念ながら、それ以外の優れた例のリポジトリには、STM32L1xxx
. ただし、一般的な DMA ヘッダー ファイルで使用可能な構成オプションに関しては、すべての基本をカバーしていることを確認しました。
当然のことながら、STM32L1xxx のリファレンス マニュアルを参照したところ、次の DMA1 の要求テーブルが記載されているため、使用する必要があるのはチャネル 6 であると確信しました。
メモリと周辺機器 (つまり USART2) のサイズがよくわからなかったので、8 ビット、16 ビット、32 ビットのすべての組み合わせを変更しましたが、役に立ちませんでした。
難しい話は抜きにして; これは、私がやろうとしていることの最小限の動作 (まあ、動作していません..) の抜粋です。USART 自体は正常に動作するため、DMA 構成で何かを見落としているように感じます。
この時点で、何でも感謝されます。
このコードの背後にある考え方は、基本的に、バッファ内のデータが完全に置き換えられるまで永久にループし、置き換えられたら出力するというものです。ホストから、非常に認識しやすい 1 キロバイトのデータを送信していますが、返ってきたのは不正な形式のゴミだけです。それは何かを書いていますが、私が書こうとしているものではありません。
編集:これはメモリマップの写真です。USART2_BASE
と評価される0x4000 4400
ので、それも問題ないようです。
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include "libopencm3/stm32/usart.h"
#include <libopencm3/stm32/dma.h>
const int buflength = 1024;
uint8_t buffer[1024];
static void clock_setup(void)
{
rcc_clock_setup_pll(&clock_config[CLOCK_VRANGE1_HSI_PLL_32MHZ]);
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_GPIOAEN);
rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_USART2EN);
rcc_periph_clock_enable(RCC_DMA1);
}
static void gpio_setup(void)
{
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO3);
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO2);
gpio_set_af(GPIOA, GPIO_AF7, GPIO3);
gpio_set_af(GPIOA, GPIO_AF7, GPIO2);
}
static void usart_setup(void)
{
usart_set_baudrate(USART2, 115200);
usart_set_databits(USART2, 8);
usart_set_stopbits(USART2, USART_STOPBITS_1);
usart_set_mode(USART2, USART_MODE_TX_RX);
usart_set_parity(USART2, USART_PARITY_NONE);
usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);
usart_enable(USART2);
}
static void dma_setup(void)
{
dma_channel_reset(DMA1, DMA_CHANNEL6);
dma_set_priority(DMA1, DMA_CHANNEL6, DMA_CCR_PL_VERY_HIGH);
dma_set_memory_size(DMA1, DMA_CHANNEL6, DMA_CCR_MSIZE_8BIT);
dma_set_peripheral_size(DMA1, DMA_CHANNEL6, DMA_CCR_PSIZE_8BIT);
dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL6);
dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL6);
dma_enable_circular_mode(DMA1, DMA_CHANNEL6);
dma_set_read_from_peripheral(DMA1, DMA_CHANNEL6);
dma_disable_transfer_error_interrupt(DMA1, DMA_CHANNEL6);
dma_disable_half_transfer_interrupt(DMA1, DMA_CHANNEL6);
dma_disable_transfer_complete_interrupt(DMA1, DMA_CHANNEL6);
dma_set_peripheral_address(DMA1, DMA_CHANNEL6, (uint32_t) USART2_BASE);
dma_set_memory_address(DMA1, DMA_CHANNEL6, (uint32_t) buffer);
dma_set_number_of_data(DMA1, DMA_CHANNEL6, buflength);
dma_enable_channel(DMA1, DMA_CHANNEL6);
}
int main(void)
{
int i;
for (i = 0; i < buflength; i++) {
buffer[i] = 65;
}
clock_setup();
gpio_setup();
usart_setup();
dma_setup();
usart_enable_rx_dma(USART2);
char flag = 1;
while (flag) {
flag = 0;
for (i = 0; i < buflength; i++) {
if (buffer[i] == 65) {
flag = 1;
}
}
}
usart_disable_rx_dma(USART2);
for (i = 0; i < buflength; i++) {
usart_send_blocking(USART2, buffer[i]);
}
usart_send_blocking(USART2, '\n');
return 0;
}