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; }
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; } } // }}}
void pca9634_setOpMode(uint8_t id, pca9634_OpMode_t mode) { if (id < 8) { unsigned char msgBuf[5]; /* */ uint8_t reg; uint8_t shift = (id&0b11)<<1; uint8_t data; if (id < 4) { reg = PCA9634_REG_LEDOUT0; pca9634_LEDOUT0 = pca9634_LEDOUT0|(mode<<shift); data = pca9634_LEDOUT0; } else if (id < 8) { reg = PCA9634_REG_LEDOUT1; pca9634_LEDOUT1 = pca9634_LEDOUT1|(mode<<shift); data = pca9634_LEDOUT1; } msgBuf[0] = (pca9634_address<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); msgBuf[1] = reg; msgBuf[2] = data; TWI_Start_Read_Write( msgBuf, 3 ); while ( TWI_Transceiver_Busy() ); } }
static int8_t twi_tx(uint8_t *buf, uint8_t len) { uint8_t i; uint8_t waits = 0; const uint8_t max_waits = TIME_TO_MS(twi_tx_timeout) / TIME_TO_MS(twi_tx_poll_interval); LOG("TWI write: "); for (i = 0; i < len; ++i) LOGP("0x%x ", msg_buf[i]); LOGA("\r\n"); TWI_Start_Transceiver_With_Data(msg_buf, len); /* NOTE: can't use nrk_time_get because before nrk_start() */ while (TWI_Transceiver_Busy() && waits++ < max_waits) nrk_spin_wait_us(twi_tx_poll_interval.nano_secs / 1000); if (waits >= max_waits) { LOG("WARN: TWI write timed out\r\n"); return NRK_ERROR; } if (!TWI_statusReg.lastTransOK) { LOG("WARN: TWI write failed\r\n"); handle_error(TWI_Get_State_Info()); return NRK_ERROR; } return NRK_OK; }
unsigned char TWI_Get_State_Info (void) { while (TWI_Transceiver_Busy ()); // Wait until TWI has completed the transmission. return (TWI_state); // Return error state. }
/**************************************************************************** Call this function to start the Transceiver without specifing new transmission data. Usefull for restarting a transmission, or just starting the transceiver for reception. The driver will reuse the data previously put in the transceiver buffers. The function will hold execution (loop) until the TWI_ISR has completed with the previous operation, then initialize the next operation and return. ****************************************************************************/ void TWI_Start_Transceiver( void ) { while ( TWI_Transceiver_Busy() ); // Wait until TWI is ready for next transmission. TWI_statusReg.all = 0; TWI_state = TWI_NO_STATE ; TWCR = (1<<TWEN)| // TWI Interface enabled. (1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag. (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Prepare to ACK next time the Slave is addressed. (0<<TWWC); // }
/**************************************************************************** Call this function to resend the last message. The driver will reuse the data previously put in the transceiver buffers. The function will hold execution (loop) until the TWI_ISR has completed with the previous operation, then initialize the next operation and return. ****************************************************************************/ void TWI_Start_Transceiver( void ) { while ( TWI_Transceiver_Busy() ); // Wait until TWI is ready for next transmission. TWI_statusReg.all = 0; TWI_state = TWI_NO_STATE ; TWCR = (1<<TWEN)| // TWI Interface enabled. (1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag. (0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)| // Initiate a START condition. (0<<TWWC); // }
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; } } } }
/**************************************************************************** Call this function to start the Transceiver without specifing new transmission data. Useful for restarting a transmission, or just starting the transceiver for reception. The driver will reuse the data previously put in the transceiver buffers. The function will hold execution (loop) until the TWI_ISR has completed with the previous operation, then initialize the next operation and return. ****************************************************************************/ void TWI_Start_Transceiver( void ) { while ( TWI_Transceiver_Busy() ) {} // Wait until TWI is ready for next transmission. TWI_statusReg.all = 0; TWI_state = TWI_NO_STATE ; USICR = (1<<USIWM1)|(0<<USIWM0)| // Mode set to TWI. (1<<USISIE)|(1<<USIOIE)| // Enable TWI Interupt and clear the flag. (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Prepare to ACK next time the Slave is addressed. (0<<USITC); // TWI_busy = 0; }
void pca9634_setDuty(uint8_t id, uint8_t step) { /* set register PWM[id] to step */ if (id < 8) { unsigned char msgBuf[5]; msgBuf[0] = (pca9634_address<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); msgBuf[1] = PCA9634_REG_PWM0+id; msgBuf[2] = step; TWI_Start_Read_Write( msgBuf, 3 ); while ( TWI_Transceiver_Busy() ); } }
void pca9634_init(uint8_t address) { unsigned char msgBuf[5]; TWI_Master_Initialise(); pca9634_address = address; /* init, MODE1.SLEEP shall be set to normal mode */ uint8_t data = PCA9634_MODE1_SLEEP|PCA9634_MODE1_SUB1|PCA9634_MODE1_SUB2|PCA9634_MODE1_SUB3|PCA9634_MODE1_ALL; msgBuf[0] = (pca9634_address<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); msgBuf[1] = PCA9634_REG_MODE1; msgBuf[2] = data; TWI_Start_Read_Write( msgBuf, 3 ); while ( TWI_Transceiver_Busy() ); }
/**************************************************************************** Call this function to read out the requested data from the TWI transceiver buffer. I.e. first call TWI_Start_Transceiver to send a request for data to the slave. Then Run this function to collect the data when they have arrived. Include a pointer to where to place the data and the number of bytes requested (including the address field) in the function call. The function will hold execution (loop) until the TWI_ISR has completed with the previous operation, before reading out the data and returning. If there was an error in the previous transmission the function will return the TWI error code. ****************************************************************************/ unsigned char TWI_Get_Data_From_Transceiver( unsigned char *msg, unsigned char msgSize ) { unsigned char i; while ( TWI_Transceiver_Busy() ); // Wait until TWI is ready for next transmission. if( TWI_statusReg.lastTransOK ) // Last transmission competed successfully. { for ( i=0; i<msgSize; i++ ) // Copy data from Transceiver buffer. { msg[ i ] = TWI_buf[ i ]; } } return( TWI_statusReg.lastTransOK ); }
// 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 }
/**************************************************************************** Call this function to send a prepared message, or start the Transceiver for reception. Include a pointer to the data to be sent if a SLA+W is received. The data will be copied to the TWI buffer. Also include how many bytes that should be sent. Note that unlike the similar Master function, the Address byte is not included in the message buffers. The function will hold execution (loop) until the TWI_ISR has completed with the previous operation, then initialize the next operation and return. ****************************************************************************/ void TWI_Start_Transceiver_With_Data( unsigned char *msg, unsigned char msgSize ) { unsigned char temp; while ( TWI_Transceiver_Busy() ); // Wait until TWI is ready for next transmission. TWI_msgSize = msgSize; // Number of data to transmit. for ( temp = 0; temp < msgSize; temp++ ) // Copy data that may be transmitted if the TWI Master requests data. TWI_buf[ temp ] = msg[ temp ]; TWI_statusReg.all = 0; TWI_state = TWI_NO_STATE ; TWCR = (1<<TWEN)| // TWI Interface enabled. (1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag. (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| // Prepare to ACK next time the Slave is addressed. (0<<TWWC); // }
//Write Register Method unsigned char wrOV7670Reg(unsigned char regID, unsigned char regDat) { /* I2C Traffic Generated: * S | OV_7670 + W | A | RegID | A | Data | A | P | */ //I2C Interface unsigned char messageBuf[TWI_BUFFER_SIZE]; messageBuf[0] = (OV7670_ADDR <<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); // The first byte must always consit of General Call code or the TWI slave address. messageBuf[1] = regID; // The first byte is used for commands. messageBuf[2] = regDat; // The second byte is used for the data. TWI_Start_Transceiver_With_Data( messageBuf, 3 ); while(TWI_Transceiver_Busy()) ; //Wait for transceiver to clear return TWI_statusReg.lastTransOK; }
/**************************************************************************** Call this function to read out the received data from the TWI transceiver buffer. I.e. first call TWI_Start_Transceiver to get the TWI Transceiver to fetch data. Then Run this function to collect the data when they have arrived. Include a pointer to where to place the data and the number of bytes to fetch in the function call. The function will hold execution (loop) until the TWI_ISR has completed with the previous operation, before reading out the data and returning. If there was an error in the previous transmission the function will return the TWI State code. ****************************************************************************/ unsigned char TWI_Get_Data_From_Transceiver( unsigned char *msg, unsigned char msgSize ) { unsigned char i; while ( TWI_Transceiver_Busy() ) {} // Wait until TWI is ready for next transmission. if( TWI_statusReg.lastTransOK ) // Last transmission completed successfully. { for ( i=0; i<msgSize; ++i ) // Copy data from Transceiver buffer. { msg[ i ] = gp_TWI_receive_buf[ i ]; } TWI_statusReg.RxDataInBuf = FALSE; // Slave Receive data has been read from buffer. } return( TWI_statusReg.lastTransOK ); }
/*============================================================================ Name : TWI_Send_Message ------------------------------------------------------------------------------ Purpose : Send the frame stored in TX_Buffer to USB Bridge Input : n/a Output : n/a Notes : Called from Send_Message in QDebugTransport.c ============================================================================*/ void TWI_Send_Message( void ) { SET_TIMEOUT(100); // 100ms timeout TWI_msgSize = ((TX_Buffer[1]<<8)+TX_Buffer[2]); TWI_addr =(TWISLAVE_ADDR<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); TWI_statusReg.all = 0; TWCR = (1<<TWEN)| // TWI Interface enabled. (1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag. (0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)| // Initiate a START condition. (0<<TWWC); while (TWI_Transceiver_Busy()&& NOT_TIMEDOUT());// Wait until TWI is ready for next transmission. }
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; } } }
unsigned char MP3_detect(void){ unsigned int i=0; //unsigned char messageBuf[25]; MP3_messageBuf[0]=(0x22<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); MP3_messageBuf[1]=0xAA; // RESET module command MP3_messageBuf[2]=0x01; TWI_Start_Transceiver_With_Data( MP3_messageBuf, 3 ); do{sleep_mode();i++;if(i==0){break;}}while( TWI_Transceiver_Busy() ); if ((!( TWI_statusReg.lastTransOK ))||(i==0)){ //error occured //TWI_Get_State_Info( ); //check the error value/last TWI state and act accordingly, error codes are defined in the header TWI_Master_Stop(); return 0; }else{ return 1; } }
unsigned char SE95_detect(void){ unsigned int i=0; //unsigned char messageBuf[25]; se95_messageBuf[0]=(0x48<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); se95_messageBuf[1]=0x01;//configuration register se95_messageBuf[2]=0x00;//POR value=0x00 TWI_Start_Transceiver_With_Data( se95_messageBuf, 3 ); do{sleep_mode();i++;if(i==0){break;}}while( TWI_Transceiver_Busy() ); if ((!( TWI_statusReg.lastTransOK ))||(i==0)){ //error occured //TWI_Get_State_Info( ); //check the error value/last TWI state and act accordingly, error codes are defined in the header TWI_Master_Stop(); return 0; }else{ return 1; } }
/**************************************************************************** Call this function to send a prepared message. The first byte must contain the slave address and the read/write bit. Consecutive bytes contain the data to be sent, or empty locations for data to be read from the slave. Also include how many bytes that should be sent/read including the address byte. The function will hold execution (loop) until the TWI_ISR has completed with the previous operation, then initialize the next operation and return. ****************************************************************************/ void TWI_Start_Transceiver_With_Data( unsigned char *msg, unsigned char msgSize ) { unsigned char temp; while ( TWI_Transceiver_Busy() ); // Wait until TWI is ready for next transmission. TWI_msgSize = msgSize; // Number of data to transmit. TWI_buf[0] = msg[0]; // Store slave address with R/W setting. if (!( msg[0] & (TRUE<<TWI_READ_BIT) )) // If it is a write operation, then also copy data. { for ( temp = 1; temp < msgSize; temp++ ) TWI_buf[ temp ] = msg[ temp ]; } TWI_statusReg.all = 0; TWI_state = TWI_NO_STATE ; TWCR = (1<<TWEN)| // TWI Interface enabled. (1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag. (0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)| // Initiate a START condition. (0<<TWWC); // }
/*============================================================================ Name : TWI_Send_Message ------------------------------------------------------------------------------ Purpose : Read one frame from USB Bridge. Store the frame in RX_Buffer Input : n/a Output : n/a Notes : Called from Receive_Message in QDebugTransport.c ============================================================================*/ void TWI_Retrieve_Message( void ) { unsigned int i; SET_TIMEOUT(100); // 100ms timeout TWI_addr = (TWISLAVE_ADDR<<TWI_ADR_BITS) | (TRUE<<TWI_READ_BIT); TWI_statusReg.all = 0; TWCR = (1<<TWEN)| // TWI Interface enabled. (1<<TWIE)|(1<<TWINT)| // Enable TWI Interupt and clear the flag. (0<<TWEA)|(1<<TWSTA)|(0<<TWSTO)| // Initiate a START condition. (0<<TWWC); // while (TWI_Transceiver_Busy()&& NOT_TIMEDOUT());// Wait until TWI is ready for next transmission. if( ! TWI_statusReg.lastTransOK ) // Last transmission completed successfully. for ( i=0; i<=TWI_msgSize; i++ ) // Copy data from Transceiver buffer. RX_Buffer[i] = 0; // Clear data if transmission not successful }
/** * Call this function to read out the received data from the TWI transceiver buffer. I.e. first * call TWI_Start_Transceiver to get the TWI Transceiver to fetch data. Then Run this function to * collect the data when they have arrived. Include a pointer to where to place the data and * the number of bytes to fetch in the function call. The function will hold execution (loop) * until the TWI_ISR has completed with the previous operation, before reading out the data * and returning. If there was an error in the previous transmission the function will return * the TWI State code. * ---------------------------------------------------------------------------------------------- */ unsigned char TWI_Get_Data_From_Transceiver( unsigned char *msg, unsigned char msgSize ) { unsigned char i; // Wait until TWI is ready for next transmission. while ( TWI_Transceiver_Busy() ); // Last transmission competed successfully. if( TWI_statusReg.lastTransOK ) { // Copy data from Transceiver buffer. for ( i=0; i<msgSize; i++ ) { msg[i] = TWI_buf[i]; } // Slave Receive data has been read from buffer. TWI_statusReg.RxDataInBuf = FALSE; } return TWI_statusReg.lastTransOK; }
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 ); }
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() ); } } } }
char MP3_check_i2c_state_machine(void){ unsigned char min,hour,second,day,month,year,dow; clock_get_time(&min,&hour,&second,&day,&month,&year,&dow); switch(MP3_state){ case 0: if(MP3_cmd==MP3_stop){ MP3_messageBuf[0]=(0x22<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); MP3_messageBuf[1]=0x07; MP3_messageBuf[2]=1; TWI_Start_Transceiver_With_Data( &MP3_messageBuf[0], 3 ); MP3_state=10; } if(MP3_cmd==MP3_play_alarm){ MP3_messageBuf[0]=(0x22<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); MP3_messageBuf[1]=0x06; MP3_messageBuf[2]=0; TWI_Start_Transceiver_With_Data( &MP3_messageBuf[0], 3 ); MP3_state=20; } if(MP3_cmd==MP3_play_cont){ MP3_messageBuf[0]=(0x22<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); MP3_messageBuf[1]=0x0A;//write the current hour+dow MP3_messageBuf[2]=hour|((dow-1)<<5); TWI_Start_Transceiver_With_Data( &MP3_messageBuf[0], 3 ); MP3_state=30; } if(MP3_cmd==MP3_talk_time){ MP3_messageBuf[0]=(0x22<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); MP3_messageBuf[1]=0x08;//write the current hour MP3_messageBuf[2]=hour; TWI_Start_Transceiver_With_Data( &MP3_messageBuf[0], 3 ); MP3_state=40; } if(MP3_cmd==MP3_play_event){ MP3_messageBuf[0]=(0x22<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); MP3_messageBuf[1]=0x04; MP3_messageBuf[2]=MP3_track; TWI_Start_Transceiver_With_Data( &MP3_messageBuf[0], 3 ); MP3_state=10; } if(MP3_cmd==MP3_play_sched){ MP3_messageBuf[0]=(0x22<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); MP3_messageBuf[1]=0x03; MP3_messageBuf[2]=MP3_track; TWI_Start_Transceiver_With_Data( &MP3_messageBuf[0], 3 ); MP3_state=10; } if(MP3_cmd==MP3_play_amb){ MP3_messageBuf[0]=(0x22<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); MP3_messageBuf[1]=0x05; MP3_messageBuf[2]=MP3_track; TWI_Start_Transceiver_With_Data( &MP3_messageBuf[0], 3 ); MP3_state=10; } if(MP3_cmd==MP3_set_volume){ MP3_messageBuf[0]=(0x22<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); MP3_messageBuf[1]=0x06; MP3_messageBuf[2]=MP3_volume; TWI_Start_Transceiver_With_Data( &MP3_messageBuf[0], 3 ); MP3_state=10; } break; case 10:if(!(TWI_Transceiver_Busy() )){ if ( TWI_statusReg.lastTransOK ){ } MP3_cmd=0; MP3_state=0; } break; case 20:if(!(TWI_Transceiver_Busy() )){ if ( TWI_statusReg.lastTransOK ){ MP3_messageBuf[0]=(0x22<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); MP3_messageBuf[1]=0x02; MP3_messageBuf[2]=MP3_track; TWI_Start_Transceiver_With_Data( &MP3_messageBuf[0], 3 ); MP3_state=10; }else{ MP3_cmd=0; MP3_state=0; } } break; case 30:if(!(TWI_Transceiver_Busy() )){ if ( TWI_statusReg.lastTransOK ){ MP3_messageBuf[0]=(0x22<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); MP3_messageBuf[1]=0x0B;//write the current day MP3_messageBuf[2]=day; TWI_Start_Transceiver_With_Data( &MP3_messageBuf[0], 3 ); MP3_state=31; }else{ //MP3_cmd+=MP3_done; MP3_cmd=0; MP3_state=0; } } break; case 31:if(!(TWI_Transceiver_Busy() )){ if ( TWI_statusReg.lastTransOK ){ MP3_messageBuf[0]=(0x22<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); MP3_messageBuf[1]=0x0C;//write the current month MP3_messageBuf[2]=month; TWI_Start_Transceiver_With_Data( &MP3_messageBuf[0], 3 ); MP3_state=32; }else{ //MP3_cmd+=MP3_done; MP3_cmd=0; MP3_state=0; } } break; case 32:if(!(TWI_Transceiver_Busy() )){ if ( TWI_statusReg.lastTransOK ){ MP3_messageBuf[0]=(0x22<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); MP3_messageBuf[1]=0x0D;//write the current minute MP3_messageBuf[2]=min; TWI_Start_Transceiver_With_Data( &MP3_messageBuf[0], 3 ); MP3_state=33; }else{ //MP3_cmd+=MP3_done; MP3_cmd=0; MP3_state=0; } } break; case 33:if(!(TWI_Transceiver_Busy() )){ if ( TWI_statusReg.lastTransOK ){ } MP3_cmd=0; MP3_state=0; } break; case 40:if(!(TWI_Transceiver_Busy() )){ if ( TWI_statusReg.lastTransOK ){ MP3_messageBuf[0]=(0x22<<TWI_ADR_BITS) | (FALSE<<TWI_READ_BIT); MP3_messageBuf[1]=0x09;//write the current minute MP3_messageBuf[2]=min; TWI_Start_Transceiver_With_Data( &MP3_messageBuf[0], 3 ); //MP3_cmd+=MP3_done; MP3_cmd=0; MP3_state=41; }else{ //MP3_cmd+=MP3_done; MP3_cmd=0; MP3_state=0; } } break; case 41:if(!(TWI_Transceiver_Busy() )){ if ( TWI_statusReg.lastTransOK ){ } MP3_cmd=0; MP3_state=0; } break; } return MP3_state; }
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() ); } } } }
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. } }
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. } }
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; } } // }}}