/* * @fn nm_bus_init * @brief Initialize the bus wrapper * @return M2M_SUCCESS in case of success and M2M_ERR_BUS_FAIL in case of failure */ sint8 nm_bus_init(void *pvinit) { sint8 result = M2M_SUCCESS; #ifdef CONF_WINC_USE_I2C twihs_options_t opt; /* Enable the peripheral clock for TWI */ pmc_enable_periph_clk(CONF_WINC_I2C_ID); /* Configure the options of TWI driver */ opt.master_clk = sysclk_get_peripheral_hz(); opt.speed = CONF_WINC_TWIHS_CLOCK; if (twihs_master_init(CONF_WINC_I2C, &opt) != TWIHS_SUCCESS) { M2M_ERR("-E-\tTWI master initialization failed.\r"); while (1) { /* Capture error */ } } #elif CONF_WINC_USE_SPI /* Configure SPI pins. */ ioport_set_pin_mode(CONF_WINC_SPI_MISO_GPIO, CONF_WINC_SPI_MISO_FLAGS); ioport_set_pin_mode(CONF_WINC_SPI_MOSI_GPIO, CONF_WINC_SPI_MOSI_FLAGS); ioport_set_pin_mode(CONF_WINC_SPI_CLK_GPIO, CONF_WINC_SPI_CLK_FLAGS); ioport_set_pin_mode(CONF_WINC_SPI_CS_GPIO, CONF_WINC_SPI_CS_FLAGS); ioport_disable_pin(CONF_WINC_SPI_MISO_GPIO); ioport_disable_pin(CONF_WINC_SPI_MOSI_GPIO); ioport_disable_pin(CONF_WINC_SPI_CLK_GPIO); ioport_disable_pin(CONF_WINC_SPI_CS_GPIO); spi_enable_clock(CONF_WINC_SPI); spi_disable(CONF_WINC_SPI); spi_reset(CONF_WINC_SPI); spi_set_master_mode(CONF_WINC_SPI); spi_disable_mode_fault_detect(CONF_WINC_SPI); spi_set_peripheral_chip_select_value(CONF_WINC_SPI, CONF_WINC_SPI_NPCS); spi_set_clock_polarity(CONF_WINC_SPI, CONF_WINC_SPI_NPCS, CONF_WINC_SPI_POL); spi_set_clock_phase(CONF_WINC_SPI, CONF_WINC_SPI_NPCS, CONF_WINC_SPI_PHA); spi_set_bits_per_transfer(CONF_WINC_SPI, CONF_WINC_SPI_NPCS, SPI_CSR_BITS_8_BIT); spi_set_baudrate_div(CONF_WINC_SPI, CONF_WINC_SPI_NPCS, (sysclk_get_cpu_hz() / CONF_WINC_SPI_CLOCK)); spi_set_transfer_delay(CONF_WINC_SPI, CONF_WINC_SPI_NPCS, CONF_WINC_SPI_DLYBS, CONF_WINC_SPI_DLYBCT); spi_enable(CONF_WINC_SPI); nm_bsp_reset(); #endif return result; }
void twi_init(void) { twihs_options_t opt; /* Enable the peripheral clock for TWI */ pmc_enable_periph_clk(ID_TWIHS0); /* Configure the options of TWI driver */ opt.master_clk = sysclk_get_cpu_hz(); opt.speed = TWIHS_CLK; //400KHz if (twihs_master_init(TWIHS0, &opt) != TWIHS_SUCCESS) { while (1) { /* Capture error */ } } }
ATCA_STATUS hal_i2c_discover_devices(int busNum, ATCAIfaceCfg cfg[], int *found ) { ATCAIfaceCfg *head = cfg; uint8_t slaveAddress = 0x01; ATCADevice device; ATCAIface discoverIface; ATCACommand command; ATCAPacket packet; uint32_t execution_time; ATCA_STATUS status; uint8_t revs508[1][4] = { { 0x00, 0x00, 0x50, 0x00 } }; uint8_t revs108[1][4] = { { 0x80, 0x00, 0x10, 0x01 } }; uint8_t revs204[2][4] = { { 0x00, 0x02, 0x00, 0x08 }, { 0x00, 0x04, 0x05, 0x00 } }; int i; /** \brief default configuration, to be reused during discovery process */ ATCAIfaceCfg discoverCfg = { .iface_type = ATCA_I2C_IFACE, .devtype = ATECC508A, .atcai2c.slave_address = 0x07, .atcai2c.bus = busNum, .atcai2c.baud = 400000, .wake_delay = 800, .rx_retries = 3 }; ATCAHAL_t hal; uint8_t address; if ( busNum < 0 ) return ATCA_COMM_FAIL; hal_i2c_init( &hal, &discoverCfg ); device = newATCADevice( &discoverCfg ); discoverIface = atGetIFace( device ); command = atGetCommands( device ); // iterate through all addresses on given i2c bus // all valid 7-bit addresses go from 0x07 to 0x78 for ( slaveAddress = 0x07; slaveAddress <= 0x78; slaveAddress++ ) { discoverCfg.atcai2c.slave_address = slaveAddress << 1; // turn it into an 8-bit address which is what the rest of the i2c HAL is expecting when a packet is sent // wake up device // If it wakes, send it a dev rev command. Based on that response, determine the device type // BTW - this will wake every cryptoauth device living on the same bus (ecc508a, sha204a) if ( hal_i2c_wake( discoverIface ) == ATCA_SUCCESS ) { (*found)++; memcpy( (uint8_t*)head, (uint8_t*)&discoverCfg, sizeof(ATCAIfaceCfg)); memset( packet.data, 0x00, sizeof(packet.data)); // get devrev info and set device type accordingly atInfo( command, &packet ); execution_time = atGetExecTime(command, CMD_INFO) + 1; // send the command if ( (status = atsend( discoverIface, (uint8_t*)&packet, packet.txsize )) != ATCA_SUCCESS ) { printf("packet send error\r\n"); continue; } // delay the appropriate amount of time for command to execute atca_delay_ms(execution_time); // receive the response if ( (status = atreceive( discoverIface, &(packet.data[0]), &(packet.rxsize) )) != ATCA_SUCCESS ) continue; if ( (status = isATCAError(packet.data)) != ATCA_SUCCESS ) continue; // determine device type from common info and dev rev response byte strings for ( i = 0; i < (int)sizeof(revs508) / 4; i++ ) { if ( memcmp( &packet.data[1], &revs508[i], 4) == 0 ) { discoverCfg.devtype = ATECC508A; break; } } for ( i = 0; i < (int)sizeof(revs204) / 4; i++ ) { if ( memcmp( &packet.data[1], &revs204[i], 4) == 0 ) { discoverCfg.devtype = ATSHA204A; break; } } for ( i = 0; i < (int)sizeof(revs108) / 4; i++ ) { if ( memcmp( &packet.data[1], &revs108[i], 4) == 0 ) { discoverCfg.devtype = ATECC108A; break; } } atca_delay_ms(15); // now the device type is known, so update the caller's cfg array element with it head->devtype = discoverCfg.devtype; head++; } hal_i2c_idle(discoverIface); } // hal_i2c_release(&hal); return ATCA_SUCCESS; } /** \brief - this HAL implementation assumes you've included the ASF Twi libraries in your project, otherwise, the HAL layer will not compile because the ASF TWI drivers are a dependency * */ /** \brief hal_i2c_init manages requests to initialize a physical interface. it manages use counts so when an interface * has released the physical layer, it will disable the interface for some other use. * You can have multiple ATCAIFace instances using the same bus, and you can have multiple ATCAIFace instances on * multiple i2c buses, so hal_i2c_init manages these things and ATCAIFace is abstracted from the physical details. */ /** \brief initialize an I2C interface using given config * \param[in] hal - opaque ptr to HAL data * \param[in] cfg - interface configuration */ ATCA_STATUS hal_i2c_init(void *hal, ATCAIfaceCfg *cfg) { int bus = cfg->atcai2c.bus; // 0-based logical bus number ATCAHAL_t *phal = (ATCAHAL_t*)hal; twihs_options_t twiOptions; if ( i2c_bus_ref_ct == 0 ) // power up state, no i2c buses will have been used for ( int i = 0; i < MAX_I2C_BUSES; i++ ) i2c_hal_data[i] = NULL; i2c_bus_ref_ct++; // total across buses if ( bus >= 0 && bus < MAX_I2C_BUSES ) { // if this is the first time this bus and interface has been created, do the physical work of enabling it if ( i2c_hal_data[bus] == NULL ) { i2c_hal_data[bus] = malloc( sizeof(ATCAI2CMaster_t) ); i2c_hal_data[bus]->ref_ct = 1; // buses are shared, this is the first instance /* Configure the options of TWI driver */ twiOptions.master_clk = sysclk_get_cpu_hz() / CONFIG_SYSCLK_DIV; twiOptions.speed = cfg->atcai2c.baud; switch ( bus ) { case 0: /* Enable the peripheral clock for TWI */ pmc_enable_periph_clk(ID_TWIHS0); if (twihs_master_init(TWIHS0, &twiOptions) != TWIHS_SUCCESS) return ATCA_COMM_FAIL; i2c_hal_data[bus]->twi_module = TWIHS0; break; case 1: /* Enable the peripheral clock for TWI */ pmc_enable_periph_clk(ID_TWIHS1); if (twihs_master_init(TWIHS1, &twiOptions) != TWIHS_SUCCESS) return ATCA_COMM_FAIL; i2c_hal_data[bus]->twi_module = TWIHS1; break; case 2: /* Enable the peripheral clock for TWI */ pmc_enable_periph_clk(ID_TWIHS2); if (twihs_master_init(TWIHS2, &twiOptions) != TWIHS_SUCCESS) return ATCA_COMM_FAIL; i2c_hal_data[bus]->twi_module = TWIHS2; break; } // store this for use during the release phase i2c_hal_data[bus]->bus_index = bus; } else{ // otherwise, another interface already initialized the bus, so this interface will share it and any different // cfg parameters will be ignored...first one to initialize this sets the configuration i2c_hal_data[bus]->ref_ct++; } phal->hal_data = i2c_hal_data[bus]; return ATCA_SUCCESS; } return ATCA_COMM_FAIL; }
/** * \brief Application entry point for TWI EEPROM example. * * \return Unused (ANSI-C compatibility). */ int main(void) { uint32_t i; twihs_options_t opt; twihs_packet_t packet_tx, packet_rx; /* Initialize the SAM system */ sysclk_init(); /* Initialize the board */ board_init(); /* Turn off LEDs */ LED_Off(LED0); /* Initialize the console UART */ configure_console(); /* Output example information */ puts(STRING_HEADER); /* Configure systick for 1 ms */ puts("Configure system tick to get 1ms tick period.\r"); if (SysTick_Config(sysclk_get_cpu_hz() / 1000)) { puts("-E- Systick configuration error\r"); while (1) { /* Capture error */ } } /* Enable the peripheral clock for TWI */ pmc_enable_periph_clk(BOARD_ID_TWIHS_EEPROM); /* Configure the options of TWI driver */ opt.master_clk = sysclk_get_cpu_hz(); opt.speed = TWIHS_CLK; /* Configure the data packet to be transmitted */ packet_tx.chip = AT24C_ADDRESS; packet_tx.addr[0] = EEPROM_MEM_ADDR >> 8; packet_tx.addr[1] = EEPROM_MEM_ADDR; packet_tx.addr_length = EEPROM_MEM_ADDR_LENGTH; packet_tx.buffer = (uint8_t *) test_data_tx; packet_tx.length = TEST_DATA_LENGTH; /* Configure the data packet to be received */ packet_rx.chip = packet_tx.chip; packet_rx.addr[0] = packet_tx.addr[0]; packet_rx.addr[1] = packet_tx.addr[1]; packet_rx.addr_length = packet_tx.addr_length; packet_rx.buffer = gs_uc_test_data_rx; packet_rx.length = packet_tx.length; if (twihs_master_init(BOARD_BASE_TWIHS_EEPROM, &opt) != TWIHS_SUCCESS) { puts("-E-\tTWI master initialization failed.\r"); while (1) { /* Capture error */ } } /* Send test pattern to EEPROM */ if (twihs_master_write(BOARD_BASE_TWIHS_EEPROM, &packet_tx) != TWIHS_SUCCESS) { puts("-E-\tTWI master write packet failed.\r"); while (1) { /* Capture error */ } } puts("Write:\tOK!\n\r"); /* Wait at least 10 ms */ mdelay(WAIT_TIME); /* Get memory from EEPROM*/ if (twihs_master_read(BOARD_BASE_TWIHS_EEPROM, &packet_rx) != TWIHS_SUCCESS) { puts("-E-\tTWI master read packet failed.\r"); while (1) { /* Capture error */ } } puts("Read:\tOK!\r"); /* Compare the sent and the received */ for (i = 0; i < TEST_DATA_LENGTH; i++) { if (test_data_tx[i] != gs_uc_test_data_rx[i]) { /* No match */ puts("Data comparison:\tUnmatched!\r"); while (1) { /* Capture error */ } } } /* Match */ puts("Data comparison:\tMatched!\r"); LED_On(LED0); while (1) { } }