void get_gps_data(void) { status_code_t gpsreturn; unsigned int bytes2Read; unsigned char gps_raw_pointer, gps_raw_data; gpsreturn = twi_master_read(&TWI_I2C400, &getgps_count); if (gpsreturn) return; // got some TWI error. Return bytes2Read = (gpsbuf[0] << 8) | gpsbuf[1]; if (!bytes2Read) return; // GPS not ready to send data. Return if (bytes2Read > 64) bytes2Read = 64; getgps_data.length = bytes2Read; gpsreturn = twi_master_read(&TWI_I2C400, &getgps_data ); for(gps_raw_pointer =0; gps_raw_pointer < bytes2Read; gps_raw_pointer++) { gps_raw_data = gpsbuf[gps_raw_pointer]; // cdcPutch(gps_raw_data); switch(gps_raw_data) { case ',': // term terminators case '\r': case '\n': case '*': if (gps_term_offset < sizeof(gps_term)) { gps_term[gps_term_offset] = 0; parse_gps_term(); } ++gps_term_number; gps_term_offset = 0; gps_checksum_term = (gps_raw_data == '*'); if(gps_raw_data == ',') gps_parity ^= gps_raw_data; break; case '$': // sentence begin gps_term_number = gps_term_offset = 0; gps_parity = 0; gps_sentence_type = GPS_SENTENCE_OTHER; gps_checksum_term = false; gps_data_good = false; break; default: // ordinary characters if (gps_term_offset < sizeof(gps_term) - 1) gps_term[gps_term_offset++] = gps_raw_data; if (!gps_checksum_term) gps_parity ^= gps_raw_data; } } }
/** \brief HAL implementation of I2C receive function for ASF I2C * \param[in] ATCAIface instance * \param[in] rxdata pointer to space to receive the data * \param[in] ptr to expected number of receive bytes to request * \return ATCA_STATUS */ ATCA_STATUS hal_i2c_receive( ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength) { #ifdef DEBUG_HAL printf("hal_i2c_receive()\r\n"); #endif ATCAIfaceCfg *cfg = atgetifacecfg(iface); int retries = cfg->rx_retries; int bus = cfg->atcai2c.bus; uint32_t status = !TWI_SUCCESS; //twi_package_t packet = { twi_packet_t packet = { .chip = cfg->atcai2c.slave_address >> 1, .addr[0] = NULL, .addr_length = 0, .buffer = (void *)rxdata, .length = (uint32_t)*rxlength }; switch(bus) { case 0: while(retries-- > 0 && status != TWI_SUCCESS) { //status = twi_master_read(TWI0, &packet); status = twi_master_read(TWI_Channel0, &packet); } break; case 1: while(retries-- > 0 && status != TWI_SUCCESS) { status = twi_master_read(TWI_Channel1, &packet); } break; } if (status != TWI_SUCCESS) { return ATCA_COMM_FAIL; } #ifdef DEBUG_HAL printf("\r\nResponse Packet (size:0x%.4x)\r\n", rxlength); printf("Count : %.2x\r\n", rxdata[0]); if (rxdata[0] > 3) { printf("Data : "); print_array(&rxdata[1], rxdata[0]-3); printf("CRC : "); print_array(&rxdata[rxdata[0]-2], 2); } printf("\r\n"); #endif return ATCA_SUCCESS; }
/** * \brief Function for show the kit data * */ static void show_kit_data(void) { uint8_t request_token = EDBG_KIT_DATA_TOKEN; uint32_t timeout = 0; uint8_t i; /** Get the extension boards info */ packet_rx.chip = EDBG_ADDRESS; packet_rx.addr_length = 1; packet_rx.addr[0] = request_token; packet_rx.buffer = kit_data; packet_rx.length = 256; while (twi_master_read(EDBG_I2C_MODULE, &packet_rx) != TWI_SUCCESS) { /* Increment timeout counter and check if timed out. */ if (timeout++ == TIMEOUT) { return; } } /** show kit data */ printf("\r\n The kit data: \r\n 0x"); for (i = 0; i < CONF_KIT_DATA_NUM; i++) { printf("%02x", kit_data[i]); } printf("\r\n"); }
int requestMPUPacket(int8_t mpuAddress, uint8_t mpuRegisterAddress, volatile void *data, uint8_t dataLength) { twi_packet_t packet; int8_t bError = 0; // Address the MPU in the body. packet.chip = mpuAddress; // We want to write to the PWR_MGMT_1 register. packet.addr[0] = mpuRegisterAddress; packet.addr[1] = 0; packet.addr[2] = 0; // It is a 1 byte address. packet.addr_length = 1; // Write a byte telling the MPU to reset and use a PLL clock derived // from the X-axis of the gyroscope. packet.buffer = (void *)data; // How many bytes do we want to write. packet.length = dataLength; if (TWI_SUCCESS != twi_master_read(TWI0, &packet)) { bError = -1; } return(bError); }
/*! \brief Read device register content. * * \param reg_index Register address. * \returns Register content. */ uint8_t at42qt1060_read_reg(uint8_t reg_index) { uint8_t data; twi_package_t twi_package; twi_package.chip = AT42QT1060_TWI_ADDRESS; twi_package.addr_length = 0; twi_package.buffer = ®_index; twi_package.length = 1; while(twi_master_write(AT42QT1060_TWI, &twi_package)!=TWI_SUCCESS); /* We need a delay here to make this work although this is not * specified in the datasheet. * Also there seems to be a bug in the TWI module or the driver * since some delay here (code or real delay) adds about 500us * between the write and the next read cycle. */ cpu_delay_us(20, cpu_hz); twi_package.chip = AT42QT1060_TWI_ADDRESS; twi_package.addr_length = 0; twi_package.buffer = &data; twi_package.length = 1; while(twi_master_read(AT42QT1060_TWI, &twi_package)!=TWI_SUCCESS); return data; }
/* * EEROM read function * */ int eeprom_read(void) { twi_packet_t packet_rx; uint16_t pMemAddress; int configsize = sizeof(Zodiac_Config); /* Configure the data packet to be received */ packet_rx.chip = AT24C_ADDRESS; packet_rx.addr_length = EEPROM_MEM_ADDR_LENGTH; printf("Reading Configuration from EEPROM (%d bytes)\r\n",configsize); pMemAddress = 0; packet_rx.addr[0] = pMemAddress; packet_rx.addr[1] = pMemAddress >> 8; packet_rx.buffer = &Zodiac_Config; packet_rx.length = configsize; if (twi_master_read(TWI0, &packet_rx) != TWI_SUCCESS) { printf("-1-\tTWI master read packet failed.\r\n"); return -1; } printf("Done!\r\n"); return 0; }
//returns the date void rtc_get_date(Rtc *p_rtc, uint32_t *ul_year, uint32_t *ul_month, uint32_t *ul_day, uint32_t *ul_week){ uint32_t r; twi_packet_t packet_rx; uint8_t rx_data [8]; int dw,dt,mo,yr; packet_rx.chip = RTC_ADDRESS; packet_rx.addr[0] = 0x3; packet_rx.addr_length = 1; packet_rx.buffer = rx_data; packet_rx.length = 4; if((r=twi_master_read(RTC_BASE_TWI, &packet_rx)) != TWI_SUCCESS){ printf("error in get_date: %d\n",(int)r); return; } //convert from BCD to decimal dw=bcd2int(rx_data[0]); dt=bcd2int(rx_data[1]); mo=bcd2int(rx_data[2]); yr=bcd2int(rx_data[3])+2000; *ul_year = yr; *ul_month= mo; *ul_day = dt; *ul_week = dw; //printf("20%d/%d/%d (%d)\n",yr,mo,dt,dw); }
status_code_t vcnl40xx_read_raw_data(void) { vcnl40xx_raw_data_t raw_big16; //package.addr[0] = REGISTER_AMBI_VALUE; //package.buffer = &raw_big16.ambient_light; //package.length = sizeof(raw_big16.ambient_light); // //status_code_t ret = twi_master_read(CONF_TWIM_PORT, &package); // //package.addr[0] = REGISTER_PROX_VALUE; //package.buffer = &raw_big16.proximity; //package.length = sizeof(raw_big16.proximity); // //ret = twi_master_read(CONF_TWIM_PORT, &package); // package.addr[0] = REGISTER_AMBI_VALUE; package.buffer = &raw_big16; package.length = sizeof(vcnl40xx_raw_data_t); status_code_t ret = twi_master_read(CONF_TWIM_PORT, &package); if(ret == STATUS_OK) { local_raw_data.ambient_light = BE16(raw_big16.ambient_light); local_raw_data.proximity = BE16(raw_big16.proximity); } return(ret); }
status_code_t vcnl40xx_probe(uint8_t* identification) { package.addr[0] = REGISTER_ID; package.length = 1; package.buffer = identification; return(twi_master_read(CONF_TWIM_PORT, &package)); }
// Supporting function implementation Accelerometer::Accelerometer() { // Initialize variables uint8_t value; // Configure VDDIO, SDA and SCL pins ioport_set_pin_dir(ACCELEROMETER_VDDIO_PIN, IOPORT_DIR_OUTPUT); ioport_set_pin_level(ACCELEROMETER_VDDIO_PIN, IOPORT_PIN_LEVEL_HIGH); ioport_set_pin_mode(ACCELEROMETER_SDA_PIN, IOPORT_MODE_WIREDANDPULL); ioport_set_pin_mode(ACCELEROMETER_SCL_PIN, IOPORT_MODE_WIREDANDPULL); // Configure interface twi_options_t options; options.speed = BUS_SPEED; options.chip = MASTER_ADDRESS; options.speed_reg = TWI_BAUD(sysclk_get_cpu_hz(), BUS_SPEED); // Initialize interface sysclk_enable_peripheral_clock(&TWI_MASTER); twi_master_init(&TWI_MASTER, &options); twi_master_enable(&TWI_MASTER); // Create packet twi_package_t packet; packet.addr[0] = WHO_AM_I; packet.addr_length = 1; packet.chip = ACCELEROMETER_ADDRESS; packet.buffer = &value; packet.length = 1; packet.no_wait = false; // Check if transmitting or receiving failed if(twi_master_read(&TWI_MASTER, &packet) != TWI_SUCCESS || value != DEVICE_ID) // Clear is working isWorking = false; // Otherwise else { // Reset the accelerometer writeValue(CTRL_REG2, CTRL_REG2_RST); // Wait enough time for accelerometer to initialize delay_ms(1); // Initialize settings initializeSettings(); // Calibrate //calibrate(); // Set is working isWorking = true; } }
/** * \brief Test if a chip answers for a given TWI address * * \param twim Base address of the TWIM * \param chip_addr Address of the chip which is searched for * * \retval STATUS_OK Slave Found * \retval ERR_IO_ERROR ANAK received or Bus Arbitration lost */ status_code_t twim_probe(Twim *twim, uint32_t chip_addr) { uint8_t data[1] = { 0 }; struct twim_package packet; packet.chip = chip_addr; packet.addr_length = 0; packet.buffer = (void *) data; packet.length = 1; return (twi_master_read(twim, &packet)); }
uint8_t at42qt1060_get_status(void) { twi_package_t twi_package; uint16_t status_data; twi_package.chip = AT42QT1060_TWI_ADDRESS; twi_package.addr_length = 0; twi_package.buffer = &status_data; twi_package.length = 2; twi_master_read(AT42QT1060_TWI, &twi_package); return MSB(status_data); }
signed int mpl115_read_pressure(void) { unsigned int Padc, Tadc; signed int a0, b1, b2, c12; signed long lt1, lt2, lt3; signed long c12x2, a1, a1x1, y1, a2x2, PComp; twi_master_read(&TWI_I2C400, &mpl115_read_package); Padc = (i2c_buffer[0] << 8) | i2c_buffer[1]; Tadc = (i2c_buffer[2] << 8) | i2c_buffer[3]; a0 = (i2c_buffer[4] << 8) | i2c_buffer[5]; b1 = (i2c_buffer[6] << 8) | i2c_buffer[7]; b2 = (i2c_buffer[8] << 8) | i2c_buffer[9]; c12 = (i2c_buffer[10] << 8) | i2c_buffer[11]; // Do compensation Padc>>=6; Tadc>>=6; //******* STEP 1 : c12x2 = c12 * Tadc lt1 = c12; // s(16,24) // c12 is s(14,13)+9 zero pad = s(16,15)+9 => s(16,24) left justified lt2 = (signed int)Tadc; // u(10,0) lt3 = lt1 * lt2; // s(26,24) = c12 * Tadc c12x2 = lt3 >> 11; // s(15,13) ? EQ 3 = c12x2 //******* STEP 2 : a1 = b1 + c12x2 lt1 = (signed int)b1; // s(16,13) lt2 = c12x2; // s(15,13) lt3 = lt1 + lt2; // s(16,13) = b1 + c12x2 a1 = lt3; // s(16,13) ? EQ 4 = a1 //******* STEP 3 : a1x1 = a1 * Padc lt1 = a1; // s(16,13) lt2 = (signed int)Padc; // u(10,0) lt3 = lt1 * lt2; // s(26,13) = a1 * Padc a1x1 = lt3; // s(26,13) ? EQ 5 = a1x1 //******* STEP 4 y1 = a0 + a1x1 lt1 = ((signed long)a0) << 10; // s(26,13) shifted to match a1x1 F value to add. So s(16,3)<<10 = s(26,13) lt2 = a1x1; // s(26,13) lt3 = lt1 + lt2; // s(26,13) = a0 + a1x1 y1 = lt3; // s(26,13) ? EQ 6 = y1 //******* STEP 5 : a2x2 = b2 * Tadc lt1 = (signed long)b2; // s(16,14) lt2 = (signed long)Tadc; // u(10,0) lt3 = lt1 * lt2; // s(26,14) = b2 * Tadc a2x2 = lt3 >> 1; // s(25,13) ? EQ 7 = a2x2 //******* STEP 6 : PComp = y1 + a2x2 lt1 = y1; // s(26,13) lt2 = a2x2; // s(25,13) lt3 = lt1 + lt2; // s(26,13) = y1 + a2x2 PComp = lt3 >> 9; // s(17,4) ? EQ 8 = PComp return (signed int)PComp; // By calibration this is less than 16 bits }
bool twi_master_transfer(uint8_t address, uint8_t *data, uint8_t data_length, bool issue_stop_condition) { bool transfer_succeeded = true; if (data_length > 0 && twi_master_clear_bus()) { NRF_TWI1->ADDRESS = (address >> 1); if ((address & TWI_READ_BIT) != 0) { transfer_succeeded = twi_master_read(data, data_length, issue_stop_condition); } else { transfer_succeeded = twi_master_write(data, data_length, issue_stop_condition); } }
static void ms3_write_reg(uint8_t reg, uint8_t data) { int twi_status; twi_package_t twi_package = { .chip = MS3_TWI_ADDRESS, .addr[0] = reg, .addr_length = 1, .buffer = &data, .length = sizeof(data) }; do { twi_status = twi_master_write(MS3_TWI, &twi_package); } while( twi_status != TWI_SUCCESS ); } static uint16_t ms3_read_reg(uint8_t reg) { int twi_status; uint8_t data; twi_package_t twi_package = { .chip = MS3_TWI_ADDRESS, .addr[0] = reg, .addr_length = 1, .buffer = &data, .length = sizeof(data) }; do { twi_status = twi_master_read(MS3_TWI, &twi_package); } while( twi_status != TWI_SUCCESS ); return data; } static uint8_t ms3_get_volume(uint8_t ch) { uint8_t gain = 0; switch (ch) { case MS3_LEFT_CHANNEL: gain = ms3_read_reg(MS3_HP_VOL_L); break; case MS3_RIGHT_CHANNEL: default: gain = ms3_read_reg(MS3_HP_VOL_R); break; } return gain; }
void cs2200_read(uint8_t address, void *buffer, uint8_t len) { twi_package_t twi_packet; int twi_status; do{ twi_packet.chip = CS2200_TWI_SLAVE_ADDRESS; //! TWI chip address to communicate with. twi_packet.addr[0] = address; //! Register address/commands inside the slave chip. twi_packet.addr_length = 1; //! Length of the TWI data address segment (1-3 bytes). twi_packet.buffer = buffer; //! Where to find the data to be written. twi_packet.length = len; //! How many bytes do we want to write. twi_status=twi_master_read(CS2200_TWI, &twi_packet); } while( twi_status != TWI_SUCCESS ); }
uint32_t adxl_read( uint8_t index, uint8_t *value, uint8_t addr){ twi_packet_t rx; rx.addr[0] = index; rx.addr_length = 1; rx.buffer = value; rx.length = 1; rx.chip = addr; return twi_master_read(TWI0, &rx); }
/** * \internal * \brief Reads out the crc value stored in the mxt-device. * * \param *device Pointer to mxt_device instance * \return crc_value 24-bit value representing the crc. */ static uint32_t mxt_get_crc_value(struct mxt_device *device) { uint8_t crc[3]; uint16_t addr = MXT_ID_BLOCK_SIZE + (OBJECT_TABLE_ELEMENT_SIZE * device->info_object->obj_count); /* Initializing the TWI packet to send to the slave */ twi_package_t packet = { .addr[0] = addr, .addr[1] = addr >> 8, .addr_length = sizeof(mxt_memory_adr), .chip = device->mxt_chip_adr, .buffer = crc, .length = sizeof(crc) }; /* Read information from the slave */ if (twi_master_read(device->interface, &packet) != STATUS_OK) { return ERR_IO_ERROR; } else { return ((uint32_t)crc[2] << 16) | ((uint16_t)crc[1] << 8) | crc[0]; } } /** * \internal * \brief Validates the info block by comparing the calculated Compares the * calculated and stored crc value. * * \param *device Pointer to mxt_device instance * \return Operation result status code. */ static status_code_t mxt_validate_info_block(struct mxt_device *device) { uint32_t crc_read; uint32_t crc_calculated; mxt_calculate_infoblock_crc(device, &crc_calculated); crc_read = mxt_get_crc_value(device); if (crc_calculated != crc_read) { return ERR_BAD_DATA; } else { return STATUS_OK; } }
/** * \brief Read single byte from AT24CXX. * * \param u32_address Address of the byte to read. * \param p_rd_byte Pointer to memory where the read byte will be stored. * * \return AT24C_READ_SUCCESS if one byte was read, AT24C_READ_FAIL otherwise. */ uint32_t at24cxx_read_byte(uint32_t u32_address, uint8_t *p_rd_byte) { twi_package_t twi_package; /* Configure the data packet to be received */ twi_package.chip = BOARD_AT24C_ADDRESS; at24c_build_word_address(twi_package.addr, u32_address); twi_package.addr_length = AT24C_MEM_ADDR_LEN; twi_package.buffer = p_rd_byte; twi_package.length = 1; if (twi_master_read(BOARD_AT24C_TWI_INSTANCE, &twi_package) != TWI_SUCCESS) { return AT24C_READ_FAIL; } return AT24C_READ_SUCCESS; }
/** * \brief Read data from the specified page in AT24CXX. * * \param u32_page_address The page number. * \param u32_page_size The size of the page (which varies with the chips). * \param p_rd_buffer Pointer to array where the bytes read are to be stored. * * \return AT24C_READ_SUCCESS if the page was read, AT24C_READ_FAIL otherwise. */ uint32_t at24cxx_read_page(uint32_t u32_page_address, uint32_t u32_page_size, uint8_t *p_rd_buffer) { twi_package_t twi_package; uint32_t start_address = (u32_page_address * u32_page_size) & 0xFFFF; /* Configure the data packet to be received */ twi_package.chip = BOARD_AT24C_ADDRESS; at24c_build_word_address(twi_package.addr, start_address); twi_package.addr_length = AT24C_MEM_ADDR_LEN; twi_package.buffer = p_rd_buffer; twi_package.length = u32_page_size; if (twi_master_read(BOARD_AT24C_TWI_INSTANCE, &twi_package) != TWI_SUCCESS) { return AT24C_READ_FAIL; } return AT24C_READ_SUCCESS; }
/*! \brief Read temperature from TMP100 device * * Returned temperature reading can be converted to degrees C, by using the formula: * temp = 128.0 / 32768 * tmp100().i; * * \retval I2C status. */ uint8_t tmp100_read(uint8_t i2c_address) { uint8_t status; twi_package_t packet; xSemaphoreTake( mutexI2C, portMAX_DELAY ); packet.chip = i2c_address; packet.addr = 0x00; packet.addr_length = 0; packet.buffer = &tmp100_data; packet.length = 2; status = twi_master_read(MOBO_TWI, &packet); // Release I2C port xSemaphoreGive( mutexI2C ); return status; }
/** * \brief HAL implementation of I2C receive function for ASF I2C * * \param[in] iface instance * \param[in] rxdata pointer to space to receive the data * \param[in] rxlength ptr to expected number of receive bytes to request * * \return ATCA_STATUS */ ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t *rxdata, uint16_t *rxlength) { #ifdef DEBUG_HAL printf("hal_i2c_receive()\r\n"); #endif 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 status = !TWI_SUCCESS; twi_package_t packet = { .chip = cfg->atcai2c.slave_address >> 1, .addr[0] = NULL, .addr_length = 0, .buffer = (void*)rxdata, .length = (uint32_t)*rxlength }; 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; #ifdef DEBUG_HAL printf("\r\nResponse Packet (size:0x%.4x)\r\n", rxlength); printf("Count : %.2x\r\n", rxdata[0]); if (rxdata[0] > 3) { printf("Data : "); print_array(&rxdata[1], rxdata[0] - 3); printf("CRC : "); print_array(&rxdata[rxdata[0] - 2], 2); } printf("\r\n"); #endif return ATCA_SUCCESS; }
//returns unix timestamp void rtc_get_time(Rtc *p_rtc, uint32_t *ul_hour, uint32_t *ul_minute, uint32_t *ul_second){ uint32_t r; twi_packet_t packet_rx; uint8_t rx_data [8]; int sc,mn,hr; packet_rx.chip = RTC_ADDRESS; packet_rx.addr[0] = 0x0; packet_rx.addr_length = 1; packet_rx.buffer = rx_data; packet_rx.length = 3; if((r=twi_master_read(RTC_BASE_TWI, &packet_rx)) != TWI_SUCCESS){ printf("error reading RTC: %d\n",(int)r); return; } //convert from BCD to decimal sc=bcd2int(rx_data[0]); mn=bcd2int(rx_data[1]); hr=bcd2int(rx_data[2]); *ul_hour = hr; *ul_minute = mn; *ul_second = sc; // printf("%d:%d:%d\n",hr,mn,sc); }
/** * \brief Function for show the extension boards information * */ static void show_extension_boards_information(void) { uint8_t request_token = EDBG_EXTEN_BOARDS_TOKEN; uint32_t timeout = 0; uint8_t board_num = 0; uint8_t i,j; /** Get the extension boards info */ packet_rx.chip = EDBG_ADDRESS; packet_rx.addr_length = 1; packet_rx.addr[0] = request_token; packet_rx.buffer = read_buffer; packet_rx.length = 1024; while (twi_master_read(EDBG_I2C_MODULE, &packet_rx) != TWI_SUCCESS) { /* Increment timeout counter and check if timed out. */ if (timeout++ == TIMEOUT) { return; } } /** Check and show info */ extension_map[0] = read_buffer[0]; extension_map[1] = read_buffer[1]; for (i = 0; i < 2; i++) { for (j = 1; j <= 8; j++) { if (extension_map[1 - i] & 0x01) { /** show extension board info */ printf("\r\n Extension board %d detected \r\n", (i * 8) + j); decode_board_info(&read_buffer[2 + 64 * board_num]); board_num++; } extension_map[1 - i] = extension_map[1 - i] >> 1; } } }
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; }
/** * \internal * \brief This test sends a packet from the master, and checks * that the sending happens without errors. Master is megaRF device and the slave * is on board EEPROM.Configuring EEPROM as slave is not required. * \param test Current test case. */ static void run_twi_master_send_test(const struct test_case *test) { status_code_t master_status; volatile uint64_t delay=0; // Package to send twi_package_t packet = { .addr[0] = (uint8_t) SLAVE_MEM_ADDR, /* TWI slave memory * address data */ .addr_length = (uint8_t)SLAVE_MEM_ADDR_LENGTH, /* TWI slave * memory * address data * size */ .chip = TWI_SLAVE_ADDR, /* TWI slave bus address */ .buffer = (void *)test_pattern, /* transfer data source * buffer */ .length = PATTERN_TEST_LENGTH /* transfer data size * (bytes) */ }; /* TWI master initialization options. */ twi_master_options_t m_options = { .speed = TWI_SPEED, .chip = TWI_SLAVE_ADDR, }; m_options.baud_reg = TWI_CLOCK_RATE(sysclk_get_cpu_hz(), m_options.speed); // Initialize TWI_MASTER sysclk_enable_peripheral_clock(TWI_MASTER); twi_master_init(TWI_MASTER, &m_options); // Send package to slave master_status = twi_master_write(TWI_MASTER, &packet); /* Write completion time for EEPROM */ for(delay=0;delay<10000;delay++); test_assert_true(test, master_status == STATUS_OK, "Master write not ok"); } /** * \internal * \brief This test requests previously sent packet to be sent from the slave, * and checks that the correct packet is received by the master. Master is * megaRF device and the slave is on board EEPROM.Configuring EEPROM as slave * is not required. * \param test Current test case. */ static void run_twi_master_recv_test(const struct test_case *test) { uint8_t i = 0; uint8_t recv_pattern[PATTERN_TEST_LENGTH] = {0}; // Package to send twi_package_t packet = { .addr[0] = (uint8_t) SLAVE_MEM_ADDR, /* TWI slave memory * address data */ .addr_length = (uint8_t)SLAVE_MEM_ADDR_LENGTH, /* TWI slave * memory * address data * size */ .chip = TWI_SLAVE_ADDR, .buffer = (void *)recv_pattern, .length = PATTERN_TEST_LENGTH, }; /* TWI master initialization options. */ twi_master_options_t m_options = { .speed = TWI_SPEED, .chip = TWI_SLAVE_ADDR, }; m_options.baud_reg = TWI_CLOCK_RATE(sysclk_get_cpu_hz(), m_options.speed); // Initialize TWI_MASTER sysclk_enable_peripheral_clock(TWI_MASTER); twi_master_init(TWI_MASTER, &m_options); // Send package to slave twi_master_read(TWI_MASTER, &packet); for (i = 0; i < PATTERN_TEST_LENGTH; i++) { test_assert_true(test, recv_pattern[i] == test_pattern[i], "Wrong twi data[%d] received, %d != %d", i, recv_pattern[i], test_pattern[i]); } } //@} /** * \brief Run TWI unit tests * * Initializes the clock system, board and serial output, then sets up the * TWI unit test suite and runs it. */ int main(void) { const usart_serial_options_t usart_serial_options = { .baudrate = CONF_TEST_BAUDRATE, .charlength = CONF_TEST_CHARLENGTH, .paritytype = CONF_TEST_PARITY, .stopbits = CONF_TEST_STOPBITS, }; sysclk_init(); board_init(); stdio_serial_init(CONF_TEST_USART, &usart_serial_options); // Define single ended conversion test cases DEFINE_TEST_CASE(twi_master_send_test, NULL, run_twi_master_send_test, NULL, "Sending packet from master test"); DEFINE_TEST_CASE(twi_master_recv_test, NULL, run_twi_master_recv_test, NULL, "Receiving packet from slave test"); // Put test case addresses in an array DEFINE_TEST_ARRAY(twi_tests) = { &twi_master_send_test, &twi_master_recv_test, }; // Define the test suite DEFINE_TEST_SUITE(twi_suite, twi_tests, "MEGARF TWI driver test suite"); // Run all tests in the suite test_suite_run(&twi_suite); while (1) { // Intentionally left empty. } }
signed int se95_read(void) { twi_master_read(&TWI_I2C400, &se95_read_package); return (i2c_buffer[0] << 8) | i2c_buffer[1]; }
static void ds2483_read(ds2483_dev_t *dev, uint8_t len, uint8_t *buf) { twi_master_read(dev->twim, DS2483_I2C_ADDR, len, buf); }
/** * \internal * \brief This test sends a packet from the master, and checks * that the sending happens without errors. * * \param test Current test case. */ static void run_twi_master_send_test( const struct test_case *test) { status_code_t master_status; // Package to send twi_package_t packet = { // No address or command .addr_length = 0, // issue to slave .chip = TWI_SLAVE_ADDR, .buffer = (void *)test_pattern, .length = PATTERN_TEST_LENGTH, // Wait if bus is busy .no_wait = false }; // TWI master options twi_options_t m_options = { .speed = TWI_SPEED, .chip = TWI_MASTER_ADDR, .speed_reg = TWI_BAUD(sysclk_get_cpu_hz(), TWI_SPEED) }; irq_initialize_vectors(); // Initialize TWI_MASTER sysclk_enable_peripheral_clock(&TWI_MASTER); twi_master_init(&TWI_MASTER, &m_options); twi_master_enable(&TWI_MASTER); // Initialize TWI_SLAVE sysclk_enable_peripheral_clock(&TWI_SLAVE); TWI_SlaveInitializeDriver(&slave, &TWI_SLAVE, *slave_process); TWI_SlaveInitializeModule(&slave, TWI_SLAVE_ADDR, TWI_SLAVE_INTLVL_MED_gc); cpu_irq_enable(); // Send package to slave master_status = twi_master_write(&TWI_MASTER, &packet); test_assert_true(test, master_status == STATUS_OK, "Master write not ok"); } /** * \internal * \brief This test sends a packet from the master to the slave, * and checks that the correct packet is received. * * \param test Current test case. */ static void run_twi_slave_recv_test( const struct test_case *test) { uint8_t i = 0; // Package to send twi_package_t packet = { // No address or command to issue to slave .addr_length = 0, .chip = TWI_SLAVE_ADDR, .buffer = (void *)test_pattern, .length = PATTERN_TEST_LENGTH, // Wait if bus is busy .no_wait = false }; // TWI master options twi_options_t m_options = { .speed = TWI_SPEED, .chip = TWI_MASTER_ADDR, .speed_reg = TWI_BAUD(sysclk_get_cpu_hz(), TWI_SPEED) }; irq_initialize_vectors(); // Initialize TWI_MASTER sysclk_enable_peripheral_clock(&TWI_MASTER); twi_master_init(&TWI_MASTER, &m_options); twi_master_enable(&TWI_MASTER); // Initialize TWI_SLAVE for (i = 0; i < TWIS_SEND_BUFFER_SIZE; i++) { slave.receivedData[i] = 0; } sysclk_enable_peripheral_clock(&TWI_SLAVE); TWI_SlaveInitializeDriver(&slave, &TWI_SLAVE, *slave_process); TWI_SlaveInitializeModule(&slave, TWI_SLAVE_ADDR, TWI_SLAVE_INTLVL_MED_gc); cpu_irq_enable(); // Send package to slave twi_master_write(&TWI_MASTER, &packet); // Wait for slave to receive packet and check that packet is correct do {} while (slave.result != TWIS_RESULT_OK); for (i = 0; i < PATTERN_TEST_LENGTH; i++) { test_assert_true(test, slave.receivedData[i] == test_pattern[i], "Wrong data[%d] received, %d != %d", i, slave.receivedData[i], test_pattern[i]); } } /** * \internal * \brief This test requests a packet to be sent from the slave, * and checks that the correct packet is received by the master. * * \param test Current test case. */ static void run_twi_master_recv_test(const struct test_case *test) { uint8_t i = 0; uint8_t recv_pattern[TWIS_SEND_BUFFER_SIZE] = {0}; // Package to send twi_package_t packet = { // No address or command to issue to slave .addr_length = 0, .chip = TWI_SLAVE_ADDR, .buffer = (void *)recv_pattern, // Wait if bus is busy .length = PATTERN_TEST_LENGTH, .no_wait = false }; // TWI master options twi_options_t m_options = { .speed = TWI_SPEED, .chip = TWI_MASTER_ADDR, .speed_reg = TWI_BAUD(sysclk_get_cpu_hz(), TWI_SPEED) }; // Data for slave to send, same as test_pattern slave.sendData[0] = 0x55; slave.sendData[1] = 0xA5; slave.sendData[2] = 0x5A; slave.sendData[3] = 0x77; slave.sendData[4] = 0x99; irq_initialize_vectors(); // Initialize TWI_MASTER sysclk_enable_peripheral_clock(&TWI_MASTER); twi_master_init(&TWI_MASTER, &m_options); twi_master_enable(&TWI_MASTER); // Initialize TWI_SLAVE for (i = 0; i < TWIS_SEND_BUFFER_SIZE; i++) { slave.receivedData[i] = 0; } sysclk_enable_peripheral_clock(&TWI_SLAVE); TWI_SlaveInitializeDriver(&slave, &TWI_SLAVE, *slave_process); TWI_SlaveInitializeModule(&slave, TWI_SLAVE_ADDR, TWI_SLAVE_INTLVL_MED_gc); cpu_irq_enable(); // Send package to slave twi_master_read(&TWI_MASTER, &packet); // Wait for slave to send packet do {} while (slave.result != TWIS_RESULT_OK); for (i = 0; i < PATTERN_TEST_LENGTH; i++) { test_assert_true(test, recv_pattern[i] == test_pattern[i], "Wrong data[%d] received, %d != %d", i, recv_pattern[i], test_pattern[i]); } } //@} /** * \brief Run TWI unit tests * * Initializes the clock system, board and serial output, then sets up the * TWI unit test suite and runs it. */ int main(void) { const usart_serial_options_t usart_serial_options = { .baudrate = CONF_TEST_BAUDRATE, .charlength = CONF_TEST_CHARLENGTH, .paritytype = CONF_TEST_PARITY, .stopbits = CONF_TEST_STOPBITS, }; sysclk_init(); board_init(); stdio_serial_init(CONF_TEST_USART, &usart_serial_options); // Use the internal pullups for SDA and SCL TWI_MASTER_PORT.PIN0CTRL = PORT_OPC_WIREDANDPULL_gc; TWI_MASTER_PORT.PIN1CTRL = PORT_OPC_WIREDANDPULL_gc; // Define single ended conversion test cases DEFINE_TEST_CASE(twi_master_send_test, NULL, run_twi_master_send_test, NULL, "Sending packet from master test"); DEFINE_TEST_CASE(twi_slave_recv_test, NULL, run_twi_slave_recv_test, NULL, "Receiving packet from master test"); DEFINE_TEST_CASE(twi_master_recv_test, NULL, run_twi_master_recv_test, NULL, "Receiving packet from slave test"); // Put test case addresses in an array DEFINE_TEST_ARRAY(twi_tests) = { &twi_master_send_test, &twi_slave_recv_test, &twi_master_recv_test, }; // Define the test suite DEFINE_TEST_SUITE(twi_suite, twi_tests, "XMEGA TWI driver test suite"); // Run all tests in the suite test_suite_run(&twi_suite); while (1) { // Intentionally left empty. } }
/** \brief TWI Master Example Main * * The master example begins by initializing required board resources. The * system clock, basic GPIO pin mapping, and interrupt vectors are established. * * A memory location on a TWI slave is written with a fixed test pattern which * is then read back into a separate buffer. As a basic sanity check, the * original write-buffer values are compared with values read from the slave to * a separate buffer. An LED on the development board is illuminated when there * is a match between the written and read data. * * \return Nothing. */ int main(void) { /* Initialize the common clock service, board-specific initialization, * and * interrupt vector support prior to using the TWI master interfaces. */ sysclk_init(); board_init(); /* TWI master initialization options. */ twi_master_options_t opt = { .speed = TWI_SPEED_HZ, .chip = SLAVE_BUS_ADDR, }; opt .baud_reg = TWI_CLOCK_RATE(sysclk_get_cpu_hz(), opt.speed); /* Enable the peripheral clock for TWI module */ sysclk_enable_peripheral_clock(TWI_EXAMPLE); /* Initialize the TWI master driver. */ twi_master_init(TWI_EXAMPLE,&opt); twi_package_t packet = { .addr[0] = slave_mem_addr[0], /* TWI slave memory * address data */ .addr_length = (uint8_t)SLAVE_MEM_ADDR_LENGTH, /* TWI slave * memory * address data * size */ .chip = SLAVE_BUS_ADDR, /* TWI slave bus address */ .buffer = (void *)test_pattern, /* transfer data source * buffer */ .length = PATTERN_TEST_LENGTH /* transfer data size * (bytes) */ }; /* Perform a multi-byte write access then check the result. */ while (twi_master_write(TWI_EXAMPLE,&packet) != TWI_SUCCESS) { } /* Write completion time for EEPROM */ delay_ms(5); uint8_t data_received[PATTERN_TEST_LENGTH] = {0}; twi_package_t packet_received = { .addr[0] = slave_mem_addr[0], /* TWI slave memory * address data */ .addr_length = (uint8_t)SLAVE_MEM_ADDR_LENGTH, /* TWI slave * memory * address data * size */ .chip = SLAVE_BUS_ADDR, /* TWI slave bus address */ .buffer = data_received, /* transfer data destination * buffer */ .length = PATTERN_TEST_LENGTH /* transfer data size * (bytes) */ }; /* Perform a multi-byte read access then check the result. */ while (twi_master_read(TWI_EXAMPLE,&packet_received) != TWI_SUCCESS) { } /* Verify that the received data matches the sent data. */ for (int i = 0; i < PATTERN_TEST_LENGTH; i++) { if (data_received[i] != test_pattern[i]) { /* Error */ while (1) { } } } /* test PASS */ /* Green LED ON */ LED_On(LED_GREEN_GPIO); while (1) { } }