static void send_and_receive(void) { uint8_t cmd[3]; uint8_t resp[2]; cmd[0] = TMP105_REG_TEMPERATURE; i2c_send(i2c, addr, cmd, 1); i2c_recv(i2c, addr, resp, 2); g_assert_cmpuint(((uint16_t)resp[0] << 8) | resp[1], ==, 0); cmd[0] = TMP105_REG_CONFIG; cmd[1] = 0x0; /* matches the reset value */ i2c_send(i2c, addr, cmd, 2); i2c_recv(i2c, addr, resp, 1); g_assert_cmphex(resp[0], ==, cmd[1]); cmd[0] = TMP105_REG_T_LOW; cmd[1] = 0x12; cmd[2] = 0x34; i2c_send(i2c, addr, cmd, 3); i2c_recv(i2c, addr, resp, 2); g_assert_cmphex(resp[0], ==, cmd[1]); g_assert_cmphex(resp[1], ==, cmd[2]); cmd[0] = TMP105_REG_T_HIGH; cmd[1] = 0x42; cmd[2] = 0x31; i2c_send(i2c, addr, cmd, 3); i2c_recv(i2c, addr, resp, 2); g_assert_cmphex(resp[0], ==, cmd[1]); g_assert_cmphex(resp[1], ==, cmd[2]); }
void smbus_write_byte(i2c_bus *bus, int addr, uint8_t command, uint8_t data) { i2c_start_transfer(bus, addr, 0); i2c_send(bus, command); i2c_send(bus, data); i2c_end_transfer(bus); }
/* * TODO! */ void RTC_WRITE(unsigned char WordAdr, unsigned char Data) { i2c_start(); // START condition i2c_send(RTC_ADR_W); // Send a PCF8583 address to write i2c_send(WordAdr); // Send on bus Word Address i2c_send(Data); // Send on bus Data i2c_stop(); // STOP condition }
int eeprom_save(void) { printf("Saving EEPROM data by 16 bytes pages...\n"); // load eeprom by pages of 32 bytes each int counter = 0; for (int i = 0; i < CONFIG_EEPROM_SIZE / 16; i++) { // set address i2c_start(I2C_Direction_Transmitter, CONFIG_EEPROM_ADDRESS); i2c_send(counter >> 8); i2c_send(counter & 0xFF); // write data for (int j = 0; j < 16; j++) { i2c_send(eeprom_map[counter++]); } I2C_GenerateSTOP(I2C1, ENABLE); while (!(I2C1->SR1 & I2C_SR1_BTF)) { uint8_t data = I2C1->DR; data++; } // wait for EEPROM to catch bytes delay_ms(20); early_putc('*'); } printf("\nDone.\n"); return 0; }
/*! \brief i2c master read byte. * Read a byte from the slave with a stop at the end. * \param addr address of the slave. * \param byte pre-allocated byte. * \return 1 - value OK, 0 - Error. */ uint8_t i2c_master_read_b(const uint8_t addr, uint8_t *byte, const uint8_t stop) { uint8_t err; err = i2c_send(START, 0); if ((err == TW_START) || (err == TW_REP_START)) err = i2c_send(SLA, addr | READ); /* send an ACK to start the TX */ if (err == TW_MR_SLA_ACK) err = i2c_send(ACK, 0); if (err == TW_MR_DATA_ACK) { *byte = TWDR; err = i2c_send(NACK, 0); } if (err == TW_MR_DATA_NACK) err = 0; if (stop) i2c_send(STOP, 0); return(err); }
void smbus_write_word(i2c_bus *bus, int addr, uint8_t command, uint16_t data) { i2c_start_transfer(bus, addr, 0); i2c_send(bus, command); i2c_send(bus, data & 0xff); i2c_send(bus, data >> 8); i2c_end_transfer(bus); }
/* * TODO! */ unsigned char RTC_READ(unsigned char WordAdr) { unsigned char byte; i2c_start(); // START condition i2c_send(RTC_ADR_W); // Send a PCF8583 address to write i2c_send(WordAdr); // Send on bus Word Address i2c_start(); // START condition i2c_send(RTC_ADR_R); // Send a PCF8583 address to read byte = i2c_take(); // Read the byte from I2C-bus i2c_stop(); // STOP condition return(byte); // Results }
int main(void) { uart_init(); i2c_init(); i2c_start(0x74); i2c_send(0x00); i2c_send(0x25); i2c_send(0x06); i2c_send(0x24); i2c_send(0x0F); i2c_stop(); uart_getchar(); i2c_start(0x74); i2c_send(0x40); i2c_send(0xC1); i2c_send(0xC2); i2c_stop(); while(1 > 0) { } return 0; }
void smbus_write_block(i2c_bus *bus, int addr, uint8_t command, uint8_t *data, int len) { int i; if (len > 32) len = 32; i2c_start_transfer(bus, addr, 0); i2c_send(bus, command); i2c_send(bus, len); for (i = 0; i < len; i++) i2c_send(bus, data[i]); i2c_end_transfer(bus); }
irom static app_action_t application_function_i2c_write(application_parameters_t ap) { uint16_t src_current, dst_current; i2c_error_t error; uint8_t bytes[32]; for(src_current = 1, dst_current = 0; (src_current < ap.nargs) && (dst_current < sizeof(bytes)); src_current++, dst_current++) { bytes[dst_current] = (uint8_t)strtoul((*ap.args)[src_current], 0, 16); } if((error = i2c_send(i2c_address, dst_current, bytes)) != i2c_error_ok) { i2c_error_format_string("i2c-write", error, ap.size, ap.dst); strlcat(ap.dst, "\n", ap.size); i2c_reset(); return(app_action_error); } snprintf(ap.dst, ap.size, "i2c_write: written %u bytes to %02x\n", dst_current, i2c_address); return(app_action_normal); }
int eps_slave_hk2(struct command_context *ctx) { printf("Requesting EPS HK2 data\r\n"); eps_hk_t * chkparam; i2c_frame_t * frame; frame = csp_buffer_get(I2C_MTU); frame->dest = slave_node; frame->data[0] = EPS_PORT_HK; frame->data[1] = 0; frame->len = 2; frame->len_rx = 2 + (uint8_t) sizeof(eps_hk_t); frame->retries = 0; if (i2c_send(0, frame, 0) != E_NO_ERR) { csp_buffer_free(frame); return CMD_ERROR_NOMEM; } if (i2c_receive(0, &frame, 20) != E_NO_ERR) return CMD_ERROR_FAIL; chkparam = (eps_hk_t *)&frame->data[2]; eps_hk_unpack(chkparam); eps_hk_print(chkparam); csp_buffer_free(frame); return CMD_ERROR_NONE; }
int eps_slave_ping(struct command_context *ctx) { i2c_frame_t * frame; frame = csp_buffer_get(I2C_MTU); frame->dest = slave_node; frame->data[0] = CSP_PING; // Ping port frame->data[1] = 0x55; frame->len = 2; frame->len_rx = 3; frame->retries = 0; if (i2c_send(0, frame, 0) != E_NO_ERR) { csp_buffer_free(frame); return CMD_ERROR_NOMEM; } if (i2c_receive(0, &frame, 20) == E_NO_ERR) { printf("Received a reply from EPS!\r\n"); } else { printf("No reply from EPS\r\n"); } csp_buffer_free(frame); return CMD_ERROR_NONE; }
irom static io_error_t read_register(string_t *error_message, int address, int reg, int *value) { uint8_t i2cbuffer[2]; i2c_error_t error; i2cbuffer[0] = reg; if((error = i2c_send(address, 1, &i2cbuffer[0])) != i2c_error_ok) { if(error_message) i2c_error_format_string(error_message, error); return(io_error); } if((error = i2c_receive(address, 1, &i2cbuffer[1])) != i2c_error_ok) { if(error_message) i2c_error_format_string(error_message, error); return(io_error); } *value = i2cbuffer[1]; return(io_ok); }
int eps_slave_volt(struct command_context *ctx) { char * args = command_args(ctx); unsigned int pv1, pv2, pv3; if (sscanf(args, "%u %u %u", &pv1, &pv2, &pv3) != 3) return CMD_ERROR_SYNTAX; printf("PV1: %04d PV2: %04d PV3: %04d\r\n", pv1, pv2, pv3); uint16_t pvolt[3]; pvolt[0] = csp_hton16(pv1); pvolt[1] = csp_hton16(pv2); pvolt[2] = csp_hton16(pv3); i2c_frame_t * frame; frame = csp_buffer_get(I2C_MTU); frame->dest = slave_node; frame->data[0] = EPS_PORT_SET_VBOOST; // Ping port memcpy(&frame->data[1], &pvolt, 3 * sizeof(uint16_t)); frame->len = 1 + 3 * sizeof(uint16_t); frame->len_rx = 0; frame->retries = 0; if (i2c_send(0, frame, 0) != E_NO_ERR) { csp_buffer_free(frame); return CMD_ERROR_NOMEM; } return CMD_ERROR_NONE; }
int eps_slave_ppt_mode(struct command_context *ctx) { char * args = command_args(ctx); unsigned int mode; printf("EPS_PPT_MODE_OFF = 0, EPS_PPT_MODE_AUTO = 1, EPS_PPT_MODE_FIXED= 2\r\n"); if (sscanf(args, "%d", &mode) != 1) return CMD_ERROR_SYNTAX; printf("Mode %d\r\n", mode); i2c_frame_t * frame; frame = csp_buffer_get(I2C_MTU); frame->dest = slave_node; frame->data[0] = EPS_PORT_SET_PPTMODE; // Ping port frame->data[1] = (uint8_t)mode; frame->len = 2; frame->len_rx = 0; frame->retries = 0; if (i2c_send(0, frame, 0) != E_NO_ERR) { csp_buffer_free(frame); return CMD_ERROR_NOMEM; } return CMD_ERROR_NONE; }
int eps_slave_output(struct command_context *ctx) { char * args = command_args(ctx); unsigned int outputs; printf("console args: %s\r\n", args); if (sscanf(args, "%X", &outputs) != 1) return CMD_ERROR_SYNTAX; printf("Outputs 0x%02X\r\n", outputs); i2c_frame_t * frame; frame = csp_buffer_get(I2C_MTU); frame->dest = slave_node; frame->data[0] = EPS_PORT_SET_OUTPUT; // Ping port frame->data[1] = outputs; frame->len = 2; frame->len_rx = 0; frame->retries = 0; if (i2c_send(0, frame, 0) != E_NO_ERR) { csp_buffer_free(frame); return CMD_ERROR_NOMEM; } return CMD_ERROR_NONE; }
int eps_slave_single_output(struct command_context *ctx) { char * args = command_args(ctx); unsigned int channel; unsigned int mode; int delay; printf("Input channel, mode (0=off, 1=on), and delay\r\n"); if (sscanf(args, "%u %u %d", &channel, &mode, &delay) != 3) return CMD_ERROR_SYNTAX; printf("Channel %d is set to %d with delay %d\r\n", channel, mode, delay); eps_output_set_single_req eps_switch; eps_switch.channel = (uint8_t)channel; eps_switch.mode = (uint8_t)mode; eps_switch.delay = csp_hton16((int16_t)delay); i2c_frame_t * frame; frame = csp_buffer_get(I2C_MTU); frame->dest = slave_node; frame->data[0] = EPS_PORT_SET_SINGLE_OUTPUT; // Ping port memcpy(&frame->data[1], &eps_switch, sizeof(eps_switch)); frame->len = 1 + sizeof(eps_switch); frame->len_rx = 0; frame->retries = 0; if (i2c_send(0, frame, 0) != E_NO_ERR) { csp_buffer_free(frame); return CMD_ERROR_NOMEM; } return CMD_ERROR_NONE; }
void initialize_i2c(void) { i2c_str i2c_h; i2c_msg_str msg; uint8_t tab[2]; i2c_init_str i2c; i2c.i2c_clock_val = 15; i2c.op_mode = I2C_MASTER; i2c.own_address = 0; i2c.rx_buffer_size = 6; i2c.tx_buffer_size = 2; i2c_h = i2c_init(&i2c); msg.destination_address = 0b1101000; msg.generate_stop_after_transmission = 1; msg.i2c_buffer = (uint8_t*)&tab; msg.i2c_buffer_length = 2; msg.i2c_op_mode = I2C_MASTER; tab[0] = 0x68; tab[1] = 0x10; i2c_enable(i2c_h); i2c_send(i2c_h, &msg); }
// Write address void LED_writeReg( uint8_t bus, uint8_t addr, uint8_t reg, uint8_t val, uint8_t page ) { /* info_msg("I2C Write bus("); printHex( bus ); print(")addr("); printHex( addr ); print(")reg("); printHex( reg ); print(")val("); printHex( val ); print(")page("); printHex( page ); print(")" NL); */ // Reg Write Setup uint16_t writeData[] = { addr, reg, val }; // Setup page LED_setupPage( bus, addr, page ); // Write register while ( i2c_send( bus, writeData, sizeof( writeData ) / 2 ) == -1 ) delay_us( ISSI_SendDelay ); // Delay until written while ( i2c_busy( bus ) ) delay_us( ISSI_SendDelay ); }
// Write register on all ISSI chips // Prepare pages first, then attempt write register with a minimal delay between chips void LED_syncReg( uint8_t reg, uint8_t val, uint8_t page ) { // Setup each of the pages for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) { LED_setupPage( LED_ChannelMapping[ ch ].bus, LED_ChannelMapping[ ch ].addr, page ); } // Reg Write Setup uint16_t writeData[] = { 0, reg, val }; // Write to all the registers for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ ) { writeData[0] = LED_ChannelMapping[ ch ].addr; uint8_t bus = LED_ChannelMapping[ ch ].bus; // Delay very little to help with synchronization while ( i2c_send( bus, writeData, sizeof( writeData ) / 2 ) == -1 ) delay_us(10); } // Delay until written while ( i2c_any_busy() ) delay_us( ISSI_SendDelay ); }
irom static app_action_t application_function_i2c_write(const string_t *src, string_t *dst) { i2c_error_t error; static uint8_t bytes[32]; int current, out; for(current = 0; current < (int)sizeof(bytes); current++) { if(parse_int(current + 1, src, &out, 16) != parse_ok) break; bytes[current] = (uint8_t)(out & 0xff); } if((error = i2c_send(i2c_address, current, bytes)) != i2c_error_ok) { string_cat(dst, "i2c_write"); i2c_error_format_string(dst, error); string_cat(dst, "\n"); i2c_reset(); return(app_action_error); } string_format(dst, "i2c_write: written %d bytes to %02x\n", current, i2c_address); return(app_action_normal); }
int csp_i2c_tx(csp_packet_t * packet, uint32_t timeout) { /* Cast the CSP packet buffer into an i2c frame */ i2c_frame_t * frame = (i2c_frame_t *) packet; /* Insert destination node into the i2c destination field */ if (csp_route_get_nexthop_mac(packet->id.dst) == CSP_NODE_MAC) { frame->dest = packet->id.dst; } else { frame->dest = csp_route_get_nexthop_mac(packet->id.dst); } /* Save the outgoing id in the buffer */ packet->id.ext = csp_hton32(packet->id.ext); /* Add the CSP header to the I2C length field */ frame->len += sizeof(packet->id); frame->len_rx = 0; /* Some I2C drivers support X number of retries * CSP don't care about this. If it doesn't work the first * time, don'y use time on it. */ frame->retries = 0; /* enqueue the frame */ if (i2c_send(csp_i2c_handle, frame, timeout) != E_NO_ERR) return CSP_ERR_DRIVER; return CSP_ERR_NONE; }
// Write ISSI page void LED_sendPage( uint8_t bus, uint8_t addr, uint16_t *buffer, uint32_t len, uint8_t page ) { /* info_msg("I2C Send Page: bus("); printHex( bus ); print(")addr("); printHex( addr ); print(")len("); printHex( len ); print(")page("); printHex( page ); print(")data[]("); for ( uint8_t c = 0; c < 9; c++ ) { printHex( buffer[c] ); print(" "); } print("..)" NL); */ // Page Setup LED_setupPage( bus, addr, page ); // Write page to I2C Tx Buffer while ( i2c_send( bus, buffer, len ) == -1 ) delay_us( ISSI_SendDelay ); }
int eeprom_load(void) { printf("Loading EEPROM data by 16 bytes pages...\n"); // load eeprom by pages of 16 bytes each int counter = 0x00; for (int i = 0; i < CONFIG_EEPROM_SIZE / 16; i++) { // set address i2c_start(I2C_Direction_Transmitter, CONFIG_EEPROM_ADDRESS); i2c_send(counter >> 8); i2c_send(counter & 0xFF); // read data i2c_restart(I2C_Direction_Receiver, CONFIG_EEPROM_ADDRESS); for (int j = 0; j < 15; j++) { eeprom_map[counter++] = i2c_recv_ack(); } // stop condition eeprom_map[counter++] = i2c_recv_nack(); early_putc('*'); } printf("\nDone.\n"); return 0; }
/* * The state machine needs some refinement. It is only used to track * invalid STOP commands for the moment. */ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value) { bus->cmd &= ~0xFFFF; bus->cmd |= value & 0xFFFF; if (bus->cmd & I2CD_M_START_CMD) { uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ? I2CD_MSTARTR : I2CD_MSTART; aspeed_i2c_set_state(bus, state); if (i2c_start_transfer(bus->bus, extract32(bus->buf, 1, 7), extract32(bus->buf, 0, 1))) { bus->intr_status |= I2CD_INTR_TX_NAK; } else { bus->intr_status |= I2CD_INTR_TX_ACK; } /* START command is also a TX command, as the slave address is * sent on the bus */ bus->cmd &= ~(I2CD_M_START_CMD | I2CD_M_TX_CMD); /* No slave found */ if (!i2c_bus_busy(bus->bus)) { return; } aspeed_i2c_set_state(bus, I2CD_MACTIVE); } if (bus->cmd & I2CD_M_TX_CMD) { aspeed_i2c_set_state(bus, I2CD_MTXD); if (i2c_send(bus->bus, bus->buf)) { bus->intr_status |= (I2CD_INTR_TX_NAK); i2c_end_transfer(bus->bus); } else { bus->intr_status |= I2CD_INTR_TX_ACK; } bus->cmd &= ~I2CD_M_TX_CMD; aspeed_i2c_set_state(bus, I2CD_MACTIVE); } if ((bus->cmd & (I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST)) && !(bus->intr_status & I2CD_INTR_RX_DONE)) { aspeed_i2c_handle_rx_cmd(bus); } if (bus->cmd & I2CD_M_STOP_CMD) { if (!(aspeed_i2c_get_state(bus) & I2CD_MACTIVE)) { qemu_log_mask(LOG_GUEST_ERROR, "%s: abnormal stop\n", __func__); bus->intr_status |= I2CD_INTR_ABNORMAL; } else { aspeed_i2c_set_state(bus, I2CD_MSTOP); i2c_end_transfer(bus->bus); bus->intr_status |= I2CD_INTR_NORMAL_STOP; } bus->cmd &= ~I2CD_M_STOP_CMD; aspeed_i2c_set_state(bus, I2CD_IDLE); } }
irom i2c_error_t i2c_send_1(int address, int byte0) { uint8_t bytes[1]; bytes[0] = byte0; return(i2c_send(address, 1, bytes)); }
void driver_reset_pos() { driver_buffer[0] = DRIVER_ADDRESS; driver_buffer[1] = 116; // Send 't' to motor, resets tacho i2c_send(driver_buffer, 2); driver_pos_overflows = 0; driver_last_pos = 0; }
// This is for the MCP4451 I2C based digipot void digipot_i2c_set_current(int channel, float current) { current = min( (float) max( current, 0.0f ), DIGIPOT_I2C_MAX_CURRENT); // these addresses are specific to Azteeg X3 Pro, can be set to others, // In this case first digipot is at address A0=0, A1= 0, second one is at A0=0, A1= 1 byte addr = 0x2C; // channel 0-3 if (channel >= 4) { addr = 0x2E; // channel 4-7 channel -= 4; } // Initial setup i2c_send(addr, 0x40, 0xff); i2c_send(addr, 0xA0, 0xff); // Set actual wiper value byte addresses[4] = { 0x00, 0x10, 0x60, 0x70 }; i2c_send(addr, addresses[channel], current_to_wiper(current)); }
irom i2c_error_t i2c_send_2(int address, int byte0, int byte1) { uint8_t bytes[2]; bytes[0] = byte0; bytes[1] = byte1; return(i2c_send(address, 2, bytes)); }
// Enables given page // IS31FL3733 requires unlocking the 0xFD register void LED_setupPage( uint8_t bus, uint8_t addr, uint8_t page ) { #if ISSI_Chip_31FL3733_define == 1 // See http://www.issi.com/WW/pdf/31FL3733.pdf Table 3 Page 12 uint16_t pageEnable[] = { addr, 0xFE, 0xC5 }; while ( i2c_send( bus, pageEnable, sizeof( pageEnable ) / 2 ) == -1 ) delay_us( ISSI_SendDelay ); #endif // Setup page uint16_t pageSetup[] = { addr, 0xFD, page }; while ( i2c_send( bus, pageSetup, sizeof( pageSetup ) / 2 ) == -1 ) delay_us( ISSI_SendDelay ); // Delay until written while ( i2c_busy( bus ) ) delay_us( ISSI_SendDelay ); }