microcontroller - Direct memory access RX for the STM32L1 -


i've been trying while transmit block of data computer stm32l100c-disco on usart. performance reasons, done using dma. far, however, have not been able work. cannot seem figure out might doing wrong, figured i'd ask here.

i'm using libopencm3, unfortunately, otherwise excellent repository of examples not appear contain 1 dma on stm32l1xxx. checked covered bases when comes configuration options available in common dma header file, though.

naturally, i've referred reference manual stm32l1xxx, mentions following requests table dma1, leading me believe channel 6 need using..

dma requests table

as unsure size of memory , peripheral (i.e. usart2), varied across combinations of 8, 16 , 32 bit both, no avail.

without further ado; minimal working (well, not working..) excerpt of i'm trying do. feel i'm overlooking in dma configuration, usart works fine.

at point, appreciated.

the idea behind code loop forever until data in buffer replaced entirely, , when is, output it. host, i'm sending kilobyte of highly recognisable data, i'm getting malformed garbage. is writing something, not intend write.

edit: here's picture of memory map. usart2_base evaluates 0x4000 4400, seems right well.

memory map

#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;     (i = 0; < 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;         (i = 0; < buflength; i++) {             if (buffer[i] == 65) {                 flag = 1;             }         }     }     usart_disable_rx_dma(usart2);      (i = 0; < buflength; i++) {         usart_send_blocking(usart2, buffer[i]);     }     usart_send_blocking(usart2, '\n');      return 0; } 

i not familiar libopencm3 or stm32l series, familiar stm32f series. know there differences in peripherals, believe mistake lies in following line:

dma_set_peripheral_address(dma1, dma_channel6, (uint32_t) usart2_base); 

here setting dma peripheral address usart2_base address, typically, want set usart2 data register, may not right @ usart2_base.

i see of comments on question have pointed out, there still remaining question of how indicate data register. st peripheral library, there memory mapped structures peripherals. appears libopencm3 has defined macro can use data register address: usart2_dr. here definition in documentation

so, believe if change line above following, may solve problem:

dma_set_peripheral_address(dma1, dma_channel6, (uint32_t) usart2_dr); 

Comments

Popular posts from this blog

android - Gradle sync Error:Configuration with name 'default' not found -

java - Andrioid studio start fail: Fatal error initializing 'null' -

html - jQuery UI Sortable - Remove placeholder after item is dropped -