Peripheral Interface Development Guide

Introduction

Quectel FLMx40D, FCMxx0D and FC41D modules support QuecOpen® solution. QuecOpen® is an embedded development platform based on RTOS system, which is intended to simplify the design and development of IoT applications. For more information on QuecOpen®, see Quick_Start_Guide.

This document is applicable to QuecOpen® solution based on SDK build environment. It outlines how to use GPIO, UART, SPI, I2C, ADC, and PWM APIs supported by the modules to develop corresponding peripheral interfaces in QuecOpen® solution.

NOTE

  1. The module supports two UARTs currently and these UARTs buffer data in FIFO mode by default.
  2. In SPI mode, the maximum frequency of the master device is 30 MHz, and the maximum frequency of the slave device is 10 MHz.

Applicable Modules

Module Family Module
FC41D
FCMxx0D FCM100D
FCM740D
FLMx40D FLM040D
FLM140D
FLM240D
FLM340D

GPIO API

Header File

ql_gpio.h, the header file of GPIO API, is in ql_components/qadpt/include/ directory. Unless otherwise specified, all header files mentioned in this document are in this directory.

API Description

ql_gpio_init

This function initializes the GPIO.

  • Prototype
ql_gpio_errcode_e ql_gpio_init(ql_gpio_num_e gpio_num, ql_gpio_mode_e mode)
  • Parameter

gpio_num:

[In] GPIO pin number. See ql_gpio_num_e for details.

mode:

[In] GPIO mode. See ql_gpio_mode_e for details.

  • Return Value

Result code. See ql_gpio_errcode_e for details.

ql_gpio_num_e

The enumeration of GPIO pin numbers:

typedef enum
{
  QL_GPIO0 = 0,
  QL_GPIO1,
  QL_GPIO6 = 6,
  QL_GPIO7,
  QL_GPIO8,
  QL_GPIO9,
  QL_GPIO10,
  QL_GPIO11,
  QL_GPIO14 = 14,
  QL_GPIO15,
  QL_GPIO16,
  QL_GPIO17,
  QL_GPIO20 = 20,
  QL_GPIO21,
  QL_GPIO22,
  QL_GPIO23,
  QL_GPIO24,
  QL_GPIO26 = 26,
  QL_GPIO28 = 28,
} ql_gpio_num_e;
  • Member
Member Description
QL_GPIO0 GPIO0
QL_GPIO1 GPIO1
QL_GPIO6 GPIO6
QL_GPIO7 GPIO7
QL_GPIO8 GPIO8
QL_GPIO9 GPIO9
QL_GPIO10 GPIO10
QL_GPIO11 GPIO11
QL_GPIO14 GPIO14
QL_GPIO15 GPIO15
QL_GPIO16 GPIO16
QL_GPIO17 GPIO17
QL_GPIO20 GPIO20
QL_GPIO21 GPIO21
QL_GPIO22 GPIO22
QL_GPIO23 GPIO23
QL_GPIO24 GPIO24
QL_GPIO26 GPIO26
QL_GPIO28 GPIO28
ql_gpio_mode_e

The enumeration of GPIO modes:

typedef enum
{
  QL_GMODE_INPUT_PULLDOWN = 0,
  QL_GMODE_OUTPUT,
  QL_GMODE_SECOND_FUNC,
  QL_GMODE_INPUT_PULLUP,
  QL_GMODE_INPUT,
  QL_GMODE_SECOND_FUNC_PULL_UP, //Special for uart1
  QL_GMODE_OUTPUT_PULLUP,
  QL_GMODE_SET_HIGH_IMPENDANCE,
  QL_GMODE_DEEP_PS,
} ql_gpio_mode_e;
  • Member
Member Description
QL_GMODE_INPUT_PULLDOWN Input is configured for pull-down
QL_GMODE_OUTPUT Output is configured for push-pull
QL_GMODE_SECOND_FUNC Second functionality of the GPIO
QL_GMODE_INPUT_PULLUP Input is configured for pull-up
QL_GMODE_INPUT Input is configured for floating
QL_GMODE_SECOND_FUNC_PULL_UP Pull up the second functionality of the pin (Only available for UART1)
QL_GMODE_OUTPUT_PULLUP Output is configured for pull-up (Not supported currently)
QL_GMODE_SET_HIGH_IMPENDANCE High impedance
QL_GMODE_DEEP_PS High impedance
ql_gpio_errcode_e

The enumeration of GPIO API result codes:

typedef enum
{
  QL_GPIO_SUCCESS = 0,
  QL_GPIO_EXECUTE_ERR,
  QL_GPIO_INVALID_PARAM_ERR,
} ql_gpio_errcode_e;
  • Member
Member Description
QL_GPIO_SUCCESS Successful execution
QL_GPIO_EXECUTE_ERR Failed execution
QL_GPIO_INVALID_PARAM_ERR Invalid parameter

ql_gpio_set_level

This function sets the pin level of the specified GPIO. It is valid only for output pins.

  • Prototype
ql_gpio_errcode_e ql_gpio_set_level(ql_gpio_num_e gpio_num, ql_gpio_output_level_e output_level)
  • Parameter

gpio_num:

[In] GPIO pin number. See ql_gpio_num_e for details.

output_level:

[In] Pin level only for output pins. See ql_gpio_output_level_e for details.

  • Return Value

Result code. See ql_gpio_errcode_e for details.

ql_gpio_output_level_e

The enumeration of GPIO output levels:

typedef enum
{
  QL_GPIO_OUTPUT_LOW = 0,
  QL_GPIO_OUTPUT_HIGH,
} ql_gpio_output_level_e;
  • Member
Member Description
QL_GPIO_OUTPUT_LOW Low level
QL_GPIO_OUTPUT_HIGH High level

ql_gpio_set_level_reverse

This function reverses the GPIO output level. It is valid only for output pins.

  • Prototype
ql_gpio_errcode_e ql_gpio_set_level_reverse(ql_gpio_num_e gpio_num)
  • Parameter

gpio_num:

[In] GPIO pin number. See ql_gpio_num_e for details.

  • Return Value

Result code. See ql_gpio_errcode_e for details.

ql_gpio_get_level

This function gets the pin level of the specified GPIO.

  • Prototype
ql_gpio_errcode_e ql_gpio_get_level(ql_gpio_num_e gpio_num, UINT32 *input_level)
  • Parameter

gpio_num:

[In] GPIO pin number. See ql_gpio_num_e for details.

input_level:

[Out] Pin level value.

  • Return Value

Result code. See ql_gpio_errcode_e for details.

ql_gpio_int_init

This function initializes and enables the GPIO interrupt.

  • Prototype
ql_gpio_errcode_e ql_gpio_int_init(ql_gpio_num_e gpio_num, ql_gpio_irq_trigger_e trigger, ql_gpio_irq_callback calback)
  • Parameter

gpio_num:

[In] GPIO pin number. See ql_gpio_num_e for details.

trigger:

[In] GPIO interrupt triggering mode. See ql_gpio_irq_trigger_e for details.

calback:

[In] GPIO interrupt callback function. See ql_gpio_irq_callback for details.

  • Return Value

Result code. See ql_gpio_errcode_e for details.

ql_gpio_irq_trigger_e

The enumeration of GPIO interrupt triggering modes:

typedef enum
{
  QL_IRQ_TRIGGER_LOW_LEVEL = 0x0,
  QL_IRQ_TRIGGER_HGIH_LEVEL,
  QL_IRQ_TRIGGER_RISING_EDGE,
  QL_IRQ_TRIGGER_FALLING_EDGE,
} ql_gpio_irq_trigger_e;
  • Member
Member Description
QL_IRQ_TRIGGER_LOW_LEVEL Pin interrupt triggered at low level
QL_IRQ_TRIGGER_HGIH_LEVEL Pin interrupt triggered at high level
QL_IRQ_TRIGGER_RISING_EDGE Pin interrupt triggered at rising edge
QL_IRQ_TRIGGER_FALLING_EDGE Pin interrupt triggered at falling edge
ql_gpio_irq_callback

This is the callback function of GPIO interrupt.

  • Prototype
typedef void (*ql_gpio_irq_callback)(void *arg)
  • Parameter

arg:

[In] Pin for triggering the interrupt.

ql_gpio_int_disable

This function disables the configured GPIO interrupt.

  • Prototype
ql_gpio_errcode_e ql_gpio_int_disable(ql_gpio_num_e gpio_num)
  • Parameter

gpio_num:

[In] GPIO pin number. See ql_gpio_num_e for details.

  • Return Value

Result code. See ql_gpio_errcode_e for details.

GPIO Development Process

This chapter explains how to use the above GPIO API to configure GPIO and perform basic debugging. The following subsections take QL_GPIO6 as an example.

GPIO Operation

The example of how to operate the GPIO is provided in the module SDK. The demo is in ql_gpio_demo.c file in the ql_application/quectel_demo directory. The descriptions of related functions are as follows:

  • ql_gpio_demo_thread_creat(): This function creates GPIO tasks. You need to call this function to run demo.

  • ql_gpio_demo_thread(): This function executes the task. It implements GPIO initialization, output level configuration and interrupt triggering functionalities.

To run the demo, enable the macro definitions CFG_ENABLE_QUECTEL_DEMO and CFG_ENABLE_QUECTEL_GPIO. This will automatically trigger the execution of ql_gpio_demo_thread_creat() and ql_gpio_demo_thread() to create a test task.

Example: Creating a GPIO Task

Example: Using GPIO API

Function Debugging

You need to use the development board (Take FC41D TE-B as an example) with the module to debug the GPIO function. Follow these steps for debugging:

  1. Run the GPIO demo as explained in GPIO Operation.

  2. Recompile the firmware version and flash it to the module.

  3. Reboot the module.

  4. Open UART 2 to obtain the debugging log. The log information will be displayed as follows:

    Getting Log via Serial Port Tool

If the following information is displayed during the debugging, it indicates the GPIO interrupt has been triggered.

GPIO Test Log

UART API

Header File

ql_uart.h, the header file of GPIO API, is in the ql_components/qadpt/include/ directory. Unless otherwise specified, all header files mentioned in this document are in this directory.

API Description

ql_uart_set_dcbconfig

This function sets the UART properties. The UART properties take effect after the UART is reopened.

  • Prototype
ql_uart_errcode_e ql_uart_set_dcbconfig(ql_uart_port_number_e port, ql_uart_config_s *dcb)
  • Parameter

port:

[In] UART number. See ql_uart_port_number_e for details.

dcb:

[In] Configuration of UART properties. See ql_uart_config_s for details.

  • Return Value

Result code. See ql_uart_errcode_e for details.

ql_uart_port_number_e

The enumeration of UART numbers. The module currently supports only two UARTs.

typedef enum
{
  QL_UART_PORT_1,
  QL_UART_PORT_2,
} ql_uart_port_number_e;
  • Member
Member Description
QL_UART_PORT_1 UART 1
QL_UART_PORT_2 UART 2
ql_uart_config_s

The structure of the configuration of UART properties:

typedef struct
{
  ql_uart_baud_e baudrate;
  ql_uart_databit_e data_bit;
  ql_uart_stopbit_e stop_bit;
  ql_uart_parityit_e parity_bit;
  ql_uart_flowctrl_e flow_ctrl;
} ql_uart_config_s;
  • Parameter
Type Parameter Description
ql_uart_baud_e baudrate Baud rate. Default: 115200 bps. See ql_uart_baud_e for details.
ql_uart_databit_e data_bit Data bit. Default: 8 bits. See ql_uart_databit_e for details.
ql_uart_stopbit_e stop_bit Stop bit. Default: 1 bit. See ql_uart_stopbit_e for details.
ql_uart_parityit_e parity_bit Parity bit. Default: No parity bit. See ql_uart_parityit_e for details.
ql_uart_flowctrl_e flow_ctrl Flow control. Default: Disabled. See ql_uart_flowctrl_e for details.
ql_uart_baud_e

The enumeration of baud rates:

typedef enum
{
  QL_UART_BAUD_1200 = 1200,
  QL_UART_BAUD_2400 = 2400,
  QL_UART_BAUD_4800 = 4800,
  QL_UART_BAUD_9600 = 9600,
  QL_UART_BAUD_14400 = 14400,
  QL_UART_BAUD_19200 = 19200,
  QL_UART_BAUD_28800 = 28800,
  QL_UART_BAUD_33600 = 33600,
  QL_UART_BAUD_38400 = 38400,
  QL_UART_BAUD_57600 = 57600,
  QL_UART_BAUD_115200 = 115200,
  QL_UART_BAUD_230400 = 230400,
  QL_UART_BAUD_460800 = 460800,
  QL_UART_BAUD_921600 = 921600,
  QL_UART_BAUD_1000000 = 1000000,
  QL_UART_BAUD_2000000 = 2000000,
} ql_uart_baud_e;
  • Member
Member Description
QL_UART_BAUD_1200 1200 bps
QL_UART_BAUD_2400 2400 bps
QL_UART_BAUD_4800 4800 bps
QL_UART_BAUD_9600 9600 bps
QL_UART_BAUD_14400 14400 bps
QL_UART_BAUD_19200 19200 bps
QL_UART_BAUD_28800 28800 bps
QL_UART_BAUD_33600 33600 bps
QL_UART_BAUD_38400 38400 bps
QL_UART_BAUD_57600 57600 bps
QL_UART_BAUD_115200 115200 bps
QL_UART_BAUD_230400 230400 bps
QL_UART_BAUD_460800 460800 bps
QL_UART_BAUD_921600 921600 bps
QL_UART_BAUD_1000000 1000000 bps
QL_UART_BAUD_2000000 2000000 bps
ql_uart_databit_e

The enumeration of data bits:

typedef enum
{
  QL_UART_DATABIT_5 = 0,
  QL_UART_DATABIT_6,
  QL_UART_DATABIT_7,
  QL_UART_DATABIT_8,
} ql_uart_databit_e;
  • Member
Member Description
QL_UART_DATABIT_5 5 bits
QL_UART_DATABIT_6 6 bits
QL_UART_DATABIT_7 7 bits
QL_UART_DATABIT_8 8 bits
ql_uart_stopbit_e

The enumeration of stop bits:

typedef enum
{
  QL_UART_STOP_1 = 0,
  QL_UART_STOP_2,
} ql_uart_stopbit_e;
  • Member
Member Description
QL_UART_STOP_1 1 bit
QL_UART_STOP_2 2 bits
ql_uart_parityit_e

The enumeration of parity bits:

typedef enum
{
  QL_UART_PARITY_NONE,
  QL_UART_PARITY_ODD,
  QL_UART_PARITY_EVEN,
} ql_uart_parityit_e;
  • Member
Member Description
QL_UART_PARITY_NONE No parity
QL_UART_PARITY_ODD Odd parity
QL_UART_PARITY_EVEN Even parity
ql_uart_flowctrl_e

The enumeration of flow control types:

typedef enum
{
  QL_FC_NONE = 0,
  QL_FC_HW_CTS,
  QL_FC_HW_RTS,
  QL_FC_HW_RTS_CTS,
} ql_uart_flowctrl_e;
  • Member
Member Description
QL_FC_NONE No flow control
QL_FC_HW_CTS Hardware CTS
QL_FC_HW_RTS Hardware RTS
QL_FC_HW_RTS_CTS Hardware CTS and RTS
ql_uart_errcode_e

The enumeration of result codes:

typedef enum
{
  QL_UART_SUCCESS = 0,
  QL_UART_EXECUTE_ERR,
  QL_UART_MEM_ADDR_NULL_ERR,
  QL_UART_INVALID_PARAM_ERR,
  QL_UART_NOT_OPEN_ERR,
} ql_uart_errcode_e;
  • Member
Member Description
QL_UART_SUCCESS Successful execution
QL_UART_EXECUTE_ERR Failed execution
QL_UART_MEM_ADDR_NULL_ERR Parameter address: Null
QL_UART_INVALID_PARAM_ERR Invalid parameter
QL_UART_NOT_OPEN_ERR UART is not open

ql_uart_get_dcbconfig

This function gets the configuration of UART properties.

  • Prototype
ql_uart_errcode_e ql_uart_get_dcbconfig(ql_uart_port_number_e port, ql_uart_config_s *dcb)
  • Parameter

port:

[In] UART number. See ql_uart_port_number_e for details.

dcb:

[In] Configuration of UART properties. See in ql_uart_config_s for details.

  • Return Value

Result code. See in ql_uart_errcode_e for details.

ql_uart_open

This function opens the UART.

  • Prototype
ql_uart_errcode_e ql_uart_open(ql_uart_port_number_e port)
  • Parameter

port:

[In] UART number. See ql_uart_port_number_e for details.

  • Return Value

Result code. See ql_uart_errcode_e for details.

ql_uart_close

This function closes the UART.

  • Prototype
ql_uart_errcode_e ql_uart_close(ql_uart_port_number_e port)
  • Parameter

port:

[In] UART number. See ql_uart_port_number_e for details.

  • Return Value

Result code. See ql_uart_errcode_e for details.

ql_uart_write

This function writes data to the module through the UART.

  • Prototype
int ql_uart_write(ql_uart_port_number_e port, unsigned char *data, unsigned int data_len)
  • Parameter

port:

[In] UART number. See ql_uart_port_number_e for details.

data:

[In] Written data.

data_len:

[In] Length of written data.

  • Return Value

Result code. See ql_uart_errcode_e for details.

ql_uart_read

This function reads the data from the module through the UART.

  • Prototype
int ql_uart_read(ql_uart_port_number_e port, unsigned char *data, unsigned int data_len)
  • Parameter

port:

[In] UART number. See ql_uart_port_number_e for details.

data:

[Out] Read data.

data_len:

[In] Length of read data.

  • Return Value

Result code. See ql_uart_errcode_e for details.

ql_uart_set_rx_cb

This function registers the callback function triggered by the UART receiving data interrupt.

  • Prototype
ql_uart_errcode_e ql_uart_set_rx_cb(ql_uart_port_number_e port, ql_uart_callback uart_cb)
  • Parameter

port:

[In] UART number. See ql_uart_port_number_e for details.

uart_cb:

[In] Callback function to be registered. See in ql_uart_callback for details.

  • Return Value

Result code. See ql_uart_errcode_e for details.

ql_uart_callback

This is the callback function of the UART interrupt.

  • Prototype
typedef void (*ql_uart_callback)(int uport, void *param);
  • Parameter

uport:

[In] UART number. See ql_uart_port_number_e for details.

param:

[In] Input parameter.

  • Return Value

None

ql_uart_set_tx_int

This function sets the interrupt event that is triggered upon completion of data transmission.

  • Prototype
ql_uart_errcode_e ql_uart_set_tx_int(ql_uart_port_number_e port, unsigned int set)
  • Parameter

port:

[In] UART number. See ql_uart_port_number_e for details.

set:

[In] Control the interrupt event

1 Enable interrupt

2 Disable interrupt

  • Return Value

Result code. See ql_uart_errcode_e for details.

ql_uart_set_tx_cb

This function registers the callback function triggered when the UART initiates a data transmission.

  • Prototype
ql_uart_errcode_e ql_uart_set_tx_cb(ql_uart_port_number_e port, ql_uart_callback uart_cb)
  • Parameter

port:

[In] UART number. See ql_uart_port_number_e for details.

uart_cb:

[In] Callback function to be registered. See ql_uart_callback for details.

  • Return Value

Result code. See ql_uart_errcode_e for details.

UART Development Process

This chapter explains how to use the above UART API in the application and perform basic debugging. The following subsections take UART 1 as an example.

UART Operation

The example of how to operate the UART is provided in the module SDK. The demo is in ql_uart_demo.c file in the ql_application/quectel_demo directory. The descriptions of related functions are as follows:

  • ql_uart_demo_thread_creat(): This function creates a UART task. You need to call this function to run the demo.

  • ql_uart_demo_thread(): This function executes the task. It initializes the UART, sends, and receives data.

To run the demo, enable CFG_ENABLE_QUECTEL_DEMO and CFG_ENABLE_QUECTEL_UART. This will automatically trigger the execution of ql_uart_demo_thread_creat() and ql_uart_demo_thread() to create a task.

Creating a UART Task

Using UART API (I)

Example: Using UART API (II)

Function Debugging

You need to use the development board (Take FC41D TE-B as an example) with the module to debug the UART function. Follow these steps for debugging:

  1. Run the UART demo as explained in UART Operation.

  2. Recompile the firmware version and flash it to the module.

  3. Reboot the module.

  4. Open UART 1 to start the test.

  5. Open UART 2 to obtain log information. The log information will be displayed as follows:

Getting Log via Serial Port Tool

The data received by UART 1:

Test Data Received by UART 1

After a successful UART data reception test is completed, send twenty bytes of data with the UART tool to UART 1, as shown in the figure below:

Test Data Sent by UART 1

The information printed from UART 2 is shown as follows:

Log After Test Completion

It can be seen that the UART function has been tested successfully by comparing the sent data in *Figure 10* with the received data in *Figure 11*.

SPI API

For this module, SPI data are transferred in the DMA mode.

Header File

ql_spi.h, the header file of SPI API, is in ql_components/qadpt/include/ directory. Unless otherwise specified, all header files mentioned in this document are in this directory.

API Description

ql_spi_init

This function initializes SPI and must be called before using other SPI functions.

  • Prototype
ql_spi_errcode_e ql_spi_init(ql_spi_config_s spi_cfg, ql_spi_messag_s *spi_msg)
  • Parameter

spi_cfg:

[In] SPI configuration. See ql_spi_config_s for details.

spi_msg:

[In] Data sent or received via SPI. See ql_spi_messag_s for details.

  • Return Value

Result code. See ql_spi_errcode_e for details.

ql_spi_config_s

The structure of SPI configuration:

typedef struct
{
  UINT32 spiclk;
  ql_spi_cpol_pol_e cpol;
  ql_spi_cpha_pol_e cpha;
  ql_spi_transfer_mode_e transmode;
  ql_spi_master_slave_mode_e masterorslave;
} ql_spi_config_s;
  • Parameter
Type Parameter Description
UINT32 spiclk SPI clock frequency. Maximum value: 30 MHz
ql_spi_cpol_pol_e cpol SPI clock polarity. See ql_spi_cpol_pol_e for details.
ql_spi_cpha_pol_e cpha SPI clock phase. See ql_spi_cpha_pol_e for details.
ql_spi_transfer_mode_e transmode SPI transmitting mode. See ql_spi_transfer_mode_e for details.
ql_spi_master_slave_mode_e masterorslave SPI master or slave selection. See ql_spi_master_slave_mode_e for details.
ql_spi_cpol_pol_e

The enumeration of SPI clock polarities:

typedef enum
{
  QL_SPI_CPOL_LOW = 0,
  QL_SPI_CPOL_HIGH,
} ql_spi_cpol_pol_e
  • Member
Member Description
QL_SPI_CPOL_LOW SCK is at a low level during idle state
QL_SPI_CPOL_HIGH SCK is at a high level during idle state
ql_spi_cpha_pol_e

The enumeration of SPI clock phases:

typedef enum
{
  QL_SPI_CPHA_1Edge,
  QL_SPI_CPHA_2Edge,
}ql_spi_cpha_pol_e;
  • Member
Member Description
QL_SPI_CPHA_1Edge Sample data on the edge of the first period of SCK
QL_SPI_CPHA_2Edge Sample data on the edge of the second period of SCK
ql_spi_transfer_mode_e

The enumeration of SPI transmitting modes:

typedef enum {
  QL_SPI_MSB = 0,
  QL_SPI_LSB,
} ql_spi_transfer_mode_e;
  • Member
Member Description
QL_SPI_MSB MSB is sent first
QL_SPI_LSB LSB is sent first
ql_spi_master_slave_mode_e

The enumeration of SPI master or slave selections:

typedef enum {
  QL_SPI_MASTER = 0,
  QL_SPI_SLAVE,
} ql_spi_master_slave_mode_e;
  • Member
Member Description
QL_SPI_MASTER SPI is master
QL_SPI_SLAVE SPI is slave
ql_spi_messag_s

The structure of data sent or received via SPI:

typedef struct {
  UINT8 *send_buf;
  UINT32 send_len;
  UINT8 *recv_buf;
  UINT32 recv_len;
} ql_spi_messag_s;
  • Parameter
Type Parameter Description
UINT8 send_buf Sent data
UINT32 send_len Sent data length
UINT8 recv_buf Received data
UINT32 recv_len Received data length
ql_spi_errcode_e

The enumeration of SPI result codes:

typedef enum {
  QL_SPI_SUCCESS = 0,
  QL_SPI_EXECUTE_ERR,
} ql_spi_errcode_e;
  • Member
Member Description
QL_SPI_SUCCESS Successful execution
QL_SPI_EXECUTE_ERR Failed execution

ql_spi_transfer

This function sends and receives SPI data, and the sending mode or receiving mode depends on the configuration of the ql_spi_messag_s() structure.

  • Prototype
ql_spi_errcode_e ql_spi_transfer(ql_spi_messag_s *spi_msg)
  • Parameter

spi_msg:

[In] Data sent or received via SPI. See ql_spi_messag_s for details.

  • Return Value

Result code. See ql_spi_errcode_e for details.

SPI Development Process

This chapter explains how to use the above SPI API in applications, and perform basic debugging, and test data transmission from the master.

SPI Operation

The example of how to operate the SPI is provided in the module SDK. The demo is in ql_spi_demo.c file in the ql_application/quectel_demo directory. The descriptions of related functions are as follows:

  • ql_spi_demo_thread_creat(): Creates an SPI task. This function needs to be called to run the SPI demo.

  • ql_spi_demo_thread(): This function executes the task. It initializes DMA and sends data via SPI.

To run this example, you need to enable the CFG_ENABLE_QUECTEL_DEMO and CFG_ENABLE_QUECTEL_SPI macro definitions, while simultaneously disabling the CFG_SUPPORT_SPI_FLASH_TEST macro definition. This will automatically trigger the execution of ql_spi_demo_thread_creat() and ql_spi_demo_thread() to create a test task.

Creating an SPI Task

Using SPI API

Function Debugging

You need to use the development board (Take FC41D TE-B as an example) with the module to debug the SPI function. Follow these steps for debugging:

  1. Run the SPI demo as explained in SPI Operation.

  2. Recompile the firmware version and flash it to the module.

  3. Reboot the module.

  4. Capture waveforms through the logic analyzer.

  5. Open UART 2 to obtain log information. The log information will be displayed as follows.

Getting Log via Serial Port Tool

Capturing Waveforms Through Logic Analyzer

I2C API

Header File

ql_i2c1_eeprom.h, the header file of I2C API, is in ql_components/qadpt/include/ directory. Unless otherwise specified, all header files mentioned in this document are in this directory.

API Description

ql_I2cInit

This function initializes the I2C bus.

  • Prototype
int ql_I2cInit(DD_HANDLE* i2c_hdl, ql_i2c_mode_e Mode)
  • Parameter

i2c_hdl:

[Out] Obtained I2C handle.

Mode

[In] Work mode of I2C. See ql_i2c_mode_e for details.

  • Return Value

Result code. See ql_errcode_i2c_e for details.

ql_i2c_mode_e

The enumeration of I2C operation modes:

typedef enum
{
  STANDARD_MODE = 0,
  FAST_MODE = 1,
} ql_i2c_mode_e
  • Member
Member Description
STANDARD_MODE Standard mode
FAST_MODE Fast mode
ql_errcode_i2c_e

The enumeration of I2C result codes:

typedef enum
{
  QL_I2C_SUCCESS =0,
  QL_I2C_INIT_ERR ,
  QL_I2C_WRITE_ERR,
  QL_I2C_READ_ERR,
  QL_I2C_RELEASE_ERR,
} ql_errcode_i2c_e
  • Member
Member Description
QL_I2C_SUCCESS Successful execution
QL_I2C_INIT_ERR Failed I2C initialization
QL_I2C_WRITE_ERR Failed to write data to I2C
QL_I2C_READ_ERR Failed to read data from I2C
QL_I2C_RELEASE_ERR Failed to release I2C

ql_I2cWrite

This function writes data to the I2C bus.

  • Prototype
int ql_I2cWrite(DD_HANDLE i2c_hdl, UINT8 slave, UINT16 addr, char *data, UINT32 length, UINT8 addr_width)
  • Parameter

i2c_hdl:

[In] I2C handle.

slave:

[In] I2C slave device address.

addr:

[In] I2C slave register address.

data:

[In] Data to be written to the I2C bus.

length:

[In] Data length to be written to the I2C bus.

addr_width:

[In] Length of the slave register address.

  • Return Value

Result code. See ql_errcode_i2c_e for details.

ql_I2cRead

This function reads data from the I2C bus.

  • Prototype
int ql_I2cRead(DD_HANDLE i2c_hdl, UINT8 slave, UINT16 addr, char *buf, UINT32 length, UINT8 addr_width)
  • Parameter

i2c_hdl:

[In] I2C handle.

slave:

[In] I2C slave device address.

addr:

[In] I2C slave register address.

buf:

[Out] Data read from the I2C bus.

length:

[In] Data length read from the I2C bus.

addr_width:

[In] Length of the slave register address.

  • Return Value

Result code. See ql_errcode_i2c_e for details.

ql_I2cRelease

This function releases the I2C bus. To reinitialize the same I2C host, call this function to release the I2C bus, and then call ql_I2cInit() again to initialize the I2C bus.

  • Prototype
int ql_I2cRelease(DD_HANDLE i2c_hdl)
  • Parameter

i2c_hdl:

[In] I2C handle.

  • Return Value

Result code. See ql_errcode_i2c_e for details.

Example

The example of how to use the I2C is provided in the module SDK. The demo is in ql_i2c_eeprom_demo.c file in the ql_application/quectel_demo directory. I2C uses peripherals for communication. EEPROM chip (Model: FM24C128A) is applied in this example. Related functions are described below:

  • ql_i2c_demo_thread_creat(): This function creates an I2C tasks. You need to call this function to run the demo.

  • ql_i2c1_eeprom_demo_thread(): This function executes the task. It initializes I2C peripherals, writes data, reads data, and releases the I2C bus.

To run this demo, enable the CFG_ENABLE_QUECTEL_DEMO and CFG_ENABLE_QUECTEL_I2C1 macro definitions. This will automatically trigger the execution of ql_i2c_demo_thread_creat() and ql_i2c1_eeprom_demo_thread() to create a test task.

Creating an EEPROM Read and Write Task to Run I2C

Using I2C API

ADC API

Header File

ql_adc.h, the header file of ADC API, is in the
ql_components/qadpt/include/ directory. Unless otherwise specified, all header files mentioned in this document are in this directory.

API Description

ql_adc_thread_init

This function creates the ADC task.

  • Prototype
ql_adc_errcode_e ql_adc_thread_init(void)
  • Parameter

None

  • Return Value

Result code. See ql_adc_errcode_e for details.

ql_adc_errcode_e

The enumeration of ADC result codes:

typedef enum
{
  QL_ADC_SUCCESS = 0,
  QL_ADC_EXECUTE_ERR,
  QL_ADC_INVALID_PARAM_ERR,
} ql_adc_errcode_e
  • Parameter
Parameter Description
QL_ADC_SUCCESS Successful execution
QL_ADC_EXECUTE_ERR Failed execution
QL_ADC_INVALID_PARAM_ERR Invalid parameter

ql_adc_channel_init

This function configures ADC channel parameters.

  • Prototype
ql_adc_errcode_e ql_adc_channel_init(ql_adc_obj_s *handle, ql_adc_obj_callback cb, ql_adc_channel_e channel, void *user_data)
  • Parameter

handle:

[In] ADC channel. See ql_adc_obj_s for details.

cb:

[In] Callback function for channel detection. See ql_adc_obj_callback for details.

channel:

[In] ADC channel number. See ql_adc_channel_e for details.

user_data:

[In] User data.

  • Return Value

Result code. See ql_adc_errcode_e for details.

ql_adc_obj_s

The structure of ADC channel:

typedef struct adc_obj_ {
  void *user_data;
  ql_adc_channel_e channel;
  ql_adc_obj_callback cb;
  struct adc_obj_ *next;
} ql_adc_obj_s
  • Parameter
Type Parameter Description
void user_data User data
ql_adc_channel_e channel ADC channel number. See ql_adc_channel_e for details.
ql_adc_obj_callback cb Callback function for channel detection
struct adc_obj_ next Address of the next node of the Linked List
ql_adc_obj_callback

This function is the callback function for ADC channel detection.

  • Prototype
typedef void (*ql_adc_obj_callback)(int new_mv, void *user_data)
  • Parameter

new_mv:

[In] Detected voltage range (0--2400 mV).

user_data:

[In] User data.

  • Return Value

None

ql_adc_channel_e

The enumeration of ADC channel numbers.

typedef enum
{
  QL_ADC_CHANNEL_0 = 0,
  QL_ADC_CHANNEL_1,
  QL_ADC_CHANNEL_2,
  QL_ADC_CHANNEL_3,
  QL_ADC_CHANNEL_4,
  QL_ADC_CHANNEL_5,
  QL_ADC_CHANNEL_6,
} ql_adc_channel_e
  • Parameter
Parameter Description
QL_ADC_CHANNEL_0 Channel 0, detects voltage for VBAT pin, which is at half the VBAT voltage
QL_ADC_CHANNEL_1 Channel 1, detects voltage from GPIO26
QL_ADC_CHANNEL_2 Channel 2, detects voltage from GPIO24
QL_ADC_CHANNEL_3 Channel 3, detects voltage from GPIO23
QL_ADC_CHANNEL_4 Channel 4, detects voltage from GPIO28
QL_ADC_CHANNEL_5 Channel 5, detects voltage from GPIO22
QL_ADC_CHANNEL_6 Channel 6, detects voltage from GPIO21

ql_adc_channel_start

This function enables ADC detection.

  • Prototype
ql_adc_errcode_e ql_adc_channel_start(ql_adc_obj_s *handle)
  • Parameter

handle:

[In] ADC channel. See ql_adc_obj_s for details.

  • Return Value

Result code. See ql_adc_errcode_e for details.

ql_adc_channel_stop

This function stops ADC detection.

  • Prototype
ql_adc_errcode_e ql_adc_channel_stop(ql_adc_obj_s *handle)
  • Parameter

handle:

[In] ADC channel. See ql_adc_obj_s for details.

  • Return Value

Result code. See ql_adc_errcode_e for details.

ADC Development Process

This chapter explains how to use the above ADC API in applications, and perform basic debugging. The following subsections take channel 1 as an example.

ADC Operation

The example of how to operate the ADC is provided in the module SDK. The demo is in ql_adc_demo.c file in the ql_application/quectel_demo directory. The descriptions of related functions are as follows:

  • ql_adc_demo_thread_creat(): Creates an ADC task. This function needs to be called to run the ADC demo.

  • ql_adc_demo_thread(): This function executes the task. It initializes ADC and detects voltage.

To run this example, just enable the CFG_ENABLE_QUECTEL_DEMO and CFG_ENABLE_QUECTEL_ADC macro definitions. This will automatically trigger the execution of ql_adc_demo_thread_creat() and ql_adc_demo_thread()to create a test task.

Creating an ADC Task

Example: Using ADC API

Function Debugging

You need to use the development board (Take FC41D TE-B as an example) with the module to debug the ADC function. Follow these steps for debugging:

  1. Run the ADC demo as explained in ADC Operation.

  2. Recompile the firmware version and flash it to the module.

  3. Reboot the module.

  4. Open UART 2 to get the log information. The log information will be displayed as follows:

Getting Log via Serial Port Tool

Change the input voltage of the pin and the detection value will change accordingly.

PWM API

Header File

ql_pwm.h, the header file of PWM API, is in ql_components/qadpt/include/ directory. Unless otherwise specified, all header files mentioned in this document are in this directory.

API Description

ql_pwmInit

This function initializes PWM.

  • Prototype
ql_pwm_errcode_e ql_pwmInit(ql_pwm_channel_e pwm, UINT32 period, UINT32 duty_cycle)
  • Parameter

pwm:

[In] PWM channel. See ql_pwm_channel_e for details.

period:

[In] PWM period. Actual output frequency: F = 26 MHz / period.

duty_cycle:

[In] Duty cycle value of PWM. It is less than the period value.

  • Return Value

Result code. See ql_pwm_errcode_e for details.

ql_pwm_channel_e

The enumeration of PWM channels. There are 6 PWM channels in total.

typedef enum
{
  QL_PWM_0,
  QL_PWM_1,
  QL_PWM_2,
  QL_PWM_3,
  QL_PWM_4,
  QL_PWM_5,
} ql_pwm_channel_e
  • Member
Member Description
QL_PWM_0 PWM 0
QL_PWM_1 PWM 1
QL_PWM_2 PWM 2
QL_PWM_3 PWM 3
QL_PWM_4 PWM 4
QL_PWM_5 PWM 5
ql_pwm_errcode_e

The enumeration of PWM result codes:

typedef enum
{
  QL_PWM_SUCCESS = 0,
  QL_PWM_EXECUTE_ERR,
  QL_PWM_INVALID_PARAM_ERR,
} ql_pwm_errcode_e
  • Member
Member Description
QL_PWM_SUCCESS Successful execution
QL_PWM_EXECUTE_ERR Failed execution
QL_PWM_INVALID_PARAM_ERR Invalid parameter

ql_pwmInit_level

This function sets initial output level of PWM.

  • Prototype
ql_pwm_errcode_e ql_pwmInit_level(ql_pwm_channel_e pwm, ql_pwm_init_level_e level)
  • Parameter

pwm:

[In] PWM channel. See ql_pwm_channel_e for details.

level:

[In] Initial level of PWM. See ql_pwm_init_level_e for details.

  • Return Value

Result code. See ql_pwm_errcode_e for details.

ql_pwm_init_level_e

The enumeration of initial levels of PWM:

typedef enum
{
  QL_PWM_INIT_LEVEL_LOW =0,
  QL_PWM_INIT_LEVEL_HIGH,
} ql_pwm_init_level_e
  • Member
Member Description
QL_PWM_INIT_LEVEL_LOW Low level
QL_PWM_INIT_LEVEL_HIGH High level

ql_pwm_enable

This function enables PWM output.

  • Prototype
ql_pwm_errcode_e ql_pwm_enable(ql_pwm_channel_e pwm)
  • Parameter

pwm:

[In] PWM channel. See ql_pwm_channel_e for details.

  • Return Value

Result code. See ql_pwm_errcode_e for details.

ql_pwm_disable

This function disables PWM output.

  • Prototype
ql_pwm_errcode_e ql_pwm_disable(ql_pwm_channel_e pwm)
  • Parameter

pwm:

[In] PWM channel. See ql_pwm_channel_e for details.

  • Return Value

Result code. See ql_pwm_errcode_e for details.

ql_pwm_update_param

This function updates the parameters of PWM configuration. The parameter takes effect in next PWM period after updating.

  • Prototype
ql_pwm_errcode_e ql_pwm_update_param(ql_pwm_channel_e pwm, UINT32 period, UINT32 duty_cycle)
  • Parameter

pwm:

[In] PWM channel. See ql_pwm_channel_e for details.

period:

[In] PWM period value. Actual output frequency: F = 26 MHz / period.

duty_cycle:

[In] PWM duty cycle value. It is less than the period value.

  • Return Value

Result code. See ql_pwm_errcode_e for details.

PWM Development Process

This chapter explains how to use the above PWM API in applications and perform basic debugging. The following subsections take PWM 1 as an example.

PWM Operation

The example of how to operate the PWM is provided in the module SDK. The demo is in ql_pwm_demo.c file in the ql_application/quectel_demo directory. The descriptions of related functions are as follows:

  • ql_pwm_demo_thread_creat(): This function creates a PWM task. You need to call the function to run PWM demo.

  • ql_pwm_demo_thread(): This function executes a PWM task. It realizes the PWM output.

To run the example program, enable the CFG_ENABLE_QUECTEL_DEMO and CFG_ENABLE_QUECTEL_PWM macro definitions. This will automatically trigger the execution of ql_pwm_demo_thread_creat() and ql_pwm_demo_thread() to create a test task.

Creating a PWM Task

Using PWM API

Function Debugging

You need to use the development board (Take FC41D TE-B as an example) with the module to debug the PWM function. Follow these steps for debugging:

  1. Run the PWM demo as explained in PWM Operation. Enable the QL_PWM_1 macro definition to enable PWM 1.

  2. Recompile the firmware version and flash it to the module.

  3. Reboot the module.

  4. Get the pin waveforms of PWM 1 with logic analyzer.

  5. Open UART 2 to get the log information. The log information will be displayed as follows:

Getting Log via Serial Port Tool

Getting Waveforms of PWM with Logic Analyzer

The waveform of PWM is the same as the configuration in the figure above. Therefore, it can be said that the PWM function test has passed.

Appendix References

Document Name
Quectel_FC41D&FCMxx0D&FLMx40D_QuecOpen(SDK)_Quick_Start_Guide

Terms and Abbreviations

Abbreviation Description
ADC Analog-to-Digital Converter
API Application Programming Interface
CLK Clock
CPHA Clock Phase
CPOL Clock Polarity
CTS Clear To Send
DMA Direct Memory Access
EEPROM Electrically Erasable Programmable Read-Only Memory
FIFO First in First Out
GPIO General-Purpose Input/Output
I2C Inter-Integrated Circuit
IoT Internet of Things
LSB Least Significant Bit
MSB Most Significant Bit
PWM Pulse Width Modulation
RTOS Real-Time Operating System
RTS Request To Send
SCK Serial Clock
SDK Software Development Kit
SPI Universal Serial Bus
UART Universal Asynchronous Receiver/Transmitter
VBAT Voltage at Battery (Pin)