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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
;;
;; spreadspace pic utils
;;
;;
;; Copyright (C) 2011-2013 Christian Pointner <equinox@spreadspace.org>
;;
;; This file is part of spreadspace pic utils.
;;
;; spreadspace pic utils 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
;; any later version.
;;
;; spreadspace pic utils 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 spreadspace pic utils. If not, see <http://www.gnu.org/licenses/>.
;;
;; flash read --------
cmd_reset
movlw E_OK
call ack_cmd
movlb .3
cmd_resset_wait_ack
btfss TXSTA,TRMT
goto cmd_resset_wait_ack
reset
;; flash read --------
cmd_r_flash
movlw FSS ; initialize EEADR:EEADRH and FSR
movwf cnt
movlb .3
movlw combuff + .2
movwf FSR
movf INDF,w
movwf EEADRL
incf FSR,f
movf INDF,w
movwf EEADRH
read_flash_segment_loop
bcf EECON1,CFGS ; perform the actual read
bsf EECON1,EEPGD
bsf EECON1,RD
nop
nop
movf EEDATL,w ; load code word from EEDAT:EEDATH to combuff
movwf INDF
incf FSR,f
movf EEDATH,w
movwf INDF
incf FSR,f
incfsz EEADRL,f ; increment flash address
goto read_flash_segment_next
incf EEADRH,f
read_flash_segment_next
decfsz cnt,f
goto read_flash_segment_loop
movlb .0
clrf combuff + .2 ; = E_OK
movlw .1 + .2*FSS ; bytes to send
call send_answer
goto wait_new_cmd
;; flash write --------
cmd_w_flash
movlw .2 ; if addr[15:8] < 2 -> boot loader section
subwf combuff + .3,w
btfss STATUS,C
goto address_prohibited
movlw FLASH_BOUNDARY ; addr on boundary?
andwf combuff + .2,w
btfss STATUS,Z
goto address_invalid
movlw FSS ; initialize EEADR:EEADRH and FSR
movwf cnt
movlb .3
movlw combuff + .2
movwf FSR
movf INDF,w
movwf EEADRL
incf FSR,f
movf INDF,w
movwf EEADRH
bcf EECON1,CFGS
bsf EECON1,EEPGD
bsf EECON1,WREN
write_flash_segment_loop
incf FSR,f ; load code word into EEDAT:EEDATH
movf INDF,w
movwf EEDATL
incf FSR,f
movf INDF,w
movwf EEDATH
bsf EECON1,FREE ; erase row before writing
movlw H'55'
movwf EECON2
movlw H'AA'
movwf EECON2
bsf EECON1,WR
nop
nop
bcf EECON1,FREE ; now start the acutal write sequence
movf EEADRL,w
andlw FLASH_BOUNDARY
xorlw FLASH_BOUNDARY
btfss STATUS,Z
bsf EECON1,LWLO
btfsc STATUS,Z
bcf EECON1,LWLO
movlw H'55'
movwf EECON2
movlw H'AA'
movwf EECON2
bsf EECON1,WR
nop
nop
incfsz EEADRL,f ; increment flash address
goto write_flash_segment_next
incf EEADRH,f
write_flash_segment_next
decfsz cnt,f
goto write_flash_segment_loop
bcf EECON1,WREN
movlw E_OK ; check if a write error occured
btfsc EECON1,WRERR
movlw E_FLASH_WERR
movlb .0
movwf combuff + .2 ; = E_OK or write error
movlw .1 ; bytes to send
call send_answer
goto wait_new_cmd
;; read config --------
cmd_r_config
movf combuff + .2,w
sublw CFG - .1
btfss STATUS,C
goto address_invalid
movf combuff + .2,w
movlb .3
addlw CONFIG_OFFSET
movwf EEADRL
clrf EEADRH
bsf EECON1,CFGS
bsf EECON1,RD
nop
nop
movf EEDATL,w
movlb .0
movwf combuff + .3
movlb .3
movf EEDATH,w
movlb .0
movwf combuff + .4
movlw E_OK
movwf combuff + .2 ; = E_OK
movlw .3 ; bytes to send
call send_answer
goto wait_new_cmd
|