--- trunk/PIC/main.c 2007/01/29 15:29:28 10 +++ trunk/PIC/main.c 2007/01/30 22:16:53 20 @@ -3,6 +3,8 @@ /////////////////////////////////////////////////////////////////////// //Includes #include +#include + #include "delay.h" #include "i2c.h" #include "lcd.h" @@ -11,8 +13,15 @@ //Defines #define TC74 0x9A /* I2C TC74 IC */ -////////////// -// Enums +#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, @@ -21,29 +30,116 @@ 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[10]; + +unsigned char global_comm_buffer[BUFFERLEN]; unsigned char global_comm_length; -unsigned char global_comm_index; + bit global_comm_ready; -bit global_comm_recieving; +bit global_comm_error; + +unsigned char global_comm_slipstate; +unsigned char global_comm_currentrate; -unsigned char global_comm_state; +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) { @@ -52,19 +148,161 @@ recieve_interrupt(); RCIF = 0; } - if (TXIF == 1) + /*if (TXIF == 1) { transmit_interrupt(); TXIF = 0; } + */ } /////////////////////////////////////////////////////////////////// -// Alm funktioner +// 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 = 1; //Enable AUX TX interrupt - testes med TXIF; + 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 @@ -108,15 +346,50 @@ // 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; @@ -152,20 +425,45 @@ lcd_init(0); //init in 4-bit mode i2c_init(); serial_init(); //9600 8N1 - + ad_init(); + io_init(); interrupt_init(); - global_comm_length = 0; - global_comm_ready = 0; - - global_comm_state = SlipNormal; + 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 + } } }