mirror of
https://github.com/opentx/opentx.git
synced 2025-07-21 23:35:17 +03:00
EEPROM async write bug solved. Progress bar. Popup on MODELSEL. Simu EEPROM async write.
This commit is contained in:
parent
9761da9de3
commit
5e633363a9
14 changed files with 132 additions and 106 deletions
|
@ -21,12 +21,16 @@
|
||||||
|
|
||||||
#include "gruvin9x.h"
|
#include "gruvin9x.h"
|
||||||
|
|
||||||
#ifndef SIMU
|
|
||||||
|
|
||||||
uint16_t eeprom_pointer;
|
uint16_t eeprom_pointer;
|
||||||
const char* eeprom_buffer_data;
|
const char* eeprom_buffer_data;
|
||||||
volatile int8_t eeprom_buffer_size = 0;
|
volatile int8_t eeprom_buffer_size = 0;
|
||||||
|
|
||||||
|
#ifdef SIMU
|
||||||
|
|
||||||
|
extern void eeprom_write_byte();
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
inline void eeprom_write_byte()
|
inline void eeprom_write_byte()
|
||||||
{
|
{
|
||||||
EEAR = eeprom_pointer;
|
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);
|
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_data = (const char*)i_pointer_ram;
|
||||||
eeprom_buffer_size = size+1;
|
eeprom_buffer_size = size+1;
|
||||||
|
|
||||||
#if defined (PCBV3)
|
#ifdef SIMU
|
||||||
|
sem_post(&eeprom_write_sem);
|
||||||
|
#elif defined (PCBV3)
|
||||||
EECR |= (1<<EERIE);
|
EECR |= (1<<EERIE);
|
||||||
#else
|
#else
|
||||||
EECR |= (1<<EERIE);
|
EECR |= (1<<EERIE);
|
||||||
|
@ -75,9 +83,6 @@ void eeWriteBlockCmp(const void *i_pointer_ram, void *i_pointer_eeprom, size_t s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static uint8_t s_evt;
|
static uint8_t s_evt;
|
||||||
void putEvent(uint8_t evt)
|
void putEvent(uint8_t evt)
|
||||||
{
|
{
|
||||||
|
|
37
src/file.cpp
37
src/file.cpp
|
@ -46,51 +46,48 @@ struct EeFs{
|
||||||
}__attribute__((packed)) eeFs;
|
}__attribute__((packed)) eeFs;
|
||||||
|
|
||||||
|
|
||||||
static uint8_t EeFsRead(uint8_t blk,uint8_t ofs)
|
static uint8_t EeFsRead(uint8_t blk, uint8_t ofs)
|
||||||
{
|
{
|
||||||
uint8_t ret;
|
uint8_t ret;
|
||||||
eeprom_read_block(&ret,(const void*)(blk*BS+ofs),1);
|
eeprom_read_block(&ret, (const void*)(blk*BS+ofs), 1);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EeFsWrite(uint8_t blk, uint8_t ofs, uint8_t val)
|
|
||||||
{
|
|
||||||
eeWriteBlockCmp(&val, (void*)(blk*BS+ofs), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t EeFsGetLink(uint8_t blk)
|
static uint8_t EeFsGetLink(uint8_t blk)
|
||||||
{
|
{
|
||||||
return EeFsRead( blk,0);
|
return EeFsRead(blk, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EeFsSetLink(uint8_t blk,uint8_t val)
|
static void EeFsSetLink(uint8_t blk, uint8_t val)
|
||||||
{
|
{
|
||||||
EeFsWrite( blk,0,val);
|
static uint8_t s_link; // we write asynchronously, then nothing on the stack!
|
||||||
|
s_link = val;
|
||||||
|
eeWriteBlockCmp(&s_link, (blk*BS), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t EeFsGetDat(uint8_t blk,uint8_t ofs)
|
static uint8_t EeFsGetDat(uint8_t blk,uint8_t ofs)
|
||||||
{
|
{
|
||||||
return EeFsRead( blk,ofs+1);
|
return EeFsRead(blk, ofs+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EeFsSetDat(uint8_t blk,uint8_t ofs,uint8_t*buf,uint8_t len)
|
static void EeFsSetDat(uint8_t blk,uint8_t ofs,uint8_t*buf,uint8_t len)
|
||||||
{
|
{
|
||||||
eeWriteBlockCmp(buf, (void*)(blk*BS+ofs+1), len);
|
eeWriteBlockCmp(buf, blk*BS+ofs+1, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EeFsFlushFreelist()
|
static void EeFsFlushFreelist()
|
||||||
{
|
{
|
||||||
eeWriteBlockCmp(&eeFs.freeList,&((EeFs*)0)->freeList ,sizeof(eeFs.freeList));
|
eeWriteBlockCmp(&eeFs.freeList, offsetof(EeFs, freeList), sizeof(eeFs.freeList));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EeFsFlushDirEnt(uint8_t i_fileId)
|
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()
|
static void EeFsFlush()
|
||||||
{
|
{
|
||||||
eeWriteBlockCmp(&eeFs, 0,sizeof(eeFs));
|
eeWriteBlockCmp(&eeFs, 0, sizeof(eeFs));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t EeFsGetFree()
|
uint16_t EeFsGetFree()
|
||||||
|
@ -337,7 +334,7 @@ void RlcFile::write(uint8_t *buf, uint8_t i_len)
|
||||||
|
|
||||||
void RlcFile::nextWriteStep()
|
void RlcFile::nextWriteStep()
|
||||||
{
|
{
|
||||||
if(!m_currBlk && m_pos==0) {
|
if (!m_currBlk && m_pos==0) {
|
||||||
eeFs.files[FILE_TMP].startBlk = m_currBlk = eeFs.freeList;
|
eeFs.files[FILE_TMP].startBlk = m_currBlk = eeFs.freeList;
|
||||||
if (m_currBlk) {
|
if (m_currBlk) {
|
||||||
eeFs.freeList = EeFsGetLink(m_currBlk);
|
eeFs.freeList = EeFsGetLink(m_currBlk);
|
||||||
|
@ -574,4 +571,12 @@ void RlcFile::flush()
|
||||||
s_sync_write = false;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,16 +95,15 @@ class RlcFile: public EFile
|
||||||
uint8_t m_zeroes;
|
uint8_t m_zeroes;
|
||||||
|
|
||||||
uint8_t m_flags;
|
uint8_t m_flags;
|
||||||
#define WRITE_FIRST_LINK 0x01
|
#define WRITE_FIRST_LINK 0x01
|
||||||
#define WRITE_NEXT_LINK_1 0x02
|
#define WRITE_NEXT_LINK_1 0x02
|
||||||
#define WRITE_NEXT_LINK_2 0x03
|
#define WRITE_NEXT_LINK_2 0x03
|
||||||
#define WRITE_START_STEP 0x10
|
#define WRITE_START_STEP 0x10
|
||||||
#define WRITE_FREE_UNUSED_BLOCKS_STEP1 0x20
|
#define WRITE_FREE_UNUSED_BLOCKS_STEP1 0x20
|
||||||
#define WRITE_FREE_UNUSED_BLOCKS_STEP2 0x30
|
#define WRITE_FREE_UNUSED_BLOCKS_STEP2 0x30
|
||||||
#define WRITE_FINAL_DIRENT_STEP 0x40
|
#define WRITE_FINAL_DIRENT_STEP 0x40
|
||||||
#define WRITE_TMP_DIRENT_STEP 0x50
|
#define WRITE_TMP_DIRENT_STEP 0x50
|
||||||
uint8_t m_write_step;
|
uint8_t m_write_step;
|
||||||
|
|
||||||
uint16_t m_rlc_len;
|
uint16_t m_rlc_len;
|
||||||
uint8_t * m_rlc_buf;
|
uint8_t * m_rlc_buf;
|
||||||
uint8_t m_cur_rlc_len;
|
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?
|
uint16_t readRlc(uint8_t*buf, uint16_t i_len); // TODO should be like writeRlc?
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void DisplayProgressBar();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -34,9 +34,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SIMU
|
#ifdef SIMU
|
||||||
#include "simpgmspace.h"
|
#include "simpgmspace.h"
|
||||||
#define APM
|
|
||||||
#include "stdio.h"
|
|
||||||
#else
|
#else
|
||||||
///opt/cross/avr/include/avr/pgmspace.h
|
///opt/cross/avr/include/avr/pgmspace.h
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
@ -557,7 +555,7 @@ template<class t> 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
|
/// Markiert einen EEPROM-Bereich als dirty. der Bereich wird dann in
|
||||||
/// eeCheck ins EEPROM zurueckgeschrieben.
|
/// 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);
|
void eeDirty(uint8_t msk);
|
||||||
inline void eeFlush() { theFile.flush(); }
|
inline void eeFlush() { theFile.flush(); }
|
||||||
void eeCheck(bool immediately=false);
|
void eeCheck(bool immediately=false);
|
||||||
|
|
|
@ -72,7 +72,7 @@ TEST(outdezNAtt, test_unsigned) {
|
||||||
EXPECT_EQ(memcmp(refBuf, displayBuf, sizeof(displayBuf)), 0) << "Unsigned numbers will be bad displayed";
|
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
|
eepromFile = NULL; // in memory
|
||||||
RlcFile f;
|
RlcFile f;
|
||||||
uint8_t buf[1000];
|
uint8_t buf[1000];
|
||||||
|
@ -80,7 +80,7 @@ TEST(EEPROM, test1) {
|
||||||
|
|
||||||
EeFsFormat();
|
EeFsFormat();
|
||||||
|
|
||||||
for(int i=0; i<10000; i++) {
|
for(int i=0; i<1000; i++) {
|
||||||
int size = rand()%800;
|
int size = rand()%800;
|
||||||
for(int j=0; j<size; j++) {
|
for(int j=0; j<size; j++) {
|
||||||
buf[j] = rand() < (RAND_MAX/10000*i) ? 0 : (j&0xff);
|
buf[j] = rand() < (RAND_MAX/10000*i) ? 0 : (j&0xff);
|
||||||
|
@ -258,6 +258,7 @@ TEST(getSwitch, nullSW) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
InitEepromThread();
|
||||||
::testing::InitGoogleTest(&argc, argv);
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
return RUN_ALL_TESTS();
|
return RUN_ALL_TESTS();
|
||||||
}
|
}
|
||||||
|
|
|
@ -534,4 +534,6 @@ void menuMainView(uint8_t event)
|
||||||
else { // timer2
|
else { // timer2
|
||||||
putsTime(33+FW+2, FH*5, timer2, DBLSIZE, DBLSIZE);
|
putsTime(33+FW+2, FH*5, timer2, DBLSIZE, DBLSIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO here it's too intrusive: theFile.DisplayProgressBar();
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,6 +185,8 @@ bool check(uint8_t event, uint8_t curr, MenuFuncP *menuTab, uint8_t menuTabSize,
|
||||||
DisplayScreenIndex(curr, menuTabSize, attr);
|
DisplayScreenIndex(curr, menuTabSize, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
theFile.DisplayProgressBar();
|
||||||
|
|
||||||
uint8_t maxcol = MAXCOL(m_posVert);
|
uint8_t maxcol = MAXCOL(m_posVert);
|
||||||
switch(event)
|
switch(event)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,11 +19,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
Insert obligatories here
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef menus_h
|
#ifndef menus_h
|
||||||
#define menus_h
|
#define menus_h
|
||||||
|
|
||||||
|
@ -49,8 +44,6 @@ extern uint8_t s_pgOfs;
|
||||||
extern uint8_t s_noHi;
|
extern uint8_t s_noHi;
|
||||||
extern uint8_t s_noScroll;
|
extern uint8_t s_noScroll;
|
||||||
|
|
||||||
// extern int16_t expo(int16_t x, int16_t k);
|
|
||||||
|
|
||||||
void menu_lcd_onoff(uint8_t x, uint8_t y, uint8_t value, uint8_t mode);
|
void menu_lcd_onoff(uint8_t x, uint8_t y, uint8_t value, uint8_t mode);
|
||||||
void menu_lcd_HYPHINV(uint8_t x, uint8_t y, uint8_t value, uint8_t mode);
|
void menu_lcd_HYPHINV(uint8_t x, uint8_t y, uint8_t value, uint8_t mode);
|
||||||
|
|
||||||
|
|
|
@ -97,15 +97,27 @@ uint8_t s_warning_info_len;
|
||||||
// uint8_t s_warning_info_att not needed now
|
// uint8_t s_warning_info_att not needed now
|
||||||
uint8_t s_confirmation = 0;
|
uint8_t s_confirmation = 0;
|
||||||
|
|
||||||
|
void displayBox()
|
||||||
|
{
|
||||||
|
lcd_filled_rect(10, 16, 108, 40, WHITE);
|
||||||
|
lcd_rect(10, 16, 108, 40);
|
||||||
|
lcd_puts_P(16, 3*FH, s_warning);
|
||||||
|
// could be a place for a s_warning_info
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayPopup(const prog_char * pstr)
|
||||||
|
{
|
||||||
|
s_warning = pstr;
|
||||||
|
displayBox();
|
||||||
|
s_warning = 0;
|
||||||
|
refreshDiplay();
|
||||||
|
}
|
||||||
|
|
||||||
void displayWarning(uint8_t event)
|
void displayWarning(uint8_t event)
|
||||||
{
|
{
|
||||||
if (s_warning) {
|
if (s_warning) {
|
||||||
lcd_filled_rect(10, 16, 108, 40, WHITE);
|
displayBox();
|
||||||
lcd_rect(10, 16, 108, 40);
|
|
||||||
lcd_puts_P(16, 3*FH, s_warning);
|
|
||||||
// could be a place for a s_warning_info
|
|
||||||
lcd_puts_P(16, 5*FH, PSTR("[EXIT]"));
|
lcd_puts_P(16, 5*FH, PSTR("[EXIT]"));
|
||||||
|
|
||||||
switch(event) {
|
switch(event) {
|
||||||
case EVT_KEY_FIRST(KEY_EXIT):
|
case EVT_KEY_FIRST(KEY_EXIT):
|
||||||
killEvents(event);
|
killEvents(event);
|
||||||
|
@ -118,9 +130,7 @@ void displayWarning(uint8_t event)
|
||||||
void displayConfirmation(uint8_t event)
|
void displayConfirmation(uint8_t event)
|
||||||
{
|
{
|
||||||
s_confirmation = false;
|
s_confirmation = false;
|
||||||
lcd_filled_rect(10, 16, 108, 40, WHITE);
|
displayBox();
|
||||||
lcd_rect(10, 16, 108, 40);
|
|
||||||
lcd_puts_P(16, 3*FH, s_warning);
|
|
||||||
if (s_warning_info)
|
if (s_warning_info)
|
||||||
lcd_putsnAtt(16, 4*FH, s_warning_info, s_warning_info_len, ZCHAR);
|
lcd_putsnAtt(16, 4*FH, s_warning_info, s_warning_info_len, ZCHAR);
|
||||||
lcd_puts_P(16, 5*FH, PSTR("[MENU] [EXIT]"));
|
lcd_puts_P(16, 5*FH, PSTR("[MENU] [EXIT]"));
|
||||||
|
@ -201,6 +211,7 @@ void menuProcModelSelect(uint8_t event)
|
||||||
case EVT_KEY_LONG(KEY_MENU):
|
case EVT_KEY_LONG(KEY_MENU):
|
||||||
case EVT_KEY_BREAK(KEY_MENU):
|
case EVT_KEY_BREAK(KEY_MENU):
|
||||||
if (s_copyMode && (s_copyTgtOfs || s_copySrcRow>=0)) {
|
if (s_copyMode && (s_copyTgtOfs || s_copySrcRow>=0)) {
|
||||||
|
displayPopup(s_copyMode==COPY_MODE ? PSTR("Copying model...") : PSTR("Moving model..."));
|
||||||
eeCheck(true); // force writing of current model data before this is changed
|
eeCheck(true); // force writing of current model data before this is changed
|
||||||
|
|
||||||
uint8_t cur = (16 + sub + s_copyTgtOfs) % 16;
|
uint8_t cur = (16 + sub + s_copyTgtOfs) % 16;
|
||||||
|
@ -231,6 +242,7 @@ void menuProcModelSelect(uint8_t event)
|
||||||
s_copyTgtOfs = 0;
|
s_copyTgtOfs = 0;
|
||||||
}
|
}
|
||||||
else if (_event == EVT_KEY_LONG(KEY_MENU)) {
|
else if (_event == EVT_KEY_LONG(KEY_MENU)) {
|
||||||
|
displayPopup(PSTR("Loading model..."));
|
||||||
eeCheck(true); // force writing of current model data before this is changed
|
eeCheck(true); // force writing of current model data before this is changed
|
||||||
if (g_eeGeneral.currModel != sub) {
|
if (g_eeGeneral.currModel != sub) {
|
||||||
g_eeGeneral.currModel = sub;
|
g_eeGeneral.currModel = sub;
|
||||||
|
@ -238,6 +250,7 @@ void menuProcModelSelect(uint8_t event)
|
||||||
eeLoadModel(sub);
|
eeLoadModel(sub);
|
||||||
}
|
}
|
||||||
killEvents(event);
|
killEvents(event);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if (EFile::exists(FILE_MODEL(sub))) {
|
else if (EFile::exists(FILE_MODEL(sub))) {
|
||||||
s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE);
|
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)
|
#define PARAM_OFS (9*FW+2)
|
||||||
void menuProcModel(uint8_t event)
|
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});
|
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 sub = m_posVert;
|
||||||
uint8_t y = 1*FH;
|
uint8_t y = 1*FH;
|
||||||
|
|
||||||
lcd_outdezNAtt(7*FW,0,g_eeGeneral.currModel+1,INVERS+LEADING0,2);
|
|
||||||
|
|
||||||
uint8_t subN = 1;
|
uint8_t subN = 1;
|
||||||
if(s_pgOfs<subN) {
|
if(s_pgOfs<subN) {
|
||||||
lcd_puts_P(0*FW, y, PSTR("Name"));
|
lcd_puts_P(0*FW, y, PSTR("Name"));
|
||||||
|
@ -530,12 +542,12 @@ static uint8_t s_currIdx;
|
||||||
|
|
||||||
void menuProcPhaseOne(uint8_t event)
|
void menuProcPhaseOne(uint8_t event)
|
||||||
{
|
{
|
||||||
SUBMENU("EDIT FLIGHT PHASE", (s_currIdx==0 ? 3 : 5), {6, 0, 3/*, 0, 0*/});
|
PhaseData *phase = phaseaddress(s_currIdx);
|
||||||
|
putsFlightPhase(13*FW, 0, s_currIdx+1, 0);
|
||||||
|
|
||||||
|
SUBMENU("FLIGHT PHASE", (s_currIdx==0 ? 3 : 5), {6, 0, 3/*, 0, 0*/});
|
||||||
|
|
||||||
int8_t sub = m_posVert;
|
int8_t sub = m_posVert;
|
||||||
PhaseData *phase = phaseaddress(s_currIdx);
|
|
||||||
|
|
||||||
putsFlightPhase(18*FW, 0, s_currIdx+1, 0);
|
|
||||||
|
|
||||||
for (uint8_t i=0, k=0, y=2*FH; i<5; i++, k++, y+=FH) {
|
for (uint8_t i=0, k=0, y=2*FH; i<5; i++, k++, y+=FH) {
|
||||||
if (s_currIdx == 0 && i==1) i = 3;
|
if (s_currIdx == 0 && i==1) i = 3;
|
||||||
|
@ -733,6 +745,7 @@ void menuProcCurveOne(uint8_t event)
|
||||||
|
|
||||||
TITLE("CURVE");
|
TITLE("CURVE");
|
||||||
lcd_outdezAtt(5*FW+1, 0, s_curveChan+1, INVERS|LEFT);
|
lcd_outdezAtt(5*FW+1, 0, s_curveChan+1, INVERS|LEFT);
|
||||||
|
theFile.DisplayProgressBar();
|
||||||
|
|
||||||
if (s_curveChan >= MAX_CURVE5) {
|
if (s_curveChan >= MAX_CURVE5) {
|
||||||
points = 9;
|
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)
|
void menuProcExpoOne(uint8_t event)
|
||||||
{
|
{
|
||||||
SIMPLE_SUBMENU("DR/EXPO", 6);
|
|
||||||
|
|
||||||
ExpoData *ed = expoaddress(s_currIdx);
|
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;
|
int8_t sub = m_posVert;
|
||||||
|
|
||||||
|
@ -1077,10 +1089,11 @@ void menuProcExpoOne(uint8_t event)
|
||||||
|
|
||||||
void menuProcMixOne(uint8_t event)
|
void menuProcMixOne(uint8_t event)
|
||||||
{
|
{
|
||||||
SIMPLE_SUBMENU_NOTITLE(13);
|
|
||||||
TITLEP(s_currCh ? PSTR("INSERT MIX ") : PSTR("EDIT MIX "));
|
TITLEP(s_currCh ? PSTR("INSERT MIX ") : PSTR("EDIT MIX "));
|
||||||
MixData *md2 = mixaddress(s_currIdx) ;
|
MixData *md2 = mixaddress(s_currIdx) ;
|
||||||
putsChn(lcd_lastPos+1*FW,0,md2->destCh,0);
|
putsChn(lcd_lastPos+1*FW,0,md2->destCh,0);
|
||||||
|
SIMPLE_SUBMENU_NOTITLE(13);
|
||||||
|
|
||||||
int8_t sub = m_posVert;
|
int8_t sub = m_posVert;
|
||||||
|
|
||||||
for(uint8_t k=0; k<7; k++)
|
for(uint8_t k=0; k<7; k++)
|
||||||
|
@ -1245,8 +1258,10 @@ void menuProcExpoMix(uint8_t expo, uint8_t __event)
|
||||||
event -= KEY_EXIT;
|
event -= KEY_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMPLE_MENU_NOTITLE(menuTabModel, expo ? e_ExposAll : e_MixAll, s_maxLines);
|
|
||||||
TITLEP(expo ? PSTR("DR/EXPO") : PSTR("MIXER"));
|
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;
|
uint8_t sub = m_posVert;
|
||||||
|
|
||||||
|
@ -1351,9 +1366,6 @@ void menuProcExpoMix(uint8_t expo, uint8_t __event)
|
||||||
break;
|
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;
|
s_currCh = 0;
|
||||||
uint8_t cur = 1;
|
uint8_t cur = 1;
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
|
|
|
@ -289,7 +289,7 @@ void eeLoadModel(uint8_t id)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (sz != sizeof(ModelData)) {
|
if (sz < 730/*sizeof(last compatible eeprom)*/) {
|
||||||
// alert("Error Loading Model");
|
// alert("Error Loading Model");
|
||||||
modelDefault(id);
|
modelDefault(id);
|
||||||
eeCheck(true);
|
eeCheck(true);
|
||||||
|
|
|
@ -30,51 +30,52 @@
|
||||||
volatile unsigned char pinb=0, pinc=0xff, pind, pine=0xff, ping=0xff;
|
volatile unsigned char pinb=0, pinc=0xff, pind, pine=0xff, ping=0xff;
|
||||||
unsigned char portb, dummyport;
|
unsigned char portb, dummyport;
|
||||||
const char *eepromFile = "eeprom.bin";
|
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];
|
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
|
while (!sem_wait(&eeprom_write_sem)) {
|
||||||
printf(" eeWriteBlockCmp(%d %d)", size, (int)pointer_eeprom);
|
|
||||||
for(uint8_t i=0; i<size; i++)
|
|
||||||
printf(" %02X", ((const char*)i_pointer_ram)[i]);
|
|
||||||
printf("\n");fflush(stdout);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (eepromFile) {
|
FILE *fp = NULL;
|
||||||
FILE *fp = fopen(eepromFile, "r+");
|
|
||||||
long ofs = (long) pointer_eeprom;
|
if (eepromFile) {
|
||||||
const char* pointer_ram= (const char*)i_pointer_ram;
|
fp = fopen(eepromFile, "r+");
|
||||||
//printf("eeWr p=%10p blk%3d ofs=%2d l=%d",pointer_ram,
|
assert(fp);
|
||||||
// (int)pointer_eeprom/16,
|
}
|
||||||
// (int)pointer_eeprom%16,
|
|
||||||
// (int)size);
|
while (--eeprom_buffer_size) {
|
||||||
while(size) {
|
assert(eeprom_buffer_size > 0);
|
||||||
if(fseek(fp, ofs , SEEK_SET)==-1) perror("error in seek");
|
if (fp) {
|
||||||
char buf[1];
|
if (fseek(fp, eeprom_pointer, SEEK_SET) == -1)
|
||||||
if (fread(buf, 1, 1, fp) != 1) perror("error in read");
|
perror("error in fseek");
|
||||||
|
if (fwrite(eeprom_buffer_data, 1, 1, fp) != 1)
|
||||||
if (buf[0] != pointer_ram[0]){
|
perror("error in fwrite");
|
||||||
//printf("X");
|
usleep(5000/*5ms*/);
|
||||||
g_tmr10ms++;
|
}
|
||||||
if(fseek(fp, ofs , SEEK_SET)==-1) perror("error in seek");
|
else {
|
||||||
fwrite(pointer_ram, 1, 1,fp);
|
memcpy(&eeprom[eeprom_pointer], eeprom_buffer_data, 1);
|
||||||
}
|
}
|
||||||
else{
|
eeprom_pointer++;
|
||||||
//printf(".");
|
eeprom_buffer_data++;
|
||||||
}
|
|
||||||
|
if (fp && eeprom_buffer_size == 1) {
|
||||||
size--;
|
fclose(fp);
|
||||||
ofs++;
|
}
|
||||||
(const char*)pointer_ram++;
|
|
||||||
}
|
}
|
||||||
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,
|
void eeprom_read_block (void *pointer_ram,
|
||||||
|
|
|
@ -22,6 +22,10 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
|
||||||
|
#define APM
|
||||||
|
|
||||||
typedef unsigned char prog_uchar;
|
typedef unsigned char prog_uchar;
|
||||||
typedef const char prog_char;
|
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 int16_t prog_int16_t;
|
||||||
typedef const int8_t prog_int8_t;
|
typedef const int8_t prog_int8_t;
|
||||||
|
|
||||||
|
extern sem_t eeprom_write_sem;
|
||||||
|
|
||||||
#define PROGMEM
|
#define PROGMEM
|
||||||
#define pgm_read_byte(address_short) (*(uint8_t*)(address_short))
|
#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 volatile unsigned char pinb,pinc,pind,pine,ping;
|
||||||
extern unsigned char portb,dummyport;
|
extern unsigned char portb,dummyport;
|
||||||
|
|
||||||
|
void InitEepromThread();
|
||||||
|
|
||||||
extern const char *eepromFile;
|
extern const char *eepromFile;
|
||||||
void eeprom_read_block (void *pointer_ram,
|
void eeprom_read_block (void *pointer_ram,
|
||||||
const void *pointer_eeprom,
|
const void *pointer_eeprom,
|
||||||
|
|
|
@ -363,7 +363,6 @@ void *init_function(void *) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
long Gruvin9xSim::onChore(FXObject*,FXSelector,void*)
|
long Gruvin9xSim::onChore(FXObject*,FXSelector,void*)
|
||||||
{
|
{
|
||||||
pthread_t pid;
|
pthread_t pid;
|
||||||
|
@ -396,7 +395,9 @@ int main(int argc,char **argv)
|
||||||
if(argc>=2){
|
if(argc>=2){
|
||||||
eepromFile = argv[1];
|
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.
|
// Each FOX GUI program needs one, and only one, application object.
|
||||||
// The application objects coordinates some common stuff shared between
|
// The application objects coordinates some common stuff shared between
|
||||||
|
|
|
@ -73,7 +73,7 @@ void menuProcStatistic2(uint8_t event)
|
||||||
switch(event)
|
switch(event)
|
||||||
{
|
{
|
||||||
case EVT_KEY_FIRST(KEY_MENU):
|
case EVT_KEY_FIRST(KEY_MENU):
|
||||||
g_tmr1Latency_min = 0x7ff;
|
g_tmr1Latency_min = 0xff;
|
||||||
g_tmr1Latency_max = 0;
|
g_tmr1Latency_max = 0;
|
||||||
g_timeMain = 0;
|
g_timeMain = 0;
|
||||||
// g_time_per10 = 0;
|
// g_time_per10 = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue