Microchip® Advanced Software Framework

Quick start guide for MEGARF TWI driver

This is the quick start guide for the TWI Driver, with step-by-step instructions on how to configure and use the driver for specific use cases.

The section described below can be compiled into e.g. the main application loop or any other function that might use the TWI functionality.

Basic use case of the TWI driver

In our basic use case, the TWI driver is used to set up internal communication between TWI modules on the two MEGARF STK600 boards, On one STK600 megarf board TWI is set up in master mode, and on another STK600 megarf board TWI is set up in slave mode, and these are connected together on the board by placing a connection between SDA/SCL.

Prerequisites

The System Clock Management module is required to enable the clock to the TWI modules.

Setup

When the System Clock Management module has been included, it must be initialized:

Use case

Example code

#define TWI_SPEED_HZ 125000
#define SLAVE_BUS_ADDR 0xB0
#define PATTERN_TEST_LENGTH sizeof(test_pattern)
const uint8_t test_pattern[] = {
0x05,
0x15,
0x25,
0x35,
0x45,
0x55,
0x65,
0x75,
};
int main(void)
{
.speed = TWI_SPEED_HZ,
.chip = SLAVE_BUS_ADDR,
};
twi_package_t packet = {
.addr[0] = slave_mem_addr[0],
.addr_length = (uint8_t)SLAVE_MEM_ADDR_LENGTH,
.chip = SLAVE_BUS_ADDR,
.buffer = (void *)test_pattern,
};
}
uint8_t data_received[PATTERN_TEST_LENGTH] = {0};
twi_package_t packet_received = {
.addr[0] = slave_mem_addr[0],
.addr_length = (uint8_t)SLAVE_MEM_ADDR_LENGTH,
.chip = SLAVE_BUS_ADDR,
.buffer = data_received,
};
while (twi_master_read(TWI_EXAMPLE,&packet_received) != TWI_SUCCESS) {
}
for (int i = 0; i < PATTERN_TEST_LENGTH; i++) {
if (data_received[i] != test_pattern[i]) {
while (1) {
}
}
}
LED_On(LED_GREEN_GPIO);
while (1) {
}
}

Workflow

We first create some definitions. TWI slave, speed, and addresses:

#define TWI_SPEED_HZ 125000
#define SLAVE_BUS_ADDR 0xB0
#define PATTERN_TEST_LENGTH sizeof(test_pattern)

We create two variables, one which contains data that will be transmitted, and one which will contain the received data:

const uint8_t test_pattern[] = {
0x05,
0x15,
0x25,
0x35,
0x45,
0x55,
0x65,
0x75,
};
uint8_t data_received[PATTERN_TEST_LENGTH] = {0};

Options for the TWI module initialization procedure are given below:

.speed = TWI_SPEED_HZ,
.chip = SLAVE_BUS_ADDR,
};

Set up the interrupt handler:

ISR(TWI_vect)
{
}

We create a packet for the data that we will be sent to the slave TWI:

twi_package_t packet = {
.addr[0] = slave_mem_addr[0],
.addr_length = (uint8_t)SLAVE_MEM_ADDR_LENGTH,
.chip = SLAVE_BUS_ADDR,
.buffer = (void *)test_pattern,
.length = PATTERN_TEST_LENGTH
};

We enable the clock to the master module, and initialize it with the options we described before:

We do the same for the slave on another board, using the slave portion of the driver, passing through the twi_slave_init function, its address,

And enable interrupts:

Finally, we write our packet through the master TWI module:

We wait for the slave to finish receiving:

}

We read back the sent data and check whether slave received properly

while (twi_master_read(TWI_EXAMPLE,&packet_received) != TWI_SUCCESS) {
}
Note
When the master has finished receiving, the twi_master_interrupt_handler() function will copy the received data into our data_received buffer,which now contains what was sent through.