void SpiFlash::writeCmd(cTerm & t,int argc,char *argv[])
{
	if (argc > 3)
	{
		cyg_uint32 addr = (cyg_uint32)strtoul(argv[1],NULL,16);
		cyg_uint32 num = (cyg_uint32)strtoul(argv[2],NULL,16);
		cyg_uint8 val = (cyg_uint8)strtoul(argv[3],NULL,16);

		cyg_uint8 buff[num];

		memset(buff,val,num);


		int error = cyg_flash_program(addr, buff, num, 0);

		if (!error)
		{
			t<<t.format(GREEN("Wrote %d bytes of 0x%02X to serial flash at address 0x%08X\n"), num, val, addr);
		}
		else
		{
			t<<(RED("Error writing to serial flash!\n"));
			printfError(error);
		}
	}
	else
	{
		t<<"You need to supply an address, number of bytes and value to write\n";
	}
}
Example #2
0
/**
 * Store parameters of object dictionary into flash memory.
 * \param[in] FlashAddress Use CO_OD_Flash_Adress for the normal parameter
 *                         block and CO_OD_Flash_Default_Param for the
 *                         default parameters
 */
static CO_SDO_abortCode_t storeParameters(cyg_flashaddr_t FlashAddress,
	uint8_t ParametersSub)
{
	CO_DBG_PRINT("Store parameters\n");

	cyg_flashaddr_t ErrorAddress;

	//unlock flash
#ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
	int Result = cyg_flash_unlock(FlashAddress, sizeof(struct sCO_OD_ROM),
		&ErrorAddress);
	CHECK_FLASH_RESULT(Result);
	if (CYG_FLASH_ERR_OK != Result)
	{
		return CO_SDO_AB_HW;
	}
#endif

	// erase block
	Result = cyg_flash_erase(FlashAddress, sizeof(struct sCO_OD_ROM),
		&ErrorAddress);
	CHECK_FLASH_RESULT(Result);
	if (CYG_FLASH_ERR_OK != Result)
	{
		return CO_SDO_AB_HW;
	}

	// program data into flash
	Result = cyg_flash_program(FlashAddress, &CO_OD_ROM,
		sizeof(CO_OD_ROM), &ErrorAddress);
	CHECK_FLASH_RESULT(Result);
	if (CYG_FLASH_ERR_OK != Result)
	{
		return CO_SDO_AB_HW;
	}

	return CO_SDO_AB_NONE;
}
Example #3
0
__externC int
cyg_flash_program(cyg_flashaddr_t flash_base,
                  const void *ram_base,
                  size_t len,
                  cyg_flashaddr_t *err_address)
{
  struct cyg_flash_dev * dev;
  cyg_flashaddr_t addr, end_addr, block;
  const unsigned char * ram = ram_base;
  size_t write_count, offset;
  int stat = CYG_FLASH_ERR_OK;
  HAL_FLASH_CACHES_STATE(d_cache, i_cache);

  dev = find_dev(flash_base, &stat);
  if (!dev) return stat;

  CHECK_SOFT_WRITE_PROTECT(flash_base, len);

  LOCK(dev);
  addr = flash_base;
  if (len > (dev->end + 1 - flash_base)) {
    end_addr = dev->end;
  } else {
    end_addr = flash_base + len - 1;
  }
  write_count = (end_addr + 1) - flash_base;

  // The first write may be in the middle of a block. Do the necessary
  // adjustment here rather than inside the loop.
  block = flash_block_begin(flash_base, dev);
  if (addr == block) {
      offset = 0;
  } else {
      offset = addr - block;
  }

  CHATTER(dev, "... Program from %p-%p to %p: ", ram_base, ((CYG_ADDRESS)ram_base)+write_count, addr);

  HAL_FLASH_CACHES_OFF(d_cache, i_cache);
  FLASH_Enable(flash_base, end_addr);
  while (write_count > 0) {
    size_t block_size = flash_block_size(dev, addr);
    size_t this_write;
    if (write_count > (block_size - offset)) {
        this_write = block_size - offset;
    } else {
        this_write = write_count;
    }
    // Only the first block may need the offset.
    offset       = 0;

    FLASH_WATCHDOG_RESET;
    stat = dev->funs->flash_program(dev, addr, ram, this_write);
#ifdef CYGSEM_IO_FLASH_VERIFY_PROGRAM
    if (CYG_FLASH_ERR_OK == stat) // Claims to be OK
      if (!dev->funs->flash_read && memcmp((void *)addr, ram, this_write) != 0) {
        stat = CYG_FLASH_ERR_DRV_VERIFY;
        CHATTER(dev, "V");
      }
#endif
    if (CYG_FLASH_ERR_OK != stat) {
        if (err_address)
            *err_address = addr;
        break;
    }
    CHATTER(dev, ".");
    write_count -= this_write;
    addr        += this_write;
    ram         += this_write;
  }
  FLASH_Disable(flash_base, end_addr);
  HAL_FLASH_CACHES_ON(d_cache, i_cache);
  CHATTER(dev, "\n");
  UNLOCK(dev);
  if (stat != CYG_FLASH_ERR_OK) {
    return (stat);
  }
  if (len > (dev->end + 1 - flash_base)) {
    FLASH_WATCHDOG_RESET;
    return cyg_flash_program(dev->end+1, ram,
                             len - (dev->end + 1 - flash_base),
                             err_address);
  }
  return CYG_FLASH_ERR_OK;
}
Example #4
0
void cyg_user_start(void)
{
    int ret;
    cyg_flashaddr_t flash_start=0, flash_end=0;
    cyg_flash_info_t info;
    cyg_uint32 i=0;
    cyg_uint32 j;
    int block_size=0, blocks=0;
    cyg_flashaddr_t prog_start;
    unsigned char * ptr;

    CYG_TEST_INIT();
  
    cyg_flash_set_global_printf((cyg_flash_printf *)&diag_printf);
    ret=cyg_flash_init(NULL);
    
    CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_init");

    do {
      ret = cyg_flash_get_info(i, &info);
      if (ret == CYG_FLASH_ERR_OK) {
        diag_printf("INFO: Nth=%d, start=%p, end=%p\n",
                    i, (void *) info.start, (void *) info.end);
        if (i == 0) {
          flash_start = info.start;
          flash_end = info.end;
          block_size = info.block_info[0].block_size;
          blocks = info.block_info[0].blocks;
        }
        for (j=0;j < info.num_block_infos; j++) {
          diag_printf("INFO:\t block_size %zd, blocks %u\n",
                      info.block_info[j].block_size,
                      info.block_info[j].blocks);
        }
      }
      i++;
    } while (ret != CYG_FLASH_ERR_INVALID);
    
    /* Erase the whole flash. Not recommended on real hardware since this
     will probably erase the bootloader etc!!! */
    ret=cyg_flash_erase(flash_start,block_size * blocks,NULL);
    CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_erase1");

    /* check that its actually been erased, and test the mmap area */
    for (ptr=(unsigned char *)flash_start,ret=0; 
         ptr <= (unsigned char *)flash_end; ptr++) {
        if (*ptr != 0xff) {
            ret++;
        }
    }
  
    CYG_TEST_PASS_FAIL((ret == 0),"flash empty check");

    ret = cyg_flash_program(flash_start,&copyright,sizeof(copyright),NULL);
    CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_program1");
  
    /* Check the contents made it into the flash */
    CYG_TEST_PASS_FAIL(!strncmp((void *)flash_start,
                                copyright,sizeof(copyright)),
                       "flash program contents");

    /* .. and check nothing else changed */
    for (ptr=(unsigned char *)flash_start+sizeof(copyright),ret=0; 
         ptr < (unsigned char *)flash_end; ptr++) {
        if (*ptr != 0xff) {
            ret++;
        }
    }
  
    CYG_TEST_PASS_FAIL((ret == 0),"flash program overrun check");

    /* Program over a block boundary */
    prog_start = flash_start + block_size - sizeof(copyright)/2;
    ret = cyg_flash_program(prog_start,&copyright,sizeof(copyright),NULL);
    CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_program2");
  
    /* Check the first version is still OK */
    CYG_TEST_PASS_FAIL(!strncmp((void *)flash_start,
                                copyright,
                                sizeof(copyright)),
                       "Original contents");
  
    CYG_TEST_PASS_FAIL(!strncmp((void *)prog_start,
                                copyright,
                                sizeof(copyright)),
                       "New program contents");

    /* Check the bit in between is still erased */
    for (ptr=(unsigned char *)flash_start+sizeof(copyright),ret=0; 
         ptr < (unsigned char *)prog_start; ptr++) {
        if (*ptr != 0xff) {
            ret++;
        }
    }
    CYG_TEST_PASS_FAIL((ret == 0),"flash erase check1");
  
    /* Erase the second block and make sure the first is not erased */
    ret=cyg_flash_erase(flash_start+block_size,block_size,NULL);
    CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_erase2");

    /* Check the erase worked */
    for (ptr=(unsigned char *)flash_start+block_size,ret=0; 
         ptr < (unsigned char *)flash_start+block_size*2; 
         ptr++) {
        if (*ptr != 0xff) {
            ret++;
        }
    }

    CYG_TEST_PASS_FAIL((ret == 0), "flash erase check2");
  
    /* Lastly check the first half of the copyright message is still there */
    CYG_TEST_PASS_FAIL(!strncmp((void *)prog_start,
                                copyright,
                                sizeof(copyright)/2),
                       "Block 1 OK");

#if 0
    /* This test is be fatal! Its not run by default!
     Check the flash is read only, by trying to write to it. We expect
     to get an exception */

    *(char *)flash_start = 'a';
#endif

    CYG_TEST_PASS_FINISH("flash2");
}