-
Notifications
You must be signed in to change notification settings - Fork 0
/
avr.asm
111 lines (108 loc) · 3.03 KB
/
avr.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
; This file is part of Programator.
;
; Programator is free software: you can redistribute it and/or
; modify it under the terms of the GNU General Public License as
; published by the Free Software Foundation, either version 3 of the
; License, or (at your option) any later version.
;
; Programator is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
; General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with Programator. If not, see <https://www.gnu.org/licenses/>.
;
; Copyright (c) 2022 Aleksander Mazur
;
; Procedury pomocnicze do programowania AVR-ów (np. ATtiny2313)
;-----------------------------------------------------------
; Inicjuje komunikację z mikrokontrolerem.
; W razie błędu wypisuje komunikat i nie wraca!
; Niszczy A, C, R5, R6, R7
avr_init:
mov R6, #0
avr_init_loop1:
; SCK=0, nRST=0
anl P1, #01101111b
djnz R6, avr_init_loop1
mov R7, #20
avr_init_reset:
mov R6, #10
avr_init_loop2:
; nRST=1
setb AVR_nRST
djnz R6, avr_init_loop2
; nRST=0
clr AVR_nRST
; sleep 20ms
mov TH0, #-72
mov TL0, #0
acall sleep_timer0
; wysyłamy Programming Enable (0xAC53)
mov A, #10101100b
acall avr_transfer_byte
mov A, #01010011b
acall avr_transfer_byte
; czytamy 2 bajty - prawidłowa odpowiedź to 53h w trzecim bajcie
acall avr_transfer_byte
mov R5, A
acall avr_transfer_byte
cjne R5, #01010011b, avr_init_error
ret
avr_init_error:
mov DPTR, #s_error_avrerr
acall uart_send_rom
acall uart_send_colon
mov A, R5
acall uart_send_hex_byte
acall uart_send_crlf
djnz R7, avr_init_reset
avr_error:
mov DPTR, #s_error_avrerr
ajmp print_error_then_prompt
;-----------------------------------------------------------
; Wymienia bajt danych z AVR
; Wysyła bity z A na linię MOSI (od najstarszych)
; i zasysa bity z MISO do A (od najmłodszych)
; Na wejściu nRST=0 i SCK=0
; Przesuwa A, niszczy C, R6
avr_transfer_byte:
mov R6, #8
avr_transfer_bits:
rlc A
mov AVR_MOSI, C ; najstarszy bit z A -> MOSI
rr A ; przywracamy A do poprzedniego stanu (oprócz najstarszego bitu, który jest już nieistotny, bo przed chwilą go wysłaliśmy)
setb AVR_SCK
nop
mov C, AVR_MISO
rlc A ; MISO -> najmłodszy bit w A
clr AVR_SCK
djnz R6, avr_transfer_bits
ret
;-----------------------------------------------------------
; Czeka, aż AVR przejdzie w stan READY z BUSY
; Niszczy A, C, R2, R6
; Zwraca C=0, jeśli jest READY, a C=1, jeśli strasznie długo jest BUSY
avr_wait_until_ready:
mov R2, #0
avr_poll_rdy_bsy_loop:
; Poll RDY/nBSY: 1111 0000 0000 0000 xxxx xxxx xxxx xxxo
mov A, #11110000b
acall avr_transfer_byte
clr A
acall avr_transfer_byte
acall avr_transfer_byte
acall avr_transfer_byte
rrc A
jnc avr_poll_rdy_bsy_end
djnz R2, avr_poll_rdy_bsy_loop2
; C=1 (djnz nie zmienia flag)
avr_poll_rdy_bsy_end:
ret
avr_poll_rdy_bsy_loop2:
; było 230 djnz-ów (0,5ms)
mov TH0, #-2
mov TL0, #-204
acall sleep_timer0
sjmp avr_poll_rdy_bsy_loop