/**** IR Mrakomer 4 ****/#define VERSION "4.0"#define ID "$Id: irmrak4.c 1298 2009-01-16 23:40:59Z kakl $"#include "irmrak4.h"#bit CREN = 0x18.4 // USART registers#bit SPEN = 0x18.7#bit OERR = 0x18.1#bit FERR = 0x18.2#include <string.h>//!!! #include "bloader.c" // Boot Loader driver#CASE // Case sensitive compiler#define MAXHEAT 20 // Number of cycles for heating#define MAXOPEN 20 // Number of cycles for dome open#define MEASURE_DELAY 6000 // Delay to a next measurement#define RESPONSE_DELAY 100 // Reaction time after receiving a command#define SAFETY_COUNT 90 // Time of one emergency cycle#define SEND_DELAY 50 // Time between two characters on RS232#define DOME PIN_B4 // Dome controll port#define HEATING PIN_B3 // Heating for defrostingchar VER[4]=VERSION; // Buffer for concatenate of a version stringint8 heat; // Status variablesint8 open;inline void toggle_dome(void) // Wire exercise{if (open>0){output_toggle(DOME);} // Toggle = Open Domeelse{output_high(DOME);} // Do not toggle = Close Dome}void delay(int16 cycles) // Wire exercise with delay{int16 i;for(i=0; i<cycles; i++) {toggle_dome(); delay_us(100);}}void welcome(void) // Welcome message{char REV[50]=ID; // Buffer for concatenate of a version stringif (REV[strlen(REV)-1]=='$') REV[strlen(REV)-1]=0;printf("\n\r# Mrakomer %s (C) 2007 KAKL\n\r",VER); // Welcome messageprintf("#%s\n\r",&REV[4]);printf("# <sequence> <ambient[1/100 C]> <sky[1/100 C]> ");printf("<heating[s]> <dome[s]> <check>\n\r\n\r");}#include "smb.c" // System Management Bus driver// Read sensor's RAM// Returns temperature in °Kint16 ReadTemp(int8 addr, int8 select){unsigned char arr[6]; // Buffer for the sent bytesint8 crc; // Readed CRCint16 temp; // Readed temperatureaddr<<=1;SMB_STOP_bit(); //If slave send NACK stop comunicationSMB_START_bit(); //Start conditionSMB_TX_byte(addr);SMB_TX_byte(RAM_Access|select);SMB_START_bit(); //Repeated Start conditionSMB_TX_byte(addr);arr[2]=SMB_RX_byte(ACK); //Read low data,master must send ACKarr[1]=SMB_RX_byte(ACK); //Read high data,master must send ACKtemp=make16(arr[1],arr[2]);crc=SMB_RX_byte(NACK); //Read PEC byte, master must send NACKSMB_STOP_bit(); //Stop conditionarr[5]=addr;arr[4]=RAM_Access|select;arr[3]=addr;arr[0]=0;if (crc != PEC_calculation(arr)) temp=0; // Calculate and check CRCreturn temp;}/*-------------------------------- MAIN --------------------------------------*/void real_main(){unsigned int16 seq, temp, tempa;signed int16 ta, to;int8 safety_counter;int1 repeat;output_high(DOME); // Close Domeoutput_low(HEATING); // Heating offdelay_ms(1000);restart_wdt();seq=0; // Variables initiationheat=0;open=0;repeat=TRUE;welcome();tempa=ReadTemp(SA, RAM_Tamb); // Dummy readtemp=ReadTemp(SA, RAM_Tobj1);delay_ms(1000);//---WDTrestart_wdt();while(TRUE) // Main Loop{safety_counter=SAFETY_COUNT; // Heating and Dome Count Downdo{if (safety_counter<SAFETY_COUNT) safety_counter++;delay(RESPONSE_DELAY);if (safety_counter>=SAFETY_COUNT){if (heat>0) heat--;if (open>0) open--;if (heat>0) { output_high(HEATING); } else { output_low(HEATING); }safety_counter=0;//---WDTrestart_wdt();}} while (!kbhit()&&!repeat);//---WDTrestart_wdt();{ // Retrieve commandchar ch='k';if(kbhit()) ch=getc();switch (ch){case 'h':heat=MAXHEAT; // Need heatingbreak;case 'c':heat=0; // Need colderbreak;case 'o':open=MAXOPEN; // Open the domebreak;case 'x':open=MAXOPEN; // Open the domeheat=MAXHEAT; // Need heatingbreak;case 'l':open=0; // Lock the domebreak;case 'i':if (open==0) welcome(); // Information about version, etc...break; // Only when dome is closedcase 'r':repeat=TRUE; // Repeated measure modebreak;case 's':repeat=FALSE; // Single measure modebreak;case 'u':// load_program(); // Update firmware}}// while(kbhit()) getc(); // Flush USART bufferCREN=0; CREN=1; // Reinitialise USARTseq++; // Increment the number of measurementtempa=ReadTemp(SA, RAM_Tamb); // Read temperatures from sensortemp=ReadTemp(SA, RAM_Tobj1);ta=tempa*2-27315; // °K -> °Cto=temp*2-27315;{ // printfchar output[8]; // Output bufferint8 j; // String pointerint8 check=0; // Checksum is calculated between '$' and '*'delay(SEND_DELAY);putc('$');delay(SEND_DELAY);sprintf(output,"M%s ",VER);j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }sprintf(output,"%Lu ", seq);j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }sprintf(output,"%Ld ", ta);j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }sprintf(output,"%Ld ", to);j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }sprintf(output,"%u ", heat);j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }sprintf(output,"%u ", open);j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j]); check^=output[j++]; }sprintf(output,"*%X\n\r\0", check);j=0; while(output[j]!=0) { delay(SEND_DELAY); putc(output[j++]); }delay(SEND_DELAY);}delay(MEASURE_DELAY); // Delay to a next measurement//---WDTrestart_wdt();}}/*------------------- BOOT LOADER --------------------------------------------*/#define LOADER_RESERVED getenv("PROGRAM_MEMORY")-getenv("FLASH_ERASE_SIZE")-800#define BUFFER_LEN_LOD 46#ORG LOADER_RESERVED,getenv("PROGRAM_MEMORY")-201 auto=0 defaultunsigned int atoi_b16(char *s) { // Convert two hex characters to a int8unsigned int result = 0;int i;for (i=0; i<2; i++,s++) {if (*s >= 'A')result = 16*result + (*s) - 'A' + 10;elseresult = 16*result + (*s) - '0';}return(result);}void assert(int1 Condition, int8 ErrorCode){if(Condition){putchar('E');putchar(ErrorCode+'1');reset_cpu();}}void pause(){int16 timeout;for(timeout=0; timeout<65535; timeout++); // Delay cca 300ms}boot_loader(){int buffidx;char buffer[BUFFER_LEN_LOD];int8 checksum, line_type;int16 l_addr,h_addr=0;int32 addr;#if getenv("FLASH_ERASE_SIZE")>2int32 next_addr;#endif//!!! #error ble getenv("FLASH_ERASE_SIZE") getenv("FLASH_WRITE_SIZE")int8 dataidx, i, count;union program_data {int8 i8[16];int16 i16[8];} data;putchar('@');//!!!nesmaze obsluhu prerusenifor(i=getenv("FLASH_ERASE_SIZE")+1;i<LOADER_RESERVED;i+=getenv("FLASH_ERASE_SIZE"))erase_program_eeprom(i);putchar('@');while(TRUE){//---WDT//!!! musi fungovat watchdogwhile (getc()!=':') restart_wdt(); // Only process data blocks that starts with ':'buffidx = 0; // Read into the buffer until 'x' is received or buffer is fulldo{buffer[buffidx] = getc();} while ( (buffer[buffidx++] != 'x') && (buffidx < BUFFER_LEN_LOD) );assert(buffidx == BUFFER_LEN_LOD,1); // Overrun buffer?//---WDTrestart_wdt();checksum = 0; // Sum the bytes to find the check sum valuefor (i=0; i<(buffidx-3); i+=2)checksum += atoi_b16 (&buffer[i]);checksum = 0xFF - checksum + 1;assert(checksum != atoi_b16 (&buffer[buffidx-3]),2); // Bad CheckSum?count = atoi_b16 (&buffer[0]); // Get the number of bytes from the buffer// Get the lower 16 bits of addressl_addr = make16(atoi_b16(&buffer[2]),atoi_b16(&buffer[4]));line_type = atoi_b16 (&buffer[6]);addr = make32(h_addr,l_addr);addr /= 2; // PIC16 uses word addresses// If the line type is 1, then data is done being sentif (line_type == 1){putchar('#');reset_cpu();}assert (line_type == 4,4);//!!! pozor, nevypalilo by to obsluhu preruseniif (addr > 3 || addr < LOADER_RESERVED){if (line_type == 0){for (i=0,next_addr=addr;i<8;i++)data.i16[i]=read_program_eeprom(next_addr++);// Loops through all of the data and stores it in data// The last 2 bytes are the check sum, hence buffidx-3for (i=8,dataidx=0; i < buffidx-3; i += 2)data.i8[dataidx++]=atoi_b16(&buffer[i]);write_program_memory(addr, data.i8, count);}putchar('*');}}}#ORG default#ORG getenv("PROGRAM_MEMORY")-200,getenv("PROGRAM_MEMORY")-1void main(){int8 timeout;disable_interrupts(GLOBAL);setup_wdt(WDT_2304MS); // Setup Watch Dogsetup_adc_ports(NO_ANALOGS);setup_adc(ADC_OFF);setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);setup_timer_1(T1_DISABLED);setup_timer_2(T2_DISABLED,0,1);setup_comparator(NC_NC_NC_NC);setup_vref(FALSE);setup_oscillator(OSC_8MHZ|OSC_INTRC);/*for(timeout=0; timeout<(3*20); timeout++) //cca 20sif (kbhit()){if (getc()=='u') if (getc()=='f') boot_loader(); // Update Firmware starterpause();CREN=0; CREN=1;restart_wdt();};*/real_main();}#include "dbloader.c"