suart.S 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. ;---------------------------------------------------------------------------;
  2. ; Software implemented UART module ;
  3. ; (C)ChaN, 2005 (http://elm-chan.org/) ;
  4. ;---------------------------------------------------------------------------;
  5. ; Bit rate settings:
  6. ;
  7. ; 1MHz 2MHz 4MHz 6MHz 8MHz 10MHz 12MHz 16MHz 20MHz
  8. ; 2.4kbps 138 - - - - - - - -
  9. ; 4.8kbps 68 138 - - - - - - -
  10. ; 9.6kbps 33 68 138 208 - - - - -
  11. ; 19.2kbps - 33 68 102 138 173 208 - -
  12. ; 38.4kbps - - 33 50 68 85 102 138 172
  13. ; 57.6kbps - - 21 33 44 56 68 91 114
  14. ; 115.2kbps - - - - 21 27 33 44 56
  15. .nolist
  16. #include <avr/io.h>
  17. .list
  18. #define BPS 25 /* Bit delay. (see above table) */
  19. #define BIDIR 0 /* 0:Separated Tx/Rx, 1:Shared Tx/Rx */
  20. #define USE_RCV 0
  21. #define OUT_1 sbi _SFR_IO_ADDR(PORTB), 1 /* Output mark */
  22. #define OUT_0 cbi _SFR_IO_ADDR(PORTB), 1 /* Output space */
  23. #define SKIP_IN_1 sbic _SFR_IO_ADDR(PINB), 1 /* Skip if mark */
  24. #define SKIP_IN_0 sbis _SFR_IO_ADDR(PINB), 1 /* Skip if space */
  25. ;---------------------------------------------------------------------------;
  26. ; Transmit a byte in serial format of N81
  27. ;
  28. ;Prototype: void xmit (uint8_t data);
  29. ;Size: 16 words
  30. .global xmit
  31. .func xmit
  32. xmit:
  33. #if BIDIR
  34. ldi r23, BPS-1 ;Pre-idle time for bidirectional data line
  35. 5: dec r23 ;
  36. brne 5b ;/
  37. #endif
  38. in r0, _SFR_IO_ADDR(SREG) ;Save flags
  39. com r24 ;C = start bit
  40. ldi r25, 10 ;Bit counter
  41. cli ;Start critical section
  42. 1: ldi r23, BPS-1 ;----- Bit transferring loop
  43. 2: dec r23 ;Wait for a bit time
  44. brne 2b ;/
  45. brcs 3f ;MISO = bit to be sent
  46. OUT_1 ;
  47. 3: brcc 4f ;
  48. OUT_0 ;/
  49. 4: lsr r24 ;Get next bit into C
  50. dec r25 ;All bits sent?
  51. brne 1b ; no, coutinue
  52. out _SFR_IO_ADDR(SREG), r0 ;End of critical section
  53. ret
  54. .endfunc
  55. ;---------------------------------------------------------------------------;
  56. ; Receive a byte
  57. ;
  58. ;Prototype: uint8_t rcvr (void);
  59. ;Size: 19 words
  60. #if USE_RCV
  61. .global rcvr
  62. .func rcvr
  63. rcvr:
  64. in r0, _SFR_IO_ADDR(SREG) ;Save flags
  65. ldi r24, 0x80 ;Receiving shift reg
  66. cli ;Start critical section
  67. 1: SKIP_IN_1 ;Wait for idle
  68. rjmp 1b
  69. 2: SKIP_IN_0 ;Wait for start bit
  70. rjmp 2b
  71. ldi r25, BPS/2 ;Wait for half bit time
  72. 3: dec r25
  73. brne 3b
  74. 4: ldi r25, BPS ;----- Bit receiving loop
  75. 5: dec r25 ;Wait for a bit time
  76. brne 5b ;/
  77. lsr r24 ;Next bit
  78. SKIP_IN_0 ;Get a data bit into r24.7
  79. ori r24, 0x80
  80. brcc 4b ;All bits received? no, continue
  81. out _SFR_IO_ADDR(SREG), r0 ;End of critical section
  82. ret
  83. .endfunc
  84. #endif