static uint8_t mma7455_read_reg(struct mma7455 *self, uint8_t reg){ uint8_t data; i2c_start_write(self->i2c, self->addr, ®, 1); i2c_start_read(self->i2c, self->addr, &data, 1); i2c_stop(self->i2c); return data; }
static void clear_display(void) { matrix_clear(&display); // Clear all of the display bits (there can be random noise // in the RAM on startup) send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1); send_cmd3(ColumnAddr, 0, DisplayWidth - 1); if (i2c_start_write(SSD1306_ADDRESS)) { goto done; } if (i2c_master_write(0x40)) { // Data mode goto done; } for (uint8_t row = 0; row < MatrixRows; ++row) { for (uint8_t col = 0; col < DisplayWidth; ++col) { i2c_master_write(0); } } display.dirty = false; done: i2c_master_stop(); }
void mma7455_init(struct mma7455 *self, i2c_dev_t i2c, uint8_t addr, uint8_t mode) { self->i2c = i2c; self->addr = addr; self->mode = mode; uint8_t data[2] = {0x16, MMA7455_RANGE}; i2c_start_write(i2c, addr, data, 2); i2c_stop(i2c); }
void matrix_render(struct CharacterMatrix *matrix) { last_flush = timer_read(); iota_gfx_on(); #if DEBUG_TO_SCREEN ++displaying; #endif // Move to the home position send_cmd3(PageAddr, 0, MatrixRows - 1); send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1); if (i2c_start_write(SSD1306_ADDRESS)) { goto done; } if (i2c_master_write(0x40)) { // Data mode goto done; } for (uint8_t row = 0; row < MatrixRows; ++row) { for (uint8_t col = 0; col < MatrixCols; ++col) { const uint8_t *glyph = font + (matrix->display[row][col] * FontWidth); for (uint8_t glyphCol = 0; glyphCol < FontWidth; ++glyphCol) { uint8_t colBits = pgm_read_byte(glyph + glyphCol); i2c_master_write(colBits); } // 1 column of space between chars (it's not included in the glyph) //i2c_master_write(0); } } matrix->dirty = false; done: i2c_master_stop(); #if DEBUG_TO_SCREEN --displaying; #endif }
// Write command sequence. // Returns true on success. static inline bool _send_cmd1(uint8_t cmd) { bool res = false; if (i2c_start_write(SSD1306_ADDRESS)) { xprintf("failed to start write to %d\n", SSD1306_ADDRESS); goto done; } if (i2c_master_write(0x0 /* command byte follows */)) { print("failed to write control byte\n"); goto done; } if (i2c_master_write(cmd)) { xprintf("failed to write command %d\n", cmd); goto done; } res = true; done: i2c_master_stop(); return res; }
/* * i2c state machine * returns 0 when state == IDLE */ uint8_t i2c_async_run(void){ uint8_t i2c_stat; switch(i2c_a.state){ case I2C_IDLE: if(i2c_a.connecting){ // if connecting => start connection i2c_send_start_condition(); set_state(I2C_SENDING_START_CONDITON); } else if(i2c_a.stop &&(i2c_a.stop_forced || (!i2c_a.operation && i2c_a.connected))){ i2c_send_stop_condition(); set_state(I2C_SENDING_STOP_CONDITION); } else { switch(i2c_a.operation){ case NONE: break; case READ_BYTE_ACK: case READ_WORD: // the first read action of read_word and read_array is always a read_ack case READ_ARRAY: i2c_start_read_ack(); // if read_ack, issue command, set state to I2C_READING set_state(I2C_READING); break; case READ_BYTE_NAK: // if read_nak, issue command, set state to I2C_READING i2c_start_read_nak(); set_state(I2C_READING); break; case WRITE: // if read, issue command, set state to I2C_WRITING i2c_start_write(i2c_a.b1); set_state(I2C_WRITING); break; case WRITE_2: i2c_start_write(i2c_a.b2); set_state(I2C_WRITING); break; } } break; case I2C_SENDING_START_CONDITON: if(i2c_trans_completed){ // if transmission has been completed i2c_stat = TW_STATUS; // read i2c status if((i2c_stat != TW_START) && (i2c_stat != TW_REP_START)) error(); //if there is an error => return and set state i2c_start_send_address(i2c_a.address); // start sending address set_state(I2C_SENDING_ADDRESS); // set state to I2C_SENDING_ADDRESS } break; case I2C_SENDING_ADDRESS: if(i2c_trans_completed){ // if transmission has been completed i2c_stat = TW_STATUS; // read i2c status if(!i2c_a.start_wait && (i2c_stat != TW_MT_SLA_ACK) && (i2c_stat != TW_MR_SLA_ACK)) error(); //if there is an error => return and set state if(i2c_a.start_wait && ((i2c_stat == TW_MT_SLA_NACK )||(i2c_stat ==TW_MR_DATA_NACK))){ i2c_send_stop_condition(); // if device bussy => send stop condition set_state(I2C_WAITING_FOR_DEVICE); } else { i2c_a.connecting = false; // if there was no error => connected => go to idle i2c_a.connected = true; i2c_a.start_wait = false; set_state(I2C_IDLE); } } break; case I2C_WAITING_FOR_DEVICE: if(!i2c_stop_trans_not_completed){ // if transmission has been completed set_state(I2C_IDLE); // restart connect } break; case I2C_SENDING_STOP_CONDITION: if(!i2c_stop_trans_not_completed){ // if transmission has been completed i2c_a.connected = false; i2c_a.stop = false; end_operation(); } break; case I2C_READING: if(i2c_trans_completed){ // if transmission has been completed switch(i2c_a.operation){ case READ_BYTE_ACK: // if reading byte value case READ_BYTE_NAK: i2c_a.b1 = TWDR; // save byte in byte value end_operation(); // done => set operation to NONE and go to IDLE break; case READ_WORD: if(i2c_a.reading_msb){ i2c_a.w = (TWDR<<8); // save msb i2c_a.reading_msb = false; // not reading msb anymore i2c_start_read_nak(); // start reading again set_state(I2C_READING); // set corresponding state } else { i2c_a.w |= TWDR; end_operation(); // done => set operation to NONE and go to IDLE } break; case READ_ARRAY: //deb_b(i2c_a.array_length); if(i2c_a.reading_msb){ *i2c_a.array = ((TWDR & i2c_a.bit_mask)<<8);// save msb i2c_a.reading_msb = false; // not reading msb anymore if(i2c_a.array_length < 2){ // if length = 1 i2c_start_read_nak(); // start reading again } else { i2c_start_read_ack(); // start reading again } set_state(I2C_READING); // set corresponding state } else{ *i2c_a.array |= TWDR; // save lsb if(i2c_a.array_length < 2){ // if length = 1 end_operation(); // done => set operation to NONE and go to IDLE } else { if(i2c_a.array_length == i2c_a.array_omit_value){ i2c_a.array_omit_value = -1; } else { i2c_a.array++; // move array pointer i2c_a.array_length--; // decrease length to be read } i2c_a.reading_msb = true; // read msb next i2c_start_read_ack(); // start reading again set_state(I2C_READING); // set corresponding state } } break; case WRITE: case WRITE_2: case NONE: break; } } break; case I2C_WRITING: if(i2c_trans_completed){ // if transmission has been completed i2c_stat = TW_STATUS; // read i2c status if(i2c_stat != TW_MT_DATA_ACK) error();// if there is an error => return and set state if(i2c_a.operation == WRITE_2){ i2c_a.operation = WRITE; set_state(I2C_IDLE); } else{ end_operation(); // if there is no error => done => set operation to NONE and go to IDLE } } break; case I2C_FAILED: i2c_a.failed = true; end_operation(); break; default: set_state(I2C_IDLE); break; } return (i2c_a.state || i2c_a.start_wait || i2c_a.operation || i2c_a.stop) && !i2c_a.failed; }