uart.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * (c) danielinux 2019
  3. *
  4. * GPLv.2
  5. *
  6. * See LICENSE for details
  7. */
  8. #include <stdint.h>
  9. #include <stdio.h>
  10. #include "uart.h"
  11. #include "system.h"
  12. #define UART2 (0x40004400)
  13. #define UART2_SR (*(volatile uint32_t *)(UART2))
  14. #define UART2_DR (*(volatile uint32_t *)(UART2 + 0x04))
  15. #define UART2_BRR (*(volatile uint32_t *)(UART2 + 0x08))
  16. #define UART2_CR1 (*(volatile uint32_t *)(UART2 + 0x0c))
  17. #define UART2_CR2 (*(volatile uint32_t *)(UART2 + 0x10))
  18. #define UART_CR1_UART_ENABLE (1 << 13)
  19. #define UART_CR1_SYMBOL_LEN (1 << 12)
  20. #define UART_CR1_PARITY_ENABLED (1 << 10)
  21. #define UART_CR1_PARITY_ODD (1 << 9)
  22. #define UART_CR1_TX_ENABLE (1 << 3)
  23. #define UART_CR1_RX_ENABLE (1 << 2)
  24. #define UART_CR2_STOPBITS (3 << 12)
  25. #define UART_SR_TX_EMPTY (1 << 7)
  26. #define UART_SR_RX_NOTEMPTY (1 << 5)
  27. #define APB1_CLOCK_ER (*(volatile uint32_t *)(0x40023840))
  28. #define UART2_APB1_CLOCK_ER_VAL (1 << 17)
  29. #define AHB1_CLOCK_ER (*(volatile uint32_t *)(0x40023830))
  30. #define GPIO_MODE_AF (2)
  31. #define UART2_PIN_AF 7
  32. #define UART2_RX_PIN 2
  33. #define UART2_TX_PIN 3
  34. static void uart2_pins_setup(void)
  35. {
  36. uint32_t reg;
  37. AHB1_CLOCK_ER |= GPIOA_AHB1_CLOCK_ER;
  38. /* Set mode = AF */
  39. reg = GPIOA_MODE & ~ (0x03 << (UART2_RX_PIN * 2));
  40. GPIOA_MODE = reg | (2 << (UART2_RX_PIN * 2));
  41. reg = GPIOA_MODE & ~ (0x03 << (UART2_TX_PIN * 2));
  42. GPIOA_MODE = reg | (2 << (UART2_TX_PIN * 2));
  43. /* Alternate function: use low pins */
  44. reg = GPIOA_AFL & ~(0xf << ((UART2_TX_PIN) * 4));
  45. GPIOA_AFL = reg | (UART2_PIN_AF << ((UART2_TX_PIN) * 4));
  46. reg = GPIOA_AFL & ~(0xf << ((UART2_RX_PIN) * 4));
  47. GPIOA_AFL = reg | (UART2_PIN_AF << ((UART2_RX_PIN) * 4));
  48. }
  49. int uart2_setup(uint32_t bitrate, uint8_t data, char parity, uint8_t stop)
  50. {
  51. uint32_t reg;
  52. int pin_rx, pin_tx, pin_af;
  53. /* Enable pins and configure for AF7 */
  54. uart2_pins_setup();
  55. /* Turn on the device */
  56. APB1_CLOCK_ER |= UART2_APB1_CLOCK_ER_VAL;
  57. /* Configure for TX */
  58. UART2_CR1 |= UART_CR1_TX_ENABLE;
  59. /* Configure clock */
  60. UART2_BRR = cpu_freq / bitrate;
  61. /* Configure data bits */
  62. if (data == 8)
  63. UART2_CR1 &= ~UART_CR1_SYMBOL_LEN;
  64. else
  65. UART2_CR1 |= UART_CR1_SYMBOL_LEN;
  66. /* Configure parity */
  67. switch (parity) {
  68. case 'O':
  69. UART2_CR1 |= UART_CR1_PARITY_ODD;
  70. /* fall through to enable parity */
  71. case 'E':
  72. UART2_CR1 |= UART_CR1_PARITY_ENABLED;
  73. break;
  74. default:
  75. UART2_CR1 &= ~(UART_CR1_PARITY_ENABLED | UART_CR1_PARITY_ODD);
  76. }
  77. /* Set stop bits */
  78. reg = UART2_CR2 & ~UART_CR2_STOPBITS;
  79. if (stop > 1)
  80. UART2_CR2 = reg & (2 << 12);
  81. else
  82. UART2_CR2 = reg;
  83. /* Turn on uart */
  84. UART2_CR1 |= UART_CR1_UART_ENABLE;
  85. return 0;
  86. }
  87. int _write(void *r, uint8_t *text, int len)
  88. {
  89. char *p = (char *)text;
  90. int i;
  91. volatile uint32_t reg;
  92. text[len - 1] = 0;
  93. while(*p) {
  94. do {
  95. reg = UART2_SR;
  96. } while ((reg & UART_SR_TX_EMPTY) == 0);
  97. UART2_DR = *p;
  98. p++;
  99. }
  100. return len;
  101. }
  102. /* commodity to print binary buffers */
  103. void printbin(const uint8_t *buf, int len)
  104. {
  105. int i;
  106. for (i = 0; i < len; i++) {
  107. if ((i % 16) == 0)
  108. printf("\r\n%08x: ", i);
  109. printf("%02x ", buf[i]);
  110. }
  111. printf("\r\n");
  112. }