/********************************************************* * --------------------------------------------------------------------------- * Zwembad.c - v1.0 (c) 2008 UU/Beta/Instrumentatie * --------------------------------------------------------------------------- * Universiteit Utrecht * Faculteit Betawetenschappen * Instrumentatie * Postbus 80004, 3508 TA Utrecht * Tel: +31 30 2532802 * Fax: +31 30 2522267 * Email: j.a.wisman@uu.nl * Web:http: www.science.uu.nl/instrumentatie * --------------------------------------------------------------------------- * Description: Zwembad - main module * -------------------------------------------------------------------------- * Version: 1.0, 21-08-2008, Jody Wisman * Creation. *****************************************************************************/ #define USING_REAL_MICROCONTR #include "C:\MentorProjects\Arjens_Badkuip\PIC_Code\Zwembad.h" #include "C:\MentorProjects\Arjens_Badkuip\PIC_Code\M95160SPI.c" #include "C:\MentorProjects\Arjens_Badkuip\PIC_Code\IR_RECEIVE.c" #include #include #include #include #include // Defines #define RS485_ENABLE PIN_B1 #define POLY 0x0107 // 0000 0001 0000 0111 = x^8+x^2+x^1+x^0 #define CRC_INIT 0x00 #define MAXINPUTBUF 45 // Maximum length of input #define GETSTATUS_ID 1 #define RESET_ID 2 #define GETID_ID 3 #define SETLIGHT_ID 5 #define UNKNOWN_ID 8 // Typedefs typedef unsigned char CRC_TYPE; void emptyString(char *in); // Declarations of globals int1 endInput = FALSE; byte next_in = 0; unsigned char crc_calculated; char ModState='C'; char input485[MAXINPUTBUF]; char input232[MAXINPUTBUF]; char string_copy[MAXINPUTBUF]; char string_backup[MAXINPUTBUF]; char string_spare[MAXINPUTBUF]; char delimiters[2]; char *ptr; char asnummer[1]; char commando[10]; char param1[6]; char param2[6]; char param3[6]; char *commands[10]; int8 idnummer; int8 commandids[] = {GETSTATUS_ID, RESET_ID, GETID_ID, SETLIGHT_ID, UNKNOWN_ID }; // Functions and function prototypes void sendAck(int8 idnummer, unsigned char crc_calculated); void sendNack(int8 idnummer); // Interrupt routine for RC5 receiving data // EXT: Extern interrupt // This routine reads input from the RC5 infrared receiver #int_EXT EXT_isr() { get_RC5(); } // Interrupt routine for 485 communication // RDA: Receive Data Available. This routine reads input from the RS485 input until an End Of Line (0x0a) // is received #int_RDA RDA_isr() { if((next_in < (MAXINPUTBUF-1)) && (next_in >= 0)) { input485[next_in] = getc (); if ((input485[next_in] == 0x0A) && (next_in > 1)) { endInput = TRUE; input485[next_in + 1] = '\0'; } next_in = (next_in + 1); } else { emptyString(input485); } } // Interrupt routine for RS232 communication // RDA: Receive Data Available. This routine reads input from the RS232 input until an End Of Line (0x0a) // is received #int_RDA2 RDA2_isr() { if((next_in < (MAXINPUTBUF-1)) && (next_in >= 0)) { input232[next_in] = getc (); if ((input232[next_in] == 0x0A) && (next_in > 1)) { endInput = TRUE; input232[next_in + 1] = '\0'; } next_in = (next_in + 1); } else { emptyString(input232); } } /* The following TYPEDEF's should be adjusted for the particular platform. * CRC - 8 x ^ 8 + x ^ 2 + x + 1 * prototypes */ unsigned char generate_8bit_crc(char* data, int16 length, int pattern) { int *current_data; int crc_byte; int16 byte_counter; int bit_counter; current_data = data; crc_byte = *current_data++; for (byte_counter = 0; byte_counter < (length - 1) ; byte_counter++) { for (bit_counter = 0; bit_counter < 8; bit_counter++) { if ( ! bit_test (crc_byte, 7)) { crc_byte <<= 1; bit_test ( * current_data, 7 - bit_counter) ? bit_set (crc_byte, 0) : bit_clear (crc_byte, 0) ; continue; } crc_byte <<= 1; bit_test ( * current_data, 7 - bit_counter) ? bit_set (crc_byte, 0) : bit_clear (crc_byte, 0) ; crc_byte ^= pattern; } current_data++; } for (bit_counter = 0; bit_counter < 8; bit_counter++) { if ( ! bit_test (crc_byte, 7)) { crc_byte <<= 1; continue; } crc_byte <<= 1; crc_byte ^= pattern; } return crc_byte; } void emptyString(char *in) { int8 i; for (i = 0; i < MAXINPUTBUF; i++) { in[i] = 0; } next_in = 0; } int8 getCommandID(char *cmdstr) { int8 i; for(i = 1; i < UNKNOWN_ID; i++) { if( ! strcmp(cmdstr, commands[i])) { return (commandids[i]); } } return (UNKNOWN_ID); } void sendAck(int8 idnummer, unsigned char crc_calculated) { output_high (RS485_ENABLE); delay_ms (10); printf (" %c", ModState); printf (" %02x ACK \n", crc_calculated); delay_ms (5); output_low (RS485_ENABLE); return; } void sendNack(int8 idnummer) { output_high (RS485_ENABLE); delay_ms (500); printf (" %c", ModState); printf (" %02x NACK \n", crc_calculated); delay_ms (500); output_low (RS485_ENABLE); return; } void initSystem(void) { // System initialisation setup_ccp1 (CCP_PWM); // Configure CCP1 as a PWM at RC2 setup_ccp2 (CCP_PWM); // Configure CCP2 as a PWM at RC1 setup_ccp3 (CCP_PWM); // Configure CCP3 as a PWM at RG3 setup_adc_ports(NO_ANALOGS); // No ADC setup_adc(ADC_OFF); // No ADC setup_spi(spi_master |spi_l_to_h | spi_clk_div_16 ); setup_wdt(WDT_OFF); // No Watchdog setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); setup_timer_2(T2_DISABLED,0,1); setup_comparator(NC_NC_NC_NC); setup_vref(FALSE); setup_psp(PSP_DISABLED); ext_int_edge(0,H_TO_L); enable_interrupts(INT_TIMER1); enable_interrupts(INT_EXT); enable_interrupts(INT_RDA); enable_interrupts(INT_RDA2); enable_interrupts(GLOBAL); set_pwm1_duty (0); set_pwm2_duty (0); set_pwm3_duty (0); init_ext_eeprom(); } void main(void) { int8 lengte = 0; int8 commandID; int32 redval=0, blueval=0,greenval=0; unsigned int32 axis_val = 0; emptyString(input485); endInput = FALSE; initSystem(); rc5.state = 0; // Set periphery in default status output_low (RS485_ENABLE); idnummer = 1; while(1) { if(rc5.state==1) // did we receive a valid RC5 - command? { // interprete the command here...RC5 command..... rc5.state = 0; enable_interrupts(INT_EXT); } if (endInput == TRUE) // Complete input string is read in, do something { lengte = strlen (input485); if ((lengte > MAXINPUTBUF) || (lengte < 10) ) { /* "2 Reset f0" = 10 characters, shortest command */ /* (longest commandstring ca. 25 readable characters) */ /* something wrong, flush it */ lengte = 0; // sendNack(idnummer); // crc_calculated=0xaa; // sendNack(idnummer); } else { /* good length, handle further */ strcpy (string_backup, input485); // save inputstring strcpy (string_copy, string_backup); lengte = lengte - 4; /* = minus: space after last arg , two crc chars, eol= 0x0a */ string_copy[lengte]=0; /* 0..(lengte-1), is full string */ crc_calculated = generate_8bit_crc (string_copy, lengte , 0x107); strcpy (delimiters, " "); /* this is the commandstring, with ' ' as delimeters */ ptr = strtok (string_backup, delimiters); strcpy (asnummer, ptr); axis_val = atoi (asnummer); // ---------------------------------------------------------------------------- // Check which command to perform // ---------------------------------------------------------------------------- if ( (axis_val == idnummer) || (axis_val == 255)) { /* advance over the delimeter(s) to the next string part */ ptr = strtok (0, delimiters); strcpy (commando, ptr); // Check which command is received // Check command commandID = getCommandID(commando); switch(commandID) { case GETSTATUS_ID : sendAck(idnummer, crc_calculated); break; case RESET_ID : sendAck(idnummer, crc_calculated); lengte = 0; set_pwm1_duty (0); set_pwm2_duty (0); set_pwm3_duty (0); break; case GETID_ID : sendAck(idnummer, crc_calculated); break; case SETLIGHT_ID : // PWM1 = Blauw, PWM2 = Rood, PWM3 = Groen ptr = strtok (0, delimiters); strcpy (param1, ptr); redval = atol (param1); ptr = strtok (0, delimiters); strcpy (param2, ptr); greenval = atol (param2); ptr = strtok (0, delimiters); strcpy (param3, ptr); blueval = atol (param3); if ((redval >= 0) && (redval < 1024)) { if ((greenval >= 0) && (greenval < 1024)) { if ((blueval >= 0) && (blueval < 1024)) { /* ALL values are OK, now shine a light */ set_pwm3_duty (redval); // PWM2 = Rood set_pwm2_duty (greenval); // PWM3 = Groen set_pwm1_duty (blueval); // PWM1 = Blauw sendAck(idnummer, crc_calculated); } else sendNack(idnummer); } else sendNack(idnummer); } else sendNack(idnummer); break; case UNKNOWN_ID : sendNack(idnummer); break; default: sendNack(idnummer); break; } // End of switch(commandID) /* remember this command (for this module!) */ strcpy (string_spare, string_backup); } /* we end up here after starting or rejecting a command for this module */ /* we also end up here if the command was for another module */ /* flush any unread strtok() parts */ { int stringdone = FALSE; char * sp; while (!stringdone) { sp = strtok(0,delimiters); stringdone = (sp == NULL); } } } /* after either good or bad input, end up here */ emptyString(input485); EndInput = FALSE; /* allow filling of inputbuffer again*/ } } }