/*  Filename     zgr64sms.c
    Description  TEST SEND SMS
    Hardware     SLAB51 + GR64
    Clock        11.0592 Mhz (89V51RD2BN x1) 
    Compiler     Keil PK51 v7.10
    Engineer     PATIKHOM KONKENG
    Company      Sila Research Co.,Ltd. 
*/

#include <reg52.h>
#include <stdio.h>

#define  MAXBUF 16          	  	// maximun for combuf (not include ':' & 0xd)

/********** I/O PORT **********/

sbit    KINT0   = P3^3;            	// INT0
sbit    KINT1   = P3^2;            	// INT1
sbit    P10     = P1^0;             // LED for test

/********** INT-RAM WORKING AREA **********/

unsigned char      COMBUF[MAXBUF+1]; 	// communication buffer
unsigned char      COMINX;              // COMBUF index

         bit       TXOK;                // tx flag
         bit       RXOK;                // rx command ready flag
         bit       SCOMF;               // start comand flag
		 bit       NEWSMSF;             // new sms flag
		 bit       SENDOK;              // send sms complete

/********** BASIC FUNCTION **********/

void dmsec (unsigned int count) {       // mSec Delay
    unsigned int i;
    while (count) {
        i = 115; while (i>0) i--;
        count--;
    }
}

char putchar (unsigned char x) {            // change putchar for printf  
    while (!TXOK);
    TXOK = 0;
    return (SBUF = x);
}

// ************  GR64 AT Command ******************

void send_cmgf(void){							// set sms text mode
	printf("AT+CMGF=1");
	printf("\r");
}

void send_csmp(void){							// set parameter
	printf("AT+CSMP=17,167,0,0");
	printf("\r");
}

void send_cmgs(void){							// set telephone number
	printf("AT+CMGS=\"0817279123\"");			// tel num for test
	printf("\r");
}

void send_text(void){							// send text
	printf("TEST SEND SMS FROM GR64 MODULE");
	putchar(0x1A);								// keyboard = Ctrl + z
}

void send_cmgd(void){							// delete
	printf("AT+CMGD=1");						// delete message index = 1
	printf("\r");
}

void send_cmgl(void){							// read message 
	printf("AT+CMGL=\"REC UNREAD\"");
	printf("\r");
}

void sendsms(void){
	send_cmgf();
	dmsec(1000);
	send_csmp();
	dmsec(1000);
	send_cmgs();
	dmsec(1000);
	send_text();
	SENDOK = 1;
}

void readsms(void){
	send_cmgf();
	dmsec(1000);
	send_cmgl();
}

void doevents(void){
	if (COMBUF[1] == '0') P10 = 1;					// LED OFF
	if (COMBUF[1] == '1') P10 = 0;					// LED ON

	if (NEWSMSF){
		send_cmgd();
		NEWSMSF = 0;
	}
}

/********** INTERRUPT FUNCTION **********/

void inputcom (unsigned char a) {           // input to COMBUF
    unsigned char i;                   

    if (a==':') {                           		// start 
        COMINX = 0;  
        SCOMF = 1;
        for (i=0;i<=MAXBUF;i++) COMBUF[i] = 0;
    }
	else {
        if (SCOMF) {
            if (a==0x0d || a==0xff) {     // end
                COMBUF[COMINX] = a;
                SCOMF = 0;
                RXOK = 1;
            }    
            else if (a<0x20) return;        // nothing
            else if (COMINX<MAXBUF) {
                COMBUF[COMINX] = a;         // command
                COMINX++;
            }
        }
    }
}

void serial (void) interrupt 4 {            // serial interrupt 
    unsigned char a;                        // receive binary command
    if (TI) {                               // TXD
        TI = 0;
        TXOK = 1;
        return;
    }

    a = SBUF;                               // RXD
    RI = 0;
    inputcom (a);
}

/********** START FUNCTION **********/

void start (void) {				  // start

    SCON = 0x52;             	  // set RS232 parameter
    TMOD = 0x20;                  // t1=serial,t0=timer(16 bit)
    TH1 = 0xfd;					  // set baud-rate 9600                  
	TR1 = 1;

	TI = 1;
	TXOK = 1;
	SENDOK = 1;
    ES = 1;                       // serial interrupt enable
    EA = 1;                       // enable all interrupt
	NEWSMSF = 0;
    dmsec (200);
}

/********** MAIN FUNCTION **********/


void main (void) {
    start();

    while(1) {
	
      	if (KINT0 == 0){
			if (SENDOK){
				SENDOK = 0;
				sendsms();
			}
		}
		
		readsms();
		dmsec(1000);

		if (RXOK){
			if (COMBUF[0] == 'P'){
				NEWSMSF = 1;
				doevents();			// check COMBUF0
			}
		}
	}
}