示例#1
0
void system_config_init(void)
{
	struct nvm_device_serial	device_serial;
	nvm_read_device_serial(&device_serial);

	for(uint8_t x = 0; x < sizeof(device_serial); x++)
		sprintf((char *) serial_number + (2 * x), "%02X", device_serial.byte[x]);

	nvm_eeprom_read_buffer((eeprom_addr_t) &EEPROM_PDICLOCK, &(systemconfig.pdiclock), sizeof(EEPROM_PDICLOCK));
	nvm_eeprom_read_buffer((eeprom_addr_t) &EEPROM_TPICLOCK, &(systemconfig.tpiclock), sizeof(EEPROM_TPICLOCK));
	nvm_eeprom_read_buffer((eeprom_addr_t) &EEPROM_VERSION, &(systemconfig.version), sizeof(EEPROM_VERSION));
	nvm_eeprom_read_buffer((eeprom_addr_t) &EEPROM_DRIVER, &(systemconfig.driver), sizeof(EEPROM_DRIVER));
	
	system_config_check();
}
示例#2
0
/**
 * \brief Test device serial number readout
 *
 * This test reads out the \e LOTNUMn, \e WAFNUM, \e COORDXn and \e COORDYn
 * values from the device signature row and checks that they are not all 0xFF.
 *
 * \param test Current test case.
 */
static void run_device_serial_test(const struct test_case *test)
{
	struct nvm_device_serial dev_sn;
	bool serial_is_set;
	uint8_t byte_index;

	nvm_read_device_serial(&dev_sn);

	serial_is_set = false;
	for (byte_index = 0; byte_index < sizeof(dev_sn.byte); byte_index++) {
		if (dev_sn.byte[byte_index] != 0xff) {
			serial_is_set = true;
			break;
		}
	}
	test_assert_true(test, serial_is_set, "Read device serial as all 0xFF");
}
int main(void)
{
	// Configure CPU and peripherals clock
	xmega_set_cpu_clock_to_32MHz();
	
	// Enable interrupts
	PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;
	
	// Power management - configure sleep mode to IDLE
	set_sleep_mode(SLEEP_SMODE_IDLE_gc);
	// Enable sleep mode
	sleep_enable();

#ifdef MMSN_DEBUG	
	// Initialize serial communication terminal
	//usartCommTerminalInit();
	
	// Configure and initialize communication bus usart
	xmega_usart_configure();
	
	/* RS-485 PHYSICAL DEVICE CONFIGURATION */
	// Initialize GPIO related to RS-485 interface
	rs485_driver_gpio_initialize();
	// Initially go LOW to enable receiver and start listening
	rs485_driver_enable();
	
	/* USART INTERRUPTS CONFIGURATION - RECEIVING */
	// Turn on USART RXC interrupt
	xmega_set_usart_rx_interrupt_level(&USART_COMMUNICATION_BUS, USART_RXCINTLVL_HI_gc);
	
	// Turn off TXC and DRE interrupts
	xmega_set_usart_tx_interrupt_level(&USART_COMMUNICATION_BUS, USART_TXCINTLVL_OFF_gc);
	xmega_set_usart_dre_interrupt_level(&USART_COMMUNICATION_BUS, USART_DREINTLVL_OFF_gc);
	
	// Redirect stream to standard output
	stdout = &mystdout;
	
	/* Print out welcome message */
	//static const char WelcomeMessage[] PROGMEM = "Multi-Master Serial Network Manager ver 1.0";
	//printf("%S\n", WelcomeMessage);
	printf_P(PSTR("\nMulti-Master Serial Network Manager ver 1.0\n"));
	//printf("Multi-Master Serial Network Manager ver 1.0\n");
#endif
	
	// Calculate CRC-16 value based on the random Internal SRAM memory content.
	// Move by 0x400 from the beginning to omit memory area related to global variables section.
	// Take 20 consecutive SRAM bytes for CRC-16 calculation.
	uint16_t u16RandomValue = xmega_calculate_checksum_crc16((uint8_t *)(INTERNAL_SRAM_START + 1200), 20);
	// Pseudo-random number generator seeding with previously obtain value
	srand(u16RandomValue);
	
#ifdef MMSN_DEBUG
	printf("rnd = %u\n", u16RandomValue);
#endif	
	
	// Read XMEGA device serial number
	nvm_read_device_serial(&xmegaSerialNumber);

	// Read configuration data from EEPROM
	xmega_read_configuration_data();

	// Check if logical address was already assigned
	if (true == _isLogicalNetworkAddrAssigned(&ConfigurationData.u8LogicalNetworkAddr))
	{
		// Logical Network Address was already assigned.
		g_DeviceConfigStatus = eLogicalAddrAssigned;
		
		// Calculate Collision Avoidance (back-off/busy line) timer period value.
		g_u16CollisionAvoidancePeriod = (ConfigurationData.u8LogicalNetworkAddr * TIMER_COLLISION_AVOIDANCE_520us_VALUE) +
									   TIMER_COLLISION_AVOIDANCE_32us_VALUE;
#ifdef MMSN_DEBUG
		printf("LNA_CA = %d\n", g_u16CollisionAvoidancePeriod);
#endif
	}
	else
	{
		// Logical Network Address was NOT assigned.
		g_DeviceConfigStatus = eLogicalAddrNotAssigned;
		
		// Calculate Collision Avoidance (back-off/busy line) timer period using random value.
		g_u16CollisionAvoidancePeriod = (xmega_generate_random_logical_network_address() * TIMER_COLLISION_AVOIDANCE_520us_VALUE) +
		TIMER_COLLISION_AVOIDANCE_32us_VALUE;

#ifdef MMSN_DEBUG
		printf("RND_CA = %d\n", g_u16CollisionAvoidancePeriod);
#endif		
	}
	
	/************************************************************************/
	/* TIMERS CONFIGURATION                                                 */
	/************************************************************************/
	
	// No response timer - configure but do not run
	xmega_timer_config(&TIMER_NO_RESPONSE, TC_CLKSEL_OFF_gc, TIMER_NO_RESPONSE_PERIOD);
	
	// Collision Avoidance timer - configure but do not run
	xmega_timer_config(&TIMER_COLLISION_AVOIDANCE, TC_CLKSEL_OFF_gc, g_u16CollisionAvoidancePeriod);
	
	// Heartbeat timer - configure but do not run
	xmega_timer_config(&TIMER_HEARTBEAT, TC_CLKSEL_OFF_gc, TIMER_HEARTBEAT_PERIOD);
	
	// Force the state of the SREG register on exit, disabling the Global Interrupt Status flag bit.
	/* ATOMIC_BLOCK(NONATOMIC_FORCEOFF)
	{
		// Clear busy line timeout event
		FLAG_CLEAR(gSystemEvents, EVENT_IRQ_COLLISION_AVOIDANCE_TIMEOUT_bm);
	}
	
	// Turn busy line timer off
	xmega_tc_select_clock_source(&TIMER_COLLISION_AVOIDANCE, TC_CLKSEL_OFF_gc); */
	
	/* Initialize event queue */
	fifo_init(&eventQueue_desc, &EventQueue[0], EVENT_FIFO_BUFFER_SIZE);
	
	/************************************************************************/
	/* Initialize Multi-Master Serial Network State Machine                 */
	/************************************************************************/
	// SM_stateTable[eSM_Initialize]();
	//mmsn_InitializeStateMachine(&mmsnFSM);
	
	// Initialize global storage for data sending
	_sendData_FrameBuffer_Init(&gStorage_SendData);
	
	// Start heartbeat timer
	xmega_tc_select_clock_source(&TIMER_HEARTBEAT, TC_CLKSEL_DIV64_gc);
	
	xmega_set_usart_rx_interrupt_level(&USART_COMMUNICATION_BUS, USART_RXCINTLVL_HI_gc);
	
	// Turn on global interrupts
	sei();
	
	/************************************************************************/
	/* Start infinite main loop, go to sleep and wait for interruption      */
	/************************************************************************/
	for(;;)
    {
		// Force the state of the SREG register on exit, enabling the Global Interrupt Status flag bit.
        ATOMIC_BLOCK(ATOMIC_FORCEON)
		{
			// Atomic interrupt safe read of global variable storing event flags
			u16EventFlags = gSystemEvents;
		};
		
        while (u16EventFlags)
        {
	        // Note: Each handler will clear the relevant bit in global variable gSystemEvents
			// Corresponding event flag will be cleared in FSM handler		

			// Heartbeat timer interrupt fired up
			if (u16EventFlags & SYSEV_HEARTBEAT_TIMEOUT_bm)
			{
				if (gHeartBeatCounter > 5000)
				{
					// create a message
					gStorage_SendData.u8DataSize = 7;
					gStorage_SendData.u8IsResponseNeeded = true;
					gStorage_SendData.u8SendDataBuffer[0] = 1;
					gStorage_SendData.u8SendDataBuffer[1] = 3;
					gStorage_SendData.u8SendDataBuffer[2] = 5;
					gStorage_SendData.u8SendDataBuffer[3] = 7;
					gStorage_SendData.u8SendDataBuffer[4] = 9;
					gStorage_SendData.u8SendDataBuffer[5] = 11;
					gStorage_SendData.u8SendDataBuffer[6] = 33;
					
					// add event to queue
					ADD_EVENT_TO_QUEUE(&eventQueue_desc, MMSN_SEND_DATA_EVENT);
					
					// reset counter
					gHeartBeatCounter = 0;
					
					// Stop heartbeat timer
					xmega_tc_select_clock_source(&TIMER_HEARTBEAT, TC_CLKSEL_OFF_gc);
				}
				
				sys_HeartbeatTimeout_Handler();
			};
			
			// Collision Avoidance timer interrupt fired up
			if (u16EventFlags & SYSEV_COLLISION_AVOIDANCE_TIMEOUT_bm)
			{
				sysev_CollisionAvoidanceTimeout_Handler();
			};
			
			// No response timer interrupt fired up
			if (u16EventFlags & SYSEV_NO_RESPONSE_TIMEOUT_bm)
			{
				sysev_NoResponseTimeout_Handler();
			};
			
			// Receive Complete (RXC) interrupt fired up
			if (u16EventFlags & SYSEV_RECEIVE_COMPLETE_bm)
			{
				sysev_ReceiveComplete_Handler();
			};
			
			// Data Register Empty (DRE) interrupt fired up
			if (u16EventFlags & SYSEV_DATA_REGISTER_EMPTY_bm)
			{
				sysev_DataRegisterEmpty_Handler();
			};
			
			// Transmit Complete (TXC) interrupt fired up
			if (u16EventFlags & SYSEV_TRANSMIT_COMPLETE_bm)
			{
				sysev_TransmitComplete_Handler();
			};
			
			// Dispatch events from the MMSN FSM queue
			while(!fifo_is_empty(&eventQueue_desc))
			{
				// Get event from the queue
				uint8_t currEvent = fifo_pull_uint8_nocheck(&eventQueue_desc);
				
				// Call corresponding FSM event handler
				if (mmsnFSMActionTable[mmsnFSM.CurrentState][currEvent])
				{
					mmsnFSMActionTable[mmsnFSM.CurrentState][currEvent](&mmsnFSM, currEvent, &g_u8GlobalArgument);
				}
			};
			
			// Read the system event flag again after handlers return
			ATOMIC_BLOCK(ATOMIC_FORCEON)
			{
				// Atomic interrupt safe read of global variable storing event flags
				u16EventFlags = gSystemEvents;
			}
        }	// while(...)
        
        // Read the event register again without allowing any new interrupts
		cli();
		
        if (0 == gSystemEvents)
        {
			sei();
			
	        // Go to sleep, everything is handled by interrupts.
	        // An interrupt will cause a wake up and run the while loop
	        sleep_cpu();
        };
        
		// Set Global Interrupt Status flag
        sei();
    };
};