mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[ion] add millis() and micros() using systick on device
This commit is contained in:
@@ -27,6 +27,8 @@ namespace Ion {
|
||||
|
||||
void msleep(long ms);
|
||||
void usleep(long us);
|
||||
extern "C" long millis();
|
||||
extern "C" long micros();
|
||||
|
||||
const char * serialNumber();
|
||||
const char * softwareVersion();
|
||||
|
||||
@@ -3,3 +3,17 @@
|
||||
|
||||
void Ion::msleep(long ms) {
|
||||
}
|
||||
|
||||
#include <chrono>
|
||||
|
||||
static auto start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
long Ion::millis() {
|
||||
auto elapsed = std::chrono::high_resolution_clock::now() - start;
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count();
|
||||
}
|
||||
|
||||
long Ion::micros() {
|
||||
auto elapsed = std::chrono::high_resolution_clock::now() - start;
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ ISR InitialisationVector[INITIALISATION_VECTOR_SIZE]
|
||||
0, // DebugMonitor service routine,
|
||||
0, // Reserved
|
||||
0, // PendSV service routine,
|
||||
0, // SysTick service routine
|
||||
sysTick, // SysTick service routine
|
||||
0, // WWDG service routine
|
||||
0, // PVD service routine
|
||||
0, // TampStamp service routine
|
||||
|
||||
@@ -92,3 +92,9 @@ void start() {
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
volatile long millis_elapsed = 0;
|
||||
|
||||
void __attribute__((interrupt)) sysTick() {
|
||||
millis_elapsed++;
|
||||
}
|
||||
|
||||
@@ -4,4 +4,6 @@
|
||||
void start();
|
||||
void abort();
|
||||
|
||||
void sysTick();
|
||||
|
||||
#endif
|
||||
|
||||
@@ -39,6 +39,22 @@ void Ion::usleep(long us) {
|
||||
}
|
||||
}
|
||||
|
||||
extern volatile long millis_elapsed;
|
||||
|
||||
long Ion::millis() {
|
||||
return millis_elapsed;
|
||||
}
|
||||
|
||||
long Ion::micros() {
|
||||
uint32_t c1 = CM4.STCVR()->getCURRENT();
|
||||
uint32_t ms1 = millis_elapsed;
|
||||
uint32_t c2 = CM4.STCVR()->getCURRENT();
|
||||
uint32_t ms2 = millis_elapsed;
|
||||
uint32_t load = CM4.STRVR()->getRELOAD();
|
||||
|
||||
return ((c1 > c2) ? ms1 : ms2) * 1000 + ((load - c2) * 1000) / (load + 1);
|
||||
}
|
||||
|
||||
uint32_t Ion::crc32(const uint32_t * data, size_t length) {
|
||||
bool initialCRCEngineState = RCC.AHB1ENR()->getCRCEN();
|
||||
RCC.AHB1ENR()->setCRCEN(true);
|
||||
@@ -184,9 +200,17 @@ void initPeripherals() {
|
||||
#endif
|
||||
Console::Device::init();
|
||||
SWD::Device::init();
|
||||
|
||||
CM4.STRVR()->setRELOAD(11999);
|
||||
CM4.STCVR()->setCURRENT(0);
|
||||
CM4.STCSR()->setCLKSOURCE(CM4::STCSR::CLKSOURCE::AHB_DIV8);
|
||||
CM4.STCSR()->setTICKINT(true);
|
||||
CM4.STCSR()->setENABLE(true);
|
||||
}
|
||||
|
||||
void shutdownPeripherals(bool keepLEDAwake) {
|
||||
CM4.STCSR()->setENABLE(false);
|
||||
|
||||
SWD::Device::shutdown();
|
||||
Console::Device::shutdown();
|
||||
#if USE_SD_CARD
|
||||
|
||||
@@ -19,6 +19,8 @@ void shutdownPeripherals(bool keepLEDAwake = false);
|
||||
void initClocks();
|
||||
void shutdownClocks(bool keepLEDAwake = false);
|
||||
|
||||
void sysTick();
|
||||
|
||||
/* The serial number is 96 bits long. That's equal to 16 digits in base 64. We
|
||||
* expose a convenient "copySerialNumber" routine which can be called without
|
||||
* using a static variable (and therefore without a .bss section). This is used
|
||||
|
||||
@@ -40,14 +40,39 @@ public:
|
||||
REGS_BOOL_FIELD(SLEEPDEEP, 2);
|
||||
};
|
||||
|
||||
class STCSR : public Register32 {
|
||||
public:
|
||||
enum class CLKSOURCE : uint8_t {
|
||||
AHB_DIV8 = 0,
|
||||
AHB = 1
|
||||
};
|
||||
REGS_BOOL_FIELD(COUNTFLAG, 16);
|
||||
REGS_TYPE_FIELD(CLKSOURCE, 2, 2);
|
||||
REGS_BOOL_FIELD(TICKINT, 1);
|
||||
REGS_BOOL_FIELD(ENABLE, 0);
|
||||
};
|
||||
|
||||
class STRVR : public Register32 {
|
||||
public:
|
||||
REGS_FIELD(RELOAD, uint32_t, 23, 0);
|
||||
};
|
||||
|
||||
class STCVR : public Register32 {
|
||||
public:
|
||||
REGS_FIELD(CURRENT, uint32_t, 23, 0);
|
||||
};
|
||||
|
||||
constexpr CM4() {};
|
||||
REGS_REGISTER_AT(VTOR, 0x08);
|
||||
REGS_REGISTER_AT(AIRCR, 0x0C);
|
||||
REGS_REGISTER_AT(SCR, 0x10);
|
||||
REGS_REGISTER_AT(CPACR, 0x88);
|
||||
REGS_REGISTER_AT(STCSR, 0x10);
|
||||
REGS_REGISTER_AT(STRVR, 0x14);
|
||||
REGS_REGISTER_AT(STCVR, 0x18);
|
||||
REGS_REGISTER_AT(VTOR, 0xD08);
|
||||
REGS_REGISTER_AT(AIRCR, 0xD0C);
|
||||
REGS_REGISTER_AT(SCR, 0xD10);
|
||||
REGS_REGISTER_AT(CPACR, 0xD88);
|
||||
private:
|
||||
constexpr uint32_t Base() const {
|
||||
return 0xE000ED00;
|
||||
return 0xE000E000;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ typedef Register<uint32_t> Register32;
|
||||
typedef Register<uint64_t> Register64;
|
||||
|
||||
#define REGS_FIELD_R(name,type,high,low) type get##name() volatile { return (type)getBitRange(high,low); };
|
||||
#define REGS_FIELD_W(name,type,high,low) void set##name(type v) volatile { static_assert(sizeof(type) <= 2, "Invalid size"); setBitRange(high, low, static_cast<uint16_t>(v)); };
|
||||
#define REGS_FIELD_W(name,type,high,low) void set##name(type v) volatile { static_assert(sizeof(type) <= 4, "Invalid size"); setBitRange(high, low, static_cast<uint32_t>(v)); };
|
||||
#define REGS_FIELD(name,type,high,low) REGS_FIELD_R(name,type,high,low); REGS_FIELD_W(name,type,high,low);
|
||||
#define REGS_TYPE_FIELD(name,high,low) REGS_FIELD(name,name,high,low)
|
||||
#define REGS_BOOL_FIELD(name,bit) REGS_FIELD(name,bool,bit,bit)
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace USB {
|
||||
namespace Device {
|
||||
|
||||
void Calculator::PollAndReset(bool exitWithKeyboard) {
|
||||
CM4.STCSR()->setTICKINT(false);
|
||||
char serialNumber[Ion::Device::SerialNumberLength+1];
|
||||
Ion::Device::copySerialNumber(serialNumber);
|
||||
Calculator c(serialNumber);
|
||||
@@ -37,6 +38,7 @@ void Calculator::PollAndReset(bool exitWithKeyboard) {
|
||||
* will enter the newly flashed firmware. */
|
||||
Ion::Device::jumpReset();
|
||||
}
|
||||
CM4.STCSR()->setTICKINT(true);
|
||||
}
|
||||
|
||||
Descriptor * Calculator::descriptor(uint8_t type, uint8_t index) {
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
#include "display.h"
|
||||
#include "events_keyboard.h"
|
||||
#include "../../../apps/global_preferences.h"
|
||||
extern "C" {
|
||||
#include <SDL/SDL.h>
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
const char * IonSoftwareVersion();
|
||||
@@ -21,3 +24,7 @@ int main(int argc, char * argv[]) {
|
||||
|
||||
void Ion::msleep(long ms) {
|
||||
}
|
||||
|
||||
long Ion::millis() {
|
||||
return SDL_GetTicks();
|
||||
}
|
||||
|
||||
@@ -116,3 +116,19 @@ void Ion::msleep(long ms) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static auto start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
long Ion::millis() {
|
||||
sDisplay->redraw();
|
||||
Fl::wait(0);
|
||||
auto elapsed = std::chrono::high_resolution_clock::now() - start;
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count();
|
||||
}
|
||||
|
||||
long Ion::micros() {
|
||||
sDisplay->redraw();
|
||||
Fl::wait(0);
|
||||
auto elapsed = std::chrono::high_resolution_clock::now() - start;
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user