void uart_open(uint8_t port) { Usart* usart = get_usart(port); if (0 == port) { // IO is initialized in board init // Enable interrupt with priority higher than USB NVIC_SetPriority((IRQn_Type) USART_ID_0, USART_INT_LEVEL_0); NVIC_EnableIRQ((IRQn_Type) USART_ID_0); NVIC_SetPriority((IRQn_Type) USART_ID_1, USART_INT_LEVEL_1); NVIC_EnableIRQ((IRQn_Type) USART_ID_1); // Initialize it in RS232 mode. pmc_enable_periph_clk(USART_ID_0); USART_ENABLE_0(); } else if (1 == port) { // IO is initialized in board init // Enable interrupt with priority higher than USB NVIC_SetPriority((IRQn_Type) USART_ID_1, USART_INT_LEVEL_1); NVIC_EnableIRQ((IRQn_Type) USART_ID_1); // Initialize it in RS232 mode. pmc_enable_periph_clk(USART_ID_1); USART_ENABLE_1(); } else { return; } if (usart_init_rs232(usart, &usart_options, sysclk_get_peripheral_hz())) { return; } // Enable both RX and TX usart_enable_tx(usart); usart_enable_rx(usart); // Enable interrupts usart_enable_interrupt(usart, US_IER_RXRDY | US_IER_TXRDY); }
void uart_rx_notify(uint8_t port) { Usart* usart = get_usart(port); // If UART is open if (usart_get_interrupt_mask(usart) & US_IMR_RXRDY) { // Enable UART TX interrupt to send a new value usart_enable_tx(usart); usart_enable_interrupt(usart, US_IER_TXRDY); } }
void USART_cmd(void) { char c; int16_t t16; uint32_t t32; c = get_usart(); if(c >= 255) return; switch (c) { case 'v': printf("D-oscope, V=0.1\r\n>"); break; case 'V': printf("Copyright (c) Mitescu George Dan 2015\r\n>"); break; } }
static void usart_handler(uint8_t port) { Usart* usart = get_usart(port); uint32_t sr = usart_get_status(usart); if (sr & US_CSR_RXRDY) { // Data received ui_com_tx_start(); uint32_t value; bool b_error = usart_read(usart, &value) || (sr & (US_CSR_FRAME | US_CSR_TIMEOUT | US_CSR_PARE)); if (b_error) { usart_reset_rx(usart); usart_enable_rx(usart); udi_cdc_multi_signal_framing_error(port); ui_com_error(); } // Transfer UART RX fifo to CDC TX if (!udi_cdc_multi_is_tx_ready(port)) { // Fifo full udi_cdc_multi_signal_overrun(port); ui_com_overflow(); } else { udi_cdc_multi_putc(port, value); } ui_com_tx_stop(); return; } if (sr & US_CSR_TXRDY) { // Data send if (udi_cdc_multi_is_rx_ready(port)) { // Transmit next data ui_com_rx_start(); int c = udi_cdc_multi_getc(port); usart_write(usart, c); } else { // Fifo empty then Stop UART transmission usart_disable_tx(usart); usart_disable_interrupt(usart, US_IDR_TXRDY); ui_com_rx_stop(); } } }
void init_usart(void) { usart_t *usart1 = get_usart(1); *RCC_APB2ENR |= RCC_APB2ENR_USART1EN; /* Enable USART1 Clock */ *RCC_AHB1ENR |= RCC_AHB1ENR_GPIOBEN; /* Enable GPIOB Clock */ /* Set PB6 and PB7 to alternative function USART * See stm32f4_ref.pdf pg 141 and stm32f407.pdf pg 51 */ /* PB6 */ gpio_moder(GPIOB, 6, GPIO_MODER_ALT); gpio_afr(GPIOB, 6, GPIO_AF_USART13); gpio_otyper(GPIOB, 6, GPIO_OTYPER_PP); gpio_pupdr(GPIOB, 6, GPIO_PUPDR_NONE); gpio_ospeedr(GPIOB, 6, GPIO_OSPEEDR_50M); /* PB7 */ gpio_moder(GPIOB, 7, GPIO_MODER_ALT); gpio_afr(GPIOB, 7, GPIO_AF_USART13); gpio_otyper(GPIOB, 7, GPIO_OTYPER_PP); gpio_pupdr(GPIOB, 7, GPIO_PUPDR_NONE); gpio_ospeedr(GPIOB, 7, GPIO_OSPEEDR_50M); /* Enable USART1 */ usart1->CR1 |= USART_CR1_UE; /* 8 data bits */ usart1->CR1 &= ~(1 << 12); /* 1 stop bit */ usart1->CR2 &= ~(3 << 12); /** DMA set up **/ /* DMA2, Stream 2, Channel 4 is USART1_RX * DMA2, Stream 7, Channel 4 is USART1_TX */ usart1->CR3 |= USART_CR3_DMAR | USART_CR3_DMAT; /* Enable DMA2 clock */ *RCC_AHB1ENR |= RCC_AHB1ENR_DMA2EN; *RCC_AHB1ENR |= RCC_AHB1ENR_DMA1EN; /* Clear configuration registers enable bits and wait for them to be ready */ *DMA2_CR_S(2) &= ~(DMA_SxCR_EN); *DMA2_CR_S(7) &= ~(DMA_SxCR_EN); while ( (*DMA2_CR_S(2) & DMA_SxCR_EN) || (*DMA2_CR_S(7) & DMA_SxCR_EN) ); /* Select channel 4 */ *DMA2_CR_S(2) |= DMA_SxCR_CHSEL(4); *DMA2_CR_S(7) |= DMA_SxCR_CHSEL(4); /* Peripheral address - Both use USART data register */ *DMA2_PAR_S(2) = (uint32_t) &usart1->DR; /* RX */ *DMA2_PAR_S(7) = (uint32_t) &usart1->DR; /* TX */ /* * Allocate buffer memory. * This must be allocated because static data goes into * CCMRAM on STM32F4 implementation, and the bus matrix * does not connect CCMRAM to the DMA engine. Thus, it * is allocated from user heap to ensure it is accessible * by DMA */ usart_rx_buf = (char *) malloc(USART_DMA_MSIZE); usart_tx_buf = (char *) malloc(USART_DMA_MSIZE); if ((usart_rx_buf == NULL) || (usart_tx_buf == NULL)) { panic(); } else { /* Clear buffers */ memset(usart_rx_buf, 0, USART_DMA_MSIZE); memset(usart_tx_buf, 0, USART_DMA_MSIZE); *DMA2_M0AR_S(2) = (uint32_t) usart_rx_buf; *DMA2_M0AR_S(7) = (uint32_t) usart_tx_buf; } /* Number of data items to be transferred */ *DMA2_NDTR_S(2) = (uint16_t) USART_DMA_MSIZE; /* FIFO setup */ *DMA2_FCR_S(7) |= DMA_SxFCR_FTH_4 | DMA_SxFCR_DMDIS; /* Data direct, memory increment, high priority, memory burst */ *DMA2_CR_S(2) |= DMA_SxCR_DIR_PM | DMA_SxCR_MINC | DMA_SxCR_PL_HIGH | DMA_SxCR_CIRC; *DMA2_CR_S(7) |= DMA_SxCR_DIR_MP | DMA_SxCR_MINC | DMA_SxCR_PL_HIGH | DMA_SxCR_MBURST_4; /* Enable DMAs */ *DMA2_CR_S(2) |= DMA_SxCR_EN; /** DMA End **/ /* Set baud rate */ usart1->BRR = usart_baud(115200); /* Enable reciever and transmitter */ usart1->CR1 |= USART_CR1_RE; usart1->CR1 |= USART_CR1_TE; usart_ready = 1; }
void uart_config(uint8_t port, usb_cdc_line_coding_t * cfg) { Usart* usart = get_usart(port); uint32_t stopbits, parity, databits; uint32_t imr; switch (cfg->bCharFormat) { case CDC_STOP_BITS_2: stopbits = US_MR_NBSTOP_2_BIT; break; case CDC_STOP_BITS_1_5: stopbits = US_MR_NBSTOP_1_5_BIT; break; case CDC_STOP_BITS_1: default: // Default stop bit = 1 stop bit stopbits = US_MR_NBSTOP_1_BIT; break; } switch (cfg->bParityType) { case CDC_PAR_EVEN: parity = US_MR_PAR_EVEN; break; case CDC_PAR_ODD: parity = US_MR_PAR_ODD; break; case CDC_PAR_MARK: parity = US_MR_PAR_MARK; break; case CDC_PAR_SPACE: parity = US_MR_PAR_SPACE; break; default: case CDC_PAR_NONE: parity = US_MR_PAR_NO; break; } switch(cfg->bDataBits) { case 5: case 6: case 7: databits = cfg->bDataBits - 5; break; default: case 8: databits = US_MR_CHRL_8_BIT; break; } // Options for USART. usart_options.baudrate = LE32_TO_CPU(cfg->dwDTERate); usart_options.char_length = databits; usart_options.parity_type = parity; usart_options.stop_bits = stopbits; usart_options.channel_mode = US_MR_CHMODE_NORMAL; imr = usart_get_interrupt_mask(usart); usart_disable_interrupt(usart, 0xFFFFFFFF); usart_init_rs232(usart, &usart_options, sysclk_get_peripheral_hz()); // Restore both RX and TX usart_enable_tx(usart); usart_enable_rx(usart); usart_enable_interrupt(usart, imr); }