Skip to content

CI230X Chip Driver


1. Overview of CI230X chip driver

CI230X chip driver includes voice part and WIFI part. For voice part driver, please refer to the chip driver part in CI130X chip SDK; The WIFI part and the voice part communicate through UART, and the communication rate can support 2Mbits/s at most. Next, the WIFI part driver will be described in detail.


2. Serial peripheral driver (SPI)

  • SPI initialization and enable API interface
void    hal_ spi_ init(uint32_t spi_x_base,spi_init_type_def* spi_init);
void    hal_ spi_ deinit(uint32_t spi_x_base);
void    hal_ spi_ en(uint32_t spi_x_base,hal_en_t en)
  • API interface for SPI receiving and transmitting data
void     hal_ spi_ send_ data(uint32_t spi_x_base,uint16_t data);
uint16_ t hal_ spi_ recv_ data(uint32_t spi_x_base);

3. Advanced timer (ADV_Timer)

The timer is a 16 bit automatic loading counter driven by a programmable prescaler.

Main features of advanced timer:

  • 16 bit up, down, up/down auto load counter
  • 6-bit programmable prescaler, the frequency division coefficient of the counter clock frequency is any value between 0 and 63, and 0 is no frequency division
  • Complementary output of 12 bit programmable dead time
  • Six independent channels
  • Support PWM output comparison, input capture and PWM trigger ADC sampling functions

Advanced timer initialization and configuration API interface

void    hal_ adv_ tim_ init(uint32_t adv_tim_x_base,adv_tim_init_t_def* adv_tim_init);
void    hal_ adv_ tim_ deinit(void);

Advanced timer data acquisition API interface

uint16_ t   hal_ adv_ tim_ get_ count(uint32_t adv_tim_x_base);

4. Basic Timer

The timer is composed of a 24 bit automatic loading counter driven by a programmable prescaler.

Main characteristics of timer:

  • 8-bit programmable (can be modified in real time) prescaler, the frequency division coefficient of the counter clock frequency is any value between 0 and 255, and 0 is no frequency division.
  • Four completely independent timers
  • PWM duty cycle can be modified in real time (but the latest LOAD value can be loaded only when the CNT value is 0)
  • 24 bit down counter

Timer initialization API interface

void        hal_ tim_ init(uint32_t tim_x_base,tim_init_t_def* tim_init);
void        hal_ tim_ deinit(void);
void        hal_ tim_ en(uint32_t tim_x_base,hal_en_t en);
void        hal_ tim_ set_ load_ value(uint32_t tim_x_base,uint32_t value);
uint32_ t    hal_ tim_ get_ current_ cnt_ value(uint32_t tim_x_base);

Timer interrupt initialization API interface

void    hal_ tim_ it_ cfg(uint32_t tim_x_base,tim_it_flag_t tim_it_flag,hal_en_t en);
uint8_ t hal_ tim_ get_ it_ flag(uint32_t tim_x_base,tim_it_flag_t tim_it_flag);
void    hal_ tim_ clr_ it_ flag(uint32_t tim_x_base,tim_it_flag_t tim_it_flag);

5. Watchdog (WDT)

WDT initialization and configuration API interface

void    hal_ wdt_ init(uint32_t wdt_base,wdt_init_t_def *wdt_init);
void    hal_ wdt_ deinit(void);
void    hal_ wdt_ en(uint32_t wdt_base,hal_en_t en);
void    hal_ wdt_ cnt_ restart(uint32_t wdt_base);

6. Clock control (CLOCK)

Clock controller initialization API interface

void    hal_ clock_ init(clock_init_t *clock_init);

7. Real time clock (RTC)

Real time clock initialization and configuration API interface

void      hal_ rtc_ init(uint32_t rtc_base,rtc_init_t_def* rtc_init);
void      hal_ rtc_ deinit(``void``);
void      hal_ rtc_ en(uint32_t rtc_base,hal_en_t en);
uint32_ t  hal_ rtc_ get_ cnt(uint32_t rtc_base);

Real time clock interrupt API interface

void     hal_ rtc_ it_ cfg(uint32_t rtc_base,rtc_it_flag_t rtc_it_flag,hal_en_t en);
uint8_ t  hal_ rtc_ get_ it_ flag(uint32_t rtc_base,rtc_it_flag_t rtc_it_flag);
void     hal_ rtc_ clr_ it_ flag(uint32_t rtc_base,rtc_it_flag_t rtc_it_flag);

8. Universal Asynchronous Transceiver (UART)

Universal asynchronous transceiver API interface

void       hal_ uart_ init(uint32_t uart_base, uart_init_t_def* uart_init);
void       hal_ uart_ deinit(uint32_t uart_base);
void       hal_ uart_ send_ data(uint32_t uart_base, uint16_t data);
uint16_ t   hal_ uart_ recv_ data(uint32_t uart_base);
void     hal_ uart_ en(uint32_t uart_base, hal_en_t en);
void     hal_ uart_ baudrate_ set(uint32_t uart_base, uint32_t baudrate);
void     hal_ uart_ it_ en(uint32_t uart_base, uart_it_en_enum it_en);
void     hal_ uart_ it_ disable(uint32_t uart_base, uart_it_en_enum it_en);

9. AES module

Advanced Encryption Standard (AES) in cryptography, also known as Rijndael encryption method, is the United States Association A block encryption standard adopted by the state government

Main features of AES:

  • Support ECB and CBC encryption
  • Support 128bit, 192bit and 256bit secret keys
  • Support encryption of 128bit plaintext at a time
  • Support encryption completion interrupt
  • Support busy flag

AES initialization and configuration API interface

void     hal_ uart_ init(uint32_t uart_base, uart_init_t_def* uart_init);
void     hal_ uart_ deinit(uint32_t uart_base);
void     hal_ uart_ send_ data(uint32_t uart_base, uint16_t data);
uint16_ t   hal_ uart_ recv_ data(uint32_t uart_base);
void       hal_ uart_ en(uint32_t uart_base, hal_en_t en);
void       hal_ uart_ baudrate_ set(uint32_t uart_base, uint32_t baudrate);
void       hal_ uart_ it_ en(uint32_t uart_base, uart_it_en_enum it_en);
void       hal_ uart_ it_ disable(uint32_t uart_base, uart_it_en_enum it_en);

10. Universal Asynchronous Transceiver (UART)

Initialization, configuration and API interface for sending and receiving data of universal asynchronous transceiver

void     hal_ uart_ init(uint32_t uart_base, uart_init_t_def* uart_init);
void     hal_ uart_ deinit(uint32_t uart_base);
void     hal_ uart_ send_ data(uint32_t uart_base, uint16_t data);
uint16_ t   hal_ uart_ recv_ data(uint32_t uart_base);
void     hal_ uart_ en(uint32_t uart_base, hal_en_t en);
void     hal_ uart_ baudrate_ set(uint32_t uart_base, uint32_t baudrate);
void     hal_ uart_ it_ en(uint32_t uart_base, uart_it_en_enum it_en);
void     hal_ uart_ it_ disable(uint32_t uart_base, uart_it_en_enum it_en);

11. DMA controller (DMA)

DMA controller initialization and configuration API interface

void    hal_ dma_ init(uint32_t dma_x_base,dma_init_t_def* dma_init);
void    hal_ dma_ deinit(``void``);
void    hal_ dma_ en(uint32_t dma_x_base,hal_en_t en);
void    hal_ dma_ set_ dir(uint32_t dma_x_base,dma_dir_t dma_dir);
void    hal_ dma_ set_ mem_ addr(uint32_t dma_x_base,uint32_t dma_mem_addr);
void    hal_ dma_ set_ p_ addr(uint32_t dma_x_base,uint32_t dma_p_addr);
void    hal_ dma_ set_ data_ num(uint32_t dma_x_base,uint16_t dma_data_num);
void    hal_ dma_ set_ mem_ size(uint32_t dma_x_base,dma_mem_size_t dma_mem_size);
void    hal_ dma_ set_ p_ size(uint32_t dma_x_base,dma_p_size_t dma_p_size);
void    hal_ dma_ set_ pri_ lev(uint32_t dma_x_base,dma_pri_lev_t dma_pri_lev);
void    hal_ dma_ set_ mem_ inc_ en(uint32_t dma_x_base,dma_mem_inc_en_t dma_mem_inc_en);
void    hal_ dma_ set_ p_ inc_ en(uint32_t dma_x_base,dma_p_inc_en_t dma_p_inc_en);
uint16_ t  hal_ dma_ get_ data_ num(uint32_t dma_x_base);

DMA interrupt API interface

void      hal_ dma_ it_ cfg(uint32_t dma_x_base,dma_it_flag_t dma_it_flag,hal_en_t en);
uint8_ t   hal_ dma_ get_ it_ flag(uint32_t dma_x_base,dma_it_flag_t dma_it_flag);
void      hal_ dma_ clr_ it_ flag(uint32_t dma_x_base,dma_it_flag_t dma_it_flag);
uint8_ t   hal_ dma_ get_ status_ flag(uint32_t dma_x_base,dma_status_flag_t dma_status_flag);
void      hal_ dma_ clr_ status_ flag(uint32_t dma_x_base,dma_status_flag_t dma_status_flag);

12. EXT interrupt

EX interrupt initialization API interface

void    hal_ ext_ init(ext_int_sense_t ext_int_sense,ext_trig_mode_t ext_trig_mode,hal_en_t en);
void    hal_ ext_ deinit(void);

13. FLASH control (4K alignment)

FLASH initialization, configuration, erasure, read-write API interfaces

void    hal_ flash_ init(void);
void    hal_ flash_ deinit(void);
uint8_ t hal_ flash_ read_ by_ cache(uint32_t offset, uint32_t length, uint8_t *buffer);
uint8_ t hal_ flash_ read(uint32_t offset, uint32_t length, uint8_t *buffer);
uint8_ t hal_ flash_ program(uint32_t offset, uint32_t length, uint8_t *buffer);
void    hal_ flash_ erase(uint32_t offset, uint32_t length);

14. GPIO and EXT interrupt (maximum flip rate 40M)

GPIO and interrupt configuration API interfaces

void      hal_ gpio_ init(uint32_t gpio_base, gpio_init_t_def *gpio_init);
uint16_ t  hal_ gpio_ port_ output_ read(uint32_t gpio_base);
void      hal_ gpio_ pin_ set(uint32_t gpio_base, gpio_pin_t pin);
void      hal_ gpio_ pin_ reset(uint32_t gpio_base, gpio_pin_t pin);

15. I2C interface

I2C interface configuration process

  1. First configure the IIC pin, and reuse the I2C SCL and I2C SDA through the pin function.
  2. Set IIC_ The freq in CR2 sets the peripheral clock. The range is 0 - 63. The unit is Mhz. The default value of 4 is recommended.
  3. Set IIC_ The pe in CR1 is set to zero, and the IIC bus is disabled first to set the IIC clock.
  4. Set IIC_ fs in CCR sets IIC to 1 and IIC to fast mode (0 is standard mode).
  5. Set IIC_ duty in CCR, this register determines T_ High and T_ The proportional relationship of low. 0: T_ low/T_ high = 2; 1: T_ low/T_ High=16/9 (see ccr description in IIC_CCR for instructions).
  6. Set IIC_ ccr in CCR, set the bus frequency. T = T_ high + T_ low.
  7. Set IIC_ trise in TRISE, this register determines the level rise time of SCL and SDA of IIC. Rise time=trise * Tpclk, 0xF is recommended.
  8. Set IIC_ The smbus register in CCR1 is 0 and set to IIC mode (1 is SMBus mode).
  9. Set IIC_ pe in CCR1 is 1, enabling IIC peripherals.
  10. Start configuring I2C_ swrst in CR1, reset IIC bus. First set it to 1, then set it to 0
In standard mode:
T_ high = CCR * Tpclk,
T_ low = 2 * CCR * Tpclk ,
T = CCR * Tpclk + 2 * CCR * Tpclk
In fast mode:
When duty=0:
T_ high = CCR * Tpclk
T_ low = 2  ×  CCR * Tpclk
When duty=1:
T_ high = 9 * CCR * Tpclk
T_ low = 16 * CCR * Tpclk
Example of clock configuration:
In fast mode: 400k SCL cycle is 2.5us, assuming the peripheral working clock is 40MHz, so Tpckl=1/40M=0.025us
If duty=0;
fs = 1;
Thigh = CCR  ×  TPCLK1
Tlow = 2  ×  CCR  ×  TPCLK1
Thigh + Tlow = 2.5us
So 3 * CCR ×  TPCLK1 = 2.5us CCR = 33
If duty=1;
fs = 1;
Thigh = 9 * CCR  ×  TPCLK1
Tlow = 16  ×  CCR  ×  TPCLK1
Thigh + Tlow = 2.5us
So 3 * CCR ×  TPCLK1 = 2.5us CCR = 4
duty -> I2C_ CCR->duty
fs -> I2C_ CCR->fs
Thigh -> I2C_ CLK high level time
Tlow -> I2C_ CLK low level time
TPCLK1 ->peripheral clock
CCR -> I2C_ CCR->ccr

I2C initialization, configuration, data receiving and transmitting API interface

void            hal_ i2c_ init(uint32_t i2c_x_base,i2c_init_t_def* i2c_init);
void            hal_ i2c_ deinit(void);
void            hal_ i2c_ set_ peripheral_ clock_ freq(uint32_t i2c_x_base, uint32_t peripheral_clock_freq);
void            hal_ i2c_ en(uint32_t i2c_x_base,hal_en_t en);
void            hal_ i2c_ master_ reset(uint32_t i2c_x_base);
uint8_ t         hal_ i2c_ master_ start(uint32_t i2c_x_base,uint32_t timeout);
void            hal_ i2c_ master_ stop(uint32_t i2c_x_base);
void            hal_ i2c_ master_ send_ data(uint32_t i2c_x_base,uint8_t data);
uint8_ t         hal_ i2c_ master_ recv_ data(uint32_t i2c_x_base);
uint8_ t         hal_ i2c_ master_ wait_ addr(uint32_t i2c_x_base,uint32_t timeout);

16. I2S interface

I2S interface characteristics:

  • Only slave mode is supported, and I2S clock is provided by the host
  • Full duplex mode dual channel stereo
  • Configurable data bit width, supporting 12, 16, 20, 24 and 32 bit data
  • Support Philips I2S standard
  • I2S does not support DMA and has only one channel
  • During I2S test, be sure to turn on the host first and then the slave, otherwise the host may receive data by mistake when initializing the slave
  • I2S may lose the header and footer data when it is received as a slave

I2S initialization and configuration API interface

void        hal_ i2s_ init(uint32_t i2s_base,i2s_init_t_def* i2s_init);
void        hal_ i2s_ deinit(void);
void        hal_ i2s_ rx_ en(uint32_t i2s_base,hal_en_t en);
void        hal_ i2s_ tx_ en(uint32_t i2s_base,hal_en_t en);
void        hal_ i2s_ en(uint32_t i2s_base,hal_en_t en);
void        hal_ i2s_ send_ data(uint32_t i2s_base,uint32_t left_data,uint32_t right_data);
void        hal_ i2s_ recv_ data(uint32_t i2s_base,uint32_t *left_data,uint32_t *right_data);

I2S interrupts API interface

void        hal_ i2s_ it_ cfg(uint32_t i2s_base,i2s_it_flag_t i2s_it_flag,hal_en_t en);
uint8_ t     hal_ i2s_ get_ it_ flag(uint32_t i2s_base,i2s_it_flag_t i2s_it_flag);
void        hal_ i2s_ clr_ it_ flag(uint32_t i2s_base,i2s_it_flag_t i2s_it_flag);

17. SDIO interface (SDIO)

SDIO interface characteristics:

  • SDIO is composed of a 24 bit automatic loading counter driven by a programmable prescaler. During SDIO debugging, CMD, D0, D1, D2, and D3 must be connected with pull-up resistors. For LN8XXX chip, we must select high-speed mode, otherwise there will be abnormal data.
  • The maximum speed is 40Mhz, and the recommended speed is 25Mhz (the measured maximum speed is 22Mhz, pay attention to wire connection)
  • It can only be used as a slave

SDIO initialization, configuration, data receiving and transmitting API interface

void      hal_ sdio_ device_ init(sdio_init_t *sdio_init);
void      hal_ sdio_ device_ deinit(void);
void      hal_ sdio_ device_ clear_ busy(void);
void      hal_ sdio_ device_ set_ busy(void);
uint32_ t* hal_ sdio_ device_ get_ recv_ buf_ addr(void);
void      hal_ sdio_ device_ set_ recv_ buf_ addr(uint8_t * addr);
uint16_ t  hal_ sdio_ device_ get_ recv_ buf_ size(void);
uint32_ t* hal_ sdio_ device_ get_ send_ buf_ addr(void);
void      hal_ sdio_ device_ set_ send_ buf_ addr(uint8_t *addr);
void      hal_ sdio_ device_ set_ send_ buf_ size(uint32_t size);
void      hal_ sdio_ device_ trig_ host_ data1_ int(void);
void      hal_ sdio_ device_ trig_ host_ s2m1_ int(void);
uint8_ t*  hal_ sdio_ device_ cis_ func_ get(sdio_dev_func_num_t fn);
uint8_ t   hal_ sdio_ device_ cis_ fn_ set(sdio_dev_func_num_t fn,uint32_t offset,uint8_t value);
void      hal_ sdio_ device_ cis_ init(void);
void      hal_ sdio_ device_ it_ cfg(uint32_t sdio_dev_int_flag,hal_en_t en);
uint8_ t   hal_ sdio_ device_ it_ get_ flag(sdio_dev_int_flag_t sdio_dev_int_flag);
void      hal_ sdio_ device_ it_ clr_ flag(sdio_dev_int_flag_t sdio_dev_int_flag);

18. WS2811 control interface

WS2811 interface characteristics:

  • WS2811 control interface is specially developed for controlling WS2811 series LED control chip (or other chips supporting WS2811 chip protocol)
  • Support DMA transmission
  • Support custom baud rate (7-bit width)
  • Supports all interrupts (triggered when DR is empty)
For WS2811, the most important thing is the time of T0L, T1L, T0H and T1H. The following is a brief description of how to set these values:
First of all, we need to know that we have artificially fixed the ratio of T0H to T0L as 1:4, and the ratio of T1H to T1L as 4:1 (according to the WS2811 manual, this ratio is valid)
The baud rate here is the time of a single 0 (T0) or a single 1 (T1), so T0=T0H+T0L, T1=T1H+T1L,
According to the WS2811 manual and the proportion between T0H, T0L, T1H and T1L, we generally think (the following data are measured values, which can be used directly):
T0=1125 ns, T0L=900ns, T0H=225ns, T1=1125 ns, T1L=225ns, T1H=900ns and T0=T1=(br+1) * 5 * (1/pclk)
Where br is the WS2811 BR register, pclk is the peripheral clock, and pclk=40M on the FPGA, so br=8;

WS2811 initialization and configuration API interface

void   hal_ ws2811_ init(uint32_t ws2811_base, ws2811_init_t_def *ws2811_init);
void   hal_ ws2811_ deinit(void);
void   hal_ ws2811_ en(uint32_t ws2811_base,hal_en_t en);
void   hal_ ws2811_ set_ data(uint32_t ws2811_base,uint8_t value);
void   hal_ ws2811_ dma_ en(uint32_t ws2811_base,hal_en_t en);
uint8_ thal_ ws2811_ get_ status_ flag(uint32_t ws2811_base,ws2811_status_flag_t ws2811_status_flag);

WS2811 interrupt API interface

void   hal_ ws2811_ it_ cfg(uint32_t ws2811_base,ws2811_it_flag_t ws2811_it_flag ,hal_en_t en);
uint8_ thal_ ws2811_ get_ it_ flag(uint32_t ws2811_base,ws2811_it_flag_t ws2811_it_flag);

19. Analog to Digital Converter (ADC)

ADC interface characteristics:

  • Support 6-channel polling sampling
  • Support single and continuous conversion mode
  • DMA support
  • Support conversion completion interrupt
  • 12bit resolution

Relation between rough measured voltage value and original ADC value:

0 32 0.4 480 1.1 1248 3.0 3360
0.01 32 0.51 608 1.5 1696 3.1 3488
0.11 160 0.8 928 2.0 2272 3.2 3616
0.33 416 1 1120 2.5 2848 3.3 3744

ADC initialization and configuration API interface

void        hal_ adc_ init(uint32_t adc_base,adc_init_t_def* adc_init);
void        hal_ adc_ deinit(void);
void        hal_ adc_ en(uint32_t adc_base,hal_en_t en);
void        hal_ adc_ start_ conv(uint32_t adc_base);
void        hal_ adc_ stop_ conv(uint32_t adc_base);
uint8_ t     hal_ adc_ get_ conv_ status(uint32_t adc_base, adc_ch_t ch);
void        hal_ adc_ clr_ conv_ status(uint32_t adc_base, adc_ch_t ch);
void        hal_ adc_ spe_ sw_ start(uint32_t adc_base);
uint16_ t    hal_ adc_ get_ data(uint32_t adc_base,adc_ch_t ch);