/*
===============================================================================
 Name        : iap.c
 Author      : $(author)
 Version     :
 Copyright   : $(copyright)
 Description : main definition
===============================================================================
*/

#ifdef __USE_CMSIS
#include "LPC17xx.h"
#endif

#include "iap.h"

uint32_t command[5];
uint32_t output[5];
IAP iap_entry =(IAP) IAP_LOCATION;



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, int dst_flash, uint32_t* src_ram, int num_bytes){
    //iap_prepare_sectors(status, dst_flash, dst_flash+num_bytes);
    //iap_erase_sectors(status, dst_flash, dst_flash+num_bytes);
    iap_prepare_sectors(status, dst_flash, dst_flash+num_bytes);
    command[0] = 51;
    command[1] = dst_flash;
    command[2] = 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 = -1;
    }
}

// TODO: insert other include files here

// TODO: insert other definitions and declarations here
/*
int main(void) {
    LPC_PINCON->PINSEL4 &= ~0xFF;  //Configure the PORT2 Pins as GPIO;
    LPC_GPIO2->FIODIR = 0xff;  //Configure the PORT2 pins as OUTPUT;
    iap_read_part_id();
    iap_erase_sectors(2, 9);
    iap_copy_to_flash(0x8000,(uint8_t*)test, 4);
}*/
