/*! /brief Example code * * Example code that reads the key pressed and show a value from the buffer, * sends the value to the slave and read back the processed value which will * be inverted and displayed after key release. */ int main(void) { // Enable internal pull-up on PC0, PC1.. Uncomment if you don't have external pullups // PORTCFG.MPCMASK = 0x03; // Configure several PINxCTRL registers at the same time // PORTE.PIN0CTRL = (PORTE.PIN0CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLUP_gc; // Enable pull-up to get a defined level on the switches /* Initialize TWI master. */ /*TWI_MasterInit(&twiMaster, &TWIE, TWI_MASTER_INTLVL_LO_gc, TWI_BAUDSETTING);*/ /* Initialize TWI slave. */ TWI_SlaveInitializeDriver(&twiSlave, &TWIE, TWIE_SlaveProcessData); TWI_SlaveInitializeModule(&twiSlave, SLAVE_ADDRESS, TWI_SLAVE_INTLVL_LO_gc); /* Enable LO interrupt level. */ PMIC.CTRL |= PMIC_LOLVLEN_bm; sei(); uint8_t BufPos = 0; while(true); return 0; }
/**************************************************************************//** \brief TWI module initialisation \param twi The TWI_Slave_t struct instance. ******************************************************************************/ void hwInitTwi(void) { uint8_t temp = PMIC.CTRL | PMIC_IVSEL_bm; CCP = CCP_IOREG_gc; PMIC.CTRL = temp; TWI_SlaveInitializeDriver(&twiSlave, TWI_MODULE); TWI_SlaveInitializeModule(&twiSlave, SLAVE_BUS_ADDR, TWI_SLAVE_INTLVL_LO_gc); // Enable LO interrupt level. PMIC.CTRL |= PMIC_LOLVLEN_bm; }
int main(void) { facilitatePowersaving(); // Pull-ups and PR Registers initHardware(); // Switches, LEDs, Sleep, Interrupt sei(); // Enable global interrupts /* === Initialization of TWI Module === */ // Enable internal pull-up on PD0, PD1 for correct TWI operation PORTCFG.MPCMASK = 0x03; TWIPORT.PIN0CTRL = (TWIPORT.PIN0CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLUP_gc; /* Initialize TWI master. */ TWI_MasterInit(&twiMaster, &TWI, TWI_MASTER_INTLVL_LO_gc, TWI_BAUDSETTING); /* Initialize TWI slave. */ TWI_SlaveInitializeDriver(&twiSlave, &TWI, TWI_SlaveProcessData); TWI_SlaveInitializeModule(&twiSlave, OWN_ADDRESS, TWI_SLAVE_INTLVL_LO_gc); /* === End Initialization === */ while (1) { // Try to sleep while we are waiting for button press while (READ_SWITCHES == 0x00){ //See board.h for READ_SWITCHES define. sleep(); } _delay_ms(5); // Debounce switch sendBuffer[0] = READ_SWITCHES; TWI_MasterWrite(&twiMaster, // Module OTHER_ADDRESS, // Which slave &sendBuffer[0], // What to send 1); // Send how much /* Wait until transaction is complete. Required TWI interrupts will be executed while waiting */ while (twiMaster.status != TWIM_STATUS_READY); // Wait for user to release button. while (READ_SWITCHES != 0x00); //See board.h for READ_SWITCHES define. } }
void init_twi(void) { /* /\* make sure our I2C pins are set to input *\/ */ /* PORTC.DIRCLR = PIN_SDA_2 | PIN_SCL_2; */ /* set the i2c pins to use internal pullup resistors */ PORTCFG.MPCMASK = PIN_SDA_2 | PIN_SCL_2; PORTC.PIN0CTRL = (PORTC.PIN0CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLUP_gc; PORTCFG.MPCMASK = 0x00; /* set our callback */ TWI_SlaveInitializeDriver(&twiSlave, &TWIC, TWIC_SlaveProcessData); /* low-priority interrupt */ TWI_SlaveInitializeModule(&twiSlave, SLAVE_ADDRESS, TWI_SLAVE_INTLVL_LO_gc); /* enable low-priority interrupts */ PMIC.CTRL |= PMIC_LOLVLEN_bm; }
/*! /brief Example code * * Example code that reads the key pressed and show a value from the buffer, * sends the value to the slave and read back the processed value which will * be inverted and displayed after key release. */ int main(void) { /* Initialize PORTE for output and PORTD for inverted input. */ PORTE.DIRSET = 0xFF; PORTD.DIRCLR = 0xFF; PORTCFG.MPCMASK = 0xFF; PORTD.PIN0CTRL |= PORT_INVEN_bm; // PORTCFG.MPCMASK = 0xFF; // PORTD.PIN0CTRL = (PORTD.PIN0CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLUP_gc; // Enable internal pull-up on PC0, PC1.. Uncomment if you don't have external pullups // PORTCFG.MPCMASK = 0x03; // Configure several PINxCTRL registers at the same time // PORTC.PIN0CTRL = (PORTC.PIN0CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLUP_gc; //Enable pull-up to get a defined level on the switches /* Initialize TWI master. */ TWI_MasterInit(&twiMaster, &TWIC, TWI_MASTER_INTLVL_LO_gc, TWI_BAUDSETTING); /* Initialize TWI slave. */ TWI_SlaveInitializeDriver(&twiSlave, &TWIC, TWIC_SlaveProcessData); TWI_SlaveInitializeModule(&twiSlave, SLAVE_ADDRESS, TWI_SLAVE_INTLVL_LO_gc); /* Enable LO interrupt level. */ PMIC.CTRL |= PMIC_LOLVLEN_bm; sei(); uint8_t BufPos = 0; while (1) { while(!PORTD.IN); /* Wait for user to press button */ switch(PORTD.IN){ case (PIN0_bm): BufPos = 0; break; case (PIN1_bm): BufPos = 1; break; case (PIN2_bm): BufPos = 2; break; case (PIN3_bm): BufPos = 3; break; case (PIN4_bm): BufPos = 4; break; case (PIN5_bm): BufPos = 5; break; case (PIN6_bm): BufPos = 6; break; case (PIN7_bm): BufPos = 7; break; default: break; } /* Show the byte to send while holding down the key. */ while(PORTD.IN != 0x00){ PORTE.OUT = sendBuffer[BufPos]; } TWI_MasterWriteRead(&twiMaster, SLAVE_ADDRESS, &sendBuffer[BufPos], 1, 1); while (twiMaster.status != TWIM_STATUS_READY) { /* Wait until transaction is complete. */ } /* Show the sent byte received and processed on LEDs. */ PORTE.OUT = (twiMaster.readData[0]); while(PORTD.IN); /* Wait for user to release button */ } }
/** * \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. } }