/** * \brief wake up CryptoAuth device using I2C bus * * \param[in] iface interface to logical device to wakeup * * \return ATCA_STATUS */ ATCA_STATUS hal_i2c_wake(ATCAIface iface) { ATCAIfaceCfg *cfg = atgetifacecfg(iface); int bus = cfg->atcai2c.bus; uint32_t bdrt = cfg->atcai2c.baud; uint8_t data[4], expected[4] = { 0x04, 0x11, 0x33, 0x43 }; if ( bdrt != 100000 ) // if not already at 100KHz, change it change_i2c_speed(iface, 100000); // Send 0x00 as wake pulse i2c_write(i2c_hal_data[bus]->id, 0x00, NULL, NULL); atca_delay_ms(3); // wait tWHI + tWLO which is configured based on device type and configuration structure //atca_delay_us(cfg->wake_delay); // if necessary, revert baud rate to what came in. if ( bdrt != 100000 ) change_i2c_speed(iface, cfg->atcai2c.baud); i2c_read(i2c_hal_data[bus]->id, cfg->atcai2c.slave_address, data, 4); if (memcmp(data, expected, 4) == 0) return ATCA_SUCCESS; return ATCA_COMM_FAIL; }
/** * \brief wake up CryptoAuth device using I2C bus * * \param[in] iface interface to logical device to wakeup * * \return ATCA_STATUS */ ATCA_STATUS hal_i2c_wake(ATCAIface iface) { ATCAIfaceCfg *cfg = atgetifacecfg(iface); // set to default i2c bus if (cfg->atcai2c.bus > MAX_I2C_BUSES - 1) cfg->atcai2c.bus = 0; int bus = cfg->atcai2c.bus; int retries = cfg->rx_retries; uint32_t bdrt = cfg->atcai2c.baud; int status = !TWI_SUCCESS; uint8_t data[4], expected[4] = { 0x04, 0x11, 0x33, 0x43 }; // if not already at 100kHz, change it if (bdrt != 100000) change_i2c_speed(iface, 100000); // Send 0x00 as wake pulse twi_write_byte(i2c_hal_data[bus]->twi_master_instance, 0x00); // rounded up to the nearest ms atca_delay_ms(((uint32_t)cfg->wake_delay + (1000 - 1)) / 1000); // wait tWHI + tWLO which is configured based on device type and configuration structure twi_package_t packet = { .chip = cfg->atcai2c.slave_address >> 1, .addr[0] = NULL, .addr_length = 0, .buffer = (void*)data, .length = 4 }; // if necessary, revert baud rate to what came in. if (bdrt != 100000) change_i2c_speed(iface, bdrt); while (retries-- > 0 && status != TWI_SUCCESS) status = twi_master_read(i2c_hal_data[bus]->twi_master_instance, &packet); if (status != TWI_SUCCESS) return ATCA_COMM_FAIL; if (memcmp(data, expected, 4) == 0) return ATCA_SUCCESS; return ATCA_COMM_FAIL; } /** * \brief idle CryptoAuth device using I2C bus * * \param[in] iface interface to logical device to idle * * \return ATCA_STATUS */ ATCA_STATUS hal_i2c_idle(ATCAIface iface) { ATCAIfaceCfg *cfg = atgetifacecfg(iface); // set to default i2c bus if (cfg->atcai2c.bus > MAX_I2C_BUSES - 1) cfg->atcai2c.bus = 0; int bus = cfg->atcai2c.bus; uint8_t data[4]; data[0] = 0x02; // idle word address value twi_package_t packet = { .chip = cfg->atcai2c.slave_address >> 1, .addr[0] = NULL, .addr_length = 0, .buffer = (void*)data, .length = 1 }; if (twi_master_write(i2c_hal_data[bus]->twi_master_instance, &packet) != TWI_SUCCESS) return ATCA_COMM_FAIL; return ATCA_SUCCESS; } /** * \brief sleep CryptoAuth device using I2C bus * * \param[in] iface interface to logical device to sleep * * \return ATCA_STATUS */ ATCA_STATUS hal_i2c_sleep(ATCAIface iface) { ATCAIfaceCfg *cfg = atgetifacecfg(iface); // set to default i2c bus if (cfg->atcai2c.bus > MAX_I2C_BUSES - 1) cfg->atcai2c.bus = 0; int bus = cfg->atcai2c.bus; uint8_t data[4]; data[0] = 0x01; // sleep word address value twi_package_t packet = { .chip = cfg->atcai2c.slave_address >> 1, .addr[0] = NULL, .addr_length = 0, .buffer = (void*)data, .length = 1 }; if (twi_master_write(i2c_hal_data[bus]->twi_master_instance, &packet) != TWI_SUCCESS) return ATCA_COMM_FAIL; return ATCA_SUCCESS; } /** * \brief manages reference count on given bus and releases resource if no more refences exist * * \param[in] hal_data - opaque pointer to hal data structure - known only to the HAL implementation * * \return ATCA_STATUS */ ATCA_STATUS hal_i2c_release(void *hal_data) { ATCAI2CMaster_t *hal = (ATCAI2CMaster_t*)hal_data; // set to default i2c bus if (hal->bus_index > MAX_I2C_BUSES - 1) hal->bus_index = 0; i2c_bus_ref_ct--; // track total i2c bus interface instances for consistency checking and debugging // if the use count for this bus has gone to 0 references, disable it. protect against an unbracketed release if (hal && --(hal->ref_ct) <= 0 && i2c_hal_data[hal->bus_index] != NULL) { twi_reset(hal->twi_master_instance); free(i2c_hal_data[hal->bus_index]); i2c_hal_data[hal->bus_index] = NULL; } return ATCA_SUCCESS; }
ATCA_STATUS hal_i2c_wake(ATCAIface iface) { ATCAIfaceCfg *cfg = atgetifacecfg(iface); int bus = cfg->atcai2c.bus; int retries = cfg->rx_retries; uint32_t bdrt = cfg->atcai2c.baud; int status = !STATUS_OK; uint8_t data[4], expected[4] = { 0x04, 0x11, 0x33, 0x43 }; if ( bdrt != 100000 ) // if not already at 100KHz, change it change_i2c_speed( iface, 100000 ); // Send the wake by writing to an address of 0x00 twi_package_t packet = { .addr_length = 0, // TWI slave memory address data size .chip = 0x00, // TWI slave bus address .buffer = &data[0], // transfer data source buffer .length = 0 // transfer data size (bytes) }; // Send the 00 address as the wake pulse twi_master_write(i2c_hal_data[bus]->i2c_master_instance, &packet ); // part will NACK, so don't check for status atca_delay_us(cfg->wake_delay); // wait tWHI + tWLO which is configured based on device type and configuration structure packet.chip = cfg->atcai2c.slave_address >> 1; packet.length = 4; packet.buffer = data; while ( retries-- > 0 && status != STATUS_OK ) status = twi_master_read(i2c_hal_data[bus]->i2c_master_instance, &packet); if ( status != STATUS_OK ) return ATCA_COMM_FAIL; // if necessary, revert baud rate to what came in. if ( bdrt != 100000 ) change_i2c_speed( iface, bdrt ); if ( memcmp( data, expected, 4 ) == 0 ) return ATCA_SUCCESS; return ATCA_COMM_FAIL; } /** \brief idle CryptoAuth device using I2C bus * \param[in] iface interface to logical device to idle */ ATCA_STATUS hal_i2c_idle(ATCAIface iface) { ATCAIfaceCfg *cfg = atgetifacecfg(iface); int bus = cfg->atcai2c.bus; uint8_t data[4]; twi_package_t packet = { .addr_length = 0, // TWI slave memory address data size .chip = cfg->atcai2c.slave_address >> 1, // TWI slave bus address .buffer = &data[0], // transfer data source buffer .length = 1 // transfer data size (bytes) }; data[0] = 0x02; // idle word address value if ( twi_master_write((i2c_hal_data[bus]->i2c_master_instance), &packet) != STATUS_OK ) return ATCA_COMM_FAIL; return ATCA_SUCCESS; } /** \brief sleep CryptoAuth device using I2C bus * \param[in] iface interface to logical device to sleep */ ATCA_STATUS hal_i2c_sleep(ATCAIface iface) { ATCAIfaceCfg *cfg = atgetifacecfg(iface); int bus = cfg->atcai2c.bus; uint8_t data[4]; twi_package_t packet = { .addr_length = 0, // TWI slave memory address data size .chip = cfg->atcai2c.slave_address >> 1, // TWI slave bus address .buffer = &data[0], // transfer data source buffer .length = 1 // transfer data size (bytes) }; data[0] = 0x01; // sleep word address value if ( twi_master_write((i2c_hal_data[bus]->i2c_master_instance), &packet) != STATUS_OK ) return ATCA_COMM_FAIL; return ATCA_SUCCESS; } /** \brief manages reference count on given bus and releases resource if no more refences exist * \param[in] hal_data - opaque pointer to hal data structure - known only to the HAL implementation */ ATCA_STATUS hal_i2c_release( void *hal_data ) { ATCAI2CMaster_t *hal = (ATCAI2CMaster_t*)hal_data; i2c_bus_ref_ct--; // track total i2c bus interface instances for consistency checking and debugging // if the use count for this bus has gone to 0 references, disable it. protect against an unbracketed release if ( hal && --(hal->ref_ct) <= 0 && i2c_hal_data[hal->bus_index] != NULL ) { twi_master_disable(hal->i2c_master_instance); free(i2c_hal_data[hal->bus_index]); i2c_hal_data[hal->bus_index] = NULL; } return ATCA_SUCCESS; }
/** \brief wake up CryptoAuth device using I2C bus * \param[in] interface to logical device to wakeup */ ATCA_STATUS hal_i2c_wake(ATCAIface iface) { ATCAIfaceCfg *cfg = atgetifacecfg(iface); int bus = cfg->atcai2c.bus; int retries = cfg->rx_retries; uint32_t bdrt = cfg->atcai2c.baud; uint8_t data[4], expected[4] = { 0x04,0x11,0x33,0x43 }; int status = !TWI_SUCCESS; // if not already at 100KHz, change it if (bdrt != 100000) { change_i2c_speed(iface, 100000); } // Send 0x00 as wake pulse switch(bus) { //case 0: twi_write_byte(TWI0, 0x00); break; case 0: twi_write_byte(TWI_Channel0,0);break; case 1: twi_write_byte(TWI_Channel1,0); break; } atca_delay_us(cfg->wake_delay); // wait tWHI + tWLO which is configured based on device type and configuration structure //twi_package_t packet = { twi_packet_t packet = { .chip = cfg->atcai2c.slave_address >> 1, .addr[0] = NULL, .addr_length = 0, .buffer = (void *)data, .length = 4 }; // if necessary, revert baud rate to what came in. if (bdrt != 100000) { change_i2c_speed(iface, bdrt); } switch(bus) { case 0: //if (twi_master_read(TWI0, &packet) != TWI_SUCCESS) while (retries-- > 0 && status != TWI_SUCCESS) status = twi_master_read(TWI_Channel0, &packet); /*if (twi_master_read(TWI_Channel0, &packet) != TWI_SUCCESS) { return ATCA_COMM_FAIL; }*/ break; case 1: /* if (twi_master_read(TWI_Channel1, &packet) != TWI_SUCCESS) { return ATCA_COMM_FAIL; }*/ break; } if (memcmp(data, expected, 4) == 0) { return ATCA_SUCCESS; } return ATCA_COMM_FAIL; } /** \brief idle CryptoAuth device using I2C bus * \param[in] interface to logical device to idle */ ATCA_STATUS hal_i2c_idle(ATCAIface iface) { ATCAIfaceCfg *cfg = atgetifacecfg(iface); int bus = cfg->atcai2c.bus; uint8_t data[4]; data[0] = 0x02; // idle word address value //twi_package_t packet = { twi_packet_t packet = { .chip = cfg->atcai2c.slave_address >> 1, .addr[0] = NULL, .addr_length = 0, .buffer = (void *)data, .length = 1 }; switch(bus) { case 0: //if (twi_master_write(TWI0, &packet) != TWI_SUCCESS) if (twi_master_write(TWI_Channel0, &packet) != TWI_SUCCESS) { return ATCA_COMM_FAIL; } break; case 1: if (twi_master_write(TWI_Channel1, &packet) != TWI_SUCCESS) { return ATCA_COMM_FAIL; } break; } return ATCA_SUCCESS; } /** \brief sleep CryptoAuth device using I2C bus * \param[in] interface to logical device to sleep */ ATCA_STATUS hal_i2c_sleep(ATCAIface iface) { ATCAIfaceCfg *cfg = atgetifacecfg(iface); int bus = cfg->atcai2c.bus; uint8_t data[4]; data[0] = 0x01; // sleep word address value //twi_package_t packet = { twi_packet_t packet = { .chip = cfg->atcai2c.slave_address >> 1, .addr[0] = NULL, .addr_length = 0, .buffer = (void *)data, .length = 1 }; switch(bus) { case 0: //if (twi_master_write(TWI0, &packet) != TWI_SUCCESS) if (twi_master_write(TWI_Channel0, &packet) != TWI_SUCCESS) { return ATCA_COMM_FAIL; } break; case 1: if (twi_master_write(TWI_Channel1, &packet) != TWI_SUCCESS) { return ATCA_COMM_FAIL; } break; } return ATCA_SUCCESS; } /** \brief manages reference count on given bus and releases resource if no more refences exist * \param[in] hal_data - opaque pointer to hal data structure - known only to the HAL implementation */ ATCA_STATUS hal_i2c_release( void *hal_data ) { ATCAI2CMaster_t *hal = (ATCAI2CMaster_t *)hal_data; i2c_bus_ref_ct--; // track total i2c bus interface instances for consistency checking and debugging // if the use count for this bus has gone to 0 references, disable it. protect against an unbracketed release if (hal && --(hal->ref_ct) <= 0 && i2c_hal_data[hal->bus_index] != NULL) { switch(hal->bus_index) { //case 0: twi_reset(TWI0); break; case 0: twi_reset(TWI_Channel0);break; case 1: twi_reset(TWI_Channel1);break; } free(i2c_hal_data[hal->bus_index]); i2c_hal_data[hal->bus_index] = NULL; } return ATCA_SUCCESS; }