示例#1
0
void StdCan_SendHeartbeat(uint8_t n)
{
	/* TODO: When a Tx queue is implemented, the heartbeat should
	 * be sent via StdCan_Put instead of directly to lower layer.
	 */
	Can_Message_t Heartbeat;

	/* Set up Heartbeat message format. */
	Heartbeat.ExtendedFlag = 1;
	Heartbeat.RemoteFlag = 0;
#ifdef MODULE_APPLICATION
	Heartbeat.DataLength = 5;
	Heartbeat.Id = (CAN_NMT << CAN_SHIFT_CLASS) | (CAN_NMT_HEARTBEAT << CAN_SHIFT_NMT_TYPE);
	Heartbeat.Data.bytes[0] = NODE_HW_ID_BYTE0;
	Heartbeat.Data.bytes[1] = NODE_HW_ID_BYTE1;
	Heartbeat.Data.bytes[2] = NODE_HW_ID_BYTE2;
	Heartbeat.Data.bytes[3] = NODE_HW_ID_BYTE3;
	Heartbeat.Data.bytes[4] = NUMBER_OF_MODULES;
#else


	Heartbeat.DataLength = 0;
	Heartbeat.Id = (CAN_NMT << CAN_SHIFT_CLASS)
				 | (CAN_NMT_HEARTBEAT << CAN_SHIFT_NMT_TYPE)
				 | (NODE_ID << CAN_SHIFT_NMT_SID);
#endif

	/* Try to send it. */
	Can_Send(&Heartbeat);
}
示例#2
0
StdCan_Ret_t StdCan_Put(StdCan_Msg_t* msg)
{
	Can_Message_t Can_Msg;
	unsigned char n;

	/* Validate message. */
	if ((unsigned)msg->Length > 8) return StdCan_Ret_DataErr;

	/* Copy message directly to lower layer until a proper
	 * queue has been implemented.
	 * TODO: Implement a proper queue. This requires TX interrupt
	 * support in the driver and BIOS.
	 */
	Can_Msg.ExtendedFlag = 1;
	Can_Msg.RemoteFlag = 0;
	Can_Msg.Id = msg->Id;
	Can_Msg.DataLength = msg->Length;
	for (n = 0; n < msg->Length; n++) {
		Can_Msg.Data.bytes[n] = msg->Data[n];
	}

	if (Can_Send(&Can_Msg) == CAN_OK) {
#ifdef MODULE_APPLICATION
		Can_Process(&Can_Msg);
#endif
		return StdCan_Ret_OK;
	}
	else
		return StdCan_Ret_Full;
}
示例#3
0
StdCan_Ret_t StdCan_Init(Node_Desc_t* node_desc)
{
#endif
	StdCan_Ret_t retval;

	/* Reset all queue variables. */
	RxQ_Rd_idx = 0;
	RxQ_Wr_idx = 0;
	RxQ_Len    = 0;
#if (STDCAN_TX_QUEUE_SIZE > 1)
	TxQ_Rd_idx = 0;
	TxQ_Wr_idx = 0;
	TxQ_Len    = 0;
#endif

#if defined(_AVRLIB_BIOS_)
	/* Initialize BIOS' interface for CAN. */
	BIOS_CanCallback = Can_Process;
	retval = StdCan_Ret_OK;
#else
	/* Initialize CAN driver. */
	if (Can_Init() == CAN_OK)
		retval = StdCan_Ret_OK;
	else
		retval = StdCan_Ret_Fail;
#endif

	//TODO: Do something with the Node Descriptor.
	//(why have constats passed as parameters? they are defined at compiletime /arune)
#if defined(_AVRLIB_BIOS_)
	/* TODO: When a Tx queue is implemented, the startup message should
	 * be sent via StdCan_Put instead of directly to lower layer.
	 */
	Can_Message_t Startup;

	/* Set up Startup message format. */
	Startup.ExtendedFlag = 1;
	Startup.RemoteFlag = 0;
	Startup.DataLength = 4;
#ifdef MODULE_APPLICATION
	Startup.Id = (CAN_NMT << CAN_SHIFT_CLASS) | (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE);
	Startup.Data.bytes[0] = NODE_HW_ID&0xff;
	Startup.Data.bytes[1] = (NODE_HW_ID>>8)&0xff;
	Startup.Data.bytes[2] = (NODE_HW_ID>>16)&0xff;
	Startup.Data.bytes[3] = (NODE_HW_ID>>24)&0xff;
#else
	Startup.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID);
	Startup.Data.bytes[1] = APP_TYPE&0xff;
	Startup.Data.bytes[0] = (APP_TYPE>>8)&0xff;
	Startup.Data.bytes[3] = APP_VERSION&0xff;
	Startup.Data.bytes[2] = (APP_VERSION>>8)&0xff;
#endif
	/* Try to send it. */
	Can_Send(&Startup);
#endif

	return retval;
}
示例#4
0
int main(void)
{
	// Enable interrupts as early as possible
	sei();
	
	Timer_Init();
	Serial_Init();
	uint8_t returnval = Can_Init();
	if (returnval != CAN_OK) {
	}
	
	Can_Message_t txMsg;
	txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID);
	txMsg.DataLength = 4;
	txMsg.RemoteFlag = 0;
	txMsg.ExtendedFlag = 1;
	txMsg.Data.words[0] = APP_TYPE;
	txMsg.Data.words[1] = APP_VERSION;
	
	// Set up callback for CAN reception, this is optional if only sending is required.
	BIOS_CanCallback = &can_receive;
	// Send CAN_NMT_APP_START
	BIOS_CanSend(&txMsg);
	
	while (1) {
		
		if (extRxMsgFull) {
			txMsg.Id = extRxMsg.Id;
			txMsg.DataLength = extRxMsg.DataLength;
			txMsg.RemoteFlag = extRxMsg.RemoteFlag;
			txMsg.ExtendedFlag = extRxMsg.ExtendedFlag;
			for (uint8_t i = 0; i < txMsg.DataLength; i++) {
				txMsg.Data.bytes[i] = extRxMsg.Data.bytes[i];
			}
			BIOS_CanSend(&txMsg);

    		extRxMsgFull = 0; //  
		}
		if (rxMsgFull) {
			extTxMsg.Id = rxMsg.Id;
			extTxMsg.DataLength = rxMsg.DataLength;
			extTxMsg.RemoteFlag = rxMsg.RemoteFlag;
			extTxMsg.ExtendedFlag = rxMsg.ExtendedFlag;
			for (uint8_t i = 0; i < extTxMsg.DataLength; i++) {
				extTxMsg.Data.bytes[i] = rxMsg.Data.bytes[i];
			}
			Can_Send(&extTxMsg);

    		rxMsgFull = 0; //  
		}
	}
	
	return 0;
}
示例#5
0
/*-----------------------------------------------------------------------------
 * Main Program
 *---------------------------------------------------------------------------*/
int main(void) {
	Mcu_Init();
	Timebase_Init();
	sei();
#if defined(UART_OUTPUT)
	Serial_Init();

	printf("\n------------------------------------------------------------\n");
	printf(  "   CAN Test:\n");
	printf(  "   Periodic Transmission on CAN\n");
	printf(  "   CAN Dump\n");
	printf(  "   CAN Echo\n");
	printf(  "------------------------------------------------------------\n");
	
	printf("CanInit...");
	if (Can_Init() != CAN_OK) {
		printf("FAILED!\n");
		printf("Check wires between AVR and MCP2515 and the MCP speed (xtal).");
	}
	else {
		printf("OK!\n");
		printf("MCP2515 working fine\n");
	}
#elif defined(LED_OUTPUT)
	Can_Init();
#else
	Can_Init();
#endif
	
	uint32_t timeStamp = 0;
	
	Can_Message_t txMsg;
	Can_Message_t rxMsg;
	txMsg.RemoteFlag = 0;
	txMsg.ExtendedFlag = 1;
	txMsg.Id = SENDING_ID;
	txMsg.DataLength = 2;
	txMsg.Data.bytes[0] = 0x12;
	txMsg.Data.bytes[1] = 0x34;

	/* main loop */
	while (1) {
		/* service the CAN routines */
		Can_Service();
		
		/* send CAN message and check for CAN errors once every second */
		if (Timebase_PassedTimeMillis(timeStamp) >= 1000) {
			timeStamp = Timebase_CurrentTime();
			/* send txMsg */
			txMsg.Id = SENDING_ID;
			Can_Send(&txMsg);
		}
		
		/* check if any messages have been received */
		while (Can_Receive(&rxMsg) == CAN_OK) {
#if defined(UART_OUTPUT)
			/* Dump message data on uart */
			printf("\nPKT %#lx %u %u", rxMsg.Id, (uint16_t)(rxMsg.ExtendedFlag), (uint16_t)(rxMsg.RemoteFlag));
			for (uint8_t i=0; i<rxMsg.DataLength; i++) {
				printf(" %#x", rxMsg.Data.bytes[i]);
			}
#endif
			/* Echo function */
			if(rxMsg.Id == ECHO_RECEIVE_ID){
#if defined(UART_OUTPUT)
				printf("\n\"ping\" received");
				txMsg.Id = ECHO_SENDING_ID;
				/* Send reply */
				Can_Send(&txMsg);
				printf("\nreply sent");
#else
				txMsg.Id = ECHO_SENDING_ID;
				/* Send reply */
				Can_Send(&txMsg);
#endif
			}
		}
	}
	
	return 0;
}
示例#6
0
/*-----------------------------------------------------------------------------
 * Main Program
 *---------------------------------------------------------------------------*/
int main(void) {
//	For calibrating internal oscillator
//	OSCCAL = eeprom_read_byte(0);
	Timebase_Init();
	Serial_Init();

#if MCP_CS_BIT != PB2
	/* If slave select is not set as output it might change SPI hw to slave
	 * See ch 18.3.2 (18.3 SS Pin Functionality) in ATmega48/88/168-datasheet */
	DDRB |= (1<<PB2);
#endif
#if USE_STDCAN == 0
	Can_Init();
#else
	StdCan_Init(0);
#endif	
	
	DDRC |= 1<<PC1 | 1<<PC0;
	PORTC |= (1<<PC1) | (1<<PC0);
	
	sei();
	
#if SENDTIMESTAMP == 1
#if USE_STDCAN == 0
	Can_Message_t timeMsg;
#else
	StdCan_Msg_t timeMsg;
#endif	
	uint32_t time = Timebase_CurrentTime();
	uint32_t time1 = time;
	uint32_t unixtime = 0;
#endif
	uint16_t rxByte;
	uint8_t i = 0;
	
#if SENDTIMESTAMP == 1
#if USE_STDCAN == 0
	timeMsg.ExtendedFlag = 1;
	timeMsg.RemoteFlag = 0;
	timeMsg.DataLength = 8;
#else
	/* Jag orkar inte fixa in datan i paketen, sätter längd till 0 sålänge */
	timeMsg.Length = 0;
#endif
	timeMsg.Id = (CAN_NMT << CAN_SHIFT_CLASS) | (CAN_NMT_TIME << CAN_SHIFT_NMT_TYPE);
	//timeMsg.Id = 0; //Same thing, and lib's can.h is not updated.
#endif
	
#if USE_STDCAN == 1
	StdCan_Msg_t rxMsg;
#endif	
	
	/* main loop */
	while (1) {
		/* any new CAN messages received? */
#if USE_STDCAN == 0
		if (rxMsgFull) {
#else
		if (StdCan_Get(&rxMsg) == StdCan_Ret_OK) {
#endif
			// Toggle activity LED
			PORTC ^= (1<<PC1);
			/* send message to CanWatcher */
			uart_putc(UART_START_BYTE);
			uart_putc((uint8_t)rxMsg.Id);
			uart_putc((uint8_t)(rxMsg.Id>>8));
			uart_putc((uint8_t)(rxMsg.Id>>16));
			uart_putc((uint8_t)(rxMsg.Id>>24));
#if USE_STDCAN == 0
			uart_putc(rxMsg.ExtendedFlag);
			uart_putc(rxMsg.RemoteFlag);
			uart_putc(rxMsg.DataLength);
			for (i=0; i<8; i++) {
				uart_putc(rxMsg.Data.bytes[i]);
			}
#else
			uart_putc(1);
			uart_putc(0);
			uart_putc(rxMsg.Length);
			for (i=0; i<8; i++) {
				uart_putc(rxMsg.Data[i]);
			}
#endif
			uart_putc(UART_END_BYTE);
			
#if USE_STDCAN == 0
			rxMsgFull = 0;
#endif
		}
		
		/* any UART bytes received? */
		rxByte = uart_getc();
		while (rxByte != UART_NO_DATA) {
			/* parse byte! */
			UartParseByte((uint8_t)(rxByte & 0x00FF));
			/* receive next */
			rxByte = uart_getc();
		}
		
#if SENDTIMESTAMP == 1
		time1 = Timebase_CurrentTime();
		if ((time1 - time) > 1000) {
			time = time1;
#if USE_STDCAN == 0
			timeMsg.Data.dwords[0] = ++unixtime;
			IncTime();
			timeMsg.Data.dwords[1] = date.packed;
			Can_Send(&timeMsg);
#else
			/* Jag orkar inte fixa in datan i paketen, sätter längd till 0 sålänge */
			StdCan_Put(&timeMsg);
#endif
		}
#endif
	}
	
	return 0;
}
示例#7
0
/**
 * Parses an incoming UART byte by maintaining a state machine. The UART
 * bytes will build up a CAN message according to the protocol described here:
 * 
 * http://www.arune.se/projekt/doku.php?id=homeautomation:pc-mjukvara
 * 
 * @param c
 * 		The received UART byte.
 */
void UartParseByte(uint8_t c) {
#if USE_STDCAN == 0
	static Can_Message_t cm;
#else
	static StdCan_Msg_t cm;
#endif
	static uint8_t waitingMessage = 0;
	static uint32_t startTime = 0;
	static int8_t count = 0;
	
	/* 50ms timeout */
	if (waitingMessage && Timebase_PassedTimeMillis(startTime) > 50) {
		waitingMessage = 0;
	}
	
	if (waitingMessage) {
		/* save start time */
		startTime = Timebase_CurrentTime();
		/* UART END */
		if (count >= 15) {
			if (c == UART_END_BYTE) {
				PORTC ^= (1<<PC0);
#if USE_STDCAN == 0
				Can_Send(&cm);
#else
				StdCan_Put(&cm);
#endif
			}
			waitingMessage = 0;
			return;
		}
		/* data */
		else if (count >= 7) {
#if USE_STDCAN == 0
			cm.Data.bytes[count-7] = c;
#else
			cm.Data[count-7] = c;
#endif
			count++;
			return;
		}
		/* data length */
		else if (count >= 6) {
#if USE_STDCAN == 0
			cm.DataLength = c;
#else
			cm.Length = c;
#endif
			count++;
			return;
		}
		/* remote request flag */
		else if (count >= 5) {
#if USE_STDCAN == 0
			cm.RemoteFlag = c;
#endif
			count++;
			return;
		}
		/* extended */
		else if (count >= 4) {
#if USE_STDCAN == 0
			cm.ExtendedFlag = c;
#endif
			count++;
			return;
		}
		/* ident */
		else if (count >= 0) {
			cm.Id += ((uint32_t)c << (count*8));
			count++;
			return;
		}
	}
	
	if (c == UART_START_BYTE && !waitingMessage) {
		waitingMessage = 1;
		startTime = Timebase_CurrentTime();
		count = 0;
		cm.Id = 0;
		return;	
	}
}
示例#8
0
/*-----------------------------------------------------------------------------
 * Main Program
 *---------------------------------------------------------------------------*/
int main(void) {
	uint8_t nSensors, i;
	uint8_t subzero, cel, cel_frac_bits;
	
	Mcu_Init();
	Timebase_Init();
	Serial_Init();
	
	sei();
	
	printf( "\nDS18X20 1-Wire-Reader\n" );
	printf( "-----------------------" );
	nSensors = search_sensors();
	printf( "%i DS18X20 Sensor(s) available:\n", (int) nSensors );
	
	for (i=0; i<nSensors; i++) {
		printf("Sensor# %i is a ", (int) i+1);
		if ( gSensorIDs[i][0] == DS18S20_ID)
			printf("DS18S20/DS1820");
		else printf("DS18B20");
		printf(" which is ");
		if ( DS18X20_get_power_status( &gSensorIDs[i][0] ) ==
			DS18X20_POWER_PARASITE ) 
			printf( "parasite" );
		else printf( "externally" ); 
		printf( " powered\n" );
	}
	
	printf("CanInit...\n");
	if (Can_Init() != CAN_OK) {
		printf("FAILED!\n");
	}
	else {
		printf("OK!\n");
	}
	
	uint32_t timeStamp = 0;
	
	Can_Message_t txMsg;
	Can_Message_t rxMsg;
	
	txMsg.DataLength = 2;
	txMsg.Id = 0;
	txMsg.RemoteFlag = 0;
	txMsg.ExtendedFlag = 1;
	
	/* main loop */
	while (1) {
		/* service the CAN routines */
		Can_Service();

		/* check if any messages have been received */
		while (Can_Receive(&rxMsg) == CAN_OK) {
			
		}

		/* check temperature and send on CAN once every other second */
		if (Timebase_PassedTimeMillis(timeStamp) >= 2000) {
			timeStamp = Timebase_CurrentTime();
			
			if ( DS18X20_start_meas( DS18X20_POWER_PARASITE, NULL ) == DS18X20_OK) {
				printf("Measuring temperature... ");
				delay_ms(DS18B20_TCONV_12BIT);
				for ( i=0; i<nSensors; i++ ) {
					if ( DS18X20_read_meas( &gSensorIDs[i][0], &subzero,
							&cel, &cel_frac_bits) == DS18X20_OK ) {
						
						//txMsg.Data.bytes[0] = subzero;
						if (subzero) {
							txMsg.Data.bytes[i*2] = -cel;
							txMsg.Data.bytes[i*2+1] = ~(cel_frac_bits<<4);
						} else {
							txMsg.Data.bytes[i*2] = cel;
							txMsg.Data.bytes[i*2+1] = (cel_frac_bits<<4);
						}
						
					}
					else printf("CRC Error (lost connection?)\n");
				}
				
				txMsg.DataLength = nSensors*2;
				printf("sending...\n");
				/* send txMsg */
				Can_Send(&txMsg);
			}
			else printf("Start meas. failed (short circuit?)\n");

		}
	}
	
	return 0;
}