Creating I2C Interrupt using Atmel Start

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi everybody out there, 
I am new at embedded system programming, so I apologize if I make any kind of mistake.
I am trying to create an interrupt for I2C Slave mode using Atmel Start. But could not find any way to do this.  I used to use CubeMX and it was so easy to create interrupt. Just click "enable interrupt" or something like that. But could find it on Atmel Studio. 
Does anyone know how to create an I2C IRQ handler using Atmel Studio?

Btw ii am using SAME54 X Plained Pro Discovery Board.

Last Edited: Mon. Jun 10, 2019 - 02:28 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In theory (I never tried this): add the I2C driver "HAL:Driver:I2C_Slave_Async".  Then look in the examples/driver_examples.c at the callback and the way to register it (it will be called by the interrupt handler which is part of the driver).

/Lars

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Unfortunately. The functions are below;

 

/*
 * Code generated from Atmel Start.
 *
 * This file will be overwritten when reconfiguring your Atmel Start project.
 * Please copy examples or other code you want to keep to a separate file
 * to avoid losing it when reconfiguring.
 */

#include "driver_examples.h"
#include "driver_init.h"
#include "utils.h"

 

void I2C_0_example(void)
{
    struct io_descriptor *io;
    uint8_t               c;

    i2c_s_sync_get_io_descriptor(&I2C_0, &io);
    i2c_s_sync_set_addr(&I2C_0, 0x21);
    i2c_s_sync_enable(&I2C_0);

    io_read(io, &c, 1);
}

 

 

/**
 * Example of using EDBG_COM to write "Hello World" using the IO abstraction.
 *
 * Since the driver is asynchronous we need to use statically allocated memory for string
 * because driver initiates transfer and then returns before the transmission is completed.
 *
 * Once transfer has been completed the tx_cb function will be called.
 */

 

static uint8_t example_EDBG_COM[12] = "Hello World!";

 

static void tx_cb_EDBG_COM(const struct usart_async_descriptor *const io_descr)
{
    /* Transfer completed */
}

 

void EDBG_COM_example(void)
{
    struct io_descriptor *io;

    usart_async_register_callback(&EDBG_COM, USART_ASYNC_TXC_CB, tx_cb_EDBG_COM);
    /*usart_async_register_callback(&EDBG_COM, USART_ASYNC_RXC_CB, rx_cb);
    usart_async_register_callback(&EDBG_COM, USART_ASYNC_ERROR_CB, err_cb);*/
    usart_async_get_io_descriptor(&EDBG_COM, &io);
    usart_async_enable(&EDBG_COM);

    io_write(io, example_EDBG_COM, 12);
}

 

/**
 * Example of using USART_0 to write "Hello World" using the IO abstraction.
 *
 * Since the driver is asynchronous we need to use statically allocated memory for string
 * because driver initiates transfer and then returns before the transmission is completed.
 *
 * Once transfer has been completed the tx_cb function will be called.
 */

static uint8_t example_USART_0[12] = "Hello World!";

 

static void tx_cb_USART_0(const struct usart_async_descriptor *const io_descr)
{
    /* Transfer completed */
}

 

void USART_0_example(void)
{
    struct io_descriptor *io;

    usart_async_register_callback(&USART_0, USART_ASYNC_TXC_CB, tx_cb_USART_0);
    /*usart_async_register_callback(&USART_0, USART_ASYNC_RXC_CB, rx_cb);
    usart_async_register_callback(&USART_0, USART_ASYNC_ERROR_CB, err_cb);*/
    usart_async_get_io_descriptor(&USART_0, &io);
    usart_async_enable(&USART_0);

    io_write(io, example_USART_0, 12);
}
 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You need the async driver, the example looks like this

/*
 * Code generated from Atmel Start.
 *
 * This file will be overwritten when reconfiguring your Atmel Start project.
 * Please copy examples or other code you want to keep to a separate file
 * to avoid losing it when reconfiguring.
 */

#include "driver_examples.h"
#include "driver_init.h"
#include "utils.h"

static struct io_descriptor *io;

static void I2C_0_rx_complete(const struct i2c_s_async_descriptor *const descr)
{
    uint8_t c;

    io_read(io, &c, 1);
}

void I2C_0_example(void)
{
    i2c_s_async_get_io_descriptor(&I2C_0, &io);
    i2c_s_async_register_callback(&I2C_0, I2C_S_RX_COMPLETE, I2C_0_rx_complete);
    i2c_s_async_enable(&I2C_0);
}

/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So, where is the interrupt function?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

The callback is your interrupt function,  it will be called from the actual interrupt handler which is part of the driver.

/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But i want to use I2C slave sync mode. In sync mode driver, there is not callback functions (interrupt). So, i will change my question.

Do you know how to use interrupt (IRQ handler or callback function) when I2C slave is in sync mode? 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't see the point, you would have to write this yourself. And what to do should be what's already done in the async driver (look in hpl_sercom.c).

/Lars

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you man, 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

By the way. what does async mean in I2C. I2C is a synchronous communication protocol. As i understood async do not use Clock signal but i2c is based on clock signal !!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Synchronous vs. asynchronous in the context of ASF4 drivers is explained here (2.2.2 Driver Variants):

http://ww1.microchip.com/downloads/en/DeviceDoc/50002633B.pdf

/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

oh! page 271 as  I2C Slave Asynchronous Driver. Thank you. This paper will help me a lot.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Were you able to develop an I2C interrupt based on this ?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

[edit]: moved my reply in a new post

Last Edited: Thu. Jul 1, 2021 - 07:16 AM