uart.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*****************************************************************
  2. * uart.c
  3. * by Zhiyi Huang, [email protected]
  4. * University of Otago
  5. *
  6. ********************************************************************/
  7. #include "types.h"
  8. #include "defs.h"
  9. #include "memlayout.h"
  10. #include "traps.h"
  11. #include "arm.h"
  12. #define GPFSEL0 0xFE200000
  13. #define GPFSEL1 0xFE200004
  14. #define GPFSEL2 0xFE200008
  15. #define GPFSEL3 0xFE20000C
  16. #define GPFSEL4 0xFE200010
  17. #define GPFSEL5 0xFE200014
  18. #define GPSET0 0xFE20001C
  19. #define GPSET1 0xFE200020
  20. #define GPCLR0 0xFE200028
  21. #define GPCLR1 0xFE20002C
  22. #define GPPUD 0xFE200094
  23. #define GPPUDCLK0 0xFE200098
  24. #define GPPUDCLK1 0xFE20009C
  25. #define AUX_IRQ 0xFE215000
  26. #define AUX_ENABLES 0xFE215004
  27. #define AUX_MU_IO_REG 0xFE215040
  28. #define AUX_MU_IER_REG 0xFE215044
  29. #define AUX_MU_IIR_REG 0xFE215048
  30. #define AUX_MU_LCR_REG 0xFE21504C
  31. #define AUX_MU_MCR_REG 0xFE215050
  32. #define AUX_MU_LSR_REG 0xFE215054
  33. #define AUX_MU_MSR_REG 0xFE215058
  34. #define AUX_MU_SCRATCH 0xFE21505C
  35. #define AUX_MU_CNTL_REG 0xFE215060
  36. #define AUX_MU_STAT_REG 0xFE215064
  37. #define AUX_MU_BAUD_REG 0xFE215068
  38. void
  39. setgpioval(uint func, uint val)
  40. {
  41. uint sel, ssel, rsel;
  42. if(func > 53) return;
  43. sel = func >> 5;
  44. ssel = GPSET0 + (sel << 2);
  45. rsel = GPCLR0 + (sel << 2);
  46. sel = func & 0x1f;
  47. if(val == 0) outw(rsel, 1<<sel);
  48. else outw(ssel, 1<<sel);
  49. }
  50. void
  51. setgpiofunc(uint func, uint alt)
  52. {
  53. uint sel, data, shift;
  54. if(func > 53) return;
  55. sel = 0;
  56. while (func > 10) {
  57. func = func - 10;
  58. sel++;
  59. }
  60. sel = (sel << 2) + GPFSEL0;
  61. data = inw(sel);
  62. shift = func + (func << 1);
  63. data &= ~(7 << shift);
  64. data |= alt << shift;
  65. outw(sel, data);
  66. }
  67. void
  68. uartputc(uint c)
  69. {
  70. if(c=='\n') {
  71. while(1) if(inw(AUX_MU_LSR_REG) & 0x20) break;
  72. outw(AUX_MU_IO_REG, 0x0d); // add CR before LF
  73. }
  74. while(1) if(inw(AUX_MU_LSR_REG) & 0x20) break;
  75. outw(AUX_MU_IO_REG, c);
  76. }
  77. static int
  78. uartgetc(void)
  79. {
  80. if(inw(AUX_MU_LSR_REG)&0x1) return inw(AUX_MU_IO_REG);
  81. else return -1;
  82. }
  83. void
  84. enableirqminiuart(void)
  85. {
  86. intctrlregs *ip;
  87. ip = (intctrlregs *)INT_REGS_BASE;
  88. ip->gpuenable[0] |= (1 << 29); // enable the miniuart through Aux
  89. }
  90. void
  91. miniuartintr(void)
  92. {
  93. consoleintr(uartgetc);
  94. }
  95. void
  96. uartinit(void)
  97. {
  98. outw(AUX_ENABLES, 1);
  99. outw(AUX_MU_CNTL_REG, 0);
  100. outw(AUX_MU_LCR_REG, 0x3);
  101. outw(AUX_MU_MCR_REG, 0);
  102. outw(AUX_MU_IER_REG, 0x1);
  103. outw(AUX_MU_IIR_REG, 0xC7);
  104. outw(AUX_MU_BAUD_REG, 270); // (250,000,000/(115200*8))-1 = 270
  105. setgpiofunc(14, 2); // gpio 14, alt 5
  106. setgpiofunc(15, 2); // gpio 15, alt 5
  107. outw(GPPUD, 0);
  108. delay(10);
  109. outw(GPPUDCLK0, (1 << 14) | (1 << 15) );
  110. delay(10);
  111. outw(GPPUDCLK0, 0);
  112. outw(AUX_MU_CNTL_REG, 3);
  113. enableirqminiuart();
  114. }