
#include <stdio.h>
#include "eeprom.h"
#include "timer.h"
#include "device.h"
#include "definitions.h"
#include "uart1.h"

//#define APP_FLASH_ADDRESS (NVM_FLASH_START_ADDRESS + (NVM_FLASH_SIZE / 2)) 
#define APP_FLASH_ADDRESS (NVM_FLASH_START_ADDRESS + (NVM_FLASH_SIZE - NVM_FLASH_PAGESIZE)) 

extern uint8_t CACHE_ALIGN rowBuffer[NVM_FLASH_ROWSIZE];
//eeprom variables
extern uint8_t eePosition;
extern uint16_t eePump;
extern uint16_t eePurge;
extern uint16_t eeHome;
extern uint16_t eeOffset;

uint8_t eePosition_default=0;
uint16_t eePump_default=500;
uint16_t eePurge_default=100;
uint16_t eeHome_default=800;
uint16_t eeOffset_default=3900;


void PopulateBuffer(uint8_t* data) {
    //for (int i = 0; i < sizeof(rowBuffer); i++) {
    //    *(data + i) = (uint8_t)i; // Fill with some data
    //}
    
    *(data)      = (uint8_t) (eePosition);
    *(data + 1 ) = (uint8_t) (eePump & 0x00FF); //pump LSB
    *(data + 2 ) = (uint8_t) ( (eePump & 0xFF00) >> 4); //pump MSB
    *(data + 3 ) = (uint8_t) (eePurge & 0x00FF); //purge LSB
    *(data + 4 ) = (uint8_t) ( (eePurge & 0xFF00) >> 4); //purge MSB  
    *(data + 5 ) = (uint8_t) (eeHome & 0x00FF); //Home LSB
    *(data + 6 ) = (uint8_t) ( (eeHome & 0xFF00) >> 4); //Home MSB
    *(data + 7 ) = (uint8_t) (eeOffset & 0x00FF); //Offset LSB
    *(data + 8 ) = (uint8_t) ( (eeOffset & 0xFF00) >> 4); //Offset MSB
}

void write_eeprom(void)
{
    (void)__builtin_disable_interrupts();
    
    PopulateBuffer(rowBuffer); // Fill RAM buffer
    
    // Erase Page
    NVM_PageErase(APP_FLASH_ADDRESS);
    while(NVM_IsBusy()); // Wait for erase

    // Program Row
    NVM_RowWrite((uint32_t*)rowBuffer, APP_FLASH_ADDRESS);
    while(NVM_IsBusy()); // Wait for program

    (void)__builtin_enable_interrupts();
    return;
}

void read_eeprom(void)
{
    uint32_t ch1=0x00;
    uint32_t ch2=0x00;
    uint16_t test = 0;
    
    //start with position
    NVM_Read(&ch1, 1, APP_FLASH_ADDRESS);
    eePosition = ch1;
    //printf("Position = %d\n",eePosition);
    
    //pump revs
    NVM_Read(&ch1, 1, APP_FLASH_ADDRESS+1);
    NVM_Read(&ch2, 1, APP_FLASH_ADDRESS+2);
    eePump = ( (ch2 & 0x000000FF)<<4) | (ch1 & 0x000000FF) ;
    //printf("Pump revs = %d\n",eePump);   
 
    //purge revs
    NVM_Read(&ch1, 1, APP_FLASH_ADDRESS+3);
    NVM_Read(&ch2, 1, APP_FLASH_ADDRESS+4);
    eePurge = ( (ch2 & 0x000000FF)<<4) | (ch1 & 0x000000FF) ;
    //printf("Purge revs = %d\n",eePurge);  
    
    //Home
    NVM_Read(&ch1, 1, APP_FLASH_ADDRESS+5);
    NVM_Read(&ch2, 1, APP_FLASH_ADDRESS+6);
    eeHome = ( (ch2 & 0x000000FF)<<4) | (ch1 & 0x000000FF) ;
    //printf("Home offset = %d\n",eeHome);  
    
    //pump revs
    NVM_Read(&ch1, 1, APP_FLASH_ADDRESS+7);
    NVM_Read(&ch2, 1, APP_FLASH_ADDRESS+8);
    eeOffset = ( (ch2 & 0x000000FF)<<4) | (ch1 & 0x000000FF) ;
    //printf("Pump revs = %d\n",eeOffset);  
    
    return;
}

void test_eeprom(void)
{
    int i = 0;
    
    (void)__builtin_disable_interrupts();
    
    PopulateBuffer(rowBuffer); // Fill RAM buffer

    uint32_t read_data;
    NVM_Read(&read_data, 1, APP_FLASH_ADDRESS); 
    printf("read_data = 0x%x\n",read_data);
    
    // Erase Page
    NVM_PageErase(APP_FLASH_ADDRESS);
    while(NVM_IsBusy()); // Wait for erase

    // Program Row
    NVM_RowWrite((uint32_t*)rowBuffer, APP_FLASH_ADDRESS);
    while(NVM_IsBusy()); // Wait for program

    // Verification (optional)
    for (i=0;i<9;i++)
    {
        NVM_Read(&read_data, 1, APP_FLASH_ADDRESS+i); 
        printf("read_data[%d] = 0x%x\n",i,read_data);
    }

    (void)__builtin_enable_interrupts();
    return;
}

void change_eeprom (int ms)
{
    int val;
    int choice = 1;
    while (choice > 0 && choice < 7)
    {
        printf("1: Position(%d)\n",eePosition);
        printf("2: Pump revs(%d)\n",eePump);
        printf("3: Purge revs(%d)\n",eePurge);
        printf("4: Home offset(%d)\n",eeHome);
        printf("5: Bag offset(%d)\n",eeOffset);
        printf("6: Load default values\n");
        printf("0: to exit menu\n");
        printf("Enter choice: ");
        
        choice = UI_parse(ms);
        
        if (choice < 1 || choice > 6)return;
    
        printf("\nYou entered a %d\n",choice);
        
        switch (choice)
        {
            case 1:
                printf("Enter new value for position: ");
                val = UI_parse(ms);
                eePosition = (uint8_t)val;
                printf("\n");
                break;
            case 2:
                printf("Enter new value for Pump revs: ");
                val = UI_parse(ms);
                eePump = (uint16_t)val;
                printf("\n");
                break;
            case 3:
                printf("Enter new value for Purge revs: ");
                val = UI_parse(ms);
                eePurge = (uint16_t)val;
                printf("\n");
                break;
            case 4:
                printf("Enter new value for Home offset cnts: ");
                val = UI_parse(ms);
                eeHome = (uint16_t)val;
                printf("\n");
                break;
            case 5:
                printf("Enter new value for bag offset cnts: ");
                val = UI_parse(ms);
                eeOffset = (uint16_t)val;
                printf("\n");
                break;
            case 6:
                printf("Loading default values\n");
                eePosition = (uint8_t)eePosition_default;
                eePump = (uint16_t)eePump_default;
                eePurge = (uint16_t)eePurge_default;
                eeHome = (uint16_t)eeHome_default;
                eeOffset = (uint16_t)eeOffset_default;
                printf("\n");
                break;
            default :
                break;
           
        } //end switch
        
    }//end while
    
    write_eeprom();
    
    return;
}

int eeRead (int choice)
{
  int val = 0;

  switch (choice)
   {
      case 1:
          val = eePosition;
          break;
      case 2:
          val = eePump;
          break;
      case 3:
          val = eePurge;
          break;
      case 4:
          val = eeHome;
          break;
      case 5:
          val = eeOffset;
          break;
      default:
          break;
   } //end switch
  return (val);
}
