diff --git a/apps/external/app/sample.c b/apps/external/app/sample.c index dbc13fd9545..84fc8a5ae0b 100644 --- a/apps/external/app/sample.c +++ b/apps/external/app/sample.c @@ -1,6 +1,6 @@ #include -void extapp_main() { +void extapp_main(int argc, char **argv) { extapp_pushRectUniform(10, 10, LCD_WIDTH-20, LCD_HEIGHT-20, 0); extapp_msleep(1000); } diff --git a/apps/external/archive.cpp b/apps/external/archive.cpp index 285e262a586..ad44114a187 100644 --- a/apps/external/archive.cpp +++ b/apps/external/archive.cpp @@ -5,6 +5,11 @@ #include #include +// Argv static definition (temporary), will be removed when argv is implemented +// TODO: Move it to executeFileAtIndex() +static char *argv[] = { "archive", "--help" }; +static int argc = 2; + namespace External { namespace Archive { @@ -98,7 +103,7 @@ bool fileAtIndex(size_t index, File &entry) { } extern "C" void (* const apiPointers[])(void); -typedef uint32_t (*entrypoint)(const uint32_t, const void *, void *, const uint32_t); +typedef uint32_t (*entrypoint)(const uint32_t, const void *, void *, const uint32_t, int, char * []); uint32_t executeFile(const char *name, void * heap, const uint32_t heapSize) { File entry; @@ -108,7 +113,7 @@ uint32_t executeFile(const char *name, void * heap, const uint32_t heapSize) { } uint32_t ep = *reinterpret_cast(entry.data); if(ep >= 0x90200000 && ep < 0x90800000) { - return ((entrypoint)ep)(API_VERSION, apiPointers, heap, heapSize); + return ((entrypoint)ep)(API_VERSION, apiPointers, heap, heapSize, argc, argv); } } return -1; @@ -130,10 +135,10 @@ bool fileAtIndex(size_t index, File &entry) { return true; } -extern "C" void extapp_main(void); +extern "C" void extapp_main(int argc, char *argv[]); uint32_t executeFile(const char *name, void * heap, const uint32_t heapSize) { - extapp_main(); + extapp_main(argc, argv); return 0; } diff --git a/apps/external/extapp_api.cpp b/apps/external/extapp_api.cpp index 23254ab9146..9d71b07d48e 100644 --- a/apps/external/extapp_api.cpp +++ b/apps/external/extapp_api.cpp @@ -212,6 +212,11 @@ static void reloadTitleBar() { AppsContainer::sharedAppsContainer()->updateBatteryState(); AppsContainer::sharedAppsContainer()->reloadTitleBarView(); AppsContainer::sharedAppsContainer()->redrawWindow(); + // Refresh the display on simulator. + #ifndef DEVICE + Ion::Keyboard::scan(); + #endif + } void extapp_lockAlpha() { @@ -377,6 +382,174 @@ bool extapp_inExamMode() { return GlobalPreferences::sharedGlobalPreferences()->isInExamMode(); } +uint8_t extapp_getBrightness () { + // TODO: Support dimming + return GlobalPreferences::sharedGlobalPreferences()->brightnessLevel(); +} + +void extapp_setBrightness (uint8_t b) { + GlobalPreferences::sharedGlobalPreferences()->setBrightnessLevel(b); + Ion::Backlight::setBrightness(b); +} + +int extapp_batteryLevel() { + return (int)Ion::Battery::level(); +} + +float extapp_batteryVoltage() { + return Ion::Battery::voltage(); +} + +bool extapp_batteryCharging() { + return Ion::Battery::isCharging(); +} + +int extapp_batteryPercentage() { + // We don't have a battery percentage, so compute it from the voltage + // TODO: Move it to Ion::Battery + int percentage = (extapp_batteryVoltage() - 3.6) * 166; + // Ensure that the percentage is between 0 and 100 + if (percentage < 0) + percentage = 1; + if (percentage > 100) + percentage = 100; + return (int)percentage; +} + +DateTime extapp_getDateTime() { + Ion::RTC::DateTime dt = Ion::RTC::dateTime(); + // TODO: This should not be necessary + return DateTime { + dt.tm_sec, + dt.tm_min, + dt.tm_hour, + dt.tm_mday, + dt.tm_mon, + dt.tm_year, + dt.tm_wday, + }; +} + +void extapp_setDateTime(DateTime dt) { + // TODO: Conversion should not be necessary (same format is used in the RTC), but casting is not working... + Ion::RTC::setDateTime(Ion::RTC::DateTime { + dt.tm_sec, + dt.tm_min, + dt.tm_hour, + dt.tm_mday, + dt.tm_mon, + dt.tm_year, + dt.tm_wday, + }); +} + +void extapp_setRTCMode(int mode) { + Ion::RTC::setMode((Ion::RTC::Mode)mode); +} + +int extapp_getRTCMode() { + return (int)Ion::RTC::mode(); +} + +//////////////////////////////////////////////////////////////////////////////// +// Code from MicroPython +static const uint16_t days_since_jan1[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; + +bool is_leap_year(mp_uint_t year) { + return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; +} + +// compute the day of the year, between 1 and 366 +// month should be between 1 and 12, date should start at 1 +uint64_t year_day(uint16_t year, uint8_t month, uint8_t date) { + mp_uint_t yday = days_since_jan1[month - 1] + date; + if (month >= 3 && is_leap_year(year)) { + yday += 1; + } + return yday; +} + +// returns the number of seconds, as an integer, since 2000-01-01 +uint64_t seconds_since_2000(Ion::RTC::DateTime tm) { + return + tm.tm_sec + + tm.tm_min * 60 + + tm.tm_hour * 3600 + + (year_day(tm.tm_year, tm.tm_mon, tm.tm_mday) - 1 + + ((tm.tm_year - 2000 + 3) / 4) // add a day each 4 years starting with 2001 + - ((tm.tm_year - 2000 + 99) / 100) // subtract a day each 100 years starting with 2001 + + ((tm.tm_year - 2000 + 399) / 400) // add a day each 400 years starting with 2001 + ) * 86400 + + (tm.tm_year - 2000) * 31536000; +} + +//////////////////////////////////////////////////////////////////////////////// + +uint64_t extapp_getTime() { + Ion::RTC::DateTime dt = Ion::RTC::dateTime(); + return seconds_since_2000(dt); +} + +uint32_t extapp_random() { + return Ion::random(); +} + +void extapp_reloadTitleBar() { + reloadTitleBar(); +} + +const char * extapp_username() { + return (const char *)Ion::username(); +} + +const char * extapp_getOS() { + return "Upsilon"; +} + +const char * extapp_getOSVersion() { + return Ion::upsilonVersion(); +} + +const char * extapp_getOSCommit() { + return Ion::patchLevel(); +} + +size_t extapp_storageSize() { + return Ion::Storage::k_storageSize; +} + +size_t extapp_storageAvailable() { + return Ion::Storage::sharedStorage()->availableSize(); +} + +size_t extapp_storageUsed() { + return extapp_storageSize() - extapp_storageAvailable(); +} + +struct Settings extapp_getSettings() { + Poincare::Preferences * poincare_preferences = Poincare::Preferences::sharedPreferences(); + return Settings { + (uint8_t)poincare_preferences->angleUnit(), + (uint8_t)poincare_preferences->displayMode(), + poincare_preferences->numberOfSignificantDigits(), + (uint8_t)poincare_preferences->complexFormat(), + GlobalPreferences::sharedGlobalPreferences()->font() == KDFont::LargeFont ? true : false, + }; +} + +void extapp_setSettings(Settings settings) { + Poincare::Preferences * poincare_preferences = Poincare::Preferences::sharedPreferences(); + poincare_preferences->setAngleUnit((Poincare::Preferences::AngleUnit)settings.angleUnit); + poincare_preferences->setDisplayMode((Poincare::Preferences::PrintFloatMode)settings.displayMode); + poincare_preferences->setNumberOfSignificantDigits(settings.numberOfSignificantDigits); + poincare_preferences->setComplexFormat((Poincare::Preferences::ComplexFormat)settings.complexFormat); + if (settings.largeFont) { + GlobalPreferences::sharedGlobalPreferences()->setFont(KDFont::LargeFont); + } else { + GlobalPreferences::sharedGlobalPreferences()->setFont(KDFont::SmallFont); + } +} + extern "C" void (* const apiPointers[])(void) = { (void (*)(void)) extapp_millis, (void (*)(void)) extapp_msleep, @@ -402,5 +575,27 @@ extern "C" void (* const apiPointers[])(void) = { (void (*)(void)) extapp_eraseSector, (void (*)(void)) extapp_writeMemory, (void (*)(void)) extapp_inExamMode, + (void (*)(void)) extapp_getBrightness, + (void (*)(void)) extapp_setBrightness, + (void (*)(void)) extapp_batteryLevel, + (void (*)(void)) extapp_batteryVoltage, + (void (*)(void)) extapp_batteryCharging, + (void (*)(void)) extapp_batteryPercentage, + (void (*)(void)) extapp_getDateTime, + (void (*)(void)) extapp_setDateTime, + (void (*)(void)) extapp_setRTCMode, + (void (*)(void)) extapp_getRTCMode, + (void (*)(void)) extapp_getTime, + (void (*)(void)) extapp_random, + (void (*)(void)) extapp_reloadTitleBar, + (void (*)(void)) extapp_username, + (void (*)(void)) extapp_getOS, + (void (*)(void)) extapp_getOSVersion, + (void (*)(void)) extapp_getOSCommit, + (void (*)(void)) extapp_storageSize, + (void (*)(void)) extapp_storageAvailable, + (void (*)(void)) extapp_storageUsed, + (void (*)(void)) extapp_getSettings, + (void (*)(void)) extapp_setSettings, (void (*)(void)) nullptr, -}; \ No newline at end of file +}; diff --git a/apps/external/extapp_api.h b/apps/external/extapp_api.h index 9a98e5526d4..6f381177250 100644 --- a/apps/external/extapp_api.h +++ b/apps/external/extapp_api.h @@ -5,21 +5,30 @@ #include #include -#define API_VERSION 2 +#define API_VERSION 3 #ifdef __cplusplus #define EXTERNC extern "C" #else -#define EXTERNC +#define EXTERNC extern #endif +// Screen size +// The screen width #define LCD_WIDTH 320 +// The screen height #define LCD_HEIGHT 240 +// Files systems +// The RAM file system, which can be written, and it is used by the system applications, +// this storage is erased on reset #define EXTAPP_RAM_FILE_SYSTEM 0 +// The flash file system, which is written by the external application website, +// used for big files storing, and roms, this storage is kept after a reset #define EXTAPP_FLASH_FILE_SYSTEM 1 #define EXTAPP_BOTH_FILE_SYSTEM 2 +// The code of the keys, returned by `extapp_scanKeyboard()` #define SCANCODE_Left ((uint64_t)1 << 0) #define SCANCODE_Up ((uint64_t)1 << 1) #define SCANCODE_Down ((uint64_t)1 << 2) @@ -68,6 +77,7 @@ #define SCANCODE_EXE ((uint64_t)1 << 52) #define SCANCODE_None ((uint64_t)1 << 54) +// Keys, returned by `extapp_getKey()` // Character codes #define KEY_CHAR_0 0x30 #define KEY_CHAR_1 0x31 @@ -234,28 +244,310 @@ #define KEY_PRGM_SHIFT 78 #define KEY_PRGM_MENU 48 +// Types definitions +// Date and time +struct DateTime { + int tm_sec; + int tm_min; + int tm_hour; // 0-23 + int tm_mday; // 1-31 + int tm_mon; // 1-12 + int tm_year; + int tm_wday; // 0-6, 0 is Monday +}; + +// Settings +// TODO: Improve this structure when using C++ +struct Settings { + // 0 for degrees, 1 for radians, 2 for gradians + uint8_t angleUnit; + // 0 for decimal, 1 for Scientific, 2 for Engineering + uint8_t displayMode; + // Raw number of digits, max is 14 + uint8_t numberOfSignificantDigits; + // 0 for real, 1 for cartesian, 2 for polar + uint8_t complexFormat; + // If true, the big font should be used. + bool largeFont; +}; + +// External API functions +/** + * Get the current date, in milliseconds, from the boot, excluding suspended time + * @return uint64_t, the current date from the boot in milliseconds + */ EXTERNC uint64_t extapp_millis(); +/** + * Sleep ms milliseconds + * @param ms uint32_t, the number of milliseconds to sleep + */ EXTERNC void extapp_msleep(uint32_t ms); +// Scan the keyboard, and return a key that can be identified by SCANCODE_* constants (like SCANCODE_Left) EXTERNC uint64_t extapp_scanKeyboard(); +/** + * Push a buffer of pixels to the screen + * @param x uint16_t, the x position of the buffer to display on the screen + * @param y uint16_t, the y position of the buffer to display on the screen + * @param w uint16_t, the width of the buffer to display on the screen + * @param h uint16_t, the height of the buffer to display on the screen + * @param pixels const uint16_t *, the buffer to display on the screen + */ EXTERNC void extapp_pushRect(int16_t x, int16_t y, uint16_t w, uint16_t h, const uint16_t * pixels); +/** + * Push a colored rectangle on the screen + * @param x uint16_t, the x position of the rectangle + * @param y uint16_t, the y position of the rectangle + * @param w uint16_t, the width of the rectangle + * @param h uint16_t, the height of the rectangle + * @param color uint16_t, the color of the rectangle + */ EXTERNC void extapp_pushRectUniform(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t color); +/** + * Push a rectangle from the screen + * @param x uint16_t, the x position of the rectangle + * @param y uint16_t, the y position of the rectangle + * @param w uint16_t, the width of the rectangle + * @param h uint16_t, the height of the rectangle + * @param pixels uint16_t *, the pointer to the buffer to store the pixel rect + */ EXTERNC void extapp_pullRect(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t * pixels); +/** + * Display large text + * @param text const char *t, the text to display + * @param x int16_t, the x position of the text to display + * @param y int16_t, the y position of the text to display + * @param fg uint16_t, the color of the foreground + * @param bg uint16_t, the color of the background + * @param fake bool, whether to not display the text, just return the size of the text + * @return uint16_t, the width of the text + */ EXTERNC int16_t extapp_drawTextLarge(const char *text, int16_t x, int16_t y, uint16_t fg, uint16_t bg, bool fake); +/** + * Display small text + * @param text const char *t, the text to display + * @param x int16_t, the x position of the text to display + * @param y int16_t, the y position of the text to display + * @param fg uint16_t, the color of the foreground + * @param bg uint16_t, the color of the background + * @param fake bool, whether to not display the text, just return the size of the text + * @return uint16_t, the width of the text + */ EXTERNC int16_t extapp_drawTextSmall(const char *text, int16_t x, int16_t y, uint16_t fg, uint16_t bg, bool fake); +/** + * Wait for screen refresh + */ EXTERNC bool extapp_waitForVBlank(); +/** + * Set text into clipboard + * @param text const char *t, the text to copy + */ EXTERNC void extapp_clipboardStore(const char *text); +/** + * Get clipboard contents + * @return const char *, the contents of the clipboard + */ EXTERNC const char * extapp_clipboardText(); +/** + * Get a list of files in "storage", filtered by extension + * @param filename const char **, an array that must to be a equal to + * the maxrecords variable, to avoid buffer overflow + * @param maxrecords int, the maximum number of records that can be retrieved, + * it should be equal to the length of the filenames array, + * to avoid buffer overflow + * @param extension const char *, the extension of the filename to retrieve, + * it work only with RAM file system for now + * @param storage int, the storage to use (like EXTAPP_FLASH_FILE_SYSTEM) + * @return int, the number of retrieved records + */ EXTERNC int extapp_fileListWithExtension(const char ** filenames, int maxrecords, const char * extension, int storage); +/** + * Return if "filename" exist in "storage" + * @param filename const char *, the file to check existing + * @param storage int, the storage to use (like EXTAPP_FLASH_FILE_SYSTEM) + * @return bool, true if the operation is successful + */ EXTERNC bool extapp_fileExists(const char * filename, int storage); +/** + * Erase "filename" in "storage" + * @param filename const char *, the file to remove + * @param storage int, the storage to use (like EXTAPP_RAM_FILE_SYSTEM) + * @return bool, true if the operation is successful + */ EXTERNC bool extapp_fileErase(const char * filename, int storage); +/** + * Read "filename" from "storage" + * @param filename const char *, the file to read + * @param len, size_t, a pointer to a size_t variable, to store the file length + * @param storage int, the storage to use (like EXTAPP_FLASH_FILE_SYSTEM) + * @return const char *, the file content + */ EXTERNC const char * extapp_fileRead(const char * filename, size_t *len, int storage); +/** + * Write "content" into "filename" in "storage" + * @param filename const char *, the file to write + * @param content, const char *, the content of the file to write + * @param len, size_t, the length of the file to write + * @param storage int, the storage to use (like EXTAPP_FLASH_FILE_SYSTEM) + * @return bool, true if the operation is successful + */ EXTERNC bool extapp_fileWrite(const char * filename, const char * content, size_t len, int storage); +/** + * Enable alpha lock + */ EXTERNC void extapp_lockAlpha(); +/** + * Reset keyboard status, like alpha lock + */ EXTERNC void extapp_resetKeyboard(); +/** + * Get pressed keys + * @param allowSuspend bool, whether to allow suspending the calculator + * @param alphaWasActive bool, a pointer to a bool to store if the alpha (lock) was active + * @return int, the code of the pressed key, like KEY_CHAR_0 or KEY_CTRL_EXE + */ EXTERNC int extapp_getKey(int allowSuspend, bool *alphaWasActive); +/** + * If given key is pressed + * @param key int, the key to check + * @return bool, true if the key is pressed + */ EXTERNC bool extapp_isKeydown(int key); -EXTERNC int extapp_restoreBackup(int mode); // Keep for compatibility with KhiCAS on Khi -EXTERNC bool extapp_eraseSector(void * ptr); -EXTERNC bool extapp_writeMemory(unsigned char * dest,const unsigned char * data,size_t length); +/** + * Restore the exam mode backup, created by KhiCAS and Khi + * @param mode int, the mode to restore (TODO: Improve this) + * @return int, higher than 0 if the operation is successful + */ +EXTERNC int extapp_restorebackup(int mode); // currently works only with mode==-1 to restore scriptstore after exam mode +/** + * Erase flash sector, works only when "Write allowed" is enabled in the calculator + * @param ptr void *, the sector to erase + * @return bool, true if the operation is successful + */ +EXTERNC bool extapp_erasesector(void * ptr); +/** + * Write flash sector, works only when "Write allowed" is enabled in the calculator + * @param dest unsigned char *, the destination address + * @param data unsigned char *, the data to write + * @param length size_t, the length of the data to write + */ +EXTERNC bool extapp_writesector(unsigned char * dest,const unsigned char * data,size_t length); +/** + * Get if the exam mode is active + * @return bool, true if the exam mode is active + */ +EXTERNC bool extapp_inExamMode(); +/** + * Get the actual brightness + * @return uint8_t, the actual brightness + */ +EXTERNC uint8_t extapp_getBrightness(); +/** + * Set the brightness + * @param brightness uint8_t, the brightness to set + */ +EXTERNC void extapp_setBrightness(uint8_t brightness); +/** + * Get the battery level (0-3, 0 is empty, 1 is low, 2 is somewhere in between, 3 is full) + * @return int, the battery level + */ +EXTERNC int extapp_batteryLevel(); +/** + * Get the battery voltage (in V) + * @return float, the battery voltage + */ +EXTERNC float extapp_batteryVoltage(); +/** + * Get if the battery is charging + * @return bool, true if the battery is charging + */ +EXTERNC bool extapp_batteryCharging(); +/** + * Get battery percentage (0-100), computed from battery voltage + * @return int, the battery percentage + */ +EXTERNC int extapp_batteryPercentage(); +/** + * Get the current RTC time + * @return DateTime, the current RTC time + */ +EXTERNC struct DateTime extapp_getDateTime(); + +/** + * Set the RTC time + * @param dt DateTime, the time to set + */ +EXTERNC void extapp_setDateTime(struct DateTime dt); +/** + * Set the RTC mode (0 for disabled, 1 for LSI (low consumption), 2 for HSE (high precision)) + * @param mode int, the mode to set + */ +EXTERNC void extapp_setRTCMode(int mode); +/** + * Get the RTC mode (0 for disabled, 1 for LSI (low consumption), 2 for HSE (high precision)) + * @return int, the RTC mode + */ +EXTERNC int extapp_getRTCMode(); +/** + * Get the current time from 2000-01-01 00:00:00 + * @return uint64_t, the current time from 2000-01-01 00:00:00 + */ +EXTERNC uint64_t extapp_getTime(); +/** + * Get a 32 bit true random number that can be casted to any (32 bit or less) type + * @return uint32_t, the random number + */ +EXTERNC uint32_t extapp_random(); +/** + * Reload the title bar + */ +EXTERNC void extapp_reloadTitleBar(); +/** + * Get the username + * @return const char *, the username + */ +EXTERNC const char * extapp_username(); +/** + * Get the OS name + * @return const char *, the OS name + */ +EXTERNC const char * extapp_getOS(); +/** + * Get the OS version + * @return const char *, the OS version + */ +EXTERNC const char * extapp_getOSVersion(); +/** + * Get the OS commit hash + * @return const char *, the OS commit hash + */ +EXTERNC const char * extapp_getOSCommit(); +/** + * Get the RAM storage size + * @return size_t, the RAM storage size + */ +EXTERNC size_t extapp_storageSize(); +/** + * Get the available RAM storage size + * @return size_t, the available RAM storage size + */ +EXTERNC size_t extapp_storageAvailable(); +/** + * Get the used RAM storage size + * @return size_t, the used RAM storage size + */ +EXTERNC size_t extapp_storageUsed(); +/** + * Get the settings + * @return struct Settings, the settings + */ +EXTERNC struct Settings extapp_getSettings(); +/** + * Set the settings + * @param settings struct Settings, the settings to set + */ +EXTERNC void extapp_setSettings(struct Settings settings); +EXTERNC uint32_t _heap_size; +EXTERNC void *_heap_base; +EXTERNC void *_heap_ptr; #endif