Exemplo n.º 1
0
//------------------------------------------------------------------------------
static void RxInit(unsigned int start_comm_tmout, unsigned int max_interchar_tmout)
{
	rx_state = RX_NOT_STARTED;
	start_reception_tmout = start_comm_tmout;
	interchar_tmout = max_interchar_tmout;
	TickStart(0, start_reception_tmout);
	comm_buf[0] = 0x00; // end of string
	p_comm_buf = comm_buf;
	comm_buf_len = 0;
	//mySerial.flush(); // erase rx circular buffer
	while(SerialDataAvailable())
		SerialReadByte();
}
Exemplo n.º 2
0
//------------------------------------------------------------------------------
static unsigned char IsRxFinished(void)
{
	unsigned char num_of_bytes;
	unsigned char ret_val = RX_NOT_FINISHED;  // default not finished

	// Rx state machine
	// ----------------

	if (rx_state == RX_NOT_STARTED)
	{
		// Reception is not started yet - check tmout
		if (!SerialDataAvailable())
		{
			// still no character received => check timeout
			/*  
			#ifdef DEBUG_GSMRX

			DebugPrint("\r\nDEBUG: reception timeout", 0);			
			Serial.print((unsigned long)(millis() - prev_time));	
			DebugPrint("\r\nDEBUG: start_reception_tmout\r\n", 0);			
			Serial.print(start_reception_tmout);	


			#endif
			*/
			if (TickExpired(0))
			{
				// timeout elapsed => GSM module didn't start with response
				// so communication is takes as finished
				/*
				#ifdef DEBUG_GSMRX		
				DebugPrint("\r\nDEBUG: RECEPTION TIMEOUT", 0);	
				#endif
				*/
				comm_buf[comm_buf_len] = 0x00;
				ret_val = RX_TMOUT_ERR;
			}
		}
		else
		{
			// at least one character received => so init inter-character 
			// counting process again and go to the next state
			TickStart(0, interchar_tmout); // init tmout for inter-character space
			rx_state = RX_ALREADY_STARTED;
		}
	}

	if (rx_state == RX_ALREADY_STARTED)
	{
		// Reception already started
		// check new received bytes
		// only in case we have place in the buffer
		num_of_bytes = SerialDataAvailable();
		// if there are some received bytes postpone the timeout
		if (num_of_bytes)
			TickStart(0, interchar_tmout);

		// read all received bytes      
		while (num_of_bytes)
		{
			num_of_bytes--;
			if (comm_buf_len < COMM_BUF_LEN)
			{
				// we have still place in the GSM internal comm. buffer =>
				// move available bytes from circular buffer 
				// to the rx buffer
				*p_comm_buf = SerialReadByte();

				p_comm_buf++;
				comm_buf_len++;
				comm_buf[comm_buf_len] = 0x00;  // and finish currently received characters
				// so after each character we have
				// valid string finished by the 0x00
			}
			else
			{
				// comm buffer is full, other incoming characters
				// will be discarded 
				// but despite of we have no place for other characters 
				// we still must to wait until  
				// inter-character tmout is reached

				// so just readout character from circular RS232 buffer 
				// to find out when communication id finished(no more characters
				// are received in inter-char timeout)
				SerialReadByte();
			}
		}

		// finally check the inter-character timeout 
		/*
		#ifdef DEBUG_GSMRX

		DebugPrint("\r\nDEBUG: intercharacter", 0);			
		Serial.print((unsigned long)(millis() - prev_time));	
		DebugPrint("\r\nDEBUG: interchar_tmout\r\n", 0);			
		Serial.print(interchar_tmout);	


		#endif
		*/
		if (TickExpired(0))
		{
			// timeout between received character was reached
			// reception is finished
			// ---------------------------------------------

			/*
			#ifdef DEBUG_GSMRX

			DebugPrint("\r\nDEBUG: OVER INTER TIMEOUT", 0);					
			#endif
			*/
			comm_buf[comm_buf_len] = 0x00;  // for sure finish string again
			// but it is not necessary
			ret_val = RX_FINISHED;
		}
	}
	
  	#ifdef DEBUG_GSMRX
	if (ret_val == RX_FINISHED)
	{
		DebugPrint("DEBUG: Received string\r\n", 0);
		for (int i=0; i<comm_buf_len; i++)
		{
			Serial.print(byte(comm_buf[i]));	
		}
	}
	#endif
	
	return (ret_val);
}
Exemplo n.º 3
0
int main(void)
{
	InitClock();
	SerialInit();
	
	RingBufferInit(&location_buffer, 4, locations);
	
	PORTC.DIRSET = 0xF3;
	PORTE.DIRSET = 0xFF;
	PORTD.DIRSET = 0x33;
	PORTB.DIRCLR = 0xFF; /* PortB all inputs */
	
	/* Timers */
	//x_axis.step_timer = &TCC1;
	x_axis.pwm_timer = &TCC0;
	
	/* Limit Switches */
	x_axis.limit_switch_port = &PORTB;
	x_axis.limit_switch_mask = (1<<0); /* PORTB.0 */
	
	/* DIR ports (for inverting the stepper motor driver polarity) */
	x_axis.sign_select_port = &PORTC;
	x_axis.sign_switch_mask1 = 0x20; /* PORTC.5 */
	x_axis.sign_switch_mask2 = 0x10; /* PORTC.4 */
	
	/* PWM outputs: outputs will be 90 degrees out of phase */
	x_axis.phase_pwm_cmp1 = &(TCC0.CCB);
	x_axis.phase_pwm_cmp2 = &(TCC0.CCA);
	x_axis.compare_mask = TC0_CCBEN_bm | TC0_CCAEN_bm;
	
	/* Power Controls change the period: a longer period means longer off time and lower duty cycle */
	//x_axis.axis_idle_power = 60;
	x_axis.axis_run_power = 31;
	
	/* The minimum period of the PWM update timer/counter */
	/* Stepper motor tick period = 32 * min_period / 16000000 */
	//x_axis.min_period = 15;
	AxisInit (&x_axis);
	
	//y_axis.step_timer = &TCD1;
	y_axis.pwm_timer = &TCD0;
	y_axis.limit_switch_port = &PORTB;
	y_axis.limit_switch_mask  = (1<<1); /* PORTB.1 */
	y_axis.sign_select_port = &PORTD;
	y_axis.sign_switch_mask1 = 0x20;
	y_axis.sign_switch_mask2 = 0x10;
	y_axis.phase_pwm_cmp1 = &(TCD0.CCB);
	y_axis.phase_pwm_cmp2 = &(TCD0.CCA);
	y_axis.compare_mask = TC0_CCBEN_bm | TC0_CCAEN_bm;
	//y_axis.axis_idle_power = 60;
	y_axis.axis_run_power = 31;
	//y_axis.min_period = 15;
	AxisInit (&y_axis);
	
	//z_axis.step_timer = &TCE1;
	z_axis.pwm_timer = &TCE0;
	z_axis.limit_switch_port = &PORTB;
	z_axis.limit_switch_mask = (1<<2); /* PORTB.2 */
	z_axis.sign_select_port = &PORTE;
	z_axis.sign_switch_mask1 = 0x20; /* PORTE.5 */
	z_axis.sign_switch_mask2 = 0x10; /* PORTE.4 */
	z_axis.phase_pwm_cmp1 = &(TCE0.CCD);
	z_axis.phase_pwm_cmp2 = &(TCE0.CCC);
	z_axis.compare_mask = TC0_CCDEN_bm | TC0_CCCEN_bm;
	//z_axis.axis_idle_power = 60;
	z_axis.axis_run_power = 31; /* 33 unique waveform values: 0 (ground) to 33 (3.3v) */
	//z_axis.min_period = 15;
	AxisInit (&z_axis);

	PMIC.CTRL |= PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;
	
	// Fire up the timer for incrementing/decrementing steps
	TC0_t * step_timer = &TCC1;
	
	step_timer->CTRLB = TC_WGMODE_SS_gc;
	
	/* Overflow every 1 ms: 16Mhz / (64 * 250) = 1ms */						
	step_timer->PER = 250;
	step_timer->CTRLA = TC_CLKSEL_DIV64_gc;
	step_timer->CTRLFSET = TC_CMD_RESTART_gc;
	
	/* Enable the step overflow interrupt */
	step_timer->INTCTRLA |= TC_OVFINTLVL_LO_gc;
	// To Disable: axis->step_timer->INTCTRLA &= ~TC1_OVFINTLVL_gm;	
	
	
	char task = 0;
	sei();
	while(1)
    {
		//PORTE.OUTTGL = 0x02;
		
		//_delay_ms (10);
		
		//SerialData * s = SerialDataTransmitStruct();
		//if (s != 0)
		//{
		//	s->transmit_data[0] = 'a';
		//	s->transmit_data[1] = 'b';
		//	s->transmit_data[2] = 'c';
		//	SerialTransmit(s, 0x00, 3);
		//}
		
		SerialData * s = SerialDataAvailable();
		if (s != 0)
		{
			switch (s->receive_data[0])
			{
				case 0x88: // Reset everything (all axis back to limit switches)
				{
					task = TASK_LIMIT_SWITCH_Y;
					x_axis.state = 1;
					y_axis.state = 1;
					z_axis.state = 1;
					s->transmit_data[0] = 0x88;
					SerialTransmit (s, 0x00, 1); // Transmit to master device
					break;
				}
				case 0x77: // Ping (and location/status information)
				{
					s->transmit_data[0] = 0x77;
					
					// TODO: find a better way to do this
					step_timer->INTCTRLA &= ~TC1_OVFINTLVL_gm; // Disable the step timer
					int32_t x = AxisGetCurrentPosition(&x_axis);
					int32_t y = AxisGetCurrentPosition(&y_axis);
					int32_t z = AxisGetCurrentPosition(&z_axis);
					step_timer->INTCTRLA |= TC_OVFINTLVL_LO_gc; // Enable the step timer
					
					s->transmit_data[1] = x & 0xFF; x = x >> 8;
					s->transmit_data[2] = x & 0xFF; x = x >> 8;
					s->transmit_data[3] = x & 0xFF; x = x >> 8;
					s->transmit_data[4] = x & 0xFF;
					
					s->transmit_data[5] = y & 0xFF; y = y >> 8;
					s->transmit_data[6] = y & 0xFF; y = y >> 8;
					s->transmit_data[7] = y & 0xFF; y = y >> 8;
					s->transmit_data[8] = y & 0xFF;
					
					s->transmit_data[9] = z & 0xFF; z = z >> 8;
					s->transmit_data[10] = z & 0xFF; z = z >> 8;
					s->transmit_data[11] = z & 0xFF; z = z >> 8;
					s->transmit_data[12] = z & 0xFF;
					
					uint8_t status_bits = 0;
					if (IsMoving (&x_axis))
					{
						status_bits |= 0x01;
					}
					if (IsMoving (&y_axis))
					{
						status_bits |= 0x02;
					}
					if (IsMoving (&z_axis))
					{
						status_bits |= 0x04;
					}
					s->transmit_data[13] = status_bits;
					
					//step_timer->INTCTRLA &= ~TC1_OVFINTLVL_gm; // Disable the step timer
					buffer_lock = 1;
					s->transmit_data[14] = RingBufferCount(&location_buffer);
					buffer_lock = 0;
					//step_timer->INTCTRLA |= TC_OVFINTLVL_LO_gc; // Enable the step timer
					
					//s->transmit_data[14] = location_buffer_size;
					
					SerialTransmit (s, 0x00, 15); // Transmit to master device
					break;
				}
				case 0x32: // Set Position + Speed
				{
					Location_t l;
					
					/* Bytes 1:2 are time in milliseconds */
					l.time = decode_uint16_t(&(s->receive_data[1]));
					
					/* Bytes 3:14 are position */
					l.x = decode_uint32_t(&(s->receive_data[3]));
					l.y = decode_uint32_t(&(s->receive_data[7]));
					l.z = decode_uint32_t(&(s->receive_data[11]));
					
					// Add the new location to the buffer
					//step_timer->INTCTRLA &= ~TC1_OVFINTLVL_gm; // Disable the step timer
					
					buffer_lock = 1;
					if (!RingBufferIsFull(&location_buffer))
					{
						RingBufferAdd(&location_buffer, l);
					}
					//if (location_buffer_size < 1)
					//{
					//	nextLocation = l;
					//	location_buffer_size++;
					//}
					s->transmit_data[1] = RingBufferCount(&location_buffer);
					buffer_lock = 0;
					//step_timer->INTCTRLA |= TC_OVFINTLVL_LO_gc; // Enable the step timer
					
					s->transmit_data[0] = 0x32;
					//s->transmit_data[1] = location_buffer_size;
					SerialTransmit(s, 0x00, 2);
					break;
				}
			}
		}
		else if (task == TASK_LIMIT_SWITCH_Y)
		{
			uint8_t v = LimitSwitchHelper(&x_axis);
			v &= LimitSwitchHelper(&y_axis);
			v &= LimitSwitchHelper(&z_axis);
			if (v)
			{
				task = 0;
			}
		}
	}