mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
Merge with Omega-dev
This commit is contained in:
2
Makefile
2
Makefile
@@ -34,7 +34,7 @@ endif
|
||||
ifeq (${MODEL}, n0110)
|
||||
apps_list = ${EPSILON_APPS}
|
||||
else
|
||||
ifeq (${MODEL}, bootloader)
|
||||
ifeq (${MODEL},bootloader)
|
||||
apps_list = ${EPSILON_APPS}
|
||||
else
|
||||
apps_list = $(foreach i, ${EPSILON_APPS}, $(if $(filter external, $(i)),,$(i)))
|
||||
|
||||
@@ -15,7 +15,6 @@ void Interface::drawImage(KDContext* ctx, const Image* image, int offset) {
|
||||
const uint8_t* data;
|
||||
size_t size;
|
||||
size_t pixelBufferSize;
|
||||
|
||||
if (image != nullptr) {
|
||||
data = image->compressedPixelData();
|
||||
size = image->compressedPixelDataSize();
|
||||
|
||||
@@ -5,7 +5,6 @@ MAGIK_CODE = [0x32, 0x30, 0x30, 0x36]
|
||||
MAGIK_POS = 0x44F
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
print("Patching external bin...")
|
||||
ext_path = os.path.join(os.getcwd(), sys.argv[1])
|
||||
if not os.path.isfile(ext_path):
|
||||
print("Error: File not found!")
|
||||
@@ -23,4 +22,4 @@ if len(sys.argv) > 1:
|
||||
|
||||
file.seek(MAGIK_POS)
|
||||
file.write(packet)
|
||||
print("External bin Patched!")
|
||||
print("External bin patched!")
|
||||
@@ -35,6 +35,7 @@ HANDY_TARGETS += epsilon.A epsilon.B
|
||||
|
||||
.PHONY: epsilon
|
||||
epsilon: $(BUILD_DIR)/epsilon.onboarding.bin
|
||||
$(PYTHON) build/device/secure_ext.py $(BUILD_DIR)/epsilon.onboarding.bin
|
||||
.DEFAULT_GOAL := epsilon
|
||||
|
||||
.PHONY: %_flash
|
||||
|
||||
@@ -17,7 +17,7 @@ class Storage {
|
||||
public:
|
||||
typedef uint16_t record_size_t;
|
||||
|
||||
constexpr static size_t k_storageSize = 61000;
|
||||
constexpr static size_t k_storageSize = 60000;
|
||||
static_assert(UINT16_MAX >= k_storageSize, "record_size_t not big enough");
|
||||
|
||||
static Storage * sharedStorage();
|
||||
|
||||
@@ -225,8 +225,6 @@ void __attribute__((noinline)) start() {
|
||||
|
||||
/* Initialize the FPU as early as possible.
|
||||
* For example, static C++ objects are very likely to manipulate float values */
|
||||
Ion::Device::Board::initFPU();
|
||||
|
||||
/* Copy data section to RAM
|
||||
* The data section is R/W but its initialization value matters. It's stored
|
||||
* in Flash, but linked as if it were in RAM. Now's our opportunity to copy
|
||||
|
||||
@@ -405,7 +405,7 @@ int SectorAtAddress(uint32_t address) {
|
||||
i = address >> NumberOfAddressBitsIn32KbyteBlock;
|
||||
if (i >= 1) {
|
||||
i = Config::NumberOf4KSectors + i - 1;
|
||||
assert(i >= 0 && i <= Config::NumberOf32KSectors);
|
||||
assert(i >= Config::NumberOf4KSectors && i <= Config::NumberOf4KSectors + Config::NumberOf32KSectors);
|
||||
return i;
|
||||
}
|
||||
i = address >> NumberOfAddressBitsIn4KbyteBlock;
|
||||
|
||||
@@ -371,14 +371,13 @@ void MassErase() {
|
||||
|
||||
void WriteMemory(uint8_t * destination, const uint8_t * source, size_t length) {
|
||||
asm("cpsid if");
|
||||
reinterpret_cast<void(*)(uint8_t*, const uint8_t*, size_t)>(Ion::Device::Trampoline::address(Ion::Device::Trampoline::ExternalFlashWriteMemory))(destination, source, length);
|
||||
(*reinterpret_cast<void(**)(uint8_t*, const uint8_t*, size_t)>(Ion::Device::Trampoline::address(Ion::Device::Trampoline::ExternalFlashWriteMemory)))(destination, source, length);
|
||||
asm("cpsie if");
|
||||
}
|
||||
|
||||
void EraseSector(int i) {
|
||||
asm("cpsid if");
|
||||
reinterpret_cast<void(*)(int)>(Ion::Device::Trampoline::address(Ion::Device::Trampoline::ExternalFlashEraseSector))(i);
|
||||
asm("cpsie if");
|
||||
(*reinterpret_cast<void(**)(int)>(Ion::Device::Trampoline::address(Ion::Device::Trampoline::ExternalFlashEraseSector)))(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ void __attribute__((noinline)) internalFlashStandby() {
|
||||
}
|
||||
|
||||
void enterLowPowerMode() {
|
||||
reinterpret_cast<void(*)(void)>(Ion::Device::Trampoline::address(Ion::Device::Trampoline::Suspend))();
|
||||
(*reinterpret_cast<void(**)(void)>(Ion::Device::Trampoline::address(Ion::Device::Trampoline::Suspend)))();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -136,7 +136,6 @@ public:
|
||||
SlotInfo() :
|
||||
m_header(Magic),
|
||||
m_footer(Magic) {}
|
||||
|
||||
void update() {
|
||||
m_header = Magic;
|
||||
m_kernelHeaderAddress = &k_kernelHeader;
|
||||
|
||||
@@ -10,13 +10,22 @@
|
||||
typedef void (*cxx_constructor)();
|
||||
|
||||
extern "C" {
|
||||
extern char _data_section_start_flash;
|
||||
extern char _data_section_start_ram;
|
||||
extern char _data_section_end_ram;
|
||||
extern char _bss_section_start_ram;
|
||||
extern char _bss_section_end_ram;
|
||||
extern cxx_constructor _init_array_start;
|
||||
extern cxx_constructor _init_array_end;
|
||||
extern char _data_section_start_flash;
|
||||
extern char _data_section_start_ram;
|
||||
extern char _data_section_end_ram;
|
||||
extern char _bss_section_start_ram;
|
||||
extern char _bss_section_end_ram;
|
||||
extern cxx_constructor _init_array_start;
|
||||
extern cxx_constructor _init_array_end;
|
||||
}
|
||||
|
||||
void __attribute__((noinline)) abort() {
|
||||
#ifdef NDEBUG
|
||||
Ion::Device::Reset::core();
|
||||
#else
|
||||
while (1) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* In order to ensure that this method is execute from the external flash, we
|
||||
@@ -29,6 +38,7 @@ static void __attribute__((noinline)) external_flash_start() {
|
||||
* after the Power-On Self-Test if there is one or before switching to the
|
||||
* home app otherwise. */
|
||||
Ion::Device::Board::initPeripherals(false);
|
||||
|
||||
return ion_main(0, nullptr);
|
||||
}
|
||||
|
||||
@@ -54,154 +64,6 @@ static void __attribute__((noinline)) jump_to_external_flash() {
|
||||
external_flash_start();
|
||||
}
|
||||
|
||||
void __attribute__((noinline)) abort_init() {
|
||||
Ion::Device::Board::shutdownPeripherals(true);
|
||||
Ion::Device::Board::initPeripherals(false);
|
||||
Ion::Timing::msleep(100);
|
||||
Ion::Backlight::init();
|
||||
Ion::LED::setColor(KDColorRed);
|
||||
Ion::Backlight::setBrightness(180);
|
||||
}
|
||||
|
||||
void __attribute__((noinline)) abort_economy() {
|
||||
int brightness = Ion::Backlight::brightness();
|
||||
bool plugged = Ion::USB::isPlugged();
|
||||
while (brightness > 0) {
|
||||
brightness--;
|
||||
Ion::Backlight::setBrightness(brightness);
|
||||
Ion::Timing::msleep(50);
|
||||
if(plugged || (!plugged && Ion::USB::isPlugged())){
|
||||
Ion::Backlight::setBrightness(180);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Ion::Backlight::shutdown();
|
||||
while (1) {
|
||||
Ion::Device::Power::sleepConfiguration();
|
||||
Ion::Device::WakeUp::onUSBPlugging();
|
||||
Ion::Device::WakeUp::onChargingEvent();
|
||||
Ion::Device::Power::internalFlashSuspend(true);
|
||||
if (!plugged && Ion::USB::isPlugged()) {
|
||||
break;
|
||||
}
|
||||
plugged = Ion::USB::isPlugged();
|
||||
};
|
||||
Ion::Device::Board::setStandardFrequency(Ion::Device::Board::Frequency::High);
|
||||
Ion::Backlight::init();
|
||||
Ion::Backlight::setBrightness(180);
|
||||
}
|
||||
|
||||
void __attribute__((noinline)) abort_sleeping() {
|
||||
if (Ion::Battery::level() != Ion::Battery::Charge::EMPTY) {
|
||||
return;
|
||||
}
|
||||
// we don't use Ion::Power::suspend because we don't want to move the exam buffer into the internal
|
||||
Ion::Device::Board::shutdownPeripherals(true);
|
||||
bool plugged = Ion::USB::isPlugged();
|
||||
while (1) {
|
||||
Ion::Device::Battery::initGPIO();
|
||||
Ion::Device::USB::initGPIO();
|
||||
Ion::Device::LED::init();
|
||||
Ion::Device::Power::sleepConfiguration();
|
||||
Ion::Device::Board::shutdownPeripherals(true);
|
||||
Ion::Device::WakeUp::onUSBPlugging();
|
||||
Ion::Device::WakeUp::onChargingEvent();
|
||||
Ion::Device::Power::internalFlashSuspend(true);
|
||||
Ion::Device::USB::initGPIO();
|
||||
if (!plugged && Ion::USB::isPlugged()) {
|
||||
break;
|
||||
}
|
||||
plugged = Ion::USB::isPlugged();
|
||||
}
|
||||
Ion::Device::Board::setStandardFrequency(Ion::Device::Board::Frequency::High);
|
||||
abort_init();
|
||||
}
|
||||
|
||||
void __attribute__((noinline)) abort_core(const char * text) {
|
||||
Ion::Timing::msleep(100);
|
||||
int counting;
|
||||
while (true) {
|
||||
counting = 0;
|
||||
if (Ion::Battery::level() == Ion::Battery::Charge::EMPTY) {
|
||||
abort_sleeping();
|
||||
abort_screen(text);
|
||||
}
|
||||
|
||||
Ion::USB::enable();
|
||||
Ion::Battery::Charge previous_state = Ion::Battery::level();
|
||||
while (!Ion::USB::isEnumerated()) {
|
||||
if (Ion::Battery::level() == Ion::Battery::Charge::LOW) {
|
||||
if (previous_state != Ion::Battery::Charge::LOW) {
|
||||
previous_state = Ion::Battery::Charge::LOW;
|
||||
counting = 0;
|
||||
}
|
||||
Ion::Timing::msleep(500);
|
||||
if (counting >= 20) {
|
||||
abort_sleeping();
|
||||
abort_screen(text);
|
||||
counting = -1;
|
||||
}
|
||||
counting++;
|
||||
|
||||
} else {
|
||||
if (previous_state == Ion::Battery::Charge::LOW) {
|
||||
previous_state = Ion::Battery::level();
|
||||
counting = 0;
|
||||
}
|
||||
Ion::Timing::msleep(100);
|
||||
if (counting >= 300) {
|
||||
abort_economy();
|
||||
counting = -1;
|
||||
}
|
||||
counting++;
|
||||
}
|
||||
}
|
||||
Ion::USB::DFU(false, false, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void __attribute__((noinline)) abort_screen(const char * text){
|
||||
KDRect screen = KDRect(0, 0, Ion::Display::Width, Ion::Display::Height);
|
||||
Ion::Display::pushRectUniform(KDRect(0, 0, Ion::Display::Width, Ion::Display::Height), KDColor::RGB24(0xffffff));
|
||||
KDContext* ctx = KDIonContext::sharedContext();
|
||||
ctx->setOrigin(KDPointZero);
|
||||
ctx->setClippingRect(screen);
|
||||
ctx->drawString("UPSILON CRASH", KDPoint(90, 10), KDFont::LargeFont, KDColorRed, KDColor::RGB24(0xffffff));
|
||||
ctx->drawString("An error occurred", KDPoint(10, 30), KDFont::SmallFont, KDColorBlack, KDColor::RGB24(0xffffff));
|
||||
ctx->drawString("If you have some important data, please", KDPoint(10, 45), KDFont::SmallFont, KDColorBlack, KDColor::RGB24(0xffffff));
|
||||
ctx->drawString("use bit.ly/upsiBackup to backup them.", KDPoint(10, 60), KDFont::SmallFont, KDColorBlack, KDColor::RGB24(0xffffff));
|
||||
ctx->drawString("YOU WILL LOSE ALL YOUR DATA", KDPoint(10, 85), KDFont::SmallFont, KDColorBlack, KDColor::RGB24(0xffffff));
|
||||
ctx->drawString("→ You can try to reboot by presssing the", KDPoint(10, 110), KDFont::SmallFont, KDColorBlack, KDColor::RGB24(0xffffff));
|
||||
ctx->drawString("reset button at the back of the calculator", KDPoint(10, 125), KDFont::SmallFont, KDColorBlack, KDColor::RGB24(0xffffff));
|
||||
ctx->drawString("→ If Upsilon keeps crashing, you can connect", KDPoint(10, 140), KDFont::SmallFont, KDColorBlack, KDColor::RGB24(0xffffff));
|
||||
ctx->drawString("the calculator to a computer or a phone", KDPoint(10, 160), KDFont::SmallFont, KDColorBlack, KDColor::RGB24(0xffffff));
|
||||
ctx->drawString("and try to reinstall Upsilon", KDPoint(10, 175), KDFont::SmallFont, KDColorBlack, KDColor::RGB24(0xffffff));
|
||||
ctx->drawString(text, KDPoint(220, 200), KDFont::SmallFont, KDColorRed, KDColor::RGB24(0xffffff));
|
||||
}
|
||||
|
||||
void __attribute__((noinline)) abort() {
|
||||
abort_init();
|
||||
abort_screen("HARDFAULT");
|
||||
abort_core("HARDFAULT");
|
||||
}
|
||||
|
||||
void __attribute__((noinline)) nmi_abort() {
|
||||
abort_init();
|
||||
abort_screen("NMIFAULT");
|
||||
abort_core("NMIFAULT");
|
||||
}
|
||||
|
||||
void __attribute__((noinline)) bf_abort() {
|
||||
abort_init();
|
||||
abort_screen("BUSFAULT");
|
||||
abort_core("BUSFAULT");
|
||||
}
|
||||
void __attribute__((noinline)) uf_abort() {
|
||||
abort_init();
|
||||
abort_screen("USAGEFAULT");
|
||||
abort_core("USAGEFAULT");
|
||||
}
|
||||
|
||||
/* When 'start' is executed, the external flash is supposed to be shutdown. We
|
||||
* thus forbid inlining to prevent executing this code from external flash
|
||||
* (just in case 'start' was to be called from the external flash). */
|
||||
@@ -235,7 +97,7 @@ void __attribute__((noinline)) start() {
|
||||
* call the pointed function. */
|
||||
#define SUPPORT_CPP_GLOBAL_CONSTRUCTORS 0
|
||||
#if SUPPORT_CPP_GLOBAL_CONSTRUCTORS
|
||||
for (cxx_constructor* c = &_init_array_start; c < &_init_array_end; c++) {
|
||||
for (cxx_constructor * c = &_init_array_start; c<&_init_array_end; c++) {
|
||||
(*c)();
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <ion.h>
|
||||
#include <ion/usb.h>
|
||||
|
||||
namespace Ion {
|
||||
namespace USB {
|
||||
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
m_storageSize(Ion::Storage::k_storageSize),
|
||||
m_footer(Magic),
|
||||
m_omegaMagicHeader(OmegaMagic),
|
||||
m_OmegaVersion{OMEGA_VERSION},
|
||||
m_omegaVersion{OMEGA_VERSION},
|
||||
#ifdef OMEGA_USERNAME
|
||||
m_username{OMEGA_USERNAME},
|
||||
#else
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
#endif
|
||||
m_omegaMagicFooter(OmegaMagic),
|
||||
m_upsilonMagicHeader(UpsilonMagic),
|
||||
m_UpsilonVersion{UPSILON_VERSION},
|
||||
m_upsilonVersion{UPSILON_VERSION},
|
||||
m_osType(OSType),
|
||||
m_upsilonMagicFooter(UpsilonMagic) { }
|
||||
const char * version() const {
|
||||
@@ -63,7 +63,9 @@ public:
|
||||
assert(m_footer == Magic);
|
||||
assert(m_omegaMagicHeader == OmegaMagic);
|
||||
assert(m_omegaMagicFooter == OmegaMagic);
|
||||
return m_UpsilonVersion;
|
||||
assert(m_upsilonMagicHeader == UpsilonMagic);
|
||||
assert(m_upsilonMagicFooter == UpsilonMagic);
|
||||
return m_upsilonVersion;
|
||||
}
|
||||
const char * omegaVersion() const {
|
||||
assert(m_storageAddress != nullptr);
|
||||
@@ -72,7 +74,7 @@ public:
|
||||
assert(m_footer == Magic);
|
||||
assert(m_omegaMagicHeader == OmegaMagic);
|
||||
assert(m_omegaMagicFooter == OmegaMagic);
|
||||
return m_OmegaVersion;
|
||||
return m_omegaVersion;
|
||||
}
|
||||
const volatile char * username() const volatile {
|
||||
assert(m_storageAddress != nullptr);
|
||||
@@ -104,11 +106,11 @@ private:
|
||||
size_t m_storageSize;
|
||||
uint32_t m_footer;
|
||||
uint32_t m_omegaMagicHeader;
|
||||
const char m_OmegaVersion[16];
|
||||
const char m_omegaVersion[16];
|
||||
const volatile char m_username[16];
|
||||
uint32_t m_omegaMagicFooter;
|
||||
uint32_t m_upsilonMagicHeader;
|
||||
const char m_UpsilonVersion[16];
|
||||
const char m_upsilonVersion[16];
|
||||
uint32_t m_osType;
|
||||
uint32_t m_upsilonMagicFooter;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user