Compare commits
1232 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f2ff5bccd3 | |||
| e064edc69b | |||
| 4d03134e9e | |||
| 541c5aa000 | |||
| ad82ce9c1b | |||
| 7c4bb27ebd | |||
| e484668033 | |||
| 5f9a24cddd | |||
| 5154ba238a | |||
| c4a8e121d3 | |||
| 6c068076e4 | |||
| 8b5165c271 | |||
| 61f430cb43 | |||
| 144f47b6cf | |||
| a493e022a7 | |||
| 517c5521be | |||
| aedb5211ab | |||
| 8833a3e451 | |||
| 79c0754af9 | |||
| 49cb4f97d6 | |||
| a5bf114f2b | |||
| 022caee996 | |||
| ca4d00ca4b | |||
| a1a18aae57 | |||
| bc078d5e3f | |||
| 8bab0aee9a | |||
| 900bc139b5 | |||
| 48c913a96a | |||
| 9092f52999 | |||
| 68f6d68138 | |||
| e2df5ef0ed | |||
| 3001a754c1 | |||
| 56c4db624a | |||
| 5126de7ed8 | |||
| 1a7bb8e966 | |||
| 9701ac54e8 | |||
| 311c05b256 | |||
| 1ddfb6b81e | |||
| 91abaa4f61 | |||
| e3327ce2c1 | |||
| 4b4c9728be | |||
| 3a93ae3558 | |||
| dc2c4efde5 | |||
| d2aaac6819 | |||
| 7d5543f5a7 | |||
| 0a49777e6d | |||
| 8f0a996c0a | |||
| 0b665f145a | |||
| c1a8026406 | |||
| 07dc3459a2 | |||
| 8132f530d9 | |||
| 6686c75206 | |||
| 692f8b1ef4 | |||
| 237fa71133 | |||
| c7491a8dee | |||
| 4d7f2c8579 | |||
| b4e2086506 | |||
| c0a509e3fa | |||
| 8b7ed2bdec | |||
| bf43703666 | |||
| 5845bb8d4a | |||
| 874281a081 | |||
| d3c967c6cd | |||
| e9531e3990 | |||
| 34b56368dd | |||
| 2df2c5a011 | |||
| 17cdf85d15 | |||
| aef84e0063 | |||
| 9358ed084e | |||
| 4a1f897ad5 | |||
| 39b1492f19 | |||
| 93ccb3da05 | |||
| 564c1469a3 | |||
| 1c1ca9b890 | |||
| deb5954055 | |||
| 3b16e017d4 | |||
| e102a9d57d | |||
| fc363d408e | |||
| b46278b791 | |||
| 4858993cd8 | |||
| c5fbd3dd73 | |||
| 7513dfaf1d | |||
| a2076c8717 | |||
| aa92d59ada | |||
| 3d3c3833dd | |||
| 1e2edee88c | |||
| b9b4214d8f | |||
| 86b5e0de04 | |||
| aca37b43f3 | |||
| 6d653cf2db | |||
| 80b85fcc87 | |||
| 63461069b8 | |||
| 38ea2afa9c | |||
| 2ab712f40b | |||
| 21c518e5f3 | |||
| c41185f690 | |||
| cf54528a9e | |||
| c6d6c7f66d | |||
| 781b3c6188 | |||
| 8760bae8a6 | |||
| cffdacbe94 | |||
| 8f7959a201 | |||
| 1284ed2051 | |||
| 1e7f517aa5 | |||
| 0dc7060c92 | |||
| 6d2a731acc | |||
| 7973386f9a | |||
| 63f2fcd507 | |||
| 3326b69169 | |||
| 0cdfa9b6e5 | |||
| 873847e42e | |||
| 998f904c41 | |||
| 403f14c0ea | |||
| 7f15566d5c | |||
| 3eea221b24 | |||
| a8dd74bd89 | |||
| dfdca2dcfc | |||
| 566291bc17 | |||
| 0ddf92ce0e | |||
| 12f866cfb6 | |||
| 431a9ecc0e | |||
| 39bc1700be | |||
| 6e6b0c4b5f | |||
| 4fb205def7 | |||
| 989593f5f6 | |||
| b0ae67e2e5 | |||
| 2a41cec5ae | |||
| c00620b891 | |||
| 0026262520 | |||
| 49f0da06fa | |||
| d1d3d7ff95 | |||
| 8fa5bc405f | |||
| f44607aff0 | |||
| d92a379249 | |||
| d558e33647 | |||
| d360c0e820 | |||
| 617b256bb8 | |||
| 3291f21309 | |||
| 95aa8f2ec8 | |||
| fa268017c8 | |||
| 4dd2daedcd | |||
| 283b75dfd7 | |||
| cee86dd968 | |||
| 36e6751f73 | |||
| caaf6db7ad | |||
| d92f6d4978 | |||
| f9b9a5497c | |||
| ded307c494 | |||
| 1d5e1881eb | |||
| 49762250d6 | |||
| 392a10c98d | |||
| ea148dfcda | |||
| 28bd8e4f07 | |||
| 2abaa19c01 | |||
| e9cb986bdf | |||
| 770376e4ad | |||
| 1cd24d218b | |||
| 0994312782 | |||
| 1f44987aff | |||
| 92106aedd8 | |||
| 3a662afe73 | |||
| 5bdd8f8994 | |||
| d6543f6c55 | |||
| a81d77b364 | |||
| 2d1f3e3441 | |||
| 21de55e550 | |||
| e419708561 | |||
| ff609188cb | |||
| 958dee594f | |||
| d8467af191 | |||
| 6e553663ee | |||
| c41ac65fd2 | |||
| de1cac6e5d | |||
| 5d507af66d | |||
| 10dce7dee4 | |||
| 67689c8f71 | |||
| 52c283602d | |||
| 1ad5aa4785 | |||
| 7b5cca58c0 | |||
| 53315d0132 | |||
| 204014c8c2 | |||
| fac0e5df5e | |||
| 41431161b3 | |||
| 4b09e1ed23 | |||
| ea6820a046 | |||
| bb83933c8c | |||
| a19cf2d7ef | |||
| c66fab2e6d | |||
| 9f2b486152 | |||
| 214bc9c4d4 | |||
| 82783013fd | |||
| 792412f5fe | |||
| 6fbbac60dc | |||
| 8bb4681578 | |||
| 62d80d8145 | |||
| b74f8ee61d | |||
| 48a7090e6e | |||
| 6fc8ba804c | |||
| fbd1488b62 | |||
| 42b41e8f03 | |||
| 98aa332fb3 | |||
| 5c8d5dbd95 | |||
| 78c713d7a5 | |||
| 18385ceebd | |||
| 944c66dca4 | |||
| 56eec662a3 | |||
| 74eb65117d | |||
| dcfbd424dd | |||
| e35cf751de | |||
| d1b862a4f3 | |||
| 38bcc1f29f | |||
| 98100708d6 | |||
| 83dedd83bc | |||
| 5def4849fe | |||
| 87105c1268 | |||
| 74a6b54071 | |||
| f7441620cb | |||
| 1b8e0f12b9 | |||
| eb2b7623c1 | |||
| 0358976a4a | |||
| 3984a68671 | |||
| f3a02f0f4e | |||
| f69a77098f | |||
| 3af21718cb | |||
| 4814a529da | |||
| 3e91b3f46d | |||
| d9d52762ae | |||
| bb0489725b | |||
| 69bf79f0bc | |||
| 86807ea1f4 | |||
| 85e6ac893b | |||
| 2a9160fcab | |||
| b7a37c4e8a | |||
| 21a5238ca9 | |||
| 3824939030 | |||
| 1e3c1d8ce2 | |||
| 8cfde7854b | |||
| e4296225a8 | |||
| 229cfe45f3 | |||
| 390b7f12cf | |||
| a0a9d13694 | |||
| aef70fc850 | |||
| 7a3499b6a4 | |||
| 2b12eabcb9 | |||
| 28b62a0f80 | |||
| 4a1ae0eaa4 | |||
| 2633af9fef | |||
| 3c064d2275 | |||
| f5cd611683 | |||
| 69731d7904 | |||
| 35fc938b1e | |||
| abb604bf6d | |||
| 8eaefce7b5 | |||
| 63e2ae60a5 | |||
| 9fb1eb665f | |||
| 9d8bfea60a | |||
| 71b311cb26 | |||
| c184efeb31 | |||
| c724779b4d | |||
| a0aca08c3d | |||
| a830c0c95c | |||
| d64a71f5ab | |||
| 5cda44ac0b | |||
| e53ce519ff | |||
| 3b756bcede | |||
| 2ee478d310 | |||
| c36fe15174 | |||
| 93ca2436b1 | |||
| e616c4674d | |||
| d7bb012f16 | |||
| 983a7d8c28 | |||
| 18cbde2e41 | |||
| 2a39ece5af | |||
| fa91162539 | |||
| 0d9544d914 | |||
| d72c58ef92 | |||
| 8e6c1074e5 | |||
| 1568e3475f | |||
| 309d340daf | |||
| ac2fd120dc | |||
| a90f09c4dd | |||
| 0b5f85ab90 | |||
| c087ed17ef | |||
| a323af62c0 | |||
| db21488060 | |||
| 992006217e | |||
| 82ee36571e | |||
| 0a4604615c | |||
| 8f485462eb | |||
| 2eed4e35a2 | |||
| 46da62bf05 | |||
| 9187b52f81 | |||
| c4b3f94a31 | |||
| 6cc2f8c889 | |||
| 2b29a65bb1 | |||
| 2ed85780f8 | |||
| 26dfee2b7f | |||
| eb161ff3e8 | |||
| 20db18316d | |||
| 554aeeae76 | |||
| 21b888be5d | |||
| 29025d98bb | |||
| afc058ad7b | |||
| 04fb2bdc2b | |||
| 3a1d0b1fd9 | |||
| 3829212bef | |||
| 8886906c0f | |||
| cf54d94f08 | |||
| 2163c7a1fe | |||
| 992e0f7ea4 | |||
| b1881ead99 | |||
| e247194fac | |||
| 313a74bc7c | |||
| cdc4470d1e | |||
| 66beb47e2d | |||
| 9c5f5c12b6 | |||
| 6e80e39443 | |||
| 02d9800ba1 | |||
| c8abcc85ef | |||
| 857442f147 | |||
| 4c6b4dd061 | |||
| 0b1bdc540e | |||
| 302de76fff | |||
| 303f79f0bd | |||
| d859c9acd6 | |||
| afe88258d5 | |||
| 6dacb0fd7c | |||
| b94f54822f | |||
| a095fab84c | |||
| bd2e522bcf | |||
| 7c40eefe84 | |||
| 791d9cf66e | |||
| 1ae35b5148 | |||
| 469346178a | |||
| a157f0e22a | |||
| 90405ad9ed | |||
| a599e6da11 | |||
| a626ea2ceb | |||
| 12ca975280 | |||
| cd90b935f3 | |||
| 2087078d83 | |||
| 73386b309d | |||
| 2a6692b37a | |||
| b07308ab80 | |||
| 9290ccc988 | |||
| 72351d5f5d | |||
| f0b2b56990 | |||
| dbc0a16134 | |||
| 5a11cf03cb | |||
| 0287369be2 | |||
| 19aaeb8a27 | |||
| aa21524183 | |||
| 200edbf857 | |||
| b3e7e25849 | |||
| dccb20d127 | |||
| 3a852e9be1 | |||
| 9537c3f940 | |||
| e41aa9fbd6 | |||
| 2e747a1663 | |||
| 29e669cc03 | |||
| c3eb1254bc | |||
| 3f724dc6ab | |||
| c1c4631b73 | |||
| 3b7cebe09a | |||
| 52b7208335 | |||
| 4cb48022a2 | |||
| af344a3687 | |||
| c60210f799 | |||
| 0d38bd3323 | |||
| dfca0bd85a | |||
| ec3d660258 | |||
| a9a561aa4c | |||
| 9d52bdd6bd | |||
| 51a665cec7 | |||
| b3d26bc21f | |||
| 7f9092a90e | |||
| ca617d8094 | |||
| a4ea524748 | |||
| 2f0cc91aaf | |||
| 13957219b9 | |||
| 45458792bc | |||
| 5a5c9828d5 | |||
| d82e8a9359 | |||
| 20900734b8 | |||
| 29deb4c4d4 | |||
| 3236481bd6 | |||
| b1625e7980 | |||
| ab501696ed | |||
| 73e807062a | |||
| d271f3422e | |||
| b431f2e5bf | |||
| 8abf660e2b | |||
| 78ed555f6e | |||
| c434217b08 | |||
| d8ab94d07c | |||
| cfb1550ff5 | |||
| c07e0a7f2f | |||
| 4c24e881c4 | |||
| 9812daa0aa | |||
| 7189fa0b54 | |||
| b746528ac8 | |||
| edd838d866 | |||
| 599bacd673 | |||
| dfee4b4f36 | |||
| 5cb5ee0111 | |||
| 8123713372 | |||
| 6ab940a334 | |||
| 6cd0b4832f | |||
| f686e5325d | |||
| df1a2ac19a | |||
| d3fd34a765 | |||
| 97595efa83 | |||
| 5e940e56f4 | |||
| 5c60440d36 | |||
| 6ff0448d67 | |||
| 3cc65aa771 | |||
| 3f21e6c1a4 | |||
| 148d8a726f | |||
| 796c1adfbc | |||
| d657619430 | |||
| 59696d639d | |||
| f420cc7d56 | |||
| f8bff1640e | |||
| 24ce936d2b | |||
| 0a976e1f3e | |||
| 78efc5f0f0 | |||
| 6c4193f158 | |||
| 4953141252 | |||
| 6b3836e9a2 | |||
| 8f5aaad3d6 | |||
| a8f3e77e22 | |||
| ee7b9f2001 | |||
| 356906c1eb | |||
| 216e172dcf | |||
| 9c7c55e4cd | |||
| 532848849c | |||
| e406021828 | |||
| e13b957b17 | |||
| c84314862e | |||
| 4b87e1a859 | |||
| 5d88b83491 | |||
| 0c0d8ba47e | |||
| 4e522fce6c | |||
| 13c15bd6ef | |||
| 485d5bbdea | |||
| 56e01f4fb5 | |||
| 3d92371570 | |||
| 7eae709938 | |||
| aeb727bcbf | |||
| 13f8bb018b | |||
| 759027cea4 | |||
| 326f85dcd7 | |||
| fd002d68cd | |||
| b7de04020d | |||
| 155f27c217 | |||
| 94b710ceaa | |||
| e410336348 | |||
| 3f3cdadb30 | |||
| 5e29fa0737 | |||
| 808809650d | |||
| cb92decfe3 | |||
| a999009c24 | |||
| 310a9e03e2 | |||
| 4cb7f6497e | |||
| 40c353524d | |||
| f5addfa8ca | |||
| 618d7f924f | |||
| e534c2c7ea | |||
| fd6f0ec952 | |||
| 5954d213a6 | |||
| 57bf12dbdb | |||
| b1bc43aa1d | |||
| 4996756e21 | |||
| a87c74bf31 | |||
| a78c5d348e | |||
| cea3ee724e | |||
| 3d6d7e6a20 | |||
| f00ed18da8 | |||
| 8c3c429a20 | |||
| e15654edad | |||
| 5f19f78509 | |||
| fada51f5b3 | |||
| 0c6dbbba4c | |||
| 648d2c3beb | |||
| 689fea2f90 | |||
| 139c700025 | |||
| bc52f7077f | |||
| 7329d8b728 | |||
| 2f311dddfd | |||
| 16d4601043 | |||
| 5a2d6cb250 | |||
| 2037f0d8b0 | |||
| fb7525e42d | |||
| 7e75360ef3 | |||
| 46000a15ba | |||
| 8a98283cb0 | |||
| f6caf5eae3 | |||
| 13370a6abf | |||
| 05649d7123 | |||
| 488fbfd29d | |||
| 7591e6411e | |||
| 37457e8151 | |||
| b80a6dccaa | |||
| 209c685f11 | |||
| 7303e99bab | |||
| ce7adabfbe | |||
| 968d1307fc | |||
| 6b77921948 | |||
| 3256be6f3a | |||
| 72fd306015 | |||
| a2309abc88 | |||
| 2248750812 | |||
| 7b84ba8c6d | |||
| cdaa063188 | |||
| c89d4b05c7 | |||
| 206f3bd334 | |||
| 7c192910d1 | |||
| 1d6c8627c0 | |||
| 53a4bfaac5 | |||
| 424daa752c | |||
| 5e78ec7edd | |||
| 18174446bc | |||
| c5a8e15f21 | |||
| 897a698e4b | |||
| 814452ee35 | |||
| ab1fcd9997 | |||
| 0a6cbe92b6 | |||
| b16971b644 | |||
| 7173fc3d2b | |||
| 9f8045c362 | |||
| 10fa05c3ce | |||
| ad8eb930da | |||
| 031bf5e3a1 | |||
| 6e558b41f0 | |||
| 7ce5df53a9 | |||
| 92e20f2427 | |||
| 8220f84616 | |||
| 03751a1c75 | |||
| 31c2d69303 | |||
| 9d4f38f127 | |||
| 1c3a8a9803 | |||
| 613ebe97d4 | |||
| 99aa5eead5 | |||
| 60616c1619 | |||
| b6debf27ec | |||
| 47fc05c25e | |||
| 28b736f1e8 | |||
| 84e91d8c27 | |||
| f99f7bcd55 | |||
| d489482dfc | |||
| 98992ce1b0 | |||
| efe8c2ec8c | |||
| 92a7363abc | |||
| 40ba5925fc | |||
| 6f2452afd0 | |||
| 680f838b1d | |||
| 923a03f775 | |||
| 97b261abe2 | |||
| 6014b6fdbf | |||
| d707709b94 | |||
| aec4c783eb | |||
| 554521746b | |||
| bef5ee525d | |||
| 6150cac0f5 | |||
| b3b670b55f | |||
| bad137b615 | |||
| 4339896e4b | |||
| e924c8fa64 | |||
| 395d0d6b39 | |||
| 4c22ea18fd | |||
| 7a6d3fea3f | |||
| 3f787ffe24 | |||
| 339e250b76 | |||
| aceb935066 | |||
| 1801cc5b53 | |||
| a29c9c724e | |||
| b135645132 | |||
| 7f4fe24c68 | |||
| 03936ee234 | |||
| e25c54e83e | |||
| 50a6b2645a | |||
| 3a9dac665b | |||
| d3aba9688c | |||
| 71c0b7b1d9 | |||
| b627237b1d | |||
| 2d12a7dc44 | |||
| 6a08bd830a | |||
| f222600612 | |||
| fa7de3dbd8 | |||
| bff713d8d8 | |||
| 434c071bda | |||
| 340043a73e | |||
| 087f4e3276 | |||
| 327b8f78dd | |||
| 0a411ea12f | |||
| 0a029ab3ff | |||
| 8e3d389e99 | |||
| 8845ae57f3 | |||
| e3d8ea1117 | |||
| dfa697d47c | |||
| 839bad199e | |||
| cedb966958 | |||
| 7d63dbf226 | |||
| fa28b67db6 | |||
| 63e6edc5af | |||
| 91747475c8 | |||
| ba65591076 | |||
| eb4bfffc33 | |||
| 0d6b19e350 | |||
| 6cffbed503 | |||
| 172820b4ae | |||
| 10416db062 | |||
| 0126797857 | |||
| 5113a3f5d3 | |||
| 0d591c748f | |||
| fdc0ff334d | |||
| 55b242c96b | |||
| 1080514bd9 | |||
| abcc80b266 | |||
| 81aedf9ecd | |||
| 18317070f2 | |||
| 1a7449b227 | |||
| 2e96ba10b1 | |||
| c4aca143a0 | |||
| 631079ff1b | |||
| 495c67406c | |||
| 37387f91fd | |||
| d02ef1b603 | |||
| c71ee46e5f | |||
| 21f3e4395a | |||
| c130f48f2d | |||
| 6305fd84d2 | |||
| 42650540ca | |||
| 721e64c993 | |||
| b8a040606b | |||
| dc5bf21171 | |||
| 00390a6fd4 | |||
| 4ae4850820 | |||
| 8144b42a6d | |||
| 3875bf981d | |||
| a5ba6ff463 | |||
| 09a7cc5e03 | |||
| bc3539d777 | |||
| c8b51eb063 | |||
| 0a531d258f | |||
| 0b01665112 | |||
| bf8bddb147 | |||
| 90dd3e45cd | |||
| 3516845bef | |||
| 1515062bcf | |||
| bfd95c0345 | |||
| fbd4c1b204 | |||
| fe81dd7f54 | |||
| 36d937e5b3 | |||
| 76f7813329 | |||
| e144f12cd7 | |||
| 30ce636008 | |||
| 795b48e7c5 | |||
| 87532ac457 | |||
| 20894baf69 | |||
| 6a35d36c0a | |||
| f9e64eb2ab | |||
| 9e9a273081 | |||
| 13c867e122 | |||
| 8e772f18b0 | |||
| 527517207e | |||
| c704e7ad12 | |||
| a946c0206d | |||
| 14d58c8d8b | |||
| 8d775abd8b | |||
| 2565f22cf8 | |||
| e4f45398df | |||
| 93eafc667a | |||
| 99283c6ed6 | |||
| f497c4f9d2 | |||
| b5d110b8ce | |||
| f0d3d9e5dc | |||
| 2f4bc4990f | |||
| 7526f4f5b4 | |||
| e52ef22269 | |||
| a57dbf9411 | |||
| 7663968e44 | |||
| bca4660742 | |||
| cd995aa975 | |||
| 08c7b2898f | |||
| 993948a521 | |||
| 2ce7ac1b2a | |||
| 63890d63bd | |||
| e02dd7a751 | |||
| acb7822712 | |||
| d737e314ea | |||
| d7e3c1251e | |||
| 01e2bcbf3b | |||
| 50616680fa | |||
| 1085b8b7b2 | |||
| e919ffdc6a | |||
| fc3dcda4d4 | |||
| 7dfcdecb1f | |||
| 2e59961319 | |||
| b4b00ecddc | |||
| 2b78b499f4 | |||
| 6ecf3375c2 | |||
| 6f395c2563 | |||
| 28e6e0bd95 | |||
| 580a3c88f5 | |||
| 48b350a8c2 | |||
| b5a030c9df | |||
| 2efdcf51f0 | |||
| 5d20400f86 | |||
| fa97e9366d | |||
| b4a9d62b22 | |||
| 3179dd1d41 | |||
| f2154feda1 | |||
| 36bd3a5caf | |||
| f8cfa99547 | |||
| f5d794e4ca | |||
| 81c6bb1ba7 | |||
| 194c9b7978 | |||
| 190c47e1f4 | |||
| 0ca5c21e6b | |||
| 8fac78d446 | |||
| 002447dbb5 | |||
| 18f06e8395 | |||
| ba9831f52e | |||
| 32b5f47992 | |||
| 5e402bb5a5 | |||
| 702b956a2d | |||
| 733682a51a | |||
| 81d37a96dd | |||
| deabf40080 | |||
| c40191d3bc | |||
| 121c41719d | |||
| d8be36e2f4 | |||
| ad4f4e7e09 | |||
| f66f016c0d | |||
| dc53114edf | |||
| 0986ecd66d | |||
| fd31fc1dd5 | |||
| 9327d5d2c0 | |||
| fa10615077 | |||
| b19386d8a7 | |||
| b2818b6b22 | |||
| 6d3bec464a | |||
| a046a8723e | |||
| 5522b7ca78 | |||
| c5903d2689 | |||
| b332e0d287 | |||
| 1d71b15914 | |||
| 9cc2ee171c | |||
| 51491381ce | |||
| 22ee458db5 | |||
| fd546d3370 | |||
| 0d4c3d761b | |||
| bfa043a175 | |||
| b3f2197371 | |||
| 77c87e5da3 | |||
| 2fa4a6bb3f | |||
| 3a9c375908 | |||
| 9a7976cf6e | |||
| 3cfed9b80c | |||
| 77bfa1dc2a | |||
| 324a0c4b77 | |||
| 03ff032ec7 | |||
| 622bc9bef0 | |||
| 3c095ad5e9 | |||
| 7c3a4d3863 | |||
| b2e29e911f | |||
| 92d45358e3 | |||
| a2b404090a | |||
| 3245de0446 | |||
| 548953623b | |||
| 0b70b3c052 | |||
| 6cdb3b7b2c | |||
| dd87ac6514 | |||
| bed2f6eb5e | |||
| 0a1fa6bd7d | |||
| 89cf4016b7 | |||
| 1e69cfa94a | |||
| 956d034fdc | |||
| 4283acac4f | |||
| 2e0a7a293e | |||
| 46a0fe8533 | |||
| fcf6f436b0 | |||
| 91fbcb94d7 | |||
| aedc89fccd | |||
| 65cb5ec9e6 | |||
| f72926fb74 | |||
| 993eba0af5 | |||
| 2b27f24260 | |||
| 9144776fba | |||
| 95bb18a311 | |||
| 60eecd928d | |||
| 7f401d9155 | |||
| 3b319d1aa5 | |||
| e9fe881c17 | |||
| 18f1c6e620 | |||
| 60936211ae | |||
| 03a1517531 | |||
| fdb2b937f1 | |||
| 772b8318ec | |||
| 1185443850 | |||
| f22f207242 | |||
| 3ab2e20a5e | |||
| a24a8736b1 | |||
| 6e3152633b | |||
| ad54506f86 | |||
| d7226f5e61 | |||
| 485a96745d | |||
| c0577e77df | |||
| e42fb6da31 | |||
| 7a6e800c8a | |||
| efe50710c4 | |||
| bd341d1590 | |||
| 5f8ddf88e4 | |||
| 9fc5401ff2 | |||
| bd2def4d4d | |||
| fddbe300a1 | |||
| 9ee908957b | |||
| eac6950994 | |||
| 05a55c728b | |||
| c7228194df | |||
| 0df8509289 | |||
| 9da2ce3ac4 | |||
| acfb88ac7b | |||
| 88b5b8f82c | |||
| d9cb411c12 | |||
| 9dc1a1fa53 | |||
| f4c52723d7 | |||
| 1bd590195f | |||
| 5ddc88d8a4 | |||
| 5712b03bca | |||
| fee65d8ae5 | |||
| 57f4a5ff97 | |||
| 97f3d832ac | |||
| 02c6edacbe | |||
| 461ed960ce | |||
| d6b3416f7b | |||
| c4149407e3 | |||
| 8be25ddbc7 | |||
| a5602535aa | |||
| 64d5bba3d7 | |||
| 665830cf82 | |||
| 3223b890ad | |||
| 60c3d2f3ae | |||
| e54ba36d4c | |||
| 50360ee6a7 | |||
| eeb150f377 | |||
| 6b660b4af7 | |||
| 4407071146 | |||
| db3bd97935 | |||
| ce34047e12 | |||
| 6606ed07d1 | |||
| 401ec8d370 | |||
| 0c43ff8882 | |||
| 839ee83a6b | |||
| fbc95a04da | |||
| 642b3bf2a9 | |||
| 323329eeca | |||
| 0dac1386ec | |||
| c08302ecb5 | |||
| b8449a42db | |||
| 43542c9d9f | |||
| f1abf9a8c8 | |||
| dd230b7e5a | |||
| d8ba7a577b | |||
| f47692a258 | |||
| 2fac92a843 | |||
| 6c323f6f0c | |||
| c3ef8e7d44 | |||
| 295bd75b96 | |||
| 7aff9f1077 | |||
| 1a34b150e8 | |||
| 6e857556f5 | |||
| 606619910f | |||
| 2fcc6a36ef | |||
| ef65a16850 | |||
| 6cd1d6283b | |||
| 6829a94516 | |||
| c14da4fdbe | |||
| 77571bd9cd | |||
| 9960e84d2d | |||
| d5bf3a6b82 | |||
| 2f7f0806dc | |||
| 2bd7cfae95 | |||
| 0c20942573 | |||
| 403c36e35e | |||
| 2bb2654e05 | |||
| 007f15b1ee | |||
| 9a73530bb7 | |||
| dd09df994c | |||
| bdf5ef4e0d | |||
| e193963c93 | |||
| 51b297b46f | |||
| 04b90dd9d2 | |||
| 894f78427e | |||
| c16af175aa | |||
| 328e322edf | |||
| d4685c9e4e | |||
| 3b4c9412a1 | |||
| 55dc92a6f2 | |||
| 65591dda63 | |||
| 00bb1e70e4 | |||
| 84513c8c0e | |||
| 12cb97b88c | |||
| 0727523472 | |||
| bd56fcab06 | |||
| 80b63a9d37 | |||
| d6690cbb01 | |||
| bf2055e1ad | |||
| 223c0645e8 | |||
| 76ea24e62c | |||
| 0e7c08ba15 | |||
| 196de34b27 | |||
| ae5d7c8952 | |||
| 511f5b8338 | |||
| c2563ca816 | |||
| f9a2cec8b1 | |||
| a4238e0b11 | |||
| 96a2f9a32a | |||
| 346f4b4c20 | |||
| 2fcad17aaa | |||
| 2f423f73a0 | |||
| 01fcc62e64 | |||
| 5b26647c30 | |||
| de7a8c800b | |||
| 14598e9d59 | |||
| a4e7ecca55 | |||
| 6bba0a5311 | |||
| de18436cda | |||
| 08c24d0ffb | |||
| 7f630f4781 | |||
| f824c6c83c | |||
| cae265b05c | |||
| fd2ad2121f | |||
| bec173556d | |||
| 640a4c21dc | |||
| 7d520e08af | |||
| a46a2c8756 | |||
| 83fe77fa8e | |||
| 36c981d55f | |||
| dc091c121f | |||
| 0faa35ab97 | |||
| debbff51e0 | |||
| 78823788b4 | |||
| eda268518b | |||
| 8c8b40f5a8 | |||
| ea112520ea | |||
| 24c36f3184 | |||
| 8f103ecee3 | |||
| b94b11d466 | |||
| ec1df22130 | |||
| ddfc9f9e17 | |||
| 9186bfa3af | |||
| 961fa24faa | |||
| 8c5dd2b0d9 | |||
| 0f5e855849 | |||
| 0eee68144d | |||
| 5697f4aa72 | |||
| 3fd77ab737 | |||
| e84ece8055 | |||
| 9574eadd44 | |||
| 86c127b5f4 | |||
| bcec714aa0 | |||
| ab1a87ecbf | |||
| 50234fde13 | |||
| 9510721ef4 | |||
| 0796cda8c9 | |||
| 9f0f9f93a2 | |||
| 1cfffd8d45 | |||
| 07ddcd1758 | |||
| bedce98a14 | |||
| 3d6a1dd621 | |||
| a62cfe7016 | |||
| abd3917bc8 | |||
| 386be4c44b | |||
| 36c1e9cb1d | |||
| 0674958659 | |||
| 2a73d29b4b | |||
| 45a570fb86 | |||
| 174a7b29d9 | |||
| d2fabe2b2e | |||
| c515db3610 | |||
| a2f5158c79 | |||
| 2f033ff455 | |||
| 66ea773f5f | |||
| 71f71357c2 | |||
| 6ed367834b | |||
| 55e0b5d241 | |||
| 3c8c213ce3 | |||
| 9c20efb6ef | |||
| 92071b9643 | |||
| d27ae57b4a | |||
| bfdc66635d | |||
| 7111fcfb82 | |||
| e5ddc1c430 | |||
| a5112d2463 | |||
| effdd542ca | |||
| 08eb59147c | |||
| a10f725a0a | |||
| 7c2fb0e460 | |||
| 10265a90ca | |||
| 176cd898a0 | |||
| 16ea2616bd | |||
| 78bae1357d | |||
| 533fd05414 | |||
| 201d7d095e | |||
| 1675bfc42a | |||
| 3718efd9d8 | |||
| 391f211015 | |||
| 9dd2b9b1b1 | |||
| 4a8f0979fd | |||
| 6cc287b4eb | |||
| f881418fe4 | |||
| 9e8ef373b0 | |||
| ee0521981b | |||
| 688660228a | |||
| 3d737e3eb1 | |||
| 50d21a4c72 | |||
| e8b41de152 | |||
| 06b2a1f0e4 | |||
| cda34966fe | |||
| 64886eec04 | |||
| e5169e1ef5 | |||
| bdf409ea5c | |||
| 314bda18cb | |||
| 1c0a1cf777 | |||
| ffee72c649 | |||
| 1953eb4cfe | |||
| 25e980e231 | |||
| be7338fa11 | |||
| 326dc07834 | |||
| 73e1dd761a | |||
| 23add71329 | |||
| b1123dfbfe | |||
| 974860ffef | |||
| b86c0b4aaa | |||
| 7ca6a733c8 | |||
| 17945fc24f | |||
| b9a74b0f89 | |||
| 0ac6582225 | |||
| 228d934b88 | |||
| b4f61dea80 | |||
| 09c1ad284b | |||
| 866ed66a9e | |||
| 5d659c359c | |||
| 955767669e | |||
| 95170b5930 | |||
| d1425e77a9 | |||
| da2d1fd8a0 | |||
| 0beaadc2e5 | |||
| 7fd2f1d571 | |||
| 9a83ed8017 | |||
| 978aef3279 | |||
| 846d0a6114 | |||
| 82fbc66388 | |||
| 45fa6eadd0 | |||
| fa4e1e4fc0 | |||
| dba6841815 | |||
| c95ff048d8 | |||
| 89dd6aaf47 | |||
| dece55d558 | |||
| c6b2a1f815 | |||
| 4ffd5115d3 | |||
| 6585294321 | |||
| 536f032a15 | |||
| f10b2f7b14 | |||
| d2c1706825 | |||
| 34e412d4b2 | |||
| 0e5c1b9498 | |||
| 356933f0bf | |||
| 177d3739d4 | |||
| 2fc645486d | |||
| 9573976c7a | |||
| 4b7cc132b1 | |||
| a3c768e899 | |||
| 23db0a9587 | |||
| cb073fa549 | |||
| e94db55b27 | |||
| 3cb83df6cd | |||
| a761db40a2 | |||
| 602ff6ca46 | |||
| 8989ce4e6c | |||
| b78533f86c | |||
| 4b3fad5266 | |||
| 095b38a076 | |||
| 6b9ee4ec76 | |||
| d762b150b0 | |||
| ed89675f78 | |||
| 91e2c8222b | |||
| 79fd273755 | |||
| 6a09f6fdb7 | |||
| 67b774cc47 | |||
| d08c172860 | |||
| 6636bf90c8 | |||
| 190aafa1ef | |||
| 9c4b9d7f1b | |||
| 2e29aaa96b | |||
| d5eff9481d | |||
| b0e13cde89 | |||
| 85f7a85f98 | |||
| da024aad74 | |||
| 236c3539d1 | |||
| 68dce1bc92 | |||
| a125a3866a | |||
| 1c7f8c2457 | |||
| c0ccef70c8 | |||
| fcf93ad789 | |||
| 4505d886f6 | |||
| c6f7ba0b55 | |||
| 51dc2fbc1b | |||
| 34697da8d2 | |||
| b541cb5c3a | |||
| 2d99899bce | |||
| 133a52473d | |||
| 5831148201 | |||
| 86195a1841 | |||
| e95af52d98 | |||
| 221826f457 | |||
| 30378b111a | |||
| 250281884b | |||
| eb61944c0a | |||
| 0da5214a11 | |||
| 6b6c945f59 | |||
| 48e3a2ebf4 | |||
| d44a0a126e | |||
| 7b000b376d | |||
| 5eb81c5853 | |||
| 99a6b32421 | |||
| 3ca8834d44 | |||
| 03e89f382e | |||
| d69af0cafc | |||
| 8f2e3732a2 | |||
| 8a34c2d51e | |||
| d46c65c8fd | |||
| 7911dd927f | |||
| 0ab16b6734 | |||
| 5dd7c105b6 | |||
| 61bbfd6e7c | |||
| 6c28032e9b | |||
| f6a8ff9f2a | |||
| dcde118437 | |||
| 9b25e154e5 | |||
| fa667dbc78 | |||
| ef141403bc | |||
| 5158ed5dc4 | |||
| 971a44feeb | |||
| c9a8934e06 | |||
| fb493b5415 | |||
| 476eb4c2d5 | |||
| 777f48121b | |||
| 0d1496dbcd | |||
| f9edbd453d | |||
| 831541bd61 | |||
| cb24c1e46e | |||
| d8f6b5b643 | |||
| 6314541f66 | |||
| 471f294f07 | |||
| 342b643661 | |||
| 963b07439b | |||
| f935757503 | |||
| f3d040af69 | |||
| 33e2588f00 | |||
| 6eca03264a | |||
| 3a5c07703e | |||
| a5600847e2 | |||
| c715aa2557 | |||
| 06b5a2903d | |||
| 8dee4218f7 | |||
| 65167cf315 | |||
| 38d5ca9236 | |||
| a45b03ded3 | |||
| f0c9202e6d | |||
| eb648e4cb5 | |||
| 75acac5f4c | |||
| 640b5fe668 | |||
| f2dcecc059 | |||
| 17409f04ed | |||
| 88cd8e4027 | |||
| 1570814b45 | |||
| 1d430c1296 | |||
| b0f0bac3e2 | |||
| 94742f38b8 | |||
| c6886c63eb | |||
| 71e1283508 | |||
| 82fe7c61b1 | |||
| 214332fbb9 | |||
| ef1c7db957 | |||
| d6927be07b | |||
| 25fa42b0f0 | |||
| ae372abeaa | |||
| 99766e97a8 | |||
| 57fb4d41f3 | |||
| a834931c4d | |||
| 4711ca4c91 | |||
| ef5441df09 | |||
| e80339aadd | |||
| 3d02551e6a | |||
| 2221cce51a | |||
| 54cf0a40f9 | |||
| ed8379c44b | |||
| 68d8fa7794 | |||
| 46634e1ff3 | |||
| 33daf76a9b | |||
| 948f3a78c1 | |||
| 571b877a8d | |||
| 15ed275cf4 | |||
| 249e6f2e63 | |||
| a462949bc2 | |||
| c61f643332 | |||
| dde599fdd6 | |||
| 2fb32eb9cc | |||
| 4d3c4e4ecf | |||
| 7fe4fc8491 | |||
| 1784409df0 | |||
| 3e9bb483dc | |||
| 34d7db24b2 | |||
| 77f518874e | |||
| 6eec97aa23 | |||
| 235c578a9c | |||
| 251ce1d69c | |||
| 181ced12fc | |||
| 9ef47a1e63 | |||
| d3b14ea3e2 | |||
| 3dd8338028 | |||
| d810537125 | |||
| cc91c5e399 | |||
| 6a0114d612 | |||
| c1e61fdd38 | |||
| 29f91b4024 | |||
| 1ab87150d8 | |||
| 0e44200b9c | |||
| 9941bc12a7 |
@@ -1,2 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
|
||||
@@ -0,0 +1,206 @@
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
#define TWI_CMD_PAGEUPDATE 0x01 // TWI Command to program a flash page
|
||||
#define TWI_CMD_EXECUTEAPP 0x02 // TWI Command to jump to the application program
|
||||
#define TWI_CMD_SETREAD_ADDRESS 0x03 // TWI Command to set address to read from
|
||||
#define TWI_CMD_WRITE_DATA 0x04 // TWI Command send data to the application
|
||||
|
||||
#define TWI_CMD_REBOOT 0x55 // TWI Command to restart back in the bootloader
|
||||
|
||||
#define TWI_SUBCMD_SETDATETIME 0x74 // TWI Command to set the date and time
|
||||
//#define TWI_CMD_BVERSION 0x04 // TWI Command to get the bootloader revision identifier
|
||||
//#define TWI_CMD_ERASEFLASH 0x05 // TWI Command to erase the entire application section of flash memory
|
||||
//#define TWI_CMD_GETERRCONDN 0x07 // TWI Command to get Error condition
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
//#define BOOT_SETTLE_DELAY 100 // Debounce delay for the boot pin in MCU cycles
|
||||
//#define SLAVE_ADDRESS 0xb0 // The address identifier of this slave device on the TWI (I2C) bus
|
||||
#define INTVECT_PAGE_ADDRESS 0x000 // The location of the start of the interrupt vector table address
|
||||
|
||||
|
||||
|
||||
// Select the communcation interfacing type: TWI or USI
|
||||
/*#if defined(__ATTINY25__) | defined(__ATTINY25V__) | \
|
||||
defined(__ATTINY45__) | defined(__ATTINY45V__) | \
|
||||
defined(__ATTINY85__) | defined(__ATTINY85V__) | \
|
||||
defined(__ATTINY24__) | defined(__ATTINY24A__) | \
|
||||
defined(__ATTINY44__) | defined(__ATTINY44A__) | \
|
||||
defined(__ATTINY84__) | defined(__ATTINY84A__) | \
|
||||
defined(__ATTINY2313__) | defined(__ATTINY2313A__) | \
|
||||
defined(__ATTINY4313__) | defined(__ATTINY4313A__) | \
|
||||
defined(__ATTINY261__) | defined(__ATTINY261A__) | \
|
||||
defined(__ATTINY461__) | defined(__ATTINY461A__) | \
|
||||
defined(__ATTINY861__) | defined(__ATTINY861A__) | \
|
||||
defined(__ATTINY43U__) | \
|
||||
defined(__ATTINY87__) | \
|
||||
defined(__ATTINY167__)
|
||||
#define __USI__ // set the communication type as USI
|
||||
#endif */
|
||||
|
||||
#define __USI__ // set the communication type as USI
|
||||
|
||||
|
||||
/*#if defined(__ATTINY48__) | defined(__ATTINY88__) | \
|
||||
defined(__ATMEGA48A__) | defined(__ATMEGA48PA__) | \
|
||||
defined(__ATMEGA48__)
|
||||
#define __TWI__
|
||||
#endif */
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
|
||||
// Page size selection for the controller with 2K flash
|
||||
/*#if defined(__ATTINY25__) | defined(__ATTINY25V__) | \
|
||||
defined(__ATTINY24__) | defined(__ATTINY24A__) | \
|
||||
defined(__ATTINY2313__) | defined(__ATTINY2313A__) | \
|
||||
defined(__ATTINY261__) | defined(__ATTINY261A__)
|
||||
|
||||
// The flash memory page size for these devices
|
||||
#define PAGE_SIZE 32
|
||||
|
||||
// Page 32, the start of bootloader section
|
||||
#define BOOT_PAGE_ADDRESS 0X0400
|
||||
|
||||
// 2KB of flash divided by pages of size 32 bytes
|
||||
#define TOTAL_NO_OF_PAGES 64
|
||||
|
||||
// The number of pages being used for bootloader code
|
||||
#define BOOTLOADER_PAGES (TOTAL_NO_OF_PAGES - BOOT_PAGE_ADDRESS/PAGE_SIZE)
|
||||
|
||||
// For bounds check during page write/erase operation to protect the bootloader code from being corrupted
|
||||
#define LAST_PAGE_NO_TO_BE_ERASED (TOTAL_NO_OF_PAGES - BOOTLOADER_PAGES)
|
||||
#endif */
|
||||
|
||||
// Page size selection for the controller with 4K flash
|
||||
|
||||
/*#if defined(__ATTINY45__) | defined(__ATTINY45V__) | \
|
||||
defined(__ATTINY44__) | defined(__ATTINY44A__) | \
|
||||
defined(__ATTINY4313__) | defined(__ATTINY4313A__) | \
|
||||
defined(__ATTINY461__) | defined(__ATTINY461A__) | \
|
||||
defined(__ATTINY43U__) | \
|
||||
defined(__ATTINY48__) | \
|
||||
defined(__ATMEGA48__) | \
|
||||
defined(__ATMEGA48A__) | defined(__ATMEGA48PA__)
|
||||
|
||||
// The flash memory page size for these devices
|
||||
#define PAGE_SIZE 64
|
||||
|
||||
// Page 48, the start of bootloader section
|
||||
#define BOOT_PAGE_ADDRESS 0X0C00
|
||||
|
||||
// 4KB of flash divided by pages of size 64 bytes
|
||||
#define TOTAL_NO_OF_PAGES 64
|
||||
|
||||
// The number of pages being used for bootloader code
|
||||
#define BOOTLOADER_PAGES (TOTAL_NO_OF_PAGES - BOOT_PAGE_ADDRESS/PAGE_SIZE)
|
||||
|
||||
// For bounds check during page write/erase operation to protect the bootloader code from being corrupted
|
||||
#define LAST_PAGE_NO_TO_BE_ERASED (TOTAL_NO_OF_PAGES - BOOTLOADER_PAGES)
|
||||
#endif */
|
||||
|
||||
|
||||
// Page size selection for the controller with 8K flash
|
||||
/*#if defined(__ATTINY85__) | defined(__ATTINY85V__) | \
|
||||
defined(__ATTINY84__) | defined(__ATTINY84A__) | \
|
||||
defined(__ATTINY861__) | defined(__ATTINY861A__) | \
|
||||
defined(__ATTINY87__) | \
|
||||
defined(__ATTINY88__)
|
||||
|
||||
// The flash memory page size for these devices
|
||||
#define PAGE_SIZE 64
|
||||
|
||||
// Page 112, the start of bootloader section
|
||||
#define BOOT_PAGE_ADDRESS 0X1C00
|
||||
|
||||
// 8KB of flash divided by pages of size 64 bytes
|
||||
#define TOTAL_NO_OF_PAGES 128
|
||||
|
||||
// The number of pages being used for bootloader code
|
||||
#define BOOTLOADER_PAGES (TOTAL_NO_OF_PAGES - BOOT_PAGE_ADDRESS/PAGE_SIZE)
|
||||
|
||||
// // For bounds check during page write/erase operation to protect the bootloader code from being corrupted
|
||||
// #define LAST_PAGE_NO_TO_BE_ERASED (TOTAL_NO_OF_PAGES - BOOTLOADER_PAGES)
|
||||
//#endif*/
|
||||
|
||||
// Page size selection for the controller with 16K flash
|
||||
//#if defined(__ATTINY167__)
|
||||
|
||||
// The flash memory page size for Atiny167
|
||||
#define PAGE_SIZE 128
|
||||
|
||||
// Page 120, the start of bootloader section
|
||||
#define BOOT_PAGE_ADDRESS 0X3800
|
||||
|
||||
// 16KB of flash divided by pages of size 128 bytes
|
||||
#define TOTAL_NO_OF_PAGES 128
|
||||
|
||||
// The number of pages being used for bootloader code
|
||||
#define BOOTLOADER_PAGES (TOTAL_NO_OF_PAGES - BOOT_PAGE_ADDRESS/PAGE_SIZE)
|
||||
|
||||
// For bounds check during page write/erase operation to protect the bootloader code from being corrupted
|
||||
#define LAST_PAGE_NO_TO_BE_ERASED (TOTAL_NO_OF_PAGES - BOOTLOADER_PAGES)
|
||||
|
||||
//#endif
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
// Select the correct Bit name of to SELFPROGRAMming
|
||||
/*#if defined(__ATTINY48__) | defined(__ATTINY48A__) | \
|
||||
defined(__ATTINY88__) | defined(__ATTINY88A__) | \
|
||||
defined(__ATMEGA48__) | \
|
||||
defined(__ATMEGA48A__) | defined(__ATMEGA48PA__)
|
||||
|
||||
#define SELFPROGEN SELFPRGEN
|
||||
|
||||
#endif */
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/*#if defined(__ATTINY25__) | defined(__ATTINY25V__) | \
|
||||
defined(__ATTINY45__) | defined(__ATTINY45V__) | \
|
||||
defined(__ATTINY85__) | defined(__ATTINY85V__) | \
|
||||
defined(__ATTINY87__) | defined(__ATTINY167__) */
|
||||
|
||||
#define SELFPROGEN SPMEN
|
||||
|
||||
//#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
#define WDT_TIMEOUT_8s ( _BV( WDP3 ) | _BV( WDP0 ) ) // Watchdog timeout for inactivity in the boot section
|
||||
#define WDT_TIMEOUT_16ms 0 // Watchdog timeout for system reset (cleanup) before jump to application
|
||||
#define WDT_TIMEOUT_min WDT_TIMEOUT_16ms // The minimum watchdog reset time interval for jump to application
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#define STATUSMASK_SPMBUSY 0x01 // The mask bit for SPM busy status code
|
||||
#define STATUSMASK_BLSCERR 0x02 // The mask bit for attempt to override bootloader section
|
||||
#define STATUSMASK_TWIABORT 0x04 // The mask bit for indicating TWI abort fn called
|
||||
#define STATUSMASK_SLTR_BUSY 0x08 // The mask bit for slave transmit
|
||||
#define STATUSMASK_SLRBAA_BUSY 0x10 // The mask bit for slave receive and ack
|
||||
#define STATUSMASK_SLRBAN_BUSY 0x20 // The mask bit for slave receive and Nack
|
||||
#define STATUSMASK_EEPROM_BUSY 0x40 // The mask bit for EEPROM busy
|
||||
#define STATUSMASK_BOOTLOADER 0x80 // The mask bit for bootloader operations
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
#define EEMEM_ADDR_AVERSION 0x05 // The address in EEPROM where application revision identifier will be stored
|
||||
#define BVERSION 0x96 // This bootloader revision identifier
|
||||
|
||||
|
||||
//static void UpdatePage (uint16_t);
|
||||
|
||||
#ifndef _BV
|
||||
#define _BV( __BIT_POSITION__ ) ( 1 << __BIT_POSITION__ )
|
||||
#endif
|
||||
|
||||
//#ifdef _BV
|
||||
//#warning _BV now stands defined
|
||||
//#endif
|
||||
@@ -0,0 +1,624 @@
|
||||
# Hey Emacs, this is a -*- makefile -*-
|
||||
#----------------------------------------------------------------------------
|
||||
# WinAVR Makefile
|
||||
#
|
||||
# On command line:
|
||||
#
|
||||
# make all = Make software.
|
||||
#
|
||||
# make clean = Clean out built project files.
|
||||
#
|
||||
# make coff = Convert ELF to AVR COFF.
|
||||
#
|
||||
# make extcoff = Convert ELF to AVR Extended COFF.
|
||||
#
|
||||
# make program = Download the hex file to the device, using avrdude.
|
||||
# Please customize the avrdude settings below first!
|
||||
#
|
||||
# make debug = Start either simulavr or avarice as specified for debugging,
|
||||
# with avr-gdb or avr-insight as the front end for debugging.
|
||||
#
|
||||
# make filename.s = Just compile filename.c into the assembler code only.
|
||||
#
|
||||
# make filename.i = Create a preprocessed source file for use in submitting
|
||||
# bug reports to the GCC project.
|
||||
#
|
||||
# To rebuild project do "make clean" then "make all".
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
|
||||
# MCU name
|
||||
MCU = attiny167
|
||||
|
||||
|
||||
# Processor frequency.
|
||||
# This will define a symbol, F_CPU, in all source code files equal to the
|
||||
# processor frequency. You can then use this symbol in your source code to
|
||||
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
|
||||
# automatically to create a 32-bit value in your source code.
|
||||
# Typical values are:
|
||||
# F_CPU = 1000000
|
||||
# F_CPU = 1843200
|
||||
# F_CPU = 2000000
|
||||
# F_CPU = 3686400
|
||||
# F_CPU = 4000000
|
||||
# F_CPU = 7372800
|
||||
# F_CPU = 8000000
|
||||
# F_CPU = 11059200
|
||||
# F_CPU = 14745600
|
||||
# F_CPU = 16000000
|
||||
# F_CPU = 18432000
|
||||
# F_CPU = 20000000
|
||||
F_CPU = 8000000
|
||||
|
||||
|
||||
# Output format. (can be srec, ihex, binary)
|
||||
FORMAT = ihex
|
||||
|
||||
|
||||
# Target file name (without extension).
|
||||
TARGET = TinyApp
|
||||
|
||||
|
||||
# Object files directory
|
||||
# To put object files in current directory, use a dot (.), do NOT make
|
||||
# this an empty or blank macro!
|
||||
OBJDIR = .
|
||||
|
||||
|
||||
# List C source files here. (C dependencies are automatically generated.)
|
||||
SRC = $(TARGET).c
|
||||
|
||||
|
||||
# List C++ source files here. (C dependencies are automatically generated.)
|
||||
CPPSRC =
|
||||
|
||||
|
||||
# List Assembler source files here.
|
||||
# Make them always end in a capital .S. Files ending in a lowercase .s
|
||||
# will not be considered source files but generated files (assembler
|
||||
# output from the compiler), and will be deleted upon "make clean"!
|
||||
# Even though the DOS/Win* filesystem matches both .s and .S the same,
|
||||
# it will preserve the spelling of the filenames, and gcc itself does
|
||||
# care about how the name is spelled on its command-line.
|
||||
ASRC =
|
||||
|
||||
|
||||
# Optimization level, can be [0, 1, 2, 3, s].
|
||||
# 0 = turn off optimization. s = optimize for size.
|
||||
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
|
||||
OPT = s
|
||||
|
||||
|
||||
# Debugging format.
|
||||
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
|
||||
# AVR Studio 4.10 requires dwarf-2.
|
||||
# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
|
||||
#DEBUG = stabs
|
||||
DEBUG = dwarf-2
|
||||
|
||||
|
||||
# List any extra directories to look for include files here.
|
||||
# Each directory must be seperated by a space.
|
||||
# Use forward slashes for directory separators.
|
||||
# For a directory that has spaces, enclose it in quotes.
|
||||
EXTRAINCDIRS = c:\progs\iccv7avr\include
|
||||
|
||||
|
||||
# Compiler flag to set the C Standard level.
|
||||
# c89 = "ANSI" C
|
||||
# gnu89 = c89 plus GCC extensions
|
||||
# c99 = ISO C99 standard (not yet fully implemented)
|
||||
# gnu99 = c99 plus GCC extensions
|
||||
CSTANDARD = -std=gnu99
|
||||
|
||||
|
||||
# Place -D or -U options here for C sources
|
||||
CDEFS = -DF_CPU=$(F_CPU)UL
|
||||
|
||||
|
||||
# Place -D or -U options here for ASM sources
|
||||
ADEFS = -DF_CPU=$(F_CPU)
|
||||
|
||||
|
||||
# Place -D or -U options here for C++ sources
|
||||
CPPDEFS = -DF_CPU=$(F_CPU)UL
|
||||
#CPPDEFS += -D__STDC_LIMIT_MACROS
|
||||
#CPPDEFS += -D__STDC_CONSTANT_MACROS
|
||||
|
||||
|
||||
|
||||
#---------------- Compiler Options C ----------------
|
||||
# -g*: generate debugging information
|
||||
# -O*: optimization level
|
||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
||||
# -Wall...: warning level
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -adhlns...: create assembler listing
|
||||
CFLAGS = -g$(DEBUG)
|
||||
CFLAGS += $(CDEFS)
|
||||
CFLAGS += -O$(OPT)
|
||||
CFLAGS += -funsigned-char
|
||||
CFLAGS += -funsigned-bitfields
|
||||
CFLAGS += -fpack-struct
|
||||
CFLAGS += -fshort-enums
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wno-main
|
||||
CFLAGS += -Wstrict-prototypes
|
||||
#CFLAGS += -mshort-calls
|
||||
#CFLAGS += -fno-unit-at-a-time
|
||||
#CFLAGS += -Wundef
|
||||
#CFLAGS += -Wunreachable-code
|
||||
#CFLAGS += -Wsign-compare
|
||||
CFLAGS += -Wa,-adlns=$(<:%.c=$(OBJDIR)/%.lst)
|
||||
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
||||
CFLAGS += $(CSTANDARD)
|
||||
# Next line dumps rtl file
|
||||
#CFLAGS += -dr
|
||||
#CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
|
||||
|
||||
|
||||
#---------------- Compiler Options C++ ----------------
|
||||
# -g*: generate debugging information
|
||||
# -O*: optimization level
|
||||
# -f...: tuning, see GCC manual and avr-libc documentation
|
||||
# -Wall...: warning level
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -adhlns...: create assembler listing
|
||||
CPPFLAGS = -g$(DEBUG)
|
||||
CPPFLAGS += $(CPPDEFS)
|
||||
CPPFLAGS += -O$(OPT)
|
||||
CPPFLAGS += -funsigned-char
|
||||
CPPFLAGS += -funsigned-bitfields
|
||||
CPPFLAGS += -fpack-struct
|
||||
CPPFLAGS += -fshort-enums
|
||||
CPPFLAGS += -fno-exceptions
|
||||
CPPFLAGS += -Wall
|
||||
CFLAGS += -Wundef
|
||||
#CPPFLAGS += -mshort-calls
|
||||
#CPPFLAGS += -fno-unit-at-a-time
|
||||
#CPPFLAGS += -Wstrict-prototypes
|
||||
#CPPFLAGS += -Wunreachable-code
|
||||
#CPPFLAGS += -Wsign-compare
|
||||
CPPFLAGS += -Wa,-adlns=$(<:%.cpp=$(OBJDIR)/%.lst)
|
||||
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
||||
#CPPFLAGS += $(CSTANDARD)
|
||||
#CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
|
||||
|
||||
|
||||
#---------------- Assembler Options ----------------
|
||||
# -Wa,...: tell GCC to pass this to the assembler.
|
||||
# -adhlns: create listing
|
||||
# -gstabs: have the assembler create line number information; note that
|
||||
# for use in COFF files, additional information about filenames
|
||||
# and function names needs to be present in the assembler source
|
||||
# files -- see avr-libc docs [FIXME: not yet described there]
|
||||
# -listing-cont-lines: Sets the maximum number of continuation lines of hex
|
||||
# dump that will be displayed for a given single line of source input.
|
||||
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100
|
||||
|
||||
|
||||
#---------------- Library Options ----------------
|
||||
# Minimalistic printf version
|
||||
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
|
||||
|
||||
# Floating point printf version (requires MATH_LIB = -lm below)
|
||||
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
|
||||
|
||||
# If this is left blank, then it will use the Standard printf version.
|
||||
PRINTF_LIB =
|
||||
#PRINTF_LIB = $(PRINTF_LIB_MIN)
|
||||
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)
|
||||
|
||||
|
||||
# Minimalistic scanf version
|
||||
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
|
||||
|
||||
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
|
||||
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
|
||||
|
||||
# If this is left blank, then it will use the Standard scanf version.
|
||||
SCANF_LIB =
|
||||
#SCANF_LIB = $(SCANF_LIB_MIN)
|
||||
#SCANF_LIB = $(SCANF_LIB_FLOAT)
|
||||
|
||||
|
||||
MATH_LIB = -lm
|
||||
|
||||
|
||||
# List any extra directories to look for libraries here.
|
||||
# Each directory must be seperated by a space.
|
||||
# Use forward slashes for directory separators.
|
||||
# For a directory that has spaces, enclose it in quotes.
|
||||
EXTRALIBDIRS =
|
||||
|
||||
|
||||
|
||||
#---------------- External Memory Options ----------------
|
||||
|
||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
|
||||
# used for variables (.data/.bss) and heap (malloc()).
|
||||
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
|
||||
|
||||
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
|
||||
# only used for heap (malloc()).
|
||||
#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
|
||||
|
||||
EXTMEMOPTS =
|
||||
|
||||
|
||||
|
||||
#---------------- Linker Options ----------------
|
||||
# -Wl,...: tell GCC to pass this to linker.
|
||||
# -Map: create map file
|
||||
# --cref: add cross reference to map file
|
||||
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
|
||||
LDFLAGS += $(EXTMEMOPTS)
|
||||
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
|
||||
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
|
||||
LDFLAGS += -Wl,--section-start=.text=0x00D0
|
||||
LDFLAGS += -Wl,--section-start=.vectors=0x0080
|
||||
LDFLAGS += -T avr3-167.ld
|
||||
LDFLAGS += -N
|
||||
|
||||
|
||||
|
||||
#---------------- Programming Options (avrdude) ----------------
|
||||
|
||||
# Programming hardware: alf avr910 avrisp bascom bsd
|
||||
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
|
||||
#
|
||||
# Type: avrdude -c ?
|
||||
# to get a full listing.
|
||||
#
|
||||
AVRDUDE_PROGRAMMER = stk500
|
||||
|
||||
# com1 = serial port. Use lpt1 to connect to parallel port.
|
||||
AVRDUDE_PORT = com3
|
||||
|
||||
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
|
||||
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
|
||||
|
||||
|
||||
# Uncomment the following if you want avrdude's erase cycle counter.
|
||||
# Note that this counter needs to be initialized first using -Yn,
|
||||
# see avrdude manual.
|
||||
#AVRDUDE_ERASE_COUNTER = -y
|
||||
|
||||
# Uncomment the following if you do /not/ wish a verification to be
|
||||
# performed after programming the device.
|
||||
#AVRDUDE_NO_VERIFY = -V
|
||||
|
||||
# Increase verbosity level. Please use this when submitting bug
|
||||
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
|
||||
# to submit bug reports.
|
||||
#AVRDUDE_VERBOSE = -v -v
|
||||
|
||||
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
|
||||
|
||||
|
||||
|
||||
#---------------- Debugging Options ----------------
|
||||
|
||||
# For simulavr only - target MCU frequency.
|
||||
DEBUG_MFREQ = $(F_CPU)
|
||||
|
||||
# Set the DEBUG_UI to either gdb or insight.
|
||||
# DEBUG_UI = gdb
|
||||
DEBUG_UI = insight
|
||||
|
||||
# Set the debugging back-end to either avarice, simulavr.
|
||||
DEBUG_BACKEND = avarice
|
||||
#DEBUG_BACKEND = simulavr
|
||||
|
||||
# GDB Init Filename.
|
||||
GDBINIT_FILE = __avr_gdbinit
|
||||
|
||||
# When using avarice settings for the JTAG
|
||||
JTAG_DEV = /dev/com1
|
||||
|
||||
# Debugging port used to communicate between GDB / avarice / simulavr.
|
||||
DEBUG_PORT = 4242
|
||||
|
||||
# Debugging host used to communicate between GDB / avarice / simulavr, normally
|
||||
# just set to localhost unless doing some sort of crazy debugging when
|
||||
# avarice is running on a different computer.
|
||||
DEBUG_HOST = localhost
|
||||
|
||||
|
||||
|
||||
#============================================================================
|
||||
|
||||
|
||||
# Define programs and commands.
|
||||
SHELL = sh
|
||||
CC = avr-gcc
|
||||
OBJCOPY = avr-objcopy
|
||||
OBJDUMP = avr-objdump
|
||||
SIZE = avr-size
|
||||
AR = avr-ar rcs
|
||||
NM = avr-nm
|
||||
AVRDUDE = avrdude
|
||||
REMOVE = rm -f
|
||||
REMOVEDIR = rm -rf
|
||||
COPY = cp
|
||||
WINSHELL = cmd
|
||||
|
||||
|
||||
# Define Messages
|
||||
# English
|
||||
MSG_ERRORS_NONE = Errors: none
|
||||
MSG_BEGIN = -------- begin --------
|
||||
MSG_END = -------- end --------
|
||||
MSG_SIZE_BEFORE = Size before:
|
||||
MSG_SIZE_AFTER = Size after:
|
||||
MSG_COFF = Converting to AVR COFF:
|
||||
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
|
||||
MSG_FLASH = Creating load file for Flash:
|
||||
MSG_EEPROM = Creating load file for EEPROM:
|
||||
MSG_EXTENDED_LISTING = Creating Extended Listing:
|
||||
MSG_SYMBOL_TABLE = Creating Symbol Table:
|
||||
MSG_LINKING = Linking:
|
||||
MSG_COMPILING = Compiling C:
|
||||
MSG_COMPILING_CPP = Compiling C++:
|
||||
MSG_ASSEMBLING = Assembling:
|
||||
MSG_CLEANING = Cleaning project:
|
||||
MSG_CREATING_LIBRARY = Creating library:
|
||||
|
||||
|
||||
|
||||
|
||||
# Define all object files.
|
||||
OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
|
||||
|
||||
# Define all listing files.
|
||||
LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)
|
||||
|
||||
|
||||
# Compiler flags to generate dependency files.
|
||||
GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d
|
||||
|
||||
|
||||
# Combine all necessary flags and optional flags.
|
||||
# Add target processor to flags.
|
||||
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
|
||||
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)
|
||||
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Default target.
|
||||
all: begin gccversion sizebefore build sizeafter end
|
||||
|
||||
# Change the build target to build a HEX file or a library.
|
||||
build: elf hex eep lss sym bin
|
||||
#build: lib
|
||||
|
||||
|
||||
elf: $(TARGET).elf
|
||||
hex: $(TARGET).hex
|
||||
bin: $(TARGET).bin
|
||||
eep: $(TARGET).eep
|
||||
lss: $(TARGET).lss
|
||||
sym: $(TARGET).sym
|
||||
LIBNAME=lib$(TARGET).a
|
||||
lib: $(LIBNAME)
|
||||
|
||||
|
||||
|
||||
# Eye candy.
|
||||
# AVR Studio 3.x does not check make's exit code but relies on
|
||||
# the following magic strings to be generated by the compile job.
|
||||
begin:
|
||||
@echo
|
||||
@echo $(MSG_BEGIN)
|
||||
|
||||
end:
|
||||
@echo $(MSG_END)
|
||||
@echo
|
||||
|
||||
|
||||
# Display size of file.
|
||||
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
|
||||
ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf
|
||||
|
||||
sizebefore:
|
||||
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
|
||||
2>/dev/null; echo; fi
|
||||
|
||||
sizeafter:
|
||||
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
|
||||
2>/dev/null; echo; fi
|
||||
|
||||
|
||||
|
||||
# Display compiler version information.
|
||||
gccversion :
|
||||
@$(CC) --version
|
||||
|
||||
|
||||
|
||||
# Program the device.
|
||||
program: $(TARGET).hex $(TARGET).eep
|
||||
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
|
||||
|
||||
|
||||
# Generate avr-gdb config/init file which does the following:
|
||||
# define the reset signal, load the target file, connect to target, and set
|
||||
# a breakpoint at main().
|
||||
gdb-config:
|
||||
@$(REMOVE) $(GDBINIT_FILE)
|
||||
@echo define reset >> $(GDBINIT_FILE)
|
||||
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
|
||||
@echo end >> $(GDBINIT_FILE)
|
||||
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
|
||||
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)
|
||||
ifeq ($(DEBUG_BACKEND),simulavr)
|
||||
@echo load >> $(GDBINIT_FILE)
|
||||
endif
|
||||
@echo break main >> $(GDBINIT_FILE)
|
||||
|
||||
debug: gdb-config $(TARGET).elf
|
||||
ifeq ($(DEBUG_BACKEND), avarice)
|
||||
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
|
||||
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
|
||||
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
|
||||
@$(WINSHELL) /c pause
|
||||
|
||||
else
|
||||
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
|
||||
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
|
||||
endif
|
||||
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)
|
||||
|
||||
|
||||
|
||||
|
||||
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
|
||||
COFFCONVERT = $(OBJCOPY) --debugging
|
||||
COFFCONVERT += --change-section-address .data-0x800000
|
||||
COFFCONVERT += --change-section-address .bss-0x800000
|
||||
COFFCONVERT += --change-section-address .noinit-0x800000
|
||||
COFFCONVERT += --change-section-address .eeprom-0x810000
|
||||
|
||||
|
||||
|
||||
coff: $(TARGET).elf
|
||||
@echo
|
||||
@echo $(MSG_COFF) $(TARGET).cof
|
||||
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
|
||||
|
||||
|
||||
extcoff: $(TARGET).elf
|
||||
@echo
|
||||
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
|
||||
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
|
||||
|
||||
|
||||
|
||||
# Create final output files (.hex, .eep) from ELF output file.
|
||||
%.hex: %.elf
|
||||
@echo
|
||||
@echo $(MSG_FLASH) $@
|
||||
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
|
||||
|
||||
%.bin: %.elf
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
|
||||
%.eep: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EEPROM) $@
|
||||
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
|
||||
--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0
|
||||
|
||||
# Create extended listing file from ELF output file.
|
||||
%.lss: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EXTENDED_LISTING) $@
|
||||
$(OBJDUMP) -h -S $< > $@
|
||||
|
||||
# Create a symbol table from ELF output file.
|
||||
%.sym: %.elf
|
||||
@echo
|
||||
@echo $(MSG_SYMBOL_TABLE) $@
|
||||
$(NM) -n $< > $@
|
||||
|
||||
|
||||
|
||||
# Create library from object files.
|
||||
.SECONDARY : $(TARGET).a
|
||||
.PRECIOUS : $(OBJ)
|
||||
%.a: $(OBJ)
|
||||
@echo
|
||||
@echo $(MSG_CREATING_LIBRARY) $@
|
||||
$(AR) $@ $(OBJ)
|
||||
|
||||
|
||||
# Link: create ELF output file from object files.
|
||||
.SECONDARY : $(TARGET).elf
|
||||
.PRECIOUS : $(OBJ)
|
||||
%.elf: $(OBJ)
|
||||
@echo
|
||||
@echo $(MSG_LINKING) $@
|
||||
$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)
|
||||
|
||||
|
||||
# Compile: create object files from C source files.
|
||||
$(OBJDIR)/%.o : %.c
|
||||
@echo
|
||||
@echo $(MSG_COMPILING) $<
|
||||
$(CC) -c $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Compile: create object files from C++ source files.
|
||||
$(OBJDIR)/%.o : %.cpp
|
||||
@echo
|
||||
@echo $(MSG_COMPILING_CPP) $<
|
||||
$(CC) -c $(ALL_CPPFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Compile: create assembler files from C source files.
|
||||
%.s : %.c
|
||||
$(CC) -S $(ALL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Compile: create assembler files from C++ source files.
|
||||
%.s : %.cpp
|
||||
$(CC) -S $(ALL_CPPFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Assemble: create object files from assembler source files.
|
||||
$(OBJDIR)/%.o : %.S
|
||||
@echo
|
||||
@echo $(MSG_ASSEMBLING) $<
|
||||
$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Create preprocessed source for use in sending a bug report.
|
||||
%.i : %.c
|
||||
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@
|
||||
|
||||
|
||||
# Target: clean project.
|
||||
clean: begin clean_list end
|
||||
|
||||
clean_list :
|
||||
@echo
|
||||
@echo $(MSG_CLEANING)
|
||||
$(REMOVE) $(TARGET).bin
|
||||
$(REMOVE) $(TARGET).hex
|
||||
$(REMOVE) $(TARGET).eep
|
||||
$(REMOVE) $(TARGET).cof
|
||||
$(REMOVE) $(TARGET).elf
|
||||
$(REMOVE) $(TARGET).map
|
||||
$(REMOVE) $(TARGET).sym
|
||||
$(REMOVE) $(TARGET).lss
|
||||
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
|
||||
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
|
||||
$(REMOVE) $(SRC:.c=.s)
|
||||
$(REMOVE) $(SRC:.c=.d)
|
||||
$(REMOVE) $(SRC:.c=.i)
|
||||
$(REMOVEDIR) .dep
|
||||
|
||||
|
||||
# Create object files directory
|
||||
$(shell mkdir $(OBJDIR) 2>/dev/null)
|
||||
|
||||
|
||||
# Include the dependency files.
|
||||
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
|
||||
|
||||
|
||||
# Listing of phony targets.
|
||||
.PHONY : all begin finish end sizebefore sizeafter gccversion \
|
||||
build elf hex eep lss sym coff extcoff \
|
||||
clean clean_list program debug gdb-config
|
||||
|
||||
|
||||
|
||||
|
||||
+1070
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,174 @@
|
||||
#ifdef __USI__
|
||||
|
||||
/****************************************************************************/
|
||||
static void USI_TWI_SLAVE_Init( void );
|
||||
static void USI_TWI_SLAVE_Abort(void);
|
||||
static void USI_TWI_SLAVE_ReadAndProcessPacket(void);
|
||||
static void USI_TWI_SLAVE_Process_Start_Condition(void);
|
||||
void USI_TWI_SLAVE_Process_Overflow_Condition(void);
|
||||
|
||||
// void prog_buffer_set_byte(uint8_t );
|
||||
|
||||
// uint8_t bootloader_exit;
|
||||
uint8_t Run_boot ;
|
||||
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
// TWI write states.
|
||||
#define USI_TWI_SLAVE_WRITE_ADDR_HI_BYTE (0x00)
|
||||
#define USI_TWI_SLAVE_WRITE_ADDR_LO_BYTE (0x01)
|
||||
#define USI_TWI_SLAVE_WRITE_DATA_BYTE (0x02)
|
||||
|
||||
// TWI overflow states.
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_NONE (0x00)
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_ACK_PR_RX (0x01)
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_DATA_RX (0x02)
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_ACK_PR_TX (0x03)
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_PR_ACK_TX (0x04)
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX (0x05)
|
||||
|
||||
// newly added ..
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_CMD_RX (0x06)
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX_AVERSION (0x07)
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX_BVERSION (0x08)
|
||||
#define USI_TWI_SLAVE_OVERFLOW_STATE_DATA_TX_GETERRCONDN (0x09)
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// typedef unsigned char uint8_t;
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
///////////////// Driver Buffer Definitions //////////////////////
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// 1,2,4,8,16,32,64,128 or 256 bytes are allowed buffer sizes
|
||||
|
||||
#define TWI_RX_BUFFER_SIZE (16)
|
||||
#define TWI_RX_BUFFER_MASK ( TWI_RX_BUFFER_SIZE - 1 )
|
||||
|
||||
#if ( TWI_RX_BUFFER_SIZE & TWI_RX_BUFFER_MASK )
|
||||
#error TWI RX buffer size is not a power of 2
|
||||
#endif
|
||||
|
||||
// 1,2,4,8,16,32,64,128 or 256 bytes are allowed buffer sizes
|
||||
|
||||
#define TWI_TX_BUFFER_SIZE (16)
|
||||
#define TWI_TX_BUFFER_MASK ( TWI_TX_BUFFER_SIZE - 1 )
|
||||
|
||||
#if ( TWI_TX_BUFFER_SIZE & TWI_TX_BUFFER_MASK )
|
||||
#error TWI TX buffer size is not a power of 2
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define USI_SLAVE_CHECK_ADDRESS (0x00)
|
||||
#define USI_SLAVE_SEND_DATA (0x01)
|
||||
#define USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA (0x02)
|
||||
#define USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA (0x03)
|
||||
#define USI_SLAVE_REQUEST_DATA (0x04)
|
||||
#define USI_SLAVE_GET_DATA_AND_SEND_ACK (0x05)
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/*#if defined(__ATTINY2313__) | defined(__ATTINY2313A__) | \
|
||||
defined(__ATTINY4313__) | defined(__ATTINY4313A__) */
|
||||
|
||||
// #define DDR_USI DDRB
|
||||
// #define PORT_USI PORTB
|
||||
// #define PIN_USI PINB
|
||||
// #define PORT_USI_SDA PORTB5
|
||||
// #define PORT_USI_SCL PORTB7
|
||||
// #define PIN_USI_SDA PINB5
|
||||
// #define PIN_USI_SCL PINB7
|
||||
// #define USI_START_COND_INT USISIF
|
||||
// #define USI_START_VECTOR USI_STRT_vect
|
||||
// #define USI_OVERFLOW_VECTOR USI_OVF_vect
|
||||
//#endif
|
||||
|
||||
/*#if defined(__ATTINY25__) | defined(__ATTINY25V__) | \
|
||||
// defined(__ATTINY45__) | defined(__ATTINY45V__) | \
|
||||
// defined(__ATTINY85__) | defined(__ATTINY85V__) */
|
||||
// #define DDR_USI DDRB
|
||||
// #define PORT_USI PORTB
|
||||
// #define PIN_USI PINB
|
||||
// #define PORT_USI_SDA PORTB0
|
||||
// #define PORT_USI_SCL PORTB2
|
||||
// #define PIN_USI_SDA PINB0
|
||||
// #define PIN_USI_SCL PINB2
|
||||
// #define USI_START_COND_INT USICIF
|
||||
// #define USI_START_VECTOR USI_START_vect
|
||||
// #define USI_OVERFLOW_VECTOR USI_OVF_vect
|
||||
//#endif
|
||||
|
||||
/*#if defined(__ATTINY24__) | defined(__ATTINY24A__) | \
|
||||
defined(__ATTINY44__) | defined(__ATTINY44A__) | \
|
||||
defined(__ATTINY84__) | defined(__ATTINY84V__) */
|
||||
|
||||
// #define DDR_USI DDRA
|
||||
// #define PORT_USI PORTA
|
||||
// #define PIN_USI PINA
|
||||
// #define PORT_USI_SDA PORTA6
|
||||
// #define PORT_USI_SCL PORTA4
|
||||
// #define PIN_USI_SDA PINA6
|
||||
// #define PIN_USI_SCL PINA4
|
||||
// #define USI_START_COND_INT USISIF
|
||||
// #define USI_START_VECTOR USI_START_vect
|
||||
// #define USI_OVERFLOW_VECTOR USI_OVF_vect
|
||||
//#endif
|
||||
|
||||
|
||||
/*#if defined(__ATTINY261__) | defined(__ATTINY261A__) | \
|
||||
defined(__ATTINY461__) | defined(__ATTINY461A__) | \
|
||||
defined(__ATTINY861A__) | defined(__ATTINY861A__) */
|
||||
|
||||
// #define DDR_USI DDRB
|
||||
// #define PORT_USI PORTB
|
||||
// #define PIN_USI PINB
|
||||
// #define PORT_USI_SDA PORTB0
|
||||
// #define PORT_USI_SCL PORTB2
|
||||
// #define PIN_USI_SDA PINB0
|
||||
// #define PIN_USI_SCL PINB2
|
||||
// #define USI_START_COND_INT USISIF
|
||||
// #define USI_START_VECTOR USI_START_vect
|
||||
// #define USI_OVERFLOW_VECTOR USI_OVF_vect
|
||||
//#endif
|
||||
|
||||
|
||||
//#if defined(__ATTINY43U__)
|
||||
// #define DDR_USI DDRB
|
||||
// #define PORT_USI PORTB
|
||||
// #define PIN_USI PINB
|
||||
// #define PORT_USI_SDA PORTB4
|
||||
// #define PORT_USI_SCL PORTB6
|
||||
// #define PIN_USI_SDA PINB4
|
||||
// #define PIN_USI_SCL PINB6
|
||||
// #define USI_START_COND_INT USISIF
|
||||
// #define USI_START_VECTOR USI_START_vect
|
||||
// #define USI_OVERFLOW_VECTOR USI_OVF_vect
|
||||
//#endif
|
||||
|
||||
|
||||
//#if defined(__ATTINY87__) | defined(__ATTINY167__)
|
||||
|
||||
#define DDR_USI DDRB
|
||||
#define PORT_USI PORTB
|
||||
#define PIN_USI PINB
|
||||
#define PORT_USI_SDA PORTB0
|
||||
#define PORT_USI_SCL PORTB2
|
||||
#define PIN_USI_SDA PINB0
|
||||
#define PIN_USI_SCL PINB2
|
||||
#define USI_START_COND_INT USISIF
|
||||
#define USI_START_VECTOR USI_START_vect
|
||||
#define USI_OVERFLOW_VECTOR USI_OVF_vect
|
||||
//#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
/* Default linker script, for normal executables */
|
||||
OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
|
||||
OUTPUT_ARCH(avr:3)
|
||||
MEMORY
|
||||
{
|
||||
text (rx) : ORIGIN = 0, LENGTH = 16K
|
||||
data (rw!x) : ORIGIN = 0x800060, LENGTH = 0xffa0
|
||||
eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K
|
||||
fuse (rw!x) : ORIGIN = 0x820000, LENGTH = 1K
|
||||
lock (rw!x) : ORIGIN = 0x830000, LENGTH = 1K
|
||||
signature (rw!x) : ORIGIN = 0x840000, LENGTH = 1K
|
||||
}
|
||||
SECTIONS
|
||||
{
|
||||
/* Read-only sections, merged into text segment: */
|
||||
.hash : { *(.hash) }
|
||||
.dynsym : { *(.dynsym) }
|
||||
.dynstr : { *(.dynstr) }
|
||||
.gnu.version : { *(.gnu.version) }
|
||||
.gnu.version_d : { *(.gnu.version_d) }
|
||||
.gnu.version_r : { *(.gnu.version_r) }
|
||||
.rel.init : { *(.rel.init) }
|
||||
.rela.init : { *(.rela.init) }
|
||||
.rel.text :
|
||||
{
|
||||
*(.rel.text)
|
||||
*(.rel.text.*)
|
||||
*(.rel.gnu.linkonce.t*)
|
||||
}
|
||||
.rela.text :
|
||||
{
|
||||
*(.rela.text)
|
||||
*(.rela.text.*)
|
||||
*(.rela.gnu.linkonce.t*)
|
||||
}
|
||||
.rel.fini : { *(.rel.fini) }
|
||||
.rela.fini : { *(.rela.fini) }
|
||||
.rel.rodata :
|
||||
{
|
||||
*(.rel.rodata)
|
||||
*(.rel.rodata.*)
|
||||
*(.rel.gnu.linkonce.r*)
|
||||
}
|
||||
.rela.rodata :
|
||||
{
|
||||
*(.rela.rodata)
|
||||
*(.rela.rodata.*)
|
||||
*(.rela.gnu.linkonce.r*)
|
||||
}
|
||||
.rel.data :
|
||||
{
|
||||
*(.rel.data)
|
||||
*(.rel.data.*)
|
||||
*(.rel.gnu.linkonce.d*)
|
||||
}
|
||||
.rela.data :
|
||||
{
|
||||
*(.rela.data)
|
||||
*(.rela.data.*)
|
||||
*(.rela.gnu.linkonce.d*)
|
||||
}
|
||||
.rel.ctors : { *(.rel.ctors) }
|
||||
.rela.ctors : { *(.rela.ctors) }
|
||||
.rel.dtors : { *(.rel.dtors) }
|
||||
.rela.dtors : { *(.rela.dtors) }
|
||||
.rel.got : { *(.rel.got) }
|
||||
.rela.got : { *(.rela.got) }
|
||||
.rel.bss : { *(.rel.bss) }
|
||||
.rela.bss : { *(.rela.bss) }
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rela.plt : { *(.rela.plt) }
|
||||
/* Internal text space or external memory. */
|
||||
.vectors :
|
||||
{
|
||||
*(.vectors)
|
||||
KEEP(*(.vectors))
|
||||
}
|
||||
.text :
|
||||
{
|
||||
/* For data that needs to reside in the lower 64k of progmem. */
|
||||
*(.progmem.gcc*)
|
||||
*(.progmem*)
|
||||
. = ALIGN(2);
|
||||
__trampolines_start = . ;
|
||||
/* The jump trampolines for the 16-bit limited relocs will reside here. */
|
||||
*(.trampolines)
|
||||
*(.trampolines*)
|
||||
__trampolines_end = . ;
|
||||
/* For future tablejump instruction arrays for 3 byte pc devices.
|
||||
We don't relax jump/call instructions within these sections. */
|
||||
*(.jumptables)
|
||||
*(.jumptables*)
|
||||
/* For code that needs to reside in the lower 128k progmem. */
|
||||
*(.lowtext)
|
||||
*(.lowtext*)
|
||||
__ctors_start = . ;
|
||||
*(.ctors)
|
||||
__ctors_end = . ;
|
||||
__dtors_start = . ;
|
||||
*(.dtors)
|
||||
__dtors_end = . ;
|
||||
KEEP(SORT(*)(.ctors))
|
||||
KEEP(SORT(*)(.dtors))
|
||||
/* From this point on, we don't bother about wether the insns are
|
||||
below or above the 16 bits boundary. */
|
||||
*(.init0) /* Start here after reset. */
|
||||
KEEP (*(.init0))
|
||||
*(.init1)
|
||||
KEEP (*(.init1))
|
||||
*(.init2) /* Clear __zero_reg__, set up stack pointer. */
|
||||
KEEP (*(.init2))
|
||||
*(.init3)
|
||||
KEEP (*(.init3))
|
||||
*(.init4) /* Initialize data and BSS. */
|
||||
KEEP (*(.init4))
|
||||
*(.init5)
|
||||
KEEP (*(.init5))
|
||||
*(.init6) /* C++ constructors. */
|
||||
KEEP (*(.init6))
|
||||
*(.init7)
|
||||
KEEP (*(.init7))
|
||||
*(.init8)
|
||||
KEEP (*(.init8))
|
||||
*(.init9) /* Call main(). */
|
||||
KEEP (*(.init9))
|
||||
*(.text)
|
||||
. = ALIGN(2);
|
||||
*(.text.*)
|
||||
. = ALIGN(2);
|
||||
*(.fini9) /* _exit() starts here. */
|
||||
KEEP (*(.fini9))
|
||||
*(.fini8)
|
||||
KEEP (*(.fini8))
|
||||
*(.fini7)
|
||||
KEEP (*(.fini7))
|
||||
*(.fini6) /* C++ destructors. */
|
||||
KEEP (*(.fini6))
|
||||
*(.fini5)
|
||||
KEEP (*(.fini5))
|
||||
*(.fini4)
|
||||
KEEP (*(.fini4))
|
||||
*(.fini3)
|
||||
KEEP (*(.fini3))
|
||||
*(.fini2)
|
||||
KEEP (*(.fini2))
|
||||
*(.fini1)
|
||||
KEEP (*(.fini1))
|
||||
*(.fini0) /* Infinite loop after program termination. */
|
||||
KEEP (*(.fini0))
|
||||
_etext = . ;
|
||||
} > text
|
||||
.data : AT (ADDR (.text) + SIZEOF (.text))
|
||||
{
|
||||
PROVIDE (__data_start = .) ;
|
||||
*(.data)
|
||||
*(.data*)
|
||||
*(.rodata) /* We need to include .rodata here if gcc is used */
|
||||
*(.rodata*) /* with -fdata-sections. */
|
||||
*(.gnu.linkonce.d*)
|
||||
. = ALIGN(2);
|
||||
_edata = . ;
|
||||
PROVIDE (__data_end = .) ;
|
||||
} > data
|
||||
.bss : AT (ADDR (.bss))
|
||||
{
|
||||
PROVIDE (__bss_start = .) ;
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
PROVIDE (__bss_end = .) ;
|
||||
} > data
|
||||
__data_load_start = LOADADDR(.data);
|
||||
__data_load_end = __data_load_start + SIZEOF(.data);
|
||||
/* Global data not cleared after reset. */
|
||||
.noinit :
|
||||
{
|
||||
PROVIDE (__noinit_start = .) ;
|
||||
*(.noinit*)
|
||||
PROVIDE (__noinit_end = .) ;
|
||||
_end = . ;
|
||||
PROVIDE (__heap_start = .) ;
|
||||
} > data
|
||||
.eeprom :
|
||||
{
|
||||
*(.eeprom*)
|
||||
__eeprom_end = . ;
|
||||
} > eeprom
|
||||
.fuse :
|
||||
{
|
||||
KEEP(*(.fuse))
|
||||
KEEP(*(.lfuse))
|
||||
KEEP(*(.hfuse))
|
||||
KEEP(*(.efuse))
|
||||
} > fuse
|
||||
.lock :
|
||||
{
|
||||
KEEP(*(.lock*))
|
||||
} > lock
|
||||
.signature :
|
||||
{
|
||||
KEEP(*(.signature*))
|
||||
} > signature
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
# ----------------------------------------------------------------------------
|
||||
# ATMEL Microcontroller Software Support
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 2011, Atmel Corporation
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# - Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the disclaimer below.
|
||||
#
|
||||
# Atmel's name may not be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# Makefile for compiling the applet-serial flash project
|
||||
|
||||
# Chip & board used for compilation
|
||||
# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
|
||||
CHIP = atsam3s4
|
||||
BOARD = atsam3s4_ek
|
||||
DYN = OFF
|
||||
|
||||
# Makefile for compiling applet-serialflash applet.
|
||||
|
||||
ifeq (atsam3s4,$(CHIP))
|
||||
BOARD_DIR = at91sam3s4-ek
|
||||
endif
|
||||
|
||||
ifeq (atsam3s2,$(CHIP))
|
||||
BOARD_DIR = at91sam3s2-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9g15,$(CHIP))
|
||||
BOARD =sam9g15_ek
|
||||
BOARD_DIR = at91sam9g15-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9g25,$(CHIP))
|
||||
BOARD =sam9g25_ek
|
||||
BOARD_DIR = at91sam9g25-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9g35,$(CHIP))
|
||||
BOARD =sam9g35_ek
|
||||
BOARD_DIR = at91sam9g35-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9x25,$(CHIP))
|
||||
BOARD =sam9x25_ek
|
||||
BOARD_DIR = at91sam9x25-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9x35,$(CHIP))
|
||||
BOARD =sam9x35_ek
|
||||
BOARD_DIR = at91sam9x35-ek
|
||||
endif
|
||||
|
||||
# Defines which are the available memory targets for the AT91SAM3S-EK board.
|
||||
MEMORIES = sram
|
||||
|
||||
# Trace level used for compilation
|
||||
# (can be overriden by adding TRACE_LEVEL=#number to the command-line)
|
||||
# TRACE_LEVEL_DEBUG 5
|
||||
# TRACE_LEVEL_INFO 4
|
||||
# TRACE_LEVEL_WARNING 3
|
||||
# TRACE_LEVEL_ERROR 2
|
||||
# TRACE_LEVEL_FATAL 1
|
||||
# TRACE_LEVEL_NO_TRACE 0
|
||||
|
||||
# Info traces allowed by default
|
||||
TR_LEV = 0
|
||||
|
||||
# Optimization level, put in comment for debugging
|
||||
OPTIMIZATION = -Os
|
||||
|
||||
# Output file basename
|
||||
OUTPUT = applet-coprocessor-$(CHIP)
|
||||
|
||||
# Output directories
|
||||
BIN = bin
|
||||
OBJ = obj
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Tools
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Tool suffix when cross-compiling
|
||||
CROSS_COMPILE = arm-none-eabi-
|
||||
|
||||
# Libraries
|
||||
LIBRARIES = ../../libraries
|
||||
# Chip library directory
|
||||
CHIP_LIB = $(LIBRARIES)/libchip_atsam3s
|
||||
# Board library directory
|
||||
BOARD_LIB = $(LIBRARIES)/libboard_atsam3s-ek
|
||||
# Spiflash library directory
|
||||
#SPIFLASH_LIB = $(LIBRARIES)/libspiflash
|
||||
|
||||
# ISP directory
|
||||
ISP = ..
|
||||
# tcl_lib directory
|
||||
|
||||
#INSTALLDIR = "../../../../tcl_lib/$(BOARD_DIR)/"
|
||||
|
||||
LIBS = -Wl,--start-group -lgcc -lc -Wl,--end-group
|
||||
|
||||
#-lchip_$(CHIP)_gcc_rel -lboard_$(BOARD)_gcc_rel -lspiflash_gcc_rel -Wl,--end-group
|
||||
|
||||
LIB_PATH = -L$(CHIP_LIB)/lib
|
||||
LIB_PATH += -L$(BOARD_LIB)/lib
|
||||
#LIB_PATH += -L$(SPIFLASH_LIB)/lib
|
||||
#LIB_PATH+=-L=/lib
|
||||
#LIB_PATH+=-L=/../lib/gcc/arm-none-eabi/4.4.1
|
||||
|
||||
# Compilation tools
|
||||
AR = $(CROSS_COMPILE)ar
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
LD = $(CROSS_COMPILE)ld
|
||||
SIZE = $(CROSS_COMPILE)size
|
||||
STRIP = $(CROSS_COMPILE)strip
|
||||
OBJCOPY = $(CROSS_COMPILE)objcopy
|
||||
GDB = $(CROSS_COMPILE)gdb
|
||||
NM = $(CROSS_COMPILE)nm
|
||||
CLSS = $(CROSS_COMPILE)objdump
|
||||
|
||||
# Flags
|
||||
INCLUDES = -I$(CHIP_LIB)
|
||||
INCLUDES += -I$(BOARD_LIB)
|
||||
INCLUDES += -I$(SPIFLASH_LIB)
|
||||
INCLUDES += -I$(LIBRARIES)
|
||||
|
||||
CFLAGS += -Wall -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int
|
||||
CFLAGS += -Werror-implicit-function-declaration -Wmain -Wparentheses
|
||||
CFLAGS += -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused
|
||||
CFLAGS += -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef
|
||||
CFLAGS += -Wshadow -Wpointer-arith -Wbad-function-cast -Wwrite-strings
|
||||
CFLAGS += -Wsign-compare -Waggregate-return -Wstrict-prototypes
|
||||
CFLAGS += -Wmissing-prototypes -Wmissing-declarations
|
||||
CFLAGS += -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations
|
||||
CFLAGS += -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long
|
||||
CFLAGS += -Wunreachable-code
|
||||
CFLAGS += -Wcast-align
|
||||
#CFLAGS += -Wmissing-noreturn
|
||||
#CFLAGS += -Wconversion
|
||||
|
||||
# To reduce application size use only integer printf function.
|
||||
CFLAGS += -Dprintf=iprintf
|
||||
TRACE_LEVEL = 4
|
||||
#CFLAGS += -DTRACE_LEVEL=$(TR_LEV)
|
||||
#-DDYN_TRACES
|
||||
# -mlong-calls -Wall
|
||||
CFLAGS += -ffunction-sections -D$(MEMORIES)
|
||||
#CFLAGS += -DNDEBUG
|
||||
CFLAGS += -mthumb -g -gdwarf-2 $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -DTRACE_LEVEL=$(TRACE_LEVEL) -DDYN_TRACES
|
||||
ASFLAGS = -Wall -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D__ASSEMBLY__
|
||||
LDFLAGS= -nostartfiles -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=entry -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols
|
||||
LD_OPTIONAL=-Wl,--print-gc-sections -Wl,--stats
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Files
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Directories where source files can be found
|
||||
|
||||
VPATH += ../..
|
||||
VPATH += $(ISP)/common
|
||||
|
||||
|
||||
# Objects built from Asm source files
|
||||
//ASM_OBJECTS = applet_cstartup.o
|
||||
|
||||
# Objects built from C source files
|
||||
C_OBJECTS += main.o
|
||||
C_OBJECTS += applet_cstartup.o
|
||||
|
||||
# Append OBJ and BIN directories to output filename
|
||||
OUTPUT := $(BIN)/$(OUTPUT)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Rules
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
all: $(BIN) $(OBJ) $(MEMORIES)
|
||||
|
||||
$(BIN) $(OBJ):
|
||||
mkdir $@
|
||||
|
||||
define RULES
|
||||
C_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(C_OBJECTS))
|
||||
ASM_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(ASM_OBJECTS))
|
||||
|
||||
$(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1))
|
||||
$(CC) $(LIB_PATH) $(LDFLAGS) $(LD_OPTIONAL) -T"$(BOARD_LIB)/resources/gcc/$(CHIP)/$$@_samba.lds" -Wl,-Map,$(OUTPUT).map -o $(OUTPUT).elf $$^ $(LIBS)
|
||||
$(NM) $(OUTPUT).elf >$(OUTPUT).elf.txt
|
||||
$(OBJCOPY) -O binary $(OUTPUT).elf $(OUTPUT).bin
|
||||
$(SIZE) $$^ $(OUTPUT).elf
|
||||
$(CLSS) -h -S $(OUTPUT).elf >$(OUTPUT).lss
|
||||
# @[ -e $(INSTALLDIR) ] || mkdir $(INSTALLDIR)
|
||||
# @cp -f $(OUTPUT).bin $(INSTALLDIR)
|
||||
|
||||
$$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)
|
||||
$(CC) $(CFLAGS) -D$(1) -c -o $$@ $$<
|
||||
|
||||
$$(ASM_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.S Makefile $(OBJ) $(BIN)
|
||||
$(CC) $(ASFLAGS) -D$(1) -c -o $$@ $$<
|
||||
|
||||
debug_$(1): $(1)
|
||||
$(GDB) -x "$(BOARD_LIB)/resources/gcc/$(BOARD)_$(1).gdb" -ex "reset" -readnow -se $(OUTPUT)-$(1).elf
|
||||
endef
|
||||
|
||||
$(foreach MEMORY, $(MEMORIES), $(eval $(call RULES,$(MEMORY))))
|
||||
|
||||
clean:
|
||||
-del $(OBJ)\*.o $(BIN)\*.bin $(BIN)\*.elf $(BIN)\*.map
|
||||
|
||||
# Create extended listing file from ELF output file.
|
||||
%.lss: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EXTENDED_LISTING) $@
|
||||
$(OBJDUMP) -h -S $< > $@
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,101 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef APPLET_H
|
||||
#define APPLET_H
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Global definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** Refers to the Version of SAM-BA */
|
||||
#define SAM_BA_APPLETS_VERSION "2.11"
|
||||
|
||||
/** Applet initialization command code.*/
|
||||
#define APPLET_CMD_INIT 0x00
|
||||
/** Applet full erase command code.*/
|
||||
#define APPLET_CMD_FULL_ERASE 0x01
|
||||
/** Applet write command code.*/
|
||||
#define APPLET_CMD_WRITE 0x02
|
||||
/** Applet read command code.*/
|
||||
#define APPLET_CMD_READ 0x03
|
||||
/** Applet read command code.*/
|
||||
#define APPLET_CMD_LOCK 0x04
|
||||
/** Applet read command code.*/
|
||||
#define APPLET_CMD_UNLOCK 0x05
|
||||
/** Applet set/clear GPNVM command code.*/
|
||||
#define APPLET_CMD_GPNVM 0x06
|
||||
/** Applet set security bit command code.*/
|
||||
#define APPLET_CMD_SECURITY 0x07
|
||||
/** Applet buffer erase command code.*/
|
||||
#define APPLET_CMD_BUFFER_ERASE 0x08
|
||||
/** Applet binary page command code for Dataflash.*/
|
||||
#define APPLET_CMD_BINARY_PAGE 0x09
|
||||
/** List Bad Blocks of a Nandflash*/
|
||||
#define APPLET_CMD_LIST_BAD_BLOCKS 0x10
|
||||
/** Tag a Nandflash Block*/
|
||||
#define APPLET_CMD_TAG_BLOCK 0x11
|
||||
/** Read the Unique ID bits (on SAM3)*/
|
||||
#define APPLET_CMD_READ_UNIQUE_ID 0x12
|
||||
/** Applet blocks erase command code. */
|
||||
#define APPLET_CMD_ERASE_BLOCKS 0x13
|
||||
/** Applet batch full erase command code. */
|
||||
#define APPLET_CMD_BATCH_ERASE 0x14
|
||||
|
||||
/** Operation was successful.*/
|
||||
#define APPLET_SUCCESS 0x00
|
||||
/** Device unknown.*/
|
||||
#define APPLET_DEV_UNKNOWN 0x01
|
||||
/** Write operation failed.*/
|
||||
#define APPLET_WRITE_FAIL 0x02
|
||||
/** Read operation failed.*/
|
||||
#define APPLET_READ_FAIL 0x03
|
||||
/** Protect operation failed.*/
|
||||
#define APPLET_PROTECT_FAIL 0x04
|
||||
/** Unprotect operation failed.*/
|
||||
#define APPLET_UNPROTECT_FAIL 0x05
|
||||
/** Erase operation failed.*/
|
||||
#define APPLET_ERASE_FAIL 0x06
|
||||
/** No device defined in board.h*/
|
||||
#define APPLET_NO_DEV 0x07
|
||||
/** Read / write address is not aligned*/
|
||||
#define APPLET_ALIGN_ERROR 0x08
|
||||
/** Read / write found bad block*/
|
||||
#define APPLET_BAD_BLOCK 0x09
|
||||
/** Applet failure.*/
|
||||
#define APPLET_FAIL 0x0f
|
||||
|
||||
|
||||
/** Communication link identification*/
|
||||
#define USB_COM_TYPE 0x00
|
||||
#define DBGU_COM_TYPE 0x01
|
||||
#define JTAG_COM_TYPE 0x02
|
||||
|
||||
#endif //#ifndef APPLET_H
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2011, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
#include "board.h"
|
||||
#include "board_lowlevel.h"
|
||||
typedef void( *IntFunc )( void );
|
||||
/*----------------------------------------------------------------------------
|
||||
* Prototypes
|
||||
*----------------------------------------------------------------------------*/
|
||||
/** Stack top */
|
||||
extern unsigned long _sstack;
|
||||
|
||||
/** Initialize segments*/
|
||||
extern unsigned int _sidata;
|
||||
extern unsigned int _sdata, _edata;
|
||||
extern unsigned int _szero, _ezero;
|
||||
|
||||
/** Default link entry */
|
||||
extern int main(int argc, char **argv);
|
||||
|
||||
/** Reset entry */
|
||||
void ResetException(void) ;//__attribute__((__interrupt__));
|
||||
|
||||
/** Exception Table */
|
||||
__attribute__((section(".isr_vector")))
|
||||
//IntFunc exception_table[] = {
|
||||
//__attribute__ ((section(".vectors"), used))
|
||||
void (* const gVectors[])(void) =
|
||||
{
|
||||
/* Configure Initial Stack Pointer, using linker-generated symbols */
|
||||
(void (*)(void))((unsigned long)&_sstack),
|
||||
// /*(IntFunc)&*/_sstack,
|
||||
ResetException, /* Initial PC, set to entry point */
|
||||
(unsigned int) 0 /*NMIException*/,
|
||||
(unsigned int) 0 /*HardFaultException*/,
|
||||
(unsigned int) 0 /*MemManageException*/,
|
||||
(unsigned int) 0 /*BusFaultException*/,
|
||||
(unsigned int) 0 /*UsageFaultException*/,
|
||||
0, 0, 0, 0, /* Reserved */
|
||||
(unsigned int) 0 /*SVCHandler*/,
|
||||
(unsigned int) 0 /*DebugMonitor*/,
|
||||
0, /* Reserved */
|
||||
(unsigned int) 0 /*PendSVC*/,
|
||||
(unsigned int) 0 /*SysTickHandler*/,
|
||||
/*
|
||||
:
|
||||
*/
|
||||
};
|
||||
|
||||
/** Applet Mailbox and initialization flag */
|
||||
#define MAILBOX_SIZE 32
|
||||
__attribute__((section(".mailbox")))
|
||||
unsigned int mailbox[MAILBOX_SIZE];
|
||||
volatile unsigned int isInitialized = 0;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Reset Handler
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief This is the code that gets called on processor reset. To initialize the
|
||||
* device. And call the main() routine.
|
||||
*
|
||||
*/
|
||||
__attribute__ ((section(".text"), used))
|
||||
void ResetException(void)
|
||||
{
|
||||
unsigned int *pSrc, *pDest;
|
||||
// { asm volatile ("cpsid i"); }
|
||||
|
||||
// Initialize data
|
||||
// Zero fill bss
|
||||
if (isInitialized == 0) {
|
||||
pSrc = &_sidata;
|
||||
for(pDest = &_sdata; pDest < &_edata;) {
|
||||
|
||||
*(pDest ++) = *(pSrc ++);
|
||||
}
|
||||
|
||||
for (pDest = &_szero; pDest < &_ezero;) {
|
||||
|
||||
*(pDest ++) = 0;
|
||||
}
|
||||
isInitialized = 1;
|
||||
}
|
||||
|
||||
/* LowLevelInit(); */
|
||||
|
||||
/* Save original SP. */
|
||||
__asm("mov r4, sp");
|
||||
/* Change SP to current stack point. */
|
||||
__asm("ldr r5, =_sstack");
|
||||
__asm(" mov sp, r5");
|
||||
main(1, (char**)mailbox);
|
||||
/* Restore previous SP point. */
|
||||
__asm("mov sp, r4");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Interface for the low-level initialization function.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BOARD_LOWLEVEL_H
|
||||
#define BOARD_LOWLEVEL_H
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
extern void LowLevelInit( void ) ;
|
||||
|
||||
#endif /* BOARD_LOWLEVEL_H */
|
||||
|
||||
@@ -0,0 +1,235 @@
|
||||
# ----------------------------------------------------------------------------
|
||||
# ATMEL Microcontroller Software Support
|
||||
# ----------------------------------------------------------------------------
|
||||
# Copyright (c) 2011, Atmel Corporation
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# - Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the disclaimer below.
|
||||
#
|
||||
# Atmel's name may not be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# Makefile for compiling the applet-serial flash project
|
||||
|
||||
# Chip & board used for compilation
|
||||
# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
|
||||
CHIP = atsam3s4
|
||||
BOARD = atsam3s4_ek
|
||||
DYN = OFF
|
||||
|
||||
# Makefile for compiling applet-serialflash applet.
|
||||
|
||||
ifeq (atsam3s4,$(CHIP))
|
||||
BOARD_DIR = at91sam3s4-ek
|
||||
endif
|
||||
|
||||
ifeq (atsam3s2,$(CHIP))
|
||||
BOARD_DIR = at91sam3s2-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9g15,$(CHIP))
|
||||
BOARD =sam9g15_ek
|
||||
BOARD_DIR = at91sam9g15-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9g25,$(CHIP))
|
||||
BOARD =sam9g25_ek
|
||||
BOARD_DIR = at91sam9g25-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9g35,$(CHIP))
|
||||
BOARD =sam9g35_ek
|
||||
BOARD_DIR = at91sam9g35-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9x25,$(CHIP))
|
||||
BOARD =sam9x25_ek
|
||||
BOARD_DIR = at91sam9x25-ek
|
||||
endif
|
||||
|
||||
ifeq (sam9x35,$(CHIP))
|
||||
BOARD =sam9x35_ek
|
||||
BOARD_DIR = at91sam9x35-ek
|
||||
endif
|
||||
|
||||
# Defines which are the available memory targets for the AT91SAM3S-EK board.
|
||||
MEMORIES = sram
|
||||
|
||||
# Trace level used for compilation
|
||||
# (can be overriden by adding TRACE_LEVEL=#number to the command-line)
|
||||
# TRACE_LEVEL_DEBUG 5
|
||||
# TRACE_LEVEL_INFO 4
|
||||
# TRACE_LEVEL_WARNING 3
|
||||
# TRACE_LEVEL_ERROR 2
|
||||
# TRACE_LEVEL_FATAL 1
|
||||
# TRACE_LEVEL_NO_TRACE 0
|
||||
|
||||
# Info traces allowed by default
|
||||
TR_LEV = 0
|
||||
|
||||
# Optimization level, put in comment for debugging
|
||||
OPTIMIZATION = -Os
|
||||
|
||||
# Output file basename
|
||||
OUTPUT = applet-serialflash-$(CHIP)
|
||||
|
||||
# Output directories
|
||||
BIN = bin
|
||||
OBJ = obj
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Tools
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Tool suffix when cross-compiling
|
||||
CROSS_COMPILE = arm-none-eabi-
|
||||
|
||||
# Libraries
|
||||
LIBRARIES = ../../libraries
|
||||
# Chip library directory
|
||||
CHIP_LIB = $(LIBRARIES)/libchip_atsam3s
|
||||
# Board library directory
|
||||
BOARD_LIB = $(LIBRARIES)/libboard_atsam3s-ek
|
||||
# Spiflash library directory
|
||||
#SPIFLASH_LIB = $(LIBRARIES)/libspiflash
|
||||
|
||||
# ISP directory
|
||||
ISP = ..
|
||||
# tcl_lib directory
|
||||
|
||||
#INSTALLDIR = "../../../../tcl_lib/$(BOARD_DIR)/"
|
||||
|
||||
LIBS = -Wl,--start-group -lgcc -lc -Wl,--end-group
|
||||
|
||||
#-lchip_$(CHIP)_gcc_rel -lboard_$(BOARD)_gcc_rel -lspiflash_gcc_rel -Wl,--end-group
|
||||
|
||||
LIB_PATH = -L$(CHIP_LIB)/lib
|
||||
LIB_PATH += -L$(BOARD_LIB)/lib
|
||||
#LIB_PATH += -L$(SPIFLASH_LIB)/lib
|
||||
#LIB_PATH+=-L=/lib
|
||||
#LIB_PATH+=-L=/../lib/gcc/arm-none-eabi/4.4.1
|
||||
|
||||
# Compilation tools
|
||||
AR = $(CROSS_COMPILE)ar
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
LD = $(CROSS_COMPILE)ld
|
||||
SIZE = $(CROSS_COMPILE)size
|
||||
STRIP = $(CROSS_COMPILE)strip
|
||||
OBJCOPY = $(CROSS_COMPILE)objcopy
|
||||
GDB = $(CROSS_COMPILE)gdb
|
||||
NM = $(CROSS_COMPILE)nm
|
||||
CLSS = $(CROSS_COMPILE)objdump
|
||||
|
||||
# Flags
|
||||
INCLUDES = -I$(CHIP_LIB)
|
||||
INCLUDES += -I$(BOARD_LIB)
|
||||
INCLUDES += -I$(SPIFLASH_LIB)
|
||||
INCLUDES += -I$(LIBRARIES)
|
||||
|
||||
CFLAGS += -Wall -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int
|
||||
CFLAGS += -Werror-implicit-function-declaration -Wmain -Wparentheses
|
||||
CFLAGS += -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused
|
||||
CFLAGS += -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef
|
||||
CFLAGS += -Wshadow -Wpointer-arith -Wbad-function-cast -Wwrite-strings
|
||||
CFLAGS += -Wsign-compare -Waggregate-return -Wstrict-prototypes
|
||||
CFLAGS += -Wmissing-prototypes -Wmissing-declarations
|
||||
CFLAGS += -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations
|
||||
CFLAGS += -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long
|
||||
CFLAGS += -Wunreachable-code
|
||||
CFLAGS += -Wcast-align
|
||||
#CFLAGS += -Wmissing-noreturn
|
||||
#CFLAGS += -Wconversion
|
||||
|
||||
# To reduce application size use only integer printf function.
|
||||
CFLAGS += -Dprintf=iprintf
|
||||
TRACE_LEVEL = 4
|
||||
#CFLAGS += -DTRACE_LEVEL=$(TR_LEV)
|
||||
#-DDYN_TRACES
|
||||
# -mlong-calls -Wall
|
||||
CFLAGS += -ffunction-sections -D$(MEMORIES)
|
||||
#CFLAGS += -DNDEBUG
|
||||
CFLAGS += -mthumb -g -gdwarf-2 $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -DTRACE_LEVEL=$(TRACE_LEVEL) -DDYN_TRACES
|
||||
ASFLAGS = -Wall -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D__ASSEMBLY__
|
||||
LDFLAGS= -nostartfiles -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=entry -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols
|
||||
LD_OPTIONAL=-Wl,--print-gc-sections -Wl,--stats
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Files
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Directories where source files can be found
|
||||
|
||||
VPATH += ../..
|
||||
VPATH += $(ISP)/common
|
||||
|
||||
|
||||
# Objects built from Asm source files
|
||||
//ASM_OBJECTS = applet_cstartup.o
|
||||
|
||||
# Objects built from C source files
|
||||
C_OBJECTS += main.o
|
||||
C_OBJECTS += applet_cstartup.o
|
||||
|
||||
# Append OBJ and BIN directories to output filename
|
||||
OUTPUT := $(BIN)/$(OUTPUT)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Rules
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
all: $(BIN) $(OBJ) $(MEMORIES)
|
||||
|
||||
$(BIN) $(OBJ):
|
||||
mkdir $@
|
||||
|
||||
define RULES
|
||||
C_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(C_OBJECTS))
|
||||
ASM_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(ASM_OBJECTS))
|
||||
|
||||
$(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1))
|
||||
$(CC) $(LIB_PATH) $(LDFLAGS) $(LD_OPTIONAL) -T"$(BOARD_LIB)/resources/gcc/$(CHIP)/$$@_samba.lds" -Wl,-Map,$(OUTPUT).map -o $(OUTPUT).elf $$^ $(LIBS)
|
||||
$(NM) $(OUTPUT).elf >$(OUTPUT).elf.txt
|
||||
$(OBJCOPY) -O binary $(OUTPUT).elf $(OUTPUT).bin
|
||||
$(SIZE) $$^ $(OUTPUT).elf
|
||||
$(CLSS) -h -S $(OUTPUT).elf >$(OUTPUT).lss
|
||||
# @[ -e $(INSTALLDIR) ] || mkdir $(INSTALLDIR)
|
||||
# @cp -f $(OUTPUT).bin $(INSTALLDIR)
|
||||
|
||||
$$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)
|
||||
$(CC) $(CFLAGS) -D$(1) -c -o $$@ $$<
|
||||
|
||||
$$(ASM_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.S Makefile $(OBJ) $(BIN)
|
||||
$(CC) $(ASFLAGS) -D$(1) -c -o $$@ $$<
|
||||
|
||||
debug_$(1): $(1)
|
||||
$(GDB) -x "$(BOARD_LIB)/resources/gcc/$(BOARD)_$(1).gdb" -ex "reset" -readnow -se $(OUTPUT)-$(1).elf
|
||||
endef
|
||||
|
||||
$(foreach MEMORY, $(MEMORIES), $(eval $(call RULES,$(MEMORY))))
|
||||
|
||||
clean:
|
||||
-del $(OBJ)\*.o $(BIN)\*.bin $(BIN)\*.elf $(BIN)\*.map
|
||||
|
||||
# Create extended listing file from ELF output file.
|
||||
%.lss: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EXTENDED_LISTING) $@
|
||||
$(OBJDUMP) -h -S $< > $@
|
||||
|
||||
@@ -0,0 +1,971 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2011, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "../common/applet.h"
|
||||
#include <board.h>
|
||||
//#include "libspiflash.h"
|
||||
#include <string.h>
|
||||
|
||||
#undef DYN_TRACES
|
||||
#define DYN_TRACES 0
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Internal definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** SPI clock frequency in Hz. */
|
||||
#define SPCK 8000000
|
||||
|
||||
|
||||
/** Stack size in SRAM */
|
||||
#define STACK_SIZE 0x100
|
||||
|
||||
/** Last erased sector id, this will avoid to erase if the block is already erased. */
|
||||
//static unsigned short lastErasedBlock = 0xFFFF;
|
||||
|
||||
/** Indicate the farthest memory offset ever erase, if current write address is less
|
||||
than the address, the related block should be erase again before write. */
|
||||
//static uint32_t writtenAddress = 0;
|
||||
|
||||
|
||||
/** Max size of data we can tranfsert in one shot */
|
||||
#define MAX_COUNT 0x6000
|
||||
|
||||
/** Chip select value used to select the AT25 chip. */
|
||||
#define SPI_CS 0
|
||||
/** SPI peripheral pins to configure to access the serial flash. */
|
||||
#define SPI_PINS PINS_SPI0, PIN_SPI0_NPCS0
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Types
|
||||
*----------------------------------------------------------------------------*/
|
||||
/** Structure for storing parameters for each command that can be performed by
|
||||
the applet. */
|
||||
struct _Mailbox {
|
||||
|
||||
/** Command send to the monitor to be executed. */
|
||||
uint32_t command;
|
||||
/** Returned status, updated at the end of the monitor execution.*/
|
||||
uint32_t status;
|
||||
|
||||
/** Input Arguments in the argument area*/
|
||||
union {
|
||||
|
||||
/** Input arguments for the Init command.*/
|
||||
struct {
|
||||
|
||||
/** Communication link used.*/
|
||||
uint32_t comType;
|
||||
/**Trace level.*/
|
||||
uint32_t traceLevel;
|
||||
/** Serial flash index.*/
|
||||
uint32_t at25Idx;
|
||||
|
||||
} inputInit;
|
||||
|
||||
/** Output arguments for the Init command.*/
|
||||
struct {
|
||||
|
||||
/** Memory size.*/
|
||||
uint32_t memorySize;
|
||||
/** Buffer address.*/
|
||||
uint32_t bufferAddress;
|
||||
/** Buffer size.*/
|
||||
uint32_t bufferSize;
|
||||
|
||||
} outputInit;
|
||||
|
||||
/** Input arguments for the Write command.*/
|
||||
struct {
|
||||
|
||||
/** Buffer address.*/
|
||||
uint32_t bufferAddr;
|
||||
/** Buffer size.*/
|
||||
uint32_t bufferSize;
|
||||
/** Memory offset.*/
|
||||
uint32_t memoryOffset;
|
||||
|
||||
} inputWrite;
|
||||
|
||||
/** Output arguments for the Write command.*/
|
||||
struct {
|
||||
|
||||
/** Bytes written.*/
|
||||
uint32_t bytesWritten;
|
||||
|
||||
uint32_t bufferSize; // temp
|
||||
/** Memory offset.*/
|
||||
uint32_t memoryOffset; // temp
|
||||
uint32_t debug1 ;
|
||||
uint32_t debug2 ;
|
||||
|
||||
} outputWrite;
|
||||
|
||||
/** Input arguments for the Read command.*/
|
||||
struct {
|
||||
|
||||
/** Buffer address. */
|
||||
uint32_t bufferAddr;
|
||||
/** Buffer size.*/
|
||||
uint32_t bufferSize;
|
||||
/** Memory offset.*/
|
||||
uint32_t memoryOffset;
|
||||
|
||||
} inputRead;
|
||||
|
||||
/** Output arguments for the Read command.*/
|
||||
struct {
|
||||
|
||||
/** Bytes read.*/
|
||||
uint32_t bytesRead;
|
||||
|
||||
} outputRead;
|
||||
|
||||
/** Input arguments for the Full Erase command.*/
|
||||
// NONE
|
||||
|
||||
/** Output arguments for the Full Erase command.*/
|
||||
// NONE
|
||||
/** Input arguments for the Buffer Erase command.*/
|
||||
struct {
|
||||
|
||||
/** Memory offset to be erase.*/
|
||||
uint32_t memoryOffset;
|
||||
|
||||
} inputBufferErase;
|
||||
|
||||
/** Output arguments for the Buffer Erase command.*/
|
||||
struct {
|
||||
|
||||
/** Memory offset to be erase.*/
|
||||
uint32_t bytesErased;
|
||||
|
||||
} outputBufferErase;
|
||||
} argument;
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Global variables
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** End of program space (code + data). */
|
||||
extern int end;
|
||||
extern int _sstack;
|
||||
/*----------------------------------------------------------------------------
|
||||
* Local variables
|
||||
*----------------------------------------------------------------------------*/
|
||||
/** Global DMA driver instance for all DMA transfers in application. */
|
||||
//static sDmad dmad;
|
||||
|
||||
/** SPI driver instance. */
|
||||
//static Spid spid;
|
||||
|
||||
/** Serial flash driver instance. */
|
||||
//static At25 at25;
|
||||
|
||||
/** Pins to configure for the application. */
|
||||
//static Pin pins[] = {SPI_PINS};
|
||||
|
||||
/** Size of one page in the serial flash, in bytes. */
|
||||
static uint32_t pageSize;
|
||||
|
||||
/** Size of one block in the serial flash, in bytes. */
|
||||
static uint32_t blockSize;
|
||||
|
||||
/**Size of the buffer used for read/write operations in bytes. */
|
||||
static uint32_t bufferSize;
|
||||
|
||||
/** Depending on DYN_TRACES, dwTraceLevel is a modifable runtime variable or a define */
|
||||
uint32_t dwTraceLevel;
|
||||
|
||||
uint32_t Spi_init_done = 0 ;
|
||||
struct _Mailbox *Pmailbox = 0 ;
|
||||
|
||||
uint8_t Spi_tx_buf[24] ;
|
||||
uint8_t Spi_rx_buf[24] ;
|
||||
|
||||
uint8_t Block_buffer[4096] ;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Global functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
uint32_t eeprom_write_one( uint8_t byte, uint8_t count ) ;
|
||||
uint32_t eeprom_read_status( void ) ;
|
||||
void eeprom_write_enable( void ) ;
|
||||
void eeprom_wait_busy( void ) ;
|
||||
uint32_t spi_operation( register uint8_t *tx, register uint8_t *rx, register uint32_t count ) ;
|
||||
void init_spi( void ) ;
|
||||
uint32_t unprotect_eeprom( void ) ;
|
||||
uint32_t spi_PDC_action( register uint8_t *command, register uint8_t *tx, register uint8_t *rx, register uint32_t comlen, register uint32_t count ) ;
|
||||
uint32_t eeprom_block_erased( register uint8_t *p) ;
|
||||
uint32_t eeprom_page_erased( register uint8_t *p) ;
|
||||
void AT25D_Read( uint8_t *BufferAddr, uint32_t size, uint32_t memoryOffset) ;
|
||||
void AT25D_Write( uint8_t *BufferAddr, uint32_t size, uint32_t memoryOffset ) ;
|
||||
uint32_t AT25D_EraseBlock( uint32_t memoryOffset ) ;
|
||||
//uint32_t min( uint32_t a, uint32_t b ) ;
|
||||
|
||||
|
||||
uint32_t eeprom_write_one( uint8_t byte, uint8_t count )
|
||||
{
|
||||
register Spi *spiptr ;
|
||||
register uint32_t result ;
|
||||
|
||||
spiptr = SPI ;
|
||||
spiptr->SPI_CR = 1 ; // Enable
|
||||
(void) spiptr->SPI_RDR ; // Dump any rx data
|
||||
|
||||
spiptr->SPI_TDR = byte ;
|
||||
|
||||
result = 0 ;
|
||||
while( ( spiptr->SPI_SR & SPI_SR_RDRF ) == 0 )
|
||||
{
|
||||
// wait for received
|
||||
if ( ++result > 10000 )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( count == 0 )
|
||||
{
|
||||
spiptr->SPI_CR = 2 ; // Disable
|
||||
return spiptr->SPI_RDR ;
|
||||
}
|
||||
(void) spiptr->SPI_RDR ; // Dump the rx data
|
||||
spiptr->SPI_TDR = 0 ;
|
||||
result = 0 ;
|
||||
while( ( spiptr->SPI_SR & SPI_SR_RDRF ) == 0 )
|
||||
{
|
||||
// wait for received
|
||||
if ( ++result > 10000 )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
spiptr->SPI_CR = 2 ; // Disable
|
||||
return spiptr->SPI_RDR ;
|
||||
}
|
||||
|
||||
|
||||
uint32_t eeprom_read_status()
|
||||
{
|
||||
return eeprom_write_one( 5, 1 ) ;
|
||||
}
|
||||
|
||||
|
||||
void eeprom_write_enable()
|
||||
{
|
||||
eeprom_write_one( 6, 0 ) ;
|
||||
}
|
||||
|
||||
void eeprom_wait_busy()
|
||||
{
|
||||
register uint32_t x ;
|
||||
register uint32_t y ;
|
||||
|
||||
y = 0 ;
|
||||
do
|
||||
{
|
||||
y += 1 ;
|
||||
if ( y > 1000000 )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
x = eeprom_read_status() ;
|
||||
} while ( x & 1 ) ;
|
||||
|
||||
Pmailbox->argument.outputWrite.debug2 = y ;
|
||||
}
|
||||
|
||||
uint32_t spi_operation( register uint8_t *tx, register uint8_t *rx, register uint32_t count )
|
||||
{
|
||||
register Spi *spiptr ;
|
||||
register uint32_t result ;
|
||||
|
||||
// PMC->PMC_PCER0 |= 0x00200000L ; // Enable peripheral clock to SPI
|
||||
|
||||
result = 0 ;
|
||||
spiptr = SPI ;
|
||||
spiptr->SPI_CR = 1 ; // Enable
|
||||
(void) spiptr->SPI_RDR ; // Dump any rx data
|
||||
while( count )
|
||||
{
|
||||
result = 0 ;
|
||||
while( ( spiptr->SPI_SR & SPI_SR_TXEMPTY ) == 0 )
|
||||
{
|
||||
// wait
|
||||
if ( ++result > 10000 )
|
||||
{
|
||||
result = 0xFFFF ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( result > 10000 )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
// if ( count == 1 )
|
||||
// {
|
||||
// spiptr->SPI_CR = SPI_CR_LASTXFER ; // LastXfer bit
|
||||
// }
|
||||
spiptr->SPI_TDR = *tx++ ;
|
||||
result = 0 ;
|
||||
while( ( spiptr->SPI_SR & SPI_SR_RDRF ) == 0 )
|
||||
{
|
||||
// wait for received
|
||||
if ( ++result > 10000 )
|
||||
{
|
||||
result = 0x2FFFF ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( result > 10000 )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
*rx++ = spiptr->SPI_RDR ;
|
||||
count -= 1 ;
|
||||
}
|
||||
if ( result <= 10000 )
|
||||
{
|
||||
result = 0 ;
|
||||
}
|
||||
spiptr->SPI_CR = 2 ; // Disable
|
||||
|
||||
// Power save
|
||||
// PMC->PMC_PCER0 &= ~0x00200000L ; // Disable peripheral clock to SPI
|
||||
|
||||
return result ;
|
||||
}
|
||||
|
||||
uint32_t spi_PDC_action( register uint8_t *command, register uint8_t *tx, register uint8_t *rx, register uint32_t comlen, register uint32_t count )
|
||||
{
|
||||
register Spi *spiptr ;
|
||||
// register uint32_t result ;
|
||||
register uint32_t condition ;
|
||||
static uint8_t discard_rx_command[4] ;
|
||||
|
||||
// PMC->PMC_PCER0 |= 0x00200000L ; // Enable peripheral clock to SPI
|
||||
|
||||
// Spi_complete = 0 ;
|
||||
if ( comlen > 4 )
|
||||
{
|
||||
// Spi_complete = 1 ;
|
||||
return 0x4FFFF ;
|
||||
}
|
||||
condition = SPI_SR_TXEMPTY ;
|
||||
spiptr = SPI ;
|
||||
spiptr->SPI_CR = 1 ; // Enable
|
||||
(void) spiptr->SPI_RDR ; // Dump any rx data
|
||||
(void) spiptr->SPI_SR ; // Clear error flags
|
||||
spiptr->SPI_RPR = (uint32_t)discard_rx_command ;
|
||||
spiptr->SPI_RCR = comlen ;
|
||||
if ( rx )
|
||||
{
|
||||
spiptr->SPI_RNPR = (uint32_t)rx ;
|
||||
spiptr->SPI_RNCR = count ;
|
||||
condition = SPI_SR_RXBUFF ;
|
||||
}
|
||||
spiptr->SPI_TPR = (uint32_t)command ;
|
||||
spiptr->SPI_TCR = comlen ;
|
||||
if ( tx )
|
||||
{
|
||||
spiptr->SPI_TNPR = (uint32_t)tx ;
|
||||
}
|
||||
else
|
||||
{
|
||||
spiptr->SPI_TNPR = (uint32_t)rx ;
|
||||
}
|
||||
spiptr->SPI_TNCR = count ;
|
||||
|
||||
spiptr->SPI_PTCR = SPI_PTCR_RXTEN | SPI_PTCR_TXTEN ; // Start transfers
|
||||
|
||||
// Wait for things to get started, avoids early interrupt
|
||||
for ( count = 0 ; count < 1000 ; count += 1 )
|
||||
{
|
||||
if ( ( spiptr->SPI_SR & SPI_SR_TXEMPTY ) == 0 )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
count = 0 ;
|
||||
while( ( spiptr->SPI_SR & condition ) == 0 )
|
||||
{
|
||||
if ( ++count > 1000000 )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
spiptr->SPI_CR = 2 ; // Disable
|
||||
(void) spiptr->SPI_RDR ; // Dump any rx data
|
||||
(void) spiptr->SPI_SR ; // Clear error flags
|
||||
spiptr->SPI_PTCR = SPI_PTCR_RXTDIS | SPI_PTCR_TXTDIS ; // Stop tramsfers
|
||||
|
||||
if ( count > 1000000 )
|
||||
{
|
||||
return 1 ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
uint32_t unprotect_eeprom()
|
||||
{
|
||||
register uint8_t *p ;
|
||||
|
||||
eeprom_write_enable() ;
|
||||
|
||||
p = Spi_tx_buf ;
|
||||
*p = 0x39 ; // Unprotect sector command
|
||||
*(p+1) = 0 ;
|
||||
*(p+2) = 0 ;
|
||||
*(p+3) = 0 ; // 3 bytes address
|
||||
|
||||
return spi_operation( p, Spi_rx_buf, 4 ) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void init_spi()
|
||||
{
|
||||
register Pio *pioptr ;
|
||||
register Spi *spiptr ;
|
||||
register uint32_t timer ;
|
||||
register uint8_t *p ;
|
||||
uint8_t spi_buf[4] ;
|
||||
|
||||
if ( !Spi_init_done)
|
||||
{
|
||||
PMC->PMC_PCER0 |= 0x00200000L ; // Enable peripheral clock to SPI
|
||||
/* Configure PIO */
|
||||
pioptr = PIOA ;
|
||||
pioptr->PIO_ABCDSR[0] &= ~0x00007800 ; // Peripheral A bits 14,13,12,11
|
||||
pioptr->PIO_ABCDSR[1] &= ~0x00007800 ; // Peripheral A
|
||||
pioptr->PIO_PDR = 0x00007800 ; // Assign to peripheral
|
||||
|
||||
spiptr = SPI ;
|
||||
timer = ( 64000000 / 3000000 ) << 8 ;
|
||||
spiptr->SPI_MR = 0x14000011 ; // 0001 0100 0000 0000 0000 0000 0001 0001 Master
|
||||
spiptr->SPI_CSR[0] = 0x01180009 | timer ; // 0000 0001 0001 1000 xxxx xxxx 0000 1001
|
||||
// NVIC_EnableIRQ(SPI_IRQn) ;
|
||||
|
||||
p = spi_buf ;
|
||||
|
||||
// *p = 0x39 ; // Unprotect sector command
|
||||
// *(p+1) = 0 ;
|
||||
// *(p+2) = 0 ;
|
||||
// *(p+3) = 0 ; // 3 bytes address
|
||||
|
||||
// spi_operation( p, spi_buf, 4 ) ;
|
||||
|
||||
eeprom_write_enable() ;
|
||||
|
||||
*p = 1 ; // Write status register command
|
||||
*(p+1) = 0 ;
|
||||
spi_operation( p, spi_buf, 2 ) ;
|
||||
Spi_init_done = 1 ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32_t eeprom_block_erased( register uint8_t *p)
|
||||
{
|
||||
register uint32_t x ;
|
||||
register uint32_t result ;
|
||||
|
||||
result = 1 ;
|
||||
|
||||
for ( x = 0 ; x < 4096 ; x += 1 )
|
||||
{
|
||||
if ( *p++ != 0xFF )
|
||||
{
|
||||
result = 0 ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
return result ;
|
||||
}
|
||||
|
||||
uint32_t eeprom_page_erased( register uint8_t *p)
|
||||
{
|
||||
register uint32_t x ;
|
||||
register uint32_t result ;
|
||||
|
||||
result = 1 ;
|
||||
|
||||
for ( x = 0 ; x < 256 ; x += 1 )
|
||||
{
|
||||
if ( *p++ != 0xFF )
|
||||
{
|
||||
result = 0 ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
return result ;
|
||||
}
|
||||
|
||||
|
||||
void AT25D_Read( uint8_t *BufferAddr, uint32_t size, uint32_t memoryOffset)
|
||||
{
|
||||
register uint8_t *p ;
|
||||
|
||||
p = Spi_tx_buf ;
|
||||
*p = 3 ; // Read command
|
||||
*(p+1) = memoryOffset >> 16 ;
|
||||
*(p+2) = memoryOffset >> 8 ;
|
||||
*(p+3) = memoryOffset ; // 3 bytes address
|
||||
|
||||
spi_PDC_action( p, 0, BufferAddr, 4, size ) ;
|
||||
}
|
||||
|
||||
void AT25D_Write( uint8_t *BufferAddr, uint32_t size, uint32_t memoryOffset )
|
||||
{
|
||||
register uint8_t *p ;
|
||||
|
||||
eeprom_write_enable() ;
|
||||
|
||||
p = Spi_tx_buf ;
|
||||
*p = 2 ; // Write command
|
||||
*(p+1) = memoryOffset >> 16 ;
|
||||
*(p+2) = memoryOffset >> 8 ;
|
||||
*(p+3) = memoryOffset ; // 3 bytes address
|
||||
|
||||
spi_PDC_action( p, BufferAddr, 0, 4, size ) ;
|
||||
|
||||
eeprom_wait_busy() ;
|
||||
|
||||
}
|
||||
|
||||
uint32_t AT25D_EraseBlock( uint32_t memoryOffset )
|
||||
{
|
||||
register uint8_t *p ;
|
||||
register uint32_t x ;
|
||||
|
||||
eeprom_write_enable() ;
|
||||
p = Spi_tx_buf ;
|
||||
*p = 0x20 ; // Block Erase command
|
||||
*(p+1) = memoryOffset >> 16 ;
|
||||
*(p+2) = memoryOffset >> 8 ;
|
||||
*(p+3) = memoryOffset ; // 3 bytes address
|
||||
x = spi_operation( p, Spi_rx_buf, 4 ) ;
|
||||
|
||||
eeprom_wait_busy() ;
|
||||
return x ;
|
||||
}
|
||||
|
||||
//uint32_t min( uint32_t a, uint32_t b )
|
||||
//{
|
||||
// if ( a < b )
|
||||
// {
|
||||
// return a ;
|
||||
// }
|
||||
// return b ;
|
||||
//}
|
||||
|
||||
/**
|
||||
* \brief Applet main entry. This function decodes received command and executes it.
|
||||
* \param argc always 1
|
||||
* \param argv Address of the argument area.
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct _Mailbox *pMailbox = (struct _Mailbox *) argv;
|
||||
Pmailbox = pMailbox ;
|
||||
/* Communication type with SAM-BA GUI. */
|
||||
// uint8_t comType;
|
||||
|
||||
// uint32_t jedecId;
|
||||
uint32_t bytesToWrite, bytesToRead, bufferAddr, startMemoryOffset, memoryOffset, packetSize;
|
||||
/* index on read/write buffer */
|
||||
uint8_t *pBuffer;
|
||||
/* Temporary buffer used for non block aligned read/write */
|
||||
// uint32_t tempBufferAddr;
|
||||
/* Offset in destination buffer during buffer copy */
|
||||
// uint32_t bufferOffset;
|
||||
|
||||
uint32_t block_address ;
|
||||
uint32_t x ;
|
||||
/* INIT */
|
||||
/* Save communication link type */
|
||||
// comType = pMailbox->argument.inputInit.comType;
|
||||
|
||||
init_spi() ;
|
||||
|
||||
if (pMailbox->command == APPLET_CMD_INIT)
|
||||
{
|
||||
#if (DYN_TRACES == 1)
|
||||
dwTraceLevel = pMailbox->argument.inputInit.traceLevel;
|
||||
#endif
|
||||
|
||||
// TRACE_INFO("-- SerialFlash AT25/AT26 applet %s --\n\r", SAM_BA_APPLETS_VERSION);
|
||||
// TRACE_INFO("-- %s\n\r", BOARD_NAME);
|
||||
// TRACE_INFO("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);
|
||||
/* Configure pins */
|
||||
// PIO_Configure(pins, PIO_LISTSIZE(pins));
|
||||
/* Initialize DMA driver instance with polling mode */
|
||||
// DMAD_Initialize( &dmad, 1 );
|
||||
|
||||
/* Initialize the SPI and serial flash */
|
||||
init_spi() ;
|
||||
|
||||
|
||||
|
||||
// SPID_Configure(&spid, SPI0, ID_SPI0, &dmad);
|
||||
// AT25_Configure(&at25, &spid, SPI_CS, 1);
|
||||
// TRACE_INFO("SPI and AT25/AT25 drivers initialized\n\r");
|
||||
pMailbox->argument.outputInit.bufferAddress = (uint32_t) &end ;
|
||||
/* Read the JEDEC ID of the device to identify it */
|
||||
// jedecId = AT25D_ReadJedecId(&at25);
|
||||
// if (AT25_FindDevice(&at25, jedecId) == 0) {
|
||||
// pMailbox->status = APPLET_DEV_UNKNOWN;
|
||||
// pMailbox->argument.outputInit.bufferSize = 0;
|
||||
// pMailbox->argument.outputInit.memorySize = 0;
|
||||
// TRACE_INFO("Device Unknown\n\r");
|
||||
// goto exit;
|
||||
// }
|
||||
// else {
|
||||
/* Get device parameters */
|
||||
pMailbox->status = APPLET_SUCCESS;
|
||||
pageSize = 256 ;
|
||||
// pageSize = AT25_PageSize(&at25);
|
||||
blockSize = 4096 ;
|
||||
// blockSize = AT25_BlockSize(&at25);
|
||||
|
||||
/* Program page */
|
||||
// if (AT25_ManId(&at25) == SST_SPI_FLASH) {
|
||||
/* SST Flash write is slower, we reduce buffer size to avoid USB timeout */
|
||||
// bufferSize = 10 * pageSize;
|
||||
// }
|
||||
// else {
|
||||
bufferSize = 2 * blockSize;
|
||||
// }
|
||||
/* integer number of pages can be contained in each buffer */
|
||||
bufferSize -= bufferSize % pageSize;
|
||||
if ( bufferSize < pageSize) {
|
||||
// TRACE_INFO("No enought memory to load buffer.\n\r");
|
||||
goto exit;
|
||||
}
|
||||
pMailbox->argument.outputInit.bufferSize = bufferSize;
|
||||
pMailbox->argument.outputInit.memorySize = 128*4096;
|
||||
// TRACE_INFO("%s blockSize : 0x%lx bufferAddr : 0x%lx\n\r",
|
||||
// "sky9x", blockSize, pMailbox->argument.outputInit.bufferAddress);
|
||||
// }
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// WRITE:
|
||||
// ----------------------------------------------------------
|
||||
else if (pMailbox->command == APPLET_CMD_WRITE)
|
||||
{
|
||||
startMemoryOffset = pMailbox->argument.inputWrite.memoryOffset;
|
||||
memoryOffset = startMemoryOffset;
|
||||
bufferAddr = pMailbox->argument.inputWrite.bufferAddr;
|
||||
// tempBufferAddr = bufferAddr + bufferSize;
|
||||
bytesToWrite = pMailbox->argument.inputWrite.bufferSize;
|
||||
// TRACE_INFO("WRITE at offset: 0x%lx buffer at : 0x%lx of: 0x%lx Bytes\n\r",
|
||||
// memoryOffset, bufferAddr, bytesToWrite);
|
||||
/* Check word alignment */
|
||||
if (memoryOffset % 4) {
|
||||
|
||||
pMailbox->status = APPLET_ALIGN_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
unprotect_eeprom() ;
|
||||
// if (AT25D_Unprotect(&at25)) {
|
||||
|
||||
// TRACE_INFO("Can not unprotect the flash\n\r");
|
||||
// pMailbox->status = APPLET_UNPROTECT_FAIL;
|
||||
// goto exit;
|
||||
// }
|
||||
|
||||
pBuffer = (uint8_t *) bufferAddr;
|
||||
|
||||
block_address = memoryOffset &0xFFFFF000 ; // 4k boundary
|
||||
AT25D_Read( Block_buffer, 4096, block_address ) ; // read block to write to
|
||||
// Check to see if it is blank
|
||||
x = eeprom_block_erased( Block_buffer ) ;
|
||||
if ( x == 0 )
|
||||
{
|
||||
AT25D_EraseBlock( block_address ) ;
|
||||
}
|
||||
|
||||
if (bytesToWrite)
|
||||
{
|
||||
uint32_t bytes_to_copy ;
|
||||
uint32_t i ;
|
||||
uint32_t j ;
|
||||
uint8_t *s ;
|
||||
uint8_t *dest ;
|
||||
|
||||
dest = Block_buffer + (memoryOffset & 0x0FFF ) ;
|
||||
s = pBuffer ;
|
||||
bytes_to_copy = 4096 - ( memoryOffset - block_address ) ;
|
||||
if ( bytes_to_copy > bytesToWrite )
|
||||
{
|
||||
bytes_to_copy = bytesToWrite ;
|
||||
}
|
||||
for ( i = 0 ; i < bytes_to_copy ; i += 1 )
|
||||
{
|
||||
*dest++ = *s++ ;
|
||||
}
|
||||
memoryOffset += bytes_to_copy ;
|
||||
bytesToWrite -= bytes_to_copy ;
|
||||
s = Block_buffer ;
|
||||
j = 0 ;
|
||||
for ( i = 0 ; i < 16 ; i += 1 ) // pages in block
|
||||
{
|
||||
j <<= 1 ;
|
||||
x = eeprom_page_erased( s ) ;
|
||||
if ( x == 0 ) // Not blank
|
||||
{
|
||||
AT25D_Write( s, 256, block_address ) ;
|
||||
j |= 1 ;
|
||||
}
|
||||
s += 256 ;
|
||||
block_address += 256 ;
|
||||
}
|
||||
pMailbox->argument.outputWrite.debug1 = j ;
|
||||
}
|
||||
|
||||
|
||||
// if ((memoryOffset % pageSize) != 0) {
|
||||
|
||||
// /* We are not page aligned, retrieve first page content to update it*/
|
||||
// if (memoryOffset < writtenAddress) {
|
||||
// lastErasedBlock = 0xFFFF;
|
||||
// }
|
||||
// /* Flush temp buffer */
|
||||
// memset((uint32_t *)tempBufferAddr, 0xFF, pageSize);
|
||||
|
||||
// bufferOffset = (memoryOffset % pageSize);
|
||||
// packetSize = pageSize - bufferOffset;
|
||||
// memoryOffset -= bufferOffset;
|
||||
// /* Read page to be updated*/
|
||||
// AT25D_Read( (uint8_t *) tempBufferAddr, pageSize, memoryOffset);
|
||||
// /* Fill retrieved page with data to be programmed */
|
||||
// memcpy((uint8_t *)(tempBufferAddr + bufferOffset), pBuffer, packetSize);
|
||||
|
||||
// if (((memoryOffset / blockSize) > lastErasedBlock) || (lastErasedBlock == 0xFFFF)) {
|
||||
// /* Erase the block to be updated */
|
||||
//// AT25D_EraseBlock( memoryOffset);
|
||||
// lastErasedBlock = (memoryOffset / blockSize);
|
||||
// }
|
||||
|
||||
// /* Write the page contents */
|
||||
//// AT25D_Write( (uint8_t *) tempBufferAddr, pageSize, memoryOffset);
|
||||
// bytesToWrite = (bytesToWrite > packetSize) ? (bytesToWrite - packetSize) : 0;
|
||||
// pBuffer += packetSize;
|
||||
// memoryOffset += pageSize;
|
||||
// writtenAddress = memoryOffset;
|
||||
// }
|
||||
|
||||
// /* If it remains more than one page to write */
|
||||
// while (bytesToWrite >= pageSize)
|
||||
// {
|
||||
// if (memoryOffset < writtenAddress)
|
||||
// {
|
||||
// lastErasedBlock = 0xFFFF;
|
||||
// }
|
||||
// if (((memoryOffset / blockSize) > lastErasedBlock) || (lastErasedBlock == 0xFFFF)) {
|
||||
// /* Erase the block to be updated */
|
||||
//// AT25D_EraseBlock( memoryOffset);
|
||||
// lastErasedBlock = (memoryOffset / blockSize);
|
||||
// }
|
||||
// /* Write the page contents */
|
||||
// AT25D_Write( (uint8_t *) pBuffer, pageSize, memoryOffset);
|
||||
// pBuffer += pageSize;
|
||||
// memoryOffset += pageSize;
|
||||
// bytesToWrite -= pageSize;
|
||||
// writtenAddress = memoryOffset;
|
||||
// }
|
||||
|
||||
// /* Write remaining data */
|
||||
// if (bytesToWrite > 0) {
|
||||
|
||||
// /* Read previous content of page */
|
||||
// AT25D_Read( (uint8_t *) tempBufferAddr, pageSize, memoryOffset);
|
||||
// /* Fill retrieved block with data to be programmed */
|
||||
// memcpy((uint8_t *)tempBufferAddr, pBuffer, bytesToWrite);
|
||||
// if (((memoryOffset / blockSize) > lastErasedBlock) || (lastErasedBlock == 0xFFFF)) {
|
||||
// /* Erase the block to be updated */
|
||||
//// AT25D_EraseBlock( memoryOffset);
|
||||
// lastErasedBlock = (memoryOffset / blockSize);
|
||||
// }
|
||||
// /* Write the page contents */;
|
||||
//// AT25D_Write( (uint8_t *) tempBufferAddr, pageSize, memoryOffset);
|
||||
// writtenAddress = memoryOffset + bytesToWrite;
|
||||
// /* No more bytes to write */
|
||||
// bytesToWrite = 0;
|
||||
// }
|
||||
|
||||
//// TRACE_INFO("WRITE return byte written : 0x%lx Bytes\n\r",
|
||||
//// pMailbox->argument.inputWrite.bufferSize - bytesToWrite);
|
||||
|
||||
pMailbox->argument.outputWrite.bytesWritten = pMailbox->argument.inputWrite.bufferSize - bytesToWrite;
|
||||
// pMailbox->argument.outputWrite.bytesWritten = bytesToWrite;
|
||||
pMailbox->status = APPLET_SUCCESS;
|
||||
}
|
||||
|
||||
// // ----------------------------------------------------------
|
||||
// // READ:
|
||||
// // ----------------------------------------------------------
|
||||
else if (pMailbox->command == APPLET_CMD_READ)
|
||||
{
|
||||
memoryOffset = pMailbox->argument.inputRead.memoryOffset;
|
||||
bufferAddr = pMailbox->argument.inputRead.bufferAddr;
|
||||
bytesToRead = pMailbox->argument.inputRead.bufferSize;
|
||||
|
||||
// TRACE_INFO("READ at offset: 0x%lx buffer at : 0x%lx of: 0x%lx Bytes\n\r",
|
||||
// memoryOffset, bufferAddr, bytesToRead);
|
||||
/* Check word alignment */
|
||||
if (memoryOffset % 4) {
|
||||
|
||||
pMailbox->status = APPLET_ALIGN_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
pBuffer = (uint8_t *) bufferAddr;
|
||||
|
||||
/* Read packet after packets */
|
||||
while (((uint32_t)pBuffer < (bufferAddr + bufferSize)) && (bytesToRead > 0))
|
||||
{
|
||||
packetSize = bytesToRead ;
|
||||
if ( packetSize > MAX_COUNT )
|
||||
{
|
||||
packetSize = MAX_COUNT ;
|
||||
}
|
||||
AT25D_Read( pBuffer, packetSize, memoryOffset);
|
||||
pBuffer += packetSize;
|
||||
bytesToRead -= packetSize;
|
||||
memoryOffset += packetSize;
|
||||
}
|
||||
|
||||
// TRACE_INFO("READ return byte read : 0x%lx Bytes\n\r",
|
||||
// pMailbox->argument.inputRead.bufferSize - bytesToRead);
|
||||
|
||||
pMailbox->argument.outputRead.bytesRead = pMailbox->argument.inputRead.bufferSize - bytesToRead;
|
||||
pMailbox->status = APPLET_SUCCESS;
|
||||
}
|
||||
|
||||
// // ----------------------------------------------------------
|
||||
// // FULL ERASE:
|
||||
// // ----------------------------------------------------------
|
||||
else if (pMailbox->command == APPLET_CMD_FULL_ERASE)
|
||||
{
|
||||
pMailbox->status = APPLET_ERASE_FAIL;
|
||||
// TRACE_INFO("FULL ERASE\n\r");
|
||||
|
||||
// unprotect_eeprom() ;
|
||||
|
||||
// /* Unprotected the flash */
|
||||
//// if (AT25D_Unprotect(&at25)) {
|
||||
|
||||
//// TRACE_INFO("Can not unprotect the flash\n\r");
|
||||
//// pMailbox->status = APPLET_UNPROTECT_FAIL;
|
||||
//// goto exit;
|
||||
//// }
|
||||
|
||||
// TRACE_INFO("Flash unprotected\n\r");
|
||||
|
||||
// /* Erase the chip */
|
||||
// TRACE_INFO("Chip is being erased...\n\r");
|
||||
|
||||
//// if (AT25D_EraseChip()) {
|
||||
|
||||
// // NOT IMPLEMENTED (YET?)
|
||||
|
||||
// TRACE_INFO("Erasing error\n\r");
|
||||
// pMailbox->status = APPLET_ERASE_FAIL;
|
||||
// goto exit;
|
||||
//// }
|
||||
|
||||
// TRACE_INFO("Full Erase achieved\n\r");
|
||||
// pMailbox->status = APPLET_SUCCESS;
|
||||
}
|
||||
// // ----------------------------------------------------------
|
||||
// // BUFFER ERASE:
|
||||
// // ----------------------------------------------------------
|
||||
else if (pMailbox->command == APPLET_CMD_BUFFER_ERASE)
|
||||
{
|
||||
|
||||
// TRACE_INFO("BUFFER ERASE \n\r");
|
||||
/* Unprotected the flash */
|
||||
unprotect_eeprom() ;
|
||||
|
||||
// if (AT25D_Unprotect(&at25)) {
|
||||
|
||||
// TRACE_INFO("Can not unprotect the flash\n\r");
|
||||
// pMailbox->status = APPLET_UNPROTECT_FAIL;
|
||||
// goto exit;
|
||||
// }
|
||||
|
||||
memoryOffset = pMailbox->argument.inputBufferErase.memoryOffset;
|
||||
|
||||
if (AT25D_EraseBlock( memoryOffset))
|
||||
{
|
||||
pMailbox->status = APPLET_ERASE_FAIL;
|
||||
// TRACE_INFO("Block erasing error\n\r");
|
||||
goto exit;
|
||||
}
|
||||
pMailbox->argument.outputBufferErase.bytesErased = 4096;
|
||||
|
||||
// TRACE_INFO("Buffer Erase achieved\n\r");
|
||||
pMailbox->status = APPLET_SUCCESS;
|
||||
}
|
||||
exit:
|
||||
/* Acknowledge the end of command */
|
||||
// TRACE_INFO("\tEnd of applet (command : %lx --- status : %lx)\n\r", pMailbox->command, pMailbox->status);
|
||||
|
||||
/* Notify the host application of the end of the command processing */
|
||||
pMailbox->command = ~(pMailbox->command);
|
||||
/* Send ACK character */
|
||||
// if (comType == DBGU_COM_TYPE)
|
||||
// {
|
||||
/* Wait for the transmitter to be ready */
|
||||
// while ( (DBGU->DBGU_SR & DBGU_SR_TXEMPTY) == 0 ) ;
|
||||
/* Send character */
|
||||
// DBGU->DBGU_THR= 0x06 ;
|
||||
// }
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,734 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2011, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \page sam3s_ek_board_desc SAM3S-EK - Board Description
|
||||
*
|
||||
* \section Purpose
|
||||
*
|
||||
* A file is dedicated to descibe the AT91SAM3S-EK board.
|
||||
*
|
||||
* \section Contents
|
||||
*
|
||||
* - For AT91SAM3S-EK information, see \subpage sam3s_ek_board_info.
|
||||
* - For operating frequency information, see \subpage sam3s_ek_opfreq.
|
||||
* - For using portable PIO definitions, see \subpage sam3s_ek_piodef.
|
||||
* - For on-board memories, see \subpage sam3s_ek_mem.
|
||||
* - Several USB definitions are included here, see \subpage sam3s_ek_usb.
|
||||
* - For External components, see \subpage sam3s_ek_extcomp.
|
||||
* - For Individual chip definition, see \subpage sam3s_ek_chipdef.
|
||||
*
|
||||
* To get more software details and the full list of parameters related to the
|
||||
* SAM3S-EK board configuration, please have a look at the source file:
|
||||
* \ref board.h\n
|
||||
*
|
||||
* \section Usage
|
||||
*
|
||||
* - The code for booting the board is provided by board_cstartup_xxx.c and
|
||||
* board_lowlevel.c.
|
||||
* - For using board PIOs, board characteristics (clock, etc.) and external
|
||||
* components, see board.h.
|
||||
* - For manipulating memories, see board_memories.h.
|
||||
*
|
||||
* This file can be used as a template and modified to fit a custom board, with
|
||||
* specific PIOs usage or memory connections.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file board.h
|
||||
*
|
||||
* Definition of AT91SAM3S-EK characteristics, AT91SAM3S-dependant PIOs and
|
||||
* external components interfacing.
|
||||
*/
|
||||
|
||||
#ifndef _BOARD_
|
||||
#define _BOARD_
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include <chip.h>
|
||||
|
||||
|
||||
//#include <include/at45d.h>
|
||||
//#include <include/at45_spi.h>
|
||||
#include <include/board_lowlevel.h>
|
||||
//#include <include/board_memories.h>
|
||||
//#include <include/hamming.h>
|
||||
//#include <include/math.h>
|
||||
//#include <include/uart_console.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \page sam3s_ek_board_info "SAM3S-EK - Board informations"
|
||||
* This page lists several definition related to the board description.
|
||||
*
|
||||
* \section Definitions
|
||||
* - \ref BOARD_NAME
|
||||
*/
|
||||
|
||||
/** Name of the board */
|
||||
#define BOARD_NAME "ATSAM3S-EK"
|
||||
/** Board definition */
|
||||
#define atsam3sek
|
||||
/** Family definition (already defined) */
|
||||
#define atsam3s
|
||||
/** Core definition */
|
||||
#define cortexm3
|
||||
|
||||
/*
|
||||
#define BOARD_REV_A
|
||||
*/
|
||||
#define BOARD_REV_B
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \page sam3s_ek_opfreq "SAM3S-EK - Operating frequencies"
|
||||
* This page lists several definition related to the board operating frequency
|
||||
* (when using the initialization done by board_lowlevel.c).
|
||||
*
|
||||
* \section Definitions
|
||||
* - \ref BOARD_MAINOSC
|
||||
* - \ref BOARD_MCK
|
||||
*/
|
||||
|
||||
/** Frequency of the board main oscillator */
|
||||
#define BOARD_MAINOSC 12000000
|
||||
|
||||
/** Master clock frequency (when using board_lowlevel.c) */
|
||||
// #define BOARD_MCK 64000000
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \page sam3s_ek_piodef "SAM3S-EK - PIO definitions"
|
||||
* This pages lists all the pio definitions contained in board.h. The constants
|
||||
* are named using the following convention: PIN_* for a constant which defines
|
||||
* a single Pin instance (but may include several PIOs sharing the same
|
||||
* controller), and PINS_* for a list of Pin instances.
|
||||
*
|
||||
* ADC
|
||||
* - \ref PIN_ADC0_AD0
|
||||
* - \ref PIN_ADC0_AD1
|
||||
* - \ref PIN_ADC0_AD2
|
||||
* - \ref PIN_ADC0_AD3
|
||||
* - \ref PIN_ADC0_AD4
|
||||
* - \ref PIN_ADC0_AD5
|
||||
* - \ref PIN_ADC0_AD6
|
||||
* - \ref PIN_ADC0_AD7
|
||||
* - \ref PINS_ADC
|
||||
*
|
||||
* UART
|
||||
* - \ref PINS_UART
|
||||
*
|
||||
* EBI
|
||||
* - \ref PIN_EBI_DATA_BUS
|
||||
* - \ref PIN_EBI_NRD
|
||||
* - \ref PIN_EBI_NWE
|
||||
* - \ref PIN_EBI_NCS0
|
||||
* - \ref PIN_EBI_PSRAM_ADDR_BUS
|
||||
* - \ref PIN_EBI_PSRAM_NBS
|
||||
* - \ref PIN_EBI_A1
|
||||
* - \ref PIN_EBI_NCS1
|
||||
* - \ref PIN_EBI_LCD_RS
|
||||
*
|
||||
* LEDs
|
||||
* - \ref PIN_LED_0
|
||||
* - \ref PIN_LED_1
|
||||
* - \ref PIN_LED_2
|
||||
* - \ref PINS_LEDS
|
||||
*
|
||||
* MCI
|
||||
* - \ref PINS_MCI
|
||||
*
|
||||
* Push buttons
|
||||
* - \ref PIN_PUSHBUTTON_1
|
||||
* - \ref PIN_PUSHBUTTON_2
|
||||
* - \ref PINS_PUSHBUTTONS
|
||||
* - \ref PUSHBUTTON_BP1
|
||||
* - \ref PUSHBUTTON_BP2
|
||||
*
|
||||
* PWMC
|
||||
* - \ref PIN_PWMC_PWMH0
|
||||
* - \ref PIN_PWMC_PWML0
|
||||
* - \ref PIN_PWMC_PWMH1
|
||||
* - \ref PIN_PWMC_PWML1
|
||||
* - \ref PIN_PWMC_PWMH2
|
||||
* - \ref PIN_PWMC_PWML2
|
||||
* - \ref PIN_PWMC_PWMH3
|
||||
* - \ref PIN_PWMC_PWML3
|
||||
* - \ref PIN_PWM_LED0
|
||||
* - \ref PIN_PWM_LED1
|
||||
* - \ref PIN_PWM_LED2
|
||||
* - \ref CHANNEL_PWM_LED0
|
||||
* - \ref CHANNEL_PWM_LED1
|
||||
* - \ref CHANNEL_PWM_LED2
|
||||
*
|
||||
* SPI
|
||||
* - \ref PIN_SPI_MISO
|
||||
* - \ref PIN_SPI_MOSI
|
||||
* - \ref PIN_SPI_SPCK
|
||||
* - \ref PINS_SPI
|
||||
* - \ref PIN_SPI_NPCS0_PA11
|
||||
*
|
||||
* SSC
|
||||
* - \ref PIN_SSC_TD
|
||||
* - \ref PIN_SSC_TK
|
||||
* - \ref PIN_SSC_TF
|
||||
* - \ref PINS_SSC_CODEC
|
||||
*
|
||||
* PCK0
|
||||
* - \ref PIN_PCK0
|
||||
*
|
||||
* PIO PARALLEL CAPTURE
|
||||
* - \ref PIN_PIODCEN1
|
||||
* - \ref PIN_PIODCEN2
|
||||
*
|
||||
* TWI
|
||||
* - \ref TWI_V3XX
|
||||
* - \ref PIN_TWI_TWD0
|
||||
* - \ref PIN_TWI_TWCK0
|
||||
* - \ref PINS_TWI0
|
||||
* - \ref PIN_TWI_TWD1
|
||||
* - \ref PIN_TWI_TWCK1
|
||||
* - \ref PINS_TWI1
|
||||
*
|
||||
* USART0
|
||||
* - \ref PIN_USART0_RXD
|
||||
* - \ref PIN_USART0_TXD
|
||||
* - \ref PIN_USART0_CTS
|
||||
* - \ref PIN_USART0_RTS
|
||||
* - \ref PIN_USART0_SCK
|
||||
*
|
||||
* USB
|
||||
* - \ref PIN_USB_VBUS
|
||||
*
|
||||
* NandFlash
|
||||
* - \ref PIN_EBI_NANDOE
|
||||
* - \ref PIN_EBI_NANDWE
|
||||
* - \ref PIN_EBI_NANDCLE
|
||||
* - \ref PIN_EBI_NANDALE
|
||||
* - \ref PIN_EBI_NANDIO
|
||||
* - \ref BOARD_NF_CE_PIN
|
||||
* - \ref BOARD_NF_RB_PIN
|
||||
* - \ref PINS_NANDFLASH
|
||||
*
|
||||
* QTouch
|
||||
* PIO definitions for Slider
|
||||
* \ref SLIDER_IOMASK_SNS
|
||||
* \ref SLIDER_IOMASK_SNSK
|
||||
* \ref PINS_SLIDER_SNS
|
||||
* \ref PINS_SLIDER_SNSK
|
||||
*
|
||||
* PIO definitions for keys
|
||||
* \ref KEY_IOMASK_SNS
|
||||
* \ref KEY_IOMASK_SNSK
|
||||
* \ref PINS_KEY_SNS
|
||||
* \ref PINS_KEY_SNSK
|
||||
*
|
||||
* PIOS for QTouch
|
||||
* \ref PINS_QTOUCH
|
||||
*/
|
||||
|
||||
/** ADC_AD0 pin definition. */
|
||||
#define PIN_ADC0_AD0 {1 << 21, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||
/** ADC_AD1 pin definition. */
|
||||
#define PIN_ADC0_AD1 {1 << 30, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||
/** ADC_AD2 pin definition. */
|
||||
#define PIN_ADC0_AD2 {1 << 3, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
|
||||
/** ADC_AD3 pin definition. */
|
||||
#define PIN_ADC0_AD3 {1 << 4, PIOB, ID_PIOB, PIO_INPUT, PIO_DEFAULT}
|
||||
/** ADC_AD4 pin definition. */
|
||||
#define PIN_ADC0_AD4 {1 << 15, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
|
||||
/** ADC_AD5 pin definition. */
|
||||
#define PIN_ADC0_AD5 {1 << 16, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
|
||||
/** ADC_AD6 pin definition. */
|
||||
#define PIN_ADC0_AD6 {1 << 17, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
|
||||
/** ADC_AD7 pin definition. */
|
||||
#define PIN_ADC0_AD7 {1 << 18, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
|
||||
|
||||
/** Pins ADC */
|
||||
#define PINS_ADC PIN_ADC0_AD0, PIN_ADC0_AD1, PIN_ADC0_AD2, PIN_ADC0_AD3, PIN_ADC0_AD4, PIN_ADC0_AD5, PIN_ADC0_AD6, PIN_ADC0_AD7
|
||||
|
||||
/** Startup time max, return from Idle mode (in µs) */
|
||||
#define ADC_STARTUP_TIME_MAX 15
|
||||
/** Track and hold Acquisition Time min (in ns) */
|
||||
#define ADC_TRACK_HOLD_TIME_MIN 1200
|
||||
/** ADC clock frequence */
|
||||
#define BOARD_ADC_FREQ (6000000)
|
||||
|
||||
/** UART pins (UTXD0 and URXD0) definitions, PA9,10. */
|
||||
#define PINS_UART {0x00000600, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
|
||||
/** EBI Data Bus pins */
|
||||
#define PIN_EBI_DATA_BUS {0xFF, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** EBI NRD pin */
|
||||
#define PIN_EBI_NRD {1 << 11, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** EBI NWE pin */
|
||||
#define PIN_EBI_NWE {1 << 8, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** EBI NCS0 pin */
|
||||
#define PIN_EBI_NCS0 {1 << 20, PIOB, ID_PIOB, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** EBI pins for PSRAM address bus */
|
||||
#define PIN_EBI_PSRAM_ADDR_BUS {0x3f00fff, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** EBI pins for PSRAM NBS pins */
|
||||
#define PIN_EBI_PSRAM_NBS {1 << 7, PIOB, ID_PIOB, PIO_PERIPH_B, PIO_PULLUP}, \
|
||||
{1 << 15, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** EBI A1 pin */
|
||||
#define PIN_EBI_A1 {1 << 19, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** EBI NCS1 pin */
|
||||
#define PIN_EBI_NCS1 {1 << 15, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP} /* LCD CS pin */
|
||||
/** EBI pin for LCD RS */
|
||||
#define PIN_EBI_LCD_RS {1 << 19, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP} /* LCD RS pin */
|
||||
|
||||
#define LED_BLUE 0
|
||||
#define LED_GREEN 1
|
||||
#define LED_RED 2
|
||||
|
||||
#ifdef BOARD_REV_A
|
||||
/** LED #0 pin definition (BLUE). */
|
||||
#define PIN_LED_0 {PIO_PC20, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||
/** LED #1 pin definition (GREEN). */
|
||||
#define PIN_LED_1 {PIO_PC21, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||
/** LED #2 pin definition (RED). */
|
||||
#define PIN_LED_2 {PIO_PC22, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_REV_B
|
||||
/** LED #0 pin definition (BLUE). */
|
||||
#define PIN_LED_0 {PIO_PA19, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||
/** LED #1 pin definition (GREEN). */
|
||||
#define PIN_LED_1 {PIO_PA20, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||
/** LED #2 pin definition (RED). */
|
||||
#define PIN_LED_2 {PIO_PC20, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||
|
||||
#endif
|
||||
|
||||
/** List of all LEDs definitions. */
|
||||
#define PINS_LEDS PIN_LED_0, PIN_LED_1, PIN_LED_2
|
||||
|
||||
/** MCI pins definition. */
|
||||
#define PINS_MCI {0x3fUL << 26, PIOA, ID_PIOA, PIO_PERIPH_C, PIO_PULLUP}
|
||||
/** MCI pin Card Detect. */
|
||||
#ifdef BOARD_REV_A
|
||||
#define PIN_MCI_CD {PIO_PA15, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_REV_B
|
||||
#define PIN_MCI_CD {PIO_PA6, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
|
||||
#endif
|
||||
|
||||
/** Push button #0 definition. Attributes = pull-up + debounce + interrupt on rising edge. */
|
||||
#define PIN_PUSHBUTTON_1 {PIO_PB3, PIOB, ID_PIOB, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_RISE_EDGE}
|
||||
/** Push button #1 definition. Attributes = pull-up + debounce + interrupt on falling edge. */
|
||||
#define PIN_PUSHBUTTON_2 {PIO_PC12, PIOC, ID_PIOC, PIO_INPUT, PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_FALL_EDGE}
|
||||
/** List of all push button definitions. */
|
||||
#define PINS_PUSHBUTTONS PIN_PUSHBUTTON_1, PIN_PUSHBUTTON_2
|
||||
|
||||
/** Push button #1 index. */
|
||||
#define PUSHBUTTON_BP1 0
|
||||
/** Push button #2 index. */
|
||||
#define PUSHBUTTON_BP2 1
|
||||
|
||||
/** Simulated joystick LEFT index. */
|
||||
#define JOYSTICK_LEFT 0
|
||||
/** Simulated joystick RIGHT index. */
|
||||
#define JOYSTICK_RIGHT 1
|
||||
|
||||
/** PWMC PWM0 pin definition: Output High. */
|
||||
#define PIN_PWMC_PWMH0 {PIO_PC18B_PWMH0, PIOC, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT}
|
||||
/** PWMC PWM0 pin definition: Output Low. */
|
||||
#define PIN_PWMC_PWML0 {PIO_PA19B_PWML0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||
/** PWMC PWM1 pin definition: Output High. */
|
||||
#define PIN_PWMC_PWMH1 {PIO_PC19B_PWMH1, PIOC, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT}
|
||||
/** PWMC PWM1 pin definition: Output Low. */
|
||||
#define PIN_PWMC_PWML1 {PIO_PA20B_PWML1, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||
/** PWMC PWM2 pin definition: Output High. */
|
||||
#define PIN_PWMC_PWMH2 {PIO_PC20B_PWMH2, PIOC, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT}
|
||||
/** PWMC PWM2 pin definition: Output Low. */
|
||||
#define PIN_PWMC_PWML2 {PIO_PA16C_PWML2, PIOA, ID_PIOA, PIO_PERIPH_C, PIO_DEFAULT}
|
||||
/** PWMC PWM3 pin definition: Output High. */
|
||||
#define PIN_PWMC_PWMH3 {PIO_PC21B_PWMH3, PIOC, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT}
|
||||
/** PWMC PWM3 pin definition: Output Low. */
|
||||
#define PIN_PWMC_PWML3 {PIO_PA15C_PWML3, PIOA, ID_PIOA, PIO_PERIPH_C, PIO_DEFAULT}
|
||||
/** PWM pins definition for LED0 */
|
||||
#define PIN_PWM_LED0 PIN_PWMC_PWMH0, PIN_PWMC_PWML0
|
||||
/** PWM pins definition for LED1 */
|
||||
#define PIN_PWM_LED1 PIN_PWMC_PWMH1, PIN_PWMC_PWML1
|
||||
/** PWM pins definition for LED2 */
|
||||
#define PIN_PWM_LED2 PIN_PWMC_PWMH2, PIN_PWMC_PWML2
|
||||
/** PWM channel for LED0 */
|
||||
#define CHANNEL_PWM_LED0 0
|
||||
/** PWM channel for LED1 */
|
||||
#define CHANNEL_PWM_LED1 1
|
||||
/** PWM channel for LED2 */
|
||||
#define CHANNEL_PWM_LED2 2
|
||||
|
||||
/** SPI MISO pin definition. */
|
||||
#define PIN_SPI_MISO {PIO_PA12A_MISO, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** SPI MOSI pin definition. */
|
||||
#define PIN_SPI_MOSI {PIO_PA13A_MOSI, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** SPI SPCK pin definition. */
|
||||
#define PIN_SPI_SPCK {PIO_PA14A_SPCK, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** SPI chip select pin definition. */
|
||||
#define PIN_SPI_NPCS0_PA11 {PIO_PA11A_NPCS0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** List of SPI pin definitions (MISO, MOSI & SPCK). */
|
||||
#define PINS_SPI PIN_SPI_MISO, PIN_SPI_MOSI, PIN_SPI_SPCK
|
||||
|
||||
/** SSC pin Transmitter Data (TD) */
|
||||
#define PIN_SSC_TD {PIO_PA17A_TD, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** SSC pin Transmitter Clock (TK) */
|
||||
#define PIN_SSC_TK {PIO_PA16A_TK, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** SSC pin Transmitter FrameSync (TF) */
|
||||
#define PIN_SSC_TF {PIO_PA15A_TF, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** SSC pins definition for codec. */
|
||||
#define PINS_SSC_CODEC PIN_SSC_TD, PIN_SSC_TK, PIN_SSC_TF
|
||||
|
||||
/** PCK0 */
|
||||
#define PIN_PCK0 {PIO_PA6B_PCK0, PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||
#define PIN_PCK1 {PIO_PA17B_PCK1,PIOA, ID_PIOA, PIO_PERIPH_B, PIO_DEFAULT}
|
||||
|
||||
/** PIO PARALLEL CAPTURE */
|
||||
/** Parallel Capture Mode Data Enable1 */
|
||||
#define PIN_PIODCEN1 PIO_PA15
|
||||
/** Parallel Capture Mode Data Enable2 */
|
||||
#define PIN_PIODCEN2 PIO_PA16
|
||||
|
||||
/** TWI ver 3.xx */
|
||||
#define TWI_V3XX
|
||||
/** TWI0 data pin */
|
||||
#define PIN_TWI_TWD0 {PIO_PA3A_TWD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** TWI0 clock pin */
|
||||
#define PIN_TWI_TWCK0 {PIO_PA4A_TWCK0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** TWI0 pins */
|
||||
#define PINS_TWI0 PIN_TWI_TWD0, PIN_TWI_TWCK0
|
||||
/** TWI1 data pin */
|
||||
#define PIN_TWI_TWD1 {PIO_PB4A_TWD1, PIOB, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** TWI1 clock pin */
|
||||
#define PIN_TWI_TWCK1 {PIO_PB5A_TWCK1, PIOB, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** TWI1 pins */
|
||||
#define PINS_TWI1 PIN_TWI_TWD1, PIN_TWI_TWCK1
|
||||
|
||||
/** USART0 pin RX */
|
||||
#define PIN_USART0_RXD {PIO_PA5A_RXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** USART0 pin TX */
|
||||
#define PIN_USART0_TXD {PIO_PA6A_TXD0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** USART0 pin CTS */
|
||||
#define PIN_USART0_CTS {PIO_PA8A_CTS0, PIOB, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** USART0 pin RTS */
|
||||
#define PIN_USART0_RTS {PIO_PA7A_RTS0, PIOB, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** USART0 pin SCK */
|
||||
#define PIN_USART0_SCK {PIO_PA2B_SCK0, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
|
||||
/** USART1 pin RX */
|
||||
#define PIN_USART1_RXD {PIO_PA21A_RXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** USART1 pin TX */
|
||||
#define PIN_USART1_TXD {PIO_PA22A_TXD1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** USART1 pin CTS */
|
||||
#define PIN_USART1_CTS {PIO_PA25A_CTS1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** USART1 pin RTS */
|
||||
#define PIN_USART1_RTS {PIO_PA24A_RTS1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
/** USART1 pin ENABLE */
|
||||
#define PIN_USART1_EN {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||
/** USART1 pin SCK */
|
||||
#define PIN_USART1_SCK {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
|
||||
|
||||
/** USB VBus monitoring pin definition. */
|
||||
#ifdef BOARD_REV_A
|
||||
#define PIN_USB_VBUS {PIO_PC23, PIOC, ID_PIOC, PIO_INPUT, PIO_PULLUP}
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_REV_B
|
||||
#define PIN_USB_VBUS {PIO_PC21, PIOC, ID_PIOC, PIO_INPUT, PIO_PULLUP}
|
||||
#endif
|
||||
|
||||
/** NandFlash pins definition: OE. */
|
||||
#define PIN_EBI_NANDOE {PIO_PC9, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** NandFlash pins definition: WE. */
|
||||
#define PIN_EBI_NANDWE {PIO_PC10, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** NandFlash pins definition: CLE. */
|
||||
#define PIN_EBI_NANDCLE {PIO_PC17, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** NandFlash pins definition: ALE. */
|
||||
#define PIN_EBI_NANDALE {PIO_PC16, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
/** NandFlash pins definition: DATA. */
|
||||
#define PIN_EBI_NANDIO {0x000000FF, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_PULLUP}
|
||||
|
||||
/** Nandflash chip enable pin definition. */
|
||||
#define BOARD_NF_CE_PIN {PIO_PC14, PIOC, ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
|
||||
|
||||
/** Nandflash controller peripheral pins definition. */
|
||||
#define PINS_NANDFLASH PIN_EBI_NANDIO, BOARD_NF_CE_PIN, PIN_EBI_NANDOE, \
|
||||
PIN_EBI_NANDWE, PIN_EBI_NANDCLE, PIN_EBI_NANDALE
|
||||
|
||||
/* PIO definitions for Slider */
|
||||
#define SLIDER_IOMASK_SNS (uint32_t)(PIO_PA0 | PIO_PA2 | PIO_PA4)
|
||||
#define SLIDER_IOMASK_SNSK (uint32_t)(PIO_PA1 | PIO_PA3 | PIO_PA5)
|
||||
#define PINS_SLIDER_SNS {SLIDER_IOMASK_SNS, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||
#define PINS_SLIDER_SNSK {SLIDER_IOMASK_SNSK, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||
|
||||
/* PIO definitions for keys */
|
||||
#define KEY_IOMASK_SNS (uint32_t)(PIO_PC22 | PIO_PC24 | PIO_PC26 | PIO_PC28 | PIO_PC30)
|
||||
#define KEY_IOMASK_SNSK (uint32_t)(PIO_PC23 | PIO_PC25 | PIO_PC27 | PIO_PC29 | PIO_PC31)
|
||||
#define PINS_KEY_SNS {KEY_IOMASK_SNS, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
|
||||
#define PINS_KEY_SNSK {KEY_IOMASK_SNSK, PIOC, ID_PIOC, PIO_INPUT, PIO_DEFAULT}
|
||||
|
||||
/* PIOS for QTouch */
|
||||
#define PINS_QTOUCH PINS_SLIDER_SNS, PINS_SLIDER_SNSK, PINS_KEY_SNS, PINS_KEY_SNSK
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \page sam3s_ek_usb "SAM3S-EK - USB device"
|
||||
*
|
||||
* \section Definitions
|
||||
* - \ref BOARD_USB_BMATTRIBUTES
|
||||
* - \ref CHIP_USB_UDP
|
||||
* - \ref CHIP_USB_PULLUP_INTERNAL
|
||||
* - \ref CHIP_USB_NUMENDPOINTS
|
||||
* - \ref CHIP_USB_ENDPOINTS_MAXPACKETSIZE
|
||||
* - \ref CHIP_USB_ENDPOINTS_BANKS
|
||||
*/
|
||||
|
||||
/** USB attributes configuration descriptor (bus or self powered, remote wakeup) */
|
||||
#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_SELFPOWERED_RWAKEUP
|
||||
|
||||
/** Indicates chip has an UDP Full Speed. */
|
||||
#define CHIP_USB_UDP
|
||||
|
||||
/** Indicates chip has an internal pull-up. */
|
||||
#define CHIP_USB_PULLUP_INTERNAL
|
||||
|
||||
/** Number of USB endpoints */
|
||||
#define CHIP_USB_NUMENDPOINTS 8
|
||||
|
||||
/** Endpoints max paxcket size */
|
||||
#define CHIP_USB_ENDPOINTS_MAXPACKETSIZE(i) \
|
||||
((i == 0) ? 64 : \
|
||||
((i == 1) ? 64 : \
|
||||
((i == 2) ? 64 : \
|
||||
((i == 3) ? 64 : \
|
||||
((i == 4) ? 512 : \
|
||||
((i == 5) ? 512 : \
|
||||
((i == 6) ? 64 : \
|
||||
((i == 7) ? 64 : 0 ))))))))
|
||||
|
||||
/** Endpoints Number of Bank */
|
||||
#define CHIP_USB_ENDPOINTS_BANKS(i) \
|
||||
((i == 0) ? 1 : \
|
||||
((i == 1) ? 2 : \
|
||||
((i == 2) ? 2 : \
|
||||
((i == 3) ? 1 : \
|
||||
((i == 4) ? 2 : \
|
||||
((i == 5) ? 2 : \
|
||||
((i == 6) ? 2 : \
|
||||
((i == 7) ? 2 : 0 ))))))))
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \page sam3s_ek_extcomp "SAM3S-EK - External components"
|
||||
* This page lists the definitions related to external on-board components
|
||||
* located in the board.h file for the AT91SAM3S-EK.
|
||||
*
|
||||
* SD Card
|
||||
* - \ref BOARD_SD_PINS
|
||||
* - \ref BOARD_SD_PIN_CD
|
||||
*
|
||||
* LCD
|
||||
* - \ref BOARD_LCD_ILI9325
|
||||
* - \ref BOARD_LCD_PINS
|
||||
* - \ref BOARD_BACKLIGHT_PIN
|
||||
* - \ref BOARD_LCD_BASE
|
||||
* - \ref BOARD_LCD_RS
|
||||
* - \ref BOARD_LCD_WIDTH
|
||||
* - \ref BOARD_LCD_HEIGHT
|
||||
*
|
||||
* TouchScreen
|
||||
* - \ref BOARD_TSC_ADS7843
|
||||
* - \ref PIN_TCS_IRQ
|
||||
* - \ref PIN_TCS_BUSY
|
||||
* - \ref BOARD_TSC_SPI_BASE
|
||||
* - \ref BOARD_TSC_SPI_ID
|
||||
* - \ref BOARD_TSC_SPI_PINS
|
||||
* - \ref BOARD_TSC_NPCS
|
||||
* - \ref BOARD_TSC_NPCS_PIN
|
||||
*
|
||||
* SmartCard
|
||||
* - \ref SMARTCARD_CONNECT_PIN
|
||||
* - \ref PIN_ISO7816_RSTMC
|
||||
* - \ref PINS_ISO7816
|
||||
*/
|
||||
|
||||
/** MCI pins that shall be configured to access the SD card. */
|
||||
#define BOARD_SD_PINS PINS_MCI
|
||||
/** MCI Card Detect pin. */
|
||||
#define BOARD_SD_PIN_CD PIN_MCI_CD
|
||||
|
||||
/** Indicates board has an ILI9325 external component to manage LCD. */
|
||||
#define BOARD_LCD_ILI9325
|
||||
|
||||
/** LCD pins definition. */
|
||||
#define BOARD_LCD_PINS PIN_EBI_DATA_BUS, PIN_EBI_NRD, PIN_EBI_NWE, PIN_EBI_NCS1, PIN_EBI_LCD_RS
|
||||
/** Backlight pin definition. */
|
||||
#define BOARD_BACKLIGHT_PIN {PIO_PC13, PIOC, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||
/** Define ILI9325 base address. */
|
||||
#define BOARD_LCD_BASE 0x61000000
|
||||
/** Define ILI9325 register select signal. */
|
||||
#define BOARD_LCD_RS (1 << 1)
|
||||
/** Display width in pixels. */
|
||||
#define BOARD_LCD_WIDTH 240
|
||||
/** Display height in pixels. */
|
||||
#define BOARD_LCD_HEIGHT 320
|
||||
|
||||
/** Indicates board has an ADS7843 external component to manage Touch Screen */
|
||||
#define BOARD_TSC_ADS7843
|
||||
|
||||
/** Touchscreen controller IRQ pin definition. */
|
||||
#ifdef BOARD_REV_A
|
||||
#define PIN_TSC_IRQ {PIO_PA4, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
|
||||
#define PIN_TSC_IRQ_WUP_ID (1 << 3)
|
||||
/** Touchscreen controller Busy pin definition. */
|
||||
#define PIN_TSC_BUSY {PIO_PA5, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
|
||||
#endif
|
||||
|
||||
#ifdef BOARD_REV_B
|
||||
#define PIN_TSC_IRQ {PIO_PA16, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
|
||||
#define PIN_TSC_IRQ_WUP_ID (1 << 15)
|
||||
/** Touchscreen controller Busy pin definition. */
|
||||
#define PIN_TSC_BUSY {PIO_PA17, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP}
|
||||
#endif
|
||||
|
||||
/** Base address of SPI peripheral connected to the touchscreen controller. */
|
||||
#define BOARD_TSC_SPI_BASE SPI
|
||||
/** Identifier of SPI peripheral connected to the touchscreen controller. */
|
||||
#define BOARD_TSC_SPI_ID ID_SPI
|
||||
/** Pins of the SPI peripheral connected to the touchscreen controller. */
|
||||
#define BOARD_TSC_SPI_PINS PINS_SPI
|
||||
/** Chip select connected to the touchscreen controller. */
|
||||
#define BOARD_TSC_NPCS 0
|
||||
/** Chip select pin connected to the touchscreen controller. */
|
||||
#define BOARD_TSC_NPCS_PIN PIN_SPI_NPCS0_PA11
|
||||
|
||||
/// Smartcard detection pin
|
||||
//#define SMARTCARD_CONNECT_PIN {1 << 13, PIOA, ID_PIOA, PIO_INPUT, PIO_DEFAULT}
|
||||
|
||||
/// PIN used for reset the smartcard
|
||||
#define PIN_ISO7816_RSTMC {1 << 11, PIOA, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT}
|
||||
/// Pins used for connect the smartcard
|
||||
#define PINS_ISO7816 PIN_USART1_TXD, PIN_USART1_SCK, PIN_ISO7816_RSTMC
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \page sam3s_ek_mem "SAM3S-EK - Memories"
|
||||
* This page lists definitions related to internal & external on-board memories.
|
||||
*
|
||||
* \section SRAM
|
||||
* - \ref AT91C_ISRAM
|
||||
* - \ref AT91C_ISRAM_SIZE
|
||||
*
|
||||
* \section Flash
|
||||
* - \ref AT91C_IFLASH_SIZE
|
||||
* - \ref AT91C_IFLASH_PAGE_SIZE
|
||||
* - \ref AT91C_IFLASH_NB_OF_PAGES
|
||||
* - \ref AT91C_IFLASH_LOCK_REGION_SIZE
|
||||
* - \ref AT91C_IFLASH_NB_OF_LOCK_BITS
|
||||
*
|
||||
* \section NandFlash
|
||||
* - \ref BOARD_NF_COMMAND_ADDR
|
||||
* - \ref BOARD_NF_ADDRESS_ADDR
|
||||
* - \ref BOARD_NF_DATA_ADDR
|
||||
*
|
||||
* \section NorFlash
|
||||
* - \ref BOARD_NORFLASH_ADDR
|
||||
* - \ref BOARD_NORFLASH_DFT_BUS_SIZE
|
||||
*/
|
||||
|
||||
/** Address for transferring command bytes to the nandflash. */
|
||||
#define BOARD_NF_COMMAND_ADDR 0x60400000
|
||||
/** Address for transferring address bytes to the nandflash. */
|
||||
#define BOARD_NF_ADDRESS_ADDR 0x60200000
|
||||
/** Address for transferring data bytes to the nandflash. */
|
||||
#define BOARD_NF_DATA_ADDR 0x60000000
|
||||
|
||||
/** Address for transferring command bytes to the norflash. */
|
||||
#define BOARD_NORFLASH_ADDR 0x63000000
|
||||
/** Default NOR bus size after power up reset */
|
||||
#define BOARD_NORFLASH_DFT_BUS_SIZE 8
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \page sam3s_ek_chipdef "SAM3S-EK - Individual chip definition"
|
||||
* This page lists the definitions related to different chip's definition
|
||||
* located in the board.h file for the SAM3S-EK.
|
||||
*
|
||||
* \section USART
|
||||
* - \ref BOARD_PIN_USART_RXD
|
||||
* - \ref BOARD_PIN_USART_TXD
|
||||
* - \ref BOARD_PIN_USART_CTS
|
||||
* - \ref BOARD_PIN_USART_RTS
|
||||
* - \ref BOARD_PIN_USART_EN
|
||||
* - \ref BOARD_USART_BASE
|
||||
* - \ref BOARD_ID_USART
|
||||
*/
|
||||
|
||||
/** Rtc */
|
||||
#define BOARD_RTC_ID ID_RTC
|
||||
|
||||
/** TWI ID for EEPROM application to use */
|
||||
#define BOARD_ID_TWI_EEPROM ID_TWI1
|
||||
/** TWI ID for SLAVE application to use */
|
||||
#define BOARD_ID_TWI_SLAVE ID_TWI1
|
||||
/** TWI Base for TWI EEPROM application to use */
|
||||
#define BOARD_BASE_TWI_EEPROM TWI1
|
||||
/** TWI Base for TWI SLAVE application to use */
|
||||
#define BOARD_BASE_TWI_SLAVE TWI1
|
||||
/** TWI pins for EEPROM application to use */
|
||||
#define BOARD_PINS_TWI_EEPROM PINS_TWI1
|
||||
/** TWI pins for TWI SLAVE application to use */
|
||||
#define BOARD_PINS_TWI_SLAVE PINS_TWI1
|
||||
|
||||
/** USART RX pin for application */
|
||||
#define BOARD_PIN_USART_RXD PIN_USART1_RXD
|
||||
/** USART TX pin for application */
|
||||
#define BOARD_PIN_USART_TXD PIN_USART1_TXD
|
||||
/** USART CTS pin for application */
|
||||
#define BOARD_PIN_USART_CTS PIN_USART1_CTS
|
||||
/** USART RTS pin for application */
|
||||
#define BOARD_PIN_USART_RTS PIN_USART1_RTS
|
||||
/** USART ENABLE pin for application */
|
||||
#define BOARD_PIN_USART_EN PIN_USART1_EN
|
||||
/** USART Base for application */
|
||||
#define BOARD_USART_BASE USART1
|
||||
/** USART ID for application */
|
||||
#define BOARD_ID_USART ID_USART1
|
||||
|
||||
#endif /* #ifndef _BOARD_ */
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Interface for the low-level initialization function.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BOARD_LOWLEVEL_H
|
||||
#define BOARD_LOWLEVEL_H
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
extern void LowLevelInit( void ) ;
|
||||
|
||||
#endif /* BOARD_LOWLEVEL_H */
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Linker script for running in internal SRAM on the AT91SAM3S1
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(ResetException)
|
||||
|
||||
/* Memory Spaces Definitions */
|
||||
MEMORY
|
||||
{
|
||||
sram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x00004000 /* sram, 16K */
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.fixed :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sfixed = .;
|
||||
KEEP(*(.vectors))
|
||||
*(.text*)
|
||||
*(.ramfunc)
|
||||
*(.rodata*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
. = ALIGN(4);
|
||||
_efixed = .; /* End of text section */
|
||||
} > sram
|
||||
|
||||
.relocate : AT (_efixed)
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_srelocate = .;
|
||||
*(.data)
|
||||
. = ALIGN(4);
|
||||
_erelocate = .;
|
||||
} >sram
|
||||
|
||||
.bss (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
_szero = .;
|
||||
*(.bss)
|
||||
. = ALIGN(4);
|
||||
_ezero = .;
|
||||
} >sram
|
||||
|
||||
/* Stack in the end of SRAM */
|
||||
_estack = 0x20003FFC;
|
||||
|
||||
}
|
||||
end = .;
|
||||
@@ -0,0 +1,91 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Linker script for running in internal SRAM on the AT91SAM3S1
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(entry)
|
||||
|
||||
/* Memory Spaces Definitions */
|
||||
MEMORY
|
||||
{
|
||||
romcodesram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x0800
|
||||
sram (W!RX) : ORIGIN = 0x20000800, LENGTH = 0x00003800 /* sram, 16K - sizeof(romcodesram) */
|
||||
}
|
||||
|
||||
/* Entry point */
|
||||
/*ENTRY (ResetException)*/
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* startup code in the .isr_vector */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_stext = .;
|
||||
KEEP(*(.isr_vector .isr_vector.*))
|
||||
*(.mailbox)
|
||||
*(.text .text.*)
|
||||
*(.rodata .rodata.*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.gcc_except_table)
|
||||
*(.rodata .rodata*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
. = ALIGN(4);
|
||||
_etext = .;
|
||||
} > sram
|
||||
|
||||
/* data */
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sidata = .;
|
||||
_sdata = .;
|
||||
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} > sram
|
||||
|
||||
.bss (NOLOAD) : {
|
||||
_szero = .;
|
||||
*(.bss)
|
||||
. = ALIGN(4);
|
||||
_ezero = .;
|
||||
} >sram
|
||||
|
||||
/* Stack in SRAM */
|
||||
_sstack = 0x20003FFC;
|
||||
}
|
||||
end = .;
|
||||
@@ -0,0 +1,81 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Linker script for running in internal SRAM on the AT91SAM3S2
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(ResetException)
|
||||
|
||||
/* Memory Spaces Definitions */
|
||||
MEMORY
|
||||
{
|
||||
sram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x00008000 /* sram, 32K */
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.fixed :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sfixed = .;
|
||||
KEEP(*(.vectors))
|
||||
*(.text*)
|
||||
*(.ramfunc)
|
||||
*(.rodata*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
. = ALIGN(4);
|
||||
_efixed = .; /* End of text section */
|
||||
} > sram
|
||||
|
||||
.relocate : AT (_efixed)
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_srelocate = .;
|
||||
*(.data)
|
||||
. = ALIGN(4);
|
||||
_erelocate = .;
|
||||
} >sram
|
||||
|
||||
.bss (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
_szero = .;
|
||||
*(.bss)
|
||||
. = ALIGN(4);
|
||||
_ezero = .;
|
||||
} >sram
|
||||
|
||||
/* Stack in the end of SRAM */
|
||||
_estack = 0x20007FFC;
|
||||
|
||||
}
|
||||
end = .;
|
||||
@@ -0,0 +1,91 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Linker script for running in internal SRAM on the AT91SAM3S2
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(entry)
|
||||
|
||||
/* Memory Spaces Definitions */
|
||||
MEMORY
|
||||
{
|
||||
romcodesram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x0800
|
||||
sram (W!RX) : ORIGIN = 0x20000800, LENGTH = 0x00007800 /* sram, 32K - sizeof(romcodesram) */
|
||||
}
|
||||
|
||||
/* Entry point */
|
||||
/*ENTRY (ResetException)*/
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* startup code in the .isr_vector */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_stext = .;
|
||||
KEEP(*(.isr_vector .isr_vector.*))
|
||||
*(.mailbox)
|
||||
*(.text .text.*)
|
||||
*(.rodata .rodata.*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.gcc_except_table)
|
||||
*(.rodata .rodata*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
. = ALIGN(4);
|
||||
_etext = .;
|
||||
} > sram
|
||||
|
||||
/* data */
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sidata = .;
|
||||
_sdata = .;
|
||||
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} > sram
|
||||
|
||||
.bss (NOLOAD) : {
|
||||
_szero = .;
|
||||
*(.bss)
|
||||
. = ALIGN(4);
|
||||
_ezero = .;
|
||||
} >sram
|
||||
|
||||
/* Stack in SRAM */
|
||||
_sstack = 0x20007FFC;
|
||||
}
|
||||
end = .;
|
||||
@@ -0,0 +1,215 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Linker script for running in internal SRAM on the AT91SAM3S4
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
OUTPUT_FORMAT ("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
ENTRY(_start)
|
||||
SEARCH_DIR(.)
|
||||
GROUP(-lgcc -lc -lcs3 -lcs3unhosted -lcs3micro)
|
||||
|
||||
/* Memory Spaces Definitions */
|
||||
MEMORY
|
||||
{
|
||||
sram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x0000C000 /* sram, 48K */
|
||||
}
|
||||
|
||||
/* These force the linker to search for particular symbols from
|
||||
* the start of the link process and thus ensure the user's
|
||||
* overrides are picked up
|
||||
*/
|
||||
EXTERN(__cs3_reset_generic_m)
|
||||
INCLUDE atsam3s.inc
|
||||
EXTERN(__cs3_interrupt_vector_micro)
|
||||
EXTERN(__cs3_start_c main __cs3_stack __cs3_heap_end)
|
||||
|
||||
PROVIDE(__cs3_heap_start = _end);
|
||||
PROVIDE(__cs3_heap_end = __cs3_region_start_ram + __cs3_region_size_ram);
|
||||
PROVIDE(__cs3_region_num = (__cs3_regions_end - __cs3_regions) / 20);
|
||||
PROVIDE(__cs3_stack = __cs3_region_start_ram + __cs3_region_size_ram);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
.text :
|
||||
{
|
||||
CREATE_OBJECT_SYMBOLS
|
||||
__cs3_region_start_ram = .;
|
||||
*(.cs3.region-head.ram)
|
||||
ASSERT (. == __cs3_region_start_ram, ".cs3.region-head.ram not permitted");
|
||||
__cs3_interrupt_vector = __cs3_interrupt_vector_micro;
|
||||
*(.cs3.interrupt_vector)
|
||||
/* Make sure we pulled in an interrupt vector. */
|
||||
ASSERT (. != __cs3_interrupt_vector_micro, "No interrupt vector");
|
||||
|
||||
_start = __cs3_reset_generic_m;
|
||||
__cs3_reset = __cs3_reset_generic_m;
|
||||
*(.cs3.reset)
|
||||
/* Make sure we pulled in some reset code. */
|
||||
ASSERT (. != __cs3_reset, "No reset code");
|
||||
|
||||
*(.text .text.* .gnu.linkonce.t.*)
|
||||
*(.plt)
|
||||
*(.gnu.warning)
|
||||
*(.glue_7t) *(.glue_7) *(.vfp11_veneer)
|
||||
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
*(.gcc_except_table)
|
||||
} >ram
|
||||
.eh_frame_hdr : ALIGN (4)
|
||||
{
|
||||
KEEP (*(.eh_frame_hdr))
|
||||
} >ram
|
||||
.eh_frame : ALIGN (4)
|
||||
{
|
||||
KEEP (*(.eh_frame))
|
||||
} >ram
|
||||
/* .ARM.exidx is sorted, so has to go in its own output section. */
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
} >ram
|
||||
__exidx_end = .;
|
||||
.rodata : ALIGN (4)
|
||||
{
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.init))
|
||||
|
||||
. = ALIGN(4);
|
||||
__preinit_array_start = .;
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__init_array_start = .;
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
__init_array_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.fini))
|
||||
|
||||
. = ALIGN(4);
|
||||
__fini_array_start = .;
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
__fini_array_end = .;
|
||||
|
||||
. = ALIGN(0x4);
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*crtend.o(.ctors))
|
||||
|
||||
. = ALIGN(0x4);
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*crtend.o(.dtors))
|
||||
|
||||
. = ALIGN(4);
|
||||
__cs3_regions = .;
|
||||
LONG (0)
|
||||
LONG (__cs3_region_init_ram)
|
||||
LONG (__cs3_region_start_ram)
|
||||
LONG (__cs3_region_init_size_ram)
|
||||
LONG (__cs3_region_zero_size_ram)
|
||||
__cs3_regions_end = .;
|
||||
|
||||
. = ALIGN (8);
|
||||
_etext = .;
|
||||
} >ram
|
||||
|
||||
.data : ALIGN (8)
|
||||
{
|
||||
|
||||
KEEP(*(.jcr))
|
||||
*(.got.plt) *(.got)
|
||||
*(.shdata)
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
. = ALIGN (8);
|
||||
*(.ram)
|
||||
_edata = .;
|
||||
} >ram
|
||||
.bss :
|
||||
{
|
||||
*(.shbss)
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN (8);
|
||||
*(.ram.b)
|
||||
_end = .;
|
||||
__end = .;
|
||||
} >ram
|
||||
__cs3_region_init_ram = __cs3_region_start_ram;
|
||||
__cs3_region_init_size_ram = _edata - __cs3_region_start_ram;
|
||||
__cs3_region_zero_size_ram = _end - _edata;
|
||||
/* Default to 1M of heap */
|
||||
__cs3_region_size_ram = ALIGN (1024) - __cs3_region_start_ram + 1M;
|
||||
|
||||
.stab 0 (NOLOAD) : { *(.stab) }
|
||||
.stabstr 0 (NOLOAD) : { *(.stabstr) }
|
||||
/* DWARF debug sections.
|
||||
* Symbols in the DWARF debugging sections are relative to the beginning
|
||||
* of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* DWARF 2.1 */
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
|
||||
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
||||
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) }
|
||||
}
|
||||
/* checksum: 576d003e2604ff7a1b02791267 */
|
||||
@@ -0,0 +1,91 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Linker script for running in internal SRAM on the AT91SAM3S4
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(entry)
|
||||
|
||||
/* Memory Spaces Definitions */
|
||||
MEMORY
|
||||
{
|
||||
romcodesram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x01000
|
||||
sram (W!RX) : ORIGIN = 0x20001000, LENGTH = 0x0000B000 /* sram, 48K - sizeof(romcodesram) */
|
||||
}
|
||||
|
||||
/* Entry point */
|
||||
/*ENTRY (ResetException)*/
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* startup code in the .isr_vector */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_stext = .;
|
||||
KEEP(*(.isr_vector .isr_vector.*))
|
||||
*(.mailbox)
|
||||
*(.text .text.*)
|
||||
*(.rodata .rodata.*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.gcc_except_table)
|
||||
*(.rodata .rodata*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
. = ALIGN(4);
|
||||
_etext = .;
|
||||
} > sram
|
||||
|
||||
/* data */
|
||||
.data :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sidata = .;
|
||||
_sdata = .;
|
||||
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} > sram
|
||||
|
||||
.bss (NOLOAD) : {
|
||||
_szero = .;
|
||||
*(.bss)
|
||||
. = ALIGN(4);
|
||||
_ezero = .;
|
||||
} >sram
|
||||
|
||||
/* Stack in SRAM */
|
||||
_sstack = 0x2000BFFC;
|
||||
}
|
||||
end = .;
|
||||
@@ -0,0 +1,63 @@
|
||||
#ifndef _LIB_ATSAM3S_
|
||||
#define _LIB_ATSAM3S_
|
||||
|
||||
/*
|
||||
* Peripherals registers definitions
|
||||
*/
|
||||
#if defined atsam3s4
|
||||
#include <include/ATSAM3S4.h>
|
||||
#elif defined atsam3s2
|
||||
#include <include/ATSAM3S2.h>
|
||||
#elif defined atsam3s1
|
||||
#include <include/ATSAM3S1.h>
|
||||
#else
|
||||
#warning Library does not support the specified chip, specifying atsam3s4.
|
||||
#define atsam3s4
|
||||
#include <include/ATSAM3S4.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* Define attribute */
|
||||
#if defined ( __CC_ARM ) /* Keil µVision 4 */
|
||||
#define WEAK __attribute__ ((weak))
|
||||
#elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */
|
||||
#define WEAK __weak
|
||||
#elif defined ( __GNUC__ ) /* GCC CS3 2009q3-68 */
|
||||
#define WEAK __attribute__ ((weak))
|
||||
#endif
|
||||
|
||||
/* Define NO_INIT attribute */
|
||||
#if defined ( __CC_ARM )
|
||||
#define NO_INIT
|
||||
#elif defined ( __ICCARM__ )
|
||||
#define NO_INIT __no_init
|
||||
#elif defined ( __GNUC__ )
|
||||
#define NO_INIT
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Core
|
||||
*/
|
||||
|
||||
/*
|
||||
* Peripherals
|
||||
*/
|
||||
//#include <include/async.h>
|
||||
//#include <include/efc.h>
|
||||
//#include <include/flashd.h>
|
||||
//#include <include/pio.h>
|
||||
//#include <include/pmc.h>
|
||||
//#include <include/spi.h>
|
||||
//#include <include/spi_pdc.h>
|
||||
//#include <include/twi.h>
|
||||
//#include <include/twid.h>
|
||||
//#include <include/usart.h>
|
||||
|
||||
/*
|
||||
#include <USBD_Config.h>
|
||||
*/
|
||||
|
||||
//#include <include/trace.h>
|
||||
//#include <include/wdt.h>
|
||||
|
||||
#endif /* _LIB_ATSAM3S_ */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file CoOS.h
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief API header file of CooCox CoOS.
|
||||
* @details This file including all API functions's declare of CooCox CoOS.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _CCRTOS_H
|
||||
#define _CCRTOS_H
|
||||
#include "OsConfig.h"
|
||||
/*---------------------------- Type Define ----------------------------------*/
|
||||
typedef signed char S8;
|
||||
typedef unsigned char U8;
|
||||
typedef short S16;
|
||||
typedef unsigned short U16;
|
||||
typedef int S32;
|
||||
typedef unsigned int U32;
|
||||
typedef long long S64;
|
||||
typedef unsigned long long U64;
|
||||
typedef unsigned char BIT;
|
||||
typedef unsigned char BOOL;
|
||||
typedef unsigned int OS_STK;
|
||||
typedef U8 OS_TID;
|
||||
typedef U8 OS_TCID;
|
||||
typedef U8 OS_MutexID;
|
||||
typedef U8 OS_EventID;
|
||||
typedef U8 OS_FlagID;
|
||||
typedef U8 OS_MMID;
|
||||
typedef U8 StatusType;
|
||||
typedef U16 OS_VER;
|
||||
typedef void (*FUNCPtr)(void*);
|
||||
typedef void (*vFUNCPtr)(void);
|
||||
|
||||
|
||||
/*---------------------------- Constant Define -------------------------------*/
|
||||
#ifndef Co_NULL
|
||||
#define Co_NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
#ifndef Co_FALSE
|
||||
#define Co_FALSE (0)
|
||||
#endif
|
||||
|
||||
#ifndef Co_TRUE
|
||||
#define Co_TRUE (1)
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------- Error Codes ---------------------------------*/
|
||||
#define E_CREATE_FAIL (StatusType)-1
|
||||
#define E_OK (StatusType)0
|
||||
#define E_INVALID_ID (StatusType)1
|
||||
#define E_INVALID_PARAMETER (StatusType)2
|
||||
#define E_CALL (StatusType)3
|
||||
#define E_TASK_WAITING (StatusType)4
|
||||
#define E_TIMEOUT (StatusType)5
|
||||
#define E_SEM_FULL (StatusType)6
|
||||
#define E_MBOX_FULL (StatusType)7
|
||||
#define E_QUEUE_FULL (StatusType)8
|
||||
#define E_SEM_EMPTY (StatusType)9
|
||||
#define E_MBOX_EMPTY (StatusType)10
|
||||
#define E_QUEUE_EMPTY (StatusType)11
|
||||
#define E_FLAG_NOT_READY (StatusType)12
|
||||
#define E_ALREADY_IN_WAITING (StatusType)13
|
||||
#define E_TASK_NOT_WAITING (StatusType)14
|
||||
#define E_TASK_WAIT_OTHER (StatusType)15
|
||||
#define E_EXCEED_MAX_NUM (StatusType)16
|
||||
#define E_NOT_IN_DELAY_LIST (StatusType)17
|
||||
#define E_SEV_REQ_FULL (StatusType)18
|
||||
#define E_NOT_FREE_ALL (StatusType)19
|
||||
#define E_PROTECTED_TASK (StatusType)20
|
||||
#define E_OS_IN_LOCK (StatusType)21
|
||||
|
||||
|
||||
/*---------------------------- Wait Opreation type --------------------------*/
|
||||
#define OPT_WAIT_ALL 0 /*!< Wait for all flags. */
|
||||
#define OPT_WAIT_ANY 1 /*!< Wait for any one of flags. */
|
||||
#define OPT_WAIT_ONE 2 /*!< Waot for one flag. */
|
||||
|
||||
|
||||
/*---------------------------- Delete Opreation type ------------------------*/
|
||||
#define OPT_DEL_NO_PEND 0 /*!< Delete when no task waitting for */
|
||||
#define OPT_DEL_ANYWAY 1 /*!< Delete always. */
|
||||
|
||||
|
||||
/*---------------------------- Timer Types ----------------------------------*/
|
||||
#if CFG_TMR_EN >0
|
||||
#define TMR_TYPE_ONE_SHOT 0 /*!< Timer counter type: One-shot */
|
||||
#define TMR_TYPE_PERIODIC 1 /*!< Timer counter type: Periodic */
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------- Event Control ---------------------------------*/
|
||||
#if CFG_EVENT_EN >0
|
||||
#define EVENT_SORT_TYPE_FIFO (U8)0x01 /*!< Insert a event by FIFO */
|
||||
#define EVENT_SORT_TYPE_PRIO (U8)0x02 /*!< Insert a event by prio */
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------------- Function declare-------------------------------*/
|
||||
|
||||
/* Implement in file "core.c" */
|
||||
extern void CoInitOS(void); /*!< Initialize OS */
|
||||
extern void CoStartOS(void); /*!< Start multitask */
|
||||
extern void CoEnterISR(void); /*!< Enter a ISR */
|
||||
extern void CoExitISR(void); /*!< Exit a ISR */
|
||||
extern void CoSchedLock(void);
|
||||
extern void CoSchedUnlock(void);
|
||||
extern OS_VER CoGetOSVersion(void); /*!< Get OS version value */
|
||||
|
||||
|
||||
/* Implement in file "task.c" */
|
||||
#define CoCreateTask(task,argv,prio,stk,stkSz) \
|
||||
CreateTask(task,argv,(prio)|(((stkSz)<<8) &0x000FFF00 ),stk)
|
||||
|
||||
|
||||
#define CoCreateTaskEx(task,argv,prio,stk,stkSz,timeSlice,isWaitting) \
|
||||
CreateTask(task,argv,(prio)|(((stkSz)<<8)&0x000FFF00)|(((timeSlice)<<20)&0x7FF00000)|((isWaitting<<31)&0x80000000),stk)
|
||||
|
||||
extern void CoExitTask(void);
|
||||
extern OS_TID CoGetCurTaskID(void);
|
||||
extern StatusType CoDelTask(OS_TID taskID);
|
||||
extern StatusType CoActivateTask(OS_TID taskID,void *argv);
|
||||
extern StatusType CoAwakeTask(OS_TID taskID);
|
||||
extern StatusType CoSuspendTask(OS_TID taskID);
|
||||
extern StatusType CoSetPriority(OS_TID taskID,U8 priority);
|
||||
extern OS_TID CreateTask(FUNCPtr task,void *argv,U32 parameter,OS_STK *stk);
|
||||
|
||||
/* Implement in file "time.c" */
|
||||
extern U64 CoGetOSTime(void);
|
||||
extern StatusType CoTickDelay(U32 ticks);
|
||||
extern StatusType CoResetTaskDelayTick(OS_TID taskID,U32 ticks);
|
||||
extern StatusType CoTimeDelay(U8 hour,U8 minute,U8 sec,U16 millsec);
|
||||
|
||||
|
||||
/* Implement in file "timer.c" */
|
||||
extern StatusType CoDelTmr(OS_TCID tmrID);
|
||||
extern StatusType CoStopTmr(OS_TCID tmrID);
|
||||
extern StatusType CoStartTmr(OS_TCID tmrID);
|
||||
extern U32 CoGetCurTmrCnt(OS_TCID tmrID,StatusType* perr);
|
||||
extern StatusType CoSetTmrCnt(OS_TCID tmrID,U32 tmrCnt,U32 tmrReload);
|
||||
extern OS_TCID CoCreateTmr(U8 tmrType, U32 tmrCnt, U32 tmrReload, vFUNCPtr func);
|
||||
|
||||
|
||||
/* Implement in file "kernelHeap.c"*/
|
||||
extern void* CoKmalloc(U32 size);
|
||||
extern void CoKfree(void* memBuf);
|
||||
|
||||
|
||||
/* Implement in file "mm.c" */
|
||||
extern void* CoGetMemoryBuffer(OS_MMID mmID);
|
||||
extern StatusType CoDelMemoryPartition(OS_MMID mmID);
|
||||
extern StatusType CoFreeMemoryBuffer(OS_MMID mmID,void* buf);
|
||||
extern U32 CoGetFreeBlockNum(OS_MMID mmID,StatusType* perr);
|
||||
extern OS_MMID CoCreateMemPartition(U8* memBuf,U32 blockSize,U32 blockNum);
|
||||
|
||||
/* Implement in file "mutex.c" */
|
||||
extern OS_MutexID CoCreateMutex(void);
|
||||
extern StatusType CoEnterMutexSection(OS_MutexID mutexID);
|
||||
extern StatusType CoLeaveMutexSection(OS_MutexID mutexID);
|
||||
|
||||
|
||||
/* Implement in file "sem.c" */
|
||||
extern StatusType CoPostSem(OS_EventID id);
|
||||
extern StatusType CoAcceptSem(OS_EventID id);
|
||||
extern StatusType isr_PostSem(OS_EventID id);
|
||||
extern StatusType CoDelSem(OS_EventID id,U8 opt);
|
||||
extern StatusType CoPendSem(OS_EventID id,U32 timeout);
|
||||
extern OS_EventID CoCreateSem(U16 initCnt,U16 maxCnt,U8 sortType);
|
||||
|
||||
|
||||
/* Implement in file "mbox.c" */
|
||||
extern OS_EventID CoCreateMbox(U8 sortType);
|
||||
extern StatusType CoDelMbox(OS_EventID id,U8 opt);
|
||||
extern StatusType CoPostMail(OS_EventID id,void* pmail);
|
||||
extern StatusType isr_PostMail(OS_EventID id,void* pmail);
|
||||
extern void* CoAcceptMail(OS_EventID id,StatusType* perr);
|
||||
extern void* CoPendMail(OS_EventID id,U32 timeout,StatusType* perr);
|
||||
|
||||
|
||||
/* Implement in file "queue.c" */
|
||||
extern StatusType CoDelQueue(OS_EventID id,U8 opt);
|
||||
extern StatusType CoPostQueueMail(OS_EventID id,void* pmail);
|
||||
extern StatusType isr_PostQueueMail(OS_EventID id,void* pmail);
|
||||
extern void* CoAcceptQueueMail(OS_EventID id,StatusType* perr);
|
||||
extern OS_EventID CoCreateQueue(void **qStart, U16 size ,U8 sortType);
|
||||
extern void* CoPendQueueMail(OS_EventID id,U32 timeout,StatusType* perr);
|
||||
|
||||
|
||||
|
||||
/* Implement in file "flag.c" */
|
||||
extern StatusType CoSetFlag (OS_FlagID id);
|
||||
extern StatusType CoClearFlag (OS_FlagID id);
|
||||
extern StatusType isr_SetFlag (OS_FlagID id);
|
||||
extern StatusType CoDelFlag (OS_FlagID id,U8 opt);
|
||||
extern StatusType CoAcceptSingleFlag (OS_FlagID id);
|
||||
extern StatusType CoWaitForSingleFlag (OS_FlagID id,U32 timeout);
|
||||
extern OS_FlagID CoCreateFlag (BOOL bAutoReset,BOOL bInitialState);
|
||||
extern U32 CoAcceptMultipleFlags (U32 flags,U8 waitType,StatusType *perr);
|
||||
extern U32 CoWaitForMultipleFlags (U32 flags,U8 waitType,U32 timeout,StatusType *perr);
|
||||
|
||||
|
||||
/* Implement in file "utility.c" */
|
||||
extern StatusType CoTimeToTick(U8 hour,U8 minute,U8 sec,U16 millsec,U32* ticks);
|
||||
extern void CoTickToTime(U32 ticks,U8* hour,U8* minute,U8* sec,U16* millsec);
|
||||
|
||||
|
||||
/* Implement in file "hook.c" */
|
||||
extern void CoIdleTask(void* pdata);
|
||||
extern void CoStkOverflowHook(OS_TID taskID);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,280 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file OsConfig.h
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief This file use by user to configuration CooCox CoOS.
|
||||
* @note Ensure you have knew every item before modify this file.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _CONFIG_H
|
||||
#define _CONFIG_H
|
||||
|
||||
|
||||
/*!<
|
||||
Defines chip type,cortex-m3(1),cortex-m0(2)
|
||||
*/
|
||||
#define CFG_CHIP_TYPE (1)
|
||||
|
||||
/*!<
|
||||
Defines the lowest priority that be assigned.
|
||||
*/
|
||||
#define CFG_LOWEST_PRIO (64)
|
||||
|
||||
/*!<
|
||||
Max number of tasks that can be running.
|
||||
*/
|
||||
#define CFG_MAX_USER_TASKS (5)
|
||||
|
||||
/*!<
|
||||
Idle task stack size(word).
|
||||
*/
|
||||
#define CFG_IDLE_STACK_SIZE (25)
|
||||
|
||||
/*!<
|
||||
System frequency (Hz).
|
||||
*/
|
||||
#if defined(PCBTARANIS)
|
||||
#define CFG_CPU_FREQ (60000000)
|
||||
#else
|
||||
#define CFG_CPU_FREQ (36000000) // TODO check if really correct for sky9x?
|
||||
#endif
|
||||
|
||||
/*!<
|
||||
systick frequency (Hz).
|
||||
*/
|
||||
#define CFG_SYSTICK_FREQ (500)
|
||||
|
||||
/*!<
|
||||
max systerm api call num in ISR.
|
||||
*/
|
||||
#define CFG_MAX_SERVICE_REQUEST (5)
|
||||
|
||||
/*!<
|
||||
Enable(1) or disable(0) order list schedule.
|
||||
If disable(0),CoOS use Binary-Scheduling Algorithm.
|
||||
*/
|
||||
#if (CFG_MAX_USER_TASKS) <15
|
||||
#define CFG_ORDER_LIST_SCHEDULE_EN (1)
|
||||
#else
|
||||
#define CFG_ORDER_LIST_SCHEDULE_EN (0)
|
||||
#endif
|
||||
|
||||
|
||||
/*!<
|
||||
Enable(1) or disable(0) Round-Robin Task switching.
|
||||
*/
|
||||
#define CFG_ROBIN_EN (1)
|
||||
|
||||
/*!<
|
||||
Default slice of task.
|
||||
*/
|
||||
#if CFG_ROBIN_EN > 0
|
||||
#define CFG_TIME_SLICE (10)
|
||||
#endif
|
||||
|
||||
|
||||
/*----------------------- Schedule model Config -----------------------------*/
|
||||
/*!<
|
||||
Enable(1) or disable(0) all waiting function.
|
||||
Include sem,mailbox,queue,flag,mutex,delay modules.
|
||||
If CFG_TASK_WAITTING_EN=0,all these modules are disable.
|
||||
*/
|
||||
#define CFG_TASK_WAITTING_EN (1)
|
||||
|
||||
/*!<
|
||||
Dynamic task scheduling(1) or Static Task Scheduling(0) model.
|
||||
If in Static Task Scheduling model(0),cannot creat task and change task priority
|
||||
after coocox os start running. In Dynamic Task Scheduling model(1), all these can.
|
||||
When task terminated, if in Static Task Scheduling model(0),
|
||||
CoOS do not recovered task resources, and you can activate it again.
|
||||
But in Dynamic Task Scheduling model(1),task resources will be recovered.
|
||||
If in Static Task Scheduling model(0),mutex module can not be used, as this model don't
|
||||
support to change task priority while CoOS running.
|
||||
*/
|
||||
#define CFG_TASK_SCHEDULE_EN (1)
|
||||
|
||||
|
||||
/*---------------------- Task Management Config -----------------------------*/
|
||||
/*!<
|
||||
Enable(1) or disable(0) CoSetPriority() API.
|
||||
*/
|
||||
#if CFG_TASK_SCHEDULE_EN >0
|
||||
#define CFG_PRIORITY_SET_EN (1)
|
||||
#endif
|
||||
|
||||
/*!<
|
||||
Enable(1) or disable(0) CoAwakeTask() and CoSuspendTask() API.
|
||||
*/
|
||||
#define CFG_TASK_SUSPEND_EN (0)
|
||||
|
||||
|
||||
/*---------------------- Debug Management Config ----------------------------*/
|
||||
/*!<
|
||||
Enable(1) or disable(0) parameter checkout .
|
||||
*/
|
||||
#define CFG_PAR_CHECKOUT_EN (0)
|
||||
|
||||
/*!<
|
||||
Enable(1) or disable(0) stack overflow checkout .
|
||||
*/
|
||||
#define CFG_STK_CHECKOUT_EN (0)
|
||||
|
||||
|
||||
|
||||
/*---------------------- Memory Management Config ----------------------------*/
|
||||
/*!<
|
||||
Enable(1) or disable(0) memory management.
|
||||
*/
|
||||
#define CFG_MM_EN (0)
|
||||
|
||||
/*!<
|
||||
Max number of memory.(must be less than 32).
|
||||
*/
|
||||
#if CFG_MM_EN >0
|
||||
#define CFG_MAX_MM (2)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*-------------------- Kernel heap Management Config -------------------------*/
|
||||
/*!<
|
||||
Enable(1) or disable(0) kernel heap management.
|
||||
*/
|
||||
#define CFG_KHEAP_EN (0)
|
||||
|
||||
/*!<
|
||||
Kernel heap size(word).
|
||||
*/
|
||||
#if CFG_KHEAP_EN >0
|
||||
#define KHEAP_SIZE (50)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*---------------------- Time Management Config -----------------------------*/
|
||||
/*!<
|
||||
Enable(1) or disable(0) TimeDelay() API.
|
||||
*/
|
||||
#if CFG_TASK_WAITTING_EN >0
|
||||
#define CFG_TIME_DELAY_EN (0)
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------- Timer Management Config ----------------------------*/
|
||||
/*!<
|
||||
Enable(1) or disable(0) timer management.
|
||||
*/
|
||||
#define CFG_TMR_EN (1)
|
||||
|
||||
/*!<
|
||||
Specify max number timer.(must be less than 32)
|
||||
*/
|
||||
#if CFG_TMR_EN >0
|
||||
#define CFG_MAX_TMR (2)
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------- Event Management Config ----------------------------*/
|
||||
/*!<
|
||||
Enable(1) or disable(0) events management,
|
||||
events including semaphore,mailbox,queue.
|
||||
*/
|
||||
#if CFG_TASK_WAITTING_EN > 0
|
||||
#define CFG_EVENT_EN (1)
|
||||
#endif
|
||||
|
||||
#if CFG_EVENT_EN > 0
|
||||
/*!<
|
||||
Event sort type.(1)FIFO (2)PRI (3)FIFO+PRI
|
||||
*/
|
||||
#define CFG_EVENT_SORT (3)
|
||||
|
||||
/*!<
|
||||
Max number of event.(must be less than 255)
|
||||
Event = semaphore + mailbox + queue;
|
||||
*/
|
||||
#define CFG_MAX_EVENT (10)
|
||||
|
||||
/*!<
|
||||
Enable(1) or disable(0) semaphore management.
|
||||
*/
|
||||
#define CFG_SEM_EN (0)
|
||||
|
||||
/*!<
|
||||
Enable(1) or disable(0) mailbox management.
|
||||
*/
|
||||
#define CFG_MAILBOX_EN (0)
|
||||
|
||||
/*!<
|
||||
Enable(1) or disable(0) queue management.
|
||||
*/
|
||||
#define CFG_QUEUE_EN (0)
|
||||
|
||||
/*!<
|
||||
Max number of queue.(less than CFG_MAX_EVENT).
|
||||
*/
|
||||
#if CFG_QUEUE_EN >0
|
||||
#define CFG_MAX_QUEUE (2)
|
||||
#endif // CFG_QUEUE_EN
|
||||
|
||||
#endif // CFG_EVENT_EN
|
||||
|
||||
|
||||
|
||||
/*----------------------- Flag Management Config ----------------------------*/
|
||||
/*!<
|
||||
Enable(1) or disable(0) flag management.
|
||||
Max number of flag is 32.
|
||||
*/
|
||||
#if CFG_TASK_WAITTING_EN > 0
|
||||
#define CFG_FLAG_EN (1)
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------- Mutex Management Config ----------------------------*/
|
||||
/*!<
|
||||
Enable(1) or disable(0) mutex management.
|
||||
*/
|
||||
#if CFG_TASK_WAITTING_EN > 0
|
||||
#if CFG_TASK_SCHEDULE_EN > 0
|
||||
#define CFG_MUTEX_EN (1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*!<
|
||||
Max number of mutex.(must be less than 255).
|
||||
*/
|
||||
#if CFG_MUTEX_EN >0
|
||||
#define CFG_MAX_MUTEX (10)
|
||||
#endif
|
||||
|
||||
/*---------------------- Utility Management Config --------------------------*/
|
||||
/*!<
|
||||
Enable(1) or disable(0) utility management.
|
||||
*/
|
||||
#define CFG_UTILITY_EN (0)
|
||||
|
||||
#if CFG_UTILITY_EN >0
|
||||
|
||||
/*!<
|
||||
Enable(1) or disable(0) TickToTime() utility
|
||||
*/
|
||||
#define CFG_TICK_TO_TIME_EN (1)
|
||||
/*!<
|
||||
Enable(1) or disable(0) TimeToTick() utility
|
||||
*/
|
||||
#define CFG_TIME_TO_TICK_EN (1)
|
||||
#endif
|
||||
|
||||
|
||||
#endif // _CONFIG_H
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file OsCore.h
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Header file related to kernel
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _CORE_H
|
||||
#define _CORE_H
|
||||
|
||||
#include <CoOS.h>
|
||||
|
||||
|
||||
#define OsSchedLock() OSSchedLock++; /*!< Lock schedule */
|
||||
extern void OsSchedUnlock(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file OsError.h
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief rror dispose header file
|
||||
* @details This file use to dispose error which from error configure for OS.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _ERROR_H
|
||||
#define _ERROR_H
|
||||
|
||||
#if (CFG_SYSTICK_FREQ > 1000) ||(CFG_SYSTICK_FREQ < 1)
|
||||
#error " OsConfig.h System Tick time must between 1ms and 1s!"
|
||||
#endif
|
||||
|
||||
#if CFG_MAX_USER_TASKS > 253
|
||||
#error " OsConfig.h, CFG_MAX_USER_TASKS must be <= 253! "
|
||||
#endif
|
||||
|
||||
#if CFG_LOWEST_PRIO > 254
|
||||
#error " OsConfig.h, CFG_LOWEST_PRIO must be <= 254! "
|
||||
#endif
|
||||
|
||||
#if CFG_IDLE_STACK_SIZE <25
|
||||
#error " OsConfig.h, CFG_IDLE_STACK_SIZE must be >= 25! "
|
||||
#endif
|
||||
|
||||
|
||||
#if CFG_ROBIN_EN > 0
|
||||
#if CFG_TIME_SLICE > 4095
|
||||
#error " OsConfig.h, CFG_TIME_SLICE must be <= 4095! "
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CFG_TMR_EN > 0
|
||||
#if CFG_MAX_TMR > 32
|
||||
#error " OsConfig.h, CFG_MAX_TMR must be <= 32! "
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if CFG_MM_EN > 0
|
||||
#if CFG_MAX_MM > 32
|
||||
#error " config.h, CFG_MAX_MM must be <= 32! "
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if CFG_KHEAP_EN > 0
|
||||
#if KHEAP_SIZE < 0x20
|
||||
#error " config.h, CFG_MAX_MM must be >= 0x20! "
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CFG_MUTEX_EN > 0
|
||||
#if CFG_MAX_MUTEX > 254
|
||||
#error " config.h, CFG_MAX_MUTEX must be <= 254! "
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if CFG_EVENT_EN > 0
|
||||
#if (CFG_MAX_EVENT > 254 || CFG_MAX_EVENT <= 0)
|
||||
#error " config.h, CFG_MAX_EVENT must be <= 254 && > 0! "
|
||||
#endif
|
||||
|
||||
|
||||
#if CFG_QUEUE_EN > 0
|
||||
#if CFG_MAX_QUEUE > CFG_MAX_EVENT
|
||||
#error " config.h, CFG_MAX_QUEUE must be <= CFG_MAX_EVENT! "
|
||||
#endif
|
||||
#endif
|
||||
#endif /* CFG_EVENT_EN */
|
||||
|
||||
#endif /* _ERROR_H */
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file OsEvent.h
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Event management header file
|
||||
* @details This file including some defines and declares related to event
|
||||
* (semaphore,mailbox,queque) management.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _EVENT_H
|
||||
#define _EVENT_H
|
||||
|
||||
#define EVENT_TYPE_SEM (U8)0x01 /*!< Event type:Semaphore. */
|
||||
#define EVENT_TYPE_MBOX (U8)0x02 /*!< Event type:Mailbox. */
|
||||
#define EVENT_TYPE_QUEUE (U8)0x03 /*!< Event type:Queue. */
|
||||
#define EVENT_TYPE_INVALID (U8)0x04 /*!< Invalid event type. */
|
||||
|
||||
|
||||
/**
|
||||
* @struct EventCtrBlk event.h
|
||||
* @brief Event control block
|
||||
* @details This struct is use to manage event,
|
||||
* e.g. semaphore,mailbox,queue.
|
||||
*/
|
||||
typedef struct EventCtrBlk
|
||||
{
|
||||
void* eventPtr; /*!< Point to mailbox or queue struct */
|
||||
U8 id; /*!< ECB id */
|
||||
U8 eventType:4; /*!< Type of event */
|
||||
U8 eventSortType:4; /*!< 0:FIFO 1: Preemptive by prio */
|
||||
U16 eventCounter; /*!< Counter of semaphore. */
|
||||
U16 initialEventCounter; /*!< Initial counter of semaphore. */
|
||||
P_OSTCB eventTCBList; /*!< Task waitting list. */
|
||||
}ECB,*P_ECB;
|
||||
|
||||
/*---------------------------- Variable declare ------------------------------*/
|
||||
extern ECB EventTbl[CFG_MAX_EVENT]; /*!< Table use to save TCB. */
|
||||
|
||||
/*---------------------------- Function declare ------------------------------*/
|
||||
/*!< Create a event */
|
||||
extern P_ECB CreatEvent(U8 eventType,U8 eventSortType,void* eventPtr);
|
||||
|
||||
/*!< Remove a task from wait list */
|
||||
extern void EventTaskToWait(P_ECB pecb,P_OSTCB ptcb);
|
||||
extern StatusType DeleteEvent(P_ECB pecb,U8 opt); /*!< Delete a event. */
|
||||
extern void EventTaskToRdy(P_ECB pecb); /*!< Insert a task to ready list*/
|
||||
extern void CreateEventList(void); /*!< Create a event list. */
|
||||
extern void RemoveEventWaittingList(P_OSTCB ptcb);
|
||||
#endif
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file OsFlag.h
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Evnet flag management header file
|
||||
* @details This file including some defines and declares about flag management.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _FLAG_H
|
||||
#define _FLAG_H
|
||||
|
||||
/**
|
||||
* @struct FlagNode flag.h
|
||||
* @brief Flag node struct
|
||||
* @details
|
||||
*/
|
||||
typedef struct FlagNode
|
||||
{
|
||||
struct FlagNode* nextNode; /*!< A pointer to next flag node */
|
||||
struct FlagNode* prevNode; /*!< A pointer to prev flag node */
|
||||
U32 waitFlags; /*!< Flag value */
|
||||
P_OSTCB waitTask; /*!< A pointer to task waitting flag */
|
||||
U8 waitType; /*!< Wait type */
|
||||
}FLAG_NODE,*P_FLAG_NODE;
|
||||
|
||||
|
||||
/**
|
||||
* @struct Flag flag.h
|
||||
* @brief Flag control block
|
||||
* @details This struct use to mange event flag.
|
||||
*/
|
||||
typedef struct Flag
|
||||
{
|
||||
U32 flagRdy; /*!< Ready flag */
|
||||
U32 resetOpt; /*!< Reset option */
|
||||
U32 flagActive; /*!< Active flag */
|
||||
P_FLAG_NODE headNode; /*!< Head node */
|
||||
P_FLAG_NODE tailNode; /*!< Tail node */
|
||||
}FCB,*P_FCB;
|
||||
|
||||
|
||||
/*---------------------------- Variable declare ------------------------------*/
|
||||
extern FCB FlagCrl;
|
||||
|
||||
/*---------------------------- Function declare ------------------------------*/
|
||||
extern void RemoveLinkNode(P_FLAG_NODE pnode);
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file OsKernelHeap.h
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Header file related to memory management
|
||||
* @details This file including some defines and function declare related to
|
||||
* kernel heap management.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _KERNELHEAP_H
|
||||
#define _KERNELHEAP_H
|
||||
|
||||
|
||||
typedef struct KennelHeap
|
||||
{
|
||||
U32 startAddr;
|
||||
U32 endAddr;
|
||||
}KHeap,*P_KHeap;
|
||||
|
||||
|
||||
typedef struct UsedMemBlk
|
||||
{
|
||||
void* nextMB;
|
||||
void* preMB;
|
||||
}UMB,*P_UMB;
|
||||
|
||||
|
||||
typedef struct FreeMemBlk
|
||||
{
|
||||
struct FreeMemBlk* nextFMB;
|
||||
struct UsedMemBlk* nextUMB;
|
||||
struct UsedMemBlk* preUMB;
|
||||
}FMB,*P_FMB;
|
||||
|
||||
/*---------------------------- Function Declare ------------------------------*/
|
||||
extern void CoCreateKheap(void);
|
||||
|
||||
#endif /* _KERNELHEAP_H */
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file OsMm.h
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Header file related to memory management
|
||||
* @details This file including some defines and function declare related to
|
||||
* memory management.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _MM_H
|
||||
#define _MM_H
|
||||
|
||||
|
||||
typedef struct Memory
|
||||
{
|
||||
U8* memAddr;
|
||||
U8* freeBlock;
|
||||
U32 blockSize;
|
||||
U32 blockNum;
|
||||
}MM,*P_MM;
|
||||
|
||||
|
||||
typedef struct MemoryBlock
|
||||
{
|
||||
struct MemoryBlock* nextBlock;
|
||||
}MemBlk,*P_MemBlk;
|
||||
|
||||
|
||||
extern U32 MemoryIDVessel;
|
||||
|
||||
#endif /* _MM_H */
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file OsMutex.h
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Mutex management header file
|
||||
* @details This file including some defines and declare related to mutex
|
||||
* management.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _MUTEX_H
|
||||
#define _MUTEX_H
|
||||
|
||||
#include <coocox.h>
|
||||
|
||||
#if CFG_MUTEX_EN > 0
|
||||
|
||||
/*---------------------------- Resource status -------------------------------*/
|
||||
#define MUTEX_FREE 0 /*!< Mutex is free */
|
||||
#define MUTEX_OCCUPY 1 /*!< Mutex is occupy */
|
||||
#define WAITING_MUTEX 0x80
|
||||
|
||||
/**
|
||||
* @struct Mutex mutex.h
|
||||
* @brief Mutex control block
|
||||
* @details This struct is use to mutex management.
|
||||
*/
|
||||
typedef struct Mutex
|
||||
{
|
||||
U8 originalPrio; /*!< Mutex priority. */
|
||||
U8 mutexFlag; /*!< Mutex flag. */
|
||||
OS_TID taskID; /*!< Task ID. */
|
||||
OS_TID hipriTaskID; /*!< Mutex ID. */
|
||||
P_OSTCB waittingList; /*!< waitting the Mutex. */
|
||||
}MUTEX,*P_MUTEX;
|
||||
|
||||
|
||||
/*---------------------------- Variable declare ------------------------------*/
|
||||
/*!< Table use to save mutex control block. */
|
||||
extern MUTEX MutexTbl[CFG_MAX_MUTEX];
|
||||
extern OS_MutexID MutexFreeID; /*!< A pointer to next vliad resource ID. */
|
||||
|
||||
|
||||
/*---------------------------- Function declare ------------------------------*/
|
||||
extern void RemoveMutexList(P_OSTCB ptcb);
|
||||
|
||||
#endif /* CFG_MUTEX_EN */
|
||||
|
||||
#endif /* _MUTEX_H */
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file OsQueue.h
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Queue management header file
|
||||
* @details This file including some defines and declares about queue management.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _QUEUE_H
|
||||
#define _QUEUE_H
|
||||
|
||||
|
||||
/**
|
||||
* @struct Queue queue.h
|
||||
* @brief Queue struct
|
||||
* @details This struct use to manage queue.
|
||||
*
|
||||
*/
|
||||
typedef struct Queue
|
||||
{
|
||||
void **qStart; /*!< */
|
||||
U8 id; /*!< */
|
||||
U16 head; /*!< The header of queue */
|
||||
U16 tail; /*!< The end of queue */
|
||||
U16 qMaxSize; /*!< The max size of queue */
|
||||
U16 qSize; /*!< Current size of queue */
|
||||
}QCB,*P_QCB;
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file OsServiceReq.h
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Header file related to service request
|
||||
* @details This file including some defines and function declare related to
|
||||
* service request.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _SERVICEREQ_H
|
||||
#define _SERVICEREQ_H
|
||||
|
||||
#if CFG_MAX_SERVICE_REQUEST > 0
|
||||
#define SEM_REQ (U8)0x1
|
||||
#define MBOX_REQ (U8)0x2
|
||||
#define FLAG_REQ (U8)0x3
|
||||
#define QUEUE_REQ (U8)0x4
|
||||
|
||||
|
||||
typedef struct ServiceReqCell
|
||||
{
|
||||
U8 type;
|
||||
U8 id;
|
||||
void* arg;
|
||||
}SQC,*P_SQC;
|
||||
|
||||
typedef struct ServiceReqQueue
|
||||
{
|
||||
U8 cnt;
|
||||
U8 head;
|
||||
SQC cell[CFG_MAX_SERVICE_REQUEST];
|
||||
}SRQ,*P_SRQ;
|
||||
|
||||
|
||||
extern SRQ ServiceReq;
|
||||
extern BOOL InsertInSRQ(U8 type,U8 id,void* arg);
|
||||
#endif
|
||||
|
||||
extern void RespondSRQ(void);
|
||||
extern BOOL TimeReq;
|
||||
extern BOOL TimerReq;
|
||||
extern BOOL IsrReq;
|
||||
#endif
|
||||
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file OsTask.h
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Header file related to task.
|
||||
* @details This file including some defines and function declare related to task.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _TASK_H
|
||||
#define _TASK_H
|
||||
|
||||
#define SYS_TASK_NUM (1) /*!< System task number. */
|
||||
|
||||
/*---------------------------- Task Status -----------------------------------*/
|
||||
#define TASK_READY 0 /*!< Ready status of task. */
|
||||
#define TASK_RUNNING 1 /*!< Running status of task. */
|
||||
#define TASK_WAITING 2 /*!< Waitting status of task. */
|
||||
#define TASK_DORMANT 3 /*!< Dormant status of task. */
|
||||
|
||||
|
||||
#define INVALID_ID (U8)0xff
|
||||
#define INVALID_VALUE (U32)0xffffffff
|
||||
#define MAGIC_WORD (U32)0x5a5aa5a5
|
||||
|
||||
|
||||
/**
|
||||
* @struct TCB task.h
|
||||
* @brief Task control blcok.
|
||||
* @details This struct use to manage task.
|
||||
*/
|
||||
typedef struct TCB
|
||||
{
|
||||
OS_STK *stkPtr; /*!< The current point of task. */
|
||||
U8 prio; /*!< Task priority. */
|
||||
U8 state; /*!< TaSk status. */
|
||||
OS_TID taskID; /*!< Task ID. */
|
||||
|
||||
#if CFG_MUTEX_EN > 0
|
||||
OS_MutexID mutexID; /*!< Mutex ID. */
|
||||
#endif
|
||||
|
||||
#if CFG_EVENT_EN > 0
|
||||
OS_EventID eventID; /*!< Event ID. */
|
||||
#endif
|
||||
|
||||
#if CFG_ROBIN_EN >0
|
||||
U16 timeSlice; /*!< Task time slice */
|
||||
#endif
|
||||
|
||||
#if CFG_STK_CHECKOUT_EN >0
|
||||
OS_STK *stack; /*!< The top point of task. */
|
||||
#endif
|
||||
|
||||
#if CFG_EVENT_EN > 0
|
||||
void* pmail; /*!< Mail to task. */
|
||||
struct TCB *waitNext; /*!< Point to next TCB in the Event waitting list.*/
|
||||
struct TCB *waitPrev; /*!< Point to prev TCB in the Event waitting list.*/
|
||||
#endif
|
||||
|
||||
#if CFG_TASK_SCHEDULE_EN == 0
|
||||
FUNCPtr taskFuc;
|
||||
OS_STK *taskStk;
|
||||
#endif
|
||||
|
||||
|
||||
#if CFG_FLAG_EN > 0
|
||||
void* pnode; /*!< Pointer to node of event flag. */
|
||||
#endif
|
||||
|
||||
#if CFG_TASK_WAITTING_EN >0
|
||||
U32 delayTick; /*!< The number of ticks which delay. */
|
||||
#endif
|
||||
struct TCB *TCBnext; /*!< The pointer to next TCB. */
|
||||
struct TCB *TCBprev; /*!< The pointer to prev TCB. */
|
||||
|
||||
}OSTCB,*P_OSTCB;
|
||||
|
||||
|
||||
/*---------------------------- Variable declare ------------------------------*/
|
||||
// save tcb ptr that created
|
||||
extern P_OSTCB FreeTCB; /*!< A pointer to free TCB. */
|
||||
extern OSTCB TCBTbl[CFG_MAX_USER_TASKS+SYS_TASK_NUM];
|
||||
extern P_OSTCB TCBRdy; /*!< A pointer to TCB that is ready status */
|
||||
extern P_OSTCB TCBNext; /*!< A pointer to TCB next be scheduled. */
|
||||
extern P_OSTCB TCBRunning; /*!< A pointer to TCB that is running. */
|
||||
|
||||
extern U64 OSCheckTime;
|
||||
extern volatile U8 OSIntNesting; /*!< Use to indicate interrupt nesting level.*/
|
||||
extern volatile U8 OSSchedLock; /*!< Schedule is lock(LOCK) or unlock(UN_LOCK).*/
|
||||
extern volatile BOOL TaskSchedReq;
|
||||
extern OS_STK idle_stk[CFG_IDLE_STACK_SIZE];
|
||||
|
||||
|
||||
void Schedule(void); /*!< Schedule function */
|
||||
void IdleTask(void* pdata); /*!< IDLE task code */
|
||||
void InsertToTCBRdyList (P_OSTCB tcbInser);
|
||||
void RemoveFromTCBRdyList(P_OSTCB ptcb);
|
||||
void CreateTCBList(void);
|
||||
#if CFG_ORDER_LIST_SCHEDULE_EN ==0
|
||||
void ActiveTaskPri(U8 pri);
|
||||
void DeleteTaskPri(U8 pri);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file OsTime.c
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Header file related to time management
|
||||
* @details Thie file including some data declare related to time managment.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _TIME_H
|
||||
#define _TIME_H
|
||||
|
||||
/*---------------------------- Variable declare ------------------------------*/
|
||||
extern P_OSTCB DlyList; /*!< A pointer to ther delay list. */
|
||||
|
||||
/*---------------------------- Function declare ------------------------------*/
|
||||
extern void TimeDispose(void); /*!< Time dispose function. */
|
||||
extern void isr_TimeDispose(void);
|
||||
extern void RemoveDelayList(P_OSTCB ptcb);
|
||||
extern void InsertDelayList(P_OSTCB ptcb,U32 ticks);
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file OsTimer.h
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Timer manage header file
|
||||
* @details This file including some declares and defines related to timer
|
||||
* management.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_H
|
||||
#define _TIMER_H
|
||||
|
||||
#define TMR_STATE_RUNNING 0 /*!< Timer State: Running */
|
||||
#define TMR_STATE_STOPPED 1 /*!< Timer State: Stopped */
|
||||
|
||||
/**
|
||||
* @struct tmrCtrl timer.h
|
||||
* @brief Timer control block
|
||||
* @details This struct is use to manage user timer.
|
||||
*
|
||||
*/
|
||||
typedef struct tmrCtrl /* Timer Control Block Define. */
|
||||
{
|
||||
OS_TCID tmrID; /*!< Timer ID. */
|
||||
U8 tmrType; /*!< Timer Type. */
|
||||
U8 tmrState; /*!< Timer State. */
|
||||
U32 tmrCnt; /*!< Timer Counter. */
|
||||
U32 tmrReload; /*!< Timer Reload Counter Value. */
|
||||
vFUNCPtr tmrCallBack; /*!< Call-back Function When Timer overrun. */
|
||||
struct tmrCtrl* tmrNext; /*!< Point to Next Timer Control Block. */
|
||||
struct tmrCtrl* tmrPrev; /*!< Point to Previous Timer Control Block*/
|
||||
|
||||
}TmrCtrl,*P_TmrCtrl;
|
||||
|
||||
/*---------------------------- Variable declare ------------------------------*/
|
||||
extern P_TmrCtrl TmrList; /*!< A pointer to the timer list. */
|
||||
extern U32 TmrIDVessel;
|
||||
/*---------------------------- Function declare ------------------------------*/
|
||||
extern void TmrDispose(void); /*!< Timer counter function. */
|
||||
extern void isr_TmrDispose(void);
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file coocox.h
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Gather for all header file of CooCox CoOS.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _COOCOX_H
|
||||
#define _COOCOX_H
|
||||
|
||||
#define OS_VERSION (U16)0x0113 /*!< OS version.(format: Vx.xx),
|
||||
e.g. value 0x0113 is version V1.13*/
|
||||
/*---------------------------- Include ---------------------------------------*/
|
||||
#include "CoOS.h"
|
||||
#include "OsArch.h"
|
||||
#include "OsCore.h"
|
||||
#include "OsTask.h"
|
||||
#include "OsServiceReq.h"
|
||||
#include "OsError.h"
|
||||
#include "OsTime.h"
|
||||
|
||||
|
||||
#if CFG_TMR_EN > 0
|
||||
#include "OsTimer.h"
|
||||
#endif
|
||||
|
||||
#if CFG_KHEAP_EN > 0
|
||||
#include "OsKernelHeap.h"
|
||||
#endif
|
||||
|
||||
#if CFG_MM_EN >0
|
||||
#include "OsMM.h"
|
||||
#endif
|
||||
|
||||
#if CFG_EVENT_EN > 0
|
||||
#include "OsEvent.h"
|
||||
#endif
|
||||
|
||||
#if CFG_MUTEX_EN > 0
|
||||
#include "OsMutex.h"
|
||||
#endif
|
||||
|
||||
#if CFG_QUEUE_EN > 0
|
||||
#include "OsQueue.h"
|
||||
#endif
|
||||
|
||||
#if CFG_FLAG_EN > 0
|
||||
#include "OsFlag.h"
|
||||
#endif
|
||||
|
||||
#endif /* _COOCOX_H */
|
||||
@@ -0,0 +1,238 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file core.c
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Core implementation code of CooCox CoOS kernel.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
/*---------------------------- Include ---------------------------------------*/
|
||||
#include <coocox.h>
|
||||
|
||||
/*---------------------------- Variable Define -------------------------------*/
|
||||
volatile U8 OSIntNesting = 0; /*!< Use to indicate interrupt nesting level*/
|
||||
volatile U8 OSSchedLock = 0; /*!< Task Switch lock. */
|
||||
volatile BOOL TaskSchedReq = Co_FALSE;
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Enter a ISR.
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to notify OS when enter to an ISR.
|
||||
*
|
||||
* @note When you call API in ISR,you must call CoEnterISR() before your
|
||||
* interrupt handler code,and call CoExitISR() after your handler
|
||||
* code and before exiting from ISR.
|
||||
*******************************************************************************
|
||||
*/
|
||||
void CoEnterISR(void)
|
||||
{
|
||||
Inc8(&OSIntNesting); /* OSIntNesting increment */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Exit a ISR.
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called when exit from a ISR.
|
||||
*
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
void CoExitISR(void)
|
||||
{
|
||||
Dec8(&OSIntNesting); /* OSIntNesting decrease */
|
||||
if( OSIntNesting == 0) /* Is OSIntNesting == 0? */
|
||||
{
|
||||
if(TaskSchedReq == Co_TRUE)
|
||||
{
|
||||
OSSchedLock++;
|
||||
Schedule(); /* Call task schedule */
|
||||
OSSchedLock--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Unlock schedule
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to unlock schedule(i.e.enable schedule again)
|
||||
*
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
void OsSchedUnlock(void)
|
||||
{
|
||||
if(OSSchedLock == 1) /* Is OSSchedLock == 0? */
|
||||
{
|
||||
#if CFG_TASK_WAITTING_EN > 0
|
||||
if(IsrReq == Co_TRUE)
|
||||
{
|
||||
RespondSRQ(); /* Respond service request */
|
||||
}
|
||||
#endif
|
||||
/* Judge task state change or higher PRI task coming in */
|
||||
if(TaskSchedReq == Co_TRUE)
|
||||
{
|
||||
Schedule(); /* Call task schedule */
|
||||
}
|
||||
OSSchedLock = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
OSSchedLock--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Lock schedule
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called in application code to lock schedule.
|
||||
*
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
void CoSchedLock(void)
|
||||
{
|
||||
OsSchedLock(); /* Lock schedule */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Unlock schedule
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called in APP to unlock schedule.
|
||||
*
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
void CoSchedUnlock(void)
|
||||
{
|
||||
OsSchedUnlock(); /* Unlock schedule */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Initialize OS
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to initialize OS.
|
||||
*
|
||||
* @note You must call this function first,before any other OS API function
|
||||
*
|
||||
* @code There is a example for useage of this function,as follows:
|
||||
* e.g.
|
||||
* ... // Your target initial code.
|
||||
*
|
||||
* OsInit(); // Initial OS.
|
||||
* CreateTask(...); // Create tasks.
|
||||
* ...
|
||||
* OsStart(); // Start multitask.
|
||||
* @endcode
|
||||
*******************************************************************************
|
||||
*/
|
||||
void CoInitOS(void)
|
||||
{
|
||||
InitSysTick(); /* Initialize system tick. */
|
||||
InitInt(); /* Initialize PendSV,SVC,SysTick interrupt */
|
||||
CreateTCBList(); /* Create TCB list. */
|
||||
#if CFG_EVENT_EN > 0
|
||||
CreateEventList(); /* Create event control list. */
|
||||
#endif
|
||||
#if CFG_KHEAP_EN > 0
|
||||
CoCreateKheap(); /* Create kernel heap within user define */
|
||||
#endif
|
||||
OsSchedLock(); /* Lock Schedule */
|
||||
/* Create first task -- IDLE task. */
|
||||
CoCreateTask( CoIdleTask,
|
||||
Co_NULL,
|
||||
CFG_LOWEST_PRIO,
|
||||
&idle_stk[CFG_IDLE_STACK_SIZE-1],
|
||||
CFG_IDLE_STACK_SIZE
|
||||
);
|
||||
/* Set PSP for CoIdleTask coming in */
|
||||
SetEnvironment(&idle_stk[CFG_IDLE_STACK_SIZE-1]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Start multitask
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to start multitask.After it is called,
|
||||
* OS start schedule task by priority or/and time slice.
|
||||
* @note This function must be called to start OS when you use CoOS,and must
|
||||
* call after CoOsInit().
|
||||
*******************************************************************************
|
||||
*/
|
||||
void CoStartOS(void)
|
||||
{
|
||||
TCBRunning = &TCBTbl[0]; /* Get running task */
|
||||
TCBNext = TCBRunning; /* Set next scheduled task as running task */
|
||||
TCBRunning->state = TASK_RUNNING; /* Set running task status to RUNNING */
|
||||
RemoveFromTCBRdyList(TCBRunning); /* Remove running task from READY list */
|
||||
OsSchedUnlock(); /* Enable Schedule,call task schedule */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Get OS version
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval The value is version of OS mutipled by 100.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is used to return the version number of CooCox OS.
|
||||
* the return value corresponds to CooCox's version number multiplied
|
||||
* by 100. In other words, version 1.02 would be returned as 102.
|
||||
*******************************************************************************
|
||||
*/
|
||||
OS_VER CoGetOSVersion(void)
|
||||
{
|
||||
return OS_VERSION; /* Get CooCox CoOS version */
|
||||
}
|
||||
|
||||
@@ -0,0 +1,410 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file event.c
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief event management implementation code of CooCox CoOS kernel.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------- Include ---------------------------------------*/
|
||||
#include <coocox.h>
|
||||
|
||||
|
||||
/*---------------------------- Variable Define -------------------------------*/
|
||||
#if CFG_EVENT_EN > 0
|
||||
|
||||
ECB EventTbl[CFG_MAX_EVENT]= {{0}};/*!< Table which save event control block.*/
|
||||
P_ECB FreeEventList = Co_NULL; /*!< Pointer to free event control block. */
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Create a empty list of event control block
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called by OSInit() API to create a ECB list,supply
|
||||
* a pointer to next event control block that not used.
|
||||
*******************************************************************************
|
||||
*/
|
||||
void CreateEventList(void)
|
||||
{
|
||||
U8 i;
|
||||
P_ECB pecb1;
|
||||
#if CFG_MAX_EVENT > 1
|
||||
P_ECB pecb2;
|
||||
#endif
|
||||
i=0;
|
||||
pecb1 = &EventTbl[0]; /* Get first item */
|
||||
#if CFG_MAX_EVENT == 1 /* Build event list for only one item */
|
||||
pecb1->eventPtr = Co_NULL;
|
||||
pecb1->id = i; /* Assign ID. */
|
||||
pecb1->eventType = EVENT_TYPE_INVALID; /* Sign that not to use. */
|
||||
#endif
|
||||
|
||||
#if CFG_MAX_EVENT > 1 /* Build event list for more than one item */
|
||||
pecb2 = &EventTbl[1];
|
||||
for(;i< (CFG_MAX_EVENT-1);i++ )
|
||||
{
|
||||
pecb1->eventPtr = (void*)pecb2; /* Set link for list */
|
||||
pecb1->id = i; /* Assign ID. */
|
||||
pecb1->eventType = EVENT_TYPE_INVALID;/* Sign that not to use. */
|
||||
pecb1++; /* Get next item */
|
||||
pecb2++;
|
||||
}
|
||||
pecb1->eventType = EVENT_TYPE_INVALID; /* Sign that not to use. */
|
||||
pecb1->eventPtr = Co_NULL; /* Set link for last item */
|
||||
pecb1->id = i;
|
||||
#endif
|
||||
|
||||
FreeEventList = &EventTbl[0]; /* Set free event item */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Release a ECB
|
||||
* @param[in] pecb A pointer to event control block which be released.
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to release a event control block when a
|
||||
* event be deleted.
|
||||
*******************************************************************************
|
||||
*/
|
||||
static void ReleaseECB(P_ECB pecb)
|
||||
{
|
||||
pecb->eventType = EVENT_TYPE_INVALID; /* Sign that not to use. */
|
||||
OsSchedLock(); /* Lock schedule */
|
||||
pecb->eventPtr = FreeEventList; /* Release ECB that event hold */
|
||||
FreeEventList = pecb; /* Reset free event item */
|
||||
OsSchedUnlock(); /* Unlock schedule */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Create a event
|
||||
* @param[in] eventType The type of event which being created.
|
||||
* @param[in] eventSortType Event sort type.
|
||||
* @param[in] eventCounter Event counter,ONLY for EVENT_TYPE_SEM.
|
||||
* @param[in] eventPtr Event struct pointer,ONLY for Queue.Co_NULL for other
|
||||
* event type.
|
||||
* @param[out] None
|
||||
* @retval Co_NULL Invalid pointer,create event fail.
|
||||
* @retval others Pointer to event control block which had assigned right now.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called by CreateSem(),...
|
||||
* to get a event control block and initial the event content.
|
||||
*
|
||||
* @note This is a internal function of CooCox CoOS,User can't call.
|
||||
*******************************************************************************
|
||||
*/
|
||||
P_ECB CreatEvent(U8 eventType,U8 eventSortType,void* eventPtr)
|
||||
{
|
||||
P_ECB pecb;
|
||||
|
||||
OsSchedLock(); /* Lock schedule */
|
||||
if(FreeEventList == Co_NULL) /* Is there no free evnet item */
|
||||
{
|
||||
OsSchedUnlock(); /* Yes,unlock schedule */
|
||||
return Co_NULL; /* Return error */
|
||||
}
|
||||
pecb = FreeEventList;/* Assign the free event item to this event */
|
||||
FreeEventList = FreeEventList->eventPtr; /* Reset free event item */
|
||||
OsSchedUnlock(); /* Unlock schedul */
|
||||
|
||||
pecb->eventType = eventType; /* Initialize event item as user set */
|
||||
pecb->eventSortType = eventSortType;
|
||||
pecb->eventPtr = eventPtr;
|
||||
pecb->eventTCBList = Co_NULL;
|
||||
return pecb; /* Return event item pointer */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Delete a event
|
||||
* @param[in] pecb Pointer to event control block which will be deleted.
|
||||
* @param[in] opt Delete option.
|
||||
* @arg == OPT_DEL_ANYWAY Delete event always
|
||||
* @arg == OPT_DEL_NO_PEND Delete event only when no task pending on.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_PARAMETER Parameter passed is invalid,deleted fail.
|
||||
* @retval E_TASK_WAITTING These are one more tasks waitting event.
|
||||
* @retval E_OK Delete event control block successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to delete a event from the event wait list
|
||||
* use specify option.
|
||||
*
|
||||
* @note This is a internal function of Coocox CoOS,user can't call.
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType DeleteEvent(P_ECB pecb,U8 opt)
|
||||
{
|
||||
P_OSTCB ptcb;
|
||||
if(opt == OPT_DEL_NO_PEND) /* Do delete event when no task pend? */
|
||||
{
|
||||
if(pecb->eventTCBList != Co_NULL) /* Yes,is there task pend this event? */
|
||||
{
|
||||
return E_TASK_WAITING; /* Yes,error return */
|
||||
}
|
||||
else
|
||||
{
|
||||
ReleaseECB(pecb); /* No,release resource that event hold*/
|
||||
}
|
||||
}
|
||||
else if(opt == OPT_DEL_ANYWAY) /* Do delete event anyway? */
|
||||
{
|
||||
OsSchedLock(); /* Lock schedule */
|
||||
while(pecb->eventTCBList != Co_NULL) /* Is there task pend this event? */
|
||||
{ /* Yes,remove it */
|
||||
ptcb = pecb->eventTCBList;/* Get first task in event waiting list */
|
||||
if(ptcb->delayTick != INVALID_VALUE) /* Is task in delay list? */
|
||||
{
|
||||
RemoveDelayList(ptcb); /* Yes,remove task from delay list */
|
||||
}
|
||||
|
||||
/* Set next item as event waiting list head */
|
||||
pecb->eventTCBList = ptcb->waitNext;
|
||||
ptcb->waitNext = Co_NULL; /* Clear link for event waiting list */
|
||||
ptcb->eventID = INVALID_ID; /* Sign that not to use. */
|
||||
|
||||
InsertToTCBRdyList(ptcb); /* Insert task into ready list */
|
||||
}
|
||||
OsSchedUnlock(); /* Unlock schedule */
|
||||
ReleaseECB(pecb); /* Release resource that event hold */
|
||||
}
|
||||
return E_OK; /* Return OK */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Insert a task to event wait list
|
||||
* @param[in] pecb Pointer to event control block corresponding to the event.
|
||||
* @param[in] ptcb Pointer to task that will be insert to event wait list.
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to insert a task by fllowing manner:
|
||||
* opt == EVENT_SORT_TYPE_FIFO By FIFO.
|
||||
* opt == EVENT_SORT_TYPE_PRIO By priority order,hghest priority
|
||||
* as head,lowest priority as end.
|
||||
* (Highest-->...-->Lowest-->Co_NULL)
|
||||
*******************************************************************************
|
||||
*/
|
||||
void EventTaskToWait(P_ECB pecb,P_OSTCB ptcb)
|
||||
{
|
||||
P_OSTCB ptcb1;
|
||||
#if (CFG_EVENT_SORT == 2) || (CFG_EVENT_SORT == 3)
|
||||
P_OSTCB ptcb2;
|
||||
#endif
|
||||
|
||||
OsSchedLock(); /* Lock schedule */
|
||||
ptcb1 = pecb->eventTCBList; /* Get first task in event waiting list */
|
||||
ptcb->eventID = pecb->id; /* Set event ID for task */
|
||||
|
||||
#if CFG_EVENT_SORT == 3 /* Does event waiting list sort as FIFO? */
|
||||
|
||||
if(pecb->eventSortType == EVENT_SORT_TYPE_FIFO)
|
||||
#endif
|
||||
|
||||
#if (CFG_EVENT_SORT == 1) || (CFG_EVENT_SORT == 3)
|
||||
{
|
||||
if(ptcb1 == Co_NULL) /* Is no item in event waiting list?*/
|
||||
{
|
||||
pecb->eventTCBList = ptcb; /* Yes,set task as first item */
|
||||
}
|
||||
else
|
||||
{
|
||||
while(ptcb1->waitNext != Co_NULL)/* No,insert task in last */
|
||||
{
|
||||
ptcb1 = ptcb1->waitNext;
|
||||
}
|
||||
ptcb1->waitNext = ptcb; /* Set link for list */
|
||||
ptcb->waitPrev = ptcb1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CFG_EVENT_SORT ==3 /* Does event waiting list sort as preemptive priority?*/
|
||||
else if(pecb->eventSortType == EVENT_SORT_TYPE_PRIO)
|
||||
#endif
|
||||
#if (CFG_EVENT_SORT == 2) || (CFG_EVENT_SORT == 3)
|
||||
{
|
||||
if(ptcb1 == Co_NULL) /* Is no item in event waiting list? */
|
||||
{
|
||||
pecb->eventTCBList = ptcb; /* Yes,set task as first item */
|
||||
}
|
||||
/* Is PRI of task higher than list first item? */
|
||||
else if(ptcb1->prio > ptcb->prio)
|
||||
{
|
||||
pecb->eventTCBList = ptcb; /* Reset task as first item */
|
||||
ptcb->waitNext = ptcb1; /* Set link for list */
|
||||
ptcb1->waitPrev = ptcb;
|
||||
}
|
||||
else /* No,find correct place to insert */
|
||||
{
|
||||
ptcb2 = ptcb1->waitNext;
|
||||
while(ptcb2 != Co_NULL) /* Is last item? */
|
||||
{
|
||||
if(ptcb2->prio > ptcb->prio) /* No,is correct place? */
|
||||
{
|
||||
break; /* Yes,break Circulation */
|
||||
}
|
||||
ptcb1 = ptcb2; /* Save current item */
|
||||
ptcb2 = ptcb2->waitNext; /* Get next item */
|
||||
}
|
||||
ptcb1->waitNext = ptcb; /* Set link for list */
|
||||
ptcb->waitPrev = ptcb1;
|
||||
ptcb->waitNext = ptcb2;
|
||||
if(ptcb2 != Co_NULL)
|
||||
{
|
||||
ptcb2->waitPrev = ptcb;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ptcb->state = TASK_WAITING; /* Set task status to TASK_WAITING state */
|
||||
TaskSchedReq = Co_TRUE;
|
||||
OsSchedUnlock(); /* Unlock schedule,and call task schedule */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Move a task from event WAITING list to the DELAY list
|
||||
* @param[in] pecb Pointer to event control block corresponding to the event.
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to remove a task from event wait list,and
|
||||
* then insert it into the READY list.
|
||||
*******************************************************************************
|
||||
*/
|
||||
void EventTaskToRdy(P_ECB pecb)
|
||||
{
|
||||
P_OSTCB ptcb;
|
||||
#if CFG_QUEUE_EN >0
|
||||
P_QCB pqcb;
|
||||
#endif
|
||||
ptcb = pecb->eventTCBList;
|
||||
if(ptcb == Co_NULL)
|
||||
return;
|
||||
|
||||
pecb->eventTCBList = ptcb->waitNext;/* Get first task in event waiting list*/
|
||||
if(pecb->eventTCBList != Co_NULL) /* Is no item in event waiting list? */
|
||||
{
|
||||
pecb->eventTCBList->waitPrev = Co_NULL; /* No,clear link for first item */
|
||||
}
|
||||
|
||||
ptcb->waitNext = Co_NULL; /* Clear event waiting link for task*/
|
||||
ptcb->eventID = INVALID_ID; /* Sign that not to use. */
|
||||
|
||||
if(ptcb->delayTick != INVALID_VALUE) /* Is task in delay list? */
|
||||
{
|
||||
RemoveDelayList(ptcb); /* Yes,remove task from DELAY list */
|
||||
}
|
||||
if(pecb->eventType == EVENT_TYPE_MBOX)/* Is it a mailbox event? */
|
||||
{
|
||||
ptcb->pmail = pecb->eventPtr; /* Yes,send mail to task */
|
||||
pecb->eventPtr = Co_NULL; /* Clear event sign */
|
||||
pecb->eventCounter--;
|
||||
}
|
||||
#if CFG_QUEUE_EN >0
|
||||
else if(pecb->eventType == EVENT_TYPE_QUEUE) /* Is it a queue event? */
|
||||
{
|
||||
pqcb = (P_QCB)pecb->eventPtr; /* Yes,get queue pointer */
|
||||
ptcb->pmail = *(pqcb->qStart + pqcb->head); /* Send mail to task */
|
||||
pqcb->head++; /* Clear event sign */
|
||||
pqcb->qSize--;
|
||||
if(pqcb->head == pqcb->qMaxSize)
|
||||
{
|
||||
pqcb->head = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CFG_MAILBOX_EN >0
|
||||
else if(pecb->eventType == EVENT_TYPE_SEM)/* Is it a semaphore event? */
|
||||
{
|
||||
pecb->eventCounter--; /* Yes,clear event sign */
|
||||
ptcb->pmail = (void*)0xffffffff; /* Indicate task woke by event */
|
||||
}
|
||||
#endif
|
||||
if(ptcb == TCBRunning)
|
||||
{
|
||||
ptcb->state = TASK_RUNNING;
|
||||
}
|
||||
else
|
||||
{
|
||||
InsertToTCBRdyList(ptcb); /* Insert task into ready list */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Move a task from event wait list to the ready list
|
||||
* @param[in] pecb Pointer to event control block corresponding to the event.
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to remove a task from event wait list,and
|
||||
* then insert it to the ready list.
|
||||
*******************************************************************************
|
||||
*/
|
||||
void RemoveEventWaittingList(P_OSTCB ptcb)
|
||||
{
|
||||
P_ECB pecb;
|
||||
pecb = &EventTbl[ptcb->eventID]; /* Get event control block */
|
||||
|
||||
/* Is there only one item in event waiting list? */
|
||||
if((ptcb->waitNext == Co_NULL) && (ptcb->waitPrev == Co_NULL))
|
||||
{
|
||||
pecb->eventTCBList = Co_NULL; /* Yes,set event waiting list as Co_NULL */
|
||||
}
|
||||
else if(ptcb->waitPrev == Co_NULL)/* Is the first item in event waiting list?*/
|
||||
{
|
||||
/* Yes,remove task from list,and reset event waiting list */
|
||||
ptcb->waitNext->waitPrev = Co_NULL;
|
||||
pecb->eventTCBList = ptcb->waitNext;
|
||||
ptcb->waitNext = Co_NULL;
|
||||
}
|
||||
else if(ptcb->waitNext == Co_NULL)/* Is the last item in event waiting list? */
|
||||
{
|
||||
ptcb->waitPrev->waitNext = Co_NULL; /* Yes,remove task form list */
|
||||
ptcb->waitPrev = Co_NULL;
|
||||
}
|
||||
else /* No, remove task from list */
|
||||
{
|
||||
ptcb->waitPrev->waitNext = ptcb->waitNext;
|
||||
ptcb->waitNext->waitPrev = ptcb->waitPrev;
|
||||
ptcb->waitPrev = Co_NULL;
|
||||
ptcb->waitNext = Co_NULL;
|
||||
}
|
||||
ptcb->eventID = INVALID_ID; /* Sign that not to use. */
|
||||
}
|
||||
|
||||
#endif //CFG_EVENT_EN
|
||||
|
||||
@@ -0,0 +1,712 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file flag.c
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Flag management implementation code of coocox CoOS kernel.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*---------------------------- Include ---------------------------------------*/
|
||||
#include <coocox.h>
|
||||
|
||||
#if CFG_FLAG_EN > 0
|
||||
/*---------------------------- Variable Define -------------------------------*/
|
||||
#define FLAG_MAX_NUM 32 /*!< Define max flag number. */
|
||||
FCB FlagCrl = {0}; /*!< Flags list struct */
|
||||
|
||||
|
||||
/*---------------------------- Function Declare ------------------------------*/
|
||||
static void FlagBlock(P_FLAG_NODE pnode,U32 flags,U8 waitType);
|
||||
static P_FLAG_NODE RemoveFromLink(P_FLAG_NODE pnode);
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Create a flag
|
||||
* @param[in] bAutoReset Reset mode,Co_TRUE(Auto Reset) FLASE(Manual Reset).
|
||||
* @param[in] bInitialState Initial state.
|
||||
* @param[out] None
|
||||
* @retval E_CREATE_FAIL Create flag fail.
|
||||
* @retval others Create flag successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function use to create a event flag.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
OS_FlagID CoCreateFlag(BOOL bAutoReset,BOOL bInitialState)
|
||||
{
|
||||
U8 i;
|
||||
OsSchedLock();
|
||||
|
||||
for(i=0;i<FLAG_MAX_NUM;i++)
|
||||
{
|
||||
/* Assign a free flag control block */
|
||||
if((FlagCrl.flagActive&(1<<i)) == 0 )
|
||||
{
|
||||
FlagCrl.flagActive |= (1<<i); /* Initialize active flag */
|
||||
FlagCrl.flagRdy |= (bInitialState<<i);/* Initialize ready flag */
|
||||
FlagCrl.resetOpt |= (bAutoReset<<i);/* Initialize reset option */
|
||||
OsSchedUnlock();
|
||||
return i ; /* Return Flag ID */
|
||||
}
|
||||
}
|
||||
OsSchedUnlock();
|
||||
|
||||
return E_CREATE_FAIL; /* There is no free flag control block*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Delete a flag
|
||||
* @param[in] id Flag ID.
|
||||
* @param[in] opt Delete option.
|
||||
* @param[out] None
|
||||
* @retval E_CALL Error call in ISR.
|
||||
* @retval E_INVALID_ID Invalid event ID.
|
||||
* @retval E_TASK_WAITTING Tasks waitting for the event,delete fail.
|
||||
* @retval E_OK Event deleted successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to delete a event flag.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoDelFlag(OS_FlagID id,U8 opt)
|
||||
{
|
||||
P_FLAG_NODE pnode;
|
||||
P_FCB pfcb;
|
||||
pfcb = &FlagCrl;
|
||||
if(OSIntNesting > 0) /* If be called from ISR */
|
||||
{
|
||||
return E_CALL;
|
||||
}
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if((pfcb->flagActive&(1<<id)) == 0) /* Flag is valid or not */
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
OsSchedLock();
|
||||
pnode = pfcb->headNode;
|
||||
|
||||
while(pnode != Co_NULL) /* Ready all tasks waiting for flags */
|
||||
{
|
||||
if((pnode->waitFlags&(1<<id)) != 0) /* If no task is waiting on flags */
|
||||
{
|
||||
if(opt == OPT_DEL_NO_PEND) /* Delete flag if no task waiting */
|
||||
{
|
||||
OsSchedUnlock();
|
||||
return E_TASK_WAITING;
|
||||
}
|
||||
else if (opt == OPT_DEL_ANYWAY) /* Always delete the flag */
|
||||
{
|
||||
if(pnode->waitType == OPT_WAIT_ALL)
|
||||
{
|
||||
/* If the flag is only required by NODE */
|
||||
if( pnode->waitFlags == (1<<id) )
|
||||
{
|
||||
/* Remove the NODE from waiting list */
|
||||
pnode = RemoveFromLink(pnode);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
pnode->waitFlags &= ~(1<<id); /* Update waitflags */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pnode = RemoveFromLink(pnode);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
pnode = pnode->nextNode;
|
||||
}
|
||||
|
||||
/* Remove the flag from the flags list */
|
||||
pfcb->flagActive &= ~(1<<id);
|
||||
pfcb->flagRdy &= ~(1<<id);
|
||||
pfcb->resetOpt &= ~(1<<id);
|
||||
OsSchedUnlock();
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief AcceptSingleFlag
|
||||
* @param[in] id Flag ID.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID Invalid event ID.
|
||||
* @retval E_FLAG_NOT_READY Flag is not in ready state.
|
||||
* @retval E_OK The call was successful and your task owns the Flag.
|
||||
*
|
||||
* @par Description
|
||||
* @details This fucntion is called to accept single flag
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoAcceptSingleFlag(OS_FlagID id)
|
||||
{
|
||||
P_FCB pfcb;
|
||||
pfcb = &FlagCrl;
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(id >= FLAG_MAX_NUM)
|
||||
{
|
||||
return E_INVALID_ID; /* Invalid 'id',return error */
|
||||
}
|
||||
if((pfcb->flagActive&(1<<id)) == 0)
|
||||
{
|
||||
return E_INVALID_ID; /* Flag is deactive,return error */
|
||||
}
|
||||
#endif
|
||||
if((pfcb->flagRdy&(1<<id)) != 0) /* If the required flag is set */
|
||||
{
|
||||
OsSchedLock()
|
||||
pfcb->flagRdy &= ~((FlagCrl.resetOpt)&(1<<id)); /* Clear the flag */
|
||||
OsSchedUnlock();
|
||||
return E_OK;
|
||||
}
|
||||
else /* If the required flag is not set */
|
||||
{
|
||||
return E_FLAG_NOT_READY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief AcceptMultipleFlags
|
||||
* @param[in] flags Flags that waiting to active task.
|
||||
* @param[in] waitType Flags wait type.
|
||||
* @param[out] perr A pointer to error code.
|
||||
* @retval 0
|
||||
* @retval springFlag
|
||||
*
|
||||
* @par Description
|
||||
* @details This fucntion is called to accept multiple flags.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
U32 CoAcceptMultipleFlags(U32 flags,U8 waitType,StatusType *perr)
|
||||
{
|
||||
U32 springFlag;
|
||||
P_FCB pfcb;
|
||||
pfcb = &FlagCrl;
|
||||
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if((flags&pfcb->flagActive) != flags ) /* Judge flag is active or not? */
|
||||
{
|
||||
*perr = E_INVALID_PARAMETER; /* Invalid flags */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
springFlag = flags & pfcb->flagRdy;
|
||||
|
||||
OsSchedLock();
|
||||
/* If any required flags are set */
|
||||
if( (springFlag != 0) && (waitType == OPT_WAIT_ANY) )
|
||||
{
|
||||
|
||||
pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt); /* Clear the flags */
|
||||
OsSchedUnlock();
|
||||
*perr = E_OK;
|
||||
return springFlag;
|
||||
}
|
||||
|
||||
/* If all required flags are set */
|
||||
if((springFlag == flags) && (waitType == OPT_WAIT_ALL))
|
||||
{
|
||||
pfcb->flagRdy &= ~(springFlag&pfcb->resetOpt); /* Clear the flags */
|
||||
OsSchedUnlock();
|
||||
*perr = E_OK;
|
||||
return springFlag;
|
||||
}
|
||||
OsSchedUnlock();
|
||||
*perr = E_FLAG_NOT_READY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief WaitForSingleFlag
|
||||
* @param[in] id Flag ID.
|
||||
* @param[in] timeout The longest time for writting flag.
|
||||
* @param[out] None
|
||||
* @retval E_CALL Error call in ISR.
|
||||
* @retval E_INVALID_ID Invalid event ID.
|
||||
* @retval E_TIMEOUT Flag wasn't received within 'timeout' time.
|
||||
* @retval E_OK The call was successful and your task owns the Flag,
|
||||
* or the event you are waiting for occurred.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to wait for only one flag,
|
||||
* (1) if parameter "timeout" == 0,waiting until flag be set;
|
||||
* (2) when "timeout" != 0,if flag was set or wasn't set but timeout
|
||||
* occured,the task will exit the waiting list,convert to READY
|
||||
* or RUNNING state.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoWaitForSingleFlag(OS_FlagID id,U32 timeout)
|
||||
{
|
||||
FLAG_NODE flagNode;
|
||||
P_FCB pfcb;
|
||||
P_OSTCB curTCB;
|
||||
|
||||
if(OSIntNesting > 0) /* See if the caller is ISR */
|
||||
{
|
||||
return E_CALL;
|
||||
}
|
||||
if(OSSchedLock != 0) /* Schedule is lock? */
|
||||
{
|
||||
return E_OS_IN_LOCK; /* Yes,error return */
|
||||
}
|
||||
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(id >= FLAG_MAX_NUM) /* Judge id is valid or not? */
|
||||
{
|
||||
return E_INVALID_ID; /* Invalid 'id' */
|
||||
}
|
||||
if((FlagCrl.flagActive&(1<<id)) == 0 )/* Judge flag is active or not? */
|
||||
{
|
||||
return E_INVALID_ID; /* Flag is deactive ,return error */
|
||||
}
|
||||
#endif
|
||||
|
||||
OsSchedLock();
|
||||
pfcb = &FlagCrl;
|
||||
/* See if the required flag is set */
|
||||
if((pfcb->flagRdy&(1<<id)) != 0) /* If the required flag is set */
|
||||
{
|
||||
pfcb->flagRdy &= ~((pfcb->resetOpt&(1<<id))); /* Clear the flag */
|
||||
OsSchedUnlock();
|
||||
}
|
||||
else /* If the required flag is not set */
|
||||
{
|
||||
curTCB = TCBRunning;
|
||||
if(timeout == 0) /* If time-out is not configured */
|
||||
{
|
||||
/* Block task until the required flag is set */
|
||||
FlagBlock (&flagNode,(1<<id),OPT_WAIT_ONE);
|
||||
curTCB->state = TASK_WAITING;
|
||||
TaskSchedReq = Co_TRUE;
|
||||
OsSchedUnlock();
|
||||
|
||||
/* The required flag is set and the task is in running state */
|
||||
curTCB->pnode = Co_NULL;
|
||||
OsSchedLock();
|
||||
|
||||
/* Clear the required flag or not */
|
||||
pfcb->flagRdy &= ~((1<<id)&(pfcb->resetOpt));
|
||||
OsSchedUnlock();
|
||||
}
|
||||
else /* If time-out is configured */
|
||||
{
|
||||
/* Block task until the required flag is set or time-out occurs */
|
||||
FlagBlock(&flagNode,(1<<id),OPT_WAIT_ONE);
|
||||
InsertDelayList(curTCB,timeout);
|
||||
|
||||
OsSchedUnlock();
|
||||
if(curTCB->pnode == Co_NULL) /* If time-out occurred */
|
||||
{
|
||||
return E_TIMEOUT;
|
||||
}
|
||||
else /* If flag is set */
|
||||
{
|
||||
curTCB->pnode = Co_NULL;
|
||||
OsSchedLock();
|
||||
|
||||
/* Clear the required flag or not */
|
||||
pfcb->flagRdy &= ~((1<<id)&(pfcb->resetOpt));
|
||||
OsSchedUnlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief WaitForMultipleFlags
|
||||
* @param[in] flags Flags that waiting to active task.
|
||||
* @param[in] waitType Flags wait type.
|
||||
* @param[in] timeout The longest time for writting flag.
|
||||
* @param[out] perr A pointer to error code.
|
||||
* @retval 0
|
||||
* @retval springFlag
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to pend a task for waitting multiple flag.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
U32 CoWaitForMultipleFlags(U32 flags,U8 waitType,U32 timeout,StatusType *perr)
|
||||
{
|
||||
U32 springFlag;
|
||||
P_FCB pfcb;
|
||||
FLAG_NODE flagNode;
|
||||
P_OSTCB curTCB;
|
||||
|
||||
|
||||
if(OSIntNesting > 0) /* If the caller is ISR */
|
||||
{
|
||||
*perr = E_CALL;
|
||||
return 0;
|
||||
}
|
||||
if(OSSchedLock != 0) /* Schedule is lock? */
|
||||
{
|
||||
*perr = E_OS_IN_LOCK;
|
||||
return 0; /* Yes,error return */
|
||||
}
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if( (flags&FlagCrl.flagActive) != flags )
|
||||
{
|
||||
*perr = E_INVALID_PARAMETER; /* Invalid 'flags' */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
OsSchedLock();
|
||||
pfcb = &FlagCrl;
|
||||
springFlag = flags & pfcb->flagRdy;
|
||||
|
||||
/* If any required flags are set */
|
||||
if((springFlag != 0) && (waitType == OPT_WAIT_ANY))
|
||||
{
|
||||
pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt); /* Clear the flag */
|
||||
OsSchedUnlock();
|
||||
*perr = E_OK;
|
||||
return springFlag;
|
||||
}
|
||||
|
||||
/* If all required flags are set */
|
||||
if( (springFlag == flags) && (waitType == OPT_WAIT_ALL) )
|
||||
{
|
||||
pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt); /* Clear the flags */
|
||||
OsSchedUnlock();
|
||||
*perr = E_OK;
|
||||
return springFlag;
|
||||
}
|
||||
|
||||
curTCB = TCBRunning;
|
||||
if(timeout == 0) /* If time-out is not configured */
|
||||
{
|
||||
/* Block task until the required flag are set */
|
||||
FlagBlock(&flagNode,flags,waitType);
|
||||
curTCB->state = TASK_WAITING;
|
||||
TaskSchedReq = Co_TRUE;
|
||||
OsSchedUnlock();
|
||||
|
||||
curTCB->pnode = Co_NULL;
|
||||
OsSchedLock();
|
||||
springFlag = flags & pfcb->flagRdy;
|
||||
pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt);/* Clear the flags */
|
||||
OsSchedUnlock();
|
||||
*perr = E_OK;
|
||||
return springFlag;
|
||||
}
|
||||
else /* If time-out is configured */
|
||||
{
|
||||
/* Block task until the required flag are set or time-out occurred */
|
||||
FlagBlock(&flagNode,flags,waitType);
|
||||
InsertDelayList(curTCB,timeout);
|
||||
|
||||
OsSchedUnlock();
|
||||
if(curTCB->pnode == Co_NULL) /* If time-out occurred */
|
||||
{
|
||||
*perr = E_TIMEOUT;
|
||||
return 0;
|
||||
}
|
||||
else /* If the required flags are set */
|
||||
{
|
||||
curTCB->pnode = Co_NULL;
|
||||
OsSchedLock();
|
||||
springFlag = flags & FlagCrl.flagRdy;
|
||||
|
||||
/* Clear the required ready flags or not */
|
||||
pfcb->flagRdy &= ~(springFlag & pfcb->resetOpt);
|
||||
OsSchedUnlock();
|
||||
*perr = E_OK;
|
||||
return springFlag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Clear a Flag
|
||||
* @param[in] id Flag ID.
|
||||
* @param[out] None
|
||||
* @retval E_OK Event deleted successful.
|
||||
* @retval E_INVALID_ID Invalid event ID.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to clear a flag.
|
||||
*
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoClearFlag(OS_FlagID id)
|
||||
{
|
||||
P_FCB pfcb;
|
||||
pfcb = &FlagCrl;
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(id >= FLAG_MAX_NUM)
|
||||
{
|
||||
return E_INVALID_ID; /* Invalid id */
|
||||
}
|
||||
if((pfcb->flagActive&(1<<id)) == 0)
|
||||
{
|
||||
return E_INVALID_ID; /* Invalid flag */
|
||||
}
|
||||
#endif
|
||||
|
||||
pfcb->flagRdy &= ~(1<<id); /* Clear the flag */
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Set a flag
|
||||
* @param[in] id Flag ID.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID Invalid event ID.
|
||||
* @retval E_OK Event deleted successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to set a flag.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoSetFlag(OS_FlagID id)
|
||||
{
|
||||
P_FLAG_NODE pnode;
|
||||
P_FCB pfcb;
|
||||
pfcb = &FlagCrl;
|
||||
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(id >= FLAG_MAX_NUM) /* Flag is valid or not */
|
||||
{
|
||||
return E_INVALID_ID; /* Invalid flag id */
|
||||
}
|
||||
if((pfcb->flagActive&(1<<id)) == 0)
|
||||
{
|
||||
return E_INVALID_ID; /* Flag is not exist */
|
||||
}
|
||||
#endif
|
||||
|
||||
if((pfcb->flagRdy&(1<<id)) != 0) /* Flag had already been set */
|
||||
{
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
pfcb->flagRdy |= (1<<id); /* Update the flags ready list */
|
||||
|
||||
OsSchedLock();
|
||||
pnode = pfcb->headNode;
|
||||
while(pnode != Co_NULL)
|
||||
{
|
||||
if(pnode->waitType == OPT_WAIT_ALL) /* Extract all the bits we want */
|
||||
{
|
||||
if((pnode->waitFlags&pfcb->flagRdy) == pnode->waitFlags)
|
||||
{
|
||||
/* Remove the flag node from the wait list */
|
||||
pnode = RemoveFromLink(pnode);
|
||||
if((pfcb->resetOpt&(1<<id)) != 0)/* If the flags is auto-reset*/
|
||||
{
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else /* Extract only the bits we want */
|
||||
{
|
||||
if( (pnode->waitFlags & pfcb->flagRdy) != 0)
|
||||
{
|
||||
/* Remove the flag node from the wait list */
|
||||
pnode = RemoveFromLink(pnode);
|
||||
if((pfcb->resetOpt&(1<<id)) != 0)
|
||||
{
|
||||
break; /* The flags is auto-reset */
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
pnode = pnode->nextNode;
|
||||
}
|
||||
OsSchedUnlock();
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Set a flag in ISR
|
||||
* @param[in] id Flag ID.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID Invalid event ID.
|
||||
* @retval E_OK Event deleted successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called in ISR to set a flag.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
#if CFG_MAX_SERVICE_REQUEST > 0
|
||||
StatusType isr_SetFlag(OS_FlagID id)
|
||||
{
|
||||
if(OSSchedLock > 0) /* If scheduler is locked,(the caller is ISR) */
|
||||
{
|
||||
/* Insert the request into service request queue */
|
||||
if(InsertInSRQ(FLAG_REQ,id,Co_NULL) == Co_FALSE)
|
||||
{
|
||||
return E_SEV_REQ_FULL; /* The service requst queue is full */
|
||||
}
|
||||
else
|
||||
{
|
||||
return E_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return(CoSetFlag(id)); /* The caller is not ISR, set the flag*/
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Block a task to wait a flag event
|
||||
* @param[in] pnode A node that will link into flag waiting list.
|
||||
* @param[in] flags Flag(s) that the node waiting for.
|
||||
* @param[in] waitType Waiting type of the node.
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to block a task to wait a flag event.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
static void FlagBlock(P_FLAG_NODE pnode,U32 flags,U8 waitType)
|
||||
{
|
||||
P_FCB pfcb;
|
||||
pfcb = &FlagCrl;
|
||||
|
||||
TCBRunning->pnode = pnode;
|
||||
pnode->waitTask = TCBRunning;
|
||||
pnode->waitFlags = flags; /* Save the flags that we need to wait for*/
|
||||
pnode->waitType = waitType; /* Save the type of wait */
|
||||
|
||||
if(pfcb->tailNode == Co_NULL) /* If this is the first NODE to insert? */
|
||||
{
|
||||
pnode->nextNode = Co_NULL;
|
||||
pnode->prevNode = Co_NULL;
|
||||
pfcb->headNode = pnode; /* Insert the NODE to the head */
|
||||
}
|
||||
else /* If it is not the first NODE to insert? */
|
||||
{
|
||||
pfcb->tailNode->nextNode = pnode; /* Insert the NODE to the tail */
|
||||
pnode->prevNode = pfcb->tailNode;
|
||||
pnode->nextNode = Co_NULL;
|
||||
}
|
||||
pfcb->tailNode = pnode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Remove a flag node from list
|
||||
* @param[in] pnode A node that will remove from flag waiting list.
|
||||
* @param[out] None
|
||||
* @retval pnode Next node of the node that have removed out.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to remove a flag node from the wait list.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
static P_FLAG_NODE RemoveFromLink(P_FLAG_NODE pnode)
|
||||
{
|
||||
P_OSTCB ptcb;
|
||||
|
||||
RemoveLinkNode(pnode); /* Remove the flag node from wait list. */
|
||||
ptcb = pnode->waitTask;
|
||||
|
||||
/* The task in the delay list */
|
||||
if(ptcb->delayTick != INVALID_VALUE)/* If the task is in tick delay list */
|
||||
{
|
||||
RemoveDelayList(ptcb); /* Remove the task from tick delay list */
|
||||
}
|
||||
|
||||
ptcb->pnode = (void*)0xffffffff;
|
||||
|
||||
if(ptcb == TCBRunning)
|
||||
{
|
||||
ptcb->state = TASK_RUNNING;
|
||||
}
|
||||
else
|
||||
{
|
||||
InsertToTCBRdyList(ptcb); /* Insert the task to ready list */
|
||||
}
|
||||
return (pnode->nextNode);
|
||||
}
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Remove a flag node from list
|
||||
* @param[in] pnode A node that will remove from flag waiting list.
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to remove a flag node from the wait list.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
void RemoveLinkNode(P_FLAG_NODE pnode)
|
||||
{
|
||||
/* If only one NODE in the list*/
|
||||
if((pnode->nextNode == Co_NULL) && (pnode->prevNode == Co_NULL))
|
||||
{
|
||||
FlagCrl.headNode = Co_NULL;
|
||||
FlagCrl.tailNode = Co_NULL;
|
||||
}
|
||||
else if(pnode->nextNode == Co_NULL) /* If the NODE is tail */
|
||||
{
|
||||
FlagCrl.tailNode = pnode->prevNode;
|
||||
pnode->prevNode->nextNode = Co_NULL;
|
||||
}
|
||||
else if(pnode->prevNode == Co_NULL) /* If the NODE is head */
|
||||
{
|
||||
FlagCrl.headNode = pnode->nextNode;
|
||||
pnode->nextNode->prevNode = Co_NULL;
|
||||
}
|
||||
else /* The NODE is in the middle */
|
||||
{
|
||||
pnode->nextNode->prevNode = pnode->prevNode;
|
||||
pnode->prevNode->nextNode = pnode->nextNode;
|
||||
}
|
||||
pnode->waitTask->pnode = Co_NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file hook.c
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief hook management implementation code of CooCox CoOS kernel.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------- Inlcude --------------------------------------*/
|
||||
#include <coocox.h>
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief IDLE task of OS
|
||||
* @param[in] pdata The parameter passed to IDLE task.
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is system IDLE task code.
|
||||
*******************************************************************************
|
||||
*/
|
||||
void CoIdleTask(void* pdata)
|
||||
{
|
||||
/* Add your codes here */
|
||||
for(; ;)
|
||||
{
|
||||
/* Add your codes here */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Hook for stack overflow
|
||||
* @param[in] taskID Piont to the task which lead to stack overflow.
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is a hook for stack overflow.
|
||||
*******************************************************************************
|
||||
*/
|
||||
void CoStkOverflowHook(OS_TID taskID)
|
||||
{
|
||||
/* Process stack overflow here */
|
||||
for(; ;)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,409 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file kernelHeap.c
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief kernel heap management implementation code of CooCox CoOS kernel.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------- Include ---------------------------------------*/
|
||||
#include <coocox.h>
|
||||
|
||||
|
||||
#if CFG_KHEAP_EN >0
|
||||
/*---------------------------- Variable Define -------------------------------*/
|
||||
U32 KernelHeap[KHEAP_SIZE] = {0}; /*!< Kernel heap */
|
||||
P_FMB FMBlist = Co_NULL; /*!< Free memory block list */
|
||||
KHeap Kheap = {0}; /*!< Kernel heap control */
|
||||
|
||||
|
||||
/*---------------------------- Function Declare ------------------------------*/
|
||||
static P_FMB GetPreFMB(P_UMB usedMB);
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Create kernel heap
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to create kernel heap.
|
||||
*******************************************************************************
|
||||
*/
|
||||
void CoCreateKheap(void)
|
||||
{
|
||||
Kheap.startAddr = (U32)(KernelHeap); /* Initialize kernel heap control */
|
||||
Kheap.endAddr = (U32)(KernelHeap) + KHEAP_SIZE*4;
|
||||
FMBlist = (P_FMB)KernelHeap; /* Initialize free memory block list*/
|
||||
FMBlist->nextFMB = Co_NULL;
|
||||
FMBlist->nextUMB = Co_NULL;
|
||||
FMBlist->preUMB = Co_NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Allocation size bytes of memory block from kernel heap.
|
||||
* @param[in] size Length of menory block.
|
||||
* @param[out] None
|
||||
* @retval Co_NULL Allocate fail.
|
||||
* @retval others Pointer to memory block.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to allocation size bytes of memory block.
|
||||
*******************************************************************************
|
||||
*/
|
||||
void* CoKmalloc(U32 size)
|
||||
{
|
||||
P_FMB freeMB,newFMB,preFMB;
|
||||
P_UMB usedMB,tmpUMB;
|
||||
U8* memAddr;
|
||||
U32 freeSize;
|
||||
U32 kheapAddr;
|
||||
|
||||
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
|
||||
if( size == 0 )
|
||||
{
|
||||
return Co_NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Word alignment,and add used memory head size */
|
||||
size = (((size+3)>>2)<<2) + 8;
|
||||
kheapAddr = Kheap.endAddr; /* Get the end address of kernel heap */
|
||||
OsSchedLock(); /* Lock schedule */
|
||||
freeMB = FMBlist; /* Get first item of free memory list */
|
||||
preFMB = Co_NULL;
|
||||
while(freeMB != Co_NULL ) /* Is out of free memory list? */
|
||||
{ /* No */
|
||||
if(freeMB->nextUMB == Co_NULL) /* Is last item of free memory list? */
|
||||
{ /* Yes,get size for this free item */
|
||||
freeSize = kheapAddr - (U32)(freeMB);
|
||||
}
|
||||
else /* No,get size for this free item */
|
||||
{
|
||||
freeSize = (U32)(freeMB->nextUMB) -1 - (U32)(freeMB);
|
||||
}
|
||||
if(freeSize >= size) /* If the size equal or greater than need */
|
||||
{ /* Yes,assign in this free memory */
|
||||
usedMB=(P_UMB)freeMB;/* Get the address for used memory block head*/
|
||||
|
||||
/* Get the address for used memory block */
|
||||
memAddr = (U8*)((U32)(usedMB) + 8);
|
||||
|
||||
/* Is left size of free memory smaller than 12? */
|
||||
if((freeSize-size) < 12)
|
||||
{
|
||||
/* Yes,malloc together(12 is the size of the header information
|
||||
of free memory block ). */
|
||||
if(preFMB != Co_NULL)/* Is first item of free memory block list? */
|
||||
{ /* No,set the link for list */
|
||||
preFMB->nextFMB = freeMB->nextFMB;
|
||||
}
|
||||
else /* Yes,reset the first item */
|
||||
{
|
||||
FMBlist = freeMB->nextFMB;
|
||||
}
|
||||
|
||||
if(freeMB->nextUMB != Co_NULL) /* Is last item? */
|
||||
{ /* No,set the link for list */
|
||||
tmpUMB = (P_UMB)((U32)(freeMB->nextUMB)-1);
|
||||
tmpUMB->preMB = (void*)((U32)usedMB|0x1);
|
||||
}
|
||||
|
||||
usedMB->nextMB = freeMB->nextUMB;/* Set used memory block link*/
|
||||
usedMB->preMB = freeMB->preUMB;
|
||||
}
|
||||
else /* No,the left size more than 12 */
|
||||
{
|
||||
/* Get new free memory block address */
|
||||
newFMB = (P_FMB)((U32)(freeMB) + size);
|
||||
|
||||
if(preFMB != Co_NULL)/* Is first item of free memory block list? */
|
||||
{
|
||||
preFMB->nextFMB = newFMB; /* No,set the link for list */
|
||||
}
|
||||
else
|
||||
{
|
||||
FMBlist = newFMB; /* Yes,reset the first item */
|
||||
}
|
||||
|
||||
/* Set link for new free memory block */
|
||||
newFMB->preUMB = (P_UMB)((U32)usedMB|0x1);
|
||||
newFMB->nextUMB = freeMB->nextUMB;
|
||||
newFMB->nextFMB = freeMB->nextFMB;
|
||||
|
||||
if(freeMB->nextUMB != Co_NULL) /* Is last item? */
|
||||
{ /* No,set the link for list */
|
||||
tmpUMB = (P_UMB)((U32)(freeMB->nextUMB)-1);
|
||||
tmpUMB->preMB = newFMB;
|
||||
}
|
||||
|
||||
usedMB->nextMB = newFMB; /* Set used memory block link */
|
||||
usedMB->preMB = freeMB->preUMB;
|
||||
}
|
||||
|
||||
if(freeMB->preUMB != Co_NULL) /* Is first item? */
|
||||
{ /* No,set the link for list */
|
||||
tmpUMB = (P_UMB)((U32)(freeMB->preUMB)-1);
|
||||
tmpUMB->nextMB = (void*)((U32)usedMB|0x1);
|
||||
}
|
||||
|
||||
OsSchedUnlock(); /* Unlock schedule */
|
||||
return memAddr; /* Return used memory block address */
|
||||
}
|
||||
preFMB = freeMB; /* Save current free memory block as previous */
|
||||
freeMB = freeMB->nextFMB; /* Get the next item as current item*/
|
||||
}
|
||||
OsSchedUnlock(); /* Unlock schedule */
|
||||
return Co_NULL; /* Error return */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Release memory block to kernel heap.
|
||||
* @param[in] memBuf Pointer to memory block.
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to release memory block.
|
||||
*******************************************************************************
|
||||
*/
|
||||
void CoKfree(void* memBuf)
|
||||
{
|
||||
P_FMB curFMB,nextFMB,preFMB;
|
||||
P_UMB usedMB,nextUMB,preUMB;
|
||||
|
||||
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
|
||||
if(memBuf == Co_NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
usedMB = (P_UMB)((U32)(memBuf)-8);
|
||||
|
||||
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
|
||||
if((U32)(memBuf) < Kheap.startAddr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if((U32)(memBuf) > Kheap.endAddr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
OsSchedLock(); /* Lock schedule */
|
||||
|
||||
#if CFG_PAR_CHECKOUT_EN >0 /* Check UMB in list */
|
||||
if((U32)(usedMB) < (U32)(FMBlist))
|
||||
{
|
||||
preUMB = (P_UMB)((U32)(FMBlist->preUMB)-1);
|
||||
while(preUMB != usedMB)
|
||||
{
|
||||
if(preUMB == Co_NULL)
|
||||
{
|
||||
OsSchedUnlock();
|
||||
return;
|
||||
}
|
||||
preUMB = (P_UMB)((U32)(preUMB->preMB)-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(FMBlist == Co_NULL)
|
||||
{
|
||||
nextUMB = (P_UMB)(Kheap.startAddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(FMBlist->nextUMB != Co_NULL)
|
||||
{
|
||||
nextUMB = (P_UMB)((U32)(FMBlist->nextUMB)-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextUMB = Co_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
while(nextUMB != usedMB)
|
||||
{
|
||||
if(nextUMB == Co_NULL)
|
||||
{
|
||||
OsSchedUnlock();
|
||||
return;
|
||||
}
|
||||
if(((U32)(nextUMB->nextMB)&0x1) == 0)
|
||||
{
|
||||
nextFMB = (P_FMB)(nextUMB->nextMB);
|
||||
nextUMB = (P_UMB)((U32)(nextFMB->nextUMB)-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextUMB = (P_UMB)((U32)(nextUMB->nextMB)-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Is between two free memory block? */
|
||||
if( (((U32)(usedMB->nextMB)&0x1) == 0) && (((U32)(usedMB->preMB)&0x1)==0) )
|
||||
{ /* Yes,is the only one item in kernel heap? */
|
||||
if((usedMB->nextMB == Co_NULL) && (usedMB->preMB == Co_NULL))
|
||||
{
|
||||
curFMB = (P_FMB)usedMB; /* Yes,release this item */
|
||||
curFMB->nextFMB = Co_NULL;
|
||||
curFMB->nextUMB = Co_NULL;
|
||||
curFMB->preUMB = Co_NULL;
|
||||
FMBlist = curFMB;
|
||||
}
|
||||
else if(usedMB->preMB == Co_NULL) /* Is the first item in kernel heap */
|
||||
{
|
||||
/* Yes,release this item,and set link for list */
|
||||
curFMB = (P_FMB)usedMB;
|
||||
nextFMB = (P_FMB)usedMB->nextMB;
|
||||
|
||||
curFMB->nextFMB = nextFMB->nextFMB;
|
||||
curFMB->nextUMB = nextFMB->nextUMB;
|
||||
curFMB->preUMB = Co_NULL;
|
||||
FMBlist = curFMB;
|
||||
}
|
||||
else if(usedMB->nextMB == Co_NULL) /* Is the last item in kernel heap */
|
||||
{ /* Yes,release this item,and set link for list */
|
||||
curFMB = (P_FMB)(usedMB->preMB);
|
||||
curFMB->nextFMB = Co_NULL;
|
||||
curFMB->nextUMB = Co_NULL;
|
||||
}
|
||||
else /* All no,show this item between two normal FMB */
|
||||
{
|
||||
/* release this item,and set link for list */
|
||||
nextFMB = (P_FMB)usedMB->nextMB;
|
||||
curFMB = (P_FMB)(usedMB->preMB);
|
||||
|
||||
curFMB->nextFMB = nextFMB->nextFMB;
|
||||
curFMB->nextUMB = nextFMB->nextUMB;
|
||||
}
|
||||
}
|
||||
else if(((U32)(usedMB->preMB)&0x1) == 0) /* Is between FMB and UMB? */
|
||||
{
|
||||
if(usedMB->preMB == Co_NULL) /* Yes,is the first item in kernel heap? */
|
||||
{
|
||||
/* Yes,release this item,and set link for list */
|
||||
curFMB = (P_FMB)usedMB;
|
||||
nextUMB = (P_UMB)usedMB->nextMB;
|
||||
curFMB->nextUMB = nextUMB;
|
||||
curFMB->preUMB = Co_NULL;
|
||||
curFMB->nextFMB = FMBlist;
|
||||
FMBlist = curFMB;
|
||||
}
|
||||
else /* No,release this item,and set link for list */
|
||||
{
|
||||
curFMB = (P_FMB)usedMB->preMB;
|
||||
nextUMB = (P_UMB)usedMB->nextMB;
|
||||
curFMB->nextUMB = nextUMB;
|
||||
}
|
||||
|
||||
}
|
||||
else if(((U32)(usedMB->nextMB)&0x1) == 0) /* Is between UMB and FMB? */
|
||||
{ /* Yes */
|
||||
preUMB = (P_UMB)(usedMB->preMB); /* Get previous UMB */
|
||||
curFMB = (P_FMB)(usedMB); /* new FMB */
|
||||
preFMB = GetPreFMB(usedMB); /* Get previous FMB */
|
||||
if(preFMB == Co_NULL) /* Is previous FMB==Co_NULL? */
|
||||
{
|
||||
nextFMB = FMBlist; /* Yes,get next FMB */
|
||||
FMBlist = curFMB; /* Reset new FMB as the first item of FMB list*/
|
||||
}
|
||||
else
|
||||
{
|
||||
nextFMB = preFMB->nextFMB; /* No,get next FMB */
|
||||
preFMB->nextFMB = curFMB; /* Set link for FMB list */
|
||||
}
|
||||
|
||||
if(nextFMB == Co_NULL) /* Is new FMB as last item of FMB list? */
|
||||
{
|
||||
curFMB->preUMB = preUMB; /* Yes,set link for list */
|
||||
curFMB->nextUMB = Co_NULL;
|
||||
curFMB->nextFMB = Co_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
curFMB->preUMB = preUMB; /* No,set link for list */
|
||||
curFMB->nextUMB = nextFMB->nextUMB;
|
||||
curFMB->nextFMB = nextFMB->nextFMB;
|
||||
}
|
||||
}
|
||||
else /* All no,show UMB between two UMB*/
|
||||
{
|
||||
curFMB = (P_FMB)(usedMB); /* new FMB */
|
||||
preFMB = GetPreFMB(usedMB); /* Get previous FMB */
|
||||
preUMB = (P_UMB)(usedMB->preMB); /* Get previous UMB */
|
||||
nextUMB = (P_UMB)(usedMB->nextMB); /* Get next UMB */
|
||||
|
||||
if(preFMB == Co_NULL ) /* Is previous FMB==Co_NULL? */
|
||||
{
|
||||
nextFMB = FMBlist; /* Yes,get next FMB */
|
||||
FMBlist = curFMB; /* Reset new FMB as the first item of FMB list */
|
||||
}
|
||||
else
|
||||
{
|
||||
nextFMB = preFMB->nextFMB; /* No,get next FMB */
|
||||
preFMB->nextFMB = curFMB; /* Set link for FMB list */
|
||||
}
|
||||
|
||||
curFMB->preUMB = preUMB; /* Set current FMB link for list */
|
||||
curFMB->nextUMB = nextUMB;
|
||||
curFMB->nextFMB = nextFMB;
|
||||
}
|
||||
|
||||
if(curFMB->preUMB != Co_NULL)/* Is current FMB as first item in kernel heap? */
|
||||
{ /* No,set link for list */
|
||||
preUMB = (P_UMB)((U32)(curFMB->preUMB)-1);
|
||||
preUMB->nextMB = (void*)curFMB;
|
||||
}
|
||||
if(curFMB->nextUMB != Co_NULL)/* Is current FMB as last item in kernel heap? */
|
||||
{ /* No,set link for list */
|
||||
nextUMB = (P_UMB)((U32)(curFMB->nextUMB)-1);
|
||||
nextUMB->preMB = (void*)curFMB;
|
||||
}
|
||||
OsSchedUnlock(); /* Unlock schedule */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Get previous free memory block pointer.
|
||||
* @param[in] usedMB Current used memory block.
|
||||
* @param[out] None
|
||||
* @retval Previous free memory block pointer.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to get previous free memory block pointer.
|
||||
*******************************************************************************
|
||||
*/
|
||||
static P_FMB GetPreFMB(P_UMB usedMB)
|
||||
{
|
||||
P_UMB preUMB;
|
||||
preUMB = usedMB;
|
||||
while(((U32)(preUMB->preMB)&0x1)) /* Is previous MB as FMB? */
|
||||
{ /* No,get previous MB */
|
||||
preUMB = (P_UMB)((U32)(preUMB->preMB)-1);
|
||||
}
|
||||
return (P_FMB)(preUMB->preMB); /* Yes,return previous MB */
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,325 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file mbox.c
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Mailbox management implementation code of CooCox CoOS kernel.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
/*---------------------------- Include ---------------------------------------*/
|
||||
#include <coocox.h>
|
||||
|
||||
|
||||
#if CFG_MAILBOX_EN > 0
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Create a mailbox
|
||||
* @param[in] sortType Mail box waiting list sort type.
|
||||
* @param[out] None
|
||||
* @retval E_CREATE_FAIL Create mailbox fail.
|
||||
* @retval others Create mailbox successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to create a mailbox.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
OS_EventID CoCreateMbox(U8 sortType)
|
||||
{
|
||||
P_ECB pecb;
|
||||
|
||||
/* Create a mailbox type event control block */
|
||||
pecb = CreatEvent(EVENT_TYPE_MBOX,sortType,Co_NULL);
|
||||
if(pecb == Co_NULL) /* If failed to create event block */
|
||||
{
|
||||
return E_CREATE_FAIL;
|
||||
}
|
||||
pecb->eventCounter = 0;
|
||||
return (pecb->id); /* Create a mailbox successfully, return event ID */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Delete a mailbox
|
||||
* @param[in] id Event ID.
|
||||
* @param[in] opt Delete option.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID Invalid event ID.
|
||||
* @retval E_INVALID_PARAMETER Invalid parameter.
|
||||
* @retval E_TASK_WAITTING Tasks waitting for the event,delete fail.
|
||||
* @retval E_OK Event deleted successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to delete a mailbox.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoDelMbox(OS_EventID id,U8 opt)
|
||||
{
|
||||
P_ECB pecb;
|
||||
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(id >= CFG_MAX_EVENT) /* Judge id is valid or not? */
|
||||
{
|
||||
return E_INVALID_ID; /* Id is invalid ,return error */
|
||||
}
|
||||
#endif
|
||||
pecb = &EventTbl[id];
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(pecb->eventType != EVENT_TYPE_MBOX)/* Validate event control block type*/
|
||||
{
|
||||
return E_INVALID_ID; /* The event is not mailbox */
|
||||
}
|
||||
#endif
|
||||
return (DeleteEvent(pecb,opt)); /* Delete the mailbox event control block */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Accept a mailbox
|
||||
* @param[in] id Event ID.
|
||||
* @param[out] perr A pointer to error code.
|
||||
* @retval Co_NULL
|
||||
* @retval A pointer to mailbox accepted.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to accept a mailbox.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
void* CoAcceptMail(OS_EventID id,StatusType* perr)
|
||||
{
|
||||
P_ECB pecb;
|
||||
void* pmail;
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(id >= CFG_MAX_EVENT)
|
||||
{
|
||||
*perr = E_INVALID_ID; /* Invalid 'id' */
|
||||
return Co_NULL;
|
||||
}
|
||||
#endif
|
||||
pecb = &EventTbl[id];
|
||||
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(pecb->eventType != EVENT_TYPE_MBOX)/* Invalid event control block type */
|
||||
{
|
||||
*perr = E_INVALID_ID;
|
||||
return Co_NULL;
|
||||
}
|
||||
#endif
|
||||
OsSchedLock();
|
||||
if(pecb->eventCounter == 1) /* If there is already a message */
|
||||
{
|
||||
*perr = E_OK;
|
||||
pmail = pecb->eventPtr; /* Get the message */
|
||||
pecb->eventPtr = Co_NULL; /* Clear the mailbox */
|
||||
pecb->eventCounter = 0;
|
||||
OsSchedUnlock();
|
||||
return pmail; /* Return the message received */
|
||||
}
|
||||
else /* If the mailbox is empty */
|
||||
{
|
||||
OsSchedUnlock();
|
||||
*perr = E_MBOX_EMPTY; /* Mailbox is empty,return Co_NULL */
|
||||
return Co_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Wait for a mailbox
|
||||
* @param[in] id Event ID.
|
||||
* @param[in] timeout The longest time for writting mail.
|
||||
* @param[out] perr A pointer to error code.
|
||||
* @retval Co_NULL
|
||||
* @retval A pointer to mailbox accept.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to wait a mailbox.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
void* CoPendMail(OS_EventID id,U32 timeout,StatusType* perr)
|
||||
{
|
||||
P_ECB pecb;
|
||||
void* pmail;
|
||||
P_OSTCB curTCB;
|
||||
|
||||
if(OSIntNesting > 0) /* If the caller is ISR */
|
||||
{
|
||||
*perr = E_CALL;
|
||||
return Co_NULL;
|
||||
}
|
||||
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(id >= CFG_MAX_EVENT)
|
||||
{
|
||||
*perr = E_INVALID_ID; /* Invalid 'id',retrun error */
|
||||
return Co_NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
pecb = &EventTbl[id];
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(pecb->eventType != EVENT_TYPE_MBOX)
|
||||
{
|
||||
*perr = E_INVALID_ID; /* Invalid event type,not EVENT_TYPE_MBOX */
|
||||
return Co_NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(OSSchedLock != 0) /* Judge schedule is locked or not? */
|
||||
{
|
||||
*perr = E_OS_IN_LOCK; /* Schedule is locked */
|
||||
return Co_NULL; /* return Co_NULL */
|
||||
}
|
||||
OsSchedLock();
|
||||
if( pecb->eventCounter == 1) /* If there is already a message */
|
||||
{
|
||||
*perr = E_OK;
|
||||
pmail = pecb->eventPtr; /* Get the message */
|
||||
pecb->eventPtr = Co_NULL; /* Clear the mailbox */
|
||||
pecb->eventCounter = 0;
|
||||
OsSchedUnlock();
|
||||
return pmail; /* Return the message received */
|
||||
}
|
||||
else /* If message is not available, task will pend */
|
||||
{
|
||||
OsSchedUnlock();
|
||||
curTCB = TCBRunning;
|
||||
if(timeout == 0) /* If time-out is not configured */
|
||||
{
|
||||
EventTaskToWait(pecb,curTCB); /* Block task until event occurs */
|
||||
*perr = E_OK;
|
||||
|
||||
/* Have recived a message or the mailbox have been deleted */
|
||||
pmail = curTCB->pmail;
|
||||
curTCB->pmail = Co_NULL;
|
||||
return pmail; /* Return received message or Co_NULL */
|
||||
}
|
||||
else /* If time-out is configured */
|
||||
{
|
||||
OsSchedLock();
|
||||
|
||||
/* Block task until event or timeout occurs */
|
||||
EventTaskToWait(pecb,curTCB);
|
||||
InsertDelayList(curTCB,timeout);
|
||||
OsSchedUnlock();
|
||||
if( curTCB->pmail == Co_NULL) /* Time-out occurred */
|
||||
{
|
||||
*perr = E_TIMEOUT;
|
||||
return Co_NULL;
|
||||
}
|
||||
else /* Have recived a message or the mailbox have been deleted*/
|
||||
{
|
||||
*perr = E_OK;
|
||||
pmail = curTCB->pmail;
|
||||
curTCB->pmail = Co_NULL;
|
||||
return pmail; /* Return received message or Co_NULL */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Post a mailbox
|
||||
* @param[in] id Event ID.
|
||||
* @param[in] pmail Pointer to mail that want to send.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID
|
||||
* @retval E_OK
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to post a mail.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoPostMail(OS_EventID id,void* pmail)
|
||||
{
|
||||
P_ECB pecb;
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(id >= CFG_MAX_EVENT)
|
||||
{
|
||||
return E_INVALID_ID; /* Invalid id,return error */
|
||||
}
|
||||
#endif
|
||||
|
||||
pecb = &EventTbl[id];
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(pecb->eventType != EVENT_TYPE_MBOX)/* Validate event control block type*/
|
||||
{
|
||||
return E_INVALID_ID; /* Event is not mailbox,return error*/
|
||||
}
|
||||
#endif
|
||||
|
||||
if(pecb->eventCounter == 0) /* If mailbox doesn't already have a message*/
|
||||
{
|
||||
OsSchedLock();
|
||||
pecb->eventPtr = pmail; /* Place message in mailbox */
|
||||
pecb->eventCounter = 1;
|
||||
EventTaskToRdy(pecb); /* Check waiting list */
|
||||
OsSchedUnlock();
|
||||
return E_OK;
|
||||
}
|
||||
else /* If there is already a message in mailbox */
|
||||
{
|
||||
return E_MBOX_FULL; /* Mailbox is full,and return "E_MBOX_FULL" */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Post a mailbox in ISR
|
||||
* @param[in] id Event ID.
|
||||
* @param[in] pmail Pointer to mail that want to send.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID
|
||||
* @retval E_OK
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to post a mail in ISR.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
#if CFG_MAX_SERVICE_REQUEST > 0
|
||||
StatusType isr_PostMail(OS_EventID id,void* pmail)
|
||||
{
|
||||
if(OSSchedLock > 0) /* If scheduler is locked,(the caller is ISR) */
|
||||
{
|
||||
/* Insert the request into service request queue */
|
||||
if(InsertInSRQ(MBOX_REQ,id,pmail) == Co_FALSE)
|
||||
{
|
||||
return E_SEV_REQ_FULL; /* If service request queue is full */
|
||||
}
|
||||
else /* Operate successfully */
|
||||
{
|
||||
return E_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return(CoPostMail(id,pmail)); /* Sends the message to the mailbox */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file mm.c
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief memory management implementation code of CooCox CoOS kernel.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------- Include ---------------------------------------*/
|
||||
#include <coocox.h>
|
||||
|
||||
|
||||
#if CFG_MM_EN > 0
|
||||
/*---------------------------- Variable Define -------------------------------*/
|
||||
MM MemoryTbl[CFG_MAX_MM] = {{0}};/*!< Table which save memory control block. */
|
||||
U32 MemoryIDVessel = 0; /*!< Memory ID container. */
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Create a memory partition
|
||||
* @param[in] memBuf Specify memory partition head address.
|
||||
* @param[in] blockSize Specify memory block size.
|
||||
* @param[in] blockNum Specify memory block number.
|
||||
* @param[out] None
|
||||
* @retval E_CREATE_FAIL Create memory partition fail.
|
||||
* @retval others Create memory partition successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to create a memory partition.
|
||||
*******************************************************************************
|
||||
*/
|
||||
OS_MMID CoCreateMemPartition(U8* memBuf,U32 blockSize,U32 blockNum)
|
||||
{
|
||||
U8 i,j;
|
||||
U8 *memory;
|
||||
P_MemBlk memBlk;
|
||||
memory = memBuf;
|
||||
|
||||
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
|
||||
if(memBuf == Co_NULL)
|
||||
{
|
||||
return E_CREATE_FAIL;
|
||||
}
|
||||
if(blockSize == 0)
|
||||
{
|
||||
return E_CREATE_FAIL;
|
||||
}
|
||||
if((blockSize&0x3) != 0)
|
||||
{
|
||||
return E_CREATE_FAIL;
|
||||
}
|
||||
if(blockNum<=1)
|
||||
{
|
||||
return E_CREATE_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
OsSchedLock(); /* Lock schedule */
|
||||
for(i = 0; i < CFG_MAX_MM; i++)
|
||||
{
|
||||
if((MemoryIDVessel & (1 << i)) == 0) /* Is free memory ID? */
|
||||
{
|
||||
MemoryIDVessel |= (1<<i); /* Yes,assign ID to this memory block */
|
||||
OsSchedUnlock(); /* Unlock schedule */
|
||||
MemoryTbl[i].memAddr = memory;/* Initialize memory control block*/
|
||||
MemoryTbl[i].freeBlock = memory;
|
||||
MemoryTbl[i].blockSize = blockSize;
|
||||
MemoryTbl[i].blockNum = blockNum;
|
||||
memBlk = (P_MemBlk)memory; /* Bulid list in this memory block*/
|
||||
for(j=0;j<blockNum-1;j++)
|
||||
{
|
||||
memory = memory+blockSize;
|
||||
memBlk->nextBlock = (P_MemBlk)memory;
|
||||
memBlk = memBlk->nextBlock;
|
||||
}
|
||||
memBlk->nextBlock = Co_NULL;
|
||||
return i; /* Return memory block ID */
|
||||
}
|
||||
}
|
||||
OsSchedUnlock(); /* Unlock schedule */
|
||||
return E_CREATE_FAIL; /* Error return */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Delete a memory partition
|
||||
* @param[in] mmID Specify memory partition that want to delete.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID The memory partition id passed was invalid,delete fail.
|
||||
* @retval E_OK Delete successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to Delete a memory partition.
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoDelMemoryPartition(OS_MMID mmID)
|
||||
{
|
||||
P_MM memCtl;
|
||||
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
|
||||
if(mmID >= CFG_MAX_MM)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
if( ((1<<mmID)&MemoryIDVessel) == 0)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
OsSchedLock(); /* Lock schedule */
|
||||
memCtl = &MemoryTbl[mmID]; /* Release memory control block */
|
||||
MemoryIDVessel &= ~(1<<mmID);
|
||||
OsSchedUnlock(); /* Unlock schedule */
|
||||
|
||||
memCtl->memAddr = Co_NULL;
|
||||
memCtl->freeBlock = Co_NULL;
|
||||
memCtl->blockSize = 0;
|
||||
memCtl->blockNum = 0;
|
||||
return E_OK; /* Return OK */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Get free block number in a memory partition
|
||||
* @param[in] mmID Specify memory partition.
|
||||
*
|
||||
* @param[out] E_INVALID_ID Invalid ID was passed and get counter failure.
|
||||
* @param[out] E_OK Get current counter successful.
|
||||
* @retval fbNum The number of free block.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to get free block number in a memory
|
||||
* partition.
|
||||
*******************************************************************************
|
||||
*/
|
||||
U32 CoGetFreeBlockNum(OS_MMID mmID,StatusType* perr)
|
||||
{
|
||||
U32 fbNum;
|
||||
P_MM memCtl;
|
||||
P_MemBlk memBlk;
|
||||
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
|
||||
if(mmID >= CFG_MAX_MM)
|
||||
{
|
||||
*perr = E_INVALID_ID;
|
||||
return 0;
|
||||
}
|
||||
if( ((1<<mmID)&MemoryIDVessel) == 0)
|
||||
{
|
||||
*perr = E_INVALID_ID; /* Invalid memory id,return 0 */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
memCtl = &MemoryTbl[mmID];
|
||||
OsSchedLock(); /* Lock schedule */
|
||||
memBlk = (P_MemBlk)(memCtl->freeBlock);/* Get the free item in memory list*/
|
||||
fbNum = 0;
|
||||
while(memBlk != Co_NULL) /* Get counter of free item */
|
||||
{
|
||||
fbNum++;
|
||||
memBlk = memBlk->nextBlock; /* Get next free iterm */
|
||||
}
|
||||
OsSchedUnlock(); /* Unlock schedul */
|
||||
*perr = E_OK;
|
||||
return fbNum; /* Return the counter of free item */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Get a memory buffer from memory partition
|
||||
* @param[in] mmID Specify memory partition that want to assign buffer.
|
||||
* @param[out] None
|
||||
* @retval Co_NULL Assign buffer fail.
|
||||
* @retval others Assign buffer successful,and return the buffer pointer.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to Delete a memory partition.
|
||||
*******************************************************************************
|
||||
*/
|
||||
void* CoGetMemoryBuffer(OS_MMID mmID)
|
||||
{
|
||||
P_MM memCtl;
|
||||
P_MemBlk memBlk;
|
||||
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
|
||||
if(mmID >= CFG_MAX_MM)
|
||||
{
|
||||
return Co_NULL;
|
||||
}
|
||||
if( ((1<<mmID)&MemoryIDVessel) == 0)
|
||||
{
|
||||
return Co_NULL;
|
||||
}
|
||||
#endif
|
||||
memCtl = &MemoryTbl[mmID];
|
||||
OsSchedLock(); /* Lock schedule */
|
||||
if(memCtl->freeBlock == Co_NULL ) /* Is there no free item in memory list */
|
||||
{
|
||||
OsSchedUnlock(); /* Unlock schedule */
|
||||
return Co_NULL; /* Yes,error return */
|
||||
}
|
||||
memBlk = (P_MemBlk)memCtl->freeBlock; /* Get free memory block */
|
||||
memCtl->freeBlock = (U8*)memBlk->nextBlock; /* Reset the first free item */
|
||||
OsSchedUnlock(); /* Unlock schedule */
|
||||
return memBlk; /* Return free memory block address */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Free a memory buffer to memory partition
|
||||
* @param[in] mmID Specify memory partition.
|
||||
* @param[in] buf Specify memory buffer that want to free.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID The memory partition id passed was invalid.
|
||||
* @retval E_INVALID_PARAMETER The parameter passed was invalid.
|
||||
* @retval E_OK Free successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to Delete a memory partition.
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoFreeMemoryBuffer(OS_MMID mmID,void* buf)
|
||||
{
|
||||
P_MM memCtl;
|
||||
P_MemBlk memBlk;
|
||||
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
|
||||
if(mmID >= CFG_MAX_MM)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
if( ((1<<mmID)&MemoryIDVessel) == 0)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
if(buf == Co_NULL)
|
||||
{
|
||||
return E_INVALID_PARAMETER;
|
||||
}
|
||||
#endif
|
||||
|
||||
memCtl = &MemoryTbl[mmID];
|
||||
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
|
||||
if((U32)buf < (U32)(memCtl->memAddr))
|
||||
{
|
||||
return E_INVALID_PARAMETER;
|
||||
}
|
||||
if((U32)buf > (U32)(memCtl->memAddr + memCtl->blockSize*memCtl->blockNum))
|
||||
{
|
||||
return E_INVALID_PARAMETER;
|
||||
}
|
||||
if(((U32)buf - (U32)(memCtl->memAddr))%(memCtl->blockSize) != 0)
|
||||
{
|
||||
return E_INVALID_PARAMETER;
|
||||
}
|
||||
#endif
|
||||
memBlk = (P_MemBlk)buf; /* Reset the first free item */
|
||||
OsSchedLock();
|
||||
memBlk->nextBlock = (P_MemBlk)memCtl->freeBlock;
|
||||
memCtl->freeBlock = buf;
|
||||
OsSchedUnlock();
|
||||
return E_OK; /* Return OK */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,349 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file mutex.c
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Mutex management implementation code of CooCox CoOS kernel.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*---------------------------- Include ---------------------------------------*/
|
||||
#include <coocox.h>
|
||||
|
||||
|
||||
/*---------------------------- Variable Define -------------------------------*/
|
||||
#if CFG_MUTEX_EN > 0
|
||||
|
||||
OS_MutexID MutexFreeID = 0; /*!< Point to next vliad mutex ID. */
|
||||
MUTEX MutexTbl[CFG_MAX_MUTEX] = {{0}}; /*!< Mutex struct array */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Create a mutex
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval E_CREATE_FAIL Create mutex fail.
|
||||
* @retval others Create mutex successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to create a mutex.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
OS_MutexID CoCreateMutex(void)
|
||||
{
|
||||
OS_MutexID id;
|
||||
P_MUTEX pMutex;
|
||||
OsSchedLock();
|
||||
|
||||
/* Assign a free mutex control block */
|
||||
if(MutexFreeID < CFG_MAX_MUTEX )
|
||||
{
|
||||
id = MutexFreeID++;
|
||||
OsSchedUnlock();
|
||||
pMutex = &MutexTbl[id];
|
||||
pMutex->hipriTaskID = INVALID_ID;
|
||||
pMutex->originalPrio = 0xff;
|
||||
pMutex->mutexFlag = MUTEX_FREE; /* Mutex is free,not was occupied */
|
||||
pMutex->taskID = INVALID_ID;
|
||||
pMutex->waittingList = Co_NULL;
|
||||
return id; /* Return mutex ID */
|
||||
}
|
||||
|
||||
OsSchedUnlock();
|
||||
return E_CREATE_FAIL; /* No free mutex control block */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Enter a critical area
|
||||
* @param[in] mutexID Specify mutex.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID Invalid mutex id.
|
||||
* @retval E_CALL Error call in ISR.
|
||||
* @retval E_OK Enter critical area successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called when entering a critical area.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoEnterMutexSection(OS_MutexID mutexID)
|
||||
{
|
||||
P_OSTCB ptcb,pCurTcb;
|
||||
P_MUTEX pMutex;
|
||||
|
||||
#if CFG_EVENT_EN >0
|
||||
P_ECB pecb;
|
||||
#endif
|
||||
|
||||
if(OSIntNesting > 0) /* If the caller is ISR */
|
||||
{
|
||||
return E_CALL;
|
||||
}
|
||||
if(OSSchedLock != 0) /* Is OS lock? */
|
||||
{
|
||||
return E_OS_IN_LOCK; /* Yes,error return */
|
||||
}
|
||||
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(mutexID >= MutexFreeID) /* Invalid 'mutexID' */
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
|
||||
OsSchedLock();
|
||||
pCurTcb = TCBRunning;
|
||||
pMutex = &MutexTbl[mutexID];
|
||||
|
||||
pCurTcb->mutexID = mutexID;
|
||||
if(pMutex->mutexFlag == MUTEX_FREE) /* If mutex is available */
|
||||
{
|
||||
pMutex->originalPrio = pCurTcb->prio; /* Save priority of owning task */
|
||||
pMutex->taskID = pCurTcb->taskID; /* Acquire the resource */
|
||||
pMutex->hipriTaskID = pCurTcb->taskID;
|
||||
pMutex->mutexFlag = MUTEX_OCCUPY; /* Occupy the mutex resource*/
|
||||
}
|
||||
/* If the mutex resource had been occupied */
|
||||
else if(pMutex->mutexFlag == MUTEX_OCCUPY)
|
||||
{
|
||||
ptcb = &TCBTbl[pMutex->taskID];
|
||||
if(ptcb->prio > pCurTcb->prio) /* Need to promote priority of owner? */
|
||||
{
|
||||
#if CFG_ORDER_LIST_SCHEDULE_EN ==0
|
||||
DeleteTaskPri(ptcb->prio);
|
||||
ActiveTaskPri(pCurTcb->prio);
|
||||
#endif
|
||||
ptcb->prio = pCurTcb->prio; /* Promote prio of owner */
|
||||
|
||||
/* Upgarde the highest priority about the mutex */
|
||||
pMutex->hipriTaskID = pCurTcb->taskID;
|
||||
if(ptcb->state == TASK_READY) /* If the task is ready to run */
|
||||
{
|
||||
RemoveFromTCBRdyList(ptcb); /* Remove the task from READY list*/
|
||||
InsertToTCBRdyList(ptcb); /* Insert the task into READY list*/
|
||||
}
|
||||
#if CFG_EVENT_EN >0
|
||||
/* If the task is waiting on a event */
|
||||
else if(ptcb->eventID != INVALID_ID)
|
||||
{
|
||||
pecb = &EventTbl[ptcb->eventID];
|
||||
|
||||
/* If the event waiting type is preemptive Priority */
|
||||
if(pecb->eventSortType == EVENT_SORT_TYPE_PRIO)
|
||||
{
|
||||
/* Remove the task from event waiting list */
|
||||
RemoveEventWaittingList(ptcb);
|
||||
|
||||
/* Insert the task into event waiting list */
|
||||
EventTaskToWait(pecb,ptcb);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
pCurTcb->state = TASK_WAITING; /* Block current task */
|
||||
TaskSchedReq = Co_TRUE;
|
||||
pCurTcb->TCBnext = Co_NULL;
|
||||
pCurTcb->TCBprev = Co_NULL;
|
||||
|
||||
ptcb = pMutex->waittingList;
|
||||
if(ptcb == Co_NULL) /* If the event waiting list is empty */
|
||||
{
|
||||
pMutex->waittingList = pCurTcb; /* Insert the task to head */
|
||||
}
|
||||
else /* If the event waiting list is not empty */
|
||||
{
|
||||
while(ptcb->TCBnext != Co_NULL) /* Insert the task to tail */
|
||||
{
|
||||
ptcb = ptcb->TCBnext;
|
||||
}
|
||||
ptcb->TCBnext = pCurTcb;
|
||||
pCurTcb->TCBprev = ptcb;
|
||||
pCurTcb->TCBnext = Co_NULL;
|
||||
}
|
||||
}
|
||||
OsSchedUnlock();
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Leave from a critical area
|
||||
* @param[in] mutexID Specify mutex id.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID Invalid mutex id.
|
||||
* @retval E_CALL Error call in ISR.
|
||||
* @retval E_OK Exit a critical area successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function must be called when exiting from a critical area.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoLeaveMutexSection(OS_MutexID mutexID)
|
||||
{
|
||||
P_OSTCB ptcb;
|
||||
P_MUTEX pMutex;
|
||||
U8 prio;
|
||||
U8 taskID;
|
||||
|
||||
if(OSIntNesting > 0) /* If the caller is ISR */
|
||||
{
|
||||
return E_CALL;
|
||||
}
|
||||
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(mutexID >= MutexFreeID)
|
||||
{
|
||||
return E_INVALID_ID; /* Invalid mutex id, return error */
|
||||
}
|
||||
#endif
|
||||
OsSchedLock();
|
||||
pMutex = &MutexTbl[mutexID]; /* Obtain point of mutex control block*/
|
||||
ptcb = &TCBTbl[pMutex->taskID];
|
||||
ptcb->mutexID = INVALID_ID;
|
||||
if(pMutex->waittingList == Co_NULL) /* If the mutex waiting list is empty */
|
||||
{
|
||||
pMutex->mutexFlag = MUTEX_FREE; /* The mutex resource is available */
|
||||
pMutex->taskID = INVALID_ID;
|
||||
OsSchedUnlock();
|
||||
}
|
||||
else /* If there is at least one task waitting for the mutex */
|
||||
{
|
||||
taskID = pMutex->taskID; /* Get task ID of mutex owner */
|
||||
|
||||
/* we havn't promoted current task's priority */
|
||||
if(pMutex->hipriTaskID == taskID)
|
||||
{
|
||||
ptcb = pMutex->waittingList;/* Point to mutex first waiting task */
|
||||
prio = ptcb->prio;
|
||||
while(ptcb != Co_NULL) /* Find the highest priority task */
|
||||
{
|
||||
if(ptcb->prio < prio)
|
||||
{
|
||||
prio = ptcb->prio;
|
||||
pMutex->hipriTaskID = ptcb->taskID;
|
||||
}
|
||||
ptcb = ptcb->TCBnext;
|
||||
}
|
||||
}
|
||||
else /* we have promoted current task's priority */
|
||||
{
|
||||
prio = TCBTbl[taskID].prio;
|
||||
}
|
||||
|
||||
/* Reset the task priority */
|
||||
pMutex->taskID = INVALID_ID;
|
||||
CoSetPriority(taskID,pMutex->originalPrio);
|
||||
|
||||
/* Find first task in waiting list ready to run */
|
||||
ptcb = pMutex->waittingList;
|
||||
pMutex->waittingList = ptcb->TCBnext;
|
||||
pMutex->originalPrio = ptcb->prio;
|
||||
pMutex->taskID = ptcb->taskID;
|
||||
|
||||
#if CFG_ORDER_LIST_SCHEDULE_EN ==0
|
||||
if(prio != ptcb->prio)
|
||||
{
|
||||
DeleteTaskPri(ptcb->prio);
|
||||
ActiveTaskPri(prio);
|
||||
}
|
||||
#endif
|
||||
|
||||
ptcb->prio = prio; /* Raise the task's priority */
|
||||
|
||||
/* Insert the task which acquire the mutex into ready list. */
|
||||
ptcb->TCBnext = Co_NULL;
|
||||
ptcb->TCBprev = Co_NULL;
|
||||
|
||||
InsertToTCBRdyList(ptcb); /* Insert the task into the READY list */
|
||||
OsSchedUnlock();
|
||||
}
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Remove a task from mutex waiting list
|
||||
* @param[in] ptcb TCB which will remove out.
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function be called when delete a task.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
void RemoveMutexList(P_OSTCB ptcb)
|
||||
{
|
||||
U8 prio;
|
||||
OS_TID taskID;
|
||||
P_MUTEX pMutex;
|
||||
pMutex = &MutexTbl[ptcb->mutexID];
|
||||
|
||||
/* If only one task waiting on mutex */
|
||||
if((ptcb->TCBnext ==Co_NULL) && (ptcb->TCBprev == Co_NULL))
|
||||
{
|
||||
pMutex->waittingList = Co_NULL; /* Waiting list is empty */
|
||||
}
|
||||
else if(ptcb->TCBnext == Co_NULL) /* If the task is the last of waiting list*/
|
||||
{
|
||||
/* Remove task from mutex waiting list */
|
||||
ptcb->TCBprev->TCBnext = Co_NULL;
|
||||
ptcb->TCBprev = Co_NULL;
|
||||
}
|
||||
else if(ptcb->TCBprev == Co_NULL)/* If the task is the first of waiting list*/
|
||||
{
|
||||
/* Remove task from waiting list */
|
||||
ptcb->TCBnext->TCBprev = Co_NULL;
|
||||
ptcb->TCBnext = Co_NULL;
|
||||
}
|
||||
else /* If the task is in the middle of waiting list */
|
||||
{
|
||||
/* Remove task from wait list */
|
||||
ptcb->TCBnext->TCBprev = ptcb->TCBprev;
|
||||
ptcb->TCBprev->TCBnext = ptcb->TCBnext;
|
||||
ptcb->TCBprev = Co_NULL;
|
||||
ptcb->TCBnext = Co_NULL;
|
||||
}
|
||||
|
||||
ptcb->mutexID = INVALID_ID;
|
||||
|
||||
/* If the task have highest priority in mutex waiting list */
|
||||
if(pMutex->hipriTaskID == ptcb->taskID)
|
||||
{
|
||||
ptcb = pMutex->waittingList;
|
||||
prio = pMutex->originalPrio;
|
||||
pMutex->hipriTaskID = pMutex->taskID;
|
||||
while(ptcb != Co_NULL) /* Find task ID of highest priority task*/
|
||||
{
|
||||
if(ptcb->prio < prio)
|
||||
{
|
||||
prio = ptcb->prio;
|
||||
pMutex->hipriTaskID = ptcb->taskID;
|
||||
}
|
||||
ptcb = ptcb->TCBnext;
|
||||
}
|
||||
taskID = pMutex->taskID;
|
||||
pMutex->taskID = INVALID_ID;
|
||||
CoSetPriority(taskID,prio); /* Reset the mutex ower priority */
|
||||
pMutex->taskID = taskID;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,393 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file queue.c
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Queue management implementation code of CooCox CoOS kernel.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
/*---------------------------- Include ---------------------------------------*/
|
||||
#include <coocox.h>
|
||||
|
||||
|
||||
#if CFG_QUEUE_EN > 0
|
||||
/*---------------------------- Variable Define -------------------------------*/
|
||||
QCB QueueTbl[CFG_MAX_QUEUE] = {{0}}; /*!< Queue control block table */
|
||||
U32 QueueIDVessel = 0; /*!< Queue list mask */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Create a queue
|
||||
* @param[in] qStart Pointer to mail pointer buffer.
|
||||
* @param[in] size The length of queue.
|
||||
* @param[in] sortType Mail queue waiting list sort type.
|
||||
* @param[out] None
|
||||
* @retval E_CREATE_FAIL Create queue fail.
|
||||
* @retval others Create queue successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to create a queue.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
OS_EventID CoCreateQueue(void **qStart, U16 size ,U8 sortType)
|
||||
{
|
||||
U8 i;
|
||||
P_ECB pecb;
|
||||
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if((qStart == Co_NULL) || (size == 0))
|
||||
{
|
||||
return E_CREATE_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
OsSchedLock();
|
||||
for(i = 0; i < CFG_MAX_QUEUE; i++)
|
||||
{
|
||||
/* Assign a free QUEUE control block */
|
||||
if((QueueIDVessel & (1 << i)) == 0)
|
||||
{
|
||||
QueueIDVessel |= (1<<i);
|
||||
OsSchedUnlock();
|
||||
|
||||
QueueTbl[i].qStart = qStart; /* Initialize the queue */
|
||||
QueueTbl[i].id = i;
|
||||
QueueTbl[i].head = 0;
|
||||
QueueTbl[i].tail = 0;
|
||||
QueueTbl[i].qMaxSize = size;
|
||||
QueueTbl[i].qSize = 0;
|
||||
|
||||
/* Get a event control block and initial the event content */
|
||||
pecb = CreatEvent(EVENT_TYPE_QUEUE,sortType,&QueueTbl[i]);
|
||||
|
||||
if(pecb == Co_NULL ) /* If there is no free EVENT control block*/
|
||||
{
|
||||
return E_CREATE_FAIL;
|
||||
}
|
||||
return (pecb->id);
|
||||
}
|
||||
}
|
||||
|
||||
OsSchedUnlock();
|
||||
return E_CREATE_FAIL; /* There is no free QUEUE control block */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Delete a queue
|
||||
* @param[in] id Event ID.
|
||||
* @param[in] opt Delete option.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID Invalid event ID.
|
||||
* @retval E_INVALID_PARAMETER Invalid parameter.
|
||||
* @retval E_TASK_WAITTING Tasks waitting for the event,delete fail.
|
||||
* @retval E_OK Event deleted successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to delete a queue.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoDelQueue(OS_EventID id,U8 opt)
|
||||
{
|
||||
P_ECB pecb;
|
||||
P_QCB pqcb;
|
||||
StatusType err;
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(id >= CFG_MAX_EVENT)
|
||||
{
|
||||
return E_INVALID_ID; /* Invalid id,return error */
|
||||
}
|
||||
#endif
|
||||
|
||||
pecb = &EventTbl[id];
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if( pecb->eventType != EVENT_TYPE_QUEUE)
|
||||
{
|
||||
return E_INVALID_ID; /* The event is not queue,return error*/
|
||||
}
|
||||
#endif
|
||||
pqcb = (P_QCB)pecb->eventPtr; /* Point at queue control block */
|
||||
err = DeleteEvent(pecb,opt); /* Delete the event control block */
|
||||
if(err == E_OK) /* If the event block have been deleted */
|
||||
{
|
||||
QueueIDVessel &= ~((U32)(1<<(pqcb->id))); /* Update free queue list */
|
||||
pqcb->qStart = Co_NULL;
|
||||
pqcb->id = 0;
|
||||
pqcb->head = 0;
|
||||
pqcb->tail = 0;
|
||||
pqcb->qMaxSize = 0;
|
||||
pqcb->qSize = 0;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Accept a mail from queue
|
||||
* @param[in] id Event ID.
|
||||
* @param[out] perr A pointer to error code.
|
||||
* @retval Co_NULL
|
||||
* @retval A pointer to mail accepted.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to accept a mail from queue.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
void* CoAcceptQueueMail(OS_EventID id,StatusType* perr)
|
||||
{
|
||||
P_ECB pecb;
|
||||
P_QCB pqcb;
|
||||
void* pmail;
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(id >= CFG_MAX_EVENT)
|
||||
{
|
||||
*perr = E_INVALID_ID; /* Invalid id,return error */
|
||||
return Co_NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
pecb = &EventTbl[id];
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(pecb->eventType != EVENT_TYPE_QUEUE)/* Invalid event control block type*/
|
||||
{
|
||||
*perr = E_INVALID_ID;
|
||||
return Co_NULL;
|
||||
}
|
||||
#endif
|
||||
pqcb = (P_QCB)pecb->eventPtr; /* Point at queue control block */
|
||||
OsSchedLock();
|
||||
if(pqcb->qSize != 0) /* If there are any messages in the queue */
|
||||
{
|
||||
/* Extract oldest message from the queue */
|
||||
pmail = *(pqcb->qStart + pqcb->head);
|
||||
pqcb->head++; /* Update the queue head */
|
||||
pqcb->qSize--; /* Update the number of messages in the queue */
|
||||
if(pqcb->head == pqcb->qMaxSize)
|
||||
{
|
||||
pqcb->head = 0;
|
||||
}
|
||||
OsSchedUnlock();
|
||||
*perr = E_OK;
|
||||
return pmail; /* Return message received */
|
||||
}
|
||||
else /* If there is no message in the queue*/
|
||||
{
|
||||
OsSchedUnlock();
|
||||
*perr = E_QUEUE_EMPTY;
|
||||
return Co_NULL; /* Return Co_NULL */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Pend for a mail
|
||||
* @param[in] id Event ID.
|
||||
* @param[in] timeout The longest time for writting mail.
|
||||
* @param[out] perr A pointer to error code.
|
||||
* @retval Co_NULL
|
||||
* @retval A pointer to mail accept.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to wait for a mail.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
void* CoPendQueueMail(OS_EventID id,U32 timeout,StatusType* perr)
|
||||
{
|
||||
P_ECB pecb;
|
||||
P_QCB pqcb;
|
||||
P_OSTCB curTCB;
|
||||
void* pmail;
|
||||
if(OSIntNesting > 0) /* If the caller is ISR */
|
||||
{
|
||||
*perr = E_CALL;
|
||||
return Co_NULL;
|
||||
}
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(id >= CFG_MAX_EVENT)
|
||||
{
|
||||
*perr = E_INVALID_ID; /* Invalid event id,return error */
|
||||
return Co_NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
pecb = &EventTbl[id];
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(pecb->eventType != EVENT_TYPE_QUEUE) /* The event type is not queue */
|
||||
{
|
||||
*perr = E_INVALID_ID;
|
||||
return Co_NULL;
|
||||
}
|
||||
#endif
|
||||
if(OSSchedLock != 0) /* Judge schedule is locked or not? */
|
||||
{
|
||||
*perr = E_OS_IN_LOCK; /* Schedule is locked,return error */
|
||||
return Co_NULL;
|
||||
}
|
||||
pqcb = (P_QCB)pecb->eventPtr; /* Point at queue control block */
|
||||
OsSchedLock();
|
||||
if(pqcb->qSize != 0) /* If there are any messages in the queue */
|
||||
{
|
||||
/* Extract oldest message from the queue */
|
||||
pmail = *(pqcb->qStart + pqcb->head);
|
||||
pqcb->head++; /* Update the queue head */
|
||||
pqcb->qSize--; /* Update the number of messages in the queue */
|
||||
if(pqcb->head == pqcb->qMaxSize)/* Check queue head */
|
||||
{
|
||||
pqcb->head = 0;
|
||||
}
|
||||
OsSchedUnlock();
|
||||
*perr = E_OK;
|
||||
return pmail; /* Return message received */
|
||||
}
|
||||
else /* If there is no message in the queue*/
|
||||
{
|
||||
OsSchedUnlock();
|
||||
curTCB = TCBRunning;
|
||||
if(timeout == 0) /* If time-out is not configured */
|
||||
{
|
||||
/* Block current task until the event occur */
|
||||
EventTaskToWait(pecb,curTCB);
|
||||
|
||||
/* Have recived message or the queue have been deleted */
|
||||
pmail = curTCB->pmail;
|
||||
curTCB->pmail = Co_NULL;
|
||||
*perr = E_OK;
|
||||
return pmail; /* Return message received or Co_NULL */
|
||||
}
|
||||
else /* If time-out is configured */
|
||||
{
|
||||
OsSchedLock();
|
||||
|
||||
/* Block current task until event or timeout occurs */
|
||||
EventTaskToWait(pecb,curTCB);
|
||||
InsertDelayList(curTCB,timeout);
|
||||
OsSchedUnlock();
|
||||
if(curTCB->pmail == Co_NULL) /* If time-out occurred */
|
||||
{
|
||||
*perr = E_TIMEOUT;
|
||||
return Co_NULL;
|
||||
}
|
||||
else /* If event occured */
|
||||
{
|
||||
pmail = curTCB->pmail;
|
||||
curTCB->pmail = Co_NULL;
|
||||
*perr = E_OK;
|
||||
return pmail; /* Return message received or Co_NULL */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Post a mail to queue
|
||||
* @param[in] id Event ID.
|
||||
* @param[in] pmail Pointer to mail that want to send.
|
||||
* @param[out] None
|
||||
* @retval E_OK
|
||||
* @retval E_INVALID_ID
|
||||
* @retval E_QUEUE_FULL
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to post a mail to queue.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoPostQueueMail(OS_EventID id,void* pmail)
|
||||
{
|
||||
P_ECB pecb;
|
||||
P_QCB pqcb;
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(id >= CFG_MAX_EVENT)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
|
||||
pecb = &EventTbl[id];
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(pecb->eventType != EVENT_TYPE_QUEUE)
|
||||
{
|
||||
return E_INVALID_ID; /* The event type isn't queue,return */
|
||||
}
|
||||
#endif
|
||||
pqcb = (P_QCB)pecb->eventPtr;
|
||||
if(pqcb->qSize == pqcb->qMaxSize) /* If queue is full */
|
||||
{
|
||||
return E_QUEUE_FULL;
|
||||
}
|
||||
else /* If queue is not full */
|
||||
{
|
||||
OsSchedLock();
|
||||
*(pqcb->qStart + pqcb->tail) = pmail; /* Insert message into queue */
|
||||
pqcb->tail++; /* Update queue tail */
|
||||
pqcb->qSize++; /* Update the number of messages in the queue */
|
||||
if(pqcb->tail == pqcb->qMaxSize) /* Check queue tail */
|
||||
{
|
||||
pqcb->tail = 0;
|
||||
}
|
||||
EventTaskToRdy(pecb); /* Check the event waiting list */
|
||||
OsSchedUnlock();
|
||||
return E_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Post a mail to queue in ISR
|
||||
* @param[in] id Event ID.
|
||||
* @param[in] pmail Pointer to mail that want to send.
|
||||
* @param[out] None
|
||||
* @retval E_OK
|
||||
* @retval E_INVALID_ID
|
||||
* @retval E_QUEUE_FULL
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called in ISR to post a mail to queue.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
#if CFG_MAX_SERVICE_REQUEST > 0
|
||||
StatusType isr_PostQueueMail(OS_EventID id,void* pmail)
|
||||
{
|
||||
if(OSSchedLock > 0) /* If scheduler is locked,(the caller is ISR) */
|
||||
{
|
||||
/* Insert the request into service request queue */
|
||||
if(InsertInSRQ(QUEUE_REQ,id,pmail) == Co_FALSE)
|
||||
{
|
||||
return E_SEV_REQ_FULL; /* If service request queue is full */
|
||||
}
|
||||
else /* If the request have been inserted into service request queue */
|
||||
{
|
||||
return E_OK;
|
||||
}
|
||||
}
|
||||
else /* The scheduler is unlocked */
|
||||
{
|
||||
return(CoPostQueueMail(id,pmail)); /* Send the message to the queue*/
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,322 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file sem.c
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Semaphore management implementation code of CooCox CoOS kernel.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------- Include ---------------------------------------*/
|
||||
#include <coocox.h>
|
||||
|
||||
#if CFG_SEM_EN >0
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Create a semaphore
|
||||
* @param[in] initCnt Semaphore valid counter.
|
||||
* @param[in] maxCnt Semaphore max initialize counter.
|
||||
* @param[in] sortType Semaphore sort type.
|
||||
* @param[out] None
|
||||
* @retval E_CREATE_FAIL Create semaphore fail.
|
||||
* @retval others Create semaphore successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to create a semaphore.
|
||||
*******************************************************************************
|
||||
*/
|
||||
OS_EventID CoCreateSem(U16 initCnt,U16 maxCnt,U8 sortType)
|
||||
{
|
||||
P_ECB pecb;
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(initCnt > maxCnt)
|
||||
{
|
||||
return E_CREATE_FAIL; /* Invalid 'initCnt' or 'maxCnt' */
|
||||
}
|
||||
|
||||
if ((sortType != EVENT_SORT_TYPE_FIFO) && (sortType != EVENT_SORT_TYPE_PRIO))
|
||||
{
|
||||
return E_CREATE_FAIL; /* Illegal sort type,return error */
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create a semaphore type event control block */
|
||||
pecb = CreatEvent(EVENT_TYPE_SEM,sortType,Co_NULL);
|
||||
if(pecb == Co_NULL) /* If failed to create event block */
|
||||
{
|
||||
return E_CREATE_FAIL;
|
||||
}
|
||||
pecb->eventCounter = initCnt;/* Initialize event block */
|
||||
pecb->initialEventCounter = maxCnt;
|
||||
return (pecb->id); /* Return event id */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Delete a semaphore
|
||||
* @param[in] id Event ID which to be deleted.
|
||||
* @param[in] opt Delete option.
|
||||
* @arg == OPT_DEL_ANYWAY Delete semaphore always
|
||||
* @arg == OPT_DEL_NO_PEND Delete semaphore only when no task pending on.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID Invalid event ID.
|
||||
* @retval E_INVALID_PARAMETER Invalid parameter.
|
||||
* @retval E_TASK_WAITTING Tasks waitting for the event,delete fail.
|
||||
* @retval E_OK Event deleted successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to delete a semaphore.
|
||||
*
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoDelSem(OS_EventID id,U8 opt)
|
||||
{
|
||||
P_ECB pecb;
|
||||
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(id >= CFG_MAX_EVENT)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
|
||||
pecb = &EventTbl[id];
|
||||
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(pecb->eventType != EVENT_TYPE_SEM)
|
||||
{
|
||||
return E_INVALID_ID; /* The event type is not semaphore */
|
||||
}
|
||||
#endif
|
||||
|
||||
return (DeleteEvent(pecb,opt));/* Delete the semaphore event control block*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Accept a semaphore without waitting
|
||||
* @param[in] id Event ID
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID Invalid event ID.
|
||||
* @retval E_SEM_EMPTY No semaphore exist.
|
||||
* @retval E_OK Get semaphore successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called accept a semaphore without waitting.
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoAcceptSem(OS_EventID id)
|
||||
{
|
||||
P_ECB pecb;
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(id >= CFG_MAX_EVENT)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
|
||||
pecb = &EventTbl[id];
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if( pecb->eventType != EVENT_TYPE_SEM)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
OsSchedLock();
|
||||
if(pecb->eventCounter > 0) /* If semaphore is positive,resource available */
|
||||
{
|
||||
OsSchedUnlock();
|
||||
pecb->eventCounter--; /* Decrement semaphore only if positive */
|
||||
return E_OK;
|
||||
}
|
||||
else /* Resource is not available */
|
||||
{
|
||||
OsSchedUnlock();
|
||||
return E_SEM_EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief wait for a semaphore
|
||||
* @param[in] id Event ID.
|
||||
* @param[in] timeout The longest time for writting semaphore.
|
||||
* @para 0
|
||||
* @para 0x1~0xff
|
||||
* @param[out] None
|
||||
* @retval E_CALL Error call in ISR.
|
||||
* @retval E_INVALID_ID Invalid event ID.
|
||||
* @retval E_TIMEOUT Semaphore was not received within the specified
|
||||
* 'timeout' time.
|
||||
* @retval E_OK The call was successful and your task owns the
|
||||
* resource,or the event you are waiting for occurred.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to waits for a semaphore.
|
||||
* @note IF this function is called in ISR,nothing to do and return immediately.
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoPendSem(OS_EventID id,U32 timeout)
|
||||
{
|
||||
P_ECB pecb;
|
||||
P_OSTCB curTCB;
|
||||
if(OSIntNesting > 0) /* If the caller is ISR */
|
||||
{
|
||||
return E_CALL;
|
||||
}
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(id >= CFG_MAX_EVENT)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
|
||||
pecb = &EventTbl[id];
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(pecb->eventType != EVENT_TYPE_SEM)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
if(OSSchedLock != 0) /* Schdule is locked? */
|
||||
{
|
||||
return E_OS_IN_LOCK; /* Yes,error return */
|
||||
}
|
||||
OsSchedLock();
|
||||
if(pecb->eventCounter > 0) /* If semaphore is positive,resource available */
|
||||
{
|
||||
pecb->eventCounter--; /* Decrement semaphore only if positive */
|
||||
OsSchedUnlock();
|
||||
return E_OK;
|
||||
}
|
||||
else /* Resource is not available */
|
||||
{
|
||||
OsSchedUnlock();
|
||||
curTCB = TCBRunning;
|
||||
if(timeout == 0) /* If time-out is not configured */
|
||||
{
|
||||
EventTaskToWait(pecb,curTCB); /* Block task until event occurs */
|
||||
curTCB->pmail = Co_NULL;
|
||||
return E_OK;
|
||||
}
|
||||
else /* If time-out is configured */
|
||||
{
|
||||
OsSchedLock();
|
||||
|
||||
/* Block task until event or timeout occurs */
|
||||
EventTaskToWait(pecb,curTCB);
|
||||
InsertDelayList(curTCB,timeout);
|
||||
|
||||
OsSchedUnlock();
|
||||
if (curTCB->pmail == Co_NULL) /* If pmail is Co_NULL, time-out occurred*/
|
||||
{
|
||||
return E_TIMEOUT;
|
||||
}
|
||||
else /* Event occurred or event have been deleted*/
|
||||
{
|
||||
curTCB->pmail = Co_NULL;
|
||||
return E_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Post a semaphore
|
||||
* @param[in] id id of event control block associated with the desired semaphore.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID Parameter id passed was invalid event ID.
|
||||
* @retval E_SEM_FULL Semaphore full.
|
||||
* @retval E_OK Semaphore had post successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to post a semaphore to corresponding event.
|
||||
*
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoPostSem(OS_EventID id)
|
||||
{
|
||||
P_ECB pecb;
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(id >= CFG_MAX_EVENT)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
|
||||
pecb = &EventTbl[id];
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(pecb->eventType != EVENT_TYPE_SEM) /* Invalid event control block type */
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Make sure semaphore will not overflow */
|
||||
if(pecb->eventCounter == pecb->initialEventCounter)
|
||||
{
|
||||
return E_SEM_FULL; /* The counter of Semaphore reach the max number*/
|
||||
}
|
||||
OsSchedLock();
|
||||
pecb->eventCounter++; /* Increment semaphore count to register event */
|
||||
EventTaskToRdy(pecb); /* Check semaphore event waiting list */
|
||||
OsSchedUnlock();
|
||||
return E_OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Post a semaphore in ISR
|
||||
* @param[in] id identifier of event control block associated with the
|
||||
* desired semaphore.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID Parameter id passed was invalid event ID.
|
||||
* @retval E_NO_TASK_WAITTING There are one more tasks waitting for the event.
|
||||
* @retval E_OK Semaphore had signaled successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called in ISR to post a semaphore to corresponding
|
||||
* event.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
#if CFG_MAX_SERVICE_REQUEST > 0
|
||||
StatusType isr_PostSem(OS_EventID id)
|
||||
{
|
||||
if(OSSchedLock > 0) /* If scheduler is locked,(the caller is ISR) */
|
||||
{
|
||||
/* Initiate a post service handling request */
|
||||
if(InsertInSRQ(SEM_REQ,id,Co_NULL) == Co_FALSE)
|
||||
{
|
||||
return E_SEV_REQ_FULL; /* If service request queue is full */
|
||||
}
|
||||
else /* Operate successfully */
|
||||
{
|
||||
return E_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return(CoPostSem(id)); /* Post semaphore */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,165 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file serviceReq.c
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief servive request management implementation code of CooCox CoOS kernel.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*---------------------------- Include ---------------------------------------*/
|
||||
#include <coocox.h>
|
||||
|
||||
#if (CFG_TASK_WAITTING_EN > 0) || (CFG_TMR_EN >0)
|
||||
|
||||
#if CFG_MAX_SERVICE_REQUEST > 0
|
||||
/*---------------------------- Variable Define -------------------------------*/
|
||||
SRQ ServiceReq = {0,0}; /*!< ISR server request queue */
|
||||
#endif
|
||||
BOOL IsrReq = Co_FALSE;
|
||||
#if (CFG_TASK_WAITTING_EN > 0)
|
||||
BOOL TimeReq = Co_FALSE; /*!< Time delay dispose request */
|
||||
#endif
|
||||
|
||||
#if CFG_TMR_EN > 0
|
||||
BOOL TimerReq = Co_FALSE; /*!< Timer dispose request */
|
||||
#endif
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Insert into service requst queue
|
||||
* @param[in] type Service request type.
|
||||
* @param[in] id Service request event id,event id/flag id.
|
||||
* @param[in] arg Service request argument.
|
||||
* @param[out] None
|
||||
*
|
||||
* @retval Co_FALSE Successfully insert into service request queue.
|
||||
* @retval Co_TRUE Failure to insert into service request queue.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function be called to insert a requst into service request
|
||||
* queue.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
#if (CFG_MAX_SERVICE_REQUEST > 0)
|
||||
BOOL InsertInSRQ(U8 type,U8 id,void* arg)
|
||||
{
|
||||
P_SQC pcell;
|
||||
U8 cnt;
|
||||
U8 heed;
|
||||
IRQ_DISABLE_SAVE();
|
||||
if (ServiceReq.cnt >= CFG_MAX_SERVICE_REQUEST)
|
||||
{
|
||||
IRQ_ENABLE_RESTORE ();
|
||||
|
||||
return Co_FALSE; /* Error return */
|
||||
}
|
||||
cnt = Inc8(&ServiceReq.cnt);
|
||||
heed = ServiceReq.head;
|
||||
IsrReq = Co_TRUE;
|
||||
pcell = &ServiceReq.cell[((cnt+heed)%CFG_MAX_SERVICE_REQUEST)];/*the tail */
|
||||
pcell->type = type; /* Save service request type, */
|
||||
pcell->id = id; /* event id */
|
||||
pcell->arg = arg; /* and parameter */
|
||||
IRQ_ENABLE_RESTORE ();
|
||||
|
||||
return Co_TRUE; /* Return OK */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Respond the request in the service request queue.
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function be called to respond the request in the service
|
||||
* request queue.
|
||||
* @note
|
||||
*******************************************************************************
|
||||
*/
|
||||
void RespondSRQ(void)
|
||||
{
|
||||
|
||||
#if CFG_MAX_SERVICE_REQUEST > 0
|
||||
SQC cell;
|
||||
|
||||
#endif
|
||||
|
||||
#if (CFG_TASK_WAITTING_EN > 0)
|
||||
if(TimeReq == Co_TRUE) /* Time delay request? */
|
||||
{
|
||||
TimeDispose(); /* Yes,call handler */
|
||||
TimeReq = Co_FALSE; /* Reset time delay request Co_FALSE */
|
||||
}
|
||||
#endif
|
||||
#if CFG_TMR_EN > 0
|
||||
if(TimerReq == Co_TRUE) /* Timer request? */
|
||||
{
|
||||
TmrDispose(); /* Yes,call handler */
|
||||
TimerReq = Co_FALSE; /* Reset timer request Co_FALSE */
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CFG_MAX_SERVICE_REQUEST > 0
|
||||
|
||||
while (ServiceReq.cnt != 0)
|
||||
{
|
||||
IRQ_DISABLE_SAVE (); /* need to protect the following */
|
||||
cell = ServiceReq.cell[ServiceReq.head]; /* extract one cell */
|
||||
ServiceReq.head = (ServiceReq.head + 1) % /* move head (pop) */
|
||||
CFG_MAX_SERVICE_REQUEST;
|
||||
ServiceReq.cnt--;
|
||||
IRQ_ENABLE_RESTORE (); /* now use the cell copy */
|
||||
|
||||
switch(cell.type) /* Judge service request type */
|
||||
{
|
||||
#if CFG_SEM_EN > 0
|
||||
case SEM_REQ: /* Semaphore post request,call handler*/
|
||||
CoPostSem(cell.id);
|
||||
break;
|
||||
#endif
|
||||
#if CFG_MAILBOX_EN > 0
|
||||
case MBOX_REQ: /* Mailbox post request,call handler */
|
||||
CoPostMail(cell.id, cell.arg);
|
||||
break;
|
||||
#endif
|
||||
#if CFG_FLAG_EN > 0
|
||||
case FLAG_REQ: /* Flag set request,call handler */
|
||||
CoSetFlag(cell.id);
|
||||
break;
|
||||
#endif
|
||||
#if CFG_QUEUE_EN > 0
|
||||
case QUEUE_REQ: /* Queue post request,call handler */
|
||||
CoPostQueueMail(cell.id, cell.arg);
|
||||
break;
|
||||
#endif
|
||||
default: /* Others,break */
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
IRQ_DISABLE_SAVE (); /* need to protect the following */
|
||||
|
||||
if (ServiceReq.cnt == 0) /* another item in the queue already? */
|
||||
{
|
||||
IsrReq = Co_FALSE; /* queue still empty here */
|
||||
}
|
||||
IRQ_ENABLE_RESTORE (); /* now it is done and return */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,376 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file time.c
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief time management implementation code of CooCox CoOS kernel.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*---------------------------- Include ---------------------------------------*/
|
||||
#include <coocox.h>
|
||||
|
||||
#if CFG_TASK_WAITTING_EN > 0
|
||||
|
||||
/*---------------------------- Variable Define -------------------------------*/
|
||||
P_OSTCB DlyList = Co_NULL; /*!< Header pointer to the DELAY list.*/
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Insert into DELAY list
|
||||
*
|
||||
* @param[in] ptcb Task that want to insert into DELAY list.
|
||||
* @param[in] ticks Delay system ticks.
|
||||
* @param[out] None
|
||||
* @retval None.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to insert task into DELAY list.
|
||||
*******************************************************************************
|
||||
*/
|
||||
void InsertDelayList(P_OSTCB ptcb,U32 ticks)
|
||||
{
|
||||
S32 deltaTicks;
|
||||
P_OSTCB dlyNext;
|
||||
|
||||
if(ticks == 0) /* Is delay tick == 0? */
|
||||
return; /* Yes,do nothing,return */
|
||||
if(DlyList == Co_NULL) /* Is no item in DELAY list? */
|
||||
{
|
||||
ptcb->delayTick = ticks; /* Yes,set this as first item */
|
||||
DlyList = ptcb;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No,find correct place ,and insert the task */
|
||||
dlyNext = DlyList;
|
||||
deltaTicks = ticks; /* Get task delay ticks */
|
||||
|
||||
/* Find correct place */
|
||||
while(dlyNext != Co_NULL)
|
||||
{
|
||||
/* Get delta ticks with previous item */
|
||||
deltaTicks -= dlyNext->delayTick;
|
||||
if(deltaTicks < 0) /* Is delta ticks<0? */
|
||||
{
|
||||
/* Yes,get correct place */
|
||||
if(dlyNext->TCBprev != Co_NULL) /* Is head item of DELAY list? */
|
||||
{
|
||||
dlyNext->TCBprev->TCBnext = ptcb; /* No,insert into */
|
||||
ptcb->TCBprev = dlyNext->TCBprev;
|
||||
ptcb->TCBnext = dlyNext;
|
||||
dlyNext->TCBprev = ptcb;
|
||||
}
|
||||
else /* Yes,set task as first item */
|
||||
{
|
||||
ptcb->TCBnext = DlyList;
|
||||
DlyList->TCBprev = ptcb;
|
||||
DlyList = ptcb;
|
||||
}
|
||||
ptcb->delayTick = ptcb->TCBnext->delayTick+deltaTicks;
|
||||
ptcb->TCBnext->delayTick -= ptcb->delayTick;
|
||||
break;
|
||||
}
|
||||
/* Is last item in DELAY list? */
|
||||
else if((deltaTicks >= 0) && (dlyNext->TCBnext == Co_NULL) )
|
||||
{
|
||||
ptcb->TCBprev = dlyNext; /* Yes,insert into */
|
||||
dlyNext->TCBnext = ptcb;
|
||||
ptcb->delayTick = deltaTicks;
|
||||
break;
|
||||
}
|
||||
dlyNext = dlyNext->TCBnext; /* Get the next item in DELAY list */
|
||||
}
|
||||
}
|
||||
|
||||
ptcb->state = TASK_WAITING; /* Set task status as TASK_WAITING */
|
||||
TaskSchedReq = Co_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Remove from the DELAY list
|
||||
* @param[in] ptcb Task that want to remove from the DELAY list.
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to remove task from the DELAY list.
|
||||
*******************************************************************************
|
||||
*/
|
||||
void RemoveDelayList(P_OSTCB ptcb)
|
||||
{
|
||||
|
||||
/* Is there only one item in the DELAY list? */
|
||||
if((ptcb->TCBprev == Co_NULL) && ( ptcb->TCBnext == Co_NULL))
|
||||
{
|
||||
DlyList = Co_NULL; /* Yes,set DELAY list as Co_NULL */
|
||||
}
|
||||
else if(ptcb->TCBprev == Co_NULL) /* Is the first item in DELAY list? */
|
||||
{
|
||||
/* Yes,remove task from the DELAY list,and reset the list */
|
||||
DlyList = ptcb->TCBnext;
|
||||
ptcb->TCBnext->delayTick += ptcb->delayTick;
|
||||
ptcb->TCBnext->TCBprev = Co_NULL;
|
||||
ptcb->TCBnext = Co_NULL;
|
||||
|
||||
}
|
||||
else if(ptcb->TCBnext == Co_NULL) /* Is the last item in DELAY list? */
|
||||
{
|
||||
ptcb->TCBprev->TCBnext = Co_NULL; /* Yes,remove task form DELAY list */
|
||||
ptcb->TCBprev = Co_NULL;
|
||||
}
|
||||
else /* No, remove task from DELAY list */
|
||||
{
|
||||
ptcb->TCBprev->TCBnext = ptcb->TCBnext;
|
||||
ptcb->TCBnext->TCBprev = ptcb->TCBprev;
|
||||
ptcb->TCBnext->delayTick += ptcb->delayTick;
|
||||
ptcb->TCBnext = Co_NULL;
|
||||
ptcb->TCBprev = Co_NULL;
|
||||
}
|
||||
ptcb->delayTick = INVALID_VALUE; /* Set task delay tick value as invalid */
|
||||
}
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Get current ticks
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval Return current system tick counter.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to obtain current system tick counter.
|
||||
*******************************************************************************
|
||||
*/
|
||||
U64 CoGetOSTime(void)
|
||||
{
|
||||
return OSTickCnt; /* Get system time(tick) */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Delay current task for specify ticks number
|
||||
* @param[in] ticks Specify system tick number which will delay.
|
||||
* @param[out] None
|
||||
* @retval E_CALL Error call in ISR.
|
||||
* @retval E_OK The current task was insert to DELAY list successful,it
|
||||
* will delay specify time.
|
||||
* @par Description
|
||||
* @details This function delay specify ticks for current task.
|
||||
*
|
||||
* @note This function be called in ISR,do nothing and return immediately.
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoTickDelay(U32 ticks)
|
||||
{
|
||||
if(OSIntNesting >0) /* Is call in ISR? */
|
||||
{
|
||||
return E_CALL; /* Yes,error return */
|
||||
}
|
||||
|
||||
if(ticks == INVALID_VALUE) /* Is tick==INVALID_VALUE? */
|
||||
{
|
||||
return E_INVALID_PARAMETER; /* Yes,error return */
|
||||
}
|
||||
if(ticks == 0) /* Is tick==0? */
|
||||
{
|
||||
return E_OK; /* Yes,do nothing ,return OK */
|
||||
}
|
||||
if(OSSchedLock != 0) /* Is OS lock? */
|
||||
{
|
||||
return E_OS_IN_LOCK; /* Yes,error return */
|
||||
}
|
||||
OsSchedLock(); /* Lock schedule */
|
||||
InsertDelayList(TCBRunning,ticks); /* Insert task in DELAY list */
|
||||
OsSchedUnlock(); /* Unlock schedule,and call task schedule */
|
||||
return E_OK; /* Return OK */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Reset task delay ticks
|
||||
* @param[in] ptcb Task that want to insert into DELAY list.
|
||||
* @param[in] ticks Specify system tick number which will delay .
|
||||
* @param[out] None
|
||||
* @retval E_CALL Error call in ISR.
|
||||
* @retval E_INVALID_ID Invalid task id.
|
||||
* @retval E_NOT_IN_DELAY_LIST Task not in delay list.
|
||||
* @retval E_OK The current task was inserted to DELAY list
|
||||
* successful,it will delay for specify time.
|
||||
* @par Description
|
||||
* @details This function delay specify ticks for current task.
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoResetTaskDelayTick(OS_TID taskID,U32 ticks)
|
||||
{
|
||||
P_OSTCB ptcb;
|
||||
|
||||
|
||||
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
|
||||
if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
|
||||
ptcb = &TCBTbl[taskID];
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
if(ptcb->stkPtr == Co_NULL)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(ptcb->delayTick == INVALID_VALUE) /* Is tick==INVALID_VALUE? */
|
||||
{
|
||||
return E_NOT_IN_DELAY_LIST; /* Yes,error return */
|
||||
}
|
||||
OsSchedLock(); /* Lock schedule */
|
||||
RemoveDelayList(ptcb); /* Remove task from the DELAY list */
|
||||
|
||||
if(ticks == 0) /* Is delay tick==0? */
|
||||
{
|
||||
InsertToTCBRdyList(ptcb); /* Insert task into the DELAY list */
|
||||
}
|
||||
else
|
||||
{
|
||||
InsertDelayList(ptcb,ticks); /* No,insert task into DELAY list */
|
||||
}
|
||||
OsSchedUnlock(); /* Unlock schedule,and call task schedule */
|
||||
return E_OK; /* Return OK */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Delay current task for detail time
|
||||
* @param[in] hour Specify the number of hours.
|
||||
* @param[in] minute Specify the number of minutes.
|
||||
* @param[in] sec Specify the number of seconds.
|
||||
* @param[in] millsec Specify the number of millseconds.
|
||||
* @param[out] None
|
||||
* @retval E_CALL Error call in ISR.
|
||||
* @retval E_INVALID_PARAMETER Parameter passed was invalid,delay fail.
|
||||
* @retval E_OK The current task was inserted to DELAY list
|
||||
* successful,it will delay for specify time.
|
||||
* @par Description
|
||||
* @details This function delay specify time for current task.
|
||||
*
|
||||
* @note If this function called in ISR,do nothing and return immediately.
|
||||
*******************************************************************************
|
||||
*/
|
||||
#if CFG_TIME_DELAY_EN >0
|
||||
StatusType CoTimeDelay(U8 hour,U8 minute,U8 sec,U16 millsec)
|
||||
{
|
||||
U32 ticks;
|
||||
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
|
||||
if(OSIntNesting > 0)
|
||||
{
|
||||
return E_CALL;
|
||||
}
|
||||
if((minute > 59)||(sec > 59)||(millsec > 999))
|
||||
return E_INVALID_PARAMETER;
|
||||
#endif
|
||||
if(OSSchedLock != 0) /* Is OS lock? */
|
||||
{
|
||||
return E_OS_IN_LOCK; /* Yes,error return */
|
||||
}
|
||||
|
||||
/* Get tick counter from time */
|
||||
ticks = ((hour*3600) + (minute*60) + (sec)) * (CFG_SYSTICK_FREQ)\
|
||||
+ (millsec*CFG_SYSTICK_FREQ + 500)/1000;
|
||||
|
||||
CoTickDelay(ticks); /* Call tick delay */
|
||||
return E_OK; /* Return OK */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Dispose time delay
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to dispose time delay of all task.
|
||||
*******************************************************************************
|
||||
*/
|
||||
void TimeDispose(void)
|
||||
{
|
||||
P_OSTCB dlyList;
|
||||
|
||||
dlyList = DlyList; /* Get first item of DELAY list */
|
||||
while((dlyList != Co_NULL) && (dlyList->delayTick == 0) )
|
||||
{
|
||||
|
||||
#if CFG_EVENT_EN > 0
|
||||
if(dlyList->eventID != INVALID_ID) /* Is task in event waiting list? */
|
||||
{
|
||||
RemoveEventWaittingList(dlyList); /* Yes,remove task from list */
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CFG_FLAG_EN > 0
|
||||
if(dlyList->pnode != Co_NULL) /* Is task in flag waiting list? */
|
||||
{
|
||||
RemoveLinkNode(dlyList->pnode); /* Yes,remove task from list */
|
||||
}
|
||||
#endif
|
||||
dlyList->delayTick = INVALID_VALUE; /* Set delay tick value as invalid*/
|
||||
DlyList = dlyList->TCBnext; /* Get next item as the head of DELAY list*/
|
||||
dlyList->TCBnext = Co_NULL;
|
||||
|
||||
InsertToTCBRdyList(dlyList); /* Insert task into READY list */
|
||||
|
||||
dlyList = DlyList; /* Get the first item of DELAY list */
|
||||
if(dlyList != Co_NULL) /* Is DELAY list as Co_NULL? */
|
||||
{
|
||||
dlyList->TCBprev = Co_NULL; /* No,initialize the first item */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Dispose time delay in ISR
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called in systick interrupt to dispose time delay
|
||||
* of all task.
|
||||
*******************************************************************************
|
||||
*/
|
||||
void isr_TimeDispose(void)
|
||||
{
|
||||
if(OSSchedLock > 1) /* Is schedule lock? */
|
||||
{
|
||||
IsrReq = Co_TRUE;
|
||||
TimeReq = Co_TRUE; /* Yes,set time request Co_TRUE */
|
||||
}
|
||||
else
|
||||
{
|
||||
TimeDispose(); /* No,call handler */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,447 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file timer.c
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief timer management implementation code of CooCox CoOS kernel.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*---------------------------- Include ---------------------------------------*/
|
||||
#include <coocox.h>
|
||||
|
||||
/*---------------------------- Variable Define -------------------------------*/
|
||||
#if CFG_TMR_EN > 0
|
||||
|
||||
TmrCtrl TmrTbl[CFG_MAX_TMR]= {{0}};/*!< Table which save timer control block.*/
|
||||
P_TmrCtrl TmrList = Co_NULL; /*!< The header of the TmrCtrl list. */
|
||||
U32 TmrIDVessel = 0; /*!< Timer ID container. */
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Insert a timer into the timer list
|
||||
* @param[in] tmrID Specify timer ID which insertted.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID Timer ID passed was invalid,insert fail.
|
||||
* @retval E_OK Insert successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to insert a timer into the timer list.
|
||||
*******************************************************************************
|
||||
*/
|
||||
static void InsertTmrList(OS_TCID tmrID)
|
||||
{
|
||||
P_TmrCtrl pTmr;
|
||||
S32 deltaTicks;
|
||||
U32 tmrCnt;
|
||||
tmrCnt = TmrTbl[tmrID].tmrCnt; /* Get timer time */
|
||||
|
||||
if(tmrCnt == 0) /* Is timer time==0? */
|
||||
{
|
||||
return; /* Do nothing,return */
|
||||
}
|
||||
|
||||
OsSchedLock(); /* Lock schedule */
|
||||
if(TmrList == Co_NULL) /* Is no item in timer list? */
|
||||
{
|
||||
TmrList = &TmrTbl[tmrID]; /* Yes,set this as first item */
|
||||
}
|
||||
else /* No,find correct place ,and insert inserted timer */
|
||||
{
|
||||
pTmr = TmrList;
|
||||
deltaTicks = tmrCnt; /* Get timer tick */
|
||||
|
||||
/* find correct place */
|
||||
while(pTmr != Co_NULL)
|
||||
{
|
||||
deltaTicks -= pTmr->tmrCnt; /* Get ticks with previous item */
|
||||
if(deltaTicks < 0) /* Is delta ticks<0? */
|
||||
{
|
||||
/* Yes,get correct place */
|
||||
if(pTmr->tmrPrev!= Co_NULL)/* Is head item of timer list? */
|
||||
{
|
||||
/* No,insert into */
|
||||
pTmr->tmrPrev->tmrNext = &TmrTbl[tmrID];
|
||||
TmrTbl[tmrID].tmrPrev = pTmr->tmrPrev;
|
||||
TmrTbl[tmrID].tmrNext = pTmr;
|
||||
pTmr->tmrPrev = &TmrTbl[tmrID];
|
||||
}
|
||||
else /* Yes,set task as first item */
|
||||
{
|
||||
TmrTbl[tmrID].tmrNext = TmrList;
|
||||
TmrList->tmrPrev = &TmrTbl[tmrID];
|
||||
TmrList = &TmrTbl[tmrID];
|
||||
}
|
||||
TmrTbl[tmrID].tmrCnt = TmrTbl[tmrID].tmrNext->tmrCnt+deltaTicks;
|
||||
TmrTbl[tmrID].tmrNext->tmrCnt -= TmrTbl[tmrID].tmrCnt;
|
||||
break;
|
||||
}
|
||||
/* Is last item in list? */
|
||||
else if((deltaTicks >= 0) && (pTmr->tmrNext == Co_NULL))
|
||||
{
|
||||
/* Yes,insert into */
|
||||
TmrTbl[tmrID].tmrPrev = pTmr;
|
||||
pTmr->tmrNext = &TmrTbl[tmrID];
|
||||
TmrTbl[tmrID].tmrCnt = deltaTicks;
|
||||
break;
|
||||
}
|
||||
pTmr = pTmr->tmrNext; /* Get the next item in timer list */
|
||||
}
|
||||
}
|
||||
OsSchedUnlock(); /* Unlock schedule */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Remove a timer from the timer list
|
||||
* @param[in] tmrID Specify ID for a timer which removed form timer list.
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to remove a timer from the timer list.
|
||||
*******************************************************************************
|
||||
*/
|
||||
static void RemoveTmrList(OS_TCID tmrID)
|
||||
{
|
||||
P_TmrCtrl pTmr;
|
||||
|
||||
pTmr = &TmrTbl[tmrID];
|
||||
|
||||
OsSchedLock(); /* Lock schedule */
|
||||
|
||||
/* Is there only one item in timer list? */
|
||||
if((pTmr->tmrPrev == Co_NULL) && (pTmr->tmrNext == Co_NULL))
|
||||
{
|
||||
TmrList = Co_NULL; /* Yes,set timer list as Co_NULL */
|
||||
}
|
||||
else if(pTmr->tmrPrev == Co_NULL) /* Is the first item in timer list? */
|
||||
{ /* Yes,remove timer from list,and reset timer list */
|
||||
TmrList = pTmr->tmrNext;
|
||||
TmrList->tmrPrev = Co_NULL;
|
||||
pTmr->tmrNext->tmrCnt += pTmr->tmrCnt;
|
||||
pTmr->tmrNext = Co_NULL;
|
||||
}
|
||||
else if(pTmr->tmrNext == Co_NULL) /* Is the last item in timer list? */
|
||||
{
|
||||
/* Yes,remove timer form list */
|
||||
pTmr->tmrPrev->tmrNext = Co_NULL;
|
||||
pTmr->tmrPrev = Co_NULL;
|
||||
}
|
||||
else /* No, remove timer from list */
|
||||
{
|
||||
pTmr->tmrPrev->tmrNext = pTmr->tmrNext;
|
||||
pTmr->tmrNext->tmrPrev = pTmr->tmrPrev;
|
||||
pTmr->tmrNext->tmrCnt += pTmr->tmrCnt;
|
||||
pTmr->tmrNext = Co_NULL;
|
||||
pTmr->tmrPrev = Co_NULL;
|
||||
}
|
||||
OsSchedUnlock(); /* Unlock schedule */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Create a timer
|
||||
* @param[in] tmrType Specify timer's type.
|
||||
* @param[in] tmrCnt Specify timer initial counter value.
|
||||
* @param[in] tmrReload Specify timer reload value.
|
||||
* @param[in] func Specify timer callback function entry.
|
||||
* @param[out] None
|
||||
* @retval E_CREATE_FAIL Create timer fail.
|
||||
* @retval others Create timer successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to create a timer.
|
||||
*******************************************************************************
|
||||
*/
|
||||
OS_TCID CoCreateTmr(U8 tmrType, U32 tmrCnt, U32 tmrReload, vFUNCPtr func)
|
||||
{
|
||||
U8 i;
|
||||
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
|
||||
if((tmrType != TMR_TYPE_ONE_SHOT) && (tmrType != TMR_TYPE_PERIODIC))
|
||||
{
|
||||
return E_CREATE_FAIL;
|
||||
}
|
||||
if(func == Co_NULL)
|
||||
{
|
||||
return E_CREATE_FAIL;
|
||||
}
|
||||
#endif
|
||||
OsSchedLock(); /* Lock schedule */
|
||||
for(i = 0; i < CFG_MAX_TMR; i++)
|
||||
{
|
||||
if((TmrIDVessel & (1 << i)) == 0) /* Is free timer ID? */
|
||||
{
|
||||
TmrIDVessel |= (1<<i); /* Yes,assign ID to this timer */
|
||||
OsSchedUnlock(); /* Unlock schedule */
|
||||
TmrTbl[i].tmrID = i; /* Initialize timer as user set */
|
||||
TmrTbl[i].tmrType = tmrType;
|
||||
TmrTbl[i].tmrState = TMR_STATE_STOPPED;
|
||||
TmrTbl[i].tmrCnt = tmrCnt;
|
||||
TmrTbl[i].tmrReload = tmrReload;
|
||||
TmrTbl[i].tmrCallBack = func;
|
||||
TmrTbl[i].tmrPrev = Co_NULL;
|
||||
TmrTbl[i].tmrNext = Co_NULL;
|
||||
return i; /* Return timer ID */
|
||||
}
|
||||
}
|
||||
OsSchedUnlock(); /* Unlock schedule */
|
||||
return E_CREATE_FAIL; /* Error return */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Start counter
|
||||
* @param[in] tmrID Specify a timer which startted.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID The timer id passed was invalid,can't start timer
|
||||
* @retval E_OK Insert a timer to timer list and start it successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to make a timer start countering.
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoStartTmr(OS_TCID tmrID)
|
||||
{
|
||||
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
|
||||
if(tmrID >= CFG_MAX_TMR)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
if( (TmrIDVessel & (1<<tmrID)) == 0)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(TmrTbl[tmrID].tmrState == TMR_STATE_RUNNING) /* Is timer running? */
|
||||
{
|
||||
return E_OK; /* Yes,do nothing,return OK */
|
||||
}
|
||||
|
||||
/* No,set timer status as TMR_STATE_RUNNING */
|
||||
TmrTbl[tmrID].tmrState = TMR_STATE_RUNNING;
|
||||
InsertTmrList(tmrID); /* Insert this timer into timer list */
|
||||
return E_OK; /* Return OK */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Stop countering for a spcify timer
|
||||
* @param[in] tmrID Specify a timer which stopped.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID The timer id passed was invalid, stop failure.
|
||||
* @retval E_OK Stop a timer countering successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to stop a timer from counting.
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoStopTmr(OS_TCID tmrID)
|
||||
{
|
||||
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
|
||||
if(tmrID >= CFG_MAX_TMR)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
if((TmrIDVessel & (1<<tmrID)) == 0)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if(TmrTbl[tmrID].tmrState == TMR_STATE_STOPPED)/* Does timer stop running?*/
|
||||
{
|
||||
return E_OK; /* Yes,do nothing,return OK */
|
||||
}
|
||||
RemoveTmrList(tmrID); /* No,remove this timer from timer list */
|
||||
|
||||
/* Set timer status as TMR_STATE_STOPPED */
|
||||
TmrTbl[tmrID].tmrState = TMR_STATE_STOPPED;
|
||||
return E_OK; /* Return OK */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Delete a timer
|
||||
* @param[in] tmrID Specify a timer which deleted.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID The timer id passed was invalid,deleted failure.
|
||||
* @retval E_OK Delete a timer successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to delete a timer which created before.
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoDelTmr(OS_TCID tmrID)
|
||||
{
|
||||
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
|
||||
if(tmrID >= CFG_MAX_TMR)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
if( (TmrIDVessel & (1<<tmrID)) == 0)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(TmrTbl[tmrID].tmrState == TMR_STATE_RUNNING) /* Is timer running? */
|
||||
{
|
||||
RemoveTmrList(tmrID); /* Yes,remove this timer from timer list*/
|
||||
}
|
||||
TmrIDVessel &=~(1<<tmrID); /* Release resource that this timer hold*/
|
||||
return E_OK; /* Return OK */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Get current counter of specify timer
|
||||
* @param[in] tmrID Specify timer by ID.
|
||||
* @param[out] E_INVALID_ID Invalid ID was passed and get counter failure.
|
||||
* @param[out] E_OK Get current counter successful.
|
||||
* @retval Current counter of a timer which specify by id.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to obtain current counter of specify timer.
|
||||
*******************************************************************************
|
||||
*/
|
||||
U32 CoGetCurTmrCnt(OS_TCID tmrID,StatusType* perr)
|
||||
{
|
||||
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
|
||||
if(tmrID >= CFG_MAX_TMR)
|
||||
{
|
||||
*perr = E_INVALID_ID;
|
||||
return 0;
|
||||
}
|
||||
if((TmrIDVessel & (1<<tmrID)) == 0)
|
||||
{
|
||||
*perr = E_INVALID_ID;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
*perr = E_OK;
|
||||
return TmrTbl[tmrID].tmrCnt; /* Return timer counter */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Setting for a specify timer
|
||||
* @param[in] tmrID Specify timer by ID.
|
||||
* @param[in] tmrCnt Specify timer counter which need to be set.
|
||||
* @param[in] tmrReload Specify timer reload value which need to be set.
|
||||
* @param[out] None
|
||||
* @retval E_INVALID_ID The ID passed was invalid,set fail.
|
||||
* @retval E_OK Set timer counter successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to set timer counter and reload value.
|
||||
*******************************************************************************
|
||||
*/
|
||||
StatusType CoSetTmrCnt(OS_TCID tmrID,U32 tmrCnt,U32 tmrReload)
|
||||
{
|
||||
#if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */
|
||||
if(tmrID >= CFG_MAX_TMR)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
if( (TmrIDVessel & (1<<tmrID)) == 0)
|
||||
{
|
||||
return E_INVALID_ID;
|
||||
}
|
||||
#endif
|
||||
TmrTbl[tmrID].tmrCnt = tmrCnt; /* Reset timer counter and reload value */
|
||||
TmrTbl[tmrID].tmrReload = tmrReload;
|
||||
|
||||
if(TmrTbl[tmrID].tmrState == TMR_STATE_RUNNING) /* Is timer running? */
|
||||
{
|
||||
RemoveTmrList(tmrID); /* Yes,reorder timer in timer list */
|
||||
InsertTmrList(tmrID);
|
||||
}
|
||||
return E_OK; /* Return OK */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Timer counter dispose
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to dispose timer counter.
|
||||
*******************************************************************************
|
||||
*/
|
||||
void TmrDispose(void)
|
||||
{
|
||||
P_TmrCtrl pTmr;
|
||||
|
||||
pTmr = TmrList; /* Get first item of timer list */
|
||||
while((pTmr != Co_NULL) && (pTmr->tmrCnt == 0) )
|
||||
{
|
||||
if(pTmr->tmrType == TMR_TYPE_ONE_SHOT) /* Is a One-shot timer? */
|
||||
{
|
||||
/* Yes,remove this timer from timer list */
|
||||
RemoveTmrList(pTmr->tmrID);
|
||||
|
||||
/* Set timer status as TMR_STATE_STOPPED */
|
||||
pTmr->tmrState = TMR_STATE_STOPPED;
|
||||
(pTmr->tmrCallBack)(); /* Call timer callback function */
|
||||
}
|
||||
else if(pTmr->tmrType == TMR_TYPE_PERIODIC) /* Is a periodic timer? */
|
||||
{
|
||||
/* Yes,remove this timer from timer list */
|
||||
RemoveTmrList(pTmr->tmrID);
|
||||
pTmr->tmrCnt = pTmr->tmrReload; /* Reset timer tick */
|
||||
InsertTmrList(pTmr->tmrID); /* Insert timer into timer list */
|
||||
(pTmr->tmrCallBack)(); /* Call timer callback function */
|
||||
}
|
||||
pTmr = TmrList; /* Get first item of timer list */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Timer counter dispose in ISR
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to dispose timer counter.
|
||||
*******************************************************************************
|
||||
*/
|
||||
void isr_TmrDispose(void)
|
||||
{
|
||||
if(OSSchedLock > 1) /* Is schedule lock? */
|
||||
{
|
||||
IsrReq = Co_TRUE;
|
||||
TimerReq = Co_TRUE; /* Yes,set timer request true */
|
||||
}
|
||||
else
|
||||
{
|
||||
TmrDispose(); /* No,call handler */
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file utility.c
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Utility management implementation code of CooCox CoOS kernel.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------- Include ---------------------------------------*/
|
||||
#include <coocox.h>
|
||||
|
||||
#if CFG_UTILITY_EN > 0
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Convert tick number to time
|
||||
* @param[in] ticks Specifies the systerm tick numbers that will be converted.
|
||||
* @param[out] hour Hours which converted.
|
||||
* @param[out] minute minutes which converted.
|
||||
* @param[out] sec seconds which converted.
|
||||
* @param[out] millsec millseconds which converted.
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to convert specify ticks to time format.
|
||||
*******************************************************************************
|
||||
*/
|
||||
#if CFG_TICK_TO_TIME_EN > 0
|
||||
void CoTickToTime(U32 ticks,U8* hour,U8* minute,U8* sec,U16* millsec)
|
||||
{
|
||||
U32 totalTime;
|
||||
|
||||
/* Convert ticks to time*/
|
||||
totalTime = ticks * (1000/CFG_SYSTICK_FREQ);
|
||||
*millsec = totalTime%1000;
|
||||
totalTime = totalTime/1000;
|
||||
*sec = totalTime%60;
|
||||
totalTime = totalTime/60;
|
||||
*minute = totalTime%60;
|
||||
totalTime = totalTime/60;
|
||||
*hour = totalTime;
|
||||
}
|
||||
#endif /* CFG_TICK_TO_TIME_EN */
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief Convert time to tick
|
||||
* @param[in] hour Specifies the number of hours.
|
||||
* @param[in] minute Specifies the number of minutes.
|
||||
* @param[in] sec Specifies the number of seconds.
|
||||
* @param[in] millsec Specifies the number of millseconds.
|
||||
* @param[out] ticks Tick numbers that converted.
|
||||
* @retval E_INVALID_PARAMETER Invalid parameter be passed and convert fail.
|
||||
* @retval E_OK Convert successful.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to convert specify time to tick number.
|
||||
*******************************************************************************
|
||||
*/
|
||||
#if CFG_TIME_TO_TICK_EN > 0
|
||||
StatusType CoTimeToTick(U8 hour,U8 minute,U8 sec,U16 millsec,U32* ticks)
|
||||
{
|
||||
#if CFG_PAR_CHECKOUT_EN >0
|
||||
/* Validate arguments to be within range */
|
||||
if((minute > 59)||(sec > 59)||(millsec > 999))
|
||||
return E_INVALID_PARAMETER;
|
||||
#endif
|
||||
|
||||
/* Convert time to ticks */
|
||||
*ticks = ((hour*3600) + (minute*60) + (sec)) * (CFG_SYSTICK_FREQ)\
|
||||
+ (millsec*CFG_SYSTICK_FREQ + 500)/1000;
|
||||
return E_OK;
|
||||
}
|
||||
#endif /* CFG_TIME_TO_TICK_EN */
|
||||
|
||||
#endif /* CFG_UTILITY_EN */
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file utility.h
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Utility function header file
|
||||
* @details This file including some defines and declares related to utility
|
||||
* function.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _UTILITY_H
|
||||
#define _UTILITY_H
|
||||
|
||||
|
||||
/**
|
||||
* @struct Time struct utility.h
|
||||
* @brief Time struct
|
||||
* @details This struct use to manage time
|
||||
*/
|
||||
typedef struct SysTime
|
||||
{
|
||||
U8 sec; /*!< Second */
|
||||
U8 min; /*!< Minute */
|
||||
U8 hour; /*!< Hour */
|
||||
U8 date; /*!< Date */
|
||||
U8 month; /*!< Month */
|
||||
U16 year; /*!< Year */
|
||||
}TIME;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,295 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file prot.c
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Compiler adapter for CooCox CoOS kernel.
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2010 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
/*---------------------------- Include ---------------------------------------*/
|
||||
#include "coocox.h"
|
||||
|
||||
|
||||
//******************************************************************************
|
||||
// EQUATES
|
||||
//******************************************************************************
|
||||
U32 NVIC_INT_CTRL = 0xE000ED04; // Interrupt control state register
|
||||
U32 NVIC_PENDSVSET = 0x10000000; // Value to trigger PendSV exception
|
||||
U32 INT_EXIT = 0xFFFFFFFC;
|
||||
|
||||
//******************************************************************************
|
||||
// PUBLIC FUNCTIONS
|
||||
//******************************************************************************
|
||||
extern U8 Inc8(volatile U8 *data) ;
|
||||
extern U8 Dec8(volatile U8 *data) ;
|
||||
extern void IRQ_ENABLE_RESTORE(void);
|
||||
extern void IRQ_DISABLE_SAVE(void);
|
||||
extern void SetEnvironment(OS_STK *pstk) __attribute__ ((naked));
|
||||
extern void SwitchContext(void) __attribute__ ((naked));
|
||||
extern void PendSV_Handler(void) __attribute__ ((naked));
|
||||
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @brief Plus a byte integers and Saved into memory cell
|
||||
* @param[in] data byte integers.
|
||||
* @param[out] None
|
||||
* @retval Returns Original value.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to Plus a byte integers
|
||||
* and Saved into memory cell.
|
||||
******************************************************************************
|
||||
*/
|
||||
U8 Inc8 (volatile U8 *data)
|
||||
{
|
||||
register U8 result = 0;
|
||||
|
||||
__asm volatile
|
||||
(
|
||||
" PUSH {R1} \n"
|
||||
" CPSID I \n"
|
||||
" LDRB R1,[%1] \n"
|
||||
" ADD R1,#1 \n"
|
||||
" STRB R1,[%1] \n"
|
||||
" CPSIE I \n"
|
||||
" SUB R1,#0x1 \n"
|
||||
" MOVS %0,R1 \n"
|
||||
" POP {R1} \n"
|
||||
:"=r"(result)
|
||||
:"r"(data)
|
||||
);
|
||||
return (result);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @brief Decrease a byte integers and Saved into memory cell
|
||||
* @param[in] data byte integers.
|
||||
* @param[out] None
|
||||
* @retval Returns Original value.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to Decrease a byte integers
|
||||
* and Saved into memory cell.
|
||||
******************************************************************************
|
||||
*/
|
||||
U8 Dec8 (volatile U8 *data)
|
||||
{
|
||||
register U8 result = 0;
|
||||
__asm volatile
|
||||
(
|
||||
" PUSH {R1} \n"
|
||||
" CPSID I \n"
|
||||
" LDRB R1,[%1] \n"
|
||||
" SUB R1,#1 \n"
|
||||
" STRB R1,[%1] \n"
|
||||
" CPSIE I \n"
|
||||
" MOVS %0,R1 \n"
|
||||
" POP {R1} \n"
|
||||
:"=r"(result)
|
||||
:"r"(data)
|
||||
);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @brief ENABLE Interrupt
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to ENABLE Interrupt.
|
||||
******************************************************************************
|
||||
*/
|
||||
void IRQ_ENABLE_RESTORE(void)
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" CPSIE I \n"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @brief Close Interrupt
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to close Interrupt.
|
||||
******************************************************************************
|
||||
*/
|
||||
void IRQ_DISABLE_SAVE(void)
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" CPSID I \n"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @brief Set environment for Coocox OS running
|
||||
* @param[in] pstk stack pointer
|
||||
* @param[out] None
|
||||
* @retval None.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to Set environment
|
||||
* for Coocox OS running.
|
||||
******************************************************************************
|
||||
*/
|
||||
void SetEnvironment (OS_STK *pstk)
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" SUB R0,#28 \n"
|
||||
" MSR PSP,R0 \n"
|
||||
" BX LR \n"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @brief Do ready work to Switch Context for task change
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to Do ready work to
|
||||
* Switch Context for task change
|
||||
******************************************************************************
|
||||
*/
|
||||
void SwitchContext(void)
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" LDR R3,=NVIC_INT_CTRL \n"
|
||||
" LDR R3,[R3] \n"
|
||||
" LDR R2,=NVIC_PENDSVSET \n"
|
||||
" LDR R1,[R2] \n"
|
||||
" STR R1, [R3] \n"
|
||||
" BX LR \n"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @brief Switch Context for task change
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to Switch Context for task change.
|
||||
******************************************************************************
|
||||
*/
|
||||
#if CFG_CHIP_TYPE == 2
|
||||
void PendSV_Handler(void)
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" LDR R3,=TCBRunning \n"
|
||||
" LDR R1,[R3] \n" // R1 == running tcb
|
||||
" LDR R2,=TCBNext \n"
|
||||
" LDR R2,[R2] \n" // R2 == next tcb
|
||||
|
||||
" CMP R1,R2 \n"
|
||||
" BEQ exitPendSV \n"
|
||||
" MRS R0, PSP \n" // Get PSP point (can not use PUSH,in ISR,SP is MSP )
|
||||
|
||||
" SUB R0,R0,#32 \n"
|
||||
" STR R0,[R1] \n" // Save orig PSP
|
||||
// Store r4-r11,r0 -= regCnt * 4,r0 is new stack
|
||||
// top point (addr h->l r11,r10,...,r5,r4)
|
||||
" STMIA R0!,{R4-R7} \n" // Save old context (R4-R7)
|
||||
" MOV R4,R8 \n"
|
||||
" MOV R5,R9 \n"
|
||||
" MOV R6,R10 \n"
|
||||
" MOV R7,R11 \n"
|
||||
" STMIA R0!,{R4-R7} \n" // Save old context (R8-R11)
|
||||
|
||||
" popStk: \n"
|
||||
" STR R2, [R3] \n" // TCBRunning = TCBNext;
|
||||
" LDR R0, [R2] \n" // Get SP of task that be switch into.
|
||||
|
||||
" ADD R0,R0,#16 \n"
|
||||
" LDMIA R0!,{R4-R7} \n" // Restore new Context (R8-R11)
|
||||
" MOV R8,R4 \n"
|
||||
" MOV R9,R5 \n"
|
||||
" MOV R10,R6 \n"
|
||||
" MOV R11,R7 \n"
|
||||
" SUB R0,R0,#32 \n"
|
||||
" LDMIA R0!,{R4-R7} \n" // Restore new Context (R4-R7)
|
||||
" ADD R0,R0,#16 \n"
|
||||
" MSR PSP, R0 \n" // Mov new stack point to PSP
|
||||
|
||||
" exitPendSV: \n"
|
||||
" LDR R3,=OSSchedLock \n"
|
||||
" MOV R0, #0x0 \n"
|
||||
" STRB R0, [R3] \n"
|
||||
|
||||
" LDR R3,=INT_EXIT \n"
|
||||
" LDR R0, [R3] \n"
|
||||
" BX R0 \n" // Exit interrupt
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CFG_CHIP_TYPE == 1
|
||||
void PendSV_Handler(void)
|
||||
{
|
||||
////////debug block /////////////////////////
|
||||
__asm volatile
|
||||
(
|
||||
" LDR R3,=TCBRunning \n"
|
||||
" LDR R1,[R3] \n" // R1 == running tcb
|
||||
" LDR R2,=TCBNext \n"
|
||||
" LDR R2,[R2] \n" // R2 == next tcb
|
||||
|
||||
" CMP R1,R2 \n"
|
||||
" BEQ exitPendSV \n"
|
||||
|
||||
" MRS R0, PSP \n" // Get PSP point (can not use PUSH,in ISR,SP is MSP )
|
||||
" STMDB R0!,{R4-R11} \n" // Store r4-r11,r0 -= regCnt * 4,r0 is new stack
|
||||
// top point (addr h->l r11,r10,...,r5,r4)
|
||||
" STR R0,[R1] \n" // Save orig PSP
|
||||
|
||||
" STR R2, [R3] \n" // TCBRunning = TCBNext;
|
||||
" LDR R0, [R2] \n" // Get SP of task that be switch into.
|
||||
" LDMIA R0!,{R4-R11} \n" // POP {R4-R11},R0 += regCnt * 4
|
||||
" MSR PSP, R0 \n" // Mov new stack point to PSP
|
||||
|
||||
|
||||
" exitPendSV: \n"
|
||||
" LDR R3,=OSSchedLock\n"
|
||||
" MOVS R0, #0x0 \n"
|
||||
" STRB R0, [R3] \n"
|
||||
" ORR LR,LR,#0x04 \n" // Ensure exception return uses process stack
|
||||
" BX LR \n" // Exit interrupt
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file OsArch.h
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief Implement function declare related to Cortex-M3(ARM-v7)
|
||||
* @details This header file including functions or defines related to
|
||||
* Cortex-M3(ARM-v7).
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
*
|
||||
* INTERNAL FILE,DON'T PUBLIC.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _CPU_H
|
||||
#define _CPU_H
|
||||
|
||||
|
||||
#define NVIC_ST_CTRL (*((volatile U32 *)0xE000E010))
|
||||
#define NVIC_ST_RELOAD (*((volatile U32 *)0xE000E014))
|
||||
#define RELOAD_VAL ((U32)(( (U32)CFG_CPU_FREQ) / (U32)CFG_SYSTICK_FREQ) -1)
|
||||
|
||||
/*!< Initial System tick. */
|
||||
#define InitSysTick() NVIC_ST_RELOAD = RELOAD_VAL; \
|
||||
NVIC_ST_CTRL = 0x0007
|
||||
|
||||
#define NVIC_SYS_PRI2 (*((volatile U32 *)0xE000ED1C))
|
||||
#define NVIC_SYS_PRI3 (*((volatile U32 *)0xE000ED20))
|
||||
|
||||
/*!< Initialize PendSV,SVC and SysTick interrupt priority to lowest. */
|
||||
#define InitInt() NVIC_SYS_PRI2 |= 0xFF000000;\
|
||||
NVIC_SYS_PRI3 |= 0xFFFF0000
|
||||
|
||||
|
||||
/*---------------------------- Variable declare ------------------------------*/
|
||||
extern U64 OSTickCnt; /*!< Counter for current system ticks. */
|
||||
|
||||
/*!< Initial context of task being created */
|
||||
extern OS_STK *InitTaskContext(FUNCPtr task,void *param,OS_STK *pstk);
|
||||
extern void SwitchContext(void); /*!< Switch context */
|
||||
extern void SetEnvironment(OS_STK *pstk);/*!< Set environment for run */
|
||||
extern U8 Inc8 (volatile U8 *data);
|
||||
extern U8 Dec8 (volatile U8 *data);
|
||||
extern void IRQ_ENABLE_RESTORE(void);
|
||||
extern void IRQ_DISABLE_SAVE(void);
|
||||
#endif
|
||||
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file arch.c
|
||||
* @version V1.1.4
|
||||
* @date 2011.04.20
|
||||
* @brief This file provides InitTaskContext() and SysTick_Handler().
|
||||
*******************************************************************************
|
||||
* @copy
|
||||
* WRITE COPY INFORMATION USE CAPITAL LETTER
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2009 CooCox </center></h2>
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
/*---------------------------- Include ---------------------------------------*/
|
||||
#include <coocox.h>
|
||||
U64 OSTickCnt = 0; /*!< Current system tick counter */
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @brief Initial task context
|
||||
* @param[in] task Entry point of task.
|
||||
* @param[in] param The parameter pass to task.
|
||||
* @param[in] pstk The pointer to stack top.
|
||||
* @param[out] None
|
||||
* @retval Returns location of new stack top.
|
||||
*
|
||||
* @par Description
|
||||
* @details This function is called to initialize the stack frame of the
|
||||
* task being created.
|
||||
******************************************************************************
|
||||
*/
|
||||
OS_STK *InitTaskContext(FUNCPtr task,void *param,OS_STK *pstk)
|
||||
{
|
||||
OS_STK *context;
|
||||
context = pstk;
|
||||
*(context--) = (U32)0x01000000L; /* xPSR */
|
||||
*(context--) = (U32)task; /* Entry point of task. */
|
||||
*(context) = (U32)0xFFFFFFFEL;
|
||||
context = context - 5;
|
||||
*(context) = (U32)param; /* R0: argument */
|
||||
context = context - 8;
|
||||
|
||||
return (context); /* Returns location of new stack top. */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @brief System tick interrupt handler.
|
||||
* @param[in] None
|
||||
* @param[out] None
|
||||
* @retval None
|
||||
*
|
||||
* @par Description
|
||||
* @details This is system tick interrupt headler.
|
||||
* @note CoOS may schedule when exiting this ISR.
|
||||
*******************************************************************************
|
||||
*/
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
OSSchedLock++; /* Lock scheduler. */
|
||||
OSTickCnt++; /* Increment systerm time. */
|
||||
#if CFG_TASK_WAITTING_EN >0
|
||||
if(DlyList != Co_NULL) /* Have task in delay list? */
|
||||
{
|
||||
if(DlyList->delayTick > 1) /* Delay time > 1? */
|
||||
{
|
||||
DlyList->delayTick--; /* Decrease delay time of the list head. */
|
||||
}
|
||||
else
|
||||
{
|
||||
DlyList->delayTick = 0;
|
||||
isr_TimeDispose(); /* Call hander for delay time list */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CFG_TMR_EN > 0
|
||||
if(TmrList != Co_NULL) /* Have timer in working? */
|
||||
{
|
||||
if(TmrList->tmrCnt > 1) /* Timer time > 1? */
|
||||
{
|
||||
TmrList->tmrCnt--; /* Decrease timer time of the list head. */
|
||||
}
|
||||
else
|
||||
{
|
||||
TmrList->tmrCnt = 0;
|
||||
isr_TmrDispose(); /* Call hander for timer list */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
TaskSchedReq = Co_TRUE;
|
||||
OsSchedUnlock();
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
FatFs Module Source Files R0.09 (C)ChaN, 2011
|
||||
|
||||
|
||||
FILES
|
||||
|
||||
ffconf.h Configuration file for FatFs module.
|
||||
ff.h Common include file for FatFs and application module.
|
||||
ff.c FatFs module.
|
||||
diskio.h Common include file for FatFs and disk I/O module.
|
||||
integer.h Alternative type definitions for integer variables.
|
||||
option Optional external functions.
|
||||
|
||||
Low level disk I/O module is not included in this archive because the FatFs
|
||||
module is only a generic file system layer and not depend on any specific
|
||||
storage device. You have to provide a low level disk I/O module that written
|
||||
to control your storage device.
|
||||
|
||||
|
||||
|
||||
AGREEMENTS
|
||||
|
||||
FatFs module is an open source software to implement FAT file system to
|
||||
small embedded systems. This is a free software and is opened for education,
|
||||
research and commercial developments under license policy of following trems.
|
||||
|
||||
Copyright (C) 2011, ChaN, all right reserved.
|
||||
|
||||
* The FatFs module is a free software and there is NO WARRANTY.
|
||||
* No restriction on use. You can use, modify and redistribute it for
|
||||
personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
|
||||
* Redistributions of source code must retain the above copyright notice.
|
||||
|
||||
|
||||
|
||||
REVISION HISTORY
|
||||
|
||||
Feb 26, 2006 R0.00 Prototype
|
||||
|
||||
Apr 29, 2006 R0.01 First release.
|
||||
|
||||
Jun 01, 2006 R0.02 Added FAT12.
|
||||
Removed unbuffered mode.
|
||||
Fixed a problem on small (<32M) patition.
|
||||
|
||||
Jun 10, 2006 R0.02a Added a configuration option _FS_MINIMUM.
|
||||
|
||||
Sep 22, 2006 R0.03 Added f_rename.
|
||||
Changed option _FS_MINIMUM to _FS_MINIMIZE.
|
||||
|
||||
Dec 11, 2006 R0.03a Improved cluster scan algolithm to write files fast.
|
||||
Fixed f_mkdir creates incorrect directory on FAT32.
|
||||
|
||||
Feb 04, 2007 R0.04 Supported multiple drive system. (FatFs)
|
||||
Changed some APIs for multiple drive system.
|
||||
Added f_mkfs. (FatFs)
|
||||
Added _USE_FAT32 option. (Tiny-FatFs)
|
||||
|
||||
Apr 01, 2007 R0.04a Supported multiple partitions on a plysical drive. (FatFs)
|
||||
Fixed an endian sensitive code in f_mkfs. (FatFs)
|
||||
Added a capability of extending the file size to f_lseek.
|
||||
Added minimization level 3.
|
||||
Fixed a problem that can collapse a sector when recreate an
|
||||
existing file in any sub-directory at non FAT32 cfg. (Tiny-FatFs)
|
||||
|
||||
May 05, 2007 R0.04b Added _USE_NTFLAG option.
|
||||
Added FSInfo support.
|
||||
Fixed some problems corresponds to FAT32. (Tiny-FatFs)
|
||||
Fixed DBCS name can result FR_INVALID_NAME.
|
||||
Fixed short seek (0 < ofs <= csize) collapses the file object.
|
||||
|
||||
Aug 25, 2007 R0.05 Changed arguments of f_read, f_write.
|
||||
Changed arguments of f_mkfs. (FatFs)
|
||||
Fixed f_mkfs on FAT32 creates incorrect FSInfo. (FatFs)
|
||||
Fixed f_mkdir on FAT32 creates incorrect directory. (FatFs)
|
||||
|
||||
Feb 03, 2008 R0.05a Added f_truncate().
|
||||
Added f_utime().
|
||||
Fixed off by one error at FAT sub-type determination.
|
||||
Fixed btr in f_read() can be mistruncated.
|
||||
Fixed cached sector is not flushed when create and close without write.
|
||||
|
||||
Apr 01, 2008 R0.06 Added f_forward(). (Tiny-FatFs)
|
||||
Added string functions: fputc(), fputs(), fprintf() and fgets().
|
||||
Improved performance of f_lseek() on move to the same or following cluster.
|
||||
|
||||
Apr 01, 2009, R0.07 Merged Tiny-FatFs as a buffer configuration option.
|
||||
Added long file name support.
|
||||
Added multiple code page support.
|
||||
Added re-entrancy for multitask operation.
|
||||
Added auto cluster size selection to f_mkfs().
|
||||
Added rewind option to f_readdir().
|
||||
Changed result code of critical errors.
|
||||
Renamed string functions to avoid name collision.
|
||||
|
||||
Apr 14, 2009, R0.07a Separated out OS dependent code on reentrant cfg.
|
||||
Added multiple sector size support.
|
||||
|
||||
Jun 21, 2009, R0.07c Fixed f_unlink() may return FR_OK on error.
|
||||
Fixed wrong cache control in f_lseek().
|
||||
Added relative path feature.
|
||||
Added f_chdir().
|
||||
Added f_chdrive().
|
||||
Added proper case conversion for extended characters.
|
||||
|
||||
Nov 03, 2009 R0.07e Separated out configuration options from ff.h to ffconf.h.
|
||||
Added a configuration option, _LFN_UNICODE.
|
||||
Fixed f_unlink() fails to remove a sub-dir on _FS_RPATH.
|
||||
Fixed name matching error on the 13 char boundary.
|
||||
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||
|
||||
May 15, 2010, R0.08 Added a memory configuration option. (_USE_LFN)
|
||||
Added file lock feature. (_FS_SHARE)
|
||||
Added fast seek feature. (_USE_FASTSEEK)
|
||||
Changed some types on the API, XCHAR->TCHAR.
|
||||
Changed fname member in the FILINFO structure on Unicode cfg.
|
||||
String functions support UTF-8 encoding files on Unicode cfg.
|
||||
|
||||
Aug 16,'10 R0.08a Added f_getcwd(). (_FS_RPATH = 2)
|
||||
Added sector erase feature. (_USE_ERASE)
|
||||
Moved file lock semaphore table from fs object to the bss.
|
||||
Fixed a wrong directory entry is created on non-LFN cfg when the given name contains ';'.
|
||||
Fixed f_mkfs() creates wrong FAT32 volume.
|
||||
|
||||
Jan 15,'11 R0.08b Fast seek feature is also applied to f_read() and f_write().
|
||||
f_lseek() reports required table size on creating CLMP.
|
||||
Extended format syntax of f_printf function.
|
||||
Ignores duplicated directory separators in given path names.
|
||||
|
||||
Sep 06,'11 R0.09 f_mkfs() supports multiple partition to finish the multiple partition feature.
|
||||
Added f_fdisk(). (_MULTI_PARTITION = 2)
|
||||
@@ -1,53 +1,14 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny <shadow@privy.de>
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* open9x is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
/ Low level disk interface modlue include file (C)ChaN, 2010
|
||||
/ Low level disk interface modlue include file
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef DEF_DISKIO
|
||||
#define DEF_DISKIO
|
||||
#ifndef _DISKIO
|
||||
|
||||
#define _READONLY 0 /* 1: Remove write functions */
|
||||
#define _USE_IOCTL 1 /* 1: Use disk_ioctl fucntion */
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
#define DN_MCI 0 /* Physical drive number for MCI */
|
||||
#define DN_NAND 1 /* Physical drive number for NAND flash */
|
||||
|
||||
|
||||
/* These functions are defined in asmfunc.S */
|
||||
void Copy_al2un (BYTE *dst, const DWORD *src, int count); /* Copy aligned to unaligned. */
|
||||
void Copy_un2al (DWORD *dst, const BYTE *src, int count); /* Copy unaligned to aligned. */
|
||||
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
@@ -65,12 +26,22 @@ typedef enum {
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int assign_drives (int, int);
|
||||
DSTATUS disk_initialize (BYTE);
|
||||
DSTATUS disk_status (BYTE);
|
||||
DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);
|
||||
#if _READONLY == 0
|
||||
DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);
|
||||
DRESULT disk_ioctl (BYTE, BYTE, BYTE*);
|
||||
void disk_timerproc (void);
|
||||
#endif
|
||||
DRESULT disk_ioctl (BYTE, BYTE, void*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
@@ -82,14 +53,14 @@ void disk_timerproc (void);
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic ioctl command (defined for FatFs) */
|
||||
/* Generic command (defined for FatFs) */
|
||||
#define CTRL_SYNC 0 /* Flush disk cache (for write functions) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (for only f_mkfs()) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (for only f_mkfs()) */
|
||||
#define CTRL_ERASE_SECTOR 4 /* Force erased a block of sectors (for only _USE_ERASE) */
|
||||
|
||||
/* Generic ioctl command */
|
||||
/* Generic command */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
@@ -110,6 +81,5 @@ void disk_timerproc (void);
|
||||
#define NAND_FORMAT 30 /* Create physical format */
|
||||
|
||||
|
||||
volatile extern BYTE Timer1, Timer2; /* 100Hz decrement timer */
|
||||
|
||||
#define _DISKIO
|
||||
#endif
|
||||
@@ -1,42 +1,53 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny <shadow@privy.de>
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* open9x is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
void init_SDcard()
|
||||
{
|
||||
#ifndef SIMU
|
||||
configure_pins( 0xFC000000, PIN_PERIPHERAL | PIN_INPUT | PIN_PER_C | PIN_PORTA | PIN_NO_PULLUP ) ;
|
||||
configure_pins( PIO_PB7, PIN_INPUT | PIN_PORTB | PIN_NO_PULLUP | PIN_NO_PULLDOWN ) ;
|
||||
SD_Init() ;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "integer.h"
|
||||
#include "../rtc.h"
|
||||
|
||||
DWORD get_fattime(void)
|
||||
{
|
||||
struct gtm t;
|
||||
|
||||
gettime(&t);
|
||||
|
||||
/* Pack date and time into a DWORD variable */
|
||||
return ((DWORD)(t.tm_year - 80) << 25)
|
||||
| ((uint32_t)(t.tm_mon+1) << 21)
|
||||
| ((uint32_t)t.tm_mday << 16)
|
||||
| ((uint32_t)t.tm_hour << 11)
|
||||
| ((uint32_t)t.tm_min << 5)
|
||||
| ((uint32_t)t.tm_sec >> 1);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
+337
@@ -0,0 +1,337 @@
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module include file R0.09 (C)ChaN, 2011
|
||||
/----------------------------------------------------------------------------/
|
||||
/ FatFs module is a generic FAT file system module for small embedded systems.
|
||||
/ This is a free software that opened for education, research and commercial
|
||||
/ developments under license policy of following trems.
|
||||
/
|
||||
/ Copyright (C) 2011, ChaN, all right reserved.
|
||||
/
|
||||
/ * The FatFs module is a free software and there is NO WARRANTY.
|
||||
/ * No restriction on use. You can use, modify and redistribute it for
|
||||
/ personal, non-profit or commercial product UNDER YOUR RESPONSIBILITY.
|
||||
/ * Redistributions of source code must retain the above copyright notice.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _FATFS
|
||||
#define _FATFS 6502 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if _FATFS != _FFCONF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive number */
|
||||
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition index */
|
||||
|
||||
#else /* Single partition configuration */
|
||||
#define LD2PD(vol) (vol) /* Each logical drive is bound to the same physical drive number */
|
||||
#define LD2PT(vol) 0 /* Always mounts the 1st partition or in SFD */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#if _LFN_UNICODE /* Unicode string */
|
||||
#if !_USE_LFN
|
||||
#error _LFN_UNICODE must be 0 in non-LFN cfg.
|
||||
#endif
|
||||
#ifndef _INC_TCHAR
|
||||
typedef WCHAR TCHAR;
|
||||
#define _T(x) L ## x
|
||||
#define _TEXT(x) L ## x
|
||||
#endif
|
||||
|
||||
#else /* ANSI/OEM string */
|
||||
#ifndef _INC_TCHAR
|
||||
typedef char TCHAR;
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* File system object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
|
||||
BYTE drv; /* Physical drive number */
|
||||
BYTE csize; /* Sectors per cluster (1,2,4...128) */
|
||||
BYTE n_fats; /* Number of FAT copies (1,2) */
|
||||
BYTE wflag; /* win[] dirty flag (1:must be written back) */
|
||||
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
|
||||
WORD id; /* File system mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
#if _MAX_SS != 512
|
||||
WORD ssize; /* Bytes per sector (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if _FS_REENTRANT
|
||||
_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !_FS_READONLY
|
||||
DWORD last_clust; /* Last allocated cluster */
|
||||
DWORD free_clust; /* Number of free clusters */
|
||||
DWORD fsi_sector; /* fsinfo sector (FAT32) */
|
||||
#endif
|
||||
#if _FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#endif
|
||||
DWORD n_fatent; /* Number of FAT entries (= number of clusters + 2) */
|
||||
DWORD fsize; /* Sectors per FAT */
|
||||
DWORD fatbase; /* FAT start sector */
|
||||
DWORD dirbase; /* Root directory start sector (FAT32:Cluster#) */
|
||||
DWORD database; /* Data start sector */
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
WORD id; /* Owner file system mount ID */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE pad1;
|
||||
DWORD fptr; /* File read/write pointer (0 on file open) */
|
||||
DWORD fsize; /* File size */
|
||||
DWORD sclust; /* File start cluster (0 when fsize==0) */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD dsect; /* Current data sector */
|
||||
#if !_FS_READONLY
|
||||
DWORD dir_sect; /* Sector containing the directory entry */
|
||||
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
|
||||
#endif
|
||||
#if _USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (null on file open) */
|
||||
#endif
|
||||
#if _FS_SHARE
|
||||
UINT lockid; /* File lock ID (index of file semaphore table) */
|
||||
#endif
|
||||
#if !_FS_TINY
|
||||
BYTE buf[_MAX_SS]; /* File data read/write buffer */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the owner file system object */
|
||||
WORD id; /* Owner file system mount ID */
|
||||
WORD index; /* Current read/write index number */
|
||||
DWORD sclust; /* Table start cluster (0:Root dir) */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector */
|
||||
BYTE* dir; /* Pointer to the current SFN entry in the win[] */
|
||||
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
|
||||
#if _USE_LFN
|
||||
WCHAR* lfn; /* Pointer to the LFN working buffer */
|
||||
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File status structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
DWORD fsize; /* File size */
|
||||
WORD fdate; /* Last modified date */
|
||||
WORD ftime; /* Last modified time */
|
||||
BYTE fattrib; /* Attribute */
|
||||
TCHAR fname[13]; /* Short file name (8.3 format) */
|
||||
#if _USE_LFN
|
||||
TCHAR* lfname; /* Pointer to the LFN buffer */
|
||||
UINT lfsize; /* Size of LFN buffer in TCHAR */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* (0) Succeeded */
|
||||
FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */
|
||||
FR_INT_ERR, /* (2) Assertion failed */
|
||||
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||
FR_NO_FILE, /* (4) Could not find the file */
|
||||
FR_NO_PATH, /* (5) Could not find the path */
|
||||
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||
FR_DENIED, /* (7) Acces denied due to prohibited access or directory full */
|
||||
FR_EXIST, /* (8) Acces denied due to prohibited access */
|
||||
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
||||
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any parameter error */
|
||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file shareing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_SHARE */
|
||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_open (FIL*, const TCHAR*, BYTE); /* Open or create a file */
|
||||
FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */
|
||||
FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
|
||||
FRESULT f_close (FIL*); /* Close an open file object */
|
||||
FRESULT f_opendir (DIR*, const TCHAR*); /* Open an existing directory */
|
||||
FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */
|
||||
FRESULT f_stat (const TCHAR*, FILINFO*); /* Get file status */
|
||||
FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */
|
||||
FRESULT f_getfree (const TCHAR*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
|
||||
FRESULT f_truncate (FIL*); /* Truncate file */
|
||||
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
|
||||
FRESULT f_unlink (const TCHAR*); /* Delete an existing file or directory */
|
||||
FRESULT f_mkdir (const TCHAR*); /* Create a new directory */
|
||||
FRESULT f_chmod (const TCHAR*, BYTE, BYTE); /* Change attriburte of the file/dir */
|
||||
FRESULT f_utime (const TCHAR*, const FILINFO*); /* Change timestamp of the file/dir */
|
||||
FRESULT f_rename (const TCHAR*, const TCHAR*); /* Rename/Move a file or directory */
|
||||
FRESULT f_chdrive (BYTE); /* Change current drive */
|
||||
FRESULT f_chdir (const TCHAR*); /* Change current directory */
|
||||
FRESULT f_getcwd (TCHAR*, UINT); /* Get current directory */
|
||||
FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */
|
||||
FRESULT f_mkfs (BYTE, BYTE, UINT); /* Create a file system on the drive */
|
||||
FRESULT f_fdisk (BYTE, const DWORD[], void*); /* Divide a physical drive into some partitions */
|
||||
int f_putc (TCHAR, FIL*); /* Put a character to the file */
|
||||
int f_puts (const TCHAR*, FIL*); /* Put a string to the file */
|
||||
int f_printf (FIL*, const TCHAR*, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the file */
|
||||
|
||||
#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
|
||||
#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->fsize)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !_FS_READONLY
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* Unicode support functions */
|
||||
#if _USE_LFN /* Unicode - OEM code conversion */
|
||||
WCHAR ff_convert (WCHAR, UINT); /* OEM-Unicode bidirectional conversion */
|
||||
WCHAR ff_wtoupper (WCHAR); /* Unicode upper-case conversion */
|
||||
#if _USE_LFN == 3 /* Memory functions */
|
||||
void* ff_memalloc (UINT); /* Allocate memory block */
|
||||
void ff_memfree (void*); /* Free memory block */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if _FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE, _SYNC_t*);/* Create a sync object */
|
||||
int ff_req_grant (_SYNC_t); /* Lock sync object */
|
||||
void ff_rel_grant (_SYNC_t); /* Unlock sync object */
|
||||
int ff_del_syncobj (_SYNC_t); /* Delete a sync object */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access control and file status flags (FIL.flag) */
|
||||
|
||||
#define FA_READ 0x01
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#define FA__ERROR 0x80
|
||||
|
||||
#if !_FS_READONLY
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA__WRITTEN 0x20
|
||||
#define FA__DIRTY 0x40
|
||||
#endif
|
||||
|
||||
|
||||
/* FAT sub type (FATFS.fs_type) */
|
||||
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
|
||||
|
||||
/* File attribute bits for directory entry */
|
||||
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_VOL 0x08 /* Volume label */
|
||||
#define AM_LFN 0x0F /* LFN entry */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
#define AM_MASK 0x3F /* Mask of defined bits */
|
||||
|
||||
|
||||
/* Fast seek feature */
|
||||
#define CREATE_LINKMAP 0xFFFFFFFF
|
||||
|
||||
|
||||
|
||||
/*--------------------------------*/
|
||||
/* Multi-byte word access macros */
|
||||
|
||||
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
|
||||
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
|
||||
#else /* Use byte-by-byte access to the FAT structure */
|
||||
#define LD_WORD(ptr) (WORD)(((WORD)*((BYTE*)(ptr)+1)<<8)|(WORD)*(BYTE*)(ptr))
|
||||
#define LD_DWORD(ptr) (DWORD)(((DWORD)*((BYTE*)(ptr)+3)<<24)|((DWORD)*((BYTE*)(ptr)+2)<<16)|((WORD)*((BYTE*)(ptr)+1)<<8)|*(BYTE*)(ptr))
|
||||
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)
|
||||
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FATFS */
|
||||
@@ -1,38 +1,5 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny <shadow@privy.de>
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* open9x is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module configuration file R0.08a (C)ChaN, 2010
|
||||
/ FatFs - FAT file system module configuration file R0.09 (C)ChaN, 2011
|
||||
/----------------------------------------------------------------------------/
|
||||
/
|
||||
/ CAUTION! Do not forget to make clean the project after any changes to
|
||||
@@ -40,14 +7,23 @@
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
#ifndef _FFCONF
|
||||
#define _FFCONF 8255 /* Revision ID */
|
||||
#define _FFCONF 6502 /* Revision ID */
|
||||
|
||||
#if defined(CPUARM) && !defined(SIMU)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "../CoOS/kernel/CoOS.h"
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function and Buffer Configurations
|
||||
/ Functions and Buffer Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_TINY 1 /* 0:Normal or 1:Tiny */
|
||||
#define _FS_TINY 0 /* 0:Normal or 1:Tiny */
|
||||
/* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
|
||||
/ object instead of the sector buffer in the individual file object for file
|
||||
/ data transfer. This reduces memory consumption 512 bytes each file object. */
|
||||
@@ -69,11 +45,11 @@
|
||||
/ 3: f_lseek is removed in addition to 2. */
|
||||
|
||||
|
||||
#define _USE_STRFUNC 1 /* 0:Disable or 1/2:Enable */
|
||||
#define _USE_STRFUNC 1 /* 0:Disable or 1-2:Enable */
|
||||
/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
|
||||
|
||||
|
||||
#define _USE_MKFS 1 /* 0:Disable or 1:Enable */
|
||||
#define _USE_MKFS 1 /* 0:Disable or 1:Enable */
|
||||
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
|
||||
|
||||
|
||||
@@ -90,7 +66,7 @@
|
||||
/ Locale and Namespace Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _CODE_PAGE 932
|
||||
#define _CODE_PAGE 1252
|
||||
/* The _CODE_PAGE specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect setting of the code page can cause a file open failure.
|
||||
/
|
||||
@@ -122,9 +98,14 @@
|
||||
/ 1 - ASCII only (Valid for non LFN cfg.)
|
||||
*/
|
||||
|
||||
#if defined(CPUARM)
|
||||
#define _USE_LFN 2 /* 0 to 3 */
|
||||
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
|
||||
#else
|
||||
#define _USE_LFN 1 /* 0 to 3 */
|
||||
#define _MAX_LFN 32 /* Maximum LFN length to handle (12 to 255) */
|
||||
#endif
|
||||
|
||||
#define _USE_LFN 0 /* 0 to 3 */
|
||||
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
|
||||
/* The _USE_LFN option switches the LFN support.
|
||||
/
|
||||
/ 0: Disable LFN feature. _MAX_LFN and _LFN_UNICODE have no effect.
|
||||
@@ -143,7 +124,7 @@
|
||||
/ enable LFN feature and set _LFN_UNICODE to 1. */
|
||||
|
||||
|
||||
#define _FS_RPATH 2 /* 0 to 2 */
|
||||
#define _FS_RPATH 2 /* 0 to 2 */
|
||||
/* The _FS_RPATH option configures relative path feature.
|
||||
/
|
||||
/ 0: Disable relative path feature and remove related functions.
|
||||
@@ -165,19 +146,20 @@
|
||||
#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */
|
||||
/* Maximum sector size to be handled.
|
||||
/ Always set 512 for memory card and hard disk but a larger value may be
|
||||
/ required for floppy disk (512/1024) and optical disk (512/2048).
|
||||
/ When _MAX_SS is larger than 512, GET_SECTOR_SIZE command must be implememted
|
||||
/ to the disk_ioctl function. */
|
||||
/ required for on-board flash memory, floppy disk and optical disk.
|
||||
/ When _MAX_SS is larger than 512, it configures FatFs to variable sector size
|
||||
/ and GET_SECTOR_SIZE command must be implememted to the disk_ioctl function. */
|
||||
|
||||
|
||||
#define _MULTI_PARTITION 0 /* 0:Single partition or 1:Multiple partition */
|
||||
#define _MULTI_PARTITION 0 /* 0:Single partition, 1/2:Enable multiple partition */
|
||||
/* When set to 0, each volume is bound to the same physical drive number and
|
||||
/ it can mount only first primaly partition. When it is set to 1, each volume
|
||||
/ is tied to the partitions listed in VolToPart[]. */
|
||||
|
||||
|
||||
#define _USE_ERASE 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable sector erase feature, set _USE_ERASE to 1. */
|
||||
/* To enable sector erase feature, set _USE_ERASE to 1. CTRL_ERASE_SECTOR command
|
||||
/ should be added to the disk_ioctl functio. */
|
||||
|
||||
|
||||
|
||||
@@ -195,25 +177,30 @@
|
||||
/ When the byte order on the memory is big-endian or address miss-aligned word
|
||||
/ access results incorrect behavior, the _WORD_ACCESS must be set to 0.
|
||||
/ If it is not the case, the value can also be set to 1 to improve the
|
||||
/ performance and code size. */
|
||||
/ performance and code size.
|
||||
*/
|
||||
|
||||
|
||||
/* Include a header file here to define sync object types on the O/S */
|
||||
/* #include <windows.h>, <ucos_ii.h.h>, <semphr.h> or ohters. */
|
||||
/* A header file that defines sync object types on the O/S, such as
|
||||
/ windows.h, ucos_ii.h and semphr.h, must be included prior to ff.h. */
|
||||
|
||||
#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
|
||||
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
|
||||
#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
|
||||
#if defined(CPUARM)
|
||||
#define _FS_REENTRANT 1 /* 0:Disable or 1:Enable */
|
||||
#else
|
||||
#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
|
||||
#endif
|
||||
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
|
||||
#define _SYNC_t OS_MutexID /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
|
||||
|
||||
/* The _FS_REENTRANT option switches the reentrancy of the FatFs module.
|
||||
/* The _FS_REENTRANT option switches the reentrancy (thread safe) of the FatFs module.
|
||||
/
|
||||
/ 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect.
|
||||
/ 1: Enable reentrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj
|
||||
/ function must be added to the project. */
|
||||
|
||||
|
||||
#define _FS_SHARE 0 /* 0:Disable or >=1:Enable */
|
||||
|
||||
/* To enable file shareing feature, set _FS_SHARE to 1 or greater. The value
|
||||
defines how many files can be opened simultaneously. */
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*-------------------------------------------*/
|
||||
/* Integer type definitions for FatFs module */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
#ifndef _INTEGER
|
||||
#define _INTEGER
|
||||
|
||||
#ifdef _WIN32 /* FatFs development platform */
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#else /* Embedded platform */
|
||||
|
||||
/* These types must be 16-bit, 32-bit or larger integer */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* These types must be 8-bit integer */
|
||||
typedef char CHAR;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* These types must be 16-bit integer */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
|
||||
/* These types must be 32-bit integer */
|
||||
typedef long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,540 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Unicode - Local code bidirectional converter (C)ChaN, 2009 */
|
||||
/* (SBCS code pages) */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* 437 U.S. (OEM)
|
||||
/ 720 Arabic (OEM)
|
||||
/ 1256 Arabic (Windows)
|
||||
/ 737 Greek (OEM)
|
||||
/ 1253 Greek (Windows)
|
||||
/ 1250 Central Europe (Windows)
|
||||
/ 775 Baltic (OEM)
|
||||
/ 1257 Baltic (Windows)
|
||||
/ 850 Multilingual Latin 1 (OEM)
|
||||
/ 852 Latin 2 (OEM)
|
||||
/ 1252 Latin 1 (Windows)
|
||||
/ 855 Cyrillic (OEM)
|
||||
/ 1251 Cyrillic (Windows)
|
||||
/ 866 Russian (OEM)
|
||||
/ 857 Turkish (OEM)
|
||||
/ 1254 Turkish (Windows)
|
||||
/ 858 Multilingual Latin 1 + Euro (OEM)
|
||||
/ 862 Hebrew (OEM)
|
||||
/ 1255 Hebrew (Windows)
|
||||
/ 874 Thai (OEM, Windows)
|
||||
/ 1258 Vietnam (OEM, Windows)
|
||||
*/
|
||||
|
||||
#include "../ff.h"
|
||||
|
||||
|
||||
#if _CODE_PAGE == 437
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP437(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
|
||||
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 720
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP720(0x80-0xFF) to Unicode conversion table */
|
||||
0x0000, 0x0000, 0x00E9, 0x00E2, 0x0000, 0x00E0, 0x0000, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0651, 0x0652, 0x00F4, 0x00A4, 0x0640, 0x00FB, 0x00F9,
|
||||
0x0621, 0x0622, 0x0623, 0x0624, 0x00A3, 0x0625, 0x0626, 0x0627,
|
||||
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
|
||||
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x0636, 0x0637, 0x0638, 0x0639, 0x063A, 0x0641, 0x00B5, 0x0642,
|
||||
0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064A,
|
||||
0x2261, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, 0xO650, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 737
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP737(0x80-0xFF) to Unicode conversion table */
|
||||
0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
|
||||
0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0,
|
||||
0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9,
|
||||
0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8,
|
||||
0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0,
|
||||
0x03C1, 0x03C3, 0x03C2, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03C9, 0x03AC, 0x03AD, 0x03AE, 0x03CA, 0x03AF, 0x03CC, 0x03CD,
|
||||
0x03CB, 0x03CE, 0x0386, 0x0388, 0x0389, 0x038A, 0x038C, 0x038E,
|
||||
0x038F, 0x00B1, 0x2265, 0x2264, 0x03AA, 0x03AB, 0x00F7, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 775
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP775(0x80-0xFF) to Unicode conversion table */
|
||||
0x0106, 0x00FC, 0x00E9, 0x0101, 0x00E4, 0x0123, 0x00E5, 0x0107,
|
||||
0x0142, 0x0113, 0x0156, 0x0157, 0x012B, 0x0179, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x014D, 0x00F6, 0x0122, 0x00A2, 0x015A,
|
||||
0x015B, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x00A4,
|
||||
0x0100, 0x012A, 0x00F3, 0x017B, 0x017C, 0x017A, 0x201D, 0x00A6,
|
||||
0x00A9, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x0141, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010C, 0x0118,
|
||||
0x0116, 0x2563, 0x2551, 0x2557, 0x255D, 0x012E, 0x0160, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0172, 0x016A,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x017D,
|
||||
0x0105, 0x010D, 0x0119, 0x0117, 0x012F, 0x0161, 0x0173, 0x016B,
|
||||
0x017E, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x00D3, 0x00DF, 0x014C, 0x0143, 0x00F5, 0x00D5, 0x00B5, 0x0144,
|
||||
0x0136, 0x0137, 0x013B, 0x013C, 0x0146, 0x0112, 0x0145, 0x2019,
|
||||
0x00AD, 0x00B1, 0x201C, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x201E,
|
||||
0x00B0, 0x2219, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 850
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP850(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
|
||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
|
||||
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 852
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP852(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x016F, 0x0107, 0x00E7,
|
||||
0x0142, 0x00EB, 0x0150, 0x0151, 0x00EE, 0x0179, 0x00C4, 0x0106,
|
||||
0x00C9, 0x0139, 0x013A, 0x00F4, 0x00F6, 0x013D, 0x013E, 0x015A,
|
||||
0x015B, 0x00D6, 0x00DC, 0x0164, 0x0165, 0x0141, 0x00D7, 0x010D,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x0104, 0x0105, 0x017D, 0x017E,
|
||||
0x0118, 0x0119, 0x00AC, 0x017A, 0x010C, 0x015F, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x011A,
|
||||
0x015E, 0x2563, 0x2551, 0x2557, 0x255D, 0x017B, 0x017C, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x0102, 0x0103,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x0111, 0x0110, 0x010E, 0x00CB, 0x010F, 0x0147, 0x00CD, 0x00CE,
|
||||
0x011B, 0x2518, 0x250C, 0x2588, 0x2584, 0x0162, 0x016E, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161,
|
||||
0x0154, 0x00DA, 0x0155, 0x0170, 0x00FD, 0x00DD, 0x0163, 0x00B4,
|
||||
0x00AD, 0x02DD, 0x02DB, 0x02C7, 0x02D8, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x02D9, 0x0171, 0x0158, 0x0159, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 855
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP855(0x80-0xFF) to Unicode conversion table */
|
||||
0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404,
|
||||
0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408,
|
||||
0x0459, 0x0409, 0x045A, 0x040A, 0x045B, 0x040B, 0x045C, 0x040C,
|
||||
0x045E, 0x040E, 0x045F, 0x040F, 0x044E, 0x042E, 0x044A, 0x042A,
|
||||
0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414,
|
||||
0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438,
|
||||
0x0418, 0x2563, 0x2551, 0x2557, 0x255D, 0x0439, 0x0419, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x043A, 0x041A,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x043B, 0x041B, 0x043C, 0x041C, 0x043D, 0x041D, 0x043E, 0x041E,
|
||||
0x043F, 0x2518, 0x250C, 0x2588, 0x2584, 0x041F, 0x044F, 0x2580,
|
||||
0x042F, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443,
|
||||
0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044C, 0x042C, 0x2116,
|
||||
0x00AD, 0x044B, 0x042B, 0x0437, 0x0417, 0x0448, 0x0428, 0x044D,
|
||||
0x042D, 0x0449, 0x0429, 0x0447, 0x0427, 0x00A7, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 857
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP857(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x0131, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x0130, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x015E, 0x015F,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x011E, 0x011F,
|
||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00BA, 0x00AA, 0x00CA, 0x00CB, 0x00C8, 0x0000, 0x00CD, 0x00CE,
|
||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x0000,
|
||||
0x00D7, 0x00DA, 0x00DB, 0x00D9, 0x00EC, 0x00FF, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x0000, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 858
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP858(0x80-0xFF) to Unicode conversion table */
|
||||
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
||||
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
||||
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
||||
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
|
||||
0x00A9, 0x2563, 0x2551, 0x2557, 0x2550, 0x00A2, 0x00A5, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
|
||||
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x20AC, 0x00CD, 0x00CE,
|
||||
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00C6, 0x00CC, 0x2580,
|
||||
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
|
||||
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
|
||||
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
|
||||
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 862
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP862(0x80-0xFF) to Unicode conversion table */
|
||||
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
|
||||
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
||||
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
|
||||
0x05E8, 0x05E9, 0x05EA, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
||||
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
||||
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
|
||||
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
||||
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 866
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP866(0x80-0xFF) to Unicode conversion table */
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
|
||||
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
|
||||
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
|
||||
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
||||
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
||||
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
||||
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
||||
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
||||
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
|
||||
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
|
||||
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E,
|
||||
0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 874
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP874(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
|
||||
0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
|
||||
0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
|
||||
0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
|
||||
0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
|
||||
0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
|
||||
0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
|
||||
0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F,
|
||||
0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
|
||||
0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
|
||||
0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
|
||||
0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1250
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1250(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
|
||||
0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
|
||||
0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
|
||||
0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
|
||||
0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
|
||||
0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
|
||||
0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
|
||||
0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
|
||||
0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
|
||||
0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
|
||||
0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1251
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1251(0x80-0xFF) to Unicode conversion table */
|
||||
0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
|
||||
0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2111, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
|
||||
0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
|
||||
0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
|
||||
0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
|
||||
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
|
||||
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
|
||||
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
|
||||
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
|
||||
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
|
||||
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
|
||||
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
|
||||
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1252
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1252(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
|
||||
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1253
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1253(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x0000, 0x2030, 0x0000, 0x2039, 0x000C, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
|
||||
0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
|
||||
0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
|
||||
0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
|
||||
0x03A8, 0x03A9, 0x03AA, 0x03AD, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
|
||||
0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
|
||||
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
|
||||
0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
|
||||
0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1254
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1254(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x210A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
|
||||
0x00D8, 0x00D9, 0x00DA, 0x00BD, 0x00DC, 0x0130, 0x015E, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1255
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1255(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
|
||||
0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
|
||||
0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3,
|
||||
0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
|
||||
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
|
||||
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
|
||||
0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1256
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1256(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
|
||||
0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
|
||||
0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
|
||||
0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
|
||||
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
|
||||
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7,
|
||||
0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0640, 0x0642, 0x0643,
|
||||
0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
|
||||
0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7,
|
||||
0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2
|
||||
}
|
||||
|
||||
#elif _CODE_PAGE == 1257
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1257(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000,
|
||||
0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7,
|
||||
0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
|
||||
0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
|
||||
0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
|
||||
0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
|
||||
0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
|
||||
0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
|
||||
0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
|
||||
0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
|
||||
0x0173, 0x014E, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9
|
||||
};
|
||||
|
||||
#elif _CODE_PAGE == 1258
|
||||
#define _TBLDEF 1
|
||||
static
|
||||
const WCHAR Tbl[] = { /* CP1258(0x80-0xFF) to Unicode conversion table */
|
||||
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
|
||||
0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
|
||||
0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
|
||||
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
|
||||
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
||||
0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
|
||||
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
|
||||
0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7,
|
||||
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
|
||||
0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
|
||||
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7,
|
||||
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if !_TBLDEF || !_USE_LFN
|
||||
#error This file is not needed in current configuration. Remove from the project.
|
||||
#endif
|
||||
|
||||
|
||||
WCHAR ff_convert ( /* Converted character, Returns zero on error */
|
||||
WCHAR src, /* Character code to be converted */
|
||||
UINT dir /* 0: Unicode to OEMCP, 1: OEMCP to Unicode */
|
||||
)
|
||||
{
|
||||
WCHAR c;
|
||||
|
||||
|
||||
if (src < 0x80) { /* ASCII */
|
||||
c = src;
|
||||
|
||||
} else {
|
||||
if (dir) { /* OEMCP to Unicode */
|
||||
c = (src >= 0x100) ? 0 : Tbl[src - 0x80];
|
||||
|
||||
} else { /* Unicode to OEMCP */
|
||||
for (c = 0; c < 0x80; c++) {
|
||||
if (src == Tbl[c]) break;
|
||||
}
|
||||
c = (c + 0x80) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
WCHAR ff_wtoupper ( /* Upper converted character */
|
||||
WCHAR chr /* Input character */
|
||||
)
|
||||
{
|
||||
static const WCHAR tbl_lower[] = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xA1, 0x00A2, 0x00A3, 0x00A5, 0x00AC, 0x00AF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x0FF, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10B, 0x10D, 0x10F, 0x111, 0x113, 0x115, 0x117, 0x119, 0x11B, 0x11D, 0x11F, 0x121, 0x123, 0x125, 0x127, 0x129, 0x12B, 0x12D, 0x12F, 0x131, 0x133, 0x135, 0x137, 0x13A, 0x13C, 0x13E, 0x140, 0x142, 0x144, 0x146, 0x148, 0x14B, 0x14D, 0x14F, 0x151, 0x153, 0x155, 0x157, 0x159, 0x15B, 0x15D, 0x15F, 0x161, 0x163, 0x165, 0x167, 0x169, 0x16B, 0x16D, 0x16F, 0x171, 0x173, 0x175, 0x177, 0x17A, 0x17C, 0x17E, 0x192, 0x3B1, 0x3B2, 0x3B3, 0x3B4, 0x3B5, 0x3B6, 0x3B7, 0x3B8, 0x3B9, 0x3BA, 0x3BB, 0x3BC, 0x3BD, 0x3BE, 0x3BF, 0x3C0, 0x3C1, 0x3C3, 0x3C4, 0x3C5, 0x3C6, 0x3C7, 0x3C8, 0x3C9, 0x3CA, 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F, 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457, 0x458, 0x459, 0x45A, 0x45B, 0x45C, 0x45E, 0x45F, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217A, 0x217B, 0x217C, 0x217D, 0x217E, 0x217F, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0 };
|
||||
static const WCHAR tbl_upper[] = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x21, 0xFFE0, 0xFFE1, 0xFFE5, 0xFFE2, 0xFFE3, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0x178, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10A, 0x10C, 0x10E, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11A, 0x11C, 0x11E, 0x120, 0x122, 0x124, 0x126, 0x128, 0x12A, 0x12C, 0x12E, 0x130, 0x132, 0x134, 0x136, 0x139, 0x13B, 0x13D, 0x13F, 0x141, 0x143, 0x145, 0x147, 0x14A, 0x14C, 0x14E, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15A, 0x15C, 0x15E, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16A, 0x16C, 0x16E, 0x170, 0x172, 0x174, 0x176, 0x179, 0x17B, 0x17D, 0x191, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397, 0x398, 0x399, 0x39A, 0x39B, 0x39C, 0x39D, 0x39E, 0x39F, 0x3A0, 0x3A1, 0x3A3, 0x3A4, 0x3A5, 0x3A6, 0x3A7, 0x3A8, 0x3A9, 0x3AA, 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F, 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407, 0x408, 0x409, 0x40A, 0x40B, 0x40C, 0x40E, 0x40F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0x216C, 0x216D, 0x216E, 0x216F, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0 };
|
||||
int i;
|
||||
|
||||
|
||||
for (i = 0; tbl_lower[i] && chr != tbl_lower[i]; i++) ;
|
||||
|
||||
return tbl_lower[i] ? tbl_upper[i] : chr;
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Sample code of OS dependent controls for FatFs R0.08b */
|
||||
/* (C)ChaN, 2011 */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdlib.h> /* ANSI memory controls */
|
||||
#include <malloc.h> /* ANSI memory controls */
|
||||
|
||||
#include "../ff.h"
|
||||
|
||||
|
||||
#if _FS_REENTRANT
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Create a Synchronization Object
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount function to create a new
|
||||
/ synchronization object, such as semaphore and mutex. When a zero is
|
||||
/ returned, the f_mount function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_cre_syncobj ( /* TRUE:Function succeeded, FALSE:Could not create due to any error */
|
||||
BYTE vol, /* Corresponding logical drive being processed */
|
||||
_SYNC_t *sobj /* Pointer to return the created sync object */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
*sobj = CreateMutex(NULL, FALSE, NULL); /* Win32 */
|
||||
ret = (*sobj != INVALID_HANDLE_VALUE);
|
||||
|
||||
// *sobj = SyncObjects[vol]; /* uITRON (give a static sync object) */
|
||||
// ret = 1; /* The initial value of the semaphore must be 1. */
|
||||
|
||||
// *sobj = OSMutexCreate(0, &err); /* uC/OS-II */
|
||||
// ret = (err == OS_NO_ERR);
|
||||
|
||||
// *sobj = xSemaphoreCreateMutex(); /* FreeRTOS */
|
||||
// ret = (*sobj != NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Delete a Synchronization Object */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called in f_mount function to delete a synchronization
|
||||
/ object that created with ff_cre_syncobj function. When a zero is
|
||||
/ returned, the f_mount function fails with FR_INT_ERR.
|
||||
*/
|
||||
|
||||
int ff_del_syncobj ( /* TRUE:Function succeeded, FALSE:Could not delete due to any error */
|
||||
_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
||||
)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
ret = CloseHandle(sobj); /* Win32 */
|
||||
|
||||
// ret = 1; /* uITRON (nothing to do) */
|
||||
|
||||
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err); /* uC/OS-II */
|
||||
// ret = (err == OS_NO_ERR);
|
||||
|
||||
// ret = 1; /* FreeRTOS (nothing to do) */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Request Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on entering file functions to lock the volume.
|
||||
/ When a zero is returned, the file function fails with FR_TIMEOUT.
|
||||
*/
|
||||
|
||||
int ff_req_grant ( /* TRUE:Got a grant to access the volume, FALSE:Could not get a grant */
|
||||
_SYNC_t sobj /* Sync object to wait */
|
||||
)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = (WaitForSingleObject(sobj, _FS_TIMEOUT) == WAIT_OBJECT_0); /* Win32 */
|
||||
|
||||
// ret = (wai_sem(sobj) == E_OK); /* uITRON */
|
||||
|
||||
// OSMutexPend(sobj, _FS_TIMEOUT, &err)); /* uC/OS-II */
|
||||
// ret = (err == OS_NO_ERR);
|
||||
|
||||
// ret = (xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE); /* FreeRTOS */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Release Grant to Access the Volume */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* This function is called on leaving file functions to unlock the volume.
|
||||
*/
|
||||
|
||||
void ff_rel_grant (
|
||||
_SYNC_t sobj /* Sync object to be signaled */
|
||||
)
|
||||
{
|
||||
ReleaseMutex(sobj); /* Win32 */
|
||||
|
||||
// sig_sem(sobj); /* uITRON */
|
||||
|
||||
// OSMutexPost(sobj); /* uC/OS-II */
|
||||
|
||||
// xSemaphoreGive(sobj); /* FreeRTOS */
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#if _USE_LFN == 3 /* LFN with a working buffer on the heap */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Allocate a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE.
|
||||
*/
|
||||
|
||||
void* ff_memalloc ( /* Returns pointer to the allocated memory block */
|
||||
UINT size /* Number of bytes to allocate */
|
||||
)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Free a memory block */
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void ff_memfree(
|
||||
void* mblock /* Pointer to the memory block to free */
|
||||
)
|
||||
{
|
||||
free(mblock);
|
||||
}
|
||||
|
||||
#endif
|
||||
+720
-221
File diff suppressed because it is too large
Load Diff
+4
-4
@@ -1,5 +1,5 @@
|
||||
27,32,
|
||||
0xf0,0xfc,0xfc,0xfe,0xfe,0x7c,0x7c,0x78,0x78,0x70,0x70,0xe0,0xe0,0xc0,0xc0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0xff,0xff,0xff,0xff,0xfe,0xfc,0xf0,0xc0,0x00,0x00,0x80,0x87,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfc,0xf8,0xf8,0xf0,0xf0,0xe0,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf3,0xe1,0xe1,0xe1,0xe1,0xf3,0xff,0x7f,0x3f,0x3f,0x1f,0x0f,0x0f,0x07,0x03,0x03,0x01,0x00,
|
||||
0x07,0x1f,0x3f,0x3f,0x3f,0x3f,0x1f,0x1f,0x0f,0x07,0x07,0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0xfc,0x04,0x04,0x04,0x04,0x04,0x04,0x84,0xc4,0x84,0x04,0xe4,0xf4,0xe4,0x04,0x84,0xc4,0xc4,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0xfc,
|
||||
0xff,0x00,0x00,0x00,0xfc,0xfe,0x00,0xff,0xff,0xff,0x80,0xff,0xff,0xff,0x80,0xff,0xff,0xff,0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0xff,
|
||||
0xff,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0xfc,0xff,0x3f,0x0f,0x03,0x00,0x00,0xff,
|
||||
0x3f,0x20,0x20,0x20,0x21,0x27,0x27,0x2f,0x2f,0x2f,0x2b,0x27,0x2f,0x2f,0x2f,0x2f,0x2f,0x2f,0x27,0x23,0x20,0x20,0x20,0x20,0x20,0x20,0x3f,
|
||||
|
||||
+14
-14
@@ -1,14 +1,14 @@
|
||||
#define asterisk_width 27
|
||||
#define asterisk_height 32
|
||||
static unsigned char asterisk_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
|
||||
0xfe, 0x01, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00,
|
||||
0xff, 0x7f, 0x00, 0x00, 0x1f, 0xf8, 0x01, 0x00, 0x0f, 0xf8, 0x07, 0x00,
|
||||
0x1f, 0xf8, 0x1f, 0x00, 0x3f, 0xf8, 0x3f, 0x00, 0x3f, 0xf0, 0xff, 0x00,
|
||||
0x7f, 0xf0, 0xff, 0x03, 0x7f, 0xf0, 0xff, 0x07, 0xff, 0xf0, 0xff, 0x07,
|
||||
0xff, 0xfc, 0xff, 0x07, 0xff, 0xff, 0xff, 0x03, 0xff, 0xc3, 0xff, 0x01,
|
||||
0xff, 0x81, 0x7f, 0x00, 0xff, 0x81, 0x3f, 0x00, 0xff, 0xc3, 0x0f, 0x00,
|
||||
0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||
0xff, 0x3f, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00,
|
||||
0xfe, 0x01, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
#define asterisk_width 27
|
||||
#define asterisk_height 32
|
||||
static unsigned char asterisk_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x07,
|
||||
0x01, 0x00, 0x00, 0x04, 0x01, 0x10, 0x00, 0x04, 0x01, 0x38, 0x00, 0x04,
|
||||
0x01, 0x39, 0x03, 0x04, 0x81, 0xbb, 0x03, 0x04, 0x81, 0xbb, 0x03, 0x04,
|
||||
0xa1, 0xbb, 0x03, 0x04, 0xb1, 0xbb, 0x03, 0x04, 0xb1, 0xbb, 0x03, 0x04,
|
||||
0xb1, 0xbb, 0x03, 0x04, 0xb1, 0xbb, 0x03, 0x04, 0xb1, 0xbb, 0x03, 0x04,
|
||||
0xb1, 0xff, 0xe3, 0x04, 0xf1, 0xff, 0xf3, 0x04, 0xf1, 0xff, 0xf3, 0x04,
|
||||
0xf1, 0xff, 0x7b, 0x04, 0xf1, 0xff, 0x7f, 0x04, 0xf1, 0xff, 0x3f, 0x04,
|
||||
0xf1, 0xff, 0x3f, 0x04, 0xf1, 0xff, 0x1f, 0x04, 0xf1, 0xff, 0x1f, 0x04,
|
||||
0xf1, 0xff, 0x0f, 0x04, 0xe1, 0xff, 0x0f, 0x04, 0xe1, 0xfb, 0x07, 0x04,
|
||||
0x81, 0xf7, 0x03, 0x04, 0x01, 0x00, 0x00, 0x04, 0xff, 0xff, 0xff, 0x07,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
@@ -0,0 +1,932 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
// Must NOT be in flash, PDC needs a RAM source.
|
||||
// Amplitude reduced to 30% to allow for voice volume
|
||||
uint16_t Sine_values[] =
|
||||
{
|
||||
2048,2085,2123,2160,2197,2233,2268,2303,2336,2369,
|
||||
2400,2430,2458,2485,2510,2533,2554,2573,2590,2605,
|
||||
2618,2629,2637,2643,2646,2648,2646,2643,2637,2629,
|
||||
2618,2605,2590,2573,2554,2533,2510,2485,2458,2430,
|
||||
2400,2369,2336,2303,2268,2233,2197,2160,2123,2085,
|
||||
2048,2010,1972,1935,1898,1862,1826,1792,1758,1726,
|
||||
1695,1665,1637,1610,1585,1562,1541,1522,1505,1490,
|
||||
1477,1466,1458,1452,1448,1448,1448,1452,1458,1466,
|
||||
1477,1490,1505,1522,1541,1562,1585,1610,1637,1665,
|
||||
1695,1726,1758,1792,1826,1862,1898,1935,1972,2010
|
||||
};
|
||||
|
||||
#if defined(SDCARD)
|
||||
const char * audioFilenames[] = {
|
||||
"inactiv",
|
||||
"lowbatt",
|
||||
"highmah",
|
||||
"hightemp",
|
||||
"thralert",
|
||||
"swalert",
|
||||
"eebad",
|
||||
"eeformat",
|
||||
"error",
|
||||
"keyup",
|
||||
"keydown",
|
||||
"menus",
|
||||
"trim",
|
||||
"warning1",
|
||||
"warning2",
|
||||
"warning3",
|
||||
"midtrim",
|
||||
"endtrim",
|
||||
"tada",
|
||||
"midpot",
|
||||
"mixwarn1",
|
||||
"mixwarn2",
|
||||
"mixwarn3",
|
||||
"timerlt3",
|
||||
"timer10",
|
||||
"timer20",
|
||||
"timer30"
|
||||
};
|
||||
|
||||
|
||||
uint32_t sdAvailableSystemAudioFiles = 0;
|
||||
uint8_t sdAvailablePhaseAudioFiles[MAX_PHASES] = { 0 };
|
||||
uint8_t sdAvailableMixerAudioFiles[MAX_MIXERS] = { 0 };
|
||||
|
||||
void refreshSystemAudioFiles()
|
||||
{
|
||||
FILINFO info;
|
||||
#if _USE_LFN
|
||||
TCHAR lfn[_MAX_LFN + 1];
|
||||
info.lfname = lfn;
|
||||
info.lfsize = sizeof(lfn);
|
||||
#endif
|
||||
|
||||
char filename[32] = SYSTEM_SOUNDS_PATH "/";
|
||||
|
||||
assert(sizeof(audioFilenames)==AU_FRSKY_FIRST*sizeof(char *));
|
||||
assert(sizeof(sdAvailableSystemAudioFiles)*8 > AU_FRSKY_FIRST);
|
||||
|
||||
uint32_t availableAudioFiles = 0;
|
||||
|
||||
for (uint32_t i=0; i<AU_FRSKY_FIRST; i++) {
|
||||
strcpy(filename+sizeof(SYSTEM_SOUNDS_PATH), audioFilenames[i]);
|
||||
strcat(filename+sizeof(SYSTEM_SOUNDS_PATH), SOUNDS_EXT);
|
||||
if (f_stat(filename, &info) == FR_OK)
|
||||
availableAudioFiles |= ((uint32_t)1 << i);
|
||||
}
|
||||
|
||||
sdAvailableSystemAudioFiles = availableAudioFiles;
|
||||
}
|
||||
|
||||
const char * suffixes[] = { "-OFF", "-ON", /*"-BG", */NULL };
|
||||
|
||||
inline uint8_t getAvailableFiles(char *prefix, FILINFO &info, char *filename)
|
||||
{
|
||||
uint8_t result = 0;
|
||||
|
||||
for (uint8_t i=0; suffixes[i]; i++) {
|
||||
strcpy(prefix, suffixes[i]);
|
||||
strcat(prefix, SOUNDS_EXT);
|
||||
if (f_stat(filename, &info) == FR_OK)
|
||||
result |= ((uint8_t)1 << i);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void refreshModelAudioFiles()
|
||||
{
|
||||
FILINFO info;
|
||||
#if _USE_LFN
|
||||
TCHAR lfn[_MAX_LFN + 1];
|
||||
info.lfname = lfn;
|
||||
info.lfsize = sizeof(lfn);
|
||||
#endif
|
||||
|
||||
char filename[AUDIO_FILENAME_MAXLEN+1] = SOUNDS_PATH "/";
|
||||
|
||||
if (sdMounted()) {
|
||||
char *buf = strcat_modelname(&filename[sizeof(SOUNDS_PATH)], g_eeGeneral.currModel);
|
||||
*buf++ = '/';
|
||||
|
||||
for (uint32_t i=0; i<MAX_PHASES; i++) {
|
||||
char *tmp = strcat_phasename(buf, i);
|
||||
sdAvailablePhaseAudioFiles[i] = (tmp != buf ? getAvailableFiles(strcat_phasename(buf, i), info, filename) : 0);
|
||||
}
|
||||
|
||||
/* for (uint32_t i=0; i<MAX_MIXERS; i++) {
|
||||
char *tmp = strcat_mixername_nodefault(buf, i);
|
||||
sdAvailableMixerAudioFiles[i] = (tmp != buf ? getAvailableFiles(tmp, info, filename) : 0);
|
||||
} */
|
||||
}
|
||||
}
|
||||
|
||||
bool isAudioFileAvailable(uint32_t i, char * filename)
|
||||
{
|
||||
uint8_t category = (i >> 24);
|
||||
uint8_t index = (i >> 16) & 0xFF;
|
||||
uint8_t event = i & 0xFF;
|
||||
|
||||
#if 0
|
||||
printf("isAudioFileAvailable(%08x)\n", i); fflush(stdout);
|
||||
#endif
|
||||
|
||||
if (category == SYSTEM_AUDIO_CATEGORY) {
|
||||
if (sdAvailableSystemAudioFiles & ((uint32_t)1 << event)) {
|
||||
strcpy(filename, SYSTEM_SOUNDS_PATH "/");
|
||||
strcpy(filename+sizeof(SYSTEM_SOUNDS_PATH), audioFilenames[i]);
|
||||
strcat(filename+sizeof(SYSTEM_SOUNDS_PATH), SOUNDS_EXT);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (category == PHASE_AUDIO_CATEGORY) {
|
||||
if (sdAvailablePhaseAudioFiles[index] & ((uint32_t)1 << event)) {
|
||||
strcpy(filename, SOUNDS_PATH "/");
|
||||
char *str = strcat_modelname(filename+sizeof(SOUNDS_PATH), g_eeGeneral.currModel);
|
||||
*str++ = '/';
|
||||
char * tmp = strcat_phasename(str, index);
|
||||
if (tmp != str) {
|
||||
strcpy(tmp, suffixes[event]);
|
||||
strcat(tmp, SOUNDS_EXT);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (category == MIXER_AUDIO_CATEGORY) {
|
||||
if (sdAvailableMixerAudioFiles[index] & ((uint32_t)1 << event)) {
|
||||
strcpy(filename, SOUNDS_PATH "/");
|
||||
char *str = strcat_modelname(filename+sizeof(SOUNDS_PATH), g_eeGeneral.currModel);
|
||||
*str++ = '/';
|
||||
char * tmp = strcat_mixername(str, index);
|
||||
if (tmp != str) {
|
||||
strcpy(tmp, suffixes[event]);
|
||||
strcat(tmp, SOUNDS_EXT);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
#define isAudioFileAvailable(i, f) false
|
||||
#endif
|
||||
|
||||
uint16_t alawTable[256];
|
||||
uint16_t ulawTable[256];
|
||||
|
||||
#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
|
||||
#define QUANT_MASK (0xf) /* Quantization field mask. */
|
||||
#define SEG_SHIFT (4) /* Left shift for segment number. */
|
||||
#define SEG_MASK (0x70) /* Segment field mask. */
|
||||
#define BIAS (0x84) /* Bias for linear code. */
|
||||
|
||||
static short alaw2linear(unsigned char a_val)
|
||||
{
|
||||
int t;
|
||||
int seg;
|
||||
|
||||
a_val ^= 0x55;
|
||||
|
||||
t = a_val & QUANT_MASK;
|
||||
seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
|
||||
if(seg) t= (t + t + 1 + 32) << (seg + 2);
|
||||
else t= (t + t + 1 ) << 3;
|
||||
|
||||
return (a_val & SIGN_BIT) ? t : -t;
|
||||
}
|
||||
|
||||
static short ulaw2linear(unsigned char u_val)
|
||||
{
|
||||
int t;
|
||||
|
||||
/* Complement to obtain normal u-law value. */
|
||||
u_val = ~u_val;
|
||||
|
||||
/*
|
||||
* Extract and bias the quantization bits. Then
|
||||
* shift up by the segment number and subtract out the bias.
|
||||
*/
|
||||
t = ((u_val & QUANT_MASK) << 3) + BIAS;
|
||||
t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
|
||||
|
||||
return (u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS);
|
||||
}
|
||||
|
||||
void codecsInit()
|
||||
{
|
||||
for (uint32_t i=0; i<256; i++) {
|
||||
alawTable[i] = (0x8000 + alaw2linear(i)) >> 4;
|
||||
ulawTable[i] = (0x8000 + ulaw2linear(i)) >> 4;
|
||||
}
|
||||
}
|
||||
|
||||
AudioQueue audioQueue;
|
||||
|
||||
AudioQueue::AudioQueue()
|
||||
{
|
||||
memset(this, 0, sizeof(AudioQueue));
|
||||
prioIdx = -1;
|
||||
}
|
||||
|
||||
void AudioQueue::start()
|
||||
{
|
||||
state = AUDIO_SLEEPING;
|
||||
CoSetFlag(audioFlag);
|
||||
}
|
||||
|
||||
void audioTimerHandle(void)
|
||||
{
|
||||
CoSetFlag(audioFlag);
|
||||
}
|
||||
|
||||
#define CODEC_ID_PCM_S16LE 1
|
||||
#define CODEC_ID_PCM_ALAW 6
|
||||
#define CODEC_ID_PCM_MULAW 7
|
||||
|
||||
#ifndef SIMU
|
||||
void audioTask(void* pdata)
|
||||
{
|
||||
while (!audioQueue.started()) {
|
||||
CoWaitForSingleFlag(audioFlag, 0);
|
||||
}
|
||||
|
||||
#if defined(SDCARD)
|
||||
if (!unexpectedShutdown) {
|
||||
codecsInit();
|
||||
sdInit();
|
||||
AUDIO_TADA();
|
||||
}
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
|
||||
CoWaitForSingleFlag(audioFlag, 0);
|
||||
|
||||
audioQueue.wakeup();
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#define WAV_BUFFER_SIZE 512
|
||||
uint16_t wavSamplesArray[3*WAV_BUFFER_SIZE];
|
||||
uint16_t * wavSamplesBuffer = &wavSamplesArray[0];
|
||||
uint16_t * nextAudioData = NULL;
|
||||
uint16_t nextAudioSize = 0;
|
||||
|
||||
#if defined(SDCARD) && !defined(SIMU)
|
||||
|
||||
#define RIFF_CHUNK_SIZE 12
|
||||
|
||||
void AudioQueue::sdWakeup(AudioContext & context)
|
||||
{
|
||||
if (!nextAudioData) {
|
||||
AudioFragment & fragment = context.fragment;
|
||||
FRESULT result = FR_OK;
|
||||
UINT read = 0;
|
||||
if (fragment.file[1]) {
|
||||
result = f_open(&context.wavFile, fragment.file, FA_OPEN_EXISTING | FA_READ);
|
||||
fragment.file[1] = 0;
|
||||
if (result == FR_OK) {
|
||||
result = f_read(&context.wavFile, (uint8_t *)wavSamplesBuffer, RIFF_CHUNK_SIZE+8, &read);
|
||||
if (result == FR_OK && read == RIFF_CHUNK_SIZE+8 && !memcmp(wavSamplesBuffer, "RIFF", 4) && !memcmp(wavSamplesBuffer+4/*short*/, "WAVEfmt ", 8)) {
|
||||
uint32_t size = *((uint32_t *)(wavSamplesBuffer+8/*short*/));
|
||||
result = (size < 256 ? f_read(&context.wavFile, (uint8_t *)wavSamplesBuffer, size+8, &read) : FR_DENIED);
|
||||
if (result == FR_OK && read == size+8) {
|
||||
context.pcmCodec = wavSamplesBuffer[0];
|
||||
context.pcmFreq = wavSamplesBuffer[2];
|
||||
uint32_t *wavSamplesPtr = (uint32_t *)(wavSamplesBuffer + size/2);
|
||||
uint32_t size = wavSamplesPtr[1];
|
||||
while (result == FR_OK && memcmp(wavSamplesPtr, "data", 4) != 0) {
|
||||
result = (size < 256 ? f_read(&context.wavFile, (uint8_t *)wavSamplesBuffer, size+8, &read) : FR_DENIED);
|
||||
if (read != size+8) result = FR_DENIED;
|
||||
wavSamplesPtr = (uint32_t *)(wavSamplesBuffer + size/2);
|
||||
size = wavSamplesPtr[1];
|
||||
}
|
||||
context.wavSize = size;
|
||||
}
|
||||
else {
|
||||
result = FR_DENIED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = FR_DENIED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
read = 0;
|
||||
uint16_t bufsize = (context.pcmCodec == CODEC_ID_PCM_S16LE ? WAV_BUFFER_SIZE * sizeof(uint16_t) : WAV_BUFFER_SIZE);
|
||||
if (result == FR_OK) {
|
||||
result = f_read(&context.wavFile, (uint8_t *)wavSamplesBuffer, bufsize, &read);
|
||||
}
|
||||
|
||||
if (result != FR_OK) {
|
||||
dacStop();
|
||||
memset(&fragment, 0, sizeof(fragment));
|
||||
f_close(&context.wavFile);
|
||||
if (context.pcmFreq) {
|
||||
CoSetTmrCnt(audioTimer, (WAV_BUFFER_SIZE * 1000) / context.pcmFreq, 0);
|
||||
CoStartTmr(audioTimer);
|
||||
CoClearFlag(audioFlag);
|
||||
}
|
||||
else {
|
||||
CoSetFlag(audioFlag);
|
||||
}
|
||||
state = AUDIO_RESUMING;
|
||||
}
|
||||
else {
|
||||
if (read > context.wavSize)
|
||||
read = context.wavSize;
|
||||
context.wavSize -= read;
|
||||
|
||||
if (read != bufsize) {
|
||||
memset(&fragment, 0, sizeof(fragment));
|
||||
f_close(&context.wavFile);
|
||||
}
|
||||
|
||||
setFrequency(context.pcmFreq);
|
||||
|
||||
if (context.pcmCodec == CODEC_ID_PCM_S16LE) {
|
||||
read /= 2;
|
||||
uint32_t i = 0;
|
||||
for (; i < read; i++)
|
||||
wavSamplesBuffer[i] = ((uint16_t) 0x8000 + ((int16_t) (wavSamplesBuffer[i]))) >> 4;
|
||||
for (; i < WAV_BUFFER_SIZE; i++)
|
||||
wavSamplesBuffer[i] = 0x8000;
|
||||
}
|
||||
else if (context.pcmCodec == CODEC_ID_PCM_ALAW) {
|
||||
int32_t i;
|
||||
for (i = read - 1; i >= 0; i--)
|
||||
wavSamplesBuffer[i] = alawTable[((uint8_t *) wavSamplesBuffer)[i]];
|
||||
for (i = read; i < WAV_BUFFER_SIZE; i++)
|
||||
wavSamplesBuffer[i] = 0x8000;
|
||||
}
|
||||
else if (context.pcmCodec == CODEC_ID_PCM_MULAW) {
|
||||
int32_t i;
|
||||
for (i = read - 1; i >= 0; i--)
|
||||
wavSamplesBuffer[i] = ulawTable[((uint8_t *) wavSamplesBuffer)[i]];
|
||||
for (i = read; i < WAV_BUFFER_SIZE; i++)
|
||||
wavSamplesBuffer[i] = 0x8000;
|
||||
}
|
||||
|
||||
read /= 2;
|
||||
|
||||
if (read) {
|
||||
state = AUDIO_PLAYING_WAV;
|
||||
if (dacQueue(wavSamplesBuffer, read)) {
|
||||
CoSetFlag(audioFlag);
|
||||
}
|
||||
else {
|
||||
nextAudioSize = read;
|
||||
nextAudioData = wavSamplesBuffer;
|
||||
#if defined(PCBSKY9X)
|
||||
dacStart();
|
||||
#endif
|
||||
CoSetTmrCnt(audioTimer, (WAV_BUFFER_SIZE * 500) / context.pcmFreq, 0);
|
||||
CoStartTmr(audioTimer);
|
||||
}
|
||||
wavSamplesBuffer += WAV_BUFFER_SIZE;
|
||||
if (wavSamplesBuffer >= wavSamplesArray + 3 * WAV_BUFFER_SIZE)
|
||||
wavSamplesBuffer = wavSamplesArray;
|
||||
}
|
||||
else {
|
||||
state = AUDIO_RESUMING;
|
||||
CoSetFlag(audioFlag);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
CoSetTmrCnt(audioTimer, 5/*10ms*/, 0);
|
||||
CoStartTmr(audioTimer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void AudioQueue::wakeup()
|
||||
{
|
||||
AudioFragment & fragment = currentContext.fragment;
|
||||
|
||||
if (prioIdx >= 0) {
|
||||
memset(&fragment, 0, sizeof(fragment));
|
||||
}
|
||||
|
||||
#if defined(SDCARD) && !defined(SIMU)
|
||||
if (fragment.file[0]) {
|
||||
sdWakeup(currentContext);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (fragment.duration > 0) {
|
||||
if (state != AUDIO_PLAYING_TONE) {
|
||||
state = AUDIO_PLAYING_TONE;
|
||||
dacFill(Sine_values, 50/*100 samples*/);
|
||||
}
|
||||
|
||||
setFrequency(fragment.freq * 6100 / 4);
|
||||
|
||||
if (fragment.freqIncr) {
|
||||
CoSetTmrCnt(audioTimer, 2, 0);
|
||||
fragment.freq += fragment.freqIncr;
|
||||
fragment.duration--;
|
||||
}
|
||||
else {
|
||||
CoSetTmrCnt(audioTimer, fragment.duration*2, 0);
|
||||
fragment.duration = 0;
|
||||
}
|
||||
dacStart();
|
||||
CoClearFlag(audioFlag);
|
||||
CoStartTmr(audioTimer);
|
||||
}
|
||||
else if (fragment.pause > 0) {
|
||||
state = AUDIO_PLAYING_TONE;
|
||||
CoSetTmrCnt(audioTimer, fragment.pause*2, 0);
|
||||
fragment.pause = 0;
|
||||
dacStop();
|
||||
CoClearFlag(audioFlag);
|
||||
CoStartTmr(audioTimer);
|
||||
}
|
||||
#if defined(SDCARD) && !defined(SIMU)
|
||||
else if (ridx == widx && prioIdx < 0 && backgroundContext.fragment.file[0]) {
|
||||
if (!isFunctionActive(FUNC_BACKGND_MUSIC_PAUSE)) {
|
||||
sdWakeup(backgroundContext);
|
||||
}
|
||||
else {
|
||||
CoSetTmrCnt(audioTimer, 5/*10ms*/, 0);
|
||||
CoStartTmr(audioTimer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (ridx == widx && prioIdx < 0 && backgroundContext.fragment.duration > 0) {
|
||||
if (state != AUDIO_PLAYING_TONE) {
|
||||
state = AUDIO_PLAYING_TONE;
|
||||
dacFill(Sine_values, 50/*100 samples*/);
|
||||
}
|
||||
CoSetTmrCnt(audioTimer, backgroundContext.fragment.duration*2, 0);
|
||||
backgroundContext.fragment.duration = 0;
|
||||
setFrequency(backgroundContext.fragment.freq * 6100 / 4);
|
||||
dacStart();
|
||||
CoClearFlag(audioFlag);
|
||||
CoStartTmr(audioTimer);
|
||||
}
|
||||
else {
|
||||
CoEnterMutexSection(audioMutex);
|
||||
|
||||
if (ridx != widx) {
|
||||
if (prioIdx >= 0) {
|
||||
ridx = prioIdx;
|
||||
prioIdx = -1;
|
||||
dacStop();
|
||||
CoClearFlag(audioFlag);
|
||||
nextAudioData = NULL;
|
||||
if (state == AUDIO_PLAYING_WAV) {
|
||||
state = AUDIO_RESUMING;
|
||||
CoSetTmrCnt(audioTimer, 1/*2ms*/ + (WAV_BUFFER_SIZE * 1000) / getFrequency(), 0);
|
||||
CoStartTmr(audioTimer);
|
||||
}
|
||||
else if (state == AUDIO_PLAYING_TONE) {
|
||||
state = AUDIO_RESUMING;
|
||||
CoSetTmrCnt(audioTimer, 1/*2ms*/, 0);
|
||||
CoStartTmr(audioTimer);
|
||||
}
|
||||
else {
|
||||
CoSetFlag(audioFlag);
|
||||
}
|
||||
}
|
||||
else {
|
||||
CoSetFlag(audioFlag);
|
||||
}
|
||||
|
||||
memcpy(&fragment, &fragments[ridx], sizeof(fragment));
|
||||
if (!fragments[ridx].repeat--) {
|
||||
ridx = (ridx + 1) % AUDIO_QUEUE_LENGTH;
|
||||
}
|
||||
}
|
||||
else {
|
||||
memset(&fragment, 0, sizeof(fragment));
|
||||
state = AUDIO_SLEEPING;
|
||||
dacStop();
|
||||
}
|
||||
|
||||
CoLeaveMutexSection(audioMutex);
|
||||
}
|
||||
}
|
||||
|
||||
inline uint8_t getToneLength(uint8_t tLen)
|
||||
{
|
||||
uint8_t result = tLen; // default
|
||||
if (g_eeGeneral.beeperLength < 0) {
|
||||
result /= (1-g_eeGeneral.beeperLength);
|
||||
}
|
||||
if (g_eeGeneral.beeperLength > 0) {
|
||||
result *= (1+g_eeGeneral.beeperLength);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void AudioQueue::pause(uint8_t tLen)
|
||||
{
|
||||
play(0, 0, tLen); // a pause
|
||||
}
|
||||
|
||||
bool AudioQueue::isPlaying(uint8_t id)
|
||||
{
|
||||
if (currentContext.fragment.id == id || backgroundContext.fragment.id == id)
|
||||
return true;
|
||||
|
||||
uint8_t i = ridx;
|
||||
while (i != widx) {
|
||||
AudioFragment & fragment = fragments[i];
|
||||
if (fragment.id == id)
|
||||
return true;
|
||||
i = (i + 1) % AUDIO_QUEUE_LENGTH;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef SIMU
|
||||
extern OS_MutexID audioMutex;
|
||||
#endif
|
||||
|
||||
void AudioQueue::play(uint16_t tFreq, uint8_t tLen, uint8_t tPause, uint8_t tFlags, int8_t tFreqIncr)
|
||||
{
|
||||
CoEnterMutexSection(audioMutex);
|
||||
|
||||
if (tFlags & PLAY_BACKGROUND) {
|
||||
backgroundContext.fragment.freq = tFreq;
|
||||
backgroundContext.fragment.duration = tLen;
|
||||
backgroundContext.fragment.pause = tPause;
|
||||
if (!busy()) {
|
||||
state = AUDIO_RESUMING;
|
||||
CoSetFlag(audioFlag);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tFreq > 0) { //we dont add pitch if zero as this is a pause only event
|
||||
tFreq += g_eeGeneral.speakerPitch + BEEP_OFFSET; // add pitch compensator
|
||||
}
|
||||
tLen = getToneLength(tLen);
|
||||
|
||||
uint8_t next_widx = (widx + 1) % AUDIO_QUEUE_LENGTH;
|
||||
if (next_widx != ridx) {
|
||||
AudioFragment & fragment = fragments[widx];
|
||||
memset(&fragment, 0, sizeof(fragment));
|
||||
fragment.freq = tFreq;
|
||||
fragment.duration = tLen;
|
||||
fragment.pause = tPause;
|
||||
fragment.repeat = tFlags & 0x0f;
|
||||
fragment.freqIncr = tFreqIncr;
|
||||
if (tFlags & PLAY_NOW)
|
||||
prioIdx = widx;
|
||||
widx = next_widx;
|
||||
if (!busy()) {
|
||||
state = AUDIO_RESUMING;
|
||||
CoSetFlag(audioFlag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CoLeaveMutexSection(audioMutex);
|
||||
}
|
||||
|
||||
#if defined(SDCARD)
|
||||
void AudioQueue::playFile(const char *filename, uint8_t flags, uint8_t id)
|
||||
{
|
||||
#if defined(SIMU)
|
||||
printf("playFile(\"%s\", flags=%x, id=%d)\n", filename, flags, id);
|
||||
fflush(stdout);
|
||||
#else
|
||||
|
||||
if (!sdMounted())
|
||||
return;
|
||||
|
||||
CoEnterMutexSection(audioMutex);
|
||||
|
||||
if (flags & PLAY_BACKGROUND) {
|
||||
memset(&backgroundContext.fragment, 0, sizeof(AudioFragment));
|
||||
strcpy(backgroundContext.fragment.file, filename);
|
||||
backgroundContext.fragment.id = id;
|
||||
if (!busy()) {
|
||||
state = AUDIO_RESUMING;
|
||||
CoSetFlag(audioFlag);
|
||||
}
|
||||
}
|
||||
else {
|
||||
uint8_t next_widx = (widx + 1) % AUDIO_QUEUE_LENGTH;
|
||||
if (next_widx != ridx) {
|
||||
AudioFragment & fragment = fragments[widx];
|
||||
memset(&fragment, 0, sizeof(fragment));
|
||||
strcpy(fragment.file, filename);
|
||||
fragment.repeat = flags & 0x0f;
|
||||
fragment.id = id;
|
||||
if (flags & PLAY_NOW)
|
||||
prioIdx = widx;
|
||||
widx = next_widx;
|
||||
if (!busy()) {
|
||||
state = AUDIO_RESUMING;
|
||||
CoSetFlag(audioFlag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CoLeaveMutexSection(audioMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void AudioQueue::stopPlay(uint8_t id)
|
||||
{
|
||||
#if defined(SIMU)
|
||||
printf("stopPlay(id=%d)\n", id); fflush(stdout);
|
||||
#endif
|
||||
|
||||
// For the moment it's only needed to stop the background music
|
||||
if (backgroundContext.fragment.id == id) {
|
||||
memset(&backgroundContext.fragment, 0, sizeof(AudioFragment));
|
||||
}
|
||||
}
|
||||
|
||||
void AudioQueue::stopSD()
|
||||
{
|
||||
sdAvailableSystemAudioFiles = 0;
|
||||
reset();
|
||||
play(0, 0, 100, PLAY_NOW); // insert a 100ms pause
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void AudioQueue::reset()
|
||||
{
|
||||
CoEnterMutexSection(audioMutex);
|
||||
widx = ridx; // clean the queue
|
||||
memset(¤tContext.fragment, 0, sizeof(AudioFragment));
|
||||
memset(&backgroundContext.fragment, 0, sizeof(AudioFragment));
|
||||
CoLeaveMutexSection(audioMutex);
|
||||
}
|
||||
|
||||
void audioEvent(uint8_t e, uint8_t f)
|
||||
{
|
||||
#if defined(SDCARD)
|
||||
char filename[AUDIO_FILENAME_MAXLEN+1];
|
||||
#endif
|
||||
|
||||
#if defined(HAPTIC)
|
||||
haptic.event(e); //do this before audio to help sync timings
|
||||
#endif
|
||||
|
||||
if (e <= AU_ERROR || e >= AU_WARNING1) {
|
||||
#if defined(BEEPER)
|
||||
beep();
|
||||
#endif
|
||||
|
||||
if (g_eeGeneral.alarmsFlash) {
|
||||
if (lightOffCounter < FLASH_DURATION)
|
||||
lightOffCounter = FLASH_DURATION;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_eeGeneral.beeperMode>0 || (g_eeGeneral.beeperMode==0 && e>=AU_TRIM_MOVE) || (g_eeGeneral.beeperMode>=-1 && e<=AU_ERROR)) {
|
||||
#if defined(SDCARD)
|
||||
if (e < AU_FRSKY_FIRST && isAudioFileAvailable(e, filename)) {
|
||||
audioQueue.playFile(filename);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (e < AU_FRSKY_FIRST || audioQueue.empty()) {
|
||||
switch (e) {
|
||||
// inactivity timer alert
|
||||
case AU_INACTIVITY:
|
||||
audioQueue.play(140, 20, 4, 2|PLAY_NOW);
|
||||
break;
|
||||
// low battery in tx
|
||||
case AU_TX_BATTERY_LOW:
|
||||
if (!audioQueue.busy()) {
|
||||
audioQueue.play(120, 40, 6, 2, 1);
|
||||
audioQueue.play(160, 40, 6, 2, -1);
|
||||
}
|
||||
break;
|
||||
case AU_TX_MAH_HIGH:
|
||||
if (!audioQueue.busy()) {
|
||||
// TODO Rob something better here?
|
||||
audioQueue.play(120, 40, 6, 2, 1);
|
||||
audioQueue.play(160, 40, 6, 2, -1);
|
||||
}
|
||||
break;
|
||||
case AU_TX_TEMP_HIGH:
|
||||
if (!audioQueue.busy()) {
|
||||
// TODO Rob something better here?
|
||||
audioQueue.play(120, 40, 6, 2, 1);
|
||||
audioQueue.play(160, 40, 6, 2, -1);
|
||||
}
|
||||
break;
|
||||
// error
|
||||
#if defined(VOICE)
|
||||
case AU_THROTTLE_ALERT:
|
||||
case AU_SWITCH_ALERT:
|
||||
#endif
|
||||
case AU_ERROR:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ, 50, 2, PLAY_NOW);
|
||||
break;
|
||||
// keypad up (seems to be used when going left/right through system menu options. 0-100 scales etc)
|
||||
case AU_KEYPAD_UP:
|
||||
audioQueue.play(BEEP_KEY_UP_FREQ, 20, 2, PLAY_NOW);
|
||||
break;
|
||||
// keypad down (seems to be used when going left/right through system menu options. 0-100 scales etc)
|
||||
case AU_KEYPAD_DOWN:
|
||||
audioQueue.play(BEEP_KEY_DOWN_FREQ, 20, 2, PLAY_NOW);
|
||||
break;
|
||||
// menu display (also used by a few generic beeps)
|
||||
case AU_MENUS:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ, 20, 4, PLAY_NOW);
|
||||
break;
|
||||
// trim move
|
||||
case AU_TRIM_MOVE:
|
||||
audioQueue.play(f, 12, 2, PLAY_NOW);
|
||||
break;
|
||||
// trim center
|
||||
case AU_TRIM_MIDDLE:
|
||||
audioQueue.play(f, 20, 4, PLAY_NOW);
|
||||
break;
|
||||
// trim center
|
||||
case AU_TRIM_END:
|
||||
audioQueue.play(f, 20, 4, PLAY_NOW);
|
||||
break;
|
||||
// warning one
|
||||
case AU_WARNING1:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ, 20, 2, PLAY_NOW);
|
||||
break;
|
||||
// warning two
|
||||
case AU_WARNING2:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ, 40, 2, PLAY_NOW);
|
||||
break;
|
||||
// warning three
|
||||
case AU_WARNING3:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ, 50, 2, PLAY_NOW);
|
||||
break;
|
||||
// pot/stick center
|
||||
case AU_POT_STICK_MIDDLE:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ+100, 20, 2, PLAY_NOW);
|
||||
break;
|
||||
// mix warning 1
|
||||
case AU_MIX_WARNING_1:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ+96, 12, 0);
|
||||
break;
|
||||
// mix warning 2
|
||||
case AU_MIX_WARNING_2:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ+104, 12, 8, PLAY_REPEAT(1));
|
||||
break;
|
||||
// mix warning 3
|
||||
case AU_MIX_WARNING_3:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ+112, 12, 8, PLAY_REPEAT(2));
|
||||
break;
|
||||
// time 30 seconds left
|
||||
case AU_TIMER_30:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ, 30, 6, PLAY_REPEAT(2)|PLAY_NOW);
|
||||
break;
|
||||
// time 20 seconds left
|
||||
case AU_TIMER_20:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ, 30, 6, PLAY_REPEAT(1)|PLAY_NOW);
|
||||
break;
|
||||
// time 10 seconds left
|
||||
case AU_TIMER_10:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ, 30, 6, PLAY_NOW);
|
||||
break;
|
||||
// time <3 seconds left
|
||||
case AU_TIMER_LT3:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ+10, 30, 6, PLAY_NOW);
|
||||
break;
|
||||
case AU_FRSKY_BEEP1:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ, 15, 2);
|
||||
audioQueue.pause(200);
|
||||
break;
|
||||
case AU_FRSKY_BEEP2:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ, 30, 2);
|
||||
audioQueue.pause(200);
|
||||
break;
|
||||
case AU_FRSKY_BEEP3:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ, 50, 2);
|
||||
audioQueue.pause(200);
|
||||
break;
|
||||
case AU_FRSKY_WARN1:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ+40, 30, 10, 2);
|
||||
audioQueue.pause(200);
|
||||
break;
|
||||
case AU_FRSKY_WARN2:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ+60,30,10,2);
|
||||
audioQueue.pause(200);
|
||||
break;
|
||||
case AU_FRSKY_CHEEP:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ+60,20,4,2,2);
|
||||
audioQueue.pause(200);
|
||||
break;
|
||||
case AU_FRSKY_RING:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ+50,10,4,10);
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ+50,10,20,1);
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ+50,10,4,10);
|
||||
audioQueue.pause(200);
|
||||
break;
|
||||
case AU_FRSKY_SCIFI:
|
||||
audioQueue.play(160,20,6,2,-1);
|
||||
audioQueue.play(120,20,6,2,1);
|
||||
audioQueue.play(140,20,2,0);
|
||||
audioQueue.pause(200);
|
||||
break;
|
||||
case AU_FRSKY_ROBOT:
|
||||
audioQueue.play(140,10,2,1);
|
||||
audioQueue.play(100,30,4,1);
|
||||
audioQueue.play(160,30,4,1);
|
||||
audioQueue.pause(200);
|
||||
break;
|
||||
case AU_FRSKY_CHIRP:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ+80,10,2,2);
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ+108,10,2,3);
|
||||
audioQueue.pause(200);
|
||||
break;
|
||||
case AU_FRSKY_TADA:
|
||||
audioQueue.play(100,20,10);
|
||||
audioQueue.play(180,20,10);
|
||||
audioQueue.play(220,16,8,2);
|
||||
audioQueue.pause(200);
|
||||
break;
|
||||
case AU_FRSKY_CRICKET:
|
||||
audioQueue.play(160,10,20,3);
|
||||
audioQueue.play(160,10,40,1);
|
||||
audioQueue.play(160,10,20,3);
|
||||
audioQueue.pause(200);
|
||||
break;
|
||||
case AU_FRSKY_SIREN:
|
||||
audioQueue.play(20,40,10,2,1);
|
||||
audioQueue.pause(200);
|
||||
break;
|
||||
case AU_FRSKY_ALARMC:
|
||||
audioQueue.play(100,8,20,2);
|
||||
audioQueue.play(140,16,40,1);
|
||||
audioQueue.play(100,16,20,2);
|
||||
audioQueue.play(140,8,40,1);
|
||||
audioQueue.pause(200);
|
||||
break;
|
||||
case AU_FRSKY_RATATA:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ+100,10,20,10);
|
||||
break;
|
||||
case AU_FRSKY_TICK:
|
||||
audioQueue.play(BEEP_DEFAULT_FREQ+100,10,100,2);
|
||||
audioQueue.pause(200);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pushPrompt(uint16_t prompt, uint8_t id)
|
||||
{
|
||||
#if defined(SDCARD)
|
||||
|
||||
char filename[] = SYSTEM_SOUNDS_PATH "/0000" SOUNDS_EXT;
|
||||
|
||||
for (int8_t i=3; i>=0; i--) {
|
||||
filename[sizeof(SYSTEM_SOUNDS_PATH)+i] = '0' + (prompt%10);
|
||||
prompt /= 10;
|
||||
}
|
||||
|
||||
audioQueue.playFile(filename, 0, id);
|
||||
|
||||
#endif
|
||||
}
|
||||
+228
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef audio_h
|
||||
#define audio_h
|
||||
|
||||
#include "FatFs/ff.h"
|
||||
|
||||
#define AUDIO_FILENAME_MAXLEN (40)
|
||||
#define AUDIO_QUEUE_LENGTH (20)
|
||||
#define BEEP_DEFAULT_FREQ (140)
|
||||
#define BEEP_OFFSET (10)
|
||||
#define BEEP_KEY_UP_FREQ (BEEP_DEFAULT_FREQ+10)
|
||||
#define BEEP_KEY_DOWN_FREQ (BEEP_DEFAULT_FREQ-10)
|
||||
|
||||
extern uint16_t Sine_values[];
|
||||
|
||||
class ToneFragment {
|
||||
public:
|
||||
uint16_t freq;
|
||||
uint8_t duration;
|
||||
uint8_t pause;
|
||||
uint8_t repeat;
|
||||
int8_t freqIncr;
|
||||
uint8_t id;
|
||||
};
|
||||
|
||||
class AudioFragment : public ToneFragment {
|
||||
public:
|
||||
char file[AUDIO_FILENAME_MAXLEN+1];
|
||||
};
|
||||
|
||||
extern "C" void DAC_IRQHandler();
|
||||
|
||||
#define AUDIO_NOT_STARTED 0
|
||||
#define AUDIO_SLEEPING 1
|
||||
#define AUDIO_RESUMING 2
|
||||
#define AUDIO_PLAYING_TONE 3
|
||||
#define AUDIO_PLAYING_WAV 4
|
||||
|
||||
extern bool playingBackground;
|
||||
|
||||
class AudioContext {
|
||||
public:
|
||||
AudioFragment fragment;
|
||||
#if defined(SDCARD)
|
||||
FIL wavFile;
|
||||
#endif
|
||||
uint8_t pcmCodec;
|
||||
uint32_t pcmFreq;
|
||||
uint32_t wavSize;
|
||||
};
|
||||
|
||||
class AudioQueue {
|
||||
|
||||
friend void audioTask(void* pdata);
|
||||
friend void DAC_IRQHandler();
|
||||
|
||||
public:
|
||||
|
||||
AudioQueue();
|
||||
|
||||
void start();
|
||||
|
||||
void play(uint16_t tFreq, uint8_t tLen, uint8_t tPause, uint8_t tFlags=0, int8_t tFreqIncr=0);
|
||||
|
||||
void playFile(const char *filename, uint8_t flags=0, uint8_t id=0);
|
||||
|
||||
void stopPlay(uint8_t id);
|
||||
|
||||
void pause(uint8_t tLen);
|
||||
|
||||
void stopSD();
|
||||
|
||||
bool isPlaying(uint8_t id);
|
||||
|
||||
bool started()
|
||||
{
|
||||
return (state != AUDIO_NOT_STARTED);
|
||||
}
|
||||
|
||||
bool busy()
|
||||
{
|
||||
#ifdef SIMU
|
||||
return false;
|
||||
#else
|
||||
return (state != AUDIO_SLEEPING);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool empty()
|
||||
{
|
||||
return ridx == widx;
|
||||
}
|
||||
|
||||
void reset();
|
||||
|
||||
protected:
|
||||
|
||||
void wakeup();
|
||||
|
||||
void sdWakeup(AudioContext & context);
|
||||
|
||||
volatile uint8_t state;
|
||||
uint8_t ridx;
|
||||
uint8_t widx;
|
||||
int8_t prioIdx;
|
||||
|
||||
AudioFragment fragments[AUDIO_QUEUE_LENGTH];
|
||||
|
||||
AudioContext currentContext;
|
||||
AudioContext backgroundContext; // for background music / vario
|
||||
};
|
||||
|
||||
extern AudioQueue audioQueue;
|
||||
|
||||
void codecsInit();
|
||||
void audioEvent(uint8_t e, uint8_t f=BEEP_DEFAULT_FREQ);
|
||||
void audioStart();
|
||||
|
||||
#define AUDIO_TADA() audioEvent(AU_TADA)
|
||||
#define AUDIO_KEYPAD_UP() audioEvent(AU_KEYPAD_UP)
|
||||
#define AUDIO_KEYPAD_DOWN() audioEvent(AU_KEYPAD_DOWN)
|
||||
#define AUDIO_MENUS() audioEvent(AU_MENUS)
|
||||
#define AUDIO_WARNING1() audioEvent(AU_WARNING1)
|
||||
#define AUDIO_WARNING2() audioEvent(AU_WARNING2)
|
||||
#define AUDIO_TX_BATTERY_LOW() audioEvent(AU_TX_BATTERY_LOW)
|
||||
#define AUDIO_TX_MAH_HIGH() audioEvent(AU_TX_MAH_HIGH)
|
||||
#define AUDIO_TX_TEMP_HIGH() audioEvent(AU_TX_TEMP_HIGH)
|
||||
#define AUDIO_ERROR() audioEvent(AU_ERROR)
|
||||
|
||||
#if defined(VOICE)
|
||||
#define AUDIO_ERROR_MESSAGE(e) audioEvent(e)
|
||||
#define AUDIO_TIMER_MINUTE(t) playDuration(t, 0)
|
||||
#else
|
||||
#define AUDIO_ERROR_MESSAGE(e) audioEvent(AU_ERROR)
|
||||
#define AUDIO_TIMER_MINUTE(t) audioDefevent(AU_WARNING1)
|
||||
#endif
|
||||
|
||||
#define AUDIO_TIMER_30() audioEvent(AU_TIMER_30)
|
||||
#define AUDIO_TIMER_20() audioEvent(AU_TIMER_20)
|
||||
#define AUDIO_TIMER_10() audioEvent(AU_TIMER_10)
|
||||
#define AUDIO_TIMER_LT3(x) audioEvent(AU_TIMER_LT3)
|
||||
#define AUDIO_INACTIVITY() audioEvent(AU_INACTIVITY)
|
||||
#define AUDIO_MIX_WARNING(x) audioEvent(AU_MIX_WARNING_1+x-1)
|
||||
#define AUDIO_POT_STICK_MIDDLE() audioEvent(AU_POT_STICK_MIDDLE)
|
||||
#define AUDIO_VARIO_UP() audioEvent(AU_KEYPAD_UP)
|
||||
#define AUDIO_VARIO_DOWN() audioEvent(AU_KEYPAD_DOWN)
|
||||
#define AUDIO_TRIM_MIDDLE(f) audioEvent(AU_TRIM_MIDDLE, f)
|
||||
#define AUDIO_TRIM_END(f) audioEvent(AU_TRIM_END, f)
|
||||
#define AUDIO_TRIM(event, f) audioEvent(AU_TRIM_MOVE, f)
|
||||
#define AUDIO_PLAY(p) audioEvent(p)
|
||||
#define AUDIO_VARIO(f, t) audioQueue.play(f, t, 0, PLAY_BACKGROUND)
|
||||
|
||||
#define AUDIO_HEARTBEAT()
|
||||
|
||||
#define SYSTEM_AUDIO_CATEGORY 0
|
||||
#define MODEL_AUDIO_CATEGORY 1
|
||||
#define PHASE_AUDIO_CATEGORY 2
|
||||
#define MIXER_AUDIO_CATEGORY 3
|
||||
|
||||
#define AUDIO_EVENT_OFF 0
|
||||
#define AUDIO_EVENT_ON 1
|
||||
#define AUDIO_EVENT_BG 2
|
||||
|
||||
extern void pushPrompt(uint16_t prompt, uint8_t id=0);
|
||||
|
||||
#define PLAY_FUNCTION(x, ...) void x(__VA_ARGS__, uint8_t id)
|
||||
#define PUSH_NUMBER_PROMPT(p) pushPrompt((p), id)
|
||||
#define PLAY_NUMBER(n, u, a) playNumber((n), (u), (a), id)
|
||||
#define PLAY_DURATION(d) playDuration((d), id)
|
||||
#define IS_PLAYING(id) audioQueue.isPlaying((id))
|
||||
#define PLAY_VALUE(v, id) playValue((v), (id))
|
||||
#define PLAY_FILE(f, flags, id) audioQueue.playFile((f), (flags), (id))
|
||||
#define STOP_PLAY(id) audioQueue.stopPlay((id))
|
||||
#define AUDIO_RESET() audioQueue.reset()
|
||||
|
||||
#if defined(SDCARD)
|
||||
#define PLAY_PHASE_OFF(phase) do { char filename[AUDIO_FILENAME_MAXLEN+1]; if (isAudioFileAvailable((PHASE_AUDIO_CATEGORY << 24) + (phase << 16) + AUDIO_EVENT_OFF, filename)) audioQueue.playFile(filename); } while (0)
|
||||
#define PLAY_PHASE_ON(phase) do { char filename[AUDIO_FILENAME_MAXLEN+1]; if (isAudioFileAvailable((PHASE_AUDIO_CATEGORY << 24) + (phase << 16) + AUDIO_EVENT_ON, filename)) audioQueue.playFile(filename); } while (0)
|
||||
#else
|
||||
#define PLAY_PHASE_OFF(phase)
|
||||
#define PLAY_PHASE_ON(phase)
|
||||
#endif
|
||||
|
||||
extern void refreshSystemAudioFiles();
|
||||
extern void refreshModelAudioFiles();
|
||||
extern bool isAudioFileAvailable(uint32_t i, char * filename);
|
||||
|
||||
// TODO not public, everything could be inside a function in audio_arm.cpp
|
||||
extern OS_TCID audioTimer;
|
||||
extern OS_FlagID audioFlag;
|
||||
extern OS_MutexID audioMutex;
|
||||
|
||||
#endif
|
||||
@@ -1,11 +1,14 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny <shadow@privy.de>
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
@@ -14,7 +17,7 @@
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* open9x is based on code named
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
@@ -31,12 +34,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../open9x.h"
|
||||
#include "opentx.h"
|
||||
|
||||
audioQueue::audioQueue()
|
||||
{
|
||||
toneTimeLeft = 0;
|
||||
tonePause = 0;
|
||||
tone2TimeLeft = 0;
|
||||
|
||||
t_queueRidx = 0;
|
||||
t_queueWidx = 0;
|
||||
@@ -50,21 +54,19 @@ void audioQueue::heartbeat()
|
||||
{
|
||||
#if defined(SIMU)
|
||||
return;
|
||||
#endif
|
||||
|
||||
#else
|
||||
if (toneTimeLeft > 0) {
|
||||
if (toneFreq == 0) { //pause only events
|
||||
SPEAKER_OFF;
|
||||
}
|
||||
else {
|
||||
#if defined(PCBV4)
|
||||
#if defined(PCBGRUVIN9X)
|
||||
if (toneFreq) {
|
||||
OCR0A = (5000 / toneFreq); // sticking with old values approx 20(abs. min) to 90, 60 being the default tone(?).
|
||||
SPEAKER_ON;
|
||||
}
|
||||
#endif
|
||||
toneFreq += toneFreqIncr;
|
||||
// TODO tone2TimeLeft = 0?
|
||||
}
|
||||
toneTimeLeft--; //time gets counted down
|
||||
}
|
||||
@@ -79,12 +81,12 @@ void audioQueue::heartbeat()
|
||||
toneFreqIncr = queueToneFreqIncr[t_queueRidx];
|
||||
tonePause = queueTonePause[t_queueRidx];
|
||||
if (!queueToneRepeat[t_queueRidx]--) {
|
||||
t_queueRidx = (t_queueRidx + 1) % AUDIO_QUEUE_LENGTH;
|
||||
t_queueRidx = (t_queueRidx + 1) & (AUDIO_QUEUE_LENGTH-1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tone2TimeLeft > 0) {
|
||||
#if defined(PCBV4)
|
||||
#if defined(PCBGRUVIN9X)
|
||||
if (tone2Freq) {
|
||||
OCR0A = (5000 / tone2Freq); // sticking with old values approx 20(abs. min) to 90, 60 being the default tone(?).
|
||||
SPEAKER_ON;
|
||||
@@ -96,12 +98,10 @@ void audioQueue::heartbeat()
|
||||
}
|
||||
else {
|
||||
SPEAKER_OFF;
|
||||
if (tone2Pause > 0) {
|
||||
tone2Pause--; //time gets counted down
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // defined(SIMU)
|
||||
}
|
||||
|
||||
inline uint8_t audioQueue::getToneLength(uint8_t tLen)
|
||||
@@ -117,24 +117,25 @@ inline uint8_t audioQueue::getToneLength(uint8_t tLen)
|
||||
}
|
||||
|
||||
void audioQueue::pause(uint8_t tLen)
|
||||
{
|
||||
play(0, tLen, 5); // a pause
|
||||
{
|
||||
play(0, tLen, 5); // a pause
|
||||
}
|
||||
|
||||
void audioQueue::play(uint8_t tFreq, uint8_t tLen, uint8_t tPause,
|
||||
uint8_t tFlags, int8_t tFreqIncr)
|
||||
void audioQueue::play(uint8_t tFreq, uint8_t tLen, uint8_t tPause, uint8_t tFlags)
|
||||
{
|
||||
if (tFlags & PLAY_SOUND_VARIO) {
|
||||
if (tFlags & PLAY_BACKGROUND) {
|
||||
tone2Freq = tFreq;
|
||||
tone2TimeLeft = tLen;
|
||||
tone2Pause = tPause;
|
||||
}
|
||||
else {
|
||||
int8_t tFreqIncr = (tFlags >> 6);
|
||||
if (tFreqIncr == 3) tFreqIncr = -1;
|
||||
|
||||
if (tFreq > 0) { //we dont add pitch if zero as this is a pause only event
|
||||
tFreq += g_eeGeneral.speakerPitch + BEEP_OFFSET; // add pitch compensator
|
||||
}
|
||||
tLen = getToneLength(tLen);
|
||||
if (tFlags & PLAY_NOW || (!busy() && empty())) {
|
||||
if ((tFlags & PLAY_NOW) || (!busy() && empty())) {
|
||||
toneFreq = tFreq;
|
||||
toneTimeLeft = tLen;
|
||||
tonePause = tPause;
|
||||
@@ -147,7 +148,7 @@ void audioQueue::play(uint8_t tFreq, uint8_t tLen, uint8_t tPause,
|
||||
|
||||
tFlags &= 0x0f;
|
||||
if (tFlags) {
|
||||
uint8_t next_queueWidx = (t_queueWidx + 1) % AUDIO_QUEUE_LENGTH;
|
||||
uint8_t next_queueWidx = (t_queueWidx + 1) & (AUDIO_QUEUE_LENGTH-1);
|
||||
if (next_queueWidx != t_queueRidx) {
|
||||
queueToneFreq[t_queueWidx] = tFreq;
|
||||
queueToneLength[t_queueWidx] = tLen;
|
||||
@@ -162,25 +163,34 @@ void audioQueue::play(uint8_t tFreq, uint8_t tLen, uint8_t tPause,
|
||||
|
||||
void audioQueue::event(uint8_t e, uint8_t f)
|
||||
{
|
||||
#ifdef HAPTIC
|
||||
#if defined(HAPTIC)
|
||||
haptic.event(e); //do this before audio to help sync timings
|
||||
#endif
|
||||
|
||||
if (g_eeGeneral.flashBeep && (e <= AU_ERROR || e >= AU_WARNING1))
|
||||
g_LightOffCounter = FLASH_DURATION;
|
||||
if (e <= AU_ERROR || e >= AU_WARNING1) {
|
||||
#if defined(BEEPER)
|
||||
beep();
|
||||
#endif
|
||||
|
||||
if (g_eeGeneral.alarmsFlash) {
|
||||
if (lightOffCounter < FLASH_DURATION)
|
||||
lightOffCounter = FLASH_DURATION;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_eeGeneral.beeperMode>0 || (g_eeGeneral.beeperMode==0 && e>=AU_TRIM_MOVE) || (g_eeGeneral.beeperMode>=-1 && e<=AU_ERROR)) {
|
||||
if (e < AU_FRSKY_FIRST || empty()) {
|
||||
// TODO when VOICE enable some cases here are not needed!
|
||||
switch (e) {
|
||||
// inactivity timer alert
|
||||
case AU_INACTIVITY:
|
||||
play(70, 10, 2, 2|PLAY_NOW);
|
||||
play(70, 10, 2, PLAY_REPEAT(2)|PLAY_NOW);
|
||||
break;
|
||||
// low battery in tx
|
||||
case AU_TX_BATTERY_LOW:
|
||||
if (empty()) {
|
||||
play(60, 20, 3, 2, 1);
|
||||
play(80, 20, 3, 2, -1);
|
||||
play(60, 20, 3, PLAY_REPEAT(2)|PLAY_INCREMENT(1));
|
||||
play(80, 20, 3, PLAY_REPEAT(2)|PLAY_INCREMENT(-1));
|
||||
}
|
||||
break;
|
||||
// error
|
||||
@@ -219,35 +229,29 @@ void audioQueue::event(uint8_t e, uint8_t f)
|
||||
case AU_WARNING3:
|
||||
play(BEEP_DEFAULT_FREQ, 30, 1, PLAY_NOW);
|
||||
break;
|
||||
// startup tune
|
||||
case AU_TADA:
|
||||
play(50, 10, 5);
|
||||
play(90, 10, 5);
|
||||
play(110, 5, 4, 2);
|
||||
break;
|
||||
// pot/stick center
|
||||
case AU_POT_STICK_MIDDLE:
|
||||
play(BEEP_DEFAULT_FREQ + 50, 10, 1, PLAY_NOW);
|
||||
break;
|
||||
// mix warning 1
|
||||
case AU_MIX_WARNING_1:
|
||||
play(BEEP_DEFAULT_FREQ + 50, 6, 0, PLAY_NOW);
|
||||
play(BEEP_DEFAULT_FREQ + 50, 6, 0);
|
||||
break;
|
||||
// mix warning 2
|
||||
case AU_MIX_WARNING_2:
|
||||
play(BEEP_DEFAULT_FREQ + 52, 6, 0, PLAY_NOW);
|
||||
play(BEEP_DEFAULT_FREQ + 52, 6, 3, PLAY_REPEAT(1));
|
||||
break;
|
||||
// mix warning 3
|
||||
case AU_MIX_WARNING_3:
|
||||
play(BEEP_DEFAULT_FREQ + 54, 6, 0, PLAY_NOW);
|
||||
play(BEEP_DEFAULT_FREQ + 54, 6, 3, PLAY_REPEAT(2));
|
||||
break;
|
||||
// time 30 seconds left
|
||||
case AU_TIMER_30:
|
||||
play(BEEP_DEFAULT_FREQ + 50, 15, 3, 2|PLAY_NOW);
|
||||
play(BEEP_DEFAULT_FREQ + 50, 15, 3, PLAY_REPEAT(2)|PLAY_NOW);
|
||||
break;
|
||||
// time 20 seconds left
|
||||
case AU_TIMER_20:
|
||||
play(BEEP_DEFAULT_FREQ + 50, 15, 3, 1|PLAY_NOW);
|
||||
play(BEEP_DEFAULT_FREQ + 50, 15, 3, PLAY_REPEAT(1)|PLAY_NOW);
|
||||
break;
|
||||
// time 10 seconds left
|
||||
case AU_TIMER_10:
|
||||
@@ -255,70 +259,82 @@ void audioQueue::event(uint8_t e, uint8_t f)
|
||||
case AU_TIMER_LT3:
|
||||
play(BEEP_DEFAULT_FREQ + 50, 15, 3, PLAY_NOW);
|
||||
break;
|
||||
case AU_FRSKY_BEEP1:
|
||||
play(BEEP_DEFAULT_FREQ, 10, 1);
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_BEEP2:
|
||||
play(BEEP_DEFAULT_FREQ, 20, 1);
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_BEEP3:
|
||||
play(BEEP_DEFAULT_FREQ, 30, 1);
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_WARN1:
|
||||
play(BEEP_DEFAULT_FREQ+20,15,5,2);
|
||||
play(BEEP_DEFAULT_FREQ+20, 15, 5, PLAY_REPEAT(2));
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_WARN2:
|
||||
play(BEEP_DEFAULT_FREQ+30,15,5,2);
|
||||
play(BEEP_DEFAULT_FREQ+30, 15, 5, PLAY_REPEAT(2));
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_CHEEP:
|
||||
play(BEEP_DEFAULT_FREQ+30,10,2,2,2);
|
||||
play(BEEP_DEFAULT_FREQ+30, 10, 2, PLAY_REPEAT(2)|PLAY_INCREMENT(2));
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_RING:
|
||||
play(BEEP_DEFAULT_FREQ+25,5,2,10);
|
||||
play(BEEP_DEFAULT_FREQ+25,5,10,1);
|
||||
play(BEEP_DEFAULT_FREQ+25,5,2,10);
|
||||
play(BEEP_DEFAULT_FREQ+25, 5, 2, PLAY_REPEAT(10));
|
||||
play(BEEP_DEFAULT_FREQ+25, 5, 10, PLAY_REPEAT(1));
|
||||
play(BEEP_DEFAULT_FREQ+25, 5, 2, PLAY_REPEAT(10));
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_SCIFI:
|
||||
play(80,10,3,2,-1);
|
||||
play(60,10,3,2,1);
|
||||
play(70,10,1,0);
|
||||
play(80, 10, 3, PLAY_REPEAT(2)|PLAY_INCREMENT(-1));
|
||||
play(60, 10, 3, PLAY_REPEAT(2)|PLAY_INCREMENT(1));
|
||||
play(70, 10, 1);
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_ROBOT:
|
||||
play(70,5,1,1);
|
||||
play(50,15,2,1);
|
||||
play(80,15,2,1);
|
||||
play(70, 5, 1, PLAY_REPEAT(1));
|
||||
play(50, 15, 2, PLAY_REPEAT(1));
|
||||
play(80, 15, 2, PLAY_REPEAT(1));
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_CHIRP:
|
||||
play(BEEP_DEFAULT_FREQ+40,5,1,2);
|
||||
play(BEEP_DEFAULT_FREQ+54,5,1,3);
|
||||
play(BEEP_DEFAULT_FREQ+40, 5, 1, PLAY_REPEAT(2));
|
||||
play(BEEP_DEFAULT_FREQ+54, 5, 1, PLAY_REPEAT(3));
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_TADA:
|
||||
play(50,5,5);
|
||||
play(90,5,5);
|
||||
play(110,3,4,2);
|
||||
play(50, 5, 5);
|
||||
play(90, 5, 5);
|
||||
play(110, 3, 4, PLAY_REPEAT(2));
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_CRICKET:
|
||||
play(80,5,10,3);
|
||||
play(80,5,20,1);
|
||||
play(80,5,10,3);
|
||||
play(80, 5, 10, PLAY_REPEAT(3));
|
||||
play(80, 5, 20, PLAY_REPEAT(1));
|
||||
play(80, 5, 10, PLAY_REPEAT(3));
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_SIREN:
|
||||
play(10,20,5,2,1);
|
||||
play(10, 20, 5, PLAY_REPEAT(2)|PLAY_INCREMENT(1));
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_ALARMC:
|
||||
play(50,4,10,2);
|
||||
play(70,8,20,1);
|
||||
play(50,8,10,2);
|
||||
play(70,4,20,1);
|
||||
play(50, 4, 10, PLAY_REPEAT(2));
|
||||
play(70, 8, 20, PLAY_REPEAT(1));
|
||||
play(50, 8, 10, PLAY_REPEAT(2));
|
||||
play(70, 4, 20, PLAY_REPEAT(1));
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_RATATA:
|
||||
play(BEEP_DEFAULT_FREQ+50,5,10,10);
|
||||
play(BEEP_DEFAULT_FREQ+50, 5, 10, PLAY_REPEAT(10));
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_TICK:
|
||||
play(BEEP_DEFAULT_FREQ+50,5,50,2);
|
||||
play(BEEP_DEFAULT_FREQ+50, 5, 50, PLAY_REPEAT(2));
|
||||
pause(200);
|
||||
break;
|
||||
default:
|
||||
+162
-139
@@ -1,139 +1,162 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny <shadow@privy.de>
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* open9x is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(PCBARM)
|
||||
#include "ersky9x/sound.h"
|
||||
#endif
|
||||
|
||||
#if defined(PCBSTD)
|
||||
#define SPEAKER_ON BUZZER_ON
|
||||
#define SPEAKER_OFF toneFreq=0; BUZZER_OFF
|
||||
#endif
|
||||
|
||||
//audio
|
||||
#define AUDIO_QUEUE_LENGTH (8) //8 seems to suit most alerts
|
||||
#define BEEP_DEFAULT_FREQ (70)
|
||||
#define BEEP_OFFSET (10)
|
||||
#define BEEP_KEY_UP_FREQ (BEEP_DEFAULT_FREQ+5)
|
||||
#define BEEP_KEY_DOWN_FREQ (BEEP_DEFAULT_FREQ-5)
|
||||
|
||||
class audioQueue
|
||||
{
|
||||
public:
|
||||
|
||||
audioQueue();
|
||||
|
||||
void play(uint8_t tFreq, uint8_t tLen, uint8_t tPause, uint8_t tFlags=0, int8_t tFreqIncr=0);
|
||||
void pause(uint8_t tLen);
|
||||
|
||||
inline bool busy() { return (toneTimeLeft > 0); }
|
||||
|
||||
void event(uint8_t e, uint8_t f=BEEP_DEFAULT_FREQ);
|
||||
|
||||
inline void driver() {
|
||||
if (toneFreq) {
|
||||
toneCounter += toneFreq;
|
||||
if ((toneCounter & 0x80) == 0x80)
|
||||
BUZZER_ON;
|
||||
else
|
||||
BUZZER_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
// heartbeat is responsibile for issueing the audio tones and general square waves
|
||||
// it is essentially the life of the class.
|
||||
void heartbeat();
|
||||
|
||||
// bool freeslots(uint8_t slots);
|
||||
|
||||
inline bool empty() {
|
||||
return (t_queueRidx == t_queueWidx);
|
||||
}
|
||||
|
||||
protected:
|
||||
inline uint8_t getToneLength(uint8_t tLen);
|
||||
|
||||
private:
|
||||
uint8_t t_queueRidx;
|
||||
uint8_t t_queueWidx;
|
||||
|
||||
uint8_t toneFreq;
|
||||
int8_t toneFreqIncr;
|
||||
uint8_t toneTimeLeft;
|
||||
uint8_t tonePause;
|
||||
|
||||
// vario has less priority
|
||||
uint8_t tone2Freq;
|
||||
uint8_t tone2TimeLeft;
|
||||
uint8_t tone2Pause;
|
||||
|
||||
// queue arrays
|
||||
uint8_t queueToneFreq[AUDIO_QUEUE_LENGTH];
|
||||
int8_t queueToneFreqIncr[AUDIO_QUEUE_LENGTH];
|
||||
uint8_t queueToneLength[AUDIO_QUEUE_LENGTH];
|
||||
uint8_t queueTonePause[AUDIO_QUEUE_LENGTH];
|
||||
uint8_t queueToneRepeat[AUDIO_QUEUE_LENGTH];
|
||||
|
||||
uint8_t toneCounter;
|
||||
|
||||
};
|
||||
|
||||
|
||||
extern audioQueue audio;
|
||||
|
||||
void audioDefevent(uint8_t e);
|
||||
|
||||
#define AUDIO_KEYPAD_UP() audioDefevent(AU_KEYPAD_UP)
|
||||
#define AUDIO_KEYPAD_DOWN() audioDefevent(AU_KEYPAD_DOWN)
|
||||
#define AUDIO_MENUS() audioDefevent(AU_MENUS)
|
||||
#define AUDIO_WARNING1() audioDefevent(AU_WARNING1)
|
||||
#define AUDIO_WARNING2() audioDefevent(AU_WARNING2)
|
||||
#define AUDIO_ERROR() audioDefevent(AU_ERROR)
|
||||
#define AUDIO_TIMER_30() audioDefevent(AU_TIMER_30)
|
||||
#define AUDIO_TIMER_20() audioDefevent(AU_TIMER_20)
|
||||
#define AUDIO_TIMER_10() audioDefevent(AU_TIMER_10)
|
||||
#define AUDIO_TIMER_LT3() audioDefevent(AU_TIMER_LT3)
|
||||
#define AUDIO_MINUTE_BEEP() audioDefevent(AU_WARNING1)
|
||||
#define AUDIO_INACTIVITY() audioDefevent(AU_INACTIVITY)
|
||||
#define AUDIO_MIX_WARNING_1() audioDefevent(AU_MIX_WARNING_1)
|
||||
#define AUDIO_MIX_WARNING_2() audioDefevent(AU_MIX_WARNING_2)
|
||||
#define AUDIO_MIX_WARNING_3() audioDefevent(AU_MIX_WARNING_3)
|
||||
#define AUDIO_POT_STICK_MIDDLE() audioDefevent(AU_POT_STICK_MIDDLE)
|
||||
#define AUDIO_VARIO_UP() audioDefevent(AU_KEYPAD_UP)
|
||||
#define AUDIO_VARIO_DOWN() audioDefevent(AU_KEYPAD_DOWN)
|
||||
#define AUDIO_TRIM_MIDDLE(f) audio.event(AU_TRIM_MIDDLE, f)
|
||||
|
||||
#define AUDIO_DRIVER() audio.driver()
|
||||
#define AUDIO_HEARTBEAT() audio.heartbeat()
|
||||
#define IS_AUDIO_BUSY() audio.busy()
|
||||
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef audio_h
|
||||
#define audio_h
|
||||
|
||||
#if defined(PCBSTD)
|
||||
#define SPEAKER_ON BUZZER_ON
|
||||
#define SPEAKER_OFF toneFreq=0; BUZZER_OFF
|
||||
#endif
|
||||
|
||||
//audio
|
||||
#define AUDIO_QUEUE_LENGTH (8) // 8 seems to suit most alerts
|
||||
#define BEEP_DEFAULT_FREQ (70)
|
||||
#define BEEP_OFFSET (10)
|
||||
#define BEEP_KEY_UP_FREQ (BEEP_DEFAULT_FREQ+5)
|
||||
#define BEEP_KEY_DOWN_FREQ (BEEP_DEFAULT_FREQ-5)
|
||||
|
||||
class audioQueue
|
||||
{
|
||||
public:
|
||||
|
||||
audioQueue();
|
||||
|
||||
void play(uint8_t tFreq, uint8_t tLen, uint8_t tPause, uint8_t tFlags=0);
|
||||
void pause(uint8_t tLen);
|
||||
|
||||
inline bool busy() { return (toneTimeLeft > 0); }
|
||||
|
||||
void event(uint8_t e, uint8_t f=BEEP_DEFAULT_FREQ);
|
||||
|
||||
inline void driver() {
|
||||
if (toneFreq) {
|
||||
toneCounter += toneFreq;
|
||||
if ((toneCounter & 0x80) == 0x80)
|
||||
BUZZER_ON;
|
||||
else
|
||||
BUZZER_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
// heartbeat is responsibile for issueing the audio tones and general square waves
|
||||
// it is essentially the life of the class.
|
||||
void heartbeat();
|
||||
|
||||
inline bool empty() {
|
||||
return (t_queueRidx == t_queueWidx);
|
||||
}
|
||||
|
||||
protected:
|
||||
inline uint8_t getToneLength(uint8_t tLen);
|
||||
|
||||
private:
|
||||
uint8_t t_queueRidx;
|
||||
uint8_t t_queueWidx;
|
||||
|
||||
uint8_t toneFreq;
|
||||
int8_t toneFreqIncr;
|
||||
uint8_t toneTimeLeft;
|
||||
uint8_t tonePause;
|
||||
|
||||
// vario has less priority
|
||||
uint8_t tone2Freq;
|
||||
uint8_t tone2TimeLeft;
|
||||
|
||||
// queue arrays
|
||||
uint8_t queueToneFreq[AUDIO_QUEUE_LENGTH];
|
||||
int8_t queueToneFreqIncr[AUDIO_QUEUE_LENGTH];
|
||||
uint8_t queueToneLength[AUDIO_QUEUE_LENGTH];
|
||||
uint8_t queueTonePause[AUDIO_QUEUE_LENGTH];
|
||||
uint8_t queueToneRepeat[AUDIO_QUEUE_LENGTH];
|
||||
|
||||
uint8_t toneCounter;
|
||||
|
||||
};
|
||||
|
||||
|
||||
extern audioQueue audio;
|
||||
|
||||
void audioDefevent(uint8_t e);
|
||||
|
||||
#define AUDIO_KEYPAD_UP() audioDefevent(AU_KEYPAD_UP)
|
||||
#define AUDIO_KEYPAD_DOWN() audioDefevent(AU_KEYPAD_DOWN)
|
||||
#define AUDIO_MENUS() audioDefevent(AU_MENUS)
|
||||
#define AUDIO_WARNING1() audioDefevent(AU_WARNING1)
|
||||
#define AUDIO_WARNING2() audioDefevent(AU_WARNING2)
|
||||
#define AUDIO_ERROR() audioDefevent(AU_ERROR)
|
||||
|
||||
#if defined(VOICE)
|
||||
#define AUDIO_TADA() PUSH_SYSTEM_PROMPT(AU_TADA)
|
||||
#define AUDIO_TX_BATTERY_LOW() PUSH_SYSTEM_PROMPT(AU_TX_BATTERY_LOW)
|
||||
#define AUDIO_INACTIVITY() PUSH_SYSTEM_PROMPT(AU_INACTIVITY)
|
||||
#define AUDIO_ERROR_MESSAGE(e) PUSH_SYSTEM_PROMPT((e))
|
||||
#define AUDIO_TIMER_MINUTE(t) playDuration(t)
|
||||
#define AUDIO_TIMER_30() PUSH_SYSTEM_PROMPT(AU_TIMER_30)
|
||||
#define AUDIO_TIMER_20() PUSH_SYSTEM_PROMPT(AU_TIMER_20)
|
||||
#define AUDIO_TIMER_10() PUSH_SYSTEM_PROMPT(AU_TIMER_10)
|
||||
#define AUDIO_TIMER_LT3(x) PUSH_SYSTEM_PROMPT(AU_TIMER_LT3)
|
||||
#else
|
||||
#define AUDIO_TADA()
|
||||
#define AUDIO_TX_BATTERY_LOW() audioDefevent(AU_TX_BATTERY_LOW)
|
||||
#define AUDIO_INACTIVITY() audioDefevent(AU_INACTIVITY)
|
||||
#define AUDIO_ERROR_MESSAGE(e) audioDefevent(AU_ERROR)
|
||||
#define AUDIO_TIMER_MINUTE(t) audioDefevent(AU_WARNING1)
|
||||
#define AUDIO_TIMER_30() audioDefevent(AU_TIMER_30)
|
||||
#define AUDIO_TIMER_20() audioDefevent(AU_TIMER_20)
|
||||
#define AUDIO_TIMER_10() audioDefevent(AU_TIMER_10)
|
||||
#define AUDIO_TIMER_LT3(x) audioDefevent(AU_TIMER_LT3)
|
||||
#endif
|
||||
|
||||
#define AUDIO_MIX_WARNING(x) audioDefevent(AU_MIX_WARNING_1+x-1)
|
||||
#define AUDIO_POT_STICK_MIDDLE() audioDefevent(AU_POT_STICK_MIDDLE)
|
||||
#define AUDIO_VARIO_UP() audioDefevent(AU_KEYPAD_UP)
|
||||
#define AUDIO_VARIO_DOWN() audioDefevent(AU_KEYPAD_DOWN)
|
||||
#define AUDIO_TRIM_MIDDLE(f) audio.event(AU_TRIM_MIDDLE, f)
|
||||
#define AUDIO_TRIM_END(f) AUDIO_TRIM_MIDDLE(f)
|
||||
#define AUDIO_TRIM(event, f) audio.event(AU_TRIM_MOVE, f)
|
||||
#define AUDIO_PLAY(p) audio.event(p)
|
||||
#define AUDIO_VARIO(f, t) audio.play(f, t, 0, PLAY_BACKGROUND)
|
||||
|
||||
#define AUDIO_DRIVER() audio.driver()
|
||||
#define AUDIO_HEARTBEAT() audio.heartbeat()
|
||||
#define IS_AUDIO_BUSY() audio.busy()
|
||||
#define AUDIO_RESET()
|
||||
|
||||
#define PLAY_PHASE_OFF(phase)
|
||||
#define PLAY_PHASE_ON(phase)
|
||||
|
||||
#endif
|
||||
+18
-5
@@ -1,11 +1,14 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny <shadow@privy.de>
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
@@ -14,7 +17,7 @@
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* open9x is based on code named
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
@@ -31,7 +34,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "open9x.h"
|
||||
#include "opentx.h"
|
||||
|
||||
uint8_t g_beepCnt;
|
||||
uint8_t beepAgain = 0;
|
||||
@@ -40,6 +43,15 @@ uint8_t beepOn = false;
|
||||
bool warble = false;
|
||||
bool warbleC;
|
||||
|
||||
#if defined(AUDIO)
|
||||
static const pm_uint8_t beepTab[] PROGMEM = {
|
||||
60, 80, 100, 120, 150,
|
||||
};
|
||||
void beep()
|
||||
{
|
||||
_beep(pgm_read_byte(beepTab+(2+g_eeGeneral.beeperLength)));
|
||||
}
|
||||
#else
|
||||
// The various "beep" tone lengths
|
||||
static const pm_uint8_t beepTab[] PROGMEM = {
|
||||
// key, trim, warn2, warn1, error
|
||||
@@ -53,12 +65,13 @@ static const pm_uint8_t beepTab[] PROGMEM = {
|
||||
void beep(uint8_t val)
|
||||
{
|
||||
#if defined(HAPTIC)
|
||||
haptic.event(val==0 ? 0 : AU_TIMER_10+beepAgain);
|
||||
haptic.event(val==0 ? AU_KEYPAD_UP : (val==4 ? AU_ERROR : AU_TIMER_10+beepAgain));
|
||||
#endif
|
||||
|
||||
if(g_eeGeneral.flashBeep && val > 1) g_LightOffCounter = FLASH_DURATION;
|
||||
if (g_eeGeneral.alarmsFlash && val>1 && lightOffCounter<FLASH_DURATION) lightOffCounter = FLASH_DURATION;
|
||||
|
||||
if (g_eeGeneral.beeperMode>0 || (g_eeGeneral.beeperMode==0 && val!=0) || (g_eeGeneral.beeperMode==-1 && val>=3)) {
|
||||
_beep(pgm_read_byte(beepTab+5*(2+g_eeGeneral.beeperLength)+val));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
+61
-31
@@ -1,11 +1,14 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny <shadow@privy.de>
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
@@ -14,7 +17,7 @@
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* open9x is based on code named
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
@@ -44,44 +47,71 @@ extern bool warbleC;
|
||||
extern uint8_t hapticTick;
|
||||
#endif
|
||||
|
||||
#if defined(PCBARM)
|
||||
#include "ersky9x/sound.h"
|
||||
inline void _beep(uint8_t b) {
|
||||
buzzer_sound(b);
|
||||
#if defined(CPUARM)
|
||||
inline void _beep(uint8_t b)
|
||||
{
|
||||
buzzerSound(b);
|
||||
}
|
||||
#else
|
||||
inline void _beep(uint8_t b) {
|
||||
inline void _beep(uint8_t b)
|
||||
{
|
||||
g_beepCnt = b;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void beep(uint8_t val);
|
||||
#if defined(AUDIO)
|
||||
void beep();
|
||||
#else
|
||||
void beep(uint8_t val);
|
||||
#endif
|
||||
|
||||
#define AUDIO_KEYPAD_UP() beep(0)
|
||||
#define AUDIO_KEYPAD_DOWN() beep(0)
|
||||
#define AUDIO_MENUS() beep(0)
|
||||
#define AUDIO_TRIM() beep(1)
|
||||
#define AUDIO_WARNING2() beep(2)
|
||||
#define AUDIO_WARNING1() beep(3)
|
||||
#define AUDIO_ERROR() beep(4)
|
||||
#define AUDIO_TIMER_30() { beepAgain=2; beep(2); }
|
||||
#define AUDIO_TIMER_20() { beepAgain=1; beep(2); }
|
||||
#define AUDIO_TIMER_10() beep(2)
|
||||
#define AUDIO_TIMER_LT3() beep(2)
|
||||
#define AUDIO_MINUTE_BEEP() beep(2)
|
||||
#define AUDIO_INACTIVITY() beep(3)
|
||||
#define AUDIO_MIX_WARNING_1() beep(1)
|
||||
#define AUDIO_MIX_WARNING_2() beep(1)
|
||||
#define AUDIO_MIX_WARNING_3() beep(1)
|
||||
#define AUDIO_POT_STICK_MIDDLE() beep(2)
|
||||
#define AUDIO_VARIO_UP() _beep(1)
|
||||
#define AUDIO_VARIO_DOWN() _beep(1)
|
||||
#define AUDIO_TRIM_MIDDLE(f) beep(2)
|
||||
#if !defined(AUDIO)
|
||||
#if defined(VOICE)
|
||||
#define AUDIO_TADA() PUSH_SYSTEM_PROMPT(AU_TADA)
|
||||
#define AUDIO_TX_BATTERY_LOW() PUSH_SYSTEM_PROMPT(AU_TX_BATTERY_LOW)
|
||||
#define AUDIO_INACTIVITY() PUSH_SYSTEM_PROMPT(AU_INACTIVITY)
|
||||
#define AUDIO_ERROR_MESSAGE(e) PUSH_SYSTEM_PROMPT((e))
|
||||
#define AUDIO_TIMER_MINUTE(t) playDuration(t)
|
||||
#define AUDIO_TIMER_30() PUSH_SYSTEM_PROMPT(AU_TIMER_30)
|
||||
#define AUDIO_TIMER_20() PUSH_SYSTEM_PROMPT(AU_TIMER_20)
|
||||
#define AUDIO_TIMER_10() PUSH_SYSTEM_PROMPT(AU_TIMER_10)
|
||||
#define AUDIO_TIMER_LT3(x) PUSH_SYSTEM_PROMPT(AU_TIMER_LT3)
|
||||
#else
|
||||
#define AUDIO_TADA()
|
||||
#define AUDIO_TX_BATTERY_LOW() beep(4)
|
||||
#define AUDIO_INACTIVITY() beep(3)
|
||||
#define AUDIO_ERROR_MESSAGE(e) beep(4)
|
||||
#define AUDIO_TIMER_MINUTE(t) beep(2)
|
||||
#define AUDIO_TIMER_30() { beepAgain=2; beep(2); }
|
||||
#define AUDIO_TIMER_20() { beepAgain=1; beep(2); }
|
||||
#define AUDIO_TIMER_10() beep(2)
|
||||
#define AUDIO_TIMER_LT3(x) beep(2)
|
||||
#endif
|
||||
|
||||
#define IS_AUDIO_BUSY() (g_beepCnt || beepAgain || beepOn)
|
||||
#define AUDIO_KEYPAD_UP() beep(0)
|
||||
#define AUDIO_KEYPAD_DOWN() beep(0)
|
||||
#define AUDIO_MENUS() beep(0)
|
||||
#define AUDIO_WARNING2() beep(2)
|
||||
#define AUDIO_WARNING1() beep(3)
|
||||
#define AUDIO_ERROR() beep(4)
|
||||
#define AUDIO_MIX_WARNING(x) beep(1)
|
||||
#define AUDIO_POT_STICK_MIDDLE() beep(2)
|
||||
#define AUDIO_VARIO_UP() _beep(1)
|
||||
#define AUDIO_VARIO_DOWN() _beep(1)
|
||||
#define AUDIO_TRIM(event, f) { if (!IS_KEY_FIRST(event)) warble = true; beep(1); }
|
||||
#define AUDIO_TRIM_MIDDLE(f) beep(2)
|
||||
#define AUDIO_TRIM_END(f) beep(2)
|
||||
#define AUDIO_PLAY(p) beep(3)
|
||||
|
||||
#if !defined(PCBARM)
|
||||
FORCEINLINE void AUDIO_HEARTBEAT()
|
||||
#define IS_AUDIO_BUSY() (g_beepCnt || beepAgain || beepOn)
|
||||
#define AUDIO_RESET()
|
||||
|
||||
#define PLAY_PHASE_OFF(phase)
|
||||
#define PLAY_PHASE_ON(phase)
|
||||
#endif
|
||||
|
||||
#if !defined(CPUARM)
|
||||
inline void BUZZER_HEARTBEAT()
|
||||
{
|
||||
if(g_beepCnt) {
|
||||
if(!beepAgainOrig) {
|
||||
|
||||
+243
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
const pm_char * bmpLoad(uint8_t *dest, const char *filename, const xcoord_t width, const uint8_t height)
|
||||
{
|
||||
FIL bmpFile;
|
||||
UINT read;
|
||||
uint8_t palette[16];
|
||||
uint8_t bmpBuf[64]; /* maximum with 64px */
|
||||
uint8_t *buf = &bmpBuf[0];
|
||||
|
||||
assert(width <= 64);
|
||||
|
||||
FRESULT result = f_open(&bmpFile, filename, FA_OPEN_EXISTING | FA_READ);
|
||||
if (result != FR_OK) {
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
|
||||
if (f_size(&bmpFile) < 14) {
|
||||
f_close(&bmpFile);
|
||||
return STR_INCOMPATIBLE;
|
||||
}
|
||||
|
||||
result = f_read(&bmpFile, buf, 14, &read);
|
||||
if (result != FR_OK || read != 14) {
|
||||
f_close(&bmpFile);
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
|
||||
if (buf[0] != 'B' || buf[1] != 'M') {
|
||||
f_close(&bmpFile);
|
||||
return STR_INCOMPATIBLE;
|
||||
}
|
||||
|
||||
uint32_t fsize = *((uint32_t *)&buf[2]);
|
||||
uint32_t hsize = *((uint32_t *)&buf[10]); /* header size */
|
||||
|
||||
uint32_t len = limit((uint32_t)0, (uint32_t)(hsize-14), (uint32_t)32);
|
||||
result = f_read(&bmpFile, buf, len, &read);
|
||||
if (result != FR_OK || read != len) {
|
||||
f_close(&bmpFile);
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
|
||||
uint32_t ihsize = *((uint32_t *)&buf[0]); /* more header size */
|
||||
|
||||
/* invalid header size */
|
||||
if (ihsize + 14 > hsize) {
|
||||
f_close(&bmpFile);
|
||||
return STR_INCOMPATIBLE;
|
||||
}
|
||||
|
||||
/* sometimes file size is set to some headers size, set a real size in that case */
|
||||
if (fsize == 14 || fsize == ihsize + 14)
|
||||
fsize = f_size(&bmpFile) - 2;
|
||||
|
||||
/* declared file size less than header size */
|
||||
if (fsize <= hsize) {
|
||||
f_close(&bmpFile);
|
||||
return STR_INCOMPATIBLE;
|
||||
}
|
||||
|
||||
uint32_t w, h;
|
||||
|
||||
switch (ihsize){
|
||||
case 40: // windib
|
||||
case 56: // windib v3
|
||||
case 64: // OS/2 v2
|
||||
case 108: // windib v4
|
||||
case 124: // windib v5
|
||||
w = *((uint32_t *)&buf[4]);
|
||||
h = *((uint32_t *)&buf[8]);
|
||||
buf += 12;
|
||||
break;
|
||||
case 12: // OS/2 v1
|
||||
w = *((uint16_t *)&buf[4]);
|
||||
h = *((uint16_t *)&buf[6]);
|
||||
buf += 8;
|
||||
break;
|
||||
default:
|
||||
f_close(&bmpFile);
|
||||
return STR_INCOMPATIBLE;
|
||||
}
|
||||
|
||||
if (*((uint16_t *)&buf[0]) != 1) { /* planes */
|
||||
f_close(&bmpFile);
|
||||
return STR_INCOMPATIBLE;
|
||||
}
|
||||
|
||||
if (w > width || h > height) {
|
||||
f_close(&bmpFile);
|
||||
return STR_INCOMPATIBLE;
|
||||
}
|
||||
|
||||
uint16_t depth = *((uint16_t *)&buf[2]);
|
||||
|
||||
buf = &bmpBuf[0];
|
||||
|
||||
if (depth == 4) {
|
||||
if (f_lseek(&bmpFile, hsize-64) != FR_OK || f_read(&bmpFile, buf, 64, &read) != FR_OK || read != 64) {
|
||||
f_close(&bmpFile);
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
for (uint8_t i=0; i<16; i++) {
|
||||
palette[i] = buf[4*i] >> 4;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (f_lseek(&bmpFile, hsize) != FR_OK) {
|
||||
f_close(&bmpFile);
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
}
|
||||
|
||||
*dest++ = w;
|
||||
*dest++ = h;
|
||||
|
||||
memset(dest, 0, w*(h/8)*4);
|
||||
|
||||
uint32_t n;
|
||||
|
||||
switch (depth) {
|
||||
case 1:
|
||||
n = w/8;
|
||||
for (uint32_t i=0; i<h; i+=8) {
|
||||
result = f_read(&bmpFile, buf, n*8, &read);
|
||||
if (result != FR_OK || read != n*8) {
|
||||
f_close(&bmpFile);
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
uint8_t * dst = dest + 4*((h-i-8)/8 * w);
|
||||
for (uint32_t j=0; j<n; j++) {
|
||||
#define PUSH_4BYTES(x) *dst = *(dst+1) = *(dst+2) = *(dst+3) = (x); dst += 4
|
||||
PUSH_4BYTES(~(((buf[j+0*n] >> 7) << 7) + ((buf[j+1*n] >> 7) << 6) + ((buf[j+2*n] >> 7) << 5) + ((buf[j+3*n] >> 7) << 4) + ((buf[j+4*n] >> 7) << 3) + ((buf[j+5*n] >> 7) << 2) + ((buf[j+6*n] >> 7) << 1) + ((buf[j+7*n] >> 7) << 0)));
|
||||
PUSH_4BYTES(~((((buf[j+0*n] >> 6) & 1) << 7) + (((buf[j+1*n] >> 6) & 1) << 6) + (((buf[j+2*n] >> 6) & 1) << 5) + (((buf[j+3*n] >> 6) & 1) << 4) + (((buf[j+4*n] >> 6) & 1) << 3) + (((buf[j+5*n] >> 6) & 1) << 2) + (((buf[j+6*n] >> 6) & 1) << 1) + (((buf[j+7*n] >> 6) & 1) << 0)));
|
||||
PUSH_4BYTES(~((((buf[j+0*n] >> 5) & 1) << 7) + (((buf[j+1*n] >> 5) & 1) << 6) + (((buf[j+2*n] >> 5) & 1) << 5) + (((buf[j+3*n] >> 5) & 1) << 4) + (((buf[j+4*n] >> 5) & 1) << 3) + (((buf[j+5*n] >> 5) & 1) << 2) + (((buf[j+6*n] >> 5) & 1) << 1) + (((buf[j+7*n] >> 5) & 1) << 0)));
|
||||
PUSH_4BYTES(~((((buf[j+0*n] >> 4) & 1) << 7) + (((buf[j+1*n] >> 4) & 1) << 6) + (((buf[j+2*n] >> 4) & 1) << 5) + (((buf[j+3*n] >> 4) & 1) << 4) + (((buf[j+4*n] >> 4) & 1) << 3) + (((buf[j+5*n] >> 4) & 1) << 2) + (((buf[j+6*n] >> 4) & 1) << 1) + (((buf[j+7*n] >> 4) & 1) << 0)));
|
||||
PUSH_4BYTES(~((((buf[j+0*n] >> 3) & 1) << 7) + (((buf[j+1*n] >> 3) & 1) << 6) + (((buf[j+2*n] >> 3) & 1) << 5) + (((buf[j+3*n] >> 3) & 1) << 4) + (((buf[j+4*n] >> 3) & 1) << 3) + (((buf[j+5*n] >> 3) & 1) << 2) + (((buf[j+6*n] >> 3) & 1) << 1) + (((buf[j+7*n] >> 3) & 1) << 0)));
|
||||
PUSH_4BYTES(~((((buf[j+0*n] >> 2) & 1) << 7) + (((buf[j+1*n] >> 2) & 1) << 6) + (((buf[j+2*n] >> 2) & 1) << 5) + (((buf[j+3*n] >> 2) & 1) << 4) + (((buf[j+4*n] >> 2) & 1) << 3) + (((buf[j+5*n] >> 2) & 1) << 2) + (((buf[j+6*n] >> 2) & 1) << 1) + (((buf[j+7*n] >> 2) & 1) << 0)));
|
||||
PUSH_4BYTES(~((((buf[j+0*n] >> 1) & 1) << 7) + (((buf[j+1*n] >> 1) & 1) << 6) + (((buf[j+2*n] >> 1) & 1) << 5) + (((buf[j+3*n] >> 1) & 1) << 4) + (((buf[j+4*n] >> 1) & 1) << 3) + (((buf[j+5*n] >> 1) & 1) << 2) + (((buf[j+6*n] >> 1) & 1) << 1) + (((buf[j+7*n] >> 1) & 1) << 0)));
|
||||
PUSH_4BYTES(~((((buf[j+0*n] >> 0) & 1) << 7) + (((buf[j+1*n] >> 0) & 1) << 6) + (((buf[j+2*n] >> 0) & 1) << 5) + (((buf[j+3*n] >> 0) & 1) << 4) + (((buf[j+4*n] >> 0) & 1) << 3) + (((buf[j+5*n] >> 0) & 1) << 2) + (((buf[j+6*n] >> 0) & 1) << 1) + (((buf[j+7*n] >> 0) & 1) << 0)));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
n = w/8;
|
||||
for (int32_t i=h-1; i>=0; i--) {
|
||||
result = f_read(&bmpFile, buf, w/2, &read);
|
||||
if (result != FR_OK || read != w/2) {
|
||||
f_close(&bmpFile);
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
uint8_t mask = 1 << (i%8);
|
||||
for (uint32_t j=0; j<w/2; j++) {
|
||||
uint8_t * dst = dest + (i/8)*w*4 + j*8;
|
||||
uint8_t val = palette[(buf[j] >> 4) & 0x0F];
|
||||
*(dst+0) = ((*(dst+0)) & (~mask)) + ((val & 0x1) ? 0 : mask);
|
||||
*(dst+1) = ((*(dst+1)) & (~mask)) + ((val & 0x2) ? 0 : mask);
|
||||
*(dst+2) = ((*(dst+2)) & (~mask)) + ((val & 0x4) ? 0 : mask);
|
||||
*(dst+3) = ((*(dst+3)) & (~mask)) + ((val & 0x8) ? 0 : mask);
|
||||
val = palette[buf[j] & 0x0F];
|
||||
*(dst+4) = ((*(dst+4)) & (~mask)) + ((val & 0x1) ? 0 : mask);
|
||||
*(dst+5) = ((*(dst+5)) & (~mask)) + ((val & 0x2) ? 0 : mask);
|
||||
*(dst+6) = ((*(dst+6)) & (~mask)) + ((val & 0x4) ? 0 : mask);
|
||||
*(dst+7) = ((*(dst+7)) & (~mask)) + ((val & 0x8) ? 0 : mask);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
f_close(&bmpFile);
|
||||
return STR_INCOMPATIBLE;
|
||||
}
|
||||
|
||||
f_close(&bmpFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lcd_bmp(xcoord_t x, uint8_t y, const pm_uchar * img, uint8_t offset, uint8_t width)
|
||||
{
|
||||
const pm_uchar *q = img;
|
||||
#if LCD_W >= 260
|
||||
xcoord_t w = pgm_read_byte(q++);
|
||||
if (w == 255) w += pgm_read_byte(q++);
|
||||
#else
|
||||
uint8_t w = pgm_read_byte(q++);
|
||||
#endif
|
||||
if (!width) width = w;
|
||||
uint8_t hb = (pgm_read_byte(q++)+7)/8;
|
||||
q += 4*offset;
|
||||
for (uint8_t yb = 0; yb < hb; yb++) {
|
||||
uint8_t *p = &displayBuf[ (y / 8 + yb) * LCD_W + x ];
|
||||
for (xcoord_t i=0; i<width; i++) {
|
||||
for (uint8_t plan=0; plan<4; plan++) {
|
||||
uint8_t b = pgm_read_byte(q++);
|
||||
uint8_t ym8 = (y & 0x07);
|
||||
uint8_t *pp = p + plan*DISPLAY_PLAN_SIZE;
|
||||
LCD_BYTE_FILTER_PLAN(pp, ~(0xff << ym8), b << ym8);
|
||||
if (ym8) {
|
||||
uint8_t *r = pp + LCD_W;
|
||||
LCD_BYTE_FILTER_PLAN(r, ~(0xff >> (8-ym8)), b >> (8-ym8));
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny <shadow@privy.de>
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* open9x is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef board_ersky9x_h
|
||||
#define board_ersky9x_h
|
||||
|
||||
#ifdef REVA
|
||||
#include "ersky9x/AT91SAM3S2.h"
|
||||
#else
|
||||
#include "ersky9x/AT91SAM3S4.h"
|
||||
#endif
|
||||
|
||||
#include "ersky9x/sound_driver.h"
|
||||
#include "ersky9x/haptic_driver.h"
|
||||
#include "ersky9x/sdcard_driver.h"
|
||||
|
||||
#define PIN_ENABLE 0x001
|
||||
#define PIN_PERIPHERAL 0x000
|
||||
#define PIN_INPUT 0x002
|
||||
#define PIN_OUTPUT 0x000
|
||||
#define PIN_PULLUP 0x004
|
||||
#define PIN_NO_PULLUP 0x000
|
||||
#define PIN_PULLDOWN 0x008
|
||||
#define PIN_NO_PULLDOWN 0x000
|
||||
#define PIN_PERI_MASK_L 0x010
|
||||
#define PIN_PERI_MASK_H 0x020
|
||||
#define PIN_PER_A 0x000
|
||||
#define PIN_PER_B 0x010
|
||||
#define PIN_PER_C 0x020
|
||||
#define PIN_PER_D 0x030
|
||||
#define PIN_PORT_MASK 0x0C0
|
||||
#define PIN_PORTA 0x000
|
||||
#define PIN_PORTB 0x040
|
||||
#define PIN_PORTC 0x080
|
||||
#define PIN_LOW 0x000
|
||||
#define PIN_HIGH 0x100
|
||||
|
||||
void configure_pins( uint32_t pins, uint16_t config );
|
||||
uint16_t getCurrent();
|
||||
|
||||
extern uint16_t Temperature ; // Raw temp reading
|
||||
extern uint16_t maxTemperature ; // Raw temp reading
|
||||
|
||||
#endif
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny <shadow@privy.de>
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* open9x is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "open9x.h"
|
||||
|
||||
#ifndef SIMU
|
||||
inline void board_init()
|
||||
{
|
||||
// Set up I/O port data directions and initial states
|
||||
DDRA = 0xff; PORTA = 0x00; // LCD data
|
||||
DDRB = 0x81; PORTB = 0x7e; //pullups keys+nc
|
||||
DDRC = 0x3e; PORTC = 0xc1; //pullups nc
|
||||
DDRD = 0x00; PORTD = 0xff; //pullups keys
|
||||
DDRE = (1<<OUT_E_BUZZER); PORTE = 0xff-(1<<OUT_E_BUZZER); //pullups + buzzer 0
|
||||
DDRF = 0x00; PORTF = 0x00; //anain
|
||||
DDRG = 0x14; PORTG = 0xfb; //pullups + SIM_CTL=1 = phonejack = ppm_in, Haptic output and off (0)
|
||||
|
||||
ADMUX=ADC_VREF_TYPE;
|
||||
ADCSRA=0x85; // ADC enabled, pre-scaler division=32 (no interrupt, no auto-triggering)
|
||||
|
||||
/**** Set up timer/counter 0 ****/
|
||||
#if defined (AUDIO)
|
||||
// TCNT0 10ms = 16MHz/1024/2(/78) periodic timer (for speaker tone generation)
|
||||
// Capture ISR 7812.5/second -- runs per-10ms code segment once every 78
|
||||
// cycles (9.984ms). Timer overflows at about 61Hz or once every 16ms.
|
||||
TCCR0 = (0b111 << CS00);// Norm mode, clk/1024
|
||||
OCR0 = 2;
|
||||
#else
|
||||
// TCNT0 10ms = 16MHz/1024/156 periodic timer (9.984ms)
|
||||
// (with 1:4 duty at 157 to average 10.0ms)
|
||||
// Timer overflows at about 61Hz or once every 16ms.
|
||||
TCCR0 = (0b111 << CS00);// Norm mode, clk/1024
|
||||
OCR0 = 156;
|
||||
#endif
|
||||
|
||||
TIMSK |= (1<<OCIE0) | (1<<TOIE0); // Enable Output-Compare and Overflow interrrupts
|
||||
/********************************/
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SIMU
|
||||
FORCEINLINE
|
||||
#endif
|
||||
uint8_t keyDown()
|
||||
{
|
||||
return (~PINB) & 0x7E;
|
||||
}
|
||||
|
||||
bool keyState(EnumKeys enuk)
|
||||
{
|
||||
uint8_t result = 0 ;
|
||||
|
||||
if (enuk < (int)DIM(keys))
|
||||
return keys[enuk].state() ? 1 : 0;
|
||||
|
||||
switch(enuk){
|
||||
case SW_ElevDR:
|
||||
result = PINE & (1<<INP_E_ElevDR);
|
||||
break;
|
||||
|
||||
#if defined(JETI) || defined(FRSKY) || defined(ARDUPILOT) || defined(NMEA) || defined(MAVLINK)
|
||||
case SW_AileDR:
|
||||
result = PINC & (1<<INP_C_AileDR); //shad974: rerouted inputs to free up UART0
|
||||
break;
|
||||
#else
|
||||
case SW_AileDR:
|
||||
result = PINE & (1<<INP_E_AileDR);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SW_RuddDR:
|
||||
result = PING & (1<<INP_G_RuddDR);
|
||||
break;
|
||||
// INP_G_ID1 INP_E_ID2
|
||||
// id0 0 1
|
||||
// id1 1 1
|
||||
// id2 1 0
|
||||
case SW_ID0:
|
||||
result = !(PING & (1<<INP_G_ID1));
|
||||
break;
|
||||
|
||||
case SW_ID1:
|
||||
result = (PING & (1<<INP_G_ID1)) && (PINE & (1<<INP_E_ID2));
|
||||
break;
|
||||
|
||||
case SW_ID2:
|
||||
result = !(PINE & (1<<INP_E_ID2));
|
||||
break;
|
||||
|
||||
case SW_Gear:
|
||||
result = PINE & (1<<INP_E_Gear);
|
||||
break;
|
||||
|
||||
//case SW_ThrCt : return PINE & (1<<INP_E_ThrCt);
|
||||
|
||||
#if defined(JETI) || defined(FRSKY) || defined(ARDUPILOT) || defined(NMEA) || defined(MAVLINK)
|
||||
case SW_ThrCt:
|
||||
result = PINC & (1<<INP_C_ThrCt); //shad974: rerouted inputs to free up UART0
|
||||
break;
|
||||
|
||||
#else
|
||||
case SW_ThrCt:
|
||||
result = PINE & (1<<INP_E_ThrCt);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SW_Trainer:
|
||||
result = PINE & (1<<INP_E_Trainer);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef SIMU
|
||||
FORCEINLINE
|
||||
#endif
|
||||
void readKeysAndTrims()
|
||||
{
|
||||
uint8_t enuk = KEY_MENU;
|
||||
|
||||
// User buttons ...
|
||||
uint8_t in = ~PINB;
|
||||
|
||||
for(int i=1; i<7; i++)
|
||||
{
|
||||
//INP_B_KEY_MEN 1 .. INP_B_KEY_LFT 6
|
||||
keys[enuk].input(in & (1<<i),(EnumKeys)enuk);
|
||||
++enuk;
|
||||
}
|
||||
|
||||
// Trim switches ...
|
||||
static const pm_uchar crossTrim[] PROGMEM ={
|
||||
1<<INP_D_TRM_LH_DWN, // bit 7
|
||||
1<<INP_D_TRM_LH_UP,
|
||||
1<<INP_D_TRM_LV_DWN,
|
||||
1<<INP_D_TRM_LV_UP,
|
||||
1<<INP_D_TRM_RV_DWN,
|
||||
1<<INP_D_TRM_RV_UP,
|
||||
1<<INP_D_TRM_RH_DWN,
|
||||
1<<INP_D_TRM_RH_UP // bit 0
|
||||
};
|
||||
|
||||
in = ~PIND;
|
||||
|
||||
for (int i=0; i<8; i++) {
|
||||
// INP_D_TRM_RH_UP 0 .. INP_D_TRM_LH_UP 7
|
||||
keys[enuk].input(in & pgm_read_byte(crossTrim+i),(EnumKeys)enuk);
|
||||
++enuk;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../opentx.h"
|
||||
#include <stdarg.h>
|
||||
#include "fifo.h"
|
||||
|
||||
#if !defined(SIMU)
|
||||
|
||||
Fifo<512> debugRxFifo;
|
||||
Fifo<512> debugTxFifo;
|
||||
|
||||
// Outputs a string to the UART
|
||||
void debugPuts(const char *format, ...)
|
||||
{
|
||||
va_list arglist;
|
||||
char tmp[256];
|
||||
|
||||
va_start(arglist, format);
|
||||
vsnprintf(tmp, 256, format, arglist);
|
||||
va_end(arglist);
|
||||
|
||||
const char *t = tmp;
|
||||
while (*t) {
|
||||
debugTxFifo.push(*t++);
|
||||
}
|
||||
}
|
||||
|
||||
void dump(unsigned char *data, unsigned int size)
|
||||
{
|
||||
debugPuts("DUMP %d bytes ...\n\r", size);
|
||||
unsigned int i = 0, j=0;
|
||||
while (i*32+j < size) {
|
||||
debugPuts("%.2X ", data[i*32+j]);
|
||||
j++;
|
||||
if (j==32) {
|
||||
i++; j=0;
|
||||
debugPuts("\n\r");
|
||||
}
|
||||
}
|
||||
debugPuts("\n\r");
|
||||
}
|
||||
|
||||
void debugTask(void* pdata)
|
||||
{
|
||||
uint8_t rxchar ;
|
||||
|
||||
for (;;) {
|
||||
while (!debugRxFifo.pop(rxchar))
|
||||
CoTickDelay(5); // 10ms
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void debugTx(void)
|
||||
{
|
||||
uint8_t txchar;
|
||||
|
||||
if (debugTxFifo.pop(txchar))
|
||||
debugPutc(txchar);
|
||||
}
|
||||
#endif
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef debug_h
|
||||
#define debug_h
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#if defined(SIMU)
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define TRACE_DEBUG(...) { printf("-D- " __VA_ARGS__); fflush(stdout); }
|
||||
#define TRACE_DEBUG_WP(...) { printf(__VA_ARGS__); fflush(stdout); }
|
||||
#define TRACE_INFO(...) { printf("-I- " __VA_ARGS__); fflush(stdout); }
|
||||
#define TRACE_INFO_WP(...) { printf(__VA_ARGS__); fflush(stdout); }
|
||||
#define TRACE_WARNING(...) { printf("-W- " __VA_ARGS__); fflush(stdout); }
|
||||
#define TRACE_WARNING_WP(...) { printf(__VA_ARGS__); fflush(stdout); }
|
||||
#define TRACE_ERROR(...) { printf("-E- " __VA_ARGS__); fflush(stdout); }
|
||||
inline void dump(unsigned char *data, unsigned int size)
|
||||
{
|
||||
printf("DUMP %d bytes ...\n\r", size);
|
||||
unsigned int i = 0, j=0;
|
||||
while (i*32+j < size) {
|
||||
printf("%.2X ", data[i*32+j]);
|
||||
j++;
|
||||
if (j==32) {
|
||||
i++; j=0;
|
||||
printf("\n\r");
|
||||
}
|
||||
}
|
||||
printf("\n\r");
|
||||
}
|
||||
#define DUMP(data, size) dump(data, size)
|
||||
|
||||
#elif defined(DEBUG) && defined(CPUARM)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void debugPutc(const char c);
|
||||
void debugPuts(const char *string, ...);
|
||||
void dump(unsigned char *data, unsigned int size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define TRACE_DEBUG(...) debugPuts("-D- " __VA_ARGS__)
|
||||
#define TRACE_DEBUG_WP(...) debugPuts(__VA_ARGS__)
|
||||
#define TRACE_INFO(...) debugPuts("-I- " __VA_ARGS__)
|
||||
#define TRACE_INFO_WP(...) debugPuts(__VA_ARGS__)
|
||||
#define TRACE_WARNING(...) debugPuts("-W- " __VA_ARGS__)
|
||||
#define TRACE_WARNING_WP(...) debugPuts(__VA_ARGS__)
|
||||
#define TRACE_ERROR(...) debugPuts("-E- " __VA_ARGS__)
|
||||
#define DUMP(data, size) dump(data, size)
|
||||
|
||||
void debugTask(void* pdata);
|
||||
void debugTx(void);
|
||||
|
||||
#else
|
||||
|
||||
#define TRACE_DEBUG(...) { }
|
||||
#define TRACE_DEBUG_WP(...) { }
|
||||
#define TRACE_INFO(...) { }
|
||||
#define TRACE_INFO_WP(...) { }
|
||||
#define TRACE_WARNING(...) { }
|
||||
#define TRACE_WARNING_WP(...) { }
|
||||
#define TRACE_ERROR(...) { }
|
||||
#define DUMP(...) { }
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny <shadow@privy.de>
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
@@ -14,7 +17,7 @@
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* open9x is based on code named
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
@@ -31,26 +34,35 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef RTC_H
|
||||
#define RTC_H
|
||||
#include <stdint.h>
|
||||
#include "opentx.h"
|
||||
#include "inttypes.h"
|
||||
#include "string.h"
|
||||
|
||||
#include "integer.h"
|
||||
uint8_t s_eeDirtyMsk;
|
||||
tmr10ms_t s_eeDirtyTime10ms;
|
||||
|
||||
typedef struct {
|
||||
WORD year; /* 2000..2099 */
|
||||
BYTE month; /* 1..12 */
|
||||
BYTE mday; /* 1.. 31 */
|
||||
BYTE wday; /* 1..7 */
|
||||
BYTE hour; /* 0..23 */
|
||||
BYTE min; /* 0..59 */
|
||||
BYTE sec; /* 0..59 */
|
||||
} RTC;
|
||||
void eeDirty(uint8_t msk)
|
||||
{
|
||||
s_eeDirtyMsk |= msk;
|
||||
s_eeDirtyTime10ms = get_tmr10ms() ;
|
||||
}
|
||||
|
||||
int iic_write (BYTE, UINT, UINT, const void*); /* Write to IIC device */
|
||||
int iic_read (BYTE, UINT, UINT, void*); /* Read from IIC device */
|
||||
#if defined(CPUARM)
|
||||
|
||||
int rtc_init (void); /* Initialize RTC */
|
||||
int rtc_gettime (RTC*); /* Get time */
|
||||
int rtc_settime (const RTC*); /* Set time */
|
||||
char modelNames[MAX_MODELS][sizeof(g_model.name)];
|
||||
|
||||
#if defined(PXX)
|
||||
uint8_t modelIds[MAX_MODELS];
|
||||
#endif
|
||||
|
||||
void eeLoadModelNames()
|
||||
{
|
||||
for (uint32_t i=0; i<MAX_MODELS; i++) {
|
||||
eeLoadModelName(i, modelNames[i]);
|
||||
#if defined(PXX)
|
||||
modelIds[i] = eeLoadModelId(i);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,11 +1,14 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny <shadow@privy.de>
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
@@ -14,7 +17,7 @@
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* open9x is based on code named
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
@@ -31,40 +34,39 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/*-------------------------------------------*/
|
||||
/* Integer type definitions for FatFs module */
|
||||
/*-------------------------------------------*/
|
||||
|
||||
#ifndef _INTEGER
|
||||
#define _INTEGER
|
||||
|
||||
#ifdef _WIN32 /* FatFs development platform */
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#else /* Embedded platform */
|
||||
|
||||
/* These types must be 16-bit, 32-bit or larger integer */
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
|
||||
/* These types must be 8-bit integer */
|
||||
typedef char CHAR;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef unsigned char BYTE;
|
||||
|
||||
/* These types must be 16-bit integer */
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned short WCHAR;
|
||||
|
||||
/* These types must be 32-bit integer */
|
||||
typedef long LONG;
|
||||
typedef unsigned long ULONG;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
#if defined(SIMU)
|
||||
#define WRITE_DELAY_10MS 200
|
||||
#elif defined(PCBTARANIS)
|
||||
#define WRITE_DELAY_10MS 500
|
||||
#elif defined(PCBSKY9X) && !defined(REV0)
|
||||
#define WRITE_DELAY_10MS 500
|
||||
#elif defined(PCBGRUVIN9X) && !defined(REV0)
|
||||
#define WRITE_DELAY_10MS 500
|
||||
#else
|
||||
#define WRITE_DELAY_10MS 200
|
||||
#endif
|
||||
|
||||
extern uint8_t s_eeDirtyMsk;
|
||||
extern tmr10ms_t s_eeDirtyTime10ms;
|
||||
|
||||
void eeDirty(uint8_t msk);
|
||||
void eeCheck(bool immediately=false);
|
||||
void eeReadAll();
|
||||
bool eeModelExists(uint8_t id);
|
||||
void eeLoadModelName(uint8_t id, char *name);
|
||||
void eeLoadModel(uint8_t id);
|
||||
|
||||
#if defined(CPUARM)
|
||||
|
||||
extern char modelNames[MAX_MODELS][sizeof(g_model.name)];
|
||||
void eeLoadModelNames();
|
||||
|
||||
#if defined(PXX)
|
||||
extern uint8_t modelIds[MAX_MODELS];
|
||||
#endif
|
||||
|
||||
#else // defined(CPUARM)
|
||||
|
||||
#define eeLoadModelNames()
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
PACK(typedef struct {
|
||||
uint8_t destCh;
|
||||
uint16_t phases;
|
||||
uint8_t curveMode:1; // O=curve, 1=differential
|
||||
uint8_t noExpo:1;
|
||||
int8_t carryTrim:3;
|
||||
uint8_t mltpx:2; // multiplex method: 0 means +=, 1 means *=, 2 means :=
|
||||
uint8_t spare:1;
|
||||
int8_t weight;
|
||||
int8_t swtch;
|
||||
int8_t curveParam;
|
||||
uint8_t mixWarn; // mixer warning
|
||||
uint8_t delayUp;
|
||||
uint8_t delayDown;
|
||||
uint8_t speedUp;
|
||||
uint8_t speedDown;
|
||||
uint8_t srcRaw;
|
||||
int8_t sOffset;
|
||||
char name[LEN_EXPOMIX_NAME];
|
||||
}) MixData_v212;
|
||||
|
||||
PACK(typedef struct {
|
||||
int8_t mode; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
|
||||
uint16_t val;
|
||||
}) TimerData_v212;
|
||||
|
||||
PACK(typedef struct {
|
||||
uint16_t persistent:1;
|
||||
uint16_t value:15;
|
||||
}) TimerDataExtra_v212;
|
||||
|
||||
PACK(typedef struct {
|
||||
FrSkyChannelData channels[2];
|
||||
FrSkyRSSIAlarm rssiAlarms[2];
|
||||
uint8_t usrProto; // Protocol in FrSky user data, 0=None, 1=FrSky hub, 2=WS HowHigh
|
||||
uint8_t voltsSource;
|
||||
uint8_t blades; // How many blades for RPMs, 0=2 blades, 1=3 blades
|
||||
uint8_t currentSource;
|
||||
FrSkyBarData bars[4];
|
||||
uint8_t lines[4*2*2];
|
||||
uint8_t varioSource;
|
||||
uint8_t varioCenterMin;
|
||||
uint8_t varioCenterMax;
|
||||
uint8_t spare[4];
|
||||
}) FrSkyData_v212;
|
||||
|
||||
PACK(typedef struct {
|
||||
char name[LEN_MODEL_NAME]; // must be first for eeLoadModelName
|
||||
TimerData_v212 timers[MAX_TIMERS];
|
||||
uint8_t protocol:3;
|
||||
uint8_t thrTrim:1; // Enable Throttle Trim
|
||||
int8_t ppmNCH:4;
|
||||
uint8_t trimInc:3; // Trim Increments
|
||||
uint8_t disableThrottleWarning:1;
|
||||
uint8_t pulsePol:1;
|
||||
uint8_t extendedLimits:1;
|
||||
uint8_t extendedTrims:1;
|
||||
uint8_t spare1:1;
|
||||
int8_t ppmDelay;
|
||||
BeepANACenter beepANACenter; // 1<<0->A1.. 1<<6->A7
|
||||
MixData_v212 mixData[MAX_MIXERS];
|
||||
LimitData limitData[NUM_CHNOUT];
|
||||
ExpoData expoData[MAX_EXPOS];
|
||||
|
||||
CURVTYPE curves[MAX_CURVES];
|
||||
int8_t points[NUM_POINTS];
|
||||
|
||||
CustomSwData customSw[NUM_CSW];
|
||||
CustomFnData funcSw[NUM_CFN];
|
||||
SwashRingData swashR;
|
||||
PhaseData phaseData[MAX_PHASES];
|
||||
|
||||
int8_t ppmFrameLength; // 0=22.5ms (10ms-30ms) 0.5ms increments
|
||||
uint8_t thrTraceSrc;
|
||||
uint8_t modelId;
|
||||
|
||||
uint8_t switchWarningStates;
|
||||
|
||||
FrSkyData_v212 frsky;
|
||||
|
||||
TimerDataExtra_v212 timersXtra[MAX_TIMERS];
|
||||
|
||||
}) ModelData_v212;
|
||||
|
||||
bool eeConvert()
|
||||
{
|
||||
if (g_eeGeneral.version == 212) {
|
||||
g_eeGeneral.optrexDisplay = 0;
|
||||
g_eeGeneral.backlightBright = 0;
|
||||
g_eeGeneral.contrast = 25;
|
||||
ALERT(STR_EEPROMWARN, PSTR("EEprom Data v212"), AU_BAD_EEPROM);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
MESSAGE(STR_EEPROMWARN, PSTR("EEPROM Converting"), NULL, AU_EEPROM_FORMATTING); // TODO translations
|
||||
|
||||
if (g_eeGeneral.version == 212) {
|
||||
memmove(((uint8_t*)&g_eeGeneral)+3, ((uint8_t*)&g_eeGeneral)+1, 81);
|
||||
g_eeGeneral.variant = 0;
|
||||
g_eeGeneral.version = 213;
|
||||
|
||||
Eeprom32_source_address = (uint8_t *)&g_eeGeneral ; // Get data from here
|
||||
Eeprom32_data_size = sizeof(g_eeGeneral) ; // This much
|
||||
Eeprom32_file_index = 0 ; // This file system entry
|
||||
Eeprom32_process_state = E32_BLANKCHECK ;
|
||||
eeWaitFinished();
|
||||
|
||||
for (uint8_t id=0; id<MAX_MODELS; id++) {
|
||||
uint16_t size = File_system[id+1].size;
|
||||
if (size >= 256) {
|
||||
ModelData_v212 oldModel;
|
||||
memset(&oldModel, 0, sizeof(oldModel));
|
||||
if (size > sizeof(oldModel)) {
|
||||
size = sizeof(oldModel) ;
|
||||
}
|
||||
read32_eeprom_data((File_system[id+1].block_no << 12) + sizeof(struct t_eeprom_header), (uint8_t *)&oldModel, size);
|
||||
|
||||
memcpy(g_model.name, oldModel.name, 10);
|
||||
for (uint8_t i=0; i<2; i++) {
|
||||
g_model.timers[i].mode = oldModel.timers[i].mode;
|
||||
g_model.timers[i].start = oldModel.timers[i].val;
|
||||
g_model.timers[i].persistent = oldModel.timersXtra[i].persistent;
|
||||
g_model.timers[i].value = oldModel.timersXtra[i].value;
|
||||
}
|
||||
g_model.protocol = oldModel.protocol;
|
||||
g_model.thrTrim = oldModel.thrTrim;
|
||||
g_model.ppmNCH = oldModel.ppmNCH;
|
||||
g_model.trimInc = oldModel.trimInc;
|
||||
g_model.disableThrottleWarning = oldModel.disableThrottleWarning;
|
||||
g_model.pulsePol = oldModel.pulsePol;
|
||||
g_model.extendedLimits = oldModel.extendedLimits;
|
||||
g_model.extendedTrims = oldModel.extendedTrims;
|
||||
g_model.ppmDelay = oldModel.ppmDelay;
|
||||
g_model.beepANACenter = oldModel.beepANACenter;
|
||||
for (uint8_t i=0; i<64; i++) {
|
||||
g_model.mixData[i].destCh = oldModel.mixData[i].destCh;
|
||||
g_model.mixData[i].phases = oldModel.mixData[i].phases;
|
||||
g_model.mixData[i].curveMode = oldModel.mixData[i].curveMode;
|
||||
g_model.mixData[i].noExpo = oldModel.mixData[i].noExpo;
|
||||
g_model.mixData[i].carryTrim = oldModel.mixData[i].carryTrim;
|
||||
g_model.mixData[i].mltpx = oldModel.mixData[i].mltpx;
|
||||
g_model.mixData[i].weight = oldModel.mixData[i].weight;
|
||||
g_model.mixData[i].swtch = oldModel.mixData[i].swtch;
|
||||
g_model.mixData[i].curveParam = oldModel.mixData[i].curveParam;
|
||||
g_model.mixData[i].mixWarn = oldModel.mixData[i].mixWarn;
|
||||
g_model.mixData[i].delayUp = oldModel.mixData[i].delayUp;
|
||||
g_model.mixData[i].delayDown = oldModel.mixData[i].delayDown;
|
||||
g_model.mixData[i].speedUp = oldModel.mixData[i].speedUp;
|
||||
g_model.mixData[i].speedDown = oldModel.mixData[i].speedDown;
|
||||
g_model.mixData[i].srcRaw = oldModel.mixData[i].srcRaw;
|
||||
g_model.mixData[i].offset = oldModel.mixData[i].sOffset;
|
||||
memcpy(g_model.mixData[i].name, oldModel.mixData[i].name, 6);
|
||||
}
|
||||
for (uint8_t i=0; i<32; i++) {
|
||||
g_model.limitData[i] = oldModel.limitData[i];
|
||||
}
|
||||
for (uint8_t i=0; i<32; i++) {
|
||||
g_model.expoData[i] = oldModel.expoData[i];
|
||||
}
|
||||
for (uint8_t i=0; i<16; i++) {
|
||||
g_model.curves[i] = oldModel.curves[i];
|
||||
}
|
||||
for (uint16_t i=0; i<512; i++) {
|
||||
g_model.points[i] = oldModel.points[i];
|
||||
}
|
||||
for (uint8_t i=0; i<32; i++) {
|
||||
g_model.customSw[i] = oldModel.customSw[i];
|
||||
}
|
||||
for (uint8_t i=0; i<32; i++) {
|
||||
g_model.funcSw[i] = oldModel.funcSw[i];
|
||||
}
|
||||
g_model.swashR = oldModel.swashR;
|
||||
for (uint8_t i=0; i<9; i++) {
|
||||
g_model.phaseData[i].swtch = oldModel.phaseData[i].swtch;
|
||||
g_model.phaseData[i].fadeIn = oldModel.phaseData[i].fadeIn;
|
||||
g_model.phaseData[i].fadeOut = oldModel.phaseData[i].fadeOut;
|
||||
memcpy(g_model.phaseData[i].name, oldModel.phaseData[i].name, 6);
|
||||
memcpy(g_model.phaseData[i].trim, oldModel.phaseData[i].trim, 4*sizeof(int16_t));
|
||||
memcpy(g_model.phaseData[i].rotaryEncoders, oldModel.phaseData[i].rotaryEncoders, 1*sizeof(int16_t));
|
||||
}
|
||||
g_model.ppmFrameLength = oldModel.ppmFrameLength;
|
||||
g_model.thrTraceSrc = oldModel.thrTraceSrc;
|
||||
g_model.modelId = oldModel.modelId;
|
||||
g_model.switchWarningStates = oldModel.switchWarningStates;
|
||||
g_model.frsky.usrProto = oldModel.frsky.usrProto;
|
||||
g_model.frsky.voltsSource = oldModel.frsky.voltsSource;
|
||||
g_model.frsky.blades = oldModel.frsky.blades;
|
||||
g_model.frsky.currentSource = oldModel.frsky.currentSource;
|
||||
g_model.frsky.varioSource = oldModel.frsky.varioSource;
|
||||
g_model.frsky.varioCenterMax = oldModel.frsky.varioCenterMax;
|
||||
g_model.frsky.varioCenterMin = oldModel.frsky.varioCenterMin;
|
||||
for (uint8_t i=0; i<2; i++) {
|
||||
g_model.frsky.channels[i] = oldModel.frsky.channels[i];
|
||||
g_model.frsky.rssiAlarms[i] = oldModel.frsky.rssiAlarms[i];
|
||||
}
|
||||
|
||||
Eeprom32_source_address = (uint8_t *)&g_model ; // Get data from here
|
||||
Eeprom32_data_size = sizeof(g_model) ; // This much
|
||||
Eeprom32_file_index = g_eeGeneral.currModel + 1 ; // This file system entry
|
||||
Eeprom32_process_state = E32_BLANKCHECK ;
|
||||
eeWaitFinished();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,7 +1,27 @@
|
||||
/*
|
||||
* Author - Erez Raviv <erezraviv@gmail.com>
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -14,18 +34,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include "open9x.h"
|
||||
#include "stdio.h"
|
||||
#include "opentx.h"
|
||||
#include "inttypes.h"
|
||||
#include "string.h"
|
||||
|
||||
volatile uint32_t Spi_complete ;
|
||||
uint8_t s_eeDirtyMsk;
|
||||
uint16_t s_eeDirtyTime10ms;
|
||||
volatile uint32_t Spi_complete; // TODO in the driver ?
|
||||
|
||||
// Logic for storing to EERPOM/loading from EEPROM
|
||||
// Logic for storing to EEPROM/loading from EEPROM
|
||||
// If main needs to wait for the eeprom, call mainsequence without actioning menus
|
||||
// General configuration
|
||||
// 'main' set flag STORE_GENERAL
|
||||
@@ -42,16 +58,14 @@ uint16_t s_eeDirtyTime10ms;
|
||||
|
||||
|
||||
// These may not be needed, or might just be smaller
|
||||
// TODO in the driver ?
|
||||
uint8_t Spi_tx_buf[24] ;
|
||||
uint8_t Spi_rx_buf[24] ;
|
||||
|
||||
|
||||
struct t_file_entry File_system[MAX_MODELS+1] ;
|
||||
|
||||
char ModelNames[MAX_MODELS][sizeof(g_model.name)] ; // Allow for general
|
||||
|
||||
// TODO check everything here
|
||||
uint8_t Eeprom32_process_state ;
|
||||
uint8_t Eeprom32_process_state = E32_IDLE;
|
||||
uint8_t Eeprom32_state_after_erase ;
|
||||
uint8_t Eeprom32_write_pending ;
|
||||
uint8_t Eeprom32_file_index ;
|
||||
@@ -62,19 +76,8 @@ uint32_t Eeprom32_data_size ;
|
||||
|
||||
#define EE_NOWAIT 1
|
||||
|
||||
void eeDirty(uint8_t msk)
|
||||
{
|
||||
s_eeDirtyMsk |= msk;
|
||||
s_eeDirtyTime10ms = get_tmr10ms() ;
|
||||
}
|
||||
|
||||
void handle_serial( void ) ;
|
||||
|
||||
uint32_t get_current_block_number( uint32_t block_no, uint16_t *p_size, uint32_t *p_seq ) ;
|
||||
void read32_eeprom_data( uint32_t eeAddress, register uint8_t *buffer, uint32_t size, uint32_t immediate=0 ) ;
|
||||
void write32_eeprom_block( uint32_t eeAddress, register uint8_t *buffer, uint32_t size, uint32_t immediate=0 ) ;
|
||||
void ee32_read_model_names( void ) ;
|
||||
void ee32LoadModelName(uint8_t id, char *buf, uint8_t len) ;
|
||||
|
||||
// New file system
|
||||
|
||||
@@ -87,16 +90,6 @@ void ee32LoadModelName(uint8_t id, char *buf, uint8_t len) ;
|
||||
uint8_t Current_general_block ; // 0 or 1 is active block
|
||||
uint8_t Other_general_block_blank ;
|
||||
|
||||
struct t_eeprom_header
|
||||
{
|
||||
uint32_t sequence_no ; // sequence # to decide which block is most recent
|
||||
uint16_t data_size ; // # bytes in data area
|
||||
uint8_t flags ;
|
||||
uint8_t hcsum ;
|
||||
} ;
|
||||
|
||||
#define EEPROM_BUFFER_SIZE ((sizeof(ModelData) + sizeof( struct t_eeprom_header ) + 3)/4)
|
||||
|
||||
struct t_eeprom_buffer
|
||||
{
|
||||
struct t_eeprom_header header ;
|
||||
@@ -104,17 +97,15 @@ struct t_eeprom_buffer
|
||||
{
|
||||
EEGeneral general_data ;
|
||||
ModelData model_data ;
|
||||
uint32_t words[ EEPROM_BUFFER_SIZE ] ;
|
||||
uint8_t bytes[4096-sizeof(t_eeprom_header)];
|
||||
} data ;
|
||||
} Eeprom_buffer ;
|
||||
|
||||
#define EEPROM_BUFFER_SIZE ((sizeof(ModelData) + sizeof( struct t_eeprom_header ) + 3)/4)
|
||||
|
||||
void eeDeleteModel(uint8_t id)
|
||||
{
|
||||
eeCheck(true);
|
||||
|
||||
memset(ModelNames[id], 0, sizeof(g_model.name));
|
||||
memset(modelNames[id], 0, sizeof(g_model.name));
|
||||
|
||||
Eeprom32_source_address = (uint8_t *)&g_model ; // Get data from here
|
||||
Eeprom32_data_size = 0 ; // This much
|
||||
@@ -131,9 +122,9 @@ bool eeCopyModel(uint8_t dst, uint8_t src)
|
||||
read32_eeprom_data( (File_system[src+1].block_no << 12) + sizeof( struct t_eeprom_header), ( uint8_t *)&Eeprom_buffer.data.model_data, size) ;
|
||||
|
||||
if (size > sizeof(g_model.name))
|
||||
memcpy(ModelNames[dst], Eeprom_buffer.data.model_data.name, sizeof(g_model.name));
|
||||
memcpy(modelNames[dst], Eeprom_buffer.data.model_data.name, sizeof(g_model.name));
|
||||
else
|
||||
memset(ModelNames[dst], 0, sizeof(g_model.name));
|
||||
memset(modelNames[dst], 0, sizeof(g_model.name));
|
||||
|
||||
Eeprom32_source_address = (uint8_t *)&Eeprom_buffer.data.model_data; // Get data from here
|
||||
Eeprom32_data_size = sizeof(g_model) ; // This much
|
||||
@@ -157,10 +148,10 @@ void eeSwapModels(uint8_t id1, uint8_t id2)
|
||||
// TODO flash saving with function above ...
|
||||
if (id2_size > sizeof(g_model.name)) {
|
||||
read32_eeprom_data( (id2_block_no << 12) + sizeof( struct t_eeprom_header), ( uint8_t *)&Eeprom_buffer.data.model_data, id2_size);
|
||||
memcpy(ModelNames[id1], Eeprom_buffer.data.model_data.name, sizeof(g_model.name));
|
||||
memcpy(modelNames[id1], Eeprom_buffer.data.model_data.name, sizeof(g_model.name));
|
||||
}
|
||||
else {
|
||||
memset(ModelNames[id1], 0, sizeof(g_model.name));
|
||||
memset(modelNames[id1], 0, sizeof(g_model.name));
|
||||
}
|
||||
|
||||
Eeprom32_source_address = (uint8_t *)&Eeprom_buffer.data.model_data; // Get data from here
|
||||
@@ -170,115 +161,8 @@ void eeSwapModels(uint8_t id1, uint8_t id2)
|
||||
eeWaitFinished();
|
||||
}
|
||||
|
||||
uint32_t spi_PDC_action( register uint8_t *command, register uint8_t *tx, register uint8_t *rx, register uint32_t comlen, register uint32_t count )
|
||||
{
|
||||
#ifndef SIMU
|
||||
|
||||
register Spi *spiptr ;
|
||||
register uint32_t condition ;
|
||||
static uint8_t discard_rx_command[4] ;
|
||||
|
||||
// PMC->PMC_PCER0 |= 0x00200000L ; // Enable peripheral clock to SPI
|
||||
|
||||
Spi_complete = 0 ;
|
||||
if ( comlen > 4 )
|
||||
{
|
||||
Spi_complete = 1 ;
|
||||
return 0x4FFFF ;
|
||||
}
|
||||
condition = SPI_SR_TXEMPTY ;
|
||||
spiptr = SPI ;
|
||||
spiptr->SPI_CR = 1 ; // Enable
|
||||
(void) spiptr->SPI_RDR ; // Dump any rx data
|
||||
(void) spiptr->SPI_SR ; // Clear error flags
|
||||
spiptr->SPI_RPR = (uint32_t)discard_rx_command ;
|
||||
spiptr->SPI_RCR = comlen ;
|
||||
if ( rx )
|
||||
{
|
||||
spiptr->SPI_RNPR = (uint32_t)rx ;
|
||||
spiptr->SPI_RNCR = count ;
|
||||
condition = SPI_SR_RXBUFF ;
|
||||
}
|
||||
spiptr->SPI_TPR = (uint32_t)command ;
|
||||
spiptr->SPI_TCR = comlen ;
|
||||
if ( tx )
|
||||
{
|
||||
spiptr->SPI_TNPR = (uint32_t)tx ;
|
||||
}
|
||||
else
|
||||
{
|
||||
spiptr->SPI_TNPR = (uint32_t)rx ;
|
||||
}
|
||||
spiptr->SPI_TNCR = count ;
|
||||
|
||||
spiptr->SPI_PTCR = SPI_PTCR_RXTEN | SPI_PTCR_TXTEN ; // Start transfers
|
||||
|
||||
// Wait for things to get started, avoids early interrupt
|
||||
for ( count = 0 ; count < 1000 ; count += 1 )
|
||||
{
|
||||
if ( ( spiptr->SPI_SR & SPI_SR_TXEMPTY ) == 0 )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
}
|
||||
spiptr->SPI_IER = condition ;
|
||||
|
||||
#endif
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
uint32_t eeprom_write_one( uint8_t byte, uint8_t count )
|
||||
{
|
||||
#ifndef SIMU
|
||||
register Spi *spiptr;
|
||||
register uint32_t result;
|
||||
|
||||
spiptr = SPI;
|
||||
spiptr->SPI_CR = 1; // Enable
|
||||
(void) spiptr->SPI_RDR; // Dump any rx data
|
||||
|
||||
spiptr->SPI_TDR = byte;
|
||||
|
||||
result = 0;
|
||||
while ((spiptr->SPI_SR & SPI_SR_RDRF) == 0) {
|
||||
// wait for received
|
||||
if (++result > 10000) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (count == 0) {
|
||||
spiptr->SPI_CR = 2; // Disable
|
||||
return spiptr->SPI_RDR;
|
||||
}
|
||||
(void) spiptr->SPI_RDR; // Dump the rx data
|
||||
spiptr->SPI_TDR = 0;
|
||||
result = 0;
|
||||
while ((spiptr->SPI_SR & SPI_SR_RDRF) == 0) {
|
||||
// wait for received
|
||||
if (++result > 10000) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
spiptr->SPI_CR = 2; // Disable
|
||||
return spiptr->SPI_RDR ;
|
||||
#else
|
||||
return !Spi_complete;
|
||||
#endif
|
||||
}
|
||||
|
||||
void eeprom_write_enable()
|
||||
{
|
||||
eeprom_write_one( 6, 0 ) ;
|
||||
}
|
||||
|
||||
uint32_t eeprom_read_status()
|
||||
{
|
||||
return eeprom_write_one( 5, 1 ) ;
|
||||
}
|
||||
|
||||
// Read eeprom data starting at random address
|
||||
void read32_eeprom_data( uint32_t eeAddress, register uint8_t *buffer, uint32_t size, uint32_t immediate )
|
||||
void read32_eeprom_data(uint32_t eeAddress, register uint8_t *buffer, uint32_t size, uint32_t immediate)
|
||||
{
|
||||
#ifdef SIMU
|
||||
assert(size);
|
||||
@@ -287,7 +171,7 @@ void read32_eeprom_data( uint32_t eeAddress, register uint8_t *buffer, uint32_t
|
||||
eeprom_buffer_size = size;
|
||||
eeprom_read_operation = true;
|
||||
Spi_complete = false;
|
||||
sem_post(&eeprom_write_sem);
|
||||
sem_post(eeprom_write_sem);
|
||||
#else
|
||||
register uint8_t *p = Spi_tx_buf ;
|
||||
*p = 3 ; // Read command
|
||||
@@ -316,7 +200,7 @@ void write32_eeprom_block( uint32_t eeAddress, register uint8_t *buffer, uint32_
|
||||
eeprom_buffer_size = size+1;
|
||||
eeprom_read_operation = false;
|
||||
Spi_complete = false;
|
||||
sem_post(&eeprom_write_sem);
|
||||
sem_post(eeprom_write_sem);
|
||||
#else
|
||||
eeprom_write_enable();
|
||||
|
||||
@@ -433,11 +317,9 @@ uint32_t get_current_block_number( uint32_t block_no, uint16_t *p_size, uint32_t
|
||||
return block_no ;
|
||||
}
|
||||
|
||||
bool ee32LoadGeneral()
|
||||
bool eeLoadGeneral()
|
||||
{
|
||||
uint16_t size ;
|
||||
|
||||
size = File_system[0].size ;
|
||||
uint16_t size = File_system[0].size;
|
||||
|
||||
memset(&g_eeGeneral, 0, sizeof(EEGeneral));
|
||||
|
||||
@@ -449,17 +331,19 @@ bool ee32LoadGeneral()
|
||||
read32_eeprom_data( ( File_system[0].block_no << 12) + sizeof( struct t_eeprom_header), ( uint8_t *)&g_eeGeneral, size) ;
|
||||
}
|
||||
|
||||
if (g_eeGeneral.myVers == EEPROM_VER) {
|
||||
uint16_t sum = evalChkSum();
|
||||
if (g_eeGeneral.chkSum == sum) {
|
||||
return true;
|
||||
}
|
||||
if (g_eeGeneral.version != EEPROM_VER) {
|
||||
if (!eeConvert())
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t sum = evalChkSum();
|
||||
if (g_eeGeneral.chkSum == sum) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef SIMU
|
||||
else {
|
||||
printf("EEPROM version %d instead of %d\n", g_eeGeneral.myVers, EEPROM_VER);
|
||||
fflush(stdout);
|
||||
}
|
||||
printf("EEPROM version %d (%d) instead of %d (%d)\n", g_eeGeneral.version, g_eeGeneral.variant, EEPROM_VER, EEPROM_VARIANT);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
return false;
|
||||
@@ -467,15 +351,23 @@ bool ee32LoadGeneral()
|
||||
|
||||
void eeLoadModel(uint8_t id)
|
||||
{
|
||||
uint16_t size ;
|
||||
|
||||
if (id<MAX_MODELS) {
|
||||
|
||||
size = File_system[id+1].size ;
|
||||
#if defined(SDCARD)
|
||||
closeLogs();
|
||||
#endif
|
||||
|
||||
if (pulsesStarted()) {
|
||||
pausePulses();
|
||||
}
|
||||
|
||||
pauseMixerCalculations();
|
||||
|
||||
uint16_t size = File_system[id+1].size ;
|
||||
|
||||
memset(&g_model, 0, sizeof(g_model));
|
||||
|
||||
#ifdef SIMU
|
||||
#if defined(SIMU)
|
||||
if (size > 0 && size != sizeof(g_model)) {
|
||||
printf("Model data read=%d bytes vs %d bytes\n", size, (int)sizeof(ModelData));
|
||||
}
|
||||
@@ -484,21 +376,47 @@ void eeLoadModel(uint8_t id)
|
||||
if (size > sizeof(g_model)) {
|
||||
size = sizeof(g_model) ;
|
||||
}
|
||||
|
||||
|
||||
if(size < 256) { // if not loaded a fair amount
|
||||
modelDefault(id) ;
|
||||
eeCheck(true);
|
||||
}
|
||||
else {
|
||||
read32_eeprom_data( ( File_system[id+1].block_no << 12) + sizeof( struct t_eeprom_header), ( uint8_t *)&g_model, size) ;
|
||||
read32_eeprom_data((File_system[id+1].block_no << 12) + sizeof(struct t_eeprom_header), (uint8_t *)&g_model, size) ;
|
||||
}
|
||||
|
||||
resetProto();
|
||||
resetAll();
|
||||
|
||||
#if defined(SDCARD) && defined(PCBV4)
|
||||
initLogs();
|
||||
if (pulsesStarted()) {
|
||||
checkAll();
|
||||
resumePulses();
|
||||
}
|
||||
|
||||
activeSwitches = 0;
|
||||
activeFnSwitches = 0;
|
||||
activeFunctions = 0;
|
||||
memclear(lastFunctionTime, sizeof(lastFunctionTime));
|
||||
|
||||
for (uint8_t i=0; i<MAX_TIMERS; i++) {
|
||||
if (g_model.timers[i].persistent) {
|
||||
s_timerVal[i] = g_model.timers[i].value;
|
||||
}
|
||||
}
|
||||
|
||||
resumeMixerCalculations();
|
||||
// TODO pulses should be started after mixer calculations ...
|
||||
|
||||
#if defined(FRSKY)
|
||||
frskySendAlarms();
|
||||
#endif
|
||||
|
||||
#if defined(CPUARM) && defined(SDCARD)
|
||||
refreshModelAudioFiles();
|
||||
#endif
|
||||
|
||||
LOAD_MODEL_BITMAP();
|
||||
|
||||
SEND_FAILSAFE_1S();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -507,165 +425,71 @@ bool eeModelExists(uint8_t id)
|
||||
return ( File_system[id+1].size > 0 ) ;
|
||||
}
|
||||
|
||||
void ee32LoadModelName(uint8_t id, char *buf, uint8_t len)
|
||||
void eeLoadModelName(uint8_t id, char *name)
|
||||
{
|
||||
memclear(name, sizeof(g_model.name));
|
||||
if (id < MAX_MODELS) {
|
||||
id += 1;
|
||||
memset(buf, 0, len);
|
||||
if (File_system[id].size > sizeof(g_model.name) ) {
|
||||
read32_eeprom_data( ( File_system[id].block_no << 12) + 8, ( uint8_t *)buf, sizeof(g_model.name)) ;
|
||||
read32_eeprom_data( ( File_system[id].block_no << 12) + 8, ( uint8_t *)name, sizeof(g_model.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(PXX)
|
||||
uint8_t eeLoadModelId(uint8_t id)
|
||||
{
|
||||
uint8_t modelId = 0;
|
||||
if (id < MAX_MODELS) {
|
||||
id += 1;
|
||||
if (File_system[id].size > sizeof(g_model.name) + 1) {
|
||||
read32_eeprom_data( ( File_system[id].block_no << 12) + 8 + sizeof(g_model.name), &modelId, 1);
|
||||
}
|
||||
}
|
||||
return modelId;
|
||||
}
|
||||
#endif
|
||||
|
||||
void fill_file_index()
|
||||
{
|
||||
for (uint32_t i = 0 ; i < MAX_MODELS + 1 ; i += 1 )
|
||||
{
|
||||
File_system[i].block_no = get_current_block_number( i * 2, &File_system[i].size, &File_system[i].sequence_no ) ;
|
||||
}
|
||||
}
|
||||
|
||||
void eeReadAll()
|
||||
{
|
||||
if (!ee32LoadGeneral() )
|
||||
fill_file_index() ;
|
||||
|
||||
if (!eeLoadGeneral() )
|
||||
{
|
||||
generalDefault();
|
||||
|
||||
alert(STR_EEPROMWARN, STR_BADEEPROMDATA);
|
||||
message(STR_EEPROMWARN, STR_EEPROMFORMATTING, NULL);
|
||||
|
||||
modelDefault(0);
|
||||
|
||||
if (check_soft_power() < e_power_usb) { // Usb on or power off
|
||||
/* we remove all models */
|
||||
for (uint32_t i=0; i<MAX_MODELS; i++)
|
||||
eeDeleteModel(i);
|
||||
ALERT(STR_EEPROMWARN, STR_BADEEPROMDATA, AU_BAD_EEPROM);
|
||||
|
||||
STORE_GENERALVARS;
|
||||
STORE_MODELVARS;
|
||||
if (pwrCheck() == e_power_off) {
|
||||
// the radio has been powered off during the ALERT
|
||||
pwrOff(); // turn power off now
|
||||
}
|
||||
|
||||
MESSAGE(STR_EEPROMWARN, STR_EEPROMFORMATTING, NULL, AU_EEPROM_FORMATTING);
|
||||
|
||||
/* we remove all models */
|
||||
for (uint32_t i=0; i<MAX_MODELS; i++)
|
||||
eeDeleteModel(i);
|
||||
|
||||
STORE_GENERALVARS;
|
||||
STORE_MODELVARS;
|
||||
}
|
||||
else
|
||||
{
|
||||
eeLoadModel(g_eeGeneral.currModel);
|
||||
ee32_read_model_names() ;
|
||||
else {
|
||||
eeLoadModelNames() ;
|
||||
}
|
||||
|
||||
stickMode = g_eeGeneral.stickMode; // TODO common!
|
||||
}
|
||||
|
||||
uint32_t spi_operation( register uint8_t *tx, register uint8_t *rx, register uint32_t count )
|
||||
{
|
||||
register Spi *spiptr;
|
||||
register uint32_t result;
|
||||
|
||||
// PMC->PMC_PCER0 |= 0x00200000L ; // Enable peripheral clock to SPI
|
||||
|
||||
result = 0;
|
||||
spiptr = SPI;
|
||||
spiptr->SPI_CR = 1; // Enable
|
||||
(void) spiptr->SPI_RDR; // Dump any rx data
|
||||
while (count) {
|
||||
result = 0;
|
||||
while ((spiptr->SPI_SR & SPI_SR_TXEMPTY) == 0) {
|
||||
// wait
|
||||
if (++result > 10000) {
|
||||
result = 0xFFFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result > 10000) {
|
||||
break;
|
||||
}
|
||||
// if ( count == 1 )
|
||||
// {
|
||||
// spiptr->SPI_CR = SPI_CR_LASTXFER ; // LastXfer bit
|
||||
// }
|
||||
spiptr->SPI_TDR = *tx++;
|
||||
result = 0;
|
||||
while ((spiptr->SPI_SR & SPI_SR_RDRF) == 0) {
|
||||
// wait for received
|
||||
if (++result > 10000) {
|
||||
result = 0x2FFFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result > 10000) {
|
||||
break;
|
||||
}
|
||||
*rx++ = spiptr->SPI_RDR;
|
||||
count -= 1;
|
||||
}
|
||||
if (result <= 10000) {
|
||||
result = 0;
|
||||
}
|
||||
spiptr->SPI_CR = 2; // Disable
|
||||
|
||||
// Power save
|
||||
// PMC->PMC_PCER0 &= ~0x00200000L ; // Disable peripheral clock to SPI
|
||||
|
||||
return result ;
|
||||
}
|
||||
|
||||
// SPI i/f to EEPROM (4Mb)
|
||||
// Peripheral ID 21 (0x00200000)
|
||||
// Connections:
|
||||
// SS PA11 (peripheral A)
|
||||
// MISO PA12 (peripheral A)
|
||||
// MOSI PA13 (peripheral A)
|
||||
// SCK PA14 (peripheral A)
|
||||
// Set clock to 3 MHz, AT25 device is rated to 70MHz, 18MHz would be better
|
||||
void init_spi()
|
||||
{
|
||||
register Spi *spiptr ;
|
||||
register uint32_t timer ;
|
||||
register uint8_t *p ;
|
||||
uint8_t spi_buf[4] ;
|
||||
|
||||
PMC->PMC_PCER0 |= 0x00200000L ; // Enable peripheral clock to SPI
|
||||
/* Configure PIO */
|
||||
configure_pins( 0x00007800, PIN_PERIPHERAL | PIN_INPUT | PIN_PER_A | PIN_PORTA | PIN_NO_PULLUP ) ;
|
||||
|
||||
spiptr = SPI ;
|
||||
timer = ( Master_frequency / 3000000 ) << 8 ; // Baud rate 3Mb/s
|
||||
spiptr->SPI_MR = 0x14000011 ; // 0001 0100 0000 0000 0000 0000 0001 0001 Master
|
||||
spiptr->SPI_CSR[0] = 0x01180009 | timer ; // 0000 0001 0001 1000 xxxx xxxx 0000 1001
|
||||
NVIC_EnableIRQ(SPI_IRQn) ;
|
||||
|
||||
p = spi_buf ;
|
||||
|
||||
// *p = 0x39 ; // Unprotect sector command
|
||||
// *(p+1) = 0 ;
|
||||
// *(p+2) = 0 ;
|
||||
// *(p+3) = 0 ; // 3 bytes address
|
||||
|
||||
// spi_operation( p, spi_buf, 4 ) ;
|
||||
|
||||
eeprom_write_enable() ;
|
||||
|
||||
*p = 1 ; // Write status register command
|
||||
*(p+1) = 0 ;
|
||||
spi_operation( p, spi_buf, 2 ) ;
|
||||
}
|
||||
|
||||
#ifndef SIMU
|
||||
extern "C" void SPI_IRQHandler()
|
||||
{
|
||||
register Spi *spiptr ;
|
||||
|
||||
spiptr = SPI ;
|
||||
SPI->SPI_IDR = 0x07FF ; // All interrupts off
|
||||
spiptr->SPI_CR = 2 ; // Disable
|
||||
(void) spiptr->SPI_RDR ; // Dump any rx data
|
||||
(void) spiptr->SPI_SR ; // Clear error flags
|
||||
spiptr->SPI_PTCR = SPI_PTCR_RXTDIS | SPI_PTCR_TXTDIS ; // Stop tramsfers
|
||||
Spi_complete = 1 ; // Indicate completion
|
||||
|
||||
// Power save
|
||||
// PMC->PMC_PCER0 &= ~0x00200000L ; // Disable peripheral clock to SPI
|
||||
}
|
||||
#endif
|
||||
|
||||
void end_spi()
|
||||
{
|
||||
SPI->SPI_CR = 2 ; // Disable
|
||||
SPI->SPI_IDR = 0x07FF ; // All interrupts off
|
||||
NVIC_DisableIRQ(SPI_IRQn) ;
|
||||
}
|
||||
|
||||
void eeWaitFinished()
|
||||
{
|
||||
while (Eeprom32_process_state != E32_IDLE) {
|
||||
@@ -673,7 +497,6 @@ void eeWaitFinished()
|
||||
#ifdef SIMU
|
||||
sleep(5/*ms*/);
|
||||
#endif
|
||||
// TODO perMain()?
|
||||
}
|
||||
}
|
||||
|
||||
@@ -775,7 +598,6 @@ void ee32_process()
|
||||
p = Eeprom32_source_address;
|
||||
q = (uint8_t *) &Eeprom_buffer.data;
|
||||
if (p != q) {
|
||||
// TODO why not memcpy
|
||||
for (x = 0; x < Eeprom32_data_size; x += 1) {
|
||||
*q++ = *p++; // Copy the data to temp buffer
|
||||
}
|
||||
@@ -793,7 +615,7 @@ void ee32_process()
|
||||
p += x; // Add offset
|
||||
x = total_size % 256; // Size of last bit
|
||||
if (x == 0) // Last bit empty
|
||||
{
|
||||
{
|
||||
x = 256;
|
||||
p -= x;
|
||||
eeAddress -= x;
|
||||
@@ -864,49 +686,7 @@ void ee32_process()
|
||||
}
|
||||
}
|
||||
|
||||
void fill_file_index()
|
||||
{
|
||||
for (uint32_t i = 0 ; i < MAX_MODELS + 1 ; i += 1 )
|
||||
{
|
||||
File_system[i].block_no = get_current_block_number( i * 2, &File_system[i].size, &File_system[i].sequence_no ) ;
|
||||
}
|
||||
}
|
||||
|
||||
void ee32_read_model_names()
|
||||
{
|
||||
for (uint32_t i=0; i<MAX_MODELS; i++)
|
||||
{
|
||||
ee32LoadModelName(i, ModelNames[i], sizeof(g_model.name));
|
||||
}
|
||||
}
|
||||
|
||||
void eeprom_init()
|
||||
{
|
||||
#ifndef SIMU
|
||||
init_spi() ;
|
||||
#endif
|
||||
fill_file_index() ;
|
||||
Eeprom32_process_state = E32_IDLE ;
|
||||
}
|
||||
|
||||
uint32_t unprotect_eeprom()
|
||||
{
|
||||
register uint8_t *p;
|
||||
|
||||
eeprom_write_enable();
|
||||
|
||||
p = Spi_tx_buf;
|
||||
*p = 0x39; // Unprotect sector command
|
||||
*(p + 1) = 0;
|
||||
*(p + 2) = 0;
|
||||
*(p + 3) = 0; // 3 bytes address
|
||||
|
||||
return spi_operation( p, Spi_rx_buf, 4 ) ;
|
||||
}
|
||||
|
||||
#if defined(SDCARD)
|
||||
FATFS g_FATFS_Obj; // TODO not here
|
||||
#define FILENAME_MAXLEN 8
|
||||
const pm_char * eeBackupModel(uint8_t i_fileSrc)
|
||||
{
|
||||
char *buf = reusableBuffer.models.mainname;
|
||||
@@ -914,67 +694,52 @@ const pm_char * eeBackupModel(uint8_t i_fileSrc)
|
||||
DIR archiveFolder;
|
||||
UINT written;
|
||||
|
||||
FRESULT result = f_mount(0, &g_FATFS_Obj);
|
||||
if (result != FR_OK) {
|
||||
return SDCARD_ERROR(result);
|
||||
if (!sdMounted()) {
|
||||
return STR_NO_SDCARD;
|
||||
}
|
||||
|
||||
// check and create folder here
|
||||
strcpy(buf, STR_MODELS_PATH);
|
||||
result = f_opendir(&archiveFolder, buf);
|
||||
FRESULT result = f_opendir(&archiveFolder, buf);
|
||||
if (result != FR_OK) {
|
||||
result = f_mkdir(buf);
|
||||
if (result == FR_NO_PATH)
|
||||
result = f_mkdir(buf);
|
||||
if (result != FR_OK)
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
|
||||
buf[sizeof(MODELS_PATH)-1] = '/';
|
||||
memcpy(&buf[sizeof(MODELS_PATH)], ModelNames[i_fileSrc], sizeof(g_model.name));
|
||||
buf[sizeof(MODELS_PATH)+FILENAME_MAXLEN] = '\0';
|
||||
strcpy(strcat_modelname(&buf[sizeof(MODELS_PATH)], i_fileSrc), STR_MODELS_EXT);
|
||||
|
||||
uint8_t i = sizeof(MODELS_PATH)+FILENAME_MAXLEN-1;
|
||||
uint8_t len = 0;
|
||||
while (i>sizeof(MODELS_PATH)-1) {
|
||||
if (!len && buf[i])
|
||||
len = i+1;
|
||||
if (len) {
|
||||
if (buf[i])
|
||||
buf[i] = idx2char(buf[i]);
|
||||
else
|
||||
buf[i] = '_';
|
||||
}
|
||||
i--;
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
uint8_t num = i_fileSrc + 1;
|
||||
strcpy(&buf[sizeof(MODELS_PATH)], STR_MODEL);
|
||||
buf[sizeof(MODELS_PATH) + PSIZE(TR_MODEL)] = (char)((num / 10) + '0');
|
||||
buf[sizeof(MODELS_PATH) + PSIZE(TR_MODEL) + 1] = (char)((num % 10) + '0');
|
||||
len = sizeof(MODELS_PATH) + PSIZE(TR_MODEL) + 2;
|
||||
}
|
||||
|
||||
strcpy(&buf[len], STR_MODELS_EXT);
|
||||
|
||||
result = f_open(&archiveFile, buf, FA_OPEN_ALWAYS | FA_WRITE);
|
||||
result = f_open(&archiveFile, buf, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
if (result != FR_OK) {
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
|
||||
result = f_write(&archiveFile, &g_eeGeneral.myVers, 1, &written);
|
||||
if (result != FR_OK) {
|
||||
strcpy(statusLineMsg, PSTR("File "));
|
||||
strcpy(statusLineMsg+5, &buf[sizeof(MODELS_PATH)]);
|
||||
|
||||
uint16_t size = File_system[i_fileSrc+1].size;
|
||||
|
||||
*(uint32_t*)&buf[0] = O9X_FOURCC;
|
||||
buf[4] = g_eeGeneral.version;
|
||||
buf[5] = 'M';
|
||||
*(uint16_t*)&buf[6] = size;
|
||||
|
||||
result = f_write(&archiveFile, buf, 8, &written);
|
||||
if (result != FR_OK || written != 8) {
|
||||
f_close(&archiveFile);
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
|
||||
uint16_t size = File_system[i_fileSrc].size ;
|
||||
read32_eeprom_data( (File_system[i_fileSrc+1].block_no << 12) + sizeof( struct t_eeprom_header), ( uint8_t *)&Eeprom_buffer.data.model_data, size) ;
|
||||
|
||||
result = f_write(&archiveFile, (uint8_t *)&Eeprom_buffer.data.model_data, size, &written);
|
||||
if (result != FR_OK) {
|
||||
f_close(&archiveFile);
|
||||
if (result != FR_OK || written != size) {
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
|
||||
f_close(&archiveFile);
|
||||
showStatusLine();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -985,9 +750,8 @@ const pm_char * eeRestoreModel(uint8_t i_fileDst, char *model_name)
|
||||
FIL restoreFile;
|
||||
UINT read;
|
||||
|
||||
FRESULT result = f_mount(0, &g_FATFS_Obj);
|
||||
if (result != FR_OK) {
|
||||
return SDCARD_ERROR(result);
|
||||
if (!sdMounted()) {
|
||||
return STR_NO_SDCARD;
|
||||
}
|
||||
|
||||
strcpy(buf, STR_MODELS_PATH);
|
||||
@@ -995,41 +759,51 @@ const pm_char * eeRestoreModel(uint8_t i_fileDst, char *model_name)
|
||||
strcpy(&buf[sizeof(MODELS_PATH)], model_name);
|
||||
strcpy(&buf[strlen(buf)], STR_MODELS_EXT);
|
||||
|
||||
result = f_open(&restoreFile, buf, FA_OPEN_EXISTING | FA_READ);
|
||||
FRESULT result = f_open(&restoreFile, buf, FA_OPEN_EXISTING | FA_READ);
|
||||
if (result != FR_OK) {
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
|
||||
result = f_read(&restoreFile, (uint8_t *)buf, 1, &read);
|
||||
if (result != FR_OK || read != 1) {
|
||||
if (f_size(&restoreFile) < 8) {
|
||||
f_close(&restoreFile);
|
||||
return STR_INCOMPATIBLE;
|
||||
}
|
||||
|
||||
result = f_read(&restoreFile, (uint8_t *)buf, 8, &read);
|
||||
if (result != FR_OK || read != 8) {
|
||||
f_close(&restoreFile);
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
|
||||
if (buf[0] != g_eeGeneral.myVers) {
|
||||
// TODO
|
||||
if (*(uint32_t*)&buf[0] != O9X_FOURCC || (uint8_t)buf[4] != EEPROM_VER || buf[5] != 'M') {
|
||||
f_close(&restoreFile);
|
||||
return STR_INCOMPATIBLE;
|
||||
}
|
||||
|
||||
uint16_t size = max((uint16_t)sizeof(g_model), *(uint16_t*)&buf[6]);
|
||||
|
||||
if (eeModelExists(i_fileDst)) {
|
||||
eeDeleteModel(i_fileDst);
|
||||
}
|
||||
|
||||
result = f_read(&restoreFile, ( uint8_t *)&Eeprom_buffer.data.model_data, sizeof(g_model), &read);
|
||||
memset((uint8_t *)&Eeprom_buffer.data.model_data, 0, sizeof(g_model));
|
||||
result = f_read(&restoreFile, ( uint8_t *)&Eeprom_buffer.data.model_data, size, &read);
|
||||
f_close(&restoreFile);
|
||||
|
||||
if (result != FR_OK) {
|
||||
return SDCARD_ERROR(result);
|
||||
if (result != FR_OK || read != read) {
|
||||
return STR_INCOMPATIBLE;
|
||||
}
|
||||
|
||||
// TODO flash saving ...
|
||||
if (read > sizeof(g_model.name))
|
||||
memcpy(ModelNames[i_fileDst], Eeprom_buffer.data.model_data.name, sizeof(g_model.name));
|
||||
memcpy(modelNames[i_fileDst], Eeprom_buffer.data.model_data.name, sizeof(g_model.name));
|
||||
else
|
||||
memset(ModelNames[i_fileDst], 0, sizeof(g_model.name));
|
||||
memset(modelNames[i_fileDst], 0, sizeof(g_model.name));
|
||||
|
||||
Eeprom32_source_address = (uint8_t *)&Eeprom_buffer.data.model_data; // Get data from here
|
||||
Eeprom32_data_size = sizeof(g_model) ; // This much
|
||||
Eeprom32_file_index = i_fileDst + 1 ; // This file system entry
|
||||
Eeprom32_process_state = E32_BLANKCHECK ;
|
||||
Eeprom32_data_size = sizeof(g_model); // This much
|
||||
Eeprom32_file_index = i_fileDst + 1; // This file system entry
|
||||
Eeprom32_process_state = E32_BLANKCHECK;
|
||||
eeWaitFinished();
|
||||
|
||||
return NULL;
|
||||
@@ -1,7 +1,27 @@
|
||||
/*
|
||||
* Author - Erez Raviv <erezraviv@gmail.com>
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@@ -20,15 +40,6 @@
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef REV0
|
||||
#define WRITE_DELAY_10MS 100
|
||||
#else
|
||||
#define WRITE_DELAY_10MS 500
|
||||
#endif
|
||||
|
||||
extern uint8_t s_eeDirtyMsk;
|
||||
extern uint16_t s_eeDirtyTime10ms;
|
||||
|
||||
// States in Eeprom32_process_state
|
||||
#define E32_IDLE 1
|
||||
#define E32_ERASESENDING 2
|
||||
@@ -40,12 +51,14 @@ extern uint16_t s_eeDirtyTime10ms;
|
||||
#define E32_BLANKCHECK 8
|
||||
#define E32_WRITESTART 9
|
||||
extern uint8_t Eeprom32_process_state ;
|
||||
extern uint8_t *Eeprom32_source_address ;
|
||||
extern uint8_t Eeprom32_file_index ;
|
||||
extern uint32_t Eeprom32_data_size ;
|
||||
|
||||
extern void eeprom_init( void ) ;
|
||||
extern void end_spi(); // TODO not public
|
||||
extern void ee32_process( void ) ;
|
||||
extern bool ee32LoadGeneral( void ) ;
|
||||
|
||||
extern bool eeLoadGeneral( void ) ;
|
||||
extern bool eeConvert();
|
||||
extern void eeWaitFinished();
|
||||
|
||||
extern void eeDeleteModel( uint8_t id ) ;
|
||||
@@ -53,19 +66,29 @@ extern bool eeModelExists(uint8_t id) ;
|
||||
extern bool eeCopyModel(uint8_t dst, uint8_t src);
|
||||
extern void eeSwapModels(uint8_t id1, uint8_t id2);
|
||||
|
||||
#if defined(PXX)
|
||||
uint8_t eeLoadModelId(uint8_t id);
|
||||
#endif
|
||||
|
||||
#define DISPLAY_PROGRESS_BAR(x)
|
||||
|
||||
struct t_file_entry
|
||||
{
|
||||
uint32_t block_no ;
|
||||
uint32_t sequence_no ;
|
||||
uint16_t size ;
|
||||
uint8_t flags ;
|
||||
uint32_t block_no ;
|
||||
uint32_t sequence_no ;
|
||||
uint16_t size ;
|
||||
uint8_t flags ;
|
||||
} ;
|
||||
|
||||
struct t_eeprom_header
|
||||
{
|
||||
uint32_t sequence_no ; // sequence # to decide which block is most recent
|
||||
uint16_t data_size ; // # bytes in data area
|
||||
uint8_t flags ;
|
||||
uint8_t hcsum ;
|
||||
};
|
||||
|
||||
extern struct t_file_entry File_system[] ;
|
||||
extern char ModelNames[][sizeof(g_model.name)] ; // Allow for general
|
||||
|
||||
extern EEGeneral g_eeGeneral;
|
||||
extern ModelData g_model;
|
||||
@@ -73,6 +96,11 @@ extern ModelData g_model;
|
||||
extern uint8_t Spi_tx_buf[] ;
|
||||
extern uint8_t Spi_rx_buf[] ;
|
||||
|
||||
void eeprom_write_enable();
|
||||
uint32_t eeprom_read_status();
|
||||
void read32_eeprom_data(uint32_t eeAddress, register uint8_t *buffer, uint32_t size, uint32_t immediate=0);
|
||||
uint32_t spi_PDC_action( register uint8_t *command, register uint8_t *tx, register uint8_t *rx, register uint32_t comlen, register uint32_t count );
|
||||
|
||||
#if defined(SDCARD)
|
||||
const pm_char * eeBackupModel(uint8_t i_fileSrc);
|
||||
const pm_char * eeRestoreModel(uint8_t i_fileDst, char *model_name);
|
||||
@@ -1,11 +1,14 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny <shadow@privy.de>
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
@@ -14,7 +17,7 @@
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* open9x is based on code named
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
@@ -31,40 +34,29 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "open9x.h"
|
||||
#include "opentx.h"
|
||||
#include "stdio.h"
|
||||
#include "inttypes.h"
|
||||
#include "string.h"
|
||||
|
||||
uint8_t s_write_err = 0; // error reasons
|
||||
uint8_t s_write_err = 0; // error reasons
|
||||
|
||||
RlcFile theFile; //used for any file operation
|
||||
EeFs eeFs;
|
||||
|
||||
#if !defined(CPUARM)
|
||||
uint8_t s_sync_write = false;
|
||||
uint8_t s_eeDirtyMsk;
|
||||
#if defined(PCBV4) && !defined(REV0)
|
||||
uint16_t s_eeDirtyTime10ms;
|
||||
#endif
|
||||
|
||||
RlcFile theFile; //used for any file operation
|
||||
EeFs eeFs;
|
||||
|
||||
void eeDirty(uint8_t msk)
|
||||
{
|
||||
s_eeDirtyMsk |= msk;
|
||||
#if defined(PCBV4) && !defined(REV0)
|
||||
s_eeDirtyTime10ms = get_tmr10ms();
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t eeprom_pointer;
|
||||
const char* eeprom_buffer_data;
|
||||
const char * eeprom_buffer_data;
|
||||
volatile int8_t eeprom_buffer_size = 0;
|
||||
|
||||
#if !defined(SIMU)
|
||||
|
||||
inline void eeprom_write_byte()
|
||||
{
|
||||
EEAR = eeprom_pointer;
|
||||
EEDR = *eeprom_buffer_data;
|
||||
#if defined (PCBV4)
|
||||
// TODO add some define here
|
||||
#if defined (PCBGRUVIN9X)
|
||||
EECR |= 1<<EEMPE;
|
||||
EECR |= 1<<EEPE;
|
||||
#else
|
||||
@@ -81,14 +73,13 @@ ISR(EE_READY_vect)
|
||||
eeprom_write_byte();
|
||||
}
|
||||
else {
|
||||
#if defined (PCBV4)
|
||||
#if defined(PCBGRUVIN9X)
|
||||
EECR &= ~(1<<EERIE);
|
||||
#else
|
||||
EECR &= ~(1<<EERIE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void eeWriteBlockCmp(const void *i_pointer_ram, uint16_t i_pointer_eeprom, size_t size)
|
||||
@@ -99,11 +90,9 @@ void eeWriteBlockCmp(const void *i_pointer_ram, uint16_t i_pointer_eeprom, size_
|
||||
eeprom_buffer_data = (const char*)i_pointer_ram;
|
||||
eeprom_buffer_size = size+1;
|
||||
|
||||
#ifdef SIMU
|
||||
sem_post(&eeprom_write_sem);
|
||||
#elif defined (PCBARM)
|
||||
|
||||
#elif defined (PCBV4)
|
||||
#if defined(SIMU)
|
||||
sem_post(eeprom_write_sem);
|
||||
#elif defined (PCBGRUVIN9X)
|
||||
EECR |= (1<<EERIE);
|
||||
#else
|
||||
EECR |= (1<<EERIE);
|
||||
@@ -113,11 +102,14 @@ void eeWriteBlockCmp(const void *i_pointer_ram, uint16_t i_pointer_eeprom, size_
|
||||
while (eeprom_buffer_size > 0) wdt_reset();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint8_t EeFsRead(uint8_t blk, uint8_t ofs)
|
||||
static uint8_t EeFsRead(blkid_t blk, uint8_t ofs)
|
||||
{
|
||||
uint8_t ret;
|
||||
#ifdef SIMU
|
||||
#if defined(CPUARM)
|
||||
eeprom_read_block(&ret, (uint16_t)(blk*BS+ofs+BLOCKS_OFFSET), 1);
|
||||
#elif defined(SIMU)
|
||||
eeprom_read_block(&ret, (const void*)(uint64_t)(blk*BS+ofs+BLOCKS_OFFSET), 1);
|
||||
#else
|
||||
eeprom_read_block(&ret, (const void*)(blk*BS+ofs+BLOCKS_OFFSET), 1);
|
||||
@@ -125,76 +117,88 @@ static uint8_t EeFsRead(uint8_t blk, uint8_t ofs)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint8_t EeFsGetLink(uint8_t blk)
|
||||
static blkid_t EeFsGetLink(blkid_t blk)
|
||||
{
|
||||
#if defined(CPUARM)
|
||||
blkid_t ret;
|
||||
eeprom_read_block((uint8_t *)&ret, blk*BS+BLOCKS_OFFSET, sizeof(blkid_t));
|
||||
return ret;
|
||||
#else
|
||||
return EeFsRead(blk, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void EeFsSetLink(uint8_t blk, uint8_t val)
|
||||
static void EeFsSetLink(blkid_t blk, blkid_t val)
|
||||
{
|
||||
static uint8_t s_link; // we write asynchronously, then nothing on the stack!
|
||||
static blkid_t s_link; // we write asynchronously, then nothing on the stack!
|
||||
s_link = val;
|
||||
eeWriteBlockCmp(&s_link, (blk*BS)+BLOCKS_OFFSET, 1);
|
||||
eeWriteBlockCmp((uint8_t *)&s_link, (blk*BS)+BLOCKS_OFFSET, sizeof(blkid_t));
|
||||
}
|
||||
|
||||
static uint8_t EeFsGetDat(uint8_t blk,uint8_t ofs)
|
||||
static uint8_t EeFsGetDat(blkid_t blk, uint8_t ofs)
|
||||
{
|
||||
return EeFsRead(blk, ofs+1);
|
||||
return EeFsRead(blk, ofs+sizeof(blkid_t));
|
||||
}
|
||||
|
||||
static void EeFsSetDat(uint8_t blk,uint8_t ofs,uint8_t*buf,uint8_t len)
|
||||
static void EeFsSetDat(blkid_t blk, uint8_t ofs, uint8_t *buf, uint8_t len)
|
||||
{
|
||||
eeWriteBlockCmp(buf, blk*BS+ofs+1+BLOCKS_OFFSET, len);
|
||||
eeWriteBlockCmp(buf, (blk*BS)+ofs+sizeof(blkid_t)+BLOCKS_OFFSET, len);
|
||||
}
|
||||
|
||||
static void EeFsFlushFreelist()
|
||||
{
|
||||
eeWriteBlockCmp(&eeFs.freeList, offsetof(EeFs, freeList), sizeof(eeFs.freeList));
|
||||
eeWriteBlockCmp((uint8_t *)&eeFs.freeList, offsetof(EeFs, freeList), sizeof(eeFs.freeList));
|
||||
}
|
||||
|
||||
static void EeFsFlushDirEnt(uint8_t i_fileId)
|
||||
{
|
||||
eeWriteBlockCmp(&eeFs.files[i_fileId], offsetof(EeFs, files) + sizeof(DirEnt)*i_fileId, sizeof(DirEnt));
|
||||
eeWriteBlockCmp((uint8_t *)&eeFs.files[i_fileId], offsetof(EeFs, files) + sizeof(DirEnt)*i_fileId, sizeof(DirEnt));
|
||||
}
|
||||
|
||||
static void EeFsFlush()
|
||||
{
|
||||
eeWriteBlockCmp(&eeFs, 0, sizeof(eeFs));
|
||||
eeWriteBlockCmp((uint8_t *)&eeFs, 0, sizeof(eeFs));
|
||||
}
|
||||
|
||||
uint16_t EeFsGetFree()
|
||||
{
|
||||
uint16_t ret = 0;
|
||||
uint8_t i = eeFs.freeList;
|
||||
while( i ){
|
||||
#if defined(CPUARM)
|
||||
int32_t ret = 0;
|
||||
#else
|
||||
int16_t ret = 0;
|
||||
#endif
|
||||
blkid_t i = eeFs.freeList;
|
||||
while (i) {
|
||||
ret += BS-1;
|
||||
i = EeFsGetLink(i);
|
||||
}
|
||||
return ret;
|
||||
ret += eeFs.files[FILE_TMP].size;
|
||||
ret -= eeFs.files[FILE_MODEL(g_eeGeneral.currModel)].size;
|
||||
return (ret > 0 ? ret : 0);
|
||||
}
|
||||
|
||||
/// free one or more blocks
|
||||
static void EeFsFree(uint8_t blk)
|
||||
static void EeFsFree(blkid_t blk)
|
||||
{
|
||||
uint8_t i = blk;
|
||||
while( EeFsGetLink(i)) i = EeFsGetLink(i);
|
||||
EeFsSetLink(i,eeFs.freeList);
|
||||
blkid_t i = blk;
|
||||
blkid_t tmp;
|
||||
while ((tmp=EeFsGetLink(i))) i = tmp;
|
||||
EeFsSetLink(i, eeFs.freeList);
|
||||
eeFs.freeList = blk; //chain in front
|
||||
EeFsFlushFreelist();
|
||||
}
|
||||
|
||||
int8_t EeFsck()
|
||||
{
|
||||
s_sync_write = true;
|
||||
ENABLE_SYNC_WRITE(true);
|
||||
|
||||
uint8_t *bufp = reusableBuffer.eefs_buffer;
|
||||
memset(bufp, 0, BLOCKS);
|
||||
uint8_t blk ;
|
||||
int8_t ret = 0;
|
||||
memclear(bufp, BLOCKS);
|
||||
blkid_t blk ;
|
||||
|
||||
for(uint8_t i = 0; i <= MAXFILES; i++) {
|
||||
uint8_t *startP = (i==MAXFILES ? &eeFs.freeList : &eeFs.files[i].startBlk);
|
||||
uint8_t lastBlk = 0;
|
||||
for (uint8_t i=0; i<=MAXFILES; i++) {
|
||||
blkid_t *startP = (i==MAXFILES ? &eeFs.freeList : &eeFs.files[i].startBlk);
|
||||
blkid_t lastBlk = 0;
|
||||
blk = *startP;
|
||||
while (blk) {
|
||||
if (blk < FIRSTBLK || // bad blk index
|
||||
@@ -225,31 +229,33 @@ int8_t EeFsck()
|
||||
}
|
||||
}
|
||||
|
||||
s_sync_write = false;
|
||||
ENABLE_SYNC_WRITE(false);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EeFsFormat()
|
||||
{
|
||||
s_sync_write = true;
|
||||
ENABLE_SYNC_WRITE(true);
|
||||
|
||||
memset(&eeFs,0, sizeof(eeFs));
|
||||
memclear(&eeFs, sizeof(eeFs));
|
||||
eeFs.version = EEFS_VERS;
|
||||
eeFs.mySize = sizeof(eeFs);
|
||||
eeFs.freeList = 0;
|
||||
eeFs.bs = BS;
|
||||
for(uint8_t i = FIRSTBLK; i < BLOCKS-1; i++) EeFsSetLink(i,i+1);
|
||||
for (blkid_t i=FIRSTBLK; i<BLOCKS-1; i++) {
|
||||
EeFsSetLink(i, i+1);
|
||||
}
|
||||
EeFsSetLink(BLOCKS-1, 0);
|
||||
eeFs.freeList = FIRSTBLK;
|
||||
EeFsFlush();
|
||||
|
||||
s_sync_write = false;
|
||||
ENABLE_SYNC_WRITE(false);
|
||||
}
|
||||
|
||||
bool EeFsOpen() // TODO inline?
|
||||
inline bool EeFsOpen()
|
||||
{
|
||||
eeprom_read_block(&eeFs, 0, sizeof(eeFs));
|
||||
eeprom_read_block((uint8_t *)&eeFs, 0, sizeof(eeFs));
|
||||
|
||||
#ifdef SIMU
|
||||
if (eeFs.version != EEFS_VERS) {
|
||||
@@ -257,7 +263,7 @@ bool EeFsOpen() // TODO inline?
|
||||
fflush(stdout);
|
||||
}
|
||||
if (eeFs.mySize != sizeof(eeFs)) {
|
||||
printf("bad eeFs.mySize (%u instead of %u)\n", eeFs.mySize, sizeof(eeFs));
|
||||
printf("bad eeFs.mySize (%d instead of %d)\n", (int)eeFs.mySize, (int)sizeof(eeFs));
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
@@ -275,36 +281,24 @@ bool EFile::exists(uint8_t i_fileId)
|
||||
*/
|
||||
void EFile::swap(uint8_t i_fileId1, uint8_t i_fileId2)
|
||||
{
|
||||
|
||||
#if ((__GNUC__ > 4 || __GNUC__ == 4) && (__GNUC_MINOR__ > 7 || __GNUC_MINOR__ == 7))
|
||||
DirEnt tmp;
|
||||
__builtin_memcpy(&tmp, __builtin_assume_aligned(&eeFs.files[i_fileId1], sizeof(DirEnt)), sizeof(DirEnt));
|
||||
__builtin_memcpy(&eeFs.files[i_fileId1], __builtin_assume_aligned(&eeFs.files[i_fileId2], sizeof(DirEnt)), sizeof(DirEnt));
|
||||
__builtin_memcpy(&eeFs.files[i_fileId2], __builtin_assume_aligned(&tmp, sizeof(DirEnt)), sizeof(DirEnt));
|
||||
#else
|
||||
DirEnt tmp = eeFs.files[i_fileId1];
|
||||
eeFs.files[i_fileId1] = eeFs.files[i_fileId2];
|
||||
eeFs.files[i_fileId2] = tmp;
|
||||
#endif
|
||||
s_sync_write = true;
|
||||
|
||||
ENABLE_SYNC_WRITE(true);
|
||||
EeFsFlushDirEnt(i_fileId1);
|
||||
EeFsFlushDirEnt(i_fileId2);
|
||||
s_sync_write = false;
|
||||
ENABLE_SYNC_WRITE(false);
|
||||
}
|
||||
|
||||
void EFile::rm(uint8_t i_fileId)
|
||||
{
|
||||
uint8_t i = eeFs.files[i_fileId].startBlk;
|
||||
memset(&eeFs.files[i_fileId], 0, sizeof(eeFs.files[i_fileId]));
|
||||
s_sync_write = true;
|
||||
blkid_t i = eeFs.files[i_fileId].startBlk;
|
||||
memclear(&eeFs.files[i_fileId], sizeof(eeFs.files[i_fileId]));
|
||||
ENABLE_SYNC_WRITE(true);
|
||||
EeFsFlushDirEnt(i_fileId);
|
||||
if (i) EeFsFree(i); //chain in
|
||||
s_sync_write = false;
|
||||
}
|
||||
|
||||
uint16_t EFile::size()
|
||||
{
|
||||
return eeFs.files[m_fileId].size;
|
||||
ENABLE_SYNC_WRITE(false);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -327,72 +321,59 @@ void RlcFile::openRlc(uint8_t i_fileId)
|
||||
m_bRlc = 0;
|
||||
}
|
||||
|
||||
uint8_t EFile::read(uint8_t*buf,uint16_t i_len)
|
||||
uint8_t EFile::read(uint8_t *buf, uint8_t i_len)
|
||||
{
|
||||
uint16_t len = eeFs.files[m_fileId].size - m_pos;
|
||||
if(len < i_len) i_len = len;
|
||||
len = i_len;
|
||||
while(len)
|
||||
{
|
||||
if(!m_currBlk) break;
|
||||
if (i_len > len) i_len = len;
|
||||
|
||||
uint8_t remaining = i_len;
|
||||
while (remaining) {
|
||||
if (!m_currBlk) break;
|
||||
|
||||
*buf++ = EeFsGetDat(m_currBlk, m_ofs++);
|
||||
if(m_ofs>=(BS-1)){
|
||||
m_ofs=0;
|
||||
m_currBlk=EeFsGetLink(m_currBlk);
|
||||
if (m_ofs >= BS-sizeof(blkid_t)) {
|
||||
m_ofs = 0;
|
||||
m_currBlk = EeFsGetLink(m_currBlk);
|
||||
}
|
||||
len--;
|
||||
remaining--;
|
||||
}
|
||||
m_pos += i_len - len;
|
||||
return i_len - len;
|
||||
|
||||
i_len -= remaining;
|
||||
m_pos += i_len;
|
||||
return i_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read runlength (RLE) compressed bytes into buf.
|
||||
*/
|
||||
#ifdef TRANSLATIONS
|
||||
uint16_t RlcFile::readRlc12(uint8_t*buf,uint16_t i_len, bool rlc2)
|
||||
#else
|
||||
uint16_t RlcFile::readRlc(uint8_t*buf,uint16_t i_len)
|
||||
#endif
|
||||
uint16_t RlcFile::readRlc(uint8_t *buf, uint16_t i_len)
|
||||
{
|
||||
uint16_t i=0;
|
||||
for( ; 1; ){
|
||||
uint8_t l=min<uint16_t>(m_zeroes,i_len-i);
|
||||
memset(&buf[i],0,l);
|
||||
i += l;
|
||||
m_zeroes -= l;
|
||||
if(m_zeroes) break;
|
||||
uint16_t i = 0;
|
||||
for( ; 1; ) {
|
||||
uint8_t ln = min<uint16_t>(m_zeroes, i_len-i);
|
||||
memclear(&buf[i], ln);
|
||||
i += ln;
|
||||
m_zeroes -= ln;
|
||||
if (m_zeroes) break;
|
||||
|
||||
l=min<uint16_t>(m_bRlc,i_len-i);
|
||||
uint8_t lr = read(&buf[i],l);
|
||||
ln = min<uint16_t>(m_bRlc, i_len-i);
|
||||
uint8_t lr = read(&buf[i], ln);
|
||||
i += lr ;
|
||||
m_bRlc -= lr;
|
||||
if(m_bRlc) break;
|
||||
|
||||
if(read(&m_bRlc,1)!=1) break; //read how many bytes to read
|
||||
if (read(&m_bRlc, 1) !=1) break; // read how many bytes to read
|
||||
|
||||
assert(m_bRlc & 0x7f);
|
||||
#ifdef TRANSLATIONS
|
||||
if (rlc2) {
|
||||
#endif
|
||||
if(m_bRlc&0x80){ // if contains high byte
|
||||
m_zeroes =(m_bRlc>>4) & 0x7;
|
||||
m_bRlc = m_bRlc & 0x0f;
|
||||
}
|
||||
else if(m_bRlc&0x40){
|
||||
m_zeroes = m_bRlc & 0x3f;
|
||||
m_bRlc = 0;
|
||||
}
|
||||
//else m_bRlc
|
||||
#ifdef TRANSLATIONS
|
||||
|
||||
if (m_bRlc&0x80) { // if contains high byte
|
||||
m_zeroes =(m_bRlc>>4) & 0x7;
|
||||
m_bRlc = m_bRlc & 0x0f;
|
||||
}
|
||||
else {
|
||||
if(m_bRlc&0x80){ // if contains high byte
|
||||
m_zeroes = m_bRlc & 0x7f;
|
||||
m_bRlc = 0;
|
||||
}
|
||||
else if(m_bRlc&0x40) {
|
||||
m_zeroes = m_bRlc & 0x3f;
|
||||
m_bRlc = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return i;
|
||||
}
|
||||
@@ -410,7 +391,7 @@ void RlcFile::write(uint8_t *buf, uint8_t i_len)
|
||||
|
||||
do {
|
||||
nextWriteStep();
|
||||
} while (s_sync_write && m_write_len && !s_write_err);
|
||||
} while (IS_SYNC_WRITE_ENABLE() && m_write_len && !s_write_err);
|
||||
}
|
||||
|
||||
void RlcFile::nextWriteStep()
|
||||
@@ -436,15 +417,15 @@ void RlcFile::nextWriteStep()
|
||||
s_write_err = ERR_FULL;
|
||||
break;
|
||||
}
|
||||
if (m_ofs >= (BS-1)) {
|
||||
if (m_ofs >= (BS-sizeof(blkid_t))) {
|
||||
m_ofs = 0;
|
||||
uint8_t nextBlk = EeFsGetLink(m_currBlk);
|
||||
blkid_t nextBlk = EeFsGetLink(m_currBlk);
|
||||
if (!nextBlk) {
|
||||
if (!eeFs.freeList) {
|
||||
s_write_err = ERR_FULL;
|
||||
break;
|
||||
}
|
||||
m_write_step += WRITE_NEXT_LINK_1; // TODO review all these names
|
||||
m_write_step += WRITE_NEXT_LINK_1;
|
||||
EeFsSetLink(m_currBlk, eeFs.freeList);
|
||||
return;
|
||||
}
|
||||
@@ -459,14 +440,10 @@ void RlcFile::nextWriteStep()
|
||||
return;
|
||||
case WRITE_NEXT_LINK_2:
|
||||
m_write_step -= WRITE_NEXT_LINK_2;
|
||||
EeFsSetLink(m_currBlk, 0); // TODO needed?
|
||||
EeFsSetLink(m_currBlk, 0);
|
||||
return;
|
||||
}
|
||||
if (!m_currBlk) { // TODO needed?
|
||||
s_write_err = ERR_FULL;
|
||||
break;
|
||||
}
|
||||
uint8_t tmp = BS-1-m_ofs; if(tmp>m_write_len) tmp=m_write_len;
|
||||
uint8_t tmp = BS-sizeof(blkid_t)-m_ofs; if(tmp>m_write_len) tmp = m_write_len;
|
||||
m_write_buf += tmp;
|
||||
m_write_len -= tmp;
|
||||
m_ofs += tmp;
|
||||
@@ -476,13 +453,14 @@ void RlcFile::nextWriteStep()
|
||||
}
|
||||
|
||||
if (s_write_err == ERR_FULL) {
|
||||
alert(STR_EEPROMWARN, STR_EEPROMOVERFLOW);
|
||||
s_global_warning = STR_EEPROMOVERFLOW;
|
||||
m_write_step = 0;
|
||||
m_write_len = 0;
|
||||
m_cur_rlc_len = 0;
|
||||
}
|
||||
|
||||
if (!s_sync_write)
|
||||
else if (!IS_SYNC_WRITE_ENABLE()) {
|
||||
nextRlcWriteStep();
|
||||
}
|
||||
}
|
||||
|
||||
void RlcFile::create(uint8_t i_fileId, uint8_t typ, uint8_t sync_write)
|
||||
@@ -492,7 +470,7 @@ void RlcFile::create(uint8_t i_fileId, uint8_t typ, uint8_t sync_write)
|
||||
eeFs.files[FILE_TMP].typ = typ;
|
||||
eeFs.files[FILE_TMP].size = 0;
|
||||
m_fileId = i_fileId;
|
||||
s_sync_write = sync_write;
|
||||
ENABLE_SYNC_WRITE(sync_write);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -504,18 +482,19 @@ bool RlcFile::copy(uint8_t i_fileDst, uint8_t i_fileSrc)
|
||||
theFile2.openRd(i_fileSrc);
|
||||
|
||||
create(i_fileDst, FILE_TYP_MODEL/*optimization, only model files are copied. should be eeFs.files[i_fileSrc].typ*/, true);
|
||||
uint8_t buf[15];
|
||||
|
||||
uint8_t buf[BS-sizeof(blkid_t)];
|
||||
uint8_t len;
|
||||
while ((len=theFile2.read(buf, 15)))
|
||||
while ((len=theFile2.read(buf, BS-sizeof(blkid_t))))
|
||||
{
|
||||
write(buf, len);
|
||||
if (write_errno() != 0) {
|
||||
s_sync_write = false;
|
||||
ENABLE_SYNC_WRITE(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t fri=0;
|
||||
blkid_t fri=0;
|
||||
if (m_currBlk && (fri=EeFsGetLink(m_currBlk)))
|
||||
EeFsSetLink(m_currBlk, 0);
|
||||
|
||||
@@ -531,37 +510,31 @@ bool RlcFile::copy(uint8_t i_fileDst, uint8_t i_fileSrc)
|
||||
}
|
||||
|
||||
#if defined(SDCARD)
|
||||
#define FILENAME_MAXLEN 8
|
||||
extern FIL g_oLogFile;
|
||||
const pm_char * eeBackupModel(uint8_t i_fileSrc)
|
||||
{
|
||||
char *buf = reusableBuffer.models.mainname;
|
||||
FIL archiveFile;
|
||||
DIR archiveFolder;
|
||||
UINT written;
|
||||
|
||||
#ifndef SIMU
|
||||
FRESULT result = f_mount(0, &g_FATFS_Obj);
|
||||
if (result != FR_OK) {
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
#endif
|
||||
// we must close the logs as we reuse the same FIL structure
|
||||
closeLogs();
|
||||
|
||||
// check and create folder here
|
||||
strcpy_P(buf, STR_MODELS_PATH);
|
||||
#ifndef SIMU
|
||||
result = f_opendir(&archiveFolder, buf);
|
||||
FRESULT result = f_opendir(&archiveFolder, buf);
|
||||
if (result != FR_OK) {
|
||||
result = f_mkdir(buf);
|
||||
if (result == FR_NO_PATH)
|
||||
result = f_mkdir(buf);
|
||||
if (result != FR_OK)
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
#endif
|
||||
|
||||
buf[sizeof(MODELS_PATH)-1] = '/';
|
||||
eeLoadModelName(i_fileSrc, &buf[sizeof(MODELS_PATH)]);
|
||||
buf[sizeof(MODELS_PATH)+FILENAME_MAXLEN] = '\0';
|
||||
buf[sizeof(MODELS_PATH)+sizeof(g_model.name)] = '\0';
|
||||
|
||||
uint8_t i = sizeof(MODELS_PATH)+FILENAME_MAXLEN-1;
|
||||
uint8_t i = sizeof(MODELS_PATH)+sizeof(g_model.name)-1;
|
||||
uint8_t len = 0;
|
||||
while (i>sizeof(MODELS_PATH)-1) {
|
||||
if (!len && buf[i])
|
||||
@@ -587,15 +560,9 @@ const pm_char * eeBackupModel(uint8_t i_fileSrc)
|
||||
|
||||
#ifdef SIMU
|
||||
printf("SD-card backup filename=%s\n", buf); fflush(stdout);
|
||||
FRESULT
|
||||
#endif
|
||||
|
||||
result = f_open(&archiveFile, buf, FA_OPEN_ALWAYS | FA_WRITE);
|
||||
if (result != FR_OK) {
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
|
||||
result = f_write(&archiveFile, &g_eeGeneral.myVers, 1, &written);
|
||||
result = f_open(&g_oLogFile, buf, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
if (result != FR_OK) {
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
@@ -603,45 +570,61 @@ const pm_char * eeBackupModel(uint8_t i_fileSrc)
|
||||
EFile theFile2;
|
||||
theFile2.openRd(FILE_MODEL(i_fileSrc));
|
||||
|
||||
*(uint32_t*)&buf[0] = O9X_FOURCC;
|
||||
buf[4] = g_eeGeneral.version;
|
||||
buf[5] = 'M';
|
||||
*(uint16_t*)&buf[6] = eeModelSize(i_fileSrc);
|
||||
|
||||
result = f_write(&g_oLogFile, buf, 8, &written);
|
||||
if (result != FR_OK || written != 8) {
|
||||
f_close(&g_oLogFile);
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
|
||||
while ((len=theFile2.read((uint8_t *)buf, 15))) {
|
||||
result = f_write(&archiveFile, (uint8_t *)buf, len, &written);
|
||||
if (result != FR_OK) {
|
||||
result = f_write(&g_oLogFile, (uint8_t *)buf, len, &written);
|
||||
if (result != FR_OK || written != len) {
|
||||
f_close(&g_oLogFile);
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
}
|
||||
|
||||
f_close(&archiveFile);
|
||||
f_close(&g_oLogFile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const pm_char * eeRestoreModel(uint8_t i_fileDst, char *model_name)
|
||||
{
|
||||
char *buf = reusableBuffer.models.mainname;
|
||||
FIL restoreFile;
|
||||
UINT read;
|
||||
|
||||
FRESULT result = f_mount(0, &g_FATFS_Obj);
|
||||
if (result != FR_OK) {
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
// we must close the logs as we reuse the same FIL structure
|
||||
closeLogs();
|
||||
|
||||
strcpy_P(buf, STR_MODELS_PATH);
|
||||
buf[sizeof(MODELS_PATH)-1] = '/';
|
||||
strcpy(&buf[sizeof(MODELS_PATH)], model_name);
|
||||
strcpy_P(&buf[strlen(buf)], STR_MODELS_EXT);
|
||||
|
||||
result = f_open(&restoreFile, buf, FA_OPEN_EXISTING | FA_READ);
|
||||
FRESULT result = f_open(&g_oLogFile, buf, FA_OPEN_EXISTING | FA_READ);
|
||||
if (result != FR_OK) {
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
|
||||
result = f_read(&restoreFile, (uint8_t *)buf, 1, &read);
|
||||
if (result != FR_OK || read != 1) {
|
||||
if (f_size(&g_oLogFile) < 8) {
|
||||
f_close(&g_oLogFile);
|
||||
return STR_INCOMPATIBLE;
|
||||
}
|
||||
|
||||
result = f_read(&g_oLogFile, (uint8_t *)buf, 8, &read);
|
||||
if (result != FR_OK || read != 8) {
|
||||
f_close(&g_oLogFile);
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
|
||||
if (buf[0] != g_eeGeneral.myVers) {
|
||||
// TODO
|
||||
if (*(uint32_t*)&buf[0] != O9X_FOURCC || (uint8_t)buf[4] != EEPROM_VER || buf[5] != 'M') {
|
||||
f_close(&g_oLogFile);
|
||||
return STR_INCOMPATIBLE;
|
||||
}
|
||||
|
||||
if (eeModelExists(i_fileDst)) {
|
||||
@@ -651,21 +634,23 @@ const pm_char * eeRestoreModel(uint8_t i_fileDst, char *model_name)
|
||||
theFile.create(FILE_MODEL(i_fileDst), FILE_TYP_MODEL, true);
|
||||
|
||||
do {
|
||||
result = f_read(&restoreFile, (uint8_t *)buf, 15, &read);
|
||||
result = f_read(&g_oLogFile, (uint8_t *)buf, 15, &read);
|
||||
if (result != FR_OK) {
|
||||
s_sync_write = false;
|
||||
ENABLE_SYNC_WRITE(false);
|
||||
f_close(&g_oLogFile);
|
||||
return SDCARD_ERROR(result);
|
||||
}
|
||||
if (read > 0) {
|
||||
theFile.write((uint8_t *)buf, read);
|
||||
if (write_errno() != 0) {
|
||||
s_sync_write = false;
|
||||
ENABLE_SYNC_WRITE(false);
|
||||
f_close(&g_oLogFile);
|
||||
return STR_EEPROMOVERFLOW;
|
||||
}
|
||||
}
|
||||
} while (read == 15);
|
||||
|
||||
uint8_t fri=0;
|
||||
blkid_t fri=0;
|
||||
if (theFile.m_currBlk && (fri=EeFsGetLink(theFile.m_currBlk)))
|
||||
EeFsSetLink(theFile.m_currBlk, 0);
|
||||
|
||||
@@ -674,12 +659,12 @@ const pm_char * eeRestoreModel(uint8_t i_fileDst, char *model_name)
|
||||
eeFs.files[FILE_TMP].size = theFile.m_pos;
|
||||
EFile::swap(theFile.m_fileId, FILE_TMP); // s_sync_write is set to false in swap();
|
||||
|
||||
f_close(&restoreFile);
|
||||
f_close(&g_oLogFile);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
void RlcFile::writeRlc(uint8_t i_fileId, uint8_t typ, uint8_t*buf, uint16_t i_len, uint8_t sync_write)
|
||||
void RlcFile::writeRlc(uint8_t i_fileId, uint8_t typ, uint8_t *buf, uint16_t i_len, uint8_t sync_write)
|
||||
{
|
||||
create(i_fileId, typ, sync_write);
|
||||
|
||||
@@ -693,7 +678,7 @@ void RlcFile::writeRlc(uint8_t i_fileId, uint8_t typ, uint8_t*buf, uint16_t i_le
|
||||
|
||||
do {
|
||||
nextRlcWriteStep();
|
||||
} while (s_sync_write && m_write_step && !s_write_err);
|
||||
} while (IS_SYNC_WRITE_ENABLE() && m_write_step && !s_write_err);
|
||||
}
|
||||
|
||||
void RlcFile::nextRlcWriteStep()
|
||||
@@ -711,14 +696,14 @@ void RlcFile::nextRlcWriteStep()
|
||||
return;
|
||||
}
|
||||
|
||||
bool run0 = m_rlc_buf[0] == 0;
|
||||
bool run0 = (m_rlc_buf[0] == 0);
|
||||
|
||||
if(m_rlc_len==0) goto close;
|
||||
if (m_rlc_len==0) goto close;
|
||||
|
||||
for (i=1; 1; i++) // !! laeuft ein byte zu weit !!
|
||||
{
|
||||
bool cur0 = m_rlc_buf[i] == 0;
|
||||
if (cur0 != run0 || cnt==0x3f || (cnt0 && cnt==0xf)|| i==m_rlc_len){
|
||||
if (cur0 != run0 || cnt==0x3f || (cnt0 && cnt==0x0f) || i==m_rlc_len) {
|
||||
if (run0) {
|
||||
assert(cnt0==0);
|
||||
if (cnt<8 && i!=m_rlc_len)
|
||||
@@ -754,10 +739,10 @@ void RlcFile::nextRlcWriteStep()
|
||||
switch(m_write_step) {
|
||||
case WRITE_START_STEP:
|
||||
{
|
||||
uint8_t fri=0;
|
||||
blkid_t fri=0;
|
||||
|
||||
if (m_currBlk && ( fri = EeFsGetLink(m_currBlk))) {
|
||||
uint8_t prev_freeList = eeFs.freeList;
|
||||
if (m_currBlk && (fri=EeFsGetLink(m_currBlk))) {
|
||||
blkid_t prev_freeList = eeFs.freeList;
|
||||
eeFs.freeList = fri;
|
||||
while( EeFsGetLink(fri)) fri = EeFsGetLink(fri);
|
||||
m_write_step = WRITE_FREE_UNUSED_BLOCKS_STEP1;
|
||||
@@ -767,14 +752,18 @@ void RlcFile::nextRlcWriteStep()
|
||||
}
|
||||
|
||||
case WRITE_FINAL_DIRENT_STEP:
|
||||
{
|
||||
m_currBlk = eeFs.files[FILE_TMP].startBlk;
|
||||
eeFs.files[FILE_TMP].startBlk = eeFs.files[m_fileId].startBlk;
|
||||
eeFs.files[m_fileId].startBlk = m_currBlk;
|
||||
eeFs.files[m_fileId].size = m_pos;
|
||||
eeFs.files[m_fileId].typ = eeFs.files[FILE_TMP].typ;
|
||||
DirEnt & f = eeFs.files[m_fileId];
|
||||
eeFs.files[FILE_TMP].startBlk = f.startBlk;
|
||||
eeFs.files[FILE_TMP].size = f.size;
|
||||
f.startBlk = m_currBlk;
|
||||
f.size = m_pos;
|
||||
f.typ = eeFs.files[FILE_TMP].typ;
|
||||
m_write_step = WRITE_TMP_DIRENT_STEP;
|
||||
EeFsFlushDirEnt(m_fileId);
|
||||
return;
|
||||
}
|
||||
|
||||
case WRITE_TMP_DIRENT_STEP:
|
||||
m_write_step = 0;
|
||||
@@ -793,24 +782,26 @@ void RlcFile::nextRlcWriteStep()
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(CPUARM)
|
||||
void RlcFile::flush()
|
||||
{
|
||||
while (eeprom_buffer_size > 0) wdt_reset();
|
||||
|
||||
s_sync_write = true;
|
||||
ENABLE_SYNC_WRITE(true);
|
||||
while (m_write_len && !s_write_err)
|
||||
nextWriteStep();
|
||||
while (isWriting() && !s_write_err)
|
||||
nextRlcWriteStep();
|
||||
s_sync_write = false;
|
||||
ENABLE_SYNC_WRITE(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (EEPROM_PROGRESS_BAR)
|
||||
void RlcFile::DisplayProgressBar(uint8_t x)
|
||||
{
|
||||
if (s_eeDirtyMsk || isWriting() || eeprom_buffer_size) {
|
||||
uint8_t len = s_eeDirtyMsk ? 1 : limit((uint8_t)1, (uint8_t)(7 - (m_rlc_len/m_ratio)), (uint8_t)7);
|
||||
lcd_filled_rect(x+1, 0, 5, FH, SOLID, WHITE);
|
||||
lcd_filled_rect(x+1, 0, 5, FH, SOLID, ERASE);
|
||||
lcd_filled_rect(x+2, 7-len, 3, len);
|
||||
}
|
||||
}
|
||||
@@ -819,39 +810,68 @@ void RlcFile::DisplayProgressBar(uint8_t x)
|
||||
bool eeLoadGeneral()
|
||||
{
|
||||
theFile.openRlc(FILE_GENERAL);
|
||||
if (theFile.readRlc((uint8_t*)&g_eeGeneral, 1) == 1 && g_eeGeneral.myVers == EEPROM_VER) {
|
||||
theFile.openRlc(FILE_GENERAL); // TODO include this openRlc inside readRlc
|
||||
if (theFile.readRlc((uint8_t*)&g_eeGeneral, 1) == 1 && g_eeGeneral.version == EEPROM_VER) {
|
||||
theFile.openRlc(FILE_GENERAL);
|
||||
if (theFile.readRlc((uint8_t*)&g_eeGeneral, sizeof(g_eeGeneral)) <= sizeof(EEGeneral)) {
|
||||
uint16_t sum = evalChkSum();
|
||||
if (g_eeGeneral.chkSum == sum) {
|
||||
#if defined(PCBSTD)
|
||||
if (g_eeGeneral.variant == EEPROM_VARIANT && g_eeGeneral.chkSum == evalChkSum()) {
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
if (g_eeGeneral.chkSum == evalChkSum()) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SIMU
|
||||
printf("EEPROM version %d (%d) instead of %d (%d)\n", g_eeGeneral.version, g_eeGeneral.variant, EEPROM_VER, EEPROM_VARIANT);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
uint16_t eeLoadModelName(uint8_t id, char *name)
|
||||
void eeLoadModelName(uint8_t id, char *name)
|
||||
{
|
||||
memset(name, 0, sizeof(g_model.name));
|
||||
if (id<MAX_MODELS) {
|
||||
memclear(name, sizeof(g_model.name));
|
||||
if (id < MAX_MODELS) {
|
||||
theFile.openRlc(FILE_MODEL(id));
|
||||
if (theFile.readRlc((uint8_t*)name, sizeof(g_model.name)) == sizeof(g_model.name)) {
|
||||
return theFile.size();
|
||||
}
|
||||
theFile.readRlc((uint8_t*)name, sizeof(g_model.name));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(PXX)
|
||||
// must be called just after eeLoadModelName!
|
||||
uint8_t eeLoadModelIdAfterName()
|
||||
{
|
||||
uint8_t modelId = 0;
|
||||
theFile.readRlc(&modelId, sizeof(modelId));
|
||||
return modelId;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool eeModelExists(uint8_t id)
|
||||
{
|
||||
return EFile::exists(FILE_MODEL(id));
|
||||
}
|
||||
|
||||
// TODO Now the 2 functions in eeprom_rlc.cpp and eeprom_raw.cpp are really close, should be merged.
|
||||
void eeLoadModel(uint8_t id)
|
||||
{
|
||||
if (id<MAX_MODELS) {
|
||||
|
||||
#if defined(SDCARD)
|
||||
closeLogs();
|
||||
#endif
|
||||
|
||||
if (pulsesStarted()) {
|
||||
pausePulses();
|
||||
}
|
||||
|
||||
pauseMixerCalculations();
|
||||
|
||||
theFile.openRlc(FILE_MODEL(id));
|
||||
uint16_t sz = theFile.readRlc((uint8_t*)&g_model, sizeof(g_model));
|
||||
|
||||
@@ -862,45 +882,89 @@ void eeLoadModel(uint8_t id)
|
||||
#endif
|
||||
|
||||
if (sz < 256) {
|
||||
// alert("Error Loading Model");
|
||||
modelDefault(id);
|
||||
eeCheck(true);
|
||||
}
|
||||
|
||||
resetProto();
|
||||
resetAll();
|
||||
|
||||
#ifdef SDCARD
|
||||
initLogs();
|
||||
if (pulsesStarted()) {
|
||||
checkAll();
|
||||
resumePulses();
|
||||
}
|
||||
|
||||
activeSwitches = 0;
|
||||
activeFnSwitches = 0;
|
||||
activeFunctions = 0;
|
||||
memclear(lastFunctionTime, sizeof(lastFunctionTime));
|
||||
|
||||
#if !defined(PCBSTD)
|
||||
for (uint8_t i=0; i<MAX_TIMERS; i++) {
|
||||
if (g_model.timers[i].persistent) {
|
||||
s_timerVal[i] = g_model.timers[i].value;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
resumeMixerCalculations();
|
||||
// TODO pulses should be started after mixer calculations ...
|
||||
|
||||
#if defined(FRSKY)
|
||||
frskySendAlarms();
|
||||
#endif
|
||||
|
||||
#if defined(CPUARM) && defined(SDCARD)
|
||||
refreshModelAudioFiles();
|
||||
#endif
|
||||
|
||||
LOAD_MODEL_BITMAP();
|
||||
|
||||
SEND_FAILSAFE_1S();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO merge this code with eeprom_arm.cpp one
|
||||
void eeReadAll()
|
||||
{
|
||||
if(!EeFsOpen() ||
|
||||
EeFsck() < 0 ||
|
||||
!eeLoadGeneral())
|
||||
if (!EeFsOpen() ||
|
||||
EeFsck() < 0 ||
|
||||
!eeLoadGeneral())
|
||||
{
|
||||
generalDefault();
|
||||
|
||||
alert(STR_EEPROMWARN, STR_BADEEPROMDATA);
|
||||
message(STR_EEPROMWARN, STR_EEPROMFORMATTING, NULL);
|
||||
ALERT(STR_EEPROMWARN, STR_BADEEPROMDATA, AU_BAD_EEPROM);
|
||||
|
||||
if (pwrCheck() == e_power_off) {
|
||||
// the radio has been powered off during the ALERT
|
||||
pwrOff();
|
||||
}
|
||||
|
||||
MESSAGE(STR_EEPROMWARN, STR_EEPROMFORMATTING, NULL, AU_EEPROM_FORMATTING);
|
||||
|
||||
EeFsFormat();
|
||||
|
||||
theFile.writeRlc(FILE_GENERAL, FILE_TYP_GENERAL,(uint8_t*)&g_eeGeneral,sizeof(EEGeneral), true);
|
||||
theFile.writeRlc(FILE_GENERAL, FILE_TYP_GENERAL, (uint8_t*)&g_eeGeneral, sizeof(EEGeneral), true);
|
||||
|
||||
modelDefault(0);
|
||||
|
||||
theFile.writeRlc(FILE_MODEL(0), FILE_TYP_MODEL, (uint8_t*)&g_model, sizeof(g_model), true);
|
||||
}
|
||||
else {
|
||||
eeLoadModelNames();
|
||||
}
|
||||
|
||||
stickMode = g_eeGeneral.stickMode;
|
||||
#if !defined(CPUARM)
|
||||
eeLoadModel(g_eeGeneral.currModel);
|
||||
#endif
|
||||
}
|
||||
|
||||
void eeCheck(bool immediately)
|
||||
{
|
||||
if (EEPROM_MASSSTORAGE()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (immediately) {
|
||||
eeFlush();
|
||||
}
|
||||
@@ -917,3 +981,25 @@ void eeCheck(bool immediately)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CPUARM)
|
||||
bool eeCopyModel(uint8_t dst, uint8_t src)
|
||||
{
|
||||
if (theFile.copy(FILE_MODEL(dst), FILE_MODEL(src))) {
|
||||
memcpy(modelNames[dst], modelNames[src], sizeof(g_model.name));
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void eeSwapModels(uint8_t id1, uint8_t id2)
|
||||
{
|
||||
EFile::swap(FILE_MODEL(id1), FILE_MODEL(id2));
|
||||
|
||||
char tmp[sizeof(g_model.name)];
|
||||
memcpy(tmp, modelNames[id1], sizeof(g_model.name));
|
||||
memcpy(modelNames[id1], modelNames[id2], sizeof(g_model.name));
|
||||
memcpy(modelNames[id2], tmp, sizeof(g_model.name));
|
||||
}
|
||||
#endif
|
||||
@@ -1,11 +1,14 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny <shadow@privy.de>
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
@@ -14,7 +17,7 @@
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* open9x is based on code named
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
@@ -36,41 +39,53 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#if defined(PCBV4) && !defined(REV0)
|
||||
#define WRITE_DELAY_10MS 500
|
||||
extern uint16_t s_eeDirtyTime10ms;
|
||||
#endif
|
||||
|
||||
//
|
||||
// bs=16 128 blocks verlust link:128 16files:16*8 128 sum 256
|
||||
// bs=32 64 blocks verlust link: 64 16files:16*16 256 sum 320
|
||||
//
|
||||
#if defined(PCBV4)
|
||||
#define EESIZE 4096
|
||||
#define EEFS_VERS 5
|
||||
#define MAXFILES 36
|
||||
#if defined(PCBTARANIS)
|
||||
#define blkid_t uint16_t
|
||||
#if defined(REV3)
|
||||
#define EESIZE (32*1024)
|
||||
#else
|
||||
#define EESIZE (64*1024)
|
||||
#endif
|
||||
#define EEFS_VERS 5
|
||||
#define MAXFILES 62
|
||||
#define BS 64
|
||||
#elif defined(PCBGRUVIN9X) || defined(CPUM128)
|
||||
#define blkid_t uint8_t
|
||||
#define EESIZE 4096
|
||||
#define EEFS_VERS 5
|
||||
#define MAXFILES 36
|
||||
#define BS 16
|
||||
#else
|
||||
#define EESIZE 2048
|
||||
#define EEFS_VERS 4
|
||||
#define MAXFILES 20
|
||||
#define blkid_t uint8_t
|
||||
#define EESIZE 2048
|
||||
#define EEFS_VERS 4
|
||||
#define MAXFILES 20
|
||||
#define BS 16
|
||||
#endif
|
||||
|
||||
#define BS 16
|
||||
|
||||
PACK(struct DirEnt{
|
||||
uint8_t startBlk;
|
||||
blkid_t startBlk;
|
||||
uint16_t size:12;
|
||||
uint16_t typ:4;
|
||||
});
|
||||
|
||||
#if defined(CPUARM)
|
||||
#define EEFS_EXTRA_FIELDS uint8_t spare[2];
|
||||
#else
|
||||
#define EEFS_EXTRA_FIELDS
|
||||
#endif
|
||||
|
||||
PACK(struct EeFs{
|
||||
uint8_t version;
|
||||
uint8_t mySize;
|
||||
uint8_t freeList;
|
||||
blkid_t mySize;
|
||||
blkid_t freeList;
|
||||
uint8_t bs;
|
||||
EEFS_EXTRA_FIELDS
|
||||
DirEnt files[MAXFILES];
|
||||
});
|
||||
|
||||
extern EeFs eeFs;
|
||||
|
||||
#define FILE_TYP_GENERAL 1
|
||||
#define FILE_TYP_MODEL 2
|
||||
|
||||
@@ -80,24 +95,25 @@ PACK(struct EeFs{
|
||||
#define FILE_MODEL(n) (1+(n))
|
||||
#define FILE_TMP (1+MAX_MODELS)
|
||||
|
||||
#define RESV sizeof(EeFs) //reserv for eeprom header with directory (eeFs)
|
||||
#define RESV sizeof(EeFs) //reserv for eeprom header with directory (eeFs)
|
||||
|
||||
#if defined(PCBV4)
|
||||
#define FIRSTBLK 1
|
||||
#define BLOCKS (1+(EESIZE-RESV)/BS)
|
||||
#define BLOCKS_OFFSET (RESV-BS)
|
||||
#else
|
||||
#if defined(CPUM64)
|
||||
#define FIRSTBLK (RESV/BS)
|
||||
#define BLOCKS (EESIZE/BS)
|
||||
#define BLOCKS_OFFSET 0
|
||||
#else
|
||||
#define FIRSTBLK 1
|
||||
#define BLOCKS (1+(EESIZE-RESV)/BS)
|
||||
#define BLOCKS_OFFSET (RESV-BS)
|
||||
#endif
|
||||
|
||||
bool EeFsOpen();
|
||||
int8_t EeFsck();
|
||||
void EeFsFormat();
|
||||
uint16_t EeFsGetFree();
|
||||
|
||||
#if !defined(CPUARM)
|
||||
extern volatile int8_t eeprom_buffer_size;
|
||||
#endif
|
||||
|
||||
class EFile
|
||||
{
|
||||
@@ -107,31 +123,44 @@ class EFile
|
||||
static void rm(uint8_t i_fileId);
|
||||
|
||||
///swap contents of file1 with them of file2
|
||||
static void swap(uint8_t i_fileId1,uint8_t i_fileId2);
|
||||
static void swap(uint8_t i_fileId1, uint8_t i_fileId2);
|
||||
|
||||
///return true if the file with given fileid exists
|
||||
static bool exists(uint8_t i_fileId);
|
||||
|
||||
///return size of compressed file without block overhead
|
||||
uint16_t size(); // TODO static ?
|
||||
|
||||
///open file for reading, no close necessary
|
||||
void openRd(uint8_t i_fileId);
|
||||
|
||||
uint8_t read(uint8_t*buf, uint16_t i_len);
|
||||
uint8_t read(uint8_t *buf, uint8_t len);
|
||||
|
||||
// protected:
|
||||
|
||||
uint8_t m_fileId; //index of file in directory = filename
|
||||
uint16_t m_pos; //over all filepos
|
||||
uint8_t m_currBlk; //current block.id
|
||||
blkid_t m_currBlk; //current block.id
|
||||
uint8_t m_ofs; //offset inside of the current block
|
||||
};
|
||||
|
||||
#define eeFileSize(f) eeFs.files[f].size
|
||||
#define eeModelSize(id) eeFileSize(FILE_MODEL(id))
|
||||
|
||||
#if defined(PXX)
|
||||
uint8_t eeLoadModelIdAfterName();
|
||||
#define eeLoadModelId(id) eeLoadModelIdAfterName()
|
||||
#endif
|
||||
|
||||
#define ERR_NONE 0
|
||||
#define ERR_FULL 1
|
||||
extern uint8_t s_write_err; // error reasons
|
||||
|
||||
#if defined(CPUARM)
|
||||
#define ENABLE_SYNC_WRITE(val)
|
||||
#define IS_SYNC_WRITE_ENABLE() true
|
||||
#else
|
||||
extern uint8_t s_sync_write;
|
||||
#define ENABLE_SYNC_WRITE(val) s_sync_write = val;
|
||||
#define IS_SYNC_WRITE_ENABLE() s_sync_write
|
||||
#endif
|
||||
|
||||
///deliver current errno, this is reset in open
|
||||
inline uint8_t write_errno() { return s_write_err; }
|
||||
@@ -167,32 +196,24 @@ public:
|
||||
|
||||
void create(uint8_t i_fileId, uint8_t typ, uint8_t sync_write);
|
||||
|
||||
///copy contents of i_fileSrc to i_fileDst
|
||||
/// copy contents of i_fileSrc to i_fileDst
|
||||
bool copy(uint8_t i_fileDst, uint8_t i_fileSrc);
|
||||
|
||||
inline bool isWriting() { return m_write_step != 0; }
|
||||
void write(uint8_t*buf, uint8_t i_len);
|
||||
void write(uint8_t *buf, uint8_t i_len);
|
||||
void write1(uint8_t b);
|
||||
void nextWriteStep();
|
||||
void nextRlcWriteStep();
|
||||
void writeRlc(uint8_t i_fileId, uint8_t typ, uint8_t *buf, uint16_t i_len, uint8_t sync_write);
|
||||
void flush();
|
||||
|
||||
///read from opened file and decode rlc-coded data
|
||||
#ifdef TRANSLATIONS
|
||||
uint16_t readRlc12(uint8_t*buf,uint16_t i_len,bool rlc2);
|
||||
inline uint16_t readRlc1(uint8_t*buf,uint16_t i_len)
|
||||
{
|
||||
return readRlc12(buf,i_len,false);
|
||||
}
|
||||
inline uint16_t readRlc(uint8_t*buf, uint16_t i_len)
|
||||
{
|
||||
return readRlc12(buf,i_len,true);
|
||||
}
|
||||
#else
|
||||
uint16_t readRlc(uint8_t*buf, uint16_t i_len); // TODO should be like writeRlc?
|
||||
#if !defined(CPUARM)
|
||||
// flush the current write operation if any
|
||||
void flush();
|
||||
#endif
|
||||
|
||||
// read from opened file and decode rlc-coded data
|
||||
uint16_t readRlc(uint8_t *buf, uint16_t i_len);
|
||||
|
||||
#if defined (EEPROM_PROGRESS_BAR)
|
||||
void DisplayProgressBar(uint8_t x);
|
||||
#endif
|
||||
@@ -200,7 +221,11 @@ public:
|
||||
|
||||
extern RlcFile theFile; //used for any file operation
|
||||
|
||||
#if defined(CPUARM)
|
||||
#define eeFlush()
|
||||
#else
|
||||
inline void eeFlush() { theFile.flush(); }
|
||||
#endif
|
||||
|
||||
#if defined (EEPROM_PROGRESS_BAR)
|
||||
#define DISPLAY_PROGRESS_BAR(x) theFile.DisplayProgressBar(x)
|
||||
@@ -211,8 +236,14 @@ inline void eeFlush() { theFile.flush(); }
|
||||
uint16_t evalChkSum();
|
||||
|
||||
#define eeDeleteModel(x) EFile::rm(FILE_MODEL(x))
|
||||
|
||||
#if defined(CPUARM)
|
||||
bool eeCopyModel(uint8_t dst, uint8_t src);
|
||||
void eeSwapModels(uint8_t id1, uint8_t id2);
|
||||
#else
|
||||
#define eeCopyModel(dst, src) theFile.copy(FILE_MODEL(dst), FILE_MODEL(src))
|
||||
#define eeSwapModels(id1, id2) EFile::swap(FILE_MODEL(id1), FILE_MODEL(id2))
|
||||
#endif
|
||||
|
||||
#if defined(SDCARD)
|
||||
const pm_char * eeBackupModel(uint8_t i_fileSrc);
|
||||
@@ -220,4 +251,3 @@ const pm_char * eeRestoreModel(uint8_t i_fileDst, char *model_name);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*eof*/
|
||||
@@ -1,348 +0,0 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny <shadow@privy.de>
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* open9x is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../open9x.h"
|
||||
|
||||
audioQueue::audioQueue()
|
||||
{
|
||||
toneTimeLeft = 0;
|
||||
tonePause = 0;
|
||||
|
||||
t_queueRidx = 0;
|
||||
t_queueWidx = 0;
|
||||
}
|
||||
|
||||
// heartbeat is responsibile for issueing the audio tones and general square waves
|
||||
// it is essentially the life of the class.
|
||||
// it is called every 10ms
|
||||
void audioQueue::heartbeat()
|
||||
{
|
||||
#if defined(SIMU)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (toneTimeLeft > 0) {
|
||||
if (toneChanged) {
|
||||
toneChanged = 0;
|
||||
set_frequency(toneFreq * 61 / 2);
|
||||
if(toneRateLimit == 0){ //only start if within rate limit
|
||||
if(toneFreq == 0){
|
||||
tone_stop();
|
||||
} else {
|
||||
tone_start(0);
|
||||
}
|
||||
}
|
||||
toneRateLimit++; //count up the rate limit
|
||||
if(toneRateLimit == TONE1_RATE_LIMIT){ //reset the rate limit
|
||||
toneRateLimit = 0;
|
||||
}
|
||||
}
|
||||
else if (toneFreqIncr && (toneTimeLeft&1) == 0) {
|
||||
toneFreq += toneFreqIncr;
|
||||
set_frequency(toneFreq * 61 / 2);
|
||||
}
|
||||
toneTimeLeft--; //time gets counted down
|
||||
}
|
||||
else {
|
||||
if (tonePause > 0) {
|
||||
tone_stop();
|
||||
toneRateLimit = 0; //reset rate limit
|
||||
tonePause--; //time gets counted down
|
||||
}
|
||||
else if (t_queueRidx != t_queueWidx) {
|
||||
toneChanged = 1;
|
||||
toneFreq = queueToneFreq[t_queueRidx];
|
||||
toneTimeLeft = queueToneLength[t_queueRidx];
|
||||
toneFreqIncr = queueToneFreqIncr[t_queueRidx];
|
||||
tonePause = queueTonePause[t_queueRidx];
|
||||
if (!queueToneRepeat[t_queueRidx]--) {
|
||||
t_queueRidx = (t_queueRidx + 1) % AUDIO_QUEUE_LENGTH;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tone2TimeLeft > 0) {
|
||||
if (tone2Changed) {
|
||||
tone2Changed = 0;
|
||||
set_frequency(tone2Freq * 61 / 2);
|
||||
if(tone2RateLimit == 0){ //only start if within rate limit
|
||||
tone_start(0);
|
||||
}
|
||||
}
|
||||
tone2TimeLeft--; //time gets counted down
|
||||
tone2RateLimit++; //count up the rate limit
|
||||
if(tone2RateLimit == TONE2_RATE_LIMIT){ //reset the rate limit
|
||||
tone2RateLimit = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
tone_stop();
|
||||
tone2RateLimit = 0; //reset rate limit
|
||||
if (tone2Pause > 0) {
|
||||
tone2Pause--; //time gets counted down
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline uint8_t audioQueue::getToneLength(uint8_t tLen)
|
||||
{
|
||||
uint8_t result = tLen; // default
|
||||
if (g_eeGeneral.beeperLength < 0) {
|
||||
result /= (1-g_eeGeneral.beeperLength);
|
||||
}
|
||||
if (g_eeGeneral.beeperLength > 0) {
|
||||
result *= (1+g_eeGeneral.beeperLength);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void audioQueue::pause(uint8_t tLen)
|
||||
{
|
||||
play(0, tLen, 5); // a pause
|
||||
}
|
||||
|
||||
void audioQueue::play(uint8_t tFreq, uint8_t tLen, uint8_t tPause,
|
||||
uint8_t tFlags, int8_t tFreqIncr)
|
||||
{
|
||||
if (tFlags & PLAY_SOUND_VARIO) {
|
||||
tone2Changed = 1;
|
||||
tone2Freq = tFreq;
|
||||
tone2TimeLeft = tLen;
|
||||
tone2Pause = tPause;
|
||||
}
|
||||
else {
|
||||
if (tFreq > 0) { //we dont add pitch if zero as this is a pause only event
|
||||
tFreq += g_eeGeneral.speakerPitch + BEEP_OFFSET; // add pitch compensator
|
||||
}
|
||||
tLen = getToneLength(tLen);
|
||||
if (tFlags & PLAY_NOW || (!busy() && empty())) {
|
||||
toneChanged = 1;
|
||||
toneFreq = tFreq;
|
||||
toneTimeLeft = tLen;
|
||||
tonePause = tPause;
|
||||
toneFreqIncr = tFreqIncr;
|
||||
t_queueWidx = t_queueRidx;
|
||||
}
|
||||
else {
|
||||
tFlags++;
|
||||
}
|
||||
|
||||
tFlags &= 0x0f;
|
||||
if (tFlags) {
|
||||
uint8_t next_queueWidx = (t_queueWidx + 1) % AUDIO_QUEUE_LENGTH;
|
||||
if (next_queueWidx != t_queueRidx) {
|
||||
queueToneFreq[t_queueWidx] = tFreq;
|
||||
queueToneLength[t_queueWidx] = tLen;
|
||||
queueTonePause[t_queueWidx] = tPause;
|
||||
queueToneRepeat[t_queueWidx] = tFlags - 1;
|
||||
queueToneFreqIncr[t_queueWidx] = tFreqIncr;
|
||||
t_queueWidx = next_queueWidx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void audioQueue::event(uint8_t e, uint8_t f)
|
||||
{
|
||||
#ifdef HAPTIC
|
||||
haptic.event(e); //do this before audio to help sync timings
|
||||
#endif
|
||||
|
||||
if (g_eeGeneral.flashBeep && (e <= AU_ERROR || e >= AU_WARNING1))
|
||||
g_LightOffCounter = FLASH_DURATION;
|
||||
|
||||
if (g_eeGeneral.beeperMode>0 || (g_eeGeneral.beeperMode==0 && e>=AU_TRIM_MOVE) || (g_eeGeneral.beeperMode>=-1 && e<=AU_ERROR)) {
|
||||
if (e < AU_FRSKY_FIRST || empty()) {
|
||||
switch (e) {
|
||||
// inactivity timer alert
|
||||
case AU_INACTIVITY:
|
||||
play(70, 20, 4, 2|PLAY_NOW);
|
||||
break;
|
||||
// low battery in tx
|
||||
case AU_TX_BATTERY_LOW:
|
||||
if (empty()) {
|
||||
play(60, 40, 6, 2, 1);
|
||||
play(80, 40, 6, 2, -1);
|
||||
}
|
||||
break;
|
||||
// error
|
||||
case AU_ERROR:
|
||||
play(BEEP_DEFAULT_FREQ, 80, 2, PLAY_NOW);
|
||||
break;
|
||||
// keypad up (seems to be used when going left/right through system menu options. 0-100 scales etc)
|
||||
case AU_KEYPAD_UP:
|
||||
play(BEEP_KEY_UP_FREQ, 20, 2, PLAY_NOW);
|
||||
break;
|
||||
// keypad down (seems to be used when going left/right through system menu options. 0-100 scales etc)
|
||||
case AU_KEYPAD_DOWN:
|
||||
play(BEEP_KEY_DOWN_FREQ, 20, 2, PLAY_NOW);
|
||||
break;
|
||||
// menu display (also used by a few generic beeps)
|
||||
case AU_MENUS:
|
||||
play(BEEP_DEFAULT_FREQ, 20, 4, PLAY_NOW);
|
||||
break;
|
||||
// trim move
|
||||
case AU_TRIM_MOVE:
|
||||
play(f, 12, 2, PLAY_NOW);
|
||||
break;
|
||||
// trim center
|
||||
case AU_TRIM_MIDDLE:
|
||||
play(f, 20, 4, PLAY_NOW);
|
||||
break;
|
||||
// warning one
|
||||
case AU_WARNING1:
|
||||
play(BEEP_DEFAULT_FREQ, 20, 2, PLAY_NOW);
|
||||
break;
|
||||
// warning two
|
||||
case AU_WARNING2:
|
||||
play(BEEP_DEFAULT_FREQ, 40, 2, PLAY_NOW);
|
||||
break;
|
||||
// warning three
|
||||
case AU_WARNING3:
|
||||
play(BEEP_DEFAULT_FREQ, 60, 2, PLAY_NOW);
|
||||
break;
|
||||
// startup tune
|
||||
case AU_TADA:
|
||||
play(50, 20, 10);
|
||||
play(90, 20, 10);
|
||||
play(110, 10, 8, 2);
|
||||
break;
|
||||
// pot/stick center
|
||||
case AU_POT_STICK_MIDDLE:
|
||||
play(BEEP_DEFAULT_FREQ + 50, 20, 2, PLAY_NOW);
|
||||
break;
|
||||
// mix warning 1
|
||||
case AU_MIX_WARNING_1:
|
||||
play(BEEP_DEFAULT_FREQ + 50, 12, 0, PLAY_NOW);
|
||||
break;
|
||||
// mix warning 2
|
||||
case AU_MIX_WARNING_2:
|
||||
play(BEEP_DEFAULT_FREQ + 52, 12, 0, PLAY_NOW);
|
||||
break;
|
||||
// mix warning 3
|
||||
case AU_MIX_WARNING_3:
|
||||
play(BEEP_DEFAULT_FREQ + 54, 12, 0, PLAY_NOW);
|
||||
break;
|
||||
// time 30 seconds left
|
||||
case AU_TIMER_30:
|
||||
play(BEEP_DEFAULT_FREQ + 50, 30, 6, 2|PLAY_NOW);
|
||||
break;
|
||||
// time 20 seconds left
|
||||
case AU_TIMER_20:
|
||||
play(BEEP_DEFAULT_FREQ + 50, 30, 6, 1|PLAY_NOW);
|
||||
break;
|
||||
// time 10 seconds left
|
||||
case AU_TIMER_10:
|
||||
play(BEEP_DEFAULT_FREQ + 50, 30, 6, PLAY_NOW);
|
||||
break;
|
||||
// time <3 seconds left
|
||||
case AU_TIMER_LT3:
|
||||
play(BEEP_DEFAULT_FREQ + 50, 30, 6, PLAY_NOW);
|
||||
break;
|
||||
case AU_FRSKY_WARN1:
|
||||
play(BEEP_DEFAULT_FREQ+20,30,10,2);
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_WARN2:
|
||||
play(BEEP_DEFAULT_FREQ+30,30,10,2);
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_CHEEP:
|
||||
play(BEEP_DEFAULT_FREQ+30,20,4,2,2);
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_RING:
|
||||
play(BEEP_DEFAULT_FREQ+25,10,4,10);
|
||||
play(BEEP_DEFAULT_FREQ+25,10,20,1);
|
||||
play(BEEP_DEFAULT_FREQ+25,10,4,10);
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_SCIFI:
|
||||
play(80,20,6,2,-1);
|
||||
play(60,20,6,2,1);
|
||||
play(70,20,2,0);
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_ROBOT:
|
||||
play(70,10,2,1);
|
||||
play(50,30,4,1);
|
||||
play(80,30,4,1);
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_CHIRP:
|
||||
play(BEEP_DEFAULT_FREQ+40,10,2,2);
|
||||
play(BEEP_DEFAULT_FREQ+54,10,2,3);
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_TADA:
|
||||
play(50,10,10);
|
||||
play(90,10,10);
|
||||
play(110,6,8,2);
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_CRICKET:
|
||||
play(80,10,20,3);
|
||||
play(80,10,40,1);
|
||||
play(80,10,20,3);
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_SIREN:
|
||||
play(10,40,10,2,1);
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_ALARMC:
|
||||
play(50,8,20,2);
|
||||
play(70,16,40,1);
|
||||
play(50,16,20,2);
|
||||
play(70,8,40,1);
|
||||
pause(200);
|
||||
break;
|
||||
case AU_FRSKY_RATATA:
|
||||
play(BEEP_DEFAULT_FREQ+50,10,20,10);
|
||||
break;
|
||||
case AU_FRSKY_TICK:
|
||||
play(BEEP_DEFAULT_FREQ+50,10,100,2);
|
||||
pause(200);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void audioDefevent(uint8_t e)
|
||||
{
|
||||
audio.event(e, BEEP_DEFAULT_FREQ);
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny <shadow@privy.de>
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* open9x is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef audio_h
|
||||
#define audio_h
|
||||
|
||||
#define AUDIO_QUEUE_LENGTH (100)
|
||||
#define BEEP_DEFAULT_FREQ (70)
|
||||
#define BEEP_OFFSET (10)
|
||||
#define BEEP_KEY_UP_FREQ (BEEP_DEFAULT_FREQ+5)
|
||||
#define BEEP_KEY_DOWN_FREQ (BEEP_DEFAULT_FREQ-5)
|
||||
#define TONE1_RATE_LIMIT (10)
|
||||
#define TONE2_RATE_LIMIT (10)
|
||||
|
||||
class audioQueue
|
||||
{
|
||||
public:
|
||||
|
||||
audioQueue();
|
||||
|
||||
|
||||
void play(uint8_t tFreq, uint8_t tLen, uint8_t tPause, uint8_t tFlags=0, int8_t tFreqIncr=0);
|
||||
void pause(uint8_t tLen);
|
||||
|
||||
inline bool busy() {
|
||||
return (toneTimeLeft > 0);
|
||||
}
|
||||
|
||||
void event(uint8_t e, uint8_t f=BEEP_DEFAULT_FREQ);
|
||||
|
||||
// heartbeat is responsibile for issueing the audio tones and general square waves
|
||||
// it is essentially the life of the class.
|
||||
void heartbeat();
|
||||
|
||||
// bool freeslots(uint8_t slots);
|
||||
|
||||
inline bool empty() {
|
||||
return (t_queueRidx == t_queueWidx);
|
||||
}
|
||||
|
||||
protected:
|
||||
inline uint8_t getToneLength(uint8_t tLen);
|
||||
|
||||
private:
|
||||
uint8_t t_queueRidx;
|
||||
uint8_t t_queueWidx;
|
||||
|
||||
uint8_t toneChanged;
|
||||
uint8_t toneFreq;
|
||||
int8_t toneFreqIncr;
|
||||
uint8_t toneTimeLeft;
|
||||
uint8_t tonePause;
|
||||
uint8_t toneRateLimit;
|
||||
|
||||
// vario
|
||||
uint8_t tone2Changed;
|
||||
uint8_t tone2Freq;
|
||||
uint8_t tone2TimeLeft;
|
||||
uint8_t tone2Pause;
|
||||
uint8_t tone2RateLimit;
|
||||
|
||||
// queue arrays
|
||||
uint8_t queueToneFreq[AUDIO_QUEUE_LENGTH];
|
||||
int8_t queueToneFreqIncr[AUDIO_QUEUE_LENGTH];
|
||||
uint8_t queueToneLength[AUDIO_QUEUE_LENGTH];
|
||||
uint8_t queueTonePause[AUDIO_QUEUE_LENGTH];
|
||||
uint8_t queueToneRepeat[AUDIO_QUEUE_LENGTH];
|
||||
|
||||
};
|
||||
|
||||
//wrapper function - dirty but results in a space saving!!!
|
||||
extern audioQueue audio;
|
||||
|
||||
void audioDefevent(uint8_t e);
|
||||
|
||||
#define AUDIO_KEYPAD_UP() audioDefevent(AU_KEYPAD_UP)
|
||||
#define AUDIO_KEYPAD_DOWN() audioDefevent(AU_KEYPAD_DOWN)
|
||||
#define AUDIO_MENUS() audioDefevent(AU_MENUS)
|
||||
#define AUDIO_WARNING1() audioDefevent(AU_WARNING1)
|
||||
#define AUDIO_WARNING2() audioDefevent(AU_WARNING2)
|
||||
#define AUDIO_ERROR() audioDefevent(AU_ERROR)
|
||||
|
||||
|
||||
#define IS_AUDIO_BUSY() audio.busy()
|
||||
|
||||
#define AUDIO_TIMER_30() audioDefevent(AU_TIMER_30)
|
||||
#define AUDIO_TIMER_20() audioDefevent(AU_TIMER_20)
|
||||
#define AUDIO_TIMER_10() audioDefevent(AU_TIMER_10)
|
||||
#define AUDIO_TIMER_LT3() audioDefevent(AU_TIMER_LT3)
|
||||
#define AUDIO_MINUTE_BEEP() audioDefevent(AU_WARNING1)
|
||||
#define AUDIO_INACTIVITY() audioDefevent(AU_INACTIVITY)
|
||||
#define AUDIO_MIX_WARNING_1() audioDefevent(AU_MIX_WARNING_1)
|
||||
#define AUDIO_MIX_WARNING_2() audioDefevent(AU_MIX_WARNING_2)
|
||||
#define AUDIO_MIX_WARNING_3() audioDefevent(AU_MIX_WARNING_3)
|
||||
#define AUDIO_POT_STICK_MIDDLE() audioDefevent(AU_POT_STICK_MIDDLE)
|
||||
#define AUDIO_VARIO_UP() audioDefevent(AU_KEYPAD_UP)
|
||||
#define AUDIO_VARIO_DOWN() audioDefevent(AU_KEYPAD_DOWN)
|
||||
#define AUDIO_TRIM_MIDDLE(f) audio.event(AU_TRIM_MIDDLE, f)
|
||||
|
||||
#define AUDIO_HEARTBEAT() audio.heartbeat()
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny <shadow@privy.de>
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* open9x is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
/ Low level disk interface modlue include file (C)ChaN, 2010
|
||||
/-----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef DEF_DISKIO
|
||||
#define DEF_DISKIO
|
||||
|
||||
#include "integer.h"
|
||||
|
||||
#define DN_MCI 0 /* Physical drive number for MCI */
|
||||
#define DN_NAND 1 /* Physical drive number for NAND flash */
|
||||
|
||||
|
||||
/* These functions are defined in asmfunc.S */
|
||||
void Copy_al2un (BYTE *dst, const DWORD *src, int count); /* Copy aligned to unaligned. */
|
||||
void Copy_un2al (DWORD *dst, const BYTE *src, int count); /* Copy unaligned to aligned. */
|
||||
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum {
|
||||
RES_OK = 0, /* 0: Successful */
|
||||
RES_ERROR, /* 1: R/W Error */
|
||||
RES_WRPRT, /* 2: Write Protected */
|
||||
RES_NOTRDY, /* 3: Not Ready */
|
||||
RES_PARERR /* 4: Invalid Parameter */
|
||||
} DRESULT;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
|
||||
DSTATUS disk_initialize (BYTE);
|
||||
DSTATUS disk_status (BYTE);
|
||||
DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE);
|
||||
DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE);
|
||||
DRESULT disk_ioctl (BYTE, BYTE, BYTE*);
|
||||
void disk_timerproc (void);
|
||||
|
||||
|
||||
/* Disk Status Bits (DSTATUS) */
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
#define STA_PROTECT 0x04 /* Write protected */
|
||||
|
||||
|
||||
/* Command code for disk_ioctrl fucntion */
|
||||
|
||||
/* Generic ioctl command (defined for FatFs) */
|
||||
#define CTRL_SYNC 0 /* Flush disk cache (for write functions) */
|
||||
#define GET_SECTOR_COUNT 1 /* Get media size (for only f_mkfs()) */
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (for multiple sector size (_MAX_SS >= 1024)) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (for only f_mkfs()) */
|
||||
#define CTRL_ERASE_SECTOR 4 /* Force erased a block of sectors (for only _USE_ERASE) */
|
||||
|
||||
/* Generic ioctl command */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||
#define CTRL_EJECT 7 /* Eject media */
|
||||
|
||||
/* MMC/SDC specific ioctl command */
|
||||
#define MMC_GET_TYPE 10 /* Get card type */
|
||||
#define MMC_GET_CSD 11 /* Get CSD */
|
||||
#define MMC_GET_CID 12 /* Get CID */
|
||||
#define MMC_GET_OCR 13 /* Get OCR */
|
||||
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||
|
||||
/* ATA/CF specific ioctl command */
|
||||
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||
#define ATA_GET_MODEL 21 /* Get model name */
|
||||
#define ATA_GET_SN 22 /* Get serial number */
|
||||
|
||||
/* NAND specific ioctl command */
|
||||
#define NAND_FORMAT 30 /* Create physical format */
|
||||
|
||||
|
||||
volatile extern BYTE Timer1, Timer2; /* 100Hz decrement timer */
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// Detect if SD card is connected
|
||||
//------------------------------------------------------------------------------
|
||||
#define CardIsConnected() ( (PIOB->PIO_PDSR & PIO_PB7) == 0 )
|
||||
|
||||
extern uint32_t Card_ID[4] ;
|
||||
extern uint32_t Card_SCR[2] ;
|
||||
extern uint32_t Card_CSD[4] ;
|
||||
extern uint32_t Sd_128_resp[4] ;
|
||||
extern uint32_t Sd_rca ;
|
||||
//extern uint32_t Cmd_55_resp ;
|
||||
|
||||
extern uint32_t SD_SetBusWidth( uint32_t busWidth) ;
|
||||
extern void SD_EnableHsMode( uint8_t hsEnable) ;
|
||||
extern uint32_t SD_SetSpeed( uint32_t mciSpeed ) ;
|
||||
extern void SD_Reset( uint8_t keepSettings) ;
|
||||
extern void sd_cmd55( void ) ;
|
||||
extern uint32_t sd_acmd41( void ) ;
|
||||
extern uint32_t sd_cmd2( void ) ;
|
||||
extern uint32_t sd_cmd3( void ) ;
|
||||
extern uint32_t sd_cmd7( void ) ;
|
||||
extern uint32_t sd_cmd9( void ) ;
|
||||
extern uint32_t sd_acmd6( void ) ;
|
||||
extern uint32_t sd_acmd51( uint32_t *presult ) ;
|
||||
extern void sd_poll_10mS( void ) ;
|
||||
extern uint32_t sd_card_ready( void ) ;
|
||||
extern uint32_t sd_read_block( uint32_t block_no, uint32_t *data ) ;
|
||||
|
||||
|
||||
#endif
|
||||
-3819
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user