void mew_bluetooth_init(void) { gpio_mode_setup(MEW_BLUETOOTH_POWER_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, MEW_BLUETOOTH_POWER_PIN); gpio_set_output_options(MEW_BLUETOOTH_POWER_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, MEW_BLUETOOTH_POWER_PIN); gpio_clear(MEW_BLUETOOTH_POWER_PORT, MEW_BLUETOOTH_POWER_PIN); gpio_mode_setup(MEW_BLUETOOTH_RESET_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, MEW_BLUETOOTH_RESET_PIN); gpio_set_output_options(MEW_BLUETOOTH_RESET_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, MEW_BLUETOOTH_RESET_PIN); gpio_set(MEW_BLUETOOTH_RESET_PORT, MEW_BLUETOOTH_RESET_PIN); gpio_mode_setup(MEW_BLUETOOTH_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, MEW_BLUETOOTH_PIN); gpio_set_af(MEW_BLUETOOTH_PORT, MEW_BLUETOOTH_PORT_AF, MEW_BLUETOOTH_PIN); usart_disable(MEW_BLUETOOTH_USART); usart_set_baudrate(MEW_BLUETOOTH_USART, MEW_BLUETOOTH_SPEED); usart_set_databits(MEW_BLUETOOTH_USART, 8); usart_set_stopbits(MEW_BLUETOOTH_USART, USART_STOPBITS_1); usart_set_mode(MEW_BLUETOOTH_USART, USART_MODE_TX_RX); usart_set_parity(MEW_BLUETOOTH_USART, USART_PARITY_NONE); usart_set_flow_control(MEW_BLUETOOTH_USART, USART_FLOWCONTROL_NONE); usart_enable_rx_interrupt(MEW_BLUETOOTH_USART); usart_disable_tx_interrupt(MEW_BLUETOOTH_USART); usart_enable_tx_dma(MEW_BLUETOOTH_USART); usart_enable(MEW_BLUETOOTH_USART); nvic_enable_irq(MEW_BLUETOOTH_IRQ); nvic_enable_irq(MEW_BLUETOOTH_DMA_NVIC_TX); memset(_mew_bt_buffer, 0, MEW_BT_RECEIVE_BUFFER_SIZE); }
void dma_transmit(const void* buffer, const int datasize) { dma_set_memory_address(DMA1, DMA_CHANNEL4, (uint32_t) buffer); dma_set_number_of_data(DMA1, DMA_CHANNEL4, datasize); dma_enable_channel(DMA1, DMA_CHANNEL4); usart_enable_tx_dma(USART2); }
/** Setup the USART for transmission with DMA. This function sets up the DMA * controller and additional USART parameters for DMA transmission. The USART * must first be configured using \ref usart_setup_common. */ void usart_tx_dma_setup(void) { /* Set up the USART1 TX DMA and interrupts. */ /* Enable clock to DMA peripheral. */ RCC_AHB1ENR |= RCC_AHB1ENR_DMA2EN; /* Enable TX DMA on the USART. */ usart_enable_tx_dma(USART1); /* USART1 TX - DMA2, stream 7, channel 4 */ /* Make sure stream is disabled to start. */ DMA2_S7CR &= ~DMA_SxCR_EN; DMA2_S7CR = 0; /* Configure the DMA controller. */ /* Error interrupts. */ DMA2_S7CR = DMA_SxCR_DMEIE | DMA_SxCR_TEIE | /* Transfer complete interrupt. */ DMA_SxCR_TCIE | DMA_SxCR_DIR_MEM_TO_PERIPHERAL | /* Increment the memory address after each transfer. */ DMA_SxCR_MINC | /* 8 bit transfers to USART peripheral. */ DMA_SxCR_PSIZE_8BIT | /* and from memory. */ DMA_SxCR_MSIZE_8BIT | /* Low priority. */ DMA_SxCR_PL_LOW | /* The channel selects which request line will trigger a * transfer. In this case, channel 4 = UART1_TX * (see CD00225773.pdf Table 23). */ DMA_SxCR_CHSEL(4); /* For now, don't transfer any number of datas (will be set in the initiating * function). */ DMA2_S7NDTR = 0; DMA2_S7PAR = &USART1_DR; /* DMA into the USART1 data register. */ DMA2_S7M0AR = buff; /* from the buff. */ /* TODO: Investigate more about the best FIFO settings. */ DMA2_S7FCR = DMA_SxFCR_DMDIS | /* Enable DMA stream FIFO. */ DMA_SxFCR_FTH_2_4_FULL | /* Trigger level 1/2 full. */ DMA_SxFCR_FEIE; /* Enable FIFO error interrupt. */ wr = rd = 0; /* Buffer is empty to begin with. */ /* Enable DMA2 Stream 7 (TX) interrupts with the NVIC. */ nvic_enable_irq(NVIC_DMA2_STREAM7_IRQ); }
void usart_tx(char *buf, unsigned short len) { usart_enable_tx_dma(USART1); dma_stream_reset(DMA2, DMA_STREAM7); dma_set_priority(DMA2, DMA_STREAM7, DMA_SxCR_PL_LOW); dma_set_memory_size(DMA2, DMA_STREAM7, DMA_SxCR_MSIZE_8BIT); dma_set_peripheral_size(DMA2, DMA_STREAM7, DMA_SxCR_PSIZE_8BIT); dma_enable_memory_increment_mode(DMA2, DMA_STREAM7); dma_set_transfer_mode(DMA2, DMA_STREAM7, DMA_SxCR_DIR_MEM_TO_PERIPHERAL); dma_set_peripheral_address(DMA2, DMA_STREAM7, (uint32_t) &USART1_DR); dma_set_memory_address(DMA2, DMA_STREAM7, (uint32_t) buf); dma_set_number_of_data(DMA2, DMA_STREAM7, len); dma_enable_transfer_complete_interrupt(DMA2, DMA_STREAM7); dma_channel_select(DMA2, DMA_STREAM7, DMA_SxCR_CHSEL_4); dma_enable_stream(DMA2, DMA_STREAM7); }
u8 UART_Send(u8 *data, u16 len) { if (busy) return 1; busy = 1; dma_channel_reset(_USART_DMA, _USART_DMA_CHANNEL); dma_set_peripheral_address(_USART_DMA, _USART_DMA_CHANNEL,(u32) &_USART_DR); /* send data to the USART data register */ dma_set_memory_address(_USART_DMA, _USART_DMA_CHANNEL, (u32) data); dma_set_number_of_data(_USART_DMA, _USART_DMA_CHANNEL, len); dma_set_read_from_memory(_USART_DMA, _USART_DMA_CHANNEL); /* direction is from memory to usart */ dma_enable_memory_increment_mode(_USART_DMA, _USART_DMA_CHANNEL); /* memory pointer increments, peripheral no */ dma_set_peripheral_size(_USART_DMA, _USART_DMA_CHANNEL, DMA_CCR_PSIZE_8BIT); /* USART_DR is 8bit wide in this mode */ dma_set_memory_size(_USART_DMA, _USART_DMA_CHANNEL, DMA_CCR_MSIZE_8BIT); /* destination memory is also 8 bit wide */ dma_set_priority(_USART_DMA, _USART_DMA_CHANNEL, DMA_CCR_PL_LOW); dma_enable_transfer_complete_interrupt(_USART_DMA, _USART_DMA_CHANNEL); dma_enable_channel(_USART_DMA, _USART_DMA_CHANNEL); /* dma ready to go */ usart_enable_tx_dma(_USART); return 0; }
u8 UART_Send(u8 *data, u16 len) { if (busy) return 1; busy = 1; DMA_stream_reset(USART_DMA); dma_set_peripheral_address(USART_DMA.dma, USART_DMA.stream, (u32) &USART_DR(UART_CFG.uart)); /* send data to the USART data register */ dma_set_memory_address(USART_DMA.dma, USART_DMA.stream, (u32) data); dma_set_number_of_data(USART_DMA.dma, USART_DMA.stream, len); dma_set_read_from_memory(USART_DMA.dma, USART_DMA.stream); /* direction is from memory to usart */ dma_enable_memory_increment_mode(USART_DMA.dma, USART_DMA.stream); /* memory pointer increments, peripheral no */ dma_set_peripheral_size(USART_DMA.dma, USART_DMA.stream, DMA_SxCR_PSIZE_8BIT); /* USART_DR is 8bit wide in this mode */ dma_set_memory_size(USART_DMA.dma, USART_DMA.stream, DMA_SxCR_MSIZE_8BIT); /* destination memory is also 8 bit wide */ dma_set_priority(USART_DMA.dma, USART_DMA.stream, DMA_CCR_PL_LOW); dma_enable_transfer_complete_interrupt(USART_DMA.dma, USART_DMA.stream); DMA_channel_select(USART_DMA); DMA_enable_stream(USART_DMA); /* dma ready to go */ usart_enable_tx_dma(UART_CFG.uart); return 0; }
void hal_uart_dma_send_block(const uint8_t *data, uint16_t size){ // printf("hal_uart_dma_send_block size %u\n", size); /* * USART3_TX Using DMA_CHANNEL2 */ /* Reset DMA channel*/ dma_channel_reset(DMA1, DMA_CHANNEL2); dma_set_peripheral_address(DMA1, DMA_CHANNEL2, (uint32_t)&USART3_DR); dma_set_memory_address(DMA1, DMA_CHANNEL2, (uint32_t)data); dma_set_number_of_data(DMA1, DMA_CHANNEL2, size); dma_set_read_from_memory(DMA1, DMA_CHANNEL2); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL2); dma_set_peripheral_size(DMA1, DMA_CHANNEL2, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(DMA1, DMA_CHANNEL2, DMA_CCR_MSIZE_8BIT); dma_set_priority(DMA1, DMA_CHANNEL2, DMA_CCR_PL_VERY_HIGH); dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL2); dma_enable_channel(DMA1, DMA_CHANNEL2); usart_enable_tx_dma(USART3); }
/** Setup the USART for transmission with DMA. * This function sets up the DMA controller and additional USART parameters for * DMA transmit. The USART must already be configured for normal operation. * * \param s The USART DMA state structure. * \oaram usart The USART base address. * \param dma The DMA controller base address. * \param stream The DMA stream number to use. * \param channel The DMA channel to use. The stream and channel must * correspond to a USART RX channel. */ void usart_tx_dma_setup(usart_tx_dma_state* s, u32 usart, u32 dma, u8 stream, u8 channel) { s->dma = dma; s->usart = usart; s->stream = stream; s->channel = channel; s->byte_counter = 0; s->last_byte_ticks = chTimeNow(); /* Enable clock to DMA peripheral. */ if (dma == DMA1) RCC_AHB1ENR |= RCC_AHB1ENR_DMA1EN; else if (dma == DMA2) RCC_AHB1ENR |= RCC_AHB1ENR_DMA2EN; /* Enable TX DMA on the USART. */ usart_enable_tx_dma(usart); /* Make sure stream is disabled to start. */ DMA_SCR(dma, stream) &= ~DMA_SxCR_EN; /* Configure the DMA controller. */ DMA_SCR(dma, stream) = 0; DMA_SCR(dma, stream) = /* Error interrupts. */ DMA_SxCR_DMEIE | DMA_SxCR_TEIE | /* Transfer complete interrupt. */ DMA_SxCR_TCIE | DMA_SxCR_DIR_MEM_TO_PERIPHERAL | /* Increment the memory address after each transfer. */ DMA_SxCR_MINC | /* 4 bytes written to the FIFO from memory at a time */ DMA_SxCR_MBURST_INCR4 | /* 8 bit transfers from USART peripheral. */ DMA_SxCR_PSIZE_8BIT | /* and to memory. */ DMA_SxCR_MSIZE_8BIT | /* TODO: what priority level is necessary? */ /* Very high priority. */ DMA_SxCR_PL_VERY_HIGH | /* The channel selects which request line will trigger a transfer. * (see CD00225773.pdf Table 23). */ DMA_SxCR_CHSEL(channel); /* For now, don't transfer any number of datas * (will be set in the initiating function). */ DMA_SNDTR(dma, stream) = 0; /* DMA into the USART data register... */ DMA_SPAR(dma, stream) = &USART_DR(usart); /* ...from the TX buffer. */ DMA_SM0AR(dma, stream) = s->buff; /* TODO: Investigate more about the best FIFO settings. */ DMA_SFCR(dma, stream) = DMA_SxFCR_DMDIS | /* Enable DMA stream FIFO. */ DMA_SxFCR_FTH_2_4_FULL | /* Trigger level 2/4 full. */ DMA_SxFCR_FEIE; /* Enable FIFO error interrupt. */ s->wr = s->rd = 0; /* Buffer is empty to begin with. */ /* Enable DMA interrupts for this stream with the NVIC. */ if (dma == DMA1) nvicEnableVector(dma_irq_lookup[0][stream], CORTEX_PRIORITY_MASK(USART_DMA_ISR_PRIORITY)); else if (dma == DMA2) nvicEnableVector(dma_irq_lookup[1][stream], CORTEX_PRIORITY_MASK(USART_DMA_ISR_PRIORITY)); }