void USART_Open(USART * serial, unsigned char port, unsigned char baud_rate, unsigned short tx_buf, unsigned short rx_buf, bool use_rs485, bool isSerialProtocol) {
	serial->ref = 0;
	serial->CharacterReceived = 0;
	serial->CharacterTransmitted = 0;
	serial->charCtr = 0;
	
	serial->port_num = port;
	serial->port = usart_ports[port];
	
	serial->baud_rate = baud_rate;
	serial->use_rs485 = use_rs485;
	
	if (isSerialProtocol) {
		serial->isSerialProtocol=true;
	}
	else {
		serial->isSerialProtocol=false;
		RingBufferInit(&serial->tx_buffer, tx_buf);
		RingBufferInit(&serial->rx_buffer, rx_buf);
	}
	
	USART_Table[port] = serial;
	
	serial->port.gpio_port->DIRSET = serial->port.tx_pin_bm;
	serial->port.gpio_port->DIRCLR = serial->port.rx_pin_bm;
	
	#ifdef USE_RS485
	if (use_rs485) {
		serial->port.gpio_port->DIRSET = serial->port.txen_pin_bm;
		serial->port.gpio_port->OUTCLR = serial->port.txen_pin_bm;
	}
	#endif
	
	cli();
		
	USART_Format_Set(serial->port.usart_port, USART_CHSIZE_8BIT_gc,
			USART_PMODE_DISABLED_gc, false); // 8 bits, no parity, one stop bit
	
	serial->port.usart_port->CTRLA = ((serial->port.usart_port)->CTRLA & ~USART_RXCINTLVL_gm) | USART_RXCINTLVL_LO_gc;
	
	if (use_rs485 || isSerialProtocol) { // only enable the TXC interrupt if we're in RS485 mode, as it's only used to clear the TXEN line
		serial->port.usart_port->CTRLA = ((serial->port.usart_port)->CTRLA & ~USART_TXCINTLVL_gm) | USART_TXCINTLVL_LO_gc;
	}
	
	if (isSerialProtocol) {
	//	serial->port.usart_port->CTRLA = ((serial->port.usart_port)->CTRLA & ~USART_DREINTLVL_gm) | USART_DREINTLVL_LO_gc;
	}
	
	serial->port.usart_port->BAUDCTRLA = USART_BAUD_TABLE[baud_rate] & 0xFF;
	serial->port.usart_port->BAUDCTRLB = (USART_BAUD_TABLE[baud_rate] >> 8);
	
	serial->port.usart_port->BAUDCTRLB |= ((USART_BSCALE_TABLE[baud_rate]&0x0F) << USART_BSCALE0_bp);
	
	USART_Rx_Enable(serial->port.usart_port);
	USART_Tx_Enable(serial->port.usart_port);
	
	PMIC.CTRL |= PMIC_LOLVLEX_bm;
	
	sei();
}
void UartMockDriverStateInit(UartMockDriverState *ms) {
    mock_state = ms;
    RingBufferInit(&ms->comm_state.uart_in_ringbuffer,
                   ms->comm_state.uart_in_data,
                   UART_MOCK_DRIVER_BUFFER_SIZE);
    RingBufferInit(&ms->comm_state.uart_out_ringbuffer,
                   ms->comm_state.uart_out_data,
                   UART_MOCK_DRIVER_BUFFER_SIZE);
    ms->int_handler = 0;
    ms->int_flags = 0;
}
Exemple #3
0
void SerialStartup()
{
        RingBufferInit( SerialInputBuffer, BUFFER_SIZE, &SerialInputRing );
        RingBufferInit( SerialOutputBuffer, BUFFER_SIZE, &SerialOutputRing );

        ReadGenerationCount=0;
        GenerationInit(&ReadGeneration, ReadGenerationCount);
        HandlerInit(&ReadGenerationCritObject);

        IsrRegisterHandler( SendBytesInterrupt, (void *) HAL_ISR_SERIAL_WRITE, IRQ_LEVEL_SERIAL_WRITE);
        IsrRegisterHandler( GetBytesInterrupt, (void *) HAL_ISR_SERIAL_READ, IRQ_LEVEL_SERIAL_READ);

        HalStartSerial();
}
Exemple #4
0
/*
 * Initializes a pipe
 */
void PipeInit( char * buff, COUNT size, struct PIPE * pipe )
{
        SemaphoreInit( & pipe->Mutex, 1 );
        SemaphoreInit( & pipe->ReaderLock, 0 ); //Buffer starts empty, to it is not readable. Semaphore starts locked
        SemaphoreInit( & pipe->WriterLock, 1 );//Buffer starts empty, so it is writable. Semaphore started unlocked.
        RingBufferInit( buff, size, & pipe->Ring );
}
Exemple #5
0
/**
 * \brief TmqhPacketpoolRegister
 * \initonly
 */
void TmqhPacketpoolRegister (void) {
    tmqh_table[TMQH_PACKETPOOL].name = "packetpool";
    tmqh_table[TMQH_PACKETPOOL].InHandler = TmqhInputPacketpool;
    tmqh_table[TMQH_PACKETPOOL].OutHandler = TmqhOutputPacketpool;

    ringbuffer = RingBufferInit();
    if (ringbuffer == NULL) {
        SCLogError(SC_ERR_FATAL, "Error registering Packet pool handler (at ring buffer init)");
        exit(EXIT_FAILURE);
    }
}
Exemple #6
0
/*
 * Initializes a pipe
 */
void PipeInit( char * buff, COUNT size, struct PIPE * pipe, PIPE_READ * pr, PIPE_WRITE * pw )
{
        SemaphoreInit( & pipe->Mutex, 1 );
        SemaphoreInit( & pipe->EmptyLock, 0 ); //Buffer starts empty, block reads.
        SemaphoreInit( & pipe->FullLock, 1 );//Buffer starts empty, allow writes.
        SemaphoreInit( & pipe->ReadLock, 1 );
        SemaphoreInit( & pipe->WriteLock, 1 );
        RingBufferInit( buff, size, & pipe->Ring );
        * pr = pipe;
        * pw = pipe;
}
void CommunicationInit(CommunicationState *com) {
    RingBufferInit(&com->uart_in_ringbuffer, com->uart_in_data,
            COMMUNICATION_UART_IN_BUFF_SIZE);
    BufferInit(&com->deframed_buffer, com->deframed_data,
            COMMUNICATION_UART_IN_BUFF_SIZE);
    RingBufferInit(&com->uart_out_ringbuffer, com->uart_out_data,
            COMMUNICATION_UART_OUT_BUFF_SIZE);

    _communicationState = com;
    CommunicationIntRegisterHandler(CommunicationISR);

    LogCString(LOG_LEVEL_DEBUG, "Initializing communication");

    // Initialize UART peripheral
    CommunicationHwInit();

    // Enable UART read interrupts
    CommunicationIntEnableRead();

    LogCString(LOG_LEVEL_DEBUG, "Communication initialized");
}
Exemple #8
0
void USART_Open(USART * serial, unsigned char port, unsigned char baud_rate, unsigned short tx_buf, unsigned short rx_buf, bool use_rs485) {
    serial->ref = 0;
    serial->CharacterReceived = 0;

    serial->port_num = port;
    serial->port = usart_ports[port];
    serial->baud_rate = baud_rate;
    serial->use_rs485 = use_rs485;

    //if (port==1){
    RingBufferInit(&serial->tx_buffer, tx_buf);
    RingBufferInit(&serial->rx_buffer, rx_buf);
    //}
    USART_Table[port] = serial;

    *(serial->port.GPIODDR) |= serial->port.tx_pin_bm;
    *(serial->port.GPIODDR) &= ~(serial->port.rx_pin_bm);

    if (use_rs485) {
        *(serial->port.GPIODDR) |= serial->port.txen_pin_bm;
        *(serial->port.GPIO) &= ~(serial->port.txen_pin_bm); // put RS485 transceiver in receive mode by default
    }
    cli();

    *(serial->port.UBRRH) = (USART_BAUD_TABLE[baud_rate] >> 8);
    *(serial->port.UBRRL) = USART_BAUD_TABLE[baud_rate] & 0xFF;
    USART_Tx_Enable(serial->port);
    USART_Rx_Enable(serial->port);
    USART_RxdInterrupt_Enable(serial->port);
    USART_UdeInterrupt_Enable(serial->port);
    if (use_rs485) { // only enable the TXC interrupt if in RS485 mode, since it's only used to clear the TXEN line
        USART_TxdInterrupt_Enable(serial->port);
        //*(serial->port.GPIO) |= serial->port.txen_pin_bm;
    }

    sei();
}
Exemple #9
0
/*********************************************************************//**
 * @brief 		Client Field Initialize
 * @param[in] 	None
 * @return 		None
 ***********************************************************************/
void ClientParserStructInit(void)
{
	// Reset from client ring buffer
	RingBufferInit(&(client_parser.buffer));

	// Initialize events
    client_parser.event = OSMboxCreate(NULL);

	// CMD Parse
    client_parser.mode = CLIENT_CFG_MODE;
    
    client_parser.data.current = CLIENT_RECV_HEADER_1;
	client_parser.parser[CLIENT_CFG_MODE] = CfgParser;
	client_parser.parser[CLIENT_OBD_MODE] = ObdParser;
    
    client_parser.cfg[CLIENT_RECV_HEADER_1] = CfgParserHeader1;
    client_parser.cfg[CLIENT_RECV_HEADER_2] = CfgParserHeader2;
    client_parser.cfg[CLIENT_RECV_LENGTH_1] = CfgParserLength1;
    client_parser.cfg[CLIENT_RECV_LENGTH_2] = CfgParserLength2;
    client_parser.cfg[CLIENT_RECV_DATA] = CfgParserData;
    client_parser.cfg[CLIENT_RECV_CHECKSUM] = CfgParserChecksum;
    
    client_parser.exe[CLIENT_CFG_GET_VERSION] = CfgExeGetVersion;
    client_parser.exe[CLIENT_CFG_OBD_MODE] = CfgExeOBDMode;
    client_parser.exe[CLIENT_CFG_SET_HEART_BEAT] = CfgExeSetHeartBeat;
    client_parser.exe[CLIENT_CFG_EXIT_OBD] = CfgExeExitOBD;
    
    client_parser.version[0] = 'D';
    client_parser.version[1] = 'A';
    client_parser.version[2] = '-';
    client_parser.version[3] = 'V';
    client_parser.version[4] = '0';
    client_parser.version[5] = '.';
    client_parser.version[6] = '0';
    client_parser.version[7] = '.';
    client_parser.version[8] = '1';
    client_parser.version[9] = '\0';
}
Exemple #10
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;
			}
		}
	}