mirror of
https://github.com/micropython/micropython.git
synced 2025-12-24 05:40:15 +01:00
Compare commits
1198 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe08e3a54f | ||
|
|
8fd8bb36b3 | ||
|
|
3b24e83731 | ||
|
|
bb489066e8 | ||
|
|
109b363ddc | ||
|
|
075ca64521 | ||
|
|
be2879ce89 | ||
|
|
ee0058d174 | ||
|
|
1f2daf4304 | ||
|
|
1c7f9b16f0 | ||
|
|
ceb169008d | ||
|
|
04db848dc7 | ||
|
|
4b630c452d | ||
|
|
719dca2515 | ||
|
|
d67ea6b29f | ||
|
|
7ff585333e | ||
|
|
9a507c67ad | ||
|
|
9d7ef05caf | ||
|
|
e693e52442 | ||
|
|
9d0192de4a | ||
|
|
f09f8097d5 | ||
|
|
d19e4f0ba4 | ||
|
|
f961456b29 | ||
|
|
22521ea9e2 | ||
|
|
04353cc85e | ||
|
|
183edefddd | ||
|
|
aedb859177 | ||
|
|
7e359c648b | ||
|
|
aaef1851a7 | ||
|
|
60401d461a | ||
|
|
b106532b32 | ||
|
|
8e6e9eaea5 | ||
|
|
acea9352a9 | ||
|
|
9058a7031f | ||
|
|
a787467569 | ||
|
|
4078336d38 | ||
|
|
2f96b1982a | ||
|
|
bedab235f9 | ||
|
|
83158e0e7f | ||
|
|
d8066e999d | ||
|
|
504420c51d | ||
|
|
2c040edef8 | ||
|
|
9c72c71c05 | ||
|
|
f4c50f1cfc | ||
|
|
ae70e98ed4 | ||
|
|
8faf2dc75b | ||
|
|
36ae417c9f | ||
|
|
2e0cd20a1d | ||
|
|
65f6324573 | ||
|
|
d8137178bb | ||
|
|
39a380b621 | ||
|
|
e0f5df579b | ||
|
|
8ee153f234 | ||
|
|
fd379db286 | ||
|
|
096d1e4512 | ||
|
|
949c5c9180 | ||
|
|
7799410950 | ||
|
|
2ca7b05552 | ||
|
|
f8e9ef5cd0 | ||
|
|
020386b61c | ||
|
|
c3000b6f69 | ||
|
|
6ec6f51326 | ||
|
|
4542643025 | ||
|
|
fca3308cc3 | ||
|
|
e19dfe1c32 | ||
|
|
affcbe4139 | ||
|
|
6a515b95a8 | ||
|
|
c13be69a8e | ||
|
|
035a0a2b6e | ||
|
|
e813541e3f | ||
|
|
4bf3f2d3c0 | ||
|
|
556c8a9a4f | ||
|
|
4300c7dba2 | ||
|
|
74d0df7324 | ||
|
|
d7e3b36a09 | ||
|
|
fcce1483fa | ||
|
|
2430dfac31 | ||
|
|
fe29cc192d | ||
|
|
41eb705477 | ||
|
|
2ec835f572 | ||
|
|
59a41e8fcd | ||
|
|
d6442407f5 | ||
|
|
b5c43be135 | ||
|
|
b8f9ac5411 | ||
|
|
21f43ba9b0 | ||
|
|
3c9c3687d6 | ||
|
|
408b74d74c | ||
|
|
fdfcee7b1e | ||
|
|
64f2b213bb | ||
|
|
91fc075a33 | ||
|
|
3aa7dd23c9 | ||
|
|
fccbe9aa4d | ||
|
|
0334058fa4 | ||
|
|
6206f431cf | ||
|
|
46a1102852 | ||
|
|
1b586f3a73 | ||
|
|
53ca6ae1f3 | ||
|
|
95b352064e | ||
|
|
24652228af | ||
|
|
845b5a2a58 | ||
|
|
7381b7ac71 | ||
|
|
0e87bc7be6 | ||
|
|
01d64914c5 | ||
|
|
366239b8b9 | ||
|
|
02041bf2e0 | ||
|
|
216b6a494e | ||
|
|
b948de36fb | ||
|
|
4fb5ff86ee | ||
|
|
9f5f156b9d | ||
|
|
7e12a601b8 | ||
|
|
2a8d7ee0f8 | ||
|
|
fd38799049 | ||
|
|
fa391eed9d | ||
|
|
37ab061f4d | ||
|
|
aaa8867d4a | ||
|
|
062bd81814 | ||
|
|
f4d55c91fe | ||
|
|
326ff54649 | ||
|
|
90a36942b4 | ||
|
|
1ea4b77a9a | ||
|
|
0496de26d3 | ||
|
|
f22be4ebd9 | ||
|
|
34f26ea862 | ||
|
|
9e0a3d46b6 | ||
|
|
90b1cc5103 | ||
|
|
58e0f4ac50 | ||
|
|
e5635f4ab3 | ||
|
|
2065373f67 | ||
|
|
a81539db25 | ||
|
|
2f4e8511cd | ||
|
|
4c02e54298 | ||
|
|
5f3c3ec5e6 | ||
|
|
c4489a0543 | ||
|
|
0eba162ab5 | ||
|
|
f3ca8623f7 | ||
|
|
77020281ae | ||
|
|
f1a9923308 | ||
|
|
2a8a564fbd | ||
|
|
0d28a3edb9 | ||
|
|
ff736d6f6f | ||
|
|
d88d3b0b3a | ||
|
|
b6bdb0dbda | ||
|
|
ed6a5b78ad | ||
|
|
d5de1bf853 | ||
|
|
eb9a3ec654 | ||
|
|
6143f63560 | ||
|
|
37a2015cc5 | ||
|
|
958e273336 | ||
|
|
c92e6a45eb | ||
|
|
0a7e4fa5ce | ||
|
|
8192310dad | ||
|
|
ef369249cb | ||
|
|
a7261ae059 | ||
|
|
635ef16432 | ||
|
|
57fa14b5be | ||
|
|
dbdcb58d64 | ||
|
|
81d64ab939 | ||
|
|
c0a79cc919 | ||
|
|
7e18d3b6ff | ||
|
|
9d5e5c08ab | ||
|
|
5572f735b6 | ||
|
|
e632b1fda7 | ||
|
|
941040e9e8 | ||
|
|
dfa915a6af | ||
|
|
fbcaf0ea18 | ||
|
|
e6978a4e26 | ||
|
|
587914169c | ||
|
|
ed22e9ba3e | ||
|
|
dcbe936c50 | ||
|
|
dffa9f6da6 | ||
|
|
660f8613fd | ||
|
|
06d93b36f9 | ||
|
|
b2d880d749 | ||
|
|
6196aa45ed | ||
|
|
15018291b2 | ||
|
|
bfb272b9e0 | ||
|
|
c0035d1694 | ||
|
|
1e9d8e110b | ||
|
|
b0c08c8c17 | ||
|
|
011c7f5718 | ||
|
|
1cb5de2cd5 | ||
|
|
861fad5819 | ||
|
|
22b4c28f85 | ||
|
|
0e52d9860a | ||
|
|
aba75e1233 | ||
|
|
624cdeacc4 | ||
|
|
41f6948545 | ||
|
|
8332044f75 | ||
|
|
d5ec336eef | ||
|
|
f38d16483a | ||
|
|
e77abc261b | ||
|
|
c69642a460 | ||
|
|
3c4b78e166 | ||
|
|
7d6b6f6681 | ||
|
|
4ba9b34012 | ||
|
|
cb6cf5e257 | ||
|
|
661d9d1901 | ||
|
|
aeb62f9ae3 | ||
|
|
d80174d7c3 | ||
|
|
e2bfa471fa | ||
|
|
04fffe6562 | ||
|
|
0d6b2341b8 | ||
|
|
8b4fb4fe14 | ||
|
|
b230a86d33 | ||
|
|
5167332131 | ||
|
|
7a4b10cc4c | ||
|
|
a5deadf082 | ||
|
|
26a9b4d48e | ||
|
|
7731edf2f5 | ||
|
|
229b908d2e | ||
|
|
3ca84026db | ||
|
|
0af73014cc | ||
|
|
4e7bde8c9e | ||
|
|
9d6128acdc | ||
|
|
e79c6b6312 | ||
|
|
f352fe82a5 | ||
|
|
d265df589e | ||
|
|
7c87747db0 | ||
|
|
425958b616 | ||
|
|
4cc0cd6cab | ||
|
|
d936317143 | ||
|
|
359b4e9ed9 | ||
|
|
1d399c3c88 | ||
|
|
4d7fa05b43 | ||
|
|
4054c4eadd | ||
|
|
f8b98d8329 | ||
|
|
88ca6c94d9 | ||
|
|
f91f212d9f | ||
|
|
36821d095a | ||
|
|
d5e256486e | ||
|
|
42054c3cad | ||
|
|
598aad2140 | ||
|
|
475c60eefc | ||
|
|
86854c7071 | ||
|
|
e3f8777ee8 | ||
|
|
ec8589e4c9 | ||
|
|
b864e7afe4 | ||
|
|
75a811a6df | ||
|
|
2b000474d9 | ||
|
|
0be3c70cd8 | ||
|
|
081f9325f5 | ||
|
|
a7ffa972f3 | ||
|
|
558a016e2c | ||
|
|
3a2171e406 | ||
|
|
42cec5c893 | ||
|
|
55b11e6d38 | ||
|
|
0b7a66ab97 | ||
|
|
ea5b59bfe6 | ||
|
|
8d8fdcb4be | ||
|
|
821b7f22fe | ||
|
|
25afc7da0d | ||
|
|
e2aa117798 | ||
|
|
516982242d | ||
|
|
8bf00084b6 | ||
|
|
81794fcd31 | ||
|
|
22602cc37b | ||
|
|
1b693543aa | ||
|
|
ab2594e341 | ||
|
|
2ff2ea5f3b | ||
|
|
21ffa7c4ba | ||
|
|
696eee9475 | ||
|
|
a9058bf294 | ||
|
|
39c91d3624 | ||
|
|
000730ecaa | ||
|
|
c9fa667252 | ||
|
|
c2ec2ad8fb | ||
|
|
6433f71e8f | ||
|
|
a3fe307400 | ||
|
|
1a1b48e51a | ||
|
|
e8ad47a6ca | ||
|
|
b648e98ad0 | ||
|
|
7ef75f9f75 | ||
|
|
51b9a0d0c4 | ||
|
|
1d350b8ac6 | ||
|
|
a488c266c3 | ||
|
|
86e6ad76cb | ||
|
|
58d9b10d70 | ||
|
|
0a8b5d160b | ||
|
|
18c22faf4d | ||
|
|
5cb524673e | ||
|
|
a66a99bfd8 | ||
|
|
a160b70ced | ||
|
|
8b3b2d04a8 | ||
|
|
936e25b164 | ||
|
|
5ab0a4a671 | ||
|
|
aa65e1edb3 | ||
|
|
d007cb8903 | ||
|
|
d292a81e95 | ||
|
|
22ff397fb1 | ||
|
|
7f70b60f4d | ||
|
|
2a6660ba59 | ||
|
|
1abb449dfb | ||
|
|
65dc960e3b | ||
|
|
0e978349a5 | ||
|
|
e9fa7625f4 | ||
|
|
c0c07fb1b6 | ||
|
|
aa8e8acb7d | ||
|
|
f837d166e5 | ||
|
|
9249242119 | ||
|
|
641a3d39e1 | ||
|
|
6ff2d54347 | ||
|
|
11d21081b4 | ||
|
|
34c290b678 | ||
|
|
ea5061e409 | ||
|
|
4c5bfe2d10 | ||
|
|
c6f1d47dcb | ||
|
|
3179d23cee | ||
|
|
bdd78c31b6 | ||
|
|
c39093d801 | ||
|
|
94ef8879cd | ||
|
|
b7d59060e2 | ||
|
|
032b0e9369 | ||
|
|
0d5d16074f | ||
|
|
7027fd5343 | ||
|
|
7da2fdc3cd | ||
|
|
2673374d18 | ||
|
|
651c870d77 | ||
|
|
aa3569cd57 | ||
|
|
8cd9fedf58 | ||
|
|
e23ae63970 | ||
|
|
31f6a6fa70 | ||
|
|
e54a4f1f48 | ||
|
|
d43019163d | ||
|
|
00c4d6562e | ||
|
|
e86b47175f | ||
|
|
20f40c3229 | ||
|
|
dbfba6a20e | ||
|
|
7ede3ec4b1 | ||
|
|
872f9af6ae | ||
|
|
8f59bacb92 | ||
|
|
be66a9ecf6 | ||
|
|
4836bcc957 | ||
|
|
89852d38ef | ||
|
|
526dd54252 | ||
|
|
8a1a5c236d | ||
|
|
5e11d2b349 | ||
|
|
34fe5a30c6 | ||
|
|
26664dd180 | ||
|
|
4434e43fa1 | ||
|
|
7a55c1a884 | ||
|
|
28e51c9eb1 | ||
|
|
af9d885f8c | ||
|
|
9e8eba797e | ||
|
|
8f1eced69d | ||
|
|
751485fe6b | ||
|
|
a632037866 | ||
|
|
c0e39864c6 | ||
|
|
6e552e15fa | ||
|
|
0851751615 | ||
|
|
6f1c00869c | ||
|
|
1934dca6de | ||
|
|
7a26e4f484 | ||
|
|
9a2913ed1c | ||
|
|
c6926c374d | ||
|
|
3a2fb201a5 | ||
|
|
a95b06fc6b | ||
|
|
92d4b51ad5 | ||
|
|
7e7fb0b7a3 | ||
|
|
ea8bf81058 | ||
|
|
f243851ccd | ||
|
|
7c934ae501 | ||
|
|
aa58c7ec74 | ||
|
|
b56634e691 | ||
|
|
fb3f9cff33 | ||
|
|
da33b31c7d | ||
|
|
9a348fc840 | ||
|
|
007878781c | ||
|
|
cfc4c33801 | ||
|
|
28596edf07 | ||
|
|
7ccdf8be77 | ||
|
|
f5d04750db | ||
|
|
92e9a5e0a7 | ||
|
|
84d59c2873 | ||
|
|
d8a7f8bff2 | ||
|
|
3dd0b69e46 | ||
|
|
7d588b0c7c | ||
|
|
cd14188bc8 | ||
|
|
db109ca0fc | ||
|
|
f1236734bb | ||
|
|
9de53bf788 | ||
|
|
3900fed849 | ||
|
|
96f0dd3cbc | ||
|
|
fa7c61dfab | ||
|
|
d241c2a592 | ||
|
|
f17e663493 | ||
|
|
e45c1dbd6f | ||
|
|
7693ef3bd6 | ||
|
|
99a21dc05d | ||
|
|
abc24c1876 | ||
|
|
6f5e0fe955 | ||
|
|
6a388aaa7c | ||
|
|
2af846e711 | ||
|
|
4915c2b871 | ||
|
|
cceff157dd | ||
|
|
32aba40830 | ||
|
|
f576057274 | ||
|
|
0621eca05e | ||
|
|
a39df51d8a | ||
|
|
e4d43401eb | ||
|
|
d136737872 | ||
|
|
75b1d881ec | ||
|
|
c3bd9415cc | ||
|
|
1e8ca3a3cf | ||
|
|
ab14c30493 | ||
|
|
f22b35e4e5 | ||
|
|
a243d6b057 | ||
|
|
f738424403 | ||
|
|
753a8e8bc4 | ||
|
|
e955089da0 | ||
|
|
9309e609cd | ||
|
|
ade9a05236 | ||
|
|
c48740e20b | ||
|
|
b178dccb9c | ||
|
|
3b83aeb403 | ||
|
|
115afdb07d | ||
|
|
cf814b2d34 | ||
|
|
ecb7f9fe58 | ||
|
|
fa47bebfbc | ||
|
|
8eb802a55b | ||
|
|
af33ebb13b | ||
|
|
9220dc466a | ||
|
|
d18ced9cdd | ||
|
|
7463442e58 | ||
|
|
354d17523f | ||
|
|
a0a3de60be | ||
|
|
5685b565c3 | ||
|
|
76e52b5daf | ||
|
|
fa655ce196 | ||
|
|
194c8c761e | ||
|
|
11115e4d23 | ||
|
|
c91727b75a | ||
|
|
9f76dcd682 | ||
|
|
ef7dd8db2d | ||
|
|
6ab8b63bdd | ||
|
|
68e8b595de | ||
|
|
722d4842df | ||
|
|
de575c80b9 | ||
|
|
3a2e9f20f6 | ||
|
|
7e66b859b2 | ||
|
|
aaf7c5b35e | ||
|
|
c030e77861 | ||
|
|
219a74c014 | ||
|
|
7370fd5560 | ||
|
|
e284a95cc3 | ||
|
|
616986a5f3 | ||
|
|
b19d273beb | ||
|
|
31b40eebe8 | ||
|
|
035deae1c6 | ||
|
|
5161239c9f | ||
|
|
9a65fa304c | ||
|
|
7c1c9af5d4 | ||
|
|
4f8eeaedef | ||
|
|
d680e28a11 | ||
|
|
7fd538c1b6 | ||
|
|
f522849a4d | ||
|
|
077812b2ab | ||
|
|
bdf958df30 | ||
|
|
70fc42cb28 | ||
|
|
5ebf39784a | ||
|
|
9780e55274 | ||
|
|
4f5b896a0b | ||
|
|
813b581127 | ||
|
|
778413168b | ||
|
|
0807139c1d | ||
|
|
fa1cdb09fc | ||
|
|
8cc8f280eb | ||
|
|
9896314f5b | ||
|
|
c4045f57e3 | ||
|
|
6557a096d6 | ||
|
|
f44cc517a2 | ||
|
|
abfd4da287 | ||
|
|
59fba2d6ea | ||
|
|
ed570e4b2a | ||
|
|
484adac0bb | ||
|
|
f64e080d9a | ||
|
|
e44c1d3ace | ||
|
|
186b355b28 | ||
|
|
0d3e309ebc | ||
|
|
2110dc5a6d | ||
|
|
aef3846c13 | ||
|
|
4af5424242 | ||
|
|
c5175526dd | ||
|
|
3299f687f5 | ||
|
|
9c7d183a94 | ||
|
|
d02f671737 | ||
|
|
d709622bd2 | ||
|
|
e64afde073 | ||
|
|
2a1090a637 | ||
|
|
228c68a9cd | ||
|
|
6e1dfb0d1a | ||
|
|
de8b585ab7 | ||
|
|
c4b592d379 | ||
|
|
fe99ea9aab | ||
|
|
7f19a39a3b | ||
|
|
a06c38b486 | ||
|
|
63b9e598a3 | ||
|
|
60ccb41fac | ||
|
|
06593fb0f2 | ||
|
|
a193ced7fa | ||
|
|
c8870b7c69 | ||
|
|
b6a08208e1 | ||
|
|
fb4b800820 | ||
|
|
0cba23716d | ||
|
|
b85bf25e97 | ||
|
|
2474c2ae94 | ||
|
|
92d95cc9d3 | ||
|
|
7c61249ae6 | ||
|
|
686516f90a | ||
|
|
ea2cc2b907 | ||
|
|
cdfa11f550 | ||
|
|
e78a8c94b6 | ||
|
|
f6518a7bd5 | ||
|
|
d59ca4efdb | ||
|
|
3ce212e0a6 | ||
|
|
e9ce00d874 | ||
|
|
c5029bcbf3 | ||
|
|
6f49520042 | ||
|
|
05c6fbcae6 | ||
|
|
dd0e24f4b0 | ||
|
|
32eb4b9055 | ||
|
|
ee3fec3167 | ||
|
|
431603ad69 | ||
|
|
a19ba5fea0 | ||
|
|
f28ed55aeb | ||
|
|
0a903be7d0 | ||
|
|
cfcf47c064 | ||
|
|
b630de1103 | ||
|
|
1811c6bccf | ||
|
|
e2dc7ac2a9 | ||
|
|
95cc1ff542 | ||
|
|
330e21c986 | ||
|
|
f960d753e4 | ||
|
|
3319780e96 | ||
|
|
8a6d93aeed | ||
|
|
640d00ea9d | ||
|
|
071d47fa3b | ||
|
|
6148f8b7d2 | ||
|
|
76285469d3 | ||
|
|
3d30d605f5 | ||
|
|
7ed58cb663 | ||
|
|
6e56bb623c | ||
|
|
371f4ba6b3 | ||
|
|
0aa5e75000 | ||
|
|
491c321720 | ||
|
|
b4a41a8f70 | ||
|
|
a3acaa000c | ||
|
|
098f5ae221 | ||
|
|
1406d9ccde | ||
|
|
06e85ecfa6 | ||
|
|
1679696612 | ||
|
|
07408cbd1f | ||
|
|
d7192fe68c | ||
|
|
3eece29807 | ||
|
|
601cfea6a3 | ||
|
|
7ca1bd314b | ||
|
|
031278f661 | ||
|
|
9724a0538b | ||
|
|
87ad80edf9 | ||
|
|
567b349c2b | ||
|
|
4d9cad180d | ||
|
|
a3cf4ea2f6 | ||
|
|
71f85cc330 | ||
|
|
53a8aeb6e7 | ||
|
|
80f638fe19 | ||
|
|
953c23b1bc | ||
|
|
181adc6a4e | ||
|
|
c36635c112 | ||
|
|
f8a39e3bb1 | ||
|
|
0e6c89a5c8 | ||
|
|
cc20482aa9 | ||
|
|
a546acda8c | ||
|
|
a32538bb66 | ||
|
|
2ffb6e1b15 | ||
|
|
32ce72cb9e | ||
|
|
f8bce131c0 | ||
|
|
0df20da4dd | ||
|
|
9456732b86 | ||
|
|
2fc1e64319 | ||
|
|
3ac2d06bd1 | ||
|
|
18fda7b42f | ||
|
|
db52fd8e4d | ||
|
|
0ec8cf8e80 | ||
|
|
4e4772bb5b | ||
|
|
26b512ea1b | ||
|
|
7d8edeff4e | ||
|
|
78ccb44a90 | ||
|
|
278d22ce8f | ||
|
|
9a522dda6e | ||
|
|
100004eeaf | ||
|
|
6a664cb114 | ||
|
|
51726b4d43 | ||
|
|
c02dc8b2c9 | ||
|
|
a8e7c03171 | ||
|
|
f5ae384d4f | ||
|
|
84d11b5e53 | ||
|
|
417205623a | ||
|
|
2f2c0a13fb | ||
|
|
622f241317 | ||
|
|
286ced4c2f | ||
|
|
25a8a42447 | ||
|
|
492fd5cb6b | ||
|
|
a16715ac62 | ||
|
|
9ede4dcfbb | ||
|
|
79474c6b16 | ||
|
|
2cae0f6290 | ||
|
|
78744c4f7a | ||
|
|
2abb58d758 | ||
|
|
1580e331ef | ||
|
|
6d1ff7e966 | ||
|
|
17d9b5006d | ||
|
|
5a57447a8c | ||
|
|
669dbca959 | ||
|
|
70446f46c2 | ||
|
|
0e6f5e08e1 | ||
|
|
1775b65e07 | ||
|
|
9ae3fc6523 | ||
|
|
4a10214be2 | ||
|
|
2acfb7c002 | ||
|
|
c754d8011d | ||
|
|
95104b0fbd | ||
|
|
d07de2d307 | ||
|
|
9414f92fa9 | ||
|
|
8096be089e | ||
|
|
fca3493442 | ||
|
|
5a0c5f8fea | ||
|
|
ec1f0e7551 | ||
|
|
967f3230f5 | ||
|
|
59610c4004 | ||
|
|
fabe79f7af | ||
|
|
124aa000af | ||
|
|
2dd47239de | ||
|
|
6545336206 | ||
|
|
5cd34aca27 | ||
|
|
95f19b4542 | ||
|
|
90d7c4ef3d | ||
|
|
1a97f6721f | ||
|
|
3c4b5d4281 | ||
|
|
968b7dd173 | ||
|
|
3cb804de26 | ||
|
|
9f8c5456be | ||
|
|
0d31bbc7fa | ||
|
|
ed56b0baba | ||
|
|
18030bd85d | ||
|
|
7bd273b818 | ||
|
|
a3a14b9db7 | ||
|
|
6f1cffeb28 | ||
|
|
7506db4ccb | ||
|
|
2fddc68fdf | ||
|
|
0f716aced7 | ||
|
|
a3c96c9252 | ||
|
|
e800db562f | ||
|
|
5e38b48dd6 | ||
|
|
56053c37cf | ||
|
|
514ba15d6a | ||
|
|
afaa66b657 | ||
|
|
3ad94d6072 | ||
|
|
97ce883217 | ||
|
|
861670ba2a | ||
|
|
f5dd6f7f37 | ||
|
|
b5cef5c7ea | ||
|
|
cf5112b26f | ||
|
|
44e7cbf019 | ||
|
|
6f848b6dba | ||
|
|
95a4f61499 | ||
|
|
c27dc38e85 | ||
|
|
cd3f2523f1 | ||
|
|
a379b6ed11 | ||
|
|
fb9e4cf463 | ||
|
|
8e611e8414 | ||
|
|
9466e154b4 | ||
|
|
2b62707051 | ||
|
|
ebf8dc6b03 | ||
|
|
d7b7d5f6ee | ||
|
|
709955b601 | ||
|
|
1db3577bcb | ||
|
|
0bfc57022d | ||
|
|
1511dd4f84 | ||
|
|
1c132c8587 | ||
|
|
40c6d57804 | ||
|
|
a09757f104 | ||
|
|
304a96d7d6 | ||
|
|
4e7dc97bdc | ||
|
|
103d12a877 | ||
|
|
b47931978f | ||
|
|
1db4253886 | ||
|
|
800d5cd16f | ||
|
|
c7df9c6c47 | ||
|
|
f601390ef8 | ||
|
|
7bab32ef89 | ||
|
|
c50772d19f | ||
|
|
c2a4e4effc | ||
|
|
6738c1dded | ||
|
|
d5e629ad0e | ||
|
|
aa9dbb1b03 | ||
|
|
5df81de7af | ||
|
|
a7c02c4538 | ||
|
|
8fbabab1a8 | ||
|
|
4a60cac916 | ||
|
|
717a958256 | ||
|
|
4ed7b7f751 | ||
|
|
a37d13c95d | ||
|
|
c3ae03ff18 | ||
|
|
351424e719 | ||
|
|
d792d9e49e | ||
|
|
d3b32caea4 | ||
|
|
0589c19d52 | ||
|
|
76abb2e623 | ||
|
|
2bdefea9d6 | ||
|
|
4865a22f78 | ||
|
|
ff987ccf11 | ||
|
|
bda7041294 | ||
|
|
d39d96b700 | ||
|
|
2d56df67cd | ||
|
|
57ebe1b27d | ||
|
|
28076f3d4b | ||
|
|
9a42eb541e | ||
|
|
cd87d20f46 | ||
|
|
c097ea5dd2 | ||
|
|
c98c128fe8 | ||
|
|
367d4d1098 | ||
|
|
3d91b1f67f | ||
|
|
82d08dccc6 | ||
|
|
8872abcbc4 | ||
|
|
37c6555b44 | ||
|
|
7667727021 | ||
|
|
e04aa96b4d | ||
|
|
5ab5ac5448 | ||
|
|
3d3ef36e97 | ||
|
|
1829d86ef5 | ||
|
|
9e00ac89d5 | ||
|
|
04ee5983fe | ||
|
|
47b9809d23 | ||
|
|
0116218fa8 | ||
|
|
c4dc1b5c23 | ||
|
|
7e7039b53c | ||
|
|
2378be4e93 | ||
|
|
8c8d7f3c60 | ||
|
|
e4c899a08c | ||
|
|
f54bdecff2 | ||
|
|
71d482df47 | ||
|
|
a9afcb159a | ||
|
|
a62c106974 | ||
|
|
6f218d7472 | ||
|
|
d8713d78f5 | ||
|
|
e282884e54 | ||
|
|
dbb4aef5e3 | ||
|
|
bf4576dc91 | ||
|
|
c3e37a0cde | ||
|
|
f27aa27a0c | ||
|
|
a1a2c411b2 | ||
|
|
b7a4f15b34 | ||
|
|
ad9daadf8a | ||
|
|
95f53461c2 | ||
|
|
d11317bcab | ||
|
|
94792dd88f | ||
|
|
5225e29ce7 | ||
|
|
f81684141e | ||
|
|
6fefd5d330 | ||
|
|
6bbbb1ab41 | ||
|
|
f1ed8c8a2e | ||
|
|
0458833072 | ||
|
|
abea1c38a9 | ||
|
|
9fbc265eb8 | ||
|
|
d34c4784a5 | ||
|
|
fdcb3b7ebb | ||
|
|
9472907ae1 | ||
|
|
ae2c81ff38 | ||
|
|
0f553fe10b | ||
|
|
271d18eb08 | ||
|
|
7c8b4c1a8b | ||
|
|
8b85d14b92 | ||
|
|
cf5b6f6974 | ||
|
|
8c1d23a0e2 | ||
|
|
ede0f3ab3d | ||
|
|
fd787c5e4e | ||
|
|
40d43ea88d | ||
|
|
5e9810396f | ||
|
|
f66ee4dfd7 | ||
|
|
8f6aad2f48 | ||
|
|
eaefc8b9d6 | ||
|
|
1f9e2188a6 | ||
|
|
956d765786 | ||
|
|
c52f1258a8 | ||
|
|
dea853d3a3 | ||
|
|
4735c45c51 | ||
|
|
fa90ab1407 | ||
|
|
d8837cea6f | ||
|
|
c3184aea63 | ||
|
|
5aa311d330 | ||
|
|
23a2b11abf | ||
|
|
43d56f9ba9 | ||
|
|
e521f0eb68 | ||
|
|
c8b60f013b | ||
|
|
2bb5f41611 | ||
|
|
f35b5d28db | ||
|
|
df5d9c77f4 | ||
|
|
d8475092d1 | ||
|
|
5008972fef | ||
|
|
d8cbbcaa9d | ||
|
|
404b68da88 | ||
|
|
b42a5050fb | ||
|
|
3e592531eb | ||
|
|
90e6d0c2ac | ||
|
|
e4b4e5aa31 | ||
|
|
0435e76250 | ||
|
|
03ec6e4d01 | ||
|
|
9253e7bdf7 | ||
|
|
6be0bbb886 | ||
|
|
5a11086d64 | ||
|
|
d15fe5a6b3 | ||
|
|
8892f71dd0 | ||
|
|
73f1a49137 | ||
|
|
c92c7a69fd | ||
|
|
7d6595fd18 | ||
|
|
50ea86fe8b | ||
|
|
2e5704d101 | ||
|
|
8bdbc20e74 | ||
|
|
23008db6e1 | ||
|
|
e3cd154317 | ||
|
|
259eaab9a9 | ||
|
|
2764a8ee8d | ||
|
|
f53a8e712f | ||
|
|
1c9a499135 | ||
|
|
c1a77a0c9f | ||
|
|
2cd247e819 | ||
|
|
dcbf62b43d | ||
|
|
7d5e34287c | ||
|
|
4c45921349 | ||
|
|
feff00e1a5 | ||
|
|
a102e01ce1 | ||
|
|
90aa7595b4 | ||
|
|
2941d5c714 | ||
|
|
a86d40ccd4 | ||
|
|
044c473de2 | ||
|
|
e72cda99fd | ||
|
|
5ae5ec986e | ||
|
|
7f9d1d6ab9 | ||
|
|
56beb01724 | ||
|
|
9a18e21066 | ||
|
|
4c37489f4c | ||
|
|
f7a26472af | ||
|
|
b1f68685ec | ||
|
|
99f7184073 | ||
|
|
c69b4310c8 | ||
|
|
b21786947f | ||
|
|
8b7faa31e1 | ||
|
|
6eb7530083 | ||
|
|
55fe92bb8f | ||
|
|
7a6dbaa89b | ||
|
|
b1bbe966c4 | ||
|
|
d07ccc5a39 | ||
|
|
d278e49475 | ||
|
|
6e25d955f4 | ||
|
|
d35ac956d1 | ||
|
|
91bc32dc16 | ||
|
|
4dea922610 | ||
|
|
df1637c580 | ||
|
|
e50cff69bb | ||
|
|
36cc84a2a9 | ||
|
|
e97dddcdca | ||
|
|
9988618e0e | ||
|
|
18bd51707c | ||
|
|
c7acfc90b9 | ||
|
|
c9aa1883ed | ||
|
|
78772ada0d | ||
|
|
282ca09f8e | ||
|
|
e2d44e30c7 | ||
|
|
96b60ed956 | ||
|
|
2192824ad8 | ||
|
|
3a84c8b58d | ||
|
|
e5c4362a98 | ||
|
|
97abe22963 | ||
|
|
9dd3640464 | ||
|
|
7e758b1cf8 | ||
|
|
b9d850227d | ||
|
|
56606f3475 | ||
|
|
0528c5a22a | ||
|
|
0f6424efda | ||
|
|
40fc01f406 | ||
|
|
2801e6fad8 | ||
|
|
7f59b4b2ca | ||
|
|
acf6aec71c | ||
|
|
620058cc57 | ||
|
|
ac2f7a7f6a | ||
|
|
82f37bf0d1 | ||
|
|
fa5950eb00 | ||
|
|
99957384ea | ||
|
|
4cd9ced8dc | ||
|
|
2cc5473021 | ||
|
|
c0dcf6e878 | ||
|
|
43ea73faa6 | ||
|
|
12ab9eda8d | ||
|
|
3f327cc4c6 | ||
|
|
567184e21e | ||
|
|
12a5e17afb | ||
|
|
dbc0191d5f | ||
|
|
7f1c98177b | ||
|
|
f0a8f21190 | ||
|
|
e6c6fe3275 | ||
|
|
390e92688c | ||
|
|
332a909d44 | ||
|
|
2039757b85 | ||
|
|
f88eec0de2 | ||
|
|
2686f9b3e8 | ||
|
|
d460a30711 | ||
|
|
3f42f32648 | ||
|
|
344057ac50 | ||
|
|
9d2c0c231c | ||
|
|
1bc534247c | ||
|
|
fdaac1dbf8 | ||
|
|
e178ef2520 | ||
|
|
47098efbda | ||
|
|
7b19e99edd | ||
|
|
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 |
31
.gitattributes
vendored
Normal file
31
.gitattributes
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# Per default everything gets normalized and gets LF line endings on checkout.
|
||||
* text eol=lf
|
||||
|
||||
# These will always have CRLF line endings on checkout.
|
||||
*.vcxproj text eol=crlf
|
||||
*.props text eol=crlf
|
||||
*.bat text eol=crlf
|
||||
|
||||
# These are binary so should never be modified by git.
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.dxf binary
|
||||
|
||||
# These should also not be modified by git.
|
||||
tests/basics/string_cr_conversion.py -text
|
||||
tests/basics/string_crlf_conversion.py -text
|
||||
stmhal/startup_stm32f40xx.s -text
|
||||
stmhal/pybcdc.inf_template -text
|
||||
stmhal/usbd_* -text
|
||||
stmhal/boards/*/stm32f4xx_hal_conf.h -text
|
||||
stmhal/cmsis/** -text
|
||||
stmhal/hal/** -text
|
||||
stmhal/usbdev/** -text
|
||||
stmhal/usbhost/** -text
|
||||
cc3200/hal/aes.c -text
|
||||
cc3200/hal/aes.h -text
|
||||
cc3200/hal/des.c -text
|
||||
cc3200/hal/i2s.c -text
|
||||
cc3200/hal/i2s.h -text
|
||||
cc3200/version.h -text
|
||||
lib/fatfs/** -text
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -33,5 +33,7 @@ tests/*.out
|
||||
######################
|
||||
__pycache__/
|
||||
|
||||
# Customized Makefile overrides
|
||||
# Customized Makefile/project overrides
|
||||
######################
|
||||
GNUmakefile
|
||||
user.props
|
||||
|
||||
7
.gitmodules
vendored
Normal file
7
.gitmodules
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
[submodule "lib/axtls"]
|
||||
path = lib/axtls
|
||||
url = https://github.com/pfalcon/axtls
|
||||
branch = micropython
|
||||
[submodule "lib/libffi"]
|
||||
path = lib/libffi
|
||||
url = https://github.com/atgreen/libffi
|
||||
19
.travis.yml
19
.travis.yml
@@ -7,14 +7,16 @@ 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
|
||||
- make -C unix deplibs CC=gcc-4.7
|
||||
- make -C unix CC=gcc-4.7
|
||||
- make -C unix-cpy CC=gcc-4.7
|
||||
- make -C bare-arm
|
||||
- make -C qemu-arm test
|
||||
- make -C stmhal
|
||||
@@ -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)
|
||||
|
||||
914
ACKNOWLEDGEMENTS
Normal file
914
ACKNOWLEDGEMENTS
Normal file
@@ -0,0 +1,914 @@
|
||||
The MicroPython 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
|
||||
506 Glenn Ruben Bakke, Norway
|
||||
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
|
||||
673 Xie Yanbo, China
|
||||
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
|
||||
768 Sam Shams
|
||||
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)
|
||||
873 Markus Schuss, Austria
|
||||
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
|
||||
1013 Herbert Graef, Stuttgart
|
||||
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
|
||||
1505 Victor Suarez, Argentina
|
||||
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
|
||||
1928 Peter Korcz
|
||||
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
|
||||
@@ -33,37 +33,50 @@ Braces:
|
||||
closing brace.
|
||||
|
||||
Header files:
|
||||
- Try to stick to the Plan 9 header style, where header files do not
|
||||
include other header files.
|
||||
- Don't protect a header file from multiple inclusion with #if directives.
|
||||
- Header files should be protected from multiple inclusion with #if
|
||||
directives. See an existing header for naming convention.
|
||||
|
||||
Type names and declarations:
|
||||
- When defining a type, put '_t' after it.
|
||||
Names:
|
||||
- Use underscore_case, not camelCase for all names.
|
||||
- Use CAPS_WITH_UNDERSCORE for enums and macros.
|
||||
- When defining a type use underscore_case and put '_t' after it.
|
||||
|
||||
Integer types: Micro Python runs on 32 and 64 bit machines (and one day
|
||||
maybe 16 bit), so it's important to use the correctly-sized (and signed)
|
||||
integer types. The general guidelines are:
|
||||
Integer types: MicroPython runs on 16, 32, and 64 bit machines, so it's
|
||||
important to use the correctly-sized (and signed) integer types. The
|
||||
general guidelines are:
|
||||
- For most cases use mp_int_t for signed and mp_uint_t for unsigned
|
||||
integer values. These are guaranteed to be machine-word sized and
|
||||
therefore big enough to hold the value from a Micro Python small-int
|
||||
therefore big enough to hold the value from a MicroPython small-int
|
||||
object.
|
||||
- Use size_t for things that count bytes / sizes of objects.
|
||||
- You can use int/uint, but remember that they may be 16-bits wide.
|
||||
- If in doubt, use mp_int_t/mp_uint_t.
|
||||
|
||||
Comments:
|
||||
- Be concise and only write comments for things that are not obvious.
|
||||
- Use `// ` prefix, NOT `/* ... */`. No extra fluff.
|
||||
|
||||
Memory allocation:
|
||||
- Use m_new, m_renew, m_del (and friends) to allocate and free heap memory.
|
||||
These macros are defined in py/misc.h.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Braces and spaces:
|
||||
Braces, spaces, names and comments:
|
||||
|
||||
int foo(int x, int y) {
|
||||
if (x < y) {
|
||||
foo(y, x);
|
||||
#define TO_ADD (123)
|
||||
|
||||
// This function will always recurse indefinitely and is only used to show
|
||||
// coding style
|
||||
int foo_function(int x, int some_value) {
|
||||
if (x < some_value) {
|
||||
foo(some_value, x);
|
||||
} else {
|
||||
foo(x + 1, y - 1);
|
||||
foo(x + TO_ADD, some_value - 1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < x; i++) {
|
||||
for (int my_counter = 0; my_counter < x; my_counter++) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
8
CONTRIBUTING.md
Normal file
8
CONTRIBUTING.md
Normal file
@@ -0,0 +1,8 @@
|
||||
When reporting an issue and especially submitting a pull request, please
|
||||
make sure that you are acquainted with Contributor Guidelines:
|
||||
|
||||
https://github.com/micropython/micropython/wiki/ContributorGuidelines
|
||||
|
||||
and Code Conventions:
|
||||
|
||||
https://github.com/micropython/micropython/blob/master/CODECONVENTIONS.md
|
||||
108
README.md
108
README.md
@@ -1,45 +1,56 @@
|
||||
[![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
|
||||
========================
|
||||
The MicroPython project
|
||||
=======================
|
||||
<p align="center">
|
||||
<img src="https://raw.githubusercontent.com/micropython/micropython/master/logo/upython-with-micro.jpg" alt="MicroPython Logo"/>
|
||||
</p>
|
||||
|
||||
This is the Micro Python project, which aims to put an implementation
|
||||
of Python 3.x on a microcontroller.
|
||||
This is the MicroPython project, which aims to put an implementation
|
||||
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,
|
||||
MicroPython 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.
|
||||
- unix/ -- a version of Micro Python that runs on Unix.
|
||||
- stmhal/ -- a version of Micro Python that runs on the Micro Python board
|
||||
- py/ -- the core Python implementation, including compiler, runtime, and
|
||||
core library.
|
||||
- unix/ -- a version of MicroPython that runs on Unix.
|
||||
- stmhal/ -- a version of MicroPython that runs on the MicroPython 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 MicroPython port. Start with this if you want
|
||||
to port MicroPython 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.
|
||||
- unix-cpy/ -- a version of Micro Python that outputs bytecode (for testing).
|
||||
- bare-arm/ -- a bare minimum version of MicroPython for ARM MCUs. Used
|
||||
mostly to control code size.
|
||||
- teensy/ -- a version of MicroPython that runs on the Teensy 3.1
|
||||
(preliminary but functional).
|
||||
- pic16bit/ -- a version of MicroPython for 16-bit PIC microcontrollers.
|
||||
- cc3200/ -- a version of MicroPython that runs on the CC3200 from TI.
|
||||
- esp8266/ -- an experimental port for ESP8266 WiFi modules.
|
||||
- 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).
|
||||
@@ -53,7 +64,7 @@ as ARM and MIPS. Making full-featured port to another architecture requires
|
||||
writing some assembly code for the exception handling and garbage collection.
|
||||
Alternatively, fallback implementation based on setjmp/longjmp can be used.
|
||||
|
||||
To build:
|
||||
To build (*):
|
||||
|
||||
$ cd unix
|
||||
$ make
|
||||
@@ -63,14 +74,55 @@ Then to give it a try:
|
||||
$ ./micropython
|
||||
>>> list(5 * x + y for x in range(10) for y in [4, 2, 1])
|
||||
|
||||
Use `CTRL-D` (i.e. EOF) to exit the shell.
|
||||
Learn about command-line options (in particular, how to increase heap size
|
||||
which may be needed for larger applications):
|
||||
|
||||
$ ./micropython --help
|
||||
|
||||
Run complete testsuite:
|
||||
|
||||
$ make test
|
||||
|
||||
Debian/Ubuntu/Mint derivative Linux distros will require build-essentials and
|
||||
libreadline-dev packages installed. To build FFI (Foreign Function Interface)
|
||||
module, libffi-dev and pkg-config packages are required. If you have problems
|
||||
with some dependencies, they can be disabled in unix/mpconfigport.mk .
|
||||
Unix version comes with a builtin package manager called upip, e.g.:
|
||||
|
||||
$ ./micropython -m upip install micropython-pystone
|
||||
$ ./micropython -m pystone
|
||||
|
||||
Browse available modules on
|
||||
[PyPI](https://pypi.python.org/pypi?%3Aaction=search&term=micropython).
|
||||
Standard library modules come from
|
||||
[micropython-lib](https://github.com/micropython/micropython-lib) project.
|
||||
|
||||
External dependencies
|
||||
---------------------
|
||||
|
||||
Building Unix version requires some dependencies installed. For
|
||||
Debian/Ubuntu/Mint derivative Linux distros, install `build-essentials`
|
||||
(includes toolchain and make), `libffi-dev`, and `pkg-config` packages.
|
||||
|
||||
Other dependencies can be built together with MicroPython. Oftentimes,
|
||||
you need to do this to enable extra features or capabilities. To build
|
||||
these additional dependencies, first fetch git submodules for them:
|
||||
|
||||
$ git submodule update --init
|
||||
|
||||
Use this same command to get the latest versions of dependencies, as
|
||||
they are updated from time to time. After that, in `unix/` dir, execute:
|
||||
|
||||
$ make deplibs
|
||||
|
||||
This will build all available dependencies (regardless whether they
|
||||
are used or not). If you intend to build MicroPython with additional
|
||||
options (like cross-compiling), the same set of options should be passed
|
||||
to `make deplibs`. To actually enabled use of dependencies, edit
|
||||
`unix/mpconfigport.mk` file, which has inline descriptions of the options.
|
||||
For example, to build SSL module (required for `upip` tool described above),
|
||||
set `MICROPY_PY_USSL` to 1.
|
||||
|
||||
In `unix/mpconfigport.mk`, you can also disable some dependencies enabled
|
||||
by default, like FFI support, which requires libffi development files to
|
||||
be installed.
|
||||
|
||||
The STM version
|
||||
---------------
|
||||
@@ -110,6 +162,8 @@ preferably in a virtualenv:
|
||||
|
||||
In `micropython/docs`, build the docs:
|
||||
|
||||
make html
|
||||
make MICROPY_PORT=<port_name> BUILDDIR=<port_name>/build html
|
||||
|
||||
You'll find the index page at `micropython/docs/build/html/index.html`.
|
||||
Where `<port_name>` can be `unix`, `pyboard`, `wipy` or `esp8266`.
|
||||
|
||||
You'll find the index page at `micropython/docs/<port_name>/build/html/index.html`.
|
||||
|
||||
@@ -8,7 +8,7 @@ include ../py/py.mk
|
||||
|
||||
CROSS_COMPILE = arm-none-eabi-
|
||||
|
||||
INC = -I.
|
||||
INC += -I.
|
||||
INC += -I..
|
||||
INC += -I$(BUILD)
|
||||
|
||||
|
||||
@@ -6,9 +6,8 @@
|
||||
#include "py/compile.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/repl.h"
|
||||
#include "py/pfenv.h"
|
||||
|
||||
void do_str(const char *src) {
|
||||
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
|
||||
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||
if (lex == NULL) {
|
||||
return;
|
||||
@@ -17,19 +16,20 @@ void do_str(const char *src) {
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
qstr source_name = lex->source_name;
|
||||
mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT);
|
||||
mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, true);
|
||||
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
|
||||
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true);
|
||||
mp_call_function_0(module_fun);
|
||||
nlr_pop();
|
||||
} else {
|
||||
// uncaught exception
|
||||
mp_obj_print_exception(printf_wrapper, NULL, (mp_obj_t)nlr.ret_val);
|
||||
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
mp_init();
|
||||
do_str("print('hello world!', list(x+1 for x in range(10)), end='eol\n')");
|
||||
do_str("print('hello world!', list(x+1 for x in range(10)), end='eol\\n')", MP_PARSE_SINGLE_INPUT);
|
||||
do_str("for i in range(10):\n print(i)", MP_PARSE_FILE_INPUT);
|
||||
mp_deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
|
||||
// options to control how Micro Python is built
|
||||
|
||||
#define MICROPY_QSTR_BYTES_IN_HASH (1)
|
||||
#define MICROPY_ALLOC_PATH_MAX (512)
|
||||
#define MICROPY_EMIT_X64 (0)
|
||||
#define MICROPY_EMIT_THUMB (0)
|
||||
#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)
|
||||
@@ -16,15 +19,19 @@
|
||||
#define MICROPY_ENABLE_SOURCE_LINE (0)
|
||||
#define MICROPY_ENABLE_DOC_STRING (0)
|
||||
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
|
||||
#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0)
|
||||
#define MICROPY_PY_BUILTINS_BYTEARRAY (0)
|
||||
#define MICROPY_PY_BUILTINS_MEMORYVIEW (0)
|
||||
#define MICROPY_PY_BUILTINS_ENUMERATE (0)
|
||||
#define MICROPY_PY_BUILTINS_FROZENSET (0)
|
||||
#define MICROPY_PY_BUILTINS_REVERSED (0)
|
||||
#define MICROPY_PY_BUILTINS_SET (0)
|
||||
#define MICROPY_PY_BUILTINS_SLICE (0)
|
||||
#define MICROPY_PY_BUILTINS_PROPERTY (0)
|
||||
#define MICROPY_PY___FILE__ (0)
|
||||
#define MICROPY_PY_GC (0)
|
||||
#define MICROPY_PY_ARRAY (0)
|
||||
#define MICROPY_PY_ATTRTUPLE (0)
|
||||
#define MICROPY_PY_COLLECTIONS (0)
|
||||
#define MICROPY_PY_MATH (0)
|
||||
#define MICROPY_PY_CMATH (0)
|
||||
@@ -50,6 +57,9 @@ typedef void *machine_ptr_t; // must be of pointer size
|
||||
typedef const void *machine_const_ptr_t; // must be of pointer size
|
||||
typedef long mp_off_t;
|
||||
|
||||
// dummy print
|
||||
#define MP_PLAT_PRINT_STRN(str, len) (void)0
|
||||
|
||||
// extra built in names to add to the global namespace
|
||||
extern const struct _mp_obj_fun_builtin_t mp_builtin_open_obj;
|
||||
#define MICROPY_PORT_BUILTINS \
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,26 +1,27 @@
|
||||
# Select the board to build for: if not given on the command line,
|
||||
# then default to LAUNCHXL
|
||||
BOARD ?= LAUNCHXL
|
||||
# then default to WIPY
|
||||
BOARD ?= WIPY
|
||||
ifeq ($(wildcard boards/$(BOARD)/.),)
|
||||
$(error Invalid BOARD specified)
|
||||
endif
|
||||
|
||||
# Make 'release' the default build type
|
||||
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
|
||||
CFLAGS += -Iboards/$(BOARD)
|
||||
|
||||
LDFLAGS = -Wl,-nostdlib -Wl,--gc-sections -Wl,-Map=$@.map --specs=nano.specs
|
||||
LDFLAGS = -Wl,-nostdlib -Wl,--gc-sections -Wl,-Map=$@.map
|
||||
|
||||
ifeq ($(BTARGET), application)
|
||||
# qstr definitions (must come before including py.mk)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Build Instructions for the CC3200
|
||||
|
||||
Currently the CC3200 port of Micro Python builds under Linux and OSX and not under Windows.
|
||||
Currently the CC3200 port of MicroPython builds under Linux and OSX **but not under Windows**.
|
||||
|
||||
The tool chain required for the build can be found at <https://launchpad.net/gcc-arm-embedded>.
|
||||
|
||||
@@ -13,43 +13,55 @@ In order to debug the port specific code, optimizations need to be disabled on t
|
||||
port file (check the Makefile for specific details). You can use CCS from TI.
|
||||
Use the CC3200.ccxml file supplied with this distribution for the debuuger configuration.
|
||||
```bash
|
||||
make BTARGET=application BTYPE=debug
|
||||
make BTARGET=application BTYPE=debug BOARD=LAUNCHXL
|
||||
```
|
||||
## To build an image suitable to be flashed to the device:
|
||||
```bash
|
||||
make BTARGET=application BTYPE=release
|
||||
make BTARGET=application BTYPE=release BOARD=LAUNCHXL
|
||||
```
|
||||
## Building the bootloader
|
||||
```bash
|
||||
make BTARGET=bootloader BTYPE=release
|
||||
make BTARGET=bootloader BTYPE=release BOARD=LAUNCHXL
|
||||
```
|
||||
|
||||
## Regarding old revisions of the CC3200-LAUNCHXL
|
||||
First silicon (pre-release) revisions of the CC3200 had issues with the ram blocks, and MicroPython cannot run
|
||||
there. Make sure to use a **v4.1 (or higer) LAUNCHXL board** when trying this port, otherwise it won't work.
|
||||
|
||||
## 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.
|
||||
- Format the serial flash (select 1MB size in case of the CC3200-LAUNCHXL, 2MB in case of the WiPy, leave the rest unchecked).
|
||||
- Mark the following files for erasing: `/cert/ca.pem`, `/cert/client.pem`, `/cert/private.key` and `/tmp/pac.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.
|
||||
- Flash the latest service pack (servicepack_1.0.0.10.0.bin) using the "Service Pack Update" button.
|
||||
- Close CCS_Uniflash, remove the SOP2 jumper and reset the board.
|
||||
|
||||
## Updating the board to with new software version
|
||||
- Make sure the board is running and connected to the same network as the computer.
|
||||
|
||||
```bash
|
||||
make BTARGET=application BTYPE=release BOARD=LAUNCHXL WIPY_IP=192.168.1.1 WIPY_USER=micro WIPY_PWD=python deploy
|
||||
```
|
||||
|
||||
If `WIPY_IP`, `WIPY_USER` or `WIPY_PWD` are omitted the default values (the ones shown above) will be used.
|
||||
|
||||
## Playing with MicroPython and the CC3200:
|
||||
|
||||
Once the software is running, you have two options to access the MicroPython REPL:
|
||||
|
||||
- Through the UART.
|
||||
**Connect to PORT 22, baud rate = 115200, parity = none, stop bits = 1**
|
||||
- Through telnet.
|
||||
* Connect to the network created by the board (as boots up in AP mode), **ssid = "micropy-wlan", key = "micropython"**
|
||||
* Connect to the network created by the board (as boots up in AP mode), **ssid = "wipy-wlan", key = "www.wipy.io"**.
|
||||
* You can also reinitialize the WLAN in station mode and connect to another AP, or in AP mode but with a
|
||||
different ssid and/or key.
|
||||
* Use your favourite telnet client with the following settings: **host = 192.168.1.1, port = 23.**
|
||||
* Log in with **user = "micro" and password = "python"**
|
||||
|
||||
The board has a small file system of 64K located in the serial flash connected to the CC3200. SD cards are also supported, but
|
||||
since the CC3200 LaunchXL doesn't come with an SD card socket installed, you will need to add one yourself. Any SD card breakout
|
||||
board will do, as long as you connect it as described here: <http://processors.wiki.ti.com/index.php/CC32xx_SDHost_FatFS>
|
||||
The board has a small file system of 192K (WiPy) or 64K (Launchpad) located in the serial flash connected to the CC3200.
|
||||
SD cards are also supported, you can connect any SD card and configure the pinout using the SD class API.
|
||||
|
||||
## Uploading scripts:
|
||||
|
||||
@@ -62,14 +74,14 @@ not 100% sure of it.
|
||||
## Upgrading the firmware Over The Air:
|
||||
|
||||
OTA software updates can be performed through the FTP server. After building a new MCUIMG.BIN in release mode, upload it to:
|
||||
`/SFLASH/SYS/MCUIMG.BIN` it will take around 8s (The TI simplelink file system is quite slow because every file is mirrored for
|
||||
safety). You won't see the file being stored inside `/SFLASH/SYS/` because it's actually saved bypassing FatFS, but rest assured that
|
||||
`/flash/sys/mcuimg.bin` it will take around 6s (The TI simplelink file system is quite slow because every file is mirrored for
|
||||
safety). You won't see the file being stored inside `/flash/sys/` because it's actually saved bypassing FatFS, but rest assured that
|
||||
the file was successfully transferred, and it has been signed with a MD5 checksum to verify its integrity.
|
||||
Now, reset the MCU by pressing the switch on the board, or by typing:
|
||||
|
||||
```python
|
||||
import pyb
|
||||
pyb.hard_reset()
|
||||
pyb.reset()
|
||||
```
|
||||
|
||||
### Note regarding FileZilla:
|
||||
@@ -79,4 +91,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,9 +24,8 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
__stack_size__ = 1024; /* interrupts are handled using this stack */
|
||||
__min_heap_size__ = 4K;
|
||||
__rtos_heap_size = 16K;
|
||||
__stack_size__ = 3K; /* interrupts are handled within this stack */
|
||||
__min_heap_size__ = 8K;
|
||||
|
||||
MEMORY
|
||||
{
|
||||
@@ -84,8 +45,6 @@ SECTIONS
|
||||
. = ALIGN(8);
|
||||
} > SRAMB
|
||||
|
||||
_ertos_heap = ORIGIN(SRAMB) + LENGTH(SRAMB);
|
||||
|
||||
.text :
|
||||
{
|
||||
_text = .;
|
||||
@@ -103,13 +62,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 +81,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,16 +10,18 @@ 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../lib/netutils
|
||||
APP_INC += -I../lib/timeutils
|
||||
APP_INC += -I../stmhal
|
||||
|
||||
APP_CPPDEFINES = -Dgcc -DTARGET_IS_CC3200 -DSL_FULL -DUSE_FREERTOS
|
||||
@@ -73,38 +75,49 @@ APP_HAL_SRC_C = $(addprefix hal/,\
|
||||
)
|
||||
|
||||
APP_MISC_SRC_C = $(addprefix misc/,\
|
||||
antenna.c \
|
||||
FreeRTOSHooks.c \
|
||||
pin_named_pins.c \
|
||||
help.c \
|
||||
mpirq.c \
|
||||
mperror.c \
|
||||
mpexception.c \
|
||||
pin_defs_cc3200.c \
|
||||
mpsystick.c \
|
||||
)
|
||||
|
||||
APP_MODS_SRC_C = $(addprefix mods/,\
|
||||
modmachine.c \
|
||||
modnetwork.c \
|
||||
modpyb.c \
|
||||
modubinascii.c \
|
||||
moduos.c \
|
||||
modusocket.c \
|
||||
modussl.c \
|
||||
modutime.c \
|
||||
modwipy.c \
|
||||
modwlan.c \
|
||||
pybextint.c \
|
||||
pybadc.c \
|
||||
pybpin.c \
|
||||
pybi2c.c \
|
||||
pybrtc.c \
|
||||
pybstdio.c \
|
||||
pybsystick.c \
|
||||
pybsd.c \
|
||||
pybsleep.c \
|
||||
pybspi.c \
|
||||
pybtimer.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 \
|
||||
)
|
||||
@@ -114,6 +127,7 @@ APP_TELNET_SRC_C = $(addprefix telnet/,\
|
||||
)
|
||||
|
||||
APP_UTIL_SRC_C = $(addprefix util/,\
|
||||
cryptohash.c \
|
||||
fifo.c \
|
||||
gccollect.c \
|
||||
random.c \
|
||||
@@ -122,6 +136,7 @@ APP_UTIL_SRC_C = $(addprefix util/,\
|
||||
|
||||
APP_UTIL_SRC_S = $(addprefix util/,\
|
||||
gchelper.s \
|
||||
sleeprestore.s \
|
||||
)
|
||||
|
||||
APP_MAIN_SRC_C = \
|
||||
@@ -131,7 +146,11 @@ APP_MAIN_SRC_C = \
|
||||
|
||||
APP_LIB_SRC_C = $(addprefix lib/,\
|
||||
fatfs/ff.c \
|
||||
fatfs/option/ccsbcs.c \
|
||||
libc/string0.c \
|
||||
mp-readline/readline.c \
|
||||
netutils/netutils.c \
|
||||
timeutils/timeutils.c \
|
||||
)
|
||||
|
||||
APP_STM_SRC_C = $(addprefix stmhal/,\
|
||||
@@ -144,11 +163,11 @@ APP_STM_SRC_C = $(addprefix stmhal/,\
|
||||
moduselect.c \
|
||||
printf.c \
|
||||
pyexec.c \
|
||||
string0.c \
|
||||
pybstdio.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 +179,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)
|
||||
@@ -178,12 +197,17 @@ $(BUILD)/FreeRTOS/Source/%.o: CFLAGS += -Os
|
||||
$(BUILD)/ftp/%.o: CFLAGS += -Os
|
||||
$(BUILD)/hal/%.o: CFLAGS += -Os
|
||||
$(BUILD)/misc/%.o: CFLAGS += -Os
|
||||
$(BUILD)/mods/%.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
|
||||
@@ -191,8 +215,18 @@ endif
|
||||
|
||||
SHELL = bash
|
||||
APP_SIGN = appsign.sh
|
||||
UPDATE_WIPY ?= tools/update-wipy.py
|
||||
WIPY_IP ?= '192.168.1.1'
|
||||
WIPY_USER ?= 'micro'
|
||||
WIPY_PWD ?= 'python'
|
||||
|
||||
all: $(BUILD)/MCUIMG.BIN
|
||||
all: $(BUILD)/mcuimg.bin
|
||||
|
||||
.PHONY: deploy
|
||||
|
||||
deploy: $(BUILD)/mcuimg.bin
|
||||
$(ECHO) "Writing $< to the board"
|
||||
$(Q)$(PYTHON) $(UPDATE_WIPY) --verify --ip $(WIPY_IP) --user $(WIPY_USER) --password $(WIPY_PWD) --file $<
|
||||
|
||||
$(BUILD)/application.axf: $(OBJ) $(LINKER_SCRIPT)
|
||||
$(ECHO) "LINK $@"
|
||||
@@ -203,9 +237,9 @@ $(BUILD)/application.bin: $(BUILD)/application.axf
|
||||
$(ECHO) "Create $@"
|
||||
$(Q)$(OBJCOPY) -O binary $< $@
|
||||
|
||||
$(BUILD)/MCUIMG.BIN: $(BUILD)/application.bin
|
||||
$(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 +248,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
|
||||
cat $BUILD/application.bin __md5hash.bin > $BUILD/mcuimg.bin
|
||||
RET=$?
|
||||
|
||||
# Remove the tmp files
|
||||
rm -f __md5hash.bin
|
||||
|
||||
# Remove hte unsigned binary
|
||||
# Remove the unsigned binary
|
||||
rm -f $BUILD/application.bin
|
||||
|
||||
exit $RET
|
||||
|
||||
@@ -30,9 +30,20 @@
|
||||
#define MICROPY_HW_BOARD_NAME "LaunchPad"
|
||||
#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_HW_ANTENNA_DIVERSITY (0)
|
||||
|
||||
#define MICROPY_STDIO_UART PYB_UART_1
|
||||
#define MICROPY_STDIO_UART 0
|
||||
#define MICROPY_STDIO_UART_BAUD 115200
|
||||
|
||||
#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_GP9
|
||||
#define MICROPY_SYS_LED_PIN_NUM PIN_64 // GP9
|
||||
#define MICROPY_SAFE_BOOT_PIN_NUM PIN_15 // GP22
|
||||
#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
|
||||
|
||||
|
||||
45
cc3200/boards/WIPY/mpconfigboard.h
Normal file
45
cc3200/boards/WIPY/mpconfigboard.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 WIPY
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "WiPy"
|
||||
#define MICROPY_HW_MCU_NAME "CC3200"
|
||||
|
||||
#define MICROPY_HW_ANTENNA_DIVERSITY (1)
|
||||
|
||||
#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_GP25
|
||||
#define MICROPY_SYS_LED_PIN_NUM PIN_21 // GP25 (SOP2)
|
||||
#define MICROPY_SAFE_BOOT_PIN_NUM PIN_18 // GP28
|
||||
#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,GP2
|
||||
L3,GP1
|
||||
L4,GP23
|
||||
L5,GP24
|
||||
L6,GP11
|
||||
L7,GP12
|
||||
L8,GP13
|
||||
L9,GP14
|
||||
L10,GP15
|
||||
L11,GP16
|
||||
L12,GP17
|
||||
L13,GP22
|
||||
L14,GP28
|
||||
R4,GP10
|
||||
R5,GP9
|
||||
R6,GP8
|
||||
R7,GP7
|
||||
R8,GP6
|
||||
R9,GP30
|
||||
R10,GP31
|
||||
R11,GP3
|
||||
R12,GP0
|
||||
R13,GP4
|
||||
R14,GP5
|
||||
HBL,GP25
|
||||
|
@@ -1,25 +1,25 @@
|
||||
Pin,Name,Default,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF14,AF15,ADC
|
||||
1,GPIO10,GPIO10,GPIO10,I2C_SCL,,GT_PWM06,,,SDCARD_CLK,UART1_TX,,,,,GT_CCP01,,,,
|
||||
2,GPIO11,GPIO11,GPIO11,I2C_SDA,,GT_PWM07,pXCLK(XVCLK),,SDCARD_CMD,UART1_RX,,,,,GT_CCP02,McAFSX,,,
|
||||
3,GPIO12,GPIO12,GPIO12,,,McACLK,pVS(VSYNC),I2C_SCL,,UART0_TX,,,,,GT_CCP03,,,,
|
||||
4,GPIO13,GPIO13,GPIO13,,,,pHS(HSYNC),I2C_SDA,,UART0_RX,,,,,GT_CCP04,,,,
|
||||
5,GPIO14,GPIO14,GPIO14,,,,pDATA8(CAM_D4),2C_SCL,,GSPI_CLK,,,,,GT_CCP05,,,,
|
||||
6,GPIO15,GPIO15,GPIO15,,,,pDATA9(CAM_D5),I2C_SDA,,GSPI_MISO,,,,,,GT_CCP06,,,
|
||||
7,GPIO16,GPIO16,GPIO16,,,,pDATA10(CAM_D6),UART1_TX,,GSPI_MOSI,,,,,,GT_CCP07,,,
|
||||
8,GPIO17,GPIO17,GPIO17,,,,pDATA11(CAM_D7),UART1_RX,,GSPI_CS,,,,,,,,,
|
||||
1,GP10,GP10,GP10,I2C0_SCL,,TIM3_PWM0,,,SD0_CLK,UART1_TX,,,,,TIM0_CC1,,,,
|
||||
2,GP11,GP11,GP11,I2C0_SDA,,TIM3_PWM1,pXCLK(XVCLK),,SD0_CMD,UART1_RX,,,,,TIM1_CC0,I2S0_FS,,,
|
||||
3,GP12,GP12,GP12,,,I2S0_CLK,pVS(VSYNC),I2C0_SCL,,UART0_TX,,,,,TIM1_CC1,,,,
|
||||
4,GP13,GP13,GP13,,,,pHS(HSYNC),I2C0_SDA,,UART0_RX,,,,,TIM2_CC0,,,,
|
||||
5,GP14,GP14,GP14,,,,pDATA8(CAM_D4),I2C0_SCL,,SPI0_CLK,,,,,TIM2_CC1,,,,
|
||||
6,GP15,GP15,GP15,,,,pDATA9(CAM_D5),I2C0_SDA,,SPI0_MISO,SD0_DAT0,,,,,TIM3_CC0,,,
|
||||
7,GP16,GP16,GP16,,,,pDATA10(CAM_D6),UART1_TX,,SPI0_MOSI,SD0_CLK,,,,,TIM3_CC1,,,
|
||||
8,GP17,GP17,GP17,,,,pDATA11(CAM_D7),UART1_RX,,SPI0_CS0,SD0_CMD,,,,,,,,
|
||||
9,VDD_DIG1,VDD_DIG1,VDD_DIG1,,,,,,,,,,,,,,,,
|
||||
10,VIN_IO1,VIN_IO1,VIN_IO1,,,,,,,,,,,,,,,,
|
||||
11,FLASH_SPI_CLK,FLASH_SPI_CLK,FLASH_SPI_CLK,,,,,,,,,,,,,,,,
|
||||
12,FLASH_SPI_DOUT,FLASH_SPI_DOUT,FLASH_SPI_DOUT,,,,,,,,,,,,,,,,
|
||||
13,FLASH_SPI_DIN,FLASH_SPI_DIN,FLASH_SPI_DIN,,,,,,,,,,,,,,,,
|
||||
14,FLASH_SPI_CS,FLASH_SPI_CS,FLASH_SPI_CS,,,,,,,,,,,,,,,,
|
||||
15,GPIO22,GPIO22,GPIO22,,,,,GT_CCP04,,McAFSX,,,,,,,,,
|
||||
16,GPIO23,TDI,GPIO23,TDI,UART1_TX,,,,,,,2C_SCL,,,,,,,
|
||||
17,GPIO24,TDO,GPIO24,TDO,UART1_RX,,GT_CCP06,PWM0,McAFSX,,,I2C_SDA,,,,,,,
|
||||
18,GPIO28,GPIO28,GPIO28,,,,,,,,,,,,,,,,
|
||||
19,TCK,TCK,,TCK,,,,,,,GT_PWM03,,,,,,,,
|
||||
20,GPIO29,TMS,GPIO29,TMS,,,,,,,,,,,,,,,
|
||||
21,GPIO25,SOP2,GPIO25,,McAFSX,,,,,,,GT_PWM02,,,,,,,
|
||||
15,GP22,GP22,GP22,,,,,TIM2_CC0,,I2S0_FS,,,,,,,,,
|
||||
16,GP23,TDI,GP23,TDI,UART1_TX,,,,,,,I2C0_SCL,,,,,,,
|
||||
17,GP24,TDO,GP24,TDO,UART1_RX,,TIM3_CC0,TIM0_PWM0,I2S0_FS,,,I2C0_SDA,,,,,,,
|
||||
18,GP28,GP28,GP28,,,,,,,,,,,,,,,,
|
||||
19,TCK,TCK,,TCK,,,,,,,TIM1_PWM2,,,,,,,,
|
||||
20,GP29,TMS,GP29,TMS,,,,,,,,,,,,,,,
|
||||
21,GP25,SOP2,GP25,,I2S0_FS,,,,,,,TIM1_PWM0,,,,,,,
|
||||
22,WLAN_XTAL_N,WLAN_XTAL_N,WLAN_XTAL_N,,,,,,,,,,,,,,,,
|
||||
23,WLAN_XTAL_P,WLAN_XTAL_P,WLAN_XTAL_P,,,,,,,,,,,,,,,,
|
||||
24,VDD_PLL,VDD_PLL,VDD_PLL,,,,,,,,,,,,,,,,
|
||||
@@ -43,24 +43,24 @@ Pin,Name,Default,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF1
|
||||
42,DCDC_PA_OUT,DCDC_PA_O UT,DCDC_PA_O UT,,,,,,,,,,,,,,,,
|
||||
43,DCDC_DIG_SW,DCDC_DIG_ SW,DCDC_DIG_ SW,,,,,,,,,,,,,,,,
|
||||
44,VIN_DCDC_DIG,VIN_DCDC_ DIG,VIN_DCDC_ DIG,,,,,,,,,,,,,,,,
|
||||
45,GPIO31,DCDC_ANA2_SW_P,GPIO31,,UART1_RX,,,,McAXR0,GSPI_CLK,,UART0_RX,,,McAFSX,,,,
|
||||
45,GP31,DCDC_ANA2_SW_P,GP31,,UART1_RX,,,,I2S0_DAT0,SPI0_CLK,,UART0_RX,,,I2S0_FS,,,,
|
||||
46,DCDC_ANA2_SW_N,DCDC_ANA2_SW_N,DCDC_ANA2_SW_N,,,,,,,,,,,,,,,,
|
||||
47,VDD_ANA2,VDD_ANA2,VDD_ANA2,,,,,,,,,,,,,,,,
|
||||
48,VDD_ANA1,VDD_ANA1,VDD_ANA1,,,,,,,,,,,,,,,,
|
||||
49,VDD_RAM,VDD_RAM,VDD_RAM,,,,,,,,,,,,,,,,
|
||||
50,GPIO0,GPIO0,GPIO0,,,UART0_RTS,McAXR0,,McAXR1,GT_CCP00,,GSPI_CS,UART1_RTS,,UART0_CTS,,,,
|
||||
50,GP0,GP0,GP0,,,UART0_RTS,I2S0_DAT0,,I2S0_DAT1,TIM0_CC0,,SPI0_CS0,UART1_RTS,,UART0_CTS,,,,
|
||||
51,RTC_XTAL_P,RTC_XTAL_P,RTC_XTAL_P,,,,,,,,,,,,,,,,
|
||||
52,RTC_XTAL_N,RTC_XTAL_N,GPIO32,,McACLK,,McAXR0,,UART0_RTS,,GSPI_MOSI,,,,,,,,
|
||||
53,GPIO30,GPIO30,GPIO30,,McACLK,McAFSX,GT_CCP05,,,GSPI_MISO,,UART0_TX,,,,,,,
|
||||
52,RTC_XTAL_N,RTC_XTAL_N,GP32,,I2S0_CLK,,I2S0_DAT0,,UART0_RTS,,SPI0_MOSI,,,,,,,,
|
||||
53,GP30,GP30,GP30,,I2S0_CLK,I2S0_FS,TIM2_CC1,,,SPI0_MISO,,UART0_TX,,,,,,,
|
||||
54,VIN_IO2,VIN_IO2,VIN_IO2,,,,,,,,,,,,,,,,
|
||||
55,GPIO1,GPIO1,GPIO1,,,GSPI_MISO,pCLK (PIXCLK),,UART1_TX,GT_CCP01,,,,,,,,,
|
||||
55,GP1,GP1,GP1,,,UART0_TX,pCLK (PIXCLK),,UART1_TX,TIM0_CC1,,,,,,,,,
|
||||
56,VDD_DIG2,VDD_DIG2,VDD_DIG2,,,,,,,,,,,,,,,,
|
||||
57,GPIO2,GPIO2,GPIO2,,,UART0_RX,,,UART1_RX,GT_CCP02,,,,,,,,,ADC_CH0
|
||||
58,GPIO3,GPIO3,GPIO3,,,,pDATA7(CAM_D3),,UART1_TX,,,,,,,,,,ADC_CH1
|
||||
59,GPIO4,GPIO4,GPIO4,,,,pDATA6(CAM_D2),,UART1_RX,,,,,,,,,,ADC_CH2
|
||||
60,GPIO5,GPIO5,GPIO5,,,,pDATA5(CAM_D1),,McAXR1,GT_CCP05,,,,,,,,,ADC_CH3
|
||||
61,GPIO6,GPIO6,GPIO6,,,UART1_CTS,pDATA4(CAM_D0),UART0_RTS,UART0_CTS,GT_CCP06,,,,,,,,,
|
||||
62,GPIO7,GPIO7,GPIO7,,,UART1_RTS,,,,,,,UART0_RTS,UART0_TX,,McACLKX,,,
|
||||
63,GPIO8,GPIO8,GPIO8,,,,,,SDCARD_IRQ,McAFSX,,,,,GT_CCP06,,,,
|
||||
64,GPIO9,GPIO9,GPIO9,,,GT_PWM05,,,SDCARD_DATA,McAXR0,,,,,GT_CCP00,,,,
|
||||
57,GP2,GP2,GP2,,,UART0_RX,,,UART1_RX,TIM1_CC0,,,,,,,,,ADC0_CH0
|
||||
58,GP3,GP3,GP3,,,,pDATA7(CAM_D3),,UART1_TX,,,,,,,,,,ADC0_CH1
|
||||
59,GP4,GP4,GP4,,,,pDATA6(CAM_D2),,UART1_RX,,,,,,,,,,ADC0_CH2
|
||||
60,GP5,GP5,GP5,,,,pDATA5(CAM_D1),,I2S0_DAT1,TIM2_CC1,,,,,,,,,ADC0_CH3
|
||||
61,GP6,GP6,GP6,,,UART1_CTS,pDATA4(CAM_D0),UART0_RTS,UART0_CTS,TIM3_CC0,,,,,,,,,
|
||||
62,GP7,GP7,GP7,,,UART1_RTS,,,,,,,UART0_RTS,UART0_TX,,I2S0_CLK,,,
|
||||
63,GP8,GP8,GP8,,,,,,SD0_IRQ,I2S0_FS,,,,,TIM3_CC0,,,,
|
||||
64,GP9,GP9,GP9,,,TIM2_PWM1,,,SD0_DAT0,I2S0_DAT0,,,,,TIM0_CC0,,,,
|
||||
65,GND_TAB,GND_TAB,GND_TAB,,,,,,,,,,,,,,,,
|
||||
|
||||
|
@@ -30,20 +30,40 @@
|
||||
#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) \
|
||||
#define AF(af_name, af_idx, af_fn, af_unit, af_type) \
|
||||
{ \
|
||||
.name = MP_QSTR_ ## af_name, \
|
||||
.idx = (af_idx), \
|
||||
.fn = PIN_FN_ ## af_fn, \
|
||||
.unit = (af_unit), \
|
||||
.type = PIN_TYPE_ ## af_fn ## _ ## af_type, \
|
||||
}
|
||||
|
||||
|
||||
#define PIN(p_pin_name, p_port, p_bit, p_pin_num, p_af_list, p_num_afs) \
|
||||
{ \
|
||||
{ &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, \
|
||||
.af_list = (p_af_list), \
|
||||
.pull = PIN_TYPE_STD, \
|
||||
.bit = (p_bit), \
|
||||
.pin_num = (p_pin_num), \
|
||||
.af = PIN_MODE_0, \
|
||||
.strength = PIN_STRENGTH_4MA, \
|
||||
.mode = GPIO_DIR_MODE_IN, \
|
||||
.num_afs = (p_num_afs), \
|
||||
.value = 0, \
|
||||
.used = false, \
|
||||
.irq_trigger = 0, \
|
||||
.irq_flags = 0, \
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
"""Generates the pins files for the CC3200."""
|
||||
"""Generates the pins file for the CC3200."""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
@@ -8,20 +8,43 @@ import sys
|
||||
import csv
|
||||
|
||||
|
||||
SUPPORTED_AFS = { 'UART': ('TX', 'RX', 'RTS', 'CTS'),
|
||||
'SPI': ('CLK', 'MOSI', 'MISO', 'CS0'),
|
||||
#'I2S': ('CLK', 'FS', 'DAT0', 'DAT1'),
|
||||
'I2C': ('SDA', 'SCL'),
|
||||
'TIM': ('PWM0', 'PWM1', 'CC0', 'CC1'),
|
||||
'SD': ('CLK', 'CMD', 'DAT0'),
|
||||
'ADC': ('CH0', 'CH1', 'CH2', 'CH3')
|
||||
}
|
||||
|
||||
def parse_port_pin(name_str):
|
||||
"""Parses a string and returns a (port, gpio_bit) tuple."""
|
||||
if len(name_str) < 5:
|
||||
raise ValueError("Expecting pin name to be at least 5 characters")
|
||||
if name_str[:4] != 'GPIO':
|
||||
raise ValueError("Expecting pin name to start with GPIO")
|
||||
if not name_str[4:].isdigit():
|
||||
if len(name_str) < 3:
|
||||
raise ValueError("Expecting pin name to be at least 3 characters")
|
||||
if name_str[:2] != 'GP':
|
||||
raise ValueError("Expecting pin name to start with GP")
|
||||
if not name_str[2:].isdigit():
|
||||
raise ValueError("Expecting numeric GPIO number")
|
||||
port = int(int(name_str[4:]) / 8)
|
||||
gpio_bit = 1 << int(int(name_str[4:]) % 8)
|
||||
port = int(int(name_str[2:]) / 8)
|
||||
gpio_bit = 1 << int(int(name_str[2:]) % 8)
|
||||
return (port, gpio_bit)
|
||||
|
||||
|
||||
class Pin(object):
|
||||
class AF:
|
||||
"""Holds the description of an alternate function"""
|
||||
def __init__(self, name, idx, fn, unit, type):
|
||||
self.name = name
|
||||
self.idx = idx
|
||||
if self.idx > 15:
|
||||
self.idx = -1
|
||||
self.fn = fn
|
||||
self.unit = unit
|
||||
self.type = type
|
||||
|
||||
def print(self):
|
||||
print (' AF({:16s}, {:4d}, {:8s}, {:4d}, {:8s}), // {}'.format(self.name, self.idx, self.fn, self.unit, self.type, self.name))
|
||||
|
||||
class Pin:
|
||||
"""Holds the information associated with a pin."""
|
||||
def __init__(self, name, port, gpio_bit, pin_num):
|
||||
self.name = name
|
||||
@@ -29,41 +52,48 @@ class Pin(object):
|
||||
self.gpio_bit = gpio_bit
|
||||
self.pin_num = pin_num
|
||||
self.board_pin = False
|
||||
self.afs = []
|
||||
|
||||
def cpu_pin_name(self):
|
||||
return self.name
|
||||
|
||||
def is_board_pin(self):
|
||||
return self.board_pin
|
||||
def add_af(self, af):
|
||||
self.afs.append(af)
|
||||
|
||||
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(
|
||||
self.name, self.name, self.port, self.gpio_bit, self.pin_num))
|
||||
print('// {}'.format(self.name))
|
||||
if len(self.afs):
|
||||
print('const pin_af_t pin_{}_af[] = {{'.format(self.name))
|
||||
for af in self.afs:
|
||||
af.print()
|
||||
print('};')
|
||||
print('pin_obj_t pin_{:4s} = PIN({:6s}, {:1d}, {:3d}, {:2d}, pin_{}_af, {});\n'.format(
|
||||
self.name, self.name, self.port, self.gpio_bit, self.pin_num, self.name, len(self.afs)))
|
||||
else:
|
||||
print('pin_obj_t pin_{:4s} = PIN({:6s}, {:1d}, {:3d}, {:2d}, NULL, 0);\n'.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):
|
||||
|
||||
class Pins:
|
||||
def __init__(self):
|
||||
self.cpu_pins = [] # list of pin objects
|
||||
self.board_pins = [] # list of pin objects
|
||||
|
||||
def find_pin(self, port, gpio_bit):
|
||||
for pin in self.cpu_pins:
|
||||
for pin in self.board_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:
|
||||
for pin in self.board_pins:
|
||||
if pin.pin_num == pin_num:
|
||||
return pin
|
||||
|
||||
def parse_af_file(self, filename, pin_col, pinname_col):
|
||||
def find_pin_by_name(self, name):
|
||||
for pin in self.board_pins:
|
||||
if pin.name == name:
|
||||
return pin
|
||||
|
||||
def parse_af_file(self, filename, pin_col, pinname_col, af_start_col):
|
||||
with open(filename, 'r') as csvfile:
|
||||
rows = csv.reader(csvfile)
|
||||
for row in rows:
|
||||
@@ -72,50 +102,70 @@ class Pins(object):
|
||||
except:
|
||||
continue
|
||||
if not row[pin_col].isdigit():
|
||||
raise ValueError("Invalid pin number: {:s} in row {:s}".format(row[pin_col]), row)
|
||||
raise ValueError("Invalid pin number {:s} in row {:s}".format(row[pin_col]), row)
|
||||
# Pin numbers must start from 0 when used with the TI API
|
||||
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):
|
||||
self.board_pins.append(pin)
|
||||
af_idx = 0
|
||||
for af in row[af_start_col:]:
|
||||
af_splitted = af.split('_')
|
||||
fn_name = af_splitted[0].rstrip('0123456789')
|
||||
if fn_name in SUPPORTED_AFS:
|
||||
type_name = af_splitted[1]
|
||||
if type_name in SUPPORTED_AFS[fn_name]:
|
||||
unit_idx = af_splitted[0][-1]
|
||||
pin.add_af(AF(af, af_idx, fn_name, int(unit_idx), type_name))
|
||||
af_idx += 1
|
||||
|
||||
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()
|
||||
pin.board_pin = True
|
||||
|
||||
def print_named(self, label, pins):
|
||||
print('')
|
||||
print('STATIC const mp_map_elem_t pin_{:s}_pins_locals_dict_table[] = {{'.format(label))
|
||||
for pin in pins:
|
||||
if pin.is_board_pin():
|
||||
print(' {{ MP_OBJ_NEW_QSTR(MP_QSTR_{:6s}), (mp_obj_t)&pin_{:6s} }},'.format(pin.cpu_pin_name(), pin.cpu_pin_name()))
|
||||
if pin.board_pin:
|
||||
print(' {{ MP_OBJ_NEW_QSTR(MP_QSTR_{:6s}), (mp_obj_t)&pin_{:6s} }},'.format(pin.name, pin.name))
|
||||
print('};')
|
||||
print('MP_DEFINE_CONST_DICT(pin_{:s}_pins_locals_dict, pin_{:s}_pins_locals_dict_table);'.format(label, label));
|
||||
|
||||
def print(self):
|
||||
for pin in self.cpu_pins:
|
||||
if pin.is_board_pin():
|
||||
for pin in self.board_pins:
|
||||
if pin.board_pin:
|
||||
pin.print()
|
||||
self.print_named('cpu', self.cpu_pins)
|
||||
self.print_named('board', self.board_pins)
|
||||
print('')
|
||||
|
||||
def print_header(self, hdr_filename):
|
||||
with open(hdr_filename, 'wt') as hdr_file:
|
||||
for pin in self.cpu_pins:
|
||||
if pin.is_board_pin():
|
||||
for pin in self.board_pins:
|
||||
if pin.board_pin:
|
||||
pin.print_header(hdr_file)
|
||||
|
||||
def print_qstr(self, qstr_filename):
|
||||
with open(qstr_filename, 'wt') as qstr_file:
|
||||
qstr_set = set([])
|
||||
for pin in self.cpu_pins:
|
||||
if pin.is_board_pin():
|
||||
qstr_set |= set([pin.cpu_pin_name()])
|
||||
for qstr in sorted(qstr_set):
|
||||
pin_qstr_set = set([])
|
||||
af_qstr_set = set([])
|
||||
for pin in self.board_pins:
|
||||
if pin.board_pin:
|
||||
pin_qstr_set |= set([pin.name])
|
||||
for af in pin.afs:
|
||||
af_qstr_set |= set([af.name])
|
||||
print('// Board pins', file=qstr_file)
|
||||
for qstr in sorted(pin_qstr_set):
|
||||
print('Q({})'.format(qstr), file=qstr_file)
|
||||
print('\n// Pin AFs', file=qstr_file)
|
||||
for qstr in sorted(af_qstr_set):
|
||||
print('Q({})'.format(qstr), file=qstr_file)
|
||||
|
||||
|
||||
@@ -162,12 +212,12 @@ def main():
|
||||
print('//')
|
||||
if args.af_filename:
|
||||
print('// --af {:s}'.format(args.af_filename))
|
||||
pins.parse_af_file(args.af_filename, 0, 1)
|
||||
pins.parse_af_file(args.af_filename, 0, 1, 3)
|
||||
|
||||
if args.board_filename:
|
||||
print('// --board {:s}'.format(args.board_filename))
|
||||
pins.parse_board_file(args.board_filename, 1)
|
||||
|
||||
pins.parse_board_file(args.board_filename, 1)
|
||||
|
||||
if args.prefix_filename:
|
||||
print('// --prefix {:s}'.format(args.prefix_filename))
|
||||
print('')
|
||||
|
||||
@@ -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,8 @@ BOOT_CPPDEFINES = -Dgcc -DBOOTLOADER -DTARGET_IS_CC3200 -DSL_TINY
|
||||
BOOT_HAL_SRC_C = $(addprefix hal/,\
|
||||
cpu.c \
|
||||
interrupt.c \
|
||||
gpio.c \
|
||||
pin.c \
|
||||
prcm.c \
|
||||
shamd5.c \
|
||||
spi.c \
|
||||
@@ -26,22 +29,30 @@ 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/,\
|
||||
antenna.c \
|
||||
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 \
|
||||
)
|
||||
|
||||
BOOT_UTIL_SRC_C = $(addprefix util/,\
|
||||
hash.c \
|
||||
cryptohash.c \
|
||||
)
|
||||
|
||||
BOOT_MAIN_SRC_C = \
|
||||
@@ -51,17 +62,20 @@ BOOT_MAIN_SRC_S = \
|
||||
bootmgr/runapp.s
|
||||
|
||||
BOOT_PY_SRC_C = $(addprefix py/,\
|
||||
pfenv.c \
|
||||
pfenv_printf.c \
|
||||
mpprint.c \
|
||||
)
|
||||
|
||||
BOOT_STM_SRC_C = $(addprefix stmhal/,\
|
||||
printf.c \
|
||||
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))
|
||||
|
||||
BOOT_LIB_SRC_C = $(addprefix lib/,\
|
||||
libc/string0.c \
|
||||
)
|
||||
|
||||
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))
|
||||
OBJ += $(addprefix $(BUILD)/, $(BOOT_LIB_SRC_C:.c=.o))
|
||||
|
||||
# Add the linker script
|
||||
LINKER_SCRIPT = bootmgr/bootmgr.lds
|
||||
@@ -70,11 +84,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 +97,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,13 +124,12 @@ $(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)
|
||||
touch $@
|
||||
|
||||
# Create an empty "py-version.h" needed by py/mkrules.mk
|
||||
$(HEADER_BUILD)/py-version.h: | $(HEADER_BUILD)
|
||||
# Create an empty "mpversion.h" needed by py/mkrules.mk
|
||||
$(HEADER_BUILD)/mpversion.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
|
||||
{
|
||||
@@ -51,6 +39,7 @@ SECTIONS
|
||||
{
|
||||
_text = .;
|
||||
KEEP(*(.intvecs))
|
||||
*(.boot*)
|
||||
*(.text*)
|
||||
*(.rodata*)
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
@@ -65,9 +54,7 @@ SECTIONS
|
||||
_etext = .;
|
||||
} > SRAM
|
||||
|
||||
__init_data = .;
|
||||
|
||||
.data : AT(__init_data)
|
||||
.data :
|
||||
{
|
||||
_data = .;
|
||||
*(.data*)
|
||||
|
||||
@@ -43,23 +43,31 @@ extern "C"
|
||||
*******************************************************************************/
|
||||
#define IMG_BOOT_INFO "/sys/bootinfo.bin"
|
||||
#define IMG_FACTORY "/sys/factimg.bin"
|
||||
#define IMG_UPDATE "/sys/updtimg.bin"
|
||||
#define IMG_UPDATE1 "/sys/updtimg1.bin"
|
||||
#define IMG_UPDATE2 "/sys/updtimg2.bin"
|
||||
#define IMG_PREFIX "/sys/updtimg"
|
||||
|
||||
#define IMG_SRVPACK "/sys/servicepack.ucf"
|
||||
#define SRVPACK_SIGN "/sys/servicepack.sig"
|
||||
|
||||
#define CA_FILE "/cert/ca.pem"
|
||||
#define CERT_FILE "/cert/cert.pem"
|
||||
#define KEY_FILE "/cert/private.key"
|
||||
|
||||
/******************************************************************************
|
||||
Image file sizes
|
||||
Special file sizes
|
||||
*******************************************************************************/
|
||||
#define IMG_SIZE (232 * 1024) /* 16KB are reserved for the bootloader and at least 8KB for the heap*/
|
||||
#define IMG_SIZE (192 * 1024) /* 16KB are reserved for the bootloader and at least 48KB for the heap*/
|
||||
#define SRVPACK_SIZE (16 * 1024)
|
||||
#define SIGN_SIZE (2 * 1024)
|
||||
#define CA_KEY_SIZE (4 * 1024)
|
||||
|
||||
/******************************************************************************
|
||||
Active Image
|
||||
*******************************************************************************/
|
||||
#define IMG_ACT_FACTORY 0
|
||||
#define IMG_ACT_UPDATE 1
|
||||
#define IMG_ACT_UPDATE1 1
|
||||
#define IMG_ACT_UPDATE2 2
|
||||
|
||||
#define IMG_STATUS_CHECK 0
|
||||
#define IMG_STATUS_READY 1
|
||||
@@ -67,13 +75,13 @@ extern "C"
|
||||
/******************************************************************************
|
||||
Boot Info structure
|
||||
*******************************************************************************/
|
||||
typedef struct sBootInfo
|
||||
typedef struct _sBootInfo_t
|
||||
{
|
||||
_u8 ActiveImg;
|
||||
_u8 Status;
|
||||
_u8 PrevImg;
|
||||
_u8 : 8;
|
||||
_u8 : 8;
|
||||
}sBootInfo_t;
|
||||
} sBootInfo_t;
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
@@ -27,7 +27,10 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <std.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "hw_ints.h"
|
||||
#include "hw_types.h"
|
||||
#include "hw_gpio.h"
|
||||
@@ -45,32 +48,32 @@
|
||||
#include "flc.h"
|
||||
#include "bootmgr.h"
|
||||
#include "shamd5.h"
|
||||
#include "hash.h"
|
||||
#include "cryptohash.h"
|
||||
#include "utils.h"
|
||||
#include "cc3200_hal.h"
|
||||
#include "debug.h"
|
||||
#include "mperror.h"
|
||||
#include "antenna.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_WAIT_SAFE_MODE_0_MS 500
|
||||
|
||||
#define BOOTMGR_SAFE_MODE_ENTER_MS 1000
|
||||
#define BOOTMGR_SAFE_MODE_ENTER_TOOGLE_MS 100
|
||||
#define BOOTMGR_WAIT_SAFE_MODE_1_MS 3000
|
||||
#define BOOTMGR_WAIT_SAFE_MODE_1_BLINK_MS 500
|
||||
|
||||
#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_2_MS 3000
|
||||
#define BOOTMGR_WAIT_SAFE_MODE_2_BLINK_MS 250
|
||||
|
||||
#define BOOTMGR_WAIT_SAFE_MODE_3_MS 1500
|
||||
#define BOOTMGR_WAIT_SAFE_MODE_3_BLINK_MS 100
|
||||
|
||||
//*****************************************************************************
|
||||
// Exported functions declarations
|
||||
@@ -81,9 +84,11 @@ extern void bootmgr_run_app (_u32 base);
|
||||
// Local functions declarations
|
||||
//*****************************************************************************
|
||||
static void bootmgr_board_init (void);
|
||||
static bool bootmgr_verify (void);
|
||||
static bool bootmgr_verify (_u8 *image);
|
||||
static void bootmgr_load_and_execute (_u8 *image);
|
||||
static bool safe_mode_boot (void);
|
||||
static bool wait_while_blinking (uint32_t wait_time, uint32_t period, bool force_wait);
|
||||
static bool safe_boot_request_start (uint32_t wait_time);
|
||||
static void wait_for_safe_boot (sBootInfo_t *psBootInfo);
|
||||
static void bootmgr_image_loader (sBootInfo_t *psBootInfo);
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -142,49 +147,52 @@ void SimpleLinkSockEventHandler(SlSockEvent_t *pSock)
|
||||
//! Board Initialization & Configuration
|
||||
//*****************************************************************************
|
||||
static void bootmgr_board_init(void) {
|
||||
// Set vector table base
|
||||
// set the vector table base
|
||||
MAP_IntVTableBaseSet((unsigned long)&g_pfnVectors[0]);
|
||||
|
||||
// Enable Processor Interrupts
|
||||
// enable processor interrupts
|
||||
MAP_IntMasterEnable();
|
||||
MAP_IntEnable(FAULT_SYSTICK);
|
||||
|
||||
// Mandatory MCU Initialization
|
||||
// mandatory MCU initialization
|
||||
PRCMCC3200MCUInit();
|
||||
|
||||
// Enable the Data Hashing Engine
|
||||
HASH_Init();
|
||||
// clear all the special bits, since we can't trust their content after reset
|
||||
// except for the WDT reset one!!
|
||||
PRCMClearSpecialBit(PRCM_SAFE_BOOT_BIT);
|
||||
PRCMClearSpecialBit(PRCM_FIRST_BOOT_BIT);
|
||||
|
||||
// Enable GPIOA3 Peripheral Clock
|
||||
MAP_PRCMPeripheralClkEnable(BOOTMGR_PINS_PRCM, PRCM_RUN_MODE_CLK);
|
||||
// check the reset after clearing the special bits
|
||||
mperror_bootloader_check_reset_cause();
|
||||
|
||||
// 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);
|
||||
#if MICROPY_HW_ANTENNA_DIVERSITY
|
||||
// configure the antenna selection pins
|
||||
antenna_init0();
|
||||
#endif
|
||||
|
||||
// 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);
|
||||
// enable the data hashing engine
|
||||
CRYPTOHASH_Init();
|
||||
|
||||
// init the system led and the system switch
|
||||
mperror_init0();
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//! Verifies the integrity of the new application binary
|
||||
//*****************************************************************************
|
||||
static bool bootmgr_verify (void) {
|
||||
static bool bootmgr_verify (_u8 *image) {
|
||||
SlFsFileInfo_t FsFileInfo;
|
||||
_u32 reqlen, offset = 0;
|
||||
_i32 fHandle;
|
||||
|
||||
// open the file for reading
|
||||
if (0 == sl_FsOpen((_u8 *)IMG_UPDATE, FS_MODE_OPEN_READ, NULL, &fHandle)) {
|
||||
if (0 == sl_FsOpen(image, FS_MODE_OPEN_READ, NULL, &fHandle)) {
|
||||
// get the file size
|
||||
sl_FsGetInfo((_u8 *)IMG_UPDATE, 0, &FsFileInfo);
|
||||
sl_FsGetInfo(image, 0, &FsFileInfo);
|
||||
|
||||
if (FsFileInfo.FileLen > BOOTMGR_HASH_SIZE) {
|
||||
FsFileInfo.FileLen -= BOOTMGR_HASH_SIZE;
|
||||
HASH_SHAMD5Start(BOOTMGR_HASH_ALGO, FsFileInfo.FileLen);
|
||||
CRYPTOHASH_SHAMD5Start(BOOTMGR_HASH_ALGO, FsFileInfo.FileLen);
|
||||
do {
|
||||
if ((FsFileInfo.FileLen - offset) > BOOTMGR_BUFF_SIZE) {
|
||||
reqlen = BOOTMGR_BUFF_SIZE;
|
||||
@@ -194,10 +202,10 @@ static bool bootmgr_verify (void) {
|
||||
}
|
||||
|
||||
offset += sl_FsRead(fHandle, offset, bootmgr_file_buf, reqlen);
|
||||
HASH_SHAMD5Update(bootmgr_file_buf, reqlen);
|
||||
CRYPTOHASH_SHAMD5Update(bootmgr_file_buf, reqlen);
|
||||
} while (offset < FsFileInfo.FileLen);
|
||||
|
||||
HASH_SHAMD5Read (bootmgr_file_buf);
|
||||
CRYPTOHASH_SHAMD5Read (bootmgr_file_buf);
|
||||
|
||||
// convert the resulting hash to hex
|
||||
for (_u32 i = 0; i < (BOOTMGR_HASH_SIZE / 2); i++) {
|
||||
@@ -205,7 +213,7 @@ static bool bootmgr_verify (void) {
|
||||
}
|
||||
|
||||
// read the hash from the file and close it
|
||||
ASSERT (BOOTMGR_HASH_SIZE == sl_FsRead(fHandle, offset, bootmgr_file_buf, BOOTMGR_HASH_SIZE));
|
||||
sl_FsRead(fHandle, offset, bootmgr_file_buf, BOOTMGR_HASH_SIZE);
|
||||
sl_FsClose (fHandle, NULL, NULL, 0);
|
||||
bootmgr_file_buf[BOOTMGR_HASH_SIZE] = '\0';
|
||||
// compare both hashes
|
||||
@@ -244,44 +252,81 @@ static void bootmgr_load_and_execute (_u8 *image) {
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//! Check for the safe mode pin
|
||||
//! Wait while the safe mode pin is being held high and blink the system led
|
||||
//! with the specified period
|
||||
//*****************************************************************************
|
||||
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)) {
|
||||
static bool wait_while_blinking (uint32_t wait_time, uint32_t period, bool force_wait) {
|
||||
_u32 count;
|
||||
for (count = 0; (force_wait || MAP_GPIOPinRead(MICROPY_SAFE_BOOT_PORT, MICROPY_SAFE_BOOT_PORT_PIN)) &&
|
||||
((period * count) < wait_time); count++) {
|
||||
// toogle the led
|
||||
MAP_GPIOPinWrite(BOOTMGR_PINS_PORT, BOOTMGR_LED_PORT_PIN, ~MAP_GPIOPinRead(GPIOA3_BASE, BOOTMGR_LED_PORT_PIN));
|
||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT(BOOTMGR_WAIT_SAFE_MODE_TOOGLE_MS * 1000));
|
||||
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(period * 1000));
|
||||
}
|
||||
return MAP_GPIOPinRead(BOOTMGR_PINS_PORT, BOOTMGR_SFE_PORT_PIN) ? false : true;
|
||||
return MAP_GPIOPinRead(MICROPY_SAFE_BOOT_PORT, MICROPY_SAFE_BOOT_PORT_PIN) ? true : false;
|
||||
}
|
||||
|
||||
static bool safe_boot_request_start (uint32_t wait_time) {
|
||||
if (MAP_GPIOPinRead(MICROPY_SAFE_BOOT_PORT, MICROPY_SAFE_BOOT_PORT_PIN)) {
|
||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT(wait_time * 1000));
|
||||
}
|
||||
return MAP_GPIOPinRead(MICROPY_SAFE_BOOT_PORT, MICROPY_SAFE_BOOT_PORT_PIN) ? true : false;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//! Load the proper image based on information from boot info and executes it.
|
||||
//! Check for the safe mode pin
|
||||
//*****************************************************************************
|
||||
static void wait_for_safe_boot (sBootInfo_t *psBootInfo) {
|
||||
if (safe_boot_request_start(BOOTMGR_WAIT_SAFE_MODE_0_MS)) {
|
||||
if (wait_while_blinking(BOOTMGR_WAIT_SAFE_MODE_1_MS, BOOTMGR_WAIT_SAFE_MODE_1_BLINK_MS, false)) {
|
||||
// go back one step in time
|
||||
psBootInfo->ActiveImg = psBootInfo->PrevImg;
|
||||
if (wait_while_blinking(BOOTMGR_WAIT_SAFE_MODE_2_MS, BOOTMGR_WAIT_SAFE_MODE_2_BLINK_MS, false)) {
|
||||
// go back directly to the factory image
|
||||
psBootInfo->ActiveImg = IMG_ACT_FACTORY;
|
||||
wait_while_blinking(BOOTMGR_WAIT_SAFE_MODE_3_MS, BOOTMGR_WAIT_SAFE_MODE_3_BLINK_MS, true);
|
||||
}
|
||||
}
|
||||
// turn off the system led
|
||||
MAP_GPIOPinWrite(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, 0);
|
||||
// request a safe boot to the application
|
||||
PRCMSetSpecialBit(PRCM_SAFE_BOOT_BIT);
|
||||
}
|
||||
// deinit the safe boot pin
|
||||
mperror_deinit_sfe_pin();
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//! Load the proper image based on the information from the boot info
|
||||
//! and launch it.
|
||||
//*****************************************************************************
|
||||
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) {
|
||||
// toogle the led
|
||||
MAP_GPIOPinWrite(BOOTMGR_PINS_PORT, BOOTMGR_LED_PORT_PIN, ~MAP_GPIOPinRead(GPIOA3_BASE, BOOTMGR_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);
|
||||
_u8 *image;
|
||||
|
||||
// search for the active image
|
||||
switch (psBootInfo->ActiveImg) {
|
||||
case IMG_ACT_UPDATE1:
|
||||
image = (unsigned char *)IMG_UPDATE1;
|
||||
break;
|
||||
case IMG_ACT_UPDATE2:
|
||||
image = (unsigned char *)IMG_UPDATE2;
|
||||
break;
|
||||
default:
|
||||
image = (unsigned char *)IMG_FACTORY;
|
||||
break;
|
||||
}
|
||||
// do we have a new update image that needs to be verified?
|
||||
else if ((psBootInfo->ActiveImg == IMG_ACT_UPDATE) && (psBootInfo->Status == IMG_STATUS_CHECK)) {
|
||||
if (!bootmgr_verify()) {
|
||||
// delete the corrupted file
|
||||
sl_FsDel((_u8 *)IMG_UPDATE, 0);
|
||||
// switch to the factory image
|
||||
psBootInfo->ActiveImg = IMG_ACT_FACTORY;
|
||||
|
||||
// do we have a new image that needs to be verified?
|
||||
if ((psBootInfo->ActiveImg != IMG_ACT_FACTORY) && (psBootInfo->Status == IMG_STATUS_CHECK)) {
|
||||
if (!bootmgr_verify(image)) {
|
||||
// verification failed, delete the broken file
|
||||
sl_FsDel(image, 0);
|
||||
// switch to the previous image
|
||||
psBootInfo->ActiveImg = psBootInfo->PrevImg;
|
||||
psBootInfo->PrevImg = IMG_ACT_FACTORY;
|
||||
}
|
||||
// in any case, set the status as "READY"
|
||||
// in any case, change the status to "READY"
|
||||
psBootInfo->Status = IMG_STATUS_READY;
|
||||
// write the new boot info
|
||||
if (!sl_FsOpen((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_WRITE, NULL, &fhandle)) {
|
||||
@@ -291,28 +336,38 @@ static void bootmgr_image_loader(sBootInfo_t *psBootInfo) {
|
||||
}
|
||||
}
|
||||
|
||||
// now boot the active image
|
||||
if (IMG_ACT_UPDATE == psBootInfo->ActiveImg) {
|
||||
bootmgr_load_and_execute((unsigned char *)IMG_UPDATE);
|
||||
}
|
||||
else {
|
||||
bootmgr_load_and_execute((unsigned char *)IMG_FACTORY);
|
||||
// this one might modify the boot info hence it MUST be called after
|
||||
// bootmgr_verify! (so that the changes are not saved to flash)
|
||||
wait_for_safe_boot(psBootInfo);
|
||||
|
||||
// select the active image again, since it might have changed
|
||||
switch (psBootInfo->ActiveImg) {
|
||||
case IMG_ACT_UPDATE1:
|
||||
image = (unsigned char *)IMG_UPDATE1;
|
||||
break;
|
||||
case IMG_ACT_UPDATE2:
|
||||
image = (unsigned char *)IMG_UPDATE2;
|
||||
break;
|
||||
default:
|
||||
image = (unsigned char *)IMG_FACTORY;
|
||||
break;
|
||||
}
|
||||
bootmgr_load_and_execute(image);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//! Main function
|
||||
//*****************************************************************************
|
||||
int main (void) {
|
||||
sBootInfo_t sBootInfo = { .ActiveImg = IMG_ACT_FACTORY, .Status = IMG_STATUS_READY };
|
||||
sBootInfo_t sBootInfo = { .ActiveImg = IMG_ACT_FACTORY, .Status = IMG_STATUS_READY, .PrevImg = IMG_ACT_FACTORY };
|
||||
bool bootapp = false;
|
||||
_i32 fhandle;
|
||||
|
||||
// Board Initialization
|
||||
// board setup
|
||||
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)) {
|
||||
@@ -321,17 +376,20 @@ int main (void) {
|
||||
}
|
||||
sl_FsClose(fhandle, 0, 0, 0);
|
||||
}
|
||||
// boot info file not present, it means that this is the first boot after being programmed
|
||||
if (!bootapp) {
|
||||
// create a new boot info file
|
||||
_u32 BootInfoCreateFlag = _FS_FILE_OPEN_FLAG_COMMIT | _FS_FILE_PUBLIC_WRITE | _FS_FILE_PUBLIC_READ;
|
||||
if (!sl_FsOpen ((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_CREATE((2 * sizeof(sBootInfo_t)),
|
||||
BootInfoCreateFlag), NULL, &fhandle)) {
|
||||
// Write the default boot info.
|
||||
// write the default boot info.
|
||||
if (sizeof(sBootInfo_t) == sl_FsWrite(fhandle, 0, (unsigned char *)&sBootInfo, sizeof(sBootInfo_t))) {
|
||||
bootapp = true;
|
||||
}
|
||||
sl_FsClose(fhandle, 0, 0, 0);
|
||||
}
|
||||
// signal the first boot to the application
|
||||
PRCMSetSpecialBit(PRCM_FIRST_BOOT_BIT);
|
||||
}
|
||||
|
||||
if (bootapp) {
|
||||
@@ -342,14 +400,23 @@ int main (void) {
|
||||
// stop simplelink
|
||||
sl_Stop(SL_STOP_TIMEOUT);
|
||||
|
||||
// if we've reached this point, then it means a fatal error occurred and the application
|
||||
// could not be loaded, so, loop forever and signal the crash to the user
|
||||
// if we've reached this point, then it means that a fatal error has occurred and the
|
||||
// application 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);
|
||||
__asm volatile(" dsb \n"
|
||||
" isb \n"
|
||||
" wfi \n");
|
||||
MAP_GPIOPinWrite(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, MICROPY_SYS_LED_PORT_PIN);
|
||||
__asm volatile(" dsb \n"
|
||||
" isb \n"
|
||||
" wfi \n");
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//! The following stub function is needed to link mp_vprintf
|
||||
//*****************************************************************************
|
||||
#include "py/qstr.h"
|
||||
|
||||
const byte *qstr_data(qstr q, mp_uint_t *len) {
|
||||
*len = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -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,22 +9,22 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "diskio.h" /* FatFs lower layer API */
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/obj.h"
|
||||
#include "diskio.h" /* FatFs lower layer API */
|
||||
#include "sflash_diskio.h" /* Serial flash disk IO API */
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
#include "sd_diskio.h" /* SDCARD disk IO API */
|
||||
#endif
|
||||
#include "modutime.h"
|
||||
#include "sd_diskio.h" /* SDCARD disk IO API */
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "rom_map.h"
|
||||
#include "prcm.h"
|
||||
|
||||
/* Definitions of physical drive number for each drive */
|
||||
#define SFLASH 0 /* Map SFLASH drive to drive number 0 */
|
||||
#define SDCARD 1 /* Map SD card to drive number 1 */
|
||||
#include "pybrtc.h"
|
||||
#include "timeutils.h"
|
||||
#include "ff.h"
|
||||
#include "pybsd.h"
|
||||
#include "moduos.h"
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
@@ -35,21 +35,20 @@ DSTATUS disk_status (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
switch (pdrv) {
|
||||
case SFLASH :
|
||||
return sflash_disk_status();
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
case SDCARD :
|
||||
return sd_disk_status();
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return STA_NODISK;
|
||||
if (pdrv == FLASH) {
|
||||
return sflash_disk_status();
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||
if (mount_obj->writeblocks[0] == MP_OBJ_NULL) {
|
||||
return STA_PROTECT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return STA_NODISK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Inidialize a Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
@@ -58,29 +57,22 @@ DSTATUS disk_initialize (
|
||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||
)
|
||||
{
|
||||
DSTATUS stat = 0;
|
||||
|
||||
switch (pdrv) {
|
||||
case SFLASH :
|
||||
if (RES_OK != sflash_disk_init()) {
|
||||
stat = STA_NOINIT;
|
||||
}
|
||||
return stat;
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
case SDCARD :
|
||||
if (RES_OK != sd_disk_init()) {
|
||||
stat = STA_NOINIT;
|
||||
if (pdrv == FLASH) {
|
||||
if (RES_OK != sflash_disk_init()) {
|
||||
return STA_NOINIT;
|
||||
}
|
||||
return stat;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return STA_NOINIT;
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||
if (mount_obj->writeblocks[0] == MP_OBJ_NULL) {
|
||||
return STA_PROTECT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return STA_NODISK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
@@ -92,22 +84,25 @@ DRESULT disk_read (
|
||||
UINT count /* Number of sectors to read */
|
||||
)
|
||||
{
|
||||
switch (pdrv) {
|
||||
case SFLASH :
|
||||
return sflash_disk_read(buff, sector, count);
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
case SDCARD :
|
||||
return sd_disk_read(buff, sector, count);
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return RES_PARERR;
|
||||
if (pdrv == FLASH) {
|
||||
return sflash_disk_read(buff, sector, count);
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||
// optimization for the built-in sd card device
|
||||
if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
|
||||
return sd_disk_read(buff, sector, count);
|
||||
}
|
||||
mount_obj->readblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
|
||||
mount_obj->readblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, buff);
|
||||
return mp_obj_get_int(mp_call_method_n_kw(2, 0, mount_obj->readblocks));
|
||||
}
|
||||
// nothing mounted
|
||||
return RES_ERROR;
|
||||
}
|
||||
return RES_PARERR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
@@ -120,18 +115,23 @@ DRESULT disk_write (
|
||||
UINT count /* Number of sectors to write */
|
||||
)
|
||||
{
|
||||
switch (pdrv) {
|
||||
case SFLASH :
|
||||
return sflash_disk_write(buff, sector, count);
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
case SDCARD :
|
||||
return sd_disk_write(buff, sector, count);
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return RES_PARERR;
|
||||
if (pdrv == FLASH) {
|
||||
return sflash_disk_write(buff, sector, count);
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||
// optimization for the built-in sd card device
|
||||
if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
|
||||
return sd_disk_write(buff, sector, count);
|
||||
}
|
||||
mount_obj->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
|
||||
mount_obj->writeblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, (void *)buff);
|
||||
return mp_obj_get_int(mp_call_method_n_kw(2, 0, mount_obj->writeblocks));
|
||||
}
|
||||
// nothing mounted
|
||||
return RES_ERROR;
|
||||
}
|
||||
return RES_PARERR;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -147,41 +147,47 @@ DRESULT disk_ioctl (
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
switch (pdrv) {
|
||||
case SFLASH:
|
||||
if (pdrv == FLASH) {
|
||||
switch (cmd) {
|
||||
case CTRL_SYNC:
|
||||
return sflash_disk_flush();
|
||||
case GET_SECTOR_COUNT:
|
||||
*((DWORD*)buff) = SFLASH_SECTOR_COUNT;
|
||||
return RES_OK;
|
||||
break;
|
||||
case GET_SECTOR_SIZE:
|
||||
*((WORD*)buff) = SFLASH_SECTOR_SIZE;
|
||||
*((DWORD*)buff) = SFLASH_SECTOR_SIZE;
|
||||
return RES_OK;
|
||||
break;
|
||||
case GET_BLOCK_SIZE:
|
||||
*((DWORD*)buff) = 1; // high-level sector erase size in units of the block size
|
||||
return RES_OK;
|
||||
}
|
||||
break;
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
case SDCARD:
|
||||
switch (cmd) {
|
||||
case CTRL_SYNC:
|
||||
return RES_OK;
|
||||
case GET_SECTOR_COUNT:
|
||||
*(WORD*)buff = sd_disk_info.ulNofBlock;
|
||||
break;
|
||||
case GET_SECTOR_SIZE :
|
||||
*(WORD*)buff = SD_SECTOR_SIZE;
|
||||
break;
|
||||
case GET_BLOCK_SIZE:
|
||||
*((DWORD*)buff) = 1; // high-level sector erase size in units of the block size
|
||||
return RES_OK;
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||
switch (cmd) {
|
||||
case CTRL_SYNC:
|
||||
if (mount_obj->sync[0] != MP_OBJ_NULL) {
|
||||
mp_call_method_n_kw(0, 0, mount_obj->sync);
|
||||
}
|
||||
return RES_OK;
|
||||
case GET_SECTOR_COUNT:
|
||||
// optimization for the built-in sd card device
|
||||
if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
|
||||
*((DWORD*)buff) = sd_disk_info.ulNofBlock * (sd_disk_info.ulBlockSize / 512);
|
||||
} else {
|
||||
*((DWORD*)buff) = mp_obj_get_int(mp_call_method_n_kw(0, 0, mount_obj->count));
|
||||
}
|
||||
return RES_OK;
|
||||
case GET_SECTOR_SIZE:
|
||||
*((DWORD*)buff) = SD_SECTOR_SIZE; // Sector size is fixed to 512 bytes, as with SD cards
|
||||
return RES_OK;
|
||||
case GET_BLOCK_SIZE:
|
||||
*((DWORD*)buff) = 1; // high-level sector erase size in units of the block size
|
||||
return RES_OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
// nothing mounted
|
||||
return RES_ERROR;
|
||||
}
|
||||
return RES_PARERR;
|
||||
}
|
||||
@@ -192,13 +198,8 @@ DWORD get_fattime (
|
||||
void
|
||||
)
|
||||
{
|
||||
mod_struct_time tm;
|
||||
uint32_t seconds;
|
||||
uint16_t mseconds;
|
||||
|
||||
// Get the time from the on-chip RTC and convert it to struct_time
|
||||
MAP_PRCMRTCGet(&seconds, &mseconds);
|
||||
mod_time_seconds_since_2000_to_struct_time(seconds, &tm);
|
||||
timeutils_struct_time_t tm;
|
||||
timeutils_seconds_since_2000_to_struct_time(pyb_rtc_get_seconds(), &tm);
|
||||
|
||||
return ((tm.tm_year - 1980) << 25) | ((tm.tm_mon) << 21) |
|
||||
((tm.tm_mday) << 16) | ((tm.tm_hour) << 11) |
|
||||
|
||||
@@ -38,6 +38,8 @@ DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
/* Definitions of physical drive number for each drive */
|
||||
#define FLASH 0 /* Map FLASH drive to drive number 0 */
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -286,8 +279,6 @@ DSTATUS sd_disk_init (void) {
|
||||
sd_disk_info.bStatus = 0;
|
||||
}
|
||||
}
|
||||
// Set card rd/wr block len
|
||||
MAP_SDHostBlockSizeSet(SDHOST_BASE, SD_SECTOR_SIZE);
|
||||
}
|
||||
|
||||
return sd_disk_info.bStatus;
|
||||
@@ -295,24 +286,18 @@ DSTATUS sd_disk_init (void) {
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Gets the disk status.
|
||||
//! De-initializes the physical drive
|
||||
//!
|
||||
//! This function gets the current status of the drive.
|
||||
//!
|
||||
//! \return Returns the current status of the specified drive
|
||||
//
|
||||
//! This function de-initializes the physical drive
|
||||
//*****************************************************************************
|
||||
DSTATUS sd_disk_status (void) {
|
||||
return sd_disk_info.bStatus;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Returns wether the sd card is ready to be accessed or not
|
||||
//
|
||||
//*****************************************************************************
|
||||
bool sd_disk_ready (void) {
|
||||
return (!sd_disk_info.bStatus);
|
||||
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;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -367,6 +352,7 @@ DRESULT sd_disk_read (BYTE* pBuffer, DWORD ulSectorNumber, UINT SectorCount) {
|
||||
pBuffer += 4;
|
||||
}
|
||||
CardSendCmd(CMD_STOP_TRANS, 0);
|
||||
while (!(MAP_SDHostIntStatus(SDHOST_BASE) & SDHOST_INT_TC));
|
||||
Res = RES_OK;
|
||||
}
|
||||
}
|
||||
@@ -386,61 +372,62 @@ DRESULT sd_disk_read (BYTE* pBuffer, DWORD ulSectorNumber, UINT SectorCount) {
|
||||
//
|
||||
//*****************************************************************************
|
||||
DRESULT sd_disk_write (const BYTE* pBuffer, DWORD ulSectorNumber, UINT SectorCount) {
|
||||
DRESULT Res = RES_ERROR;
|
||||
unsigned long ulSize;
|
||||
DRESULT Res = RES_ERROR;
|
||||
unsigned long ulSize;
|
||||
|
||||
if (SectorCount > 0) {
|
||||
// Return if disk not initialized
|
||||
if (sd_disk_info.bStatus & STA_NOINIT) {
|
||||
return RES_NOTRDY;
|
||||
}
|
||||
if (SectorCount > 0) {
|
||||
// Return if disk not initialized
|
||||
if (sd_disk_info.bStatus & STA_NOINIT) {
|
||||
return RES_NOTRDY;
|
||||
}
|
||||
|
||||
// SDSC uses linear address, SDHC uses block address
|
||||
if (sd_disk_info.ulCapClass == CARD_CAP_CLASS_SDSC) {
|
||||
ulSectorNumber = ulSectorNumber * SD_SECTOR_SIZE;
|
||||
}
|
||||
// SDSC uses linear address, SDHC uses block address
|
||||
if (sd_disk_info.ulCapClass == CARD_CAP_CLASS_SDSC) {
|
||||
ulSectorNumber = ulSectorNumber * SD_SECTOR_SIZE;
|
||||
}
|
||||
|
||||
// Set the block count
|
||||
MAP_SDHostBlockCountSet(SDHOST_BASE, SectorCount);
|
||||
// Set the block count
|
||||
MAP_SDHostBlockCountSet(SDHOST_BASE, SectorCount);
|
||||
|
||||
// Compute the number of words
|
||||
ulSize = (SD_SECTOR_SIZE * SectorCount) / 4;
|
||||
// Compute the number of words
|
||||
ulSize = (SD_SECTOR_SIZE * SectorCount) / 4;
|
||||
|
||||
// Check if 1 block or multi block transfer
|
||||
if (SectorCount == 1) {
|
||||
// Send single block write command
|
||||
if (CardSendCmd(CMD_WRITE_SINGLE_BLK, ulSectorNumber) == 0) {
|
||||
// Write the data
|
||||
while (ulSize--) {
|
||||
MAP_SDHostDataWrite (SDHOST_BASE, (*(unsigned long *)pBuffer));
|
||||
pBuffer += 4;
|
||||
}
|
||||
// Wait for data transfer complete
|
||||
while (!(MAP_SDHostIntStatus(SDHOST_BASE) & SDHOST_INT_TC));
|
||||
Res = RES_OK;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Set the card write block count
|
||||
if (sd_disk_info.ucCardType == CARD_TYPE_SDCARD) {
|
||||
CardSendCmd(CMD_APP_CMD,sd_disk_info.usRCA << 16);
|
||||
CardSendCmd(CMD_SET_BLK_CNT, SectorCount);
|
||||
}
|
||||
// Check if 1 block or multi block transfer
|
||||
if (SectorCount == 1) {
|
||||
// Send single block write command
|
||||
if (CardSendCmd(CMD_WRITE_SINGLE_BLK, ulSectorNumber) == 0) {
|
||||
// Write the data
|
||||
while (ulSize--) {
|
||||
MAP_SDHostDataWrite (SDHOST_BASE, (*(unsigned long *)pBuffer));
|
||||
pBuffer += 4;
|
||||
}
|
||||
// Wait for data transfer complete
|
||||
while (!(MAP_SDHostIntStatus(SDHOST_BASE) & SDHOST_INT_TC));
|
||||
Res = RES_OK;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Set the card write block count
|
||||
if (sd_disk_info.ucCardType == CARD_TYPE_SDCARD) {
|
||||
CardSendCmd(CMD_APP_CMD,sd_disk_info.usRCA << 16);
|
||||
CardSendCmd(CMD_SET_BLK_CNT, SectorCount);
|
||||
}
|
||||
|
||||
// Send multi block write command
|
||||
if (CardSendCmd(CMD_WRITE_MULTI_BLK, ulSectorNumber) == 0) {
|
||||
// Write the data buffer
|
||||
while (ulSize--) {
|
||||
MAP_SDHostDataWrite(SDHOST_BASE, (*(unsigned long *)pBuffer));
|
||||
pBuffer += 4;
|
||||
}
|
||||
// Wait for transfer complete
|
||||
while (!(MAP_SDHostIntStatus(SDHOST_BASE) & SDHOST_INT_TC));
|
||||
CardSendCmd(CMD_STOP_TRANS, 0);
|
||||
Res = RES_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Send multi block write command
|
||||
if (CardSendCmd(CMD_WRITE_MULTI_BLK, ulSectorNumber) == 0) {
|
||||
// Write the data buffer
|
||||
while (ulSize--) {
|
||||
MAP_SDHostDataWrite(SDHOST_BASE, (*(unsigned long *)pBuffer));
|
||||
pBuffer += 4;
|
||||
}
|
||||
// Wait for transfer complete
|
||||
while (!(MAP_SDHostIntStatus(SDHOST_BASE) & SDHOST_INT_TC));
|
||||
CardSendCmd(CMD_STOP_TRANS, 0);
|
||||
while (!(MAP_SDHostIntStatus(SDHOST_BASE) & SDHOST_INT_TC));
|
||||
Res = RES_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Res;
|
||||
return Res;
|
||||
}
|
||||
|
||||
@@ -20,8 +20,7 @@ typedef struct
|
||||
extern DiskInfo_t sd_disk_info;
|
||||
|
||||
DSTATUS sd_disk_init (void);
|
||||
DSTATUS sd_disk_status (void);
|
||||
bool sd_disk_ready (void);
|
||||
void sd_disk_deinit (void);
|
||||
DRESULT sd_disk_read (BYTE* pBuffer, DWORD ulSectorNumber, UINT bSectorCount);
|
||||
DRESULT sd_disk_write (const BYTE* pBuffer, DWORD ulSectorNumber, UINT bSectorCount);
|
||||
|
||||
|
||||
@@ -2,20 +2,16 @@
|
||||
#include <stdbool.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/obj.h"
|
||||
#include "simplelink.h"
|
||||
#include "diskio.h"
|
||||
#include "sflash_diskio.h"
|
||||
#include "debug.h"
|
||||
#include "modnetwork.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 +34,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 +53,29 @@ 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;
|
||||
sflash_prblock = UINT32_MAX;
|
||||
sflash_cache_is_dirty = false;
|
||||
|
||||
// Proceed to format the memory if not done yet
|
||||
// In order too speed up booting, check the last block, if exists, then
|
||||
// it means that the file system has been already created
|
||||
print_block_name (SFLASH_BLOCK_COUNT - 1);
|
||||
sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
|
||||
if (!sl_FsGetInfo(sflash_block_name, 0, &FsFileInfo)) {
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
return RES_OK;
|
||||
}
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
|
||||
// Proceed to format the memory
|
||||
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_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,19 +83,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;
|
||||
}
|
||||
return RES_OK;
|
||||
}
|
||||
@@ -112,7 +107,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 +140,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)
|
||||
|
||||
@@ -25,22 +25,18 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <std.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "py/mpstate.h"
|
||||
#include "ff.h"
|
||||
#include "ffconf.h"
|
||||
#include "diskio.h"
|
||||
#include "moduos.h"
|
||||
|
||||
#if _FS_RPATH
|
||||
extern BYTE ff_CurrVol;
|
||||
#endif
|
||||
|
||||
STATIC bool check_path(const TCHAR **path, const char *mount_point_str, mp_uint_t mount_point_len) {
|
||||
stoupper ((char *)(*path));
|
||||
if (strncmp(*path, mount_point_str, mount_point_len) == 0) {
|
||||
if ((*path)[mount_point_len] == '/') {
|
||||
*path += mount_point_len;
|
||||
@@ -61,39 +57,37 @@ 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)) {
|
||||
return 0;
|
||||
if (check_path(path, "/flash", 6)) {
|
||||
return FLASH;
|
||||
}
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
else if (check_path(path, "/SD", 3)) {
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
return -1;
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
if (check_path(path, mount_obj->path, mount_obj->pathlen)) {
|
||||
return mount_obj->vol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ff_get_volname(BYTE vol, TCHAR **dest) {
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
if (vol == 0)
|
||||
#endif
|
||||
{
|
||||
memcpy(*dest, "/SFLASH", 7);
|
||||
*dest += 7;
|
||||
if (vol == FLASH) {
|
||||
memcpy(*dest, "/flash", 6);
|
||||
*dest += 6;
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_volume(vol))) {
|
||||
memcpy(*dest, mount_obj->path, mount_obj->pathlen);
|
||||
*dest += mount_obj->pathlen;
|
||||
}
|
||||
}
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
else
|
||||
{
|
||||
memcpy(*dest, "/SD", 3);
|
||||
*dest += 3;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,15 +1,42 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module configuration file R0.10c (C)ChaN, 2014
|
||||
/---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* Original file from:
|
||||
* FatFs - FAT file system module configuration file R0.10c (C)ChaN, 2014
|
||||
*
|
||||
* 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 _FFCONF
|
||||
#define _FFCONF 32020 /* Revision ID */
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
#define _FFCONF 80376 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Functions and Buffer Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
@@ -24,9 +51,9 @@
|
||||
|
||||
#define _FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes basic writing API functions, f_write(),
|
||||
/ f_sync(), f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(),
|
||||
/ f_getfree() and optional writing functions as well. */
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0
|
||||
@@ -48,9 +75,13 @@
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define _USE_FIND 0
|
||||
/* This option switches filtered directory read feature and related functions,
|
||||
/ f_findfirst() and f_findnext(). (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_MKFS 1
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable)
|
||||
/ To enable it, also _FS_READONLY need to be set to 0. */
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define _USE_FASTSEEK 0
|
||||
@@ -63,8 +94,8 @@
|
||||
|
||||
|
||||
#define _USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
/* To enable it, also _FS_TINY need to be set to 1. */
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable)
|
||||
/ To enable it, also _FS_TINY need to be set to 1. */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
@@ -75,32 +106,24 @@
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect setting of the code page can cause a file open failure.
|
||||
/
|
||||
/ 932 - Japanese Shift_JIS (DBCS, OEM, Windows)
|
||||
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
|
||||
/ 949 - Korean (DBCS, OEM, Windows)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
|
||||
/ 1250 - Central Europe (Windows)
|
||||
/ 1251 - Cyrillic (Windows)
|
||||
/ 1252 - Latin 1 (Windows)
|
||||
/ 1253 - Greek (Windows)
|
||||
/ 1254 - Turkish (Windows)
|
||||
/ 1255 - Hebrew (Windows)
|
||||
/ 1256 - Arabic (Windows)
|
||||
/ 1257 - Baltic (Windows)
|
||||
/ 1258 - Vietnam (OEM, Windows)
|
||||
/ 437 - U.S. (OEM)
|
||||
/ 720 - Arabic (OEM)
|
||||
/ 737 - Greek (OEM)
|
||||
/ 775 - Baltic (OEM)
|
||||
/ 850 - Multilingual Latin 1 (OEM)
|
||||
/ 858 - Multilingual Latin 1 + Euro (OEM)
|
||||
/ 852 - Latin 2 (OEM)
|
||||
/ 855 - Cyrillic (OEM)
|
||||
/ 866 - Russian (OEM)
|
||||
/ 857 - Turkish (OEM)
|
||||
/ 862 - Hebrew (OEM)
|
||||
/ 874 - Thai (OEM, Windows)
|
||||
/ 1 - ASCII (No extended character. Valid for only non-LFN configuration.) */
|
||||
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 775 - Baltic
|
||||
/ 850 - Multilingual Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 858 - Multilingual Latin 1 + Euro
|
||||
/ 862 - Hebrew
|
||||
/ 866 - Russian
|
||||
/ 874 - Thai
|
||||
/ 932 - Japanese Shift_JIS (DBCS)
|
||||
/ 936 - Simplified Chinese GBK (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS)
|
||||
*/
|
||||
|
||||
|
||||
#define _USE_LFN (MICROPY_ENABLE_LFN)
|
||||
@@ -155,8 +178,8 @@
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
#define _STR_VOLUME_ID 0
|
||||
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
|
||||
#define _STR_VOLUME_ID 0
|
||||
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
|
||||
/* _STR_VOLUME_ID option switches string volume ID feature.
|
||||
/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
|
||||
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each
|
||||
@@ -169,7 +192,7 @@
|
||||
/ number is bound to the same physical drive number and only an FAT volume found on
|
||||
/ the physical drive will be mounted. When multi-partition feature is enabled (1),
|
||||
/ each logical drive number is bound to arbitrary physical drive and partition
|
||||
/ listed in the VolToPart[]. Also f_fdisk() funciton will be enabled. */
|
||||
/ listed in the VolToPart[]. Also f_fdisk() funciton will be available. */
|
||||
|
||||
|
||||
#define _MIN_SS 512
|
||||
@@ -206,9 +229,9 @@
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_NORTC 0
|
||||
#define _NORTC_MON 11
|
||||
#define _NORTC_MDAY 9
|
||||
#define _NORTC_YEAR 2014
|
||||
#define _NORTC_MON 2
|
||||
#define _NORTC_MDAY 1
|
||||
#define _NORTC_YEAR 2015
|
||||
/* The _FS_NORTC option switches timestamp feature. If the system does not have
|
||||
/ an RTC function or valid timestamp is not needed, set _FS_NORTC to 1 to disable
|
||||
/ the timestamp feature. All objects modified by FatFs will have a fixed timestamp
|
||||
@@ -232,7 +255,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
|
||||
@@ -274,3 +297,4 @@
|
||||
/ PIC32 0 H8/300H 0 8051 0/1
|
||||
*/
|
||||
|
||||
#endif // _FFCONF
|
||||
|
||||
@@ -3,12 +3,6 @@
|
||||
/* (C)ChaN, 2014 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "misc.h"
|
||||
#include "nlr.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "ff.h"
|
||||
|
||||
|
||||
@@ -38,7 +32,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;
|
||||
@@ -138,7 +132,7 @@ void* ff_memalloc ( /* Returns pointer to the allocated memory block */
|
||||
UINT msize /* Number of bytes to allocate */
|
||||
)
|
||||
{
|
||||
return malloc(msize); /* Allocate a new memory block with POSIX API */
|
||||
return pvPortMalloc(msize); /* Allocate a new memory block with POSIX API */
|
||||
}
|
||||
|
||||
|
||||
@@ -150,7 +144,7 @@ void ff_memfree (
|
||||
void* mblock /* Pointer to the memory block to free */
|
||||
)
|
||||
{
|
||||
free(mblock); /* Discard the memory block with POSIX API */
|
||||
vPortFree(mblock); /* Discard the memory block with POSIX API */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
301
cc3200/ftp/ftp.c
301
cc3200/ftp/ftp.c
@@ -26,15 +26,11 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ctype.h>
|
||||
#include <std.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpstate.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"
|
||||
@@ -43,17 +39,17 @@
|
||||
#include "pybrtc.h"
|
||||
#include "ftp.h"
|
||||
#include "simplelink.h"
|
||||
#include "modnetwork.h"
|
||||
#include "modwlan.h"
|
||||
#include "modutime.h"
|
||||
#include "modusocket.h"
|
||||
#include "debug.h"
|
||||
#include "serverstask.h"
|
||||
#include "ff.h"
|
||||
#include "fifo.h"
|
||||
#include "socketfifo.h"
|
||||
#include "diskio.h"
|
||||
#include "sd_diskio.h"
|
||||
#include "updater.h"
|
||||
|
||||
#include "timeutils.h"
|
||||
#include "moduos.h"
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE CONSTANTS
|
||||
@@ -70,8 +66,7 @@
|
||||
#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_SOCKETFIFO_ELEMENTS_MAX 4
|
||||
#define FTP_CYCLE_TIME_MS (SERVERS_CYCLE_TIME_MS * 2)
|
||||
|
||||
@@ -98,16 +93,12 @@ typedef enum {
|
||||
E_FTP_STE_SUB_DISCONNECTED = 0,
|
||||
E_FTP_STE_SUB_LISTEN_FOR_DATA,
|
||||
E_FTP_STE_SUB_DATA_CONNECTED
|
||||
} ftp_data_substate_t;
|
||||
|
||||
typedef union {
|
||||
ftp_data_substate_t data;
|
||||
} ftp_substate_t;
|
||||
|
||||
typedef struct {
|
||||
bool uservalid : 1;
|
||||
bool passvalid : 1;
|
||||
}ftp_loggin_t;
|
||||
} ftp_loggin_t;
|
||||
|
||||
typedef enum {
|
||||
E_FTP_NOTHING_OPEN = 0,
|
||||
@@ -123,6 +114,7 @@ typedef enum {
|
||||
|
||||
typedef struct {
|
||||
uint8_t *dBuffer;
|
||||
uint32_t ctimeout;
|
||||
union {
|
||||
DIR dp;
|
||||
FIL fp;
|
||||
@@ -130,28 +122,28 @@ 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;
|
||||
ftp_substate_t substate;
|
||||
uint16_t volcount;
|
||||
uint8_t state;
|
||||
uint8_t substate;
|
||||
uint8_t txRetries;
|
||||
uint8_t logginRetries;
|
||||
ftp_loggin_t loggin;
|
||||
uint8_t e_open;
|
||||
bool closechild;
|
||||
bool enabled;
|
||||
bool swupdating;
|
||||
|
||||
bool special_file;
|
||||
bool listroot;
|
||||
} ftp_data_t;
|
||||
|
||||
typedef struct {
|
||||
char * cmd;
|
||||
}ftp_cmd_t;
|
||||
} ftp_cmd_t;
|
||||
|
||||
typedef struct {
|
||||
char * month;
|
||||
}ftp_month_t;
|
||||
} ftp_month_t;
|
||||
|
||||
typedef enum {
|
||||
E_FTP_CMD_NOT_SUPPORTED = -1,
|
||||
@@ -178,7 +170,7 @@ typedef enum {
|
||||
E_FTP_CMD_NOOP,
|
||||
E_FTP_CMD_QUIT,
|
||||
E_FTP_NUM_FTP_CMDS
|
||||
}ftp_cmd_index_t;
|
||||
} ftp_cmd_index_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
@@ -198,7 +190,7 @@ static const ftp_month_t ftp_month[] = { { "Jan" }, { "Feb" }, { "Mar" }, { "Apr
|
||||
{ "May" }, { "Jun" }, { "Jul" }, { "Ago" },
|
||||
{ "Sep" }, { "Oct" }, { "Nov" }, { "Dec" } };
|
||||
|
||||
static SocketFifoElement_t *ftp_fifoelements;
|
||||
static SocketFifoElement_t ftp_fifoelements[FTP_SOCKETFIFO_ELEMENTS_MAX];
|
||||
static FIFO_t ftp_socketfifo;
|
||||
|
||||
/******************************************************************************
|
||||
@@ -216,7 +208,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);
|
||||
@@ -224,7 +215,7 @@ static int ftp_print_eplf_drive (char *dest, uint32_t destsize, char *name);
|
||||
static bool ftp_open_file (const char *path, int mode);
|
||||
static ftp_result_t ftp_read_file (char *filebuf, uint32_t desiredsize, uint32_t *actualsize);
|
||||
static ftp_result_t ftp_write_file (char *filebuf, uint32_t size);
|
||||
static ftp_result_t ftp_open_dir_for_listing (const char *path, char *list, uint32_t maxlistsize, uint32_t *listsize);
|
||||
static ftp_result_t ftp_open_dir_for_listing (const char *path);
|
||||
static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *listsize);
|
||||
static void ftp_open_child (char *pwd, char *dir);
|
||||
static void ftp_close_child (char *pwd);
|
||||
@@ -239,7 +230,6 @@ void ftp_init (void) {
|
||||
ASSERT ((ftp_path = mem_Malloc(FTP_MAX_PARAM_SIZE)) != NULL);
|
||||
ASSERT ((ftp_scratch_buffer = mem_Malloc(FTP_MAX_PARAM_SIZE)) != NULL);
|
||||
ASSERT ((ftp_cmd_buffer = mem_Malloc(FTP_MAX_PARAM_SIZE + FTP_CMD_SIZE_MAX)) != NULL);
|
||||
ASSERT ((ftp_fifoelements = mem_Malloc(FTP_SOCKETFIFO_ELEMENTS_MAX * sizeof(SocketFifoElement_t))) != NULL);
|
||||
SOCKETFIFO_Init (&ftp_socketfifo, (void *)ftp_fifoelements, FTP_SOCKETFIFO_ELEMENTS_MAX);
|
||||
ftp_data.c_sd = -1;
|
||||
ftp_data.d_sd = -1;
|
||||
@@ -247,8 +237,9 @@ void ftp_init (void) {
|
||||
ftp_data.ld_sd = -1;
|
||||
ftp_data.e_open = E_FTP_NOTHING_OPEN;
|
||||
ftp_data.state = E_FTP_STE_DISABLED;
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
|
||||
ftp_data.swupdating = false;
|
||||
ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
|
||||
ftp_data.special_file = false;
|
||||
ftp_data.volcount = 0;
|
||||
}
|
||||
|
||||
void ftp_run (void) {
|
||||
@@ -257,12 +248,12 @@ void ftp_run (void) {
|
||||
ftp_wait_for_enabled();
|
||||
break;
|
||||
case E_FTP_STE_START:
|
||||
if (ftp_create_listening_socket(&ftp_data.lc_sd, FTP_CMD_PORT, FTP_CMD_CLIENTS_MAX )) {
|
||||
if (wlan_is_connected() && ftp_create_listening_socket(&ftp_data.lc_sd, FTP_CMD_PORT, FTP_CMD_CLIENTS_MAX)) {
|
||||
ftp_data.state = E_FTP_STE_READY;
|
||||
}
|
||||
break;
|
||||
case E_FTP_STE_READY:
|
||||
if (ftp_data.c_sd < 0 && ftp_data.substate.data == E_FTP_STE_SUB_DISCONNECTED) {
|
||||
if (ftp_data.c_sd < 0 && ftp_data.substate == E_FTP_STE_SUB_DISCONNECTED) {
|
||||
if (E_FTP_RESULT_OK == ftp_wait_for_connection(ftp_data.lc_sd, &ftp_data.c_sd)) {
|
||||
ftp_data.txRetries = 0;
|
||||
ftp_data.logginRetries = 0;
|
||||
@@ -275,7 +266,7 @@ void ftp_run (void) {
|
||||
}
|
||||
}
|
||||
if (SOCKETFIFO_IsEmpty()) {
|
||||
if (ftp_data.c_sd > 0 && ftp_data.substate.data != E_FTP_STE_SUB_LISTEN_FOR_DATA) {
|
||||
if (ftp_data.c_sd > 0 && ftp_data.substate != E_FTP_STE_SUB_LISTEN_FOR_DATA) {
|
||||
ftp_process_cmd();
|
||||
if (ftp_data.state != E_FTP_STE_READY) {
|
||||
break;
|
||||
@@ -292,8 +283,7 @@ void ftp_run (void) {
|
||||
ftp_list_dir((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, &listsize);
|
||||
if (listsize > 0) {
|
||||
ftp_send_data(listsize);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
ftp_send_reply(226, NULL);
|
||||
ftp_data.state = E_FTP_STE_END_TRANSFER;
|
||||
}
|
||||
@@ -305,19 +295,21 @@ void ftp_run (void) {
|
||||
if (SOCKETFIFO_IsEmpty()) {
|
||||
uint32_t readsize;
|
||||
ftp_result_t result;
|
||||
ftp_data.ctimeout = 0;
|
||||
result = ftp_read_file ((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, &readsize);
|
||||
if (readsize > 0 && result != E_FTP_RESULT_FAILED) {
|
||||
ftp_send_data(readsize);
|
||||
ftp_data.ctimeout = 0;
|
||||
if (result == E_FTP_RESULT_FAILED) {
|
||||
ftp_send_reply(451, NULL);
|
||||
ftp_data.state = E_FTP_STE_END_TRANSFER;
|
||||
}
|
||||
else {
|
||||
if (readsize > 0) {
|
||||
ftp_send_data(readsize);
|
||||
}
|
||||
if (result == E_FTP_RESULT_OK) {
|
||||
ftp_send_reply(226, NULL);
|
||||
ftp_data.state = E_FTP_STE_END_TRANSFER;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ftp_send_reply(451, NULL);
|
||||
ftp_data.state = E_FTP_STE_END_TRANSFER;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case E_FTP_STE_CONTINUE_FILE_RX:
|
||||
@@ -328,7 +320,7 @@ void ftp_run (void) {
|
||||
ftp_data.dtimeout = 0;
|
||||
ftp_data.ctimeout = 0;
|
||||
// its a software update
|
||||
if (ftp_data.swupdating) {
|
||||
if (ftp_data.special_file) {
|
||||
if (updater_write(ftp_data.dBuffer, len)) {
|
||||
break;
|
||||
}
|
||||
@@ -348,8 +340,8 @@ void ftp_run (void) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ftp_data.swupdating) {
|
||||
ftp_data.swupdating = false;
|
||||
if (ftp_data.special_file) {
|
||||
ftp_data.special_file = false;
|
||||
updater_finnish();
|
||||
}
|
||||
ftp_close_files();
|
||||
@@ -362,19 +354,19 @@ void ftp_run (void) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ftp_data.substate.data) {
|
||||
switch (ftp_data.substate) {
|
||||
case E_FTP_STE_SUB_DISCONNECTED:
|
||||
break;
|
||||
case E_FTP_STE_SUB_LISTEN_FOR_DATA:
|
||||
if (E_FTP_RESULT_OK == ftp_wait_for_connection(ftp_data.ld_sd, &ftp_data.d_sd)) {
|
||||
ftp_data.dtimeout = 0;
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_DATA_CONNECTED;
|
||||
ftp_data.substate = E_FTP_STE_SUB_DATA_CONNECTED;
|
||||
}
|
||||
else if (ftp_data.dtimeout++ > FTP_DATA_TIMEOUT_MS / FTP_CYCLE_TIME_MS) {
|
||||
ftp_data.dtimeout = 0;
|
||||
// close the listening socket
|
||||
servers_close_socket(&ftp_data.ld_sd);
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
|
||||
ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
|
||||
}
|
||||
break;
|
||||
case E_FTP_STE_SUB_DATA_CONNECTED:
|
||||
@@ -383,7 +375,7 @@ void ftp_run (void) {
|
||||
servers_close_socket(&ftp_data.ld_sd);
|
||||
servers_close_socket(&ftp_data.d_sd);
|
||||
ftp_close_filesystem_on_error ();
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
|
||||
ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -395,7 +387,7 @@ void ftp_run (void) {
|
||||
|
||||
// check the state of the data sockets
|
||||
if (ftp_data.d_sd < 0 && (ftp_data.state > E_FTP_STE_READY)) {
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
|
||||
ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
|
||||
ftp_data.state = E_FTP_STE_READY;
|
||||
}
|
||||
}
|
||||
@@ -410,6 +402,17 @@ void ftp_disable (void) {
|
||||
ftp_data.state = E_FTP_STE_DISABLED;
|
||||
}
|
||||
|
||||
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 = E_FTP_STE_SUB_DISCONNECTED;
|
||||
ftp_data.volcount = 0;
|
||||
SOCKETFIFO_Flush();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
@@ -431,21 +434,27 @@ static bool ftp_create_listening_socket (_i16 *sd, _u16 port, _u8 backlog) {
|
||||
_sd = *sd;
|
||||
|
||||
if (_sd > 0) {
|
||||
// add the new socket to the network administration
|
||||
modusocket_socket_add(_sd, false);
|
||||
|
||||
// Enable non-blocking mode
|
||||
nonBlockingOption.NonblockingEnabled = 1;
|
||||
ASSERT (sl_SetSockOpt(_sd, SOL_SOCKET, SL_SO_NONBLOCKING, &nonBlockingOption, sizeof(nonBlockingOption)) == SL_SOC_OK);
|
||||
ASSERT ((result = sl_SetSockOpt(_sd, SOL_SOCKET, SL_SO_NONBLOCKING, &nonBlockingOption, sizeof(nonBlockingOption))) == SL_SOC_OK);
|
||||
|
||||
// Bind the socket to a port number
|
||||
sServerAddress.sin_family = AF_INET;
|
||||
sServerAddress.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
sServerAddress.sin_addr.s_addr = INADDR_ANY;
|
||||
sServerAddress.sin_port = htons(port);
|
||||
|
||||
ASSERT (sl_Bind(_sd, (const SlSockAddr_t *)&sServerAddress, sizeof(sServerAddress)) == SL_SOC_OK);
|
||||
ASSERT ((result |= sl_Bind(_sd, (const SlSockAddr_t *)&sServerAddress, sizeof(sServerAddress))) == SL_SOC_OK);
|
||||
|
||||
// Start listening
|
||||
ASSERT ((result = sl_Listen (_sd, backlog)) == SL_SOC_OK);
|
||||
ASSERT ((result |= sl_Listen (_sd, backlog)) == SL_SOC_OK);
|
||||
|
||||
return (result == SL_SOC_OK) ? true : false;
|
||||
if (result == SL_SOC_OK) {
|
||||
return true;
|
||||
}
|
||||
servers_close_socket(sd);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -466,6 +475,9 @@ static ftp_result_t ftp_wait_for_connection (_i16 l_sd, _i16 *n_sd) {
|
||||
return E_FTP_RESULT_FAILED;
|
||||
}
|
||||
|
||||
// add the new socket to the network administration
|
||||
modusocket_socket_add(_sd, false);
|
||||
|
||||
// client connected, so go on
|
||||
return E_FTP_RESULT_OK;
|
||||
}
|
||||
@@ -541,7 +553,7 @@ static void ftp_send_from_fifo (void) {
|
||||
servers_close_socket(&ftp_data.ld_sd);
|
||||
// this one is the command socket
|
||||
servers_close_socket(fifoelement.sd);
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
|
||||
ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
|
||||
}
|
||||
ftp_close_filesystem_on_error();
|
||||
}
|
||||
@@ -562,8 +574,8 @@ static void ftp_send_from_fifo (void) {
|
||||
// close the listening and the data sockets
|
||||
servers_close_socket(&ftp_data.ld_sd);
|
||||
servers_close_socket(&ftp_data.d_sd);
|
||||
if (ftp_data.swupdating) {
|
||||
ftp_data.swupdating = false;
|
||||
if (ftp_data.special_file) {
|
||||
ftp_data.special_file = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -591,9 +603,12 @@ static void ftp_process_cmd (void) {
|
||||
_i32 len;
|
||||
char *bufptr = (char *)ftp_cmd_buffer;
|
||||
ftp_result_t result;
|
||||
uint32_t listsize;
|
||||
FILINFO fno;
|
||||
FRESULT fres;
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
fno.lfname = NULL;
|
||||
fno.lfsize = 0;
|
||||
#endif
|
||||
|
||||
ftp_data.closechild = false;
|
||||
// also use the reply buffer to receive new commands
|
||||
@@ -669,7 +684,7 @@ static void ftp_process_cmd (void) {
|
||||
case E_FTP_CMD_USER:
|
||||
ftp_pop_param (&bufptr, ftp_scratch_buffer);
|
||||
if (!memcmp(ftp_scratch_buffer, servers_user, MAX(strlen(ftp_scratch_buffer), strlen(servers_user)))) {
|
||||
ftp_data.loggin.uservalid = true;
|
||||
ftp_data.loggin.uservalid = true && (strlen(servers_user) == strlen(ftp_scratch_buffer));
|
||||
}
|
||||
ftp_send_reply(331, NULL);
|
||||
break;
|
||||
@@ -677,18 +692,19 @@ static void ftp_process_cmd (void) {
|
||||
ftp_pop_param (&bufptr, ftp_scratch_buffer);
|
||||
if (!memcmp(ftp_scratch_buffer, servers_pass, MAX(strlen(ftp_scratch_buffer), strlen(servers_pass))) &&
|
||||
ftp_data.loggin.uservalid) {
|
||||
ftp_data.loggin.passvalid = true;
|
||||
ftp_send_reply(230, NULL);
|
||||
}
|
||||
else {
|
||||
ftp_send_reply(530, NULL);
|
||||
ftp_data.loggin.passvalid = true && (strlen(servers_pass) == strlen(ftp_scratch_buffer));
|
||||
if (ftp_data.loggin.passvalid) {
|
||||
ftp_send_reply(230, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ftp_send_reply(530, NULL);
|
||||
break;
|
||||
case E_FTP_CMD_PASV:
|
||||
{
|
||||
// some servers (e.g. google chrome) send PASV several times very quickly
|
||||
servers_close_socket(&ftp_data.d_sd);
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
|
||||
ftp_data.substate = E_FTP_STE_SUB_DISCONNECTED;
|
||||
bool socketcreated = true;
|
||||
if (ftp_data.ld_sd < 0) {
|
||||
socketcreated = ftp_create_listening_socket(&ftp_data.ld_sd, FTP_PASIVE_DATA_PORT, FTP_DATA_CLIENTS_MAX);
|
||||
@@ -699,8 +715,8 @@ static void ftp_process_cmd (void) {
|
||||
ftp_data.dtimeout = 0;
|
||||
wlan_get_ip(&ip);
|
||||
snprintf((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, "(%u,%u,%u,%u,%u,%u)",
|
||||
pip[0], pip[1], pip[2], pip[3], (FTP_PASIVE_DATA_PORT >> 8), (FTP_PASIVE_DATA_PORT & 0xFF));
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_LISTEN_FOR_DATA;
|
||||
pip[3], pip[2], pip[1], pip[0], (FTP_PASIVE_DATA_PORT >> 8), (FTP_PASIVE_DATA_PORT & 0xFF));
|
||||
ftp_data.substate = E_FTP_STE_SUB_LISTEN_FOR_DATA;
|
||||
ftp_send_reply(227, (char *)ftp_data.dBuffer);
|
||||
}
|
||||
else {
|
||||
@@ -709,13 +725,7 @@ static void ftp_process_cmd (void) {
|
||||
}
|
||||
break;
|
||||
case E_FTP_CMD_LIST:
|
||||
if ((result = ftp_open_dir_for_listing(ftp_path, (char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, &listsize)) == E_FTP_RESULT_OK) {
|
||||
ftp_data.state = E_FTP_STE_END_TRANSFER;
|
||||
ftp_send_reply(150, NULL);
|
||||
ftp_send_data(listsize);
|
||||
ftp_send_reply(226, NULL);
|
||||
}
|
||||
else if (result == E_FTP_RESULT_CONTINUE) {
|
||||
if (ftp_open_dir_for_listing(ftp_path) == E_FTP_RESULT_CONTINUE) {
|
||||
ftp_data.state = E_FTP_STE_CONTINUE_LISTING;
|
||||
ftp_send_reply(150, NULL);
|
||||
}
|
||||
@@ -738,15 +748,14 @@ static void ftp_process_cmd (void) {
|
||||
ftp_get_param_and_open_child (&bufptr);
|
||||
// first check if a software update is being requested
|
||||
if (updater_check_path (ftp_path)) {
|
||||
// start by erasing the previous status file
|
||||
// must be done before starting the updater
|
||||
f_unlink(ftp_path);
|
||||
if (updater_start()) {
|
||||
ftp_data.swupdating = true;
|
||||
ftp_data.special_file = true;
|
||||
ftp_data.state = E_FTP_STE_CONTINUE_FILE_RX;
|
||||
ftp_send_reply(150, NULL);
|
||||
}
|
||||
else {
|
||||
// to unlock the updater
|
||||
updater_finnish();
|
||||
ftp_data.state = E_FTP_STE_END_TRANSFER;
|
||||
ftp_send_reply(550, NULL);
|
||||
}
|
||||
@@ -819,7 +828,7 @@ static void ftp_process_cmd (void) {
|
||||
}
|
||||
}
|
||||
else if (result == E_FTP_RESULT_CONTINUE) {
|
||||
if (ftp_data.ctimeout++ > (FTP_CMD_TIMEOUT_MS / FTP_CYCLE_TIME_MS)) {
|
||||
if (ftp_data.ctimeout++ > (servers_get_timeout() / FTP_CYCLE_TIME_MS)) {
|
||||
ftp_send_reply(221, NULL);
|
||||
}
|
||||
}
|
||||
@@ -840,9 +849,9 @@ static void ftp_close_files (void) {
|
||||
|
||||
static void ftp_close_filesystem_on_error (void) {
|
||||
ftp_close_files();
|
||||
if (ftp_data.swupdating) {
|
||||
if (ftp_data.special_file) {
|
||||
updater_finnish ();
|
||||
ftp_data.swupdating = false;
|
||||
ftp_data.special_file = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -852,16 +861,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);
|
||||
@@ -888,37 +887,43 @@ static int ftp_print_eplf_item (char *dest, uint32_t destsize, FILINFO *fno) {
|
||||
|
||||
char *type = (fno->fattrib & AM_DIR) ? "d" : "-";
|
||||
uint32_t tseconds;
|
||||
uint16_t mseconds;
|
||||
uint mindex = (((fno->fdate >> 5) & 0x0f) > 0) ? (((fno->fdate >> 5) & 0x0f) - 1) : 0;
|
||||
uint day = ((fno->fdate & 0x1f) > 0) ? (fno->fdate & 0x1f) : 1;
|
||||
uint fseconds = mod_time_seconds_since_2000(1980 + ((fno->fdate >> 9) & 0x7f),
|
||||
uint fseconds = timeutils_seconds_since_2000(1980 + ((fno->fdate >> 9) & 0x7f),
|
||||
(fno->fdate >> 5) & 0x0f,
|
||||
fno->fdate & 0x1f,
|
||||
(fno->ftime >> 11) & 0x1f,
|
||||
(fno->ftime >> 5) & 0x3f,
|
||||
2 * (fno->ftime & 0x1f));
|
||||
MAP_PRCMRTCGet(&tseconds, &mseconds);
|
||||
tseconds = pyb_rtc_get_seconds();
|
||||
if (FTP_UNIX_SECONDS_180_DAYS < tseconds - fseconds) {
|
||||
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %5u %s\r\n",
|
||||
type, (_u32)fno->fsize, ftp_month[mindex].month, day,
|
||||
#if _USE_LFN
|
||||
1980 + ((fno->fdate >> 9) & 0x7f), *fno->lfname ? fno->lfname : fno->fname);
|
||||
#else
|
||||
1980 + ((fno->fdate >> 9) & 0x7f), fno->fname);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %02u:%02u %s\r\n",
|
||||
type, (_u32)fno->fsize, ftp_month[mindex].month, day,
|
||||
#if _USE_LFN
|
||||
(fno->ftime >> 11) & 0x1f, (fno->ftime >> 5) & 0x3f, *fno->lfname ? fno->lfname : fno->fname);
|
||||
#else
|
||||
(fno->ftime >> 11) & 0x1f, (fno->ftime >> 5) & 0x3f, fno->fname);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static int ftp_print_eplf_drive (char *dest, uint32_t destsize, char *name) {
|
||||
mod_struct_time tm;
|
||||
timeutils_struct_time_t tm;
|
||||
uint32_t tseconds;
|
||||
uint16_t mseconds;
|
||||
char *type = "d";
|
||||
|
||||
mod_time_seconds_since_2000_to_struct_time((FTP_UNIX_TIME_20150101 - FTP_UNIX_TIME_20000101), &tm);
|
||||
timeutils_seconds_since_2000_to_struct_time((FTP_UNIX_TIME_20150101 - FTP_UNIX_TIME_20000101), &tm);
|
||||
|
||||
MAP_PRCMRTCGet(&tseconds, &mseconds);
|
||||
tseconds = pyb_rtc_get_seconds();
|
||||
if (FTP_UNIX_SECONDS_180_DAYS < tseconds - (FTP_UNIX_TIME_20150101 - FTP_UNIX_TIME_20000101)) {
|
||||
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %5u %s\r\n",
|
||||
type, 0, ftp_month[(tm.tm_mon - 1)].month, tm.tm_mday, tm.tm_year, name);
|
||||
@@ -966,61 +971,82 @@ static ftp_result_t ftp_write_file (char *filebuf, uint32_t size) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static ftp_result_t ftp_open_dir_for_listing (const char *path, char *list, uint32_t maxlistsize, uint32_t *listsize) {
|
||||
uint next = 0;
|
||||
// "hack" to list root directory
|
||||
static ftp_result_t ftp_open_dir_for_listing (const char *path) {
|
||||
// "hack" to detect the root directory
|
||||
if (path[0] == '/' && path[1] == '\0') {
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "SFLASH");
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
if (sd_disk_ready()) {
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "SD");
|
||||
ftp_data.listroot = true;
|
||||
} else {
|
||||
FRESULT res;
|
||||
res = f_opendir(&ftp_data.dp, path); /* Open the directory */
|
||||
if (res != FR_OK) {
|
||||
return E_FTP_RESULT_FAILED;
|
||||
}
|
||||
#endif
|
||||
*listsize = next;
|
||||
return E_FTP_RESULT_OK;
|
||||
ftp_data.e_open = E_FTP_DIR_OPEN;
|
||||
ftp_data.listroot = false;
|
||||
}
|
||||
|
||||
FRESULT res;
|
||||
res = f_opendir(&ftp_data.dp, path); /* Open the directory */
|
||||
if (res != FR_OK) {
|
||||
return E_FTP_RESULT_FAILED;
|
||||
}
|
||||
ftp_data.e_open = E_FTP_DIR_OPEN;
|
||||
return E_FTP_RESULT_CONTINUE;
|
||||
}
|
||||
|
||||
static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *listsize) {
|
||||
uint next = 0;
|
||||
uint count = 0;
|
||||
uint listcount = 0;
|
||||
FRESULT res;
|
||||
FILINFO fno;
|
||||
ftp_result_t result = E_FTP_RESULT_CONTINUE;
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
fno.lfname = mem_Malloc(_MAX_LFN);
|
||||
fno.lfsize = _MAX_LFN;
|
||||
|
||||
/* read up to 4 directory items */
|
||||
while (count++ < 4) {
|
||||
res = f_readdir(&ftp_data.dp, &fno); /* Read a directory item */
|
||||
if (res != FR_OK || fno.fname[0] == 0) {
|
||||
result = E_FTP_RESULT_OK;
|
||||
break; /* Break on error or end of dp */
|
||||
// read up to 2 directory items
|
||||
while (listcount < 2) {
|
||||
#else
|
||||
// read up to 4 directory items
|
||||
while (listcount < 4) {
|
||||
#endif
|
||||
if (ftp_data.listroot) {
|
||||
// root directory "hack"
|
||||
if (0 == ftp_data.volcount) {
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "flash");
|
||||
} else if (ftp_data.volcount <= MP_STATE_PORT(mount_obj_list).len) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[(ftp_data.volcount - 1)]));
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), (char *)&mount_obj->path[1]);
|
||||
} else {
|
||||
if (!next) {
|
||||
// no volume found this time, we are done
|
||||
ftp_data.volcount = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ftp_data.volcount++;
|
||||
} else {
|
||||
// a "normal" directory
|
||||
res = f_readdir(&ftp_data.dp, &fno); /* Read a directory item */
|
||||
if (res != FR_OK || fno.fname[0] == 0) {
|
||||
result = E_FTP_RESULT_OK;
|
||||
break; /* Break on error or end of dp */
|
||||
}
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
|
||||
|
||||
// add the entry to the list
|
||||
next += ftp_print_eplf_item((list + next), (maxlistsize - next), &fno);
|
||||
}
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
|
||||
|
||||
// Add the entry to the list
|
||||
next += ftp_print_eplf_item((list + next), (maxlistsize - next), &fno);
|
||||
listcount++;
|
||||
}
|
||||
if (result == E_FTP_RESULT_OK) {
|
||||
ftp_close_files();
|
||||
}
|
||||
*listsize = next;
|
||||
#if _USE_LFN
|
||||
mem_Free(fno.lfname);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
static void ftp_open_child (char *pwd, char *dir) {
|
||||
if (dir[0] == '/') {
|
||||
strcpy (pwd, dir);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (strlen(pwd) > 1) {
|
||||
strcat (pwd, "/");
|
||||
}
|
||||
@@ -1040,8 +1066,7 @@ static void ftp_close_child (char *pwd) {
|
||||
}
|
||||
if (len == 0) {
|
||||
strcpy (pwd, "/");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
pwd[len] = '\0';
|
||||
}
|
||||
}
|
||||
@@ -1054,9 +1079,9 @@ static void ftp_return_to_previous_path (char *pwd, char *dir) {
|
||||
else {
|
||||
if (newlen == 0) {
|
||||
strcpy (pwd, "/");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
pwd[newlen] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,4 +34,6 @@ extern void ftp_init (void);
|
||||
extern void ftp_run (void);
|
||||
extern void ftp_enable (void);
|
||||
extern void ftp_disable (void);
|
||||
extern void ftp_reset (void);
|
||||
|
||||
#endif /* FTP_H_ */
|
||||
|
||||
@@ -1,22 +1,53 @@
|
||||
/*
|
||||
* 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 <stdbool.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/obj.h"
|
||||
#include "simplelink.h"
|
||||
#include "flc.h"
|
||||
#include "updater.h"
|
||||
#include "shamd5.h"
|
||||
#include "modnetwork.h"
|
||||
#include "modwlan.h"
|
||||
#include "debug.h"
|
||||
#include "osi.h"
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define UPDATER_IMG_PATH "/SFLASH/SYS/MCUIMG.BIN"
|
||||
#define UPDATER_SRVPACK_PATH "/SFLASH/SYS/SRVPCK.UCF"
|
||||
#define UPDATER_SIGN_PATH "/SFLASH/SYS/SRVPCK.SIG"
|
||||
#define UPDATER_IMG_PATH "/flash/sys/mcuimg.bin"
|
||||
#define UPDATER_SRVPACK_PATH "/flash/sys/servicepack.ucf"
|
||||
#define UPDATER_SIGN_PATH "/flash/sys/servicepack.sig"
|
||||
#define UPDATER_CA_PATH "/flash/cert/ca.pem"
|
||||
#define UPDATER_CERT_PATH "/flash/cert/cert.pem"
|
||||
#define UPDATER_KEY_PATH "/flash/cert/private.key"
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
@@ -31,91 +62,142 @@ typedef struct {
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
static updater_data_t updater_data;
|
||||
static updater_data_t updater_data = { .path = NULL, .fhandle = -1, .fsize = 0, .foffset = 0 };
|
||||
static OsiLockObj_t updater_LockObj;
|
||||
static sBootInfo_t sBootInfo;
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
__attribute__ ((section (".boot")))
|
||||
void updater_pre_init (void) {
|
||||
// create the updater lock
|
||||
ASSERT(OSI_OK == sl_LockObjCreate(&updater_LockObj, "UpdaterLock"));
|
||||
}
|
||||
|
||||
bool updater_check_path (void *path) {
|
||||
// conert the path supplied to upper case
|
||||
stoupper (path);
|
||||
sl_LockObjLock (&updater_LockObj, SL_OS_WAIT_FOREVER);
|
||||
if (!strcmp(UPDATER_IMG_PATH, path)) {
|
||||
updater_data.path = IMG_UPDATE;
|
||||
updater_data.fsize = IMG_SIZE;
|
||||
return true;
|
||||
}
|
||||
else if (!strcmp(UPDATER_SRVPACK_PATH, path)) {
|
||||
updater_data.path = IMG_UPDATE1;
|
||||
// the launchxl doesn't have enough flash space for 2 user update images
|
||||
#ifdef WIPY
|
||||
// check which one should be the next active image
|
||||
_i32 fhandle;
|
||||
if (!sl_FsOpen((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_READ, NULL, &fhandle)) {
|
||||
ASSERT (sizeof(sBootInfo_t) == sl_FsRead(fhandle, 0, (unsigned char *)&sBootInfo, sizeof(sBootInfo_t)));
|
||||
sl_FsClose(fhandle, 0, 0, 0);
|
||||
// if we still have an image pending for verification, keep overwriting it
|
||||
if ((sBootInfo.Status == IMG_STATUS_CHECK && sBootInfo.ActiveImg == IMG_ACT_UPDATE2) ||
|
||||
(sBootInfo.ActiveImg == IMG_ACT_UPDATE1 && sBootInfo.Status != IMG_STATUS_CHECK)) {
|
||||
updater_data.path = IMG_UPDATE2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else if (!strcmp(UPDATER_SRVPACK_PATH, path)) {
|
||||
updater_data.path = IMG_SRVPACK;
|
||||
updater_data.fsize = SRVPACK_SIZE;
|
||||
return true;
|
||||
}
|
||||
else if (!strcmp(UPDATER_SIGN_PATH, path)) {
|
||||
} else if (!strcmp(UPDATER_SIGN_PATH, path)) {
|
||||
updater_data.path = SRVPACK_SIGN;
|
||||
updater_data.fsize = SIGN_SIZE;
|
||||
return true;
|
||||
} else if (!strcmp(UPDATER_CA_PATH, path)) {
|
||||
updater_data.path = CA_FILE;
|
||||
updater_data.fsize = CA_KEY_SIZE;
|
||||
} else if (!strcmp(UPDATER_CERT_PATH, path)) {
|
||||
updater_data.path = CERT_FILE;
|
||||
updater_data.fsize = CA_KEY_SIZE;
|
||||
} else if (!strcmp(UPDATER_KEY_PATH, path)) {
|
||||
updater_data.path = KEY_FILE;
|
||||
updater_data.fsize = CA_KEY_SIZE;
|
||||
} else {
|
||||
sl_LockObjUnlock (&updater_LockObj);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool updater_start (void) {
|
||||
_u32 AccessModeAndMaxSize = FS_MODE_OPEN_WRITE;
|
||||
SlFsFileInfo_t FsFileInfo;
|
||||
#ifdef USE_FREERTOS
|
||||
xSemaphoreTake (xWlanSemaphore, portMAX_DELAY);
|
||||
#endif
|
||||
bool result = false;
|
||||
|
||||
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);
|
||||
}
|
||||
if (!sl_FsOpen((_u8 *)updater_data.path, AccessModeAndMaxSize, NULL, &updater_data.fhandle)) {
|
||||
updater_data.foffset = 0;
|
||||
return true;
|
||||
result = true;
|
||||
}
|
||||
#ifdef USE_FREERTOS
|
||||
xSemaphoreGive (xWlanSemaphore);
|
||||
#endif
|
||||
return false;
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool updater_write (uint8_t *buf, uint32_t len) {
|
||||
bool result = false;
|
||||
|
||||
sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
|
||||
if (len == sl_FsWrite(updater_data.fhandle, updater_data.foffset, buf, len)) {
|
||||
updater_data.foffset += len;
|
||||
return true;
|
||||
result = true;
|
||||
}
|
||||
return false;
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void updater_finnish (void) {
|
||||
sBootInfo_t sBootInfo;
|
||||
_i32 fhandle;
|
||||
|
||||
if (updater_data.fhandle > 0) {
|
||||
sl_LockObjLock (&wlan_LockObj, SL_OS_WAIT_FOREVER);
|
||||
// close the file being updated
|
||||
sl_FsClose(updater_data.fhandle, NULL, NULL, 0);
|
||||
|
||||
if (!strcmp (IMG_UPDATE, updater_data.path)) {
|
||||
// open the boot info file for reading
|
||||
#ifdef WIPY
|
||||
// if we still have an image pending for verification, leave the boot info as it is
|
||||
if (!strncmp(IMG_PREFIX, updater_data.path, strlen(IMG_PREFIX)) && sBootInfo.Status != IMG_STATUS_CHECK) {
|
||||
#else
|
||||
if (!strncmp(IMG_PREFIX, updater_data.path, strlen(IMG_PREFIX))) {
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
if (!sl_FsOpen((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_READ, NULL, &fhandle)) {
|
||||
|
||||
ASSERT (sizeof(sBootInfo_t) == sl_FsRead(fhandle, 0, (unsigned char *)&sBootInfo, sizeof(sBootInfo_t)));
|
||||
sl_FsClose(fhandle, 0, 0, 0);
|
||||
// open the file for writing
|
||||
#endif
|
||||
// open the boot info file for writing
|
||||
ASSERT (sl_FsOpen((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_WRITE, NULL, &fhandle) == 0);
|
||||
#ifdef DEBUG
|
||||
}
|
||||
else {
|
||||
// the boot info file doesn't exist yet
|
||||
_u32 BootInfoCreateFlag = _FS_FILE_OPEN_FLAG_COMMIT | _FS_FILE_PUBLIC_WRITE | _FS_FILE_PUBLIC_READ;
|
||||
ASSERT (sl_FsOpen ((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_CREATE((2 * sizeof(sBootInfo_t)),
|
||||
BootInfoCreateFlag), NULL, &fhandle) == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// write the new boot info
|
||||
sBootInfo.ActiveImg = IMG_ACT_UPDATE;
|
||||
// save the new boot info
|
||||
#ifdef WIPY
|
||||
sBootInfo.PrevImg = sBootInfo.ActiveImg;
|
||||
if (sBootInfo.ActiveImg == IMG_ACT_UPDATE1) {
|
||||
sBootInfo.ActiveImg = IMG_ACT_UPDATE2;
|
||||
} else {
|
||||
sBootInfo.ActiveImg = IMG_ACT_UPDATE1;
|
||||
}
|
||||
// the launchxl doesn't have enough flash space for 2 user updates
|
||||
#else
|
||||
sBootInfo.PrevImg = IMG_ACT_FACTORY;
|
||||
sBootInfo.ActiveImg = IMG_ACT_UPDATE1;
|
||||
#endif
|
||||
sBootInfo.Status = IMG_STATUS_CHECK;
|
||||
ASSERT (sizeof(sBootInfo_t) == sl_FsWrite(fhandle, 0, (unsigned char *)&sBootInfo, sizeof(sBootInfo_t)));
|
||||
sl_FsClose(fhandle, 0, 0, 0);
|
||||
}
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
updater_data.fhandle = -1;
|
||||
}
|
||||
updater_data.fhandle = -1;
|
||||
#ifdef USE_FREERTOS
|
||||
xSemaphoreGive (xWlanSemaphore);
|
||||
#endif
|
||||
sl_LockObjUnlock (&updater_LockObj);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,38 @@
|
||||
/*
|
||||
* 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 UPDATER_H_
|
||||
#define UPDATER_H_
|
||||
|
||||
bool updater_check_path (void *path);
|
||||
bool updater_start (void);
|
||||
bool updater_write (uint8_t *buf, uint32_t len);
|
||||
void updater_finnish (void);
|
||||
bool updater_verify (uint8_t *rbuff, uint8_t *hasbuff);
|
||||
extern void updater_pre_init (void);
|
||||
extern bool updater_check_path (void *path);
|
||||
extern bool updater_start (void);
|
||||
extern bool updater_write (uint8_t *buf, uint32_t len);
|
||||
extern void updater_finnish (void);
|
||||
extern bool updater_verify (uint8_t *rbuff, uint8_t *hasbuff);
|
||||
|
||||
#endif /* UPDATER_H_ */
|
||||
|
||||
@@ -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,28 @@
|
||||
******************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/runtime.h"
|
||||
#include "py/objstr.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_nvic.h"
|
||||
#include "hw_memmap.h"
|
||||
#include "mpconfig.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"
|
||||
#include "utils.h"
|
||||
#include "irq.h"
|
||||
#include "moduos.h"
|
||||
|
||||
#ifdef USE_FREERTOS
|
||||
#include "FreeRTOS.h"
|
||||
@@ -51,23 +60,15 @@
|
||||
#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;
|
||||
|
||||
@@ -79,13 +80,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 +95,6 @@ void HAL_SystemInit (void) {
|
||||
#ifndef USE_FREERTOS
|
||||
hal_TickInit();
|
||||
#endif
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
hal_EnableSdCard();
|
||||
#endif
|
||||
}
|
||||
|
||||
void HAL_SystemDeInit (void) {
|
||||
@@ -110,22 +109,94 @@ uint32_t HAL_GetTick(void) {
|
||||
}
|
||||
|
||||
void HAL_Delay(uint32_t delay) {
|
||||
#ifdef USE_FREERTOS
|
||||
vTaskDelay (delay / portTICK_PERIOD_MS);
|
||||
#else
|
||||
uint32_t start = HAL_tickCount;
|
||||
// Wraparound of tick is taken care of by 2's complement arithmetic.
|
||||
while (HAL_tickCount - start < delay) {
|
||||
// Enter sleep mode, waiting for (at least) the SysTick interrupt.
|
||||
__WFI();
|
||||
// only if we are not within interrupt context and interrupts are enabled
|
||||
if ((HAL_NVIC_INT_CTRL_REG & HAL_VECTACTIVE_MASK) == 0 && query_irq() == IRQ_STATE_ENABLED) {
|
||||
#ifdef USE_FREERTOS
|
||||
vTaskDelay (delay / portTICK_PERIOD_MS);
|
||||
#else
|
||||
uint32_t start = HAL_tickCount;
|
||||
// wraparound of tick is taken care of by 2's complement arithmetic.
|
||||
while (HAL_tickCount - start < delay) {
|
||||
// enter sleep mode, waiting for (at least) the SysTick interrupt.
|
||||
__WFI();
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
for (int ms = 0; ms < delay; ms++) {
|
||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT(1000));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NORETURN void mp_hal_raise(int errno) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, mp_obj_new_int(errno)));
|
||||
}
|
||||
|
||||
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) {
|
||||
if (MP_STATE_PORT(os_term_dup_obj)) {
|
||||
if (MP_OBJ_IS_TYPE(MP_STATE_PORT(os_term_dup_obj)->stream_o, &pyb_uart_type)) {
|
||||
uart_tx_strn(MP_STATE_PORT(os_term_dup_obj)->stream_o, str, len);
|
||||
} else {
|
||||
MP_STATE_PORT(os_term_dup_obj)->write[2] = mp_obj_new_str_of_type(&mp_type_str, (const byte *)str, len);
|
||||
mp_call_method_n_kw(1, 0, MP_STATE_PORT(os_term_dup_obj)->write);
|
||||
}
|
||||
}
|
||||
// and also to telnet
|
||||
telnet_tx_strn(str, len);
|
||||
}
|
||||
|
||||
void mp_hal_stdout_tx_strn_cooked (const char *str, uint32_t len) {
|
||||
int32_t nslen = 0;
|
||||
const char *_str = str;
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (str[i] == '\n') {
|
||||
mp_hal_stdout_tx_strn(_str, nslen);
|
||||
mp_hal_stdout_tx_strn("\r\n", 2);
|
||||
_str += nslen + 1;
|
||||
nslen = 0;
|
||||
} else {
|
||||
nslen++;
|
||||
}
|
||||
}
|
||||
if (_str < str + len) {
|
||||
mp_hal_stdout_tx_strn(_str, nslen);
|
||||
}
|
||||
}
|
||||
|
||||
int mp_hal_stdin_rx_chr(void) {
|
||||
for ( ;; ) {
|
||||
// read telnet first
|
||||
if (telnet_rx_any()) {
|
||||
return telnet_rx_char();
|
||||
} else if (MP_STATE_PORT(os_term_dup_obj)) { // then the stdio_dup
|
||||
if (MP_OBJ_IS_TYPE(MP_STATE_PORT(os_term_dup_obj)->stream_o, &pyb_uart_type)) {
|
||||
if (uart_rx_any(MP_STATE_PORT(os_term_dup_obj)->stream_o)) {
|
||||
return uart_rx_char(MP_STATE_PORT(os_term_dup_obj)->stream_o);
|
||||
}
|
||||
} else {
|
||||
MP_STATE_PORT(os_term_dup_obj)->read[2] = mp_obj_new_int(1);
|
||||
mp_obj_t data = mp_call_method_n_kw(1, 0, MP_STATE_PORT(os_term_dup_obj)->read);
|
||||
// data len is > 0
|
||||
if (mp_obj_is_true(data)) {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
|
||||
return ((int *)(bufinfo.buf))[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
HAL_Delay(1);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
@@ -143,23 +214,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
|
||||
|
||||
@@ -37,7 +37,10 @@
|
||||
#define HAL_FCPU_MHZ 80U
|
||||
#define HAL_FCPU_HZ (1000000U * HAL_FCPU_MHZ)
|
||||
#define HAL_SYSTICK_PERIOD_US 1000U
|
||||
#define UTILS_DELAY_US_TO_COUNT(us) (((us) * HAL_FCPU_MHZ) / 3)
|
||||
#define UTILS_DELAY_US_TO_COUNT(us) (((us) * HAL_FCPU_MHZ) / 6)
|
||||
|
||||
#define HAL_NVIC_INT_CTRL_REG (*((volatile uint32_t *) 0xE000ED04 ) )
|
||||
#define HAL_VECTACTIVE_MASK (0x1FUL)
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
@@ -61,6 +64,12 @@ extern void HAL_SystemDeInit (void);
|
||||
extern void HAL_IncrementTick(void);
|
||||
extern uint32_t HAL_GetTick(void);
|
||||
extern void HAL_Delay(uint32_t delay);
|
||||
extern NORETURN void mp_hal_raise(int errno);
|
||||
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__
|
||||
|
||||
|
||||
@@ -49,15 +49,6 @@
|
||||
#include "inc/hw_ocp_shared.h"
|
||||
#include "pin.h"
|
||||
|
||||
//*****************************************************************************
|
||||
// Macros
|
||||
//*****************************************************************************
|
||||
#define PAD_MODE_MASK 0x0000000F
|
||||
#define PAD_STRENGTH_MASK 0x000000E0
|
||||
#define PAD_TYPE_MASK 0x00000310
|
||||
#define PAD_CONFIG_BASE ((OCP_SHARED_BASE + \
|
||||
OCP_SHARED_O_GPIO_PAD_CONFIG_0))
|
||||
|
||||
//*****************************************************************************
|
||||
// PIN to PAD matrix
|
||||
//*****************************************************************************
|
||||
@@ -334,7 +325,7 @@ void PinConfigSet(unsigned long ulPin,unsigned long ulPinStrength,
|
||||
//
|
||||
// Isolate the output
|
||||
//
|
||||
HWREG(ulPad) |= 0xC00;
|
||||
HWREG(ulPad) = 0xC00;
|
||||
|
||||
}
|
||||
else
|
||||
|
||||
@@ -143,6 +143,13 @@ extern "C"
|
||||
#define PIN_TYPE_OD_PD 0x00000210
|
||||
#define PIN_TYPE_ANALOG 0x10000000
|
||||
|
||||
//*****************************************************************************
|
||||
// Macros for mode and type
|
||||
//*****************************************************************************
|
||||
#define PAD_MODE_MASK 0x0000000F
|
||||
#define PAD_STRENGTH_MASK 0x000000E0
|
||||
#define PAD_TYPE_MASK 0x00000310
|
||||
#define PAD_CONFIG_BASE ((OCP_SHARED_BASE + OCP_SHARED_O_GPIO_PAD_CONFIG_0))
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
|
||||
@@ -98,28 +98,43 @@
|
||||
#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() (RTCFastDomainCounterGet() >> 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.
|
||||
// bit: 28 is used to indicate that the board is booting for the first time after being programmed in factory.
|
||||
// Bits: 27 and 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
|
||||
// Bits: 15 to 0 are being used for HW Changes / ECO.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
@@ -128,13 +143,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 +167,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 +197,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 +205,40 @@ 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);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// Fast function to get the most accurate RTC counter value
|
||||
//*****************************************************************************
|
||||
static unsigned long long RTCFastDomainCounterGet (void) {
|
||||
|
||||
#define BRK_IF_RTC_CTRS_ALIGN(c2, c1) if (c2 - c1 <= 1) { \
|
||||
itr++; \
|
||||
break; \
|
||||
}
|
||||
|
||||
unsigned long long rtc_count1, rtc_count2, rtc_count3;
|
||||
unsigned int itr;
|
||||
|
||||
do {
|
||||
rtc_count1 = PRCMSlowClkCtrFastGet();
|
||||
rtc_count2 = PRCMSlowClkCtrFastGet();
|
||||
rtc_count3 = PRCMSlowClkCtrFastGet();
|
||||
itr = 0;
|
||||
|
||||
BRK_IF_RTC_CTRS_ALIGN(rtc_count2, rtc_count1);
|
||||
BRK_IF_RTC_CTRS_ALIGN(rtc_count3, rtc_count2);
|
||||
BRK_IF_RTC_CTRS_ALIGN(rtc_count3, rtc_count1);
|
||||
|
||||
// Consistent values in two consecutive reads implies a correct
|
||||
// value of the counter. Do note, the counter does not give the
|
||||
// calendar time but a hardware that ticks upwards continuously.
|
||||
// The 48-bit counter operates at 32,768 HZ.
|
||||
|
||||
} while (true);
|
||||
|
||||
return (1 == itr) ? rtc_count2 : rtc_count3;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -200,9 +246,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 +286,53 @@ static const PRCM_PeriphRegs_t PRCM_PeriphRegsList[] =
|
||||
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Set a special bit
|
||||
//!
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void PRCMSetSpecialBit(unsigned char bit)
|
||||
{
|
||||
unsigned int uiRegValue;
|
||||
|
||||
uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) | (1 << bit);
|
||||
|
||||
PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Clear a special bit
|
||||
//!
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void PRCMClearSpecialBit(unsigned char bit)
|
||||
{
|
||||
unsigned int uiRegValue;
|
||||
|
||||
uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(1 << bit));
|
||||
|
||||
PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Read a special bit
|
||||
//!
|
||||
//! \return Value of the bit
|
||||
//
|
||||
//*****************************************************************************
|
||||
tBoolean PRCMGetSpecialBit(unsigned char bit)
|
||||
{
|
||||
tBoolean value = (MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (1 << bit)) ? true : false;
|
||||
// special bits must be cleared immediatelly after reading
|
||||
PRCMClearSpecialBit(bit);
|
||||
return value;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Performs a software reset of a SOC
|
||||
@@ -304,7 +398,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 +412,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 +443,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 +479,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 +501,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 +553,7 @@ PRCMPeripheralClockGet(unsigned long ulPeripheral)
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMPeripheralReset(unsigned long ulPeripheral)
|
||||
void PRCMPeripheralReset(unsigned long ulPeripheral)
|
||||
{
|
||||
volatile unsigned long ulDelay;
|
||||
|
||||
@@ -503,8 +593,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 +635,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 +665,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 +687,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 +714,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 +737,7 @@ PRCMLPDSEnter()
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMLPDSWakeupSourceEnable(unsigned long ulLpdsWakeupSrc)
|
||||
void PRCMLPDSWakeupSourceEnable(unsigned long ulLpdsWakeupSrc)
|
||||
{
|
||||
unsigned long ulRegVal;
|
||||
|
||||
@@ -678,8 +772,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 +788,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 +806,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 +850,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 +875,7 @@ PRCMLPDSWakeUpGPIOSelect(unsigned long ulGPIOPin, unsigned long ulType)
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMSleepEnter()
|
||||
void PRCMSleepEnter(void)
|
||||
{
|
||||
//
|
||||
// Request Sleep
|
||||
@@ -806,8 +895,7 @@ PRCMSleepEnter()
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
PRCMDeepSleepEnter()
|
||||
void PRCMDeepSleepEnter(void)
|
||||
{
|
||||
//
|
||||
// Set bandgap duty cycle to 1
|
||||
@@ -857,8 +945,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 +989,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 +1030,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 +1047,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 +1062,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 +1078,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 +1095,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 +1110,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 +1124,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 +1140,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 +1164,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 +1201,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 +1218,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 +1236,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,26 +1259,54 @@ 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;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Gets the current value of the internal slow clock counter
|
||||
//!
|
||||
//! This function is similar to \sa PRCMSlowClkCtrGet() but reads the counter
|
||||
//! value from a relatively faster interface using an auto-latch mechainsm.
|
||||
//!
|
||||
//! \note Due to the nature of implemetation of auto latching, when using this
|
||||
//! API, the recommendation is to read the value thrice and identify the right
|
||||
//! value (as 2 out the 3 read values will always be correct and with a max. of
|
||||
//! 1 LSB change)
|
||||
//!
|
||||
//! \return 64-bit current counter vlaue.
|
||||
//
|
||||
//*****************************************************************************
|
||||
unsigned long long PRCMSlowClkCtrFastGet(void)
|
||||
{
|
||||
unsigned long long ullRTCVal;
|
||||
|
||||
//
|
||||
// Read as 2 32-bit values
|
||||
//
|
||||
ullRTCVal = HWREG(HIB1P2_BASE + HIB1P2_O_HIB_RTC_TIMER_MSW_1P2);
|
||||
ullRTCVal = ullRTCVal << 32;
|
||||
ullRTCVal |= HWREG(HIB1P2_BASE + HIB1P2_O_HIB_RTC_TIMER_LSW_1P2);
|
||||
|
||||
return ullRTCVal;
|
||||
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
@@ -1217,9 +1325,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 +1341,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 +1373,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 +1393,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 +1434,7 @@ void PRCMIntRegister(void (*pfnHandler)(void))
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void PRCMIntUnregister()
|
||||
void PRCMIntUnregister(void)
|
||||
{
|
||||
//
|
||||
// Enable the UART interrupt.
|
||||
@@ -1368,9 +1476,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 +1512,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 +1528,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 +1545,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 +1584,7 @@ void PRCMRTCInUseSet()
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
tBoolean PRCMRTCInUseGet()
|
||||
tBoolean PRCMRTCInUseGet(void)
|
||||
{
|
||||
return IS_RTC_USED()? true : false;
|
||||
}
|
||||
@@ -1498,7 +1616,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 +1647,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 +1683,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 +1716,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 +1734,7 @@ void PRCMRTCMatchGet(unsigned long *ulSecs, unsigned short *usMsec)
|
||||
//! \return None
|
||||
//
|
||||
//*****************************************************************************
|
||||
void PRCMCC3200MCUInit()
|
||||
void PRCMCC3200MCUInit(void)
|
||||
{
|
||||
unsigned long ulRegValue;
|
||||
|
||||
@@ -1627,11 +1745,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 +1888,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
|
||||
|
||||
@@ -192,11 +192,21 @@ unsigned long ulRstReg;
|
||||
// PRCM_ADC should never be used in any user code.
|
||||
#define PRCM_ADC 0x000000FF
|
||||
|
||||
//*****************************************************************************
|
||||
// User bits in the PRCM persistent registers
|
||||
//*****************************************************************************
|
||||
#define PRCM_SAFE_BOOT_BIT 30
|
||||
#define PRCM_WDT_RESET_BIT 29
|
||||
#define PRCM_FIRST_BOOT_BIT 28
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// API Function prototypes
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void PRCMSetSpecialBit(unsigned char bit);
|
||||
extern void PRCMClearSpecialBit(unsigned char bit);
|
||||
extern tBoolean PRCMGetSpecialBit(unsigned char bit);
|
||||
extern void PRCMSOCReset(void);
|
||||
extern void PRCMMCUReset(tBoolean bIncludeSubsystem);
|
||||
extern unsigned long PRCMSysResetCauseGet(void);
|
||||
@@ -237,6 +247,7 @@ extern void PRCMHibernateWakeupSourceDisable(unsigned long ulHIBWakupSrc);
|
||||
extern void PRCMHibernateIntervalSet(unsigned long long ullTicks);
|
||||
|
||||
extern unsigned long long PRCMSlowClkCtrGet(void);
|
||||
extern unsigned long long PRCMSlowClkCtrFastGet(void);
|
||||
extern void PRCMSlowClkCtrMatchSet(unsigned long long ullTicks);
|
||||
extern unsigned long long PRCMSlowClkCtrMatchGet(void);
|
||||
|
||||
@@ -250,6 +261,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 +270,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,14 @@
|
||||
#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 "antenna.h"
|
||||
#include "mperror.h"
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE CONSTANTS
|
||||
@@ -61,11 +60,20 @@ OsiTaskHandle mpTaskHandle;
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
__attribute__ ((section (".boot")))
|
||||
int main (void) {
|
||||
|
||||
// Initialize the clocks and the interrupt system
|
||||
HAL_SystemInit();
|
||||
|
||||
#if MICROPY_HW_ANTENNA_DIVERSITY
|
||||
// configure the antenna selection pins
|
||||
antenna_init0();
|
||||
#endif
|
||||
|
||||
// Init the watchdog
|
||||
pybwdt_init0();
|
||||
|
||||
#ifdef DEBUG
|
||||
ASSERT (OSI_OK == osi_TaskCreate(TASK_Micropython,
|
||||
(const signed char *)"MicroPy",
|
||||
@@ -81,7 +89,6 @@ int main (void) {
|
||||
for ( ; ; );
|
||||
}
|
||||
|
||||
|
||||
void stoupper (char *str) {
|
||||
while (str && *str != '\0') {
|
||||
*str = (char)toupper((int)(*str));
|
||||
|
||||
@@ -28,19 +28,15 @@
|
||||
#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 "mperror.h"
|
||||
|
||||
|
||||
#ifdef USE_FREERTOS
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! \brief Application defined idle task hook
|
||||
@@ -50,10 +46,11 @@
|
||||
//! \return none
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void
|
||||
vApplicationIdleHook( void)
|
||||
void vApplicationIdleHook (void)
|
||||
{
|
||||
//Handle Idle Hook for Profiling, Power Management etc
|
||||
// signal that we are alive and kicking
|
||||
mperror_heartbeat_signal();
|
||||
// gate the processor's clock to save power
|
||||
__WFI();
|
||||
}
|
||||
|
||||
@@ -66,19 +63,14 @@ 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)
|
||||
{
|
||||
}
|
||||
__fatal_error("FreeRTOS malloc failed!");
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -90,19 +82,14 @@ 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)
|
||||
{
|
||||
}
|
||||
__fatal_error("Stack overflow!");
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -114,9 +101,7 @@ void vApplicationStackOverflowHook( OsiTaskHandle *pxTask, signed char *pcTaskNa
|
||||
//! \return none
|
||||
//!
|
||||
//*****************************************************************************
|
||||
void vApplicationTickHook( void )
|
||||
void vApplicationTickHook (void)
|
||||
{
|
||||
HAL_IncrementTick();
|
||||
}
|
||||
|
||||
#endif //USE_FREERTOS
|
||||
|
||||
97
cc3200/misc/antenna.c
Normal file
97
cc3200/misc/antenna.c
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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 "mpconfigboard.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 "antenna.h"
|
||||
|
||||
|
||||
#if MICROPY_HW_ANTENNA_DIVERSITY
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define REG_PAD_CONFIG_26 (0x4402E108)
|
||||
#define REG_PAD_CONFIG_27 (0x4402E10C)
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
static antenna_type_t antenna_type_selected = ANTENNA_TYPE_INTERNAL;
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
void antenna_init0(void) {
|
||||
// enable the peripheral clock and set the gpio direction for
|
||||
// both antenna 1 and antenna 2 pins
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_GPIOA3, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
MAP_GPIODirModeSet(GPIOA3_BASE, 0x0C, GPIO_DIR_MODE_OUT);
|
||||
|
||||
// configure antenna 1 pin type and strength
|
||||
HWREG(REG_PAD_CONFIG_26) = ((HWREG(REG_PAD_CONFIG_26) & ~(PAD_STRENGTH_MASK | PAD_TYPE_MASK)) | (0x00000020 | 0x00000000));
|
||||
// set the mode
|
||||
HWREG(REG_PAD_CONFIG_26) = ((HWREG(REG_PAD_CONFIG_26) & ~PAD_MODE_MASK) | 0x00000000) & ~(3 << 10);
|
||||
// set the direction
|
||||
HWREG(REG_PAD_CONFIG_26) = ((HWREG(REG_PAD_CONFIG_26) & ~0xC00) | 0x00000800);
|
||||
|
||||
// configure antenna 2 pin type and strength
|
||||
HWREG(REG_PAD_CONFIG_27) = ((HWREG(REG_PAD_CONFIG_27) & ~(PAD_STRENGTH_MASK | PAD_TYPE_MASK)) | (0x00000020 | 0x00000000));
|
||||
// set the mode
|
||||
HWREG(REG_PAD_CONFIG_27) = ((HWREG(REG_PAD_CONFIG_27) & ~PAD_MODE_MASK) | 0x00000000) & ~(3 << 10);
|
||||
// set the direction
|
||||
HWREG(REG_PAD_CONFIG_27) = ((HWREG(REG_PAD_CONFIG_27) & ~0xC00) | 0x00000800);
|
||||
|
||||
// select the currently active antenna
|
||||
antenna_select(antenna_type_selected);
|
||||
}
|
||||
|
||||
void antenna_select (antenna_type_t _antenna) {
|
||||
if (_antenna == ANTENNA_TYPE_INTERNAL) {
|
||||
MAP_GPIOPinWrite(GPIOA3_BASE, 0x0C, 0x04);
|
||||
// also configure the pull-up and pull-down accordingly
|
||||
HWREG(REG_PAD_CONFIG_26) = ((HWREG(REG_PAD_CONFIG_26) & ~PAD_TYPE_MASK)) | PIN_TYPE_STD_PU;
|
||||
HWREG(REG_PAD_CONFIG_27) = ((HWREG(REG_PAD_CONFIG_27) & ~PAD_TYPE_MASK)) | PIN_TYPE_STD_PD;
|
||||
} else {
|
||||
MAP_GPIOPinWrite(GPIOA3_BASE, 0x0C, 0x08);
|
||||
// also configure the pull-up and pull-down accordingly
|
||||
HWREG(REG_PAD_CONFIG_26) = ((HWREG(REG_PAD_CONFIG_26) & ~PAD_TYPE_MASK)) | PIN_TYPE_STD_PD;
|
||||
HWREG(REG_PAD_CONFIG_27) = ((HWREG(REG_PAD_CONFIG_27) & ~PAD_TYPE_MASK)) | PIN_TYPE_STD_PU;
|
||||
}
|
||||
antenna_type_selected = _antenna;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
38
cc3200/misc/antenna.h
Normal file
38
cc3200/misc/antenna.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 _ANTENNA_H_
|
||||
#define _ANTENNA_H_
|
||||
|
||||
typedef enum {
|
||||
ANTENNA_TYPE_INTERNAL = 0,
|
||||
ANTENNA_TYPE_EXTERNAL
|
||||
} antenna_type_t;
|
||||
|
||||
extern void antenna_init0 (void);
|
||||
extern void antenna_select (antenna_type_t antenna_type);
|
||||
|
||||
#endif /* _ANTENNA_H_ */
|
||||
@@ -27,13 +27,10 @@
|
||||
|
||||
#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"
|
||||
STATIC const char help_text[] = "Welcome to MicroPython!\n"
|
||||
"For online help please visit http://micropython.org/help/.\n"
|
||||
"For further help on a specific object, type help(obj)\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);
|
||||
|
||||
@@ -25,30 +25,157 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <std.h>
|
||||
#include <stdio.h>
|
||||
#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 "py/runtime.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 (50)
|
||||
#define MPERROR_SIGNAL_ERROR_MS (1200)
|
||||
#define MPERROR_HEARTBEAT_ON_MS (80)
|
||||
#define MPERROR_HEARTBEAT_OFF_MS (3920)
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
#ifndef BOOTLOADER
|
||||
STATIC const mp_obj_base_t pyb_heartbeat_obj = {&pyb_heartbeat_type};
|
||||
#endif
|
||||
|
||||
struct mperror_heart_beat {
|
||||
uint32_t off_time;
|
||||
uint32_t on_time;
|
||||
bool beating;
|
||||
bool enabled;
|
||||
bool do_disable;
|
||||
} mperror_heart_beat = {.off_time = 0, .on_time = 0, .beating = false, .enabled = false, .do_disable = 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, 0, PIN_STRENGTH_6MA);
|
||||
#endif
|
||||
mperror_heart_beat.enabled = true;
|
||||
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
|
||||
PRCMSetSpecialBit(PRCM_WDT_RESET_BIT);
|
||||
|
||||
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_heartbeat_switch_off (void) {
|
||||
if (mperror_heart_beat.enabled) {
|
||||
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_heartbeat_signal (void) {
|
||||
if (mperror_heart_beat.do_disable) {
|
||||
mperror_heart_beat.do_disable = false;
|
||||
} else 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 +195,17 @@ void nlr_jump_fail(void *val) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void mperror_enable_heartbeat (bool enable) {
|
||||
if (enable) {
|
||||
mperror_heart_beat.enabled = true;
|
||||
mperror_heart_beat.do_disable = false;
|
||||
mperror_heartbeat_switch_off();
|
||||
} else {
|
||||
mperror_heart_beat.do_disable = true;
|
||||
mperror_heart_beat.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool mperror_is_heartbeat_enabled (void) {
|
||||
return mperror_heart_beat.enabled;
|
||||
}
|
||||
|
||||
@@ -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_type_t pyb_heartbeat_type;
|
||||
#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_heartbeat_switch_off (void);
|
||||
void mperror_heartbeat_signal (void);
|
||||
void mperror_enable_heartbeat (bool enable);
|
||||
bool mperror_is_heartbeat_enabled (void);
|
||||
|
||||
#endif // MPERROR_H_
|
||||
|
||||
@@ -27,14 +27,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#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"
|
||||
|
||||
|
||||
|
||||
202
cc3200/misc/mpirq.c
Normal file
202
cc3200/misc/mpirq.c
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* 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 "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 "mpexception.h"
|
||||
#include "mperror.h"
|
||||
#include "mpirq.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC DATA
|
||||
******************************************************************************/
|
||||
const mp_arg_t mp_irq_init_args[] = {
|
||||
{ MP_QSTR_trigger, 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} }, // the lowest priority
|
||||
{ MP_QSTR_handler, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_wake, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC uint8_t mp_irq_priorities[] = { INT_PRIORITY_LVL_7, INT_PRIORITY_LVL_6, INT_PRIORITY_LVL_5, INT_PRIORITY_LVL_4,
|
||||
INT_PRIORITY_LVL_3, INT_PRIORITY_LVL_2, INT_PRIORITY_LVL_1 };
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
void mp_irq_init0 (void) {
|
||||
// initialize the callback objects list
|
||||
mp_obj_list_init(&MP_STATE_PORT(mp_irq_obj_list), 0);
|
||||
}
|
||||
|
||||
mp_obj_t mp_irq_new (mp_obj_t parent, mp_obj_t handler, const mp_irq_methods_t *methods) {
|
||||
mp_irq_obj_t *self = m_new_obj(mp_irq_obj_t);
|
||||
self->base.type = &mp_irq_type;
|
||||
self->handler = handler;
|
||||
self->parent = parent;
|
||||
self->methods = (mp_irq_methods_t *)methods;
|
||||
self->isenabled = true;
|
||||
// remove it in case it was already registered
|
||||
mp_irq_remove(parent);
|
||||
mp_obj_list_append(&MP_STATE_PORT(mp_irq_obj_list), self);
|
||||
return self;
|
||||
}
|
||||
|
||||
mp_irq_obj_t *mp_irq_find (mp_obj_t parent) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mp_irq_obj_list).len; i++) {
|
||||
mp_irq_obj_t *callback_obj = ((mp_irq_obj_t *)(MP_STATE_PORT(mp_irq_obj_list).items[i]));
|
||||
if (callback_obj->parent == parent) {
|
||||
return callback_obj;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void mp_irq_wake_all (void) {
|
||||
// re-enable all active callback objects one by one
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mp_irq_obj_list).len; i++) {
|
||||
mp_irq_obj_t *callback_obj = ((mp_irq_obj_t *)(MP_STATE_PORT(mp_irq_obj_list).items[i]));
|
||||
if (callback_obj->isenabled) {
|
||||
callback_obj->methods->enable(callback_obj->parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mp_irq_disable_all (void) {
|
||||
// re-enable all active callback objects one by one
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mp_irq_obj_list).len; i++) {
|
||||
mp_irq_obj_t *callback_obj = ((mp_irq_obj_t *)(MP_STATE_PORT(mp_irq_obj_list).items[i]));
|
||||
callback_obj->methods->disable(callback_obj->parent);
|
||||
}
|
||||
}
|
||||
|
||||
void mp_irq_remove (const mp_obj_t parent) {
|
||||
mp_irq_obj_t *callback_obj;
|
||||
if ((callback_obj = mp_irq_find(parent))) {
|
||||
mp_obj_list_remove(&MP_STATE_PORT(mp_irq_obj_list), callback_obj);
|
||||
}
|
||||
}
|
||||
|
||||
uint mp_irq_translate_priority (uint priority) {
|
||||
if (priority < 1 || priority > MP_ARRAY_SIZE(mp_irq_priorities)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
return mp_irq_priorities[priority - 1];
|
||||
}
|
||||
|
||||
void mp_irq_handler (mp_obj_t self_in) {
|
||||
mp_irq_obj_t *self = self_in;
|
||||
if (self && self->handler != mp_const_none) {
|
||||
// when executing code within a handler we must lock the GC to prevent
|
||||
// any memory allocations.
|
||||
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;
|
||||
// signal the error using the heart beat led and
|
||||
// by printing a message
|
||||
printf("Uncaught exception in callback handler\n");
|
||||
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
|
||||
mperror_signal_error();
|
||||
}
|
||||
gc_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
STATIC mp_obj_t mp_irq_init (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
mp_irq_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(mp_irq_init_obj, 1, mp_irq_init);
|
||||
|
||||
STATIC mp_obj_t mp_irq_enable (mp_obj_t self_in) {
|
||||
mp_irq_obj_t *self = self_in;
|
||||
self->methods->enable(self->parent);
|
||||
self->isenabled = true;
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_irq_enable_obj, mp_irq_enable);
|
||||
|
||||
STATIC mp_obj_t mp_irq_disable (mp_obj_t self_in) {
|
||||
mp_irq_obj_t *self = self_in;
|
||||
self->methods->disable(self->parent);
|
||||
self->isenabled = false;
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_irq_disable_obj, mp_irq_disable);
|
||||
|
||||
STATIC mp_obj_t mp_irq_flags (mp_obj_t self_in) {
|
||||
mp_irq_obj_t *self = self_in;
|
||||
return mp_obj_new_int(self->methods->flags(self->parent));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_irq_flags_obj, mp_irq_flags);
|
||||
|
||||
STATIC mp_obj_t mp_irq_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);
|
||||
mp_irq_handler (self_in);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
STATIC const mp_map_elem_t mp_irq_locals_dict_table[] = {
|
||||
// instance methods
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&mp_irq_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&mp_irq_enable_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable), (mp_obj_t)&mp_irq_disable_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_flags), (mp_obj_t)&mp_irq_flags_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_irq_locals_dict, mp_irq_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t mp_irq_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_irq,
|
||||
.call = mp_irq_call,
|
||||
.locals_dict = (mp_obj_t)&mp_irq_locals_dict,
|
||||
};
|
||||
|
||||
75
cc3200/misc/mpirq.h
Normal file
75
cc3200/misc/mpirq.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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 MPIRQ_H_
|
||||
#define MPIRQ_H_
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define mp_irq_INIT_NUM_ARGS 4
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
******************************************************************************/
|
||||
typedef mp_obj_t (*mp_irq_init_t) (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
||||
typedef void (*mp_irq_void_method_t) (mp_obj_t self);
|
||||
typedef int (*mp_irq_int_method_t) (mp_obj_t self);
|
||||
|
||||
typedef struct {
|
||||
mp_irq_init_t init;
|
||||
mp_irq_void_method_t enable;
|
||||
mp_irq_void_method_t disable;
|
||||
mp_irq_int_method_t flags;
|
||||
} mp_irq_methods_t;
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t parent;
|
||||
mp_obj_t handler;
|
||||
mp_irq_methods_t *methods;
|
||||
bool isenabled;
|
||||
} mp_irq_obj_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE EXPORTED DATA
|
||||
******************************************************************************/
|
||||
extern const mp_arg_t mp_irq_init_args[];
|
||||
extern const mp_obj_type_t mp_irq_type;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
void mp_irq_init0 (void);
|
||||
mp_obj_t mp_irq_new (mp_obj_t parent, mp_obj_t handler, const mp_irq_methods_t *methods);
|
||||
mp_irq_obj_t *mp_irq_find (mp_obj_t parent);
|
||||
void mp_irq_wake_all (void);
|
||||
void mp_irq_disable_all (void);
|
||||
void mp_irq_remove (const mp_obj_t parent);
|
||||
void mp_irq_handler (mp_obj_t self_in);
|
||||
uint mp_irq_translate_priority (uint priority);
|
||||
|
||||
#endif /* MPIRQ_H_ */
|
||||
@@ -25,14 +25,10 @@
|
||||
* 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 "irq.h"
|
||||
#include "pybsystick.h"
|
||||
#include "py/obj.h"
|
||||
#include "mpsystick.h"
|
||||
#include "systick.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_nvic.h"
|
||||
@@ -62,32 +58,14 @@ void sys_tick_wait_at_least(uint32_t start_tick, uint32_t delay_ms) {
|
||||
|
||||
// The SysTick timer counts down at HAL_FCPU_HZ, so we can use that knowledge
|
||||
// to grab a microsecond counter.
|
||||
//
|
||||
// We assume that HAL_GetTick returns milliseconds.
|
||||
uint32_t sys_tick_get_microseconds(void) {
|
||||
mp_uint_t irq_state = disable_irq();
|
||||
uint32_t counter = SysTickValueGet();
|
||||
uint32_t milliseconds = HAL_GetTick();
|
||||
uint32_t status = (HWREG(NVIC_ST_CTRL));
|
||||
enable_irq(irq_state);
|
||||
|
||||
// It's still possible for the countflag bit to get set if the counter was
|
||||
// reloaded between reading VAL and reading CTRL. With interrupts disabled
|
||||
// it definitely takes less than 50 HCLK cycles between reading VAL and
|
||||
// reading CTRL, so the test (counter > 50) is to cover the case where VAL
|
||||
// is +ve and very close to zero, and the COUNTFLAG bit is also set.
|
||||
if ((status & NVIC_ST_CTRL_COUNT) && counter > 50) {
|
||||
// This means that the HW reloaded VAL between the time we read VAL and the
|
||||
// time we read CTRL, which implies that there is an interrupt pending
|
||||
// to increment the tick counter.
|
||||
milliseconds++;
|
||||
}
|
||||
uint32_t load = (HWREG(NVIC_ST_RELOAD));
|
||||
uint32_t load = SysTickPeriodGet();
|
||||
counter = load - counter; // Convert from decrementing to incrementing
|
||||
|
||||
// ((load + 1) / 1000) is the number of counts per microsecond.
|
||||
//
|
||||
// counter / ((load + 1) / 1000) scales from the systick clock to microseconds
|
||||
// and is the same thing as (counter * 1000) / (load + 1)
|
||||
return milliseconds * 1000 + (counter * 1000) / (load + 1);
|
||||
return (milliseconds * 1000) + ((counter * 1000) / load);
|
||||
}
|
||||
@@ -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
|
||||
218
cc3200/mods/modmachine.c
Normal file
218
cc3200/mods/modmachine.c
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* 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 "std.h"
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/runtime.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "irq.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 "prcm.h"
|
||||
#include "pyexec.h"
|
||||
#include "pybuart.h"
|
||||
#include "pybpin.h"
|
||||
#include "pybrtc.h"
|
||||
#include "simplelink.h"
|
||||
#include "modnetwork.h"
|
||||
#include "modwlan.h"
|
||||
#include "moduos.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "portable.h"
|
||||
#include "task.h"
|
||||
#include "mpexception.h"
|
||||
#include "random.h"
|
||||
#include "pybadc.h"
|
||||
#include "pybi2c.h"
|
||||
#include "pybsd.h"
|
||||
#include "pybwdt.h"
|
||||
#include "pybsleep.h"
|
||||
#include "pybspi.h"
|
||||
#include "pybtimer.h"
|
||||
#include "utils.h"
|
||||
#include "gccollect.h"
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
extern OsiTaskHandle mpTaskHandle;
|
||||
extern OsiTaskHandle svTaskHandle;
|
||||
extern OsiTaskHandle xSimpleLinkSpawnTaskHndl;
|
||||
#endif
|
||||
|
||||
|
||||
/// \module machine - functions related to the SoC
|
||||
///
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings;
|
||||
|
||||
STATIC mp_obj_t machine_reset(void) {
|
||||
// disable wlan
|
||||
wlan_stop(SL_STOP_TIMEOUT_LONG);
|
||||
// reset the cpu and it's peripherals
|
||||
MAP_PRCMMCUReset(true);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_obj, machine_reset);
|
||||
|
||||
#ifdef DEBUG
|
||||
STATIC mp_obj_t machine_info(uint n_args, const mp_obj_t *args) {
|
||||
// FreeRTOS info
|
||||
{
|
||||
printf("---------------------------------------------\n");
|
||||
printf("FreeRTOS\n");
|
||||
printf("---------------------------------------------\n");
|
||||
printf("Total heap: %u\n", configTOTAL_HEAP_SIZE);
|
||||
printf("Free heap: %u\n", xPortGetFreeHeapSize());
|
||||
printf("MpTask min free stack: %u\n", (unsigned int)uxTaskGetStackHighWaterMark((TaskHandle_t)mpTaskHandle));
|
||||
printf("ServersTask min free stack: %u\n", (unsigned int)uxTaskGetStackHighWaterMark((TaskHandle_t)svTaskHandle));
|
||||
printf("SlTask min free stack: %u\n", (unsigned int)uxTaskGetStackHighWaterMark(xSimpleLinkSpawnTaskHndl));
|
||||
printf("IdleTask min free stack: %u\n", (unsigned int)uxTaskGetStackHighWaterMark(xTaskGetIdleTaskHandle()));
|
||||
|
||||
uint32_t *pstack = (uint32_t *)&_stack;
|
||||
while (*pstack == 0x55555555) {
|
||||
pstack++;
|
||||
}
|
||||
printf("MAIN min free stack: %u\n", pstack - ((uint32_t *)&_stack));
|
||||
printf("---------------------------------------------\n");
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_info_obj, 0, 1, machine_info);
|
||||
#endif
|
||||
|
||||
STATIC mp_obj_t machine_freq(void) {
|
||||
mp_obj_t tuple[1] = {
|
||||
mp_obj_new_int(HAL_FCPU_HZ),
|
||||
};
|
||||
return mp_obj_new_tuple(1, tuple);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_freq_obj, machine_freq);
|
||||
|
||||
STATIC mp_obj_t machine_unique_id(void) {
|
||||
uint8_t mac[SL_BSSID_LENGTH];
|
||||
wlan_get_mac (mac);
|
||||
return mp_obj_new_bytes(mac, SL_BSSID_LENGTH);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_unique_id_obj, machine_unique_id);
|
||||
|
||||
STATIC mp_obj_t machine_main(mp_obj_t main) {
|
||||
if (MP_OBJ_IS_STR(main)) {
|
||||
MP_STATE_PORT(machine_config_main) = main;
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(machine_main_obj, machine_main);
|
||||
|
||||
STATIC mp_obj_t machine_idle(void) {
|
||||
__WFI();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_idle_obj, machine_idle);
|
||||
|
||||
STATIC mp_obj_t machine_sleep (void) {
|
||||
pyb_sleep_sleep();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_sleep_obj, machine_sleep);
|
||||
|
||||
STATIC mp_obj_t machine_deepsleep (void) {
|
||||
pyb_sleep_deepsleep();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_deepsleep_obj, machine_deepsleep);
|
||||
|
||||
STATIC mp_obj_t machine_reset_cause (void) {
|
||||
return mp_obj_new_int(pyb_sleep_get_reset_cause());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_cause_obj, machine_reset_cause);
|
||||
|
||||
STATIC mp_obj_t machine_wake_reason (void) {
|
||||
return mp_obj_new_int(pyb_sleep_get_wake_reason());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_wake_reason_obj, machine_wake_reason);
|
||||
|
||||
STATIC const mp_map_elem_t machine_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_machine) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_reset), (mp_obj_t)&machine_reset_obj },
|
||||
#ifdef DEBUG
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&machine_info_obj },
|
||||
#endif
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_freq), (mp_obj_t)&machine_freq_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unique_id), (mp_obj_t)&machine_unique_id_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_main), (mp_obj_t)&machine_main_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rng), (mp_obj_t)&machine_rng_get_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_idle), (mp_obj_t)&machine_idle_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&machine_sleep_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_deepsleep), (mp_obj_t)&machine_deepsleep_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_reset_cause), (mp_obj_t)&machine_reset_cause_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_wake_reason), (mp_obj_t)&machine_wake_reason_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_RTC), (mp_obj_t)&pyb_rtc_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_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_Timer), (mp_obj_t)&pyb_timer_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WDT), (mp_obj_t)&pyb_wdt_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SD), (mp_obj_t)&pyb_sd_type },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IDLE), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_ACTIVE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SLEEP), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_LPDS) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_DEEPSLEEP), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_HIBERNATE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_POWER_ON), 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_DEEPSLEEP_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_GPIO) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_RTC_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_RTC) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table);
|
||||
|
||||
const mp_obj_module_t machine_module = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_machine,
|
||||
.globals = (mp_obj_dict_t*)&machine_module_globals,
|
||||
};
|
||||
@@ -26,59 +26,135 @@
|
||||
*/
|
||||
|
||||
#include <std.h>
|
||||
#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 "py/obj.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "modnetwork.h"
|
||||
#include "mpexception.h"
|
||||
#include "mpstate.h"
|
||||
#include "serverstask.h"
|
||||
#include "simplelink.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
} network_server_obj_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC network_server_obj_t network_server_obj;
|
||||
STATIC const mp_obj_type_t network_server_type;
|
||||
|
||||
/// \module network - network configuration
|
||||
///
|
||||
/// This module provides network drivers and routing configuration.
|
||||
/// This module provides network drivers and server configuration.
|
||||
|
||||
void mod_network_init(void) {
|
||||
mp_obj_list_init(&MP_STATE_PORT(mod_network_nic_list), 0);
|
||||
void mod_network_init0(void) {
|
||||
}
|
||||
|
||||
void mod_network_register_nic(mp_obj_t nic) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) {
|
||||
if (MP_STATE_PORT(mod_network_nic_list).items[i] == nic) {
|
||||
// nic already registered
|
||||
return;
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
STATIC mp_obj_t network_server_init_helper(mp_obj_t self, const mp_arg_val_t *args) {
|
||||
const char *user = SERVERS_DEF_USER;
|
||||
const char *pass = SERVERS_DEF_PASS;
|
||||
if (args[0].u_obj != MP_OBJ_NULL) {
|
||||
mp_obj_t *login;
|
||||
mp_obj_get_array_fixed_n(args[0].u_obj, 2, &login);
|
||||
user = mp_obj_str_get_str(login[0]);
|
||||
pass = mp_obj_str_get_str(login[1]);
|
||||
}
|
||||
|
||||
uint32_t timeout = SERVERS_DEF_TIMEOUT_MS / 1000;
|
||||
if (args[1].u_obj != MP_OBJ_NULL) {
|
||||
timeout = mp_obj_get_int(args[1].u_obj);
|
||||
}
|
||||
|
||||
// configure the new login
|
||||
servers_set_login ((char *)user, (char *)pass);
|
||||
|
||||
// configure the timeout
|
||||
servers_set_timeout(timeout * 1000);
|
||||
|
||||
// start the servers
|
||||
servers_start();
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
STATIC const mp_arg_t network_server_args[] = {
|
||||
{ MP_QSTR_id, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_login, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
};
|
||||
STATIC mp_obj_t network_server_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
|
||||
// parse args
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(network_server_args)];
|
||||
mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), network_server_args, args);
|
||||
|
||||
// check the server id
|
||||
if (args[0].u_obj != MP_OBJ_NULL) {
|
||||
if (mp_obj_get_int(args[0].u_obj) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
}
|
||||
// nic not registered so add to list
|
||||
mp_obj_list_append(&MP_STATE_PORT(mod_network_nic_list), nic);
|
||||
|
||||
// setup the object and initialize it
|
||||
network_server_obj_t *self = &network_server_obj;
|
||||
self->base.type = &network_server_type;
|
||||
network_server_init_helper(self, &args[1]);
|
||||
|
||||
return (mp_obj_t)self;
|
||||
}
|
||||
|
||||
mp_obj_t mod_network_find_nic(const uint8_t *ip) {
|
||||
// find a NIC that is suited to given IP address
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) {
|
||||
mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i];
|
||||
return nic;
|
||||
STATIC mp_obj_t network_server_init(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(network_server_args) - 1];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &network_server_args[1], args);
|
||||
return network_server_init_helper(pos_args[0], args);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(network_server_init_obj, 1, network_server_init);
|
||||
|
||||
// timeout value given in seconds
|
||||
STATIC mp_obj_t network_server_timeout(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
if (n_args > 1) {
|
||||
uint32_t timeout = mp_obj_get_int(args[1]);
|
||||
servers_set_timeout(timeout * 1000);
|
||||
return mp_const_none;
|
||||
} else {
|
||||
// get
|
||||
return mp_obj_new_int(servers_get_timeout() / 1000);
|
||||
}
|
||||
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_server_timeout_obj, 1, 2, network_server_timeout);
|
||||
|
||||
STATIC mp_obj_t network_route(void) {
|
||||
return &MP_STATE_PORT(mod_network_nic_list);
|
||||
STATIC mp_obj_t network_server_running(mp_obj_t self_in) {
|
||||
// get
|
||||
return mp_obj_new_bool(servers_are_enabled());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_route_obj, network_route);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(network_server_running_obj, network_server_running);
|
||||
|
||||
STATIC mp_obj_t network_server_deinit(mp_obj_t self_in) {
|
||||
// simply stop the servers
|
||||
servers_stop();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(network_server_deinit_obj, network_server_deinit);
|
||||
#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 },
|
||||
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_server), (mp_obj_t)&network_server_type },
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_network_globals, mp_module_network_globals_table);
|
||||
@@ -89,64 +165,20 @@ const mp_obj_module_t mp_module_network = {
|
||||
.globals = (mp_obj_dict_t*)&mp_module_network_globals,
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
// Miscellaneous helpers
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
STATIC const mp_map_elem_t network_server_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&network_server_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&network_server_deinit_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_timeout), (mp_obj_t)&network_server_timeout_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_isrunning), (mp_obj_t)&network_server_running_obj },
|
||||
};
|
||||
|
||||
void mod_network_convert_ipv4_endianness(uint8_t *ip) {
|
||||
uint8_t ip0 = ip[0]; ip[0] = ip[3]; ip[3] = ip0;
|
||||
uint8_t ip1 = ip[1]; ip[1] = ip[2]; ip[2] = ip1;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_DICT(network_server_locals_dict, network_server_locals_dict_table);
|
||||
|
||||
// Takes an address of the form '192.168.0.1' and converts it to network format
|
||||
// in out_ip (big endian, so the 192 is the first byte).
|
||||
void mod_network_parse_ipv4_addr(mp_obj_t addr_in, uint8_t *out_ip) {
|
||||
mp_uint_t addr_len;
|
||||
const char *addr_str = mp_obj_str_get_data(addr_in, &addr_len);
|
||||
if (addr_len == 0) {
|
||||
// special case of no address given
|
||||
memset(out_ip, 0, MOD_NETWORK_IPV4ADDR_BUF_SIZE);
|
||||
return;
|
||||
}
|
||||
const char *s = addr_str;
|
||||
const char *s_top = addr_str + addr_len;
|
||||
for (mp_uint_t i = 0;; i++) {
|
||||
mp_uint_t val = 0;
|
||||
for (; s < s_top && *s != '.'; s++) {
|
||||
val = val * 10 + *s - '0';
|
||||
}
|
||||
out_ip[i] = val;
|
||||
if (i == 3 && s == s_top) {
|
||||
return;
|
||||
} else if (i < 3 && s < s_top && *s == '.') {
|
||||
s++;
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Takes an address of the form ('192.168.0.1', 8080), returns the port and
|
||||
// puts IP in out_ip (which must take at least IPADDR_BUF_SIZE bytes).
|
||||
mp_uint_t mod_network_parse_inet_addr(mp_obj_t addr_in, uint8_t *out_ip) {
|
||||
mp_obj_t *addr_items;
|
||||
mp_obj_get_array_fixed_n(addr_in, 2, &addr_items);
|
||||
mod_network_parse_ipv4_addr(addr_items[0], out_ip);
|
||||
return mp_obj_get_int(addr_items[1]);
|
||||
}
|
||||
|
||||
// Takes an array with a raw IPv4 address and returns something like '192.168.0.1'.
|
||||
mp_obj_t mod_network_format_ipv4_addr(uint8_t *ip) {
|
||||
char ip_str[16];
|
||||
mp_uint_t ip_len = snprintf(ip_str, 16, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
|
||||
return mp_obj_new_str(ip_str, ip_len, false);
|
||||
}
|
||||
|
||||
// Takes an array with a raw IP address, and a port, and returns a net-address
|
||||
// tuple such as ('192.168.0.1', 8080).
|
||||
mp_obj_t mod_network_format_inet_addr(uint8_t *ip, mp_uint_t port) {
|
||||
mp_obj_t tuple[2] = {
|
||||
tuple[0] = mod_network_format_ipv4_addr(ip),
|
||||
tuple[1] = mp_obj_new_int(port),
|
||||
};
|
||||
return mp_obj_new_tuple(2, tuple);
|
||||
}
|
||||
STATIC const mp_obj_type_t network_server_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_server,
|
||||
.make_new = network_server_make_new,
|
||||
.locals_dict = (mp_obj_t)&network_server_locals_dict,
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -25,57 +25,50 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MODNETWORK_H_
|
||||
#define MODNETWORK_H_
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define MOD_NETWORK_IPV4ADDR_BUF_SIZE (4)
|
||||
|
||||
// Forward declaration
|
||||
struct _mod_network_socket_obj_t;
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
******************************************************************************/
|
||||
typedef struct _mod_network_nic_type_t {
|
||||
mp_obj_type_t base;
|
||||
|
||||
// API for non-socket operations
|
||||
int (*gethostbyname)(mp_obj_t nic, const char *name, mp_uint_t len, uint8_t *ip_out, uint8_t family);
|
||||
|
||||
// API for socket operations; return -1 on error
|
||||
int (*socket)(struct _mod_network_socket_obj_t *s, int *_errno);
|
||||
void (*close)(struct _mod_network_socket_obj_t *socket);
|
||||
int (*bind)(struct _mod_network_socket_obj_t *s, byte *ip, mp_uint_t port, int *_errno);
|
||||
int (*listen)(struct _mod_network_socket_obj_t *s, mp_int_t backlog, int *_errno);
|
||||
int (*accept)(struct _mod_network_socket_obj_t *s, struct _mod_network_socket_obj_t *s2, byte *ip, mp_uint_t *port, int *_errno);
|
||||
int (*connect)(struct _mod_network_socket_obj_t *s, byte *ip, mp_uint_t port, int *_errno);
|
||||
int (*send)(struct _mod_network_socket_obj_t *s, const byte *buf, mp_uint_t len, int *_errno);
|
||||
int (*recv)(struct _mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, int *_errno);
|
||||
int (*sendto)(struct _mod_network_socket_obj_t *s, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno);
|
||||
int (*recvfrom)(struct _mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno);
|
||||
int (*setsockopt)(struct _mod_network_socket_obj_t *s, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno);
|
||||
int (*settimeout)(struct _mod_network_socket_obj_t *s, mp_uint_t timeout_ms, int *_errno);
|
||||
int (*ioctl)(struct _mod_network_socket_obj_t *s, mp_uint_t request, mp_uint_t arg, int *_errno);
|
||||
} mod_network_nic_type_t;
|
||||
|
||||
typedef struct _mod_network_socket_base_t {
|
||||
union {
|
||||
struct {
|
||||
// this order is important so that fileno gets > 0 once
|
||||
// the socket descriptor is assigned after being created.
|
||||
uint8_t domain;
|
||||
int8_t fileno;
|
||||
uint8_t type;
|
||||
uint8_t proto;
|
||||
} u_param;
|
||||
int16_t sd;
|
||||
};
|
||||
bool has_timeout;
|
||||
bool cert_req;
|
||||
} mod_network_socket_base_t;
|
||||
|
||||
typedef struct _mod_network_socket_obj_t {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t nic;
|
||||
mod_network_nic_type_t *nic_type;
|
||||
union {
|
||||
struct {
|
||||
uint8_t domain;
|
||||
uint8_t type;
|
||||
uint8_t proto;
|
||||
int8_t fileno;
|
||||
} u_param;
|
||||
int16_t sd;
|
||||
bool closed;
|
||||
};
|
||||
mod_network_socket_base_t sock_base;
|
||||
} mod_network_socket_obj_t;
|
||||
|
||||
/******************************************************************************
|
||||
EXPORTED DATA
|
||||
******************************************************************************/
|
||||
extern const mod_network_nic_type_t mod_network_nic_type_wlan;
|
||||
|
||||
void mod_network_init(void);
|
||||
void mod_network_register_nic(mp_obj_t nic);
|
||||
mp_obj_t mod_network_find_nic(const uint8_t *ip);
|
||||
/******************************************************************************
|
||||
DECLARE FUNCTIONS
|
||||
******************************************************************************/
|
||||
void mod_network_init0(void);
|
||||
|
||||
void mod_network_convert_ipv4_endianness(uint8_t *ip);
|
||||
void mod_network_parse_ipv4_addr(mp_obj_t addr_in, uint8_t *out_ip);
|
||||
mp_uint_t mod_network_parse_inet_addr(mp_obj_t addr_in, uint8_t *out_ip);
|
||||
mp_obj_t mod_network_format_ipv4_addr(uint8_t *ip);
|
||||
mp_obj_t mod_network_format_inet_addr(uint8_t *ip, mp_uint_t port);
|
||||
#endif // MODNETWORK_H_
|
||||
|
||||
@@ -1,318 +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 <std.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "mpconfig.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"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "inc/hw_uart.h"
|
||||
#include "prcm.h"
|
||||
#include "pyexec.h"
|
||||
#include "pybuart.h"
|
||||
#include "pybpin.h"
|
||||
#include "pybstdio.h"
|
||||
#include "pybrtc.h"
|
||||
#include "pybsystick.h"
|
||||
#include "simplelink.h"
|
||||
#include "modwlan.h"
|
||||
#include "telnet.h"
|
||||
#include "ff.h"
|
||||
#include "diskio.h"
|
||||
#include "sflash_diskio.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "portable.h"
|
||||
#include "task.h"
|
||||
#include "mpexception.h"
|
||||
#include "random.h"
|
||||
#include "pybextint.h"
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
extern OsiTaskHandle mpTaskHandle;
|
||||
extern OsiTaskHandle svTaskHandle;
|
||||
extern TaskHandle_t xSimpleLinkSpawnTaskHndl;
|
||||
#endif
|
||||
|
||||
/// \module pyb - functions related to the pyboard
|
||||
///
|
||||
/// The `pyb` module contains specific functions related to the pyboard.
|
||||
|
||||
/// \function hard_reset()
|
||||
/// 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();
|
||||
// perform a SoC reset
|
||||
PRCMSOCReset();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_hard_reset_obj, pyb_hard_reset);
|
||||
|
||||
#ifdef DEBUG
|
||||
/// \function info([dump_alloc_table])
|
||||
/// Print out some run time info which is helpful duirng development.
|
||||
STATIC mp_obj_t pyb_info(uint n_args, const mp_obj_t *args) {
|
||||
// FreeRTOS info
|
||||
{
|
||||
printf("---------------------------------------------\n");
|
||||
printf("FreeRTOS\n");
|
||||
printf("---------------------------------------------\n");
|
||||
printf("Total heap: %u\n", configTOTAL_HEAP_SIZE);
|
||||
printf("Free heap: %u\n", xPortGetFreeHeapSize());
|
||||
printf("MpTask min free stack: %u\n", (unsigned int)uxTaskGetStackHighWaterMark((TaskHandle_t)mpTaskHandle));
|
||||
printf("ServersTask min free stack: %u\n", (unsigned int)uxTaskGetStackHighWaterMark((TaskHandle_t)svTaskHandle));
|
||||
printf("SlTask min free stack: %u\n", (unsigned int)uxTaskGetStackHighWaterMark(xSimpleLinkSpawnTaskHndl));
|
||||
printf("IdleTask min free stack: %u\n", (unsigned int)uxTaskGetStackHighWaterMark(xTaskGetIdleTaskHandle()));
|
||||
|
||||
uint32_t *pstack = (uint32_t *)&_stack;
|
||||
while (*pstack == 0x55555555) {
|
||||
pstack++;
|
||||
}
|
||||
printf("MAIN min free stack: %u\n", pstack - ((uint32_t *)&_stack));
|
||||
printf("---------------------------------------------\n");
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
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) {
|
||||
return mp_obj_new_int(HAL_FCPU_HZ);
|
||||
}
|
||||
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.
|
||||
///
|
||||
/// The result is always a micropython smallint (31-bit signed number), so
|
||||
/// after 2^30 milliseconds (about 12.4 days) this will start to return
|
||||
/// negative numbers.
|
||||
STATIC mp_obj_t pyb_millis(void) {
|
||||
// We want to "cast" the 32 bit unsigned into a small-int. This means
|
||||
// copying the MSB down 1 bit (extending the sign down), which is
|
||||
// equivalent to just using the MP_OBJ_NEW_SMALL_INT macro.
|
||||
return MP_OBJ_NEW_SMALL_INT(HAL_GetTick());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_millis_obj, pyb_millis);
|
||||
|
||||
/// \function elapsed_millis(start)
|
||||
/// Returns the number of milliseconds which have elapsed since `start`.
|
||||
///
|
||||
/// This function takes care of counter wrap, and always returns a positive
|
||||
/// number. This means it can be used to measure periods upto about 12.4 days.
|
||||
///
|
||||
/// Example:
|
||||
/// start = pyb.millis()
|
||||
/// while pyb.elapsed_millis(start) < 1000:
|
||||
/// # Perform some operation
|
||||
STATIC mp_obj_t pyb_elapsed_millis(mp_obj_t start) {
|
||||
uint32_t startMillis = mp_obj_get_int(start);
|
||||
uint32_t currMillis = HAL_GetTick();
|
||||
return MP_OBJ_NEW_SMALL_INT((currMillis - startMillis) & 0x3fffffff);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_elapsed_millis_obj, pyb_elapsed_millis);
|
||||
|
||||
/// \function micros()
|
||||
/// Returns the number of microseconds since the board was last reset.
|
||||
///
|
||||
/// The result is always a micropython smallint (31-bit signed number), so
|
||||
/// after 2^30 microseconds (about 17.8 minutes) this will start to return
|
||||
/// negative numbers.
|
||||
STATIC mp_obj_t pyb_micros(void) {
|
||||
// We want to "cast" the 32 bit unsigned into a small-int. This means
|
||||
// copying the MSB down 1 bit (extending the sign down), which is
|
||||
// equivalent to just using the MP_OBJ_NEW_SMALL_INT macro.
|
||||
return MP_OBJ_NEW_SMALL_INT(sys_tick_get_microseconds());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_micros_obj, pyb_micros);
|
||||
|
||||
/// \function elapsed_micros(start)
|
||||
/// Returns the number of microseconds which have elapsed since `start`.
|
||||
///
|
||||
/// This function takes care of counter wrap, and always returns a positive
|
||||
/// number. This means it can be used to measure periods upto about 17.8 minutes.
|
||||
///
|
||||
/// Example:
|
||||
/// start = pyb.micros()
|
||||
/// while pyb.elapsed_micros(start) < 1000:
|
||||
/// # Perform some operation
|
||||
STATIC mp_obj_t pyb_elapsed_micros(mp_obj_t start) {
|
||||
uint32_t startMicros = mp_obj_get_int(start);
|
||||
uint32_t currMicros = sys_tick_get_microseconds();
|
||||
return MP_OBJ_NEW_SMALL_INT((currMicros - startMicros) & 0x3fffffff);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_elapsed_micros_obj, pyb_elapsed_micros);
|
||||
|
||||
/// \function delay(ms)
|
||||
/// Delay for the given number of milliseconds.
|
||||
STATIC mp_obj_t pyb_delay(mp_obj_t ms_in) {
|
||||
mp_int_t ms = mp_obj_get_int(ms_in);
|
||||
if (ms > 0) {
|
||||
HAL_Delay(ms);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_delay_obj, pyb_delay);
|
||||
|
||||
/// \function udelay(us)
|
||||
/// Delay for the given number of microseconds.
|
||||
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) {
|
||||
}
|
||||
}
|
||||
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) {
|
||||
return mp_const_none;
|
||||
} else {
|
||||
return MP_STATE_PORT(pyb_stdio_uart);
|
||||
}
|
||||
} else {
|
||||
if (args[0] == mp_const_none) {
|
||||
MP_STATE_PORT(pyb_stdio_uart) = NULL;
|
||||
} else if (mp_obj_get_type(args[0]) == &pyb_uart_type) {
|
||||
MP_STATE_PORT(pyb_stdio_uart) = args[0];
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, 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);
|
||||
|
||||
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 },
|
||||
#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_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 },
|
||||
|
||||
#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 },
|
||||
#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_UART), (mp_obj_t)&pyb_uart_type },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_module_globals, pyb_module_globals_table);
|
||||
|
||||
const mp_obj_module_t pyb_module = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_pyb,
|
||||
.globals = (mp_obj_dict_t*)&pyb_module_globals,
|
||||
};
|
||||
64
cc3200/mods/modubinascii.c
Normal file
64
cc3200/mods/modubinascii.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Paul Sokolovsky
|
||||
* 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/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/binary.h"
|
||||
#include "extmod/modubinascii.h"
|
||||
#include "modubinascii.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_nvic.h"
|
||||
#include "inc/hw_dthe.h"
|
||||
#include "hw_memmap.h"
|
||||
#include "rom_map.h"
|
||||
#include "prcm.h"
|
||||
#include "crc.h"
|
||||
#include "cryptohash.h"
|
||||
#include "mpexception.h"
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
STATIC const mp_map_elem_t mp_module_binascii_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_ubinascii) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_hexlify), (mp_obj_t)&mod_binascii_hexlify_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unhexlify), (mp_obj_t)&mod_binascii_unhexlify_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_a2b_base64), (mp_obj_t)&mod_binascii_a2b_base64_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_b2a_base64), (mp_obj_t)&mod_binascii_b2a_base64_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_binascii_globals, mp_module_binascii_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_ubinascii = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_ubinascii,
|
||||
.globals = (mp_obj_dict_t*)&mp_module_binascii_globals,
|
||||
};
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2014 Paul Sokolovsky
|
||||
*
|
||||
* 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 +24,8 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename);
|
||||
#ifndef MODUBINASCII_H_
|
||||
#define MODUBINASCII_H_
|
||||
|
||||
|
||||
#endif /* MODUBINASCII_H_ */
|
||||
210
cc3200/mods/moduhashlib.c
Normal file
210
cc3200/mods/moduhashlib.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) 2014 Paul Sokolovsky
|
||||
* 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 <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_nvic.h"
|
||||
#include "inc/hw_shamd5.h"
|
||||
#include "inc/hw_dthe.h"
|
||||
#include "hw_memmap.h"
|
||||
#include "rom_map.h"
|
||||
#include "prcm.h"
|
||||
#include "shamd5.h"
|
||||
#include "cryptohash.h"
|
||||
#include "mpexception.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE TYPES
|
||||
******************************************************************************/
|
||||
typedef struct _mp_obj_hash_t {
|
||||
mp_obj_base_t base;
|
||||
uint8_t *buffer;
|
||||
uint32_t b_size;
|
||||
uint32_t c_size;
|
||||
uint8_t algo;
|
||||
uint8_t h_size;
|
||||
bool fixedlen;
|
||||
bool digested;
|
||||
uint8_t hash[32];
|
||||
} mp_obj_hash_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC void hash_update_internal(mp_obj_t self_in, mp_obj_t data, bool digest);
|
||||
STATIC mp_obj_t hash_read (mp_obj_t self_in);
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC void hash_update_internal(mp_obj_t self_in, mp_obj_t data, bool digest) {
|
||||
mp_obj_hash_t *self = self_in;
|
||||
mp_buffer_info_t bufinfo;
|
||||
|
||||
if (data) {
|
||||
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
|
||||
}
|
||||
|
||||
if (digest) {
|
||||
CRYPTOHASH_SHAMD5Start (self->algo, self->b_size);
|
||||
}
|
||||
|
||||
if (self->c_size < self->b_size || !data || !self->fixedlen) {
|
||||
if (digest || self->fixedlen) {
|
||||
// no data means we want to process our internal buffer
|
||||
CRYPTOHASH_SHAMD5Update (data ? bufinfo.buf : self->buffer, data ? bufinfo.len : self->b_size);
|
||||
self->c_size += data ? bufinfo.len : 0;
|
||||
} else {
|
||||
self->buffer = m_renew(byte, self->buffer, self->b_size, self->b_size + bufinfo.len);
|
||||
mp_seq_copy((byte*)self->buffer + self->b_size, bufinfo.buf, bufinfo.len, byte);
|
||||
self->b_size += bufinfo.len;
|
||||
self->digested = false;
|
||||
}
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t hash_read (mp_obj_t self_in) {
|
||||
mp_obj_hash_t *self = self_in;
|
||||
|
||||
if (!self->fixedlen) {
|
||||
if (!self->digested) {
|
||||
hash_update_internal(self, MP_OBJ_NULL, true);
|
||||
}
|
||||
} else if (self->c_size < self->b_size) {
|
||||
// it's a fixed len block which is still incomplete
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
|
||||
if (!self->digested) {
|
||||
CRYPTOHASH_SHAMD5Read ((uint8_t *)self->hash);
|
||||
self->digested = true;
|
||||
}
|
||||
return mp_obj_new_bytes(self->hash, self->h_size);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
/// \classmethod \constructor([data[, block_size]])
|
||||
/// initial data must be given if block_size wants to be passed
|
||||
STATIC mp_obj_t hash_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, 2, false);
|
||||
mp_obj_hash_t *self = m_new0(mp_obj_hash_t, 1);
|
||||
self->base.type = type_in;
|
||||
if (self->base.type->name == MP_QSTR_sha1) {
|
||||
self->algo = SHAMD5_ALGO_SHA1;
|
||||
self->h_size = 20;
|
||||
} else /* if (self->base.type->name == MP_QSTR_sha256) */ {
|
||||
self->algo = SHAMD5_ALGO_SHA256;
|
||||
self->h_size = 32;
|
||||
} /* else {
|
||||
self->algo = SHAMD5_ALGO_MD5;
|
||||
self->h_size = 32;
|
||||
} */
|
||||
|
||||
if (n_args) {
|
||||
// CPython extension to avoid buffering the data before digesting it
|
||||
// Note: care must be taken to provide all intermediate blocks as multiple
|
||||
// of four bytes, otherwise the resulting hash will be incorrect.
|
||||
// the final block can be of any length
|
||||
if (n_args > 1) {
|
||||
// block size given, we will feed the data directly into the hash engine
|
||||
self->fixedlen = true;
|
||||
self->b_size = mp_obj_get_int(args[1]);
|
||||
hash_update_internal(self, args[0], true);
|
||||
} else {
|
||||
hash_update_internal(self, args[0], false);
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t hash_update(mp_obj_t self_in, mp_obj_t arg) {
|
||||
mp_obj_hash_t *self = self_in;
|
||||
hash_update_internal(self, arg, false);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(hash_update_obj, hash_update);
|
||||
|
||||
STATIC mp_obj_t hash_digest(mp_obj_t self_in) {
|
||||
return hash_read(self_in);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(hash_digest_obj, hash_digest);
|
||||
|
||||
STATIC const mp_map_elem_t hash_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_update), (mp_obj_t) &hash_update_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_digest), (mp_obj_t) &hash_digest_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(hash_locals_dict, hash_locals_dict_table);
|
||||
|
||||
//STATIC const mp_obj_type_t md5_type = {
|
||||
// { &mp_type_type },
|
||||
// .name = MP_QSTR_md5,
|
||||
// .make_new = hash_make_new,
|
||||
// .locals_dict = (mp_obj_t)&hash_locals_dict,
|
||||
//};
|
||||
|
||||
STATIC const mp_obj_type_t sha1_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_sha1,
|
||||
.make_new = hash_make_new,
|
||||
.locals_dict = (mp_obj_t)&hash_locals_dict,
|
||||
};
|
||||
|
||||
STATIC const mp_obj_type_t sha256_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_sha256,
|
||||
.make_new = hash_make_new,
|
||||
.locals_dict = (mp_obj_t)&hash_locals_dict,
|
||||
};
|
||||
|
||||
STATIC const mp_map_elem_t mp_module_hashlib_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_uhashlib) },
|
||||
// { MP_OBJ_NEW_QSTR(MP_QSTR_md5), (mp_obj_t)&md5_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sha1), (mp_obj_t)&sha1_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sha256), (mp_obj_t)&sha256_type },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_hashlib_globals, mp_module_hashlib_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_uhashlib = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_uhashlib,
|
||||
.globals = (mp_obj_dict_t*)&mp_module_hashlib_globals,
|
||||
};
|
||||
|
||||
@@ -27,21 +27,23 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#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 "ff.h"
|
||||
#include "py/mpstate.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "genhdr/mpversion.h"
|
||||
#include "moduos.h"
|
||||
#include "diskio.h"
|
||||
#include "sflash_diskio.h"
|
||||
#include "file.h"
|
||||
#include "modutime.h"
|
||||
#include "random.h"
|
||||
#include "sd_diskio.h"
|
||||
#include "mpexception.h"
|
||||
#include "version.h"
|
||||
#include "timeutils.h"
|
||||
#include "pybsd.h"
|
||||
#include "pybuart.h"
|
||||
|
||||
/// \module os - basic "operating system" services
|
||||
///
|
||||
@@ -50,163 +52,59 @@
|
||||
/// The filesystem has `/` as the root directory, and the available physical
|
||||
/// drives are accessible from here. They are currently:
|
||||
///
|
||||
/// /SFLASH -- the serial flash filesystem
|
||||
/// /SD -- the SD card (if it exists)
|
||||
/// /flash -- the serial flash filesystem
|
||||
///
|
||||
/// On boot up, the current directory is `/SFLASH` if no SD card is inserted,
|
||||
/// otherwise it is `/SD`.
|
||||
/// On boot up, the current directory is `/flash`.
|
||||
|
||||
STATIC bool sd_in_root(void) {
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
return sd_disk_ready();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC uint32_t os_num_mounted_devices;
|
||||
STATIC os_term_dup_obj_t os_term_dup_obj;
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
void moduos_init0 (void) {
|
||||
// initialize the mount objects list
|
||||
mp_obj_list_init(&MP_STATE_PORT(mount_obj_list), 0);
|
||||
os_num_mounted_devices = 0;
|
||||
}
|
||||
|
||||
/// \function chdir(path)
|
||||
/// Change current directory.
|
||||
STATIC mp_obj_t os_chdir(mp_obj_t path_in) {
|
||||
const char *path;
|
||||
path = mp_obj_str_get_str(path_in);
|
||||
|
||||
FRESULT res = f_chdrive(path);
|
||||
|
||||
if (res == FR_OK) {
|
||||
res = f_chdir(path);
|
||||
}
|
||||
// TODO: Warn if too many open files...
|
||||
if (res != FR_OK) {
|
||||
// TODO should be mp_type_FileNotFoundError
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "No such file or directory: '%s'", path));
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_chdir_obj, os_chdir);
|
||||
|
||||
/// \function getcwd()
|
||||
/// Get the current directory.
|
||||
STATIC mp_obj_t os_getcwd(void) {
|
||||
char buf[MICROPY_ALLOC_PATH_MAX + 1];
|
||||
FRESULT res = f_getcwd(buf, sizeof buf);
|
||||
|
||||
if (res != FR_OK) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
|
||||
}
|
||||
|
||||
return mp_obj_new_str(buf, strlen(buf), false);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_getcwd_obj, os_getcwd);
|
||||
|
||||
/// \function listdir([dir])
|
||||
/// With no argument, list the current directory. Otherwise list the given directory.
|
||||
STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
bool is_str_type = true;
|
||||
const char *path;
|
||||
if (n_args == 1) {
|
||||
if (mp_obj_get_type(args[0]) == &mp_type_bytes) {
|
||||
is_str_type = false;
|
||||
os_fs_mount_t *osmount_find_by_path (const char *path) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
if (!strcmp(path, mount_obj->path)) {
|
||||
return mount_obj;
|
||||
}
|
||||
path = mp_obj_str_get_str(args[0]);
|
||||
} else {
|
||||
path = "";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// "hack" to list root directory
|
||||
if (path[0] == '/' && path[1] == '\0') {
|
||||
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
|
||||
mp_obj_list_append(dir_list, MP_OBJ_NEW_QSTR(MP_QSTR_SFLASH));
|
||||
if (sd_in_root()) {
|
||||
mp_obj_list_append(dir_list, MP_OBJ_NEW_QSTR(MP_QSTR_SD));
|
||||
os_fs_mount_t *osmount_find_by_volume (uint8_t vol) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
if (vol == mount_obj->vol) {
|
||||
return mount_obj;
|
||||
}
|
||||
return dir_list;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FRESULT res;
|
||||
FILINFO fno;
|
||||
DIR dir;
|
||||
|
||||
res = f_opendir(&dir, path); /* Open the directory */
|
||||
if (res != FR_OK) {
|
||||
// TODO should be mp_type_FileNotFoundError
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "No such file or directory: '%s'", path));
|
||||
}
|
||||
|
||||
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
|
||||
|
||||
for (;;) {
|
||||
res = f_readdir(&dir, &fno); /* Read a directory item */
|
||||
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
|
||||
|
||||
char *fn = fno.fname;
|
||||
|
||||
// make a string object for this entry
|
||||
mp_obj_t entry_o;
|
||||
if (is_str_type) {
|
||||
entry_o = mp_obj_new_str(fn, strlen(fn), false);
|
||||
} else {
|
||||
entry_o = mp_obj_new_bytes((const byte*)fn, strlen(fn));
|
||||
os_fs_mount_t *osmount_find_by_device (mp_obj_t device) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
if (device == mount_obj->device) {
|
||||
return mount_obj;
|
||||
}
|
||||
|
||||
// add the entry to the list
|
||||
mp_obj_list_append(dir_list, entry_o);
|
||||
}
|
||||
|
||||
f_closedir(&dir);
|
||||
|
||||
return dir_list;
|
||||
return NULL;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_listdir_obj, 0, 1, os_listdir);
|
||||
|
||||
/// \function mkdir(path)
|
||||
/// Create a new directory.
|
||||
STATIC mp_obj_t os_mkdir(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
FRESULT res = f_mkdir(path);
|
||||
switch (res) {
|
||||
case FR_OK:
|
||||
return mp_const_none;
|
||||
case FR_EXIST:
|
||||
// TODO should be FileExistsError
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "File exists: '%s'", path));
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error creating directory '%s'", path));
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir);
|
||||
|
||||
/// \function remove(path)
|
||||
/// Remove a file.
|
||||
STATIC mp_obj_t os_remove(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
// TODO check that path is actually a file before trying to unlink it
|
||||
FRESULT res = f_unlink(path);
|
||||
switch (res) {
|
||||
case FR_OK:
|
||||
return mp_const_none;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing file '%s'", path));
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove);
|
||||
|
||||
/// \function rmdir(path)
|
||||
/// Remove a directory.
|
||||
STATIC mp_obj_t os_rmdir(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
// TODO check that path is actually a directory before trying to unlink it
|
||||
FRESULT res = f_unlink(path);
|
||||
switch (res) {
|
||||
case FR_OK:
|
||||
return mp_const_none;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing directory '%s'", path));
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_rmdir_obj, os_rmdir);
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
// Checks for path equality, ignoring trailing slashes:
|
||||
// path_equal(/, /) -> true
|
||||
@@ -223,30 +121,273 @@ STATIC bool path_equal(const char *path, const char *path_canonical) {
|
||||
return *path == '\0';
|
||||
}
|
||||
|
||||
/// \function stat(path)
|
||||
/// Get the status of a file or directory.
|
||||
STATIC void append_dir_item (mp_obj_t dirlist, const char *item, bool string) {
|
||||
// make a string object for this entry
|
||||
mp_obj_t entry_o;
|
||||
if (string) {
|
||||
entry_o = mp_obj_new_str(item, strlen(item), false);
|
||||
} else {
|
||||
entry_o = mp_obj_new_bytes((const byte*)item, strlen(item));
|
||||
}
|
||||
|
||||
// add the entry to the list
|
||||
mp_obj_list_append(dirlist, entry_o);
|
||||
}
|
||||
|
||||
STATIC void mount (mp_obj_t device, const char *path, uint pathlen, bool readonly) {
|
||||
// is the mount point already in use?
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
fno.lfname = NULL;
|
||||
fno.lfsize = 0;
|
||||
#endif
|
||||
// cannot mount twice or on existing paths
|
||||
if (f_stat(path, &fno) == FR_OK || osmount_find_by_device(device)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
|
||||
// create a new object
|
||||
os_fs_mount_t *self = m_new_obj(os_fs_mount_t);
|
||||
self->device = device;
|
||||
self->path = path;
|
||||
self->pathlen = pathlen;
|
||||
self->vol = os_num_mounted_devices + 1; // '/flash' is volume 0
|
||||
|
||||
if (device == (mp_obj_t)&pybsd_obj) {
|
||||
// need to make it different to NULL, otherwise it's read only by default
|
||||
self->writeblocks[0] = mp_const_none;
|
||||
self->sync[0] = MP_OBJ_NULL; // no need to sync the SD card
|
||||
self->count[0] = MP_OBJ_NULL;
|
||||
} else {
|
||||
// load block protocol methods
|
||||
mp_load_method(device, MP_QSTR_readblocks, self->readblocks);
|
||||
mp_load_method_maybe(device, MP_QSTR_writeblocks, self->writeblocks);
|
||||
mp_load_method_maybe(device, MP_QSTR_sync, self->sync);
|
||||
mp_load_method(device, MP_QSTR_count, self->count);
|
||||
}
|
||||
|
||||
// Read-only device indicated by writeblocks[0] == MP_OBJ_NULL.
|
||||
// User can specify read-only device by:
|
||||
// 1. readonly=True keyword argument
|
||||
// 2. nonexistent writeblocks method (then writeblocks[0] == MP_OBJ_NULL already)
|
||||
if (readonly) {
|
||||
self->writeblocks[0] = MP_OBJ_NULL;
|
||||
}
|
||||
|
||||
// we need to add it before doing the actual mount, so that the volume can be found
|
||||
mp_obj_list_append(&MP_STATE_PORT(mount_obj_list), self);
|
||||
|
||||
// actually mount it
|
||||
if (f_mount(&self->fatfs, self->path, 1) != FR_OK) {
|
||||
// remove it and raise
|
||||
mp_obj_list_remove(&MP_STATE_PORT(mount_obj_list), self);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
// mount succeeded, increment the count
|
||||
os_num_mounted_devices++;
|
||||
}
|
||||
|
||||
STATIC void unmount (const char *path) {
|
||||
if (FR_OK != f_mount (NULL, path, 1)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
// remove from the list after the actual unmount
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_path(path))) {
|
||||
mp_obj_list_remove(&MP_STATE_PORT(mount_obj_list), mount_obj);
|
||||
os_num_mounted_devices--;
|
||||
} else {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
//
|
||||
|
||||
STATIC const qstr os_uname_info_fields[] = {
|
||||
MP_QSTR_sysname, MP_QSTR_nodename,
|
||||
MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine
|
||||
};
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, MICROPY_PY_SYS_PLATFORM);
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, MICROPY_PY_SYS_PLATFORM);
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, WIPY_SW_VERSION_NUMBER);
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE);
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME);
|
||||
STATIC MP_DEFINE_ATTRTUPLE(
|
||||
os_uname_info_obj,
|
||||
os_uname_info_fields,
|
||||
5,
|
||||
(mp_obj_t)&os_uname_info_sysname_obj,
|
||||
(mp_obj_t)&os_uname_info_nodename_obj,
|
||||
(mp_obj_t)&os_uname_info_release_obj,
|
||||
(mp_obj_t)&os_uname_info_version_obj,
|
||||
(mp_obj_t)&os_uname_info_machine_obj
|
||||
);
|
||||
|
||||
STATIC mp_obj_t os_uname(void) {
|
||||
return (mp_obj_t)&os_uname_info_obj;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_uname_obj, os_uname);
|
||||
|
||||
/// \function chdir(path)
|
||||
/// Change current directory.
|
||||
STATIC mp_obj_t os_chdir(mp_obj_t path_in) {
|
||||
const char *path;
|
||||
path = mp_obj_str_get_str(path_in);
|
||||
|
||||
FRESULT res = f_chdrive(path);
|
||||
|
||||
if (res == FR_OK) {
|
||||
res = f_chdir(path);
|
||||
}
|
||||
|
||||
if (res != FR_OK) {
|
||||
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(os_chdir_obj, os_chdir);
|
||||
|
||||
STATIC mp_obj_t os_getcwd(void) {
|
||||
char buf[MICROPY_ALLOC_PATH_MAX + 1];
|
||||
FRESULT res = f_getcwd(buf, sizeof buf);
|
||||
if (res != FR_OK) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
|
||||
}
|
||||
return mp_obj_new_str(buf, strlen(buf), false);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_getcwd_obj, os_getcwd);
|
||||
|
||||
STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
bool is_str_type = true;
|
||||
const char *path;
|
||||
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
|
||||
|
||||
if (n_args == 1) {
|
||||
if (mp_obj_get_type(args[0]) == &mp_type_bytes) {
|
||||
is_str_type = false;
|
||||
}
|
||||
path = mp_obj_str_get_str(args[0]);
|
||||
} else {
|
||||
path = "";
|
||||
}
|
||||
|
||||
// "hack" to list the root directory
|
||||
if (path[0] == '/' && path[1] == '\0') {
|
||||
// add 'flash' to the list
|
||||
append_dir_item (dir_list, "flash", is_str_type);
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
append_dir_item (dir_list, &mount_obj->path[1], is_str_type);
|
||||
}
|
||||
} else {
|
||||
FRESULT res;
|
||||
DIR dir;
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
char lfn_buf[_MAX_LFN + 1];
|
||||
fno.lfname = lfn_buf;
|
||||
fno.lfsize = sizeof(lfn_buf);
|
||||
#endif
|
||||
|
||||
res = f_opendir(&dir, path); /* Open the directory */
|
||||
if (res != FR_OK) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
for ( ; ; ) {
|
||||
res = f_readdir(&dir, &fno); /* Read a directory item */
|
||||
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */
|
||||
if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */
|
||||
|
||||
#if _USE_LFN
|
||||
char *fn = *fno.lfname ? fno.lfname : fno.fname;
|
||||
#else
|
||||
char *fn = fno.fname;
|
||||
#endif
|
||||
|
||||
// add the entry to the list
|
||||
append_dir_item (dir_list, fn, is_str_type);
|
||||
}
|
||||
f_closedir(&dir);
|
||||
}
|
||||
|
||||
return dir_list;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_listdir_obj, 0, 1, os_listdir);
|
||||
|
||||
STATIC mp_obj_t os_mkdir(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
FRESULT res = f_mkdir(path);
|
||||
switch (res) {
|
||||
case FR_OK:
|
||||
return mp_const_none;
|
||||
case FR_EXIST:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
break;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir);
|
||||
|
||||
STATIC mp_obj_t os_rename(mp_obj_t path_in, mp_obj_t path_out) {
|
||||
const char *old_path = mp_obj_str_get_str(path_in);
|
||||
const char *new_path = mp_obj_str_get_str(path_out);
|
||||
FRESULT res = f_rename(old_path, new_path);
|
||||
switch (res) {
|
||||
case FR_OK:
|
||||
return mp_const_none;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(os_rename_obj, os_rename);
|
||||
|
||||
STATIC mp_obj_t os_remove(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
FRESULT res = f_unlink(path);
|
||||
switch (res) {
|
||||
case FR_OK:
|
||||
return mp_const_none;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove);
|
||||
|
||||
STATIC mp_obj_t os_stat(mp_obj_t path_in) {
|
||||
const char *path = mp_obj_str_get_str(path_in);
|
||||
stoupper((char *)path);
|
||||
|
||||
bool isbuilt_in = false;
|
||||
FILINFO fno;
|
||||
FRESULT res;
|
||||
if (path_equal(path, "/") || path_equal(path, "/SFLASH") || path_equal(path, "/SD")) {
|
||||
#if _USE_LFN
|
||||
fno.lfname = NULL;
|
||||
fno.lfsize = 0;
|
||||
#endif
|
||||
|
||||
// check on the user mounted devices
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||
if (path_equal(path, mount_obj->path)) {
|
||||
isbuilt_in = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (path_equal(path, "/") || path_equal(path, "/flash") || isbuilt_in) {
|
||||
// stat built-in directory
|
||||
if (path[1] == 'S' && !sd_in_root()) {
|
||||
// no /SD directory
|
||||
res = FR_NO_PATH;
|
||||
goto error;
|
||||
}
|
||||
fno.fsize = 0;
|
||||
fno.fdate = 0;
|
||||
fno.ftime = 0;
|
||||
fno.fattrib = AM_DIR;
|
||||
} else {
|
||||
res = f_stat(path, &fno);
|
||||
if (res != FR_OK) {
|
||||
goto error;
|
||||
}
|
||||
fno.fsize = 0;
|
||||
fno.fdate = 0;
|
||||
fno.ftime = 0;
|
||||
fno.fattrib = AM_DIR;
|
||||
} else if ((res = f_stat(path, &fno)) != FR_OK) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
|
||||
}
|
||||
|
||||
mp_obj_tuple_t *t = mp_obj_new_tuple(10, NULL);
|
||||
@@ -256,7 +397,7 @@ STATIC mp_obj_t os_stat(mp_obj_t path_in) {
|
||||
} else {
|
||||
mode |= 0x8000; // stat.S_IFREG
|
||||
}
|
||||
mp_int_t seconds = mod_time_seconds_since_2000(
|
||||
mp_int_t seconds = timeutils_seconds_since_2000(
|
||||
1980 + ((fno.fdate >> 9) & 0x7f),
|
||||
(fno.fdate >> 5) & 0x0f,
|
||||
fno.fdate & 0x1f,
|
||||
@@ -274,26 +415,16 @@ STATIC mp_obj_t os_stat(mp_obj_t path_in) {
|
||||
t->items[7] = mp_obj_new_int(seconds); // st_atime
|
||||
t->items[8] = t->items[7]; // st_mtime
|
||||
t->items[9] = t->items[7]; // st_ctime
|
||||
|
||||
return t;
|
||||
|
||||
error:
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(fresult_to_errno_table[res])));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat);
|
||||
|
||||
/// \function sync()
|
||||
/// Sync all filesystems.
|
||||
STATIC 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);
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
/// \function urandom(n)
|
||||
/// Return a bytes object with n random bytes, generated by the hardware
|
||||
/// random number generator.
|
||||
STATIC mp_obj_t os_urandom(mp_obj_t num) {
|
||||
mp_int_t n = mp_obj_get_int(num);
|
||||
vstr_t vstr;
|
||||
@@ -304,28 +435,157 @@ STATIC mp_obj_t os_urandom(mp_obj_t num) {
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom);
|
||||
#endif
|
||||
|
||||
STATIC mp_obj_t os_mount(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t mount_args[] = {
|
||||
{ MP_QSTR_readonly, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
||||
};
|
||||
|
||||
// parse args
|
||||
mp_obj_t device = pos_args[0];
|
||||
mp_obj_t mount_point = pos_args[1];
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(mount_args)];
|
||||
mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(mount_args), mount_args, args);
|
||||
|
||||
// get the mount point
|
||||
mp_uint_t pathlen;
|
||||
const char *path_in = mp_obj_str_get_data(mount_point, &pathlen);
|
||||
if (pathlen == 0) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
char *path = m_new(char, pathlen + 1);
|
||||
memcpy(path, path_in, pathlen);
|
||||
path[pathlen] = '\0';
|
||||
|
||||
// "remove" any extra slahes at the end
|
||||
while (path[(pathlen - 1)] == '/') {
|
||||
path[--pathlen] = '\0';
|
||||
}
|
||||
|
||||
// is the mount point valid?
|
||||
if (pathlen < 2 || path[0] !='/' || strchr(&path[1], '/')) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
// now mount it
|
||||
mount(device, path, pathlen, args[0].u_bool);
|
||||
|
||||
return mp_const_none;
|
||||
|
||||
invalid_args:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(os_mount_obj, 2, os_mount);
|
||||
|
||||
STATIC mp_obj_t os_unmount(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
|
||||
// '/flash' cannot be unmounted, also not the current working directory
|
||||
if (path_equal(path, "/flash")) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
|
||||
// now unmount it
|
||||
unmount (path);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_unmount_obj, os_unmount);
|
||||
|
||||
STATIC mp_obj_t os_mkfs(mp_obj_t device) {
|
||||
const char *path = "/__mkfs__mnt__";
|
||||
bool unmt = false;
|
||||
FRESULT res;
|
||||
|
||||
if (MP_OBJ_IS_STR_OR_BYTES(device)) {
|
||||
path = mp_obj_str_get_str(device);
|
||||
// otherwise the relative path check will pass...
|
||||
if (path[0] != '/') {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
} else {
|
||||
// mount it and unmount it briefly
|
||||
unmt = true;
|
||||
mount(device, path, strlen(path), false);
|
||||
}
|
||||
|
||||
byte sfd = 0;
|
||||
if (!memcmp(path, "/flash", strlen("/flash"))) {
|
||||
sfd = 1;
|
||||
} else {
|
||||
os_fs_mount_t *mount_obj;
|
||||
if ((mount_obj = osmount_find_by_path(path))) {
|
||||
if (mount_obj->device != (mp_obj_t)&pybsd_obj &&
|
||||
mp_obj_get_int(mp_call_method_n_kw(0, 0, mount_obj->count)) < 2048) {
|
||||
sfd = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now format the device
|
||||
res = f_mkfs(path, sfd, 0);
|
||||
|
||||
if (unmt) {
|
||||
unmount (path);
|
||||
}
|
||||
|
||||
if (res != FR_OK) {
|
||||
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(os_mkfs_obj, os_mkfs);
|
||||
|
||||
STATIC mp_obj_t os_dupterm(uint n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0) {
|
||||
if (MP_STATE_PORT(os_term_dup_obj) == MP_OBJ_NULL) {
|
||||
return mp_const_none;
|
||||
} else {
|
||||
return MP_STATE_PORT(os_term_dup_obj)->stream_o;
|
||||
}
|
||||
} else {
|
||||
mp_obj_t stream_o = args[0];
|
||||
if (stream_o == mp_const_none) {
|
||||
MP_STATE_PORT(os_term_dup_obj) = MP_OBJ_NULL;
|
||||
} else {
|
||||
if (!MP_OBJ_IS_TYPE(stream_o, &pyb_uart_type)) {
|
||||
// must be a stream-like object providing at least read and write methods
|
||||
mp_load_method(stream_o, MP_QSTR_read, os_term_dup_obj.read);
|
||||
mp_load_method(stream_o, MP_QSTR_write, os_term_dup_obj.write);
|
||||
}
|
||||
os_term_dup_obj.stream_o = stream_o;
|
||||
MP_STATE_PORT(os_term_dup_obj) = &os_term_dup_obj;
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_dupterm_obj, 0, 1, os_dupterm);
|
||||
|
||||
STATIC const mp_map_elem_t os_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_uos) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_uos) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_chdir), (mp_obj_t)&os_chdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_getcwd), (mp_obj_t)&os_getcwd_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_listdir), (mp_obj_t)&os_listdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&os_mkdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&os_remove_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_rmdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&os_stat_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&os_remove_obj }, // unlink aliases to remove
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_uname), (mp_obj_t)&os_uname_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_chdir), (mp_obj_t)&os_chdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_getcwd), (mp_obj_t)&os_getcwd_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_listdir), (mp_obj_t)&os_listdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&os_mkdir_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rename), (mp_obj_t)&os_rename_obj},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&os_remove_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_remove_obj }, // rmdir aliases to remove
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&os_stat_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&os_remove_obj }, // unlink aliases to remove
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_urandom), (mp_obj_t)&os_urandom_obj },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj },
|
||||
// MicroPython additions
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&os_mount_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unmount), (mp_obj_t)&os_unmount_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkfs), (mp_obj_t)&os_mkfs_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_dupterm), (mp_obj_t)&os_dupterm_obj },
|
||||
|
||||
/// \constant sep - separation character used in paths
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sep), MP_OBJ_NEW_QSTR(MP_QSTR__slash_) },
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_urandom), (mp_obj_t)&os_urandom_obj },
|
||||
#endif
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sep), MP_OBJ_NEW_QSTR(MP_QSTR__slash_) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table);
|
||||
|
||||
61
cc3200/mods/moduos.h
Normal file
61
cc3200/mods/moduos.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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 MODUOS_H_
|
||||
#define MODUOS_H_
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC TYPES
|
||||
******************************************************************************/
|
||||
typedef struct _os_fs_mount_t {
|
||||
mp_obj_t device;
|
||||
const char *path;
|
||||
mp_uint_t pathlen;
|
||||
mp_obj_t readblocks[4];
|
||||
mp_obj_t writeblocks[4];
|
||||
mp_obj_t sync[2];
|
||||
mp_obj_t count[2];
|
||||
FATFS fatfs;
|
||||
uint8_t vol;
|
||||
} os_fs_mount_t;
|
||||
|
||||
typedef struct _os_term_dup_obj_t {
|
||||
mp_obj_t stream_o;
|
||||
mp_obj_t read[3];
|
||||
mp_obj_t write[3];
|
||||
} os_term_dup_obj_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
void moduos_init0 (void);
|
||||
os_fs_mount_t *osmount_find_by_path (const char *path);
|
||||
os_fs_mount_t *osmount_find_by_volume (uint8_t vol);
|
||||
|
||||
#endif // MODUOS_H_
|
||||
@@ -25,76 +25,145 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <std.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "simplelink.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 "objtuple.h"
|
||||
#include "objlist.h"
|
||||
#include "runtime.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "netutils.h"
|
||||
#include "modnetwork.h"
|
||||
#include "modwlan.h"
|
||||
#include "modusocket.h"
|
||||
#include "mpexception.h"
|
||||
#include "mpstate.h"
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define MOD_NETWORK_MAX_SOCKETS 10
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE TYPES
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
int16_t sd;
|
||||
bool user;
|
||||
} modusocket_sock_t;
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC const mp_obj_type_t socket_type;
|
||||
STATIC OsiLockObj_t modusocket_LockObj;
|
||||
STATIC modusocket_sock_t modusocket_sockets[MOD_NETWORK_MAX_SOCKETS] = {{.sd = -1}, {.sd = -1}, {.sd = -1}, {.sd = -1}, {.sd = -1},
|
||||
{.sd = -1}, {.sd = -1}, {.sd = -1}, {.sd = -1}, {.sd = -1}};
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
__attribute__ ((section (".boot")))
|
||||
void modusocket_pre_init (void) {
|
||||
// create the wlan lock
|
||||
ASSERT(OSI_OK == sl_LockObjCreate(&modusocket_LockObj, "SockLock"));
|
||||
sl_LockObjUnlock (&modusocket_LockObj);
|
||||
}
|
||||
|
||||
void modusocket_socket_add (int16_t sd, bool user) {
|
||||
sl_LockObjLock (&modusocket_LockObj, SL_OS_WAIT_FOREVER);
|
||||
for (int i = 0; i < MOD_NETWORK_MAX_SOCKETS; i++) {
|
||||
if (modusocket_sockets[i].sd < 0) {
|
||||
modusocket_sockets[i].sd = sd;
|
||||
modusocket_sockets[i].user = user;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sl_LockObjUnlock (&modusocket_LockObj);
|
||||
}
|
||||
|
||||
void modusocket_socket_delete (int16_t sd) {
|
||||
sl_LockObjLock (&modusocket_LockObj, SL_OS_WAIT_FOREVER);
|
||||
for (int i = 0; i < MOD_NETWORK_MAX_SOCKETS; i++) {
|
||||
if (modusocket_sockets[i].sd == sd) {
|
||||
modusocket_sockets[i].sd = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sl_LockObjUnlock (&modusocket_LockObj);
|
||||
}
|
||||
|
||||
void modusocket_enter_sleep (void) {
|
||||
fd_set socketset;
|
||||
int16_t maxfd = 0;
|
||||
|
||||
for (int i = 0; i < MOD_NETWORK_MAX_SOCKETS; i++) {
|
||||
int16_t sd;
|
||||
if ((sd = modusocket_sockets[i].sd) >= 0) {
|
||||
FD_SET(sd, &socketset);
|
||||
maxfd = (maxfd > sd) ? maxfd : sd;
|
||||
}
|
||||
}
|
||||
|
||||
// wait for any of the sockets to become ready...
|
||||
sl_Select(maxfd + 1, &socketset, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void modusocket_close_all_user_sockets (void) {
|
||||
sl_LockObjLock (&modusocket_LockObj, SL_OS_WAIT_FOREVER);
|
||||
for (int i = 0; i < MOD_NETWORK_MAX_SOCKETS; i++) {
|
||||
if (modusocket_sockets[i].sd >= 0 && modusocket_sockets[i].user) {
|
||||
sl_Close(modusocket_sockets[i].sd);
|
||||
modusocket_sockets[i].sd = -1;
|
||||
}
|
||||
}
|
||||
sl_LockObjUnlock (&modusocket_LockObj);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// socket class
|
||||
|
||||
STATIC const mp_obj_type_t socket_type;
|
||||
|
||||
// constructor socket(family=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP, fileno=None)
|
||||
STATIC mp_obj_t socket_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, 4, false);
|
||||
|
||||
// create socket object (not bound to any NIC yet)
|
||||
// create socket object
|
||||
mod_network_socket_obj_t *s = m_new_obj_with_finaliser(mod_network_socket_obj_t);
|
||||
s->base.type = (mp_obj_t)&socket_type;
|
||||
s->nic = MP_OBJ_NULL;
|
||||
s->nic_type = NULL;
|
||||
s->u_param.domain = AF_INET;
|
||||
s->u_param.type = SOCK_STREAM;
|
||||
s->u_param.proto = IPPROTO_TCP;
|
||||
s->u_param.fileno = -1;
|
||||
if (n_args >= 1) {
|
||||
s->u_param.domain = mp_obj_get_int(args[0]);
|
||||
if (n_args >= 2) {
|
||||
s->u_param.type = mp_obj_get_int(args[1]);
|
||||
if (n_args >= 3) {
|
||||
s->u_param.proto = mp_obj_get_int(args[2]);
|
||||
if (n_args == 4) {
|
||||
s->u_param.fileno = mp_obj_get_int(args[3]);
|
||||
s->sock_base.u_param.domain = AF_INET;
|
||||
s->sock_base.u_param.type = SOCK_STREAM;
|
||||
s->sock_base.u_param.proto = IPPROTO_TCP;
|
||||
s->sock_base.u_param.fileno = -1;
|
||||
s->sock_base.has_timeout = false;
|
||||
s->sock_base.cert_req = false;
|
||||
|
||||
if (n_args > 0) {
|
||||
s->sock_base.u_param.domain = mp_obj_get_int(args[0]);
|
||||
if (n_args > 1) {
|
||||
s->sock_base.u_param.type = mp_obj_get_int(args[1]);
|
||||
if (n_args > 2) {
|
||||
s->sock_base.u_param.proto = mp_obj_get_int(args[2]);
|
||||
if (n_args > 3) {
|
||||
s->sock_base.u_param.fileno = mp_obj_get_int(args[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create the socket
|
||||
int _errno;
|
||||
if (wlan_socket_socket(s, &_errno) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
STATIC void socket_select_nic(mod_network_socket_obj_t *self, const byte *ip) {
|
||||
if (self->nic == MP_OBJ_NULL) {
|
||||
// select NIC based on IP
|
||||
self->nic = mod_network_find_nic(ip);
|
||||
self->nic_type = (mod_network_nic_type_t*)mp_obj_get_type(self->nic);
|
||||
|
||||
// call the NIC to open the socket
|
||||
int _errno;
|
||||
if (self->nic_type->socket(self, &_errno) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
|
||||
}
|
||||
}
|
||||
}
|
||||
// method socket.close()
|
||||
STATIC mp_obj_t socket_close(mp_obj_t self_in) {
|
||||
mod_network_socket_obj_t *self = self_in;
|
||||
if (self->nic != MP_OBJ_NULL) {
|
||||
self->nic_type->close(self);
|
||||
}
|
||||
wlan_socket_close(self);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_close_obj, socket_close);
|
||||
@@ -105,67 +174,59 @@ STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) {
|
||||
|
||||
// get address
|
||||
uint8_t ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
|
||||
mp_uint_t port = mod_network_parse_inet_addr(addr_in, ip);
|
||||
|
||||
// check if we need to select a NIC
|
||||
socket_select_nic(self, ip);
|
||||
mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_LITTLE);
|
||||
|
||||
// call the NIC to bind the socket
|
||||
int _errno;
|
||||
if (self->nic_type->bind(self, ip, port, &_errno) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
|
||||
if (wlan_socket_bind(self, ip, port, &_errno) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_bind_obj, socket_bind);
|
||||
|
||||
// method socket.listen(backlog)
|
||||
STATIC mp_obj_t socket_listen(mp_obj_t self_in, mp_obj_t backlog) {
|
||||
mod_network_socket_obj_t *self = self_in;
|
||||
// method socket.listen([backlog])
|
||||
STATIC mp_obj_t socket_listen(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
mod_network_socket_obj_t *self = args[0];
|
||||
|
||||
if (self->nic == MP_OBJ_NULL) {
|
||||
// not connected
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ENOTCONN)));
|
||||
int32_t backlog = 0;
|
||||
if (n_args > 1) {
|
||||
backlog = mp_obj_get_int(args[1]);
|
||||
backlog = (backlog < 0) ? 0 : backlog;
|
||||
}
|
||||
|
||||
int _errno;
|
||||
if (self->nic_type->listen(self, mp_obj_get_int(backlog), &_errno) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
|
||||
if (wlan_socket_listen(self, backlog, &_errno) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_listen_obj, socket_listen);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_listen_obj, 1, 2, socket_listen);
|
||||
|
||||
// method socket.accept()
|
||||
STATIC mp_obj_t socket_accept(mp_obj_t self_in) {
|
||||
mod_network_socket_obj_t *self = self_in;
|
||||
|
||||
// create new socket object
|
||||
// starts with empty NIC so that finaliser doesn't run close() method if accept() fails
|
||||
mod_network_socket_obj_t *socket2 = m_new_obj_with_finaliser(mod_network_socket_obj_t);
|
||||
socket2->base.type = (mp_obj_t)&socket_type;
|
||||
socket2->nic = MP_OBJ_NULL;
|
||||
socket2->nic_type = NULL;
|
||||
// the new socket inherits all properties from its parent
|
||||
memcpy (socket2, self, sizeof(mod_network_socket_obj_t));
|
||||
|
||||
// accept incoming connection
|
||||
// accept the incoming connection
|
||||
uint8_t ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
|
||||
mp_uint_t port;
|
||||
int _errno;
|
||||
if (self->nic_type->accept(self, socket2, ip, &port, &_errno) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
|
||||
if (wlan_socket_accept(self, socket2, ip, &port, &_errno) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
|
||||
// new socket has valid state, so set the NIC to the same as parent
|
||||
socket2->nic = self->nic;
|
||||
socket2->nic_type = self->nic_type;
|
||||
// add the socket to the list
|
||||
modusocket_socket_add(socket2->sock_base.sd, true);
|
||||
|
||||
// make the return value
|
||||
mp_obj_tuple_t *client = mp_obj_new_tuple(2, NULL);
|
||||
client->items[0] = socket2;
|
||||
client->items[1] = mod_network_format_inet_addr(ip, port);
|
||||
|
||||
client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_LITTLE);
|
||||
return client;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_accept_obj, socket_accept);
|
||||
@@ -176,17 +237,16 @@ STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
|
||||
|
||||
// get address
|
||||
uint8_t ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
|
||||
mp_uint_t port = mod_network_parse_inet_addr(addr_in, ip);
|
||||
mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_LITTLE);
|
||||
|
||||
// check if we need to select a NIC
|
||||
socket_select_nic(self, ip);
|
||||
|
||||
// call the NIC to connect the socket
|
||||
// connect the socket
|
||||
int _errno;
|
||||
if (self->nic_type->connect(self, ip, port, &_errno) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
|
||||
if (wlan_socket_connect(self, ip, port, &_errno) != 0) {
|
||||
if (!self->sock_base.cert_req && _errno == SL_ESECSNOVERIFY) {
|
||||
return mp_const_none;
|
||||
}
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect);
|
||||
@@ -194,16 +254,12 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect);
|
||||
// method socket.send(bytes)
|
||||
STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
|
||||
mod_network_socket_obj_t *self = self_in;
|
||||
if (self->nic == MP_OBJ_NULL) {
|
||||
// not connected
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EBADF)));
|
||||
}
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
|
||||
int _errno;
|
||||
mp_uint_t ret = self->nic_type->send(self, bufinfo.buf, bufinfo.len, &_errno);
|
||||
if (ret == -1) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
|
||||
mp_int_t ret = wlan_socket_send(self, bufinfo.buf, bufinfo.len, &_errno);
|
||||
if (ret < 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
return mp_obj_new_int_from_uint(ret);
|
||||
}
|
||||
@@ -212,17 +268,16 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_send_obj, socket_send);
|
||||
// method socket.recv(bufsize)
|
||||
STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
|
||||
mod_network_socket_obj_t *self = self_in;
|
||||
if (self->nic == MP_OBJ_NULL) {
|
||||
// not connected
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ENOTCONN)));
|
||||
}
|
||||
mp_int_t len = mp_obj_get_int(len_in);
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, len);
|
||||
int _errno;
|
||||
mp_uint_t ret = self->nic_type->recv(self, (byte*)vstr.buf, len, &_errno);
|
||||
if (ret == -1) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
|
||||
mp_int_t ret = wlan_socket_recv(self, (byte*)vstr.buf, len, &_errno);
|
||||
if (ret < 0) {
|
||||
if (_errno == EAGAIN && self->sock_base.has_timeout) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TimeoutError, "timed out"));
|
||||
}
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
if (ret == 0) {
|
||||
return mp_const_empty_bytes;
|
||||
@@ -243,18 +298,14 @@ STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_
|
||||
|
||||
// get address
|
||||
uint8_t ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
|
||||
mp_uint_t port = mod_network_parse_inet_addr(addr_in, ip);
|
||||
mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_LITTLE);
|
||||
|
||||
// check if we need to select a NIC
|
||||
socket_select_nic(self, ip);
|
||||
|
||||
// call the NIC to sendto
|
||||
// call the nic to sendto
|
||||
int _errno;
|
||||
mp_int_t ret = self->nic_type->sendto(self, bufinfo.buf, bufinfo.len, ip, port, &_errno);
|
||||
if (ret == -1) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
|
||||
mp_int_t ret = wlan_socket_sendto(self, bufinfo.buf, bufinfo.len, ip, port, &_errno);
|
||||
if (ret < 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
|
||||
return mp_obj_new_int(ret);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(socket_sendto_obj, socket_sendto);
|
||||
@@ -262,18 +313,17 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(socket_sendto_obj, socket_sendto);
|
||||
// method socket.recvfrom(bufsize)
|
||||
STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) {
|
||||
mod_network_socket_obj_t *self = self_in;
|
||||
if (self->nic == MP_OBJ_NULL) {
|
||||
// not connected
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ENOTCONN)));
|
||||
}
|
||||
vstr_t vstr;
|
||||
vstr_init_len(&vstr, mp_obj_get_int(len_in));
|
||||
byte ip[4];
|
||||
mp_uint_t port;
|
||||
int _errno;
|
||||
mp_int_t ret = self->nic_type->recvfrom(self, (byte*)vstr.buf, vstr.len, ip, &port, &_errno);
|
||||
if (ret == -1) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
|
||||
mp_int_t ret = wlan_socket_recvfrom(self, (byte*)vstr.buf, vstr.len, ip, &port, &_errno);
|
||||
if (ret < 0) {
|
||||
if (_errno == EAGAIN && self->sock_base.has_timeout) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TimeoutError, "timed out"));
|
||||
}
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
mp_obj_t tuple[2];
|
||||
if (ret == 0) {
|
||||
@@ -283,7 +333,7 @@ STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) {
|
||||
vstr.buf[vstr.len] = '\0';
|
||||
tuple[0] = mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
tuple[1] = mod_network_format_inet_addr(ip, port);
|
||||
tuple[1] = netutils_format_inet_addr(ip, port, NETUTILS_LITTLE);
|
||||
return mp_obj_new_tuple(2, tuple);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recvfrom_obj, socket_recvfrom);
|
||||
@@ -299,7 +349,7 @@ STATIC mp_obj_t socket_setsockopt(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
mp_uint_t optlen;
|
||||
mp_int_t val;
|
||||
if (mp_obj_is_integer(args[3])) {
|
||||
val = mp_obj_int_get_truncated(args[3]);
|
||||
val = mp_obj_get_int_truncated(args[3]);
|
||||
optval = &val;
|
||||
optlen = sizeof(val);
|
||||
} else {
|
||||
@@ -310,10 +360,9 @@ STATIC mp_obj_t socket_setsockopt(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
}
|
||||
|
||||
int _errno;
|
||||
if (self->nic_type->setsockopt(self, level, opt, optval, optlen, &_errno) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
|
||||
if (wlan_socket_setsockopt(self, level, opt, optval, optlen, &_errno) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_setsockopt_obj, 4, 4, socket_setsockopt);
|
||||
@@ -324,19 +373,15 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_setsockopt_obj, 4, 4, socket_s
|
||||
// otherwise, timeout is in seconds
|
||||
STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) {
|
||||
mod_network_socket_obj_t *self = self_in;
|
||||
if (self->nic == MP_OBJ_NULL) {
|
||||
// not connected
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ENOTCONN)));
|
||||
}
|
||||
mp_uint_t timeout;
|
||||
if (timeout_in == mp_const_none) {
|
||||
timeout = -1;
|
||||
} else {
|
||||
timeout = 1000 * mp_obj_get_int(timeout_in);
|
||||
timeout = mp_obj_get_int(timeout_in);
|
||||
}
|
||||
int _errno;
|
||||
if (self->nic_type->settimeout(self, timeout, &_errno) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
|
||||
if (wlan_socket_settimeout(self, timeout, &_errno) != 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
@@ -352,30 +397,84 @@ STATIC mp_obj_t socket_setblocking(mp_obj_t self_in, mp_obj_t blocking) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_setblocking_obj, socket_setblocking);
|
||||
|
||||
STATIC mp_obj_t socket_makefile(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
// TODO: CPython explicitly says that closing the returned object doesn't
|
||||
// close the original socket (Python2 at all says that fd is dup()ed). But
|
||||
// we save on the bloat.
|
||||
mod_network_socket_obj_t *self = args[0];
|
||||
if (n_args > 1) {
|
||||
const char *mode = mp_obj_str_get_str(args[1]);
|
||||
if (strcmp(mode, "rb") && strcmp(mode, "wb")) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_makefile_obj, 1, 6, socket_makefile);
|
||||
|
||||
STATIC const mp_map_elem_t socket_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&socket_close_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&socket_close_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_bind), (mp_obj_t)&socket_bind_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_listen), (mp_obj_t)&socket_listen_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_accept), (mp_obj_t)&socket_accept_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&socket_connect_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&socket_send_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&socket_recv_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sendto), (mp_obj_t)&socket_sendto_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_recvfrom), (mp_obj_t)&socket_recvfrom_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_setsockopt), (mp_obj_t)&socket_setsockopt_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_settimeout), (mp_obj_t)&socket_settimeout_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_setblocking), (mp_obj_t)&socket_setblocking_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&socket_close_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&socket_close_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_bind), (mp_obj_t)&socket_bind_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_listen), (mp_obj_t)&socket_listen_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_accept), (mp_obj_t)&socket_accept_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&socket_connect_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&socket_send_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sendall), (mp_obj_t)&socket_send_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&socket_recv_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sendto), (mp_obj_t)&socket_sendto_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_recvfrom), (mp_obj_t)&socket_recvfrom_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_setsockopt), (mp_obj_t)&socket_setsockopt_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_settimeout), (mp_obj_t)&socket_settimeout_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_setblocking), (mp_obj_t)&socket_setblocking_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_makefile), (mp_obj_t)&socket_makefile_obj },
|
||||
|
||||
// stream methods
|
||||
{ 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_readinto), (mp_obj_t)&mp_stream_readinto_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 },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(socket_locals_dict, socket_locals_dict_table);
|
||||
MP_DEFINE_CONST_DICT(socket_locals_dict, socket_locals_dict_table);
|
||||
|
||||
mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
|
||||
STATIC mp_uint_t socket_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) {
|
||||
mod_network_socket_obj_t *self = self_in;
|
||||
return self->nic_type->ioctl(self, request, arg, errcode);
|
||||
mp_int_t ret = wlan_socket_recv(self, buf, size, errcode);
|
||||
if (ret < 0) {
|
||||
// we need to ignore the socket closed error here because a readall() or read() without params
|
||||
// only returns when the socket is closed by the other end
|
||||
if (*errcode != SL_ESECCLOSED) {
|
||||
ret = MP_STREAM_ERROR;
|
||||
// needed to convert simplelink's negative error codes to POSIX
|
||||
(*errcode) *= -1;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC const mp_stream_p_t socket_stream_p = {
|
||||
STATIC mp_uint_t socket_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) {
|
||||
mod_network_socket_obj_t *self = self_in;
|
||||
mp_int_t ret = wlan_socket_send(self, buf, size, errcode);
|
||||
if (ret < 0) {
|
||||
ret = MP_STREAM_ERROR;
|
||||
// needed to convert simplelink's negative error codes to POSIX
|
||||
(*errcode) *= -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
|
||||
mod_network_socket_obj_t *self = self_in;
|
||||
return wlan_socket_ioctl(self, request, arg, errcode);
|
||||
}
|
||||
|
||||
const mp_stream_p_t socket_stream_p = {
|
||||
.read = socket_read,
|
||||
.write = socket_write,
|
||||
.ioctl = socket_ioctl,
|
||||
.is_text = false,
|
||||
};
|
||||
@@ -398,28 +497,19 @@ STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {
|
||||
const char *host = mp_obj_str_get_data(host_in, &hlen);
|
||||
mp_int_t port = mp_obj_get_int(port_in);
|
||||
|
||||
// find a NIC that can do a name lookup
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) {
|
||||
mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i];
|
||||
mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic);
|
||||
if (nic_type->gethostbyname != NULL) {
|
||||
// Only IPv4 is supported
|
||||
uint8_t out_ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
|
||||
int32_t result = nic_type->gethostbyname(nic, host, hlen, out_ip, AF_INET);
|
||||
if (result != 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(result)));
|
||||
}
|
||||
mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL);
|
||||
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(AF_INET);
|
||||
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(SOCK_STREAM);
|
||||
tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0);
|
||||
tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_);
|
||||
tuple->items[4] = mod_network_format_inet_addr(out_ip, port);
|
||||
return mp_obj_new_list(1, (mp_obj_t*)&tuple);
|
||||
}
|
||||
// ipv4 only
|
||||
uint8_t out_ip[MOD_NETWORK_IPV4ADDR_BUF_SIZE];
|
||||
int32_t result = wlan_gethostbyname(host, hlen, out_ip, AF_INET);
|
||||
if (result < 0) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-result)));
|
||||
}
|
||||
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL);
|
||||
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(AF_INET);
|
||||
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(SOCK_STREAM);
|
||||
tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0);
|
||||
tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_);
|
||||
tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_LITTLE);
|
||||
return mp_obj_new_list(1, (mp_obj_t*)&tuple);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_usocket_getaddrinfo_obj, mod_usocket_getaddrinfo);
|
||||
|
||||
@@ -429,17 +519,19 @@ STATIC const mp_map_elem_t mp_module_usocket_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&socket_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_getaddrinfo), (mp_obj_t)&mod_usocket_getaddrinfo_obj },
|
||||
|
||||
// class exceptions
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_error), (mp_obj_t)&mp_type_OSError },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_timeout), (mp_obj_t)&mp_type_TimeoutError },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_AF_INET), MP_OBJ_NEW_SMALL_INT(AF_INET) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_AF_INET6), MP_OBJ_NEW_SMALL_INT(AF_INET6) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_STREAM), MP_OBJ_NEW_SMALL_INT(SOCK_STREAM) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_DGRAM), MP_OBJ_NEW_SMALL_INT(SOCK_DGRAM) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SOCK_RAW), MP_OBJ_NEW_SMALL_INT(SOCK_RAW) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_SEC), MP_OBJ_NEW_SMALL_INT(SL_SEC_SOCKET) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_TCP), MP_OBJ_NEW_SMALL_INT(IPPROTO_TCP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_UDP), MP_OBJ_NEW_SMALL_INT(IPPROTO_UDP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IPPROTO_RAW), MP_OBJ_NEW_SMALL_INT(IPPROTO_RAW) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_usocket_globals, mp_module_usocket_globals_table);
|
||||
|
||||
39
cc3200/mods/modusocket.h
Normal file
39
cc3200/mods/modusocket.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 MODUSOCKET_H_
|
||||
#define MODUSOCKET_H_
|
||||
|
||||
extern const mp_obj_dict_t socket_locals_dict;
|
||||
extern const mp_stream_p_t socket_stream_p;
|
||||
|
||||
extern void modusocket_pre_init (void);
|
||||
extern void modusocket_socket_add (int16_t sd, bool user);
|
||||
extern void modusocket_socket_delete (int16_t sd);
|
||||
extern void modusocket_enter_sleep (void);
|
||||
extern void modusocket_close_all_user_sockets (void);
|
||||
|
||||
#endif /* MODUSOCKET_H_ */
|
||||
155
cc3200/mods/modussl.c
Normal file
155
cc3200/mods/modussl.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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 <std.h>
|
||||
|
||||
#include "simplelink.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/obj.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "modnetwork.h"
|
||||
#include "modusocket.h"
|
||||
#include "mpexception.h"
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define SSL_CERT_NONE (0)
|
||||
#define SSL_CERT_OPTIONAL (1)
|
||||
#define SSL_CERT_REQUIRED (2)
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
******************************************************************************/
|
||||
typedef struct _mp_obj_ssl_socket_t {
|
||||
mp_obj_base_t base;
|
||||
mod_network_socket_base_t sock_base;
|
||||
mp_obj_t o_sock;
|
||||
} mp_obj_ssl_socket_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC const mp_obj_type_t ssl_socket_type;
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings; SSL class
|
||||
|
||||
// ssl sockets inherit from normal socket, so we take its
|
||||
// locals and stream methods
|
||||
STATIC const mp_obj_type_t ssl_socket_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_ussl,
|
||||
.getiter = NULL,
|
||||
.iternext = NULL,
|
||||
.stream_p = &socket_stream_p,
|
||||
.locals_dict = (mp_obj_t)&socket_locals_dict,
|
||||
};
|
||||
|
||||
STATIC mp_obj_t mod_ssl_wrap_socket(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_sock, MP_ARG_REQUIRED | MP_ARG_OBJ, },
|
||||
{ MP_QSTR_keyfile, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_certfile, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_server_side, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
||||
{ MP_QSTR_cert_reqs, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SSL_CERT_NONE} },
|
||||
{ MP_QSTR_ca_certs, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
};
|
||||
|
||||
// parse arguments
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
// chech if ca validation is required
|
||||
if (args[4].u_int != SSL_CERT_NONE && args[5].u_obj == mp_const_none) {
|
||||
goto arg_error;
|
||||
}
|
||||
|
||||
// retrieve the file paths (with an 6 byte offset in order to strip it from the '/flash' prefix)
|
||||
const char *keyfile = (args[1].u_obj == mp_const_none) ? NULL : &(mp_obj_str_get_str(args[1].u_obj)[6]);
|
||||
const char *certfile = (args[2].u_obj == mp_const_none) ? NULL : &(mp_obj_str_get_str(args[2].u_obj)[6]);
|
||||
const char *cafile = (args[5].u_obj == mp_const_none || args[4].u_int != SSL_CERT_REQUIRED) ?
|
||||
NULL : &(mp_obj_str_get_str(args[5].u_obj)[6]);
|
||||
|
||||
// server side requires both certfile and keyfile
|
||||
if (args[3].u_bool && (!keyfile || !certfile)) {
|
||||
goto arg_error;
|
||||
}
|
||||
|
||||
_i16 sd = ((mod_network_socket_obj_t *)args[0].u_obj)->sock_base.sd;
|
||||
_i16 _errno;
|
||||
if (keyfile && (_errno = sl_SetSockOpt(sd, SL_SOL_SOCKET, SL_SO_SECURE_FILES_PRIVATE_KEY_FILE_NAME, keyfile, strlen(keyfile))) < 0) {
|
||||
goto socket_error;
|
||||
}
|
||||
if (certfile && (_errno = sl_SetSockOpt(sd, SL_SOL_SOCKET, SL_SO_SECURE_FILES_CERTIFICATE_FILE_NAME, certfile, strlen(certfile))) < 0) {
|
||||
goto socket_error;
|
||||
}
|
||||
if (cafile && (_errno = sl_SetSockOpt(sd, SL_SOL_SOCKET, SL_SO_SECURE_FILES_CA_FILE_NAME, cafile, strlen(cafile))) < 0) {
|
||||
goto socket_error;
|
||||
}
|
||||
|
||||
// create the ssl socket
|
||||
mp_obj_ssl_socket_t *ssl_sock = m_new_obj(mp_obj_ssl_socket_t);
|
||||
// ssl sockets inherit all properties from the original socket
|
||||
memcpy (&ssl_sock->sock_base, &((mod_network_socket_obj_t *)args[0].u_obj)->sock_base, sizeof(mod_network_socket_base_t));
|
||||
ssl_sock->base.type = &ssl_socket_type;
|
||||
ssl_sock->sock_base.cert_req = (args[4].u_int == SSL_CERT_REQUIRED) ? true : false;
|
||||
ssl_sock->o_sock = args[0].u_obj;
|
||||
|
||||
return ssl_sock;
|
||||
|
||||
socket_error:
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(_errno)));
|
||||
|
||||
arg_error:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_wrap_socket_obj, 0, mod_ssl_wrap_socket);
|
||||
|
||||
STATIC const mp_map_elem_t mp_module_ussl_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_ussl) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_wrap_socket), (mp_obj_t)&mod_ssl_wrap_socket_obj },
|
||||
|
||||
// class exceptions
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SSLError), (mp_obj_t)&mp_type_OSError },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_CERT_NONE), MP_OBJ_NEW_SMALL_INT(SSL_CERT_NONE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_CERT_OPTIONAL), MP_OBJ_NEW_SMALL_INT(SSL_CERT_OPTIONAL) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_CERT_REQUIRED), MP_OBJ_NEW_SMALL_INT(SSL_CERT_REQUIRED) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_ussl_globals, mp_module_ussl_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_ussl = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_ussl,
|
||||
.globals = (mp_obj_dict_t*)&mp_module_ussl_globals,
|
||||
};
|
||||
|
||||
@@ -28,146 +28,36 @@
|
||||
#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 "modutime.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/smallint.h"
|
||||
#include "timeutils.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "rom_map.h"
|
||||
#include "prcm.h"
|
||||
#include "systick.h"
|
||||
#include "pybrtc.h"
|
||||
#include "mpsystick.h"
|
||||
#include "mpexception.h"
|
||||
|
||||
|
||||
// LEAPOCH corresponds to 2000-03-01, which is a mod-400 year, immediately
|
||||
// after Feb 29. We calculate seconds as a signed integer relative to that.
|
||||
//
|
||||
// Our timebase is relative to 2000-01-01.
|
||||
|
||||
#define LEAPOCH ((31 + 29) * 86400)
|
||||
|
||||
#define DAYS_PER_400Y (365*400 + 97)
|
||||
#define DAYS_PER_100Y (365*100 + 24)
|
||||
#define DAYS_PER_4Y (365*4 + 1)
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
/// \module time - time related functions
|
||||
///
|
||||
/// The `time` module provides functions for getting the current time and date,
|
||||
/// and for sleeping.
|
||||
|
||||
STATIC const uint16_t days_since_jan1[]= { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
|
||||
|
||||
STATIC bool is_leap_year(mp_uint_t year) {
|
||||
return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
|
||||
}
|
||||
|
||||
// Month is one based
|
||||
STATIC mp_uint_t mod_time_days_in_month(mp_uint_t year, mp_uint_t month) {
|
||||
mp_uint_t mdays = days_since_jan1[month] - days_since_jan1[month - 1];
|
||||
if (month == 2 && is_leap_year(year)) {
|
||||
mdays++;
|
||||
}
|
||||
return mdays;
|
||||
}
|
||||
|
||||
// compute the day of the year, between 1 and 366
|
||||
// month should be between 1 and 12, date should start at 1
|
||||
STATIC mp_uint_t mod_time_year_day(mp_uint_t year, mp_uint_t month, mp_uint_t date) {
|
||||
mp_uint_t yday = days_since_jan1[month - 1] + date;
|
||||
if (month >= 3 && is_leap_year(year)) {
|
||||
yday += 1;
|
||||
}
|
||||
return yday;
|
||||
}
|
||||
|
||||
// returns the number of seconds, as an integer, since 2000-01-01
|
||||
mp_uint_t mod_time_seconds_since_2000(mp_uint_t year, mp_uint_t month, mp_uint_t date, mp_uint_t hour, mp_uint_t minute, mp_uint_t second) {
|
||||
return
|
||||
second
|
||||
+ minute * 60
|
||||
+ hour * 3600
|
||||
+ (mod_time_year_day(year, month, date) - 1
|
||||
+ ((year - 2000 + 3) / 4) // add a day each 4 years starting with 2001
|
||||
- ((year - 2000 + 99) / 100) // subtract a day each 100 years starting with 2001
|
||||
+ ((year - 2000 + 399) / 400) // add a day each 400 years starting with 2001
|
||||
) * 86400
|
||||
+ (year - 2000) * 31536000;
|
||||
}
|
||||
|
||||
void mod_time_seconds_since_2000_to_struct_time(mp_uint_t t, mod_struct_time *tm) {
|
||||
// The following algorithm was adapted from musl's __secs_to_tm and adapted
|
||||
// for differences in Micro Python's timebase.
|
||||
|
||||
mp_int_t seconds = t - LEAPOCH;
|
||||
|
||||
mp_int_t days = seconds / 86400;
|
||||
seconds %= 86400;
|
||||
tm->tm_hour = seconds / 3600;
|
||||
tm->tm_min = seconds / 60 % 60;
|
||||
tm->tm_sec = seconds % 60;
|
||||
|
||||
mp_int_t wday = (days + 2) % 7; // Mar 1, 2000 was a Wednesday (2)
|
||||
if (wday < 0) {
|
||||
wday += 7;
|
||||
}
|
||||
tm->tm_wday = wday;
|
||||
|
||||
mp_int_t qc_cycles = days / DAYS_PER_400Y;
|
||||
days %= DAYS_PER_400Y;
|
||||
if (days < 0) {
|
||||
days += DAYS_PER_400Y;
|
||||
qc_cycles--;
|
||||
}
|
||||
mp_int_t c_cycles = days / DAYS_PER_100Y;
|
||||
if (c_cycles == 4) {
|
||||
c_cycles--;
|
||||
}
|
||||
days -= (c_cycles * DAYS_PER_100Y);
|
||||
|
||||
mp_int_t q_cycles = days / DAYS_PER_4Y;
|
||||
if (q_cycles == 25) {
|
||||
q_cycles--;
|
||||
}
|
||||
days -= q_cycles * DAYS_PER_4Y;
|
||||
|
||||
mp_int_t years = days / 365;
|
||||
if (years == 4) {
|
||||
years--;
|
||||
}
|
||||
days -= (years * 365);
|
||||
|
||||
tm->tm_year = 2000 + years + 4 * q_cycles + 100 * c_cycles + 400 * qc_cycles;
|
||||
|
||||
// Note: days_in_month[0] corresponds to March
|
||||
STATIC const int8_t days_in_month[] = {31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29};
|
||||
|
||||
mp_int_t month;
|
||||
for (month = 0; days_in_month[month] <= days; month++) {
|
||||
days -= days_in_month[month];
|
||||
}
|
||||
|
||||
tm->tm_mon = month + 2;
|
||||
if (tm->tm_mon >= 12) {
|
||||
tm->tm_mon -= 12;
|
||||
tm->tm_year++;
|
||||
}
|
||||
tm->tm_mday = days + 1; // Make one based
|
||||
tm->tm_mon++; // Make one based
|
||||
|
||||
tm->tm_yday = mod_time_year_day(tm->tm_year, tm->tm_mon, tm->tm_mday);
|
||||
}
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
/// \function localtime([secs])
|
||||
/// Convert a time expressed in seconds since Jan 1, 2000 into an 8-tuple which
|
||||
/// contains: (year, month, mday, hour, minute, second, weekday, yearday)
|
||||
/// If secs is not provided or None, then the current time from the RTC is used.
|
||||
/// year includes the century (for example 2014)
|
||||
/// year includes the century (for example 2015)
|
||||
/// month is 1-12
|
||||
/// mday is 1-31
|
||||
/// hour is 0-23
|
||||
@@ -177,30 +67,25 @@ void mod_time_seconds_since_2000_to_struct_time(mp_uint_t t, mod_struct_time *tm
|
||||
/// yearday is 1-366
|
||||
STATIC mp_obj_t time_localtime(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0 || args[0] == mp_const_none) {
|
||||
mod_struct_time tm;
|
||||
uint32_t seconds;
|
||||
uint16_t mseconds;
|
||||
|
||||
// get the seconds and the milliseconds from the RTC
|
||||
MAP_PRCMRTCGet(&seconds, &mseconds);
|
||||
mseconds = RTC_CYCLES_U16MS(mseconds);
|
||||
mod_time_seconds_since_2000_to_struct_time(seconds, &tm);
|
||||
timeutils_struct_time_t tm;
|
||||
|
||||
// get the seconds from the RTC
|
||||
timeutils_seconds_since_2000_to_struct_time(pyb_rtc_get_seconds(), &tm);
|
||||
mp_obj_t tuple[8] = {
|
||||
mp_obj_new_int(tm.tm_year),
|
||||
mp_obj_new_int(tm.tm_mon),
|
||||
mp_obj_new_int(tm.tm_mday),
|
||||
mp_obj_new_int(tm.tm_wday),
|
||||
mp_obj_new_int(tm.tm_hour),
|
||||
mp_obj_new_int(tm.tm_min),
|
||||
mp_obj_new_int(tm.tm_sec),
|
||||
mp_obj_new_int(mseconds)
|
||||
mp_obj_new_int(tm.tm_wday),
|
||||
mp_obj_new_int(tm.tm_yday)
|
||||
};
|
||||
return mp_obj_new_tuple(8, tuple);
|
||||
} else {
|
||||
mp_int_t seconds = mp_obj_get_int(args[0]);
|
||||
mod_struct_time tm;
|
||||
mod_time_seconds_since_2000_to_struct_time(seconds, &tm);
|
||||
timeutils_struct_time_t tm;
|
||||
timeutils_seconds_since_2000_to_struct_time(seconds, &tm);
|
||||
mp_obj_t tuple[8] = {
|
||||
tuple[0] = mp_obj_new_int(tm.tm_year),
|
||||
tuple[1] = mp_obj_new_int(tm.tm_mon),
|
||||
@@ -216,13 +101,7 @@ STATIC mp_obj_t time_localtime(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(time_localtime_obj, 0, 1, time_localtime);
|
||||
|
||||
|
||||
/// \function mktime()
|
||||
/// This is inverse function of localtime. It's argument is a full 8-tuple
|
||||
/// which expresses a time as per localtime. It returns an integer which is
|
||||
/// the number of seconds since Jan 1, 2000.
|
||||
STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
|
||||
|
||||
mp_uint_t len;
|
||||
mp_obj_t *elem;
|
||||
|
||||
@@ -233,95 +112,84 @@ STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments));
|
||||
}
|
||||
|
||||
mp_int_t year = mp_obj_get_int(elem[0]);
|
||||
mp_int_t month = mp_obj_get_int(elem[1]);
|
||||
mp_int_t mday = mp_obj_get_int(elem[2]);
|
||||
mp_int_t hours = mp_obj_get_int(elem[3]);
|
||||
mp_int_t minutes = mp_obj_get_int(elem[4]);
|
||||
mp_int_t seconds = mp_obj_get_int(elem[5]);
|
||||
|
||||
// Normalize the tuple. This allows things like:
|
||||
//
|
||||
// tm_tomorrow = list(time.localtime())
|
||||
// tm_tomorrow[2] += 1 # Adds 1 to mday
|
||||
// tomorrow = time.mktime(tm_tommorrow)
|
||||
//
|
||||
// And not have to worry about all the weird overflows.
|
||||
//
|
||||
// You can subtract dates/times this way as well.
|
||||
|
||||
minutes += seconds / 60;
|
||||
if ((seconds = seconds % 60) < 0) {
|
||||
seconds += 60;
|
||||
minutes--;
|
||||
}
|
||||
|
||||
hours += minutes / 60;
|
||||
if ((minutes = minutes % 60) < 0) {
|
||||
minutes += 60;
|
||||
hours--;
|
||||
}
|
||||
|
||||
mday += hours / 24;
|
||||
if ((hours = hours % 24) < 0) {
|
||||
hours += 24;
|
||||
mday--;
|
||||
}
|
||||
|
||||
month--; // make month zero based
|
||||
year += month / 12;
|
||||
if ((month = month % 12) < 0) {
|
||||
month += 12;
|
||||
year--;
|
||||
}
|
||||
month++; // back to one based
|
||||
|
||||
while (mday < 1) {
|
||||
if (--month == 0) {
|
||||
month = 12;
|
||||
year--;
|
||||
}
|
||||
mday += mod_time_days_in_month(year, month);
|
||||
}
|
||||
while (mday > mod_time_days_in_month(year, month)) {
|
||||
mday -= mod_time_days_in_month(year, month);
|
||||
if (++month == 13) {
|
||||
month = 1;
|
||||
year++;
|
||||
}
|
||||
}
|
||||
return mp_obj_new_int_from_uint(mod_time_seconds_since_2000(year, month, mday, hours, minutes, seconds));
|
||||
return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]), mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]),
|
||||
mp_obj_get_int(elem[3]), mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5])));
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime);
|
||||
|
||||
STATIC mp_obj_t time_time(void) {
|
||||
return mp_obj_new_int(pyb_rtc_get_seconds());
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time);
|
||||
|
||||
/// \function sleep(milliseconds)
|
||||
/// Sleep for the given number of milliseconds.
|
||||
STATIC mp_obj_t time_sleep(mp_obj_t milliseconds_o) {
|
||||
HAL_Delay(mp_obj_get_int(milliseconds_o));
|
||||
STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) {
|
||||
int32_t sleep_s = mp_obj_get_int(seconds_o);
|
||||
if (sleep_s > 0) {
|
||||
HAL_Delay(sleep_s * 1000);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep);
|
||||
|
||||
/// \function time()
|
||||
/// Returns the number of seconds, as an integer, since 1/1/2000.
|
||||
STATIC mp_obj_t time_time(void) {
|
||||
uint32_t seconds;
|
||||
uint16_t mseconds;
|
||||
|
||||
// get the seconds and the milliseconds from the RTC
|
||||
MAP_PRCMRTCGet(&seconds, &mseconds);
|
||||
return mp_obj_new_int(seconds);
|
||||
STATIC mp_obj_t time_sleep_ms (mp_obj_t ms_in) {
|
||||
mp_int_t ms = mp_obj_get_int(ms_in);
|
||||
if (ms > 0) {
|
||||
HAL_Delay(ms);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_ms_obj, time_sleep_ms);
|
||||
|
||||
STATIC mp_obj_t time_sleep_us (mp_obj_t usec_in) {
|
||||
mp_int_t usec = mp_obj_get_int(usec_in);
|
||||
if (usec > 0) {
|
||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT(usec));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_us_obj, time_sleep_us);
|
||||
|
||||
STATIC mp_obj_t time_ticks_ms(void) {
|
||||
// We want to "cast" the 32 bit unsigned into a 30-bit small-int
|
||||
return MP_OBJ_NEW_SMALL_INT(HAL_GetTick() & MP_SMALL_INT_POSITIVE_MASK);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_ms_obj, time_ticks_ms);
|
||||
|
||||
STATIC mp_obj_t time_ticks_us(void) {
|
||||
// We want to "cast" the 32 bit unsigned into a 30-bit small-int
|
||||
return MP_OBJ_NEW_SMALL_INT(sys_tick_get_microseconds() & MP_SMALL_INT_POSITIVE_MASK);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_us_obj, time_ticks_us);
|
||||
|
||||
STATIC mp_obj_t time_ticks_cpu(void) {
|
||||
// We want to "cast" the 32 bit unsigned into a 30-bit small-int
|
||||
return MP_OBJ_NEW_SMALL_INT((SysTickPeriodGet() - SysTickValueGet()) & MP_SMALL_INT_POSITIVE_MASK);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_cpu_obj, time_ticks_cpu);
|
||||
|
||||
STATIC mp_obj_t time_ticks_diff(mp_obj_t t0, mp_obj_t t1) {
|
||||
// We want to "cast" the 32 bit unsigned into a 30-bit small-int
|
||||
uint32_t start = mp_obj_get_int(t0);
|
||||
uint32_t end = mp_obj_get_int(t1);
|
||||
return MP_OBJ_NEW_SMALL_INT((end - start) & MP_SMALL_INT_POSITIVE_MASK);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(time_ticks_diff_obj, time_ticks_diff);
|
||||
|
||||
STATIC const mp_map_elem_t time_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_utime) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_utime) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_localtime), (mp_obj_t)&time_localtime_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mktime), (mp_obj_t)&time_mktime_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&time_sleep_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_time_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_localtime), (mp_obj_t)&time_localtime_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mktime), (mp_obj_t)&time_mktime_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_time_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&time_sleep_obj },
|
||||
|
||||
// MicroPython additions
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep_ms), (mp_obj_t)&time_sleep_ms_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sleep_us), (mp_obj_t)&time_sleep_us_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_ms), (mp_obj_t)&time_ticks_ms_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_us), (mp_obj_t)&time_ticks_us_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_cpu), (mp_obj_t)&time_ticks_cpu_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ticks_diff), (mp_obj_t)&time_ticks_diff_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
|
||||
|
||||
32
cc3200/mods/modwipy.c
Normal file
32
cc3200/mods/modwipy.c
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "mperror.h"
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
STATIC mp_obj_t mod_wipy_heartbeat (mp_uint_t n_args, const mp_obj_t *args) {
|
||||
if (n_args) {
|
||||
mperror_enable_heartbeat (mp_obj_is_true(args[0]));
|
||||
return mp_const_none;
|
||||
} else {
|
||||
return mp_obj_new_bool(mperror_is_heartbeat_enabled());
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_wipy_heartbeat_obj, 0, 1, mod_wipy_heartbeat);
|
||||
|
||||
STATIC const mp_map_elem_t wipy_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_wipy) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_heartbeat), (mp_obj_t)&mod_wipy_heartbeat_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(wipy_module_globals, wipy_module_globals_table);
|
||||
|
||||
const mp_obj_module_t wipy_module = {
|
||||
.base = { &mp_type_module },
|
||||
.name = MP_QSTR_wipy,
|
||||
.globals = (mp_obj_dict_t*)&wipy_module_globals,
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,48 +24,91 @@
|
||||
* 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 MODWLAN_WIFI_EVENT_ANY 0x01
|
||||
|
||||
#define MODWLAN_SSID_LEN_MAX 32
|
||||
|
||||
/******************************************************************************
|
||||
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;
|
||||
|
||||
}modwlan_Status_t;
|
||||
typedef struct _wlan_obj_t {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t irq_obj;
|
||||
uint32_t status;
|
||||
|
||||
uint32_t ip;
|
||||
|
||||
int8_t mode;
|
||||
uint8_t auth;
|
||||
uint8_t channel;
|
||||
uint8_t antenna;
|
||||
|
||||
// my own ssid, key and mac
|
||||
uint8_t ssid[(MODWLAN_SSID_LEN_MAX + 1)];
|
||||
uint8_t key[65];
|
||||
uint8_t mac[SL_MAC_ADDR_LEN];
|
||||
|
||||
// the sssid (or name) and mac of the other device
|
||||
uint8_t ssid_o[33];
|
||||
uint8_t bssid[6];
|
||||
uint8_t irq_flags;
|
||||
bool irq_enabled;
|
||||
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
bool servers_enabled;
|
||||
#endif
|
||||
} wlan_obj_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
|
||||
******************************************************************************/
|
||||
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_pre_init (void);
|
||||
extern void wlan_sl_init (int8_t mode, const char *ssid, uint8_t ssid_len, uint8_t auth, const char *key, uint8_t key_len,
|
||||
uint8_t channel, uint8_t antenna, bool add_mac);
|
||||
extern void wlan_first_start (void);
|
||||
extern void wlan_update(void);
|
||||
extern void wlan_stop (uint32_t timeout);
|
||||
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);
|
||||
extern bool wlan_is_connected (void);
|
||||
extern void wlan_set_current_time (uint32_t seconds_since_2000);
|
||||
|
||||
#endif /* SIMPLELINKTASK_H_ */
|
||||
extern int wlan_gethostbyname(const char *name, mp_uint_t len, uint8_t *out_ip, uint8_t family);
|
||||
extern int wlan_socket_socket(mod_network_socket_obj_t *s, int *_errno);
|
||||
extern void wlan_socket_close(mod_network_socket_obj_t *s);
|
||||
extern int wlan_socket_bind(mod_network_socket_obj_t *s, byte *ip, mp_uint_t port, int *_errno);
|
||||
extern int wlan_socket_listen(mod_network_socket_obj_t *s, mp_int_t backlog, int *_errno);
|
||||
extern int wlan_socket_accept(mod_network_socket_obj_t *s, mod_network_socket_obj_t *s2, byte *ip, mp_uint_t *port, int *_errno);
|
||||
extern int wlan_socket_connect(mod_network_socket_obj_t *s, byte *ip, mp_uint_t port, int *_errno);
|
||||
extern int wlan_socket_send(mod_network_socket_obj_t *s, const byte *buf, mp_uint_t len, int *_errno);
|
||||
extern int wlan_socket_recv(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, int *_errno);
|
||||
extern int wlan_socket_sendto( mod_network_socket_obj_t *s, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno);
|
||||
extern int wlan_socket_recvfrom(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno);
|
||||
extern int wlan_socket_setsockopt(mod_network_socket_obj_t *s, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno);
|
||||
extern int wlan_socket_settimeout(mod_network_socket_obj_t *s, mp_uint_t timeout_s, int *_errno);
|
||||
extern int wlan_socket_ioctl (mod_network_socket_obj_t *s, mp_uint_t request, mp_uint_t arg, int *_errno);
|
||||
|
||||
#endif /* MODWLAN_H_ */
|
||||
|
||||
312
cc3200/mods/pybadc.c
Normal file
312
cc3200/mods/pybadc.c
Normal file
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYB_ADC_NUM_CHANNELS 4
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE TYPES
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
bool enabled;
|
||||
} pyb_adc_obj_t;
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
pin_obj_t *pin;
|
||||
byte channel;
|
||||
byte id;
|
||||
bool enabled;
|
||||
} pyb_adc_channel_obj_t;
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC pyb_adc_channel_obj_t pyb_adc_channel_obj[PYB_ADC_NUM_CHANNELS] = { {.pin = &pin_GP2, .channel = ADC_CH_0, .id = 0, .enabled = false},
|
||||
{.pin = &pin_GP3, .channel = ADC_CH_1, .id = 1, .enabled = false},
|
||||
{.pin = &pin_GP4, .channel = ADC_CH_2, .id = 2, .enabled = false},
|
||||
{.pin = &pin_GP5, .channel = ADC_CH_3, .id = 3, .enabled = false} };
|
||||
STATIC pyb_adc_obj_t pyb_adc_obj = {.enabled = false};
|
||||
|
||||
STATIC const mp_obj_type_t pyb_adc_channel_type;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC mp_obj_t adc_channel_deinit(mp_obj_t self_in);
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC void pyb_adc_init (pyb_adc_obj_t *self) {
|
||||
// enable and configure the timer
|
||||
MAP_ADCTimerConfig(ADC_BASE, (1 << 17) - 1);
|
||||
MAP_ADCTimerEnable(ADC_BASE);
|
||||
// enable the ADC peripheral
|
||||
MAP_ADCEnable(ADC_BASE);
|
||||
self->enabled = true;
|
||||
}
|
||||
|
||||
STATIC void pyb_adc_check_init(void) {
|
||||
// not initialized
|
||||
if (!pyb_adc_obj.enabled) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void pyb_adc_channel_init (pyb_adc_channel_obj_t *self) {
|
||||
// the ADC block must be enabled first
|
||||
pyb_adc_check_init();
|
||||
// configure the pin in analog mode
|
||||
pin_config (self->pin, -1, PIN_TYPE_ANALOG, PIN_TYPE_STD, -1, PIN_STRENGTH_2MA);
|
||||
// enable the ADC channel
|
||||
MAP_ADCChannelEnable(ADC_BASE, self->channel);
|
||||
self->enabled = true;
|
||||
}
|
||||
|
||||
STATIC void pyb_adc_deinit_all_channels (void) {
|
||||
for (int i = 0; i < PYB_ADC_NUM_CHANNELS; i++) {
|
||||
adc_channel_deinit(&pyb_adc_channel_obj[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings : adc object */
|
||||
|
||||
STATIC void adc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_adc_obj_t *self = self_in;
|
||||
if (self->enabled) {
|
||||
mp_printf(print, "ADC(0, bits=12)");
|
||||
} else {
|
||||
mp_printf(print, "ADC(0)");
|
||||
}
|
||||
}
|
||||
|
||||
STATIC const mp_arg_t pyb_adc_init_args[] = {
|
||||
{ MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 12} },
|
||||
};
|
||||
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 *all_args) {
|
||||
// parse args
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_adc_init_args)];
|
||||
mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), pyb_adc_init_args, args);
|
||||
|
||||
// check the peripheral id
|
||||
if (args[0].u_int != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
// check the number of bits
|
||||
if (args[1].u_int != 12) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
// setup the object
|
||||
pyb_adc_obj_t *self = &pyb_adc_obj;
|
||||
self->base.type = &pyb_adc_type;
|
||||
|
||||
// initialize and register with the sleep module
|
||||
pyb_adc_init(self);
|
||||
pyb_sleep_add ((const mp_obj_t)self, (WakeUpCB_t)pyb_adc_init);
|
||||
return self;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t adc_init(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(pyb_adc_init_args) - 1];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &pyb_adc_init_args[1], args);
|
||||
// check the number of bits
|
||||
if (args[0].u_int != 12) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
pyb_adc_init(pos_args[0]);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(adc_init_obj, 1, adc_init);
|
||||
|
||||
STATIC mp_obj_t adc_deinit(mp_obj_t self_in) {
|
||||
pyb_adc_obj_t *self = self_in;
|
||||
// first deinit all channels
|
||||
pyb_adc_deinit_all_channels();
|
||||
MAP_ADCDisable(ADC_BASE);
|
||||
self->enabled = false;
|
||||
// unregister it with the sleep module
|
||||
pyb_sleep_remove ((const mp_obj_t)self);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_deinit_obj, adc_deinit);
|
||||
|
||||
STATIC mp_obj_t adc_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
STATIC const mp_arg_t pyb_adc_channel_args[] = {
|
||||
{ MP_QSTR_id, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_pin, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
};
|
||||
|
||||
// parse args
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_adc_channel_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), pyb_adc_channel_args, args);
|
||||
|
||||
uint ch_id;
|
||||
if (args[0].u_obj != MP_OBJ_NULL) {
|
||||
ch_id = mp_obj_get_int(args[0].u_obj);
|
||||
if (ch_id >= PYB_ADC_NUM_CHANNELS) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_os_resource_not_avaliable));
|
||||
} else if (args[1].u_obj != mp_const_none) {
|
||||
uint pin_ch_id = pin_find_peripheral_type (args[1].u_obj, PIN_FN_ADC, 0);
|
||||
if (ch_id != pin_ch_id) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ch_id = pin_find_peripheral_type (args[1].u_obj, PIN_FN_ADC, 0);
|
||||
}
|
||||
|
||||
// setup the object
|
||||
pyb_adc_channel_obj_t *self = &pyb_adc_channel_obj[ch_id];
|
||||
self->base.type = &pyb_adc_channel_type;
|
||||
pyb_adc_channel_init (self);
|
||||
// register it with the sleep module
|
||||
pyb_sleep_add ((const mp_obj_t)self, (WakeUpCB_t)pyb_adc_channel_init);
|
||||
return self;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(adc_channel_obj, 1, adc_channel);
|
||||
|
||||
STATIC const mp_map_elem_t adc_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&adc_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&adc_deinit_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_channel), (mp_obj_t)&adc_channel_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,
|
||||
};
|
||||
|
||||
STATIC void adc_channel_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_adc_channel_obj_t *self = self_in;
|
||||
if (self->enabled) {
|
||||
mp_printf(print, "ADCChannel(%u, pin=%q)", self->id, self->pin->name);
|
||||
} else {
|
||||
mp_printf(print, "ADCChannel(%u)", self->id);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t adc_channel_init(mp_obj_t self_in) {
|
||||
pyb_adc_channel_obj_t *self = self_in;
|
||||
// re-enable it
|
||||
pyb_adc_channel_init(self);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_channel_init_obj, adc_channel_init);
|
||||
|
||||
STATIC mp_obj_t adc_channel_deinit(mp_obj_t self_in) {
|
||||
pyb_adc_channel_obj_t *self = self_in;
|
||||
|
||||
MAP_ADCChannelDisable(ADC_BASE, self->channel);
|
||||
// unregister it with the sleep module
|
||||
pyb_sleep_remove ((const mp_obj_t)self);
|
||||
self->enabled = false;
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_channel_deinit_obj, adc_channel_deinit);
|
||||
|
||||
STATIC mp_obj_t adc_channel_value(mp_obj_t self_in) {
|
||||
pyb_adc_channel_obj_t *self = self_in;
|
||||
uint32_t value;
|
||||
|
||||
// the channel must be enabled
|
||||
if (!self->enabled) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
|
||||
// wait until a new value is available
|
||||
while (!MAP_ADCFIFOLvlGet(ADC_BASE, self->channel));
|
||||
// read the sample
|
||||
value = MAP_ADCFIFORead(ADC_BASE, self->channel);
|
||||
// the 12 bit sampled value is stored in bits [13:2]
|
||||
return MP_OBJ_NEW_SMALL_INT((value & 0x3FFF) >> 2);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_channel_value_obj, adc_channel_value);
|
||||
|
||||
STATIC mp_obj_t adc_channel_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);
|
||||
return adc_channel_value (self_in);
|
||||
}
|
||||
|
||||
STATIC const mp_map_elem_t adc_channel_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&adc_channel_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&adc_channel_deinit_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&adc_channel_value_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(adc_channel_locals_dict, adc_channel_locals_dict_table);
|
||||
|
||||
STATIC const mp_obj_type_t pyb_adc_channel_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_ADCChannel,
|
||||
.print = adc_channel_print,
|
||||
.call = adc_channel_call,
|
||||
.locals_dict = (mp_obj_t)&adc_channel_locals_dict,
|
||||
};
|
||||
@@ -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 PYBADC_H_
|
||||
#define PYBADC_H_
|
||||
|
||||
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);
|
||||
}
|
||||
532
cc3200/mods/pybi2c.c
Normal file
532
cc3200/mods/pybi2c.c
Normal file
@@ -0,0 +1,532 @@
|
||||
/*
|
||||
* 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"
|
||||
#include "pybpin.h"
|
||||
#include "pins.h"
|
||||
|
||||
/// \moduleref pyb
|
||||
/// \class I2C - a two-wire serial protocol
|
||||
|
||||
typedef struct _pyb_i2c_obj_t {
|
||||
mp_obj_base_t base;
|
||||
uint baudrate;
|
||||
} pyb_i2c_obj_t;
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYBI2C_MASTER (0)
|
||||
|
||||
#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};
|
||||
|
||||
STATIC const mp_obj_t pyb_i2c_def_pin[2] = {&pin_GP13, &pin_GP23};
|
||||
|
||||
/******************************************************************************
|
||||
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 void pyb_i2c_check_init(pyb_i2c_obj_t *self) {
|
||||
// not initialized
|
||||
if (!self->baudrate) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
STATIC bool pyb_i2c_mem_addr_write (byte addr, byte *mem_addr, uint mem_addr_len) {
|
||||
// Set I2C codec slave address
|
||||
MAP_I2CMasterSlaveAddrSet(I2CA0_BASE, addr, false);
|
||||
// Write the first byte to the controller.
|
||||
MAP_I2CMasterDataPut(I2CA0_BASE, *mem_addr++);
|
||||
// Initiate the transfer.
|
||||
RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_BURST_SEND_START));
|
||||
|
||||
// Loop until the completion of transfer or error
|
||||
while (--mem_addr_len) {
|
||||
// Write the next byte of data
|
||||
MAP_I2CMasterDataPut(I2CA0_BASE, *mem_addr++);
|
||||
// Transact over I2C to send the next byte
|
||||
RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_BURST_SEND_CONT));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
STATIC bool pyb_i2c_mem_write (byte addr, byte *mem_addr, uint mem_addr_len, byte *data, uint data_len) {
|
||||
if (pyb_i2c_mem_addr_write (addr, mem_addr, mem_addr_len)) {
|
||||
// Loop until the completion of transfer or error
|
||||
while (data_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));
|
||||
}
|
||||
// send the stop bit
|
||||
RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_BURST_SEND_STOP));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
STATIC bool pyb_i2c_write(byte addr, byte *data, uint len, bool stop) {
|
||||
// Set I2C codec slave address
|
||||
MAP_I2CMasterSlaveAddrSet(I2CA0_BASE, addr, 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, do it.
|
||||
if (stop) {
|
||||
RET_IF_ERR(pyb_i2c_transaction(I2C_MASTER_CMD_BURST_SEND_STOP));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
STATIC bool pyb_i2c_read(byte addr, byte *data, uint len) {
|
||||
// Initiate a burst or single receive sequence
|
||||
uint cmd = --len > 0 ? I2C_MASTER_CMD_BURST_RECEIVE_START : I2C_MASTER_CMD_SINGLE_RECEIVE;
|
||||
// Set I2C codec slave address
|
||||
MAP_I2CMasterSlaveAddrSet(I2CA0_BASE, addr, true);
|
||||
// Initiate the transfer.
|
||||
RET_IF_ERR(pyb_i2c_transaction(cmd));
|
||||
// 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 void pyb_i2c_read_into (mp_arg_val_t *args, vstr_t *vstr) {
|
||||
pyb_i2c_check_init(&pyb_i2c_obj);
|
||||
// get the buffer to receive into
|
||||
pyb_buf_get_for_recv(args[1].u_obj, vstr);
|
||||
|
||||
// receive the data
|
||||
if (!pyb_i2c_read(args[0].u_int, (byte *)vstr->buf, vstr->len)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void pyb_i2c_readmem_into (mp_arg_val_t *args, vstr_t *vstr) {
|
||||
pyb_i2c_check_init(&pyb_i2c_obj);
|
||||
// get the buffer to receive into
|
||||
pyb_buf_get_for_recv(args[2].u_obj, vstr);
|
||||
|
||||
// get the addresses
|
||||
mp_uint_t i2c_addr = args[0].u_int;
|
||||
mp_uint_t mem_addr = args[1].u_int;
|
||||
// determine the width of mem_addr (1 or 2 bytes)
|
||||
mp_uint_t mem_addr_size = args[3].u_int >> 3;
|
||||
|
||||
// write the register address to be read from
|
||||
if (pyb_i2c_mem_addr_write (i2c_addr, (byte *)&mem_addr, mem_addr_size)) {
|
||||
// Read the specified length of data
|
||||
if (!pyb_i2c_read (i2c_addr, (byte *)vstr->buf, vstr->len)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings */
|
||||
/******************************************************************************/
|
||||
STATIC void pyb_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_i2c_obj_t *self = self_in;
|
||||
if (self->baudrate > 0) {
|
||||
mp_printf(print, "I2C(0, I2C.MASTER, baudrate=%u)", self->baudrate);
|
||||
} else {
|
||||
mp_print_str(print, "I2C(0)");
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_init_helper(pyb_i2c_obj_t *self, const mp_arg_val_t *args) {
|
||||
// verify that mode is master
|
||||
if (args[0].u_int != PYBI2C_MASTER) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
// make sure the baudrate is between the valid range
|
||||
self->baudrate = MIN(MAX(args[1].u_int, PYBI2C_MIN_BAUD_RATE_HZ), PYBI2C_MAX_BAUD_RATE_HZ);
|
||||
|
||||
// assign the pins
|
||||
mp_obj_t pins_o = args[2].u_obj;
|
||||
if (pins_o != mp_const_none) {
|
||||
mp_obj_t *pins;
|
||||
if (pins_o == MP_OBJ_NULL) {
|
||||
// use the default pins
|
||||
pins = (mp_obj_t *)pyb_i2c_def_pin;
|
||||
} else {
|
||||
mp_obj_get_array_fixed_n(pins_o, 2, &pins);
|
||||
}
|
||||
pin_assign_pins_af (pins, 2, PIN_TYPE_STD_PU, PIN_FN_I2C, 0);
|
||||
}
|
||||
|
||||
// init the I2C bus
|
||||
i2c_init(self);
|
||||
|
||||
// register it with the sleep module
|
||||
pyb_sleep_add ((const mp_obj_t)self, (WakeUpCB_t)i2c_init);
|
||||
|
||||
return mp_const_none;
|
||||
|
||||
invalid_args:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
STATIC const mp_arg_t pyb_i2c_init_args[] = {
|
||||
{ MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_mode, MP_ARG_INT, {.u_int = PYBI2C_MASTER} },
|
||||
{ MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 100000} },
|
||||
{ MP_QSTR_pins, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
};
|
||||
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 *all_args) {
|
||||
// parse args
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, all_args + n_args);
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_i2c_init_args)];
|
||||
mp_arg_parse_all(n_args, all_args, &kw_args, MP_ARRAY_SIZE(args), pyb_i2c_init_args, args);
|
||||
|
||||
// check the peripheral id
|
||||
if (args[0].u_int != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
// setup the object
|
||||
pyb_i2c_obj_t *self = &pyb_i2c_obj;
|
||||
self->base.type = &pyb_i2c_type;
|
||||
|
||||
// start the peripheral
|
||||
pyb_i2c_init_helper(self, &args[1]);
|
||||
|
||||
return (mp_obj_t)self;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_init(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(pyb_i2c_init_args) - 1];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), &pyb_i2c_init_args[1], args);
|
||||
return pyb_i2c_init_helper(pos_args[0], args);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_init_obj, 1, pyb_i2c_init);
|
||||
|
||||
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
|
||||
pyb_sleep_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);
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_scan(mp_obj_t self_in) {
|
||||
pyb_i2c_check_init(&pyb_i2c_obj);
|
||||
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);
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_readfrom(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
STATIC const mp_arg_t pyb_i2c_readfrom_args[] = {
|
||||
{ MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, },
|
||||
{ MP_QSTR_nbytes, MP_ARG_REQUIRED | MP_ARG_OBJ, },
|
||||
};
|
||||
|
||||
// parse args
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_i2c_readfrom_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), pyb_i2c_readfrom_args, args);
|
||||
|
||||
vstr_t vstr;
|
||||
pyb_i2c_read_into(args, &vstr);
|
||||
|
||||
// return the received data
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_readfrom_obj, 3, pyb_i2c_readfrom);
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_readfrom_into(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
STATIC const mp_arg_t pyb_i2c_readfrom_into_args[] = {
|
||||
{ MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, },
|
||||
{ MP_QSTR_buf, MP_ARG_REQUIRED | MP_ARG_OBJ, },
|
||||
};
|
||||
|
||||
// parse args
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_i2c_readfrom_into_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), pyb_i2c_readfrom_into_args, args);
|
||||
|
||||
vstr_t vstr;
|
||||
pyb_i2c_read_into(args, &vstr);
|
||||
|
||||
// return the number of bytes received
|
||||
return mp_obj_new_int(vstr.len);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_readfrom_into_obj, 1, pyb_i2c_readfrom_into);
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_writeto(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
STATIC const mp_arg_t pyb_i2c_writeto_args[] = {
|
||||
{ MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, },
|
||||
{ MP_QSTR_buf, MP_ARG_REQUIRED | MP_ARG_OBJ, },
|
||||
{ MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
|
||||
};
|
||||
|
||||
// parse args
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_i2c_writeto_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), pyb_i2c_writeto_args, args);
|
||||
|
||||
pyb_i2c_check_init(&pyb_i2c_obj);
|
||||
|
||||
// get the buffer to send from
|
||||
mp_buffer_info_t bufinfo;
|
||||
uint8_t data[1];
|
||||
pyb_buf_get_for_send(args[1].u_obj, &bufinfo, data);
|
||||
|
||||
// send the data
|
||||
if (!pyb_i2c_write(args[0].u_int, bufinfo.buf, bufinfo.len, args[2].u_bool)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
// return the number of bytes written
|
||||
return mp_obj_new_int(bufinfo.len);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_writeto_obj, 1, pyb_i2c_writeto);
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_readfrom_mem(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
STATIC const mp_arg_t pyb_i2c_readfrom_mem_args[] = {
|
||||
{ MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, },
|
||||
{ MP_QSTR_memaddr, MP_ARG_REQUIRED | MP_ARG_INT, },
|
||||
{ MP_QSTR_nbytes, MP_ARG_REQUIRED | MP_ARG_OBJ, },
|
||||
{ MP_QSTR_addrsize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
|
||||
};
|
||||
|
||||
// parse args
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(pyb_i2c_readfrom_mem_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), pyb_i2c_readfrom_mem_args, args);
|
||||
|
||||
vstr_t vstr;
|
||||
pyb_i2c_readmem_into (args, &vstr);
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_readfrom_mem_obj, 1, pyb_i2c_readfrom_mem);
|
||||
|
||||
STATIC const mp_arg_t pyb_i2c_readfrom_mem_into_args[] = {
|
||||
{ MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, },
|
||||
{ MP_QSTR_memaddr, MP_ARG_REQUIRED | MP_ARG_INT, },
|
||||
{ MP_QSTR_buf, MP_ARG_REQUIRED | MP_ARG_OBJ, },
|
||||
{ MP_QSTR_addrsize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
|
||||
};
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_readfrom_mem_into(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(pyb_i2c_readfrom_mem_into_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), pyb_i2c_readfrom_mem_into_args, args);
|
||||
|
||||
// get the buffer to read into
|
||||
vstr_t vstr;
|
||||
pyb_i2c_readmem_into (args, &vstr);
|
||||
return mp_obj_new_int(vstr.len);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_readfrom_mem_into_obj, 1, pyb_i2c_readfrom_mem_into);
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_writeto_mem(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(pyb_i2c_readfrom_mem_into_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(pyb_i2c_readfrom_mem_into_args), pyb_i2c_readfrom_mem_into_args, args);
|
||||
|
||||
pyb_i2c_check_init(&pyb_i2c_obj);
|
||||
|
||||
// get the buffer to write from
|
||||
mp_buffer_info_t bufinfo;
|
||||
uint8_t data[1];
|
||||
pyb_buf_get_for_send(args[2].u_obj, &bufinfo, data);
|
||||
|
||||
// get the addresses
|
||||
mp_uint_t i2c_addr = args[0].u_int;
|
||||
mp_uint_t mem_addr = args[1].u_int;
|
||||
// determine the width of mem_addr (1 or 2 bytes)
|
||||
mp_uint_t mem_addr_size = args[3].u_int >> 3;
|
||||
|
||||
// write the register address to write to.
|
||||
if (pyb_i2c_mem_write (i2c_addr, (byte *)&mem_addr, mem_addr_size, bufinfo.buf, bufinfo.len)) {
|
||||
// return the number of bytes written
|
||||
return mp_obj_new_int(bufinfo.len);
|
||||
}
|
||||
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_writeto_mem_obj, 1, pyb_i2c_writeto_mem);
|
||||
|
||||
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_scan), (mp_obj_t)&pyb_i2c_scan_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readfrom), (mp_obj_t)&pyb_i2c_readfrom_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readfrom_into), (mp_obj_t)&pyb_i2c_readfrom_into_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_writeto), (mp_obj_t)&pyb_i2c_writeto_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readfrom_mem), (mp_obj_t)&pyb_i2c_readfrom_mem_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readfrom_mem_into), (mp_obj_t)&pyb_i2c_readfrom_mem_into_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_writeto_mem), (mp_obj_t)&pyb_i2c_writeto_mem_obj },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_MASTER), MP_OBJ_NEW_SMALL_INT(PYBI2C_MASTER) },
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user