├── LICENSE
├── Makefile
├── README.md
├── cdc.c
├── cdc_app.c
├── ffff.c
├── include
├── interface.h
└── task.h
├── kernel
├── app_hdr.c
├── app_integrated.c
├── dummy.c
├── fixcrc.c
├── map.pl
├── syms.c
└── task.c
├── manufacturing.c
├── merge.sh
├── onerng.inf
├── random_data
├── set_size.c
├── size.sh
├── usb.c
├── usb.h
├── val
└── validate.c
└── validate.c
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
167 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # (c) Copyright Paul Campbell paul@taniwha.com 2013, 2014
2 | #
3 | # This library is free software; you can redistribute it and/or
4 | # modify it under the terms of the GNU Lesser General Public
5 | # License as published by the Free Software Foundation; either
6 | # version 2.1 of the License, or (at your option) version 3, or any
7 | # later version accepted by Paul Campbell , who shall
8 | # act as a proxy defined in Section 6 of version 3 of the license.
9 | #
10 | # This library is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | # Lesser General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU Lesser General Public
16 | # License along with this library. If not, see .
17 | #
18 |
19 | THIS_ARCH = 255 # set this to match the hardware - invalid in this case
20 | THIS_CODE_BASE = 0 # set this to match the code base currently running in the board
21 | THIS_VERSION = 2 # suota version
22 | # DRV_KEYS = 1 # define for key driver
23 | # DRV_LEDS = 1 # define for leds driver
24 | # DRV_DAYLIGHT = 1 # define for daylight detector driver
25 |
26 | # kernel tree root for building kernels
27 | KERNEL_ROOT=.
28 | SERIAL_ROOT=../sys
29 |
30 | #
31 | # where the app is
32 | #
33 | APP_ROOT=.
34 | APP_NAME=cdc_app
35 |
36 |
37 | SDCC_INSTALL_DIR = /usr/local/share/sdcc
38 | KERNEL_ALL = packet_loader kernel.ihx kernel.lk
39 | #KERNEL_ALL =
40 |
41 | HOST_CC = gcc
42 | HOST_CPP = g++
43 | CC = sdcc
44 | LD = sdld -n
45 | AS = sdas8051
46 |
47 | BASE0 = 0x2000
48 | BASE1 = 0x5000
49 |
50 | CFLAGS = -mmcs51 --model-medium --opt-code-size --debug -I$(KERNEL_ROOT)/include -DBASE0=$(BASE0) -DBASE1=$(BASE1)
51 | CFLAGS += -DTHIS_ARCH=$(THIS_ARCH) -DTHIS_CODE_BASE=$(THIS_CODE_BASE) -DTHIS_VERSION=$(THIS_VERSION)
52 | ifdef DRV_KEYS
53 | CFLAGS += -DDRV_KEYS
54 | endif
55 | ifdef DRV_LEDS
56 | CFLAGS += -DDRV_LEDS
57 | endif
58 | ifdef DRV_DAYLIGHT
59 | CFLAGS += -DDRV_DAYLIGHT
60 | endif
61 | CFLAGS += -DPOOL_SIZE=7168
62 | LDLIBS_SA = -k $(SDCC_INSTALL_DIR)/lib/medium -l mcs51 -l libsdcc -l libint -l liblong -l libfloat
63 | LDLIBS = -k $(SDCC_INSTALL_DIR)/lib/medium -l libsdcc -l libint -l liblong -l libfloat
64 | LDFLAGS_SA = -muwx -b SSEG=0x80 $(LDLIBS_SA) -M -Y -b BSEG=9
65 | LDFLAGS = -muwx -b SSEG=0x80 $(LDLIBS) -M -Y
66 | LDEVEN = -b GSINIT0=$(BASE0)
67 | LDODD = -b GSINIT0=$(BASE1)
68 |
69 |
70 | # kernel objects
71 | KOBJ = task.rel # suota.rel rf.rel suota_key.rel
72 | ifdef DRV_LEDS
73 | KOBJ += leds.rel
74 | endif
75 | ifdef DRV_KEYS
76 | KOBJ += keys.rel
77 | endif
78 |
79 | CFLAGS += -DAPP
80 | AOBJ = $(APP_NAME).rel cdc.rel usb.rel validate.rel manufacturing.rel
81 | APP_REQUIRED=kernel.lk syms.rel app_hdr.rel fixcrc
82 | #APP_REQUIRED=
83 |
84 | all: $(APP_NAME).256k
85 | images: $(APP_NAME).img.256k
86 |
87 | $(APP_NAME).128k: $(APP_NAME).sig.128k $(APP_NAME).img.128k $(APP_NAME).len.sig.128k FFFF
88 | cat $(APP_NAME).img.128k $(APP_NAME).len.sig.128k $(APP_NAME).sig.128k FFFF >$(APP_NAME).128k
89 | truncate -s 131072 $(APP_NAME).128k
90 | $(APP_NAME).256k: $(APP_NAME).sig.256k $(APP_NAME).img.256k $(APP_NAME).len.sig.256k FFFF
91 | cat $(APP_NAME).img.256k $(APP_NAME).len.sig.256k $(APP_NAME).sig.256k FFFF >$(APP_NAME).256k
92 | truncate -s 262144 $(APP_NAME).256k
93 |
94 |
95 | FFFF: ffff.c
96 | gcc -o ff ffff.c
97 | ./ff >FFFF
98 |
99 | $(APP_NAME).len.sig.256k: $(APP_NAME).sig.256k set_size
100 | ./set_size $(APP_NAME).sig.256k >$(APP_NAME).len.sig.256k
101 |
102 | $(APP_NAME).len.sig.128k: $(APP_NAME).sig.128k set_size
103 | ./set_size $(APP_NAME).sig.128k >$(APP_NAME).len.sig.128k
104 |
105 | set_size: set_size.c
106 | gcc -o set_size set_size.c
107 |
108 | $(APP_NAME).sig.128k: $(APP_NAME).img.128k
109 | rm -f $(APP_NAME).sig.128k
110 | gpg -u 0x35d6020c --output $(APP_NAME).sig.128k --detach-sig $(APP_NAME).img.128k
111 |
112 | $(APP_NAME).sig.256k: $(APP_NAME).img.256k
113 | rm -f $(APP_NAME).sig.256k
114 | gpg -u 0x35d6020c --output $(APP_NAME).sig.256k --detach-sig $(APP_NAME).img.256k
115 |
116 |
117 |
118 | $(APP_NAME).img.128k: $(APP_NAME).ihx random_data merge.sh
119 | ./merge.sh $(APP_NAME).ihx random_data 131072 $(APP_NAME).img.128k
120 |
121 | $(APP_NAME).img.256k: $(APP_NAME).ihx random_data merge.sh
122 | ./merge.sh $(APP_NAME).ihx random_data 262144 $(APP_NAME).img.256k
123 |
124 |
125 | ############## App starts here ############################################
126 | #
127 | # To build a SUOTA app:
128 | #
129 | # - create a new app build directory
130 | # - copy this Makefile to the app build directory
131 | # - copy sample_app/app.c to app build directory
132 | # - change directory to the new build directory
133 | # - edit the Makefile
134 | # - edit APP_NAME
135 | # - edit APP_ROOT to point to "."
136 | # - edit KERNEL_ROOT and SERIAL_ROOT to point to the place you installed the kernel
137 | # - set "THIS_ARCH" to match your hardware
138 | # - choose a value for "THIS_CODE_BASE" (probably this means choosing a random CODE_BASE between 1-254)
139 | # - edit THIS_VERSION to 1 (increment each time you make a downloadble build)
140 | # - type "make" to build a kernel/etc
141 | # - build and test your kernel and app until you want to freeze it then:
142 | # - make a subdirectory called 'save' and copy everything into it (just in case you lose the kernel)
143 | # - edit the Makefile again
144 | # - in the makefile remove everything below "## Kernel starts here ##"
145 | # - edit APP_REQUIRED to make it empty
146 | # - edit KERNEL_ALL to make it empty
147 | #
148 | # Below is a 'push' target you can use to automatically bump the version number, build
149 | # and push a new image to a device
150 | #
151 |
152 | #
153 | # unified build for example application - you must include app_integrated.rel
154 | #
155 | $(APP_NAME).ihx: $(KOBJ) $(AOBJ) app_integrated.rel
156 | $(LD) $(LDFLAGS_SA) -i $(APP_NAME).ihx $(KOBJ) $(AOBJ) app_integrated.rel
157 |
158 | #
159 | # example application
160 | #
161 | $(APP_NAME).rel: $(APP_ROOT)/$(APP_NAME).c $(KERNEL_ROOT)/include/interface.h
162 | $(CC) $(CFLAGS) -I $(SERIAL_ROOT)/serial -c $(APP_ROOT)/$(APP_NAME).c -o $(APP_NAME).rel
163 | cdc.rel: $(APP_ROOT)/cdc.c $(KERNEL_ROOT)/include/interface.h
164 | $(CC) $(CFLAGS) -c $(APP_ROOT)/cdc.c -o cdc.rel
165 | usb.rel: $(APP_ROOT)/usb.c $(KERNEL_ROOT)/include/interface.h
166 | $(CC) $(CFLAGS) -c $(APP_ROOT)/usb.c -o usb.rel
167 | validate.rel: $(APP_ROOT)/validate.c $(KERNEL_ROOT)/include/interface.h
168 | $(CC) $(CFLAGS) -I.. -c $(APP_ROOT)/validate.c -o validate.rel
169 | manufacturing.rel: $(APP_ROOT)/manufacturing.c $(KERNEL_ROOT)/include/interface.h
170 | $(CC) $(CFLAGS) -I.. -c $(APP_ROOT)/manufacturing.c -o manufacturing.rel
171 |
172 | #
173 | # code to automatically build and push new software versions of code to
174 | # a single remote device.
175 | #
176 | # Put the key you want to SUOTA with and the channel it happens on below, use the
177 | # command
178 | #
179 | # "make push"
180 | #
181 | # to build new code and push it to a device
182 | #
183 | APP_SUOTA_KEY=-k ccb17cb57448634ce595c15acf966145
184 | APP_SUOTA_CHANNEL=11
185 |
186 | push: $(AOBJ) $(APP_REQUIRED) THIS_VERSION packet_loader
187 | version=`cat ./THIS_VERSION` ; \
188 | version=$$(($$version+1));\
189 | odd=$$(($$version%2));\
190 | if test $$odd -eq 1; then \
191 | $(LD) $(LDODD) $(LDFLAGS) -f kernel.lk -i tmp.ihx $(AOBJ) syms.rel app_hdr.rel;\
192 | else \
193 | $(LD) $(LDEVEN) $(LDFLAGS) -f kernel.lk -i tmp.ihx $(AOBJ) syms.rel app_hdr.rel;\
194 | fi ; \
195 | ./fixcrc -v $$version $(APP_SUOTA_KEY) $(APP_NAME).suota;\
196 | echo $$version >THIS_VERSION ; \
197 | echo Installing version $$version ; \
198 | ./packet_loader -c $(APP_SUOTA_CHANNEL) -x $(APP_NAME).suota
199 |
200 | THIS_VERSION:
201 | echo $(THIS_VERSION) >THIS_VERSION
202 |
203 |
204 | ############## Kernel starts here ############################################
205 | #
206 | # To build a kernel for SUOTA:
207 | #
208 | # - edit the "THIS_" variables above to suit set the version to 0
209 | # - edit LDLIBS/LDLIBS_SA to point to where your SDCC libraries were installed
210 | # - change HOST_CC/HOST_CPP to point to your local native compilers
211 | # - type "make kernel"
212 | # - copy the folowing files to your app build directory:
213 | # - kernel.lk
214 | # - app_hdr.rel
215 | # - syms.rel
216 | # - fixcrc
217 | # - burn the kernel.ihx file into your hardware
218 | #
219 | kernel: kernel.lk app_hdr.rel syms.rel fixcrc
220 |
221 | #
222 | # create loader script to export kernel context to loadable apps
223 | #
224 | kernel.lk: kernel.map $(KERNEL_ROOT)/kernel/map.pl
225 | perl $(KERNEL_ROOT)/kernel/map.pl kernel.lk
226 | #
227 | # build kernel - kernel.ihx is what you build into a board (we'll add somethign here to allow
228 | # later patching of MAC addresses)
229 | #
230 | kernel.ihx kernel.map: $(KOBJ) dummy.rel
231 | $(LD) $(LDFLAGS_SA) -l mcs51 -b PSEG=0 -b XSEG=0x100 -i kernel.ihx $(KOBJ) dummy.rel
232 |
233 |
234 | #
235 | # build kernel objects - leds.rel and kerys.rel should be left out of you don't need them
236 | #
237 | task.rel: $(KERNEL_ROOT)/kernel/task.c $(KERNEL_ROOT)/include/task.h $(KERNEL_ROOT)/include/interface.h
238 | $(CC) $(CFLAGS) -c $(KERNEL_ROOT)/kernel/task.c
239 | #rf.rel: $(KERNEL_ROOT)/kernel/rf.c $(KERNEL_ROOT)/include/rf.h $(KERNEL_ROOT)/include/task.h $(KERNEL_ROOT)/include/interface.h $(KERNEL_ROOT)/include/suota.h $(KERNEL_ROOT)/include/protocol.h
240 | # $(CC) $(CFLAGS) -c $(KERNEL_ROOT)/kernel/rf.c
241 | #keys.rel: $(KERNEL_ROOT)/kernel/keys.c $(KERNEL_ROOT)/include/rf.h $(KERNEL_ROOT)/include/task.h $(KERNEL_ROOT)/include/interface.h $(KERNEL_ROOT)/include/suota.h $(KERNEL_ROOT)/include/protocol.h
242 | # $(CC) $(CFLAGS) -c $(KERNEL_ROOT)/kernel/keys.c
243 | #suota.rel: $(KERNEL_ROOT)/kernel/suota.c $(KERNEL_ROOT)/include/rf.h $(KERNEL_ROOT)/include/task.h $(KERNEL_ROOT)/include/interface.h $(KERNEL_ROOT)/include/suota.h $(KERNEL_ROOT)/include/protocol.h
244 | # $(CC) $(CFLAGS) -c $(KERNEL_ROOT)/kernel/suota.c
245 | #suota_key.rel: $(KERNEL_ROOT)/kernel/suota_key.c #change this if you want a private efault suota key
246 | # $(CC) $(CFLAGS) -c $(KERNEL_ROOT)/kernel/suota_key.c
247 | #leds.rel: $(KERNEL_ROOT)/kernel/leds.s
248 | # $(AS) -z -l -o leds.rel $(KERNEL_ROOT)/kernel/leds.s
249 |
250 | #
251 | # this file provides access to kernel symbols exported using the linker .lk file - this
252 | # is solely to avoid a bug in sdcc's linker which complains if you have a -g
253 | # directive to declare a global variable but never use it
254 | #
255 | syms.rel: $(KERNEL_ROOT)/kernel/syms.c
256 | $(CC) $(CFLAGS) -c $(KERNEL_ROOT)/kernel/syms.c
257 |
258 | #
259 | # code header for unified build
260 | #
261 | app_integrated.rel: $(KERNEL_ROOT)/kernel/app_integrated.c $(KERNEL_ROOT)/include/task.h $(KERNEL_ROOT)/include/interface.h
262 | $(CC) $(CFLAGS) -c $(KERNEL_ROOT)/kernel/app_integrated.c
263 |
264 | #
265 | # code header for SUOTA apps
266 | #
267 | app_hdr.rel: $(KERNEL_ROOT)/kernel/app_hdr.c $(KERNEL_ROOT)/include/rf.h $(KERNEL_ROOT)/include/task.h $(KERNEL_ROOT)/include/interface.h $(KERNEL_ROOT)/include/suota.h $(KERNEL_ROOT)/include/protocol.h
268 | $(CC) $(CFLAGS) -c $(KERNEL_ROOT)/kernel/app_hdr.c
269 |
270 | #
271 | # dummy code header for kernel build
272 | #
273 | dummy.rel: $(KERNEL_ROOT)/kernel/dummy.c $(KERNEL_ROOT)/include/protocol.h
274 | $(CC) $(CFLAGS) -c $(KERNEL_ROOT)/kernel/dummy.c
275 |
276 | #
277 | # app to fill in code headers in SUOTA builds and create loadable binaries
278 | #
279 | fixcrc: $(KERNEL_ROOT)/kernel/fixcrc.c
280 | $(HOST_CC) -o fixcrc $(KERNEL_ROOT)/kernel/fixcrc.c
281 |
282 |
283 | #
284 | # linux side packet interface code for talking to the serial internet gateway
285 | # plus example interactive version - this app will host a SUOTA server for your
286 | # network
287 | #
288 | packet_loader: packet_interface.o packet_loader.o
289 | $(HOST_CPP) -o packet_loader packet_interface.o packet_loader.o -lpthread -g -lz
290 | packet_loader.o: $(SERIAL_ROOT)/serial/packet_interface.h $(SERIAL_ROOT)/serial/test.cpp $(SERIAL_ROOT)/serial/ip_packet_interface.h
291 | $(HOST_CPP) -c $(SERIAL_ROOT)/serial/test.cpp -o packet_loader.o -I $(KERNEL_ROOT)/include -I $(SERIAL_ROOT)/serial -g
292 | packet_interface.o: $(SERIAL_ROOT)/serial/packet_interface.h $(SERIAL_ROOT)/serial/packet_interface.cpp
293 | $(HOST_CPP) -c $(SERIAL_ROOT)/serial/packet_interface.cpp -I $(KERNEL_ROOT)/include -I $(SERIAL_ROOT)/serial -g
294 | ip_packet_interface.o: $(SERIAL_ROOT)/serial/packet_interface.h $(SERIAL_ROOT)/serial/ip_packet_interface.cpp $(SERIAL_ROOT)/serial/ip_packet_interface.h
295 | $(HOST_CPP) -c $(SERIAL_ROOT)/serial/ip_packet_interface.cpp -I $(KERNEL_ROOT)/include -I $(SERIAL_ROOT)/serial -g
296 |
297 |
298 | #
299 | #
300 | # unified serial app for the dev board that turns it into a packet gateway
301 | #
302 | SOBJ = serial_app.rel app_integrated.rel
303 | serial.ihx: $(KOBJ) packet_interface.o $(SOBJ)
304 | $(LD) $(LDFLAGS_SA) -i serial.ihx $(KOBJ) $(SOBJ)
305 | serial_app.rel: $(SERIAL_ROOT)/serial/serial_app.c $(KERNEL_ROOT)/include/rf.h $(KERNEL_ROOT)/include/task.h $(KERNEL_ROOT)/include/interface.h $(KERNEL_ROOT)/include/suota.h $(SERIAL_ROOT)/serial/packet_interface.h $(KERNEL_ROOT)/include/protocol.h
306 | $(CC) $(CFLAGS) -c $(SERIAL_ROOT)/serial/serial_app.c
307 |
308 |
309 |
310 | #
311 | # how to build standalone code without the kernel
312 | #
313 | TOBJ = test.rel leds.rel
314 | test: $(TOBJ)
315 | $(LD) $(LDFLAGS_SA) -i test $(TOBJ)
316 |
317 | test.rel: test.c
318 | $(CC) $(CFLAGS) -c test.c
319 |
320 | clean:
321 | rm -f *.rel *.map *.lst *.ihx *.asm *.mem *.sym *.lk *.rst *.o *.cdb *.adb *.omf packet_loader fixcrc *.suota *.128k *.256k
322 |
323 |
324 |
325 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | firmware
2 | ========
3 |
4 | This repository contains firmware for the OneRNG entropy generator
5 |
6 | To build this you will need a copy of the same version of the open source SDCC compiler
7 | that we use to build the system - you can find one here
8 |
9 | http://moonbaseotago.com/cheaprf/sdcc-2533.tar.gz
10 |
11 | You can find more documentation about setting up a build sustem and programming devices here:
12 |
13 | http://www.moonbaseotago.com/cheaprf/#programming
14 |
15 | The code contained in this directory is a fork of the MoonbaseOtago CheapRF code - it has
16 | had the RF and SUOTA bits removed for obvious security reasons, you can look at and download
17 | the original code in its repository here:
18 |
19 | https://github.com/MoonbaseOtago/CC-System
20 |
21 | Documentation about the minimal OS and how to use it is here:
22 |
23 | http://www.moonbaseotago.com/cheaprf/programming.html
24 |
25 | The one main difference is that the thread schedular instead of low power idling the CPU
26 | it runs the entropy gathering idle_pool() routine
27 |
28 | Files:
29 |
30 | Makefile - type 'make' to build - change SDCC_INSTALL_DIR to point to where your compiler is installed
31 | usb.c - cc2531 USB stack
32 | cdc.c - USB decsriptors - handler stubs for CDC messages
33 | cdc_app.c - main entropy gathering code (the interesting stuff is here)
34 | kernel/* - task scheuler/kernel support
35 | include/* - kernel incloude files
36 |
37 | The build system works like this:
38 |
39 | 1) build a lodable app cdc_app.ihx (intel hex format - you can just use this if you are rolling your own)
40 | 2) concatenate the memory image of the code with known random_data, truncate the result to
41 | the ROM size less room for a signing
42 | 3) sign the resulting image with our private key (not provided)
43 | 4) pad the remaining code with FFs so that the chip is not code locked (open source and binaries right?)
44 |
--------------------------------------------------------------------------------
/cdc.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "usb.h"
4 | // (c) Copyright Paul Campbell paul@taniwha.com 2013
5 | //
6 | // This library is free software; you can redistribute it and/or
7 | // modify it under the terms of the GNU Lesser General Public
8 | // License as published by the Free Software Foundation; either
9 | // version 2.1 of the License, or (at your option) version 3, or any
10 | // later version accepted by Paul Campbell , who shall
11 | // act as a proxy defined in Section 6 of version 3 of the license.
12 | //
13 | // This library is distributed in the hope that it will be useful,
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 | // Lesser General Public License for more details.
17 | //
18 | // You should have received a copy of the GNU Lesser General Public
19 | // License along with this library. If not, see .
20 | //
21 |
22 | extern void wake_5();
23 | const unsigned char __code descs[] = {
24 | //deviceDesc: ; Device descriptor
25 | 18,
26 | DESC_TYPE_DEVICE, // bDescriptorType
27 | 0, 2, // bcdUSB
28 | 2, // bDeviceClass
29 | 0, // bDeviceSubClass
30 | 0, // bDeviceProtocol
31 | EP0_PACKET_SIZE,
32 | //0x51, 4, // idVendor Texas Instruments
33 | //0xA8, 0x16, // idProduct CC2531
34 | 0x50, 0x1d, // openmoko
35 | 0x86, 0x60,
36 | 9, 0, // bcdDevice
37 | 1, // iManufacturer
38 | 3, // iProduct
39 | 3, // iSerialNumber
40 | 1, // bNumConfigurations
41 |
42 |
43 | //configDesc: ; Configuration descriptor
44 | 9,
45 | DESC_TYPE_CONFIG,// bDescriptorType
46 | 0x43, 0,
47 | 2, // NumInterfaces
48 | 1, // bConfigurationValue
49 | 0, // iConfiguration
50 | 0x80, // bmAttributes
51 | 100, // MaxPower
52 | //
53 | // INTERFACE 0 //
54 | //
55 |
56 |
57 | //interface0Desc: ; Interface descriptor
58 | 9,
59 | DESC_TYPE_INTERFACE, // bDescriptorType
60 | 0, // bInterfaceNumber
61 | 0, // bAlternateSetting
62 | 1, // bNumEndpoints
63 | COMM_INTF, // bInterfaceClass
64 | ABSTRACT_CONTROL_MODEL, // bInterfaceSubClass
65 | V25TER, // bInterfaceProcotol
66 | 0, // iInterface
67 |
68 | // CDC Class-Specific Descriptors
69 | //headerFunctionalDesc: ; Header Functional Descriptor
70 | 5,
71 | CS_INTERFACE,
72 | DSC_FN_HEADER,
73 | 0x10, 0x1,
74 | //absCtrlManFuncDesc: ; Abstract Control Management Functional Descriptor
75 | 4,
76 | CS_INTERFACE,
77 | DSC_FN_ACM,
78 | 0x6,
79 | //unionFunctionalDesc: ; Union Functional Descriptor
80 | 5,
81 | CS_INTERFACE,
82 | DSC_FN_UNION,
83 | 0,
84 | 1,
85 | //callMngFuncDesc: ; Call Management Functional Descriptor
86 | 5,
87 | CS_INTERFACE,
88 | DSC_FN_CALL_MGT,
89 | 0,
90 | 1,
91 |
92 | //endpoint0Desc: ; Endpoint descriptor (EP2 IN)
93 | 7,
94 | DESC_TYPE_ENDPOINT, // bDescriptorType
95 | 0x82, // bEndpointAddress
96 | EP_ATTR_INT, // bmAttributes
97 | 0x20, 0, // wMaxPacketSize
98 | 0x40, // bInterval
99 |
100 | //
101 | // INTERFACE 1 - EP 5 - random
102 | //
103 |
104 | //interface1Desc: ; Interface descriptor
105 | 9,
106 | DESC_TYPE_INTERFACE, // Interface descriptor type
107 | 1, // Interface Number
108 | 0, // Alternate Setting Number
109 | 2, // Number of endpoints in this intf
110 | DATA_INTF, // Class code
111 | 0, // Subclass code
112 | NO_PROTOCOL, // Protocol code
113 | 4, // Interface string index
114 |
115 |
116 | //endpoint1Desc: ; Endpoint descriptor (EP5 OUT)
117 | 7,
118 | DESC_TYPE_ENDPOINT, // bDescriptorType
119 | 0x85, // bEndpointAddress
120 | EP_ATTR_BULK, // bmAttributes
121 | 64, 0, // wMaxPacketSize
122 | 1, // bInterval
123 |
124 | //endpoint2Desc: ; Endpoint descriptor (EP5 IN)
125 | 7,
126 | DESC_TYPE_ENDPOINT, // bDescriptorType
127 | 5, // bEndpointAddress
128 | EP_ATTR_BULK, // bmAttributes
129 | 64, 0, // wMaxPacketSize
130 | 1, // bInterval
131 |
132 |
133 | //--------------
134 | // String descriptors
135 | //string0Desc: ; Language ID
136 | 4,
137 | DESC_TYPE_STRING, // bDescriptorType
138 | 9, // US-EN
139 | 4,
140 |
141 | //string1Desc: ; Manufacturer
142 | 102,
143 | DESC_TYPE_STRING, // bDescriptorType
144 | 'M', 0,
145 | 'o', 0,
146 | 'o', 0,
147 | 'n', 0,
148 | 'b', 0,
149 | 'a', 0,
150 | 's', 0,
151 | 'e', 0,
152 | ' ', 0,
153 | 'O', 0,
154 | 't', 0,
155 | 'a', 0,
156 | 'g', 0,
157 | 'o', 0,
158 | ' ', 0,
159 | 'h', 0,
160 | 't', 0,
161 | 't', 0,
162 | 'p', 0,
163 | ':', 0,
164 | '/', 0,
165 | '/', 0,
166 | 'w', 0,
167 | 'w', 0,
168 | 'w', 0,
169 | '.', 0,
170 | 'm', 0,
171 | 'o', 0,
172 | 'o', 0,
173 | 'n', 0,
174 | 'b', 0,
175 | 'a', 0,
176 | 's', 0,
177 | 'e', 0,
178 | 'o', 0,
179 | 't', 0,
180 | 'a', 0,
181 | 'g', 0,
182 | 'o', 0,
183 | '.', 0,
184 | 'c', 0,
185 | 'o', 0,
186 | 'm', 0,
187 | '/', 0,
188 | 'r', 0,
189 | 'a', 0,
190 | 'n', 0,
191 | 'd', 0,
192 | 'o', 0,
193 | 'm', 0,
194 |
195 | //string2Desc: ; Product
196 | 70,
197 | DESC_TYPE_STRING, // bDescriptorType
198 | 'C', 0,
199 | 'C', 0,
200 | '2', 0,
201 | '5', 0,
202 | '3', 0,
203 | '1', 0,
204 | ' ', 0,
205 | 'U', 0,
206 | 'S', 0,
207 | 'B', 0,
208 | ' ', 0,
209 | 'R', 0,
210 | 'a', 0,
211 | 'n', 0,
212 | 'd', 0,
213 | 'o', 0,
214 | 'm', 0,
215 | ' ', 0,
216 | 'N', 0,
217 | 'u', 0,
218 | 'm', 0,
219 | 'b', 0,
220 | 'e', 0,
221 | 'r', 0,
222 | ' ', 0,
223 | 'G', 0,
224 | 'e', 0,
225 | 'n', 0,
226 | 'e', 0,
227 | 'r', 0,
228 | 'a', 0,
229 | 't', 0,
230 | 'o', 0,
231 | 'r', 0,
232 |
233 | //string3Desc: ; Serial number
234 | 6,
235 | DESC_TYPE_STRING, // bDescriptorType
236 | '0', 0,
237 | '0', 0,
238 |
239 | //string4Desc: ; interface 1 - "random"
240 | 14,
241 | DESC_TYPE_STRING, // bDescriptorType
242 | 'R', 0,
243 | 'a', 0,
244 | 'n', 0,
245 | 'd', 0,
246 | 'o', 0,
247 | 'm', 0,
248 |
249 | 0 // 0 len is end tag
250 | };
251 |
252 | struct lc __xdata line_config;
253 | static struct lc __xdata line_config_alt;
254 | __bit cdcRTS;
255 |
256 | void class_out(void)
257 | {
258 | if (setup_header.request == CDC_SET_CONTROL_LINE_STATE) { // 0x22
259 | if(ep0Status == EP_IDLE) {
260 | unsigned char ep = setup_header.index&0x1f;
261 | unsigned char v = setup_header.value&1;
262 | cdcRTS = v;
263 | usb_can_send_5();
264 | ep0Status = EP_RX;
265 | }
266 | } else
267 | if (setup_header.request == CDC_SET_LINE_CODING) {
268 | if(ep0Status == EP_IDLE) {
269 | unsigned char ep = setup_header.index&0x1f;
270 | if (ep == 0) {
271 | pData = (unsigned char __xdata *) &line_config;
272 | } else {
273 | pData = (unsigned char __xdata *) &line_config_alt;
274 | }
275 |
276 | ep0Status = EP_RX;
277 | } else
278 | if (ep0Status == EP_RX) {
279 | unsigned char ep = setup_header.index&0x1f;
280 | if (ep == 0)
281 | change_uart_mode();
282 | }
283 | } else {
284 | ep0Status = EP_STALL;
285 | }
286 | }
287 |
288 | void class_in(void)
289 | {
290 | if (setup_header.request == CDC_GET_LINE_CODING) {
291 | if (ep0Status == EP_IDLE) {
292 | unsigned char ep = setup_header.index;
293 | if (ep == 0) {
294 | pData = (unsigned char __xdata *) &line_config;
295 | } else {
296 | pData = (unsigned char __xdata *) &line_config_alt;
297 | }
298 | bytes_left = 7;
299 | ep0Status = EP_TX;
300 | } else
301 | if (ep0Status == EP_TX) {
302 | }
303 | } else {
304 | ep0Status = EP_STALL;
305 | }
306 | }
307 |
308 | void cdc_init(unsigned long baudrate)
309 | {
310 | // Set default line coding.
311 | line_config.baudRate = baudrate;
312 | line_config.charFormat = CDC_CHAR_FORMAT_1_STOP_BIT;
313 | line_config.parityType = CDC_PARITY_TYPE_NONE;
314 | line_config.dataBits = 8;
315 | cdcRTS = 0;
316 |
317 | // Initialise hardware flow control
318 | // Initialize the USB interrupt handler with bit mask containing all processed USBIRQ events
319 | usb_init();
320 |
321 | P1DIR |= 1<<0;
322 | P1INP |= 1<<0;
323 | P1_0 = 1;
324 | }
325 |
326 |
--------------------------------------------------------------------------------
/cdc_app.c:
--------------------------------------------------------------------------------
1 | #define VERSION 3
2 | __code char version[] = "\r\nVersion 3\r\n";
3 | // (c) Copyright Paul Campbell paul@taniwha.com 2013, 2014, 2015
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) version 3, or any
9 | // later version accepted by Paul Campbell , who shall
10 | // act as a proxy defined in Section 6 of version 3 of the license.
11 | //
12 | // This library is distributed in the hope that it will be useful,
13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | // Lesser General Public License for more details.
16 | //
17 | // You should have received a copy of the GNU Lesser General Public
18 | // License along with this library. If not, see .
19 | //
20 |
21 | #define NORM_LED 1 // disable when debugging
22 |
23 | #include
24 | #include
25 | #include "interface.h"
26 | #include "string.h"
27 | #include "packet_interface.h"
28 | #include "usb.h"
29 |
30 | #define RX_SIZE 250
31 | #define TX_SIZE 250
32 |
33 | extern __xdata task manufacturing_task; // manufacturing task;
34 |
35 | //
36 | // UART access USB<->uart
37 | //
38 |
39 | unsigned char __xdata pool[POOL_SIZE];
40 | __xdata unsigned char *__data pool_in = &pool[0];
41 | __xdata unsigned char *__data pool_out = &pool[0];
42 | __xdata unsigned char *__data pool_update = &pool[0];
43 | unsigned int __data pool_count=0;
44 | __bit pool_busy=0;
45 | __bit no_crc=0;
46 | __bit no_avalanche=0;
47 | __bit rf_source=0;
48 | __bit rf_running=0;
49 | __bit dumping=0;
50 | __bit versioning=0;
51 | __bit secret=0;
52 | __bit IDing=0;
53 | __bit alt_action=0;
54 | __bit in_odd=0;
55 | unsigned char sv;
56 | extern void start_encrypt();
57 | extern void send_id_block();
58 | extern void encrypt_random_block();
59 | extern void encrypt_token();
60 | extern void encrypt_secret_blocks();
61 | extern void sync_header();
62 | extern unsigned char __xdata token[];
63 |
64 | static unsigned char __pdata time_rf_dwell = 0;
65 | unsigned char __data vind;
66 | #define MAX_00_S 8
67 | #define MAX_FF_S 8
68 |
69 | unsigned char __data num_zeros=0;
70 | unsigned char __data num_ffs=0;
71 | unsigned char __data error_state=0;
72 | unsigned char __data dump_state;
73 | unsigned int __data dump_addr;
74 | unsigned char __data dump_page;
75 |
76 | extern __bit cdcRTS;
77 | __bit pause=1;
78 | extern unsigned char __data eventMaskIn;
79 | extern unsigned char __data eventMaskOut;
80 |
81 | static void pool_rcv_thread(task __xdata*t);
82 | static __xdata task pool_rcv_task = {pool_rcv_thread,0,0,0};
83 |
84 | static void pool_cmd_thread(task __xdata*t);
85 | static __xdata task pool_cmd_task = {pool_cmd_thread,0,0,0};
86 |
87 | static void error_thread(task __xdata*t);
88 | static __xdata task error_task = {error_thread,0,0,0};
89 |
90 | static void rf_thread(task __xdata*t);
91 | static __xdata task rf_task = {rf_thread,0,0,0};
92 |
93 | __bit flv=0;
94 | __bit flash=0;
95 | static void flash_thread(task __xdata*t);
96 | static __xdata task flash_task = {flash_thread,0,0,0};
97 | void flash_thread(task __xdata*t)
98 | {
99 | if (!flash)
100 | return;
101 | P1_1 = flv; // we use this to signal that the USB is working
102 | flv = !flv; // during manufacturing tests
103 | queue_task(&flash_task, HZ/4);
104 | }
105 |
106 | static void
107 | cpl() __naked
108 | {
109 | __asm;
110 | cpl p1.1
111 | ret
112 | __endasm;
113 | }
114 |
115 | static void
116 | error_thread(task __xdata*t)
117 | {
118 | if (num_zeros == MAX_00_S) {
119 | if (error_state == 1) { // too many 00s? flash 1 on 3 off - stuck at 0
120 | #ifdef NORM_LED
121 | P1_1 = 0;
122 | #endif
123 | error_state = 0;
124 | queue_task(&error_task, 3*HZ);
125 | } else {
126 | P1_1 = 1;
127 | error_state = 1;
128 | queue_task(&error_task, 1*HZ);
129 | }
130 | } else
131 | if (num_ffs == MAX_FF_S) { // too many FFs? flash 1 on 1 off 1 on 3 off - stuck at 1
132 | if (error_state >= 3) {
133 | #ifdef NORM_LED
134 | P1_1 = 0;
135 | #endif
136 | error_state = 0;
137 | queue_task(&error_task, 3*HZ);
138 | } else
139 | if (error_state == 1) {
140 | #ifdef NORM_LED
141 | P1_1 = 0;
142 | #endif
143 | error_state = 2;
144 | queue_task(&error_task, 1*HZ);
145 | } else {
146 | #ifdef NORM_LED
147 | P1_1 = 1;
148 | #endif
149 | error_state++;
150 | queue_task(&error_task, 1*HZ);
151 | }
152 | } else {
153 | error_state = 0; // normal state - just poll for an error state
154 | // P1_1 = pool_busy;
155 | queue_task(&error_task, 1*HZ);
156 | }
157 | }
158 |
159 | void
160 | queue_pool_data(unsigned char x) __naked
161 | {
162 | __asm;
163 | mov _RNDH, dpl // RNDH = x; // through the crc16
164 | jb _no_crc, 0200$ // if (!no_crc) { // whiten the data
165 | mov dpl, _RNDH // x = RNDH; // hardware
166 | // }
167 | 0200$: clr EA
168 | mov a, _pool_count // if (pool_count == POOL_SIZE) {
169 | cjne a, #POOL_SIZE, 0001$
170 | mov a, _pool_count+1
171 | cjne a, #POOL_SIZE>>8, 0001$ // // the pool is full, keep stiring it
172 | mov r0, dpl
173 | mov dpl, _pool_update // *pool_update++ ^= x;
174 | mov dph, _pool_update+1
175 | movx a, @dptr
176 | xrl a, r0
177 | movx @dptr, a
178 | inc dptr
179 | mov a, dpl
180 | cjne a, #_pool+POOL_SIZE, 0002$// if (pool_update == &pool[POOL_SIZE])
181 | mov a, dph // pool_update = &pool[0];
182 | cjne a, #(_pool+POOL_SIZE)>>8, 0002$
183 | mov dptr, #_pool
184 | 0002$: mov _pool_update, dpl
185 | mov _pool_update+1, dph
186 | setb EA
187 | ret
188 |
189 | 0001$: // } else {
190 | mov a, dpl
191 | mov dpl, _pool_in // *pool_in++ = x;
192 | mov dph, _pool_in+1
193 | movx @dptr, a
194 | inc dptr
195 | mov a, dpl // if (pool_in == &pool[POOL_SIZE])
196 | cjne a, #_pool+POOL_SIZE, 0003$// pool_in = &pool[0];
197 | mov a, dph
198 | cjne a, #(_pool+POOL_SIZE)>>8, 0003$
199 | mov dptr, #_pool
200 | 0003$: mov _pool_in, dpl
201 | mov _pool_in+1, dph
202 | inc _pool_count // pool_count++;
203 | mov a, _pool_count
204 | jnz 0004$
205 | inc _pool_count+1
206 | 0004$:
207 | jb _pool_busy, 0005$ // if (!pool_busy && pool_count > 64) {
208 | mov a, _pool_count+1
209 | jnz 0007$
210 | mov a, _pool_count
211 | jb a.7, 0007$
212 | jnb a.6, 0005$
213 | 0007$:
214 | setb _pool_busy // pool_busy = 1;
215 | #ifdef NORM_LED
216 | setb p1.1 // p1.1 = 1;
217 | #endif
218 | mov dptr, #_pool_rcv_task// queue_task(&pool_rcv_task, 0_'
219 | lcall _queue_task_0
220 | 0005$: // }
221 | setb EA // }
222 | ret
223 | __endasm;
224 | }
225 |
226 | void
227 | idle_pool() __naked
228 | {
229 | __asm; // for (;; ) {
230 | 0001$: jb _no_avalanche, 0200$ // if (!no_avalanche) {
231 | mov r0, #8 // for (i = 0; i < 8 i++)
232 | 0003$: mov c, p1.7 // v = (v<<1)|p1.7;
233 | rlc a
234 | djnz r0, 0003$
235 | mov r1, a // r1 = v;
236 | mov r0, #8 // for (i = 0; i < 8 i++)
237 | 0033$: mov c, p1.7 // v = (v<<1)|p1.7;
238 | rlc a
239 | djnz r0, 0033$
240 | xrl a, r1 // v = v^r1;
241 | mov dpl, a
242 | jnz 0300$ // if (v == 0) {
243 | mov _num_ffs, #0 // num_ffs = 0;
244 | mov a, _num_zeros // if (num_zeros == MAX_00_S)
245 | cjne a, #MAX_00_S, 0310$ // goto retry
246 | sjmp 0200$
247 | 0310$: inc _num_zeros // num_zeros++;
248 | sjmp 0302$ // } else
249 | 0300$: cjne a, #0xff, 0301$ // if (v == 0xff) {
250 | mov _num_zeros, #0 // num_zeros = 0;
251 | mov a, _num_ffs // if (num_ffs == MAX_FF_S)
252 | cjne a, #MAX_FF_S, 0311$ // goto retry;
253 | sjmp 0200$
254 |
255 | 0311$: inc _num_ffs // num_ffs++;
256 | sjmp 0302$ // } else {
257 |
258 | 0301$: mov _num_zeros, #0 // num_zeros = 0;
259 | mov _num_ffs, #0 // num_ffs = 0;
260 | 0302$: // }
261 | mov a, _enter_sleep_mod_flag // if (enter_sleep_mod_flag) break;
262 | jz 0002$
263 | lcall _queue_pool_data // queue_pool_data(v);
264 | 0200$: mov a, _enter_sleep_mod_flag //retry: if (enter_sleep_mod_flag) break;
265 | jz 0002$
266 | // }
267 | jnb _rf_running, 0001$ // if (rf_running) {
268 |
269 |
270 | mov a, _enter_sleep_mod_flag //retry: if (enter_sleep_mod_flag) break;
271 | jz 0002$
272 | mov r0, #8 // for (i = 0; i < 8;i++)
273 | mov dptr, #_RFRND
274 | mov r2, #0
275 | 0500$: movx a, @dptr // v = (v<<1)|RFRND&1;
276 |
277 | mov c, a.0 // - note must wait 8 clocks between samples
278 | mov a, r2
279 | rlc a
280 | mov r2, a
281 | nop
282 | djnz r0, 0500$
283 | mov dpl, r2
284 | mov a, _enter_sleep_mod_flag// if (enter_sleep_mod_flag) break;
285 | jz 0002$
286 | lcall _queue_pool_data // queue_pool_data(v);
287 | // }
288 | 0201$: mov a, _enter_sleep_mod_flag // if (enter_sleep_mod_flag) break;
289 | jz 0002$
290 | ljmp 0001$
291 | 0002$: // }
292 | ret
293 | __endasm;
294 | }
295 |
296 | static unsigned char
297 | get_5(void) __naked
298 | {
299 | __asm;
300 | mov dptr, #_USBF5
301 | movx a, @dptr
302 | mov dpl, a
303 | ret
304 | __endasm;
305 | }
306 |
307 | static unsigned char __data in_state=0;
308 |
309 | static void
310 | pool_cmd_thread(task __xdata*t) // woken when uart buffers have room new data or USB has data to send
311 | {
312 | for (;;) {
313 | unsigned char c, a;
314 | unsigned char x;
315 | unsigned char x2;
316 |
317 | EA=0;
318 | c = USBINDEX;
319 | USBINDEX = 5;
320 | if (!(USBCSOL&USBCSOL_OUTPKT_RDY)) {
321 | USBINDEX = c;
322 | EA=1;
323 | return;
324 | }
325 | x = USBCNTL;
326 | x2 = USBCNTH;
327 | a = get_5(); // get a character in from USBA
328 | if (in_state == 0) {
329 | if (a == 'c')
330 | in_state=1;
331 | } else
332 | if (in_state == 1) {
333 | if (a == 'm') {
334 | in_state=2;
335 | } else {
336 | in_state=0;
337 | }
338 | } else
339 | if (in_state == 2) {
340 | if (a == 'd') {
341 | in_state=3;
342 | } else {
343 | in_state=0;
344 | }
345 | } else
346 | if (in_state == 3) {
347 | in_state=0;
348 | if (a >= '0' && a <= '9') {
349 | a -= '0';
350 | set: // a is 4 bit mask
351 | // - bit 0 - disables CRC whitening
352 | // - bit 1 - enables RF source
353 | // - bit 2 - disables avalanche source
354 | if (a&1) {
355 | no_crc = 1;
356 | } else {
357 | no_crc = 0;
358 | }
359 | if (a&2) {
360 | if (!rf_source) {
361 | rf_source = 1;
362 | time_rf_dwell = 0;
363 | cancel_task(&rf_task);
364 | queue_task(&rf_task, 0);
365 | }
366 | } else {
367 | rf_source = 0;
368 | rf_running = 0;
369 | RFST = 0xef;
370 | RFST = 0xec;
371 | }
372 | if (a&4) {
373 | no_avalanche = 1;
374 | } else {
375 | no_avalanche = 0;
376 | }
377 | } else
378 | if (a >= 'a' && a <= 'f') {
379 | a = a-'a'+10;
380 | goto set;
381 | } else
382 | if (a >= 'A' && a <= 'F') {
383 | a = a-'A'+10;
384 | goto set;
385 | } else
386 | if (a == 'X') {
387 | alt_action = 1;
388 | dumping = 1;
389 | dump_state = 0;
390 | dump_addr = 0x8000;
391 | dump_page = 0;
392 | } else
393 | if (a == 'O') {
394 | pause = 0; // run
395 | queue_task_0(&pool_rcv_task);
396 |
397 | } else
398 | if (a == 'v') {
399 | vind = 0; // version
400 | versioning = 1;
401 | alt_action = 1;
402 | } else
403 | if (a == 'I') {
404 | vind = 0; // extract ID
405 | IDing = 1;
406 | alt_action = 1;
407 | } else
408 | if (a == 'S') {
409 | in_state = 10;
410 | in_odd = 0;
411 | } else
412 | if (a == 'o') {
413 | pause = 1; // pause
414 | } else
415 | if (a == 'T') { // flash for testing - flashes the LED during manufacturing when we're testing the USN
416 | flash = !flash;
417 | if (flash) {
418 | flv = 0;
419 | queue_task(&flash_task, 0);
420 | } else {
421 | cancel_task(&flash_task);
422 | }
423 | } else
424 | if (a == 'w') { // flush
425 | pool_in = &pool[0];
426 | pool_out = &pool[0];
427 | pool_update = &pool[0];
428 | pool_count=0;
429 | pool_busy=0;
430 | }
431 | } else
432 | if (in_state >= 10 && in_state < 26) { // suck in token
433 | if (a >= '0' && a <= '9') {
434 | a = a-'0';
435 | } else
436 | if (a >= 'A' && a <= 'F') {
437 | a = a-'A';
438 | a = a+10;
439 | } else
440 | if (a >= 'a' && a <= 'f') {
441 | a = a-'a';
442 | a = a+10;
443 | } else {
444 | goto bad;
445 | }
446 | if (!in_odd) {
447 | sv = a<<4;
448 | in_odd = 1;
449 | } else {
450 | token[in_state-10] = sv|a;
451 | in_odd = 0;
452 | in_state++;
453 | }
454 | if (in_state == 26) {
455 | vind = 0; // encrypt secret
456 | secret = 1;
457 | alt_action = 1;
458 | in_state =0;
459 | }
460 | } else {
461 | bad: in_state = 0;
462 | }
463 | if (x==1 && !x2) {
464 | USBINDEX = 5;
465 | USBCSOL = 0;
466 | }
467 | USBINDEX = c;
468 | EA=1;
469 | }
470 | }
471 |
472 |
473 |
474 | static void
475 | pool_rcv_thread(task __xdata*t) __naked // woken when pool has new data or USB can send data
476 | {
477 | __asm;
478 | mov _DPS, #0
479 | 0001$: // for (;;) {
480 | // unsigned int len;
481 | // unsigned char ep, xlen;
482 | mov a, _eventMaskIn // if (eventMaskIn&USBIIE_EP0IE)
483 | jb a.0, 0020$ // break;
484 | mov a, _eventMaskOut
485 | jb a.5, 0020$ // if (eventMaskOut&USBOIE_OUTEP5IE)
486 | // break
487 | jb _pause, 0020$ // if (pause)
488 | // return;
489 | jnb _cdcRTS, 0020$ // if (!cdcRTS)
490 | // return;
491 | clr EA // EA = 0;
492 | jb _alt_action, 0002$ // if (alt_action) goto do_xtra;
493 | mov a, _pool_count+1 // if (pool_count < 64) {
494 | jnz 0002$
495 | mov a, _pool_count
496 | jb a.7, 0002$
497 | jb a.6, 0002$
498 | #ifdef NORM_LED
499 | clr p1.1
500 | #endif
501 | clr _pool_busy // pool_busy = 0;
502 | setb EA // EA = 1;
503 | 0020$: ret // return;
504 | 0555$:
505 | ljmp 0510$ // }
506 |
507 | 0002$:
508 | mov dptr, #_USBINDEX // ep = USBINDEX;
509 | movx a, @dptr
510 | mov r7, a
511 | mov a, #5 // USBINDEX = 5;
512 | movx @dptr, a
513 | mov dptr, #_USBCSIL // if (USBCSIL&USBCSIL_INPKT_RDY) {
514 | movx a, @dptr
515 | jnb a.0, 0003$
516 | mov dptr, #_USBINDEX// USBINDEX = ep;
517 | mov a, r7
518 | movx @dptr, a
519 | mov a, _eventMaskIn // eventMaskIn &= ~USBIIE_INEP5IE;
520 | clr a.5
521 | mov _eventMaskIn, a
522 | setb EA // EA = 1;
523 | ret // return;
524 | // }
525 | 1201$: ljmp 1200$
526 | 6002$: jnb _secret, 4202$ // if (secret) goto do_secret;
527 | ljmp 5202$
528 | 4202$: jnb _IDing, 4201$ // if (IDing) goto do_id;
529 | ljmp 5201$
530 | 4201$: jb _versioning, 1201$ // if (versioning) goto do_version;
531 | jnb _dumping, 1555$ // if (dumping) goto do_dump;
532 | ljmp 0555$
533 | 1555$: clr _alt_action // alt_action = 0;
534 |
535 | 0003$: jb _alt_action, 6002$ //
536 | mov r2, #64 // len = 64;
537 | clr c
538 | mov a, _pool_count // pool_count -= 64;
539 | subb a, r2
540 | mov _pool_count, a
541 | mov a, _pool_count+1
542 | subb a, #0
543 | mov _pool_count+1, a
544 | mov _DPL1, #_USBF5 // // usb_write_fifo_5(pool_out, len);
545 | mov _DPH1, #_USBF5>>8
546 | mov dpl, _pool_out // for (i = 0;i < 64; i++) {
547 | mov dph, _pool_out+1
548 | 0010$: movx a, @dptr // *USBF5 = *pool_out;
549 | inc _DPS
550 | movx @dptr, a
551 | dec _DPS
552 | clr a // *pool_out++ = 0; // delete data once it's sent
553 | movx @dptr, a
554 | inc dptr
555 | mov a, dpl // if (pool_out == &pool[POOL_SIZE])
556 | cjne a, #_pool+POOL_SIZE, 0011$
557 | mov a, dph // pool_out = &pool[0];
558 | cjne a, #(_pool+POOL_SIZE)>>8, 0011$
559 | mov dptr, #_pool
560 | 0011$: djnz r2, 0010$ // }
561 | mov _pool_out, dpl
562 | mov _pool_out+1, dph
563 |
564 | 0501$: //send_usb:
565 | mov dptr, #_USBINDEX // USBINDEX = 5;
566 | mov a, #5
567 | movx @dptr, a
568 | mov a, #USBCSIL_INPKT_RDY // USBCSIL = USBCSIL_INPKT_RDY;
569 | mov dptr, #_USBCSIL
570 | movx @dptr, a
571 | mov dptr, #_USBINDEX // USBINDEX = ep;
572 | mov a, r7
573 | movx @dptr, a
574 | setb EA // EA = 1;
575 | ljmp 0001$ // }
576 |
577 | //
578 | // code to push rom image
579 | //
580 | // looks like:
581 | // fe ed be ef 20 14 - magic number
582 | // 00 00 04 - len (little endian)
583 | // 00 00 - version (little endian)
584 | // image - len bytes of image
585 | //
586 | 0510$:
587 | clr _DPS
588 | mov _DPL1, #_USBF5
589 | mov _DPH1, #_USBF5>>8
590 | mov r2, #64 // for (i = 0; i < 64; i++) {
591 |
592 | 0500$:
593 | mov a, _dump_state // switch (dump_state) {
594 | cjne a, #13, 0575$ // case 13:
595 | mov a, _dump_page // v = *{dump_page,dump_addr};
596 | mov _FMAP, a
597 | mov dpl, _dump_addr
598 | mov dph, _dump_addr+1
599 | clr a
600 | movc a, @a+dptr
601 | mov r0, a
602 | inc dptr // dump_addr++;
603 | mov _dump_addr, dpl
604 | mov a, dph
605 | mov _dump_addr+1, a // if (dump_addr == 0) {
606 |
607 |
608 | jnz 0570$
609 | mov _dump_addr+1, #0x80 // dump_addr = 0x800;
610 | inc _dump_page // dump_page++;
611 | sjmp 0572$ // }
612 | 0570$: cjne a, #0xff, 0572$ // if (address == last 128 bytes) // hide the 'secret'
613 | mov r3, dpl
614 | cjne r3, #0x80, 0572$
615 | mov r3, _dump_page
616 | cjne r3, #0x7, 0572$
617 | inc _dump_state // last bytes dump_state++
618 | //
619 | 0572$: mov a, r0 // break;
620 |
621 | 0700$: inc _DPS // // at end of case statement
622 | movx @dptr, a // *USBF5 = v;
623 | dec _DPS
624 | djnz r2, 0500$
625 | ljmp 0501$ // goto send_usb;
626 |
627 | 0575$: cjne a, #14, 0600$ // case 14:
628 | mov dpl, _dump_addr // v = 0xff // for secret area
629 | mov dph, _dump_addr+1
630 | mov r0, #0xff
631 | inc dptr // dump_addr++;
632 | mov _dump_addr, dpl
633 | mov a, dph
634 | mov _dump_addr+1, a // if (dump_addr == 0)
635 | jnz 0572$
636 | inc _dump_state // last byte dump_state++
637 | sjmp 0572$
638 |
639 | 0600$: inc _dump_state // case 0: dump_state++;
640 | cjne a, #0, 0601$
641 | mov a, #0xfe // v = 0xfe;
642 | sjmp 0700$ // break;
643 | 0601$: cjne a, #1, 0602$ // case 1: dump_state++;
644 | mov a, #0xed // v = 0xed;
645 | sjmp 0700$ // break;
646 | 0602$: cjne a, #2, 0603$ // case 2: dump_state++;
647 | mov a, #0xbe // v = 0xbe;
648 | sjmp 0700$ // break;
649 | 0603$: cjne a, #3, 0604$ // case 3: dump_state++;
650 | mov a, #0xef // v = 0xef;
651 | sjmp 0700$ // break;
652 | 0604$: cjne a, #4, 0605$ // case 4: dump_state++;
653 | mov a, #0x20 // v = 0x20;
654 | sjmp 0700$ // break;
655 | 0605$: cjne a, #5, 0606$ // case 5: dump_state++;
656 | mov a, #0x14 // v = 0x14;
657 | sjmp 0700$ // break;
658 | 0606$: cjne a, #6, 0607$ // case 6: dump_state++;
659 | mov a, #0x00 // v = 0x00;
660 | sjmp 0700$ // break;
661 | 0607$: cjne a, #7, 0608$ // case 7: dump_state++;
662 | mov a, #0x00 // v = 0x00;
663 | sjmp 0700$ // break;
664 | 0608$: cjne a, #8, 0609$ // case 8: dump_state++;
665 | mov a, #0x04 // v = 0x04;
666 | sjmp 0700$ // break;
667 | 0609$: cjne a, #9, 0610$ // case 9: dump_state++;
668 | mov a, #VERSION // v = VERSION;
669 | sjmp 0700$ // break;
670 | 0610$: cjne a, #10, 0611$ // case 10: dump_state++;
671 | mov a, #VERSION>>8 // v = VERSION>>8;
672 | ljmp 0700$ // break;
673 | 0611$: cjne a, #11, 0612$ // case 11: dump_state++;
674 | .globl s_CODE
675 | .globl l_CODE
676 | mov a, #s_CODE
677 | add a, #l_CODE // v = text size;
678 | ljmp 0700$ // break;
679 | 0612$: cjne a, #12, 0613$ // case 12: dump_state++;
680 | mov a, #s_CODE
681 | add a, #l_CODE
682 | mov a, #s_CODE>>8
683 | addc a, #l_CODE>>8 // v = (text size)>>8;
684 | ljmp 0700$ // break;
685 |
686 | 0613$: clr _dumping // default:dumping = 0;
687 | ljmp 0501$ // goto send_usb;
688 | // }
689 | // do_version
690 | 1200$:
691 | clr _DPS
692 | mov _DPL1, #_USBF5
693 | mov _DPH1, #_USBF5>>8
694 | mov dptr, #_version
695 | 1203$: // for (;;) {
696 | mov a, _vind // v = version[vind++];
697 | inc _vind //
698 | movc a, @a+dptr //
699 | jz 1202$ // if (!v)
700 | // break;
701 | inc _DPS //
702 | movx @dptr, a // *USBF5 = v;
703 | dec _DPS
704 | sjmp 1203$ // }
705 | 1202$:
706 | clr _versioning
707 | ljmp 0501$ // goto send_usb;
708 | 5201$: mov a, _vind // do_id: switch (vind) {
709 | jnz 5705$ // case 0:
710 | inc _vind // vind = 1;
711 | lcall _crlf // crlf()
712 | lcall _sync_header// sync_header()
713 | ajmp 0501$ // break;
714 | 5705$: cjne a, #1, 5215$
715 | inc _vind // case 1: vind = 2;
716 | lcall _send_id_block // send_id_block(); // load block
717 | ajmp 0501$ // break;
718 | 5215$: lcall _sync_header// default:sync_header()
719 | lcall _crlf // crlf()
720 | clr _IDing // IDing = 0;
721 | // }
722 | ajmp 0501$ // goto do_usb; // send blocks
723 |
724 | 5202$: mov a, _vind // do_secret: switch (vind) {
725 | jnz 5207$ // case 0:
726 | inc _vind // vind = 1;
727 | lcall _crlf // crlf()
728 | lcall _sync_header// sync_header()
729 | ajmp 0501$ // break;
730 | 5207$: cjne a, #1, 5206$ // case 1:
731 | inc _vind // vind = 2;
732 | lcall _start_encrypt// start_encrypt();
733 | lcall _encrypt_random_block// encrypt_random_block();
734 | ajmp 0501$ // break;
735 | 5206$: cjne a, #2, 5203$ // case 2:
736 | inc _vind // vind = 3;
737 | lcall _encrypt_token// encrypt_token();
738 | ajmp 0501$ // break;
739 | 5203$: cjne a, #3, 5204$ // case 3:
740 | inc _vind // vind = 4;
741 | lcall _sync_header// sync_header()
742 | ajmp 0501$ // break;
743 | 5204$: cjne a, #4, 5205$ // case 4:
744 | inc _vind // vind = 5;
745 | mov dptr, #0xff80+32
746 | lcall _encrypt_secret_blocks// encrypt_secret_blocks(&secret[32]);
747 | ajmp 0501$ // break;
748 | 5205$: cjne a, #5, 5214$ // case 5:
749 | inc _vind // vind = 6;
750 | mov dptr, #0xff80+64 //
751 | lcall _encrypt_secret_blocks// encrypt_secret_blocks(&secret[32]);
752 | ajmp 0501$ // break;
753 | 5214$: clr _secret // default:secret = 0;
754 | lcall _sync_header// sync_header()
755 | lcall _crlf // crlf()
756 | ajmp 0501$ // }
757 | // goto do_usb; // send blocks
758 | __endasm;
759 | }
760 |
761 |
762 | void
763 | usb_can_send_5()
764 | {
765 | queue_task(&pool_rcv_task, 0);
766 | }
767 |
768 | void
769 | flush_in_5()
770 | {
771 | }
772 |
773 | void
774 | usb_has_data_5()
775 | {
776 | queue_task(&pool_cmd_task, 0);
777 | }
778 |
779 | static void
780 | uart_setup()
781 | {
782 | EA = 0;
783 | cdc_init(9600);
784 | EA = 1;
785 | }
786 |
787 | void
788 | change_uart_mode()
789 | {
790 | }
791 |
792 |
793 | static void rf_thread(task __xdata*t)
794 | {
795 | if (!rf_source) { // idle .... poll
796 | queue_task(&rf_task, HZ/5);
797 | rf_running = 0;
798 | time_rf_dwell = 0;
799 | return;
800 | }
801 | if (time_rf_dwell == 0) {
802 | FREQCTRL = RNDH&0x3f;
803 | time_rf_dwell = (RNDL&0x1f)+80;
804 | FRMCTRL0 = (FRMCTRL0&(3<<2))|(1<<2); // infinite receive mode
805 | RFST = 0xED; // flush
806 | RFST = 0xED;
807 | RFST = 0xec;
808 | RFST = 0xe3;
809 | rf_running = 0;
810 | queue_task(&rf_task, 2);
811 | return;
812 | }
813 | if (!(RSSISTAT&1)) {
814 | queue_task(&rf_task, 2);
815 | rf_running = 0;
816 | time_rf_dwell--;
817 | return;
818 | }
819 | rf_running = 1;
820 | time_rf_dwell--;
821 | queue_task(&rf_task, HZ/30);
822 | }
823 |
824 |
825 |
826 |
827 | unsigned char my_app(unsigned char op)
828 | {
829 | switch (op) {
830 | case APP_INIT:
831 | RNDL = 1;
832 | RNDL = 1;
833 | sys_active = 1;
834 | uart_setup();
835 | P1DIR |= 1<<1;
836 | P1INP |= 1<<1;
837 | #ifdef NORM_LED
838 | P1_1 = 1;
839 | #else
840 | P1_1 = 0;
841 | #endif
842 | P1DIR &= ~(1<<7);
843 | P1INP |= (1<<7);
844 | RFIRQM0 = 0; // disable RF subsection interrupts
845 | RFIRQM1 = 0;
846 | FRMCTRL0 = (FRMCTRL0&(3<<2))|(1<<2); // infinite receive mode
847 | queue_task(&error_task, 1*HZ);
848 | queue_task(&rf_task, HZ/2);
849 | queue_task(&manufacturing_task, 0);
850 | break;
851 | case APP_GET_MAC:
852 | return 0;
853 | case APP_GET_KEY:
854 | break;
855 | case APP_GET_SUOTA_KEY:
856 | break;
857 | case APP_RCV_PACKET:
858 | break;
859 | }
860 | return 0;
861 | }
862 |
--------------------------------------------------------------------------------
/ffff.c:
--------------------------------------------------------------------------------
1 | #include
2 | main()
3 | {
4 | int i;
5 | for (i = 0; i < 66536; i++)
6 | putchar(0xff);
7 | exit(0);
8 | }
9 |
--------------------------------------------------------------------------------
/include/interface.h:
--------------------------------------------------------------------------------
1 | // (c) Copyright Paul Campbell paul@taniwha.com 2013
2 | //
3 | // This library is free software; you can redistribute it and/or
4 | // modify it under the terms of the GNU Lesser General Public
5 | // License as published by the Free Software Foundation; either
6 | // version 2.1 of the License, or (at your option) version 3, or any
7 | // later version accepted by Paul Campbell , who shall
8 | // act as a proxy defined in Section 6 of version 3 of the license.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library. If not, see .
17 | //
18 |
19 | #ifndef __interface_h
20 | #define __interface_h
21 |
22 | #include
23 | #include
24 | #include "task.h"
25 |
26 | #ifndef THIS_ARCH
27 | #define THIS_ARCH 1 // initial CC2533 // 0 unavailable as an extension
28 | #endif
29 | #ifndef THIS_CODE_BASE
30 | #define THIS_CODE_BASE 0 // initial CC2533
31 | #endif
32 | typedef struct code_hdr { // caution: these offsets are hard coded in suota assembly, fixcrc and packet_interface.cpp
33 | unsigned char crc[4];
34 | unsigned char len[2];
35 | unsigned char arch;
36 | unsigned char code_base;
37 | unsigned char version[2];
38 | unsigned char data[1];
39 | } code_hdr;
40 |
41 |
42 | extern unsigned char (* __data x_app) (u8 v);
43 | #define APP_INIT 0
44 | #define APP_GET_MAC 1
45 | #define APP_GET_KEY 2
46 | #define APP_GET_SUOTA_KEY 3
47 | #define APP_RCV_PACKET 4
48 | #define APP_LOW_LEVEL_INIT 0xff
49 | #define APP_WAKE 5
50 | #define APP_KEY 6
51 | #define APP_SUOTA_START 7
52 | #define APP_SUOTA_DONE 8
53 | __bit __at (0x06) sys_active;
54 | #define KEY_X 0
55 | #define KEY_O 1
56 | #define KEY_LEFT 2
57 | #define KEY_RIGHT 3
58 |
59 | // call backs
60 | #ifdef DRV_LEDS
61 | extern void leds_rgb(unsigned char * __xdata);
62 | extern void leds_off();
63 | #endif
64 | extern void uart_init();
65 | extern void putchar(char c);
66 | extern void putstr(char __code *cp);
67 | extern void puthex(unsigned char v);
68 |
69 |
70 | extern void (* __pdata uart_rx_0_vect) ();
71 | extern void (* __pdata uart_rx_1_vect) ();
72 | extern void (* __pdata uart_tx_0_vect) ();
73 | extern void (* __pdata uart_tx_1_vect) ();
74 | extern void (* __pdata p0_vect) ();
75 | extern void (* __pdata p1_vect) ();
76 | extern void (* __pdata p2_vect) ();
77 | extern void (* __pdata t2_vect) ();
78 | extern void (* __pdata t3_vect) ();
79 | extern void (* __pdata t4_vect) ();
80 | extern void (* __pdata adc_vect) ();
81 | extern void (* __pdata aec_vect) ();
82 | extern void (* __pdata dma_vect) ();
83 |
84 | //
85 | // Simple Arduino compatability macros
86 | //
87 | // instead of pin numbers we use P(port,bit)
88 | // P(1,2) refers to pin p1.2
89 | //
90 | // "digitalWrite(P(1,2), HIGH);"
91 | //
92 | #ifndef LOW
93 | #define HIGH 1
94 | #define LOW 0
95 | #define P(p, b) p , b
96 | #define __XP(p,b) P##p##_##b
97 | #define __Xp(p,b) p
98 | #define __Xb(p,b) b
99 | #define digitalWrite(p , v) __XP(p)=(v)
100 | #define digitalRead(p) __XP(p)
101 | #define INPUT 0
102 | #define OUTPUT 1
103 | #define INPUT_PULLUP 2
104 | #define __XPINP(p) P##p##INP
105 | #define __XPDIR(p) P##p##DIR
106 | #define __PINP(p) __XPINP(p)
107 | #define __PDIR(p) __XPDIR(p)
108 | #define pinMode(p, m) if ((m)==OUTPUT) {__PDIR(__Xp(p)) |= (1<<__Xb(p)); __PINP(__Xp(p)) |= (1<<__Xb(p));} else { __PDIR(__Xp(p)) &= ~(1<<__Xb(p)); if ((m)==INPUT_PULLUP) {__PINP(__Xp(p)) &= ~(1<<__Xb(p)); } else {__PINP(__Xp(p)) |= (1<<__Xb(p));} }
109 | #endif
110 | #endif
111 |
--------------------------------------------------------------------------------
/include/task.h:
--------------------------------------------------------------------------------
1 | // (c) Copyright Paul Campbell paul@taniwha.com 2013
2 | //
3 | // This library is free software; you can redistribute it and/or
4 | // modify it under the terms of the GNU Lesser General Public
5 | // License as published by the Free Software Foundation; either
6 | // version 2.1 of the License, or (at your option) version 3, or any
7 | // later version accepted by Paul Campbell , who shall
8 | // act as a proxy defined in Section 6 of version 3 of the license.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library. If not, see .
17 | //
18 |
19 | #ifndef _TASK_H
20 | #define _TASK_H
21 |
22 | __sfr __at (0x93) _XPAGE;
23 |
24 | typedef unsigned char u8;
25 |
26 | typedef struct task {
27 | void (*callout)(struct task __xdata*); // offset 0
28 | unsigned int time; // offset 2
29 | struct task __xdata*next; // offset 4
30 | u8 state; // offset 6
31 | } task;
32 |
33 | void queue_task(task __xdata *, unsigned int);
34 | void queue_task_0(task __xdata *);
35 | void cancel_task(task __xdata * );
36 |
37 | #define HZ (32000/256)
38 |
39 |
40 | #define TASK_IDLE 0
41 | #define TASK_CALLOUT 1
42 | #define TASK_QUEUED 2
43 |
44 | extern void wait_us(u8);
45 | extern unsigned char app(u8);
46 |
47 | #endif
48 |
--------------------------------------------------------------------------------
/kernel/app_hdr.c:
--------------------------------------------------------------------------------
1 | // (c) Copyright Paul Campbell paul@taniwha.com 2013
2 | //
3 | // This library is free software; you can redistribute it and/or
4 | // modify it under the terms of the GNU Lesser General Public
5 | // License as published by the Free Software Foundation; either
6 | // version 2.1 of the License, or (at your option) version 3, or any
7 | // later version accepted by Paul Campbell , who shall
8 | // act as a proxy defined in Section 6 of version 3 of the license.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library. If not, see .
17 | //
18 |
19 | #include "interface.h"
20 | static xxxx() __naked {
21 | __asm;
22 | .area GSINIT0 (CODE)
23 | .globl _CODE_HEADER
24 | _CODE_HEADER:
25 | .db 0, 0, 0, 0 // CRC will go here
26 | .db 0, 0 // len from here to end of code
27 | .db THIS_ARCH
28 | .db THIS_CODE_BASE
29 | .db 0, 0 // version (little endian)
30 | .globl _my_app
31 | mov a, dpl
32 | cjne a, #APP_LOW_LEVEL_INIT, 0001$
33 | sjmp 0002$
34 | 0001$: ljmp _my_app
35 | 0002$: mov r0, #s_DSEG // clear data seg
36 | mov a, #l_DSEG
37 | jz 0004$
38 | mov r1, a
39 | clr a
40 | 0003$: mov @r0, a
41 | inc r0
42 | 0004$: mov r0, #s_PSEG // clear pseg
43 | mov a, #l_PSEG
44 | jz 0006$
45 | mov r1, a
46 | clr a
47 | 0005$: movx @r0, a
48 | inc r0
49 | djnz r1, 0005$
50 | 0006$: mov dptr, #s_XSEG // clear xseg
51 | mov r1, #l_XSEG
52 | mov r2, #l_XSEG>>8
53 | cjne r1, #0, 0007$
54 | cjne r2, #0, 0007$
55 | sjmp 0011$
56 | 0007$:
57 | inc r2
58 | 0010$: movx @dptr, a
59 | inc dptr
60 | djnz r1, 0010$
61 | djnz r2, 0010$
62 | 0011$:
63 | mov r1, #l_XINIT
64 | mov a, r1
65 | orl a, #(l_XINIT >> 8)
66 | jz 0023$
67 | mov r2, #((l_XINIT+255) >> 8)
68 | mov _DPS, #0x01
69 | mov dptr, #s_XINIT
70 | dec _DPS
71 | mov dptr, #s_XISEG
72 | 0021$: clr a
73 | inc _DPS
74 | movc a, @a+dptr
75 | inc dptr
76 | dec _DPS
77 | movx @dptr, a
78 | inc dptr
79 | djnz r1, 0021$
80 | djnz r2, 0021$
81 | 0023$: ret
82 | .area XSEG (XDATA)
83 | .globl _xseg_end
84 | _xseg_end:
85 | .ds 1
86 | __endasm;
87 | }
88 |
89 |
--------------------------------------------------------------------------------
/kernel/app_integrated.c:
--------------------------------------------------------------------------------
1 | // (c) Copyright Paul Campbell paul@taniwha.com 2013
2 | //
3 | // This library is free software; you can redistribute it and/or
4 | // modify it under the terms of the GNU Lesser General Public
5 | // License as published by the Free Software Foundation; either
6 | // version 2.1 of the License, or (at your option) version 3, or any
7 | // later version accepted by Paul Campbell , who shall
8 | // act as a proxy defined in Section 6 of version 3 of the license.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library. If not, see .
17 | //
18 |
19 | #include "interface.h"
20 | static xxxx() __naked {
21 | __asm;
22 | .area CODE (CODE)
23 | .globl _CODE_HEADER
24 | _CODE_HEADER:
25 | .db 0, 0, 0, 0 // CRC will go here
26 | .db 1, 0 // len from arch to end of code - '1' signals a standalone app
27 | .db THIS_ARCH
28 | .db THIS_CODE_BASE
29 | .db 0, 0 // version (little endian)
30 | .globl _my_app
31 | ljmp _my_app
32 | .area XSEG (XDATA)
33 | .globl _xseg_end
34 | _xseg_end:
35 | .ds 1
36 | __endasm;
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/kernel/dummy.c:
--------------------------------------------------------------------------------
1 | // (c) Copyright Paul Campbell paul@taniwha.com 2013
2 | //
3 | // This library is free software; you can redistribute it and/or
4 | // modify it under the terms of the GNU Lesser General Public
5 | // License as published by the Free Software Foundation; either
6 | // version 2.1 of the License, or (at your option) version 3, or any
7 | // later version accepted by Paul Campbell , who shall
8 | // act as a proxy defined in Section 6 of version 3 of the license.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library. If not, see .
17 | //
18 |
19 | #include "protocol.h"
20 |
21 | static void xxxx() __naked {
22 | __asm;
23 | .area CSEG (CODE)
24 | .globl _CODE_HEADER
25 | _CODE_HEADER:
26 | .db 0, 0, 0, 0 // CRC will go here
27 | .db 0, 0 // len from arch to end of code - must be 0
28 | .db THIS_ARCH
29 | .db THIS_CODE_BASE
30 | .db 0, 0 // version (little endian)
31 | clr a
32 | mov dpl, a
33 | ret
34 | .area DSEG (DATA)
35 | .globl _data_end
36 | _data_end:
37 | .ds 1
38 | .area XSEG (XDATA)
39 | .globl _xseg_end
40 | _xseg_end:
41 | .ds 1
42 |
43 | __endasm;
44 | }
45 |
--------------------------------------------------------------------------------
/kernel/fixcrc.c:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2013 Paul Campbell paul@taniwha.com
3 | //
4 | //
5 | // This library is free software; you can redistribute it and/or
6 | // modify it under the terms of the GNU Lesser General Public
7 | // License as published by the Free Software Foundation; either
8 | // version 2.1 of the License, or (at your option) version 3, or any
9 | // later version accepted by Paul Campbell , who shall
10 | // act as a proxy defined in Section 6 of version 3 of the license.
11 | //
12 | // This library is distributed in the hope that it will be useful,
13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | // Lesser General Public License for more details.
16 | //
17 | // You should have received a copy of the GNU Lesser General Public
18 | // License along with this library. If not, see .
19 | //
20 |
21 | #include
22 | #include
23 | #include
24 |
25 | int mn=0x10000, mx=0;
26 | unsigned char m[65536];
27 |
28 |
29 | int
30 | hex(FILE *f)
31 | {
32 | char c1, c2;
33 | int r;
34 | c1 = fgetc(f);
35 | if (c1 < 0)
36 | return -1;
37 | c2 = fgetc(f);
38 | if (c2 < 0)
39 | return -1;
40 | if (c1 >= '0' && c1 <= '9') {
41 | r = c1-'0';
42 | } else
43 | if (c1 >= 'A' && c1 <= 'F') {
44 | r = c1-'A'+10;
45 | } else
46 | if (c1 >= 'a' && c1 <= 'f') {
47 | r = c1-'a'+10;
48 | } else return -1;
49 | r=r<<4;
50 | if (c2 >= '0' && c2 <= '9') {
51 | r += c2-'0';
52 | } else
53 | if (c2 >= 'A' && c2 <= 'F') {
54 | r += c2-'A'+10;
55 | } else
56 | if (c2 >= 'a' && c2 <= 'f') {
57 | r += c2-'a'+10;
58 | } else return -1;
59 | return r;
60 | }
61 |
62 | int
63 | upload(FILE *f)
64 | {
65 | memset(m, 0xff, sizeof(m));
66 | for(;;) {
67 | int c;
68 | int i;
69 | int sum=0, len, addr;
70 | c = fgetc(f);
71 | if (c < 0)
72 | break;
73 | if (c == '\n')
74 | continue;
75 | if (c != ':') {
76 | fprintf(stderr, "bad file format\n");
77 | fail2:
78 | return 0;
79 | }
80 | len = hex(f);
81 | if (len < 0) {
82 | fprintf(stderr, "bad file format\n");
83 | goto fail2;
84 | }
85 | sum += len;
86 | addr = hex(f);
87 | if (addr < 0) {
88 | fprintf(stderr, "bad file format\n");
89 | goto fail2;
90 | }
91 | sum += addr;
92 | i = hex(f);
93 | if (i < 0) {
94 | fprintf(stderr, "bad file format\n");
95 | goto fail2;
96 | }
97 | sum += i;
98 | addr = (addr<<8)+i;
99 | int type = hex(f);
100 | if (type < 0) {
101 | fprintf(stderr, "bad file format\n");
102 | goto fail2;
103 | }
104 | sum += type;
105 | if (type == 0x01)
106 | break;
107 | if (mn > addr)
108 | mn = addr;
109 | for (i = 0; i < len; i++) {
110 | int v = hex(f);
111 | if (v < 0)
112 | break;
113 | m[(addr+i)&0xffff] = v;
114 | sum += v;
115 | }
116 | i = hex(f);
117 | if (i < 0) {
118 | goto fail2;
119 | }
120 | if (i < 0 || i != ((0x100-(sum&0xff))&0xff)) {
121 | fprintf(stderr, "bad checksum\n");
122 | goto fail2;
123 | }
124 | addr += len;
125 | if (addr > mx)
126 | mx = addr;
127 | }
128 | return 1;
129 | }
130 |
131 | unsigned long
132 | crc(unsigned long c, unsigned char *p, int len)
133 | {
134 | while (len--) {
135 | unsigned char v = *p++;
136 | int i;
137 |
138 | c ^= (v<<24);
139 | for (i = 0; i < 8; i++) {
140 | if (c&0x80000000) {
141 | c = (c<<1)^0x04c11db7;
142 | } else {
143 | c = (c<<1);
144 | }
145 | }
146 | }
147 | return c;
148 | }
149 |
150 |
151 | int
152 | main(int argc, char **argv)
153 | {
154 | unsigned char h[4];
155 | unsigned char k[16];
156 | int len;
157 | unsigned long c;
158 | int version = -1;
159 | int i;
160 |
161 | for (i = 1; i < argc; i++) {
162 | if (strcmp(argv[i], "-v") == 0 && i < argc) {
163 | i++;
164 | version = strtol(argv[i], 0, 0);
165 | } else
166 | if (strcmp(argv[i], "-k") == 0 && i < argc) {
167 | char *cp;
168 | i++;
169 | cp = argv[i];
170 | for (i = 0; i < 16; i++) {
171 | int v;
172 |
173 | if (*cp >= '0' && *cp <= '9') {
174 | v = (*cp-'0');
175 | } else
176 | if (*cp >= 'a' && *cp <= 'f') {
177 | v = (*cp-'a')+10;
178 | } else
179 | if (*cp >= 'A' && *cp <= 'F') {
180 | v = (*cp-'A')+10;
181 | } else {
182 | fprintf(stderr, "%s: bad key '%s'\n", argv[0], argv[i]);
183 | exit(9);
184 | }
185 | cp++;
186 | v = v<<4;
187 | if (*cp >= '0' && *cp <= '9') {
188 | v |= (*cp-'0');
189 | } else
190 | if (*cp >= 'a' && *cp <= 'f') {
191 | v |= (*cp-'a')+10;
192 | } else
193 | if (*cp >= 'A' && *cp <= 'F') {
194 | v |= (*cp-'A')+10;
195 | } else {
196 | fprintf(stderr, "%s: bad key '%s'\n", argv[0], argv[i]);
197 | exit(9);
198 | }
199 | cp++;
200 | k[i] = v;
201 | }
202 | if (*cp) {
203 | fprintf(stderr, "%s: bad key '%s' - too long\n", argv[0], argv[i]);
204 | exit(9);
205 | }
206 | } else {
207 | fprintf(stderr, "%s: unknown flag '%s'\n", argv[0], argv[i]);
208 | exit(9);
209 | }
210 | }
211 | if (!upload(stdin) || mx <= mn) {
212 | fprintf(stderr, "unpack failed mx=%d mn=%d\n", mx, mn);
213 | exit(9);
214 | }
215 | len = mx-mn;
216 | m[mn+4] = (len-4);
217 | m[mn+5] = (len-4)>>8;
218 | if (version >= 0) {
219 | m[mn+8] = version;
220 | m[mn+9] = version>>8;
221 | }
222 | c = crc(0xffffffff, &m[mn+4], len-4);
223 | m[mn+0] = c;
224 | m[mn+1] = c>>8;
225 | m[mn+2] = c>>16;
226 | m[mn+3] = c>>24;
227 | h[0] = mn; // base addr
228 | h[1] = mn>>8;
229 | h[2] = len; // len
230 | h[3] = len>>8;
231 | fwrite(&h[0], 4, 1, stdout);
232 | fwrite(&k[0], 16, 1, stdout);
233 | fwrite(&m[mn], len, 1, stdout);
234 | exit(0);
235 | }
236 |
--------------------------------------------------------------------------------
/kernel/map.pl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/perl
2 | # (c) Copyright Paul Campbell paul@taniwha.com 2013
3 | #
4 | # This library is free software; you can redistribute it and/or
5 | # modify it under the terms of the GNU Lesser General Public
6 | # License as published by the Free Software Foundation; either
7 | # version 2.1 of the License, or (at your option) version 3, or any
8 | # later version accepted by Paul Campbell , who shall
9 | # act as a proxy defined in Section 6 of version 3 of the license.
10 | #
11 | # This library is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | # Lesser General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU Lesser General Public
17 | # License along with this library. If not, see .
18 | #
19 |
20 |
21 | while (<>) {
22 |
23 | # BITS
24 | # rx_crypto
25 | # rx_broadcast
26 | # key_down
27 | # _limit
28 | if (/^C:.*([0-9A-F][0-9A-F]*).*s_BSEG .*$/ ) {
29 | $bs = hex($1);
30 | }
31 | if (/^C:.*([0-9A-F][0-9A-F]*).*l_BSEG .*$/ ) {
32 | $bl = hex($1);
33 | }
34 |
35 | # DATA
36 | # rtx_key
37 | if (/^ *([0-9A-F][0-9A-F]*) *_rtx_key .*$/ ) {
38 | printf STDOUT "-g _rtx_key=0x%x\n", hex($1);
39 | }
40 | # rx_mac
41 | if (/^ *([0-9A-F][0-9A-F]*) *_rx_mac .*$/ ) {
42 | printf STDOUT "-g _rx_mac=0x%x\n", hex($1);
43 | }
44 | # rx_len
45 | if (/^ *([0-9A-F][0-9A-F]*) *_rx_len .*$/ ) {
46 | printf STDOUT "-g _rx_len=0x%x\n", hex($1);
47 | }
48 | # rx_packet
49 | if (/^ *([0-9A-F][0-9A-F]*) *_rx_packet .*$/ ) {
50 | printf STDOUT "-g _rx_packet=0x%x\n", hex($1);
51 | }
52 | # _limit
53 | if (/^ *([0-9A-F][0-9A-F]*) *_data_end .*$/ ) {
54 | printf STDOUT "-b DSEG=0x%x\n", hex($1);
55 | }
56 |
57 |
58 | # CODE
59 | # leds_rgb
60 | if (/^C: *([0-9A-F][0-9A-F]*) *_leds_rgb .*$/ ) {
61 | printf STDOUT "-g _leds_rgb=0x%x\n", hex($1);
62 | }
63 | # leds_off
64 | if (/^C: *([0-9A-F][0-9A-F]*) *_leds_off .*$/ ) {
65 | printf STDOUT "-g _leds_off=0x%x\n", hex($1);
66 | }
67 | # rf_receive_on
68 | if (/^C: *([0-9A-F][0-9A-F]*) *_rf_receive_on .*$/ ) {
69 | printf STDOUT "-g _rf_receive_on=0x%x\n", hex($1);
70 | }
71 | # rf_receive_off
72 | if (/^C: *([0-9A-F][0-9A-F]*) *_rf_receive_off .*$/ ) {
73 | printf STDOUT "-g _rf_receive_off=0x%x\n", hex($1);
74 | }
75 | # rf_set_channel
76 | if (/^C: *([0-9A-F][0-9A-F]*) *_rf_set_channel .*$/ ) {
77 | printf STDOUT "-g _rf_set_channel=0x%x\n", hex($1);
78 | }
79 | # rf_set_key_c
80 | if (/^C: *([0-9A-F][0-9A-F]*) *_rf_set_key_c .*$/ ) {
81 | printf STDOUT "-g _rf_set_key_c=0x%x\n", hex($1);
82 | }
83 | # rf_set_key
84 | if (/^C: *([0-9A-F][0-9A-F]*) *_rf_set_key .*$/ ) {
85 | printf STDOUT "-g _rf_set_key=0x%x\n", hex($1);
86 | }
87 | # rf_set_mac
88 | if (/^C: *([0-9A-F][0-9A-F]*) *_rf_set_mac .*$/ ) {
89 | printf STDOUT "-g _rf_set_mac=0x%x\n", hex($1);
90 | }
91 | # rf_send
92 | if (/^C: *([0-9A-F][0-9A-F]*) *_rf_send .*$/ ) {
93 | printf STDOUT "-g _rf_send=0x%x\n", hex($1);
94 | }
95 | if (/^D: *([0-9A-F][0-9A-F]*) *_rf_send_PARM_2 .*$/ ) {
96 | printf STDOUT "-g _rf_send_PARM_2=0x%x\n", hex($1);
97 | }
98 | if (/^D: *([0-9A-F][0-9A-F]*) *_rf_send_PARM_3 .*$/ ) {
99 | printf STDOUT "-g _rf_send_PARM_3=0x%x\n", hex($1);
100 | }
101 | if (/^D: *([0-9A-F][0-9A-F]*) *_rf_send_PARM_4 .*$/ ) {
102 | printf STDOUT "-g _rf_send_PARM_4=0x%x\n", hex($1);
103 | }
104 | # rf_set_transmit_power
105 | if (/^C: *([0-9A-F][0-9A-F]*) *_rf_set_transmit_power .*$/ ) {
106 | printf STDOUT "-g _rf_set_transmit_power=0x%x\n", hex($1);
107 | }
108 | # rf_set_promiscuous
109 | if (/^C: *([0-9A-F][0-9A-F]*) *_rf_set_promiscuous .*$/ ) {
110 | printf STDOUT "-g _rf_set_promiscuous=0x%x\n", hex($1);
111 | }
112 | # rf_set_raw
113 | if (/^C: *([0-9A-F][0-9A-F]*) *_rf_set_raw .*$/ ) {
114 | printf STDOUT "-g _rf_set_raw=0x%x\n", hex($1);
115 | }
116 | # daylight
117 | if (/^C: *([0-9A-F][0-9A-F]*) *_daylight .*$/ ) {
118 | printf STDOUT "-g _daylight=0x%x\n", hex($1);
119 | }
120 | # keys_on
121 | if (/^C: *([0-9A-F][0-9A-F]*) *_keys_on .*$/ ) {
122 | printf STDOUT "-g _keys_on=0x%x\n", hex($1);
123 | }
124 | # keys_off
125 | if (/^C: *([0-9A-F][0-9A-F]*) *_keys_off .*$/ ) {
126 | printf STDOUT "-g _keys_off=0x%x\n", hex($1);
127 | }
128 | # uart_init
129 | if (/^C: *([0-9A-F][0-9A-F]*) *_uart_init .*$/ ) {
130 | printf STDOUT "-g _uart_init=0x%x\n", hex($1);
131 | }
132 | # putchar
133 | if (/^C: *([0-9A-F][0-9A-F]*) *_putchar .*$/ ) {
134 | printf STDOUT "-g _putchar=0x%x\n", hex($1);
135 | }
136 | # system_attributes
137 | if (/^C: *([0-9A-F][0-9A-F]*) *_system_attributes .*$/ ) {
138 | printf STDOUT "-g _system_attributes=0x%x\n", hex($1);
139 | }
140 | # putstr
141 | if (/^C: *([0-9A-F][0-9A-F]*) *_putstr .*$/ ) {
142 | printf STDOUT "-g _putstr=0x%x\n", hex($1);
143 | }
144 | # puthex
145 | if (/^C: *([0-9A-F][0-9A-F]*) *_puthex .*$/ ) {
146 | printf STDOUT "-g _puthex=0x%x\n", hex($1);
147 | }
148 | # queue_task
149 | if (/^C: *([0-9A-F][0-9A-F]*) *_queue_task .*$/ ) {
150 | printf STDOUT "-g _queue_task=0x%x\n", hex($1);
151 | }
152 | if (/^D: *([0-9A-F][0-9A-F]*) *_queue_task_PARM_2 .*$/ ) {
153 | printf STDOUT "-g _queue_task_PARM_2=0x%x\n", hex($1);
154 | }
155 | # cancel_task
156 | if (/^C: *([0-9A-F][0-9A-F]*) *_cancel_task .*$/ ) {
157 | printf STDOUT "-g _cancel_task=0x%x\n", hex($1);
158 | }
159 | # wait_us
160 | if (/^C: *([0-9A-F][0-9A-F]*) *_wait_us .*$/ ) {
161 | printf STDOUT "-g _wait_us=0x%x\n", hex($1);
162 | }
163 | # _limit
164 |
165 | # PDATA
166 | # key
167 | if (/^D: *([0-9A-F][0-9A-F]*) *_key .*$/ ) {
168 | printf STDOUT "-g _key=0x%x\n", hex($1);
169 | }
170 | # uart_rx_0_vect
171 | if (/^D: *([0-9A-F][0-9A-F]*) *_uart_rx_0_vect .*$/ ) {
172 | printf STDOUT "-g _uart_rx_0_vect=0x%x\n", hex($1);
173 | }
174 | # uart_rx_1_vect
175 | if (/^D: *([0-9A-F][0-9A-F]*) *_uart_rx_1_vect .*$/ ) {
176 | printf STDOUT "-g _uart_rx_1_vect=0x%x\n", hex($1);
177 | }
178 | # uart_tx_0_vect
179 | if (/^D: *([0-9A-F][0-9A-F]*) *_uart_tx_0_vect .*$/ ) {
180 | printf STDOUT "-g _uart_tx_0_vect=0x%x\n", hex($1);
181 | }
182 | # uart_tx_1_vect
183 | if (/^D: *([0-9A-F][0-9A-F]*) *_uart_tx_1_vect .*$/ ) {
184 | printf STDOUT "-g _uart_tx_1_vect=0x%x\n", hex($1);
185 | }
186 | # p0_vect
187 | if (/^D: *([0-9A-F][0-9A-F]*) *_p0_vect .*$/ ) {
188 | printf STDOUT "-g _p0_vect=0x%x\n", hex($1);
189 | }
190 | # p1_vect
191 | if (/^D: *([0-9A-F][0-9A-F]*) *_p1_vect .*$/ ) {
192 | printf STDOUT "-g _p1_vect=0x%x\n", hex($1);
193 | }
194 | # p2_vect
195 | if (/^D: *([0-9A-F][0-9A-F]*) *_p2_vect .*$/ ) {
196 | printf STDOUT "-g _p2_vect=0x%x\n", hex($1);
197 | }
198 | # t2_vect
199 | if (/^D: *([0-9A-F][0-9A-F]*) *_t2_vect .*$/ ) {
200 | printf STDOUT "-g _t2_vect=0x%x\n", hex($1);
201 | }
202 | # t3_vect
203 | if (/^D: *([0-9A-F][0-9A-F]*) *_t3_vect .*$/ ) {
204 | printf STDOUT "-g _t3_vect=0x%x\n", hex($1);
205 | }
206 | # t4_vect
207 | if (/^D: *([0-9A-F][0-9A-F]*) *_t4_vect .*$/ ) {
208 | printf STDOUT "-g _t4_vect=0x%x\n", hex($1);
209 | }
210 | # adc_vect
211 | if (/^D: *([0-9A-F][0-9A-F]*) *_adc_vect .*$/ ) {
212 | printf STDOUT "-g _adc_vect=0x%x\n", hex($1);
213 | }
214 | # aec_vect
215 | if (/^D: *([0-9A-F][0-9A-F]*) *_aec_vect .*$/ ) {
216 | printf STDOUT "-g _aec_vect=0x%x\n", hex($1);
217 | }
218 | # dma_vect
219 | if (/^D: *([0-9A-F][0-9A-F]*) *_dma_vect .*$/ ) {
220 | printf STDOUT "-g _dma_vect=0x%x\n", hex($1);
221 | }
222 | # _limit
223 | if (/^C: *([0-9A-F][0-9A-F]*) *l_PSEG.*$/ ) {
224 | printf STDOUT "-b PSEG=0x%x\n", hex($1);
225 | }
226 |
227 | # XDATA
228 | # _limit
229 | # if (/^D: *([0-9A-F][0-9A-F]*) *_xseg_end.*$/ ) {
230 | # printf STDOUT "-b XSEG=0x%x\n", hex($1);
231 | # }
232 | if (/^C: *([0-9A-F][0-9A-F]*) *s_XISEG.*$/ ) {
233 | $a=hex($1);
234 | }
235 | if (/^C: *([0-9A-F][0-9A-F]*) *l_XISEG.*$/ ) {
236 | $b=hex($1);
237 | }
238 |
239 | }
240 | printf STDOUT "-b xSEG=0x%x\n", $a+$b;
241 | printf STDOUT "-b BSEG=0x%x\n", $bs+$bl;
242 | printf STDOUT "-e\n";
243 |
244 |
--------------------------------------------------------------------------------
/kernel/syms.c:
--------------------------------------------------------------------------------
1 | // (c) Copyright Paul Campbell paul@taniwha.com 2013
2 | //
3 | // This library is free software; you can redistribute it and/or
4 | // modify it under the terms of the GNU Lesser General Public
5 | // License as published by the Free Software Foundation; either
6 | // version 2.1 of the License, or (at your option) version 3, or any
7 | // later version accepted by Paul Campbell , who shall
8 | // act as a proxy defined in Section 6 of version 3 of the license.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library. If not, see .
17 | //
18 |
19 | void ____x___() __naked
20 | {
21 | __asm;
22 | .globl _rx_len
23 | .globl _rx_packet
24 | .globl _rx_mac
25 | .globl _rtx_key
26 | .globl _uart_rx_0_vect
27 | .globl _uart_rx_1_vect
28 | .globl _uart_tx_0_vect
29 | .globl _uart_tx_1_vect
30 | .globl _p0_vect
31 | .globl _p1_vect
32 | .globl _p2_vect
33 | .globl _t2_vect
34 | .globl _t3_vect
35 | .globl _t4_vect
36 | .globl _adc_vect
37 | .globl _aec_vect
38 | .globl _dma_vect
39 | .globl _queue_task_PARM_2
40 | .globl _rf_send_PARM_2
41 | .globl _rf_send_PARM_3
42 | .globl _rf_send_PARM_4
43 | #ifdef DRV_KEYS
44 | .globl _key
45 | #endif
46 | #ifdef DRV_DAYLIGHT
47 | .globl _daylight
48 | #endif
49 | .globl _putchar
50 | .globl _putstr
51 | .globl _puthex
52 | .globl _wait_us
53 | .globl _queue_task
54 | .globl _cancel_task
55 | .globl _uart_init
56 | .globl _rf_set_key
57 | .globl _rf_set_key_c
58 | .globl _rf_set_promiscuous
59 | .globl _rf_set_raw
60 | .globl _rf_set_mac
61 | .globl _rf_set_channel
62 | .globl _rf_set_transmit_power
63 | .globl _rf_receive_on
64 | .globl _rf_receive_off
65 | .globl _rf_send
66 | #ifdef DRV_LEDS
67 | .globl _leds_off
68 | .globl _leds_rgb
69 | #endif
70 | #ifdef DRV_KEYS
71 | .globl _keys_off
72 | #endif
73 | .globl _system_attributes
74 | #ifdef DRV_KEYS
75 | .globl _keys_on
76 | #endif
77 | .area CSEG (CODE)
78 | .globl __2
79 | __2=_rx_len
80 | .globl __3
81 | __3=_rx_packet
82 | .globl __4
83 | __4=_rx_mac
84 | .globl __5
85 | __5=_rtx_key
86 | .globl __6
87 | __6=_uart_rx_0_vect
88 | .globl __7
89 | __7=_uart_rx_1_vect
90 | .globl __8
91 | __8=_uart_tx_0_vect
92 | .globl __9
93 | __9=_uart_tx_1_vect
94 | .globl __10
95 | __10=_p0_vect
96 | .globl __11
97 | __11=_p1_vect
98 | .globl __12
99 | __12=_p2_vect
100 | .globl __13
101 | __13=_t2_vect
102 | .globl __14
103 | __14=_t3_vect
104 | .globl __15
105 | __15=_t4_vect
106 | .globl __16
107 | __16=_adc_vect
108 | .globl __17
109 | __17=_aec_vect
110 | .globl __18
111 | __18=_dma_vect
112 | .globl __19
113 | __19=_queue_task_PARM_2
114 | .globl __20
115 | __20=_rf_send_PARM_2
116 | .globl __21
117 | __21=_rf_send_PARM_3
118 | .globl __22
119 | __22=_rf_send_PARM_4
120 | #ifdef DRV_KEYS
121 | .globl __23
122 | __23=_key
123 | #endif
124 | #ifdef DRV_DAYLIGHT
125 | .globl __24
126 | __24=_daylight
127 | #endif
128 | .globl __25
129 | __25=_putchar
130 | .globl __26
131 | __26=_putstr
132 | .globl __27
133 | __27=_puthex
134 | .globl __28
135 | __28=_wait_us
136 | .globl __29
137 | __29=_queue_task
138 | .globl __30
139 | __30=_cancel_task
140 | .globl __31
141 | __31=_uart_init
142 | .globl __32
143 | __32=_rf_set_key
144 | .globl __33
145 | __33=_rf_set_promiscuous
146 | .globl __34
147 | __34=_rf_set_raw
148 | .globl __35
149 | __35=_rf_set_mac
150 | .globl __36
151 | __36=_rf_set_channel
152 | .globl __37
153 | __37=_rf_set_transmit_power
154 | .globl __38
155 | __38=_rf_receive_on
156 | .globl __39
157 | __39=_rf_receive_off
158 | .globl __40
159 | __40=_rf_send
160 | #ifdef DRV_LEDS
161 | .globl __41
162 | __41=_leds_off
163 | .globl __42
164 | __42=_leds_rgb
165 | #endif
166 | #ifdef DRV_KEYS
167 | .globl __43
168 | __43=_keys_off
169 | .globl __44
170 | __44=_keys_on
171 | .globl __45
172 | #endif
173 | __45=_system_attributes
174 | .globl __46
175 | __46=_rf_set_key_c
176 | .globl __33
177 | __endasm;
178 | }
179 |
--------------------------------------------------------------------------------
/kernel/task.c:
--------------------------------------------------------------------------------
1 | // (c) Copyright Paul Campbell paul@taniwha.com 2013
2 | //
3 | // This library is free software; you can redistribute it and/or
4 | // modify it under the terms of the GNU Lesser General Public
5 | // License as published by the Free Software Foundation; either
6 | // version 2.1 of the License, or (at your option) version 3, or any
7 | // later version accepted by Paul Campbell , who shall
8 | // act as a proxy defined in Section 6 of version 3 of the license.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library. If not, see .
17 | //
18 |
19 | //#define TDEBUG
20 | //#define XMT
21 | #include
22 | #include
23 | #include "task.h"
24 | #include "interface.h"
25 |
26 | extern __bit inSuspend;
27 | static task __xdata * __data waitq;
28 | volatile u8 __data enter_sleep_mod_flag;
29 | void putstr(char __code *cp);
30 | #define radio_busy 1
31 | extern void idle_pool();
32 |
33 | static unsigned char dummy_app(u8 v) { return 0; }
34 | unsigned char (* __data x_app) (u8 v) = dummy_app;
35 |
36 | static unsigned int __data last;
37 | static unsigned char __data tmp0;
38 | static unsigned char __data tmp1;
39 |
40 | //extern __bit rx_active;
41 |
42 | #ifndef SYSTEM_ATTRIBUTES
43 | #define SYSTEM_ATTRIBUTES 0
44 | #endif
45 | unsigned char __code system_attributes=SYSTEM_ATTRIBUTES;
46 |
47 | static void
48 | iretx() __naked
49 | {
50 | __asm;
51 | reti
52 | __endasm;
53 | }
54 |
55 | u8 app(u8 v) __naked
56 | {
57 | __asm;
58 | push _x_app
59 | push _x_app+1
60 | ret
61 | __endasm;
62 | }
63 |
64 | static u8 __data isr_save0;
65 | static u8 __data isr_save1;
66 | extern void sleep();
67 | //extern void rf_err_isr() __interrupt(0);
68 | #ifdef DRV_KEYS
69 | extern void t1_isr() __interrupt(9);
70 | extern void keys_on();
71 | #else
72 | void (* __pdata t1_vect) () = iretx;
73 | void t1_isr() __interrupt(9) __naked
74 | {
75 | __asm;
76 | mov _isr_save0, r0
77 | mov r0, #_t1_vect
78 | sjmp do_isr
79 | __endasm;
80 | }
81 | #endif
82 |
83 | void (* __pdata uart_rx_0_vect) () = iretx;
84 | void (* __pdata uart_rx_1_vect) () = iretx;
85 | void (* __pdata uart_tx_0_vect) () = iretx;
86 | void (* __pdata uart_tx_1_vect) () = iretx;
87 | void (* __pdata p0_vect) () = iretx;
88 | void (* __pdata p1_vect) () = iretx;
89 | void (* __pdata p2_vect) () = iretx;
90 | void (* __pdata t2_vect) () = iretx;
91 | void (* __pdata t3_vect) () = iretx;
92 | void (* __pdata t4_vect) () = iretx;
93 | void (* __pdata adc_vect) () = iretx;
94 | void (* __pdata aec_vect) () = iretx;
95 | void (* __pdata dma_vect) () = iretx;
96 | void uart_rx_0_isr() __interrupt(2) __naked
97 | {
98 | __asm;
99 | mov _isr_save0, r0
100 | mov r0, #_uart_rx_0_vect
101 | do_isr: mov _isr_save1, a
102 | movx a, @r0
103 | push acc
104 | inc r0
105 | movx a, @r0
106 | push acc
107 | mov r0, _isr_save0
108 | mov a, _isr_save1
109 |
110 | ret
111 | __endasm;
112 | }
113 | void uart_rx_1_isr() __interrupt(3) __naked
114 | {
115 | __asm;
116 | mov _isr_save0, r0
117 | mov r0, #_uart_rx_1_vect
118 | sjmp do_isr
119 | __endasm;
120 | }
121 | void uart_tx_0_isr() __interrupt(7) __naked
122 | {
123 | __asm;
124 | mov _isr_save0, r0
125 | mov r0, #_uart_tx_0_vect
126 | sjmp do_isr
127 | __endasm;
128 | }
129 | void uart_tx_1_isr() __interrupt(14) __naked
130 | {
131 | __asm;
132 | mov _isr_save0, r0
133 | mov r0, #_uart_tx_1_vect
134 | sjmp do_isr
135 | __endasm;
136 | }
137 | void p0_isr() __interrupt(13) __naked
138 | {
139 | __asm;
140 | mov _isr_save0, r0
141 | mov r0, #_p0_vect
142 | sjmp do_isr
143 | __endasm;
144 | }
145 | void p1_isr() __interrupt(15) __naked
146 | {
147 | __asm;
148 | mov _isr_save0, r0
149 | mov r0, #_p1_vect
150 | sjmp do_isr
151 | __endasm;
152 | }
153 | void p2_isr() __interrupt(6) __naked
154 | {
155 | __asm;
156 | mov _isr_save0, r0
157 | mov r0, #_p2_vect
158 | sjmp do_isr
159 | __endasm;
160 | }
161 | void t2_isr() __interrupt(10) __naked
162 | {
163 | __asm;
164 | mov _isr_save0, r0
165 | mov r0, #_t2_vect
166 | sjmp do_isr
167 | __endasm;
168 | }
169 | void t3_isr() __interrupt(11) __naked
170 | {
171 | __asm;
172 | mov _isr_save0, r0
173 | mov r0, #_t3_vect
174 | sjmp do_isr
175 | __endasm;
176 | }
177 | void t4_isr() __interrupt(12) __naked
178 | {
179 | __asm;
180 | mov _isr_save0, r0
181 | mov r0, #_t4_vect
182 | sjmp do_isr
183 | __endasm;
184 | }
185 | void adc_isr() __interrupt(1) __naked
186 | {
187 | __asm;
188 | mov _isr_save0, r0
189 | mov r0, #_adc_vect
190 | sjmp do_isr
191 | __endasm;
192 | }
193 | void aec_isr() __interrupt(4) __naked
194 | {
195 | __asm;
196 | mov _isr_save0, r0
197 | mov r0, #_aec_vect
198 | sjmp do_isr
199 | __endasm;
200 | }
201 | void dma_isr() __interrupt(8) __naked
202 | {
203 | __asm;
204 | mov _isr_save0, r0
205 | mov r0, #_dma_vect
206 | sjmp do_isr
207 | __endasm;
208 | }
209 |
210 | #ifdef DRV_DAYLIGHT
211 | unsigned char
212 | daylight() __naked
213 | {
214 | __asm;
215 | clr a
216 | jb P0.7, 0001$
217 | inc a
218 | 0001$:
219 | mov dpl, a
220 | ret
221 | __endasm;
222 | }
223 | #endif
224 |
225 | static void
226 | xxxx_sleep() __naked
227 | {
228 | __asm;
229 | .odd
230 | _sleep:
231 | mov PCON, _enter_sleep_mod_flag
232 | nop
233 | ret
234 | __endasm;
235 | }
236 | void
237 | start_timer(unsigned int v) __naked
238 | {
239 | __asm;
240 | mov a, _ST0
241 | mov b, a
242 | mov a, _ST1
243 | mov _last, a
244 | add a, dpl
245 | mov dpl, a
246 | mov a, _ST2
247 | mov _last+1, a
248 | addc a, dph
249 | mov dph, a
250 | xxx: mov a, _STLOAD
251 | jnb a.0, xxx
252 | mov _ST2, dph
253 | mov _ST1, dpl
254 | mov a, b
255 | mov _ST0, a
256 | setb _STIE
257 | ret
258 | __endasm;
259 | }
260 |
261 | unsigned int
262 | get_timer() __naked
263 | {
264 | __asm;
265 | mov a, _ST0
266 | mov dpl, _ST1
267 | mov dph, _ST2
268 | ret
269 | __endasm;
270 | }
271 |
272 | unsigned int
273 | stop_timer() __naked
274 | {
275 | __asm;
276 | clr _STIE
277 | mov a, _ST0
278 | clr c
279 | mov a, _ST1
280 | subb a, _last
281 | mov dpl, a
282 | mov a, _ST2
283 | subb a, _last+1
284 | mov dph, a
285 | ret
286 | __endasm;
287 | }
288 |
289 | unsigned int
290 | save_timer() __naked
291 | {
292 | __asm;
293 | mov a, _ST0
294 | clr c
295 | mov a, _ST1
296 | mov r0, a
297 | subb a, _last
298 | mov dpl, a
299 | mov _last, r0
300 | mov a, _ST2
301 | mov r0, a
302 | subb a, _last+1
303 | mov dph, a
304 | mov _last+1, r0
305 | ret
306 | __endasm;
307 | }
308 |
309 | void sleep_isr() __interrupt(5) __naked
310 | {
311 | __asm;
312 | clr _STIE
313 | clr _STIF
314 | mov _enter_sleep_mod_flag, #0
315 | reti
316 | __endasm;
317 | }
318 |
319 | void putchar(char c) __naked
320 | {
321 | __asm;
322 | push ACC
323 | mov _U0DBUF, dpl // U0DBUF = c;
324 | 0004$: mov a, _U0CSR
325 | jb _ACC_0, 0004$
326 | pop ACC
327 | ret
328 | __endasm;
329 | }
330 | void
331 | putstr(char __code *cp) __naked
332 | {
333 | __asm;
334 | 0001$: // for (;;) {
335 | clr a
336 | movc a, @a+dptr// // c = *cp++;
337 | inc dptr
338 | jnz 0002$ // if (!c) break;
339 | ret
340 | 0002$: cjne a, #'\n', 0003$ // if (*cp == '\n') {
341 | mov _U0DBUF, #13 // U0DBUF = 13;
342 | 0004$: mov a, _U0CSR
343 | jb _ACC_0, 0004$
344 | mov _U0DBUF, #10 // U0DBUF = 10;
345 | 0014$: mov a, _U0CSR
346 | jb _ACC_0, 0014$
347 | sjmp 0001$
348 | 0003$: // } else {
349 | mov _U0DBUF, a // U0DBUF = c;
350 | 0034$: mov a, _U0CSR
351 | jb _ACC_0, 0034$
352 | sjmp 0001$ // }
353 | __endasm; // }
354 | }
355 | void
356 | puthex(unsigned char v) __naked
357 | {
358 | __asm;
359 | mov a, dpl
360 | swap a
361 | anl a, #0xf // i = (v>>4)&0xf;
362 | cjne a, #9, 0001$ // if (i <= 9) {
363 | 0002$:
364 | add a, #'0' // i += '0'
365 |
366 | sjmp 0003$ // } else {
367 | 0001$: jc 0002$
368 | add a, #'a'-10// i += 'a'-10
369 | // }
370 | 0003$: mov _U0DBUF, a // putchar(i);
371 | 0094$: mov a, _U0CSR
372 | jb _ACC_0, 0094$
373 |
374 | 0024$:
375 | mov a, dpl
376 | anl a, #0xf // i = v&0xf;
377 | cjne a, #9, 0011$ // if (i <= 9) {
378 | 0012$:
379 | add a, #'0' // i += '0'
380 |
381 | sjmp 0013$ // } else {
382 | 0011$: jc 0012$
383 | add a, #'a'-10// i += 'a'-10
384 | // }
385 | 0013$: mov _U0DBUF, a // putchar(i);
386 | 0084$: mov a, _U0CSR
387 | jb _ACC_0, 0084$
388 | ret
389 | __endasm;
390 | }
391 |
392 | void dump_wait_list(char __code *cp) __naked
393 | {
394 | #ifdef TDEBUG
395 | __asm;
396 | lcall _putstr
397 | mov dpl, _waitq
398 | mov dph, _waitq+1
399 | 0001$:
400 | mov a, dpl
401 | orl a, dph
402 | jnz 0002$
403 | mov _U0DBUF, #13
404 | 0032$: mov a, _U0CSR
405 | jb _ACC_0, 0032$
406 | mov _U0DBUF, #10
407 | 0033$: mov a, _U0CSR
408 | jb _ACC_0, 0033$
409 | ret
410 | 0002$: push dpl
411 | push dph
412 | push dpl
413 | mov _U0DBUF, #'('
414 | 0034$: mov a, _U0CSR
415 | jb _ACC_0, 0034$
416 | mov dpl, dph
417 | lcall _puthex
418 | pop dpl
419 | lcall _puthex
420 | mov _U0DBUF, #','
421 | 0035$: mov a, _U0CSR
422 | jb _ACC_0, 0035$
423 |
424 | // pop dph
425 | // pop dpl
426 | // push dpl
427 | // push dph
428 | // movx a, @dptr
429 | // push acc
430 | // inc dptr
431 | // movx a, @dptr
432 | // mov dpl, a
433 | // lcall _puthex
434 | // pop dpl
435 | // lcall _puthex
436 | //
437 | // mov _U0DBUF, #','
438 | //0135$: mov a, _U0CSR
439 | // jb _ACC_0, 0135$
440 |
441 | pop dph
442 | pop dpl
443 | inc dptr
444 | inc dptr
445 | movx a, @dptr
446 | inc dptr
447 | push acc
448 | movx a, @dptr
449 | inc dptr
450 | push dpl
451 | push dph
452 | mov dpl, a
453 | lcall _puthex
454 | pop dph
455 | pop dpl
456 | pop acc
457 | push dpl
458 | push dph
459 | mov dpl, a
460 | lcall _puthex
461 | pop dph
462 | pop dpl
463 | mov _U0DBUF, #')'
464 | 0036$: mov a, _U0CSR
465 | jb _ACC_0, 0036$
466 | movx a, @dptr
467 | push acc
468 | inc dptr
469 | movx a, @dptr
470 | mov dph, a
471 | pop dpl
472 | ljmp 0001$
473 | __endasm;
474 | #endif
475 | }
476 |
477 | void
478 | wait_us(unsigned char t)
479 | {
480 | while (t--) {
481 | __asm
482 | nop
483 | nop
484 | nop
485 | nop
486 | nop
487 | nop
488 | nop
489 | nop
490 | __endasm;
491 | }
492 | }
493 |
494 | void queue_task_0(task __xdata * t) __naked // for ISRs - save param so we don't trash global
495 | {
496 | __asm;
497 | mov r0, #_queue_task_PARM_2
498 | movx a, @r0
499 | push ACC
500 | clr a
501 | movx @r0, a
502 | inc r0
503 | movx a, @r0
504 | push ACC
505 | clr a
506 | movx @r0, a
507 | acall _queue_task
508 | mov r0, #_queue_task_PARM_2+1
509 | pop ACC
510 | movx @r0, a
511 | dec r0
512 | pop ACC
513 | movx @r0, a
514 | ret
515 | __endasm;
516 | }
517 |
518 | void
519 | queue_task(task __xdata * t, unsigned int time) __naked
520 | {
521 | __asm;
522 | #ifdef TDEBUG
523 | push dpl
524 | push dph
525 | push dpl
526 | push dph
527 | movx a, @dptr
528 | push acc
529 | inc dptr
530 | movx a, @dptr
531 | push acc
532 | sjmp 0101$
533 | 0102$: .ascii "queue "
534 | .db 0
535 | 0103$: .ascii " "
536 | .db 0
537 | 0101$: mov dptr, #0102$
538 | lcall _putstr
539 | pop dpl
540 | lcall _puthex
541 | pop dpl
542 | lcall _puthex
543 | mov dpl, #' '
544 | lcall _putchar
545 | pop dpl
546 | lcall _puthex
547 | pop dpl
548 | lcall _puthex
549 |
550 | mov dpl, #' '
551 | lcall _putchar
552 | mov r0, #_queue_task_PARM_2+1
553 | movx a, @r0
554 | mov dpl, a
555 | lcall _puthex
556 | mov r0, #_queue_task_PARM_2
557 | movx a, @r0
558 | mov dpl, a
559 | lcall _puthex
560 | mov dptr, #0103$
561 | lcall _dump_wait_list
562 | pop dph
563 | pop dpl
564 | #endif
565 | mov r4, dpl
566 | mov r5, dph // t
567 | push _IEN0
568 | clr EA
569 | acall _save_timer// delta = stop_timer()
570 | mov a, dpl // delta
571 | mov r6, a
572 | mov r7, dph
573 | #ifdef TDEBUG
574 | push acc
575 | lcall xlog6
576 | pop acc
577 | #endif
578 | mov _enter_sleep_mod_flag, #0 // enter_sleep_mod_flag = 0;
579 | // for (pt = waitq; delta && pt; pt = pt->next) {
580 | // if (pt->time > delta) {
581 | // pt->time -= delta;
582 | // break;
583 | // }
584 | // delta -= pt->time;
585 | // pt->time = 0;
586 | // enter_sleep_mod_flag = 0;
587 | // }
588 | orl a, r7 // for (;;) {
589 | jz qt_2 // if (!delta) break
590 | mov a, _waitq
591 | mov dpl, a
592 | mov dph, _waitq+1
593 | orl a, dph
594 | jz qt_2
595 | qt_1: // a contains dpl
596 | inc dptr
597 | inc dptr // points at time
598 | movx a, @dptr
599 | mov _DPL1, dpl
600 | mov _DPH1, dph
601 | clr c
602 | subb a, r6
603 | mov r2, a
604 | inc dptr
605 | movx a, @dptr
606 | subb a, r7
607 | inc _DPS
608 | jc qt_3 // if (pt->time > delta)
609 | mov r0, a // pt->time -= delta;
610 | mov a, r2
611 | movx @dptr, a
612 | inc dptr
613 | mov a, r0
614 | movx @dptr, a
615 | dec _DPS
616 | sjmp qt_2
617 | qt_3: mov r3, a
618 | clr a // pt->time = 0;
619 | movx @dptr, a
620 | inc dptr
621 | movx @dptr, a
622 | inc dptr
623 |
624 | //mov _enter_sleep_mod_flag, #0 // enter_sleep_mod_flag = 0;
625 | subb a, r2 // delta -= pt->time;
626 | mov r6, a
627 | clr a
628 | subb a, r3
629 | mov r7, a
630 | movx a, @dptr// pt = pt->next
631 | mov r0, a
632 | inc dptr
633 | mov _DPL0, a
634 | movx a, @dptr
635 | mov _DPH0, a
636 | dec _DPS
637 | orl a, r0 // if pt == null break
638 | jz qt_2
639 | mov a, r6
640 | orl a, r7
641 | jnz qt_1
642 | qt_2:
643 | // if (t->state == TASK_QUEUED) {
644 | // t->state = TASK_IDLE;
645 | // pt = waitq;
646 | // ptp = &waitq;
647 | // for (;;) {
648 | // if (pt == t) {
649 | // if ((*ptp = pt = t->next) != 0)
650 | // pt->time += t->time;
651 | // break;
652 | // }
653 | // ptp = &pt->next;
654 | // pt = *ptp;
655 | // }
656 | // }
657 |
658 | mov a, r4 // if (t->state == TASK_QUEUED)
659 | add a, #6
660 | mov dpl, a
661 | mov a, r5
662 | addc a, #0
663 | mov dph, a
664 | movx a, @dptr
665 | cjne a, #TASK_QUEUED, qt_4
666 | mov a, #TASK_IDLE // t->state = TASK_IDLE;
667 | movx @dptr, a
668 | mov r2, #0
669 | mov r0, _waitq // for (pt = waitq;;) {
670 | mov r1, _waitq+1
671 | qt_5:
672 | mov a, r0 // if (pt == t) {
673 | cjne a, ar4, qt_6
674 | mov a, r1
675 | cjne a, ar5, qt_6
676 | mov dpl, r4
677 | mov dph, r5
678 | inc dptr
679 | inc dptr
680 | movx a, @dptr // r1:r0 = t->time
681 | inc dptr
682 | mov r0, a
683 | movx a, @dptr
684 | inc dptr
685 | mov r1, a
686 |
687 | movx a, @dptr // pt = dptr0 = t->next
688 | inc dptr
689 | mov r3, a
690 | movx a, @dptr
691 | mov dph, a
692 | mov dpl, r3
693 |
694 | cjne r2, #0, qt_8 // if (prev)
695 | //mov _enter_sleep_mod_flag, #0 // enter_sleep_mod_flag = 0;
696 | mov _waitq, dpl // waitq = dptr0
697 | mov _waitq+1, dph
698 | sjmp qt_9 // else
699 | qt_8:
700 | inc _DPS
701 | mov a, _DPL0 // prev->next = dptr0
702 | movx @dptr, a
703 | inc dptr
704 | mov a, _DPH0
705 | movx @dptr, a
706 | dec _DPS
707 | qt_9:
708 | mov a, dpl
709 | orl a, dph
710 | jz qt_4
711 | inc dptr
712 | inc dptr
713 | movx a, @dptr // pt->time += t->time;
714 | add a, r0
715 | movx @dptr, a
716 | inc dptr
717 | movx a, @dptr
718 | addc a, r1
719 | movx @dptr, a
720 | sjmp qt_4
721 |
722 | qt_6:
723 | mov r2, #1
724 | mov dpl, r0
725 | mov dph, r1
726 | inc dptr
727 | inc dptr
728 | inc dptr
729 | inc dptr
730 | mov _DPL1, dpl // prev = pt
731 | mov _DPH1, dph
732 | movx a, @dptr // pt = pt->next
733 | mov r0, a
734 | inc dptr
735 | movx a, @dptr //}
736 | mov r1, a
737 | sjmp qt_5
738 | qt_4:
739 | // ptp = &waitq;
740 | // pt = waitq;
741 | // for (;;) {
742 | // while (pt && pt->time == 0) {
743 | // ptp = &pt->next;
744 | // pt = *ptp;
745 | // }
746 | // if (!pt) {
747 | // t->time = time;
748 | // t->next = 0;
749 | // t->state = TASK_QUEUED;
750 | // *ptp = t;
751 | // break;
752 | // }
753 | // if (pt->time <= time) {
754 | // time -= pt->time;
755 | // ptp = &pt->next;
756 | // pt = *ptp;
757 | // continue;
758 | // }
759 | // pt->time -= time;
760 | // t->time = time;
761 | // t->next = pt;
762 | // *ptp = t;
763 | // t->state = TASK_QUEUED;
764 | // break;
765 | // }
766 | mov dpl, _waitq // pt = waitq
767 | mov dph, _waitq+1
768 | mov r2, #0 // prev marked invalid
769 | qt_11: // for (;;) {
770 | mov r6, dpl // save pt in r7:r6
771 | mov r7, dph
772 | mov a, r6 //
773 | orl a, r7 // if (!pt) break;
774 | jz qt_12
775 |
776 |
777 | inc dptr // if (pt->time != 0) break;
778 | inc dptr
779 | movx a, @dptr
780 | mov r3, a
781 | inc dptr
782 | movx a, @dptr
783 | orl a, r3
784 | jnz qt_13
785 |
786 | mov r2, #1 // mark prev valid
787 | inc dptr
788 | mov _DPL1, dpl // prev = &pt->next
789 | mov _DPH1, dph
790 | movx a, @dptr // pt = pt->next
791 | mov r3, a
792 | inc dptr
793 | movx a, @dptr
794 | mov dph, a
795 | mov dpl, r3
796 | sjmp qt_11 // }
797 | qt_12: // if (pt == 0) { // end of Q
798 |
799 | qt_99:
800 | #ifdef TDEBUG
801 | //lcall xlog3
802 | //lcall xlog4
803 | push dpl
804 | push dph
805 | mov dptr, #i0033
806 | lcall _dump_wait_list
807 | pop dph
808 | pop dpl
809 | #endif
810 | cjne r2, #0, qt_14 // if (prev) {
811 | //mov _enter_sleep_mod_flag, #0 // enter_sleep_mod_flag = 0;
812 | mov _waitq, r4 // waitq = t
813 | mov _waitq+1, r5 //
814 | sjmp qt_15
815 | qt_14: // } else {
816 | inc _DPS
817 | mov a, r4
818 | movx @dptr, a // *prev = t
819 | inc dptr
820 | mov a, r5
821 | movx @dptr, a
822 | dec _DPS // }
823 | qt_15: mov dpl, r4 // dptr = t
824 | mov dph, r5
825 | inc dptr
826 | inc dptr
827 | mov r0, #_queue_task_PARM_2 // t->time = time;
828 | movx a, @r0
829 | movx @dptr, a
830 | inc dptr
831 | inc r0
832 | movx a, @r0
833 | movx @dptr, a
834 | inc dptr
835 | mov a, r6
836 | movx @dptr, a // t->next = next;
837 | inc dptr
838 | mov a, r7
839 | movx @dptr, a
840 | inc dptr
841 | mov a, #TASK_QUEUED // t->state = TASK_QUEUED;
842 | movx @dptr, a
843 | #ifdef TDEBUG
844 | sjmp $0064
845 | $0063: .ascii " post-queue "
846 | .db 0
847 | $0064:
848 | mov dptr, #$0063
849 | lcall _dump_wait_list
850 | #endif
851 | pop _IEN0
852 | ret // return
853 | // }
854 | qt_13:
855 | mov dpl, r6 //
856 | mov dph, r7
857 | inc dptr
858 | inc dptr
859 | clr c
860 | mov r0, #_queue_task_PARM_2
861 | movx a, @r0
862 | mov r1, a
863 | movx a, @dptr
864 | subb a, r1 // tmp1:0 = pt->time - time
865 | inc dptr
866 | mov _tmp0, a
867 | inc r0
868 | movx a, @r0
869 | mov r1, a
870 | movx a, @dptr
871 | subb a, r1
872 | mov _tmp1, a
873 | jc qt_98 // if pt->time was >= time (must insert t prior to pt)
874 | mov dpl, r6
875 | mov dph, r7
876 | inc dptr
877 | inc dptr
878 | mov a, _tmp0 // pt->time = p->time - time
879 | movx @dptr, a
880 | inc dptr
881 | mov a, _tmp1
882 | movx @dptr, a // t->time = time
883 | ajmp qt_99
884 |
885 | // if (pt->time <= time) {
886 | // time -= pt->time;
887 | // ptp = &pt->next;
888 | // pt = *ptp;
889 | // continue;
890 | // }
891 | qt_98:
892 | dec r0
893 | clr a
894 | clr c
895 | subb a, _tmp0 // time = -tmp //
896 | movx @r0, a //
897 | inc r0
898 | clr a
899 | subb a, _tmp1
900 | movx @r0, a
901 | inc dptr
902 | mov _DPL1, dpl // prev = &pt->next
903 | mov _DPH1, dph
904 | movx a, @dptr // pt = pt->next
905 | mov r0, a
906 | inc dptr
907 | movx a, @dptr
908 | mov dpl, r0
909 | mov dph, a
910 | mov r2, #1
911 | ajmp qt_11 //}
912 |
913 | #ifdef TDEBUG
914 | xlog6:
915 | push dpl
916 | push dph
917 | mov dptr, #0157$
918 | lcall _putstr
919 | mov dpl, r7
920 | lcall _puthex
921 | mov dpl, r6
922 | lcall _puthex
923 | pop dph
924 | pop dpl
925 | ret
926 | 0157$: .ascii "timer "
927 | .db 0
928 | xlog3:
929 | push dpl
930 | push dph
931 | mov dptr, #0152$
932 | lcall _putstr
933 | mov dpl, r5
934 | lcall _puthex
935 | mov dpl, r4
936 | lcall _puthex
937 | pop dph
938 | pop dpl
939 | ret
940 | 0152$: .ascii "r5/4 "
941 | .db 0
942 | xlog4:
943 | push dpl
944 | push dph
945 | mov dptr, #0153$
946 | lcall _putstr
947 | mov dpl, r7
948 | lcall _puthex
949 | mov dpl, r6
950 | lcall _puthex
951 | pop dph
952 | pop dpl
953 | ret
954 | 0153$: .ascii "r7/6 "
955 | .db 0
956 | i0033: //.db 0x0a
957 | .ascii "pre-queue "
958 | .db 0
959 | #endif
960 |
961 |
962 | __endasm;
963 | }
964 |
965 | void
966 | cancel_task(task __xdata* t) __naked
967 | {
968 | __asm;
969 | #ifdef TDEBUG
970 | push dpl
971 | push dph
972 | push dpl
973 | push dph
974 | sjmp 0201$
975 | 0202$: .ascii "cancel "
976 | .db 0
977 | 0203$: .ascii " "
978 | .db 0
979 | 0201$: mov dptr, #0202$
980 | lcall _putstr
981 | pop dpl
982 | lcall _puthex
983 | pop dpl
984 | lcall _puthex
985 | mov dptr, #0203$
986 | lcall _dump_wait_list
987 | pop dph
988 | pop dpl
989 | #endif
990 | mov r6, dpl //
991 | mov r7, dph
992 |
993 | push _IEN0 // s=EA;
994 | clr EA // EA = 0;
995 | mov r2, #0
996 | mov dpl, _waitq // pt = waitq;
997 | mov dph, _waitq+1
998 | // ptp = &waitq;
999 | ct_1: // for (;;) {
1000 | //
1001 | mov a, r6
1002 | cjne a, dpl, ct_2 // if (pt == t) {
1003 | mov a, r7
1004 | cjne a, dph, ct_2
1005 | inc dptr
1006 | inc dptr
1007 | movx a, @dptr // r1:r0 = t->time
1008 | mov r0, a
1009 | inc dptr
1010 | movx a, @dptr
1011 | mov r1, a
1012 | inc dptr
1013 | movx a, @dptr // pt = t->next
1014 | mov r4, a
1015 | inc dptr
1016 | movx a, @dptr
1017 | mov r5, a
1018 | inc dptr
1019 | mov a, #TASK_IDLE // t->state = T_IDLE
1020 | movx @dptr, a
1021 |
1022 | cjne r4, #0, ct_6 // if (pt) {
1023 | cjne r5, #0, ct_6
1024 | sjmp ct_3
1025 | ct_6: mov dpl, r4
1026 | mov dph, r5
1027 | inc dptr
1028 | inc dptr // pt->time += t->time;
1029 | movx a, @dptr
1030 | add a, r0
1031 | movx @dptr, a
1032 | inc dptr
1033 | movx a, @dptr
1034 | addc a, r1
1035 | movx @dptr, a
1036 | ct_3: // }
1037 | cjne r2, #0, ct_8 // *prev = pt
1038 | mov _waitq, r4 // waitq = dptr0
1039 | mov _waitq+1, r5
1040 | pop _IEN0 // EA = s;
1041 | ret
1042 | ct_8: inc _DPS
1043 | mov a, r4 // prev->next = dptr0
1044 | movx @dptr, a
1045 | inc dptr
1046 | mov a, r5
1047 | movx @dptr, a
1048 | dec _DPS
1049 | ct_9: pop _IEN0 // EA = s;
1050 | ret
1051 |
1052 | // }
1053 |
1054 | ct_2:
1055 |
1056 | #ifdef TDEBUG
1057 | push dpl
1058 | push dph
1059 | push dpl
1060 | mov dpl, dph
1061 | lcall _puthex
1062 | pop dpl
1063 | lcall _puthex
1064 | mov dpl, #13 // U0DBUF = c;
1065 | lcall _putchar
1066 | mov dpl, #10 // U0DBUF = c;
1067 | lcall _putchar
1068 | pop dph
1069 | pop dpl
1070 | #endif
1071 |
1072 | mov a, dpl
1073 | orl a, dph
1074 | jz ct_9
1075 |
1076 | inc dptr
1077 | inc dptr
1078 | inc dptr
1079 | inc dptr
1080 | mov _DPL1, dpl // prev = &pt->next
1081 | mov _DPH1, dph
1082 | movx a, @dptr // pt = pt->next
1083 | inc dptr
1084 | mov r2, a
1085 | movx a, @dptr
1086 | mov dph, a
1087 | mov dpl, r2
1088 | mov r2, #1
1089 | ajmp ct_1 // }
1090 | __endasm;
1091 | }
1092 |
1093 | #ifdef TASK_TEST
1094 | static unsigned char __xdata rgb[6]={0,0,0,0,0,0};
1095 | static void test(task __xdata*t);
1096 | static __xdata task test_task = {test,0,0,0};
1097 | static void test(task __xdata*t)
1098 | {
1099 | rgb[0]+=16;
1100 | rgb[1]+=16;
1101 | send_RGB(&rgb[0]);
1102 | putstr("1");
1103 | queue_task(&test_task, HZ);
1104 |
1105 | }
1106 | static void test2(task __xdata*t);
1107 | static __xdata task test_task2 = {test2,0,0,0};
1108 | static void test2(task __xdata*t)
1109 | {
1110 | putstr("2");
1111 | rgb[2]+=64;
1112 | rgb[3]+=64;
1113 | send_RGB(&rgb[0]);
1114 | queue_task(&test_task2, 2*HZ);
1115 | }
1116 | static void test3(task __xdata*t);
1117 | static __xdata task test_task3 = {test3,0,0,0};
1118 | static void test3(task __xdata*t)
1119 | {
1120 | putstr("3");
1121 | rgb[4]-=32;
1122 | rgb[5]-=32;
1123 | send_RGB(&rgb[0]);
1124 | queue_task(&test_task3, 5*HZ/2);
1125 | }
1126 | #endif
1127 |
1128 | void
1129 | uart_init() __naked
1130 | {
1131 | __asm;
1132 | orl _P0DIR, #0x08
1133 | orl _P0SEL, #0x08 // p0.3 out - TXD
1134 | mov _U0CSR, #0x80
1135 | mov _U0GCR, #0x08
1136 | mov _U0BAUD, #59
1137 | mov _U0CSR, #0x80
1138 | //U0UCR = 0x82;
1139 | mov _U0UCR, #0x86
1140 | mov _UTX0IF, #0
1141 | ret
1142 | __endasm;
1143 | }
1144 |
1145 | void
1146 | main()
1147 | {
1148 | EA = 0;
1149 | sys_active = 0;
1150 | //
1151 | CLKCONCMD=0x80; // 32MHz ext, int 32khz
1152 | while (CLKCONSTA != 0x80)
1153 | ;
1154 | P1 = 0;
1155 | P1DIR = 0xc1;
1156 | P0DIR = 0x00;
1157 | P0SEL = 0;
1158 | P1SEL = 0;
1159 | P2SEL = 0;
1160 | P2DIR = 0;
1161 | PERCFG = 0;
1162 | //
1163 | // sleep timer
1164 | //
1165 | ST2 = 0;
1166 | {
1167 | extern code_hdr __code CODE_HEADER;
1168 | x_app = (unsigned char (* __data ) (u8))(&CODE_HEADER.data[0]);
1169 | }
1170 | #ifdef TDEBUG
1171 | uart_init();
1172 | putstr("calling suota_setup ...\n");
1173 | #endif
1174 | //suota_setup();
1175 | // rf_init();
1176 | #ifdef TDEBUG
1177 | putstr("calling APP_INIT ...\n");
1178 | #endif
1179 | app(APP_INIT);
1180 | #ifdef TDEBUG
1181 | putstr("return APP_INIT ...\n");
1182 | #endif
1183 | #ifdef XMT
1184 | queue_task(&test_task4, 1*HZ);
1185 | #endif
1186 | #ifdef TASK_TEST
1187 | queue_task(&test_task, 1*HZ);
1188 | queue_task(&test_task2, 2*HZ);
1189 | queue_task(&test_task3, 3*HZ);
1190 | #endif
1191 | __asm;
1192 | .globl _restart_point
1193 | _restart_point:
1194 | mov r6, #0 // delta = 0;
1195 | mov r7, #0
1196 | m_1: // for (;;) {
1197 | distribute:
1198 | #ifdef TDEBUG
1199 | sjmp 0707$
1200 | 0706$: .ascii "."
1201 | .db 0
1202 | 0707$: mov dptr, #0706$
1203 | lcall _dump_wait_list
1204 | #endif
1205 | mov dpl, _waitq // for (xpt = waitq;;) {
1206 | mov dph, _waitq+1
1207 | m_2: mov a, dph
1208 | m_2a: orl a, dpl
1209 | jz m_4
1210 | cjne r6, #0, m_5// if (!delta) break
1211 | cjne r7, #0, m_5
1212 | sjmp m_4
1213 | m_5: inc dptr
1214 | inc dptr
1215 | clr c
1216 | movx a, @dptr// delta = xpt->time = xpt->time-delta
1217 | subb a, r6
1218 | movx @dptr, a
1219 | mov r6, a
1220 | inc dptr
1221 | movx a, @dptr
1222 | subb a, r7
1223 | jc m_6 // if (xpt->time >= delta) {
1224 | movx @dptr, a// xpt->time -= delta;
1225 | sjmp m_4// break;
1226 | // }
1227 | m_6: mov r7, a
1228 | clr a
1229 | movx @dptr, a// xpt->time = 0;
1230 | dec dpl
1231 | mov r0, dpl
1232 | cjne r0, #0xff, m_6a
1233 | dec dph
1234 | m_6a: movx @dptr, a
1235 | clr c
1236 | subb a, r6 // delta = -delta
1237 | mov r6, a
1238 | clr a
1239 | subb a, r7
1240 | mov r7, a
1241 | inc dptr
1242 | inc dptr
1243 | movx a, @dptr// xpt = xpt->next
1244 | mov r0, a
1245 | inc dptr
1246 | movx a, @dptr
1247 | mov dpl, r0
1248 | mov dph, a
1249 | sjmp m_2a // }
1250 | m_4: // for (;;) {
1251 | #ifdef TDEBUG
1252 | sjmp 0717$
1253 | 0716$: .ascii "-"
1254 | .db 0
1255 | 0717$: mov dptr, #0716$
1256 | lcall _dump_wait_list
1257 | #endif
1258 | mov dpl, _waitq // xpt = waitq;
1259 | mov dph, _waitq+1
1260 | mov a, dpl // if (!xpt) break
1261 | orl a, dph
1262 | jz m_8
1263 | mov r6, dpl
1264 | mov r7, dph
1265 | inc dptr // if (xpt->time != 0) break
1266 | inc dptr
1267 | movx a, @dptr
1268 | cjne a, #0, m_8
1269 | inc dptr
1270 | movx a, @dptr
1271 | cjne a, #0, m_8
1272 | #ifdef TDEBUG
1273 | lcall xlog1
1274 | #endif
1275 | push dpl
1276 | push dph
1277 | mov dpl, #0xff // start_timer(60000);
1278 | mov dph, #0xfe
1279 | acall _start_timer
1280 | pop dph
1281 | pop dpl
1282 | inc dptr // waitq = xpt->next;
1283 | movx a, @dptr
1284 | mov _waitq, a
1285 | inc dptr
1286 | movx a, @dptr
1287 | mov _waitq+1, a
1288 | inc dptr
1289 | mov a, #TASK_CALLOUT// xpt->state = TASK_CALLOUT;
1290 | movx @dptr, a
1291 | setb EA // EA = 1;
1292 | push dpl
1293 | push dph
1294 |
1295 | mov a, #m_ret
1296 | push acc
1297 | mov a, #m_ret>>8
1298 | push acc
1299 | mov dpl, r6 // xpt->callout(xpt);
1300 | mov dph, r7
1301 | movx a, @dptr
1302 | push acc
1303 | inc dptr
1304 | movx a, @dptr
1305 | push acc
1306 | mov dpl, r6
1307 | mov dph, r7
1308 | ret
1309 | m_ret:
1310 | #ifdef TDEBUG
1311 | lcall xlog2
1312 | #endif
1313 | pop dph
1314 | pop dpl
1315 | clr EA // EA = 0;
1316 | movx a, @dptr
1317 | cjne a, #TASK_CALLOUT, m_9// if (xpt->state == TASK_CALLOUT)
1318 | mov a, #TASK_IDLE// xpt->state = TASK_IDLE;
1319 | movx @dptr, a
1320 | m_9:
1321 | acall _stop_timer// delta = stop_timer();
1322 | mov r6, dpl
1323 | mov r7, dph
1324 | cjne r6, #0, m_9a// if (delta)
1325 | cjne r7, #0, m_9a// goto distribute;
1326 | sjmp m_4 // }
1327 | m_9a:
1328 | ajmp distribute
1329 | m_8:
1330 | #ifdef TDEBUG
1331 | // lcall xlog5
1332 | #endif
1333 | mov a, _waitq // if (!waitq) {
1334 | orl a, _waitq+1
1335 | jnz m_10
1336 | mov _enter_sleep_mod_flag, #1//enter_sleep_mod_flag = 1;
1337 | // jb _rx_active, m_85
1338 | jb _sys_active, m_85
1339 |
1340 | mov a, _CLKCONSTA
1341 | anl a, #0x38 // tsaved = CLKCONSTA & TICKSPD_MASK
1342 | push acc
1343 | anl _CLKCONSTA, #~0x38 // CLKCONCMD &= ~TICKSPD_MASK;
1344 |
1345 | mov _SLEEPCMD, #5 // SLEEPCMD = PM1
1346 | setb EA // EA = 1;
1347 | m_81d: mov a, _enter_sleep_mod_flag
1348 | cjne a, #1, m_11c // while(enter_sleep_mod_flag)
1349 | lcall _idle_pool
1350 | //lcall _sleep // sleep();
1351 | sjmp m_81d
1352 |
1353 | m_81c: mov a, _CLKCONSTA // while ((CLKCONSTA & OSC) != CLKCONCMD_32MHZ);
1354 | jnb a.6, m_81c
1355 | pop acc
1356 | orl _CLKCONCMD, a // CLKCONCMD |= tsaved;
1357 | clr EA
1358 | //mov _rtx_key, #NO_CRYPTO // crypto key is invalidated in PM2
1359 | sjmp m_8x// EA = 0;
1360 |
1361 | m_85: mov _SLEEPCMD, #4 // SLEEPCMD = 4;//(radio_busy?0:2); IDLE
1362 | setb EA // EA = 1;
1363 | m_8b: mov a, _enter_sleep_mod_flag
1364 | cjne a, #1, m_8a // while(enter_sleep_mod_flag)
1365 | lcall _idle_pool
1366 | //acall _sleep // sleep();
1367 | sjmp m_8b
1368 | m_8a: clr EA // EA = 0;
1369 | m_8x: mov r6, #0 // delta = 0;
1370 | mov r7, #0
1371 | ajmp m_1
1372 |
1373 |
1374 | m_10: // } else {
1375 | #ifdef TDEBUG
1376 | mov a, _ST0
1377 | push _ST1
1378 | push _ST2
1379 | // lcall _puthex
1380 | // pop dpl
1381 | // lcall _puthex
1382 |
1383 | // lcall xlog5
1384 | #endif
1385 | mov dpl, _waitq
1386 | mov dph, _waitq+1
1387 | inc dptr
1388 | inc dptr
1389 | movx a, @dptr // if (!xpt->time) {
1390 | mov r0, a
1391 | inc dptr
1392 | movx a, @dptr
1393 | cjne a, #0, m_11
1394 | cjne r0, #0, m_11
1395 | #ifdef TDEBUG
1396 | pop ACC
1397 | pop ACC
1398 | #endif
1399 |
1400 | mov r6, #0 // delta = 0;
1401 | mov r7, #0
1402 | ljmp m_1
1403 |
1404 | m_11: // } else {
1405 | mov _enter_sleep_mod_flag, #1 // enter_sleep_mod_flag = 1;
1406 | mov dpl, r0
1407 | mov dph, a
1408 | // jb _rx_active, m_55
1409 | jb _sys_active, m_55
1410 |
1411 | mov a, _CLKCONSTA
1412 | anl a, #0x38 // tsaved = CLKCONSTA & TICKSPD_MASK
1413 | push acc
1414 | anl _CLKCONSTA, #~0x38 // CLKCONCMD &= ~TICKSPD_MASK;
1415 |
1416 | lcall _start_timer // start_timer(xpt->time);
1417 | mov _SLEEPCMD, #5 // SLEEPCMD = PM1
1418 | setb EA // EA = 1;
1419 | m_11d: mov a, _enter_sleep_mod_flag
1420 | cjne a, #1, m_11c // while(enter_sleep_mod_flag)
1421 | #ifdef NOTDEF
1422 | jnb _inSuspend, x_idle1
1423 | lcall _sleep // sleep();
1424 | sjmp m_11d
1425 | #endif
1426 | x_idle1: lcall _idle_pool
1427 | sjmp m_11d
1428 |
1429 | m_11c: mov a, _CLKCONSTA // while ((CLKCONSTA & OSC) != CLKCONCMD_32MHZ);
1430 | jnb a.6, m_11c
1431 | pop acc
1432 | orl _CLKCONCMD, a // CLKCONCMD |= tsaved;
1433 | clr EA // EA = 0;
1434 | //mov _rtx_key, #NO_CRYPTO // crypto key is invalidated in PM2
1435 | lcall _stop_timer // delta = stop_timer();
1436 | mov r6, dpl
1437 | mov r7, dph
1438 | sjmp m_56
1439 |
1440 |
1441 |
1442 | m_55:
1443 | lcall _start_timer // start_timer(xpt->time);
1444 | mov _SLEEPCMD, #4 // SLEEPCMD = IDLE
1445 | setb EA // EA = 1;
1446 | m_11b: mov a, _enter_sleep_mod_flag
1447 | cjne a, #1, m_11a // while(enter_sleep_mod_flag)
1448 | #ifdef NOTDEF
1449 | jnb _inSuspend, x_idle2
1450 | lcall _sleep // sleep();
1451 | sjmp m_11b
1452 | #endif
1453 | x_idle2: lcall _idle_pool
1454 | sjmp m_11b
1455 | m_11a: clr EA // EA = 0;
1456 | lcall _stop_timer // delta = stop_timer();
1457 | mov r6, dpl
1458 | mov r7, dph
1459 | m_56:
1460 | #ifdef TDEBUG
1461 | mov a, _ST0
1462 | push _ST1
1463 | mov dpl, _ST2
1464 | lcall _puthex // current time
1465 | pop dpl
1466 | lcall _puthex
1467 |
1468 | mov dpl, r7 // measured delta
1469 | lcall _puthex
1470 | mov dpl, r6
1471 | lcall _puthex
1472 | mov dpl, _last+1 // last time when we started
1473 | lcall _puthex
1474 | mov dpl, _last
1475 | lcall _puthex
1476 | pop dpl // measured same thing
1477 | lcall _puthex
1478 | pop dpl
1479 | lcall _puthex
1480 | mov dptr,#317$
1481 | lcall _putstr
1482 | #endif
1483 | ljmp m_1 // }
1484 | // }
1485 | //}
1486 | #ifdef TDEBUG
1487 | 0317$: .db 0x0a, 0
1488 | xlog1:
1489 | push dpl
1490 | push dph
1491 | mov dptr, #0102$
1492 | lcall _putstr
1493 | mov dpl, r7
1494 | lcall _puthex
1495 | mov dpl, r6
1496 | lcall _puthex
1497 | mov dptr, #0103$
1498 | lcall _dump_wait_list
1499 | pop dph
1500 | pop dpl
1501 | ret
1502 | 0102$: .ascii "call "
1503 | .db 0
1504 | 0103$: .ascii " "
1505 | .db 0
1506 | xlog2:
1507 | push dpl
1508 | push dph
1509 | mov dptr, #0202$
1510 | lcall _putstr
1511 | pop dph
1512 | pop dpl
1513 | ret
1514 | 0202$: .ascii "done"
1515 | 0203$: .db 0x0a, 0
1516 | xlog5:
1517 | push dpl
1518 | push dph
1519 | mov dptr, #0312$
1520 | lcall _dump_wait_list
1521 | pop dph
1522 | pop dpl
1523 | ret
1524 | 0312$: .ascii "sleeping "
1525 | 0313$: .db 0x0a, 0
1526 | #endif
1527 | __endasm;
1528 | }
1529 |
--------------------------------------------------------------------------------
/manufacturing.c:
--------------------------------------------------------------------------------
1 | // (c) Copyright Paul Campbell paul@taniwha.com 2015
2 | //
3 | // This library is free software; you can redistribute it and/or
4 | // modify it under the terms of the GNU Lesser General Public
5 | // License as published by the Free Software Foundation; either
6 | // version 2.1 of the License, or (at your option) version 3, or any
7 | // later version accepted by Paul Campbell , who shall
8 | // act as a proxy defined in Section 6 of version 3 of the license.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library. If not, see .
17 | //
18 |
19 | //
20 | // Manufacturing test
21 | //
22 | // this file generates a stream of bits on P2.1 (the debug data pin) describing
23 | // the results of self test - (valid CRC, active RNG)
24 | // this provide no more useful information to an outside snooper
25 | // other than "the device is operating" (basically what the LED displays)
26 | //
27 |
28 | #include
29 | #include
30 | #include "interface.h"
31 |
32 | static void manufacturing_thread(task __xdata*t);
33 | __xdata task manufacturing_task = {manufacturing_thread,0,0,0};
34 | static __data unsigned char manufacturing_state=0;
35 | static __bit crc_ok; // should be 1
36 | extern __bit pool_busy; // should be 1
37 | extern unsigned char __data error_state; // should be 0
38 |
39 | static void check_manufacturing_crc_16() __naked
40 | {
41 | __asm;
42 | mov r6, _RNDL
43 | mov r7, _RNDH
44 | mov _RNDL, #0xff // crc = 0xff
45 | mov _RNDL, #0xff
46 |
47 | mov _FMAP, #0x00 // for (ptr = 0; ptr < (top-of-mem-32); ptr++)
48 | 0001$:
49 | mov dptr, #0x8000
50 | 0002$:
51 | clr a
52 | movc a, @a+dptr // crc = crc16(crc, *ptr);
53 | mov _RNDH, a
54 | inc dptr
55 | mov a, dph
56 | jnz 0002$
57 | mov a, _FMAP
58 | inc a
59 | mov _FMAP, a
60 | cjne a, #7, 0001$
61 |
62 | mov dptr, #0x8000
63 | 0003$:
64 | clr a
65 | movc a, @a+dptr
66 | mov _RNDH, a
67 | inc dptr
68 | mov a, dph
69 | cjne a, #0xff, 0003$
70 | 0004$:
71 | clr a
72 | movc a, @a+dptr
73 | mov _RNDH, a
74 | inc dptr
75 | mov a, dpl
76 | cjne a, #0xe0, 0004$
77 | clr a
78 | movc a, @a+dptr // lsb CRC // crc_ok = crc == *(u16*)ptr;
79 | mov r0, a
80 | inc dptr
81 | clr a
82 | movc a, @a+dptr // msb CRC
83 | mov r1, a
84 | mov a, _RNDL
85 | cjne a, ar0, 0005$
86 | mov a, _RNDH
87 | cjne a, ar1, 0005$
88 | setb _crc_ok
89 | sjmp 0006$
90 | 0005$: clr _crc_ok
91 | 0006$:
92 | mov _RNDL, r7
93 | mov _RNDL, r6
94 | mov _ADCCON1, #0x00 // go
95 | ret
96 | __endasm;
97 | }
98 |
99 | static void
100 | manufacturing_thread(task __xdata*t)
101 | {
102 | switch (manufacturing_state) {
103 | case 0: check_manufacturing_crc_16(); // fall thru
104 | P2DIR |= 1<<1;
105 | P2INP |= 1<<1;
106 | P2_1 = 0;
107 | case 1: manufacturing_state = 2; // frame 00110101
108 | P2_1 = 0;
109 | break;
110 | case 2: manufacturing_state = 3; // frame 00110101
111 | P2_1 = 0;
112 | break;
113 | case 3: manufacturing_state = 4; // frame 00110101
114 | P2_1 = 1;
115 | break;
116 | case 4: manufacturing_state = 5; // frame 00110101
117 | P2_1 = 1;
118 | break;
119 | case 5: manufacturing_state = 6; // frame 00110101
120 | P2_1 = 0;
121 | break;
122 | case 6: manufacturing_state = 7; // frame 00110101
123 | P2_1 = 1;
124 | break;
125 | case 7: manufacturing_state = 8; // frame 00110101
126 | P2_1 = 0;
127 | break;
128 | case 8: manufacturing_state = 9; // frame 00110101
129 | P2_1 = 1;
130 | break;
131 | case 9: manufacturing_state = 10; // CRC - should be 1
132 | P2_1 = crc_ok;
133 | break;
134 | case 10:manufacturing_state = 11; // no error - should be 1
135 | if (error_state == 0) {
136 | P2_1 = 1;
137 | } else {
138 | P2_1 = 0;
139 | }
140 | break;
141 | case 11:manufacturing_state = 1; // no error - should be 1
142 | P2_1 = pool_busy;
143 | break;
144 | default:
145 | manufacturing_state = 1;
146 | break;
147 | }
148 | queue_task(&manufacturing_task, HZ/10);
149 | }
150 |
--------------------------------------------------------------------------------
/merge.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # $1 incoming .ihx file
3 | # $2 random_data
4 | # $3 size
5 | # $4 output file
6 | #
7 | # makebin comes from the sdcc build system
8 | #
9 | makebin -p $1 $1.tmp
10 | cat $1.tmp $2 >$4
11 | n=$(($3-600-80))
12 | truncate -s $n $4
13 | rm $1.tmp
14 | exit 0
15 |
--------------------------------------------------------------------------------
/onerng.inf:
--------------------------------------------------------------------------------
1 | ;
2 | ; Moonbase Otago CC2531 entropy generator
3 | ;
4 | ; based on Windows USB CDC ACM Setup file
5 | ; Copyright (c) 2000 Microsoft Corporation
6 | ; Copyright (C) 2009 Texas Instruments Inc
7 |
8 | [Version]
9 | Signature="$Windows NT$"
10 | Class=Ports
11 | ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
12 | Provider=%PROVIDER%
13 | LayoutFile=layout.inf
14 | DriverVer=05/01/2009,1.1.0.0
15 |
16 | [Manufacturer]
17 | %MFGNAME%=DeviceList, NTx86, NTia64, NTamd64
18 |
19 | [DestinationDirs]
20 | DefaultDestDir=12
21 |
22 | [SourceDisksFiles]
23 |
24 | [SourceDisksNames]
25 |
26 | [DeviceList.NTx86]
27 | %DESCRIPTION%=DriverInstall, USB\VID_1d50&PID_6086
28 |
29 | [DeviceList.NTia64]
30 | %DESCRIPTION%=DriverInstall, USB\VID_1d50&PID_6086
31 |
32 | [DeviceList.NTamd64]
33 | %DESCRIPTION%=DriverInstall, USB\VID_1d50&PID_6086
34 |
35 |
36 | ;------------------------------------------------------------------------------
37 | ; 32-bit section for Windows 2000/2003/XP/Vista
38 | ;------------------------------------------------------------------------------
39 |
40 | [DriverInstall.NTx86]
41 | include=mdmcpq.inf
42 | CopyFiles=DriverCopyFiles
43 | AddReg=DriverInstall.NTx86.AddReg
44 |
45 | [DriverInstall.NTx86]
46 | include=mdmcpq.inf
47 | CopyFiles=DriverCopyFiles
48 | AddReg=DriverInstall.NTx86.AddReg
49 |
50 | [DriverCopyFiles]
51 | usbser.sys,,,0x20
52 |
53 | [DriverInstall.NTx86.AddReg]
54 | HKR,,DevLoader,,*ntkern
55 | HKR,,NTMPDriver,,usbser.sys
56 | HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
57 |
58 | [DriverInstall.NTx86.Services]
59 | AddService=usbser, 0x00000002, DriverService
60 |
61 | ;------------------------------------------------------------------------------
62 | ; 64-bit section for Intel Itanium based systems
63 | ;------------------------------------------------------------------------------
64 |
65 | [DriverInstall.NTia64]
66 | include=mdmcpq.inf
67 | CopyFiles=DriverCopyFiles
68 | AddReg=DriverInstall.NTia64.AddReg
69 |
70 | [DriverInstall.NTia64]
71 | include=mdmcpq.inf
72 | CopyFiles=DriverCopyFiles
73 | AddReg=DriverInstall.NTia64.AddReg
74 |
75 | [DriverCopyFiles]
76 | usbser.sys,,,0x20
77 |
78 | [DriverInstall.NTia64.AddReg]
79 | HKR,,DevLoader,,*ntkern
80 | HKR,,NTMPDriver,,usbser.sys
81 | HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
82 |
83 | [DriverInstall.NTia64.Services]
84 | AddService=usbser, 0x00000002, DriverService
85 |
86 | ;------------------------------------------------------------------------------
87 | ; 64-bit section for AMD64 and Intel EM64T based systems
88 | ;------------------------------------------------------------------------------
89 |
90 | [DriverInstall.NTamd64]
91 | include=mdmcpq.inf
92 | CopyFiles=DriverCopyFiles
93 | AddReg=DriverInstall.NTamd64.AddReg
94 |
95 | [DriverInstall.NTamd64]
96 | include=mdmcpq.inf
97 | CopyFiles=DriverCopyFiles
98 | AddReg=DriverInstall.NTamd64.AddReg
99 |
100 | [DriverCopyFiles]
101 | usbser.sys,,,0x20
102 |
103 | [DriverInstall.NTamd64.AddReg]
104 | HKR,,DevLoader,,*ntkern
105 | HKR,,NTMPDriver,,usbser.sys
106 | HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
107 |
108 | [DriverInstall.NTamd64.Services]
109 | AddService=usbser, 0x00000002, DriverService
110 |
111 | ;------------------------------------------------------------------------------
112 | ;
113 | ;------------------------------------------------------------------------------
114 |
115 | [DriverService]
116 | DisplayName=%SERVICE%
117 | ServiceType=1
118 | StartType=3
119 | ErrorControl=1
120 | ServiceBinary=%12%\usbser.sys ;;%12% == "%WINDIR%\system32\"
121 |
122 | ;------------------------------------------------------------------------------
123 | ; String Definitions
124 | ;------------------------------------------------------------------------------
125 |
126 | [Strings]
127 | PROVIDER="Moonbase Otago"
128 | MFGNAME="Moonbase Otago"
129 | DESCRIPTION="OneRNG entropy generator"
130 | SERVICE="OneRNG entropy generator"
131 |
--------------------------------------------------------------------------------
/random_data:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OneRNG/firmware/81d70bf5e24d8b672b1f50fde7366c8e21640c38/random_data
--------------------------------------------------------------------------------
/set_size.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | void
7 | main(int argc, char**argv)
8 | {
9 | struct stat s;
10 |
11 | stat(argv[1], &s);
12 | printf("%c%c", (int)s.st_size&0xff, (int)(s.st_size>>8)&0xff);
13 | exit(0);
14 | }
15 |
--------------------------------------------------------------------------------
/size.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | s=`stat --format="%s" $1`
4 | echo $s
5 |
--------------------------------------------------------------------------------
/usb.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "usb.h"
4 | #include "interface.h"
5 |
6 | // (c) Copyright Paul Campbell paul@taniwha.com 2013
7 | //
8 | // This library is free software; you can redistribute it and/or
9 | // modify it under the terms of the GNU Lesser General Public
10 | // License as published by the Free Software Foundation; either
11 | // version 2.1 of the License, or (at your option) version 3, or any
12 | // later version accepted by Paul Campbell , who shall
13 | // act as a proxy defined in Section 6 of version 3 of the license.
14 | //
15 | // This library is distributed in the hope that it will be useful,
16 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 | // Lesser General Public License for more details.
19 | //
20 | // You should have received a copy of the GNU Lesser General Public
21 | // License along with this library. If not, see .
22 | //
23 |
24 | unsigned char __data eventMaskIn;
25 | unsigned char __data eventMaskOut;
26 | static unsigned char __data eventMaskCtrl;
27 | static unsigned char __pdata irqMaskCtrl;
28 | static unsigned char __pdata irqMaskIn;
29 | static unsigned char __pdata irqMaskOut;
30 |
31 | __bit inSuspend;
32 | extern __bit pool_busy;
33 | static void usb_handler(struct task __xdata *p);
34 | static struct task __xdata usb_task = {usb_handler, 0, 0, 0};
35 |
36 | struct sh __pdata setup_header;
37 |
38 | unsigned char __xdata * __data pData;
39 | unsigned int __data bytes_left;
40 | unsigned char __pdata usbState; ///< USB device state
41 | unsigned char __xdata configurationValue; ///< Current configuration value
42 | unsigned char __xdata pAlternateSetting[5]; ///< Current alternate settings
43 | unsigned char __pdata ep0Status; ///< Endpoint 0 status
44 | unsigned char __pdata pEpInStatus[5]; ///< Endpoint 1-5 IN status
45 | unsigned char __pdata pEpOutStatus[5];
46 | unsigned char __pdata remoteWakeup;
47 |
48 | #ifndef NULL
49 | #define NULL 0
50 | #endif
51 |
52 | static void (* __pdata ProcessFunc)();
53 |
54 |
55 | void usb_intr(void);
56 | void
57 | usb_init()
58 | {
59 | eventMaskIn = 0x00;
60 | eventMaskOut = 0x00;
61 | eventMaskCtrl = 0x00;
62 | inSuspend = 0;
63 | irqMaskCtrl = 0xff;
64 | irqMaskIn = 0xff;
65 | irqMaskOut = 0x3e;
66 |
67 | USBCIE = 0xff;
68 | USBIIE = 0xff;
69 | USBOIE = 0x3E;
70 |
71 | P2IFG = 0;
72 | P2IF = 0;
73 | P2IEN |= 0x20;
74 | IEN2 |= 0x02;
75 |
76 | p2_vect = usb_intr;
77 |
78 | USBCTRL= USBCTRL_PLL_EN|USBCTRL_USB_EN;
79 | while (!(USBCTRL&USBCTRL_PLL_LOCKED))
80 | ;
81 | USBCIE |= USBCIE_RESUMEIE;
82 | }
83 |
84 | void
85 | usb_intr(void) __naked
86 | {
87 | __asm;
88 | push PSW
89 | push ACC
90 | push _DPS
91 | push dpl
92 | push dph
93 | push _DPL1
94 | push _DPH1
95 | push ar0
96 | push ar1
97 | push ar2
98 | push ar3
99 | push ar4
100 | push ar5
101 | push ar6
102 | push ar7
103 | mov _DPS, #0
104 | 0001$: mov a, _SLEEPSTA // while (!(SLEEPSTA & SLEEP_XOSC_STB_BM));
105 | jnb a.6, 0001$
106 |
107 | mov dptr, #_USBCIF
108 | movx a, @dptr // u = USBCIF;
109 |
110 |
111 | jnb a.0, 0003$ // if (u&USBCIF_SUSPENDIF)
112 | setb _inSuspend // inSuspend = 1;
113 | clr p1.1
114 | 0003$:
115 | jb a.2, 0004$ // if (u&(USBCIF_RSTIF|USBCIF_RESUMEIF))
116 | jnb a.1, 0005$
117 | 0004$:
118 | clr _inSuspend // inSuspend = 0;
119 | mov c, _pool_busy
120 | mov p1.1, c
121 | 0005$:
122 |
123 | jnb a.2, 0002$ // if (u&USBCIF_RSTIF) {
124 | mov r1, #_irqMaskCtrl //
125 | movx a, @r1 // USBCIE = irqMask;
126 | mov dptr, #_USBCIE
127 | movx @dptr, a
128 |
129 | mov r1, #_irqMaskIn //
130 | movx a, @r1 // USBIIE = irqMask;
131 | mov dptr, #_USBIIE
132 | movx @dptr, a
133 |
134 | mov r1, #_irqMaskOut //
135 | movx a, @r1 // USBOIE = irqMask;
136 | mov dptr, #_USBOIE
137 | movx @dptr, a
138 |
139 | mov dptr, #_USBPOW // USBPOW |= USBPOW_SUSPEND_EN;
140 | movx a, @dptr
141 | orl a, #USBPOW_SUSPEND_EN
142 | movx @dptr, a
143 | // }
144 | 0002$:
145 | anl a, #0x0f
146 | orl a, _eventMaskCtrl // eventMask |= USN;
147 | mov _eventMaskCtrl, a
148 |
149 | mov dptr, #_USBIIF // eventMask |= USBIIF;
150 | movx a, @dptr
151 | orl a, _eventMaskIn
152 | mov _eventMaskIn, a
153 |
154 | mov dptr, #_USBOIF // eventMask |= USBOIF << 9;
155 | movx a, @dptr
156 | orl a, _eventMaskOut
157 | mov _eventMaskOut, a
158 |
159 |
160 | // if (P2IFG&P2IFG_DPIF) {
161 | mov a, _P2IFG
162 | jnb a.5, 0010$
163 | anl _P2IFG, #~(1<<5)// P2IFG = ~P2IFG_DPIF;
164 | clr _inSuspend // inSuspend = 0;
165 | mov c, _pool_busy
166 | mov p1.1, c
167 | // }
168 | 0010$:
169 | mov _P2IFG, #0 // P2IFG = 0;
170 | clr _P2IF // P2IF = 0;
171 |
172 | mov dptr, #_usb_task
173 | lcall _queue_task_0
174 |
175 | pop ar7
176 | pop ar6
177 | pop ar5
178 | pop ar4
179 | pop ar3
180 | pop ar2
181 | pop ar1
182 | pop ar0
183 | pop _DPH1
184 | pop _DPL1
185 | pop dph
186 | pop dpl
187 | pop _DPS
188 | pop ACC
189 | pop PSW
190 | reti
191 | __endasm;
192 | }
193 |
194 | static unsigned char __code * __data pDesc;
195 | unsigned char __code*
196 | find_next(unsigned char type, unsigned char halt) __naked
197 | {
198 | __asm;
199 | // unsigned char __code *p;
200 |
201 | mov r2, dpl // p = NULL;
202 | mov r0, #_find_next_PARM_2
203 | movx a, @r0
204 | mov r3, a
205 | mov dpl, _pDesc
206 | mov dph, _pDesc+1
207 | 0001$:
208 | clr a // while (pDesc[0] != 0) {
209 | movc a, @a+dptr
210 | jz 0002$
211 | mov r4, a
212 |
213 | mov a, #1 // if (pDesc[1] == type) {
214 | movc a, @a+dptr
215 | cjne a, ar2, 0003$
216 |
217 | // p = pDesc;
218 | mov a, r4 // pDesc += pDesc[0];
219 | add a, dpl
220 | mov _pDesc, a
221 | clr a
222 | addc a, dph
223 | mov _pDesc+1, a
224 | ret // break;
225 | // } else
226 | 0003$:
227 | cjne a, ar3, 0004$ // if (halt && pDesc[1] == halt)
228 | mov a, r3 // break;
229 | jnz 0002$
230 | 0004$:
231 | mov a, r4 // pDesc += pDesc[0];
232 | add a, dpl
233 | mov dpl, a
234 | clr a
235 | addc a, dph
236 | mov dph, a
237 | sjmp 0001$ // }
238 | 0002$:
239 | mov _pDesc, dpl
240 | mov _pDesc+1, dph
241 |
242 | mov dptr, #0 // return p;
243 | ret
244 | __endasm;
245 | }
246 |
247 | static unsigned char __xdata temp_desc[256];
248 | static unsigned char __xdata *
249 | copy_to_xdata(unsigned char __code *p, unsigned char l) __naked
250 | {
251 | __asm;
252 | clr _DPS
253 | mov r0, #_copy_to_xdata_PARM_2
254 | movx a, @r0
255 | mov r0, a
256 | mov _DPL1, #_temp_desc
257 | mov _DPH1, #_temp_desc>>8
258 | 0001$: clr a
259 | movc a, @a+dptr
260 | inc dptr
261 | inc _DPS
262 | movx @dptr, a
263 | inc dptr
264 | dec _DPS
265 | djnz r0, 0001$
266 | mov dptr, #_temp_desc
267 | ret
268 | __endasm;
269 | }
270 |
271 |
272 | unsigned char __xdata *
273 | get_device_desc()
274 | {
275 | unsigned char __code *p;
276 | pDesc = &descs[0];
277 | p = find_next(DESC_TYPE_DEVICE, 0);
278 | return copy_to_xdata(p, p[0]);
279 | }
280 |
281 | unsigned char __xdata *
282 | get_config_desc(unsigned char val, unsigned char ind)
283 | {
284 | unsigned char __code *p;
285 | pDesc = &descs[0];
286 | while (p = find_next(DESC_TYPE_CONFIG, 0)) {
287 | if (val) {
288 | if (val == ((struct configuration_desc __code *)p)->bConfigurationValue)
289 | return copy_to_xdata(p, p[2]);
290 | } else {
291 | if (!ind)
292 | return copy_to_xdata(p, p[2]);
293 | ind--;
294 | }
295 | }
296 | return 0;
297 | }
298 |
299 | unsigned char __code *
300 | get_interface_desc(unsigned char val, unsigned char num, unsigned char alt)
301 | {
302 | unsigned char __code *p;
303 | pDesc = &descs[0];
304 | get_config_desc(val, 0);
305 | while (p = find_next(DESC_TYPE_INTERFACE, DESC_TYPE_CONFIG)) {
306 | if (num == ((struct interface_desc __code *)p)->bInterfaceNumber &&
307 | alt == ((struct interface_desc __code *)p)->bAlternateSetting)
308 | return p;
309 | }
310 | return 0;
311 | }
312 |
313 | unsigned char __xdata *
314 | get_string_desc(unsigned char ind)
315 | {
316 | unsigned char __code *p;
317 | pDesc = &descs[0];
318 | for (;;) {
319 | p = find_next(DESC_TYPE_STRING, 0);
320 | if (!p)
321 | return 0;
322 | if (ind == 0)
323 | return copy_to_xdata(p, p[0]);
324 | ind--;
325 | }
326 | }
327 |
328 | void
329 | usb_read_fifo_0_p(unsigned char __pdata *pd, unsigned char count)
330 | {
331 | __asm;
332 | mov r0, #_usb_read_fifo_0_p_PARM_2
333 | movx a, @r0
334 | mov r0, a
335 | mov r1, dpl
336 | mov dptr, #_USBF0
337 | 0001$: movx a, @dptr
338 | movx @r1, a
339 | inc r1
340 | djnz r0, 0001$
341 | ret
342 | __endasm;
343 | }
344 | void
345 | usb_read_fifo_0(unsigned char __xdata *pd, unsigned char count)
346 | {
347 | __asm;
348 | clr _DPS
349 | mov r0, #_usb_read_fifo_0_PARM_2
350 | movx a, @r0
351 | mov r0, a
352 | mov _DPL1, #_USBF0
353 | mov _DPH1, #_USBF0>>8
354 | 0001$: inc _DPS
355 | movx a, @dptr
356 | dec _DPS
357 | movx @dptr, a
358 | inc dptr
359 | djnz r0, 0001$
360 | ret
361 | __endasm;
362 | }
363 |
364 | void
365 | usb_read_fifo_5(unsigned char __xdata *pd, unsigned char count)
366 | {
367 | __asm;
368 | clr _DPS
369 | mov r0, #_usb_read_fifo_5_PARM_2
370 | movx a, @r0
371 | mov r0, a
372 | mov _DPL1, #_USBF5
373 | mov _DPH1, #_USBF5>>8
374 | 0001$: inc _DPS
375 | movx a, @dptr
376 | dec _DPS
377 | movx @dptr, a
378 | inc dptr
379 | djnz r0, 0001$
380 | ret
381 | __endasm;
382 | }
383 |
384 | void
385 | usb_read_fifo_4(unsigned char __xdata *pd, unsigned char count)
386 | {
387 | __asm;
388 | clr _DPS
389 | mov r0, #_usb_read_fifo_4_PARM_2
390 | movx a, @r0
391 | mov r0, a
392 | mov _DPL1, #_USBF4
393 | mov _DPH1, #_USBF4>>8
394 | 0001$: inc _DPS
395 | movx a, @dptr
396 | dec _DPS
397 | movx @dptr, a
398 | inc dptr
399 | djnz r0, 0001$
400 | ret
401 | __endasm;
402 | }
403 |
404 | void
405 | usb_read_fifo_3(unsigned char __xdata *pd, unsigned char count)
406 | {
407 | __asm;
408 | clr _DPS
409 | mov r0, #_usb_read_fifo_3_PARM_2
410 | movx a, @r0
411 | mov r0, a
412 | mov _DPL1, #_USBF3
413 | mov _DPH1, #_USBF3>>8
414 | 0001$: inc _DPS
415 | movx a, @dptr
416 | dec _DPS
417 | movx @dptr, a
418 | inc dptr
419 | djnz r0, 0001$
420 | ret
421 | __endasm;
422 | }
423 |
424 | void
425 | usb_read_fifo_2(unsigned char __xdata *pd, unsigned char count)
426 | {
427 | __asm;
428 | clr _DPS
429 | mov r0, #_usb_read_fifo_2_PARM_2
430 | movx a, @r0
431 | mov r0, a
432 | mov _DPL1, #_USBF2
433 | mov _DPH1, #_USBF2>>8
434 | 0001$: inc _DPS
435 | movx a, @dptr
436 | dec _DPS
437 | movx @dptr, a
438 | inc dptr
439 | djnz r0, 0001$
440 | ret
441 | __endasm;
442 | }
443 |
444 | void
445 | usb_read_fifo_1(unsigned char __xdata *pd, unsigned char count)
446 | {
447 | __asm;
448 | clr _DPS
449 | mov r0, #_usb_read_fifo_1_PARM_2
450 | movx a, @r0
451 | mov r0, a
452 | mov _DPL1, #_USBF1
453 | mov _DPH1, #_USBF1>>8
454 | 0001$: inc _DPS
455 | movx a, @dptr
456 | dec _DPS
457 | movx @dptr, a
458 | inc dptr
459 | djnz r0, 0001$
460 | ret
461 | __endasm;
462 | }
463 |
464 | void
465 | usb_write_fifo_0(unsigned char __xdata *pd, unsigned char count)
466 | {
467 | __asm;
468 | mov r0, #_usb_write_fifo_0_PARM_2
469 | movx a, @r0
470 | jz 0002$
471 | mov r0, a
472 | mov _DPL1, #_USBF0
473 | mov _DPH1, #_USBF0>>8
474 | 0001$: movx a, @dptr
475 | inc dptr
476 | inc _DPS
477 | movx @dptr, a
478 | dec _DPS
479 | djnz r0, 0001$
480 | 0002$:
481 | ret
482 | __endasm;
483 | }
484 |
485 | static unsigned char __xdata xtmp[32];
486 |
487 | static void usb_has_data_1()
488 | {
489 | for (;;) {
490 | unsigned char c;
491 | unsigned char l, x, x2;
492 |
493 | EA=0;
494 | c = USBINDEX;
495 | USBINDEX = 1;
496 | if (!(USBCSOL&USBCSOL_OUTPKT_RDY)) {
497 | USBINDEX = c;
498 | EA=1;
499 | return;
500 | }
501 | x = USBCNTL;
502 | x2 = USBCNTH;
503 | if (x2 || x > sizeof(xtmp)) {
504 | l = sizeof(xtmp);
505 | } else {
506 | l = x;
507 | }
508 | usb_read_fifo_1(&xtmp[0], l);
509 | if (l == x && !x2) {
510 | USBINDEX = 1;
511 | USBCSOL = 0;
512 | }
513 | EA=1;
514 | }
515 | }
516 | static void usb_has_data_2()
517 | {
518 |
519 | for (;;) {
520 | unsigned char c;
521 | unsigned char l, x, x2;
522 |
523 | EA=0;
524 | c = USBINDEX;
525 | USBINDEX = 2;
526 | if (!(USBCSOL&USBCSOL_OUTPKT_RDY)) {
527 | USBINDEX = c;
528 | EA=1;
529 | return;
530 | }
531 | x = USBCNTL;
532 | x2 = USBCNTH;
533 | if (x2 || x > sizeof(xtmp)) {
534 | l = sizeof(xtmp);
535 | } else {
536 | l = x;
537 | }
538 | usb_read_fifo_2(&xtmp[0], l);
539 | if (l == x && !x2) {
540 | USBINDEX = 2;
541 | USBCSOL = 0;
542 | }
543 | EA=1;
544 | }
545 |
546 | }
547 | static void usb_has_data_3()
548 | {
549 |
550 | for (;;) {
551 | unsigned char c;
552 | unsigned char l, x, x2;
553 |
554 | EA=0;
555 | c = USBINDEX;
556 | USBINDEX = 3;
557 | if (!(USBCSOL&USBCSOL_OUTPKT_RDY)) {
558 | USBINDEX = c;
559 | EA=1;
560 | return;
561 | }
562 | x = USBCNTL;
563 | x2 = USBCNTH;
564 | if (x2 || x > sizeof(xtmp)) {
565 | l = sizeof(xtmp);
566 | } else {
567 | l = x;
568 | }
569 | usb_read_fifo_3(&xtmp[0], l);
570 | if (l == x && !x2) {
571 | USBINDEX = 3;
572 | USBCSOL = 0;
573 | }
574 | EA=1;
575 | }
576 |
577 | }
578 | static void usb_has_data_4()
579 | {
580 |
581 | for (;;) {
582 | unsigned char c;
583 | unsigned char l, x, x2;
584 |
585 | EA=0;
586 | c = USBINDEX;
587 | USBINDEX = 4;
588 | if (!(USBCSOL&USBCSOL_OUTPKT_RDY)) {
589 | USBINDEX = c;
590 | EA=1;
591 | return;
592 | }
593 | x = USBCNTL;
594 | x2 = USBCNTH;
595 | if (x2 || x > sizeof(xtmp)) {
596 | l = sizeof(xtmp);
597 | } else {
598 | l = x;
599 | }
600 | usb_read_fifo_4(&xtmp[0], l);
601 | if (l == x && !x2) {
602 | USBINDEX = 4;
603 | USBCSOL = 0;
604 | }
605 | EA=1;
606 | }
607 |
608 | }
609 |
610 | static unsigned char
611 | change_feature(unsigned char set)
612 | {
613 | unsigned char endpoint;
614 |
615 | if (setup_header.length || usbState != DEV_CONFIGURED && (setup_header.index != 0)) {
616 | ep0Status = EP_STALL;
617 | } else {
618 | switch (setup_header.requestType&RT_MASK_RECIP) {
619 | case RT_RECIP_DEV:
620 | if ((setup_header.value&0xff) != DEVICE_REMOTE_WAKEUP)
621 | return 0;
622 | remoteWakeup = set;
623 | break;
624 | case RT_RECIP_IF:
625 | return 0;
626 | case RT_RECIP_EP:
627 | endpoint = setup_header.index&0x7F;
628 | if ((setup_header.value&0xff) != ENDPOINT_HALT)
629 | return 0;
630 | if (endpoint > 5) {
631 | ep0Status = EP_STALL;
632 | } else {
633 | USBINDEX = endpoint;
634 | if (setup_header.index&0x80) {
635 | USBCSIL = set ? USBCSIL_SEND_STALL : USBCSIL_CLR_DATA_TOG;
636 | pEpInStatus[endpoint - 1] = set ? EP_HALT : EP_IDLE;
637 | } else {
638 | USBCSOL = set ? USBCSOL_SEND_STALL : USBCSOL_CLR_DATA_TOG;
639 | pEpOutStatus[endpoint - 1] = set ? EP_HALT : EP_IDLE;
640 | }
641 | USBINDEX = 0;
642 | }
643 | break;
644 | default:
645 | ep0Status = EP_STALL;
646 | break;
647 | }
648 | }
649 | return 1;
650 | }
651 |
652 | static void
653 | config_endpoints(struct interface_desc __code *pi)
654 | {
655 | unsigned char n;
656 |
657 | for (n = 0; n < pi->bNumEndpoints; n++) {
658 | struct endpoint_desc __code *pe;
659 | if (pe = (struct endpoint_desc __code *)find_next(DESC_TYPE_ENDPOINT, 0)) {
660 | unsigned char endpoint;
661 | unsigned int maxpRegValue;
662 | unsigned char csRegValue;
663 |
664 | endpoint = pe->bEndpointAddress & 0x0F;
665 | USBINDEX = endpoint;
666 | csRegValue = 0x00;
667 | maxpRegValue = (pe->wMaxPacketSize + 7) >> 3;
668 |
669 | if (pe->bEndpointAddress&0x80) { // in
670 | USBCSIL = USBCSIL_CLR_DATA_TOG | USBCSIL_FLUSH_PACKET;
671 | USBCSIL = USBCSIL_FLUSH_PACKET;
672 | if ((pe->bmAttributes&EP_ATTR_TYPE_BM) == EP_ATTR_ISO)
673 | csRegValue |= USBCSIH_ISO; // ISO flag
674 | if (endpoint >= 4)
675 | csRegValue |= USBCSIH_IN_DBL_BUF; // Double buffering
676 | USBCSIH = csRegValue;
677 | USBMAXI = maxpRegValue;
678 | pEpInStatus[endpoint - 1] = EP_IDLE;
679 | } else {
680 | USBCSOL = USBCSOL_CLR_DATA_TOG | USBCSOL_FLUSH_PACKET;
681 | USBCSOL = USBCSOL_FLUSH_PACKET;
682 | if ((pe->bmAttributes&EP_ATTR_TYPE_BM) == EP_ATTR_ISO)
683 | csRegValue |= USBCSOH_ISO; // ISO flag
684 | if (endpoint >= 4)
685 | csRegValue |= USBCSOH_OUT_DBL_BUF; // Double buffering
686 | USBCSOH = csRegValue;
687 | USBMAXO = maxpRegValue;
688 | pEpOutStatus[endpoint - 1] = EP_IDLE;
689 | }
690 | USBINDEX = 0;
691 | }
692 | }
693 | }
694 |
695 |
696 | static unsigned int __xdata status;
697 |
698 | static void
699 | usb_handler(struct task __xdata *p)
700 | {
701 |
702 | for (;;) {
703 | EA = 0;
704 | if (eventMaskCtrl&USBCIF_RSTIF) {
705 | u8 i;
706 | eventMaskCtrl &= ~USBCIF_RSTIF;
707 | EA = 1;
708 | usbState = DEV_DEFAULT;
709 | configurationValue = 0;
710 |
711 | ep0Status = EP_IDLE;
712 | for (i = 0; i < sizeof(pEpInStatus); i++)
713 | pEpInStatus[i] = EP_HALT;
714 | for (i = 0; i < sizeof(pEpOutStatus); i++)
715 | pEpOutStatus[i] = EP_HALT;
716 | ProcessFunc = NULL;
717 | continue;
718 | }
719 |
720 | if (eventMaskIn&USBIIE_EP0IE) {
721 | unsigned char controlReg;
722 | unsigned char bytesNow;
723 | unsigned char oldEndpoint;
724 | eventMaskIn &= ~USBIIE_EP0IE;
725 | EA = 1;
726 |
727 | oldEndpoint = USBINDEX;
728 | USBINDEX = 0;
729 | controlReg = USBCS0;
730 | if (controlReg&USBCS0_SETUP_END) {
731 | USBCS0 = USBCS0_CLR_SETUP_END;
732 | ep0Status = EP_CANCEL;
733 | if (ProcessFunc)
734 | ProcessFunc();
735 | ep0Status = EP_IDLE;
736 | }
737 |
738 | if (controlReg&USBCS0_SENT_STALL) {
739 | USBCS0 = 0x00;
740 | ep0Status = EP_IDLE;
741 | }
742 |
743 | if (ep0Status == EP_RX) {
744 | bytesNow = USBCNT0;
745 | usb_read_fifo_0(pData, bytesNow);
746 | bytes_left -= bytesNow;
747 | pData += bytesNow;
748 |
749 | USBCS0 = bytes_left ? USBCS0_CLR_OUTPKT_RDY : (USBCS0_CLR_OUTPKT_RDY | USBCS0_DATA_END);
750 | if (bytes_left == 0) {
751 | if (ProcessFunc)
752 | ProcessFunc();
753 | ep0Status = EP_IDLE;
754 | }
755 | USBINDEX = oldEndpoint;
756 | EA=0;
757 | goto do_next;
758 | } else
759 | if (ep0Status == EP_IDLE) {
760 | if (controlReg&USBCS0_OUTPKT_RDY) {
761 | usb_read_fifo_0_p((unsigned char __pdata *)&setup_header, 8);
762 | ProcessFunc = NULL;
763 | switch (setup_header.requestType & (RT_MASK_TYPE | RT_MASK_DIR)) {
764 | case RT_STD_OUT:
765 | switch (setup_header.request) {
766 | case SET_ADDRESS:
767 | if (setup_header.index || setup_header.length || setup_header.value&0xff80) {
768 | ep0Status = EP_STALL;
769 | break;
770 | }
771 | {
772 | unsigned char a = setup_header.value;
773 | USBADDR = a;
774 | if (a != 0) {
775 | if (usbState == DEV_DEFAULT)
776 | usbState = DEV_ADDRESS;
777 | } else {
778 | if (usbState == DEV_ADDRESS)
779 | usbState = DEV_DEFAULT;
780 | }
781 | }
782 | break;
783 | case SET_FEATURE:
784 | if (change_feature(1))
785 | ep0Status = EP_STALL;
786 | break;
787 | case CLEAR_FEATURE:
788 | if (change_feature(0))
789 | ep0Status = EP_STALL;
790 | break;
791 | case SET_CONFIGURATION:
792 | if (usbState == DEV_DEFAULT || setup_header.index || setup_header.length || setup_header.value&0xff00) {
793 | ep0Status = EP_STALL;
794 | break;
795 | }
796 | if (setup_header.value&0xff) {
797 | struct configuration_desc __xdata *pConfiguration;
798 |
799 | pConfiguration = (struct configuration_desc __xdata *)get_config_desc(setup_header.value&0xff, 0);
800 | if (pConfiguration) {
801 | unsigned char n;
802 | usbState = DEV_CONFIGURED;
803 | configurationValue = setup_header.value&0xff;
804 | for (n = 0; n < pConfiguration->bNumInterfaces; n++) {
805 | struct interface_desc __code *pi;
806 | pAlternateSetting[n] = 0x00;
807 | do {
808 | pi = (struct interface_desc __code *)find_next(DESC_TYPE_INTERFACE, 0);
809 | } while (pi->bAlternateSetting != pAlternateSetting[n]);
810 | config_endpoints(pi);
811 | }
812 | } else {
813 | ep0Status = EP_STALL;
814 | }
815 | } else {
816 | u8 i;
817 | configurationValue = setup_header.value;
818 | usbState = DEV_ADDRESS;
819 | for (i = 0; i < sizeof(pEpInStatus); i++)
820 | pEpInStatus[i] = EP_HALT;
821 | for (i = 0; i < sizeof(pEpOutStatus); i++)
822 | pEpOutStatus[i] = EP_HALT;
823 | }
824 | break;
825 | case SET_INTERFACE:
826 | if (usbState != DEV_CONFIGURED || setup_header.requestType != RT_OUT_INTERFACE || setup_header.length) {
827 | ep0Status = EP_STALL;
828 | break;
829 | }
830 | {
831 | struct interface_desc __code *pi;
832 | if (pi = (struct interface_desc __code *)get_interface_desc(configurationValue, setup_header.index, setup_header.value)) {
833 | pAlternateSetting[setup_header.index] = setup_header.value;
834 | config_endpoints(pi);
835 | } else {
836 | ep0Status = EP_STALL;
837 | }
838 | }
839 | break;
840 | case SET_DESCRIPTOR:
841 | default:
842 | ep0Status = EP_STALL;
843 | break;
844 | }
845 | break;
846 | case RT_STD_IN:
847 | switch (setup_header.request) {
848 | case GET_STATUS:
849 | if (setup_header.value || setup_header.index&0xff00 || setup_header.length != 2) {
850 | ep0Status = EP_STALL;
851 | break;
852 | }
853 | switch (setup_header.requestType) {
854 | case RT_IN_DEVICE:
855 | if (setup_header.index&0xff) {
856 | ep0Status = EP_STALL;
857 | break;
858 | }
859 | status = selfPowered ? 0x0001 : 0x0000;
860 | if (remoteWakeup)
861 | status |= 0x0002;
862 | break;
863 | case RT_IN_INTERFACE:
864 | if (usbState != DEV_CONFIGURED) {
865 | ep0Status = EP_STALL;
866 | } else {
867 | status = 0x0000;
868 | }
869 | break;
870 | case RT_IN_ENDPOINT:
871 | {
872 | unsigned char endpoint;
873 | endpoint = setup_header.index&0x7F;
874 | if (usbState != DEV_CONFIGURED || endpoint > 5) {
875 | ep0Status = EP_STALL;
876 | break;
877 | }
878 | if (setup_header.index&0x80) {
879 | status = (pEpInStatus[endpoint-1] == EP_HALT) ? 0x0001 : 0x0000;
880 | } else {
881 | status = (pEpOutStatus[endpoint-1] == EP_HALT) ? 0x0001 : 0x0000;
882 | }
883 | }
884 | break;
885 | default:
886 | ep0Status = EP_STALL;
887 | break;
888 | }
889 | if (ep0Status != EP_STALL) {
890 | pData = (unsigned char __xdata *)&status;
891 | bytes_left = 2;
892 | ep0Status = EP_TX;
893 | }
894 | break;
895 | case GET_DESCRIPTOR:
896 | switch (setup_header.value>>8) {
897 | case DESC_TYPE_DEVICE:
898 | pData = get_device_desc();
899 | bytes_left = pData[0];
900 | break;
901 | case DESC_TYPE_CONFIG:
902 | pData = get_config_desc(0, setup_header.value);
903 | bytes_left = pData[2]; // never more than 255
904 | break;
905 | case DESC_TYPE_STRING:
906 | pData = get_string_desc(setup_header.value);
907 | bytes_left = pData[0];
908 | break;
909 | default:
910 | {
911 | pData = NULL;
912 | bytes_left = 0;
913 | }
914 | }
915 | if (pData == NULL)
916 | ep0Status = EP_STALL;
917 | if (ep0Status != EP_STALL) {
918 | if (bytes_left > setup_header.length)
919 | bytes_left = setup_header.length;
920 | ep0Status = EP_TX;
921 | }
922 | break;
923 | case GET_CONFIGURATION:
924 | if (setup_header.value || setup_header.index || setup_header.length != 1) {
925 | ep0Status = EP_STALL;
926 | break;
927 | }
928 | pData = &configurationValue;
929 | bytes_left = 1;
930 | ep0Status = EP_TX;
931 | break;
932 | case GET_INTERFACE:
933 | if (usbState != DEV_CONFIGURED || setup_header.requestType != RT_IN_INTERFACE || setup_header.value || (setup_header.length != 1)) {
934 | ep0Status = EP_STALL;
935 | break;
936 | }
937 | pData = (unsigned char __xdata *)&pAlternateSetting[setup_header.index];
938 | bytes_left = 1;
939 | ep0Status = EP_TX;
940 | break;
941 | case SYNCH_FRAME:
942 | default:
943 | ep0Status = EP_STALL;
944 | break;
945 | }
946 | break;
947 | case RT_VEND_OUT:
948 | ep0Status = EP_STALL;
949 | break;
950 | case RT_VEND_IN:
951 | ep0Status = EP_STALL;
952 | break;
953 | case RT_CLASS_OUT:
954 | ProcessFunc = class_out;
955 | class_out();
956 | break;
957 | case RT_CLASS_IN:
958 | ProcessFunc = class_in;
959 | class_in();
960 | break;
961 | default:
962 | ep0Status = EP_STALL;
963 | break;
964 | }
965 | USBCS0 = (ep0Status == EP_STALL) ? (USBCS0_CLR_OUTPKT_RDY | USBCS0_SEND_STALL) : USBCS0_CLR_OUTPKT_RDY;
966 | }
967 | }
968 | if (ep0Status == EP_TX) {
969 | controlReg = USBCS0_INPKT_RDY;
970 | if (bytes_left < EP0_PACKET_SIZE) {
971 | bytesNow = bytes_left;
972 | controlReg |= USBCS0_DATA_END;
973 | } else {
974 | bytesNow = EP0_PACKET_SIZE;
975 | }
976 | usb_write_fifo_0(pData, bytesNow);
977 | pData += bytesNow;
978 | bytes_left -= bytesNow;
979 |
980 | USBCS0 = controlReg;
981 |
982 | if (bytesNow < EP0_PACKET_SIZE) {
983 | if (ProcessFunc)
984 | ProcessFunc();
985 | ep0Status = EP_IDLE;
986 | }
987 |
988 | }
989 | USBINDEX = oldEndpoint;
990 | EA=0;
991 | }
992 | do_next:
993 | if (eventMaskIn&USBIIE_INEP5IE) {
994 | USBINDEX = 5;
995 | if (!(USBCSIL&USBCSIL_INPKT_RDY)) {
996 | EA = 1;
997 | usb_can_send_5();
998 | EA=0;
999 | }
1000 | }
1001 | if (eventMaskOut&USBOIE_OUTEP5IE) {
1002 | eventMaskOut &= ~USBOIE_OUTEP5IE;
1003 | USBINDEX = 5;
1004 | if (USBCSOL&USBCSOL_OUTPKT_RDY) {
1005 | EA = 1;
1006 | usb_has_data_5();
1007 | EA=0;
1008 | }
1009 | }
1010 | if (eventMaskOut&USBOIE_OUTEP4IE) {
1011 | eventMaskOut &= ~USBOIE_OUTEP4IE;
1012 | }
1013 | if (eventMaskOut&USBOIE_OUTEP3IE) {
1014 | eventMaskOut &= ~USBOIE_OUTEP3IE;
1015 | }
1016 | if (eventMaskIn&USBIIE_INEP4IE) {
1017 | eventMaskIn &= ~USBIIE_INEP4IE;
1018 | USBINDEX = 4;
1019 | if (USBCSOL&USBCSOL_OUTPKT_RDY) {
1020 | EA = 1;
1021 | usb_has_data_4();
1022 | EA=0;
1023 | }
1024 | }
1025 | if (eventMaskIn&USBIIE_INEP3IE) {
1026 | eventMaskIn &= ~USBIIE_INEP3IE;
1027 | USBINDEX = 3;
1028 | if (USBCSOL&USBCSOL_OUTPKT_RDY) {
1029 | EA = 1;
1030 | usb_has_data_3();
1031 | EA=0;
1032 | }
1033 | }
1034 | if (eventMaskIn&USBIIE_INEP2IE) {
1035 | eventMaskIn &= ~USBIIE_INEP2IE;
1036 | USBINDEX = 2;
1037 | if (USBCSOL&USBCSOL_OUTPKT_RDY) {
1038 | EA = 1;
1039 | usb_has_data_2();
1040 | EA=0;
1041 | }
1042 | }
1043 | if (eventMaskIn&USBIIE_INEP1IE) {
1044 | eventMaskIn &= ~USBIIE_INEP1IE;
1045 | USBINDEX = 1;
1046 | if (USBCSOL&USBCSOL_OUTPKT_RDY) {
1047 | EA = 1;
1048 | usb_has_data_1();
1049 | EA=0;
1050 | }
1051 | }
1052 | if (eventMaskCtrl&USBCIF_SUSPENDIF) {
1053 | eventMaskCtrl &= ~USBCIF_SUSPENDIF;
1054 | EA=1;
1055 |
1056 | // Take the chip into PM1 until a USB resume is detected.
1057 | //usbsuspEnter();
1058 |
1059 | EA=0;
1060 | eventMaskCtrl &= ~USBCIF_RESUMEIF;
1061 | EA=1;
1062 | continue;
1063 | }
1064 | EA=1;
1065 | break;
1066 | }
1067 | }
1068 |
--------------------------------------------------------------------------------
/usb.h:
--------------------------------------------------------------------------------
1 | #ifndef USB_H
2 | #define USB_H
3 | // USBADDR
4 | #define USBADDR_UPDATE 0x80
5 | #define USBADDR_USBADDR 0x7F
6 |
7 | // USBPOW
8 | #define USBPOW_ISO_WAIT_SOF 0x80
9 | #define USBPOW_RST 0x08
10 | #define USBPOW_RESUME 0x04
11 | #define USBPOW_SUSPEND 0x02
12 | #define USBPOW_SUSPEND_EN 0x01
13 |
14 | // USBIIF
15 | #define USBIIF_INEP5IF 0x20
16 | #define USBIIF_INEP4IF 0x10
17 | #define USBIIF_INEP3IF 0x08
18 | #define USBIIF_INEP2IF 0x04
19 | #define USBIIF_INEP1IF 0x02
20 | #define USBIIF_EP0IF 0x01
21 |
22 | // USBOIF
23 | #define USBOIF_OUTEP5IF 0x20
24 | #define USBOIF_OUTEP4IF 0x10
25 | #define USBOIF_OUTEP3IF 0x08
26 | #define USBOIF_OUTEP2IF 0x04
27 | #define USBOIF_OUTEP1IF 0x02
28 |
29 | // USBCIF
30 | #define USBCIF_SOFIF 0x08
31 | #define USBCIF_RSTIF 0x04
32 | #define USBCIF_RESUMEIF 0x02
33 | #define USBCIF_SUSPENDIF 0x01
34 |
35 | // USBIIE
36 | #define USBIIE_INEP5IE 0x20
37 | #define USBIIE_INEP4IE 0x10
38 | #define USBIIE_INEP3IE 0x08
39 | #define USBIIE_INEP2IE 0x04
40 | #define USBIIE_INEP1IE 0x02
41 | #define USBIIE_EP0IE 0x01
42 |
43 | // USBOIE
44 | #define USBOIE_OUTEP5IE 0x20
45 | #define USBOIE_OUTEP4IE 0x10
46 | #define USBOIE_OUTEP3IE 0x08
47 | #define USBOIE_OUTEP2IE 0x04
48 | #define USBOIE_OUTEP1IE 0x02
49 |
50 | // USBCIE
51 | #define USBCIE_SOFIE 0x08
52 | #define USBCIE_RSTIE 0x04
53 | #define USBCIE_RESUMEIE 0x02
54 | #define USBCIE_SUSPENDIE 0x01
55 |
56 | // USBCS0
57 | #define USBCS0_CLR_SETUP_END 0x80
58 | #define USBCS0_CLR_OUTPKT_RDY 0x40
59 | #define USBCS0_SEND_STALL 0x20
60 | #define USBCS0_SETUP_END 0x10
61 | #define USBCS0_DATA_END 0x08
62 | #define USBCS0_SENT_STALL 0x04
63 | #define USBCS0_INPKT_RDY 0x02
64 | #define USBCS0_OUTPKT_RDY 0x01
65 |
66 | // USBCSIL
67 | #define USBCSIL_CLR_DATA_TOG 0x40
68 | #define USBCSIL_SENT_STALL 0x20
69 | #define USBCSIL_SEND_STALL 0x10
70 | #define USBCSIL_FLUSH_PACKET 0x08
71 | #define USBCSIL_UNDERRUN 0x04
72 | #define USBCSIL_PKT_PRESENT 0x02
73 | #define USBCSIL_INPKT_RDY 0x01
74 |
75 | // USBCSIH
76 | #define USBCSIH_AUTOSET 0x80
77 | #define USBCSIH_ISO 0x40
78 | #define USBCSIH_FORCE_DATA_TOG 0x08
79 | #define USBCSIH_IN_DBL_BUF 0x01
80 |
81 | // USBCSOL
82 | #define USBCSOL_CLR_DATA_TOG 0x80
83 | #define USBCSOL_SENT_STALL 0x40
84 | #define USBCSOL_SEND_STALL 0x20
85 | #define USBCSOL_FLUSH_PACKET 0x10
86 | #define USBCSOL_DATA_ERROR 0x08
87 | #define USBCSOL_OVERRUN 0x04
88 | #define USBCSOL_FIFO_FULL 0x02
89 | #define USBCSOL_OUTPKT_RDY 0x01
90 |
91 | // USBCSOH
92 | #define USBCSOH_AUTOCLEAR 0x80
93 | #define USBCSOH_ISO 0x40
94 | #define USBCSOH_OUT_DBL_BUF 0x01
95 |
96 | #define SLEEP_USB_EN 0x80
97 |
98 | // USBCTRL
99 | #define USBCTRL_PLL_LOCKED 0x80
100 | #define USBCTRL_PLL_EN 0x02
101 | #define USBCTRL_USB_EN 0x01
102 |
103 | struct device_desc {
104 | unsigned char bLength;
105 | unsigned char bDescriptorType;
106 | unsigned int bcdUSB;
107 | unsigned char bDeviceClass;
108 | unsigned char bDeviceSubClass;
109 | unsigned char bDeviceProtocol;
110 | unsigned char bMaxPacketSize0;
111 | unsigned int idVendor;
112 | unsigned int idProduct;
113 | unsigned int bcdDevice;
114 | unsigned char iManufacturer;
115 | unsigned char iProduct;
116 | unsigned char iSerialNumber;
117 | unsigned char bNumConfigurations;
118 | };
119 |
120 | struct configuration_desc {
121 | unsigned char bLength;
122 | unsigned char bDescriptorType;
123 | unsigned int wTotalLength;
124 | unsigned char bNumInterfaces;
125 | unsigned char bConfigurationValue;
126 | unsigned char iConfiguration;
127 | unsigned char bmAttributes;
128 | unsigned char bMaxPower;
129 | };
130 |
131 | struct interface_desc {
132 | unsigned char bLength;
133 | unsigned char bDescriptorType;
134 | unsigned char bInterfaceNumber;
135 | unsigned char bAlternateSetting;
136 | unsigned char bNumEndpoints;
137 | unsigned char bInterfaceClass;
138 | unsigned char bInterfaceSubClass;
139 | unsigned char bInterfaceProtocol;
140 | unsigned char iInterface;
141 | } ;
142 |
143 | struct endpoint_desc {
144 | unsigned char bLength;
145 | unsigned char bDescriptorType;
146 | unsigned char bEndpointAddress;
147 | unsigned char bmAttributes;
148 | unsigned int wMaxPacketSize;
149 | unsigned char bInterval;
150 | };
151 |
152 | struct string_desc {
153 | unsigned char bLength;
154 | unsigned char bDescriptorType;
155 | unsigned int pString[1];
156 | };
157 |
158 | #define EP0_PACKET_SIZE 32
159 |
160 | #define DESC_TYPE_DEVICE 1
161 | #define DESC_TYPE_CONFIG 2
162 | #define DESC_TYPE_STRING 3
163 | #define DESC_TYPE_INTERFACE 4
164 | #define DESC_TYPE_ENDPOINT 5
165 |
166 | #define EP_ATTR_CTRL 0
167 | #define EP_ATTR_ISO 1
168 | #define EP_ATTR_BULK 2
169 | #define EP_ATTR_INT 3
170 | #define EP_ATTR_TYPE_BM 3
171 |
172 | #define CDC_SEND_ENCAPSULATED_COMMAND 0x00
173 | #define CDC_GET_ENCAPSULATED_RESPONSE 0x01
174 | #define CDC_SET_COMM_FEATURE 0x02 //optional
175 | #define CDC_GET_COMM_FEATURE 0x03 //optional
176 | #define CDC_CLEAR_COMM_FEATURE 0x04 //optional
177 | #define CDC_SET_LINE_CODING 0x20 //optional
178 | #define CDC_GET_LINE_CODING 0x21 //optional
179 | #define CDC_SET_CONTROL_LINE_STATE 0x22 //optional
180 | #define CDC_SEND_BREAK 0x23 //optional
181 |
182 | #define CDC_CHAR_FORMAT_1_STOP_BIT 0
183 | #define CDC_CHAR_FORMAT_1_5_STOP_BIT 1
184 | #define CDC_CHAR_FORMAT_2_STOP_BIT 2
185 |
186 | #define CDC_PARITY_TYPE_NONE 0
187 | #define CDC_PARITY_TYPE_ODD 1
188 | #define CDC_PARITY_TYPE_EVEN 2
189 | #define CDC_PARITY_TYPE_MARK 3
190 | #define CDC_PARITY_TYPE_SPACE 4
191 |
192 | #define CDC_DEVICE 0x02
193 | #define COMM_INTF 0x02
194 |
195 | #define ABSTRACT_CONTROL_MODEL 0x02
196 | #define V25TER 0x01
197 | #define DATA_INTF 0x0A
198 | #define NO_PROTOCOL 0x00
199 |
200 | #define ABSTRACT_STATE 0x01
201 | #define COUNTRY_SETTING 0x02
202 |
203 | #define CS_INTERFACE 0x24
204 | #define CS_ENDPOINT 0x25
205 |
206 | #define DSC_FN_HEADER 0x00
207 | #define DSC_FN_CALL_MGT 0x01
208 | #define DSC_FN_ACM 0x02
209 | #define DSC_FN_DLM 0x03
210 | #define DSC_FN_TELEPHONE_RINGER 0x04
211 | #define DSC_FN_RPT_CAPABILITIES 0x05
212 | #define DSC_FN_UNION 0x06
213 | #define DSC_FN_COUNTRY_SELECTION 0x07
214 | #define DSC_FN_TEL_OP_MODES 0x08
215 | #define DSC_FN_USB_TERMINAL 0x09
216 |
217 | #define CDC_COMM_INTF_ID 0x00
218 | #define CDC_DATA_INTF_ID 0x01
219 |
220 |
221 |
222 | extern unsigned char __code descs[];
223 | extern unsigned char __xdata * __data pData;
224 | extern unsigned int __data bytes_left;
225 | extern unsigned char __pdata usbState; ///< USB device state
226 | extern unsigned char __xdata configurationValue; ///< Current configuration value
227 | extern unsigned char __xdata pAlternateSetting[5]; ///< Current alternate settings
228 | extern unsigned char __pdata ep0Status; ///< Endpoint 0 status
229 | extern unsigned char __pdata pEpInStatus[5]; ///< Endpoint 1-5 IN status
230 | extern unsigned char __pdata pEpOutStatus[5];
231 | extern unsigned char __pdata remoteWakeup;
232 | #define selfPowered 0
233 |
234 | struct sh {
235 | unsigned char requestType;
236 | unsigned char request;
237 | unsigned int value;
238 | unsigned int index;
239 | unsigned int length;
240 | };
241 | extern struct sh __pdata setup_header;
242 |
243 | struct lc {
244 | unsigned long baudRate;
245 | unsigned char charFormat;
246 | unsigned char parityType;
247 | unsigned char dataBits;
248 | };
249 |
250 | extern struct lc __xdata line_config;
251 |
252 | void usb_read_fifo_5(unsigned char __xdata *p, unsigned char l);
253 | void usb_read_fifo_4(unsigned char __xdata *p, unsigned char l);
254 | void usb_read_fifo_3(unsigned char __xdata *p, unsigned char l);
255 | void usb_write_fifo_5(unsigned char __xdata *p, unsigned char l);
256 | void usb_write_fifo_4(unsigned char __xdata *p, unsigned char l);
257 | void usb_write_fifo_3(unsigned char __xdata *p, unsigned char l);
258 | void usb_has_data_5();
259 | void usb_has_data_4();
260 | void usb_has_data_3();
261 | void usb_can_send_5();
262 | void usb_can_send_4();
263 | void usb_can_send_3();
264 | void flush_in_3();
265 | void flush_in_4();
266 | void flush_in_5();
267 | void cdc_init(unsigned long baudrate);
268 | void usb_init();
269 |
270 | extern __bit cdcRTS_3, cdcRTS_4, cdcRTS_5;
271 |
272 | #define EP_IDLE 0
273 | #define EP_TX 1
274 | #define EP_RX 2
275 | #define EP_HALT 3
276 | #define EP_STALL 4
277 | #define EP_MANUAL_TX 5
278 | #define EP_MANUAL_RX 6
279 | #define EP_CANCEL 7
280 |
281 | #define DEV_ATTACHED 0
282 | #define DEV_POWERED 1
283 | #define DEV_DEFAULT 2
284 | #define DEV_ADDRESS 3
285 | #define DEV_CONFIGURED 4
286 | #define DEV_SUSPENDED 5
287 |
288 | #define RT_MASK_DIR 0x80
289 | #define RT_MASK_TYPE 0x60
290 | #define RT_MASK_RECIP 0x1F
291 |
292 | #define RT_DIR_IN 0x80
293 | #define RT_DIR_OUT 0x00
294 |
295 | #define RT_TYPE_STD 0x00
296 | #define RT_TYPE_CLASS 0x20
297 | #define RT_TYPE_VEND 0x40
298 |
299 | #define RT_RECIP_DEV 0x00
300 | #define RT_RECIP_IF 0x01
301 | #define RT_RECIP_EP 0x02
302 | #define RT_RECIP_OTHER 0x03
303 |
304 | #define RT_STD_OUT (RT_TYPE_STD | RT_DIR_OUT)
305 | #define RT_STD_IN (RT_TYPE_STD | RT_DIR_IN)
306 | #define RT_VEND_OUT (RT_TYPE_VEND | RT_DIR_OUT)
307 | #define RT_VEND_IN (RT_TYPE_VEND | RT_DIR_IN)
308 | #define RT_CLASS_OUT (RT_TYPE_CLASS | RT_DIR_OUT)
309 | #define RT_CLASS_IN (RT_TYPE_CLASS | RT_DIR_IN)
310 |
311 | #define RT_OUT_DEVICE (RT_DIR_OUT | RT_RECIP_DEV)
312 | #define RT_IN_DEVICE (RT_DIR_IN | RT_RECIP_DEV)
313 | #define RT_OUT_INTERFACE (RT_DIR_OUT | RT_RECIP_IF)
314 | #define RT_IN_INTERFACE (RT_DIR_IN | RT_RECIP_IF)
315 | #define RT_OUT_ENDPOINT (RT_DIR_OUT | RT_RECIP_EP)
316 | #define RT_IN_ENDPOINT (RT_DIR_IN | RT_RECIP_EP)
317 |
318 |
319 | #define GET_STATUS 0x00
320 | #define CLEAR_FEATURE 0x01
321 | #define SET_FEATURE 0x03
322 | #define SET_ADDRESS 0x05
323 | #define GET_DESCRIPTOR 0x06
324 | #define SET_DESCRIPTOR 0x07
325 | #define GET_CONFIGURATION 0x08
326 | #define SET_CONFIGURATION 0x09
327 | #define GET_INTERFACE 0x0A
328 | #define SET_INTERFACE 0x0B
329 | #define SYNCH_FRAME 0x0C
330 |
331 | #define ENDPOINT_HALT 0x00
332 | #define DEVICE_REMOTE_WAKEUP 0x01
333 |
334 | extern void class_in();
335 | extern void class_out();
336 | extern void change_uart_mode();
337 | extern void prog_setup();
338 | #endif
339 |
340 |
--------------------------------------------------------------------------------
/val/validate.c:
--------------------------------------------------------------------------------
1 | // (c) Copyright Paul Campbell paul@taniwha.com 2015
2 | //
3 | // This library is free software; you can redistribute it and/or
4 | // modify it under the terms of the GNU Lesser General Public
5 | // License as published by the Free Software Foundation; either
6 | // version 2.1 of the License, or (at your option) version 3, or any
7 | // later version accepted by Paul Campbell , who shall
8 | // act as a proxy defined in Section 6 of version 3 of the license.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library. If not, see .
17 | //
18 |
19 | //
20 | // This code handles the extra anti-tamper feature of RNG
21 | // essentially it works this way:
22 | //
23 | // 1) OneRNG device flash is protected so we can't read it from the debug interface
24 | // but we can erase (all of) it
25 | //
26 | // 2) when we program it we put a known random value in the first 96 bytes of
27 | // the last 128 bytes of it 16 bytes 'ID, 16 bytes 'K', 64 bytes 'S'
28 | //
29 | // 3) user asks device for a its 'ID' from bytes 0:15 of this area 'cmdI'
30 | // returns '!!iiiiii....iiii!' where iiii...iiii is 32 hex digits
31 | //
32 | // 4) user provides 'ID' to the OneRNG web site
33 | // a) it generates a 16 byte token 'T'
34 | // b) caches the tuple ('ID'/'T') - TTL 2 minutes
35 | // c) and returns 'T' to the user
36 | //
37 | // 5) when asked for a confirmation a OneRNG is given the token 'T' 'cmdRtttt....tttt'
38 | // (ttt....tttt is 32 hex digits) and:
39 | // a) use the bytes 16:31 of the region as an AES128 key 'K'
40 | // b) encrypt a 2 block nonce of random data 'R' (32 bytes) -> 'ER'
41 | // c) encrypt (chained) 2 blocks of token 'T' (32 bytes) -> 'ET'
42 | // d) encrypt (chained) the final 32:95 bytes of the region 'S' (64 bytes) -> 'ES'
43 | // e) offer the resulting 128 bytes from the encryption to the host 'ER'+'ET'+'ES'
44 | //
45 | // 6) user presents bytes 0:15 of the user data 'ID' and bytes 0:63 of the encrypted data 'ER'+'ET' to OneRNG's web page
46 | //
47 | // 7) OneRNG's server:
48 | // a) wait a random time (to hide error cause info)
49 | // b) inspects its database of manufactured devices using the key from bytes 16-31 'ID'
50 | // c) if 'ID' isn't in the DB return an error
51 | // d) retrieves bytes 0-95 'K'+'ID'+'S' that were programmed into the device
52 | // e) decrypts 'ER' using 'K' giving nonce 'R' (discarded)
53 | // f) decrypts (chained) 'ET' using 'K' giving 'T'
54 | // g) if 'T' doesn't match returns an error
55 | // h) reencrypts 'R'+'T'+'S' using 'K' giving 'ER'+'ET'+'ES'
56 | // i) returns 'ES' to user
57 | // j) tells user how many times it has offered up results for this id (to record
58 | // potential replay attacks)
59 | //
60 | // 8) User compares 'ES' from user's OneRNG with value that OneRNG delivered in step 5d)
61 | // gets worried if they are not the same
62 | //
63 | // (we allow this to be done manually but we also provide a python script)
64 | //
65 | // The basic idea is that we have a shared secret K+S (ID is essentially a secret id)
66 | // we tell the server we know the key by encrypting something it does know with K (T) and return
67 | // the encrypted second secret S - the user compares the encrypted second secret (ES) with the
68 | // one the OneRNG gave it
69 | //
70 | // We also use T to stop replay attacks (where someone records a good transaction from another
71 | // OneRNG and replays it from a compromised one)
72 | //
73 | // In other words:
74 | //
75 | // step OneRNG web host/user User's OneRNG
76 | //
77 | // 3) 'ID'<-'ID'
78 | //
79 | // 4) 'ID'<-'ID'
80 | // 'T'->'T'
81 | //
82 | // 5) 'T'->'T'
83 | // 'ER'+'ET'+'ESa'<-'R'+'T'+'S'
84 | //
85 | // 6) 'ID'+'ER'+'ET'<-'ID'+''ER'+'ET'
86 | //
87 | // 7) 'ID'+'ER'+'ET'->'R'+'T'->'ESb'
88 | // 'ESa'=='ESb'
89 | //
90 |
91 | #include
92 | #include
93 | #include "task.h"
94 | #include "interface.h"
95 |
96 | #define AES_ENCRYPT 0x00
97 | #define AES_DECRYPT 0x02
98 | #define AES_LOAD_KEY 0x04
99 | #define AES_LOAD_IV 0x06
100 | #define AES_MODE_CBC 0x00
101 |
102 | unsigned char __xdata token[16];
103 | static __bit tmpb;
104 | extern __bit no_avalanche;
105 | extern __xdata unsigned char *__data pool_out;
106 | extern unsigned char __xdata pool[];
107 | extern unsigned int __data pool_count;
108 | static void out_hex();
109 |
110 | void
111 | start_encrypt() __naked
112 | {
113 | __asm; // u8 i;
114 | mov _FMAP, #7 // ptr = 0x
115 | mov dptr, #0xff80+16
116 | mov _ENCCS, #AES_LOAD_KEY|AES_MODE_CBC // ENCCS = ES_LOAD_KEY|AES_MODE_CBC
117 | orl _ENCCS, #1 // ENCCS |= 0x01; // start
118 | mov r0, #16 // for (i=0; i<16; i++)
119 | 0002$: clr a
120 | movc a, @a+dptr// ENCDI = *key++;
121 | inc dptr
122 | mov _ENCDI, a
123 | djnz r0, 0002$
124 | 0001$: mov a, _ENCCS // aes_done();
125 | jnb _ACC_3, 0001$
126 |
127 | mov dptr, #0xff80
128 | mov _ENCCS, #AES_LOAD_IV|AES_MODE_CBC // ENCCS = ES_LOAD_IV|AES_MODE_CBC
129 | orl _ENCCS, #1 // ENCCS |= 0x01; // start
130 | mov r0, #16 // for (i=0; i<16; i++)
131 | 0004$: clr a
132 | movc a, @a+dptr// ENCDI = *key++;
133 | inc dptr
134 | mov _ENCDI, a
135 | djnz r0, 0004$
136 | 0003$: mov a, _ENCCS // aes_done();
137 | jnb _ACC_3, 0003$
138 | ret
139 | __endasm;
140 | }
141 |
142 | void
143 | sync_header() __naked
144 | {
145 | __asm;
146 | mov dptr, #_USBF5 // start with '@@@@@@@@'
147 | mov a, #'@'
148 | mov r0, #8 // for (i = 0; i < 8; i++)
149 | 0044$: movx @dptr, a // USBF5 = '@'
150 | djnz r0, 0044$
151 | ret
152 | __endasm;
153 | }
154 |
155 | void
156 | send_id_block() __naked
157 | {
158 | __asm;
159 | mov dptr, #_USBF5
160 | inc _DPS
161 | mov dptr, #0xff80
162 | mov r0, #16 // for (i = 0; i < 16; i++)
163 | 0004$: clr a
164 | movc a, @a+dptr // USBF5 = *id++;
165 | inc dptr
166 | dec _DPS
167 | lcall _out_hex
168 | inc _DPS
169 | djnz r0, 0004$
170 |
171 | dec _DPS
172 | ret
173 | __endasm;
174 | }
175 |
176 | void
177 | encrypt_random_block() __naked
178 | {
179 | __asm;
180 | mov dptr, #_USBF5 // start with '@@@@@@@@'
181 | mov a, #'@'
182 | mov r0, #8 // for (i = 0; i < 8; i++)
183 | 0044$: movx @dptr, a // USBF5 = '@'
184 | djnz r0, 0044$
185 | mov c, _no_avalanche // tmpb = no_avalanche;
186 | mov _tmpb, c
187 | clr _no_avalanche // no_avalanche = 0;
188 | 0002$: mov a, _pool_count+1 // while (pool_count < 32)
189 | jnz 0001$
190 | mov a, _pool_count
191 | anl a, #0xe0
192 | jnz 0001$
193 | lcall _idle_pool // idle_pool();
194 | sjmp 0002$
195 | 0001$:
196 | mov c, _tmpb // idle_pool = tmpb;
197 | mov _no_avalanche, c
198 |
199 | mov r1, #2 // for (j = 0 j < 2; j++) {
200 | 0077$:
201 | mov dpl, _pool_out
202 | mov dph, _pool_out+1
203 |
204 | mov _ENCCS, #AES_MODE_CBC|AES_ENCRYPT // ENCCS = AES_MODE_CBC|AES_ENCRYPT
205 | orl _ENCCS, #1 // ENCCS |= 0x01; // start
206 | mov r0, #16 // for (i=0; i<16; i++)
207 | 0004$: movx a, @dptr // ENCDI = *pool_out++;
208 | mov _ENCDI, a
209 | inc dptr
210 | mov a, dpl // if (pool_out == &pool[POOL_SIZE])
211 | cjne a, #_pool+POOL_SIZE, 0011$
212 | mov a, dph // pool_out = &pool[0];
213 | cjne a, #(_pool+POOL_SIZE)>>8, 0011$
214 | mov dptr, #_pool
215 | 0011$:
216 | djnz r0, 0004$
217 | mov _pool_out, dpl
218 | mov _pool_out+1, dph
219 |
220 | clr c
221 | mov a, _pool_count // pool_count -= 16;
222 | subb a, #16
223 | mov _pool_count, a
224 | mov a, _pool_count+1
225 | subb a, #0
226 | mov _pool_count+1, a
227 |
228 | mov r0, #32 // wait_us(1);
229 | 0111$: djnz r0, 0111$
230 |
231 | mov dptr, #_USBF5
232 | mov r0, #16 // for (i=0; i<16; i++)
233 | 0014$: mov a, _ENCDO // *USBF5 = hex(*ENCDO)
234 | lcall _out_hex
235 | djnz r0, 0014$
236 | 0013$: mov a, _ENCCS // aes_done();
237 | jnb _ACC_3, 0013$
238 | djnz r1, 0077$ // }
239 |
240 | ret
241 | __endasm;
242 | }
243 |
244 | static void
245 | out_hex() __naked // dptr is dest, a is value, r7 is free
246 | {
247 | __asm;
248 | mov r7, a
249 | swap a
250 | anl a, #0x0f
251 | cjne a, #9, 1$
252 | 2$: add a, #'0'
253 | sjmp 3$
254 | 1$: jc 2$
255 | add a, #('A'-10)
256 | 3$: movx @dptr, a
257 |
258 | mov a, r7
259 | anl a, #0x0f
260 | cjne a, #9, 11$
261 | 12$: add a, #'0'
262 | sjmp 13$
263 | 11$: jc 12$
264 | add a, #('A'-10)
265 | 13$: movx @dptr, a
266 | ret
267 | __endasm;
268 | }
269 |
270 | void
271 | encrypt_token() __naked
272 | {
273 | __asm;
274 | mov dptr, #_token
275 | mov _ENCCS, #AES_MODE_CBC|AES_ENCRYPT // ENCCS = AES_MODE_CBC|AES_ENCRYPT
276 | orl _ENCCS, #1 // ENCCS |= 0x01; // start
277 | mov r0, #16 // for (i=0; i<16; i++)
278 | 0004$: movx a, @dptr // ENCDI = *pool_out++;
279 | mov _ENCDI, a
280 | inc dptr
281 | djnz r0, 0004$
282 |
283 | mov r0, #32 // wait_us(1);
284 | 0011$: djnz r0, 0011$
285 |
286 | mov dptr, #_USBF5
287 | mov r0, #16 // for (i=0; i<16; i++)
288 | 0014$: mov a, _ENCDO // *USBF5 = hex(*ENCDO)
289 | lcall _out_hex
290 | djnz r0, 0014$
291 | 0013$: mov a, _ENCCS // aes_done();
292 | jnb _ACC_3, 0013$
293 | //
294 |
295 | ret
296 | __endasm;
297 | }
298 |
299 |
300 | void
301 | encrypt_secret_blocks() __naked
302 | {
303 | __asm;
304 | mov _FMAP, #7 // ptr = 0x
305 | //mov dptr, #0xff80+32 // in dptr at call time
306 | mov _DPL, #_USBF5
307 | mov _DPH, #_USBF5>>8
308 |
309 | mov r1, #2 // for (j = 0 j < 4; j++) {
310 | 0077$:
311 |
312 | mov _ENCCS, #AES_MODE_CBC|AES_ENCRYPT// ENCCS = AES_MODE_CBC|AES_ENCRYPT
313 | orl _ENCCS, #1 // ENCCS |= 0x01; // start
314 | mov r0, #16 // for (i=0; i<16; i++)
315 | 0004$: clr a
316 | movc a, @a+dptr // ENCDI = *secret++;
317 | mov _ENCDI, a
318 | inc dptr
319 | djnz r0, 0004$
320 |
321 | mov r0, #32 // wait_us(1);
322 | 0011$: djnz r0, 0011$
323 |
324 | inc _DPS
325 | mov r0, #16 // for (i=0; i<16; i++)
326 | 0014$: mov a, _ENCDO // *USBF5 = hex(*ENCDO)
327 | lcall _out_hex
328 | djnz r0, 0014$
329 | dec _DPS
330 | 0013$: mov a, _ENCCS // aes_done();
331 | jnb _ACC_3, 0013$
332 | djnz r1, 0077$ // }
333 |
334 | ret
335 | __endasm;
336 | }
337 |
--------------------------------------------------------------------------------
/validate.c:
--------------------------------------------------------------------------------
1 | // (c) Copyright Paul Campbell paul@taniwha.com 2015
2 | //
3 | // This library is free software; you can redistribute it and/or
4 | // modify it under the terms of the GNU Lesser General Public
5 | // License as published by the Free Software Foundation; either
6 | // version 2.1 of the License, or (at your option) version 3, or any
7 | // later version accepted by Paul Campbell , who shall
8 | // act as a proxy defined in Section 6 of version 3 of the license.
9 | //
10 | // This library is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | // Lesser General Public License for more details.
14 | //
15 | // You should have received a copy of the GNU Lesser General Public
16 | // License along with this library. If not, see .
17 | //
18 |
19 | //
20 | // This code handles the extra anti-tamper feature of RNG
21 | // essentially it works this way:
22 | //
23 | // 1) OneRNG device flash is protected so we can't read it from the debug interface
24 | // but we can erase (all of) it
25 | //
26 | // 2) when we program it we put a known random value in the first 96 bytes of
27 | // the last 128 bytes of it 16 bytes 'ID, 16 bytes 'K', 64 bytes 'S'
28 | //
29 | // 3) user asks device for a its 'ID' from bytes 0:15 of this area 'cmdI'
30 | // returns '@@@@@@iiiiii....iiii!' where iiii...iiii is 32 hex digits
31 | //
32 | // 4) user provides 'ID' to the OneRNG web site
33 | // a) it generates a 16 byte token 'T'
34 | // b) caches the tuple ('ID'/'T') - TTL 2 minutes
35 | // c) and returns 'T' to the user
36 | //
37 | // 5) when asked for a confirmation a OneRNG is given the token 'T' 'cmdRtttt....tttt'
38 | // (ttt....tttt is 32 hex digits) and:
39 | // a) use the bytes 16:31 of the region as an AES128 key 'K'
40 | // b) encrypt a 1 block nonce of random data 'R' (16 bytes) -> 'ER'
41 | // c) encrypt (chained) 1 blocks of token 'T' (16 bytes) -> 'ET'
42 | // d) encrypt (chained) the final 32:95 bytes of the region 'S' (64 bytes) -> 'ES'
43 | // e) offer the resulting 96 bytes from the encryption to the host 'ER'+'ET'+'ES'
44 | //
45 | // 6) user presents bytes 0:15 of the user data 'ID' and bytes 0:31 of the encrypted data 'ER'+'ET' to OneRNG's web page
46 | //
47 | // 7) OneRNG's server:
48 | // a) wait a random time (to hide error cause info)
49 | // b) inspects its database of manufactured devices using the key from bytes 16-31 'ID'
50 | // c) if 'ID' isn't in the DB return an error
51 | // d) retrieves bytes 0-95 'K'+'ID'+'S' that were programmed into the device
52 | // e) decrypts 'ER' using 'K' giving nonce 'R' (discarded)
53 | // f) decrypts (chained) 'ET' using 'K' giving 'T'
54 | // g) if 'T' doesn't match returns an error
55 | // h) reencrypts 'R'+'T'+'S' using 'K' giving 'ER'+'ET'+'ES'
56 | // i) returns 'ES' to user
57 | // j) tells user how many times it has offered up results for this id (to record
58 | // potential replay attacks)
59 | //
60 | // 8) User compares 'ES' from user's OneRNG with value that OneRNG delivered in step 5d)
61 | // gets worried if they are not the same
62 | //
63 | // (we allow this to be done manually but we also provide a python script)
64 | //
65 | // The basic idea is that we have a shared secret K+S (ID is essentially a secret id)
66 | // we tell the server we know the key by encrypting something it does know with K (T) and return
67 | // the encrypted second secret S - the user compares the encrypted second secret (ES) with the
68 | // one the OneRNG gave it
69 | //
70 | // We also use T to stop replay attacks (where someone records a good transaction from another
71 | // OneRNG and replays it from a compromised one)
72 | //
73 | // In other words:
74 | //
75 | // step OneRNG web host/user User's OneRNG
76 | //
77 | // 3) 'ID'<-'ID'
78 | //
79 | // 4) 'ID'<-'ID'
80 | // 'T'->'T'
81 | //
82 | // 5) 'T'->'T'
83 | // 'ER'+'ET'+'ESa'<-'R'+'T'+'S'
84 | //
85 | // 6) 'ID'+'ER'+'ET'<-'ID'+''ER'+'ET'
86 | //
87 | // 7) 'ID'+'ER'+'ET'->'R'+'T'->'ESb'
88 | // 'ESa'=='ESb'
89 | //
90 |
91 | #include
92 | #include
93 | #include "task.h"
94 | #include "interface.h"
95 |
96 | #define AES_ENCRYPT 0x00
97 | #define AES_DECRYPT 0x02
98 | #define AES_LOAD_KEY 0x04
99 | #define AES_LOAD_IV 0x06
100 | #define AES_MODE_CBC 0x00
101 |
102 | unsigned char __xdata token[16];
103 | static __bit tmpb;
104 | extern __bit no_avalanche;
105 | extern __xdata unsigned char *__data pool_out;
106 | extern unsigned char __xdata pool[];
107 | extern unsigned int __data pool_count;
108 | static void out_hex();
109 |
110 | void
111 | start_encrypt() __naked
112 | {
113 | __asm; // u8 i;
114 | mov _FMAP, #7 // ptr = 0x
115 | mov dptr, #0xff80+16
116 | mov _ENCCS, #AES_LOAD_KEY|AES_MODE_CBC // ENCCS = ES_LOAD_KEY|AES_MODE_CBC
117 | orl _ENCCS, #1 // ENCCS |= 0x01; // start
118 | mov r0, #16 // for (i=0; i<16; i++)
119 | 0002$: clr a
120 | movc a, @a+dptr// ENCDI = *key++;
121 | inc dptr
122 | mov _ENCDI, a
123 | djnz r0, 0002$
124 | 0001$: mov a, _ENCCS // aes_done();
125 | jnb _ACC_3, 0001$
126 |
127 | mov dptr, #0xff80
128 | mov _ENCCS, #AES_LOAD_IV|AES_MODE_CBC // ENCCS = ES_LOAD_IV|AES_MODE_CBC
129 | orl _ENCCS, #1 // ENCCS |= 0x01; // start
130 | mov r0, #16 // for (i=0; i<16; i++)
131 | 0004$: clr a
132 | movc a, @a+dptr// ENCDI = *key++;
133 | inc dptr
134 | mov _ENCDI, a
135 | djnz r0, 0004$
136 |
137 | 0003$: mov a, _ENCCS // aes_done();
138 | jnb _ACC_3, 0003$
139 | ret
140 | __endasm;
141 | }
142 |
143 | void
144 | crlf() __naked
145 | {
146 | __asm;
147 | mov dptr, #_USBF5 // start with '/n@@@@@@@@'
148 | mov a, #'\r'
149 | movx @dptr, a // USBF5 = '\r'
150 | mov a, #'\n'
151 | movx @dptr, a // USBF5 = '\n'
152 | ret
153 | __endasm;
154 | }
155 | void
156 | sync_header() __naked
157 | {
158 | __asm;
159 | mov dptr, #_USBF5 // start with '/n@@@@@@@@'
160 | mov a, #'_'
161 | mov r0, #8 // for (i = 0; i < 8; i++)
162 | 0044$: movx @dptr, a // USBF5 = '@'
163 | djnz r0, 0044$
164 | ret
165 | __endasm;
166 | }
167 |
168 | void
169 | send_id_block() __naked
170 | {
171 | __asm;
172 | mov dptr, #_USBF5
173 | inc _DPS
174 | mov dptr, #0xff80
175 | mov r0, #16 // for (i = 0; i < 16; i++)
176 | 0004$: clr a
177 | movc a, @a+dptr // USBF5 = *id++;
178 | inc dptr
179 | dec _DPS
180 | lcall _out_hex
181 | inc _DPS
182 | djnz r0, 0004$
183 |
184 | dec _DPS
185 | ret
186 | __endasm;
187 | }
188 |
189 | void
190 | encrypt_random_block() __naked
191 | {
192 | __asm;
193 | mov dptr, #_USBF5 // start with '@@@@@@@@'
194 | 0077$:
195 | mov _ENCCS, #AES_MODE_CBC|AES_ENCRYPT // ENCCS = AES_MODE_CBC|AES_ENCRYPT
196 | orl _ENCCS, #1 // ENCCS |= 0x01; // start
197 | mov r0, #16 // for (i=0; i<16; i++) {
198 | 0004$: mov r1, #16 // rand = 0
199 | clr a // for (j = 0; j < 16; j++) {
200 | 0005$: mov c, p1.7 // rand = (rand<<1)|p1.7
201 | rlc a
202 | jnc 0015$ // rand = (rand&0xff)^(rand>>8)
203 | xrl a, #1
204 | 0015$: // }
205 | djnz r1, 0005$
206 | mov _ENCDI, a // ENCDI = rand
207 | 0011$: // }
208 | djnz r0, 0004$
209 |
210 | mov r0, #255 // wait_us(1);
211 | 0111$: djnz r0, 0111$
212 |
213 | mov dptr, #_USBF5
214 | mov r0, #16 // for (i=0; i<16; i++)
215 | 0014$: mov a, _ENCDO // *USBF5 = hex(*ENCDO)
216 | lcall _out_hex
217 | djnz r0, 0014$
218 | 0013$: mov a, _ENCCS // aes_done();
219 | jnb _ACC_3, 0013$
220 | ret
221 | __endasm;
222 | }
223 |
224 | static void
225 | out_hex() __naked // dptr is dest, a is value, r7 is free
226 | {
227 | __asm;
228 | mov r7, a
229 | swap a
230 | anl a, #0x0f
231 | cjne a, #9, 1$
232 | 2$: add a, #'0'
233 | sjmp 3$
234 | 1$: jc 2$
235 | add a, #('A'-10)
236 | 3$: movx @dptr, a
237 |
238 | mov a, r7
239 | anl a, #0x0f
240 | cjne a, #9, 11$
241 | 12$: add a, #'0'
242 | sjmp 13$
243 | 11$: jc 12$
244 | add a, #('A'-10)
245 | 13$: movx @dptr, a
246 | ret
247 | __endasm;
248 | }
249 |
250 | void
251 | encrypt_token() __naked
252 | {
253 | __asm;
254 | mov dptr, #_token
255 | mov _ENCCS, #AES_MODE_CBC|AES_ENCRYPT // ENCCS = AES_MODE_CBC|AES_ENCRYPT
256 | orl _ENCCS, #1 // ENCCS |= 0x01; // start
257 | mov r0, #16 // for (i=0; i<16; i++)
258 | 0004$: movx a, @dptr // ENCDI = *pool_out++;
259 | mov _ENCDI, a
260 | inc dptr
261 | djnz r0, 0004$
262 |
263 | mov r0, #255 // wait_us(1);
264 | 0011$: djnz r0, 0011$
265 |
266 | mov dptr, #_USBF5
267 | mov r0, #16 // for (i=0; i<16; i++)
268 | 0014$: mov a, _ENCDO // *USBF5 = hex(*ENCDO)
269 | lcall _out_hex
270 | djnz r0, 0014$
271 | 0013$: mov a, _ENCCS // aes_done();
272 | jnb _ACC_3, 0013$
273 | ret
274 |
275 | __endasm;
276 | }
277 |
278 |
279 | void
280 | encrypt_secret_blocks() __naked
281 | {
282 | __asm;
283 | clr _DPS
284 | mov _FMAP, #7 // ptr = 0x
285 | //mov dptr, #0xff80+32 // in dptr at call time
286 | mov _DPL1, #_USBF5
287 | mov _DPH1, #_USBF5>>8
288 |
289 | mov r1, #2 // for (j = 0 j < 4; j++) {
290 | 0077$:
291 | mov _ENCCS, #AES_MODE_CBC|AES_ENCRYPT// ENCCS = AES_MODE_CBC|AES_ENCRYPT
292 | orl _ENCCS, #1 // ENCCS |= 0x01; // start
293 | mov r0, #16 // for (i=0; i<16; i++)
294 | 0004$: clr a
295 | movc a, @a+dptr // ENCDI = *secret++;
296 | mov _ENCDI, a
297 | inc dptr
298 | djnz r0, 0004$
299 |
300 | mov r0, #255 // wait_us(1);
301 | 0011$: djnz r0, 0011$
302 |
303 | inc _DPS
304 | mov r0, #16 // for (i=0; i<16; i++)
305 | 0014$: mov a, _ENCDO // *USBF5 = hex(*ENCDO)
306 | lcall _out_hex
307 | djnz r0, 0014$
308 | dec _DPS
309 | 0013$: mov a, _ENCCS // aes_done();
310 | jnb _ACC_3, 0013$
311 | djnz r1, 0077$ // }
312 | ret
313 | __endasm;
314 | }
315 |
--------------------------------------------------------------------------------