/*! /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;
}
예제 #2
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;
}
예제 #3
0
파일: task5.c 프로젝트: LaneTee/xmega-intro
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.
	}
	
}
예제 #4
0
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;
}
예제 #5
0
/*! /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 */
	}
}
예제 #6
0
/**
 * \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.
	}
}