Optiboot / optiboot

Small and Fast Bootloader for Arduino and other Atmel AVR chips
Other
1.08k stars 396 forks source link

Advice: Points corresponding to AVR_Ex series #371

Open askn37 opened 8 months ago

askn37 commented 8 months ago
  1. The recording address of SIGROW_DEVICEID[012] is different for AVR_EA and AVR_EB. Therefore, you need to create separate binaries for each.
  2. CLKCTRL of AVR_Ex is equivalent to tinyAVR/megaAVR series. Select the UART baud rate by reading the 20MHz/16MHz configuration bits in FUSE.
  3. NVMCTRL of AVR_Ex is ver.3. The usage method and command selection are different from AVR_Dx.
  4. The maximum flash capacity of AVR_Ex is 64KiB, so there is no RAMPZ register. Therefore, the STK_UNIVERSAL+AVR_OP_LOAD_EXT_ADDR command is not required. It is sufficient to select the desired 32KiB bank with the FLMAP bit and use normal SD/LD instructions.

Working code can be found here.

point.2

if (bit_is_set(FUSE_OSCCFG, FUSE_OSCHFFRQ_bp)) {
  #if (BAUD_SETTING_16 < 256)
    MYUART.BAUDL = BAUD_SETTING_16;    // 8bit-wide register
  #else
    MYUART.BAUD = BAUD_SETTING_16;     // 16bit-wide register
  #endif
}
else {
  #if (BAUD_SETTING_20 < 256)
    MYUART.BAUDL = BAUD_SETTING_20;    // 8bit-wide register
  #else
    MYUART.BAUD = BAUD_SETTING_20;     // 16bit-wide register
  #endif
}

point.3

void nvmctrl (uint8_t _nvm_cmd) {
  _PROTECTED_WRITE_SPM(NVMCTRL_CTRLA, _nvm_cmd);
  while (NVMCTRL.STATUS & (NVMCTRL_EEBUSY_bm | NVMCTRL_FLBUSY_bm));
}

point.4

#ifdef BIGBOOT
    else if (ch == STK_UNIVERSAL) {
      // Not used because it is within 64KiB
      getNch(4);
      putch(0x00);  // response '0'
    }
#endif
    else if (ch == STK_PROG_PAGE) {
      /* Write up to 1 page of flash */
      /* Write memory block mode, length is big endian.  */
      length.bytes[1] = getch();
      length.bytes[0] = getch();
      ch = getch();

      nvmctrl(NVMCTRL_CMD_NOCMD_gc);
      if (ch == 'F') {
        /* Flash write */
        /*
         * The AVR_Ex series does not have a RAMPZ register, so adjust the FLMAP bit.
         */
        if (address.bytes[1] < 0x80) {
          /* Select low FPAGE */
          address.word += MAPPED_PROGMEM_START;
          _PROTECTED_WRITE(NVMCTRL_CTRLB, NVMCTRL_FLMAP_SECTION0_gc);
        }
        else {
          /* Select high FPAGE */
          _PROTECTED_WRITE(NVMCTRL_CTRLB, NVMCTRL_FLMAP_SECTION1_gc);
        }
        ch = NVMCTRL_CMD_FLPERW_gc;
      }
      else {
        /* EEPROM write */
        address.word += MAPPED_EEPROM_START;
        ch = NVMCTRL_CMD_EEPERW_gc;
      }
      do *(address.bptr++) = getch(); while (--length.word);
      nvmctrl(ch);

      /* Read command terminator, start reply */
      verifySpace();
    }
    else if (ch == STK_READ_PAGE) {
      /* Read memory block mode, length is big endian.  */
      length.bytes[1] = getch();
      length.bytes[0] = getch();
      ch = getch();
      verifySpace();

      /*
       * The entire flash does not fit in the same address space
       * so we call that helper function.
       * The AVR_Ex series does not have a RAMPZ register, so adjust the FLMAP bit.
       */
      if (ch == 'F') {
        if (address.bytes[1] < 0x80) {
          /* Select low FPAGE */
          address.word += MAPPED_PROGMEM_START;
          _PROTECTED_WRITE(NVMCTRL_CTRLB, NVMCTRL_FLMAP_SECTION0_gc);
        }
        else {
          /* Select high FPAGE */
          _PROTECTED_WRITE(NVMCTRL_CTRLB, NVMCTRL_FLMAP_SECTION1_gc);
        }
      }
      else { // it's EEPROM and we just read it
        address.word += MAPPED_EEPROM_START;
      }
      do putch(*(address.bptr++)); while (--length.word);
    }
    else if (ch == STK_READ_SIGN) {
      // READ SIGN - return actual device signature from SIGROW
      // this enables the same binary to be ued on multiple chips.
      verifySpace();

      /* SIGROW_DEVICEID0 : This value is always fixed. */
      putch(0x1E);

      /* This value indicates the size of the flash. */
      putch(SIGROW_DEVICEID1);

      /* Inconsistent values to avoid duplicate SIGROW */
      putch(SIGROW_DEVICEID2);
    }
WestfW commented 8 months ago

Noted. Since Optiboot doesn't currently support AVR-Ex chips at all, this seems a bit academic. Was there another issue or PR for adding the initial Ex (or Dx, for that matter) support?

Note that DxCore has switched to urboot.