void twi_init(void) /* short: Init AVR TWI interface and set bitrate inputs: outputs: notes: TWI clock is set to 100 kHz Version : DMK, Initial code *******************************************************************/ { TWSR = 0; TWBR = 32; // TWI clock set to 100kHz, prescaler = 0 // Init HT16K22. Page 32 datasheet twi_start(); twi_tx(0xE0); // Display I2C addres + R/W bit twi_tx(0x21); // Internal osc on (page 10 HT16K33) twi_stop(); twi_start(); twi_tx(0xE0); // Display I2C address + R/W bit twi_tx(0xA0); // HT16K33 pins all output twi_stop(); twi_start(); twi_tx(0xE0); // Display I2C address + R/W bit twi_tx(0xE3); // Display Dimming 4/16 duty cycle twi_stop(); twi_start(); twi_tx(0xE0); // Display I2C address + R/W bit twi_tx(0x81); // Display OFF - Blink On twi_stop(); }
uint8_t twi_read_byte(void) { //uint8_t databyte; twi_start(); if (twi_get_status() != 0x08) return ERROR; //select devise and send A2 A1 A0 address bits twi_write(0xD0); if (twi_get_status() != 0x18) return ERROR; twi_write(0x01); if (twi_get_status() != 0x18) return ERROR; twi_read_ack(); twi_write(0xD1); if (twi_get_status() != 0x18) return ERROR; twi_start(); twi_read_nack(); if (twi_get_status() != 0x58) return ERROR; twi_stop(); return SUCCESS; }
/** \brief This function acquires data from the L3GD20 Gyro module, via i2c communication. */ void imu::gyro_position(void) { uint8_t x_l = 0; uint8_t x_h = 0; uint8_t y_l = 0; uint8_t y_h = 0; uint8_t z_l = 0; uint8_t z_h = 0; twi_start(); // Start Condition twi_write(0b11010110); // SLA + W = 0x29 + w(0) twi_write(0x28 | 0x80); //Set Address Pointer to data register location. Setting the MSB makes sure the data autoincrements twi_start(); twi_write(0b11010111); //SLA + R = 0x29 + w(1) x_l = twi_read(1); x_h = twi_read(1); y_l = twi_read(1); y_h = twi_read(1); z_l = twi_read(1); z_h = twi_read(0); twi_stop(); x_gyro = ( (uint16_t) x_h<<8)|(x_l) ; // HUGE PROBLEM HERE. DOUBLE CHECK y_gyro = ( (uint16_t) y_h<<8)|(y_l) ; z_gyro = ( (uint16_t) z_h<<8)|(z_l) ; }
/** \brief This function acquires data from the LSM303DLHC accelerometer module. */ void imu::mag_position(void) { uint8_t x_l = 0; uint8_t x_h = 0; uint8_t z_l = 0; uint8_t z_h = 0; uint8_t y_l = 0; uint8_t y_h = 0; twi_start(); // Start Condition twi_write(0b00111100); // SLA + W = 0x29 + w(0) twi_write(0x03 | 0x80); //Set Address Pointer to data register location. Setting the MSB makes sure the data autoincrements twi_start(); twi_write(0b00111101); //SLA + R = 0x29 + w(1) x_l = twi_read(1); x_h = twi_read(1); y_l = twi_read(1); y_h = twi_read(1); z_l = twi_read(1); z_h = twi_read(0); twi_stop(); x_mag = (x_h<<8)|(x_l) ; y_mag = (y_h<<8)|(y_l) ; z_mag = (z_h<<8)|(z_l) ; }
/** * rtc_read_register() - read a register of realt time clock * * @address: address of realt time clock register * @byte: pointer to address where the read byte will be stored in * * Return: TWI_OK on success, TWI_ERR on error */ uint8_t rtc_read_register(uint8_t address, uint8_t* byte) { rtc_disable_avr_interrupt(); uint8_t ret = 0; ret |= twi_start(); if (ret != TWI_OK) goto rtc_read_register_exit; ret |= twi_send_slave_address(TWI_WRITE, RTC_ADDRESS); if (ret != TWI_OK) goto rtc_read_register_exit; ret |= twi_send_byte(address); if (ret != TWI_OK) goto rtc_read_register_exit; ret |= twi_start(); if (ret != TWI_OK) goto rtc_read_register_exit; ret |= twi_send_slave_address(TWI_READ, RTC_ADDRESS); if (ret != TWI_OK) goto rtc_read_register_exit; ret |= twi_read_byte(TWI_NACK, byte); twi_stop(); rtc_read_register_exit: if (during_bitmask == FALSE) { rtc_enable_avr_interrupt(); } return ret; }
int main( void ) { twi_init(); // Init TWI interface // Init HT16K22. Page 32 datasheet twi_start(); twi_tx(0xE0); // Display I2C addres + R/W bit twi_tx(0x21); // Internal osc on (page 10 HT16K33) twi_stop(); twi_start(); twi_tx(0xE0); // Display I2C address + R/W bit twi_tx(0xA0); // HT16K33 pins all output twi_stop(); twi_start(); twi_tx(0xE0); // Display I2C address + R/W bit twi_tx(0xE3); // Display Dimming 4/16 duty cycle twi_stop(); twi_start(); twi_tx(0xE0); // Display I2C address + R/W bit twi_tx(0x81); // Display OFF - Blink On twi_stop(); twi_clear(); play_fill_animation(); clear_rows(); return 1; }
char lsm303_whoami() { char a; twi_start(); twi_send_address(LSM303::ADDRW); //write twi_send_data(LSM303::WHO_AM_I); //WHOAMI twi_start(); twi_send_address(LSM303::ADDRR); //read twi_read_data(&a, 0); twi_stop(); return a; }
uint8_t i2c_readByte( uint8_t dev_addr, uint8_t data_addr ){ uint8_t data; twi_start( ); twi_send( I2C_ADDR_WRITE(dev_addr) ); twi_send( data_addr ); twi_start( ); twi_send( I2C_ADDR_READ(dev_addr) ); data = twi_recv( 0 ); twi_stop(); return data; }
uint16_t twi_read_2byte(uint8_t addr) { uint32_t tmp; twi_start(); twi_write(addr << 1); /* slave addr */ twi_write(0x00); /* register addr */ twi_stop(); twi_start(); twi_write((addr << 1) | 0x1);/* slave addr + read */ tmp = twi_read(); tmp = (tmp << 8) | twi_read(); twi_stop(); return (tmp & 0xffff); }
int32_t lps25h_read() { char xl, l, h; twi_start(); twi_send_address(LPS25H::ADDRW); twi_send_data(LPS25H::PRESS_OUT_XL|(1<<7)); twi_start(); twi_send_address(LPS25H::ADDRR); //read twi_read_data(&xl, 1); twi_read_data(&l, 1); twi_read_data(&h, 0); twi_stop(); return ((int32_t)h << 16) | ((int32_t)l << 8) | xl; }
void twi_adc_query(void) { /* keep sampling adc data */ twi_start(TWI_ADC_ADDR<<1); /* start at AIN0, autoincrement through channels */ twi_write(1<<2 | (0 & 0x03)); twi_stop(); twi_start((TWI_ADC_ADDR<<1) | 1); twi_read(1); /* discard result code of precious cycle */ for (uint8_t adc = 0; adc < TWI_ADC_CHANNELS; adc++) { twi_adc_raw[adc] = twi_read(adc < TWI_ADC_CHANNELS-1); /* scale to 10 bit values */ twi_adc_values[adc] = twi_adc_raw[adc]<<2; } }
void acc_query(void) { uint8_t buf[6]; twi_start(ACC_ADDRESS<<1); twi_write(0x32); twi_start(ACC_ADDRESS<<1 | 1); for (uint8_t i=0; i<sizeof(buf); i++) { buf[i] = twi_read(i<sizeof(buf)-1); } twi_stop(); ACC_ORIENTATION(buf[1]<<8 | buf[0], buf[3]<<8 | buf[2], buf[5]<<8 | buf[4]); }
/** \brief This function initializes the LSM303DLHC magnetometer module, via i2c communication. */ void imu::mag_init(void) { _delay_us(1); twi_start(); twi_write(0b00111100); //Write SLA + W. twi_write(0x00); twi_write(0x14); twi_stop(); _delay_us(1); twi_start(); twi_write(0b00111100); //Write SLA + W. twi_write(0x01); twi_write(0x40); twi_stop(); }
uint8_t i2c_readBytes( uint8_t dev_addr, uint8_t data_addr, uint8_t *data, uint8_t data_len ){ uint8_t i; twi_start( ); twi_send( I2C_ADDR_WRITE(dev_addr) ); twi_send( data_addr ); twi_start( ); twi_send( I2C_ADDR_READ(dev_addr) ); for( i=0; i<data_len-1; ++i ){ data[i] = twi_recv( 1 ); } data[i] = twi_recv( 0 ); twi_stop(); return data_len; }
/* Read num bytes starting from regAddrStart. Each subsequent byte will be from the register above (newRegPtr = oldRegPtr + 1). * * Input: regAddrStart The register address to start reading bytes from * data Location to store read data * num The number of registers to be read * Return: 0 Succeeded * >0 Failed, see handle_error() for relavant error codes */ uint8_t twi_read_bytes(uint8_t regAddrStart, uint8_t *data, uint8_t num) { uint8_t i, error; /* Transmit start condition. */ if((error = twi_start())) return error; /* Transmit slave address and write bit. */ if((error = twi_sla_w(IMU_ADDR))) return error; /* Transmit to slave the register to be read. */ if((error = twi_write(regAddrStart))) return error; /* Transmit repeated start condition. */ if((error = twi_start_r())) return error; /* Transmit slave address and read bit. */ if((error = twi_sla_r(IMU_ADDR))) return error; /* Read data from slave. */ for(i = 0; i < num; i++) { if(i == num - 1) { /* Last byte, return NACK. */ if((error = twi_read_nack(&data[i]))) return error; } else { if((error = twi_read_ack(&data[i]))) return error; } } /* Transmit stop condition. */ twi_stop(); return 0; }
void write_data(int row, int column){ twi_start(); twi_tx(0xE0); // Display I2C address + R/W bit twi_tx(row); // Address twi_tx(column); //column twi_stop(); }
void bios(void) { uart_start(); pwm_setup(2); adc_start(1); twi_start(); //button code init_buttons(); //set the CPU_POW led pin to high to show we have power DDRD |= (1<<CPU_POW); PORTD |= (1<<CPU_POW); //set the status leds as outputs DDRD |= (1<<stat_led1); DDRD |= (1<<stat_led2); //if this is my dev board, pull them low because the leds are cathode #if DEV PORTD &= ~(1<<stat_led1) & ~(1<<stat_led2); #endif #if DEBUG uart_sendstr("0x01 - Hardware setup successful..."); uart_sendstr("Bios complete..."); uart_sendstr("Starting main code..."); #endif return; }
/** \brief Initialize the L3GD20 Gyro module, via i2c communication protocol. * \details This function initializes the L3GD20 Gyro to acquire data at 95Hz, over * a range of (+-)500 degrees per second. */ void imu::gyro_init(void) { _delay_us(1); twi_start(); twi_write(0b11010110); //Write SLA + W. twi_write(0x20); // Write SUB address to CTRL_REG1. twi_write(0x0F); // Set data rate to 95Hz. twi_stop(); _delay_ms(1); //_delay_us(1); twi_start(); twi_write(0b11010110); //Write SLA + W. twi_write(0x23); // Write SUB address to CTRL_REG4. twi_write(0x10); // Set range to 500degrees/second twi_stop(); }
void l3gd20h_write(char reg, char data) { twi_start(); twi_send_address(L3GD20H::ADDRW); //write twi_send_data(reg); twi_send_data(data); twi_stop(); }
void write_data(unsigned char adress,unsigned char data) { twi_start(); twi_tx(0xE0); // Display I2C addres + R/W bit twi_tx(adress); // Address twi_tx(data); // data twi_stop(); }
void lsm303_write(char reg, char data) { twi_start(); twi_send_address(LSM303::ADDRW); //write twi_send_data(reg); twi_send_data(data); twi_stop(); }
/** \brief This function initializes the LSM303DLHC accelerometer module, via i2c communication. */ void imu::accl_init(void) { _delay_us(1); twi_start(); twi_write(0b00110010); //Write SLA + W. twi_write(0x20); // Write SUB address to CTRL_REG1. twi_write(0x47); // Set data rate to 95Hz. twi_stop(); }
void twi_write_2byte(uint16_t buf, uint8_t addr) { twi_start(); twi_write(addr << 1); /* slave addr */ twi_write(0x00); /* register addr */ twi_write(buf); twi_write(buf >> 8); twi_stop(); }
uint8_t i2c_writeByte( uint8_t dev_addr, uint8_t data_addr, uint8_t data ){ twi_start( ); twi_send( I2C_ADDR_WRITE(dev_addr) ); twi_send( data_addr ); twi_send( data ); twi_stop( ); return 0; }
void l3gd20h_read(int16_t *x, int16_t *y, int16_t *z) { char xl, xh, yl, yh, zl, zh; twi_start(); twi_send_address(L3GD20H::ADDRW); twi_send_data(L3GD20H::OUT_X_L|(1<<7)); twi_start(); twi_send_address(L3GD20H::ADDRR); //read twi_read_data(&xl, 1); twi_read_data(&xh, 1); twi_read_data(&yl, 1); twi_read_data(&yh, 1); twi_read_data(&zl, 1); twi_read_data(&zh, 0); twi_stop(); *x = (int16_t)(xh << 8 | xl); *y = (int16_t)(yh << 8 | yl); *z = (int16_t)(zh << 8 | zl); }
void lps25h_init() { // 0xB0 = 0b10110000 // PD = 1 (active mode); ODR = 011 (12.5 Hz pressure & temperature output data rate) twi_start(); twi_send_address(LPS25H::ADDRW); //write twi_send_data(LPS25H::CTRL_REG1); twi_send_data(0xB0); twi_stop(); }
void lsm303_read_mag(int16_t *x, int16_t *y, int16_t *z) { char xl, xh, yl, yh, zl, zh; twi_start(); twi_send_address(LSM303::ADDRW); twi_send_data(LSM303::D_OUT_X_L_M|(1<<7)); twi_start(); twi_send_address(LSM303::ADDRR); //read twi_read_data(&xl, 1); twi_read_data(&xh, 1); twi_read_data(&yl, 1); twi_read_data(&yh, 1); twi_read_data(&zl, 1); twi_read_data(&zh, 0); twi_stop(); *x = (int16_t)(xh << 8 | xl); *y = (int16_t)(yh << 8 | yl); *z = (int16_t)(zh << 8 | zl); }
void twi_clear(void){ int i = 0x00; for(; i <=0x0E; i += 0x02){ twi_start(); twi_tx(0xE0); twi_tx(i); twi_tx(0x00); twi_stop(); } }
void twi_data(PATTERN_STRUCT pattern[]) //geeft een simpele pattern weer { twi_start(); twi_tx(0xE0); for (int i = 0; i < 8; i++) { twi_tx(pattern[i].address); twi_tx(pattern[i].data); } twi_stop(); }
void twi_data_inverse(PATTERN_STRUCT pattern[]) //geeft pattern weer (inverted) nog niet getest! { twi_start(); twi_tx(0xE0); for (int i = 0; i < 8; i++) { twi_tx(pattern[i].address); twi_tx(pattern[i].data |~(0xFF)); } twi_stop(); }