f

Embed: (wiki syntax)

« Back to documentation index

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

arduino-mbed.h

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 
00008 
00009 #ifdef ARDUINO
00010 #ifndef __ARDUINO_MBED_H__
00011 #define __ARDUINO_MBED_H__
00012 
00013 #include <arduino.h>
00014 #include "Callback-A.h"
00015 #include <SPI.h>
00016 #undef min
00017 #undef max
00018 #undef map
00019 
00020 typedef int PinName;
00021 #define NC  -1
00022 /* we need to redefine out dprintf because stdio.h uses the same name */
00023 #define dprint  dxprintf
00024 #if ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606
00025  #define MYdigitalPinToInterrupt(x) digitalPinToInterrupt(x)
00026 #else
00027  #define MYdigitalPinToInterrupt(x) (x)
00028 #endif
00029 
00030 void InitSerial(Stream *serial, int timeout_ms);
00031 extern Stream *ser;
00032 extern bool SerialUSB_active;
00033 
00034 /*
00035  * Arduino_d21.cpp
00036  */
00037 extern void startTimer(Tcc *t, uint64_t delay_ns);
00038 extern void stopTimer(Tcc *t);
00039 extern uint64_t ns_getTicker(void);
00040 extern Tcc *getTimeout_tcc(void);
00041 extern int CPUID(uint8_t *buf, int maxSize, uint32_t xorval);
00042 
00043 
00044 extern void sleep(void);
00045 extern void deepsleep(void);
00046 
00047 #define MAX_TIMEOUTS    10
00048 class Timeout;
00049 struct TimeoutVector {
00050     Timeout *timer;
00051 };
00052 extern TimeoutVector TimeOuts[];
00053 
00054 
00055 /*
00056  * Arduino-mbed.cpp
00057  */
00058 extern uint32_t s_getTicker(void);
00059 extern uint32_t ms_getTicker(void);
00060 extern uint32_t us_getTicker(void);
00061 extern void wait_ms(uint32_t ms);
00062 
00063 
00064 enum PinMode {
00065     PullUp = 1,
00066     PullDown = 2,
00067 };
00068 
00069 class DigitalInOut {
00070 public:
00071     DigitalInOut(PinName pin) {
00072         _gpioPin = pin;
00073     }
00074     void write(int value) {
00075         digitalWrite(_gpioPin, value == 0 ? LOW : HIGH);
00076     };
00077     
00078     void output() {
00079         pinMode(_gpioPin, OUTPUT);
00080     };
00081     
00082     void input() {
00083         pinMode(_gpioPin, INPUT);
00084     };
00085     
00086     void mode(PinMode pull) {
00087         switch(pull) {
00088             case PullUp:
00089                 pinMode(_gpioPin, INPUT_PULLUP);
00090                 break;
00091             case PullDown:
00092                 pinMode(_gpioPin, INPUT_PULLDOWN);
00093                 break;
00094         }
00095     }
00096               
00097     int read() {
00098         if (digitalRead(_gpioPin) == HIGH)
00099             return 1;
00100         else
00101             return 0;
00102     };
00103     operator int() {
00104         return read();
00105     };
00106     
00107     DigitalInOut& operator= (int value) {
00108         // Underlying write is thread safe
00109         write(value);
00110         return *this;
00111     }
00112     
00113     DigitalInOut& operator= (DigitalInOut& rhs) {
00114         write(rhs.read());
00115         return *this;
00116     }
00117     
00118 private:
00119     int _gpioPin;
00120 };
00121 
00122 class DigitalOut : public DigitalInOut {
00123 public:
00124     
00125     DigitalOut(PinName pin) : DigitalInOut(pin) {
00126         output();
00127     }
00128     
00129     DigitalOut& operator= (int value) {
00130         write(value);
00131         return *this;
00132     }
00133     
00134 };
00135 
00136 class DigitalIn : public DigitalInOut {
00137 public:
00138     
00139     DigitalIn(PinName pin) :  DigitalInOut(pin) {
00140         input();
00141     }
00142 };
00143 
00144 class XSPI {
00145 public:
00146     XSPI(PinName mosi, PinName miso, PinName sclk) {
00147         _mosi = mosi;
00148         _miso = miso;
00149         _sclk = sclk;
00150         if (mosi == PIN_SPI_MOSI && miso == PIN_SPI_MISO && sclk == PIN_SPI_SCK)
00151             _spi = &SPI;
00152 #if SPI_INTERFACES_COUNT > 1
00153         else if (mosi == PIN_SPI1_MOSI && miso == PIN_SPI1_MISO && sclk == PIN_SPI1_SCK)
00154             _spi = &SPI1;
00155 #endif
00156 #if SPI_INTERFACES_COUNT > 2
00157         else if (mosi == PIN_SPI2_MOSI && miso == PIN_SPI2_MISO && sclk == PIN_SPI2_SCK)
00158             _spi = &SPI2;
00159 #endif
00160         else {
00161             _spi = NULL;
00162             return;
00163         }
00164         _hz = 1000000;
00165         _mode = SPI_MODE0;
00166         _spi->beginTransaction(SPISettings(_hz, MSBFIRST, _mode));
00167     }
00168     ~XSPI() {
00169         _spi->endTransaction();
00170     };
00171     
00172     void format(int bits, int mode = 0) {
00173         if (mode == 0)
00174             _mode = SPI_MODE0;
00175         else if (mode == 1)
00176             _mode = SPI_MODE1;
00177         else if (mode == 2)
00178             _mode = SPI_MODE2;
00179         else if (mode == 3)
00180             _mode = SPI_MODE3;
00181         else
00182             _mode = SPI_MODE0;
00183         _bits = bits;
00184         _spi->endTransaction();
00185         _spi->beginTransaction(SPISettings(_hz, MSBFIRST, _mode));
00186     }
00187     void frequency(int hz) {
00188         _hz = hz;
00189         _spi->endTransaction();
00190         _spi->beginTransaction(SPISettings(_hz, MSBFIRST, _mode));
00191     }
00192     
00193     int write(int value) {
00194         int ret = _spi->transfer(value);
00195         return ret;
00196     }
00197 
00198 private:
00199     SPIClass *_spi;
00200     int _hz;
00201     int _mode;
00202     int _bits;
00203     int _mosi, _miso, _sclk;
00204 };
00205 
00206 class InterruptIn {
00207 public:
00208     static void donothing(void) {
00209     }
00210     
00211     InterruptIn(PinName pin) :  _func() {
00212         _gpioPin = pin;
00213         _func = InterruptIn::donothing;
00214         pinMode(_gpioPin, INPUT);
00215     }
00216     
00217     ~InterruptIn() {
00218         detachInterrupt(MYdigitalPinToInterrupt(_gpioPin));
00219     };
00220     
00221     static void _irq_handler(InterruptIn *id) {
00222         if (id)
00223             id->_func();
00224     }
00225     
00226     void rise(Callback<void()> func);
00227     
00228     void fall(Callback<void()> func);
00229     
00230     void mode(PinMode pull) {
00231         switch(pull) {
00232             case PullUp:
00233                 pinMode(_gpioPin, INPUT_PULLUP);
00234                 break;
00235             case PullDown:
00236                 pinMode(_gpioPin, INPUT_PULLDOWN);
00237                 break;
00238         }
00239     }
00240 private:
00241     int _gpioPin;
00242     Callback<void()> _func;
00243 };
00244 
00245 
00246 
00247 class Timer {
00248 public:
00249     void start(void) {
00250         _time = ns_getTicker();
00251     }
00252     uint32_t read_sec(void) {
00253         int64_t n = ns_getTicker() - (uint64_t)_time;
00254         n /= (uint64_t)1000000000;
00255         return n;
00256     }
00257     uint32_t read_ms(void) {
00258         int64_t n = ns_getTicker() - (uint64_t)_time;
00259         n /= (uint64_t)1000000;
00260         return n;
00261     }
00262     uint32_t read_us(void) {
00263         int64_t n = ns_getTicker() - (uint64_t)_time;
00264         n /= (uint64_t)1000;
00265         return n;
00266     }
00267 private:
00268     uint64_t _time;
00269 };
00270 
00271 
00272 class Timeout {
00273 public:
00274     Timeout() : _func() {
00275     }
00276     ~Timeout() {
00277         detach();
00278     }
00279     
00280     void attach_sec(Callback<void()> func, uint32_t secs) {
00281         if (secs == 0)
00282             return detach();
00283         _func = func;
00284         _timeout = ns_getTicker() + (uint64_t)secs * (uint64_t)1000000000;
00285         insert();
00286         restart();
00287     }
00288 
00289     void attach(Callback<void()> func, uint32_t msecs) {
00290         if (msecs == 0)
00291             return detach();
00292         _func = func;
00293         _timeout = ns_getTicker() + (uint64_t)msecs * (uint64_t)1000000;
00294         insert();
00295         restart();
00296     }
00297     
00298     void attach_us(Callback<void()> func, long usecs) {
00299         if (usecs == 0)
00300             return detach();
00301         _func = func;
00302         _timeout = ns_getTicker() + (uint64_t)usecs * (uint64_t)1000;
00303         insert();
00304         restart();
00305     }
00306     
00307     void detach(void) {
00308         _func = NULL;
00309         remove();
00310         restart();
00311     }
00312     
00313     static void _irq_handler(Timeout *tp) {
00314         if (tp) {
00315             tp->_func();
00316         }
00317     }
00318 
00319     static void restart(void);
00320     uint64_t _timeout;  // in ns this lasts for 539 years.
00321 protected:
00322     void insert(void);
00323     void remove(void);
00324 private:
00325     Callback<void()> _func;
00326 };
00327 
00328 #endif // __ARDUINO_MBED_H__
00329 
00330 #endif // ARDUINO