Advertisement
Guest User

Untitled

a guest
May 23rd, 2017
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; to disassmble:
  2. ; avr-objdump -m avr -D firmware.hex
  3. ; firmware.hex is located in .pioenvs/uno in project dir
  4.  
  5. #include "atmega328p_def_inc.S"
  6.  
  7. .equ LED_DATA_PIN, 7
  8. .equ SRAM_DATA_BUF_ADDR, 255
  9.  
  10. .equ LED_COUNT, (1024 * 3)
  11. .equ SRAM_DATA_BUF_ADDR_END, SRAM_DATA_BUF_ADDR + (LED_COUNT / 2) + 1
  12.  
  13. .text
  14.  
  15. .org 0
  16.   rjmp main
  17.  
  18. main:
  19.   ; reset system status register
  20.   ldi r16,0
  21.   out SREG,r16
  22.  
  23.   ; init stack pointer
  24.   ldi r16,lo8(RAMEND)
  25.   out SPL,r16
  26.   ldi r16,hi8(RAMEND)
  27.   out SPH,r16
  28.  
  29.   ; set data pin as output
  30.   ldi r16, (1 << LED_DATA_PIN)
  31.   out DDRD, r16
  32.   rcall uart_init
  33.   rjmp mainloop
  34.  
  35.  
  36.   ;-----------------------------------------------------------
  37.   ; UART
  38.   ;-----------------------------------------------------------
  39.   uart_init:
  40.     ; set baud rate to 1 Mbps
  41.     ldi r16, 1<<U2X0
  42.     sts UCSR0A, r16
  43.     ldi r16, 0
  44.     sts UBRR0H, r16
  45.     ldi r16, 1
  46.     sts UBRR0L, r16
  47.  
  48.     ; enable receive and transmit, without interrupts
  49.     ldi r16, (1<<RXEN0)|(1<<TXEN0)
  50.     sts UCSR0B,r16
  51.  
  52.     ; frame format: 8 data bits, 1 stop bit, no parity.
  53.     ldi r16, (1<<UCSZ01)|(1<<UCSZ00)
  54.     sts UCSR0C,r16
  55.  
  56.     ret
  57.  
  58.   ; sends one byte over the serial line.
  59.   ; data must reside in r17.
  60.   uart_send_byte:
  61.     ; wait for send register to become empty
  62.     lds r16, UCSR0A
  63.     sbrs r16, UDRE0
  64.     rjmp uart_send_byte
  65.  
  66.     ; write data to transmit register
  67.     sts UDR0, R17
  68.  
  69.     ret
  70.  
  71.   ; receives one byte from the serial line.
  72.   ; data received is moved to r17.
  73.   uart_receive_byte:
  74.     ; wait for receive complete flag
  75.     lds r16, UCSR0A
  76.     sbrs r16, RXC0
  77.     rjmp uart_receive_byte
  78.  
  79.     ; write data to r17
  80.     lds r17, UDR0
  81.  
  82.     ret
  83.  
  84. ;-----------------------------------------------------------
  85. ; main loop
  86. ;-----------------------------------------------------------
  87. mainloop:
  88.   call uart_receive_frame
  89.   call write_leds
  90.   rjmp mainloop
  91.  
  92.  
  93. ;-----------------------------------------------------------
  94. ; receive frame
  95. ;-----------------------------------------------------------
  96. ; receive a complete frame through serial line
  97. ; frame consists of 1 nibble per led, followed by 0xf
  98. ; r30 + r31: frame data pointer
  99. ; r20 + r21: data counter
  100. ; r22: 0x0f
  101. ; r23: 0xf0
  102. uart_receive_frame:
  103.   ; reset data pointer
  104.   ldi r30, lo8(SRAM_DATA_BUF_ADDR)
  105.   ldi r31, hi8(SRAM_DATA_BUF_ADDR)
  106.  
  107.   ; reset data counter
  108.   ldi r20, lo8(LED_COUNT)
  109.   ldi r21, hi8(LED_COUNT)
  110.  
  111. rcv_loop:
  112.   ; fetch data from uart
  113.   call uart_receive_byte
  114.   st Z+, r17
  115.  
  116.   ; look for 0xf nibble
  117.  
  118.  
  119.   ; decrement counter
  120.   dec r20
  121.   cpi r20, 0
  122.   breq dec_hi
  123.   rjmp rcv_loop
  124.  
  125.   dec_hi:
  126.   dec r21
  127.   cpi r21, 0
  128.   breq rcv_done
  129.   ldi r20, 0xff
  130.   rjmp rcv_loop
  131.  
  132. rcv_done:
  133.   ret
  134.  
  135. ; ws2812b led data output
  136. ;
  137. ; r30 + r31: frame data pointer
  138. ; r20 + r21: data counter
  139. ; r22: bit counter
  140. ; r23: current frame byte
  141. ; r26: 3
  142. ; r27: 7
  143. write_leds:
  144.   ; reset data pointer
  145.   ldi r30, lo8(SRAM_DATA_BUF_ADDR) ; ZL
  146.   ldi r31, hi8(SRAM_DATA_BUF_ADDR) ; ZH
  147.  
  148.   ; reset data counter
  149.   ldi r20, lo8(LED_COUNT)
  150.   ldi r21, hi8(LED_COUNT)
  151.  
  152.   ; reset bit counter
  153.   ldi r22, 0
  154.  
  155.   ; set constants
  156.   ldi r26, 3
  157.   ldi r27, 7
  158.  
  159.   ; load first led byte
  160.   ld r23, Z+
  161.  
  162.   lsl r23
  163.   inc r22
  164.  
  165. write_nibble_start:
  166.  
  167.   ; start with two zeros
  168.   sbi PORTD, LED_DATA_PIN ; +2
  169.   nop
  170.   nop ; +4
  171.   nop
  172.   nop ; +6
  173.   cbi PORTD, LED_DATA_PIN ; +2
  174.   nop
  175.   nop ; +4
  176.   nop
  177.   nop ; +6
  178.   nop
  179.   nop ; +8
  180.   nop
  181.   nop ; +10
  182.   nop
  183.   nop ; +12
  184.   nop
  185.   nop ; +14
  186.   nop ; +15
  187.   sbi PORTD, LED_DATA_PIN ; +2
  188.   nop
  189.   nop ; +4
  190.   nop
  191.   nop ; +6
  192.   cbi PORTD, LED_DATA_PIN ; +2
  193.   nop
  194.   nop ; +4
  195.   nop
  196.   nop ; +6
  197.   nop
  198.   nop ; +8
  199.   nop
  200.   nop ; +10
  201.   nop
  202.   nop ; +12
  203.   brbs SREG_C, write_one ; +14 if true / +13 if false
  204.   rjmp write_zero ; +15
  205.  
  206. write_one:
  207.   nop ; +15
  208.   sbi PORTD, LED_DATA_PIN ; +2
  209.   nop
  210.   nop ; +4
  211.   nop
  212.   nop ; +6
  213.   inc r22
  214.   lsl r23 ; + 8
  215.   cp r26, r22
  216.   breq write_nibble_end3 ; +11 true, +10 false
  217.   cp r27, r22 ; + 11
  218.   breq write_nibble_end4 ; +13 true, +12 false
  219.   nop ; +13
  220.   nop ; +14
  221.   nop ; +15 cycles total high
  222.   cbi PORTD, LED_DATA_PIN ; +2
  223.   nop
  224.   brbs SREG_C, write_one ; +5 true, +4 false
  225.   rjmp write_zero ; + 6
  226.  
  227. ; END WRITE_ONE
  228.  
  229.  
  230. write_zero:
  231.   sbi PORTD, LED_DATA_PIN ; +2
  232.   nop
  233.   nop ; +4
  234.   nop
  235.   nop ; +6
  236.   cbi PORTD, LED_DATA_PIN ; +2
  237.   nop
  238.   nop ; +4
  239.   nop
  240.   nop ; +6
  241.   inc r22
  242.   lsl r23 ; + 8
  243.   cp r26, r22
  244.   breq write_nibble_end1 ; +11 true, +10 false
  245.   cp r27, r22 ; + 11
  246.   breq write_nibble_end2 ; +13 true, +12 false
  247.   nop ; +13
  248.   nop ; +14
  249.   nop ; +15
  250. ; END WRITE_ZERO
  251.  
  252.  
  253. ; end with two zeros
  254. write_nibble_end3:
  255.   nop
  256.   nop
  257. write_nibble_end4:
  258.   nop
  259.   nop
  260.   cbi PORTD, LED_DATA_PIN
  261. write_nibble_end1:
  262.   nop
  263.   nop
  264. write_nibble_end2:
  265.   nop ; +14
  266.   nop ; +15
  267.   sbi PORTD, LED_DATA_PIN ; +2
  268.   nop
  269.   nop ; +4
  270.   nop
  271.   nop ; +6
  272.   cbi PORTD, LED_DATA_PIN ; +2
  273.   nop
  274.   nop ; +4
  275.   cp r22, r27  ; +5
  276.   breq next_byte ; +7 true, +6 false
  277.   nop ; +7
  278.   nop ; +8
  279.   rjmp next_led ; + 10
  280.  
  281. next_byte:  ; load next byte
  282.   ld r23, Z+ ; +9
  283.   clr r22 ; + 10
  284.  
  285. next_led: ; test ledcount max
  286.   cp r31, lo8(LED_COUNT) ; +11
  287.   breq cmp_hi            ; +13 true, +12 false
  288.   rjmp init_next_led     ; +14
  289.  
  290. cmp_hi:
  291.   nop ; +14
  292.   nop ; +15
  293.   sbi PORTD, LED_DATA_PIN ; +2
  294.   nop
  295.   nop ; +4
  296.   nop
  297.   nop ; +6
  298.   cbi PORTD, LED_DATA_PIN ; +2
  299.   cp r30, hi8(LED_COUNT) ; +1
  300.   breq done ; +2
  301.   lsl r23 ; +3
  302.   inc r22 ; +4
  303.   nop
  304.   nop ; +6
  305.   nop
  306.   nop ; +8
  307.   nop
  308.   nop ; +10
  309.   nop
  310.   nop ; +12
  311.   nop
  312.   nop ; +14
  313.   nop
  314.   rjmp write_nibble_start
  315.  
  316. init_next_led:
  317.   nop  ; +15
  318.   sbi PORTD, LED_DATA_PIN ; +2
  319.   nop
  320.   nop ; +4
  321.   nop
  322.   nop ; +6
  323.   cbi PORTD, LED_DATA_PIN ; +2
  324.   nop
  325.   nop ; +4
  326.   nop
  327.   nop ; +6
  328.   nop
  329.   nop ; +8
  330.   nop
  331.   nop ; +10
  332.   nop
  333.   lsl r23 ; +12
  334.   inc r22
  335.   rjmp write_nibble_start ; +15
  336.  
  337. done:
  338.   ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement