FireBLE/Spi driver

来自Firefly wiki
跳转至: 导航搜索

Introduction

SPI is the abbreviation of Serial Peripheral Interface,is a kind of high speed,full duplex,synchronous communication bus,and on the pin of the chip takes only four lines.

  1. SDO – The Master device data output,input data from the Slave;
  2. SDI – The Master device data input,output data from the Slave;
  3. SCLK – Clock signal,produced by the Master device;
  4. CS – Make the signal from the device,controlled by the Master device;

The SDO/SDI/SCLK three lines to realize full-duplex communication,although simple and efficient,but because the device addressing only a CS choose foot to specify,when many connection SPI equipment,would be more troublesome.

SCLK provides clock pulse,SDI, SDO is based on the complete data transmission pulse.Data output by the SDO line,when data clock low-going edge/rising edge the change,in the next low-going edge/rising edge is read.Complete a data transfer,input and use the same principle.So,change in at least eight times the clock (low-going edge and rising edge for a time),can complete 8 bits of data transmission.

Initialization

Typically driven development process: system initialization-->GPIO configuration-->Each driver module initialization-->The main loop function.The first step in system initialization is necessary to each routine,initialization process is the same,so just call system initialization interface.

The following three parts are all we need to according to their own requirements to implementation,in the previous section we have configured the GPIO,this routine is only introduced SPI initialization.

Initialization function

Initialization function prototypes for SPI:

void spi_init(QN_SPI_TypeDef * SPI, uint32_t bitrate, enum SPI_BUFFER_WIDTH width, enum SPI_MODE mode)

Incoming parameters:

  1. SPI channel
  2. SPI baud rate
  3. SPI transfers data width
  4. SPI working mode

Initialize sample

spi_init(QN_SPI1, SPI_BITRATE(200000), SPI_8BIT, SPI_MASTER_MOD);

SPI channel

QN9021 only contains SPI1 channel,so the first argument must be a QN_SPI1.

SPI baud rate

SPI baud rate range between 62500 ~ 4000000.Can be seen in the macro definition method of baud rate setting.

/// SPI bit rate algorithm
#define SPI_BITRATE(x)                  ((__USART_CLK/(2*(x)) - 1) << SPI_POS_CLK_DIV_MASTER)

In the macro definition,the value of x is affected by a SPI_POS_CLK_DIV_MASTER,according to the name,this value should be a divider coefficient.

Track SPI_POS_CLK_DIV_MASTER ,find SPI_POS_CLK_DIV_MASTER macro definition for 16.

#define SPI_POS_CLK_DIV_MASTER                      16

Obviously (__USART_CLK/(2*(x)) - 1) this value should be written to a register,in addressing the relevant register mask found here.

/* SPI REGISTER MASK */
// CR0
#define SPI_MASK_BITRATE                    0x003F0000   /* 21 - 16 */

The original register of 16 to 21 deposit is frequency coefficient.Before back to the macro definition,assumption __USART_CLK/(2*(x)) - 1 = div ,that is really can be found for __USART_CLK 2 * (div + 1) times the frequency division. div value range of 0 ~ 63 ,find __USART_CLK is 8 MHZ frequency,so the baud rate value is 62.5 KHz ~ 4 MHZ , the basic unit of x is Hz.

#define CLK_8M                    (8000000UL)         /*!< Clock is 8MHz */
#define __USART_CLK                                     CLK_8M           /*!< UART and SPI clock frequency */

SPI Read-Write

The next program initialization rxbuffer,used as a data transceiver cache.

for (j = 0; j < 40; j++) {
    rxbuffer[j] = 0;
    buffer[j] = j;
}

Written to the flag bit,and then to write buffer on the SPI bus of the array before 4 bytes of data,after finish write clear flag bit .

//Write 4byte data
    tx_flag = 1;
//    spi_write(QN_SPI0, buffer, 4, led_blink_right);
    spi_write(QN_SPI1, buffer, 4, led_blink_right);
    while(tx_flag);

Read the flag bit,4 bytes read from the SPI bus then store to rxbuffer array,after the finish of the clear flag bit.

//Read 4byte data
    rx_flag = 1;
//    spi_read(QN_SPI0,  rxbuffer, 4, led_blink_left);
    spi_read(QN_SPI1,  rxbuffer, 4, led_blink_left);
    while(rx_flag);