Compare commits
1987 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d1398e03f | |||
| 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 | |||
| c47a380c0e | |||
| 521f7fc2f4 | |||
| 0f9036f00d | |||
| d88cd7d95f | |||
| 84add995ce | |||
| 975cb17612 | |||
| a377326c6e | |||
| 091885090f | |||
| fcabcf8f9f | |||
| b7860b3363 | |||
| 40341b20ee | |||
| 925d661640 | |||
| 090a74369a | |||
| b5e76c186c | |||
| e32eeec487 | |||
| f9673e3b8b | |||
| 714bbf4fa2 | |||
| 28337362f9 | |||
| b4a3f2038d | |||
| b4e881f1c0 | |||
| f94a25b22e | |||
| e84f291724 | |||
| 93b8251338 | |||
| 3b02b184cf | |||
| 18718f0ec1 | |||
| dceec43442 | |||
| ecf7831af5 | |||
| a4a91dcd72 | |||
| 20a7e91796 | |||
| 72d8d5e255 | |||
| bc0958f436 | |||
| 3be919b20c | |||
| 11c9e23550 | |||
| b4b615303e | |||
| 735e272d36 | |||
| 0682da0ff1 | |||
| 8a62c195d2 | |||
| 7bce71ef64 | |||
| 1400fdddbb | |||
| 1b800f6e53 | |||
| a1e9920799 | |||
| 926528e17f | |||
| 4f0a102ccf | |||
| 6d98f9f7ae | |||
| 168a3bc1eb | |||
| f05f28c5fe | |||
| 99b8e1e398 | |||
| d64c4710e7 | |||
| bb871ce6cf | |||
| 02f135a596 | |||
| 1e8219e110 | |||
| a4be1f9177 | |||
| 5b580bf59c | |||
| 9fc9cd18be | |||
| 1272f34ccb | |||
| 22562a2d60 | |||
| d976a34736 | |||
| dcd2a57cf5 | |||
| aaa6367ac0 | |||
| 7904888162 | |||
| 2d57bc4d18 | |||
| cc791bd880 | |||
| a46b06714f | |||
| b9032878a7 | |||
| ab259ab135 | |||
| 1ef129829b | |||
| 099e48080c | |||
| 38fd7921e5 | |||
| 14f8d3e968 | |||
| 8e3345c019 | |||
| 14f0f7ca10 | |||
| 32ce85fc20 | |||
| f035d089b2 | |||
| 082186b67a | |||
| ad95946378 | |||
| 14f1e30287 | |||
| a66b7730c2 | |||
| 45bdef6b3a | |||
| 0e5360f07f | |||
| 945c4b8528 | |||
| b02ff17828 | |||
| 99eeee6fef | |||
| 0da63ae049 | |||
| 5081f4ab0c | |||
| ab2c65b9f2 | |||
| 7b16972636 | |||
| d403da541f | |||
| b790953846 | |||
| 994e702b2d | |||
| e989e22fbd | |||
| 97bbcbc4b9 | |||
| caef4a460f | |||
| 1641572377 | |||
| 3e4677f0b8 | |||
| e3c81400bc | |||
| 43c6b7cbb9 | |||
| e5b9dec07e | |||
| bd7f2d7669 | |||
| 830d1ffd90 | |||
| 1504870094 | |||
| 9c0d231085 | |||
| d5411a4f87 | |||
| 18804873b6 | |||
| ff878bf884 | |||
| b4645560f6 | |||
| b210b7f83f | |||
| 2bb11cd2eb | |||
| 9c0d89a9b0 | |||
| 782466cc73 | |||
| fe45498199 | |||
| aacca8434a | |||
| 88dcfdcf30 | |||
| 3d9a020178 | |||
| 7eded397f7 | |||
| 8a7dc4d009 | |||
| aabe510663 | |||
| 0f780eca35 | |||
| 91dd67204b | |||
| e9e6cfd19b | |||
| d2413055e3 | |||
| d5d902d05e | |||
| 12c014d79f | |||
| 6472138b54 | |||
| 4e1218e191 | |||
| cb1d384a03 | |||
| 57ab818538 | |||
| 10f017275d | |||
| 7e6eccfbc9 | |||
| d29e2e25b2 | |||
| 44b3e31d5a | |||
| 0b356b1886 | |||
| 1a5a89e3d1 | |||
| 571be5bf77 | |||
| a96785cca7 | |||
| 547aa3fede | |||
| fe61a4fe7f | |||
| 176ee13455 | |||
| 50b6a95fee | |||
| 8f06ef1645 | |||
| 3fc27a627f | |||
| a47cebfdd5 | |||
| c8e8a4aba7 | |||
| 46d6a8196b | |||
| 8b225699c9 | |||
| 69d19c868c | |||
| 943f7969c0 | |||
| 4724ccc780 | |||
| 71685e582c | |||
| e27629ca98 | |||
| 8f2a091fbe | |||
| 4d953a8452 | |||
| 99a8e85bed | |||
| 597d201b30 | |||
| 809e45c1e2 | |||
| ca4b1b6ba3 | |||
| 1b2eda66d3 | |||
| 9a4f9b373a | |||
| 801c0c2a52 | |||
| 2c8c1f856b | |||
| 71daab636d | |||
| 532109ba8c | |||
| 0174cb94d3 | |||
| b9c24d8ac3 | |||
| 3708915dc8 | |||
| 9d6efd2dbd | |||
| 5321dae917 | |||
| 6d014ea291 | |||
| 5c9f7f4db8 | |||
| 7fa73b64bc | |||
| 43e675761c | |||
| dc7270598c | |||
| 910c44f4f3 | |||
| 0ea75845af | |||
| 0eb4f84ad8 | |||
| 0d4911a0d4 | |||
| 2eeedf6c55 | |||
| 82dbdb523b | |||
| 65c6dddf98 | |||
| d033378784 | |||
| fe2a5b461d | |||
| 5383549e2a | |||
| 344cf5c308 | |||
| 388d7eb772 | |||
| 9c8c447f54 | |||
| 523f988b16 | |||
| 6e201bc4b6 | |||
| 8188c48d5b | |||
| 9d2e875501 | |||
| 8f20e423f6 | |||
| df1107b2ea | |||
| 6afc680d93 | |||
| b0ee619d0a | |||
| a9243dddb9 | |||
| 18e6803eda | |||
| b4937b5e25 | |||
| 14e446497d | |||
| f45ae2da51 | |||
| 940bb7b351 | |||
| 2cc208f8a1 | |||
| 530c0f5a05 | |||
| 0937e11c2d | |||
| cbdb623321 | |||
| 76e3999de2 | |||
| 021f31186a | |||
| 9bc161e4b1 | |||
| 94d344765d | |||
| 8868ee2686 | |||
| 3a981ef490 | |||
| b813908493 | |||
| d5793858b0 | |||
| 3303846fce | |||
| a84e72f4ff | |||
| 5e9485b7c5 | |||
| 87597c206d | |||
| 0ca2a879af | |||
| 124db1cc7f | |||
| dc85a648d2 | |||
| a2ade445ac | |||
| d39c35439a | |||
| 33c4363c93 | |||
| 0aa0f96346 | |||
| 075fed796b | |||
| cdd862f261 | |||
| 30be30212c | |||
| ea53713580 | |||
| e44dce029e | |||
| 802fc6e77e | |||
| 9a53a256de | |||
| 7023c18c65 | |||
| e100ddfd8c | |||
| a7596c3499 | |||
| aeca178de7 | |||
| 4796acbd49 | |||
| 3d44f10989 | |||
| 5c675a8e0b | |||
| e7c03fa587 | |||
| e80cd15112 | |||
| cf18753986 | |||
| 1a18d51869 | |||
| c50859fe62 | |||
| 29700853fd | |||
| d3f6d6ea4d | |||
| 640e5d1ed2 | |||
| 9bc18d1888 | |||
| f33c110340 | |||
| 7d7736703f | |||
| d573b1ba33 | |||
| 9deddaaecd | |||
| 98e1c57db3 | |||
| 3967d82a28 | |||
| 35f60e9899 | |||
| edc8c4cbb3 | |||
| c0cd43a250 | |||
| 9f378d1342 | |||
| ac38c6b0a0 | |||
| 148f64cca1 | |||
| 1d2de3d3e0 | |||
| 090b111b7a | |||
| ddc1899b71 | |||
| 91afbf2347 | |||
| 1c9802f9ce | |||
| c3ddf66058 | |||
| b3113fbcbc | |||
| 85540e1ef4 | |||
| bb47626b67 | |||
| a9e4e885a1 | |||
| 1552a5bb51 | |||
| e4c59f402d | |||
| bcfc573312 | |||
| 224bed6872 | |||
| 2a4158d878 | |||
| e0002b36bb | |||
| a34652e99c | |||
| 938e907322 | |||
| 3aa1f1d3ed | |||
| ec96505709 | |||
| fe9afeb6a2 | |||
| 8c6bf54cf9 | |||
| 4d07444bc4 | |||
| 25ce47aa06 | |||
| 347292ca3c | |||
| abd4de973b | |||
| d5b386d5db | |||
| 6bc2ddc3d4 | |||
| bedc673b98 | |||
| 1da0ad3926 | |||
| 7553ec4dd4 | |||
| 2af7e34ee2 | |||
| f7e1d86949 | |||
| ec5363abbc | |||
| 304a7018d3 | |||
| f632dd11fa | |||
| 223677c7ff | |||
| f7b1754257 | |||
| f59d7a3836 | |||
| 46e7f90b34 | |||
| 22bed6212b | |||
| 8b11cbe549 | |||
| 80ab800ec3 | |||
| f9bacfd453 | |||
| 6cacc7f2c7 | |||
| f350666920 | |||
| b87f321cae | |||
| 3279b2ef67 | |||
| 80867a9b3b | |||
| ddcf6db9f7 | |||
| 9de279b819 | |||
| 6eb5a47cdb | |||
| 96cf8df98e | |||
| d057d1f441 | |||
| 16cf012583 | |||
| 7807afa13d | |||
| 0ccedb4f42 | |||
| 80d36a783f | |||
| c49f31748c | |||
| 2c14066675 | |||
| 039b76179a | |||
| 7b969e2f62 | |||
| 7647fea036 | |||
| 49a828877a | |||
| 395ecaff7e | |||
| 10a29a676e | |||
| 41cafa4d98 | |||
| 8933184c2d | |||
| 3b2a05016e | |||
| c344bfd6ce | |||
| 3a0f5b155e | |||
| 15987815a8 | |||
| d91bd29d58 | |||
| ccce2d88b8 | |||
| ebf2f86eb5 | |||
| 70fb17a9f4 | |||
| 6cae60940c | |||
| 8c0c30e371 | |||
| 54c1ed1997 | |||
| 5d5bfec63d | |||
| 69b84d865c | |||
| 9a484408f6 | |||
| f08e201045 | |||
| af3f17a8ae | |||
| 9448363b95 | |||
| a5086a0e83 | |||
| 8bb66b489b | |||
| 9d9e69f22d | |||
| 1828d06122 | |||
| 576c1ae47b | |||
| ea4bba0dea | |||
| 2623aa00ed | |||
| e7d404fff4 | |||
| ab07e8d099 | |||
| 5778f06b1f | |||
| 0be7d4a671 | |||
| d970ddc9b4 | |||
| 0a3f3d6c6b | |||
| d0cb3bb51c | |||
| 8c6a2bdada | |||
| d311818604 | |||
| 531f093514 | |||
| e7c785105d | |||
| 01d05d7d96 | |||
| b31b040903 | |||
| 53040ba48a | |||
| 66b7c537c5 | |||
| 18879a301a | |||
| 736d0fa10e | |||
| 1052e9f36c | |||
| 426ceff2e9 | |||
| 9199b7980f | |||
| 95b77c1524 | |||
| b18b6505f3 | |||
| e7eaced156 | |||
| 6113420a02 | |||
| 0cf23e266d | |||
| 3f4e5004a4 | |||
| d9a7ceeedd | |||
| 7538153d0f | |||
| b39f5fcac2 | |||
| 2007b88ae1 | |||
| 9c16acb445 | |||
| c63c467182 | |||
| a211de6bc1 | |||
| e2824aaec4 | |||
| 5f5fc14c19 | |||
| 2acfb7df3d | |||
| ee1bd73788 | |||
| bb0bdae2fd | |||
| ec170cce04 | |||
| 9a7861eaad | |||
| c28f7bfc9a | |||
| 0a292381e1 | |||
| 39f14cdaae | |||
| ce3db201ff | |||
| 35ba45c1d5 | |||
| bdda7c3ddf | |||
| 3016192052 | |||
| 30b8497b1e | |||
| e3d9a29765 | |||
| 5ff76b29b9 | |||
| a26ae476ce | |||
| 1ad8a84201 | |||
| 8d30efddc5 | |||
| 9ef6e139f7 | |||
| 9498debf6d | |||
| 21571b0050 | |||
| dfdb4bbade | |||
| 629480d4ae | |||
| abe7cb1366 | |||
| 326ea5cfb8 | |||
| cdf61de493 | |||
| 2e5cf5a4f3 | |||
| 45c685fab7 | |||
| 15c73e1ece | |||
| da83ed3f34 | |||
| 9e7d832d38 | |||
| 0edbc8555b | |||
| 25cd34ef29 | |||
| 01fd9d719e | |||
| a7a530487b | |||
| 32b6726968 | |||
| 16bf388c30 | |||
| 5f56761842 | |||
| 61f56ab915 | |||
| 4b3e743520 | |||
| f0dc2e9a8c | |||
| 0611c1de96 | |||
| 695ecf7a0d | |||
| 2b5eb64540 | |||
| f12dcd7365 | |||
| 1144d93c43 | |||
| 5961611dfe | |||
| 31a5104730 | |||
| ccca6ed24f | |||
| f281fcb920 | |||
| 7fa15005ab | |||
| 09caf6afae | |||
| 43c3982d09 | |||
| 42f71da725 | |||
| 46cffb0660 | |||
| 9add1b4326 | |||
| f795510e0c | |||
| 052252ae37 | |||
| d8ff75c147 | |||
| f7b8eeeec5 | |||
| 8477f99762 | |||
| daff24615a | |||
| b30216b4c0 | |||
| 66f12ab76b | |||
| 8e696b222e | |||
| 0fdb85067a | |||
| ba2a9d7f34 | |||
| 9512053d69 | |||
| 3cb1ffc153 | |||
| ce68d6d77d | |||
| 357b87a281 | |||
| d6828c284a | |||
| e2658c9a1b | |||
| 438255df43 | |||
| c493240343 | |||
| 8ca4750f0f | |||
| 4ea539e69d | |||
| c63fd0605f | |||
| b7bf67c057 | |||
| 8704c61e81 | |||
| 555d478d94 | |||
| c375ac0713 | |||
| 685b637c37 | |||
| 54b00d5966 | |||
| d83a755a21 | |||
| 2786a7f3ba | |||
| 44b761dc17 | |||
| ad1c06c392 | |||
| b6de4538fb | |||
| 74f5cba651 | |||
| d4fb419f4c | |||
| d3c15495c2 | |||
| 8b6659b517 | |||
| cf68258531 | |||
| 55de51acb9 | |||
| 84b2d2b9ac | |||
| c27a086c5d | |||
| 6f17631ae8 | |||
| 26cdf24ca0 | |||
| ac83640093 | |||
| 7614ff24ab | |||
| cfdc8806f9 | |||
| f19e150bd0 | |||
| 8c311f9f40 | |||
| 47a228611c | |||
| ab7fa5575e | |||
| 5923ed5e1e | |||
| 228fb38b67 | |||
| 6415b50638 | |||
| 3984e3cac5 | |||
| d8f74f2c8e | |||
| 402eb726d2 | |||
| a180d836ae | |||
| 040160efc9 | |||
| ab6f9108b0 | |||
| e5a949334d | |||
| 5b41b980f6 | |||
| c03950c0fa | |||
| 30cd6bf15d | |||
| bd7ab010ca | |||
| 71e2456371 | |||
| 834357fb4f | |||
| 68c7aa108a | |||
| b5dbe135e7 | |||
| fcb678a11f | |||
| 8496624617 | |||
| 46b17b8d91 | |||
| d1689d3e81 | |||
| cbd475cc30 | |||
| 10e62f5828 | |||
| 6c1d0cab8a | |||
| 0826ceada1 | |||
| e9dc2e26aa | |||
| 36c2991c2f | |||
| 3c40237cc6 | |||
| 5c52b74574 | |||
| 7e39ccf80c | |||
| e91ac3d7cf | |||
| a88e168b69 | |||
| 01240715a7 | |||
| af677d03e4 | |||
| 7de3ce7d13 | |||
| a094fd9ba2 | |||
| 16d35bfd99 | |||
| 983fb132e2 | |||
| 4200c203b6 | |||
| 0a1b7a39bf | |||
| 76406f1f9c | |||
| 1446ae8ada | |||
| eba1924a08 | |||
| cdc2beb202 | |||
| 6a1f12281c | |||
| b72f9ef1b8 | |||
| 4e484ad656 | |||
| 6f1f234b40 | |||
| 97723c5732 | |||
| e2088df620 | |||
| f71eb46023 | |||
| 6cd32e7bd6 | |||
| 5d557c73e8 | |||
| e5161c9622 | |||
| 5323106a1a | |||
| 33e30b8fef | |||
| 9997b8c599 | |||
| 63edd26442 | |||
| b4870d1e04 | |||
| 26f1a5706b | |||
| a5fef987df | |||
| a8167c5e0c | |||
| b40aff1058 | |||
| 1ed8d7ca44 | |||
| 03fd1e3b01 | |||
| e7e7a6ca97 | |||
| 8057d13c22 | |||
| c4147980c9 | |||
| a021b66a9b | |||
| f98585acbe | |||
| 4bd49938f3 | |||
| 0c8cea428d | |||
| cd057686ef | |||
| 65621cae81 | |||
| 99be733e29 | |||
| 6e4a9ff05c | |||
| d8a5ee4e1d | |||
| 5a28372850 | |||
| 1219c9ca17 | |||
| 2204c7523a | |||
| 47955a3527 | |||
| 0e3675a1b6 | |||
| 80ee43db71 | |||
| 8aee92218d | |||
| f93bca77ce | |||
| 11c8219f79 | |||
| a9ac3f2015 | |||
| 3f496b5028 | |||
| c6b55a8b47 | |||
| 2e767943c4 | |||
| 5da87a5f8d | |||
| d643917904 | |||
| 5d67f4ba65 | |||
| 7fef74d041 | |||
| 97e531dd95 | |||
| caa2aec727 | |||
| 2c64004e7c | |||
| d2cc0a3f02 | |||
| f42596a2a7 | |||
| fa1ebafae4 | |||
| f2126a8aa6 | |||
| 209589ccc7 | |||
| a57727b028 | |||
| d3c4cb2534 | |||
| 8be03cd80d | |||
| d2b44a87e6 | |||
| 885e27cbbe | |||
| db76315506 | |||
| b122ba1545 | |||
| 1d8fb1f6ee | |||
| 064d0eeb20 | |||
| 1f562bfda4 | |||
| 7449cfb5fb | |||
| d3bd550ed7 | |||
| d399f9f9c4 | |||
| 51ef48b03e | |||
| d84b018c56 | |||
| 865c211d91 | |||
| 14676ab361 | |||
| 7f00d8c3dc | |||
| acd523e699 | |||
| 973b91cd3f | |||
| 3e009decfb | |||
| 715c5967c7 | |||
| 55680a13fe | |||
| 1ef48ee323 | |||
| 8d0265cd3e | |||
| da4b1e7007 | |||
| 3609f88c32 | |||
| 010d8dce52 | |||
| d325076e61 | |||
| 4d459edcf8 | |||
| 3b49bc9d6a | |||
| 837eddf1df | |||
| 088d2d88c8 | |||
| 4c6cd51c26 | |||
| 74e454cd0b | |||
| 3c8475636c | |||
| a6a7c516a6 | |||
| 6a5d21696e | |||
| 52d4d5721b | |||
| 7617d25501 | |||
| 59b0f62a6f | |||
| 4776415c14 | |||
| 0af7630523 | |||
| 3adb512e39 | |||
| 3bcb1f6097 | |||
| dea8c79811 | |||
| 7d511b1e13 | |||
| e6d8648074 | |||
| 5b1bad8705 | |||
| 57bdc48e6d | |||
| 6d138fe89f | |||
| db5ed2b1c1 | |||
| a8ec3ddaa7 | |||
| be6385bf2f | |||
| cf955a7a60 | |||
| 104f0abf9b | |||
| 31524e4eb4 | |||
| df063a7298 | |||
| f40a5445c9 | |||
| d3ebb51176 | |||
| 53ff8cc768 | |||
| 1ee27fb979 | |||
| 23a4080358 | |||
| 358ec39304 | |||
| 5de422d287 | |||
| 2064ae4235 | |||
| 8f3a0a28cf | |||
| ddc9a07eef | |||
| 7cc5a37c4b | |||
| 1f84c10b50 | |||
| e4d0f37b14 | |||
| 59d3f9dd73 | |||
| dbbb31aa5e | |||
| 7ca995bf9f | |||
| 05fcb5047f | |||
| 9c658018f4 | |||
| 490e48123c | |||
| d05b7bba21 | |||
| 63a5835db8 | |||
| 30f513d586 | |||
| 80bfc11a83 | |||
| f9d3e11956 | |||
| 0418cb318f | |||
| c7c9edc2dc | |||
| c4b622fcf5 | |||
| 48e0a262de | |||
| 6266898738 | |||
| 23e49d4f7c | |||
| c67ba218fa | |||
| ebff7a9d09 | |||
| c651917da8 | |||
| 9cdf70f9d8 | |||
| 40d418c007 | |||
| e92ed21627 | |||
| a8c3125f00 | |||
| 3e453ec236 | |||
| ba941f02bf | |||
| 50816ba01b | |||
| 45d56d4efc | |||
| 262458e1d0 | |||
| 5d8a717131 | |||
| 8bac9c2784 | |||
| b496e1fba8 | |||
| 8977d71d0a | |||
| 40d36bb0c5 | |||
| e96b9d410e | |||
| 6b38d8f0ee | |||
| 21328f75ea | |||
| a6e6a2dd12 | |||
| 9e0fd2a3d2 | |||
| debda06f8e | |||
| 0115012eff | |||
| 5fbec8a513 | |||
| 29cc8a3529 | |||
| 26bfcae3e7 | |||
| 64f8123987 | |||
| f88064273d | |||
| 6e2ee25fee | |||
| 492052e04e | |||
| 851950338d | |||
| 43ccaa60e6 | |||
| 88fca5135d | |||
| b72fb334d4 | |||
| b491bf5dfe | |||
| 423ca57f10 | |||
| 8a2e035dc9 | |||
| 835d8dc0f4 | |||
| 934e176b47 | |||
| f25c282249 | |||
| 9c40d8b9b3 | |||
| aefc409173 | |||
| 53d9ddfacd | |||
| 87dddbb773 | |||
| 352b04302a | |||
| 8faf304b14 | |||
| 6a579226cd | |||
| a82d2346a8 | |||
| 7a525257bd | |||
| c38cb2e0ff | |||
| ab5de66405 | |||
| e0cdbb8294 | |||
| 2ec3769bb5 | |||
| 5e633363a9 | |||
| 9761da9de3 | |||
| 5d9a2a483b | |||
| afe2e339b3 | |||
| a9a8947744 | |||
| 2b4823ab84 | |||
| 3772179692 | |||
| 14104d00a2 | |||
| 58ab92f7a8 | |||
| af4391857e | |||
| 5a29859183 | |||
| f529eca41c | |||
| c3bb6ac2b5 | |||
| 54d6634a8b | |||
| f131b0a016 | |||
| f65942d83b | |||
| 423a394bb4 | |||
| 7f41efd74d | |||
| 8312f5d20e | |||
| ac45e5bfac | |||
| b91b63615c | |||
| ec2f6064f4 | |||
| ac982ef991 | |||
| daa74368e1 | |||
| 5897553265 | |||
| 3fc4203261 | |||
| dc0b387b6e | |||
| 807e76f112 | |||
| c1e7fba8d9 | |||
| 6fe807e7af | |||
| baa8c58813 | |||
| c6925989ed | |||
| 3d27fed72f | |||
| 446ea4deab | |||
| c9fae27078 | |||
| 46b340a06b | |||
| b228f1397b | |||
| af73d05bbd | |||
| f0fca34b7e | |||
| 4788ea632e |
@@ -1,734 +0,0 @@
|
||||
# !!!! BETA Makefile !!!!
|
||||
# !!!! Use at own risk !!!!
|
||||
#----------------------------------------------------------------------------
|
||||
# On command line:
|
||||
#
|
||||
# make all = Make software.
|
||||
#
|
||||
# make clean = Clean out built project files.
|
||||
#
|
||||
# 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".
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
#----------- BUILD OPTIONS ---------------------------
|
||||
|
||||
# PCB version
|
||||
# Values: STD, V4, ARM
|
||||
PCB = STD
|
||||
|
||||
# PCB revision
|
||||
# Values: REVA, REVB
|
||||
PCBREV = REVB
|
||||
|
||||
# Enable JETI-Telemetry or FrSky Telemetry reception on UART0
|
||||
# For this option you need to modify your hardware!
|
||||
# More information at [insertURLhere]
|
||||
# Values = STD, FRSKY, JETI, NMEA, ARDUPILOT, MAVLINK
|
||||
EXT = STD
|
||||
|
||||
# Enable heli menu
|
||||
# Values = YES, NO
|
||||
HELI = NO
|
||||
|
||||
# Enable templates menu
|
||||
# Values = YES, NO
|
||||
TEMPLATES = YES
|
||||
|
||||
# Enable navigation with Pots / Rotary encoders
|
||||
# Values = NO
|
||||
# POT1 (only POT1 available for fields modification),
|
||||
# POT2 (menus scroll),
|
||||
# POT3 (cursor down/up),
|
||||
# POTS (POT1, POT2, POT3),
|
||||
NAVIGATION = NO
|
||||
|
||||
# Switches autmatic selection
|
||||
# Values = YES, NO
|
||||
AUTOSWITCH = NO
|
||||
|
||||
# AUDIO Mods
|
||||
# Values = YES, NO
|
||||
AUDIO = NO
|
||||
|
||||
# HAPTIC Mods
|
||||
# Values = YES, NO
|
||||
HAPTIC = NO
|
||||
|
||||
# SPLASH on START
|
||||
SPLASH = YES
|
||||
|
||||
# PPM center adjustable
|
||||
# Values = YES, NO
|
||||
PPM_CENTER_ADJUSTABLE = NO
|
||||
|
||||
# Limits display in the LIMITS
|
||||
# Values = PERCENT, US
|
||||
PPM_LIMITS_UNIT = PERCENT
|
||||
|
||||
# Decimals display in the main view / PPM calibration,
|
||||
# Values = YES, NO
|
||||
DECIMALS = YES
|
||||
|
||||
# DISPLAY_USER_DATA to display on screen data from FrSky module (testing/demo purpose)
|
||||
# Values = YES, NO
|
||||
DISPLAY_USER_DATA = NO
|
||||
|
||||
# FrSky Hub
|
||||
# Values = YES, NO
|
||||
FRSKY_HUB = YES
|
||||
|
||||
# WS HowHigh
|
||||
# Values = YES, NO
|
||||
WS_HOW_HIGH = YES
|
||||
|
||||
# WS HowHigh
|
||||
# Values = YES, NO
|
||||
VARIO = YES
|
||||
|
||||
# SDCARD Logs
|
||||
# Values = YES, NO
|
||||
SDCARD = NO
|
||||
|
||||
# PXX (FrSky PCM) protocol
|
||||
PXX = NO
|
||||
|
||||
# DSM2 (Spektrum) protocol
|
||||
DSM2 = NO
|
||||
|
||||
# SOMO-14D module (V4 board only)
|
||||
SOMO = NO
|
||||
|
||||
# TRANSLATIONS
|
||||
# Values = en, fr, se
|
||||
TRANSLATIONS = EN
|
||||
|
||||
# UNITS
|
||||
# Values = imperial, metric
|
||||
UNITS = METRIC
|
||||
|
||||
# EEPROM_PROGRESS_BAR
|
||||
# Values = YES, NO
|
||||
EEPROM_PROGRESS_BAR = NO
|
||||
|
||||
# Enable extra rotary encoders (V4 board only)
|
||||
# Values = YES, NO
|
||||
EXTRA_ROTARY_ENCODERS = NO
|
||||
|
||||
# DEBUG mode
|
||||
DEBUG = NO
|
||||
|
||||
# Flight Phases
|
||||
# Values = YES, NO
|
||||
FLIGHT_PHASES = YES
|
||||
|
||||
#------- END BUILD OPTIONS ---------------------------
|
||||
|
||||
# Define programs and commands.
|
||||
SHELL = sh
|
||||
IMG2LBM = python ../util/img2lbm.py
|
||||
SVNREV = $(shell sh -c "svnversion | egrep -o '[[:digit:]]+[[:alpha:]]*$$'")
|
||||
|
||||
CPPDEFS =
|
||||
|
||||
# MCU name
|
||||
ifeq ($(PCB), STD)
|
||||
TRGT = avr-
|
||||
MCU = atmega64
|
||||
CPPDEFS += -DF_CPU=$(F_CPU)UL
|
||||
endif
|
||||
|
||||
ifeq ($(PCB), V4)
|
||||
ifeq ($(PCBREV), REV0)
|
||||
CPPDEFS += -DREV0
|
||||
else
|
||||
CPPDEFS += -DREV1
|
||||
endif
|
||||
TRGT = avr-
|
||||
MCU = atmega2560
|
||||
CPPDEFS += -DF_CPU=$(F_CPU)UL
|
||||
endif
|
||||
|
||||
ifeq ($(PCB), ARM)
|
||||
ifeq ($(PCBREV), REVA)
|
||||
CPPDEFS += -DREVA
|
||||
LDSCRIPT = ersky9x/sam3s2c_flash.ld
|
||||
else
|
||||
CPPDEFS += -DREVB
|
||||
LDSCRIPT = ersky9x/sam3s4c_flash.ld
|
||||
endif
|
||||
TRGT = arm-none-eabi-
|
||||
MCU = cortex-m3
|
||||
endif
|
||||
|
||||
CC = $(TRGT)gcc
|
||||
OBJCOPY = $(TRGT)objcopy
|
||||
OBJDUMP = $(TRGT)objdump
|
||||
SIZE = $(TRGT)size
|
||||
NM = $(TRGT)nm
|
||||
|
||||
AVRDUDE = avrdude
|
||||
REMOVE = rm -f
|
||||
REMOVEDIR = rm -rf
|
||||
|
||||
# Processor frequency.
|
||||
F_CPU = 16000000
|
||||
|
||||
# Output format. (can be srec, ihex, binary)
|
||||
FORMAT = ihex
|
||||
|
||||
# Target file name (without extension).
|
||||
TARGET = open9x
|
||||
|
||||
# List C++ source files here. (C dependencies are automatically generated.)
|
||||
CPPSRC = open9x.cpp $(PULSESSRC) stamp.cpp menus.cpp model_menus.cpp general_menus.cpp main_views.cpp statistics_views.cpp $(EEPROMSRC) lcd.cpp drivers.cpp o9xstrings.cpp
|
||||
|
||||
ifeq ($(EXT), JETI)
|
||||
CPPSRC += jeti.cpp
|
||||
endif
|
||||
|
||||
ifeq ($(EXT), ARDUPILOT)
|
||||
CPPSRC += ardupilot.cpp
|
||||
endif
|
||||
|
||||
ifeq ($(EXT), NMEA)
|
||||
CPPSRC += nmea.cpp
|
||||
endif
|
||||
|
||||
# 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.
|
||||
DBGFMT = 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 = . translations
|
||||
|
||||
# NOTE: PCB version now overrides all the earlier individual settings
|
||||
# These individual settings work only for PCB=STD
|
||||
|
||||
CPPDEFS += -DTRANSLATIONS_$(TRANSLATIONS)
|
||||
|
||||
ifeq ($(UNITS), IMPERIAL)
|
||||
CPPDEFS += -DIMPERIAL_UNITS
|
||||
endif
|
||||
|
||||
# If POT1/POTS/RE1 is used for fields modification
|
||||
ifeq ($(NAVIGATION), POT1)
|
||||
CPPDEFS += -DNAVIGATION_POT1
|
||||
endif
|
||||
ifeq ($(NAVIGATION), POT2)
|
||||
CPPDEFS += -DNAVIGATION_POT2
|
||||
endif
|
||||
ifeq ($(NAVIGATION), POT3)
|
||||
CPPDEFS += -DNAVIGATION_POT3
|
||||
endif
|
||||
ifeq ($(NAVIGATION), POTS)
|
||||
CPPDEFS += -DNAVIGATION_POT1 -DNAVIGATION_POT2 -DNAVIGATION_POT3
|
||||
endif
|
||||
|
||||
ifeq ($(AUTOSWITCH), YES)
|
||||
CPPDEFS += -DAUTOSWITCH
|
||||
endif
|
||||
|
||||
ifeq ($(SPLASH), YES)
|
||||
CPPDEFS += -DSPLASH
|
||||
endif
|
||||
|
||||
ifeq ($(FLIGHT_PHASES), YES)
|
||||
CPPDEFS += -DFLIGHT_PHASES
|
||||
endif
|
||||
|
||||
# If ARDUPILOT-Support is enabled
|
||||
ifeq ($(EXT), ARDUPILOT)
|
||||
CPPDEFS += -DARDUPILOT
|
||||
endif
|
||||
|
||||
# If NMEA-Support is enabled
|
||||
ifeq ($(EXT), NMEA)
|
||||
CPPDEFS += -DNMEA
|
||||
endif
|
||||
|
||||
# If JETI-Support is enabled
|
||||
ifeq ($(EXT), JETI)
|
||||
MODS:=${MODS}J
|
||||
CPPDEFS += -DJETI
|
||||
endif
|
||||
|
||||
ifeq ($(EXT), MAVLINK)
|
||||
MODS:=${MODS}M
|
||||
CPPDEFS += -DMAVLINK
|
||||
CPPSRC += mavlink.cpp rotarysw.cpp serial.cpp
|
||||
endif
|
||||
|
||||
# If FRSKY-Support is enabled
|
||||
ifeq ($(EXT), FRSKY)
|
||||
MODS:=${MODS}F
|
||||
CPPDEFS += -DFRSKY
|
||||
CPPSRC += frsky.cpp
|
||||
# If FRSKY-Hub is enabled
|
||||
ifeq ($(FRSKY_HUB), YES)
|
||||
CPPDEFS += -DFRSKY_HUB
|
||||
endif
|
||||
# If WS HowHigh is enabled
|
||||
ifeq ($(WS_HOW_HIGH), YES)
|
||||
MODS:=${MODS}W
|
||||
CPPDEFS += -DWS_HOW_HIGH
|
||||
endif
|
||||
# If Vario is enabled
|
||||
ifeq ($(VARIO), YES)
|
||||
CPPDEFS += -DVARIO
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(DEBUG), YES)
|
||||
CPPDEFS += -DDEBUG
|
||||
endif
|
||||
|
||||
ifeq ($(EEPROM_PROGRESS_BAR), YES)
|
||||
CPPDEFS += -DEEPROM_PROGRESS_BAR
|
||||
endif
|
||||
|
||||
ifeq ($(SDCARD), YES)
|
||||
CPPDEFS += -DSDCARD
|
||||
endif
|
||||
|
||||
RUN_FROM_FLASH = 1
|
||||
|
||||
ifeq ($(PCB), ARM)
|
||||
# V4 ARM, so ...
|
||||
OPT = 2
|
||||
CPPDEFS += -DPCBARM -DAUDIO -DHAPTIC -DPXX -DDSM2 -DDSM2_PPM
|
||||
EXTRAINCDIRS += ersky9x
|
||||
BOARDSRC = board_ersky9x.cpp
|
||||
EXTRABOARDSRC = ersky9x/core_cm3.c ersky9x/board_lowlevel.c ersky9x/crt.c ersky9x/vectors_sam3s.c
|
||||
CPPSRC += ersky9x/ff.cpp ersky9x/diskio.cpp ersky9x/gtime.cpp
|
||||
EEPROMSRC = eeprom_arm.cpp
|
||||
PULSESSRC = pulses_arm.cpp
|
||||
CPPSRC += ersky9x/audio.cpp haptic.cpp
|
||||
CPPSRC += ersky9x/sound_driver.cpp ersky9x/haptic_driver.cpp ersky9x/sdcard_driver.cpp
|
||||
endif
|
||||
|
||||
ifeq ($(PCB), V4)
|
||||
# V4 PCB, so ...
|
||||
OPT = 2
|
||||
CPPDEFS += -DPCBV4 -DAUDIO -DHAPTIC -DROTARY_ENCODERS
|
||||
EXTRAINCDIRS += gruvin9x stock
|
||||
BOARDSRC += board_gruvin9x.cpp
|
||||
EEPROMSRC = eeprom_avr.cpp
|
||||
PULSESSRC = pulses_avr.cpp
|
||||
CPPSRC += stock/audio.cpp haptic.cpp
|
||||
|
||||
ifeq ($(SDCARD), YES)
|
||||
CPPSRC += gruvin9x/logs.cpp gruvin9x/gtime.cpp gruvin9x/rtc.cpp gruvin9x/ff.cpp gruvin9x/diskio.cpp
|
||||
MODS:=${MODS}S
|
||||
endif
|
||||
|
||||
ifeq ($(SOMO), YES)
|
||||
CPPSRC += gruvin9x/somo14d.cpp
|
||||
CPPDEFS += -DSOMO
|
||||
endif
|
||||
|
||||
ifeq ($(EXTRA_ROTARY_ENCODERS), YES)
|
||||
CPPDEFS += -DEXTRA_ROTARY_ENCODERS
|
||||
MODS:=${MODS}X
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(PCB), STD)
|
||||
# STD PCB, so ...
|
||||
OPT = s
|
||||
EXTRAINCDIRS += stock
|
||||
CPPDEFS += -DPCBSTD
|
||||
BOARDSRC = board_stock.cpp
|
||||
EEPROMSRC = eeprom_avr.cpp
|
||||
PULSESSRC = pulses_avr.cpp
|
||||
|
||||
ifeq ($(AUDIO), YES)
|
||||
CPPDEFS += -DAUDIO
|
||||
CPPSRC += stock/audio.cpp
|
||||
else
|
||||
CPPSRC += beeper.cpp
|
||||
endif
|
||||
|
||||
ifeq ($(HAPTIC), YES)
|
||||
CPPDEFS += -DHAPTIC
|
||||
CPPSRC += haptic.cpp
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
### Global Build-Option Directives ###
|
||||
|
||||
ifeq ($(PPM_CENTER_ADJUSTABLE), YES)
|
||||
CPPDEFS += -DPPM_CENTER_ADJUSTABLE
|
||||
endif
|
||||
|
||||
ifeq ($(PPM_LIMITS_UNIT), US)
|
||||
CPPDEFS += -DPPM_LIMITS_UNIT_US
|
||||
endif
|
||||
|
||||
ifeq ($(DECIMALS), YES)
|
||||
CPPDEFS += -DDECIMALS_DISPLAYED
|
||||
endif
|
||||
|
||||
ifeq ($(HELI), YES)
|
||||
MODS:=${MODS}H
|
||||
CPPDEFS += -DHELI
|
||||
endif
|
||||
|
||||
ifeq ($(TEMPLATES), YES)
|
||||
CPPDEFS += -DTEMPLATES
|
||||
CPPSRC += templates.cpp
|
||||
endif
|
||||
|
||||
ifeq ($(DISPLAY_USER_DATA), YES)
|
||||
CPPDEFS += -DDISPLAY_USER_DATA
|
||||
endif
|
||||
|
||||
ifeq ($(PXX), YES)
|
||||
CPPDEFS += -DPXX
|
||||
endif
|
||||
|
||||
ifeq ($(DSM2), SERIAL)
|
||||
CPPDEFS += -DDSM2 -DDSM2_SERIAL
|
||||
endif
|
||||
|
||||
ifeq ($(DSM2), PPM)
|
||||
CPPDEFS += -DDSM2 -DDSM2_PPM
|
||||
endif
|
||||
|
||||
#---------------- 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$(DBGFMT)
|
||||
CPPFLAGS += $(CPPDEFS)
|
||||
CPPFLAGS += -O$(OPT)
|
||||
CPPFLAGS += -Wall
|
||||
CPPFLAGS += -fno-exceptions
|
||||
CPPFLAGS += -Wno-strict-aliasing
|
||||
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
||||
|
||||
ifneq ($(PCB), ARM)
|
||||
GCCVERSIONGTE462 := $(shell expr 4.6.2 \<= `$(CC) -dumpversion`)
|
||||
ifeq ($(GCCVERSIONGTE462),1)
|
||||
CPPFLAGS += -flto
|
||||
endif
|
||||
CPPFLAGS += -fno-inline-small-functions
|
||||
endif
|
||||
|
||||
MATH_LIB = -lm
|
||||
|
||||
#---------------- 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,--defsym=__heap_start=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 += $(MATH_LIB)
|
||||
#LDFLAGS += -T linker_script.x
|
||||
|
||||
# Define Messages
|
||||
# English
|
||||
MSG_BEGIN = -------- begin --------
|
||||
MSG_END = -------- end --------
|
||||
MSG_SIZE_BEFORE = Size before:
|
||||
MSG_SIZE_AFTER = Size after:
|
||||
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_COMPILING = Compiling C++:
|
||||
MSG_CLEANING = Cleaning project:
|
||||
|
||||
# Combine all necessary flags and optional flags.
|
||||
# Add target processor to flags.
|
||||
|
||||
ifeq ($(PCB), ARM)
|
||||
ALL_CPPFLAGS = -c -mcpu=$(MCU) -mthumb -fomit-frame-pointer -fverbose-asm -Wa,-ahlms=open9x.lst -Dat91sam3s4 -DRUN_FROM_FLASH=1 $(CPPFLAGS) $(GENDEPFLAGS)
|
||||
else
|
||||
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS) -fwhole-program
|
||||
endif
|
||||
|
||||
MAJ_VER = ${shell sh -c "grep \"MAJ_VERS\" open9x.h | cut -d\ -f3 | egrep -o \"[[:digit:]]\""}
|
||||
MIN_VER = ${shell sh -c "grep \"MIN_VERS\" open9x.h | cut -d\ -f3"}
|
||||
|
||||
# Default target.
|
||||
all: begin gccversion sizebefore build sizeafter end
|
||||
|
||||
# Change the build target to build a HEX file or a library.
|
||||
ifeq ($(PCB), ARM)
|
||||
build: stamp_header font.lbm font_dblsize.lbm sticks.lbm s9xsplash.lbm allsrc.cpp elf remallsrc bin hex lss
|
||||
else
|
||||
build: stamp_header font.lbm font_dblsize.lbm sticks.lbm s9xsplash.lbm allsrc.cpp elf remallsrc hex eep lss sym
|
||||
endif
|
||||
|
||||
elf: $(TARGET).elf
|
||||
bin: $(TARGET).bin
|
||||
hex: $(TARGET).hex
|
||||
eep: $(TARGET).eep
|
||||
lss: $(TARGET).lss
|
||||
sym: $(TARGET).sym
|
||||
|
||||
# Build stamp-file
|
||||
stamp_header:
|
||||
@echo
|
||||
@echo "Generate Version-stamp:"
|
||||
@echo "//Automatically generated file (Makefile) - do not edit" > stamp-open9x.h
|
||||
@echo "#define DATE_STR \"`date +%Y-%m-%d`\"" >> stamp-open9x.h
|
||||
@echo "#define TIME_STR \"`date +%H:%M:%S`\"" >> stamp-open9x.h
|
||||
@echo "#define VERS_STR \"$(MAJ_VER).$(MIN_VER)-$(MODS)\"" >> stamp-open9x.h
|
||||
@echo "#define SVN_STR \"open9x-r$(SVNREV)\"" >> stamp-open9x.h
|
||||
@cat stamp-open9x.h
|
||||
|
||||
stock-stamp:
|
||||
@echo "#define DATE_STR \"`date +%Y-%m-%d`\"" > stamp-open9x-stock.txt
|
||||
@echo "#define TIME_STR \"`date +%H:%M:%S`\"" >> stamp-open9x-stock.txt
|
||||
@echo "#define VERS_STR \"$(MAJ_VER).$(MIN_VER)\"" >> stamp-open9x-stock.txt
|
||||
@echo "#define SVN_VERS \"open9x-r$(SVNREV)\"" >> stamp-open9x-stock.txt
|
||||
@cat stamp-open9x-stock.txt
|
||||
|
||||
v4-stamp:
|
||||
@echo "#define DATE_STR \"`date +%Y-%m-%d`\"" > stamp-open9x-v4.txt
|
||||
@echo "#define TIME_STR \"`date +%H:%M:%S`\"" >> stamp-open9x-v4.txt
|
||||
@echo "#define VERS_STR \"$(MAJ_VER).$(MIN_VER)\"" >> stamp-open9x-v4.txt
|
||||
@echo "#define SVN_VERS \"open9x-r$(SVNREV)\"" >> stamp-open9x-v4.txt
|
||||
@cat stamp-open9x-v4.txt
|
||||
|
||||
arm-stamp:
|
||||
@echo "#define DATE_STR \"`date +%Y-%m-%d`\"" > stamp-open9x-arm.txt
|
||||
@echo "#define TIME_STR \"`date +%H:%M:%S`\"" >> stamp-open9x-arm.txt
|
||||
@echo "#define VERS_STR \"$(MAJ_VER).$(MIN_VER)\"" >> stamp-open9x-arm.txt
|
||||
@echo "#define SVN_VERS \"open9x-r$(SVNREV)\"" >> stamp-open9x-arm.txt
|
||||
@cat stamp-open9x-arm.txt
|
||||
|
||||
font.lbm: font_6x1.xbm
|
||||
@echo
|
||||
@echo "Convert font from xbm to lbm:"
|
||||
$(IMG2LBM) $< $@ char
|
||||
$(IMG2LBM) translations/font_se.xbm translations/font_se.lbm char
|
||||
$(IMG2LBM) translations/font_de.xbm translations/font_de.lbm char
|
||||
$(IMG2LBM) translations/font_it.xbm translations/font_it.lbm char
|
||||
|
||||
font_dblsize.lbm: font_dblsize.xbm
|
||||
@echo
|
||||
@echo "Convert font from xbm to lbm:"
|
||||
$(IMG2LBM) $< $@ dblsize
|
||||
$(IMG2LBM) translations/font_dblsize_se.xbm translations/font_dblsize_se.lbm dblsize
|
||||
$(IMG2LBM) translations/font_dblsize_de.xbm translations/font_dblsize_de.lbm dblsize
|
||||
$(IMG2LBM) translations/font_dblsize_it.xbm translations/font_dblsize_it.lbm dblsize
|
||||
|
||||
sticks.lbm: sticks_4x1.xbm
|
||||
@echo
|
||||
@echo "Convert sticks from xbm to lbm:"
|
||||
$(IMG2LBM) $< $@ img 4
|
||||
|
||||
s9xsplash.lbm: s9xsplash.xbm
|
||||
@echo
|
||||
@echo "Convert font from xbm to lbm:"
|
||||
$(IMG2LBM) $< $@ img
|
||||
|
||||
# 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.
|
||||
ifeq ($(PCB), ARM)
|
||||
ELFSIZE = $(SIZE) $(TARGET).elf
|
||||
else
|
||||
ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf
|
||||
endif
|
||||
|
||||
sizebefore:
|
||||
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); fi
|
||||
|
||||
sizeafter:
|
||||
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); fi
|
||||
|
||||
# Display compiler version information.
|
||||
gccversion :
|
||||
@$(CC) --version
|
||||
|
||||
# gruvin: added extra include and lib paths to get simu working on my Mac
|
||||
FOXINC=-I/usr/local/include/fox-1.6 -I/usr/include/fox-1.6 \
|
||||
-I$(FOXPATH)/include \
|
||||
-I/opt/local/include/fox-1.6
|
||||
FOXLIB=-L/usr/local/lib \
|
||||
-L$(FOXPATH)/src/.libs \
|
||||
-L/opt/local/lib \
|
||||
-lFOX-1.6 \
|
||||
-Wl,-rpath,$(FOXPATH)/src/.libs
|
||||
|
||||
simu: $(BOARDSRC) $(CPPSRC) Makefile simu.cpp simpgmspace.cpp *.h *.lbm eeprom.bin
|
||||
g++ simu.cpp $(CPPFLAGS) $(BOARDSRC) $(CPPSRC) simpgmspace.cpp $(ARCH) -MD -DSIMU -o simu $(FOXINC) $(FOXLIB) -pthread
|
||||
|
||||
eeprom.bin:
|
||||
dd if=/dev/zero of=$@ bs=1 count=2048
|
||||
|
||||
|
||||
# Create final output files (.hex, .eep) from ELF output file.
|
||||
ifeq ($(PCB), ARM)
|
||||
%.hex: %.elf
|
||||
@echo
|
||||
@echo $(MSG_FLASH) $@
|
||||
$(OBJCOPY) -O ihex open9x.elf open9x.hex
|
||||
else
|
||||
%.hex: %.elf
|
||||
@echo
|
||||
@echo $(MSG_FLASH) $@
|
||||
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
|
||||
endif
|
||||
|
||||
%.bin: %.elf
|
||||
@echo
|
||||
@echo $(MSG_FLASH) $@
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
|
||||
%.eep: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EEPROM) $@
|
||||
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
|
||||
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
|
||||
|
||||
# Create a symbol table from ELF output file.
|
||||
%.sym: %.elf
|
||||
@echo
|
||||
@echo $(MSG_SYMBOL_TABLE) $@
|
||||
$(NM) -n $< > $@
|
||||
|
||||
# Create extended listing file from ELF output file.
|
||||
%.lss: %.elf
|
||||
@echo
|
||||
@echo $(MSG_EXTENDED_LISTING) $@
|
||||
$(OBJDUMP) -h -S $< > $@
|
||||
|
||||
# Concatenate all sources files in one big file to optimize size
|
||||
allsrc.cpp: Makefile $(BOARDSRC) $(CPPSRC) $(EXTRABOARDSRC)
|
||||
@rm -f allsrc.cpp
|
||||
for f in $(BOARDSRC) $(CPPSRC) $(EXTRABOARDSRC) ; do echo "# 1 \"$$f\"" >> allsrc.cpp; cat "$$f" >> allsrc.cpp; done
|
||||
|
||||
remallsrc:
|
||||
$(REMOVE) allsrc.cpp
|
||||
|
||||
# Link: create ELF output file from object files.
|
||||
ifeq ($(PCB), ARM)
|
||||
%.elf: allsrc.cpp
|
||||
@echo
|
||||
@echo $(MSG_COMPILING) $@
|
||||
$(CC) $(ALL_CPPFLAGS) $< -o allsrc.o
|
||||
$(CC) allsrc.o -mcpu=cortex-m3 -mthumb -nostartfiles -T$(LDSCRIPT) -Wl,-Map=$(TARGET).map,--cref,--no-warn-mismatch -o $@
|
||||
else
|
||||
%.elf: allsrc.cpp
|
||||
@echo
|
||||
@echo $(MSG_COMPILING) $@
|
||||
$(CC) $(ALL_CPPFLAGS) $< --output $@ $(LDFLAGS)
|
||||
endif
|
||||
|
||||
# Target: clean project.
|
||||
clean: begin clean_list end
|
||||
|
||||
clean_list :
|
||||
@echo
|
||||
@echo $(MSG_CLEANING)
|
||||
$(REMOVE) simu
|
||||
$(REMOVE) gtests
|
||||
$(REMOVE) gtest.a
|
||||
$(REMOVE) gtest_main.a
|
||||
$(REMOVE) $(TARGET).hex
|
||||
$(REMOVE) $(TARGET).eep
|
||||
$(REMOVE) $(TARGET).elf
|
||||
$(REMOVE) $(TARGET).map
|
||||
$(REMOVE) $(TARGET).sym
|
||||
$(REMOVE) $(TARGET).lss
|
||||
$(REMOVE) $(TARGET).lst
|
||||
$(REMOVE) $(SRC:.c=.s)
|
||||
$(REMOVE) *.o
|
||||
$(REMOVE) *.d
|
||||
$(REMOVE) *.lst
|
||||
$(REMOVE) allsrc.cpp
|
||||
|
||||
#### GOOGLE TESTS
|
||||
|
||||
GTEST_DIR = ../gtest-1.6.0
|
||||
|
||||
# Where to find user code.
|
||||
USER_DIR = ./
|
||||
|
||||
# Flags passed to the preprocessor.
|
||||
CPPFLAGS += -I$(GTEST_DIR)/include
|
||||
|
||||
# Flags passed to the C++ compiler.
|
||||
CXXFLAGS += -g -Wall -Wextra
|
||||
|
||||
# All Google Test headers. Usually you shouldn't change this
|
||||
# definition.
|
||||
GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
|
||||
$(GTEST_DIR)/include/gtest/internal/*.h
|
||||
|
||||
# House-keeping build targets.
|
||||
|
||||
# Builds gtest.a and gtest_main.a.
|
||||
|
||||
# Usually you shouldn't tweak such internal variables, indicated by a
|
||||
# trailing _.
|
||||
GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
|
||||
|
||||
# For simplicity and to avoid depending on Google Test's
|
||||
# implementation details, the dependencies specified below are
|
||||
# conservative and not optimized. This is fine as Google Test
|
||||
# compiles fast and for ordinary users its source rarely changes.
|
||||
gtest-all.o : $(GTEST_SRCS_)
|
||||
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
|
||||
$(GTEST_DIR)/src/gtest-all.cc
|
||||
|
||||
gtest_main.o : $(GTEST_SRCS_)
|
||||
$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
|
||||
$(GTEST_DIR)/src/gtest_main.cc
|
||||
|
||||
gtest.a : gtest-all.o
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
gtest_main.a : gtest-all.o gtest_main.o
|
||||
$(AR) $(ARFLAGS) $@ $^
|
||||
|
||||
# Builds a sample test. A test should link with either gtest.a or
|
||||
# gtest_main.a, depending on whether it defines its own main()
|
||||
# function.
|
||||
|
||||
gtests: $(CPPSRC) gtests.cpp simpgmspace.cpp *.h gtest_main.a
|
||||
g++ $(CPPSRC) gtests.cpp simpgmspace.cpp $(CPPFLAGS) -I$(GTEST_DIR) $(ARCH) -o gtests -lpthread -MD -DSIMU gtest_main.a
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
TODO list (no particular order)
|
||||
|
||||
- DSM2 channel order (Cam)
|
||||
- Variometer (rate as cm/sec)
|
||||
- Trace telemetry data
|
||||
@@ -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
@@ -1,121 +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 BEEPER_H
|
||||
#define BEEPER_H
|
||||
|
||||
extern uint8_t g_beepCnt;
|
||||
extern uint8_t beepAgain;
|
||||
extern uint8_t beepAgainOrig;
|
||||
extern uint8_t beepOn;
|
||||
extern bool warble;
|
||||
extern bool warbleC;
|
||||
#if defined(HAPTIC)
|
||||
extern uint8_t hapticTick;
|
||||
#endif
|
||||
|
||||
#if defined(PCBARM)
|
||||
#include "ersky9x/sound.h"
|
||||
inline void _beep(uint8_t b) {
|
||||
buzzer_sound(b);
|
||||
}
|
||||
#else
|
||||
inline void _beep(uint8_t b) {
|
||||
g_beepCnt = b;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void beep(uint8_t val);
|
||||
|
||||
#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)
|
||||
#define AUDIO_TELEMETRY_ALARM() { warble = !(g_tmr10ms % 60); AUDIO_WARNING2(); }
|
||||
|
||||
#define IS_AUDIO_BUSY() (g_beepCnt || beepAgain || beepOn)
|
||||
|
||||
#if !defined(PCBARM)
|
||||
FORCEINLINE void AUDIO_HEARTBEAT()
|
||||
{
|
||||
if(g_beepCnt) {
|
||||
if(!beepAgainOrig) {
|
||||
beepAgainOrig = g_beepCnt;
|
||||
beepOn = true;
|
||||
}
|
||||
g_beepCnt--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(beepAgain && beepAgainOrig) {
|
||||
beepOn = !beepOn;
|
||||
g_beepCnt = beepOn ? beepAgainOrig : 8;
|
||||
if(beepOn) beepAgain--;
|
||||
}
|
||||
else {
|
||||
beepAgainOrig = 0;
|
||||
beepOn = false;
|
||||
warble = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (beepOn) {
|
||||
warbleC = warble && !warbleC;
|
||||
if (warbleC)
|
||||
BUZZER_OFF;
|
||||
else
|
||||
BUZZER_ON;
|
||||
}
|
||||
else {
|
||||
BUZZER_OFF;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
-184
@@ -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;
|
||||
}
|
||||
}
|
||||
+235
@@ -0,0 +1,235 @@
|
||||
******************************************
|
||||
CHANGELOG: 07-05-2012 BSS
|
||||
AutoSwitch feature added
|
||||
Mix Warning was not so regular (sometime 2 ticks instead of 3)
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 06-05-2012 BSS
|
||||
FW options now stored in a byte of the EEPROM
|
||||
[Arm] getSwitch() problem with Custom Switches
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 05-05-2012 BSS
|
||||
[FrSky] Speed in Gauges configuration was buggy
|
||||
[FrSky] We stored Min Speed instead of Max Speed
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 04-05-2012 BSS
|
||||
Momentary Switches in Function Switches
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 03-05-2012 BSS
|
||||
[Arm] Audio / Haptic refactoring
|
||||
[Arm] Timer blocked at 10:55
|
||||
[V4] SDcard menu reworked
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 02-05-2012 BSS
|
||||
[V4/Arm] Problem in Models Move
|
||||
[stock] Flash saving (840bytes)
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 01-05-2012 BSS
|
||||
[FrSky] GPS distance bug fix
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 29-04-2012 BSS
|
||||
[V4/Arm] EEPROM marked as dirty on reboot
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 27-04-2012 BSS
|
||||
Vario feature added
|
||||
New EEPROM format 205
|
||||
[FrSky] Telemetry offset for A1/A2 on 12bits
|
||||
[V4] Models with empty name bug when SDcard backup
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 26-04-2012 BSS
|
||||
[Arm] 32Channels 9Phases 64Mixes 32Expos 32VSwitches 32FSwitches
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 23-04-2012 BSS
|
||||
[V4] SDcard Models storage implemented
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 20-04-2012 BSS
|
||||
[Stock] 400bytes flash saving
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 15-03-2012 BSS
|
||||
FAAST option in protocol to enable startPulses before the splash screen
|
||||
Telemetry configurable screen
|
||||
Confirmation before applying templates
|
||||
Used channels cleaned before applying a template
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 14-03-2012 BSS
|
||||
Potscroll option added
|
||||
|
||||
******************************************
|
||||
|
||||
Version 364:
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 04-03-2012 BSS
|
||||
New EEPROM format 205
|
||||
Introduction of differential in Mixers
|
||||
Introduction of Switches as Mixer Source (FULL now removed)
|
||||
Negative curves in Mixers
|
||||
Optimizations in Mixer
|
||||
Extended chars for localization
|
||||
Swedish translations
|
||||
Beep length updated
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 01-03-2012 BSS
|
||||
Feature "Use THR trim as a slider" now finished
|
||||
[FrSky] Jitter (2us) introduced by last optimization removed
|
||||
Trim parameter in Mixer is OFF if the source is not a stick
|
||||
GPS distance fixed
|
||||
|
||||
******************************************
|
||||
|
||||
Version 304:
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 28-02-2012 BSS
|
||||
Flash saving (600bytes)
|
||||
[FrSky] NO DATA displayed on the status line when nothing received
|
||||
Sticks/Pots center beep now more accurate
|
||||
Beeps length for center beep and inactivity reduced
|
||||
Vibration when MIN/MID/MAX trim position reached
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 27-02-2012 BSS
|
||||
Flash saving (idea from er9x)
|
||||
Trims2Offsets function removed
|
||||
A "Safety CHxx" function is not applied when it is currently edited
|
||||
The Stick Mode needs confirmation before being applied
|
||||
|
||||
******************************************
|
||||
|
||||
Version 288:
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 24-02-2012 BSS
|
||||
Throttle Trace bug solved when using P1-P3
|
||||
New way of dealing with recursive mixers in Flight Phases (with FadeIn / FadeOut)
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 23-02-2012 BSS
|
||||
PXX updates + optimizations pulled from er9x
|
||||
FrSky TELEMETRY menu is now moved to [DOWN long]
|
||||
Optimizations
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 22-02-2012 BSS
|
||||
Blades count may now be 4
|
||||
V4: New mixers/expos fields inflight modifiable through RE1
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 21-02-2012 BSS
|
||||
V4: Logs format ported from gruvin9x
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 20-02-2012 BSS
|
||||
Last GPS coords displayed even when streaming stops (model lost)
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 19-02-2012 BSS
|
||||
V4: Inflight fields modification through RE1 feature added
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 17-02-2012 BSS
|
||||
RSSI thresholds on a per model basis
|
||||
Flash Saving
|
||||
FrSky Hub variometer + cells voltage fix
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 16-02-2012 BSS
|
||||
Beeper mode splitted from Beeper length
|
||||
Haptic redesigned
|
||||
No FrSky alarms when Tx asked to be quiet
|
||||
Flash Saving
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 14-02-2012 BSS
|
||||
Blades count configuration for RPMs
|
||||
Instant trim bug fixed for stick modes != RETA
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 1O-02-2012 BSS
|
||||
Copyright updated
|
||||
GPS distance and speed bug fixes
|
||||
|
||||
******************************************
|
||||
|
||||
Version 232:
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 09-02-2012 BSS
|
||||
Multiplier added for telemetry A1/A2 => 204.0v!
|
||||
GPS distance added
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 08-02-2012 BSS
|
||||
Telemetry bars screen
|
||||
Add individual cell voltages from FrSky Hub 2.0
|
||||
New units for A1/A2
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 06-02-2012 BSS
|
||||
Flash saving
|
||||
Telemetry screens redesigned
|
||||
|
||||
******************************************
|
||||
|
||||
Version 213:
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 05-02-2012 BSS
|
||||
Add GPS speed display, with max speed
|
||||
GPS screen redesigned
|
||||
|
||||
******************************************
|
||||
|
||||
Version 205:
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 04-02-2012 BSS
|
||||
New way of configuring A1 and A2 using Range and Offset
|
||||
Named sounds in Func Switches
|
||||
Haptic only sounds skipped when HAPTIC option disable
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 03-02-2012 BSS
|
||||
Safety switches screen removed (moved to Func Switches)
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 02-02-2012 BSS
|
||||
French translations updated
|
||||
AUDIO optimizations
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 01-02-2012 BSS
|
||||
AUDIO and HAPTIC may be enabled separately
|
||||
AUDIO bug fixes
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 31-01-2012 BSS
|
||||
HAPTIC now working
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 29-01-2012 BSS
|
||||
Inactivity timer reset on Keys and Trims press
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 28-01-2012 BSS
|
||||
New splash
|
||||
|
||||
******************************************
|
||||
CHANGELOG: 27-01-2012 BSS
|
||||
NMEA and ARDUPILOT ported from er9x
|
||||
|
||||
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Author - Erez Raviv <erezraviv@gmail.com>
|
||||
*
|
||||
* Based on 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 eeprom_arm_h
|
||||
#define eeprom_arm_h
|
||||
|
||||
#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
|
||||
#define E32_ERASEWAITING 3
|
||||
#define E32_WRITESENDING 4
|
||||
#define E32_WRITEWAITING 5
|
||||
#define E32_READSENDING 6
|
||||
#define E32_READWAITING 7
|
||||
#define E32_BLANKCHECK 8
|
||||
#define E32_WRITESTART 9
|
||||
extern uint8_t Eeprom32_process_state ;
|
||||
|
||||
extern void eeprom_init( void ) ;
|
||||
extern void end_spi(); // TODO not public
|
||||
extern void ee32_process( void ) ;
|
||||
extern bool ee32LoadGeneral( void ) ;
|
||||
|
||||
extern void eeWaitFinished();
|
||||
|
||||
extern void eeDeleteModel( uint8_t id ) ;
|
||||
extern bool eeModelExists(uint8_t id) ;
|
||||
extern bool eeCopyModel(uint8_t dst, uint8_t src);
|
||||
extern void eeSwapModels(uint8_t id1, uint8_t id2);
|
||||
|
||||
|
||||
#define DISPLAY_PROGRESS_BAR(x)
|
||||
|
||||
struct t_file_entry
|
||||
{
|
||||
uint32_t block_no ;
|
||||
uint32_t sequence_no ;
|
||||
uint16_t size ;
|
||||
uint8_t flags ;
|
||||
} ;
|
||||
|
||||
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;
|
||||
|
||||
extern uint8_t Spi_tx_buf[] ;
|
||||
extern uint8_t Spi_rx_buf[] ;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
-134
@@ -1,134 +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_TELEMETRY_ALARM() audioDefevent(AU_WARNING1)
|
||||
|
||||
#define AUDIO_HEARTBEAT() audio.heartbeat()
|
||||
|
||||
#endif
|
||||
-1010
File diff suppressed because it is too large
Load Diff
@@ -1,145 +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_cmd17( uint32_t address, uint32_t *presult ) ;
|
||||
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
-575
@@ -1,575 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module include file R0.08a (C)ChaN, 2010
|
||||
/----------------------------------------------------------------------------/
|
||||
/ 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) 2010, 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 8255 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "inttypes.h"
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if _FATFS != _FFCONF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
|
||||
/* DBCS code ranges and SBCS extend char conversion table */
|
||||
|
||||
#if _CODE_PAGE == 932 /* Japanese Shift-JIS */
|
||||
#define _DF1S 0x81 /* DBC 1st byte range 1 start */
|
||||
#define _DF1E 0x9F /* DBC 1st byte range 1 end */
|
||||
#define _DF2S 0xE0 /* DBC 1st byte range 2 start */
|
||||
#define _DF2E 0xFC /* DBC 1st byte range 2 end */
|
||||
#define _DS1S 0x40 /* DBC 2nd byte range 1 start */
|
||||
#define _DS1E 0x7E /* DBC 2nd byte range 1 end */
|
||||
#define _DS2S 0x80 /* DBC 2nd byte range 2 start */
|
||||
#define _DS2E 0xFC /* DBC 2nd byte range 2 end */
|
||||
|
||||
#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x40
|
||||
#define _DS1E 0x7E
|
||||
#define _DS2S 0x80
|
||||
#define _DS2E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 949 /* Korean */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x41
|
||||
#define _DS1E 0x5A
|
||||
#define _DS2S 0x61
|
||||
#define _DS2E 0x7A
|
||||
#define _DS3S 0x81
|
||||
#define _DS3E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x40
|
||||
#define _DS1E 0x7E
|
||||
#define _DS2S 0xA1
|
||||
#define _DS2E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 437 /* U.S. (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 720 /* Arabic (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 737 /* Greek (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \
|
||||
0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 775 /* Baltic (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \
|
||||
0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \
|
||||
0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \
|
||||
0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 857 /* Turkish (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \
|
||||
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 862 /* Hebrew (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 866 /* Russian (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
|
||||
0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF}
|
||||
|
||||
#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \
|
||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
|
||||
|
||||
#elif _CODE_PAGE == 1253 /* Greek (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \
|
||||
0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1254 /* Turkish (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
|
||||
|
||||
#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1256 /* Arabic (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1257 /* Baltic (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \
|
||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F}
|
||||
|
||||
#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */
|
||||
#define _DF1S 0
|
||||
|
||||
#else
|
||||
#error Unknown code page
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive# */
|
||||
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition# */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive# */
|
||||
BYTE pt; /* Partition # (0-3) */
|
||||
} PARTITION;
|
||||
extern const PARTITION VolToPart[]; /* Volume - Physical location resolution table */
|
||||
|
||||
#else /* Single partition configuration */
|
||||
#define LD2PD(vol) (vol) /* Logical drive# is bound to the same physical drive# */
|
||||
#define LD2PT(vol) 0 /* Always mounts the 1st partition */
|
||||
|
||||
#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,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 org_clust; /* File start cluster (0 when fsize==0) */
|
||||
DWORD curr_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 on the physical drive
|
||||
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
|
||||
} 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*, BYTE*, 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 */
|
||||
|
||||
#if !_FS_READONLY
|
||||
FRESULT f_write (FIL*, const BYTE *, 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 */
|
||||
#endif
|
||||
|
||||
#if _USE_FORWARD
|
||||
FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */
|
||||
#endif
|
||||
|
||||
#if _USE_MKFS
|
||||
FRESULT f_mkfs (BYTE, BYTE, UINT); /* Create a file system on the drive */
|
||||
#endif
|
||||
|
||||
#if _FS_RPATH
|
||||
FRESULT f_chdrive (BYTE); /* Change current drive */
|
||||
FRESULT f_chdir (const TCHAR*); /* Change current directory */
|
||||
FRESULT f_getcwd (TCHAR*, UINT); /* Get current directory */
|
||||
#endif
|
||||
|
||||
#if _USE_STRFUNC
|
||||
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 */
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !_FS_READONLY
|
||||
extern uint32_t o9x_get_fattime (void); /* Returns 32-bit packed date and time */
|
||||
#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_del_syncobj (_SYNC_t); /* Delete a sync object */
|
||||
int ff_req_grant (_SYNC_t); /* Lock sync object */
|
||||
void ff_rel_grant (_SYNC_t); /* Unlock 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 function */
|
||||
#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,221 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module configuration file R0.08a (C)ChaN, 2010
|
||||
/----------------------------------------------------------------------------/
|
||||
/
|
||||
/ CAUTION! Do not forget to make clean the project after any changes to
|
||||
/ the configuration options.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
#ifndef _FFCONF
|
||||
#define _FFCONF 8255 /* Revision ID */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function and Buffer Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _FS_TINY 1 /* 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. */
|
||||
|
||||
|
||||
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */
|
||||
/* Setting _FS_READONLY to 1 defines read only configuration. This removes
|
||||
/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
|
||||
/ f_truncate and useless f_getfree. */
|
||||
|
||||
|
||||
#define _FS_MINIMIZE 0 /* 0 to 3 */
|
||||
/* The _FS_MINIMIZE option defines minimization level to remove some functions.
|
||||
/
|
||||
/ 0: Full function.
|
||||
/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename
|
||||
/ are removed.
|
||||
/ 2: f_opendir and f_readdir are removed in addition to 1.
|
||||
/ 3: f_lseek is removed in addition to 2. */
|
||||
|
||||
|
||||
#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 */
|
||||
/* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
|
||||
|
||||
|
||||
#define _USE_FORWARD 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
|
||||
|
||||
|
||||
#define _USE_FASTSEEK 0 /* 0:Disable or 1:Enable */
|
||||
/* To enable fast seek feature, set _USE_FASTSEEK to 1. */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _CODE_PAGE 932
|
||||
/* 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.
|
||||
/
|
||||
/ 932 - Japanese Shift-JIS (DBCS, OEM, Windows)
|
||||
/ 936 - Simplified Chinese GBK (DBCS, OEM, Windows)
|
||||
/ 949 - Korean (DBCS, OEM, Windows)
|
||||
/ 950 - Traditional Chinese Big5 (DBCS, OEM, Windows)
|
||||
/ 1250 - Central Europe (Windows)
|
||||
/ 1251 - Cyrillic (Windows)
|
||||
/ 1252 - Latin 1 (Windows)
|
||||
/ 1253 - Greek (Windows)
|
||||
/ 1254 - Turkish (Windows)
|
||||
/ 1255 - Hebrew (Windows)
|
||||
/ 1256 - Arabic (Windows)
|
||||
/ 1257 - Baltic (Windows)
|
||||
/ 1258 - Vietnam (OEM, Windows)
|
||||
/ 437 - U.S. (OEM)
|
||||
/ 720 - Arabic (OEM)
|
||||
/ 737 - Greek (OEM)
|
||||
/ 775 - Baltic (OEM)
|
||||
/ 850 - Multilingual Latin 1 (OEM)
|
||||
/ 858 - Multilingual Latin 1 + Euro (OEM)
|
||||
/ 852 - Latin 2 (OEM)
|
||||
/ 855 - Cyrillic (OEM)
|
||||
/ 866 - Russian (OEM)
|
||||
/ 857 - Turkish (OEM)
|
||||
/ 862 - Hebrew (OEM)
|
||||
/ 874 - Thai (OEM, Windows)
|
||||
/ 1 - ASCII only (Valid for non LFN cfg.)
|
||||
*/
|
||||
|
||||
|
||||
#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.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT reentrant.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. To enable LFN,
|
||||
/ Unicode handling functions ff_convert() and ff_wtoupper() must be added
|
||||
/ to the project. When enable to use heap, memory control functions
|
||||
/ ff_memalloc() and ff_memfree() must be added to the project. */
|
||||
|
||||
|
||||
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
|
||||
/* To switch the character code set on FatFs API to Unicode,
|
||||
/ enable LFN feature and set _LFN_UNICODE to 1. */
|
||||
|
||||
|
||||
#define _FS_RPATH 2 /* 0 to 2 */
|
||||
/* The _FS_RPATH option configures relative path feature.
|
||||
/
|
||||
/ 0: Disable relative path feature and remove related functions.
|
||||
/ 1: Enable relative path. f_chdrive() and f_chdir() are available.
|
||||
/ 2: f_getcwd() is available in addition to 1.
|
||||
/
|
||||
/ Note that output of the f_readdir fnction is affected by this option. */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Physical Drive Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _VOLUMES 1
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
#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. */
|
||||
|
||||
|
||||
#define _MULTI_PARTITION 0 /* 0:Single partition or 1: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. */
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _WORD_ACCESS 0 /* 0 or 1 */
|
||||
/* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS
|
||||
/ option defines which access method is used to the word data on the FAT volume.
|
||||
/
|
||||
/ 0: Byte-by-byte access.
|
||||
/ 1: Word access. Do not choose this unless following condition is met.
|
||||
/
|
||||
/ 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. */
|
||||
|
||||
|
||||
/* 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. */
|
||||
|
||||
#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.. */
|
||||
|
||||
/* The _FS_REENTRANT option switches the reentrancy 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. */
|
||||
|
||||
|
||||
#endif /* _FFCONFIG */
|
||||
@@ -1,495 +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 "gtime.h"
|
||||
|
||||
#define LEAP_SECONDS_POSSIBLE 0
|
||||
|
||||
/* Shift A right by B bits portably, by dividing A by 2**B and
|
||||
truncating towards minus infinity. A and B should be free of side
|
||||
effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
|
||||
INT_BITS is the number of useful bits in an int. GNU code can
|
||||
assume that INT_BITS is at least 32.
|
||||
|
||||
ISO C99 says that A >> B is implementation-defined if A < 0. Some
|
||||
implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
|
||||
right in the usual way when A < 0, so SHR falls back on division if
|
||||
ordinary A >> B doesn't seem to be the usual signed shift. */
|
||||
#define SHR(a, b) \
|
||||
(-1 >> 1 == -1 \
|
||||
? (a) >> (b) \
|
||||
: (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
|
||||
|
||||
/* The extra casts in the following macros work around compiler bugs,
|
||||
e.g., in Cray C 5.0.3.0. */
|
||||
|
||||
/* True if the arithmetic type T is an integer type. bool counts as
|
||||
an integer. */
|
||||
#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)
|
||||
|
||||
/* True if negative values of the signed integer type T use two's
|
||||
complement, ones' complement, or signed magnitude representation,
|
||||
respectively. Much GNU code assumes two's complement, but some
|
||||
people like to be portable to all possible C hosts. */
|
||||
#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1)
|
||||
#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0)
|
||||
#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1)
|
||||
|
||||
/* True if the arithmetic type T is signed. */
|
||||
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
|
||||
|
||||
/* The maximum and minimum values for the integer type T. These
|
||||
macros have undefined behavior if T is signed and has padding bits.
|
||||
If this is a problem for you, please let us know how to fix it for
|
||||
your host. */
|
||||
#define TYPE_MINIMUM(t) \
|
||||
((t) (! TYPE_SIGNED (t) \
|
||||
? (t) 0 \
|
||||
: TYPE_SIGNED_MAGNITUDE (t) \
|
||||
? ~ (t) 0 \
|
||||
: ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))
|
||||
#define TYPE_MAXIMUM(t) \
|
||||
((t) (! TYPE_SIGNED (t) \
|
||||
? (t) -1 \
|
||||
: ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))))
|
||||
|
||||
#ifndef TIME_T_MIN
|
||||
# define TIME_T_MIN TYPE_MINIMUM (gtime_t)
|
||||
#endif
|
||||
#ifndef TIME_T_MAX
|
||||
# define TIME_T_MAX TYPE_MAXIMUM (gtime_t)
|
||||
#endif
|
||||
#define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1)
|
||||
|
||||
/* Verify a requirement at compile-time (unlike assert, which is runtime). */
|
||||
#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
|
||||
|
||||
verify (gtime_t_is_integer, TYPE_IS_INTEGER (gtime_t));
|
||||
verify (twos_complement_arithmetic, TYPE_TWOS_COMPLEMENT (int));
|
||||
/* The code also assumes that signed integer overflow silently wraps
|
||||
around, but this assumption can't be stated without causing a
|
||||
diagnostic on some hosts. */
|
||||
|
||||
#define EPOCH_YEAR 1970
|
||||
#define TM_YEAR_BASE 1900
|
||||
verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0);
|
||||
|
||||
#define SECS_PER_HOUR 3600ul
|
||||
#define SECS_PER_DAY 86400ul
|
||||
|
||||
/* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */
|
||||
static inline int
|
||||
leapyear (long int year)
|
||||
{
|
||||
/* Don't add YEAR to TM_YEAR_BASE, as that might overflow.
|
||||
Also, work even if YEAR is negative. */
|
||||
return
|
||||
((year & 3) == 0
|
||||
&& (year % 100 != 0
|
||||
|| ((year / 100) & 3) == (- (TM_YEAR_BASE / 100) & 3)));
|
||||
}
|
||||
|
||||
const unsigned short int __mon_yday[2][13] =
|
||||
{
|
||||
/* Normal years. */
|
||||
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
|
||||
/* Leap years. */
|
||||
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
|
||||
};
|
||||
|
||||
/* Compute the `struct tm' representation of *T,
|
||||
offset OFFSET seconds east of UTC,
|
||||
and store year, yday, mon, mday, wday, hour, min, sec into *TP.
|
||||
Return nonzero if successful. */
|
||||
int
|
||||
__offtime (
|
||||
gtime_t *t,
|
||||
long int offset,
|
||||
struct gtm *tp)
|
||||
{
|
||||
long int days, rem, y;
|
||||
const unsigned short int *ip;
|
||||
|
||||
days = *t / SECS_PER_DAY;
|
||||
rem = *t % SECS_PER_DAY;
|
||||
rem += offset;
|
||||
while (rem < 0)
|
||||
{
|
||||
rem += SECS_PER_DAY;
|
||||
--days;
|
||||
}
|
||||
while (rem >= (long int)SECS_PER_DAY)
|
||||
{
|
||||
rem -= SECS_PER_DAY;
|
||||
++days;
|
||||
}
|
||||
tp->tm_hour = rem / SECS_PER_HOUR;
|
||||
rem %= SECS_PER_HOUR;
|
||||
tp->tm_min = rem / 60;
|
||||
tp->tm_sec = rem % 60;
|
||||
/* January 1, 1970 was a Thursday. */
|
||||
tp->tm_wday = (4 + days) % 7;
|
||||
if (tp->tm_wday < 0)
|
||||
tp->tm_wday += 7;
|
||||
y = 1970;
|
||||
|
||||
#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
|
||||
#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
|
||||
|
||||
while (days < 0 || days >= (leapyear (y) ? 366 : 365))
|
||||
{
|
||||
/* Guess a corrected year, assuming 365 days per year. */
|
||||
long int yg = y + days / 365 - (days % 365 < 0);
|
||||
|
||||
/* Adjust DAYS and Y to match the guessed year. */
|
||||
days -= ((yg - y) * 365
|
||||
+ LEAPS_THRU_END_OF (yg - 1)
|
||||
- LEAPS_THRU_END_OF (y - 1));
|
||||
y = yg;
|
||||
}
|
||||
tp->tm_year = y - 1900;
|
||||
if (tp->tm_year != y - 1900)
|
||||
{
|
||||
/* The year cannot be represented due to overflow. */
|
||||
// __set_errno (EOVERFLOW);
|
||||
return 0;
|
||||
}
|
||||
tp->tm_yday = days;
|
||||
ip = __mon_yday[leapyear(y)];
|
||||
for (y = 11; days < (long int) ip[y]; --y)
|
||||
continue;
|
||||
days -= ip[y];
|
||||
tp->tm_mon = y;
|
||||
tp->tm_mday = days + 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* time_r function implementations */
|
||||
// G: No time zones in our implementation so just do the converion from gtime_t to struct tm
|
||||
struct gtm *
|
||||
__localtime_r (gtime_t * t, struct gtm * tp)
|
||||
{
|
||||
__offtime(t, 0, tp);
|
||||
return tp;
|
||||
}
|
||||
|
||||
|
||||
/* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) -
|
||||
(YEAR0-YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks
|
||||
were not adjusted between the time stamps.
|
||||
|
||||
The YEAR values uses the same numbering as TP->tm_year. Values
|
||||
need not be in the usual range. However, YEAR1 must not be less
|
||||
than 2 * INT_MIN or greater than 2 * INT_MAX.
|
||||
|
||||
The result may overflow. It is the caller's responsibility to
|
||||
detect overflow. */
|
||||
|
||||
static inline gtime_t
|
||||
ydhms_diff (long int year1, long int yday1, int hour1, int min1, int sec1,
|
||||
int year0, int yday0, int hour0, int min0, int sec0)
|
||||
{
|
||||
verify (C99_integer_division, -1 / 2 == 0);
|
||||
verify (long_int_year_and_yday_are_wide_enough,
|
||||
INT_MAX <= LONG_MAX / 2 || TIME_T_MAX <= UINT_MAX);
|
||||
|
||||
/* Compute intervening leap days correctly even if year is negative.
|
||||
Take care to avoid integer overflow here. */
|
||||
int a4 = SHR (year1, 2) + SHR (TM_YEAR_BASE, 2) - ! (year1 & 3);
|
||||
int b4 = SHR (year0, 2) + SHR (TM_YEAR_BASE, 2) - ! (year0 & 3);
|
||||
int a100 = a4 / 25 - (a4 % 25 < 0);
|
||||
int b100 = b4 / 25 - (b4 % 25 < 0);
|
||||
int a400 = SHR (a100, 2);
|
||||
int b400 = SHR (b100, 2);
|
||||
int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
|
||||
|
||||
/* Compute the desired time in gtime_t precision. Overflow might
|
||||
occur here. */
|
||||
gtime_t tyear1 = year1;
|
||||
gtime_t years = tyear1 - year0;
|
||||
gtime_t days = 365 * years + yday1 - yday0 + intervening_leap_days;
|
||||
gtime_t hours = 24 * days + hour1 - hour0;
|
||||
gtime_t minutes = 60 * hours + min1 - min0;
|
||||
gtime_t seconds = 60 * minutes + sec1 - sec0;
|
||||
return seconds;
|
||||
}
|
||||
|
||||
/* Return a gtime_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC),
|
||||
assuming that *T corresponds to *TP and that no clock adjustments
|
||||
occurred between *TP and the desired time.
|
||||
If TP is null, return a value not equal to *T; this avoids false matches.
|
||||
If overflow occurs, yield the minimal or maximal value, except do not
|
||||
yield a value equal to *T. */
|
||||
static gtime_t
|
||||
guess_time_tm (long int year, long int yday, int hour, int min, int sec,
|
||||
gtime_t *t, struct gtm *tp)
|
||||
{
|
||||
if (tp)
|
||||
{
|
||||
gtime_t d = ydhms_diff (year, yday, hour, min, sec,
|
||||
tp->tm_year, tp->tm_yday,
|
||||
tp->tm_hour, tp->tm_min, tp->tm_sec);
|
||||
gtime_t t1 = *t + d;
|
||||
if ((t1 < *t) == (TYPE_SIGNED (gtime_t) ? d < 0 : TIME_T_MAX / 2 < d))
|
||||
return t1;
|
||||
}
|
||||
|
||||
/* Overflow occurred one way or another. Return the nearest result
|
||||
that is actually in range, except don't report a zero difference
|
||||
if the actual difference is nonzero, as that would cause a false
|
||||
match; and don't oscillate between two values, as that would
|
||||
confuse the spring-forward gap detector. */
|
||||
return (*t < TIME_T_MIDPOINT
|
||||
? (*t <= TIME_T_MIN + 1 ? *t + 1 : TIME_T_MIN)
|
||||
: (TIME_T_MAX - 1 <= *t ? *t - 1 : TIME_T_MAX));
|
||||
}
|
||||
|
||||
/* Use CONVERT to convert *T to a broken down time in *TP.
|
||||
If *T is out of range for conversion, adjust it so that
|
||||
it is the nearest in-range value and then convert that. */
|
||||
static struct gtm *
|
||||
ranged_convert (struct gtm *(*convert) (gtime_t *, struct gtm *),
|
||||
gtime_t *t, struct gtm *tp)
|
||||
{
|
||||
struct gtm *r = convert (t, tp);
|
||||
|
||||
if (!r && *t)
|
||||
{
|
||||
gtime_t bad = *t;
|
||||
gtime_t ok = 0;
|
||||
|
||||
/* BAD is a known unconvertible gtime_t, and OK is a known good one.
|
||||
Use binary search to narrow the range between BAD and OK until
|
||||
they differ by 1. */
|
||||
while (bad != ok + (bad < 0 ? -1 : 1))
|
||||
{
|
||||
gtime_t mid = *t = (bad < 0
|
||||
? bad + ((ok - bad) >> 1)
|
||||
: ok + ((bad - ok) >> 1));
|
||||
r = convert (t, tp);
|
||||
if (r)
|
||||
ok = mid;
|
||||
else
|
||||
bad = mid;
|
||||
}
|
||||
|
||||
if (!r && ok)
|
||||
{
|
||||
/* The last conversion attempt failed;
|
||||
revert to the most recent successful attempt. */
|
||||
*t = ok;
|
||||
r = convert (t, tp);
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Convert *TP to a gtime_t value, inverting
|
||||
the monotonic and mostly-unit-linear conversion function CONVERT.
|
||||
Use *OFFSET to keep track of a guess at the offset of the result,
|
||||
compared to what the result would be for UTC without leap seconds.
|
||||
If *OFFSET's guess is correct, only one CONVERT call is needed.
|
||||
This function is external because it is used also by timegm.c. */
|
||||
gtime_t
|
||||
__mktime_internal (struct gtm *tp,
|
||||
struct gtm *(*convert) (gtime_t *, struct gtm *),
|
||||
gtime_t *offset)
|
||||
{
|
||||
gtime_t t, gt, t0, t1, t2;
|
||||
struct gtm tm;
|
||||
|
||||
/* The maximum number of probes (calls to CONVERT) should be enough
|
||||
to handle any combinations of time zone rule changes, solar time,
|
||||
leap seconds, and oscillations around a spring-forward gap.
|
||||
POSIX.1 prohibits leap seconds, but some hosts have them anyway. */
|
||||
int remaining_probes = 6;
|
||||
|
||||
/* Time requested. Copy it in case CONVERT modifies *TP; this can
|
||||
occur if TP is localtime's returned value and CONVERT is localtime. */
|
||||
int sec = tp->tm_sec;
|
||||
int min = tp->tm_min;
|
||||
int hour = tp->tm_hour;
|
||||
int mday = tp->tm_mday;
|
||||
int mon = tp->tm_mon;
|
||||
int year_requested = tp->tm_year;
|
||||
|
||||
/* Ensure that mon is in range, and set year accordingly. */
|
||||
int mon_remainder = mon % 12;
|
||||
int negative_mon_remainder = mon_remainder < 0;
|
||||
int mon_years = mon / 12 - negative_mon_remainder;
|
||||
long int lyear_requested = year_requested;
|
||||
long int year = lyear_requested + mon_years;
|
||||
|
||||
/* The other values need not be in range:
|
||||
the remaining code handles minor overflows correctly,
|
||||
assuming int and gtime_t arithmetic wraps around.
|
||||
Major overflows are caught at the end. */
|
||||
|
||||
/* Calculate day of year from year, month, and day of month.
|
||||
The result need not be in range. */
|
||||
int mon_yday = ((__mon_yday[leapyear (year)]
|
||||
[mon_remainder + 12 * negative_mon_remainder])
|
||||
- 1);
|
||||
long int lmday = mday;
|
||||
long int yday = mon_yday + lmday;
|
||||
|
||||
gtime_t guessed_offset = *offset;
|
||||
|
||||
int sec_requested = sec;
|
||||
|
||||
/*
|
||||
if (LEAP_SECONDS_POSSIBLE)
|
||||
{
|
||||
// Handle out-of-range seconds specially,
|
||||
// since ydhms_tm_diff assumes every minute has 60 seconds.
|
||||
if (sec < 0)
|
||||
sec = 0;
|
||||
if (59 < sec)
|
||||
sec = 59;
|
||||
}
|
||||
*/
|
||||
|
||||
/* Invert CONVERT by probing. First assume the same offset as last
|
||||
time. */
|
||||
|
||||
t0 = ydhms_diff (year, yday, hour, min, sec,
|
||||
EPOCH_YEAR - TM_YEAR_BASE, 0, 0, 0, - guessed_offset);
|
||||
|
||||
if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
|
||||
{
|
||||
/* gtime_t isn't large enough to rule out overflows, so check
|
||||
for major overflows. A gross check suffices, since if t0
|
||||
has overflowed, it is off by a multiple of TIME_T_MAX -
|
||||
TIME_T_MIN + 1. So ignore any component of the difference
|
||||
that is bounded by a small value. */
|
||||
|
||||
/* Approximate log base 2 of the number of time units per
|
||||
biennium. A biennium is 2 years; use this unit instead of
|
||||
years to avoid integer overflow. For example, 2 average
|
||||
Gregorian years are 2 * 365.2425 * 24 * 60 * 60 seconds,
|
||||
which is 63113904 seconds, and rint (log2 (63113904)) is
|
||||
26. */
|
||||
int ALOG2_SECONDS_PER_BIENNIUM = 26;
|
||||
int ALOG2_MINUTES_PER_BIENNIUM = 20;
|
||||
int ALOG2_HOURS_PER_BIENNIUM = 14;
|
||||
int ALOG2_DAYS_PER_BIENNIUM = 10;
|
||||
int LOG2_YEARS_PER_BIENNIUM = 1;
|
||||
|
||||
int approx_requested_biennia =
|
||||
(SHR (year_requested, LOG2_YEARS_PER_BIENNIUM)
|
||||
- SHR (EPOCH_YEAR - TM_YEAR_BASE, LOG2_YEARS_PER_BIENNIUM)
|
||||
+ SHR (mday, ALOG2_DAYS_PER_BIENNIUM)
|
||||
+ SHR (hour, ALOG2_HOURS_PER_BIENNIUM)
|
||||
+ SHR (min, ALOG2_MINUTES_PER_BIENNIUM)
|
||||
+ (LEAP_SECONDS_POSSIBLE
|
||||
? 0
|
||||
: SHR (sec, ALOG2_SECONDS_PER_BIENNIUM)));
|
||||
|
||||
int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM);
|
||||
int diff = approx_biennia - approx_requested_biennia;
|
||||
int abs_diff = diff < 0 ? - diff : diff;
|
||||
|
||||
/* IRIX 4.0.5 cc miscalculates TIME_T_MIN / 3: it erroneously
|
||||
gives a positive value of 715827882. Setting a variable
|
||||
first then doing math on it seems to work.
|
||||
(ghazi@caip.rutgers.edu) */
|
||||
gtime_t time_t_max = TIME_T_MAX;
|
||||
gtime_t time_t_min = TIME_T_MIN;
|
||||
gtime_t overflow_threshold =
|
||||
(time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM;
|
||||
|
||||
if (overflow_threshold < abs_diff)
|
||||
{
|
||||
/* Overflow occurred. Try repairing it; this might work if
|
||||
the time zone offset is enough to undo the overflow. */
|
||||
gtime_t repaired_t0 = -1 - t0;
|
||||
approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM);
|
||||
diff = approx_biennia - approx_requested_biennia;
|
||||
abs_diff = diff < 0 ? - diff : diff;
|
||||
if (overflow_threshold < abs_diff)
|
||||
return -1;
|
||||
guessed_offset += repaired_t0 - t0;
|
||||
t0 = repaired_t0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Repeatedly use the error to improve the guess. */
|
||||
|
||||
for (t = t1 = t2 = t0;
|
||||
(gt = guess_time_tm (year, yday, hour, min, sec, &t,
|
||||
ranged_convert (convert, &t, &tm)),
|
||||
t != gt);
|
||||
t1 = t2, t2 = t, t = gt)
|
||||
if (t == t1 && t != t2)
|
||||
goto offset_found;
|
||||
else if (--remaining_probes == 0)
|
||||
return -1;
|
||||
|
||||
offset_found:
|
||||
*offset = guessed_offset + t - t0;
|
||||
|
||||
if (LEAP_SECONDS_POSSIBLE && sec_requested != tm.tm_sec)
|
||||
{
|
||||
/* Adjust time to reflect the tm_sec requested, not the normalized value.
|
||||
Also, repair any damage from a false match due to a leap second. */
|
||||
int sec_adjustment = (sec == 0 && tm.tm_sec == 60) - sec;
|
||||
t1 = t + sec_requested;
|
||||
t2 = t1 + sec_adjustment;
|
||||
if (((t1 < t) != (sec_requested < 0))
|
||||
| ((t2 < t1) != (sec_adjustment < 0))
|
||||
| ! convert (&t2, &tm))
|
||||
return -1;
|
||||
t = t2;
|
||||
}
|
||||
|
||||
*tp = tm;
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Convert *TP to a gtime_t value. */
|
||||
gtime_t
|
||||
mktime (struct gtm *tp)
|
||||
{
|
||||
// no time zone stuff. Just do the math ;)
|
||||
static gtime_t localtime_offset;
|
||||
return __mktime_internal (tp, __localtime_r, &localtime_offset);
|
||||
}
|
||||
|
||||
/* Fill a (struct tm) TP* from a given gtime_t time stamp */
|
||||
gtime_t
|
||||
filltm(gtime_t *t, struct gtm *tp)
|
||||
{
|
||||
return __offtime(t, 0, tp);
|
||||
}
|
||||
|
||||
@@ -1,35 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
extern void hapticOff(void) ;
|
||||
extern void hapticOn( uint32_t pwmPercent ) ;
|
||||
@@ -1,70 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*-------------------------------------------*/
|
||||
/* 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
|
||||
@@ -1,286 +0,0 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2011 by Michael Blandford. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************
|
||||
* History:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "../open9x.h"
|
||||
|
||||
volatile uint8_t Buzzer_count ;
|
||||
|
||||
// Must NOT be in flash, PDC needs a RAM source.
|
||||
uint16_t Sine_values[] =
|
||||
{
|
||||
2048,2173,2298,2422,2545,2666,2784,2899,3011,3119,
|
||||
3223,3322,3417,3505,3589,3666,3736,3800,3857,3907,
|
||||
3950,3985,4012,4032,4044,4048,4044,4032,4012,3985,
|
||||
3950,3907,3857,3800,3736,3666,3589,3505,3417,3322,
|
||||
3223,3119,3011,2899,2784,2666,2545,2422,2298,2173,
|
||||
2048,1922,1797,1673,1550,1429,1311,1196,1084, 976,
|
||||
872, 773, 678, 590, 506, 429, 359, 295, 238, 188,
|
||||
145, 110, 83, 63, 51, 48, 51, 63, 83, 110,
|
||||
145, 188, 238, 295, 359, 429, 506, 590, 678, 773,
|
||||
872, 976,1084,1196,1311,1429,1550,1673,1797,1922
|
||||
} ;
|
||||
|
||||
const uint16_t PianoTones[] =
|
||||
{
|
||||
28, 29, 31, 33, 35, 37, 39, 41, 44, 46,
|
||||
49, 52, 55, 58, 62, 65, 69, 73, 78, 82,
|
||||
87, 92, 98, 104, 110, 117, 123, 131, 139, 147,
|
||||
156, 165, 175, 185, 196, 208, 220, 233, 247, 262, // d#, E, F, f#, G, g#, A, a#, B, C(middle)
|
||||
277, 294, 311, 330, 349, 370, 392, 415, 440, 466, // c#, D, d#, E, F, f#, G, g#, A, a#
|
||||
494, 523, 554, 587, 622, 659, 698, 740, 784, 831, // B, C, c#, D, d#, E, F, f#, G, g#
|
||||
880, 932, 988, 1047, 1109, 1175, 1245, 1319, 1397, 1480,
|
||||
1568, 1661, 1760, 1865, 1976, 2093, 2217, 2349, 2489, 2637,
|
||||
2794, 2960, 3136, 3322, 3520 ,3729, 3951, 4186
|
||||
} ;
|
||||
|
||||
|
||||
// Sound routines
|
||||
|
||||
void start_sound()
|
||||
{
|
||||
register Pio *pioptr ;
|
||||
|
||||
start_timer1() ;
|
||||
init_dac() ;
|
||||
init_twi() ;
|
||||
|
||||
pioptr = PIOA ;
|
||||
#ifdef REVB
|
||||
pioptr->PIO_CODR = 0x02000000L ; // Set bit A25 OFF
|
||||
pioptr->PIO_PER = 0x02000000L ; // Enable bit A25 (Stock buzzer)
|
||||
pioptr->PIO_OER = 0x02000000L ; // Set bit A25 as output
|
||||
#else
|
||||
pioptr->PIO_CODR = 0x00010000L ; // Set bit A16 OFF
|
||||
pioptr->PIO_PER = 0x00010000L ; // Enable bit A16 (Stock buzzer)
|
||||
pioptr->PIO_OER = 0x00010000L ; // Set bit A16 as output
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef REVB
|
||||
void buzzer_on()
|
||||
{
|
||||
PIOA->PIO_SODR = 0x02000000L ; // Set bit A25 ON
|
||||
}
|
||||
|
||||
void buzzer_off()
|
||||
{
|
||||
PIOA->PIO_CODR = 0x02000000L ; // Set bit A25 ON
|
||||
}
|
||||
#else
|
||||
void buzzer_on()
|
||||
{
|
||||
PIOA->PIO_SODR = 0x00010000L ; // Set bit A16 ON
|
||||
}
|
||||
|
||||
void buzzer_off()
|
||||
{
|
||||
PIOA->PIO_CODR = 0x00010000L ; // Set bit A16 ON
|
||||
}
|
||||
#endif
|
||||
|
||||
void buzzer_sound( uint8_t time )
|
||||
{
|
||||
buzzer_on() ;
|
||||
Buzzer_count = time ;
|
||||
}
|
||||
|
||||
void set_frequency( uint32_t frequency )
|
||||
{
|
||||
register Tc *ptc ;
|
||||
register uint32_t timer ;
|
||||
|
||||
timer = Master_frequency / (800 * frequency) ; // MCK/8 and 100 000 Hz
|
||||
if ( timer > 65535 )
|
||||
{
|
||||
timer = 65535 ;
|
||||
}
|
||||
if ( timer < 2 )
|
||||
{
|
||||
timer = 2 ;
|
||||
}
|
||||
ptc = TC0 ; // Tc block 0 (TC0-2)
|
||||
ptc->TC_CHANNEL[1].TC_CCR = TC_CCR0_CLKDIS ; // Stop clock
|
||||
ptc->TC_CHANNEL[1].TC_RC = timer ; // 100 000 Hz
|
||||
ptc->TC_CHANNEL[1].TC_RA = timer >> 1 ;
|
||||
ptc->TC_CHANNEL[1].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger)
|
||||
}
|
||||
|
||||
|
||||
// Start TIMER1 at 100000Hz, used for DACC trigger
|
||||
void start_timer1()
|
||||
{
|
||||
register Tc *ptc ;
|
||||
register uint32_t timer ;
|
||||
|
||||
// Enable peripheral clock TC0 = bit 23 thru TC5 = bit 28
|
||||
PMC->PMC_PCER0 |= 0x01000000L ; // Enable peripheral clock to TC1
|
||||
|
||||
timer = Master_frequency / 800000 ; // MCK/8 and 100 000 Hz
|
||||
ptc = TC0 ; // Tc block 0 (TC0-2)
|
||||
ptc->TC_BCR = 0 ; // No sync
|
||||
ptc->TC_BMR = 0 ;
|
||||
ptc->TC_CHANNEL[1].TC_CMR = 0x00008000 ; // Waveform mode
|
||||
ptc->TC_CHANNEL[1].TC_RC = timer ; // 100 000 Hz
|
||||
ptc->TC_CHANNEL[1].TC_RA = timer >> 1 ;
|
||||
ptc->TC_CHANNEL[1].TC_CMR = 0x0009C001 ; // 0000 0000 0000 1001 1100 0000 0000 0001
|
||||
// MCK/8, set @ RA, Clear @ RC waveform
|
||||
ptc->TC_CHANNEL[1].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger)
|
||||
// Sound_g.Frequency = 1000 ;
|
||||
}
|
||||
|
||||
|
||||
// Configure DAC1 (or DAC0 for REVB)
|
||||
// Not sure why PB14 has not be allocated to the DAC, although it is an EXTRA function
|
||||
// So maybe it is automatically done
|
||||
void init_dac()
|
||||
{
|
||||
register Dacc *dacptr ;
|
||||
|
||||
PMC->PMC_PCER0 |= 0x40000000L ; // Enable peripheral clock to DAC
|
||||
dacptr = DACC ;
|
||||
#ifdef REVB
|
||||
dacptr->DACC_MR = 0x0B000215L ; // 0000 1011 0000 0001 0000 0010 0001 0101
|
||||
#else
|
||||
dacptr->DACC_MR = 0x0B010215L ; // 0000 1011 0000 0001 0000 0010 0001 0101
|
||||
#endif
|
||||
#ifdef REVB
|
||||
dacptr->DACC_CHER = 1 ; // Enable channel 0
|
||||
#else
|
||||
dacptr->DACC_CHER = 2 ; // Enable channel 1
|
||||
#endif
|
||||
dacptr->DACC_CDR = 2048 ; // Half amplitude
|
||||
// Data for PDC must NOT be in flash, PDC needs a RAM source.
|
||||
#ifndef SIMU
|
||||
dacptr->DACC_TPR = (uint32_t) Sine_values ;
|
||||
dacptr->DACC_TNPR = (uint32_t) Sine_values ;
|
||||
#endif
|
||||
dacptr->DACC_TCR = 50 ; // words, 100 16 bit values
|
||||
dacptr->DACC_TNCR = 50 ; // words, 100 16 bit values
|
||||
dacptr->DACC_PTCR = DACC_PTCR_TXTEN ;
|
||||
NVIC_EnableIRQ(DACC_IRQn) ;
|
||||
}
|
||||
|
||||
extern "C" void DAC_IRQHandler()
|
||||
{
|
||||
// Data for PDC must NOT be in flash, PDC needs a RAM source.
|
||||
#ifndef SIMU
|
||||
DACC->DACC_TNPR = (uint32_t) Sine_values ;
|
||||
#endif
|
||||
DACC->DACC_TNCR = 50 ; // words, 100 16 bit values
|
||||
}
|
||||
|
||||
void end_sound()
|
||||
{
|
||||
DACC->DACC_IDR = DACC_IDR_ENDTX ;
|
||||
NVIC_DisableIRQ(DACC_IRQn) ;
|
||||
TWI0->TWI_IDR = TWI_IDR_TXCOMP ;
|
||||
NVIC_DisableIRQ(TWI0_IRQn) ;
|
||||
PMC->PMC_PCER0 &= ~0x00080000L ; // Disable peripheral clock to TWI0
|
||||
PMC->PMC_PCER0 &= ~0x40000000L ; // Disable peripheral clock to DAC
|
||||
}
|
||||
|
||||
// Set up for volume control (TWI0)
|
||||
// Need PA3 and PA4 set to peripheral A
|
||||
void init_twi()
|
||||
{
|
||||
register Pio *pioptr ;
|
||||
register uint32_t timing ;
|
||||
|
||||
PMC->PMC_PCER0 |= 0x00080000L ; // Enable peripheral clock to TWI0
|
||||
|
||||
/* Configure PIO */
|
||||
pioptr = PIOA ;
|
||||
pioptr->PIO_ABCDSR[0] &= ~0x00000018 ; // Peripheral A
|
||||
pioptr->PIO_ABCDSR[1] &= ~0x00000018 ; // Peripheral A
|
||||
pioptr->PIO_PDR = 0x00000018 ; // Assign to peripheral
|
||||
|
||||
timing = Master_frequency * 5 / 1000000 ; // 5uS high and low
|
||||
timing += 15 - 4 ;
|
||||
timing /= 16 ;
|
||||
timing |= timing << 8 ;
|
||||
|
||||
TWI0->TWI_CWGR = 0x00040000 | timing ; // TWI clock set
|
||||
TWI0->TWI_CR = TWI_CR_MSEN | TWI_CR_SVDIS ; // Master mode enable
|
||||
TWI0->TWI_MMR = 0x002F0000 ; // Device 5E (>>1) and master is writing
|
||||
NVIC_EnableIRQ(TWI0_IRQn) ;
|
||||
set_volume( 2 ) ;
|
||||
}
|
||||
|
||||
static int16_t Volume_required ;
|
||||
static const uint8_t Volume_scale[NUM_VOL_LEVELS] =
|
||||
{
|
||||
0, 2, 4, 6, 8, 10, 13, 17, 22, 27, 33, 40,
|
||||
64, 82, 96, 105, 112, 117, 120, 122, 124, 125, 126, 127
|
||||
} ;
|
||||
|
||||
void set_volume( register uint8_t volume )
|
||||
{
|
||||
// PMC->PMC_PCER0 |= 0x00080000L ; // Enable peripheral clock to TWI0
|
||||
|
||||
if ( volume >= NUM_VOL_LEVELS )
|
||||
{
|
||||
volume = NUM_VOL_LEVELS - 1 ;
|
||||
}
|
||||
volume = Volume_scale[volume] ;
|
||||
|
||||
__disable_irq() ;
|
||||
if ( TWI0->TWI_IMR & TWI_IMR_TXCOMP )
|
||||
{
|
||||
Volume_required = volume ;
|
||||
}
|
||||
else
|
||||
{
|
||||
TWI0->TWI_THR = volume ; // Send data
|
||||
TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx
|
||||
TWI0->TWI_IER = TWI_IER_TXCOMP ;
|
||||
|
||||
}
|
||||
__enable_irq() ;
|
||||
}
|
||||
|
||||
extern "C" void TWI0_IRQHandler()
|
||||
{
|
||||
if ( Volume_required >= 0 )
|
||||
{
|
||||
TWI0->TWI_THR = Volume_required ; // Send data
|
||||
Volume_required = -1 ;
|
||||
TWI0->TWI_CR = TWI_CR_STOP ; // Stop Tx
|
||||
}
|
||||
else
|
||||
{
|
||||
TWI0->TWI_IDR = TWI_IDR_TXCOMP ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
/****************************************************************************
|
||||
* Copyright (c) 2011 by Michael Blandford. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the author nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************
|
||||
* History:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef sound_driver_h
|
||||
#define sound_driver_h
|
||||
|
||||
#define NUM_VOL_LEVELS 24
|
||||
|
||||
extern void start_sound( void ) ;
|
||||
extern void buzzer_on( void ) ;
|
||||
extern void buzzer_off( void ) ;
|
||||
extern void buzzer_sound( uint8_t time ) ;
|
||||
extern void set_frequency( uint32_t frequency ) ;
|
||||
extern void start_timer1( void ) ;
|
||||
extern void init_dac( void ) ;
|
||||
extern "C" void DAC_IRQHandler( void ) ;
|
||||
extern void end_sound( void ) ;
|
||||
|
||||
inline void tone_start( register uint32_t time )
|
||||
{
|
||||
PMC->PMC_PCER0 |= 0x40000000L ; // Enable peripheral clock to DAC
|
||||
DACC->DACC_IER = DACC_IER_ENDTX ;
|
||||
}
|
||||
|
||||
inline void tone_stop( void )
|
||||
{
|
||||
DACC->DACC_IDR = DACC_IDR_ENDTX ; // Disable interrupt
|
||||
}
|
||||
|
||||
extern volatile uint8_t Buzzer_count ;
|
||||
|
||||
extern void init_twi( void ) ;
|
||||
extern void set_volume( register uint8_t volume ) ;
|
||||
extern "C" void TWI0_IRQHandler (void) ;
|
||||
|
||||
#endif
|
||||
@@ -1,737 +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"
|
||||
|
||||
const pm_uchar sticks[] PROGMEM = {
|
||||
#include "sticks.lbm"
|
||||
};
|
||||
|
||||
enum EnumTabDiag {
|
||||
e_Setup,
|
||||
#if defined(PCBV4) && defined(SDCARD)
|
||||
e_FrskyTime,
|
||||
#endif
|
||||
e_Trainer,
|
||||
e_Vers,
|
||||
e_Keys,
|
||||
e_Ana,
|
||||
e_Calib
|
||||
};
|
||||
|
||||
void menuProcSetup(uint8_t event);
|
||||
#if defined(PCBV4) && defined(SDCARD)
|
||||
void menuProcTime(uint8_t event);
|
||||
#endif
|
||||
void menuProcTrainer(uint8_t event);
|
||||
void menuProcDiagVers(uint8_t event);
|
||||
void menuProcDiagKeys(uint8_t event);
|
||||
void menuProcDiagAna(uint8_t event);
|
||||
void menuProcDiagCalib(uint8_t event);
|
||||
|
||||
const MenuFuncP_PROGMEM menuTabDiag[] PROGMEM = {
|
||||
menuProcSetup,
|
||||
#if defined(PCBV4) && defined(SDCARD)
|
||||
menuProcTime,
|
||||
#endif
|
||||
menuProcTrainer,
|
||||
menuProcDiagVers,
|
||||
menuProcDiagKeys,
|
||||
menuProcDiagAna,
|
||||
menuProcDiagCalib
|
||||
};
|
||||
|
||||
#define GENERAL_PARAM_OFS (2+16*FW)
|
||||
NOINLINE int8_t selectMenuItem(uint8_t y, const pm_char *label, const pm_char *values, int8_t value, int8_t min, int8_t max, uint8_t attr, uint8_t event)
|
||||
{
|
||||
lcd_putsLeft(y, label);
|
||||
if (values) lcd_putsiAtt(GENERAL_PARAM_OFS, y, values, value-min, attr) ;
|
||||
if (attr) CHECK_INCDEC_GENVAR(event, value, min, max);
|
||||
return value;
|
||||
}
|
||||
|
||||
NOINLINE uint8_t onoffMenuItem(uint8_t value, uint8_t y, const pm_char *label, uint8_t attr, uint8_t event )
|
||||
{
|
||||
return selectMenuItem(y, label, STR_OFFON, value, 0, 1, attr, event);
|
||||
}
|
||||
|
||||
void displaySlider(uint8_t x, uint8_t y, uint8_t value, uint8_t attr)
|
||||
{
|
||||
lcd_putc(GENERAL_PARAM_OFS+2*FW+(value*FW), y, '$');
|
||||
lcd_hline(GENERAL_PARAM_OFS, y+3, 5*FW-1, SOLID);
|
||||
if (attr && (!(attr & BLINK) || !BLINK_ON_PHASE)) lcd_filled_rect(GENERAL_PARAM_OFS, y, 5*FW-1, FH-1);
|
||||
}
|
||||
|
||||
enum menuProcSetupItems {
|
||||
ITEM_SETUP_BEEPER_MODE,
|
||||
#if defined(PCBARM)
|
||||
ITEM_SETUP_SPEAKER_VOLUME,
|
||||
#endif
|
||||
ITEM_SETUP_BEEPER_LENGTH,
|
||||
#if defined(AUDIO)
|
||||
ITEM_SETUP_SPEAKER_PITCH,
|
||||
#endif
|
||||
#if defined(HAPTIC)
|
||||
ITEM_SETUP_HAPTIC_MODE,
|
||||
ITEM_SETUP_HAPTIC_LENGTH,
|
||||
ITEM_SETUP_HAPTIC_STRENGTH,
|
||||
#endif
|
||||
#if defined(PCBARM)
|
||||
ITEM_SETUP_OPTREX_DISPLAY,
|
||||
ITEM_SETUP_BRIGHTNESS,
|
||||
#endif
|
||||
ITEM_SETUP_CONTRAST,
|
||||
ITEM_SETUP_BATTERY_WARNING,
|
||||
ITEM_SETUP_INACTIVITY_ALARM,
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
ITEM_SETUP_RE_NAVIGATION,
|
||||
#endif
|
||||
ITEM_SETUP_FILTER_ADC,
|
||||
ITEM_SETUP_THROTTLE_REVERSED,
|
||||
ITEM_SETUP_MINUTE_BEEP,
|
||||
ITEM_SETUP_COUNTDOWN_BEEP,
|
||||
ITEM_SETUP_FLASH_BEEP,
|
||||
ITEM_SETUP_LIGHT_SWITCH,
|
||||
ITEM_SETUP_LIGHT_OFF_AFTER,
|
||||
#if defined(SPLASH)
|
||||
ITEM_SETUP_DISABLE_SPLASH,
|
||||
#endif
|
||||
ITEM_SETUP_SWITCH_WARNING,
|
||||
ITEM_SETUP_MEMORY_WARNING,
|
||||
ITEM_SETUP_ALARM_WARNING,
|
||||
#if defined(FRSKY)
|
||||
ITEM_SETUP_TELEMETRY_ALARM,
|
||||
ITEM_SETUP_TIMEZONE,
|
||||
ITEM_SETUP_GPSFORMAT,
|
||||
#endif
|
||||
ITEM_SETUP_RX_CHANNEL_ORD,
|
||||
ITEM_SETUP_STICK_MODE,
|
||||
ITEM_SETUP_MAX
|
||||
};
|
||||
|
||||
void menuProcSetup(uint8_t event)
|
||||
{
|
||||
#ifdef AUDIO
|
||||
#define AUDIO_ZEROS 0,
|
||||
#else
|
||||
#define AUDIO_ZEROS
|
||||
#endif
|
||||
#ifdef HAPTIC
|
||||
#define HAPTIC_ZEROS 0, 0, 0,
|
||||
#else
|
||||
#define HAPTIC_ZEROS
|
||||
#endif
|
||||
#ifdef SPLASH
|
||||
#define SPLASH_ZEROS 0,
|
||||
#else
|
||||
#define SPLASH_ZEROS
|
||||
#endif
|
||||
#ifdef FRSKY
|
||||
#define FRSKY_ZEROS 0, 0, 0,
|
||||
#else
|
||||
#define FRSKY_ZEROS
|
||||
#endif
|
||||
#ifdef PCBARM
|
||||
#define ARM_ZEROS 0, 0, 0,
|
||||
#else
|
||||
#define ARM_ZEROS
|
||||
#endif
|
||||
#ifdef ROTARY_ENCODERS
|
||||
#define ROTARY_ENCODERS_ZEROS 0,
|
||||
#else
|
||||
#define ROTARY_ENCODERS_ZEROS
|
||||
#endif
|
||||
|
||||
MENU(STR_MENURADIOSETUP, menuTabDiag, e_Setup, ITEM_SETUP_MAX+2, {0, 0, AUDIO_ZEROS HAPTIC_ZEROS ARM_ZEROS ROTARY_ENCODERS_ZEROS 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, SPLASH_ZEROS 0, 0, 0, 0, FRSKY_ZEROS 0, (uint8_t)-1, 1});
|
||||
|
||||
uint8_t sub = m_posVert - 1;
|
||||
|
||||
for (uint8_t i=0; i<7; i++) {
|
||||
uint8_t y = 1*FH + i*FH;
|
||||
uint8_t k = i+s_pgOfs;
|
||||
uint8_t blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
|
||||
uint8_t attr = (sub == k ? blink : 0);
|
||||
|
||||
switch(k) {
|
||||
case ITEM_SETUP_BEEPER_MODE:
|
||||
g_eeGeneral.beeperMode = selectMenuItem(y, STR_BEEPERMODE, STR_VBEEPMODE, g_eeGeneral.beeperMode, -2, 1, attr, event);
|
||||
#if defined(FRSKY)
|
||||
if (attr && checkIncDec_Ret) FRSKY_setModelAlarms();
|
||||
#endif
|
||||
break;
|
||||
|
||||
#if defined(PCBARM)
|
||||
case ITEM_SETUP_SPEAKER_VOLUME:
|
||||
{
|
||||
uint8_t current_volume = g_eeGeneral.speakerVolume;
|
||||
lcd_putsLeft(y, PSTR("Speaker Volume")); // TODO translations
|
||||
lcd_outdezAtt(GENERAL_PARAM_OFS, y, current_volume, attr|LEFT);
|
||||
if(attr) {
|
||||
CHECK_INCDEC_GENVAR(event, current_volume, 0, NUM_VOL_LEVELS-1);
|
||||
if (current_volume != g_eeGeneral.speakerVolume) {
|
||||
set_volume(g_eeGeneral.speakerVolume = current_volume);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case ITEM_SETUP_BEEPER_LENGTH: {
|
||||
int8_t beeperLength = g_eeGeneral.beeperLength;
|
||||
displaySlider(GENERAL_PARAM_OFS, y, beeperLength, attr);
|
||||
g_eeGeneral.beeperLength = selectMenuItem(y, STR_BEEPERLEN, NULL, beeperLength, -2, 2, attr, event);
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(AUDIO)
|
||||
case ITEM_SETUP_SPEAKER_PITCH:
|
||||
lcd_putsLeft( y, STR_SPKRPITCH);
|
||||
lcd_outdezAtt(GENERAL_PARAM_OFS, y, g_eeGeneral.speakerPitch, attr|LEFT);
|
||||
if (attr) {
|
||||
CHECK_INCDEC_GENVAR(event, g_eeGeneral.speakerPitch, 0, 100);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAPTIC
|
||||
case ITEM_SETUP_HAPTIC_MODE:
|
||||
g_eeGeneral.hapticMode = selectMenuItem(y, STR_HAPTICMODE, STR_VBEEPMODE, g_eeGeneral.hapticMode, -2, 1, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_SETUP_HAPTIC_LENGTH:
|
||||
{
|
||||
int8_t hapticLength = g_eeGeneral.hapticLength;
|
||||
displaySlider(GENERAL_PARAM_OFS, y, hapticLength, attr);
|
||||
g_eeGeneral.hapticLength = selectMenuItem(y, STR_HAPTICLENGTH, NULL, hapticLength, -2, 2, attr, event);
|
||||
break;
|
||||
}
|
||||
|
||||
case ITEM_SETUP_HAPTIC_STRENGTH:
|
||||
lcd_putsLeft( y, STR_HAPTICSTRENGTH);
|
||||
lcd_outdezAtt(GENERAL_PARAM_OFS, y, g_eeGeneral.hapticStrength, attr|LEFT);
|
||||
if (attr) {
|
||||
CHECK_INCDEC_GENVAR(event, g_eeGeneral.hapticStrength, 0, 5);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(PCBARM)
|
||||
case ITEM_SETUP_OPTREX_DISPLAY:
|
||||
g_eeGeneral.optrexDisplay = onoffMenuItem( g_eeGeneral.optrexDisplay, y, PSTR("Optrex Display"), attr, event ) ;
|
||||
break;
|
||||
|
||||
case ITEM_SETUP_BRIGHTNESS:
|
||||
lcd_putsLeft(y, PSTR("Brightness")); // TODO translations in the whole file ...
|
||||
lcd_outdezAtt(GENERAL_PARAM_OFS, y, 100-g_eeGeneral.backlightBright, attr|LEFT) ;
|
||||
if(attr) {
|
||||
uint8_t b ;
|
||||
b = 100 - g_eeGeneral.backlightBright;
|
||||
CHECK_INCDEC_GENVAR(event, b, 0, 100);
|
||||
g_eeGeneral.backlightBright = 100 - b;
|
||||
#ifndef SIMU
|
||||
PWM->PWM_CH_NUM[0].PWM_CDTYUPD = g_eeGeneral.backlightBright ;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case ITEM_SETUP_CONTRAST:
|
||||
lcd_putsLeft( y, STR_CONTRAST);
|
||||
lcd_outdezAtt(GENERAL_PARAM_OFS,y,g_eeGeneral.contrast, attr|LEFT);
|
||||
if(attr) {
|
||||
CHECK_INCDEC_GENVAR(event, g_eeGeneral.contrast, 10, 45);
|
||||
lcdSetRefVolt(g_eeGeneral.contrast);
|
||||
}
|
||||
break;
|
||||
|
||||
case ITEM_SETUP_BATTERY_WARNING:
|
||||
lcd_putsLeft( y,STR_BATTERYWARNING);
|
||||
putsVolts(GENERAL_PARAM_OFS, y, g_eeGeneral.vBatWarn, attr|LEFT);
|
||||
if(attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatWarn, 40, 120); //4-12V
|
||||
break;
|
||||
|
||||
case ITEM_SETUP_INACTIVITY_ALARM:
|
||||
lcd_putsLeft( y,STR_INACTIVITYALARM);
|
||||
lcd_outdezAtt(GENERAL_PARAM_OFS, y, g_eeGeneral.inactivityTimer, attr|LEFT);
|
||||
lcd_putc(lcd_lastPos, y, 'm');
|
||||
if(attr) g_eeGeneral.inactivityTimer = checkIncDec(event, g_eeGeneral.inactivityTimer, 0, 250, EE_GENERAL); //0..250minutes
|
||||
break;
|
||||
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
case ITEM_SETUP_RE_NAVIGATION:
|
||||
g_eeGeneral.reNavigation = selectMenuItem(y, STR_RENAVIG, STR_VRENAVIG, g_eeGeneral.reNavigation, 0, 2, attr, event);
|
||||
if (attr && checkIncDec_Ret) {
|
||||
g_rotenc[0] = 0;
|
||||
g_rotenc[1] = 0;
|
||||
p1valdiff = 0;
|
||||
scrollRE = 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case ITEM_SETUP_FILTER_ADC:
|
||||
g_eeGeneral.filterInput = selectMenuItem(y, STR_FILTERADC, STR_VFILTERADC, g_eeGeneral.filterInput, 0, 2, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_SETUP_THROTTLE_REVERSED:
|
||||
g_eeGeneral.throttleReversed = onoffMenuItem( g_eeGeneral.throttleReversed, y, STR_THROTTLEREVERSE, attr, event ) ;
|
||||
break;
|
||||
|
||||
case ITEM_SETUP_MINUTE_BEEP:
|
||||
g_eeGeneral.minuteBeep = onoffMenuItem( g_eeGeneral.minuteBeep, y, STR_MINUTEBEEP, attr, event ) ;
|
||||
break;
|
||||
|
||||
case ITEM_SETUP_COUNTDOWN_BEEP:
|
||||
g_eeGeneral.preBeep = onoffMenuItem( g_eeGeneral.preBeep, y, STR_BEEPCOUNTDOWN, attr, event ) ;
|
||||
break;
|
||||
|
||||
case ITEM_SETUP_FLASH_BEEP:
|
||||
g_eeGeneral.flashBeep = onoffMenuItem( g_eeGeneral.flashBeep, y, STR_FLASHONBEEP, attr, event ) ;
|
||||
break;
|
||||
|
||||
case ITEM_SETUP_LIGHT_SWITCH:
|
||||
lcd_putsLeft( y, STR_LIGHTSWITCH);
|
||||
putsSwitches(GENERAL_PARAM_OFS,y,g_eeGeneral.lightSw,attr ? INVERS : 0);
|
||||
if(attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.lightSw, SWITCH_OFF, SWITCH_ON);
|
||||
break;
|
||||
|
||||
case ITEM_SETUP_LIGHT_OFF_AFTER:
|
||||
lcd_putsLeft( y, STR_LIGHTOFFAFTER);
|
||||
if(g_eeGeneral.lightAutoOff) {
|
||||
lcd_outdezAtt(GENERAL_PARAM_OFS, y, g_eeGeneral.lightAutoOff*5, attr|LEFT);
|
||||
lcd_putc(lcd_lastPos, y, 's');
|
||||
}
|
||||
else {
|
||||
lcd_putsiAtt(GENERAL_PARAM_OFS, y, STR_OFFON, 0, attr);
|
||||
}
|
||||
if(attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.lightAutoOff, 0, 600/5);
|
||||
break;
|
||||
|
||||
#ifdef SPLASH
|
||||
case ITEM_SETUP_DISABLE_SPLASH:
|
||||
{
|
||||
uint8_t b = 1-g_eeGeneral.disableSplashScreen;
|
||||
g_eeGeneral.disableSplashScreen = 1 - onoffMenuItem( b, y, STR_SPLASHSCREEN, attr, event ) ;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case ITEM_SETUP_SWITCH_WARNING:
|
||||
g_eeGeneral.switchWarning = selectMenuItem(y, STR_SWITCHWARNING, STR_WARNSW, g_eeGeneral.switchWarning, -1, 1, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_SETUP_MEMORY_WARNING:
|
||||
{
|
||||
uint8_t b = 1-g_eeGeneral.disableMemoryWarning;
|
||||
g_eeGeneral.disableMemoryWarning = 1 - onoffMenuItem( b, y, STR_MEMORYWARNING, attr, event ) ;
|
||||
break;
|
||||
}
|
||||
|
||||
case ITEM_SETUP_ALARM_WARNING:
|
||||
{
|
||||
uint8_t b = 1-g_eeGeneral.disableAlarmWarning;
|
||||
g_eeGeneral.disableAlarmWarning = 1 - onoffMenuItem( b, y, STR_ALARMWARNING, attr, event ) ;
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(FRSKY)
|
||||
case ITEM_SETUP_TELEMETRY_ALARM:
|
||||
{
|
||||
uint8_t b = g_eeGeneral.enableTelemetryAlarm;
|
||||
g_eeGeneral.enableTelemetryAlarm = onoffMenuItem( b, y, STR_NODATAALARM, attr, event ) ;
|
||||
break;
|
||||
}
|
||||
|
||||
case ITEM_SETUP_TIMEZONE:
|
||||
lcd_putsLeft(y, STR_TIMEZONE);
|
||||
lcd_outdezAtt(GENERAL_PARAM_OFS, y, g_eeGeneral.timezone, attr|LEFT);
|
||||
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.timezone, -12, 12);
|
||||
break;
|
||||
|
||||
case ITEM_SETUP_GPSFORMAT:
|
||||
g_eeGeneral.gpsFormat = selectMenuItem(y, STR_GPSCOORD, STR_GPSFORMAT, g_eeGeneral.gpsFormat, 0, 1, attr, event);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case ITEM_SETUP_RX_CHANNEL_ORD:
|
||||
lcd_putsLeft( y,STR_RXCHANNELORD);// RAET->AETR
|
||||
for (uint8_t i=1; i<=4; i++)
|
||||
putsChnLetter(GENERAL_PARAM_OFS - FW + i*FW, y, channel_order(i), attr);
|
||||
if(attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.templateSetup, 0, 23);
|
||||
break;
|
||||
|
||||
case ITEM_SETUP_STICK_MODE:
|
||||
lcd_puts( 1*FW, y, STR_MODE);
|
||||
for(uint8_t i=0; i<4; i++) lcd_img((6+4*i)*FW, y, sticks,i,0);
|
||||
if((y+=FH)>7*FH) return;
|
||||
lcd_putcAtt( 3*FW, y, '1'+g_eeGeneral.stickMode,(sub==k+1) ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0);
|
||||
for(uint8_t i=0; i<4; i++) putsChnRaw( (6+4*i)*FW, y, pgm_read_byte(modn12x3 + 4*g_eeGeneral.stickMode + i), 0);
|
||||
|
||||
if (sub==k+1 && s_editMode>0)
|
||||
CHECK_INCDEC_GENVAR(event, g_eeGeneral.stickMode, 0, 3);
|
||||
else
|
||||
stickMode = g_eeGeneral.stickMode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(PCBV4) && defined(SDCARD)
|
||||
// SD card interface contains Real-Time-Clock chip
|
||||
void menuProcTime(uint8_t event)
|
||||
{
|
||||
MENU(STR_MENUDATEANDTIME, menuTabDiag, e_FrskyTime, 3, {0, 2/*, 2*/});
|
||||
|
||||
int8_t sub = m_posVert - 1; // vertical position (1 = page counter, top/right)
|
||||
uint8_t subSub = m_posHorz; // horizontal position
|
||||
static struct gtm t;
|
||||
struct gtm *at = &t;
|
||||
|
||||
switch(event)
|
||||
{
|
||||
case EVT_KEY_LONG(KEY_MENU):
|
||||
// get data time from RTC chip (may not implement)
|
||||
killEvents(event);
|
||||
break;
|
||||
case EVT_KEY_FIRST(KEY_MENU):
|
||||
if (sub >= 0 && s_editMode<=0) // set the date and time into RTC chip
|
||||
{
|
||||
g_ms100 = 0; // start of next second begins now
|
||||
g_unixTime = mktime(&t); // update local timestamp and get wday calculated
|
||||
|
||||
RTC rtc;
|
||||
rtc.year = t.tm_year + 1900;
|
||||
rtc.month = t.tm_mon + 1;
|
||||
rtc.mday = t.tm_mday;
|
||||
rtc.hour = t.tm_hour;
|
||||
rtc.min = t.tm_min;
|
||||
rtc.sec = t.tm_sec;
|
||||
rtc.wday = t.tm_wday + 1;
|
||||
|
||||
rtc_settime(&rtc);
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (s_editMode<=0) filltm(&g_unixTime, &t);
|
||||
|
||||
lcd_putc(FW*10+2, FH*2, '-'); lcd_putc(FW*13, FH*2, '-');
|
||||
lcd_putc(FW*10+1, FH*4, ':'); lcd_putc(FW*13-1, FH*4, ':');
|
||||
|
||||
for(uint8_t i=0; i<2; i++) // 2 rows, date then time
|
||||
{
|
||||
uint8_t y=(i*2+2)*FH;
|
||||
|
||||
lcd_putsiAtt(0, y, STR_DATETIME, i, 0);
|
||||
|
||||
for(uint8_t j=0; j<3;j++) // 3 settings each for date and time (YMD and HMS)
|
||||
{
|
||||
uint8_t attr = (sub==i && subSub==j) ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0;
|
||||
switch(i)
|
||||
{
|
||||
case 0: // DATE
|
||||
switch(j)
|
||||
{
|
||||
case 0:
|
||||
lcd_outdezAtt(FW*10+2, y, at->tm_year+1900, attr);
|
||||
if(attr && (s_editMode>0 || p1valdiff)) at->tm_year = checkIncDec( event, at->tm_year, 110, 200, 0);
|
||||
break;
|
||||
case 1:
|
||||
lcd_outdezNAtt(FW*13, y, at->tm_mon+1, attr|LEADING0, 2);
|
||||
if(attr && (s_editMode>0 || p1valdiff)) at->tm_mon = checkIncDec( event, at->tm_mon, 0, 11, 0);
|
||||
break;
|
||||
case 2:
|
||||
lcd_outdezNAtt(FW*16-2, y, at->tm_mday, attr|LEADING0, 2);
|
||||
if(attr && (s_editMode>0 || p1valdiff)) at->tm_mday = checkIncDec( event, at->tm_mday, 1, 31, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
switch (j)
|
||||
{
|
||||
case 0:
|
||||
lcd_outdezNAtt(FW*10+1, y, at->tm_hour, attr|LEADING0, 2);
|
||||
if(attr && (s_editMode>0 || p1valdiff)) at->tm_hour = checkIncDec( event, at->tm_hour, 0, 23, 0);
|
||||
break;
|
||||
case 1:
|
||||
lcd_outdezNAtt(FW*13-1, y, at->tm_min, attr|LEADING0, 2);
|
||||
if(attr && (s_editMode>0 || p1valdiff)) at->tm_min = checkIncDec( event, at->tm_min, 0, 59, 0);
|
||||
break;
|
||||
case 2:
|
||||
lcd_outdezNAtt(FW*16-2, y, at->tm_sec, attr|LEADING0, 2);
|
||||
if(attr && (s_editMode>0 || p1valdiff)) at->tm_sec = checkIncDec( event, at->tm_sec, 0, 59, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void menuProcTrainer(uint8_t event)
|
||||
{
|
||||
uint8_t y;
|
||||
bool slave = SLAVE_MODE;
|
||||
|
||||
MENU(STR_MENUTRAINER, menuTabDiag, e_Trainer, slave ? 1 : 7, {0, 2, 2, 2, 2, 0/*, 0*/});
|
||||
|
||||
if (slave) { // i am the slave
|
||||
lcd_puts(7*FW, 3*FH, STR_SLAVE);
|
||||
}
|
||||
else {
|
||||
uint8_t attr;
|
||||
uint8_t blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
|
||||
|
||||
lcd_puts(3*FW, 1*FH, STR_MODESRC);
|
||||
|
||||
y = 2*FH;
|
||||
|
||||
for (uint8_t i=1; i<=NUM_STICKS; i++) {
|
||||
uint8_t chan = channel_order(i);
|
||||
volatile TrainerMix *td = &g_eeGeneral.trainer.mix[chan-1];
|
||||
|
||||
putsChnRaw(0, y, chan, 0);
|
||||
|
||||
for (uint8_t j=0; j<3; j++) {
|
||||
|
||||
attr = ((m_posVert==i && m_posHorz==j) ? blink : 0);
|
||||
|
||||
switch(j) {
|
||||
case 0:
|
||||
lcd_putsiAtt(4*FW, y, STR_TRNMODE, td->mode, attr);
|
||||
if (attr&BLINK) CHECK_INCDEC_GENVAR(event, td->mode, 0, 2);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
lcd_outdezAtt(11*FW, y, td->studWeight, attr);
|
||||
if (attr&BLINK) CHECK_INCDEC_GENVAR(event, td->studWeight, -100, 100);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
lcd_putsiAtt(12*FW, y, STR_TRNCHN, td->srcChn, attr);
|
||||
if (attr&BLINK) CHECK_INCDEC_GENVAR(event, td->srcChn, 0, 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
y += FH;
|
||||
}
|
||||
|
||||
attr = (m_posVert==5) ? blink : 0;
|
||||
lcd_putsLeft(6*FH, STR_MULTIPLIER);
|
||||
lcd_outdezAtt(LEN_MULTIPLIER*FW+3*FW, 6*FH, g_eeGeneral.PPM_Multiplier+10, attr|PREC1);
|
||||
if (attr) CHECK_INCDEC_GENVAR(event, g_eeGeneral.PPM_Multiplier, -10, 40);
|
||||
|
||||
attr = (m_posVert==6) ? blink : 0;
|
||||
lcd_putsAtt(0*FW, 7*FH, STR_CAL, attr);
|
||||
for (uint8_t i=0; i<4; i++) {
|
||||
uint8_t x = (i*8+16)*FW/2;
|
||||
#if defined (DECIMALS_DISPLAYED)
|
||||
lcd_outdezAtt(x, 7*FH, (g_ppmIns[i]-g_eeGeneral.trainer.calib[i])*2, PREC1);
|
||||
#else
|
||||
lcd_outdezAtt(x, 7*FH, (g_ppmIns[i]-g_eeGeneral.trainer.calib[i])/5, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (attr) {
|
||||
if (event==EVT_KEY_FIRST(KEY_MENU)){
|
||||
s_editMode = -1;
|
||||
memcpy(g_eeGeneral.trainer.calib, g_ppmIns, sizeof(g_eeGeneral.trainer.calib));
|
||||
eeDirty(EE_GENERAL);
|
||||
AUDIO_KEYPAD_UP();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void menuProcDiagVers(uint8_t event)
|
||||
{
|
||||
SIMPLE_MENU(STR_MENUVERSION, menuTabDiag, e_Vers, 1);
|
||||
|
||||
lcd_putsLeft(2*FH, stamp1);
|
||||
lcd_putsLeft(3*FH, stamp2);
|
||||
lcd_putsLeft(4*FH, stamp3);
|
||||
lcd_putsLeft(5*FH, stamp4);
|
||||
lcd_putsLeft(7*FH, STR_EEPROMV);
|
||||
lcd_outdezAtt(8*FW, 7*FH, g_eeGeneral.myVers, LEFT);
|
||||
}
|
||||
|
||||
void menuProcDiagKeys(uint8_t event)
|
||||
{
|
||||
SIMPLE_MENU(STR_MENUDIAG, menuTabDiag, e_Keys, 1);
|
||||
|
||||
for(uint8_t i=0; i<9; i++) {
|
||||
uint8_t y=i*FH; //+FH;
|
||||
if(i>(SW_ID0-SW_BASE_DIAG)) y-=FH; //overwrite ID0
|
||||
bool t=keyState((EnumKeys)(SW_BASE_DIAG+i));
|
||||
putsSwitches(8*FW, y, i+1, 0); //ohne off,on
|
||||
lcd_putcAtt(11*FW+2, y, t+'0', t ? INVERS : 0);
|
||||
}
|
||||
|
||||
for(uint8_t i=0; i<6; i++) {
|
||||
uint8_t y=(5-i)*FH+2*FH;
|
||||
bool t=keyState((EnumKeys)(KEY_MENU+i));
|
||||
lcd_putsiAtt(0, y, STR_VKEYS, i, 0);
|
||||
lcd_putcAtt(5*FW+2, y, t+'0', t);
|
||||
}
|
||||
|
||||
#if defined (PCBV4)
|
||||
for(uint8_t i=0; i<2; i++) {
|
||||
uint8_t y = i*FH + FH;
|
||||
lcd_putsiAtt(14*FW, y, STR_RE1RE2, i, 0);
|
||||
lcd_outdezNAtt(18*FW, y, g_rotenc[i], LEFT|(keyState((EnumKeys)(BTN_REa+i)) ? INVERS : 0));
|
||||
}
|
||||
#endif
|
||||
|
||||
lcd_puts(14*FW, 3*FH, STR_VTRIM);
|
||||
for(uint8_t i=0; i<4; i++) {
|
||||
uint8_t y=i*FH+FH*4;
|
||||
lcd_img(14*FW, y, sticks,i,0);
|
||||
bool tm=keyState((EnumKeys)(TRM_BASE+2*i));
|
||||
bool tp=keyState((EnumKeys)(TRM_BASE+2*i+1));
|
||||
lcd_putcAtt(18*FW, y, tm+'0', tm ? INVERS : 0);
|
||||
lcd_putcAtt(20*FW, y, tp+'0', tp ? INVERS : 0);
|
||||
}
|
||||
}
|
||||
|
||||
void menuProcDiagAna(uint8_t event)
|
||||
{
|
||||
#if defined(PCBARM) && defined(REVB)
|
||||
#define ANAS_ITEMS_COUNT 3
|
||||
#else
|
||||
#define ANAS_ITEMS_COUNT 2
|
||||
#endif
|
||||
|
||||
SIMPLE_MENU(STR_MENUANA, menuTabDiag, e_Ana, ANAS_ITEMS_COUNT);
|
||||
|
||||
for (uint8_t i=0; i<7; i++) {
|
||||
uint8_t y = 1+FH+(i/2)*FH;
|
||||
uint8_t x = i&1 ? 64+5 : 0;
|
||||
putsStrIdx(x, y, PSTR("A"), i+1, TWO_DOTS);
|
||||
lcd_outhex4(x+3*FW-1, y, anaIn(i));
|
||||
lcd_outdez8(x+10*FW-1, y, (int16_t)calibratedStick[CONVERT_MODE(i+1)-1]*25/256);
|
||||
}
|
||||
|
||||
#if !defined(PCBARM)
|
||||
// Display raw BandGap result (debug)
|
||||
lcd_puts(64+5, 1+4*FH, STR_BG);
|
||||
lcd_outdezAtt(64+5+6*FW-3, 1+4*FH, BandGap, 0);
|
||||
#endif
|
||||
|
||||
// Voltage calibration
|
||||
lcd_putsLeft(6*FH-2, STR_BATT_CALIB);
|
||||
putsVolts(LEN_CALIB_FIELDS*FW+4*FW, 6*FH-2, g_vbat100mV, (m_posVert==1 ? INVERS : 0));
|
||||
if (m_posVert==1) CHECK_INCDEC_GENVAR(event, g_eeGeneral.vBatCalib, -127, 127);
|
||||
|
||||
#if defined(PCBARM) && defined(REVB)
|
||||
lcd_putsLeft(7*FH-2, STR_CURRENT_CALIB);
|
||||
putsTelemetryValue(LEN_CALIB_FIELDS*FW+4*FW, 7*FH-2, getCurrent(), UNIT_MILLIAMPS, (m_posVert==2 ? INVERS : 0)) ;
|
||||
if (m_posVert==2) CHECK_INCDEC_GENVAR(event, g_eeGeneral.currentCalib, -49, 49);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void menuProcDiagCalib(uint8_t event)
|
||||
{
|
||||
SIMPLE_MENU(STR_MENUCALIBRATION, menuTabDiag, e_Calib, 1);
|
||||
|
||||
static uint8_t idxState;
|
||||
|
||||
for (uint8_t i=0; i<7; i++) { //get low and high vals for sticks and trims
|
||||
int16_t vt = anaIn(i);
|
||||
reusableBuffer.calib.loVals[i] = min(vt, reusableBuffer.calib.loVals[i]);
|
||||
reusableBuffer.calib.hiVals[i] = max(vt, reusableBuffer.calib.hiVals[i]);
|
||||
//if(i>=4) midVals[i] = (loVals[i] + hiVals[i])/2;
|
||||
}
|
||||
|
||||
s_noScroll = idxState; // make sure we don't scroll while calibrating
|
||||
|
||||
switch(event)
|
||||
{
|
||||
case EVT_ENTRY:
|
||||
idxState = 0;
|
||||
break;
|
||||
|
||||
case EVT_KEY_BREAK(KEY_MENU):
|
||||
idxState++;
|
||||
if (idxState==3) {
|
||||
STORE_GENERALVARS;
|
||||
idxState = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
switch (idxState) {
|
||||
case 0:
|
||||
// START CALIBRATION
|
||||
lcd_puts(3*FW, 3*FH, STR_MENUTOSTART);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// SET MIDPOINT
|
||||
lcd_putsAtt(5*FW, 2*FH, STR_SETMIDPOINT, s_noScroll ? INVERS : 0);
|
||||
lcd_puts(3*FW, 3*FH, STR_MENUWHENDONE);
|
||||
|
||||
for (uint8_t i=0; i<7; i++) {
|
||||
reusableBuffer.calib.loVals[i] = 15000;
|
||||
reusableBuffer.calib.hiVals[i] = -15000;
|
||||
reusableBuffer.calib.midVals[i] = anaIn(i);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// MOVE STICKS/POTS
|
||||
lcd_putsAtt(3*FW, 2*FH, STR_MOVESTICKSPOTS, s_noScroll ? INVERS : 0);
|
||||
lcd_puts(3*FW, 3*FH, STR_MENUWHENDONE);
|
||||
|
||||
for (uint8_t i=0; i<7; i++) {
|
||||
if (abs(reusableBuffer.calib.loVals[i]-reusableBuffer.calib.hiVals[i])>50) {
|
||||
g_eeGeneral.calibMid[i] = reusableBuffer.calib.midVals[i];
|
||||
int16_t v = reusableBuffer.calib.midVals[i] - reusableBuffer.calib.loVals[i];
|
||||
g_eeGeneral.calibSpanNeg[i] = v - v/64;
|
||||
v = reusableBuffer.calib.hiVals[i] - reusableBuffer.calib.midVals[i];
|
||||
g_eeGeneral.calibSpanPos[i] = v - v/64;
|
||||
}
|
||||
}
|
||||
|
||||
g_eeGeneral.chkSum = evalChkSum();
|
||||
break;
|
||||
}
|
||||
|
||||
doMainScreenGrphics();
|
||||
}
|
||||
@@ -1,95 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
I put this in place of the code in the FRSKY first menu page, just as a quick test
|
||||
*/
|
||||
// DISK_IO DEBUG -- XXX DELETE ME
|
||||
|
||||
static uint8_t onceonly = 0;
|
||||
static FRESULT f_err_code;
|
||||
static FATFS FATFS_Obj;
|
||||
static uint8_t result = 0;
|
||||
static TCHAR sBuffer[100] = {0};
|
||||
static TCHAR *myStr = sBuffer;
|
||||
|
||||
if (!onceonly)
|
||||
{
|
||||
// First, let's try to set the RTC date/time
|
||||
RTC rtc;
|
||||
|
||||
rtc.year = 2011;
|
||||
rtc.month = 6;
|
||||
rtc.mday = 23;
|
||||
rtc.wday = 5;
|
||||
rtc.hour = 21;
|
||||
rtc.min = 53;
|
||||
rtc.sec = 0;
|
||||
|
||||
// rtc_settime(&rtc);
|
||||
// IT WORKED! And battery back-up for the RTC chip is working also.
|
||||
//////////////////////
|
||||
|
||||
f_err_code = f_mount(0, &FATFS_Obj);
|
||||
FIL fil_obj;
|
||||
|
||||
// atempt creating and writing to a new file
|
||||
result = f_open(&fil_obj, "/foo.txt", FA_CREATE_ALWAYS | FA_WRITE);
|
||||
f_printf(&fil_obj, "gruvin9x created this file! Yay!\n");
|
||||
f_close(&fil_obj);
|
||||
|
||||
// That worked! Now test reading a line from another file.
|
||||
result = f_open(&fil_obj, "/foo.txt", FA_READ);
|
||||
myStr = f_gets(sBuffer, 100, &fil_obj);
|
||||
|
||||
f_close(&fil_obj);
|
||||
|
||||
onceonly = 1;
|
||||
}
|
||||
|
||||
lcd_outdezAtt(5*FW, 2*FH, f_err_code, 0);
|
||||
lcd_outdezAtt(5*FW, 3*FH, result, 0);
|
||||
lcd_outdezAtt(5*FW, 4*FH, strlen(myStr), 0);
|
||||
lcd_outdezAtt(5*FW, 5*FH, myStr[0], 0);
|
||||
|
||||
// can't use lcd_puts... becasue it specifies prog_char mem space, not SRAM
|
||||
uint8_t x=0;
|
||||
uint8_t j=6;
|
||||
for (uint8_t i=0; i<strlen(myStr); i++)
|
||||
{
|
||||
if (myStr[i]==0) break;
|
||||
if (myStr[i]!='\n') lcd_putc(x, j*FH, myStr[i]);
|
||||
x+=FW;
|
||||
}
|
||||
|
||||
return;
|
||||
-578
@@ -1,578 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs - FAT file system module include file R0.08a (C)ChaN, 2010
|
||||
/----------------------------------------------------------------------------/
|
||||
/ 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) 2010, 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 8255 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "inttypes.h"
|
||||
#include "integer.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
#include "gtime.h"
|
||||
|
||||
#if _FATFS != _FFCONF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
|
||||
/* DBCS code ranges and SBCS extend char conversion table */
|
||||
|
||||
#if _CODE_PAGE == 932 /* Japanese Shift-JIS */
|
||||
#define _DF1S 0x81 /* DBC 1st byte range 1 start */
|
||||
#define _DF1E 0x9F /* DBC 1st byte range 1 end */
|
||||
#define _DF2S 0xE0 /* DBC 1st byte range 2 start */
|
||||
#define _DF2E 0xFC /* DBC 1st byte range 2 end */
|
||||
#define _DS1S 0x40 /* DBC 2nd byte range 1 start */
|
||||
#define _DS1E 0x7E /* DBC 2nd byte range 1 end */
|
||||
#define _DS2S 0x80 /* DBC 2nd byte range 2 start */
|
||||
#define _DS2E 0xFC /* DBC 2nd byte range 2 end */
|
||||
|
||||
#elif _CODE_PAGE == 936 /* Simplified Chinese GBK */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x40
|
||||
#define _DS1E 0x7E
|
||||
#define _DS2S 0x80
|
||||
#define _DS2E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 949 /* Korean */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x41
|
||||
#define _DS1E 0x5A
|
||||
#define _DS2S 0x61
|
||||
#define _DS2E 0x7A
|
||||
#define _DS3S 0x81
|
||||
#define _DS3E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 950 /* Traditional Chinese Big5 */
|
||||
#define _DF1S 0x81
|
||||
#define _DF1E 0xFE
|
||||
#define _DS1S 0x40
|
||||
#define _DS1E 0x7E
|
||||
#define _DS2S 0xA1
|
||||
#define _DS2E 0xFE
|
||||
|
||||
#elif _CODE_PAGE == 437 /* U.S. (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0x41,0x8E,0x41,0x8F,0x80,0x45,0x45,0x45,0x49,0x49,0x49,0x8E,0x8F,0x90,0x92,0x92,0x4F,0x99,0x4F,0x55,0x55,0x59,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 720 /* Arabic (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x45,0x41,0x84,0x41,0x86,0x43,0x45,0x45,0x45,0x49,0x49,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x49,0x49,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 737 /* Greek (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x92,0x92,0x93,0x94,0x95,0x96,0x97,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, \
|
||||
0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0xAA,0x92,0x93,0x94,0x95,0x96,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0x97,0xEA,0xEB,0xEC,0xE4,0xED,0xEE,0xE7,0xE8,0xF1,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 775 /* Baltic (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x91,0xA0,0x8E,0x95,0x8F,0x80,0xAD,0xED,0x8A,0x8A,0xA1,0x8D,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0x95,0x96,0x97,0x97,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xE0,0xA3,0xA3,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xB5,0xB6,0xB7,0xB8,0xBD,0xBE,0xC6,0xC7,0xA5,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE3,0xE8,0xE8,0xEA,0xEA,0xEE,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 850 /* Multilingual Latin 1 (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 852 /* Latin 2 (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xDE,0x8F,0x80,0x9D,0xD3,0x8A,0x8A,0xD7,0x8D,0x8E,0x8F,0x90,0x91,0x91,0xE2,0x99,0x95,0x95,0x97,0x97,0x99,0x9A,0x9B,0x9B,0x9D,0x9E,0x9F, \
|
||||
0xB5,0xD6,0xE0,0xE9,0xA4,0xA4,0xA6,0xA6,0xA8,0xA8,0xAA,0x8D,0xAC,0xB8,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBD,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC6,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD2,0xD5,0xD6,0xD7,0xB7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE3,0xD5,0xE6,0xE6,0xE8,0xE9,0xE8,0xEB,0xED,0xED,0xDD,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xEB,0xFC,0xFC,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 855 /* Cyrillic (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x81,0x81,0x83,0x83,0x85,0x85,0x87,0x87,0x89,0x89,0x8B,0x8B,0x8D,0x8D,0x8F,0x8F,0x91,0x91,0x93,0x93,0x95,0x95,0x97,0x97,0x99,0x99,0x9B,0x9B,0x9D,0x9D,0x9F,0x9F, \
|
||||
0xA1,0xA1,0xA3,0xA3,0xA5,0xA5,0xA7,0xA7,0xA9,0xA9,0xAB,0xAB,0xAD,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB6,0xB6,0xB8,0xB8,0xB9,0xBA,0xBB,0xBC,0xBE,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD7,0xDD,0xD9,0xDA,0xDB,0xDC,0xDD,0xE0,0xDF, \
|
||||
0xE0,0xE2,0xE2,0xE4,0xE4,0xE6,0xE6,0xE8,0xE8,0xEA,0xEA,0xEC,0xEC,0xEE,0xEE,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF8,0xFA,0xFA,0xFC,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 857 /* Turkish (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0x98,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x98,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9E, \
|
||||
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA6,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xDE,0x59,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 858 /* Multilingual Latin 1 + Euro (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x9A,0x90,0xB6,0x8E,0xB7,0x8F,0x80,0xD2,0xD3,0xD4,0xD8,0xD7,0xDE,0x8E,0x8F,0x90,0x92,0x92,0xE2,0x99,0xE3,0xEA,0xEB,0x59,0x99,0x9A,0x9D,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xB5,0xD6,0xE0,0xE9,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC7,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD1,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE5,0xE5,0xE6,0xE7,0xE7,0xE9,0xEA,0xEB,0xED,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 862 /* Hebrew (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0x41,0x49,0x4F,0x55,0xA5,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0x21,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 866 /* Russian (OEM) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0x90,0x91,0x92,0x93,0x9d,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xF0,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 874 /* Thai (OEM, Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1250 /* Central Europe (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xA3,0xB4,0xB5,0xB6,0xB7,0xB8,0xA5,0xAA,0xBB,0xBC,0xBD,0xBC,0xAF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1251 /* Cyrillic (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x82,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x80,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x8D,0x8E,0x8F, \
|
||||
0xA0,0xA2,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB2,0xA5,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xA3,0xBD,0xBD,0xAF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF}
|
||||
|
||||
#elif _CODE_PAGE == 1252 /* Latin 1 (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0xAd,0x9B,0x8C,0x9D,0xAE,0x9F, \
|
||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
|
||||
|
||||
#elif _CODE_PAGE == 1253 /* Greek (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xA2,0xB8,0xB9,0xBA, \
|
||||
0xE0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xFB,0xBC,0xFD,0xBF,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1254 /* Turkish (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x8A,0x9B,0x8C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x9F}
|
||||
|
||||
#elif _CODE_PAGE == 1255 /* Hebrew (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1256 /* Arabic (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x8C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0x41,0xE1,0x41,0xE3,0xE4,0xE5,0xE6,0x43,0x45,0x45,0x45,0x45,0xEC,0xED,0x49,0x49,0xF0,0xF1,0xF2,0xF3,0x4F,0xF5,0xF6,0xF7,0xF8,0x55,0xFA,0x55,0x55,0xFD,0xFE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1257 /* Baltic (Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, \
|
||||
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xA8,0xB9,0xAA,0xBB,0xBC,0xBD,0xBE,0xAF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xFF}
|
||||
|
||||
#elif _CODE_PAGE == 1258 /* Vietnam (OEM, Windows) */
|
||||
#define _DF1S 0
|
||||
#define _EXCVT {0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0xAC,0x9D,0x9E,0x9F, \
|
||||
0xA0,0x21,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, \
|
||||
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xEC,0xCD,0xCE,0xCF,0xD0,0xD1,0xF2,0xD3,0xD4,0xD5,0xD6,0xF7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xFE,0x9F}
|
||||
|
||||
#elif _CODE_PAGE == 1 /* ASCII (for only non-LFN cfg) */
|
||||
#define _DF1S 0
|
||||
|
||||
#else
|
||||
#error Unknown code page
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if _MULTI_PARTITION /* Multiple partition configuration */
|
||||
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive# */
|
||||
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition# */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive# */
|
||||
BYTE pt; /* Partition # (0-3) */
|
||||
} PARTITION;
|
||||
extern const PARTITION VolToPart[]; /* Volume - Physical location resolution table */
|
||||
|
||||
#else /* Single partition configuration */
|
||||
#define LD2PD(vol) (vol) /* Logical drive# is bound to the same physical drive# */
|
||||
#define LD2PT(vol) 0 /* Always mounts the 1st partition */
|
||||
|
||||
#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,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 org_clust; /* File start cluster (0 when fsize==0) */
|
||||
DWORD curr_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 on the physical drive
|
||||
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
|
||||
} 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*, BYTE*, 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 */
|
||||
|
||||
#if !_FS_READONLY
|
||||
FRESULT f_write (FIL*, const BYTE *, 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 */
|
||||
#endif
|
||||
|
||||
#if _USE_FORWARD
|
||||
FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */
|
||||
#endif
|
||||
|
||||
#if _USE_MKFS
|
||||
FRESULT f_mkfs (BYTE, BYTE, UINT); /* Create a file system on the drive */
|
||||
#endif
|
||||
|
||||
#if _FS_RPATH
|
||||
FRESULT f_chdrive (BYTE); /* Change current drive */
|
||||
FRESULT f_chdir (const TCHAR*); /* Change current directory */
|
||||
FRESULT f_getcwd (TCHAR*, UINT); /* Get current directory */
|
||||
#endif
|
||||
|
||||
#if _USE_STRFUNC
|
||||
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 */
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !_FS_READONLY
|
||||
extern uint32_t o9x_get_fattime (void); /* Returns 32-bit packed date and time */
|
||||
#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_del_syncobj (_SYNC_t); /* Delete a sync object */
|
||||
int ff_req_grant (_SYNC_t); /* Lock sync object */
|
||||
void ff_rel_grant (_SYNC_t); /* Unlock 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 function */
|
||||
#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
|
||||
|
||||
extern gtime_t g_unixTime; // Global date/time register, incremented each second in per10ms()
|
||||
|
||||
#endif /* _FATFS */
|
||||
@@ -1,63 +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 g9x_time_h
|
||||
#define g9x_time_h
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
|
||||
#undef CHAR_BIT
|
||||
#define CHAR_BIT 8
|
||||
|
||||
typedef long int gtime_t;
|
||||
|
||||
struct gtm
|
||||
{
|
||||
int8_t tm_sec; /* Seconds. [0-60] (1 leap second) */
|
||||
int8_t tm_min; /* Minutes. [0-59] */
|
||||
int8_t tm_hour; /* Hours. [0-23] */
|
||||
int8_t tm_mday; /* Day. [1-31] */
|
||||
int8_t tm_mon; /* Month. [0-11] */
|
||||
int8_t tm_year; /* Year - 1900. Limited to the year 2115. Oh no! :P */
|
||||
int8_t tm_wday; /* Day of week. [0-6] */
|
||||
int16_t tm_yday; /* Day of year. [0-365] Needed internally for calculations */
|
||||
};
|
||||
|
||||
extern const unsigned short int __mon_yday[2][13];
|
||||
|
||||
extern gtime_t mktime(struct gtm *tp);
|
||||
extern gtime_t filltm(gtime_t *t, struct gtm *tp);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,235 +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"
|
||||
#include "ff.h"
|
||||
|
||||
char g_logFilename[21]; // "/O9XLOGS/M00_000.CSV\0" max required length = 21
|
||||
FATFS g_FATFS_Obj;
|
||||
FIL g_oLogFile;
|
||||
int8_t g_logState = 0; // 0=closed, >0=opened, <0=error
|
||||
const pm_char * g_logError = NULL;
|
||||
|
||||
// TODO initSDCard()
|
||||
void initLogs()
|
||||
{
|
||||
// Determine and set log file filename
|
||||
FRESULT result;
|
||||
|
||||
// close any file left open. E.G. Changing models with log switch still on.
|
||||
if (g_oLogFile.fs) f_close(&g_oLogFile);
|
||||
g_logState = 0;
|
||||
|
||||
strcpy_P(g_logFilename, PSTR(LOGS_PATH "/M00_000.CSV"));
|
||||
|
||||
// Set log file model number
|
||||
uint8_t num = g_eeGeneral.currModel + 1;
|
||||
char *n = &g_logFilename[sizeof(LOGS_PATH) + 3];
|
||||
*n = (char)((num % 10) + '0');
|
||||
*(--n) = (char)((num / 10) + '0');
|
||||
|
||||
result = f_mount(0, &g_FATFS_Obj);
|
||||
if (result!=FR_OK)
|
||||
{
|
||||
g_logState = -result;
|
||||
g_logError = PSTR("SDCARD F/S ERROR");
|
||||
return;
|
||||
}
|
||||
|
||||
DIR dir;
|
||||
result = f_opendir(&dir, MODELS_PATH);
|
||||
if (result != FR_OK) {
|
||||
if (result == FR_NO_PATH)
|
||||
result = f_mkdir(MODELS_PATH);
|
||||
if (result != FR_OK) {
|
||||
g_logState = -result;
|
||||
g_logError = PSTR("Check " MODELS_PATH " folder");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Loop, skipping over any existing log files ... _000, _001, etc. until we have a unique file name
|
||||
while (1)
|
||||
{
|
||||
result = f_open(&g_oLogFile, g_logFilename, FA_OPEN_EXISTING | FA_READ);
|
||||
if (result == FR_OK)
|
||||
{
|
||||
f_close(&g_oLogFile);
|
||||
|
||||
// bump log file counter (file extension)
|
||||
n = &g_logFilename[sizeof(LOGS_PATH) + 7];
|
||||
if (++*n > '9')
|
||||
{
|
||||
*n='0';
|
||||
n--;
|
||||
if (++*n > '9')
|
||||
{
|
||||
*n='0';
|
||||
n--;
|
||||
if (++*n > '9')
|
||||
{
|
||||
*n='0';
|
||||
break; // Wow. We looped back around past 999 to 000! abort loop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (result == FR_NO_FILE /*TODO check this code*/)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (result == FR_NO_PATH)
|
||||
{
|
||||
if (f_mkdir(LOGS_PATH) != FR_OK)
|
||||
{
|
||||
g_logState = -result;
|
||||
g_logError = PSTR("Check " LOGS_PATH " folder");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_logState = -result;
|
||||
g_logError = SDCARD_ERROR(result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// g_logFilename should now be set appropriately.
|
||||
}
|
||||
|
||||
const pm_char *SDCARD_ERROR(FRESULT result)
|
||||
{
|
||||
if (result == FR_NOT_READY)
|
||||
return STR_NO_SDCARD;
|
||||
else
|
||||
return STR_SDCARD_ERROR;
|
||||
}
|
||||
|
||||
void writeLogs()
|
||||
{
|
||||
FRESULT result;
|
||||
|
||||
if (isFunctionActive(FUNC_LOGS))
|
||||
{
|
||||
if (g_logState==0)
|
||||
{
|
||||
result = f_mount(0, &g_FATFS_Obj);
|
||||
if (result != FR_OK)
|
||||
{
|
||||
g_logState = -result;
|
||||
// TODO beepAgain = result - 1;
|
||||
AUDIO_WARNING2();
|
||||
}
|
||||
else
|
||||
{
|
||||
// create new log file using filename set up in initLogs()
|
||||
result = f_open(&g_oLogFile, g_logFilename, FA_OPEN_ALWAYS | FA_WRITE);
|
||||
if (result != FR_OK)
|
||||
{
|
||||
g_logState = -result;
|
||||
// TODO beepAgain = result - 1; // TODO FOR DEBUG -- count out error_number beeps
|
||||
AUDIO_KEYPAD_UP();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_oLogFile.fsize == 0) {
|
||||
// if data type == Hub TODO
|
||||
f_puts("Buffer,RX,TX,A1,A2,Date,Time,Long,Lat,Course,Speed,Alt,BarAlt,"
|
||||
"Temp1,Temp2,RPM,Fuel,Volts,AccelX,AccelY,AccelZ,THR,RUD,ELE,IDL0,IDL1,IDL2,AIL,GEA,TRN\n",
|
||||
&g_oLogFile);
|
||||
}
|
||||
|
||||
f_lseek(&g_oLogFile, g_oLogFile.fsize); // append
|
||||
g_logState = 1;
|
||||
AUDIO_WARNING2();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_logState>0)
|
||||
{
|
||||
// For now, append 'anything' as a test
|
||||
// if data type == Hub
|
||||
#ifdef FRSKY
|
||||
f_printf(&g_oLogFile, "%d,", frskyStreaming);
|
||||
f_printf(&g_oLogFile, "%d,", frskyRSSI[0].value);
|
||||
f_printf(&g_oLogFile, "%d,", frskyRSSI[1].value);
|
||||
f_printf(&g_oLogFile, "%d,", frskyTelemetry[0].value);
|
||||
f_printf(&g_oLogFile, "%d,", frskyTelemetry[1].value);
|
||||
#endif
|
||||
#ifdef FRSKY_HUB
|
||||
f_printf(&g_oLogFile, "%4d-%02d-%02d,", frskyHubData.year+2000, frskyHubData.month, frskyHubData.day);
|
||||
f_printf(&g_oLogFile, "%02d:%02d:%02d,", frskyHubData.hour, frskyHubData.min, frskyHubData.sec);
|
||||
f_printf(&g_oLogFile, "%03d.%04d%c,", frskyHubData.gpsLongitude_bp, frskyHubData.gpsLongitude_ap,
|
||||
frskyHubData.gpsLongitudeEW ? frskyHubData.gpsLongitudeEW : '-');
|
||||
f_printf(&g_oLogFile, "%03d.%04d%c,", frskyHubData.gpsLatitude_bp, frskyHubData.gpsLatitude_ap,
|
||||
frskyHubData.gpsLatitudeNS ? frskyHubData.gpsLatitudeNS : '-');
|
||||
f_printf(&g_oLogFile, "%03d.%d,", frskyHubData.gpsCourse_bp, frskyHubData.gpsCourse_ap);
|
||||
f_printf(&g_oLogFile, "%d.%d,", frskyHubData.gpsSpeed_bp, frskyHubData.gpsSpeed_ap);
|
||||
f_printf(&g_oLogFile, "%03d.%d,", frskyHubData.gpsAltitude_bp, frskyHubData.gpsAltitude_ap);
|
||||
f_printf(&g_oLogFile, "%d.%d,", frskyHubData.baroAltitude_bp, frskyHubData.baroAltitude_ap);
|
||||
f_printf(&g_oLogFile, "%d,", frskyHubData.temperature1);
|
||||
f_printf(&g_oLogFile, "%d,", frskyHubData.temperature2);
|
||||
f_printf(&g_oLogFile, "%d,", frskyHubData.rpm);
|
||||
f_printf(&g_oLogFile, "%d,", frskyHubData.fuelLevel);
|
||||
f_printf(&g_oLogFile, "%d,", frskyHubData.volts);
|
||||
f_printf(&g_oLogFile, "%d,", frskyHubData.accelX);
|
||||
f_printf(&g_oLogFile, "%d,", frskyHubData.accelY);
|
||||
f_printf(&g_oLogFile, "%d,", frskyHubData.accelZ);
|
||||
#endif
|
||||
f_printf(&g_oLogFile, "%d,", keyState(SW_ThrCt));
|
||||
f_printf(&g_oLogFile, "%d,", keyState(SW_RuddDR));
|
||||
f_printf(&g_oLogFile, "%d,", keyState(SW_ElevDR));
|
||||
f_printf(&g_oLogFile, "%d,", keyState(SW_ID0));
|
||||
f_printf(&g_oLogFile, "%d,", keyState(SW_ID1));
|
||||
f_printf(&g_oLogFile, "%d,", keyState(SW_ID2));
|
||||
f_printf(&g_oLogFile, "%d,", keyState(SW_AileDR));
|
||||
f_printf(&g_oLogFile, "%d,", keyState(SW_Gear));
|
||||
f_printf(&g_oLogFile, "%d\n", keyState(SW_Trainer));
|
||||
|
||||
// Don't close the log file here. We have 'soft off' available on the v4.1 board. Once
|
||||
// that is implemented, it can take care of closing the file, should the radio be
|
||||
// powered off before the FUNC SWITCH is turned off.
|
||||
}
|
||||
}
|
||||
else if (g_logState > 0)
|
||||
{
|
||||
f_close(&g_oLogFile);
|
||||
AUDIO_WARNING2();
|
||||
g_logState = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,158 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Cam: I did think about implimenting this with an array for the timing durations
|
||||
like the original bit bang DSM2 code was done but that meant another array
|
||||
on top of the playlist one, therefore more memory waisted, and because
|
||||
the playlist must be executed one after another it would mean putting
|
||||
the code to fill the array in the interrupt (This would be unlike the
|
||||
old DSM2 code) which seemed to much for the interrupt.
|
||||
*/
|
||||
|
||||
#include "open9x.h"
|
||||
|
||||
// Start and stop bits need to be 2ms in duration. Start bit is low, stop bit is high
|
||||
#define SOMOSSBIT 4 //The 2ms of a stop/start bit
|
||||
#define SOMOSTOP 48 //This is the needed 2ms (4) + 20ms (40) to allow for the
|
||||
//point at which the busy flag is checkable + 2ms for saftey (4)
|
||||
#define SOMOSTART 60 //This is the needed 2ms (4) + 2ms (4) for safety + 26ms (52) for the
|
||||
//undocumented delay that must exist between playbacks.
|
||||
#define SOMOBUSY (PINH & 0x40) /* SOMO14D Busy flag */
|
||||
#define SOMOCLK (PINH & 0x10) /* SOMO14D CLK */
|
||||
|
||||
#define QUEUE_LENGTH 10
|
||||
uint16_t somo14playlist[QUEUE_LENGTH] = {0};
|
||||
uint16_t somo14command = 0;
|
||||
uint8_t somo14RIdx = 0;
|
||||
volatile uint8_t somo14WIdx = 0;
|
||||
|
||||
#ifdef SIMU
|
||||
#define BUSY busy
|
||||
bool TIMER4_COMPA_vect()
|
||||
#else
|
||||
#define BUSY
|
||||
ISR(TIMER4_COMPA_vect) //Every 0.5ms
|
||||
#endif
|
||||
{
|
||||
static uint16_t somo14_current;
|
||||
static uint8_t i=0;
|
||||
static uint8_t busy=0; // debugging make BOOL when done
|
||||
static uint8_t startstop=SOMOSSBIT; // Only the first playback can have this short delay
|
||||
|
||||
OCR4A = 0x7d; //another 0.5ms
|
||||
|
||||
// printf("startstop=%d i=%d\n", startstop, i); fflush(stdout);
|
||||
|
||||
// Send no data unless we are either not busy or it's a command
|
||||
|
||||
// Only when stop bit is sent do we increment read pointer
|
||||
// This will happen before the SOMO14D busy flag gets set
|
||||
// Busy flag happens 20ms after the last data is clocked in
|
||||
if (i==0 && !busy) {
|
||||
if(somo14command) { // Allow a command to be send even if the SOMO is busy, i.e. STOP or PAUSE
|
||||
somo14_current=somo14command;
|
||||
busy=1;
|
||||
}
|
||||
else if (!SOMOBUSY) {
|
||||
if (somo14RIdx == somo14WIdx) {
|
||||
TIMSK4 &= ~(1<<OCIE4A);
|
||||
return BUSY;
|
||||
}
|
||||
somo14_current = somo14playlist[somo14RIdx];
|
||||
somo14RIdx = (somo14RIdx + 1) % QUEUE_LENGTH;
|
||||
busy = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Start and stop bits
|
||||
if (busy && startstop) {
|
||||
// Start bit
|
||||
if (i==0) {
|
||||
if (startstop < SOMOSSBIT) { // This stretches the time before we start sending data to allow for the
|
||||
// undocumented delay that must exist between playbacks. Unfortunately the
|
||||
// device isn't ready even though the busy flag says it is.
|
||||
PORTH &= ~(1<<OUT_H_14DCLK); // Start Bit, CLK low for 2ms
|
||||
}
|
||||
startstop--;
|
||||
return BUSY;
|
||||
}
|
||||
// Stop bit
|
||||
if (i==16) {
|
||||
PORTH &= ~(1<<OUT_H_14DDATA); // Data low
|
||||
PORTH |= (1<<OUT_H_14DCLK); // Stop Bit, CLK high for 2ms
|
||||
startstop--;
|
||||
return BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
// After stop bit is sent
|
||||
// we are done sending so prepair for next
|
||||
if (i==16 && !startstop) {
|
||||
// Cam, here I think there is a bug (if we send a "command") somo14RPtr++;
|
||||
i=0;
|
||||
busy=0;
|
||||
startstop=SOMOSTART;
|
||||
return BUSY;
|
||||
}
|
||||
|
||||
// Send the data
|
||||
if (i<16 && busy) {
|
||||
if (!SOMOCLK) { // Only change data when the CLK is low
|
||||
startstop =SOMOSTOP;
|
||||
if (somo14_current & 0x8000) {
|
||||
PORTH |= (1<<OUT_H_14DDATA); // Data high
|
||||
}
|
||||
somo14_current = (somo14_current<<1);
|
||||
i++;
|
||||
// Strictly speaking there should be a data setup delay in here of 1us
|
||||
// Be we don't like no stinking delays !
|
||||
PORTH |= (1<<OUT_H_14DCLK); // CLK high
|
||||
}
|
||||
|
||||
else { // Don't alter after sending last bit in preparation for sending stop bit
|
||||
PORTH &= ~(1<<OUT_H_14DCLK); // CLK low
|
||||
PORTH &= ~(1<<OUT_H_14DDATA); // Data low
|
||||
}
|
||||
}
|
||||
|
||||
return BUSY;
|
||||
}
|
||||
|
||||
void somoPushPrompt(uint16_t prompt)
|
||||
{
|
||||
somo14playlist[somo14WIdx] = prompt;
|
||||
somo14WIdx = (somo14WIdx + 1) % QUEUE_LENGTH;
|
||||
TIMSK4 |= (1<<OCIE4A);
|
||||
}
|
||||
@@ -1,34 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
extern void somoPushPrompt(uint16_t prompt);
|
||||
-288
@@ -1,288 +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 <gtest/gtest.h>
|
||||
#include "open9x.h"
|
||||
|
||||
uint16_t anaIn(uint8_t chan)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST(trims, greaterTrimLink)
|
||||
{
|
||||
memset(&g_model, 0, sizeof(g_model));
|
||||
setTrimValue(1, 0, TRIM_EXTENDED_MAX+3); // link to FP3 trim
|
||||
setTrimValue(3, 0, 32);
|
||||
EXPECT_EQ(getRawTrimValue(getTrimFlightPhase(0, 1), 0), 32);
|
||||
}
|
||||
|
||||
TEST(trims, chainedTrims)
|
||||
{
|
||||
memset(&g_model, 0, sizeof(g_model));
|
||||
setTrimValue(0, 0, 32);
|
||||
setTrimValue(1, 0, TRIM_EXTENDED_MAX+1); // link to FP0 trim
|
||||
setTrimValue(2, 0, TRIM_EXTENDED_MAX+2); // link to FP1 trim
|
||||
EXPECT_EQ(getRawTrimValue(getTrimFlightPhase(0, 2), 0), 32);
|
||||
}
|
||||
|
||||
TEST(trims, infiniteChainedTrims)
|
||||
{
|
||||
memset(&g_model, 0, sizeof(g_model));
|
||||
setTrimValue(0, 0, 32);
|
||||
setTrimValue(1, 0, TRIM_EXTENDED_MAX+3); // link to FP3 trim
|
||||
setTrimValue(2, 0, TRIM_EXTENDED_MAX+2); // link to FP1 trim
|
||||
setTrimValue(3, 0, TRIM_EXTENDED_MAX+3); // link to FP2 trim
|
||||
EXPECT_EQ(getRawTrimValue(getTrimFlightPhase(0, 2), 0), 32);
|
||||
}
|
||||
|
||||
TEST(outdezNAtt, test_unsigned) {
|
||||
uint16_t altitude = 65530;
|
||||
|
||||
uint8_t refBuf[sizeof(displayBuf)];
|
||||
memset(displayBuf, 0, sizeof(displayBuf));
|
||||
lcd_putc(0*FWNUM, 0, '6');
|
||||
lcd_putc(1*FWNUM, 0, '5');
|
||||
lcd_putc(2*FWNUM, 0, '5');
|
||||
lcd_putc(3*FWNUM, 0, '3');
|
||||
lcd_putc(4*FWNUM, 0, '0');
|
||||
memcpy(refBuf, displayBuf, sizeof(displayBuf));
|
||||
|
||||
memset(displayBuf, 0, sizeof(displayBuf));
|
||||
lcd_outdezNAtt(1, 0, altitude, LEFT|UNSIGN);
|
||||
|
||||
EXPECT_EQ(memcmp(refBuf, displayBuf, sizeof(displayBuf)), 0) << "Unsigned numbers will be bad displayed";
|
||||
}
|
||||
|
||||
TEST(EEPROM, 1000_random_writes) {
|
||||
eepromFile = NULL; // in memory
|
||||
RlcFile f;
|
||||
uint8_t buf[1000];
|
||||
uint8_t buf2[1000];
|
||||
|
||||
EeFsFormat();
|
||||
|
||||
for(int i=0; i<1000; i++) {
|
||||
int size = rand()%800;
|
||||
for(int j=0; j<size; j++) {
|
||||
buf[j] = rand() < (RAND_MAX/10000*i) ? 0 : (j&0xff);
|
||||
}
|
||||
f.writeRlc(5, 5, buf, size, 100);
|
||||
// printf("size=%4d red=%4d\n\n\n", size, f.size());
|
||||
f.openRd(5);
|
||||
uint16_t n = f.readRlc(buf2,size+1);
|
||||
EXPECT_EQ(n, size);
|
||||
EXPECT_EQ(memcmp(buf, buf2, size), 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EEPROM, test2) {
|
||||
eepromFile = NULL; // in memory
|
||||
RlcFile f;
|
||||
uint8_t buf[1000];
|
||||
|
||||
EeFsFormat();
|
||||
|
||||
for(int i=0; i<1000; i++) buf[i]='6'+i%4;
|
||||
|
||||
f.writeRlc(6, 6, buf, 300, 100);
|
||||
|
||||
f.openRd(6);
|
||||
uint16_t sz=0;
|
||||
for(int i=0; i<500; i++){
|
||||
uint8_t b;
|
||||
uint16_t n=f.readRlc(&b,1);
|
||||
if(n) EXPECT_EQ(b, ('6'+sz%4));
|
||||
sz+=n;
|
||||
}
|
||||
EXPECT_EQ(sz, 300);
|
||||
}
|
||||
|
||||
TEST(EEPROM, eeCheckImmediately) {
|
||||
eepromFile = NULL; // in memory
|
||||
// RlcFile f;
|
||||
uint8_t buf[1000];
|
||||
|
||||
EeFsFormat();
|
||||
|
||||
for(int i=0; i<1000; i++) buf[i]='6'+i%4;
|
||||
|
||||
theFile.writeRlc(6, 6, buf, 300, false);
|
||||
|
||||
eeCheck(true);
|
||||
|
||||
theFile.openRd(6);
|
||||
uint16_t sz=0;
|
||||
for(int i=0; i<500; i++){
|
||||
uint8_t b;
|
||||
uint16_t n=theFile.readRlc(&b,1);
|
||||
if(n) EXPECT_EQ(b, ('6'+sz%4));
|
||||
sz+=n;
|
||||
}
|
||||
EXPECT_EQ(sz, 300);
|
||||
}
|
||||
|
||||
TEST(EEPROM, copy) {
|
||||
eepromFile = NULL; // in memory
|
||||
|
||||
uint8_t buf[1000];
|
||||
|
||||
EeFsFormat();
|
||||
|
||||
for(int i=0; i<1000; i++) buf[i]='6'+i%4;
|
||||
|
||||
theFile.writeRlc(5, 6, buf, 300, true);
|
||||
|
||||
theFile.copy(6, 5);
|
||||
|
||||
theFile.openRd(6);
|
||||
uint16_t sz=0;
|
||||
for(int i=0; i<500; i++){
|
||||
uint8_t b;
|
||||
uint16_t n=theFile.readRlc(&b,1);
|
||||
if(n) EXPECT_EQ(b, ('6'+sz%4));
|
||||
sz+=n;
|
||||
}
|
||||
EXPECT_EQ(sz, 300);
|
||||
}
|
||||
|
||||
TEST(EEPROM, rm) {
|
||||
eepromFile = NULL; // in memory
|
||||
|
||||
uint8_t buf[1000];
|
||||
|
||||
EeFsFormat();
|
||||
|
||||
for(int i=0; i<1000; i++) buf[i]='6'+i%4;
|
||||
|
||||
theFile.writeRlc(5, 6, buf, 300, true);
|
||||
|
||||
EXPECT_EQ(EFile::exists(5), true);
|
||||
|
||||
EFile::rm(5);
|
||||
|
||||
EXPECT_EQ(EFile::exists(5), false);
|
||||
|
||||
theFile.openRd(5);
|
||||
uint16_t sz=0;
|
||||
for(int i=0; i<500; i++){
|
||||
uint8_t b;
|
||||
uint16_t n=theFile.readRlc(&b,1);
|
||||
if(n) EXPECT_EQ(b, ('6'+sz%4));
|
||||
sz+=n;
|
||||
}
|
||||
EXPECT_EQ(sz, 0);
|
||||
}
|
||||
|
||||
extern void processFrskyPacket(uint8_t *packet);
|
||||
|
||||
TEST(FrSky, gpsNfuel) {
|
||||
g_model.frsky.usrProto = 1;
|
||||
frskyHubData.gpsFix = 1;
|
||||
|
||||
uint8_t pkt1[] = { 0xfd, 0x07, 0x00, 0x5e, 0x14, 0x2c, 0x00, 0x5e, 0x1c, 0x03 };
|
||||
uint8_t pkt2[] = { 0xfd, 0x07, 0x00, 0x00, 0x5e, 0x13, 0x38, 0x0c, 0x5e, 0x1b };
|
||||
uint8_t pkt3[] = { 0xfd, 0x07, 0x00, 0xc9, 0x06, 0x5e, 0x23, 0x4e, 0x00, 0x5e };
|
||||
uint8_t pkt4[] = { 0xfd, 0x07, 0x00, 0x12, 0xef, 0x2e, 0x5e, 0x1a, 0x98, 0x26 };
|
||||
uint8_t pkt5[] = { 0xfd, 0x07, 0x00, 0x5e, 0x22, 0x45, 0x00, 0x5e, 0x11, 0x02 };
|
||||
uint8_t pkt6[] = { 0xfd, 0x07, 0x00, 0x00, 0x5e, 0x19, 0x93, 0x00, 0x5e, 0x04 };
|
||||
uint8_t pkt7[] = { 0xfd, 0x03, 0x00, 0x64, 0x00, 0x5e };
|
||||
processFrskyPacket(pkt1);
|
||||
processFrskyPacket(pkt2);
|
||||
processFrskyPacket(pkt3);
|
||||
processFrskyPacket(pkt4);
|
||||
processFrskyPacket(pkt5);
|
||||
processFrskyPacket(pkt6);
|
||||
processFrskyPacket(pkt7);
|
||||
EXPECT_EQ(frskyHubData.gpsCourse_bp, 44);
|
||||
EXPECT_EQ(frskyHubData.gpsCourse_ap, 03);
|
||||
EXPECT_EQ(frskyHubData.gpsLongitude_bp / 100, 120);
|
||||
EXPECT_EQ(frskyHubData.gpsLongitude_bp % 100, 15);
|
||||
EXPECT_EQ(frskyHubData.gpsLongitude_ap, 0x2698);
|
||||
EXPECT_EQ(frskyHubData.gpsLatitudeNS, 'N');
|
||||
EXPECT_EQ(frskyHubData.gpsLongitudeEW, 'E');
|
||||
EXPECT_EQ(frskyHubData.fuelLevel, 100);
|
||||
}
|
||||
|
||||
TEST(FrSky, dateNtime) {
|
||||
uint8_t pkt1[] = { 0xfd, 0x07, 0x00, 0x5e, 0x15, 0x0f, 0x07, 0x5e, 0x16, 0x0b };
|
||||
uint8_t pkt2[] = { 0xfd, 0x07, 0x00, 0x00, 0x5e, 0x17, 0x06, 0x12, 0x5e, 0x18 };
|
||||
uint8_t pkt3[] = { 0xfd, 0x03, 0x00, 0x32, 0x00, 0x5e };
|
||||
processFrskyPacket(pkt1);
|
||||
processFrskyPacket(pkt2);
|
||||
processFrskyPacket(pkt3);
|
||||
EXPECT_EQ(frskyHubData.day, 15);
|
||||
EXPECT_EQ(frskyHubData.month, 07);
|
||||
EXPECT_EQ(frskyHubData.year, 11);
|
||||
EXPECT_EQ(frskyHubData.hour, 06);
|
||||
EXPECT_EQ(frskyHubData.min, 18);
|
||||
EXPECT_EQ(frskyHubData.sec, 50);
|
||||
}
|
||||
|
||||
TEST(getSwitch, undefCSW) {
|
||||
memset(&g_model, 0, sizeof(g_model));
|
||||
EXPECT_EQ(getSwitch(MAX_SWITCH-NUM_CSW, 0), false);
|
||||
EXPECT_EQ(getSwitch(-(MAX_SWITCH-NUM_CSW), 0), false);
|
||||
}
|
||||
|
||||
TEST(getSwitch, circularCSW) {
|
||||
memset(&g_model, 0, sizeof(g_model));
|
||||
g_model.customSw[0] = { MAX_SWITCH-NUM_CSW, MAX_SWITCH-NUM_CSW, CS_OR };
|
||||
g_model.customSw[1] = { MAX_SWITCH-NUM_CSW, MAX_SWITCH-NUM_CSW, CS_AND };
|
||||
EXPECT_EQ(getSwitch(MAX_SWITCH-NUM_CSW, 0), false);
|
||||
EXPECT_EQ(getSwitch(-(MAX_SWITCH-NUM_CSW), 0), true);
|
||||
EXPECT_EQ(getSwitch(1+MAX_SWITCH-NUM_CSW, 0), false);
|
||||
EXPECT_EQ(getSwitch(-(1+MAX_SWITCH-NUM_CSW), 0), true);
|
||||
}
|
||||
|
||||
TEST(getSwitch, nullSW) {
|
||||
memset(&g_model, 0, sizeof(g_model));
|
||||
EXPECT_EQ(getSwitch(0, 0), false);
|
||||
EXPECT_EQ(getSwitch(0, true), true);
|
||||
EXPECT_EQ(getSwitch(0, 0), false);
|
||||
}
|
||||
|
||||
TEST(phases, nullFadeOut_posFadeIn) {
|
||||
memset(&g_model, 0, sizeof(g_model));
|
||||
g_model.phaseData[1].swtch = DSW_ID1;
|
||||
g_model.phaseData[1].fadeIn = 15;
|
||||
perMain();
|
||||
setSwitch(DSW_ID1);
|
||||
perMain();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
StartEepromThread(NULL);
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@@ -1,218 +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"
|
||||
|
||||
uint16_t jeti_keys = JETI_KEY_NOCHANGE;
|
||||
uint8_t JetiBuffer[32]; // 32 characters
|
||||
uint8_t JetiBufferReady;
|
||||
|
||||
#ifndef SIMU
|
||||
ISR (USART0_RX_vect)
|
||||
{
|
||||
uint8_t stat;
|
||||
uint8_t rh;
|
||||
uint8_t rl;
|
||||
static uint8_t jbp;
|
||||
|
||||
stat = UCSR0A;
|
||||
rh = UCSR0B;
|
||||
rl = UDR0;
|
||||
|
||||
|
||||
if (stat & ((1 << FE0) | (1 << DOR0) | (1 << UPE0)))
|
||||
{ // discard buffer and start new on any error
|
||||
JetiBufferReady = 0;
|
||||
jbp = 0;
|
||||
}
|
||||
else if ((rh & (1 << RXB80)) == 0)
|
||||
{ // control
|
||||
if (rl == 0xfe)
|
||||
{ // start condition
|
||||
JetiBufferReady = 0;
|
||||
jbp = 0;
|
||||
}
|
||||
else if (rl == 0xff)
|
||||
{ // stop condition
|
||||
JetiBufferReady = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // data
|
||||
if (jbp < 32)
|
||||
{
|
||||
JetiBuffer[jbp++] = rl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void JETI_Init (void)
|
||||
{
|
||||
|
||||
jeti_keys = JETI_KEY_NOCHANGE;
|
||||
|
||||
DDRE &= ~(1 << DDE0); // set RXD0 pin as input
|
||||
PORTE &= ~(1 << PORTE0); // disable pullup on RXD0 pin
|
||||
|
||||
#ifndef SIMU
|
||||
|
||||
#undef BAUD
|
||||
#define BAUD 9600
|
||||
#include <util/setbaud.h>
|
||||
UBRR0H = UBRRH_VALUE;
|
||||
UBRR0L = UBRRL_VALUE;
|
||||
|
||||
UCSR0A &= ~(1 << U2X0); // disable double speed operation
|
||||
|
||||
// set 9O1
|
||||
UCSR0C = (1 << UPM01) | (1 << UPM00) | (1 << UCSZ01) | (1 << UCSZ00);
|
||||
UCSR0B = (1 << UCSZ02);
|
||||
|
||||
// flush receive buffer
|
||||
while ( UCSR0A & (1 << RXC0) ) UDR0;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void JETI_DisableTXD (void)
|
||||
{
|
||||
UCSR0B &= ~(1 << TXEN0); // disable TX
|
||||
}
|
||||
|
||||
|
||||
void JETI_EnableTXD (void)
|
||||
{
|
||||
UCSR0B |= (1 << TXEN0); // enable TX
|
||||
}
|
||||
|
||||
|
||||
void JETI_DisableRXD (void)
|
||||
{
|
||||
UCSR0B &= ~(1 << RXEN0); // disable RX
|
||||
UCSR0B &= ~(1 << RXCIE0); // disable Interrupt
|
||||
}
|
||||
|
||||
|
||||
void JETI_EnableRXD (void)
|
||||
{
|
||||
UCSR0B |= (1 << RXEN0); // enable RX
|
||||
UCSR0B |= (1 << RXCIE0); // enable Interrupt
|
||||
}
|
||||
|
||||
|
||||
void JETI_putw (uint16_t c)
|
||||
{
|
||||
loop_until_bit_is_set(UCSR0A, UDRE0);
|
||||
UCSR0B &= ~(1 << TXB80);
|
||||
if (c & 0x0100)
|
||||
{
|
||||
UCSR0B |= (1 << TXB80);
|
||||
}
|
||||
UDR0 = c;
|
||||
}
|
||||
|
||||
void JETI_putc (uint8_t c)
|
||||
{
|
||||
loop_until_bit_is_set(UCSR0A, UDRE0);
|
||||
// UCSRB &= ~(1 << TXB8);
|
||||
UCSR0B |= (1 << TXB80);
|
||||
UDR0 = c;
|
||||
}
|
||||
|
||||
void JETI_puts (char *s)
|
||||
{
|
||||
while (*s)
|
||||
{
|
||||
JETI_putc (*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
void JETI_put_start (void)
|
||||
{
|
||||
loop_until_bit_is_set(UCSR0A, UDRE0);
|
||||
UCSR0B &= ~(1 << TXB80);
|
||||
UDR0 = 0xFE;
|
||||
}
|
||||
|
||||
void JETI_put_stop (void)
|
||||
{
|
||||
loop_until_bit_is_set(UCSR0A, UDRE0);
|
||||
UCSR0B &= ~(1 << TXB80);
|
||||
UDR0 = 0xFF;
|
||||
}
|
||||
|
||||
#include "menus.h"
|
||||
|
||||
extern void menuMainView(uint8_t event);
|
||||
|
||||
void menuProcJeti(uint8_t event)
|
||||
{
|
||||
TITLE("JETI");
|
||||
|
||||
switch(event)
|
||||
{
|
||||
//case EVT_KEY_FIRST(KEY_MENU):
|
||||
// break;
|
||||
case EVT_KEY_FIRST(KEY_EXIT):
|
||||
JETI_DisableRXD();
|
||||
chainMenu(menuMainView);
|
||||
break;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 16; i++)
|
||||
{
|
||||
lcd_putcAtt((i+2)*FW, 3*FH, JetiBuffer[i], BSS);
|
||||
lcd_putcAtt((i+2)*FW, 4*FH, JetiBuffer[i+16], BSS);
|
||||
}
|
||||
|
||||
if (JetiBufferReady)
|
||||
{
|
||||
JETI_EnableTXD();
|
||||
if (keyState((EnumKeys)(KEY_UP))) jeti_keys &= JETI_KEY_UP;
|
||||
if (keyState((EnumKeys)(KEY_DOWN))) jeti_keys &= JETI_KEY_DOWN;
|
||||
if (keyState((EnumKeys)(KEY_LEFT))) jeti_keys &= JETI_KEY_LEFT;
|
||||
if (keyState((EnumKeys)(KEY_RIGHT))) jeti_keys &= JETI_KEY_RIGHT;
|
||||
|
||||
JetiBufferReady = 0; // invalidate buffer
|
||||
|
||||
JETI_putw((uint16_t) jeti_keys);
|
||||
_delay_ms (1);
|
||||
JETI_DisableTXD();
|
||||
|
||||
jeti_keys = JETI_KEY_NOCHANGE;
|
||||
}
|
||||
}
|
||||
@@ -1,945 +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"
|
||||
|
||||
#define font_5x8_x20_x7f (font)
|
||||
#define font_10x16_x20_x7f (font_dblsize)
|
||||
|
||||
uint8_t displayBuf[DISPLAY_W*DISPLAY_H/8];
|
||||
#define DISPLAY_END (displayBuf+sizeof(displayBuf))
|
||||
|
||||
#ifdef SIMU
|
||||
bool lcd_refresh = true;
|
||||
uint8_t lcd_buf[DISPLAY_W*DISPLAY_H/8];
|
||||
#endif
|
||||
|
||||
void lcd_clear()
|
||||
{
|
||||
memset(displayBuf, 0, sizeof(displayBuf));
|
||||
}
|
||||
|
||||
void lcd_img(uint8_t x, uint8_t y, const pm_uchar * img, uint8_t idx, uint8_t mode)
|
||||
{
|
||||
const pm_uchar *q = img;
|
||||
uint8_t w = pgm_read_byte(q++);
|
||||
uint8_t hb = (pgm_read_byte(q++)+7)/8;
|
||||
bool inv = (mode & INVERS) ? true : (mode & BLINK ? BLINK_ON_PHASE : false);
|
||||
q += idx*w*hb;
|
||||
for (uint8_t yb = 0; yb < hb; yb++) {
|
||||
uint8_t *p = &displayBuf[ (y / 8 + yb) * DISPLAY_W + x ];
|
||||
for (uint8_t i=0; i<w; i++){
|
||||
uint8_t b = pgm_read_byte(q++);
|
||||
*p++ = inv ? ~b : b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t lcd_lastPos;
|
||||
|
||||
void lcd_putcAtt(uint8_t x, uint8_t y, const unsigned char c, uint8_t mode)
|
||||
{
|
||||
uint8_t *p = &displayBuf[ y / 8 * DISPLAY_W + x ];
|
||||
|
||||
const pm_uchar *q = &font_5x8_x20_x7f[ (c-0x20)*5];
|
||||
|
||||
bool inv = false;
|
||||
if (mode & BLINK) {
|
||||
if (BLINK_ON_PHASE) {
|
||||
if (mode & INVERS)
|
||||
inv = true;
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (mode & INVERS) {
|
||||
inv = true;
|
||||
}
|
||||
|
||||
if(mode & DBLSIZE)
|
||||
{
|
||||
/* each letter consists of ten top bytes followed by
|
||||
* by ten bottom bytes (20 bytes per * char) */
|
||||
q = &font_10x16_x20_x7f[((uint16_t)c-0x20)*20];
|
||||
for (int8_t i=11; i>=0; i--) {
|
||||
if (mode & CONDENSED && i<=1) break;
|
||||
uint8_t b1=0, b2=0;
|
||||
if (i>1) {
|
||||
b1 = pgm_read_byte(q++); /*top byte*/
|
||||
b2 = pgm_read_byte(q++); /*top byte*/
|
||||
}
|
||||
if(inv) {
|
||||
b1=~b1;
|
||||
b2=~b2;
|
||||
}
|
||||
if(&p[DISPLAY_W+1] < DISPLAY_END) {
|
||||
p[0]=b1;
|
||||
p[DISPLAY_W] = b2;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
uint8_t condense=0;
|
||||
|
||||
if (mode & CONDENSED) {
|
||||
*p++ = inv ? ~0 : 0;
|
||||
condense=1;
|
||||
}
|
||||
|
||||
uint8_t ym8 = (y % 8);
|
||||
for (int8_t i=5; i>=0; i--) {
|
||||
uint8_t b = (i>0 ? pgm_read_byte(q++) : 0);
|
||||
if (inv) b = ~b;
|
||||
|
||||
if (condense && i==4) {
|
||||
/*condense the letter by skipping column 4 */
|
||||
continue;
|
||||
}
|
||||
if (p<DISPLAY_END) {
|
||||
*p = (*p & (~(0xff << ym8))) + (b << ym8);
|
||||
if (ym8) { uint8_t *r = p + DISPLAY_W; if (r<DISPLAY_END) *r = (*r & (~(0xff >> (8-ym8)))) + (b >> (8-ym8)); }
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_putc(uint8_t x, uint8_t y, const unsigned char c)
|
||||
{
|
||||
lcd_putcAtt(x,y,c,0);
|
||||
}
|
||||
|
||||
void lcd_putsiAtt(uint8_t x,uint8_t y,const pm_char * s,uint8_t idx, uint8_t flags)
|
||||
{
|
||||
uint8_t length;
|
||||
length = pgm_read_byte(s++) ;
|
||||
lcd_putsnAtt(x,y,s+length*idx,length,flags);
|
||||
}
|
||||
|
||||
void lcd_putsnAtt(uint8_t x,uint8_t y,const pm_char * s,uint8_t len,uint8_t mode)
|
||||
{
|
||||
while(len!=0) {
|
||||
unsigned char c;
|
||||
switch (mode & (BSS+ZCHAR)) {
|
||||
case BSS:
|
||||
c = *s;
|
||||
break;
|
||||
case ZCHAR:
|
||||
c = idx2char(*s);
|
||||
break;
|
||||
default:
|
||||
c = pgm_read_byte(s);
|
||||
break;
|
||||
}
|
||||
if (!c || x>DISPLAY_W-6) break;
|
||||
if (c >= 0x20) {
|
||||
lcd_putcAtt(x,y,c,mode);
|
||||
x += FW;
|
||||
if (mode&DBLSIZE) x += FW-1;
|
||||
}
|
||||
else {
|
||||
x += (c*FW);
|
||||
}
|
||||
s++;
|
||||
len--;
|
||||
}
|
||||
lcd_lastPos = x;
|
||||
}
|
||||
|
||||
void lcd_putsn(uint8_t x,uint8_t y,const pm_char * s,uint8_t len)
|
||||
{
|
||||
lcd_putsnAtt(x, y, s, len, 0);
|
||||
}
|
||||
|
||||
void lcd_putsAtt(uint8_t x,uint8_t y,const pm_char * s,uint8_t mode)
|
||||
{
|
||||
lcd_putsnAtt(x, y, s, 255, mode);
|
||||
}
|
||||
|
||||
void lcd_puts(uint8_t x,uint8_t y,const pm_char * s)
|
||||
{
|
||||
lcd_putsAtt( x, y, s, 0);
|
||||
}
|
||||
|
||||
void lcd_putsLeft(uint8_t y, const pm_char * s)
|
||||
{
|
||||
lcd_putsAtt(0, y, s, 0);
|
||||
}
|
||||
|
||||
void lcd_outhex4(uint8_t x,uint8_t y,uint16_t val)
|
||||
{
|
||||
x+=FWNUM*4;
|
||||
for(int i=0; i<4; i++)
|
||||
{
|
||||
x-=FWNUM;
|
||||
char c = val & 0xf;
|
||||
c = c>9 ? c+'A'-10 : c+'0';
|
||||
lcd_putcAtt(x,y,c,c>='A'?CONDENSED:0);
|
||||
val>>=4;
|
||||
}
|
||||
}
|
||||
void lcd_outdez8(uint8_t x, uint8_t y, int8_t val)
|
||||
{
|
||||
lcd_outdezAtt(x, y, val);
|
||||
}
|
||||
|
||||
void lcd_outdezAtt(uint8_t x, uint8_t y, int16_t val, uint8_t flags)
|
||||
{
|
||||
lcd_outdezNAtt(x, y, val, flags);
|
||||
}
|
||||
|
||||
// TODO use doxygen style comments here
|
||||
|
||||
/*
|
||||
USAGE:
|
||||
lcd_outdezNAtt(x-coord, y-coord, (un)signed-value{0..65535|0..+/-32768},
|
||||
mode_flags, length)
|
||||
|
||||
Available mode_flas: PREC{1..3}, UNSIGN (for programmer selected signed numbers
|
||||
to allow for unsigned values up to the ful 65535 16-bit limt))
|
||||
|
||||
LEADING0 means pad 0 to the left of sig. digits up to 'len' total characters
|
||||
*/
|
||||
|
||||
void lcd_outdezNAtt(uint8_t x, uint8_t y, int16_t val, uint8_t flags, uint8_t len)
|
||||
{
|
||||
uint8_t fw = FWNUM;
|
||||
int8_t mode = MODE(flags);
|
||||
bool dblsize = flags & DBLSIZE;
|
||||
|
||||
bool neg = false;
|
||||
if (flags & UNSIGN) { flags -= UNSIGN; }
|
||||
else if (val < 0) { neg=true; val=-val; }
|
||||
|
||||
uint8_t xn = 0;
|
||||
uint8_t ln = 2;
|
||||
|
||||
if (mode != MODE(LEADING0)) {
|
||||
len = 1;
|
||||
uint16_t tmp = ((uint16_t)val) / 10;
|
||||
while (tmp) {
|
||||
len++;
|
||||
tmp /= 10;
|
||||
}
|
||||
if (len <= mode)
|
||||
len = mode + 1;
|
||||
}
|
||||
|
||||
if (dblsize) {
|
||||
fw += FWNUM;
|
||||
}
|
||||
else {
|
||||
if (flags & LEFT) {
|
||||
if (mode > 0)
|
||||
x += 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & LEFT) {
|
||||
x += len * fw;
|
||||
if (neg)
|
||||
x += (dblsize ? 7 : FWNUM);
|
||||
}
|
||||
|
||||
lcd_lastPos = x;
|
||||
x -= fw + 1;
|
||||
|
||||
for (uint8_t i=1; i<=len; i++) {
|
||||
char c = ((uint16_t)val % 10) + '0';
|
||||
uint8_t f = flags;
|
||||
if (dblsize) {
|
||||
if (c=='1' && i==len && xn>x+10) { x+=2; f|=CONDENSED; }
|
||||
if (val >= 1000) { x+=FWNUM; f&=~DBLSIZE; }
|
||||
}
|
||||
lcd_putcAtt(x, y, c, f);
|
||||
if (mode==i) {
|
||||
flags &= ~PREC2; // TODO not needed but removes 64bytes, could be improved for sure, check asm
|
||||
if (dblsize) {
|
||||
xn = x;
|
||||
if(c>='1' && c<='3') ln++;
|
||||
uint8_t tn = ((uint16_t)val/10) % 10;
|
||||
if (tn==2 || tn==4) {
|
||||
if (c=='4') { xn++; }
|
||||
else { xn--; ln++; }
|
||||
}
|
||||
}
|
||||
else {
|
||||
x--;
|
||||
lcd_plot(x, y+6);
|
||||
if ((flags&INVERS) && ((~flags & BLINK) || BLINK_ON_PHASE))
|
||||
lcd_vline(x, y, 8);
|
||||
x--;
|
||||
}
|
||||
}
|
||||
if (dblsize && val >= 1000 && val < 10000) x-=2;
|
||||
val = ((uint16_t)val) / 10;
|
||||
x-=fw;
|
||||
}
|
||||
|
||||
if (xn) {
|
||||
y &= ~0x07;
|
||||
lcd_hline(xn, (y & ~0x07)+2*FH-3, ln);
|
||||
lcd_hline(xn, y+2*FH-2, ln);
|
||||
}
|
||||
|
||||
if (neg) lcd_putcAtt(x, y, '-', flags);
|
||||
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
if (flags & SURROUNDED) {
|
||||
xn = lcd_lastPos - x + 2;
|
||||
if (!neg) { x+=FW; xn-=FW; }
|
||||
lcd_rect(x-1, y-1, xn, 9, BLINK_ON_PHASE ? DOTTED : ~DOTTED);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void lcd_mask(uint8_t *p, uint8_t mask, uint8_t att)
|
||||
{
|
||||
assert(p >= displayBuf && p < DISPLAY_END);
|
||||
|
||||
if (att & BLACK)
|
||||
*p |= mask;
|
||||
else if (att & WHITE)
|
||||
*p &= ~mask;
|
||||
else
|
||||
*p ^= mask;
|
||||
}
|
||||
|
||||
void lcd_plot(uint8_t x,uint8_t y, uint8_t att)
|
||||
{
|
||||
uint8_t *p = &displayBuf[ y / 8 * DISPLAY_W + x ];
|
||||
if (p<DISPLAY_END)
|
||||
lcd_mask(p, BITMASK(y%8), att);
|
||||
}
|
||||
|
||||
void lcd_hlineStip(int8_t x, uint8_t y, uint8_t w, uint8_t pat, uint8_t att)
|
||||
{
|
||||
if (y >= DISPLAY_H) return;
|
||||
if (x<0) { w+=x; x=0; }
|
||||
if (x+w > DISPLAY_W) { w = DISPLAY_W - x; }
|
||||
|
||||
uint8_t *p = &displayBuf[ y / 8 * DISPLAY_W + x ];
|
||||
uint8_t msk = BITMASK(y%8);
|
||||
while(w) {
|
||||
if(pat&1) {
|
||||
lcd_mask(p, msk, att);
|
||||
pat = (pat >> 1) | 0x80;
|
||||
}
|
||||
else {
|
||||
pat = pat >> 1;
|
||||
}
|
||||
w--;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_hline(uint8_t x, uint8_t y, uint8_t w, uint8_t att)
|
||||
{
|
||||
lcd_hlineStip(x, y, w, 0xff, att);
|
||||
}
|
||||
|
||||
void lcd_vlineStip(uint8_t x, int8_t y, int8_t h, uint8_t pat)
|
||||
{
|
||||
if (x >= DISPLAY_W) return;
|
||||
if (h<0) { y+=h; h=-h; }
|
||||
if (y<0) { h+=y; y=0; }
|
||||
if (y+h > DISPLAY_H) { h = DISPLAY_H - y; }
|
||||
|
||||
if (pat==DOTTED && !(y%2))
|
||||
pat = ~pat;
|
||||
|
||||
uint8_t *p = &displayBuf[ y / 8 * DISPLAY_W + x ];
|
||||
y = y % 8;
|
||||
if (y) {
|
||||
assert(p >= displayBuf && p < DISPLAY_END);
|
||||
*p ^= ~(BITMASK(y)-1) & pat;
|
||||
p += DISPLAY_W;
|
||||
h -= 8-y;
|
||||
}
|
||||
while (h>0) {
|
||||
assert(p >= displayBuf && p < DISPLAY_END);
|
||||
*p ^= pat;
|
||||
p += DISPLAY_W;
|
||||
h -= 8;
|
||||
}
|
||||
if (h < 0) h += 8;
|
||||
if (h) {
|
||||
p -= DISPLAY_W;
|
||||
assert(p >= displayBuf && p < DISPLAY_END);
|
||||
*p ^= ~(BITMASK(h)-1) & pat;
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_vline(uint8_t x, int8_t y, int8_t h)
|
||||
{
|
||||
lcd_vlineStip(x, y, h, 0xff);
|
||||
}
|
||||
|
||||
void lcd_rect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t pat, uint8_t att)
|
||||
{
|
||||
if (!((att & BLINK) && BLINK_ON_PHASE)) {
|
||||
lcd_vlineStip(x, y, h, pat);
|
||||
lcd_vlineStip(x+w-1, y, h, pat);
|
||||
if (~att & ROUND) { x+=1; w-=2; }
|
||||
lcd_hlineStip(x, y+h-1, w, pat);
|
||||
lcd_hlineStip(x, y, w, pat);
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_filled_rect(uint8_t x, int8_t y, uint8_t w, uint8_t h, uint8_t pat, uint8_t att)
|
||||
{
|
||||
for (int8_t i=y; i<y+h; i++) {
|
||||
if (i>=0 && i<64) lcd_hlineStip(x, i, w, pat, att);
|
||||
if (pat != 0xff) pat = ~pat;
|
||||
}
|
||||
}
|
||||
|
||||
void putsTime(uint8_t x,uint8_t y,int16_t tme,uint8_t att,uint8_t att2)
|
||||
{
|
||||
if (att & LEFT) x+=3*FW;
|
||||
|
||||
if (tme<0) {
|
||||
lcd_putcAtt(x - ((att & DBLSIZE) ? FW+1 : FWNUM), y, '-', att);
|
||||
tme = -tme;
|
||||
}
|
||||
|
||||
lcd_outdezNAtt(x, y, tme/60, att|LEADING0|LEFT, 2);
|
||||
lcd_putcAtt(lcd_lastPos-((att & DBLSIZE) ? 1 : 0), y, ':', att&att2);
|
||||
lcd_outdezNAtt(lcd_lastPos+FW, y, tme%60, att2|LEADING0|LEFT, 2);
|
||||
}
|
||||
|
||||
// TODO to be optimized with putsTelemetryValue
|
||||
void putsVolts(uint8_t x, uint8_t y, uint16_t volts, uint8_t att)
|
||||
{
|
||||
lcd_outdezAtt(x, y, (int16_t)volts, (~NO_UNIT) & (att | ((att&PREC2)==PREC2 ? 0 : PREC1)));
|
||||
if (~att & NO_UNIT) lcd_putcAtt(lcd_lastPos, y, 'v', att&(~INVERS));
|
||||
}
|
||||
|
||||
void putsVBat(uint8_t x, uint8_t y, uint8_t att)
|
||||
{
|
||||
putsVolts(x, y, g_vbat100mV, att);
|
||||
}
|
||||
|
||||
void putsStrIdx(uint8_t x, uint8_t y, const pm_char *str, uint8_t idx, uint8_t att)
|
||||
{
|
||||
lcd_putsAtt(x, y, str, att & ~BSS); // TODO use something else than BSS for LEADING0
|
||||
lcd_outdezNAtt(lcd_lastPos, y, idx, att|LEFT, 2);
|
||||
if (att&TWO_DOTS) lcd_putc(lcd_lastPos, y, ':');
|
||||
}
|
||||
|
||||
void putsChnRaw(uint8_t x, uint8_t y, uint8_t idx, uint8_t att)
|
||||
{
|
||||
if (idx==0)
|
||||
lcd_putsiAtt(x, y, STR_MMMINV, 0, att);
|
||||
else if (idx<=NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS+NUM_STICKS+2+NUM_CYC)
|
||||
lcd_putsiAtt(x, y, STR_VSRCRAW, idx-1, att);
|
||||
else if (idx<=NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS+NUM_STICKS+2+NUM_CYC+NUM_PPM)
|
||||
putsStrIdx(x, y, STR_PPM, idx - (NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS+NUM_STICKS+2+NUM_CYC), att);
|
||||
else if (idx<=NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS+NUM_STICKS+2+NUM_CYC+NUM_PPM+NUM_CHNOUT)
|
||||
putsStrIdx(x, y, STR_CH, idx - (NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS+NUM_STICKS+2+NUM_CYC+NUM_PPM), att);
|
||||
else
|
||||
lcd_putsiAtt(x, y, STR_VTELEMCHNS, idx-(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS+NUM_STICKS+2+NUM_CYC+NUM_PPM+NUM_CHNOUT), att);
|
||||
}
|
||||
|
||||
void putsChn(uint8_t x, uint8_t y, uint8_t idx, uint8_t att)
|
||||
{
|
||||
if (idx > 0 && idx <= NUM_CHNOUT)
|
||||
putsChnRaw(x, y, idx+(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS+NUM_STICKS+2+NUM_CYC+NUM_PPM), att);
|
||||
}
|
||||
|
||||
void putsMixerSource(uint8_t x, uint8_t y, uint8_t idx, uint8_t att)
|
||||
{
|
||||
if (idx<=NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS+NUM_STICKS+2)
|
||||
putsChnRaw(x, y, idx, att);
|
||||
else if (idx<=NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS+NUM_STICKS+2+MAX_SWITCH)
|
||||
putsSwitches(x, y, idx-NUM_STICKS-NUM_POTS-NUM_ROTARY_ENCODERS-NUM_STICKS-2, att);
|
||||
else
|
||||
putsChnRaw(x, y, idx-MAX_SWITCH, att);
|
||||
}
|
||||
|
||||
void putsChnLetter(uint8_t x, uint8_t y, uint8_t idx, uint8_t attr)
|
||||
{
|
||||
lcd_putsiAtt(x, y, STR_RETA123, idx-1, attr);
|
||||
}
|
||||
|
||||
void putsModelName(uint8_t x, uint8_t y, char *name, uint8_t id, uint8_t att)
|
||||
{
|
||||
uint8_t len = sizeof(g_model.name);
|
||||
while (len>0 && !name[len-1]) --len;
|
||||
if (len==0) {
|
||||
putsStrIdx(x, y, STR_MODEL, id+1, att|LEADING0);
|
||||
}
|
||||
else {
|
||||
lcd_putsnAtt(x, y, name, sizeof(g_model.name), ZCHAR|att);
|
||||
}
|
||||
}
|
||||
|
||||
void putsSwitches(uint8_t x, uint8_t y, int8_t idx, uint8_t att)
|
||||
{
|
||||
if (idx == 0)
|
||||
return lcd_putsiAtt(x, y, STR_MMMINV, 0, att);
|
||||
if (~att & SWONLY) {
|
||||
if (idx == SWITCH_ON)
|
||||
return lcd_putsiAtt(x, y, STR_OFFON, 1, att);
|
||||
if (idx == SWITCH_OFF)
|
||||
return lcd_putsiAtt(x, y, STR_OFFON, 0, att);
|
||||
}
|
||||
if (idx<0) {
|
||||
lcd_vlineStip(x-2, y, 8, 0x5E/*'!'*/);
|
||||
idx = -idx;
|
||||
}
|
||||
if (idx > MAX_SWITCH) {
|
||||
idx -= ((att & SWONLY) ? MAX_SWITCH : MAX_SWITCH+1);
|
||||
if (~att & SWCONDENSED) lcd_putcAtt(x+3*FW, y, 'm', att);
|
||||
}
|
||||
lcd_putsiAtt(x, y, STR_VSWITCHES, idx-1, att);
|
||||
}
|
||||
|
||||
#ifdef FLIGHT_PHASES
|
||||
void putsFlightPhase(uint8_t x, uint8_t y, int8_t idx, uint8_t att)
|
||||
{
|
||||
if (idx==0) { lcd_putsiAtt(x, y, STR_MMMINV, 0, att); return; }
|
||||
if (idx < 0) { lcd_vlineStip(x-2, y, 8, 0x5E/*'!'*/); idx = -idx; }
|
||||
if (att & CONDENSED)
|
||||
lcd_outdezNAtt(x+FW*1, y, idx-1, (att & ~CONDENSED), 1);
|
||||
else
|
||||
putsStrIdx(x, y, STR_FP, idx-1, att);
|
||||
}
|
||||
#endif
|
||||
|
||||
void putsCurve(uint8_t x, uint8_t y, int8_t idx, uint8_t att)
|
||||
{
|
||||
if (idx < 0) {
|
||||
lcd_putcAtt(x-1*FW, y, '!', att);
|
||||
idx = -idx + 6;
|
||||
}
|
||||
if (idx < CURVE_BASE)
|
||||
lcd_putsiAtt(x, y, STR_VCURVEFUNC, idx, att);
|
||||
else
|
||||
putsStrIdx(x, y, PSTR("c"), idx-CURVE_BASE+1, att);
|
||||
}
|
||||
|
||||
void putsTmrMode(uint8_t x, uint8_t y, int8_t mode, uint8_t att)
|
||||
{
|
||||
if (mode < 0) {
|
||||
mode = TMR_VAROFS - mode - 1;
|
||||
lcd_putcAtt(x-1*FW, y, '!', att);
|
||||
}
|
||||
else if (mode < TMR_VAROFS) {
|
||||
lcd_putsiAtt(x, y, STR_VTMRMODES, mode, att);
|
||||
return;
|
||||
}
|
||||
|
||||
putsSwitches(x, y, mode-(TMR_VAROFS-1), att|SWONLY);
|
||||
}
|
||||
|
||||
void putsTrimMode(uint8_t x, uint8_t y, uint8_t phase, uint8_t idx, uint8_t att)
|
||||
{
|
||||
int16_t v = getRawTrimValue(phase, idx);
|
||||
|
||||
if (v > TRIM_EXTENDED_MAX) {
|
||||
uint8_t p = v - TRIM_EXTENDED_MAX - 1;
|
||||
if (p >= phase) p++;
|
||||
lcd_putcAtt(x, y, '0'+p, att);
|
||||
}
|
||||
else {
|
||||
putsChnLetter(x, y, idx+1, att);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(PCBV4)
|
||||
void putsRotaryEncoderMode(uint8_t x, uint8_t y, uint8_t phase, uint8_t idx, uint8_t att)
|
||||
{
|
||||
int16_t v = phaseaddress(phase)->rotaryEncoders[idx];
|
||||
|
||||
if (v > ROTARY_ENCODER_MAX) {
|
||||
uint8_t p = v - ROTARY_ENCODER_MAX - 1;
|
||||
if (p >= phase) p++;
|
||||
lcd_putcAtt(x, y, '0'+p, att);
|
||||
}
|
||||
else {
|
||||
lcd_putcAtt(x, y, 'a'+idx, att);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PCBARM
|
||||
|
||||
// LCD i/o pins
|
||||
// LCD_RES PC27
|
||||
// LCD_CS1 PC26
|
||||
// LCD_E PC12
|
||||
// LCD_RnW PC13
|
||||
// LCD_A0 PC15
|
||||
// LCD_D0 PC0
|
||||
// LCD_D1 PC7
|
||||
// LCD_D2 PC6
|
||||
// LCD_D3 PC5
|
||||
// LCD_D4 PC4
|
||||
// LCD_D5 PC3
|
||||
// LCD_D6 PC2
|
||||
// LCD_D7 PC1
|
||||
|
||||
#define LCD_DATA 0x000000FFL
|
||||
#ifdef REVB
|
||||
#define LCD_A0 0x00000080L
|
||||
#else
|
||||
#define LCD_A0 0x00008000L
|
||||
#endif
|
||||
#define LCD_RnW 0x00002000L
|
||||
#define LCD_E 0x00001000L
|
||||
#define LCD_CS1 0x04000000L
|
||||
#define LCD_RES 0x08000000L
|
||||
|
||||
// Lookup table for prototype board
|
||||
#ifndef REVB
|
||||
const uint8_t Lcd_lookup[] =
|
||||
{
|
||||
0x00,0x01,0x80,0x81,0x40,0x41,0xC0,0xC1,0x20,0x21,0xA0,0xA1,0x60,0x61,0xE0,0xE1,
|
||||
0x10,0x11,0x90,0x91,0x50,0x51,0xD0,0xD1,0x30,0x31,0xB0,0xB1,0x70,0x71,0xF0,0xF1,
|
||||
0x08,0x09,0x88,0x89,0x48,0x49,0xC8,0xC9,0x28,0x29,0xA8,0xA9,0x68,0x69,0xE8,0xE9,
|
||||
0x18,0x19,0x98,0x99,0x58,0x59,0xD8,0xD9,0x38,0x39,0xB8,0xB9,0x78,0x79,0xF8,0xF9,
|
||||
0x04,0x05,0x84,0x85,0x44,0x45,0xC4,0xC5,0x24,0x25,0xA4,0xA5,0x64,0x65,0xE4,0xE5,
|
||||
0x14,0x15,0x94,0x95,0x54,0x55,0xD4,0xD5,0x34,0x35,0xB4,0xB5,0x74,0x75,0xF4,0xF5,
|
||||
0x0C,0x0D,0x8C,0x8D,0x4C,0x4D,0xCC,0xCD,0x2C,0x2D,0xAC,0xAD,0x6C,0x6D,0xEC,0xED,
|
||||
0x1C,0x1D,0x9C,0x9D,0x5C,0x5D,0xDC,0xDD,0x3C,0x3D,0xBC,0xBD,0x7C,0x7D,0xFC,0xFD,
|
||||
0x02,0x03,0x82,0x83,0x42,0x43,0xC2,0xC3,0x22,0x23,0xA2,0xA3,0x62,0x63,0xE2,0xE3,
|
||||
0x12,0x13,0x92,0x93,0x52,0x53,0xD2,0xD3,0x32,0x33,0xB2,0xB3,0x72,0x73,0xF2,0xF3,
|
||||
0x0A,0x0B,0x8A,0x8B,0x4A,0x4B,0xCA,0xCB,0x2A,0x2B,0xAA,0xAB,0x6A,0x6B,0xEA,0xEB,
|
||||
0x1A,0x1B,0x9A,0x9B,0x5A,0x5B,0xDA,0xDB,0x3A,0x3B,0xBA,0xBB,0x7A,0x7B,0xFA,0xFB,
|
||||
0x06,0x07,0x86,0x87,0x46,0x47,0xC6,0xC7,0x26,0x27,0xA6,0xA7,0x66,0x67,0xE6,0xE7,
|
||||
0x16,0x17,0x96,0x97,0x56,0x57,0xD6,0xD7,0x36,0x37,0xB6,0xB7,0x76,0x77,0xF6,0xF7,
|
||||
0x0E,0x0F,0x8E,0x8F,0x4E,0x4F,0xCE,0xCF,0x2E,0x2F,0xAE,0xAF,0x6E,0x6F,0xEE,0xEF,
|
||||
0x1E,0x1F,0x9E,0x9F,0x5E,0x5F,0xDE,0xDF,0x3E,0x3F,0xBE,0xBF,0x7E,0x7F,0xFE,0xFF
|
||||
} ;
|
||||
#endif
|
||||
|
||||
void lcdSendCtl(uint8_t val)
|
||||
{
|
||||
register Pio *pioptr ;
|
||||
// register uint32_t x ;
|
||||
|
||||
#ifdef REVB
|
||||
pioptr = PIOC ;
|
||||
pioptr->PIO_CODR = LCD_CS1 ; // Select LCD
|
||||
PIOA->PIO_CODR = LCD_A0 ;
|
||||
pioptr->PIO_CODR = LCD_RnW ; // Write
|
||||
pioptr->PIO_ODSR = val ;
|
||||
#else
|
||||
pioptr = PIOC ;
|
||||
pioptr->PIO_CODR = LCD_CS1 ; // Select LCD
|
||||
pioptr->PIO_CODR = LCD_A0 ; // Control
|
||||
pioptr->PIO_CODR = LCD_RnW ; // Write
|
||||
pioptr->PIO_ODSR = Lcd_lookup[val] ;
|
||||
#endif
|
||||
|
||||
pioptr->PIO_SODR = LCD_E ; // Start E pulse
|
||||
// Need a delay here (250nS)
|
||||
TC0->TC_CHANNEL[0].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger)
|
||||
while ( TC0->TC_CHANNEL[0].TC_CV < 3 ) // Value depends on MCK/2 (used 6MHz)
|
||||
{
|
||||
// Wait
|
||||
}
|
||||
pioptr->PIO_CODR = LCD_E ; // End E pulse
|
||||
#ifdef REVB
|
||||
PIOA->PIO_SODR = LCD_A0 ; // Data
|
||||
#else
|
||||
pioptr->PIO_SODR = LCD_A0 ; // Data
|
||||
#endif
|
||||
pioptr->PIO_SODR = LCD_CS1 ; // Deselect LCD
|
||||
}
|
||||
|
||||
void lcd_init()
|
||||
{
|
||||
register Pio *pioptr ;
|
||||
// /home/thus/txt/datasheets/lcd/KS0713.pdf
|
||||
// ~/txt/flieger/ST7565RV17.pdf from http://www.glyn.de/content.asp?wdid=132&sid=
|
||||
|
||||
#ifdef REVB
|
||||
configure_pins( LCD_A0, PIN_ENABLE | PIN_LOW | PIN_OUTPUT | PIN_PORTA | PIN_NO_PULLUP ) ;
|
||||
pioptr = PIOC ;
|
||||
pioptr->PIO_PER = 0x0C0030FFL ; // Enable bits 27,26,13,12,7-0
|
||||
pioptr->PIO_CODR = LCD_E | LCD_RnW ;
|
||||
pioptr->PIO_SODR = LCD_RES | LCD_CS1 ;
|
||||
pioptr->PIO_OER = 0x0C0030FFL ; // Set bits 27,26,13,12,7-0 output
|
||||
pioptr->PIO_OWER = 0x000000FFL ; // Allow write to ls 8 bits in ODSR
|
||||
#else
|
||||
pioptr = PIOC ;
|
||||
pioptr->PIO_PER = 0x0C00B0FFL ; // Enable bits 27,26,15,13,12,7-0
|
||||
pioptr->PIO_CODR = LCD_E | LCD_RnW | LCD_A0 ;
|
||||
pioptr->PIO_SODR = LCD_RES | LCD_CS1 ;
|
||||
pioptr->PIO_OER = 0x0C00B0FFL ; // Set bits 27,26,15,13,12,7-0 output
|
||||
pioptr->PIO_OWER = 0x000000FFL ; // Allow write to ls 8 bits in ODSR
|
||||
#endif
|
||||
|
||||
pioptr->PIO_CODR = LCD_RES ; // Reset LCD
|
||||
TC0->TC_CHANNEL[0].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger)
|
||||
while ( TC0->TC_CHANNEL[0].TC_CV < 12 ) // 2 uS, Value depends on MCK/2 (used 6MHz)
|
||||
{
|
||||
// Wait
|
||||
}
|
||||
pioptr->PIO_SODR = LCD_RES ; // Remove LCD reset
|
||||
TC0->TC_CHANNEL[0].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger)
|
||||
while ( TC0->TC_CHANNEL[0].TC_CV < 9000 ) // 1500 uS, Value depends on MCK/2 (used 6MHz)
|
||||
{
|
||||
// Wait
|
||||
}
|
||||
lcdSendCtl(0xe2); //Initialize the internal functions
|
||||
lcdSendCtl(0xae); //DON = 0: display OFF
|
||||
lcdSendCtl(0xa1); //ADC = 1: reverse direction(SEG132->SEG1)
|
||||
lcdSendCtl(0xA6); //REV = 0: non-reverse display
|
||||
lcdSendCtl(0xA4); //EON = 0: normal display. non-entire
|
||||
lcdSendCtl(0xA2); // Select LCD bias=0
|
||||
lcdSendCtl(0xC0); //SHL = 0: normal direction (COM1->COM64)
|
||||
lcdSendCtl(0x2F); //Control power circuit operation VC=VR=VF=1
|
||||
lcdSendCtl(0x25); //Select int resistance ratio R2 R1 R0 =5
|
||||
lcdSendCtl(0x81); //Set reference voltage Mode
|
||||
lcdSendCtl(0x22); // 24 SV5 SV4 SV3 SV2 SV1 SV0 = 0x18
|
||||
lcdSendCtl(0xAF); //DON = 1: display ON
|
||||
// g_eeGeneral.contrast = 0x22;
|
||||
|
||||
#ifdef REVB
|
||||
pioptr->PIO_ODR = 0x0000003AL ; // Set bits 1, 3, 4, 5 input
|
||||
pioptr->PIO_PUER = 0x0000003AL ; // Set bits 1, 3, 4, 5 with pullups
|
||||
pioptr->PIO_ODSR = 0 ; // Drive D0 low
|
||||
#else
|
||||
pioptr->PIO_ODR = 0x0000003CL ; // Set bits 2, 3, 4, 5 input
|
||||
pioptr->PIO_PUER = 0x0000003CL ; // Set bits 2, 3, 4, 5 with pullups
|
||||
pioptr->PIO_ODSR = 0 ; // Drive D0 low
|
||||
#endif
|
||||
}
|
||||
|
||||
void lcdSetRefVolt(uint8_t val)
|
||||
{
|
||||
#ifndef SIMU
|
||||
register Pio *pioptr ;
|
||||
pioptr = PIOC ;
|
||||
|
||||
pioptr->PIO_OER = 0x0C00B0FFL ; // Set bits 27,26,15,13,12,7-0 output
|
||||
|
||||
lcdSendCtl(0x81);
|
||||
if ( val == 0 )
|
||||
{
|
||||
val = 0x22 ;
|
||||
}
|
||||
lcdSendCtl(val);
|
||||
|
||||
#ifdef REVB
|
||||
pioptr->PIO_ODR = 0x0000003AL ; // Set bits 1, 3, 4, 5 input
|
||||
pioptr->PIO_PUER = 0x0000003AL ; // Set bits 1, 3, 4, 5 with pullups
|
||||
pioptr->PIO_ODSR = 0 ; // Drive D0 low
|
||||
#else
|
||||
pioptr->PIO_ODR = 0x0000003CL ; // Set bits 2, 3, 4, 5 input
|
||||
pioptr->PIO_PUER = 0x0000003CL ; // Set bits 2, 3, 4, 5 with pullups
|
||||
pioptr->PIO_ODSR = 0 ; // Drive D0 low
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef SIMU
|
||||
void refreshDisplay()
|
||||
{
|
||||
register Pio *pioptr;
|
||||
register uint8_t *p = displayBuf;
|
||||
register uint32_t y;
|
||||
register uint32_t x;
|
||||
register uint32_t z;
|
||||
register uint32_t ebit;
|
||||
#ifdef REVB
|
||||
#else
|
||||
register uint8_t *lookup;
|
||||
lookup = (uint8_t *) Lcd_lookup;
|
||||
#endif
|
||||
ebit = LCD_E;
|
||||
|
||||
#ifdef REVB
|
||||
pioptr = PIOA;
|
||||
pioptr->PIO_PER = 0x00000080; // Enable bit 7 (LCD-A0)
|
||||
pioptr->PIO_OER = 0x00000080;// Set bit 7 output
|
||||
#endif
|
||||
|
||||
pioptr = PIOC;
|
||||
#ifdef REVB
|
||||
pioptr->PIO_OER = 0x0C0030FFL; // Set bits 27,26,15,13,12,7-0 output
|
||||
#else
|
||||
pioptr->PIO_OER = 0x0C00B0FFL; // Set bits 27,26,15,13,12,7-0 output
|
||||
#endif
|
||||
for (y = 0; y < 8; y++) {
|
||||
lcdSendCtl(g_eeGeneral.optrexDisplay ? 0 : 0x04);
|
||||
lcdSendCtl(0x10); //column addr 0
|
||||
lcdSendCtl(y | 0xB0); //page addr y
|
||||
|
||||
pioptr->PIO_CODR = LCD_CS1; // Select LCD
|
||||
PIOA->PIO_SODR = LCD_A0; // Data
|
||||
pioptr->PIO_CODR = LCD_RnW; // Write
|
||||
|
||||
#ifdef REVB
|
||||
x = *p;
|
||||
#else
|
||||
x = lookup[*p];
|
||||
#endif
|
||||
for (z = 0; z < 128; z += 1) {
|
||||
|
||||
// The following 7 lines replaces by a lookup table
|
||||
// x = __RBIT( *p++ ) ;
|
||||
// x >>= 23 ;
|
||||
// if ( x & 0x00000100 )
|
||||
// {
|
||||
// x |= 1 ;
|
||||
// }
|
||||
// pioptr->PIO_ODSR = x ;
|
||||
|
||||
pioptr->PIO_ODSR = x;
|
||||
pioptr->PIO_SODR = ebit; // Start E pulse
|
||||
// Need a delay here (250nS)
|
||||
p += 1;
|
||||
#ifdef REVB
|
||||
x = *p;
|
||||
#else
|
||||
x = lookup[*p];
|
||||
#endif
|
||||
// TC0->TC_CHANNEL[0].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger)
|
||||
// while ( TC0->TC_CHANNEL[0].TC_CV < 3 ) // Value depends on MCK/2 (used 6MHz)
|
||||
// {
|
||||
// // Wait
|
||||
// }
|
||||
pioptr->PIO_CODR = ebit; // End E pulse
|
||||
}
|
||||
pioptr->PIO_SODR = LCD_CS1; // Deselect LCD
|
||||
}
|
||||
|
||||
pioptr->PIO_ODSR = 0xFF ; // Drive lines high
|
||||
#ifdef REVB
|
||||
pioptr->PIO_PUER = 0x0000003AL ; // Set bits 1, 3, 4, 5 with pullups
|
||||
pioptr->PIO_ODR = 0x0000003AL ; // Set bits 1, 3, 4, 5 input
|
||||
#else
|
||||
pioptr->PIO_PUER = 0x0000003CL ; // Set bits 2, 3, 4, 5 with pullups
|
||||
pioptr->PIO_ODR = 0x0000003CL ; // Set bits 2, 3, 4, 5 input
|
||||
#endif
|
||||
pioptr->PIO_ODSR = 0xFE ; // Drive D0 low
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define delay_1us() _delay_us(1)
|
||||
void delay_1_5us(int ms)
|
||||
{
|
||||
for(int i=0; i<ms; i++) delay_1us();
|
||||
}
|
||||
|
||||
void lcdSendCtl(uint8_t val)
|
||||
{
|
||||
PORTC_LCD_CTRL &= ~(1<<OUT_C_LCD_CS1);
|
||||
#ifdef LCD_MULTIPLEX
|
||||
DDRA = 0xFF; // set LCD_DAT pins to output
|
||||
#endif
|
||||
PORTC_LCD_CTRL &= ~(1<<OUT_C_LCD_A0);
|
||||
PORTC_LCD_CTRL &= ~(1<<OUT_C_LCD_RnW);
|
||||
PORTA_LCD_DAT = val;
|
||||
PORTC_LCD_CTRL |= (1<<OUT_C_LCD_E);
|
||||
PORTC_LCD_CTRL &= ~(1<<OUT_C_LCD_E);
|
||||
PORTC_LCD_CTRL |= (1<<OUT_C_LCD_A0);
|
||||
#ifdef LCD_MULTIPLEX
|
||||
DDRA = 0x00; // set LCD_DAT pins to input
|
||||
#endif
|
||||
PORTC_LCD_CTRL |= (1<<OUT_C_LCD_CS1);
|
||||
}
|
||||
|
||||
inline void lcd_init()
|
||||
{
|
||||
// /home/thus/txt/datasheets/lcd/KS0713.pdf
|
||||
// ~/txt/flieger/ST7565RV17.pdf from http://www.glyn.de/content.asp?wdid=132&sid=
|
||||
|
||||
PORTC_LCD_CTRL &= ~(1<<OUT_C_LCD_RES); //LCD_RES
|
||||
delay_1us();
|
||||
delay_1us();// f520 call 0xf4ce delay_1us() ; 0x0xf4ce
|
||||
PORTC_LCD_CTRL |= (1<<OUT_C_LCD_RES); // f524 sbi 0x15, 2 IOADR-PORTC_LCD_CTRL; 21 1
|
||||
delay_1_5us(1500);
|
||||
lcdSendCtl(0xe2); //Initialize the internal functions
|
||||
lcdSendCtl(0xae); //DON = 0: display OFF
|
||||
lcdSendCtl(0xa1); //ADC = 1: reverse direction(SEG132->SEG1)
|
||||
lcdSendCtl(0xA6); //REV = 0: non-reverse display
|
||||
lcdSendCtl(0xA4); //EON = 0: normal display. non-entire
|
||||
lcdSendCtl(0xA2); // Select LCD bias=0
|
||||
lcdSendCtl(0xC0); //SHL = 0: normal direction (COM1->COM64)
|
||||
lcdSendCtl(0x2F); //Control power circuit operation VC=VR=VF=1
|
||||
lcdSendCtl(0x25); //Select int resistance ratio R2 R1 R0 =5
|
||||
lcdSendCtl(0x81); //Set reference voltage Mode
|
||||
lcdSendCtl(0x22); // 24 SV5 SV4 SV3 SV2 SV1 SV0 = 0x18
|
||||
lcdSendCtl(0xAF); //DON = 1: display ON
|
||||
g_eeGeneral.contrast = 0x22;
|
||||
}
|
||||
|
||||
void lcdSetRefVolt(uint8_t val)
|
||||
{
|
||||
lcdSendCtl(0x81);
|
||||
lcdSendCtl(val);
|
||||
}
|
||||
|
||||
#ifndef SIMU
|
||||
void refreshDisplay()
|
||||
{
|
||||
uint8_t *p=displayBuf;
|
||||
for(uint8_t y=0; y < 8; y++) {
|
||||
lcdSendCtl(0x04);
|
||||
lcdSendCtl(0x10); //column addr 0
|
||||
lcdSendCtl( y | 0xB0); //page addr y
|
||||
PORTC_LCD_CTRL &= ~(1<<OUT_C_LCD_CS1);
|
||||
#ifdef LCD_MULTIPLEX
|
||||
DDRA = 0xFF; // set LCD_DAT pins to output
|
||||
#endif
|
||||
PORTC_LCD_CTRL |= (1<<OUT_C_LCD_A0);
|
||||
PORTC_LCD_CTRL &= ~(1<<OUT_C_LCD_RnW);
|
||||
for(uint8_t x=128; x>0; --x) {
|
||||
PORTA_LCD_DAT = *p++;
|
||||
PORTC_LCD_CTRL |= (1<<OUT_C_LCD_E);
|
||||
PORTC_LCD_CTRL &= ~(1<<OUT_C_LCD_E);
|
||||
}
|
||||
PORTC_LCD_CTRL |= (1<<OUT_C_LCD_A0);
|
||||
PORTC_LCD_CTRL |= (1<<OUT_C_LCD_CS1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef SIMU
|
||||
void refreshDisplay()
|
||||
{
|
||||
memcpy(lcd_buf, displayBuf, sizeof(displayBuf));
|
||||
lcd_refresh = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,161 +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 lcd_h
|
||||
#define lcd_h
|
||||
|
||||
#define DISPLAY_W 128
|
||||
#define DISPLAY_H 64
|
||||
#define FW 6
|
||||
#define FWNUM 5
|
||||
#define FH 8
|
||||
|
||||
/* lcd common flags */
|
||||
#define BLINK 0x01
|
||||
#define SURROUNDED 0x40
|
||||
|
||||
/* lcd text flags */
|
||||
#define INVERS 0x02
|
||||
#define DBLSIZE 0x04
|
||||
|
||||
/* lcd putc flags */
|
||||
#define CONDENSED 0x08
|
||||
|
||||
/* lcd puts flags */
|
||||
#define BSS 0x10
|
||||
#define ZCHAR 0x20
|
||||
|
||||
/* lcd outdez flags */
|
||||
#define UNSIGN 0x08
|
||||
#define LEADING0 0x10
|
||||
#define PREC1 0x20
|
||||
#define PREC2 0x30
|
||||
#define MODE(flags) ((((int8_t)(flags) & 0x30) - 0x10) >> 4)
|
||||
#define LEFT 0x80 /* align left */
|
||||
|
||||
/* line, rect, square flags */
|
||||
#define BLACK 0x02
|
||||
#define WHITE 0x04
|
||||
#define ROUND 0x08
|
||||
|
||||
/* switches flags */
|
||||
#define SWONLY 0x40 /* means no ON OFF, only switches */
|
||||
#define SWCONDENSED 0x80 /* means that THRm will be displayed as THR */
|
||||
|
||||
/* telemetry flags */
|
||||
#define NO_UNIT 0x40
|
||||
|
||||
/* other flags */
|
||||
#define TWO_DOTS LEFT
|
||||
|
||||
extern uint8_t displayBuf[DISPLAY_W*DISPLAY_H/8];
|
||||
extern uint8_t lcd_lastPos;
|
||||
|
||||
extern void lcd_putc(uint8_t x,uint8_t y,const unsigned char c);
|
||||
extern void lcd_putcAtt(uint8_t x,uint8_t y,const unsigned char c,uint8_t mode);
|
||||
|
||||
extern void lcd_putsAtt(uint8_t x,uint8_t y,const pm_char * s,uint8_t mode);
|
||||
extern void lcd_putsiAtt(uint8_t x,uint8_t y,const pm_char * s,uint8_t idx, uint8_t mode);
|
||||
extern void lcd_putsnAtt(uint8_t x,uint8_t y,const pm_char * s,unsigned char len,uint8_t mode);
|
||||
extern void lcd_puts(uint8_t x,uint8_t y,const pm_char * s);
|
||||
extern void lcd_putsLeft(uint8_t y, const pm_char * s);
|
||||
extern void lcd_putsn(uint8_t x,uint8_t y,const pm_char * s,unsigned char len);
|
||||
|
||||
extern void lcd_outhex4(uint8_t x,uint8_t y,uint16_t val);
|
||||
|
||||
extern void lcd_outdezAtt(uint8_t x, uint8_t y, int16_t val, uint8_t mode=0);
|
||||
extern void lcd_outdezNAtt(uint8_t x, uint8_t y, int16_t val, uint8_t mode=0, uint8_t len=0);
|
||||
extern void lcd_outdez8(uint8_t x, uint8_t y, int8_t val);
|
||||
|
||||
extern void putsStrIdx(uint8_t x, uint8_t y, const pm_char *str, uint8_t idx, uint8_t att=0);
|
||||
|
||||
extern void putsModelName(uint8_t x, uint8_t y, char *name, uint8_t id, uint8_t att);
|
||||
extern void putsSwitches(uint8_t x, uint8_t y, int8_t swtch, uint8_t att=0);
|
||||
extern void putsMixerSource(uint8_t x, uint8_t y, uint8_t idx, uint8_t att=0);
|
||||
extern void putsFlightPhase(uint8_t x, uint8_t y, int8_t idx, uint8_t att=0);
|
||||
extern void putsCurve(uint8_t x, uint8_t y, int8_t idx, uint8_t att=0);
|
||||
extern void putsTmrMode(uint8_t x, uint8_t y, int8_t mode, uint8_t att);
|
||||
extern void putsTrimMode(uint8_t x, uint8_t y, uint8_t phase, uint8_t idx, uint8_t att);
|
||||
#if defined(PCBV4)
|
||||
void putsRotaryEncoderMode(uint8_t x, uint8_t y, uint8_t phase, uint8_t idx, uint8_t att);
|
||||
#endif
|
||||
|
||||
extern void putsChnRaw(uint8_t x,uint8_t y,uint8_t idx1,uint8_t att);
|
||||
extern void putsChn(uint8_t x,uint8_t y,uint8_t idx1,uint8_t att);
|
||||
extern void putsChnLetter(uint8_t x, uint8_t y, uint8_t idx, uint8_t attr);
|
||||
|
||||
extern void putsVolts(uint8_t x, uint8_t y, uint16_t volts, uint8_t att);
|
||||
extern void putsVBat(uint8_t x, uint8_t y, uint8_t att);
|
||||
extern void putsTime(uint8_t x,uint8_t y, int16_t tme, uint8_t att, uint8_t att2);
|
||||
|
||||
#define SOLID 0xff
|
||||
#define DOTTED 0x55
|
||||
|
||||
extern void lcd_plot(uint8_t x, uint8_t y, uint8_t att=0);
|
||||
extern void lcd_hline(uint8_t x, uint8_t y, uint8_t w, uint8_t att=0);
|
||||
extern void lcd_hlineStip(int8_t x, uint8_t y, uint8_t w, uint8_t pat, uint8_t att=0);
|
||||
extern void lcd_vline(uint8_t x, int8_t y, int8_t h);
|
||||
extern void lcd_vlineStip(uint8_t x, int8_t y, int8_t h, uint8_t pat);
|
||||
|
||||
extern void lcd_rect(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t pat=SOLID, uint8_t att=0);
|
||||
extern void lcd_filled_rect(uint8_t x, int8_t y, uint8_t w, uint8_t h, uint8_t pat=SOLID, uint8_t att=0);
|
||||
#define lcd_status_line() lcd_filled_rect(0, 7*FH, DISPLAY_W, 8)
|
||||
inline void lcd_square(uint8_t x, uint8_t y, uint8_t w, uint8_t att=0) { lcd_rect(x, y, w, w, SOLID, att); }
|
||||
|
||||
#define DO_CROSS(xx,yy,ww) \
|
||||
lcd_vline(xx,yy-ww/2,ww); \
|
||||
lcd_hline(xx-ww/2,yy,ww);
|
||||
|
||||
// TODO optimization here!!!
|
||||
#define V_BAR(xx,yy,ll) \
|
||||
lcd_vline(xx-1,yy-ll,ll); \
|
||||
lcd_vline(xx ,yy-ll,ll); \
|
||||
lcd_vline(xx+1,yy-ll,ll);
|
||||
|
||||
extern void lcd_img(uint8_t x, uint8_t y, const pm_uchar * img, uint8_t idx, uint8_t mode);
|
||||
extern void lcdSetRefVolt(unsigned char val);
|
||||
extern void lcd_init();
|
||||
extern void lcd_clear();
|
||||
|
||||
extern void refreshDisplay();
|
||||
|
||||
#define BLINK_ON_PHASE (g_blinkTmr10ms & (1<<6))
|
||||
#define BLINK_SYNC g_blinkTmr10ms = (3<<5)
|
||||
|
||||
#ifdef SIMU
|
||||
extern bool lcd_refresh;
|
||||
extern uint8_t lcd_buf[DISPLAY_W*DISPLAY_H/8];
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*eof*/
|
||||
-366
@@ -1,366 +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"
|
||||
|
||||
#define BOX_WIDTH 23
|
||||
#define BAR_HEIGHT (BOX_WIDTH-1l)
|
||||
#define MARKER_WIDTH 5
|
||||
#define SCREEN_WIDTH 128
|
||||
#define SCREEN_HEIGHT 64
|
||||
#define BOX_LIMIT (BOX_WIDTH-MARKER_WIDTH)
|
||||
#define LBOX_CENTERX ( SCREEN_WIDTH/4 + 10)
|
||||
#define LBOX_CENTERY (SCREEN_HEIGHT-9-BOX_WIDTH/2)
|
||||
#define RBOX_CENTERX (3*SCREEN_WIDTH/4 - 10)
|
||||
#define RBOX_CENTERY (SCREEN_HEIGHT-9-BOX_WIDTH/2)
|
||||
|
||||
void doMainScreenGrphics()
|
||||
{
|
||||
lcd_square(LBOX_CENTERX-BOX_WIDTH/2, LBOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH);
|
||||
lcd_square(RBOX_CENTERX-BOX_WIDTH/2, RBOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH);
|
||||
|
||||
DO_CROSS(LBOX_CENTERX,LBOX_CENTERY,3)
|
||||
DO_CROSS(RBOX_CENTERX,RBOX_CENTERY,3)
|
||||
|
||||
int16_t calibStickVert = calibratedStick[CONVERT_MODE(1+1)-1];
|
||||
if (g_eeGeneral.throttleReversed && CONVERT_MODE(1+1)-1 == THR_STICK)
|
||||
calibStickVert = -calibStickVert;
|
||||
lcd_square(LBOX_CENTERX+(calibratedStick[CONVERT_MODE(0+1)-1]*BOX_LIMIT/(2*RESX))-MARKER_WIDTH/2, LBOX_CENTERY-(calibStickVert*BOX_LIMIT/(2*RESX))-MARKER_WIDTH/2, MARKER_WIDTH, ROUND);
|
||||
calibStickVert = calibratedStick[CONVERT_MODE(2+1)-1];
|
||||
if (g_eeGeneral.throttleReversed && CONVERT_MODE(2+1)-1 == THR_STICK)
|
||||
calibStickVert = -calibStickVert;
|
||||
lcd_square(RBOX_CENTERX+(calibratedStick[CONVERT_MODE(3+1)-1]*BOX_LIMIT/(2*RESX))-MARKER_WIDTH/2, RBOX_CENTERY-(calibStickVert*BOX_LIMIT/(2*RESX))-MARKER_WIDTH/2, MARKER_WIDTH, ROUND);
|
||||
|
||||
// Optimization by Mike Blandford
|
||||
{
|
||||
uint8_t x, y, len ; // declare temporary variables
|
||||
for( x = -5, y = 4 ; y < 7 ; x += 5, y += 1 )
|
||||
{
|
||||
len = ((calibratedStick[y]+RESX)*BAR_HEIGHT/(RESX*2))+1l; // calculate once per loop
|
||||
V_BAR(SCREEN_WIDTH/2+x,SCREEN_HEIGHT-8, len)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void menuMainView(uint8_t event)
|
||||
{
|
||||
uint8_t view = g_eeGeneral.view;
|
||||
uint8_t view_base = view & 0x0f;
|
||||
|
||||
switch(event)
|
||||
{
|
||||
/* TODO if timer2 is OFF, it's possible to use this timer2 as in er9x...
|
||||
case EVT_KEY_BREAK(KEY_MENU):
|
||||
if (view_base == e_timer2) {
|
||||
Timer2_running = !Timer2_running;
|
||||
AUDIO_KEYPAD_UP();
|
||||
}
|
||||
break;
|
||||
*/
|
||||
case EVT_KEY_LONG(KEY_MENU):// go to last menu
|
||||
pushMenu(lastPopMenu());
|
||||
killEvents(event);
|
||||
break;
|
||||
case EVT_KEY_BREAK(KEY_RIGHT):
|
||||
case EVT_KEY_BREAK(KEY_LEFT):
|
||||
if (view_base <= e_inputs) {
|
||||
#if defined(PCBARM)
|
||||
if (view_base == e_inputs)
|
||||
g_eeGeneral.view ^= ALTERNATE_VIEW;
|
||||
else
|
||||
g_eeGeneral.view = (g_eeGeneral.view + (4*ALTERNATE_VIEW) + ((event==EVT_KEY_BREAK(KEY_RIGHT)) ? ALTERNATE_VIEW : -ALTERNATE_VIEW)) % (4*ALTERNATE_VIEW);
|
||||
#else
|
||||
g_eeGeneral.view ^= ALTERNATE_VIEW;
|
||||
#endif
|
||||
eeDirty(EE_GENERAL);
|
||||
AUDIO_KEYPAD_UP();
|
||||
}
|
||||
break;
|
||||
case EVT_KEY_LONG(KEY_RIGHT):
|
||||
pushMenu(menuProcModelSelect);
|
||||
killEvents(event);
|
||||
break;
|
||||
case EVT_KEY_LONG(KEY_LEFT):
|
||||
pushMenu(menuProcSetup);
|
||||
killEvents(event);
|
||||
break;
|
||||
case EVT_KEY_BREAK(KEY_UP):
|
||||
case EVT_KEY_BREAK(KEY_DOWN):
|
||||
g_eeGeneral.view = (event == EVT_KEY_BREAK(KEY_UP) ? (view_base == MAIN_VIEW_MAX ? 0 : view_base + 1) : (view_base == 0 ? MAIN_VIEW_MAX : view_base - 1));
|
||||
eeDirty(EE_GENERAL);
|
||||
AUDIO_KEYPAD_UP();
|
||||
break;
|
||||
case EVT_KEY_LONG(KEY_UP):
|
||||
chainMenu(menuProcStatistic);
|
||||
killEvents(event);
|
||||
break;
|
||||
case EVT_KEY_LONG(KEY_DOWN):
|
||||
#if defined(FRSKY)
|
||||
chainMenu(menuProcFrsky);
|
||||
#elif defined(JETI)
|
||||
JETI_EnableRXD(); // enable JETI-Telemetry reception
|
||||
chainMenu(menuProcJeti);
|
||||
#elif defined(ARDUPILOT)
|
||||
ARDUPILOT_EnableRXD(); // enable ArduPilot-Telemetry reception
|
||||
chainMenu(menuProcArduPilot);
|
||||
#elif defined(NMEA)
|
||||
NMEA_EnableRXD(); // enable NMEA-Telemetry reception
|
||||
chainMenu(menuProcNMEA);
|
||||
#elif defined(MAVLINK)
|
||||
chainMenu(menuProcMavlink);
|
||||
#else
|
||||
chainMenu(menuProcDebug);
|
||||
#endif
|
||||
killEvents(event);
|
||||
break;
|
||||
case EVT_KEY_FIRST(KEY_EXIT):
|
||||
if(s_timerState[0]==TMR_BEEPING) {
|
||||
s_timerState[0] = TMR_STOPPED;
|
||||
}
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
else if (s_warning) {
|
||||
s_warning = NULL;
|
||||
}
|
||||
#endif
|
||||
else if (view == e_timer2) {
|
||||
resetTimer(1);
|
||||
}
|
||||
else {
|
||||
resetTimer(0);
|
||||
}
|
||||
AUDIO_KEYPAD_UP();
|
||||
break;
|
||||
case EVT_KEY_LONG(KEY_EXIT):
|
||||
resetAll();
|
||||
AUDIO_KEYPAD_UP();
|
||||
break;
|
||||
case EVT_ENTRY:
|
||||
killEvents(KEY_EXIT);
|
||||
killEvents(KEY_UP);
|
||||
killEvents(KEY_DOWN);
|
||||
break;
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
case EVT_KEY_LONG(BTN_REa):
|
||||
case EVT_KEY_LONG(BTN_REb):
|
||||
if (navigationRotaryEncoder(event)) {
|
||||
killEvents(event);
|
||||
if (s_inflight_value && !s_warning) {
|
||||
s_warning = s_inflight_label;
|
||||
s_editMode = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// no break
|
||||
case EVT_KEY_BREAK(BTN_REa):
|
||||
case EVT_KEY_BREAK(BTN_REb):
|
||||
s_warning = NULL;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
uint8_t phase = s_perout_flight_phase;
|
||||
lcd_putsnAtt(6*FW, 2*FH, g_model.phaseData[phase].name, sizeof(g_model.phaseData[phase].name), ZCHAR);
|
||||
|
||||
uint8_t att = (g_vbat100mV < g_eeGeneral.vBatWarn ? BLINK|INVERS : 0) | DBLSIZE;
|
||||
putsModelName(2*FW-2, 0*FH, g_model.name, g_eeGeneral.currModel, DBLSIZE);
|
||||
putsVBat(6*FW-1, 2*FH, att|NO_UNIT);
|
||||
lcd_putc(6*FW, 3*FH, 'V');
|
||||
|
||||
if (g_model.timers[0].mode) {
|
||||
uint8_t att = DBLSIZE | (s_timerState[0]==TMR_BEEPING ? BLINK|INVERS : 0);
|
||||
putsTime(12*FW+3, FH*2, s_timerVal[0], att, att);
|
||||
putsTmrMode(s_timerVal[0] >= 0 ? 9*FW-FW/2+5 : 9*FW-FW/2-2, FH*3, g_model.timers[0].mode, SWCONDENSED);
|
||||
}
|
||||
|
||||
// trim sliders
|
||||
for(uint8_t i=0; i<4; i++)
|
||||
{
|
||||
#define TL 27
|
||||
// LH LV RV RH
|
||||
static uint8_t x[4] = {128*1/4+2, 3, 128-4, 128*3/4-2};
|
||||
static uint8_t vert[4] = {0,1,1,0};
|
||||
uint8_t xm, ym;
|
||||
xm = x[CONVERT_MODE(i+1)-1];
|
||||
|
||||
uint8_t att = ROUND;
|
||||
int16_t val = getTrimValue(phase, i);
|
||||
|
||||
if (val < -125 || val > 125)
|
||||
att = BLINK|INVERS|ROUND;
|
||||
|
||||
if (val < -(TL+1)*4)
|
||||
val = -(TL+1);
|
||||
else if (val > (TL+1)*4)
|
||||
val = TL+1;
|
||||
else
|
||||
val /= 4;
|
||||
|
||||
if (vert[i]) {
|
||||
ym = 31;
|
||||
lcd_vline(xm, ym-TL, TL*2);
|
||||
if (i!=2 || !g_model.thrTrim) {
|
||||
lcd_vline(xm-1, ym-1, 3);
|
||||
lcd_vline(xm+1, ym-1, 3);
|
||||
}
|
||||
ym -= val;
|
||||
}
|
||||
else {
|
||||
ym = 60;
|
||||
lcd_hline(xm-TL, ym, TL*2);
|
||||
lcd_hline(xm-1, ym-1, 3);
|
||||
lcd_hline(xm-1, ym+1, 3);
|
||||
xm += val;
|
||||
}
|
||||
lcd_square(xm-3, ym-3, 7, att);
|
||||
}
|
||||
}
|
||||
|
||||
if (view_base < e_inputs) {
|
||||
// scroll bar
|
||||
lcd_hlineStip(38, 34, 54, DOTTED);
|
||||
#if defined(PCBARM)
|
||||
lcd_hline(38 + (g_eeGeneral.view / ALTERNATE_VIEW) * 13, 34, 13, SOLID);
|
||||
#else
|
||||
lcd_hline((g_eeGeneral.view & ALTERNATE_VIEW) ? 64 : 38, 34, 26, SOLID);
|
||||
#endif
|
||||
|
||||
for (uint8_t i=0; i<8; i++) {
|
||||
uint8_t x0,y0;
|
||||
#if defined(PCBARM)
|
||||
int16_t val = g_chans512[8*(g_eeGeneral.view / ALTERNATE_VIEW) + i];
|
||||
#else
|
||||
int16_t val = g_chans512[(g_eeGeneral.view & ALTERNATE_VIEW) ? 8+i : i];
|
||||
#endif
|
||||
|
||||
switch(view_base)
|
||||
{
|
||||
case e_outputValues:
|
||||
x0 = (i%4*9+3)*FW/2;
|
||||
y0 = i/4*FH+40;
|
||||
// *1000/1024 = x - x/32 + x/128
|
||||
#define GPERC(x) (x - x/32 + x/128)
|
||||
#if defined (DECIMALS_DISPLAYED)
|
||||
lcd_outdezAtt( x0+4*FW , y0, GPERC(val), PREC1);
|
||||
#else
|
||||
lcd_outdezAtt( x0+4*FW , y0, GPERC(val)/10, 0); // G: Don't like the decimal part*
|
||||
#endif
|
||||
break;
|
||||
|
||||
case e_outputBars:
|
||||
#define WBAR2 (50/2)
|
||||
x0 = i<4 ? 128/4+2 : 128*3/4-2;
|
||||
y0 = 38+(i%4)*5;
|
||||
|
||||
int8_t len = (abs(val) * WBAR2 + 512) / 1024;
|
||||
if(len>WBAR2) len = WBAR2; // prevent bars from going over the end - comment for debugging
|
||||
lcd_hlineStip(x0-WBAR2, y0, WBAR2*2+1, DOTTED);
|
||||
lcd_vline(x0,y0-2,5);
|
||||
if (val>0){
|
||||
x0+=1;
|
||||
}else{
|
||||
x0-=len;
|
||||
}
|
||||
lcd_hline(x0,y0+1,len);
|
||||
lcd_hline(x0,y0-1,len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (view_base == e_inputs) {
|
||||
if (view == e_inputs) {
|
||||
// hardware inputs
|
||||
doMainScreenGrphics();
|
||||
for (uint8_t i=0; i<6; i++) {
|
||||
int8_t sw1 = (i<3 ? 1+i : 4+i);
|
||||
int8_t sw2 = (sw1 == 9 ? (getSwitch(4, 0) ? 4 : (getSwitch(5, 0) ? 5 : 6)) : sw1);
|
||||
putsSwitches(i<3 ? 2*FW-2: 17*FW-1, (i%3)*FH+4*FH+1, sw2, getSwitch(sw1, 0) ? INVERS : 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
#if defined(PCBV4)
|
||||
for (uint8_t i=0; i<NUM_ROTARY_ENCODERS; i++) {
|
||||
int16_t val = getRotaryEncoder(i);
|
||||
int8_t len = limit((int16_t)0, (int16_t)(((val+1024) * BAR_HEIGHT) / 2048), (int16_t)BAR_HEIGHT); // TODO uint16_t?
|
||||
#if defined(EXTRA_ROTARY_ENCODERS)
|
||||
#define V_BAR_W 4
|
||||
V_BAR(SCREEN_WIDTH/2-9+V_BAR_W*i, SCREEN_HEIGHT-8, len)
|
||||
#else //EXTRA_ROTARY_ENCODERS
|
||||
#define V_BAR_W 5
|
||||
V_BAR(SCREEN_WIDTH/2-3+V_BAR_W*i, SCREEN_HEIGHT-8, len)
|
||||
#endif //EXTRA_ROTARY_ENCODERS
|
||||
}
|
||||
#endif //PCBV4
|
||||
#if defined(PCBARM)
|
||||
for (uint8_t i=0; i<NUM_CSW; i++) {
|
||||
int8_t len = getSwitch(10+i, 0) ? BAR_HEIGHT : 1;
|
||||
lcd_vline(16+3*i-1,SCREEN_HEIGHT-8-len,len);
|
||||
lcd_vline(16+3*i ,SCREEN_HEIGHT-8-len,len);
|
||||
}
|
||||
#elif defined(PCBV4) && defined(EXTRA_ROTARY_ENCODERS)
|
||||
for (uint8_t i=0; i<NUM_CSW; i++)
|
||||
putsSwitches(2*FW-2 + (i/3)*(4*FW-2) + (i/3>1 ? 3*FW+6 : 0), 4*FH+1 + (i%3)*FH, 10+i, getSwitch(10+i, 0) ? INVERS : 0);
|
||||
#elif defined(PCBV4)
|
||||
for (uint8_t i=0; i<NUM_CSW; i++)
|
||||
putsSwitches(2*FW-2 + (i/3)*(4*FW) + (i/3>1 ? 3*FW : 0), 4*FH+1 + (i%3)*FH, 10+i, getSwitch(10+i, 0) ? INVERS : 0);
|
||||
#else
|
||||
for (uint8_t i=0; i<NUM_CSW; i++)
|
||||
putsSwitches(2*FW-2 + (i/3)*(5*FW), 4*FH+1 + (i%3)*FH, 10+i, getSwitch(10+i, 0) ? INVERS : 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else { // timer2
|
||||
putsTime(33+FW+2, FH*5, s_timerVal[1], DBLSIZE, DBLSIZE);
|
||||
putsTmrMode(s_timerVal[1] >= 0 ? 20-FW/2+5 : 20-FW/2-2, FH*6, g_model.timers[1].mode, SWCONDENSED);
|
||||
// lcd_outdezNAtt(33+11*FW, FH*6, s_timerVal_10ms[1], LEADING0, 2); // 1/100s
|
||||
}
|
||||
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
check_rotary_encoder();
|
||||
if (s_warning) {
|
||||
int8_t value = (((uint8_t)(*s_inflight_value)) >> s_inflight_bitshift) - s_inflight_shift;
|
||||
if (p1valdiff) {
|
||||
value = checkIncDecModel(event, value, s_inflight_min, s_inflight_max);
|
||||
*s_inflight_value = (((uint8_t)(*s_inflight_value)) & ((1 << s_inflight_bitshift) - 1)) + ((s_inflight_shift + value) << s_inflight_bitshift);
|
||||
}
|
||||
displayBox();
|
||||
lcd_outdezAtt(16, 4*FH, value, LEFT);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// in case we want a progress bar in the Main Views
|
||||
DISPLAY_PROGRESS_BAR(20*FW+1);
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -1,629 +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"
|
||||
|
||||
int16_t calibratedStick[NUM_STICKS+NUM_POTS];
|
||||
uint8_t s_pgOfs;
|
||||
int8_t s_editMode;
|
||||
uint8_t s_noHi;
|
||||
uint8_t s_noScroll;
|
||||
|
||||
int16_t g_chans512[NUM_CHNOUT]; // TODO not here!
|
||||
|
||||
void menu_lcd_onoff( uint8_t x,uint8_t y, uint8_t value, uint8_t mode )
|
||||
{
|
||||
lcd_putsiAtt(x, y, STR_OFFON, value, mode ? INVERS:0) ;
|
||||
}
|
||||
|
||||
void DisplayScreenIndex(uint8_t index, uint8_t count, uint8_t attr)
|
||||
{
|
||||
lcd_outdezAtt(128,0,count,attr);
|
||||
lcd_putcAtt(1+128-FW*(count>9 ? 3 : 2),0,'/',attr);
|
||||
lcd_outdezAtt(1+128-FW*(count>9 ? 3 : 2),0,index+1,attr);
|
||||
}
|
||||
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
int8_t scrollRE;
|
||||
int16_t p1valdiff;
|
||||
#elif defined(NAVIGATION_POT1)
|
||||
int16_t p1valdiff;
|
||||
#endif
|
||||
|
||||
int8_t checkIncDec_Ret;
|
||||
int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, uint8_t i_flags)
|
||||
{
|
||||
int16_t newval = val;
|
||||
uint8_t kpl=KEY_RIGHT, kmi=KEY_LEFT, kother = -1;
|
||||
|
||||
if (event & _MSK_KEY_DBL) {
|
||||
uint8_t hlp=kpl;
|
||||
kpl=kmi;
|
||||
kmi=hlp;
|
||||
event=EVT_KEY_FIRST(EVT_KEY_MASK & event);
|
||||
}
|
||||
if (event==EVT_KEY_FIRST(kpl) || event== EVT_KEY_REPT(kpl) || (s_editMode>0 && (event==EVT_KEY_FIRST(KEY_UP) || event== EVT_KEY_REPT(KEY_UP))) ) {
|
||||
newval++;
|
||||
AUDIO_KEYPAD_UP();
|
||||
kother=kmi;
|
||||
}
|
||||
else if (event==EVT_KEY_FIRST(kmi) || event== EVT_KEY_REPT(kmi) || (s_editMode>0 && (event==EVT_KEY_FIRST(KEY_DOWN) || event== EVT_KEY_REPT(KEY_DOWN))) ) {
|
||||
newval--;
|
||||
AUDIO_KEYPAD_DOWN();
|
||||
kother=kpl;
|
||||
}
|
||||
if ((kother != (uint8_t)-1) && keyState((EnumKeys)kother)) {
|
||||
newval=-val;
|
||||
killEvents(kmi);
|
||||
killEvents(kpl);
|
||||
}
|
||||
if (i_min==0 && i_max==1 && event==EVT_KEY_FIRST(KEY_MENU)) {
|
||||
s_editMode = 0;
|
||||
newval=!val;
|
||||
killEvents(event);
|
||||
}
|
||||
|
||||
#if defined (ROTARY_ENCODERS) || defined(NAVIGATION_POT1)
|
||||
//change values based on P1
|
||||
newval -= p1valdiff;
|
||||
#endif
|
||||
|
||||
#if defined(AUTOSWITCH)
|
||||
if (s_editMode>0 && (i_flags & INCDEC_SWITCH)) {
|
||||
uint8_t swtch = getMovedSwitch();
|
||||
if (swtch) {
|
||||
newval = (val == swtch ? -swtch : swtch);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (newval > i_max) {
|
||||
newval = i_max;
|
||||
killEvents(event);
|
||||
AUDIO_WARNING2();
|
||||
}
|
||||
if (newval < i_min) {
|
||||
newval = i_min;
|
||||
killEvents(event);
|
||||
AUDIO_WARNING2();
|
||||
}
|
||||
if (newval != val) {
|
||||
if ((~i_flags & NO_INCDEC_MARKS) && (newval==0 || newval==-100 || newval==+100)) {
|
||||
pauseEvents(event); // delay before auto-repeat continues
|
||||
if (newval>val) // without AUDIO it's optimized, because the 2 sounds are the same
|
||||
AUDIO_KEYPAD_UP();
|
||||
else
|
||||
AUDIO_KEYPAD_DOWN();
|
||||
}
|
||||
eeDirty(i_flags & (EE_GENERAL|EE_MODEL));
|
||||
checkIncDec_Ret = (newval > val ? 1 : -1);
|
||||
}
|
||||
else {
|
||||
checkIncDec_Ret = 0;
|
||||
}
|
||||
return newval;
|
||||
}
|
||||
|
||||
int8_t checkIncDecModel(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max)
|
||||
{
|
||||
return checkIncDec(event,i_val,i_min,i_max,EE_MODEL);
|
||||
}
|
||||
|
||||
int8_t checkIncDecGen(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max)
|
||||
{
|
||||
return checkIncDec(event,i_val,i_min,i_max,EE_GENERAL);
|
||||
}
|
||||
|
||||
bool check_simple(uint8_t event, uint8_t curr, const MenuFuncP *menuTab, uint8_t menuTabSize, uint8_t maxrow)
|
||||
{
|
||||
return check(event, curr, menuTab, menuTabSize, 0, 0, maxrow);
|
||||
}
|
||||
|
||||
bool check_submenu_simple(uint8_t event, uint8_t maxrow)
|
||||
{
|
||||
return check_simple(event, 0, 0, 0, maxrow);
|
||||
}
|
||||
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
void check_rotary_encoder()
|
||||
{
|
||||
// check rotary encoder 1 if changed -> cursor down/up
|
||||
static int16_t re1valprev;
|
||||
|
||||
if (g_eeGeneral.reNavigation) {
|
||||
uint8_t re = g_eeGeneral.reNavigation - 1;
|
||||
p1valdiff = 0;
|
||||
scrollRE = re1valprev - g_rotenc[re];
|
||||
if (scrollRE) {
|
||||
re1valprev = g_rotenc[re];
|
||||
if (s_editMode > 0) {
|
||||
p1valdiff = -scrollRE;
|
||||
scrollRE = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
re1valprev = 0;
|
||||
p1valdiff = 0;
|
||||
scrollRE = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SCROLL_TH 64
|
||||
#define SCROLL_POT1_TH 32
|
||||
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
#define MAXCOL(row) ((horTab && row >= 0) ? pgm_read_byte(horTab+min(row, (int8_t)horTabMax)) : (const uint8_t)0)
|
||||
#else
|
||||
#define MAXCOL(row) (horTab ? pgm_read_byte(horTab+min(row, horTabMax)) : (const uint8_t)0)
|
||||
#endif
|
||||
#define INC(val,max) if(val<max) {val++;} else {val=0;}
|
||||
#define DEC(val,max) if(val>0 ) {val--;} else {val=max;}
|
||||
bool check(uint8_t event, uint8_t curr, const MenuFuncP *menuTab, uint8_t menuTabSize, const pm_uint8_t *horTab, uint8_t horTabMax, uint8_t maxrow)
|
||||
{
|
||||
int8_t maxcol = MAXCOL(m_posVert);
|
||||
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
if (!(s_warning || s_sdcard_error || s_menu_count))
|
||||
check_rotary_encoder();
|
||||
if (m_posVert < 0 && (event==EVT_KEY_FIRST(BTN_REa) || event==EVT_KEY_FIRST(BTN_REb) || event==EVT_KEY_FIRST(KEY_MENU))) {
|
||||
popMenu();
|
||||
killEvents(event);
|
||||
return false;
|
||||
}
|
||||
if (g_eeGeneral.reNavigation && event == EVT_KEY_BREAK(BTN_REa+g_eeGeneral.reNavigation-1)) {
|
||||
if (s_editMode > 0 && (maxcol & ZCHAR)) {
|
||||
if (m_posHorz < maxcol-ZCHAR) {
|
||||
m_posHorz++;
|
||||
}
|
||||
else {
|
||||
s_editMode = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
scrollRE = 0;
|
||||
if (s_editMode++ > 0) s_editMode = 0;
|
||||
if (s_editMode > 0 && m_posVert == 0 && menuTab) s_editMode = -1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define scrollRE 0
|
||||
#endif
|
||||
|
||||
#ifdef NAVIGATION_POT1
|
||||
// check pot 1 - if changed -> scroll values
|
||||
static int16_t p1valprev;
|
||||
p1valdiff = (p1valprev-calibratedStick[6]) / SCROLL_POT1_TH;
|
||||
if (p1valdiff) p1valprev = calibratedStick[6];
|
||||
#endif
|
||||
|
||||
#ifdef NAVIGATION_POT2
|
||||
// check pot 2 - if changed -> scroll menu
|
||||
static int16_t p2valprev;
|
||||
int8_t scrollLR = (p2valprev-calibratedStick[4]) / SCROLL_TH;
|
||||
if (scrollLR) p2valprev = calibratedStick[4];
|
||||
#else
|
||||
#define scrollLR 0
|
||||
#endif
|
||||
|
||||
#ifdef NAVIGATION_POT3
|
||||
// check pot 3 if changed -> cursor down/up
|
||||
static int16_t p3valprev;
|
||||
int8_t scrollUD = (p3valprev-calibratedStick[5]) / SCROLL_TH;
|
||||
if (scrollUD) p3valprev = calibratedStick[5];
|
||||
#else
|
||||
#define scrollUD 0
|
||||
#endif
|
||||
|
||||
if(scrollRE || scrollLR || scrollUD || p1valdiff) g_LightOffCounter = g_eeGeneral.lightAutoOff*500; // on keypress turn the light on 5*100
|
||||
|
||||
if (menuTab) {
|
||||
uint8_t attr = 0;
|
||||
|
||||
if (m_posVert==0 && !s_noScroll) {
|
||||
attr = INVERS;
|
||||
|
||||
int8_t cc = curr;
|
||||
|
||||
if (scrollLR || (scrollRE && s_editMode < 0)) {
|
||||
cc = limit((int8_t)0, (int8_t)(curr - scrollLR + scrollRE), (int8_t)(menuTabSize-1));
|
||||
}
|
||||
|
||||
switch(event) {
|
||||
case EVT_KEY_FIRST(KEY_LEFT):
|
||||
if (curr > 0)
|
||||
cc = curr - 1;
|
||||
else
|
||||
cc = menuTabSize-1;
|
||||
break;
|
||||
|
||||
case EVT_KEY_FIRST(KEY_RIGHT):
|
||||
if (curr < (menuTabSize-1))
|
||||
cc = curr + 1;
|
||||
else
|
||||
cc = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cc != curr) {
|
||||
chainMenu((MenuFuncP)pgm_read_adr(&menuTab[cc]));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
s_noScroll = 0;
|
||||
DisplayScreenIndex(curr, menuTabSize, attr);
|
||||
}
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
else if (m_posVert < 0) {
|
||||
lcd_putsAtt(DISPLAY_W-LEN_BACK*FW, 0, STR_BACK, INVERS);
|
||||
}
|
||||
#endif
|
||||
|
||||
DISPLAY_PROGRESS_BAR(menuTab ? lcd_lastPos-2*FW-((curr+1)/10*FWNUM)-2 : 20*FW+1);
|
||||
|
||||
if (s_editMode<=0) {
|
||||
if (scrollUD) {
|
||||
m_posVert = limit((int8_t)0, (int8_t)(m_posVert - scrollUD), (int8_t)maxrow);
|
||||
m_posHorz = min(m_posHorz, MAXCOL(m_posVert));
|
||||
BLINK_SYNC;
|
||||
}
|
||||
|
||||
if (scrollLR && m_posVert>0) {
|
||||
m_posHorz = limit((int8_t)0, (int8_t)(m_posHorz - scrollLR), (int8_t)maxcol);
|
||||
BLINK_SYNC;
|
||||
}
|
||||
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
while (!s_editMode && scrollRE) {
|
||||
if (scrollRE > 0) {
|
||||
--scrollRE;
|
||||
maxcol = MAXCOL(m_posVert);
|
||||
if (maxcol & ZCHAR) maxcol = 0;
|
||||
if (++m_posHorz > maxcol) {
|
||||
if (m_posVert < maxrow) {
|
||||
++m_posVert;
|
||||
maxcol = MAXCOL(m_posVert); // TODO not stored into maxcol?
|
||||
if (maxcol < 0) m_posVert++;
|
||||
m_posHorz = 0;
|
||||
}
|
||||
else {
|
||||
--m_posHorz;
|
||||
scrollRE = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
++scrollRE;
|
||||
if (m_posHorz-- == 0) {
|
||||
if (m_posVert-- <= 0) {
|
||||
m_posVert = menuTab ? 0 : -1;
|
||||
m_posHorz = 0;
|
||||
scrollRE = 0;
|
||||
}
|
||||
else {
|
||||
maxcol = MAXCOL(m_posVert);
|
||||
if (maxcol < 0) { --m_posVert; maxcol = MAXCOL(m_posVert); }
|
||||
m_posHorz = maxcol;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
switch(event)
|
||||
{
|
||||
case EVT_ENTRY:
|
||||
minit();
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
if (menuTab) {
|
||||
s_editMode = -1;
|
||||
break;
|
||||
}
|
||||
// no break
|
||||
#else
|
||||
s_editMode = -1;
|
||||
break;
|
||||
#endif
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
case EVT_ENTRY_UP:
|
||||
s_editMode = 0;
|
||||
break;
|
||||
#endif
|
||||
case EVT_KEY_FIRST(KEY_MENU):
|
||||
if (!menuTab || m_posVert>0)
|
||||
s_editMode = (s_editMode<=0);
|
||||
break;
|
||||
case EVT_KEY_LONG(KEY_EXIT):
|
||||
s_editMode = 0;
|
||||
popMenu();
|
||||
break;
|
||||
case EVT_KEY_BREAK(KEY_EXIT):
|
||||
if(s_editMode>0) {
|
||||
s_editMode = 0;
|
||||
break;
|
||||
}
|
||||
if (m_posVert==0 || !menuTab) {
|
||||
popMenu(); //beeps itself
|
||||
}
|
||||
else {
|
||||
AUDIO_MENUS();
|
||||
minit();
|
||||
BLINK_SYNC;
|
||||
}
|
||||
break;
|
||||
|
||||
case EVT_KEY_REPT(KEY_RIGHT): //inc
|
||||
if(m_posHorz==maxcol) break;
|
||||
case EVT_KEY_FIRST(KEY_RIGHT)://inc
|
||||
if(!horTab || s_editMode>0)break;
|
||||
INC(m_posHorz,maxcol);
|
||||
BLINK_SYNC;
|
||||
break;
|
||||
|
||||
case EVT_KEY_REPT(KEY_LEFT): //dec
|
||||
if(m_posHorz==0) break;
|
||||
case EVT_KEY_FIRST(KEY_LEFT)://dec
|
||||
if(!horTab || s_editMode>0)break;
|
||||
DEC(m_posHorz,maxcol);
|
||||
BLINK_SYNC;
|
||||
break;
|
||||
|
||||
case EVT_KEY_REPT(KEY_DOWN): //inc
|
||||
if(m_posVert==maxrow) break;
|
||||
case EVT_KEY_FIRST(KEY_DOWN): //inc
|
||||
if(s_editMode>0)break;
|
||||
do {
|
||||
INC(m_posVert, maxrow);
|
||||
} while(MAXCOL(m_posVert) == (uint8_t)-1);
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
s_editMode = 0;
|
||||
#endif
|
||||
m_posHorz = min(m_posHorz, MAXCOL(m_posVert));
|
||||
BLINK_SYNC;
|
||||
break;
|
||||
|
||||
case EVT_KEY_REPT(KEY_UP): //dec
|
||||
if(m_posVert==0) break;
|
||||
case EVT_KEY_FIRST(KEY_UP): //dec
|
||||
if(s_editMode>0)break;
|
||||
do {
|
||||
DEC(m_posVert,maxrow);
|
||||
} while(MAXCOL(m_posVert) == (uint8_t)-1);
|
||||
m_posHorz = min(m_posHorz, MAXCOL(m_posVert));
|
||||
BLINK_SYNC;
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t max = menuTab ? 7 : 6;
|
||||
if(m_posVert<1) s_pgOfs=0;
|
||||
else if(m_posVert-s_pgOfs>max) s_pgOfs = m_posVert-max;
|
||||
else if(m_posVert-s_pgOfs<1) s_pgOfs = m_posVert-1;
|
||||
return true;
|
||||
}
|
||||
|
||||
MenuFuncP g_menuStack[5];
|
||||
uint8_t g_menuPos[4];
|
||||
uint8_t g_menuStackPtr = 0;
|
||||
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
int8_t m_posVert;
|
||||
#else
|
||||
uint8_t m_posVert;
|
||||
#endif
|
||||
uint8_t m_posHorz;
|
||||
|
||||
void popMenu()
|
||||
{
|
||||
if (g_menuStackPtr>0) {
|
||||
g_menuStackPtr = g_menuStackPtr-1;
|
||||
AUDIO_KEYPAD_UP();
|
||||
m_posHorz = 0;
|
||||
m_posVert = g_menuPos[g_menuStackPtr];
|
||||
(*g_menuStack[g_menuStackPtr])(EVT_ENTRY_UP);
|
||||
}
|
||||
else {
|
||||
alert(STR_MENUSERROR);
|
||||
}
|
||||
}
|
||||
|
||||
void chainMenu(MenuFuncP newMenu)
|
||||
{
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
s_warning = NULL;
|
||||
#endif
|
||||
g_menuStack[g_menuStackPtr] = newMenu;
|
||||
(*newMenu)(EVT_ENTRY);
|
||||
AUDIO_MENUS();
|
||||
}
|
||||
|
||||
void pushMenu(MenuFuncP newMenu)
|
||||
{
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
s_warning = NULL;
|
||||
#endif
|
||||
|
||||
g_menuPos[g_menuStackPtr] = m_posVert;
|
||||
|
||||
g_menuStackPtr++;
|
||||
if(g_menuStackPtr >= DIM(g_menuStack))
|
||||
{
|
||||
g_menuStackPtr--;
|
||||
alert(STR_MENUSERROR);
|
||||
return;
|
||||
}
|
||||
AUDIO_MENUS();
|
||||
g_menuStack[g_menuStackPtr] = newMenu;
|
||||
(*newMenu)(EVT_ENTRY);
|
||||
}
|
||||
|
||||
const pm_char * s_warning = 0;
|
||||
const pm_char * s_warning_info;
|
||||
uint8_t s_warning_info_len;
|
||||
// uint8_t s_warning_info_att not needed now
|
||||
uint8_t s_confirmation = 0;
|
||||
|
||||
void displayBox()
|
||||
{
|
||||
lcd_filled_rect(10, 16, 108, 40, SOLID, WHITE);
|
||||
lcd_rect(10, 16, 108, 40);
|
||||
lcd_puts(16, 3*FH, s_warning);
|
||||
// could be a place for a s_warning_info
|
||||
}
|
||||
|
||||
void displayPopup(const pm_char * pstr)
|
||||
{
|
||||
s_warning = pstr;
|
||||
displayBox();
|
||||
s_warning = 0;
|
||||
refreshDisplay();
|
||||
}
|
||||
|
||||
void displayWarning(uint8_t event)
|
||||
{
|
||||
if (s_warning) {
|
||||
displayBox();
|
||||
lcd_puts(16, 5*FH, STR_EXIT);
|
||||
switch(event) {
|
||||
case EVT_KEY_FIRST(KEY_EXIT):
|
||||
killEvents(event);
|
||||
s_warning = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void displayConfirmation(uint8_t event)
|
||||
{
|
||||
s_confirmation = false;
|
||||
displayBox();
|
||||
if (s_warning_info)
|
||||
lcd_putsnAtt(16, 4*FH, s_warning_info, s_warning_info_len, ZCHAR);
|
||||
lcd_puts(16, 5*FH, STR_POPUPS);
|
||||
|
||||
switch(event) {
|
||||
case EVT_KEY_FIRST(KEY_MENU):
|
||||
s_confirmation = true;
|
||||
// no break
|
||||
case EVT_KEY_FIRST(KEY_EXIT):
|
||||
killEvents(event);
|
||||
s_warning = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(SDCARD)
|
||||
const char *s_menu[MENU_MAX_LINES];
|
||||
char s_bss_menu[MENU_MAX_LINES*MENU_LINE_LENGTH];
|
||||
uint8_t s_menu_item = 0;
|
||||
uint8_t s_menu_count = 0;
|
||||
uint8_t s_menu_flags = 0;
|
||||
uint8_t s_menu_offset = 0;
|
||||
bool s_menu_more = false;
|
||||
const char * displayMenu(uint8_t event)
|
||||
{
|
||||
const char * result = NULL;
|
||||
|
||||
lcd_filled_rect(10, 16, 108, s_menu_count * (FH+1) + 2, SOLID, WHITE);
|
||||
lcd_rect(10, 16, 108, s_menu_count * (FH+1) + 2);
|
||||
|
||||
for (uint8_t i=0; i<s_menu_count; i++) {
|
||||
lcd_putsAtt(16, i*(FH+1) + 2*FH + 2, s_menu[i], s_menu_flags);
|
||||
if (i == s_menu_item) lcd_filled_rect(11, i*(FH+1) + 2*FH + 1, 106, 9);
|
||||
}
|
||||
|
||||
switch(event) {
|
||||
case EVT_KEY_FIRST(KEY_UP):
|
||||
if (s_menu_item > 0)
|
||||
s_menu_item--;
|
||||
else if (s_menu_offset > 0) {
|
||||
s_menu_offset--;
|
||||
result = STR_UPDATE_LIST;
|
||||
}
|
||||
break;
|
||||
case EVT_KEY_FIRST(KEY_DOWN):
|
||||
if (s_menu_item < s_menu_count - 1)
|
||||
s_menu_item++;
|
||||
else if (s_menu_more) {
|
||||
s_menu_offset++;
|
||||
result = STR_UPDATE_LIST;
|
||||
}
|
||||
break;
|
||||
case EVT_KEY_FIRST(KEY_MENU):
|
||||
result = s_menu[s_menu_item];
|
||||
// no break
|
||||
case EVT_KEY_FIRST(KEY_EXIT):
|
||||
killEvents(event);
|
||||
s_menu_count = 0;
|
||||
s_menu_item = 0;
|
||||
s_menu_flags = 0;
|
||||
s_menu_offset = 0;
|
||||
s_menu_more = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
int8_t *s_inflight_value = NULL;
|
||||
int8_t s_inflight_min;
|
||||
int8_t s_inflight_max;
|
||||
int8_t s_inflight_shift;
|
||||
uint8_t s_inflight_bitshift;
|
||||
const pm_char *s_inflight_label;
|
||||
|
||||
void checkInFlightIncDecModel(uint8_t event, int8_t *value, int8_t i_min, int8_t i_max, int8_t i_shift, const pm_char *label, uint8_t bitshift)
|
||||
{
|
||||
*value = (((uint8_t)(*value)) & ((1 << bitshift) - 1)) + ((i_shift + checkIncDecModel(event, (((uint8_t)(*value)) >> bitshift)-i_shift, i_min, i_max)) << bitshift);
|
||||
|
||||
if (g_eeGeneral.reNavigation && event == EVT_KEY_LONG(BTN_REa+g_eeGeneral.reNavigation-1)) {
|
||||
if (value == s_inflight_value) {
|
||||
s_inflight_value = NULL;
|
||||
}
|
||||
else {
|
||||
s_inflight_value = value;
|
||||
s_inflight_min = i_min;
|
||||
s_inflight_max = i_max;
|
||||
s_inflight_shift = i_shift;
|
||||
s_inflight_label = label;
|
||||
s_inflight_bitshift = bitshift;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,213 +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 menus_h
|
||||
#define menus_h
|
||||
|
||||
#define NO_HI_LEN 25
|
||||
|
||||
#define RESX 1024
|
||||
#define RESXu 1024u
|
||||
#define RESXul 1024ul
|
||||
#define RESXl 1024l
|
||||
#define RESKul 100ul
|
||||
#define RESX_PLUS_TRIM (RESX+128)
|
||||
|
||||
typedef void (*MenuFuncP)(uint8_t event);
|
||||
|
||||
void DisplayScreenIndex(uint8_t index, uint8_t count, uint8_t attr);
|
||||
|
||||
extern uint8_t s_pgOfs;
|
||||
extern uint8_t s_noHi;
|
||||
extern uint8_t s_noScroll;
|
||||
|
||||
void menu_lcd_onoff(uint8_t x, uint8_t y, uint8_t value, uint8_t mode);
|
||||
|
||||
extern MenuFuncP g_menuStack[5];
|
||||
extern uint8_t g_menuStackPtr;
|
||||
|
||||
/// goto given Menu, but substitute current menu in menuStack
|
||||
void chainMenu(MenuFuncP newMenu);
|
||||
/// goto given Menu, store current menu in menuStack
|
||||
void pushMenu(MenuFuncP newMenu);
|
||||
/// return to last menu in menustack
|
||||
void popMenu();
|
||||
///deliver address of last menu which was popped from
|
||||
inline MenuFuncP lastPopMenu()
|
||||
{
|
||||
return g_menuStack[g_menuStackPtr+1];
|
||||
}
|
||||
|
||||
void doMainScreenGrphics();
|
||||
void menuMainView(uint8_t event);
|
||||
#ifdef FRSKY
|
||||
void menuProcFrsky(uint8_t event);
|
||||
#endif
|
||||
void menuProcSetup(uint8_t event);
|
||||
void menuProcModelSelect(uint8_t event);
|
||||
void menuProcFunctionSwitches(uint8_t event);
|
||||
void menuProcStatistic(uint8_t event);
|
||||
void menuProcDebug(uint8_t event);
|
||||
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
extern int8_t scrollRE;
|
||||
extern int16_t p1valdiff;
|
||||
#define IS_RE_NAVIGATION_EVT_TYPE(event, type) (g_eeGeneral.reNavigation && event==type(BTN_REa + g_eeGeneral.reNavigation - 1))
|
||||
#define IS_RE_NAVIGATION_EVT(event) (g_eeGeneral.reNavigation && (event&EVT_KEY_MASK)==(BTN_REa + g_eeGeneral.reNavigation - 1))
|
||||
#else
|
||||
#define IS_RE_NAVIGATION_EVT_TYPE(event, type) (0)
|
||||
#define IS_RE_NAVIGATION_EVT(event) (0)
|
||||
#if defined(NAVIGATION_POT1)
|
||||
extern int16_t p1valdiff;
|
||||
#else
|
||||
#define p1valdiff 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern int8_t checkIncDec_Ret; // global helper vars
|
||||
extern int8_t s_editMode; // global editmode
|
||||
|
||||
// checkIncDec flags
|
||||
#define EE_GENERAL 0x01
|
||||
#define EE_MODEL 0x02
|
||||
#define NO_INCDEC_MARKS 0x04
|
||||
#define INCDEC_SWITCH 0x08
|
||||
int16_t checkIncDec(uint8_t event, int16_t i_pval, int16_t i_min, int16_t i_max, uint8_t i_flags);
|
||||
int8_t checkIncDecModel(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max);
|
||||
int8_t checkIncDecGen(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max);
|
||||
|
||||
#define CHECK_INCDEC_MODELVAR(event, var, min, max) \
|
||||
var = checkIncDecModel(event,var,min,max)
|
||||
|
||||
#if defined(AUTOSWITCH)
|
||||
#define CHECK_INCDEC_MODELSWITCH(event, var, min, max) \
|
||||
var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SWITCH)
|
||||
#else
|
||||
#define CHECK_INCDEC_MODELSWITCH CHECK_INCDEC_MODELVAR
|
||||
#endif
|
||||
|
||||
#define CHECK_INCDEC_GENVAR(event, var, min, max) \
|
||||
var = checkIncDecGen(event,var,min,max)
|
||||
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
extern int8_t *s_inflight_value;
|
||||
extern const pm_char *s_inflight_label;
|
||||
extern int8_t s_inflight_min;
|
||||
extern int8_t s_inflight_max;
|
||||
extern int8_t s_inflight_shift;
|
||||
extern uint8_t s_inflight_bitshift;
|
||||
#define PREPARE_INFLIGHT_BITFIELD(a) int8_t *bitfield = (a)
|
||||
#define INFLIGHT(val) (s_inflight_value==&val ? SURROUNDED : 0)
|
||||
void checkInFlightIncDecModel(uint8_t event, int8_t *value, int8_t i_min, int8_t i_max, int8_t i_shift, const pm_char *label, uint8_t bitshift=0);
|
||||
#define CHECK_INFLIGHT_INCDEC_MODELVAR(event, var, imin, imax, ishift, label) \
|
||||
checkInFlightIncDecModel(event, &var, imin, imax, ishift, label)
|
||||
#define CHECK_INFLIGHT_INCDEC_MODELVAR_BITFIELD(event, var, imin, imax, ishift, label, bitshift) \
|
||||
checkInFlightIncDecModel(event, bitfield, imin, imax, ishift, label, bitshift);
|
||||
void check_rotary_encoder();
|
||||
#else
|
||||
#define PREPARE_INFLIGHT_BITFIELD(a)
|
||||
#define INFLIGHT(val) 0
|
||||
#define CHECK_INFLIGHT_INCDEC_MODELVAR(event, var, min, max, shift, label) \
|
||||
var = shift+checkIncDecModel(event,var-(shift),min,max)
|
||||
#define CHECK_INFLIGHT_INCDEC_MODELVAR_BITFIELD(event, var, min, max, shift, label, bitshift) \
|
||||
var = shift+checkIncDecModel(event,var-(shift),min,max)
|
||||
#endif
|
||||
|
||||
// Menus related stuff ...
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
extern int8_t m_posVert;
|
||||
#else
|
||||
extern uint8_t m_posVert;
|
||||
#endif
|
||||
extern uint8_t m_posHorz;
|
||||
inline void minit(){m_posVert=m_posHorz=0;}
|
||||
bool check(uint8_t event, uint8_t curr, const MenuFuncP *menuTab, uint8_t menuTabSize, const pm_uint8_t *subTab, uint8_t subTabMax, uint8_t maxrow);
|
||||
bool check_simple(uint8_t event, uint8_t curr, const MenuFuncP *menuTab, uint8_t menuTabSize, uint8_t maxrow);
|
||||
bool check_submenu_simple(uint8_t event, uint8_t maxrow);
|
||||
|
||||
typedef void (*MenuFuncP_PROGMEM)(uint8_t event);
|
||||
|
||||
#define TITLEP(pstr) lcd_putsAtt(0,0,pstr,INVERS)
|
||||
#define TITLE(str) TITLEP(str)
|
||||
|
||||
#define MENU(title, tab, menu, lines_count, ...) \
|
||||
static const pm_uint8_t mstate_tab[] PROGMEM = __VA_ARGS__; \
|
||||
if (!check(event,menu,tab,DIM(tab),mstate_tab,DIM(mstate_tab)-1,(lines_count)-1)) return; \
|
||||
TITLE(title)
|
||||
|
||||
#define SIMPLE_MENU_NOTITLE(tab, menu, lines_count) \
|
||||
if (!check_simple(event,menu,tab,DIM(tab),(lines_count)-1)) return;
|
||||
|
||||
#define SIMPLE_MENU(title, tab, menu, lines_count) \
|
||||
SIMPLE_MENU_NOTITLE(tab, menu, lines_count); \
|
||||
TITLE(title)
|
||||
|
||||
#define SUBMENU(title, lines_count, ...) \
|
||||
static const pm_uint8_t mstate_tab[] PROGMEM = __VA_ARGS__; \
|
||||
if (!check(event,0,NULL,0,mstate_tab,DIM(mstate_tab)-1,(lines_count)-1)) return; \
|
||||
TITLE(title)
|
||||
|
||||
#define SIMPLE_SUBMENU_NOTITLE(lines_count) \
|
||||
if (!check_submenu_simple(event,(lines_count)-1)) return;
|
||||
|
||||
#define SIMPLE_SUBMENU(title, lines_count) \
|
||||
SIMPLE_SUBMENU_NOTITLE(lines_count); \
|
||||
TITLE(title)
|
||||
|
||||
extern const pm_char * s_warning;
|
||||
extern const pm_char * s_warning_info;
|
||||
extern uint8_t s_warning_info_len;
|
||||
extern uint8_t s_confirmation;
|
||||
|
||||
void displayBox();
|
||||
void displayPopup(const pm_char * pstr);
|
||||
void displayWarning(uint8_t event);
|
||||
void displayConfirmation(uint8_t event);
|
||||
|
||||
#if defined(SDCARD)
|
||||
#define MENU_MAX_LINES 4
|
||||
#define MENU_LINE_LENGTH (8+1)
|
||||
extern const char *s_menu[MENU_MAX_LINES];
|
||||
extern char s_bss_menu[MENU_MAX_LINES*MENU_LINE_LENGTH];
|
||||
extern uint8_t s_menu_count;
|
||||
extern uint8_t s_menu_flags;
|
||||
extern uint8_t s_menu_offset;
|
||||
extern bool s_menu_more;
|
||||
const char * displayMenu(uint8_t event);
|
||||
extern const pm_char * s_sdcard_error;
|
||||
#else
|
||||
#define s_menu_count 0
|
||||
#define s_sdcard_error 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
-2515
File diff suppressed because it is too large
Load Diff
-586
@@ -1,586 +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 eeprom_h
|
||||
#define eeprom_h
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#define WARN_THR_BIT 0x01
|
||||
#define WARN_BEP_BIT 0x80
|
||||
#define WARN_SW_BIT 0x02
|
||||
#define WARN_MEM_BIT 0x04
|
||||
#define WARN_BVAL_BIT 0x38
|
||||
|
||||
#define WARN_THR (!(g_eeGeneral.warnOpts & WARN_THR_BIT))
|
||||
#define WARN_BEP (!(g_eeGeneral.warnOpts & WARN_BEP_BIT))
|
||||
#define WARN_SW (!(g_eeGeneral.warnOpts & WARN_SW_BIT))
|
||||
#define WARN_MEM (!(g_eeGeneral.warnOpts & WARN_MEM_BIT))
|
||||
#define BEEP_VAL ( (g_eeGeneral.warnOpts & WARN_BVAL_BIT) >>3 )
|
||||
|
||||
#if defined(PCBARM)
|
||||
#define EEPROM_VER 209
|
||||
#elif defined(PCBV4)
|
||||
#define EEPROM_VER 209
|
||||
#else
|
||||
#define EEPROM_VER 209
|
||||
#endif
|
||||
|
||||
#ifndef PACK
|
||||
#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))
|
||||
#endif
|
||||
|
||||
PACK(typedef struct t_TrainerMix {
|
||||
uint8_t srcChn:6; // 0-7 = ch1-8
|
||||
uint8_t mode:2; // off,add-mode,subst-mode
|
||||
int8_t studWeight;
|
||||
}) TrainerMix; //
|
||||
|
||||
PACK(typedef struct t_TrainerData {
|
||||
int16_t calib[4];
|
||||
TrainerMix mix[4];
|
||||
}) TrainerData;
|
||||
|
||||
PACK(typedef struct t_FrSkyRSSIAlarm {
|
||||
int8_t level:2;
|
||||
int8_t value:6;
|
||||
}) FrSkyRSSIAlarm;
|
||||
|
||||
enum MainViews {
|
||||
e_outputValues,
|
||||
e_outputBars,
|
||||
e_inputs,
|
||||
e_timer2,
|
||||
MAIN_VIEW_MAX = e_timer2
|
||||
};
|
||||
|
||||
enum BeeperMode {
|
||||
e_mode_quiet = -2,
|
||||
e_mode_alarms,
|
||||
e_mode_nokeys,
|
||||
e_mode_all
|
||||
};
|
||||
|
||||
#if defined(PCBARM)
|
||||
#define EXTRA_ARM_FIELDS \
|
||||
uint8_t speakerVolume; \
|
||||
uint8_t backlightBright; \
|
||||
int8_t currentCalib;
|
||||
#else
|
||||
#define EXTRA_ARM_FIELDS
|
||||
#endif
|
||||
|
||||
#define ALTERNATE_VIEW 0x10
|
||||
PACK(typedef struct t_EEGeneral {
|
||||
uint8_t myVers;
|
||||
int16_t calibMid[7];
|
||||
int16_t calibSpanNeg[7];
|
||||
int16_t calibSpanPos[7];
|
||||
uint16_t chkSum;
|
||||
uint8_t currModel; //0..15
|
||||
uint8_t contrast;
|
||||
uint8_t vBatWarn;
|
||||
int8_t vBatCalib;
|
||||
int8_t lightSw;
|
||||
TrainerData trainer;
|
||||
uint8_t view; //index of subview in main scrren
|
||||
uint8_t spare0:1;
|
||||
int8_t switchWarning:2; // -1=down, 0=off, 1=up
|
||||
int8_t beeperMode:2;
|
||||
uint8_t spare1:1;
|
||||
uint8_t disableMemoryWarning:1;
|
||||
uint8_t disableAlarmWarning:1;
|
||||
uint8_t stickMode:2;
|
||||
int8_t timezone:5;
|
||||
uint8_t optrexDisplay:1;
|
||||
uint8_t inactivityTimer;
|
||||
uint8_t throttleReversed:1;
|
||||
uint8_t minuteBeep:1;
|
||||
uint8_t preBeep:1;
|
||||
uint8_t flashBeep:1;
|
||||
uint8_t disableSplashScreen:1;
|
||||
uint8_t enableTelemetryAlarm:1; // 0=no, 1=yes (Sound alarm when there's no telem. data coming in)
|
||||
int8_t hapticMode:2; // -2=quiet, -1=only alarms, 0=no keys, 1=all
|
||||
uint8_t filterInput;
|
||||
uint8_t lightAutoOff;
|
||||
uint8_t templateSetup; //RETA order according to chout_ar array
|
||||
int8_t PPM_Multiplier;
|
||||
int8_t hapticLength;
|
||||
uint8_t reNavigation; // TODO not needed on stock board
|
||||
int8_t beeperLength:3;
|
||||
uint8_t hapticStrength:3;
|
||||
uint8_t gpsFormat:1;
|
||||
uint8_t unexpectedShutdown:1;
|
||||
uint8_t speakerPitch;
|
||||
|
||||
EXTRA_ARM_FIELDS
|
||||
|
||||
}) EEGeneral;
|
||||
|
||||
// eeprom modelspec
|
||||
|
||||
#if defined(PCBARM)
|
||||
PACK(typedef struct t_ExpoData {
|
||||
uint8_t mode; // 0=end, 1=pos, 2=neg, 3=both
|
||||
uint8_t chn;
|
||||
int8_t curve; // 0=no curve, 1-6=std curves, 7-10=CV1-CV4, 11-15=CV9-CV13
|
||||
int8_t swtch;
|
||||
int8_t phase; // if negPhase is 0: 0=normal, 5=FP4 if negPhase is 1: 5=!FP4
|
||||
uint8_t weight;
|
||||
int8_t expo;
|
||||
}) ExpoData;
|
||||
#else
|
||||
PACK(typedef struct t_ExpoData {
|
||||
uint8_t mode:2; // 0=end, 1=pos, 2=neg, 3=both
|
||||
uint8_t chn:2;
|
||||
uint8_t curve:4; // 0=no curve, 1-6=std curves, 7-10=CV1-CV4, 11-15=CV9-CV13
|
||||
int8_t swtch:5;
|
||||
uint8_t phase:3; // if negPhase is 0: 0=normal, 5=FP4 if negPhase is 1: 5=!FP4
|
||||
uint8_t negPhase:1;
|
||||
uint8_t weight:7;
|
||||
int8_t expo;
|
||||
}) ExpoData;
|
||||
#endif
|
||||
|
||||
PACK(typedef struct t_LimitData {
|
||||
int8_t min;
|
||||
int8_t max;
|
||||
bool revert;
|
||||
int16_t offset;
|
||||
}) LimitData;
|
||||
|
||||
enum MixSources {
|
||||
MIXSRC_Rud = 1,
|
||||
MIXSRC_Ele,
|
||||
MIXSRC_Thr,
|
||||
MIXSRC_Ail,
|
||||
MIXSRC_P1,
|
||||
MIXSRC_P2,
|
||||
MIXSRC_P3,
|
||||
#if defined(PCBV4)
|
||||
MIXSRC_REa,
|
||||
MIXSRC_REb,
|
||||
#if defined(EXTRA_ROTARY_ENCODERS)
|
||||
MIXSRC_REc,
|
||||
MIXSRC_REd,
|
||||
MIXSRC_REe,
|
||||
#endif
|
||||
#endif
|
||||
MIXSRC_TrimRud,
|
||||
MIXSRC_TrimEle,
|
||||
MIXSRC_TrimThr,
|
||||
MIXSRC_TrimAil,
|
||||
MIXSRC_MAX ,
|
||||
MIXSRC_3POS,
|
||||
MIXSRC_THR,
|
||||
MIXSRC_RUD,
|
||||
MIXSRC_ELE,
|
||||
MIXSRC_ID0,
|
||||
MIXSRC_ID1,
|
||||
MIXSRC_ID2,
|
||||
MIXSRC_AIL,
|
||||
MIXSRC_GEA,
|
||||
MIXSRC_TRN,
|
||||
MIXSRC_SW1,
|
||||
MIXSRC_SW9 = MIXSRC_SW1 + 8,
|
||||
MIXSRC_SWA,
|
||||
MIXSRC_SWB,
|
||||
MIXSRC_SWC,
|
||||
MIXSRC_CYC1,
|
||||
MIXSRC_CYC2,
|
||||
MIXSRC_CYC3,
|
||||
MIXSRC_PPM1,
|
||||
MIXSRC_PPM8 = MIXSRC_PPM1 + 7,
|
||||
MIXSRC_CH1,
|
||||
MIXSRC_CH9 = MIXSRC_CH1 + 8,
|
||||
MIXSRC_CH10,
|
||||
MIXSRC_CH11,
|
||||
MIXSRC_CH16 = MIXSRC_CH11 + 5
|
||||
};
|
||||
|
||||
#define TRIM_OFF 1
|
||||
#define TRIM_ON 0
|
||||
#define TRIM_RUD -1
|
||||
#define TRIM_ELE -2
|
||||
#define TRIM_THR -3
|
||||
#define TRIM_AIL -4
|
||||
|
||||
#define MLTPX_ADD 0
|
||||
#define MLTPX_MUL 1
|
||||
#define MLTPX_REP 2
|
||||
|
||||
#if defined(PCBARM)
|
||||
PACK(typedef struct t_MixData {
|
||||
uint8_t destCh;
|
||||
int8_t phase;
|
||||
int8_t weight;
|
||||
int8_t swtch;
|
||||
uint8_t mltpx; // multiplex method: 0 means +=, 1 means *=, 2 means :=
|
||||
int8_t curve;
|
||||
uint8_t mixWarn; // mixer warning
|
||||
uint8_t delayUp;
|
||||
uint8_t delayDown;
|
||||
uint8_t speedUp; // Servogeschwindigkeit aus Tabelle (10ms Cycle)
|
||||
uint8_t speedDown; // 0 nichts
|
||||
uint8_t srcRaw; //
|
||||
int8_t differential;
|
||||
int8_t carryTrim;
|
||||
int8_t sOffset;
|
||||
}) MixData;
|
||||
#else
|
||||
PACK(typedef struct t_MixData {
|
||||
uint8_t destCh:4; // 0, 1..NUM_CHNOUT
|
||||
int8_t phase:4; // -5=!FP4, 0=normal, 5=FP4
|
||||
int8_t weight;
|
||||
int8_t swtch:6;
|
||||
uint8_t mltpx:2; // multiplex method: 0 means +=, 1 means *=, 2 means :=
|
||||
int8_t curve:6;
|
||||
uint8_t mixWarn:2; // mixer warning
|
||||
uint8_t delayUp:4;
|
||||
uint8_t delayDown:4;
|
||||
uint8_t speedUp:4; // Servogeschwindigkeit aus Tabelle (10ms Cycle)
|
||||
uint8_t speedDown:4; // 0 nichts
|
||||
uint16_t srcRaw:6; //
|
||||
int16_t differential:7;
|
||||
int16_t carryTrim:3;
|
||||
int8_t sOffset;
|
||||
}) MixData;
|
||||
#endif
|
||||
|
||||
PACK(typedef struct t_CustomSwData { // Custom Switches data
|
||||
int8_t v1; //input
|
||||
int8_t v2; //offset
|
||||
uint8_t func;
|
||||
}) CustomSwData;
|
||||
|
||||
enum Functions {
|
||||
FUNC_SAFETY_CH1,
|
||||
FUNC_SAFETY_CH16=FUNC_SAFETY_CH1+15,
|
||||
FUNC_TRAINER,
|
||||
FUNC_TRAINER_RUD,
|
||||
FUNC_TRAINER_ELE,
|
||||
FUNC_TRAINER_THR,
|
||||
FUNC_TRAINER_AIL,
|
||||
FUNC_INSTANT_TRIM,
|
||||
FUNC_PLAY_SOUND,
|
||||
FUNC_HAPTIC,
|
||||
#if defined(PCBV4)
|
||||
FUNC_PLAY_SOMO,
|
||||
#endif
|
||||
FUNC_RESET,
|
||||
FUNC_VARIO,
|
||||
#if defined(PCBV4)
|
||||
FUNC_LOGS,
|
||||
#endif
|
||||
#if defined(DEBUG)
|
||||
FUNC_TEST, // should remain the last before MAX as not added in companion9x
|
||||
#endif
|
||||
FUNC_MAX
|
||||
};
|
||||
|
||||
PACK(typedef struct t_FuncSwData { // Function Switches data
|
||||
int8_t swtch; //input
|
||||
uint8_t func;
|
||||
uint8_t param;
|
||||
}) FuncSwData;
|
||||
|
||||
enum TelemetryUnit {
|
||||
UNIT_VOLTS,
|
||||
UNIT_AMPS,
|
||||
UNIT_METERS_PER_SECOND,
|
||||
UNIT_RAW,
|
||||
UNIT_KMH,
|
||||
UNIT_KTS = UNIT_KMH,
|
||||
UNIT_METERS,
|
||||
UNIT_DEGREES,
|
||||
UNIT_PERCENT,
|
||||
UNIT_MILLIAMPS,
|
||||
UNIT_MAX,
|
||||
UNIT_FEET
|
||||
};
|
||||
|
||||
PACK(typedef struct t_FrSkyChannelData {
|
||||
uint8_t ratio; // 0.0 means not used, 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc.
|
||||
int16_t offset:12;
|
||||
uint16_t type:4; // channel unit (0=volts, ...)
|
||||
uint8_t alarms_value[2]; // 0.1V steps EG. 6.6 Volts = 66. 25.1V = 251, etc.
|
||||
uint8_t alarms_level:4;
|
||||
uint8_t alarms_greater:2; // 0=LT(<), 1=GT(>)
|
||||
uint8_t multiplier:2; // 0=no multiplier, 1=*2 multiplier
|
||||
}) FrSkyChannelData;
|
||||
|
||||
enum TelemetrySource {
|
||||
TELEM_NONE,
|
||||
TELEM_TM1,
|
||||
TELEM_TM2,
|
||||
TELEM_A1,
|
||||
TELEM_A2,
|
||||
TELEM_RSSI_TX,
|
||||
TELEM_RSSI_RX,
|
||||
TELEM_ALT,
|
||||
TELEM_RPM,
|
||||
TELEM_FUEL,
|
||||
TELEM_T1,
|
||||
TELEM_T2,
|
||||
TELEM_SPEED,
|
||||
TELEM_DIST,
|
||||
TELEM_GPSALT,
|
||||
TELEM_CELL,
|
||||
TELEM_ACCx,
|
||||
TELEM_ACCy,
|
||||
TELEM_ACCz,
|
||||
TELEM_HDG,
|
||||
TELEM_VSPD,
|
||||
TELEM_MIN_A1,
|
||||
TELEM_MIN_A2,
|
||||
TELEM_MIN_ALT,
|
||||
TELEM_MAX_ALT,
|
||||
TELEM_MAX_RPM,
|
||||
TELEM_MAX_T1,
|
||||
TELEM_MAX_T2,
|
||||
TELEM_MAX_SPEED,
|
||||
TELEM_MAX_DIST,
|
||||
TELEM_ACC,
|
||||
TELEM_GPS_TIME,
|
||||
TELEM_BAR_MAX = TELEM_CELL,
|
||||
TELEM_NOUSR_BAR_MAX = TELEM_RSSI_RX,
|
||||
TELEM_CSW_MAX = TELEM_CELL,
|
||||
TELEM_NOUSR_CSW_MAX = TELEM_RSSI_RX,
|
||||
TELEM_DISPLAY_MAX = TELEM_MAX_DIST,
|
||||
TELEM_STATUS_MAX = TELEM_GPS_TIME
|
||||
};
|
||||
|
||||
enum VarioSource {
|
||||
VARIO_SOURCE_FIRST = 0,
|
||||
VARIO_SOURCE_BARO_V1 = 0,
|
||||
VARIO_SOURCE_BARO_V2,
|
||||
VARIO_SOURCE_A1,
|
||||
VARIO_SOURCE_A2,
|
||||
VARIO_SOURCE_LAST
|
||||
};
|
||||
|
||||
PACK(typedef struct t_FrSkyBarData {
|
||||
uint16_t source:4;
|
||||
uint16_t barMin:6; // minimum for bar display
|
||||
uint16_t barMax:6; // ditto for max display (would usually = ratio)
|
||||
}) FrSkyBarData;
|
||||
|
||||
enum FrskyUsrProtocols {
|
||||
PROTO_NONE,
|
||||
PROTO_FRSKY_HUB,
|
||||
PROTO_WS_HOW_HIGH
|
||||
};
|
||||
|
||||
PACK(typedef struct t_FrSkyData {
|
||||
FrSkyChannelData channels[2];
|
||||
uint8_t usrProto:3; // Protocol in FrSky user data, 0=None, 1=FrSky hub, 2=WS HowHigh
|
||||
uint8_t imperial:1;
|
||||
uint8_t blades:2; // How many blades for RPMs, 0=2 blades, 1=3 blades
|
||||
uint8_t spare:2;
|
||||
FrSkyBarData bars[4];
|
||||
FrSkyRSSIAlarm rssiAlarms[2];
|
||||
}) FrSkyData;
|
||||
|
||||
#ifdef MAVLINK
|
||||
#define ROTARY_TYPE_OFF 0
|
||||
#define ROTARY_TYPE_PPM 1
|
||||
#define ROTARY_TYPE_MAVLINK 2
|
||||
#define NUM_ROTARY_SW 8
|
||||
#define MAX_MODES_VAL 16
|
||||
PACK(typedef struct t_RotarySwChannelData {
|
||||
uint8_t typeRotary:2; // see defines ROTARY_TYPE
|
||||
uint8_t numMode:6; // num mode
|
||||
}) RotarySwChannelData;
|
||||
|
||||
PACK(typedef struct t_MavlinkData {
|
||||
RotarySwChannelData rotarySw[NUM_ROTARY_SW];
|
||||
int8_t modesVal[MAX_MODES_VAL];
|
||||
}) MavlinkData;
|
||||
#endif
|
||||
|
||||
PACK(typedef struct t_SwashRingData { // Swash Ring data
|
||||
uint8_t invertELE:1;
|
||||
uint8_t invertAIL:1;
|
||||
uint8_t invertCOL:1;
|
||||
uint8_t type:5;
|
||||
uint8_t collectiveSource;
|
||||
uint8_t value;
|
||||
}) SwashRingData;
|
||||
|
||||
#define TRIM_EXTENDED_MAX 500
|
||||
#define TRIM_EXTENDED_MIN (-TRIM_EXTENDED_MAX)
|
||||
#define TRIM_MAX 125
|
||||
#define TRIM_MIN (-TRIM_MAX)
|
||||
|
||||
#if defined(PCBV4)
|
||||
#if defined(EXTRA_ROTARY_ENCODERS)
|
||||
#define NUM_EXTRA_ROTARY_ENCODERS 3
|
||||
#else
|
||||
#define NUM_EXTRA_ROTARY_ENCODERS 0
|
||||
#endif
|
||||
#define NUM_ROTARY_ENCODERS (2+NUM_EXTRA_ROTARY_ENCODERS)
|
||||
#define ROTARY_ENCODER_MAX 1024
|
||||
#define ROTARY_ENCODER_ARRAY int16_t rotaryEncoders[NUM_ROTARY_ENCODERS];
|
||||
#else
|
||||
#define NUM_ROTARY_ENCODERS 0
|
||||
#define ROTARY_ENCODER_ARRAY
|
||||
#endif
|
||||
|
||||
#if defined(PCBSTD)
|
||||
#define TRIM_ARRAY int8_t trim[4]; int8_t trim_ext:8
|
||||
#else
|
||||
#define TRIM_ARRAY int16_t trim[4]
|
||||
#endif
|
||||
|
||||
PACK(typedef struct t_PhaseData {
|
||||
TRIM_ARRAY;
|
||||
int8_t swtch; // swtch of phase[0] is not used
|
||||
char name[6];
|
||||
uint8_t fadeIn:4;
|
||||
uint8_t fadeOut:4;
|
||||
ROTARY_ENCODER_ARRAY
|
||||
}) PhaseData;
|
||||
|
||||
#if defined(PCBARM)
|
||||
#define MAX_MODELS 60
|
||||
#define NUM_CHNOUT 32 // number of real output channels CH1-CH32
|
||||
#define MAX_PHASES 9
|
||||
#define MAX_MIXERS 64
|
||||
#define MAX_EXPOS 32
|
||||
#define NUM_CSW 32 // number of custom switches
|
||||
#define NUM_FSW 32 // number of functions assigned to switches
|
||||
#elif defined(PCBV4)
|
||||
#define MAX_MODELS 30
|
||||
#define NUM_CHNOUT 16 // number of real output channels CH1-CH16
|
||||
#define MAX_PHASES 5
|
||||
#define MAX_MIXERS 32
|
||||
#define MAX_EXPOS 14
|
||||
#define NUM_CSW 12 // number of custom switches
|
||||
#define NUM_FSW 16 // number of functions assigned to switches
|
||||
#else
|
||||
#define MAX_MODELS 16
|
||||
#define NUM_CHNOUT 16 // number of real output channels CH1-CH16
|
||||
#define MAX_PHASES 5
|
||||
#define MAX_MIXERS 32
|
||||
#define MAX_EXPOS 14
|
||||
#define NUM_CSW 12 // number of custom switches
|
||||
#define NUM_FSW 16 // number of functions assigned to switches
|
||||
#endif
|
||||
|
||||
#define MAX_TIMERS 2
|
||||
#define MAX_CURVE5 8
|
||||
#define MAX_CURVE9 8
|
||||
|
||||
#define TMRMODE_NONE 0
|
||||
#define TMRMODE_ABS 1
|
||||
#define TMRMODE_THR 2
|
||||
#define TMRMODE_THR_REL 3
|
||||
#define TMRMODE_THR_TRG 4
|
||||
PACK(typedef struct t_TimerData {
|
||||
int8_t mode; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw
|
||||
uint16_t val;
|
||||
}) TimerData;
|
||||
|
||||
enum Protocols {
|
||||
PROTO_PPM,
|
||||
PROTO_PPM16,
|
||||
PROTO_PPMSIM,
|
||||
PROTO_PXX,
|
||||
PROTO_DSM2,
|
||||
PROTO_MAX
|
||||
};
|
||||
|
||||
enum Dsm2Variants {
|
||||
LPXDSM2,
|
||||
DSM2only,
|
||||
DSM2_DSMX
|
||||
};
|
||||
|
||||
#ifdef MAVLINK
|
||||
#define EXTDATA MavlinkData mavlink
|
||||
#else
|
||||
#define EXTDATA FrSkyData frsky
|
||||
#endif
|
||||
|
||||
#if defined(PCBV4) || defined(PCBARM)
|
||||
#define BeepANACenter uint16_t
|
||||
#else
|
||||
#define BeepANACenter uint8_t
|
||||
#endif
|
||||
|
||||
PACK(typedef struct t_ModelData {
|
||||
char name[10]; // must be first for eeLoadModelName
|
||||
TimerData 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 spare2:1;
|
||||
int8_t ppmDelay;
|
||||
BeepANACenter beepANACenter; // 1<<0->A1.. 1<<6->A7
|
||||
MixData mixData[MAX_MIXERS];
|
||||
LimitData limitData[NUM_CHNOUT];
|
||||
ExpoData expoData[MAX_EXPOS];
|
||||
int8_t curves5[MAX_CURVE5][5];
|
||||
int8_t curves9[MAX_CURVE9][9];
|
||||
CustomSwData customSw[NUM_CSW];
|
||||
FuncSwData funcSw[NUM_FSW];
|
||||
SwashRingData swashR;
|
||||
PhaseData phaseData[MAX_PHASES];
|
||||
|
||||
EXTDATA;
|
||||
|
||||
int8_t ppmFrameLength; // 0=22.5ms (10ms-30ms) 0.5msec increments
|
||||
uint8_t thrTraceSrc;
|
||||
uint8_t modelId;
|
||||
uint8_t frskyLines[4];
|
||||
uint16_t frskyLinesXtra;
|
||||
int8_t servoCenter[NUM_CHNOUT];
|
||||
|
||||
// TODO:temporary place, need to move to frskydata
|
||||
uint8_t varioSource:3;
|
||||
uint8_t varioSpeedUpMin:5; // if increment in 0.2m/s = 3.0m/s max
|
||||
uint8_t varioSpeedDownMin;
|
||||
}) ModelData;
|
||||
|
||||
extern EEGeneral g_eeGeneral;
|
||||
extern ModelData g_model;
|
||||
|
||||
#define TOTAL_EEPROM_USAGE (sizeof(ModelData)*MAX_MODELS + sizeof(EEGeneral))
|
||||
|
||||
#endif
|
||||
/*eof*/
|
||||
-400
@@ -1,400 +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 o9xstrings_h
|
||||
#define o9xstrings_h
|
||||
|
||||
#if defined(TRANSLATIONS_FR)
|
||||
#include "translations/fr.h"
|
||||
#define LEN_SPECIAL_CHARS 0
|
||||
#elif defined(TRANSLATIONS_IT)
|
||||
#include "translations/it.h"
|
||||
#define LEN_SPECIAL_CHARS 1
|
||||
#elif defined(TRANSLATIONS_SE)
|
||||
#include "translations/se.h"
|
||||
#define LEN_SPECIAL_CHARS 6
|
||||
#elif defined(TRANSLATIONS_DE)
|
||||
#include "translations/de.h"
|
||||
#define LEN_SPECIAL_CHARS 6
|
||||
#elif defined(TRANSLATIONS_CZ)
|
||||
#include "translations/cz.h"
|
||||
#define LEN_SPECIAL_CHARS 0
|
||||
#else
|
||||
#include "translations/en.h"
|
||||
#define LEN_SPECIAL_CHARS 0
|
||||
#endif
|
||||
|
||||
#define PSIZE(x) ( sizeof(x) - 1 )
|
||||
#define EOFS(x) ( OFS_##x + sizeof(TR_##x) )
|
||||
// The non-0-terminated-strings
|
||||
|
||||
extern const pm_char STR_OPEN9X[];
|
||||
|
||||
#define OFS_OFFON 0
|
||||
#define OFS_MMMINV (OFS_OFFON + sizeof(TR_OFFON))
|
||||
#define OFS_NCHANNELS (OFS_MMMINV + sizeof(TR_MMMINV))
|
||||
#define OFS_VBEEPMODE (OFS_NCHANNELS + sizeof(TR_NCHANNELS))
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
#define OFS_VRENAVIG (OFS_VBEEPMODE + sizeof(TR_VBEEPMODE))
|
||||
#define OFS_VFILTERADC (OFS_VRENAVIG + sizeof(TR_VRENAVIG))
|
||||
#else
|
||||
#define OFS_VFILTERADC (OFS_VBEEPMODE + sizeof(TR_VBEEPMODE))
|
||||
#endif
|
||||
#define OFS_WARNSW (OFS_VFILTERADC + sizeof(TR_VFILTERADC))
|
||||
#define OFS_TRNMODE (OFS_WARNSW + sizeof(TR_WARNSW))
|
||||
#define OFS_TRNCHN (OFS_TRNMODE + sizeof(TR_TRNMODE))
|
||||
#define OFS_VTRIMINC (OFS_TRNCHN + sizeof(TR_TRNCHN))
|
||||
#define OFS_RETA123 (OFS_VTRIMINC + sizeof(TR_VTRIMINC))
|
||||
#define OFS_VPROTOS (OFS_RETA123 + sizeof(TR_RETA123))
|
||||
#define OFS_POSNEG (OFS_VPROTOS + sizeof(TR_VPROTOS))
|
||||
#define OFS_VCURVEFUNC (OFS_POSNEG + sizeof(TR_POSNEG))
|
||||
#define OFS_CURVMODES (OFS_VCURVEFUNC + sizeof(TR_VCURVEFUNC))
|
||||
#define OFS_EXPLABELS (OFS_CURVMODES + sizeof(TR_CURVMODES))
|
||||
#define OFS_VMLTPX (OFS_EXPLABELS + sizeof(TR_EXPLABELS))
|
||||
#define OFS_VMLTPX2 (OFS_VMLTPX + sizeof(TR_VMLTPX))
|
||||
#define OFS_VMIXTRIMS (OFS_VMLTPX2 + sizeof(TR_VMLTPX2))
|
||||
#define OFS_VCSWFUNC (OFS_VMIXTRIMS + sizeof(TR_VMIXTRIMS))
|
||||
#define OFS_VFSWFUNC (OFS_VCSWFUNC + sizeof(TR_VCSWFUNC))
|
||||
#define OFS_VFSWRESET (OFS_VFSWFUNC + sizeof(TR_VFSWFUNC))
|
||||
#define OFS_FUNCSOUNDS (OFS_VFSWRESET + sizeof(TR_VFSWRESET))
|
||||
#define OFS_VTELEMCHNS (OFS_FUNCSOUNDS + sizeof(TR_FUNCSOUNDS))
|
||||
#if defined(FRSKY) || defined(PCBARM)
|
||||
#define OFS_VTELEMUNIT (OFS_VTELEMCHNS + sizeof(TR_VTELEMCHNS))
|
||||
#define OFS_VALARM (OFS_VTELEMUNIT + sizeof(TR_VTELEMUNIT))
|
||||
#define OFS_VALARMFN (OFS_VALARM + sizeof(TR_VALARM))
|
||||
#define OFS_VTELPROTO (OFS_VALARMFN + sizeof(TR_VALARMFN))
|
||||
#define OFS_GPSFORMAT (OFS_VTELPROTO + sizeof(TR_VTELPROTO))
|
||||
#define OFS_VARIOSRC (OFS_GPSFORMAT + sizeof(TR_GPSFORMAT))
|
||||
#define OFS_ENDTELEM (OFS_VARIOSRC + sizeof(TR_VARIOSRC))
|
||||
#else
|
||||
#define OFS_ENDTELEM (OFS_VTELEMCHNS + sizeof(TR_VTELEMCHNS))
|
||||
#endif
|
||||
#ifdef TEMPLATES
|
||||
#define OFS_VTEMPLATES (OFS_ENDTELEM)
|
||||
#define OFS_ENDTPLS (OFS_VTEMPLATES + sizeof(TR_VTEMPLATES))
|
||||
#else
|
||||
#define OFS_ENDTPLS (OFS_ENDTELEM)
|
||||
#endif
|
||||
#ifdef HELI
|
||||
#define OFS_VSWASHTYPE (OFS_ENDTPLS)
|
||||
#define OFS_ENDHELI (OFS_VSWASHTYPE + sizeof(TR_VSWASHTYPE))
|
||||
#else
|
||||
#define OFS_ENDHELI (OFS_ENDTPLS)
|
||||
#endif
|
||||
#define OFS_VKEYS (OFS_ENDHELI)
|
||||
#define OFS_VSWITCHES (OFS_VKEYS + sizeof(TR_VKEYS))
|
||||
#define OFS_VSRCRAW (OFS_VSWITCHES + sizeof(TR_VSWITCHES))
|
||||
#define OFS_VTMRMODES (OFS_VSRCRAW + sizeof(TR_VSRCRAW))
|
||||
#if defined(DSM2)
|
||||
#define OFS_DSM2MODE (OFS_VTMRMODES + sizeof(TR_VTMRMODES))
|
||||
#define OFS_ENDDSM2 (OFS_DSM2MODE + sizeof(TR_DSM2MODE))
|
||||
#else
|
||||
#define OFS_ENDDSM2 (OFS_VTMRMODES + sizeof(TR_VTMRMODES))
|
||||
#endif
|
||||
#if defined(PCBV4)
|
||||
#define OFS_RE1RE2 (OFS_ENDDSM2)
|
||||
#define OFS_DATETIME (OFS_RE1RE2 + sizeof(TR_RE1RE2))
|
||||
#endif
|
||||
|
||||
#define STR_OFFON (STR_OPEN9X + OFS_OFFON)
|
||||
#define STR_MMMINV (STR_OPEN9X + OFS_MMMINV)
|
||||
#define STR_NCHANNELS (STR_OPEN9X + OFS_NCHANNELS)
|
||||
#define STR_VBEEPMODE (STR_OPEN9X + OFS_VBEEPMODE)
|
||||
#define STR_VRENAVIG (STR_OPEN9X + OFS_VRENAVIG)
|
||||
#define STR_VFILTERADC (STR_OPEN9X + OFS_VFILTERADC)
|
||||
#define STR_WARNSW (STR_OPEN9X + OFS_WARNSW)
|
||||
#define STR_TRNMODE (STR_OPEN9X + OFS_TRNMODE)
|
||||
#define STR_TRNCHN (STR_OPEN9X + OFS_TRNCHN)
|
||||
#define STR_VTRIMINC (STR_OPEN9X + OFS_VTRIMINC)
|
||||
#define STR_RETA123 (STR_OPEN9X + OFS_RETA123)
|
||||
#define STR_VPROTOS (STR_OPEN9X + OFS_VPROTOS)
|
||||
#define STR_POSNEG (STR_OPEN9X + OFS_POSNEG)
|
||||
#define STR_VCURVEFUNC (STR_OPEN9X + OFS_VCURVEFUNC)
|
||||
#define STR_VWHEN STR_VCURVEFUNC
|
||||
#define LEN_VWHEN LEN_VCURVEFUNC
|
||||
#define STR_CURVMODES (STR_OPEN9X + OFS_CURVMODES)
|
||||
#define STR_EXPLABELS (STR_OPEN9X + OFS_EXPLABELS)
|
||||
#define STR_VMLTPX (STR_OPEN9X + OFS_VMLTPX)
|
||||
#define STR_VMLTPX2 (STR_OPEN9X + OFS_VMLTPX2)
|
||||
#define STR_VMIXTRIMS (STR_OPEN9X + OFS_VMIXTRIMS)
|
||||
#define STR_VCSWFUNC (STR_OPEN9X + OFS_VCSWFUNC)
|
||||
#define STR_VFSWFUNC (STR_OPEN9X + OFS_VFSWFUNC)
|
||||
#define STR_VFSWRESET (STR_OPEN9X + OFS_VFSWRESET)
|
||||
#define STR_FUNCSOUNDS (STR_OPEN9X + OFS_FUNCSOUNDS)
|
||||
#define STR_VTELEMCHNS (STR_OPEN9X + OFS_VTELEMCHNS)
|
||||
|
||||
#if defined(FRSKY) || defined(PCBARM)
|
||||
#define STR_VTELEMUNIT (STR_OPEN9X + OFS_VTELEMUNIT)
|
||||
#define STR_VALARM (STR_OPEN9X + OFS_VALARM)
|
||||
#define STR_VALARMFN (STR_OPEN9X + OFS_VALARMFN)
|
||||
#define STR_VTELPROTO (STR_OPEN9X + OFS_VTELPROTO)
|
||||
#define STR_GPSFORMAT (STR_OPEN9X + OFS_GPSFORMAT)
|
||||
#define STR_VARIOSRC (STR_OPEN9X + OFS_VARIOSRC)
|
||||
#define STR_TELEMCHNS (STR_OPEN9X + OFS_TELEMCHNS)
|
||||
#endif
|
||||
|
||||
#ifdef TEMPLATES
|
||||
#define STR_VTEMPLATES (STR_OPEN9X + OFS_VTEMPLATES)
|
||||
#endif
|
||||
|
||||
#ifdef HELI
|
||||
#define STR_VSWASHTYPE (STR_OPEN9X + OFS_VSWASHTYPE)
|
||||
#endif
|
||||
|
||||
#define STR_VKEYS (STR_OPEN9X + OFS_VKEYS)
|
||||
#define STR_VSWITCHES (STR_OPEN9X + OFS_VSWITCHES)
|
||||
#define STR_VSRCRAW (STR_OPEN9X + OFS_VSRCRAW)
|
||||
#define STR_VTMRMODES (STR_OPEN9X + OFS_VTMRMODES)
|
||||
|
||||
#if defined(DSM2)
|
||||
#define STR_DSM2MODE (STR_OPEN9X + OFS_DSM2MODE)
|
||||
#endif
|
||||
|
||||
#if defined(PCBV4)
|
||||
#define STR_RE1RE2 (STR_OPEN9X + OFS_RE1RE2)
|
||||
#define STR_DATETIME (STR_OPEN9X + OFS_DATETIME)
|
||||
#endif
|
||||
|
||||
// The 0-terminated-strings
|
||||
|
||||
extern const pm_char STR_POPUPS[];
|
||||
#define STR_EXIT (STR_POPUPS + OFS_EXIT)
|
||||
extern const pm_char STR_MENUWHENDONE[];
|
||||
extern const pm_char STR_FREE[];
|
||||
#define LEN_FREE PSIZE(TR_FREE)
|
||||
extern const pm_char STR_DELETEMODEL[];
|
||||
extern const pm_char STR_COPYINGMODEL[];
|
||||
extern const pm_char STR_MOVINGMODEL[];
|
||||
extern const pm_char STR_LOADINGMODEL[];
|
||||
extern const pm_char STR_NAME[];
|
||||
extern const pm_char STR_TIMER[];
|
||||
extern const pm_char STR_ELIMITS[];
|
||||
extern const pm_char STR_ETRIMS[];
|
||||
extern const pm_char STR_TRIMINC[];
|
||||
extern const pm_char STR_TTRACE[];
|
||||
extern const pm_char STR_TTRIM[];
|
||||
extern const pm_char STR_BEEPCTR[];
|
||||
extern const pm_char STR_PROTO[];
|
||||
extern const pm_char STR_PPMFRAME[];
|
||||
extern const pm_char STR_MS[];
|
||||
extern const pm_char STR_SWITCH[];
|
||||
extern const pm_char STR_TRIMS[];
|
||||
extern const pm_char STR_FADEIN[];
|
||||
extern const pm_char STR_FADEOUT[];
|
||||
extern const pm_char STR_DEFAULT[];
|
||||
extern const pm_char STR_CHECKTRIMS[];
|
||||
extern const pm_char STR_SWASHTYPE[];
|
||||
extern const pm_char STR_COLLECTIVE[];
|
||||
extern const pm_char STR_SWASHRING[];
|
||||
extern const pm_char STR_ELEDIRECTION[];
|
||||
extern const pm_char STR_AILDIRECTION[];
|
||||
extern const pm_char STR_COLDIRECTION[];
|
||||
extern const pm_char STR_MODE[];
|
||||
extern const pm_char STR_NOFREEEXPO[];
|
||||
extern const pm_char STR_NOFREEMIXER[];
|
||||
extern const pm_char STR_INSERTMIX[];
|
||||
extern const pm_char STR_EDITMIX[];
|
||||
extern const pm_char STR_SOURCE[];
|
||||
extern const pm_char STR_WEIGHT[];
|
||||
extern const pm_char STR_DIFFERENTIAL[];
|
||||
extern const pm_char STR_OFFSET[];
|
||||
extern const pm_char STR_TRIM[];
|
||||
extern const pm_char STR_CURVES[];
|
||||
extern const pm_char STR_FPHASE[];
|
||||
extern const pm_char STR_WARNING[];
|
||||
extern const pm_char STR_OFF[];
|
||||
extern const pm_char STR_MULTPX[];
|
||||
extern const pm_char STR_DELAYDOWN[];
|
||||
extern const pm_char STR_DELAYUP[];
|
||||
extern const pm_char STR_SLOWDOWN[];
|
||||
extern const pm_char STR_SLOWUP[];
|
||||
extern const pm_char STR_MIXER[];
|
||||
extern const pm_char STR_CV[];
|
||||
extern const pm_char STR_ACHANNEL[];
|
||||
extern const pm_char STR_RANGE[];
|
||||
extern const pm_char STR_BAR[];
|
||||
extern const pm_char STR_ALARM[];
|
||||
extern const pm_char STR_USRDATA[];
|
||||
extern const pm_char STR_BLADES[];
|
||||
extern const pm_char STR_BARS[];
|
||||
extern const pm_char STR_DISPLAY[];
|
||||
extern const pm_char STR_BEEPERMODE[];
|
||||
extern const pm_char STR_BEEPERLEN[];
|
||||
extern const pm_char STR_SPKRPITCH[];
|
||||
extern const pm_char STR_HAPTICMODE[];
|
||||
extern const pm_char STR_HAPTICSTRENGTH[];
|
||||
extern const pm_char STR_HAPTICLENGTH[];
|
||||
extern const pm_char STR_CONTRAST[];
|
||||
extern const pm_char STR_BATTERYWARNING[];
|
||||
extern const pm_char STR_INACTIVITYALARM[];
|
||||
extern const pm_char STR_RENAVIG[];
|
||||
extern const pm_char STR_FILTERADC[];
|
||||
extern const pm_char STR_THROTTLEREVERSE[];
|
||||
extern const pm_char STR_MINUTEBEEP[];
|
||||
extern const pm_char STR_BEEPCOUNTDOWN[];
|
||||
extern const pm_char STR_FLASHONBEEP[];
|
||||
extern const pm_char STR_LIGHTSWITCH[];
|
||||
extern const pm_char STR_LIGHTOFFAFTER[];
|
||||
extern const pm_char STR_SPLASHSCREEN[];
|
||||
extern const pm_char STR_THROTTLEWARNING[];
|
||||
extern const pm_char STR_SWITCHWARNING[];
|
||||
extern const pm_char STR_MEMORYWARNING[];
|
||||
extern const pm_char STR_ALARMWARNING[];
|
||||
extern const pm_char STR_NODATAALARM[];
|
||||
extern const pm_char STR_TIMEZONE[];
|
||||
extern const pm_char STR_GPSCOORD[];
|
||||
extern const pm_char STR_VARIO[];
|
||||
extern const pm_char STR_RXCHANNELORD[];
|
||||
extern const pm_char STR_SLAVE[];
|
||||
extern const pm_char STR_MODESRC[];
|
||||
extern const pm_char STR_MULTIPLIER[];
|
||||
#define LEN_MULTIPLIER PSIZE(TR_MULTIPLIER)
|
||||
extern const pm_char STR_CAL[];
|
||||
extern const pm_char STR_EEPROMV[];
|
||||
extern const pm_char STR_VTRIM[];
|
||||
extern const pm_char STR_BG[];
|
||||
extern const pm_char STR_MENUTOSTART[];
|
||||
extern const pm_char STR_SETMIDPOINT[];
|
||||
extern const pm_char STR_MOVESTICKSPOTS[];
|
||||
extern const pm_char STR_RXBATT[];
|
||||
extern const pm_char STR_TX[];
|
||||
#define STR_RX (STR_TX+OFS_RX)
|
||||
extern const pm_char STR_ACCEL[];
|
||||
extern const pm_char STR_NODATA[];
|
||||
extern const pm_char STR_TM1TM2[];
|
||||
extern const pm_char STR_THRTHP[];
|
||||
extern const pm_char STR_TOT[];
|
||||
extern const pm_char STR_TMR1LATMAXUS[];
|
||||
extern const pm_char STR_TMR1LATMINUS[];
|
||||
extern const pm_char STR_TMR1JITTERUS[];
|
||||
extern const pm_char STR_TMAINMAXMS[];
|
||||
extern const pm_char STR_T10MSUS[];
|
||||
extern const pm_char STR_FREESTACKMINB[];
|
||||
extern const pm_char STR_MENUTORESET[];
|
||||
extern const pm_char STR_PPM[];
|
||||
extern const pm_char STR_CH[];
|
||||
extern const pm_char STR_MODEL[];
|
||||
extern const pm_char STR_FP[];
|
||||
extern const pm_char STR_EEPROMLOWMEM[];
|
||||
extern const pm_char STR_ALERT[];
|
||||
extern const pm_char STR_PRESSANYKEYTOSKIP[];
|
||||
extern const pm_char STR_THROTTLENOTIDLE[];
|
||||
extern const pm_char STR_RESETTHROTTLE[];
|
||||
extern const pm_char STR_ALARMSDISABLED[];
|
||||
extern const pm_char STR_SWITCHESNOTOFF[];
|
||||
extern const pm_char STR_PLEASERESETTHEM[];
|
||||
extern const pm_char STR_MESSAGE[];
|
||||
extern const pm_char STR_PRESSANYKEY[];
|
||||
#define LEN_PRESSANYKEY PSIZE(TR_PRESSANYKEY)
|
||||
extern const pm_char STR_BADEEPROMDATA[];
|
||||
extern const pm_char STR_EEPROMFORMATTING[];
|
||||
extern const pm_char STR_EEPROMOVERFLOW[];
|
||||
extern const pm_char STR_MENUSERROR[];
|
||||
extern const pm_char STR_TRIMS2OFFSETS[];
|
||||
extern const pm_char STR_MENURADIOSETUP[];
|
||||
extern const pm_char STR_MENUDATEANDTIME[];
|
||||
extern const pm_char STR_MENUTRAINER[];
|
||||
extern const pm_char STR_MENUVERSION[];
|
||||
extern const pm_char STR_MENUDIAG[];
|
||||
extern const pm_char STR_MENUANA[];
|
||||
extern const pm_char STR_MENUCALIBRATION[];
|
||||
extern const pm_char STR_MENUMODELSEL[];
|
||||
extern const pm_char STR_MENUSETUP[];
|
||||
extern const pm_char STR_MENUFLIGHTPHASE[];
|
||||
extern const pm_char STR_MENUFLIGHTPHASES[];
|
||||
extern const pm_char STR_MENUHELISETUP[];
|
||||
extern const pm_char STR_MENUDREXPO[];
|
||||
extern const pm_char STR_MENULIMITS[];
|
||||
extern const pm_char STR_MENUCURVES[];
|
||||
extern const pm_char STR_MENUCURVE[];
|
||||
extern const pm_char STR_MENUCUSTOMSWITCHES[];
|
||||
extern const pm_char STR_MENUFUNCSWITCHES[];
|
||||
extern const pm_char STR_MENUTELEMETRY[];
|
||||
extern const pm_char STR_MENUTEMPLATES[];
|
||||
extern const pm_char STR_MENUSTAT[];
|
||||
extern const pm_char STR_MENUDEBUG[];
|
||||
extern const pm_char STR_RXNUM[];
|
||||
extern const pm_char STR_SYNCMENU[];
|
||||
#endif
|
||||
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
extern const pm_char STR_BACK[];
|
||||
#define LEN_BACK PSIZE(TR_BACK)
|
||||
extern const pm_char STR_MIXERWEIGHT[];
|
||||
extern const pm_char STR_MIXEROFFSET[];
|
||||
extern const pm_char STR_DRWEIGHT[];
|
||||
extern const pm_char STR_DREXPO[];
|
||||
extern const pm_char STR_MAXLIMIT[];
|
||||
#endif
|
||||
|
||||
#if defined(ROTARY_ENCODERS) || defined(FRSKY)
|
||||
extern const pm_char STR_MINLIMIT[];
|
||||
#endif
|
||||
|
||||
#ifdef FRSKY_HUB
|
||||
extern const pm_char STR_MINRSSI[];
|
||||
extern const pm_char STR_LATITUDE[];
|
||||
extern const pm_char STR_LONGITUDE[];
|
||||
#endif
|
||||
|
||||
#if defined(PCBARM) || defined(PCBV4)
|
||||
extern const pm_char STR_SHUTDOWN[];
|
||||
#endif
|
||||
|
||||
extern const pm_char STR_BATT_CALIB[];
|
||||
|
||||
#if defined(PCBARM)
|
||||
extern const pm_char STR_CURRENT_CALIB[];
|
||||
extern const pm_char STR_CURRENT[];
|
||||
#define LEN_CALIB_FIELDS (PSIZE(TR_BATT_CALIB) > PSIZE(TR_CURRENT_CALIB) ? PSIZE(TR_BATT_CALIB) : PSIZE(TR_CURRENT_CALIB))
|
||||
#else
|
||||
#define LEN_CALIB_FIELDS PSIZE(TR_BATT_CALIB)
|
||||
#endif
|
||||
|
||||
#if defined(SDCARD)
|
||||
extern const pm_char STR_SELECT_MODEL[];
|
||||
extern const pm_char STR_CREATE_MODEL[];
|
||||
extern const pm_char STR_BACKUP_MODEL[];
|
||||
extern const pm_char STR_DELETE_MODEL[];
|
||||
extern const pm_char STR_RESTORE_MODEL[];
|
||||
extern const pm_char STR_SDCARD_ERROR[];
|
||||
extern const pm_char STR_NO_SDCARD[];
|
||||
extern const pm_char STR_LOGS_PATH[];
|
||||
extern const pm_char STR_MODELS_PATH[];
|
||||
extern const pm_char STR_MODELS_EXT[];
|
||||
#define STR_UPDATE_LIST STR_DELAYDOWN
|
||||
#endif
|
||||
|
||||
extern const pm_uchar font[];
|
||||
extern const pm_uchar font_dblsize[];
|
||||
|
||||
-2726
File diff suppressed because it is too large
Load Diff
@@ -1,908 +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 open9x_h
|
||||
#define open9x_h
|
||||
|
||||
#define MAJ_VERS 2
|
||||
#define MIN_VERS 00
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(PCBARM)
|
||||
#include "board_ersky9x.h"
|
||||
#endif
|
||||
|
||||
#if defined(SIMU)
|
||||
#include "simpgmspace.h"
|
||||
#elif defined(PCBARM)
|
||||
#include "ersky9x/core_cm3.h"
|
||||
typedef const unsigned char pm_uchar;
|
||||
typedef const char pm_char;
|
||||
typedef const uint16_t pm_uint16_t;
|
||||
typedef const uint8_t pm_uint8_t;
|
||||
typedef const int16_t pm_int16_t;
|
||||
typedef const int8_t pm_int8_t;
|
||||
#define pgm_read_byte(address_short) (*(uint8_t*)(address_short))
|
||||
#define PSTR(adr) adr
|
||||
#define PROGMEM
|
||||
#define pgm_read_adr(x) *(x)
|
||||
#define cli()
|
||||
#define sei()
|
||||
#define wdt_enable(x) WDT->WDT_MR = 0x3FFF2FFF
|
||||
#define wdt_reset() WDT->WDT_CR = 0xA5000001
|
||||
extern void board_init();
|
||||
#else
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include "pgmtypes.h"
|
||||
|
||||
#include <avr/eeprom.h>
|
||||
#include <avr/sleep.h>
|
||||
#include <avr/interrupt.h>
|
||||
#define F_CPU 16000000UL // 16 MHz
|
||||
#include <util/delay.h>
|
||||
#define pgm_read_adr(address_short) pgm_read_word(address_short)
|
||||
#include <avr/wdt.h>
|
||||
#endif
|
||||
|
||||
#include "myeeprom.h"
|
||||
|
||||
#define PPM_CENTER 1500
|
||||
|
||||
#if defined(PCBARM)
|
||||
#include "eeprom_arm.h"
|
||||
#include "pulses_arm.h"
|
||||
#else
|
||||
#include "eeprom_avr.h"
|
||||
#include "pulses_avr.h"
|
||||
#endif
|
||||
|
||||
#include "lcd.h"
|
||||
#include "menus.h"
|
||||
#ifdef TEMPLATES
|
||||
#include "templates.h"
|
||||
#endif
|
||||
|
||||
#if !defined(SIMU)
|
||||
#define assert(x)
|
||||
#define printf printf_not_allowed
|
||||
#endif
|
||||
|
||||
// G: The following comments relate to the original stock PCB only
|
||||
//
|
||||
// elev thr
|
||||
// LV RV
|
||||
// 2 ^ 4 ^
|
||||
// 1 2
|
||||
// | rudd | aile
|
||||
// <----X--3-> LH <----X--0-> RH
|
||||
// 6 | 7 1 | 0
|
||||
// | |
|
||||
// 3 v 5 v
|
||||
//
|
||||
//PORTA 7 6 5 4 3 2 1 0
|
||||
// O O O O O O O O
|
||||
// ------------------------ LCD_DAT -----------------------
|
||||
//
|
||||
//PORTB 7 6 5 4 3 2 1 0
|
||||
// O i i i i i i O
|
||||
// light KEY_LFT KEY_RGT KEY_UP KEY_DWN KEY_EXT KEY_MEN PPM
|
||||
//
|
||||
//PORTC 7 6 5 4 3 2 1 0
|
||||
// - - O O O O O -
|
||||
// NC NC LCD_E LCD_RNW LCD_A0 LCD_RES LCD_CS1 NC
|
||||
//
|
||||
//PORTD 7 6 5 4 3 2 1 0
|
||||
// i i i i i i i i
|
||||
// TRM_D_DWN _UP TRM_C_DWN _UP TRM_B_DWN _UP TRM_A_DWN _UP
|
||||
//
|
||||
//PORTE 7 6 5 4 3 2 1 0
|
||||
// i i i i O i i i
|
||||
// PPM_IN ID2 Trainer Gear Buzzer ElevDR AileDR THRCT
|
||||
//
|
||||
//PORTF 7 6 5 4 3 2 1 0
|
||||
// ai ai ai ai ai ai ai ai
|
||||
// ANA_ BAT PITT_TRM HOV_THR HOV_PIT STCK_LH STCK_RV STCK_LV STCK_RH
|
||||
// rud thro elev aile
|
||||
//PORTG 7 6 5 4 3 2 1 0
|
||||
// - - - O i i i
|
||||
// SIM_CTL ID1 Haptic RF_POW RuddDR
|
||||
|
||||
#define PORTA_LCD_DAT PORTA
|
||||
#define PORTC_LCD_CTRL PORTC
|
||||
#define OUT_C_LCD_E 5
|
||||
#define OUT_C_LCD_RnW 4
|
||||
#define OUT_C_LCD_A0 3
|
||||
#define OUT_C_LCD_RES 2
|
||||
#define OUT_C_LCD_CS1 1
|
||||
|
||||
#if defined (PCBV4)
|
||||
|
||||
# define INP_P_SPARE6 7
|
||||
# define INP_P_SPARE5 6
|
||||
# define INP_P_KEY_EXT 5
|
||||
# define INP_P_KEY_MEN 4
|
||||
# define INP_P_KEY_LFT 3
|
||||
# define INP_P_KEY_RGT 2
|
||||
# define INP_P_KEY_UP 1
|
||||
# define INP_P_KEY_DWN 0
|
||||
|
||||
# define INP_J_TRM_RH_UP 7
|
||||
# define INP_J_TRM_RH_DWN 6
|
||||
# define INP_J_TRM_RV_UP 5
|
||||
# define INP_J_TRM_RV_DWN 4
|
||||
# define INP_J_TRM_LV_UP 3
|
||||
# define INP_J_TRM_LV_DWN 2
|
||||
# define INP_J_TRM_LH_UP 1
|
||||
# define INP_J_TRM_LH_DWN 0
|
||||
|
||||
# define INP_E_PPM_IN 7
|
||||
# define INP_E_ROT_ENC_1_B 6
|
||||
# define INP_E_ROT_ENC_1_A 5
|
||||
# define INP_E_USB_D_PLS 4
|
||||
# define OUT_E_BUZZER 3
|
||||
# define INP_E_USB_D_NEG 2
|
||||
# define INP_E_TELEM_RX 1
|
||||
# define OUT_E_TELEM_TX 0
|
||||
|
||||
# define INP_D_HAPTIC 7
|
||||
# define INP_D_SPARE4 6
|
||||
# define INP_D_ROT_ENC_2_PUSH 5
|
||||
# define INP_D_ROT_ENC_1_PUSH 4
|
||||
# define OUT_D_ROT_ENC_2_B 3
|
||||
# define INP_D_ROT_ENC_2_A 2
|
||||
# define INP_D_I2C_SCL 1
|
||||
# define INP_D_I2C_SDA 0
|
||||
|
||||
# define INP_G_Gear 5
|
||||
# define INP_G_ThrCt 2
|
||||
# define OUT_G_SIM_CTL 4 //1 : phone-jack=ppm_in
|
||||
# define INP_G_ID1 3
|
||||
# define INP_G_RF_POW 1
|
||||
# define INP_G_RuddDR 0
|
||||
|
||||
# define INP_C_AileDR 7
|
||||
# define INP_C_ElevDR 6
|
||||
# define OUT_C_LIGHT 0
|
||||
|
||||
# define OUT_B_Speaker 7
|
||||
# define OUT_B_PPM 6 // will be switched by TCNT1==OCR1B in hardware
|
||||
# define INP_B_Trainer 5
|
||||
# define INP_B_ID2 4
|
||||
|
||||
#ifdef SOMO
|
||||
# define OUT_H_14DCLK 4
|
||||
# define OUT_H_14DDATA 5
|
||||
# define OUT_H_14DBUSY 6
|
||||
#endif
|
||||
|
||||
#else // boards prior to v4 ...
|
||||
|
||||
#define OUT_B_LIGHT 7
|
||||
#define INP_B_KEY_LFT 6
|
||||
#define INP_B_KEY_RGT 5
|
||||
#define INP_B_KEY_UP 4
|
||||
#define INP_B_KEY_DWN 3
|
||||
#define INP_B_KEY_EXT 2
|
||||
#define INP_B_KEY_MEN 1
|
||||
#define OUT_B_PPM 0
|
||||
|
||||
#define INP_D_TRM_LH_UP 7
|
||||
#define INP_D_TRM_LH_DWN 6
|
||||
#define INP_D_TRM_RV_DWN 5
|
||||
#define INP_D_TRM_RV_UP 4
|
||||
#define INP_D_TRM_LV_DWN 3
|
||||
#define INP_D_TRM_LV_UP 2
|
||||
#define INP_D_TRM_RH_DWN 1
|
||||
#define INP_D_TRM_RH_UP 0
|
||||
|
||||
#define INP_E_PPM_IN 7
|
||||
#define INP_E_ID2 6
|
||||
#define INP_E_Trainer 5
|
||||
#define INP_E_Gear 4
|
||||
#define OUT_E_BUZZER 3
|
||||
#define INP_E_ElevDR 2
|
||||
#define INP_E_AileDR 1
|
||||
#define INP_E_ThrCt 0
|
||||
|
||||
#if defined(JETI) || defined(FRSKY) || defined(ARDUPILOT) || defined(NMEA) || defined(MAVLINK)
|
||||
#undef INP_E_ThrCt
|
||||
#undef INP_E_AileDR
|
||||
#define INP_C_ThrCt 6
|
||||
#define INP_C_AileDR 7
|
||||
#endif
|
||||
|
||||
#define OUT_G_SIM_CTL 4 //1 : phone-jack=ppm_in
|
||||
#define INP_G_ID1 3
|
||||
#define INP_G_HAPTIC 2
|
||||
#define INP_G_RF_POW 1
|
||||
#define INP_G_RuddDR 0
|
||||
|
||||
#endif // defined (PCBV4)
|
||||
|
||||
#if defined(PCBARM)
|
||||
#define SLAVE_MODE (check_soft_power() == e_power_trainer)
|
||||
#else
|
||||
#define SLAVE_MODE (PING & (1<<INP_G_RF_POW))
|
||||
#endif
|
||||
|
||||
extern const pm_uint8_t bchout_ar[];
|
||||
extern const pm_uint8_t modn12x3[];
|
||||
|
||||
extern uint8_t stickMode;
|
||||
|
||||
//convert from mode 1 to mode stickMode
|
||||
//NOTICE! => 1..4 -> 1..4
|
||||
#define CONVERT_MODE(x) (((x)<=4) ? pgm_read_byte(modn12x3 + 4*stickMode + (x)-1) : (x) )
|
||||
|
||||
#define RUD_STICK 0
|
||||
#define ELE_STICK 1
|
||||
#define THR_STICK 2
|
||||
#define AIL_STICK 3
|
||||
|
||||
extern uint8_t channel_order(uint8_t x);
|
||||
|
||||
enum EnumKeys {
|
||||
KEY_MENU ,
|
||||
KEY_EXIT ,
|
||||
KEY_DOWN ,
|
||||
KEY_UP ,
|
||||
KEY_RIGHT ,
|
||||
KEY_LEFT ,
|
||||
TRM_LH_DWN ,
|
||||
TRM_LH_UP ,
|
||||
TRM_LV_DWN ,
|
||||
TRM_LV_UP ,
|
||||
TRM_RV_DWN ,
|
||||
TRM_RV_UP ,
|
||||
TRM_RH_DWN ,
|
||||
TRM_RH_UP ,
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
BTN_REa,
|
||||
BTN_REb,
|
||||
#endif
|
||||
//SW_NC ,
|
||||
//SW_ON ,
|
||||
SW_ThrCt ,
|
||||
SW_RuddDR ,
|
||||
SW_ElevDR ,
|
||||
SW_ID0 ,
|
||||
SW_ID1 ,
|
||||
SW_ID2 ,
|
||||
SW_AileDR ,
|
||||
SW_Gear ,
|
||||
SW_Trainer,
|
||||
NUM_KEYS = SW_ThrCt
|
||||
};
|
||||
|
||||
class Key
|
||||
{
|
||||
#define FILTERBITS 4
|
||||
#ifdef SIMU
|
||||
#define FFVAL 1
|
||||
#else
|
||||
#define FFVAL ((1<<FILTERBITS)-1)
|
||||
#endif
|
||||
#define KSTATE_OFF 0
|
||||
#define KSTATE_RPTDELAY 95 // gruvin: delay state before key repeating starts
|
||||
//#define KSTATE_SHORT 96
|
||||
#define KSTATE_START 97
|
||||
#define KSTATE_PAUSE 98
|
||||
#define KSTATE_KILLED 99
|
||||
uint8_t m_vals:FILTERBITS; // key debounce? 4 = 40ms
|
||||
uint8_t m_dblcnt:2;
|
||||
uint8_t m_cnt;
|
||||
uint8_t m_state;
|
||||
public:
|
||||
void input(bool val, EnumKeys enuk);
|
||||
bool state() { return m_vals==FFVAL; }
|
||||
void pauseEvents() { m_state = KSTATE_PAUSE; m_cnt = 0;}
|
||||
void killEvents() { m_state = KSTATE_KILLED; m_dblcnt=0; }
|
||||
uint8_t getDbl() { return m_dblcnt; }
|
||||
};
|
||||
|
||||
extern Key keys[NUM_KEYS];
|
||||
|
||||
#define CURVE_BASE 7
|
||||
|
||||
#define SWASH_TYPE_120 1
|
||||
#define SWASH_TYPE_120X 2
|
||||
#define SWASH_TYPE_140 3
|
||||
#define SWASH_TYPE_90 4
|
||||
#define SWASH_TYPE_NUM 4
|
||||
|
||||
#define CS_OFF 0
|
||||
#define CS_VPOS 1 //v>offset
|
||||
#define CS_VNEG 2 //v<offset
|
||||
#define CS_APOS 3 //|v|>offset
|
||||
#define CS_ANEG 4 //|v|<offset
|
||||
#define CS_AND 5
|
||||
#define CS_OR 6
|
||||
#define CS_XOR 7
|
||||
#define CS_EQUAL 8
|
||||
#define CS_NEQUAL 9
|
||||
#define CS_GREATER 10
|
||||
#define CS_LESS 11
|
||||
#define CS_EGREATER 12
|
||||
#define CS_ELESS 13
|
||||
#define CS_MAXF 13 //max function
|
||||
|
||||
#define CS_VOFS 0
|
||||
#define CS_VBOOL 1
|
||||
#define CS_VCOMP 2
|
||||
#define CS_STATE(x) ((x)<CS_AND ? CS_VOFS : ((x)<CS_EQUAL ? CS_VBOOL : CS_VCOMP))
|
||||
|
||||
#define SW_BASE SW_ThrCt
|
||||
#define SW_BASE_DIAG SW_ThrCt
|
||||
|
||||
#define MAX_PSWITCH (SW_Trainer-SW_ThrCt+1) // 9 physical switches
|
||||
#define MAX_SWITCH (MAX_PSWITCH+NUM_CSW)
|
||||
#define SWITCH_ON (1+MAX_SWITCH)
|
||||
#define SWITCH_OFF (-SWITCH_ON)
|
||||
#if defined(PCBARM)
|
||||
#define MAX_DRSWITCH (MAX_PSWITCH+NUM_CSW) // 15(9+6) !switches + 0 + 15 switches: 5 bits needed
|
||||
#else
|
||||
#define MAX_DRSWITCH (MAX_PSWITCH+NUM_CSW/2) // 15(9+6) !switches + 0 + 15 switches: 5 bits needed
|
||||
#endif
|
||||
|
||||
#define NUM_STICKS 4
|
||||
#define NUM_POTS 3
|
||||
#define NUM_CYC 3
|
||||
#define CSW_PPM_BASE (MIXSRC_3POS+NUM_CYC) // because srcRaw is shifted +1!
|
||||
#define NUM_CAL_PPM 4
|
||||
#define NUM_PPM 8
|
||||
#define CSW_CHOUT_BASE (CSW_PPM_BASE+NUM_PPM)
|
||||
|
||||
#if defined(FRSKY_HUB)
|
||||
#define NUM_TELEMETRY TELEM_CSW_MAX
|
||||
#elif defined(WS_HOW_HIGH)
|
||||
#define NUM_TELEMETRY TELEM_ALT
|
||||
#elif defined(FRSKY)
|
||||
#define NUM_TELEMETRY TELEM_RSSI_RX
|
||||
#elif defined(MAVLINK)
|
||||
// Number sw position
|
||||
#define NUM_TELEMETRY 4
|
||||
#define ROTARY_SW_CHANNEL "UP DOWN"
|
||||
// Channel number for rotary switch
|
||||
//#define MIX_SW_ROLL_CHAN (CSW_CHOUT_BASE+NUM_CHNOUT+NUM_VIRTUAL) // GVA:Rotary switch
|
||||
#define MIX_INC_ROTARY_SW (CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+1)
|
||||
#define MIX_DEC_ROTARY_SW (CSW_CHOUT_BASE+NUM_CHNOUT+MAX_TIMERS+1)
|
||||
#else
|
||||
#define NUM_TELEMETRY TELEM_TM2
|
||||
#endif
|
||||
|
||||
#define NUM_XCHNRAW (NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS+NUM_STICKS+1/*MAX*/+1/*ID3*/+NUM_CYC+NUM_PPM+NUM_CHNOUT)
|
||||
#define NUM_XCHNCSW (NUM_XCHNRAW+NUM_TELEMETRY)
|
||||
#define NUM_XCHNMIX (NUM_XCHNRAW+MAX_SWITCH)
|
||||
|
||||
#define DSW_THR 1
|
||||
#define DSW_RUD 2
|
||||
#define DSW_ELE 3
|
||||
#define DSW_ID0 4
|
||||
#define DSW_ID1 5
|
||||
#define DSW_ID2 6
|
||||
#define DSW_AIL 7
|
||||
#define DSW_GEA 8
|
||||
#define DSW_TRN 9
|
||||
#define DSW_SW1 10
|
||||
#define DSW_SW2 11
|
||||
#define DSW_SW3 12
|
||||
#define DSW_SW4 13
|
||||
#define DSW_SW5 14
|
||||
#define DSW_SW6 15
|
||||
|
||||
#define THRCHK_DEADBAND 16
|
||||
#define SPLASH_TIMEOUT (4*100) //400 msec - 4 seconds
|
||||
|
||||
#define TRM_BASE TRM_LH_DWN
|
||||
|
||||
#define _MSK_KEY_DBL 0x10
|
||||
#define _MSK_KEY_BREAK 0x20
|
||||
#define _MSK_KEY_REPT 0x40
|
||||
#define _MSK_KEY_LONG 0x80
|
||||
#define IS_KEY_BREAK(key) (((key)&0xf0) == 0x20)
|
||||
#define EVT_KEY_BREAK(key) ((key)|_MSK_KEY_BREAK)
|
||||
#define EVT_KEY_FIRST(key) ((key)|_MSK_KEY_REPT|0x20)
|
||||
#define EVT_KEY_REPT(key) ((key)|_MSK_KEY_REPT)
|
||||
#define EVT_KEY_LONG(key) ((key)|_MSK_KEY_LONG)
|
||||
#define EVT_KEY_DBL(key) ((key)|_MSK_KEY_DBL)
|
||||
#define EVT_ENTRY (0xff - _MSK_KEY_REPT)
|
||||
#define EVT_ENTRY_UP (0xfe - _MSK_KEY_REPT)
|
||||
#define EVT_KEY_MASK (0x0f)
|
||||
|
||||
#define HEART_TIMER_PULSES 1
|
||||
#define HEART_TIMER10ms 2
|
||||
extern uint8_t heartbeat;
|
||||
|
||||
#define MAX_ALERT_TIME 60
|
||||
|
||||
extern uint32_t inacCounter;
|
||||
|
||||
#if defined(PXX)
|
||||
extern uint8_t pxxFlag;
|
||||
#endif
|
||||
|
||||
#define PXX_SEND_RXNUM 0x01
|
||||
#define PXX_SEND_FAILSAFE 0x02 // TODO where is it used?
|
||||
|
||||
#define ZCHAR_MAX (40 + LEN_SPECIAL_CHARS)
|
||||
|
||||
extern char idx2char(int8_t idx);
|
||||
|
||||
void pauseEvents(uint8_t enuk);
|
||||
void killEvents(uint8_t enuk);
|
||||
uint8_t getEvent();
|
||||
void putEvent(uint8_t evt);
|
||||
|
||||
uint8_t keyDown();
|
||||
|
||||
enum PowerState {
|
||||
e_power_on,
|
||||
e_power_trainer,
|
||||
e_power_usb,
|
||||
e_power_off
|
||||
};
|
||||
|
||||
#if defined(PCBARM)
|
||||
uint32_t keyState(EnumKeys enuk);
|
||||
uint32_t check_soft_power();
|
||||
#else
|
||||
#if defined(PCBV4)
|
||||
uint8_t check_soft_power();
|
||||
#else
|
||||
#define check_soft_power() (e_power_on)
|
||||
#endif
|
||||
|
||||
bool keyState(EnumKeys enuk);
|
||||
#endif
|
||||
void readKeysAndTrims();
|
||||
|
||||
uint16_t evalChkSum();
|
||||
|
||||
extern void alert(const pm_char * s);
|
||||
extern void message(const pm_char *title, const pm_char *s, const pm_char *t, const char *last);
|
||||
|
||||
void perMain();
|
||||
void per10ms();
|
||||
|
||||
int16_t getValue(uint8_t i);
|
||||
bool getSwitch(int8_t swtch, bool nc);
|
||||
int8_t getMovedSwitch();
|
||||
|
||||
#ifdef FLIGHT_PHASES
|
||||
extern uint8_t getFlightPhase();
|
||||
#else
|
||||
#define getFlightPhase() 0
|
||||
#endif
|
||||
|
||||
extern uint8_t getTrimFlightPhase(uint8_t phase, uint8_t idx);
|
||||
extern int16_t getRawTrimValue(uint8_t phase, uint8_t idx);
|
||||
extern int16_t getTrimValue(uint8_t phase, uint8_t idx);
|
||||
extern void setTrimValue(uint8_t phase, uint8_t idx, int16_t trim);
|
||||
|
||||
extern uint8_t s_perout_flight_phase;
|
||||
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
int16_t getRotaryEncoder(uint8_t idx);
|
||||
void incRotaryEncoder(uint8_t idx, int8_t inc);
|
||||
inline bool navigationRotaryEncoder(uint8_t event)
|
||||
{
|
||||
return g_eeGeneral.reNavigation == ((event & EVT_KEY_MASK) - BTN_REa + 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
extern uint16_t s_timeCumTot;
|
||||
extern uint16_t s_timeCumThr; //gewichtete laufzeit in 1/16 sec
|
||||
extern uint16_t s_timeCum16ThrP; //gewichtete laufzeit in 1/16 sec
|
||||
extern uint8_t s_timerState[2];
|
||||
extern int16_t s_timerVal[2];
|
||||
extern uint8_t s_timerVal_10ms[2];
|
||||
extern int8_t safetyCh[NUM_CHNOUT];
|
||||
|
||||
extern uint8_t trimsCheckTimer;
|
||||
|
||||
#define TMR_OFF 0
|
||||
#define TMR_RUNNING 1
|
||||
#define TMR_BEEPING 2
|
||||
#define TMR_STOPPED 3
|
||||
void resetTimer(uint8_t idx);
|
||||
void resetAll();
|
||||
|
||||
extern uint8_t g_tmr1Latency_max;
|
||||
extern uint8_t g_tmr1Latency_min;
|
||||
extern uint16_t g_timeMain;
|
||||
#ifdef DEBUG
|
||||
extern uint16_t g_time_per10;
|
||||
#endif
|
||||
|
||||
#define MAXTRACE 120
|
||||
extern uint8_t s_traceBuf[MAXTRACE];
|
||||
extern uint8_t s_traceWr;
|
||||
extern int8_t s_traceCnt;
|
||||
|
||||
extern int8_t *s_trimPtr[NUM_STICKS];
|
||||
|
||||
#if defined(PCBARM)
|
||||
static inline uint16_t getTmr2MHz() { return TC1->TC_CHANNEL[0].TC_CV; }
|
||||
#else
|
||||
uint16_t getTmr16KHz();
|
||||
#endif
|
||||
|
||||
uint16_t stack_free();
|
||||
|
||||
#ifdef SPLASH
|
||||
void doSplash();
|
||||
#endif
|
||||
|
||||
void checkLowEEPROM();
|
||||
void checkTHR();
|
||||
void checkSwitches();
|
||||
void checkAlarm();
|
||||
|
||||
#define ADC_VREF_TYPE 0x40 // AVCC with external capacitor at AREF pin
|
||||
|
||||
#define GETADC_SING = 0
|
||||
#define GETADC_OSMP = 1
|
||||
#define GETADC_FILT = 2
|
||||
|
||||
void getADC_single();
|
||||
void getADC_osmp();
|
||||
void getADC_filt();
|
||||
|
||||
extern uint8_t s_eeDirtyMsk;
|
||||
|
||||
#define STORE_MODELVARS eeDirty(EE_MODEL)
|
||||
#define STORE_GENERALVARS eeDirty(EE_GENERAL)
|
||||
|
||||
#if defined (PCBARM)
|
||||
#ifndef SIMU
|
||||
#define BACKLIGHT_ON (PWM->PWM_CH_NUM[0].PWM_CDTY = g_eeGeneral.backlightBright)
|
||||
#define BACKLIGHT_OFF (PWM->PWM_CH_NUM[0].PWM_CDTY = 100)
|
||||
#else
|
||||
#define BACKLIGHT_ON
|
||||
#define BACKLIGHT_OFF
|
||||
#endif
|
||||
#ifdef REVB
|
||||
#define NUMBER_ANALOG 9
|
||||
#else
|
||||
#define NUMBER_ANALOG 8
|
||||
extern uint16_t Analog_values[NUMBER_ANALOG] ;
|
||||
void read_9_adc(void ) ;
|
||||
#endif
|
||||
#elif defined (PCBV4)
|
||||
#define SPEAKER_ON TCCR0A |= (1 << COM0A0)
|
||||
#define SPEAKER_OFF TCCR0A &= ~(1 << COM0A0)
|
||||
#define BACKLIGHT_ON PORTC |= (1 << OUT_C_LIGHT)
|
||||
#define BACKLIGHT_OFF PORTC &= ~(1 << OUT_C_LIGHT)
|
||||
#else
|
||||
#define BACKLIGHT_ON PORTB |= (1 << OUT_B_LIGHT)
|
||||
#define BACKLIGHT_OFF PORTB &= ~(1 << OUT_B_LIGHT)
|
||||
#endif
|
||||
|
||||
#define BUZZER_ON PORTE |= (1 << OUT_E_BUZZER)
|
||||
#define BUZZER_OFF PORTE &= ~(1 << OUT_E_BUZZER)
|
||||
|
||||
#if defined(HAPTIC)
|
||||
#if defined(PCBARM)
|
||||
#define HAPTIC_OFF hapticOff()
|
||||
#elif defined(PCBV4)
|
||||
#define HAPTIC_ON PORTD &= ~(1 << INP_D_HAPTIC)
|
||||
#define HAPTIC_OFF PORTD |= (1 << INP_D_HAPTIC)
|
||||
#else
|
||||
#define HAPTIC_ON PORTG |= (1 << INP_G_HAPTIC)
|
||||
#define HAPTIC_OFF PORTG &= ~(1 << INP_G_HAPTIC)
|
||||
#endif
|
||||
#else
|
||||
#define HAPTIC_ON
|
||||
#define HAPTIC_OFF
|
||||
#endif
|
||||
|
||||
#define BITMASK(bit) (1<<(bit))
|
||||
|
||||
/// liefert Dimension eines Arrays
|
||||
#define DIM(arr) (sizeof((arr))/sizeof((arr)[0]))
|
||||
|
||||
#ifndef FORCEINLINE
|
||||
#define FORCEINLINE inline __attribute__ ((always_inline))
|
||||
#endif
|
||||
|
||||
#ifndef NOINLINE
|
||||
#define NOINLINE __attribute__ ((noinline))
|
||||
#endif
|
||||
|
||||
/// liefert Betrag des Arguments
|
||||
template<class t> FORCEINLINE t abs(t a) { return a>0?a:-a; }
|
||||
/// liefert das Minimum der Argumente
|
||||
template<class t> FORCEINLINE t min(t a, t b) { return a<b?a:b; }
|
||||
/// liefert das Maximum der Argumente
|
||||
template<class t> FORCEINLINE t max(t a, t b) { return a>b?a:b; }
|
||||
template<class t> FORCEINLINE t sgn(t a) { return a>0 ? 1 : (a < 0 ? -1 : 0); }
|
||||
template<class t> FORCEINLINE t limit(t mi, t x, t ma) { return min(max(mi,x),ma); }
|
||||
|
||||
#if defined(HELI) || defined(FRSKY_HUB)
|
||||
uint16_t isqrt32(uint32_t n);
|
||||
#endif
|
||||
|
||||
/// Markiert einen EEPROM-Bereich als dirty. der Bereich wird dann in
|
||||
/// eeCheck ins EEPROM zurueckgeschrieben.
|
||||
void eeWriteBlockCmp(const void *i_pointer_ram, uint16_t i_pointer_eeprom, size_t size);
|
||||
void eeDirty(uint8_t msk);
|
||||
void eeCheck(bool immediately=false);
|
||||
void eeReadAll();
|
||||
bool eeModelExists(uint8_t id);
|
||||
uint16_t eeLoadModelName(uint8_t id, char *name);
|
||||
void eeLoadModel(uint8_t id);
|
||||
void generalDefault();
|
||||
void modelDefault(uint8_t id);
|
||||
void resetProto();
|
||||
|
||||
#if defined(PCBARM)
|
||||
inline int32_t calc100toRESX(register int8_t x)
|
||||
{
|
||||
return ((uint32_t)x*655)>>6 ;
|
||||
}
|
||||
|
||||
inline int16_t calc1000toRESX( register int32_t x) // improve calc time by Pat MacKenzie
|
||||
{
|
||||
register int32_t y = x>>5;
|
||||
x+=y;
|
||||
y=y>>2;
|
||||
x-=y;
|
||||
return x+(y>>2);
|
||||
// return x + x/32 - x/128 + x/512;
|
||||
}
|
||||
#else
|
||||
extern inline int16_t calc100toRESX(int8_t x)
|
||||
{
|
||||
// return (int16_t)x*10 + x/4 - x/64;
|
||||
return ((x*41)>>2) - x/64;
|
||||
}
|
||||
|
||||
extern inline int16_t calc1000toRESX(int16_t x)
|
||||
{
|
||||
// return x + x/32 - x/128 + x/512;
|
||||
int16_t y = x>>5;
|
||||
x+=y;
|
||||
y=y>>2;
|
||||
x-=y;
|
||||
return x+(y>>2);
|
||||
}
|
||||
#endif
|
||||
|
||||
extern volatile uint16_t g_tmr10ms;
|
||||
|
||||
#if defined(PCBARM)
|
||||
// This doesn't need protection on this processor
|
||||
#define get_tmr10ms() g_tmr10ms
|
||||
#else
|
||||
extern inline uint16_t get_tmr10ms()
|
||||
{
|
||||
uint16_t time ;
|
||||
cli();
|
||||
time = g_tmr10ms ;
|
||||
sei();
|
||||
return time ;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define TMR_VAROFS 5
|
||||
|
||||
extern const char stamp1[];
|
||||
extern const char stamp2[];
|
||||
extern const char stamp3[];
|
||||
extern const char stamp4[];
|
||||
|
||||
extern uint16_t g_vbat100mV;
|
||||
extern volatile uint16_t g_tmr10ms;
|
||||
extern volatile uint8_t g_blinkTmr10ms;
|
||||
extern uint8_t g_beepCnt;
|
||||
extern uint8_t g_beepVal[5];
|
||||
|
||||
#include "o9xstrings.h"
|
||||
|
||||
extern uint8_t ppmInState; //0=unsync 1..8= wait for value i-1
|
||||
extern int16_t g_ppmIns[8];
|
||||
extern int16_t ex_chans[NUM_CHNOUT]; // Outputs (before LIMITS) of the last perMain
|
||||
extern int16_t g_chans512[NUM_CHNOUT];
|
||||
extern volatile uint8_t tick10ms;
|
||||
extern uint16_t BandGap;
|
||||
|
||||
extern uint16_t expou(uint16_t x, uint16_t k);
|
||||
extern int16_t expo(int16_t x, int16_t k);
|
||||
extern int16_t intpol(int16_t, uint8_t);
|
||||
extern int16_t applyCurve(int16_t, int8_t);
|
||||
extern void applyExpos(int16_t *anas);
|
||||
|
||||
extern uint16_t anaIn(uint8_t chan);
|
||||
extern int16_t calibratedStick[7];
|
||||
|
||||
#define FLASH_DURATION 50
|
||||
|
||||
extern uint8_t beepAgain;
|
||||
extern uint16_t g_LightOffCounter;
|
||||
extern uint8_t mixWarning;
|
||||
|
||||
extern PhaseData *phaseaddress(uint8_t idx);
|
||||
extern ExpoData *expoaddress(uint8_t idx);
|
||||
extern MixData *mixaddress(uint8_t idx);
|
||||
extern LimitData *limitaddress(uint8_t idx);
|
||||
|
||||
extern void deleteExpoMix(uint8_t expo, uint8_t idx);
|
||||
|
||||
extern void incSubtrim(uint8_t idx, int16_t inc);
|
||||
extern void instantTrim();
|
||||
extern void moveTrimsToOffsets();
|
||||
|
||||
extern uint16_t active_functions;
|
||||
inline bool isFunctionActive(uint8_t func)
|
||||
{
|
||||
return active_functions & (1 << (func-FUNC_TRAINER));
|
||||
}
|
||||
|
||||
#ifdef DISPLAY_USER_DATA
|
||||
#define TELEM_SCREEN_BUFFER_SIZE 21
|
||||
extern char userDataDisplayBuf[TELEM_SCREEN_BUFFER_SIZE]; // text buffer for frsky telem. user data experiments
|
||||
#endif
|
||||
|
||||
#if defined (PCBV4)
|
||||
// Global rotary encoder registers -- 8-bit, 0-255
|
||||
extern volatile uint8_t g_rotenc[2];
|
||||
#endif
|
||||
|
||||
#ifdef JETI
|
||||
// Jeti-DUPLEX Telemetry
|
||||
extern uint16_t jeti_keys;
|
||||
#include "jeti.h"
|
||||
#endif
|
||||
|
||||
#if defined (FRSKY)
|
||||
// FrSky Telemetry
|
||||
#include "frsky.h"
|
||||
#endif
|
||||
|
||||
#ifdef ARDUPILOT
|
||||
// ArduPilot Telemetry
|
||||
#include "ardupilot.h"
|
||||
#endif
|
||||
|
||||
#ifdef NMEA
|
||||
// NMEA Telemetry
|
||||
#include "nmea.h"
|
||||
#endif
|
||||
|
||||
#ifdef MAVLINK
|
||||
// Mavlink Telemetry
|
||||
#include "rotarysw.h"
|
||||
#include "mavlink.h"
|
||||
#endif
|
||||
|
||||
// REPEAT uses 0x01 to 0x0f
|
||||
#define PLAY_NOW 0x10
|
||||
#define PLAY_SOUND_VARIO 0x20
|
||||
|
||||
/* make sure the defines below always go in numeric order */
|
||||
enum AUDIO_SOUNDS {
|
||||
AU_INACTIVITY,
|
||||
AU_TX_BATTERY_LOW,
|
||||
AU_ERROR,
|
||||
AU_KEYPAD_UP,
|
||||
AU_KEYPAD_DOWN,
|
||||
AU_MENUS,
|
||||
AU_TRIM_MOVE,
|
||||
AU_WARNING1,
|
||||
AU_WARNING2,
|
||||
AU_WARNING3,
|
||||
AU_TRIM_MIDDLE,
|
||||
AU_TADA,
|
||||
AU_POT_STICK_MIDDLE,
|
||||
AU_MIX_WARNING_1,
|
||||
AU_MIX_WARNING_2,
|
||||
AU_MIX_WARNING_3,
|
||||
AU_TIMER_LT3,
|
||||
AU_TIMER_10,
|
||||
AU_TIMER_20,
|
||||
AU_TIMER_30,
|
||||
AU_FRSKY_FIRST,
|
||||
AU_FRSKY_WARN1 = AU_FRSKY_FIRST,
|
||||
AU_FRSKY_WARN2,
|
||||
AU_FRSKY_CHEEP,
|
||||
AU_FRSKY_RING,
|
||||
AU_FRSKY_SCIFI,
|
||||
AU_FRSKY_ROBOT,
|
||||
AU_FRSKY_CHIRP,
|
||||
AU_FRSKY_TADA,
|
||||
AU_FRSKY_CRICKET,
|
||||
AU_FRSKY_SIREN,
|
||||
AU_FRSKY_ALARMC,
|
||||
AU_FRSKY_RATATA,
|
||||
AU_FRSKY_TICK,
|
||||
AU_FRSKY_LAST,
|
||||
};
|
||||
#if defined(AUDIO)
|
||||
#if defined(PCBARM)
|
||||
#include "ersky9x/audio.h"
|
||||
#else
|
||||
#include "stock/audio.h"
|
||||
#endif
|
||||
#else
|
||||
#include "beeper.h"
|
||||
#endif
|
||||
|
||||
#if defined(HAPTIC)
|
||||
#include "haptic.h"
|
||||
#endif
|
||||
|
||||
#if defined(SDCARD)
|
||||
#include "gruvin9x/sdcard.h"
|
||||
#endif
|
||||
|
||||
#if defined(SOMO)
|
||||
#include "somo14d.h"
|
||||
#endif
|
||||
|
||||
// Re-useable byte array to save having multiple buffers
|
||||
union ReusableBuffer
|
||||
{
|
||||
#if !defined(PCBARM)
|
||||
uint8_t eefs_buffer[BLOCKS]; // used by EeFsck
|
||||
#endif
|
||||
|
||||
struct
|
||||
{
|
||||
char mainname[42]; // used by menuProcModelSelect and for SD card archive / restore
|
||||
char listnames[7][10];
|
||||
uint16_t listsizes[7];
|
||||
uint16_t eepromfree;
|
||||
} models;
|
||||
|
||||
struct
|
||||
{
|
||||
int16_t midVals[7];
|
||||
int16_t loVals[7];
|
||||
int16_t hiVals[7];
|
||||
} calib; // used by menuProcDiagCalib
|
||||
};
|
||||
|
||||
extern union ReusableBuffer reusableBuffer;
|
||||
|
||||
void checkFlashOnBeep();
|
||||
|
||||
#if defined(FRSKY) || defined(PCBARM)
|
||||
void putsTelemetryValue(uint8_t x, uint8_t y, int16_t val, uint8_t unit, uint8_t att);
|
||||
#endif
|
||||
|
||||
#endif // gruvin9x_h
|
||||
/*eof*/
|
||||
-869
@@ -1,869 +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"
|
||||
|
||||
#if defined(DSM2)
|
||||
// DSM2 control bits
|
||||
#define DSM2_CHANS 6
|
||||
#define BIND_BIT 0x80
|
||||
#define RANGECHECK_BIT 0x20
|
||||
#define FRANCE_BIT 0x10
|
||||
#define DSMX_BIT 0x08
|
||||
#define BAD_DATA 0x47
|
||||
#endif
|
||||
|
||||
uint8_t s_current_protocol = 255;
|
||||
|
||||
#ifdef DSM2_SERIAL
|
||||
inline void DSM2_EnableTXD(void)
|
||||
{
|
||||
UCSR0B |= (1 << TXEN0); // enable TX
|
||||
// UCSR0B |= (1 << UDRIE0); // don't enable UDRE0 interrupt, it will be enabled during next setupPulses
|
||||
}
|
||||
#endif
|
||||
|
||||
void set_timer3_capture( void ) ;
|
||||
void set_timer3_ppm( void ) ;
|
||||
void setupPulsesPPM16( uint8_t proto ) ;
|
||||
|
||||
void startPulses()
|
||||
{
|
||||
#ifndef SIMU
|
||||
setupPulses();
|
||||
|
||||
#ifdef DSM2_SERIAL
|
||||
if (g_model.protocol != PROTO_DSM2)
|
||||
#endif
|
||||
|
||||
{
|
||||
#if defined(PCBV4)
|
||||
OCR1B = 0xffff; /* Prevent any PPM_PUT pin toggle before the TCNT1 interrupt
|
||||
fires for the first time and sets up the pulse period. */
|
||||
// TCCR1A |= (1<<COM1B0); // (COM1B1=0 and COM1B0=1 in TCCR1A) toogle the state of PB6(OC1B) on each TCNT1==OCR1B
|
||||
TCCR1A = (3<<COM1B0); // Connect OC1B to PPM_OUT pin (SET the state of PB6(OC1B) on next TCNT1==OCR1B)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(PCBV4)
|
||||
TIMSK1 |= (1<<OCIE1A); // Pulse generator enable immediately before mainloop
|
||||
#else
|
||||
TIMSK |= (1<<OCIE1A); // Pulse generator enable immediately before mainloop
|
||||
#endif
|
||||
|
||||
#endif // SIMU
|
||||
}
|
||||
|
||||
#define PULSES_SIZE 144
|
||||
uint8_t pulses2MHz[PULSES_SIZE] = {0}; // TODO check this length, pulled from er9x, perhaps too big
|
||||
uint8_t *pulses2MHzRPtr = pulses2MHz;
|
||||
|
||||
#if defined(DSM2) || defined(PXX)
|
||||
uint8_t *pulses2MHzWPtr = pulses2MHz;
|
||||
#endif
|
||||
|
||||
#define CTRL_END 0
|
||||
#define CTRL_CNT 1
|
||||
#define CTRL_REP_1CMD -3
|
||||
#define CTRL_REP_2CMD -6
|
||||
|
||||
#ifndef SIMU
|
||||
|
||||
ISR(TIMER1_COMPA_vect) //2MHz pulse generation
|
||||
{
|
||||
static uint8_t pulsePol; // TODO strange, it's always 0 at first, shouldn't it be initialized properly in setupPulses?
|
||||
|
||||
// Latency -- how far further on from interrupt trigger has the timer counted?
|
||||
// (or -- how long did it take to get to this function)
|
||||
uint8_t dt = TCNT1L;
|
||||
|
||||
#ifdef DSM2_SERIAL
|
||||
if (g_model.protocol == PROTO_DSM2) {
|
||||
OCR1A = 40000;
|
||||
// sei will be called inside setupPulses()
|
||||
setupPulses();
|
||||
cli();
|
||||
UCSR0B |= (1 << UDRIE0); // enable UDRE0 interrupt
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Orginal bitbang for PPM
|
||||
#if !defined(PCBV4)
|
||||
if (pulsePol) {
|
||||
PORTB |= (1<<OUT_B_PPM); // GCC optimisation should result in a single SBI instruction
|
||||
pulsePol = 0;
|
||||
}
|
||||
else {
|
||||
PORTB &= ~(1<<OUT_B_PPM);
|
||||
pulsePol = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
OCR1A = *((uint16_t*)pulses2MHzRPtr); // Schedule next interrupt vector (to this handler)
|
||||
|
||||
#if defined(PCBV4)
|
||||
OCR1B = *((uint16_t*)pulses2MHzRPtr); /* G: Using timer in CTC mode, restricted to using OCR1A for interrupt triggering.
|
||||
So we actually have to handle the OCR1B register separately in this way. */
|
||||
|
||||
// We cannot read the status of the PPM_OUT pin when OC1B is connected to it on the ATmega2560.
|
||||
// So the only way to set polarity is to manually control set/reset mode in COM1B0/1
|
||||
if (pulsePol) {
|
||||
TCCR1A = (3<<COM1B0); // SET the state of PB6(OC1B) on next TCNT1==OCR1B
|
||||
pulsePol = 0;
|
||||
}
|
||||
else {
|
||||
TCCR1A = (2<<COM1B0); // CLEAR the state of PB6(OC1B) on next TCNT1==OCR1B
|
||||
pulsePol = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
pulses2MHzRPtr += sizeof(uint16_t);
|
||||
if (*((uint16_t*)pulses2MHzRPtr) == 0) {
|
||||
|
||||
pulsePol = !g_model.pulsePol;
|
||||
|
||||
#if defined(PCBV4)
|
||||
TIMSK1 &= ~(1<<OCIE1A); //stop reentrance
|
||||
#else
|
||||
TIMSK &= ~(1<<OCIE1A); //stop reentrance
|
||||
#endif
|
||||
|
||||
// sei will be called inside setupPulses()
|
||||
|
||||
setupPulses();
|
||||
|
||||
// TODO test that it's optimized
|
||||
if (1
|
||||
#if defined(PXX)
|
||||
&& g_model.protocol != PROTO_PXX
|
||||
#endif
|
||||
#if defined(DSM2_PPM)
|
||||
&& g_model.protocol != PROTO_DSM2
|
||||
#endif
|
||||
) {
|
||||
|
||||
// cli is not needed because for these 2 protocols interrupts are not enabled when entering here
|
||||
|
||||
#if defined(PCBV4)
|
||||
TIMSK1 |= (1<<OCIE1A);
|
||||
#else
|
||||
TIMSK |= (1<<OCIE1A);
|
||||
#endif
|
||||
sei();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dt > g_tmr1Latency_max) g_tmr1Latency_max = dt;
|
||||
if (dt < g_tmr1Latency_min) g_tmr1Latency_min = dt;
|
||||
|
||||
heartbeat |= HEART_TIMER_PULSES;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
FORCEINLINE void setupPulsesPPM()
|
||||
{
|
||||
int16_t PPM_range = g_model.extendedLimits ? 640*2 : 512*2; //range of 0.7..1.7msec
|
||||
|
||||
//Total frame length = 22.5msec
|
||||
//each pulse is 0.7..1.7ms long with a 0.3ms stop tail
|
||||
//The pulse ISR is 2mhz that's why everything is multiplied by 2
|
||||
|
||||
// G: Found the following reference at th9x. The below code does not seem
|
||||
// to produce quite exactly this, to my eye. *shrug*
|
||||
// http://www.aerodesign.de/peter/2000/PCM/frame_ppm.gif
|
||||
uint16_t *ptr = (uint16_t *)pulses2MHz;
|
||||
uint8_t p = 8+(g_model.ppmNCH*2); // channels count
|
||||
uint16_t q = (g_model.ppmDelay*50+300)*2; //Stoplen *2
|
||||
uint16_t rest = 22500u*2-q; //Minimum Framelen=22.5 ms
|
||||
rest += (int16_t(g_model.ppmFrameLength))*1000;
|
||||
for (uint8_t i=0; i<p; i++) {
|
||||
#ifdef PPM_CENTER_ADJUSTABLE
|
||||
int16_t v = limit((int16_t)-PPM_range, g_chans512[i], (int16_t)PPM_range) + 2*(PPM_CENTER+g_model.servoCenter[i]);
|
||||
#else
|
||||
int16_t v = limit((int16_t)-PPM_range, g_chans512[i], (int16_t)PPM_range) + 2*PPM_CENTER;
|
||||
#endif
|
||||
rest -= v;
|
||||
*ptr++ = v - q; /* as Pat MacKenzie suggests, reviewed and modified by Cam */
|
||||
*ptr++ = q;
|
||||
}
|
||||
*ptr = rest;
|
||||
*(ptr+1) = q;
|
||||
*(ptr+2) = 0;
|
||||
|
||||
pulses2MHzRPtr = pulses2MHz;
|
||||
}
|
||||
|
||||
#if defined(PXX)
|
||||
const pm_uint16_t CRCTable[] PROGMEM =
|
||||
{
|
||||
0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf,
|
||||
0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7,
|
||||
0x1081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e,
|
||||
0x9cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876,
|
||||
0x2102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd,
|
||||
0xad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5,
|
||||
0x3183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c,
|
||||
0xbdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974,
|
||||
0x4204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb,
|
||||
0xce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3,
|
||||
0x5285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a,
|
||||
0xdecd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72,
|
||||
0x6306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9,
|
||||
0xef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1,
|
||||
0x7387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738,
|
||||
0xffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70,
|
||||
0x8408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7,
|
||||
0x0840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff,
|
||||
0x9489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036,
|
||||
0x18c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e,
|
||||
0xa50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5,
|
||||
0x2942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd,
|
||||
0xb58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134,
|
||||
0x39c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c,
|
||||
0xc60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3,
|
||||
0x4a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb,
|
||||
0xd68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232,
|
||||
0x5ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a,
|
||||
0xe70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1,
|
||||
0x6b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9,
|
||||
0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330,
|
||||
0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78
|
||||
};
|
||||
|
||||
uint8_t PcmByte ;
|
||||
uint8_t PcmBitCount ;
|
||||
uint16_t PcmCrc ;
|
||||
uint8_t PcmOnesCount ;
|
||||
uint8_t pxxFlag = 0;
|
||||
|
||||
void crc( uint8_t data )
|
||||
{
|
||||
PcmCrc=(PcmCrc>>8)^pgm_read_word(&CRCTable[(PcmCrc^data) & 0xFF]);
|
||||
}
|
||||
|
||||
|
||||
void putPcmPart( uint8_t value )
|
||||
{
|
||||
PcmByte >>= 2 ;
|
||||
PcmByte |= value ;
|
||||
if ( ++PcmBitCount >= 4 )
|
||||
{
|
||||
*pulses2MHzWPtr++ = PcmByte ;
|
||||
PcmBitCount = PcmByte = 0 ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void putPcmFlush()
|
||||
{
|
||||
while ( PcmBitCount != 0 )
|
||||
{
|
||||
putPcmPart( 0 ) ; // Empty
|
||||
}
|
||||
*pulses2MHzWPtr = 0 ; // Mark end
|
||||
}
|
||||
|
||||
void putPcmBit( uint8_t bit )
|
||||
{
|
||||
if ( bit )
|
||||
{
|
||||
PcmOnesCount += 1 ;
|
||||
putPcmPart( 0x80 ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
PcmOnesCount = 0 ;
|
||||
putPcmPart( 0xC0 ) ;
|
||||
}
|
||||
if ( PcmOnesCount >= 5 )
|
||||
{
|
||||
putPcmBit( 0 ) ; // Stuff a 0 bit in
|
||||
}
|
||||
}
|
||||
|
||||
void putPcmByte( uint8_t byte )
|
||||
{
|
||||
uint8_t i ;
|
||||
|
||||
crc( byte ) ;
|
||||
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
putPcmBit( byte & 0x80 ) ;
|
||||
byte <<= 1 ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void putPcmHead()
|
||||
{
|
||||
// send 7E, do not CRC
|
||||
// 01111110
|
||||
putPcmPart( 0xC0 ) ;
|
||||
putPcmPart( 0x80 ) ;
|
||||
putPcmPart( 0x80 ) ;
|
||||
putPcmPart( 0x80 ) ;
|
||||
putPcmPart( 0x80 ) ;
|
||||
putPcmPart( 0x80 ) ;
|
||||
putPcmPart( 0x80 ) ;
|
||||
putPcmPart( 0xC0 ) ;
|
||||
}
|
||||
|
||||
void setupPulsesPXX()
|
||||
{
|
||||
uint8_t i ;
|
||||
uint16_t chan ;
|
||||
uint16_t chan_1 ;
|
||||
|
||||
pulses2MHzWPtr = pulses2MHz;
|
||||
pulses2MHzRPtr = pulses2MHz;
|
||||
|
||||
PcmCrc = 0 ;
|
||||
PcmBitCount = PcmByte = 0 ;
|
||||
PcmOnesCount = 0 ;
|
||||
putPcmHead() ;
|
||||
putPcmByte( g_model.modelId ) ; // putPcmByte( g_model.rxnum ) ; //
|
||||
putPcmByte( pxxFlag ) ; // First byte of flags
|
||||
putPcmByte( 0 ) ; // Second byte of flags
|
||||
pxxFlag = 0; // reset flag after send
|
||||
for ( i = 0 ; i < 8 ; i += 2 ) // First 8 channels only
|
||||
{
|
||||
chan = g_chans512[i] * 3 / 4 + 2250 ;
|
||||
chan_1 = g_chans512[i+1] * 3 / 4 + 2250 ;
|
||||
putPcmByte( chan ) ; // Low byte of channel
|
||||
putPcmByte( ( ( chan >> 8 ) & 0x0F ) | ( chan_1 << 4) ) ; // 4 bits each from 2 channels
|
||||
putPcmByte( chan_1 >> 4 ) ; // High byte of channel
|
||||
}
|
||||
chan = PcmCrc ; // get the crc
|
||||
putPcmByte( chan ) ; // Checksum lo
|
||||
putPcmByte( chan >> 8 ) ; // Checksum hi
|
||||
putPcmHead( ) ;
|
||||
putPcmFlush() ;
|
||||
OCR1C += 40000 ; // 20mS on
|
||||
PORTB |= (1<<OUT_B_PPM);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DSM2_SERIAL
|
||||
|
||||
// DSM2 protocol pulled from th9x - Thanks thus!!!
|
||||
|
||||
//http://www.rclineforum.de/forum/board49-zubeh-r-elektronik-usw/fernsteuerungen-sender-und-emp/neuer-9-kanal-sender-f-r-70-au/Beitrag_3897736#post3897736
|
||||
//(dsm2( LP4DSM aus den RTF ( Ready To Fly ) Sendern von Spektrum.
|
||||
//http://www.rcgroups.com/forums/showpost.php?p=18554028&postcount=237
|
||||
// /home/thus/txt/flieger/PPMtoDSM.c
|
||||
/*
|
||||
125000 Baud 8n1 _ xxxx xxxx - ---
|
||||
#define DSM2_CHANNELS 6 // Max number of DSM2 Channels transmitted
|
||||
#define DSM2_BIT (8*2)
|
||||
bind:
|
||||
DSM2_Header = 0x80,0
|
||||
static byte DSM2_Channel[DSM2_CHANNELS*2] = {
|
||||
ch
|
||||
0x00,0xAA, 0 0aa
|
||||
0x05,0xFF, 1 1ff
|
||||
0x09,0xFF, 2 1ff
|
||||
0x0D,0xFF, 3 1ff
|
||||
0x13,0x54, 4 354
|
||||
0x14,0xAA 5 0aa
|
||||
};
|
||||
|
||||
normal:
|
||||
DSM2_Header = 0,0;
|
||||
DSM2_Channel[i*2] = (byte)(i<<2) | highByte(pulse);
|
||||
DSM2_Channel[i*2+1] = lowByte(pulse);
|
||||
|
||||
*/
|
||||
|
||||
bool s_bind_allowed = true;
|
||||
|
||||
FORCEINLINE void setupPulsesDsm2()
|
||||
{
|
||||
uint16_t *ptr = (uint16_t *)pulses2MHz;
|
||||
if (s_bind_allowed) {
|
||||
*ptr++ = (keyState(SW_Trainer) ? BIND_BIT : 0x00);
|
||||
s_bind_allowed = false;
|
||||
}
|
||||
else {
|
||||
*ptr++ = 0x00;
|
||||
}
|
||||
*ptr++ = g_model.modelId;
|
||||
for (uint8_t i=0; i<DSM2_CHANS; i++) {
|
||||
uint16_t pulse = limit(0, ((g_chans512[i]*13)>>5)+512,1023);
|
||||
*ptr++ = (i<<2) | ((pulse>>8)&0x03);
|
||||
*ptr++ = pulse & 0xff;
|
||||
}
|
||||
|
||||
pulses2MHzWPtr = (uint8_t *)ptr;
|
||||
pulses2MHzRPtr = pulses2MHz;
|
||||
}
|
||||
|
||||
void DSM2_Done()
|
||||
{
|
||||
UCSR0B &= ~((1 << TXEN0) | (1 << UDRIE0)); // disable UART TX and interrupt
|
||||
}
|
||||
|
||||
void DSM2_Init(void)
|
||||
{
|
||||
#ifndef SIMU
|
||||
|
||||
DDRE &= ~(1 << DDE0); // set RXD0 pin as input
|
||||
PORTE |= (1 << PORTE0); // enable pullup on RXD0 pin
|
||||
|
||||
#undef BAUD
|
||||
#define BAUD 125000
|
||||
|
||||
#include <util/setbaud.h>
|
||||
|
||||
UBRR0H = UBRRH_VALUE;
|
||||
UBRR0L = UBRRL_VALUE;
|
||||
UCSR0A &= ~(1 << U2X0); // disable double speed operation.
|
||||
|
||||
// set 8N1 (leave TX and RX disabled for now)
|
||||
UCSR0B = 0 | (0 << RXCIE0) | (0 << TXCIE0) | (0 << UDRIE0) | (0 << RXEN0) | (0 << TXEN0) | (0 << UCSZ02);
|
||||
UCSR0C = 0 | (1 << UCSZ01) | (1 << UCSZ00);
|
||||
|
||||
while (UCSR0A & (1 << RXC0)) UDR0; // flush receive buffer
|
||||
|
||||
// These should be running right from power up on a FrSky enabled '9X.
|
||||
DSM2_EnableTXD(); // enable DSM2 UART transmitter
|
||||
|
||||
#endif // SIMU
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DSM2_PPM)
|
||||
inline void _send_1(uint8_t v)
|
||||
{
|
||||
*pulses2MHzWPtr++ = v;
|
||||
}
|
||||
|
||||
#define BITLEN_DSM2 (8*2) //125000 Baud
|
||||
void sendByteDsm2(uint8_t b) //max 10changes 0 10 10 10 10 1
|
||||
{
|
||||
bool lev = 0;
|
||||
uint8_t len = BITLEN_DSM2; //max val: 9*16 < 256
|
||||
for( uint8_t i=0; i<=8; i++){ //8Bits + Stop=1
|
||||
bool nlev = b & 1; //lsb first
|
||||
if(lev == nlev){
|
||||
len += BITLEN_DSM2;
|
||||
}else{
|
||||
_send_1(len -1);
|
||||
len = BITLEN_DSM2;
|
||||
lev = nlev;
|
||||
}
|
||||
b = (b>>1) | 0x80; //shift in stop bit
|
||||
}
|
||||
_send_1(len+BITLEN_DSM2-1); // 2 stop bits
|
||||
}
|
||||
|
||||
void setupPulsesDsm2()
|
||||
{
|
||||
static uint8_t dsmDat[2+6*2] = {0xFF,0x00, 0x00,0xAA, 0x05,0xFF, 0x09,0xFF, 0x0D,0xFF, 0x13,0x54, 0x14,0xAA};
|
||||
uint8_t counter;
|
||||
|
||||
pulses2MHzWPtr = pulses2MHz;
|
||||
|
||||
// If more channels needed make sure the pulses union/array is large enough
|
||||
if (dsmDat[0] & BAD_DATA) // first time through, setup header
|
||||
{
|
||||
switch(g_model.ppmNCH)
|
||||
{
|
||||
case LPXDSM2:
|
||||
dsmDat[0] = BIND_BIT;
|
||||
break;
|
||||
case DSM2only:
|
||||
dsmDat[0] = 0x90;
|
||||
break;
|
||||
default:
|
||||
dsmDat[0] = 0x98; // DSMX bind mode
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((dsmDat[0] & BIND_BIT) && (!keyState(SW_Trainer))) dsmDat[0] &= ~BIND_BIT; // clear bind bit if trainer not pulled
|
||||
// TODO find a way to do that, FUNC SWITCH: if ((!(dsmDat[0] & BIND_BIT)) && getSwitch(MAX_DRSWITCH-1, 0, 0)) dsmDat[0] |= RANGECHECK_BIT; // range check function
|
||||
// else dsmDat[0] &= ~RANGECHECK_BIT;
|
||||
dsmDat[1] = g_model.modelId; // DSM2 Header second byte for model match
|
||||
for (uint8_t i=0; i<DSM2_CHANS; i++)
|
||||
{
|
||||
uint16_t pulse = limit(0, ((g_chans512[i]*13)>>5)+512,1023);
|
||||
dsmDat[2+2*i] = (i<<2) | ((pulse>>8)&0x03);
|
||||
dsmDat[3+2*i] = pulse & 0xff;
|
||||
}
|
||||
|
||||
for (counter=0; counter<14; counter++)
|
||||
sendByteDsm2(dsmDat[counter]);
|
||||
|
||||
pulses2MHzWPtr -= 1; //remove last stopbits and
|
||||
_send_1(255); //prolong them
|
||||
_send_1(0); //end of pulse stream
|
||||
|
||||
pulses2MHzRPtr = pulses2MHz;
|
||||
}
|
||||
#endif
|
||||
|
||||
void setupPulses()
|
||||
{
|
||||
if (s_current_protocol != g_model.protocol) {
|
||||
|
||||
s_current_protocol = g_model.protocol;
|
||||
|
||||
switch (g_model.protocol) {
|
||||
|
||||
#if defined(DSM2_PPM)
|
||||
case PROTO_DSM2:
|
||||
set_timer3_capture() ;
|
||||
TCCR1B = 0; // Stop counter
|
||||
OCR1C = 200; // 100 uS
|
||||
TCNT1 = 300; // Past the OCR1C value
|
||||
ICR1 = 44000; // Next frame starts in 22 mS
|
||||
#if defined(PCBV4)
|
||||
TIMSK1 &= ~0x3C; // All interrupts off
|
||||
TIFR1 = 0x2F;
|
||||
TIMSK1 |= 0x28; // Enable CAPT and COMPB
|
||||
#else
|
||||
TIMSK &= ~0x3C; // All interrupts off
|
||||
TIFR = 0x3C;
|
||||
ETIFR = 0x3F ;
|
||||
TIMSK |= 0x20; // Enable CAPT
|
||||
ETIMSK |= (1<<OCIE1C); // Enable COMPC
|
||||
#endif
|
||||
TCCR1A = (0 << WGM10);
|
||||
TCCR1B = (3 << WGM12) | (2 << CS10); // CTC ICR, 16MHz / 8
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(PXX)
|
||||
case PROTO_PXX:
|
||||
set_timer3_capture() ;
|
||||
TCCR1B = 0 ; // Stop counter
|
||||
TCNT1 = 0 ;
|
||||
OCR1B = 6000 ; // Next frame starts in 3 mS
|
||||
OCR1C = 4000 ; // Next frame setup in 2 mS
|
||||
#if defined(PCBV4)
|
||||
TIMSK1 &= ~0x3C; // All interrupts off
|
||||
TIFR1 = 0x2F;
|
||||
#else
|
||||
TIMSK &= ~0x3C; // All interrupts off
|
||||
TIFR = 0x3C ;
|
||||
ETIFR = 0x3F ;
|
||||
TIMSK |= (1<<OCIE1B) ; // Enable COMPB
|
||||
ETIMSK |= (1<<OCIE1C); // Enable COMPC
|
||||
#endif
|
||||
TCCR1A = 0;
|
||||
TCCR1B = (2<<CS10); //ICNC3 16MHz / 8
|
||||
break;
|
||||
#endif
|
||||
|
||||
case PROTO_PPM16 :
|
||||
TCCR1B = 0 ; // Stop counter
|
||||
OCR1A = 40000 ; // Next frame starts in 20 mS
|
||||
TCNT1 = 0 ;
|
||||
#if defined(PCBV4)
|
||||
TIMSK1 &= ~0x3C; // All interrupts off
|
||||
TIMSK3 &= ~(1<<OCIE1C) ; // COMPC1 off
|
||||
TIFR1 = 0x2F;
|
||||
TIMSK1 |= 0x10; // Enable COMPA
|
||||
#else
|
||||
TIMSK &= ~0x3C ; // All interrupts off
|
||||
ETIMSK &= ~(1<<OCIE1C) ; // COMPC1 off
|
||||
TIFR = 0x3C ; // Clear all pending interrupts
|
||||
ETIFR = 0x3F ; // Clear all pending interrupts
|
||||
TIMSK |= 0x10 ; // Enable COMPA
|
||||
#endif
|
||||
TCCR1A = (0<<WGM10) ;
|
||||
TCCR1B = (1 << WGM12) | (2<<CS10) ; // CTC OCRA, 16MHz / 8
|
||||
setupPulsesPPM16(PROTO_PPM16);
|
||||
OCR3A = 50000 ;
|
||||
OCR3B = 5000 ;
|
||||
set_timer3_ppm() ;
|
||||
break ;
|
||||
|
||||
case PROTO_PPMSIM :
|
||||
TCCR1B = 0 ; // Stop counter
|
||||
TCNT1 = 0 ;
|
||||
#if defined(PCBV4)
|
||||
TIMSK1 &= ~0x3C; // All interrupts off
|
||||
TIMSK3 &= ~(1<<OCIE1C) ; // COMPC1 off
|
||||
TIFR1 = 0x2F;
|
||||
#else
|
||||
TIMSK &= ~0x3C ; // All interrupts off
|
||||
ETIMSK &= ~(1<<OCIE1C) ; // COMPC1 off
|
||||
TIFR = 0x3C ; // Clear all pending interrupts
|
||||
ETIFR = 0x3F ; // Clear all pending interrupts
|
||||
#endif
|
||||
setupPulsesPPM16(PROTO_PPMSIM);
|
||||
OCR3A = 50000 ;
|
||||
OCR3B = 5000 ;
|
||||
set_timer3_ppm() ;
|
||||
break ;
|
||||
|
||||
default:
|
||||
set_timer3_capture() ;
|
||||
TCCR1B = 0; // Stop counter
|
||||
OCR1A = 40000; // Next frame starts in 20 mS
|
||||
TCNT1 = 0;
|
||||
#if defined(PCBV4)
|
||||
TIMSK1 &= ~0x3C; // All interrupts off
|
||||
TIFR1 = 0x2F;
|
||||
TIMSK1 |= 0x10; // Enable COMPA
|
||||
#else
|
||||
TIMSK &= ~0x3C; // All interrupts off
|
||||
TIFR = 0x3C;
|
||||
ETIFR = 0x3F ; // Clear all pending interrupts
|
||||
TIMSK |= 0x10; // Enable COMPA
|
||||
#endif
|
||||
// TCNT1 2MHz counter (auto-cleared) plus Capture Compare int.
|
||||
// Used for PPM pulse generator
|
||||
TCCR1A = (0 << WGM10);
|
||||
TCCR1B = (1 << WGM12) | (2 << CS10); // CTC OCRA, 16MHz / 8
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(g_model.protocol) {
|
||||
|
||||
#ifdef PXX
|
||||
case PROTO_PXX:
|
||||
sei();
|
||||
setupPulsesPXX();
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef DSM2
|
||||
case PROTO_DSM2:
|
||||
sei();
|
||||
setupPulsesDsm2();
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
// no sei here
|
||||
setupPulsesPPM();
|
||||
// if PPM16, PPM16 pulses are set up automatically within the interrupts
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SIMU
|
||||
|
||||
#if defined(DSM2_PPM) || defined(PXX)
|
||||
ISR(TIMER1_CAPT_vect) // 2MHz pulse generation
|
||||
{
|
||||
uint8_t x ;
|
||||
PORTB ^= (1<<OUT_B_PPM);
|
||||
x = *pulses2MHzRPtr++; // Byte size
|
||||
ICR1 = x ;
|
||||
if (x > 200) PORTB |= (1<<OUT_B_PPM); // Make sure pulses are the correct way up
|
||||
heartbeat |= HEART_TIMER_PULSES; // TODO why not in TIMER1_COMPB_vect (in setupPulses)?
|
||||
}
|
||||
|
||||
#if defined(PXX)
|
||||
ISR(TIMER1_COMPB_vect) // PXX main interrupt
|
||||
{
|
||||
uint8_t x ;
|
||||
PORTB ^= (1<<OUT_B_PPM) ;
|
||||
x = *pulses2MHzRPtr; // Byte size
|
||||
if ( ( x & 1 ) == 0 )
|
||||
{
|
||||
OCR1B += 32 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
OCR1B += 16 ;
|
||||
}
|
||||
if ( (x >>= 1) == 0 )
|
||||
{
|
||||
if ( *(++pulses2MHzRPtr) == 0 )
|
||||
{
|
||||
OCR1B = OCR1C + 2000 ; // 1mS on from OCR1B
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulses2MHzRPtr = x;
|
||||
}
|
||||
|
||||
heartbeat |= HEART_TIMER_PULSES;
|
||||
}
|
||||
#endif
|
||||
|
||||
ISR(TIMER1_COMPC_vect) // DSM2 or PXX end of frame
|
||||
{
|
||||
#if defined(DSM2_PPM) && defined(PXX)
|
||||
if ( g_model.protocol == PROTO_DSM2 ) {
|
||||
#endif
|
||||
|
||||
#if defined(DSM2_PPM)
|
||||
ICR1 = 41536 ; // next frame starts in 22ms 41536 = 2*(22000 - 14*11*8)
|
||||
if (OCR1C < 255) {
|
||||
OCR1C = 39000; // delay setup pulses by 19.5ms to reduce system latency
|
||||
}
|
||||
else {
|
||||
OCR1C = 200;
|
||||
// sei will be called inside setupPulses()
|
||||
setupPulses();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DSM2_PPM) && defined(PXX)
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
|
||||
#if defined(PXX)
|
||||
// must be PXX
|
||||
setupPulses() ;
|
||||
#endif
|
||||
|
||||
#if defined(DSM2_PPM) && defined(PXX)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void set_timer3_capture()
|
||||
{
|
||||
#ifndef SIMU
|
||||
#if defined (PCBV4)
|
||||
TIMSK3 &= ~( (1<<OCIE3A) | (1<<OCIE3B) | (1<<OCIE3C) ) ; // Stop compare interrupts
|
||||
#else
|
||||
ETIMSK &= ~( (1<<OCIE3A) | (1<<OCIE3B) | (1<<OCIE3C) ) ; // Stop compare interrupts
|
||||
#endif
|
||||
DDRE &= ~0x80; PORTE |= 0x80 ; // Bit 7 input + pullup
|
||||
|
||||
TCCR3B = 0 ; // Stop counter
|
||||
TCCR3A = 0;
|
||||
// Noise Canceller enabled, neg. edge, clock at 16MHz / 8 (2MHz) (Correct for PCB V4.x+ also)
|
||||
TCCR3B = (1<<ICNC3) | (0b010 << CS30);
|
||||
#if defined (PCBV4)
|
||||
TIMSK3 |= (1<<ICIE3);
|
||||
#else
|
||||
ETIMSK |= (1<<TICIE3);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_timer3_ppm()
|
||||
{
|
||||
#ifndef SIMU
|
||||
#if defined (PCBV4)
|
||||
TIMSK3 &= ~(1<<ICIE3);
|
||||
#else
|
||||
ETIMSK &= ~(1<<TICIE3) ; // Stop capture interrupt
|
||||
#endif
|
||||
DDRE |= 0x80; // Bit 7 output
|
||||
|
||||
TCCR3B = 0 ; // Stop counter
|
||||
TCCR3A = (0<<WGM10);
|
||||
TCCR3B = (1 << WGM12) | (2<<CS10); // CTC OCR1A, 16MHz / 8
|
||||
|
||||
#if defined (PCBV4)
|
||||
TIMSK3 |= ( (1<<OCIE3A) | (1<<OCIE3B) ); // enable immediately before mainloop
|
||||
#else
|
||||
ETIMSK |= ( (1<<OCIE3A) | (1<<OCIE3B) ); // enable immediately before mainloop
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t B3_comp_value ;
|
||||
|
||||
#ifndef SIMU
|
||||
|
||||
ISR(TIMER3_COMPA_vect) //2MHz pulse generation
|
||||
{
|
||||
static uint8_t pulsePol;
|
||||
static uint16_t *pulse2MHzPPM16RPtr = (uint16_t*) &pulses2MHz[PULSES_SIZE/2];
|
||||
|
||||
if (pulsePol) {
|
||||
PORTE |= 0x80 ; // (1<<OUT_B_PPM);
|
||||
pulsePol = 0;
|
||||
}
|
||||
else {
|
||||
PORTE &= ~0x80; // (1<<OUT_B_PPM);
|
||||
pulsePol = 1;
|
||||
}
|
||||
|
||||
OCR3A = *pulse2MHzPPM16RPtr++;
|
||||
OCR3B = B3_comp_value ;
|
||||
|
||||
if (*pulse2MHzPPM16RPtr == 0) {
|
||||
pulse2MHzPPM16RPtr = (uint16_t*) &pulses2MHz[PULSES_SIZE/2];
|
||||
pulsePol = g_model.pulsePol;
|
||||
}
|
||||
|
||||
heartbeat |= HEART_TIMER_PULSES;
|
||||
}
|
||||
|
||||
ISR(TIMER3_COMPB_vect) //2MHz pulse generation
|
||||
{
|
||||
sei() ;
|
||||
setupPulsesPPM16(g_model.protocol) ;
|
||||
}
|
||||
|
||||
#endif // SIMU
|
||||
|
||||
void setupPulsesPPM16(uint8_t proto)
|
||||
{
|
||||
int16_t PPM_range = g_model.extendedLimits ? 640*2 : 512*2; //range of 0.7..1.7msec
|
||||
|
||||
//Total frame length = 22.5msec
|
||||
//each pulse is 0.7..1.7ms long with a 0.3ms stop tail
|
||||
//The pulse ISR is 2mhz that's why everything is multiplied by 2
|
||||
uint16_t *ptr ;
|
||||
ptr = (uint16_t *) &pulses2MHz[PULSES_SIZE/2] ;
|
||||
uint8_t p= ( ( proto == PROTO_PPM16) ? 16 : 8 ) +g_model.ppmNCH*2 ; //Channels *2
|
||||
uint16_t q=(g_model.ppmDelay*50+300)*2; //Stoplen *2
|
||||
uint16_t rest=22500u*2-q; //Minimum Framelen=22.5 ms
|
||||
rest += (int16_t(g_model.ppmFrameLength))*1000;
|
||||
for (uint8_t i=(proto==PROTO_PPM16) ? p-8 : 0; i<p; i++) {
|
||||
#ifdef PPM_CENTER_ADJUSTABLE
|
||||
int16_t v = limit((int16_t)-PPM_range, g_chans512[i], (int16_t)PPM_range) + 2*(PPM_CENTER+g_model.servoCenter[i]);
|
||||
#else
|
||||
int16_t v = limit((int16_t)-PPM_range, g_chans512[i], (int16_t)PPM_range) + 2*PPM_CENTER;
|
||||
#endif
|
||||
rest -= v;
|
||||
*ptr++ = q;
|
||||
*ptr++ = v - q; /* as Pat MacKenzie suggests, reviewed and modified by Cam */
|
||||
}
|
||||
*ptr = q; //reverse these two assignments
|
||||
*(ptr+1) = rest;
|
||||
B3_comp_value = rest - 1000 ; // 500uS before end of sync pulse
|
||||
*(ptr+2) = 0;
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
128,64,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x7f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x7f,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x3f,0x3f,0x3f,0x3f,0xff,0x7f,0x7f,0x3f,0x3f,0x3f,0x3f,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x7f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x7f,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x3f,0x3f,0x3f,0x3f,0xff,0x7f,0x3f,0x3f,0x3f,0x3f,0x3f,0x7f,0xff,0xff,0xff,0xff,0x7f,0x0f,0x07,0x03,0x01,0x81,0xe0,0xf0,0xf0,0xf0,0xe0,0x00,0x01,0x01,0x07,0x1f,0xff,0xff,0xff,0xff,0xff,0xbf,0x3f,0x3f,0x3f,0x3f,0x7f,0xff,0xff,0xff,0xff,0xff,0x7f,0x3f,0x3f,0x3f,0x3f,0x3f,0xbf,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0x3f,0x07,0x03,0x01,0x00,0xc0,0xf0,0xf8,0xfc,0xfc,0xfc,0xfc,0xf8,0x00,0x00,0x00,0x01,0x03,0xff,0xff,0xff,0x3f,0x01,0x00,0x00,0x00,0x80,0xe0,0xf8,0xfc,0xfc,0xfc,0xf8,0x00,0x00,0x00,0x00,0x01,0xff,0xff,0x3f,0x07,0x03,0x01,0x00,0x00,0x10,0x18,0x1c,0x1c,0x1c,0x1c,0x18,0x00,0x00,0x00,0x01,0x03,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0xc0,0xf8,0xfc,0xfc,0xfc,0x10,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xe0,0x80,0x00,0x00,0x00,0x0f,0x1f,0x1f,0x1f,0x0f,0x03,0x00,0x00,0x00,0x00,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xf8,0xe0,0x00,0x00,0x01,0x07,0x07,0x01,0x80,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xe0,0xc0,0x80,0x00,0x00,0x0f,0x1f,0x1f,0x1f,0x1f,0x0f,0x07,0x01,0x80,0xc0,0xe0,0xf0,0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,0xc0,0x0f,0x1f,0x1f,0x1f,0x0f,0x07,0x01,0x00,0x80,0xe0,0xf0,0xfe,0xff,0xff,0xe0,0xc0,0x80,0x00,0x00,0x0e,0x0e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x0e,0xce,0xfe,0xfe,0xff,0xff,0x7f,0x03,0x00,0x00,0x00,0x80,0xfc,0xff,0xff,0xff,0x3f,0x03,0x00,0x00,0x00,0x80,0xfc,0xff,0xff,0x1f,0x0f,0x0f,0x1f,0x1f,0x1e,0x1e,0x1e,0x0e,0x0e,0x07,0x81,0xc0,0xe0,0xf0,0xfc,0xff,0xff,0xff,0xff,0x7f,0x3f,0x1f,0x0f,0x03,0x01,0x80,0xe0,0xf0,0xf8,0xe0,0x80,0x00,0x01,0x07,0x1f,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0xc0,0xfe,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
@@ -1,89 +0,0 @@
|
||||
#define s9xsplash_width 128
|
||||
#define s9xsplash_height 64
|
||||
static unsigned char s9xsplash_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xf8, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||
0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0x7f, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x70, 0xf0, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xf8,
|
||||
0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0xfe, 0x07, 0x87, 0xff, 0x07, 0xfe,
|
||||
0x0f, 0x06, 0x3f, 0xf8, 0xe0, 0x83, 0x3f, 0xf0, 0xff, 0x01, 0xf8, 0x07,
|
||||
0x01, 0xff, 0x01, 0xf8, 0x0f, 0x02, 0x1e, 0xfc, 0xe0, 0x07, 0x1f, 0xf8,
|
||||
0xff, 0x00, 0xf0, 0x07, 0x00, 0xfe, 0x00, 0xf0, 0x07, 0x00, 0x1c, 0xfc,
|
||||
0xe0, 0x07, 0x0f, 0xfc, 0x7f, 0x00, 0xe0, 0x03, 0x00, 0x7c, 0x00, 0xe0,
|
||||
0x07, 0x00, 0x1c, 0xfc, 0xe0, 0x0f, 0x06, 0xfe, 0x3f, 0xf0, 0xc0, 0x03,
|
||||
0x0e, 0x3c, 0xf0, 0xc0, 0x07, 0x0e, 0x1c, 0x7c, 0xe0, 0x0f, 0x06, 0xff,
|
||||
0x1f, 0xf8, 0xc1, 0x03, 0x1f, 0x1c, 0xf8, 0xc1, 0x07, 0x0f, 0x1c, 0x7c,
|
||||
0xe0, 0x1f, 0x80, 0xff, 0x1f, 0xfc, 0xc1, 0x03, 0x1f, 0x1c, 0xfc, 0xc1,
|
||||
0x07, 0x1f, 0x1c, 0x38, 0xe0, 0x1f, 0xc0, 0xff, 0x1f, 0xfc, 0xc1, 0x83,
|
||||
0x1f, 0x1c, 0x00, 0xc0, 0x03, 0x0f, 0x3c, 0x00, 0xf0, 0x3f, 0xe0, 0xff,
|
||||
0x0f, 0xfe, 0xc1, 0x81, 0x1f, 0x0c, 0x00, 0xc0, 0x83, 0x0f, 0x3e, 0x00,
|
||||
0xf0, 0x3f, 0xe0, 0xff, 0x0f, 0xfe, 0xc1, 0xc1, 0x1f, 0x0c, 0x00, 0xc0,
|
||||
0x83, 0x0f, 0x7e, 0x00, 0xf0, 0x3f, 0xf0, 0xff, 0x0f, 0xfe, 0xc1, 0xc1,
|
||||
0x1f, 0x0c, 0x00, 0xc0, 0x83, 0x0f, 0xfe, 0x60, 0xf8, 0x1f, 0xf0, 0xff,
|
||||
0x0f, 0xfe, 0xe0, 0xc1, 0x0f, 0x0e, 0xfe, 0xff, 0x83, 0x0f, 0xfe, 0x3f,
|
||||
0xf8, 0x0f, 0xe0, 0xff, 0x0f, 0xfe, 0xe0, 0xc1, 0x0f, 0x0e, 0xfe, 0xff,
|
||||
0xc1, 0x07, 0xff, 0x3f, 0xfc, 0x07, 0xe0, 0xff, 0x0f, 0x7e, 0xe0, 0xc0,
|
||||
0x07, 0x0e, 0xfe, 0xff, 0xc1, 0x07, 0xff, 0x1f, 0xfc, 0x07, 0xc1, 0xff,
|
||||
0x0f, 0x3c, 0xf0, 0x80, 0x03, 0x0f, 0xf8, 0xf3, 0xc1, 0x07, 0xcf, 0x07,
|
||||
0xfe, 0x83, 0xc1, 0xff, 0x1f, 0x00, 0xf8, 0x00, 0x80, 0x1f, 0x00, 0xf0,
|
||||
0xc1, 0x07, 0x07, 0x00, 0xff, 0xc1, 0x83, 0xff, 0x3f, 0x00, 0xfc, 0x20,
|
||||
0x80, 0x3f, 0x00, 0xf8, 0xc1, 0x03, 0x07, 0x80, 0xff, 0xc0, 0x83, 0xff,
|
||||
0x7f, 0x00, 0xfe, 0x20, 0xc0, 0x7f, 0x00, 0xf8, 0xe0, 0x83, 0x07, 0xc0,
|
||||
0x7f, 0xe0, 0x07, 0xff, 0xff, 0x81, 0x7f, 0x60, 0xf0, 0xff, 0x01, 0xfe,
|
||||
0xe0, 0x83, 0x1f, 0xf0, 0x3f, 0xf0, 0x07, 0xff, 0xff, 0xff, 0x7f, 0xf0,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0x7f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xf0, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xf0,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xf8, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xf8,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00 };
|
||||
-260
@@ -1,260 +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"
|
||||
|
||||
volatile uint8_t pinb=0xff, pinc=0xff, pind, pine=0xff, ping=0xff, pinh=0xff, pinj=0xff, pinl=0;
|
||||
uint8_t portb, portc, porth=0, dummyport;
|
||||
uint16_t dummyport16;
|
||||
const char *eepromFile = NULL;
|
||||
FILE *fp = NULL;
|
||||
|
||||
#if defined(PCBARM)
|
||||
Pio Pioa, Piob, Pioc;
|
||||
Twi Twio;
|
||||
Usart Usart0;
|
||||
uint32_t eeprom_pointer;
|
||||
char* eeprom_buffer_data;
|
||||
volatile int32_t eeprom_buffer_size;
|
||||
bool eeprom_read_operation;
|
||||
#define EESIZE (128*4096)
|
||||
void configure_pins( uint32_t pins, uint16_t config ) { }
|
||||
#else
|
||||
extern uint16_t eeprom_pointer;
|
||||
extern const char* eeprom_buffer_data;
|
||||
#endif
|
||||
|
||||
uint8_t eeprom[EESIZE];
|
||||
sem_t eeprom_write_sem;
|
||||
|
||||
void setSwitch(int8_t swtch)
|
||||
{
|
||||
switch (swtch) {
|
||||
case DSW_ID0:
|
||||
#if defined(PCBARM)
|
||||
PIOC->PIO_PDSR &= ~0x00004000;
|
||||
PIOC->PIO_PDSR |= 0x00000800;
|
||||
#elif defined(PCBV4)
|
||||
ping |= (1<<INP_G_ID1);
|
||||
pinb &= ~(1<<INP_B_ID2);
|
||||
#else
|
||||
ping |= (1<<INP_G_ID1);
|
||||
pine &= ~(1<<INP_E_ID2);
|
||||
#endif
|
||||
break;
|
||||
case DSW_ID1:
|
||||
#if defined(PCBARM)
|
||||
PIOC->PIO_PDSR |= 0x00004800;
|
||||
#elif defined(PCBV4)
|
||||
ping &= ~(1<<INP_G_ID1);
|
||||
pinb &= ~(1<<INP_B_ID2);
|
||||
#else
|
||||
ping &= ~(1<<INP_G_ID1);
|
||||
pine &= ~(1<<INP_E_ID2);
|
||||
#endif
|
||||
break;
|
||||
case DSW_ID2:
|
||||
#if defined(PCBARM)
|
||||
PIOC->PIO_PDSR &= ~0x00000800;
|
||||
PIOC->PIO_PDSR |= 0x00004000;
|
||||
#elif defined(PCBV4)
|
||||
ping &= ~(1<<INP_G_ID1);
|
||||
pinb |= (1<<INP_B_ID2);
|
||||
#else
|
||||
ping &= ~(1<<INP_G_ID1);
|
||||
pine |= (1<<INP_E_ID2);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool eeprom_thread_running = true;
|
||||
void *eeprom_write_function(void *)
|
||||
{
|
||||
while (!sem_wait(&eeprom_write_sem)) {
|
||||
|
||||
if (!eeprom_thread_running)
|
||||
return NULL;
|
||||
#if defined(PCBARM)
|
||||
if (eeprom_read_operation) {
|
||||
assert(eeprom_buffer_size);
|
||||
eeprom_read_block(eeprom_buffer_data, (const void *)(int64_t)eeprom_pointer, eeprom_buffer_size);
|
||||
// TODO sleep()
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
if (fp) {
|
||||
if (fseek(fp, eeprom_pointer, SEEK_SET) == -1)
|
||||
perror("error in fseek");
|
||||
}
|
||||
while (--eeprom_buffer_size) {
|
||||
assert(eeprom_buffer_size > 0);
|
||||
if (fp) {
|
||||
if (fwrite(eeprom_buffer_data, 1, 1, fp) != 1)
|
||||
perror("error in fwrite");
|
||||
#if !defined(PCBARM)
|
||||
sleep(5/*ms*/);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
memcpy(&eeprom[eeprom_pointer], eeprom_buffer_data, 1);
|
||||
}
|
||||
eeprom_pointer++;
|
||||
eeprom_buffer_data++;
|
||||
|
||||
if (fp && eeprom_buffer_size == 1) {
|
||||
fflush(fp);
|
||||
}
|
||||
}
|
||||
#if defined(PCBARM)
|
||||
}
|
||||
Spi_complete = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t main_thread_running = 0;
|
||||
char * main_thread_error = NULL;
|
||||
void *main_thread(void *)
|
||||
{
|
||||
#ifdef SIMU_EXCEPTIONS
|
||||
signal(SIGFPE, sig);
|
||||
signal(SIGSEGV, sig);
|
||||
|
||||
try {
|
||||
#endif
|
||||
g_menuStack[0] = menuMainView;
|
||||
g_menuStack[1] = menuProcModelSelect;
|
||||
|
||||
#ifdef PCBARM
|
||||
eeprom_init();
|
||||
#endif
|
||||
|
||||
eeReadAll(); //load general setup and selected model
|
||||
|
||||
if (main_thread_running == 1) {
|
||||
#ifdef SPLASH
|
||||
doSplash();
|
||||
#endif
|
||||
#if !defined(PCBARM)
|
||||
checkLowEEPROM();
|
||||
#endif
|
||||
checkTHR();
|
||||
checkSwitches();
|
||||
checkAlarm();
|
||||
}
|
||||
|
||||
while (main_thread_running) {
|
||||
perMain();
|
||||
sleep(1/*ms*/);
|
||||
}
|
||||
#ifdef SIMU_EXCEPTIONS
|
||||
}
|
||||
catch (...) {
|
||||
main_thread_running = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pthread_t main_thread_pid;
|
||||
void StartMainThread(bool tests)
|
||||
{
|
||||
main_thread_running = (tests ? 1 : 2);
|
||||
pthread_create(&main_thread_pid, NULL, &main_thread, NULL);
|
||||
}
|
||||
|
||||
void StopMainThread()
|
||||
{
|
||||
main_thread_running = 0;
|
||||
pthread_join(main_thread_pid, NULL);
|
||||
}
|
||||
|
||||
pthread_t eeprom_thread_pid;
|
||||
void StartEepromThread(const char *filename)
|
||||
{
|
||||
eepromFile = filename;
|
||||
if (eepromFile) {
|
||||
fp = fopen(eepromFile, "r+");
|
||||
if (!fp)
|
||||
fp = fopen(eepromFile, "w+");
|
||||
if (!fp) perror("error in fopen");
|
||||
}
|
||||
sem_init(&eeprom_write_sem, 0, 0);
|
||||
eeprom_thread_running = true;
|
||||
assert(!pthread_create(&eeprom_thread_pid, NULL, &eeprom_write_function, NULL));
|
||||
}
|
||||
|
||||
void StopEepromThread()
|
||||
{
|
||||
eeprom_thread_running = false;
|
||||
sem_post(&eeprom_write_sem);
|
||||
pthread_join(eeprom_thread_pid, NULL);
|
||||
}
|
||||
|
||||
void eeprom_read_block (void *pointer_ram,
|
||||
const void *pointer_eeprom,
|
||||
size_t size)
|
||||
{
|
||||
assert(size);
|
||||
|
||||
if (fp) {
|
||||
memset(pointer_ram, 0, size);
|
||||
if (fseek(fp, (long) pointer_eeprom, SEEK_SET)==-1) perror("error in seek");
|
||||
if (fread(pointer_ram, size, 1, fp) <= 0) perror("error in read");
|
||||
}
|
||||
else {
|
||||
memcpy(pointer_ram, &eeprom[(uint64_t)pointer_eeprom], size);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t stack_free()
|
||||
{
|
||||
return 500;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void EeFsDump(){
|
||||
for(int i=0; i<EESIZE; i++)
|
||||
{
|
||||
printf("%02x ",eeprom[i]);
|
||||
if(i%16 == 15) puts("");
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
#endif
|
||||
@@ -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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user