uint8_t process_ARE_frame(uint8_t status_code) { uint8_t ack_needed; uint8_t data_size=0; uint8_t command; uint8_t bitmask = 0; // LEDs_ToggleLEDs(LED0); // indicate correct frame command=(uint8_t)ARE_frame.request_code; CIM_frame.cim_feature=ARE_frame.cim_feature; CIM_frame.serial_number=ARE_frame.serial_number; CIM_frame.reply_code=(((uint16_t)status_code)<<8) + command; data_size=(uint8_t)ARE_frame.data_size; ack_needed=1; // if ((status_code & (CIM_ERROR_INVALID_ARE_VERSION | CIM_ERROR_CRC_MISMATCH)) == 0) if ((status_code & CIM_ERROR_INVALID_ARE_VERSION) == 0) { // UART_Print(" feature "); UART_Putchar(command); // no serious packet error switch (command) { // process requested command case CMD_REQUEST_FEATURELIST: if (data_size==0) { reply_FeatureList(); // reply requested feature list ack_needed=0; } else status_code |= CIM_ERROR_INVALID_FEATURE; break; case CMD_REQUEST_RESET_CIM: if (data_size!=0) status_code |= CIM_ERROR_INVALID_FEATURE; break; case CMD_REQUEST_START_CIM: if (data_size==0) { enable_timer_ISR(); } else status_code |= CIM_ERROR_INVALID_FEATURE; break; case CMD_REQUEST_STOP_CIM: if (data_size==0) { // LEDs_ToggleLEDs(LED4); // indicate reset CIM first_packet=1; // reset first frame indicator etc. disable_timer_ISR(); DDRD = 0x00; servo3_en = 0; disable_PWM(3); servo5_en = 0; disable_PWM(5); servo6_en = 0; disable_PWM(6); } else status_code |= CIM_ERROR_INVALID_FEATURE; break; case CMD_REQUEST_READ_FEATURE: // read feature from CIM switch (ARE_frame.cim_feature) { case ARDUINO_CIM_FEATURE_UNIQUENUMBER: // read unique serial number if (data_size==0) { reply_UniqueNumber(); ack_needed=0; } else status_code |= CIM_ERROR_INVALID_FEATURE; break; case ARDUINO_CIM_FEATURE_GET_PINVALUES: generate_PINFrame(); reply_DataFrame(); ack_needed=0; break; case ARDUINO_CIM_FEATURE_ADCREPORT: generate_ADCFrame(); reply_DataFrame(); ack_needed=0; break; default: // not a valid read feature; status_code |= CIM_ERROR_INVALID_FEATURE; } break; case CMD_REQUEST_WRITE_FEATURE: // write feature to CIM switch (ARE_frame.cim_feature) { // which feature address ? case ARDUINO_CIM_FEATURE_SET_PINDIRECTION: // set DDR registers if (data_size==2) { DDRD=ARE_frame.data[0]; DDRB=ARE_frame.data[1]; } else status_code |= CIM_ERROR_INVALID_FEATURE; break; case ARDUINO_CIM_FEATURE_SET_PINSTATE: // set PORT registers if (data_size==2) { //check for running PWM bitmask = 0xFF; if(is_active_PWM(3)) bitmask &= ~(1<<PD3); if(is_active_PWM(6)) bitmask &= ~(1<<PD5); if(is_active_PWM(5)) bitmask &= ~(1<<PD6); if(servo3_en) bitmask &= ~(1<<PD3); if(servo5_en) bitmask &= ~(1<<PD5); if(servo6_en) bitmask &= ~(1<<PD6); PORTD=ARE_frame.data[0] & bitmask; PORTB=ARE_frame.data[1]; } else status_code |= CIM_ERROR_INVALID_FEATURE; break; case ARDUINO_CIM_FEATURE_SET_ADCPERIOD: if (data_size==2) { cli(); ADC_updatetime= (uint16_t)ARE_frame.data[0]; ADC_updatetime+= ((uint16_t)ARE_frame.data[1])<<8; sei(); } else status_code |= CIM_ERROR_INVALID_FEATURE; break; case ARDUINO_CIM_FEATURE_SET_PINMASK: if (data_size==2) { //check for running PWM bitmask = 0xFF; if(is_active_PWM(3)) bitmask &= ~(1<<PD3); if(is_active_PWM(5)) bitmask &= ~(1<<PD5); if(is_active_PWM(6)) bitmask &= ~(1<<PD6); if(servo3_en) bitmask &= ~(1<<PD3); if(servo5_en) bitmask &= ~(1<<PD5); if(servo6_en) bitmask &= ~(1<<PD6); PIND_Mask=ARE_frame.data[0] & bitmask; PINB_Mask=ARE_frame.data[1]; PCMSK0 = ARE_frame.data[1] & 0x3F; //enable pin change sensing on pins PB0-PB5 (PB6-7 are not connected) PCMSK2 = ARE_frame.data[0] & bitmask; //pin change sensing enable on port D } else status_code |= CIM_ERROR_INVALID_FEATURE; break; case ARDUINO_CIM_FEATURE_SET_PWM: if (data_size==2) { switch(ARE_frame.data[0] & 0xF0) //high nibble: operational mode of the output pin (PWM 1kHz-28kHz, servo or disabled) { case 0x10: // Servo output switch(ARE_frame.data[0] & 0x0F) //low nibble: selected output pin { case 0x03: //output pin 3 disable_PWM(3); servo3_en = 1; servo[0] = ARE_frame.data[1] * 79 + 13000; //extend range to timer values DDRD |= (1<<PD3); enable_servo_ISR(); break; case 0x05: //output pin 5 disable_PWM(5); servo5_en = 1; servo[1] = ARE_frame.data[1] * 79 + 13000; //extend range to timer values DDRD |= (1<<PD5); enable_servo_ISR(); break; case 0x06: //output pin 6 disable_PWM(6); servo6_en = 1; servo[2] = ARE_frame.data[1] * 79 + 13000; //extend range to timer values DDRD |= (1<<PD6); enable_servo_ISR(); break; } break; case 0x20: //PWM 500Hz output switch(ARE_frame.data[0] & 0x0F) //low nibble: selected output pin { case 0x03: //output pin 3 servo3_en = 0; pwm3 = ARE_frame.data[1]; enable_PWM_500Hz(3); break; case 0x05: //output pin 5 servo5_en = 0; pwm5 = ARE_frame.data[1]; enable_PWM_500Hz(5); break; case 0x06: //output pin 6 servo6_en = 0; pwm6 = ARE_frame.data[1]; enable_PWM_500Hz(6); break; } break; //disabled due to speed limitations of the controller /*case 0x30: //PWM 10kHz output switch(ARE_frame.data[0] & 0x0F) //low nibble: selected output pin { case 0x03: //output pin 3 pwm3 = ARE_frame.data[1]; enable_PWM_10kHz(3); break; case 0x05: //output pin 5 pwm5 = ARE_frame.data[1]; enable_PWM_10kHz(5); break; case 0x06: //output pin 6 pwm6 = ARE_frame.data[1]; enable_PWM_10kHz(6); break; } break; case 0x40: //PWM 28kHz output switch(ARE_frame.data[0] & 0x0F) //low nibble: selected output pin { case 0x03: //output pin 3 pwm3 = ARE_frame.data[1]; enable_PWM_28kHz(3); break; case 0x05: //output pin 5 pwm5 = ARE_frame.data[1]; enable_PWM_28kHz(5); break; case 0x06: //output pin 6 pwm6 = ARE_frame.data[1]; enable_PWM_28kHz(6); break; } break;*/ default: //default: disable switch(ARE_frame.data[0] & 0x0F) //low nibble: selected output pin { case 0x03: //output pin 3 DDRD &= ~(1<<PD3); PORTD &= ~(1<<PD3); servo3_en = 0; disable_PWM(3); if(!(servo5_en | servo6_en)) disable_servo_ISR(); break; case 0x05: //output pin 5 DDRD &= ~(1<<PD5); PORTD &= ~(1<<PD5); servo5_en = 0; disable_PWM(5); if(!(servo3_en | servo6_en)) disable_servo_ISR(); break; case 0x06: //output pin 6 DDRD &= ~(1<<PD6); PORTD &= ~(1<<PD6); servo6_en = 0; disable_PWM(6); if(!(servo3_en | servo5_en)) disable_servo_ISR(); break; } break; } } else status_code |= CIM_ERROR_INVALID_FEATURE; break; default: // not a valid write feature; status_code |= CIM_ERROR_INVALID_FEATURE; } } } if (status_code & CIM_ERROR_INVALID_FEATURE) { // invalid data size or feature // LEDs_ToggleLEDs(LED5); // indicate wrong feature // UART_Print(" invalid data size or no feature "); } if (ack_needed) { reply_Acknowledge(); } return(1); }
uint8_t process_ARE_frame(uint8_t status_code) { uint8_t ack_needed; uint8_t data_size=0; uint8_t command; // LEDs_ToggleLEDs(LED0); // indicate correct frame command=(uint8_t)ARE_frame.request_code; CIM_frame.cim_feature=ARE_frame.cim_feature; CIM_frame.serial_number=ARE_frame.serial_number; CIM_frame.reply_code=(((uint16_t)status_code)<<8) + command; data_size=(uint8_t)ARE_frame.data_size; ack_needed=1; // if ((status_code & (CIM_ERROR_INVALID_ARE_VERSION | CIM_ERROR_CRC_MISMATCH)) == 0) if ((status_code & CIM_ERROR_INVALID_ARE_VERSION) == 0) { // UART_Print(" feature "); UART_Putchar(command); // no serious packet error switch (command) { // process requested command case CMD_REQUEST_FEATURELIST: if (data_size==0) { reply_FeatureList(); // reply requested feature list ack_needed=0; } else status_code |= CIM_ERROR_INVALID_FEATURE; break; case CMD_REQUEST_RESET_CIM: if (data_size!=0) status_code |= CIM_ERROR_INVALID_FEATURE; break; case CMD_REQUEST_START_CIM: if (data_size==0) { cli(); init_CIM_frame(); setupHardware(); start_timer1(); sei(); } else status_code |= CIM_ERROR_INVALID_FEATURE; break; case CMD_REQUEST_STOP_CIM: if (data_size==0) { first_packet=1; // reset first frame indicator etc. stop_timer1(); } else status_code |= CIM_ERROR_INVALID_FEATURE; break; case CMD_REQUEST_READ_FEATURE: // read feature from CIM switch (ARE_frame.cim_feature) { case TEENSY_CIM_FEATURE_UNIQUENUMBER: // read unique serial number if (data_size==0) { reply_UniqueNumber(); ack_needed=0; } else status_code |= CIM_ERROR_INVALID_FEATURE; break; default: // not a valid read feature; status_code |= CIM_ERROR_INVALID_FEATURE; } break; case CMD_REQUEST_WRITE_FEATURE: // write feature to CIM switch (ARE_frame.cim_feature) { // which feature address ? case TEENSY_CIM_FEATURE_MODE_SELECTION: if (data_size==2) { cli(); selection = (uint16_t)ARE_frame.data[0]; selection += ((uint16_t)ARE_frame.data[1])<<8; sei(); } break; case TEENSY_CIM_FEATURE_SET_THRESHOLD: if (data_size==2) { cli(); threshold = (uint16_t)ARE_frame.data[0]; threshold += ((uint16_t)ARE_frame.data[1])<<8; sei(); } break; /*case TEENSY_CIM_FEATURE_SET_ADCPERIOD: if (data_size==2) { cli(); ADC_updatetime= (uint16_t)ARE_frame.data[0]; ADC_updatetime+= ((uint16_t)ARE_frame.data[1])<<8; sei(); } break;*/ default: // not a valid write feature; status_code |= CIM_ERROR_INVALID_FEATURE; } } } if (status_code & CIM_ERROR_INVALID_FEATURE) { // invalid data size or feature // LEDs_ToggleLEDs(LED5); // indicate wrong feature // UART_Print(" invalid data size or no feature "); } if (ack_needed) { reply_Acknowledge(); } return(1); }
uint8_t process_ARE_frame(uint8_t status_code) { uint8_t ack_needed; uint8_t data_size=0; uint8_t command; // LEDs_ToggleLEDs(LED0); // indicate correct frame command=(uint8_t)ARE_frame.request_code; CIM_frame.cim_feature=ARE_frame.cim_feature; CIM_frame.serial_number=ARE_frame.serial_number; CIM_frame.reply_code=(((uint16_t)status_code)<<8) + command; data_size=(uint8_t)ARE_frame.data_size; ack_needed=1; // if ((status_code & (CIM_ERROR_INVALID_ARE_VERSION | CIM_ERROR_CRC_MISMATCH)) == 0) if ((status_code & CIM_ERROR_INVALID_ARE_VERSION) == 0) { // UART_Print(" feature "); UART_Putchar(command); // no serious packet error switch (command) { // process requested command case CMD_REQUEST_FEATURELIST: if (data_size==0) { reply_FeatureList(); // reply requested feature list ack_needed=0; } else status_code |= CIM_ERROR_INVALID_FEATURE; break; case CMD_REQUEST_RESET_CIM: if (data_size!=0) status_code |= CIM_ERROR_INVALID_FEATURE; break; case CMD_REQUEST_START_CIM: if (data_size==0) { enable_timer_ISR(); } else status_code |= CIM_ERROR_INVALID_FEATURE; break; case CMD_REQUEST_STOP_CIM: if (data_size==0) { // LEDs_ToggleLEDs(LED4); // indicate reset CIM first_packet=1; // reset first frame indicator etc. disable_timer_ISR(); } else status_code |= CIM_ERROR_INVALID_FEATURE; break; case CMD_REQUEST_READ_FEATURE: // read feature from CIM switch (ARE_frame.cim_feature) { case LIPMOUSE_CIM_FEATURE_UNIQUENUMBER: // read unique serial number if (data_size==0) { reply_UniqueNumber(); ack_needed=0; } else status_code |= CIM_ERROR_INVALID_FEATURE; break; case LIPMOUSE_CIM_FEATURE_ADCREPORT: generate_ADCFrame(); reply_DataFrame(); ack_needed=0; break; case LIPMOUSE_CIM_FEATURE_BUTTONREPORT: generate_ButtonFrame(); reply_DataFrame(); ack_needed=0; break; default: // not a valid read feature; status_code |= CIM_ERROR_INVALID_FEATURE; } break; case CMD_REQUEST_WRITE_FEATURE: // write feature to CIM switch (ARE_frame.cim_feature) { // which feature address ? case LIPMOUSE_CIM_FEATURE_SET_ADCPERIOD: if (data_size==2) { cli(); ADC_updatetime= (uint16_t)ARE_frame.data[0]; ADC_updatetime+= ((uint16_t)ARE_frame.data[1])<<8; sei(); } break; case LIPMOUSE_CIM_FEATURE_SET_LEDS: if (data_size==1) { uint8_t actLeds=ARE_frame.data[0]; if (actLeds&1) PORTB&=~(1<<0); else PORTB|=(1<<0); if (actLeds&2) PORTE&=~(1<<7); else PORTE|=(1<<7); if (actLeds&4) PORTE&=~(1<<6); else PORTE|=(1<<6); } break; default: // not a valid write feature; status_code |= CIM_ERROR_INVALID_FEATURE; } } } if (status_code & CIM_ERROR_INVALID_FEATURE) { // invalid data size or feature // LEDs_ToggleLEDs(LED5); // indicate wrong feature // UART_Print(" invalid data size or no feature "); } if (ack_needed) { reply_Acknowledge(); } return(1); }