Simple single-color 8x8x8 LED Cube with AVRs
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

serial.c 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * serial.c
  3. *
  4. * Copyright 2011 Thomas Buck <xythobuz@me.com>
  5. *
  6. * This file is part of xyRobot.
  7. *
  8. * xyRobot is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * xyRobot is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with xyRobot. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #include <avr/io.h>
  22. #include <avr/interrupt.h>
  23. #include <stdint.h>
  24. #include <serial.h>
  25. uint8_t volatile rxBuffer[RX_BUFFER_SIZE];
  26. uint8_t volatile txBuffer[TX_BUFFER_SIZE];
  27. uint16_t volatile rxRead = 0;
  28. uint16_t volatile rxWrite = 0;
  29. uint16_t volatile txRead = 0;
  30. uint16_t volatile txWrite = 0;
  31. uint8_t volatile shouldStartTransmission = 1;
  32. ISR(USART_RXC_vect) { // Receive complete
  33. rxBuffer[rxWrite] = UDR;
  34. if (rxWrite < (RX_BUFFER_SIZE - 1)) {
  35. rxWrite++;
  36. } else {
  37. rxWrite = 0;
  38. }
  39. }
  40. ISR(USART_UDRE_vect) { // Data register empty
  41. if (txRead != txWrite) {
  42. UDR = txBuffer[txRead];
  43. if (txRead < (TX_BUFFER_SIZE -1)) {
  44. txRead++;
  45. } else {
  46. txRead = 0;
  47. }
  48. } else {
  49. shouldStartTransmission = 1;
  50. UCSRB &= ~(1 << UDRIE); // Disable Interrupt
  51. }
  52. }
  53. uint8_t serialInit(uint16_t baud, uint8_t databits, uint8_t parity, uint8_t stopbits) {
  54. if (parity > ODD) {
  55. return 1;
  56. }
  57. if ((databits < 5) || (databits > 8)) {
  58. return 1;
  59. }
  60. if ((stopbits < 1) || (stopbits > 2)) {
  61. return 1;
  62. }
  63. if (parity != NONE) {
  64. UCSRC |= (1 << UPM1);
  65. if (parity == ODD) {
  66. UCSRC |= (1 << UPM0);
  67. }
  68. }
  69. if (stopbits == 2) {
  70. UCSRC |= (1 << USBS);
  71. }
  72. if (databits != 5) {
  73. if ((databits == 6) || (databits >= 8)) {
  74. UCSRC |= (1 << UCSZ0);
  75. }
  76. if (databits >= 7) {
  77. UCSRC |= (1 << UCSZ1);
  78. }
  79. if (databits == 9) {
  80. UCSRB |= (1 << UCSZ2);
  81. }
  82. }
  83. UBRRH = (baud >> 8);
  84. UBRRL = baud;
  85. UCSRB |= (1 << RXCIE) | (1 << RXEN) | (1 << TXEN); // Enable Interrupts and Receiver/Transmitter
  86. return 0;
  87. }
  88. uint8_t serialHasChar() {
  89. if (rxRead != rxWrite) {
  90. return 1;
  91. } else {
  92. return 0;
  93. }
  94. }
  95. uint8_t serialGet() {
  96. uint8_t c;
  97. if (rxRead != rxWrite) {
  98. c = rxBuffer[rxRead];
  99. rxBuffer[rxRead] = 0;
  100. if (rxRead < (RX_BUFFER_SIZE - 1)) {
  101. rxRead++;
  102. } else {
  103. rxRead = 0;
  104. }
  105. return c;
  106. } else {
  107. return 0;
  108. }
  109. }
  110. uint8_t serialBufferSpaceRemaining() {
  111. return (((txWrite + 1) == txRead) || ((txRead == 0) && ((txWrite + 1) == TX_BUFFER_SIZE)));
  112. }
  113. void serialWrite(uint8_t data) {
  114. while (((txWrite + 1) == txRead) || ((txRead == 0) && ((txWrite + 1) == TX_BUFFER_SIZE))); // Buffer is full, wait!
  115. txBuffer[txWrite] = data;
  116. if (txWrite < (TX_BUFFER_SIZE - 1)) {
  117. txWrite++;
  118. } else {
  119. txWrite = 0;
  120. }
  121. if (shouldStartTransmission == 1) {
  122. shouldStartTransmission = 0;
  123. UCSRB |= (1 << UDRIE); // Enable Interrupt
  124. UCSRA |= (1 << UDRE); // Trigger Interrupt
  125. }
  126. }
  127. void serialWriteString(char *data) {
  128. while (*data != '\0') {
  129. serialWrite(*data++);
  130. }
  131. }
  132. void serialClose() {
  133. UCSRB = 0;
  134. UCSRC = 0;
  135. UBRRH = 0;
  136. UBRRL = 0;
  137. rxRead = 0;
  138. txRead = 0;
  139. rxWrite = 0;
  140. txWrite = 0;
  141. }