uint8_t ICACHE_FLASH_ATTR twi_writeTo(uint8_t address, uint8_t *buf, unsigned int len, uint8_t sendStop) { unsigned int i; if (!twi_write_start()) { serial_print("I2C: bus busy\r\n"); return 4; } if (!twi_write_byte(((address << 1) | 0) & 0xFF)) { if (sendStop) twi_write_stop(); serial_print("I2C: received NACK on transmit of address\r\n"); return 2; } for (i = 0; i < len; i++) { if (!twi_write_byte(buf[i])) { if (sendStop) twi_write_stop(); serial_print("I2C: received NACK on transmit of data\r\n"); return 3; } } if (sendStop) twi_write_stop(); i = 0; while (SDA_READ() == 0 && (i++) < 10) { SCL_LOW(); twi_delay(twi_dcount); SCL_HIGH(); twi_delay(twi_dcount); } return 0; }
void rtc_set_time (uint8_t h, uint8_t m, uint8_t s) { twi_send_start(); twi_write_byte(RTC_ADDR & 0xFE); twi_write_byte(RTC_SEC_OFFSET); twi_write_byte(((s/10) << 4) | (s%10)); twi_write_byte(((m/10) << 4) | (m%10)); twi_write_byte(((h/10) << 4) | (h%10)); twi_send_stop(); }
/** Czyści rekord w logu * @param logp wartość wskaźnika */ void log_clear_record (uint16_t logp) { twi_send_start(); twi_write_byte(EXT_EEPROM_ADDR & 0xFE); twi_write_byte(FIRST_WORD(logp)); twi_write_byte(SECOND_WORD(logp)); twi_write_byte(UINT8_T_DISABLED); twi_send_stop(); _delay_ms(LOG_WRITE_DELAY); }
/** Ustawia wskaźnik wpisu * @param pointer wartość wskaźnika */ void log_write_pointer(uint16_t pointer) { twi_send_start(); twi_write_byte(EXT_EEPROM_ADDR & 0xFE); twi_write_byte(FIRST_WORD(LOG_CONTROL_RECORD_NUMBER) + LOG_CONTROL_POINTER_LSB); twi_write_byte(SECOND_WORD(LOG_CONTROL_RECORD_NUMBER)); twi_write_byte((uint8_t)pointer); twi_write_byte((uint8_t)(pointer >> 8)); twi_send_stop(); _delay_ms(LOG_WRITE_DELAY); }
void main() { //clock_buffer test = {1,2,3,4,5,6,7}; init(); q = twi_write_byte(0,0); clock = rtc_read(); q = twi_write_byte(7,( 0<<OUT | 1<<SQWE | 0<<RS1 | 0<<RS0 )); // Set DS1307 square wave output on, freq = 1Hz set_display(DISPLAY_TIME); while(1); }
/** Zwraca wskaźnik * @return wartość wskaźnika */ uint16_t log_read_pointer(void) { uint16_t logp; twi_send_start(); twi_write_byte(EXT_EEPROM_ADDR & 0xFE); twi_write_byte(FIRST_WORD(LOG_CONTROL_RECORD_NUMBER) + LOG_CONTROL_POINTER_LSB); twi_write_byte(SECOND_WORD(LOG_CONTROL_RECORD_NUMBER)); twi_send_start(); twi_write_byte(EXT_EEPROM_ADDR); twi_read_byte(TRUE); logp = twi_byte; twi_read_byte(FALSE); logp |= ((uint16_t)twi_byte) << 8; return logp; }
void rtc_get_time (void) { twi_send_start(); twi_write_byte(RTC_ADDR & 0xFE); twi_write_byte(RTC_SEC_OFFSET); twi_send_start(); twi_write_byte(RTC_ADDR); twi_read_byte(TRUE); seconds=((twi_byte&0x7f)>>4)*10 + (twi_byte&0xf); twi_read_byte(TRUE); minutes=((twi_byte&0x7f)>>4)*10 + (twi_byte&0xf); twi_read_byte(FALSE); hours=((twi_byte&0x3f)>>4)*10 + (twi_byte&0xf); twi_send_stop(); }
uint8_t ICACHE_FLASH_ATTR twi_readFrom(uint8_t address, uint8_t *buf, unsigned int len, uint8_t sendStop) { unsigned int i; if (!twi_write_start()) { serial_print("I2C: bus busy\r\n"); return 4; } if (!twi_write_byte(((address << 1) | 1) & 0xFF)) { if (sendStop) twi_write_stop(); serial_print("I2C: received NACK on transmit of address\r\n"); return 2; } for (i = 0; i < (len - 1); i++) buf[i] = twi_read_byte(false); buf[len - 1] = twi_read_byte(true); if (sendStop) twi_write_stop(); i = 0; while (SDA_READ() == 0 && (i++) < 10) { SCL_LOW(); twi_delay(twi_dcount); SCL_HIGH(); twi_delay(twi_dcount); } return 0; }
uint8_t get_io (uint8_t addr) { twi_send_start(); twi_write_byte(addr); twi_read_byte(FALSE); twi_send_stop(); return twi_byte; }
void rtc_get_date (void) { twi_send_start(); twi_write_byte(RTC_ADDR & 0xFE); twi_write_byte(RTC_DAY_OFFSET); twi_send_start(); twi_write_byte(RTC_ADDR); twi_read_byte(TRUE); day=((twi_byte&0x3f)>>4)*10 + (twi_byte&0xf); twi_read_byte(TRUE); wday=twi_byte&0x07; twi_read_byte(TRUE); month=((twi_byte&0x1f)>>4)*10 + (twi_byte&0xf); twi_read_byte(FALSE); year=((twi_byte)>>4)*10 + (twi_byte&0xf); twi_send_stop(); }
/** * \brief Notification about the start condition was sent. * * This function is a TWI Master start indication. * * \param none */ static void twi_master_start(void) { uint8_t chip_add; if ((TWI_WRITE_IADDR_WRITE_DATA == master_transfer.state) || (TWI_WRITE_DATA == master_transfer.state) || (TWI_WRITE_IADDR_READ_DATA == master_transfer.state)) { chip_add = TWI_WRITE_ENABLE(master_transfer.pkg->chip); twi_write_byte(chip_add); } else if (TWI_READ_DATA == master_transfer.state) { chip_add = TWI_READ_ENABLE(master_transfer.pkg->chip); twi_write_byte(chip_add); } else { /* abnormal */ twi_master_bus_reset(); master_transfer.status = ERR_PROTOCOL; } }
/** Czyta wpis z loga * @param logp wartość wskaźnika * @param *pbuff wskaźnik do bufora, gdzie zostanie zapisany wpis */ void log_read_record_at_pointer(uint16_t logp,uint8_t *pbuff) { uint8_t i; twi_send_start(); twi_write_byte(EXT_EEPROM_ADDR & 0xFE); twi_write_byte(FIRST_WORD(logp)); twi_write_byte(SECOND_WORD(logp)); twi_send_start(); twi_write_byte(EXT_EEPROM_ADDR); for(i=0;i<LOG_BYTES_PER_RECORD-1;i++) { // 7 bajtów z potwierdzeniem twi_read_byte(TRUE); *pbuff++ = twi_byte; } twi_read_byte(FALSE); // 1 bajt bez potwierdzenia *pbuff = twi_byte; twi_send_stop(); }
/** * \brief Sending data to twi bus. If last byte then send stop condition. * * \param none. */ static void twi_master_data_write(void) { if (master_transfer.data_count < master_transfer.pkg->length) { twi_write_byte(master_transfer.pkg->buffer[master_transfer.data_count++]); } else { twi_send_stop(); master_transfer.state = TWI_IDLE; master_transfer.status = STATUS_OK; twi_master_busy = false; } }
unsigned char twi_writeTo(unsigned char address, unsigned char * buf, unsigned int len, unsigned char sendStop){ unsigned int i; if(!twi_write_start()) return 4;//line busy if(!twi_write_byte(((address << 1) | 0) & 0xFF)) { if (sendStop) twi_write_stop(); return 2; //received NACK on transmit of address } for(i=0; i<len; i++) { if(!twi_write_byte(buf[i])) { if (sendStop) twi_write_stop(); return 3;//received NACK on transmit of data } } if(sendStop) twi_write_stop(); i = 0; while(SDA_READ() == 0 && (i++) < 10){ SCL_LOW(); twi_delay(twi_dcount); SCL_HIGH(); unsigned int t=0; while(SCL_READ()==0 && (t++)<twi_clockStretchLimit); // twi_clockStretchLimit twi_delay(twi_dcount); } return 0; }
void rtc_set_date (uint8_t y, uint8_t m, uint8_t d,uint8_t wd) { twi_send_start(); twi_write_byte(RTC_ADDR & 0xFE); twi_write_byte(RTC_DAY_OFFSET); twi_write_byte(((d/10) << 4) | (d%10)); twi_write_byte(wd); twi_write_byte(((m/10) << 4) | (m%10)); twi_write_byte(((y/10) << 4) | (y%10)); twi_send_stop(); }
/** * \brief Sending internal device address to twi bus. * * \param none. */ static void twi_master_internal_addr_write(void) { uint8_t data; data = master_transfer.pkg->addr[master_transfer.addr_count]; master_transfer.addr_count++; twi_write_byte(data); if (master_transfer.pkg->addr_length == master_transfer.addr_count) { if (TWI_WRITE_IADDR_WRITE_DATA == master_transfer.state) { master_transfer.state = TWI_WRITE_DATA; } else { master_transfer.state = TWI_READ_DATA; } } }
// // Originally, 'endTransmission' was an f(void) function. // It has been modified to take one parameter indicating // whether or not a STOP should be performed on the bus. // Calling endTransmission(false) allows a sketch to // perform a repeated start. // // WARNING: Nothing in the library keeps track of whether // the bus tenure has been properly ended with a STOP. It // is very possible to leave the bus in a hung state if // no call to endTransmission(true) is made. Some I2C // devices will behave oddly if they do not see a STOP. // uint8_t TwoWire::endTransmission(uint8_t sendStop) { // transmit buffer (blocking) TWI_StartWrite(twi, txAddress, 0, 0, txBuffer[0]); TWI_WaitByteSent(twi, XMIT_TIMEOUT); int sent = 1; while (sent < txBufferLength) { twi_write_byte(twi, txBuffer[sent++]); TWI_WaitByteSent(twi, XMIT_TIMEOUT); } TWI_Stop( twi); TWI_WaitTransferComplete(twi, XMIT_TIMEOUT); // empty buffer txBufferLength = 0; status = MASTER_IDLE; return sent; }
unsigned char twi_readFrom(unsigned char address, unsigned char* buf, unsigned int len, unsigned char sendStop){ unsigned int i; if(!twi_write_start()) return 4;//line busy if(!twi_write_byte(((address << 1) | 1) & 0xFF)) { if (sendStop) twi_write_stop(); return 2;//received NACK on transmit of address } for(i=0; i<(len-1); i++) buf[i] = twi_read_byte(false); buf[len-1] = twi_read_byte(true); if(sendStop) twi_write_stop(); i = 0; while(SDA_READ() == 0 && (i++) < 10){ SCL_LOW(); twi_delay(twi_dcount); SCL_HIGH(); unsigned int t=0; while(SCL_READ()==0 && (t++)<twi_clockStretchLimit); // twi_clockStretchLimit twi_delay(twi_dcount); } return 0; }
/** * \brief Starts a write operation on the TWI to access the selected slave, then * returns immediately. A byte of data must be provided to start the write; * other bytes are written next. * after that to send the remaining bytes. * \param pTwi Pointer to an Twi instance. * \param address Address of slave to acccess on the bus. * \param iaddress Optional slave internal address. * \param isize Number of internal address bytes. * \param byte First byte to send. */ static void TWI_StartWrite( Twi *pTwi, uint8_t address, uint32_t iaddress, uint8_t isize, uint8_t byte) { // assert( pTwi != NULL ) ; // assert( (address & 0x80) == 0 ) ; // assert( (iaddress & 0xFF000000) == 0 ) ; // assert( isize < 4 ) ; /* Set slave address and number of internal address bytes. */ pTwi->TWI_MMR = 0; pTwi->TWI_MMR = (isize << 8) | (address << 16); /* Set internal address bytes. */ pTwi->TWI_IADR = 0; pTwi->TWI_IADR = iaddress; /* Write first byte to send.*/ twi_write_byte(pTwi, byte); }
/** Wpisuje kolejne zdarzenie do logu we wskazanym przez wskaźnik miejscu. * @param logp wskaźnik rekordu * @param type typ wpisu * @param val1 warotść 1 * @param val2 warotść 2 * @param val3 warotść 3 */ void log_write_record_at_pointer(uint16_t logp,uint8_t type,uint8_t val1,uint8_t val2, uint8_t val3) { twi_send_start(); twi_write_byte(EXT_EEPROM_ADDR & 0xFE); twi_write_byte(FIRST_WORD(logp)); twi_write_byte(SECOND_WORD(logp)); twi_write_byte(year); twi_write_byte( month << 4 | (type & 0x0F) ); twi_write_byte(day); twi_write_byte(hours); twi_write_byte(minutes); twi_write_byte(val1); twi_write_byte(val2); twi_write_byte(val3); twi_send_stop(); _delay_ms(LOG_WRITE_DELAY); }
void set_io (uint8_t addr,uint8_t byte) { twi_send_start(); twi_write_byte(addr); twi_write_byte(byte); twi_send_stop(); }
static inline void write8(uint8_t reg, uint8_t value){ twi_write_byte(TCS34725_ADDRESS, (TCS34725_COMMAND_BIT | reg), value); }
void BOARD_TWI_Handler(void) { uint32_t status; status = twi_get_interrupt_status(BOARD_BASE_TWI_SLAVE); if (((status & TWI_SR_SVACC) == TWI_SR_SVACC) && (emulate_driver.uc_acquire_address == 0)) { twi_disable_interrupt(BOARD_BASE_TWI_SLAVE, TWI_IDR_SVACC); twi_enable_interrupt(BOARD_BASE_TWI_SLAVE, TWI_IER_RXRDY | TWI_IER_GACC | TWI_IER_NACK | TWI_IER_EOSACC | TWI_IER_SCL_WS); emulate_driver.uc_acquire_address++; emulate_driver.us_page_address = 0; emulate_driver.us_offset_memory = 0; } if ((status & TWI_SR_GACC) == TWI_SR_GACC) { puts("General Call Treatment\n\r"); puts("not treated"); } if (((status & TWI_SR_SVACC) == TWI_SR_SVACC) && ((status & TWI_SR_GACC) == 0) && ((status & TWI_SR_RXRDY) == TWI_SR_RXRDY)) { if (emulate_driver.uc_acquire_address == 1) { /* Acquire MSB address */ emulate_driver.us_page_address = (twi_read_byte(BOARD_BASE_TWI_SLAVE) & 0xFF) << 8; emulate_driver.uc_acquire_address++; } else { if (emulate_driver.uc_acquire_address == 2) { /* Acquire LSB address */ emulate_driver.us_page_address |= (twi_read_byte(BOARD_BASE_TWI_SLAVE) & 0xFF); emulate_driver.uc_acquire_address++; } else { /* Read one byte of data from master to slave device */ emulate_driver.uc_memory[emulate_driver.us_page_address + emulate_driver.us_offset_memory] = (twi_read_byte(BOARD_BASE_TWI_SLAVE) & 0xFF); emulate_driver.us_offset_memory++; } } } else { if (((status & TWI_SR_TXRDY) == TWI_SR_TXRDY) && ((status & TWI_SR_TXCOMP) == TWI_SR_TXCOMP) && ((status & TWI_SR_EOSACC) == TWI_SR_EOSACC)) { /* End of transfer, end of slave access */ emulate_driver.us_offset_memory = 0; emulate_driver.uc_acquire_address = 0; emulate_driver.us_page_address = 0; twi_enable_interrupt(BOARD_BASE_TWI_SLAVE, TWI_SR_SVACC); twi_disable_interrupt(BOARD_BASE_TWI_SLAVE, TWI_IDR_RXRDY | TWI_IDR_GACC | TWI_IDR_NACK | TWI_IDR_EOSACC | TWI_IDR_SCL_WS); } else { if (((status & TWI_SR_SVACC) == TWI_SR_SVACC) && ((status & TWI_SR_GACC) == 0) && (emulate_driver.uc_acquire_address == 3) && ((status & TWI_SR_SVREAD) == TWI_SR_SVREAD) && ((status & TWI_SR_NACK) == 0)) { /* Write one byte of data from slave to master device */ twi_write_byte(BOARD_BASE_TWI_SLAVE, emulate_driver.uc_memory[emulate_driver.us_page_address + emulate_driver.us_offset_memory]); emulate_driver.us_offset_memory++; } } } }
/** * \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; }
void TwoWire::onService(void) { // Retrieve interrupt status uint32_t sr = twi_get_interrupt_status(twi); if (status == SLAVE_IDLE && TWI_STATUS_SVACC(sr)) { twi_disable_interrupt(twi, TWI_IDR_SVACC); twi_enable_interrupt(twi, TWI_IER_RXRDY | TWI_IER_GACC | TWI_IER_NACK | TWI_IER_EOSACC | TWI_IER_SCL_WS | TWI_IER_TXCOMP); srvBufferLength = 0; srvBufferIndex = 0; // Detect if we should go into RECV or SEND status // SVREAD==1 means *master* reading -> SLAVE_SEND if (!TWI_STATUS_SVREAD(sr)) { status = SLAVE_RECV; } else { status = SLAVE_SEND; // Alert calling program to generate a response ASAP if (onRequestCallback) onRequestCallback(); else // create a default 1-byte response write((uint8_t) 0); } } if (status != SLAVE_IDLE) { if (TWI_STATUS_TXCOMP(sr) && TWI_STATUS_EOSACC(sr)) { if (status == SLAVE_RECV && onReceiveCallback) { // Copy data into rxBuffer // (allows to receive another packet while the // user program reads actual data) for (uint8_t i = 0; i < srvBufferLength; ++i) rxBuffer[i] = srvBuffer[i]; rxBufferIndex = 0; rxBufferLength = srvBufferLength; // Alert calling program onReceiveCallback( rxBufferLength); } // Transfer completed twi_enable_interrupt(twi, TWI_SR_SVACC); twi_disable_interrupt(twi, TWI_IDR_RXRDY | TWI_IDR_GACC | TWI_IDR_NACK | TWI_IDR_EOSACC | TWI_IDR_SCL_WS | TWI_IER_TXCOMP); status = SLAVE_IDLE; } } if (status == SLAVE_RECV) { if (TWI_STATUS_RXRDY(sr)) { if (srvBufferLength < BUFFER_LENGTH) { srvBuffer[srvBufferLength++] = twi_read_byte(twi); } } } if (status == SLAVE_SEND) { if (TWI_STATUS_TXRDY(sr) && !TWI_STATUS_NACK(sr)) { uint8_t c = 'x'; if (srvBufferIndex < srvBufferLength) { c = srvBuffer[srvBufferIndex++]; } twi_write_byte(twi, c); } } }
__interrupt void INT_timer1_comp_A(void) { TCNT1 = 0x00; keyboard = PINC & 0x0F; if(keyboard == 0x0F) { set_display(DISPLAY_TIME); OCR1A = keyboard_poll; } else { OCR1A = keyboard_delay; switch(keyboard) { case 0x0E: // date button pressed set_display(DISPLAY_DATE); break; case 0x0D: set_display(DISPLAY_TIME); clock.hours = bcd_inc(clock.hours); if(clock.hours == 0x24) clock.hours = 0; q = twi_write_byte(2,clock.hours); break; case 0x0B: set_display(DISPLAY_TIME); clock.minutes = bcd_inc(clock.minutes); if(clock.minutes == 0x60) clock.minutes = 0; q = twi_write_byte(1,clock.minutes); break; case 0x0C: set_display(DISPLAY_DATE); clock.date = bcd_inc(clock.date); switch(clock.month) { case 0x01: case 0x03: case 0x05: case 0x07: case 0x08: case 0x10: case 0x12: if(clock.date == 0x32) clock.date = 1; break; case 0x04: case 0x06: case 0x09: case 0x11: if(clock.date == 0x31) clock.date = 1; break; default : if(clock.date == 0x29) clock.date = 1; break; } q = twi_write_byte(4,clock.date); break; case 0x0A: set_display(DISPLAY_DATE); clock.month = bcd_inc(clock.month); if(clock.month == 0x13) clock.month = 1; q = twi_write_byte(5,clock.month); break; default : break; } } }
/** \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; }