stm32f4-uart-bootloader

Simple UART bootloader for STM32F4 MCU's
git clone git://git.mdnr.space/stm32f4-uart-bootloader
Log | Files | Refs | Submodules | README | LICENSE

drv-usart-dma.c (6454B)


      1 /*#include "drv-usart.h"*/
      2 /*#include "shared/drivers/drv-dma.h"*/
      3 #include "drv-usart-dma.h"
      4 #include "shared/drv-gpio.h"
      5 #include <libopencm3/cm3/nvic.h>
      6 #include <libopencm3/stm32/f4/nvic.h>
      7 #include <libopencm3/stm32/f4/rcc.h>
      8 
      9 static uint8_t dbgRxBuf[DMA_RX_BUFFER_SIZE];
     10 static uint8_t dbgTxBuf[DMA_TX_BUFFER_SIZE];
     11 static uint8_t gsmRxBuf[DMA_RX_BUFFER_SIZE];
     12 static uint8_t gsmTxBuf[DMA_TX_BUFFER_SIZE];
     13 
     14 USART_t dbg;
     15 USART_t gsm;
     16 USART_t *comm;
     17 
     18 void res_usart_init(void)
     19 {
     20     dbg.port = USART1;
     21     dbg.clock = RCC_USART1;
     22     dbg.nvic_irq = NVIC_USART1_IRQ;
     23 
     24     dbg.gpio_port = SERIAL_PORT;
     25     dbg.gpio_tx = SERIAL_TX_PIN;
     26     dbg.gpio_rx = SERIAL_RX_PIN;
     27 
     28     dbg.dma.addr = DMA2;
     29     dbg.dma.clock = RCC_DMA2;
     30     dbg.dma.tx_stream = DMA_STREAM7;
     31     dbg.dma.rx_stream = DMA_STREAM2;
     32     dbg.dma.txBuf = dbgTxBuf;
     33     dbg.dma.rxBuf = dbgRxBuf;
     34     dbg.dma.tx_stream_irq = NVIC_DMA2_STREAM7_IRQ; 
     35     dbg.dma.rx_stream_irq = NVIC_DMA2_STREAM2_IRQ; 
     36 
     37     gsm.port = USART2;
     38     gsm.clock = RCC_USART2;
     39     gsm.nvic_irq = NVIC_USART2_IRQ;
     40 
     41     gsm.gpio_port = GSM_PORT;
     42     gsm.gpio_tx = GSM_TX_PIN;
     43     gsm.gpio_rx = GSM_RX_PIN;
     44 
     45     gsm.dma.addr = DMA1;
     46     gsm.dma.clock = RCC_DMA1;
     47     gsm.dma.tx_stream = DMA_STREAM6;
     48     gsm.dma.rx_stream = DMA_STREAM5;
     49     gsm.dma.txBuf = gsmTxBuf;
     50     gsm.dma.rxBuf = gsmRxBuf;
     51     gsm.dma.tx_stream_irq = NVIC_DMA1_STREAM6_IRQ; 
     52     gsm.dma.rx_stream_irq = NVIC_DMA1_STREAM5_IRQ; 
     53 }
     54 
     55 static void setup_dma_for_usart(USART_t *usart)
     56 {
     57     rcc_periph_clock_enable(usart->dma.clock);
     58     // Stream5: usart_rx
     59     dma_disable_stream(usart->dma.addr, usart->dma.rx_stream);
     60     dma_set_peripheral_address(usart->dma.addr, usart->dma.rx_stream, usart->port + 0x04); // DR register of usart->port
     61     dma_set_memory_address(usart->dma.addr, usart->dma.rx_stream, (uint32_t)usart->dma.rxBuf);
     62     dma_set_number_of_data(usart->dma.addr, usart->dma.rx_stream, DMA_RX_BUFFER_SIZE);
     63     dma_channel_select(usart->dma.addr, usart->dma.rx_stream, DMA_SxCR_CHSEL_4);
     64     dma_enable_memory_increment_mode(usart->dma.addr, usart->dma.rx_stream);
     65     dma_set_transfer_mode(usart->dma.addr, usart->dma.rx_stream, DMA_SxCR_DIR_PERIPHERAL_TO_MEM);
     66     dma_enable_circular_mode(usart->dma.addr, usart->dma.rx_stream);
     67     
     68     // Stream6: usart_tx
     69     dma_disable_stream(usart->dma.addr, usart->dma.tx_stream);
     70     dma_set_peripheral_address(usart->dma.addr, usart->dma.tx_stream, usart->port + 0x04); // DR register of usart->port
     71     dma_channel_select(usart->dma.addr, usart->dma.tx_stream, DMA_SxCR_CHSEL_4);
     72     dma_enable_memory_increment_mode(usart->dma.addr, usart->dma.tx_stream);
     73     dma_set_transfer_mode(usart->dma.addr, usart->dma.tx_stream, DMA_SxCR_DIR_MEM_TO_PERIPHERAL);
     74 
     75     nvic_set_priority(usart->dma.rx_stream_irq, 0x06 << 4);
     76     nvic_enable_irq(usart->dma.rx_stream_irq);
     77     nvic_set_priority(usart->dma.tx_stream_irq, 0x06 << 4);
     78     nvic_enable_irq(usart->dma.tx_stream_irq);
     79     dma_enable_transfer_complete_interrupt(usart->dma.addr, usart->dma.rx_stream);
     80     dma_enable_transfer_complete_interrupt(usart->dma.addr, usart->dma.tx_stream);
     81 
     82     dma_enable_stream(usart->dma.addr, usart->dma.rx_stream);
     83 }
     84 
     85 void res_usart_dma_gsm_setup(void)
     86 {
     87     // Config peripheral
     88     rcc_periph_clock_enable(gsm.clock);
     89     usart_set_flow_control(gsm.port, USART_FLOWCONTROL_NONE);
     90     usart_set_baudrate(gsm.port, 921600);
     91     usart_set_databits(gsm.port, 8);
     92     usart_set_stopbits(gsm.port, 1);
     93     usart_set_parity(gsm.port, 0);
     94     usart_set_mode(gsm.port, USART_MODE_TX_RX);
     95     usart_enable_rx_dma(gsm.port);
     96     usart_enable_tx_dma(gsm.port);
     97 
     98     gpio_mode_setup(gsm.gpio_port, GPIO_MODE_AF, GPIO_PUPD_NONE, gsm.gpio_rx | gsm.gpio_tx);
     99     gpio_set_af(gsm.gpio_port, GPIO_AF7, gsm.gpio_rx | gsm.gpio_tx);
    100 
    101     // Enable interrupt
    102     nvic_set_priority(gsm.nvic_irq, 0x05 << 4);
    103     nvic_enable_irq(gsm.nvic_irq);
    104 
    105     gsm.dma.addr = DMA1;
    106     gsm.dma.clock = RCC_DMA1;
    107     gsm.dma.tx_stream = DMA_STREAM6;
    108     gsm.dma.rx_stream = DMA_STREAM5;
    109     gsm.dma.txBuf = gsmTxBuf;
    110     gsm.dma.rxBuf = gsmRxBuf;
    111     gsm.dma.tx_stream_irq = NVIC_DMA1_STREAM6_IRQ; 
    112     gsm.dma.rx_stream_irq = NVIC_DMA1_STREAM5_IRQ; 
    113 
    114     setup_dma_for_usart(&gsm);
    115 }
    116 
    117 void res_usart_dma_dbg_setup(void)
    118 {
    119     // Config peripheral
    120     rcc_periph_clock_enable(dbg.clock);
    121     usart_set_flow_control(dbg.port, USART_FLOWCONTROL_NONE);
    122     usart_set_baudrate(dbg.port, 921600);
    123     usart_set_databits(dbg.port, 8);
    124     usart_set_stopbits(dbg.port, 1);
    125     usart_set_parity(dbg.port, 0);
    126     usart_set_mode(dbg.port, USART_MODE_TX_RX);
    127     usart_enable_rx_dma(dbg.port);
    128     usart_enable_tx_dma(dbg.port);
    129 
    130     gpio_mode_setup(dbg.gpio_port, GPIO_MODE_AF, GPIO_PUPD_NONE, dbg.gpio_rx | dbg.gpio_tx);
    131     gpio_set_af(dbg.gpio_port, GPIO_AF7, dbg.gpio_rx | dbg.gpio_tx);
    132 
    133     // Enable interrupt
    134     nvic_set_priority(dbg.nvic_irq, 0x05 << 4);
    135     nvic_enable_irq(dbg.nvic_irq);
    136 
    137     dbg.dma.addr = DMA2;
    138     dbg.dma.clock = RCC_DMA2;
    139     dbg.dma.tx_stream = DMA_STREAM7;
    140     dbg.dma.rx_stream = DMA_STREAM2;
    141     dbg.dma.txBuf = dbgTxBuf;
    142     dbg.dma.rxBuf = dbgRxBuf;
    143     dbg.dma.tx_stream_irq = NVIC_DMA2_STREAM7_IRQ; 
    144     dbg.dma.rx_stream_irq = NVIC_DMA2_STREAM2_IRQ; 
    145 
    146     setup_dma_for_usart(&dbg);
    147 }
    148 
    149 static void res_usart_write_byte(const uint32_t port, const uint8_t data) { usart_send_blocking(port, (uint16_t)data); }
    150 
    151 void res_usart_write(const USART_t *usart, const uint8_t *data, const uint32_t length) {
    152     for (uint32_t i = 0; i < length; i++) {
    153         res_usart_write_byte(usart->port, data[i]);
    154     }
    155 }
    156 
    157 void res_usart_dma_write(const USART_t *usart, const uint16_t offset, const uint32_t length) {
    158     dma_set_memory_address(usart->dma.addr, usart->dma.tx_stream, (uint32_t)(usart->dma.txBuf + offset));
    159     dma_set_number_of_data(usart->dma.addr, usart->dma.tx_stream, length);
    160     dma_enable_stream(usart->dma.addr, usart->dma.tx_stream);
    161 }
    162 
    163 /*uint32_t res_usart_read(uint8_t *data, const uint32_t length) {*/
    164 /*    if (length > 0 && dataAvailable) {*/
    165 /*        *data = dataBuffer;*/
    166 /*        dataAvailable = false;*/
    167 /*        return 1;*/
    168 /*    }*/
    169 /*    return 0;*/
    170 /*}*/
    171 
    172 /*uint8_t res_usart_read_byte(void) {*/
    173 /*    dataAvailable = false;*/
    174 /*    return dataBuffer;*/
    175 /*}*/
    176 
    177 /*bool res_usart_data_available(void) { return dataAvailable; }*/
    178 
    179 uint16_t res_usart_dma_get_buffer_tail(USART_t *usart) {
    180     return DMA_RX_BUFFER_SIZE - dma_get_number_of_data(usart->dma.addr, usart->dma.rx_stream);
    181 }