Changeset - 9aa54f04a19a
[Not reviewed]
default
0 2 0
kripperger@CL-SEC241-09.cedarville.edu - 12 years ago 2013-03-19 23:47:01
kripperger@CL-SEC241-09.cedarville.edu
Timeouts
2 files changed with 90 insertions and 19 deletions:
0 comments (0 inline, 0 general)
slave/slave/lib/i2c.c
Show inline comments
 
/*
 
 * i2c.c
 
 *
 
 * Created: 11/7/2012 7:18:23 PM
 
 *  Author: kripperger
 
 */ 
 
 
#include <inttypes.h>
 
#include <compat/twi.h>
 
#include "loopTimer.h"
 
#include "../config.h"
 
#include "i2c.h"
 
 
uint32_t startTime = 0;
 
 
/* I2C clock in Hz */
 
#define SCL_CLOCK  100000L
 
#define SCL_CLOCK  300000L
 
 
 
/*************************************************************************
 
 Initialization of the I2C bus interface. Need to be called only once
 
*************************************************************************/
 
void i2c_init(void)
 
{
 
  /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */
 
  /* initialize TWI clock: 300 kHz clock, TWPS = 0 => prescaler = 1 */
 
  
 
  TWSR = 0;                         /* no prescaler */
 
  TWBR = ((F_CPU/SCL_CLOCK)-16)/2;  /* must be > 10 for stable operation */
 
 
 
}/* i2c_init */
 
 
 
 
/*************************************************************************	
 
  Issues a start condition and sends address and transfer direction.
 
  return 0 = device accessible, 1= failed to access device
 
*************************************************************************/
 
unsigned char i2c_start(unsigned char address)
 
{
 
    uint8_t   twst;
 
 
	// send START condition
 
	TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
 
 
	// wait until transmission completed
 
	while(!(TWCR & (1<<TWINT)));
 
	startTime = time_millis();
 
	while(!(TWCR & (1<<TWINT)))
 
	{
 
		if ((time_millis() - startTime) > 10)
 
		{
 
			break;	// Timeout Reached!
 
		}
 
	}
 
 
	// check value of TWI Status Register. Mask prescaler bits.
 
	twst = TW_STATUS & 0xF8;
 
	if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
 
 
	// send device address
 
	TWDR = address;
 
	TWCR = (1<<TWINT) | (1<<TWEN);
 
 
	// wail until transmission completed and ACK/NACK has been received
 
	while(!(TWCR & (1<<TWINT)));
 
	startTime = time_millis();
 
	while(!(TWCR & (1<<TWINT)))
 
	{
 
		if ((time_millis() - startTime) > 10)
 
		{
 
			break;	// Timeout Reached!
 
		}
 
	}
 
 
	// check value of TWI Status Register. Mask prescaler bits.
 
	twst = TW_STATUS & 0xF8;
 
	if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
 
 
	return 0;
 
 
}/* i2c_start */
 
 
 
 
/*************************************************************************
 
@@ -72,46 +89,67 @@ unsigned char i2c_start(unsigned char ad
 
*************************************************************************/
 
void i2c_start_wait(unsigned char address)
 
{
 
    uint8_t   twst;
 
 
 
    while ( 1 )
 
    {
 
	    // send START condition
 
	    TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
 
    
 
    	// wait until transmission completed
 
    	while(!(TWCR & (1<<TWINT)));
 
		startTime = time_millis();
 
    	while(!(TWCR & (1<<TWINT)))
 
		{
 
			if ((time_millis() - startTime) > 10)
 
			{
 
				break;	// Timeout Reached!
 
			}
 
		}
 
    
 
    	// check value of TWI Status Register. Mask prescaler bits.
 
    	twst = TW_STATUS & 0xF8;
 
    	if ( (twst != TW_START) && (twst != TW_REP_START)) continue;
 
    
 
    	// send device address
 
    	TWDR = address;
 
    	TWCR = (1<<TWINT) | (1<<TWEN);
 
    
 
    	// wail until transmission completed
 
    	while(!(TWCR & (1<<TWINT)));
 
		startTime = time_millis();
 
    	while(!(TWCR & (1<<TWINT)))
 
		{
 
			if ((time_millis() - startTime) > 10)
 
			{
 
				break;	// Timeout Reached!
 
			}
 
		}
 
    
 
    	// check value of TWI Status Register. Mask prescaler bits.
 
    	twst = TW_STATUS & 0xF8;
 
    	if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) ) 
 
    	{    	    
 
    	    /* device busy, send stop condition to terminate write operation */
 
	        TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
 
	        
 
	        // wait until stop condition is executed and bus released
 
	        while(TWCR & (1<<TWSTO));
 
			startTime = time_millis();
 
	        while(TWCR & (1<<TWSTO))
 
			{
 
				if ((time_millis() - startTime) > 10)
 
				{
 
					break;	// Timeout Reached!
 
				}
 
			}
 
	        
 
    	    continue;
 
    	}
 
    	//if( twst != TW_MT_SLA_ACK) return 1;
 
    	break;
 
     }
 
 
}/* i2c_start_wait */
 
 
 
 
/*************************************************************************
 
@@ -130,82 +168,113 @@ unsigned char i2c_rep_start(unsigned cha
 
 
 
 
/*************************************************************************
 
 Terminates the data transfer and releases the I2C bus
 
*************************************************************************/
 
void i2c_stop(void)
 
{
 
    /* send stop condition */
 
	TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
 
	
 
	// wait until stop condition is executed and bus released
 
	while(TWCR & (1<<TWSTO));
 
	startTime = time_millis();
 
	while(TWCR & (1<<TWSTO))
 
	{
 
		if ((time_millis() - startTime) > 10)
 
		{
 
			break;	// Timeout Reached!
 
		}
 
	}
 
 
}/* i2c_stop */
 
 
 
 
/*************************************************************************
 
  Send one byte to I2C device
 
  
 
  Input:    byte to be transfered
 
  Return:   0 write successful 
 
            1 write failed
 
*************************************************************************/
 
unsigned char i2c_writeX( unsigned char data )
 
{	
 
    uint8_t   twst;
 
    
 
	// send data to the previously addressed device
 
	TWDR = data;
 
	TWCR = (1<<TWINT) | (1<<TWEN);
 
 
	// wait until transmission completed
 
	while(!(TWCR & (1<<TWINT)));
 
	startTime = time_millis();
 
	while(!(TWCR & (1<<TWINT)))
 
	{
 
		if ((time_millis() - startTime) > 10)
 
		{
 
			break;	// Timeout Reached!
 
		}
 
	}
 
	
 
 
	// check value of TWI Status Register. Mask prescaler bits
 
	twst = TW_STATUS & 0xF8;
 
	if( twst != TW_MT_DATA_ACK) return 1;
 
	return 0;
 
 
}/* i2c_write */
 
 
 
 
/*************************************************************************
 
 Read one byte from the I2C device, request more data from device 
 
 
 
 Return:  byte read from I2C device
 
*************************************************************************/
 
unsigned char i2c_readAck(void)
 
{
 
	TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
 
	while(!(TWCR & (1<<TWINT)));    
 
	
 
	startTime = time_millis();
 
	while(!(TWCR & (1<<TWINT)))
 
	{
 
		if ((time_millis() - startTime) > 10)
 
		{
 
			break;	// Timeout Reached!
 
		}
 
	}  
 
 
    return TWDR;
 
 
}/* i2c_readAck */
 
 
 
 
/*************************************************************************
 
 Read one byte from the I2C device, read is followed by a stop condition 
 
 
 
 Return:  byte read from I2C device
 
*************************************************************************/
 
unsigned char i2c_readNak(void)
 
{
 
	TWCR = (1<<TWINT) | (1<<TWEN);
 
	while(!(TWCR & (1<<TWINT)));
 
	
 
	startTime = time_millis();
 
	while(!(TWCR & (1<<TWINT)))
 
	{
 
		if ((time_millis() - startTime) > 10)
 
		{
 
			break;	// Timeout Reached!
 
		}
 
	}
 
	
 
    return TWDR;
 
 
}/* i2c_readNak */
 
 
 
 
/*************************************************************************
 
 Write one byte to the I2C device, read is followed by a stop condition 
 
 
 
 Return:  void
 
*************************************************************************/
slave/slave/slave.c
Show inline comments
 
@@ -32,57 +32,54 @@
 
#include "lib/geiger.h"
 
#include "lib/sensors.h"
 
#include "lib/cameras.h"
 
#include "lib/loopTimer.h"
 
#include "lib/masterComm.h"
 
#include "lib/watchdog.h"
 

	
 
bool WDTreset = false;
 

	
 
void micro_setup()
 
{
 
	// Generic microcontroller config options
 
	sei();			// Enable interrupts
 
	WDTreset = ((MCUSR & 0b00001000) > 0);	// Set variable if WDT reset occured
 
	WDTreset = ((MCUSR & 0b00001000) > 0);	// Check if WDT reset occured
 
	MCUSR = 0;		// Clear reset flags
 
	wdt_disable();	// Disable WDT
 
	_delay_ms(20);	// Power debounce
 
	sei();			// Enable interrupts
 
}
 

	
 

	
 

	
 
int main(void)
 
{
 
	// Writes ID to EEPROM, change for all modules and delete after programming
 
	// 0 is for generic setup,	 1 is for sensors,	 2 is for Geiger,	3 is for cameras
 
	//i2c_write(EEPROM_ADDR, 0x05, 0x03);
 

	
 
		
 
	// Initialize	
 
	micro_setup();			// Generic microcontroller config options
 
	time_setup();			// Setup loop timer and interrupts (TIMER0)
 
	watchdog_setup();		// Setup watchdog timer
 
	led_configure();		// Configure ports and registers for LED operation
 
	io_configure();			// Configure IO ports and registers
 
	i2c_init();				// Setup I2C
 
	serial0_setup();		// Config serial port 0
 
	serial1_setup();		// Config serial port 1
 
	
 
	_delay_ms(50);	// Setup hold delay
 
	if(WDTreset) led_on(1);	// Turn on LED if WDT reset has occurred	
 
	
 
	io_readModuleId();
 
	modules_setup(io_getModuleId());	// Run setup functions for specific module
 

	
 
	uint32_t lastLoop = 0;
 
	
 
	if(WDTreset) led_on(1);	// Turn on LED if WDT reset has occured
 
	uint32_t lastLoop = 0;	// Time in ms when last loop occurred 
 
	
 
	// Serial output //DEBUG
 
	char buff[128];						//Buffer for serial output //DEBUG
 
	serial1_sendString("Starting Slave\r\n");	//DEBUG
 
			
 
    while(1)
 
    {	
 
		wdt_reset();	// Resets WDT (to prevent restart)
 
		
 
		// Master communication
 
		masterComm_checkParser();	//Checks parser for data requests from master
 

	
 
@@ -92,24 +89,29 @@ int main(void)
 
			led_on(0);
 
			sensors_readBatt();				// Read Battery level
 
			sensors_readBoardTemp();		// Read board temperature sensor (Common on all slaves) (Data Read)
 
			modules_run(io_getModuleId());	// Runs specific module functions (like data reading)
 
			
 
			io_regulateTemp();			// Gets board temperature and enables heater if below threshold
 

	
 
			snprintf(buff,128,"|ModuleID: %u |BoardTemp: %i |Millis: %lu |Lux: %lu |Pressure: %lu |Altitude: %lu |Battery: %u \r\n ",io_getModuleId(),sensors_getBoardTemp(),time_millis(),sensors_getLux(),sensors_getPressure(),sensors_getAltitude(),sensors_getBatt()); //DEBUG
 
			serial1_sendString(buff); //DEBUG
 
			
 
			led_off(0);
 
			lastLoop = time_millis();
 
			
 
// Writes ID to EEPROM, change for all modules and delete after programming
 
// 0 is for generic setup,	 1 is for sensors,	 2 is for Geiger,	3 is for cameras
 
//i2c_write(EEPROM_ADDR, 0x05, 0x03);			
 
			
 
		}
 

	
 
    }
 
	
 
	return 0;
 
}
 

	
 

	
 

	
 

	
 

	
 
		/********Examples of data reading and getting******************
0 comments (0 inline, 0 general)