diff --git a/src/drivers.cpp b/src/drivers.cpp index 46e1d429c..138ac755f 100644 --- a/src/drivers.cpp +++ b/src/drivers.cpp @@ -21,12 +21,16 @@ #include "gruvin9x.h" -#ifndef SIMU - uint16_t eeprom_pointer; const char* eeprom_buffer_data; volatile int8_t eeprom_buffer_size = 0; +#ifdef SIMU + +extern void eeprom_write_byte(); + +#else + inline void eeprom_write_byte() { EEAR = eeprom_pointer; @@ -56,15 +60,19 @@ ISR(EE_READY_vect) } } -void eeWriteBlockCmp(const void *i_pointer_ram, void *i_pointer_eeprom, size_t size) +#endif + +void eeWriteBlockCmp(const void *i_pointer_ram, uint16_t i_pointer_eeprom, size_t size) { assert(!eeprom_buffer_size); - eeprom_pointer = (uint16_t)i_pointer_eeprom; + eeprom_pointer = i_pointer_eeprom; eeprom_buffer_data = (const char*)i_pointer_ram; eeprom_buffer_size = size+1; -#if defined (PCBV3) +#ifdef SIMU + sem_post(&eeprom_write_sem); +#elif defined (PCBV3) EECR |= (1<freeList ,sizeof(eeFs.freeList)); + eeWriteBlockCmp(&eeFs.freeList, offsetof(EeFs, freeList), sizeof(eeFs.freeList)); } static void EeFsFlushDirEnt(uint8_t i_fileId) { - eeWriteBlockCmp(&eeFs.files[i_fileId], &((EeFs*)0)->files[i_fileId], sizeof(DirEnt)); + eeWriteBlockCmp(&eeFs.files[i_fileId], offsetof(EeFs, files) + sizeof(DirEnt)*i_fileId, sizeof(DirEnt)); } static void EeFsFlush() { - eeWriteBlockCmp(&eeFs, 0,sizeof(eeFs)); + eeWriteBlockCmp(&eeFs, 0, sizeof(eeFs)); } uint16_t EeFsGetFree() @@ -337,7 +334,7 @@ void RlcFile::write(uint8_t *buf, uint8_t i_len) void RlcFile::nextWriteStep() { - if(!m_currBlk && m_pos==0) { + if (!m_currBlk && m_pos==0) { eeFs.files[FILE_TMP].startBlk = m_currBlk = eeFs.freeList; if (m_currBlk) { eeFs.freeList = EeFsGetLink(m_currBlk); @@ -574,4 +571,12 @@ void RlcFile::flush() s_sync_write = false; } +void RlcFile::DisplayProgressBar() +{ + if (s_eeDirtyMsk || m_rlc_len || eeprom_buffer_size) { + uint8_t len = (s_eeDirtyMsk ? 123 : min((uint8_t)123, (uint8_t)((m_rlc_len) / 5 + eeprom_buffer_size))); + lcd_filled_rect(2, 1, 125, 5, WHITE); + lcd_filled_rect(3, 2, 123-len, 3); + } +} diff --git a/src/file.h b/src/file.h index 82d0351ba..aab72b7dd 100644 --- a/src/file.h +++ b/src/file.h @@ -95,16 +95,15 @@ class RlcFile: public EFile uint8_t m_zeroes; uint8_t m_flags; -#define WRITE_FIRST_LINK 0x01 -#define WRITE_NEXT_LINK_1 0x02 -#define WRITE_NEXT_LINK_2 0x03 +#define WRITE_FIRST_LINK 0x01 +#define WRITE_NEXT_LINK_1 0x02 +#define WRITE_NEXT_LINK_2 0x03 #define WRITE_START_STEP 0x10 #define WRITE_FREE_UNUSED_BLOCKS_STEP1 0x20 #define WRITE_FREE_UNUSED_BLOCKS_STEP2 0x30 #define WRITE_FINAL_DIRENT_STEP 0x40 #define WRITE_TMP_DIRENT_STEP 0x50 uint8_t m_write_step; - uint16_t m_rlc_len; uint8_t * m_rlc_buf; uint8_t m_cur_rlc_len; @@ -144,6 +143,7 @@ public: uint16_t readRlc(uint8_t*buf, uint16_t i_len); // TODO should be like writeRlc? #endif + void DisplayProgressBar(); }; #endif diff --git a/src/gruvin9x.h b/src/gruvin9x.h index 2cc0cfa88..d34e34a90 100644 --- a/src/gruvin9x.h +++ b/src/gruvin9x.h @@ -34,9 +34,7 @@ #endif #ifdef SIMU - #include "simpgmspace.h" - #define APM - #include "stdio.h" +#include "simpgmspace.h" #else ///opt/cross/avr/include/avr/pgmspace.h #include @@ -557,7 +555,7 @@ template inline t limit(t mi, t x, t ma){ return min(max(mi,x),ma); } /// Markiert einen EEPROM-Bereich als dirty. der Bereich wird dann in /// eeCheck ins EEPROM zurueckgeschrieben. -void eeWriteBlockCmp(const void *i_pointer_ram, void *i_pointer_eeprom, size_t size); +void eeWriteBlockCmp(const void *i_pointer_ram, uint16_t i_pointer_eeprom, size_t size); void eeDirty(uint8_t msk); inline void eeFlush() { theFile.flush(); } void eeCheck(bool immediately=false); diff --git a/src/gtests.cpp b/src/gtests.cpp index cc4614560..c90db4341 100644 --- a/src/gtests.cpp +++ b/src/gtests.cpp @@ -72,7 +72,7 @@ TEST(outdezNAtt, test_unsigned) { EXPECT_EQ(memcmp(refBuf, displayBuf, sizeof(displayBuf)), 0) << "Unsigned numbers will be bad displayed"; } -TEST(EEPROM, test1) { +TEST(EEPROM, 1000_random_writes) { eepromFile = NULL; // in memory RlcFile f; uint8_t buf[1000]; @@ -80,7 +80,7 @@ TEST(EEPROM, test1) { EeFsFormat(); - for(int i=0; i<10000; i++) { + for(int i=0; i<1000; i++) { int size = rand()%800; for(int j=0; j=0)) { + displayPopup(s_copyMode==COPY_MODE ? PSTR("Copying model...") : PSTR("Moving model...")); eeCheck(true); // force writing of current model data before this is changed uint8_t cur = (16 + sub + s_copyTgtOfs) % 16; @@ -231,6 +242,7 @@ void menuProcModelSelect(uint8_t event) s_copyTgtOfs = 0; } else if (_event == EVT_KEY_LONG(KEY_MENU)) { + displayPopup(PSTR("Loading model...")); eeCheck(true); // force writing of current model data before this is changed if (g_eeGeneral.currModel != sub) { g_eeGeneral.currModel = sub; @@ -238,6 +250,7 @@ void menuProcModelSelect(uint8_t event) eeLoadModel(sub); } killEvents(event); + return; } else if (EFile::exists(FILE_MODEL(sub))) { s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE); @@ -370,13 +383,12 @@ void EditName(uint8_t x, uint8_t y, char *name, uint8_t size, uint8_t event, boo #define PARAM_OFS (9*FW+2) void menuProcModel(uint8_t event) { + lcd_outdezNAtt(7*FW,0,g_eeGeneral.currModel+1,INVERS+LEADING0,2); MENU("SETUP", menuTabModel, e_Model, (g_model.protocol ? 10 : 11), {0,sizeof(g_model.name)-1,3,3,0,0,0,1,6,2,1}); uint8_t sub = m_posVert; uint8_t y = 1*FH; - lcd_outdezNAtt(7*FW,0,g_eeGeneral.currModel+1,INVERS+LEADING0,2); - uint8_t subN = 1; if(s_pgOfs= MAX_CURVE5) { points = 9; @@ -1041,11 +1054,10 @@ inline void editExpoVals(uint8_t event, uint8_t which, bool edit, uint8_t y, uin void menuProcExpoOne(uint8_t event) { - SIMPLE_SUBMENU("DR/EXPO", 6); - ExpoData *ed = expoaddress(s_currIdx); + putsChnRaw(7*FW+FW/2,0,ed->chn+1,0); - putsChnRaw(lcd_lastPos+FW/2,0,ed->chn+1,0); + SIMPLE_SUBMENU("DR/EXPO", 6); int8_t sub = m_posVert; @@ -1077,10 +1089,11 @@ void menuProcExpoOne(uint8_t event) void menuProcMixOne(uint8_t event) { - SIMPLE_SUBMENU_NOTITLE(13); TITLEP(s_currCh ? PSTR("INSERT MIX ") : PSTR("EDIT MIX ")); MixData *md2 = mixaddress(s_currIdx) ; putsChn(lcd_lastPos+1*FW,0,md2->destCh,0); + SIMPLE_SUBMENU_NOTITLE(13); + int8_t sub = m_posVert; for(uint8_t k=0; k<7; k++) @@ -1245,8 +1258,10 @@ void menuProcExpoMix(uint8_t expo, uint8_t __event) event -= KEY_EXIT; } - SIMPLE_MENU_NOTITLE(menuTabModel, expo ? e_ExposAll : e_MixAll, s_maxLines); TITLEP(expo ? PSTR("DR/EXPO") : PSTR("MIXER")); + lcd_outdezAtt(lcd_lastPos+2*FW+FW/2, 0, getExpoMixCount(expo)); + lcd_puts_P(lcd_lastPos, 0, expo ? PSTR("/14") : PSTR("/32")); + SIMPLE_MENU_NOTITLE(menuTabModel, expo ? e_ExposAll : e_MixAll, s_maxLines); uint8_t sub = m_posVert; @@ -1351,9 +1366,6 @@ void menuProcExpoMix(uint8_t expo, uint8_t __event) break; } - lcd_outdezAtt(lcd_lastPos+2*FW+FW/2, 0, getExpoMixCount(expo)); - lcd_puts_P(lcd_lastPos, 0, expo ? PSTR("/14") : PSTR("/32")); - s_currCh = 0; uint8_t cur = 1; uint8_t i = 0; diff --git a/src/pers.cpp b/src/pers.cpp index 42364f7db..c7d5e8246 100644 --- a/src/pers.cpp +++ b/src/pers.cpp @@ -289,7 +289,7 @@ void eeLoadModel(uint8_t id) } #endif - if (sz != sizeof(ModelData)) { + if (sz < 730/*sizeof(last compatible eeprom)*/) { // alert("Error Loading Model"); modelDefault(id); eeCheck(true); diff --git a/src/simpgmspace.cpp b/src/simpgmspace.cpp index b5ab2bae5..ee18b09d4 100644 --- a/src/simpgmspace.cpp +++ b/src/simpgmspace.cpp @@ -30,51 +30,52 @@ volatile unsigned char pinb=0, pinc=0xff, pind, pine=0xff, ping=0xff; unsigned char portb, dummyport; const char *eepromFile = "eeprom.bin"; -volatile int8_t eeprom_buffer_size = 0; +extern uint16_t eeprom_pointer; +extern const char* eeprom_buffer_data; uint8_t eeprom[EESIZE]; +sem_t eeprom_write_sem; +pthread_t write_thread_pid = 0; -void eeWriteBlockCmp(const void *i_pointer_ram, void *pointer_eeprom, size_t size) +void *eeprom_write_function(void *) { -#if 0 - printf(" eeWriteBlockCmp(%d %d)", size, (int)pointer_eeprom); - for(uint8_t i=0; i 0); + if (fp) { + if (fseek(fp, eeprom_pointer, SEEK_SET) == -1) + perror("error in fseek"); + if (fwrite(eeprom_buffer_data, 1, 1, fp) != 1) + perror("error in fwrite"); + usleep(5000/*5ms*/); + } + else { + memcpy(&eeprom[eeprom_pointer], eeprom_buffer_data, 1); + } + eeprom_pointer++; + eeprom_buffer_data++; + + if (fp && eeprom_buffer_size == 1) { + fclose(fp); + } } - fclose(fp); - } - else { - memcpy(&eeprom[(int64_t)pointer_eeprom], i_pointer_ram, size); } + + return 0; +} + +void InitEepromThread() +{ + sem_init(&eeprom_write_sem, 0, 0); + assert(!pthread_create(&write_thread_pid, NULL, &eeprom_write_function, NULL)); } void eeprom_read_block (void *pointer_ram, diff --git a/src/simpgmspace.h b/src/simpgmspace.h index e86f715ec..ee4a14e4e 100644 --- a/src/simpgmspace.h +++ b/src/simpgmspace.h @@ -22,6 +22,10 @@ #include #include #include +#include +#include + +#define APM typedef unsigned char prog_uchar; typedef const char prog_char; @@ -30,7 +34,7 @@ typedef const uint8_t prog_uint8_t; typedef const int16_t prog_int16_t; typedef const int8_t prog_int8_t; - +extern sem_t eeprom_write_sem; #define PROGMEM #define pgm_read_byte(address_short) (*(uint8_t*)(address_short)) @@ -76,6 +80,8 @@ typedef const int8_t prog_int8_t; extern volatile unsigned char pinb,pinc,pind,pine,ping; extern unsigned char portb,dummyport; +void InitEepromThread(); + extern const char *eepromFile; void eeprom_read_block (void *pointer_ram, const void *pointer_eeprom, diff --git a/src/simu.cpp b/src/simu.cpp index 7c6de7b6d..4684e2c9c 100644 --- a/src/simu.cpp +++ b/src/simu.cpp @@ -363,7 +363,6 @@ void *init_function(void *) { return 0; } -#include long Gruvin9xSim::onChore(FXObject*,FXSelector,void*) { pthread_t pid; @@ -396,7 +395,9 @@ int main(int argc,char **argv) if(argc>=2){ eepromFile = argv[1]; } - printf("eeprom = %s\n",eepromFile); + printf("eeprom = %s\n", eepromFile); + + InitEepromThread(); // Each FOX GUI program needs one, and only one, application object. // The application objects coordinates some common stuff shared between diff --git a/src/statistics_views.cpp b/src/statistics_views.cpp index b1303bcfe..836621ec9 100644 --- a/src/statistics_views.cpp +++ b/src/statistics_views.cpp @@ -73,7 +73,7 @@ void menuProcStatistic2(uint8_t event) switch(event) { case EVT_KEY_FIRST(KEY_MENU): - g_tmr1Latency_min = 0x7ff; + g_tmr1Latency_min = 0xff; g_tmr1Latency_max = 0; g_timeMain = 0; // g_time_per10 = 0;