uart.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. * Copyright (c) 2019-2021 Arm Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #include "uart.h"
  19. #include <stdint.h>
  20. #include <stdio.h>
  21. #define UART0_BASE 0x49303000
  22. #define UART0_BAUDRATE 115200
  23. #define SYSTEM_CORE_CLOCK 25000000
  24. /*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/
  25. #define __IO volatile
  26. #define __I volatile const
  27. #define __O volatile
  28. typedef struct
  29. {
  30. __IO uint32_t DATA; /* Offset: 0x000 (R/W) Data Register */
  31. __IO uint32_t STATE; /* Offset: 0x004 (R/W) Status Register */
  32. __IO uint32_t CTRL; /* Offset: 0x008 (R/W) Control Register */
  33. union
  34. {
  35. __I uint32_t INTSTATUS; /* Offset: 0x00C (R/ ) Interrupt Status Register */
  36. __O uint32_t INTCLEAR; /* Offset: 0x00C ( /W) Interrupt Clear Register */
  37. };
  38. __IO uint32_t BAUDDIV; /* Offset: 0x010 (R/W) Baudrate Divider Register */
  39. } CMSDK_UART_TypeDef;
  40. #define CMSDK_UART0_BASE UART0_BASE
  41. #define CMSDK_UART0 ((CMSDK_UART_TypeDef *)CMSDK_UART0_BASE)
  42. #define CMSDK_UART0_BAUDRATE UART0_BAUDRATE
  43. void uart_init(void)
  44. {
  45. // SystemCoreClock / 9600
  46. CMSDK_UART0->BAUDDIV = SYSTEM_CORE_CLOCK / CMSDK_UART0_BAUDRATE;
  47. CMSDK_UART0->CTRL = ((1ul << 0) | /* TX enable */
  48. (1ul << 1)); /* RX enable */
  49. }
  50. // Output a character
  51. unsigned char uart_putc(unsigned char my_ch)
  52. {
  53. while ((CMSDK_UART0->STATE & 1))
  54. ; // Wait if Transmit Holding register is full
  55. if (my_ch == '\n')
  56. {
  57. CMSDK_UART0->DATA = '\r';
  58. while ((CMSDK_UART0->STATE & 1))
  59. ; // Wait if Transmit Holding register is full
  60. }
  61. CMSDK_UART0->DATA = my_ch; // write to transmit holding register
  62. return (my_ch);
  63. }
  64. // Get a character
  65. unsigned char uart_getc(void)
  66. {
  67. unsigned char my_ch;
  68. // unsigned int cnt;
  69. while ((CMSDK_UART0->STATE & 2) == 0) // Wait if Receive Holding register is empty
  70. {
  71. #if 0
  72. cnt = MPS3_FPGAIO->CLK100HZ / 50;
  73. if (cnt & 0x8)
  74. MPS3_FPGAIO->LED = 0x01 << (cnt & 0x7);
  75. else
  76. MPS3_FPGAIO->LED = 0x80 >> (cnt & 0x7);
  77. #endif
  78. }
  79. my_ch = CMSDK_UART0->DATA;
  80. // Convert CR to LF
  81. if (my_ch == '\r')
  82. my_ch = '\n';
  83. return (my_ch);
  84. }