ST-DEVKIT-LRWAN
Dependents: DISCO-L072CZ-LRWAN1-base
Fork of SX1276GenericLib by
sx1276/arduino-mbed.cpp@65:b2d98328fcba, 2017-07-11 (annotated)
- Committer:
- Helmut Tschemernjak
- Date:
- Tue Jul 11 13:32:34 2017 +0200
- Revision:
- 65:b2d98328fcba
- Parent:
- sx1276/sx1276-arduino-hal.cpp@61:08b50780eb91
- Child:
- 66:fbb2da34bd9a
Added Arduino Support, it still needs further testing
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Helmut Tschemernjak | 46:e78a1d0391ac | 1 | /* |
Helmut Tschemernjak | 65:b2d98328fcba | 2 | * The file is Licensed under the Apache License, Version 2.0 |
Helmut Tschemernjak | 46:e78a1d0391ac | 3 | * (c) 2017 Helmut Tschemernjak |
Helmut Tschemernjak | 46:e78a1d0391ac | 4 | * 30826 Garbsen (Hannover) Germany |
Helmut Tschemernjak | 46:e78a1d0391ac | 5 | */ |
Helmut Tschemernjak | 46:e78a1d0391ac | 6 | |
Helmut Tschemernjak | 65:b2d98328fcba | 7 | #ifdef ARDUINO |
Helmut Tschemernjak | 65:b2d98328fcba | 8 | |
Helmut Tschemernjak | 65:b2d98328fcba | 9 | using namespace std; |
Helmut Tschemernjak | 65:b2d98328fcba | 10 | |
Helmut Tschemernjak | 65:b2d98328fcba | 11 | #include "arduino-mbed.h" |
Helmut Tschemernjak | 65:b2d98328fcba | 12 | |
Helmut Tschemernjak | 65:b2d98328fcba | 13 | |
Helmut Tschemernjak | 65:b2d98328fcba | 14 | static void pinInt00(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 15 | static void pinInt01(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 16 | static void pinInt02(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 17 | static void pinInt03(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 18 | static void pinInt04(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 19 | static void pinInt05(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 20 | static void pinInt06(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 21 | static void pinInt07(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 22 | static void pinInt08(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 23 | static void pinInt09(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 24 | static void pinInt10(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 25 | static void pinInt11(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 26 | static void pinInt12(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 27 | static void pinInt13(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 28 | static void pinInt14(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 29 | static void pinInt15(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 30 | static void pinInt16(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 31 | static void pinInt17(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 32 | static void pinInt18(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 33 | static void pinInt19(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 34 | static void pinInt20(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 35 | static void pinInt21(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 36 | static void pinInt22(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 37 | static void pinInt23(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 38 | static void pinInt24(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 39 | static void pinInt25(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 40 | static void pinInt26(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 41 | static void pinInt27(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 42 | static void pinInt28(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 43 | static void pinInt29(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 44 | static void pinInt30(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 45 | static void pinInt31(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 46 | static void pinInt32(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 47 | static void pinInt33(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 48 | static void pinInt34(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 49 | static void pinInt35(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 50 | static void pinInt36(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 51 | static void pinInt37(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 52 | static void pinInt38(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 53 | static void pinInt39(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 54 | static void pinInt40(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 55 | static void pinInt41(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 56 | static void pinInt42(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 57 | static void pinInt43(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 58 | static void pinInt44(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 59 | static void pinInt45(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 60 | static void pinInt46(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 61 | static void pinInt47(void); |
Helmut Tschemernjak | 46:e78a1d0391ac | 62 | |
Helmut Tschemernjak | 46:e78a1d0391ac | 63 | |
Helmut Tschemernjak | 46:e78a1d0391ac | 64 | |
Helmut Tschemernjak | 65:b2d98328fcba | 65 | #define MAX_MCU_PINS 48 |
Helmut Tschemernjak | 65:b2d98328fcba | 66 | class InterruptIn; |
Helmut Tschemernjak | 65:b2d98328fcba | 67 | struct intPtrTable { |
Helmut Tschemernjak | 65:b2d98328fcba | 68 | void (*func)(void); |
Helmut Tschemernjak | 65:b2d98328fcba | 69 | InterruptIn *context; |
Helmut Tschemernjak | 65:b2d98328fcba | 70 | } intPtrTable[MAX_MCU_PINS] = { |
Helmut Tschemernjak | 65:b2d98328fcba | 71 | { pinInt00, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 72 | { pinInt01, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 73 | { pinInt02, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 74 | { pinInt03, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 75 | { pinInt04, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 76 | { pinInt05, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 77 | { pinInt06, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 78 | { pinInt07, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 79 | { pinInt08, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 80 | { pinInt09, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 81 | { pinInt10, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 82 | { pinInt11, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 83 | { pinInt12, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 84 | { pinInt13, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 85 | { pinInt14, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 86 | { pinInt15, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 87 | { pinInt16, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 88 | { pinInt17, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 89 | { pinInt18, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 90 | { pinInt19, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 91 | { pinInt20, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 92 | { pinInt21, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 93 | { pinInt22, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 94 | { pinInt23, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 95 | { pinInt24, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 96 | { pinInt25, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 97 | { pinInt26, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 98 | { pinInt27, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 99 | { pinInt28, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 100 | { pinInt29, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 101 | { pinInt30, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 102 | { pinInt31, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 103 | { pinInt32, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 104 | { pinInt33, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 105 | { pinInt34, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 106 | { pinInt35, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 107 | { pinInt36, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 108 | { pinInt37, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 109 | { pinInt38, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 110 | { pinInt39, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 111 | { pinInt40, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 112 | { pinInt41, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 113 | { pinInt42, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 114 | { pinInt43, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 115 | { pinInt44, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 116 | { pinInt45, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 117 | { pinInt46, NULL }, |
Helmut Tschemernjak | 65:b2d98328fcba | 118 | { pinInt47, NULL } |
Helmut Tschemernjak | 65:b2d98328fcba | 119 | }; // our max MCUs pins |
Helmut Tschemernjak | 46:e78a1d0391ac | 120 | |
Helmut Tschemernjak | 46:e78a1d0391ac | 121 | |
Helmut Tschemernjak | 46:e78a1d0391ac | 122 | |
Helmut Tschemernjak | 65:b2d98328fcba | 123 | static void pinInt00(void) { InterruptIn::_irq_handler(intPtrTable[0].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 124 | static void pinInt01(void) { InterruptIn::_irq_handler(intPtrTable[1].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 125 | static void pinInt02(void) { InterruptIn::_irq_handler(intPtrTable[2].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 126 | static void pinInt03(void) { InterruptIn::_irq_handler(intPtrTable[3].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 127 | static void pinInt04(void) { InterruptIn::_irq_handler(intPtrTable[4].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 128 | static void pinInt05(void) { InterruptIn::_irq_handler(intPtrTable[5].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 129 | static void pinInt06(void) { InterruptIn::_irq_handler(intPtrTable[6].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 130 | static void pinInt07(void) { InterruptIn::_irq_handler(intPtrTable[7].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 131 | static void pinInt08(void) { InterruptIn::_irq_handler(intPtrTable[8].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 132 | static void pinInt09(void) { InterruptIn::_irq_handler(intPtrTable[9].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 133 | static void pinInt10(void) { InterruptIn::_irq_handler(intPtrTable[10].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 134 | static void pinInt11(void) { InterruptIn::_irq_handler(intPtrTable[11].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 135 | static void pinInt12(void) { InterruptIn::_irq_handler(intPtrTable[12].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 136 | static void pinInt13(void) { InterruptIn::_irq_handler(intPtrTable[13].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 137 | static void pinInt14(void) { InterruptIn::_irq_handler(intPtrTable[14].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 138 | static void pinInt15(void) { InterruptIn::_irq_handler(intPtrTable[15].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 139 | static void pinInt16(void) { InterruptIn::_irq_handler(intPtrTable[16].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 140 | static void pinInt17(void) { InterruptIn::_irq_handler(intPtrTable[17].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 141 | static void pinInt18(void) { InterruptIn::_irq_handler(intPtrTable[18].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 142 | static void pinInt19(void) { InterruptIn::_irq_handler(intPtrTable[19].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 143 | static void pinInt20(void) { InterruptIn::_irq_handler(intPtrTable[20].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 144 | static void pinInt21(void) { InterruptIn::_irq_handler(intPtrTable[21].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 145 | static void pinInt22(void) { InterruptIn::_irq_handler(intPtrTable[22].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 146 | static void pinInt23(void) { InterruptIn::_irq_handler(intPtrTable[23].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 147 | static void pinInt24(void) { InterruptIn::_irq_handler(intPtrTable[24].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 148 | static void pinInt25(void) { InterruptIn::_irq_handler(intPtrTable[25].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 149 | static void pinInt26(void) { InterruptIn::_irq_handler(intPtrTable[26].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 150 | static void pinInt27(void) { InterruptIn::_irq_handler(intPtrTable[27].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 151 | static void pinInt28(void) { InterruptIn::_irq_handler(intPtrTable[28].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 152 | static void pinInt29(void) { InterruptIn::_irq_handler(intPtrTable[29].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 153 | static void pinInt30(void) { InterruptIn::_irq_handler(intPtrTable[30].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 154 | static void pinInt31(void) { InterruptIn::_irq_handler(intPtrTable[31].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 155 | static void pinInt32(void) { InterruptIn::_irq_handler(intPtrTable[32].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 156 | static void pinInt33(void) { InterruptIn::_irq_handler(intPtrTable[33].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 157 | static void pinInt34(void) { InterruptIn::_irq_handler(intPtrTable[34].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 158 | static void pinInt35(void) { InterruptIn::_irq_handler(intPtrTable[35].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 159 | static void pinInt36(void) { InterruptIn::_irq_handler(intPtrTable[36].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 160 | static void pinInt37(void) { InterruptIn::_irq_handler(intPtrTable[37].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 161 | static void pinInt38(void) { InterruptIn::_irq_handler(intPtrTable[38].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 162 | static void pinInt39(void) { InterruptIn::_irq_handler(intPtrTable[39].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 163 | static void pinInt40(void) { InterruptIn::_irq_handler(intPtrTable[40].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 164 | static void pinInt41(void) { InterruptIn::_irq_handler(intPtrTable[41].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 165 | static void pinInt42(void) { InterruptIn::_irq_handler(intPtrTable[42].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 166 | static void pinInt43(void) { InterruptIn::_irq_handler(intPtrTable[43].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 167 | static void pinInt44(void) { InterruptIn::_irq_handler(intPtrTable[44].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 168 | static void pinInt45(void) { InterruptIn::_irq_handler(intPtrTable[45].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 169 | static void pinInt46(void) { InterruptIn::_irq_handler(intPtrTable[46].context); } |
Helmut Tschemernjak | 65:b2d98328fcba | 170 | static void pinInt47(void) { InterruptIn::_irq_handler(intPtrTable[47].context); } |
Helmut Tschemernjak | 46:e78a1d0391ac | 171 | |
Helmut Tschemernjak | 46:e78a1d0391ac | 172 | |
Helmut Tschemernjak | 65:b2d98328fcba | 173 | |
Helmut Tschemernjak | 46:e78a1d0391ac | 174 | |
Helmut Tschemernjak | 65:b2d98328fcba | 175 | void |
Helmut Tschemernjak | 65:b2d98328fcba | 176 | InterruptIn::rise(Callback<void()> func) { |
Helmut Tschemernjak | 65:b2d98328fcba | 177 | if (_gpioPin >= MAX_MCU_PINS-1) |
Helmut Tschemernjak | 65:b2d98328fcba | 178 | return; |
Helmut Tschemernjak | 65:b2d98328fcba | 179 | if (func) { |
Helmut Tschemernjak | 65:b2d98328fcba | 180 | _func = func; |
Helmut Tschemernjak | 65:b2d98328fcba | 181 | intPtrTable[_gpioPin].context = this; |
Helmut Tschemernjak | 65:b2d98328fcba | 182 | attachInterrupt(digitalPinToInterrupt(_gpioPin), intPtrTable[_gpioPin].func, RISING); |
Helmut Tschemernjak | 65:b2d98328fcba | 183 | } else { |
Helmut Tschemernjak | 65:b2d98328fcba | 184 | _func = InterruptIn::donothing; |
Helmut Tschemernjak | 65:b2d98328fcba | 185 | intPtrTable[_gpioPin].context = NULL; |
Helmut Tschemernjak | 65:b2d98328fcba | 186 | detachInterrupt(_gpioPin); |
Helmut Tschemernjak | 46:e78a1d0391ac | 187 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 188 | }; |
Helmut Tschemernjak | 46:e78a1d0391ac | 189 | |
Helmut Tschemernjak | 65:b2d98328fcba | 190 | void |
Helmut Tschemernjak | 65:b2d98328fcba | 191 | InterruptIn::fall(Callback<void()> func) { |
Helmut Tschemernjak | 65:b2d98328fcba | 192 | if (func) { |
Helmut Tschemernjak | 65:b2d98328fcba | 193 | _func = func; |
Helmut Tschemernjak | 65:b2d98328fcba | 194 | intPtrTable[_gpioPin].context = this; |
Helmut Tschemernjak | 65:b2d98328fcba | 195 | attachInterrupt(digitalPinToInterrupt(_gpioPin), intPtrTable[_gpioPin].func, FALLING); |
Helmut Tschemernjak | 65:b2d98328fcba | 196 | } else { |
Helmut Tschemernjak | 65:b2d98328fcba | 197 | _func = InterruptIn::donothing; |
Helmut Tschemernjak | 65:b2d98328fcba | 198 | intPtrTable[_gpioPin].context = NULL; |
Helmut Tschemernjak | 65:b2d98328fcba | 199 | detachInterrupt(_gpioPin); |
Helmut Tschemernjak | 46:e78a1d0391ac | 200 | } |
Helmut Tschemernjak | 46:e78a1d0391ac | 201 | } |
Helmut Tschemernjak | 46:e78a1d0391ac | 202 | |
Helmut Tschemernjak | 46:e78a1d0391ac | 203 | |
Helmut Tschemernjak | 65:b2d98328fcba | 204 | #define MAX_TIMEOUTS 10 |
Helmut Tschemernjak | 65:b2d98328fcba | 205 | class Timeout; |
Helmut Tschemernjak | 65:b2d98328fcba | 206 | struct TimeoutVector { |
Helmut Tschemernjak | 65:b2d98328fcba | 207 | Timeout *timer; |
Helmut Tschemernjak | 65:b2d98328fcba | 208 | volatile uint32_t timeout; // us |
Helmut Tschemernjak | 65:b2d98328fcba | 209 | } TimeOuts[MAX_TIMEOUTS]; |
Helmut Tschemernjak | 65:b2d98328fcba | 210 | |
Helmut Tschemernjak | 65:b2d98328fcba | 211 | |
Helmut Tschemernjak | 65:b2d98328fcba | 212 | #if defined(__SAMD21G18A__) || defined(__SAMD21J18A__) |
Helmut Tschemernjak | 65:b2d98328fcba | 213 | /* |
Helmut Tschemernjak | 65:b2d98328fcba | 214 | * __SAMD21J18A__ is the SamD21 Explained Board |
Helmut Tschemernjak | 65:b2d98328fcba | 215 | * __SAMD21G18A__ is Genuino Zero-Board (compatible with the LoRa board) |
Helmut Tschemernjak | 65:b2d98328fcba | 216 | */ |
Helmut Tschemernjak | 65:b2d98328fcba | 217 | |
Helmut Tschemernjak | 65:b2d98328fcba | 218 | /* |
Helmut Tschemernjak | 65:b2d98328fcba | 219 | * see tcc.h included from |
Helmut Tschemernjak | 65:b2d98328fcba | 220 | * Arduino15/packages/arduino/tools/CMSIS-Atmel/1.1.0/CMSIS/ |
Helmut Tschemernjak | 65:b2d98328fcba | 221 | * Device/ATMEL/samd21/include/component/tcc.h |
Helmut Tschemernjak | 65:b2d98328fcba | 222 | */ |
Helmut Tschemernjak | 65:b2d98328fcba | 223 | static const struct TCC_CONFIG { |
Helmut Tschemernjak | 65:b2d98328fcba | 224 | Tcc *tcc_ptr; |
Helmut Tschemernjak | 65:b2d98328fcba | 225 | IRQn_Type tcc_irq; |
Helmut Tschemernjak | 65:b2d98328fcba | 226 | uint8_t nbits; |
Helmut Tschemernjak | 65:b2d98328fcba | 227 | } TCC_CONFIG[] { |
Helmut Tschemernjak | 65:b2d98328fcba | 228 | { TCC0, TCC0_IRQn, 24 }, |
Helmut Tschemernjak | 65:b2d98328fcba | 229 | { TCC1, TCC1_IRQn, 24 }, |
Helmut Tschemernjak | 65:b2d98328fcba | 230 | { TCC2, TCC2_IRQn, 16 }, |
Helmut Tschemernjak | 65:b2d98328fcba | 231 | }; |
Helmut Tschemernjak | 65:b2d98328fcba | 232 | #define USE_TCC 0 // TCC0, TTC1, TTC2 are working using the Arduino D21 |
Helmut Tschemernjak | 65:b2d98328fcba | 233 | |
Helmut Tschemernjak | 65:b2d98328fcba | 234 | |
Helmut Tschemernjak | 65:b2d98328fcba | 235 | static bool initTimerDone = false; |
Helmut Tschemernjak | 65:b2d98328fcba | 236 | |
Helmut Tschemernjak | 65:b2d98328fcba | 237 | static void initTimer() { |
Helmut Tschemernjak | 65:b2d98328fcba | 238 | Tcc *TC = TCC_CONFIG[USE_TCC].tcc_ptr; |
Helmut Tschemernjak | 65:b2d98328fcba | 239 | |
Helmut Tschemernjak | 65:b2d98328fcba | 240 | // Enable clock for TC, see gclk.h |
Helmut Tschemernjak | 65:b2d98328fcba | 241 | if (TC == TCC0 || TC == TCC1) { |
Helmut Tschemernjak | 65:b2d98328fcba | 242 | REG_GCLK_CLKCTRL = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TCC0_TCC1); |
Helmut Tschemernjak | 65:b2d98328fcba | 243 | } else if (TC == TCC2) { |
Helmut Tschemernjak | 65:b2d98328fcba | 244 | REG_GCLK_CLKCTRL = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TCC2_TC3_Val); |
Helmut Tschemernjak | 46:e78a1d0391ac | 245 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 246 | while (GCLK->STATUS.bit.SYNCBUSY == 1); // wait for sync |
Helmut Tschemernjak | 65:b2d98328fcba | 247 | |
Helmut Tschemernjak | 65:b2d98328fcba | 248 | TC->CTRLA.reg &= ~TCC_CTRLA_ENABLE; // Disable TC |
Helmut Tschemernjak | 65:b2d98328fcba | 249 | while (TC->SYNCBUSY.bit.ENABLE == 1); // wait for sync |
Helmut Tschemernjak | 65:b2d98328fcba | 250 | |
Helmut Tschemernjak | 65:b2d98328fcba | 251 | TC->CTRLA.reg |= (TCC_CTRLA_PRESCALER_DIV1024 | TCC_CTRLA_RUNSTDBY); // Set perscaler |
Helmut Tschemernjak | 65:b2d98328fcba | 252 | |
Helmut Tschemernjak | 65:b2d98328fcba | 253 | TC->WAVE.reg |= TCC_WAVE_WAVEGEN_NFRQ; // Set wave form configuration |
Helmut Tschemernjak | 65:b2d98328fcba | 254 | while (TC->SYNCBUSY.bit.WAVE == 1); // wait for sync |
Helmut Tschemernjak | 65:b2d98328fcba | 255 | |
Helmut Tschemernjak | 65:b2d98328fcba | 256 | TC->PER.bit.PER = 0xFFFFFF; // set counter top to max 24 bit |
Helmut Tschemernjak | 65:b2d98328fcba | 257 | while (TC->SYNCBUSY.bit.PER == 1); // wait for sync |
Helmut Tschemernjak | 65:b2d98328fcba | 258 | |
Helmut Tschemernjak | 65:b2d98328fcba | 259 | // the compare counter TC->CC[0].reg will be set in the startTimer |
Helmut Tschemernjak | 65:b2d98328fcba | 260 | // after the timeout calculation is known. |
Helmut Tschemernjak | 65:b2d98328fcba | 261 | |
Helmut Tschemernjak | 65:b2d98328fcba | 262 | // Interrupts |
Helmut Tschemernjak | 65:b2d98328fcba | 263 | TC->INTENSET.reg = 0; // disable all interrupts |
Helmut Tschemernjak | 65:b2d98328fcba | 264 | TC->INTENSET.bit.OVF = 1; // enable overfollow |
Helmut Tschemernjak | 65:b2d98328fcba | 265 | TC->INTENSET.bit.MC0 = 1; // enable compare match to CC0 |
Helmut Tschemernjak | 65:b2d98328fcba | 266 | |
Helmut Tschemernjak | 65:b2d98328fcba | 267 | NVIC_EnableIRQ( TCC_CONFIG[USE_TCC].tcc_irq); // Enable InterruptVector |
Helmut Tschemernjak | 65:b2d98328fcba | 268 | initTimerDone = true; |
Helmut Tschemernjak | 46:e78a1d0391ac | 269 | } |
Helmut Tschemernjak | 46:e78a1d0391ac | 270 | |
Helmut Tschemernjak | 65:b2d98328fcba | 271 | static void stopTimer(void) |
Helmut Tschemernjak | 46:e78a1d0391ac | 272 | { |
Helmut Tschemernjak | 65:b2d98328fcba | 273 | Tcc *TC = TCC_CONFIG[USE_TCC].tcc_ptr; |
Helmut Tschemernjak | 65:b2d98328fcba | 274 | |
Helmut Tschemernjak | 65:b2d98328fcba | 275 | TC->CTRLA.reg &= ~TCC_CTRLA_ENABLE; // Disable TC |
Helmut Tschemernjak | 65:b2d98328fcba | 276 | while (TC->SYNCBUSY.bit.ENABLE == 1); // wait for sync |
Helmut Tschemernjak | 46:e78a1d0391ac | 277 | } |
Helmut Tschemernjak | 46:e78a1d0391ac | 278 | |
Helmut Tschemernjak | 65:b2d98328fcba | 279 | static void startTimer(uint32_t delay_us) |
Helmut Tschemernjak | 46:e78a1d0391ac | 280 | { |
Helmut Tschemernjak | 65:b2d98328fcba | 281 | Tcc *TC = TCC_CONFIG[USE_TCC].tcc_ptr; |
Helmut Tschemernjak | 65:b2d98328fcba | 282 | |
Helmut Tschemernjak | 65:b2d98328fcba | 283 | if (!initTimerDone) |
Helmut Tschemernjak | 65:b2d98328fcba | 284 | initTimer(); // initial setup with stopped timer |
Helmut Tschemernjak | 65:b2d98328fcba | 285 | |
Helmut Tschemernjak | 65:b2d98328fcba | 286 | stopTimer(); // avoid timer interrupts while calculating |
Helmut Tschemernjak | 46:e78a1d0391ac | 287 | |
Helmut Tschemernjak | 65:b2d98328fcba | 288 | /* |
Helmut Tschemernjak | 65:b2d98328fcba | 289 | * every 21333 ns equals one tick (1/(48000000/1024)) |
Helmut Tschemernjak | 65:b2d98328fcba | 290 | * COUNT*DIVIDER*SECS until interrupt |
Helmut Tschemernjak | 65:b2d98328fcba | 291 | * 48 Mhz = (65536*1024)/1.398636s |
Helmut Tschemernjak | 65:b2d98328fcba | 292 | */ |
Helmut Tschemernjak | 65:b2d98328fcba | 293 | long long nclocks = delay_us * 1000; // ns; |
Helmut Tschemernjak | 65:b2d98328fcba | 294 | nclocks = nclocks / 21333; |
Helmut Tschemernjak | 65:b2d98328fcba | 295 | int nCounts = nclocks; |
Helmut Tschemernjak | 65:b2d98328fcba | 296 | |
Helmut Tschemernjak | 65:b2d98328fcba | 297 | int bits = TCC_CONFIG[USE_TCC].nbits; |
Helmut Tschemernjak | 65:b2d98328fcba | 298 | int maxCounts = (uint32_t)(1<<bits)-1; |
Helmut Tschemernjak | 46:e78a1d0391ac | 299 | |
Helmut Tschemernjak | 65:b2d98328fcba | 300 | if (nCounts > maxCounts) // if count exceeds timer capacity |
Helmut Tschemernjak | 65:b2d98328fcba | 301 | nCounts = maxCounts; // set the largest posible count. |
Helmut Tschemernjak | 65:b2d98328fcba | 302 | if (nCounts == 0) |
Helmut Tschemernjak | 65:b2d98328fcba | 303 | nCounts = 1; |
Helmut Tschemernjak | 65:b2d98328fcba | 304 | TC->CC[0].bit.CC = nCounts; |
Helmut Tschemernjak | 65:b2d98328fcba | 305 | while (TC->SYNCBUSY.bit.CC0 == 1); // wait for sync |
Helmut Tschemernjak | 46:e78a1d0391ac | 306 | |
Helmut Tschemernjak | 65:b2d98328fcba | 307 | TC->CTRLA.reg |= TCC_CTRLA_ENABLE ; // Enable TC |
Helmut Tschemernjak | 65:b2d98328fcba | 308 | while (TC->SYNCBUSY.bit.ENABLE == 1); // wait for sync |
Helmut Tschemernjak | 65:b2d98328fcba | 309 | #if 1 |
Helmut Tschemernjak | 65:b2d98328fcba | 310 | Serial.print(millis(), DEC); |
Helmut Tschemernjak | 65:b2d98328fcba | 311 | Serial.print(" startTimer: nCounts="); |
Helmut Tschemernjak | 65:b2d98328fcba | 312 | Serial.println(nCounts, DEC); |
Helmut Tschemernjak | 65:b2d98328fcba | 313 | #endif |
Helmut Tschemernjak | 46:e78a1d0391ac | 314 | } |
Helmut Tschemernjak | 46:e78a1d0391ac | 315 | |
Helmut Tschemernjak | 46:e78a1d0391ac | 316 | |
Helmut Tschemernjak | 46:e78a1d0391ac | 317 | |
Helmut Tschemernjak | 65:b2d98328fcba | 318 | #if USE_TCC == 0 |
Helmut Tschemernjak | 65:b2d98328fcba | 319 | void TCC0_Handler() |
Helmut Tschemernjak | 65:b2d98328fcba | 320 | #elif USE_TCC == 1 |
Helmut Tschemernjak | 65:b2d98328fcba | 321 | void TCC1_Handler() |
Helmut Tschemernjak | 65:b2d98328fcba | 322 | #elif USE_TCC == 2 |
Helmut Tschemernjak | 65:b2d98328fcba | 323 | void TCC2_Handler() |
Helmut Tschemernjak | 65:b2d98328fcba | 324 | #endif |
Helmut Tschemernjak | 65:b2d98328fcba | 325 | { |
Helmut Tschemernjak | 65:b2d98328fcba | 326 | static uint32_t last_usecs = 0; |
Helmut Tschemernjak | 65:b2d98328fcba | 327 | Tcc *TC = TCC_CONFIG[USE_TCC].tcc_ptr; |
Helmut Tschemernjak | 65:b2d98328fcba | 328 | uint32_t usecs = micros(); |
Helmut Tschemernjak | 65:b2d98328fcba | 329 | uint32_t u_offset = 0; |
Helmut Tschemernjak | 65:b2d98328fcba | 330 | |
Helmut Tschemernjak | 65:b2d98328fcba | 331 | if (last_usecs && last_usecs < usecs) { |
Helmut Tschemernjak | 65:b2d98328fcba | 332 | /* |
Helmut Tschemernjak | 65:b2d98328fcba | 333 | * Problem is that the micros sometimes gives smaller values |
Helmut Tschemernjak | 65:b2d98328fcba | 334 | * compared to previuos micros. As a workaround we all 1ms. |
Helmut Tschemernjak | 65:b2d98328fcba | 335 | */ |
Helmut Tschemernjak | 65:b2d98328fcba | 336 | u_offset = 1000; |
Helmut Tschemernjak | 65:b2d98328fcba | 337 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 338 | last_usecs = usecs; |
Helmut Tschemernjak | 46:e78a1d0391ac | 339 | |
Helmut Tschemernjak | 65:b2d98328fcba | 340 | /* |
Helmut Tschemernjak | 65:b2d98328fcba | 341 | * Overflow means the max timer exeeded, we need restart the timer |
Helmut Tschemernjak | 65:b2d98328fcba | 342 | * Interrupts and |
Helmut Tschemernjak | 65:b2d98328fcba | 343 | */ |
Helmut Tschemernjak | 65:b2d98328fcba | 344 | if (TC->INTFLAG.bit.OVF == 1) { // A overflow caused the interrupt |
Helmut Tschemernjak | 65:b2d98328fcba | 345 | Serial.print("OVF\r\n"); |
Helmut Tschemernjak | 65:b2d98328fcba | 346 | TC->INTFLAG.bit.OVF = 1; // writing a one clears the flag ovf flag |
Helmut Tschemernjak | 65:b2d98328fcba | 347 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 348 | |
Helmut Tschemernjak | 65:b2d98328fcba | 349 | if (TC->INTFLAG.bit.MC0 == 1) { // A compare to cc0 caused the interrupt |
Helmut Tschemernjak | 65:b2d98328fcba | 350 | //Serial.print("MC0\r\n"); |
Helmut Tschemernjak | 65:b2d98328fcba | 351 | TC->INTFLAG.bit.MC0 = 1; // writing a one clears the MCO (match capture) flag |
Helmut Tschemernjak | 65:b2d98328fcba | 352 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 353 | |
Helmut Tschemernjak | 65:b2d98328fcba | 354 | TC->CTRLA.reg &= ~TCC_CTRLA_ENABLE; // Disable TC |
Helmut Tschemernjak | 65:b2d98328fcba | 355 | while (TC->SYNCBUSY.bit.ENABLE == 1); // wait for sync |
Helmut Tschemernjak | 65:b2d98328fcba | 356 | |
Helmut Tschemernjak | 65:b2d98328fcba | 357 | for (int i = 0; i < MAX_TIMEOUTS-1; i++) { |
Helmut Tschemernjak | 65:b2d98328fcba | 358 | struct TimeoutVector *tvp = &TimeOuts[i]; |
Helmut Tschemernjak | 65:b2d98328fcba | 359 | if (tvp->timer && tvp->timeout && usecs + u_offset >= tvp->timeout) { |
Helmut Tschemernjak | 65:b2d98328fcba | 360 | Timeout *saveTimer = tvp->timer; |
Helmut Tschemernjak | 65:b2d98328fcba | 361 | tvp->timer = NULL; |
Helmut Tschemernjak | 65:b2d98328fcba | 362 | tvp->timeout = 0; |
Helmut Tschemernjak | 65:b2d98328fcba | 363 | Timeout::_irq_handler(saveTimer); |
Helmut Tschemernjak | 65:b2d98328fcba | 364 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 365 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 366 | /* |
Helmut Tschemernjak | 65:b2d98328fcba | 367 | * we need to restart the timer for remaining interrupts |
Helmut Tschemernjak | 65:b2d98328fcba | 368 | * we provide the interrupt entry time in usecs which means |
Helmut Tschemernjak | 65:b2d98328fcba | 369 | * we don't count the irq_hander duration or debug prints |
Helmut Tschemernjak | 65:b2d98328fcba | 370 | */ |
Helmut Tschemernjak | 65:b2d98328fcba | 371 | Timeout::restart(usecs); |
Helmut Tschemernjak | 65:b2d98328fcba | 372 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 373 | |
Helmut Tschemernjak | 65:b2d98328fcba | 374 | #endif // D21 TCC Timer |
Helmut Tschemernjak | 65:b2d98328fcba | 375 | |
Helmut Tschemernjak | 65:b2d98328fcba | 376 | void |
Helmut Tschemernjak | 65:b2d98328fcba | 377 | Timeout::insert(void) |
Helmut Tschemernjak | 65:b2d98328fcba | 378 | { |
Helmut Tschemernjak | 65:b2d98328fcba | 379 | noInterrupts(); |
Helmut Tschemernjak | 65:b2d98328fcba | 380 | for (int i = 0; i < MAX_TIMEOUTS-1; i++) { |
Helmut Tschemernjak | 65:b2d98328fcba | 381 | struct TimeoutVector *tvp = &TimeOuts[i]; |
Helmut Tschemernjak | 65:b2d98328fcba | 382 | if (tvp->timer == NULL) { |
Helmut Tschemernjak | 65:b2d98328fcba | 383 | tvp->timeout = _timeout; |
Helmut Tschemernjak | 65:b2d98328fcba | 384 | tvp->timer = this; |
Helmut Tschemernjak | 65:b2d98328fcba | 385 | break; |
Helmut Tschemernjak | 65:b2d98328fcba | 386 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 387 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 388 | interrupts(); |
Helmut Tschemernjak | 65:b2d98328fcba | 389 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 390 | |
Helmut Tschemernjak | 65:b2d98328fcba | 391 | void |
Helmut Tschemernjak | 65:b2d98328fcba | 392 | Timeout::remove(void) |
Helmut Tschemernjak | 65:b2d98328fcba | 393 | { |
Helmut Tschemernjak | 65:b2d98328fcba | 394 | noInterrupts(); |
Helmut Tschemernjak | 65:b2d98328fcba | 395 | for (int i = 0; i < MAX_TIMEOUTS-1; i++) { |
Helmut Tschemernjak | 65:b2d98328fcba | 396 | struct TimeoutVector *tvp = &TimeOuts[i]; |
Helmut Tschemernjak | 65:b2d98328fcba | 397 | if (tvp->timer == this) { |
Helmut Tschemernjak | 65:b2d98328fcba | 398 | tvp->timer = NULL; |
Helmut Tschemernjak | 65:b2d98328fcba | 399 | tvp->timeout = 0; |
Helmut Tschemernjak | 65:b2d98328fcba | 400 | break; |
Helmut Tschemernjak | 65:b2d98328fcba | 401 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 402 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 403 | interrupts(); |
Helmut Tschemernjak | 65:b2d98328fcba | 404 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 405 | |
Helmut Tschemernjak | 65:b2d98328fcba | 406 | |
Helmut Tschemernjak | 65:b2d98328fcba | 407 | void |
Helmut Tschemernjak | 65:b2d98328fcba | 408 | Timeout::restart(uint32_t usecs) |
Helmut Tschemernjak | 65:b2d98328fcba | 409 | { |
Helmut Tschemernjak | 65:b2d98328fcba | 410 | uint32_t timeout = ~0; |
Helmut Tschemernjak | 65:b2d98328fcba | 411 | |
Helmut Tschemernjak | 65:b2d98328fcba | 412 | /* |
Helmut Tschemernjak | 65:b2d98328fcba | 413 | * find the lowest timeout value which is our the next timeout |
Helmut Tschemernjak | 65:b2d98328fcba | 414 | * zero means stop the timer. |
Helmut Tschemernjak | 65:b2d98328fcba | 415 | */ |
Helmut Tschemernjak | 65:b2d98328fcba | 416 | noInterrupts(); |
Helmut Tschemernjak | 65:b2d98328fcba | 417 | for (int i = 0; i < MAX_TIMEOUTS-1; i++) { |
Helmut Tschemernjak | 65:b2d98328fcba | 418 | struct TimeoutVector *tvp = &TimeOuts[i]; |
Helmut Tschemernjak | 65:b2d98328fcba | 419 | if (tvp->timer && tvp->timeout > 0) { |
Helmut Tschemernjak | 65:b2d98328fcba | 420 | if (tvp->timeout < timeout) { |
Helmut Tschemernjak | 65:b2d98328fcba | 421 | timeout = tvp->timeout; |
Helmut Tschemernjak | 65:b2d98328fcba | 422 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 423 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 424 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 425 | interrupts(); |
Helmut Tschemernjak | 65:b2d98328fcba | 426 | |
Helmut Tschemernjak | 65:b2d98328fcba | 427 | if (timeout == (uint32_t)~0) { |
Helmut Tschemernjak | 65:b2d98328fcba | 428 | stopTimer(); |
Helmut Tschemernjak | 65:b2d98328fcba | 429 | return; |
Helmut Tschemernjak | 65:b2d98328fcba | 430 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 431 | if (!usecs) |
Helmut Tschemernjak | 65:b2d98328fcba | 432 | usecs = micros(); |
Helmut Tschemernjak | 65:b2d98328fcba | 433 | |
Helmut Tschemernjak | 65:b2d98328fcba | 434 | if (timeout > usecs) { |
Helmut Tschemernjak | 65:b2d98328fcba | 435 | startTimer(timeout - usecs); |
Helmut Tschemernjak | 65:b2d98328fcba | 436 | return; |
Helmut Tschemernjak | 65:b2d98328fcba | 437 | } else { |
Helmut Tschemernjak | 65:b2d98328fcba | 438 | startTimer(1); // just one usec to trigger interrrupt |
Helmut Tschemernjak | 65:b2d98328fcba | 439 | } |
Helmut Tschemernjak | 65:b2d98328fcba | 440 | } |
Helmut Tschemernjak | 46:e78a1d0391ac | 441 | #endif // ARDUINO |