//! [initialize_i2c] void configure_EEPROM(void) { pinMode(WP, OUTPUT); PinSet(WP); /* Initialize config structure and software module. */ //! [init_conf] struct i2c_master_config config_i2c_master; i2c_master_get_config_defaults(&config_i2c_master); //! [init_conf] /* Change buffer timeout to something longer. */ //! [conf_change] config_i2c_master.buffer_timeout = 10000; config_i2c_master.generator_source=GCLK_GENERATOR_0; config_i2c_master.pinmux_pad0=PINMUX_PA12C_SERCOM2_PAD0; config_i2c_master.pinmux_pad1=PINMUX_PA13C_SERCOM2_PAD1; //! [conf_change] /* Initialize and enable device with config. */ //! [init_module] i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master); /*BAUD=GCLK0freq(48Mhz)*Thigh /i.e SCLfreq=GCLK/(2*Baud)*/ REG_SERCOM2_I2CM_BAUD=200; //force baud rate after above setting gives around 100Khz //! [enable_module] i2c_master_enable(&i2c_master_instance); //! [enable_module] }
/*---------------------------------------------------------------------------*/ void i2c_master_interface_init(void) { if (!initialized) { struct i2c_master_config config_i2c_master; /* Toggle SCL for some time, this solves I2C periperhal problem */ struct port_config pin_conf; port_get_config_defaults(&pin_conf); pin_conf.direction = PORT_PIN_DIR_OUTPUT; port_pin_set_config(PIN_PA13, &pin_conf); for (int i = 0; i < 1000; i++) { port_pin_toggle_output_level(PIN_PA13); clock_wait(CLOCK_SECOND / 1000); } /* Initialize config structure and software module. */ i2c_master_get_config_defaults(&config_i2c_master); config_i2c_master.baud_rate = 400; config_i2c_master.pinmux_pad0 = SENSORS_I2C_SERCOM_PINMUX_PAD0; config_i2c_master.pinmux_pad1 = SENSORS_I2C_SERCOM_PINMUX_PAD1; /* Initialize and enable device with config. */ i2c_master_init(&i2c_master_instance, SENSORS_I2C_MODULE, &config_i2c_master); i2c_master_enable(&i2c_master_instance); initialized = true; } }
void configure_i2c_master(void) { /* initialize config structure and software module */ struct i2c_master_config config_i2c_master; i2c_master_get_config_defaults(&config_i2c_master); /* change buffer timeout to something longer */ config_i2c_master.buffer_timeout = 10000; /* initialize and enable device with config. */ i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master); i2c_master_enable(&i2c_master_instance); }
/** * \internal * \brief Test for I2C master initialization. * * This test initializes the i2c master module and checks whether the * initialization is successful or not. * * \param test Current test case. */ static void run_i2c_init_test(const struct test_case *test) { enum status_code status; struct i2c_master_config config_i2c_master; i2c_master_get_config_defaults(&config_i2c_master); config_i2c_master.buffer_timeout = 10000; status = i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master); /* Check for successful initialization */ test_assert_true(test, status == STATUS_OK, "I2C master initialization failed"); i2c_master_enable(&i2c_master_instance); }
/** * \brief Initialize EDBG I2C communication for SAM0 * */ bool adp_interface_init(void) { enum status_code return_value; system_init(); struct i2c_master_config config_i2c_master; i2c_master_get_config_defaults(&config_i2c_master); config_i2c_master.buffer_timeout = 10000; return_value = i2c_master_init(&i2c_master_instance, EDBG_TWI, &config_i2c_master); i2c_master_enable(&i2c_master_instance); return return_value; }
/** * Configure I2C master. */ static void configure_i2c_master(void) { struct i2c_master_config config_i2c_master; i2c_master_get_config_defaults(&config_i2c_master); config_i2c_master.buffer_timeout = 10000; config_i2c_master.pinmux_pad0 = BOOT_I2C_PAD0; config_i2c_master.pinmux_pad1 = BOOT_I2C_PAD1; i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master); i2c_master_enable(&i2c_master_instance); }
/* * @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 /* Initialize config structure and software module. */ struct i2c_master_config config_i2c_master; i2c_master_get_config_defaults(&config_i2c_master); /* Change buffer timeout to something longer. */ config_i2c_master.buffer_timeout = 1000; /* Initialize and enable device with config. */ i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master); i2c_master_enable(&i2c_master_instance); #elif defined CONF_WINC_USE_SPI /* Structure for SPI configuration. */ struct spi_config config; struct spi_slave_inst_config slave_config; /* Select SPI slave CS pin. */ /* This step will set the CS high */ spi_slave_inst_get_config_defaults(&slave_config); slave_config.ss_pin = CONF_WINC_SPI_CS_PIN; spi_attach_slave(&slave_inst, &slave_config); /* Configure the SPI master. */ spi_get_config_defaults(&config); config.mux_setting = CONF_WINC_SPI_SERCOM_MUX; config.pinmux_pad0 = CONF_WINC_SPI_PINMUX_PAD0; config.pinmux_pad1 = CONF_WINC_SPI_PINMUX_PAD1; config.pinmux_pad2 = CONF_WINC_SPI_PINMUX_PAD2; config.pinmux_pad3 = CONF_WINC_SPI_PINMUX_PAD3; config.master_slave_select_enable = false; config.mode_specific.master.baudrate = CONF_WINC_SPI_CLOCK; if (spi_init(&master, CONF_WINC_SPI_MODULE, &config) != STATUS_OK) { return M2M_ERR_BUS_FAIL; } /* Enable the SPI master. */ spi_enable(&master); nm_bsp_reset(); nm_bsp_sleep(1); #endif return result; }
void configure_i2c_master(void){ /* Initialize config structure and software module. */ struct i2c_master_config config_i2c_master; i2c_master_get_config_defaults(&config_i2c_master); config_i2c_master.buffer_timeout = 10000; config_i2c_master.pinmux_pad0 = PINMUX_PA16C_SERCOM1_PAD0; config_i2c_master.pinmux_pad1 = PINMUX_PA17C_SERCOM1_PAD1; /* Initialize and enable device with config. */ i2c_master_init(&i2c_master_instance, SERCOM1, &config_i2c_master); //i2c_master_reset(&i2c_master_instance); i2c_master_enable(&i2c_master_instance); }
/** * \brief Function for configuring I2C master module * * This function will configure the I2C master module with * the SERCOM module to be used and pinmux settings */ static void configure_i2c_master(void) { /* Create and initialize config structure */ struct i2c_master_config config_i2c; i2c_master_get_config_defaults(&config_i2c); /* Change pins */ config_i2c.pinmux_pad0 = EDBG_I2C_SERCOM_PINMUX_PAD0; config_i2c.pinmux_pad1 = EDBG_I2C_SERCOM_PINMUX_PAD1; /* Initialize and enable device with config */ i2c_master_init(&i2c_master_instance, EDBG_I2C_MODULE, &config_i2c); i2c_master_enable(&i2c_master_instance); }
//! [initialize_i2c] void configure_i2c_master(void) { /* Initialize config structure and software module. */ //! [init_conf] struct i2c_master_config config_i2c_master; i2c_master_get_config_defaults(&config_i2c_master); //! [init_conf] /* Change buffer timeout to something longer. */ //! [conf_change] config_i2c_master.buffer_timeout = 10000; //! [conf_change] /* Initialize and enable device with config. */ //! [init_module] i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master); //! [init_module] //! [enable_module] i2c_master_enable(&i2c_master_instance); //! [enable_module] }
/** * \internal * \brief Test for I2C master transfer. * * First test transfer function with stop. * write to slave, read from slave and then compare the data. * the slave send out the data it received, * so master write and read data should be the same. * * Then test transfer function without stop. * write to slave, then use i2c_master_send_stop to complete writing, * read from slave, compare the data. * finally, use function with stop to complete the transfer. * * \param test Current test case. */ static void run_i2c_master_transfer_test(const struct test_case *test) { uint32_t timeout_cycles = 1000; uint32_t i; bool status = true; uint8_t read_buffer[DATA_LENGTH] = {0}; struct i2c_master_packet packet = { .address = SLAVE_ADDRESS, .data_length = DATA_LENGTH, .data = write_buffer, .ten_bit_address = false, .high_speed = false, .hs_master_code = 0x0, }; /* with stop function: master transfer test */ /* wait the master write to complete */ do { timeout_cycles--; if (i2c_master_write_packet_wait(&i2c_master_instance, &packet) == STATUS_OK) { break; } } while (timeout_cycles > 0); test_assert_true(test, timeout_cycles > 0, "i2c master write failed"); /* wait the master read to complete */ packet.data = read_buffer; timeout_cycles = 1000; do { timeout_cycles--; if (i2c_master_read_packet_wait(&i2c_master_instance, &packet) == STATUS_OK) { break; } } while (timeout_cycles > 0); test_assert_true(test, timeout_cycles > 0, "i2c master read failed"); /* Compare the sent and the received */ for (i = 0; i < DATA_LENGTH; i++) { if (read_buffer[i] != write_buffer[i]) { status = false; break; } } test_assert_true(test, status == true, "i2c master transfer comparsion failed"); /* with stop function master transfer test end */ /* without stop function: master transfer test*/ /* wait the master write to finish */ packet.data = write_buffer; timeout_cycles = 1000; do { timeout_cycles--; if (i2c_master_write_packet_wait_no_stop(&i2c_master_instance, &packet) == STATUS_OK) { break; } } while (timeout_cycles > 0); test_assert_true(test, timeout_cycles > 0, "i2c master write without stop failed"); /* use i2c_master_send_stop to complete master writing */ i2c_master_send_stop(&i2c_master_instance); /* wait the master read to finish */ packet.data = read_buffer; timeout_cycles = 1000; do { timeout_cycles--; if (i2c_master_read_packet_wait_no_stop(&i2c_master_instance, &packet) == STATUS_OK) { break; } } while (timeout_cycles > 0); test_assert_true(test, timeout_cycles > 0, "i2c master read without stop failed"); /* Compare the sent and the received */ for (i = 0; i < DATA_LENGTH; i++) { if (read_buffer[i] != write_buffer[i]) { status = false; break; } } test_assert_true(test, status == true, "i2c master transfer without stop comparsion failed"); /* use i2c_master_write_packet_wait to complete the transfer */ packet.data = write_buffer; do { timeout_cycles--; if (i2c_master_write_packet_wait(&i2c_master_instance, &packet) == STATUS_OK) { break; } } while (timeout_cycles > 0); test_assert_true(test, timeout_cycles > 0, "i2c master write with repeated start failed"); /* without stop function: master transfer test end*/ } /** * \internal * \brief Test full speed mode master transfer. * * test function with stop in full speed mode. * \param test Current test case. */ static void run_i2c_full_speed_test(const struct test_case *test) { enum status_code status; struct i2c_master_config config_i2c_master; /* init i2c master in full speed mode*/ i2c_master_get_config_defaults(&config_i2c_master); config_i2c_master.buffer_timeout = 10000; config_i2c_master.baud_rate = I2C_MASTER_BAUD_RATE_400KHZ; i2c_master_disable(&i2c_master_instance); status = i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master); /* Check for successful initialization */ test_assert_true(test, status == STATUS_OK, "I2C master fast-mode initialization failed"); i2c_master_enable(&i2c_master_instance); uint32_t timeout_cycles = 1000; uint32_t i; bool status1 = true; struct i2c_master_packet packet = { .address = SLAVE_ADDRESS, .data_length = DATA_LENGTH, .data = write_buffer, .ten_bit_address = false, .high_speed = false, .hs_master_code = 0x0, }; uint8_t read_buffer[DATA_LENGTH] = {0}; /* wait master write complete */ do { timeout_cycles--; if (i2c_master_write_packet_wait(&i2c_master_instance, &packet) == STATUS_OK) { break; } } while (timeout_cycles > 0); test_assert_true(test, timeout_cycles > 0, "i2c master write failed"); /* wait master read complete */ packet.data = read_buffer; timeout_cycles = 1000; do { timeout_cycles--; if (i2c_master_read_packet_wait(&i2c_master_instance, &packet) == STATUS_OK) { break; } } while (timeout_cycles > 0); test_assert_true(test, timeout_cycles > 0, "i2c master read failed"); /* Compare the sent and the received */ for (i = 0; i < DATA_LENGTH; i++) { if (read_buffer[i] != write_buffer[i]) { status1 = false; break; } } test_assert_true(test, status1 == true, "i2c master transfer comparsion failed"); } /** * \brief Run I2C master unit tests * * Initializes the system and serial output, then sets up the * I2C master unit test suite and runs it. */ int main(void) { system_init(); cdc_uart_init(); /* Define Test Cases */ DEFINE_TEST_CASE(i2c_init_test, NULL, run_i2c_init_test, NULL, "Testing I2C Initialization"); DEFINE_TEST_CASE(i2c_master_transfer_test, NULL, run_i2c_master_transfer_test, NULL, "Testing I2C master data transfer"); DEFINE_TEST_CASE(i2c_full_speed_test, NULL, run_i2c_full_speed_test, NULL, "Testing I2C change speed transfer"); /* Put test case addresses in an array */ DEFINE_TEST_ARRAY(i2c_tests) = { &i2c_init_test, &i2c_master_transfer_test, &i2c_full_speed_test, }; /* Define the test suite */ DEFINE_TEST_SUITE(i2c_test_suite, i2c_tests, "SAM I2C driver test suite"); /* Run all tests in the suite*/ test_suite_run(&i2c_test_suite); while (true) { /* Intentionally left empty */ } }
/* * @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 /* Initialize config structure and software module. */ struct i2c_master_config config_i2c_master; i2c_master_get_config_defaults(&config_i2c_master); /* Change buffer timeout to something longer. */ config_i2c_master.buffer_timeout = 1000; /* Initialize and enable device with config. */ i2c_master_init(&i2c_master_instance, SERCOM2, &config_i2c_master); i2c_master_enable(&i2c_master_instance); #elif defined CONF_WINC_USE_SPI // hspi1.Instance = SPI1; // hspi1.Init.Mode = SPI_MODE_MASTER; // hspi1.Init.Direction = SPI_DIRECTION_2LINES; // hspi1.Init.DataSize = SPI_DATASIZE_8BIT; // hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; // hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; // hspi1.Init.NSS = SPI_NSS_SOFT; // hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; // hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; // hspi1.Init.TIMode = SPI_TIMODE_DISABLED; // hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; // hspi1.Init.CRCPolynomial = 10; /* Structure for SPI configuration. */ // struct spi_config config; // struct spi_slave_inst_config slave_config; // /* Select SPI slave CS pin. */ // /* This step will set the CS high */ // spi_slave_inst_get_config_defaults(&slave_config); // slave_config.ss_pin = CONF_WINC_SPI_CS_PIN; // spi_attach_slave(&slave_inst, &slave_config); // /* Configure the SPI master. */ // spi_get_config_defaults(&config); // config.mux_setting = CONF_WINC_SPI_SERCOM_MUX; // config.pinmux_pad0 = CONF_WINC_SPI_PINMUX_PAD0; // config.pinmux_pad1 = CONF_WINC_SPI_PINMUX_PAD1; // config.pinmux_pad2 = CONF_WINC_SPI_PINMUX_PAD2; // config.pinmux_pad3 = CONF_WINC_SPI_PINMUX_PAD3; // config.master_slave_select_enable = false; // config.mode_specific.master.baudrate = CONF_WINC_SPI_CLOCK; // if (spi_init(&master, CONF_WINC_SPI_MODULE, &config) != STATUS_OK) { // return M2M_ERR_BUS_FAIL; // } // /* Enable the SPI master. */ // spi_enable(&master); nm_bsp_reset(); nm_bsp_sleep(1); #endif return result; }
/** * I2C Write. * * address is the full write address like 0xEE */ void i2c_master_write(uint8_t address, uint8_t* data, uint16_t data_length) { uint32_t timeout = 0; struct i2c_master_packet packet = { .address = address >> 1, .data_length = data_length, .data = data, .ten_bit_address = false, .high_speed = false, .hs_master_code = 0x0, }; while (i2c_master_write_packet_wait(&i2c_master_instance, &packet) != STATUS_OK) { /* Increment timeout counter and check if timed out. */ if (timeout++ > 1000) { break; } } } /** * I2C Read. * * address is the full write address like 0xEE */ void i2c_master_read(uint8_t address, uint8_t* data, uint16_t data_length) { uint32_t timeout = 0; struct i2c_master_packet packet = { .address = address >> 1, .data_length = data_length, .data = data, .ten_bit_address = false, .high_speed = false, .hs_master_code = 0x0, }; while (i2c_master_read_packet_wait(&i2c_master_instance, &packet) != STATUS_OK) { /* Increment timeout counter and check if timed out. */ if (timeout++ > 1000) { break; } } } /** * I2C bus master. */ void i2c_init(SercomI2cm*const sercom, uint32_t pad0_pinmux, uint32_t pad1_pinmux) { struct i2c_master_config config_i2c_master; i2c_master_get_config_defaults(&config_i2c_master); /* Config */ config_i2c_master.buffer_timeout = 10000; config_i2c_master.baud_rate = 100; /* 100 kBaud */ /* Pinmux */ config_i2c_master.pinmux_pad0 = pad0_pinmux; config_i2c_master.pinmux_pad1 = pad1_pinmux; /* Initialize and enable device with config. */ i2c_master_init(&i2c_master_instance, (Sercom*)sercom, &config_i2c_master); i2c_master_enable(&i2c_master_instance); }