/*******************************************************************************
* Device      : AD18F06A
* Author      : XAD Application Team
* Version     : V0.0.1
* Date        : 202012001
* Description :
* Note		  :
********************************************************************************/
//UART Tx-> PB0;BPS ->9600
//使用FLASH_ADDR->0x0400页，擦除整页，并给全部地址写入数据0~FF,读该页地址中数据确认FLASH功能无误
/********************************INCLUDES*************************************/
#include <stdio.h>
#include "AD18F06A.h"

__CONFIG(1,_FINTOSC_DIV1_1L   & _LVREN_OFF_1L      & _LVR24V_1L                                                                                          );
__CONFIG(2,_FLASH_CP7_OFF_2L  & _FLASH_CP6_OFF_2L  & _FLASH_CP5_OFF_2L   & _FLASH_CP4_OFF_2L   & _FLASH_CP3_OFF_2L
         & _FLASH_CP2_OFF_2L  & _FLASH_CP1_OFF_2L  & _FLASH_CP0_OFF_2L   & _CRYLEN_OFF_2L      & _CRYHEN_OFF_2L
  	     & _IDIS_ON_2L        & _CKSUM_OFF_2L      & _CBP_OFF_2L         & _RESETE_OFF_2L      & _RSEL_LOW_2L     & _STV_ON_2L              	         );
__CONFIG(3,_DBG_OFF_3L        & _PSUT_8_3L         & _FCPU_2T_3L         & _WDTEN_OFF_3L       & _TWDT_011_3L                                            );
__CONFIG(4,_OSCM_HIRC_16M_4L  & _ENVDDL_ON_4L      & _EEDIS_OFF_4L       & _FLDIS_OFF_4L       & _FCMEN_OFF_4L    & _IESO_OFF_4L&  _DBGS_IOSEL_1_4L      );


#define ADDR_FLASH1      0x0300
#define ADDR_FLASH2      0x0400
#define ADDR_FLASH3      0x0500
#define ADDR_FLASH4      0x0600
#define ADDR_FLASH5      0x0700
#define ADDR_FLASH6      0x0800
#define ADDR_FLASH7      0x0900
#define ADDR_FLASH8      0x1000
#define ADDR_FLASH9      0x1100
#define ADDR_FLASH10     0x1200

const unsigned char buf2[256] @ADDR_FLASH2 ={
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,

0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};


void putch(unsigned char byte)
{
	while(!TXIF)continue;
	TXREG = byte;
}

unsigned char getch()
{
	while(!RCIF)continue;
	return RCREG;
}


void FLASH_Erase(unsigned int addr)
{
    GIE = 0;            //FLASH的操作过程中必须关闭中断
    IAPWAIT = 0x20;     //系统时钟16MHz，按照写入时间设定FLASH操作时间

	IAPRIG   = 0xad;
	IAPRIG   = 0x18;
	IAPRIG   = 0xf6;
	IAPADDRH = (unsigned char)(addr>>8);
	IAPADDRL = (unsigned char)(addr&0xff);
	IAPCTRL  = 0X02;
	IAPRIG   = 0X00;
    //GIE = 1;           //打开总中断使能位，若应用程序有中断使能需求，请去掉注释
}

void FLASH_Write(unsigned int addr,unsigned int pbuf)
{
    GIE = 0;            //FLASH的操作过程中必须关闭中断
    ////Demo一次写入256字节，固将IAPTRIG写在主函数中；用户直接写1Byte或不频繁使用FLASH,可将此处IAPWAIT和IAPTRIG打开使用
    // IAPWAIT  = 0x17;     //系统时钟16MHz，按照写入时间设定FLASH操作时间，DEMO中设定一次可依次写入256字节
    // IAPRIG   = 0xad;	   //in IAP mode
    // IAPRIG   = 0x18;
    // IAPRIG   = 0xf6;

	IAPADDRH = (unsigned char)(addr>>8);
	IAPADDRL = (unsigned char)(addr&0xff);
	IAPDATL  = (unsigned char)(pbuf>>8);
	IAPDATH  = (unsigned char)(pbuf&0xff);
	IAPCTRL  = 0X01;

    //Demo一次写入256字节，单字节写入需要在此退出IAP操作
    // IAPRIG  = 0X00;	 //out IAP mode
    //FLASH的操作过程中必须关闭中断，如有需求可在操作完成后使能中断
    //GIE = 1;          //打开总中断使能位，若应用程序有中断使能需求，请去掉注释
}
unsigned char buf1[256];
//UART Tx-> PB0;BPS ->9600
//使用FLASH_ADDR->0x0400页，擦除整页，并给全部地址写入数据0~FF,读该页地址中数据确认FLASH功能无误
void main(void)
{
    unsigned int i = 0,pr_temp = 0;

	//TX_PAx_RX_PAx@9600
	UART0CLKEN = 1;
    TX0_MAP    = MAP_PB0;
	TRISB0     = 0;

	UARTCON    = 0x00;
	SPBRG      = 0x1A;
	RCSTA      = 0x90;
	TXSTA      = 0x20;

    for(i = 0;i < 256;i++)
    {
        if(!(i%16))printf("\r\n");
        if(!(i%2))
        {
            pr_temp = (unsigned int)(buf2[i]  << 8);
            pr_temp = (unsigned int)(pr_temp|buf2[i+1]);
            printf("0x%04X",pr_temp);
        }

        if(i != 255)printf(", ");
    }
    //擦FLASH
    FLASH_Erase(ADDR_FLASH2);
    //读
    for(i = 0;i < 256;i++)
    {
        if(!(i%16))printf("\r\n");
        if(!(i%2))
        {
            pr_temp = (unsigned int)(buf1[i]  << 8);
            pr_temp = (unsigned int)(pr_temp|buf1[i+1]);
           printf("0x%04X",pr_temp);
        }

		if(i != 255)printf(", ");
    }
    //写FLASH
    IAPWAIT  = 0x17;    //系统时钟16MHz，按照写入时间设定FLASH操作时间
    IAPRIG   = 0xad;
    IAPRIG   = 0x18;
    IAPRIG   = 0xf6;        //in IAP mode
    for(i = 0;i < 256; i++)
    {
        if((i%2)== 0)
        {
            FLASH_Write(ADDR_FLASH2+i,0xFF00+i);
        }
    }
    IAPRIG  = 0X00;	                           //out IAP mode
    //读
    for(i = 0;i < 256;i++)
    {
        if(!(i%16))printf("\r\n");
        if((i%2) == 0)
        {
            pr_temp = (unsigned int)(buf2[i] << 8);
            pr_temp = (unsigned int)(pr_temp|buf2[i+1]);
            printf("0x%04X",pr_temp);
        }

        if(i != 255)printf(", ");
    }
	while(1);
}


void interrupt ISR_h (void)
{

}


void interrupt low_priority ISR_l (void)
{

}
