monoZ docs
SPI EXAMPLE

Objectives of Example

  1. Demonstrate how to create a SPI instance, configure and integrate the SPI instance with monoZ_Lib
  2. Demonstrate how to use SPI in different modes for receiving data
  3. Demonstrate how to create a Application Thread using monoZ_Lib
  4. Demonstrate how to create single-shot and recursive timers, and use them.
  5. Demonstrate how to use CLI for printing information.

Example construct

1. monoZ_Lib context Setup

There are certain context variables provided by user to initialize all the context required by the monoZ_Lib.
i. Hardware related context[Mandatory]
ii. Modem related context[Optional]

i. Hardware related context

The definitions of all hardware context variables are present in “MZ_public.h” header file. The sample template for using is also provided in the same header file.

a. Main context variable

User must create this context variable for successful use of the library. In case the context variable is not created by user, The monoZ_Lib will not initialize and a linker error will occur.

  • monoZ Click tool user

    Incase using tool, this variable is created and placed in "MZ_hardware_config.c"

    SPI Sample code implementation

    extern MZ_SPI_INIT_ST spi1_instance;
    
    spi_enable spi_enable_cfg =
    {
    .s2 = MZI_SPI2,
    .s2p = 0,
    .s3 = MZI_SPI3,
    .s3p = 0,
    
    };
    

b. SPI Peripheral context variable

User must create the peripheral context variable for the desired interface and use it in Main context variable. In case of the SPI example, any free SPI interface for sensor communication can be used. monoZ_Lib takes all SPI related initialization context through “spi_enable_cfg“ context variable. For the SPI application, we need to define a peripheral context variable. Let’s say “spi1_instance”.

  • monoZ Click tool user

    User have to create the SPI instance first in the tool and then associate the instance to the example application during SPI example creation. Incase using tool, this variable is created and placed in "MZ_spiX_instance.c"

    SPI Sample code implementation

    MZ_SPI_INIT_ST spi1_instance =
    {
            .Instance = MZ_SPI1_INSTANCE,
            .Init.Mode = MZ_SPI1_INIT_MODE,
            .Init.Direction = MZ_SPI1_INIT_DIRECTION,
            .Init.DataSize = MZ_SPI1_INIT_DATASIZE,
            .Init.CLKPolarity = MZ_SPI1_INIT_CLKPOLARITY,
            .Init.CLKPhase = MZ_SPI1_INIT_CLKPHASE,
            .Init.NSS = MZ_SPI1_INIT_NSS,
            .Init.BaudRatePrescaler = MZ_SPI1_INIT_BAUDRATEPRESCALER,
            .Init.FirstBit = MZ_SPI1_INIT_FIRSTBIT,
            .Init.TIMode = MZ_SPI1_INIT_TIMODE,
            .Init.CRCCalculation = MZ_SPI1_INIT_CRCCALCULATION,
            .Init.CRCPolynomial = MZ_SPI1_INIT_CRCPOLYNOMIAL,
            .Init.CRCLength = MZ_SPI1_INIT_CRCLENGTH,
            .Init.NSSPMode = MZ_SPI1_INIT_NSSPMODE
    };
    

ii. Modem related context

User must create the modem context functions if wish to initialize modem with specific configuration. There are 2 function definitions present to provide flexibility. The names of the function are fixed. User need to define the function with this exact name. Prototype of the functions are as follows:

  • void mz_reset_sequence (void * arg) This function will execute all ATcommands required to initialize modem during Power ON.
  • void mz_reboot_sequence (void * arg) This function will execute all ATcommands required to initialize modem during Wakeup.
  • Here we are setting the configurations like power saving mode,Device Configurations and its control settings.
  • Also the time out for a particular API can also be defined and even the duration between API consecutive hits can be specified.
  • Access point can be defined to which we need to use.
  • LWM2M configurations are been defined and set using the AT commands. LWM2M commands are been set with different input params.
  • Device has been rebooted using Z AT command and and board is reinitialized using AT command. Once the Device is reinitialized, set of AT commands like AT command initialization, registration and reading the Clock value.
  • LWM2M initialization is done and command is issued.

Note: User must define the desired AT commands need to be executed during these actions.

  • monoZ Click tool user

    Incase using tool, these functions are created and placed in "MZ_modem_config.c"

    Sample code implementation

    void mz_reset_sequence(void * arg)
    {
        (void)arg;
        mz_power_config();
        mz_apn_set();
        mz_lwm2m_config();
        mz_device_reboot();
        mz_device_start();
        mz_lwm2m_start();
    }
    
    Void mz_reboot_sequence(void * arg)
    {
        (void)arg;
        mz_device_reboot();
        mz_device_start();
        mz_lwm2m_start();
    }
    
    Note
    1. In case no context function is defined by user, a default context is taken by monoZ_Lib to initialize the modem.
    2. In case blank context function is defined by user, Modem will be on without any initialization.
    3. In case of user wish to use any protocol related feature, its mandatory to define the context by user.

2. monoZ_Lib Initialization and start

User must initialize the monoZ_Lib before it can start using the library features. The monoZ Library can be initialized using the API MZ_init (). “MZ_main. h” header file provides a sample use of how to initialize the library.

  • monoZ Click tool user

    Incase using tool, monoZ Library initialization code is placed inside main() API present in main.c

    Sample code implementation

    mz_version ver = {
            ._major = MZ_SW_VERSION_MAJOR,
            ._minor = MZ_SW_VERSION_MINOR,
            ._patch = MZ_SW_VERSION_PATCH
      };
    if(MZ_OK != MZ_init(&ver))
    {
        Error_Handler();
    }
    
    Note
    The initialization function should be called prior to FreeRTOS kernel initialization.

3. Application creation and start

The SPI Application initialization is done before the Main FreeRTOS kernel starts. User must create a user application using the monoZ Library API’s.

  • monoZ Click tool user

    Incase using tool, the code is generated and placed in "MZ_spi_example.c" and the code is called within main in "main.c" .

    SPI Sample code implementation

    • The SPI main user application function
        static void spi_app(void * arg)
        {
            …
        }
      


    • The SPI main user application initialization function
        mz_error_t spi_app_init(void)
        {
            …
            if(!mz_thread_create(    &spi_thread_id,
                        "spi_example Scheduler",
                        spi_app,
                        NULL,
                        osPriorityNormal,
                        spi_stack,
                        SPI_APP_STACK_SIZE,
                        &spi_cb_mem,
                        sizeof(spi_cb_mem)))
        {
            _ret = MZ_THREAD_CREATE_FAIL;
        }
      
            ...
        }
      



    • The SPI main user application initialization function called from main.c
        /* creation of user task */
        if(MZ_OK != spi_app_init())
        {
            Error_Handler();
        }
      
      Note
      The user application must be created after FreeRTOS Kernel initialization and before FreeRTOS main scheduler start to avoid delay in application start. It will ensure the user application starts at the time of FreeRTOS scheduler starts.

4. Application Process

User must design the application based on requirements. Application should send SPI data periodically.

SPI Sample code implementation

  • Create and start the timer
      if(MZ_OK != mz_tm_create_start_recursive("SPI Read timer",SPI_TX_TIME,timer_cb))
      {
          /* Timer create and start failed. */
          __NOP(); /* Dummy No operation statement */
      }
    

  • Call back function is provided while creating timer, this call back will be called by monoZ Library when the timer expires.
      static void timer_cb(TimerHandle_t xTimer)
      {
          mz_puts("Timer expires\r\n");
          MZ_SPI_Transmit_IT(MZ_SPI_INSTANCE,(uint8_t *)&send_data, sizeof(send_data));
      }
    

5. Miscellaneous

a. How to use SPI in interrupt mode.

User must register SPI event callback to use SPI in interrupt mode.

  • Here is a sample code used to register receive event callback for SPI1.
      MZ_SPI_register_intr_cb_tx(MZ_SPI_INSTANCE,spi1_tx_intr);
    
    The callback API spi1_rx_intr () will be called by monoZ_Lib after spi receive interrupt is generated by MCU. User must first set the SPI in receive interrupt mode when expecting data to be received on interface.
  • Here is a sample code used for receiving data on interrupt mode
      MZ_SPI_Receive_IT(MZ_SPI_INSTANCE, (uint8_t *)&rx_char, 1);
    
    For more details user can check "MZ_spi.h"


b. How to use SPI in polling mode.

  • Here is a sample code used for transmitting data on polling mode.
      MZ_SPI_Transmit(_SPI1, &transmit_buffer, sizeof(transmit_buffer), 1000);
    

source code

Click here to access the source code of this file.