mirror of
https://github.com/micropython/micropython.git
synced 2025-12-25 22:30:12 +01:00
Compare commits
285 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64e8b62291 | ||
|
|
ad038ca101 | ||
|
|
28fa84b445 | ||
|
|
c260836beb | ||
|
|
1eba62cac9 | ||
|
|
1826036a83 | ||
|
|
51229afbde | ||
|
|
4112590a60 | ||
|
|
a210c774f9 | ||
|
|
542bd6b4a1 | ||
|
|
760a6eca9b | ||
|
|
4be44014ab | ||
|
|
0090c714ba | ||
|
|
2d717ad97a | ||
|
|
e909e38871 | ||
|
|
23d7fd526d | ||
|
|
214179b430 | ||
|
|
44f65c0e2f | ||
|
|
5e1d993f54 | ||
|
|
aedf583af2 | ||
|
|
7f41f650de | ||
|
|
26d230419c | ||
|
|
4729a212b1 | ||
|
|
684dba40f0 | ||
|
|
e15f8198bc | ||
|
|
9d3588f2be | ||
|
|
3d598256df | ||
|
|
ec1b1cf834 | ||
|
|
dfad7f471a | ||
|
|
44cd46a7e4 | ||
|
|
8705171233 | ||
|
|
4a8556ca58 | ||
|
|
8657342973 | ||
|
|
e38b892144 | ||
|
|
cfe623ae3e | ||
|
|
f44ace11fb | ||
|
|
104a867447 | ||
|
|
55b74d1ff5 | ||
|
|
59f6831336 | ||
|
|
77791b5633 | ||
|
|
c1c23e2f6a | ||
|
|
cd9bc14c8f | ||
|
|
c45e641c1d | ||
|
|
6bf423df2c | ||
|
|
db80b65402 | ||
|
|
49d8e5ebaa | ||
|
|
3cc17c69ff | ||
|
|
07b8dc68d6 | ||
|
|
8d51c9d376 | ||
|
|
2e22c2b477 | ||
|
|
7674da8057 | ||
|
|
69922c602c | ||
|
|
d478fc75b3 | ||
|
|
d1cee02783 | ||
|
|
d48035b06b | ||
|
|
0ef01d0a75 | ||
|
|
1004535237 | ||
|
|
8e9a71257d | ||
|
|
3425431370 | ||
|
|
f8ee88bbe0 | ||
|
|
92496abe0f | ||
|
|
6b07a6132f | ||
|
|
2e2e404ff7 | ||
|
|
02894b51f4 | ||
|
|
d7194f1b8e | ||
|
|
0e96d1b3f1 | ||
|
|
f382f4442e | ||
|
|
963d7c7ee6 | ||
|
|
d3912549a3 | ||
|
|
f43e03ee4f | ||
|
|
005a7f4190 | ||
|
|
181fe5016c | ||
|
|
6de1b39368 | ||
|
|
fcf6db0695 | ||
|
|
98b8568362 | ||
|
|
ea43fa104e | ||
|
|
1954d8021f | ||
|
|
49fe6dc89a | ||
|
|
3cb766344d | ||
|
|
f0dc0d50e3 | ||
|
|
2b67a40fdb | ||
|
|
66c11ec581 | ||
|
|
d4bd37a561 | ||
|
|
78d7c45b69 | ||
|
|
ed20ac56f7 | ||
|
|
5dd8ae6b9c | ||
|
|
0962358026 | ||
|
|
1080802e8f | ||
|
|
dc545d6512 | ||
|
|
b2cb75efb7 | ||
|
|
2b8a718d73 | ||
|
|
c292632b59 | ||
|
|
0d0646d915 | ||
|
|
dac79324b5 | ||
|
|
1ef26b35c1 | ||
|
|
836e46976f | ||
|
|
f256cfef4f | ||
|
|
fa1edff006 | ||
|
|
6837d46c1d | ||
|
|
26a9975fba | ||
|
|
0683c1ceef | ||
|
|
703c009681 | ||
|
|
42e0c59308 | ||
|
|
a77ffe66b2 | ||
|
|
2c103d5200 | ||
|
|
d432bcb9ac | ||
|
|
2ae17def52 | ||
|
|
09721e2314 | ||
|
|
c7fabe1f3e | ||
|
|
ac4f6b804f | ||
|
|
1129de5ac0 | ||
|
|
143c34109c | ||
|
|
af43565322 | ||
|
|
848dd0e762 | ||
|
|
04749e677f | ||
|
|
10f7ef0832 | ||
|
|
d1ba8b7659 | ||
|
|
6ae9383f63 | ||
|
|
37337427c3 | ||
|
|
c832bde05f | ||
|
|
b761ed2103 | ||
|
|
db0580d0a5 | ||
|
|
b2a237d337 | ||
|
|
5be4a84a58 | ||
|
|
e9786f40f5 | ||
|
|
8cbbaa052a | ||
|
|
9e44383e3f | ||
|
|
73aee8da54 | ||
|
|
26cbc91373 | ||
|
|
02fda44a30 | ||
|
|
d226dd2f59 | ||
|
|
0475de1350 | ||
|
|
55278dcc76 | ||
|
|
8dead2a6c6 | ||
|
|
b4c9a25eab | ||
|
|
b57b56f293 | ||
|
|
cb0fc063ed | ||
|
|
24c1000741 | ||
|
|
16b1f5e842 | ||
|
|
48ef64a729 | ||
|
|
4f94d90d4d | ||
|
|
6cb6947b99 | ||
|
|
2a68c2c21b | ||
|
|
d891452a73 | ||
|
|
e104acdb8c | ||
|
|
72ddcfd9ff | ||
|
|
dc790977d4 | ||
|
|
3665d0b2ff | ||
|
|
9c5cabb502 | ||
|
|
086a7616dd | ||
|
|
25f1264699 | ||
|
|
803264bb17 | ||
|
|
9be0d599cd | ||
|
|
f2a889564b | ||
|
|
fe3da09fa0 | ||
|
|
67c5f89af5 | ||
|
|
24ffb8e876 | ||
|
|
db1e10d5ea | ||
|
|
96e37d3bb8 | ||
|
|
9f142f0c84 | ||
|
|
565da3f569 | ||
|
|
a2e383820d | ||
|
|
2af921fb51 | ||
|
|
18fd7e8305 | ||
|
|
81e661f28b | ||
|
|
b753009a38 | ||
|
|
47538cc880 | ||
|
|
62a3a287d9 | ||
|
|
d01060241a | ||
|
|
6a41bf99bd | ||
|
|
7711afbb4a | ||
|
|
63f3832e81 | ||
|
|
0b2fd91890 | ||
|
|
562fa575a6 | ||
|
|
992284be39 | ||
|
|
cefcbb22b2 | ||
|
|
0bb971370b | ||
|
|
4d77e1a034 | ||
|
|
eb0a7129a5 | ||
|
|
b67253e96f | ||
|
|
4852e09c79 | ||
|
|
d155fecf9e | ||
|
|
12d6d777e1 | ||
|
|
74589cbeeb | ||
|
|
5330d8996f | ||
|
|
f3661d4100 | ||
|
|
7a074a14ce | ||
|
|
8a5aee103d | ||
|
|
bbaf68f2cb | ||
|
|
534574348e | ||
|
|
11aa6ba456 | ||
|
|
fe2eb5f58a | ||
|
|
993f067fa2 | ||
|
|
e5315f7ffd | ||
|
|
e41b21c01e | ||
|
|
8f7976ba0d | ||
|
|
2330fe08fe | ||
|
|
8c437f95fc | ||
|
|
4fddbe5ab6 | ||
|
|
1babb6d0c7 | ||
|
|
5d323defe4 | ||
|
|
71ebd4b7f0 | ||
|
|
70b3160871 | ||
|
|
379a3fa305 | ||
|
|
88b7f52ebb | ||
|
|
626ee90ce1 | ||
|
|
d38939e676 | ||
|
|
caf5c40c19 | ||
|
|
44bb616b53 | ||
|
|
4bfc491753 | ||
|
|
0c11b167a7 | ||
|
|
5687ce7e35 | ||
|
|
33ddb566a7 | ||
|
|
5c047b97f2 | ||
|
|
5cbeacebdb | ||
|
|
9ab94c468c | ||
|
|
3527085587 | ||
|
|
77fc276c08 | ||
|
|
e06cf89f04 | ||
|
|
3611c1de14 | ||
|
|
92ea99a0fb | ||
|
|
18605b36dc | ||
|
|
7102e51506 | ||
|
|
a7208bcc43 | ||
|
|
1cf82a9800 | ||
|
|
5ca1f5f9d9 | ||
|
|
49c2ad4fb4 | ||
|
|
36e2845e36 | ||
|
|
4a23a01945 | ||
|
|
eff359e114 | ||
|
|
59d14914cd | ||
|
|
c020109cfa | ||
|
|
571e3f5804 | ||
|
|
a6862fc812 | ||
|
|
4e3906d6b5 | ||
|
|
d09a5b51c2 | ||
|
|
2e24034c3f | ||
|
|
82fabf4e52 | ||
|
|
6b21c3fdd6 | ||
|
|
7807da20ab | ||
|
|
868fa82ea4 | ||
|
|
5d2344d009 | ||
|
|
2b899b6708 | ||
|
|
6ff9a47255 | ||
|
|
e1dfc44178 | ||
|
|
690458300b | ||
|
|
8c705233f3 | ||
|
|
1f91e92cc6 | ||
|
|
eff10f66a6 | ||
|
|
42495392da | ||
|
|
3d7bf5d4b1 | ||
|
|
b191038198 | ||
|
|
ee831cafa9 | ||
|
|
9e6c82960e | ||
|
|
078172dcab | ||
|
|
e8432b3c72 | ||
|
|
fa3b895145 | ||
|
|
29c4f92e13 | ||
|
|
3077fbff26 | ||
|
|
e89cc13e5c | ||
|
|
53e5e0fa28 | ||
|
|
e5039c6ff8 | ||
|
|
f80f1a7077 | ||
|
|
ed8b4da0db | ||
|
|
f6532bb9e0 | ||
|
|
d1c3788375 | ||
|
|
0868942e77 | ||
|
|
1b8e76b8e6 | ||
|
|
c1832fd206 | ||
|
|
aa730620bb | ||
|
|
87c6250b4c | ||
|
|
baafb290ad | ||
|
|
089c3f321e | ||
|
|
99f3f6b5de | ||
|
|
601c814603 | ||
|
|
ccf45a4283 | ||
|
|
0b32e50365 | ||
|
|
c385a639e6 | ||
|
|
b157a99a8b | ||
|
|
55d6218b9a | ||
|
|
65af7ebdc5 | ||
|
|
39ce2db181 | ||
|
|
d39c7aa517 | ||
|
|
b384bcc5de | ||
|
|
fb2006cc69 |
17
.travis.yml
17
.travis.yml
@@ -7,9 +7,11 @@ before_script:
|
||||
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
- sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -y python3.3 python3 gcc-4.7 gcc-multilib gcc-arm-none-eabi qemu-system mingw32
|
||||
- sudo apt-get install -y python3.4 python3 gcc-4.7 gcc-multilib gcc-arm-none-eabi qemu-system mingw32
|
||||
# For teensy build
|
||||
- sudo apt-get install realpath
|
||||
# For coverage testing
|
||||
- sudo pip install cpp-coveralls
|
||||
|
||||
script:
|
||||
- make -C minimal test
|
||||
@@ -25,8 +27,17 @@ script:
|
||||
- make -C cc3200 BTARGET=bootloader BTYPE=release
|
||||
- make -C windows CROSS_COMPILE=i586-mingw32msvc-
|
||||
|
||||
- (cd tests && MICROPY_CPYTHON3=python3.3 ./run-tests)
|
||||
- (cd tests && MICROPY_CPYTHON3=python3.3 ./run-tests --emit native)
|
||||
# run tests without coverage info
|
||||
#- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests)
|
||||
#- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests --emit native)
|
||||
|
||||
# run tests with coverage info
|
||||
- make -C unix CC=gcc-4.7 coverage
|
||||
- (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../unix/micropython_coverage ./run-tests)
|
||||
- (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../unix/micropython_coverage ./run-tests --emit native)
|
||||
|
||||
after_success:
|
||||
- (cd unix && coveralls --root .. --build-root . --gcov $(which gcov-4.7) --gcov-options '\-o build-coverage/' --include py --include extmod)
|
||||
|
||||
after_failure:
|
||||
- (cd tests && for exp in *.exp; do testbase=$(basename $exp .exp); echo -e "\nFAILURE $testbase"; diff -u $testbase.exp $testbase.out; done)
|
||||
|
||||
907
ACKNOWLEDGEMENTS
Normal file
907
ACKNOWLEDGEMENTS
Normal file
@@ -0,0 +1,907 @@
|
||||
The Micro Python project was proudly and successfully crowdfunded
|
||||
via a Kickstarter campaign which ended on 13th December 2013. The
|
||||
project was supported by 1923 very generous backers, who pledged
|
||||
for a total of 2320 pyboards.
|
||||
|
||||
Damien George, the project creator, is grateful to the people
|
||||
listed below (and others who asked not to be named), whose support
|
||||
of the project help make the code in this repository what it is
|
||||
today. The names appear in order of pledging.
|
||||
|
||||
3 Cliff Senkbeil
|
||||
4 MacDefender (http://www.macdefender.org)
|
||||
11 Shaun Walker - http://theshaun.com
|
||||
12 Robert Joscelyne
|
||||
17 Peter Simon, Germany
|
||||
18 theNetImp
|
||||
21 Eamonn Maguire
|
||||
22 Rob Knegjens
|
||||
27 Greg, https://www.logre.eu
|
||||
28 Rick S
|
||||
30 Norman Jaffe (OpenDragon)
|
||||
34 UltraBob was here.
|
||||
35 Geoffrey R. Thompson
|
||||
36 MrAtoni
|
||||
40 Proud to be a backer of Micro Python, Phil C. United Kingdom.
|
||||
42 www.babybadger.co.uk
|
||||
45 Mert
|
||||
46 Miles Cederman-Haysom
|
||||
47 unixarmy.com
|
||||
52 Proud to be here! Tonton Pommes
|
||||
54 Espen Sae-Tang Ottersen
|
||||
56 howang.hk
|
||||
58 Innovatology
|
||||
59 Marzsman
|
||||
63 Tristan A. Hearn
|
||||
64 Patrick Clarke
|
||||
65 Bryan Lyon
|
||||
70 Craig Burkhead
|
||||
72 Dr Igor Vizir
|
||||
73 Steve Iltis, @steven_iltis
|
||||
79 www.giacomo.inches.ch
|
||||
80 Alexander Gordeyev
|
||||
81 Steve Conklin www.ai4qr.com
|
||||
83 n1c0la5
|
||||
84 Matthew R. Johnson
|
||||
86 Jeppe Rishede
|
||||
87 Kirill Zakharenko - Russian Federation
|
||||
88 beltwaybureau.com
|
||||
93 felix svoboda
|
||||
95 Smart
|
||||
96 Stephen Goudge
|
||||
97 Dr Richard Whitaker, www.drrich.co.uk, UK
|
||||
99 Tim Robertson
|
||||
101 Rudy De Volder, www.devolder.be, Belgium
|
||||
104 August H., Wien
|
||||
107 Jason Hsu
|
||||
109 dstensnes
|
||||
110 Joe Reynolds (professorlamp)
|
||||
112 Michael Davies (AU) - @butterparty @spaceduststudio
|
||||
113 Jim Kirk, Westborough, MA, USA
|
||||
114 yfnt
|
||||
117 Even when it looks like someone is reaching for blue sky. Some days you just have to blindly support that dreamer.
|
||||
118 G. Todd Vaules - todd.vaules.net
|
||||
122 Gunnar Wehrhahn
|
||||
124 Eric Masser
|
||||
126 Vaibhav Sagar
|
||||
128 Eric Wallstedt
|
||||
129 Richard G Wiater
|
||||
130 Toby Nance
|
||||
132 Michael Fogleman
|
||||
133 Snepo Research www.snepo.com Gary says Hi!
|
||||
137 nic gihl
|
||||
138 Felix Yuan
|
||||
139 mmhanif
|
||||
141 James Snyder
|
||||
144 roddyr2
|
||||
146 Richard Jones <http://mechanicalcat.net/richard>
|
||||
147 Jon-Eric Simmons
|
||||
148 Craig "The Coder" Dunn
|
||||
150 Jesse S (USA)
|
||||
151 Matt I. - github.com/pengii23
|
||||
153 Seth Borders - sethborders.com
|
||||
155 David Zemon (http://david.zemon.name)
|
||||
156 Garry DuBose
|
||||
157 Apeiron Systems
|
||||
158 BAR
|
||||
160 Jakob Hedman
|
||||
163 Bryan Moffatt
|
||||
165 Moises Lorenzo, Tenerife Isl.
|
||||
166 Erik H.
|
||||
170 Peter George
|
||||
171 Nikolas Akerblom
|
||||
174 Chris (@chassing)
|
||||
176 Wei-Ning Huang
|
||||
178 Edd Barrett, UK
|
||||
179 Alec Langford
|
||||
180 Shunya Sato
|
||||
181 Serge GUILLAUME
|
||||
183 Dr. Ross A Lumley
|
||||
184 Dorian Pula
|
||||
189 Tendayi Mawushe
|
||||
190 SDanziger
|
||||
191 Sean O'Donnell
|
||||
192 Kevin McLaughlin
|
||||
193 Tommy Allen
|
||||
194 Beedlebub
|
||||
195 Brad Howes
|
||||
196 Mike B
|
||||
200 Aleš Bublík
|
||||
202 David Dever
|
||||
206 Danilo Bargen, https://dbrgn.ch/
|
||||
209 Brendan Curran-Johnson
|
||||
210 Piotr Maliński http://www.rkblog.rk.edu.pl
|
||||
211 SEE Co. - Science, Engineering and Education Co. - www.seeco.us
|
||||
215 Richard Lancaster
|
||||
218 Bilbo Baggins from Middle Zealand
|
||||
219 Ollie Guy
|
||||
221 Shlomo Zippel
|
||||
222 Andy Kenny
|
||||
223 Double-O-ren
|
||||
226 For the pleasure of @tinproject
|
||||
229 mfr
|
||||
230 Eric Floehr
|
||||
232 Matt from Adp.EU.Com
|
||||
234 Joanna Tustanowska & Wojciech Bederski
|
||||
235 Eric LeBlanc
|
||||
236 Siggy , Belgium
|
||||
238 Mauro De Giorgi
|
||||
239 Belug http://belug.ca/
|
||||
241 Arik Baratz - @arikb
|
||||
242 Zvika Palkovich
|
||||
243 Yves Dorfsman - yves at zioup dot com
|
||||
244 Asad Ansari, Canada
|
||||
245 Brandon Bennett
|
||||
246 Christoph Bluoss
|
||||
248 Konstantin Renner
|
||||
249 Abtin Afshar
|
||||
250 A. Soltani
|
||||
251 Jon Mills
|
||||
256 NoisyGecko
|
||||
258 Lothilius
|
||||
262 Jay Deiman
|
||||
263 flo at twigs dot de
|
||||
265 _Mark_ eichin at thok dot org
|
||||
267 Adrian Astley
|
||||
268 aknerats[::-1]
|
||||
271 @robberwick
|
||||
272 Daniele Lacamera
|
||||
273 Thanks to M. Derome
|
||||
275 Paul Paradigm, Australia
|
||||
276 lyuden
|
||||
277 www.SamuelJohn.de
|
||||
279 John Pinner, funthyme at gmail dot com
|
||||
280 Michael and Vicky Twomey-Lee
|
||||
281 Kenneth Ljungqvist
|
||||
292 Karin Beitins, Australia
|
||||
295 Nick Johnson
|
||||
297 Chris Cole U.K.
|
||||
298 The planet Andete is famous for its killer edible poets.
|
||||
302 Patrick B (aged 11)
|
||||
304 Chris Mason, Australia
|
||||
306 Steven Foster
|
||||
308 Pat Fleury, Andrew Hodgson
|
||||
311 @moneywithwings
|
||||
313 Neil Stephen
|
||||
314 Cory A. Johannsen
|
||||
315 Massimo Di Stefano - geofemengineering.it - Italy
|
||||
317 James Luscher, Madison, Wisconsin, USA
|
||||
319 Lindsay Watt
|
||||
320 Nils Fischbeck
|
||||
324 Peter J. Farrell - Maestro Publishing, LLC - Minneapolis, MN, USA
|
||||
325 Alex Willmer (@moreati)
|
||||
328 T.R. Renicker
|
||||
329 William B. Phelps
|
||||
330 David Goodger
|
||||
331 Viktoriya Skoryk
|
||||
334 JR Rickerson
|
||||
336 Keven Webb
|
||||
338 www.hcfengineering.com
|
||||
341 Larry Lab Rat, Shalford.
|
||||
342 Rob Hetland
|
||||
343 Brush Technology (NZ)
|
||||
346 Jason Fehr
|
||||
347 Olivier Vigneresse
|
||||
348 Nano Gennari, me at nngn dot net, Brasilia, Brazil
|
||||
352 Petr Viktorin (http://encukou.cz)
|
||||
355 Karijn Wessing (IN2TECH)
|
||||
356 Arsham Hatambeiki
|
||||
358 Alvaro Rivera-Rei
|
||||
360 Nolan & Theo Baldwin
|
||||
362 Tyler Baker, USA
|
||||
363 Russell Warren (Canada)
|
||||
365 Aaron Peterson
|
||||
366 Al Billings
|
||||
367 Jeremy Herbert
|
||||
372 Dimitrios Bogiatzoules, www.bogiatzoules.de, Germany
|
||||
375 Paul Nicholls
|
||||
376 Robert F. Brost
|
||||
378 Aideen (Cambridge, UK) - Very happy backer and follower of this great project
|
||||
379 Caelan Borowiec
|
||||
380 Caroline, Canada - carolinesimpson.ca
|
||||
382 Rikard Anglerud
|
||||
383 Scott Will
|
||||
384 Jussi Ylanen
|
||||
385 @joshbapiste
|
||||
387 spongefile
|
||||
389 Keith Baston
|
||||
392 Holger Steinlechner
|
||||
394 sent by State mail service
|
||||
398 N.Pearce, Wells UK - @t #ashtag UK
|
||||
399 Paid up & stood back;;
|
||||
401 Mike M. Tempe, AZ, USA
|
||||
406 Brandon Jasper
|
||||
407 Dan Mahoney
|
||||
411 George Bushnell, for use in CPSS
|
||||
412 Per Konradsson
|
||||
413 Supported by afinzel
|
||||
417 Tom Igoe
|
||||
418 Jonathan Saggau
|
||||
419 Chris Allick http://chrisallick.com
|
||||
420 joshuaalbers.com
|
||||
423 B. Adryan
|
||||
432 Tim Fuchs
|
||||
433 steven antalics
|
||||
434 BezouwenR
|
||||
435 Andrew Addison
|
||||
436 Hubert de L'arrêtdubus - France
|
||||
437 Salim Fadhley
|
||||
438 Ben Hockley
|
||||
439 Geoffrey Webb
|
||||
441 Vladimir Mikulik
|
||||
442 7 Elements & Troy Benjegerdes - hozer at hozed dot org
|
||||
443 Pashakun
|
||||
444 Craig Barnes, UK
|
||||
445 Andres Ayala
|
||||
446 Stonly Baptiste (urban.us)
|
||||
448 Brian Conner
|
||||
452 Jeremy Blum (jeremyblum.com)
|
||||
454 Pebble Technology
|
||||
455 Andrew
|
||||
456 Jeffrey Allen Randorf, PE PhD
|
||||
457 J.A.Zaratiegui a.k.a. Zara
|
||||
459 simon.vc and hack.rs
|
||||
462 La vida es para vivirla y ser feliz, de esa forma damos gracias por tan gran regalo!
|
||||
463 Alistair Walsh
|
||||
469 fun, Ireland
|
||||
474 martijnthe.nl
|
||||
479 Andreas Kobara
|
||||
486 Armanda
|
||||
487 Richard Myhill
|
||||
488 Ash Gibbons
|
||||
489 Glenn Franxman HackerMojo.com
|
||||
492 Russell Durrett
|
||||
494 Pieter Ennes
|
||||
495 Tom Gross, Washington D.C.
|
||||
496 Mark Schafer
|
||||
497 Sandro Dutra, Brazil
|
||||
500 Can Bulbul
|
||||
501 Chih-Chun Chen, http://abmcet.net/Chih-Chun_Chen/home.html
|
||||
502 Lost Property Bureau Ltd
|
||||
503 skakz
|
||||
504 Chad Cooper
|
||||
505 Makhan Virdi, mlvirdi.com, InfinityXLabs.com, USA
|
||||
507 Alasdair Allan
|
||||
509 dlbrandon
|
||||
511 Dr J Garcia, Sweden
|
||||
513 Tiago Vieira
|
||||
518 Team ME
|
||||
519 OBD Solutions (http://www.obdsol.com)
|
||||
520 @pors
|
||||
521 Joo Chew Ang
|
||||
523 garbas
|
||||
526 http://epoz.org/
|
||||
527 J. Sabater
|
||||
530 José-María Súnico
|
||||
537 Erfundnix
|
||||
538 Tontonisback Belgium
|
||||
539 Greg Benson, Professor, University of San Francisco
|
||||
542 Thomas Sarlandie aka @sarfata
|
||||
545 JanTheMan kickstarter at embedded-systems dot craftx dot biz
|
||||
546 Chuhan Frank Qin
|
||||
549 Peb R Aryan, Indonesia
|
||||
553 Johan Deimert, http://www.ldchome.org
|
||||
555 Conny Sjöblom / Finland
|
||||
558 AndyboyH, UK
|
||||
559 Anthony Lupinetti
|
||||
561 Travis Travelstead
|
||||
566 Siegfried Boyd Isidro-Cloudas
|
||||
567 G. Schroeer
|
||||
568 mmths, http://randomaccessmemory.at/
|
||||
570 Andy Miller - NZ..
|
||||
571 Rodolfo Lara from México
|
||||
572 Gary Patton Wolfe
|
||||
574 Vend-lab Russia
|
||||
578 Super Job! FXF
|
||||
579 Oliver Heggelbacher, www.kickdrive.de
|
||||
581 James Husum
|
||||
585 David Lodge
|
||||
587 Tess
|
||||
592 PR Taylor
|
||||
593 6306665119
|
||||
598 Jorg Bliesener, Brazil - www.bliesener.com
|
||||
602 Rodrigo, Germany
|
||||
605 Tanja Kaiser, www.mrsminirobot.de, Germany
|
||||
606 Franco Ponticelli - www.weblob.net
|
||||
608 Piet Hoffman
|
||||
609 Paul Cunnane
|
||||
610 Balazs Kinszler
|
||||
611 Nathan Ramella (synthesizerpatel)
|
||||
612 Tyler Jones (squirly)
|
||||
613 James Saffery
|
||||
614 Christoffer Sjowall
|
||||
615 Iman Shames
|
||||
616 Thomas Dejanovic, Australia.
|
||||
618 Tom Alker
|
||||
619 Matt Davis, UK
|
||||
621 Design for the real world! @UXnightingale
|
||||
622 Budd Van Lines
|
||||
624 __Gio__
|
||||
628 Chew Kok Hoor
|
||||
630 Santiago Alarcon, Thanks Damien for Micro Python
|
||||
632 hardtoneselector
|
||||
633 supported by Chris Bunker
|
||||
634 Sebus - France
|
||||
635 Mechanical Men Sweden
|
||||
638 A Fellow Electronics Enthusiast
|
||||
639 Stan Seibert
|
||||
642 Dave Curtis
|
||||
652 Sebastian Ross - www.ross.sx
|
||||
653 Julien Goodwin
|
||||
654 Reinoud de Lange, the Netherlands
|
||||
655 carl beck
|
||||
659 John Gaidimas
|
||||
660 Tyler Eckwright
|
||||
661 Keith Rome (Wintellect - http://www.wintellect.com/blogs/krome)
|
||||
662 Kashev Dalmia - kashevdalmia.com
|
||||
666 Alberto Martín de la Torre
|
||||
667 Niels Kjøller Hansen
|
||||
668 pmst - Italy
|
||||
671 Sergio Conde Gómez (skgsergio)
|
||||
672 Micromint, www.micromint.com
|
||||
675 Thank you
|
||||
677 Kacem Ben Dhiab
|
||||
679 CornishSteve
|
||||
680 Daniel Wood, Warrington, UK.
|
||||
682 Greg "GothAck" Miell
|
||||
688 Matt Williams & Sam Carter
|
||||
691 Frédéric Lasnier
|
||||
694 Tim K
|
||||
697 Joshua Clarke, Guernsey!
|
||||
700 daynewaterlow.com
|
||||
703 Scott Winder
|
||||
704 @DepletionMode
|
||||
707 Maria Yablonina
|
||||
710 Roger Hausermann
|
||||
713 Crazy_Owl
|
||||
714 mike hardin usa
|
||||
717 C. Towne Springer
|
||||
719 ursm gruesst euch
|
||||
720 madnis
|
||||
727 http://itay.bazoo.org
|
||||
729 @0atman
|
||||
730 Jerry Gagnon
|
||||
732 Emmanuel Boyer
|
||||
738 suspenders
|
||||
739 Roland Frédéric - http://www.creativeconvergence.be/
|
||||
742 @herchu
|
||||
745 Riley Lundquist
|
||||
746 Go LOBOS
|
||||
749 João Alves, http://jpralves.net, Portugal
|
||||
751 Nick Porcino
|
||||
753 Jack E. Wilkinson, Texas, USA
|
||||
754 @rcarmo on Twitter/Github
|
||||
758 Matt Manuel, www.mattmanuel.com
|
||||
759 Padraic D. Hallinan
|
||||
760 Rob Fairbairn
|
||||
763 Zac Luzader
|
||||
773 terje nagel, dk
|
||||
775 Luc LEGER
|
||||
782 Luis M. Morales S.
|
||||
785 Charles Edward Pax
|
||||
786 Daryl Cumbo
|
||||
787 Zephyris13
|
||||
788 Wonderful project.
|
||||
792 Sylvain Maziere
|
||||
794 Milen
|
||||
795 Robert Mai, Germany, hsapps.com
|
||||
797 Angelo Compagnucci angelo.compagnucci at gmail dot com
|
||||
801 Long Live Micro Python, airtripper.com
|
||||
804 António M P Mendes
|
||||
805 Marc Z.
|
||||
809 Anoyomouse
|
||||
810 in memory of Dan J. Schlacks III
|
||||
817 Peter Froehlich - http://werk-schau.blogspot.com
|
||||
818 Ahmad Albaqsami
|
||||
821 Peter Lavelle (http://solderintheveins.co.uk)
|
||||
822 Manuel Sagra de Diego http://manuelsagra.com/
|
||||
823 Sam Wilson
|
||||
824 Khalis
|
||||
825 c't Hacks
|
||||
828 Georg Bremer
|
||||
830 Ward en Sanne (WenS)
|
||||
832 javacasm http://www.elcacharreo.com Spain
|
||||
833 mctouch
|
||||
835 Bruce Schreiner @ www.stevenscollege.edu/electronics
|
||||
836 Jonas
|
||||
839 Nick Ludlam
|
||||
840 Patrick_Law, UK
|
||||
843 Alex Crouzen, UK
|
||||
848 Ben Banfield-Zanin
|
||||
850 Wouter Slegers, Your Creative Solutions <http://www.yourcreativesolutions.nl/>
|
||||
851 Fred Zyda
|
||||
853 Gianfranco Risaliti
|
||||
854 Ron Hochsprung
|
||||
858 Vianney Tran
|
||||
862 Aaron Mahler - http://halfpress.com
|
||||
868 Stephan Schulte, Germany
|
||||
869 Kenneth Henderick
|
||||
872 DaveP (www.davepeake.com)
|
||||
876 Kyle Gordon, http://lodge.glasgownet.com
|
||||
877 Joseph Gerard Campbell
|
||||
881 Thanks for the board. Good luck to you. --Jason Doege
|
||||
883 Garet McKinley
|
||||
884 www.magtouchelectronics.co.za
|
||||
889 Ben Johnson
|
||||
896 Ruairi Newman
|
||||
897 Gemma Hentsch
|
||||
902 Alexander Steppke
|
||||
906 Stephen Paulger
|
||||
907 Martin Buhr, http://lonelycode.com, UK
|
||||
912 Dale Drummond
|
||||
913 Go Utah State
|
||||
918 Jarturomartinez, Mexico
|
||||
921 Barry Bourne Micro Python Supporter
|
||||
923 Andreas Bolka
|
||||
927 Thanks Susan, Tom, Paul, and Mark!
|
||||
935 http://wall-y.fr
|
||||
937 Eero af Heurlin, Finland, https://github.com/rambo/
|
||||
938 Guillaume DAVY
|
||||
941 Alexander Steffen
|
||||
942 Janne "Lietu" Enberg
|
||||
945 Luca 'loop' de Marinis - https://github.com/loop23
|
||||
946 Andras Veres-Szentkiralyi http://techblog.vsza.hu/
|
||||
948 Florian flowolf Klien (http://blog.flo.cx)
|
||||
949 nickyb
|
||||
951 Mark Walland, England
|
||||
952 Ian Barfield
|
||||
953 Andrew Murray, UK - eat my code - http://links.bloater.org/micropython
|
||||
955 Kyle Howells
|
||||
956 Chris Cadonic
|
||||
957 LCS, USA: scripting___/||\===/||\___embedded
|
||||
958 Sven Wegener
|
||||
963 Kean Electronics http://www.kean.com.au/
|
||||
964 Beandob
|
||||
965 Don't feed the troll.
|
||||
966 Alexis Polti (http://rose.eu.org)
|
||||
969 Scottyler
|
||||
971 The Dead's Own Jones
|
||||
974 Evseev Alexey
|
||||
976 Arnaud
|
||||
978 Jannis Rosenbaum
|
||||
980 paul at fontenworks dot com
|
||||
981 John Griessen ecosensory.com USA
|
||||
982 Tobias Ammann
|
||||
983 Simon V.
|
||||
984 JaWi
|
||||
987 Ergun Kucukkose
|
||||
989 Jonathan Piat France
|
||||
990 Steve Pemberton
|
||||
993 Aaron Robson
|
||||
994 Antoine Authier
|
||||
995 Thomas Winkler, Austria
|
||||
997 Jannes mit dem dicken Pannes
|
||||
1001 Joe Baker
|
||||
1002 Jon Hylands, Canada (blog.huv.com)
|
||||
1004 Mike Asker (aka mpymike)
|
||||
1007 Charles V Bock - Charles at CharlesBock dot com
|
||||
1010 Remember June 4th, 1989
|
||||
1012 Stuart Marsden
|
||||
1014 Arthur P, USA
|
||||
1015 John Hall & Jeremy Armijo
|
||||
1017 Luciano Ramalho, Python.pro.br
|
||||
1018 Quentin Stafford-Fraser
|
||||
1019 Marcin Walendzik Ratingpedia.eu
|
||||
1020 Wincent Balin
|
||||
1022 rbp
|
||||
1024 Frank Carver ( www.frankcarver.me )
|
||||
1026 Peter Farmer, http://geekytronics.com/
|
||||
1029 Rubens Altimari
|
||||
1033 Sebastian
|
||||
1035 Gerli, Estonia
|
||||
1036 Maurin, Switzerland
|
||||
1037 Kevin Houlihan (http://crimsoncookie.com)
|
||||
1039 Jon Green of Adeptium Consulting (www.adeptium.com)
|
||||
1040 Eirik S. Mikkelsen
|
||||
1042 Jogy Sam
|
||||
1043 GGG
|
||||
1045 Sean E Palmer, epimetheon.com
|
||||
1049 Greg O'Drobinak, USA
|
||||
1050 RaptorBird Robotics Inc
|
||||
1051 Desmond Larsen-Rosner
|
||||
1056 Crusty
|
||||
1057 ArthurGuy.co.uk
|
||||
1059 Melissa-Ivan, 14/04/2013
|
||||
1064 Enrico Spinielli, https://github.com/espinielli
|
||||
1066 Dave Snowdon
|
||||
1067 Martin P. Hellwig
|
||||
1070 Carl Clement
|
||||
1074 Paul Taylor
|
||||
1076 Pandemon
|
||||
1082 Thrilled to support Damien's effort to put this together: there will no doubt be many applications for this effort and many enhancements and ports..
|
||||
1083 Oddvar Lovaas
|
||||
1090 BenScarb
|
||||
1093 Www.qualnetics.com
|
||||
1094 Manny Muro - Now Python can RULE from below as it does from above! PYTHON RULES!!! :)
|
||||
1095 Michael Grazebrook
|
||||
1098 Mark Shuttleworth, UK
|
||||
1106 wyzzar
|
||||
1110 Luca Zanetti
|
||||
1112 Carl A Fagg
|
||||
1115 Adam Klotblixt
|
||||
1118 Breawn
|
||||
1122 pippyisatruck
|
||||
1124 Andrew "ClothBot" Plumb
|
||||
1126 Realise the projects your heart beats for! Sven Wiebus (http://wiebus.tumblr.com)
|
||||
1128 Citius Systems
|
||||
1130 Benjamin & Reuben Fuller
|
||||
1131 aglimme
|
||||
1133 John Becker
|
||||
1135 Mark Drummond
|
||||
1138 JHProuty
|
||||
1141 Lars Olsson Sweden
|
||||
1144 daisuke, http://dkpyn.com
|
||||
1145 Chris Pawley - http://www.pawley.co.uk/honey/
|
||||
1147 Daniel from EzSBC.com
|
||||
1149 New York Mortgage Exchange NYME.COM
|
||||
1150 Herb Winters,USA,www.ecs87.com
|
||||
1151 renttu
|
||||
1159 Joe Rickerby
|
||||
1160 john guthrie
|
||||
1161 PUBLIC
|
||||
1163 dobra-dobra
|
||||
1164 Neil Reynolds, Staffordshire
|
||||
1165 GEHoward
|
||||
1166 Frank Delporte
|
||||
1167 Bauer Brauner Enterprise
|
||||
1168 Francisco Mardones
|
||||
1169 Ryan Kirkpatrick, @rkirkpatnet, http://rkirkpat.net/
|
||||
1170 Krister Svanlund
|
||||
1174 Derek Patton Pearcy
|
||||
1177 Roger Olsson, Sweden
|
||||
1179 Jan-Niklas Braak
|
||||
1180 Pete boy
|
||||
1181 MilenX
|
||||
1182 Ubbe Larsson
|
||||
1183 Simon Freethy
|
||||
1184 Daniel Andersson
|
||||
1187 Daniele Procida
|
||||
1190 Adrian Duke
|
||||
1191 Pauline Middelink
|
||||
1193 Ted Gueniche
|
||||
1197 Craig Knott, University of Queensland, Australia
|
||||
1198 Jamie Mackenzie - Australia
|
||||
1199 ravenoak
|
||||
1200 LucaP Luni Italy
|
||||
1203 jacanterbury
|
||||
1205 Bleachin, www.rhyspowell.com
|
||||
1207 Supported by Andrew Maier via Kickstarter
|
||||
1208 Rob, http://robjstanley.me.uk
|
||||
1210 George Gingell
|
||||
1213 Chris Elleman
|
||||
1215 Jack Barham - @jackbarham - http://jackbarham.com
|
||||
1221 Kyle Dausin
|
||||
1222 Ben Lucker
|
||||
1225 Gareth cheesewhisk Evans
|
||||
1226 Jacob Forsyth
|
||||
1227 Olof S - Germany
|
||||
1231 Brasil
|
||||
1233 glaslos
|
||||
1234 Will Cooke - http://www.whizzy.org
|
||||
1236 Andrew Wright - Canada
|
||||
1239 Resourceful Robin
|
||||
1240 Jay O'Neill @jayoneilluk
|
||||
1241 Dennis G Daniels
|
||||
1244 J. Peterson (www.saccade.com)
|
||||
1245 Chipaca
|
||||
1246 Nicko van Someren
|
||||
1247 C. Cumbaa, Canada
|
||||
1248 Gyro Gearloose was here
|
||||
1249 Magnus Ericmats, Sweden
|
||||
1253 Steve Wilson
|
||||
1256 Adrian Bullock
|
||||
1258 Sarevian & Longwall
|
||||
1261 Skipp Savage
|
||||
1265 Eric Nahon
|
||||
1267 Stuart Dallas / 3ft9 Ltd
|
||||
1270 USA
|
||||
1271 Oliver
|
||||
1277 jeffmcneill.com
|
||||
1278 alnjxn
|
||||
1283 Marc Liyanage
|
||||
1285 Christian Lange
|
||||
1286 Bryant Paul Umali from the Philippines
|
||||
1290 W.B.Hill, Norwich, UK
|
||||
1292 Michael Karliner
|
||||
1293 Oli Larkin
|
||||
1303 A. Pockberger
|
||||
1304 dc - bagel
|
||||
1305 Thadeus Arnel
|
||||
1308 technoweenie
|
||||
1309 Liam Welsh
|
||||
1313 Per Thorell, Sweden
|
||||
1314 peterlee
|
||||
1316 Dustin Mierau
|
||||
1317 tech-zen.tv
|
||||
1320 Cheers from IDF :)
|
||||
1322 www.a-d-k.de
|
||||
1323 rixx
|
||||
1324 @jlev
|
||||
1325 e2e4
|
||||
1328 Thomas J. Quinlan, London UK
|
||||
1329 Don Bone
|
||||
1331 Narayanamurthi
|
||||
1333 PGS_Astra-ProjeX_Wilts
|
||||
1337 Mark Schulz & Phillip Long, CEIT, The University of Queensland
|
||||
1340 Tiegeng (Tim) Ren
|
||||
1344 EMR_1344, DE
|
||||
1348 Matt Ward, Nottingham
|
||||
1351 Rupert
|
||||
1352 Cory Li - http://cory.li
|
||||
1354 Jim Davies, Brighton, UK
|
||||
1355 Jon Watkins, UK
|
||||
1356 Thomas, www.bitmix.de
|
||||
1359 Markus Gritsch
|
||||
1362 Carl H. Blomqvist
|
||||
1371 Brian Green
|
||||
1374 Ben Merryman
|
||||
1375 O'Dea
|
||||
1376 Josh Trujillo
|
||||
1378 Daniel Halloran
|
||||
1379 another_martin
|
||||
1383 Thanks for innovating!
|
||||
1385 CoderDojo Malahide
|
||||
1397 Jacob Z
|
||||
1398 Staffan Hillberg
|
||||
1399 http://kim.ht
|
||||
1402 Can't wait to plug it in!
|
||||
1403 Márton Szinovszki
|
||||
1405 sellorm says 'Hi!'
|
||||
1406 Thomas Provoost
|
||||
1411 Clive Freeman
|
||||
1412 Norman Thomas
|
||||
1415 Javier Llopis
|
||||
1417 Ho Man Fai
|
||||
1418 Anders Helland
|
||||
1421 Richard lavanture
|
||||
1425 Alan Churley, UK
|
||||
1426 Robert'); DROP TABLE Students;--unicode is fun!
|
||||
1427 Go Illini!
|
||||
1430 MicroPy FTW
|
||||
1431 Bryan Morrissey, www.browninnovations.com
|
||||
1436 Krzysztof Chomski, Poland
|
||||
1437 WellAware (USA)
|
||||
1441 Tomas Hau
|
||||
1443 Paul Way
|
||||
1444 Benjamin Anderson
|
||||
1445 Andrew Bates
|
||||
1446 Davide Di Blasi
|
||||
1451 Mathias Fischer
|
||||
1453 Drexore, NL
|
||||
1454 Marek Mroz
|
||||
1455 Mark Easley Jr. - USA
|
||||
1457 Joshua Warren
|
||||
1459 Rohan Menon
|
||||
1460 Paul Sokolovsky
|
||||
1461 Chris Foresman, @foresmac
|
||||
1475 USI
|
||||
1478 Chris Emerson
|
||||
1479 Ph. Truillet, France, http://www.irit.fr/~Philippe.Truillet
|
||||
1480 WAB3
|
||||
1481 Lucidologia.pl
|
||||
1482 Ed Hardebeck | www.hardebeck.us
|
||||
1484 Ludovic Léau-Mercier, www.coriolys.org, France
|
||||
1487 BLUEBOBO
|
||||
1488 Berno Kneer, Germany
|
||||
1491 Julian Eccli
|
||||
1494 Batman
|
||||
1495 Manuel Núñez Sánchez
|
||||
1496 Millie and Sadie Smith
|
||||
1499 Ronald Eddy
|
||||
1500 SynShop Las Vegas
|
||||
1503 This is really cool. - Jack Conway
|
||||
1507 Renesas Electronics America
|
||||
1509 Team
|
||||
1513 A. Lamborn KD0ZFY
|
||||
1514 olifink
|
||||
1520 mike at sustainable-opportunities dot com
|
||||
1521 luis almeida, Teresina - Brazil
|
||||
1523 Muhammad Jamaludin
|
||||
1524 Sdlion
|
||||
1525 Charles Rogers
|
||||
1526 Diego M. Aires, Brazil
|
||||
1529 muwatt.com
|
||||
1532 Proud supporter of microPython
|
||||
1535 Jesus J. de Felipe
|
||||
1536 slminneman.com -- Wow, an acknowledgement? ...really?
|
||||
1538 Mike (Meski) Smith
|
||||
1541 Piero Steinger
|
||||
1545 Alex Rembish (https://rembish.org)
|
||||
1551 Sergey [BuG2BuG] Sobko, Russia
|
||||
1553 Serge Krier
|
||||
1556 Luuk Derksen
|
||||
1561 Jimmy Caille (CH)
|
||||
1562 Jesús Leganés Combarro "piranna"
|
||||
1564 Viacheslav Olegovich Savitskiy
|
||||
1565 Jamie Whitehorn
|
||||
1567 Bagge Carlson
|
||||
1568 Milan Cermak
|
||||
1569 Matthias Lemp
|
||||
1570 BOFG
|
||||
1571 Johan Elmerfjord, Sweden
|
||||
1573 Matt Finch • fnch.io
|
||||
1574 Jean-Francois Paris
|
||||
1575 Florian Franzen, Germany
|
||||
1576 doganowscy.com
|
||||
1579 Stan Yamane
|
||||
1580 William Cirillo
|
||||
1583 David Dibben
|
||||
1584 Nicolás, Amelia, Luli y alecu
|
||||
1586 Alex W
|
||||
1591 Livia Maria Dias Tavares
|
||||
1593 d freymann chicago il & his australian shepherd jaldi
|
||||
1594 Barnstorm Studio, LLC
|
||||
1595 Sashi Penta
|
||||
1597 tflhyl
|
||||
1598 clacktronics
|
||||
1599 j3hyde
|
||||
1600 Rik Williams
|
||||
1602 Valeriy Van, Ukraine, w7software.com
|
||||
1603 Louis Taylor - https://github.com/kragniz
|
||||
1606 What's the derivative of (6.022 x 10^23)x? That's A(n)mol
|
||||
1611 Bailey & Brayden Yoong Policarpio
|
||||
1613 William Bettridge-Radford
|
||||
1617 Urbane Jackson
|
||||
1618 Henius
|
||||
1622 Alister Galpin, New Zealand
|
||||
1623 Marco Bertoldi
|
||||
1627 Julian Pistorius
|
||||
1628 www.neotral.com
|
||||
1632 ChrisB
|
||||
1633 Norbini
|
||||
1634 Eric Rand at Brownhatsecurity.com
|
||||
1636 Benjamin Eberle
|
||||
1637 MG Projects bvba, Geert Maertens, Belgium
|
||||
1640 Robson dos Santos França (Brasil)
|
||||
1642 Udine
|
||||
1643 Simon Critchley
|
||||
1644 Sven Haiges, Germany
|
||||
1645 Yi Qing Sim
|
||||
1646 "silicium" ("silicium_one", if "silicium" is busy)
|
||||
1648 Andy O'Malia, @andyomalia
|
||||
1650 RedCamelApps.com
|
||||
1652 Christoph Heer
|
||||
1653 AlisonW
|
||||
1654 Yannick Allard (Belgium) supported this project.
|
||||
1655 Andy Pointon, UK
|
||||
1660 Diego Cantalapiedra
|
||||
1664 Pepillou
|
||||
1670 Sonny Cannon
|
||||
1671 Rick W
|
||||
1672 David Chan, USA
|
||||
1674 Philip Rowlands
|
||||
1675 dieresys
|
||||
1676 T.R. Fullhart
|
||||
1683 Oleg Sidorkin
|
||||
1686 Tatsuro Yasukawa
|
||||
1687 Brad Smith, Somerville MA, USA
|
||||
1688 kristoffervikhansen.com
|
||||
1690 Nice Project de W6AKB Alan Biocca
|
||||
1691 Hiss Hisss Hissss Hiss Hiss Hissssssss
|
||||
1692 Alan Kennedy
|
||||
1698 ElChessu
|
||||
1701 Flower Craswell
|
||||
1702 David Fontenot
|
||||
1707 To innovation & creativity. Tony J Winter
|
||||
1708 Joakim Hentula
|
||||
1711 Michael Schaefer
|
||||
1713 Brody Radford ~ www.brodyradford.com
|
||||
1714 Charles Durrant
|
||||
1715 Rodrigo S.
|
||||
1718 Dima Shylo
|
||||
1719 Jiahao James Jian
|
||||
1722 Helen Wilson, Christ's Hospital
|
||||
1726 Martin Aule, http://hackest.org/
|
||||
1727 İsmail Etem Tezcan, Rasteda
|
||||
1728 Charlie "Blackfrog" Sizer
|
||||
1729 Matloob Qureshi
|
||||
1730 Travis Saul http://travissaul.com
|
||||
1731 Michael Cavins
|
||||
1733 Peter Köllensperger, Norway
|
||||
1734 Anne Harrison
|
||||
1736 Peter Bradeen
|
||||
1739 Fredrik Luthander
|
||||
1740 Nick LaRosa
|
||||
1744 Aladuino
|
||||
1745 dgrebb
|
||||
1746 Truls Unstad
|
||||
1748 Jesus Saves
|
||||
1750 Andy Stannard (@rockmonkey)
|
||||
1751 Daniel Atkinson
|
||||
1755 John Potter
|
||||
1758 Ian V
|
||||
1760 David Leinbach
|
||||
1761 nemec-automation.com
|
||||
1765 Supported by JoW with Hardwired TCP/IP from www.WIZnet.eu
|
||||
1767 misskniss, Boise Idaho. It is our responsibility to code the freedom we want to see in the world.
|
||||
1768 Jeff Vahue - Knowlogic Software Corp.
|
||||
1769 Pat Molloy
|
||||
1770 Greg Maxwell gregmaxwell-at-mac-dot-com
|
||||
1771 Rich Robinson
|
||||
1773 Ken Corey @ flippinbits.com
|
||||
1782 Acknowledged
|
||||
1785 Optimized Tomfoolery
|
||||
1791 Nontakan Nuntachit, Thailand
|
||||
1794 Rasit Eskicioglu - Canada
|
||||
1795 Simon Elliston Ball
|
||||
1796 pfh
|
||||
1798 John W. C. McNabb
|
||||
1799 Frank Sanborn
|
||||
1803 Morgan Hough
|
||||
1804 Sorcha Bowler
|
||||
1805 http://www.WayneKeenan.info
|
||||
1806 HBEE, hbee.eu
|
||||
1807 Deadlight
|
||||
1809 www.danenet.org
|
||||
1811 Sergey Nebolsin
|
||||
1813 Threv
|
||||
1817 dynsne
|
||||
1818 David Wright
|
||||
1819 John Warren
|
||||
1821 I wanted Erlang! (╯°□°)╯︵ ┻━┻
|
||||
1825 Howard R Hansen
|
||||
1828 Kevin Schumacher
|
||||
1833 Matthias Erll, Sweden
|
||||
1836 Matt Graham
|
||||
1837 thedawn
|
||||
1838 Ruby Feinstein
|
||||
1839 Gustavo Muñoz (timbergus)
|
||||
1840 Ian Paczek
|
||||
1841 Köteles Károly, Hungary
|
||||
1843 Tobias Sette Ferreira
|
||||
1846 x4FF3 <3 microPython
|
||||
1847 Enrico Faulhaber (Germany)
|
||||
1850 jolan00
|
||||
1854 Red Harbinger Inc
|
||||
1855 Noman
|
||||
1858 @DerLinkshaender
|
||||
1863 Jon Woodcock
|
||||
1864 Elmo, hakkerikartano.fi
|
||||
1865 Imaginals
|
||||
1866 Sam Hathaway and Rachel Stevens
|
||||
1874 Remo Sanges, SZN, Italy
|
||||
1875 Devraj Mukherjee
|
||||
1876 an Embedded fan
|
||||
1877 Peter Huisers
|
||||
1878 Kin-Wai Lee (Malaysia)
|
||||
1879 Samuel Hawksby-Robinson
|
||||
1881 R. Stock
|
||||
1886 Randy of Capistrano street backed Damien's MicroPython!
|
||||
1887 Rogério Bulha Siqueira - www.esd-talk.com - Brazil
|
||||
1889 NickE is happy to support such a worthy project!
|
||||
1892 John Boudreaux
|
||||
1894 Riverfreeloader
|
||||
1895 Jose Marcelino http://metavurt.net
|
||||
1896 T Britto-Borges
|
||||
1899 DannyWhitsonUSA
|
||||
1904 José Iván Ferrer Ruiz.
|
||||
1905 Tom Loredo
|
||||
1906 Gregory Perry USA
|
||||
1908 josephoberholtzer.com
|
||||
1910 Michael Klos, USA
|
||||
1912 Adam Mildenberger
|
||||
1913 R Anderson
|
||||
1914 Nikesh, USA
|
||||
1915 Bogdan Chivoiu, Romania
|
||||
1916 Scott C. Lemon, USA
|
||||
1918 Konstantin Ufimtsev (@KestL)
|
||||
1919 Benny Khoo
|
||||
1922 Nicci Tofts
|
||||
1925 Joshua Coxwell
|
||||
1926 Franklin Hamilton
|
||||
1929 Leroy Douglas
|
||||
1930 A ナルと fan from Nigeria who likes smileys, here's one for good measure :)
|
||||
1931 Kimmo Lahtinen, Finland
|
||||
1932 http://staybles.co.uk
|
||||
1937 The Olivetti's: Emanuele Laura Nausicaa Sibilla Ettore
|
||||
1940 Pascal Hirsch
|
||||
1942 cbernander, Sweden
|
||||
1944 Enrico M.
|
||||
1947 Dinis Cruz
|
||||
1949 Jonathan Greig, http://embroidermodder.github.io
|
||||
1950 Andy Bower
|
||||
1952 Gerard Hickey
|
||||
1953 Fabrice BARRAL was here ...
|
||||
1955 Pieter Röhling
|
||||
1957 uomorando, Italy
|
||||
1959 Acacio Cruz
|
||||
35
README.md
35
README.md
@@ -1,6 +1,12 @@
|
||||
[![Build Status][travis-img]][travis-repo]
|
||||
[![Build Status][travis-img]][travis-repo] [![Coverage Status][coveralls-img]][coveralls-repo] [![Issue Stats][istats-pr-img]][istats-pr-repo] [![Issue Stats][istats-issue-img]][istats-issue-repo]
|
||||
[travis-img]: https://travis-ci.org/micropython/micropython.png?branch=master
|
||||
[travis-repo]: https://travis-ci.org/micropython/micropython
|
||||
[coveralls-img]: https://coveralls.io/repos/micropython/micropython/badge.png?branch=master
|
||||
[coveralls-repo]: https://coveralls.io/r/micropython/micropython?branch=master
|
||||
[istats-pr-img]: http://issuestats.com/github/micropython/micropython/badge/pr
|
||||
[istats-pr-repo]: http://issuestats.com/github/micropython/micropython
|
||||
[istats-issue-img]: http://issuestats.com/github/micropython/micropython/badge/issue
|
||||
[istats-issue-repo]: http://issuestats.com/github/micropython/micropython
|
||||
|
||||
The Micro Python project
|
||||
========================
|
||||
@@ -9,37 +15,40 @@ The Micro Python project
|
||||
</p>
|
||||
|
||||
This is the Micro Python project, which aims to put an implementation
|
||||
of Python 3.x on a microcontroller.
|
||||
of Python 3.x on microcontrollers and small embedded systems.
|
||||
|
||||
WARNING: this project is in early beta stage and is subject to large
|
||||
changes of the code-base, including project-wide name changes and API
|
||||
changes.
|
||||
WARNING: this project is in beta stage and is subject to changes of the
|
||||
code-base, including project-wide name changes and API changes.
|
||||
|
||||
Micro Python implements the entire Python 3.4 syntax (including exceptions,
|
||||
"with", "yield from", etc.). The following core datatypes are provided:
|
||||
str (no Unicode support yet), bytes, bytearray, tuple, list, dict, set,
|
||||
array.array, collections.namedtuple, classes and instances. Builtin
|
||||
modules include sys, time, and struct. Note that only subset of
|
||||
str (including basic Unicode support), bytes, bytearray, tuple, list, dict,
|
||||
set, frozenset, array.array, collections.namedtuple, classes and instances.
|
||||
Builtin modules include sys, time, and struct. Note that only subset of
|
||||
Python 3.4 functionality implemented for the data types and modules.
|
||||
|
||||
See the repository www.github.com/micropython/pyboard for the Micro
|
||||
Python board, the officially supported reference electronic circuit board.
|
||||
|
||||
Major components in this repository:
|
||||
- py/ -- the core Python implementation, including compiler and runtime.
|
||||
- py/ -- the core Python implementation, including compiler, runtime, and
|
||||
core library.
|
||||
- unix/ -- a version of Micro Python that runs on Unix.
|
||||
- stmhal/ -- a version of Micro Python that runs on the Micro Python board
|
||||
with an STM32F405RG (using ST's Cube HAL drivers).
|
||||
- teensy/ -- a version of Micro Python that runs on the Teensy 3.1
|
||||
(preliminary but functional).
|
||||
- minimal/ -- a minimal Micro Python port. Start with this if you want
|
||||
to port Micro Python to another microcontroller.
|
||||
|
||||
Additional components:
|
||||
- bare-arm/ -- a bare minimum version of Micro Python for ARM MCUs. Start
|
||||
with this if you want to port Micro Python to another microcontroller.
|
||||
- bare-arm/ -- a bare minimum version of Micro Python for ARM MCUs. Used
|
||||
mostly to control code size.
|
||||
- teensy/ -- a version of Micro Python that runs on the Teensy 3.1
|
||||
(preliminary but functional).
|
||||
- unix-cpy/ -- a version of Micro Python that outputs bytecode (for testing).
|
||||
- tests/ -- test framework and test scripts.
|
||||
- tools/ -- various tools, including the pyboard.py module.
|
||||
- examples/ -- a few example Python scripts.
|
||||
- docs/ -- official documentation in RST format.
|
||||
|
||||
"make" is used to build the components, or "gmake" on BSD-based systems.
|
||||
You will also need bash and Python (at least 2.7 or 3.3).
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#define MICROPY_EMIT_INLINE_THUMB (0)
|
||||
#define MICROPY_COMP_MODULE_CONST (0)
|
||||
#define MICROPY_COMP_CONST (0)
|
||||
#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (0)
|
||||
#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (0)
|
||||
#define MICROPY_MEM_STATS (0)
|
||||
#define MICROPY_DEBUG_PRINTERS (0)
|
||||
#define MICROPY_ENABLE_GC (0)
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<configurations XML_version="1.2" id="configurations_0">
|
||||
<configuration XML_version="1.2" id="Stellaris In-Circuit Debug Interface_0">
|
||||
<instance XML_version="1.2" desc="Stellaris In-Circuit Debug Interface_0" href="connections/Stellaris_ICDI_Connection.xml" id="Stellaris In-Circuit Debug Interface_0" xml="Stellaris_ICDI_Connection.xml" xmlpath="connections"/>
|
||||
<connection XML_version="1.2" id="Stellaris In-Circuit Debug Interface_0">
|
||||
<instance XML_version="1.2" href="drivers/stellaris_cs_icepick.xml" id="drivers" xml="stellaris_cs_icepick.xml" xmlpath="drivers"/>
|
||||
<instance XML_version="1.2" href="drivers/stellaris_cs_dap.xml" id="drivers" xml="stellaris_cs_dap.xml" xmlpath="drivers"/>
|
||||
<instance XML_version="1.2" href="drivers/stellaris_cortex_m4.xml" id="drivers" xml="stellaris_cortex_m4.xml" xmlpath="drivers"/>
|
||||
<platform XML_version="1.2" id="platform_0">
|
||||
<instance XML_version="1.2" desc="CC3200_0" href="devices/CC3200.xml" id="CC3200_0" xml="CC3200.xml" xmlpath="devices"/>
|
||||
</platform>
|
||||
</connection>
|
||||
</configuration>
|
||||
</configurations>
|
||||
@@ -83,14 +83,14 @@
|
||||
#define configUSE_TICK_HOOK 1
|
||||
#define configCPU_CLOCK_HZ ( ( unsigned long ) 80000000 )
|
||||
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 64 )
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 72 )
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 16384 ) )
|
||||
#define configMAX_TASK_NAME_LEN ( 12 )
|
||||
#define configMAX_TASK_NAME_LEN ( 8 )
|
||||
#define configUSE_TRACE_FACILITY 0
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configUSE_MUTEXES 1
|
||||
#define configUSE_MUTEXES 0
|
||||
#define configUSE_RECURSIVE_MUTEXES 0
|
||||
#ifdef DEBUG
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 1
|
||||
@@ -151,9 +151,4 @@ See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
||||
version. */
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "debug.h"
|
||||
#define configASSERT( x ) ASSERT( x )
|
||||
#endif
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
|
||||
@@ -202,6 +202,7 @@ static void prvTaskExitError( void );
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
__attribute__ ((section (".boot")))
|
||||
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
|
||||
{
|
||||
/* Simulate the stack frame as it would be created by a context switch
|
||||
@@ -220,6 +221,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__attribute__ ((section (".boot")))
|
||||
static void prvTaskExitError( void )
|
||||
{
|
||||
/* A function that implements a task must not exit or attempt to return to
|
||||
@@ -254,6 +256,7 @@ void vPortSVCHandler( void )
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__attribute__ ((section (".boot")))
|
||||
static void prvPortStartFirstTask( void )
|
||||
{
|
||||
__asm volatile(
|
||||
@@ -274,6 +277,7 @@ static void prvPortStartFirstTask( void )
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
__attribute__ ((section (".boot")))
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
/* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.
|
||||
@@ -643,6 +647,7 @@ void xPortSysTickHandler( void )
|
||||
* Setup the systick timer to generate the tick interrupts at the required
|
||||
* frequency.
|
||||
*/
|
||||
__attribute__ ((section (".boot")))
|
||||
__attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||
{
|
||||
/* Calculate the constants required to configure the tick interrupt. */
|
||||
|
||||
@@ -515,6 +515,7 @@ static void prvResetNextTaskUnblockTime( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__attribute__ ((section (".boot")))
|
||||
BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
@@ -1454,6 +1455,7 @@ TCB_t * pxNewTCB;
|
||||
#endif /* ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__attribute__ ((section (".boot")))
|
||||
void vTaskStartScheduler( void )
|
||||
{
|
||||
BaseType_t xReturn;
|
||||
@@ -2700,7 +2702,7 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
|
||||
}
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__attribute__ ((section (".boot")))
|
||||
static void prvInitialiseTCBVariables( TCB_t * const pxTCB, const char * const pcName, UBaseType_t uxPriority, const MemoryRegion_t * const xRegions, const uint16_t usStackDepth ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
{
|
||||
UBaseType_t x;
|
||||
@@ -2809,7 +2811,7 @@ UBaseType_t x;
|
||||
|
||||
#endif /* portUSING_MPU_WRAPPERS */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__attribute__ ((section (".boot")))
|
||||
static void prvInitialiseTaskLists( void )
|
||||
{
|
||||
UBaseType_t uxPriority;
|
||||
@@ -2912,7 +2914,7 @@ static void prvAddCurrentTaskToDelayedList( const TickType_t xTimeToWake )
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__attribute__ ((section (".boot")))
|
||||
static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer )
|
||||
{
|
||||
TCB_t *pxNewTCB;
|
||||
|
||||
@@ -5,16 +5,16 @@ ifeq ($(wildcard boards/$(BOARD)/.),)
|
||||
$(error Invalid BOARD specified)
|
||||
endif
|
||||
|
||||
BTYPE ?= release
|
||||
|
||||
# If the build directory is not given, make it reflect the board name.
|
||||
BUILD ?= build/$(BOARD)
|
||||
BUILD ?= build/$(BOARD)/$(BTYPE)
|
||||
|
||||
include ../py/mkenv.mk
|
||||
-include ../../localconfig.mk
|
||||
|
||||
CROSS_COMPILE ?= arm-none-eabi-
|
||||
|
||||
BTYPE ?= release
|
||||
|
||||
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -march=armv7e-m -mabi=aapcs -mcpu=cortex-m4 -msoft-float -mfloat-abi=soft -fsingle-precision-constant -Wdouble-promotion
|
||||
CFLAGS = -Wall -Wpointer-arith -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M4)
|
||||
CFLAGS += -g -ffunction-sections -fdata-sections -fno-common -fsigned-char -mno-unaligned-access
|
||||
|
||||
@@ -25,11 +25,13 @@ make BTARGET=bootloader BTYPE=release
|
||||
```
|
||||
|
||||
## Flashing the CC3200
|
||||
- Make sure that you have built both the *bootloader* and the *application* in **release** mode.
|
||||
- Make sure the SOP2 jumper is in position.
|
||||
- Open CCS_Uniflash and connect to the board (by default on port 22).
|
||||
- Format the serial flash (select 1MB size in case of the CC3200-LAUNCHXL, leave the rest unchecked).
|
||||
- Mark the following files for erasing: `/cert/ca.pem`, `/cert/client.pm`, `/cert/private.key` and `/tmp/pac.bin`.
|
||||
- Add a new file with the name of /sys/factimg.bin, and select the correct URL to point to cc3200\build\<BOARD_NAME>\MCUIMG.BIN.
|
||||
- Add a new file with the name of /sys/mcuimg.bin, and select the URL to point to cc3200\bootmgr\build\<BOARD_NAME>\bootloader.bin.
|
||||
- Add another file with the name of /sys/factimg.bin, and select the URL to point to cc3200\build\<BOARD_NAME>\MCUIMG.BIN.
|
||||
- Click "Program" to apply all changes.
|
||||
- Flash the latest service pack (servicepack_1.0.0.1.2.bin) using the "Service Pack Update" button.
|
||||
- Close CCS_Uniflash, remove the SOP2 jumper and reset the board.
|
||||
@@ -79,4 +81,3 @@ sure that encryption is set to: "Only use plain FTP (insecure)". In the Transfer
|
||||
to one, otherwise FileZilla will try to open a second command connection when retrieving and saving files, and for simplicity and
|
||||
to reduce code size, only one command and one data connections are possible.
|
||||
|
||||
|
||||
@@ -1,41 +1,3 @@
|
||||
/*****************************************************************************
|
||||
* cc3200.lds
|
||||
*
|
||||
* GCC Linker script for the CC3200
|
||||
*
|
||||
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
@@ -62,8 +24,8 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
__stack_size__ = 1024; /* interrupts are handled using this stack */
|
||||
__min_heap_size__ = 4K;
|
||||
__stack_size__ = 2K; /* interrupts are handled within this stack */
|
||||
__min_heap_size__ = 8K;
|
||||
__rtos_heap_size = 16K;
|
||||
|
||||
MEMORY
|
||||
@@ -84,8 +46,6 @@ SECTIONS
|
||||
. = ALIGN(8);
|
||||
} > SRAMB
|
||||
|
||||
_ertos_heap = ORIGIN(SRAMB) + LENGTH(SRAMB);
|
||||
|
||||
.text :
|
||||
{
|
||||
_text = .;
|
||||
@@ -103,13 +63,8 @@ SECTIONS
|
||||
__exidx_end = .;
|
||||
_etext = .;
|
||||
} > SRAM
|
||||
|
||||
__init_data = .;
|
||||
|
||||
/* used by the start-up to initialize data */
|
||||
_sidata = LOADADDR(.data);
|
||||
|
||||
.data : AT(__init_data)
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
_data = .;
|
||||
@@ -127,6 +82,17 @@ SECTIONS
|
||||
. = ALIGN(8);
|
||||
_ebss = .;
|
||||
} > SRAM
|
||||
|
||||
/* place here functions that are only called during boot up, */
|
||||
/* that way, we can re-use this area for the micropython heap */
|
||||
.boot :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
_boot = .;
|
||||
*(.boot*)
|
||||
. = ALIGN(8);
|
||||
_eboot = .;
|
||||
} > SRAM
|
||||
|
||||
/* allocate the micropython heap */
|
||||
.heap :
|
||||
|
||||
@@ -10,14 +10,14 @@ APP_INC += -Ihal
|
||||
APP_INC += -Ihal/inc
|
||||
APP_INC += -Imisc
|
||||
APP_INC += -Imods
|
||||
APP_INC += -I../drivers/cc3100/inc
|
||||
APP_INC += -Isimplelink
|
||||
APP_INC += -Isimplelink/include
|
||||
APP_INC += -Isimplelink/oslib
|
||||
APP_INC += -Itelnet
|
||||
APP_INC += -Iutil
|
||||
APP_INC += -Ibootmgr
|
||||
APP_INC += -I$(PY_SRC)
|
||||
APP_INC += -I$(BUILD)
|
||||
APP_INC += -I$(BUILD)/genhdr
|
||||
APP_INC += -I../lib/fatfs
|
||||
APP_INC += -I../lib/mp-readline
|
||||
APP_INC += -I../stmhal
|
||||
@@ -76,8 +76,10 @@ APP_MISC_SRC_C = $(addprefix misc/,\
|
||||
FreeRTOSHooks.c \
|
||||
pin_named_pins.c \
|
||||
help.c \
|
||||
mpcallback.c \
|
||||
mperror.c \
|
||||
mpexception.c \
|
||||
mpsystick.c \
|
||||
pin_defs_cc3200.c \
|
||||
)
|
||||
|
||||
@@ -88,23 +90,29 @@ APP_MODS_SRC_C = $(addprefix mods/,\
|
||||
modusocket.c \
|
||||
modutime.c \
|
||||
modwlan.c \
|
||||
pybextint.c \
|
||||
pybadc.c \
|
||||
pybpin.c \
|
||||
pybi2c.c \
|
||||
pybrtc.c \
|
||||
pybstdio.c \
|
||||
pybsystick.c \
|
||||
pybsd.c \
|
||||
pybsleep.c \
|
||||
pybspi.c \
|
||||
pybuart.c \
|
||||
pybwdt.c \
|
||||
)
|
||||
|
||||
APP_CC3100_SRC_C = $(addprefix drivers/cc3100/src/,\
|
||||
device.c \
|
||||
driver.c \
|
||||
flowcont.c \
|
||||
fs.c \
|
||||
netapp.c \
|
||||
netcfg.c \
|
||||
socket.c \
|
||||
wlan.c \
|
||||
)
|
||||
|
||||
APP_SL_SRC_C = $(addprefix simplelink/,\
|
||||
source/device.c \
|
||||
source/driver.c \
|
||||
source/flowcont.c \
|
||||
source/fs.c \
|
||||
source/netapp.c \
|
||||
source/netcfg.c \
|
||||
source/socket.c \
|
||||
source/wlan.c \
|
||||
oslib/osi_freertos.c \
|
||||
cc_pal.c \
|
||||
)
|
||||
@@ -122,6 +130,7 @@ APP_UTIL_SRC_C = $(addprefix util/,\
|
||||
|
||||
APP_UTIL_SRC_S = $(addprefix util/,\
|
||||
gchelper.s \
|
||||
sleeprestore.s \
|
||||
)
|
||||
|
||||
APP_MAIN_SRC_C = \
|
||||
@@ -144,11 +153,12 @@ APP_STM_SRC_C = $(addprefix stmhal/,\
|
||||
moduselect.c \
|
||||
printf.c \
|
||||
pyexec.c \
|
||||
pybstdio.c \
|
||||
string0.c \
|
||||
)
|
||||
|
||||
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(APP_FATFS_SRC_C:.c=.o) $(APP_RTOS_SRC_C:.c=.o) $(APP_FTP_SRC_C:.c=.o) $(APP_HAL_SRC_C:.c=.o) $(APP_MISC_SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(APP_MODS_SRC_C:.c=.o) $(APP_SL_SRC_C:.c=.o) $(APP_TELNET_SRC_C:.c=.o) $(APP_UTIL_SRC_C:.c=.o) $(APP_UTIL_SRC_S:.s=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(APP_MODS_SRC_C:.c=.o) $(APP_CC3100_SRC_C:.c=.o) $(APP_SL_SRC_C:.c=.o) $(APP_TELNET_SRC_C:.c=.o) $(APP_UTIL_SRC_C:.c=.o) $(APP_UTIL_SRC_S:.s=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(APP_MAIN_SRC_C:.c=.o) $(APP_LIB_SRC_C:.c=.o) $(APP_STM_SRC_C:.c=.o))
|
||||
OBJ += $(BUILD)/pins.o
|
||||
|
||||
@@ -160,7 +170,7 @@ LDFLAGS += -T $(LINKER_SCRIPT)
|
||||
CFLAGS += $(APP_CPPDEFINES) $(APP_INC)
|
||||
|
||||
# Disable strict aliasing for the simplelink driver
|
||||
$(BUILD)/simplelink/source/driver.o: CFLAGS += -fno-strict-aliasing
|
||||
$(BUILD)/drivers/cc3100/src/driver.o: CFLAGS += -fno-strict-aliasing
|
||||
|
||||
# Check if we would like to debug the port code
|
||||
ifeq ($(BTYPE), release)
|
||||
@@ -180,10 +190,14 @@ $(BUILD)/hal/%.o: CFLAGS += -Os
|
||||
$(BUILD)/misc/%.o: CFLAGS += -Os
|
||||
$(BUILD)/py/%.o: CFLAGS += -Os
|
||||
$(BUILD)/simplelink/%.o: CFLAGS += -Os
|
||||
$(BUILD)/drivers/cc3100/%.o: CFLAGS += -Os
|
||||
$(BUILD)/stmhal/%.o: CFLAGS += -Os
|
||||
$(BUILD)/telnet/%.o: CFLAGS += -Os
|
||||
$(BUILD)/util/%.o: CFLAGS += -Os
|
||||
$(BUILD)/pins.o: CFLAGS += -Os
|
||||
$(BUILD)/main.o: CFLAGS += -Os
|
||||
$(BUILD)/mptask.o: CFLAGS += -Os
|
||||
$(BUILD)/servertask.o: CFLAGS += -Os
|
||||
else
|
||||
$(error Invalid BTYPE specified)
|
||||
endif
|
||||
@@ -205,7 +219,7 @@ $(BUILD)/application.bin: $(BUILD)/application.axf
|
||||
|
||||
$(BUILD)/MCUIMG.BIN: $(BUILD)/application.bin
|
||||
$(ECHO) "Create $@"
|
||||
$(Q)$(SHELL) $(APP_SIGN) $(BOARD)
|
||||
$(Q)$(SHELL) $(APP_SIGN) $(BOARD) $(BTYPE)
|
||||
|
||||
MAKE_PINS = boards/make-pins.py
|
||||
BOARD_PINS = boards/$(BOARD)/pins.csv
|
||||
@@ -214,7 +228,7 @@ PREFIX_FILE = boards/cc3200_prefix.c
|
||||
GEN_PINS_SRC = $(BUILD)/pins.c
|
||||
GEN_PINS_HDR = $(HEADER_BUILD)/pins.h
|
||||
GEN_PINS_QSTR = $(BUILD)/pins_qstr.h
|
||||
|
||||
|
||||
# Making OBJ use an order-only dependency on the generated pins.h file
|
||||
# has the side effect of making the pins.h file before we actually compile
|
||||
# any of the objects. The normal dependency generation will deal with the
|
||||
|
||||
@@ -1,17 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$#" -ne 2 ]; then
|
||||
echo "Usage: appsign.sh *board type* *build type*"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BOARD=$1
|
||||
BTYPE=$2
|
||||
|
||||
# Build location
|
||||
# First parameter passed is the board type
|
||||
BUILD=build/$1
|
||||
# Based on build type and board type
|
||||
BUILD=build/${BOARD}/${BTYPE}
|
||||
|
||||
# Generate the MD5 hash
|
||||
echo -n md5sum --binary $BUILD/application.bin | awk '{ print $1 }' > __md5hash.bin
|
||||
echo -n `md5sum --binary $BUILD/application.bin | awk '{ print $1 }'` > __md5hash.bin
|
||||
|
||||
# Concatenate it with the application binary
|
||||
cat $BUILD/application.bin __md5hash.bin > $BUILD/MCUIMG.BIN
|
||||
RET=$?
|
||||
|
||||
# Remove the tmp files
|
||||
rm -f __md5hash.bin
|
||||
|
||||
# Remove hte unsigned binary
|
||||
rm -f $BUILD/application.bin
|
||||
|
||||
exit $RET
|
||||
|
||||
@@ -30,9 +30,23 @@
|
||||
#define MICROPY_HW_BOARD_NAME "LaunchPad"
|
||||
#define MICROPY_HW_MCU_NAME "CC3200"
|
||||
|
||||
#define MICROPY_HW_HAS_SDCARD (1)
|
||||
#define MICROPY_HW_HAS_SDCARD (0)
|
||||
#define MICROPY_HW_ENABLE_RNG (1)
|
||||
#define MICROPY_HW_ENABLE_RTC (1)
|
||||
|
||||
#define MICROPY_STDIO_UART PYB_UART_1
|
||||
#define MICROPY_STDIO_UART PYB_UART_0
|
||||
#define MICROPY_STDIO_UART_BAUD 115200
|
||||
#define MICROPY_STDIO_UART_RX_BUF_SIZE 128
|
||||
|
||||
#define MICROPY_SYS_LED_PRCM PRCM_GPIOA1
|
||||
#define MICROPY_SAFE_BOOT_PRCM PRCM_GPIOA2
|
||||
#define MICROPY_SYS_LED_PORT GPIOA1_BASE
|
||||
#define MICROPY_SAFE_BOOT_PORT GPIOA2_BASE
|
||||
#define MICROPY_SYS_LED_GPIO pin_GPIO9
|
||||
#define MICROPY_SYS_LED_PIN_NUM PIN_64 // GPIO9
|
||||
#define MICROPY_SAFE_BOOT_PIN_NUM PIN_15 // GPIO22
|
||||
#define MICROPY_SYS_LED_PORT_PIN GPIO_PIN_1
|
||||
#define MICROPY_SAFE_BOOT_PORT_PIN GPIO_PIN_6
|
||||
|
||||
#define MICROPY_PORT_SFLASH_BLOCK_COUNT 32
|
||||
|
||||
|
||||
51
cc3200/boards/WIPY-SD/mpconfigboard.h
Normal file
51
cc3200/boards/WIPY-SD/mpconfigboard.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define LAUNCHXL
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "WiPy-SD"
|
||||
#define MICROPY_HW_MCU_NAME "CC3200"
|
||||
|
||||
#define MICROPY_HW_HAS_SDCARD (1)
|
||||
#define MICROPY_HW_ENABLE_RNG (1)
|
||||
#define MICROPY_HW_ENABLE_RTC (1)
|
||||
|
||||
#define MICROPY_STDIO_UART PYB_UART_0
|
||||
#define MICROPY_STDIO_UART_BAUD 115200
|
||||
#define MICROPY_STDIO_UART_RX_BUF_SIZE 128
|
||||
|
||||
#define MICROPY_SYS_LED_PRCM PRCM_GPIOA3
|
||||
#define MICROPY_SAFE_BOOT_PRCM PRCM_GPIOA3
|
||||
#define MICROPY_SYS_LED_PORT GPIOA3_BASE
|
||||
#define MICROPY_SAFE_BOOT_PORT GPIOA3_BASE
|
||||
#define MICROPY_SYS_LED_GPIO pin_GPIO25
|
||||
#define MICROPY_SYS_LED_PIN_NUM PIN_21 // GPIO25 (SOP2)
|
||||
#define MICROPY_SAFE_BOOT_PIN_NUM PIN_18 // GPIO28
|
||||
#define MICROPY_SYS_LED_PORT_PIN GPIO_PIN_1
|
||||
#define MICROPY_SAFE_BOOT_PORT_PIN GPIO_PIN_4
|
||||
|
||||
#define MICROPY_PORT_SFLASH_BLOCK_COUNT 96
|
||||
25
cc3200/boards/WIPY-SD/pins.csv
Normal file
25
cc3200/boards/WIPY-SD/pins.csv
Normal file
@@ -0,0 +1,25 @@
|
||||
L2,GPIO2
|
||||
L3,GPIO1
|
||||
L4,GPIO23
|
||||
L5,GPIO24
|
||||
L6,GPIO11
|
||||
L7,GPIO12
|
||||
L8,GPIO13
|
||||
L9,GPIO14
|
||||
L10,GPIO15
|
||||
L11,GPIO16
|
||||
L12,GPIO17
|
||||
L13,GPIO22
|
||||
L14,GPIO28
|
||||
R4,GPIO10
|
||||
R5,GPIO9
|
||||
R6,GPIO8
|
||||
R7,GPIO7
|
||||
R8,GPIO6
|
||||
R9,GPIO30
|
||||
R10,GPIO31
|
||||
R11,GPIO3
|
||||
R12,GPIO0
|
||||
R13,GPIO4
|
||||
R14,GPIO5
|
||||
HBL,GPIO25
|
||||
|
51
cc3200/boards/WIPY/mpconfigboard.h
Normal file
51
cc3200/boards/WIPY/mpconfigboard.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define LAUNCHXL
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "WiPy"
|
||||
#define MICROPY_HW_MCU_NAME "CC3200"
|
||||
|
||||
#define MICROPY_HW_HAS_SDCARD (0)
|
||||
#define MICROPY_HW_ENABLE_RNG (1)
|
||||
#define MICROPY_HW_ENABLE_RTC (1)
|
||||
|
||||
#define MICROPY_STDIO_UART PYB_UART_0
|
||||
#define MICROPY_STDIO_UART_BAUD 115200
|
||||
#define MICROPY_STDIO_UART_RX_BUF_SIZE 128
|
||||
|
||||
#define MICROPY_SYS_LED_PRCM PRCM_GPIOA3
|
||||
#define MICROPY_SAFE_BOOT_PRCM PRCM_GPIOA3
|
||||
#define MICROPY_SYS_LED_PORT GPIOA3_BASE
|
||||
#define MICROPY_SAFE_BOOT_PORT GPIOA3_BASE
|
||||
#define MICROPY_SYS_LED_GPIO pin_GPIO25
|
||||
#define MICROPY_SYS_LED_PIN_NUM PIN_21 // GPIO25 (SOP2)
|
||||
#define MICROPY_SAFE_BOOT_PIN_NUM PIN_18 // GPIO28
|
||||
#define MICROPY_SYS_LED_PORT_PIN GPIO_PIN_1
|
||||
#define MICROPY_SAFE_BOOT_PORT_PIN GPIO_PIN_4
|
||||
|
||||
#define MICROPY_PORT_SFLASH_BLOCK_COUNT 96
|
||||
25
cc3200/boards/WIPY/pins.csv
Normal file
25
cc3200/boards/WIPY/pins.csv
Normal file
@@ -0,0 +1,25 @@
|
||||
L2,GPIO2
|
||||
L3,GPIO1
|
||||
L4,GPIO23
|
||||
L5,GPIO24
|
||||
L6,GPIO11
|
||||
L7,GPIO12
|
||||
L8,GPIO13
|
||||
L9,GPIO14
|
||||
L10,GPIO15
|
||||
L11,GPIO16
|
||||
L12,GPIO17
|
||||
L13,GPIO22
|
||||
L14,GPIO28
|
||||
R4,GPIO10
|
||||
R5,GPIO9
|
||||
R6,GPIO8
|
||||
R7,GPIO7
|
||||
R8,GPIO6
|
||||
R9,GPIO30
|
||||
R10,GPIO31
|
||||
R11,GPIO3
|
||||
R12,GPIO0
|
||||
R13,GPIO4
|
||||
R14,GPIO5
|
||||
HBL,GPIO25
|
||||
|
@@ -30,20 +30,25 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/obj.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "pin.h"
|
||||
#include "gpio.h"
|
||||
#include "pybpin.h"
|
||||
|
||||
|
||||
#define PIN(p_pin_name, p_port, p_bit, p_pin_num) \
|
||||
{ \
|
||||
{ &pin_type }, \
|
||||
.name = MP_QSTR_ ## p_pin_name, \
|
||||
.port = PORT_A ## p_port, \
|
||||
.bit = (p_bit), \
|
||||
.pin_num = (p_pin_num) \
|
||||
.name = MP_QSTR_ ## p_pin_name, \
|
||||
.port = PORT_A ## p_port, \
|
||||
.type = PIN_TYPE_STD, \
|
||||
.bit = (p_bit), \
|
||||
.pin_num = (p_pin_num), \
|
||||
.af = PIN_MODE_0, \
|
||||
.strength = PIN_STRENGTH_4MA, \
|
||||
.mode = GPIO_DIR_MODE_IN, \
|
||||
.isused = false, \
|
||||
}
|
||||
|
||||
@@ -38,14 +38,13 @@ class Pin(object):
|
||||
|
||||
def set_is_board_pin(self):
|
||||
self.board_pin = True
|
||||
|
||||
|
||||
def print(self):
|
||||
print('const pin_obj_t pin_{:6s} = PIN({:6s}, {:1d}, {:3d}, {:2d});'.format(
|
||||
print('pin_obj_t pin_{:6s} = PIN({:6s}, {:1d}, {:3d}, {:2d});'.format(
|
||||
self.name, self.name, self.port, self.gpio_bit, self.pin_num))
|
||||
|
||||
def print_header(self, hdr_file):
|
||||
hdr_file.write('extern const pin_obj_t pin_{:s};\n'.
|
||||
format(self.name))
|
||||
hdr_file.write('extern pin_obj_t pin_{:s};\n'.format(self.name))
|
||||
|
||||
|
||||
class Pins(object):
|
||||
@@ -57,12 +56,17 @@ class Pins(object):
|
||||
for pin in self.cpu_pins:
|
||||
if pin.port == port and pin.gpio_bit == gpio_bit:
|
||||
return pin
|
||||
|
||||
|
||||
def find_pin_by_num(self, pin_num):
|
||||
for pin in self.cpu_pins:
|
||||
if pin.pin_num == pin_num:
|
||||
return pin
|
||||
|
||||
def find_pin_by_name(self, name):
|
||||
for pin in self.cpu_pins:
|
||||
if pin.name == name:
|
||||
return pin
|
||||
|
||||
def parse_af_file(self, filename, pin_col, pinname_col):
|
||||
with open(filename, 'r') as csvfile:
|
||||
rows = csv.reader(csvfile)
|
||||
@@ -77,13 +81,16 @@ class Pins(object):
|
||||
pin_num = int(row[pin_col]) - 1;
|
||||
pin = Pin(row[pinname_col], port_num, gpio_bit, pin_num)
|
||||
self.cpu_pins.append(pin)
|
||||
|
||||
def parse_board_file(self, filename, cpu_pin_num_col):
|
||||
|
||||
def parse_board_file(self, filename, cpu_pin_col):
|
||||
with open(filename, 'r') as csvfile:
|
||||
rows = csv.reader(csvfile)
|
||||
for row in rows:
|
||||
# Pin numbers must start from 0 when used with the TI API
|
||||
pin = self.find_pin_by_num(int(row[cpu_pin_num_col]) - 1)
|
||||
if row[cpu_pin_col].isdigit():
|
||||
pin = self.find_pin_by_num(int(row[cpu_pin_col]) - 1)
|
||||
else:
|
||||
pin = self.find_pin_by_name(row[cpu_pin_col])
|
||||
if pin:
|
||||
pin.set_is_board_pin()
|
||||
|
||||
|
||||
@@ -1,17 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$#" -ne 2 ]; then
|
||||
echo "Usage: bootgen.sh *board type* *build type*"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BOARD=$1
|
||||
BTYPE=$2
|
||||
|
||||
# Re-locator Path
|
||||
RELOCATOR=bootmgr/relocator
|
||||
|
||||
# Boot Manager Path
|
||||
# First parameter passed is the board type
|
||||
BOOTMGR=bootmgr/build/$1
|
||||
BOOTMGR=bootmgr/build/${BOARD}/${BTYPE}
|
||||
|
||||
# Check for re-locator binary
|
||||
if [ ! -f $RELOCATOR/relocator.bin ]; then
|
||||
|
||||
echo "Error : Relocator Not found!"
|
||||
exit
|
||||
exit 1
|
||||
else
|
||||
echo "Relocator found..."
|
||||
fi
|
||||
@@ -20,7 +28,7 @@ fi
|
||||
if [ ! -f $BOOTMGR/bootmgr.bin ]; then
|
||||
|
||||
echo "Error : Boot Manager Not found!"
|
||||
exit
|
||||
exit 1
|
||||
else
|
||||
echo "Boot Manager found..."
|
||||
fi
|
||||
@@ -31,10 +39,10 @@ echo "Generating bootloader..."
|
||||
# Generate an all 0 bin file
|
||||
dd if=/dev/zero of=__tmp.bin ibs=1 count=256 conv=notrunc >/dev/null 2>&1
|
||||
|
||||
# Generate 0 a padded version of relocator
|
||||
# Generate a 0 padded version of the relocator
|
||||
dd if=$RELOCATOR/relocator.bin of=__tmp.bin ibs=1 conv=notrunc >/dev/null 2>&1
|
||||
|
||||
# Concatenate re-locator and boot-manager
|
||||
# Concatenate the re-locator and the boot-manager
|
||||
cat __tmp.bin $BOOTMGR/bootmgr.bin > $BOOTMGR/bootloader.bin
|
||||
|
||||
# Remove the tmp files
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
BUILD = bootmgr/build/$(BOARD)
|
||||
BUILD = bootmgr/build/$(BOARD)/$(BTYPE)
|
||||
|
||||
BOOT_INC = -Ibootmgr
|
||||
BOOT_INC += -Ibootmgr/sl
|
||||
BOOT_INC += -Ihal
|
||||
BOOT_INC += -Ihal/inc
|
||||
BOOT_INC += -I../drivers/cc3100/inc
|
||||
BOOT_INC += -Imisc
|
||||
BOOT_INC += -Imods
|
||||
BOOT_INC += -Isimplelink
|
||||
BOOT_INC += -Isimplelink/include
|
||||
BOOT_INC += -Isimplelink/oslib
|
||||
BOOT_INC += -Iutil
|
||||
BOOT_INC += -I..
|
||||
BOOT_INC += -I.
|
||||
BOOT_INC += -I$(PY_SRC)
|
||||
BOOT_INC += -I$(BUILD)
|
||||
|
||||
BOOT_CPPDEFINES = -Dgcc -DBOOTLOADER -DTARGET_IS_CC3200 -DSL_TINY
|
||||
@@ -18,6 +19,7 @@ BOOT_CPPDEFINES = -Dgcc -DBOOTLOADER -DTARGET_IS_CC3200 -DSL_TINY
|
||||
BOOT_HAL_SRC_C = $(addprefix hal/,\
|
||||
cpu.c \
|
||||
interrupt.c \
|
||||
pin.c \
|
||||
prcm.c \
|
||||
shamd5.c \
|
||||
spi.c \
|
||||
@@ -26,17 +28,24 @@ BOOT_HAL_SRC_C = $(addprefix hal/,\
|
||||
utils.c \
|
||||
)
|
||||
|
||||
BOOT_CC3100_SRC_C = $(addprefix drivers/cc3100/,\
|
||||
src/device.c \
|
||||
src/driver.c \
|
||||
src/flowcont.c \
|
||||
src/fs.c \
|
||||
src/netapp.c \
|
||||
src/netcfg.c \
|
||||
src/nonos.c \
|
||||
src/socket.c \
|
||||
src/spawn.c \
|
||||
src/wlan.c \
|
||||
)
|
||||
|
||||
BOOT_MISC_SRC_C = $(addprefix misc/,\
|
||||
mperror.c \
|
||||
)
|
||||
|
||||
BOOT_SL_SRC_C = $(addprefix simplelink/,\
|
||||
source/device.c \
|
||||
source/driver.c \
|
||||
source/flowcont.c \
|
||||
source/fs.c \
|
||||
source/netapp.c \
|
||||
source/netcfg.c \
|
||||
source/nonos.c \
|
||||
source/socket.c \
|
||||
source/spawn.c \
|
||||
source/wlan.c \
|
||||
cc_pal.c \
|
||||
)
|
||||
|
||||
@@ -60,8 +69,8 @@ BOOT_STM_SRC_C = $(addprefix stmhal/,\
|
||||
string0.c \
|
||||
)
|
||||
|
||||
OBJ = $(addprefix $(BUILD)/, $(BOOT_HAL_SRC_C:.c=.o) $(BOOT_SL_SRC_C:.c=.o) $(BOOT_UTIL_SRC_C:.c=.o) $(BOOT_MAIN_SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(BOOT_MAIN_SRC_S:.s=.o) $(BOOT_PY_SRC_C:.c=.o) $(BOOT_STM_SRC_C:.c=.o))
|
||||
OBJ = $(addprefix $(BUILD)/, $(BOOT_HAL_SRC_C:.c=.o) $(BOOT_SL_SRC_C:.c=.o) $(BOOT_CC3100_SRC_C:.c=.o) $(BOOT_UTIL_SRC_C:.c=.o) $(BOOT_MISC_SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(BOOT_MAIN_SRC_C:.c=.o) $(BOOT_MAIN_SRC_S:.s=.o) $(BOOT_PY_SRC_C:.c=.o) $(BOOT_STM_SRC_C:.c=.o))
|
||||
|
||||
# Add the linker script
|
||||
LINKER_SCRIPT = bootmgr/bootmgr.lds
|
||||
@@ -70,11 +79,8 @@ LDFLAGS += -T $(LINKER_SCRIPT)
|
||||
# Add the bootloader specific CFLAGS
|
||||
CFLAGS += $(BOOT_CPPDEFINES) $(BOOT_INC)
|
||||
|
||||
# Optimize for size all sources except for main
|
||||
|
||||
|
||||
# Disable strict aliasing for the simplelink driver
|
||||
$(BUILD)/simplelink/source/driver.o: CFLAGS += -fno-strict-aliasing
|
||||
$(BUILD)/drivers/cc3100/src/driver.o: CFLAGS += -fno-strict-aliasing
|
||||
|
||||
# Check if we would like to debug the port code
|
||||
ifeq ($(BTYPE), release)
|
||||
@@ -86,7 +92,9 @@ ifeq ($(BTYPE), debug)
|
||||
CFLAGS += -DDEBUG=DEBUG
|
||||
# Optimize the stable sources only
|
||||
$(BUILD)/hal/%.o: CFLAGS += -Os
|
||||
$(BUILD)/misc/%.o: CFLAGS += -Os
|
||||
$(BUILD)/simplelink/%.o: CFLAGS += -Os
|
||||
$(BUILD)/drivers/cc3100/%.o: CFLAGS += -Os
|
||||
$(BUILD)/py/%.o: CFLAGS += -Os
|
||||
$(BUILD)/stmhal/%.o: CFLAGS += -Os
|
||||
else
|
||||
@@ -111,7 +119,7 @@ $(BUILD)/bootmgr.bin: $(BUILD)/bootmgr.axf
|
||||
|
||||
$(BUILD)/bootloader.bin: $(BUILD)/bootmgr.bin
|
||||
$(ECHO) "Create $@"
|
||||
$(Q)$(SHELL) $(BOOT_GEN) $(BOARD)
|
||||
$(Q)$(SHELL) $(BOOT_GEN) $(BOARD) $(BTYPE)
|
||||
|
||||
# Create an empty "qstrdefs.generated.h" needed by py/mkrules.mk
|
||||
$(HEADER_BUILD)/qstrdefs.generated.h: | $(HEADER_BUILD)
|
||||
@@ -120,4 +128,3 @@ $(HEADER_BUILD)/qstrdefs.generated.h: | $(HEADER_BUILD)
|
||||
# Create an empty "py-version.h" needed by py/mkrules.mk
|
||||
$(HEADER_BUILD)/py-version.h: | $(HEADER_BUILD)
|
||||
touch $@
|
||||
|
||||
@@ -1,42 +1,30 @@
|
||||
/*****************************************************************************
|
||||
* bootmgr.lds
|
||||
*
|
||||
* GCC Linker script for get_time application.
|
||||
*
|
||||
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
__stack_size__ = 1024;
|
||||
__stack_size__ = 1024;
|
||||
|
||||
MEMORY
|
||||
{
|
||||
@@ -65,9 +53,7 @@ SECTIONS
|
||||
_etext = .;
|
||||
} > SRAM
|
||||
|
||||
__init_data = .;
|
||||
|
||||
.data : AT(__init_data)
|
||||
.data :
|
||||
{
|
||||
_data = .;
|
||||
*(.data*)
|
||||
|
||||
@@ -26,8 +26,10 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <std.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "hw_ints.h"
|
||||
#include "hw_types.h"
|
||||
#include "hw_gpio.h"
|
||||
@@ -48,29 +50,23 @@
|
||||
#include "hash.h"
|
||||
#include "utils.h"
|
||||
#include "cc3200_hal.h"
|
||||
#include "debug.h"
|
||||
#include "mperror.h"
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Local Constants
|
||||
//*****************************************************************************
|
||||
#define SL_STOP_TIMEOUT 500
|
||||
#define SL_STOP_TIMEOUT 35
|
||||
#define BOOTMGR_HASH_ALGO SHAMD5_ALGO_MD5
|
||||
#define BOOTMGR_HASH_SIZE 32
|
||||
#define BOOTMGR_BUFF_SIZE 512
|
||||
|
||||
#define BOOTMGR_WAIT_SAFE_MODE_MS 2000
|
||||
#define BOOTMGR_WAIT_SAFE_MODE_TOOGLE_MS 250
|
||||
|
||||
#define BOOTMGR_SAFE_MODE_ENTER_MS 1000
|
||||
#define BOOTMGR_SAFE_MODE_ENTER_TOOGLE_MS 100
|
||||
|
||||
#define BOOTMGR_PINS_PRCM PRCM_GPIOA3
|
||||
#define BOOTMGR_PINS_PORT GPIOA3_BASE
|
||||
#define BOOTMGR_LED_PIN_NUM PIN_21
|
||||
#define BOOTMGR_SFE_PIN_NUM PIN_45
|
||||
#define BOOTMGR_LED_PORT_PIN GPIO_PIN_1 // GPIO25
|
||||
#define BOOTMGR_SFE_PORT_PIN GPIO_PIN_7 // GPIO31
|
||||
#define BOOTMGR_WAIT_SAFE_MODE_MS 1600
|
||||
#define BOOTMGR_WAIT_SAFE_MODE_TOOGLE_MS 200
|
||||
|
||||
#define BOOTMGR_SAFE_MODE_ENTER_MS 800
|
||||
#define BOOTMGR_SAFE_MODE_ENTER_TOOGLE_MS 80
|
||||
|
||||
//*****************************************************************************
|
||||
// Exported functions declarations
|
||||
@@ -152,21 +148,16 @@ static void bootmgr_board_init(void) {
|
||||
// Mandatory MCU Initialization
|
||||
PRCMCC3200MCUInit();
|
||||
|
||||
mperror_bootloader_check_reset_cause();
|
||||
|
||||
// Enable the Data Hashing Engine
|
||||
HASH_Init();
|
||||
|
||||
// Enable GPIOA3 Peripheral Clock
|
||||
MAP_PRCMPeripheralClkEnable(BOOTMGR_PINS_PRCM, PRCM_RUN_MODE_CLK);
|
||||
// Init the system led and the system switch
|
||||
mperror_init0();
|
||||
|
||||
// Configure the bld
|
||||
MAP_PinTypeGPIO(BOOTMGR_LED_PIN_NUM, PIN_MODE_0, false);
|
||||
MAP_PinConfigSet(BOOTMGR_LED_PIN_NUM, PIN_STRENGTH_6MA, PIN_TYPE_STD);
|
||||
MAP_GPIODirModeSet(BOOTMGR_PINS_PORT, BOOTMGR_LED_PORT_PIN, GPIO_DIR_MODE_OUT);
|
||||
|
||||
// Configure the safe mode pin
|
||||
MAP_PinTypeGPIO(BOOTMGR_SFE_PIN_NUM, PIN_MODE_0, false);
|
||||
MAP_PinConfigSet(BOOTMGR_SFE_PIN_NUM, PIN_STRENGTH_6MA, PIN_TYPE_STD_PU);
|
||||
MAP_GPIODirModeSet(BOOTMGR_PINS_PORT, BOOTMGR_SFE_PORT_PIN, GPIO_DIR_MODE_IN);
|
||||
// clear the safe boot flag, since we can't trust its content after reset
|
||||
PRCMClearSafeBootRequest();
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -248,13 +239,14 @@ static void bootmgr_load_and_execute (_u8 *image) {
|
||||
//*****************************************************************************
|
||||
static bool safe_mode_boot (void) {
|
||||
_u32 count = 0;
|
||||
while (!MAP_GPIOPinRead(BOOTMGR_PINS_PORT, BOOTMGR_SFE_PORT_PIN) &&
|
||||
((BOOTMGR_WAIT_SAFE_MODE_TOOGLE_MS * count++) < BOOTMGR_WAIT_SAFE_MODE_MS)) {
|
||||
while (MAP_GPIOPinRead(MICROPY_SAFE_BOOT_PORT, MICROPY_SAFE_BOOT_PORT_PIN) &&
|
||||
((BOOTMGR_WAIT_SAFE_MODE_TOOGLE_MS * count++) < BOOTMGR_WAIT_SAFE_MODE_MS)) {
|
||||
// toogle the led
|
||||
MAP_GPIOPinWrite(BOOTMGR_PINS_PORT, BOOTMGR_LED_PORT_PIN, ~MAP_GPIOPinRead(GPIOA3_BASE, BOOTMGR_LED_PORT_PIN));
|
||||
MAP_GPIOPinWrite(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, ~MAP_GPIOPinRead(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN));
|
||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT(BOOTMGR_WAIT_SAFE_MODE_TOOGLE_MS * 1000));
|
||||
}
|
||||
return MAP_GPIOPinRead(BOOTMGR_PINS_PORT, BOOTMGR_SFE_PORT_PIN) ? false : true;
|
||||
mperror_deinit_sfe_pin();
|
||||
return MAP_GPIOPinRead(MICROPY_SAFE_BOOT_PORT, MICROPY_SAFE_BOOT_PORT_PIN) ? true : false;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -264,14 +256,16 @@ static void bootmgr_image_loader(sBootInfo_t *psBootInfo) {
|
||||
_i32 fhandle;
|
||||
if (safe_mode_boot()) {
|
||||
_u32 count = 0;
|
||||
while ((BOOTMGR_SAFE_MODE_ENTER_TOOGLE_MS * count++) > BOOTMGR_SAFE_MODE_ENTER_MS) {
|
||||
while ((BOOTMGR_SAFE_MODE_ENTER_TOOGLE_MS * count++) < BOOTMGR_SAFE_MODE_ENTER_MS) {
|
||||
// toogle the led
|
||||
MAP_GPIOPinWrite(BOOTMGR_PINS_PORT, BOOTMGR_LED_PORT_PIN, ~MAP_GPIOPinRead(GPIOA3_BASE, BOOTMGR_LED_PORT_PIN));
|
||||
MAP_GPIOPinWrite(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, ~MAP_GPIOPinRead(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN));
|
||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT(BOOTMGR_SAFE_MODE_ENTER_TOOGLE_MS * 1000));
|
||||
}
|
||||
psBootInfo->ActiveImg = IMG_ACT_FACTORY;
|
||||
// turn the led off
|
||||
MAP_GPIOPinWrite(BOOTMGR_PINS_PORT, BOOTMGR_LED_PORT_PIN, 0);
|
||||
MAP_GPIOPinWrite(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, 0);
|
||||
// request a safe boot to the application
|
||||
PRCMRequestSafeBoot();
|
||||
}
|
||||
// do we have a new update image that needs to be verified?
|
||||
else if ((psBootInfo->ActiveImg == IMG_ACT_UPDATE) && (psBootInfo->Status == IMG_STATUS_CHECK)) {
|
||||
@@ -312,7 +306,7 @@ int main (void) {
|
||||
bootmgr_board_init();
|
||||
|
||||
// start simplelink since we need it to access the sflash
|
||||
sl_Start(NULL, NULL, NULL);
|
||||
sl_Start(0, 0, 0);
|
||||
|
||||
// if a boot info file is found, load it, else, create a new one with the default boot info
|
||||
if (!sl_FsOpen((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_READ, NULL, &fhandle)) {
|
||||
@@ -346,7 +340,7 @@ int main (void) {
|
||||
// could not be loaded, so, loop forever and signal the crash to the user
|
||||
while (true) {
|
||||
// keep the bld on
|
||||
MAP_GPIOPinWrite(BOOTMGR_PINS_PORT, BOOTMGR_LED_PORT_PIN, BOOTMGR_LED_PORT_PIN);
|
||||
MAP_GPIOPinWrite(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, MICROPY_SYS_LED_PORT_PIN);
|
||||
__asm volatile(" dsb \n"
|
||||
" isb \n"
|
||||
" wfi \n");
|
||||
|
||||
@@ -348,7 +348,11 @@ extern "C" {
|
||||
\note belongs to \ref ported_sec
|
||||
|
||||
*/
|
||||
#define sl_DeviceEnablePreamble() NwpPowerOnPreamble()
|
||||
#ifdef DEBUG
|
||||
#define sl_DeviceEnablePreamble() NwpPowerOnPreamble()
|
||||
#else
|
||||
#define sl_DeviceEnablePreamble()
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\brief Enable the Network Processor
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include "diskio.h" /* FatFs lower layer API */
|
||||
#include "sflash_diskio.h" /* Serial flash disk IO API */
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
|
||||
@@ -37,15 +37,8 @@
|
||||
//*****************************************************************************
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "misc.h"
|
||||
#include "nlr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "objtuple.h"
|
||||
#include "objlist.h"
|
||||
#include "runtime.h"
|
||||
#include "hw_types.h"
|
||||
#include "hw_memmap.h"
|
||||
#include "hw_ints.h"
|
||||
@@ -95,7 +88,7 @@ DiskInfo_t sd_disk_info = {CARD_TYPE_UNKNOWN, CARD_VERSION_1, CARD_CAP_CLASS_SD
|
||||
static unsigned int CardSendCmd (unsigned int ulCmd, unsigned int ulArg) {
|
||||
unsigned long ulStatus;
|
||||
|
||||
// Clear interrupt status
|
||||
// Clear the interrupt status
|
||||
MAP_SDHostIntClear(SDHOST_BASE,0xFFFFFFFF);
|
||||
|
||||
// Send command
|
||||
@@ -293,6 +286,22 @@ DSTATUS sd_disk_init (void) {
|
||||
return sd_disk_info.bStatus;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! De-initializes the physical drive
|
||||
//!
|
||||
//! This function de-initializes the physical drive
|
||||
//*****************************************************************************
|
||||
void sd_disk_deinit (void) {
|
||||
sd_disk_info.ucCardType = CARD_TYPE_UNKNOWN;
|
||||
sd_disk_info.ulVersion = CARD_VERSION_1;
|
||||
sd_disk_info.ulCapClass = CARD_CAP_CLASS_SDSC;
|
||||
sd_disk_info.ulNofBlock = 0;
|
||||
sd_disk_info.ulBlockSize = 0;
|
||||
sd_disk_info.bStatus = STA_NOINIT;
|
||||
sd_disk_info.usRCA = 0;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Gets the disk status.
|
||||
|
||||
@@ -20,6 +20,7 @@ typedef struct
|
||||
extern DiskInfo_t sd_disk_info;
|
||||
|
||||
DSTATUS sd_disk_init (void);
|
||||
void sd_disk_deinit (void);
|
||||
DSTATUS sd_disk_status (void);
|
||||
bool sd_disk_ready (void);
|
||||
DRESULT sd_disk_read (BYTE* pBuffer, DWORD ulSectorNumber, UINT bSectorCount);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <stdbool.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "simplelink.h"
|
||||
#include "diskio.h"
|
||||
@@ -10,12 +10,6 @@
|
||||
#include "debug.h"
|
||||
#include "modwlan.h"
|
||||
|
||||
#ifdef USE_FREERTOS
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
#endif
|
||||
|
||||
#define SFLASH_TIMEOUT_MAX_MS 5500
|
||||
#define SFLASH_WAIT_TIME_MS 5
|
||||
|
||||
@@ -38,18 +32,15 @@ static bool sflash_access (_u32 mode, _i32 (* sl_FsFunction)(_i32 FileHdl, _u32
|
||||
bool retval = false;
|
||||
|
||||
// wlan must be enabled in order to access the serial flash
|
||||
#ifdef USE_FREERTOS
|
||||
xSemaphoreTake (xWlanSemaphore, portMAX_DELAY);
|
||||
#endif
|
||||
sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
|
||||
|
||||
if (0 == sl_FsOpen(sflash_block_name, mode, NULL, &fileHandle)) {
|
||||
if (SFLASH_BLOCK_SIZE == sl_FsFunction (fileHandle, 0, sflash_block_cache, SFLASH_BLOCK_SIZE)) {
|
||||
retval = true;
|
||||
}
|
||||
sl_FsClose (fileHandle, NULL, NULL, 0);
|
||||
}
|
||||
#ifdef USE_FREERTOS
|
||||
xSemaphoreGive (xWlanSemaphore);
|
||||
#endif
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -60,20 +51,17 @@ DRESULT sflash_disk_init (void) {
|
||||
if (!sflash_init_done) {
|
||||
// Allocate space for the block cache
|
||||
ASSERT ((sflash_block_cache = mem_Malloc(SFLASH_BLOCK_SIZE)) != NULL);
|
||||
sflash_init_done = true;
|
||||
|
||||
// Proceed to format the memory if not done yet
|
||||
for (int i = 0; i < SFLASH_BLOCK_COUNT; i++) {
|
||||
print_block_name (i);
|
||||
#ifdef USE_FREERTOS
|
||||
xSemaphoreTake (xWlanSemaphore, portMAX_DELAY);
|
||||
#endif
|
||||
sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
|
||||
// Create the block file if it doesn't exist
|
||||
if (sl_FsGetInfo(sflash_block_name, 0, &FsFileInfo) < 0) {
|
||||
if (!sl_FsOpen(sflash_block_name, FS_MODE_OPEN_CREATE(SFLASH_BLOCK_SIZE, 0), NULL, &fileHandle)) {
|
||||
sl_FsClose(fileHandle, NULL, NULL, 0);
|
||||
#ifdef USE_FREERTOS
|
||||
xSemaphoreGive (xWlanSemaphore);
|
||||
#endif
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
memset(sflash_block_cache, 0xFF, SFLASH_BLOCK_SIZE);
|
||||
if (!sflash_access(FS_MODE_OPEN_WRITE, sl_FsWrite)) {
|
||||
return RES_ERROR;
|
||||
@@ -81,17 +69,12 @@ DRESULT sflash_disk_init (void) {
|
||||
}
|
||||
else {
|
||||
// Unexpected failure while creating the file
|
||||
#ifdef USE_FREERTOS
|
||||
xSemaphoreGive (xWlanSemaphore);
|
||||
#endif
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
return RES_ERROR;
|
||||
}
|
||||
}
|
||||
#ifdef USE_FREERTOS
|
||||
xSemaphoreGive (xWlanSemaphore);
|
||||
#endif
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
}
|
||||
sflash_init_done = true;
|
||||
sflash_prblock = UINT32_MAX;
|
||||
sflash_cache_is_dirty = false;
|
||||
}
|
||||
@@ -112,7 +95,7 @@ DRESULT sflash_disk_read(BYTE *buff, DWORD sector, UINT count) {
|
||||
return STA_NOINIT;
|
||||
}
|
||||
|
||||
if (sector + count > SFLASH_SECTOR_COUNT || count == 0) {
|
||||
if ((sector + count > SFLASH_SECTOR_COUNT) || (count == 0)) {
|
||||
return RES_PARERR;
|
||||
}
|
||||
|
||||
@@ -145,7 +128,8 @@ DRESULT sflash_disk_write(const BYTE *buff, DWORD sector, UINT count) {
|
||||
return STA_NOINIT;
|
||||
}
|
||||
|
||||
if (sector + count > SFLASH_SECTOR_COUNT || count == 0) {
|
||||
if ((sector + count > SFLASH_SECTOR_COUNT) || (count == 0)) {
|
||||
sflash_disk_flush();
|
||||
return RES_PARERR;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define SFLASH_DISKIO_H_
|
||||
|
||||
#define SFLASH_BLOCK_SIZE 2048
|
||||
#define SFLASH_BLOCK_COUNT 32 // makes for 64KB of space
|
||||
#define SFLASH_BLOCK_COUNT MICROPY_PORT_SFLASH_BLOCK_COUNT
|
||||
#define SFLASH_SECTOR_SIZE 512
|
||||
#define SFLASH_SECTOR_COUNT ((SFLASH_BLOCK_SIZE * SFLASH_BLOCK_COUNT) / SFLASH_SECTOR_SIZE)
|
||||
#define SFLASH_SECTORS_PER_BLOCK (SFLASH_BLOCK_SIZE / SFLASH_SECTOR_SIZE)
|
||||
|
||||
@@ -27,10 +27,8 @@
|
||||
#include <string.h>
|
||||
#include <std.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/misc.h"
|
||||
#include "ff.h"
|
||||
#include "ffconf.h"
|
||||
#include "diskio.h"
|
||||
@@ -61,11 +59,11 @@ int ff_get_ldnumber (const TCHAR **path) {
|
||||
}
|
||||
|
||||
if (**path != '/') {
|
||||
#if _FS_RPATH
|
||||
#if _FS_RPATH
|
||||
return ff_CurrVol;
|
||||
#else
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
if (check_path(path, "/SFLASH", 7)) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
@@ -232,7 +232,7 @@
|
||||
|
||||
|
||||
#define _FS_REENTRANT 1
|
||||
#define _FS_TIMEOUT 2000
|
||||
#define _FS_TIMEOUT 2500 // milliseconds
|
||||
#define _SYNC_t SemaphoreHandle_t
|
||||
/* The _FS_REENTRANT option switches the re-entrancy (thread safe) of the FatFs
|
||||
/ module itself. Note that regardless of this option, file access to different
|
||||
|
||||
@@ -3,12 +3,8 @@
|
||||
/* (C)ChaN, 2014 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "misc.h"
|
||||
#include "nlr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "ff.h"
|
||||
|
||||
|
||||
@@ -38,7 +34,7 @@ int ff_cre_syncobj ( /* !=0:Function succeeded, ==0:Could not create due to any
|
||||
// *sobj = OSMutexCreate(0, &err); /* uC/OS-II */
|
||||
// ret = (int)(err == OS_NO_ERR);
|
||||
|
||||
*sobj = xSemaphoreCreateMutex(); /* FreeRTOS */
|
||||
vSemaphoreCreateBinary( (*sobj) ); /* FreeRTOS */
|
||||
ret = (int)(*sobj != NULL);
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -28,13 +28,9 @@
|
||||
#include <ctype.h>
|
||||
#include <std.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "misc.h"
|
||||
#include "nlr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "osi.h"
|
||||
#include "py/obj.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
@@ -70,8 +66,8 @@
|
||||
#define FTP_UNIX_TIME_20000101 946684800
|
||||
#define FTP_UNIX_TIME_20150101 1420070400
|
||||
#define FTP_UNIX_SECONDS_180_DAYS 15552000
|
||||
#define FTP_DATA_TIMEOUT_MS 5000 // 5 seconds
|
||||
#define FTP_CMD_TIMEOUT_MS 120000 // 2 minutes
|
||||
#define FTP_DATA_TIMEOUT_MS 5000 // 5 seconds
|
||||
#define FTP_CMD_TIMEOUT_MS 120000 // 2 minutes
|
||||
#define FTP_SOCKETFIFO_ELEMENTS_MAX 4
|
||||
#define FTP_CYCLE_TIME_MS (SERVERS_CYCLE_TIME_MS * 2)
|
||||
|
||||
@@ -123,6 +119,7 @@ typedef enum {
|
||||
|
||||
typedef struct {
|
||||
uint8_t *dBuffer;
|
||||
uint32_t ctimeout;
|
||||
union {
|
||||
DIR dp;
|
||||
FIL fp;
|
||||
@@ -130,7 +127,6 @@ typedef struct {
|
||||
int16_t lc_sd;
|
||||
int16_t ld_sd;
|
||||
int16_t c_sd;
|
||||
int16_t ctimeout;
|
||||
int16_t d_sd;
|
||||
int16_t dtimeout;
|
||||
ftp_state_t state;
|
||||
@@ -216,7 +212,6 @@ static void ftp_process_cmd (void);
|
||||
static void ftp_close_files (void);
|
||||
static void ftp_close_filesystem_on_error (void);
|
||||
static void ftp_close_cmd_data (void);
|
||||
static void ftp_reset (void);
|
||||
static ftp_cmd_index_t ftp_pop_command (char **str);
|
||||
static void ftp_pop_param (char **str, char *param);
|
||||
static int ftp_print_eplf_item (char *dest, uint32_t destsize, FILINFO *fno);
|
||||
@@ -229,6 +224,7 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
||||
static void ftp_open_child (char *pwd, char *dir);
|
||||
static void ftp_close_child (char *pwd);
|
||||
static void ftp_return_to_previous_path (char *pwd, char *dir);
|
||||
static void ftp_reset (void);
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
@@ -852,16 +848,6 @@ static void ftp_close_cmd_data (void) {
|
||||
ftp_close_filesystem_on_error ();
|
||||
}
|
||||
|
||||
static void ftp_reset (void) {
|
||||
// close all connections and start all over again
|
||||
servers_close_socket(&ftp_data.lc_sd);
|
||||
servers_close_socket(&ftp_data.ld_sd);
|
||||
ftp_close_cmd_data();
|
||||
ftp_data.state = E_FTP_STE_START;
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
|
||||
SOCKETFIFO_Flush();
|
||||
}
|
||||
|
||||
static ftp_cmd_index_t ftp_pop_command (char **str) {
|
||||
char _cmd[FTP_CMD_SIZE_MAX];
|
||||
ftp_pop_param (str, _cmd);
|
||||
@@ -1060,3 +1046,13 @@ static void ftp_return_to_previous_path (char *pwd, char *dir) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ftp_reset (void) {
|
||||
// close all connections and start all over again
|
||||
servers_close_socket(&ftp_data.lc_sd);
|
||||
servers_close_socket(&ftp_data.ld_sd);
|
||||
ftp_close_cmd_data();
|
||||
ftp_data.state = E_FTP_STE_START;
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
|
||||
SOCKETFIFO_Flush();
|
||||
}
|
||||
|
||||
@@ -34,4 +34,5 @@ extern void ftp_init (void);
|
||||
extern void ftp_run (void);
|
||||
extern void ftp_enable (void);
|
||||
extern void ftp_disable (void);
|
||||
|
||||
#endif /* FTP_H_ */
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <stdbool.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "simplelink.h"
|
||||
#include "flc.h"
|
||||
@@ -60,9 +60,7 @@ bool updater_check_path (void *path) {
|
||||
bool updater_start (void) {
|
||||
_u32 AccessModeAndMaxSize = FS_MODE_OPEN_WRITE;
|
||||
SlFsFileInfo_t FsFileInfo;
|
||||
#ifdef USE_FREERTOS
|
||||
xSemaphoreTake (xWlanSemaphore, portMAX_DELAY);
|
||||
#endif
|
||||
sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
|
||||
if (0 != sl_FsGetInfo((_u8 *)updater_data.path, 0, &FsFileInfo)) {
|
||||
// file doesn't exist, create it
|
||||
AccessModeAndMaxSize = FS_MODE_OPEN_CREATE(updater_data.fsize, 0);
|
||||
@@ -71,9 +69,7 @@ bool updater_start (void) {
|
||||
updater_data.foffset = 0;
|
||||
return true;
|
||||
}
|
||||
#ifdef USE_FREERTOS
|
||||
xSemaphoreGive (xWlanSemaphore);
|
||||
#endif
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -115,7 +111,5 @@ void updater_finnish (void) {
|
||||
}
|
||||
}
|
||||
updater_data.fhandle = -1;
|
||||
#ifdef USE_FREERTOS
|
||||
xSemaphoreGive (xWlanSemaphore);
|
||||
#endif
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
//{
|
||||
{
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
2690
cc3200/hal/aes.c
2690
cc3200/hal/aes.c
File diff suppressed because it is too large
Load Diff
435
cc3200/hal/aes.h
435
cc3200/hal/aes.h
@@ -1,217 +1,218 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// aes.h
|
||||
//
|
||||
// Defines and Macros for the AES module.
|
||||
//
|
||||
// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
|
||||
//
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// Neither the name of Texas Instruments Incorporated nor the names of
|
||||
// its contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef __DRIVERLIB_AES_H__
|
||||
#define __DRIVERLIB_AES_H__
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// The following defines are used to specify the operation direction in the
|
||||
// ui32Config argument in the AESConfig function. Only one is permitted.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AES_CFG_DIR_ENCRYPT 0x00000004
|
||||
#define AES_CFG_DIR_DECRYPT 0x00000000
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// The following defines are used to specify the key size in the ui32Config
|
||||
// argument in the AESConfig function. Only one is permitted.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AES_CFG_KEY_SIZE_128BIT 0x00000008
|
||||
#define AES_CFG_KEY_SIZE_192BIT 0x00000010
|
||||
#define AES_CFG_KEY_SIZE_256BIT 0x00000018
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// The following defines are used to specify the mode of operation in the
|
||||
// ui32Config argument in the AESConfig function. Only one is permitted.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AES_CFG_MODE_M 0x2007fe60
|
||||
#define AES_CFG_MODE_ECB 0x00000000
|
||||
#define AES_CFG_MODE_CBC 0x00000020
|
||||
#define AES_CFG_MODE_CTR 0x00000040
|
||||
#define AES_CFG_MODE_ICM 0x00000200
|
||||
#define AES_CFG_MODE_CFB 0x00000400
|
||||
#define AES_CFG_MODE_XTS_TWEAKJL \
|
||||
0x00000800
|
||||
#define AES_CFG_MODE_XTS_K2IJL \
|
||||
0x00001000
|
||||
#define AES_CFG_MODE_XTS_K2ILJ0 \
|
||||
0x00001800
|
||||
#define AES_CFG_MODE_F8 0x00002000
|
||||
#define AES_CFG_MODE_F9 0x20004000
|
||||
#define AES_CFG_MODE_CBCMAC 0x20008000
|
||||
#define AES_CFG_MODE_GCM_HLY0ZERO \
|
||||
0x20010040
|
||||
#define AES_CFG_MODE_GCM_HLY0CALC \
|
||||
0x20020040
|
||||
#define AES_CFG_MODE_GCM_HY0CALC \
|
||||
0x20030040
|
||||
#define AES_CFG_MODE_CCM 0x20040040
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// The following defines are used to specify the counter width in the
|
||||
// ui32Config argument in the AESConfig function. It is only required to
|
||||
// be defined when using CTR, CCM, or GCM modes. Only one length is permitted.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AES_CFG_CTR_WIDTH_32 0x00000000
|
||||
#define AES_CFG_CTR_WIDTH_64 0x00000080
|
||||
#define AES_CFG_CTR_WIDTH_96 0x00000100
|
||||
#define AES_CFG_CTR_WIDTH_128 0x00000180
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// The following defines are used to define the width of the length field for
|
||||
// CCM operation through the ui32Config argument in the AESConfig function.
|
||||
// This value is also known as L. Only one is permitted.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AES_CFG_CCM_L_2 0x00080000
|
||||
#define AES_CFG_CCM_L_4 0x00180000
|
||||
#define AES_CFG_CCM_L_8 0x00380000
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// The following defines are used to define the length of the authentication
|
||||
// field for CCM operations through the ui32Config argument in the AESConfig
|
||||
// function. This value is also known as M. Only one is permitted.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AES_CFG_CCM_M_4 0x00400000
|
||||
#define AES_CFG_CCM_M_6 0x00800000
|
||||
#define AES_CFG_CCM_M_8 0x00c00000
|
||||
#define AES_CFG_CCM_M_10 0x01000000
|
||||
#define AES_CFG_CCM_M_12 0x01400000
|
||||
#define AES_CFG_CCM_M_14 0x01800000
|
||||
#define AES_CFG_CCM_M_16 0x01c00000
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Interrupt flags for use with the AESIntEnable, AESIntDisable, and
|
||||
// AESIntStatus functions.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AES_INT_CONTEXT_IN 0x00000001
|
||||
#define AES_INT_CONTEXT_OUT 0x00000008
|
||||
#define AES_INT_DATA_IN 0x00000002
|
||||
#define AES_INT_DATA_OUT 0x00000004
|
||||
#define AES_INT_DMA_CONTEXT_IN 0x00010000
|
||||
#define AES_INT_DMA_CONTEXT_OUT 0x00020000
|
||||
#define AES_INT_DMA_DATA_IN 0x00040000
|
||||
#define AES_INT_DMA_DATA_OUT 0x00080000
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Defines used when enabling and disabling DMA requests in the
|
||||
// AESEnableDMA and AESDisableDMA functions.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AES_DMA_DATA_IN 0x00000040
|
||||
#define AES_DMA_DATA_OUT 0x00000020
|
||||
#define AES_DMA_CONTEXT_IN 0x00000080
|
||||
#define AES_DMA_CONTEXT_OUT 0x00000100
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Function prototypes.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void AESConfigSet(uint32_t ui32Base, uint32_t ui32Config);
|
||||
extern void AESKey1Set(uint32_t ui32Base, uint8_t *pui8Key,
|
||||
uint32_t ui32Keysize);
|
||||
extern void AESKey2Set(uint32_t ui32Base, uint8_t *pui8Key,
|
||||
uint32_t ui32Keysize);
|
||||
extern void AESKey3Set(uint32_t ui32Base, uint8_t *pui8Key);
|
||||
extern void AESIVSet(uint32_t ui32Base, uint8_t *pui8IVdata);
|
||||
extern void AESTagRead(uint32_t ui32Base, uint8_t *pui8TagData);
|
||||
extern void AESDataLengthSet(uint32_t ui32Base, uint64_t ui64Length);
|
||||
extern void AESAuthDataLengthSet(uint32_t ui32Base, uint32_t ui32Length);
|
||||
extern bool AESDataReadNonBlocking(uint32_t ui32Base, uint8_t *pui8Dest,
|
||||
uint8_t ui8Length);
|
||||
extern void AESDataRead(uint32_t ui32Base, uint8_t *pui8Dest,
|
||||
uint8_t ui8Length);
|
||||
extern bool AESDataWriteNonBlocking(uint32_t ui32Base, uint8_t *pui8Src,
|
||||
uint8_t ui8Length);
|
||||
extern void AESDataWrite(uint32_t ui32Base, uint8_t *pui8Src,
|
||||
uint8_t ui8Length);
|
||||
extern bool AESDataProcess(uint32_t ui32Base, uint8_t *pui8Src,
|
||||
uint8_t *pui8Dest,
|
||||
uint32_t ui32Length);
|
||||
extern bool AESDataMAC(uint32_t ui32Base, uint8_t *pui8Src,
|
||||
uint32_t ui32Length,
|
||||
uint8_t *pui8Tag);
|
||||
extern bool AESDataProcessAE(uint32_t ui32Base, uint8_t *pui8Src,
|
||||
uint8_t *pui8Dest, uint32_t ui32Length,
|
||||
uint8_t *pui8AuthSrc, uint32_t ui32AuthLength,
|
||||
uint8_t *pui8Tag);
|
||||
extern uint32_t AESIntStatus(uint32_t ui32Base, bool bMasked);
|
||||
extern void AESIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags);
|
||||
extern void AESIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags);
|
||||
extern void AESIntClear(uint32_t ui32Base, uint32_t ui32IntFlags);
|
||||
extern void AESIntRegister(uint32_t ui32Base, void(*pfnHandler)(void));
|
||||
extern void AESIntUnregister(uint32_t ui32Base);
|
||||
extern void AESDMAEnable(uint32_t ui32Base, uint32_t ui32Flags);
|
||||
extern void AESDMADisable(uint32_t ui32Base, uint32_t ui32Flags);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __DRIVERLIB_AES_H__
|
||||
//*****************************************************************************
|
||||
//
|
||||
// aes.h
|
||||
//
|
||||
// Defines and Macros for the AES module.
|
||||
//
|
||||
// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
|
||||
//
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// Neither the name of Texas Instruments Incorporated nor the names of
|
||||
// its contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef __DRIVERLIB_AES_H__
|
||||
#define __DRIVERLIB_AES_H__
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// The following defines are used to specify the operation direction in the
|
||||
// ui32Config argument in the AESConfig function. Only one is permitted.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AES_CFG_DIR_ENCRYPT 0x00000004
|
||||
#define AES_CFG_DIR_DECRYPT 0x00000000
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// The following defines are used to specify the key size in the ui32Config
|
||||
// argument in the AESConfig function. Only one is permitted.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AES_CFG_KEY_SIZE_128BIT 0x00000008
|
||||
#define AES_CFG_KEY_SIZE_192BIT 0x00000010
|
||||
#define AES_CFG_KEY_SIZE_256BIT 0x00000018
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// The following defines are used to specify the mode of operation in the
|
||||
// ui32Config argument in the AESConfig function. Only one is permitted.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AES_CFG_MODE_M 0x2007fe60
|
||||
#define AES_CFG_MODE_ECB 0x00000000
|
||||
#define AES_CFG_MODE_CBC 0x00000020
|
||||
#define AES_CFG_MODE_CTR 0x00000040
|
||||
#define AES_CFG_MODE_ICM 0x00000200
|
||||
#define AES_CFG_MODE_CFB 0x00000400
|
||||
#define AES_CFG_MODE_XTS_TWEAKJL \
|
||||
0x00000800
|
||||
#define AES_CFG_MODE_XTS_K2IJL \
|
||||
0x00001000
|
||||
#define AES_CFG_MODE_XTS_K2ILJ0 \
|
||||
0x00001800
|
||||
#define AES_CFG_MODE_F8 0x00002000
|
||||
#define AES_CFG_MODE_F9 0x20004000
|
||||
#define AES_CFG_MODE_CBCMAC 0x20008000
|
||||
#define AES_CFG_MODE_GCM_HLY0ZERO \
|
||||
0x20010040
|
||||
#define AES_CFG_MODE_GCM_HLY0CALC \
|
||||
0x20020040
|
||||
#define AES_CFG_MODE_GCM_HY0CALC \
|
||||
0x20030040
|
||||
#define AES_CFG_MODE_CCM 0x20040040
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// The following defines are used to specify the counter width in the
|
||||
// ui32Config argument in the AESConfig function. It is only required to
|
||||
// be defined when using CTR, CCM, or GCM modes. Only one length is permitted.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AES_CFG_CTR_WIDTH_32 0x00000000
|
||||
#define AES_CFG_CTR_WIDTH_64 0x00000080
|
||||
#define AES_CFG_CTR_WIDTH_96 0x00000100
|
||||
#define AES_CFG_CTR_WIDTH_128 0x00000180
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// The following defines are used to define the width of the length field for
|
||||
// CCM operation through the ui32Config argument in the AESConfig function.
|
||||
// This value is also known as L. Only one is permitted.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AES_CFG_CCM_L_2 0x00080000
|
||||
#define AES_CFG_CCM_L_4 0x00180000
|
||||
#define AES_CFG_CCM_L_8 0x00380000
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// The following defines are used to define the length of the authentication
|
||||
// field for CCM operations through the ui32Config argument in the AESConfig
|
||||
// function. This value is also known as M. Only one is permitted.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AES_CFG_CCM_M_4 0x00400000
|
||||
#define AES_CFG_CCM_M_6 0x00800000
|
||||
#define AES_CFG_CCM_M_8 0x00c00000
|
||||
#define AES_CFG_CCM_M_10 0x01000000
|
||||
#define AES_CFG_CCM_M_12 0x01400000
|
||||
#define AES_CFG_CCM_M_14 0x01800000
|
||||
#define AES_CFG_CCM_M_16 0x01c00000
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Interrupt flags for use with the AESIntEnable, AESIntDisable, and
|
||||
// AESIntStatus functions.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AES_INT_CONTEXT_IN 0x00000001
|
||||
#define AES_INT_CONTEXT_OUT 0x00000008
|
||||
#define AES_INT_DATA_IN 0x00000002
|
||||
#define AES_INT_DATA_OUT 0x00000004
|
||||
#define AES_INT_DMA_CONTEXT_IN 0x00010000
|
||||
#define AES_INT_DMA_CONTEXT_OUT 0x00020000
|
||||
#define AES_INT_DMA_DATA_IN 0x00040000
|
||||
#define AES_INT_DMA_DATA_OUT 0x00080000
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Defines used when enabling and disabling DMA requests in the
|
||||
// AESEnableDMA and AESDisableDMA functions.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define AES_DMA_DATA_IN 0x00000040
|
||||
#define AES_DMA_DATA_OUT 0x00000020
|
||||
#define AES_DMA_CONTEXT_IN 0x00000080
|
||||
#define AES_DMA_CONTEXT_OUT 0x00000100
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Function prototypes.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void AESConfigSet(uint32_t ui32Base, uint32_t ui32Config);
|
||||
extern void AESKey1Set(uint32_t ui32Base, uint8_t *pui8Key,
|
||||
uint32_t ui32Keysize);
|
||||
extern void AESKey2Set(uint32_t ui32Base, uint8_t *pui8Key,
|
||||
uint32_t ui32Keysize);
|
||||
extern void AESKey3Set(uint32_t ui32Base, uint8_t *pui8Key);
|
||||
extern void AESIVSet(uint32_t ui32Base, uint8_t *pui8IVdata);
|
||||
extern void AESIVGet(uint32_t ui32Base, uint8_t *pui8IVdata);
|
||||
extern void AESTagRead(uint32_t ui32Base, uint8_t *pui8TagData);
|
||||
extern void AESDataLengthSet(uint32_t ui32Base, uint64_t ui64Length);
|
||||
extern void AESAuthDataLengthSet(uint32_t ui32Base, uint32_t ui32Length);
|
||||
extern bool AESDataReadNonBlocking(uint32_t ui32Base, uint8_t *pui8Dest,
|
||||
uint8_t ui8Length);
|
||||
extern void AESDataRead(uint32_t ui32Base, uint8_t *pui8Dest,
|
||||
uint8_t ui8Length);
|
||||
extern bool AESDataWriteNonBlocking(uint32_t ui32Base, uint8_t *pui8Src,
|
||||
uint8_t ui8Length);
|
||||
extern void AESDataWrite(uint32_t ui32Base, uint8_t *pui8Src,
|
||||
uint8_t ui8Length);
|
||||
extern bool AESDataProcess(uint32_t ui32Base, uint8_t *pui8Src,
|
||||
uint8_t *pui8Dest,
|
||||
uint32_t ui32Length);
|
||||
extern bool AESDataMAC(uint32_t ui32Base, uint8_t *pui8Src,
|
||||
uint32_t ui32Length,
|
||||
uint8_t *pui8Tag);
|
||||
extern bool AESDataProcessAE(uint32_t ui32Base, uint8_t *pui8Src,
|
||||
uint8_t *pui8Dest, uint32_t ui32Length,
|
||||
uint8_t *pui8AuthSrc, uint32_t ui32AuthLength,
|
||||
uint8_t *pui8Tag);
|
||||
extern uint32_t AESIntStatus(uint32_t ui32Base, bool bMasked);
|
||||
extern void AESIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags);
|
||||
extern void AESIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags);
|
||||
extern void AESIntClear(uint32_t ui32Base, uint32_t ui32IntFlags);
|
||||
extern void AESIntRegister(uint32_t ui32Base, void(*pfnHandler)(void));
|
||||
extern void AESIntUnregister(uint32_t ui32Base);
|
||||
extern void AESDMAEnable(uint32_t ui32Base, uint32_t ui32Flags);
|
||||
extern void AESDMADisable(uint32_t ui32Base, uint32_t ui32Flags);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __DRIVERLIB_AES_H__
|
||||
|
||||
@@ -30,19 +30,21 @@
|
||||
******************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_nvic.h"
|
||||
#include "hw_memmap.h"
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpstate.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "rom_map.h"
|
||||
#include "interrupt.h"
|
||||
#include "systick.h"
|
||||
#include "prcm.h"
|
||||
#include "sdhost.h"
|
||||
#include "pin.h"
|
||||
#include "mpexception.h"
|
||||
#include "telnet.h"
|
||||
#include "pybuart.h"
|
||||
|
||||
#ifdef USE_FREERTOS
|
||||
#include "FreeRTOS.h"
|
||||
@@ -51,26 +53,23 @@
|
||||
#endif
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define HAL_SDCARD_FREQUENCY_HZ 15000000 // 15MHz
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
#ifndef USE_FREERTOS
|
||||
static void hal_TickInit (void);
|
||||
#endif
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
static void hal_EnableSdCard (void);
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE LOCAL VARIABLES
|
||||
DECLARE LOCAL DATA
|
||||
******************************************************************************/
|
||||
static volatile uint32_t HAL_tickCount;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC DATA
|
||||
******************************************************************************/
|
||||
struct _pyb_uart_obj_t *pyb_stdio_uart;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE IMPORTED DATA
|
||||
******************************************************************************/
|
||||
@@ -79,13 +78,14 @@ extern void (* const g_pfnVectors[256])(void);
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
__attribute__ ((section (".boot")))
|
||||
void HAL_SystemInit (void) {
|
||||
MAP_IntVTableBaseSet((unsigned long)&g_pfnVectors[0]);
|
||||
|
||||
// in the case of a release image, these steps are already performed by
|
||||
// the bootloader so we can skip it and gain some code space
|
||||
#ifndef NDEBUG
|
||||
#ifdef DEBUG
|
||||
MAP_IntMasterEnable();
|
||||
PRCMCC3200MCUInit();
|
||||
#endif
|
||||
@@ -93,9 +93,6 @@ void HAL_SystemInit (void) {
|
||||
#ifndef USE_FREERTOS
|
||||
hal_TickInit();
|
||||
#endif
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
hal_EnableSdCard();
|
||||
#endif
|
||||
}
|
||||
|
||||
void HAL_SystemDeInit (void) {
|
||||
@@ -126,6 +123,44 @@ void mp_hal_set_interrupt_char (int c) {
|
||||
mpexception_set_interrupt_char (c);
|
||||
}
|
||||
|
||||
void mp_hal_stdout_tx_str(const char *str) {
|
||||
mp_hal_stdout_tx_strn(str, strlen(str));
|
||||
}
|
||||
|
||||
void mp_hal_stdout_tx_strn(const char *str, uint32_t len) {
|
||||
// send stdout to UART
|
||||
if (pyb_stdio_uart != NULL) {
|
||||
uart_tx_strn(pyb_stdio_uart, str, len);
|
||||
}
|
||||
// and also to telnet
|
||||
if (telnet_is_active()) {
|
||||
telnet_tx_strn(str, len);
|
||||
}
|
||||
}
|
||||
|
||||
void mp_hal_stdout_tx_strn_cooked(const char *str, uint32_t len) {
|
||||
// send stdout to UART
|
||||
if (pyb_stdio_uart != NULL) {
|
||||
uart_tx_strn_cooked(pyb_stdio_uart, str, len);
|
||||
}
|
||||
// and also to telnet
|
||||
if (telnet_is_active()) {
|
||||
telnet_tx_strn_cooked(str, len);
|
||||
}
|
||||
}
|
||||
|
||||
int mp_hal_stdin_rx_chr(void) {
|
||||
for ( ;; ) {
|
||||
if (telnet_rx_any()) {
|
||||
return telnet_rx_char();
|
||||
}
|
||||
else if (pyb_stdio_uart != NULL && uart_rx_any(pyb_stdio_uart)) {
|
||||
return uart_rx_char(pyb_stdio_uart);
|
||||
}
|
||||
HAL_Delay(1);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
@@ -143,23 +178,3 @@ static void hal_TickInit (void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
static void hal_EnableSdCard (void) {
|
||||
// Configure PIN_06 for SDHOST0 SDHost_D0
|
||||
MAP_PinTypeSDHost(PIN_06, PIN_MODE_8);
|
||||
// Configure PIN_07 for SDHOST0 SDHost_CLK
|
||||
MAP_PinTypeSDHost(PIN_07, PIN_MODE_8);
|
||||
// Configure PIN_08 for SDHOST0 SDHost_CMD
|
||||
MAP_PinTypeSDHost(PIN_08, PIN_MODE_8);
|
||||
// Set the SD card clock as an output pin
|
||||
MAP_PinDirModeSet(PIN_07, PIN_DIR_MODE_OUT);
|
||||
// Enable SD peripheral clock
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_SDHOST, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
// Reset MMCHS
|
||||
MAP_PRCMPeripheralReset(PRCM_SDHOST);
|
||||
// Configure MMCHS
|
||||
MAP_SDHostInit(SDHOST_BASE);
|
||||
// Configure the card clock
|
||||
MAP_SDHostSetExpClk(SDHOST_BASE, MAP_PRCMPeripheralClockGet(PRCM_SDHOST), HAL_SDCARD_FREQUENCY_HZ);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -39,6 +39,9 @@
|
||||
#define HAL_SYSTICK_PERIOD_US 1000U
|
||||
#define UTILS_DELAY_US_TO_COUNT(us) (((us) * HAL_FCPU_MHZ) / 3)
|
||||
|
||||
#define HAL_NVIC_INT_CTRL_REG (*((volatile uint32_t *) 0xE000ED04 ) )
|
||||
#define HAL_VECTACTIVE_MASK (0x1FUL)
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
******************************************************************************/
|
||||
@@ -52,6 +55,11 @@
|
||||
" isb \n"); \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC DATA
|
||||
******************************************************************************/
|
||||
extern struct _pyb_uart_obj_t *pyb_stdio_uart;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
@@ -63,4 +71,9 @@ extern uint32_t HAL_GetTick(void);
|
||||
extern void HAL_Delay(uint32_t delay);
|
||||
extern void mp_hal_set_interrupt_char (int c);
|
||||
|
||||
int mp_hal_stdin_rx_chr(void);
|
||||
void mp_hal_stdout_tx_str(const char *str);
|
||||
void mp_hal_stdout_tx_strn(const char *str, uint32_t len);
|
||||
void mp_hal_stdout_tx_strn_cooked(const char *str, uint32_t len);
|
||||
|
||||
#endif /* CC3200_LAUNCHXL_HAL_CC3200_HAL_H_ */
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
|
||||
//
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// Neither the name of Texas Instruments Incorporated nor the names of
|
||||
// its contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef __CC_TYPES_H__
|
||||
#define __CC_TYPES_H__
|
||||
|
||||
typedef unsigned long long u64;
|
||||
typedef unsigned long u32;
|
||||
typedef int i32;
|
||||
typedef unsigned short u16;
|
||||
typedef short i16;
|
||||
typedef unsigned char u8;
|
||||
typedef char i8;
|
||||
|
||||
typedef void * cc_hndl;
|
||||
|
||||
typedef u32 (*sys_irq_dsbl)();
|
||||
typedef void (*sys_irq_enbl)(u32 mask);
|
||||
#define UNUSED(x) ((x) = (x))
|
||||
|
||||
#define INTRODUCE_SYNC_BARRIER() { \
|
||||
__asm(" dsb \n" \
|
||||
" isb \n"); \
|
||||
}
|
||||
|
||||
#endif //__CC_TYPES_H__
|
||||
1774
cc3200/hal/des.c
1774
cc3200/hal/des.c
File diff suppressed because it is too large
Load Diff
@@ -169,10 +169,8 @@ _I2CIntNumberGet(uint32_t ui32Base)
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
I2CMasterInitExpClk(uint32_t ui32Base, uint32_t ui32I2CClk,
|
||||
bool bFast)
|
||||
I2CMasterInitExpClk(uint32_t ui32Base, uint32_t ui32SCLFreq)
|
||||
{
|
||||
uint32_t ui32SCLFreq;
|
||||
uint32_t ui32TPR;
|
||||
|
||||
//
|
||||
@@ -185,25 +183,13 @@ I2CMasterInitExpClk(uint32_t ui32Base, uint32_t ui32I2CClk,
|
||||
//
|
||||
I2CMasterEnable(ui32Base);
|
||||
|
||||
//
|
||||
// Get the desired SCL speed.
|
||||
//
|
||||
if(bFast == true)
|
||||
{
|
||||
ui32SCLFreq = 400000;
|
||||
}
|
||||
else
|
||||
{
|
||||
ui32SCLFreq = 100000;
|
||||
}
|
||||
|
||||
//
|
||||
// Compute the clock divider that achieves the fastest speed less than or
|
||||
// equal to the desired speed. The numerator is biased to favor a larger
|
||||
// clock divider so that the resulting clock is always less than or equal
|
||||
// to the desired clock, never greater.
|
||||
//
|
||||
ui32TPR = ((ui32I2CClk + (2 * 10 * ui32SCLFreq) - 1) /
|
||||
ui32TPR = ((80000000 + (2 * 10 * ui32SCLFreq) - 1) /
|
||||
(2 * 10 * ui32SCLFreq)) - 1;
|
||||
HWREG(ui32Base + I2C_O_MTPR) = ui32TPR;
|
||||
|
||||
@@ -213,7 +199,7 @@ I2CMasterInitExpClk(uint32_t ui32Base, uint32_t ui32I2CClk,
|
||||
//
|
||||
if(HWREG(ui32Base + I2C_O_PP) & I2C_PP_HS)
|
||||
{
|
||||
ui32TPR = ((ui32I2CClk + (2 * 3 * 3400000) - 1) /
|
||||
ui32TPR = ((80000000 + (2 * 3 * 3400000) - 1) /
|
||||
(2 * 3 * 3400000)) - 1;
|
||||
HWREG(ui32Base + I2C_O_MTPR) = I2C_MTPR_HS | ui32TPR;
|
||||
}
|
||||
|
||||
@@ -309,8 +309,7 @@ extern void I2CMasterDataPut(uint32_t ui32Base, uint8_t ui8Data);
|
||||
extern void I2CMasterDisable(uint32_t ui32Base);
|
||||
extern void I2CMasterEnable(uint32_t ui32Base);
|
||||
extern uint32_t I2CMasterErr(uint32_t ui32Base);
|
||||
extern void I2CMasterInitExpClk(uint32_t ui32Base, uint32_t ui32I2CClk,
|
||||
bool bFast);
|
||||
extern void I2CMasterInitExpClk(uint32_t ui32Base, uint32_t ui32SCLFreq);
|
||||
extern void I2CMasterIntClear(uint32_t ui32Base);
|
||||
extern void I2CMasterIntDisable(uint32_t ui32Base);
|
||||
extern void I2CMasterIntEnable(uint32_t ui32Base);
|
||||
|
||||
1934
cc3200/hal/i2s.c
1934
cc3200/hal/i2s.c
File diff suppressed because it is too large
Load Diff
420
cc3200/hal/i2s.h
420
cc3200/hal/i2s.h
@@ -1,202 +1,218 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// i2s.h
|
||||
//
|
||||
// Defines and Macros for the I2S.
|
||||
//
|
||||
// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
|
||||
//
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// Neither the name of Texas Instruments Incorporated nor the names of
|
||||
// its contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef __I2S_H__
|
||||
#define __I2S_H__
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// I2S DMA ports.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define I2S_TX_DMA_PORT 0x4401E200
|
||||
#define I2S_RX_DMA_PORT 0x4401E280
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be passed to I2SConfigSetExpClk() as the ulConfig parameter.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define I2S_SLOT_SIZE_24 0x00B200B4
|
||||
#define I2S_SLOT_SIZE_16 0x00700074
|
||||
|
||||
#define I2S_PORT_CPU 0x00000008
|
||||
#define I2S_PORT_DMA 0x00000000
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be passed as ulDataLine parameter.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define I2S_DATA_LINE_0 0x00000001
|
||||
#define I2S_DATA_LINE_1 0x00000002
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be passed to I2SSerializerConfig() as the ulSerMode
|
||||
// parameter.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define I2S_SER_MODE_TX 0x00000001
|
||||
#define I2S_SER_MODE_RX 0x00000002
|
||||
#define I2S_SER_MODE_DISABLE 0x00000000
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be passed to I2SSerializerConfig() as the ulInActState
|
||||
// parameter.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define I2S_INACT_TRI_STATE 0x00000000
|
||||
#define I2S_INACT_LOW_LEVEL 0x00000008
|
||||
#define I2S_INACT_HIGH_LEVEL 0x0000000C
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be passed to I2SIntEnable() and I2SIntDisable() as the
|
||||
// ulIntFlags parameter.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define I2S_INT_XUNDRN 0x00000001
|
||||
#define I2S_INT_XSYNCERR 0x00000002
|
||||
#define I2S_INT_XLAST 0x00000010
|
||||
#define I2S_INT_XDATA 0x00000020
|
||||
#define I2S_INT_XSTAFRM 0x00000080
|
||||
#define I2S_INT_XDMA 0x80000000
|
||||
#define I2S_INT_ROVRN 0x00010000
|
||||
#define I2S_INT_RSYNCERR 0x00020000
|
||||
#define I2S_INT_RLAST 0x00100000
|
||||
#define I2S_INT_RDATA 0x00200000
|
||||
#define I2S_INT_RSTAFRM 0x00800000
|
||||
#define I2S_INT_RDMA 0x40000000
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be passed to I2SIntClear() as the
|
||||
// ulIntFlags parameter and returned from I2SIntStatus().
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define I2S_STS_XERR 0x00000100
|
||||
#define I2S_STS_XDMAERR 0x00000080
|
||||
#define I2S_STS_XSTAFRM 0x00000040
|
||||
#define I2S_STS_XDATA 0x00000020
|
||||
#define I2S_STS_XLAST 0x00000010
|
||||
#define I2S_STS_XSYNCERR 0x00000002
|
||||
#define I2S_STS_XUNDRN 0x00000001
|
||||
#define I2S_STS_XDMA 0x80000000
|
||||
#define I2S_STS_RERR 0x01000000
|
||||
#define I2S_STS_RDMAERR 0x00800000
|
||||
#define I2S_STS_RSTAFRM 0x00400000
|
||||
#define I2S_STS_RDATA 0x00200000
|
||||
#define I2S_STS_RLAST 0x00100000
|
||||
#define I2S_STS_RSYNCERR 0x00020000
|
||||
#define I2S_STS_ROVERN 0x00010000
|
||||
#define I2S_STS_RDMA 0x40000000
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be passed to I2SEnable() as the ulMode parameter.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define I2S_MODE_TX_ONLY 0x00000001
|
||||
#define I2S_MODE_TX_RX_SYNC 0x00000003
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// API Function prototypes
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void I2SEnable(unsigned long ulBase, unsigned long ulMode);
|
||||
extern void I2SDisable(unsigned long ulBase);
|
||||
|
||||
extern void I2SDataPut(unsigned long ulBase, unsigned long ulDataLine,
|
||||
unsigned long ulData);
|
||||
extern long I2SDataPutNonBlocking(unsigned long ulBase,
|
||||
unsigned long ulDataLine, unsigned long ulData);
|
||||
|
||||
extern void I2SDataGet(unsigned long ulBase, unsigned long ulDataLine,
|
||||
unsigned long *pulData);
|
||||
extern long I2SDataGetNonBlocking(unsigned long ulBase,
|
||||
unsigned long ulDataLine, unsigned long *pulData);
|
||||
|
||||
extern void I2SConfigSetExpClk(unsigned long ulBase, unsigned long ulI2SClk,
|
||||
unsigned long ulBitClk, unsigned long ulConfig);
|
||||
|
||||
extern void I2STxFIFOEnable(unsigned long ulBase, unsigned long ulTxLevel,
|
||||
unsigned long ulWordsPerTransfer);
|
||||
extern void I2STxFIFODisable(unsigned long ulBase);
|
||||
extern void I2SRxFIFOEnable(unsigned long ulBase, unsigned long ulRxLevel,
|
||||
unsigned long ulWordsPerTransfer);
|
||||
extern void I2SRxFIFODisable(unsigned long ulBase);
|
||||
extern unsigned long I2STxFIFOStatusGet(unsigned long ulBase);
|
||||
extern unsigned long I2SRxFIFOStatusGet(unsigned long ulBase);
|
||||
|
||||
extern void I2SSerializerConfig(unsigned long ulBase, unsigned long ulDataLine,
|
||||
unsigned long ulSerMode, unsigned long ulInActState);
|
||||
|
||||
extern void I2SIntEnable(unsigned long ulBase, unsigned long ulIntFlags);
|
||||
extern void I2SIntDisable(unsigned long ulBase, unsigned long ulIntFlags);
|
||||
extern unsigned long I2SIntStatus(unsigned long ulBase);
|
||||
extern void I2SIntClear(unsigned long ulBase, unsigned long ulIntFlags);
|
||||
extern void I2SIntRegister(unsigned long ulBase, void (*pfnHandler)(void));
|
||||
extern void I2SIntUnregister(unsigned long ulBase);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //__I2S_H__
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// i2s.h
|
||||
//
|
||||
// Defines and Macros for the I2S.
|
||||
//
|
||||
// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
|
||||
//
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
//
|
||||
// Neither the name of Texas Instruments Incorporated nor the names of
|
||||
// its contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef __I2S_H__
|
||||
#define __I2S_H__
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// I2S DMA ports.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define I2S_TX_DMA_PORT 0x4401E200
|
||||
#define I2S_RX_DMA_PORT 0x4401E280
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be passed to I2SConfigSetExpClk() as the ulConfig parameter.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define I2S_SLOT_SIZE_8 0x00300032
|
||||
#define I2S_SLOT_SIZE_16 0x00700074
|
||||
#define I2S_SLOT_SIZE_24 0x00B000B6
|
||||
|
||||
|
||||
#define I2S_PORT_CPU 0x00080008
|
||||
#define I2S_PORT_DMA 0x00000000
|
||||
|
||||
#define I2S_MODE_MASTER 0x00000000
|
||||
#define I2S_MODE_SLAVE 0x00008000
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be passed as ulDataLine parameter.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define I2S_DATA_LINE_0 0x00000001
|
||||
#define I2S_DATA_LINE_1 0x00000002
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be passed to I2SSerializerConfig() as the ulSerMode
|
||||
// parameter.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define I2S_SER_MODE_TX 0x00000001
|
||||
#define I2S_SER_MODE_RX 0x00000002
|
||||
#define I2S_SER_MODE_DISABLE 0x00000000
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be passed to I2SSerializerConfig() as the ulInActState
|
||||
// parameter.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define I2S_INACT_TRI_STATE 0x00000000
|
||||
#define I2S_INACT_LOW_LEVEL 0x00000008
|
||||
#define I2S_INACT_HIGH_LEVEL 0x0000000C
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be passed to I2SIntEnable() and I2SIntDisable() as the
|
||||
// ulIntFlags parameter.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define I2S_INT_XUNDRN 0x00000001
|
||||
#define I2S_INT_XSYNCERR 0x00000002
|
||||
#define I2S_INT_XLAST 0x00000010
|
||||
#define I2S_INT_XDATA 0x00000020
|
||||
#define I2S_INT_XSTAFRM 0x00000080
|
||||
#define I2S_INT_XDMA 0x80000000
|
||||
#define I2S_INT_ROVRN 0x00010000
|
||||
#define I2S_INT_RSYNCERR 0x00020000
|
||||
#define I2S_INT_RLAST 0x00100000
|
||||
#define I2S_INT_RDATA 0x00200000
|
||||
#define I2S_INT_RSTAFRM 0x00800000
|
||||
#define I2S_INT_RDMA 0x40000000
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be passed to I2SRxActiveSlotSet() and I2STxActiveSlotSet
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define I2S_ACT_SLOT_EVEN 0x00000001
|
||||
#define I2S_ACT_SLOT_ODD 0x00000002
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be passed to I2SIntClear() as the
|
||||
// ulIntFlags parameter and returned from I2SIntStatus().
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define I2S_STS_XERR 0x00000100
|
||||
#define I2S_STS_XDMAERR 0x00000080
|
||||
#define I2S_STS_XSTAFRM 0x00000040
|
||||
#define I2S_STS_XDATA 0x00000020
|
||||
#define I2S_STS_XLAST 0x00000010
|
||||
#define I2S_STS_XSYNCERR 0x00000002
|
||||
#define I2S_STS_XUNDRN 0x00000001
|
||||
#define I2S_STS_XDMA 0x80000000
|
||||
#define I2S_STS_RERR 0x01000000
|
||||
#define I2S_STS_RDMAERR 0x00800000
|
||||
#define I2S_STS_RSTAFRM 0x00400000
|
||||
#define I2S_STS_RDATA 0x00200000
|
||||
#define I2S_STS_RLAST 0x00100000
|
||||
#define I2S_STS_RSYNCERR 0x00020000
|
||||
#define I2S_STS_ROVERN 0x00010000
|
||||
#define I2S_STS_RDMA 0x40000000
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be passed to I2SEnable() as the ulMode parameter.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define I2S_MODE_TX_ONLY 0x00000001
|
||||
#define I2S_MODE_TX_RX_SYNC 0x00000003
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// API Function prototypes
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void I2SEnable(unsigned long ulBase, unsigned long ulMode);
|
||||
extern void I2SDisable(unsigned long ulBase);
|
||||
|
||||
extern void I2SDataPut(unsigned long ulBase, unsigned long ulDataLine,
|
||||
unsigned long ulData);
|
||||
extern long I2SDataPutNonBlocking(unsigned long ulBase,
|
||||
unsigned long ulDataLine, unsigned long ulData);
|
||||
|
||||
extern void I2SDataGet(unsigned long ulBase, unsigned long ulDataLine,
|
||||
unsigned long *pulData);
|
||||
extern long I2SDataGetNonBlocking(unsigned long ulBase,
|
||||
unsigned long ulDataLine, unsigned long *pulData);
|
||||
|
||||
extern void I2SConfigSetExpClk(unsigned long ulBase, unsigned long ulI2SClk,
|
||||
unsigned long ulBitClk, unsigned long ulConfig);
|
||||
|
||||
extern void I2STxFIFOEnable(unsigned long ulBase, unsigned long ulTxLevel,
|
||||
unsigned long ulWordsPerTransfer);
|
||||
extern void I2STxFIFODisable(unsigned long ulBase);
|
||||
extern void I2SRxFIFOEnable(unsigned long ulBase, unsigned long ulRxLevel,
|
||||
unsigned long ulWordsPerTransfer);
|
||||
extern void I2SRxFIFODisable(unsigned long ulBase);
|
||||
extern unsigned long I2STxFIFOStatusGet(unsigned long ulBase);
|
||||
extern unsigned long I2SRxFIFOStatusGet(unsigned long ulBase);
|
||||
|
||||
extern void I2SSerializerConfig(unsigned long ulBase, unsigned long ulDataLine,
|
||||
unsigned long ulSerMode, unsigned long ulInActState);
|
||||
|
||||
extern void I2SIntEnable(unsigned long ulBase, unsigned long ulIntFlags);
|
||||
extern void I2SIntDisable(unsigned long ulBase, unsigned long ulIntFlags);
|
||||
extern unsigned long I2SIntStatus(unsigned long ulBase);
|
||||
extern void I2SIntClear(unsigned long ulBase, unsigned long ulIntFlags);
|
||||
extern void I2SIntRegister(unsigned long ulBase, void (*pfnHandler)(void));
|
||||
extern void I2SIntUnregister(unsigned long ulBase);
|
||||
extern void I2STxActiveSlotSet(unsigned long ulBase, unsigned long ulActSlot);
|
||||
extern void I2SRxActiveSlotSet(unsigned long ulBase, unsigned long ulActSlot);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //__I2S_H__
|
||||
|
||||
|
||||
@@ -334,7 +334,7 @@ void PinConfigSet(unsigned long ulPin,unsigned long ulPinStrength,
|
||||
//
|
||||
// Isolate the output
|
||||
//
|
||||
HWREG(ulPad) |= 0xC00;
|
||||
HWREG(ulPad) = 0xC00;
|
||||
|
||||
}
|
||||
else
|
||||
|
||||
@@ -98,26 +98,40 @@
|
||||
#define RTC_SECS_IN_U64MSEC(u64Msec) ((unsigned long)(u64Msec >> 10))
|
||||
#define RTC_MSEC_IN_U64MSEC(u64Msec) ((unsigned short)(u64Msec & 0x3FF))
|
||||
|
||||
#define RTC_MSEC_U32_REG_ADDR (HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG2)
|
||||
#define RTC_SECS_U32_REG_ADDR (HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG3)
|
||||
#define RTC_MSEC_U16_REG_ADDR (HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG2+2)
|
||||
|
||||
#define RTC_U32SECS_REG (HWREG(RTC_SECS_U32_REG_ADDR))
|
||||
#define RTC_U16MSEC_REG (*(unsigned short*)RTC_MSEC_U16_REG_ADDR)
|
||||
|
||||
//*****************************************************************************
|
||||
// Register Access and Updates
|
||||
//
|
||||
// Tick of SCC has a resolution of 32768Hz. Therefore, scaling SCC value by 32
|
||||
// yields ~1 msec resolution. All operations of SCC in RTC context use ms unit.
|
||||
//*****************************************************************************
|
||||
#define SCC_U64MSEC_GET() (PRCMSlowClkCtrGet() >> 5)
|
||||
#define SCC_U64MSEC_MATCH_SET(u64Msec) (PRCMSlowClkCtrMatchSet(u64Msec << 5))
|
||||
#define SCC_U64MSEC_MATCH_GET() (PRCMSlowClkCtrMatchGet() >> 5)
|
||||
// Tick of SCC has a resolution of 32768Hz, meaning 1 sec is equal to 32768
|
||||
// clock ticks. Ideal way of getting time in millisecond will involve floating
|
||||
// point arithmetic (division by 32.768). To avoid this, we simply divide it by
|
||||
// 32, which will give a range from 0 -1023(instead of 0-999). To use this
|
||||
// output correctly we have to take care of this inaccuracy externally.
|
||||
// following wrapper can be used to convert the value from cycles to
|
||||
// millisecond:
|
||||
//
|
||||
// CYCLES_U16MS(cycles) ((cycles *1000)/ 1024),
|
||||
//
|
||||
// Similarly, before setting the value, it must be first converted (from ms to
|
||||
// cycles).
|
||||
//
|
||||
// U16MS_CYCLES(msec) ((msec *1024)/1000)
|
||||
//
|
||||
// Note: There is a precision loss of 1 ms with the above scheme.
|
||||
//
|
||||
//
|
||||
#define SCC_U64MSEC_GET() (MAP_PRCMSlowClkCtrGet() >> 5)
|
||||
#define SCC_U64MSEC_MATCH_SET(u64Msec) (MAP_PRCMSlowClkCtrMatchSet(u64Msec << 5))
|
||||
#define SCC_U64MSEC_MATCH_GET() (MAP_PRCMSlowClkCtrMatchGet() >> 5)
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Bit: 31 is used to indicate use of RTC. If set as '1', RTC feature is used.
|
||||
// Bits: 30 to 26 are reserved, available to software for use
|
||||
// Bit: 30 is used to indicate that a safe boot should be performed
|
||||
// bit: 29 is used to indicate that the last reset was caused by the WDT
|
||||
// Bits: 28 to 26 are unused
|
||||
// Bits: 25 to 16 are used to save millisecond part of RTC reference.
|
||||
// Bits: 15 to 0 are being used for HW Changes / ECO
|
||||
//
|
||||
@@ -128,13 +142,23 @@
|
||||
//*****************************************************************************
|
||||
static void RTCUseSet(void)
|
||||
{
|
||||
unsigned short usRegValue;
|
||||
unsigned int uiRegValue;
|
||||
|
||||
usRegValue = RTC_U16MSEC_REG | (1 << 15);
|
||||
uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) | (1 << 31);
|
||||
|
||||
UtilsDelay((80*200)/3);
|
||||
PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
|
||||
}
|
||||
|
||||
RTC_U16MSEC_REG = usRegValue;
|
||||
//*****************************************************************************
|
||||
// Clear RTC USE Bit
|
||||
//*****************************************************************************
|
||||
static void RTCUseClear(void)
|
||||
{
|
||||
unsigned int uiRegValue;
|
||||
|
||||
uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(1 << 31));
|
||||
|
||||
PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -142,41 +166,29 @@ static void RTCUseSet(void)
|
||||
//*****************************************************************************
|
||||
static tBoolean IsRTCUsed(void)
|
||||
{
|
||||
unsigned short usRegValue;
|
||||
|
||||
usRegValue = RTC_U16MSEC_REG;
|
||||
|
||||
UtilsDelay((80*200)/3);
|
||||
|
||||
return ((usRegValue & (1 << 15))? true : false);
|
||||
return (MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (1 << 31)) ? true : false;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// Read 16-bit mSecs
|
||||
//*****************************************************************************
|
||||
static unsigned short RTCU16MSecRegRead(void)
|
||||
static unsigned short RTCU32MSecRegRead(void)
|
||||
{
|
||||
unsigned short usRegValue;
|
||||
|
||||
usRegValue = RTC_U16MSEC_REG;
|
||||
|
||||
UtilsDelay((80*200)/3);
|
||||
|
||||
return (usRegValue & 0x3FF);
|
||||
return ((MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) >> 16) & 0x03FF);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// Write 16-bit mSecs
|
||||
//*****************************************************************************
|
||||
static void RTCU16MSecRegWrite(unsigned short u16Msec)
|
||||
static void RTCU32MSecRegWrite(unsigned int u32Msec)
|
||||
{
|
||||
unsigned short usRegValue;
|
||||
unsigned int uiRegValue;
|
||||
|
||||
usRegValue = RTC_U16MSEC_REG;
|
||||
// read the whole register and clear the msec bits
|
||||
uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(0x03FF << 16));
|
||||
|
||||
UtilsDelay((80*200)/3);
|
||||
|
||||
RTC_U16MSEC_REG = ((usRegValue & ~0x3FF) |u16Msec);
|
||||
// write the msec bits only
|
||||
MAP_PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue | ((u32Msec & 0x03FF) << 16));
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -184,7 +196,7 @@ static void RTCU16MSecRegWrite(unsigned short u16Msec)
|
||||
//*****************************************************************************
|
||||
static unsigned long RTCU32SecRegRead(void)
|
||||
{
|
||||
return (PRCMHIBRegRead(RTC_SECS_U32_REG_ADDR));
|
||||
return (MAP_PRCMHIBRegRead(RTC_SECS_U32_REG_ADDR));
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -192,7 +204,7 @@ static unsigned long RTCU32SecRegRead(void)
|
||||
//*****************************************************************************
|
||||
static void RTCU32SecRegWrite(unsigned long u32Msec)
|
||||
{
|
||||
PRCMHIBRegWrite(RTC_SECS_U32_REG_ADDR, u32Msec);
|
||||
MAP_PRCMHIBRegWrite(RTC_SECS_U32_REG_ADDR, u32Msec);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -200,9 +212,10 @@ static void RTCU32SecRegWrite(unsigned long u32Msec)
|
||||
//*****************************************************************************
|
||||
#define IS_RTC_USED() IsRTCUsed()
|
||||
#define RTC_USE_SET() RTCUseSet()
|
||||
#define RTC_USE_CLR() RTCUseClear()
|
||||
|
||||
#define RTC_U16MSEC_REG_RD() RTCU16MSecRegRead()
|
||||
#define RTC_U16MSEC_REG_WR(u16Msec) RTCU16MSecRegWrite(u16Msec)
|
||||
#define RTC_U32MSEC_REG_RD() RTCU32MSecRegRead()
|
||||
#define RTC_U32MSEC_REG_WR(u32Msec) RTCU32MSecRegWrite(u32Msec)
|
||||
|
||||
#define RTC_U32SECS_REG_RD() RTCU32SecRegRead()
|
||||
#define RTC_U32SECS_REG_WR(u32Secs) RTCU32SecRegWrite(u32Secs)
|
||||
@@ -239,6 +252,98 @@ static const PRCM_PeriphRegs_t PRCM_PeriphRegsList[] =
|
||||
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Requests a safe boot
|
||||
//!
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void PRCMRequestSafeBoot(void)
|
||||
{
|
||||
unsigned int uiRegValue;
|
||||
|
||||
uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) | (1 << 30);
|
||||
|
||||
PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Clear the safe boot request
|
||||
//!
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void PRCMClearSafeBootRequest(void)
|
||||
{
|
||||
unsigned int uiRegValue;
|
||||
|
||||
uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(1 << 30));
|
||||
|
||||
PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Read the safe boot request bit. This bit is cleared after reading.
|
||||
//!
|
||||
//! \return Value of the safe boot bit
|
||||
//
|
||||
//*****************************************************************************
|
||||
tBoolean PRCMIsSafeBootRequested(void)
|
||||
{
|
||||
tBoolean safeboot = (MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (1 << 30)) ? true : false;
|
||||
|
||||
PRCMClearSafeBootRequest();
|
||||
|
||||
return safeboot;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Signals that a WDT reset has occurred
|
||||
//!
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void PRCMSignalWDTReset(void)
|
||||
{
|
||||
unsigned int uiRegValue;
|
||||
|
||||
uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) | (1 << 29);
|
||||
|
||||
PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Clear the WDT reset signal
|
||||
//!
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void PRCMClearWDTResetSignal(void)
|
||||
{
|
||||
unsigned int uiRegValue;
|
||||
|
||||
uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(1 << 29));
|
||||
|
||||
PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Read the WDT reset signal bit
|
||||
//!
|
||||
//! \return Value of the WDT reset signal bit
|
||||
//
|
||||
//*****************************************************************************
|
||||
tBoolean PRCMWasResetBecauseOfWDT(void)
|
||||
{
|
||||
return (MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (1 << 29)) ? true : false;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Performs a software reset of a SOC
|
||||
@@ -304,7 +409,7 @@ void PRCMMCUReset(tBoolean bIncludeSubsystem)
|
||||
//! \return Returns one of the cause defined above.
|
||||
//
|
||||
//*****************************************************************************
|
||||
unsigned long PRCMSysResetCauseGet()
|
||||
unsigned long PRCMSysResetCauseGet(void)
|
||||
{
|
||||
unsigned long ulWakeupStatus;
|
||||
|
||||
@@ -318,7 +423,7 @@ unsigned long PRCMSysResetCauseGet()
|
||||
//
|
||||
if(ulWakeupStatus == PRCM_POWER_ON)
|
||||
{
|
||||
if(PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_WAKE_STATUS) & 0x1)
|
||||
if(MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_WAKE_STATUS) & 0x1)
|
||||
{
|
||||
ulWakeupStatus = PRCM_HIB_EXIT;
|
||||
}
|
||||
@@ -349,8 +454,7 @@ unsigned long PRCMSysResetCauseGet()
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMPeripheralClkEnable(unsigned long ulPeripheral, unsigned long ulClkFlags)
|
||||
void PRCMPeripheralClkEnable(unsigned long ulPeripheral, unsigned long ulClkFlags)
|
||||
{
|
||||
//
|
||||
// Enable the specified peripheral clocks, Nothing to be done for PRCM_ADC
|
||||
@@ -386,8 +490,7 @@ PRCMPeripheralClkEnable(unsigned long ulPeripheral, unsigned long ulClkFlags)
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMPeripheralClkDisable(unsigned long ulPeripheral, unsigned long ulClkFlags)
|
||||
void PRCMPeripheralClkDisable(unsigned long ulPeripheral, unsigned long ulClkFlags)
|
||||
{
|
||||
//
|
||||
// Disable the specified peripheral clocks
|
||||
@@ -409,8 +512,7 @@ PRCMPeripheralClkDisable(unsigned long ulPeripheral, unsigned long ulClkFlags)
|
||||
//! \return Returns input clock frequency for specified peripheral.
|
||||
//
|
||||
//*****************************************************************************
|
||||
unsigned long
|
||||
PRCMPeripheralClockGet(unsigned long ulPeripheral)
|
||||
unsigned long PRCMPeripheralClockGet(unsigned long ulPeripheral)
|
||||
{
|
||||
unsigned long ulClockFreq;
|
||||
unsigned long ulHiPulseDiv;
|
||||
@@ -462,8 +564,7 @@ PRCMPeripheralClockGet(unsigned long ulPeripheral)
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMPeripheralReset(unsigned long ulPeripheral)
|
||||
void PRCMPeripheralReset(unsigned long ulPeripheral)
|
||||
{
|
||||
volatile unsigned long ulDelay;
|
||||
|
||||
@@ -503,8 +604,7 @@ PRCMPeripheralReset(unsigned long ulPeripheral)
|
||||
//! \return Returns \b true if the peripheral is ready, \b false otherwise.
|
||||
//
|
||||
//*****************************************************************************
|
||||
tBoolean
|
||||
PRCMPeripheralStatusGet(unsigned long ulPeripheral)
|
||||
tBoolean PRCMPeripheralStatusGet(unsigned long ulPeripheral)
|
||||
{
|
||||
unsigned long ReadyBit;
|
||||
|
||||
@@ -546,8 +646,7 @@ PRCMPeripheralStatusGet(unsigned long ulPeripheral)
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMI2SClockFreqSet(unsigned long ulI2CClkFreq)
|
||||
void PRCMI2SClockFreqSet(unsigned long ulI2CClkFreq)
|
||||
{
|
||||
unsigned long long ullDiv;
|
||||
unsigned short usInteger;
|
||||
@@ -577,8 +676,7 @@ PRCMI2SClockFreqSet(unsigned long ulI2CClkFreq)
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMLPDSRestoreInfoSet(unsigned long ulStackPtr, unsigned long ulProgCntr)
|
||||
void PRCMLPDSRestoreInfoSet(unsigned long ulStackPtr, unsigned long ulProgCntr)
|
||||
{
|
||||
//
|
||||
// Set The SP Value
|
||||
@@ -600,15 +698,24 @@ PRCMLPDSRestoreInfoSet(unsigned long ulStackPtr, unsigned long ulProgCntr)
|
||||
//! \sa PRCMLPDSRestoreInfoSet().
|
||||
//!
|
||||
//! \return None.
|
||||
//!
|
||||
//! \note The Test Power Domain is shutdown whenever the system
|
||||
//! enters LPDS (by default). In order to avoid this and allow for
|
||||
//! connecting back the debugger after waking up from LPDS,
|
||||
//! the macro KEEP_TESTPD_ALIVE has to be defined while building the library.
|
||||
//! This is recommended for development purposes only as it adds to
|
||||
//! the current consumption of the system.
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMLPDSEnter()
|
||||
void PRCMLPDSEnter(void)
|
||||
{
|
||||
#ifndef DEBUG
|
||||
//
|
||||
// Disable TestPD
|
||||
//
|
||||
HWREG(0x4402E168) |= (1<<9);
|
||||
#endif
|
||||
|
||||
//
|
||||
// Set bandgap duty cycle to 1
|
||||
@@ -618,8 +725,7 @@ PRCMLPDSEnter()
|
||||
//
|
||||
// Request LPDS
|
||||
//
|
||||
HWREG(ARCM_BASE + APPS_RCM_O_APPS_LPDS_REQ)
|
||||
= APPS_RCM_APPS_LPDS_REQ_APPS_LPDS_REQ;
|
||||
HWREG(ARCM_BASE + APPS_RCM_O_APPS_LPDS_REQ) = APPS_RCM_APPS_LPDS_REQ_APPS_LPDS_REQ;
|
||||
|
||||
__asm(" nop\n"
|
||||
" nop\n"
|
||||
@@ -642,8 +748,7 @@ PRCMLPDSEnter()
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMLPDSWakeupSourceEnable(unsigned long ulLpdsWakeupSrc)
|
||||
void PRCMLPDSWakeupSourceEnable(unsigned long ulLpdsWakeupSrc)
|
||||
{
|
||||
unsigned long ulRegVal;
|
||||
|
||||
@@ -678,8 +783,7 @@ PRCMLPDSWakeupSourceEnable(unsigned long ulLpdsWakeupSrc)
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMLPDSWakeupSourceDisable(unsigned long ulLpdsWakeupSrc)
|
||||
void PRCMLPDSWakeupSourceDisable(unsigned long ulLpdsWakeupSrc)
|
||||
{
|
||||
HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_CFG) &= ~ulLpdsWakeupSrc;
|
||||
}
|
||||
@@ -695,8 +799,7 @@ PRCMLPDSWakeupSourceDisable(unsigned long ulLpdsWakeupSrc)
|
||||
//! PRCMLPDSWakeupSourceEnable().
|
||||
//
|
||||
//*****************************************************************************
|
||||
unsigned long
|
||||
PRCMLPDSWakeupCauseGet()
|
||||
unsigned long PRCMLPDSWakeupCauseGet(void)
|
||||
{
|
||||
return (HWREG(GPRCM_BASE+ GPRCM_O_APPS_LPDS_WAKEUP_SRC));
|
||||
}
|
||||
@@ -714,8 +817,7 @@ PRCMLPDSWakeupCauseGet()
|
||||
//! \return Returns \b true on success, \b false otherwise.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMLPDSIntervalSet(unsigned long ulTicks)
|
||||
void PRCMLPDSIntervalSet(unsigned long ulTicks)
|
||||
{
|
||||
//
|
||||
// Check sleep is atleast for 21 cycles
|
||||
@@ -759,13 +861,12 @@ PRCMLPDSIntervalSet(unsigned long ulTicks)
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMLPDSWakeUpGPIOSelect(unsigned long ulGPIOPin, unsigned long ulType)
|
||||
void PRCMLPDSWakeUpGPIOSelect(unsigned long ulGPIOPin, unsigned long ulType)
|
||||
{
|
||||
//
|
||||
// Set the wakeup GPIO
|
||||
//
|
||||
PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_LPDS_GPIO_SEL, ulGPIOPin);
|
||||
MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_LPDS_GPIO_SEL, ulGPIOPin);
|
||||
|
||||
//
|
||||
// Set the trigger type.
|
||||
@@ -785,8 +886,7 @@ PRCMLPDSWakeUpGPIOSelect(unsigned long ulGPIOPin, unsigned long ulType)
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMSleepEnter()
|
||||
void PRCMSleepEnter(void)
|
||||
{
|
||||
//
|
||||
// Request Sleep
|
||||
@@ -806,8 +906,7 @@ PRCMSleepEnter()
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMDeepSleepEnter()
|
||||
void PRCMDeepSleepEnter(void)
|
||||
{
|
||||
//
|
||||
// Set bandgap duty cycle to 1
|
||||
@@ -857,8 +956,7 @@ PRCMDeepSleepEnter()
|
||||
//! \return None.
|
||||
//
|
||||
//****************************************************************************
|
||||
void
|
||||
PRCMSRAMRetentionEnable(unsigned long ulSramColSel, unsigned long ulModeFlags)
|
||||
void PRCMSRAMRetentionEnable(unsigned long ulSramColSel, unsigned long ulModeFlags)
|
||||
{
|
||||
if(ulModeFlags & PRCM_SRAM_DSLP_RET)
|
||||
{
|
||||
@@ -902,8 +1000,7 @@ PRCMSRAMRetentionEnable(unsigned long ulSramColSel, unsigned long ulModeFlags)
|
||||
//! \return None.
|
||||
//
|
||||
//****************************************************************************
|
||||
void
|
||||
PRCMSRAMRetentionDisable(unsigned long ulSramColSel, unsigned long ulFlags)
|
||||
void PRCMSRAMRetentionDisable(unsigned long ulSramColSel, unsigned long ulFlags)
|
||||
{
|
||||
if(ulFlags & PRCM_SRAM_DSLP_RET)
|
||||
{
|
||||
@@ -944,15 +1041,14 @@ PRCMSRAMRetentionDisable(unsigned long ulSramColSel, unsigned long ulFlags)
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMHibernateWakeupSourceEnable(unsigned long ulHIBWakupSrc)
|
||||
void PRCMHibernateWakeupSourceEnable(unsigned long ulHIBWakupSrc)
|
||||
{
|
||||
unsigned long ulRegValue;
|
||||
|
||||
//
|
||||
// Read the RTC register
|
||||
//
|
||||
ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN);
|
||||
ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN);
|
||||
|
||||
//
|
||||
// Enable the RTC as wakeup source if specified
|
||||
@@ -962,12 +1058,12 @@ PRCMHibernateWakeupSourceEnable(unsigned long ulHIBWakupSrc)
|
||||
//
|
||||
// Enable HIB wakeup sources
|
||||
//
|
||||
PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue);
|
||||
MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue);
|
||||
|
||||
//
|
||||
// REad the GPIO wakeup configuration register
|
||||
//
|
||||
ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN);
|
||||
ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN);
|
||||
|
||||
//
|
||||
// Enable the specified GPIOs a wakeup sources
|
||||
@@ -977,7 +1073,7 @@ PRCMHibernateWakeupSourceEnable(unsigned long ulHIBWakupSrc)
|
||||
//
|
||||
// Write the new register configuration
|
||||
//
|
||||
PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN,ulRegValue);
|
||||
MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN,ulRegValue);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -993,15 +1089,14 @@ PRCMHibernateWakeupSourceEnable(unsigned long ulHIBWakupSrc)
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMHibernateWakeupSourceDisable(unsigned long ulHIBWakupSrc)
|
||||
void PRCMHibernateWakeupSourceDisable(unsigned long ulHIBWakupSrc)
|
||||
{
|
||||
unsigned long ulRegValue;
|
||||
|
||||
//
|
||||
// Read the RTC register
|
||||
//
|
||||
ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN);
|
||||
ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN);
|
||||
|
||||
//
|
||||
// Disable the RTC as wakeup source if specified
|
||||
@@ -1011,12 +1106,12 @@ PRCMHibernateWakeupSourceDisable(unsigned long ulHIBWakupSrc)
|
||||
//
|
||||
// Disable HIB wakeup sources
|
||||
//
|
||||
PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue);
|
||||
MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_EN,ulRegValue);
|
||||
|
||||
//
|
||||
// Read the GPIO wakeup configuration register
|
||||
//
|
||||
ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN);
|
||||
ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN);
|
||||
|
||||
//
|
||||
// Enable the specified GPIOs a wakeup sources
|
||||
@@ -1026,7 +1121,7 @@ PRCMHibernateWakeupSourceDisable(unsigned long ulHIBWakupSrc)
|
||||
//
|
||||
// Write the new register configuration
|
||||
//
|
||||
PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN,ulRegValue);
|
||||
MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_EN,ulRegValue);
|
||||
}
|
||||
|
||||
|
||||
@@ -1040,10 +1135,9 @@ PRCMHibernateWakeupSourceDisable(unsigned long ulHIBWakupSrc)
|
||||
//! \b PRCM_HIB_WAKEUP_CAUSE_GPIO
|
||||
//
|
||||
//*****************************************************************************
|
||||
unsigned long
|
||||
PRCMHibernateWakeupCauseGet()
|
||||
unsigned long PRCMHibernateWakeupCauseGet(void)
|
||||
{
|
||||
return ((PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_WAKE_STATUS)>>1)&0xF);
|
||||
return ((MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_WAKE_STATUS)>>1)&0xF);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -1057,22 +1151,21 @@ PRCMHibernateWakeupCauseGet()
|
||||
//! \return Returns \b true on success, \b false otherwise.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMHibernateIntervalSet(unsigned long long ullTicks)
|
||||
void PRCMHibernateIntervalSet(unsigned long long ullTicks)
|
||||
{
|
||||
unsigned long long ullRTCVal;
|
||||
|
||||
//
|
||||
// Latch the RTC vlaue
|
||||
//
|
||||
PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_READ ,0x1);
|
||||
MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_READ ,0x1);
|
||||
|
||||
//
|
||||
// Read latched values as 2 32-bit vlaues
|
||||
//
|
||||
ullRTCVal = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_MSW);
|
||||
ullRTCVal = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_MSW);
|
||||
ullRTCVal = ullRTCVal << 32;
|
||||
ullRTCVal |= PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_LSW);
|
||||
ullRTCVal |= MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_LSW);
|
||||
|
||||
//
|
||||
// Add the interval
|
||||
@@ -1082,9 +1175,9 @@ PRCMHibernateIntervalSet(unsigned long long ullTicks)
|
||||
//
|
||||
// Set RTC match value
|
||||
//
|
||||
PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_LSW_CONF,
|
||||
MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_LSW_CONF,
|
||||
(unsigned long)(ullRTCVal));
|
||||
PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_MSW_CONF,
|
||||
MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_WAKE_MSW_CONF,
|
||||
(unsigned long)(ullRTCVal>>32));
|
||||
}
|
||||
|
||||
@@ -1119,8 +1212,7 @@ PRCMHibernateIntervalSet(unsigned long long ullTicks)
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMHibernateWakeUpGPIOSelect(unsigned long ulGPIOBitMap, unsigned long ulType)
|
||||
void PRCMHibernateWakeUpGPIOSelect(unsigned long ulGPIOBitMap, unsigned long ulType)
|
||||
{
|
||||
unsigned char ucLoop;
|
||||
unsigned long ulRegValue;
|
||||
@@ -1137,9 +1229,9 @@ PRCMHibernateWakeUpGPIOSelect(unsigned long ulGPIOBitMap, unsigned long ulType)
|
||||
{
|
||||
if(ulGPIOBitMap & (1<<ucLoop))
|
||||
{
|
||||
ulRegValue = PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_CONF);
|
||||
ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_CONF);
|
||||
ulRegValue |= (ulType << (ucLoop*2));
|
||||
PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_CONF, ulRegValue);
|
||||
MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_GPIO_WAKE_CONF, ulRegValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1155,14 +1247,13 @@ PRCMHibernateWakeUpGPIOSelect(unsigned long ulGPIOBitMap, unsigned long ulType)
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMHibernateEnter()
|
||||
void PRCMHibernateEnter(void)
|
||||
{
|
||||
|
||||
//
|
||||
// Request hibernate.
|
||||
//
|
||||
PRCMHIBRegWrite((HIB3P3_BASE+HIB3P3_O_MEM_HIB_REQ),0x1);
|
||||
MAP_PRCMHIBRegWrite((HIB3P3_BASE+HIB3P3_O_MEM_HIB_REQ),0x1);
|
||||
|
||||
__asm(" nop\n"
|
||||
" nop\n"
|
||||
@@ -1179,22 +1270,21 @@ PRCMHibernateEnter()
|
||||
//! \return 64-bit current counter vlaue.
|
||||
//
|
||||
//*****************************************************************************
|
||||
unsigned long long
|
||||
PRCMSlowClkCtrGet()
|
||||
unsigned long long PRCMSlowClkCtrGet(void)
|
||||
{
|
||||
unsigned long long ullRTCVal;
|
||||
|
||||
//
|
||||
// Latch the RTC vlaue
|
||||
//
|
||||
PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_READ, 0x1);
|
||||
MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_READ, 0x1);
|
||||
|
||||
//
|
||||
// Read latched values as 2 32-bit vlaues
|
||||
//
|
||||
ullRTCVal = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_MSW);
|
||||
ullRTCVal = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_TIMER_MSW);
|
||||
ullRTCVal = ullRTCVal << 32;
|
||||
ullRTCVal |= PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_LSW);
|
||||
ullRTCVal |= MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_RTC_TIMER_LSW);
|
||||
|
||||
return ullRTCVal;
|
||||
}
|
||||
@@ -1217,9 +1307,9 @@ void PRCMSlowClkCtrMatchSet(unsigned long long ullValue)
|
||||
//
|
||||
// Set RTC match value
|
||||
//
|
||||
PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_LSW_CONF,
|
||||
MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_LSW_CONF,
|
||||
(unsigned long)(ullValue));
|
||||
PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_MSW_CONF,
|
||||
MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_MSW_CONF,
|
||||
(unsigned long)(ullValue>>32));
|
||||
}
|
||||
|
||||
@@ -1233,16 +1323,16 @@ void PRCMSlowClkCtrMatchSet(unsigned long long ullValue)
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
unsigned long long PRCMSlowClkCtrMatchGet()
|
||||
unsigned long long PRCMSlowClkCtrMatchGet(void)
|
||||
{
|
||||
unsigned long long ullValue;
|
||||
|
||||
//
|
||||
// Get RTC match value
|
||||
//
|
||||
ullValue = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_MSW_CONF);
|
||||
ullValue = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_MSW_CONF);
|
||||
ullValue = ullValue<<32;
|
||||
ullValue |= PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_LSW_CONF);
|
||||
ullValue |= MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_LSW_CONF);
|
||||
|
||||
//
|
||||
// Return the value
|
||||
@@ -1265,7 +1355,7 @@ unsigned long long PRCMSlowClkCtrMatchGet()
|
||||
//*****************************************************************************
|
||||
void PRCMOCRRegisterWrite(unsigned char ucIndex, unsigned long ulRegValue)
|
||||
{
|
||||
PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_REG2+(ucIndex << 2),ulRegValue);
|
||||
MAP_PRCMHIBRegWrite(HIB3P3_BASE+HIB3P3_O_MEM_HIB_REG2+(ucIndex << 2),ulRegValue);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -1285,7 +1375,7 @@ unsigned long PRCMOCRRegisterRead(unsigned char ucIndex)
|
||||
//
|
||||
// Return the read value.
|
||||
//
|
||||
return PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_REG2 + (ucIndex << 2));
|
||||
return MAP_PRCMHIBRegRead(HIB3P3_BASE+HIB3P3_O_MEM_HIB_REG2 + (ucIndex << 2));
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -1326,7 +1416,7 @@ void PRCMIntRegister(void (*pfnHandler)(void))
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void PRCMIntUnregister()
|
||||
void PRCMIntUnregister(void)
|
||||
{
|
||||
//
|
||||
// Enable the UART interrupt.
|
||||
@@ -1368,9 +1458,9 @@ void PRCMIntEnable(unsigned long ulIntFlags)
|
||||
//
|
||||
// Enable RTC interrupt
|
||||
//
|
||||
ulRegValue = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE);
|
||||
ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE);
|
||||
ulRegValue |= 0x1;
|
||||
PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE, ulRegValue);
|
||||
MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE, ulRegValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1404,9 +1494,9 @@ void PRCMIntDisable(unsigned long ulIntFlags)
|
||||
//
|
||||
// Disable RTC interrupt
|
||||
//
|
||||
ulRegValue = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE);
|
||||
ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE);
|
||||
ulRegValue &= ~0x1;
|
||||
PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE, ulRegValue);
|
||||
MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_RTC_IRQ_ENABLE, ulRegValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1420,7 +1510,7 @@ void PRCMIntDisable(unsigned long ulIntFlags)
|
||||
//! \return Returns the current interrupt status.
|
||||
//
|
||||
//*****************************************************************************
|
||||
unsigned long PRCMIntStatus()
|
||||
unsigned long PRCMIntStatus(void)
|
||||
{
|
||||
return HWREG(ARCM_BASE + APPS_RCM_O_APPS_RCM_INTERRUPT_STATUS);
|
||||
}
|
||||
@@ -1437,15 +1527,25 @@ unsigned long PRCMIntStatus()
|
||||
//! register is not available to user. Also, users must not excercise the Slow
|
||||
//! Clock Counter API(s), if RTC has been set for use.
|
||||
//!
|
||||
//! The RTC feature, if set or marked, can be only reset either through reboot
|
||||
//! or power cycle.
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void PRCMRTCInUseSet(void)
|
||||
{
|
||||
RTC_USE_SET();
|
||||
return;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Clear the function of RTC as being used
|
||||
//!
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void PRCMRTCInUseSet()
|
||||
void PRCMRTCInUseClear(void)
|
||||
{
|
||||
RTC_USE_SET();
|
||||
RTC_USE_CLR();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1466,7 +1566,7 @@ void PRCMRTCInUseSet()
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
tBoolean PRCMRTCInUseGet()
|
||||
tBoolean PRCMRTCInUseGet(void)
|
||||
{
|
||||
return IS_RTC_USED()? true : false;
|
||||
}
|
||||
@@ -1498,7 +1598,7 @@ void PRCMRTCSet(unsigned long ulSecs, unsigned short usMsec)
|
||||
ullMsec = RTC_U64MSEC_MK(ulSecs, usMsec) - SCC_U64MSEC_GET();
|
||||
|
||||
RTC_U32SECS_REG_WR(RTC_SECS_IN_U64MSEC(ullMsec));
|
||||
RTC_U16MSEC_REG_WR(RTC_MSEC_IN_U64MSEC(ullMsec));
|
||||
RTC_U32MSEC_REG_WR(RTC_MSEC_IN_U64MSEC(ullMsec));
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -1529,7 +1629,7 @@ void PRCMRTCGet(unsigned long *ulSecs, unsigned short *usMsec)
|
||||
|
||||
if(IS_RTC_USED()) {
|
||||
ullMsec = RTC_U64MSEC_MK(RTC_U32SECS_REG_RD(),
|
||||
RTC_U16MSEC_REG_RD());
|
||||
RTC_U32MSEC_REG_RD());
|
||||
ullMsec += SCC_U64MSEC_GET();
|
||||
}
|
||||
|
||||
@@ -1565,7 +1665,7 @@ void PRCMRTCMatchSet(unsigned long ulSecs, unsigned short usMsec)
|
||||
if(IS_RTC_USED()) {
|
||||
ullMsec = RTC_U64MSEC_MK(ulSecs, usMsec);
|
||||
ullMsec -= RTC_U64MSEC_MK(RTC_U32SECS_REG_RD(),
|
||||
RTC_U16MSEC_REG_RD());
|
||||
RTC_U32MSEC_REG_RD());
|
||||
SCC_U64MSEC_MATCH_SET(SELECT_SCC_U42BITS(ullMsec));
|
||||
}
|
||||
|
||||
@@ -1598,7 +1698,7 @@ void PRCMRTCMatchGet(unsigned long *ulSecs, unsigned short *usMsec)
|
||||
if(IS_RTC_USED()) {
|
||||
ullMsec = SCC_U64MSEC_MATCH_GET();
|
||||
ullMsec += RTC_U64MSEC_MK(RTC_U32SECS_REG_RD(),
|
||||
RTC_U16MSEC_REG_RD());
|
||||
RTC_U32MSEC_REG_RD());
|
||||
}
|
||||
|
||||
*ulSecs = RTC_SECS_IN_U64MSEC(ullMsec);
|
||||
@@ -1616,7 +1716,7 @@ void PRCMRTCMatchGet(unsigned long *ulSecs, unsigned short *usMsec)
|
||||
//! \return None
|
||||
//
|
||||
//*****************************************************************************
|
||||
void PRCMCC3200MCUInit()
|
||||
void PRCMCC3200MCUInit(void)
|
||||
{
|
||||
unsigned long ulRegValue;
|
||||
|
||||
@@ -1627,11 +1727,11 @@ void PRCMCC3200MCUInit()
|
||||
|
||||
//
|
||||
// Enable hibernate ECO for PG 1.32 devices only. With this ECO enabled,
|
||||
// any hibernate wakeup source will be kept maked until the device enters
|
||||
// any hibernate wakeup source will be kept masked until the device enters
|
||||
// hibernate completely (analog + digital)
|
||||
//
|
||||
ulRegValue = PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG0);
|
||||
PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG0, ulRegValue | (1<<4));
|
||||
ulRegValue = MAP_PRCMHIBRegRead(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG0);
|
||||
MAP_PRCMHIBRegWrite(HIB3P3_BASE + HIB3P3_O_MEM_HIB_REG0, ulRegValue | (1<<4));
|
||||
|
||||
//
|
||||
// Handling the clock switching (for 1.32 only)
|
||||
@@ -1770,6 +1870,63 @@ void PRCMHIBRegWrite(unsigned long ulRegAddr, unsigned long ulValue)
|
||||
UtilsDelay((80*200)/3);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! \param ulDivider is clock frequency divider value
|
||||
//! \param ulWidth is the width of the high pulse
|
||||
//!
|
||||
//! This function sets the input frequency for camera module.
|
||||
//!
|
||||
//! The frequency is calculated as follows:
|
||||
//!
|
||||
//! f_out = 240MHz/ulDivider;
|
||||
//!
|
||||
//! The parameter \e ulWidth sets the width of the high pulse.
|
||||
//!
|
||||
//! For e.g.:
|
||||
//!
|
||||
//! ulDivider = 4;
|
||||
//! ulWidth = 2;
|
||||
//!
|
||||
//! f_out = 30 MHz and 50% duty cycle
|
||||
//!
|
||||
//! And,
|
||||
//!
|
||||
//! ulDivider = 4;
|
||||
//! ulWidth = 1;
|
||||
//!
|
||||
//! f_out = 30 MHz and 25% duty cycle
|
||||
//!
|
||||
//! \return 0 on success, 1 on error
|
||||
//
|
||||
//*****************************************************************************
|
||||
unsigned long PRCMCameraFreqSet(unsigned char ulDivider, unsigned char ulWidth)
|
||||
{
|
||||
if(ulDivider > ulWidth && ulWidth != 0 )
|
||||
{
|
||||
//
|
||||
// Set the hifh pulse width
|
||||
//
|
||||
HWREG(ARCM_BASE +
|
||||
APPS_RCM_O_CAMERA_CLK_GEN) = (((ulWidth & 0x07) -1) << 8);
|
||||
|
||||
//
|
||||
// Set the low pulse width
|
||||
//
|
||||
HWREG(ARCM_BASE +
|
||||
APPS_RCM_O_CAMERA_CLK_GEN) = ((ulDivider - ulWidth - 1) & 0x07);
|
||||
//
|
||||
// Return success
|
||||
//
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Success;
|
||||
//
|
||||
return 1;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
|
||||
@@ -59,8 +59,8 @@ extern "C"
|
||||
typedef struct _PRCM_PeripheralRegs_
|
||||
{
|
||||
|
||||
unsigned long ulClkReg;
|
||||
unsigned long ulRstReg;
|
||||
unsigned char ulClkReg;
|
||||
unsigned char ulRstReg;
|
||||
|
||||
}PRCM_PeriphRegs_t;
|
||||
|
||||
@@ -159,7 +159,7 @@ unsigned long ulRstReg;
|
||||
#define PRCM_HIB_WAKEUP_CAUSE_GPIO 0x00000004
|
||||
|
||||
//*****************************************************************************
|
||||
// Values that can be passed to PRCMSEnableInterrupt
|
||||
// Values that can be passed to PRCMIntEnable
|
||||
//*****************************************************************************
|
||||
#define PRCM_INT_SLOW_CLK_CTR 0x00004000
|
||||
|
||||
@@ -197,6 +197,12 @@ unsigned long ulRstReg;
|
||||
// API Function prototypes
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void PRCMRequestSafeBoot(void);
|
||||
extern void PRCMClearSafeBootRequest(void);
|
||||
extern tBoolean PRCMIsSafeBootRequested(void);
|
||||
extern void PRCMSignalWDTReset(void);
|
||||
extern void PRCMClearWDTResetSignal(void);
|
||||
extern tBoolean PRCMWasResetBecauseOfWDT(void);
|
||||
extern void PRCMSOCReset(void);
|
||||
extern void PRCMMCUReset(tBoolean bIncludeSubsystem);
|
||||
extern unsigned long PRCMSysResetCauseGet(void);
|
||||
@@ -250,6 +256,7 @@ extern void PRCMIntEnable(unsigned long ulIntFlags);
|
||||
extern void PRCMIntDisable(unsigned long ulIntFlags);
|
||||
extern unsigned long PRCMIntStatus(void);
|
||||
extern void PRCMRTCInUseSet(void);
|
||||
extern void PRCMRTCInUseClear(void);
|
||||
extern tBoolean PRCMRTCInUseGet(void);
|
||||
extern void PRCMRTCSet(unsigned long ulSecs, unsigned short usMsec);
|
||||
extern void PRCMRTCGet(unsigned long *ulSecs, unsigned short *usMsec);
|
||||
@@ -258,6 +265,7 @@ extern void PRCMRTCMatchGet(unsigned long *ulSecs, unsigned short *usMsec);
|
||||
extern void PRCMCC3200MCUInit(void);
|
||||
extern unsigned long PRCMHIBRegRead(unsigned long ulRegAddr);
|
||||
extern void PRCMHIBRegWrite(unsigned long ulRegAddr, unsigned long ulValue);
|
||||
extern unsigned long PRCMCameraFreqSet(unsigned char ulDivider, unsigned char ulWidth);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
#undef ROM_IntEnable
|
||||
#undef ROM_IntDisable
|
||||
#undef ROM_IntPendSet
|
||||
#undef ROM_PRCMHibernateWakeUpGPIOSelect
|
||||
#undef ROM_SDHostCardErrorMaskSet
|
||||
#undef ROM_SDHostCardErrorMaskGet
|
||||
#undef ROM_TimerConfigure
|
||||
@@ -84,4 +83,16 @@
|
||||
#undef ROM_SPIConfigSetExpClk
|
||||
#undef ROM_GPIODirModeGet
|
||||
#undef ROM_GPIOIntTypeGet
|
||||
#undef ROM_I2CMasterInitExpClk
|
||||
#undef ROM_AESDataProcess
|
||||
#undef ROM_DESDataProcess
|
||||
#undef ROM_I2SEnable
|
||||
#undef ROM_I2SConfigSetExpClk
|
||||
#undef ROM_PinConfigSet
|
||||
#undef ROM_PRCMLPDSEnter
|
||||
#undef ROM_PRCMCC3200MCUInit
|
||||
#undef ROM_SDHostIntStatus
|
||||
#undef ROM_SDHostBlockCountSet
|
||||
#undef ROM_UARTModemControlSet
|
||||
#undef ROM_UARTModemControlClear
|
||||
|
||||
|
||||
@@ -512,7 +512,7 @@ SDHostIntStatus(unsigned long ulBase)
|
||||
//
|
||||
// Get DMA done interrupt status
|
||||
//
|
||||
ulIntStatus = HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_MASK_SET);
|
||||
ulIntStatus = HWREG(APPS_CONFIG_BASE + APPS_CONFIG_O_DMA_DONE_INT_STS_RAW);
|
||||
ulIntStatus = (ulIntStatus << 30);
|
||||
|
||||
//
|
||||
@@ -562,7 +562,7 @@ SDHostIntClear(unsigned long ulBase,unsigned long ulIntFlags)
|
||||
//! \param ulErrMask is the bit mask of card status errors to be enabled
|
||||
//!
|
||||
//! This function sets the card status error mask for response type R1, R1b,
|
||||
//! R5, R5b and R6 response. The parameter \ulErrMask is the bit mask of card
|
||||
//! R5, R5b and R6 response. The parameter \e ulErrMask is the bit mask of card
|
||||
//! status errors to be enabled, if the corresponding bits in the 'card status'
|
||||
//! field of a respose are set then the host controller indicates a card error
|
||||
//! interrupt status. Only bits referenced as type E (error) in status field in
|
||||
@@ -732,7 +732,7 @@ SDHostBlockCountSet(unsigned long ulBase, unsigned short ulBlkCount)
|
||||
//
|
||||
// Set the number of blocks
|
||||
//
|
||||
HWREG(ulBase + MMCHS_O_BLK) |= ((ulRegVal & 0x0000FFFF)|
|
||||
HWREG(ulBase + MMCHS_O_BLK) = ((ulRegVal & 0x0000FFFF)|
|
||||
(ulBlkCount << 16));
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ extern "C"
|
||||
#define SDHOST_INT_CEB 0x00040000
|
||||
#define SDHOST_INT_DTO 0x00100000
|
||||
#define SDHOST_INT_DCRC 0x00200000
|
||||
#define SDHOST_INT_DEB 0x00300000
|
||||
#define SDHOST_INT_DEB 0x00400000
|
||||
#define SDHOST_INT_CERR 0x10000000
|
||||
#define SDHOST_INT_BADA 0x20000000
|
||||
#define SDHOST_INT_DMARD 0x40000000
|
||||
|
||||
@@ -718,7 +718,7 @@ SPIReset(unsigned long ulBase)
|
||||
//! - \b SPI_WL_16
|
||||
//! - \b SPI_WL_32
|
||||
//!
|
||||
//! Active state of Chip[ Selece can be defined by:-
|
||||
//! Active state of Chip Select can be defined by:-
|
||||
//! - \b SPI_CS_ACTIVELOW
|
||||
//! - \b SPI_CS_ACTIVEHIGH
|
||||
//!
|
||||
|
||||
@@ -53,19 +53,23 @@ extern uint32_t _edata;
|
||||
extern uint32_t _bss;
|
||||
extern uint32_t _ebss;
|
||||
extern uint32_t _estack;
|
||||
extern uint32_t __init_data;
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Forward declaration of the default fault handlers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifndef BOOTLOADER
|
||||
__attribute__ ((section (".boot")))
|
||||
#endif
|
||||
void ResetISR(void);
|
||||
#ifdef DEBUG
|
||||
static void NmiSR(void) __attribute__( ( naked ) );
|
||||
static void FaultISR( void ) __attribute__( ( naked ) );
|
||||
static void IntDefaultHandler(void) __attribute__( ( naked ) );
|
||||
void HardFault_HandlerC(uint32_t *pulFaultStackAddress);
|
||||
static void BusFaultHandler(void) __attribute__( ( naked ) );
|
||||
void HardFault_HandlerC(unsigned long *hardfault_args);
|
||||
#endif
|
||||
static void IntDefaultHandler(void) __attribute__( ( naked ) );
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
@@ -96,10 +100,19 @@ void (* const g_pfnVectors[256])(void) =
|
||||
{
|
||||
(void (*)(void))((uint32_t)&_estack), // The initial stack pointer
|
||||
ResetISR, // The reset handler
|
||||
#ifdef DEBUG
|
||||
NmiSR, // The NMI handler
|
||||
FaultISR, // The hard fault handler
|
||||
#else
|
||||
IntDefaultHandler, // The NMI handler
|
||||
IntDefaultHandler, // The hard fault handler
|
||||
#endif
|
||||
IntDefaultHandler, // The MPU fault handler
|
||||
#ifdef DEBUG
|
||||
BusFaultHandler, // The bus fault handler
|
||||
#else
|
||||
IntDefaultHandler, // The bus fault handler
|
||||
#endif
|
||||
IntDefaultHandler, // The usage fault handler
|
||||
0, // Reserved
|
||||
0, // Reserved
|
||||
@@ -201,45 +214,38 @@ void (* const g_pfnVectors[256])(void) =
|
||||
void ResetISR(void)
|
||||
{
|
||||
#if defined(DEBUG) && !defined(BOOTLOADER)
|
||||
//
|
||||
// Fill the main stack with a known value so that
|
||||
// we can measure the main stack high water mark
|
||||
//
|
||||
__asm volatile
|
||||
(
|
||||
"ldr r0, =_stack \n"
|
||||
"ldr r1, =_estack \n"
|
||||
"mov r2, #0x55555555 \n"
|
||||
".thumb_func \n"
|
||||
"fill_loop: \n"
|
||||
"cmp r0, r1 \n"
|
||||
"it lt \n"
|
||||
"strlt r2, [r0], #4 \n"
|
||||
"blt fill_loop \n"
|
||||
);
|
||||
{
|
||||
//
|
||||
// Fill the main stack with a known value so that
|
||||
// we can measure the main stack high water mark
|
||||
//
|
||||
__asm volatile
|
||||
(
|
||||
"ldr r0, =_stack \n"
|
||||
"ldr r1, =_estack \n"
|
||||
"mov r2, #0x55555555 \n"
|
||||
".thumb_func \n"
|
||||
"fill_loop: \n"
|
||||
"cmp r0, r1 \n"
|
||||
"it lt \n"
|
||||
"strlt r2, [r0], #4 \n"
|
||||
"blt fill_loop \n"
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get the initial stack pointer location from the vector table
|
||||
// and write this value to the msp register
|
||||
__asm volatile
|
||||
(
|
||||
"ldr r0, =_text \n"
|
||||
"ldr r0, [r0] \n"
|
||||
"msr msp, r0 \n"
|
||||
);
|
||||
{
|
||||
// Get the initial stack pointer location from the vector table
|
||||
// and write this value to the msp register
|
||||
__asm volatile
|
||||
(
|
||||
"ldr r0, =_text \n"
|
||||
"ldr r0, [r0] \n"
|
||||
"msr msp, r0 \n"
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
uint32_t *pui32Src, *pui32Dest;
|
||||
|
||||
//
|
||||
// Copy the data segment initializers
|
||||
//
|
||||
pui32Src = &__init_data;
|
||||
for(pui32Dest = &_data; pui32Dest < &_edata; )
|
||||
{
|
||||
*pui32Dest++ = *pui32Src++;
|
||||
}
|
||||
|
||||
//
|
||||
// Zero fill the bss segment.
|
||||
//
|
||||
@@ -257,12 +263,15 @@ void ResetISR(void)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Call the application's entry point.
|
||||
//
|
||||
main();
|
||||
{
|
||||
//
|
||||
// Call the application's entry point.
|
||||
//
|
||||
main();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
//*****************************************************************************
|
||||
//
|
||||
// This is the code that gets called when the processor receives a NMI. This
|
||||
@@ -273,10 +282,8 @@ void ResetISR(void)
|
||||
|
||||
static void NmiSR(void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// Break into the debugger
|
||||
__asm volatile ("bkpt #0 \n");
|
||||
#endif
|
||||
|
||||
//
|
||||
// Enter an infinite loop.
|
||||
@@ -316,55 +323,9 @@ static void FaultISR(void)
|
||||
) ;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// This is the code that gets called when the processor receives an unexpected
|
||||
// interrupt. This simply enters an infinite loop, preserving the system state
|
||||
// for examination by a debugger.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
static void BusFaultHandler(void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// Break into the debugger
|
||||
__asm volatile ("bkpt #0 \n");
|
||||
#endif
|
||||
|
||||
//
|
||||
// Enter an infinite loop.
|
||||
//
|
||||
for ( ; ; )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// This is the code that gets called when the processor receives an unexpected
|
||||
// interrupt. This simply enters an infinite loop, preserving the system state
|
||||
// for examination by a debugger.
|
||||
//
|
||||
//*****************************************************************************
|
||||
static void IntDefaultHandler(void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// Break into the debugger
|
||||
__asm volatile ("bkpt #0 \n");
|
||||
#endif
|
||||
|
||||
//
|
||||
// Enter an infinite loop.
|
||||
//
|
||||
for ( ; ; )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//***********************************************************************************
|
||||
// HardFaultHandler_C:
|
||||
// This is called from the HardFault_HandlerAsm with a pointer the Fault stack
|
||||
// This is called from the FaultISR with a pointer the Fault stack
|
||||
// as the parameter. We can then read the values from the stack and place them
|
||||
// into local variables for ease of reading.
|
||||
// We then read the various Fault Status and Address Registers to help decode
|
||||
@@ -403,10 +364,8 @@ void HardFault_HandlerC(uint32_t *pulFaultStackAddress)
|
||||
// Bus Fault Address Register
|
||||
_BFAR = (*((volatile uint32_t *)(0xE000ED38)));
|
||||
|
||||
#ifdef DEBUG
|
||||
// Break into the debugger
|
||||
__asm volatile ("bkpt #0 \n");
|
||||
#endif
|
||||
|
||||
for ( ; ; )
|
||||
{
|
||||
@@ -416,3 +375,47 @@ void HardFault_HandlerC(uint32_t *pulFaultStackAddress)
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// This is the code that gets called when the processor receives an unexpected
|
||||
// interrupt. This simply enters an infinite loop, preserving the system state
|
||||
// for examination by a debugger.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
static void BusFaultHandler(void)
|
||||
{
|
||||
// Break into the debugger
|
||||
__asm volatile ("bkpt #0 \n");
|
||||
|
||||
//
|
||||
// Enter an infinite loop.
|
||||
//
|
||||
for ( ; ; )
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// This is the code that gets called when the processor receives an unexpected
|
||||
// interrupt. This simply enters an infinite loop, preserving the system state
|
||||
// for examination by a debugger.
|
||||
//
|
||||
//*****************************************************************************
|
||||
static void IntDefaultHandler(void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// Break into the debugger
|
||||
__asm volatile ("bkpt #0 \n");
|
||||
#endif
|
||||
|
||||
//
|
||||
// Enter an infinite loop.
|
||||
//
|
||||
for ( ; ; )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -617,6 +617,45 @@ TimerValueGet(unsigned long ulBase, unsigned long ulTimer)
|
||||
HWREG(ulBase + TIMER_O_TBR));
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Sets the current timer value.
|
||||
//!
|
||||
//! \param ulBase is the base address of the timer module.
|
||||
//! \param ulTimer specifies the timer; must be one of \b TIMER_A or
|
||||
//! \b TIMER_B. Only \b TIMER_A should be used when the timer is configured
|
||||
//! for 32-bit operation.
|
||||
//! \param ulValue is the new value of the timer to be set.
|
||||
//!
|
||||
//! This function sets the current value of the specified timer.
|
||||
//!
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
TimerValueSet(unsigned long ulBase, unsigned long ulTimer,
|
||||
unsigned long ulValue)
|
||||
{
|
||||
//
|
||||
// Check the arguments.
|
||||
//
|
||||
ASSERT(TimerBaseValid(ulBase));
|
||||
ASSERT((ulTimer == TIMER_A) || (ulTimer == TIMER_B));
|
||||
|
||||
//
|
||||
// Set the appropriate timer value.
|
||||
//
|
||||
if( (ulTimer == TIMER_A) )
|
||||
{
|
||||
HWREG(ulBase + TIMER_O_TAV) = ulValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
HWREG(ulBase + TIMER_O_TBV) = ulValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Sets the timer match value.
|
||||
@@ -979,8 +1018,8 @@ TimerIntClear(unsigned long ulBase, unsigned long ulIntFlags)
|
||||
//
|
||||
//! Enables the events that can trigger a DMA request.
|
||||
//!
|
||||
//! \param ui32Base is the base address of the timer module.
|
||||
//! \param ui32DMAEvent is a bit mask of the events that can trigger DMA.
|
||||
//! \param ulBase is the base address of the timer module.
|
||||
//! \param ulDMAEvent is a bit mask of the events that can trigger DMA.
|
||||
//!
|
||||
//! This function enables the timer events that can trigger the start of a DMA
|
||||
//! sequence. The DMA trigger events are specified in the \e ui32DMAEvent
|
||||
@@ -1022,7 +1061,7 @@ TimerDMAEventSet(unsigned long ulBase, unsigned long ulDMAEvent)
|
||||
//
|
||||
//! Returns the events that can trigger a DMA request.
|
||||
//!
|
||||
//! \param ui32Base is the base address of the timer module.
|
||||
//! \param ulBase is the base address of the timer module.
|
||||
//!
|
||||
//! This function returns the timer events that can trigger the start of a DMA
|
||||
//! sequence. The DMA trigger events are the logical OR of the following
|
||||
|
||||
@@ -180,6 +180,8 @@ extern unsigned long TimerLoadGet(unsigned long ulBase, unsigned long ulTimer);
|
||||
|
||||
extern unsigned long TimerValueGet(unsigned long ulBase,
|
||||
unsigned long ulTimer);
|
||||
extern void TimerValueSet(unsigned long ulBase, unsigned long ulTimer,
|
||||
unsigned long ulValue);
|
||||
|
||||
extern void TimerMatchSet(unsigned long ulBase, unsigned long ulTimer,
|
||||
unsigned long ulValue);
|
||||
|
||||
@@ -1167,13 +1167,8 @@ UARTIntRegister(unsigned long ulBase, void (*pfnHandler)(void))
|
||||
//
|
||||
// Determine the interrupt number based on the UART port.
|
||||
//
|
||||
#if 1
|
||||
ulInt = UARTIntNumberGet(ulBase);
|
||||
#else
|
||||
|
||||
ulInt = ((ulBase == UART0_BASE) ? INT_UART0 :
|
||||
((ulBase == UART1_BASE) ? INT_UART1 : INT_UART2));
|
||||
#endif
|
||||
ulInt = UARTIntNumberGet(ulBase);
|
||||
|
||||
//
|
||||
// Register the interrupt handler.
|
||||
@@ -1216,12 +1211,7 @@ UARTIntUnregister(unsigned long ulBase)
|
||||
//
|
||||
// Determine the interrupt number based on the UART port.
|
||||
//
|
||||
#if 1
|
||||
ulInt = UARTIntNumberGet(ulBase);
|
||||
#else
|
||||
ulInt = ((ulBase == UART0_BASE) ? INT_UART0 :
|
||||
((ulBase == UART1_BASE) ? INT_UART1 : INT_UART2));
|
||||
#endif
|
||||
|
||||
//
|
||||
// Disable the interrupt.
|
||||
|
||||
@@ -28,15 +28,13 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "mptask.h"
|
||||
#include "simplelink.h"
|
||||
#include "osi.h"
|
||||
#include "pybwdt.h"
|
||||
#include "debug.h"
|
||||
#include "mperror.h"
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE CONSTANTS
|
||||
@@ -61,11 +59,15 @@ OsiTaskHandle mpTaskHandle;
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
__attribute__ ((section (".boot")))
|
||||
int main (void) {
|
||||
|
||||
// Initialize the clocks and the interrupt system
|
||||
HAL_SystemInit();
|
||||
|
||||
// Init the watchdog
|
||||
pybwdt_init0();
|
||||
|
||||
#ifdef DEBUG
|
||||
ASSERT (OSI_OK == osi_TaskCreate(TASK_Micropython,
|
||||
(const signed char *)"MicroPy",
|
||||
@@ -81,7 +83,6 @@ int main (void) {
|
||||
for ( ; ; );
|
||||
}
|
||||
|
||||
|
||||
void stoupper (char *str) {
|
||||
while (str && *str != '\0') {
|
||||
*str = (char)toupper((int)(*str));
|
||||
|
||||
@@ -28,19 +28,16 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "py/obj.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "pybuart.h"
|
||||
#include "pybstdio.h"
|
||||
#include "osi.h"
|
||||
#include "pybwdt.h"
|
||||
#include "mperror.h"
|
||||
|
||||
|
||||
#ifdef USE_FREERTOS
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! \brief Application defined idle task hook
|
||||
@@ -50,10 +47,13 @@
|
||||
//! \return none
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void
|
||||
vApplicationIdleHook( void)
|
||||
void vApplicationIdleHook (void)
|
||||
{
|
||||
//Handle Idle Hook for Profiling, Power Management etc
|
||||
// kick the watchdog
|
||||
pybwdt_kick();
|
||||
// signal that we are alive and kicking
|
||||
mperror_heartbeat_signal();
|
||||
// gate the processor's clock to save power
|
||||
__WFI();
|
||||
}
|
||||
|
||||
@@ -66,18 +66,16 @@ vApplicationIdleHook( void)
|
||||
//! \return none
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void vApplicationMallocFailedHook()
|
||||
void vApplicationMallocFailedHook (void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// Break into the debugger
|
||||
// break into the debugger
|
||||
__asm volatile ("bkpt #0 \n");
|
||||
|
||||
printf("\nFATAL ERROR: FreeRTOS malloc failed!\n");
|
||||
#endif
|
||||
|
||||
//Handle Memory Allocation Errors
|
||||
while(1)
|
||||
for ( ; ; )
|
||||
{
|
||||
__fatal_error("FreeRTOS malloc failed!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,18 +88,16 @@ void vApplicationMallocFailedHook()
|
||||
//! \return none
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void vApplicationStackOverflowHook( OsiTaskHandle *pxTask, signed char *pcTaskName)
|
||||
void vApplicationStackOverflowHook (OsiTaskHandle *pxTask, signed char *pcTaskName)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// Break into the debugger
|
||||
__asm volatile ("bkpt #0 \n");
|
||||
|
||||
printf("\nFATAL ERROR: Application: %s stack overflow!\n", pcTaskName);
|
||||
#endif
|
||||
|
||||
//Handle FreeRTOS Stack Overflow
|
||||
while(1)
|
||||
for ( ; ; )
|
||||
{
|
||||
__fatal_error("Stack overflow!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,9 +110,7 @@ void vApplicationStackOverflowHook( OsiTaskHandle *pxTask, signed char *pcTaskNa
|
||||
//! \return none
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void vApplicationTickHook( void )
|
||||
void vApplicationTickHook (void)
|
||||
{
|
||||
HAL_IncrementTick();
|
||||
}
|
||||
|
||||
#endif //USE_FREERTOS
|
||||
|
||||
@@ -27,11 +27,8 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/obj.h"
|
||||
|
||||
STATIC const char help_text[] = "Welcome to Micro Python!\n"
|
||||
"For online help please visit http://micropython.org/help/.\n"
|
||||
@@ -49,10 +46,9 @@ STATIC mp_obj_t pyb_help(uint n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0) {
|
||||
// print a general help message
|
||||
printf("%s", help_text);
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// try to print something sensible about the given object
|
||||
|
||||
printf("object ");
|
||||
mp_obj_print(args[0], PRINT_STR);
|
||||
printf(" is of type %s\n", mp_obj_get_type_str(args[0]));
|
||||
@@ -79,7 +75,6 @@ STATIC mp_obj_t pyb_help(uint n_args, const mp_obj_t *args) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_help_obj, 0, 1, pyb_help);
|
||||
|
||||
210
cc3200/misc/mpcallback.c
Normal file
210
cc3200/misc/mpcallback.c
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/gc.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "interrupt.h"
|
||||
#include "pybsleep.h"
|
||||
#include "mpcallback.h"
|
||||
#include "mpexception.h"
|
||||
#include "mperror.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC DATA
|
||||
******************************************************************************/
|
||||
const mp_arg_t mpcallback_init_args[] = {
|
||||
{ MP_QSTR_intmode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_handler, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_priority, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
|
||||
{ MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_wakes, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PYB_PWR_MODE_ACTIVE} },
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
void mpcallback_init0 (void) {
|
||||
// initialize the callback objects list
|
||||
mp_obj_list_init(&MP_STATE_PORT(mpcallback_obj_list), 0);
|
||||
}
|
||||
|
||||
mp_obj_t mpcallback_new (mp_obj_t parent, mp_obj_t handler, const mp_cb_methods_t *methods) {
|
||||
mpcallback_obj_t *self = m_new_obj(mpcallback_obj_t);
|
||||
self->base.type = &pyb_callback_type;
|
||||
self->handler = handler;
|
||||
self->parent = parent;
|
||||
self->methods = (mp_cb_methods_t *)methods;
|
||||
self->isenabled = true;
|
||||
// remove any old callback if present
|
||||
mpcallback_remove(self->parent);
|
||||
mp_obj_list_append(&MP_STATE_PORT(mpcallback_obj_list), self);
|
||||
return self;
|
||||
}
|
||||
|
||||
mpcallback_obj_t *mpcallback_find (mp_obj_t parent) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mpcallback_obj_list).len; i++) {
|
||||
// search for the object and then remove it
|
||||
mpcallback_obj_t *callback_obj = ((mpcallback_obj_t *)(MP_STATE_PORT(mpcallback_obj_list).items[i]));
|
||||
if (callback_obj->parent == parent) {
|
||||
return callback_obj;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void mpcallback_wake_all (void) {
|
||||
// re-enable all active callback objects one by one
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mpcallback_obj_list).len; i++) {
|
||||
mpcallback_obj_t *callback_obj = ((mpcallback_obj_t *)(MP_STATE_PORT(mpcallback_obj_list).items[i]));
|
||||
if (callback_obj->isenabled) {
|
||||
callback_obj->methods->enable(callback_obj->parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mpcallback_remove (const mp_obj_t parent) {
|
||||
mpcallback_obj_t *callback_obj;
|
||||
if ((callback_obj = mpcallback_find(parent))) {
|
||||
mp_obj_list_remove(&MP_STATE_PORT(mpcallback_obj_list), callback_obj);
|
||||
}
|
||||
}
|
||||
|
||||
uint mpcallback_translate_priority (uint priority) {
|
||||
if (priority < 1 || priority > 7) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
switch (priority) {
|
||||
case 1:
|
||||
return INT_PRIORITY_LVL_7;
|
||||
case 2:
|
||||
return INT_PRIORITY_LVL_6;
|
||||
case 3:
|
||||
return INT_PRIORITY_LVL_5;
|
||||
case 4:
|
||||
return INT_PRIORITY_LVL_4;
|
||||
case 5:
|
||||
return INT_PRIORITY_LVL_3;
|
||||
case 6:
|
||||
return INT_PRIORITY_LVL_2;
|
||||
case 7:
|
||||
return INT_PRIORITY_LVL_1;
|
||||
default:
|
||||
return INT_PRIORITY_LVL_7;
|
||||
}
|
||||
}
|
||||
|
||||
void mpcallback_handler (mp_obj_t self_in) {
|
||||
mpcallback_obj_t *self = self_in;
|
||||
if (self && self->handler != mp_const_none) {
|
||||
// disable interrupts to avoid nesting
|
||||
uint primsk = disable_irq();
|
||||
// when executing code within a handler we must lock the GC to prevent
|
||||
// any memory allocations. We must also catch any exceptions.
|
||||
gc_lock();
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_call_function_1(self->handler, self->parent);
|
||||
nlr_pop();
|
||||
}
|
||||
else {
|
||||
// uncaught exception; disable the callback so that it doesn't run again
|
||||
self->methods->disable (self->parent);
|
||||
self->handler = mp_const_none;
|
||||
// printing an exception here will cause a stack overflow that will end up in
|
||||
// a hard fault, so is better to signal the uncaught (probably non-recoverable)
|
||||
// exception by blinking the system led instead.
|
||||
mperror_signal_error();
|
||||
}
|
||||
gc_unlock();
|
||||
enable_irq(primsk);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
/// \method init()
|
||||
/// Initializes the interrupt callback. With no parameters passed, everything will default
|
||||
/// to the values assigned to mpcallback_init_args[].
|
||||
STATIC mp_obj_t callback_init(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
mpcallback_obj_t *self = pos_args[0];
|
||||
// this is a bit of a hack, but it let us reuse the callback_create method from our parent
|
||||
((mp_obj_t *)pos_args)[0] = self->parent;
|
||||
self->methods->init (n_args, pos_args, kw_args);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(callback_init_obj, 1, callback_init);
|
||||
|
||||
/// \method enable()
|
||||
/// Enables the interrupt callback
|
||||
STATIC mp_obj_t callback_enable (mp_obj_t self_in) {
|
||||
mpcallback_obj_t *self = self_in;
|
||||
self->methods->enable(self->parent);
|
||||
self->isenabled = true;
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(callback_enable_obj, callback_enable);
|
||||
|
||||
/// \method disable()
|
||||
/// Disables the interrupt callback
|
||||
STATIC mp_obj_t callback_disable (mp_obj_t self_in) {
|
||||
mpcallback_obj_t *self = self_in;
|
||||
self->methods->disable(self->parent);
|
||||
self->isenabled = false;
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(callback_disable_obj, callback_disable);
|
||||
|
||||
/// \method \call()
|
||||
/// Triggers the interrupt callback
|
||||
STATIC mp_obj_t callback_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
||||
mpcallback_handler (self_in);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
STATIC const mp_map_elem_t callback_locals_dict_table[] = {
|
||||
// instance methods
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&callback_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&callback_enable_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable), (mp_obj_t)&callback_disable_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(callback_locals_dict, callback_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t pyb_callback_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_callback,
|
||||
.call = callback_call,
|
||||
.locals_dict = (mp_obj_t)&callback_locals_dict,
|
||||
};
|
||||
|
||||
73
cc3200/misc/mpcallback.h
Normal file
73
cc3200/misc/mpcallback.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MPCALLBACK_H_
|
||||
#define MPCALLBACK_H_
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define mpcallback_INIT_NUM_ARGS 5
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
******************************************************************************/
|
||||
typedef void (*mp_cb_method_t) (mp_obj_t self);
|
||||
typedef mp_obj_t (*mp_cb_init_t) (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
||||
|
||||
typedef struct {
|
||||
mp_cb_init_t init;
|
||||
mp_cb_method_t enable;
|
||||
mp_cb_method_t disable;
|
||||
} mp_cb_methods_t;
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t parent;
|
||||
mp_obj_t handler;
|
||||
mp_cb_methods_t *methods;
|
||||
bool isenabled;
|
||||
} mpcallback_obj_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE EXPORTED DATA
|
||||
******************************************************************************/
|
||||
extern const mp_arg_t mpcallback_init_args[];
|
||||
extern const mp_obj_type_t pyb_callback_type;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
void mpcallback_init0 (void);
|
||||
mp_obj_t mpcallback_new (mp_obj_t parent, mp_obj_t handler, const mp_cb_methods_t *methods);
|
||||
mpcallback_obj_t *mpcallback_find (mp_obj_t parent);
|
||||
void mpcallback_wake_all (void);
|
||||
void mpcallback_remove (const mp_obj_t parent);
|
||||
void mpcallback_handler (mp_obj_t self_in);
|
||||
uint mpcallback_translate_priority (uint priority);
|
||||
mp_obj_t mpcallback_new (mp_obj_t parent, mp_obj_t handler, const mp_cb_methods_t *methods);
|
||||
|
||||
#endif /* MPCALLBACK_H_ */
|
||||
@@ -29,26 +29,152 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "py/obj.h"
|
||||
#include "hw_ints.h"
|
||||
#include "hw_types.h"
|
||||
#include "hw_gpio.h"
|
||||
#include "hw_memmap.h"
|
||||
#include "hw_gprcm.h"
|
||||
#include "hw_common_reg.h"
|
||||
#include "pin.h"
|
||||
#include "gpio.h"
|
||||
#ifndef BOOTLOADER
|
||||
#include "pybpin.h"
|
||||
#include "pins.h"
|
||||
#endif
|
||||
#include "rom.h"
|
||||
#include "rom_map.h"
|
||||
#include "prcm.h"
|
||||
#include "pybuart.h"
|
||||
#include "pybstdio.h"
|
||||
#include "utils.h"
|
||||
#include "mperror.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define MPERROR_TOOGLE_MS (40)
|
||||
#define MPERROR_SIGNAL_ERROR_MS (1000)
|
||||
#define MPERROR_HEARTBEAT_ON_MS (80)
|
||||
#define MPERROR_HEARTBEAT_OFF_MS (4920)
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
struct mperror_heart_beat {
|
||||
uint32_t off_time;
|
||||
uint32_t on_time;
|
||||
bool beating;
|
||||
bool enabled;
|
||||
} mperror_heart_beat = {.off_time = 0, .on_time = 0, .beating = false, .enabled = false};
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
void mperror_init0 (void) {
|
||||
#ifdef BOOTLOADER
|
||||
// enable the system led and the safe boot pin peripheral clocks
|
||||
MAP_PRCMPeripheralClkEnable(MICROPY_SYS_LED_PRCM, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
MAP_PRCMPeripheralClkEnable(MICROPY_SAFE_BOOT_PRCM, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
// configure the safe boot pin
|
||||
MAP_PinTypeGPIO(MICROPY_SAFE_BOOT_PIN_NUM, PIN_MODE_0, false);
|
||||
MAP_PinConfigSet(MICROPY_SAFE_BOOT_PIN_NUM, PIN_STRENGTH_4MA, PIN_TYPE_STD_PD);
|
||||
MAP_GPIODirModeSet(MICROPY_SAFE_BOOT_PORT, MICROPY_SAFE_BOOT_PORT_PIN, GPIO_DIR_MODE_IN);
|
||||
// configure the bld
|
||||
MAP_PinTypeGPIO(MICROPY_SYS_LED_PIN_NUM, PIN_MODE_0, false);
|
||||
MAP_PinConfigSet(MICROPY_SYS_LED_PIN_NUM, PIN_STRENGTH_6MA, PIN_TYPE_STD);
|
||||
MAP_GPIODirModeSet(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, GPIO_DIR_MODE_OUT);
|
||||
#else
|
||||
// configure the system led
|
||||
pin_config ((pin_obj_t *)&MICROPY_SYS_LED_GPIO, PIN_MODE_0, GPIO_DIR_MODE_OUT, PIN_TYPE_STD, PIN_STRENGTH_6MA);
|
||||
#endif
|
||||
mperror_heartbeat_switch_off();
|
||||
}
|
||||
|
||||
void mperror_bootloader_check_reset_cause (void) {
|
||||
// if we are recovering from a WDT reset, trigger
|
||||
// a hibernate cycle for a clean boot
|
||||
if (MAP_PRCMSysResetCauseGet() == PRCM_WDT_RESET) {
|
||||
HWREG(0x400F70B8) = 1;
|
||||
UtilsDelay(800000/5);
|
||||
HWREG(0x400F70B0) = 1;
|
||||
UtilsDelay(800000/5);
|
||||
|
||||
HWREG(0x4402E16C) |= 0x2;
|
||||
UtilsDelay(800);
|
||||
HWREG(0x4402F024) &= 0xF7FFFFFF;
|
||||
|
||||
// since the reset cause will be changed, we must store the right reason
|
||||
// so that the application knows it when booting for the next time
|
||||
PRCMSignalWDTReset();
|
||||
|
||||
MAP_PRCMHibernateWakeupSourceEnable(PRCM_HIB_SLOW_CLK_CTR);
|
||||
// set the sleep interval to 10ms
|
||||
MAP_PRCMHibernateIntervalSet(330);
|
||||
MAP_PRCMHibernateEnter();
|
||||
}
|
||||
}
|
||||
|
||||
void mperror_deinit_sfe_pin (void) {
|
||||
// disable the pull-down
|
||||
MAP_PinConfigSet(MICROPY_SAFE_BOOT_PIN_NUM, PIN_STRENGTH_4MA, PIN_TYPE_STD);
|
||||
}
|
||||
|
||||
void mperror_signal_error (void) {
|
||||
uint32_t count = 0;
|
||||
while ((MPERROR_TOOGLE_MS * count++) < MPERROR_SIGNAL_ERROR_MS) {
|
||||
// toogle the led
|
||||
MAP_GPIOPinWrite(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, ~MAP_GPIOPinRead(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN));
|
||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT(MPERROR_TOOGLE_MS * 1000));
|
||||
}
|
||||
}
|
||||
|
||||
void mperror_enable_heartbeat (void) {
|
||||
mperror_heart_beat.enabled = true;
|
||||
}
|
||||
|
||||
void mperror_heartbeat_switch_off (void) {
|
||||
mperror_heart_beat.on_time = 0;
|
||||
mperror_heart_beat.off_time = 0;
|
||||
MAP_GPIOPinWrite(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, 0);
|
||||
}
|
||||
|
||||
void mperror_disable_heartbeat (void) {
|
||||
mperror_heart_beat.enabled = false;
|
||||
mperror_heartbeat_switch_off();
|
||||
}
|
||||
|
||||
void mperror_heartbeat_signal (void) {
|
||||
if (mperror_heart_beat.enabled) {
|
||||
if (!mperror_heart_beat.beating) {
|
||||
if ((mperror_heart_beat.on_time = HAL_GetTick()) - mperror_heart_beat.off_time > MPERROR_HEARTBEAT_OFF_MS) {
|
||||
MAP_GPIOPinWrite(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, MICROPY_SYS_LED_PORT_PIN);
|
||||
mperror_heart_beat.beating = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((mperror_heart_beat.off_time = HAL_GetTick()) - mperror_heart_beat.on_time > MPERROR_HEARTBEAT_ON_MS) {
|
||||
MAP_GPIOPinWrite(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, 0);
|
||||
mperror_heart_beat.beating = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NORETURN __fatal_error(const char *msg) {
|
||||
#ifdef DEBUG
|
||||
if (msg != NULL) {
|
||||
// wait for 20ms
|
||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT(20000));
|
||||
stdout_tx_str("\r\nFATAL ERROR:");
|
||||
stdout_tx_str(msg);
|
||||
stdout_tx_str("\r\n");
|
||||
mp_hal_stdout_tx_str("\r\nFATAL ERROR:");
|
||||
mp_hal_stdout_tx_str(msg);
|
||||
mp_hal_stdout_tx_str("\r\n");
|
||||
}
|
||||
#endif
|
||||
// signal the crash with the system led
|
||||
MAP_GPIOPinWrite(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, MICROPY_SYS_LED_PORT_PIN);
|
||||
for ( ;; ) {__WFI();}
|
||||
}
|
||||
|
||||
@@ -68,3 +194,37 @@ void nlr_jump_fail(void *val) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef BOOTLOADER
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
/// \function enable()
|
||||
/// Enables the heartbeat signal
|
||||
STATIC mp_obj_t pyb_enable_heartbeat(mp_obj_t self) {
|
||||
mperror_enable_heartbeat ();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_enable_heartbeat_obj, pyb_enable_heartbeat);
|
||||
|
||||
/// \function disable()
|
||||
/// Disables the heartbeat signal
|
||||
STATIC mp_obj_t pyb_disable_heartbeat(mp_obj_t self) {
|
||||
mperror_disable_heartbeat ();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_disable_heartbeat_obj, pyb_disable_heartbeat);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_heartbeat_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&pyb_enable_heartbeat_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable), (mp_obj_t)&pyb_disable_heartbeat_obj },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_heartbeat_locals_dict, pyb_heartbeat_locals_dict_table);
|
||||
|
||||
static const mp_obj_type_t pyb_heartbeat_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_HeartBeat,
|
||||
.locals_dict = (mp_obj_t)&pyb_heartbeat_locals_dict,
|
||||
};
|
||||
|
||||
const mp_obj_base_t pyb_heartbeat_obj = {&pyb_heartbeat_type};
|
||||
#endif
|
||||
|
||||
@@ -25,8 +25,22 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
extern void NORETURN __fatal_error(const char *msg);
|
||||
#else
|
||||
#define __fatal_error(...) for ( ;; ) {__WFI();}
|
||||
#ifndef MPERROR_H_
|
||||
#define MPERROR_H_
|
||||
|
||||
#ifndef BOOTLOADER
|
||||
extern const mp_obj_base_t pyb_heartbeat_obj;
|
||||
#endif
|
||||
|
||||
extern void NORETURN __fatal_error(const char *msg);
|
||||
|
||||
void mperror_init0 (void);
|
||||
void mperror_bootloader_check_reset_cause (void);
|
||||
void mperror_deinit_sfe_pin (void);
|
||||
void mperror_signal_error (void);
|
||||
void mperror_enable_heartbeat (void);
|
||||
void mperror_heartbeat_switch_off (void);
|
||||
void mperror_disable_heartbeat (void);
|
||||
void mperror_heartbeat_signal (void);
|
||||
|
||||
#endif // MPERROR_H_
|
||||
|
||||
@@ -30,11 +30,6 @@
|
||||
#include <std.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "mpexception.h"
|
||||
|
||||
|
||||
|
||||
@@ -25,14 +25,11 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "misc.h"
|
||||
#include "nlr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "py/obj.h"
|
||||
#include "irq.h"
|
||||
#include "pybsystick.h"
|
||||
#include "mpsystick.h"
|
||||
#include "systick.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_nvic.h"
|
||||
@@ -25,6 +25,11 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MPSYSTICK_H
|
||||
#define MPSYSTICK_H
|
||||
|
||||
void sys_tick_wait_at_least(uint32_t stc, uint32_t delay_ms);
|
||||
bool sys_tick_has_passed(uint32_t stc, uint32_t delay_ms);
|
||||
uint32_t sys_tick_get_microseconds(void);
|
||||
|
||||
#endif // MPSYSTICK_H
|
||||
@@ -25,11 +25,9 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/obj.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_gpio.h"
|
||||
#include "inc/hw_ints.h"
|
||||
@@ -38,33 +36,20 @@
|
||||
#include "gpio.h"
|
||||
#include "pin.h"
|
||||
#include "pybpin.h"
|
||||
#include "runtime.h"
|
||||
#include MICROPY_HAL_H
|
||||
|
||||
|
||||
|
||||
// Returns the pin mode. This value returned by this macro should be one of:
|
||||
// GPIO_DIR_MODE_IN or GPIO_DIR_MODE_OUT
|
||||
uint32_t pin_get_mode(const pin_obj_t *self) {
|
||||
return MAP_GPIODirModeGet(self->port, self->bit);
|
||||
uint32_t pin_get_mode (const pin_obj_t *self) {
|
||||
return self->mode;
|
||||
}
|
||||
|
||||
uint32_t pin_get_type(const pin_obj_t *self) {
|
||||
|
||||
uint32_t strenght;
|
||||
uint32_t type;
|
||||
|
||||
MAP_PinConfigGet(self->pin_num, &strenght, &type);
|
||||
|
||||
return type;
|
||||
uint32_t pin_get_type (const pin_obj_t *self) {
|
||||
return self->type;
|
||||
}
|
||||
|
||||
uint32_t pin_get_strenght (const pin_obj_t *self) {
|
||||
|
||||
uint32_t strenght;
|
||||
uint32_t type;
|
||||
|
||||
MAP_PinConfigGet(self->pin_num, &strenght, &type);
|
||||
|
||||
return strenght;
|
||||
return self->strength;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,15 +29,12 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/obj.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "pybpin.h"
|
||||
#include "runtime.h"
|
||||
#include MICROPY_HAL_H
|
||||
|
||||
STATIC void pin_named_pins_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
@@ -52,7 +49,7 @@ const mp_obj_type_t pin_cpu_pins_obj_type = {
|
||||
.locals_dict = (mp_obj_t)&pin_cpu_pins_locals_dict,
|
||||
};
|
||||
|
||||
const pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) {
|
||||
pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) {
|
||||
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins);
|
||||
mp_map_elem_t *named_elem = mp_map_lookup(named_map, name, MP_MAP_LOOKUP);
|
||||
if (named_elem != NULL && named_elem->value != NULL) {
|
||||
@@ -60,3 +57,24 @@ const pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t na
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pin_obj_t *pin_find_pin(const mp_obj_dict_t *named_pins, uint pin_num) {
|
||||
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins);
|
||||
for (uint i = 0; i < named_map->used; i++) {
|
||||
if (((pin_obj_t *)named_map->table[i].value)->pin_num == pin_num) {
|
||||
return named_map->table[i].value;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pin_obj_t *pin_find_pin_by_port_bit (const mp_obj_dict_t *named_pins, uint port, uint bit) {
|
||||
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins);
|
||||
for (uint i = 0; i < named_map->used; i++) {
|
||||
if ((((pin_obj_t *)named_map->table[i].value)->port == port) &&
|
||||
(((pin_obj_t *)named_map->table[i].value)->bit == bit)) {
|
||||
return named_map->table[i].value;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -29,23 +29,17 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpstate.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "objlist.h"
|
||||
#include "runtime.h"
|
||||
#include "modnetwork.h"
|
||||
#include "mpexception.h"
|
||||
#include "mpstate.h"
|
||||
#include "serverstask.h"
|
||||
|
||||
/// \module network - network configuration
|
||||
///
|
||||
/// This module provides network drivers and routing configuration.
|
||||
|
||||
void mod_network_init(void) {
|
||||
void mod_network_init0(void) {
|
||||
mp_obj_list_init(&MP_STATE_PORT(mod_network_nic_list), 0);
|
||||
}
|
||||
|
||||
@@ -75,10 +69,44 @@ STATIC mp_obj_t network_route(void) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_route_obj, network_route);
|
||||
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
STATIC mp_obj_t network_server_start(void) {
|
||||
servers_start();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_server_start_obj, network_server_start);
|
||||
|
||||
STATIC mp_obj_t network_server_stop(void) {
|
||||
servers_stop();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_server_stop_obj, network_server_stop);
|
||||
|
||||
STATIC mp_obj_t network_server_enabled(void) {
|
||||
return MP_BOOL(servers_are_enabled());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_server_enabled_obj, network_server_enabled);
|
||||
|
||||
STATIC mp_obj_t network_server_login(mp_obj_t user, mp_obj_t pass) {
|
||||
const char *_user = mp_obj_str_get_str(user);
|
||||
const char *_pass = mp_obj_str_get_str(pass);
|
||||
servers_set_login ((char *)_user, (char *)_pass);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(network_server_login_obj, network_server_login);
|
||||
#endif
|
||||
|
||||
STATIC const mp_map_elem_t mp_module_network_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_network) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WLAN), (mp_obj_t)&mod_network_nic_type_wlan },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_route), (mp_obj_t)&network_route_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_network) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WLAN), (mp_obj_t)&mod_network_nic_type_wlan },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_route), (mp_obj_t)&network_route_obj },
|
||||
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_start_server), (mp_obj_t)&network_server_start_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_stop_server), (mp_obj_t)&network_server_stop_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_server_enabled), (mp_obj_t)&network_server_enabled_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_server_login), (mp_obj_t)&network_server_login_obj },
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_network_globals, mp_module_network_globals_table);
|
||||
|
||||
@@ -64,13 +64,13 @@ typedef struct _mod_network_socket_obj_t {
|
||||
int8_t fileno;
|
||||
} u_param;
|
||||
int16_t sd;
|
||||
bool closed;
|
||||
};
|
||||
bool closed;
|
||||
} mod_network_socket_obj_t;
|
||||
|
||||
extern const mod_network_nic_type_t mod_network_nic_type_wlan;
|
||||
|
||||
void mod_network_init(void);
|
||||
void mod_network_init0(void);
|
||||
void mod_network_register_nic(mp_obj_t nic);
|
||||
mp_obj_t mod_network_find_nic(const uint8_t *ip);
|
||||
|
||||
|
||||
@@ -30,14 +30,8 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "mpconfig.h"
|
||||
#include "py/runtime.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "misc.h"
|
||||
#include "nlr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "gc.h"
|
||||
#include "gccollect.h"
|
||||
#include "irq.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_gpio.h"
|
||||
@@ -48,11 +42,11 @@
|
||||
#include "pyexec.h"
|
||||
#include "pybuart.h"
|
||||
#include "pybpin.h"
|
||||
#include "pybstdio.h"
|
||||
#include "pybrtc.h"
|
||||
#include "pybsystick.h"
|
||||
#include "mpsystick.h"
|
||||
#include "simplelink.h"
|
||||
#include "modwlan.h"
|
||||
#include "moduos.h"
|
||||
#include "telnet.h"
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
@@ -61,16 +55,26 @@
|
||||
#include "portable.h"
|
||||
#include "task.h"
|
||||
#include "mpexception.h"
|
||||
#include "mpcallback.h"
|
||||
#include "random.h"
|
||||
#include "pybextint.h"
|
||||
#include "pybadc.h"
|
||||
#include "pybi2c.h"
|
||||
#include "pybsd.h"
|
||||
#include "pybwdt.h"
|
||||
#include "pybsleep.h"
|
||||
#include "pybspi.h"
|
||||
#include "utils.h"
|
||||
#include "gccollect.h"
|
||||
#include "mperror.h"
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
extern OsiTaskHandle mpTaskHandle;
|
||||
extern OsiTaskHandle svTaskHandle;
|
||||
extern TaskHandle_t xSimpleLinkSpawnTaskHndl;
|
||||
extern OsiTaskHandle xSimpleLinkSpawnTaskHndl;
|
||||
#endif
|
||||
|
||||
|
||||
/// \module pyb - functions related to the pyboard
|
||||
///
|
||||
/// The `pyb` module contains specific functions related to the pyboard.
|
||||
@@ -79,9 +83,8 @@ extern TaskHandle_t xSimpleLinkSpawnTaskHndl;
|
||||
/// Resets the pyboard in a manner similar to pushing the external RESET
|
||||
/// button.
|
||||
STATIC mp_obj_t pyb_hard_reset(void) {
|
||||
// disable wlan services
|
||||
wlan_servers_stop();
|
||||
wlan_sl_disable();
|
||||
// disable wlan
|
||||
wlan_stop(SL_STOP_TIMEOUT_LONG);
|
||||
// perform a SoC reset
|
||||
PRCMSOCReset();
|
||||
return mp_const_none;
|
||||
@@ -117,15 +120,6 @@ STATIC mp_obj_t pyb_info(uint n_args, const mp_obj_t *args) {
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_info_obj, 0, 1, pyb_info);
|
||||
#endif
|
||||
|
||||
/// \function unique_id()
|
||||
/// Returns a string of 6 bytes (48 bits), which is the unique MAC address of the SoC
|
||||
STATIC mp_obj_t pyb_mac(void) {
|
||||
uint8_t mac[6];
|
||||
wlan_get_mac (mac);
|
||||
return mp_obj_new_bytes(mac, 6);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_mac_obj, pyb_mac);
|
||||
|
||||
/// \function freq()
|
||||
/// Returns the CPU frequency: (F_CPU).
|
||||
STATIC mp_obj_t pyb_freq(void) {
|
||||
@@ -133,14 +127,6 @@ STATIC mp_obj_t pyb_freq(void) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_freq_obj, pyb_freq);
|
||||
|
||||
/// \function sync()
|
||||
/// Sync all file systems.
|
||||
STATIC mp_obj_t pyb_sync(void) {
|
||||
sflash_disk_flush();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_sync_obj, pyb_sync);
|
||||
|
||||
/// \function millis()
|
||||
/// Returns the number of milliseconds since the board was last reset.
|
||||
///
|
||||
@@ -219,94 +205,92 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_delay_obj, pyb_delay);
|
||||
STATIC mp_obj_t pyb_udelay(mp_obj_t usec_in) {
|
||||
mp_int_t usec = mp_obj_get_int(usec_in);
|
||||
if (usec > 0) {
|
||||
uint32_t count = 0;
|
||||
const uint32_t utime = ((HAL_FCPU_HZ / 1000000) * (usec / 4));
|
||||
while (++count <= utime) {
|
||||
}
|
||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT(usec));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_udelay_obj, pyb_udelay);
|
||||
|
||||
STATIC mp_obj_t pyb_stop(void) {
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(pyb_stop_obj, pyb_stop);
|
||||
|
||||
STATIC mp_obj_t pyb_standby(void) {
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(pyb_standby_obj, pyb_standby);
|
||||
|
||||
/// \function repl_uart(uart)
|
||||
/// Get or set the UART object that the REPL is repeated on.
|
||||
STATIC mp_obj_t pyb_repl_uart(uint n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0) {
|
||||
if (MP_STATE_PORT(pyb_stdio_uart) == NULL) {
|
||||
if (pyb_stdio_uart == NULL) {
|
||||
return mp_const_none;
|
||||
} else {
|
||||
return MP_STATE_PORT(pyb_stdio_uart);
|
||||
return pyb_stdio_uart;
|
||||
}
|
||||
} else {
|
||||
if (args[0] == mp_const_none) {
|
||||
MP_STATE_PORT(pyb_stdio_uart) = NULL;
|
||||
pyb_stdio_uart = NULL;
|
||||
} else if (mp_obj_get_type(args[0]) == &pyb_uart_type) {
|
||||
MP_STATE_PORT(pyb_stdio_uart) = args[0];
|
||||
pyb_stdio_uart = args[0];
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_num_type_invalid_arguments));
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_repl_uart_obj, 0, 1, pyb_repl_uart);
|
||||
|
||||
/// \function mkdisk('path')
|
||||
/// Formats the selected drive, useful when the filesystem has been damaged beyond repair
|
||||
STATIC mp_obj_t pyb_mkdisk(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
if (FR_OK != f_mkfs(path, 1, 0)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_mkdisk_obj, pyb_mkdisk);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_main_obj); // defined in main.c
|
||||
|
||||
STATIC const mp_map_elem_t pyb_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pyb) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_hard_reset), (mp_obj_t)&pyb_hard_reset_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_reset), (mp_obj_t)&pyb_hard_reset_obj },
|
||||
#ifdef DEBUG
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&pyb_info_obj },
|
||||
#endif
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mac), (mp_obj_t)&pyb_mac_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_freq), (mp_obj_t)&pyb_freq_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_repl_info), (mp_obj_t)&pyb_set_repl_info_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_repl_uart), (mp_obj_t)&pyb_repl_uart_obj },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_wfi), (mp_obj_t)&pyb_wfi_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable_irq), (mp_obj_t)&pyb_disable_irq_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable_irq), (mp_obj_t)&pyb_enable_irq_obj },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_stop), (mp_obj_t)&pyb_stop_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_standby), (mp_obj_t)&pyb_standby_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_main), (mp_obj_t)&pyb_main_obj },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_repl_uart), (mp_obj_t)&pyb_repl_uart_obj },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_millis), (mp_obj_t)&pyb_millis_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_elapsed_millis), (mp_obj_t)&pyb_elapsed_millis_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_micros), (mp_obj_t)&pyb_micros_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_elapsed_micros), (mp_obj_t)&pyb_elapsed_micros_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_delay), (mp_obj_t)&pyb_delay_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_udelay), (mp_obj_t)&pyb_udelay_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&pyb_sync_obj },
|
||||
|
||||
//{ MP_OBJ_NEW_QSTR(MP_QSTR_Timer), (mp_obj_t)&pyb_timer_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdisk), (mp_obj_t)&pyb_mkdisk_obj },
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rng), (mp_obj_t)&pyb_rng_get_obj },
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_ENABLE_RTC
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_RTC), (mp_obj_t)&pyb_rtc_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_RTC), (mp_obj_t)&pyb_rtc_obj },
|
||||
#endif
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ExtInt), (mp_obj_t)&extint_type },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ADC), (mp_obj_t)&pyb_adc_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&pyb_i2c_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SPI), (mp_obj_t)&pyb_spi_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_UART), (mp_obj_t)&pyb_uart_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WDT), (mp_obj_t)&pyb_wdt_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_Sleep), (mp_obj_t)&pyb_sleep_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_HeartBeat), (mp_obj_t)&pyb_heartbeat_obj },
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SD), (mp_obj_t)&pyb_sd_type },
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_module_globals, pyb_module_globals_table);
|
||||
|
||||
@@ -29,12 +29,10 @@
|
||||
#include <string.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "objtuple.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
#include "sflash_diskio.h"
|
||||
@@ -284,11 +282,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat);
|
||||
|
||||
/// \function sync()
|
||||
/// Sync all filesystems.
|
||||
STATIC mp_obj_t os_sync(void) {
|
||||
mp_obj_t os_sync(void) {
|
||||
sflash_disk_flush();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync);
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync);
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
/// \function urandom(n)
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
void stdout_tx_str(const char *str);
|
||||
void stdout_tx_strn(const char *str, mp_uint_t len);
|
||||
void stdout_tx_strn_cooked(const char *str, mp_uint_t len);
|
||||
int stdin_rx_chr(void);
|
||||
#ifndef MODUTIME_H_
|
||||
#define MODUTIME_H_
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(os_sync_obj);
|
||||
|
||||
#endif // MODUTIME_H_
|
||||
@@ -30,18 +30,11 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "simplelink.h"
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpstate.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "objtuple.h"
|
||||
#include "objlist.h"
|
||||
#include "runtime.h"
|
||||
#include "py/runtime.h"
|
||||
#include "modnetwork.h"
|
||||
#include "mpexception.h"
|
||||
#include "mpstate.h"
|
||||
|
||||
/******************************************************************************/
|
||||
// socket class
|
||||
|
||||
@@ -28,12 +28,10 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "modutime.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MODUOS_H_
|
||||
#define MODUOS_H_
|
||||
|
||||
typedef struct {
|
||||
uint16_t tm_year; // i.e. 2014
|
||||
uint8_t tm_mon; // 1..12
|
||||
@@ -41,3 +44,5 @@ extern mp_uint_t mod_time_seconds_since_2000(mp_uint_t year, mp_uint_t month, mp
|
||||
mp_uint_t hour, mp_uint_t minute, mp_uint_t second);
|
||||
|
||||
extern void mod_time_seconds_since_2000_to_struct_time(mp_uint_t t, mod_struct_time *tm);
|
||||
|
||||
#endif // MODUOS_H_
|
||||
|
||||
@@ -29,30 +29,20 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "simplelink.h"
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "misc.h"
|
||||
#include "nlr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "objtuple.h"
|
||||
#include "objlist.h"
|
||||
#include "runtime.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "modnetwork.h"
|
||||
#include "modwlan.h"
|
||||
#include "pybioctl.h"
|
||||
#include "pybuart.h"
|
||||
#include "pybstdio.h"
|
||||
#include "osi.h"
|
||||
#include "debug.h"
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
#include "serverstask.h"
|
||||
#include "mpexception.h"
|
||||
|
||||
#ifdef USE_FREERTOS
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
#endif
|
||||
#include "mpexception.h"
|
||||
#include "mpcallback.h"
|
||||
#include "pybsleep.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
@@ -88,18 +78,21 @@ typedef enum{
|
||||
}e_StatusBits;
|
||||
|
||||
typedef struct _wlan_obj_t {
|
||||
mp_obj_base_t base;
|
||||
SlWlanMode_t mode;
|
||||
uint32_t status;
|
||||
uint8_t macAddr[SL_MAC_ADDR_LEN];
|
||||
uint8_t ssid_name[33];
|
||||
uint8_t bssid[6];
|
||||
bool servers_enabled;
|
||||
mp_obj_base_t base;
|
||||
SlWlanMode_t mode;
|
||||
uint32_t status;
|
||||
|
||||
// IPVv4 data
|
||||
uint32_t ip;
|
||||
uint32_t gateway;
|
||||
uint32_t dns;
|
||||
uint32_t ip;
|
||||
uint32_t gateway;
|
||||
uint32_t dns;
|
||||
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
bool servers_enabled;
|
||||
#endif
|
||||
uint8_t security;
|
||||
uint8_t mac[SL_MAC_ADDR_LEN];
|
||||
uint8_t ssid[33];
|
||||
uint8_t bssid[6];
|
||||
|
||||
} wlan_obj_t;
|
||||
|
||||
@@ -127,13 +120,16 @@ typedef struct _wlan_obj_t {
|
||||
|
||||
#define MODWLAN_TIMEOUT_MS 5000
|
||||
#define MODWLAN_MAX_NETWORKS 20
|
||||
#define MODWLAN_SCAN_PERIOD_S 300 // 5 minutes
|
||||
#define MODWLAN_WAIT_FOR_SCAN_MS 1050
|
||||
|
||||
#define ASSERT_ON_ERROR( x ) ASSERT((x) >= 0 )
|
||||
|
||||
#define IPV4_ADDR_STR_LEN_MAX (16)
|
||||
#define SL_STOP_TIMEOUT 500
|
||||
|
||||
#define WLAN_MAX_RX_SIZE 16000
|
||||
#define WLAN_MAX_TX_SIZE 1476
|
||||
|
||||
|
||||
#define MAKE_SOCKADDR(addr, ip, port) sockaddr addr; \
|
||||
addr.sa_family = AF_INET; \
|
||||
@@ -151,14 +147,29 @@ typedef struct _wlan_obj_t {
|
||||
ip[3] = addr.sa_data[5];
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC DATA
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC wlan_obj_t wlan_obj;
|
||||
STATIC wlan_obj_t wlan_obj = {
|
||||
.mode = -1,
|
||||
.status = 0,
|
||||
.ip = 0,
|
||||
.gateway = 0,
|
||||
.dns = 0,
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
.servers_enabled = false,
|
||||
#endif
|
||||
.security = SL_SEC_TYPE_OPEN,
|
||||
.ssid = {0},
|
||||
.bssid = {0},
|
||||
.mac = {0},
|
||||
};
|
||||
|
||||
STATIC const mp_cb_methods_t wlan_cb_methods;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE EXPORTED DATA
|
||||
DECLARE PUBLIC DATA
|
||||
******************************************************************************/
|
||||
SemaphoreHandle_t xWlanSemaphore = NULL;
|
||||
OsiLockObj_t wlan_LockObj;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
@@ -168,7 +179,8 @@ STATIC void wlan_reenable (SlWlanMode_t mode);
|
||||
STATIC void wlan_get_sl_mac (void);
|
||||
STATIC modwlan_Status_t wlan_do_connect (const char* ssid, uint32_t ssid_len, const char* bssid, uint8_t sec,
|
||||
const char* key, uint32_t key_len);
|
||||
|
||||
STATIC void wlan_lpds_callback_enable (mp_obj_t self_in);
|
||||
STATIC void wlan_lpds_callback_disable (mp_obj_t self_in);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
@@ -179,9 +191,8 @@ STATIC modwlan_Status_t wlan_do_connect (const char* ssid, uint32_t ssid_len, co
|
||||
//! \return None
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent)
|
||||
{
|
||||
if(!pWlanEvent) {
|
||||
void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent) {
|
||||
if (!pWlanEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -190,48 +201,37 @@ void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent)
|
||||
case SL_WLAN_CONNECT_EVENT:
|
||||
{
|
||||
SET_STATUS_BIT(wlan_obj.status, STATUS_BIT_CONNECTION);
|
||||
//
|
||||
// Information about the connected AP (like name, MAC etc) will be
|
||||
// available in 'slWlanConnectAsyncResponse_t'-Applications
|
||||
// can use it if required
|
||||
//
|
||||
|
||||
slWlanConnectAsyncResponse_t *pEventData = &pWlanEvent->EventData.STAandP2PModeWlanConnected;
|
||||
|
||||
// Copy new connection SSID and BSSID to global parameters
|
||||
memcpy(wlan_obj.ssid_name, pEventData->ssid_name, pEventData->ssid_len);
|
||||
// copy the new connection data
|
||||
memcpy(wlan_obj.ssid, pEventData->ssid_name, pEventData->ssid_len);
|
||||
memcpy(wlan_obj.bssid, pEventData->bssid, SL_BSSID_LENGTH);
|
||||
}
|
||||
break;
|
||||
case SL_WLAN_DISCONNECT_EVENT:
|
||||
{
|
||||
slWlanConnectAsyncResponse_t* pEventData = NULL;
|
||||
|
||||
CLR_STATUS_BIT(wlan_obj.status, STATUS_BIT_CONNECTION);
|
||||
CLR_STATUS_BIT(wlan_obj.status, STATUS_BIT_IP_ACQUIRED);
|
||||
|
||||
pEventData = &pWlanEvent->EventData.STAandP2PModeDisconnected;
|
||||
|
||||
// If the user has initiated the 'Disconnect' request,
|
||||
//'reason_code' is SL_USER_INITIATED_DISCONNECTION
|
||||
if (SL_USER_INITIATED_DISCONNECTION == pEventData->reason_code) {
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
memset(wlan_obj.ssid_name, 0, sizeof(wlan_obj.ssid_name));
|
||||
memset(wlan_obj.ssid, 0, sizeof(wlan_obj.ssid));
|
||||
memset(wlan_obj.bssid, 0, sizeof(wlan_obj.bssid));
|
||||
}
|
||||
break;
|
||||
case SL_WLAN_STA_CONNECTED_EVENT:
|
||||
// TODO
|
||||
break;
|
||||
case SL_WLAN_STA_DISCONNECTED_EVENT:
|
||||
// TODO
|
||||
break;
|
||||
case SL_WLAN_P2P_DEV_FOUND_EVENT:
|
||||
// TODO
|
||||
break;
|
||||
case SL_WLAN_P2P_NEG_REQ_RECEIVED_EVENT:
|
||||
// TODO
|
||||
break;
|
||||
case SL_WLAN_CONNECTION_FAILED_EVENT:
|
||||
// TODO
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -248,8 +248,7 @@ void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent)
|
||||
//! \return None
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent)
|
||||
{
|
||||
void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent) {
|
||||
if(!pNetAppEvent) {
|
||||
return;
|
||||
}
|
||||
@@ -265,7 +264,7 @@ void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent)
|
||||
// Ip Acquired Event Data
|
||||
pEventData = &pNetAppEvent->EventData.ipAcquiredV4;
|
||||
|
||||
// Get the IP addresses
|
||||
// Get ip, gateway and dns
|
||||
wlan_obj.gateway = ntohl(pEventData->gateway);
|
||||
wlan_obj.ip = ntohl(pEventData->ip);
|
||||
wlan_obj.dns = ntohl(pEventData->dns);
|
||||
@@ -294,8 +293,7 @@ void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent)
|
||||
//! \return None
|
||||
//!
|
||||
//****************************************************************************
|
||||
void SimpleLinkHttpServerCallback(SlHttpServerEvent_t *pHttpEvent, SlHttpServerResponse_t *pHttpResponse)
|
||||
{
|
||||
void SimpleLinkHttpServerCallback(SlHttpServerEvent_t *pHttpEvent, SlHttpServerResponse_t *pHttpResponse) {
|
||||
if (!pHttpEvent) {
|
||||
return;
|
||||
}
|
||||
@@ -319,8 +317,7 @@ void SimpleLinkHttpServerCallback(SlHttpServerEvent_t *pHttpEvent, SlHttpServerR
|
||||
//! \return None
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent)
|
||||
{
|
||||
void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent) {
|
||||
if (!pDevEvent) {
|
||||
return;
|
||||
}
|
||||
@@ -338,17 +335,34 @@ void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent)
|
||||
//! \return None
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void SimpleLinkSockEventHandler(SlSockEvent_t *pSock)
|
||||
{
|
||||
void SimpleLinkSockEventHandler(SlSockEvent_t *pSock) {
|
||||
if (!pSock) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch( pSock->Event ) {
|
||||
case SL_SOCKET_TX_FAILED_EVENT:
|
||||
switch( pSock->socketAsyncEvent.SockTxFailData.status) {
|
||||
case SL_ECLOSE:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SL_SOCKET_ASYNC_EVENT:
|
||||
switch(pSock->socketAsyncEvent.SockAsyncData.type) {
|
||||
case SSL_ACCEPT:
|
||||
break;
|
||||
case RX_FRAGMENTATION_TOO_BIG:
|
||||
break;
|
||||
case OTHER_SIDE_CLOSE_SSL_DATA_NOT_ENCRYPTED:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,46 +371,36 @@ void SimpleLinkSockEventHandler(SlSockEvent_t *pSock)
|
||||
//*****************************************************************************
|
||||
|
||||
void wlan_init0 (void) {
|
||||
// Set the mode to an invalid one
|
||||
wlan_obj.mode = -1;
|
||||
wlan_obj.base.type = NULL;
|
||||
memset (wlan_obj.macAddr, 0, SL_MAC_ADDR_LEN);
|
||||
#ifdef USE_FREERTOS
|
||||
if (NULL == xWlanSemaphore) {
|
||||
xWlanSemaphore = xSemaphoreCreateBinary();
|
||||
// create the wlan lock
|
||||
ASSERT(OSI_OK == sl_LockObjCreate(&wlan_LockObj, "WlanLock"));
|
||||
}
|
||||
|
||||
void wlan_first_start (void) {
|
||||
// clear wlan data after checking any of the status flags
|
||||
wlan_initialize_data();
|
||||
|
||||
if (wlan_obj.mode < 0) {
|
||||
wlan_obj.mode = sl_Start(0, 0, 0);
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
}
|
||||
#endif
|
||||
wlan_initialize_data ();
|
||||
|
||||
// get the mac address
|
||||
wlan_get_sl_mac();
|
||||
}
|
||||
|
||||
modwlan_Status_t wlan_sl_enable (SlWlanMode_t mode, const char *ssid, uint8_t ssid_len, uint8_t sec,
|
||||
const char *key, uint8_t key_len, uint8_t channel) {
|
||||
|
||||
if (mode == ROLE_STA || mode == ROLE_AP || mode == ROLE_P2P) {
|
||||
if (wlan_obj.mode < 0) {
|
||||
wlan_obj.mode = sl_Start(0, 0, 0);
|
||||
#ifdef USE_FREERTOS
|
||||
xSemaphoreGive (xWlanSemaphore);
|
||||
#endif
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
// Stop all other processes using the wlan engine
|
||||
if ((wlan_obj.servers_enabled = servers_are_enabled())) {
|
||||
servers_stop();
|
||||
}
|
||||
#endif
|
||||
|
||||
// get the mac address
|
||||
wlan_get_sl_mac();
|
||||
|
||||
// stop the device if it's not in station mode
|
||||
if (wlan_obj.mode != ROLE_STA) {
|
||||
if (ROLE_AP == wlan_obj.mode) {
|
||||
// if the device is in AP mode, we need to wait for this event
|
||||
// before doing anything
|
||||
while (!IS_IP_ACQUIRED(wlan_obj.status)) {
|
||||
HAL_Delay (5);
|
||||
}
|
||||
}
|
||||
// switch to STA mode
|
||||
ASSERT_ON_ERROR(sl_WlanSetMode(ROLE_STA));
|
||||
// stop and start again
|
||||
wlan_reenable(ROLE_STA);
|
||||
}
|
||||
// do a basic start fisrt
|
||||
wlan_first_start();
|
||||
|
||||
// Device in station-mode. Disconnect previous connection if any
|
||||
// The function returns 0 if 'Disconnected done', negative number if already
|
||||
@@ -404,16 +408,13 @@ modwlan_Status_t wlan_sl_enable (SlWlanMode_t mode, const char *ssid, uint8_t ss
|
||||
// other return-codes
|
||||
if (0 == sl_WlanDisconnect()) {
|
||||
while (IS_CONNECTED (wlan_obj.status)) {
|
||||
#ifndef SL_PLATFORM_MULTI_THREADED
|
||||
_SlTaskEntry();
|
||||
#endif
|
||||
HAL_Delay (5);
|
||||
}
|
||||
}
|
||||
|
||||
// clear wlan data after checking any of the status flags
|
||||
wlan_initialize_data ();
|
||||
|
||||
// Set connection policy to Auto + SmartConfig (Device's default connection policy)
|
||||
ASSERT_ON_ERROR(sl_WlanPolicySet(SL_POLICY_CONNECTION, SL_CONNECTION_POLICY(1, 0, 0, 0, 1), NULL, 0));
|
||||
|
||||
// Remove all profiles
|
||||
ASSERT_ON_ERROR(sl_WlanProfileDel(0xFF));
|
||||
|
||||
@@ -427,6 +428,9 @@ modwlan_Status_t wlan_sl_enable (SlWlanMode_t mode, const char *ssid, uint8_t ss
|
||||
// Unregister mDNS services
|
||||
ASSERT_ON_ERROR(sl_NetAppMDNSUnRegisterService(0, 0));
|
||||
|
||||
// Stop the internal HTTP server
|
||||
sl_NetAppStop(SL_NET_APP_HTTP_SERVER_ID);
|
||||
|
||||
// Remove all 64 filters (8 * 8)
|
||||
_WlanRxFilterOperationCommandBuff_t RxFilterIdMask;
|
||||
memset ((void *)&RxFilterIdMask, 0 ,sizeof(RxFilterIdMask));
|
||||
@@ -437,15 +441,13 @@ modwlan_Status_t wlan_sl_enable (SlWlanMode_t mode, const char *ssid, uint8_t ss
|
||||
// Number between 0-15, as dB offset from max power - 0 will set max power
|
||||
uint8_t ucPower = 0;
|
||||
if (mode == ROLE_AP) {
|
||||
// Disable the scanning
|
||||
ASSERT_ON_ERROR(sl_WlanPolicySet(SL_POLICY_SCAN, MODWLAN_SL_SCAN_DISABLE, NULL, 0));
|
||||
|
||||
// Switch to AP mode
|
||||
ASSERT_ON_ERROR(sl_WlanSetMode(mode));
|
||||
ASSERT (ssid != NULL && key != NULL);
|
||||
ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_AP_TX_POWER, sizeof(ucPower),
|
||||
(unsigned char *)&ucPower));
|
||||
ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SSID, ssid_len, (unsigned char *)ssid));
|
||||
memcpy(wlan_obj.ssid, (unsigned char *)ssid, ssid_len);
|
||||
ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SECURITY_TYPE, sizeof(uint8_t), &sec));
|
||||
ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_PASSWORD, key_len, (unsigned char *)key));
|
||||
_u8* country = (_u8*)"EU";
|
||||
@@ -475,44 +477,62 @@ modwlan_Status_t wlan_sl_enable (SlWlanMode_t mode, const char *ssid, uint8_t ss
|
||||
|
||||
// Stop and start again
|
||||
wlan_reenable(mode);
|
||||
// save the security type
|
||||
wlan_obj.security = sec;
|
||||
}
|
||||
// STA and P2P modes
|
||||
else {
|
||||
ASSERT_ON_ERROR(sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID, WLAN_GENERAL_PARAM_OPT_STA_TX_POWER,
|
||||
sizeof(ucPower), (unsigned char *)&ucPower));
|
||||
// Enable scanning every 60 seconds
|
||||
uint32_t scanSeconds = 60;
|
||||
ASSERT_ON_ERROR(sl_WlanPolicySet(SL_POLICY_SCAN , MODWLAN_SL_SCAN_ENABLE, (_u8 *)&scanSeconds, sizeof(scanSeconds)));
|
||||
|
||||
if (mode == ROLE_P2P) {
|
||||
// Switch to P2P mode
|
||||
ASSERT_ON_ERROR(sl_WlanSetMode(mode));
|
||||
// Stop and start again
|
||||
wlan_reenable(mode);
|
||||
}
|
||||
ASSERT_ON_ERROR(sl_WlanSetMode(mode));
|
||||
// stop and start again
|
||||
wlan_reenable(mode);
|
||||
// set connection policy to Auto + SmartConfig (Device's default connection policy)
|
||||
ASSERT_ON_ERROR(sl_WlanPolicySet(SL_POLICY_CONNECTION, SL_CONNECTION_POLICY(1, 0, 0, 0, 1), NULL, 0));
|
||||
}
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
// Start the servers again
|
||||
if (wlan_obj.servers_enabled) {
|
||||
servers_start();
|
||||
}
|
||||
#endif
|
||||
return MODWLAN_OK;
|
||||
}
|
||||
return MODWLAN_ERROR_INVALID_PARAMS;
|
||||
}
|
||||
|
||||
void wlan_sl_disable (void) {
|
||||
if (wlan_obj.mode >= 0) {
|
||||
#ifdef USE_FREERTOS
|
||||
xSemaphoreTake (xWlanSemaphore, portMAX_DELAY);
|
||||
#endif
|
||||
wlan_obj.mode = -1;
|
||||
ASSERT_ON_ERROR (sl_Stop(SL_STOP_TIMEOUT));
|
||||
}
|
||||
void wlan_update(void) {
|
||||
#ifndef SL_PLATFORM_MULTI_THREADED
|
||||
_SlTaskEntry();
|
||||
#endif
|
||||
}
|
||||
|
||||
SlWlanMode_t wlan_get_mode (void) {
|
||||
return wlan_obj.mode;
|
||||
void wlan_stop (uint32_t timeout) {
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
// Stop all other processes using the wlan engine
|
||||
if ((wlan_obj.servers_enabled = servers_are_enabled())) {
|
||||
servers_stop();
|
||||
}
|
||||
#endif
|
||||
sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
|
||||
sl_Stop(timeout);
|
||||
wlan_obj.mode = -1;
|
||||
}
|
||||
|
||||
void wlan_start (void) {
|
||||
wlan_obj.mode = sl_Start(0, 0, 0);
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
// start the servers if they were enabled before
|
||||
if (wlan_obj.servers_enabled) {
|
||||
servers_start();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void wlan_get_mac (uint8_t *macAddress) {
|
||||
if (macAddress) {
|
||||
memcpy (macAddress, wlan_obj.macAddr, SL_MAC_ADDR_LEN);
|
||||
memcpy (macAddress, wlan_obj.mac, SL_MAC_ADDR_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,17 +542,6 @@ void wlan_get_ip (uint32_t *ip) {
|
||||
}
|
||||
}
|
||||
|
||||
void wlan_set_pm_policy (uint8_t policy) {
|
||||
ASSERT_ON_ERROR(sl_WlanPolicySet(SL_POLICY_PM, policy, NULL, 0));
|
||||
}
|
||||
|
||||
void wlan_servers_stop (void) {
|
||||
servers_disable();
|
||||
do {
|
||||
HAL_Delay (2);
|
||||
} while (servers_are_enabled());
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// DEFINE STATIC FUNCTIONS
|
||||
//*****************************************************************************
|
||||
@@ -542,53 +551,48 @@ STATIC void wlan_initialize_data (void) {
|
||||
wlan_obj.dns = 0;
|
||||
wlan_obj.gateway = 0;
|
||||
wlan_obj.ip = 0;
|
||||
memset(wlan_obj.ssid_name, 0, sizeof(wlan_obj.ssid_name));
|
||||
wlan_obj.security = SL_SEC_TYPE_OPEN;
|
||||
memset(wlan_obj.ssid, 0, sizeof(wlan_obj.ssid));
|
||||
memset(wlan_obj.bssid, 0, sizeof(wlan_obj.bssid));
|
||||
}
|
||||
|
||||
STATIC void wlan_reenable (SlWlanMode_t mode) {
|
||||
// Stop and start again
|
||||
wlan_obj.mode = -1;
|
||||
#ifdef USE_FREERTOS
|
||||
xSemaphoreTake (xWlanSemaphore, portMAX_DELAY);
|
||||
#endif
|
||||
ASSERT_ON_ERROR(sl_Stop(SL_STOP_TIMEOUT));
|
||||
// stop and start again
|
||||
sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
|
||||
sl_Stop(SL_STOP_TIMEOUT);
|
||||
wlan_obj.mode = sl_Start(0, 0, 0);
|
||||
#ifdef USE_FREERTOS
|
||||
xSemaphoreGive (xWlanSemaphore);
|
||||
#endif
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
ASSERT (wlan_obj.mode == mode);
|
||||
}
|
||||
|
||||
STATIC modwlan_Status_t wlan_do_connect (const char* ssid, uint32_t ssid_len, const char* bssid, uint8_t sec, const char* key, uint32_t key_len)
|
||||
{
|
||||
STATIC modwlan_Status_t wlan_do_connect (const char* ssid, uint32_t ssid_len, const char* bssid, uint8_t sec,
|
||||
const char* key, uint32_t key_len) {
|
||||
SlSecParams_t secParams;
|
||||
|
||||
secParams.Key = (_i8*)key;
|
||||
secParams.KeyLen = ((key != NULL) ? key_len : 0);
|
||||
secParams.Type = sec;
|
||||
|
||||
if (0 == sl_WlanConnect((_i8*)ssid, ssid_len, (_u8*)bssid, &secParams, NULL)) {
|
||||
|
||||
// Wait for WLAN Event
|
||||
// Wait for the WLAN Event
|
||||
uint32_t waitForConnectionMs = 0;
|
||||
while (!IS_CONNECTED(wlan_obj.status)) {
|
||||
#ifndef SL_PLATFORM_MULTI_THREADED
|
||||
_SlTaskEntry();
|
||||
#endif
|
||||
HAL_Delay (5);
|
||||
if (++waitForConnectionMs >= MODWLAN_TIMEOUT_MS) {
|
||||
return MODWLAN_ERROR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
return MODWLAN_OK;
|
||||
}
|
||||
|
||||
return MODWLAN_ERROR_INVALID_PARAMS;
|
||||
}
|
||||
|
||||
STATIC void wlan_get_sl_mac (void) {
|
||||
// Get the MAC address
|
||||
uint8_t macAddrLen = SL_MAC_ADDR_LEN;
|
||||
sl_NetCfgGet(SL_MAC_ADDRESS_GET,NULL, &macAddrLen, wlan_obj.macAddr);
|
||||
sl_NetCfgGet(SL_MAC_ADDRESS_GET, NULL, &macAddrLen, wlan_obj.mac);
|
||||
}
|
||||
|
||||
/// \method init(mode, ssid=myWlan, security=wlan.WPA_WPA2, key=myWlanKey)
|
||||
@@ -622,7 +626,7 @@ STATIC mp_obj_t wlan_init_helper(mp_uint_t n_args, const mp_obj_t *pos_args, mp_
|
||||
const char *key = mp_obj_str_get_data(args[3].u_obj, &key_len);
|
||||
|
||||
if (key_len < 8) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_value_invalid_arguments));
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
// Force the channel to be between 1-11
|
||||
@@ -635,6 +639,14 @@ STATIC mp_obj_t wlan_init_helper(mp_uint_t n_args, const mp_obj_t *pos_args, mp_
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
STATIC void wlan_lpds_callback_enable (mp_obj_t self_in) {
|
||||
mp_obj_t _callback = mpcallback_find(self_in);
|
||||
pybsleep_set_wlan_lpds_callback (_callback);
|
||||
}
|
||||
|
||||
STATIC void wlan_lpds_callback_disable (mp_obj_t self_in) {
|
||||
pybsleep_set_wlan_lpds_callback (NULL);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings; WLAN class
|
||||
@@ -651,11 +663,6 @@ STATIC mp_obj_t wlan_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_k
|
||||
if (n_args > 0) {
|
||||
// Get the mode
|
||||
SlWlanMode_t mode = mp_obj_get_int(args[0]);
|
||||
|
||||
// Stop all other processes using the wlan engine
|
||||
if ( (wlan_obj.servers_enabled = servers_are_enabled()) ) {
|
||||
wlan_servers_stop();
|
||||
}
|
||||
if (mode == ROLE_AP) {
|
||||
// start the peripheral
|
||||
mp_map_t kw_args;
|
||||
@@ -671,11 +678,6 @@ STATIC mp_obj_t wlan_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_k
|
||||
else {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments));
|
||||
}
|
||||
|
||||
// Start the servers again
|
||||
if (wlan_obj.servers_enabled) {
|
||||
servers_enable ();
|
||||
}
|
||||
} else if (wlan_obj.mode < 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments));
|
||||
}
|
||||
@@ -689,82 +691,60 @@ STATIC mp_obj_t wlan_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_k
|
||||
|
||||
STATIC void wlan_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
wlan_obj_t *self = self_in;
|
||||
print(env, "wlan(mode=%u, status=%u", self->mode, self->status);
|
||||
print(env, ", mac=%02x:%02x:%02x:%02x:%02x:%02x", self->macAddr[0], self->macAddr[1], self->macAddr[2],
|
||||
self->macAddr[3], self->macAddr[4], self->macAddr[5]);
|
||||
print(env, "<WLAN, mode=%u", self->mode);
|
||||
|
||||
// Only print the ssid if in station or ap mode
|
||||
if (self->mode == ROLE_STA || self->mode == ROLE_AP) {
|
||||
print(env, ", ssid=%s", self->ssid_name);
|
||||
|
||||
// Only print the bssid if in station mode
|
||||
if (self->mode == ROLE_STA) {
|
||||
print(env, ", bssid=%02x:%02x:%02x:%02x:%02x:%02x", self->bssid[0], self->bssid[1], self->bssid[2],
|
||||
self->bssid[3], self->bssid[4], self->bssid[5]);
|
||||
}
|
||||
|
||||
char ip_str[IPV4_ADDR_STR_LEN_MAX];
|
||||
uint8_t *ip = (uint8_t *)&self->ip;
|
||||
snprintf(ip_str, 16, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
|
||||
print(env, ", ip=%s", ip_str);
|
||||
ip = (uint8_t *)&self->gateway;
|
||||
snprintf(ip_str, 16, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
|
||||
print(env, ", gateway=%s", ip_str);
|
||||
ip = (uint8_t *)&self->dns;
|
||||
snprintf(ip_str, 16, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
|
||||
print(env, ", dns=%s)", ip_str);
|
||||
// only print the bssid if in station mode
|
||||
if (self->mode != ROLE_AP && GET_STATUS_BIT(self->status, STATUS_BIT_CONNECTION)) {
|
||||
print(env, ", connected to: ssid=%s, bssid=%02x:%02x:%02x:%02x:%02x:%02x", self->ssid,
|
||||
self->bssid[0], self->bssid[1], self->bssid[2], self->bssid[3], self->bssid[4], self->bssid[5]);
|
||||
}
|
||||
else {
|
||||
print(env, ")");
|
||||
print(env, ", ssid=%s", self->ssid);
|
||||
}
|
||||
print(env, ", security=%u>", self->security);
|
||||
}
|
||||
|
||||
/// \method mode()
|
||||
/// Get the wlan mode:
|
||||
///
|
||||
/// - Returns the current wlan mode. Possible values are:
|
||||
/// ROLE_STA, ROLE_AP and ROLE_P2P
|
||||
///
|
||||
STATIC mp_obj_t wlan_getmode(mp_obj_t self_in) {
|
||||
wlan_obj_t* self = self_in;
|
||||
return mp_obj_new_int(self->mode);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_getmode_obj, wlan_getmode);
|
||||
|
||||
STATIC mp_obj_t wlan_setpm(mp_obj_t self_in, mp_obj_t pm_mode) {
|
||||
mp_int_t mode = mp_obj_get_int(pm_mode);
|
||||
if (mode < SL_NORMAL_POLICY || mode > SL_LONG_SLEEP_INTERVAL_POLICY) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
wlan_set_pm_policy((uint8_t)mode);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(wlan_setpm_obj, wlan_setpm);
|
||||
|
||||
/// \method connect(ssid, key=None, *, security=OPEN, bssid=None)
|
||||
/// \method connect(ssid, security=OPEN, key=None, bssid=None)
|
||||
// if security is WPA/WPA2, the key must be a string
|
||||
/// if security is WEP, the key must be binary
|
||||
STATIC mp_obj_t wlan_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
STATIC const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_ssid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_security, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SL_SEC_TYPE_OPEN} },
|
||||
{ MP_QSTR_key, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_bssid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
};
|
||||
|
||||
// check for correct wlan mode
|
||||
if (wlan_obj.mode != ROLE_STA && wlan_obj.mode != ROLE_P2P) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
|
||||
// parse args
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
// get ssid
|
||||
// get the ssid
|
||||
mp_uint_t ssid_len;
|
||||
const char *ssid = mp_obj_str_get_data(args[0].u_obj, &ssid_len);
|
||||
|
||||
// get key and sec
|
||||
// get the security type
|
||||
mp_uint_t sec = args[1].u_int;
|
||||
|
||||
// get key and its len
|
||||
mp_uint_t key_len = 0;
|
||||
const char *key = NULL;
|
||||
mp_uint_t sec = SL_SEC_TYPE_OPEN;
|
||||
if (args[1].u_obj != mp_const_none) {
|
||||
key = mp_obj_str_get_data(args[1].u_obj, &key_len);
|
||||
sec = args[2].u_int;
|
||||
mp_buffer_info_t wepkey;
|
||||
if (args[2].u_obj != mp_const_none) {
|
||||
// wep key must be given as raw bytes
|
||||
if (sec == SL_SEC_TYPE_WEP) {
|
||||
mp_get_buffer_raise(args[2].u_obj, &wepkey, MP_BUFFER_READ);
|
||||
key = wepkey.buf;
|
||||
key_len = wepkey.len;
|
||||
}
|
||||
else {
|
||||
key = mp_obj_str_get_data(args[2].u_obj, &key_len);
|
||||
}
|
||||
}
|
||||
|
||||
// get bssid
|
||||
@@ -773,32 +753,34 @@ STATIC mp_obj_t wlan_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
|
||||
bssid = mp_obj_str_get_str(args[3].u_obj);
|
||||
}
|
||||
|
||||
if (wlan_obj.mode != ROLE_STA) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
else {
|
||||
if (GET_STATUS_BIT(wlan_obj.status, STATUS_BIT_CONNECTION)) {
|
||||
if (0 == sl_WlanDisconnect()) {
|
||||
while (IS_CONNECTED(wlan_obj.status)) {
|
||||
HAL_Delay (5);
|
||||
}
|
||||
if (GET_STATUS_BIT(wlan_obj.status, STATUS_BIT_CONNECTION)) {
|
||||
if (0 == sl_WlanDisconnect()) {
|
||||
while (IS_CONNECTED(wlan_obj.status)) {
|
||||
#ifndef SL_PLATFORM_MULTI_THREADED
|
||||
_SlTaskEntry();
|
||||
#endif
|
||||
HAL_Delay (5);
|
||||
}
|
||||
}
|
||||
// connect to the requested access point
|
||||
modwlan_Status_t status;
|
||||
status = wlan_do_connect (ssid, ssid_len, bssid, sec, key, key_len);
|
||||
if (status != MODWLAN_OK) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
}
|
||||
|
||||
// connect to the requested access point
|
||||
modwlan_Status_t status;
|
||||
status = wlan_do_connect (ssid, ssid_len, bssid, sec, key, key_len);
|
||||
if (status == MODWLAN_ERROR_TIMEOUT) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
else if (status == MODWLAN_ERROR_INVALID_PARAMS) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
wlan_obj.security = sec;
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_connect_obj, 1, wlan_connect);
|
||||
|
||||
/// \method wlan_disconnect()
|
||||
/// Closes the current WLAN connection
|
||||
///
|
||||
/// Close the current WLAN connection
|
||||
STATIC mp_obj_t wlan_disconnect(mp_obj_t self_in) {
|
||||
sl_WlanDisconnect();
|
||||
return mp_const_none;
|
||||
@@ -806,8 +788,7 @@ STATIC mp_obj_t wlan_disconnect(mp_obj_t self_in) {
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_disconnect_obj, wlan_disconnect);
|
||||
|
||||
/// \method is_connected()
|
||||
/// Returns true if connected to the AP and an IP address has been assigned. False otherwise.
|
||||
///
|
||||
/// Return true if connected to the AP and an IP address has been assigned. False otherwise.
|
||||
STATIC mp_obj_t wlan_isconnected(mp_obj_t self_in) {
|
||||
if (GET_STATUS_BIT(wlan_obj.status, STATUS_BIT_CONNECTION) &&
|
||||
GET_STATUS_BIT(wlan_obj.status, STATUS_BIT_IP_ACQUIRED)) {
|
||||
@@ -817,24 +798,86 @@ STATIC mp_obj_t wlan_isconnected(mp_obj_t self_in) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_isconnected_obj, wlan_isconnected);
|
||||
|
||||
/// \method getip()
|
||||
/// Get the IP
|
||||
///
|
||||
/// - Returns the acquired IP address
|
||||
///
|
||||
STATIC mp_obj_t wlan_getip(mp_obj_t self_in) {
|
||||
return mod_network_format_ipv4_addr ((uint8_t *)&wlan_obj.ip);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_getip_obj, wlan_getip);
|
||||
STATIC mp_obj_t wlan_ifconfig (mp_obj_t self_in) {
|
||||
unsigned char len = sizeof(SlNetCfgIpV4Args_t);
|
||||
unsigned char dhcpIsOn;
|
||||
SlNetCfgIpV4Args_t ipV4;
|
||||
|
||||
sl_NetCfgGet(SL_IPV4_STA_P2P_CL_GET_INFO, &dhcpIsOn, &len, (uint8_t *)&ipV4);
|
||||
// shift byte order
|
||||
ipV4.ipV4Mask = ntohl(ipV4.ipV4Mask);
|
||||
|
||||
mp_obj_t ifconfig = mp_obj_new_dict(0);
|
||||
mp_obj_dict_store (ifconfig, mp_obj_new_str("ip", strlen("ip"), false), mod_network_format_ipv4_addr((uint8_t *)&wlan_obj.ip));
|
||||
mp_obj_dict_store (ifconfig, mp_obj_new_str("subnet", strlen("subnet"), false), mod_network_format_ipv4_addr((uint8_t *)&ipV4.ipV4Mask));
|
||||
mp_obj_dict_store (ifconfig, mp_obj_new_str("gateway", strlen("gateway"), false), mod_network_format_ipv4_addr((uint8_t *)&wlan_obj.gateway));
|
||||
mp_obj_dict_store (ifconfig, mp_obj_new_str("dns", strlen("dns"), false), mod_network_format_ipv4_addr((uint8_t *)&wlan_obj.dns));
|
||||
char mac_str[18];
|
||||
mp_uint_t mac_len = snprintf(mac_str, sizeof(mac_str), "%02x:%02x:%02x:%02x:%02x:%02x", wlan_obj.mac[0], wlan_obj.mac[1], wlan_obj.mac[2],
|
||||
wlan_obj.mac[3], wlan_obj.mac[4], wlan_obj.mac[5]);
|
||||
mp_obj_dict_store (ifconfig, mp_obj_new_str("mac", strlen("mac"), false), mp_obj_new_str(mac_str, mac_len, false));
|
||||
char *mode_str;
|
||||
if (wlan_obj.mode == ROLE_STA) {
|
||||
mode_str = "station";
|
||||
}
|
||||
else if (wlan_obj.mode == ROLE_AP) {
|
||||
mode_str = "ap";
|
||||
}
|
||||
else {
|
||||
mode_str = "p2p";
|
||||
}
|
||||
mp_obj_dict_store (ifconfig, mp_obj_new_str("mode", strlen("mode"), false), mp_obj_new_str(mode_str, strlen(mode_str), false));
|
||||
mp_obj_dict_store (ifconfig, mp_obj_new_str("ssid", strlen("ssid"), false), mp_obj_new_str((const char *)wlan_obj.ssid, strlen((const char *)wlan_obj.ssid), false));
|
||||
|
||||
return ifconfig;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_ifconfig_obj, wlan_ifconfig);
|
||||
|
||||
STATIC mp_obj_t wlan_urn (uint n_args, const mp_obj_t *args) {
|
||||
char urn[MAX_DEVICE_URN_LEN];
|
||||
uint8_t len = MAX_DEVICE_URN_LEN;
|
||||
|
||||
// an URN is given, so set it
|
||||
if (n_args == 2) {
|
||||
const char *p = mp_obj_str_get_str(args[1]);
|
||||
uint8_t len = strlen(p);
|
||||
|
||||
// the call to sl_NetAppSet corrupts the input string URN=args[1], so we copy into a local buffer
|
||||
if (len > MAX_DEVICE_URN_LEN) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
strcpy(urn, p);
|
||||
|
||||
if (sl_NetAppSet(SL_NET_APP_DEVICE_CONFIG_ID, NETAPP_SET_GET_DEV_CONF_OPT_DEVICE_URN, len, (unsigned char *)urn) < 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// get the URN
|
||||
if (sl_NetAppGet(SL_NET_APP_DEVICE_CONFIG_ID, NETAPP_SET_GET_DEV_CONF_OPT_DEVICE_URN, &len, (uint8_t *)urn) < 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
return mp_obj_new_str(urn, (len - 1), false);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(wlan_urn_obj, 1, 2, wlan_urn);
|
||||
|
||||
/// \method wlan_netlist()
|
||||
/// Returns a list of tuples with all the acces points within range
|
||||
/// Return a list of tuples with all the acces points within range
|
||||
STATIC mp_obj_t wlan_scan(mp_obj_t self_in) {
|
||||
Sl_WlanNetworkEntry_t wlanEntry;
|
||||
uint8_t _index = 0;
|
||||
mp_obj_t nets = NULL;
|
||||
|
||||
// trigger a new newtork scanning
|
||||
uint32_t scanSeconds = MODWLAN_SCAN_PERIOD_S;
|
||||
ASSERT_ON_ERROR(sl_WlanPolicySet(SL_POLICY_SCAN , MODWLAN_SL_SCAN_ENABLE, (_u8 *)&scanSeconds, sizeof(scanSeconds)));
|
||||
|
||||
// wait for the scan to be completed
|
||||
HAL_Delay (MODWLAN_WAIT_FOR_SCAN_MS);
|
||||
|
||||
do {
|
||||
if (sl_WlanGetNetworkList(_index++, 1, &wlanEntry) <= 0) {
|
||||
break;
|
||||
@@ -863,43 +906,41 @@ STATIC mp_obj_t wlan_scan(mp_obj_t self_in) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_scan_obj, wlan_scan);
|
||||
|
||||
STATIC mp_obj_t wlan_serversstart(mp_obj_t self_in) {
|
||||
servers_enable();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_serversstart_obj, wlan_serversstart);
|
||||
/// \method callback(handler, pwrmode)
|
||||
/// Create a callback object associated with WLAN
|
||||
/// min num of arguments is 1 (pwrmode)
|
||||
STATIC mp_obj_t wlan_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
mp_arg_val_t args[mpcallback_INIT_NUM_ARGS];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mpcallback_INIT_NUM_ARGS, mpcallback_init_args, args);
|
||||
|
||||
STATIC mp_obj_t wlan_serversstop(mp_obj_t self_in) {
|
||||
wlan_servers_stop();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_serversstop_obj, wlan_serversstop);
|
||||
wlan_obj_t *self = pos_args[0];
|
||||
mp_obj_t _callback = mpcallback_find(self);
|
||||
// check if any parameters were passed
|
||||
if (kw_args->used > 0 || !_callback) {
|
||||
// check the power mode
|
||||
if (args[4].u_int != PYB_PWR_MODE_LPDS) {
|
||||
// throw an exception since WLAN only supports LPDS mode
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
STATIC mp_obj_t wlan_areserversenabled(mp_obj_t self_in) {
|
||||
return MP_BOOL(servers_are_enabled());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(wlan_areserversenabled_obj, wlan_areserversenabled);
|
||||
// create the callback
|
||||
_callback = mpcallback_new (self, args[1].u_obj, &wlan_cb_methods);
|
||||
|
||||
STATIC mp_obj_t wlan_serversuserpass(mp_obj_t self_in, mp_obj_t user, mp_obj_t pass) {
|
||||
const char *_user = mp_obj_str_get_str(user);
|
||||
const char *_pass = mp_obj_str_get_str(pass);
|
||||
servers_set_user_pass((char *)_user, (char *)_pass);
|
||||
return mp_const_none;
|
||||
// enable network wakeup
|
||||
pybsleep_set_wlan_lpds_callback (_callback);
|
||||
}
|
||||
return _callback;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(wlan_serversuserpass_obj, wlan_serversuserpass);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wlan_callback_obj, 1, wlan_callback);
|
||||
|
||||
STATIC const mp_map_elem_t wlan_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&wlan_connect_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_getmode), (mp_obj_t)&wlan_getmode_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_setpm), (mp_obj_t)&wlan_setpm_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_scan), (mp_obj_t)&wlan_scan_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_disconnect), (mp_obj_t)&wlan_disconnect_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_isconnected), (mp_obj_t)&wlan_isconnected_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_getip), (mp_obj_t)&wlan_getip_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_serversstart), (mp_obj_t)&wlan_serversstart_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_serversstop), (mp_obj_t)&wlan_serversstop_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_areserversenabled), (mp_obj_t)&wlan_areserversenabled_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_serversuserpass), (mp_obj_t)&wlan_serversuserpass_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ifconfig), (mp_obj_t)&wlan_ifconfig_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_urn), (mp_obj_t)&wlan_urn_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&wlan_callback_obj },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_OPEN), MP_OBJ_NEW_SMALL_INT(SL_SEC_TYPE_OPEN) },
|
||||
@@ -911,14 +952,14 @@ STATIC const mp_map_elem_t wlan_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_STA), MP_OBJ_NEW_SMALL_INT(ROLE_STA) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_AP), MP_OBJ_NEW_SMALL_INT(ROLE_AP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_P2P), MP_OBJ_NEW_SMALL_INT(ROLE_P2P) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_NORMAL_PM), MP_OBJ_NEW_SMALL_INT(SL_NORMAL_POLICY) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_LOW_LATENCY_PM), MP_OBJ_NEW_SMALL_INT(SL_LOW_LATENCY_POLICY) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_LOW_POWER_PM), MP_OBJ_NEW_SMALL_INT(SL_LOW_POWER_POLICY) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ALWAYS_ON_PM), MP_OBJ_NEW_SMALL_INT(SL_ALWAYS_ON_POLICY) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_LONG_SLEEP_PM), MP_OBJ_NEW_SMALL_INT(SL_LONG_SLEEP_INTERVAL_POLICY) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(wlan_locals_dict, wlan_locals_dict_table);
|
||||
|
||||
STATIC const mp_cb_methods_t wlan_cb_methods = {
|
||||
.init = wlan_callback,
|
||||
.enable = wlan_lpds_callback_enable,
|
||||
.disable = wlan_lpds_callback_disable,
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings; WLAN socket
|
||||
|
||||
@@ -24,36 +24,31 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SIMPLELINKTASK_H_
|
||||
#define SIMPLELINKTASK_H_
|
||||
#ifndef MODWLAN_H_
|
||||
#define MODWLAN_H_
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define SIMPLELINK_SPAWN_TASK_PRIORITY 3
|
||||
#define SIMPLELINK_TASK_STACK_SIZE 2048
|
||||
#define SL_STOP_TIMEOUT 35
|
||||
#define SL_STOP_TIMEOUT_LONG 575
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
******************************************************************************/
|
||||
typedef enum
|
||||
{
|
||||
typedef enum {
|
||||
MODWLAN_OK = 0,
|
||||
MODWLAN_ERROR_INVALID_PARAMS = -1,
|
||||
MODWLAN_ERROR_TIMEOUT = -2,
|
||||
MODWLAN_ERROR_UNKNOWN = -3
|
||||
|
||||
MODWLAN_ERROR_UNKNOWN = -3,
|
||||
}modwlan_Status_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC DATA
|
||||
******************************************************************************/
|
||||
#ifdef USE_FREERTOS
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
extern SemaphoreHandle_t xWlanSemaphore;
|
||||
#endif
|
||||
extern _SlLockObj_t wlan_LockObj;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
@@ -61,11 +56,10 @@ extern SemaphoreHandle_t xWlanSemaphore;
|
||||
extern void wlan_init0 (void);
|
||||
extern modwlan_Status_t wlan_sl_enable (SlWlanMode_t mode, const char *ssid, uint8_t ssid_len, uint8_t sec,
|
||||
const char *key, uint8_t key_len, uint8_t channel);
|
||||
extern void wlan_sl_disable (void);
|
||||
extern SlWlanMode_t wlan_get_mode (void);
|
||||
extern void wlan_first_start (void);
|
||||
extern void wlan_stop (uint32_t timeout);
|
||||
extern void wlan_start (void);
|
||||
extern void wlan_get_mac (uint8_t *macAddress);
|
||||
extern void wlan_get_ip (uint32_t *ip);
|
||||
extern void wlan_set_pm_policy (uint8_t policy);
|
||||
extern void wlan_servers_stop (void);
|
||||
|
||||
#endif /* SIMPLELINKTASK_H_ */
|
||||
#endif /* MODWLAN_H_ */
|
||||
|
||||
212
cc3200/mods/pybadc.c
Normal file
212
cc3200/mods/pybadc.c
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/binary.h"
|
||||
#include "py/gc.h"
|
||||
#include "bufhelper.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_adc.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "rom_map.h"
|
||||
#include "interrupt.h"
|
||||
#include "pin.h"
|
||||
#include "gpio.h"
|
||||
#include "prcm.h"
|
||||
#include "adc.h"
|
||||
#include "pybadc.h"
|
||||
#include "pybpin.h"
|
||||
#include "pybsleep.h"
|
||||
#include "pins.h"
|
||||
#include "mpexception.h"
|
||||
|
||||
|
||||
/// \moduleref pyb
|
||||
/// \class ADC - analog to digital conversion: read analog values on a pin
|
||||
///
|
||||
/// Usage:
|
||||
///
|
||||
/// adc = pyb.ADC(channel) # create an adc object on the given channel (0 to 3)
|
||||
/// this automatically configures the pin associated to
|
||||
/// that analog channel.
|
||||
/// adc.read() # read channel value
|
||||
///
|
||||
/// The sample rate is fixed to 62.5KHz and the resolution to 12 bits.
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYB_ADC_NUM_CHANNELS 4
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
byte channel;
|
||||
byte num;
|
||||
} pyb_adc_obj_t;
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC void pybadc_init (pyb_adc_obj_t *self) {
|
||||
// enable the ADC channel
|
||||
MAP_ADCChannelEnable(ADC_BASE, self->channel);
|
||||
// enable and configure the timer
|
||||
MAP_ADCTimerConfig(ADC_BASE, (1 << 17) - 1);
|
||||
MAP_ADCTimerEnable(ADC_BASE);
|
||||
// enable the ADC peripheral
|
||||
MAP_ADCEnable(ADC_BASE);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC pyb_adc_obj_t pyb_adc_obj[PYB_ADC_NUM_CHANNELS];
|
||||
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings : adc object */
|
||||
|
||||
STATIC void adc_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_adc_obj_t *self = self_in;
|
||||
print(env, "<ADC, channel=%u>", self->num);
|
||||
}
|
||||
|
||||
/// \classmethod \constructor(channel)
|
||||
/// Create an ADC object associated with the given channel.
|
||||
/// This allows you to then read analog values on that pin.
|
||||
STATIC mp_obj_t adc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
// check number of arguments
|
||||
mp_arg_check_num(n_args, n_kw, 1, 1, false);
|
||||
|
||||
// the first argument is the channel number
|
||||
uint num = mp_obj_get_int(args[0]);
|
||||
const pin_obj_t *pin;
|
||||
uint channel;
|
||||
switch (num) {
|
||||
case 0:
|
||||
channel = ADC_CH_0;
|
||||
pin = &pin_GPIO2;
|
||||
break;
|
||||
case 1:
|
||||
channel = ADC_CH_1;
|
||||
pin = &pin_GPIO3;
|
||||
break;
|
||||
case 2:
|
||||
channel = ADC_CH_2;
|
||||
pin = &pin_GPIO4;
|
||||
break;
|
||||
case 3:
|
||||
channel = ADC_CH_3;
|
||||
pin = &pin_GPIO5;
|
||||
break;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
break;
|
||||
}
|
||||
|
||||
// disable the callback before re-configuring
|
||||
pyb_adc_obj_t *self = &pyb_adc_obj[channel];
|
||||
self->base.type = &pyb_adc_type;
|
||||
self->channel = channel;
|
||||
self->num = num;
|
||||
|
||||
// configure the pin in analog mode
|
||||
pin_config ((pin_obj_t *)pin, PIN_MODE_0, GPIO_DIR_MODE_IN, PYBPIN_ANALOG_TYPE, PIN_STRENGTH_2MA);
|
||||
|
||||
// initialize it
|
||||
pybadc_init (self);
|
||||
|
||||
// register it with the sleep module
|
||||
pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)pybadc_init);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/// \method read()
|
||||
/// Read the value on the analog pin and return it. The returned value
|
||||
/// will be between 0 and 4095.
|
||||
STATIC mp_obj_t adc_read(mp_obj_t self_in) {
|
||||
pyb_adc_obj_t *self = self_in;
|
||||
uint32_t sample;
|
||||
|
||||
// wait until a new value is available
|
||||
while (!MAP_ADCFIFOLvlGet(ADC_BASE, self->channel));
|
||||
// read the sample
|
||||
sample = MAP_ADCFIFORead(ADC_BASE, self->channel);
|
||||
// the 12 bit sampled value is stored in bits [13:2]
|
||||
return MP_OBJ_NEW_SMALL_INT((sample & 0x3FFF) >> 2);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_read_obj, adc_read);
|
||||
|
||||
/// \method enable()
|
||||
/// Enable the adc channel
|
||||
STATIC mp_obj_t adc_enable(mp_obj_t self_in) {
|
||||
pyb_adc_obj_t *self = self_in;
|
||||
|
||||
pybadc_init(self);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_enable_obj, adc_enable);
|
||||
|
||||
/// \method disable()
|
||||
/// Disable the adc channel
|
||||
STATIC mp_obj_t adc_disable(mp_obj_t self_in) {
|
||||
pyb_adc_obj_t *self = self_in;
|
||||
|
||||
MAP_ADCChannelDisable(ADC_BASE, self->channel);
|
||||
// unregister it with the sleep module
|
||||
pybsleep_remove ((const mp_obj_t)self);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_disable_obj, adc_disable);
|
||||
|
||||
STATIC const mp_map_elem_t adc_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&adc_read_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&adc_enable_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable), (mp_obj_t)&adc_disable_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(adc_locals_dict, adc_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t pyb_adc_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_ADC,
|
||||
.print = adc_print,
|
||||
.make_new = adc_make_new,
|
||||
.locals_dict = (mp_obj_t)&adc_locals_dict,
|
||||
};
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -24,9 +25,9 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
extern struct _pyb_uart_obj_t *pyb_stdio_uart;
|
||||
#ifndef PYBADC_H_
|
||||
#define PYBADC_H_
|
||||
|
||||
void stdout_tx_str(const char *str);
|
||||
void stdout_tx_strn(const char *str, mp_uint_t len);
|
||||
void stdout_tx_strn_cooked(const char *str, mp_uint_t len);
|
||||
int stdin_rx_chr(void);
|
||||
extern const mp_obj_type_t pyb_adc_type;
|
||||
|
||||
#endif /* PYBADC_H_ */
|
||||
@@ -1,357 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/pfenv.h"
|
||||
#include "py/objlist.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_gpio.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "rom_map.h"
|
||||
#include "pin.h"
|
||||
#include "gpio.h"
|
||||
#include "pybpin.h"
|
||||
#include "pybextint.h"
|
||||
#include "mpexception.h"
|
||||
#include "interrupt.h"
|
||||
#include "mpstate.h"
|
||||
#include "cc3200_asm.h"
|
||||
|
||||
/// \moduleref pyb
|
||||
/// \class ExtInt - configure I/O pins to interrupt on external events
|
||||
///
|
||||
/// There are a maximum of 25 gpio interrupt lines.
|
||||
///
|
||||
/// Example callback:
|
||||
///
|
||||
/// def callback(line):
|
||||
/// print(line.pin())
|
||||
///
|
||||
/// Note: ExtInt will automatically configure the gpio line as an input.
|
||||
///
|
||||
/// extint = pyb.ExtInt('GPIO10', pyb.ExtInt.IRQ_FALLING, pyb.GPIO.STD_PU, callback)
|
||||
///
|
||||
/// Now every time a falling edge is seen on the gpio pin, the callback will be
|
||||
/// called. Caution: mechanical pushbuttons have "bounce" and pushing or
|
||||
/// releasing a switch will often generate multiple edges.
|
||||
/// See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed
|
||||
/// explanation, along with various techniques for debouncing.
|
||||
///
|
||||
/// All pin objects go through the pin mapper to come up with one of the
|
||||
/// gpio pins.
|
||||
///
|
||||
/// extint = pyb.ExtInt(pin, mode, pull, callback)
|
||||
///
|
||||
/// There is also a C API, so that drivers which require EXTI interrupt lines
|
||||
/// can also use this code. See pybextint.h for the available functions.
|
||||
|
||||
STATIC void ExecuteIntCallback (extint_obj_t *self);
|
||||
STATIC void GPIOA0IntHandler (void);
|
||||
STATIC void GPIOA1IntHandler (void);
|
||||
STATIC void GPIOA2IntHandler (void);
|
||||
STATIC void GPIOA3IntHandler (void);
|
||||
STATIC void EXTI_Handler(uint port);
|
||||
|
||||
STATIC extint_obj_t* extint_add (uint pin_num, uint port, uint bit) {
|
||||
extint_obj_t *self = m_new_obj(extint_obj_t);
|
||||
|
||||
self->port = port;
|
||||
self->bit = bit;
|
||||
self->callback = NULL;
|
||||
self->pin_num = pin_num;
|
||||
// add it to the list
|
||||
mp_obj_list_append(&MP_STATE_PORT(pyb_extint_list), self);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
STATIC extint_obj_t* extint_find (uint port, uint8_t bit) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(pyb_extint_list).len; i++) {
|
||||
extint_obj_t *self = (extint_obj_t *)MP_STATE_PORT(pyb_extint_list).items[i];
|
||||
if (self->port == port && self->bit == bit) {
|
||||
return self;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// \method line()
|
||||
/// Return the pin number to which this external interrupt is mapped to.
|
||||
STATIC mp_obj_t extint_obj_pin(mp_obj_t self_in) {
|
||||
extint_obj_t *self = self_in;
|
||||
return MP_OBJ_NEW_SMALL_INT(self->pin_num);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(extint_obj_pin_obj, extint_obj_pin);
|
||||
|
||||
/// \method enable()
|
||||
/// Enable a disabled interrupt.
|
||||
STATIC mp_obj_t extint_obj_enable(mp_obj_t self_in) {
|
||||
extint_obj_t *self = self_in;
|
||||
extint_enable(self);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(extint_obj_enable_obj, extint_obj_enable);
|
||||
|
||||
/// \method disable()
|
||||
/// Disable the interrupt associated with the ExtInt object.
|
||||
/// This could be useful for debouncing.
|
||||
STATIC mp_obj_t extint_obj_disable(mp_obj_t self_in) {
|
||||
extint_obj_t *self = self_in;
|
||||
extint_disable(self);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(extint_obj_disable_obj, extint_obj_disable);
|
||||
|
||||
/// \method swint()
|
||||
/// Trigger the callback from software.
|
||||
STATIC mp_obj_t extint_obj_swint(mp_obj_t self_in) {
|
||||
extint_obj_t *self = self_in;
|
||||
extint_swint(self);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(extint_obj_swint_obj, extint_obj_swint);
|
||||
|
||||
/// \classmethod \constructor(pin, mode, pull, callback)
|
||||
/// Create an ExtInt object:
|
||||
///
|
||||
/// - `pin` is the pin on which to enable the interrupt (can be a pin object or any valid pin name).
|
||||
/// - `mode` can be one of:
|
||||
/// - `ExtInt.IRQ_RISING` - trigger on a rising edge;
|
||||
/// - `ExtInt.IRQ_FALLING` - trigger on a falling edge;
|
||||
/// - `ExtInt.IRQ_RISING_FALLING` - trigger on a rising or falling edge.
|
||||
/// - `pull` can be one of:
|
||||
/// - `pyb.Pin.PULL_NONE` - no pull up or down resistors;
|
||||
/// - `pyb.Pin.PULL_UP` - enable the pull-up resistor;
|
||||
/// - `pyb.Pin.PULL_DOWN` - enable the pull-down resistor.
|
||||
/// - `callback` is the function to call when the interrupt triggers. The
|
||||
/// callback function must accept exactly 1 argument, which is the line that
|
||||
/// triggered the interrupt.
|
||||
STATIC const mp_arg_t pyb_extint_make_new_args[] = {
|
||||
{ MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_pull, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_callback, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
};
|
||||
#define PYB_EXTINT_MAKE_NEW_NUM_ARGS MP_ARRAY_SIZE(pyb_extint_make_new_args)
|
||||
|
||||
STATIC mp_obj_t extint_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
// parse args
|
||||
mp_arg_val_t vals[PYB_EXTINT_MAKE_NEW_NUM_ARGS];
|
||||
mp_arg_parse_all_kw_array(n_args, n_kw, args, PYB_EXTINT_MAKE_NEW_NUM_ARGS, pyb_extint_make_new_args, vals);
|
||||
|
||||
extint_obj_t *self = extint_register(vals[0].u_obj, vals[1].u_int, vals[2].u_int, vals[3].u_obj);
|
||||
self->base.type = type_in;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
STATIC void extint_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
extint_obj_t *self = self_in;
|
||||
print(env, "<ExtInt pin=%u>", self->pin_num);
|
||||
}
|
||||
|
||||
STATIC const mp_map_elem_t extint_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_pin), (mp_obj_t)&extint_obj_pin_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&extint_obj_enable_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable), (mp_obj_t)&extint_obj_disable_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_swint), (mp_obj_t)&extint_obj_swint_obj },
|
||||
|
||||
// class constants
|
||||
/// \constant IRQ_RISING - interrupt on a rising edge
|
||||
/// \constant IRQ_FALLING - interrupt on a falling edge
|
||||
/// \constant IRQ_RISING_FALLING - interrupt on a rising or falling edge
|
||||
/// \constant IRQ_LOW_LEVEL - interrupt on a low level
|
||||
/// \constant IRQ_HIGH_LEVEL - interrupt on a high level
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_FALLING_EDGE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_RISING), MP_OBJ_NEW_SMALL_INT(GPIO_RISING_EDGE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_RISING_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_BOTH_EDGES) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_LOW_LEVEL), MP_OBJ_NEW_SMALL_INT(GPIO_LOW_LEVEL) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_HIGH_LEVEL), MP_OBJ_NEW_SMALL_INT(GPIO_HIGH_LEVEL) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(extint_locals_dict, extint_locals_dict_table);
|
||||
|
||||
STATIC void ExecuteIntCallback (extint_obj_t *self) {
|
||||
if (self->callback != mp_const_none) {
|
||||
// disable interrupts to avoid nesting
|
||||
uint primsk = disable_irq();
|
||||
// when executing code within a handler we must lock the GC to prevent
|
||||
// any memory allocations. We must also catch any exceptions.
|
||||
gc_lock();
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
mp_call_function_1(self->callback, self);
|
||||
nlr_pop();
|
||||
} else {
|
||||
// uncaught exception; disable the callback so it doesn't run again
|
||||
self->callback = mp_const_none;
|
||||
extint_disable(self);
|
||||
// printing an exception here will cause a stack overflow that ends up in a
|
||||
// hard fault so, is better to signal the uncaught (probably non-recoverable)
|
||||
// exception by blinkg the BLD
|
||||
// TODO: Blink the BLD
|
||||
}
|
||||
gc_unlock();
|
||||
enable_irq(primsk);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void GPIOA0IntHandler (void) {
|
||||
EXTI_Handler(GPIOA0_BASE);
|
||||
}
|
||||
|
||||
STATIC void GPIOA1IntHandler (void) {
|
||||
EXTI_Handler(GPIOA1_BASE);
|
||||
}
|
||||
|
||||
STATIC void GPIOA2IntHandler (void) {
|
||||
EXTI_Handler(GPIOA2_BASE);
|
||||
}
|
||||
|
||||
STATIC void GPIOA3IntHandler (void) {
|
||||
EXTI_Handler(GPIOA3_BASE);
|
||||
}
|
||||
|
||||
// common interrupt handler
|
||||
STATIC void EXTI_Handler(uint port) {
|
||||
extint_obj_t *self;
|
||||
uint32_t bit = MAP_GPIOIntStatus(port, true);
|
||||
|
||||
MAP_GPIOIntClear(port, bit);
|
||||
if (NULL != (self = extint_find(port, bit))) {
|
||||
ExecuteIntCallback(self);
|
||||
}
|
||||
}
|
||||
|
||||
const mp_obj_type_t extint_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_ExtInt,
|
||||
.print = extint_obj_print,
|
||||
.make_new = extint_make_new,
|
||||
.locals_dict = (mp_obj_t)&extint_locals_dict,
|
||||
};
|
||||
|
||||
void extint_init0(void) {
|
||||
mp_obj_list_init(&MP_STATE_PORT(pyb_extint_list), 0);
|
||||
}
|
||||
|
||||
extint_obj_t* extint_register(mp_obj_t pin_obj, uint32_t intmode, uint32_t pull, mp_obj_t callback) {
|
||||
const pin_obj_t *pin = NULL;
|
||||
extint_obj_t* self;
|
||||
void *handler;
|
||||
uint32_t intnum;
|
||||
|
||||
pin = pin_find(pin_obj);
|
||||
|
||||
if (intmode != GPIO_FALLING_EDGE &&
|
||||
intmode != GPIO_RISING_EDGE &&
|
||||
intmode != GPIO_BOTH_EDGES &&
|
||||
intmode != GPIO_LOW_LEVEL &&
|
||||
intmode != GPIO_HIGH_LEVEL) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
if (pull != PIN_TYPE_STD &&
|
||||
pull != PIN_TYPE_STD_PU &&
|
||||
pull != PIN_TYPE_STD_PD &&
|
||||
pull != PIN_TYPE_OD &&
|
||||
pull != PIN_TYPE_OD_PU &&
|
||||
pull != PIN_TYPE_OD_PD) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
if (NULL == (self = extint_find(pin->port, pin->bit))) {
|
||||
self = extint_add(pin->pin_num, pin->port, pin->bit);
|
||||
}
|
||||
else {
|
||||
// we need to update the callback atomically, so we disable the line
|
||||
// before we update anything.
|
||||
extint_disable(self);
|
||||
}
|
||||
|
||||
// invalidate the callback
|
||||
self->callback = NULL;
|
||||
|
||||
// before enabling the interrupt, configure the gpio pin
|
||||
pin_config(pin, PIN_MODE_0, GPIO_DIR_MODE_IN, pull, PIN_STRENGTH_4MA);
|
||||
|
||||
MAP_GPIOIntTypeSet(pin->port, pin->bit, intmode);
|
||||
switch (pin->port) {
|
||||
case GPIOA0_BASE:
|
||||
handler = GPIOA0IntHandler;
|
||||
intnum = INT_GPIOA0;
|
||||
break;
|
||||
case GPIOA1_BASE:
|
||||
handler = GPIOA1IntHandler;
|
||||
intnum = INT_GPIOA1;
|
||||
break;
|
||||
case GPIOA2_BASE:
|
||||
handler = GPIOA2IntHandler;
|
||||
intnum = INT_GPIOA2;
|
||||
break;
|
||||
case GPIOA3_BASE:
|
||||
default:
|
||||
handler = GPIOA3IntHandler;
|
||||
intnum = INT_GPIOA3;
|
||||
break;
|
||||
}
|
||||
|
||||
MAP_GPIOIntRegister(pin->port, handler);
|
||||
// set the interrupt to the lowest priority, to make sure that no ther
|
||||
// isr will be preemted by this one
|
||||
MAP_IntPrioritySet(intnum, INT_PRIORITY_LVL_7);
|
||||
|
||||
// set the new callback
|
||||
self->callback = callback;
|
||||
// enable the interrupt just before leaving
|
||||
extint_enable(self);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void extint_enable(extint_obj_t *self) {
|
||||
MAP_GPIOIntClear(self->port, self->bit);
|
||||
MAP_GPIOIntEnable(self->port, self->bit);
|
||||
}
|
||||
|
||||
void extint_disable(extint_obj_t *self) {
|
||||
MAP_GPIOIntDisable(self->port, self->bit);
|
||||
}
|
||||
|
||||
void extint_swint(extint_obj_t *self) {
|
||||
ExecuteIntCallback(self);
|
||||
}
|
||||
542
cc3200/mods/pybi2c.c
Normal file
542
cc3200/mods/pybi2c.c
Normal file
@@ -0,0 +1,542 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/runtime.h"
|
||||
#include "bufhelper.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_i2c.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "rom_map.h"
|
||||
#include "pin.h"
|
||||
#include "prcm.h"
|
||||
#include "i2c.h"
|
||||
#include "pybi2c.h"
|
||||
#include "mpexception.h"
|
||||
#include "pybsleep.h"
|
||||
#include "utils.h"
|
||||
|
||||
/// \moduleref pyb
|
||||
/// \class I2C - a two-wire serial protocol
|
||||
///
|
||||
/// I2C is a two-wire protocol for communicating between devices. At the physical
|
||||
/// level it consists of 2 wires: SCL and SDA, the clock and data lines respectively.
|
||||
///
|
||||
/// I2C objects are created attached to a specific bus. They can be initialised
|
||||
/// when created, or initialised later on:
|
||||
///
|
||||
/// from pyb import I2C
|
||||
///
|
||||
/// i2c = I2C() # create
|
||||
/// i2c = I2C(50000) # create and init with a 50KHz baudrate
|
||||
/// i2c.init(100000) # init with a 100KHz baudrate
|
||||
/// i2c.deinit() # turn off the peripheral
|
||||
///
|
||||
/// Printing the i2c object gives you information about its configuration.
|
||||
///
|
||||
/// Basic methods for slave are send and recv:
|
||||
///
|
||||
/// i2c.send('abc') # send 3 bytes
|
||||
/// i2c.send(0x42) # send a single byte, given by the number
|
||||
/// data = i2c.recv(3) # receive 3 bytes
|
||||
///
|
||||
/// To receive inplace, first create a bytearray:
|
||||
///
|
||||
/// data = bytearray(3) # create a buffer
|
||||
/// i2c.recv(data) # receive 3 bytes, writing them into data
|
||||
///
|
||||
/// A master must specify the recipient's address:
|
||||
///
|
||||
/// i2c.init(100000)
|
||||
/// i2c.send('123', 0x42) # send 3 bytes to slave with address 0x42
|
||||
/// i2c.send(b'456', addr=0x42) # keyword for address
|
||||
///
|
||||
/// Master also has other methods:
|
||||
///
|
||||
/// i2c.is_ready(0x42) # check if slave 0x42 is ready
|
||||
/// i2c.scan() # scan for slaves on the bus, returning
|
||||
/// # a list of valid addresses
|
||||
/// i2c.mem_read(3, 0x42, 2) # read 3 bytes from memory of slave 0x42,
|
||||
/// # starting at address 2 in the slave
|
||||
/// i2c.mem_write('abc', 0x42, 2) # write 3 bytes to memory of slave 0x42,
|
||||
/// # starting at address 2 in the slave
|
||||
|
||||
typedef struct _pyb_i2c_obj_t {
|
||||
mp_obj_base_t base;
|
||||
uint baudrate;
|
||||
} pyb_i2c_obj_t;
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYBI2C_MIN_BAUD_RATE_HZ (50000)
|
||||
#define PYBI2C_MAX_BAUD_RATE_HZ (400000)
|
||||
|
||||
#define PYBI2C_TRANSC_TIMEOUT_MS (10)
|
||||
#define PYBI2C_TRANSAC_WAIT_DELAY_US (10)
|
||||
|
||||
#define PYBI2C_TIMEOUT_TO_COUNT(to_us, baud) (((baud) * to_us) / 16000000)
|
||||
|
||||
#define RET_IF_ERR(Func) { \
|
||||
if (!Func) { \
|
||||
return false; \
|
||||
} \
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC pyb_i2c_obj_t pyb_i2c_obj = {.baudrate = 0};
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
// only master mode is available for the moment
|
||||
STATIC void i2c_init (pyb_i2c_obj_t *self) {
|
||||
// Enable the I2C Peripheral
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_I2CA0, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
MAP_PRCMPeripheralReset(PRCM_I2CA0);
|
||||
// Configure I2C module with the specified baudrate
|
||||
MAP_I2CMasterInitExpClk(I2CA0_BASE, self->baudrate);
|
||||
}
|
||||
|
||||
STATIC bool pyb_i2c_transaction(uint cmd) {
|
||||
// Convert the timeout to microseconds
|
||||
int32_t timeout = PYBI2C_TRANSC_TIMEOUT_MS * 1000;
|
||||
// Sanity check, t_timeout must be between 1 and 255
|
||||
uint t_timeout = MIN(PYBI2C_TIMEOUT_TO_COUNT(timeout, pyb_i2c_obj.baudrate), 255);
|
||||
// Clear all interrupts
|
||||
MAP_I2CMasterIntClearEx(I2CA0_BASE, MAP_I2CMasterIntStatusEx(I2CA0_BASE, false));
|
||||
// Set the time-out in terms of clock cycles. Not to be used with breakpoints.
|
||||
MAP_I2CMasterTimeoutSet(I2CA0_BASE, t_timeout);
|
||||
// Initiate the transfer.
|
||||
MAP_I2CMasterControl(I2CA0_BASE, cmd);
|
||||
// Wait until the current byte has been transferred.
|
||||
// Poll on the raw interrupt status.
|
||||
while ((MAP_I2CMasterIntStatusEx(I2CA0_BASE, false) & (I2C_MASTER_INT_DATA | I2C_MASTER_INT_TIMEOUT)) == 0) {
|
||||
// wait for a few microseconds
|
||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT(PYBI2C_TRANSAC_WAIT_DELAY_US));
|
||||
timeout -= PYBI2C_TRANSAC_WAIT_DELAY_US;
|
||||
if (timeout < 0) {
|
||||
// the peripheral is not responding, so stop
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for any errors in the transfer
|
||||
if (MAP_I2CMasterErr(I2CA0_BASE) != I2C_MASTER_ERR_NONE) {
|
||||
switch(cmd) {
|
||||
case I2C_MASTER_CMD_BURST_SEND_START:
|
||||
case I2C_MASTER_CMD_BURST_SEND_CONT:
|
||||
case I2C_MASTER_CMD_BURST_SEND_STOP:
|
||||
MAP_I2CMasterControl(I2CA0_BASE, I2C_MASTER_CMD_BURST_SEND_ERROR_STOP);
|
||||
break;
|
||||
case I2C_MASTER_CMD_BURST_RECEIVE_START:
|
||||
case I2C_MASTER_CMD_BURST_RECEIVE_CONT:
|
||||
case I2C_MASTER_CMD_BURST_RECEIVE_FINISH:
|
||||
MAP_I2CMasterControl(I2CA0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
STATIC bool pyb_i2c_write(byte devAddr, byte *data, uint len, bool stop) {
|
||||
// Set I2C codec slave address
|
||||
MAP_I2CMasterSlaveAddrSet(I2CA0_BASE, devAddr, false);
|
||||
// Write the first byte to the controller.
|
||||
MAP_I2CMasterDataPut(I2CA0_BASE, *data++);
|
||||
// Initiate the transfer.
|
||||
RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_BURST_SEND_START));
|
||||
|
||||
// Loop until the completion of transfer or error
|
||||
while (--len) {
|
||||
// Write the next byte of data
|
||||
MAP_I2CMasterDataPut(I2CA0_BASE, *data++);
|
||||
// Transact over I2C to send the byte
|
||||
RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_BURST_SEND_CONT));
|
||||
}
|
||||
|
||||
// If a stop bit is to be sent, send it.
|
||||
if (stop) {
|
||||
RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_BURST_SEND_STOP));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
STATIC bool pyb_i2c_read(byte devAddr, byte *data, uint len) {
|
||||
uint cmd;
|
||||
|
||||
// Set I2C codec slave address
|
||||
MAP_I2CMasterSlaveAddrSet(I2CA0_BASE, devAddr, true);
|
||||
|
||||
// Check if its a single receive or burst receive
|
||||
if (len > 1) {
|
||||
// Initiate a burst receive sequence
|
||||
cmd = I2C_MASTER_CMD_BURST_RECEIVE_START;
|
||||
}
|
||||
else {
|
||||
// Configure for a single receive
|
||||
cmd = I2C_MASTER_CMD_SINGLE_RECEIVE;
|
||||
}
|
||||
|
||||
// Initiate the transfer.
|
||||
RET_IF_ERR(pyb_i2c_transaction(cmd));
|
||||
// Decrement the count
|
||||
len--;
|
||||
// Loop until the completion of reception or error
|
||||
while (len) {
|
||||
// Receive the byte over I2C
|
||||
*data++ = MAP_I2CMasterDataGet(I2CA0_BASE);
|
||||
if (--len) {
|
||||
// Continue with reception
|
||||
RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_BURST_RECEIVE_CONT));
|
||||
}
|
||||
else {
|
||||
// Complete the last reception
|
||||
RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_BURST_RECEIVE_FINISH));
|
||||
}
|
||||
}
|
||||
|
||||
// Receive the last byte over I2C
|
||||
*data = MAP_I2CMasterDataGet(I2CA0_BASE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
STATIC bool pyb_i2c_scan_device(byte devAddr) {
|
||||
// Set I2C codec slave address
|
||||
MAP_I2CMasterSlaveAddrSet(I2CA0_BASE, devAddr, true);
|
||||
// Initiate the transfer.
|
||||
RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_SINGLE_RECEIVE));
|
||||
// Since this is a hack, send the stop bit anyway
|
||||
MAP_I2CMasterControl(I2CA0_BASE, I2C_MASTER_CMD_BURST_SEND_ERROR_STOP);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings */
|
||||
/******************************************************************************/
|
||||
|
||||
/// \method init(100000)
|
||||
///
|
||||
/// Initialise the I2C bus as a master with the given baudrate.
|
||||
///
|
||||
STATIC mp_obj_t pyb_i2c_init_helper(pyb_i2c_obj_t *self_in, mp_obj_t baudrate) {
|
||||
pyb_i2c_obj_t *self = self_in;
|
||||
|
||||
// make sure the baudrate is between the valid range
|
||||
self->baudrate = MIN(MAX(mp_obj_get_int(baudrate), PYBI2C_MIN_BAUD_RATE_HZ), PYBI2C_MAX_BAUD_RATE_HZ);
|
||||
|
||||
// init the I2C bus
|
||||
i2c_init(self);
|
||||
|
||||
// register it with the sleep module
|
||||
pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)i2c_init);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
/// \classmethod \constructor(bus, ...)
|
||||
///
|
||||
/// Construct an I2C object on the given bus. `bus` can only be 0.
|
||||
/// With no additional parameters, the I2C object is created but not
|
||||
/// initialised (it has the settings from the last initialisation of
|
||||
/// the bus, if any). If extra arguments are given, the bus is initialised.
|
||||
/// See `init` for parameters of initialisation.
|
||||
STATIC mp_obj_t pyb_i2c_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
// check arguments
|
||||
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
|
||||
|
||||
// setup the object
|
||||
pyb_i2c_obj_t *self = &pyb_i2c_obj;
|
||||
self->base.type = &pyb_i2c_type;
|
||||
|
||||
if (n_args > 0) {
|
||||
// start the peripheral
|
||||
pyb_i2c_init_helper(self, *args);
|
||||
}
|
||||
|
||||
return (mp_obj_t)self;
|
||||
}
|
||||
|
||||
STATIC void pyb_i2c_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_i2c_obj_t *self = self_in;
|
||||
if (self->baudrate > 0) {
|
||||
print(env, "<I2C0, I2C.MASTER, baudrate=%u>)", self->baudrate);
|
||||
}
|
||||
else {
|
||||
print(env, "<I2C0>");
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_init(mp_obj_t self_in, mp_obj_t baudrate) {
|
||||
return pyb_i2c_init_helper(self_in, baudrate);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_i2c_init_obj, pyb_i2c_init);
|
||||
|
||||
/// \method deinit()
|
||||
/// Turn off the I2C bus.
|
||||
STATIC mp_obj_t pyb_i2c_deinit(mp_obj_t self_in) {
|
||||
// disable the peripheral
|
||||
MAP_I2CMasterDisable(I2CA0_BASE);
|
||||
MAP_PRCMPeripheralClkDisable(PRCM_I2CA0, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
// invalidate the baudrate
|
||||
pyb_i2c_obj.baudrate = 0;
|
||||
// unregister it with the sleep module
|
||||
pybsleep_remove ((const mp_obj_t)self_in);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_i2c_deinit_obj, pyb_i2c_deinit);
|
||||
|
||||
/// \method is_ready(addr)
|
||||
/// Check if an I2C device responds to the given address. Only valid when in master mode.
|
||||
STATIC mp_obj_t pyb_i2c_is_ready(mp_obj_t self_in, mp_obj_t i2c_addr_o) {
|
||||
mp_uint_t i2c_addr = mp_obj_get_int(i2c_addr_o);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
if (pyb_i2c_scan_device(i2c_addr)) {
|
||||
return mp_const_true;
|
||||
}
|
||||
}
|
||||
return mp_const_false;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_i2c_is_ready_obj, pyb_i2c_is_ready);
|
||||
|
||||
/// \method scan()
|
||||
/// Scan all I2C addresses from 0x01 to 0x7f and return a list of those that respond.
|
||||
/// Only valid when in master mode.
|
||||
STATIC mp_obj_t pyb_i2c_scan(mp_obj_t self_in) {
|
||||
mp_obj_t list = mp_obj_new_list(0, NULL);
|
||||
for (uint addr = 1; addr <= 127; addr++) {
|
||||
for (int i = 0; i < 7; i++) {
|
||||
if (pyb_i2c_scan_device(addr)) {
|
||||
mp_obj_list_append(list, mp_obj_new_int(addr));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_i2c_scan_obj, pyb_i2c_scan);
|
||||
|
||||
/// \method send(send, addr=0x00)
|
||||
/// Send data on the bus:
|
||||
///
|
||||
/// - `send` is the data to send (an integer to send, or a buffer object)
|
||||
/// - `addr` is the address to send to (only required in master mode)
|
||||
/// Return value: `None`.
|
||||
STATIC const mp_arg_t pyb_i2c_send_args[] = {
|
||||
{ MP_QSTR_send, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_addr, MP_ARG_INT, {.u_int = 0} },
|
||||
};
|
||||
#define PYB_I2C_SEND_NUM_ARGS MP_ARRAY_SIZE(pyb_i2c_send_args)
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_send(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
// parse args
|
||||
mp_arg_val_t vals[PYB_I2C_SEND_NUM_ARGS];
|
||||
mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_SEND_NUM_ARGS, pyb_i2c_send_args, vals);
|
||||
|
||||
// get the buffer to send from
|
||||
mp_buffer_info_t bufinfo;
|
||||
uint8_t data[1];
|
||||
pyb_buf_get_for_send(vals[0].u_obj, &bufinfo, data);
|
||||
|
||||
// send the data
|
||||
if (!pyb_i2c_write(vals[1].u_int, bufinfo.buf, bufinfo.len, true)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_send_obj, 1, pyb_i2c_send);
|
||||
|
||||
/// \method recv(recv, addr=0x00)
|
||||
///
|
||||
/// Receive data on the bus:
|
||||
///
|
||||
/// - `recv` can be an integer, which is the number of bytes to receive,
|
||||
/// or a mutable buffer, which will be filled with received bytes
|
||||
/// - `addr` is the address to receive from (only required in master mode)
|
||||
///
|
||||
/// Return value: if `recv` is an integer then a new buffer of the bytes received,
|
||||
/// otherwise the same buffer that was passed in to `recv`.
|
||||
STATIC const mp_arg_t pyb_i2c_recv_args[] = {
|
||||
{ MP_QSTR_recv, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_addr, MP_ARG_INT, {.u_int = 0} },
|
||||
};
|
||||
#define PYB_I2C_RECV_NUM_ARGS MP_ARRAY_SIZE(pyb_i2c_recv_args)
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_recv(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
// parse args
|
||||
mp_arg_val_t vals[PYB_I2C_RECV_NUM_ARGS];
|
||||
mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_RECV_NUM_ARGS, pyb_i2c_recv_args, vals);
|
||||
|
||||
// get the buffer to receive into
|
||||
vstr_t vstr;
|
||||
mp_obj_t o_ret = pyb_buf_get_for_recv(vals[0].u_obj, &vstr);
|
||||
|
||||
// receive the data
|
||||
if (!pyb_i2c_read(vals[1].u_int, (byte *)vstr.buf, vstr.len)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
// return the received data
|
||||
if (o_ret != MP_OBJ_NULL) {
|
||||
return o_ret;
|
||||
}
|
||||
else {
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_recv_obj, 1, pyb_i2c_recv);
|
||||
|
||||
/// \method mem_read(data, addr, memaddr, addr_size=8)
|
||||
///
|
||||
/// Read from the memory of an I2C device:
|
||||
///
|
||||
/// - `data` can be an integer or a buffer to read into
|
||||
/// - `addr` is the I2C device address
|
||||
/// - `memaddr` is the memory location within the I2C device
|
||||
/// - `addr_size` selects the width of memaddr: 8 or 16 bits
|
||||
///
|
||||
/// Returns the read data.
|
||||
/// This is only valid in master mode.
|
||||
STATIC const mp_arg_t pyb_i2c_mem_read_args[] = {
|
||||
{ MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_memaddr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_addr_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
|
||||
};
|
||||
#define PYB_I2C_MEM_READ_NUM_ARGS MP_ARRAY_SIZE(pyb_i2c_mem_read_args)
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_mem_read(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
// parse args
|
||||
mp_arg_val_t vals[PYB_I2C_MEM_READ_NUM_ARGS];
|
||||
mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_MEM_READ_NUM_ARGS, pyb_i2c_mem_read_args, vals);
|
||||
|
||||
// get the buffer to read into
|
||||
vstr_t vstr;
|
||||
mp_obj_t o_ret = pyb_buf_get_for_recv(vals[0].u_obj, &vstr);
|
||||
|
||||
// get the addresses
|
||||
mp_uint_t i2c_addr = vals[1].u_int;
|
||||
mp_uint_t mem_addr = vals[2].u_int;
|
||||
// determine the width of mem_addr (1 or 2 bytes)
|
||||
mp_uint_t mem_addr_size = vals[3].u_int >> 3;
|
||||
|
||||
// Write the register address to be read from.
|
||||
if (pyb_i2c_write (i2c_addr, (byte *)&mem_addr, mem_addr_size, false)) {
|
||||
// Read the specified length of data
|
||||
if (pyb_i2c_read (i2c_addr, (byte *)vstr.buf, vstr.len)) {
|
||||
// return the read data
|
||||
if (o_ret != MP_OBJ_NULL) {
|
||||
return o_ret;
|
||||
} else {
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_mem_read_obj, 1, pyb_i2c_mem_read);
|
||||
|
||||
/// \method mem_write(data, addr, memaddr, addr_size=8)
|
||||
///
|
||||
/// Write to the memory of an I2C device:
|
||||
///
|
||||
/// - `data` can be an integer or a buffer to write from
|
||||
/// - `addr` is the I2C device address
|
||||
/// - `memaddr` is the memory location within the I2C device
|
||||
/// - `addr_size` selects the width of memaddr: 8 or 16 bits
|
||||
///
|
||||
/// Returns `None`.
|
||||
/// This is only valid in master mode.
|
||||
STATIC mp_obj_t pyb_i2c_mem_write(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
// parse args (same as mem_read)
|
||||
mp_arg_val_t vals[PYB_I2C_MEM_READ_NUM_ARGS];
|
||||
mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_I2C_MEM_READ_NUM_ARGS, pyb_i2c_mem_read_args, vals);
|
||||
|
||||
// get the buffer to write from
|
||||
mp_buffer_info_t bufinfo;
|
||||
uint8_t data[1];
|
||||
pyb_buf_get_for_send(vals[0].u_obj, &bufinfo, data);
|
||||
|
||||
// get the addresses
|
||||
mp_uint_t i2c_addr = vals[1].u_int;
|
||||
mp_uint_t mem_addr = vals[2].u_int;
|
||||
// determine the width of mem_addr (1 or 2 bytes)
|
||||
mp_uint_t mem_addr_size = vals[3].u_int >> 3;
|
||||
|
||||
// Write the register address to write to.
|
||||
if (pyb_i2c_write (i2c_addr, (byte *)&mem_addr, mem_addr_size, false)) {
|
||||
// Write the specified length of data
|
||||
if (pyb_i2c_write (i2c_addr, bufinfo.buf, bufinfo.len, true)) {
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_mem_write_obj, 1, pyb_i2c_mem_write);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_i2c_locals_dict_table[] = {
|
||||
// instance methods
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_i2c_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_i2c_deinit_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_is_ready), (mp_obj_t)&pyb_i2c_is_ready_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_scan), (mp_obj_t)&pyb_i2c_scan_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&pyb_i2c_send_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&pyb_i2c_recv_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mem_read), (mp_obj_t)&pyb_i2c_mem_read_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mem_write), (mp_obj_t)&pyb_i2c_mem_write_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_i2c_locals_dict, pyb_i2c_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t pyb_i2c_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_I2C,
|
||||
.print = pyb_i2c_print,
|
||||
.make_new = pyb_i2c_make_new,
|
||||
.locals_dict = (mp_obj_t)&pyb_i2c_locals_dict,
|
||||
};
|
||||
@@ -4,6 +4,7 @@
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -24,4 +25,9 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename);
|
||||
#ifndef PYBI2C_H_
|
||||
#define PYBI2C_H_
|
||||
|
||||
extern const mp_obj_type_t pyb_i2c_type;
|
||||
|
||||
#endif // PYBI2C_H_
|
||||
@@ -29,14 +29,12 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/mpstate.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_gpio.h"
|
||||
#include "inc/hw_ints.h"
|
||||
@@ -45,8 +43,13 @@
|
||||
#include "pin.h"
|
||||
#include "prcm.h"
|
||||
#include "gpio.h"
|
||||
#include "interrupt.h"
|
||||
#include "pybpin.h"
|
||||
#include "pins.h"
|
||||
#include "pybsleep.h"
|
||||
#include "mpcallback.h"
|
||||
#include "mpexception.h"
|
||||
#include "mperror.h"
|
||||
|
||||
|
||||
/// \moduleref pyb
|
||||
@@ -71,18 +74,97 @@
|
||||
///
|
||||
/// g = pyb.Pin('GPIO9', 0)
|
||||
///
|
||||
/// And finally, you can also pass a pin number directly:
|
||||
///
|
||||
/// g = pyb.Pin(64, 0)
|
||||
///
|
||||
/// To summarise, the following order determines how things get mapped into
|
||||
/// an ordinal pin number:
|
||||
///
|
||||
/// 1. Directly specify a Pin object
|
||||
/// 2. Supply a string which matches a CPU port/pin
|
||||
/// 2. Supply a string which matches a CPU pin name
|
||||
/// 3. Provide a pin number
|
||||
///
|
||||
/// \Interrupts:
|
||||
//// You can also configure the Pin to generate interrupts
|
||||
///
|
||||
/// Example callback:
|
||||
///
|
||||
/// def pincb(pin):
|
||||
/// print(pin.pin())
|
||||
///
|
||||
/// extint = pyb.Pin('GPIO10', 0, pyb.Pin.INT_RISING, pyb.GPIO.STD_PD, pyb.S2MA)
|
||||
/// extint.callback (intmode=pyb.Pin.INT_RISING, handler=pincb)
|
||||
/// # the callback can be triggered manually
|
||||
/// extint.callback()()
|
||||
/// # to disable the callback
|
||||
/// extint.callback().disable()
|
||||
///
|
||||
/// Now every time a falling edge is seen on the gpio pin, the callback will be
|
||||
/// called. Caution: mechanical pushbuttons have "bounce" and pushing or
|
||||
/// releasing a switch will often generate multiple edges.
|
||||
/// See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed
|
||||
/// explanation, along with various techniques for debouncing.
|
||||
///
|
||||
/// All pin objects go through the pin mapper to come up with one of the
|
||||
/// gpio pins.
|
||||
///
|
||||
/// There is also a C API, so that drivers which require Pin interrupts
|
||||
/// can also use this code. See pybextint.h for the available functions.
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC void GPIOA0IntHandler (void);
|
||||
STATIC void GPIOA1IntHandler (void);
|
||||
STATIC void GPIOA2IntHandler (void);
|
||||
STATIC void GPIOA3IntHandler (void);
|
||||
STATIC void EXTI_Handler(uint port);
|
||||
STATIC void pin_obj_configure (const pin_obj_t *self);
|
||||
STATIC void pin_get_hibernate_pin_and_idx (const pin_obj_t *self, uint *wake_pin, uint *idx);
|
||||
STATIC void pin_extint_enable (mp_obj_t self_in);
|
||||
STATIC void pin_extint_disable (mp_obj_t self_in);
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYBPIN_NUM_WAKE_PINS (6)
|
||||
#define PYBPIN_WAKES_NOT (-1)
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
bool active;
|
||||
int8_t lpds;
|
||||
int8_t hib;
|
||||
} pybpin_wake_pin_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC const mp_cb_methods_t pin_cb_methods;
|
||||
STATIC pybpin_wake_pin_t pybpin_wake_pin[PYBPIN_NUM_WAKE_PINS] =
|
||||
{ {.active = false, .lpds = PYBPIN_WAKES_NOT, .hib = PYBPIN_WAKES_NOT},
|
||||
{.active = false, .lpds = PYBPIN_WAKES_NOT, .hib = PYBPIN_WAKES_NOT},
|
||||
{.active = false, .lpds = PYBPIN_WAKES_NOT, .hib = PYBPIN_WAKES_NOT},
|
||||
{.active = false, .lpds = PYBPIN_WAKES_NOT, .hib = PYBPIN_WAKES_NOT},
|
||||
{.active = false, .lpds = PYBPIN_WAKES_NOT, .hib = PYBPIN_WAKES_NOT},
|
||||
{.active = false, .lpds = PYBPIN_WAKES_NOT, .hib = PYBPIN_WAKES_NOT} } ;
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
void pin_init0(void) {
|
||||
// assign GPIO10 and GPIO11 to the GPIO peripheral (the default is I2C), so that the I2C bus can
|
||||
// be assigned safely to any other pins (as recomended by the SDK release notes). Make them
|
||||
// inputs with pull-downs enabled to ensure they are not floating during LDPS and hibernate.
|
||||
pin_config ((pin_obj_t *)&pin_GPIO10, PIN_MODE_0, GPIO_DIR_MODE_IN, PIN_TYPE_STD_PD, PIN_STRENGTH_2MA);
|
||||
pin_config ((pin_obj_t *)&pin_GPIO11, PIN_MODE_0, GPIO_DIR_MODE_IN, PIN_TYPE_STD_PD, PIN_STRENGTH_2MA);
|
||||
}
|
||||
|
||||
// C API used to convert a user-supplied pin name into an ordinal pin number.
|
||||
const pin_obj_t *pin_find(mp_obj_t user_obj) {
|
||||
const pin_obj_t *pin_obj;
|
||||
pin_obj_t *pin_find(mp_obj_t user_obj) {
|
||||
pin_obj_t *pin_obj;
|
||||
|
||||
// If a pin was provided, then use it
|
||||
if (MP_OBJ_IS_TYPE(user_obj, &pin_type)) {
|
||||
@@ -96,36 +178,253 @@ const pin_obj_t *pin_find(mp_obj_t user_obj) {
|
||||
return pin_obj;
|
||||
}
|
||||
|
||||
// See if the pin number matches a cpu pin
|
||||
mp_int_t pin_num;
|
||||
if (mp_obj_get_int_maybe(user_obj, &pin_num)) {
|
||||
// The Pins dictionary has pin indexes, so we must substract one from the value passed
|
||||
pin_obj = pin_find_pin(&pin_cpu_pins_locals_dict, (pin_num - 1));
|
||||
if (pin_obj) {
|
||||
return pin_obj;
|
||||
}
|
||||
}
|
||||
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
void pin_config(const pin_obj_t *self, uint af, uint mode, uint type, uint strength) {
|
||||
// PIN_MODE_0 means it stays as a Pin, else, another peripheral will take control of it
|
||||
if (af == PIN_MODE_0) {
|
||||
// enable the peripheral clock for the GPIO port of this pin
|
||||
switch (self->port) {
|
||||
case PORT_A0:
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_GPIOA0, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
break;
|
||||
case PORT_A1:
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_GPIOA1, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
break;
|
||||
case PORT_A2:
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_GPIOA2, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
break;
|
||||
case PORT_A3:
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_GPIOA3, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
void pin_verify_af (uint af) {
|
||||
if (af > PIN_MODE_15) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
|
||||
void pin_config (pin_obj_t *self, uint af, uint mode, uint type, uint strength) {
|
||||
// configure the pin in analog mode
|
||||
self->af = af, self->mode = mode, self->type = type, self->strength = strength;
|
||||
pin_obj_configure ((const pin_obj_t *)self);
|
||||
// mark the pin as used
|
||||
self->isused = true;
|
||||
// register it with the sleep module
|
||||
pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)pin_obj_configure);
|
||||
}
|
||||
|
||||
void pin_extint_register(pin_obj_t *self, uint32_t intmode, uint32_t priority) {
|
||||
void *handler;
|
||||
uint32_t intnum;
|
||||
|
||||
// configure the interrupt type
|
||||
MAP_GPIOIntTypeSet(self->port, self->bit, intmode);
|
||||
switch (self->port) {
|
||||
case GPIOA0_BASE:
|
||||
handler = GPIOA0IntHandler;
|
||||
intnum = INT_GPIOA0;
|
||||
break;
|
||||
case GPIOA1_BASE:
|
||||
handler = GPIOA1IntHandler;
|
||||
intnum = INT_GPIOA1;
|
||||
break;
|
||||
case GPIOA2_BASE:
|
||||
handler = GPIOA2IntHandler;
|
||||
intnum = INT_GPIOA2;
|
||||
break;
|
||||
case GPIOA3_BASE:
|
||||
default:
|
||||
handler = GPIOA3IntHandler;
|
||||
intnum = INT_GPIOA3;
|
||||
break;
|
||||
}
|
||||
MAP_GPIOIntRegister(self->port, handler);
|
||||
// set the interrupt to the lowest priority, to make sure that
|
||||
// no other ISRs will be preemted by this one
|
||||
MAP_IntPrioritySet(intnum, priority);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC void pin_obj_configure (const pin_obj_t *self) {
|
||||
// Skip all this if the pin is to be used in analog mode
|
||||
if (self->type != PYBPIN_ANALOG_TYPE) {
|
||||
// verify the alternate function
|
||||
pin_verify_af (self->af);
|
||||
// PIN_MODE_0 means it stays as a pin, else, another peripheral will take control of it
|
||||
if (self->af == PIN_MODE_0) {
|
||||
// enable the peripheral clock for the GPIO port of this pin
|
||||
switch (self->port) {
|
||||
case PORT_A0:
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_GPIOA0, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
break;
|
||||
case PORT_A1:
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_GPIOA1, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
break;
|
||||
case PORT_A2:
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_GPIOA2, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
break;
|
||||
case PORT_A3:
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_GPIOA3, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// configure the direction
|
||||
MAP_GPIODirModeSet(self->port, self->bit, self->mode);
|
||||
}
|
||||
// configure the direction
|
||||
MAP_GPIODirModeSet(self->port, self->bit, mode);
|
||||
// now set the alternate function, strenght and type
|
||||
MAP_PinModeSet (self->pin_num, self->af);
|
||||
}
|
||||
MAP_PinConfigSet(self->pin_num, self->strength, self->type);
|
||||
}
|
||||
|
||||
STATIC void pin_get_hibernate_pin_and_idx (const pin_obj_t *self, uint *hib_pin, uint *idx) {
|
||||
// pin_num is actually : (package_pin - 1)
|
||||
switch (self->pin_num) {
|
||||
case 56: // GPIO2
|
||||
*hib_pin = PRCM_HIB_GPIO2;
|
||||
*idx = 0;
|
||||
break;
|
||||
case 58: // GPIO4
|
||||
*hib_pin = PRCM_HIB_GPIO4;
|
||||
*idx = 1;
|
||||
break;
|
||||
case 3: // GPIO13
|
||||
*hib_pin = PRCM_HIB_GPIO13;
|
||||
*idx = 2;
|
||||
break;
|
||||
case 7: // GPIO17
|
||||
*hib_pin = PRCM_HIB_GPIO17;
|
||||
*idx = 3;
|
||||
break;
|
||||
case 1: // GPIO11
|
||||
*hib_pin = PRCM_HIB_GPIO11;
|
||||
*idx = 4;
|
||||
break;
|
||||
case 16: // GPIO24
|
||||
*hib_pin = PRCM_HIB_GPIO24;
|
||||
*idx = 5;
|
||||
break;
|
||||
default:
|
||||
*idx = 0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void pin_extint_enable (mp_obj_t self_in) {
|
||||
const pin_obj_t *self = self_in;
|
||||
uint hib_pin, idx;
|
||||
|
||||
pin_get_hibernate_pin_and_idx (self, &hib_pin, &idx);
|
||||
if (idx < PYBPIN_NUM_WAKE_PINS) {
|
||||
if (pybpin_wake_pin[idx].lpds != PYBPIN_WAKES_NOT) {
|
||||
// enable GPIO as a wake source during LPDS
|
||||
MAP_PRCMLPDSWakeUpGPIOSelect(idx, pybpin_wake_pin[idx].lpds);
|
||||
MAP_PRCMLPDSWakeupSourceEnable(PRCM_LPDS_GPIO);
|
||||
}
|
||||
|
||||
if (pybpin_wake_pin[idx].hib != PYBPIN_WAKES_NOT) {
|
||||
// enable GPIO as a wake source during hibernate
|
||||
MAP_PRCMHibernateWakeUpGPIOSelect(hib_pin, pybpin_wake_pin[idx].hib);
|
||||
MAP_PRCMHibernateWakeupSourceEnable(hib_pin);
|
||||
}
|
||||
else {
|
||||
MAP_PRCMHibernateWakeupSourceDisable(hib_pin);
|
||||
}
|
||||
}
|
||||
// if idx is invalid, the pin supports active interrupts for sure
|
||||
if (idx >= PYBPIN_NUM_WAKE_PINS || pybpin_wake_pin[idx].active) {
|
||||
MAP_GPIOIntClear(self->port, self->bit);
|
||||
MAP_GPIOIntEnable(self->port, self->bit);
|
||||
}
|
||||
// in case it was enabled before
|
||||
else if (idx < PYBPIN_NUM_WAKE_PINS && !pybpin_wake_pin[idx].active) {
|
||||
MAP_GPIOIntDisable(self->port, self->bit);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void pin_extint_disable (mp_obj_t self_in) {
|
||||
const pin_obj_t *self = self_in;
|
||||
uint hib_pin, idx;
|
||||
|
||||
pin_get_hibernate_pin_and_idx (self, &hib_pin, &idx);
|
||||
if (idx < PYBPIN_NUM_WAKE_PINS) {
|
||||
if (pybpin_wake_pin[idx].lpds != PYBPIN_WAKES_NOT) {
|
||||
// disable GPIO as a wake source during LPDS
|
||||
MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_GPIO);
|
||||
}
|
||||
if (pybpin_wake_pin[idx].hib != PYBPIN_WAKES_NOT) {
|
||||
// disable GPIO as a wake source during hibernate
|
||||
MAP_PRCMHibernateWakeupSourceDisable(hib_pin);
|
||||
}
|
||||
}
|
||||
// not need to check for the active flag, it's safe to disable it anyway
|
||||
MAP_GPIOIntDisable(self->port, self->bit);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
/// \method init(mode, pull=Pin.PULL_NONE, af=-1)
|
||||
/// Initialise the pin:
|
||||
///
|
||||
/// - `af` can be in range 0-15, please check the CC3200 datasheet
|
||||
/// for the details on the AFs availables on each pin (af=0, keeps it as a gpio pin).
|
||||
/// - `mode` can be one of:
|
||||
/// - `Pin.IN` - configure the pin for input;
|
||||
/// - `Pin.OUT` - configure the pin for output;
|
||||
/// - `type` can be one of:
|
||||
/// - `Pin.STD` - standard without pull-up or pull-down;
|
||||
/// - `Pin.STD_PU` - standard with pull-up resistor;
|
||||
/// - `Pin.STD_PD` - standard with pull-down resistor.
|
||||
/// - `Pin.OD` - standard without pull up or pull down;
|
||||
/// - `Pin.OD_PU` - open drain with pull-up resistor;
|
||||
/// - `Pin.OD_PD` - open drain with pull-down resistor.
|
||||
/// - `Pin.ANALOG` - configured in analog (adc) mode
|
||||
/// - `strength` can be one of:
|
||||
/// - `Pin.S2MA` - 2ma drive strength;
|
||||
/// - `Pin.S4MA` - 4ma drive strength;
|
||||
/// - `Pin.S6MA` - 6ma drive strength;
|
||||
///
|
||||
/// Returns: `None`.
|
||||
STATIC const mp_arg_t pin_init_args[] = {
|
||||
{ MP_QSTR_af, MP_ARG_REQUIRED | MP_ARG_INT },
|
||||
{ MP_QSTR_mode, MP_ARG_INT, {.u_int = GPIO_DIR_MODE_OUT} },
|
||||
{ MP_QSTR_type, MP_ARG_INT, {.u_int = PIN_TYPE_STD} },
|
||||
{ MP_QSTR_str, MP_ARG_INT, {.u_int = PIN_STRENGTH_4MA} },
|
||||
};
|
||||
#define pin_INIT_NUM_ARGS MP_ARRAY_SIZE(pin_init_args)
|
||||
|
||||
STATIC mp_obj_t pin_obj_init_helper(pin_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
// parse args
|
||||
mp_arg_val_t args[pin_INIT_NUM_ARGS];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, pin_INIT_NUM_ARGS, pin_init_args, args);
|
||||
|
||||
// get the af
|
||||
uint af = args[0].u_int;
|
||||
if (af < PIN_MODE_0 || af > PIN_MODE_15) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
// get the io mode
|
||||
uint mode = args[1].u_int;
|
||||
// checking the mode only makes sense if af == GPIO
|
||||
if (af == PIN_MODE_0) {
|
||||
if (mode != GPIO_DIR_MODE_IN && mode != GPIO_DIR_MODE_OUT) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
// get the type
|
||||
uint type = args[2].u_int;
|
||||
if (type != PIN_TYPE_STD && type != PIN_TYPE_STD_PU && type != PIN_TYPE_STD_PD &&
|
||||
type != PIN_TYPE_OD && type != PIN_TYPE_OD_PU && type != PIN_TYPE_OD_PD) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
// get the strenght
|
||||
uint strength = args[3].u_int;
|
||||
if (strength != PIN_STRENGTH_2MA && strength != PIN_STRENGTH_4MA && strength != PIN_STRENGTH_6MA) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
// now set the alternate function, strenght and type
|
||||
MAP_PinModeSet (self->pin_num, af);
|
||||
MAP_PinConfigSet(self->pin_num, strength, type);
|
||||
// configure the pin as requested
|
||||
pin_config (self, af, mode, type, strength);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
/// \method print()
|
||||
@@ -137,7 +436,7 @@ STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env,
|
||||
uint32_t strength = pin_get_strenght(self);
|
||||
|
||||
// pin name
|
||||
print(env, "Pin(Pin.cpu.%s, af=%u", qstr_str(self->name), af);
|
||||
print(env, "<Pin.cpu.%s, af=%u", qstr_str(self->name), af);
|
||||
|
||||
if (af == PIN_MODE_0) {
|
||||
// IO mode
|
||||
@@ -177,11 +476,9 @@ STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env,
|
||||
} else {
|
||||
str_qst = MP_QSTR_S6MA;
|
||||
}
|
||||
print(env, ", strength=Pin.%s)", qstr_str(str_qst));
|
||||
print(env, ", strength=Pin.%s>", qstr_str(str_qst));
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pin_obj_init_helper(const pin_obj_t *pin, mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args);
|
||||
|
||||
/// \classmethod \constructor(id, ...)
|
||||
/// Create a new Pin object associated with the id. If additional arguments are given,
|
||||
/// they are used to initialise the pin. See `init`.
|
||||
@@ -189,9 +486,9 @@ STATIC mp_obj_t pin_make_new(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw,
|
||||
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
|
||||
|
||||
// Run an argument through the mapper and return the result.
|
||||
const pin_obj_t *pin = pin_find(args[0]);
|
||||
pin_obj_t *pin = (pin_obj_t *)pin_find(args[0]);
|
||||
|
||||
if (n_args > 1) {
|
||||
if (n_args > 1 || n_kw > 0) {
|
||||
// pin af given, so configure it
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
|
||||
@@ -201,69 +498,6 @@ STATIC mp_obj_t pin_make_new(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw,
|
||||
return (mp_obj_t)pin;
|
||||
}
|
||||
|
||||
/// \method init(mode, pull=Pin.PULL_NONE, af=-1)
|
||||
/// Initialise the pin:
|
||||
///
|
||||
/// - `af` can be in range 0-15, please check the CC3200 datasheet
|
||||
/// for the details on the AFs availables on each pin (af=0, keeps it as a gpio pin).
|
||||
/// - `mode` can be one of:
|
||||
/// - `Pin.IN` - configure the pin for input;
|
||||
/// - `Pin.OUT` - configure the pin for output;
|
||||
/// - `type` can be one of:
|
||||
/// - `Pin.STD` - standard without pull-up or pull-down;
|
||||
/// - `Pin.STD_PU` - standard with pull-up resistor;
|
||||
/// - `Pin.STD_PD` - standard with pull-down resistor.
|
||||
/// - `Pin.OD` - standard without pull up or pull down;
|
||||
/// - `Pin.OD_PU` - open drain with pull-up resistor;
|
||||
/// - `Pin.OD_PD` - open drain with pull-down resistor.
|
||||
/// - `Pin.ANALOG` - configured in analog (adc) mode
|
||||
/// - `strength` can be one of:
|
||||
/// - `Pin.2MA` - 2ma drive strength;
|
||||
/// - `Pin.4MA` - 4ma drive strength;
|
||||
/// - `Pin.6MA` - 6ma drive strength;
|
||||
///
|
||||
/// Returns: `None`.
|
||||
STATIC const mp_arg_t pin_init_args[] = {
|
||||
{ MP_QSTR_af, MP_ARG_REQUIRED | MP_ARG_INT },
|
||||
{ MP_QSTR_mode, MP_ARG_INT, {.u_int = GPIO_DIR_MODE_OUT} },
|
||||
{ MP_QSTR_type, MP_ARG_INT, {.u_int = PIN_TYPE_STD} },
|
||||
{ MP_QSTR_str, MP_ARG_INT, {.u_int = PIN_STRENGTH_4MA} },
|
||||
};
|
||||
#define pin_INIT_NUM_ARGS MP_ARRAY_SIZE(pin_init_args)
|
||||
|
||||
STATIC mp_obj_t pin_obj_init_helper(const pin_obj_t *self, mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
// parse args
|
||||
mp_arg_val_t vals[pin_INIT_NUM_ARGS];
|
||||
mp_arg_parse_all(n_args, args, kw_args, pin_INIT_NUM_ARGS, pin_init_args, vals);
|
||||
|
||||
// get the af
|
||||
uint af = vals[0].u_int;
|
||||
if (af < PIN_MODE_0 || af > PIN_MODE_15) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
// get the io mode
|
||||
uint mode = vals[1].u_int;
|
||||
if (mode != GPIO_DIR_MODE_IN && mode != GPIO_DIR_MODE_OUT) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
// get the type
|
||||
uint type = vals[2].u_int;
|
||||
if (type != PIN_TYPE_STD && type != PIN_TYPE_STD_PU && type != PIN_TYPE_STD_PD &&
|
||||
type != PIN_TYPE_OD && type != PIN_TYPE_OD_PU && type != PIN_TYPE_OD_PD) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
// get the strenght
|
||||
uint strength = vals[3].u_int;
|
||||
if (strength != PIN_STRENGTH_2MA && strength != PIN_STRENGTH_4MA && strength != PIN_STRENGTH_6MA) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
// configure the pin as requested
|
||||
pin_config (self, af, mode, type, strength);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pin_obj_init(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
return pin_obj_init_helper(args[0], n_args - 1, args + 1, kw_args);
|
||||
}
|
||||
@@ -272,7 +506,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(pin_init_obj, 1, pin_obj_init);
|
||||
/// \method value([value])
|
||||
/// Get or set the digital logic level of the pin:
|
||||
///
|
||||
/// - With no argument, return 0 or 1 depending on the logic level of the pin.
|
||||
/// - With no arguments, return 0 or 1 depending on the logic level of the pin.
|
||||
/// - With `value` given, set the logic level of the pin. `value` can be
|
||||
/// anything that converts to a boolean. If it converts to `True`, the pin
|
||||
/// is set high, otherwise it is set low.
|
||||
@@ -380,48 +614,188 @@ STATIC mp_obj_t pin_af(mp_obj_t self_in) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_af_obj, pin_af);
|
||||
|
||||
/// \method callback(method, intmode, priority, pwrmode)
|
||||
/// Creates a callback object associated to a pin
|
||||
/// min num of arguments is 1 (intmode)
|
||||
STATIC mp_obj_t pin_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
mp_arg_val_t args[mpcallback_INIT_NUM_ARGS];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mpcallback_INIT_NUM_ARGS, mpcallback_init_args, args);
|
||||
|
||||
pin_obj_t *self = pos_args[0];
|
||||
// check if any parameters were passed
|
||||
mp_obj_t _callback = mpcallback_find(self);
|
||||
if (kw_args->used > 0 || !_callback) {
|
||||
// convert the priority to the correct value
|
||||
uint priority = mpcallback_translate_priority (args[2].u_int);
|
||||
// verify the interrupt mode
|
||||
uint intmode = args[0].u_int;
|
||||
if (intmode != GPIO_FALLING_EDGE && intmode != GPIO_RISING_EDGE && intmode != GPIO_BOTH_EDGES &&
|
||||
intmode != GPIO_LOW_LEVEL && intmode != GPIO_HIGH_LEVEL) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
uint pwrmode = args[4].u_int;
|
||||
if (pwrmode > (PYB_PWR_MODE_ACTIVE | PYB_PWR_MODE_LPDS | PYB_PWR_MODE_HIBERNATE)) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
// get the wake info from this pin
|
||||
uint hib_pin, idx;
|
||||
pin_get_hibernate_pin_and_idx ((const pin_obj_t *)self, &hib_pin, &idx);
|
||||
if (pwrmode & PYB_PWR_MODE_LPDS) {
|
||||
if (idx >= PYBPIN_NUM_WAKE_PINS) {
|
||||
goto invalid_args;
|
||||
}
|
||||
// wake modes are different in LDPS
|
||||
uint wake_mode;
|
||||
switch (intmode) {
|
||||
case GPIO_FALLING_EDGE:
|
||||
wake_mode = PRCM_LPDS_FALL_EDGE;
|
||||
break;
|
||||
case GPIO_RISING_EDGE:
|
||||
wake_mode = PRCM_LPDS_RISE_EDGE;
|
||||
break;
|
||||
case GPIO_LOW_LEVEL:
|
||||
wake_mode = PRCM_LPDS_LOW_LEVEL;
|
||||
break;
|
||||
case GPIO_HIGH_LEVEL:
|
||||
wake_mode = PRCM_LPDS_HIGH_LEVEL;
|
||||
break;
|
||||
default:
|
||||
goto invalid_args;
|
||||
break;
|
||||
}
|
||||
|
||||
// first clear the lpds value from all wake-able pins
|
||||
for (uint i = 0; i < PYBPIN_NUM_WAKE_PINS; i++) {
|
||||
pybpin_wake_pin[i].lpds = PYBPIN_WAKES_NOT;
|
||||
}
|
||||
|
||||
// enable this pin as a wake-up source during LPDS
|
||||
pybpin_wake_pin[idx].lpds = wake_mode;
|
||||
}
|
||||
else {
|
||||
// this pin was the previous LPDS wake source, so disable it completely
|
||||
if (pybpin_wake_pin[idx].lpds != PYBPIN_WAKES_NOT) {
|
||||
MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_GPIO);
|
||||
}
|
||||
pybpin_wake_pin[idx].lpds = PYBPIN_WAKES_NOT;
|
||||
}
|
||||
|
||||
if (pwrmode & PYB_PWR_MODE_HIBERNATE) {
|
||||
if (idx >= PYBPIN_NUM_WAKE_PINS) {
|
||||
goto invalid_args;
|
||||
}
|
||||
// wake modes are different in hibernate
|
||||
uint wake_mode;
|
||||
switch (intmode) {
|
||||
case GPIO_FALLING_EDGE:
|
||||
wake_mode = PRCM_HIB_FALL_EDGE;
|
||||
break;
|
||||
case GPIO_RISING_EDGE:
|
||||
wake_mode = PRCM_HIB_RISE_EDGE;
|
||||
break;
|
||||
case GPIO_LOW_LEVEL:
|
||||
wake_mode = PRCM_HIB_LOW_LEVEL;
|
||||
break;
|
||||
case GPIO_HIGH_LEVEL:
|
||||
wake_mode = PRCM_HIB_HIGH_LEVEL;
|
||||
break;
|
||||
default:
|
||||
goto invalid_args;
|
||||
break;
|
||||
}
|
||||
|
||||
// enable this pin as wake-up source during hibernate
|
||||
pybpin_wake_pin[idx].hib = wake_mode;
|
||||
}
|
||||
else {
|
||||
pybpin_wake_pin[idx].hib = PYBPIN_WAKES_NOT;
|
||||
}
|
||||
|
||||
// we need to update the callback atomically, so we disable the
|
||||
// interrupt before we update anything.
|
||||
pin_extint_disable(self);
|
||||
if (pwrmode & PYB_PWR_MODE_ACTIVE) {
|
||||
// register the interrupt
|
||||
pin_extint_register((pin_obj_t *)self, intmode, priority);
|
||||
if (idx < PYBPIN_NUM_WAKE_PINS) {
|
||||
pybpin_wake_pin[idx].active = true;
|
||||
}
|
||||
}
|
||||
else if (idx < PYBPIN_NUM_WAKE_PINS) {
|
||||
pybpin_wake_pin[idx].active = false;
|
||||
}
|
||||
|
||||
// all checks have passed, now we can create the callback
|
||||
_callback = mpcallback_new (self, args[1].u_obj, &pin_cb_methods);
|
||||
if (pwrmode & PYB_PWR_MODE_LPDS) {
|
||||
pybsleep_set_gpio_lpds_callback (_callback);
|
||||
}
|
||||
|
||||
// enable the interrupt just before leaving
|
||||
pin_extint_enable(self);
|
||||
}
|
||||
return _callback;
|
||||
|
||||
invalid_args:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pin_callback_obj, 1, pin_callback);
|
||||
|
||||
STATIC const mp_map_elem_t pin_locals_dict_table[] = {
|
||||
// instance methods
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pin_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&pin_value_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_low), (mp_obj_t)&pin_low_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_high), (mp_obj_t)&pin_high_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_toggle), (mp_obj_t)&pin_toggle_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_name), (mp_obj_t)&pin_name_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_port), (mp_obj_t)&pin_port_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_pin), (mp_obj_t)&pin_pin_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mode), (mp_obj_t)&pin_mode_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_type), (mp_obj_t)&pin_type_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_strength), (mp_obj_t)&pin_strenght_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_af), (mp_obj_t)&pin_af_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pin_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&pin_value_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_low), (mp_obj_t)&pin_low_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_high), (mp_obj_t)&pin_high_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_toggle), (mp_obj_t)&pin_toggle_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_name), (mp_obj_t)&pin_name_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_port), (mp_obj_t)&pin_port_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_pin), (mp_obj_t)&pin_pin_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mode), (mp_obj_t)&pin_mode_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_type), (mp_obj_t)&pin_type_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_strength), (mp_obj_t)&pin_strenght_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_af), (mp_obj_t)&pin_af_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&pin_callback_obj },
|
||||
|
||||
// class attributes
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_cpu), (mp_obj_t)&pin_cpu_pins_obj_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_cpu), (mp_obj_t)&pin_cpu_pins_obj_type },
|
||||
|
||||
// class constants
|
||||
/// \constant IN - set the pin to input mode
|
||||
/// \constant OUT - set the pin to output mode
|
||||
/// \constant STD - set the pin to standard mode without pull-up or pull-down
|
||||
/// \constant STD_PU - set the pin to standard mode with pull-up
|
||||
/// \constant STD_PD - set the pin to standard mode with pull-down
|
||||
/// \constant OD - set the pin to open drain mode without pull-up or pull-down
|
||||
/// \constant OD_PU - set the pin to open drain mode with pull-up
|
||||
/// \constant OD_PD - set the pin to open drain mode with pull-down
|
||||
/// \constant 2MA - set the drive strength to 2ma
|
||||
/// \constant 4MA - set the drive strength to 4ma
|
||||
/// \constant 6MA - set the drive strength to 6ma
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IN), MP_OBJ_NEW_SMALL_INT(GPIO_DIR_MODE_IN) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_OUT), MP_OBJ_NEW_SMALL_INT(GPIO_DIR_MODE_OUT) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_STD), MP_OBJ_NEW_SMALL_INT(PIN_TYPE_STD) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_STD_PU), MP_OBJ_NEW_SMALL_INT(PIN_TYPE_STD_PU) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_STD_PD), MP_OBJ_NEW_SMALL_INT(PIN_TYPE_STD_PD) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_OD), MP_OBJ_NEW_SMALL_INT(PIN_TYPE_OD) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_OD_PU), MP_OBJ_NEW_SMALL_INT(PIN_TYPE_OD_PU) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_OD_PD), MP_OBJ_NEW_SMALL_INT(PIN_TYPE_OD_PD) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_S2MA), MP_OBJ_NEW_SMALL_INT(PIN_STRENGTH_2MA) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_S4MA), MP_OBJ_NEW_SMALL_INT(PIN_STRENGTH_4MA) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_S6MA), MP_OBJ_NEW_SMALL_INT(PIN_STRENGTH_6MA) },
|
||||
/// \constant IN - set the pin to input mode
|
||||
/// \constant OUT - set the pin to output mode
|
||||
/// \constant STD - set the pin to standard mode without pull-up or pull-down
|
||||
/// \constant STD_PU - set the pin to standard mode with pull-up
|
||||
/// \constant STD_PD - set the pin to standard mode with pull-down
|
||||
/// \constant OD - set the pin to open drain mode without pull-up or pull-down
|
||||
/// \constant OD_PU - set the pin to open drain mode with pull-up
|
||||
/// \constant OD_PD - set the pin to open drain mode with pull-down
|
||||
/// \constant IRQ_RISING - interrupt on a rising edge
|
||||
/// \constant IRQ_FALLING - interrupt on a falling edge
|
||||
/// \constant IRQ_RISING_FALLING - interrupt on a rising or falling edge
|
||||
/// \constant IRQ_LOW_LEVEL - interrupt on a low level
|
||||
/// \constant IRQ_HIGH_LEVEL - interrupt on a high level
|
||||
/// \constant 2MA - set the drive strength to 2ma
|
||||
/// \constant 4MA - set the drive strength to 4ma
|
||||
/// \constant 6MA - set the drive strength to 6ma
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IN), MP_OBJ_NEW_SMALL_INT(GPIO_DIR_MODE_IN) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_OUT), MP_OBJ_NEW_SMALL_INT(GPIO_DIR_MODE_OUT) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_STD), MP_OBJ_NEW_SMALL_INT(PIN_TYPE_STD) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_STD_PU), MP_OBJ_NEW_SMALL_INT(PIN_TYPE_STD_PU) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_STD_PD), MP_OBJ_NEW_SMALL_INT(PIN_TYPE_STD_PD) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_OD), MP_OBJ_NEW_SMALL_INT(PIN_TYPE_OD) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_OD_PU), MP_OBJ_NEW_SMALL_INT(PIN_TYPE_OD_PU) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_OD_PD), MP_OBJ_NEW_SMALL_INT(PIN_TYPE_OD_PD) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_INT_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_FALLING_EDGE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_INT_RISING), MP_OBJ_NEW_SMALL_INT(GPIO_RISING_EDGE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_INT_RISING_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_BOTH_EDGES) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_INT_LOW_LEVEL), MP_OBJ_NEW_SMALL_INT(GPIO_LOW_LEVEL) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_INT_HIGH_LEVEL), MP_OBJ_NEW_SMALL_INT(GPIO_HIGH_LEVEL) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_S2MA), MP_OBJ_NEW_SMALL_INT(PIN_STRENGTH_2MA) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_S4MA), MP_OBJ_NEW_SMALL_INT(PIN_STRENGTH_4MA) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_S6MA), MP_OBJ_NEW_SMALL_INT(PIN_STRENGTH_6MA) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pin_locals_dict, pin_locals_dict_table);
|
||||
@@ -433,3 +807,36 @@ const mp_obj_type_t pin_type = {
|
||||
.make_new = pin_make_new,
|
||||
.locals_dict = (mp_obj_t)&pin_locals_dict,
|
||||
};
|
||||
|
||||
STATIC const mp_cb_methods_t pin_cb_methods = {
|
||||
.init = pin_callback,
|
||||
.enable = pin_extint_enable,
|
||||
.disable = pin_extint_disable,
|
||||
};
|
||||
|
||||
STATIC void GPIOA0IntHandler (void) {
|
||||
EXTI_Handler(GPIOA0_BASE);
|
||||
}
|
||||
|
||||
STATIC void GPIOA1IntHandler (void) {
|
||||
EXTI_Handler(GPIOA1_BASE);
|
||||
}
|
||||
|
||||
STATIC void GPIOA2IntHandler (void) {
|
||||
EXTI_Handler(GPIOA2_BASE);
|
||||
}
|
||||
|
||||
STATIC void GPIOA3IntHandler (void) {
|
||||
EXTI_Handler(GPIOA3_BASE);
|
||||
}
|
||||
|
||||
// common interrupt handler
|
||||
STATIC void EXTI_Handler(uint port) {
|
||||
uint32_t bit = MAP_GPIOIntStatus(port, true);
|
||||
MAP_GPIOIntClear(port, bit);
|
||||
|
||||
pin_obj_t *self = (pin_obj_t *)pin_find_pin_by_port_bit(&pin_cpu_pins_locals_dict, port, bit);
|
||||
mp_obj_t _callback = mpcallback_find(self);
|
||||
mpcallback_handler(_callback);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,19 +30,26 @@
|
||||
|
||||
#include MICROPY_PIN_DEFS_PORT_H
|
||||
|
||||
#define PYBPIN_ANALOG_TYPE 0xFF
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
qstr name;
|
||||
uint32_t port;
|
||||
uint32_t bit : 8;
|
||||
uint32_t pin_num : 7;
|
||||
const mp_obj_base_t base;
|
||||
const qstr name;
|
||||
const uint32_t port;
|
||||
uint16_t type;
|
||||
const uint8_t bit;
|
||||
const uint8_t pin_num;
|
||||
uint8_t af;
|
||||
uint8_t strength;
|
||||
uint8_t mode;
|
||||
bool isused;
|
||||
} pin_obj_t;
|
||||
|
||||
extern const mp_obj_type_t pin_type;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const pin_obj_t *pin;
|
||||
const char *name;
|
||||
const pin_obj_t *pin;
|
||||
} pin_named_pin_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -54,12 +61,14 @@ typedef struct {
|
||||
extern const mp_obj_type_t pin_cpu_pins_obj_type;
|
||||
extern const mp_obj_dict_t pin_cpu_pins_locals_dict;
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pin_init_obj);
|
||||
|
||||
void pin_init0(void);
|
||||
void pin_config(const pin_obj_t *self, uint af, uint mode, uint type, uint strength);
|
||||
const pin_obj_t *pin_find(mp_obj_t user_obj);
|
||||
const pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name);
|
||||
void pin_verify_af (uint af);
|
||||
void pin_config(pin_obj_t *self, uint af, uint mode, uint type, uint strength);
|
||||
void pin_extint_register(pin_obj_t *self, uint32_t intmode, uint32_t priority);
|
||||
pin_obj_t *pin_find(mp_obj_t user_obj);
|
||||
pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name);
|
||||
pin_obj_t *pin_find_pin(const mp_obj_dict_t *named_pins, uint pin_num);
|
||||
pin_obj_t *pin_find_pin_by_port_bit (const mp_obj_dict_t *named_pins, uint port, uint bit);
|
||||
uint32_t pin_get_mode(const pin_obj_t *self);
|
||||
uint32_t pin_get_type(const pin_obj_t *self);
|
||||
uint32_t pin_get_strenght(const pin_obj_t *self);
|
||||
|
||||
@@ -27,12 +27,10 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "modutime.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
@@ -40,6 +38,8 @@
|
||||
#include "rom_map.h"
|
||||
#include "prcm.h"
|
||||
#include "pybrtc.h"
|
||||
#include "pybsleep.h"
|
||||
#include "mpcallback.h"
|
||||
|
||||
/// \moduleref pyb
|
||||
/// \class RTC - real time clock
|
||||
@@ -53,52 +53,86 @@
|
||||
/// rtc.datetime((2014, 5, 1, 4, 13, 0, 0, 0))
|
||||
/// print(rtc.datetime())
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYBRTC_CLOCK_FREQUENCY_HZ 32768
|
||||
#define PYBRTC_MIN_INTERVAL_VALUE 25
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
byte prwmode;
|
||||
} pybrtc_data_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC pybrtc_data_t pybrtc_data;
|
||||
STATIC const mp_cb_methods_t pybrtc_cb_methods;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
__attribute__ ((section (".boot")))
|
||||
void pybrtc_init(void) {
|
||||
// if RTC was previously set leave it alone
|
||||
// if the RTC was previously set, leave it alone
|
||||
if (MAP_PRCMSysResetCauseGet() == PRCM_POWER_ON) {
|
||||
// fresh reset; configure RTC Calendar
|
||||
// fresh reset; configure the RTC Calendar
|
||||
// set the date to 1st Jan 2015
|
||||
// set the time to 00:00:00
|
||||
uint32_t seconds = mod_time_seconds_since_2000(2015, 1, 1, 0, 0, 0);
|
||||
|
||||
MAP_PRCMRTCSet(seconds, 0);
|
||||
|
||||
// Mark that the RTC is in use
|
||||
// Mark the RTC in use first
|
||||
MAP_PRCMRTCInUseSet();
|
||||
|
||||
// Now set the RTC calendar seconds
|
||||
MAP_PRCMRTCSet(seconds, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC void pyb_rtc_callback_enable (mp_obj_t self_in) {
|
||||
// check the wake from param
|
||||
if (pybrtc_data.prwmode & PYB_PWR_MODE_ACTIVE) {
|
||||
// enable the slow clock interrupt
|
||||
MAP_PRCMIntEnable(PRCM_INT_SLOW_CLK_CTR);
|
||||
}
|
||||
else {
|
||||
// just in case it was already enabled before
|
||||
MAP_PRCMIntDisable(PRCM_INT_SLOW_CLK_CTR);
|
||||
}
|
||||
pybsleep_configure_timer_wakeup (pybrtc_data.prwmode);
|
||||
}
|
||||
|
||||
STATIC void pyb_rtc_callback_disable (mp_obj_t self_in) {
|
||||
// check the wake from param
|
||||
if (pybrtc_data.prwmode & PYB_PWR_MODE_ACTIVE) {
|
||||
// enable the slow clock interrupt
|
||||
MAP_PRCMIntDisable(PRCM_INT_SLOW_CLK_CTR);
|
||||
}
|
||||
// disable wake from ldps and hibernate
|
||||
pybsleep_configure_timer_wakeup (PYB_PWR_MODE_ACTIVE);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
typedef struct _pyb_rtc_obj_t {
|
||||
mp_obj_base_t base;
|
||||
} pyb_rtc_obj_t;
|
||||
|
||||
STATIC const pyb_rtc_obj_t pyb_rtc_obj = {{&pyb_rtc_type}};
|
||||
|
||||
/// \classmethod \constructor()
|
||||
/// Create an RTC object.
|
||||
STATIC mp_obj_t pyb_rtc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
// check arguments
|
||||
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
||||
|
||||
// return constant object
|
||||
return (mp_obj_t)&pyb_rtc_obj;
|
||||
}
|
||||
|
||||
/// \method datetime([datetimetuple])
|
||||
/// Get or set the date and time of the RTC.
|
||||
///
|
||||
/// With no arguments, this method returns an 8-tuple with the current
|
||||
/// date and time. With 1 argument (being an 8-tuple) it sets the date
|
||||
/// date and time. With 1 argument (being an 8-tuple) it sets the date
|
||||
/// and time.
|
||||
///
|
||||
/// The 8-tuple has the following format:
|
||||
///
|
||||
/// (year, month, day, weekday, hours, minutes, seconds, milliseconds)
|
||||
///
|
||||
/// `weekday` is 1-7 for Monday through Sunday.
|
||||
/// `weekday` is 0-6 for Monday through Sunday.
|
||||
///
|
||||
mp_obj_t pyb_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
mod_struct_time tm;
|
||||
@@ -143,16 +177,72 @@ mp_obj_t pyb_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_datetime_obj, 1, 2, pyb_rtc_datetime);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_datetime_obj, 1, 2, pyb_rtc_datetime);
|
||||
|
||||
/// \method callback(handler, value, pwrmode)
|
||||
/// Creates a callback object associated with the real time clock
|
||||
/// min num of arguments is 1 (value). The value is the alarm time
|
||||
/// in the future, in msec
|
||||
STATIC mp_obj_t pyb_rtc_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
mp_arg_val_t args[mpcallback_INIT_NUM_ARGS];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mpcallback_INIT_NUM_ARGS, mpcallback_init_args, args);
|
||||
|
||||
// check if any parameters were passed
|
||||
mp_obj_t _callback = mpcallback_find((mp_obj_t)&pyb_rtc_obj);
|
||||
if (kw_args->used > 0 || !_callback) {
|
||||
uint32_t f_mseconds = args[3].u_int;
|
||||
uint32_t seconds;
|
||||
uint16_t mseconds;
|
||||
// get the seconds and the milliseconds from the RTC
|
||||
MAP_PRCMRTCGet(&seconds, &mseconds);
|
||||
mseconds = RTC_CYCLES_U16MS(mseconds);
|
||||
|
||||
// configure the rtc alarm accordingly
|
||||
seconds += f_mseconds / 1000;
|
||||
mseconds += f_mseconds - ((f_mseconds / 1000) * 1000);
|
||||
|
||||
// disable the interrupt before updating anything
|
||||
// (the object is not relevant here, the function already knows it)
|
||||
pyb_rtc_callback_disable(NULL);
|
||||
|
||||
// set the match value
|
||||
MAP_PRCMRTCMatchSet(seconds, mseconds);
|
||||
|
||||
// save the match data for later
|
||||
pybrtc_data.prwmode = args[4].u_int;
|
||||
|
||||
// create the callback
|
||||
_callback = mpcallback_new ((mp_obj_t)&pyb_rtc_obj, args[1].u_obj, &pybrtc_cb_methods);
|
||||
|
||||
// set the lpds callback
|
||||
pybsleep_set_timer_lpds_callback(_callback);
|
||||
|
||||
// the interrupt priority is ignored since is already set to to highest level by the sleep module
|
||||
// to make sure that the wakeup callbacks are always called first when resuming from sleep
|
||||
|
||||
// enable the interrupt (the object is not relevant here, the function already knows it)
|
||||
pyb_rtc_callback_enable(NULL);
|
||||
}
|
||||
return _callback;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_rtc_callback_obj, 1, pyb_rtc_callback);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_rtc_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_datetime), (mp_obj_t)&pyb_rtc_datetime_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&pyb_rtc_callback_obj },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_rtc_locals_dict, pyb_rtc_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t pyb_rtc_type = {
|
||||
STATIC const mp_obj_type_t pyb_rtc_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_RTC,
|
||||
.make_new = pyb_rtc_make_new,
|
||||
.locals_dict = (mp_obj_t)&pyb_rtc_locals_dict,
|
||||
};
|
||||
|
||||
STATIC const mp_cb_methods_t pybrtc_cb_methods = {
|
||||
.init = pyb_rtc_callback,
|
||||
.enable = pyb_rtc_callback_enable,
|
||||
.disable = pyb_rtc_callback_disable,
|
||||
};
|
||||
|
||||
const mp_obj_base_t pyb_rtc_obj = {&pyb_rtc_type};
|
||||
|
||||
@@ -25,9 +25,14 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PYBRTC_H_
|
||||
#define PYBRTC_H_
|
||||
|
||||
#define RTC_U16MS_CYCLES(msec) ((msec * 1024) / 1000)
|
||||
#define RTC_CYCLES_U16MS(cycles) ((cycles * 1000) / 1024)
|
||||
|
||||
extern const mp_obj_type_t pyb_rtc_type;
|
||||
extern const mp_obj_base_t pyb_rtc_obj;
|
||||
|
||||
void pybrtc_init(void);
|
||||
|
||||
#endif // PYBRTC_H_
|
||||
|
||||
209
cc3200/mods/pybsd.c
Normal file
209
cc3200/mods/pybsd.c
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_gpio.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "rom_map.h"
|
||||
#include "pin.h"
|
||||
#include "prcm.h"
|
||||
#include "gpio.h"
|
||||
#include "sdhost.h"
|
||||
#include "pybpin.h"
|
||||
#include "pybsd.h"
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
#include "sd_diskio.h"
|
||||
#include "simplelink.h"
|
||||
#include "debug.h"
|
||||
#include "mpexception.h"
|
||||
#include "pybsleep.h"
|
||||
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
|
||||
#define PYBSD_FREQUENCY_HZ 15000000 // 15MHz
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
FATFS *fatfs;
|
||||
pin_obj_t *pin_clk;
|
||||
bool pinsset;
|
||||
bool enabled;
|
||||
} pybsd_obj_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC pybsd_obj_t pybsd_obj;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC mp_obj_t pybsd_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args);
|
||||
STATIC mp_obj_t pybsd_disable (mp_obj_t self_in);
|
||||
STATIC mp_obj_t pybsd_enable (mp_obj_t self_in);
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
__attribute__ ((section (".boot")))
|
||||
void pybsd_init0 (void) {
|
||||
// allocate memory for the sd file system
|
||||
ASSERT ((pybsd_obj.fatfs = mem_Malloc(sizeof(FATFS))) != NULL);
|
||||
}
|
||||
|
||||
void pybsd_deinit (void) {
|
||||
pybsd_disable ((mp_obj_t)&pybsd_obj);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
/// Initalizes the sd card driver
|
||||
STATIC void pybsd_init (pybsd_obj_t *self) {
|
||||
// Configure the clock pin as output only
|
||||
MAP_PinDirModeSet(self->pin_clk->pin_num, PIN_DIR_MODE_OUT);
|
||||
// Enable SD peripheral clock
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_SDHOST, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
// Reset MMCHS
|
||||
MAP_PRCMPeripheralReset(PRCM_SDHOST);
|
||||
// Initialize MMCHS
|
||||
MAP_SDHostInit(SDHOST_BASE);
|
||||
// Configure the card clock
|
||||
MAP_SDHostSetExpClk(SDHOST_BASE, MAP_PRCMPeripheralClockGet(PRCM_SDHOST), PYBSD_FREQUENCY_HZ);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
//
|
||||
|
||||
/// \classmethod \constructor()
|
||||
/// Configure the pins used for the sd card.
|
||||
/// May receive 0, or 6 arguments.
|
||||
///
|
||||
/// Usage:
|
||||
/// sd = pyb.SD()
|
||||
////
|
||||
/// sd = pyb.SD(d0_pin, d0_af, clk_pin, clk_af, cmd_pin, cmd_af)
|
||||
///
|
||||
STATIC mp_obj_t pybsd_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, 6, false);
|
||||
|
||||
if (n_args == 6) {
|
||||
// save the clock pin for later use
|
||||
pybsd_obj.pin_clk = (pin_obj_t *)pin_find(args[2]);
|
||||
|
||||
// configure the data pin with pull-up enabled
|
||||
pin_config ((pin_obj_t *)pin_find(args[0]), mp_obj_get_int(args[1]), 0, PIN_TYPE_STD_PU, PIN_STRENGTH_4MA);
|
||||
// configure the clock pin
|
||||
pin_config (pybsd_obj.pin_clk, mp_obj_get_int(args[3]), 0, PIN_TYPE_STD, PIN_STRENGTH_4MA);
|
||||
// configure the command pin with pull-up enabled
|
||||
pin_config ((pin_obj_t *)pin_find(args[4]), mp_obj_get_int(args[5]), 0, PIN_TYPE_STD_PU, PIN_STRENGTH_4MA);
|
||||
|
||||
pybsd_obj.pinsset = true;
|
||||
pybsd_obj.base.type = &pyb_sd_type;
|
||||
}
|
||||
else if (!pybsd_obj.pinsset) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments));
|
||||
}
|
||||
|
||||
return &pybsd_obj;
|
||||
}
|
||||
|
||||
/// \method enable()
|
||||
/// Enables the sd card and mounts the file system
|
||||
STATIC mp_obj_t pybsd_enable (mp_obj_t self_in) {
|
||||
pybsd_obj_t *self = self_in;
|
||||
|
||||
if (!self->enabled) {
|
||||
// do the init first
|
||||
pybsd_init (self);
|
||||
|
||||
// try to mount the sd card on /SD
|
||||
if (FR_OK != f_mount(self->fatfs, "/SD", 1)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SD));
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SD_slash_LIB));
|
||||
|
||||
// register it with the sleep module
|
||||
pybsleep_add ((const mp_obj_t)&pybsd_obj, (WakeUpCB_t)pybsd_init);
|
||||
self->enabled = true;
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pybsd_enable_obj, pybsd_enable);
|
||||
|
||||
/// \method disable()
|
||||
/// Disables the sd card and unmounts the file system
|
||||
STATIC mp_obj_t pybsd_disable (mp_obj_t self_in) {
|
||||
pybsd_obj_t *self = self_in;
|
||||
if (self->enabled) {
|
||||
self->enabled = false;
|
||||
// unmount the sd card
|
||||
f_mount (NULL, "/SD", 1);
|
||||
// remove sd paths from mp_sys_path
|
||||
mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SD));
|
||||
mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SD_slash_LIB));
|
||||
|
||||
// disable the peripheral
|
||||
MAP_PRCMPeripheralClkDisable(PRCM_SDHOST, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
|
||||
// de-initialze de sd card at diskio level
|
||||
sd_disk_deinit();
|
||||
|
||||
// unregister it with the sleep module
|
||||
pybsleep_remove (self);
|
||||
|
||||
// change the drive in case it was /SD
|
||||
f_chdrive("/SFLASH");
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pybsd_disable_obj, pybsd_disable);
|
||||
|
||||
STATIC const mp_map_elem_t pybsd_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&pybsd_enable_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable), (mp_obj_t)&pybsd_disable_obj },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(pybsd_locals_dict, pybsd_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t pyb_sd_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_SD,
|
||||
.make_new = pybsd_make_new,
|
||||
.locals_dict = (mp_obj_t)&pybsd_locals_dict,
|
||||
};
|
||||
|
||||
#endif // MICROPY_HW_HAS_SDCARD
|
||||
36
cc3200/mods/pybsd.h
Normal file
36
cc3200/mods/pybsd.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef PYBSD_H_
|
||||
#define PYBSD_H_
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
extern const mp_obj_type_t pyb_sd_type;
|
||||
|
||||
void pybsd_init0 (void);
|
||||
void pybsd_deinit (void);
|
||||
#endif
|
||||
|
||||
#endif // PYBSD_H_
|
||||
668
cc3200/mods/pybsleep.c
Normal file
668
cc3200/mods/pybsleep.c
Normal file
@@ -0,0 +1,668 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <std.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/runtime.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_nvic.h"
|
||||
#include "inc/hw_common_reg.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "cc3200_asm.h"
|
||||
#include "rom_map.h"
|
||||
#include "interrupt.h"
|
||||
#include "systick.h"
|
||||
#include "prcm.h"
|
||||
#include "spi.h"
|
||||
#include "pin.h"
|
||||
#include "pybsleep.h"
|
||||
#include "pybpin.h"
|
||||
#include "simplelink.h"
|
||||
#include "modwlan.h"
|
||||
#include "osi.h"
|
||||
#include "debug.h"
|
||||
#include "mpexception.h"
|
||||
#include "mpcallback.h"
|
||||
#include "mperror.h"
|
||||
#include "sleeprestore.h"
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define SPIFLASH_INSTR_READ_STATUS (0x05)
|
||||
#define SPIFLASH_INSTR_DEEP_POWER_DOWN (0xB9)
|
||||
#define SPIFLASH_STATUS_BUSY (0x01)
|
||||
|
||||
#define LPDS_UP_TIME (425) // 13 msec
|
||||
#define LPDS_DOWN_TIME (98) // 3 msec
|
||||
#define USER_OFFSET (131) // 4 smec
|
||||
#define WAKEUP_TIME_LPDS (LPDS_UP_TIME + LPDS_DOWN_TIME + USER_OFFSET) // 20 msec
|
||||
#define WAKEUP_TIME_HIB (32768) // 1 s
|
||||
|
||||
#define FORCED_TIMER_INTERRUPT_MS (1)
|
||||
#define FAILED_SLEEP_DELAY_MS (FORCED_TIMER_INTERRUPT_MS * 3)
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE TYPES
|
||||
******************************************************************************/
|
||||
// storage memory for Cortex M4 registers
|
||||
typedef struct {
|
||||
uint32_t msp;
|
||||
uint32_t psp;
|
||||
uint32_t psr;
|
||||
uint32_t primask;
|
||||
uint32_t faultmask;
|
||||
uint32_t basepri;
|
||||
uint32_t control;
|
||||
} arm_cm4_core_regs_t;
|
||||
|
||||
// storage memory for the NVIC registers
|
||||
typedef struct {
|
||||
uint32_t vector_table; // Vector Table Offset
|
||||
uint32_t aux_ctrl; // Auxiliary control register
|
||||
uint32_t int_ctrl_state; // Interrupt Control and State
|
||||
uint32_t app_int; // Application Interrupt Reset control
|
||||
uint32_t sys_ctrl; // System control
|
||||
uint32_t config_ctrl; // Configuration control
|
||||
uint32_t sys_pri_1; // System Handler Priority 1
|
||||
uint32_t sys_pri_2; // System Handler Priority 2
|
||||
uint32_t sys_pri_3; // System Handler Priority 3
|
||||
uint32_t sys_hcrs; // System Handler control and state register
|
||||
uint32_t systick_ctrl; // SysTick Control Status
|
||||
uint32_t systick_reload; // SysTick Reload
|
||||
uint32_t systick_calib; // SysTick Calibration
|
||||
uint32_t int_en[6]; // Interrupt set enable
|
||||
uint32_t int_priority[49]; // Interrupt priority
|
||||
} nvic_reg_store_t;
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t obj;
|
||||
WakeUpCB_t wakeup;
|
||||
} pybsleep_obj_t;
|
||||
|
||||
typedef struct {
|
||||
mp_obj_t wlan_lpds_wake_cb;
|
||||
mp_obj_t timer_lpds_wake_cb;
|
||||
mp_obj_t gpio_lpds_wake_cb;
|
||||
uint timer_wake_pwrmode;
|
||||
} pybsleep_data_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC const mp_obj_type_t pybsleep_type;
|
||||
STATIC nvic_reg_store_t *nvic_reg_store;
|
||||
STATIC pybsleep_data_t pybsleep_data = {NULL, NULL, NULL, 0};
|
||||
volatile arm_cm4_core_regs_t vault_arm_registers;
|
||||
STATIC pybsleep_reset_cause_t pybsleep_reset_cause = PYB_SLP_PWRON_RESET;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC pybsleep_obj_t *pybsleep_find (mp_obj_t obj);
|
||||
STATIC void pybsleep_flash_powerdown (void);
|
||||
STATIC NORETURN void pybsleep_suspend_enter (void);
|
||||
void pybsleep_suspend_exit (void);
|
||||
STATIC void pybsleep_obj_wakeup (void);
|
||||
STATIC void PRCMInterruptHandler (void);
|
||||
STATIC void pybsleep_iopark (void);
|
||||
STATIC bool setup_timer_lpds_wake (void);
|
||||
STATIC bool setup_timer_hibernate_wake (void);
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
__attribute__ ((section (".boot")))
|
||||
void pybsleep_pre_init (void) {
|
||||
// allocate memory for nvic registers vault
|
||||
ASSERT ((nvic_reg_store = mem_Malloc(sizeof(nvic_reg_store_t))) != NULL);
|
||||
}
|
||||
|
||||
void pybsleep_init0 (void) {
|
||||
// initialize the sleep objects list
|
||||
mp_obj_list_init(&MP_STATE_PORT(pybsleep_obj_list), 0);
|
||||
|
||||
// register and enable the PRCM interrupt
|
||||
osi_InterruptRegister(INT_PRCM, (P_OSI_INTR_ENTRY)PRCMInterruptHandler, INT_PRIORITY_LVL_1);
|
||||
|
||||
// disable all LPDS and hibernate wake up sources (WLAN is disabed/enabled before entering LDPS mode)
|
||||
MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_GPIO);
|
||||
MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_TIMER);
|
||||
MAP_PRCMHibernateWakeupSourceDisable(PRCM_HIB_SLOW_CLK_CTR | PRCM_HIB_GPIO2 | PRCM_HIB_GPIO4 | PRCM_HIB_GPIO13 |
|
||||
PRCM_HIB_GPIO17 | PRCM_HIB_GPIO11 | PRCM_HIB_GPIO24 | PRCM_HIB_GPIO26);
|
||||
|
||||
// store the reset casue (if it's soft reset, leave it as it is)
|
||||
if (pybsleep_reset_cause != PYB_SLP_SOFT_RESET) {
|
||||
switch (MAP_PRCMSysResetCauseGet()) {
|
||||
case PRCM_POWER_ON:
|
||||
pybsleep_reset_cause = PYB_SLP_PWRON_RESET;
|
||||
break;
|
||||
case PRCM_CORE_RESET:
|
||||
case PRCM_MCU_RESET:
|
||||
case PRCM_SOC_RESET:
|
||||
pybsleep_reset_cause = PYB_SLP_HARD_RESET;
|
||||
break;
|
||||
case PRCM_WDT_RESET:
|
||||
pybsleep_reset_cause = PYB_SLP_WDT_RESET;
|
||||
break;
|
||||
case PRCM_HIB_EXIT:
|
||||
if (PRCMWasResetBecauseOfWDT()) {
|
||||
pybsleep_reset_cause = PYB_SLP_WDT_RESET;
|
||||
}
|
||||
else {
|
||||
pybsleep_reset_cause = PYB_SLP_HIB_RESET;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pybsleep_signal_soft_reset (void) {
|
||||
pybsleep_reset_cause = PYB_SLP_SOFT_RESET;
|
||||
}
|
||||
|
||||
void pybsleep_add (const mp_obj_t obj, WakeUpCB_t wakeup) {
|
||||
pybsleep_obj_t * sleep_obj = m_new_obj(pybsleep_obj_t);
|
||||
sleep_obj->base.type = &pybsleep_type;
|
||||
sleep_obj->obj = obj;
|
||||
sleep_obj->wakeup = wakeup;
|
||||
// only add objects once
|
||||
if (!pybsleep_find(sleep_obj)) {
|
||||
mp_obj_list_append(&MP_STATE_PORT(pybsleep_obj_list), sleep_obj);
|
||||
}
|
||||
}
|
||||
|
||||
void pybsleep_remove (const mp_obj_t obj) {
|
||||
pybsleep_obj_t *sleep_obj;
|
||||
if ((sleep_obj = pybsleep_find(obj))) {
|
||||
mp_obj_list_remove(&MP_STATE_PORT(pybsleep_obj_list), sleep_obj);
|
||||
}
|
||||
}
|
||||
|
||||
void pybsleep_set_wlan_lpds_callback (mp_obj_t cb_obj) {
|
||||
pybsleep_data.wlan_lpds_wake_cb = cb_obj;
|
||||
}
|
||||
|
||||
void pybsleep_set_gpio_lpds_callback (mp_obj_t cb_obj) {
|
||||
pybsleep_data.gpio_lpds_wake_cb = cb_obj;
|
||||
}
|
||||
|
||||
void pybsleep_set_timer_lpds_callback (mp_obj_t cb_obj) {
|
||||
pybsleep_data.timer_lpds_wake_cb = cb_obj;
|
||||
}
|
||||
|
||||
void pybsleep_configure_timer_wakeup (uint pwrmode) {
|
||||
pybsleep_data.timer_wake_pwrmode = pwrmode;
|
||||
}
|
||||
|
||||
pybsleep_reset_cause_t pybsleep_get_reset_cause (void) {
|
||||
return pybsleep_reset_cause;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC pybsleep_obj_t *pybsleep_find (mp_obj_t obj) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(pybsleep_obj_list).len; i++) {
|
||||
// search for the object and then remove it
|
||||
pybsleep_obj_t *sleep_obj = ((pybsleep_obj_t *)(MP_STATE_PORT(pybsleep_obj_list).items[i]));
|
||||
if (sleep_obj->obj == obj) {
|
||||
return sleep_obj;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC void pybsleep_flash_powerdown (void) {
|
||||
uint32_t status;
|
||||
|
||||
// Enable clock for SSPI module
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_SSPI, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
// Reset SSPI at PRCM level and wait for reset to complete
|
||||
MAP_PRCMPeripheralReset(PRCM_SSPI);
|
||||
while(!MAP_PRCMPeripheralStatusGet(PRCM_SSPI));
|
||||
|
||||
// Reset SSPI at module level
|
||||
MAP_SPIReset(SSPI_BASE);
|
||||
// Configure SSPI module
|
||||
MAP_SPIConfigSetExpClk (SSPI_BASE, PRCMPeripheralClockGet(PRCM_SSPI),
|
||||
20000000, SPI_MODE_MASTER,SPI_SUB_MODE_0,
|
||||
(SPI_SW_CTRL_CS |
|
||||
SPI_4PIN_MODE |
|
||||
SPI_TURBO_OFF |
|
||||
SPI_CS_ACTIVELOW |
|
||||
SPI_WL_8));
|
||||
|
||||
// Enable SSPI module
|
||||
MAP_SPIEnable(SSPI_BASE);
|
||||
// Enable chip select for the spi flash.
|
||||
MAP_SPICSEnable(SSPI_BASE);
|
||||
// Wait for the spi flash
|
||||
do {
|
||||
// Send the status register read instruction and read back a dummy byte.
|
||||
MAP_SPIDataPut(SSPI_BASE, SPIFLASH_INSTR_READ_STATUS);
|
||||
MAP_SPIDataGet(SSPI_BASE, &status);
|
||||
|
||||
// Write a dummy byte then read back the actual status.
|
||||
MAP_SPIDataPut(SSPI_BASE, 0xFF);
|
||||
MAP_SPIDataGet(SSPI_BASE, &status);
|
||||
} while ((status & 0xFF) == SPIFLASH_STATUS_BUSY);
|
||||
|
||||
// Disable chip select for the spi flash.
|
||||
MAP_SPICSDisable(SSPI_BASE);
|
||||
// Start another CS enable sequence for Power down command.
|
||||
MAP_SPICSEnable(SSPI_BASE);
|
||||
// Send Deep Power Down command to spi flash
|
||||
MAP_SPIDataPut(SSPI_BASE, SPIFLASH_INSTR_DEEP_POWER_DOWN);
|
||||
// Disable chip select for the spi flash.
|
||||
MAP_SPICSDisable(SSPI_BASE);
|
||||
}
|
||||
|
||||
STATIC NORETURN void pybsleep_suspend_enter (void) {
|
||||
// enable full RAM retention
|
||||
MAP_PRCMSRAMRetentionEnable(PRCM_SRAM_COL_1 | PRCM_SRAM_COL_2 | PRCM_SRAM_COL_3 | PRCM_SRAM_COL_4, PRCM_SRAM_LPDS_RET);
|
||||
|
||||
// save the NVIC control registers
|
||||
nvic_reg_store->vector_table = HWREG(NVIC_VTABLE);
|
||||
nvic_reg_store->aux_ctrl = HWREG(NVIC_ACTLR);
|
||||
nvic_reg_store->int_ctrl_state = HWREG(NVIC_INT_CTRL);
|
||||
nvic_reg_store->app_int = HWREG(NVIC_APINT);
|
||||
nvic_reg_store->sys_ctrl = HWREG(NVIC_SYS_CTRL);
|
||||
nvic_reg_store->config_ctrl = HWREG(NVIC_CFG_CTRL);
|
||||
nvic_reg_store->sys_pri_1 = HWREG(NVIC_SYS_PRI1);
|
||||
nvic_reg_store->sys_pri_2 = HWREG(NVIC_SYS_PRI2);
|
||||
nvic_reg_store->sys_pri_3 = HWREG(NVIC_SYS_PRI3);
|
||||
nvic_reg_store->sys_hcrs = HWREG(NVIC_SYS_HND_CTRL);
|
||||
|
||||
// save the systick registers
|
||||
nvic_reg_store->systick_ctrl = HWREG(NVIC_ST_CTRL);
|
||||
nvic_reg_store->systick_reload = HWREG(NVIC_ST_RELOAD);
|
||||
nvic_reg_store->systick_calib = HWREG(NVIC_ST_CAL);
|
||||
|
||||
// save the interrupt enable registers
|
||||
uint32_t *base_reg_addr = (uint32_t *)NVIC_EN0;
|
||||
for(int32_t i = 0; i < (sizeof(nvic_reg_store->int_en) / 4); i++) {
|
||||
nvic_reg_store->int_en[i] = base_reg_addr[i];
|
||||
}
|
||||
|
||||
// save the interrupt priority registers
|
||||
base_reg_addr = (uint32_t *)NVIC_PRI0;
|
||||
for(int32_t i = 0; i < (sizeof(nvic_reg_store->int_priority) / 4); i++) {
|
||||
nvic_reg_store->int_priority[i] = base_reg_addr[i];
|
||||
}
|
||||
|
||||
// switch off the heartbeat led (this makes sure it will blink as soon as we wake up)
|
||||
mperror_heartbeat_switch_off();
|
||||
|
||||
// park the gpio pins
|
||||
pybsleep_iopark();
|
||||
|
||||
// store the cpu registers
|
||||
sleep_store();
|
||||
|
||||
// save the restore info and enter LPDS
|
||||
MAP_PRCMLPDSRestoreInfoSet(vault_arm_registers.psp, (uint32_t)sleep_restore);
|
||||
MAP_PRCMLPDSEnter();
|
||||
|
||||
// let the cpu fade away...
|
||||
for ( ; ; );
|
||||
}
|
||||
|
||||
void pybsleep_suspend_exit (void) {
|
||||
// take the I2C semaphore
|
||||
uint32_t reg = HWREG(COMMON_REG_BASE + COMMON_REG_O_I2C_Properties_Register);
|
||||
reg = (reg & ~0x3) | 0x1;
|
||||
HWREG(COMMON_REG_BASE + COMMON_REG_O_I2C_Properties_Register) = reg;
|
||||
|
||||
// take the GPIO semaphore
|
||||
reg = HWREG(COMMON_REG_BASE + COMMON_REG_O_GPIO_properties_register);
|
||||
reg = (reg & ~0x3FF) | 0x155;
|
||||
HWREG(COMMON_REG_BASE + COMMON_REG_O_GPIO_properties_register) = reg;
|
||||
|
||||
// restore de NVIC control registers
|
||||
HWREG(NVIC_VTABLE) = nvic_reg_store->vector_table;
|
||||
HWREG(NVIC_ACTLR) = nvic_reg_store->aux_ctrl;
|
||||
HWREG(NVIC_INT_CTRL) = nvic_reg_store->int_ctrl_state;
|
||||
HWREG(NVIC_APINT) = nvic_reg_store->app_int;
|
||||
HWREG(NVIC_SYS_CTRL) = nvic_reg_store->sys_ctrl;
|
||||
HWREG(NVIC_CFG_CTRL) = nvic_reg_store->config_ctrl;
|
||||
HWREG(NVIC_SYS_PRI1) = nvic_reg_store->sys_pri_1;
|
||||
HWREG(NVIC_SYS_PRI2) = nvic_reg_store->sys_pri_2;
|
||||
HWREG(NVIC_SYS_PRI3) = nvic_reg_store->sys_pri_3;
|
||||
HWREG(NVIC_SYS_HND_CTRL) = nvic_reg_store->sys_hcrs;
|
||||
|
||||
// restore the systick register
|
||||
HWREG(NVIC_ST_CTRL) = nvic_reg_store->systick_ctrl;
|
||||
HWREG(NVIC_ST_RELOAD) = nvic_reg_store->systick_reload;
|
||||
HWREG(NVIC_ST_CAL) = nvic_reg_store->systick_calib;
|
||||
|
||||
// restore the interrupt priority registers
|
||||
uint32_t *base_reg_addr = (uint32_t *)NVIC_PRI0;
|
||||
for (uint32_t i = 0; i < (sizeof(nvic_reg_store->int_priority) / 4); i++) {
|
||||
base_reg_addr[i] = nvic_reg_store->int_priority[i];
|
||||
}
|
||||
|
||||
// restore the interrupt enable registers
|
||||
base_reg_addr = (uint32_t *)NVIC_EN0;
|
||||
for(uint32_t i = 0; i < (sizeof(nvic_reg_store->int_en) / 4); i++) {
|
||||
base_reg_addr[i] = nvic_reg_store->int_en[i];
|
||||
}
|
||||
|
||||
HAL_INTRODUCE_SYNC_BARRIER();
|
||||
|
||||
// ungate the clock to the shared spi bus
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_SSPI, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
|
||||
// reinitialize simplelink's interface
|
||||
sl_IfOpen (NULL, 0);
|
||||
|
||||
// restore the configuration of all active peripherals
|
||||
pybsleep_obj_wakeup();
|
||||
|
||||
// reconfigure all the previously enabled interrupts
|
||||
mpcallback_wake_all();
|
||||
|
||||
// trigger a sw interrupt
|
||||
MAP_IntPendSet(INT_PRCM);
|
||||
|
||||
// force an exception to go back to the point where suspend mode was entered
|
||||
nlr_raise(mp_obj_new_exception(&mp_type_SystemExit));
|
||||
}
|
||||
|
||||
STATIC void PRCMInterruptHandler (void) {
|
||||
// reading the interrupt status automatically clears the interrupt
|
||||
if (PRCM_INT_SLOW_CLK_CTR == MAP_PRCMIntStatus()) {
|
||||
// this interrupt is triggered during active mode
|
||||
mpcallback_handler(pybsleep_data.timer_lpds_wake_cb);
|
||||
}
|
||||
else {
|
||||
// interrupt has been triggered while waking up from LPDS
|
||||
switch (MAP_PRCMLPDSWakeupCauseGet()) {
|
||||
case PRCM_LPDS_HOST_IRQ:
|
||||
mpcallback_handler(pybsleep_data.wlan_lpds_wake_cb);
|
||||
break;
|
||||
case PRCM_LPDS_GPIO:
|
||||
mpcallback_handler(pybsleep_data.gpio_lpds_wake_cb);
|
||||
break;
|
||||
case PRCM_LPDS_TIMER:
|
||||
// disable the timer as a wake-up source
|
||||
pybsleep_data.timer_wake_pwrmode &= ~PYB_PWR_MODE_LPDS;
|
||||
MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_TIMER);
|
||||
mpcallback_handler(pybsleep_data.timer_lpds_wake_cb);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void pybsleep_obj_wakeup (void) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(pybsleep_obj_list).len; i++) {
|
||||
pybsleep_obj_t *sleep_obj = ((pybsleep_obj_t *)MP_STATE_PORT(pybsleep_obj_list).items[i]);
|
||||
sleep_obj->wakeup(sleep_obj->obj);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void pybsleep_iopark (void) {
|
||||
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)&pin_cpu_pins_locals_dict);
|
||||
for (uint i = 0; i < named_map->used; i++) {
|
||||
pin_obj_t * pin = (pin_obj_t *)named_map->table[i].value;
|
||||
// skip the sflash pins since these are shared with the network processor
|
||||
switch (pin->pin_num) {
|
||||
case PIN_11:
|
||||
case PIN_12:
|
||||
case PIN_13:
|
||||
case PIN_14:
|
||||
#ifdef DEBUG
|
||||
// also skip the JTAG pins
|
||||
case PIN_16:
|
||||
case PIN_17:
|
||||
case PIN_19:
|
||||
case PIN_20:
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
// enable a weak pull-down if the pin is unused
|
||||
if (!pin->isused) {
|
||||
MAP_PinConfigSet(pin->pin_num, pin->strength, PIN_TYPE_STD_PD);
|
||||
}
|
||||
// make it an input
|
||||
MAP_PinDirModeSet(pin->pin_num, PIN_DIR_MODE_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// park the sflash pins
|
||||
HWREG(0x4402E0E8) &= ~(0x3 << 8);
|
||||
HWREG(0x4402E0E8) |= (0x2 << 8);
|
||||
HWREG(0x4402E0EC) &= ~(0x3 << 8);
|
||||
HWREG(0x4402E0EC) |= (0x2 << 8);
|
||||
HWREG(0x4402E0F0) &= ~(0x3 << 8);
|
||||
HWREG(0x4402E0F0) |= (0x2 << 8);
|
||||
HWREG(0x4402E0F4) &= ~(0x3 << 8);
|
||||
HWREG(0x4402E0F4) |= (0x1 << 8);
|
||||
|
||||
// park the antenna selection pins
|
||||
HWREG(0x4402E108) = 0x00000E61;
|
||||
HWREG(0x4402E10C) = 0x00000E61;
|
||||
}
|
||||
|
||||
STATIC bool setup_timer_lpds_wake (void) {
|
||||
uint64_t t_match, t_curr, t_remaining;
|
||||
|
||||
// get the time remaining for the RTC timer to expire
|
||||
t_match = MAP_PRCMSlowClkCtrMatchGet();
|
||||
t_curr = MAP_PRCMSlowClkCtrGet();
|
||||
|
||||
if (t_match > t_curr) {
|
||||
// get the time remaining in terms of slow clocks
|
||||
t_remaining = (t_match - t_curr);
|
||||
if (t_remaining > WAKEUP_TIME_LPDS) {
|
||||
// subtract the time it takes for wakeup from lpds
|
||||
t_remaining -= WAKEUP_TIME_LPDS;
|
||||
t_remaining = (t_remaining > 0xFFFFFFFF) ? 0xFFFFFFFF: t_remaining;
|
||||
// setup the LPDS wake time
|
||||
MAP_PRCMLPDSIntervalSet((uint32_t)t_remaining);
|
||||
// enable the wake source
|
||||
MAP_PRCMLPDSWakeupSourceEnable(PRCM_LPDS_TIMER);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// setup a timer interrupt immediately
|
||||
MAP_PRCMRTCMatchSet(0, FORCED_TIMER_INTERRUPT_MS);
|
||||
}
|
||||
|
||||
// disable the timer as wake source
|
||||
MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_TIMER);
|
||||
|
||||
// LPDS wake by timer was not possible, force
|
||||
// an interrupt in active mode instead
|
||||
MAP_PRCMIntEnable(PRCM_INT_SLOW_CLK_CTR);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
STATIC bool setup_timer_hibernate_wake (void) {
|
||||
uint64_t t_match, t_curr, t_remaining;
|
||||
|
||||
// get the time remaining for the RTC timer to expire
|
||||
t_match = MAP_PRCMSlowClkCtrMatchGet();
|
||||
t_curr = MAP_PRCMSlowClkCtrGet();
|
||||
|
||||
if (t_match > t_curr) {
|
||||
// get the time remaining in terms of slow clocks
|
||||
t_remaining = (t_match - t_curr);
|
||||
if (t_remaining > WAKEUP_TIME_HIB) {
|
||||
// subtract the time it takes for wakeup from hibernate
|
||||
t_remaining -= WAKEUP_TIME_HIB;
|
||||
// setup the LPDS wake time
|
||||
MAP_PRCMHibernateIntervalSet((uint32_t)t_remaining);
|
||||
// enable the wake source
|
||||
MAP_PRCMHibernateWakeupSourceEnable(PRCM_HIB_SLOW_CLK_CTR);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// setup a timer interrupt immediately
|
||||
MAP_PRCMRTCMatchSet(0, FORCED_TIMER_INTERRUPT_MS);
|
||||
}
|
||||
|
||||
// disable the timer as wake source
|
||||
MAP_PRCMLPDSWakeupSourceDisable(PRCM_HIB_SLOW_CLK_CTR);
|
||||
|
||||
// hibernate wake by timer was not possible, force
|
||||
// an interrupt in active mode instead
|
||||
MAP_PRCMIntEnable(PRCM_INT_SLOW_CLK_CTR);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings; Sleep class
|
||||
|
||||
/// \function idle()
|
||||
/// Gates the processor clock until an interrupt is triggered
|
||||
STATIC mp_obj_t pyb_sleep_idle (mp_obj_t self_in) {
|
||||
__WFI();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_idle_obj, pyb_sleep_idle);
|
||||
|
||||
/// \function suspend(wlan)
|
||||
/// Enters suspended mode. Wake up sources should have been enable prior to
|
||||
/// calling this method.
|
||||
STATIC mp_obj_t pyb_sleep_suspend (mp_obj_t self_in) {
|
||||
nlr_buf_t nlr;
|
||||
|
||||
// check if we should enable timer wake-up
|
||||
if (pybsleep_data.timer_wake_pwrmode & PYB_PWR_MODE_LPDS) {
|
||||
if (!setup_timer_lpds_wake()) {
|
||||
// lpds entering is not possible, wait for the forced interrupt and return
|
||||
pybsleep_data.timer_wake_pwrmode &= ~PYB_PWR_MODE_LPDS;
|
||||
HAL_Delay (FAILED_SLEEP_DELAY_MS);
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
|
||||
// do we need network wake-up?
|
||||
if (pybsleep_data.wlan_lpds_wake_cb) {
|
||||
MAP_PRCMLPDSWakeupSourceEnable (PRCM_LPDS_HOST_IRQ);
|
||||
}
|
||||
else {
|
||||
MAP_PRCMLPDSWakeupSourceDisable (PRCM_LPDS_HOST_IRQ);
|
||||
}
|
||||
|
||||
// entering and exiting suspended mode must be an atomic operation
|
||||
// therefore interrupts need to be disabled
|
||||
uint primsk = disable_irq();
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
pybsleep_suspend_enter();
|
||||
nlr_pop();
|
||||
}
|
||||
|
||||
// an exception is always raised when exiting suspend mode
|
||||
enable_irq(primsk);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_suspend_obj, pyb_sleep_suspend);
|
||||
|
||||
/// \function hibernate()
|
||||
/// Enters hibernate mode. Wake up sources should have been enable prior to
|
||||
/// calling this method.
|
||||
STATIC mp_obj_t pyb_sleep_hibernate (mp_obj_t self_in) {
|
||||
// check if we should enable timer wake-up
|
||||
if (pybsleep_data.timer_wake_pwrmode & PYB_PWR_MODE_HIBERNATE) {
|
||||
if (!setup_timer_hibernate_wake()) {
|
||||
// hibernating is not possible, wait for the forced interrupt and return
|
||||
pybsleep_data.timer_wake_pwrmode &= ~PYB_PWR_MODE_HIBERNATE;
|
||||
HAL_Delay (FAILED_SLEEP_DELAY_MS);
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
wlan_stop(SL_STOP_TIMEOUT);
|
||||
pybsleep_flash_powerdown();
|
||||
// must be done just before entering hibernate mode
|
||||
pybsleep_iopark();
|
||||
MAP_PRCMHibernateEnter();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_hibernate_obj, pyb_sleep_hibernate);
|
||||
|
||||
/// \function reset_cause()
|
||||
/// Returns the last reset casue
|
||||
STATIC mp_obj_t pyb_sleep_reset_cause (mp_obj_t self_in) {
|
||||
return MP_OBJ_NEW_SMALL_INT(pybsleep_reset_cause);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_reset_cause_obj, pyb_sleep_reset_cause);
|
||||
|
||||
/// \function wake_reason()
|
||||
/// Returns the wake up reson from ldps or hibernate
|
||||
STATIC mp_obj_t pyb_sleep_wake_reason (mp_obj_t self_in) {
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_wake_reason_obj, pyb_sleep_wake_reason);
|
||||
|
||||
STATIC const mp_map_elem_t pybsleep_locals_dict_table[] = {
|
||||
// instance methods
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_idle), (mp_obj_t)&pyb_sleep_idle_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_suspend), (mp_obj_t)&pyb_sleep_suspend_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_hibernate), (mp_obj_t)&pyb_sleep_hibernate_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_reset_cause), (mp_obj_t)&pyb_sleep_reset_cause_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_wake_reason), (mp_obj_t)&pyb_sleep_wake_reason_obj },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ACTIVE), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_ACTIVE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SUSPENDED), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_LPDS) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_HIBERNATING), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_HIBERNATE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PWR_ON_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_PWRON_RESET) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_HARD_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_HARD_RESET) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WDT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WDT_RESET) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_HIB_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_HIB_RESET) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SOFT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_SOFT_RESET) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WLAN_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_WLAN) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PIN_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_PIN) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_RTC_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_RTC) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pybsleep_locals_dict, pybsleep_locals_dict_table);
|
||||
|
||||
STATIC const mp_obj_type_t pybsleep_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_sleep,
|
||||
.locals_dict = (mp_obj_t)&pybsleep_locals_dict,
|
||||
};
|
||||
|
||||
const mp_obj_base_t pyb_sleep_obj = {&pybsleep_type};
|
||||
78
cc3200/mods/pybsleep.h
Normal file
78
cc3200/mods/pybsleep.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PYBSLEEP_H_
|
||||
#define PYBSLEEP_H_
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYB_PWR_MODE_ACTIVE (0x01)
|
||||
#define PYB_PWR_MODE_LPDS (0x02)
|
||||
#define PYB_PWR_MODE_HIBERNATE (0x04)
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
******************************************************************************/
|
||||
typedef enum {
|
||||
PYB_SLP_PWRON_RESET = 0,
|
||||
PYB_SLP_HARD_RESET,
|
||||
PYB_SLP_WDT_RESET,
|
||||
PYB_SLP_HIB_RESET,
|
||||
PYB_SLP_SOFT_RESET,
|
||||
|
||||
} pybsleep_reset_cause_t;
|
||||
|
||||
typedef enum {
|
||||
PYB_SLP_WAKED_BY_WLAN,
|
||||
PYB_SLP_WAKED_BY_PIN,
|
||||
PYB_SLP_WAKED_BY_RTC
|
||||
|
||||
} pybsleep_wake_reason_t;
|
||||
|
||||
typedef void (*WakeUpCB_t)(const mp_obj_t self);
|
||||
typedef void (*DeinitCB_t)(const mp_obj_t self);
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE EXPORTED VARIABLES
|
||||
******************************************************************************/
|
||||
extern const mp_obj_base_t pyb_sleep_obj;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE FUNCTIONS
|
||||
******************************************************************************/
|
||||
void pybsleep_pre_init (void);
|
||||
void pybsleep_init0 (void);
|
||||
void pybsleep_signal_soft_reset (void);
|
||||
void pybsleep_add (const mp_obj_t obj, WakeUpCB_t wakeup);
|
||||
void pybsleep_remove (const mp_obj_t obj);
|
||||
void pybsleep_set_wlan_lpds_callback (mp_obj_t cb_obj);
|
||||
void pybsleep_set_gpio_lpds_callback (mp_obj_t cb_obj);
|
||||
void pybsleep_set_timer_lpds_callback (mp_obj_t cb_obj);
|
||||
void pybsleep_configure_timer_wakeup (uint pwrmode);
|
||||
pybsleep_reset_cause_t pybsleep_get_reset_cause (void);
|
||||
|
||||
#endif /* PYBSLEEP_H_ */
|
||||
411
cc3200/mods/pybspi.c
Normal file
411
cc3200/mods/pybspi.c
Normal file
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/runtime.h"
|
||||
#include "bufhelper.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_mcspi.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "rom_map.h"
|
||||
#include "pin.h"
|
||||
#include "prcm.h"
|
||||
#include "spi.h"
|
||||
#include "pybspi.h"
|
||||
#include "mpexception.h"
|
||||
#include "pybsleep.h"
|
||||
|
||||
/// \moduleref pyb
|
||||
/// \class SPI - a master-driven serial protocol
|
||||
///
|
||||
/// SPI is a serial protocol that is driven by a master. At the physical level
|
||||
/// there are 3 lines: SCK, MOSI, MISO.
|
||||
///
|
||||
/// See usage model of I2C; SPI is very similar. Main difference is
|
||||
/// parameters to init the SPI bus:
|
||||
///
|
||||
/// from pyb import SPI
|
||||
/// spi = SPI(2000000, bits=8, submode=0, cs=SPI.ACTIVE_LOW)
|
||||
///
|
||||
/// Only required parameter is the baudrate, in Hz. Submode may be 0-3.
|
||||
/// Bit accepts 8, 16, 32. Chip select values are ACTIVE_LOW and ACTIVE_HIGH
|
||||
///
|
||||
/// Additional method for SPI:
|
||||
///
|
||||
/// data = spi.send_recv(b'1234') # send 4 bytes and receive 4 bytes
|
||||
/// buf = bytearray(4)
|
||||
/// spi.send_recv(b'1234', buf) # send 4 bytes and receive 4 into buf
|
||||
/// spi.send_recv(buf, buf) # send/recv 4 bytes from/to buf
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
******************************************************************************/
|
||||
typedef struct _pyb_spi_obj_t {
|
||||
mp_obj_base_t base;
|
||||
uint baudrate;
|
||||
uint config;
|
||||
vstr_t tx_vstr;
|
||||
vstr_t rx_vstr;
|
||||
uint tx_index;
|
||||
uint rx_index;
|
||||
byte submode;
|
||||
byte wlen;
|
||||
} pyb_spi_obj_t;
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYBSPI_DEF_BAUDRATE 1000000 // 1MHz
|
||||
#define PYBSPI_CS_NONE 0xFF // spi cs is controlled by the user
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC pyb_spi_obj_t pyb_spi_obj = {.baudrate = 0};
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
// only master mode is available for the moment
|
||||
STATIC void pybspi_init (const pyb_spi_obj_t *self) {
|
||||
// enable the peripheral clock
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_GSPI, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
MAP_PRCMPeripheralReset(PRCM_GSPI);
|
||||
MAP_SPIReset(GSPI_BASE);
|
||||
|
||||
// configure the interface (only master mode supported)
|
||||
MAP_SPIConfigSetExpClk (GSPI_BASE, MAP_PRCMPeripheralClockGet(PRCM_GSPI),
|
||||
self->baudrate, SPI_MODE_MASTER, self->submode, self->config);
|
||||
|
||||
// enable the interface
|
||||
MAP_SPIEnable(GSPI_BASE);
|
||||
}
|
||||
|
||||
STATIC void pybspi_tx (pyb_spi_obj_t *self, const void *data) {
|
||||
uint32_t txdata = 0xFFFFFFFF;
|
||||
if (data) {
|
||||
switch (self->wlen) {
|
||||
case 1:
|
||||
txdata = (uint8_t)(*(char *)data);
|
||||
break;
|
||||
case 2:
|
||||
txdata = (uint16_t)(*(uint16_t *)data);
|
||||
break;
|
||||
case 4:
|
||||
txdata = (uint32_t)(*(uint32_t *)data);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
MAP_SPIDataPut (GSPI_BASE, txdata);
|
||||
}
|
||||
|
||||
STATIC void pybspi_rx (pyb_spi_obj_t *self, void *data) {
|
||||
uint32_t rxdata;
|
||||
MAP_SPIDataGet (GSPI_BASE, &rxdata);
|
||||
if (data) {
|
||||
switch (self->wlen) {
|
||||
case 1:
|
||||
*(char *)data = rxdata;
|
||||
break;
|
||||
case 2:
|
||||
*(uint16_t *)data = rxdata;
|
||||
break;
|
||||
case 4:
|
||||
*(uint32_t *)data = rxdata;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void pybspi_transfer (pyb_spi_obj_t *self, const char *txdata, char *rxdata, uint32_t len) {
|
||||
// send and receive the data
|
||||
MAP_SPICSEnable(GSPI_BASE);
|
||||
for (int i = 0; i < len / self->wlen; i += self->wlen) {
|
||||
pybspi_tx(self, txdata ? (const void *)&txdata[i] : NULL);
|
||||
pybspi_rx(self, rxdata ? (void *)&rxdata[i] : NULL);
|
||||
}
|
||||
MAP_SPICSDisable(GSPI_BASE);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings */
|
||||
/******************************************************************************/
|
||||
STATIC void pyb_spi_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_spi_obj_t *self = self_in;
|
||||
|
||||
if (self->baudrate > 0) {
|
||||
print(env, "<SPI0, SPI.MASTER, baudrate=%u, config=%u, submode=%u, bits=%u>",
|
||||
self->baudrate, self->config, self->submode, (self->wlen * 8));
|
||||
}
|
||||
else {
|
||||
print(env, "<SPI0>");
|
||||
}
|
||||
}
|
||||
|
||||
/// \method init(2000000, *, bits=8, submode=0, cs=SPI.ACTIVELOW)
|
||||
///
|
||||
/// Initialise the SPI bus with the given parameters:
|
||||
///
|
||||
/// - `baudrate` is the SCK clock rate.
|
||||
/// - `bits` is the transfer width size (8, 16, 32).
|
||||
/// - `submode` is the spi mode (0, 1, 2, 3).
|
||||
/// - `cs` can be ACTIVELOW, ACTIVEHIGH, or NONE
|
||||
static const mp_arg_t pybspi_init_args[] = {
|
||||
{ MP_QSTR_baudrate, MP_ARG_REQUIRED | MP_ARG_INT, },
|
||||
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
|
||||
{ MP_QSTR_submode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_cs, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SPI_CS_ACTIVELOW} },
|
||||
};
|
||||
|
||||
STATIC mp_obj_t pyb_spi_init_helper(pyb_spi_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
// parse args
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(pybspi_init_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(pybspi_init_args), pybspi_init_args, args);
|
||||
|
||||
uint submode = args[2].u_int;
|
||||
uint cs = args[3].u_int;
|
||||
uint bits;
|
||||
|
||||
// save the word length for later use
|
||||
self->wlen = args[1].u_int / 8;
|
||||
switch (args[1].u_int) {
|
||||
case 8:
|
||||
bits = SPI_WL_8;
|
||||
break;
|
||||
case 16:
|
||||
bits = SPI_WL_16;
|
||||
break;
|
||||
case 32:
|
||||
bits = SPI_WL_32;
|
||||
break;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
break;
|
||||
}
|
||||
|
||||
if (submode < SPI_SUB_MODE_0 || submode > SPI_SUB_MODE_3) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
if (cs != SPI_CS_ACTIVELOW && cs != SPI_CS_ACTIVEHIGH) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
// build the configuration
|
||||
self->baudrate = args[0].u_int;
|
||||
self->config = bits | cs | SPI_SW_CTRL_CS | SPI_4PIN_MODE | SPI_TURBO_OFF;
|
||||
self->submode = submode;
|
||||
|
||||
// init the bus
|
||||
pybspi_init((const pyb_spi_obj_t *)self);
|
||||
|
||||
// register it with the sleep module
|
||||
pybsleep_add((const mp_obj_t)self, (WakeUpCB_t)pybspi_init);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
/// \classmethod \constructor(bus, ...)
|
||||
///
|
||||
/// Construct an SPI object with the given baudrate.
|
||||
/// With no parameters, the SPI object is created but not
|
||||
/// initialised (it has the settings from the last initialisation of
|
||||
/// the bus, if any). If extra arguments are given, the bus is initialised.
|
||||
/// See `init` for parameters of initialisation.
|
||||
///
|
||||
STATIC mp_obj_t pyb_spi_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
// check arguments
|
||||
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
|
||||
|
||||
pyb_spi_obj_t *self = &pyb_spi_obj;
|
||||
self->base.type = &pyb_spi_type;
|
||||
|
||||
if (n_args > 0 || n_kw > 0) {
|
||||
// start the peripheral
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
|
||||
pyb_spi_init_helper(self, n_args, args, &kw_args);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_spi_init(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
return pyb_spi_init_helper(args[0], n_args - 1, args + 1, kw_args);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_init_obj, 1, pyb_spi_init);
|
||||
|
||||
/// \method deinit()
|
||||
/// Turn off the spi bus.
|
||||
STATIC mp_obj_t pyb_spi_deinit(mp_obj_t self_in) {
|
||||
// disable the peripheral
|
||||
MAP_SPIDisable(GSPI_BASE);
|
||||
MAP_PRCMPeripheralClkDisable(PRCM_GSPI, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
// invalidate the baudrate
|
||||
pyb_spi_obj.baudrate = 0;
|
||||
// unregister it with the sleep module
|
||||
pybsleep_remove((const mp_obj_t)self_in);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_spi_deinit_obj, pyb_spi_deinit);
|
||||
|
||||
/// \method send(send)
|
||||
/// Send data on the bus:
|
||||
///
|
||||
/// - `send` is the data to send (a byte to send, or a buffer object).
|
||||
///
|
||||
STATIC mp_obj_t pyb_spi_send (mp_obj_t self_in, mp_obj_t send_o) {
|
||||
pyb_spi_obj_t *self = self_in;
|
||||
// get the buffer to send from
|
||||
mp_buffer_info_t bufinfo;
|
||||
uint8_t data[1];
|
||||
pyb_buf_get_for_send(send_o, &bufinfo, data);
|
||||
|
||||
// just send
|
||||
pybspi_transfer(self, (const char *)bufinfo.buf, NULL, bufinfo.len);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_spi_send_obj, pyb_spi_send);
|
||||
|
||||
/// \method recv(recv)
|
||||
///
|
||||
/// Receive data on the bus:
|
||||
///
|
||||
/// - `recv` can be an integer, which is the number of bytes to receive,
|
||||
/// or a mutable buffer, which will be filled with received bytes.
|
||||
///
|
||||
/// Return: if `recv` is an integer then a new buffer of the bytes received,
|
||||
/// otherwise the same buffer that was passed in to `recv`.
|
||||
STATIC mp_obj_t pyb_spi_recv(mp_obj_t self_in, mp_obj_t recv_o) {
|
||||
pyb_spi_obj_t *self = self_in;
|
||||
// get the buffer to receive into
|
||||
vstr_t vstr;
|
||||
mp_obj_t o_ret = pyb_buf_get_for_recv(recv_o, &vstr);
|
||||
|
||||
// just receive
|
||||
pybspi_transfer(self, NULL, vstr.buf, vstr.len);
|
||||
|
||||
// return the received data
|
||||
if (o_ret != MP_OBJ_NULL) {
|
||||
return o_ret;
|
||||
} else {
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_spi_recv_obj, pyb_spi_recv);
|
||||
|
||||
/// \method send_recv(send, recv)
|
||||
///
|
||||
/// Send and receive data on the bus at the same time:
|
||||
///
|
||||
/// - `send` is the data to send (an integer to send, or a buffer object).
|
||||
/// - `recv` is a mutable buffer which will be filled with received bytes.
|
||||
/// It can be the same as `send`, or omitted. If omitted, a new buffer will
|
||||
/// be created.
|
||||
///
|
||||
/// Return: the buffer with the received bytes.
|
||||
STATIC mp_obj_t pyb_spi_send_recv (mp_uint_t n_args, const mp_obj_t *args) {
|
||||
pyb_spi_obj_t *self = args[0];
|
||||
|
||||
// get buffers to send from/receive to
|
||||
mp_buffer_info_t bufinfo_send;
|
||||
uint8_t data_send[1];
|
||||
mp_buffer_info_t bufinfo_recv;
|
||||
vstr_t vstr_recv;
|
||||
mp_obj_t o_ret;
|
||||
|
||||
if (args[1] == args[2]) {
|
||||
// same object for sending and receiving, it must be a r/w buffer
|
||||
mp_get_buffer_raise(args[1], &bufinfo_send, MP_BUFFER_RW);
|
||||
bufinfo_recv = bufinfo_send;
|
||||
o_ret = args[1];
|
||||
} else {
|
||||
// get the buffer to send from
|
||||
pyb_buf_get_for_send(args[1], &bufinfo_send, data_send);
|
||||
|
||||
// get the buffer to receive into
|
||||
if (n_args == 2) {
|
||||
// only the send was argument given, so create a fresh buffer of the send length
|
||||
vstr_init_len(&vstr_recv, bufinfo_send.len);
|
||||
bufinfo_recv.len = vstr_recv.len;
|
||||
bufinfo_recv.buf = vstr_recv.buf;
|
||||
o_ret = MP_OBJ_NULL;
|
||||
}
|
||||
else {
|
||||
// recv argument given
|
||||
mp_get_buffer_raise(args[2], &bufinfo_recv, MP_BUFFER_WRITE);
|
||||
if (bufinfo_recv.len != bufinfo_send.len) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
o_ret = args[2];
|
||||
}
|
||||
}
|
||||
|
||||
// send and receive
|
||||
pybspi_transfer(self, (const char *)bufinfo_send.buf, vstr_recv.buf, bufinfo_send.len);
|
||||
|
||||
// return the received data
|
||||
if (o_ret != MP_OBJ_NULL) {
|
||||
return o_ret;
|
||||
} else {
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr_recv);
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_spi_send_recv_obj, 2, 3, pyb_spi_send_recv);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_spi_locals_dict_table[] = {
|
||||
// instance methods
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_spi_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_spi_deinit_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&pyb_spi_send_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&pyb_spi_recv_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_send_recv), (mp_obj_t)&pyb_spi_send_recv_obj },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ACTIVE_LOW), MP_OBJ_NEW_SMALL_INT(SPI_CS_ACTIVELOW) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ACTIVE_HIGH), MP_OBJ_NEW_SMALL_INT(SPI_CS_ACTIVEHIGH) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_spi_locals_dict, pyb_spi_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t pyb_spi_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_SPI,
|
||||
.print = pyb_spi_print,
|
||||
.make_new = pyb_spi_make_new,
|
||||
.locals_dict = (mp_obj_t)&pyb_spi_locals_dict,
|
||||
};
|
||||
33
cc3200/mods/pybspi.h
Normal file
33
cc3200/mods/pybspi.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PYBSPI_H_
|
||||
#define PYBSPI_H_
|
||||
|
||||
extern const mp_obj_type_t pyb_spi_type;
|
||||
|
||||
#endif // PYBSPI_H_
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "misc.h"
|
||||
#include "obj.h"
|
||||
#include "stream.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "pybuart.h"
|
||||
#include "telnet.h"
|
||||
#include "pybstdio.h"
|
||||
|
||||
// TODO make stdin, stdout and stderr writable objects so they can
|
||||
// be changed by Python code. This requires some changes, as these
|
||||
// objects are in a read-only module (py/modsys.c).
|
||||
|
||||
void stdout_tx_str(const char *str) {
|
||||
stdout_tx_strn(str, strlen(str));
|
||||
}
|
||||
|
||||
void stdout_tx_strn(const char *str, mp_uint_t len) {
|
||||
if (MP_STATE_PORT(pyb_stdio_uart) != NULL) {
|
||||
uart_tx_strn(MP_STATE_PORT(pyb_stdio_uart), str, len);
|
||||
}
|
||||
// and also to telnet
|
||||
if (telnet_is_active()) {
|
||||
telnet_tx_strn(str, len);
|
||||
}
|
||||
}
|
||||
|
||||
void stdout_tx_strn_cooked(const char *str, mp_uint_t len) {
|
||||
// send stdout to UART
|
||||
if (MP_STATE_PORT(pyb_stdio_uart) != NULL) {
|
||||
uart_tx_strn_cooked(MP_STATE_PORT(pyb_stdio_uart), str, len);
|
||||
}
|
||||
// and also to telnet
|
||||
if (telnet_is_active()) {
|
||||
telnet_tx_strn_cooked(str, len);
|
||||
}
|
||||
}
|
||||
|
||||
int stdin_rx_chr(void) {
|
||||
for ( ;; ) {
|
||||
if (telnet_rx_any()) {
|
||||
return telnet_rx_char();
|
||||
}
|
||||
else if (MP_STATE_PORT(pyb_stdio_uart) != NULL && uart_rx_any(MP_STATE_PORT(pyb_stdio_uart))) {
|
||||
return uart_rx_char(MP_STATE_PORT(pyb_stdio_uart));
|
||||
}
|
||||
HAL_Delay(1);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
#define STDIO_FD_IN (0)
|
||||
#define STDIO_FD_OUT (1)
|
||||
#define STDIO_FD_ERR (2)
|
||||
|
||||
typedef struct _pyb_stdio_obj_t {
|
||||
mp_obj_base_t base;
|
||||
int fd;
|
||||
} pyb_stdio_obj_t;
|
||||
|
||||
void stdio_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_stdio_obj_t *self = self_in;
|
||||
print(env, "<io.FileIO %d>", self->fd);
|
||||
}
|
||||
|
||||
STATIC mp_uint_t stdio_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) {
|
||||
pyb_stdio_obj_t *self = self_in;
|
||||
if (self->fd == STDIO_FD_IN) {
|
||||
for (uint i = 0; i < size; i++) {
|
||||
int c = stdin_rx_chr();
|
||||
if (c == '\r') {
|
||||
c = '\n';
|
||||
}
|
||||
((byte*)buf)[i] = c;
|
||||
}
|
||||
return size;
|
||||
} else {
|
||||
*errcode = EPERM;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_uint_t stdio_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) {
|
||||
pyb_stdio_obj_t *self = self_in;
|
||||
if (self->fd == STDIO_FD_OUT || self->fd == STDIO_FD_ERR) {
|
||||
stdout_tx_strn_cooked(buf, size);
|
||||
return size;
|
||||
} else {
|
||||
*errcode = EPERM;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
mp_obj_t stdio_obj___exit__(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
return mp_const_none;
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(stdio_obj___exit___obj, 4, 4, stdio_obj___exit__);
|
||||
|
||||
// TODO gc hook to close the file if not already closed
|
||||
|
||||
STATIC const mp_map_elem_t stdio_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readall), (mp_obj_t)&mp_stream_readall_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readline), (mp_obj_t)&mp_stream_unbuffered_readline_obj},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&mp_stream_write_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&mp_identity_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&mp_identity_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___enter__), (mp_obj_t)&mp_identity_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___exit__), (mp_obj_t)&stdio_obj___exit___obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(stdio_locals_dict, stdio_locals_dict_table);
|
||||
|
||||
STATIC const mp_stream_p_t stdio_obj_stream_p = {
|
||||
.read = stdio_read,
|
||||
.write = stdio_write,
|
||||
.is_text = true,
|
||||
};
|
||||
|
||||
STATIC const mp_obj_type_t stdio_obj_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_FileIO,
|
||||
// TODO .make_new?
|
||||
.print = stdio_obj_print,
|
||||
.getiter = mp_identity,
|
||||
.iternext = mp_stream_unbuffered_iter,
|
||||
.stream_p = &stdio_obj_stream_p,
|
||||
.locals_dict = (mp_obj_t)&stdio_locals_dict,
|
||||
};
|
||||
|
||||
/// \moduleref sys
|
||||
/// \constant stdin - standard input (connected to UART0, or to telnet, configurable)
|
||||
/// \constant stdout - standard output (connected to UART0, and optionally to telnet)
|
||||
/// \constant stderr - standard error (connected to UART0, and optionally to telnet)
|
||||
const pyb_stdio_obj_t mp_sys_stdin_obj = {{&stdio_obj_type}, .fd = STDIO_FD_IN};
|
||||
const pyb_stdio_obj_t mp_sys_stdout_obj = {{&stdio_obj_type}, .fd = STDIO_FD_OUT};
|
||||
const pyb_stdio_obj_t mp_sys_stderr_obj = {{&stdio_obj_type}, .fd = STDIO_FD_ERR};
|
||||
@@ -25,39 +25,33 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "stream.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/objlist.h"
|
||||
#include "py/stream.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_gpio.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "inc/hw_uart.h"
|
||||
#include "rom_map.h"
|
||||
#include "interrupt.h"
|
||||
#include "prcm.h"
|
||||
#include "gpio.h"
|
||||
#include "uart.h"
|
||||
#include "pin.h"
|
||||
#include "pybuart.h"
|
||||
#include "pybioctl.h"
|
||||
#include "pybstdio.h"
|
||||
#include "pybsleep.h"
|
||||
#include "mpcallback.h"
|
||||
#include "mpexception.h"
|
||||
#include "py/mpstate.h"
|
||||
#include "osi.h"
|
||||
|
||||
|
||||
/// \moduleref pyb
|
||||
/// \class UART - duplex serial communication bus
|
||||
///
|
||||
@@ -68,7 +62,7 @@
|
||||
///
|
||||
/// from pyb import UART
|
||||
///
|
||||
/// uart = UART(1, 9600) # init with given baudrate
|
||||
/// uart = UART(0, 9600) # init with given baudrate
|
||||
/// uart.init(9600, bits=8, stop=1, parity=None) # init with given parameters
|
||||
///
|
||||
/// Bits can be 5, 6, 7, 8, parity can be None, 0 (even), 1 (odd). Stop can be 1 or 2.
|
||||
@@ -91,23 +85,29 @@
|
||||
///
|
||||
/// uart.any() # returns True if any characters waiting
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYBUART_TX_WAIT_MS 1
|
||||
#define PYBUART_TX_MAX_TIMEOUT_MS 5
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC void uart_init (pyb_uart_obj_t *self);
|
||||
STATIC bool uart_rx_wait (pyb_uart_obj_t *self, uint32_t timeout);
|
||||
STATIC void UARTGenericIntHandler(uint32_t uart_id);
|
||||
STATIC void UART0IntHandler(void);
|
||||
STATIC void UART1IntHandler(void);
|
||||
STATIC mp_obj_t pyb_uart_deinit(mp_obj_t self_in);
|
||||
STATIC void uart_callback_enable (mp_obj_t self_in);
|
||||
STATIC void uart_callback_disable (mp_obj_t self_in);
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE TYPES
|
||||
******************************************************************************/
|
||||
|
||||
struct _pyb_uart_obj_t {
|
||||
mp_obj_base_t base;
|
||||
pyb_uart_t uart_id;
|
||||
pyb_uart_id_t uart_id;
|
||||
uint reg;
|
||||
uint baudrate;
|
||||
uint config;
|
||||
@@ -118,112 +118,25 @@ struct _pyb_uart_obj_t {
|
||||
uint16_t read_buf_len; // len in chars; buf can hold len-1 chars
|
||||
volatile uint16_t read_buf_head; // indexes first empty slot
|
||||
uint16_t read_buf_tail; // indexes first full slot (not full if equals head)
|
||||
bool enabled;
|
||||
byte peripheral;
|
||||
};
|
||||
|
||||
#define PYBUART_TX_WAIT_MS 1
|
||||
#define PYBUART_TX_MAX_TIMEOUT_MS 5
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC pyb_uart_obj_t pyb_uart_obj[PYB_NUM_UARTS];
|
||||
STATIC const mp_cb_methods_t uart_cb_methods;
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
void uart_init0 (void) {
|
||||
for (int i = 0; i < MP_ARRAY_SIZE(MP_STATE_PORT(pyb_uart_obj_all)); i++) {
|
||||
MP_STATE_PORT(pyb_uart_obj_all)[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// unregister all interrupt sources
|
||||
void uart_deinit(void) {
|
||||
for (int i = 0; i < MP_ARRAY_SIZE(MP_STATE_PORT(pyb_uart_obj_all)); i++) {
|
||||
pyb_uart_obj_t *self = MP_STATE_PORT(pyb_uart_obj_all)[i];
|
||||
if (self != NULL) {
|
||||
pyb_uart_deinit(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// assumes Init parameters have been set up correctly
|
||||
bool uart_init2(pyb_uart_obj_t *self) {
|
||||
uint uartPerh;
|
||||
|
||||
switch (self->uart_id) {
|
||||
case PYB_UART_1:
|
||||
self->reg = UARTA0_BASE;
|
||||
uartPerh = PRCM_UARTA0;
|
||||
MAP_PinTypeUART(PIN_55, PIN_MODE_3);
|
||||
MAP_PinTypeUART(PIN_57, PIN_MODE_3);
|
||||
MAP_UARTIntRegister(UARTA0_BASE, UART0IntHandler);
|
||||
MAP_IntPrioritySet(INT_UARTA0, INT_PRIORITY_LVL_7);
|
||||
break;
|
||||
case PYB_UART_2:
|
||||
self->reg = UARTA1_BASE;
|
||||
uartPerh = PRCM_UARTA1;
|
||||
MAP_PinTypeUART(PIN_58, PIN_MODE_6);
|
||||
MAP_PinTypeUART(PIN_59, PIN_MODE_6);
|
||||
MAP_UARTIntRegister(UARTA1_BASE, UART1IntHandler);
|
||||
MAP_IntPrioritySet(INT_UARTA1, INT_PRIORITY_LVL_7);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
// Enable the peripheral clock
|
||||
MAP_PRCMPeripheralClkEnable(uartPerh, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
|
||||
// Reset the uart
|
||||
MAP_PRCMPeripheralReset(uartPerh);
|
||||
|
||||
// Initialize the UART
|
||||
MAP_UARTConfigSetExpClk(self->reg, MAP_PRCMPeripheralClockGet(uartPerh),
|
||||
self->baudrate, self->config);
|
||||
|
||||
// Enbale the FIFO
|
||||
MAP_UARTFIFOEnable(self->reg);
|
||||
|
||||
// Configure the FIFO interrupt levels
|
||||
MAP_UARTFIFOLevelSet(self->reg, UART_FIFO_TX4_8, UART_FIFO_RX4_8);
|
||||
|
||||
// Configure the flow control mode
|
||||
UARTFlowControlSet(self->reg, self->flowcontrol);
|
||||
|
||||
// Enable the RX and RX timeout interrupts
|
||||
MAP_UARTIntEnable(self->reg, UART_INT_RX | UART_INT_RT);
|
||||
|
||||
self->enabled = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool uart_init(pyb_uart_obj_t *self, uint baudrate) {
|
||||
self->baudrate = baudrate;
|
||||
self->config = UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE;
|
||||
self->flowcontrol = UART_FLOWCONTROL_NONE;
|
||||
return uart_init2(self);
|
||||
}
|
||||
|
||||
bool uart_rx_any(pyb_uart_obj_t *self) {
|
||||
return (self->read_buf_tail != self->read_buf_head || MAP_UARTCharsAvail(self->reg));
|
||||
}
|
||||
|
||||
// Waits at most timeout milliseconds for at least 1 char to become ready for
|
||||
// reading (from buf or for direct reading).
|
||||
// Returns true if something available, false if not.
|
||||
STATIC bool uart_rx_wait(pyb_uart_obj_t *self, uint32_t timeout) {
|
||||
for (;;) {
|
||||
if (uart_rx_any(self)) {
|
||||
return true; // have at least 1 char ready for reading
|
||||
}
|
||||
if (timeout > 0) {
|
||||
HAL_Delay (1);
|
||||
timeout--;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int uart_rx_char(pyb_uart_obj_t *self) {
|
||||
if (self->read_buf_tail != self->read_buf_head) {
|
||||
// buffering via IRQ
|
||||
@@ -266,29 +179,100 @@ void uart_tx_strn_cooked(pyb_uart_obj_t *self, const char *str, uint len) {
|
||||
}
|
||||
}
|
||||
|
||||
mp_obj_t uart_callback_new (pyb_uart_obj_t *self, mp_obj_t handler, uint rxbuffer_size, mp_int_t priority) {
|
||||
// disable the uart interrupts before updating anything
|
||||
uart_callback_disable (self);
|
||||
|
||||
if (self->uart_id == PYB_UART_0) {
|
||||
MAP_IntPrioritySet(INT_UARTA0, priority);
|
||||
MAP_UARTIntRegister(self->reg, UART0IntHandler);
|
||||
}
|
||||
else {
|
||||
MAP_IntPrioritySet(INT_UARTA1, priority);
|
||||
MAP_UARTIntRegister(self->reg, UART1IntHandler);
|
||||
}
|
||||
|
||||
// check the rx buffer size
|
||||
if (rxbuffer_size > 0) {
|
||||
// allocate the read buffer
|
||||
self->read_buf_len = rxbuffer_size;
|
||||
self->read_buf = m_new(byte, rxbuffer_size);
|
||||
}
|
||||
|
||||
// create the callback
|
||||
mp_obj_t _callback = mpcallback_new ((mp_obj_t)self, handler, &uart_cb_methods);
|
||||
|
||||
// enable the interrupts now
|
||||
uart_callback_enable (self);
|
||||
|
||||
return _callback;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
STATIC void UARTGenericIntHandler(uint32_t uart_id) {
|
||||
pyb_uart_obj_t *self = MP_STATE_PORT(pyb_uart_obj_all)[uart_id];
|
||||
uint32_t status;
|
||||
|
||||
if (self == NULL) {
|
||||
// UART object has not been set, so we can't do anything, not
|
||||
// even disable the IRQ. This should never happen.
|
||||
return;
|
||||
// assumes init parameters have been set up correctly
|
||||
STATIC void uart_init (pyb_uart_obj_t *self) {
|
||||
if (self->uart_id == PYB_UART_0) {
|
||||
self->reg = UARTA0_BASE;
|
||||
self->peripheral = PRCM_UARTA0;
|
||||
}
|
||||
else {
|
||||
self->reg = UARTA1_BASE;
|
||||
self->peripheral = PRCM_UARTA1;
|
||||
}
|
||||
|
||||
status = MAP_UARTIntStatus(self->reg, true);
|
||||
// Enable the peripheral clock
|
||||
MAP_PRCMPeripheralClkEnable(self->peripheral, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
|
||||
// Receive interrupt
|
||||
// Reset the uart
|
||||
MAP_PRCMPeripheralReset(self->peripheral);
|
||||
|
||||
// Initialize the UART
|
||||
MAP_UARTConfigSetExpClk(self->reg, MAP_PRCMPeripheralClockGet(self->peripheral),
|
||||
self->baudrate, self->config);
|
||||
|
||||
// Enable the FIFO
|
||||
MAP_UARTFIFOEnable(self->reg);
|
||||
|
||||
// Configure the FIFO interrupt levels
|
||||
MAP_UARTFIFOLevelSet(self->reg, UART_FIFO_TX4_8, UART_FIFO_RX4_8);
|
||||
|
||||
// Configure the flow control mode
|
||||
UARTFlowControlSet(self->reg, self->flowcontrol);
|
||||
}
|
||||
|
||||
// Waits at most timeout milliseconds for at least 1 char to become ready for
|
||||
// reading (from buf or for direct reading).
|
||||
// Returns true if something available, false if not.
|
||||
STATIC bool uart_rx_wait (pyb_uart_obj_t *self, uint32_t timeout) {
|
||||
for ( ; ; ) {
|
||||
if (uart_rx_any(self)) {
|
||||
return true; // have at least 1 char ready for reading
|
||||
}
|
||||
if (timeout > 0) {
|
||||
HAL_Delay (1);
|
||||
timeout--;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void UARTGenericIntHandler(uint32_t uart_id) {
|
||||
pyb_uart_obj_t *self;
|
||||
uint32_t status;
|
||||
|
||||
self = &pyb_uart_obj[uart_id];
|
||||
status = MAP_UARTIntStatus(self->reg, true);
|
||||
// receive interrupt
|
||||
if (status & (UART_INT_RX | UART_INT_RT)) {
|
||||
MAP_UARTIntClear(self->reg, UART_INT_RX | UART_INT_RT);
|
||||
while (UARTCharsAvail(self->reg)) {
|
||||
int data = MAP_UARTCharGetNonBlocking(self->reg);
|
||||
if (MICROPY_STDIO_UART == self->uart_id && data == user_interrupt_char) {
|
||||
// raise exception when interrupts are finished
|
||||
if (pyb_stdio_uart == self && data == user_interrupt_char) {
|
||||
// raise an exception when interrupts are finished
|
||||
mpexception_keyboard_nlr_jump();
|
||||
}
|
||||
else if (self->read_buf_len != 0) {
|
||||
@@ -300,6 +284,9 @@ STATIC void UARTGenericIntHandler(uint32_t uart_id) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// call the user defined handler
|
||||
mp_obj_t _callback = mpcallback_find(self);
|
||||
mpcallback_handler(_callback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,15 +298,24 @@ STATIC void UART1IntHandler(void) {
|
||||
UARTGenericIntHandler(1);
|
||||
}
|
||||
|
||||
STATIC void uart_callback_enable (mp_obj_t self_in) {
|
||||
pyb_uart_obj_t *self = self_in;
|
||||
MAP_UARTIntClear(self->reg, UART_INT_RX | UART_INT_RT);
|
||||
MAP_UARTIntEnable(self->reg, UART_INT_RX | UART_INT_RT);
|
||||
}
|
||||
|
||||
STATIC void uart_callback_disable (mp_obj_t self_in) {
|
||||
pyb_uart_obj_t *self = self_in;
|
||||
MAP_UARTIntDisable(self->reg, UART_INT_RX | UART_INT_RT);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings */
|
||||
|
||||
STATIC void pyb_uart_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_uart_obj_t *self = self_in;
|
||||
if (!self->enabled) {
|
||||
print(env, "UART(%u)", self->uart_id);
|
||||
} else {
|
||||
print(env, "UART(%u, baudrate=%u, bits=", self->uart_id, self->baudrate);
|
||||
if (self->baudrate > 0) {
|
||||
print(env, "<UART%u, baudrate=%u, bits=", self->uart_id, self->baudrate);
|
||||
switch (self->config & UART_CONFIG_WLEN_MASK) {
|
||||
case UART_CONFIG_WLEN_5:
|
||||
print(env, "5");
|
||||
@@ -341,13 +337,16 @@ STATIC void pyb_uart_print(void (*print)(void *env, const char *fmt, ...), void
|
||||
} else {
|
||||
print(env, ", parity=%u", (self->config & UART_CONFIG_PAR_MASK) == UART_CONFIG_PAR_EVEN ? 0 : 1);
|
||||
}
|
||||
print(env, ", stop=%u, timeout=%u, timeout_char=%u, read_buf_len=%u)",
|
||||
print(env, ", stop=%u, timeout=%u, timeout_char=%u, read_buf_len=%u>",
|
||||
(self->config & UART_CONFIG_STOP_MASK) == UART_CONFIG_STOP_ONE ? 1 : 2,
|
||||
self->timeout, self->timeout_char, self->read_buf_len);
|
||||
}
|
||||
else {
|
||||
print(env, "<UART%u>", self->uart_id);
|
||||
}
|
||||
}
|
||||
|
||||
/// \method init(baudrate, bits=8, parity=None, stop=1, *, timeout=1000, timeout_char=0, read_buf_len=64)
|
||||
/// \method init(baudrate, bits=8, parity=None, stop=1, *, timeout=1000, timeout_char=0)
|
||||
///
|
||||
/// Initialise the UART bus with the given parameters:
|
||||
///
|
||||
@@ -357,9 +356,8 @@ STATIC void pyb_uart_print(void (*print)(void *env, const char *fmt, ...), void
|
||||
/// - `stop` is the number of stop bits, 1 or 2.
|
||||
/// - `flowcontrol` is the flow control mode, `None`, `UART.FLOW_TX`,
|
||||
/// `UART.FLOW_RX', 'UART.FLOW_TXRX`.
|
||||
/// - `timeout` is the timeout in milliseconds to wait for the first character.
|
||||
/// - `timeout_char` is the timeout in milliseconds to wait between characters.
|
||||
/// - `read_buf_len` is the character length of the read buffer (0 to disable).
|
||||
/// - `timeout` is the timeout (in milliseconds) when waiting for the first character.
|
||||
/// - `timeout_char` is the timeout (in milliseconds) between characters.
|
||||
STATIC const mp_arg_t pyb_uart_init_args[] = {
|
||||
{ MP_QSTR_baudrate, MP_ARG_REQUIRED | MP_ARG_INT, },
|
||||
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
|
||||
@@ -368,19 +366,28 @@ STATIC const mp_arg_t pyb_uart_init_args[] = {
|
||||
{ MP_QSTR_flow, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_int = UART_FLOWCONTROL_NONE} },
|
||||
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1000} },
|
||||
{ MP_QSTR_timeout_char, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
|
||||
{ MP_QSTR_read_buf_len, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} },
|
||||
};
|
||||
|
||||
STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
bool success;
|
||||
|
||||
// parse args
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_uart_init_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(pyb_uart_init_args), pyb_uart_init_args, args);
|
||||
|
||||
// set timeouts
|
||||
self->timeout = args[5].u_int;
|
||||
self->timeout_char = args[6].u_int;
|
||||
|
||||
// no read buffer for the moment
|
||||
self->read_buf_head = 0;
|
||||
self->read_buf_tail = 0;
|
||||
self->read_buf_len = 0;
|
||||
self->read_buf = NULL;
|
||||
|
||||
// get the baudrate
|
||||
self->baudrate = args[0].u_int;
|
||||
|
||||
// set the UART configuration values
|
||||
if (n_args > 1) {
|
||||
self->baudrate = args[0].u_int;
|
||||
switch (args[1].u_int) {
|
||||
case 5:
|
||||
self->config = UART_CONFIG_WLEN_5;
|
||||
@@ -406,45 +413,25 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con
|
||||
}
|
||||
// Stop bits
|
||||
self->config |= (args[3].u_int == 1 ? UART_CONFIG_STOP_ONE : UART_CONFIG_STOP_TWO);
|
||||
|
||||
// Flow control
|
||||
self->flowcontrol = args[4].u_int;
|
||||
success = uart_init2(self);
|
||||
} else {
|
||||
success = uart_init(self, args[0].u_int);
|
||||
}
|
||||
|
||||
// init UART (if it fails, something weird happened)
|
||||
if (!success) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
else {
|
||||
self->config = UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE;
|
||||
self->flowcontrol = UART_FLOWCONTROL_NONE;
|
||||
}
|
||||
|
||||
// set timeouts
|
||||
self->timeout = args[5].u_int;
|
||||
self->timeout_char = args[6].u_int;
|
||||
// initialize and enable the uart
|
||||
uart_init (self);
|
||||
// register it with the sleep module
|
||||
pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)uart_init);
|
||||
|
||||
// setup the read buffer
|
||||
m_del(byte, self->read_buf, self->read_buf_len);
|
||||
self->read_buf_head = 0;
|
||||
self->read_buf_tail = 0;
|
||||
|
||||
if (args[7].u_int <= 0) {
|
||||
// no read buffer
|
||||
self->read_buf_len = 0;
|
||||
self->read_buf = NULL;
|
||||
MAP_UARTIntDisable(self->reg, UART_INT_RX | UART_INT_RT);
|
||||
} else {
|
||||
// read buffer using interrupts
|
||||
self->read_buf_len = args[7].u_int;
|
||||
self->read_buf = m_new(byte, args[7].u_int);
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
/// \classmethod \constructor(bus, ...)
|
||||
///
|
||||
/// Construct a UART object on the given bus. `bus` can be 1-2
|
||||
/// Construct a UART object on the given bus id. `bus id` can be 0 or 1
|
||||
/// With no additional parameters, the UART object is created but not
|
||||
/// initialised (it has the settings from the last initialisation of
|
||||
/// the bus, if any).
|
||||
@@ -459,34 +446,22 @@ STATIC mp_obj_t pyb_uart_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t
|
||||
// check arguments
|
||||
mp_arg_check_num(n_args, n_kw, 1, MP_ARRAY_SIZE(pyb_uart_init_args), true);
|
||||
|
||||
// work out port
|
||||
pyb_uart_t uart_id = mp_obj_get_int(args[0]);
|
||||
// work out the uart id
|
||||
pyb_uart_id_t uart_id = mp_obj_get_int(args[0]);
|
||||
|
||||
if (uart_id < PYB_UART_1 || uart_id > MP_ARRAY_SIZE(MP_STATE_PORT(pyb_uart_obj_all))) {
|
||||
if (uart_id < PYB_UART_0 || uart_id > PYB_UART_1) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
// create object
|
||||
pyb_uart_obj_t *self;
|
||||
if (MP_STATE_PORT(pyb_uart_obj_all)[uart_id - 1] == NULL) {
|
||||
// create new UART object
|
||||
self = m_new0(pyb_uart_obj_t, 1);
|
||||
self->base.type = &pyb_uart_type;
|
||||
self->uart_id = uart_id;
|
||||
self->enabled = false;
|
||||
MP_STATE_PORT(pyb_uart_obj_all)[uart_id - 1] = self;
|
||||
} else {
|
||||
// reference existing UART object
|
||||
self = MP_STATE_PORT(pyb_uart_obj_all)[uart_id - 1];
|
||||
}
|
||||
|
||||
// get the correct uart instance
|
||||
pyb_uart_obj_t *self = &pyb_uart_obj[uart_id];
|
||||
self->base.type = &pyb_uart_type;
|
||||
self->uart_id = uart_id;
|
||||
if (n_args > 1 || n_kw > 0) {
|
||||
// start the peripheral
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
|
||||
pyb_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
|
||||
} else if (!self->enabled) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments));
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -499,31 +474,16 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_init_obj, 1, pyb_uart_init);
|
||||
|
||||
/// \method deinit()
|
||||
/// Turn off the UART bus.
|
||||
STATIC mp_obj_t pyb_uart_deinit(mp_obj_t self_in) {
|
||||
mp_obj_t pyb_uart_deinit(mp_obj_t self_in) {
|
||||
pyb_uart_obj_t *self = self_in;
|
||||
uint uartPerh;
|
||||
|
||||
switch (self->uart_id) {
|
||||
|
||||
case PYB_UART_1:
|
||||
uartPerh = PRCM_UARTA0;
|
||||
break;
|
||||
|
||||
case PYB_UART_2:
|
||||
uartPerh = PRCM_UARTA1;
|
||||
break;
|
||||
|
||||
default:
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
self->enabled = false;
|
||||
// unregister it with the sleep module
|
||||
pybsleep_remove (self);
|
||||
// invalidate the baudrate
|
||||
self->baudrate = 0;
|
||||
MAP_UARTIntDisable(self->reg, UART_INT_RX | UART_INT_RT);
|
||||
MAP_UARTIntClear(self->reg, UART_INT_RX | UART_INT_RT);
|
||||
MAP_UARTIntUnregister(self->reg);
|
||||
MAP_UARTDisable(self->reg);
|
||||
MAP_PRCMPeripheralClkDisable(uartPerh, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
|
||||
MAP_PRCMPeripheralClkDisable(self->peripheral, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_deinit_obj, pyb_uart_deinit);
|
||||
@@ -540,6 +500,33 @@ STATIC mp_obj_t pyb_uart_any(mp_obj_t self_in) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_any_obj, pyb_uart_any);
|
||||
|
||||
/// \method callback(handler, value, priority)
|
||||
/// Creates a callback object associated with the uart
|
||||
/// min num of arguments is 1 (value). The value is the size of the rx buffer
|
||||
STATIC mp_obj_t pyb_uart_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
mp_arg_val_t args[mpcallback_INIT_NUM_ARGS];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mpcallback_INIT_NUM_ARGS, mpcallback_init_args, args);
|
||||
|
||||
// check if any parameters were passed
|
||||
pyb_uart_obj_t *self = pos_args[0];
|
||||
mp_obj_t _callback = mpcallback_find((mp_obj_t)self);
|
||||
if (kw_args->used > 0 || !_callback) {
|
||||
|
||||
// convert the priority to the correct value
|
||||
uint priority = mpcallback_translate_priority (args[2].u_int);
|
||||
|
||||
// check the power mode
|
||||
if (PYB_PWR_MODE_ACTIVE != args[3].u_int) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
// register a new callback
|
||||
return uart_callback_new (self, args[1].u_obj, args[3].u_int, priority);
|
||||
}
|
||||
return _callback;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_callback_obj, 1, pyb_uart_callback);
|
||||
|
||||
/// \method writechar(char)
|
||||
/// Write a single character on the bus. `char` is an integer to write.
|
||||
/// Return value: `None`.
|
||||
@@ -574,10 +561,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_readchar_obj, pyb_uart_readchar);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_uart_locals_dict_table[] = {
|
||||
// instance methods
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_uart_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_uart_deinit_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_any), (mp_obj_t)&pyb_uart_any_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&pyb_uart_callback_obj },
|
||||
|
||||
/// \method read([nbytes])
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&mp_stream_read_obj },
|
||||
@@ -594,9 +581,6 @@ STATIC const mp_map_elem_t pyb_uart_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readchar), (mp_obj_t)&pyb_uart_readchar_obj },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_UART1), MP_OBJ_NEW_SMALL_INT(PYB_UART_1) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_UART2), MP_OBJ_NEW_SMALL_INT(PYB_UART_2) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_FLOW_NONE), MP_OBJ_NEW_SMALL_INT(UART_FLOWCONTROL_NONE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_FLOW_TX), MP_OBJ_NEW_SMALL_INT(UART_FLOWCONTROL_TX) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_FLOW_RX), MP_OBJ_NEW_SMALL_INT(UART_FLOWCONTROL_RX) },
|
||||
@@ -623,7 +607,7 @@ STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, i
|
||||
|
||||
// read the data
|
||||
byte *orig_buf = buf;
|
||||
for (;;) {
|
||||
for ( ; ; ) {
|
||||
*buf++ = uart_rx_char(self);
|
||||
if (--size == 0 || !uart_rx_wait(self, self->timeout_char)) {
|
||||
// return number of bytes read
|
||||
@@ -669,6 +653,12 @@ STATIC const mp_stream_p_t uart_stream_p = {
|
||||
.is_text = false,
|
||||
};
|
||||
|
||||
STATIC const mp_cb_methods_t uart_cb_methods = {
|
||||
.init = pyb_uart_callback,
|
||||
.enable = uart_callback_enable,
|
||||
.disable = uart_callback_disable,
|
||||
};
|
||||
|
||||
const mp_obj_type_t pyb_uart_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_UART,
|
||||
|
||||
@@ -25,21 +25,25 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PYBUART_H_
|
||||
#define PYBUART_H_
|
||||
|
||||
typedef enum {
|
||||
PYB_UART_NONE = 0,
|
||||
PYB_UART_1 = 1,
|
||||
PYB_UART_2 = 2
|
||||
} pyb_uart_t;
|
||||
PYB_UART_0 = 0,
|
||||
PYB_UART_1 = 1,
|
||||
PYB_NUM_UARTS
|
||||
} pyb_uart_id_t;
|
||||
|
||||
typedef struct _pyb_uart_obj_t pyb_uart_obj_t;
|
||||
extern const mp_obj_type_t pyb_uart_type;
|
||||
|
||||
void uart_init0(void);
|
||||
bool uart_init(pyb_uart_obj_t *uart_obj, uint baudrate);
|
||||
void uart_deinit (void);
|
||||
mp_obj_t pyb_uart_deinit(mp_obj_t self_in);
|
||||
bool uart_rx_any(pyb_uart_obj_t *uart_obj);
|
||||
int uart_rx_char(pyb_uart_obj_t *uart_obj);
|
||||
bool uart_tx_char(pyb_uart_obj_t *self, int c);
|
||||
bool uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len);
|
||||
void uart_tx_strn_cooked(pyb_uart_obj_t *uart_obj, const char *str, uint len);
|
||||
mp_obj_t uart_callback_new (pyb_uart_obj_t *self, mp_obj_t handler, uint rxbuffer_size, mp_int_t priority);
|
||||
|
||||
#endif // PYBUART_H_
|
||||
|
||||
149
cc3200/mods/pybwdt.c
Normal file
149
cc3200/mods/pybwdt.c
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_gpio.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "rom_map.h"
|
||||
#include "wdt.h"
|
||||
#include "prcm.h"
|
||||
#include "utils.h"
|
||||
#include "pybwdt.h"
|
||||
#include "mpexception.h"
|
||||
#include "mperror.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYBWDT_MILLISECONDS_TO_TICKS(ms) ((80000000 / 1000) * (ms))
|
||||
#define PYBWDT_MIN_TIMEOUT_MS (1000)
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE TYPES
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
bool servers;
|
||||
bool simplelink;
|
||||
bool running;
|
||||
}pybwdt_data_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
static pybwdt_data_t pybwdt_data;
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
// must be called in main.c just after initializing the hal
|
||||
__attribute__ ((section (".boot")))
|
||||
void pybwdt_init0 (void) {
|
||||
pybwdt_data.running = false;
|
||||
}
|
||||
|
||||
void pybwdt_kick (void) {
|
||||
// check that the servers and simplelink are running fine
|
||||
if (pybwdt_data.servers && pybwdt_data.simplelink && pybwdt_data.running) {
|
||||
pybwdt_data.servers = false;
|
||||
pybwdt_data.simplelink = false;
|
||||
MAP_WatchdogIntClear(WDT_BASE);
|
||||
}
|
||||
}
|
||||
|
||||
void pybwdt_srv_alive (void) {
|
||||
pybwdt_data.servers = true;
|
||||
}
|
||||
|
||||
void pybwdt_sl_alive (void) {
|
||||
pybwdt_data.simplelink = true;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
/// \function wdt_enable('msec')
|
||||
/// Enabled the watchdog timer with msec timeout value
|
||||
STATIC mp_obj_t pyb_enable_wdt(mp_obj_t self, mp_obj_t msec_in) {
|
||||
mp_int_t msec = mp_obj_get_int(msec_in);
|
||||
|
||||
if (msec < PYBWDT_MIN_TIMEOUT_MS) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
if (pybwdt_data.running) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
|
||||
// Enable the WDT peripheral clock
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_WDT, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
|
||||
// Unlock to be able to configure the registers
|
||||
MAP_WatchdogUnlock(WDT_BASE);
|
||||
|
||||
// make the WDT stall when the debugger stops on a breakpoint
|
||||
MAP_WatchdogStallEnable (WDT_BASE);
|
||||
|
||||
// set the watchdog timer reload value
|
||||
// the WDT trigger a system reset after the second timeout
|
||||
// so, divide by the 2 timeout value received
|
||||
MAP_WatchdogReloadSet(WDT_BASE, PYBWDT_MILLISECONDS_TO_TICKS(msec / 2));
|
||||
|
||||
// start the timer. Once wdt is started, it cannot be disabled.
|
||||
MAP_WatchdogEnable(WDT_BASE);
|
||||
pybwdt_data.running = true;
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_enable_wdt_obj, pyb_enable_wdt);
|
||||
|
||||
/// \function wdt_kick()
|
||||
/// Kicks the watchdog timer
|
||||
STATIC mp_obj_t pyb_kick_wdt(mp_obj_t self) {
|
||||
pybwdt_kick ();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_kick_wdt_obj, pyb_kick_wdt);
|
||||
|
||||
STATIC const mp_map_elem_t pybwdt_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&pyb_enable_wdt_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_kick), (mp_obj_t)&pyb_kick_wdt_obj },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(pybwdt_locals_dict, pybwdt_locals_dict_table);
|
||||
|
||||
static const mp_obj_type_t pybwdt_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_WDT,
|
||||
.locals_dict = (mp_obj_t)&pybwdt_locals_dict,
|
||||
};
|
||||
|
||||
const mp_obj_base_t pyb_wdt_obj = {&pybwdt_type};
|
||||
39
cc3200/mods/pybwdt.h
Normal file
39
cc3200/mods/pybwdt.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PYBWDT_H_
|
||||
#define PYBWDT_H_
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
extern const mp_obj_base_t pyb_wdt_obj;
|
||||
|
||||
void pybwdt_init0 (void);
|
||||
void pybwdt_kick (void);
|
||||
void pybwdt_srv_alive (void);
|
||||
void pybwdt_sl_alive (void);
|
||||
|
||||
#endif /* PYBWDT_H_ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user