Guest User

Untitled

a guest
Jan 17th, 2019
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.90 KB | None | 0 0
  1. ;--------------------------------------------------------------------------------
  2. ; File: rx_isr_asm.S - msp430 gcc asm version of SoftSerial_RX_ISR (faster code)
  3. ;
  4. ; Desc: This code handles receiving serial data using the TIMERA1 ISR
  5. ; It starts out in capture mode waiting for the start bit (transition from
  6. ; high to low) then switches to compare mode for 8 bits. It accumulates
  7. ; each lsb->msb received bit into a byte and stores it in a ringbuffer
  8. ; The code attempts to minimize register usage to just r15.
  9. ;
  10. ; This code is about ~21 cycles faster than the C version.
  11. ; However, the code size is about 22 bytes larger. Useful if you want
  12. ; to run your F_CPU at a really low frequency and still receive data
  13. ;
  14. ; Author: rick@kimballsoftware.com
  15. ; Date: 08-01-2012
  16. ;
  17.  
  18. #include <msp430.h>
  19. #include "config.h" /* for F_CPU, BAUD_RATE, and RX_BUFFER_SIZE */
  20.  
  21. ;--------------------------------------------------------------------------------
  22. ; --- Defines
  23. ;--------------------------------------------------------------------------------
  24. #define PC r0 /* program counter */
  25. #define TIMERA1_VEC 8 /* TIMERA1_VECTOR/2 (0x0010)/2 */
  26.  
  27. #define BIT_DUR (F_CPU/BAUD_RATE) /* cycle count between samples */
  28. #define BIT_DUR_1_5 (BIT_DUR)+(F_CPU/BAUD_RATE/2) /* 1.5 times a BIT_DUR */
  29.  
  30. #define rb_head rx_buffer+0 /* offsets into ringbuffer_t struct */
  31. #define rb_tail rx_buffer+2
  32. #define rb_buf rx_buffer+4
  33.  
  34. #define FOO (TIMERA1_VECTOR+1)/2
  35.  
  36. ;--------------------------------------------------------------------------------
  37. ; .interrupt - macro to declare an interrupt handler routine entry point
  38. ;--------------------------------------------------------------------------------
  39. .macro .interrupt isr_offset
  40. .global __isr_\isr_offset
  41. __isr_\isr_offset:
  42. .endm
  43.  
  44. ;--------------------------------------------------------------------------------
  45. ; --- BSS Data
  46. ;--------------------------------------------------------------------------------
  47. .section .bss.rx_isr_asm
  48. .p2align 1,0
  49. .lcomm state_vector,2
  50. .lcomm rx_mask,2
  51. .lcomm rx_data,2
  52. ;isrNo:
  53. ; .word FOO
  54.  
  55. ;--------------------------------------------------------------------------------
  56. ; --- Code
  57. ;--------------------------------------------------------------------------------
  58. .text
  59. .p2align 1,0
  60. .global SoftSerial_RX_ISR
  61. .type SoftSerial_RX_ISR,@function
  62.  
  63. .interrupt TIMERA1_VEC
  64. ;--------------------------------------------------------------------------------
  65. SoftSerial_RX_ISR:
  66. ;--------------------------------------------------------------------------------
  67. ; push, push, jump... ISR entry overhead 6 clocks
  68. ;push r15 ; preserve ... don't need to main reserved it for us
  69. bis.b #BIT0,&P1OUT ; uncomment to see where function ends.
  70. mov &TAIV, r6 ; reset interrupt flag by reading, we ignore btw
  71.  
  72. add &state_vector,PC ; use state vector to jump directly to a handler
  73. jmp handle_startbit ; 0 start bit
  74. jmp handle_databit_0_6 ; 2 bits 0 - 6
  75. jmp handle_databit_0_6 ; 4
  76. jmp handle_databit_0_6 ; 6
  77. jmp handle_databit_0_6 ; 8
  78. jmp handle_databit_0_6 ; 10
  79. jmp handle_databit_0_6 ; 12
  80. jmp handle_databit_0_6 ; 14
  81. jmp handle_databit_7 ; 16 bit 7
  82.  
  83. handle_startbit: ; handle start bit
  84. add #2, &state_vector ; set next handler
  85. bic #CAP, &TACCTL1 ; go into compare mode
  86. add #BIT_DUR_1_5, &TA0CCR1 ; set next sample in the middle of D0
  87. mov #0, &rx_data ; initialize recv byte
  88. mov #1, &rx_mask ; mask lsb -> msb
  89. jmp rx_isr_exit
  90.  
  91. handle_databit_0_6: ; handle bits 0-6
  92. add #2, &state_vector ; set next handler
  93. add #BIT_DUR, &TA0CCR1 ; set next sample time
  94. mov &rx_mask, r6 ; load mask
  95. bit #SCCI, &TACCTL1 ; check latched sampled data bit
  96. jz 1f
  97. bis r6, &rx_data ; if HI then set this bit
  98. 1:
  99. rla r6 ; make room for next data bit
  100. mov r6, &rx_mask
  101. jmp rx_isr_exit
  102.  
  103. handle_databit_7: ; handle last bit and store in ringbuffer
  104. mov #0, &state_vector ; go back to capture handler
  105. bit #SCCI, &TACCTL1 ; check latched sample data bit
  106. jz 1f
  107. bis #BIT7, &rx_data
  108. 1:
  109. mov &rb_head, r6 ; load rx_buffer.head
  110. mov.b &rx_data, rb_buf(r6) ; rx_buffer.buffer[head] = rx_data
  111. inc r6 ; rx_buffer.head++
  112. and #RX_BUFFER_SIZE-1, r6 ; take care of buffer wraparound, assumes power of 2 sized buf
  113. cmp r6, &rb_tail ; compare with tail
  114. jz 2f
  115. mov r6, &rb_head ; save new rx_buffer.head
  116. 2:
  117. bis #CAP, &TACCTL1 ; go back to capture mode
  118.  
  119. rx_isr_exit:
  120. ;pop r15 ; standard exit
  121. xor.b #BIT0,&P1OUT ; uncomment to see where function ends.
  122. ; xor.b takes 5 clocks
  123.  
  124. reti ; ISR exit overhead 5 cycles
  125. .Lfe1:
  126. .size SoftSerial_RX_ISR,.Lfe1-SoftSerial_RX_ISR
  127.  
  128. ;--------------------------------------------------------------------------------
  129. ; EOF rx_isr_asm.S
  130. ;--------------------------------------------------------------------------------
Add Comment
Please, Sign In to add comment