int ad_i2c_sync(void) { int i; int ret = -1; unsigned char sync[4] = {0x80, 0x00, 0x00, 0x00}; unsigned char res[4] = {0x00, 0x00, 0x00, 0x00}; if (ad_i2c_write(sync, 4) == 4) { for (i=0; i < AD_I2C_SYNC_RETRIES; i++) { if (ad_i2c_read(res, 4) == 4) { ALOGD("SYNC RES: 0x%02x%02x%02x%02x", res[0], res[1], res[2], res[3]); if ((res[0] == sync[0]) && (res[1] == sync[1]) && (res[2] == sync[2]) && (res[3] == sync[3])) { ret = 0; break; } } /* Chip has not yet a SYNC reply ready, wait before to re-read */ usleep(AD_I2C_SYNC_RETRIES_DELAY); } } else { ALOGE("%s write sync error", __func__); } ALOGD("%s [%d]", __func__, ret); return ret; }
int ad_i2c_sync(void) { #define AD_I2C_SYNC_RETRIES 20 int i; int ret = -1; unsigned char sync[4] = {0x80, 0x00, 0x00, 0x00}; unsigned char res[4] = {0x00, 0x00, 0x00, 0x00}; if (ad_i2c_write(sync, 4) == 4) { for (i=0; i < AD_I2C_SYNC_RETRIES; i++) { if (ad_i2c_read(sync, 4) == 4) { RTRAC("SYNC RES: 0x%02x%02x%02x%02x", sync[0], sync[1], sync[2], sync[3]); if ((res[0] == sync[0]) && (res[1] == sync[1]) && (res[2] == sync[2]) && (res[3] == sync[3])) { ret = 0; break; } } usleep(ad_i2c_op_delay); } } else { RERRO("ERROR: %s write sync error", __func__); } RDBUG("%s [%d]", __func__, ret); return ret; }
static void ad_proxy_worker(int usb_tty_fd) { protocol_state_t state = STATE_WAIT_COMMAND; audience_command_t audience_cmb_buf = { { 0, 0, 0, 0 } }; int data_block_session = 0; size_t data_block_size = 0; int status; int quit = 0; while (quit == 0) { ALOGD("State: %d", state); switch (state) { default: case STATE_WAIT_COMMAND: { // Read a command from AuViD status = full_read(usb_tty_fd, audience_cmb_buf.bytes, sizeof(audience_cmb_buf.bytes)); if (status != sizeof(audience_cmb_buf.bytes)) { ALOGE("%s Read CMD from AuViD failed\n", __func__); quit = 1; break; } if (get_command_opcode(&audience_cmb_buf) == AD_BAUD_RATE_OPCODE) { // In normal operation, the baud rate command is used as handshake command by // AuViV. This command shall be ignored and just returned back as it to AuViD. status = full_write(usb_tty_fd, audience_cmb_buf.bytes, sizeof(audience_cmb_buf.bytes)); if (status != sizeof(audience_cmb_buf.bytes)) { ALOGE("%s Write to AuVid failed\n", __func__); quit = 1; break; } state = STATE_WAIT_COMMAND; } else { // Otherwise, we need to forward the command to the chip state = STATE_WRITE_COMMAND; } break; } case STATE_WRITE_COMMAND: { // Write the command to the chip status = ad_i2c_write(audience_cmb_buf.bytes, sizeof(audience_cmb_buf.bytes)); if (status != sizeof(audience_cmb_buf.bytes)) { ALOGE("%s Write CMD to chip failed\n", __func__); quit = 1; break; } // Is it a Data Block command ? if (get_command_opcode(&audience_cmb_buf) == AD_WRITE_DATA_BLOCK_OPCODE) { data_block_session = 1; // Block Size is in 16bits command's arg data_block_size = get_command_arg(&audience_cmb_buf); ALOGD("Starting Data Block session for %d bytes", data_block_size); } // Need to handle the chip ACK response state = STATE_READ_ACK; break; } case STATE_READ_ACK: { audience_command_t audience_cmb_ack_buf; // Wait before to read ACK usleep(AUDIENCE_ACK_US_DELAY); status = ad_i2c_read(audience_cmb_ack_buf.bytes, sizeof(audience_cmb_ack_buf.bytes)); if (status != sizeof(audience_cmb_ack_buf.bytes)) { ALOGE("%s Read ACK from chip failed\n", __func__); quit = 1; break; } // Send back the ACK to AuViD status = full_write(usb_tty_fd, audience_cmb_ack_buf.bytes, sizeof(audience_cmb_ack_buf.bytes)); if (status != sizeof(audience_cmb_ack_buf.bytes)) { ALOGE("%s Write ACK to AuVid failed\n", __func__); quit = 1; break; } if (data_block_session == 1) { // Next step is Data Block to handle state = STATE_WAIT_DATA_BLOCK; } else { // Next step is to handle a next command state = STATE_WAIT_COMMAND; } break; } case STATE_WAIT_DATA_BLOCK: { unsigned char* data_block_payload = (unsigned char *) malloc(data_block_size); if (data_block_payload == NULL) { ALOGE("%s Read Data Block memory allocation failed.\n", __func__); quit = 1; break; } // Read data block from AuViD status = full_read(usb_tty_fd, data_block_payload, data_block_size); if (status != (int)data_block_size) { ALOGE("%s Read Data Block failed\n", __func__); free(data_block_payload); quit = 1; break; } // Forward these bytes to the chip status = ad_i2c_write(data_block_payload, data_block_size); free(data_block_payload); if (status != (int)data_block_size) { ALOGE("%s Write Data Block failed\n", __func__); quit = 1; break; } // No more in data block session data_block_session = 0; // Need to handle ACK of datablock session state = STATE_READ_ACK; break; } } } }