The driver is intended to use I2C master functions in a Real-Time operating system, i.e. is thread safe.
The stop condition is automatically controlled by the driver if the I/O write and read functions are used, but can be manually controlled by using the i2c_m_os_transfer function.
The transfer functions of the I2C Master RTOS driver are optimized for RTOS support. When data transfer is in progress, the transfer functions use semaphore to block the current task or thread until the transfer end. So the transfer functions do not work without RTOS, the transfer functions must be called in an RTOS task or thread.
During data transfer, the I2C transfer process is not protected, so that a more flexible way can be chosen in the application.
I2C Modes (standard mode/fastmode+/highspeed mode) can only be selected in START. If the SCL frequency (baudrate) has changed run-time, make sure to stick within the SCL clock frequency range supported by the selected mode. The requested SCL clock frequency is not validated by the i2c_m_os_set_baudrate function against the selected I2C mode.
Initialize and deinitialize the driver and associated hardware
Register I/O descriptor
Enable or disable I2C master
Hookup callback handlers on TX complete, RX complete, and error events
Set the address of the slave device
Read/Write message to/from the slave
Set I2C bus clock speed
Which clock source is used
After I2C hardware initialization, the i2c_m_os_get_io function is needed to register an I/O descriptor. Then the application needs to set the slave address by the i2c_m_os_set_slaveaddr function. At the end, start the read/write operation.
System Management Bus (SMBus) is not supported
Power Management Bus (PMBus) is not supported
The register value for the requested I2C speed is calculated and placed in the correct register, but not validated if it works correctly with the clock/prescaler settings used for the module. To validate the I2C speed setting use the formula found in the configuration file for the module. Selectable speed is automatically limited within the speed range defined by the I2C mode selected
The following shows a simple example of using the I2C master. The I2C master must have been initialized by i2c_m_os_init. This initialization will configure the operation of the I2C master.
The example registers an I/O descriptor and sets the slave address, and finally starts a writing operation.
The example creates an I2C master example task. In the task, it registers an I/O descriptor for an I2C instance, then sets the slave address. Here we assume that the I2C device is a 0AT30TSE temperature sensor on an I/O1 Xplained Pro connected to an Xplained board. Write the data to the slave device, and the RTOS task scheduler starts to read the data from the slave device.
/**
* Example task of using I2C_0 to echo using the I/O abstraction.
* Assume the I2C device is AT30TSE temp sensor on IO1 Xplained Pro connected to
* XPlained board.
*/
void I2C_example_task(void *p)
{
struct io_descriptor *io;
uint16_t data;
uint8_t buf[2];
(void)p;
i2c_m_os_get_io(&I2C_0, &io);
/* Address of the temp sensor. */
i2c_m_os_set_slaveaddr(&I2C_0, 0x4f, 0);
/* Set configuration to use 12-bit temperature */
buf[0] = 1;
buf[1] = 3 << 5;
io_write(&I2C_0.io, buf, 2);
/* Set to temperature register. */
buf[0] = 0;
io_write(&I2C_0.io, buf, 1);
for (;;) {
if (io->read(io, (uint8_t *)&data, 2) == 2) {
/* read OK, handle data. */;
} else {
/* error. */;
}
}
}
#define TASK_TRANSFER_STACK_SIZE ( 256/sizeof( portSTACK_TYPE ))
#define TASK_TRANSFER_STACK_PRIORITY ( tskIDLE_PRIORITY + 0 )
static TaskHandle_t xCreatedTransferTask;
static void task_transfer_create(void)
{
/* Create the task that handles the CLI. */
if (xTaskCreate(I2C_example_task, "transfer", TASK_TRANSFER_STACK_SIZE, NULL,
TASK_TRANSFER_STACK_PRIORITY, &xCreatedTransferTask) != pdPASS) {
while(1) {;
}
}
}
static void tasks_run(void)
{
vTaskStartScheduler();
}
int main(void)
{
/* Initializes MCU, drivers and middleware */
atmel_start_init();
task_transfer_create();
tasks_run();
/* Replace with your application code */
while (1) {
}
}
The I2C master peripheral and its related I/O lines and clocks
The NVIC must be configured so that I2C interrupt requests are periodically serviced
RTOS