bootloader/iap.c

128 lines
3.2 KiB
C

/*
===============================================================================
Name : iap.c
Author : $(author)
Version :
Copyright : $(copyright)
Description : main definition
===============================================================================
*/
#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif
#include "iap.h"
unsigned int command[5];
unsigned int output[5];
IAP iap_entry =(IAP) IAP_LOCATION;
int addr_to_sector(unsigned long int addr){
int tmp = addr & 0xfffff;
tmp = tmp >> 12;
if(tmp <= 15) return tmp;
else{
if(tmp >= 0x10 && tmp <=0x17)
return 16;
else if(tmp >= 0x18 && tmp <= 0x1f)
return 17;
else if(tmp >= 0x20 && tmp <= 0x27)
return 18;
else if(tmp >= 0x28 && tmp <= 0x2f)
return 19;
else if(tmp >= 0x30 && tmp <= 0x37)
return 20;
else if(tmp >= 0x38 && tmp <= 0x3f)
return 21;
else if(tmp >= 0x40 && tmp <= 0x47)
return 22;
else if(tmp >= 0x48 && tmp <= 0x4f)
return 23;
else if(tmp >= 0x50 && tmp <= 0x57) return 24;
else if(tmp >= 0x58 && tmp <= 0x3f) return 25;
else if(tmp >= 0x60 && tmp <= 0x67) return 26;
else if(tmp >= 0x68 && tmp <= 0x6f) return 27;
else if(tmp >= 0x70 && tmp <= 0x77) return 28;
else if(tmp >= 0x78 && tmp <= 0x7f) return 29;
}
return -1;
}
void iap_entry_wrapped(void){
__disable_irq();
iap_entry(command, output);
__enable_irq();
}
void iap_prepare_sectors(error_code* status, int start, int end){
command[0] = 50;
command[1] = start;
command[2] = end;
iap_entry_wrapped();
if(output[0] == IAP_CMD_SUCCESS) {
*status = 0;
}else{
*status = output[0];
}
}
void iap_erase_sectors(error_code* status, int start, int end){
iap_prepare_sectors(status, start, end);
command[0] = 52; //erase sectors
command[1] = start; //start sector
command[2] = end; //end sector
command[3] = IAP_CLOCK_100M;
iap_entry_wrapped();
if(output[0] == IAP_CMD_SUCCESS) {
}else{
*status = output[0];
}
}
uint32_t iap_read_part_id(error_code* status){
//iap_prepare_sectors(dst_flash, dst_flash+num_bytes-1);
iap_prepare_sectors(status, 2, 10);
command[0] = 54;
iap_entry_wrapped();
if(output[0] == IAP_CMD_SUCCESS) {
*status = 0;
return output[1];
}else{
*status = -1;
return -1;
}
}
void iap_copy_to_flash(error_code* status, long unsigned int* dst_flash, uint8_t* src_ram, int num_bytes){
iap_prepare_sectors(status, addr_to_sector((long unsigned int)dst_flash), addr_to_sector((long unsigned int)dst_flash+num_bytes));
command[0] = 51;
command[1] = (unsigned int)dst_flash;
command[2] = (unsigned int)src_ram;
command[3] = num_bytes;
command[4] = IAP_CLOCK_100M;
iap_entry_wrapped();
if(output[0] == IAP_CMD_SUCCESS) {
*status = 0;
}else{
*status = output[0];
}
}
void iap_read_serial(error_code* status, uint32_t* res){
//iap_prepare_sectors(status, 2, 9);
command[0] = 58;
iap_entry_wrapped();
if(output[0] == IAP_CMD_SUCCESS) {
*status = 0;
res[0] = output[1];
res[1] = output[2];
res[2] = output[3];
res[3] = output[4];
}else{
*status = output[0];
}
}