Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: DISCO-L072CZ-LRWAN1_LoRa_PingPong DISCO-L072CZ-LRWAN1_LoRa_PingPong DISCO-L072CZ-LRWAN1_LoRa_PingPong DISCO-L072CZ-LRWAN1_LoRa_USB_Rx ... more
Fork of SX1276Lib by
Diff: Arduino-mbed-APIs/arduino-esp32.cpp
- Revision:
- 97:3d5d489206aa
- Child:
- 101:50377edb21c6
diff -r 9da7e00c9d0f -r 3d5d489206aa Arduino-mbed-APIs/arduino-esp32.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Arduino-mbed-APIs/arduino-esp32.cpp Sat Nov 18 13:54:15 2017 +0100
@@ -0,0 +1,230 @@
+/*
+ * The file is Licensed under the Apache License, Version 2.0
+ * (c) 2017 Helmut Tschemernjak
+ * 30826 Garbsen (Hannover) Germany
+ */
+
+#ifdef ARDUINO
+
+using namespace std;
+
+#include "arduino-mbed.h"
+#include "arduino-util.h"
+
+
+
+#if defined(ARDUINO_ARCH_ESP32)
+/*
+ * ARDUINO_ARCH_ESP32 ESP32 development board
+ * Heltec ESP32 boards
+ */
+
+int
+CPUID(uint8_t *buf, int maxSize, uint32_t xorval)
+{
+ uint64_t chipid = ESP.getEfuseMac();//The chip ID is essentially its MAC address(length: 6 bytes).
+
+
+ if (maxSize >= sizeof(chipid)) {
+ memset(buf, 0, maxSize);
+ chipid = chipid ^ xorval;
+ memcpy(&chipid, buf, sizeof(chipid));
+ return sizeof(chipid) ;
+ }
+ return 0;
+}
+
+/*
+ * see esp32-hal-timer.h is automatically included from:
+ * Arduino15/packages/arduino/hardware/espressif/esp32/cores/esp32
+ */
+static void initTimer(int timerID);
+void IRAM_ATTR onTimer(void);
+/*
+ * The Atmel ESP32 has three 64-bit timer.
+ */
+struct TIMER_config {
+ int timerID;
+ hw_timer_t *timer;
+ uint8_t nbits;
+} Timer_data[] {
+ { 0, NULL, 32 },
+ { 1, NULL, 32 },
+ { 2, NULL, 32 },
+ { -1, NULL, 0 }
+};
+
+/*
+ * We preferably use ESP32 timers because it supports 64-bit counters
+ */
+#define USE_TIMER_TIMEOUT 0 // 0, 1, 2 (see ESP32 docs)
+#define USE_TIMER_TICKER 1 // 0, 1, 2 (see ESP32 docs)
+#define MAX_TIMERS 3
+
+/*
+ * Calculation of ticks see timerBegin divider
+ */
+#define NS_PER_CLOCK_CPU 1000 // ns secs per clock
+#define NS_PER_CLOCK_RTC 1000 // ns secs per clock
+#define TIMER_INFINITE 0x7fffffffffffffff // max esp alarm timeout
+#define NS_PER_CLOCK NS_PER_CLOCK_RTC
+
+
+const char *GetTimerName(int timerID)
+{
+ switch(timerID) {
+ case USE_TIMER_TIMEOUT:
+ return "TIMEOUT";
+ break;
+ case USE_TIMER_TICKER:
+ return "TICKER";
+ break;
+ default:
+ return "Uknown";
+ }
+}
+
+/* ----------------- TICKER TIMER CODE ----------------------*/
+
+/*
+ * The global ns_counter contains the time in ns from the last time
+ * the counter has been wrapped. It cannot be used directly because the
+ * current counter has to be added fore using it. Use instead
+ * ns_getTicker(), us_ ns_getTicker(), ms_getTicker()
+ */
+
+static volatile bool initTickerDone = false;
+
+uint64_t ns_getTicker(void)
+{
+ int timerID = Timer_data[USE_TIMER_TICKER].timerID;
+
+ if (!initTickerDone) {
+ initTimer(timerID);
+ initTickerDone = true;
+ dprintf("ESP32 Revision: %d (%d MHz)\r\n", ESP.getChipRevision(), ESP.getCpuFreqMHz());
+ }
+
+ hw_timer_t *timer = Timer_data[USE_TIMER_TICKER].timer;
+ uint64_t ns = timerRead(timer);
+ uint16_t div = timerGetDivider(timer);
+ ns *= div; // get to the real clocks
+ ns /= 8; // 80 MHz , divide by 8 to keep more NS
+ ns *= 100; // us to ns equals 1000, however we divided only by 8 remaing are 1000
+
+ return ns;
+}
+
+
+/* ----------------- SUPPORT CODE FOR TCC TIMERS----------------------*/
+
+static volatile bool initTimerDone = false;
+
+static void initTimer(int timerID)
+{
+ //dprintf("initTimer: %s", GetTimerName(timerID));
+ struct TIMER_config *cp = &Timer_data[timerID];
+ if (timerID > MAX_TIMERS-1)
+ return;
+
+ cp->timer = timerBegin(timerID, 80, true);
+ timerWrite(cp->timer, 0);
+ if (timerID == USE_TIMER_TICKER)
+ timerStart(cp->timer);
+ else {
+ timerAttachInterrupt(cp->timer, &onTimer, true);
+ timerAlarmWrite(cp->timer, TIMER_INFINITE, true);
+ timerAlarmEnable(cp->timer);
+ timerStart(cp->timer);
+ }
+ /*
+ * somehow the timer needs some time to initalize before being used.
+ * otherwise it will not issue any alarms
+ * This affects only ESP32 rev 0
+ */
+ delay(20);
+}
+
+
+TIMER_REF *getTimeoutTimer(void)
+{
+ struct TIMER_config *cp = &Timer_data[USE_TIMER_TIMEOUT];
+
+ return &cp->timerID;
+}
+
+
+void stopTimer(int *timerIDPtr)
+{
+ struct TIMER_config *cp = &Timer_data[*timerIDPtr];
+ if (*timerIDPtr > MAX_TIMERS-1)
+ return;
+
+ if (cp->timer)
+ timerAlarmWrite(cp->timer, TIMER_INFINITE, true);
+}
+
+
+/* ----------------- TIMEOUT TIMER CODE ----------------------*/
+
+void startTimer(int *timerIDPtr, uint64_t delay_ns)
+{
+ if (!initTimerDone) {
+ initTimer(*timerIDPtr); // initial setup with stopped timer
+ initTimerDone = true;
+ }
+
+ struct TIMER_config *cp = &Timer_data[*timerIDPtr];
+ if (*timerIDPtr > MAX_TIMERS-1)
+ return;
+ uint64_t usecs = delay_ns/1000;
+ if (delay_ns == 1) // immediate timeout
+ usecs = 1;
+ timerAlarmWrite(cp->timer, usecs, true);
+ // dprintf("startTimer: %s in %d us", GetTimerName(*timerIDPtr), usecs);
+}
+
+/*
+ * The onTimer is only called for every Timeout expired timer
+ */
+void IRAM_ATTR onTimer(void) {
+ //dprintf("onTimer int called");
+ uint64_t nsecs = ns_getTicker();
+
+ for (int i = 0; i < MAX_TIMEOUTS-1; i++) {
+ struct TimeoutVector *tvp = &TimeOuts[i];
+ if (tvp->timer && nsecs >= tvp->timer->_timeout) {
+ Timeout *saveTimer = tvp->timer;
+ tvp->timer = NULL;
+ Timeout::_irq_handler(saveTimer);
+ }
+ }
+ /*
+ * we need to restart the timer for remaining interrupts
+ * Another reason is that we stopped this counter, in case there are
+ * remaining counts, we need to re-schedule the counter.
+ */
+ Timeout::restart();
+}
+
+
+/* ----------------- ESP32 sleep() and deepsleep() code ----------------------*/
+
+void sleep(void)
+{
+ asm("waiti 0");
+}
+
+/*
+ * TODO
+ * The ESP32 deepsleep can be enhanced to bring the ESP into low power mode.
+ */
+
+void deepsleep(void)
+{
+ asm("waiti 0");
+}
+
+#endif // ESp32 Timer, sleep, etc.
+
+#endif // ARDUINO

