5.3.1. How to use your shield with EGOS

At the application level, EGOS is independent from the hardware. In that way, the application will be the same for all supported devices. As the application's developer is not supposed to know the hardware description of the used board, there are some levels of abstraction. The application is not going to write directly on the MCU pins, so there are some abstraction functions to write on the correct MCU port and pin without knowing where it is physically written by the application side. To this end, the developers need to create these interfaces. We consider here that the MCU layer is already implemented. The first abstraction level comes in the HAL files (Hardware Abstraction Layer). This first level is not usable in the application side but only by the driver side which will abstract the HAL. The focus is done here on the HAL. Let us take an example on an accelerometer which communicates with I2C bus with the MCU.

abstraction

These functions don't do the same things. The higher functions integrate more functionalities: for example the driver function also configures the accelerometer behavior whereas the MCU function only configures the I2C communication.

The definition of the interfaces are isolated in two parts:

  • The communication part which defines the protocol configuration (bitrate, size of frame ...)
  • The PCB part which defines the hardware mapping

The follow-up of this presentation will be focused on the I2C communication between a support Click board and the STM Nucleo board.

To use the Click board with an I2C communication with the MCU, the PC0 and PC1 need to be defined in I2C. To do that, we need to define:

  • the HAL pin ID to be used to configure correctly the right pin with the right configuration. As the configuration of the hardware is done within arrays, it is important to always declare the pins in the same order.
  • the GPIO definitions to link the HAL pin ID with a clock and the configuration of the I2C
  • the GPIO configuration to declare the byte order or if it is an input or an output and then link the pin ID with the GPIO definitions
  • an array to link the MCU and the HAL layers

5.3.1.1. Files in the public area

All the files presented in this part are located in EGOS_Project -> 2_USER -> SRC -> inc -> egos_hal -> BSP -> .

5.3.1.1.1. egos_hal_pin__def.h

The ID of the pins are defined here in an enum data type. This ID, called eHalPin_Id, is used then to link the configuration with the right pins, so it is important to define it in the same order in every following files. The eHalPin_Id corresponds to the array's index of the following hardware configuration.

An eHalPin definition example:

DECL_TYPEDEF(enum, eHalPin_Id)
// = = = NUCLEO-L476RG SPECIFIC = = = = = = = = = = = = = = = = = = = = = = = =
{ eHAL_PIN__ID__LED     = 0                     ///< User green LED (LD2)
, eHAL_PIN__ID__BUTTON                          ///< User button (B1-PUP)
// Arduino connector
// Mikroelectonika Click Shield
, eHAL_PIN__ID__CLICK_I2C_SCL                   ///< I2C SCL/A5
, eHAL_PIN__ID__CLICK_I2C_SDA                   ///< I2C SDA/A4
// Morpho connector only
//
// = = = NUCLEO-L476RG SPECIFIC = = = = = = = = = = = = = = = = = = = = = = = =
//
, eHAL_PIN__ID
}   DECL_INSTANCE(enum, eHalPin_Id);

5.3.1.2. Files in the private area

All the files presented in this part are located in EGOS_Project -> 1_BSPC -> SRC -> src -> egos_hal -> BSP -> .

5.3.1.2.1. hal__impl_bsp_’board_name’__com.h

The constant GPIO definitions are defined here. It defines the GPIO clock to enable the GPIO port or the pins used to a specific behavior (SPI, I2C, ...). It fills some structure fields to configure correctly the GPIO in EGOS environment then. On the NUCLEO-L476RG, the PC0 and PC1 pins are linked to the I2C3 instance.

A constant GPIO definitions example:

There is only one definition here for the I2C as the pins are linked together

#define cHAL_COM_GPIO__MODE__OUT            (cMCU_DEV_IO_GP__MODE__OUTPUT)
#define cHAL_COM_GPIO__MODE__IN             (cMCU_DEV_IO_GP__MODE__INPUT)

#define cHAL_COM_GPIO__PINS__I2C3           { .sMcuI2c = { .nScl = cMCU_DEV_IO_GP__PIN__PC0_I2C3_SCL, .nSda = cMCU_DEV_IO_GP__PIN__PC1_I2C3_SDA } }

5.3.1.2.2. hal__impl_bsp_’board_name’__com.cxx

  • An array of structure g_acsHalCom_Conf is declared here to define for each pin:

  • the GPIO mode (in/out for standard GPIO pins, DMA RX TX for the communication pins)

  • its configuration (big/little endian for GPIO or bitrate and other additional parameters for the communication protocols)

A g\_acsHalCom\_Conf example:

csHalCom_Conf   g_acsHalCom_Conf[]
//      nPriority   nMode                           sCfg                                            eHalCom_Id
// = = = NUCLEO-L476RG SPECIFIC = = = = = = = = = = = = = = = = = = = = = = = =
=   { { 0,          cHAL_COM_GPIO__MODE__OUT,       { .sGpio = cHAL_COM_GPIO__CONF__BIG_ENDIAN } }  ///< eHAL_COM__ID__LED
    , { 0,          cHAL_COM_GPIO__MODE__IN,        { .sGpio = cHAL_COM_GPIO__CONF__BIG_ENDIAN } }  ///< eHAL_COM__ID__BUTTON
// Arduino connector
// Mikroelectonika Click Shield
    , { 0,          cHAL_COM_I2C__MODE__DMA_RX_TX,  { .sI2c = cHAL_COM_I2C__CONF__FULL } }          ///< eHAL_COM__ID__CLICK_I2C
// Morpho connector only
//
// = = = NUCLEO-L476RG SPECIFIC = = = = = = = = = = = = = = = = = = = = = = = =
    };
  • An array of structure g_acsHalCom to link the GPIO communication configuration to the corresponding pins. In this way, the structure is filled with:

    • the communication type (GPIO, SPI, I2C, ...)
    • the eHalPin_Id defined in the public area
    • the constant GPIO definitions defined previously in the communication header file --TODO Needs to be developed--
    • the ePwrId
    • the eCS

A g_acsHalCom example:

csHalCom    g_acsHalCom[]
//      eType                   uInstance                                               uPins                           ePwrId          eCs             eHalCom_Id
// = = = NUCLEO-L476RG SPECIFIC = = = = = = = = = = = = = = = = = = = = = = = =
=   { { eHAL_COM__TYPE__GPIO,   { .ePinId = eHAL_PIN__ID__LED },                        cHAL_COM_GPIO__PINS__LED,       eHAL_PWR__ID,   eHAL_COM__CS }  ///< eHAL_COM__ID__LED
    , { eHAL_COM__TYPE__GPIO,   { .ePinId = eHAL_PIN__ID__BUTTON },                     cHAL_COM_GPIO__PINS__BUTTON,    eHAL_PWR__ID,   eHAL_COM__CS }  ///< eHAL_COM__ID__BUTTON
// Arduino connector
//  Mikroelectonika Click Shield
    , { eHAL_COM__TYPE__I2C,    { .eMcuI2c = eMCU_DEV_COM_I2C__INSTANCE__I2C3 },        cHAL_COM_GPIO__PINS__I2C3,      eHAL_PWR__ID,   eHAL_COM__CS }  ///< eHAL_COM__ID__CLICK_I2C
// Morpho connector only
//
// = = = NUCLEO-L476RG SPECIFIC = = = = = = = = = = = = = = = = = = = = = = = =
    };

5.3.1.2.3. hal__impl_bsp_’board_name’__pcb.cxx

  • The g_acsHalPcb_Pin array of structure is defined to attached the pin configuration to the mcu pin by given:

    • the mcu pin name
    • the configuration (analogical, in , out, inout, ...)
    • the default logic state (high, low, high impedance)

A g_acsHalPcb_Pin example:

csHalPcb_Pin    g_acsHalPcb_Pin[eHAL_PIN__ID]
//      nPin                                    eConf                   eLevel                  eHalPin_Id
// = = = NUCLEO-L476RG SPECIFIC = = = = = = = = = = = = = = = = = = = = = = = =
=   { { cMCU_DEV_IO_GP__PIN__PA5,               eHAL_PIN__CONF__OUT,    eHAL_PIN__LEVEL__HIGH } ///< eHAL_PIN__ID__LED
    , { cMCU_DEV_IO_GP__PIN__PC13,              eHAL_PIN__CONF__IN,     eHAL_PIN__LEVEL__LOW }  ///< eHAL_PIN__ID__BUTTON
// Arduino connector
//  Mikroelectonika Click Shield
    , { cMCU_DEV_IO_GP__PIN__PC0_I2C3_SCL,      eHAL_PIN__CONF__ALT,    eHAL_PIN__LEVEL__HIGH } ///< eHAL_PIN__ID__CLICK_I2C_SCL
    , { cMCU_DEV_IO_GP__PIN__PC1_I2C3_SDA,      eHAL_PIN__CONF__ALT,    eHAL_PIN__LEVEL__HIGH } ///< eHAL_PIN__ID__CLICK_I2C_SDA
// Morpho connector only
//
// = = = NUCLEO-L476RG SPECIFIC = = = = = = = = = = = = = = = = = = = = = = = =
    };
  • The g_acsHalPcb_PinConf is also introduce here to link the pin with:

  • (if necessary the pin) an Exti line in the interruption mode --TODO Need to be developed--

  • a PWM instance
  • an ADC

A g_acsHalPcb_PinConf example:

csHalPcb_PinConf    g_acsHalPcb_PinConf[eHAL_PIN__ID]
//      sAttr               ePwmInstance                    ePwmChannel                 eAdcInput                   eHalPin_Id
// = = = NUCLEO-L476RG SPECIFIC = = = = = = = = = = = = = = = = = = = = = = = =
=   { { { 0 },              eHAL_PCB__PWM_INSTANCE,         eHAL_PCB__PWM_CHANNEL,      eHAL_PCB__ADC_INPUT }       ///< eHAL_PIN__ID__LED
    , { mHAL_PCB__PIN_ATTR
        ( .nExti    = 1
        , .nMode    = eHAL_IRQ__MODE__FALLING
        ),                  eHAL_PCB__PWM_INSTANCE,         eHAL_PCB__PWM_CHANNEL,      eHAL_PCB__ADC_INPUT }       ///< eHAL_PIN__ID__BUTTON
// Arduino connector
//  Mikroelectonika Click Shield
    , { { 0 },              eHAL_PCB__PWM_INSTANCE,         eHAL_PCB__PWM_CHANNEL,      eHAL_PCB__ADC_INPUT }       ///< eHAL_PIN__ID__CLICK_I2C_SCL
    , { { 0 },              eHAL_PCB__PWM_INSTANCE,         eHAL_PCB__PWM_CHANNEL,      eHAL_PCB__ADC_INPUT }       ///< eHAL_PIN__ID__CLICK_I2C_SDA
// Morpho connector only
//
// = = = NUCLEO-L476RG SPECIFIC = = = = = = = = = = = = = = = = = = = = = = = =
    };

5.3.1.2.4. hal__impl_bsp_’board_name’_.c

This file includes the PCB and COM .cxx files in your EGOS. It also includes the HAL files of your microcontroller (ana, bin, com, irq, pcb, pin, pwr, rtc).