mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[ion/timing] Cleanup
This commit is contained in:
@@ -257,7 +257,7 @@ void AppsContainer::displayExamModePopUp(bool activate) {
|
||||
void AppsContainer::shutdownDueToLowBattery() {
|
||||
while (Ion::Battery::level() == Ion::Battery::Charge::EMPTY) {
|
||||
m_emptyBatteryWindow.redraw(true);
|
||||
Ion::msleep(3000);
|
||||
Ion::Timing::msleep(3000);
|
||||
Ion::Power::suspend();
|
||||
}
|
||||
window()->redraw(true);
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
#ifndef ION_TIMING_H
|
||||
#define ION_TIMING_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERNC extern "C"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Ion {
|
||||
namespace Timing {
|
||||
|
||||
void usleep(uint32_t us);
|
||||
#else
|
||||
#define EXTERNC
|
||||
#endif
|
||||
void msleep(uint32_t ms);
|
||||
|
||||
EXTERNC uint64_t millis();
|
||||
/* millis is the number of milliseconds ellapsed since a random epoch.
|
||||
* On the device, epoch is the boot time. */
|
||||
uint64_t millis();
|
||||
|
||||
EXTERNC void msleep(uint32_t ms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,6 +27,7 @@ objs += $(addprefix ion/src/device/, \
|
||||
sd_card.o\
|
||||
stack.o\
|
||||
swd.o \
|
||||
timing.o \
|
||||
usb.o \
|
||||
wakeup.o \
|
||||
)
|
||||
|
||||
@@ -45,12 +45,12 @@ void shutdown() {
|
||||
|
||||
void suspend() {
|
||||
GPIOC.ODR()->set(6, false);
|
||||
msleep(3); // Might not need to be blocking
|
||||
Timing::msleep(3); // Might not need to be blocking
|
||||
}
|
||||
|
||||
void resume() {
|
||||
GPIOC.ODR()->set(6, true);
|
||||
usleep(50);
|
||||
Timing::usleep(50);
|
||||
uint8_t level = sLevel;
|
||||
sLevel = 0xF;
|
||||
setLevel(level);
|
||||
@@ -74,9 +74,9 @@ uint8_t level() {
|
||||
void sendPulses(int n) {
|
||||
for (int i=0; i<n; i++) {
|
||||
GPIOC.ODR()->set(6, false);
|
||||
usleep(20);
|
||||
Timing::usleep(20);
|
||||
GPIOC.ODR()->set(6, true);
|
||||
usleep(20);
|
||||
Timing::usleep(20);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ void Suspend(const char * input) {
|
||||
return;
|
||||
}
|
||||
reply(sOK);
|
||||
Ion::msleep(100);
|
||||
Ion::Timing::msleep(100);
|
||||
Ion::Power::suspend();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "rt0.h"
|
||||
#include "isr.h"
|
||||
extern const void * _stack_start;
|
||||
|
||||
/* Interrupt Service Routines are void->void functions */
|
||||
@@ -28,7 +28,7 @@ ISR InitialisationVector[INITIALISATION_VECTOR_SIZE]
|
||||
0, // DebugMonitor service routine,
|
||||
0, // Reserved
|
||||
0, // PendSV service routine,
|
||||
sysTick, // SysTick service routine
|
||||
isr_systick, // SysTick service routine
|
||||
0, // WWDG service routine
|
||||
0, // PVD service routine
|
||||
0, // TampStamp service routine
|
||||
|
||||
16
ion/src/device/boot/isr.h
Normal file
16
ion/src/device/boot/isr.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef ION_DEVICE_BOOT_ISR_H
|
||||
#define ION_DEVICE_BOOT_ISR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void start();
|
||||
void abort();
|
||||
void isr_systick();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,10 +1,9 @@
|
||||
extern "C" {
|
||||
#include "rt0.h"
|
||||
}
|
||||
#include "isr.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <ion.h>
|
||||
#include "../device.h"
|
||||
#include "../timing.h"
|
||||
#include "../console.h"
|
||||
|
||||
typedef void (*cxx_constructor)();
|
||||
@@ -93,8 +92,6 @@ void start() {
|
||||
abort();
|
||||
}
|
||||
|
||||
volatile uint64_t millis_elapsed = 0;
|
||||
|
||||
void __attribute__((interrupt)) sysTick() {
|
||||
millis_elapsed++;
|
||||
void __attribute__((interrupt)) isr_systick() {
|
||||
Ion::Timing::Device::MillisElapsed++;
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
#ifndef ION_DEVICE_BOOT_RT0_H
|
||||
#define ION_DEVICE_BOOT_RT0_H
|
||||
|
||||
void start();
|
||||
void abort();
|
||||
|
||||
void sysTick();
|
||||
|
||||
#endif
|
||||
@@ -63,7 +63,7 @@ void shutdown() {
|
||||
bool peerConnected() {
|
||||
RxPin.group().PUPDR()->setPull(RxPin.pin(), GPIO::PUPDR::Pull::Down);
|
||||
RxPin.group().MODER()->setMode(RxPin.pin(), GPIO::MODER::Mode::Input);
|
||||
msleep(1);
|
||||
Timing::msleep(1);
|
||||
bool result = RxPin.group().IDR()->get(RxPin.pin());
|
||||
RxPin.group().PUPDR()->setPull(RxPin.pin(), GPIO::PUPDR::Pull::None);
|
||||
RxPin.group().MODER()->setMode(RxPin.pin(), GPIO::MODER::Mode::AlternateFunction);
|
||||
|
||||
@@ -24,27 +24,6 @@ extern "C" {
|
||||
|
||||
// Public Ion methods
|
||||
|
||||
/* TODO: The delay methods 'msleep' and 'usleep' are currently dependent on the
|
||||
* optimizations chosen by the compiler. To prevent that and to gain in
|
||||
* precision, we could use the controller cycle counter (Systick). */
|
||||
|
||||
void Ion::msleep(uint32_t ms) {
|
||||
for (volatile uint32_t i=0; i<8852*ms; i++) {
|
||||
__asm volatile("nop");
|
||||
}
|
||||
}
|
||||
void Ion::usleep(uint32_t us) {
|
||||
for (volatile uint32_t i=0; i<9*us; i++) {
|
||||
__asm volatile("nop");
|
||||
}
|
||||
}
|
||||
|
||||
extern volatile uint64_t millis_elapsed;
|
||||
|
||||
uint64_t Ion::millis() {
|
||||
return millis_elapsed;
|
||||
}
|
||||
|
||||
uint32_t Ion::crc32(const uint32_t * data, size_t length) {
|
||||
bool initialCRCEngineState = RCC.AHB1ENR()->getCRCEN();
|
||||
RCC.AHB1ENR()->setCRCEN(true);
|
||||
|
||||
@@ -23,8 +23,6 @@ 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
|
||||
|
||||
@@ -162,7 +162,7 @@ void initGPIO() {
|
||||
TearingEffectPin.group().MODER()->setMode(TearingEffectPin.pin(), GPIO::MODER::Mode::Input);
|
||||
TearingEffectPin.group().PUPDR()->setPull(TearingEffectPin.pin(), GPIO::PUPDR::Pull::None);
|
||||
|
||||
msleep(120);
|
||||
Timing::msleep(120);
|
||||
}
|
||||
|
||||
|
||||
@@ -247,10 +247,10 @@ void shutdownFSMC() {
|
||||
|
||||
void initPanel() {
|
||||
send_command(Command::Reset);
|
||||
msleep(5);
|
||||
Timing::msleep(5);
|
||||
|
||||
send_command(Command::SleepOut);
|
||||
msleep(5);
|
||||
Timing::msleep(5);
|
||||
|
||||
send_command(Command::PixelFormatSet, 0x05);
|
||||
send_command(Command::TearingEffectLineOn, 0x00);
|
||||
@@ -262,7 +262,7 @@ void initPanel() {
|
||||
void shutdownPanel() {
|
||||
send_command(Command::DisplayOff);
|
||||
send_command(Command::SleepIn);
|
||||
msleep(5);
|
||||
Timing::msleep(5);
|
||||
}
|
||||
|
||||
void setDrawingArea(KDRect r, Orientation o) {
|
||||
|
||||
@@ -6,11 +6,11 @@ namespace Events {
|
||||
|
||||
static bool sleepWithTimeout(int duration, int * timeout) {
|
||||
if (*timeout >= duration) {
|
||||
msleep(duration);
|
||||
Timing::msleep(duration);
|
||||
*timeout -= duration;
|
||||
return false;
|
||||
} else {
|
||||
msleep(*timeout);
|
||||
Timing::msleep(*timeout);
|
||||
*timeout = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ inline void activateRow(uint8_t row) {
|
||||
Device::RowGPIO.ODR()->setBitRange(9, 0, rowState);
|
||||
|
||||
// TODO: 100 us seems to work, but wasn't really calculated
|
||||
usleep(100);
|
||||
Timing::usleep(100);
|
||||
}
|
||||
|
||||
inline bool columnIsActive(uint8_t column) {
|
||||
|
||||
36
ion/src/device/timing.cpp
Normal file
36
ion/src/device/timing.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "timing.h"
|
||||
|
||||
namespace Ion {
|
||||
namespace Timing {
|
||||
|
||||
/* TODO: The delay methods 'msleep' and 'usleep' are currently dependent on the
|
||||
* optimizations chosen by the compiler. To prevent that and to gain in
|
||||
* precision, we could use the controller cycle counter (Systick). */
|
||||
|
||||
void msleep(uint32_t ms) {
|
||||
for (volatile uint32_t i=0; i<8852*ms; i++) {
|
||||
__asm volatile("nop");
|
||||
}
|
||||
}
|
||||
void usleep(uint32_t us) {
|
||||
for (volatile uint32_t i=0; i<9*us; i++) {
|
||||
__asm volatile("nop");
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t millis() {
|
||||
return Ion::Timing::Device::MillisElapsed;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace Ion {
|
||||
namespace Timing {
|
||||
namespace Device {
|
||||
|
||||
volatile uint64_t MillisElapsed = 0;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
16
ion/src/device/timing.h
Normal file
16
ion/src/device/timing.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef ION_DEVICE_TIMING_H
|
||||
#define ION_DEVICE_TIMING_H
|
||||
|
||||
#include <ion/timing.h>
|
||||
|
||||
namespace Ion {
|
||||
namespace Timing {
|
||||
namespace Device {
|
||||
|
||||
extern volatile uint64_t MillisElapsed;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -50,6 +50,7 @@ dfu_objs += ion/src/device/device.o
|
||||
dfu_objs += ion/src/device/usb.o
|
||||
dfu_objs += ion/src/device/base64.o
|
||||
dfu_objs += ion/src/device/flash.o
|
||||
dfu_objs += ion/src/device/timing.o
|
||||
|
||||
ion/src/device/usb/dfu.elf: LDSCRIPT = ion/src/device/usb/dfu.ld
|
||||
ion/src/device/usb/dfu.elf: $(usb_objs) $(dfu_objs)
|
||||
|
||||
@@ -131,7 +131,8 @@ port_objs += $(addprefix python/port/,\
|
||||
helpers.o \
|
||||
modkandinsky.o \
|
||||
modkandinsky_impl.o \
|
||||
modtime.o \
|
||||
mod/time/modtime.o \
|
||||
mod/time/modtime_table.o \
|
||||
mphalport.o \
|
||||
)
|
||||
|
||||
|
||||
27
python/port/mod/time/modtime.cpp
Normal file
27
python/port/mod/time/modtime.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
extern "C" {
|
||||
#include "modtime.h"
|
||||
}
|
||||
#include <ion/timing.h>
|
||||
|
||||
#include "py/smallint.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
static void delay_ms(mp_uint_t delay) {
|
||||
uint32_t start = Ion::Timing::millis();
|
||||
while (Ion::Timing::millis() - start < delay && !micropython_port_should_interrupt()) {
|
||||
Ion::Timing::msleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
mp_obj_t modtime_sleep(mp_obj_t seconds_o) {
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
delay_ms((mp_uint_t)(1000 * mp_obj_get_float(seconds_o)));
|
||||
#else
|
||||
delay_ms(1000 * mp_obj_get_int(seconds_o));
|
||||
#endif
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t modtime_monotonic(void) {
|
||||
return mp_obj_new_float(Ion::Timing::millis() / 1000.0);
|
||||
}
|
||||
4
python/port/mod/time/modtime.h
Normal file
4
python/port/mod/time/modtime.h
Normal file
@@ -0,0 +1,4 @@
|
||||
#include <py/obj.h>
|
||||
|
||||
mp_obj_t modtime_sleep(mp_obj_t seconds_o);
|
||||
mp_obj_t modtime_monotonic();
|
||||
17
python/port/mod/time/modtime_table.c
Normal file
17
python/port/mod/time/modtime_table.c
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "modtime.h"
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(modtime_sleep_obj, modtime_sleep);
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(modtime_monotonic_obj, modtime_monotonic);
|
||||
|
||||
STATIC const mp_rom_map_elem_t modtime_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_time) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&modtime_sleep_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_monotonic), MP_ROM_PTR(&modtime_monotonic_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(modtime_module_globals, modtime_module_globals_table);
|
||||
|
||||
const mp_obj_module_t modtime_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&modtime_module_globals,
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/smallint.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "ion/timing.h"
|
||||
|
||||
static void delay_ms(mp_uint_t delay) {
|
||||
uint32_t start = millis();
|
||||
while (millis() - start < delay && !micropython_port_should_interrupt()) {
|
||||
msleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) {
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
delay_ms((mp_uint_t)(1000 * mp_obj_get_float(seconds_o)));
|
||||
#else
|
||||
delay_ms(1000 * mp_obj_get_int(seconds_o));
|
||||
#endif
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep);
|
||||
|
||||
STATIC mp_obj_t time_monotonic(void) {
|
||||
return mp_obj_new_float(millis() / 1000.0);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(time_monotonic_obj, time_monotonic);
|
||||
|
||||
STATIC const mp_rom_map_elem_t time_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_time) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&time_sleep_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_monotonic), MP_ROM_PTR(&time_monotonic_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
|
||||
|
||||
const mp_obj_module_t time_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&time_module_globals,
|
||||
};
|
||||
@@ -107,8 +107,8 @@ typedef long mp_off_t;
|
||||
#define MP_STATE_PORT MP_STATE_VM
|
||||
|
||||
extern const struct _mp_obj_module_t kandinsky_module;
|
||||
extern const struct _mp_obj_module_t time_module;
|
||||
extern const struct _mp_obj_module_t modtime_module;
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULES \
|
||||
{ MP_ROM_QSTR(MP_QSTR_kandinsky), MP_ROM_PTR(&kandinsky_module) }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&time_module) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&modtime_module) },
|
||||
|
||||
Reference in New Issue
Block a user