/*******************************************************************************
* NXP Semiconductors
* ALL RIGHTS RESERVED.
********************************************************************************
Services performed by NXP in this matter are performed AS IS and without 
any warranty. CUSTOMER retains the final decision relative to the total design 
and functionality of the end product. NXP neither guarantees nor will be 
held liable by CUSTOMER for the success of this project.
NXP DISCLAIMS ALL WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY INCLUDING, 
BUT NOT LIMITED TO, IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR 
A PARTICULAR PURPOSE ON ANY HARDWARE, SOFTWARE OR ADVISE SUPPLIED TO THE PROJECT
BY NXP, AND OR NAY PRODUCT RESULTING FROM NXP SERVICES. IN NO EVENT
SHALL NXP BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF
THIS AGREEMENT.

CUSTOMER agrees to hold NXP harmless against any and all claims demands or
actions by anyone on account of any damage, or injury, whether commercial, 
contractual, or tortuous, rising directly or indirectly as a result of an advise
or assistance supplied CUSTOMER in connection with product, services or goods 
supplied under this Agreement.
********************************************************************************
* File      main.c
* Owner     NXA19261
* Version   1.0
* Date      Aug-17-2017
* Classification   General Business Information
* Brief     Application example for Simply Serial Bootloader for S12Z (SSBZ)   
********************************************************************************
* Detailed Description:
* Application example for Simply Serial Bootloader for S12Z
* 
* The application initialise API interrupt and toggle with LEDs at dedicated counter value.
* The vector table is created in flash memory and this memory range must be excluded 
* from linker use in prm linker file. See prm linker file.
* 
* When user application is merged  
* 
********************************************************************************
Revision History:
Version  Date         Author    Description of Changes
1.0      Aug-17-2017  NXA19261  Initial version
*******************************************************************************/
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */

//==============================================================================
// Function prototypes
//==============================================================================
void API_Init(void);
interrupt void API_ISR(void);
interrupt void Machine_Exception_ISR(void);
interrupt void Unimplemented_ISR(void);

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

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//example of EEPROM data. 
//Since these data are not directly referenced, I placed "my_EEPROM" into NAMES section in prm linker file for avoiding optimisation-out 
unsigned const char my_EEPROM[] @0x100000 = {0x11, 0x22, 0x33, 0x44};
//EEPROM value that fits to Bootloader request key value - Bootloader code will be executed after next MCU reset
//unsigned const char my_EEPROM[] @0x100000 = {0x42, 0x4F, 0x4F, 0x54};
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

//example of global variable
unsigned char counter = 0;

//Interrupt vector table definitions
//Note: the vector table should start with 0x10 offset from sector start because this are is by default used by Flash Configuration Field
#define INT_VECTOR_TABLE_ADDR 0xFE0010U
#define INT_VECTOR_TABLE_SIZE 123  //First 16B from sector reserved for Flash Configuration Field and last 4B is reset vector which cannot be relocated
                                   //(512B - 16B - 4B)/4B = 123 vectors
//Please see prm linker file where we removed area with vector table from linker usage.

/* ISR prototype */
typedef void (* tIsrFunc)(void);
/* Pack 3 byte pointers as 4 byte Interrupt Vector Table entries */
typedef struct
{
  byte padding;
  tIsrFunc address;
} InterruptTableEntry;

#define _VECTOR(v) {0xFFU, &v}

//Please replace aprropriate Unimplemented_ISR by implemented interrupt routine
//see table Interrupt Vector Locations in RM for more details
const InterruptTableEntry _InterruptVectorTable[INT_VECTOR_TABLE_SIZE] @INT_VECTOR_TABLE_ADDR = { /* Interrupt vector table */
		_VECTOR(Unimplemented_ISR),//0x10
		_VECTOR(Unimplemented_ISR),//0x14
		_VECTOR(Unimplemented_ISR),//0x18
		_VECTOR(Unimplemented_ISR),//0x1C		
		_VECTOR(Unimplemented_ISR),//0x20
		_VECTOR(Unimplemented_ISR),//0x24
		_VECTOR(Unimplemented_ISR),//0x28
		_VECTOR(Unimplemented_ISR),//0x2C
		_VECTOR(Unimplemented_ISR),//0x30
		_VECTOR(Unimplemented_ISR),//0x34
		_VECTOR(Unimplemented_ISR),//0x38
		_VECTOR(Unimplemented_ISR),//0x3C
		_VECTOR(Unimplemented_ISR),//0x40
		_VECTOR(Unimplemented_ISR),//0x44
		_VECTOR(Unimplemented_ISR),//0x48
		_VECTOR(Unimplemented_ISR),//0x4C		
		_VECTOR(Unimplemented_ISR),//0x50
		_VECTOR(Unimplemented_ISR),//0x54
		_VECTOR(Unimplemented_ISR),//0x58
		_VECTOR(Unimplemented_ISR),//0x5C
		_VECTOR(Unimplemented_ISR),//0x60
		_VECTOR(Unimplemented_ISR),//0x64
		_VECTOR(Unimplemented_ISR),//0x68
		_VECTOR(Unimplemented_ISR),//0x6C
		_VECTOR(Unimplemented_ISR),//0x70
		_VECTOR(Unimplemented_ISR),//0x74
		_VECTOR(Unimplemented_ISR),//0x78
		_VECTOR(Unimplemented_ISR),//0x7C		
		_VECTOR(Unimplemented_ISR),//0x80
		_VECTOR(Unimplemented_ISR),//0x84
		_VECTOR(Unimplemented_ISR),//0x88
		_VECTOR(Unimplemented_ISR),//0x8C
		_VECTOR(Unimplemented_ISR),//0x90
		_VECTOR(Unimplemented_ISR),//0x94
		_VECTOR(Unimplemented_ISR),//0x98
		_VECTOR(Unimplemented_ISR),//0x9C
		_VECTOR(Unimplemented_ISR),//0xA0
		_VECTOR(Unimplemented_ISR),//0xA4
		_VECTOR(Unimplemented_ISR),//0xA8
		_VECTOR(Unimplemented_ISR),//0xAC		
		_VECTOR(Unimplemented_ISR),//0xB0
		_VECTOR(Unimplemented_ISR),//0xB4
		_VECTOR(Unimplemented_ISR),//0xB8
		_VECTOR(Unimplemented_ISR),//0xBC
		_VECTOR(Unimplemented_ISR),//0xC0
		_VECTOR(Unimplemented_ISR),//0xC4
		_VECTOR(Unimplemented_ISR),//0xC8
		_VECTOR(Unimplemented_ISR),//0xCC
		_VECTOR(Unimplemented_ISR),//0xD0
		_VECTOR(Unimplemented_ISR),//0xD4
		_VECTOR(Unimplemented_ISR),//0xD8
		_VECTOR(Unimplemented_ISR),//0xDC		
		_VECTOR(Unimplemented_ISR),//0xE0
		_VECTOR(Unimplemented_ISR),//0xE4
		_VECTOR(Unimplemented_ISR),//0xE8
		_VECTOR(Unimplemented_ISR),//0xEC
		_VECTOR(Unimplemented_ISR),//0xF0
		_VECTOR(Unimplemented_ISR),//0xF4
		_VECTOR(Unimplemented_ISR),//0xF8
		_VECTOR(Unimplemented_ISR),//0xFC
		//_VECTOR(Unimplemented_ISR),//0x100
		_VECTOR(API_ISR),//0x100
		_VECTOR(Unimplemented_ISR),//0x104
		_VECTOR(Unimplemented_ISR),//0x108
		_VECTOR(Unimplemented_ISR),//0x10C
		_VECTOR(Unimplemented_ISR),//0x110
		_VECTOR(Unimplemented_ISR),//0x114
		_VECTOR(Unimplemented_ISR),//0x118
		_VECTOR(Unimplemented_ISR),//0x11C		
		_VECTOR(Unimplemented_ISR),//0x120
		_VECTOR(Unimplemented_ISR),//0x124
		_VECTOR(Unimplemented_ISR),//0x128
		_VECTOR(Unimplemented_ISR),//0x12C
		_VECTOR(Unimplemented_ISR),//0x130
		_VECTOR(Unimplemented_ISR),//0x134
		_VECTOR(Unimplemented_ISR),//0x138
		_VECTOR(Unimplemented_ISR),//0x13C
		_VECTOR(Unimplemented_ISR),//0x140
		_VECTOR(Unimplemented_ISR),//0x144
		_VECTOR(Unimplemented_ISR),//0x148
		_VECTOR(Unimplemented_ISR),//0x14C		
		_VECTOR(Unimplemented_ISR),//0x150
		_VECTOR(Unimplemented_ISR),//0x154
		_VECTOR(Unimplemented_ISR),//0x158
		_VECTOR(Unimplemented_ISR),//0x15C
		_VECTOR(Unimplemented_ISR),//0x160
		_VECTOR(Unimplemented_ISR),//0x164
		_VECTOR(Unimplemented_ISR),//0x168
		_VECTOR(Unimplemented_ISR),//0x16C
		_VECTOR(Unimplemented_ISR),//0x170
		_VECTOR(Unimplemented_ISR),//0x174
		_VECTOR(Unimplemented_ISR),//0x178
		_VECTOR(Unimplemented_ISR),//0x17C		
		_VECTOR(Unimplemented_ISR),//0x180
		_VECTOR(Unimplemented_ISR),//0x184
		_VECTOR(Unimplemented_ISR),//0x188
		_VECTOR(Unimplemented_ISR),//0x18C
		_VECTOR(Unimplemented_ISR),//0x190
		_VECTOR(Unimplemented_ISR),//0x194
		_VECTOR(Unimplemented_ISR),//0x198
		_VECTOR(Unimplemented_ISR),//0x19C
		_VECTOR(Unimplemented_ISR),//0x1A0
		_VECTOR(Unimplemented_ISR),//0x1A4
		_VECTOR(Unimplemented_ISR),//0x1A8
		_VECTOR(Unimplemented_ISR),//0x1AC		
		_VECTOR(Unimplemented_ISR),//0x1B0
		_VECTOR(Unimplemented_ISR),//0x1B4
		_VECTOR(Unimplemented_ISR),//0x1B8
		_VECTOR(Unimplemented_ISR),//0x1BC
		_VECTOR(Unimplemented_ISR),//0x1C0
		_VECTOR(Unimplemented_ISR),//0x1C4
		_VECTOR(Unimplemented_ISR),//0x1C8
		_VECTOR(Unimplemented_ISR),//0x1CC
		_VECTOR(Unimplemented_ISR),//0x1D0
		_VECTOR(Unimplemented_ISR),//0x1D4
		_VECTOR(Unimplemented_ISR),//0x1D8
		_VECTOR(Unimplemented_ISR),//0x1DC		
		_VECTOR(Unimplemented_ISR),//0x1E0
		_VECTOR(Unimplemented_ISR),//0x1E4
		//_VECTOR(Unimplemented_ISR),//0x1E8
		_VECTOR(Machine_Exception_ISR),//0x1E8
		_VECTOR(Unimplemented_ISR),//0x1EC
		_VECTOR(Unimplemented_ISR),//0x1F0
		_VECTOR(Unimplemented_ISR),//0x1F4
		_VECTOR(Unimplemented_ISR),//0x1F8
};



//==============================================================================
// Functions
//==============================================================================
/*******************************************************************************
 Function Name : API_Init
 Engineer      : NXA19261
 Date          : Aug-17-2017
 Parameters    : NONE
 Modifies      : NONE
 Returns       : NONE
 Notes         : API initialisation.
 Issues        : NONE
 *******************************************************************************/
void API_Init(void)
{  
  CPMUAPIR = 49;         //10ms interval  
//  CPMUACLKTR = 0x00;     //initial trim value
  CPMUAPICTL = 0x09;     //API osc is source of clock, interrupt disable, 
                         //clear flag if set
  CPMUAPICTL_APIFE = 1;  //API enable
  CPMUAPICTL_APIE = 1;   //interrupt enable 
} 

/*******************************************************************************
 Function Name : Machine_Exception_ISR
 Engineer      : NXA19261
 Date          : Aug-17-2017
 Parameters    : NONE
 Modifies      : NONE
 Returns       : NONE
 Notes         : Machine Exception is not an interrupt. There is no stack-frame 
                 created for a Machine Exception so simply calling "RTI" (which 
                 expects a stack-frame) at the end of the Machine Exception routine 
                 will result in a crash.
                 The difference is explained in S12Z CPU RM:
                 http://www.nxp.com/files/microcontrollers/doc/ref_manual/S12ZCPU_RM_V1.pdf
                 See Chapter 7 - Exceptions.
                 Therefore, the correct recovery action should be (indicate error and) MCU reset.
 Issues        : Function is programmed here so it must be removed from
                 the part "A Set of unimplemented interrupts"
 *******************************************************************************/
interrupt void Machine_Exception_ISR(void)
{  
  CPMUCOP = 0x01;   //Initialize COP watchdog
  CPMUARMCOP = 0x00; //write any value except 0x55 or 0xAA cause MCU reset
}


/*******************************************************************************
 Function Name : API_ISR
 Engineer      : NXA19261
 Date          : Aug-17-2017
 Parameters    : NONE
 Modifies      : NONE
 Returns       : NONE
 Notes         : API interrupt routine.
 Issues        : NONE
 *******************************************************************************/
interrupt void API_ISR(void)
{  
  CPMUAPICTL_APIF = 1;   //clear flag
  counter++;
}

/*******************************************************************************
 Function Name : Unimplemented_ISR
 Engineer      : NXA19261
 Date          : Aug-17-2017
 Parameters    : NONE
 Modifies      : NONE
 Returns       : NONE
 Notes         : Catch unexpected interrupts.
 Issues        : NONE
 *******************************************************************************/ 
interrupt void Unimplemented_ISR(void)
{  
  asm NOP;   //place breakpoint here
}


/*******************************************************************************
 Function Name : main
 Engineer      : NXA19261
 Date          : Aug-17-2017
 Parameters    : NONE
 Modifies      : NONE
 Returns       : NONE
 Notes         : Main loop.
 Issues        : NONE
 *******************************************************************************/ 
void main(void) {
  unsigned int i;
  
  IVBR=((INT_VECTOR_TABLE_ADDR >> 8) & 0xFFFE); //15 most significant bits from vector table address 
  
  API_Init();
  
  EnableInterrupts;
  
  //LED pins initialisation
    //DEVKIT-ZVL128(DEVKIT-S12ZVL)
  DDRP = 0x2A; //PP1, PP3, PP5 as LED output with external pull-up;
  PTP = 0xD5;
    //S12ZVMC256EVB
//  DDRT = 0x01; //PT0 as LED output with external pull-down;
//  DDRS = 0x02; //PS0 as LED output with external pull-down;
    //S12ZVM32EVB
//  DDRS = 0x30; //PS4 and PS5 as LED output with external pull-down;
  
  for(;;) 
  {
	//LED pin toggling
      //DEVKIT-ZVL128(DEVKIT-S12ZVL)
    if (counter == 63) PTP = 0xFD;   //PP1 low
    if (counter == 127) PTP = 0xF7;  //PP3 low
    if (counter == 191) PTP = 0xDF;  //PP5 low
    if (counter == 0) PTP = 0xD5;    //all PP1, PP3 and PP5 low
	  //S12ZVMC256EVB
//    if (counter == 63) PTT = 0x01;   //PT0 high
//    if (counter == 127) PTS = 0x02;   //PS1 High
//    if (counter == 191) PTT = 0x00;   //PT0 low
//    if (counter == 0) PTS = 0x00;   //PS1 low
	  //S12ZVM32EVB
//    if (counter == 63) PTS = 0x10;   //PS40 high
//    if (counter == 127) PTS = 0x30;   //PS5 High
//    if (counter == 191) PTS = 0x20;   //PS4 low
//    if (counter == 0) PTS = 0x00;   //PS5 low

	  
  } /* loop forever */
  /* please make sure that you never leave main */

}
