Esempio n. 1
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      Nvm_Write
 *
 *  DESCRIPTION
 *      Write words to the NVM Store after preparing the NVM to be writable. 
 *      After the write operation, perform the actions necessary to save power
 *      on NVM.
 *
 *      Write words from the supplied buffer into the NVM Store, starting at the
 *      word offset.
 *
 *  PARAMETERS
 *      buffer [in]             Data to write to NVM
 *      length [in]             Number of words of data to write
 *      offset [in]             Offset from which to start writing, in words
 *
 *  RETURNS
 *      Nothing
 *----------------------------------------------------------------------------*/
void Nvm_Write(uint16 *buffer, uint16 length, uint16 offset)
{
    sys_status result;          /* Function status */

    /* Write to NVM. Firmware re-enables the NVM if it is disabled */
    result = NvmWrite(buffer, length, offset);

    /* Disable NVM to save power after write operation */
    Nvm_Disable();

    /* Report panic if NVM write is not successful */
    if(sys_status_success != result)
    {
        ReportPanic(app_panic_nvm_write);
    }
}
Esempio n. 2
0
void Nvm_Write(uint16* buffer, uint16 length, uint16 offset)
{
    sys_status result;

    /* If the NVM has been earlier disabled, firmware automatically enables
     * NVM before writing to it.
     */
    result = NvmWrite(buffer, length, offset);
    /* Disable NVM to save power after write operation */
    Nvm_Disable();
    /* PIO2 usage has to be toggled between LED operation and driving the NVM.
     * So, after the power to EEPROM is disabled, configure PIO2 to Pair LED
     * back again.
     */
    SetUpPairLED();

    /* If NvmWrite was a success, return */
    if(sys_status_success == result)
    {
        /* Write was successful. */
        return;
    }
#ifdef NVM_TYPE_FLASH
    else if(nvm_status_needs_erase == result)
    {
        /* The application already has a copy of NVM data in its variables,
         * so we can erase the NVM 
         */
        Nvm_Erase();

        /* Write back the NVM data. 
         * Please note that the following function writes data into NVM and 
         * should not fail. 
         */
         WriteApplicationAndServiceDataToNVM();
    }
#endif /* NVM_TYPE_FLASH */
    else
    {
        /* Irrecoverable error. Reset the chip. */
        ReportPanic(app_panic_nvm_write);
    }
}
Esempio n. 3
0
extern void Nvm_Write(uint16* buffer, uint16 length, uint16 offset)
{
    sys_status result;

    /* Write to NVM. Firmware re-enables the NVM if it is disabled */
    result = NvmWrite(buffer, length, offset);

    /* Disable NVM to save power after write operation */
    Nvm_Disable();

    /* If NvmWrite was a success, return */
    if(sys_status_success == result)
    {
        /* Write was successful. */
        return;
    }
#ifdef NVM_TYPE_FLASH
    else if(nvm_status_needs_erase == result)
    {
        /* The application already has a copy of NVM data in its variables,
         * so we can erase the NVM 
         */
        Nvm_Erase();

        /* Write back the NVM data. 
         * Please note that the following function writes data into NVM and 
         * should not fail. 
         */
         WriteApplicationAndServiceDataToNVM();
    }
#endif /* NVM_TYPE_FLASH */
    else
    {
        /* Irrecoverable error. Reset the chip. */
        ReportPanic(app_panic_nvm_write);
    }

}
Esempio n. 4
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      readPersistentStore
 *
 *  DESCRIPTION
 *      This function is used to initialise and read NVM data.
 *
 *  PARAMETERS
 *      None
 *
 *  RETURNS
 *      Nothing
 *----------------------------------------------------------------------------*/
static void readPersistentStore(void)
{
    /* NVM offset for supported services */
    uint16 nvm_offset = NVM_MAX_APP_MEMORY_WORDS;
    uint16 nvm_sanity = 0xffff;

    /* Read persistent storage to find if the device was last bonded to another
     * device. If the device was bonded, trigger fast undirected advertisements
     * by setting the white list for bonded host. If the device was not bonded,
     * trigger undirected advertisements for any host to connect.
     */

    NvmRead(&nvm_sanity, sizeof(nvm_sanity), NVM_OFFSET_SANITY_WORD);

    if (nvm_sanity == NVM_SANITY_MAGIC)
    {
        /* Read bonded flag from NVM */
        NvmRead((uint16 *)&(IS_BONDED),
                 sizeof(IS_BONDED),
                 NVM_OFFSET_BONDED_FLAG);

        if (IS_BONDED)
        {
            /* Bonded host typed BD address will only be stored if bonded flag
             * is set to TRUE. Read last bonded device address.
             */
            NvmRead((uint16 *)&(CONN_HOST_ADDR),
                      sizeof(TYPED_BD_ADDR_T),
                      NVM_OFFSET_BONDED_ADDR);

            /* If device is bonded and bonded address is resolvable then read
             * the bonded device's IRK
             */
            if (GattIsAddressResolvableRandom(&(CONN_HOST_ADDR)))
            {
                NvmRead(CONNECTION_IRK, 
                        MAX_WORDS_IRK,
                        NVM_OFFSET_SM_IRK);
            }
        }
        else /* Case when we have only written NVM_SANITY_MAGIC to NVM but 
              * didn't get bonded to any host in the last powered session
              */
        {
            /* Any initialisation can be done here for non-bonded devices */
            
        }

        /* Read the diversifier associated with the presently bonded/last 
         * bonded device.
         */
        NvmRead(&(LINK_DIVERSIFIER),
                 sizeof(LINK_DIVERSIFIER),
                 NVM_OFFSET_SM_DIV);

        /* Read GATT data from NVM */
        GattReadDataFromNVM(&nvm_offset);
    }
    else /* NVM sanity check failed means either the device is being brought up 
          * for the first time or memory has been corrupted in which case 
          * discard the data and start fresh.
          */
    {
        nvm_sanity = NVM_SANITY_MAGIC;

        /* Write NVM Sanity word to the NVM */
        NvmWrite(&nvm_sanity, 
                 sizeof(nvm_sanity), 
                 NVM_OFFSET_SANITY_WORD);

        /* The device will not be bonded as it is coming up for the first time
         */
        IS_BONDED = FALSE;

        /* Write bonded status to NVM */
        NvmWrite((uint16 *)&(IS_BONDED),
                 sizeof(IS_BONDED), 
                 NVM_OFFSET_BONDED_FLAG);

        /* When the application is coming up for the first time after flashing 
         * the image to it, it will not have bonded to any device. So, no LTK 
         * will be associated with it. Hence, set the diversifier to 0.
         */
        LINK_DIVERSIFIER = 0;

        /* Write the same to NVM. */
        NvmWrite(&(LINK_DIVERSIFIER),
                 sizeof(LINK_DIVERSIFIER),
                 NVM_OFFSET_SM_DIV);

        /* Since device is being brought up first time, it won't be in
         * bonded state. Following function call will only initialise the NVM 
         * offset of GATT service.
         */
        GattReadDataFromNVM(&nvm_offset);
    }
}
Esempio n. 5
0
void init_platform_bootloader( void )
{
  uint32_t BootNvmInfo;
  OSStatus err;
  
  MicoGpioInitialize( BOOT_SEL, INPUT_PULL_UP );
  MicoGpioInitialize( MFG_SEL, INPUT_PULL_UP );
#ifdef MICO_ATE_START_ADDRESS
	MicoGpioInitialize( EasyLink_BUTTON, INPUT_PULL_UP );
#endif  
  /* Check USB-HOST is inserted */
  err = MicoGpioInitialize( (mico_gpio_t)USB_DETECT, INPUT_PULL_DOWN );
  require_noerr(err, exit);
  mico_thread_msleep_no_os(2);
  
  require_string( MicoGpioInputGet( (mico_gpio_t)USB_DETECT ) == true, exit, "USB device is not inserted" );

  //platform_log("USB device inserted");
  if( HardwareInit(DEV_ID_USB) ){
    FolderOpenByNum(&RootFolder, NULL, 1);
    FileBrowse(RootFolder.FsContext);
  }

  /* Check last firmware update is success or not. */
  NvmRead(UPGRADE_NVM_ADDR, (uint8_t*)&BootNvmInfo, 4);

  if(false == UpgradeFileFound)
  {
    if(BootNvmInfo == UPGRADE_SUCC_MAGIC)
    {
      /*
       * boot up check for the last time
       */
      platform_log("[UPGRADE]:upgrade successful completely");
    }
    else if(BootNvmInfo == (uint32_t)UPGRADE_ERRNO_NOERR)
    {
      platform_log("[UPGRADE]:no upgrade, boot normallly");
    }
    else if(BootNvmInfo == (uint32_t)UPGRADE_ERRNO_CODBUFDAT)
    {
      platform_log("[UPGRADE]:upgrade successful partly, data fail");
    }
    else
    {
      platform_log("[UPGRADE]:upgrade error, errno = %d", (int32_t)BootNvmInfo);
    }
  }
  else
  {
    if(BootNvmInfo == (uint32_t)UPGRADE_ERRNO_NOERR)
    {
      platform_log("[UPGRADE]:found upgrade ball, prepare to boot upgrade");
      BootNvmInfo = UPGRADE_REQT_MAGIC;
      NvmWrite(UPGRADE_NVM_ADDR, (uint8_t*)&BootNvmInfo, 4);
            //if you want PORRESET to reset GPIO only,uncomment it
            //GpioPorSysReset(GPIO_RSTSRC_PORREST);
      NVIC_SystemReset();
      while(1);;;
    }
    else if(BootNvmInfo == UPGRADE_SUCC_MAGIC)
    {
      BootNvmInfo = (uint32_t)UPGRADE_ERRNO_NOERR;
      NvmWrite(UPGRADE_NVM_ADDR, (uint8_t*)&BootNvmInfo, 4);
      platform_log("[UPGRADE]:found upgrade ball file for the last time, re-plugin/out, if you want to upgrade again");
    }
    else
    {
      platform_log("[UPGRADE]:upgrade error, errno = %d", (int32_t)BootNvmInfo);
      if( BootNvmInfo == -9 ) {
        platform_log("[UPGRADE]:Same file, no need to update");
        goto exit;
      }
      BootNvmInfo = (uint32_t)UPGRADE_ERRNO_NOERR;
      NvmWrite(UPGRADE_NVM_ADDR, (uint8_t*)&BootNvmInfo, 4);
      BootNvmInfo = UPGRADE_REQT_MAGIC;
      NvmWrite(UPGRADE_NVM_ADDR, (uint8_t*)&BootNvmInfo, 4);
            //if you want PORRESET to reset GPIO only,uncomment it
            //GpioPorSysReset(GPIO_RSTSRC_PORREST);
      NVIC_SystemReset();
    }
  }
exit:
  return;
}