/*  Filename     MKIT1.C
    Description  MKIT-1 Temperature Board
    Hardware     MKIT-1
    Clock        11.0592 Mhz 
    Compiler     Keil PK51 v7.10
    Engineer     Kriangsak B.
    Company      Sila Research Co.,Ltd. 
*/

#include <reg51.h>
#include <absacc.h>
#include <assert.h>
#include <ctype.h>
#include <intrins.h>
#include <math.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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

sbit     DPCLK     = P3^2;
sbit     DPSTR     = P3^3;
sbit     DPDAT     = P3^4;
sbit     TMDAT     = P3^5;
sbit     D485      = P3^7;

sbit     DIPS7     = P1^0;
sbit     DIPS6     = P1^1;
sbit     DIPS5     = P1^2;
sbit     DIPS4     = P1^3;
sbit     DIPS3     = P1^4;
sbit     DIPS2     = P1^5;
sbit     DIPS1     = P1^6;
sbit     RELAY     = P1^7;

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

unsigned char      DISBUF[2];               // display buffer
unsigned int       HTEMP;                   // high temp
unsigned int       LTEMP;                   // low temp

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

void dmsec (unsigned int count) {           // mSec Delay
    unsigned int i;                         // for Keil CA51 (Speed x 1)
    while (count) {
        i = 115; while (i>0) i--;
        count--;
    }
}

unsigned char code SEGTAB[16] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
                                 0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
                                 // standard segment code

unsigned char htosx (unsigned char hex) {   // change hex to segment
    return (SEGTAB[hex]);
}

void ctos (unsigned char dat) {             // change int to segment
    DISBUF[1] = htosx (dat % 10); 
	dat = dat / 10;
    DISBUF[0] = htosx (dat % 10); 
}

void outdpf (void) {                       // out to 7-segment display (3B Port)
    unsigned char a,i,j;          	  
    for (i=0;i<=1;i++) {                   // 2 digits  
        a = DISBUF[i];
    	for (j=0;j<=7;j++) {
            DPDAT = a & 0x80;
            a = a << 1;
            DPCLK = 1;
            _nop_ ();
            _nop_ ();
            DPCLK = 0;
            _nop_ ();
            _nop_ ();
    	}       
    }
    DPSTR = 1;
    _nop_ ();
    _nop_ ();
    DPSTR = 0;
    _nop_ ();
    _nop_ ();
}

void tmreset (void) {                  // Reset TX (Speed x1)
    unsigned int i;
    TMDAT = 0;
    i = 103; while (i>0) i--;          // Approx 900 uS 
    TMDAT = 1;
    i = 5; while (i>0) i--;
}

bit tmpre (void) {                     // Wait for Presence RX (Speed x1)
    unsigned char i;                   // return 0=OK 1=ERROR 
    unsigned int a;
    a = 0;
    while (TMDAT)
        if (a++>2000) return (1);
    while (~TMDAT);
    i = 5; while (i>0) i--;
    return (0);
}

bit tmrbit (void) {                    // read one bit (Speed x1)
    unsigned int i;
    bit dat;
    TMDAT = 0; i++;
    TMDAT = 1; i++; i++;
    dat = TMDAT;
    i = 9; while (i>0) i--;            // Approx 65 uS 
    return (dat);
}

unsigned char tmrbyte (void) {         // read one byte (Speed x1 x2)
    unsigned char i,j,dat;
    dat = 0;
    for (i=1;i<=8;i++) {
        j = tmrbit();
        dat = (j << 7) | (dat >> 1);
    }
    return (dat);
}

void tmwbyte (unsigned char dat) {     // write one byte (Speed x1)
    unsigned int i;
    unsigned char j;
    bit testb;
    for (j=1;j<=8;j++) {
        testb = dat & 0x01;
        dat = dat >> 1;
        if (testb) {
            TMDAT = 0;                 // Write 1 
            i++; i++;                  // Approx 4 uS 
            TMDAT = 1;
            i = 9; while (i>0) i--;    // Approx 65 uS 
        }
        else {
            TMDAT = 0;                 // Write 0 
            i = 9; while (i>0) i--;    // Approx 65 uS 
            TMDAT = 1;
            i++; i++;                  // Approx 4 uS 
        }
    }
}

void tmstart (void) {             // ds18s20 start convert 
    tmreset ();
    if (tmpre ()==1) return;
    else {
        dmsec (1);
        tmwbyte (0xcc);           // skip rom 
        tmwbyte (0x44);           // convert 
    }
}

int tmrtemp (void) {              // read temp 
    int x;
    unsigned char a,b;
    tmreset ();
    if (tmpre ()==1) return (0);
    else {
        dmsec (1);
        tmwbyte (0xcc);           // skip rom 
        tmwbyte (0xbe);           // convert 
        a = tmrbyte ();           // LSB 
        b = tmrbyte ();           // MSB 
        if (b==0xff) return (0);  // don't care negative temp 
        x = a & 0x1;              // 0=x.0 1=x.5 
        a = a >> 1;
        if (a>99) {               // max 99.5 c
            a = 99;
			x = 1;
        }
        x = (x << 8) | a;
    }
    return (x);                   // L-byte=0,1 R-byte=temp
}

/********** MAIN **********/

void start (void) {               // speed x 1
    D485 = 0;                     // RS485 send off first
    SCON = 0x52;             	  // set RS232 parameter
    TMOD = 0x20;
    TH1 = 0xfd;                   // 9600 
    TR1 = 1;

	DPCLK = 0;                    // reset i/o pin
	DPSTR = 0;
    outdpf ();                    // clear display first
	dmsec (500);
}

void checkdip (void) {            // check dip (set high,low temp) 
    unsigned char a;
	a = ~DIPS1;
	a = (a << 1) | ~DIPS2;
	a = (a << 1) | ~DIPS3;
	a = (a << 1) | ~DIPS4;
	a = (a << 1) | ~DIPS5;
	a = a + 20;                   // set high temp 20 to 51 c 
	HTEMP = a;
    a = ~DIPS6;
	a = (a << 1) | ~DIPS7;
    switch (a) {
        case 0: LTEMP = HTEMP - 1; break;
        case 1: LTEMP = HTEMP - 2; break;
        case 2: LTEMP = HTEMP - 3; break;
        case 3: LTEMP = HTEMP - 4; break;
	}
    HTEMP = HTEMP * 10;
    LTEMP = LTEMP * 10;
}

void main (void) {
    unsigned int x;
    unsigned char t;
	bit f;

    start ();                                    // power-up start
    while (1) {
        tmstart ();                              // ds18s20 start
		dmsec (1000);
		x = tmrtemp ();                          // ds18s20 read temp 
		t = x;
        ctos (t);                                // change to segment code
        f = x & 0x0100;                          // set flag 0.5 c 
		if (f) DISBUF[1] = DISBUF[1] | 0x80;     // set dot for 0.5 c
        outdpf ();                               // out to HC595 x 2

        D485 = 1;                                // send temp to rs485
		printf ("%02bd",t);
		if (f) printf (".5\r"); else printf (".0\r");
		while (~TI);
		D485 = 0;

        x = t * 10;                              // control relay
        if (f) x += 5; 
	    checkdip ();
        if (x>=HTEMP) RELAY = 0;                 // relay on
  		else if (x<=LTEMP) RELAY = 1;            // relay off
	}
}


