--- trunk/PIC/main.c 2007/01/29 09:45:25 2 +++ trunk/PIC/main.c 2007/01/30 14:56:43 17 @@ -1,15 +1,396 @@ /* H7 -projekt opgave */ - + +/////////////////////////////////////////////////////////////////////// +//Includes #include +#include + #include "delay.h" #include "i2c.h" #include "lcd.h" - +///////////////////////////////////////////////////////////////////// +//Defines #define TC74 0x9A /* I2C TC74 IC */ +#define SLIP_END 192 +#define SLIP_ESC 219 +#define SLIP_ESCAPED_END 220 +#define SLIP_ESCAPED_ESC 221 + +#define BUFFERLEN 16 + +////////////////////////////////////////////////////////////////// +// Enumerations + +enum SlipState{ + SlipNormal, + SlipEscaped, + SlipError, + SlipStopped +}; + +enum BaudRates{ + Baud1200, + Baud2400, + Baud4800, + Baud9600, + Baud19200 +}; + +enum Commands{ + CmdRead, + CmdWrite, + CmdAck, + CmdNAck +}; + +enum Targets { + TLed3, //0 + TLed4, + TLed5, + TSwitch2, + TSwitch3, + TPotmeter, + TTemp, + TBaud = 10 +}; + +////////////////////////////////////////////////////////////////// +//Globale data +// Alle globale variabler bruger "global_" som prefix + +unsigned char global_comm_buffer[BUFFERLEN]; +unsigned char global_comm_length; +unsigned char global_comm_index; + +bit global_comm_ready; +bit global_comm_error; + +unsigned char global_comm_slipstate; +unsigned char global_comm_currentrate; + +unsigned char global_lcd_buffer[20]; +unsigned char global_lcd_index; + + +bit global_led_0; +bit global_led_1; +bit global_led_2; + +bit global_reset_baudrate; + +char global_temp; +unsigned char global_potmeter_hi; +unsigned char global_potmeter_lo; + +/////////////////////////////////////////////////////////////////// +// Interrupt funktioner + +void recieve_interrupt(void) +{ + unsigned char data = RCREG; + RB2 = !RB2; + + switch (global_comm_slipstate) + { + case SlipNormal: + if (data == SLIP_END) + { + global_comm_ready = 1; + global_comm_slipstate = SlipStopped; + } + else if (data == SLIP_ESC) + { + global_comm_slipstate = SlipEscaped; + } + else + global_comm_buffer[ global_comm_length++ ] = data; + break; + + case SlipEscaped: + if (data == SLIP_ESCAPED_ESC) + { + global_comm_buffer[ global_comm_length++ ] = SLIP_ESC; + global_comm_slipstate = SlipNormal; + } + else if (data ==SLIP_ESCAPED_END) + { + global_comm_buffer[ global_comm_length++ ] = SLIP_END; + global_comm_slipstate = SlipNormal; + } + else + { + global_comm_slipstate = SlipError; + } + case SlipError: + if (data == SLIP_END) + { + global_comm_error = 1; + global_comm_slipstate = SlipStopped; + global_comm_ready = 1; + } + case SlipStopped: //vi var ikke klar til at modtage data + global_comm_error = 1; + } +} + +/* +void transmit_interrupt(void) +{ + RB2 = !RB2; +} +*/ + +void interrupt interrupt_handler(void) +{ + if (RCIF == 1) + { + recieve_interrupt(); + RCIF = 0; + } + /*if (TXIF == 1) + { + transmit_interrupt(); + TXIF = 0; + } + */ +} + +/////////////////////////////////////////////////////////////////// +// Slip funktioner + +void slip_reset(void) +{ + global_comm_error = 0; + global_comm_slipstate = SlipNormal; + global_comm_ready = 0; + global_comm_length = 0; + memset(global_comm_buffer, 0, BUFFERLEN); +} + +void slip_highlevel_protocol(void) +{ + unsigned char cmd,target,data; + + cmd = global_comm_buffer[0] & 0x0F; + target = ( global_comm_buffer[0] >> 4 ) & 0x0F; + data = global_comm_buffer[1]; + + if (cmd == CmdRead || cmd == CmdWrite) + { + //sæt standart længde - da længden kun varierer ved læsning af potmeter + if (cmd == CmdRead) + global_comm_length = 2; + else + global_comm_length = 1; + + switch(target) + { + case TLed3: + if (cmd == CmdRead) + global_comm_buffer[1] = global_led_0; + else + global_led_0 = data; + break; + case TLed4: + if(cmd == CmdRead) + global_comm_buffer[1] = global_led_1; + else + global_led_1 = data; + break; + case TLed5: + if (cmd == CmdRead) + global_comm_buffer[1] = global_led_2; + else + global_led_2 = data; + break; + case TSwitch2: + if (cmd == CmdRead) + global_comm_buffer[1] = RA4; + else + global_comm_error = 1; + break; + case TSwitch3: + if (cmd == CmdRead) + global_comm_buffer[1] = RB0; + else + global_comm_error = 1; + break; + case TPotmeter: + if (cmd == CmdRead) + { + global_comm_buffer[1] = global_potmeter_hi; + global_comm_buffer[2] = global_potmeter_lo; + global_comm_length = 3; + } + else + global_comm_error = 1; + break; + case TTemp: + if (cmd == CmdRead) + global_comm_buffer[1] = global_temp; + else + global_comm_error = 1; + break; + case TBaud: + if (cmd == CmdRead) + global_comm_error = 1; + else + { + //we can only handle 1200,2400,9600,19200 + if (data == 0 || data == 1 || data == 3 || data == 4) + global_reset_baudrate = 1; + else + global_comm_error = 1; + } + break; + default: + global_comm_error = 1; + + } + } + else //kommandoen var noget andet end read/write + { + global_comm_error = 1; + } + + + if (global_comm_error == 1) //we saw an error + { + global_comm_buffer[0] = CmdNAck | target<<4; + global_comm_length = 1; + } + else + { + global_comm_buffer[0] = CmdAck | target<<4; //skriv acknowledge feltet + } +} + +void slip_send_byte(char data) +{ + TXREG = data; + while (TRMT==0) ; + DelayUs(20); +} + +void slip_send_response(void) +{ + int i; + for (i=0; i< global_comm_length;i++) + { + if ( global_comm_buffer[i] == SLIP_ESC) + { + slip_send_byte(SLIP_ESC); + slip_send_byte(SLIP_ESCAPED_ESC); + } + else if (global_comm_buffer[i] == SLIP_END) + { + slip_send_byte(SLIP_ESC); + slip_send_byte(SLIP_ESCAPED_END); + } + else + { + slip_send_byte( global_comm_buffer[i]); + } + } + + slip_send_byte(SLIP_END); +} + +/////////////////////////////////////////////////////////////////// +// Gennerelle funktioner + +void interrupt_init(void) +{ + TXIE = 0; //Disable AUX TX interrupt - testes med TXIF; + RCIE = 1; //Enable AUX Recieve interrupt - testes med RCIF; + + IPEN = 0; // IPEN=Interrupt Priority ENable bit - her bruges ingen prioritet + + PEIE = 1; // PEIE = PEriphal Interrupt Enable + + TXIF = 0; //nulstil intterupt flag + RCIF = 0; + + GIE = 1; //Global interrupt enable bit +} + +void serial_init(void) +{ + SPEN = 0; //Make sure serial port is disabled + + // snupset fra Kim H Pedersens serialmain.c + // Set Port C bit 6 output (TxD) and bit 7 input (RxD) + TRISC6 = 0; + TRISC7 = 1; + + SPBRG = 25; // x = Fosc/(16 * Baud Rate) - 1 + // x = 4000000/(16 * 9600) - 1 + // x = 25.0417 ~ 25 + // Baud Rate = Fosc/(16 * (x+1)) + // Baud Rate = 4000000/(16 * (25+1)) + // Baud Rate = 9615 + TXSTA = 0x24; // TXSTA7 = 0 Don't care in asynchronous + // TXSTA6 = 0 8-bit transmission + // TXSTA5 = 1 Transmit enabled + // TXSTA4 = 0 Asynchronous mode + // TXSTA3 = 0 Unimplemented + // TXSTA2 = 1 High speed + // TXSTA1 = 0 TSR empty + // TXSTA0 = 0 9th bit */ + RCSTA = 0x90; // RCSTA7 = 0 Serial port disabled + // RCSTA6 = 0 8-bit reception + // RCSTA5 = 0 Don't care in asynchronous + // RCSTA4 = 1 Receiver enabled + // RCSTA3 = 0 Don't care (8-bit operation) + // RCSTA2 = 0 No framing error + // RCSTA1 = 0 Overrun error bit + // RCSTA0 = 0 9th bit */ + + //config completed + SPEN = 1; //Enable Serial port +} + +/* basic I/O ports */ +void io_init(void) +{ + TRISB3 = 0; //LED ports = output + TRISB2 = 0; + TRISB1 = 0; + + TRISB0 = 1; //Switch porte = input + TRISA0 = 1; +} + +void ad_init(void) +{ + // AD Conversion clock + ADCS0 = 0; + ADCS1 = 0; + ADCS2 = 0; + + //Select AN0/RA0 for AD source + CHS0=0; + CHS1=0; + CHS2=0; + + //Only AN0 is selected for AD and with Vdd/Vss as limits + PCFG0=0; + PCFG1=1; + PCFG2=1; + PCFG3=1; + + //Result is right justified + ADFM=1; + + //Fire up for A/D converter module + ADON=1; +} + void i2c_init(void) { +// I2C_MODULE hører hjemme i i2c.h #ifdef I2C_MODULE SSPMode(MASTER_MODE); SSPEN = 1; @@ -22,24 +403,77 @@ #endif } + + char ReadTemp(void) { char temp; - i2c_WriteTo(TC74); + i2c_WriteTo(TC74); //write to, will automatically send a start condition i2c_PutByte(0x00); //tell TC74 we want to read i2c_ReadFrom(TC74); temp = i2c_GetByte(I2C_LAST); i2c_Stop(); //assert a stop condition on SDA & SCL return temp; -} +} + + +/////////////////////////////////////////////////////////////////// +//Main + void main(void) { + char lcdbuf[20]; + int i; + + lcd_init(0); //init in 4-bit mode i2c_init(); + serial_init(); //9600 8N1 + ad_init(); + io_init(); + interrupt_init(); + + + slip_reset(); //take SLIP FSM into normal state + global_comm_currentrate = Baud9600; //default baudrate = 9600 + global_reset_baudrate = 0; + +// initialisation completed and we are ready to recieve commands - enable serial reception + CREN = 1; while (1) { + if (global_comm_ready == 1) + { + slip_highlevel_protocol(); //parse the slip frame recieved & generate response + slip_send_response(); + slip_reset(); + } + + if ( global_reset_baudrate == 1) + { + } + + RB1 = global_led_0; + RB2 = global_led_1; + RB3 = global_led_2; + + global_temp = ReadTemp(); + + //potmeter + if (GODONE ==0 )//hvis A/D-conv er færdig + { + + global_potmeter_hi = ADRESH;//gem AD resultat + global_potmeter_lo = ADRESL; + GODONE = 1; //start ny konverering + } + + + //just for fun - blink RB3 +// RB3 = !RB3; +// DelayMs(250); } }