Example #1
0
int main(void) {
	init();
	_delay_ms(100);

	DDRD  |= (1 << PIN7);
	PORTD |= (1 << PIN7);

	// enable TWI
	TWI_Start_Transceiver();
	pwm_enable();

	uint8_t _cache = 0;
	while(1) {
		if(!TWI_Transceiver_Busy()) {
			if(TWI_statusReg.RxDataInBuf){
				TWI_Get_Data_From_Transceiver(message_buff, 1);
				switch(message_buff[0] & MOTORPROTO_HEAD_GET) {
					case MOTORPROTO_INSTR_READ:
						ATOMIC_BLOCK(ATOMIC_FORCEON) {
							data.value =  enc.counter_b;
							message_buff[0] = data.byte[0];
							message_buff[1] = data.byte[1];
							message_buff[2] = data.byte[2];
							message_buff[3] = data.byte[3];
						}
						TWI_Start_Transceiver_With_Data(message_buff, 4);
						message_buff[0] = 0;
						break;
					case MOTORPROTO_INSTR_RESET:
						ATOMIC_BLOCK(ATOMIC_FORCEON) {
							enc.counter_a = 0;
							enc.counter_b = 0;
							message_buff[0] = 0;
						}
						break;
					case MOTORPROTO_INSTR_SET_FORWARD:
						TWI_Get_Data_From_Transceiver(message_buff, 2);
						_cache = message_buff[1];
						pwm_set1a(_cache);
						pwm_set1b(0);
						message_buff[0] = 0;
						break;
					case MOTORPROTO_INSTR_SET_BACKWARD:
						TWI_Get_Data_From_Transceiver(message_buff, 2);
						_cache = message_buff[1];
						pwm_set1a(0);
						pwm_set1b(_cache);
						message_buff[0] = 0;
						break;
					default:
						break;
				}
			}
		}
	}
Example #2
0
void TaskGridEYE () {
  while (1) {
    pixel_addr_l=0x80;
    pixel_addr_h=0x81;

    int row, col;
    for (row = 0; row < 8; row++) {
      for (col = 0; col < 8; col++) {
        /* Request low byte */
        messageBuf[0] = (grideye_addr<<TWI_ADR_BITS) |
          (FALSE<<TWI_READ_BIT);
        messageBuf[1] = pixel_addr_l;
        TWI_Start_Transceiver_With_Data(messageBuf, 2);

        /* Read low byte */
        messageBuf[0] = (grideye_addr<<TWI_ADR_BITS) |
          (TRUE<<TWI_READ_BIT);
        TWI_Start_Transceiver_With_Data(messageBuf, 2);
        TWI_Get_Data_From_Transceiver(messageBuf, 2);
        uint16_t pixel_l = messageBuf[1];

        /* Request high byte */
        messageBuf[0] = (grideye_addr<<TWI_ADR_BITS) |
          (FALSE<<TWI_READ_BIT);
        messageBuf[1] = pixel_addr_h;
        TWI_Start_Transceiver_With_Data(messageBuf, 2);

        /* Read high byte */
        messageBuf[0] = (grideye_addr<<TWI_ADR_BITS) |
          (TRUE<<TWI_READ_BIT);
        TWI_Start_Transceiver_With_Data(messageBuf, 2);
        TWI_Get_Data_From_Transceiver(messageBuf, 2);
        uint16_t pixel_h = messageBuf[1];

        /* Store pixel and advance */
        raw_therm[row][col] = (pixel_h << 8) | pixel_l;
        pixel_addr_l += 2;
        pixel_addr_h += 2;
      }
      int n = sprintf(printbuf, "$GRIDEYE,%d,%04X,%04X,%04X,%04X,%04X,%04X,%04X,%04X*",
          row,
          raw_therm[row][0], raw_therm[row][1],
          raw_therm[row][2], raw_therm[row][3],
          raw_therm[row][4], raw_therm[row][5],
          raw_therm[row][6], raw_therm[row][7]);
      uint8_t i;
      uint8_t checksum = 0;
      for (i = 1; i < n - 1; i++) checksum ^= printbuf[i];
      printf("%s%02X\r\n", printbuf, checksum);
    }
    nrk_wait_until_next_period();
  }
}
Example #3
0
char SE95_check_i2c_state_machine(void){

	switch(SE95_state){
		case 0:	if(SE95_cmd==SE95_get_temp){
					se95_messageBuf[0]=(0x48<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT);
					se95_messageBuf[1]=0x00;//setup reading from register 00 means temperature
					TWI_Start_Transceiver_With_Data( &se95_messageBuf[0], 2 );
					SE95_state=20;
				}
				break;
		case 20:if(!(TWI_Transceiver_Busy() )){
					if ( TWI_statusReg.lastTransOK ){
						se95_messageBuf[0]=(0x48<<TWI_ADR_BITS) | (TRUE<<TWI_READ_BIT);
						TWI_Start_Transceiver_With_Data( &se95_messageBuf[0], 3);
						SE95_state++;
					}else{
						SE95_cmd+=SE95_error;
						SE95_state=0;
					}
				}
				break;
		case 21:if(!(TWI_Transceiver_Busy() )){
					if ( TWI_statusReg.lastTransOK ){
						TWI_Get_Data_From_Transceiver( &se95_messageBuf[0], 3 );
						cli();
						SE95_temp=((se95_messageBuf[1]<<8)|se95_messageBuf[2])>>3;
						SE95_temp_frac=(SE95_temp)&0x1F;
						SE95_temp>>=5;//reduce to 1 centigrade resolution
						sei();
					}
					SE95_cmd+=SE95_done;
					SE95_state=0;
				}
				break;
	}
Example #4
0
/* prints out data received from the adxl345 */
void Task_Accelorometer()
{
  while(1){
    messageBuf[0] = (ADXL345_ADDRESS) | (FALSE<<TWI_READ_BIT);
    messageBuf[1] = ADXL345_REGISTER_XLSB;
    TWI_Start_Transceiver_With_Data(messageBuf, 2);

    /* Read 7 bytes from the data registers, starting with the LSB of X */
    messageBuf[0] = (ADXL345_ADDRESS) | (TRUE<<TWI_READ_BIT);
    /* set the rest of the messagebuf to 0, probably not necessary */
    messageBuf[1] = 0;
    messageBuf[2] = 0;
    messageBuf[3] = 0;
    messageBuf[4] = 0;
    messageBuf[5] = 0;
    messageBuf[6] = 0; 
    TWI_Start_Transceiver_With_Data(messageBuf, 7);
    /* if successful, print data received */
    /* data comes in like so: x1, x0, y1, y0, z1, z0, sign extended format */
    /* the 0th byte of every axis represents its sign */
    if (TWI_Get_Data_From_Transceiver(messageBuf, 7)){ 
      printf("ADXL: x0:%x x1:%x y0:%x y1:%x z0:%x z1:%x \r\n",messageBuf[2],messageBuf[1],messageBuf[4],messageBuf[3],messageBuf[6],messageBuf[5]);
    }
    nrk_wait_until_next_period();
  }
}
uchar sensor_read_identification_string(uchar *s) {  // {{{
	// Reads the 3 identification registers from the sensor.
	// They should read as ASCII "H43".
	//
	// Receives a pointer to a string with at least 4 chars of size.
	// After reading the registers, stores them at *s, followed by '\0'.
	// In case of a transmission error, the *s is not touched.
	//
	// This function is non-blocking.

	// 1 address byte + 3 chars
	uchar msg[4];

	uchar lastTransOK;

	switch(sensor.func_step) {
		case 0:  // Set address pointer
			if (TWI_Transceiver_Busy()) return SENSOR_FUNC_STILL_WORKING;

			sensor_set_address_pointer(SENSOR_REG_ID_A);
			sensor.func_step = 1;
		case 1:  // Start reading operation
			if (TWI_Transceiver_Busy()) return SENSOR_FUNC_STILL_WORKING;

			msg[0] = SENSOR_I2C_READ_ADDRESS;
			TWI_Start_Transceiver_With_Data(msg, 4);

			sensor.func_step = 2;
		case 2:  // Finished reading operation
			if (TWI_Transceiver_Busy()) return SENSOR_FUNC_STILL_WORKING;

			lastTransOK = TWI_Get_Data_From_Transceiver(msg, 4);
			sensor.func_step = 0;

			if (lastTransOK) {
				s[0] = msg[1];
				s[1] = msg[2];
				s[2] = msg[3];
				s[3] = '\0';
				sensor.error_while_reading = 0;
				return SENSOR_FUNC_DONE;
			} else {
				sensor.error_while_reading = 1;
				return SENSOR_FUNC_ERROR;
			}
		default:
			sensor.error_while_reading = 1;
			return SENSOR_FUNC_ERROR;
	}
}  // }}}
Example #6
0
int main()
{
  uint8_t messageBuf[TWI_BUFFER_SIZE];
  
  InitPWM();

  TWI_Slave_Initialise((PWM_ADDRESS << TWI_ADR_BITS) | (0 << TWI_GEN_BIT));
  TWI_Start_Transceiver();
  sei(); // enable interrupts
  
  while(1) {
    TWI_Get_Data_From_Transceiver(messageBuf, 1);
    SetPWM(messageBuf[0]);
    TWI_Start_Transceiver();
  }
}
Example #7
0
void process_command(void)
{
    if ( ! TWI_Transceiver_Busy() )
    {
        if ( TWI_statusReg.RxDataInBuf )
        {
            TWI_Get_Data_From_Transceiver(messageBuf, 1);
            switch (messageBuf[0])
            { 
            case M_BLUE_TOGGLE:
                m_blue(TOGGLE);
                unsigned char twi_data_1[7];
                twi_data_1[0]=M_BLUE_TOGGLE;
                twi_data_1[1]=5;
                twi_data_1[2]=1;
                twi_data_1[3]=2;
                twi_data_1[4]=3;
                twi_data_1[5]=4;
                twi_data_1[6]=5;
                TWI_Start_Transceiver_With_Data(twi_data_1, 7);
                break;
            
            case SEND_ADC_DATA:
                m_green(TOGGLE);
                unsigned char twi_data_2[7];
                twi_data_2[0]=SEND_ADC_DATA;
                twi_data_2[1]=5;
                twi_data_2[2]=(adc_value & 0x00FF);
                twi_data_2[3]=((adc_value & 0xFF00)>>8);
                twi_data_2[4]=(adc_value & 0x00FF);
                twi_data_2[5]=((adc_value & 0xFF00)>>8);
                twi_data_2[6]=0xAA;
                TWI_Start_Transceiver_With_Data(twi_data_2, 7);
                break;
            
            case M_GREEN_ON:
                m_green(ON);
                break;
				
            case M_BLUE_ON:
                m_blue(ON);
                break;
            }
        }
    }
Example #8
0
//Read Register Method
unsigned char rdOV7670Reg(unsigned char regID, unsigned char *regDat)
{
	/*	I2C Traffic Generated:
	 *	S	|	OV_ADDR + W	| A | RegID | A | P |
	 *	S	|	OV_ADDR + R | A | Data	|~A | P |
	 */
	//I2C Interface
	unsigned char messageBuf[TWI_BUFFER_SIZE]; //Initialise a buffer
	messageBuf[0] = (OV7670_ADDR<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); // The first byte must always consist of General Call code or the TWI slave address.
	messageBuf[1] = regID;             // The first byte is used for Address Pointer.
	TWI_Start_Transceiver_With_Data( messageBuf, 2 );
	
	// Request/collect the data from the Slave
	messageBuf[0] = (OV7670_ADDR<<TWI_ADR_BITS) | (TRUE<<TWI_READ_BIT); // The first byte must always consist of General Call code or the TWI slave address.
	TWI_Start_Transceiver_With_Data( messageBuf, 2 );              
    
	// Get the received data from the transceiver buffer
	TWI_Get_Data_From_Transceiver( messageBuf, 2 );
	*regDat = messageBuf[1];       
	return TWI_statusReg.lastTransOK;
}
Example #9
0
/* NOTE: multi-byte reads (using hw auto-incrementing of
 * register address) is not supported by this function
 * deliberately: it does not work -- only one byte is
 * returned. An additional issue is that an extra '0x3d'
 * (read command) byte is returned ('echoed') before
 * the actual reply byte -- we work around this here. */
int8_t twi_read(uint8_t addr, uint8_t reg, uint8_t *val)
{
    int8_t rc;
    uint8_t len = 0;
    uint8_t val_buf[2] = {0}; /* workaround for garbage byte */

    ASSERT(val);

    rc = twi_point(addr, reg);
    if (rc != NRK_OK) {
        LOG("ERROR: failed to set read ptr\r\n");
        return rc;
    }

    msg_buf[len++] = (addr << TWI_ADR_BITS) | (1 << TWI_READ_BIT);

    /* The example in the datasheet (and in sparkfun) sends the
     * count after the read req, but this seems non-standard. It
     * does not seem to make any difference. The auto-incremented
     * reads do not work in either case. */
    /* msg_buf[len++] = count; */

    rc = twi_tx(msg_buf, len);
    if (rc != NRK_OK) {
        LOG("ERROR: read req failed\r\n");
        return rc;
    }

    /* We want only one byte, but an extra byte is returned, hence len = 2 */
    rc = TWI_Get_Data_From_Transceiver( val_buf , 2 );
    if (!rc) {
        LOG("ERROR: failed to read data\r\n");
        return NRK_ERROR;
    }

    *val = val_buf[1];
    LOG("read: "); LOGP("0x%x \r\n", *val);

    return NRK_OK;
}
Example #10
0
void Task_Gyro()
{
  while(1){
    messageBuf[0] = (ITG3200_ADDRESS) | (FALSE<<TWI_READ_BIT);
    messageBuf[1] = ITG3200_REGISTER_XMSB;
    TWI_Start_Transceiver_With_Data(messageBuf, 2);

    /* Read first byte */
    messageBuf[0] = (ITG3200_ADDRESS) | (TRUE<<TWI_READ_BIT);
    messageBuf[1] = 0;
    messageBuf[2] = 0;
    messageBuf[3] = 0;
    messageBuf[4] = 0;
    messageBuf[5] = 0;
    messageBuf[6] = 0; 
    TWI_Start_Transceiver_With_Data(messageBuf, 7);
    if (TWI_Get_Data_From_Transceiver(messageBuf, 7)){
      printf("ITG: %x %x %x %x %x %x \r\n",messageBuf[1],messageBuf[2],messageBuf[3],messageBuf[4],messageBuf[5],messageBuf[6]);
    }
    nrk_wait_until_next_period();
  }
}
Example #11
0
// Read measurements of IMU Through TWI
void TWI_Read(unsigned char reg, int *result, unsigned char size){
	
	unsigned char messageBuf[8] = {0};					// Buffer for TX through TWI
	
	messageBuf[0] = MPU6050_DEFAULT_ADDRESS;			// TWI slave address (IMU) + Write.
	messageBuf[1] = reg;								// Registry Address to write.
	TWI_Start_Transceiver_With_Data(messageBuf, 2);		// TX Reg to Write IMU
	while (TWI_Transceiver_Busy());						// Wait until TWI is ready for next transmission.
	if (TWI_statusReg.lastTransOK){						// Check if the last operation was successful
		// Request/collect the data from the Slave
		messageBuf[0] = (MPU6050_DEFAULT_ADDRESS | 0x01);			// TWI slave address (IMU) + Read.
		TWI_Start_Transceiver_With_Data(messageBuf, size + 1);
	} else return;													// Out of function
	while (TWI_Transceiver_Busy());									// Wait until TWI is ready for next transmission.
	if (TWI_statusReg.lastTransOK){									// Check if the last operation was successful
		TWI_Get_Data_From_Transceiver(messageBuf, size + 1);
		if (size > 1){		
			for (int i = 0; i < (size / 2); i++)						// Get reads 16 bit on array result
			{
				result[i] = (((int)messageBuf[i * 2]) << 8) | (int)messageBuf[(i * 2) + 1];
			}
		} else result[0] = messageBuf[0];
	} else return; 										// Out of function
}
Example #12
0
void main( void )
{
  unsigned char messageBuf[TWI_BUFFER_SIZE];
  unsigned char TWI_slaveAddress;
  
  // Feedback (opcional)
  /* DDRB  = 0xFF; // Set to output
     PORTB = 0x55; // Startup pattern */
  // Le os pinos 0-2 para endereçamento
  DDRC  = ~((1 << 0) | (1 << 1) | (1 << 2)); //Bits 0-2 como entrada
  
  // Own TWI slave address
  TWI_slaveAddress = 0x10 + 0b00000111 & PORTD;

  // Initialise TWI module for slave operation. Include address and/or enable General Call.
  TWI_Slave_Initialise( (unsigned char)((TWI_slaveAddress<<TWI_ADR_BITS) | (TRUE<<TWI_GEN_BIT) )); 
                       
  __enable_interrupt();

  // Start the TWI transceiver to enable reseption of the first command from the TWI Master.
  TWI_Start_Transceiver();

  // This example is made to work together with the AVR315 TWI Master application note. In adition to connecting the TWI
  // pins, also connect PORTB to the LEDS. The code reads a message as a TWI slave and acts according to if it is a 
  // general call, or an address call. If it is an address call, then the first byte is considered a command byte and
  // it then responds differently according to the commands.

  // This loop runs forever. If the TWI is busy the execution will just continue doing other operations.
  for(;;)
  {    
    
    // Check if the TWI Transceiver has completed an operation.
    if ( ! TWI_Transceiver_Busy() )                              
    {
      // Check if the last operation was successful
      if ( TWI_statusReg.lastTransOK )
      {
        // Confere se ha algo no buffer
        if ( TWI_statusReg.RxDataInBuf )
        {
          TWI_Get_Data_From_Transceiver(messageBuf, 2);         
          // Confere se o ultimo pedido foi um General Call
          if ( TWI_statusReg.genAddressCall )
          {
            // Trata o "broadcast"
            PORTB = messageBuf[0];
          }               
          else // Ends up here if the last operation was a reception as Slave Address Match   
          {
            // Example of how to interpret a command and respond.
            
            // TWI_CMD_MASTER_WRITE stores the data to PORTB
            if (messageBuf[0] == TWI_CMD_MASTER_WRITE)
            {
              PORTB = messageBuf[1];                            
            }
            // TWI_CMD_MASTER_READ prepares the data from PINB in the transceiver buffer for the TWI master to fetch.
            if (messageBuf[0] == TWI_CMD_MASTER_READ)
            {
              messageBuf[0] = PINB;
              TWI_Start_Transceiver_With_Data( messageBuf, 1 );
            }
          }
        }                
        // Apos a operacao ele reinicia o receptor
        if ( ! TWI_Transceiver_Busy() )
        {
          TWI_Start_Transceiver();
        }
      }
      else // Trata erro de transmissao
      {
        TrataErroTransI2C( TWI_Get_State_Info() );
      }
    }
  }
}
Example #13
0
int main(void)
{
	unsigned char messageBuf[6];// data from the nunchuk
	uint8_t statusCount = 0;
	//
	// Set up the LCD
	//
	init_lcd();
	setPosition(0,0);
	display("Initialise TWI...");
	//
	// Initialise TWI for the WII nunchuk
	//
	/* Initial TWI Peripheral */
	TWSR = 0x00;   // Select Prescaler of 1

	// SCL frequency = 16000000 / (16 + 2 * 72 * 1) = 100 khz
	TWBR = 72;

	showTWIStatus(statusCount++);
#ifdef SERVOS
	setPosition(0,0);
	display("Moving Servos...");
	//
	//Set the output ports
	//
	DDRB |= _BV(PORTB5) | _BV(PORTB6) | _BV(PORTB7); // OC1A, OC1B and OC1C, PB5, PB6 and PB7, Arduino pins 11, 12 and 13
	DDRB |= _BV(PORTB4);
	DDRE |= _BV(PORTE3);

	//
	// Set up 16-bit timer/counter 1 for Fast PWM, 16MHz/8, TOP is ICR1_MAX, time period is 20ms
	//
	TCCR1A |= (1<<WGM11) | (1<<COM1A1) | (1<<COM1A0) | (1<<COM1B1) | (1<<COM1B0) | (1<<COM1C1) | (1<<COM1C0);
	TCCR1B |= (1<<WGM12) | (1<<WGM13) | (1<<CS11);
	TCCR1C |= 0;
	ICR1 = ICR1_MAX;//Sets the cycle to 20ms
	//
	// Set up 16-bit timer/counter 3 for Fast PWM, 16MHz/8, TOP is ICR1_MAX, time period is 20ms
	//
	TCCR3A |= (1<<WGM31) | (1<<COM3A1) | (1<<COM3A0);
	TCCR3B |= (1<<WGM32) | (1<<WGM33) | (1<<CS31);
	TCCR3C |= 0;
	ICR3 = ICR1_MAX;//Sets the cycle to 20ms

//
// Send two servos from one end to the other every 0.5s, REPEAT times, in anti-phase.
//
	uint8_t i = 0;
    while(i++ < REPEAT)
    {
		OCR1A = ICR1 - SERVO_9G_MIN;
		OCR3A = ICR3 - SERVO_9G_MIN;
		OCR1B = ICR1 - SERVO_9G_MIN;
		OCR1C = ICR1 - SERVO_9G_MIN;
		_delay_ms(STEP_DELAY);
		OCR1A = ICR1 - SERVO_9G_MAX;
		OCR3A = ICR3 - SERVO_9G_MAX;
		OCR1B = ICR1 - SERVO_9G_MAX;
		OCR1C = ICR1 - SERVO_9G_MAX;
		_delay_ms(STEP_DELAY);
	}
#endif
//
// Next step message
//
	setPosition(0,0);
	display("Initialising nunchuk");
	//
	// init nunchuk
	//

	messageBuf[0] = 0xA4;
	messageBuf[1] = 0xF0;
	messageBuf[2] = 0x55;
	TWI_Start_Transceiver_With_Data( messageBuf, 3 );
	showTWIStatus(statusCount++);
	messageBuf[0] = 0xA4;
	messageBuf[1] = 0xFB;
	messageBuf[2] = 0x00;
	TWI_Start_Transceiver_With_Data( messageBuf, 3 );
	showTWIStatus(statusCount++);
    while(1)
    {
		//
		// Request bytes
		//
		messageBuf[0] = 0xA4;
		messageBuf[1] = 0x00;
		TWI_Start_Transceiver_With_Data( messageBuf, 2 );
		showTWIStatus(statusCount++);
		messageBuf[0] = 0xA5;
		TWI_Start_Transceiver_With_Data( messageBuf, 1 );
		showTWIStatus(statusCount++);
		//
		// Read bytes
		//
		TWI_Get_Data_From_Transceiver( messageBuf, 1 );
		showTWIStatus(statusCount++);
		//
		// Decode Buffer
		//
		for(int i = 0;i<5;i++) {
			messageBuf[i] = (messageBuf[i]^0x17) + 0x17;
		}
		showTWIStatus(statusCount++);
		//
		// Do something with the data
		//
		/*
		char hex[3] = {' ',' ',0x00};
		setPosition(0,0);
		display("Data:               ");
		setPosition(0,6);
		to_hex(messageBuf[0], hex);
		display(hex);
		display(" ");
		to_hex(messageBuf[1], hex);
		display(hex);
		display(" ");
		to_hex(messageBuf[2], hex);
		display(hex);
		setPosition(1,0);
		display("Data: ");
		to_hex(messageBuf[3], hex);
		display(hex);
		display(" ");
		to_hex(messageBuf[4], hex);
		display(hex);
		display(" ");
		to_hex(messageBuf[5], hex);
		display(hex);
		*/
		_delay_ms(100);
    }
}
Example #14
0
int main(void)
{
  unsigned char messageBuf[TWI_BUFFER_SIZE];  
  unsigned char responseBuf[1];
  unsigned char TWI_slaveAddress;
  
  CMotor *m = NULL;
  int speed = 0;
  int direction = 0;
  
  // Own TWI slave address
  TWI_slaveAddress = 0x10;

  // Initialise TWI module for slave operation. Include address and/or enable General Call.
  TWI_Slave_Initialise( (unsigned char)((TWI_slaveAddress<<TWI_ADR_BITS) | (TRUE<<TWI_GEN_BIT) )); 
                       
   sei();

  // Start the TWI transceiver to enable reception of the first command from the TWI Master.
  TWI_Start_Transceiver(); 
  
  //start out withe the last tx being OK - to make sure we don't end up blocking on the first request
  TWI_statusReg.lastTransOK = TRUE;  
	
  m = motor_new(0);
  
  // This loop runs forever. If the TWI is busy the execution will just continue doing other operations.
  for(;;)
	{ 
	  
    // Check if the TWI Transceiver has completed an operation.
    if ( ! TWI_Transceiver_Busy() )                              
    {			  				
      // Check if the last operation was successful
      if ( TWI_statusReg.lastTransOK )
      {		  
        // Check if the last operation was a reception	
        if ( TWI_statusReg.RxDataInBuf )
        {					
          TWI_Get_Data_From_Transceiver(messageBuf, 4);       
                  
            if (messageBuf[1] == TWI_CMD_MOTOR_HALT)
            {
				motor_halt(m);
				responseBuf[0] = TWI_CMD_MOTOR_HALT;
				TWI_Start_Transceiver_With_Data( responseBuf, 1 );            
            } 
            else if (messageBuf[1] == TWI_CMD_MOTOR_SETSPEED)
            {				
				speed = messageBuf[2];
				direction = messageBuf[3];
				
				motor_setspeed_and_direction(m,speed,direction);
				responseBuf[0] = TWI_CMD_MOTOR_SETSPEED;
				TWI_Start_Transceiver_With_Data( responseBuf, 1 );
            }
            else
            {
				//log an error?  UNknown CMD
			}
        }                
        else // Ends up here if the last operation was a transmission  
        {
            //__no_operation(); // Put own code here.
 		
            responseBuf[0] = TWI_CMD_CONFIRM;
			TWI_Start_Transceiver_With_Data( responseBuf, 1 );
        }
        // Check if the TWI Transceiver has already been started.
        // If not then restart it to prepare it for new receptions.             
        if ( ! TWI_Transceiver_Busy() )
        {
          TWI_Start_Transceiver();
        }
      }
      else // Ends up here if the last operation completed unsuccessfully
      {	 		 
			//fail safe  - halt the motor
			motor_halt(m);
			TWI_Act_On_Failure_In_Last_Transmission( TWI_Get_State_Info() );
      }
    }
  }
}
Example #15
0
int main( void )
{
  uint32_t val = 0;
  char textbuf [ (2*16) + 1 ]; // lcd

  /* setup
   */

  // LCD
  lcd_init();

  // Timer: enable a timer so we can measure passage of time
  //
  // Given: 20MHz clock
  // --> if we want resolution of ms (1/1000th second) .. actually, we want us (1/10th of a ms) so we can measure partial ms
  // --> and we have 1/20000000 clock resolution
  // -----> 2000 ticks will get us there (20,000 will get us ms)
  //
  // Goal: Use CTC interupt mode (CTC -> Clear on Timer Compare)
  // So a compare matches, it clears to zero and triggers interupt
  TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode 
  OCR1A = 2000; // number to compare against
  TIMSK1 |= (1 << OCIE1A); // Enable CTC interrupt 
  TCCR1B |= (1 << CS10); // Set up timer , with no prescaler (works at full MHz of clock)

  // Receiver setup - set up pin change interupt
#if 1
  EICRA &= ~ ( (1 << ISC01) | (1 << ISC01) ); // clear ISC01+ISC00
  EICRA |= ( (1 << ISC00) ); // 00 set and 01 unset means any edge will make event
  PCMSK0 |= ( (1 << PCINT0) | (1 << PCINT1) ); // Pins to monitor: PA0 and PA1
  PCICR |= (1 << PCIE0); // PA is monitored
#endif

  // Serial - setup (for motor controller)
  mc_setup();

  // TWI - set up
  unsigned char twibuf [ TWI_BUFFER_SIZE ];
  unsigned char TWI_slaveAddress; 
  TWI_slaveAddress = 0x10; // our TWI address
  TWI_Slave_Initialise( (unsigned char)((TWI_slaveAddress<<TWI_ADR_BITS) | (TRUE<<TWI_GEN_BIT) )); // Initialise TWI module as slave; include addr+general
  unsigned char twi_heartbeat_counter = 0;

  // setup done - kick up interupts
  sei();

  // lets burn the first couple of seconds, so the receiver can get some signal
  // before we start blasting stuff into the motor controllers
  {
    unsigned int start_sec = g_time_s;
    while ( g_time_s - start_sec < 3 ) {
      nop();
    }
  }

  // Start the TWI transceiver to enable reseption of the first command from the TWI Master.
  TWI_Start_Transceiver();

#if 1 // timer test .. show per-second counter update on lcd
  if ( 1 ) {
    unsigned int last_sec = g_time_s;
    unsigned int last_us = _g_time_us_tick;

    unsigned char sent_l = 0, sent_r = 0;
    char message [ 17 ];

    while(1) {
      unsigned int ch1 = g_ch1_duration;
      unsigned int ch2 = g_ch2_duration;

      // 100ms has past?
      if ( _g_time_us_tick - last_us > 1000 ) {

        if ( g_control_twi ) {
          // we're on TWI control, but if nothing comes in.. revert back to RC
          if ( g_time_s - g_control_last_s > 2 ) {
            g_control_twi = 0;
          }
        } else {
          mc_set_by_receiver ( ch1, ch2, &sent_l, &sent_r, message );
        }

        last_us = _g_time_us_tick;
      } // .1sec tick

      // one second has past? update lcd
      if ( g_time_s != last_sec ) {
        //sprintf ( textbuf, "recv %2d %2d     ", g_ch1_duration, g_ch2_duration );
        sprintf ( textbuf, "m %2d %2d th %2d %2d #", sent_l, sent_r, ch1, ch2 );
        lcd_xy ( 0, 0 );
        lcd_puts( textbuf ); // display number right adjusted

        //sprintf ( textbuf, "t%2d #", g_time_s );
        sprintf ( textbuf, "t%2d # %s", g_time_s, message );
        lcd_xy ( 0, 1 );
        lcd_puts( textbuf ); // display number right adjusted

        last_sec = g_time_s;
      } // 1 sec tick

      // TWI/I2C stuff, talk to r-pi
      //

      // Check if the TWI Transceiver has completed an operation.
      if ( ! TWI_Transceiver_Busy() ) {

        // Check if the last operation was successful
        if ( TWI_statusReg.lastTransOK ) {

          // Check if the last operation was a reception
          if ( TWI_statusReg.RxDataInBuf ) {
            TWI_Get_Data_From_Transceiver ( twibuf, 3 );

            // Check if the last operation was a reception as General Call        
            if ( TWI_statusReg.genAddressCall ) {
              // don't care

            } else { // Ends up here if the last operation was a reception as Slave Address Match   
              // Example of how to interpret a command and respond.

#if 0            
              // TWI_CMD_MASTER_WRITE stores the data to PORTB
              if (twibuf[0] == TWI_CMD_MASTER_WRITE) {
                PORTB = twibuf[1];                            
              }
#endif

              // TWI_CMD_MASTER_READ prepares the data from PINB in the transceiver buffer for the TWI master to fetch.
              if ( twibuf[0] == tc_heartbeat ) {
                twibuf [ 0 ] = 1;
                twibuf [ 1 ] = twi_heartbeat_counter++;
                TWI_Start_Transceiver_With_Data ( twibuf, TWI_BUFFER_SIZE );

              } else if ( twibuf[0] == tc_gethello ) {
                sprintf ( twibuf + 1, "hello" );
                twibuf [ 0 ] = strlen ( twibuf + 1 ); // len
                TWI_Start_Transceiver_With_Data ( twibuf, TWI_BUFFER_SIZE );

              } else if ( twibuf[0] == tc_setmotors ) {
                g_control_last_s = g_time_s;
                mc_speed ( mcm_left, twibuf [ 1 ] );
                mc_speed ( mcm_right, twibuf [ 2 ] );

              } else if ( twibuf[0] == tc_takeover ) {
                g_control_last_s = g_time_s;
                g_control_twi = 1;

              } else if ( twibuf[0] == tc_release ) {
                g_control_twi = 0;

              } else {
                twibuf [ 0 ] = 1;
                twibuf [ 1 ] = 0xde;
                twibuf [ 2 ] = 0xad;
                twibuf [ 3 ] = 0xbe;
                twibuf [ 4 ] = 0xef;
                TWI_Start_Transceiver_With_Data ( twibuf, TWI_BUFFER_SIZE );
              }

            }

          } else { // Ends up here if the last operation was a transmission  
            // don't care
          }

          // Check if the TWI Transceiver has already been started.
          // If not then restart it to prepare it for new receptions.             
          if ( ! TWI_Transceiver_Busy() ) {
            TWI_Start_Transceiver();
          }

        } else { // Ends up here if the last operation completed unsuccessfully
          TWI_Act_On_Failure_In_Last_Transmission ( TWI_Get_State_Info() );
        } // success/fail

      } // TWI busy?

      // spin
      _delay_ms ( 20 );

    } // while forever

  } // if 1
#endif

  /* churn forever
   */
  while(1);

  return ( 0 );
}
uchar sensor_read_data_registers() {  // {{{
	// Reads the X,Y,Z data registers and store them at global vars.
	// In case of a transmission error, the previous values are not changed.
	//
	// This function is non-blocking.

	// 1 address byte + 6 data bytes = 7 bytes
	uchar msg[7];

	uchar lastTransOK;

	SensorData *sens = &sensor;
	FIX_POINTER(sens);

	switch(sens->func_step) {
		case 0:  // Set address pointer
			if (TWI_Transceiver_Busy()) return SENSOR_FUNC_STILL_WORKING;

			sensor_set_address_pointer(SENSOR_REG_DATA_START);
			sens->func_step = 1;
		case 1:  // Start reading operation
			if (TWI_Transceiver_Busy()) return SENSOR_FUNC_STILL_WORKING;

			msg[0] = SENSOR_I2C_READ_ADDRESS;
			TWI_Start_Transceiver_With_Data(msg, 7);

			sens->func_step = 2;
		case 2:  // Finished reading operation
			if (TWI_Transceiver_Busy()) return SENSOR_FUNC_STILL_WORKING;

			lastTransOK = TWI_Get_Data_From_Transceiver(msg, 7);
			sens->func_step = 0;

			if (lastTransOK) {
				// Copying data to sensor->data struct
				#define OFFSET(suffix) (1 + SENSOR_REG_DATA_##suffix - SENSOR_REG_DATA_START)
				sens->data.x = (msg[OFFSET(X_MSB)] << 8) | (msg[OFFSET(X_LSB)]);
				sens->data.y = (msg[OFFSET(Y_MSB)] << 8) | (msg[OFFSET(Y_LSB)]);
				sens->data.z = (msg[OFFSET(Z_MSB)] << 8) | (msg[OFFSET(Z_LSB)]);
				#undef OFFSET

				// Detecting overflow
				sens->overflow =
					(sens->data.x == SENSOR_DATA_OVERFLOW)
					|| (sens->data.y == SENSOR_DATA_OVERFLOW)
					|| (sens->data.z == SENSOR_DATA_OVERFLOW);

				// Applying zero compensation
				if (sens->e.zero_compensation && !sens->overflow) {
					sens->data.x -= sens->e.zero.x;
					sens->data.y -= sens->e.zero.y;
					sens->data.z -= sens->e.zero.z;
				}

				sens->new_data_available = 1;
				sens->error_while_reading = 0;
				return SENSOR_FUNC_DONE;
			} else {
				sens->error_while_reading = 1;
				return SENSOR_FUNC_ERROR;
			}
		default:
			sens->error_while_reading = 1;
			return SENSOR_FUNC_ERROR;
	}
}  // }}}
Example #17
0
int main(){
  unsigned char messageBuf[TWI_BUFFER_SIZE];
  unsigned char TWI_slaveAddress;
  


  
  // Own TWI slave address
  TWI_slaveAddress = 0x20;


	InitIO();
	defset();
	InitTimer();
	OSCCAL=0xA8;
//	wdt_reset();
	/* Write logical one to WDCE and WDE */
//	WDTCR = (1<<WDCE) | (1<<WDE) | (2<<WDP0);
//	WDTCR = (1<<WDE) | (2<<WDP0);
	TIMING=eeprom_read_word(&EETIMING);
	TWI_Slave_Initialise( (unsigned char)((TWI_slaveAddress<<TWI_ADR_BITS) | (FALSE<<TWI_GEN_BIT) ));
	sei();
  TWI_Start_Transceiver();
	while (1){
   // Check if the TWI Transceiver has completed an operation.
    if ( ! TWI_Transceiver_Busy() )                              
    {
      // Check if the last operation was successful
      if ( TWI_statusReg.lastTransOK )
      {
        // Check if the last operation was a reception
        if ( TWI_statusReg.RxDataInBuf )
        {
		PORTB^=1<<PB3;
          TWI_Get_Data_From_Transceiver(messageBuf, 2);         
          // Check if the last operation was a reception as General Call        
          if ( TWI_statusReg.genAddressCall )
          {
            // Put data received out to PORTB as an example.        
           // PORTB = messageBuf[0];
		   
          }               
          else // Ends up here if the last operation was a reception as Slave Address Match   
          {
            // Example of how to interpret a command and respond.
			
			switch (messageBuf[0]){
			case xval:
				OCR1A=255-messageBuf[1];                            
				break;
			case yval:
              OCR1B=255-messageBuf[1];                            
			  break;
//              TWI_Start_Transceiver_With_Data( messageBuf, 1 );
			}
          }
        }                
        else // Ends up here if the last operation was a transmission  
        {
          //  __no_operation(); // Put own code here.

        }
        // Check if the TWI Transceiver has already been started.
        // If not then restart it to prepare it for new receptions.             
        if ( ! TWI_Transceiver_Busy() )
        {
          TWI_Start_Transceiver();
        }
      }
      else // Ends up here if the last operation completed unsuccessfully
      {
        TWI_Act_On_Failure_In_Last_Transmission( TWI_Get_State_Info() );
      }
    }

	}

}
Example #18
0
void main( void )
{
  unsigned char messageBuf[TWI_BUFFER_SIZE];
  unsigned char TWI_slaveAddress;
  
  // LED feedback port - connect port B to the STK500 LEDS
  DDRB  = 0xFF; // Set to ouput
  PORTB = 0x55; // Startup pattern
  
  // Own TWI slave address
  TWI_slaveAddress = 0x10;

  // Initialise TWI module for slave operation. Include address and/or enable General Call.
  TWI_Slave_Initialise( (unsigned char)((TWI_slaveAddress<<TWI_ADR_BITS) | (TRUE<<TWI_GEN_BIT) )); 
                       
  __enable_interrupt();

  // Start the TWI transceiver to enable reseption of the first command from the TWI Master.
  TWI_Start_Transceiver();

  // This example is made to work together with the AVR315 TWI Master application note. In adition to connecting the TWI
  // pins, also connect PORTB to the LEDS. The code reads a message as a TWI slave and acts according to if it is a 
  // general call, or an address call. If it is an address call, then the first byte is considered a command byte and
  // it then responds differently according to the commands.

  // This loop runs forever. If the TWI is busy the execution will just continue doing other operations.
  for(;;)
  { 
    #ifdef POWER_MANAGEMENT_ENABLED
      // Sleep while waiting for TWI transceiver to complete or waiting for new commands.
      // If we have data in the buffer, we can't enter sleep because we have to take care
      // of it first.
      // If the transceiver is busy, we enter idle mode because it will wake up by all TWI
      // interrupts.
      // If the transceiver not is busy, we can enter power-down mode because next receive
      // should be a TWI address match and it wakes the device up from all sleep modes.
      if( ! TWI_statusReg.RxDataInBuf ) {
        if(TWI_Transceiver_Busy()) {
          MCUCR = (1<<SE)|(0<<SM2)|(0<<SM1)|(0<<SM0); // Enable sleep with idle mode
        } else {
          MCUCR = (1<<SE)|(0<<SM2)|(1<<SM1)|(0<<SM0); // Enable sleep with power-down mode
        }
        __sleep();
      } else {
        __no_operation(); // There is data in the buffer, code below takes care of it.
      }
    #else // No power management
      // Here you can add your own code that should be run while waiting for the TWI to finish    
      __no_operation(); // Put own code here.
    #endif
      
    
    // Check if the TWI Transceiver has completed an operation.
    if ( ! TWI_Transceiver_Busy() )                              
    {
      // Check if the last operation was successful
      if ( TWI_statusReg.lastTransOK )
      {
        // Check if the last operation was a reception
        if ( TWI_statusReg.RxDataInBuf )
        {
          TWI_Get_Data_From_Transceiver(messageBuf, 2);         
          // Check if the last operation was a reception as General Call        
          if ( TWI_statusReg.genAddressCall )
          {
            // Put data received out to PORTB as an example.        
            PORTB = messageBuf[0];
          }               
          else // Ends up here if the last operation was a reception as Slave Address Match   
          {
            // Example of how to interpret a command and respond.
            
            // TWI_CMD_MASTER_WRITE stores the data to PORTB
            if (messageBuf[0] == TWI_CMD_MASTER_WRITE)
            {
              PORTB = messageBuf[1];                            
            }
            // TWI_CMD_MASTER_READ prepares the data from PINB in the transceiver buffer for the TWI master to fetch.
            if (messageBuf[0] == TWI_CMD_MASTER_READ)
            {
              messageBuf[0] = PINB;
              TWI_Start_Transceiver_With_Data( messageBuf, 1 );
            }
          }
        }                
        else // Ends up here if the last operation was a transmission  
        {
            __no_operation(); // Put own code here.
        }
        // Check if the TWI Transceiver has already been started.
        // If not then restart it to prepare it for new receptions.             
        if ( ! TWI_Transceiver_Busy() )
        {
          TWI_Start_Transceiver();
        }
      }
      else // Ends up here if the last operation completed unsuccessfully
      {
        TWI_Act_On_Failure_In_Last_Transmission( TWI_Get_State_Info() );
      }
    }
  }
}
Example #19
0
void main(void)
{
	unsigned char messageBuf[4];
	unsigned char TWI_targetSlaveAddress, temp, TWI_operation = 0,
			pressedButton, myCounter = 0;

	//LED feedback port - connect port B to the STK500 LEDS
	DDRB = 0xFF;
	PORTB = myCounter;

	//Switch port - connect portD to the STK500 switches
	DDRD = 0x00;

	TWI_Master_Initialize();
	__enable_interrupt();

	TWI_targetSlaveAddress = 0x10;

	// This example is made to work together with the AVR311 TWI Slave application note and stk500.
	// In adition to connecting the TWI pins, also connect PORTB to the LEDS and PORTD to the switches.
	// The code reads the pins to trigger the action you request. There is an example sending a general call,
	// address call with Master Read and Master Write. The first byte in the transmission is used to send
	// commands to the TWI slave.

	// This is a stk500 demo example. The buttons on PORTD are used to control different TWI operations.
	for (;;)
	{
		pressedButton = ~PIND;
		if (pressedButton)       // Check if any button is pressed
		{
			do
			{
				temp = ~PIND;
			}      // Wait until key released
			while (temp);

			switch (pressedButton)
			{
			// Send a Generall Call
			case (1 << PD0):
				messageBuf[0] = TWI_GEN_CALL; // The first byte must always consit of General Call code or the TWI slave address.
				messageBuf[1] = 0xAA; // The command or data to be included in the general call.
				TWI_Start_Transceiver_With_Data(messageBuf, 2);
				break;

				// Send a Address Call, sending a command and data to the Slave
			case (1 << PD1):
				messageBuf[0] = (TWI_targetSlaveAddress << TWI_ADR_BITS)
						| (FALSE << TWI_READ_BIT); // The first byte must always consit of General Call code or the TWI slave address.
				messageBuf[1] = TWI_CMD_MASTER_WRITE; // The first byte is used for commands.
				messageBuf[2] = myCounter; // The second byte is used for the data.
				TWI_Start_Transceiver_With_Data(messageBuf, 3);
				break;

				// Send a Address Call, sending a request, followed by a resceive
			case (1 << PD2):
				// Send the request-for-data command to the Slave
				messageBuf[0] = (TWI_targetSlaveAddress << TWI_ADR_BITS)
						| (FALSE << TWI_READ_BIT); // The first byte must always consit of General Call code or the TWI slave address.
				messageBuf[1] = TWI_CMD_MASTER_READ; // The first byte is used for commands.
				TWI_Start_Transceiver_With_Data(messageBuf, 2);

				TWI_operation = REQUEST_DATA; // To release resources to other operations while waiting for the TWI to complete,
											  // we set a operation mode and continue this command sequence in a "followup"
											  // section further down in the code.

											  // Get status from Transceiver and put it on PORTB
			case (1 << PD5):
				PORTB = TWI_Get_State_Info();
				break;

				// Increment myCounter and put it on PORTB
			case (1 << PD6):
				PORTB = ++myCounter;
				break;

				// Reset myCounter and put it on PORTB
			case (1 << PD7):
				PORTB = myCounter = 0;
				break;
			}
		}

		if (!TWI_Transceiver_Busy())
		{
			// Check if the last operation was successful
			if (TWI_statusReg.lastTransOK)
			{
				if (TWI_operation) // Section for follow-up operations.
				{
					// Determine what action to take now
					if (TWI_operation == REQUEST_DATA)
					{ // Request/collect the data from the Slave
						messageBuf[0] = (TWI_targetSlaveAddress << TWI_ADR_BITS)
								| (TRUE << TWI_READ_BIT); // The first byte must always consit of General Call code or the TWI slave address.
						TWI_Start_Transceiver_With_Data(messageBuf, 2);
						TWI_operation = READ_DATA_FROM_BUFFER; // Set next operation
					}
					else if (TWI_operation == READ_DATA_FROM_BUFFER)
					{ // Get the received data from the transceiver buffer
						TWI_Get_Data_From_Transceiver(messageBuf, 2);
						PORTB = messageBuf[1];        // Store data on PORTB.
						TWI_operation = FALSE;     // Set next operation
					}
				}
			}
			else // Got an error during the last transmission
			{
				// Use TWI status information to detemine cause of failure and take appropriate actions.
				TWI_Act_On_Failure_In_Last_Transmission(TWI_Get_State_Info());
			}
		}

		// Do something else while waiting for TWI operation to complete and/or a switch to be pressed
		asm volatile ("nop");
		// Put own code here.

	}
}
Example #20
0
void main( void )
{
  unsigned char messageBuf[4];
  unsigned char TWI_slaveAddress, TWI_slaveAddress2, TWI_slaveAddressMask, temp;

  // LED feedback port - connect port B to the STK500 LEDS
  DDRB  = 0xFF; // Set to ouput
  PORTB = 0x55; // Startup pattern

  // Own TWI slave address
  TWI_slaveAddress     = (0x10<<TWI_ADR_BITS);
  TWI_slaveAddress2    = (0x11<<TWI_ADR_BITS);                  // Alternativ slave address to respond to.
  TWI_slaveAddressMask = TWI_slaveAddress ^ TWI_slaveAddress2;  // XOR the addresses to get the address mask.

  // Initialise TWI module for slave operation. Include address and/or enable General Call.
  TWI_Slave_Initialise( TWI_slaveAddress | (TRUE<<TWI_GEN_BIT), TWI_slaveAddressMask); 
                                                                                  
  __enable_interrupt();

  // Start the TWI transceiver to enable reseption of the first command from the TWI Master.
  TWI_Start_Transceiver();

  // This example is made to work together with the AVR315 TWI Master application note. In adition to connecting the TWI
  // pins, also connect PORTB to the LEDS. The code reads a message as a TWI slave and acts according to if it is a 
  // general call, or an address call. If it is an address call, then the first byte is considered a command byte and
  // it then responds differently according to the commands.

  // This loop runs forever. If the TWI is busy the execution will just continue doing other operations.
  for(;;)
  {    
    // Check if the TWI Transceiver has completed an operation.
    if ( ! TWI_Transceiver_Busy() )                              
    {
    // Check if the last operation was successful
      if ( TWI_statusReg.lastTransOK )
      {
    // Check if the last operation was a reception
        if ( TWI_statusReg.RxDataInBuf )
        {
          TWI_Get_Data_From_Transceiver(messageBuf, 3);         
    // Check if the last operation was a reception as General Call        
          if ( TWI_statusReg.genAddressCall )
          {
          // Put data received out to PORTB as an example.        
            PORTB = messageBuf[1];                              
          }
    // Ends up here if the last operation was a reception as Slave Address Match                  
          else
          {
    // Take action dependant on what slave address that was used in the message
            if (messageBuf[0] == TWI_slaveAddress)
            {
    // Example of how to interpret a command and respond.            
            // TWI_CMD_MASTER_WRITE stores the data to PORTB
              if (messageBuf[1] == TWI_CMD_MASTER_WRITE)
                PORTB = messageBuf[2];                            
            // TWI_CMD_MASTER_READ prepares the data from PINB in the transceiver buffer for the TWI master to fetch.
              if (messageBuf[1] == TWI_CMD_MASTER_READ)
              {
                messageBuf[0] = PINB;                             
                TWI_Start_Transceiver_With_Data( messageBuf, 1 );           
              }
            }
            else
            {
              PORTB = messageBuf[1];  // Put TWI address data on PORTB
            }
          }
        }
    // Ends up here if the last operation was a transmission                  
        else
        {
            __no_operation(); // Put own code here.
        }
    // Check if the TWI Transceiver has already been started.
    // If not then restart it to prepare it for new receptions.             
        if ( ! TWI_Transceiver_Busy() )
        {
          TWI_Start_Transceiver();
        }      
      }
    // Ends up here if the last operation completed unsuccessfully
      else
      {
        TWI_Act_On_Failure_In_Last_Transmission( TWI_Get_State_Info() );
      }
      
    }
    // Do something else while waiting for the TWI transceiver to complete.    
    __no_operation(); // Put own code here.
  }
}