/*
 * my_params_prod.c
 *
 *  Created on: gg/mmm/ccaa
 *      Author: cognome.nome
 *
 *
 *
 */

//==============================================================================
// Include files

#include "string.h"
#include "stdbool.h"
#include "stdint.h"

#include "inc/hw_memmap.h"
#include "inc/hw_ints.h"

#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/rom.h"
#include "utils/lwiplib.h"

#include "drivers/AD7193.h"
#include "drivers/my_flash.h"
#include "drivers/my_params_prod.h"

//==============================================================================
// Constants

//==============================================================================
// Types

//==============================================================================
// Static global variables

//==============================================================================
// Static functions

static void EthParamsProdCall(void *arg, struct udp_pcb *pcb, struct pbuf *p,struct ip_addr *addr, u16_t port)
{
	unsigned char *pucData,cmd,type;
	unsigned long *pDataLong;

	pDataLong = (unsigned long *)((unsigned long)p->payload + sizeof(unsigned short));
	pucData = (unsigned char *)p->payload;
    cmd = pucData[0];
    type = pucData[1];
    pbuf_free(p);

    if(cmd=='B' && type=='B')
    {
		p = pbuf_alloc(PBUF_TRANSPORT, 64, PBUF_RAM);
		pucData = (unsigned char *)p->payload;
		memset(pucData,0,64);
		pucData[0]= cmd;
		pucData[1]= type;
        udp_sendto(pcb, p, addr, port);
    	pbuf_free(p);
    	flagBootCall = 1;
    }
    else if(cmd=='P' && type=='P')
    {
    	parProd.serial_number = ntohl(*pDataLong++);
    	parProd.part_number   = ntohl(*pDataLong++);
    	parProd.offset_ch_1   = ntohl(*pDataLong++);
    	parProd.offset_ch_2   = ntohl(*pDataLong++);
    	parProd.offset_ch_3   = ntohl(*pDataLong++);
    	parProd.offset_ch_4   = ntohl(*pDataLong++);
    	WriteProdParameters(&parProd);
		p = pbuf_alloc(PBUF_TRANSPORT, 64, PBUF_RAM);
		pucData = (unsigned char *)p->payload;
		memset(pucData,0,64);
		pucData[0]= cmd;
		pucData[1]= type;
        udp_sendto(pcb, p, addr, port);
    	pbuf_free(p);
    }

    return;
}

//==============================================================================
// Global variables

volatile unsigned long flagBootCall = 0;

//==============================================================================
// Global functions

void BootCall(void)
{
	unsigned long index,flash_end;

	ROM_WatchdogResetDisable(WATCHDOG0_BASE);

	ROM_IntDisable(INT_GPIOB);
	ROM_IntDisable(INT_GPIOE);
	ROM_IntDisable(INT_GPIOR);
	ROM_IntDisable(INT_UART0);
	ROM_IntDisable(INT_TIMER0A);
	ROM_IntDisable(INT_TIMER1A);
	ROM_IntDisable(INT_FLASH);
	ROM_IntDisable(INT_EMAC0);
    ROM_IntDisable(INT_WATCHDOG);
    ROM_IntDisable(FAULT_SYSTICK);

    ROM_IntPendClear(INT_GPIOB);
    ROM_IntPendClear(INT_GPIOE);
	ROM_IntPendClear(INT_GPIOR);
    ROM_IntPendClear(INT_UART0);
    ROM_IntPendClear(INT_TIMER0A);
    ROM_IntPendClear(INT_TIMER1A);
    ROM_IntPendClear(INT_FLASH);
    ROM_IntPendClear(INT_EMAC0);
    ROM_IntPendClear(INT_WATCHDOG);
    ROM_IntPendClear(FAULT_SYSTICK);

    flash_end = 0xF8000;

    // erase flash
    for(index = 0; index < flash_end; index += 16384)
    {
        // Erase this block of the flash.
    	ROM_FlashErase((index));
    }

    ROM_SysCtlReset();

	//istruzione per saltare al boot
	(*((void (*)(void))(*(unsigned long *)0x2c)))();
}

void EthParamsProdInit(void)
{
	void *pcb = NULL;

	pcb = udp_new();
	udp_recv(pcb, EthParamsProdCall, NULL);
	udp_bind(pcb, IP_ADDR_ANY, 40000);

	return;
}
