void init_adxl345() { unsigned int read = 0; /* put in standby mode while we change fifo control bits */ messageBuf[0] = ADXL345_ADDRESS | FALSE<<TWI_READ_BIT; messageBuf[1] = ADXL_REGISTER_PWRCTL; messageBuf[2] = ADXL_PWRCTL_STBY; TWI_Start_Transceiver_With_Data(messageBuf, 3); /* set the fifo mode to stream */ messageBuf[0] = ADXL345_ADDRESS | FALSE<<TWI_READ_BIT; messageBuf[1] = ADXL_REGISTER_FIFOCTL; messageBuf[2] = ADXL_FIFOCTL_STREAM; TWI_Start_Transceiver_With_Data(messageBuf,3); /* set to measure mode */ messageBuf[0] = ADXL345_ADDRESS | FALSE<<TWI_READ_BIT; messageBuf[1] = ADXL_REGISTER_PWRCTL; messageBuf[2] = ADXL_PWRCTL_MEASURE; TWI_Start_Transceiver_With_Data(messageBuf, 3); /* set the data format */ messageBuf[0] = ADXL345_ADDRESS | FALSE<<TWI_READ_BIT; messageBuf[1] = ADXL_REGISTER_DATAFMT; messageBuf[2] = ADXL_DATAFMT_4G; TWI_Start_Transceiver_With_Data(messageBuf,3); }
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; }
/* 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(); } }
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(); } }
/**************************************************************************** Call this function to perform a random read. That is, a starting memory address is written, a second START is sent after receiving ACK, the slave address is re- transmitted with the read bit set, and multiple bytes are read from memory. This function works by setting the TWI_statusReg.memRead bit and calling the TWI_Start_Read_Write function. The ISR handles the repeated start. ****************************************************************************/ void TWI_Start_Random_Read( unsigned char *msg, unsigned char msgSize ) { msg[0] &= ~(TRUE<<TWI_READ_BIT); // Be sure read/write bit is clear (write) regardless. SavedMsgSize = msgSize; // Save msgSize - it'll be restored in the ISR TWI_statusReg.memRead = TRUE; // Flag memory read TWI_Start_Transceiver_With_Data( msg, 2 ); // Set size to 2 for initial call. }
/***************************************************************************//** * @brief Does an initialization routine * @param None * @return None * @date 30.10.2013 *******************************************************************************/ void Motor_Encoder_Init(struct EncoderStruct * Encoder) { int max = 0; //Define the speed to half speed unsigned char TWI_Message_to_DAC [3] = {DAC_MAX520_ADDR_WRITE, 0x00, 0x7F}; TWI_Start_Transceiver_With_Data(TWI_Message_to_DAC,0x03); //Move the motor to the left and reset the encoder pinDirMotor = MOTOR_RIGHT; pinEnableMotor = C_ENABLE; _delay_ms(2000); pinResetEncoder = 0; pinResetEncoder = 1; //Move the motor to the left and read the encoder to get the max value pinDirMotor = MOTOR_LEFT; _delay_ms(1000); max = Read_Encoder(); //Move to the right and read the encoder to get the min value pinDirMotor = MOTOR_RIGHT; _delay_ms(1000); Encoder->Offset = Read_Encoder(); Encoder->Range = max - Encoder->Offset; //Move the motor to the center pinDirMotor = MOTOR_LEFT; _delay_ms(250); pinEnableMotor = C_DISABLE; }
void init_hmc5843() { /* put in standby mode while we change fifo control bits */ messageBuf[0] = HMC5843_ADDRESS | FALSE<<TWI_READ_BIT; messageBuf[1] = HMC5843_REGISTER_MEASMODE; messageBuf[2] = HMC5843_MEASMODE_CONT; TWI_Start_Transceiver_With_Data(messageBuf, 3); }
void init_itg3200() { /* put in standby mode while we change fifo control bits */ messageBuf[0] = ITG3200_ADDRESS | FALSE<<TWI_READ_BIT; messageBuf[1] = ITG3200_REGISTER_DLPF; messageBuf[2] = ITG3200_FULLSCALE | ITG3200_42HZ; TWI_Start_Transceiver_With_Data(messageBuf, 3); }
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; }
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; } } }
// Write byte to IMU through TWI void TWI_Write(unsigned char reg, unsigned char data){ // reg= Direction de registro, data= data to write 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. messageBuf[2] = data; // Data to Write to IMU. TWI_Start_Transceiver_With_Data( messageBuf, 3 ); // TX Reg+Data to Write IMU return; }
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; } } } }
/***************************************************************************//** * @brief Sets the speed depending on the position of the Left slider * @param Speed This is the speed value we want to set * @return None * @date 4.11.2013 *******************************************************************************/ void Set_Speed(unsigned char Speed) { //Array[0] = Address of the DAC //Array[1] = Select channel from the DAC to be the output //Array[2] = Output value unsigned char TWI_Message_to_DAC [3] = {DAC_MAX520_ADDR_WRITE, 0x00, 0x00}; //Just send the data received from Node 1 to the DAC //The data coming from the sliders is already in a range of 0 to 255, which is the same range needed for the DAC TWI_Message_to_DAC[2] = Speed; TWI_Start_Transceiver_With_Data(TWI_Message_to_DAC,0x03); }
static void sensor_set_address_pointer(uchar reg) { // {{{ // Sets the sensor internal register pointer. // This is required before reading registers. // // This function is non-blocking (except if TWI is already busy). uchar msg[2]; msg[0] = SENSOR_I2C_WRITE_ADDRESS; msg[1] = reg; TWI_Start_Transceiver_With_Data(msg, 2); } // }}}
static void sensor_set_register_value(uchar reg, uchar value) { // {{{ // Sets one of those 3 writable registers to a value. // Only useful for configuration. // // This function is non-blocking (except if TWI is already busy). uchar msg[3]; msg[0] = SENSOR_I2C_WRITE_ADDRESS; msg[1] = reg; msg[2] = value; TWI_Start_Transceiver_With_Data(msg, 3); } // }}}
//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; }
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(); } }
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; } } // }}}
unsigned char TWI_Act_On_Failure_In_Last_Transmission ( unsigned char TWIerrorMsg ) { // A failure has occurred, use TWIerrorMsg to determine the nature of the failure // and take appropriate actions. // See header file for a list of possible failures messages. unsigned char responseBuf[1]; //return the error message to the master responseBuf[0] = TWIerrorMsg; TWI_Start_Transceiver_With_Data( responseBuf, 1 ); return TWIerrorMsg; }
// 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 }
//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; }
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; } }
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; } }
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. } }
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() ); } } } }
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() ); } } } }
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); } }
void motor_update (uint8_t output) { messageBuf[2] = output; TWI_Start_Transceiver_With_Data (messageBuf, 3); }
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. } }
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; } } // }}}