예제 #1
0
int main(void  )
{
 	setupHardware();
	init_CIM_frame();
	old_PIND=PIND;
	old_PINB=PINB;
    sei();           // enable global interrupts

	while (1)
	{  
		parse_CIM_protocol();

	    if (send_ADCFrame_now)   // this is updated in the timer ISR !!
	    {
		    send_ADCFrame_now=0;
		    autoreply_num++; 
		    if (autoreply_num==0) autoreply_num=0x80;

		    CIM_frame.cim_feature=ARDUINO_CIM_FEATURE_ADCREPORT;
		    CIM_frame.serial_number=autoreply_num;
		    CIM_frame.reply_code=CMD_EVENT_REPLY;
			generate_ADCFrame();
			reply_DataFrame();
	     
		   //DDRB |= (1<<5); PORTB ^= (1<<5);  // indicate frame send with led
	    }

		if (check_PINChange_now)  // this is updated in the timer ISR !!
		{ 
		    check_PINChange_now=0;

			// has a selected pin changed ?
		    if ( ((old_PIND ^ PIND) & PIND_Mask) || ((old_PINB ^ PINB) & PINB_Mask))
			{
			    old_PIND=PIND;
			    old_PINB=PINB;				

			    autoreply_num++; 
			    if (autoreply_num==0) autoreply_num=0x80;

			    CIM_frame.cim_feature=ARDUINO_CIM_FEATURE_GET_PINVALUES;
			    CIM_frame.serial_number=autoreply_num;
				CIM_frame.reply_code=CMD_EVENT_REPLY;
			    generate_PINFrame();	     
			    reply_DataFrame();
			}
		}

	}
}
예제 #2
0
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);
}