📄 skgespi.c
字号:
static int spi_yuk2_update_config(unsigned char *data,unsigned long off,unsigned long len){ unsigned char *spibuf; unsigned long start_sector; unsigned long end_sector; unsigned long i; /* determine the affected sectors */ start_sector = off / spi_yuk2_dev_table[spi_yuk2_dev].sector_size; end_sector = (off + len - 1) / spi_yuk2_dev_table[spi_yuk2_dev].sector_size; /* * allocate the necessary memory for temporary * save of the affected sectors */ spibuf = spi_malloc((unsigned long)(((end_sector - start_sector) + 1) * spi_yuk2_dev_table[spi_yuk2_dev].sector_size)); if(spibuf == NULL) { return(51); } /* read out the affected sectors */ if (spi_flash_manage(spibuf, start_sector * spi_yuk2_dev_table[spi_yuk2_dev].sector_size, ((end_sector - start_sector) + 1) * spi_yuk2_dev_table[spi_yuk2_dev].sector_size, SPI_READ)) { spi_free(spibuf); return(1); } /* update the just read out data */ for (i = 0; i < len; i++) { spibuf[off + i - SPI_LSECT_OFF] = data[i]; } /* erase the affected sectors */ if (spi_flash_erase(start_sector * spi_yuk2_dev_table[spi_yuk2_dev].sector_size, ((end_sector - start_sector) + 1) * spi_yuk2_dev_table[spi_yuk2_dev].sector_size)) { spi_free(spibuf); return(7); } /* write the updated data back to the flash */ if (spi_flash_manage(spibuf, start_sector * spi_yuk2_dev_table[spi_yuk2_dev].sector_size, ((end_sector - start_sector) + 1) * spi_yuk2_dev_table[spi_yuk2_dev].sector_size, SPI_WRITE)) { spi_free(spibuf); return(8); } spi_free(spibuf); return(0);}/* * BEGIN_MANUAL_ENTRY() * * static int spi_update_config( * unsigned char *data, * unsigned long off, * unsigned long len) * * Update part of config area * * Uses: spi_flash_manage, spi_flash_erase * * IN: * data data buffer * off start offset in flash eprom (config area) for operation * len length of changing data * * return: * 0 Success * 1 Timeout * * END_MANUAL_ENTRY() */static int spi_update_config(unsigned char *data,unsigned long off,unsigned long len){ switch (fl_type) { case FT_SPI: return(spi_yuk_update_config(data, off, len)); break; case FT_SPI_Y2: return(spi_yuk2_update_config(data, off, len)); break; } return(1);}/* * BEGIN_MANUAL_ENTRY() * * int flash_check_spi( unsigned long *FlashSize ) * * Determines whether a SPI Eprom present * * Uses: spi_in32, spi_out32 * * IN: * * return: * 0 No SPI * 1 SPI detected * * END_MANUAL_ENTRY() */#ifdef USE_ASF_DASH_FWint flash_check_spi( unsigned long *FlashSize ){ unsigned long a1,a2; unsigned long opcodes; *FlashSize = 0; spi_in8(B2_CHIP_ID, &chip_id); if (chip_id == CHIP_ID_YUKON_LITE || chip_id == CHIP_ID_YUKON_LP) { /* YUKON-Lite Rev. A1 */ fl_type = FT_SPI; *FlashSize = max_pages * max_faddr; fl_print("\nFlash Device\t: SPI\n"); return(1); } if (chip_id >= CHIP_ID_YUKON_XL && chip_id <= CHIP_ID_YUKON_FE) { fl_type = FT_SPI_Y2; spi_yuk2_dev = spi_yuk2_get_dev_index(); /* unknown or no flash */ if(spi_yuk2_dev < 0) { fl_print("\nFlash device\t: none\n"); fl_type = FT_SPI_UNKNOWN; return(0); } max_pages = (long)(spi_yuk2_dev_table[spi_yuk2_dev].sector_num); max_faddr = (long)(spi_yuk2_dev_table[spi_yuk2_dev].sector_size); *FlashSize = spi_yuk2_dev_table[spi_yuk2_dev].sector_num * spi_yuk2_dev_table[spi_yuk2_dev].sector_size; /* * work around for SST flash types to clear write * protection bits which are set by default. */ if (spi_yuk2_dev_table[spi_yuk2_dev].man_id == SPI_MAN_ID_SST) { spi_yuk2_sst_clear_write_protection(); } /* * set the opcodes for the SPI flash found */ spi_in32(SPI_Y2_OPCODE_REG1, &opcodes); opcodes &= 0x000000ffL; opcodes |= ((((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_read)) << 8) | (((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_read_id)) << 16) | (((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_read_status)) << 24)); spi_out32(SPI_Y2_OPCODE_REG1, opcodes); opcodes = (((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_write_enable)) | (((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_write)) << 8) | (((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_sector_erase)) << 16) | (((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_chip_erase)) << 24)); spi_out32(SPI_Y2_OPCODE_REG2, opcodes); return(1); } /* Save Eprom Address Register 1 */ spi_in32(SPI_ADR_REG1, &a1); /* Write SPI pattern */ spi_out32(SPI_ADR_REG1, SPI_PATTERN); /* Read SPI pattern */ spi_in32(SPI_ADR_REG1, &a2); /* Restore Eprom Address Register 1 */ spi_out32(SPI_ADR_REG1, a1); /* This is a SPI Eprom if one of bits 31..16 are set */ if ((a2 & SPI_COMP_MASK) != 0) { /* YUKON-Lite Rev. A0 */ fl_type = FT_SPI; *FlashSize = max_pages * max_faddr; return(1); } return(0);}#elseint flash_check_spi( unsigned long *FlashSize ){ unsigned long a1,a2; unsigned long opcodes; *FlashSize = 0; spi_in8(B2_CHIP_ID, &chip_id); if (chip_id == CHIP_ID_YUKON_LITE || chip_id == CHIP_ID_YUKON_LP) { /* YUKON-Lite Rev. A1 */ fl_type = FT_SPI; *FlashSize = max_pages * max_faddr; return(1); } if (chip_id == CHIP_ID_YUKON_XL || chip_id == CHIP_ID_YUKON_EC) { fl_type = FT_SPI_Y2; spi_yuk2_dev = spi_yuk2_get_dev_index(); /* unknown or no flash */ if(spi_yuk2_dev < 0) { fl_print("\nNo SPI flash found !\n"); fl_type = FT_SPI_UNKNOWN; return(0); } max_pages = (long)(spi_yuk2_dev_table[spi_yuk2_dev].sector_num); max_faddr = (long)(spi_yuk2_dev_table[spi_yuk2_dev].sector_size); *FlashSize = spi_yuk2_dev_table[spi_yuk2_dev].sector_num * spi_yuk2_dev_table[spi_yuk2_dev].sector_size; /* * work around for SST flash types to clear write * protection bits which are set by default. */ if (spi_yuk2_dev_table[spi_yuk2_dev].man_id == SPI_MAN_ID_SST) { spi_yuk2_sst_clear_write_protection(); } /* * set the opcodes for the SPI flash found */ spi_in32(SPI_Y2_OPCODE_REG1, &opcodes); opcodes &= 0x000000ffL; opcodes |= ((((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_read)) << 8) | (((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_read_id)) << 16) | (((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_read_status)) << 24)); spi_out32(SPI_Y2_OPCODE_REG1, opcodes); opcodes = (((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_write_enable)) | (((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_write)) << 8) | (((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_sector_erase)) << 16) | (((unsigned long)(spi_yuk2_dev_table[spi_yuk2_dev].opcodes.op_chip_erase)) << 24)); spi_out32(SPI_Y2_OPCODE_REG2, opcodes); return(1); } /* Save Eprom Address Register 1 */ spi_in32(SPI_ADR_REG1, &a1); /* Write SPI pattern */ spi_out32(SPI_ADR_REG1, SPI_PATTERN); /* Read SPI pattern */ spi_in32(SPI_ADR_REG1, &a2); /* Restore Eprom Address Register 1 */ spi_out32(SPI_ADR_REG1, a1); /* This is a SPI Eprom if one of bits 31..16 are set */ if ((a2 & SPI_COMP_MASK) != 0) { /* YUKON-Lite Rev. A0 */ fl_type = FT_SPI; *FlashSize = max_pages * max_faddr; return(1); } return(0);}#endif/* * BEGIN_MANUAL_ENTRY() * * int spi_flash_erase(unsigned long off,unsigned long len) * * Send chip erase command to SPI Eprom * * Uses: spi_in32, spi_out32, spi_in8, spi_timer * * IN: * off start offset in flash eprom for erase * len length in flash eprom for erase * (all nessesory sectors will be erased) * * return: * 0 Success * 1 Timeout * * END_MANUAL_ENTRY() */int spi_flash_erase(unsigned long off,unsigned long len){ switch (fl_type) { case FT_SPI: return(spi_yuk_flash_erase(off, len)); break; case FT_SPI_Y2: return(spi_yuk2_flash_erase(off, len)); break; } return(1);}/* * BEGIN_MANUAL_ENTRY() * * int spi_flash_manage( * unsigned char *data, * unsigned long off, * unsigned long len, * int flag) * * Read, Verify or Write SPI Eprom * * Uses: spi_in32, spi_out32, spi_in8, spi_out8, spi_in16, spi_out16, spi_timer * * IN: * data data buffer * off start offset in flash eprom for operation * len length in flash eprom * flag SPI_READ * SPI_VERIFY * SPI_WRITE * * return: * 0 Success * 1 Timeout * * END_MANUAL_ENTRY() */int spi_flash_manage(unsigned char *data,unsigned long off,unsigned long len,int flag){ switch (fl_type) { case FT_SPI: return(spi_yuk_flash_manage(data, off, len, flag)); break; case FT_SPI_Y2: return(spi_yuk2_flash_manage(data, off, len, flag)); break; } return(1);}/* * BEGIN_MANUAL_ENTRY() * * int spi_get_pig( * unsigned char *data, * unsigned long len) * * Get data from PiG area in SPI eprom * * Uses: spi_update_config * * IN: * data data buffer * len length of wanted data * * return: * 0 Success * 1 Timeout * * END_MANUAL_ENTRY() */int spi_get_pig(unsigned char *data,unsigned long len){ return(spi_flash_manage(data, SPI_PIG_OFF, len, SPI_READ));} /* * BEGIN_MANUAL_ENTRY() * * int spi_get_noc( * unsigned char *data, * unsigned long len) * * Get data from VPD area in SPI eprom * * Uses: spi_update_config * * IN: * data data buffer * len length of wanted data * * return: * 0 Success * 1 Timeout * * END_MANUAL_ENTRY() */int spi_get_noc(unsigned char *data,unsigned long len){ return(spi_flash_manage(data, SPI_NOC_OFF, len, SPI_READ));} /* * BEGIN_MANUAL_ENTRY() * * int spi_update_pig( * unsigned char *data, * unsigned long len) * * Update data in PiG area in SPI eprom * * Uses: spi_update_config * * IN: * data data buffer * len length of data to update * * return: * 0 Success * 1 Timeout * * END_MANUAL_ENTRY() */int spi_update_pig(unsigned char *data,unsigned long len){ return(spi_update_config(data, SPI_PIG_OFF, len));} /* * BEGIN_MANUAL_ENTRY() * * int spi_update_noc( * unsigned char *data, * unsigned long len) * * Update data in NOC area in SPI eprom * * Uses: spi_update_config * * IN: * data data buffer * len length of data to update * * return: * 0 Success * 1 Timeout * * END_MANUAL_ENTRY() */int spi_update_noc(unsigned char *data,unsigned long len){ return(spi_update_config(data, SPI_NOC_OFF, len));} /* * BEGIN_MANUAL_ENTRY() * * int spi_vpd_tranfer( * char *buf, * int addr, * int len, * int dir) * * Read or update data in VPD area in SPI eprom * * Uses: spi_update_config * * IN: * buf data buffer * addr VPD start address * len number of bytes to read / to write * dir transfer direction may be VPD_READ or VPD_WRITE * * return: * 0 Success * 1 Timeout * * END_MANUAL_ENTRY() */int spi_vpd_transfer(char *buf, /* data buffer */int addr, /* VPD start address */int len, /* number of bytes to read / to write */int dir) /* transfer direction may be VPD_READ or VPD_WRITE */{ if (dir == 0) { return(spi_flash_manage(buf, SPI_VPD_OFF + addr, len, SPI_READ)); } else { return(spi_update_config(buf, SPI_VPD_OFF + addr, len)); } }/* * BEGIN_MANUAL_ENTRY() * * int spi_update_pet( * unsigned char *data, * unsigned long len) * * Update data in PET area in SPI eprom * * Uses: spi_update_config * * IN: * data data buffer * len length of data to update * * return: * 0 Success * 1 Timeout * * END_MANUAL_ENTRY() */int spi_update_pet(unsigned char *data,unsigned long len){ return(spi_update_config(data, SPI_PET_OFF, len));} /* * BEGIN_MANUAL_ENTRY() * * int spi_get_pet( * unsigned char *data, * unsigned long len) * * Get data from Pet frames area in SPI eprom * * Uses: spi_update_config * * IN: * data data buffer * len length of wanted data * * return: * 0 Success * 1 Timeout * * END_MANUAL_ENTRY() */int spi_get_pet(unsigned char *data,unsigned long len){ return(spi_flash_manage(data, SPI_PET_OFF, len, SPI_READ));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -