XMEGA E TWI module provides two additionnnal features compare to regular XMEGA TWI module:
- Fast Mode Plus communication speed
- Bridge Mode
The following use case will set up the TWI module to be used in in Fast Mode Plus together with bridge mode. This use case is similar to the regular XMEGA TWI initialization, it only differs by the activation of both Bridge and Fast Mode Plus mode.
#define TWI_MASTER TWIC
#define TWI_MASTER_PORT PORTC
#define TWI_SLAVE TWIC
#define TWI_SPEED 1000000
#define TWI_MASTER_ADDR 0x50
#define TWI_SLAVE_ADDR 0x50
#define DATA_LENGTH 8
uint8_t data[DATA_LENGTH] = {
0x0f, 0x1f, 0x2f, 0x3f, 0x4f, 0x5f, 0x6f, 0x7f
};
uint8_t recv_data[DATA_LENGTH] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
.chip = TWI_MASTER_ADDR,
};
static void slave_process(void) {
int i;
for(i = 0; i < DATA_LENGTH; i++) {
}
}
}
void send_and_recv_twi()
{
.chip = TWI_SLAVE_ADDR,
.buffer = (void *)data,
.length = DATA_LENGTH,
.no_wait = false
};
uint8_t i;
TWI_MASTER_PORT.PIN0CTRL = PORT_OPC_WIREDANDPULL_gc;
TWI_MASTER_PORT.PIN1CTRL = PORT_OPC_WIREDANDPULL_gc;
twi_bridge_enable(&TWI_MASTER);
twi_fast_mode_enable(&TWI_MASTER);
twi_slave_fast_mode_enable(&TWI_SLAVE);
TWI_SLAVE_INTLVL_MED_gc);
}
do {
}
We first create some definitions. TWI master and slave, speed, and addresses:
#define TWI_MASTER TWIC
#define TWI_MASTER_PORT PORTC
#define TWI_SLAVE TWIC
#define TWI_SPEED 1000000
#define TWI_MASTER_ADDR 0x50
#define TWI_SLAVE_ADDR 0x50
#define DATA_LENGTH 8
We create a handle to contain information about the slave module:
We create two variables, one which contains data that will be transmitted, and one which will contain the received data:
uint8_t data[DATA_LENGTH] = {
0x0f, 0x1f, 0x2f, 0x3f, 0x4f, 0x5f, 0x6f, 0x7f
};
uint8_t recv_data[DATA_LENGTH] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
Options for the TWI module initialization procedure are given below:
.chip = TWI_MASTER_ADDR,
};
The TWI slave will fire an interrupt when it has received data, and the function below will be called, which will copy the data from the driver to our recv_data buffer:
static void slave_process(void) {
int i;
for(i = 0; i < DATA_LENGTH; i++) {
}
}
Set up the interrupt handler:
We create a packet for the data that we will send to the slave TWI:
.chip = TWI_SLAVE_ADDR,
.buffer = (void *)data,
.length = DATA_LENGTH,
.no_wait = false
};
We need to set SDA/SCL pins for the master TWI to be wired and enable pull-up:
TWI_MASTER_PORT.PIN0CTRL = PORT_OPC_WIREDANDPULL_gc;
TWI_MASTER_PORT.PIN1CTRL = PORT_OPC_WIREDANDPULL_gc;
We enable all interrupt levels:
We enable the clock to the master module:
We enable the global TWI bridge mode as well as the Fast Mode Plus communication speed for both master and slave:
twi_bridge_enable(&TWI_MASTER);
twi_fast_mode_enable(&TWI_MASTER);
twi_slave_fast_mode_enable(&TWI_SLAVE);
Initialize the master module with the options we described before:
We do the same for the slave, using the slave portion of the driver, passing through the slave_process function, its address, and set medium interrupt level:
TWI_SLAVE_INTLVL_MED_gc);
We zero out the receive buffer in the slave handle:
And enable interrupts:
Finally, we write our packet through the master TWI module:
We wait for the slave to finish receiving:
- Note
- When the slave has finished receiving, the slave_process() function will copy the received data into our recv_data buffer, which now contains what was sent through the master.