Exemple #1
0
int main()
{
  uint8_t index = 0;
  uint8_t maxhsize = DISPLAY_CHAR_WIDTH;
  FRESULT fr;
  uint32_t state = ST_START;
  uint32_t nameCount = 0;
  uint32_t vpos = 0;
  uint32_t hpos = 0;

#if defined(PCBTARANIS)
  wdt_reset();
  RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; 		// Enable portA clock
#endif

  pwrInit();

#if defined(PCBSKY9X)
  MATRIX->CCFG_SYSIO |= 0x000000F0L;		// Disable syspins, enable B4,5,6,7
#endif

#if defined(PCBSKY9X)
  init_SDcard();
  PIOC->PIO_PER = PIO_PC25;		// Enable bit C25 (USB-detect)
  start_timer0();
#endif

  lcdInit();
#if defined(PCBSKY9X)
  extern uint8_t OptrexDisplay;
  OptrexDisplay = 1;
#endif
  lcd_clear();
  lcd_putsLeft(0, BOOTLOADER_TITLE);
  lcd_invert_line(0);
  lcdRefresh();
#if defined(PCBSKY9X)
  OptrexDisplay = 0;
  lcdRefresh();
#endif

#if defined(PCBTARANIS)
  keysInit();
  I2C_EE_Init();
  init_hw_timer();
#endif

  __enable_irq();
  init10msTimer();

#if defined(PCBSKY9X)
  EblockAddress = -1;
  init_spi();
#endif

#if defined(PCBSKY9X)
  LockBits = readLockBits();
  if (LockBits) {
    clearLockBits();
  }
#endif

#if defined(PCBTARANIS)
  // SD card detect pin
  sdInit();
  usbInit();
  usbStart();
#endif

  for (;;) {
    wdt_reset();

    if (Tenms) {

      if (EE_timer) {
        if (--EE_timer == 0) {
#if defined(PCBSKY9X)
          writeBlock();
#endif
        }
      }

      Tenms = 0;

      lcd_clear();
      lcd_putsLeft(0, BOOTLOADER_TITLE);
      lcd_invert_line(0);

      uint8_t event = getEvent();

      if (state != ST_USB) {
        if (usbPlugged()) {
          state = ST_USB;
          if (!unlocked) {
            unlocked = 1;
            unlockFlash();
          }
          usbPluggedIn();
        }
      }

      if (state == ST_START) {
        lcd_putsLeft(2*FH, "\010Write Firmware");
        lcd_putsLeft(3*FH, "\010Restore EEPROM");
        lcd_putsLeft(4*FH, "\010Exit");
        lcd_invert_line(2+vpos);
        lcd_putsLeft(7*FH, INDENT "Or plug in a USB cable for mass storage");
        if (event == EVT_KEY_FIRST(BOOT_KEY_DOWN)) {
          vpos == 2 ? vpos = 0 : vpos = vpos+1;
        }
        else if (event == EVT_KEY_FIRST(BOOT_KEY_UP)) {
          vpos == 0 ? vpos = 2 : vpos = vpos-1;
        }
        else if (event == EVT_KEY_BREAK(BOOT_KEY_MENU)) {
          switch (vpos) {
            case 0:
              state = ST_FLASH_MENU;
              break;
            case 1:
              state = ST_RESTORE_MENU;
              break;
            default:
              state = ST_REBOOT;
          }
        }
      }

      if (state == ST_USB) {
        lcd_putsLeft(4*FH, "\026USB Connected");
        if (usbPlugged() == 0) {
          vpos = 0;
          if (unlocked) {
            lockFlash();
            unlocked = 0;
          }
          state = ST_START;
        }
#if defined(PCBSKY9X)
        usbMassStorage();
#endif
      }

      if (state == ST_FLASH_MENU || state == ST_RESTORE_MENU) {
        sdInit();
        memoryType = (state == ST_RESTORE_MENU ? MEM_EEPROM : MEM_FLASH);
        state = ST_DIR_CHECK;
      }

      else if (state == ST_DIR_CHECK) {
        fr = f_chdir(getBinaryPath());
        if (fr == FR_OK) {
          state = ST_OPEN_DIR;
        }
        else {
          lcd_putsLeft(2*FH, INDENT "Directory is missing!");
          if (event == EVT_KEY_BREAK(BOOT_KEY_EXIT) || event == EVT_KEY_BREAK(BOOT_KEY_MENU)) {
            vpos = 0;
            state = ST_START;
          }
        }
      }

      if (state == ST_OPEN_DIR) {
        index = 0;
        fr = f_opendir(&Dj, ".");
        if (fr == FR_OK) {
          state = ST_FILE_LIST;
          nameCount = fillNames(0);
          hpos = 0;
          vpos = 0;
        }
      }

      if (state == ST_FILE_LIST) {
        uint32_t limit = 6;
        if (nameCount < limit) {
          limit = nameCount;
        }
        maxhsize = 0;
        for (uint32_t i=0; i<limit; i++) {
          uint32_t x;
          x = strlen(Filenames[i]);
          if (x > maxhsize) {
            maxhsize = x;
          }
          if (x > DISPLAY_CHAR_WIDTH) {
            if (hpos + DISPLAY_CHAR_WIDTH > x) {
              x = x - DISPLAY_CHAR_WIDTH;
            }
            else {
              x = hpos;
            }
          }
          else {
            x = 0;
          }
          lcd_putsnAtt(INDENT_WIDTH, 16 + FH * i, &Filenames[i][x], DISPLAY_CHAR_WIDTH, 0);
        }

        if (event == EVT_KEY_REPT(BOOT_KEY_DOWN) || event == EVT_KEY_FIRST(BOOT_KEY_DOWN)) {
          if (vpos < limit - 1) {
            vpos += 1;
          }
          else {
            if (nameCount > limit) {
              index += 1;
              nameCount = fillNames(index);
            }
          }
        }
        else if (event == EVT_KEY_REPT(BOOT_KEY_UP) || event == EVT_KEY_FIRST(BOOT_KEY_UP)) {
          if (vpos > 0) {
            vpos -= 1;
          }
          else {
            if (index) {
              index -= 1;
              nameCount = fillNames(index);
            }
          }
        }
#if !defined(PCBTARANIS)
        else if (event == EVT_KEY_REPT(BOOT_KEY_RIGHT) || event == EVT_KEY_FIRST(BOOT_KEY_RIGHT)) {
          if (hpos + DISPLAY_CHAR_WIDTH < maxhsize) {
            hpos += 1;
          }
        }
        else if (event == EVT_KEY_REPT(BOOT_KEY_LEFT) || event == EVT_KEY_FIRST(BOOT_KEY_LEFT)) {
          if (hpos) {
            hpos -= 1;
          }
        }
#endif
        else if (event == EVT_KEY_BREAK(BOOT_KEY_MENU)) {
          // Select file to flash
          state = ST_FLASH_CHECK;
          Valid = 0;
        }
        else if (event == EVT_KEY_FIRST(BOOT_KEY_EXIT)) {
          state = ST_START;
          vpos = 0;
        }

        lcd_invert_line(2 + vpos);
      }

      else if (state == ST_FLASH_CHECK) {
        int result = menuFlashFile(vpos, event);
        FirmwareSize = FileSize[vpos] - BOOTLOADER_SIZE;
        if (result == 0) {
          // canceled
          state = ST_FILE_LIST;
        }
        else if (result == 1) {
          // confirmed
          firmwareAddress = FIRMWARE_ADDRESS + BOOTLOADER_SIZE;
          firmwareWritten = 0;
          eepromAddress = 0;
          eepromWritten = 0;
          state = ST_FLASHING;
        }
      }

      else if (state == ST_FLASHING) {
        // commit to flashing
        lcd_putsLeft(4*FH, "\032Writing...");
        
        if (!unlocked && (memoryType == MEM_FLASH)) {
          unlocked = 1;
          unlockFlash();
        }
        
        int progress;
        if (memoryType == MEM_FLASH) {
          writeFlashBlock();
          firmwareWritten += sizeof(Block_buffer);
          progress = (200*firmwareWritten) / FirmwareSize;
        }
        else {
          writeEepromBlock();
          eepromWritten += sizeof(Block_buffer);
          progress = (200*eepromWritten) / EESIZE;
        }

        lcd_rect( 3, 6*FH+4, 204, 7);
        lcd_hline(5, 6*FH+6, progress, FORCE);
        lcd_hline(5, 6*FH+7, progress, FORCE);
        lcd_hline(5, 6*FH+8, progress, FORCE);

        fr = f_read(&FlashFile, (BYTE *)Block_buffer, sizeof(Block_buffer), &BlockCount);
        if (BlockCount == 0) {
          state = ST_FLASH_DONE; // EOF
        }
        if (firmwareWritten >= FLASHSIZE - BOOTLOADER_SIZE) {
          state = ST_FLASH_DONE; // Backstop
        }
        if (eepromWritten >= EESIZE) {
          state = ST_FLASH_DONE; // Backstop
        }
      }

      if (state == ST_FLASH_DONE) {
        if (unlocked) {
          lockFlash();
          unlocked = 0;
        }
        lcd_putsLeft(4*FH, "\024Writing Complete");
        if (event == EVT_KEY_FIRST(BOOT_KEY_EXIT) || event == EVT_KEY_BREAK(BOOT_KEY_MENU)) {
          state = ST_START;
          vpos = 0;
        }
      }

      if (event == EVT_KEY_LONG(BOOT_KEY_EXIT)) {
        state = ST_REBOOT;
      }

      lcdRefresh();

      if (PowerUpDelay < 20) {	// 200 mS
        PowerUpDelay += 1;
      }
      else {
        sdPoll10ms();
      }
    }

    if (pwrCheck() == e_power_off && state != ST_FLASHING && state != ST_USB) {
      pwrOff();
      for (;;) {
        // Wait for power to go off
      }
    }

    if (state == ST_REBOOT) {
      if ((~readKeys() & 0x7E) == 0) {
        NVIC_SystemReset();
      }
    }
  }

  return 0;
}
Exemple #2
0
int main()
{
  uint8_t index = 0;
  uint8_t maxhsize = DISPLAY_CHAR_WIDTH;
  FRESULT fr;
  uint32_t state = ST_START;
  uint32_t nameCount = 0;
  uint32_t vpos = 0;
  uint32_t hpos = 0;

#if defined(PCBTARANIS)
  wdt_reset();
  RCC_AHB1PeriphClockCmd(PWR_RCC_AHB1Periph | KEYS_RCC_AHB1Periph | LCD_RCC_AHB1Periph | BACKLIGHT_RCC_AHB1Periph | I2C_RCC_AHB1Periph | SD_RCC_AHB1Periph, ENABLE);
  RCC_APB1PeriphClockCmd(LCD_RCC_APB1Periph | BACKLIGHT_RCC_APB1Periph | INTERRUPT_5MS_APB1Periph | I2C_RCC_APB1Periph | SD_RCC_APB1Periph, ENABLE);
  RCC_APB2PeriphClockCmd(BACKLIGHT_RCC_APB2Periph, ENABLE);
#endif

  pwrInit();
  delaysInit();               //needed for lcdInit()
  lcdInit();
  backlightInit();

  lcd_clear();
  lcd_putsn(0, 0, (const char *)bootloaderVersion, 0); // trick to avoid bootloaderVersion to be optimized out ...
  lcd_putsLeft(0, BOOTLOADER_TITLE);
  lcd_invert_line(0);
  lcdRefresh();

  keysInit();
  i2cInit();

  __enable_irq();
  init10msTimer();

#if defined(PCBTARANIS)
  // SD card detect pin
  sdInit();
  usbInit();
#endif

  for (;;) {
    wdt_reset();

    if (Tenms) {
      Tenms = 0;

      lcdRefreshWait();
      lcd_clear();
      lcd_putsLeft(0, BOOTLOADER_TITLE);
      lcd_invert_line(0);

      uint8_t event = getEvent();

      if (state != ST_USB) {
        if (usbPlugged()) {
          state = ST_USB;
          if (!unlocked) {
            unlocked = 1;
            unlockFlash();
          }
          usbPluggedIn();
        }
      }

      if (state == ST_START) {
        lcd_putsLeft(2*FH, "\010Write Firmware");
        lcd_putsLeft(3*FH, "\010Restore EEPROM");
        lcd_putsLeft(4*FH, "\010Exit");
        lcd_invert_line(2+vpos);
        lcd_putsLeft(7*FH, INDENT "Or plug in a USB cable for mass storage");
        if (event == EVT_KEY_FIRST(BOOT_KEY_DOWN)) {
          vpos == 2 ? vpos = 0 : vpos = vpos+1;
        }
        else if (event == EVT_KEY_FIRST(BOOT_KEY_UP)) {
          vpos == 0 ? vpos = 2 : vpos = vpos-1;
        }
        else if (event == EVT_KEY_BREAK(BOOT_KEY_MENU)) {
          switch (vpos) {
            case 0:
              state = ST_FLASH_MENU;
              break;
            case 1:
              state = ST_RESTORE_MENU;
              break;
            default:
              state = ST_REBOOT;
          }
        }
      }

      if (state == ST_USB) {
        lcd_putsLeft(4*FH, "\026USB Connected");
        if (usbPlugged() == 0) {
          vpos = 0;
          if (unlocked) {
            lockFlash();
            unlocked = 0;
          }
          state = ST_START;
        }
#if defined(PCBSKY9X)
        usbMassStorage();
#endif
      }

      if (state == ST_FLASH_MENU || state == ST_RESTORE_MENU) {
        sdInit();
        memoryType = (state == ST_RESTORE_MENU ? MEM_EEPROM : MEM_FLASH);
        state = ST_DIR_CHECK;
      }

      else if (state == ST_DIR_CHECK) {
        fr = f_chdir(getBinaryPath());
        if (fr == FR_OK) {
          state = ST_OPEN_DIR;
        }
        else {
          lcd_putsLeft(2*FH, INDENT "Directory is missing!");
          if (event == EVT_KEY_BREAK(BOOT_KEY_EXIT) || event == EVT_KEY_BREAK(BOOT_KEY_MENU)) {
            vpos = 0;
            state = ST_START;
          }
        }
      }

      if (state == ST_OPEN_DIR) {
        index = 0;
        fr = f_opendir(&Dj, ".");
        if (fr == FR_OK) {
          state = ST_FILE_LIST;
          nameCount = fillNames(0);
          hpos = 0;
          vpos = 0;
        }
      }

      if (state == ST_FILE_LIST) {
        uint32_t limit = 6;
        if (nameCount < limit) {
          limit = nameCount;
        }
        maxhsize = 0;
        for (uint32_t i=0; i<limit; i++) {
          uint32_t x;
          x = strlen(Filenames[i]);
          if (x > maxhsize) {
            maxhsize = x;
          }
          if (x > DISPLAY_CHAR_WIDTH) {
            if (hpos + DISPLAY_CHAR_WIDTH > x) {
              x = x - DISPLAY_CHAR_WIDTH;
            }
            else {
              x = hpos;
            }
          }
          else {
            x = 0;
          }
          lcd_putsnAtt(INDENT_WIDTH, 16 + FH * i, &Filenames[i][x], DISPLAY_CHAR_WIDTH, 0);
        }

        if (event == EVT_KEY_REPT(BOOT_KEY_DOWN) || event == EVT_KEY_FIRST(BOOT_KEY_DOWN)) {
          if (vpos < limit - 1) {
            vpos += 1;
          }
          else {
            if (nameCount > limit) {
              index += 1;
              nameCount = fillNames(index);
            }
          }
        }
        else if (event == EVT_KEY_REPT(BOOT_KEY_UP) || event == EVT_KEY_FIRST(BOOT_KEY_UP)) {
          if (vpos > 0) {
            vpos -= 1;
          }
          else {
            if (index) {
              index -= 1;
              nameCount = fillNames(index);
            }
          }
        }
#if !defined(PCBTARANIS)
        else if (event == EVT_KEY_REPT(BOOT_KEY_RIGHT) || event == EVT_KEY_FIRST(BOOT_KEY_RIGHT)) {
          if (hpos + DISPLAY_CHAR_WIDTH < maxhsize) {
            hpos += 1;
          }
        }
        else if (event == EVT_KEY_REPT(BOOT_KEY_LEFT) || event == EVT_KEY_FIRST(BOOT_KEY_LEFT)) {
          if (hpos) {
            hpos -= 1;
          }
        }
#endif
        else if (event == EVT_KEY_BREAK(BOOT_KEY_MENU)) {
          // Select file to flash
          state = ST_FLASH_CHECK;
          Valid = 0;
        }
        else if (event == EVT_KEY_FIRST(BOOT_KEY_EXIT)) {
          state = ST_START;
          vpos = 0;
        }

        lcd_invert_line(2 + vpos);
      }

      else if (state == ST_FLASH_CHECK) {
        int result = menuFlashFile(vpos, event);
        FirmwareSize = FileSize[vpos] - BOOTLOADER_SIZE;
        if (result == 0) {
          // canceled
          state = ST_FILE_LIST;
        }
        else if (result == 1) {
          // confirmed
          firmwareAddress = FIRMWARE_ADDRESS + BOOTLOADER_SIZE;
          firmwareWritten = 0;
          eepromAddress = 0;
          eepromWritten = 0;
          state = ST_FLASHING;
        }
      }

      else if (state == ST_FLASHING) {
        // commit to flashing
        lcd_putsLeft(4*FH, "\032Writing...");
        
        if (!unlocked && (memoryType == MEM_FLASH)) {
          unlocked = 1;
          unlockFlash();
        }
        
        int progress;
        if (memoryType == MEM_FLASH) {
          writeFlashBlock();
          firmwareWritten += sizeof(Block_buffer);
          progress = (200*firmwareWritten) / FirmwareSize;
        }
        else {
          writeEepromBlock();
          eepromWritten += sizeof(Block_buffer);
          progress = (200*eepromWritten) / EESIZE;
        }

        lcd_rect( 3, 6*FH+4, 204, 7);
        lcd_hline(5, 6*FH+6, progress, FORCE);
        lcd_hline(5, 6*FH+7, progress, FORCE);
        lcd_hline(5, 6*FH+8, progress, FORCE);

        fr = f_read(&FlashFile, (BYTE *)Block_buffer, sizeof(Block_buffer), &BlockCount);
        if (BlockCount == 0) {
          state = ST_FLASH_DONE; // EOF
        }
        if (firmwareWritten >= FLASHSIZE - BOOTLOADER_SIZE) {
          state = ST_FLASH_DONE; // Backstop
        }
        if (eepromWritten >= EESIZE) {
          state = ST_FLASH_DONE; // Backstop
        }
      }

      if (state == ST_FLASH_DONE) {
        if (unlocked) {
          lockFlash();
          unlocked = 0;
        }
        lcd_putsLeft(4*FH, "\024Writing Complete");
        if (event == EVT_KEY_FIRST(BOOT_KEY_EXIT) || event == EVT_KEY_BREAK(BOOT_KEY_MENU)) {
          state = ST_START;
          vpos = 0;
        }
      }

      if (event == EVT_KEY_LONG(BOOT_KEY_EXIT)) {
        state = ST_REBOOT;
      }

      lcdRefresh();

      if (PowerUpDelay < 20) {	// 200 mS
        PowerUpDelay += 1;
      }
      else {
        sdPoll10ms();
      }
    }

    if (state != ST_FLASHING && state != ST_USB) {
#if defined(REV9E)
      if (pwrPressed()) {
#else
      if (pwrCheck() == e_power_off) {
#endif
        lcdOff(); // this drains LCD caps
        pwrOff();
        for (;;) {
          // Wait for power to go off
        }
      }
    }

    if (state == ST_REBOOT) {
      if (readKeys() == 0) {
        lcd_clear();
        lcdRefresh();
        lcdRefreshWait();
        RCC->CSR |= RCC_CSR_RMVF;   //clear the reset flags in RCC clock control & status register
        NVIC_SystemReset();
      }
    }
  }

  return 0;
}