void backupEeprom()
{
  char filename[60];
  uint8_t buffer[1024];
  FIL file;

  lcd_clear();
  displayProgressBar(STR_WRITING);

  // reset unexpectedShutdown to prevent warning when user restores EEPROM backup
  g_eeGeneral.unexpectedShutdown = 0;
  eeDirty(EE_GENERAL);
  eeCheck(true);

  // create the directory if needed...
  DIR folder;
  FRESULT result = f_opendir(&folder, EEPROMS_PATH);
  if (result != FR_OK) {
    if (result == FR_NO_PATH)
      result = f_mkdir(EEPROMS_PATH);
    if (result != FR_OK) {
      POPUP_WARNING(SDCARD_ERROR(result));
      return;
    }
  }

  // prepare the filename...
  char * tmp = strAppend(filename, EEPROMS_PATH "/eeprom");
  tmp = strAppendDate(tmp, true);
  strAppend(tmp, EEPROM_EXT);

  // open the file for writing...
  f_open(&file, filename, FA_WRITE | FA_CREATE_ALWAYS);

  for (int i=0; i<EESIZE; i+=1024) {
    UINT count;
    eepromReadBlock(buffer, i, 1024);
    f_write(&file, buffer, 1024, &count);
    updateProgressBar(i, EESIZE);
    SIMU_SLEEP(100/*ms*/);
  }

  f_close(&file);

  //set back unexpectedShutdown
  g_eeGeneral.unexpectedShutdown = 1;
  eeDirty(EE_GENERAL);
  eeCheck(true);
}
Beispiel #2
0
bool eeCopyModel(uint8_t dst, uint8_t src)
{
  eeCheck(true);

  uint32_t eepromWriteSourceAddr = eepromHeader.files[src+1].zoneIndex * EEPROM_ZONE_SIZE;
  uint32_t eepromWriteDestinationAddr = eepromHeader.files[dst+1].zoneIndex * EEPROM_ZONE_SIZE;

  // erase blocks
  eepromEraseBlock(eepromWriteDestinationAddr);
  eepromEraseBlock(eepromWriteDestinationAddr+EEPROM_BLOCK_SIZE);

  // write model
  for (int pos=0; pos<EEPROM_ZONE_SIZE; pos+=EEPROM_BUFFER_SIZE) {
    eepromRead(eepromWriteSourceAddr+pos, eepromWriteBuffer, EEPROM_BUFFER_SIZE);
    eepromWrite(eepromWriteDestinationAddr+pos, eepromWriteBuffer, EEPROM_BUFFER_SIZE);
  }

  // write FAT
  eepromHeader.files[dst+1].exists = 1;
  eepromIncFatAddr();
  eepromWriteState = EEPROM_WRITE_NEW_FAT;
  eepromWriteWait();

  modelHeaders[dst] = modelHeaders[src];

  return true;
}
Beispiel #3
0
void eeDeleteModel(uint8_t index)
{
  eeCheck(true);
  memclear(&modelHeaders[index], sizeof(ModelHeader));
  writeFile(index+1, (uint8_t *)&g_model, 0);
  eepromWriteWait();
}
Beispiel #4
0
void eeLoadModel(uint8_t id)
{
  if(id<MAX_MODELS)
  {
    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, (int)sizeof(ModelData));
    }
#endif

    if (sz < 730/*sizeof(last compatible eeprom)*/) {
      modelDefault(id);
      eeCheck(true);
    }

    resetTimer1();
    resetTimer2();
    resetProto();
#ifdef TELEMLOGS
    initTelemLog();
#endif
  }
}
Beispiel #5
0
void checkEeprom()
{
  if (!usbPlugged()) {
    if (eepromIsWriting())
      eepromWriteProcess();
    else if (TIME_TO_WRITE())
      eeCheck(false);
  }
}
Beispiel #6
0
void eeLoadModel(uint8_t id)
{
  if (id<MAX_MODELS) {

#if defined(SDCARD)
    closeLogs();
#endif

    if (pulsesStarted()) {
      pausePulses();
    }

    pauseMixerCalculations();

    uint32_t size = loadModel(id);

#if defined(SIMU)
    if (sizeof(uint16_t) + sizeof(g_model) > EEPROM_ZONE_SIZE)
      TRACE("Model data size can't exceed %d bytes (%d bytes)", int(EEPROM_ZONE_SIZE-sizeof(uint16_t)), (int)sizeof(g_model));
    if (size > 0 && size != sizeof(g_model))
      TRACE("Model data read=%d bytes vs %d bytes\n", size, (int)sizeof(ModelData));
#endif

    if (size < EEPROM_BUFFER_SIZE) { // if not loaded a fair amount
      modelDefault(id) ;
      eeCheck(true);
    }

    AUDIO_FLUSH();
    flightReset();
    logicalSwitchesReset();

    if (pulsesStarted()) {
      checkAll();
      resumePulses();
    }

    customFunctionsReset();

    restoreTimers();

    resumeMixerCalculations();
    // TODO pulses should be started after mixer calculations ...

#if defined(FRSKY)
    frskySendAlarms();
#endif

#if defined(SDCARD)
    referenceModelAudioFiles();
#endif

    LOAD_MODEL_BITMAP();
    SEND_FAILSAFE_1S();
    PLAY_MODEL_NAME();
  }
}
Beispiel #7
0
void eeDeleteModel(uint8_t id)
{
  eeCheck(true);

  memset(modelHeaders[id].name, 0, sizeof(g_model.header.name));

  Eeprom32_source_address = (uint8_t *)&g_model ;   // Get data from here
  Eeprom32_data_size = 0 ;                          // This much
  Eeprom32_file_index = id + 1 ;                    // This file system entry
  Eeprom32_process_state = E32_BLANKCHECK ;
  eeWaitFinished();
}
Beispiel #8
0
void eeWaitComplete()
{
  while(s_eeDirtyMsk)
  {
		eeCheck(true) ;
    if(heartbeat == 0x3)
    {
      wdt_reset();
      heartbeat = 0;
    }
  }
}
Beispiel #9
0
void onModelSelectMenu(const char *result)
{
  int8_t sub = m_posVert;

  if (result == STR_SELECT_MODEL || result == STR_CREATE_MODEL) {
    selectModel(sub);
  }
  else if (result == STR_COPY_MODEL) {
    s_copyMode = COPY_MODE;
    s_copyTgtOfs = 0;
    s_copySrcRow = -1;
  }
  else if (result == STR_MOVE_MODEL) {
    s_copyMode = MOVE_MODE;
    s_copyTgtOfs = 0;
    s_copySrcRow = -1;
  }
#if defined(SDCARD)
  else if (result == STR_BACKUP_MODEL) {
    eeCheck(true); // force writing of current model data before this is changed
    POPUP_WARNING(eeBackupModel(sub));
  }
  else if (result == STR_RESTORE_MODEL || result == STR_UPDATE_LIST) {
    if (!listSdFiles(MODELS_PATH, MODELS_EXT, MENU_LINE_LENGTH-1, NULL)) {
      POPUP_WARNING(STR_NO_MODELS_ON_SD);
      s_menu_flags = 0;
    }
  }
#endif
  else if (result == STR_DELETE_MODEL) {
    POPUP_CONFIRMATION(STR_DELETEMODEL);
#if defined(CPUARM)
    SET_WARNING_INFO(modelHeaders[sub].name, sizeof(g_model.header.name), ZCHAR);
#else
    char * name = reusableBuffer.modelsel.mainname;
    eeLoadModelName(sub, name);
    SET_WARNING_INFO(name, sizeof(g_model.header.name), ZCHAR);
#endif
  }
#if defined(SDCARD)
  else {
    // The user choosed a file on SD to restore
    POPUP_WARNING(eeRestoreModel(sub, (char *)result));
    if (!s_warning && g_eeGeneral.currModel == sub) {
      eeLoadModel(sub);
    }
  }
#endif
}
Beispiel #10
0
void eeErase(bool warn)
{
  generalDefault();
  modelDefault(0);

  if (warn) {
    ALERT(STR_EEPROMWARN, STR_BADEEPROMDATA, AU_BAD_EEPROM);
  }

  MESSAGE(STR_EEPROMWARN, STR_EEPROMFORMATTING, NULL, AU_EEPROM_FORMATTING);

  eepromFormat();
  eeDirty(EE_GENERAL);
  eeDirty(EE_MODEL);
  eeCheck(true);
}
Beispiel #11
0
void eeSwapModels(uint8_t id1, uint8_t id2)
{
  eeCheck(true);
  {
    EepromHeaderFile tmp = eepromHeader.files[id1+1];
    eepromHeader.files[id1+1] = eepromHeader.files[id2+1];
    eepromHeader.files[id2+1] = tmp;
  }
  eepromIncFatAddr();
  eepromWriteState = EEPROM_WRITE_NEW_FAT;
  eepromWriteWait();

  {
    ModelHeader tmp = modelHeaders[id1];
    modelHeaders[id1] = modelHeaders[id2];
    modelHeaders[id2] = tmp;
  }
}
Beispiel #12
0
const pm_char * eeRestoreModel(uint8_t i_fileDst, char *model_name)
{
  char *buf = reusableBuffer.modelsel.mainname;
  FIL restoreFile;
  UINT read;

  eeCheck(true);

  if (!sdMounted()) {
    return STR_NO_SDCARD;
  }

  strcpy(buf, STR_MODELS_PATH);
  buf[sizeof(MODELS_PATH)-1] = '/';
  strcpy(&buf[sizeof(MODELS_PATH)], model_name);
  strcpy(&buf[strlen(buf)], STR_MODELS_EXT);

  FRESULT result = f_open(&restoreFile, buf, FA_OPEN_EXISTING | FA_READ);
  if (result != FR_OK) {
    return SDCARD_ERROR(result);
  }

  if (f_size(&restoreFile) < 8) {
    f_close(&restoreFile);
    return STR_INCOMPATIBLE;
  }

  result = f_read(&restoreFile, (uint8_t *)buf, 8, &read);
  if (result != FR_OK || read != 8) {
    f_close(&restoreFile);
    return SDCARD_ERROR(result);
  }

  uint8_t version = (uint8_t)buf[4];
  if (*(uint32_t*)&buf[0] != O9X_FOURCC || version < FIRST_CONV_EEPROM_VER || version > EEPROM_VER || buf[5] != 'M') {
    f_close(&restoreFile);
    return STR_INCOMPATIBLE;
  }

  if (eeModelExists(i_fileDst)) {
    eeDeleteModel(i_fileDst);
  }

  uint16_t size = min<uint16_t>(sizeof(g_model), *(uint16_t*)&buf[6]);
  uint32_t address = eepromHeader.files[i_fileDst+1].zoneIndex * EEPROM_ZONE_SIZE;

  // erase blocks
  eepromEraseBlock(address);
  eepromEraseBlock(address+EEPROM_BLOCK_SIZE);

  // write header
  EepromFileHeader * header = (EepromFileHeader *)eepromWriteBuffer;
  header->fileIndex = i_fileDst+1;
  header->size = size;

  int offset = 4;

  // write model
  do {
    uint16_t blockSize = min<uint16_t>(size, EEPROM_BUFFER_SIZE-offset);
    result = f_read(&restoreFile, eepromWriteBuffer+offset, blockSize, &read);
    if (result != FR_OK || read != blockSize) {
      f_close(&g_oLogFile);
      return SDCARD_ERROR(result);
    }
    eepromWrite(address, eepromWriteBuffer, blockSize+offset);
    size -= blockSize;
    address += EEPROM_BUFFER_SIZE;
    offset = 0;
  } while (size > 0);

  // write FAT
  eepromHeader.files[i_fileDst+1].exists = 1;
  eepromIncFatAddr();
  eepromWriteState = EEPROM_WRITE_NEW_FAT;
  eepromWriteWait();

  eeLoadModelHeader(i_fileDst, &modelHeaders[i_fileDst]);

#if defined(PCBSKY9X)
  if (version < EEPROM_VER) {
    ConvertModel(i_fileDst, version);
    loadModel(g_eeGeneral.currModel);
  }
#endif

  return NULL;
}
Beispiel #13
0
const pm_char * eeBackupModel(uint8_t i_fileSrc)
{
  char *buf = reusableBuffer.modelsel.mainname;
  FIL archiveFile;
  DIR archiveFolder;
  UINT written;

  eeCheck(true);

  if (!sdMounted()) {
    return STR_NO_SDCARD;
  }

  // check and create folder here
  strcpy(buf, STR_MODELS_PATH);
  FRESULT result = f_opendir(&archiveFolder, buf);
  if (result != FR_OK) {
    if (result == FR_NO_PATH)
      result = f_mkdir(buf);
    if (result != FR_OK)
      return SDCARD_ERROR(result);
  }
  else {
    f_closedir(&archiveFolder);
  }

  buf[sizeof(MODELS_PATH)-1] = '/';
  strcpy(strcat_modelname(&buf[sizeof(MODELS_PATH)], i_fileSrc), STR_MODELS_EXT);

  result = f_open(&archiveFile, buf, FA_CREATE_ALWAYS | FA_WRITE);
  if (result != FR_OK) {
    return SDCARD_ERROR(result);
  }

#if defined(PCBSKY9X)
  strcpy(statusLineMsg, PSTR("File "));
  strcpy(statusLineMsg+5, &buf[sizeof(MODELS_PATH)]);
#endif

  uint16_t size = eeModelSize(i_fileSrc);

  *(uint32_t*)&buf[0] = O9X_FOURCC;
  buf[4] = g_eeGeneral.version;
  buf[5] = 'M';
  *(uint16_t*)&buf[6] = size;

  result = f_write(&archiveFile, buf, 8, &written);
  if (result != FR_OK || written != 8) {
    f_close(&archiveFile);
    return SDCARD_ERROR(result);
  }

  uint32_t address = eepromHeader.files[i_fileSrc+1].zoneIndex * EEPROM_ZONE_SIZE + sizeof(EepromFileHeader);
  while (size > 0) {
    uint16_t blockSize = min<uint16_t>(size, EEPROM_BUFFER_SIZE);
    eepromRead(address, eepromWriteBuffer, blockSize);
    result = f_write(&archiveFile, eepromWriteBuffer, blockSize, &written);
    if (result != FR_OK || written != blockSize) {
      f_close(&archiveFile);
      return SDCARD_ERROR(result);
    }
    size -= blockSize;
    address += blockSize;
  }

  f_close(&archiveFile);

#if defined(PCBSKY9X)
  showStatusLine();
#endif

  return NULL;
}
Beispiel #14
0
void menuModelSelect(uint8_t event)
{
  if (s_warning_result) {
    s_warning_result = 0;
    eeDeleteModel(m_posVert); // delete file
    s_copyMode = 0;
    event = EVT_ENTRY_UP;
  }

  uint8_t _event_ = (IS_ROTARY_BREAK(event) || IS_ROTARY_LONG(event) ? 0 : event);

  if ((s_copyMode && EVT_KEY_MASK(event) == KEY_EXIT) || event == EVT_KEY_BREAK(KEY_EXIT)) {
    _event_ -= KEY_EXIT;
  }

  int8_t oldSub = m_posVert;

  check_submenu_simple(_event_, MAX_MODELS-1);

#if defined(NAVIGATION_POT2)
  if (event==0 && p2valdiff<0) {
    event = EVT_KEY_FIRST(KEY_RIGHT);
  }
#endif

  if (s_editMode > 0) s_editMode = 0;

#if !defined(CPUARM)
  if (event) {
    eeFlush(); // flush eeprom write
  }
#endif

  int8_t sub = m_posVert;

  switch (event)
  {
      case EVT_ENTRY:
        m_posVert = sub = g_eeGeneral.currModel;
        if (sub >= LCD_LINES-1) s_pgOfs = sub-LCD_LINES+2;
        s_copyMode = 0;
        s_editMode = EDIT_MODE_INIT;
        eeCheck(true);
        break;

      case EVT_KEY_LONG(KEY_EXIT):
        killEvents(event);
        if (s_copyMode && s_copyTgtOfs == 0 && g_eeGeneral.currModel != sub && eeModelExists(sub)) {
          POPUP_CONFIRMATION(STR_DELETEMODEL);
#if defined(CPUARM)
          SET_WARNING_INFO(modelHeaders[sub].name, sizeof(g_model.header.name), ZCHAR);
#else
          char * name = reusableBuffer.modelsel.mainname;
          eeLoadModelName(sub, name);
          SET_WARNING_INFO(name, sizeof(g_model.header.name), ZCHAR);
#endif
        }
        else {
          s_copyMode = 0;
          m_posVert = g_eeGeneral.currModel;
        }
        break;

#if defined(ROTARY_ENCODER_NAVIGATION)
      case EVT_ROTARY_LONG:
        killEvents(event);
        if (s_editMode < 0) {
          popMenu();
          break;
        }
        else if (!s_copyMode) {
          m_posVert = sub = g_eeGeneral.currModel;
          s_copyMode = 0;
          s_editMode = EDIT_MODE_INIT;
        }
        // no break
#endif

      case EVT_KEY_BREAK(KEY_EXIT):
        if (s_copyMode) {
          sub = m_posVert = (s_copyMode == MOVE_MODE || s_copySrcRow<0) ? (MAX_MODELS+sub+s_copyTgtOfs) % MAX_MODELS : s_copySrcRow;
          s_copyMode = 0;
        }
        else if (m_posVert != g_eeGeneral.currModel) {
          m_posVert = g_eeGeneral.currModel;
        }
        else {
          popMenu();
        }
        break;

#if defined(ROTARY_ENCODER_NAVIGATION)
      case EVT_ROTARY_BREAK:
        if (s_editMode == -1) {
          s_editMode = 0;
          break;
        }
        // no break;
#endif

      case EVT_KEY_LONG(KEY_ENTER):
      case EVT_KEY_BREAK(KEY_ENTER):
        s_editMode = 0;
        if (READ_ONLY()) {
          if (g_eeGeneral.currModel != sub && eeModelExists(sub)) {
            selectModel(sub);
          }
        }
        else if (s_copyMode && (s_copyTgtOfs || s_copySrcRow>=0)) {
          displayPopup(s_copyMode==COPY_MODE ? STR_COPYINGMODEL : STR_MOVINGMODEL);
          eeCheck(true); // force writing of current model data before this is changed

          uint8_t cur = (MAX_MODELS + sub + s_copyTgtOfs) % MAX_MODELS;

          if (s_copyMode == COPY_MODE) {
            if (!eeCopyModel(cur, 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+MAX_MODELS-1 : cur+1) % MAX_MODELS;
            eeSwapModels(src, 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;
            eeDirty(EE_GENERAL);
          }

          s_copyMode = 0;
          event = EVT_ENTRY_UP;
        }
        else if (event == EVT_KEY_LONG(KEY_ENTER) || IS_ROTARY_BREAK(event)) {
          s_copyMode = 0;
          killEvents(event);
#if defined(NAVIGATION_MENUS)
          if (g_eeGeneral.currModel != sub) {
            if (eeModelExists(sub)) {
              MENU_ADD_ITEM(STR_SELECT_MODEL);
              MENU_ADD_SD_ITEM(STR_BACKUP_MODEL);
              MENU_ADD_ITEM(STR_COPY_MODEL);
              MENU_ADD_ITEM(STR_MOVE_MODEL);
              MENU_ADD_ITEM(STR_DELETE_MODEL);
            }
            else {
#if defined(SDCARD)
              MENU_ADD_ITEM(STR_CREATE_MODEL);
              MENU_ADD_ITEM(STR_RESTORE_MODEL);
#else
              selectModel(sub);
#endif
            }
          }
          else {
            MENU_ADD_SD_ITEM(STR_BACKUP_MODEL);
            MENU_ADD_ITEM(STR_COPY_MODEL);
            MENU_ADD_ITEM(STR_MOVE_MODEL);
          }
          menuHandler = onModelSelectMenu;
#else
          if (g_eeGeneral.currModel != sub) {
            selectModel(sub);
          }
#endif
        }
        else if (eeModelExists(sub)) {
          s_copyMode = (s_copyMode == COPY_MODE ? MOVE_MODE : COPY_MODE);
          s_copyTgtOfs = 0;
          s_copySrcRow = -1;
        }
        break;

#if defined(ROTARY_ENCODER_NAVIGATION)
      case EVT_ROTARY_LEFT:
      case EVT_ROTARY_RIGHT:
#endif
      case EVT_KEY_FIRST(KEY_LEFT):
      case EVT_KEY_FIRST(KEY_RIGHT):
#if defined(ROTARY_ENCODER_NAVIGATION)
        if ((!IS_ROTARY_RIGHT(event) && !IS_ROTARY_LEFT(event)) || s_editMode < 0) {
#endif
        if (sub == g_eeGeneral.currModel) {
          chainMenu((IS_ROTARY_RIGHT(event) || event == EVT_KEY_FIRST(KEY_RIGHT)) ? menuModelSetup : menuTabModel[DIM(menuTabModel)-1]);
        }
        else {
          AUDIO_WARNING2();
        }
        break;
#if defined(ROTARY_ENCODER_NAVIGATION)
        }
        // no break
#endif

      case EVT_KEY_FIRST(KEY_MOVE_UP):
      case EVT_KEY_REPT(KEY_MOVE_UP):
      case EVT_KEY_FIRST(KEY_MOVE_DOWN):
      case EVT_KEY_REPT(KEY_MOVE_DOWN):
        if (s_copyMode) {
          int8_t next_ofs = s_copyTgtOfs + oldSub - m_posVert;
          if (next_ofs == MAX_MODELS || next_ofs == -MAX_MODELS)
            next_ofs = 0;

          if (s_copySrcRow < 0 && s_copyMode==COPY_MODE) {
            s_copySrcRow = oldSub;
            // find a hole (in the first empty slot above / below)
            sub = eeFindEmptyModel(s_copySrcRow, IS_ROTARY_DOWN(event) || event==EVT_KEY_FIRST(KEY_MOVE_DOWN));
            if (sub < 0) {
              // no free room for duplicating the model
              AUDIO_ERROR();
              sub = oldSub;
              s_copyMode = 0;
            }
            next_ofs = 0;
            m_posVert = sub;
          }
          s_copyTgtOfs = next_ofs;
        }
        break;
  }

#if !defined(PCBSKY9X)
  lcd_puts(9*FW-(LEN_FREE-4)*FW, 0, STR_FREE);
  if (event) reusableBuffer.modelsel.eepromfree = EeFsGetFree();
  lcd_outdezAtt(17*FW, 0, reusableBuffer.modelsel.eepromfree, 0);
#endif

#if defined(ROTARY_ENCODER_NAVIGATION)
  displayScreenIndex(e_ModelSelect, DIM(menuTabModel), (sub == g_eeGeneral.currModel) ? ((IS_RE_NAVIGATION_ENABLE() && s_editMode < 0) ? INVERS|BLINK : INVERS) : 0);
#else
  displayScreenIndex(e_ModelSelect, DIM(menuTabModel), (sub == g_eeGeneral.currModel) ? INVERS : 0);
#endif

  TITLE(STR_MENUMODELSEL);

  for (uint8_t i=0; i<LCD_LINES-1; i++) {
    coord_t y = MENU_HEADER_HEIGHT + 1 + i*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(MODELSEL_W-FW, y, '+');
        }
        else {
          k = sub + s_copyTgtOfs;
        }
      }
      else if (s_copyTgtOfs < 0 && ((k < sub && k >= sub+s_copyTgtOfs) || (k-MAX_MODELS < sub && k-MAX_MODELS >= sub+s_copyTgtOfs)))
        k += 1;
      else if (s_copyTgtOfs > 0 && ((k > sub && k <= sub+s_copyTgtOfs) || (k+MAX_MODELS > sub && k+MAX_MODELS <= sub+s_copyTgtOfs)))
        k += MAX_MODELS-1;
    }

    k %= MAX_MODELS;

    if (eeModelExists(k)) {
#if defined(PCBSKY9X)
      putsModelName(4*FW, y, modelHeaders[k].name, k, 0);
#else
      char * name = reusableBuffer.modelsel.listnames[i];
      if (event) eeLoadModelName(k, name);
      putsModelName(4*FW, y, name, k, 0);
      lcd_outdezAtt(20*FW, y, eeModelSize(k), 0);
#endif
      if (k==g_eeGeneral.currModel && (s_copyMode!=COPY_MODE || s_copySrcRow<0 || i+s_pgOfs!=(vertpos_t)sub))
        lcd_putc(1, y, '*');
    }

    if (s_copyMode && (vertpos_t)sub==i+s_pgOfs) {
      drawFilledRect(9, y, MODELSEL_W-1-9, 7);
      lcd_rect(8, y-1, MODELSEL_W-1-7, 9, s_copyMode == COPY_MODE ? SOLID : DOTTED);
    }
  }
}
Beispiel #15
0
void eeLoadModel(uint8_t id)
{
  if (id<MAX_MODELS) {

#if defined(SDCARD)
    closeLogs();
#endif

    if (pulsesStarted()) {
      pausePulses();
    }

    pauseMixerCalculations();

    uint16_t size = File_system[id+1].size ;

    memset(&g_model, 0, sizeof(g_model));

#if defined(SIMU)
    if (sizeof(struct t_eeprom_header) + sizeof(g_model) > 4096)
      TRACE("Model data size can't exceed %d bytes (%d bytes)", int(4096-sizeof(struct t_eeprom_header)), (int)sizeof(g_model));
    else if (size > 0 && size != sizeof(g_model))
      TRACE("Model data read=%d bytes vs %d bytes\n", size, (int)sizeof(ModelData));
#endif

    if (size > sizeof(g_model)) {
      size = sizeof(g_model) ;
    }

    if(size < 256) { // if not loaded a fair amount
      modelDefault(id) ;
      eeCheck(true);
    }
    else {
      read32_eeprom_data((File_system[id+1].block_no << 12) + sizeof(struct t_eeprom_header), (uint8_t *)&g_model, size) ;
    }

    AUDIO_FLUSH();
    flightReset();
    logicalSwitchesReset();

    if (pulsesStarted()) {
      checkAll();
      resumePulses();
    }

    activeFnSwitches = 0;
    activeFunctions = 0;
    memclear(lastFunctionTime, sizeof(lastFunctionTime));

    restoreTimers();

    resumeMixerCalculations();
    // TODO pulses should be started after mixer calculations ...

#if defined(FRSKY)
    frskySendAlarms();
#endif

#if defined(CPUARM) && defined(SDCARD)
    referenceModelAudioFiles();
#endif

    LOAD_MODEL_BITMAP();

    SEND_FAILSAFE_1S();
  }
}