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; } } } }
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(); } }
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(); } }
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; } } // }}}
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(); } }
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; } } }
//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; }
/* 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; }
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(); } }
// 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 }
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); } }
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() ); } } } }
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; } } // }}}
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() ); } } } }
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[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[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. } }