Data Structure
Each HAL driver contains peripheral handle structure, initialization structure and configuration structure.
To simplify parameter setting in scenarios where only LL drivers are used, Goodix defines initialization structures in LL drivers.
Peripheral Handle Structure
The HAL drivers adopt a multi-instance architecture that allows working with several instances simultaneously on a peripheral. ppp_handle_t *handle is the main structure in the architecture. It defines the handle of each instance and stores the peripheral setting parameters, register structure pointers, and diverse run-time variables of each instance.
The peripheral handle is used for the purposes below:
- Multi-instance support: Each peripheral instance has its own handle, which results in independent peripheral setting parameters and run-time variables for each instance.
- Intra-API communications: The handle stores shared variables during peripheral operation, which enables data exchange between APIs.
- Storage: The handle stores and manages global variables of a specific peripheral driver.
An example of Serial Peripheral Interface (SPI) peripheral structure is shown below:
typedef struct
{
ssi_regs_t *p_instance; /**< SPI registers base address*/
spi_init_t init; /**< SPI communication parameters*/
uint8_t *p_tx_buffer; /**< Pointer to SPI Tx transfer Buffer */
__IO uint32_t tx_xfer_size; /**< SPI Tx Transfer size*/
__IO uint32_t tx_xfer_count; /**< SPI Tx Transfer Counter*/
uint8_t *p_rx_buffer; /**< Pointer to SPI Rx transfer Buffer */
__IO uint32_t rx_xfer_size; /**< SPI Rx Transfer size*/
__IO uint32_t rx_xfer_count ; /**< SPI Rx Transfer Counter*/
void (*write_fifo)(struct _spi_handle *p_spi); /**< Pointer to SPI Tx transfer
FIFO write function */
void (*read_fifo)(struct _spi_handle *p_spi); /**< Pointer to SPI Rx transfer
FIFO read function */
dma_handle_t *p_dmatx; /**< SPI Tx DMA Handle parameters*/
dma_handle_t *p_dmarx; /**< SPI Rx DMA Handle parameters*/
__IO hal_lock_t lock; /**< Locking object*/
__IO hal_spi_state_t state; /**< SPI communication state*/
__IO uint32_t error_code; /**< SPI Error code*/
uint32_t timeout; /**< timeout for the SPI memory access*/
} spi_handle_t;
No handle structure is used for system peripherals that are shared by multiple modules. Examples include GPIO, System Tick Timer (SysTick), NVIC, and PWR.
Initialization Structure
The initialization structure is used to store setting parameters in initializing peripherals.
An example of UART initialization structure is shown below. The structure can set baud rate, data bit, stop bit, hardware flow control mode, and access (RX) timeout.
typedef struct
{
uint32_t baud_rate;
uint32_t data_bits;
uint32_t stop_bits;
uint32_t parity;
uint32_t hw_flow_ctrl;
uint32_t rx_timeout_mode;
} uart_init_t;
Configuration Structure
The configuration structure is used to configure parameters of sub-modules and sub-instances.
An example of channel initialization structure for PWM is shown below:
typedef struct
{
uint8_t duty; /**< Specifies the duty in PWM output mode. This parameter must be a number between 0 ~ 100.*/
uint8_t drive_polarity; /**< Specifies the drive polarity in PWM output mode.This parameter can be a value of @ref PWM_DRIVEPOLARITY.*/
} pwm_channel_init_t;