f

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arduino-mbed.cpp Source File

arduino-mbed.cpp

00001 /*
00002  * The file is Licensed under the Apache License, Version 2.0
00003  * (c) 2017 Helmut Tschemernjak
00004  * 30826 Garbsen (Hannover) Germany
00005  */
00006 
00007 #ifdef ARDUINO
00008 
00009 using namespace std;
00010 
00011 #include "arduino-mbed.h"
00012 #include "arduino-util.h"
00013 
00014 Stream *ser;
00015 bool SerialUSB_active = false;
00016 
00017 void InitSerial(Stream *serial, int timeout_ms) {
00018     ser = serial;
00019     if (serial == (Stream *)&SerialUSB) {
00020         uint32_t start = ms_getTicker();
00021 
00022         SerialUSB_active = true;
00023         while(!SerialUSB) {
00024             if (ms_getTicker() > start + timeout_ms) {
00025                 SerialUSB_active = false;
00026                 break;
00027             }
00028         }
00029         if (!SerialUSB_active) {
00030             USB->DEVICE.CTRLA.bit.SWRST = 1; // disconnect the USB Port
00031             while (USB->DEVICE.CTRLA.bit.SWRST == 1);
00032         }
00033     }
00034 }
00035 
00036 static void pinInt00(void);
00037 static void pinInt01(void);
00038 static void pinInt02(void);
00039 static void pinInt03(void);
00040 static void pinInt04(void);
00041 static void pinInt05(void);
00042 static void pinInt06(void);
00043 static void pinInt07(void);
00044 static void pinInt08(void);
00045 static void pinInt09(void);
00046 static void pinInt10(void);
00047 static void pinInt11(void);
00048 static void pinInt12(void);
00049 static void pinInt13(void);
00050 static void pinInt14(void);
00051 static void pinInt15(void);
00052 static void pinInt16(void);
00053 static void pinInt17(void);
00054 static void pinInt18(void);
00055 static void pinInt19(void);
00056 static void pinInt20(void);
00057 static void pinInt21(void);
00058 static void pinInt22(void);
00059 static void pinInt23(void);
00060 static void pinInt24(void);
00061 static void pinInt25(void);
00062 static void pinInt26(void);
00063 static void pinInt27(void);
00064 static void pinInt28(void);
00065 static void pinInt29(void);
00066 static void pinInt30(void);
00067 static void pinInt31(void);
00068 static void pinInt32(void);
00069 static void pinInt33(void);
00070 static void pinInt34(void);
00071 static void pinInt35(void);
00072 static void pinInt36(void);
00073 static void pinInt37(void);
00074 static void pinInt38(void);
00075 static void pinInt39(void);
00076 static void pinInt40(void);
00077 static void pinInt41(void);
00078 static void pinInt42(void);
00079 static void pinInt43(void);
00080 static void pinInt44(void);
00081 static void pinInt45(void);
00082 static void pinInt46(void);
00083 static void pinInt47(void);
00084 
00085 
00086 
00087 #define MAX_MCU_PINS    48
00088 class InterruptIn;
00089 struct intPtrTable {
00090     void (*func)(void);
00091     InterruptIn *context;
00092 } intPtrTable[MAX_MCU_PINS]  = {
00093     { pinInt00, NULL },
00094     { pinInt01, NULL },
00095     { pinInt02, NULL },
00096     { pinInt03, NULL },
00097     { pinInt04, NULL },
00098     { pinInt05, NULL },
00099     { pinInt06, NULL },
00100     { pinInt07, NULL },
00101     { pinInt08, NULL },
00102     { pinInt09, NULL },
00103     { pinInt10, NULL },
00104     { pinInt11, NULL },
00105     { pinInt12, NULL },
00106     { pinInt13, NULL },
00107     { pinInt14, NULL },
00108     { pinInt15, NULL },
00109     { pinInt16, NULL },
00110     { pinInt17, NULL },
00111     { pinInt18, NULL },
00112     { pinInt19, NULL },
00113     { pinInt20, NULL },
00114     { pinInt21, NULL },
00115     { pinInt22, NULL },
00116     { pinInt23, NULL },
00117     { pinInt24, NULL },
00118     { pinInt25, NULL },
00119     { pinInt26, NULL },
00120     { pinInt27, NULL },
00121     { pinInt28, NULL },
00122     { pinInt29, NULL },
00123     { pinInt30, NULL },
00124     { pinInt31, NULL },
00125     { pinInt32, NULL },
00126     { pinInt33, NULL },
00127     { pinInt34, NULL },
00128     { pinInt35, NULL },
00129     { pinInt36, NULL },
00130     { pinInt37, NULL },
00131     { pinInt38, NULL },
00132     { pinInt39, NULL },
00133     { pinInt40, NULL },
00134     { pinInt41, NULL },
00135     { pinInt42, NULL },
00136     { pinInt43, NULL },
00137     { pinInt44, NULL },
00138     { pinInt45, NULL },
00139     { pinInt46, NULL },
00140     { pinInt47, NULL }
00141 }; // our max MCUs pins
00142 
00143 
00144 
00145 static void pinInt00(void) { InterruptIn::_irq_handler(intPtrTable[0].context); }
00146 static void pinInt01(void) { InterruptIn::_irq_handler(intPtrTable[1].context); }
00147 static void pinInt02(void) { InterruptIn::_irq_handler(intPtrTable[2].context); }
00148 static void pinInt03(void) { InterruptIn::_irq_handler(intPtrTable[3].context); }
00149 static void pinInt04(void) { InterruptIn::_irq_handler(intPtrTable[4].context); }
00150 static void pinInt05(void) { InterruptIn::_irq_handler(intPtrTable[5].context); }
00151 static void pinInt06(void) { InterruptIn::_irq_handler(intPtrTable[6].context); }
00152 static void pinInt07(void) { InterruptIn::_irq_handler(intPtrTable[7].context); }
00153 static void pinInt08(void) { InterruptIn::_irq_handler(intPtrTable[8].context); }
00154 static void pinInt09(void) { InterruptIn::_irq_handler(intPtrTable[9].context); }
00155 static void pinInt10(void) { InterruptIn::_irq_handler(intPtrTable[10].context); }
00156 static void pinInt11(void) { InterruptIn::_irq_handler(intPtrTable[11].context); }
00157 static void pinInt12(void) { InterruptIn::_irq_handler(intPtrTable[12].context); }
00158 static void pinInt13(void) { InterruptIn::_irq_handler(intPtrTable[13].context); }
00159 static void pinInt14(void) { InterruptIn::_irq_handler(intPtrTable[14].context); }
00160 static void pinInt15(void) { InterruptIn::_irq_handler(intPtrTable[15].context); }
00161 static void pinInt16(void) { InterruptIn::_irq_handler(intPtrTable[16].context); }
00162 static void pinInt17(void) { InterruptIn::_irq_handler(intPtrTable[17].context); }
00163 static void pinInt18(void) { InterruptIn::_irq_handler(intPtrTable[18].context); }
00164 static void pinInt19(void) { InterruptIn::_irq_handler(intPtrTable[19].context); }
00165 static void pinInt20(void) { InterruptIn::_irq_handler(intPtrTable[20].context); }
00166 static void pinInt21(void) { InterruptIn::_irq_handler(intPtrTable[21].context); }
00167 static void pinInt22(void) { InterruptIn::_irq_handler(intPtrTable[22].context); }
00168 static void pinInt23(void) { InterruptIn::_irq_handler(intPtrTable[23].context); }
00169 static void pinInt24(void) { InterruptIn::_irq_handler(intPtrTable[24].context); }
00170 static void pinInt25(void) { InterruptIn::_irq_handler(intPtrTable[25].context); }
00171 static void pinInt26(void) { InterruptIn::_irq_handler(intPtrTable[26].context); }
00172 static void pinInt27(void) { InterruptIn::_irq_handler(intPtrTable[27].context); }
00173 static void pinInt28(void) { InterruptIn::_irq_handler(intPtrTable[28].context); }
00174 static void pinInt29(void) { InterruptIn::_irq_handler(intPtrTable[29].context); }
00175 static void pinInt30(void) { InterruptIn::_irq_handler(intPtrTable[30].context); }
00176 static void pinInt31(void) { InterruptIn::_irq_handler(intPtrTable[31].context); }
00177 static void pinInt32(void) { InterruptIn::_irq_handler(intPtrTable[32].context); }
00178 static void pinInt33(void) { InterruptIn::_irq_handler(intPtrTable[33].context); }
00179 static void pinInt34(void) { InterruptIn::_irq_handler(intPtrTable[34].context); }
00180 static void pinInt35(void) { InterruptIn::_irq_handler(intPtrTable[35].context); }
00181 static void pinInt36(void) { InterruptIn::_irq_handler(intPtrTable[36].context); }
00182 static void pinInt37(void) { InterruptIn::_irq_handler(intPtrTable[37].context); }
00183 static void pinInt38(void) { InterruptIn::_irq_handler(intPtrTable[38].context); }
00184 static void pinInt39(void) { InterruptIn::_irq_handler(intPtrTable[39].context); }
00185 static void pinInt40(void) { InterruptIn::_irq_handler(intPtrTable[40].context); }
00186 static void pinInt41(void) { InterruptIn::_irq_handler(intPtrTable[41].context); }
00187 static void pinInt42(void) { InterruptIn::_irq_handler(intPtrTable[42].context); }
00188 static void pinInt43(void) { InterruptIn::_irq_handler(intPtrTable[43].context); }
00189 static void pinInt44(void) { InterruptIn::_irq_handler(intPtrTable[44].context); }
00190 static void pinInt45(void) { InterruptIn::_irq_handler(intPtrTable[45].context); }
00191 static void pinInt46(void) { InterruptIn::_irq_handler(intPtrTable[46].context); }
00192 static void pinInt47(void) { InterruptIn::_irq_handler(intPtrTable[47].context); }
00193 
00194 
00195 void wait_ms(uint32_t ms)
00196 {
00197     uint32_t start = ms_getTicker();
00198     
00199     while (true) {
00200         uint32_t t = ms_getTicker();
00201         if (t < start) // warp.
00202             start = 0;
00203         if (t > (start + ms))
00204             break;
00205     }
00206 }
00207 
00208 struct TimeoutVector TimeOuts[MAX_TIMEOUTS];
00209 
00210 void
00211 InterruptIn::rise(Callback<void()> func) {
00212     if (_gpioPin >= MAX_MCU_PINS-1)
00213         return;
00214     if (func) {
00215         _func = func;
00216         intPtrTable[_gpioPin].context = this;
00217         attachInterrupt(MYdigitalPinToInterrupt(_gpioPin), intPtrTable[_gpioPin].func, RISING);
00218     } else {
00219         _func = InterruptIn::donothing;
00220         intPtrTable[_gpioPin].context = NULL;
00221         detachInterrupt(_gpioPin);
00222     }
00223 };
00224 
00225 void
00226 InterruptIn::fall(Callback<void()> func) {
00227     if (func) {
00228         _func = func;
00229         intPtrTable[_gpioPin].context = this;
00230         attachInterrupt(MYdigitalPinToInterrupt(_gpioPin), intPtrTable[_gpioPin].func, FALLING);
00231     } else {
00232         _func = InterruptIn::donothing;
00233         intPtrTable[_gpioPin].context = NULL;
00234         detachInterrupt(_gpioPin);
00235     }
00236 }
00237 
00238 
00239 uint32_t s_getTicker(void)
00240 {
00241     long long ns = ns_getTicker();
00242     ns /= (long long)1000000000; // to secs
00243     
00244     int secs = ns;
00245     return secs;
00246 }
00247 
00248 
00249 uint32_t ms_getTicker(void)
00250 {
00251     uint32_t us = us_getTicker();
00252     
00253     us /= 1000; // to ms
00254     return us;
00255 }
00256 
00257 uint32_t us_getTicker(void)
00258 {
00259     long long ns = ns_getTicker();
00260 
00261     ns /= (long long)1000; // to us
00262     uint32_t us = ns & 0xffffffff;
00263     
00264     return us;
00265 }
00266 
00267 
00268 void
00269 Timeout::insert(void)
00270 {
00271     noInterrupts();
00272     for (int i = 0; i < MAX_TIMEOUTS-1; i++) {
00273         struct TimeoutVector *tvp = &TimeOuts[i];
00274         if (tvp->timer == this) // already here, timer has been restartet.
00275             break;
00276         if (tvp->timer == NULL) {
00277             tvp->timer = this;
00278             break;
00279         }
00280     }
00281     interrupts();
00282 }
00283 
00284 void
00285 Timeout::remove(void)
00286 {
00287     noInterrupts();
00288     for (int i = 0; i < MAX_TIMEOUTS-1; i++) {
00289         struct TimeoutVector *tvp = &TimeOuts[i];
00290         if (tvp->timer == this) {
00291             tvp->timer = NULL;
00292             break;
00293         }
00294     }
00295     interrupts();
00296 }
00297 
00298 
00299 void
00300 Timeout::restart()
00301 {
00302     Tcc *t = getTimeout_tcc();
00303     uint64_t timeout = ~0;
00304     
00305     /*
00306      * find the lowest timeout value which is our the next timeout
00307      * zero means stop the timer.
00308      */
00309     noInterrupts();
00310     for (int i = 0; i < MAX_TIMEOUTS-1; i++) {
00311         struct TimeoutVector *tvp = &TimeOuts[i];
00312         if (tvp->timer) {
00313             if (tvp->timer->_timeout < timeout) {
00314                 timeout = tvp->timer->_timeout;
00315             }
00316         }
00317     }
00318     interrupts();
00319     
00320     if (timeout == (uint64_t)~0) {
00321         stopTimer(t);
00322         return;
00323     }
00324     
00325     uint64_t nsecs = ns_getTicker();
00326     
00327     if (timeout > nsecs) {
00328         startTimer(t, (uint64_t)timeout - (uint64_t)nsecs);
00329         return;
00330     } else {
00331         startTimer(t, (uint64_t)1); // just one nsec to trigger interrrupt
00332     }
00333 }
00334 
00335 #endif // ARDUINO