mirror of
https://github.com/micropython/micropython.git
synced 2025-12-24 13:50:12 +01:00
Compare commits
602 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
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
|
||||
|
||||
@@ -261,6 +261,7 @@ today. The names appear in order of pledging.
|
||||
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
|
||||
@@ -339,6 +340,7 @@ today. The names appear in order of pledging.
|
||||
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
|
||||
@@ -375,6 +377,7 @@ today. The names appear in order of pledging.
|
||||
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.
|
||||
@@ -417,6 +420,7 @@ today. The names appear in order of pledging.
|
||||
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
|
||||
@@ -477,6 +481,7 @@ today. The names appear in order of pledging.
|
||||
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
|
||||
@@ -690,6 +695,7 @@ today. The names appear in order of pledging.
|
||||
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
|
||||
@@ -889,6 +895,7 @@ today. The names appear in order of pledging.
|
||||
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
|
||||
|
||||
@@ -33,16 +33,17 @@ 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: Micro Python 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
|
||||
@@ -51,19 +52,31 @@ integer types. The general guidelines are:
|
||||
- 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
|
||||
28
README.md
28
README.md
@@ -44,6 +44,9 @@ Additional components:
|
||||
mostly to control code size.
|
||||
- teensy/ -- a version of Micro Python that runs on the Teensy 3.1
|
||||
(preliminary but functional).
|
||||
- pic16bit/ -- a version of Micro Python for 16-bit PIC microcontrollers.
|
||||
- cc3200/ -- a version of Micro Python that runs on the CC3200 from TI.
|
||||
- esp8266/ -- an experimental port for ESP8266 WiFi modules.
|
||||
- unix-cpy/ -- a version of Micro Python that outputs bytecode (for testing).
|
||||
- tests/ -- test framework and test scripts.
|
||||
- tools/ -- various tools, including the pyboard.py module.
|
||||
@@ -62,7 +65,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
|
||||
@@ -76,10 +79,19 @@ 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.
|
||||
|
||||
(*) Debian/Ubuntu/Mint derivative Linux distros will require build-essentials,
|
||||
libffi-dev and pkg-config packages installed. If you have problems with some
|
||||
dependencies, they can be disabled in unix/mpconfigport.mk .
|
||||
|
||||
The STM version
|
||||
---------------
|
||||
@@ -119,6 +131,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`.
|
||||
|
||||
@@ -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_parse_node_t pn = mp_parse(lex, input_kind);
|
||||
mp_obj_t module_fun = mp_compile(pn, 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,6 +2,7 @@
|
||||
|
||||
// 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)
|
||||
@@ -18,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)
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
#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 ) 72 )
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 64 )
|
||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 16384 ) )
|
||||
#define configMAX_TASK_NAME_LEN ( 8 )
|
||||
#define configUSE_TRACE_FACILITY 0
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# 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.
|
||||
@@ -20,7 +21,7 @@ CFLAGS = -Wall -Wpointer-arith -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_CORTE
|
||||
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 Micro Python 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,29 +13,42 @@ 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 Micro Python 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`.
|
||||
- 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.
|
||||
- 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:
|
||||
@@ -43,15 +56,14 @@ Once the software is running, you have two options to access the MicroPython REP
|
||||
- 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:
|
||||
|
||||
@@ -64,14 +76,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:
|
||||
|
||||
@@ -24,9 +24,8 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
__stack_size__ = 2K; /* interrupts are handled within this stack */
|
||||
__stack_size__ = 3K; /* interrupts are handled within this stack */
|
||||
__min_heap_size__ = 8K;
|
||||
__rtos_heap_size = 16K;
|
||||
|
||||
MEMORY
|
||||
{
|
||||
|
||||
@@ -20,6 +20,8 @@ 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,6 +75,7 @@ APP_HAL_SRC_C = $(addprefix hal/,\
|
||||
)
|
||||
|
||||
APP_MISC_SRC_C = $(addprefix misc/,\
|
||||
antenna.c \
|
||||
FreeRTOSHooks.c \
|
||||
pin_named_pins.c \
|
||||
help.c \
|
||||
@@ -80,14 +83,16 @@ APP_MISC_SRC_C = $(addprefix misc/,\
|
||||
mperror.c \
|
||||
mpexception.c \
|
||||
mpsystick.c \
|
||||
pin_defs_cc3200.c \
|
||||
)
|
||||
|
||||
APP_MODS_SRC_C = $(addprefix mods/,\
|
||||
modnetwork.c \
|
||||
moduhashlib.c \
|
||||
modubinascii.c \
|
||||
modpyb.c \
|
||||
moduos.c \
|
||||
modusocket.c \
|
||||
modussl.c \
|
||||
modutime.c \
|
||||
modwlan.c \
|
||||
pybadc.c \
|
||||
@@ -97,6 +102,7 @@ APP_MODS_SRC_C = $(addprefix mods/,\
|
||||
pybsd.c \
|
||||
pybsleep.c \
|
||||
pybspi.c \
|
||||
pybtimer.c \
|
||||
pybuart.c \
|
||||
pybwdt.c \
|
||||
)
|
||||
@@ -122,6 +128,7 @@ APP_TELNET_SRC_C = $(addprefix telnet/,\
|
||||
)
|
||||
|
||||
APP_UTIL_SRC_C = $(addprefix util/,\
|
||||
cryptohash.c \
|
||||
fifo.c \
|
||||
gccollect.c \
|
||||
random.c \
|
||||
@@ -140,7 +147,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/,\
|
||||
@@ -154,7 +165,6 @@ APP_STM_SRC_C = $(addprefix stmhal/,\
|
||||
printf.c \
|
||||
pyexec.c \
|
||||
pybstdio.c \
|
||||
string0.c \
|
||||
)
|
||||
|
||||
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(APP_FATFS_SRC_C:.c=.o) $(APP_RTOS_SRC_C:.c=.o) $(APP_FTP_SRC_C:.c=.o) $(APP_HAL_SRC_C:.c=.o) $(APP_MISC_SRC_C:.c=.o))
|
||||
@@ -188,6 +198,7 @@ $(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
|
||||
@@ -205,8 +216,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 $@"
|
||||
@@ -217,7 +238,7 @@ $(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) $(BTYPE)
|
||||
|
||||
|
||||
@@ -16,13 +16,13 @@ BUILD=build/${BOARD}/${BTYPE}
|
||||
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
|
||||
|
||||
@@ -33,18 +33,23 @@
|
||||
#define MICROPY_HW_HAS_SDCARD (0)
|
||||
#define MICROPY_HW_ENABLE_RNG (1)
|
||||
#define MICROPY_HW_ENABLE_RTC (1)
|
||||
#define MICROPY_HW_ANTENNA_DIVERSITY (0)
|
||||
|
||||
#define MICROPY_STDIO_UART PYB_UART_0
|
||||
#define MICROPY_STDIO_UART 1
|
||||
#define MICROPY_STDIO_UART_BAUD 115200
|
||||
#define MICROPY_STDIO_UART_RX_BUF_SIZE 128
|
||||
#define MICROPY_STDIO_UART_TX_PIN (pin_GP1)
|
||||
#define MICROPY_STDIO_UART_RX_PIN (pin_GP2)
|
||||
#define MICROPY_STDIO_UART_TX_PIN_AF PIN_MODE_3
|
||||
#define MICROPY_STDIO_UART_RX_PIN_AF PIN_MODE_3
|
||||
|
||||
#define MICROPY_SYS_LED_PRCM PRCM_GPIOA1
|
||||
#define MICROPY_SAFE_BOOT_PRCM PRCM_GPIOA2
|
||||
#define MICROPY_SYS_LED_PORT GPIOA1_BASE
|
||||
#define MICROPY_SAFE_BOOT_PORT GPIOA2_BASE
|
||||
#define MICROPY_SYS_LED_GPIO pin_GPIO9
|
||||
#define MICROPY_SYS_LED_PIN_NUM PIN_64 // GPIO9
|
||||
#define MICROPY_SAFE_BOOT_PIN_NUM PIN_15 // GPIO22
|
||||
#define MICROPY_SYS_LED_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
|
||||
|
||||
|
||||
@@ -1,51 +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.
|
||||
*/
|
||||
|
||||
#define LAUNCHXL
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "WiPy-SD"
|
||||
#define MICROPY_HW_MCU_NAME "CC3200"
|
||||
|
||||
#define MICROPY_HW_HAS_SDCARD (1)
|
||||
#define MICROPY_HW_ENABLE_RNG (1)
|
||||
#define MICROPY_HW_ENABLE_RTC (1)
|
||||
|
||||
#define MICROPY_STDIO_UART PYB_UART_0
|
||||
#define MICROPY_STDIO_UART_BAUD 115200
|
||||
#define MICROPY_STDIO_UART_RX_BUF_SIZE 128
|
||||
|
||||
#define MICROPY_SYS_LED_PRCM PRCM_GPIOA3
|
||||
#define MICROPY_SAFE_BOOT_PRCM PRCM_GPIOA3
|
||||
#define MICROPY_SYS_LED_PORT GPIOA3_BASE
|
||||
#define MICROPY_SAFE_BOOT_PORT GPIOA3_BASE
|
||||
#define MICROPY_SYS_LED_GPIO pin_GPIO25
|
||||
#define MICROPY_SYS_LED_PIN_NUM PIN_21 // GPIO25 (SOP2)
|
||||
#define MICROPY_SAFE_BOOT_PIN_NUM PIN_18 // GPIO28
|
||||
#define MICROPY_SYS_LED_PORT_PIN GPIO_PIN_1
|
||||
#define MICROPY_SAFE_BOOT_PORT_PIN GPIO_PIN_4
|
||||
|
||||
#define MICROPY_PORT_SFLASH_BLOCK_COUNT 96
|
||||
@@ -1,25 +0,0 @@
|
||||
L2,GPIO2
|
||||
L3,GPIO1
|
||||
L4,GPIO23
|
||||
L5,GPIO24
|
||||
L6,GPIO11
|
||||
L7,GPIO12
|
||||
L8,GPIO13
|
||||
L9,GPIO14
|
||||
L10,GPIO15
|
||||
L11,GPIO16
|
||||
L12,GPIO17
|
||||
L13,GPIO22
|
||||
L14,GPIO28
|
||||
R4,GPIO10
|
||||
R5,GPIO9
|
||||
R6,GPIO8
|
||||
R7,GPIO7
|
||||
R8,GPIO6
|
||||
R9,GPIO30
|
||||
R10,GPIO31
|
||||
R11,GPIO3
|
||||
R12,GPIO0
|
||||
R13,GPIO4
|
||||
R14,GPIO5
|
||||
HBL,GPIO25
|
||||
|
@@ -25,26 +25,23 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define LAUNCHXL
|
||||
#define WIPY
|
||||
|
||||
#define MICROPY_HW_BOARD_NAME "WiPy"
|
||||
#define MICROPY_HW_MCU_NAME "CC3200"
|
||||
|
||||
#define MICROPY_HW_HAS_SDCARD (0)
|
||||
#define MICROPY_HW_HAS_SDCARD (1)
|
||||
#define MICROPY_HW_ENABLE_RNG (1)
|
||||
#define MICROPY_HW_ENABLE_RTC (1)
|
||||
|
||||
#define MICROPY_STDIO_UART PYB_UART_0
|
||||
#define MICROPY_STDIO_UART_BAUD 115200
|
||||
#define MICROPY_STDIO_UART_RX_BUF_SIZE 128
|
||||
#define MICROPY_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_GPIO25
|
||||
#define MICROPY_SYS_LED_PIN_NUM PIN_21 // GPIO25 (SOP2)
|
||||
#define MICROPY_SAFE_BOOT_PIN_NUM PIN_18 // GPIO28
|
||||
#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
|
||||
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
L2,GPIO2
|
||||
L3,GPIO1
|
||||
L4,GPIO23
|
||||
L5,GPIO24
|
||||
L6,GPIO11
|
||||
L7,GPIO12
|
||||
L8,GPIO13
|
||||
L9,GPIO14
|
||||
L10,GPIO15
|
||||
L11,GPIO16
|
||||
L12,GPIO17
|
||||
L13,GPIO22
|
||||
L14,GPIO28
|
||||
R4,GPIO10
|
||||
R5,GPIO9
|
||||
R6,GPIO8
|
||||
R7,GPIO7
|
||||
R8,GPIO6
|
||||
R9,GPIO30
|
||||
R10,GPIO31
|
||||
R11,GPIO3
|
||||
R12,GPIO0
|
||||
R13,GPIO4
|
||||
R14,GPIO5
|
||||
HBL,GPIO25
|
||||
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,I2C_SCL,,GT_PWM06,,,SDCARD_CLK,UART1_TX,,,,,GT_CCP01,,,,
|
||||
2,GP11,GP11,GP11,I2C_SDA,,GT_PWM07,pXCLK(XVCLK),,SDCARD_CMD,UART1_RX,,,,,GT_CCP02,McAFSX,,,
|
||||
3,GP12,GP12,GP12,,,McACLK,pVS(VSYNC),I2C_SCL,,UART0_TX,,,,,GT_CCP03,,,,
|
||||
4,GP13,GP13,GP13,,,,pHS(HSYNC),I2C_SDA,,UART0_RX,,,,,GT_CCP04,,,,
|
||||
5,GP14,GP14,GP14,,,,pDATA8(CAM_D4),2C_SCL,,GSPI_CLK,,,,,GT_CCP05,,,,
|
||||
6,GP15,GP15,GP15,,,,pDATA9(CAM_D5),I2C_SDA,,GSPI_MISO,,,,,,GT_CCP06,,,
|
||||
7,GP16,GP16,GP16,,,,pDATA10(CAM_D6),UART1_TX,,GSPI_MOSI,,,,,,GT_CCP07,,,
|
||||
8,GP17,GP17,GP17,,,,pDATA11(CAM_D7),UART1_RX,,GSPI_CS,,,,,,,,,
|
||||
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,,,,,,,,,,,,,,,,
|
||||
15,GP22,GP22,GP22,,,,,GT_CCP04,,McAFSX,,,,,,,,,
|
||||
16,GP23,TDI,GP23,TDI,UART1_TX,,,,,,,2C_SCL,,,,,,,
|
||||
17,GP24,TDO,GP24,TDO,UART1_RX,,GT_CCP06,PWM0,McAFSX,,,I2C_SDA,,,,,,,
|
||||
18,GP28,GP28,GP28,,,,,,,,,,,,,,,,
|
||||
19,TCK,TCK,,TCK,,,,,,,GT_PWM03,,,,,,,,
|
||||
20,GPIO29,TMS,GPIO29,TMS,,,,,,,,,,,,,,,
|
||||
21,GPIO25,SOP2,GPIO25,,McAFSX,,,,,,,GT_PWM02,,,,,,,
|
||||
20,GP29,TMS,GP29,TMS,,,,,,,,,,,,,,,
|
||||
21,GP25,SOP2,GP25,,McAFSX,,,,,,,GT_PWM02,,,,,,,
|
||||
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,,,,McAXR0,GSPI_CLK,,UART0_RX,,,McAFSX,,,,
|
||||
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,McAXR0,,McAXR1,GT_CCP00,,GSPI_CS,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,,McACLK,,McAXR0,,UART0_RTS,,GSPI_MOSI,,,,,,,,
|
||||
53,GP30,GP30,GP30,,McACLK,McAFSX,GT_CCP05,,,GSPI_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,,,GSPI_MISO,pCLK (PIXCLK),,UART1_TX,GT_CCP01,,,,,,,,,
|
||||
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,GT_CCP02,,,,,,,,,ADC_CH0
|
||||
58,GP3,GP3,GP3,,,,pDATA7(CAM_D3),,UART1_TX,,,,,,,,,,ADC_CH1
|
||||
59,GP4,GP4,GP4,,,,pDATA6(CAM_D2),,UART1_RX,,,,,,,,,,ADC_CH2
|
||||
60,GP5,GP5,GP5,,,,pDATA5(CAM_D1),,McAXR1,GT_CCP05,,,,,,,,,ADC_CH3
|
||||
61,GP6,GP6,GP6,,,UART1_CTS,pDATA4(CAM_D0),UART0_RTS,UART0_CTS,GT_CCP06,,,,,,,,,
|
||||
62,GP7,GP7,GP7,,,UART1_RTS,,,,,,,UART0_RTS,UART0_TX,,McACLKX,,,
|
||||
63,GP8,GP8,GP8,,,,,,SDCARD_IRQ,McAFSX,,,,,GT_CCP06,,,,
|
||||
64,GP9,GP9,GP9,,,GT_PWM05,,,SDCARD_DATA,McAXR0,,,,,GT_CCP00,,,,
|
||||
65,GND_TAB,GND_TAB,GND_TAB,,,,,,,,,,,,,,,,
|
||||
|
||||
|
@@ -10,14 +10,14 @@ import csv
|
||||
|
||||
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)
|
||||
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ 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 \
|
||||
@@ -42,6 +43,7 @@ BOOT_CC3100_SRC_C = $(addprefix drivers/cc3100/,\
|
||||
)
|
||||
|
||||
BOOT_MISC_SRC_C = $(addprefix misc/,\
|
||||
antenna.c \
|
||||
mperror.c \
|
||||
)
|
||||
|
||||
@@ -50,7 +52,7 @@ BOOT_SL_SRC_C = $(addprefix simplelink/,\
|
||||
)
|
||||
|
||||
BOOT_UTIL_SRC_C = $(addprefix util/,\
|
||||
hash.c \
|
||||
cryptohash.c \
|
||||
)
|
||||
|
||||
BOOT_MAIN_SRC_C = \
|
||||
@@ -60,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 \
|
||||
)
|
||||
|
||||
|
||||
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
|
||||
@@ -125,6 +130,6 @@ $(BUILD)/bootloader.bin: $(BUILD)/bootmgr.bin
|
||||
$(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 $@
|
||||
|
||||
@@ -39,6 +39,7 @@ SECTIONS
|
||||
{
|
||||
_text = .;
|
||||
KEEP(*(.intvecs))
|
||||
*(.boot*)
|
||||
*(.text*)
|
||||
*(.rodata*)
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <std.h>
|
||||
|
||||
#include "std.h"
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
@@ -47,11 +48,12 @@
|
||||
#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"
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -62,11 +64,16 @@
|
||||
#define BOOTMGR_HASH_SIZE 32
|
||||
#define BOOTMGR_BUFF_SIZE 512
|
||||
|
||||
#define BOOTMGR_WAIT_SAFE_MODE_MS 1600
|
||||
#define BOOTMGR_WAIT_SAFE_MODE_TOOGLE_MS 200
|
||||
#define BOOTMGR_WAIT_SAFE_MODE_0_MS 500
|
||||
|
||||
#define BOOTMGR_SAFE_MODE_ENTER_MS 800
|
||||
#define BOOTMGR_SAFE_MODE_ENTER_TOOGLE_MS 80
|
||||
#define BOOTMGR_WAIT_SAFE_MODE_1_MS 3000
|
||||
#define BOOTMGR_WAIT_SAFE_MODE_1_BLINK_MS 250
|
||||
|
||||
#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
|
||||
@@ -77,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);
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -138,44 +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();
|
||||
|
||||
// clear all the special bits, since we can't trust their content after reset
|
||||
PRCMClearSpecialBit(PRCM_SAFE_BOOT_BIT);
|
||||
PRCMClearSpecialBit(PRCM_WDT_RESET_BIT);
|
||||
PRCMClearSpecialBit(PRCM_FIRST_BOOT_BIT);
|
||||
|
||||
// check the reset after clearing the special bits
|
||||
mperror_bootloader_check_reset_cause();
|
||||
|
||||
// Enable the Data Hashing Engine
|
||||
HASH_Init();
|
||||
#if MICROPY_HW_ANTENNA_DIVERSITY
|
||||
// configure the antenna selection pins
|
||||
antenna_init0();
|
||||
#endif
|
||||
|
||||
// Init the system led and the system switch
|
||||
// enable the data hashing engine
|
||||
CRYPTOHASH_Init();
|
||||
|
||||
// init the system led and the system switch
|
||||
mperror_init0();
|
||||
|
||||
// clear the safe boot flag, since we can't trust its content after reset
|
||||
PRCMClearSafeBootRequest();
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//! 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;
|
||||
@@ -185,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++) {
|
||||
@@ -196,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
|
||||
@@ -235,47 +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(MICROPY_SAFE_BOOT_PORT, MICROPY_SAFE_BOOT_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(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, ~MAP_GPIOPinRead(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN));
|
||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT(BOOTMGR_WAIT_SAFE_MODE_TOOGLE_MS * 1000));
|
||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT(period * 1000));
|
||||
}
|
||||
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));
|
||||
}
|
||||
mperror_deinit_sfe_pin();
|
||||
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(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, ~MAP_GPIOPinRead(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN));
|
||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT(BOOTMGR_SAFE_MODE_ENTER_TOOGLE_MS * 1000));
|
||||
}
|
||||
psBootInfo->ActiveImg = IMG_ACT_FACTORY;
|
||||
// turn the led off
|
||||
MAP_GPIOPinWrite(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, 0);
|
||||
// request a safe boot to the application
|
||||
PRCMRequestSafeBoot();
|
||||
_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)) {
|
||||
@@ -285,24 +336,34 @@ 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
|
||||
@@ -315,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) {
|
||||
@@ -336,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(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, MICROPY_SYS_LED_PORT_PIN);
|
||||
__asm volatile(" dsb \n"
|
||||
" isb \n"
|
||||
" wfi \n");
|
||||
__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;
|
||||
}
|
||||
|
||||
@@ -10,17 +10,19 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "py/mpconfig.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 "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "rom_map.h"
|
||||
#include "prcm.h"
|
||||
#include "pybrtc.h"
|
||||
#include "timeutils.h"
|
||||
|
||||
/* Definitions of physical drive number for each drive */
|
||||
#define SFLASH 0 /* Map SFLASH drive to drive number 0 */
|
||||
@@ -192,13 +194,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(pybrtc_get_seconds(), &tm);
|
||||
|
||||
return ((tm.tm_year - 1980) << 25) | ((tm.tm_mon) << 21) |
|
||||
((tm.tm_mday) << 16) | ((tm.tm_hour) << 11) |
|
||||
|
||||
@@ -4,10 +4,12 @@
|
||||
|
||||
#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"
|
||||
|
||||
#define SFLASH_TIMEOUT_MAX_MS 5500
|
||||
@@ -58,7 +60,7 @@ DRESULT sflash_disk_init (void) {
|
||||
print_block_name (i);
|
||||
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);
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
@@ -72,6 +74,10 @@ DRESULT sflash_disk_init (void) {
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
return RES_ERROR;
|
||||
}
|
||||
} else {
|
||||
// file system exists, break here to speed up booting
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
break;
|
||||
}
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <std.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/misc.h"
|
||||
@@ -38,7 +37,6 @@ 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;
|
||||
@@ -66,11 +64,11 @@ int ff_get_ldnumber (const TCHAR **path) {
|
||||
#endif
|
||||
}
|
||||
|
||||
if (check_path(path, "/SFLASH", 7)) {
|
||||
if (check_path(path, "/flash", 6)) {
|
||||
return 0;
|
||||
}
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
else if (check_path(path, "/SD", 3)) {
|
||||
else if (check_path(path, "/sd", 3)) {
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
@@ -84,13 +82,13 @@ void ff_get_volname(BYTE vol, TCHAR **dest) {
|
||||
if (vol == 0)
|
||||
#endif
|
||||
{
|
||||
memcpy(*dest, "/SFLASH", 7);
|
||||
*dest += 7;
|
||||
memcpy(*dest, "/flash", 6);
|
||||
*dest += 6;
|
||||
}
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
else
|
||||
{
|
||||
memcpy(*dest, "/SD", 3);
|
||||
memcpy(*dest, "/sd", 3);
|
||||
*dest += 3;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,35 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ 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 "py/mpconfig.h"
|
||||
@@ -8,8 +37,6 @@
|
||||
#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
|
||||
@@ -274,3 +297,4 @@
|
||||
/ PIC32 0 H8/300H 0 8051 0/1
|
||||
*/
|
||||
|
||||
#endif // _FFCONF
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
/* (C)ChaN, 2014 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "ff.h"
|
||||
|
||||
|
||||
@@ -134,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 */
|
||||
}
|
||||
|
||||
|
||||
@@ -146,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
|
||||
|
||||
163
cc3200/ftp/ftp.c
163
cc3200/ftp/ftp.c
@@ -26,7 +26,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ctype.h>
|
||||
#include <std.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
@@ -39,8 +39,9 @@
|
||||
#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"
|
||||
@@ -49,7 +50,7 @@
|
||||
#include "diskio.h"
|
||||
#include "sd_diskio.h"
|
||||
#include "updater.h"
|
||||
|
||||
#include "timeutils.h"
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE CONSTANTS
|
||||
@@ -67,7 +68,6 @@
|
||||
#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_SOCKETFIFO_ELEMENTS_MAX 4
|
||||
#define FTP_CYCLE_TIME_MS (SERVERS_CYCLE_TIME_MS * 2)
|
||||
|
||||
@@ -137,17 +137,16 @@ typedef struct {
|
||||
uint8_t e_open;
|
||||
bool closechild;
|
||||
bool enabled;
|
||||
bool swupdating;
|
||||
|
||||
bool special_file;
|
||||
} 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,
|
||||
@@ -174,7 +173,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
|
||||
@@ -224,7 +223,6 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
||||
static void ftp_open_child (char *pwd, char *dir);
|
||||
static void ftp_close_child (char *pwd);
|
||||
static void ftp_return_to_previous_path (char *pwd, char *dir);
|
||||
static void ftp_reset (void);
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
@@ -244,7 +242,7 @@ void ftp_init (void) {
|
||||
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.special_file = false;
|
||||
}
|
||||
|
||||
void ftp_run (void) {
|
||||
@@ -253,7 +251,7 @@ 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;
|
||||
@@ -301,19 +299,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:
|
||||
@@ -324,7 +324,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;
|
||||
}
|
||||
@@ -344,8 +344,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();
|
||||
@@ -406,6 +406,16 @@ 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.data = E_FTP_STE_SUB_DISCONNECTED;
|
||||
SOCKETFIFO_Flush();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
@@ -427,21 +437,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;
|
||||
}
|
||||
@@ -462,6 +478,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;
|
||||
}
|
||||
@@ -558,8 +577,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -588,8 +607,12 @@ static void ftp_process_cmd (void) {
|
||||
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
|
||||
@@ -665,7 +688,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;
|
||||
@@ -673,12 +696,13 @@ 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:
|
||||
{
|
||||
@@ -695,7 +719,7 @@ 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));
|
||||
pip[3], pip[2], pip[1], pip[0], (FTP_PASIVE_DATA_PORT >> 8), (FTP_PASIVE_DATA_PORT & 0xFF));
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_LISTEN_FOR_DATA;
|
||||
ftp_send_reply(227, (char *)ftp_data.dBuffer);
|
||||
}
|
||||
@@ -734,15 +758,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);
|
||||
}
|
||||
@@ -815,7 +838,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);
|
||||
}
|
||||
}
|
||||
@@ -836,9 +859,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -874,37 +897,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 = pybrtc_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 = pybrtc_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);
|
||||
@@ -956,10 +985,10 @@ static ftp_result_t ftp_open_dir_for_listing (const char *path, char *list, uint
|
||||
uint next = 0;
|
||||
// "hack" to list root directory
|
||||
if (path[0] == '/' && path[1] == '\0') {
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "SFLASH");
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "flash");
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
if (sd_disk_ready()) {
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "SD");
|
||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "sd");
|
||||
}
|
||||
#endif
|
||||
*listsize = next;
|
||||
@@ -979,11 +1008,18 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
||||
uint next = 0;
|
||||
uint count = 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) {
|
||||
// read up to 2 directory items
|
||||
while (count < 2) {
|
||||
#else
|
||||
// read up to 4 directory items
|
||||
while (count < 4) {
|
||||
#endif
|
||||
res = f_readdir(&ftp_data.dp, &fno); /* Read a directory item */
|
||||
if (res != FR_OK || fno.fname[0] == 0) {
|
||||
result = E_FTP_RESULT_OK;
|
||||
@@ -992,13 +1028,17 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
||||
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
|
||||
// add the entry to the list
|
||||
next += ftp_print_eplf_item((list + next), (maxlistsize - next), &fno);
|
||||
count++;
|
||||
}
|
||||
if (result == E_FTP_RESULT_OK) {
|
||||
ftp_close_files();
|
||||
}
|
||||
*listsize = next;
|
||||
#if _USE_LFN
|
||||
mem_Free(fno.lfname);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1047,12 +1087,3 @@ static void ftp_return_to_previous_path (char *pwd, char *dir) {
|
||||
}
|
||||
}
|
||||
|
||||
static void ftp_reset (void) {
|
||||
// close all connections and start all over again
|
||||
servers_close_socket(&ftp_data.lc_sd);
|
||||
servers_close_socket(&ftp_data.ld_sd);
|
||||
ftp_close_cmd_data();
|
||||
ftp_data.state = E_FTP_STE_START;
|
||||
ftp_data.substate.data = E_FTP_STE_SUB_DISCONNECTED;
|
||||
SOCKETFIFO_Flush();
|
||||
}
|
||||
|
||||
@@ -34,5 +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 "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,35 +62,64 @@ 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 ((sBootInfo.Status == IMG_STATUS_CHECK && sBootInfo.ActiveImg == IMG_ACT_UPDATE2) ||
|
||||
sBootInfo.ActiveImg == IMG_ACT_UPDATE1) {
|
||||
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;
|
||||
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
|
||||
@@ -67,49 +127,76 @@ bool updater_start (void) {
|
||||
}
|
||||
if (!sl_FsOpen((_u8 *)updater_data.path, AccessModeAndMaxSize, NULL, &updater_data.fhandle)) {
|
||||
updater_data.foffset = 0;
|
||||
return true;
|
||||
result = true;
|
||||
}
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
return false;
|
||||
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;
|
||||
sl_LockObjUnlock (&wlan_LockObj);
|
||||
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_ */
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
#include "mpexception.h"
|
||||
#include "telnet.h"
|
||||
#include "pybuart.h"
|
||||
#include "utils.h"
|
||||
#include "irq.h"
|
||||
|
||||
#ifdef USE_FREERTOS
|
||||
#include "FreeRTOS.h"
|
||||
@@ -107,16 +109,23 @@ 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
|
||||
}
|
||||
|
||||
void mp_hal_set_interrupt_char (int c) {
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#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)
|
||||
|
||||
@@ -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
|
||||
//*****************************************************************************
|
||||
|
||||
@@ -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))
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
|
||||
@@ -129,11 +129,12 @@
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Bit: 31 is used to indicate use of RTC. If set as '1', RTC feature is used.
|
||||
// Bit: 30 is used to indicate that a safe boot should be performed
|
||||
// bit: 29 is used to indicate that the last reset was caused by the WDT
|
||||
// Bits: 28 to 26 are unused
|
||||
// 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.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
@@ -254,94 +255,49 @@ static const PRCM_PeriphRegs_t PRCM_PeriphRegsList[] =
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Requests a safe boot
|
||||
//! Set a special bit
|
||||
//!
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void PRCMRequestSafeBoot(void)
|
||||
void PRCMSetSpecialBit(unsigned char bit)
|
||||
{
|
||||
unsigned int uiRegValue;
|
||||
|
||||
uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) | (1 << 30);
|
||||
uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) | (1 << bit);
|
||||
|
||||
PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Clear the safe boot request
|
||||
//! Clear a special bit
|
||||
//!
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void PRCMClearSafeBootRequest(void)
|
||||
void PRCMClearSpecialBit(unsigned char bit)
|
||||
{
|
||||
unsigned int uiRegValue;
|
||||
|
||||
uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(1 << 30));
|
||||
uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(1 << bit));
|
||||
|
||||
PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Read the safe boot request bit. This bit is cleared after reading.
|
||||
//! Read a special bit
|
||||
//!
|
||||
//! \return Value of the safe boot bit
|
||||
//! \return Value of the bit
|
||||
//
|
||||
//*****************************************************************************
|
||||
tBoolean PRCMIsSafeBootRequested(void)
|
||||
tBoolean PRCMGetSpecialBit(unsigned char bit)
|
||||
{
|
||||
tBoolean safeboot = (MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (1 << 30)) ? true : false;
|
||||
|
||||
PRCMClearSafeBootRequest();
|
||||
|
||||
return safeboot;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Signals that a WDT reset has occurred
|
||||
//!
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void PRCMSignalWDTReset(void)
|
||||
{
|
||||
unsigned int uiRegValue;
|
||||
|
||||
uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) | (1 << 29);
|
||||
|
||||
PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Clear the WDT reset signal
|
||||
//!
|
||||
//! \return None.
|
||||
//
|
||||
//*****************************************************************************
|
||||
void PRCMClearWDTResetSignal(void)
|
||||
{
|
||||
unsigned int uiRegValue;
|
||||
|
||||
uiRegValue = MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (~(1 << 29));
|
||||
|
||||
PRCMHIBRegWrite(RTC_MSEC_U32_REG_ADDR, uiRegValue);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! Read the WDT reset signal bit
|
||||
//!
|
||||
//! \return Value of the WDT reset signal bit
|
||||
//
|
||||
//*****************************************************************************
|
||||
tBoolean PRCMWasResetBecauseOfWDT(void)
|
||||
{
|
||||
return (MAP_PRCMHIBRegRead(RTC_MSEC_U32_REG_ADDR) & (1 << 29)) ? true : false;
|
||||
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;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
@@ -192,17 +192,21 @@ unsigned char 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 PRCMRequestSafeBoot(void);
|
||||
extern void PRCMClearSafeBootRequest(void);
|
||||
extern tBoolean PRCMIsSafeBootRequested(void);
|
||||
extern void PRCMSignalWDTReset(void);
|
||||
extern void PRCMClearWDTResetSignal(void);
|
||||
extern tBoolean PRCMWasResetBecauseOfWDT(void);
|
||||
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);
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "simplelink.h"
|
||||
#include "pybwdt.h"
|
||||
#include "debug.h"
|
||||
#include "antenna.h"
|
||||
#include "mperror.h"
|
||||
|
||||
/******************************************************************************
|
||||
@@ -65,6 +66,11 @@ 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();
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "pybuart.h"
|
||||
#include "osi.h"
|
||||
#include "pybwdt.h"
|
||||
#include "mperror.h"
|
||||
|
||||
|
||||
@@ -49,8 +48,6 @@
|
||||
//*****************************************************************************
|
||||
void vApplicationIdleHook (void)
|
||||
{
|
||||
// kick the watchdog
|
||||
pybwdt_kick();
|
||||
// signal that we are alive and kicking
|
||||
mperror_heartbeat_signal();
|
||||
// gate the processor's clock to save power
|
||||
|
||||
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
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
*
|
||||
* 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
|
||||
@@ -25,31 +24,15 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/obj.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_gpio.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "rom_map.h"
|
||||
#include "gpio.h"
|
||||
#include "pin.h"
|
||||
#include "pybpin.h"
|
||||
#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);
|
||||
|
||||
// Returns the pin mode. This value returned by this macro should be one of:
|
||||
// GPIO_DIR_MODE_IN or GPIO_DIR_MODE_OUT
|
||||
uint32_t pin_get_mode (const pin_obj_t *self) {
|
||||
return self->mode;
|
||||
}
|
||||
|
||||
uint32_t pin_get_type (const pin_obj_t *self) {
|
||||
return self->type;
|
||||
}
|
||||
|
||||
uint32_t pin_get_strenght (const pin_obj_t *self) {
|
||||
return self->strength;
|
||||
}
|
||||
|
||||
#endif /* _ANTENNA_H_ */
|
||||
@@ -24,6 +24,8 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "std.h"
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/obj.h"
|
||||
@@ -41,7 +43,7 @@
|
||||
DEFINE PUBLIC DATA
|
||||
******************************************************************************/
|
||||
const mp_arg_t mpcallback_init_args[] = {
|
||||
{ MP_QSTR_intmode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_mode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_handler, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_priority, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
|
||||
{ MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
@@ -71,7 +73,6 @@ mp_obj_t mpcallback_new (mp_obj_t parent, mp_obj_t handler, const mp_cb_methods_
|
||||
|
||||
mpcallback_obj_t *mpcallback_find (mp_obj_t parent) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(mpcallback_obj_list).len; i++) {
|
||||
// search for the object and then remove it
|
||||
mpcallback_obj_t *callback_obj = ((mpcallback_obj_t *)(MP_STATE_PORT(mpcallback_obj_list).items[i]));
|
||||
if (callback_obj->parent == parent) {
|
||||
return callback_obj;
|
||||
@@ -125,10 +126,8 @@ uint mpcallback_translate_priority (uint priority) {
|
||||
void mpcallback_handler (mp_obj_t self_in) {
|
||||
mpcallback_obj_t *self = self_in;
|
||||
if (self && self->handler != mp_const_none) {
|
||||
// disable interrupts to avoid nesting
|
||||
uint primsk = disable_irq();
|
||||
// when executing code within a handler we must lock the GC to prevent
|
||||
// any memory allocations. We must also catch any exceptions.
|
||||
// any memory allocations.
|
||||
gc_lock();
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
@@ -139,13 +138,13 @@ void mpcallback_handler (mp_obj_t self_in) {
|
||||
// uncaught exception; disable the callback so that it doesn't run again
|
||||
self->methods->disable (self->parent);
|
||||
self->handler = mp_const_none;
|
||||
// printing an exception here will cause a stack overflow that will end up in
|
||||
// a hard fault, so is better to signal the uncaught (probably non-recoverable)
|
||||
// exception by blinking the system led instead.
|
||||
// signal the error using the heart beat led and print an
|
||||
// exception message as well
|
||||
mperror_signal_error();
|
||||
printf("Uncaught exception in callback handler\n");
|
||||
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
|
||||
}
|
||||
gc_unlock();
|
||||
enable_irq(primsk);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,13 +25,14 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <std.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "hw_ints.h"
|
||||
#include "hw_types.h"
|
||||
#include "hw_gpio.h"
|
||||
@@ -63,12 +64,17 @@
|
||||
/******************************************************************************
|
||||
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;
|
||||
} mperror_heart_beat = {.off_time = 0, .on_time = 0, .beating = false, .enabled = false};
|
||||
bool do_disable;
|
||||
} mperror_heart_beat = {.off_time = 0, .on_time = 0, .beating = false, .enabled = false, .do_disable = false};
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
@@ -90,6 +96,7 @@ void mperror_init0 (void) {
|
||||
// configure the system led
|
||||
pin_config ((pin_obj_t *)&MICROPY_SYS_LED_GPIO, PIN_MODE_0, GPIO_DIR_MODE_OUT, PIN_TYPE_STD, PIN_STRENGTH_6MA);
|
||||
#endif
|
||||
mperror_heart_beat.enabled = true;
|
||||
mperror_heartbeat_switch_off();
|
||||
}
|
||||
|
||||
@@ -108,7 +115,7 @@ void mperror_bootloader_check_reset_cause (void) {
|
||||
|
||||
// since the reset cause will be changed, we must store the right reason
|
||||
// so that the application knows it when booting for the next time
|
||||
PRCMSignalWDTReset();
|
||||
PRCMSetSpecialBit(PRCM_WDT_RESET_BIT);
|
||||
|
||||
MAP_PRCMHibernateWakeupSourceEnable(PRCM_HIB_SLOW_CLK_CTR);
|
||||
// set the sleep interval to 10ms
|
||||
@@ -131,23 +138,21 @@ void mperror_signal_error (void) {
|
||||
}
|
||||
}
|
||||
|
||||
void mperror_enable_heartbeat (void) {
|
||||
mperror_heart_beat.enabled = true;
|
||||
}
|
||||
|
||||
void mperror_heartbeat_switch_off (void) {
|
||||
mperror_heart_beat.on_time = 0;
|
||||
mperror_heart_beat.off_time = 0;
|
||||
MAP_GPIOPinWrite(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, 0);
|
||||
}
|
||||
|
||||
void mperror_disable_heartbeat (void) {
|
||||
mperror_heart_beat.enabled = false;
|
||||
mperror_heartbeat_switch_off();
|
||||
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.enabled) {
|
||||
if (mperror_heart_beat.do_disable) {
|
||||
mperror_heart_beat.do_disable = false;
|
||||
mperror_heartbeat_switch_off();
|
||||
mperror_heart_beat.enabled = 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);
|
||||
@@ -198,10 +203,21 @@ void nlr_jump_fail(void *val) {
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
/// \classmethod \constructor()
|
||||
///
|
||||
/// Return the heart beat object
|
||||
STATIC mp_obj_t pyb_heartbeat_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
// check arguments
|
||||
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
||||
|
||||
// return constant object
|
||||
return (mp_obj_t)&pyb_heartbeat_obj;
|
||||
}
|
||||
|
||||
/// \function enable()
|
||||
/// Enables the heartbeat signal
|
||||
STATIC mp_obj_t pyb_enable_heartbeat(mp_obj_t self) {
|
||||
mperror_enable_heartbeat ();
|
||||
mperror_heart_beat.enabled = true;
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_enable_heartbeat_obj, pyb_enable_heartbeat);
|
||||
@@ -209,7 +225,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_enable_heartbeat_obj, pyb_enable_heartbeat)
|
||||
/// \function disable()
|
||||
/// Disables the heartbeat signal
|
||||
STATIC mp_obj_t pyb_disable_heartbeat(mp_obj_t self) {
|
||||
mperror_disable_heartbeat ();
|
||||
mperror_heart_beat.do_disable = true;
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_disable_heartbeat_obj, pyb_disable_heartbeat);
|
||||
@@ -220,11 +236,11 @@ STATIC const mp_map_elem_t pyb_heartbeat_locals_dict_table[] = {
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_heartbeat_locals_dict, pyb_heartbeat_locals_dict_table);
|
||||
|
||||
static const mp_obj_type_t pyb_heartbeat_type = {
|
||||
const mp_obj_type_t pyb_heartbeat_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_HeartBeat,
|
||||
.make_new = pyb_heartbeat_make_new,
|
||||
.locals_dict = (mp_obj_t)&pyb_heartbeat_locals_dict,
|
||||
};
|
||||
|
||||
const mp_obj_base_t pyb_heartbeat_obj = {&pyb_heartbeat_type};
|
||||
#endif
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#define MPERROR_H_
|
||||
|
||||
#ifndef BOOTLOADER
|
||||
extern const mp_obj_base_t pyb_heartbeat_obj;
|
||||
extern const mp_obj_type_t pyb_heartbeat_type;
|
||||
#endif
|
||||
|
||||
extern void NORETURN __fatal_error(const char *msg);
|
||||
@@ -38,9 +38,7 @@ void mperror_init0 (void);
|
||||
void mperror_bootloader_check_reset_cause (void);
|
||||
void mperror_deinit_sfe_pin (void);
|
||||
void mperror_signal_error (void);
|
||||
void mperror_enable_heartbeat (void);
|
||||
void mperror_heartbeat_switch_off (void);
|
||||
void mperror_disable_heartbeat (void);
|
||||
void mperror_heartbeat_signal (void);
|
||||
|
||||
#endif // MPERROR_H_
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <std.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "mpexception.h"
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/obj.h"
|
||||
#include "irq.h"
|
||||
#include "mpsystick.h"
|
||||
#include "systick.h"
|
||||
#include "inc/hw_types.h"
|
||||
|
||||
@@ -30,16 +30,17 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/obj.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "pybpin.h"
|
||||
#include MICROPY_HAL_H
|
||||
|
||||
STATIC void pin_named_pins_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
|
||||
STATIC void pin_named_pins_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pin_named_pins_obj_t *self = self_in;
|
||||
print(env, "<Pin.%s>", qstr_str(self->name));
|
||||
mp_printf(print, "<Pin.%q>", self->name);
|
||||
}
|
||||
|
||||
const mp_obj_type_t pin_cpu_pins_obj_type = {
|
||||
@@ -58,16 +59,6 @@ pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pin_obj_t *pin_find_pin(const mp_obj_dict_t *named_pins, uint pin_num) {
|
||||
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins);
|
||||
for (uint i = 0; i < named_map->used; i++) {
|
||||
if (((pin_obj_t *)named_map->table[i].value)->pin_num == pin_num) {
|
||||
return named_map->table[i].value;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pin_obj_t *pin_find_pin_by_port_bit (const mp_obj_dict_t *named_pins, uint port, uint bit) {
|
||||
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins);
|
||||
for (uint i = 0; i < named_map->used; i++) {
|
||||
|
||||
@@ -26,86 +26,75 @@
|
||||
*/
|
||||
|
||||
#include <std.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "modnetwork.h"
|
||||
#include "mpexception.h"
|
||||
#include "serverstask.h"
|
||||
#include "simplelink.h"
|
||||
|
||||
|
||||
/// \module network - network configuration
|
||||
///
|
||||
/// This module provides network drivers and routing configuration.
|
||||
/// This module provides network drivers and server configuration.
|
||||
|
||||
void mod_network_init0(void) {
|
||||
mp_obj_list_init(&MP_STATE_PORT(mod_network_nic_list), 0);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
// nic not registered so add to list
|
||||
mp_obj_list_append(&MP_STATE_PORT(mod_network_nic_list), nic);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
STATIC mp_obj_t network_route(void) {
|
||||
return &MP_STATE_PORT(mod_network_nic_list);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_route_obj, network_route);
|
||||
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
STATIC mp_obj_t network_server_start(void) {
|
||||
servers_start();
|
||||
return mp_const_none;
|
||||
STATIC mp_obj_t network_server_running(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
if (n_args > 0) {
|
||||
// set
|
||||
if (mp_obj_is_true(args[0])) {
|
||||
servers_start();
|
||||
} else {
|
||||
servers_stop();
|
||||
}
|
||||
return mp_const_none;
|
||||
} else {
|
||||
// get
|
||||
return MP_BOOL(servers_are_enabled());
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_server_start_obj, network_server_start);
|
||||
|
||||
STATIC mp_obj_t network_server_stop(void) {
|
||||
servers_stop();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_server_stop_obj, network_server_stop);
|
||||
|
||||
STATIC mp_obj_t network_server_enabled(void) {
|
||||
return MP_BOOL(servers_are_enabled());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(network_server_enabled_obj, network_server_enabled);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_server_running_obj, 0, 1, network_server_running);
|
||||
|
||||
STATIC mp_obj_t network_server_login(mp_obj_t user, mp_obj_t pass) {
|
||||
const char *_user = mp_obj_str_get_str(user);
|
||||
const char *_pass = mp_obj_str_get_str(pass);
|
||||
if (strlen(user) > SERVERS_USER_PASS_LEN_MAX || strlen(pass) > SERVERS_USER_PASS_LEN_MAX) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
servers_set_login ((char *)_user, (char *)_pass);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(network_server_login_obj, network_server_login);
|
||||
|
||||
// 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 > 0) {
|
||||
uint32_t _timeout = mp_obj_get_int(args[0]);
|
||||
if (!servers_set_timeout(_timeout * 1000)) {
|
||||
// timeout is too low
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
return mp_const_none;
|
||||
} else {
|
||||
// get
|
||||
return mp_obj_new_int(servers_get_timeout() / 1000);
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(network_server_timeout_obj, 0, 1, network_server_timeout);
|
||||
#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 },
|
||||
|
||||
#if (MICROPY_PORT_HAS_TELNET || MICROPY_PORT_HAS_FTP)
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_start_server), (mp_obj_t)&network_server_start_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_stop_server), (mp_obj_t)&network_server_stop_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_server_enabled), (mp_obj_t)&network_server_enabled_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_server_running), (mp_obj_t)&network_server_running_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_server_login), (mp_obj_t)&network_server_login_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_server_timeout), (mp_obj_t)&network_server_timeout_obj },
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -116,65 +105,3 @@ const mp_obj_module_t mp_module_network = {
|
||||
.name = MP_QSTR_network,
|
||||
.globals = (mp_obj_dict_t*)&mp_module_network_globals,
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
// Miscellaneous helpers
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
@@ -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_obj_t {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_t nic;
|
||||
mod_network_nic_type_t *nic_type;
|
||||
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;
|
||||
int8_t fileno;
|
||||
} u_param;
|
||||
int16_t sd;
|
||||
};
|
||||
bool closed;
|
||||
bool has_timeout;
|
||||
bool cert_req;
|
||||
} mod_network_socket_base_t;
|
||||
|
||||
typedef struct _mod_network_socket_obj_t {
|
||||
mp_obj_base_t base;
|
||||
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;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE FUNCTIONS
|
||||
******************************************************************************/
|
||||
void mod_network_init0(void);
|
||||
void mod_network_register_nic(mp_obj_t nic);
|
||||
mp_obj_t mod_network_find_nic(const uint8_t *ip);
|
||||
|
||||
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_
|
||||
|
||||
@@ -25,9 +25,8 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include <std.h>
|
||||
#include <stdint.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "py/mpstate.h"
|
||||
#include "py/runtime.h"
|
||||
@@ -38,6 +37,7 @@
|
||||
#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"
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "pybrtc.h"
|
||||
#include "mpsystick.h"
|
||||
#include "simplelink.h"
|
||||
#include "modnetwork.h"
|
||||
#include "modwlan.h"
|
||||
#include "moduos.h"
|
||||
#include "telnet.h"
|
||||
@@ -63,9 +64,11 @@
|
||||
#include "pybwdt.h"
|
||||
#include "pybsleep.h"
|
||||
#include "pybspi.h"
|
||||
#include "pybtimer.h"
|
||||
#include "utils.h"
|
||||
#include "gccollect.h"
|
||||
#include "mperror.h"
|
||||
#include "genhdr/mpversion.h"
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -79,17 +82,17 @@ extern OsiTaskHandle xSimpleLinkSpawnTaskHndl;
|
||||
///
|
||||
/// 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) {
|
||||
/// \function reset()
|
||||
/// Resets the pyboard in a manner similar to pushing the external
|
||||
/// reset button.
|
||||
STATIC mp_obj_t pyb_reset(void) {
|
||||
// disable wlan
|
||||
wlan_stop(SL_STOP_TIMEOUT_LONG);
|
||||
// perform a SoC reset
|
||||
PRCMSOCReset();
|
||||
// reset the cpu and it's peripherals
|
||||
MAP_PRCMMCUReset(true);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_hard_reset_obj, pyb_hard_reset);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_reset_obj, pyb_reset);
|
||||
|
||||
#ifdef DEBUG
|
||||
/// \function info([dump_alloc_table])
|
||||
@@ -123,10 +126,22 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_info_obj, 0, 1, pyb_info);
|
||||
/// \function freq()
|
||||
/// Returns the CPU frequency: (F_CPU).
|
||||
STATIC mp_obj_t pyb_freq(void) {
|
||||
return mp_obj_new_int(HAL_FCPU_HZ);
|
||||
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(pyb_freq_obj, pyb_freq);
|
||||
|
||||
/// \function unique_id()
|
||||
/// Returns a string of 6 bytes (48 bits), which is the unique ID for the MCU.
|
||||
STATIC mp_obj_t pyb_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(pyb_unique_id_obj, pyb_unique_id);
|
||||
|
||||
/// \function millis()
|
||||
/// Returns the number of milliseconds since the board was last reset.
|
||||
///
|
||||
@@ -233,27 +248,17 @@ STATIC mp_obj_t pyb_repl_uart(uint n_args, const mp_obj_t *args) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_repl_uart_obj, 0, 1, pyb_repl_uart);
|
||||
|
||||
/// \function mkdisk('path')
|
||||
/// Formats the selected drive, useful when the filesystem has been damaged beyond repair
|
||||
STATIC mp_obj_t pyb_mkdisk(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
if (FR_OK != f_mkfs(path, 1, 0)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_mkdisk_obj, pyb_mkdisk);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_main_obj); // defined in main.c
|
||||
|
||||
STATIC const mp_map_elem_t pyb_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pyb) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_reset), (mp_obj_t)&pyb_hard_reset_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_reset), (mp_obj_t)&pyb_reset_obj },
|
||||
#ifdef DEBUG
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&pyb_info_obj },
|
||||
#endif
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_freq), (mp_obj_t)&pyb_freq_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_unique_id), (mp_obj_t)&pyb_unique_id_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_repl_info), (mp_obj_t)&pyb_set_repl_info_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_repl_uart), (mp_obj_t)&pyb_repl_uart_obj },
|
||||
|
||||
@@ -268,15 +273,13 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
|
||||
{ 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)&os_sync_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mkdisk), (mp_obj_t)&pyb_mkdisk_obj },
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_rng), (mp_obj_t)&pyb_rng_get_obj },
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_ENABLE_RTC
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_RTC), (mp_obj_t)&pyb_rtc_obj },
|
||||
{ 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 },
|
||||
@@ -284,9 +287,10 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&pyb_i2c_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SPI), (mp_obj_t)&pyb_spi_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_UART), (mp_obj_t)&pyb_uart_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WDT), (mp_obj_t)&pyb_wdt_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_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_Sleep), (mp_obj_t)&pyb_sleep_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_HeartBeat), (mp_obj_t)&pyb_heartbeat_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_HeartBeat), (mp_obj_t)&pyb_heartbeat_type },
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SD), (mp_obj_t)&pyb_sd_type },
|
||||
|
||||
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,
|
||||
};
|
||||
31
cc3200/mods/modubinascii.h
Normal file
31
cc3200/mods/modubinascii.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* 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
|
||||
* 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 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,19 +27,22 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "std.h"
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "py/objstr.h"
|
||||
#include "genhdr/mpversion.h"
|
||||
#include "ff.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"
|
||||
|
||||
/// \module os - basic "operating system" services
|
||||
///
|
||||
@@ -48,12 +51,15 @@
|
||||
/// 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
|
||||
/// /sd -- the SD card (if it exists)
|
||||
///
|
||||
/// 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` if no SD card is inserted,
|
||||
/// otherwise it is `/sd`.
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC bool sd_in_root(void) {
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
return sd_disk_ready();
|
||||
@@ -62,6 +68,35 @@ STATIC bool sd_in_root(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// 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) {
|
||||
@@ -73,10 +108,9 @@ STATIC mp_obj_t os_chdir(mp_obj_t path_in) {
|
||||
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));
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
@@ -102,6 +136,7 @@ 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;
|
||||
|
||||
if (n_args == 1) {
|
||||
if (mp_obj_get_type(args[0]) == &mp_type_bytes) {
|
||||
is_str_type = false;
|
||||
@@ -114,21 +149,27 @@ STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
// "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));
|
||||
mp_obj_list_append(dir_list, MP_OBJ_NEW_QSTR(MP_QSTR_flash));
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
if (sd_in_root()) {
|
||||
mp_obj_list_append(dir_list, MP_OBJ_NEW_QSTR(MP_QSTR_SD));
|
||||
mp_obj_list_append(dir_list, MP_OBJ_NEW_QSTR(MP_QSTR_sd));
|
||||
}
|
||||
#endif
|
||||
return dir_list;
|
||||
}
|
||||
|
||||
FRESULT res;
|
||||
FILINFO fno;
|
||||
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) {
|
||||
// TODO should be mp_type_FileNotFoundError
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "No such file or directory: '%s'", path));
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
mp_obj_t dir_list = mp_obj_new_list(0, NULL);
|
||||
@@ -139,7 +180,11 @@ STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
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
|
||||
|
||||
// make a string object for this entry
|
||||
mp_obj_t entry_o;
|
||||
@@ -168,44 +213,44 @@ STATIC mp_obj_t os_mkdir(mp_obj_t path_o) {
|
||||
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));
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
break;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error creating directory '%s'", path));
|
||||
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);
|
||||
|
||||
/// \function rename(old_path, new_path)
|
||||
/// Rename a file
|
||||
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);
|
||||
|
||||
/// \function remove(path)
|
||||
/// Remove a file.
|
||||
/// Remove a file or a directory
|
||||
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));
|
||||
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);
|
||||
|
||||
/// \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);
|
||||
|
||||
// Checks for path equality, ignoring trailing slashes:
|
||||
// path_equal(/, /) -> true
|
||||
// path_equal(/flash//, /flash) -> true
|
||||
@@ -225,14 +270,18 @@ STATIC bool path_equal(const char *path, const char *path_canonical) {
|
||||
/// Get the status of a file or directory.
|
||||
STATIC mp_obj_t os_stat(mp_obj_t path_in) {
|
||||
const char *path = mp_obj_str_get_str(path_in);
|
||||
stoupper((char *)path);
|
||||
|
||||
FILINFO fno;
|
||||
FRESULT res;
|
||||
if (path_equal(path, "/") || path_equal(path, "/SFLASH") || path_equal(path, "/SD")) {
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
fno.lfname = NULL;
|
||||
fno.lfsize = 0;
|
||||
#endif
|
||||
|
||||
if (path_equal(path, "/") || path_equal(path, "/flash") || path_equal(path, "/sd")) {
|
||||
// stat built-in directory
|
||||
if (path[1] == 'S' && !sd_in_root()) {
|
||||
// no /SD directory
|
||||
if (path[1] == 's' && !sd_in_root()) {
|
||||
// no /sd directory
|
||||
res = FR_NO_PATH;
|
||||
goto error;
|
||||
}
|
||||
@@ -254,7 +303,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,
|
||||
@@ -282,11 +331,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat);
|
||||
|
||||
/// \function sync()
|
||||
/// Sync all filesystems.
|
||||
mp_obj_t os_sync(void) {
|
||||
STATIC mp_obj_t os_sync(void) {
|
||||
sflash_disk_flush();
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync);
|
||||
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
/// \function urandom(n)
|
||||
@@ -304,26 +353,38 @@ STATIC mp_obj_t os_urandom(mp_obj_t num) {
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom);
|
||||
#endif
|
||||
|
||||
/// \function mkfs('path')
|
||||
/// Formats the selected drive, useful when the filesystem has been damaged beyond repair
|
||||
STATIC mp_obj_t os_mkfs(mp_obj_t path_o) {
|
||||
const char *path = mp_obj_str_get_str(path_o);
|
||||
if (FR_OK != f_mkfs(path, 1, 0)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkfs_obj, os_mkfs);
|
||||
|
||||
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_sync), (mp_obj_t)&os_sync_obj },
|
||||
{ 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 },
|
||||
#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_mkfs), (mp_obj_t)&os_mkfs_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);
|
||||
|
||||
@@ -25,9 +25,8 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MODUTIME_H_
|
||||
#define MODUTIME_H_
|
||||
#ifndef MODUOS_H_
|
||||
#define MODUOS_H_
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(os_sync_obj);
|
||||
|
||||
#endif // MODUTIME_H_
|
||||
#endif // MODUOS_H_
|
||||
|
||||
@@ -25,69 +25,145 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <std.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "simplelink.h"
|
||||
#include "py/mpstate.h"
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_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"
|
||||
|
||||
/******************************************************************************
|
||||
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);
|
||||
@@ -98,17 +174,13 @@ 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);
|
||||
@@ -117,16 +189,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_bind_obj, socket_bind);
|
||||
STATIC mp_obj_t socket_listen(mp_obj_t self_in, mp_obj_t backlog) {
|
||||
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)));
|
||||
}
|
||||
|
||||
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, mp_obj_get_int(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);
|
||||
@@ -136,29 +202,25 @@ 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);
|
||||
@@ -169,17 +231,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);
|
||||
@@ -187,16 +248,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);
|
||||
}
|
||||
@@ -205,17 +262,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;
|
||||
@@ -236,18 +292,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);
|
||||
@@ -255,18 +307,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) {
|
||||
@@ -276,7 +327,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);
|
||||
@@ -292,7 +343,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 {
|
||||
@@ -303,10 +354,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);
|
||||
@@ -317,19 +367,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;
|
||||
}
|
||||
@@ -346,29 +392,68 @@ 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 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)&mp_identity_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,
|
||||
};
|
||||
@@ -391,28 +476,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);
|
||||
|
||||
@@ -422,6 +498,10 @@ 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) },
|
||||
@@ -430,6 +510,7 @@ STATIC const mp_map_elem_t mp_module_usocket_globals_table[] = {
|
||||
{ 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) },
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -24,19 +24,16 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
typedef unsigned int size_t;
|
||||
#ifndef MODUSOCKET_H_
|
||||
#define MODUSOCKET_H_
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
void *memmove(void *dest, const void *src, size_t n);
|
||||
void *memset(void *s, int c, size_t n);
|
||||
extern const mp_obj_dict_t socket_locals_dict;
|
||||
extern const mp_stream_p_t socket_stream_p;
|
||||
|
||||
size_t strlen(const char *str);
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
int strncmp(const char *s1, const char *s2, size_t n);
|
||||
char *strcpy(char *dest, const char *src);
|
||||
char *strcat(char *dest, const char *src);
|
||||
char *strchr(const char *s, int c);
|
||||
char *strstr(const char *haystack, const char *needle);
|
||||
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);
|
||||
|
||||
int printf(const char *fmt, ...);
|
||||
int snprintf(char *str, size_t size, const char *fmt, ...);
|
||||
#endif /* MODUSOCKET_H_ */
|
||||
149
cc3200/mods/modussl.c
Normal file
149
cc3200/mods/modussl.c
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Daniel Campora
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <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 socket inherits 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_OBJ, {.u_obj = mp_const_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) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
// server side param is irrelevant for us (at least for the moment)
|
||||
|
||||
// retrieve the file paths (with an 6 byte offset because to strip 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]);
|
||||
|
||||
_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 socket inherits 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)));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_ssl_wrap_socket_obj, 1, 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,
|
||||
};
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/nlr.h"
|
||||
#include "py/obj.h"
|
||||
#include "modutime.h"
|
||||
#include "timeutils.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
@@ -41,126 +41,11 @@
|
||||
#include "pybrtc.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)
|
||||
|
||||
|
||||
/// \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);
|
||||
}
|
||||
|
||||
/// \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)
|
||||
@@ -175,30 +60,30 @@ 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;
|
||||
timeutils_struct_time_t 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_seconds_since_2000_to_struct_time(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),
|
||||
@@ -220,7 +105,6 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(time_localtime_obj, 0, 1, time_localtime);
|
||||
/// 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;
|
||||
|
||||
@@ -231,72 +115,20 @@ 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);
|
||||
|
||||
|
||||
/// \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));
|
||||
/// \function sleep(seconds)
|
||||
/// Sleep for the given number of seconds.
|
||||
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);
|
||||
@@ -304,12 +136,7 @@ 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);
|
||||
return mp_obj_new_int(pybrtc_get_seconds());
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -43,7 +43,7 @@ typedef enum {
|
||||
MODWLAN_ERROR_INVALID_PARAMS = -1,
|
||||
MODWLAN_ERROR_TIMEOUT = -2,
|
||||
MODWLAN_ERROR_UNKNOWN = -3,
|
||||
}modwlan_Status_t;
|
||||
} modwlan_Status_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC DATA
|
||||
@@ -53,13 +53,31 @@ 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_pre_init (void);
|
||||
extern void wlan_sl_enable (int8_t mode, const char *ssid, uint8_t ssid_len, uint8_t sec,
|
||||
const char *key, uint8_t key_len, uint8_t channel, bool append_mac);
|
||||
extern void wlan_first_start (void);
|
||||
extern void wlan_update(void);
|
||||
extern void wlan_stop (uint32_t timeout);
|
||||
extern void wlan_start (void);
|
||||
extern void wlan_get_mac (uint8_t *macAddress);
|
||||
extern void wlan_get_ip (uint32_t *ip);
|
||||
extern bool wlan_is_connected (void);
|
||||
extern void wlan_set_current_time (uint32_t seconds_since_2000);
|
||||
|
||||
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_ */
|
||||
|
||||
@@ -57,10 +57,8 @@
|
||||
///
|
||||
/// Usage:
|
||||
///
|
||||
/// adc = pyb.ADC(channel) # create an adc object on the given channel (0 to 3)
|
||||
/// this automatically configures the pin associated to
|
||||
/// that analog channel.
|
||||
/// adc.read() # read channel value
|
||||
/// adc = pyb.ADC('GP5') # create an adc object on the given pin (GP2, GP3, GP4 o GP5)
|
||||
/// adc.read() # read channel value
|
||||
///
|
||||
/// The sample rate is fixed to 62.5KHz and the resolution to 12 bits.
|
||||
|
||||
@@ -75,14 +73,23 @@
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
pin_obj_t *pin;
|
||||
byte channel;
|
||||
byte num;
|
||||
byte id;
|
||||
} pyb_adc_obj_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC pyb_adc_obj_t pyb_adc_obj[PYB_ADC_NUM_CHANNELS] = { {.pin = &pin_GP2, .channel = ADC_CH_0, .id = 1}, {.pin = &pin_GP3, .channel = ADC_CH_1, .id = 2},
|
||||
{.pin = &pin_GP4, .channel = ADC_CH_2, .id = 2}, {.pin = &pin_GP5, .channel = ADC_CH_3, .id = 4} };
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC void pybadc_init (pyb_adc_obj_t *self) {
|
||||
// configure the pin in analog mode
|
||||
pin_config (self->pin, PIN_MODE_0, GPIO_DIR_MODE_IN, PYBPIN_ANALOG_TYPE, PIN_STRENGTH_2MA);
|
||||
// enable the ADC channel
|
||||
MAP_ADCChannelEnable(ADC_BASE, self->channel);
|
||||
// enable and configure the timer
|
||||
@@ -92,68 +99,34 @@ STATIC void pybadc_init (pyb_adc_obj_t *self) {
|
||||
MAP_ADCEnable(ADC_BASE);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC pyb_adc_obj_t pyb_adc_obj[PYB_ADC_NUM_CHANNELS];
|
||||
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings : adc object */
|
||||
|
||||
STATIC void adc_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
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;
|
||||
print(env, "<ADC, channel=%u>", self->num);
|
||||
mp_printf(print, "<ADC1 channel=%u on %q>", self->id, self->pin->name);
|
||||
}
|
||||
|
||||
/// \classmethod \constructor(channel)
|
||||
/// Create an ADC object associated with the given channel.
|
||||
/// \classmethod \constructor(pin)
|
||||
/// Create an ADC object associated with the given pin.
|
||||
/// This allows you to then read analog values on that pin.
|
||||
STATIC mp_obj_t adc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
// check number of arguments
|
||||
mp_arg_check_num(n_args, n_kw, 1, 1, false);
|
||||
|
||||
// the first argument is the channel number
|
||||
uint num = mp_obj_get_int(args[0]);
|
||||
const pin_obj_t *pin;
|
||||
uint channel;
|
||||
switch (num) {
|
||||
case 0:
|
||||
channel = ADC_CH_0;
|
||||
pin = &pin_GPIO2;
|
||||
break;
|
||||
case 1:
|
||||
channel = ADC_CH_1;
|
||||
pin = &pin_GPIO3;
|
||||
break;
|
||||
case 2:
|
||||
channel = ADC_CH_2;
|
||||
pin = &pin_GPIO4;
|
||||
break;
|
||||
case 3:
|
||||
channel = ADC_CH_3;
|
||||
pin = &pin_GPIO5;
|
||||
break;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
break;
|
||||
// the argument passed is the pin
|
||||
const pin_obj_t *pin = (pin_obj_t *)pin_find(args[0]);
|
||||
for (int32_t idx = 0; idx < PYB_ADC_NUM_CHANNELS; idx++) {
|
||||
if (pin == pyb_adc_obj[idx].pin) {
|
||||
pyb_adc_obj_t *self = &pyb_adc_obj[idx];
|
||||
self->base.type = &pyb_adc_type;
|
||||
pybadc_init (self);
|
||||
// register it with the sleep module
|
||||
pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)pybadc_init);
|
||||
return self;
|
||||
}
|
||||
}
|
||||
|
||||
// disable the callback before re-configuring
|
||||
pyb_adc_obj_t *self = &pyb_adc_obj[channel];
|
||||
self->base.type = &pyb_adc_type;
|
||||
self->channel = channel;
|
||||
self->num = num;
|
||||
|
||||
// configure the pin in analog mode
|
||||
pin_config ((pin_obj_t *)pin, PIN_MODE_0, GPIO_DIR_MODE_IN, PYBPIN_ANALOG_TYPE, PIN_STRENGTH_2MA);
|
||||
|
||||
// initialize it
|
||||
pybadc_init (self);
|
||||
|
||||
// register it with the sleep module
|
||||
pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)pybadc_init);
|
||||
|
||||
return self;
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
/// \method read()
|
||||
@@ -172,19 +145,19 @@ STATIC mp_obj_t adc_read(mp_obj_t self_in) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_read_obj, adc_read);
|
||||
|
||||
/// \method enable()
|
||||
/// \method init()
|
||||
/// Enable the adc channel
|
||||
STATIC mp_obj_t adc_enable(mp_obj_t self_in) {
|
||||
STATIC mp_obj_t adc_init(mp_obj_t self_in) {
|
||||
pyb_adc_obj_t *self = self_in;
|
||||
|
||||
pybadc_init(self);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_enable_obj, adc_enable);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_init_obj, adc_init);
|
||||
|
||||
/// \method disable()
|
||||
/// \method deinit()
|
||||
/// Disable the adc channel
|
||||
STATIC mp_obj_t adc_disable(mp_obj_t self_in) {
|
||||
STATIC mp_obj_t adc_deinit(mp_obj_t self_in) {
|
||||
pyb_adc_obj_t *self = self_in;
|
||||
|
||||
MAP_ADCChannelDisable(ADC_BASE, self->channel);
|
||||
@@ -192,12 +165,12 @@ STATIC mp_obj_t adc_disable(mp_obj_t self_in) {
|
||||
pybsleep_remove ((const mp_obj_t)self);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_disable_obj, adc_disable);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_deinit_obj, adc_deinit);
|
||||
|
||||
STATIC const mp_map_elem_t adc_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&adc_read_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&adc_enable_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable), (mp_obj_t)&adc_disable_obj },
|
||||
{ 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 },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(adc_locals_dict, adc_locals_dict_table);
|
||||
|
||||
@@ -56,10 +56,10 @@
|
||||
///
|
||||
/// from pyb import I2C
|
||||
///
|
||||
/// i2c = I2C() # create
|
||||
/// i2c = I2C(50000) # create and init with a 50KHz baudrate
|
||||
/// i2c.init(100000) # init with a 100KHz baudrate
|
||||
/// i2c.deinit() # turn off the peripheral
|
||||
/// i2c = I2C(1) # create
|
||||
/// i2c = I2C(1, I2C.MASTER, baudrate=50000) # create and init with a 50KHz baudrate
|
||||
/// i2c.init(I2C.MASTER, baudrate=100000) # init with a 100KHz baudrate
|
||||
/// i2c.deinit() # turn off the peripheral
|
||||
///
|
||||
/// Printing the i2c object gives you information about its configuration.
|
||||
///
|
||||
@@ -76,7 +76,6 @@
|
||||
///
|
||||
/// A master must specify the recipient's address:
|
||||
///
|
||||
/// i2c.init(100000)
|
||||
/// i2c.send('123', 0x42) # send 3 bytes to slave with address 0x42
|
||||
/// i2c.send(b'456', addr=0x42) # keyword for address
|
||||
///
|
||||
@@ -98,6 +97,8 @@ typedef struct _pyb_i2c_obj_t {
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYBI2C_MASTER (0)
|
||||
|
||||
#define PYBI2C_MIN_BAUD_RATE_HZ (50000)
|
||||
#define PYBI2C_MAX_BAUD_RATE_HZ (400000)
|
||||
|
||||
@@ -251,16 +252,40 @@ STATIC bool pyb_i2c_scan_device(byte devAddr) {
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings */
|
||||
/******************************************************************************/
|
||||
|
||||
/// \method init(100000)
|
||||
///
|
||||
/// Initialise the I2C bus as a master with the given baudrate.
|
||||
///
|
||||
STATIC mp_obj_t pyb_i2c_init_helper(pyb_i2c_obj_t *self_in, mp_obj_t baudrate) {
|
||||
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, "<I2C1, I2C.MASTER, baudrate=%u>)", self->baudrate);
|
||||
}
|
||||
else {
|
||||
mp_print_str(print, "<I2C1>");
|
||||
}
|
||||
}
|
||||
|
||||
/// \method init(mode, *, baudrate=100000)
|
||||
///
|
||||
/// Initialise the I2C bus with the given parameters:
|
||||
///
|
||||
/// - `mode` must be either `I2C.MASTER` or `I2C.SLAVE`
|
||||
/// - `baudrate` is the SCL clock rate (only sensible for a master)
|
||||
STATIC const mp_arg_t pyb_i2c_init_args[] = {
|
||||
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, },
|
||||
{ MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 100000} },
|
||||
};
|
||||
#define PYB_I2C_INIT_NUM_ARGS MP_ARRAY_SIZE(pyb_i2c_init_args)
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_init_helper(pyb_i2c_obj_t *self, mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
// parse args
|
||||
mp_arg_val_t vals[PYB_I2C_INIT_NUM_ARGS];
|
||||
mp_arg_parse_all(n_args, args, kw_args, PYB_I2C_INIT_NUM_ARGS, pyb_i2c_init_args, vals);
|
||||
|
||||
// verify that mode is master
|
||||
if (vals[0].u_int != PYBI2C_MASTER) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
// make sure the baudrate is between the valid range
|
||||
self->baudrate = MIN(MAX(mp_obj_get_int(baudrate), PYBI2C_MIN_BAUD_RATE_HZ), PYBI2C_MAX_BAUD_RATE_HZ);
|
||||
self->baudrate = MIN(MAX(vals[1].u_int, PYBI2C_MIN_BAUD_RATE_HZ), PYBI2C_MAX_BAUD_RATE_HZ);
|
||||
|
||||
// init the I2C bus
|
||||
i2c_init(self);
|
||||
@@ -273,7 +298,7 @@ STATIC mp_obj_t pyb_i2c_init_helper(pyb_i2c_obj_t *self_in, mp_obj_t baudrate) {
|
||||
|
||||
/// \classmethod \constructor(bus, ...)
|
||||
///
|
||||
/// Construct an I2C object on the given bus. `bus` can only be 0.
|
||||
/// Construct an I2C object on the given bus. `bus` can only be 1.
|
||||
/// With no additional parameters, the I2C object is created but not
|
||||
/// initialised (it has the settings from the last initialisation of
|
||||
/// the bus, if any). If extra arguments are given, the bus is initialised.
|
||||
@@ -286,28 +311,20 @@ STATIC mp_obj_t pyb_i2c_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n
|
||||
pyb_i2c_obj_t *self = &pyb_i2c_obj;
|
||||
self->base.type = &pyb_i2c_type;
|
||||
|
||||
if (n_args > 0) {
|
||||
if (n_args > 1 || n_kw > 0) {
|
||||
// start the peripheral
|
||||
pyb_i2c_init_helper(self, *args);
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
|
||||
pyb_i2c_init_helper(self, n_args - 1, args + 1, &kw_args);
|
||||
}
|
||||
|
||||
return (mp_obj_t)self;
|
||||
}
|
||||
|
||||
STATIC void pyb_i2c_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_i2c_obj_t *self = self_in;
|
||||
if (self->baudrate > 0) {
|
||||
print(env, "<I2C0, I2C.MASTER, baudrate=%u>)", self->baudrate);
|
||||
}
|
||||
else {
|
||||
print(env, "<I2C0>");
|
||||
}
|
||||
STATIC mp_obj_t pyb_i2c_init(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
return pyb_i2c_init_helper(args[0], n_args - 1, args + 1, kw_args);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_i2c_init(mp_obj_t self_in, mp_obj_t baudrate) {
|
||||
return pyb_i2c_init_helper(self_in, baudrate);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_i2c_init_obj, pyb_i2c_init);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_init_obj, 1, pyb_i2c_init);
|
||||
|
||||
/// \method deinit()
|
||||
/// Turn off the I2C bus.
|
||||
@@ -361,8 +378,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_i2c_scan_obj, pyb_i2c_scan);
|
||||
/// - `addr` is the address to send to (only required in master mode)
|
||||
/// Return value: `None`.
|
||||
STATIC const mp_arg_t pyb_i2c_send_args[] = {
|
||||
{ MP_QSTR_send, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_send, MP_ARG_REQUIRED | MP_ARG_OBJ, },
|
||||
{ MP_QSTR_addr, MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
|
||||
};
|
||||
#define PYB_I2C_SEND_NUM_ARGS MP_ARRAY_SIZE(pyb_i2c_send_args)
|
||||
|
||||
@@ -396,8 +414,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_send_obj, 1, pyb_i2c_send);
|
||||
/// Return value: if `recv` is an integer then a new buffer of the bytes received,
|
||||
/// otherwise the same buffer that was passed in to `recv`.
|
||||
STATIC const mp_arg_t pyb_i2c_recv_args[] = {
|
||||
{ MP_QSTR_recv, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_recv, MP_ARG_REQUIRED | MP_ARG_OBJ, },
|
||||
{ MP_QSTR_addr, MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
|
||||
};
|
||||
#define PYB_I2C_RECV_NUM_ARGS MP_ARRAY_SIZE(pyb_i2c_recv_args)
|
||||
|
||||
@@ -437,9 +456,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_i2c_recv_obj, 1, pyb_i2c_recv);
|
||||
/// Returns the read data.
|
||||
/// This is only valid in master mode.
|
||||
STATIC const mp_arg_t pyb_i2c_mem_read_args[] = {
|
||||
{ MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ, },
|
||||
{ MP_QSTR_addr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_memaddr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
|
||||
{ MP_QSTR_addr_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
|
||||
};
|
||||
#define PYB_I2C_MEM_READ_NUM_ARGS MP_ARRAY_SIZE(pyb_i2c_mem_read_args)
|
||||
@@ -529,6 +549,10 @@ STATIC const mp_map_elem_t pyb_i2c_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&pyb_i2c_recv_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mem_read), (mp_obj_t)&pyb_i2c_mem_read_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mem_write), (mp_obj_t)&pyb_i2c_mem_write_obj },
|
||||
|
||||
// class constants
|
||||
/// \constant MASTER - for initialising the bus to master mode
|
||||
{ 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);
|
||||
|
||||
@@ -61,29 +61,7 @@
|
||||
///
|
||||
/// Usage Model:
|
||||
///
|
||||
/// All CPU Pins are predefined as pyb.Pin.cpu.Name
|
||||
///
|
||||
/// GPIO9_pin = pyb.Pin.cpu.GPIO9
|
||||
///
|
||||
/// g = pyb.Pin(pyb.Pin.cpu.GPIO9, 0, pyb.Pin.IN)
|
||||
///
|
||||
/// CPU pins which correspond to the board pins are available
|
||||
/// as `pyb.cpu.Name`.
|
||||
///
|
||||
/// You can also use strings:
|
||||
///
|
||||
/// g = pyb.Pin('GPIO9', 0)
|
||||
///
|
||||
/// And finally, you can also pass a pin number directly:
|
||||
///
|
||||
/// g = pyb.Pin(64, 0)
|
||||
///
|
||||
/// To summarise, the following order determines how things get mapped into
|
||||
/// an ordinal pin number:
|
||||
///
|
||||
/// 1. Directly specify a Pin object
|
||||
/// 2. Supply a string which matches a CPU pin name
|
||||
/// 3. Provide a pin number
|
||||
/// g = pyb.Pin('GPIO9', af=0, mode=pyb.Pin.IN, type=pyb.Pin.STD, strength=pyb.Pin.S2MA)
|
||||
///
|
||||
/// \Interrupts:
|
||||
//// You can also configure the Pin to generate interrupts
|
||||
@@ -91,10 +69,10 @@
|
||||
/// Example callback:
|
||||
///
|
||||
/// def pincb(pin):
|
||||
/// print(pin.pin())
|
||||
/// print(pin.name())
|
||||
///
|
||||
/// extint = pyb.Pin('GPIO10', 0, pyb.Pin.INT_RISING, pyb.GPIO.STD_PD, pyb.S2MA)
|
||||
/// extint.callback (intmode=pyb.Pin.INT_RISING, handler=pincb)
|
||||
/// extint.callback (mode=pyb.Pin.INT_RISING, handler=pincb)
|
||||
/// # the callback can be triggered manually
|
||||
/// extint.callback()()
|
||||
/// # to disable the callback
|
||||
@@ -114,15 +92,17 @@
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC void pin_obj_configure (const pin_obj_t *self);
|
||||
STATIC void pin_get_hibernate_pin_and_idx (const pin_obj_t *self, uint *wake_pin, uint *idx);
|
||||
STATIC void pin_extint_enable (mp_obj_t self_in);
|
||||
STATIC void pin_extint_disable (mp_obj_t self_in);
|
||||
STATIC void pin_verify_af (uint af);
|
||||
STATIC void pin_extint_register(pin_obj_t *self, uint32_t intmode, uint32_t priority);
|
||||
STATIC void GPIOA0IntHandler (void);
|
||||
STATIC void GPIOA1IntHandler (void);
|
||||
STATIC void GPIOA2IntHandler (void);
|
||||
STATIC void GPIOA3IntHandler (void);
|
||||
STATIC void EXTI_Handler(uint port);
|
||||
STATIC void pin_obj_configure (const pin_obj_t *self);
|
||||
STATIC void pin_get_hibernate_pin_and_idx (const pin_obj_t *self, uint *wake_pin, uint *idx);
|
||||
STATIC void pin_extint_enable (mp_obj_t self_in);
|
||||
STATIC void pin_extint_disable (mp_obj_t self_in);
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
@@ -155,48 +135,32 @@ STATIC pybpin_wake_pin_t pybpin_wake_pin[PYBPIN_NUM_WAKE_PINS] =
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
void pin_init0(void) {
|
||||
// assign GPIO10 and GPIO11 to the GPIO peripheral (the default is I2C), so that the I2C bus can
|
||||
// assign GP10 and GP11 to the GPIO peripheral (the default is I2C), so that the I2C bus can
|
||||
// be assigned safely to any other pins (as recomended by the SDK release notes). Make them
|
||||
// inputs with pull-downs enabled to ensure they are not floating during LDPS and hibernate.
|
||||
pin_config ((pin_obj_t *)&pin_GPIO10, PIN_MODE_0, GPIO_DIR_MODE_IN, PIN_TYPE_STD_PD, PIN_STRENGTH_2MA);
|
||||
pin_config ((pin_obj_t *)&pin_GPIO11, PIN_MODE_0, GPIO_DIR_MODE_IN, PIN_TYPE_STD_PD, PIN_STRENGTH_2MA);
|
||||
pin_config ((pin_obj_t *)&pin_GP10, PIN_MODE_0, GPIO_DIR_MODE_IN, PIN_TYPE_STD_PD, PIN_STRENGTH_2MA);
|
||||
pin_config ((pin_obj_t *)&pin_GP11, PIN_MODE_0, GPIO_DIR_MODE_IN, PIN_TYPE_STD_PD, PIN_STRENGTH_2MA);
|
||||
}
|
||||
|
||||
// C API used to convert a user-supplied pin name into an ordinal pin number.
|
||||
pin_obj_t *pin_find(mp_obj_t user_obj) {
|
||||
pin_obj_t *pin_obj;
|
||||
|
||||
// If a pin was provided, then use it
|
||||
// if a pin was provided, use it
|
||||
if (MP_OBJ_IS_TYPE(user_obj, &pin_type)) {
|
||||
pin_obj = user_obj;
|
||||
return pin_obj;
|
||||
}
|
||||
|
||||
// See if the pin name matches a cpu pin
|
||||
// otherwise see if the pin name matches a cpu pin
|
||||
pin_obj = pin_find_named_pin(&pin_cpu_pins_locals_dict, user_obj);
|
||||
if (pin_obj) {
|
||||
return pin_obj;
|
||||
}
|
||||
|
||||
// See if the pin number matches a cpu pin
|
||||
mp_int_t pin_num;
|
||||
if (mp_obj_get_int_maybe(user_obj, &pin_num)) {
|
||||
// The Pins dictionary has pin indexes, so we must substract one from the value passed
|
||||
pin_obj = pin_find_pin(&pin_cpu_pins_locals_dict, (pin_num - 1));
|
||||
if (pin_obj) {
|
||||
return pin_obj;
|
||||
}
|
||||
}
|
||||
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
void pin_verify_af (uint af) {
|
||||
if (af > PIN_MODE_15) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
|
||||
void pin_config (pin_obj_t *self, uint af, uint mode, uint type, uint strength) {
|
||||
// configure the pin in analog mode
|
||||
self->af = af, self->mode = mode, self->type = type, self->strength = strength;
|
||||
@@ -207,37 +171,6 @@ void pin_config (pin_obj_t *self, uint af, uint mode, uint type, uint strength)
|
||||
pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)pin_obj_configure);
|
||||
}
|
||||
|
||||
void pin_extint_register(pin_obj_t *self, uint32_t intmode, uint32_t priority) {
|
||||
void *handler;
|
||||
uint32_t intnum;
|
||||
|
||||
// configure the interrupt type
|
||||
MAP_GPIOIntTypeSet(self->port, self->bit, intmode);
|
||||
switch (self->port) {
|
||||
case GPIOA0_BASE:
|
||||
handler = GPIOA0IntHandler;
|
||||
intnum = INT_GPIOA0;
|
||||
break;
|
||||
case GPIOA1_BASE:
|
||||
handler = GPIOA1IntHandler;
|
||||
intnum = INT_GPIOA1;
|
||||
break;
|
||||
case GPIOA2_BASE:
|
||||
handler = GPIOA2IntHandler;
|
||||
intnum = INT_GPIOA2;
|
||||
break;
|
||||
case GPIOA3_BASE:
|
||||
default:
|
||||
handler = GPIOA3IntHandler;
|
||||
intnum = INT_GPIOA3;
|
||||
break;
|
||||
}
|
||||
MAP_GPIOIntRegister(self->port, handler);
|
||||
// set the interrupt to the lowest priority, to make sure that
|
||||
// no other ISRs will be preemted by this one
|
||||
MAP_IntPrioritySet(intnum, priority);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
@@ -277,27 +210,27 @@ STATIC void pin_obj_configure (const pin_obj_t *self) {
|
||||
STATIC void pin_get_hibernate_pin_and_idx (const pin_obj_t *self, uint *hib_pin, uint *idx) {
|
||||
// pin_num is actually : (package_pin - 1)
|
||||
switch (self->pin_num) {
|
||||
case 56: // GPIO2
|
||||
case 56: // GP2
|
||||
*hib_pin = PRCM_HIB_GPIO2;
|
||||
*idx = 0;
|
||||
break;
|
||||
case 58: // GPIO4
|
||||
case 58: // GP4
|
||||
*hib_pin = PRCM_HIB_GPIO4;
|
||||
*idx = 1;
|
||||
break;
|
||||
case 3: // GPIO13
|
||||
case 3: // GP13
|
||||
*hib_pin = PRCM_HIB_GPIO13;
|
||||
*idx = 2;
|
||||
break;
|
||||
case 7: // GPIO17
|
||||
case 7: // GP17
|
||||
*hib_pin = PRCM_HIB_GPIO17;
|
||||
*idx = 3;
|
||||
break;
|
||||
case 1: // GPIO11
|
||||
case 1: // GP11
|
||||
*hib_pin = PRCM_HIB_GPIO11;
|
||||
*idx = 4;
|
||||
break;
|
||||
case 16: // GPIO24
|
||||
case 16: // GP24
|
||||
*hib_pin = PRCM_HIB_GPIO24;
|
||||
*idx = 5;
|
||||
break;
|
||||
@@ -358,6 +291,77 @@ STATIC void pin_extint_disable (mp_obj_t self_in) {
|
||||
MAP_GPIOIntDisable(self->port, self->bit);
|
||||
}
|
||||
|
||||
STATIC void pin_verify_af (uint af) {
|
||||
if (af > PIN_MODE_15) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void pin_extint_register(pin_obj_t *self, uint32_t intmode, uint32_t priority) {
|
||||
void *handler;
|
||||
uint32_t intnum;
|
||||
|
||||
// configure the interrupt type
|
||||
MAP_GPIOIntTypeSet(self->port, self->bit, intmode);
|
||||
switch (self->port) {
|
||||
case GPIOA0_BASE:
|
||||
handler = GPIOA0IntHandler;
|
||||
intnum = INT_GPIOA0;
|
||||
break;
|
||||
case GPIOA1_BASE:
|
||||
handler = GPIOA1IntHandler;
|
||||
intnum = INT_GPIOA1;
|
||||
break;
|
||||
case GPIOA2_BASE:
|
||||
handler = GPIOA2IntHandler;
|
||||
intnum = INT_GPIOA2;
|
||||
break;
|
||||
case GPIOA3_BASE:
|
||||
default:
|
||||
handler = GPIOA3IntHandler;
|
||||
intnum = INT_GPIOA3;
|
||||
break;
|
||||
}
|
||||
MAP_GPIOIntRegister(self->port, handler);
|
||||
// set the interrupt to the lowest priority, to make sure that
|
||||
// no other ISRs will be preemted by this one
|
||||
MAP_IntPrioritySet(intnum, priority);
|
||||
}
|
||||
|
||||
STATIC void GPIOA0IntHandler (void) {
|
||||
EXTI_Handler(GPIOA0_BASE);
|
||||
}
|
||||
|
||||
STATIC void GPIOA1IntHandler (void) {
|
||||
EXTI_Handler(GPIOA1_BASE);
|
||||
}
|
||||
|
||||
STATIC void GPIOA2IntHandler (void) {
|
||||
EXTI_Handler(GPIOA2_BASE);
|
||||
}
|
||||
|
||||
STATIC void GPIOA3IntHandler (void) {
|
||||
EXTI_Handler(GPIOA3_BASE);
|
||||
}
|
||||
|
||||
// common interrupt handler
|
||||
STATIC void EXTI_Handler(uint port) {
|
||||
uint32_t bits = MAP_GPIOIntStatus(port, true);
|
||||
MAP_GPIOIntClear(port, bits);
|
||||
|
||||
// might be that we have more than one Pin interrupt pending
|
||||
// therefore we must loop through all of the 8 possible bits
|
||||
for (int i = 0; i < 8; i++) {
|
||||
uint32_t bit = (1 << i);
|
||||
if (bit & bits) {
|
||||
pin_obj_t *self = (pin_obj_t *)pin_find_pin_by_port_bit(&pin_cpu_pins_locals_dict, port, bit);
|
||||
mp_obj_t _callback = mpcallback_find(self);
|
||||
mpcallback_handler(_callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
@@ -365,7 +369,7 @@ STATIC void pin_extint_disable (mp_obj_t self_in) {
|
||||
/// Initialise the pin:
|
||||
///
|
||||
/// - `af` can be in range 0-15, please check the CC3200 datasheet
|
||||
/// for the details on the AFs availables on each pin (af=0, keeps it as a gpio pin).
|
||||
/// for the details on the AFs availables on each pin (af=0 keeps it as a gpio pin).
|
||||
/// - `mode` can be one of:
|
||||
/// - `Pin.IN` - configure the pin for input;
|
||||
/// - `Pin.OUT` - configure the pin for output;
|
||||
@@ -376,7 +380,6 @@ STATIC void pin_extint_disable (mp_obj_t self_in) {
|
||||
/// - `Pin.OD` - standard without pull up or pull down;
|
||||
/// - `Pin.OD_PU` - open drain with pull-up resistor;
|
||||
/// - `Pin.OD_PD` - open drain with pull-down resistor.
|
||||
/// - `Pin.ANALOG` - configured in analog (adc) mode
|
||||
/// - `strength` can be one of:
|
||||
/// - `Pin.S2MA` - 2ma drive strength;
|
||||
/// - `Pin.S4MA` - 4ma drive strength;
|
||||
@@ -387,7 +390,7 @@ STATIC const mp_arg_t pin_init_args[] = {
|
||||
{ MP_QSTR_af, MP_ARG_REQUIRED | MP_ARG_INT },
|
||||
{ MP_QSTR_mode, MP_ARG_INT, {.u_int = GPIO_DIR_MODE_OUT} },
|
||||
{ MP_QSTR_type, MP_ARG_INT, {.u_int = PIN_TYPE_STD} },
|
||||
{ MP_QSTR_str, MP_ARG_INT, {.u_int = PIN_STRENGTH_4MA} },
|
||||
{ MP_QSTR_strength, MP_ARG_INT, {.u_int = PIN_STRENGTH_4MA} },
|
||||
};
|
||||
#define pin_INIT_NUM_ARGS MP_ARRAY_SIZE(pin_init_args)
|
||||
|
||||
@@ -399,55 +402,59 @@ STATIC mp_obj_t pin_obj_init_helper(pin_obj_t *self, mp_uint_t n_args, const mp_
|
||||
// get the af
|
||||
uint af = args[0].u_int;
|
||||
if (af < PIN_MODE_0 || af > PIN_MODE_15) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
goto invalid_args;
|
||||
}
|
||||
// get the io mode
|
||||
uint mode = args[1].u_int;
|
||||
// checking the mode only makes sense if af == GPIO
|
||||
if (af == PIN_MODE_0) {
|
||||
if (mode != GPIO_DIR_MODE_IN && mode != GPIO_DIR_MODE_OUT) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
goto invalid_args;
|
||||
}
|
||||
}
|
||||
// get the type
|
||||
uint type = args[2].u_int;
|
||||
if (type != PIN_TYPE_STD && type != PIN_TYPE_STD_PU && type != PIN_TYPE_STD_PD &&
|
||||
type != PIN_TYPE_OD && type != PIN_TYPE_OD_PU && type != PIN_TYPE_OD_PD) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
goto invalid_args;
|
||||
}
|
||||
// get the strenght
|
||||
uint strength = args[3].u_int;
|
||||
if (strength != PIN_STRENGTH_2MA && strength != PIN_STRENGTH_4MA && strength != PIN_STRENGTH_6MA) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
// configure the pin as requested
|
||||
pin_config (self, af, mode, type, strength);
|
||||
|
||||
return mp_const_none;
|
||||
|
||||
invalid_args:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
/// \method print()
|
||||
/// Return a string describing the pin object.
|
||||
STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
STATIC void pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pin_obj_t *self = self_in;
|
||||
uint32_t af = MAP_PinModeGet(self->pin_num);
|
||||
uint32_t type = pin_get_type(self);
|
||||
uint32_t strength = pin_get_strenght(self);
|
||||
uint32_t af = self->af;
|
||||
uint32_t type = self->type;
|
||||
uint32_t strength = self->strength;
|
||||
|
||||
// pin name
|
||||
print(env, "<Pin.cpu.%s, af=%u", qstr_str(self->name), af);
|
||||
mp_printf(print, "<Pin.cpu.%q, af=%u", self->name, af);
|
||||
|
||||
// pin mode
|
||||
if (af == PIN_MODE_0) {
|
||||
// IO mode
|
||||
qstr mode_qst;
|
||||
uint32_t mode = pin_get_mode(self);
|
||||
uint32_t mode = self->mode;
|
||||
if (mode == GPIO_DIR_MODE_IN) {
|
||||
mode_qst = MP_QSTR_IN;
|
||||
} else {
|
||||
mode_qst = MP_QSTR_OUT;
|
||||
}
|
||||
print(env, ", mode=Pin.%s", qstr_str(mode_qst)); // safe because mode_qst has no formatting chars
|
||||
mp_printf(print, ", mode=Pin.%q", mode_qst);
|
||||
}
|
||||
|
||||
// pin type
|
||||
@@ -465,9 +472,9 @@ STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env,
|
||||
} else {
|
||||
type_qst = MP_QSTR_OD_PD;
|
||||
}
|
||||
print(env, ", pull=Pin.%s", qstr_str(type_qst));
|
||||
mp_printf(print, ", type=Pin.%q", type_qst);
|
||||
|
||||
// Strength
|
||||
// pin strength
|
||||
qstr str_qst;
|
||||
if (strength == PIN_STRENGTH_2MA) {
|
||||
str_qst = MP_QSTR_S2MA;
|
||||
@@ -476,7 +483,7 @@ STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env,
|
||||
} else {
|
||||
str_qst = MP_QSTR_S6MA;
|
||||
}
|
||||
print(env, ", strength=Pin.%s>", qstr_str(str_qst));
|
||||
mp_printf(print, ", strength=Pin.%q>", str_qst);
|
||||
}
|
||||
|
||||
/// \classmethod \constructor(id, ...)
|
||||
@@ -555,68 +562,36 @@ STATIC mp_obj_t pin_toggle(mp_obj_t self_in) {
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_toggle_obj, pin_toggle);
|
||||
|
||||
/// \method name()
|
||||
/// Get the pin name.
|
||||
/// Returns the qstr name of the pin
|
||||
STATIC mp_obj_t pin_name(mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
return MP_OBJ_NEW_QSTR(self->name);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_name_obj, pin_name);
|
||||
|
||||
/// \method port()
|
||||
/// Get the pin port.
|
||||
STATIC mp_obj_t pin_port(mp_obj_t self_in) {
|
||||
/// \method info()
|
||||
/// Returns a named tupple with the current configuration of the gpio pin
|
||||
STATIC mp_obj_t pin_info(mp_obj_t self_in) {
|
||||
STATIC const qstr pin_info_fields[] = {
|
||||
MP_QSTR_name, MP_QSTR_af, MP_QSTR_mode,
|
||||
MP_QSTR_type, MP_QSTR_strength
|
||||
};
|
||||
|
||||
pin_obj_t *self = self_in;
|
||||
return mp_obj_new_int(self->port);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_port_obj, pin_port);
|
||||
mp_obj_t pin_config[5];
|
||||
pin_config[0] = MP_OBJ_NEW_QSTR(self->name);
|
||||
pin_config[1] = mp_obj_new_int(self->af);
|
||||
pin_config[2] = mp_obj_new_int(self->mode);
|
||||
pin_config[3] = mp_obj_new_int(self->type);
|
||||
pin_config[4] = mp_obj_new_int(self->strength);
|
||||
|
||||
/// \method pin()
|
||||
/// Get the pin number.
|
||||
STATIC mp_obj_t pin_pin(mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
return MP_OBJ_NEW_SMALL_INT(self->pin_num);
|
||||
return mp_obj_new_attrtuple(pin_info_fields, 5, pin_config);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_pin_obj, pin_pin);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_info_obj, pin_info);
|
||||
|
||||
/// \method mode()
|
||||
/// Returns the currently configured mode of the gpio pin. The integer returned
|
||||
/// will match one of the allowed constants for the mode argument to the init
|
||||
/// function.
|
||||
STATIC mp_obj_t pin_mode(mp_obj_t self_in) {
|
||||
return MP_OBJ_NEW_SMALL_INT(pin_get_mode(self_in));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_mode_obj, pin_mode);
|
||||
|
||||
/// \method type()
|
||||
/// Returns the currently configured type of the pin. The integer returned
|
||||
/// will match one of the allowed constants for the type argument to the init
|
||||
/// function.
|
||||
STATIC mp_obj_t pin_type_get(mp_obj_t self_in) {
|
||||
return MP_OBJ_NEW_SMALL_INT(pin_get_type(self_in));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_type_obj, pin_type_get);
|
||||
|
||||
/// \method strength()
|
||||
/// Returns the currently configured drive strength of the pin. The integer returned
|
||||
/// will match one of the allowed constants for the strength argument to the init
|
||||
/// function.
|
||||
STATIC mp_obj_t pin_strength(mp_obj_t self_in) {
|
||||
return MP_OBJ_NEW_SMALL_INT(pin_get_strenght(self_in));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_strenght_obj, pin_strength);
|
||||
|
||||
/// \method af()
|
||||
/// Returns the currently configured alternate function of the gpio pin. The integer returned
|
||||
/// will match one of the allowed constants for the af argument to the init function.
|
||||
STATIC mp_obj_t pin_af(mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
return MP_OBJ_NEW_SMALL_INT(MAP_PinModeGet(self->pin_num));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_af_obj, pin_af);
|
||||
|
||||
/// \method callback(method, intmode, priority, pwrmode)
|
||||
/// \method callback(method, mode, priority, pwrmode)
|
||||
/// Creates a callback object associated to a pin
|
||||
/// min num of arguments is 1 (intmode)
|
||||
/// min num of arguments is 1 (mode)
|
||||
STATIC mp_obj_t pin_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
mp_arg_val_t args[mpcallback_INIT_NUM_ARGS];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mpcallback_INIT_NUM_ARGS, mpcallback_init_args, args);
|
||||
@@ -631,7 +606,7 @@ STATIC mp_obj_t pin_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map
|
||||
uint intmode = args[0].u_int;
|
||||
if (intmode != GPIO_FALLING_EDGE && intmode != GPIO_RISING_EDGE && intmode != GPIO_BOTH_EDGES &&
|
||||
intmode != GPIO_LOW_LEVEL && intmode != GPIO_HIGH_LEVEL) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
uint pwrmode = args[4].u_int;
|
||||
@@ -751,12 +726,7 @@ STATIC const mp_map_elem_t pin_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_high), (mp_obj_t)&pin_high_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_toggle), (mp_obj_t)&pin_toggle_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_name), (mp_obj_t)&pin_name_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_port), (mp_obj_t)&pin_port_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_pin), (mp_obj_t)&pin_pin_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mode), (mp_obj_t)&pin_mode_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_type), (mp_obj_t)&pin_type_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_strength), (mp_obj_t)&pin_strenght_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_af), (mp_obj_t)&pin_af_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&pin_info_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&pin_callback_obj },
|
||||
|
||||
// class attributes
|
||||
@@ -792,7 +762,6 @@ STATIC const mp_map_elem_t pin_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_INT_RISING_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_BOTH_EDGES) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_INT_LOW_LEVEL), MP_OBJ_NEW_SMALL_INT(GPIO_LOW_LEVEL) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_INT_HIGH_LEVEL), MP_OBJ_NEW_SMALL_INT(GPIO_HIGH_LEVEL) },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_S2MA), MP_OBJ_NEW_SMALL_INT(PIN_STRENGTH_2MA) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_S4MA), MP_OBJ_NEW_SMALL_INT(PIN_STRENGTH_4MA) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_S6MA), MP_OBJ_NEW_SMALL_INT(PIN_STRENGTH_6MA) },
|
||||
@@ -814,29 +783,3 @@ STATIC const mp_cb_methods_t pin_cb_methods = {
|
||||
.disable = pin_extint_disable,
|
||||
};
|
||||
|
||||
STATIC void GPIOA0IntHandler (void) {
|
||||
EXTI_Handler(GPIOA0_BASE);
|
||||
}
|
||||
|
||||
STATIC void GPIOA1IntHandler (void) {
|
||||
EXTI_Handler(GPIOA1_BASE);
|
||||
}
|
||||
|
||||
STATIC void GPIOA2IntHandler (void) {
|
||||
EXTI_Handler(GPIOA2_BASE);
|
||||
}
|
||||
|
||||
STATIC void GPIOA3IntHandler (void) {
|
||||
EXTI_Handler(GPIOA3_BASE);
|
||||
}
|
||||
|
||||
// common interrupt handler
|
||||
STATIC void EXTI_Handler(uint port) {
|
||||
uint32_t bit = MAP_GPIOIntStatus(port, true);
|
||||
MAP_GPIOIntClear(port, bit);
|
||||
|
||||
pin_obj_t *self = (pin_obj_t *)pin_find_pin_by_port_bit(&pin_cpu_pins_locals_dict, port, bit);
|
||||
mp_obj_t _callback = mpcallback_find(self);
|
||||
mpcallback_handler(_callback);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,13 +25,18 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// This file requires pin_defs_xxx.h (which has port specific enums and
|
||||
// defines, so we include it here. It should never be included directly
|
||||
|
||||
#include MICROPY_PIN_DEFS_PORT_H
|
||||
#ifndef PYBPIN_H_
|
||||
#define PYBPIN_H_
|
||||
|
||||
#define PYBPIN_ANALOG_TYPE 0xFF
|
||||
|
||||
enum {
|
||||
PORT_A0 = GPIOA0_BASE,
|
||||
PORT_A1 = GPIOA1_BASE,
|
||||
PORT_A2 = GPIOA2_BASE,
|
||||
PORT_A3 = GPIOA3_BASE
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const mp_obj_base_t base;
|
||||
const qstr name;
|
||||
@@ -62,14 +67,9 @@ extern const mp_obj_type_t pin_cpu_pins_obj_type;
|
||||
extern const mp_obj_dict_t pin_cpu_pins_locals_dict;
|
||||
|
||||
void pin_init0(void);
|
||||
void pin_verify_af (uint af);
|
||||
void pin_config(pin_obj_t *self, uint af, uint mode, uint type, uint strength);
|
||||
void pin_extint_register(pin_obj_t *self, uint32_t intmode, uint32_t priority);
|
||||
pin_obj_t *pin_find(mp_obj_t user_obj);
|
||||
pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name);
|
||||
pin_obj_t *pin_find_pin(const mp_obj_dict_t *named_pins, uint pin_num);
|
||||
pin_obj_t *pin_find_pin_by_port_bit (const mp_obj_dict_t *named_pins, uint port, uint bit);
|
||||
uint32_t pin_get_mode(const pin_obj_t *self);
|
||||
uint32_t pin_get_type(const pin_obj_t *self);
|
||||
uint32_t pin_get_strenght(const pin_obj_t *self);
|
||||
|
||||
#endif // PYBPIN_H_
|
||||
|
||||
@@ -25,13 +25,12 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <std.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "modutime.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
@@ -40,6 +39,10 @@
|
||||
#include "pybrtc.h"
|
||||
#include "pybsleep.h"
|
||||
#include "mpcallback.h"
|
||||
#include "timeutils.h"
|
||||
#include "simplelink.h"
|
||||
#include "modnetwork.h"
|
||||
#include "modwlan.h"
|
||||
|
||||
/// \moduleref pyb
|
||||
/// \class RTC - real time clock
|
||||
@@ -71,6 +74,7 @@ typedef struct {
|
||||
******************************************************************************/
|
||||
STATIC pybrtc_data_t pybrtc_data;
|
||||
STATIC const mp_cb_methods_t pybrtc_cb_methods;
|
||||
STATIC const mp_obj_base_t pyb_rtc_obj = {&pyb_rtc_type};
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
@@ -82,7 +86,7 @@ void pybrtc_init(void) {
|
||||
// fresh reset; configure the RTC Calendar
|
||||
// set the date to 1st Jan 2015
|
||||
// set the time to 00:00:00
|
||||
uint32_t seconds = mod_time_seconds_since_2000(2015, 1, 1, 0, 0, 0);
|
||||
uint32_t seconds = timeutils_seconds_since_2000(2015, 1, 1, 0, 0, 0);
|
||||
|
||||
// Mark the RTC in use first
|
||||
MAP_PRCMRTCInUseSet();
|
||||
@@ -92,6 +96,26 @@ void pybrtc_init(void) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t pybrtc_get_seconds (void) {
|
||||
uint32_t seconds;
|
||||
uint16_t mseconds;
|
||||
|
||||
MAP_PRCMRTCGet(&seconds, &mseconds);
|
||||
return seconds;
|
||||
}
|
||||
|
||||
void pyb_rtc_callback_disable (mp_obj_t self_in) {
|
||||
// check the wake from param
|
||||
if (pybrtc_data.prwmode & PYB_PWR_MODE_ACTIVE) {
|
||||
// disable the slow clock interrupt
|
||||
MAP_PRCMIntDisable(PRCM_INT_SLOW_CLK_CTR);
|
||||
}
|
||||
// disable wake from ldps and hibernate
|
||||
pybsleep_configure_timer_wakeup (PYB_PWR_MODE_ACTIVE);
|
||||
// read the interrupt status to clear any pending interrupt
|
||||
(void)MAP_PRCMIntStatus();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
@@ -108,19 +132,19 @@ STATIC void pyb_rtc_callback_enable (mp_obj_t self_in) {
|
||||
pybsleep_configure_timer_wakeup (pybrtc_data.prwmode);
|
||||
}
|
||||
|
||||
STATIC void pyb_rtc_callback_disable (mp_obj_t self_in) {
|
||||
// check the wake from param
|
||||
if (pybrtc_data.prwmode & PYB_PWR_MODE_ACTIVE) {
|
||||
// enable the slow clock interrupt
|
||||
MAP_PRCMIntDisable(PRCM_INT_SLOW_CLK_CTR);
|
||||
}
|
||||
// disable wake from ldps and hibernate
|
||||
pybsleep_configure_timer_wakeup (PYB_PWR_MODE_ACTIVE);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
/// \classmethod \constructor()
|
||||
/// Create an RTC object.
|
||||
STATIC mp_obj_t pyb_rtc_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
// check arguments
|
||||
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
||||
|
||||
// return constant object
|
||||
return (mp_obj_t)&pyb_rtc_obj;
|
||||
}
|
||||
|
||||
/// \method datetime([datetimetuple])
|
||||
/// Get or set the date and time of the RTC.
|
||||
///
|
||||
@@ -135,7 +159,7 @@ STATIC void pyb_rtc_callback_disable (mp_obj_t self_in) {
|
||||
/// `weekday` is 0-6 for Monday through Sunday.
|
||||
///
|
||||
mp_obj_t pyb_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
mod_struct_time tm;
|
||||
timeutils_struct_time_t tm;
|
||||
uint32_t seconds;
|
||||
uint16_t mseconds;
|
||||
|
||||
@@ -143,7 +167,7 @@ mp_obj_t pyb_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
// 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_seconds_since_2000_to_struct_time(seconds, &tm);
|
||||
|
||||
mp_obj_t tuple[8] = {
|
||||
mp_obj_new_int(tm.tm_year),
|
||||
@@ -164,16 +188,18 @@ mp_obj_t pyb_rtc_datetime(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
tm.tm_year = mp_obj_get_int(items[0]);
|
||||
tm.tm_mon = mp_obj_get_int(items[1]);
|
||||
tm.tm_mday = mp_obj_get_int(items[2]);
|
||||
// Skip the weekday
|
||||
// skip the weekday
|
||||
tm.tm_hour = mp_obj_get_int(items[4]);
|
||||
tm.tm_min = mp_obj_get_int(items[5]);
|
||||
tm.tm_sec = mp_obj_get_int(items[6]);
|
||||
mseconds = mp_obj_get_int(items[7]);
|
||||
|
||||
seconds = mod_time_seconds_since_2000(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||
seconds = timeutils_seconds_since_2000(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
|
||||
mseconds = RTC_U16MS_CYCLES(mseconds);
|
||||
MAP_PRCMRTCSet(seconds, mseconds);
|
||||
|
||||
// set WLAN time and date, this is needed to verify certificates
|
||||
wlan_set_current_time(seconds);
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
@@ -190,7 +216,7 @@ STATIC mp_obj_t pyb_rtc_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp
|
||||
// check if any parameters were passed
|
||||
mp_obj_t _callback = mpcallback_find((mp_obj_t)&pyb_rtc_obj);
|
||||
if (kw_args->used > 0 || !_callback) {
|
||||
uint32_t f_mseconds = args[3].u_int;
|
||||
uint32_t f_mseconds = MAX(1, args[3].u_int);
|
||||
uint32_t seconds;
|
||||
uint16_t mseconds;
|
||||
// get the seconds and the milliseconds from the RTC
|
||||
@@ -208,7 +234,7 @@ STATIC mp_obj_t pyb_rtc_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp
|
||||
// set the match value
|
||||
MAP_PRCMRTCMatchSet(seconds, mseconds);
|
||||
|
||||
// save the match data for later
|
||||
// save the power mode data for later
|
||||
pybrtc_data.prwmode = args[4].u_int;
|
||||
|
||||
// create the callback
|
||||
@@ -217,7 +243,7 @@ STATIC mp_obj_t pyb_rtc_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp
|
||||
// set the lpds callback
|
||||
pybsleep_set_timer_lpds_callback(_callback);
|
||||
|
||||
// the interrupt priority is ignored since is already set to to highest level by the sleep module
|
||||
// the interrupt priority is ignored since it's already set to to highest level by the sleep module
|
||||
// to make sure that the wakeup callbacks are always called first when resuming from sleep
|
||||
|
||||
// enable the interrupt (the object is not relevant here, the function already knows it)
|
||||
@@ -233,9 +259,10 @@ STATIC const mp_map_elem_t pyb_rtc_locals_dict_table[] = {
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_rtc_locals_dict, pyb_rtc_locals_dict_table);
|
||||
|
||||
STATIC const mp_obj_type_t pyb_rtc_type = {
|
||||
const mp_obj_type_t pyb_rtc_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_RTC,
|
||||
.make_new = pyb_rtc_make_new,
|
||||
.locals_dict = (mp_obj_t)&pyb_rtc_locals_dict,
|
||||
};
|
||||
|
||||
@@ -244,5 +271,3 @@ STATIC const mp_cb_methods_t pybrtc_cb_methods = {
|
||||
.enable = pyb_rtc_callback_enable,
|
||||
.disable = pyb_rtc_callback_disable,
|
||||
};
|
||||
|
||||
const mp_obj_base_t pyb_rtc_obj = {&pyb_rtc_type};
|
||||
|
||||
@@ -31,8 +31,10 @@
|
||||
#define RTC_U16MS_CYCLES(msec) ((msec * 1024) / 1000)
|
||||
#define RTC_CYCLES_U16MS(cycles) ((cycles * 1000) / 1024)
|
||||
|
||||
extern const mp_obj_base_t pyb_rtc_obj;
|
||||
extern const mp_obj_type_t pyb_rtc_type;
|
||||
|
||||
void pybrtc_init(void);
|
||||
extern void pybrtc_init(void);
|
||||
extern void pyb_rtc_callback_disable (mp_obj_t self_in);
|
||||
extern uint32_t pybrtc_get_seconds (void);
|
||||
|
||||
#endif // PYBRTC_H_
|
||||
|
||||
@@ -73,7 +73,7 @@ STATIC mp_obj_t pybsd_disable (mp_obj_t self_in);
|
||||
STATIC mp_obj_t pybsd_enable (mp_obj_t self_in);
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
__attribute__ ((section (".boot")))
|
||||
void pybsd_init0 (void) {
|
||||
@@ -86,7 +86,7 @@ void pybsd_deinit (void) {
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
/// Initalizes the sd card driver
|
||||
STATIC void pybsd_init (pybsd_obj_t *self) {
|
||||
@@ -148,13 +148,13 @@ STATIC mp_obj_t pybsd_enable (mp_obj_t self_in) {
|
||||
// do the init first
|
||||
pybsd_init (self);
|
||||
|
||||
// try to mount the sd card on /SD
|
||||
if (FR_OK != f_mount(self->fatfs, "/SD", 1)) {
|
||||
// try to mount the sd card on /sd
|
||||
if (FR_OK != f_mount(self->fatfs, "/sd", 1)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SD));
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SD_slash_LIB));
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd));
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib));
|
||||
|
||||
// register it with the sleep module
|
||||
pybsleep_add ((const mp_obj_t)&pybsd_obj, (WakeUpCB_t)pybsd_init);
|
||||
@@ -172,10 +172,10 @@ STATIC mp_obj_t pybsd_disable (mp_obj_t self_in) {
|
||||
if (self->enabled) {
|
||||
self->enabled = false;
|
||||
// unmount the sd card
|
||||
f_mount (NULL, "/SD", 1);
|
||||
f_mount (NULL, "/sd", 1);
|
||||
// remove sd paths from mp_sys_path
|
||||
mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SD));
|
||||
mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SD_slash_LIB));
|
||||
mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd));
|
||||
mp_obj_list_remove(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_sd_slash_lib));
|
||||
|
||||
// disable the peripheral
|
||||
MAP_PRCMPeripheralClkDisable(PRCM_SDHOST, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
@@ -186,8 +186,8 @@ STATIC mp_obj_t pybsd_disable (mp_obj_t self_in) {
|
||||
// unregister it with the sleep module
|
||||
pybsleep_remove (self);
|
||||
|
||||
// change the drive in case it was /SD
|
||||
f_chdrive("/SFLASH");
|
||||
// change the drive in case it was /sd
|
||||
f_chdrive("/flash");
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <std.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -46,6 +45,7 @@
|
||||
#include "pybsleep.h"
|
||||
#include "pybpin.h"
|
||||
#include "simplelink.h"
|
||||
#include "modnetwork.h"
|
||||
#include "modwlan.h"
|
||||
#include "osi.h"
|
||||
#include "debug.h"
|
||||
@@ -53,6 +53,8 @@
|
||||
#include "mpcallback.h"
|
||||
#include "mperror.h"
|
||||
#include "sleeprestore.h"
|
||||
#include "serverstask.h"
|
||||
#include "antenna.h"
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE CONSTANTS
|
||||
@@ -124,6 +126,7 @@ STATIC nvic_reg_store_t *nvic_reg_store;
|
||||
STATIC pybsleep_data_t pybsleep_data = {NULL, NULL, NULL, 0};
|
||||
volatile arm_cm4_core_regs_t vault_arm_registers;
|
||||
STATIC pybsleep_reset_cause_t pybsleep_reset_cause = PYB_SLP_PWRON_RESET;
|
||||
STATIC pybsleep_wake_reason_t pybsleep_wake_reason = PYB_SLP_WAKED_PWRON;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
@@ -134,7 +137,7 @@ STATIC NORETURN void pybsleep_suspend_enter (void);
|
||||
void pybsleep_suspend_exit (void);
|
||||
STATIC void pybsleep_obj_wakeup (void);
|
||||
STATIC void PRCMInterruptHandler (void);
|
||||
STATIC void pybsleep_iopark (void);
|
||||
STATIC void pybsleep_iopark (bool hibernate);
|
||||
STATIC bool setup_timer_lpds_wake (void);
|
||||
STATIC bool setup_timer_hibernate_wake (void);
|
||||
|
||||
@@ -175,11 +178,22 @@ void pybsleep_init0 (void) {
|
||||
pybsleep_reset_cause = PYB_SLP_WDT_RESET;
|
||||
break;
|
||||
case PRCM_HIB_EXIT:
|
||||
if (PRCMWasResetBecauseOfWDT()) {
|
||||
if (PRCMGetSpecialBit(PRCM_WDT_RESET_BIT)) {
|
||||
pybsleep_reset_cause = PYB_SLP_WDT_RESET;
|
||||
}
|
||||
else {
|
||||
pybsleep_reset_cause = PYB_SLP_HIB_RESET;
|
||||
// set the correct wake reason
|
||||
switch (MAP_PRCMHibernateWakeupCauseGet()) {
|
||||
case PRCM_HIB_WAKEUP_CAUSE_SLOW_CLOCK:
|
||||
pybsleep_wake_reason = PYB_SLP_WAKED_BY_RTC;
|
||||
break;
|
||||
case PRCM_HIB_WAKEUP_CAUSE_GPIO:
|
||||
pybsleep_wake_reason = PYB_SLP_WAKED_BY_GPIO;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -326,7 +340,7 @@ STATIC NORETURN void pybsleep_suspend_enter (void) {
|
||||
mperror_heartbeat_switch_off();
|
||||
|
||||
// park the gpio pins
|
||||
pybsleep_iopark();
|
||||
pybsleep_iopark(false);
|
||||
|
||||
// store the cpu registers
|
||||
sleep_store();
|
||||
@@ -384,6 +398,11 @@ void pybsleep_suspend_exit (void) {
|
||||
// ungate the clock to the shared spi bus
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_SSPI, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
|
||||
#if MICROPY_HW_ANTENNA_DIVERSITY
|
||||
// re-configure the antenna selection pins
|
||||
antenna_init0();
|
||||
#endif
|
||||
|
||||
// reinitialize simplelink's interface
|
||||
sl_IfOpen (NULL, 0);
|
||||
|
||||
@@ -411,15 +430,18 @@ STATIC void PRCMInterruptHandler (void) {
|
||||
switch (MAP_PRCMLPDSWakeupCauseGet()) {
|
||||
case PRCM_LPDS_HOST_IRQ:
|
||||
mpcallback_handler(pybsleep_data.wlan_lpds_wake_cb);
|
||||
pybsleep_wake_reason = PYB_SLP_WAKED_BY_WLAN;
|
||||
break;
|
||||
case PRCM_LPDS_GPIO:
|
||||
mpcallback_handler(pybsleep_data.gpio_lpds_wake_cb);
|
||||
pybsleep_wake_reason = PYB_SLP_WAKED_BY_GPIO;
|
||||
break;
|
||||
case PRCM_LPDS_TIMER:
|
||||
// disable the timer as a wake-up source
|
||||
// disable the timer as wake-up source
|
||||
pybsleep_data.timer_wake_pwrmode &= ~PYB_PWR_MODE_LPDS;
|
||||
MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_TIMER);
|
||||
mpcallback_handler(pybsleep_data.timer_lpds_wake_cb);
|
||||
pybsleep_wake_reason = PYB_SLP_WAKED_BY_RTC;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -434,31 +456,29 @@ STATIC void pybsleep_obj_wakeup (void) {
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void pybsleep_iopark (void) {
|
||||
STATIC void pybsleep_iopark (bool hibernate) {
|
||||
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)&pin_cpu_pins_locals_dict);
|
||||
for (uint i = 0; i < named_map->used; i++) {
|
||||
pin_obj_t * pin = (pin_obj_t *)named_map->table[i].value;
|
||||
// skip the sflash pins since these are shared with the network processor
|
||||
switch (pin->pin_num) {
|
||||
case PIN_11:
|
||||
case PIN_12:
|
||||
case PIN_13:
|
||||
case PIN_14:
|
||||
#ifdef DEBUG
|
||||
// also skip the JTAG pins
|
||||
// skip the JTAG pins
|
||||
case PIN_16:
|
||||
case PIN_17:
|
||||
case PIN_19:
|
||||
case PIN_20:
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
// enable a weak pull-down if the pin is unused
|
||||
if (!pin->isused) {
|
||||
MAP_PinConfigSet(pin->pin_num, pin->strength, PIN_TYPE_STD_PD);
|
||||
}
|
||||
// make it an input
|
||||
MAP_PinDirModeSet(pin->pin_num, PIN_DIR_MODE_IN);
|
||||
if (hibernate) {
|
||||
// make it an input
|
||||
MAP_PinDirModeSet(pin->pin_num, PIN_DIR_MODE_IN);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -473,9 +493,25 @@ STATIC void pybsleep_iopark (void) {
|
||||
HWREG(0x4402E0F4) &= ~(0x3 << 8);
|
||||
HWREG(0x4402E0F4) |= (0x1 << 8);
|
||||
|
||||
// park the antenna selection pins
|
||||
HWREG(0x4402E108) = 0x00000E61;
|
||||
HWREG(0x4402E10C) = 0x00000E61;
|
||||
// if the board has antenna diversity, only park the antenna
|
||||
// selection pins when going into hibernation
|
||||
#if MICROPY_HW_ANTENNA_DIVERSITY
|
||||
if (hibernate) {
|
||||
#endif
|
||||
// park the antenna selection pins
|
||||
// (tri-stated with pull down enabled)
|
||||
HWREG(0x4402E108) = 0x00000E61;
|
||||
HWREG(0x4402E10C) = 0x00000E61;
|
||||
#if MICROPY_HW_ANTENNA_DIVERSITY
|
||||
} else {
|
||||
// park the antenna selection pins
|
||||
// (tri-stated without changing the pull up/down resistors)
|
||||
HWREG(0x4402E108) &= ~0x000000FF;
|
||||
HWREG(0x4402E108) |= 0x00000C61;
|
||||
HWREG(0x4402E10C) &= ~0x000000FF;
|
||||
HWREG(0x4402E10C) |= 0x00000C61;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC bool setup_timer_lpds_wake (void) {
|
||||
@@ -579,6 +615,7 @@ STATIC mp_obj_t pyb_sleep_suspend (mp_obj_t self_in) {
|
||||
// do we need network wake-up?
|
||||
if (pybsleep_data.wlan_lpds_wake_cb) {
|
||||
MAP_PRCMLPDSWakeupSourceEnable (PRCM_LPDS_HOST_IRQ);
|
||||
server_sleep_sockets();
|
||||
}
|
||||
else {
|
||||
MAP_PRCMLPDSWakeupSourceDisable (PRCM_LPDS_HOST_IRQ);
|
||||
@@ -615,7 +652,7 @@ STATIC mp_obj_t pyb_sleep_hibernate (mp_obj_t self_in) {
|
||||
wlan_stop(SL_STOP_TIMEOUT);
|
||||
pybsleep_flash_powerdown();
|
||||
// must be done just before entering hibernate mode
|
||||
pybsleep_iopark();
|
||||
pybsleep_iopark(true);
|
||||
MAP_PRCMHibernateEnter();
|
||||
return mp_const_none;
|
||||
}
|
||||
@@ -631,7 +668,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_reset_cause_obj, pyb_sleep_reset_caus
|
||||
/// \function wake_reason()
|
||||
/// Returns the wake up reson from ldps or hibernate
|
||||
STATIC mp_obj_t pyb_sleep_wake_reason (mp_obj_t self_in) {
|
||||
return mp_const_none;
|
||||
return MP_OBJ_NEW_SMALL_INT(pybsleep_wake_reason);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_wake_reason_obj, pyb_sleep_wake_reason);
|
||||
|
||||
@@ -647,13 +684,13 @@ STATIC const mp_map_elem_t pybsleep_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ACTIVE), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_ACTIVE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SUSPENDED), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_LPDS) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_HIBERNATING), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_HIBERNATE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PWR_ON_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_PWRON_RESET) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_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_HIB_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_HIB_RESET) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SOFT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_SOFT_RESET) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_WLAN_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_WLAN) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PIN_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_PIN) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_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) },
|
||||
};
|
||||
|
||||
@@ -661,7 +698,7 @@ STATIC MP_DEFINE_CONST_DICT(pybsleep_locals_dict, pybsleep_locals_dict_table);
|
||||
|
||||
STATIC const mp_obj_type_t pybsleep_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_sleep,
|
||||
.name = MP_QSTR_Sleep,
|
||||
.locals_dict = (mp_obj_t)&pybsleep_locals_dict,
|
||||
};
|
||||
|
||||
|
||||
@@ -42,19 +42,17 @@ typedef enum {
|
||||
PYB_SLP_HARD_RESET,
|
||||
PYB_SLP_WDT_RESET,
|
||||
PYB_SLP_HIB_RESET,
|
||||
PYB_SLP_SOFT_RESET,
|
||||
|
||||
PYB_SLP_SOFT_RESET
|
||||
} pybsleep_reset_cause_t;
|
||||
|
||||
typedef enum {
|
||||
PYB_SLP_WAKED_PWRON = 0,
|
||||
PYB_SLP_WAKED_BY_WLAN,
|
||||
PYB_SLP_WAKED_BY_PIN,
|
||||
PYB_SLP_WAKED_BY_GPIO,
|
||||
PYB_SLP_WAKED_BY_RTC
|
||||
|
||||
} pybsleep_wake_reason_t;
|
||||
|
||||
typedef void (*WakeUpCB_t)(const mp_obj_t self);
|
||||
typedef void (*DeinitCB_t)(const mp_obj_t self);
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE EXPORTED VARIABLES
|
||||
|
||||
@@ -54,9 +54,9 @@
|
||||
/// parameters to init the SPI bus:
|
||||
///
|
||||
/// from pyb import SPI
|
||||
/// spi = SPI(2000000, bits=8, submode=0, cs=SPI.ACTIVE_LOW)
|
||||
/// spi = SPI(1, SPI.MASTER, baudrate=2000000, bits=8, polarity=0, phase=0, nss=SPI.ACTIVE_LOW)
|
||||
///
|
||||
/// Only required parameter is the baudrate, in Hz. Submode may be 0-3.
|
||||
/// Only required parameter is the baudrate, in Hz. polarity and phase may be 0 or 1.
|
||||
/// Bit accepts 8, 16, 32. Chip select values are ACTIVE_LOW and ACTIVE_HIGH
|
||||
///
|
||||
/// Additional method for SPI:
|
||||
@@ -77,6 +77,8 @@ typedef struct _pyb_spi_obj_t {
|
||||
vstr_t rx_vstr;
|
||||
uint tx_index;
|
||||
uint rx_index;
|
||||
byte polarity;
|
||||
byte phase;
|
||||
byte submode;
|
||||
byte wlen;
|
||||
} pyb_spi_obj_t;
|
||||
@@ -85,7 +87,6 @@ typedef struct _pyb_spi_obj_t {
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYBSPI_DEF_BAUDRATE 1000000 // 1MHz
|
||||
#define PYBSPI_CS_NONE 0xFF // spi cs is controlled by the user
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
@@ -163,31 +164,35 @@ STATIC void pybspi_transfer (pyb_spi_obj_t *self, const char *txdata, char *rxda
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings */
|
||||
/******************************************************************************/
|
||||
STATIC void pyb_spi_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
STATIC void pyb_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_spi_obj_t *self = self_in;
|
||||
|
||||
if (self->baudrate > 0) {
|
||||
print(env, "<SPI0, SPI.MASTER, baudrate=%u, config=%u, submode=%u, bits=%u>",
|
||||
self->baudrate, self->config, self->submode, (self->wlen * 8));
|
||||
}
|
||||
else {
|
||||
print(env, "<SPI0>");
|
||||
mp_printf(print, "<SPI1, SPI.MASTER, baudrate=%u, bits=%u, polarity=%u, phase=%u, nss=%q>",
|
||||
self->baudrate, (self->wlen * 8), self->polarity, self->phase,
|
||||
(self->config & SPI_CS_ACTIVELOW) ? MP_QSTR_ACTIVE_LOW : MP_QSTR_ACTIVE_HIGH);
|
||||
} else {
|
||||
mp_print_str(print, "<SPI1>");
|
||||
}
|
||||
}
|
||||
|
||||
/// \method init(2000000, *, bits=8, submode=0, cs=SPI.ACTIVELOW)
|
||||
/// \method init(mode, *, baudrate=1000000, bits=8, polarity=0, phase=0, nss=SPI.ACTIVE_LOW)
|
||||
///
|
||||
/// Initialise the SPI bus with the given parameters:
|
||||
///
|
||||
/// - `mode` must be MASTER.
|
||||
/// - `baudrate` is the SCK clock rate.
|
||||
/// - `bits` is the transfer width size (8, 16, 32).
|
||||
/// - `submode` is the spi mode (0, 1, 2, 3).
|
||||
/// - `cs` can be ACTIVELOW, ACTIVEHIGH, or NONE
|
||||
/// - `polarity` (0, 1).
|
||||
/// - `phase` (0, 1).
|
||||
/// - `nss` can be ACTIVE_LOW or ACTIVE_HIGH.
|
||||
static const mp_arg_t pybspi_init_args[] = {
|
||||
{ MP_QSTR_baudrate, MP_ARG_REQUIRED | MP_ARG_INT, },
|
||||
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT, },
|
||||
{ MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PYBSPI_DEF_BAUDRATE} },
|
||||
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
|
||||
{ MP_QSTR_submode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_cs, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SPI_CS_ACTIVELOW} },
|
||||
{ MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_nss, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = SPI_CS_ACTIVELOW} },
|
||||
};
|
||||
|
||||
STATIC mp_obj_t pyb_spi_init_helper(pyb_spi_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
@@ -195,13 +200,13 @@ STATIC mp_obj_t pyb_spi_init_helper(pyb_spi_obj_t *self, mp_uint_t n_args, const
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(pybspi_init_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(pybspi_init_args), pybspi_init_args, args);
|
||||
|
||||
uint submode = args[2].u_int;
|
||||
uint cs = args[3].u_int;
|
||||
uint bits;
|
||||
// verify that mode is master
|
||||
if (args[0].u_int != SPI_MODE_MASTER) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
// save the word length for later use
|
||||
self->wlen = args[1].u_int / 8;
|
||||
switch (args[1].u_int) {
|
||||
uint bits;
|
||||
switch (args[2].u_int) {
|
||||
case 8:
|
||||
bits = SPI_WL_8;
|
||||
break;
|
||||
@@ -212,22 +217,28 @@ STATIC mp_obj_t pyb_spi_init_helper(pyb_spi_obj_t *self, mp_uint_t n_args, const
|
||||
bits = SPI_WL_32;
|
||||
break;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
goto invalid_args;
|
||||
break;
|
||||
}
|
||||
|
||||
if (submode < SPI_SUB_MODE_0 || submode > SPI_SUB_MODE_3) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
uint polarity = args[3].u_int;
|
||||
uint phase = args[4].u_int;
|
||||
if (polarity > 1 || phase > 1) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
if (cs != SPI_CS_ACTIVELOW && cs != SPI_CS_ACTIVEHIGH) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
uint nss = args[5].u_int;
|
||||
if (nss != SPI_CS_ACTIVELOW && nss != SPI_CS_ACTIVEHIGH) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
// build the configuration
|
||||
self->baudrate = args[0].u_int;
|
||||
self->config = bits | cs | SPI_SW_CTRL_CS | SPI_4PIN_MODE | SPI_TURBO_OFF;
|
||||
self->submode = submode;
|
||||
self->baudrate = args[1].u_int;
|
||||
self->wlen = args[2].u_int >> 3;
|
||||
self->config = bits | nss | SPI_SW_CTRL_CS | SPI_4PIN_MODE | SPI_TURBO_OFF;
|
||||
self->polarity = polarity;
|
||||
self->phase = phase;
|
||||
self->submode = (polarity << 1) | phase;
|
||||
|
||||
// init the bus
|
||||
pybspi_init((const pyb_spi_obj_t *)self);
|
||||
@@ -236,16 +247,18 @@ STATIC mp_obj_t pyb_spi_init_helper(pyb_spi_obj_t *self, mp_uint_t n_args, const
|
||||
pybsleep_add((const mp_obj_t)self, (WakeUpCB_t)pybspi_init);
|
||||
|
||||
return mp_const_none;
|
||||
|
||||
invalid_args:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
/// \classmethod \constructor(bus, ...)
|
||||
///
|
||||
/// Construct an SPI object with the given baudrate.
|
||||
/// With no parameters, the SPI object is created but not
|
||||
/// Construct an SPI object with the given baudrate. Bus can only be 1.
|
||||
/// With no extra parameters, the SPI object is created but not
|
||||
/// initialised (it has the settings from the last initialisation of
|
||||
/// the bus, if any). If extra arguments are given, the bus is initialised.
|
||||
/// See `init` for parameters of initialisation.
|
||||
///
|
||||
STATIC mp_obj_t pyb_spi_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
// check arguments
|
||||
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
|
||||
@@ -253,11 +266,11 @@ STATIC mp_obj_t pyb_spi_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n
|
||||
pyb_spi_obj_t *self = &pyb_spi_obj;
|
||||
self->base.type = &pyb_spi_type;
|
||||
|
||||
if (n_args > 0 || n_kw > 0) {
|
||||
if (n_args > 1 || n_kw > 0) {
|
||||
// start the peripheral
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
|
||||
pyb_spi_init_helper(self, n_args, args, &kw_args);
|
||||
pyb_spi_init_helper(self, n_args - 1, args + 1, &kw_args);
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -282,39 +295,59 @@ STATIC mp_obj_t pyb_spi_deinit(mp_obj_t self_in) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_spi_deinit_obj, pyb_spi_deinit);
|
||||
|
||||
/// \method send(send)
|
||||
/// \method send(send, *, timeout=5000)
|
||||
/// Send data on the bus:
|
||||
///
|
||||
/// - `send` is the data to send (a byte to send, or a buffer object).
|
||||
/// - `timeout` is the timeout in milliseconds to wait for the send.
|
||||
///
|
||||
STATIC mp_obj_t pyb_spi_send (mp_obj_t self_in, mp_obj_t send_o) {
|
||||
pyb_spi_obj_t *self = self_in;
|
||||
STATIC mp_obj_t pyb_spi_send (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_send, MP_ARG_REQUIRED | MP_ARG_OBJ, },
|
||||
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
|
||||
};
|
||||
|
||||
// parse args
|
||||
pyb_spi_obj_t *self = pos_args[0];
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
// get the buffer to send from
|
||||
mp_buffer_info_t bufinfo;
|
||||
uint8_t data[1];
|
||||
pyb_buf_get_for_send(send_o, &bufinfo, data);
|
||||
pyb_buf_get_for_send(args[0].u_obj, &bufinfo, data);
|
||||
|
||||
// just send
|
||||
pybspi_transfer(self, (const char *)bufinfo.buf, NULL, bufinfo.len);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_spi_send_obj, pyb_spi_send);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_send_obj, 1, pyb_spi_send);
|
||||
|
||||
/// \method recv(recv)
|
||||
/// \method recv(recv, *, timeout=5000)
|
||||
///
|
||||
/// Receive data on the bus:
|
||||
///
|
||||
/// - `recv` can be an integer, which is the number of bytes to receive,
|
||||
/// or a mutable buffer, which will be filled with received bytes.
|
||||
/// - `timeout` is the timeout in milliseconds to wait for the receive.
|
||||
///
|
||||
/// Return: if `recv` is an integer then a new buffer of the bytes received,
|
||||
/// otherwise the same buffer that was passed in to `recv`.
|
||||
STATIC mp_obj_t pyb_spi_recv(mp_obj_t self_in, mp_obj_t recv_o) {
|
||||
pyb_spi_obj_t *self = self_in;
|
||||
STATIC mp_obj_t pyb_spi_recv(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_recv, MP_ARG_REQUIRED | MP_ARG_OBJ, },
|
||||
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
|
||||
};
|
||||
|
||||
// parse args
|
||||
pyb_spi_obj_t *self = pos_args[0];
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
// get the buffer to receive into
|
||||
vstr_t vstr;
|
||||
mp_obj_t o_ret = pyb_buf_get_for_recv(recv_o, &vstr);
|
||||
mp_obj_t o_ret = pyb_buf_get_for_recv(args[0].u_obj, &vstr);
|
||||
|
||||
// just receive
|
||||
pybspi_transfer(self, NULL, vstr.buf, vstr.len);
|
||||
@@ -326,9 +359,9 @@ STATIC mp_obj_t pyb_spi_recv(mp_obj_t self_in, mp_obj_t recv_o) {
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_spi_recv_obj, pyb_spi_recv);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_recv_obj, 1, pyb_spi_recv);
|
||||
|
||||
/// \method send_recv(send, recv)
|
||||
/// \method send_recv(send, recv=None, *, timeout=5000)
|
||||
///
|
||||
/// Send and receive data on the bus at the same time:
|
||||
///
|
||||
@@ -336,10 +369,20 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_spi_recv_obj, pyb_spi_recv);
|
||||
/// - `recv` is a mutable buffer which will be filled with received bytes.
|
||||
/// It can be the same as `send`, or omitted. If omitted, a new buffer will
|
||||
/// be created.
|
||||
/// - `timeout` is the timeout in milliseconds to wait for the transaction to complete.
|
||||
///
|
||||
/// Return: the buffer with the received bytes.
|
||||
STATIC mp_obj_t pyb_spi_send_recv (mp_uint_t n_args, const mp_obj_t *args) {
|
||||
pyb_spi_obj_t *self = args[0];
|
||||
STATIC mp_obj_t pyb_spi_send_recv (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_send, MP_ARG_REQUIRED | MP_ARG_OBJ, },
|
||||
{ MP_QSTR_recv, MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
|
||||
};
|
||||
|
||||
// parse args
|
||||
pyb_spi_obj_t *self = pos_args[0];
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
// get buffers to send from/receive to
|
||||
mp_buffer_info_t bufinfo_send;
|
||||
@@ -348,35 +391,34 @@ STATIC mp_obj_t pyb_spi_send_recv (mp_uint_t n_args, const mp_obj_t *args) {
|
||||
vstr_t vstr_recv;
|
||||
mp_obj_t o_ret;
|
||||
|
||||
if (args[1] == args[2]) {
|
||||
if (args[0].u_obj == args[1].u_obj) {
|
||||
// same object for sending and receiving, it must be a r/w buffer
|
||||
mp_get_buffer_raise(args[1], &bufinfo_send, MP_BUFFER_RW);
|
||||
mp_get_buffer_raise(args[0].u_obj, &bufinfo_send, MP_BUFFER_RW);
|
||||
bufinfo_recv = bufinfo_send;
|
||||
o_ret = args[1];
|
||||
o_ret = args[0].u_obj;
|
||||
} else {
|
||||
// get the buffer to send from
|
||||
pyb_buf_get_for_send(args[1], &bufinfo_send, data_send);
|
||||
pyb_buf_get_for_send(args[0].u_obj, &bufinfo_send, data_send);
|
||||
|
||||
// get the buffer to receive into
|
||||
if (n_args == 2) {
|
||||
if (args[1].u_obj == mp_const_none) {
|
||||
// only the send was argument given, so create a fresh buffer of the send length
|
||||
vstr_init_len(&vstr_recv, bufinfo_send.len);
|
||||
bufinfo_recv.len = vstr_recv.len;
|
||||
bufinfo_recv.buf = vstr_recv.buf;
|
||||
o_ret = MP_OBJ_NULL;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// recv argument given
|
||||
mp_get_buffer_raise(args[2], &bufinfo_recv, MP_BUFFER_WRITE);
|
||||
mp_get_buffer_raise(args[1].u_obj, &bufinfo_recv, MP_BUFFER_WRITE);
|
||||
if (bufinfo_recv.len != bufinfo_send.len) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
o_ret = args[2];
|
||||
o_ret = args[1].u_obj;
|
||||
}
|
||||
}
|
||||
|
||||
// send and receive
|
||||
pybspi_transfer(self, (const char *)bufinfo_send.buf, vstr_recv.buf, bufinfo_send.len);
|
||||
pybspi_transfer(self, (const char *)bufinfo_send.buf, bufinfo_recv.buf, bufinfo_send.len);
|
||||
|
||||
// return the received data
|
||||
if (o_ret != MP_OBJ_NULL) {
|
||||
@@ -385,7 +427,7 @@ STATIC mp_obj_t pyb_spi_send_recv (mp_uint_t n_args, const mp_obj_t *args) {
|
||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr_recv);
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_spi_send_recv_obj, 2, 3, pyb_spi_send_recv);
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_spi_send_recv_obj, 1, pyb_spi_send_recv);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_spi_locals_dict_table[] = {
|
||||
// instance methods
|
||||
@@ -396,6 +438,7 @@ STATIC const mp_map_elem_t pyb_spi_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_send_recv), (mp_obj_t)&pyb_spi_send_recv_obj },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_MASTER), MP_OBJ_NEW_SMALL_INT(SPI_MODE_MASTER) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ACTIVE_LOW), MP_OBJ_NEW_SMALL_INT(SPI_CS_ACTIVELOW) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ACTIVE_HIGH), MP_OBJ_NEW_SMALL_INT(SPI_CS_ACTIVEHIGH) },
|
||||
};
|
||||
|
||||
880
cc3200/mods/pybtimer.c
Normal file
880
cc3200/mods/pybtimer.c
Normal file
@@ -0,0 +1,880 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/obj.h"
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/gc.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "inc/hw_timer.h"
|
||||
#include "rom_map.h"
|
||||
#include "interrupt.h"
|
||||
#include "prcm.h"
|
||||
#include "timer.h"
|
||||
#include "pybtimer.h"
|
||||
#include "pybsleep.h"
|
||||
#include "mpcallback.h"
|
||||
#include "mpexception.h"
|
||||
|
||||
|
||||
/// \moduleref pyb
|
||||
/// \class Timer - generate periodic events, count events, and create PWM signals.
|
||||
///
|
||||
/// Each timer consists of a counter that counts up at a certain rate. The rate
|
||||
/// at which it counts is the peripheral clock frequency (in Hz) divided by the
|
||||
/// timer prescaler. When the counter reaches the timer period it triggers an
|
||||
/// event, and the counter resets back to zero. By using the callback method,
|
||||
/// the timer event can call a Python function.
|
||||
///
|
||||
/// Example usage to toggle an LED at a fixed frequency:
|
||||
///
|
||||
/// tim = pyb.Timer(4) # create a timer object using timer 4
|
||||
/// tim.init(mode=Timer.PERIODIC) # initialize it in periodic mode
|
||||
/// tim_ch = tim.channel(Timer.A, freq=2) # configure channel A at a frequency of 2Hz
|
||||
/// tim_ch.callback(handler=lambda t:led.toggle()) # toggle a LED on every cycle of the timer
|
||||
///
|
||||
/// Further examples:
|
||||
///
|
||||
/// tim1 = pyb.Timer(2, mode=Timer.EVENT_COUNT) # initialize it capture mode
|
||||
/// tim2 = pyb.Timer(1, mode=Timer.PWM) # initialize it in PWM mode
|
||||
/// tim_ch = tim1.channel(Timer.A, freq=1, polarity=Timer.POSITIVE) # start the event counter with a frequency of 1Hz and triggered by positive edges
|
||||
/// tim_ch = tim2.channel(Timer.B, freq=10000, duty_cycle=50) # start the PWM on channel B with a 50% duty cycle
|
||||
/// tim_ch.time() # get the current time in usec (can also be set)
|
||||
/// tim_ch.freq(20) # set the frequency (can also get)
|
||||
/// tim_ch.duty_cycle(30) # set the duty cycle to 30% (can also get)
|
||||
/// tim_ch.duty_cycle(30, Timer.NEGATIVE) # set the duty cycle to 30% and change the polarity to negative
|
||||
/// tim_ch.event_count() # get the number of captured events
|
||||
/// tim_ch.event_time() # get the the time of the last captured event
|
||||
/// tim_ch.period(2000000) # change the period to 2 seconds
|
||||
///
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYBTIMER_NUM_TIMERS (4)
|
||||
#define PYBTIMER_POLARITY_POS (0x01)
|
||||
#define PYBTIMER_POLARITY_NEG (0x02)
|
||||
|
||||
#define PYBTIMER_SRC_FREQ_HZ HAL_FCPU_HZ
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE TYPES
|
||||
******************************************************************************/
|
||||
typedef struct _pyb_timer_obj_t {
|
||||
mp_obj_base_t base;
|
||||
uint32_t timer;
|
||||
uint32_t config;
|
||||
uint16_t intflags;
|
||||
uint8_t peripheral;
|
||||
uint8_t id;
|
||||
} pyb_timer_obj_t;
|
||||
|
||||
typedef struct _pyb_timer_channel_obj_t {
|
||||
mp_obj_base_t base;
|
||||
struct _pyb_timer_obj_t *timer;
|
||||
uint32_t frequency;
|
||||
uint32_t period;
|
||||
uint16_t channel;
|
||||
uint8_t polarity;
|
||||
uint8_t duty_cycle;
|
||||
} pyb_timer_channel_obj_t;
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC const mp_cb_methods_t pyb_timer_channel_cb_methods;
|
||||
STATIC pyb_timer_obj_t pyb_timer_obj[PYBTIMER_NUM_TIMERS] = {{.timer = TIMERA0_BASE, .peripheral = PRCM_TIMERA0},
|
||||
{.timer = TIMERA1_BASE, .peripheral = PRCM_TIMERA1},
|
||||
{.timer = TIMERA2_BASE, .peripheral = PRCM_TIMERA2},
|
||||
{.timer = TIMERA3_BASE, .peripheral = PRCM_TIMERA3}};
|
||||
STATIC const mp_obj_type_t pyb_timer_channel_type;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
STATIC mp_obj_t pyb_timer_channel_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
|
||||
STATIC void timer_disable (pyb_timer_obj_t *tim);
|
||||
STATIC void TIMER0AIntHandler(void);
|
||||
STATIC void TIMER0BIntHandler(void);
|
||||
STATIC void TIMER1AIntHandler(void);
|
||||
STATIC void TIMER1BIntHandler(void);
|
||||
STATIC void TIMER2AIntHandler(void);
|
||||
STATIC void TIMER2BIntHandler(void);
|
||||
STATIC void TIMER3AIntHandler(void);
|
||||
STATIC void TIMER3BIntHandler(void);
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
void timer_init0 (void) {
|
||||
mp_obj_list_init(&MP_STATE_PORT(pyb_timer_channel_obj_list), 0);
|
||||
}
|
||||
|
||||
void timer_disable_all (void) {
|
||||
pyb_timer_obj_t timer = {
|
||||
.timer = TIMERA0_BASE,
|
||||
.intflags = TIMER_CAPB_EVENT | TIMER_CAPB_MATCH |
|
||||
TIMER_TIMB_TIMEOUT | TIMER_CAPA_EVENT |
|
||||
TIMER_CAPA_MATCH | TIMER_TIMA_TIMEOUT,
|
||||
.peripheral = PRCM_TIMERA0
|
||||
};
|
||||
|
||||
for (uint32_t i = 0; i < PYBTIMER_NUM_TIMERS; i++) {
|
||||
// in case it's not clocked
|
||||
MAP_PRCMPeripheralClkEnable(timer.peripheral, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
timer_disable(&timer);
|
||||
// timer base offset according to hw_memmap.h
|
||||
timer.timer += 0x1000;
|
||||
// peripheral offset according to prcm.h
|
||||
timer.peripheral++;
|
||||
}
|
||||
}
|
||||
|
||||
void pyb_timer_channel_callback_enable (mp_obj_t self_in) {
|
||||
pyb_timer_channel_obj_t *self = self_in;
|
||||
MAP_TimerIntClear(self->timer->timer, self->timer->intflags & self->channel);
|
||||
MAP_TimerIntEnable(self->timer->timer, self->timer->intflags & self->channel);
|
||||
}
|
||||
|
||||
void pyb_timer_channel_callback_disable (mp_obj_t self_in) {
|
||||
pyb_timer_channel_obj_t *self = self_in;
|
||||
MAP_TimerIntDisable(self->timer->timer, self->timer->intflags & self->channel);
|
||||
}
|
||||
|
||||
pyb_timer_channel_obj_t *pyb_timer_channel_find (uint32_t timer, uint16_t channel_n) {
|
||||
for (mp_uint_t i = 0; i < MP_STATE_PORT(pyb_timer_channel_obj_list).len; i++) {
|
||||
pyb_timer_channel_obj_t *ch = ((pyb_timer_channel_obj_t *)(MP_STATE_PORT(pyb_timer_channel_obj_list).items[i]));
|
||||
// any 32-bit timer must be matched by any of its 16-bit versions
|
||||
if (ch->timer->timer == timer && ((ch->channel & TIMER_A) == channel_n || (ch->channel & TIMER_B) == channel_n)) {
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
return MP_OBJ_NULL;
|
||||
}
|
||||
|
||||
void pyb_timer_channel_remove (pyb_timer_channel_obj_t *ch) {
|
||||
pyb_timer_channel_obj_t *channel;
|
||||
if ((channel = pyb_timer_channel_find(ch->timer->timer, ch->channel))) {
|
||||
mp_obj_list_remove(&MP_STATE_PORT(pyb_timer_channel_obj_list), channel);
|
||||
}
|
||||
}
|
||||
|
||||
void pyb_timer_channel_add (pyb_timer_channel_obj_t *ch) {
|
||||
// remove it in case it already exists
|
||||
pyb_timer_channel_remove(ch);
|
||||
mp_obj_list_append(&MP_STATE_PORT(pyb_timer_channel_obj_list), ch);
|
||||
}
|
||||
|
||||
STATIC void timer_disable (pyb_timer_obj_t *tim) {
|
||||
// disable all timers and it's interrupts
|
||||
MAP_TimerDisable(tim->timer, TIMER_A | TIMER_B);
|
||||
MAP_TimerIntDisable(tim->timer, tim->intflags);
|
||||
MAP_TimerIntClear(tim->timer, tim->intflags);
|
||||
MAP_PRCMPeripheralClkDisable(tim->peripheral, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
memset(&pyb_timer_obj[tim->id], 0, sizeof(pyb_timer_obj_t));
|
||||
}
|
||||
|
||||
// computes prescaler period and match value so timer triggers at freq-Hz
|
||||
STATIC uint32_t compute_prescaler_period_and_match_value(pyb_timer_channel_obj_t *ch, uint32_t *period_out, uint32_t *match_out) {
|
||||
uint32_t maxcount = (ch->channel == (TIMER_A | TIMER_B)) ? 0xFFFFFFFF : 0xFFFF;
|
||||
uint32_t prescaler;
|
||||
uint32_t period_c = (ch->frequency > 0) ? PYBTIMER_SRC_FREQ_HZ / ch->frequency : ((PYBTIMER_SRC_FREQ_HZ / 1000000) * ch->period);
|
||||
|
||||
period_c = MAX(1, period_c) - 1;
|
||||
if (period_c == 0) {
|
||||
goto error;
|
||||
}
|
||||
prescaler = period_c >> 16;
|
||||
*period_out = period_c;
|
||||
if (prescaler > 0xFF && maxcount == 0xFFFF) {
|
||||
goto error;
|
||||
}
|
||||
// check limit values for the duty cycle
|
||||
if (ch->duty_cycle == 0) {
|
||||
*match_out = period_c - 1;
|
||||
}
|
||||
else {
|
||||
*match_out = period_c - ((period_c * ch->duty_cycle) / 100);
|
||||
}
|
||||
if ((ch->timer->config & 0x0F) == TIMER_CFG_A_PWM && (*match_out > 0xFFFF)) {
|
||||
goto error;
|
||||
}
|
||||
return prescaler;
|
||||
|
||||
error:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
STATIC void timer_init (pyb_timer_obj_t *tim) {
|
||||
MAP_PRCMPeripheralClkEnable(tim->peripheral, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
MAP_PRCMPeripheralReset(tim->peripheral);
|
||||
MAP_TimerConfigure(tim->timer, tim->config);
|
||||
}
|
||||
|
||||
STATIC void timer_channel_init (pyb_timer_channel_obj_t *ch) {
|
||||
// calculate the period, the prescaler and the match value
|
||||
uint32_t period_c;
|
||||
uint32_t match;
|
||||
uint32_t prescaler = compute_prescaler_period_and_match_value(ch, &period_c, &match);
|
||||
|
||||
// set the prescaler
|
||||
MAP_TimerPrescaleSet(ch->timer->timer, ch->channel, (prescaler < 0xFF) ? prescaler : 0);
|
||||
|
||||
// set the load value
|
||||
MAP_TimerLoadSet(ch->timer->timer, ch->channel, period_c);
|
||||
|
||||
// configure the pwm if we are in such mode
|
||||
if ((ch->timer->config & 0x0F) == TIMER_CFG_A_PWM) {
|
||||
// invert the timer output if required
|
||||
MAP_TimerControlLevel(ch->timer->timer, ch->channel, (ch->polarity == PYBTIMER_POLARITY_NEG) ? true : false);
|
||||
// set the match value (which is simply the duty cycle translated to ticks)
|
||||
MAP_TimerMatchSet(ch->timer->timer, ch->channel, match);
|
||||
}
|
||||
// configure the event edge type if we are in such mode
|
||||
else if ((ch->timer->config & 0x0F) == TIMER_CFG_A_CAP_COUNT || (ch->timer->config & 0x0F) == TIMER_CFG_A_CAP_TIME) {
|
||||
uint32_t polarity = TIMER_EVENT_BOTH_EDGES;
|
||||
if (ch->polarity == PYBTIMER_POLARITY_POS) {
|
||||
polarity = TIMER_EVENT_POS_EDGE;
|
||||
}
|
||||
else if (ch->polarity == PYBTIMER_POLARITY_NEG) {
|
||||
polarity = TIMER_EVENT_NEG_EDGE;
|
||||
}
|
||||
MAP_TimerControlEvent(ch->timer->timer, ch->channel, polarity);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// stall the timer when the processor is halted while debugging
|
||||
MAP_TimerControlStall(ch->timer->timer, ch->channel, true);
|
||||
#endif
|
||||
|
||||
// now enable the timer channel
|
||||
MAP_TimerEnable(ch->timer->timer, ch->channel);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings */
|
||||
|
||||
STATIC void pyb_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_timer_obj_t *tim = self_in;
|
||||
uint32_t mode = tim->config & 0xFF;
|
||||
|
||||
// timer mode
|
||||
qstr mode_qst = MP_QSTR_PWM;
|
||||
switch(mode) {
|
||||
case TIMER_CFG_A_ONE_SHOT:
|
||||
mode_qst = MP_QSTR_ONE_SHOT;
|
||||
break;
|
||||
case TIMER_CFG_A_PERIODIC:
|
||||
mode_qst = MP_QSTR_PERIODIC;
|
||||
break;
|
||||
case TIMER_CFG_A_CAP_COUNT:
|
||||
mode_qst = MP_QSTR_EDGE_COUNT;
|
||||
break;
|
||||
case TIMER_CFG_A_CAP_TIME:
|
||||
mode_qst = MP_QSTR_EDGE_TIME;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mp_printf(print, "<Timer%u, mode=Timer.%q>", (tim->id + 1), mode_qst);
|
||||
}
|
||||
|
||||
/// \method init(mode, *, width)
|
||||
/// Initialise the timer. Initialisation must give the desired mode
|
||||
/// and an optional timer width
|
||||
///
|
||||
/// tim.init(mode=Timer.ONE_SHOT, width=32) # one shot mode
|
||||
/// tim.init(mode=Timer.PERIODIC) # configure in free running periodic mode
|
||||
/// split into two 16-bit independent timers
|
||||
///
|
||||
/// Keyword arguments:
|
||||
///
|
||||
/// - `width` - specifies the width of the timer. Default is 32 bit mode. When in 16 bit mode
|
||||
/// the timer is splitted into 2 independent channels.
|
||||
///
|
||||
STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *tim, 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_mode, MP_ARG_REQUIRED | MP_ARG_INT, },
|
||||
{ MP_QSTR_width, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 16} },
|
||||
};
|
||||
|
||||
// parse args
|
||||
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);
|
||||
|
||||
// check the mode
|
||||
uint32_t _mode = args[0].u_int;
|
||||
if (_mode != TIMER_CFG_A_ONE_SHOT && _mode != TIMER_CFG_A_PERIODIC && _mode != TIMER_CFG_A_CAP_COUNT &&
|
||||
_mode != TIMER_CFG_A_CAP_TIME && _mode != TIMER_CFG_A_PWM) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
// check the width
|
||||
if (args[1].u_int != 16 && args[1].u_int != 32) {
|
||||
goto error;
|
||||
}
|
||||
bool is16bit = (args[1].u_int == 16);
|
||||
|
||||
if (!is16bit && (_mode != TIMER_CFG_A_ONE_SHOT && _mode != TIMER_CFG_A_PERIODIC)) {
|
||||
// 32-bit mode is only available when in free running modes
|
||||
goto error;
|
||||
}
|
||||
tim->config = is16bit ? ((_mode | (_mode << 8)) | TIMER_CFG_SPLIT_PAIR) : _mode;
|
||||
|
||||
timer_init(tim);
|
||||
// register it with the sleep module
|
||||
pybsleep_add ((const mp_obj_t)tim, (WakeUpCB_t)timer_init);
|
||||
|
||||
return mp_const_none;
|
||||
|
||||
error:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
/// \classmethod \constructor(id, ...)
|
||||
/// Construct a new timer object of the given id. If additional
|
||||
/// arguments are given, then the timer is initialised by `init(...)`.
|
||||
/// `id` can be 1 to 4
|
||||
STATIC mp_obj_t pyb_timer_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
// check arguments
|
||||
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
|
||||
|
||||
// create a new Timer object
|
||||
int32_t timer_idx = mp_obj_get_int(args[0]) - 1;
|
||||
if (timer_idx < 0 || timer_idx > (PYBTIMER_NUM_TIMERS - 1)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
}
|
||||
|
||||
pyb_timer_obj_t *tim = &pyb_timer_obj[timer_idx];
|
||||
tim->base.type = &pyb_timer_type;
|
||||
tim->id = timer_idx;
|
||||
|
||||
if (n_args > 1 || n_kw > 0) {
|
||||
// start the peripheral
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
|
||||
pyb_timer_init_helper(tim, n_args - 1, args + 1, &kw_args);
|
||||
}
|
||||
return (mp_obj_t)tim;
|
||||
}
|
||||
|
||||
// \method init()
|
||||
/// initializes the timer
|
||||
STATIC mp_obj_t pyb_timer_init(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
return pyb_timer_init_helper(args[0], n_args - 1, args + 1, kw_args);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_timer_init_obj, 1, pyb_timer_init);
|
||||
|
||||
// \method deinit()
|
||||
/// disables the timer
|
||||
STATIC mp_obj_t pyb_timer_deinit(mp_obj_t self_in) {
|
||||
pyb_timer_obj_t *self = self_in;
|
||||
timer_disable(self);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_timer_deinit_obj, pyb_timer_deinit);
|
||||
|
||||
/// \method channel(channel, *, freq, period, polarity, duty_cycle)
|
||||
/// Initialise the timer channel. Initialization requires at least a frequency param. With no
|
||||
/// extra params given besides the channel id, the channel is returned with the previous configuration
|
||||
/// os 'None', if it hasn't been initialized before.
|
||||
///
|
||||
/// tim1.channel(Timer.A, freq=1000) # set channel A frequency to 1KHz
|
||||
/// tim2.channel(Timer.AB, freq=10) # both channels (because it's a 32 bit timer) combined to create a 10Hz timer
|
||||
///
|
||||
/// when initialiazing the channel of a 32-bit timer, channel ID MUST be = Timer.AB
|
||||
///
|
||||
/// Keyword arguments:
|
||||
///
|
||||
/// - `freq` - specifies the frequency in Hz.
|
||||
/// - `period` - specifies the period in microseconds.
|
||||
/// - `polarity` - in PWM specifies the polarity of the pulse. In capture mode specifies the edge to capture.
|
||||
/// in order to capture on both negative and positive edges, make it = Timer.POSITIVE | Timer.NEGATIVE.
|
||||
/// - `duty_cycle` - sets the duty cycle value
|
||||
///
|
||||
STATIC mp_obj_t pyb_timer_channel(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_freq, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_period, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = PYBTIMER_POLARITY_POS} },
|
||||
{ MP_QSTR_duty_cycle, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
};
|
||||
|
||||
pyb_timer_obj_t *tim = pos_args[0];
|
||||
mp_int_t channel_n = mp_obj_get_int(pos_args[1]);
|
||||
|
||||
// verify that the timer has been already initialized
|
||||
if (!tim->config) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
if (channel_n != TIMER_A && channel_n != TIMER_B && channel_n != (TIMER_A | TIMER_B)) {
|
||||
// invalid channel
|
||||
goto error;
|
||||
}
|
||||
if (channel_n == (TIMER_A | TIMER_B) && (tim->config & TIMER_CFG_SPLIT_PAIR)) {
|
||||
// 32-bit channel selected when the timer is in 16-bit mode
|
||||
goto error;
|
||||
}
|
||||
|
||||
// if only the channel number is given return the previously
|
||||
// allocated channel (or None if no previous channel)
|
||||
if (n_args == 2 && kw_args->used == 0) {
|
||||
pyb_timer_channel_obj_t *ch;
|
||||
if ((ch = pyb_timer_channel_find(tim->timer, channel_n))) {
|
||||
return ch;
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
// parse the arguments
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
// throw an exception if both frequency and period are given
|
||||
if (args[0].u_int != 0 && args[1].u_int != 0) {
|
||||
goto error;
|
||||
}
|
||||
// check that at least one of them has a valid value
|
||||
if (args[0].u_int <= 0 && args[1].u_int <= 0) {
|
||||
goto error;
|
||||
}
|
||||
// check that the polarity is not 'both' in pwm mode
|
||||
if ((tim->config & TIMER_A) == TIMER_CFG_A_PWM && args[2].u_int == (PYBTIMER_POLARITY_POS | PYBTIMER_POLARITY_NEG)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
// allocate a new timer channel
|
||||
pyb_timer_channel_obj_t *ch = m_new_obj(pyb_timer_channel_obj_t);
|
||||
ch->base.type = &pyb_timer_channel_type;
|
||||
ch->timer = tim;
|
||||
ch->channel = channel_n;
|
||||
|
||||
// get the frequency the polarity and the duty cycle
|
||||
ch->frequency = args[0].u_int;
|
||||
ch->period = args[1].u_int;
|
||||
ch->polarity = args[2].u_int;
|
||||
ch->duty_cycle = MIN(100, MAX(0, args[3].u_int));
|
||||
|
||||
timer_channel_init(ch);
|
||||
|
||||
// register it with the sleep module
|
||||
pybsleep_add ((const mp_obj_t)ch, (WakeUpCB_t)timer_channel_init);
|
||||
|
||||
// add the timer to the list
|
||||
pyb_timer_channel_add(ch);
|
||||
|
||||
return ch;
|
||||
|
||||
error:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_timer_channel_obj, 2, pyb_timer_channel);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_timer_locals_dict_table[] = {
|
||||
// instance methods
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_timer_init_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_timer_deinit_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_channel), (mp_obj_t)&pyb_timer_channel_obj },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_A), MP_OBJ_NEW_SMALL_INT(TIMER_A) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_B), MP_OBJ_NEW_SMALL_INT(TIMER_B) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ONE_SHOT), MP_OBJ_NEW_SMALL_INT(TIMER_CFG_A_ONE_SHOT) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PERIODIC), MP_OBJ_NEW_SMALL_INT(TIMER_CFG_A_PERIODIC) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_EDGE_COUNT), MP_OBJ_NEW_SMALL_INT(TIMER_CFG_A_CAP_COUNT) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_EDGE_TIME), MP_OBJ_NEW_SMALL_INT(TIMER_CFG_A_CAP_TIME) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PWM), MP_OBJ_NEW_SMALL_INT(TIMER_CFG_A_PWM) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_POSITIVE), MP_OBJ_NEW_SMALL_INT(PYBTIMER_POLARITY_POS) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_NEGATIVE), MP_OBJ_NEW_SMALL_INT(PYBTIMER_POLARITY_NEG) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_timer_locals_dict, pyb_timer_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t pyb_timer_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_Timer,
|
||||
.print = pyb_timer_print,
|
||||
.make_new = pyb_timer_make_new,
|
||||
.locals_dict = (mp_obj_t)&pyb_timer_locals_dict,
|
||||
};
|
||||
|
||||
STATIC const mp_cb_methods_t pyb_timer_channel_cb_methods = {
|
||||
.init = pyb_timer_channel_callback,
|
||||
.enable = pyb_timer_channel_callback_enable,
|
||||
.disable = pyb_timer_channel_callback_disable,
|
||||
};
|
||||
|
||||
STATIC void TIMERGenericIntHandler(uint32_t timer, uint16_t channel) {
|
||||
pyb_timer_channel_obj_t *self;
|
||||
uint32_t status;
|
||||
|
||||
if ((self = pyb_timer_channel_find(timer, channel))) {
|
||||
status = MAP_TimerIntStatus(self->timer->timer, true) & self->channel;
|
||||
MAP_TimerIntClear(self->timer->timer, status);
|
||||
mp_obj_t _callback = mpcallback_find(self);
|
||||
mpcallback_handler(_callback);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void TIMER0AIntHandler(void) {
|
||||
TIMERGenericIntHandler(TIMERA0_BASE, TIMER_A);
|
||||
}
|
||||
|
||||
STATIC void TIMER0BIntHandler(void) {
|
||||
TIMERGenericIntHandler(TIMERA0_BASE, TIMER_B);
|
||||
}
|
||||
|
||||
STATIC void TIMER1AIntHandler(void) {
|
||||
TIMERGenericIntHandler(TIMERA1_BASE, TIMER_A);
|
||||
}
|
||||
|
||||
STATIC void TIMER1BIntHandler(void) {
|
||||
TIMERGenericIntHandler(TIMERA1_BASE, TIMER_B);
|
||||
}
|
||||
|
||||
STATIC void TIMER2AIntHandler(void) {
|
||||
TIMERGenericIntHandler(TIMERA2_BASE, TIMER_A);
|
||||
}
|
||||
|
||||
STATIC void TIMER2BIntHandler(void) {
|
||||
TIMERGenericIntHandler(TIMERA2_BASE, TIMER_B);
|
||||
}
|
||||
|
||||
STATIC void TIMER3AIntHandler(void) {
|
||||
TIMERGenericIntHandler(TIMERA3_BASE, TIMER_A);
|
||||
}
|
||||
|
||||
STATIC void TIMER3BIntHandler(void) {
|
||||
TIMERGenericIntHandler(TIMERA3_BASE, TIMER_B);
|
||||
}
|
||||
|
||||
STATIC void pyb_timer_channel_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_timer_channel_obj_t *ch = self_in;
|
||||
char *ch_id = "AB";
|
||||
// timer channel
|
||||
if (ch->channel == TIMER_A) {
|
||||
ch_id = "A";
|
||||
}
|
||||
else if (ch->channel == TIMER_B) {
|
||||
ch_id = "B";
|
||||
}
|
||||
|
||||
mp_printf(print, "<%q %s, timer=%u, %q=%u", MP_QSTR_TimerChannel,
|
||||
ch_id, (ch->timer->id + 1), MP_QSTR_freq, ch->frequency);
|
||||
|
||||
uint32_t mode = ch->timer->config & 0xFF;
|
||||
if (mode == TIMER_CFG_A_CAP_COUNT || mode == TIMER_CFG_A_CAP_TIME || mode == TIMER_CFG_A_PWM) {
|
||||
mp_printf(print, ", %q=Timer.", MP_QSTR_polarity);
|
||||
switch (ch->polarity) {
|
||||
case PYBTIMER_POLARITY_POS:
|
||||
mp_printf(print, "POSITIVE");
|
||||
break;
|
||||
case PYBTIMER_POLARITY_NEG:
|
||||
mp_printf(print, "NEGATIVE");
|
||||
break;
|
||||
default:
|
||||
mp_printf(print, "BOTH");
|
||||
break;
|
||||
}
|
||||
if (mode == TIMER_CFG_A_PWM) {
|
||||
mp_printf(print, ", %q=%u", MP_QSTR_duty_cycle, ch->duty_cycle);
|
||||
}
|
||||
}
|
||||
mp_printf(print, ">");
|
||||
}
|
||||
|
||||
/// \method freq([value])
|
||||
/// get or set the frequency of the timer channel
|
||||
STATIC mp_obj_t pyb_timer_channel_freq(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
pyb_timer_channel_obj_t *ch = args[0];
|
||||
if (n_args == 1) {
|
||||
// get
|
||||
return mp_obj_new_int(ch->frequency);
|
||||
} else {
|
||||
// set
|
||||
int32_t _frequency = mp_obj_get_int(args[1]);
|
||||
if (_frequency <= 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
ch->frequency = _frequency;
|
||||
ch->period = 1000000 / _frequency;
|
||||
timer_channel_init(ch);
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_timer_channel_freq_obj, 1, 2, pyb_timer_channel_freq);
|
||||
|
||||
/// \method period([value])
|
||||
/// get or set the period of the timer channel in microseconds
|
||||
STATIC mp_obj_t pyb_timer_channel_period(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
pyb_timer_channel_obj_t *ch = args[0];
|
||||
if (n_args == 1) {
|
||||
// get
|
||||
return mp_obj_new_int(ch->period);
|
||||
} else {
|
||||
// set
|
||||
int32_t _period = mp_obj_get_int(args[1]);
|
||||
if (_period <= 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
ch->period = _period;
|
||||
ch->frequency = 1000000 / _period;
|
||||
timer_channel_init(ch);
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_timer_channel_period_obj, 1, 2, pyb_timer_channel_period);
|
||||
|
||||
/// \method time([value])
|
||||
/// get or set the value of the timer channel in microseconds
|
||||
STATIC mp_obj_t pyb_timer_channel_time(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
pyb_timer_channel_obj_t *ch = args[0];
|
||||
uint32_t value;
|
||||
// calculate the period, the prescaler and the match value
|
||||
uint32_t period_c;
|
||||
uint32_t match;
|
||||
(void)compute_prescaler_period_and_match_value(ch, &period_c, &match);
|
||||
if (n_args == 1) {
|
||||
// get
|
||||
value = (ch->channel == TIMER_B) ? HWREG(ch->timer->timer + TIMER_O_TBV) : HWREG(ch->timer->timer + TIMER_O_TAV);
|
||||
// return the current timer value in microseconds
|
||||
// substract value to period since we are always operating in count-down mode
|
||||
uint32_t time_t = (1000 * (period_c - value)) / period_c;
|
||||
return mp_obj_new_int((time_t * 1000) / ch->frequency);
|
||||
}
|
||||
else {
|
||||
// set
|
||||
value = (mp_obj_get_int(args[1]) * ((ch->frequency * period_c) / 1000)) / 1000;
|
||||
if ((value > 0xFFFF) && (ch->timer->config & TIMER_CFG_SPLIT_PAIR)) {
|
||||
// this exceeds the maximum value of a 16-bit timer
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
// write period minus value since we are always operating in count-down mode
|
||||
TimerValueSet (ch->timer->timer, ch->channel, (period_c - value));
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_timer_channel_time_obj, 1, 2, pyb_timer_channel_time);
|
||||
|
||||
/// \method event_count()
|
||||
/// get the number of events triggered by the configured edge
|
||||
STATIC mp_obj_t pyb_timer_channel_event_count(mp_obj_t self_in) {
|
||||
pyb_timer_channel_obj_t *ch = self_in;
|
||||
return mp_obj_new_int(MAP_TimerValueGet(ch->timer->timer, ch->channel == (TIMER_A | TIMER_B) ? TIMER_A : ch->channel));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_timer_channel_event_count_obj, pyb_timer_channel_event_count);
|
||||
|
||||
/// \method event_time()
|
||||
/// get the time at which the last event was triggered
|
||||
STATIC mp_obj_t pyb_timer_channel_event_time(mp_obj_t self_in) {
|
||||
pyb_timer_channel_obj_t *ch = self_in;
|
||||
// calculate the period, the prescaler and the match value
|
||||
uint32_t period_c;
|
||||
uint32_t match;
|
||||
(void)compute_prescaler_period_and_match_value(ch, &period_c, &match);
|
||||
uint32_t value = MAP_TimerValueGet(ch->timer->timer, ch->channel == (TIMER_A | TIMER_B) ? TIMER_A : ch->channel);
|
||||
// substract value to period since we are always operating in count-down mode
|
||||
uint32_t time_t = (1000 * (period_c - value)) / period_c;
|
||||
return mp_obj_new_int((time_t * 1000) / ch->frequency);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_timer_channel_event_time_obj, pyb_timer_channel_event_time);
|
||||
|
||||
/// \method duty_cycle()
|
||||
/// get or set the duty cycle when in PWM mode
|
||||
STATIC mp_obj_t pyb_timer_channel_duty_cycle(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
pyb_timer_channel_obj_t *ch = args[0];
|
||||
if (n_args == 1) {
|
||||
// get
|
||||
return mp_obj_new_int(ch->duty_cycle);
|
||||
}
|
||||
else {
|
||||
// duty cycle must be converted from percentage to ticks
|
||||
// calculate the period, the prescaler and the match value
|
||||
uint32_t period_c;
|
||||
uint32_t match;
|
||||
ch->duty_cycle = MIN(100, MAX(0, mp_obj_get_int(args[1])));
|
||||
compute_prescaler_period_and_match_value(ch, &period_c, &match);
|
||||
if (n_args == 3) {
|
||||
// set the new polarity if requested
|
||||
ch->polarity = mp_obj_get_int(args[2]);
|
||||
MAP_TimerControlLevel(ch->timer->timer, ch->channel, (ch->polarity == PYBTIMER_POLARITY_NEG) ? true : false);
|
||||
}
|
||||
MAP_TimerMatchSet(ch->timer->timer, ch->channel, match);
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_timer_channel_duty_cycle_obj, 1, 3, pyb_timer_channel_duty_cycle);
|
||||
|
||||
/// \method callback(handler, priority, value)
|
||||
/// create a callback object associated with the timer channel
|
||||
STATIC mp_obj_t pyb_timer_channel_callback (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
mp_arg_val_t args[mpcallback_INIT_NUM_ARGS];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, mpcallback_INIT_NUM_ARGS, mpcallback_init_args, args);
|
||||
|
||||
pyb_timer_channel_obj_t *ch = pos_args[0];
|
||||
mp_obj_t _callback = mpcallback_find(ch);
|
||||
if (kw_args->used > 0 || !_callback) {
|
||||
// convert the priority to the correct value
|
||||
uint priority = mpcallback_translate_priority (args[2].u_int);
|
||||
|
||||
// validate the power mode
|
||||
uint pwrmode = args[4].u_int;
|
||||
if (pwrmode != PYB_PWR_MODE_ACTIVE) {
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
uint32_t _config = (ch->channel == TIMER_B) ? ((ch->timer->config & TIMER_B) >> 8) : (ch->timer->config & TIMER_A);
|
||||
|
||||
// validate and set the value if we are in edge count mode
|
||||
if (_config == TIMER_CFG_A_CAP_COUNT) {
|
||||
uint32_t c_value = args[3].u_int;
|
||||
if (!c_value || c_value > 0xFFFF) {
|
||||
// zero or exceeds the maximum value of a 16-bit timer
|
||||
goto invalid_args;
|
||||
}
|
||||
MAP_TimerMatchSet(ch->timer->timer, ch->channel, c_value);
|
||||
}
|
||||
|
||||
// disable the callback first
|
||||
pyb_timer_channel_callback_disable(ch);
|
||||
|
||||
uint8_t shift = (ch->channel == TIMER_B) ? 8 : 0;
|
||||
switch (_config) {
|
||||
case TIMER_CFG_A_ONE_SHOT:
|
||||
case TIMER_CFG_A_PERIODIC:
|
||||
ch->timer->intflags |= TIMER_TIMA_TIMEOUT << shift;
|
||||
break;
|
||||
case TIMER_CFG_A_CAP_COUNT:
|
||||
ch->timer->intflags |= TIMER_CAPA_MATCH << shift;
|
||||
// set the match value and make 1 the minimum
|
||||
MAP_TimerMatchSet(ch->timer->timer, ch->channel, MAX(1, args[3].u_int));
|
||||
break;
|
||||
case TIMER_CFG_A_CAP_TIME:
|
||||
ch->timer->intflags |= TIMER_CAPA_EVENT << shift;
|
||||
break;
|
||||
case TIMER_CFG_A_PWM:
|
||||
// special case for the PWM match interrupt
|
||||
ch->timer->intflags |= ((ch->channel & TIMER_A) == TIMER_A) ? TIMER_TIMA_MATCH : TIMER_TIMB_MATCH;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// special case for a 32-bit timer
|
||||
if (ch->channel == (TIMER_A | TIMER_B)) {
|
||||
ch->timer->intflags |= (ch->timer->intflags << 8);
|
||||
}
|
||||
|
||||
void (*pfnHandler)(void);
|
||||
uint32_t intregister;
|
||||
switch (ch->timer->timer) {
|
||||
case TIMERA0_BASE:
|
||||
if (ch->channel == TIMER_B) {
|
||||
pfnHandler = &TIMER0BIntHandler;
|
||||
intregister = INT_TIMERA0B;
|
||||
} else {
|
||||
pfnHandler = &TIMER0AIntHandler;
|
||||
intregister = INT_TIMERA0A;
|
||||
}
|
||||
break;
|
||||
case TIMERA1_BASE:
|
||||
if (ch->channel == TIMER_B) {
|
||||
pfnHandler = &TIMER1BIntHandler;
|
||||
intregister = INT_TIMERA1B;
|
||||
} else {
|
||||
pfnHandler = &TIMER1AIntHandler;
|
||||
intregister = INT_TIMERA1A;
|
||||
}
|
||||
break;
|
||||
case TIMERA2_BASE:
|
||||
if (ch->channel == TIMER_B) {
|
||||
pfnHandler = &TIMER2BIntHandler;
|
||||
intregister = INT_TIMERA2B;
|
||||
} else {
|
||||
pfnHandler = &TIMER2AIntHandler;
|
||||
intregister = INT_TIMERA2A;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (ch->channel == TIMER_B) {
|
||||
pfnHandler = &TIMER3BIntHandler;
|
||||
intregister = INT_TIMERA3B;
|
||||
} else {
|
||||
pfnHandler = &TIMER3AIntHandler;
|
||||
intregister = INT_TIMERA3A;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// register the interrupt and configure the priority
|
||||
MAP_IntPrioritySet(intregister, priority);
|
||||
MAP_TimerIntRegister(ch->timer->timer, ch->channel, pfnHandler);
|
||||
|
||||
// create the callback
|
||||
_callback = mpcallback_new (ch, args[1].u_obj, &pyb_timer_channel_cb_methods);
|
||||
|
||||
// reload the timer
|
||||
uint32_t period_c;
|
||||
uint32_t match;
|
||||
compute_prescaler_period_and_match_value(ch, &period_c, &match);
|
||||
MAP_TimerLoadSet(ch->timer->timer, ch->channel, period_c);
|
||||
|
||||
// enable the callback before returning
|
||||
pyb_timer_channel_callback_enable(ch);
|
||||
}
|
||||
return _callback;
|
||||
|
||||
invalid_args:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_timer_channel_callback_obj, 1, pyb_timer_channel_callback);
|
||||
|
||||
STATIC const mp_map_elem_t pyb_timer_channel_locals_dict_table[] = {
|
||||
// instance methods
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_freq), (mp_obj_t)&pyb_timer_channel_freq_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_period), (mp_obj_t)&pyb_timer_channel_period_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&pyb_timer_channel_time_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_event_count), (mp_obj_t)&pyb_timer_channel_event_count_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_event_time), (mp_obj_t)&pyb_timer_channel_event_time_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_duty_cycle), (mp_obj_t)&pyb_timer_channel_duty_cycle_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&pyb_timer_channel_callback_obj },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_timer_channel_locals_dict, pyb_timer_channel_locals_dict_table);
|
||||
|
||||
STATIC const mp_obj_type_t pyb_timer_channel_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_TimerChannel,
|
||||
.print = pyb_timer_channel_print,
|
||||
.locals_dict = (mp_obj_t)&pyb_timer_channel_locals_dict,
|
||||
};
|
||||
|
||||
@@ -25,17 +25,14 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// This file contains pin definitions that are specific to the cc3200 port.
|
||||
// This file should only ever be #included by pybgpio.h and not directly.
|
||||
/******************************************************************************
|
||||
DECLARE EXPORTED DATA
|
||||
******************************************************************************/
|
||||
extern const mp_obj_type_t pyb_timer_type;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
void timer_init0 (void);
|
||||
void timer_disable_all (void);
|
||||
|
||||
//*****************************************************************************
|
||||
// Define types
|
||||
//*****************************************************************************
|
||||
|
||||
enum {
|
||||
PORT_A0 = GPIOA0_BASE,
|
||||
PORT_A1 = GPIOA1_BASE,
|
||||
PORT_A2 = GPIOA2_BASE,
|
||||
PORT_A3 = GPIOA3_BASE
|
||||
};
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "mpexception.h"
|
||||
#include "py/mpstate.h"
|
||||
#include "osi.h"
|
||||
#include "utils.h"
|
||||
|
||||
/// \moduleref pyb
|
||||
/// \class UART - duplex serial communication bus
|
||||
@@ -62,7 +63,7 @@
|
||||
///
|
||||
/// from pyb import UART
|
||||
///
|
||||
/// uart = UART(0, 9600) # init with given baudrate
|
||||
/// uart = UART(1, 9600) # init with given baudrate
|
||||
/// uart.init(9600, bits=8, stop=1, parity=None) # init with given parameters
|
||||
///
|
||||
/// Bits can be 5, 6, 7, 8, parity can be None, 0 (even), 1 (odd). Stop can be 1 or 2.
|
||||
@@ -88,8 +89,8 @@
|
||||
/******************************************************************************
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define PYBUART_TX_WAIT_MS 1
|
||||
#define PYBUART_TX_MAX_TIMEOUT_MS 5
|
||||
#define PYBUART_TX_WAIT_US (50)
|
||||
#define PYBUART_TX_MAX_TIMEOUT_MS (5)
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
@@ -101,6 +102,7 @@ STATIC void UART0IntHandler(void);
|
||||
STATIC void UART1IntHandler(void);
|
||||
STATIC void uart_callback_enable (mp_obj_t self_in);
|
||||
STATIC void uart_callback_disable (mp_obj_t self_in);
|
||||
STATIC mp_obj_t pyb_uart_deinit(mp_obj_t self_in);
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE TYPES
|
||||
@@ -124,7 +126,8 @@ struct _pyb_uart_obj_t {
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
STATIC pyb_uart_obj_t pyb_uart_obj[PYB_NUM_UARTS];
|
||||
STATIC pyb_uart_obj_t pyb_uart_obj[PYB_NUM_UARTS] = {{.reg = UARTA0_BASE, .baudrate = 0, .peripheral = PRCM_UARTA0},
|
||||
{.reg = UARTA1_BASE, .baudrate = 0, .peripheral = PRCM_UARTA1}};
|
||||
STATIC const mp_cb_methods_t uart_cb_methods;
|
||||
|
||||
/******************************************************************************
|
||||
@@ -153,10 +156,10 @@ bool uart_tx_char(pyb_uart_obj_t *self, int c) {
|
||||
uint32_t timeout = 0;
|
||||
|
||||
while (!MAP_UARTCharPutNonBlocking(self->reg, c)) {
|
||||
if (timeout++ > (PYBUART_TX_MAX_TIMEOUT_MS / PYBUART_TX_WAIT_MS)) {
|
||||
if (timeout++ > ((PYBUART_TX_MAX_TIMEOUT_MS * 1000) / PYBUART_TX_WAIT_US)) {
|
||||
return false;
|
||||
}
|
||||
HAL_Delay (PYBUART_TX_WAIT_MS);
|
||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT(PYBUART_TX_WAIT_US));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -208,20 +211,19 @@ mp_obj_t uart_callback_new (pyb_uart_obj_t *self, mp_obj_t handler, uint rxbuffe
|
||||
return _callback;
|
||||
}
|
||||
|
||||
void uart_disable_all (void) {
|
||||
for (int i = 0; i < PYB_NUM_UARTS; i++) {
|
||||
// in case it's not clocked
|
||||
MAP_PRCMPeripheralClkEnable(pyb_uart_obj[i].peripheral, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
pyb_uart_deinit(&pyb_uart_obj[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE FUNCTIONS
|
||||
******************************************************************************/
|
||||
// assumes init parameters have been set up correctly
|
||||
STATIC void uart_init (pyb_uart_obj_t *self) {
|
||||
if (self->uart_id == PYB_UART_0) {
|
||||
self->reg = UARTA0_BASE;
|
||||
self->peripheral = PRCM_UARTA0;
|
||||
}
|
||||
else {
|
||||
self->reg = UARTA1_BASE;
|
||||
self->peripheral = PRCM_UARTA1;
|
||||
}
|
||||
|
||||
// Enable the peripheral clock
|
||||
MAP_PRCMPeripheralClkEnable(self->peripheral, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
|
||||
@@ -312,37 +314,37 @@ STATIC void uart_callback_disable (mp_obj_t self_in) {
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings */
|
||||
|
||||
STATIC void pyb_uart_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_uart_obj_t *self = self_in;
|
||||
if (self->baudrate > 0) {
|
||||
print(env, "<UART%u, baudrate=%u, bits=", self->uart_id, self->baudrate);
|
||||
mp_printf(print, "<UART%u, baudrate=%u, bits=", (self->uart_id + 1), self->baudrate);
|
||||
switch (self->config & UART_CONFIG_WLEN_MASK) {
|
||||
case UART_CONFIG_WLEN_5:
|
||||
print(env, "5");
|
||||
mp_print_str(print, "5");
|
||||
break;
|
||||
case UART_CONFIG_WLEN_6:
|
||||
print(env, "6");
|
||||
mp_print_str(print, "6");
|
||||
break;
|
||||
case UART_CONFIG_WLEN_7:
|
||||
print(env, "7");
|
||||
mp_print_str(print, "7");
|
||||
break;
|
||||
case UART_CONFIG_WLEN_8:
|
||||
print(env, "8");
|
||||
mp_print_str(print, "8");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ((self->config & UART_CONFIG_PAR_MASK) == UART_CONFIG_PAR_NONE) {
|
||||
print(env, ", parity=None");
|
||||
mp_print_str(print, ", parity=None");
|
||||
} else {
|
||||
print(env, ", parity=%u", (self->config & UART_CONFIG_PAR_MASK) == UART_CONFIG_PAR_EVEN ? 0 : 1);
|
||||
mp_printf(print, ", parity=%u", (self->config & UART_CONFIG_PAR_MASK) == UART_CONFIG_PAR_EVEN ? 0 : 1);
|
||||
}
|
||||
print(env, ", stop=%u, timeout=%u, timeout_char=%u, read_buf_len=%u>",
|
||||
mp_printf(print, ", stop=%u, timeout=%u, timeout_char=%u, read_buf_len=%u>",
|
||||
(self->config & UART_CONFIG_STOP_MASK) == UART_CONFIG_STOP_ONE ? 1 : 2,
|
||||
self->timeout, self->timeout_char, self->read_buf_len);
|
||||
}
|
||||
else {
|
||||
print(env, "<UART%u>", self->uart_id);
|
||||
mp_printf(print, "<UART%u>", (self->uart_id + 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,11 +353,11 @@ STATIC void pyb_uart_print(void (*print)(void *env, const char *fmt, ...), void
|
||||
/// Initialise the UART bus with the given parameters:
|
||||
///
|
||||
/// - `baudrate` is the clock rate.
|
||||
/// - `bits` is the number of bits per byte, 7, 8 or 9.
|
||||
/// - `bits` is the number of bits per byte, 5, 6, 7, 8
|
||||
/// - `parity` is the parity, `None`, 0 (even) or 1 (odd).
|
||||
/// - `stop` is the number of stop bits, 1 or 2.
|
||||
/// - `flowcontrol` is the flow control mode, `None`, `UART.FLOW_TX`,
|
||||
/// `UART.FLOW_RX', 'UART.FLOW_TXRX`.
|
||||
/// - `flow` is the flow control mode, `None`, `UART.RTS`,
|
||||
/// `UART.CTS', or `UART.CTS | UART.RTS`
|
||||
/// - `timeout` is the timeout (in milliseconds) when waiting for the first character.
|
||||
/// - `timeout_char` is the timeout (in milliseconds) between characters.
|
||||
STATIC const mp_arg_t pyb_uart_init_args[] = {
|
||||
@@ -402,7 +404,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con
|
||||
self->config = UART_CONFIG_WLEN_8;
|
||||
break;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
goto error;
|
||||
break;
|
||||
}
|
||||
// Parity
|
||||
@@ -414,6 +416,10 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con
|
||||
// Stop bits
|
||||
self->config |= (args[3].u_int == 1 ? UART_CONFIG_STOP_ONE : UART_CONFIG_STOP_TWO);
|
||||
// Flow control
|
||||
if (args[4].u_int != UART_FLOWCONTROL_NONE || args[4].u_int != UART_FLOWCONTROL_TX ||
|
||||
args[4].u_int != UART_FLOWCONTROL_RX || args[4].u_int != (UART_FLOWCONTROL_TX | UART_FLOWCONTROL_RX)) {
|
||||
goto error;
|
||||
}
|
||||
self->flowcontrol = args[4].u_int;
|
||||
}
|
||||
else {
|
||||
@@ -427,11 +433,14 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, mp_uint_t n_args, con
|
||||
pybsleep_add ((const mp_obj_t)self, (WakeUpCB_t)uart_init);
|
||||
|
||||
return mp_const_none;
|
||||
|
||||
error:
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
/// \classmethod \constructor(bus, ...)
|
||||
///
|
||||
/// Construct a UART object on the given bus id. `bus id` can be 0 or 1
|
||||
/// Construct a UART object on the given bus id. `bus id` can be 1 or 2
|
||||
/// With no additional parameters, the UART object is created but not
|
||||
/// initialised (it has the settings from the last initialisation of
|
||||
/// the bus, if any).
|
||||
@@ -447,7 +456,7 @@ STATIC mp_obj_t pyb_uart_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t
|
||||
mp_arg_check_num(n_args, n_kw, 1, MP_ARRAY_SIZE(pyb_uart_init_args), true);
|
||||
|
||||
// work out the uart id
|
||||
pyb_uart_id_t uart_id = mp_obj_get_int(args[0]);
|
||||
int32_t uart_id = mp_obj_get_int(args[0]) - 1;
|
||||
|
||||
if (uart_id < PYB_UART_0 || uart_id > PYB_UART_1) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_resource_not_avaliable));
|
||||
@@ -457,6 +466,7 @@ STATIC mp_obj_t pyb_uart_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t
|
||||
pyb_uart_obj_t *self = &pyb_uart_obj[uart_id];
|
||||
self->base.type = &pyb_uart_type;
|
||||
self->uart_id = uart_id;
|
||||
|
||||
if (n_args > 1 || n_kw > 0) {
|
||||
// start the peripheral
|
||||
mp_map_t kw_args;
|
||||
@@ -474,7 +484,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_init_obj, 1, pyb_uart_init);
|
||||
|
||||
/// \method deinit()
|
||||
/// Turn off the UART bus.
|
||||
mp_obj_t pyb_uart_deinit(mp_obj_t self_in) {
|
||||
STATIC mp_obj_t pyb_uart_deinit(mp_obj_t self_in) {
|
||||
pyb_uart_obj_t *self = self_in;
|
||||
|
||||
// unregister it with the sleep module
|
||||
@@ -516,7 +526,7 @@ STATIC mp_obj_t pyb_uart_callback (mp_uint_t n_args, const mp_obj_t *pos_args, m
|
||||
uint priority = mpcallback_translate_priority (args[2].u_int);
|
||||
|
||||
// check the power mode
|
||||
if (PYB_PWR_MODE_ACTIVE != args[3].u_int) {
|
||||
if (PYB_PWR_MODE_ACTIVE != args[4].u_int) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
|
||||
@@ -538,7 +548,7 @@ STATIC mp_obj_t pyb_uart_writechar(mp_obj_t self_in, mp_obj_t char_in) {
|
||||
|
||||
// send the character
|
||||
if (!uart_tx_char(self, data)) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ETIMEDOUT)));
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
@@ -559,6 +569,18 @@ STATIC mp_obj_t pyb_uart_readchar(mp_obj_t self_in) {
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_readchar_obj, pyb_uart_readchar);
|
||||
|
||||
/// \method sendbreak()
|
||||
STATIC mp_obj_t pyb_uart_sendbreak(mp_obj_t self_in) {
|
||||
pyb_uart_obj_t *self = self_in;
|
||||
// send a break signal for at least 2 complete frames
|
||||
MAP_UARTBreakCtl(self->reg, true);
|
||||
UtilsDelay(UTILS_DELAY_US_TO_COUNT((22 * 1000000) / self->baudrate));
|
||||
MAP_UARTBreakCtl(self->reg, false);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_sendbreak_obj, pyb_uart_sendbreak);
|
||||
|
||||
|
||||
STATIC const mp_map_elem_t pyb_uart_locals_dict_table[] = {
|
||||
// instance methods
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_uart_init_obj },
|
||||
@@ -579,12 +601,11 @@ STATIC const mp_map_elem_t pyb_uart_locals_dict_table[] = {
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_writechar), (mp_obj_t)&pyb_uart_writechar_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_readchar), (mp_obj_t)&pyb_uart_readchar_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_sendbreak), (mp_obj_t)&pyb_uart_sendbreak_obj },
|
||||
|
||||
// class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_FLOW_NONE), MP_OBJ_NEW_SMALL_INT(UART_FLOWCONTROL_NONE) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_FLOW_TX), MP_OBJ_NEW_SMALL_INT(UART_FLOWCONTROL_TX) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_FLOW_RX), MP_OBJ_NEW_SMALL_INT(UART_FLOWCONTROL_RX) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_FLOW_TXRX), MP_OBJ_NEW_SMALL_INT(UART_FLOWCONTROL_TX | UART_FLOWCONTROL_RX) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_CTS), MP_OBJ_NEW_SMALL_INT(UART_FLOWCONTROL_TX) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_RTS), MP_OBJ_NEW_SMALL_INT(UART_FLOWCONTROL_RX) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_uart_locals_dict, pyb_uart_locals_dict_table);
|
||||
@@ -622,7 +643,7 @@ STATIC mp_uint_t pyb_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t
|
||||
|
||||
// write the data
|
||||
if (!uart_tx_strn(self, buf, size)) {
|
||||
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ETIMEDOUT)));
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_operation_failed));
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -38,12 +38,12 @@ typedef struct _pyb_uart_obj_t pyb_uart_obj_t;
|
||||
extern const mp_obj_type_t pyb_uart_type;
|
||||
|
||||
void uart_init0(void);
|
||||
mp_obj_t pyb_uart_deinit(mp_obj_t self_in);
|
||||
bool uart_rx_any(pyb_uart_obj_t *uart_obj);
|
||||
int uart_rx_char(pyb_uart_obj_t *uart_obj);
|
||||
bool uart_tx_char(pyb_uart_obj_t *self, int c);
|
||||
bool uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len);
|
||||
void uart_tx_strn_cooked(pyb_uart_obj_t *uart_obj, const char *str, uint len);
|
||||
mp_obj_t uart_callback_new (pyb_uart_obj_t *self, mp_obj_t handler, uint rxbuffer_size, mp_int_t priority);
|
||||
void uart_disable_all (void);
|
||||
|
||||
#endif // PYBUART_H_
|
||||
|
||||
@@ -54,14 +54,16 @@
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
bool servers;
|
||||
bool servers_sleeping;
|
||||
bool simplelink;
|
||||
bool running;
|
||||
}pybwdt_data_t;
|
||||
} pybwdt_data_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
static pybwdt_data_t pybwdt_data;
|
||||
STATIC pybwdt_data_t pybwdt_data = {.servers = false, .servers_sleeping = false, .simplelink = false, .running = false};
|
||||
STATIC const mp_obj_base_t pyb_wdt_obj = {&pyb_wdt_type};
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
@@ -69,22 +71,16 @@ static pybwdt_data_t pybwdt_data;
|
||||
// must be called in main.c just after initializing the hal
|
||||
__attribute__ ((section (".boot")))
|
||||
void pybwdt_init0 (void) {
|
||||
pybwdt_data.running = false;
|
||||
}
|
||||
|
||||
void pybwdt_kick (void) {
|
||||
// check that the servers and simplelink are running fine
|
||||
if (pybwdt_data.servers && pybwdt_data.simplelink && pybwdt_data.running) {
|
||||
pybwdt_data.servers = false;
|
||||
pybwdt_data.simplelink = false;
|
||||
MAP_WatchdogIntClear(WDT_BASE);
|
||||
}
|
||||
}
|
||||
|
||||
void pybwdt_srv_alive (void) {
|
||||
pybwdt_data.servers = true;
|
||||
}
|
||||
|
||||
void pybwdt_srv_sleeping (bool state) {
|
||||
pybwdt_data.servers_sleeping = state;
|
||||
}
|
||||
|
||||
void pybwdt_sl_alive (void) {
|
||||
pybwdt_data.simplelink = true;
|
||||
}
|
||||
@@ -92,58 +88,66 @@ void pybwdt_sl_alive (void) {
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
/// \function wdt_enable('msec')
|
||||
/// Enabled the watchdog timer with msec timeout value
|
||||
STATIC mp_obj_t pyb_enable_wdt(mp_obj_t self, mp_obj_t msec_in) {
|
||||
mp_int_t msec = mp_obj_get_int(msec_in);
|
||||
/// \function constructor('msec')
|
||||
/// Enables the watchdog timer with msec timeout value
|
||||
STATIC mp_obj_t pyb_wdt_make_new (mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
// check the arguments
|
||||
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||
|
||||
if (msec < PYBWDT_MIN_TIMEOUT_MS) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
if (pybwdt_data.running) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
if (n_args > 0) {
|
||||
mp_int_t msec = mp_obj_get_int(args[0]);
|
||||
if (msec < PYBWDT_MIN_TIMEOUT_MS) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, mpexception_value_invalid_arguments));
|
||||
}
|
||||
if (pybwdt_data.running) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, mpexception_os_request_not_possible));
|
||||
}
|
||||
|
||||
// Enable the WDT peripheral clock
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_WDT, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
|
||||
// Unlock to be able to configure the registers
|
||||
MAP_WatchdogUnlock(WDT_BASE);
|
||||
|
||||
#ifdef DEBUG
|
||||
// make the WDT stall when the debugger stops on a breakpoint
|
||||
MAP_WatchdogStallEnable (WDT_BASE);
|
||||
#endif
|
||||
|
||||
// set the watchdog timer reload value
|
||||
// the WDT trigger a system reset after the second timeout
|
||||
// so, divide by 2 the timeout value received
|
||||
MAP_WatchdogReloadSet(WDT_BASE, PYBWDT_MILLISECONDS_TO_TICKS(msec / 2));
|
||||
|
||||
// start the timer. Once it's started, it cannot be disabled.
|
||||
MAP_WatchdogEnable(WDT_BASE);
|
||||
pybwdt_data.running = true;
|
||||
}
|
||||
|
||||
// Enable the WDT peripheral clock
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_WDT, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
|
||||
// Unlock to be able to configure the registers
|
||||
MAP_WatchdogUnlock(WDT_BASE);
|
||||
|
||||
// make the WDT stall when the debugger stops on a breakpoint
|
||||
MAP_WatchdogStallEnable (WDT_BASE);
|
||||
|
||||
// set the watchdog timer reload value
|
||||
// the WDT trigger a system reset after the second timeout
|
||||
// so, divide by the 2 timeout value received
|
||||
MAP_WatchdogReloadSet(WDT_BASE, PYBWDT_MILLISECONDS_TO_TICKS(msec / 2));
|
||||
|
||||
// start the timer. Once wdt is started, it cannot be disabled.
|
||||
MAP_WatchdogEnable(WDT_BASE);
|
||||
pybwdt_data.running = true;
|
||||
|
||||
return mp_const_none;
|
||||
return (mp_obj_t)&pyb_wdt_obj;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_enable_wdt_obj, pyb_enable_wdt);
|
||||
|
||||
/// \function wdt_kick()
|
||||
/// Kicks the watchdog timer
|
||||
STATIC mp_obj_t pyb_kick_wdt(mp_obj_t self) {
|
||||
pybwdt_kick ();
|
||||
if ((pybwdt_data.servers || pybwdt_data.servers_sleeping) && pybwdt_data.simplelink && pybwdt_data.running) {
|
||||
pybwdt_data.servers = false;
|
||||
pybwdt_data.simplelink = false;
|
||||
MAP_WatchdogIntClear(WDT_BASE);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_kick_wdt_obj, pyb_kick_wdt);
|
||||
|
||||
STATIC const mp_map_elem_t pybwdt_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&pyb_enable_wdt_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_kick), (mp_obj_t)&pyb_kick_wdt_obj },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(pybwdt_locals_dict, pybwdt_locals_dict_table);
|
||||
|
||||
static const mp_obj_type_t pybwdt_type = {
|
||||
const mp_obj_type_t pyb_wdt_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_WDT,
|
||||
.make_new = pyb_wdt_make_new,
|
||||
.locals_dict = (mp_obj_t)&pybwdt_locals_dict,
|
||||
};
|
||||
|
||||
const mp_obj_base_t pyb_wdt_obj = {&pybwdt_type};
|
||||
|
||||
@@ -29,11 +29,11 @@
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
extern const mp_obj_base_t pyb_wdt_obj;
|
||||
extern const mp_obj_type_t pyb_wdt_type;
|
||||
|
||||
void pybwdt_init0 (void);
|
||||
void pybwdt_kick (void);
|
||||
void pybwdt_srv_alive (void);
|
||||
void pybwdt_srv_sleeping (bool state);
|
||||
void pybwdt_sl_alive (void);
|
||||
|
||||
#endif /* PYBWDT_H_ */
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#define MICROPY_COMP_MODULE_CONST (1)
|
||||
#define MICROPY_ENABLE_GC (1)
|
||||
#define MICROPY_ENABLE_FINALISER (1)
|
||||
#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (0)
|
||||
#define MICROPY_STACK_CHECK (0)
|
||||
#define MICROPY_HELPER_REPL (1)
|
||||
#define MICROPY_ENABLE_SOURCE_LINE (1)
|
||||
@@ -47,6 +48,8 @@
|
||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
|
||||
#define MICROPY_OPT_COMPUTED_GOTO (0)
|
||||
#define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (0)
|
||||
#define MICROPY_CPYTHON_COMPAT (1)
|
||||
#define MICROPY_QSTR_BYTES_IN_HASH (1)
|
||||
|
||||
/* Enable FatFS LFNs
|
||||
0: Disable LFN feature.
|
||||
@@ -54,22 +57,28 @@
|
||||
2: Enable LFN with dynamic working buffer on the STACK.
|
||||
3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
*/
|
||||
#define MICROPY_ENABLE_LFN (0)
|
||||
#define MICROPY_LFN_CODE_PAGE (1)
|
||||
#define MICROPY_ENABLE_LFN (2)
|
||||
#define MICROPY_LFN_CODE_PAGE (437) // 1=SFN/ANSI 437=LFN/U.S.(OEM)
|
||||
#define MICROPY_STREAMS_NON_BLOCK (1)
|
||||
#define MICROPY_MODULE_WEAK_LINKS (0)
|
||||
#define MICROPY_CAN_OVERRIDE_BUILTINS (0)
|
||||
#define MICROPY_MODULE_WEAK_LINKS (1)
|
||||
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
|
||||
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
|
||||
#define MICROPY_PY_BUILTINS_STR_SPLITLINES (1)
|
||||
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
|
||||
#define MICROPY_PY_BUILTINS_FROZENSET (1)
|
||||
#define MICROPY_PY_BUILTINS_EXECFILE (1)
|
||||
#define MICROPY_PY_BUILTINS_TIMEOUTERROR (1)
|
||||
#define MICROPY_PY_MICROPYTHON_MEM_INFO (0)
|
||||
#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1)
|
||||
#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1)
|
||||
#define MICROPY_PY_SYS_MAXSIZE (1)
|
||||
#define MICROPY_PY_SYS_EXIT (1)
|
||||
#define MICROPY_PY_SYS_STDFILES (1)
|
||||
#define MICROPY_PY_CMATH (0)
|
||||
#define MICROPY_PY_IO (1)
|
||||
#define MICROPY_PY_IO_FILEIO (1)
|
||||
#define MICROPY_PY_UCTYPES (1)
|
||||
#define MICROPY_PY_UBINASCII (0)
|
||||
#define MICROPY_PY_UCTYPES (0)
|
||||
#define MICROPY_PY_UZLIB (0)
|
||||
#define MICROPY_PY_UJSON (1)
|
||||
#define MICROPY_PY_URE (1)
|
||||
@@ -98,17 +107,33 @@ extern const struct _mp_obj_module_t mp_module_utime;
|
||||
extern const struct _mp_obj_module_t mp_module_uselect;
|
||||
extern const struct _mp_obj_module_t mp_module_usocket;
|
||||
extern const struct _mp_obj_module_t mp_module_network;
|
||||
extern const struct _mp_obj_module_t mp_module_uhashlib;
|
||||
extern const struct _mp_obj_module_t mp_module_ubinascii;
|
||||
extern const struct _mp_obj_module_t mp_module_ussl;
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULES \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_pyb), (mp_obj_t)&pyb_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_os), (mp_obj_t)&mp_module_uos }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&mp_module_utime }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_select), (mp_obj_t)&mp_module_uselect }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&mp_module_usocket }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_network), (mp_obj_t)&mp_module_network }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_re), (mp_obj_t)&mp_module_ure }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_json), (mp_obj_t)&mp_module_ujson }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_heapq), (mp_obj_t)&mp_module_uheapq }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_pyb), (mp_obj_t)&pyb_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_uos), (mp_obj_t)&mp_module_uos }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_utime), (mp_obj_t)&mp_module_utime }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_uselect), (mp_obj_t)&mp_module_uselect }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_usocket), (mp_obj_t)&mp_module_usocket }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_network), (mp_obj_t)&mp_module_network }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_uhashlib), (mp_obj_t)&mp_module_uhashlib }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ubinascii), (mp_obj_t)&mp_module_ubinascii }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ussl), (mp_obj_t)&mp_module_ussl }, \
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&mp_module_ustruct }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_re), (mp_obj_t)&mp_module_ure }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_json), (mp_obj_t)&mp_module_ujson }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_heapq), (mp_obj_t)&mp_module_uheapq }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_os), (mp_obj_t)&mp_module_uos }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&mp_module_utime }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_select), (mp_obj_t)&mp_module_uselect }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&mp_module_usocket }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_hashlib), (mp_obj_t)&mp_module_uhashlib }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_binascii), (mp_obj_t)&mp_module_ubinascii }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ssl), (mp_obj_t)&mp_module_ussl }, \
|
||||
|
||||
// extra constants
|
||||
#define MICROPY_PORT_CONSTANTS \
|
||||
@@ -120,14 +145,15 @@ extern const struct _mp_obj_module_t mp_module_network;
|
||||
const char *readline_hist[8]; \
|
||||
mp_obj_t mp_const_user_interrupt; \
|
||||
mp_obj_t pyb_config_main; \
|
||||
mp_obj_list_t mod_network_nic_list; \
|
||||
mp_obj_list_t pybsleep_obj_list; \
|
||||
mp_obj_list_t mpcallback_obj_list; \
|
||||
mp_obj_list_t pyb_timer_channel_obj_list; \
|
||||
|
||||
|
||||
// type definitions for the specific machine
|
||||
#define BYTES_PER_WORD (4)
|
||||
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1))
|
||||
#define MP_SSIZE_MAX (0x7FFFFFFF)
|
||||
|
||||
#define UINT_FMT "%u"
|
||||
#define INT_FMT "%d"
|
||||
@@ -138,6 +164,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;
|
||||
|
||||
void mp_hal_stdout_tx_strn_cooked(const char *str, uint32_t len);
|
||||
#define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len)
|
||||
|
||||
#define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq()
|
||||
#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)
|
||||
|
||||
@@ -160,8 +189,14 @@ typedef long mp_off_t;
|
||||
#include "mpconfigboard.h"
|
||||
|
||||
#define MICROPY_HAL_H "cc3200_hal.h"
|
||||
#define MICROPY_PIN_DEFS_PORT_H "pin_defs_cc3200.h"
|
||||
#define MICROPY_PORT_HAS_TELNET (1)
|
||||
#define MICROPY_PORT_HAS_FTP (1)
|
||||
#define MICROPY_PORT_WLAN_URN (0)
|
||||
#define MICROPY_PY_SYS_PLATFORM "WiPy"
|
||||
|
||||
#define MICROPY_PORT_WLAN_AP_SSID "wipy-wlan"
|
||||
#define MICROPY_PORT_WLAN_AP_KEY "www.wipy.io"
|
||||
#define MICROPY_PORT_WLAN_AP_SECURITY SL_SEC_TYPE_WPA_WPA2
|
||||
#define MICROPY_PORT_WLAN_AP_CHANNEL 5
|
||||
|
||||
#endif // __INCLUDED_MPCONFIGPORT_H
|
||||
|
||||
150
cc3200/mptask.c
150
cc3200/mptask.c
@@ -26,7 +26,6 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <std.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
@@ -51,6 +50,7 @@
|
||||
#include "mperror.h"
|
||||
#include "simplelink.h"
|
||||
#include "modnetwork.h"
|
||||
#include "modusocket.h"
|
||||
#include "modwlan.h"
|
||||
#include "serverstask.h"
|
||||
#include "telnet.h"
|
||||
@@ -64,7 +64,10 @@
|
||||
#include "pybsd.h"
|
||||
#include "pins.h"
|
||||
#include "pybsleep.h"
|
||||
#include "pybtimer.h"
|
||||
#include "mpcallback.h"
|
||||
#include "cryptohash.h"
|
||||
#include "updater.h"
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE CONSTANTS
|
||||
@@ -102,11 +105,14 @@ void TASK_Micropython (void *pvParameters) {
|
||||
// initialize the garbage collector with the top of our stack
|
||||
uint32_t sp = gc_helper_get_sp();
|
||||
gc_collect_init (sp);
|
||||
bool safeboot = false;
|
||||
FRESULT res;
|
||||
|
||||
bool safeboot = false;
|
||||
mptask_pre_init();
|
||||
|
||||
#ifndef DEBUG
|
||||
safeboot = PRCMGetSpecialBit(PRCM_SAFE_BOOT_BIT);
|
||||
#endif
|
||||
|
||||
soft_reset:
|
||||
|
||||
// GC init
|
||||
@@ -125,20 +131,18 @@ soft_reset:
|
||||
mperror_init0();
|
||||
uart_init0();
|
||||
pin_init0();
|
||||
timer_init0();
|
||||
readline_init0();
|
||||
mod_network_init0();
|
||||
wlan_init0();
|
||||
#if MICROPY_HW_ENABLE_RNG
|
||||
rng_init0();
|
||||
#endif
|
||||
|
||||
// we are alive, so let the world know it
|
||||
mperror_enable_heartbeat();
|
||||
|
||||
#ifdef LAUNCHXL
|
||||
// configure the stdio uart pins with the correct alternate functions
|
||||
// param 3 ("mode") is DON'T CARE" for AFs others than GPIO
|
||||
pin_config ((pin_obj_t *)&pin_GPIO1, PIN_MODE_3, 0, PIN_TYPE_STD, PIN_STRENGTH_2MA);
|
||||
pin_config ((pin_obj_t *)&pin_GPIO2, PIN_MODE_3, 0, PIN_TYPE_STD, PIN_STRENGTH_2MA);
|
||||
pin_config ((pin_obj_t *)&MICROPY_STDIO_UART_TX_PIN, MICROPY_STDIO_UART_TX_PIN_AF, 0, PIN_TYPE_STD_PU, PIN_STRENGTH_2MA);
|
||||
pin_config ((pin_obj_t *)&MICROPY_STDIO_UART_RX_PIN, MICROPY_STDIO_UART_RX_PIN_AF, 0, PIN_TYPE_STD_PU, PIN_STRENGTH_2MA);
|
||||
// instantiate the stdio uart
|
||||
mp_obj_t args[2] = {
|
||||
mp_obj_new_int(MICROPY_STDIO_UART),
|
||||
@@ -147,6 +151,9 @@ soft_reset:
|
||||
pyb_stdio_uart = pyb_uart_type.make_new((mp_obj_t)&pyb_uart_type, MP_ARRAY_SIZE(args), 0, args);
|
||||
// create a callback for the uart, in order to enable the rx interrupts
|
||||
uart_callback_new (pyb_stdio_uart, mp_const_none, MICROPY_STDIO_UART_RX_BUF_SIZE, INT_PRIORITY_LVL_3);
|
||||
#else
|
||||
pyb_stdio_uart = MP_OBJ_NULL;
|
||||
#endif
|
||||
|
||||
pybsleep_reset_cause_t rstcause = pybsleep_get_reset_cause();
|
||||
if (rstcause < PYB_SLP_SOFT_RESET) {
|
||||
@@ -158,9 +165,6 @@ soft_reset:
|
||||
else {
|
||||
// only if not comming out of hibernate or a soft reset
|
||||
mptask_enter_ap_mode();
|
||||
#ifndef DEBUG
|
||||
safeboot = PRCMIsSafeBootRequested();
|
||||
#endif
|
||||
}
|
||||
|
||||
// enable telnet and ftp
|
||||
@@ -170,26 +174,22 @@ soft_reset:
|
||||
// initialize the serial flash file system
|
||||
mptask_init_sflash_filesystem();
|
||||
|
||||
// append the SFLASH paths to the system path
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SFLASH));
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SFLASH_slash_LIB));
|
||||
// append the flash paths to the system path
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash));
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_flash_slash_lib));
|
||||
|
||||
// reset config variables; they should be set by boot.py
|
||||
MP_STATE_PORT(pyb_config_main) = MP_OBJ_NULL;
|
||||
|
||||
if (!safeboot) {
|
||||
// run boot.py, if it exists
|
||||
const char *boot_py = "BOOT.PY";
|
||||
res = f_stat(boot_py, NULL);
|
||||
if (res == FR_OK) {
|
||||
int ret = pyexec_file(boot_py);
|
||||
if (ret & PYEXEC_FORCED_EXIT) {
|
||||
goto soft_reset_exit;
|
||||
}
|
||||
if (!ret) {
|
||||
// flash the system led
|
||||
mperror_signal_error();
|
||||
}
|
||||
// run boot.py
|
||||
int ret = pyexec_file("boot.py");
|
||||
if (ret & PYEXEC_FORCED_EXIT) {
|
||||
goto soft_reset_exit;
|
||||
}
|
||||
if (!ret) {
|
||||
// flash the system led
|
||||
mperror_signal_error();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,20 +204,17 @@ soft_reset:
|
||||
if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) {
|
||||
const char *main_py;
|
||||
if (MP_STATE_PORT(pyb_config_main) == MP_OBJ_NULL) {
|
||||
main_py = "MAIN.PY";
|
||||
main_py = "main.py";
|
||||
} else {
|
||||
main_py = mp_obj_str_get_str(MP_STATE_PORT(pyb_config_main));
|
||||
}
|
||||
res = f_stat(main_py, NULL);
|
||||
if (res == FR_OK) {
|
||||
int ret = pyexec_file(main_py);
|
||||
if (ret & PYEXEC_FORCED_EXIT) {
|
||||
goto soft_reset_exit;
|
||||
}
|
||||
if (!ret) {
|
||||
// flash the system led
|
||||
mperror_signal_error();
|
||||
}
|
||||
int ret = pyexec_file(main_py);
|
||||
if (ret & PYEXEC_FORCED_EXIT) {
|
||||
goto soft_reset_exit;
|
||||
}
|
||||
if (!ret) {
|
||||
// flash the system led
|
||||
mperror_signal_error();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -240,15 +237,26 @@ soft_reset_exit:
|
||||
|
||||
// soft reset
|
||||
pybsleep_signal_soft_reset();
|
||||
mp_printf(&mp_plat_print, "PYB: soft reboot\n");
|
||||
|
||||
printf("WiPy: soft reset\n");
|
||||
// disable all peripherals that could trigger a callback
|
||||
pyb_rtc_callback_disable(NULL);
|
||||
timer_disable_all();
|
||||
uart_disable_all();
|
||||
|
||||
// flush the serial flash buffer
|
||||
sflash_disk_flush();
|
||||
|
||||
// clean-up the user socket space
|
||||
modusocket_close_all_user_sockets();
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
pybsd_deinit();
|
||||
#endif
|
||||
|
||||
// wait for pending transactions to complete
|
||||
HAL_Delay(20);
|
||||
|
||||
goto soft_reset;
|
||||
}
|
||||
|
||||
@@ -270,10 +278,21 @@ STATIC void mptask_pre_init (void) {
|
||||
// this one allocates memory for the nvic vault
|
||||
pybsleep_pre_init();
|
||||
|
||||
// this one allocates memory for the WLAN semaphore
|
||||
wlan_pre_init();
|
||||
|
||||
// this one allocates memory for the updater semaphore
|
||||
updater_pre_init();
|
||||
|
||||
// this one allocates memory for the Socket semaphore
|
||||
modusocket_pre_init();
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
pybsd_init0();
|
||||
#endif
|
||||
|
||||
CRYPTOHASH_Init();
|
||||
|
||||
#ifdef DEBUG
|
||||
ASSERT (OSI_OK == osi_TaskCreate(TASK_Servers,
|
||||
(const signed char *)"Servers",
|
||||
@@ -286,38 +305,54 @@ STATIC void mptask_pre_init (void) {
|
||||
}
|
||||
|
||||
STATIC void mptask_init_sflash_filesystem (void) {
|
||||
FILINFO fno;
|
||||
#if _USE_LFN
|
||||
fno.lfname = NULL;
|
||||
fno.lfsize = 0;
|
||||
#endif
|
||||
|
||||
// Initialise the local flash filesystem.
|
||||
// Create it if needed, and mount in on /sflash.
|
||||
// try to mount the flash
|
||||
FRESULT res = f_mount(sflash_fatfs, "/SFLASH", 1);
|
||||
// Create it if needed, and mount in on /flash.
|
||||
FRESULT res = f_mount(sflash_fatfs, "/flash", 1);
|
||||
if (res == FR_NO_FILESYSTEM) {
|
||||
// no filesystem, so create a fresh one
|
||||
res = f_mkfs("/SFLASH", 1, 0);
|
||||
res = f_mkfs("/flash", 1, 0);
|
||||
if (res == FR_OK) {
|
||||
// success creating fresh LFS
|
||||
} else {
|
||||
__fatal_error("failed to create /SFLASH");
|
||||
__fatal_error("failed to create /flash");
|
||||
}
|
||||
// create empty main.py
|
||||
mptask_create_main_py();
|
||||
} else if (res == FR_OK) {
|
||||
// mount sucessful
|
||||
FILINFO fno;
|
||||
if (FR_OK != f_stat("/SFLASH/MAIN.PY", &fno)) {
|
||||
if (FR_OK != f_stat("/flash/main.py", &fno)) {
|
||||
// create empty main.py
|
||||
mptask_create_main_py();
|
||||
}
|
||||
} else {
|
||||
__fatal_error("failed to create /SFLASH");
|
||||
__fatal_error("failed to create /flash");
|
||||
}
|
||||
|
||||
// The current directory is used as the boot up directory.
|
||||
// It is set to the internal flash filesystem by default.
|
||||
f_chdrive("/SFLASH");
|
||||
f_chdrive("/flash");
|
||||
|
||||
// Make sure we have a /flash/boot.py. Create it if needed.
|
||||
FILINFO fno;
|
||||
res = f_stat("/SFLASH/BOOT.PY", &fno);
|
||||
// create /flash/sys, /flash/lib and /flash/cert if they don't exist
|
||||
if (FR_OK != f_chdir ("/flash/sys")) {
|
||||
f_mkdir("/flash/sys");
|
||||
}
|
||||
if (FR_OK != f_chdir ("/flash/lib")) {
|
||||
f_mkdir("/flash/lib");
|
||||
}
|
||||
if (FR_OK != f_chdir ("/flash/cert")) {
|
||||
f_mkdir("/flash/cert");
|
||||
}
|
||||
|
||||
f_chdir ("/flash");
|
||||
|
||||
// make sure we have a /flash/boot.py. Create it if needed.
|
||||
res = f_stat("/flash/boot.py", &fno);
|
||||
if (res == FR_OK) {
|
||||
if (fno.fattrib & AM_DIR) {
|
||||
// exists as a directory
|
||||
@@ -329,7 +364,7 @@ STATIC void mptask_init_sflash_filesystem (void) {
|
||||
} else {
|
||||
// doesn't exist, create fresh file
|
||||
FIL fp;
|
||||
f_open(&fp, "/SFLASH/BOOT.PY", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
f_open(&fp, "/flash/boot.py", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
UINT n;
|
||||
f_write(&fp, fresh_boot_py, sizeof(fresh_boot_py) - 1 /* don't count null terminator */, &n);
|
||||
// TODO check we could write n bytes
|
||||
@@ -338,15 +373,18 @@ STATIC void mptask_init_sflash_filesystem (void) {
|
||||
}
|
||||
|
||||
STATIC void mptask_enter_ap_mode (void) {
|
||||
// Enable simplelink in low power mode
|
||||
wlan_sl_enable (ROLE_AP, SERVERS_DEF_AP_SSID, strlen(SERVERS_DEF_AP_SSID), SERVERS_DEF_AP_SECURITY,
|
||||
SERVERS_DEF_AP_KEY, strlen(SERVERS_DEF_AP_KEY), SERVERS_DEF_AP_CHANNEL);
|
||||
// append the mac only if it's not the first boot
|
||||
bool append_mac = !PRCMGetSpecialBit(PRCM_FIRST_BOOT_BIT);
|
||||
|
||||
// enable simplelink in ap mode (use the MAC address to make the ssid unique)
|
||||
wlan_sl_enable (ROLE_AP, MICROPY_PORT_WLAN_AP_SSID, strlen(MICROPY_PORT_WLAN_AP_SSID), MICROPY_PORT_WLAN_AP_SECURITY,
|
||||
MICROPY_PORT_WLAN_AP_KEY, strlen(MICROPY_PORT_WLAN_AP_KEY), MICROPY_PORT_WLAN_AP_CHANNEL, append_mac);
|
||||
}
|
||||
|
||||
STATIC void mptask_create_main_py (void) {
|
||||
// create empty main.py
|
||||
FIL fp;
|
||||
f_open(&fp, "/SFLASH/MAIN.PY", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
f_open(&fp, "/flash/main.py", FA_WRITE | FA_CREATE_ALWAYS);
|
||||
UINT n;
|
||||
f_write(&fp, fresh_main_py, sizeof(fresh_main_py) - 1 /* don't count null terminator */, &n);
|
||||
f_close(&fp);
|
||||
|
||||
@@ -1,3 +1,30 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// qstrs specific to this port
|
||||
Q(__name__)
|
||||
Q(help)
|
||||
@@ -21,6 +48,7 @@ Q(readline)
|
||||
Q(input)
|
||||
Q(os)
|
||||
Q(freq)
|
||||
Q(unique_id)
|
||||
Q(repl_info)
|
||||
Q(disable_irq)
|
||||
Q(enable_irq)
|
||||
@@ -31,36 +59,50 @@ Q(elapsed_micros)
|
||||
Q(udelay)
|
||||
Q(flush)
|
||||
Q(FileIO)
|
||||
Q(mkdisk)
|
||||
Q(enable)
|
||||
Q(disable)
|
||||
// Entries for sys.path
|
||||
Q(/SFLASH)
|
||||
Q(/SFLASH/LIB)
|
||||
Q(/SD)
|
||||
Q(/SD/LIB)
|
||||
Q(/flash)
|
||||
Q(/flash/lib)
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
Q(/sd)
|
||||
Q(/sd/lib)
|
||||
#endif
|
||||
|
||||
// for module weak links
|
||||
Q(struct)
|
||||
Q(binascii)
|
||||
Q(re)
|
||||
Q(json)
|
||||
Q(heapq)
|
||||
Q(hashlib)
|
||||
|
||||
// for os module
|
||||
Q(uos)
|
||||
Q(os)
|
||||
Q(sysname)
|
||||
Q(nodename)
|
||||
Q(release)
|
||||
Q(version)
|
||||
Q(machine)
|
||||
Q(uname)
|
||||
Q(/)
|
||||
Q(SFLASH)
|
||||
Q(SD)
|
||||
Q(flash)
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
Q(sd)
|
||||
#endif
|
||||
Q(chdir)
|
||||
Q(getcwd)
|
||||
Q(listdir)
|
||||
Q(mkdir)
|
||||
Q(rename)
|
||||
Q(remove)
|
||||
Q(rmdir)
|
||||
Q(unlink)
|
||||
Q(sep)
|
||||
Q(stat)
|
||||
Q(urandom)
|
||||
Q(mkfs)
|
||||
|
||||
// for file class
|
||||
Q(seek)
|
||||
@@ -68,23 +110,18 @@ Q(tell)
|
||||
|
||||
// for Pin class
|
||||
Q(Pin)
|
||||
Q(cpu)
|
||||
Q(init)
|
||||
Q(value)
|
||||
Q(low)
|
||||
Q(high)
|
||||
Q(toggle)
|
||||
Q(info)
|
||||
Q(name)
|
||||
Q(port)
|
||||
Q(pin)
|
||||
Q(cpu)
|
||||
Q(mode)
|
||||
Q(pull)
|
||||
Q(index)
|
||||
Q(strength)
|
||||
Q(af)
|
||||
Q(intenable)
|
||||
Q(intdisable)
|
||||
Q(intmode)
|
||||
Q(swint)
|
||||
Q(mode)
|
||||
Q(type)
|
||||
Q(strength)
|
||||
Q(IN)
|
||||
Q(OUT)
|
||||
Q(STD)
|
||||
@@ -113,21 +150,23 @@ Q(deinit)
|
||||
Q(all)
|
||||
Q(writechar)
|
||||
Q(readchar)
|
||||
Q(sendbreak)
|
||||
Q(readinto)
|
||||
Q(read_buf_len)
|
||||
Q(timeout)
|
||||
Q(timeout_char)
|
||||
Q(repl_uart)
|
||||
Q(flow)
|
||||
Q(FLOW_NONE)
|
||||
Q(FLOW_TX)
|
||||
Q(FLOW_RX)
|
||||
Q(FLOW_TXRX)
|
||||
Q(RTS)
|
||||
Q(CTS)
|
||||
|
||||
// for I2C class
|
||||
Q(I2C)
|
||||
Q(mode)
|
||||
Q(baudrate)
|
||||
Q(addr)
|
||||
Q(data)
|
||||
Q(timeout)
|
||||
Q(memaddr)
|
||||
Q(addr_size)
|
||||
Q(init)
|
||||
@@ -138,15 +177,20 @@ Q(send)
|
||||
Q(recv)
|
||||
Q(mem_read)
|
||||
Q(mem_write)
|
||||
Q(MASTER)
|
||||
|
||||
// for ADC class
|
||||
Q(ADC)
|
||||
Q(read)
|
||||
Q(init)
|
||||
Q(deinit)
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
// for SD class
|
||||
Q(SD)
|
||||
Q(enable)
|
||||
Q(disable)
|
||||
#endif
|
||||
|
||||
// for RTC class
|
||||
Q(RTC)
|
||||
@@ -174,6 +218,7 @@ Q(getaddrinfo)
|
||||
Q(family)
|
||||
Q(type)
|
||||
Q(send)
|
||||
Q(sendall)
|
||||
Q(sendto)
|
||||
Q(recv)
|
||||
Q(recvfrom)
|
||||
@@ -184,26 +229,44 @@ Q(settimeout)
|
||||
Q(setblocking)
|
||||
Q(setsockopt)
|
||||
Q(close)
|
||||
Q(makefile)
|
||||
Q(protocol)
|
||||
Q(error)
|
||||
Q(timeout)
|
||||
Q(AF_INET)
|
||||
Q(AF_INET6)
|
||||
Q(SOCK_STREAM)
|
||||
Q(SOCK_DGRAM)
|
||||
Q(SOCK_RAW)
|
||||
Q(IPPROTO_SEC)
|
||||
Q(IPPROTO_TCP)
|
||||
Q(IPPROTO_UDP)
|
||||
Q(IPPROTO_RAW)
|
||||
|
||||
// for ssl class
|
||||
Q(ssl)
|
||||
Q(ussl)
|
||||
Q(wrap_socket)
|
||||
Q(sock)
|
||||
Q(keyfile)
|
||||
Q(certfile)
|
||||
Q(server_side)
|
||||
Q(cert_reqs)
|
||||
Q(ca_certs)
|
||||
Q(SSLError)
|
||||
Q(CERT_NONE)
|
||||
Q(CERT_OPTIONAL)
|
||||
Q(CERT_REQUIRED)
|
||||
|
||||
// for network class
|
||||
Q(network)
|
||||
Q(route)
|
||||
Q(start_server)
|
||||
Q(stop_server)
|
||||
Q(server_enabled)
|
||||
Q(server_running)
|
||||
Q(server_login)
|
||||
Q(server_timeout)
|
||||
|
||||
// for WLAN class
|
||||
Q(WLAN)
|
||||
Q(iwconfig)
|
||||
Q(key)
|
||||
Q(security)
|
||||
Q(ssid)
|
||||
@@ -213,21 +276,31 @@ Q(connect)
|
||||
Q(isconnected)
|
||||
Q(disconnect)
|
||||
Q(channel)
|
||||
Q(rssi)
|
||||
Q(ifconfig)
|
||||
Q(info)
|
||||
Q(connections)
|
||||
#if MICROPY_PORT_WLAN_URN
|
||||
Q(urn)
|
||||
#endif
|
||||
Q(mode)
|
||||
Q(ip)
|
||||
Q(subnet)
|
||||
Q(gateway)
|
||||
Q(dns)
|
||||
Q(mac)
|
||||
Q(antenna)
|
||||
Q(STA)
|
||||
Q(AP)
|
||||
Q(P2P)
|
||||
Q(OPEN)
|
||||
Q(WEP)
|
||||
Q(WPA_WPA2)
|
||||
Q(WPA_ENT)
|
||||
Q(WPS_PBC)
|
||||
Q(WPS_PIN)
|
||||
Q(WPA)
|
||||
Q(WPA2)
|
||||
Q(INTERNAL)
|
||||
Q(EXTERNAL)
|
||||
|
||||
// for WDT class
|
||||
Q(WDT)
|
||||
Q(enable)
|
||||
Q(kick)
|
||||
|
||||
// for HeartBeat class
|
||||
@@ -241,7 +314,7 @@ Q(enable)
|
||||
Q(disable)
|
||||
Q(callback)
|
||||
Q(handler)
|
||||
Q(intmode)
|
||||
Q(mode)
|
||||
Q(value)
|
||||
Q(priority)
|
||||
Q(wakes)
|
||||
@@ -256,7 +329,7 @@ Q(wake_reason)
|
||||
Q(ACTIVE)
|
||||
Q(SUSPENDED)
|
||||
Q(HIBERNATING)
|
||||
Q(PWR_ON_RESET)
|
||||
Q(POWER_ON)
|
||||
Q(HARD_RESET)
|
||||
Q(WDT_RESET)
|
||||
Q(HIB_RESET)
|
||||
@@ -267,15 +340,59 @@ Q(RTC_WAKE)
|
||||
|
||||
// for SPI class
|
||||
Q(SPI)
|
||||
Q(mode)
|
||||
Q(baudrate)
|
||||
Q(bits)
|
||||
Q(submode)
|
||||
Q(cs)
|
||||
Q(polarity)
|
||||
Q(phase)
|
||||
Q(nss)
|
||||
Q(init)
|
||||
Q(deinit)
|
||||
Q(send)
|
||||
Q(recv)
|
||||
Q(send_recv)
|
||||
Q(timeout)
|
||||
Q(MASTER)
|
||||
Q(ACTIVE_LOW)
|
||||
Q(ACTIVE_HIGH)
|
||||
|
||||
// for Timer class
|
||||
Q(Timer)
|
||||
Q(TimerChannel)
|
||||
Q(init)
|
||||
Q(deinit)
|
||||
Q(freq)
|
||||
Q(period)
|
||||
Q(mode)
|
||||
Q(width)
|
||||
Q(channel)
|
||||
Q(polarity)
|
||||
Q(duty_cycle)
|
||||
Q(time)
|
||||
Q(event_count)
|
||||
Q(event_time)
|
||||
Q(A)
|
||||
Q(B)
|
||||
Q(ONE_SHOT)
|
||||
Q(PERIODIC)
|
||||
Q(EDGE_COUNT)
|
||||
Q(EDGE_TIME)
|
||||
Q(PWM)
|
||||
Q(POSITIVE)
|
||||
Q(NEGATIVE)
|
||||
|
||||
// for uhashlib module
|
||||
Q(uhashlib)
|
||||
Q(update)
|
||||
Q(digest)
|
||||
//Q(md5)
|
||||
Q(sha1)
|
||||
Q(sha256)
|
||||
|
||||
// for ubinascii module
|
||||
Q(ubinascii)
|
||||
Q(hexlify)
|
||||
Q(unhexlify)
|
||||
Q(a2b_base64)
|
||||
Q(b2a_base64)
|
||||
|
||||
|
||||
@@ -25,41 +25,46 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <std.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/misc.h"
|
||||
#include "simplelink.h"
|
||||
#include "serverstask.h"
|
||||
#include "modwlan.h"
|
||||
#include "simplelink.h"
|
||||
#include "debug.h"
|
||||
#include "mpexception.h"
|
||||
#include "telnet.h"
|
||||
#include "ftp.h"
|
||||
#include "pybwdt.h"
|
||||
#include "modusocket.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DEFINITIONS
|
||||
******************************************************************************/
|
||||
|
||||
#define SERVERS_DEF_USER "micro"
|
||||
#define SERVERS_DEF_PASS "python"
|
||||
#define SERVERS_DEF_USER "micro"
|
||||
#define SERVERS_DEF_PASS "python"
|
||||
#define SERVERS_DEF_TIMEOUT_MS 300000 // 5 minutes
|
||||
#define SERVERS_MIN_TIMEOUT_MS 5000 // 5 seconds
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE TYPES
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
volatile bool enabled;
|
||||
volatile bool do_disable;
|
||||
volatile bool do_enable;
|
||||
}servers_Data_t;
|
||||
uint32_t timeout;
|
||||
bool enabled;
|
||||
bool do_disable;
|
||||
bool do_enable;
|
||||
bool do_reset;
|
||||
} servers_data_t;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE DATA
|
||||
******************************************************************************/
|
||||
static servers_Data_t servers_data = {.enabled = false, .do_disable = false, .do_enable = false};
|
||||
static servers_data_t servers_data = {.timeout = SERVERS_DEF_TIMEOUT_MS, .enabled = false, .do_disable = false,
|
||||
.do_enable = false, .do_reset = false};
|
||||
static volatile bool sleep_sockets = false;
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PRIVATE FUNCTIONS
|
||||
@@ -68,8 +73,8 @@ static servers_Data_t servers_data = {.enabled = false, .do_disable = false, .do
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC DATA
|
||||
******************************************************************************/
|
||||
char *servers_user;
|
||||
char *servers_pass;
|
||||
char servers_user[SERVERS_USER_PASS_LEN_MAX + 1];
|
||||
char servers_pass[SERVERS_USER_PASS_LEN_MAX + 1];
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
@@ -78,8 +83,6 @@ void TASK_Servers (void *pvParameters) {
|
||||
|
||||
bool cycle = false;
|
||||
|
||||
ASSERT ((servers_user = mem_Malloc(SERVERS_USER_LEN_MAX + 1)) != NULL);
|
||||
ASSERT ((servers_pass = mem_Malloc(SERVERS_PASS_LEN_MAX + 1)) != NULL);
|
||||
strcpy (servers_user, SERVERS_DEF_USER);
|
||||
strcpy (servers_pass, SERVERS_DEF_PASS);
|
||||
|
||||
@@ -88,25 +91,7 @@ void TASK_Servers (void *pvParameters) {
|
||||
|
||||
for ( ;; ) {
|
||||
|
||||
if (servers_data.enabled) {
|
||||
if (servers_data.do_disable) {
|
||||
// disable network services
|
||||
telnet_disable();
|
||||
ftp_disable();
|
||||
// now clear the flags
|
||||
servers_data.do_disable = false;
|
||||
servers_data.enabled = false;
|
||||
}
|
||||
else {
|
||||
if (cycle) {
|
||||
telnet_run();
|
||||
}
|
||||
else {
|
||||
ftp_run();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (servers_data.do_enable) {
|
||||
if (servers_data.do_enable) {
|
||||
// enable network services
|
||||
telnet_enable();
|
||||
ftp_enable();
|
||||
@@ -114,42 +99,98 @@ void TASK_Servers (void *pvParameters) {
|
||||
servers_data.enabled = true;
|
||||
servers_data.do_enable = false;
|
||||
}
|
||||
else if (servers_data.do_disable) {
|
||||
// disable network services
|
||||
telnet_disable();
|
||||
ftp_disable();
|
||||
// now clear the flags
|
||||
servers_data.do_disable = false;
|
||||
servers_data.enabled = false;
|
||||
}
|
||||
else if (servers_data.do_reset) {
|
||||
// resetting the servers is needed to prevent half-open sockets
|
||||
servers_data.do_reset = false;
|
||||
if (servers_data.enabled) {
|
||||
telnet_reset();
|
||||
ftp_reset();
|
||||
}
|
||||
// and we should also close all user sockets. We do it here
|
||||
// for convinience and to save on code size.
|
||||
modusocket_close_all_user_sockets();
|
||||
}
|
||||
|
||||
if (cycle) {
|
||||
telnet_run();
|
||||
}
|
||||
else {
|
||||
ftp_run();
|
||||
}
|
||||
|
||||
if (sleep_sockets) {
|
||||
sleep_sockets = false;
|
||||
pybwdt_srv_sleeping(true);
|
||||
modusocket_enter_sleep();
|
||||
pybwdt_srv_sleeping(false);
|
||||
}
|
||||
|
||||
// set the alive flag for the wdt
|
||||
pybwdt_srv_alive();
|
||||
|
||||
// move to the next cycle
|
||||
cycle = cycle ? false : true;
|
||||
HAL_Delay(SERVERS_CYCLE_TIME_MS);
|
||||
// set the alive flag for the wdt
|
||||
pybwdt_srv_alive();
|
||||
}
|
||||
}
|
||||
|
||||
void servers_start (void) {
|
||||
servers_data.do_disable = false;
|
||||
servers_data.do_enable = true;
|
||||
HAL_Delay (SERVERS_CYCLE_TIME_MS * 5);
|
||||
}
|
||||
|
||||
void servers_stop (void) {
|
||||
servers_data.do_enable = false;
|
||||
servers_data.do_disable = true;
|
||||
do {
|
||||
HAL_Delay (SERVERS_CYCLE_TIME_MS);
|
||||
} while (servers_are_enabled());
|
||||
HAL_Delay (SERVERS_CYCLE_TIME_MS * 5);
|
||||
}
|
||||
|
||||
void servers_reset (void) {
|
||||
servers_data.do_reset = true;
|
||||
}
|
||||
|
||||
bool servers_are_enabled (void) {
|
||||
return servers_data.enabled;
|
||||
}
|
||||
|
||||
void server_sleep_sockets (void) {
|
||||
sleep_sockets = true;
|
||||
HAL_Delay (SERVERS_CYCLE_TIME_MS + 1);
|
||||
}
|
||||
|
||||
void servers_close_socket (int16_t *sd) {
|
||||
if (*sd > 0) {
|
||||
modusocket_socket_delete(*sd);
|
||||
sl_Close(*sd);
|
||||
*sd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void servers_set_login (char *user, char *pass) {
|
||||
memcpy(servers_user, user, SERVERS_USER_LEN_MAX);
|
||||
memcpy(servers_pass, pass, SERVERS_PASS_LEN_MAX);
|
||||
memcpy(servers_user, user, SERVERS_USER_PASS_LEN_MAX);
|
||||
memcpy(servers_pass, pass, SERVERS_USER_PASS_LEN_MAX);
|
||||
}
|
||||
|
||||
bool servers_set_timeout (uint32_t timeout) {
|
||||
if (timeout < SERVERS_MIN_TIMEOUT_MS) {
|
||||
return false;
|
||||
}
|
||||
servers_data.timeout = timeout;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t servers_get_timeout (void) {
|
||||
return servers_data.timeout;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
@@ -31,18 +31,12 @@
|
||||
DEFINE CONSTANTS
|
||||
******************************************************************************/
|
||||
#define SERVERS_PRIORITY 2
|
||||
#define SERVERS_STACK_SIZE 944
|
||||
#define SERVERS_STACK_SIZE 1072
|
||||
|
||||
#define SERVERS_SSID_LEN_MAX 16
|
||||
#define SERVERS_KEY_LEN_MAX 16
|
||||
|
||||
#define SERVERS_USER_LEN_MAX 16
|
||||
#define SERVERS_PASS_LEN_MAX 16
|
||||
|
||||
#define SERVERS_DEF_AP_SSID "micropy-wlan"
|
||||
#define SERVERS_DEF_AP_SECURITY SL_SEC_TYPE_WPA_WPA2
|
||||
#define SERVERS_DEF_AP_KEY "micropython"
|
||||
#define SERVERS_DEF_AP_CHANNEL 6
|
||||
#define SERVERS_USER_PASS_LEN_MAX 16
|
||||
|
||||
#define SERVERS_CYCLE_TIME_MS 5
|
||||
|
||||
@@ -53,8 +47,8 @@
|
||||
/******************************************************************************
|
||||
EXPORTED DATA
|
||||
******************************************************************************/
|
||||
extern char *servers_user;
|
||||
extern char *servers_pass;
|
||||
extern char servers_user[];
|
||||
extern char servers_pass[];
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
@@ -62,8 +56,12 @@ extern char *servers_pass;
|
||||
extern void TASK_Servers (void *pvParameters);
|
||||
extern void servers_start (void);
|
||||
extern void servers_stop (void);
|
||||
extern void servers_reset (void);
|
||||
extern bool servers_are_enabled (void);
|
||||
extern void servers_close_socket (int16_t *sd);
|
||||
extern void servers_set_login (char *user, char *pass);
|
||||
extern void server_sleep_sockets (void);
|
||||
extern bool servers_set_timeout (uint32_t timeout);
|
||||
extern uint32_t servers_get_timeout (void);
|
||||
|
||||
#endif /* SERVERSTASK_H_ */
|
||||
|
||||
@@ -25,18 +25,20 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <std.h>
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "py/obj.h"
|
||||
#include "telnet.h"
|
||||
#include "simplelink.h"
|
||||
#include "modnetwork.h"
|
||||
#include "modwlan.h"
|
||||
#include "modusocket.h"
|
||||
#include "debug.h"
|
||||
#include "mpexception.h"
|
||||
#include "serverstask.h"
|
||||
#include "genhdr/py-version.h"
|
||||
#include "genhdr/mpversion.h"
|
||||
#include "irq.h"
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PRIVATE CONSTANTS
|
||||
@@ -45,10 +47,9 @@
|
||||
// rxRindex and rxWindex must be uint8_t and TELNET_RX_BUFFER_SIZE == 256
|
||||
#define TELNET_RX_BUFFER_SIZE 256
|
||||
#define TELNET_MAX_CLIENTS 1
|
||||
#define TELNET_TX_RETRIES_MAX 25
|
||||
#define TELNET_TX_RETRIES_MAX 50
|
||||
#define TELNET_WAIT_TIME_MS 5
|
||||
#define TELNET_LOGIN_RETRIES_MAX 3
|
||||
#define TELNET_TIMEOUT_MS 300000 // 5 minutes
|
||||
#define TELNET_CYCLE_TIME_MS (SERVERS_CYCLE_TIME_MS * 2)
|
||||
|
||||
/******************************************************************************
|
||||
@@ -108,8 +109,8 @@ typedef struct {
|
||||
******************************************************************************/
|
||||
static telnet_data_t telnet_data;
|
||||
static const char* telnet_welcome_msg = "Micro Python " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE "; " MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME "\r\n";
|
||||
static const char* telnet_request_user = "Login as:";
|
||||
static const char* telnet_request_password = "Password:";
|
||||
static const char* telnet_request_user = "Login as: ";
|
||||
static const char* telnet_request_password = "Password: ";
|
||||
static const char* telnet_invalid_loggin = "\r\nInvalid credentials, try again.\r\n";
|
||||
static const char* telnet_loggin_success = "\r\nLogin succeeded!\r\nType \"help()\" for more information.\r\n";
|
||||
static const uint8_t telnet_options_user[] = // IAC WONT ECHO IAC WONT SUPPRESS_GO_AHEAD IAC WILL LINEMODE
|
||||
@@ -129,9 +130,9 @@ static void telnet_send_and_proceed (void *data, _i16 Len, telnet_connected_subs
|
||||
static telnet_result_t telnet_send_non_blocking (void *data, _i16 Len);
|
||||
static telnet_result_t telnet_recv_text_non_blocking (void *buff, _i16 Maxlen, _i16 *rxLen);
|
||||
static void telnet_process (void);
|
||||
static int telnet_process_credential (char *credential, _i16 rxLen);
|
||||
static void telnet_parse_input (uint8_t *str, int16_t *len);
|
||||
static bool telnet_send_with_retries (int16_t sd, const void *pBuf, int16_t len);
|
||||
static void telnet_reset (void);
|
||||
static void telnet_reset_buffer (void);
|
||||
|
||||
/******************************************************************************
|
||||
@@ -150,7 +151,7 @@ void telnet_run (void) {
|
||||
telnet_wait_for_enabled();
|
||||
break;
|
||||
case E_TELNET_STE_START:
|
||||
if (telnet_create_socket()) {
|
||||
if (wlan_is_connected() && telnet_create_socket()) {
|
||||
telnet_data.state = E_TELNET_STE_LISTEN;
|
||||
}
|
||||
break;
|
||||
@@ -171,12 +172,14 @@ void telnet_run (void) {
|
||||
telnet_send_and_proceed((void *)telnet_request_user, strlen(telnet_request_user), E_TELNET_STE_SUB_GET_USER);
|
||||
break;
|
||||
case E_TELNET_STE_SUB_GET_USER:
|
||||
if (E_TELNET_RESULT_OK == telnet_recv_text_non_blocking(telnet_data.rxBuffer, TELNET_RX_BUFFER_SIZE, &rxLen)) {
|
||||
// Skip /r/n
|
||||
if (rxLen < 2 || memcmp(servers_user, (const char *)telnet_data.rxBuffer, MAX((rxLen - 2), strlen(servers_user)))) {
|
||||
telnet_data.credentialsValid = false;
|
||||
if (E_TELNET_RESULT_OK == telnet_recv_text_non_blocking(telnet_data.rxBuffer + telnet_data.rxWindex,
|
||||
TELNET_RX_BUFFER_SIZE - telnet_data.rxWindex,
|
||||
&rxLen)) {
|
||||
int result;
|
||||
if ((result = telnet_process_credential (servers_user, rxLen))) {
|
||||
telnet_data.credentialsValid = result > 0 ? true : false;
|
||||
telnet_data.substate.connected = E_TELNET_STE_SUB_REQ_PASSWORD;
|
||||
}
|
||||
telnet_data.substate.connected = E_TELNET_STE_SUB_REQ_PASSWORD;
|
||||
}
|
||||
break;
|
||||
case E_TELNET_STE_SUB_REQ_PASSWORD:
|
||||
@@ -188,16 +191,17 @@ void telnet_run (void) {
|
||||
telnet_send_and_proceed((void *)telnet_options_pass, sizeof(telnet_options_pass), E_TELNET_STE_SUB_GET_PASSWORD);
|
||||
break;
|
||||
case E_TELNET_STE_SUB_GET_PASSWORD:
|
||||
if (E_TELNET_RESULT_OK == telnet_recv_text_non_blocking(telnet_data.rxBuffer, TELNET_RX_BUFFER_SIZE, &rxLen)) {
|
||||
// skip /r/n
|
||||
if (rxLen < 2 || memcmp(servers_pass, (const char *)telnet_data.rxBuffer, MAX((rxLen - 2), strlen(servers_pass)))) {
|
||||
telnet_data.credentialsValid = false;
|
||||
}
|
||||
if (telnet_data.credentialsValid) {
|
||||
telnet_data.substate.connected = E_TELNET_STE_SUB_SND_REPL_OPTIONS;
|
||||
}
|
||||
else {
|
||||
telnet_data.substate.connected = E_TELNET_STE_SUB_INVALID_LOGGIN;
|
||||
if (E_TELNET_RESULT_OK == telnet_recv_text_non_blocking(telnet_data.rxBuffer + telnet_data.rxWindex,
|
||||
TELNET_RX_BUFFER_SIZE - telnet_data.rxWindex,
|
||||
&rxLen)) {
|
||||
int result;
|
||||
if ((result = telnet_process_credential (servers_pass, rxLen))) {
|
||||
if ((telnet_data.credentialsValid = telnet_data.credentialsValid && (result > 0 ? true : false))) {
|
||||
telnet_data.substate.connected = E_TELNET_STE_SUB_SND_REPL_OPTIONS;
|
||||
}
|
||||
else {
|
||||
telnet_data.substate.connected = E_TELNET_STE_SUB_INVALID_LOGGIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -233,7 +237,7 @@ void telnet_run (void) {
|
||||
}
|
||||
|
||||
if (telnet_data.state >= E_TELNET_STE_CONNECTED) {
|
||||
if (telnet_data.timeout++ > (TELNET_TIMEOUT_MS / TELNET_CYCLE_TIME_MS)) {
|
||||
if (telnet_data.timeout++ > (servers_get_timeout() / TELNET_CYCLE_TIME_MS)) {
|
||||
telnet_reset();
|
||||
}
|
||||
}
|
||||
@@ -289,6 +293,13 @@ void telnet_disable (void) {
|
||||
telnet_data.state = E_TELNET_STE_DISABLED;
|
||||
}
|
||||
|
||||
void telnet_reset (void) {
|
||||
// close the connection and start all over again
|
||||
servers_close_socket(&telnet_data.n_sd);
|
||||
servers_close_socket(&telnet_data.sd);
|
||||
telnet_data.state = E_TELNET_STE_START;
|
||||
}
|
||||
|
||||
bool telnet_is_enabled (void) {
|
||||
return telnet_data.enabled;
|
||||
}
|
||||
@@ -319,21 +330,27 @@ static bool telnet_create_socket (void) {
|
||||
// Open a socket for telnet
|
||||
ASSERT ((telnet_data.sd = sl_Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) > 0);
|
||||
if (telnet_data.sd > 0) {
|
||||
// add the socket to the network administration
|
||||
modusocket_socket_add(telnet_data.sd, false);
|
||||
|
||||
// Enable non-blocking mode
|
||||
nonBlockingOption.NonblockingEnabled = 1;
|
||||
ASSERT (sl_SetSockOpt(telnet_data.sd, SOL_SOCKET, SL_SO_NONBLOCKING, &nonBlockingOption, sizeof(nonBlockingOption)) == SL_SOC_OK);
|
||||
ASSERT ((result = sl_SetSockOpt(telnet_data.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(TELNET_PORT);
|
||||
|
||||
ASSERT (sl_Bind(telnet_data.sd, (const SlSockAddr_t *)&sServerAddress, sizeof(sServerAddress)) == SL_SOC_OK);
|
||||
ASSERT ((result |= sl_Bind(telnet_data.sd, (const SlSockAddr_t *)&sServerAddress, sizeof(sServerAddress))) == SL_SOC_OK);
|
||||
|
||||
// Start listening
|
||||
ASSERT ((result = sl_Listen (telnet_data.sd, TELNET_MAX_CLIENTS)) == SL_SOC_OK);
|
||||
ASSERT ((result |= sl_Listen (telnet_data.sd, TELNET_MAX_CLIENTS)) == SL_SOC_OK);
|
||||
|
||||
return (result == SL_SOC_OK) ? true : false;
|
||||
if (result == SL_SOC_OK) {
|
||||
return true;
|
||||
}
|
||||
servers_close_socket(&telnet_data.sd);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -349,15 +366,18 @@ static void telnet_wait_for_connection (void) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// close the listening socket, we don't need it anymore
|
||||
sl_Close(telnet_data.sd);
|
||||
|
||||
if (telnet_data.n_sd <= 0) {
|
||||
// error
|
||||
telnet_reset();
|
||||
return;
|
||||
}
|
||||
|
||||
// close the listening socket, we don't need it anymore
|
||||
servers_close_socket(&telnet_data.sd);
|
||||
|
||||
// add the new socket to the network administration
|
||||
modusocket_socket_add(telnet_data.n_sd, false);
|
||||
|
||||
// client connected, so go on
|
||||
telnet_data.rxWindex = 0;
|
||||
telnet_data.rxRindex = 0;
|
||||
@@ -427,6 +447,26 @@ static void telnet_process (void) {
|
||||
}
|
||||
}
|
||||
|
||||
static int telnet_process_credential (char *credential, _i16 rxLen) {
|
||||
telnet_data.rxWindex += rxLen;
|
||||
if (telnet_data.rxWindex >= SERVERS_USER_PASS_LEN_MAX) {
|
||||
telnet_data.rxWindex = SERVERS_USER_PASS_LEN_MAX;
|
||||
}
|
||||
|
||||
uint8_t *p = telnet_data.rxBuffer + SERVERS_USER_PASS_LEN_MAX;
|
||||
// if a '\r' is found, or the length exceeds the max username length
|
||||
if ((p = memchr(telnet_data.rxBuffer, '\r', telnet_data.rxWindex)) || (telnet_data.rxWindex >= SERVERS_USER_PASS_LEN_MAX)) {
|
||||
uint8_t len = p - telnet_data.rxBuffer;
|
||||
|
||||
telnet_data.rxWindex = 0;
|
||||
if ((len > 0) && (memcmp(credential, telnet_data.rxBuffer, MAX(len, strlen(credential))) == 0)) {
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void telnet_parse_input (uint8_t *str, int16_t *len) {
|
||||
int16_t b_len = *len;
|
||||
uint8_t *b_str = str;
|
||||
@@ -444,16 +484,18 @@ static void telnet_parse_input (uint8_t *str, int16_t *len) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
_str += 3;
|
||||
*len -= 3;
|
||||
// in case we have received an incomplete telnet option, unlikely, but possible
|
||||
_str += MIN(3, *len);
|
||||
*len -= MIN(3, *len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool telnet_send_with_retries (int16_t sd, const void *pBuf, int16_t len) {
|
||||
int32_t retries = 0;
|
||||
// abort sending if we happen to be within interrupt context
|
||||
if ((HAL_NVIC_INT_CTRL_REG & HAL_VECTACTIVE_MASK) == 0) {
|
||||
uint32_t delay = TELNET_WAIT_TIME_MS;
|
||||
// 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) {
|
||||
do {
|
||||
_i16 result = sl_Send(sd, pBuf, len, 0);
|
||||
if (result > 0) {
|
||||
@@ -462,19 +504,13 @@ static bool telnet_send_with_retries (int16_t sd, const void *pBuf, int16_t len)
|
||||
else if (SL_EAGAIN != result) {
|
||||
return false;
|
||||
}
|
||||
HAL_Delay (TELNET_WAIT_TIME_MS);
|
||||
// start with the default delay and increment it on each retry
|
||||
HAL_Delay (delay++);
|
||||
} while (++retries <= TELNET_TX_RETRIES_MAX);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void telnet_reset (void) {
|
||||
// close the connection and start all over again
|
||||
servers_close_socket(&telnet_data.n_sd);
|
||||
servers_close_socket(&telnet_data.sd);
|
||||
telnet_data.state = E_TELNET_STE_START;
|
||||
}
|
||||
|
||||
static void telnet_reset_buffer (void) {
|
||||
// erase any characters present in the current line
|
||||
memset (telnet_data.rxBuffer, '\b', TELNET_RX_BUFFER_SIZE / 2);
|
||||
|
||||
@@ -38,6 +38,7 @@ extern bool telnet_rx_any (void);
|
||||
extern int telnet_rx_char (void);
|
||||
extern void telnet_enable (void);
|
||||
extern void telnet_disable (void);
|
||||
extern void telnet_reset (void);
|
||||
extern bool telnet_is_enabled (void);
|
||||
extern bool telnet_is_active (void);
|
||||
|
||||
|
||||
63
cc3200/tools/smoke.py
Normal file
63
cc3200/tools/smoke.py
Normal file
@@ -0,0 +1,63 @@
|
||||
import pyb
|
||||
import os
|
||||
|
||||
"""
|
||||
Execute it like this:
|
||||
|
||||
python3 run-tests --target wipy --device 192.168.1.1 ../cc3200/tools/smoke.py
|
||||
"""
|
||||
|
||||
pin_map = [2, 1, 23, 24, 11, 12, 13, 14, 15, 16, 17, 22, 28, 10, 9, 8, 7, 6, 30, 31, 3, 0, 4, 5]
|
||||
test_bytes = os.urandom(2048)
|
||||
|
||||
def test_pin_read (type):
|
||||
# enable the pull resistor on all pins, then read the value
|
||||
for p in pin_map:
|
||||
pin = pyb.Pin('GP' + str(p), af= 0, mode=pyb.Pin.IN, type=type)
|
||||
# read the pin value
|
||||
print (pin.value())
|
||||
|
||||
def test_pin_shorts (type):
|
||||
if type == pyb.Pin.STD_PU:
|
||||
type_inverted = pyb.Pin.STD_PD
|
||||
else:
|
||||
type_inverted = pyb.Pin.STD_PU
|
||||
# enable all pulls of the specified type
|
||||
for p in pin_map:
|
||||
pin = pyb.Pin('GP' + str(p), af= 0, mode=pyb.Pin.IN, type=type_inverted)
|
||||
# then change the pull one pin at a time and read its value
|
||||
i = 0
|
||||
while i < len(pin_map):
|
||||
pin = pyb.Pin('GP' + str(pin_map[i]), af= 0, mode=pyb.Pin.IN, type=type)
|
||||
pyb.Pin('GP' + str(pin_map[i - 1]), af= 0, mode=pyb.Pin.IN, type=type_inverted)
|
||||
i += 1
|
||||
# read the pin value
|
||||
print (pin.value())
|
||||
|
||||
test_pin_read(pyb.Pin.STD_PU)
|
||||
test_pin_read(pyb.Pin.STD_PD)
|
||||
test_pin_shorts(pyb.Pin.STD_PU)
|
||||
test_pin_shorts(pyb.Pin.STD_PD)
|
||||
|
||||
# create a test directory
|
||||
os.mkdir('/flash/test')
|
||||
os.chdir('/flash/test')
|
||||
print(os.getcwd())
|
||||
# create a new file
|
||||
f = open ('test.txt', 'w')
|
||||
n_w = f.write (test_bytes)
|
||||
print (n_w == len(test_bytes))
|
||||
f.close()
|
||||
f = open('test.txt', 'r')
|
||||
r = bytes(f.readall(), 'ascii')
|
||||
# check that we can write and read it correctly
|
||||
print (r == test_bytes)
|
||||
f.close()
|
||||
os.remove('test.txt')
|
||||
os.chdir('..')
|
||||
os.rmdir('test')
|
||||
|
||||
ls = os.listdir()
|
||||
print('test' not in ls)
|
||||
print(ls)
|
||||
|
||||
101
cc3200/tools/smoke.py.exp
Normal file
101
cc3200/tools/smoke.py.exp
Normal file
@@ -0,0 +1,101 @@
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
/flash
|
||||
True
|
||||
True
|
||||
True
|
||||
['main.py', 'sys', 'lib', 'cert', 'boot.py']
|
||||
56
cc3200/tools/uniflash.py
Normal file
56
cc3200/tools/uniflash.py
Normal file
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Flash the WiPy (format, update service pack and program).
|
||||
|
||||
Example:
|
||||
|
||||
> python uniflash.py -u "C:\ti\uniflash_3.2\uniflashCLI.bat" -c "C:\VirtualBoxShared\GitHub\wipy_uniflash.usf" -p 8 -s "C:\ti\CC31xx_CC32xx_ServicePack_1.0.0.10.0\servicepack_1.0.0.10.0.bin"
|
||||
|
||||
or:
|
||||
|
||||
> python uniflash.py -u "C:\ti\uniflash_3.2\uniflashCLI.bat" -c "C:\VirtualBoxShared\GitHub\launchxl_uniflash.usf" -p 8 -s "C:\ti\CC31xx_CC32xx_ServicePack_1.0.0.10.0\servicepack_1.0.0.10.0.bin"
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
import argparse
|
||||
import subprocess
|
||||
|
||||
|
||||
def print_exception(e):
|
||||
print ('Exception: {}, on line {}'.format(e, sys.exc_info()[-1].tb_lineno))
|
||||
|
||||
|
||||
def main():
|
||||
cmd_parser = argparse.ArgumentParser(description='Flash the WiPy and optionally run a small test on it.')
|
||||
cmd_parser.add_argument('-u', '--uniflash', default=None, help='the path to the uniflash cli executable')
|
||||
cmd_parser.add_argument('-c', '--config', default=None, help='the path to the uniflash config file')
|
||||
cmd_parser.add_argument('-p', '--port', default=8, help='the com serial port')
|
||||
cmd_parser.add_argument('-s', '--servicepack', default=None, help='the path to the servicepack file')
|
||||
args = cmd_parser.parse_args()
|
||||
|
||||
result = 1
|
||||
com_port = 'com=' + str(args.port)
|
||||
servicepack_path = 'spPath=' + args.servicepack
|
||||
|
||||
try:
|
||||
if args.uniflash == None or args.config == None:
|
||||
raise ValueError('uniflash path and config path are mandatory')
|
||||
if args.servicepack == None:
|
||||
subprocess.check_call([args.uniflash, '-config', args.config, '-setOptions', com_port, '-operations', 'format', 'program'], stderr=subprocess.STDOUT)
|
||||
else:
|
||||
subprocess.check_call([args.uniflash, '-config', args.config, '-setOptions', com_port, servicepack_path, '-operations', 'format', 'servicePackUpdate', 'program'], stderr=subprocess.STDOUT)
|
||||
result = 0
|
||||
except Exception as e:
|
||||
print_exception(e)
|
||||
finally:
|
||||
if result:
|
||||
print ("ERROR: Programming failed!")
|
||||
else:
|
||||
print ("Board programmed OK")
|
||||
sys.exit(result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
189
cc3200/tools/update-wipy.py
Normal file
189
cc3200/tools/update-wipy.py
Normal file
@@ -0,0 +1,189 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
The WiPy firmware update script. Transmits the specified firmware file
|
||||
over FTP, and then resets the WiPy and optionally verifies that software
|
||||
was correctly updated.
|
||||
|
||||
Usage:
|
||||
|
||||
./update-wipy.py --file "path_to_mcuimg.bin" --verify
|
||||
|
||||
Or:
|
||||
|
||||
python update-wipy.py --file "path_to_mcuimg.bin"
|
||||
"""
|
||||
|
||||
import sys
|
||||
import argparse
|
||||
import time
|
||||
from ftplib import FTP
|
||||
from telnetlib import Telnet
|
||||
|
||||
|
||||
def print_exception(e):
|
||||
print ('Exception: {}, on line {}'.format(e, sys.exc_info()[-1].tb_lineno))
|
||||
|
||||
|
||||
def ftp_directory_exists(ftpobj, directory_name):
|
||||
filelist = []
|
||||
ftpobj.retrlines('LIST',filelist.append)
|
||||
for f in filelist:
|
||||
if f.split()[-1] == directory_name:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def transfer_file(args):
|
||||
with FTP(args.ip, timeout=20) as ftp:
|
||||
print ('FTP connection established')
|
||||
|
||||
if '230' in ftp.login(args.user, args.password):
|
||||
print ('Login successful')
|
||||
|
||||
if '250' in ftp.cwd('/flash'):
|
||||
if not ftp_directory_exists(ftp, 'sys'):
|
||||
print ('/flash/sys directory does not exist')
|
||||
if not '550' in ftp.mkd('sys'):
|
||||
print ('/flash/sys directory created')
|
||||
else:
|
||||
print ('Error: cannot create /flash/sys directory')
|
||||
return False
|
||||
if '250' in ftp.cwd('sys'):
|
||||
print ("Entered '/flash/sys' directory")
|
||||
with open(args.file, "rb") as fwfile:
|
||||
print ('Firmware image found, initiating transfer...')
|
||||
if '226' in ftp.storbinary("STOR " + 'mcuimg.bin', fwfile, 512):
|
||||
print ('File transfer complete')
|
||||
return True
|
||||
else:
|
||||
print ('Error: file transfer failed')
|
||||
else:
|
||||
print ('Error: cannot enter /flash/sys directory')
|
||||
else:
|
||||
print ('Error: cannot enter /flash directory')
|
||||
else:
|
||||
print ('Error: ftp login failed')
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def reset_board(args):
|
||||
success = False
|
||||
|
||||
try:
|
||||
tn = Telnet(args.ip, timeout=5)
|
||||
print("Connected via Telnet, trying to login now")
|
||||
|
||||
if b'Login as:' in tn.read_until(b"Login as:", timeout=5):
|
||||
tn.write(bytes(args.user, 'ascii') + b"\r\n")
|
||||
|
||||
if b'Password:' in tn.read_until(b"Password:", timeout=5):
|
||||
# needed because of internal implementation details of the WiPy's telnet server
|
||||
time.sleep(0.2)
|
||||
tn.write(bytes(args.password, 'ascii') + b"\r\n")
|
||||
|
||||
if b'Type "help()" for more information.' in tn.read_until(b'Type "help()" for more information.', timeout=5):
|
||||
print("Telnet login succeeded")
|
||||
tn.write(b'\r\x03\x03') # ctrl-C twice: interrupt any running program
|
||||
time.sleep(1)
|
||||
tn.write(b'\r\x02') # ctrl-B: enter friendly REPL
|
||||
if b'Type "help()" for more information.' in tn.read_until(b'Type "help()" for more information.', timeout=5):
|
||||
tn.write(b"import pyb\r\n")
|
||||
tn.write(b"pyb.reset()\r\n")
|
||||
time.sleep(1)
|
||||
print("Reset performed")
|
||||
success = True
|
||||
else:
|
||||
print("Error: cannot enter friendly REPL")
|
||||
else:
|
||||
print("Error: telnet login failed")
|
||||
|
||||
except Exception as e:
|
||||
print_exception(e)
|
||||
finally:
|
||||
try:
|
||||
tn.close()
|
||||
except Exception as e:
|
||||
pass
|
||||
return success
|
||||
|
||||
|
||||
def verify_update(args):
|
||||
success = False
|
||||
firmware_tag = ''
|
||||
|
||||
def find_tag (tag):
|
||||
if tag in firmware_tag:
|
||||
print("Verification passed")
|
||||
return True
|
||||
else:
|
||||
print("Error: verification failed, the git tag doesn't match")
|
||||
return False
|
||||
|
||||
try:
|
||||
# Specify a longer time out value here because the board has just been
|
||||
# reset and the wireless connection might not be fully established yet
|
||||
tn = Telnet(args.ip, timeout=15)
|
||||
print("Connected via telnet again, lets check the git tag")
|
||||
|
||||
firmware_tag = tn.read_until (b'with CC3200')
|
||||
tag_file_path = args.file.rstrip('mcuimg.bin') + 'genhdr/mpversion.h'
|
||||
|
||||
if args.tag is not None:
|
||||
success = find_tag(bytes(args.tag, 'ascii'))
|
||||
else:
|
||||
with open(tag_file_path) as tag_file:
|
||||
for line in tag_file:
|
||||
bline = bytes(line, 'ascii')
|
||||
if b'MICROPY_GIT_HASH' in bline:
|
||||
bline = bline.lstrip(b'#define MICROPY_GIT_HASH ').replace(b'"', b'').replace(b'\r', b'').replace(b'\n', b'')
|
||||
success = find_tag(bline)
|
||||
break
|
||||
|
||||
except Exception as e:
|
||||
print_exception(e)
|
||||
finally:
|
||||
try:
|
||||
tn.close()
|
||||
except Exception as e:
|
||||
pass
|
||||
return success
|
||||
|
||||
|
||||
def main():
|
||||
cmd_parser = argparse.ArgumentParser(description='Update the WiPy firmware with the specified image file')
|
||||
cmd_parser.add_argument('-f', '--file', default=None, help='the path of the firmware file')
|
||||
cmd_parser.add_argument('-u', '--user', default='micro', help='the username')
|
||||
cmd_parser.add_argument('-p', '--password', default='python', help='the login password')
|
||||
cmd_parser.add_argument('--ip', default='192.168.1.1', help='the ip address of the WiPy')
|
||||
cmd_parser.add_argument('--verify', action='store_true', help='verify that the update succeeded')
|
||||
cmd_parser.add_argument('-t', '--tag', default=None, help='git tag of the firmware image')
|
||||
args = cmd_parser.parse_args()
|
||||
|
||||
result = 1
|
||||
|
||||
try:
|
||||
if args.file is None:
|
||||
raise ValueError('the image file path must be specified')
|
||||
if transfer_file(args):
|
||||
if reset_board(args):
|
||||
if args.verify:
|
||||
print ('Waiting for the WiFi connection to come up again...')
|
||||
# this time is to allow the system's wireless network card to connect to the
|
||||
# WiPy again. Sometimes it might only take a couple of seconds, but let's
|
||||
# leave 15s to be on the safe side
|
||||
time.sleep(15)
|
||||
if verify_update(args):
|
||||
result = 0
|
||||
else:
|
||||
result = 0
|
||||
|
||||
except Exception as e:
|
||||
print_exception(e)
|
||||
finally:
|
||||
sys.exit(result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -24,7 +24,6 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "std.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "inc/hw_types.h"
|
||||
@@ -36,20 +35,20 @@
|
||||
#include "rom_map.h"
|
||||
#include "prcm.h"
|
||||
#include "shamd5.h"
|
||||
#include "hash.h"
|
||||
#include "simplelink.h"
|
||||
#include "cryptohash.h"
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
DEFINE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
void HASH_Init (void) {
|
||||
__attribute__ ((section (".boot")))
|
||||
void CRYPTOHASH_Init (void) {
|
||||
// Enable the Data Hashing and Transform Engine
|
||||
MAP_PRCMPeripheralClkEnable(PRCM_DTHE, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK);
|
||||
MAP_PRCMPeripheralReset(PRCM_DTHE);
|
||||
}
|
||||
|
||||
void HASH_SHAMD5Start (uint32_t algo, uint32_t blocklen) {
|
||||
void CRYPTOHASH_SHAMD5Start (uint32_t algo, uint32_t blocklen) {
|
||||
// wait until the context is ready
|
||||
while ((HWREG(SHAMD5_BASE + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_CONTEXT_READY) == 0);
|
||||
|
||||
@@ -65,12 +64,12 @@ void HASH_SHAMD5Start (uint32_t algo, uint32_t blocklen) {
|
||||
HWREG(SHAMD5_BASE + SHAMD5_O_LENGTH) = blocklen;
|
||||
}
|
||||
|
||||
void HASH_SHAMD5Update (uint8_t *data, uint32_t datalen) {
|
||||
void CRYPTOHASH_SHAMD5Update (uint8_t *data, uint32_t datalen) {
|
||||
// write the data
|
||||
SHAMD5DataWriteMultiple(data, datalen);
|
||||
}
|
||||
|
||||
void HASH_SHAMD5Read (uint8_t *hash) {
|
||||
void CRYPTOHASH_SHAMD5Read (uint8_t *hash) {
|
||||
// wait for the output to be ready
|
||||
while((HWREG(SHAMD5_BASE + SHAMD5_O_IRQSTATUS) & SHAMD5_INT_OUTPUT_READY) == 0);
|
||||
// read the result
|
||||
@@ -24,15 +24,15 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HASH_H_
|
||||
#define HASH_H_
|
||||
#ifndef CRYPTOHASH_H_
|
||||
#define CRYPTOHASH_H_
|
||||
|
||||
/******************************************************************************
|
||||
DECLARE PUBLIC FUNCTIONS
|
||||
******************************************************************************/
|
||||
extern void HASH_Init (void);
|
||||
extern void HASH_SHAMD5Start (uint32_t algo, uint32_t blocklen);
|
||||
extern void HASH_SHAMD5Update (uint8_t *data, uint32_t datalen);
|
||||
extern void HASH_SHAMD5Read (uint8_t *hash);
|
||||
extern void CRYPTOHASH_Init (void);
|
||||
extern void CRYPTOHASH_SHAMD5Start (uint32_t algo, uint32_t blocklen);
|
||||
extern void CRYPTOHASH_SHAMD5Update (uint8_t *data, uint32_t datalen);
|
||||
extern void CRYPTOHASH_SHAMD5Read (uint8_t *hash);
|
||||
|
||||
#endif /* HASH_H_ */
|
||||
#endif /* CRYPTOHASH_H_ */
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "std.h"
|
||||
#include "fifo.h"
|
||||
|
||||
|
||||
|
||||
@@ -27,14 +27,15 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "inc/hw_types.h"
|
||||
#include "inc/hw_ints.h"
|
||||
#include "inc/hw_memmap.h"
|
||||
#include "rom_map.h"
|
||||
#include "prcm.h"
|
||||
#include "simplelink.h"
|
||||
#include "modnetwork.h"
|
||||
#include "modwlan.h"
|
||||
#include "py/obj.h"
|
||||
#include "random.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <std.h>
|
||||
#include "osi.h"
|
||||
#include "fifo.h"
|
||||
#include "socketfifo.h"
|
||||
|
||||
@@ -24,21 +24,13 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// This file is needed because in some cases we can't include stdio.h,
|
||||
// because the CC3100 socket driver has name clashes with it.
|
||||
|
||||
typedef unsigned int size_t;
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
void *memmove(void *dest, const void *src, size_t n);
|
||||
void *memset(void *s, int c, size_t n);
|
||||
|
||||
size_t strlen(const char *str);
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
int strncmp(const char *s1, const char *s2, size_t n);
|
||||
char *strcpy(char *dest, const char *src);
|
||||
char *strcat(char *dest, const char *src);
|
||||
char *strchr(const char *s, int c);
|
||||
char *strstr(const char *haystack, const char *needle);
|
||||
|
||||
int printf(const char *fmt, ...);
|
||||
int snprintf(char *str, size_t size, const char *fmt, ...);
|
||||
|
||||
// Convenience function, defined in main.c.
|
||||
void stoupper (char *str);
|
||||
|
||||
32
cc3200/version.h
Normal file
32
cc3200/version.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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 VERSION_H_
|
||||
#define VERSION_H_
|
||||
|
||||
#define WIPY_SW_VERSION_NUMBER "0.9.1"
|
||||
|
||||
#endif /* VERSION_H_ */
|
||||
42
docs/conf.py
42
docs/conf.py
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Micro Python documentation build configuration file, created by
|
||||
# MicroPython documentation build configuration file, created by
|
||||
# sphinx-quickstart on Sun Sep 21 11:42:03 2014.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
@@ -47,10 +47,10 @@ source_suffix = '.rst'
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
#master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = 'Micro Python'
|
||||
project = 'MicroPython'
|
||||
copyright = '2014, Damien P. George'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
@@ -60,7 +60,7 @@ copyright = '2014, Damien P. George'
|
||||
# The short X.Y version.
|
||||
version = '1.4'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.4'
|
||||
release = '1.4.5'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
@@ -134,7 +134,7 @@ else:
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = '../logo/trans-logo.png'
|
||||
#html_logo = '../../logo/trans-logo.png'
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
@@ -213,7 +213,7 @@ latex_elements = {
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
('index', 'MicroPython.tex', 'Micro Python Documentation',
|
||||
('index', 'MicroPython.tex', 'MicroPython Documentation',
|
||||
'Damien P. George', 'manual'),
|
||||
]
|
||||
|
||||
@@ -243,7 +243,7 @@ latex_documents = [
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'micropython', 'Micro Python Documentation',
|
||||
('index', 'micropython', 'MicroPython Documentation',
|
||||
['Damien P. George'], 1),
|
||||
]
|
||||
|
||||
@@ -257,7 +257,7 @@ man_pages = [
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'MicroPython', 'Micro Python Documentation',
|
||||
('index', 'MicroPython', 'MicroPython Documentation',
|
||||
'Damien P. George', 'MicroPython', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
@@ -277,3 +277,29 @@ texinfo_documents = [
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
intersphinx_mapping = {'http://docs.python.org/': None}
|
||||
|
||||
|
||||
# Work out the port to generate the docs for
|
||||
from collections import OrderedDict
|
||||
micropy_port = os.getenv('MICROPY_PORT') or 'pyboard'
|
||||
tags.add('port_' + micropy_port)
|
||||
ports = OrderedDict((
|
||||
("unix", "unix"),
|
||||
("pyboard", "the pyboard"),
|
||||
("wipy", "the WiPy"),
|
||||
("esp8266", "esp8266"),
|
||||
))
|
||||
|
||||
# The members of the html_context dict are available inside topindex.html
|
||||
url_prefix = os.getenv('MICROPY_URL_PREFIX') or '/'
|
||||
html_context = {
|
||||
'port':micropy_port,
|
||||
'port_name':ports[micropy_port],
|
||||
'all_ports':[(n, url_prefix + p) for p, n in ports.items()],
|
||||
}
|
||||
|
||||
# Append the other ports' specific folders/files to the exclude pattern
|
||||
exclude_patterns.extend([port + '*' for port in ports if port != micropy_port])
|
||||
|
||||
# Specify a custom master document based on the port name
|
||||
master_doc = micropy_port + '_' + 'index'
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
Micro Python documentation contents
|
||||
===================================
|
||||
|
||||
.. toctree::
|
||||
|
||||
quickref.rst
|
||||
general.rst
|
||||
tutorial/index.rst
|
||||
library/index.rst
|
||||
hardware/index.rst
|
||||
license.rst
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user