Issues with current model during copy / move operations in MODELSEL menu.
This commit is contained in:
+1
-3
@@ -80,7 +80,7 @@ DISPLAY_USER_DATA = NO
|
||||
PXX = NO
|
||||
|
||||
# DSM2 (Spektrum) protocol
|
||||
DSM2 = YES
|
||||
DSM2 = NO
|
||||
|
||||
# Silver protocol
|
||||
SILVER = NO
|
||||
@@ -178,8 +178,6 @@ CPPDEFS = -DF_CPU=$(F_CPU)UL
|
||||
# NOTE: PCB version now overrides all the earlier individual settings
|
||||
# These individual settings work only for PCB=STD
|
||||
|
||||
CPPDEFS += -DEEPROM_ASYNC_WRITE
|
||||
|
||||
ifeq ($(PCB), STD)
|
||||
# STD PCB, so ...
|
||||
|
||||
|
||||
+4
-46
@@ -23,8 +23,6 @@
|
||||
|
||||
#ifndef SIMU
|
||||
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
|
||||
uint16_t eeprom_pointer;
|
||||
const char* eeprom_buffer_data;
|
||||
volatile int8_t eeprom_buffer_size = 0;
|
||||
@@ -77,50 +75,6 @@ void eeWriteBlockCmp(const void *i_pointer_ram, void *i_pointer_eeprom, size_t s
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
///opt/cross/avr/include/avr/eeprom.h
|
||||
static inline void __attribute__ ((always_inline))
|
||||
eeprom_write_byte_cmp (uint8_t dat, uint16_t pointer_eeprom)
|
||||
{
|
||||
//see /home/thus/work/avr/avrsdk4/avr-libc-1.4.4/libc/misc/eeprom.S:98 143
|
||||
#if defined (PCBV3)
|
||||
while(EECR & (1<<EEPE))
|
||||
#else
|
||||
while(EECR & (1<<EEWE))
|
||||
#endif
|
||||
;
|
||||
EEAR = pointer_eeprom;
|
||||
|
||||
EECR |= 1<<EERE;
|
||||
if(dat == EEDR) return;
|
||||
|
||||
EEDR = dat;
|
||||
uint8_t flags=SREG;
|
||||
cli();
|
||||
#if defined (PCBV3)
|
||||
EECR |= 1<<EEMPE;
|
||||
EECR |= 1<<EEPE;
|
||||
#else
|
||||
EECR |= 1<<EEMWE;
|
||||
EECR |= 1<<EEWE;
|
||||
#endif
|
||||
SREG = flags;
|
||||
sei();
|
||||
}
|
||||
|
||||
void eeWriteBlockCmp(const void *i_pointer_ram, void *i_pointer_eeprom, size_t size)
|
||||
{
|
||||
const char* pointer_ram = (const char*)i_pointer_ram;
|
||||
uint16_t pointer_eeprom = (uint16_t)i_pointer_eeprom;
|
||||
while(size){
|
||||
eeprom_write_byte_cmp(*pointer_ram++,pointer_eeprom++);
|
||||
size--;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -255,6 +209,10 @@ bool keyState(EnumKeys enuk)
|
||||
|
||||
case SW_Trainer: return PINB & (1<<INP_B_Trainer);
|
||||
|
||||
case SW_RE1: return (~PIND & 0b00100000);
|
||||
|
||||
case SW_RE2: return (~PIND & 0b00010000);
|
||||
|
||||
default:;
|
||||
}
|
||||
#else
|
||||
|
||||
+121
-231
@@ -24,9 +24,7 @@
|
||||
#include "string.h"
|
||||
|
||||
uint8_t s_write_err = 0; // error reasons
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
uint8_t s_sync_write = false;
|
||||
#endif
|
||||
|
||||
#define RESV 64 //reserv for eeprom header with directory (eeFs)
|
||||
#define FIRSTBLK (RESV/BS)
|
||||
@@ -48,32 +46,48 @@ struct 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;
|
||||
eeprom_read_block(&ret,(const void*)(blk*BS+ofs),1);
|
||||
return ret;
|
||||
}
|
||||
static void EeFsWrite(uint8_t blk,uint8_t ofs,uint8_t val){
|
||||
|
||||
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);
|
||||
}
|
||||
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 EeFsGetDat(uint8_t blk,uint8_t ofs){
|
||||
|
||||
static uint8_t EeFsGetDat(uint8_t blk,uint8_t ofs)
|
||||
{
|
||||
return EeFsRead( blk,ofs+1);
|
||||
}
|
||||
static void EeFsSetDat(uint8_t blk,uint8_t ofs,uint8_t*buf,uint8_t len){
|
||||
//EeFsWrite( blk,ofs+1,val);
|
||||
|
||||
static void EeFsSetDat(uint8_t blk,uint8_t ofs,uint8_t*buf,uint8_t len)
|
||||
{
|
||||
eeWriteBlockCmp(buf, (void*)(blk*BS+ofs+1), len);
|
||||
}
|
||||
|
||||
static void EeFsFlushFreelist()
|
||||
{
|
||||
eeWriteBlockCmp(&eeFs.freeList,&((EeFs*)0)->freeList ,sizeof(eeFs.freeList));
|
||||
}
|
||||
|
||||
static void EeFsFlushDirEnt(uint8_t i_fileId)
|
||||
{
|
||||
eeWriteBlockCmp(&eeFs.files[i_fileId], &((EeFs*)0)->files[i_fileId], sizeof(DirEnt));
|
||||
}
|
||||
|
||||
static void EeFsFlush()
|
||||
{
|
||||
eeWriteBlockCmp(&eeFs, 0,sizeof(eeFs));
|
||||
@@ -90,7 +104,6 @@ uint16_t EeFsGetFree()
|
||||
return ret;
|
||||
}
|
||||
|
||||
// #ifndef EEPROM_ASYNC_WRITE TODO because duplicate code
|
||||
static void EeFsFree(uint8_t blk){///free one or more blocks
|
||||
uint8_t i = blk;
|
||||
while( EeFsGetLink(i)) i = EeFsGetLink(i);
|
||||
@@ -98,25 +111,10 @@ static void EeFsFree(uint8_t blk){///free one or more blocks
|
||||
eeFs.freeList = blk; //chain in front
|
||||
EeFsFlushFreelist();
|
||||
}
|
||||
// #endif
|
||||
|
||||
#ifndef EEPROM_ASYNC_WRITE
|
||||
static uint8_t EeFsAlloc(){ ///alloc one block from freelist
|
||||
uint8_t ret=eeFs.freeList;
|
||||
if(ret){
|
||||
eeFs.freeList = EeFsGetLink(ret);
|
||||
EeFsFlushFreelist();
|
||||
EeFsSetLink(ret,0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int8_t EeFsck()
|
||||
{
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
s_sync_write = true;
|
||||
#endif
|
||||
|
||||
uint8_t *bufp;
|
||||
static uint8_t buffer[BLOCKS];
|
||||
@@ -129,45 +127,45 @@ int8_t EeFsck()
|
||||
uint8_t *startP = i==MAXFILES ? &eeFs.freeList : &eeFs.files[i].startBlk;
|
||||
uint8_t lastBlk = 0;
|
||||
blk = *startP;
|
||||
while(blk){
|
||||
if( ( blk < FIRSTBLK ) //goto err_1; //bad blk index
|
||||
|| (blk >= BLOCKS ) //goto err_2; //bad blk index
|
||||
|| (bufp[blk] ))//goto err_3; //blk double usage
|
||||
while (blk) {
|
||||
if (blk < FIRSTBLK || // bad blk index
|
||||
blk >= BLOCKS || // bad blk index
|
||||
bufp[blk]) // blk double usage
|
||||
{
|
||||
if(lastBlk){
|
||||
EeFsSetLink(lastBlk,0);
|
||||
}else{
|
||||
*startP = 0; //interrupt chain at startpos
|
||||
if (lastBlk) {
|
||||
EeFsSetLink(lastBlk, 0);
|
||||
}
|
||||
else {
|
||||
*startP = 0; // interrupt chain at startpos
|
||||
EeFsFlush();
|
||||
}
|
||||
blk=0; //abort
|
||||
}else{
|
||||
blk = 0; // abort
|
||||
}
|
||||
else {
|
||||
bufp[blk] = i+1;
|
||||
lastBlk = blk;
|
||||
blk = EeFsGetLink(blk);
|
||||
}
|
||||
}
|
||||
}
|
||||
for(blk = FIRSTBLK; blk < BLOCKS; blk++){
|
||||
if(bufp[blk]==0) { //goto err_4; //unused block
|
||||
EeFsSetLink(blk,eeFs.freeList);
|
||||
eeFs.freeList = blk; //chain in front
|
||||
for (blk=FIRSTBLK; blk<BLOCKS; blk++) {
|
||||
if (!bufp[blk]) { // unused block
|
||||
EeFsSetLink(blk, eeFs.freeList);
|
||||
eeFs.freeList = blk; // chain in front
|
||||
EeFsFlushFreelist();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
s_sync_write = false;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EeFsFormat()
|
||||
{
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
s_sync_write = true;
|
||||
#endif
|
||||
if(sizeof(eeFs) != RESV){
|
||||
|
||||
if (sizeof(eeFs) != RESV){
|
||||
extern void eeprom_RESV_mismatch();
|
||||
eeprom_RESV_mismatch();
|
||||
}
|
||||
@@ -180,14 +178,14 @@ void EeFsFormat()
|
||||
EeFsSetLink(BLOCKS-1, 0);
|
||||
eeFs.freeList = FIRSTBLK;
|
||||
EeFsFlush();
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
|
||||
s_sync_write = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool EeFsOpen()
|
||||
{
|
||||
eeprom_read_block(&eeFs,0,sizeof(eeFs));
|
||||
|
||||
#ifdef SIMU
|
||||
if(eeFs.version != EEFS_VERS) printf("bad eeFs.version\n");
|
||||
if(eeFs.mySize != sizeof(eeFs)) printf("bad eeFs.mySize\n");
|
||||
@@ -202,39 +200,41 @@ bool EFile::exists(uint8_t i_fileId)
|
||||
}
|
||||
|
||||
/*
|
||||
* swap two files in eeprom
|
||||
* called in sync AND async mode as it is a single write operation
|
||||
* Swap two files in eeprom
|
||||
*/
|
||||
void EFile::swap(uint8_t i_fileId1, uint8_t i_fileId2)
|
||||
{
|
||||
DirEnt tmp = eeFs.files[i_fileId1];
|
||||
eeFs.files[i_fileId1] = eeFs.files[i_fileId2];
|
||||
eeFs.files[i_fileId2] = tmp;
|
||||
EeFsFlush();
|
||||
s_sync_write = true;
|
||||
EeFsFlushDirEnt(i_fileId1);
|
||||
EeFsFlushDirEnt(i_fileId2);
|
||||
s_sync_write = false;
|
||||
}
|
||||
|
||||
void EFile::rm(uint8_t i_fileId)
|
||||
{
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
s_sync_write = true;
|
||||
#endif
|
||||
uint8_t i = eeFs.files[i_fileId].startBlk;
|
||||
memset(&eeFs.files[i_fileId], 0, sizeof(eeFs.files[i_fileId]));
|
||||
EeFsFlush(); //chained out
|
||||
|
||||
if(i) EeFsFree( i ); //chain in
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
s_sync_write = true;
|
||||
EeFsFlushDirEnt(i_fileId);
|
||||
if (i) EeFsFree(i); //chain in
|
||||
s_sync_write = false;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
uint16_t EFile::size(){
|
||||
uint16_t EFile::size()
|
||||
{
|
||||
return eeFs.files[m_fileId].size;
|
||||
}
|
||||
|
||||
|
||||
// G: Open file ID for reading. Return the file's type
|
||||
void EFile::openRd(uint8_t i_fileId){
|
||||
/*
|
||||
* Open file i_fileId for reading.
|
||||
* Return the file's type
|
||||
*/
|
||||
void EFile::openRd(uint8_t i_fileId)
|
||||
{
|
||||
m_fileId = i_fileId;
|
||||
m_pos = 0;
|
||||
m_currBlk = eeFs.files[m_fileId].startBlk;
|
||||
@@ -249,7 +249,8 @@ void RlcFile::openRlc(uint8_t i_fileId)
|
||||
m_bRlc = 0;
|
||||
}
|
||||
|
||||
uint8_t EFile::read(uint8_t*buf,uint16_t i_len){
|
||||
uint8_t EFile::read(uint8_t*buf,uint16_t i_len)
|
||||
{
|
||||
uint16_t len = eeFs.files[m_fileId].size - m_pos;
|
||||
if(len < i_len) i_len = len;
|
||||
len = i_len;
|
||||
@@ -267,7 +268,9 @@ uint8_t EFile::read(uint8_t*buf,uint16_t i_len){
|
||||
return i_len - len;
|
||||
}
|
||||
|
||||
// G: Read runlength (RLE) compressed bytes into buf.
|
||||
/*
|
||||
* Read runlength (RLE) compressed bytes into buf.
|
||||
*/
|
||||
#ifdef TRANSLATIONS
|
||||
uint16_t RlcFile::readRlc12(uint8_t*buf,uint16_t i_len, bool rlc2)
|
||||
#else
|
||||
@@ -316,8 +319,6 @@ uint16_t RlcFile::readRlc(uint8_t*buf,uint16_t i_len)
|
||||
return i;
|
||||
}
|
||||
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
|
||||
void RlcFile::write1(uint8_t b)
|
||||
{
|
||||
m_write1_byte = b;
|
||||
@@ -336,18 +337,18 @@ 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);
|
||||
m_write_step = WRITE_START_STEP + WRITE_FIRST_LINK;
|
||||
m_write_step |= WRITE_FIRST_LINK;
|
||||
EeFsFlushFreelist();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (m_write_step == WRITE_START_STEP + WRITE_FIRST_LINK) {
|
||||
m_write_step = WRITE_START_STEP;
|
||||
|
||||
if ((m_write_step & 0x0f) == WRITE_FIRST_LINK) {
|
||||
m_write_step -= WRITE_FIRST_LINK;
|
||||
EeFsSetLink(m_currBlk, 0);
|
||||
return;
|
||||
}
|
||||
@@ -405,59 +406,6 @@ void RlcFile::nextWriteStep()
|
||||
nextRlcWriteStep();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
uint8_t RlcFile::write1(uint8_t b)
|
||||
{
|
||||
return write(&b,1);
|
||||
}
|
||||
|
||||
uint8_t RlcFile::write(uint8_t*buf, uint8_t i_len)
|
||||
{
|
||||
uint8_t len=i_len;
|
||||
if(!m_currBlk && m_pos==0)
|
||||
{
|
||||
eeFs.files[m_fileId].startBlk = m_currBlk = EeFsAlloc();
|
||||
}
|
||||
while(len)
|
||||
{
|
||||
#ifndef SIMU
|
||||
if( (int16_t)(m_stopTime10ms - get_tmr10ms()) < 0)
|
||||
{
|
||||
s_write_err = ERR_TMO;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if(!m_currBlk) {
|
||||
s_write_err = ERR_FULL;
|
||||
break;
|
||||
}
|
||||
if(m_ofs>=(BS-1)){
|
||||
m_ofs=0;
|
||||
if( ! EeFsGetLink(m_currBlk) ){
|
||||
EeFsSetLink(m_currBlk, EeFsAlloc());
|
||||
}
|
||||
m_currBlk = EeFsGetLink(m_currBlk);
|
||||
}
|
||||
if(!m_currBlk) {
|
||||
s_write_err = ERR_FULL;
|
||||
break;
|
||||
}
|
||||
uint8_t l = BS-1-m_ofs; if(l>len) l=len;
|
||||
EeFsSetDat(m_currBlk, m_ofs, buf, l);
|
||||
buf +=l;
|
||||
m_ofs +=l;
|
||||
len -=l;
|
||||
}
|
||||
m_pos += i_len - len;
|
||||
return i_len - len;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
|
||||
void RlcFile::create(uint8_t i_fileId, uint8_t typ, uint8_t sync_write)
|
||||
{
|
||||
// all write operations will be executed on FILE_TMP
|
||||
@@ -468,6 +416,41 @@ void RlcFile::create(uint8_t i_fileId, uint8_t typ, uint8_t sync_write)
|
||||
s_sync_write = sync_write;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy file src to dst
|
||||
*/
|
||||
bool RlcFile::copy(uint8_t i_fileDst, uint8_t i_fileSrc)
|
||||
{
|
||||
EFile theFile2;
|
||||
theFile2.openRd(i_fileSrc);
|
||||
|
||||
create(i_fileDst, FILE_TYP_MODEL/*optimization, only model files are copied. should be eeFs.files[i_fileSrc].typ*/, true);
|
||||
uint8_t buf[15];
|
||||
uint8_t len;
|
||||
while ((len=theFile2.read(buf, 15)))
|
||||
{
|
||||
write(buf, len);
|
||||
if (errno() != 0) {
|
||||
s_sync_write = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t fri=0;
|
||||
if (m_currBlk && (fri=EeFsGetLink(m_currBlk)))
|
||||
EeFsSetLink(m_currBlk, 0);
|
||||
|
||||
eeFs.files[FILE_TMP].size = m_pos;
|
||||
EFile::swap(m_fileId, FILE_TMP);
|
||||
|
||||
if (fri) EeFsFree(fri); //chain in
|
||||
|
||||
assert(!m_write_step);
|
||||
|
||||
s_sync_write = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RlcFile::writeRlc(uint8_t i_fileId, uint8_t typ, uint8_t*buf, uint16_t i_len, uint8_t sync_write)
|
||||
{
|
||||
create(i_fileId, typ, sync_write);
|
||||
@@ -541,7 +524,7 @@ void RlcFile::nextRlcWriteStep()
|
||||
case WRITE_START_STEP:
|
||||
{
|
||||
uint8_t fri=0;
|
||||
eeFs.files[FILE_TMP].size = m_pos;
|
||||
|
||||
if (m_currBlk && ( fri = EeFsGetLink(m_currBlk))) {
|
||||
uint8_t prev_freeList = eeFs.freeList;
|
||||
eeFs.freeList = fri;
|
||||
@@ -552,9 +535,19 @@ void RlcFile::nextRlcWriteStep()
|
||||
}
|
||||
}
|
||||
|
||||
case WRITE_FLUSH_STEP: // TODO could be avoided
|
||||
m_write_step = WRITE_SWAP_STEP;
|
||||
EeFsFlush(); //chained out
|
||||
case WRITE_FINAL_DIRENT_STEP:
|
||||
m_currBlk = eeFs.files[FILE_TMP].startBlk;
|
||||
eeFs.files[FILE_TMP].startBlk = eeFs.files[m_fileId].startBlk;
|
||||
eeFs.files[m_fileId].startBlk = m_currBlk;
|
||||
eeFs.files[m_fileId].size = m_pos;
|
||||
eeFs.files[m_fileId].typ = eeFs.files[FILE_TMP].typ;
|
||||
m_write_step = WRITE_TMP_DIRENT_STEP;
|
||||
EeFsFlushDirEnt(m_fileId);
|
||||
return;
|
||||
|
||||
case WRITE_TMP_DIRENT_STEP:
|
||||
m_write_step = 0;
|
||||
EeFsFlushDirEnt(FILE_TMP);
|
||||
return;
|
||||
|
||||
case WRITE_FREE_UNUSED_BLOCKS_STEP1:
|
||||
@@ -563,13 +556,9 @@ void RlcFile::nextRlcWriteStep()
|
||||
return;
|
||||
|
||||
case WRITE_FREE_UNUSED_BLOCKS_STEP2:
|
||||
m_write_step = WRITE_FLUSH_STEP;
|
||||
m_write_step = WRITE_FINAL_DIRENT_STEP;
|
||||
EeFsFlushFreelist();
|
||||
return;
|
||||
|
||||
case WRITE_SWAP_STEP:
|
||||
m_write_step = 0;
|
||||
EFile::swap(m_fileId, FILE_TMP);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -585,103 +574,4 @@ void RlcFile::flush()
|
||||
s_sync_write = false;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void RlcFile::create(uint8_t i_fileId, uint8_t typ, uint16_t maxTme10ms)
|
||||
{
|
||||
openRlc(i_fileId); //internal use
|
||||
eeFs.files[i_fileId].typ = typ;
|
||||
eeFs.files[i_fileId].size = 0;
|
||||
m_stopTime10ms = get_tmr10ms() + maxTme10ms;
|
||||
}
|
||||
|
||||
// G: Write runlength (RLE) compressed bytes
|
||||
uint16_t RlcFile::writeRlc(uint8_t i_fileId, uint8_t typ,uint8_t*buf,uint16_t i_len, uint8_t maxTme10ms){
|
||||
|
||||
create(i_fileId,typ,maxTme10ms);
|
||||
bool run0 = buf[0] == 0;
|
||||
uint8_t cnt = 1;
|
||||
uint8_t cnt0 = 0;
|
||||
uint16_t i = 0;
|
||||
if(i_len==0) goto close;
|
||||
|
||||
//RLE compression:
|
||||
//rb = read byte
|
||||
//if (rb | 0x80) write rb & 0x7F zeros
|
||||
//else write rb bytes
|
||||
for( i=1; 1 ; i++) // !! laeuft ein byte zu weit !!
|
||||
{
|
||||
bool cur0 = buf[i] == 0;
|
||||
if(cur0 != run0 || cnt==0x3f || (cnt0 && cnt==0xf)|| i==i_len){
|
||||
if(run0){
|
||||
assert(cnt0==0);
|
||||
if(cnt<8 && i!=i_len)
|
||||
cnt0 = cnt; //aufbew fuer spaeter
|
||||
else {
|
||||
if( write1(cnt|0x40)!=1) goto error;//-cnt&0x3f
|
||||
}
|
||||
}else{
|
||||
if(cnt0){
|
||||
if( write1(0x80 | (cnt0<<4) | cnt)!=1) goto error;//-cnt0xx-cnt
|
||||
cnt0 = 0;
|
||||
}else{
|
||||
if( write1(cnt) !=1) goto error;//-cnt
|
||||
}
|
||||
uint8_t ret=write(&buf[i-cnt],cnt);
|
||||
if( ret !=cnt) { cnt-=ret; goto error;}//-cnt
|
||||
}
|
||||
cnt=0;
|
||||
if(i==i_len) break;
|
||||
run0 = cur0;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
if(0){
|
||||
error:
|
||||
i-=cnt+cnt0;
|
||||
#ifdef SIMU
|
||||
switch(s_write_err){
|
||||
default:
|
||||
case ERR_NONE:
|
||||
assert(!"missing errno");
|
||||
break;
|
||||
case ERR_FULL:
|
||||
printf("ERROR filesystem overflow! written: %d missing: %d\n",i,i_len-i);
|
||||
break;
|
||||
case ERR_TMO:
|
||||
printf("ERROR filesystem write timeout %d 0ms\n",(int16_t)(m_stopTime10ms - g_tmr10ms));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
close:
|
||||
close();
|
||||
return i;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// G: Close file and truncate at this blk. Add any remaining blocks to freeList chain
|
||||
void RlcFile::close()
|
||||
{
|
||||
uint8_t fri=0;
|
||||
|
||||
if(m_currBlk && ( fri = EeFsGetLink(m_currBlk))) EeFsSetLink(m_currBlk, 0);
|
||||
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
eeFs.files[FILE_TMP].size = m_pos;
|
||||
EFile::swap(m_fileId, FILE_TMP);
|
||||
#else
|
||||
eeFs.files[m_fileId].size = m_pos;
|
||||
EeFsFlush(); //chained out
|
||||
#endif
|
||||
|
||||
if(fri) EeFsFree( fri ); //chain in
|
||||
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
m_write_step = 0;
|
||||
s_sync_write = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
+12
-36
@@ -29,12 +29,15 @@
|
||||
// bs=32 64 blocks verlust link: 64 16files:16*16 256 sum 320
|
||||
//
|
||||
#if defined(PCBV3)
|
||||
#define EESIZE 4096
|
||||
#define BS 32
|
||||
// 4096 - 16 bytes to give 255 blocks, since we can't address 256 block in an 8-bit register
|
||||
#define EESIZE 4080
|
||||
#else
|
||||
#define EESIZE 2048
|
||||
#define BS 16
|
||||
#endif
|
||||
#define BS 16
|
||||
|
||||
#define FILE_TYP_GENERAL 1
|
||||
#define FILE_TYP_MODEL 2
|
||||
|
||||
/// fileId of general file
|
||||
#define FILE_GENERAL 0
|
||||
@@ -47,9 +50,7 @@ int8_t EeFsck();
|
||||
void EeFsFormat();
|
||||
uint16_t EeFsGetFree();
|
||||
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
extern volatile int8_t eeprom_buffer_size;
|
||||
#endif
|
||||
|
||||
class EFile
|
||||
{
|
||||
@@ -82,9 +83,6 @@ class EFile
|
||||
|
||||
#define ERR_NONE 0
|
||||
#define ERR_FULL 1
|
||||
#ifndef EEPROM_ASYNC_WRITE
|
||||
#define ERR_TMO 2
|
||||
#endif
|
||||
extern uint8_t s_write_err; // error reasons
|
||||
extern uint8_t s_sync_write;
|
||||
|
||||
@@ -96,7 +94,6 @@ class RlcFile: public EFile
|
||||
uint8_t m_bRlc; // control byte for run length decoder
|
||||
uint8_t m_zeroes;
|
||||
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
uint8_t m_flags;
|
||||
#define WRITE_FIRST_LINK 0x01
|
||||
#define WRITE_NEXT_LINK_1 0x02
|
||||
@@ -104,8 +101,8 @@ class RlcFile: public EFile
|
||||
#define WRITE_START_STEP 0x10
|
||||
#define WRITE_FREE_UNUSED_BLOCKS_STEP1 0x20
|
||||
#define WRITE_FREE_UNUSED_BLOCKS_STEP2 0x30
|
||||
#define WRITE_FLUSH_STEP 0x40
|
||||
#define WRITE_SWAP_STEP 0x50
|
||||
#define WRITE_FINAL_DIRENT_STEP 0x40
|
||||
#define WRITE_TMP_DIRENT_STEP 0x50
|
||||
uint8_t m_write_step;
|
||||
|
||||
uint16_t m_rlc_len;
|
||||
@@ -114,17 +111,16 @@ class RlcFile: public EFile
|
||||
uint8_t m_write1_byte;
|
||||
uint8_t m_write_len;
|
||||
uint8_t * m_write_buf;
|
||||
#else
|
||||
uint16_t m_stopTime10ms; // maximum point of time for writing
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
void openRlc(uint8_t i_fileId);
|
||||
|
||||
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
void create(uint8_t i_fileId, uint8_t typ, uint8_t sync_write);
|
||||
|
||||
///copy contents of i_fileSrc to i_fileDst
|
||||
bool copy(uint8_t i_fileDst, uint8_t i_fileSrc);
|
||||
|
||||
inline bool isWriting() { return m_write_step != 0; }
|
||||
void write(uint8_t*buf, uint8_t i_len);
|
||||
void write1(uint8_t b);
|
||||
@@ -132,26 +128,6 @@ public:
|
||||
void nextRlcWriteStep();
|
||||
void writeRlc(uint8_t i_fileId, uint8_t typ, uint8_t *buf, uint16_t i_len, uint8_t sync_write);
|
||||
void flush();
|
||||
#else
|
||||
/// create a new file with given fileId,
|
||||
/// !!! if this file already exists, then all blocks are reused
|
||||
/// and all contents will be overwritten.
|
||||
/// after writing close has to be called
|
||||
|
||||
void create(uint8_t i_fileId, uint8_t typ, uint16_t maxTme10ms);
|
||||
|
||||
uint8_t write(uint8_t*buf, uint8_t i_len);
|
||||
uint8_t write1(uint8_t b);
|
||||
///open file, write to file and close it.
|
||||
///If file existed before, then contents is overwritten.
|
||||
///If file was larger before, then unused blocks are freed
|
||||
uint16_t writeRlc(uint8_t i_fileId, uint8_t typ,uint8_t*buf,uint16_t i_len, uint8_t maxTme10ms);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* close file and truncate the blockchain if to long.
|
||||
*/
|
||||
void close();
|
||||
|
||||
///read from opened file and decode rlc-coded data
|
||||
#ifdef TRANSLATIONS
|
||||
|
||||
+112
-2
@@ -20,6 +20,8 @@
|
||||
|
||||
#include "gruvin9x.h"
|
||||
#include "frsky.h"
|
||||
#include "ff.h" // TODO
|
||||
// #include <stdlib.h> // TODO
|
||||
|
||||
// Enumerate FrSky packet codes
|
||||
#define LINKPKT 0xfe
|
||||
@@ -76,6 +78,23 @@ void frskyPushValue(uint8_t *&ptr, uint8_t value)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DISPLAY_USER_DATA
|
||||
/*
|
||||
Copies all available bytes (up to max bufsize) from frskyUserData circular
|
||||
buffer into supplied *buffer. Returns number of bytes copied (or zero)
|
||||
*/
|
||||
uint8_t frskyGetUserData(char *buffer, uint8_t bufSize)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
while (!frskyUserData.isEmpty())
|
||||
{
|
||||
buffer[i] = frskyUserData.get();
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FRSKY_HUB
|
||||
int8_t parseTelemHubIndex(uint8_t index)
|
||||
{
|
||||
@@ -133,7 +152,7 @@ void parseTelemHubByte(uint8_t byte)
|
||||
((uint8_t*)&frskyHubData)[structPos+1] = byte;
|
||||
state = TS_IDLE;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
Called from somewhere in the main loop or a low priority interrupt
|
||||
@@ -465,11 +484,102 @@ void FrskyData::set(uint8_t value)
|
||||
max = value;
|
||||
if (!min || min > value)
|
||||
min = value;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO not here!
|
||||
#if defined (PCBV3)
|
||||
char g_logFilename[21]; // "/G9XLOGS/M00_000.TXT\0" max required length = 21
|
||||
// These global so we can close any open file from anywhere
|
||||
FATFS FATFS_Obj;
|
||||
FIL g_oLogFile;
|
||||
#endif
|
||||
|
||||
void resetTelemetry()
|
||||
{
|
||||
memset(frskyTelemetry, 0, sizeof(frskyTelemetry));
|
||||
memset(frskyRSSI, 0, sizeof(frskyRSSI));
|
||||
|
||||
#if defined (PCBV3)
|
||||
|
||||
// Determine and set log file filename
|
||||
|
||||
FRESULT result;
|
||||
|
||||
// close any file left open. E.G. Changing models with log switch still on.
|
||||
if (g_oLogFile.fs) f_close(&g_oLogFile);
|
||||
|
||||
strcpy(g_logFilename, "/G9XLOGS/M00_000.TXT");
|
||||
|
||||
uint8_t num = g_eeGeneral.currModel + 1;
|
||||
char *n = &g_logFilename[11];
|
||||
*n = (char)((num % 10) + '0');
|
||||
*(--n) = (char)((num / 10) + '0');
|
||||
|
||||
result = f_mount(0, &FATFS_Obj);
|
||||
if (result!=FR_OK)
|
||||
{
|
||||
strcpy(g_logFilename, "FILE SYSTEM ERROR");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skip over any existing log files ... _000, _001, etc. (or find first gap in numbering)
|
||||
while (1)
|
||||
{
|
||||
result = f_open(&g_oLogFile, g_logFilename, FA_OPEN_EXISTING | FA_READ);
|
||||
|
||||
if (result == FR_OK)
|
||||
{
|
||||
f_close(&g_oLogFile);
|
||||
|
||||
// bump log file counter (file extension)
|
||||
n = &g_logFilename[15];
|
||||
if (++*n > '9')
|
||||
{
|
||||
*n='0';
|
||||
n--;
|
||||
if (++*n > '9')
|
||||
{
|
||||
*n='0';
|
||||
n--;
|
||||
if (++*n > '9')
|
||||
{
|
||||
*n='0';
|
||||
break; // Wow. We looped back around past 999 to 000! abort loop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (result == FR_NO_PATH)
|
||||
{
|
||||
if (f_mkdir("/G9XLOGS") != FR_OK)
|
||||
{
|
||||
result = FR_NO_PATH;
|
||||
break;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case FR_NO_PATH:
|
||||
strcpy(g_logFilename, "Check /G9XLOGS folder");
|
||||
break;
|
||||
case FR_NOT_READY:
|
||||
strcpy(g_logFilename, "DATA CARD NOT PRESENT");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// g_logFilename should now be set appropriately.
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
+12
-2
@@ -451,6 +451,14 @@ void menuProcDiagKeys(uint8_t event)
|
||||
lcd_putcAtt(5*FW+2, y, t+'0', t);
|
||||
}
|
||||
|
||||
#if defined (PCBV4)
|
||||
for(uint8_t i=0; i<2; i++) {
|
||||
uint8_t y = i*FH + FH;
|
||||
lcd_putsn_P(14*FW, y, PSTR("RE1RE2")+3*i, 3);
|
||||
lcd_outdezNAtt(18*FW, y, g_rotenc[i], LEFT|(keyState((EnumKeys)(SW_RE1+i)) ? INVERS : 0));
|
||||
}
|
||||
#endif
|
||||
|
||||
lcd_putsn_P(14*FW, 3*FH, PSTR("Trim- +"), 7);
|
||||
for(uint8_t i=0; i<4; i++)
|
||||
{
|
||||
@@ -474,8 +482,10 @@ void menuProcDiagAna(uint8_t event)
|
||||
uint8_t y=i*FH;
|
||||
lcd_putsn_P( 4*FW, y,PSTR("A1A2A3A4A5A6A7A8")+2*i,2);
|
||||
lcd_outhex4( 8*FW, y,anaIn(i));
|
||||
if(i<7) lcd_outdez8(17*FW, y, (int32_t)calibratedStick[i]*100/1024);
|
||||
if(i==7) putsVolts(17*FW, y, g_vbat100mV, (sub==1 ? INVERS : 0));
|
||||
if(i<7)
|
||||
lcd_outdez8(17*FW, y, (int32_t)calibratedStick[i]*100/1024);
|
||||
else
|
||||
putsVolts(17*FW, y, g_vbat100mV, (sub==1 ? INVERS : 0));
|
||||
}
|
||||
// lcd_outdezAtt( 21*FW, 3*FH, g_eeGeneral.vBatCalib, 0) ;
|
||||
// lcd_outdezAtt( 21*FW, 4*FH, abRunningAvg, 0) ;
|
||||
|
||||
+200
-57
@@ -43,8 +43,8 @@ mode4 ail thr ele rud
|
||||
EEGeneral g_eeGeneral;
|
||||
ModelData g_model;
|
||||
|
||||
uint16_t g_tmr1Latency_max;
|
||||
uint16_t g_tmr1Latency_min = 0x7ff;
|
||||
uint8_t g_tmr1Latency_max;
|
||||
uint8_t g_tmr1Latency_min;
|
||||
uint16_t g_timeMain;
|
||||
uint16_t g_time_per10;
|
||||
|
||||
@@ -256,12 +256,13 @@ int16_t Expo::expo(int16_t x)
|
||||
#endif
|
||||
|
||||
|
||||
void applyExpos(int16_t *anas)
|
||||
void applyExpos(int16_t *anas, uint8_t phase)
|
||||
{
|
||||
static int16_t anas2[4]; // values before expo, to ensure same expo base when multiple expo lines are used
|
||||
memcpy(anas2, anas, sizeof(anas2));
|
||||
|
||||
uint8_t phase = getFlightPhase();
|
||||
if (phase == 255)
|
||||
phase = getFlightPhase();
|
||||
|
||||
int8_t cur_chn = -1;
|
||||
for (uint8_t i=0; i<DIM(g_model.expoData); i++) {
|
||||
@@ -448,10 +449,8 @@ void setTrimValue(uint8_t phase, uint8_t idx, int16_t trim)
|
||||
STORE_MODELVARS;
|
||||
}
|
||||
|
||||
uint8_t getTrimFlightPhase(uint8_t idx, int8_t phase) // TODO uint8_t phase?
|
||||
uint8_t getTrimFlightPhase(uint8_t idx, uint8_t phase)
|
||||
{
|
||||
if (phase == -1) phase = getFlightPhase();
|
||||
|
||||
for (uint8_t i=0; i<MAX_PHASES; i++) {
|
||||
if (phase == 0) return 0;
|
||||
int16_t trim = getTrimValue(phase, idx);
|
||||
@@ -674,7 +673,7 @@ uint8_t checkTrim(uint8_t event)
|
||||
if (k>=0 && k<8) { // && (event & _MSK_KEY_REPT))
|
||||
//LH_DWN LH_UP LV_DWN LV_UP RV_DWN RV_UP RH_DWN RH_UP
|
||||
uint8_t idx = k/2;
|
||||
uint8_t phase = getTrimFlightPhase(idx);
|
||||
uint8_t phase = getTrimFlightPhase(idx, getFlightPhase());
|
||||
int16_t before = getTrimValue(phase, idx);
|
||||
int8_t v = (s==0) ? min(32, abs(before)/4+1) : 1 << (s-1); // 1=>1 2=>2 3=>4 4=>8
|
||||
bool thro = (((2-(g_eeGeneral.stickMode&1)) == idx) && g_model.thrTrim);
|
||||
@@ -817,7 +816,7 @@ void getADC_bandgap()
|
||||
{
|
||||
#if defined(PCBSTD)
|
||||
ADMUX=0x1E|ADC_VREF_TYPE; // Switch MUX to internal 1.22V reference
|
||||
_delay_us(5); // short delay to stablise reference voltage
|
||||
_delay_us(5); // short delay to stabilise reference voltage
|
||||
ADCSRA|=0x40;
|
||||
while ((ADCSRA & 0x10)==0);
|
||||
ADCSRA|=0x10; // grab a sample
|
||||
@@ -1093,13 +1092,13 @@ int32_t act [MAX_MIXERS] = {0};
|
||||
uint8_t swOn [MAX_MIXERS] = {0};
|
||||
uint8_t mixWarning;
|
||||
|
||||
inline void evalTrims()
|
||||
inline void evalTrims(uint8_t phase)
|
||||
{
|
||||
for (uint8_t i=0; i<NUM_STICKS; i++) {
|
||||
// do trim -> throttle trim if applicable
|
||||
int16_t v = anas[i];
|
||||
int32_t vv = 2*RESX;
|
||||
int16_t trim = getTrimValue(getTrimFlightPhase(i), i);
|
||||
int16_t trim = getTrimValue(getTrimFlightPhase(i, phase), i);
|
||||
if (IS_THROTTLE(i) && g_model.thrTrim) {
|
||||
if (g_eeGeneral.throttleReversed)
|
||||
trim = -trim;
|
||||
@@ -1113,7 +1112,7 @@ inline void evalTrims()
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t evalSticks()
|
||||
uint8_t evalSticks(uint8_t phase)
|
||||
{
|
||||
#ifdef HELI
|
||||
uint16_t d = 0;
|
||||
@@ -1178,10 +1177,10 @@ uint8_t evalSticks()
|
||||
}
|
||||
|
||||
/* EXPOs */
|
||||
applyExpos(anas);
|
||||
applyExpos(anas, phase);
|
||||
|
||||
/* TRIMs */
|
||||
evalTrims();
|
||||
evalTrims(phase);
|
||||
|
||||
return anaCenter;
|
||||
}
|
||||
@@ -1204,10 +1203,9 @@ void evalFunctions()
|
||||
}
|
||||
}
|
||||
|
||||
void perOut(int16_t *chanOut)
|
||||
void perOut(int16_t *chanOut, uint8_t phase)
|
||||
{
|
||||
uint8_t phase = getFlightPhase();
|
||||
uint8_t anaCenter = evalSticks();
|
||||
uint8_t anaCenter = evalSticks(phase);
|
||||
|
||||
//===========BEEP CENTER================
|
||||
anaCenter &= g_model.beepANACenter;
|
||||
@@ -1348,10 +1346,6 @@ void perOut(int16_t *chanOut)
|
||||
{
|
||||
#define DEL_MULT 256
|
||||
|
||||
//if(init) {
|
||||
//act[i]=(int32_t)v*DEL_MULT;
|
||||
//swTog = false;
|
||||
//}
|
||||
int16_t diff = v-act[i]/DEL_MULT;
|
||||
|
||||
if(swTog) {
|
||||
@@ -1472,53 +1466,113 @@ void perOut(int16_t *chanOut)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DISPLAY_USER_DATA
|
||||
char userDataDisplayBuf[TELEM_SCREEN_BUFFER_SIZE];
|
||||
#endif
|
||||
|
||||
void perMain()
|
||||
{
|
||||
static uint16_t lastTMR;
|
||||
tick10ms = (get_tmr10ms() != lastTMR);
|
||||
lastTMR = get_tmr10ms();
|
||||
|
||||
int16_t last_chans512[NUM_CHNOUT];
|
||||
int16_t next_chans512[NUM_CHNOUT];
|
||||
|
||||
static uint8_t last_phase = 0;
|
||||
#define MAX_ACT 0xffff
|
||||
static uint16_t fp_act[MAX_PHASES] = {0};
|
||||
static uint8_t s_fade_flight_phases = 0;
|
||||
static uint8_t s_last_phase = 255;
|
||||
uint8_t phase = getFlightPhase();
|
||||
|
||||
static uint8_t fading_out_timer = 0;
|
||||
if (last_phase != phase) {
|
||||
fading_out_timer = 10 * max(g_model.phaseData[last_phase].fadeOut, g_model.phaseData[phase].fadeIn);
|
||||
last_phase = phase;
|
||||
if (s_last_phase != phase) {
|
||||
if (s_last_phase == 255) {
|
||||
fp_act[phase] = MAX_ACT;
|
||||
}
|
||||
else {
|
||||
if (g_model.phaseData[s_last_phase].fadeOut) {
|
||||
s_fade_flight_phases |= (1<<s_last_phase);
|
||||
}
|
||||
else {
|
||||
fp_act[s_last_phase] = 0;
|
||||
s_fade_flight_phases &= ~(1<<s_last_phase);
|
||||
}
|
||||
if (g_model.phaseData[phase].fadeIn) {
|
||||
s_fade_flight_phases |= (1<<phase);
|
||||
}
|
||||
else {
|
||||
fp_act[phase] = MAX_ACT;
|
||||
s_fade_flight_phases &= ~(1<<phase);
|
||||
}
|
||||
}
|
||||
s_last_phase = phase;
|
||||
// printf("s_fade_flight_phases=%d\n", s_fade_flight_phases); fflush(stdout);
|
||||
}
|
||||
|
||||
if (fading_out_timer) {
|
||||
memcpy(last_chans512, g_chans512, sizeof(g_chans512));
|
||||
}
|
||||
int16_t next_chans512[NUM_CHNOUT];
|
||||
|
||||
perOut(next_chans512);
|
||||
|
||||
for (uint8_t i=0; i<NUM_CHNOUT; i++) {
|
||||
cli();
|
||||
if (fading_out_timer) {
|
||||
g_chans512[i] = last_chans512[i] + (next_chans512[i] - last_chans512[i]) / fading_out_timer;
|
||||
fading_out_timer--;
|
||||
if (s_fade_flight_phases) {
|
||||
int32_t sum_chans512[NUM_CHNOUT] = {0};
|
||||
int32_t weight = 0;
|
||||
for (uint8_t p=0; p<MAX_PHASES; p++) {
|
||||
if (s_fade_flight_phases & (1<<p)) {
|
||||
perOut(next_chans512, p);
|
||||
// printf("perOut(%d - %d)=>%d\n", p, fp_act[p], next_chans512[2]);
|
||||
for (uint8_t i=0; i<NUM_CHNOUT; i++) {
|
||||
sum_chans512[i] += (int32_t)next_chans512[i] * fp_act[p];
|
||||
}
|
||||
weight += fp_act[p];
|
||||
}
|
||||
}
|
||||
// printf("sum=%d, weight=%d ", sum_chans512[2], weight); fflush(stdout);
|
||||
assert(weight);
|
||||
for (uint8_t i=0; i<NUM_CHNOUT; i++) {
|
||||
next_chans512[i] = ((int32_t)sum_chans512[i] / weight);
|
||||
}
|
||||
// printf("output = %d\n", next_chans512[2]); fflush(stdout);
|
||||
}
|
||||
else {
|
||||
g_chans512[i] = next_chans512[i];
|
||||
perOut(next_chans512, phase);
|
||||
}
|
||||
|
||||
for (uint8_t i=0; i<NUM_CHNOUT; i++) {
|
||||
cli();
|
||||
g_chans512[i] = next_chans512[i];
|
||||
sei();
|
||||
}
|
||||
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
if (!eeprom_buffer_size) {
|
||||
if (theFile.isWriting())
|
||||
theFile.nextWriteStep();
|
||||
else if (s_eeDirtyMsk)
|
||||
eeCheck();
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!tick10ms) return; //make sure the rest happen only every 10ms.
|
||||
|
||||
if (s_fade_flight_phases) {
|
||||
for (uint8_t p=0; p<MAX_PHASES; p++) {
|
||||
// printf("f_act[%d]=%d\n", p, fp_act[p]);
|
||||
if (s_fade_flight_phases & (1<<p)) {
|
||||
if (p == phase) {
|
||||
uint16_t delta = (MAX_ACT / 100) / g_model.phaseData[p].fadeIn;
|
||||
if (MAX_ACT - fp_act[p] > delta)
|
||||
fp_act[p] += delta;
|
||||
else {
|
||||
fp_act[p] = MAX_ACT;
|
||||
s_fade_flight_phases -= (1<<p);
|
||||
}
|
||||
}
|
||||
else {
|
||||
uint16_t delta = (MAX_ACT / 100) / g_model.phaseData[p].fadeOut;
|
||||
if (fp_act[p] > delta)
|
||||
fp_act[p] -= delta;
|
||||
else {
|
||||
fp_act[p] = 0;
|
||||
s_fade_flight_phases -= (1<<p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
evalFunctions();
|
||||
|
||||
if (s_noHi) s_noHi--;
|
||||
@@ -1537,10 +1591,98 @@ void perMain()
|
||||
if (trimsCheckTimer > 0)
|
||||
trimsCheckTimer -= 1;
|
||||
|
||||
#ifndef EEPROM_ASYNC_WRITE
|
||||
eeCheck();
|
||||
#endif
|
||||
|
||||
#if defined (FRSKY)
|
||||
|
||||
/***** TEST CODE - Fr-Sky SD/MMC card / User Data experiments *****/
|
||||
|
||||
#if defined (PCBV3)
|
||||
|
||||
/* Use light switch (on) to open telemtry test log file */
|
||||
static FRESULT result;
|
||||
|
||||
static int8_t testLogOpen = 0;
|
||||
|
||||
if(getSwitch(g_eeGeneral.lightSw,0))
|
||||
{
|
||||
// while(1); // Test WDT
|
||||
if ((testLogOpen==0) // if we know we haven't started logging ...
|
||||
|| ((testLogOpen==1) && !g_oLogFile.fs)) // ... or we thought we had, but the file got closed
|
||||
{
|
||||
result = f_mount(0, &FATFS_Obj);
|
||||
if (result!=FR_OK)
|
||||
{
|
||||
testLogOpen = -1;
|
||||
beepAgain = result - 1;
|
||||
beepKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
// create new log file using filename set up in pers.cpp::resetTelemetry()
|
||||
result = f_open(&g_oLogFile, g_logFilename, FA_OPEN_ALWAYS | FA_WRITE);
|
||||
if (result!=FR_OK)
|
||||
{
|
||||
testLogOpen = -2;
|
||||
beepAgain = result - 1;
|
||||
beepKey();
|
||||
}
|
||||
else
|
||||
{
|
||||
f_lseek(&g_oLogFile, g_oLogFile.fsize); // append
|
||||
|
||||
testLogOpen = 1;
|
||||
beepWarn2();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (testLogOpen==1)
|
||||
{
|
||||
f_close(&g_oLogFile);
|
||||
beepWarn2();
|
||||
}
|
||||
testLogOpen = 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DISPLAY_USER_DATA
|
||||
////////////////
|
||||
// Write raw user data into on-screen display line buffer
|
||||
|
||||
char userDataRxBuffer[21]; // Temp buffer used to collect fr-sky user data
|
||||
|
||||
// retrieve bytes from user data buffer and insert into display string,
|
||||
// scrolling at the 21 character mark (edge of screen)
|
||||
uint8_t numbytes = frskyGetUserData(userDataRxBuffer, 21); // Get as many bytes as we can
|
||||
|
||||
static uint8_t displayBufferIndex;
|
||||
for (uint8_t byt=0; byt < numbytes; byt++)
|
||||
{
|
||||
displayBufferIndex++;
|
||||
if (displayBufferIndex > 20)
|
||||
{
|
||||
for (int xx=0; xx<20; xx++) // scroll one char left
|
||||
userDataDisplayBuf[xx] = userDataDisplayBuf[xx+1];
|
||||
displayBufferIndex = 20;
|
||||
}
|
||||
userDataDisplayBuf[displayBufferIndex] = userDataRxBuffer[byt];
|
||||
|
||||
// Write the raw byte out to log file, if open
|
||||
if (testLogOpen && (g_oLogFile.fs != 0))
|
||||
f_putc(userDataRxBuffer[byt], &g_oLogFile);
|
||||
|
||||
}
|
||||
////////////////
|
||||
#endif
|
||||
|
||||
/***** END TEST CODE - Fr-Sky User Data experiments *****/
|
||||
|
||||
// PCBV3
|
||||
#endif
|
||||
// FRSKY
|
||||
#endif
|
||||
|
||||
lcd_clear();
|
||||
uint8_t evt=getEvent();
|
||||
evt = checkTrim(evt);
|
||||
@@ -1950,22 +2092,23 @@ uint16_t DEBUG2 = 0;
|
||||
|
||||
void instantTrim()
|
||||
{
|
||||
uint8_t phase = getFlightPhase();
|
||||
|
||||
for (uint8_t i=0; i<NUM_STICKS; i++) {
|
||||
if (!IS_THROTTLE(i)) {
|
||||
// don't instant trim the throttle stick
|
||||
uint8_t phase = getTrimFlightPhase(i);
|
||||
uint8_t trim_phase = getTrimFlightPhase(i, phase);
|
||||
s_noStickInputs = true;
|
||||
evalSticks();
|
||||
evalSticks(phase);
|
||||
s_noStickInputs = false;
|
||||
int16_t trim = (anas[i] + trims[i]) / 2;
|
||||
// printf("anas[%d]=%d, trims[%d]=%d, trim=%d, subtrim=%d => trim=%d\n", i, anas[i], i, trims[i], g_model.phaseData[phase].trim[i], g_model.subtrim[i], trim);
|
||||
if (trim < TRIM_EXTENDED_MIN) {
|
||||
trim = TRIM_EXTENDED_MIN;
|
||||
}
|
||||
if (trim > TRIM_EXTENDED_MAX) {
|
||||
trim = TRIM_EXTENDED_MAX;
|
||||
}
|
||||
setTrimValue(phase, i, trim);
|
||||
setTrimValue(trim_phase, i, trim);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1978,7 +2121,7 @@ void moveTrimsToOffsets() // copy state of 3 primary to subtrim
|
||||
int16_t zero_chans512[NUM_CHNOUT];
|
||||
|
||||
s_noStickInputs = true;
|
||||
perOut(zero_chans512); // do output loop - zero input sticks
|
||||
perOut(zero_chans512, getFlightPhase()); // do output loop - zero input sticks
|
||||
s_noStickInputs = false;
|
||||
|
||||
for (uint8_t i=0; i<NUM_CHNOUT; i++)
|
||||
@@ -2001,27 +2144,27 @@ void moveTrimsToOffsets() // copy state of 3 primary to subtrim
|
||||
|
||||
#if defined (PCBV4)
|
||||
// Rotary encoder interrupts
|
||||
uint8_t volatile g_rotenc1, g_rotenc2 = 0;
|
||||
volatile uint8_t g_rotenc[2] = {0};
|
||||
ISR(INT2_vect)
|
||||
{
|
||||
uint8_t input = PIND & 0b00001100;
|
||||
if (input == 0 || input == 0b00001100) g_rotenc1--;
|
||||
if (input == 0 || input == 0b00001100) g_rotenc[0]--;
|
||||
}
|
||||
ISR(INT3_vect)
|
||||
{
|
||||
uint8_t input = PIND & 0b00001100;
|
||||
if (input == 0 || input == 0b00001100) g_rotenc1++;
|
||||
if (input == 0 || input == 0b00001100) g_rotenc[0]++;
|
||||
}
|
||||
|
||||
ISR(INT5_vect)
|
||||
{
|
||||
uint8_t input = PINE & 0b01100000;
|
||||
if (input == 0 || input == 0b01100000) g_rotenc2++;
|
||||
if (input == 0 || input == 0b01100000) g_rotenc[1]++;
|
||||
}
|
||||
ISR(INT6_vect)
|
||||
{
|
||||
uint8_t input = PINE & 0b01100000;
|
||||
if (input == 0 || input == 0b01100000) g_rotenc2--;
|
||||
if (input == 0 || input == 0b01100000) g_rotenc[1]--;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2188,7 +2331,7 @@ int main(void)
|
||||
|
||||
clearKeyEvents(); //make sure no keys are down before proceeding
|
||||
|
||||
perOut(g_chans512);
|
||||
perOut(g_chans512, getFlightPhase());
|
||||
|
||||
lcdSetRefVolt(g_eeGeneral.contrast);
|
||||
g_LightOffCounter = g_eeGeneral.lightAutoOff*500; //turn on light for x seconds - no need to press key Issue 152
|
||||
|
||||
+19
-12
@@ -29,6 +29,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#if defined(PCBV3)
|
||||
#include "ff.h"
|
||||
#include "time.h"
|
||||
#endif
|
||||
|
||||
@@ -291,7 +292,9 @@ enum EnumKeys {
|
||||
SW_ID2 ,
|
||||
SW_AileDR ,
|
||||
SW_Gear ,
|
||||
SW_Trainer
|
||||
SW_Trainer,
|
||||
SW_RE1,
|
||||
SW_RE2
|
||||
};
|
||||
|
||||
#define CURVE_BASE 7
|
||||
@@ -451,10 +454,6 @@ void per10ms();
|
||||
/// Erzeugt periodisch alle Outputs ausser Bildschirmausgaben.
|
||||
void zeroVariables();
|
||||
|
||||
#define NO_TRAINER 0x01
|
||||
#define NO_INPUT 0x02
|
||||
extern void perOut(int16_t *chanOut, uint8_t att);
|
||||
|
||||
/// Liefert den Zustand des Switches 'swtch'. Die Numerierung erfolgt ab 1
|
||||
/// (1=SW_ON, 2=SW_ThrCt, 10=SW_Trainer). 0 Bedeutet not conected.
|
||||
/// Negative Werte erzeugen invertierte Ergebnisse.
|
||||
@@ -474,7 +473,7 @@ bool getSwitch(int8_t swtch, bool nc);
|
||||
///
|
||||
|
||||
uint8_t getFlightPhase();
|
||||
uint8_t getTrimFlightPhase(uint8_t idx, int8_t phase=-1);
|
||||
uint8_t getTrimFlightPhase(uint8_t idx, uint8_t phase);
|
||||
extern int16_t getTrimValue(uint8_t phase, uint8_t idx);
|
||||
extern void setTrimValue(uint8_t phase, uint8_t idx, int16_t trim);
|
||||
|
||||
@@ -498,8 +497,8 @@ extern uint8_t Timer2_running ;
|
||||
extern uint16_t timer2 ;
|
||||
void resetTimer2() ;
|
||||
|
||||
extern uint16_t g_tmr1Latency_max;
|
||||
extern uint16_t g_tmr1Latency_min;
|
||||
extern uint8_t g_tmr1Latency_max;
|
||||
extern uint8_t g_tmr1Latency_min;
|
||||
extern uint16_t g_timeMain;
|
||||
extern uint16_t g_time_per10;
|
||||
|
||||
@@ -560,15 +559,13 @@ template<class t> inline t limit(t mi, t x, t ma){ return min(max(mi,x),ma); }
|
||||
/// eeCheck ins EEPROM zurueckgeschrieben.
|
||||
void eeWriteBlockCmp(const void *i_pointer_ram, void *i_pointer_eeprom, size_t size);
|
||||
void eeDirty(uint8_t msk);
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
inline void eeFlush() { theFile.flush(); }
|
||||
#endif
|
||||
void eeCheck(bool immediately=false);
|
||||
void eeReadAll();
|
||||
bool eeModelExists(uint8_t id);
|
||||
uint16_t eeLoadModelName(uint8_t id, char *name);
|
||||
void eeLoadModel(uint8_t id);
|
||||
int8_t eeDuplicateModel(uint8_t id, bool down=true);
|
||||
int8_t eeFindEmptyModel(uint8_t id, bool down);
|
||||
|
||||
///number of real input channels (1-9) plus virtual input channels X1-X4
|
||||
#define NUM_XCHNRAW (NUM_STICKS+NUM_POTS+2/*MAX/FULL*/+3/*CYC1-CYC3*/+NUM_PPM+NUM_CHNOUT+NUM_TELEMETRY)
|
||||
@@ -651,7 +648,7 @@ extern uint16_t expou(uint16_t x, uint16_t k);
|
||||
extern int16_t expo(int16_t x, int16_t k);
|
||||
extern int16_t intpol(int16_t, uint8_t);
|
||||
extern int16_t applyCurve(int16_t, uint8_t, uint8_t srcRaw);
|
||||
extern void applyExpos(int16_t *anas);
|
||||
extern void applyExpos(int16_t *anas, uint8_t phase=255);
|
||||
|
||||
extern uint16_t anaIn(uint8_t chan);
|
||||
extern int16_t calibratedStick[7];
|
||||
@@ -729,11 +726,21 @@ inline bool isFunctionActive(uint8_t func)
|
||||
return active_functions & (1 << (func-1));
|
||||
}
|
||||
|
||||
#ifdef DISPLAY_USER_DATA
|
||||
#define TELEM_SCREEN_BUFFER_SIZE 21
|
||||
extern char userDataDisplayBuf[TELEM_SCREEN_BUFFER_SIZE]; // text buffer for frsky telem. user data experiments
|
||||
#endif
|
||||
|
||||
#if defined (PCBV3)
|
||||
extern char g_logFilename[21]; // pers.cpp::resetTelemetry()
|
||||
extern FATFS FATFS_Obj; // pers.cpp::resetTelemetry()
|
||||
extern FIL g_oLogFile; // pers.cpp::resetTelemetry()
|
||||
#endif
|
||||
|
||||
#if defined (PCBV4)
|
||||
// Global rotary encoder registers -- 8-bit, 0-255
|
||||
extern volatile uint8_t g_rotenc[2];
|
||||
#endif
|
||||
|
||||
#endif // gruvin9x_h
|
||||
/*eof*/
|
||||
|
||||
+9
-2
@@ -140,7 +140,7 @@ TEST(EEPROM, eeCheckImmediately) {
|
||||
EXPECT_EQ(sz, 300);
|
||||
}
|
||||
|
||||
TEST(EEPROM, eeDuplicateModel) {
|
||||
TEST(EEPROM, copy) {
|
||||
eepromFile = NULL; // in memory
|
||||
|
||||
uint8_t buf[1000];
|
||||
@@ -151,7 +151,7 @@ TEST(EEPROM, eeDuplicateModel) {
|
||||
|
||||
theFile.writeRlc(5, 6, buf, 300, true);
|
||||
|
||||
eeDuplicateModel(4);
|
||||
theFile.copy(6, 5);
|
||||
|
||||
theFile.openRd(6);
|
||||
uint16_t sz=0;
|
||||
@@ -250,6 +250,13 @@ TEST(getSwitch, circularCSW) {
|
||||
EXPECT_EQ(getSwitch(-(1+MAX_SWITCH-NUM_CSW), 0), true);
|
||||
}
|
||||
|
||||
TEST(getSwitch, nullSW) {
|
||||
memset(&g_model, 0, sizeof(g_model));
|
||||
EXPECT_EQ(getSwitch(0, 0), false);
|
||||
EXPECT_EQ(getSwitch(0, true), true);
|
||||
EXPECT_EQ(getSwitch(0, 0), false);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
|
||||
+1
-1
@@ -451,7 +451,7 @@ void putsFlightPhase(uint8_t x, uint8_t y, int8_t idx, uint8_t att)
|
||||
{
|
||||
if (idx==0) { lcd_putsAtt(x,y,PSTR("---"),att); return; }
|
||||
if (idx < 0) { lcd_vlineStip(x-2, y, 8, 0x5E/*'!'*/); idx = -idx; }
|
||||
putsStrIdx(x, y, PSTR("FP"), idx, att);
|
||||
putsStrIdx(x, y, PSTR("FP"), idx-1, att);
|
||||
}
|
||||
|
||||
#define CURV_STR "---x>0x<0|x|f>0f<0|f|"
|
||||
|
||||
+76
-83
@@ -148,10 +148,8 @@ void menuProcModelSelect(uint8_t event)
|
||||
|
||||
TITLE("MODELSEL");
|
||||
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
// flush eeprom write
|
||||
eeFlush();
|
||||
#endif
|
||||
// flush eeprom write
|
||||
eeFlush();
|
||||
|
||||
if (s_confirmation) {
|
||||
EFile::rm(FILE_MODEL(m_posVert)); // delete file
|
||||
@@ -180,7 +178,7 @@ void menuProcModelSelect(uint8_t event)
|
||||
{
|
||||
case EVT_ENTRY:
|
||||
m_posVert = sub = g_eeGeneral.currModel;
|
||||
s_copyMode = 0;
|
||||
s_copyMode = 0; // TODO only this one?
|
||||
s_copyTgtOfs = 0;
|
||||
s_copySrcRow = -1;
|
||||
break;
|
||||
@@ -192,68 +190,58 @@ void menuProcModelSelect(uint8_t event)
|
||||
}
|
||||
// no break
|
||||
case EVT_KEY_BREAK(KEY_EXIT):
|
||||
if (s_copyTgtOfs || s_copySrcRow >= 0) {
|
||||
eeCheck(true); // force writing of current model data before this is changed
|
||||
do {
|
||||
if (s_copyTgtOfs < 0) {
|
||||
s_copyTgtOfs++;
|
||||
m_posVert = (MAX_MODELS+m_posVert-1) % MAX_MODELS;
|
||||
}
|
||||
else {
|
||||
s_copyTgtOfs--;
|
||||
m_posVert = (m_posVert+1) % MAX_MODELS;
|
||||
}
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
s_sync_write = true;
|
||||
#endif
|
||||
EFile::swap(FILE_MODEL(sub), FILE_MODEL(m_posVert));
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
s_sync_write = false;
|
||||
#endif
|
||||
if (m_posVert == g_eeGeneral.currModel) {
|
||||
g_eeGeneral.currModel = sub;
|
||||
STORE_GENERALVARS;
|
||||
}
|
||||
else if (sub == g_eeGeneral.currModel) {
|
||||
g_eeGeneral.currModel = m_posVert;
|
||||
STORE_GENERALVARS;
|
||||
}
|
||||
sub = m_posVert;
|
||||
} while (s_copyTgtOfs != 0);
|
||||
|
||||
if (s_copySrcRow >= 0) {
|
||||
EFile::rm(FILE_MODEL(sub));
|
||||
sub = m_posVert = s_copySrcRow;
|
||||
s_copySrcRow = -1;
|
||||
}
|
||||
if (s_copyMode) {
|
||||
sub = m_posVert = (s_copyMode == MOVE_MODE || s_copySrcRow<0) ? (16+sub+s_copyTgtOfs) % 16 : s_copySrcRow; // TODO reset s_copySrcRow?
|
||||
s_copyMode = 0; // TODO only this one?
|
||||
s_copySrcRow = -1;
|
||||
s_copyTgtOfs = 0;
|
||||
killEvents(_event);
|
||||
}
|
||||
s_copyMode = 0;
|
||||
killEvents(_event);
|
||||
break;
|
||||
case EVT_KEY_BREAK(KEY_MENU):
|
||||
if (s_copyTgtOfs || s_copySrcRow >= 0) {
|
||||
s_copyMode = 0;
|
||||
}
|
||||
else if (EFile::exists(FILE_MODEL(sub))) {
|
||||
s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE);
|
||||
}
|
||||
s_copySrcRow = -1;
|
||||
s_copyTgtOfs = 0;
|
||||
break;
|
||||
case EVT_KEY_LONG(KEY_MENU):
|
||||
if (s_copyTgtOfs) {
|
||||
case EVT_KEY_BREAK(KEY_MENU):
|
||||
if (s_copyMode && (s_copyTgtOfs || s_copySrcRow>=0)) {
|
||||
eeCheck(true); // force writing of current model data before this is changed
|
||||
|
||||
uint8_t cur = (16 + sub + s_copyTgtOfs) % 16;
|
||||
|
||||
if (s_copyMode == COPY_MODE) {
|
||||
if (!theFile.copy(FILE_MODEL(cur), FILE_MODEL(s_copySrcRow)))
|
||||
cur = sub;
|
||||
}
|
||||
|
||||
s_copySrcRow = g_eeGeneral.currModel; // to update the currModel value
|
||||
while (sub != cur) {
|
||||
uint8_t src = cur;
|
||||
cur = (s_copyTgtOfs > 0 ? cur+15 : cur+1) % 16;
|
||||
EFile::swap(FILE_MODEL(src), FILE_MODEL(cur));
|
||||
if (src == s_copySrcRow)
|
||||
s_copySrcRow = cur;
|
||||
else if (cur == s_copySrcRow)
|
||||
s_copySrcRow = src;
|
||||
}
|
||||
|
||||
if (s_copySrcRow != g_eeGeneral.currModel) {
|
||||
g_eeGeneral.currModel = s_copySrcRow;
|
||||
STORE_GENERALVARS;
|
||||
}
|
||||
|
||||
s_copyMode = 0; // TODO only this one?
|
||||
s_copySrcRow = -1;
|
||||
s_copyTgtOfs = 0;
|
||||
s_copyMode = 0;
|
||||
}
|
||||
else {
|
||||
else if (_event == EVT_KEY_LONG(KEY_MENU)) {
|
||||
eeCheck(true); // force writing of current model data before this is changed
|
||||
if (g_eeGeneral.currModel != sub) {
|
||||
g_eeGeneral.currModel = sub;
|
||||
STORE_GENERALVARS;
|
||||
eeLoadModel(sub);
|
||||
}
|
||||
eeLoadModel(sub);
|
||||
killEvents(event);
|
||||
}
|
||||
else if (EFile::exists(FILE_MODEL(sub))) {
|
||||
s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE);
|
||||
}
|
||||
killEvents(_event);
|
||||
break;
|
||||
case EVT_KEY_FIRST(KEY_LEFT):
|
||||
case EVT_KEY_FIRST(KEY_RIGHT):
|
||||
@@ -266,41 +254,25 @@ void menuProcModelSelect(uint8_t event)
|
||||
case EVT_KEY_FIRST(KEY_UP):
|
||||
case EVT_KEY_FIRST(KEY_DOWN):
|
||||
if (s_copyMode) {
|
||||
eeCheck(true);
|
||||
int8_t next_ofs = (_event == EVT_KEY_FIRST(KEY_UP) ? s_copyTgtOfs+1 : s_copyTgtOfs-1);
|
||||
if (next_ofs == 16 || next_ofs == -16)
|
||||
next_ofs = 0;
|
||||
|
||||
if (s_copySrcRow < 0 && s_copyMode==COPY_MODE) {
|
||||
s_copySrcRow = oldSub;
|
||||
// insert a model (in the first empty slot above / below)
|
||||
m_posVert = eeDuplicateModel(s_copySrcRow, _event==EVT_KEY_FIRST(KEY_DOWN));
|
||||
// find a hole (in the first empty slot above / below)
|
||||
m_posVert = eeFindEmptyModel(s_copySrcRow, _event==EVT_KEY_FIRST(KEY_DOWN));
|
||||
if (m_posVert == (uint8_t)-1) {
|
||||
// no free room for duplicating the model
|
||||
beepWarn();
|
||||
m_posVert = oldSub;
|
||||
s_copyMode = 0;
|
||||
s_copyMode = 0; // TODO only this one?
|
||||
s_copyTgtOfs = 0;
|
||||
s_copySrcRow = -1;
|
||||
}
|
||||
next_ofs = 0;
|
||||
sub = m_posVert;
|
||||
}
|
||||
else {
|
||||
// only swap the model with its neighbor
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
s_sync_write = true;
|
||||
#endif
|
||||
EFile::swap(FILE_MODEL(oldSub), FILE_MODEL(sub));
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
s_sync_write = false;
|
||||
#endif
|
||||
if (oldSub == g_eeGeneral.currModel) {
|
||||
g_eeGeneral.currModel = sub;
|
||||
STORE_GENERALVARS;
|
||||
}
|
||||
else if (sub == g_eeGeneral.currModel) {
|
||||
g_eeGeneral.currModel = oldSub;
|
||||
STORE_GENERALVARS;
|
||||
}
|
||||
}
|
||||
s_copyTgtOfs = next_ofs;
|
||||
}
|
||||
break;
|
||||
@@ -308,21 +280,42 @@ void menuProcModelSelect(uint8_t event)
|
||||
|
||||
if (sub-s_pgOfs < 1) s_pgOfs = max(0, sub-1);
|
||||
else if (sub-s_pgOfs > 5) s_pgOfs = min(MAX_MODELS-7, sub-4);
|
||||
|
||||
// printf("copy_mode=%d s_copySrcRow=%d s_copyTgtOfs=%d sub=%d\n", s_copyMode, s_copySrcRow, s_copyTgtOfs, sub); fflush(stdout);
|
||||
|
||||
for (uint8_t i=0; i<7; i++) {
|
||||
uint8_t y=(i+1)*FH;
|
||||
uint8_t k=i+s_pgOfs;
|
||||
lcd_outdezNAtt(3*FW+2, y, k+1, LEADING0+((!s_copyMode && sub==k) ? INVERS : 0), 2);
|
||||
|
||||
if (s_copyMode == MOVE_MODE || (s_copyMode == COPY_MODE && s_copySrcRow >= 0)) {
|
||||
if (k == sub) {
|
||||
if (s_copyMode == COPY_MODE) {
|
||||
k = s_copySrcRow;
|
||||
lcd_putc(20*FW+2, y, '+');
|
||||
}
|
||||
else {
|
||||
k = sub + s_copyTgtOfs;
|
||||
}
|
||||
}
|
||||
else if (s_copyTgtOfs < 0 && ((k < sub && k >= sub+s_copyTgtOfs) || (k-16 < sub && k-16 >= sub+s_copyTgtOfs)))
|
||||
k += 1;
|
||||
else if (s_copyTgtOfs > 0 && ((k > sub && k <= sub+s_copyTgtOfs) || (k+16 > sub && k+16 <= sub+s_copyTgtOfs)))
|
||||
k += 15;
|
||||
}
|
||||
|
||||
k %= 16;
|
||||
|
||||
if (EFile::exists(FILE_MODEL(k))) {
|
||||
uint16_t size = eeLoadModelName(k, name);
|
||||
putsModelName(4*FW, y, name, k, 0);
|
||||
lcd_outdezAtt(20*FW, y, size, 0);
|
||||
if (k==g_eeGeneral.currModel && (s_copySrcRow<0 || i+s_pgOfs!=sub)) lcd_putc(1, y, '*');
|
||||
}
|
||||
if (k==g_eeGeneral.currModel) lcd_putc(1, y, '*');
|
||||
if (s_copyMode && k==sub) {
|
||||
if (s_copyMode == COPY_MODE)
|
||||
lcd_putc(20*FW+2, y, '+');
|
||||
lcd_rect(8, y-1, DISPLAY_W-1-7, 9, s_copyMode == COPY_MODE ? 0xff : 0x55);
|
||||
|
||||
if (s_copyMode && sub==i+s_pgOfs) {
|
||||
lcd_filled_rect(9, y, DISPLAY_W-1-9, 7);
|
||||
lcd_rect(8, y-1, DISPLAY_W-1-7, 9, s_copyMode == COPY_MODE ? 0xff : 0x55);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-81
@@ -29,9 +29,6 @@
|
||||
|
||||
RlcFile theFile; //used for any file operation
|
||||
|
||||
#define FILE_TYP_GENERAL 1
|
||||
#define FILE_TYP_MODEL 2
|
||||
|
||||
void generalDefault()
|
||||
{
|
||||
memset(&g_eeGeneral,0,sizeof(g_eeGeneral));
|
||||
@@ -49,9 +46,7 @@ void generalDefault()
|
||||
g_eeGeneral.calibSpanNeg[i] = 0x180;
|
||||
g_eeGeneral.calibSpanPos[i] = 0x180;
|
||||
}
|
||||
int16_t sum=0;
|
||||
for(int i=0; i<12;i++) sum+=g_eeGeneral.calibMid[i];
|
||||
g_eeGeneral.chkSum = sum;
|
||||
g_eeGeneral.chkSum = (0x200 * 7) + (0x180 * 5);
|
||||
}
|
||||
|
||||
#ifdef TRANSLATIONS
|
||||
@@ -287,6 +282,13 @@ void eeLoadModel(uint8_t id)
|
||||
theFile.openRlc(FILE_MODEL(id));
|
||||
uint16_t sz = theFile.readRlc((uint8_t*)&g_model, sizeof(g_model));
|
||||
|
||||
#ifdef SIMU
|
||||
if (sz > 0 && sz != sizeof(g_model)) {
|
||||
printf("Model data read=%d bytes vs %d bytes\n", sz, sizeof(ModelData));
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sz != sizeof(ModelData)) {
|
||||
// alert("Error Loading Model");
|
||||
modelDefault(id);
|
||||
@@ -302,7 +304,7 @@ void eeLoadModel(uint8_t id)
|
||||
}
|
||||
}
|
||||
|
||||
int8_t eeDuplicateModel(uint8_t id, bool down)
|
||||
int8_t eeFindEmptyModel(uint8_t id, bool down)
|
||||
{
|
||||
int8_t i = id;
|
||||
for (;;) {
|
||||
@@ -310,25 +312,6 @@ int8_t eeDuplicateModel(uint8_t id, bool down)
|
||||
if (!EFile::exists(FILE_MODEL(i))) break;
|
||||
if (i == id) return -1; // no free space in directory left
|
||||
}
|
||||
|
||||
EFile theFile2;
|
||||
theFile2.openRd(FILE_MODEL(id));
|
||||
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
theFile.create(FILE_MODEL(i), FILE_TYP_MODEL, true);
|
||||
#else
|
||||
theFile.create(FILE_MODEL(i), FILE_TYP_MODEL, 600);
|
||||
#endif
|
||||
uint8_t buf[15];
|
||||
uint8_t len;
|
||||
while((len=theFile2.read(buf, 15)))
|
||||
{
|
||||
theFile.write(buf, len);
|
||||
if (errno() != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
theFile.close();
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -346,20 +329,11 @@ void eeReadAll()
|
||||
generalDefault();
|
||||
//alert(PSTR("default ok"));
|
||||
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
theFile.writeRlc(FILE_GENERAL, FILE_TYP_GENERAL,(uint8_t*)&g_eeGeneral,sizeof(EEGeneral), true);
|
||||
#else
|
||||
uint16_t sz = theFile.writeRlc(FILE_GENERAL,FILE_TYP_GENERAL,(uint8_t*)&g_eeGeneral,sizeof(EEGeneral), 200);
|
||||
if(sz!=sizeof(EEGeneral)) alert(PSTR("genwrite error"));
|
||||
#endif
|
||||
|
||||
modelDefault(0);
|
||||
//alert(PSTR("modef ok"));
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
theFile.writeRlc(FILE_MODEL(0), FILE_TYP_MODEL, (uint8_t*)&g_model, sizeof(g_model), true);
|
||||
#else
|
||||
theFile.writeRlc(FILE_MODEL(0), FILE_TYP_MODEL, (uint8_t*)&g_model, sizeof(g_model),200);
|
||||
#endif
|
||||
//alert(PSTR("modwrite ok"));
|
||||
}
|
||||
|
||||
@@ -368,22 +342,13 @@ void eeReadAll()
|
||||
|
||||
|
||||
uint8_t s_eeDirtyMsk;
|
||||
#ifndef EEPROM_ASYNC_WRITE
|
||||
static uint16_t s_eeDirtyTime10ms;
|
||||
#define WRITE_DELAY_10MS 100
|
||||
#endif
|
||||
void eeDirty(uint8_t msk)
|
||||
{
|
||||
s_eeDirtyMsk |= msk;
|
||||
#ifndef EEPROM_ASYNC_WRITE
|
||||
if (msk)
|
||||
s_eeDirtyTime10ms = get_tmr10ms();
|
||||
#endif
|
||||
}
|
||||
|
||||
void eeCheck(bool immediately)
|
||||
{
|
||||
#ifdef EEPROM_ASYNC_WRITE
|
||||
if (immediately) {
|
||||
eeFlush();
|
||||
}
|
||||
@@ -396,41 +361,4 @@ void eeCheck(bool immediately)
|
||||
s_eeDirtyMsk = 0;
|
||||
theFile.writeRlc(FILE_MODEL(g_eeGeneral.currModel), FILE_TYP_MODEL, (uint8_t*)&g_model, sizeof(g_model), immediately);
|
||||
}
|
||||
#else
|
||||
uint8_t msk = s_eeDirtyMsk;
|
||||
if (!msk) return;
|
||||
if( !immediately && ((get_tmr10ms() - s_eeDirtyTime10ms) < WRITE_DELAY_10MS)) return;
|
||||
s_eeDirtyMsk = 0;
|
||||
|
||||
if(msk & EE_GENERAL){
|
||||
if(theFile.writeRlc(FILE_TMP, FILE_TYP_GENERAL, (uint8_t*)&g_eeGeneral,
|
||||
sizeof(EEGeneral),20) == sizeof(EEGeneral))
|
||||
{
|
||||
EFile::swap(FILE_GENERAL,FILE_TMP);
|
||||
}else{
|
||||
if(errno()==ERR_TMO){
|
||||
s_eeDirtyMsk |= EE_GENERAL; //try again
|
||||
s_eeDirtyTime10ms = get_tmr10ms() - WRITE_DELAY_10MS;
|
||||
}else{
|
||||
alert(PSTR("EEPROM overflow"));
|
||||
}
|
||||
}
|
||||
//first finish GENERAL, then MODEL !!avoid Toggle effect
|
||||
}
|
||||
if(msk & EE_MODEL){
|
||||
if(theFile.writeRlc(FILE_TMP, FILE_TYP_MODEL, (uint8_t*)&g_model,
|
||||
sizeof(g_model),20) == sizeof(g_model))
|
||||
{
|
||||
EFile::swap(FILE_MODEL(g_eeGeneral.currModel),FILE_TMP);
|
||||
}else{
|
||||
if(errno()==ERR_TMO){
|
||||
s_eeDirtyMsk |= EE_MODEL; //try again
|
||||
s_eeDirtyTime10ms = get_tmr10ms() - WRITE_DELAY_10MS;
|
||||
}else{
|
||||
alert(PSTR("EEPROM overflow"));
|
||||
}
|
||||
}
|
||||
}
|
||||
//beepWarn1();
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user