serial.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. ** Made by fabien le mentec <texane@gmail.com>
  3. **
  4. ** Started on Mon Sep 21 08:54:27 2009 texane
  5. ** Last update Wed Nov 11 18:46:21 2009 texane
  6. */
  7. #include <pic18fregs.h>
  8. #define nop() __asm NOP __endasm
  9. /* fifo */
  10. struct fifo
  11. {
  12. unsigned char size : 4;
  13. unsigned char gie : 1;
  14. unsigned char peie : 1;
  15. unsigned char error : 1;
  16. unsigned char overflow : 1;
  17. unsigned char buffer[8];
  18. };
  19. #define FIFO_INITIALIZER { 0, }
  20. static void fifo_init(struct fifo* f)
  21. {
  22. f->size = 0;
  23. f->error = 0;
  24. f->overflow = 0;
  25. }
  26. static unsigned char fifo_pop(struct fifo* f)
  27. {
  28. return f->buffer[--f->size];
  29. }
  30. static void fifo_push(struct fifo* f, unsigned char c)
  31. {
  32. f->buffer[f->size++] = c;
  33. }
  34. static void fifo_lock(struct fifo* f)
  35. {
  36. f->gie = INTCONbits.GIE;
  37. f->peie = INTCONbits.PEIE;
  38. INTCONbits.GIE = 0;
  39. INTCONbits.PEIE = 0;
  40. }
  41. static void fifo_unlock(struct fifo* f)
  42. {
  43. INTCONbits.PEIE = f->peie;
  44. INTCONbits.GIE = f->gie;
  45. }
  46. static struct fifo gfifo;
  47. #define SERIAL_TX_TRIS TRISCbits.TRISC6
  48. #define SERIAL_TX_PIN LATCbits.LATC6
  49. #define SERIAL_RX_TRIS TRISCbits.TRISC7
  50. #define SERIAL_RX_PIN LATCbits.LATC7
  51. static void write_byte(unsigned char c)
  52. {
  53. /* load tx register
  54. */
  55. TXREG = c;
  56. nop();
  57. nop();
  58. nop();
  59. /* wait to be empty
  60. */
  61. while (!PIR1bits.TXIF)
  62. ;
  63. }
  64. static unsigned char peek_byte(void)
  65. {
  66. unsigned char c;
  67. while (!PIR1bits.RCIF)
  68. ;
  69. c = RCREG;
  70. PIR1bits.RCIF = 0;
  71. return c;
  72. }
  73. static void int_wait(void)
  74. {
  75. INTCONbits.PEIE = 1;
  76. INTCONbits.GIE = 1;
  77. __asm SLEEP __endasm ;
  78. }
  79. static unsigned char read_byte(void)
  80. {
  81. unsigned char has_read = 0;
  82. unsigned char c = 0;
  83. while (!has_read)
  84. {
  85. int_wait();
  86. fifo_lock(&gfifo);
  87. if (gfifo.size)
  88. {
  89. c = fifo_pop(&gfifo);
  90. has_read = 1;
  91. }
  92. else if (gfifo.error)
  93. {
  94. has_read = 1;
  95. }
  96. fifo_unlock(&gfifo);
  97. }
  98. return c;
  99. }
  100. /* exported */
  101. void serial_setup(void)
  102. {
  103. fifo_init(&gfifo);
  104. SERIAL_TX_TRIS = 0;
  105. SERIAL_RX_TRIS = 1;
  106. /* for PORTC
  107. */
  108. TXSTA = 0;
  109. TXSTAbits.TXEN = 1;
  110. RCSTA = 0;
  111. RCSTAbits.SPEN = 1;
  112. RCSTAbits.CREN = 1;
  113. /* disable rx/tx ints
  114. */
  115. PIR1bits.RCIF = 0;
  116. PIR1bits.TXIF = 0;
  117. PIE1bits.RCIE = 1;
  118. PIE1bits.TXIE = 0;
  119. /* 9600 bauds, 8n1
  120. */
  121. SPBRG = 12;
  122. TXSTA = 0x20;
  123. BAUDCON = 0x00;
  124. }
  125. void serial_read(unsigned char* s, unsigned char len)
  126. {
  127. len = len;
  128. *s = peek_byte();
  129. }
  130. int serial_pop_fifo(unsigned char* c)
  131. {
  132. int res = -1;
  133. fifo_lock(&gfifo);
  134. if (gfifo.size)
  135. {
  136. *c = fifo_pop(&gfifo);
  137. res = 0;
  138. }
  139. fifo_unlock(&gfifo);
  140. return res;
  141. }
  142. void serial_write(unsigned char* s, unsigned char len)
  143. {
  144. unsigned char i;
  145. for (i = 0; i < len; ++i)
  146. write_byte(s[i]);
  147. }
  148. void serial_writei(unsigned int i)
  149. {
  150. #define MASK_BYTE(VALUE, OFFSET) (((VALUE) >> (OFFSET * 8)) & 0xff)
  151. write_byte(MASK_BYTE(i, 0));
  152. write_byte(MASK_BYTE(i, 1));
  153. }
  154. void serial_writeb(unsigned char b)
  155. {
  156. write_byte(b);
  157. }
  158. void serial_handle_interrupt(void)
  159. {
  160. if (!PIR1bits.RCIF)
  161. return ;
  162. if (RCSTAbits.OERR)
  163. {
  164. unsigned char c;
  165. c = RCREG;
  166. gfifo.error = 1;
  167. }
  168. else if (RCSTAbits.FERR)
  169. {
  170. RCSTAbits.CREN = 0;
  171. RCSTAbits.CREN = 1;
  172. gfifo.error = 1;
  173. }
  174. else
  175. {
  176. if (gfifo.size < sizeof(gfifo.buffer))
  177. fifo_push(&gfifo, RCREG);
  178. else
  179. gfifo.overflow = 1;
  180. }
  181. PIR1bits.RCIF = 0;
  182. }