Пример #1
0
/**************************************************************************************************
 * @fn          sbImgValid
 *
 * @brief       Check validity of the run-code image.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      TRUE or FALSE for image valid.
 **************************************************************************************************
 */
uint8 sbImgValid(void)
{
  uint16 crc[2];


  HalFlashRead(HAL_SB_CRC_ADDR / HAL_FLASH_PAGE_SIZE,
               HAL_SB_CRC_ADDR % HAL_FLASH_PAGE_SIZE,
               (uint8 *)crc, sizeof(crc));

  if ((crc[0] == 0xFFFF) || (crc[0] == 0x0000))
  {
    return FALSE;
  }

  if (crc[0] != crc[1])
  {
    crc[1] = calcCRC();
    HalFlashWrite((HAL_SB_CRC_ADDR / HAL_FLASH_WORD_SIZE), (uint8 *)crc, 1);
    HalFlashRead(  HAL_SB_CRC_ADDR / HAL_FLASH_PAGE_SIZE,
                   HAL_SB_CRC_ADDR % HAL_FLASH_PAGE_SIZE,
                   (uint8 *)crc, sizeof(crc));
  }

  return ((crc[0] == crc[1]) && (crc[0] != 0xFFFF) && (crc[0] != 0x0000));
}
Пример #2
0
/*********************************************************************
 * @fn      Onboard_soft_reset
 *
 * @brief   Effect a soft reset.
 *
 * @param   none
 *
 * @return  none
 *
 *********************************************************************/
__near_func void Onboard_soft_reset( void )
{
#if (defined MAKE_CRC_SHDW) || (defined FAKE_CRC_SHDW)  // If built for bootloader
// If bootloader code exists - need to tell the bootloader that this is a soft reset,
// so it should not do anything, and just pass the control to the main app immediately
  uint16 sblCmdAddr;
  uint32 sblSig;
  
  HalFlashRead(SBL_SIG_ADDR / HAL_FLASH_PAGE_SIZE,
               SBL_SIG_ADDR % HAL_FLASH_PAGE_SIZE,
               (uint8 *)&sblSig, sizeof(sblSig));
  
  if (sblSig == SBL_SIGNATURE)
  {
    HalFlashRead(SBL_CMD_ADDR / HAL_FLASH_PAGE_SIZE,
                 SBL_CMD_ADDR % HAL_FLASH_PAGE_SIZE,
                 (uint8 *)&sblCmdAddr, sizeof(sblCmdAddr));

    if (sblCmdAddr != 0xFFFF)
    {
      *(uint32 *)sblCmdAddr = MAIN_APP_CMD_PASS_THROUGH;
    }
  }  
#endif	

  HAL_DISABLE_INTERRUPTS();
  // Abort all DMA channels to insure that ongoing operations do not
  // interfere with re-configuration.
  DMAARM = 0x80 | 0x1F;
  asm("LJMP 0x0");
}
Пример #3
0
/**************************************************************************************************
 * @fn          checkDL
 *
 * @brief       Check validity of the downloaded image.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      TRUE or FALSE for image valid.
 **************************************************************************************************
 */
static uint8 checkDL(void)
{
  uint16 crc[2];

  HalFlashRead(OAD_IMG_D_PAGE, OAD_IMG_CRC_OSET, (uint8 *)crc, sizeof(crc));

  if ((crc[0] == 0xFFFF) || (crc[0] == 0x0000))
  {
    return FALSE;
  }

  if (crc[1] == 0xFFFF)
  {
    //P0DIR |= 1;
    //P0_0 = 0;
    //P0_0 = 1;
    //P0_0 = 0;
    //P0_0 = 1;
    //P0_0 = 0;
    //P0_0 = 1;
    crc[1] = crcCalcDLDMA();
    //P0_0 = 0;

#if defined FEATURE_OAD_BIM  // If download image is made to run in-place, enable it here.
    uint16 addr = OAD_IMG_D_PAGE * OAD_FLASH_PAGE_MULT + OAD_IMG_CRC_OSET / HAL_FLASH_WORD_SIZE;
    crc[0] = 0xFFFF;
    HalFlashWrite(addr, (uint8 *)crc, 1);
    HalFlashRead(OAD_IMG_D_PAGE, OAD_IMG_CRC_OSET, (uint8 *)crc, sizeof(crc));
#endif
  }

  return (crc[0] == crc[1]);
}
Пример #4
0
/**************************************************************************************************
 * @fn          crcCalc
 *
 * @brief       Run the CRC16 Polynomial calculation over the image specified.
 *
 * input parameters
 *
 * @param       page - Flash page on which to beging the CRC calculation.
 *
 * output parameters
 *
 * None.
 *
 * @return      The CRC16 calculated.
 **************************************************************************************************
 */
static uint16 crcCalc(uint8 page)
{
  HalFlashRead(page, 0, pgBuf, HAL_FLASH_PAGE_SIZE);

  const img_hdr_t *pImgHdr = (const img_hdr_t *)(pgBuf + BIM_HDR_OSET);

  uint8 pageBeg = page;
  uint8 pageEnd = pImgHdr->len / (HAL_FLASH_PAGE_SIZE / HAL_FLASH_WORD_SIZE);
  uint16 osetEnd = (pImgHdr->len - (pageEnd * (HAL_FLASH_PAGE_SIZE / HAL_FLASH_WORD_SIZE)))
                                                                   * HAL_FLASH_WORD_SIZE;
  pageEnd += pageBeg;
  if (pageBeg == BIM_IMG_A_PAGE)
  {
    pageEnd += BIM_IMG_B_AREA;
  }

  ADCCON1 &= 0xF3;  // CRC configuration of LRSR.

  // CRC seed of 0x0000.
  RNDL = 0x00;
  RNDL = 0x00;

  while(1)
  {
    for (uint16 oset = 0; oset < HAL_FLASH_PAGE_SIZE; oset++)
    {
      if ((page == pageBeg) && (oset == BIM_CRC_OSET))
      {
        oset += 3;  // Skip the CRC and shadow.
      }
      else if ((page == pageEnd) && (oset == osetEnd))
      {
        uint16 crc = RNDH;
        crc = (crc << 8) | RNDL;

        return crc;
      }
      else
      {
        RNDH = pgBuf[oset];
      }
    }

    if (++page == BIM_IMG_B_PAGE)
    {
      page += BIM_IMG_B_AREA;
    }
    HalFlashRead(page, 0, pgBuf, HAL_FLASH_PAGE_SIZE);
  }
}
Пример #5
0
uint8_t persistent_pwrmgmt_get_latest(struct pwrmgmt_data *pwr_ptr)
{
	uint8_t count;
	uint32_t pwr_idx_bits, u32;

	u32 = (uint32)&(((struct persistent_page *)0)->pwr_idx_bits[0]);
    HalFlashRead(pidx, (uint16_t)u32, (uint8_t *)&pwr_idx_bits, 4);
	count = __persistent_get_idx_from_bit_map((uint8_t *)&pwr_idx_bits, 4);
	if (count == 0 || count > PERSISTENT_PWR_MAX) {
		return FAIL;
	}

	u32 = (uint32)&(((struct persistent_page *)0)->pwr_log[count - 1]);
	HalFlashRead(pidx, (uint16_t)u32, (uint8_t *)pwr_ptr, sizeof(struct pwrmgmt_data));
	return SUCCESS;
}
Пример #6
0
/*********************************************************************
 * @fn      oadImgIdentifyWrite
 *
 * @brief   Process the Image Identify Write.
 *
 * @param   connHandle - connection message was received on
 * @param   pValue - pointer to data to be written
 *
 * @return  status
 */
static bStatus_t oadImgIdentifyWrite( uint16 connHandle, uint8 *pValue )
{
  img_hdr_t rxHdr;
  img_hdr_t ImgHdr;

  rxHdr.ver = BUILD_UINT16( pValue[0], pValue[1] );
  rxHdr.len = BUILD_UINT16( pValue[2], pValue[3] );

  (void)osal_memcpy(rxHdr.uid, pValue+4, sizeof(rxHdr.uid));

  HalFlashRead(OAD_IMG_R_PAGE, OAD_IMG_HDR_OSET, (uint8 *)&ImgHdr, sizeof(img_hdr_t));

  oadBlkTot = rxHdr.len / (OAD_BLOCK_SIZE / HAL_FLASH_WORD_SIZE);

  if ( (OAD_IMG_ID( ImgHdr.ver ) != OAD_IMG_ID( rxHdr.ver )) && // TBD: add customer criteria for initiating OAD here.
       (oadBlkTot <= OAD_BLOCK_MAX) &&
       (oadBlkTot != 0) )
  {
    oadBlkNum = 0;
    oadImgBlockReq(connHandle, 0);
  }
  else
  {
    oadImgIdentifyReq(connHandle, &ImgHdr);
  }

  return ( SUCCESS );
}
Пример #7
0
/*********************************************************************
 * @fn      oadManagerSendImgNotify
 *
 * @brief   OAD device discovery.
 *
 * @return  none
 */
static void oadManagerSendImgNotify(void)
{
  attWriteReq_t req;
  img_hdr_t ImgHdr;

  HalFlashRead(OAD_IMG_B_PAGE, OAD_IMG_HDR_OSET, (uint8 *)&ImgHdr, sizeof(img_hdr_t));

  req.handle = oadManagerHandles[OAD_CHAR_IMG_IDENTIFY];
  req.len = OAD_IMG_HDR_SIZE;
  req.value[0] = LO_UINT16(ImgHdr.ver);
  req.value[1] = HI_UINT16(ImgHdr.ver);

  req.value[2] = LO_UINT16(ImgHdr.len);
  req.value[3] = HI_UINT16(ImgHdr.len);

  (void)osal_memcpy(req.value+4, ImgHdr.uid, sizeof(ImgHdr.uid));

  req.sig = FALSE;
  req.cmd = TRUE;

  VOID GATT_WriteNoRsp(oadManagerConnHandle, &req);

  // Save the total number of blocks
  oadBlkTot = ImgHdr.len / (OAD_BLOCK_SIZE / HAL_FLASH_WORD_SIZE);
}
Пример #8
0
/**************************************************************************************************
 * @fn          imgAuth
 *
 * @brief       Run the AES CTR decryption over the image area specified.
 * @brief       Run the AES CRC-MAC calculation over the image specified and set the image
 *              ready-to-run if the Signature is verified.
 *
 * input parameters
 *
 * @param       imgSel - Image select: 0 for Image-A and 1 for Image-B.
 * @param       imgHdr - Pointer to the Image Header corresponding to the image select.
 *
 * output parameters
 *
 * None.
 *
 * @return      TRUE if the image Signature verifies; FALSE otherwise.
 */
static uint8 imgAuth(uint8 imgSel, img_hdr_t *imgHdr)
{
  if ((imgHdr->crc0 == 0) || (imgHdr->crc0 == 0xFFFF))
  {
    return FALSE;
  }

  if (imgHdr->crc0 != imgHdr->crc1)
  {
    aesLoadKey();

    aes_hdr_t aesHdr;
    HalFlashRead(ImgPageBeg[imgSel], BEM_AES_OSET, (uint8 *)&aesHdr, sizeof(aes_hdr_t));

    // Image length in 3 bytes, MSB to LSB order - the Signature bytes are not to be included.
    uint32 imageLen = (uint32)HAL_FLASH_PAGE_SIZE * imgHdr->res[0] - KEY_BLENGTH;

    aesHdr.spare[0] = ((uint8 *)&imageLen)[0];
    aesHdr.spare[1] = ((uint8 *)&imageLen)[1];
    aesHdr.spare[2] = ((uint8 *)&imageLen)[2];
    aesHdr.spare[3] = imgHdr->res[0];

    if (aesSignature(imgSel, &aesHdr))
    {
      uint16 crc[2] = { 0xFFFF, imgHdr->crc0 };

      BEM_NVM_SET(ImgPageBeg[imgSel], (uint8 *)crc, 4);
      BEM_NVM_GET(ImgPageBeg[imgSel], (uint8 *)&imgHdr, 4);
    }
  }

  return (imgHdr->crc0 == imgHdr->crc1);
}
Пример #9
0
void main(void)
{
  HAL_BOARD_INIT();
#if HAL_OTA_XNV_IS_SPI
  XNV_SPI_INIT();
#endif
  /* This is in place of calling HalDmaInit() which would require init of the
   * other 4 DMA descriptors in addition to just Channel 0.
   */
  HAL_DMA_SET_ADDR_DESC0( &dmaCh0 );

  while (1)
  {
    HalFlashRead(HAL_OTA_CRC_ADDR / HAL_FLASH_PAGE_SIZE,
                 HAL_OTA_CRC_ADDR % HAL_FLASH_PAGE_SIZE,
                 (uint8 *)&OTA_crcControl, sizeof(OTA_crcControl));

    if (OTA_crcControl.crc[0] == OTA_crcControl.crc[1])
    {
      break;
    }
    else if ((OTA_crcControl.crc[0] != 0) && (OTA_crcControl.crc[0] == crcCalc()))
    {
      OTA_crcControl.crc[1] = OTA_crcControl.crc[0];
      HalFlashWrite((HAL_OTA_CRC_ADDR / HAL_FLASH_WORD_SIZE), (uint8 *)OTA_crcControl.crc, 1);
    }
    else
    {
      dl2rc();
    }
  }

  // Simulate a reset for the Application code by an absolute jump to location 0x0800.
  asm("LJMP 0x800\n");
}
Пример #10
0
/*********************************************************************
 * @fn      erasePage
 *
 * @brief   Erases a page in Flash.
 *
 * @param   pg - Valid NV page to erase.
 *
 * @return  none
 */
static void erasePage( uint8 pg )
{
  if ( !OSAL_NV_CHECK_BUS_VOLTAGE || failF)
  {
    failF = TRUE;
    return;
  }

  HalFlashErase(pg);

  {
    // Verify the erase operation
    uint16 offset;
    uint8 tmp;

    for (offset = 0; offset < OSAL_NV_PAGE_SIZE; offset ++)
    {
      HalFlashRead(pg, offset, &tmp, 1);
      if (tmp != OSAL_NV_ERASED)
      {
        failF = TRUE;
        break;
      }
    }
  }
}
Пример #11
0
// Max length of device name: 20 (excluding tailing null)
// This function prepare contents for the backup page
void persistent_flash_backup_prepare(uint16_t offset, uint8_t *buf, uint16_t len)
{
	uint32_t buf32[64];
	uint8_t i, j;

	HalFlashErase(pidx + 1);
	for (i = 0; i < 4; i++) {
		HalFlashRead(pidx, i * 256, (uint8_t *)buf32, 256);
		if (i == 0) {
			buf32[0] = 0xFFFFADDE;
		}
		// Cleanup old power mgmt data
		if (offset == 520) {
			if (i == 2) {
				for (j = 2; j < 64; j++) {
					buf32[j] = 0xFFFFFFFF;
				}
			} else if (i == 3) {
				for (j = 0; j < 64; j++) {
					buf32[j] = 0xFFFFFFFF;
				}
			}
		}
		if ((offset / 256) == (uint16_t)i) {
			memcpy((((uint8_t *)buf32) + (uint32_t)(offset % 256)), buf, len);
		}
		HalFlashWrite((pidx + 1), i * 256, (uint8_t *)buf32, 256);
	}
	buf32[0] = 0xEFBEADDE;
	HalFlashWrite((pidx + 1), 0, (uint8_t *)buf32, 4);
}
Пример #12
0
/**************************************************************************************************
 * @fn          calcCRC
 *
 * @brief       Run the CRC16 Polynomial calculation over the RC image.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      The CRC16 calculated.
 **************************************************************************************************
 */
static uint16 calcCRC(void)
{
  uint32 addr;
  uint16 crc = 0;

  // Run the CRC calculation over the active body of code.
  for (addr = HAL_SB_IMG_ADDR; addr < HAL_SB_IMG_ADDR + HAL_SB_IMG_SIZE; addr++)
  {
    if (addr == HAL_SB_CRC_ADDR)
    {
      addr += 3;
    }
    else
    {
      uint8 buf;
      HalFlashRead(addr / HAL_FLASH_PAGE_SIZE, addr % HAL_FLASH_PAGE_SIZE, &buf, 1);
      crc = runPoly(crc, buf);
    }
  }

  // IAR note explains that poly must be run with value zero for each byte of crc.
  crc = runPoly(crc, 0);
  crc = runPoly(crc, 0);

  return crc;
}
Пример #13
0
void persistent_init(void)
{
	uint8_t i, j;
	uint8_t buf[16], buf2[4];
	uint32_t magic32 = 0xEFBEADDE;		// reverse DEADBEEF
	uint32_t ido2Name1 = 0x326F4469;	// reverse iDo2
	uint32_t ido2Name2 = 0x00000000;	// string end
	uint32_t tmp32;
	uint32_t buf32[64];

	__debug_sizeof_persistent_page = sizeof(struct persistent_page);

	pidx = (uint8_t)PERSISTENT_PAGE_IDX;
	HalFlashRead(pidx, 0, buf, 4);
	HalFlashRead((pidx + 1), 0, buf2, 4);

	if (memcmp(buf2, PERSISTENT_MAGIC, 4) == 0) {
		if (memcmp(buf, PERSISTENT_MAGIC, 4) != 0) {
			ble_flash_page_erase(pidx);
			for (i = 0; i < 4; i++) {
				HalFlashRead((pidx + 1), (uint16_t)i * 256, (uint8_t *)buf32, 256);
				for (j = 0; j < 64; j++) {
					flash_word_unprotected_write((uint32_t *)((uint32_t)pidx * 1024 + (uint32_t)i * 256 + (uint32_t)j * 4), buf32[j]);
				}
			}
		}
		ble_flash_page_erase(pidx + 1);
	} else {
		if (memcmp(buf, PERSISTENT_MAGIC, 4) != 0) {
			// This is invoked before softdevice and radio
			ble_flash_page_erase(pidx);
			flash_word_unprotected_write((uint32_t *)((uint32_t)pidx * 1024), magic32);
			flash_word_unprotected_write((uint32_t *)((uint32_t)pidx * 1024 + 4), ido2Name1);
			flash_word_unprotected_write((uint32_t *)((uint32_t)pidx * 1024 + 8), ido2Name2);
		}
	}

	// Update boot count
	HalFlashRead(pidx, 24, buf, 16);
	boot_cnt = __persistent_mark_bit_map(buf, 16);

	// Write back
	for (i = 0; i < 4; i++) {
		tmp32 = ((uint32_t)buf[i * 4 + 3] << 24) | ((uint32_t)buf[i * 4 + 2] << 16) | ((uint32_t)buf[i * 4 + 1] << 8) | (uint32_t)buf[i * 4];
		flash_word_unprotected_write((uint32_t *)((uint32_t)pidx * 1024 + 24 + i * 4), tmp32);
	}
}
Пример #14
0
/**************************************************************************************************
 * @fn          main
 *
 * @brief       C-code main function.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
void main(void)
{
  uint16 crc[2];

  // Prefer to run Image-B over Image-A so that Image-A does not have to invalidate itself.
  HalFlashRead(BIM_IMG_B_PAGE, BIM_CRC_OSET, (uint8 *)crc, 4);

  if ((crc[0] != 0xFFFF) && (crc[0] != 0x0000))
  {
    if (crc[0] == crc[1])
    {
      JumpToImageAorB = 1;
      // Simulate a reset for the Application code by an absolute jump to the expected INTVEC addr.
      asm("LJMP 0x4030");
      HAL_SYSTEM_RESET();  // Should not get here.
    }
    /* This check is disruptive when an OAD process to Image-A is interrupted - this check must
     * complete before the still good Image-A is run.
    else if (crc[1] == 0xFFFF)  // If first run of an image that was physically downloaded.*/
    {
      crcCheck(BIM_IMG_B_PAGE, crc);
    }
    /**/
  }

  HalFlashRead(BIM_IMG_A_PAGE, BIM_CRC_OSET, (uint8 *)crc, 4);

  if ((crc[0] != 0xFFFF) && (crc[0] != 0x0000))
  {
    if (crc[0] == crc[1])
    {
      JumpToImageAorB = 0;
      // Simulate a reset for the Application code by an absolute jump to the expected INTVEC addr.
      asm("LJMP 0x0830");
      HAL_SYSTEM_RESET();  // Should not get here.
    }
    else if (crc[1] == 0xFFFF)  // If first run of an image that was physically downloaded.
    {
      crcCheck(BIM_IMG_A_PAGE, crc);
    }
  }

  SLEEPCMD |= 0x03;  // PM3, All clock oscillators off, voltage regulator off.
  halSleepExec();
  HAL_SYSTEM_RESET();  // Should not get here.
}
Пример #15
0
/*********************************************************************
 * @fn      setChk
 *
 * @brief   Set the item header checksum given the data buffer offset.
 *
 * @param   pg - Valid NV page.
 * @param   offset - Valid offset into the page of the item data - the header
 *                   offset is calculated from this.
 * @param   chk - The checksum to set.
 *
 * @return  The checksum read back.
 */
static uint16 setChk( uint8 pg, uint16 offset, uint16 chk )
{
  offset -= OSAL_NV_WORD_SIZE;
  writeWordH( pg, offset, (uint8 *)&chk );
  HalFlashRead( pg, offset, (uint8 *)(&chk), sizeof( chk ) );

  return chk;
}
Пример #16
0
/*********************************************************************
 * @fn      xferBuf
 *
 * @brief   Xfers an NV buffer from one location to another, enforcing OSAL_NV_WORD_SIZE writes.
 *
 * @return  none
 */
static void xferBuf( uint8 srcPg, uint16 srcOff, uint8 dstPg, uint16 dstOff, uint16 len )
{
  uint8 rem = dstOff % OSAL_NV_WORD_SIZE;
  uint8 tmp[OSAL_NV_WORD_SIZE];

  if ( rem )
  {
    dstOff -= rem;
    HalFlashRead(dstPg, dstOff, tmp, OSAL_NV_WORD_SIZE);

    while ( (rem < OSAL_NV_WORD_SIZE) && len )
    {
      HalFlashRead(srcPg, srcOff, tmp+rem, 1);
      srcOff++;
      rem++;
      len--;
    }

    writeWord( dstPg, dstOff, tmp );
    dstOff += OSAL_NV_WORD_SIZE;
  }

  rem = len % OSAL_NV_WORD_SIZE;
  len /= OSAL_NV_WORD_SIZE;

  while ( len-- )
  {
    HalFlashRead(srcPg, srcOff, tmp, OSAL_NV_WORD_SIZE);
    srcOff += OSAL_NV_WORD_SIZE;
    writeWord( dstPg, dstOff, tmp );
    dstOff += OSAL_NV_WORD_SIZE;
  }

  if ( rem )
  {
    uint8 idx = 0;
    HalFlashRead(dstPg, dstOff, tmp, OSAL_NV_WORD_SIZE);
    while ( rem-- )
    {
      HalFlashRead(srcPg, srcOff, tmp+idx, 1);
      srcOff++;
      idx++;
    }
    writeWord( dstPg, dstOff, tmp );
  }
}
Пример #17
0
/*********************************************************************
 * @fn      oadManagerHandleNoti
 *
 * @brief   Handle Notifications and Indications.
 *
 * @return  none
 */
static void oadManagerHandleNoti(attHandleValueNoti_t *pNoti)
{
  if (pNoti->handle == oadManagerHandles[OAD_CHAR_IMG_IDENTIFY])
  {
#if (defined HAL_LCD && (HAL_LCD == TRUE))
    uint16 ver = BUILD_UINT16(pNoti->value[0], pNoti->value[1]);
    uint8 userId[12] = "UserId ";

    osal_memcpy(&(userId[7]), &(pNoti->value[4]), 4);
    userId[11] = '\0';

    if ( OAD_IMG_ID( ver ) == 0 )
    {
        HalLcdWriteStringValueValue("ImgA Id", OAD_VER_NUM( ver ), 16,
                                               BUILD_UINT16(pNoti->value[2], pNoti->value[3]), 16,
                                               HAL_LCD_LINE_2);
    }
    else
    {
        HalLcdWriteStringValueValue("ImgB Id", OAD_VER_NUM( ver ), 16,
                                               BUILD_UINT16(pNoti->value[2], pNoti->value[3]), 16,
                                               HAL_LCD_LINE_2);
    }

    HalLcdWriteString((char*)userId, HAL_LCD_LINE_3);
#endif
  }
  else if (pNoti->handle == oadManagerHandles[OAD_CHAR_IMG_BLOCK])
  {
    oadBlkNum = BUILD_UINT16(pNoti->value[0], pNoti->value[1]);
    attWriteReq_t req;

    req.handle = oadManagerHandles[OAD_CHAR_IMG_BLOCK];
    req.len = 2 + OAD_BLOCK_SIZE;
    req.sig = FALSE;
    req.cmd = TRUE;

    req.value[0] = LO_UINT16(oadBlkNum);
    req.value[1] = HI_UINT16(oadBlkNum);

    uint8 page = oadBlkNum / OAD_BLOCKS_PER_PAGE;
    uint16 oset = (oadBlkNum - (OAD_BLOCKS_PER_PAGE * page)) * OAD_BLOCK_SIZE;
    HalFlashRead(page+OAD_IMG_B_PAGE, oset, req.value+2, OAD_BLOCK_SIZE);

#if (defined HAL_LCD) && (HAL_LCD == TRUE)
    if (oadBlkNum == 0)
    {
      HalLcdWriteString("", HAL_LCD_LINE_3);
    }
    HalLcdDisplayPercentBar( "OAD Progress...", (oadBlkNum / (oadBlkTot / 100)) );
#endif

    VOID GATT_WriteNoRsp(oadManagerConnHandle, &req);

    VOID osal_start_timerEx( oadManagerTaskId, OAD_DOWNLOAD_EVT, OAD_DOWNLOAD_TIMEOUT );
  }
}
Пример #18
0
/*********************************************************************
 * @fn      writeItem
 *
 * @brief   Writes an item header/data combo to the specified NV page.
 *
 * @param   pg - Valid NV Flash page.
 * @param   id - Valid NV item Id.
 * @param   len  - Byte count of the data to write.
 * @param   buf  - The data to write. If NULL, no data/checksum write.
 * @param   flag - TRUE if the checksum should be written, FALSE otherwise.
 *
 * @return  TRUE if header/data to write matches header/data read back, else FALSE.
 */
static uint8 writeItem( uint8 pg, uint16 id, uint16 len, void *buf, uint8 flag )
{
  uint16 offset = pgOff[pg-OSAL_NV_PAGE_BEG];
  uint8 rtrn = FALSE;
  osalNvHdr_t hdr;

  hdr.id = id;
  hdr.len = len;

  writeWord( pg, offset, (uint8 *)&hdr );
  HalFlashRead(pg, offset, (uint8 *)(&hdr), OSAL_NV_HDR_SIZE);

  if ( (hdr.id == id) && (hdr.len == len) )
  {
    if ( flag )
    {
      hdr.chk = calcChkB( len, buf );

      offset += OSAL_NV_HDR_SIZE;
      if ( buf != NULL )
      {
        writeBuf( pg, offset, len, buf );
      }

      if ( hdr.chk == calcChkF( pg, offset, len ) )
      {
        if ( hdr.chk == setChk( pg, offset, hdr.chk ) )
        {
          hotItemUpdate(pg, offset, hdr.id);
          rtrn = TRUE;
        }
      }
    }
    else
    {
      rtrn = TRUE;
    }

    len = OSAL_NV_ITEM_SIZE( hdr.len );
  }
  else
  {
    len = OSAL_NV_ITEM_SIZE( hdr.len );

    if (len > (OSAL_NV_PAGE_SIZE - pgOff[pg - OSAL_NV_PAGE_BEG]))
    {
      len = (OSAL_NV_PAGE_SIZE - pgOff[pg - OSAL_NV_PAGE_BEG]);
    }

    pgLost[pg - OSAL_NV_PAGE_BEG] += len;
  }
  pgOff[pg - OSAL_NV_PAGE_BEG] += len;

  return rtrn;
}
Пример #19
0
// Caller provide dev name buffer, at least 21 bytes
void persistent_get_dev_name(uint8_t *buf)
{
	uint8_t buf_flash[20];
    uint8_t idx;

    HalFlashRead(pidx, 4, buf_flash, 20);
    for (idx = 0; idx < 20; idx++) {
    	buf[idx] = buf_flash[idx];
    }
    buf[idx] = 0;
}
Пример #20
0
/*********************************************************************
 * @fn      writeBuf
 *
 * @brief   Writes a data buffer to NV.
 *
 * @param   dstPg - A valid NV Flash page.
 * @param   offset - A valid offset into the page.
 * @param   len  - Byte count of the data to write.
 * @param   buf  - The data to write.
 *
 * @return  TRUE if data buf checksum matches read back checksum, else FALSE.
 */
static void writeBuf( uint8 dstPg, uint16 dstOff, uint16 len, uint8 *buf )
{
  uint8 rem = dstOff % OSAL_NV_WORD_SIZE;
  uint8 tmp[OSAL_NV_WORD_SIZE];

  if ( rem )
  {
    dstOff = (dstOff / OSAL_NV_WORD_SIZE) * OSAL_NV_WORD_SIZE;
    HalFlashRead(dstPg, dstOff, tmp, OSAL_NV_WORD_SIZE);

    while ( (rem < OSAL_NV_WORD_SIZE) && len )
    {
      tmp[rem++] = *buf++;
      len--;
    }

    writeWord( dstPg, dstOff, tmp );
    dstOff += OSAL_NV_WORD_SIZE;
  }

  rem = len % OSAL_NV_WORD_SIZE;
  len /= OSAL_NV_WORD_SIZE;

  if ( len )
  {
    writeWordM( dstPg, dstOff, buf, len );
    dstOff += OSAL_NV_WORD_SIZE * len;
    buf += OSAL_NV_WORD_SIZE * len;
  }

  if ( rem )
  {
    uint8 idx = 0;
    HalFlashRead(dstPg, dstOff, tmp, OSAL_NV_WORD_SIZE);
    while ( rem-- )
    {
      tmp[idx++] = *buf++;
    }
    writeWord( dstPg, dstOff, tmp );
  }
}
Пример #21
0
/*********************************************************************
 * @fn      osal_nv_read
 *
 * @brief   Read data from NV. This function can be used to read an entire item from NV or
 *          an element of an item by indexing into the item with an offset.
 *          Read data is copied into *buf.
 *
 * @param   id  - Valid NV item Id.
 * @param   ndx - Index offset into item
 * @param   len - Length of data to read.
 * @param  *buf - Data is read into this buffer.
 *
 * @return  SUCCESS if NV data was copied to the parameter 'buf'.
 *          Otherwise, NV_OPER_FAILED for failure.
 */
uint8 osal_nv_read( uint16 id, uint16 ndx, uint16 len, void *buf )
{
  uint16 offset;
  uint8 hotIdx;

  if ((hotIdx = hotItem(id)) < OSAL_NV_MAX_HOT)
  {
    HalFlashRead(hotPg[hotIdx], hotOff[hotIdx]+ndx, buf, len);
    return SUCCESS;
  }

  if ((offset = findItem(id)) == OSAL_NV_ITEM_NULL)
  {
    return NV_OPER_FAILED;
  }
  else
  {
    HalFlashRead(findPg, offset+ndx, buf, len);
    return SUCCESS;
  }
}
Пример #22
0
/*********************************************************************
 * @fn      xferItem
 *
 * @brief   Copy an NV item from the active page to a designated page.
 *
 * @param   pg         - NV page where to copy the item to.
 * @param   offset     - NV page offset where to copy the item to.
 * @param   alignedLen - Length of data to write, aligned in flash word
 *                       boundary.
 * @param   srcOff     - NV page offset of the original data in active page
 *
 * @return  none.
 */
static void xferItem( uint8 pg, uint16 offset, uint16 alignedLen, uint16 srcOff )
{
  uint8 tmp[OSAL_NV_WORD_SIZE];
  uint16 i = 0;

  // Copy over the data
  while (i <= alignedLen)
  {
    HalFlashRead(activePg, srcOff + i, tmp, OSAL_NV_WORD_SIZE);
    writeWord(pg, offset + i, tmp);

    i += OSAL_NV_WORD_SIZE;
  }
}
Пример #23
0
/*********************************************************************
 * @fn      cleanErasedPage
 *
 * @brief   Erases a page in Flash if the page is not completely erased.
 *
 * @param   pg - Valid NV page to erase.
 *
 * @return  none
 */
static void cleanErasedPage( uint8 pg )
{
  uint8 buf;
  uint16 offset;

  for (offset = 0; offset < OSAL_NV_PAGE_SIZE; offset ++)
  {
    HalFlashRead(pg, offset, &buf, 1);
    if (buf != OSAL_NV_ERASED)
    {
      erasePage(pg);
      break;
    }
  }
}
Пример #24
0
/**************************************************************************************************
 * @fn          crcCalcDMA
 *
 * @brief       Run the CRC16 Polynomial calculation over the image specified,
 *              using DMA to read the flash memory into the CRC register
 *
 * input parameters
 *
 * @param       page - Flash page on which to beging the CRC calculation.
 *
 * output parameters
 *
 * None.
 *
 * @return      The CRC16 calculated.
 **************************************************************************************************
 */
static uint16 crcCalcDMA(uint8 page)
{
  uint16 crc;
  uint8 pageBeg;
  uint8 pageEnd;
  const img_hdr_t *pImgHdr;
  
  HalFlashRead(page, 0, pgBuf, HAL_FLASH_PAGE_SIZE);

  pImgHdr = (const img_hdr_t *)(pgBuf + BIM_HDR_OSET);

  pageBeg = page;
  pageEnd = pImgHdr->len / (HAL_FLASH_PAGE_SIZE / HAL_FLASH_WORD_SIZE);

  // One page is used for BIM, so we move this image's last page forward
  pageEnd += pageBeg;
  
  // If image A, set last page to be ImgA size + ImgB size
  if (pageBeg == BIM_IMG_A_PAGE)
  {
    pageEnd += BIM_IMG_B_AREA;
  }

  ADCCON1 &= 0xF3;  // CRC configuration of LRSR.

  // CRC seed of 0x0000.
  RNDL = 0x00;
  RNDL = 0x00;

  // Handle first page differently to skip CRC and CRC shadow when calculating
  DMAExecCrc(pageBeg, 4, HAL_FLASH_PAGE_SIZE-4);
  
  // Do remaining pages
  for (uint8 pg = pageBeg + 1; pg < pageEnd; pg++)
  {
    if (pg == BIM_IMG_B_PAGE)
    {
      pg += BIM_IMG_B_AREA;
    }
     
    DMAExecCrc(pg, 0, HAL_FLASH_PAGE_SIZE);
  }
  
  crc = RNDH;
  crc = (crc << 8) | RNDL;

  return crc;
}
Пример #25
0
// FIXME: currently only device name
void custom_init(void)
{
    uint8 buf[CUSTOM_DN_MAGIC_LEN + CUSTOM_DN_LEN];
    uint8 idx = 0;

    HalFlashRead(CUSTOM_DN_PAGE_IDX, CUSTOM_DN_MGIC_OFFSET, buf, (CUSTOM_DN_MAGIC_LEN + CUSTOM_DN_LEN));
    if (osal_memcmp(buf, dn_magic, CUSTOM_DN_MAGIC_LEN) != TRUE) {
        HalFlashErase(CUSTOM_DN_PAGE_IDX);
        for (idx = 0; idx < (CUSTOM_DN_MAGIC_LEN + CUSTOM_DN_LEN); idx++) {
            buf[idx] = 0;
        }
        osal_memcpy(buf, dn_magic, CUSTOM_DN_MAGIC_LEN);
        osal_memcpy((buf + CUSTOM_DN_MAGIC_LEN), dn_default, 3);
        HalFlashWrite((((uint32)CUSTOM_DN_PAGE_IDX * (uint32)2048 + CUSTOM_DN_MGIC_OFFSET) / 4), buf, (CUSTOM_DN_MAGIC_LEN + CUSTOM_DN_LEN) / 4);
    }
}
Пример #26
0
/*********************************************************************
 * @fn      findOffset
 *
 * @brief   find an offset of an empty space in active page
 *          where to write a new item to.
 *
 * @param   None
 *
 * @return  none
 */
static void findOffset(void)
{
  uint16 offset;
  for (offset = OSAL_NV_PAGE_SIZE - OSAL_NV_WORD_SIZE;
       offset >= OSAL_NV_PAGE_HDR_SIZE;
       offset -= OSAL_NV_WORD_SIZE)
  {
    uint32 tmp;

    HalFlashRead(activePg, offset, (uint8 *)&tmp, OSAL_NV_WORD_SIZE);
    if (tmp != 0xFFFFFFFF)
    {
      break;
    }
  }
  pgOff = offset + OSAL_NV_WORD_SIZE;
}
Пример #27
0
/**************************************************************************************************
 * @fn          sblExec
 *
 * @brief       Act on the SB command and received buffer.
 *
 * @param       pBuf - A pointer to the RPC command buffer received.
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
static void sblExec(uint8 *pBuf)
{
    uint16 t16 = BUILD_UINT16(pBuf[SBL_REQ_ADDR_LSB],pBuf[SBL_REQ_ADDR_MSB]) + OAD_DONGLE_SBL_IMG_BEG;
    uint8 len = 1;
    uint8 rsp = SBL_SUCCESS;

    switch (pBuf[RPC_POS_CMD1])
    {
    case SBL_WRITE_CMD:
        if ((t16 >= OAD_DONGLE_SBL_IMG_END) || (t16 < OAD_DONGLE_SBL_IMG_BEG))
        {
            rsp = SBL_FAILURE;
            break;
        }
        if ((t16 % SBL_PAGE_SIZE) == 0)
        {
            HalFlashErase(t16 / SBL_PAGE_SIZE);
        }
        HalFlashWrite(t16, (pBuf + SBL_REQ_DAT0), (SBL_RW_BUF_LEN / HAL_FLASH_WORD_SIZE));
        break;

    case SBL_READ_CMD:
        len = SBL_RW_BUF_LEN + SBL_READ_HDR_LEN;
        pBuf[SBL_RSP_ADDR_MSB] = pBuf[SBL_REQ_ADDR_MSB];
        pBuf[SBL_RSP_ADDR_LSB] = pBuf[SBL_REQ_ADDR_LSB];

        HalFlashRead(t16 / SBL_PAGE_SIZE,
                     (t16 % SBL_PAGE_SIZE) << 2, (pBuf + SBL_RSP_DAT0), SBL_RW_BUF_LEN);
        break;

    case SBL_ENABLE_CMD:
        // Bootload master must verify download by read back - no room for CRC checking code in dongle.
        break;

    case SBL_HANDSHAKE_CMD:
        break;

    default:
        rsp = SBL_FAILURE;
        break;
    }

    pBuf[RPC_POS_LEN] = len;
    pBuf[RPC_POS_CMD1] |= SBL_RSP_MASK;
    pBuf[RPC_POS_DAT0] = rsp;
}
Пример #28
0
/**************************************************************************************************
 * @fn          crcCalcDL
 *
 * @brief       Run the CRC16 Polynomial calculation over the DL image.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      The CRC16 calculated.
 **************************************************************************************************
 */
static uint16 crcCalcDL(void)
{
  uint8 pageEnd = oadBlkTot / OAD_BLOCKS_PER_PAGE;
  uint16 osetEnd = (oadBlkTot - (pageEnd * OAD_BLOCKS_PER_PAGE)) * OAD_BLOCK_SIZE;

#if defined HAL_IMAGE_B
  pageEnd += OAD_IMG_D_PAGE + OAD_IMG_B_AREA;
#else
  pageEnd += OAD_IMG_D_PAGE;
#endif

  HalCRCInit(0x0000);  // Seed thd CRC calculation with zero.

  for (uint8 page = OAD_IMG_D_PAGE; ; page++)
  {
#if defined HAL_IMAGE_B
    // Skip the Image-B area which lies between the lower & upper Image-A parts.
    if (page == OAD_IMG_B_PAGE)
    {
      page += OAD_IMG_B_AREA;
    }
#endif

    for (uint16 oset = 0; oset < HAL_FLASH_PAGE_SIZE; oset += HAL_FLASH_WORD_SIZE)
    {
      if ((page == OAD_IMG_D_PAGE) && (oset == OAD_IMG_CRC_OSET))
      {
        continue;  // Skip the CRC and shadow.
      }
      else if ((page == pageEnd) && (oset == osetEnd))
      {
        return HalCRCCalc();
      }
      else
      {
        uint8 buf[HAL_FLASH_WORD_SIZE];
        HalFlashRead(page, oset, buf, HAL_FLASH_WORD_SIZE);

        for (uint8 idx = 0; idx < HAL_FLASH_WORD_SIZE; idx++)
        {
          HalCRCExec(buf[idx]);
        }
      }
    }
  }
}
Пример #29
0
/*********************************************************************
 * @fn      verifyWordM
 *
 * @brief   verify the written word.
 *
 * @param   pg - A valid NV Flash page.
 * @param   offset - A valid offset into the page.
 * @param   pBuf - Pointer to source buffer.
 * @param   cnt - Number of 4-byte blocks to verify.
 *
 * @return  none
 */
static void verifyWordM( uint8 pg, uint16 offset, uint8 *pBuf, osalSnvLen_t cnt )
{
  uint8 tmp[OSAL_NV_WORD_SIZE];

  while (cnt--)
  {
    // Reading byte per byte will reduce code size but will slow down
    // and not sure it will meet the timing requirements.
    HalFlashRead(pg, offset, tmp, OSAL_NV_WORD_SIZE);
    if (FALSE == osal_memcmp(tmp, pBuf, OSAL_NV_WORD_SIZE))
    {
      failF = TRUE;
      return;
    }
    offset += OSAL_NV_WORD_SIZE;
    pBuf += OSAL_NV_WORD_SIZE;
  }
}
Пример #30
0
void persistent_pwrmgmt_set_latest(struct pwrmgmt_data *pwr_ptr)
{
	uint8_t count;
	uint32_t pwr_idx_bits, u32;

	u32 = (uint32)&(((struct persistent_page *)0)->pwr_idx_bits[0]);
    HalFlashRead(pidx, (uint16_t)u32, (uint8_t *)&pwr_idx_bits, 4);
	count = __persistent_get_idx_from_bit_map((uint8_t *)&pwr_idx_bits, 4);
	if (count < PERSISTENT_PWR_MAX) {
		u32 = (uint32)&(((struct persistent_page *)0)->pwr_log[count]);
		HalFlashWrite(pidx, (uint16_t)u32, (uint8_t *)pwr_ptr, sizeof(struct pwrmgmt_data));
		__persistent_mark_bit_map((uint8_t *)&pwr_idx_bits, 4);
		u32 = (uint32)&(((struct persistent_page *)0)->pwr_idx_bits[0]);
		HalFlashWrite(pidx, (uint16_t)u32, (uint8_t *)&pwr_idx_bits, 4);
	} else {
		flash_trigger_refresh_pwr_mgmt_info(pwr_ptr);
	}
}