123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- /*
- * (c) danielinux 2019
- *
- * GPLv.2
- *
- * See LICENSE for details
- */
- #include <stdint.h>
- #include <stdio.h>
- #include "uart.h"
- #include "system.h"
- #define UART2 (0x40004400)
- #define UART2_SR (*(volatile uint32_t *)(UART2))
- #define UART2_DR (*(volatile uint32_t *)(UART2 + 0x04))
- #define UART2_BRR (*(volatile uint32_t *)(UART2 + 0x08))
- #define UART2_CR1 (*(volatile uint32_t *)(UART2 + 0x0c))
- #define UART2_CR2 (*(volatile uint32_t *)(UART2 + 0x10))
- #define UART_CR1_UART_ENABLE (1 << 13)
- #define UART_CR1_SYMBOL_LEN (1 << 12)
- #define UART_CR1_PARITY_ENABLED (1 << 10)
- #define UART_CR1_PARITY_ODD (1 << 9)
- #define UART_CR1_TX_ENABLE (1 << 3)
- #define UART_CR1_RX_ENABLE (1 << 2)
- #define UART_CR2_STOPBITS (3 << 12)
- #define UART_SR_TX_EMPTY (1 << 7)
- #define UART_SR_RX_NOTEMPTY (1 << 5)
- #define APB1_CLOCK_ER (*(volatile uint32_t *)(0x40023840))
- #define UART2_APB1_CLOCK_ER_VAL (1 << 17)
- #define AHB1_CLOCK_ER (*(volatile uint32_t *)(0x40023830))
- #define GPIO_MODE_AF (2)
- #define UART2_PIN_AF 7
- #define UART2_RX_PIN 2
- #define UART2_TX_PIN 3
- static void uart2_pins_setup(void)
- {
- uint32_t reg;
- AHB1_CLOCK_ER |= GPIOA_AHB1_CLOCK_ER;
- /* Set mode = AF */
- reg = GPIOA_MODE & ~ (0x03 << (UART2_RX_PIN * 2));
- GPIOA_MODE = reg | (2 << (UART2_RX_PIN * 2));
- reg = GPIOA_MODE & ~ (0x03 << (UART2_TX_PIN * 2));
- GPIOA_MODE = reg | (2 << (UART2_TX_PIN * 2));
- /* Alternate function: use low pins */
- reg = GPIOA_AFL & ~(0xf << ((UART2_TX_PIN) * 4));
- GPIOA_AFL = reg | (UART2_PIN_AF << ((UART2_TX_PIN) * 4));
- reg = GPIOA_AFL & ~(0xf << ((UART2_RX_PIN) * 4));
- GPIOA_AFL = reg | (UART2_PIN_AF << ((UART2_RX_PIN) * 4));
- }
- int uart2_setup(uint32_t bitrate, uint8_t data, char parity, uint8_t stop)
- {
- uint32_t reg;
- int pin_rx, pin_tx, pin_af;
- /* Enable pins and configure for AF7 */
- uart2_pins_setup();
- /* Turn on the device */
- APB1_CLOCK_ER |= UART2_APB1_CLOCK_ER_VAL;
- /* Configure for TX */
- UART2_CR1 |= UART_CR1_TX_ENABLE;
- /* Configure clock */
- UART2_BRR = cpu_freq / bitrate;
- /* Configure data bits */
- if (data == 8)
- UART2_CR1 &= ~UART_CR1_SYMBOL_LEN;
- else
- UART2_CR1 |= UART_CR1_SYMBOL_LEN;
- /* Configure parity */
- switch (parity) {
- case 'O':
- UART2_CR1 |= UART_CR1_PARITY_ODD;
- /* fall through to enable parity */
- case 'E':
- UART2_CR1 |= UART_CR1_PARITY_ENABLED;
- break;
- default:
- UART2_CR1 &= ~(UART_CR1_PARITY_ENABLED | UART_CR1_PARITY_ODD);
- }
- /* Set stop bits */
- reg = UART2_CR2 & ~UART_CR2_STOPBITS;
- if (stop > 1)
- UART2_CR2 = reg & (2 << 12);
- else
- UART2_CR2 = reg;
- /* Turn on uart */
- UART2_CR1 |= UART_CR1_UART_ENABLE;
- return 0;
- }
- int _write(void *r, uint8_t *text, int len)
- {
- char *p = (char *)text;
- int i;
- volatile uint32_t reg;
- text[len - 1] = 0;
- while(*p) {
- do {
- reg = UART2_SR;
- } while ((reg & UART_SR_TX_EMPTY) == 0);
- UART2_DR = *p;
- p++;
- }
- return len;
- }
- /* commodity to print binary buffers */
- void printbin(const uint8_t *buf, int len)
- {
- int i;
- for (i = 0; i < len; i++) {
- if ((i % 16) == 0)
- printf("\r\n%08x: ", i);
- printf("%02x ", buf[i]);
- }
- printf("\r\n");
- }
|