mbed移植日記:spi_api(基於STM32F107RC,適用於C)

spi是比較流行的一種串行外設,很多外設和集成IC都會使用到,如顯示,AD、DA、FALASH等等都會用到。雖然使用stm的cube庫也用着不錯,但每次使用時都得重新粘貼複製一遍很是麻煩,故纔會有此篇文章。模塊的設計格局與官方mbed有些地方是不一致的,讀的時候請注意一下。因爲是在項目過程中創建,模塊接口不夠全面,大家可以自行添加需要的API。

注意:中斷設計方法請參考

mbed serial_api模塊移植到stm32f107vc一文

一、關聯文件

1、pinmap.h

/**
  ******************************************************************************
  * File Name          : pinmap.h
  * Description        : 
  ******************************************************************************
  */

#ifndef _PIN_MAP_H
#define _PIN_MAP_H




/* 與mbed的pinmap結構有些不同 ,主意區別 */
typedef struct{
    uint32_t    pin;            /* 外設引腳,必須使用pinnames.h中定義的引腳名稱 */
    uint32_t    pin_port;       /* 引腳端口基地址,例如:GPIOB_BASE */       
    uint32_t    peripheral;     /* 外設基地址,例如:USART1_BASE */
    uint32_t    remap;          /* 引腳重映射 */
    uint32_t    mode;           /* 引腳輸入輸出模式 */
    uint32_t    pupd;           /* 上下拉電阻 */
}pinmap_t; 

/* 引腳配置函數 */
void     pinmap_pinout(uint32_t pin,const pinmap_t *map);

/* 引腳端口合併 */
uint32_t pinmap_merge(uint32_t a,uint32_t b);

/* 查找引腳對應的外設,返回外設基地址 */
uint32_t pinmap_find_peripheral(uint32_t pin,const pinmap_t *map);

/* 調用 pinmap_find_peripheral,返回外設地址 */
uint32_t pinmap_peripheral(uint32_t pin,const pinmap_t *map);


#endif

2、pinmap.c

/**
  ******************************************************************************
  * File Name          : pinmap.c
  * Description        : 
  ******************************************************************************
  */

#include "stm32f1xx.h"
#include "pinmap.h"
#include "pinnames.h"
#include "ierror.h"
#include "iassert.h"

/* private function *******************************************/
static void pin_function(const pinmap_t *map);
static void set_gpio_clock(const pinmap_t *map);


void pinmap_pinout(uint32_t pin, const pinmap_t *map) {
    if (pin == NC)
        return;

    while (map->pin != NC) {
        if (map->pin == pin) {
            pin_function(map);
            return;
        }
        map++;
    }
    error("could not pinout");
}

void pin_function(const pinmap_t *map)
{
    I_ASSERT(map->pin != NC);
    
    /* enable AFIO clock */
    set_gpio_clock(map);
    __HAL_RCC_AFIO_CLK_ENABLE();
    
    /* configure alternate function */
    if(map->remap>0){
        switch(map->remap){
        case AFIO_MAPR_SPI1_REMAP:
            __HAL_AFIO_REMAP_SPI1_ENABLE();
            break;
        case AFIO_MAPR_I2C1_REMAP:
            __HAL_AFIO_REMAP_I2C1_ENABLE();
            break;
        case AFIO_MAPR_USART1_REMAP:
            __HAL_AFIO_REMAP_USART1_ENABLE();
            break;
        case AFIO_MAPR_USART2_REMAP:
            __HAL_AFIO_REMAP_USART2_ENABLE();
            break;
        case AFIO_MAPR_USART3_REMAP_FULLREMAP:
            __HAL_AFIO_REMAP_USART3_ENABLE();
            break;
        case AFIO_MAPR_USART3_REMAP_PARTIALREMAP:
            __HAL_AFIO_REMAP_USART3_PARTIAL();
            break;
        case AFIO_MAPR_TIM1_REMAP_PARTIALREMAP:
            __HAL_AFIO_REMAP_TIM1_PARTIAL();
            break;
        case AFIO_MAPR_TIM1_REMAP_FULLREMAP:
            __HAL_AFIO_REMAP_TIM1_ENABLE();
            break;
        case AFIO_MAPR_TIM2_REMAP_PARTIALREMAP1:
            __HAL_AFIO_REMAP_TIM2_PARTIAL_1();
            break;
        case AFIO_MAPR_TIM2_REMAP_PARTIALREMAP2:
            __HAL_AFIO_REMAP_TIM2_PARTIAL_2();
            break;
        case AFIO_MAPR_TIM2_REMAP_FULLREMAP:
            __HAL_AFIO_REMAP_TIM2_ENABLE();
            break;
        case AFIO_MAPR_TIM3_REMAP_PARTIALREMAP:
            __HAL_AFIO_REMAP_TIM3_PARTIAL();
            break;
        case AFIO_MAPR_TIM3_REMAP_FULLREMAP:
            __HAL_AFIO_REMAP_TIM3_ENABLE();
            break;
        case AFIO_MAPR_TIM4_REMAP:
            __HAL_AFIO_REMAP_TIM4_ENABLE();
            break;
        default:
            break;
        }
    }
    
    GPIO_InitTypeDef        gpio_initstruct;
    gpio_initstruct.Pin     = (uint32_t)(1<<(map->pin & 0xF));
    gpio_initstruct.Mode    = map->mode;
    gpio_initstruct.Pull    = map->pupd;
    gpio_initstruct.Speed   = GPIO_SPEED_HIGH;
    HAL_GPIO_Init((GPIO_TypeDef *)map->pin_port,&gpio_initstruct);
    
    if((map->pin == PA_13) || (map->pin == PA_14))
       __HAL_AFIO_REMAP_SWJ_DISABLE();              /* JTAG-DP Disabled and SW-DP Disabled */
    
    if((map->pin == PA_15) || (map->pin == PB_3))
        __HAL_AFIO_REMAP_SWJ_NOJTAG();              /* JTAG-DP Disabled and SW-DP enabled */
    
    
}

void set_gpio_clock(const pinmap_t *map)
{
    if(map == NULL)
        return;
    
    switch(map->pin_port){
    case GPIOA_BASE:
        __GPIOA_CLK_ENABLE();
        break;
    case GPIOB_BASE:
        __GPIOB_CLK_ENABLE();
        break;
    case GPIOC_BASE:
        __GPIOC_CLK_ENABLE();
        break;
    case GPIOD_BASE:
        __GPIOD_CLK_ENABLE();
        break;
    case GPIOE_BASE:
        __GPIOE_CLK_ENABLE();
        break;
    default:
        error("Pinmap error: wrong port number.");
        break;
    }
}

uint32_t pinmap_merge(uint32_t a,uint32_t b)
{
    // both are the same (inc both NC)
    if (a == b)
        return a;

    // one (or both) is not connected
    if (a == (uint32_t)NC)
        return b;
    if (b == (uint32_t)NC)
        return a;

    // mis-match error case
    error("pinmap mis-match");
    return (uint32_t)NC;    
}


uint32_t pinmap_find_peripheral(uint32_t pin,const pinmap_t *map)
{
    while(map->pin != NC){
        if(map->pin == pin)
            return map->peripheral;
        
        map++;
    }
    return (uint32_t)NC;
}


uint32_t pinmap_peripheral(uint32_t pin,const pinmap_t *map)
{
    uint32_t  peripheral = (uint32_t)NC;
    
    if(pin == NC)
        return (uint32_t)NC;
    
    peripheral = pinmap_find_peripheral(pin,map);
    if((uint32_t)NC == peripheral)
        error("pinmap not found for peripheral");
    return peripheral;
}

3、pinnames.h

/**
  ******************************************************************************
  * File Name          : pinnames.h
  * Description        : 
  ******************************************************************************
  */
#ifndef PIN_NAMES_H
#define PIN_NAMES_H


#ifdef __cplusplus
extern "C" {
#endif

// See stm32f3xx_hal_gpio.h and stm32f3xx_hal_gpio_ex.h for values of MODE, PUPD and AFNUM
#define STM_PIN_DATA(MODE, PUPD, AFNUM)  ((int)(((AFNUM) << 7) | ((PUPD) << 4) | ((MODE) << 0)))
#define STM_PIN_MODE(X)   (((X) >> 0) & 0x0F)
#define STM_PIN_PUPD(X)   (((X) >> 4) & 0x07)
#define STM_PIN_AFNUM(X)  (((X) >> 7) & 0x0F)
#define STM_MODE_INPUT              (0)
#define STM_MODE_OUTPUT_PP          (1)
#define STM_MODE_OUTPUT_OD          (2)
#define STM_MODE_AF_PP              (3)
#define STM_MODE_AF_OD              (4)
#define STM_MODE_ANALOG             (5)
#define STM_MODE_IT_RISING          (6)
#define STM_MODE_IT_FALLING         (7)
#define STM_MODE_IT_RISING_FALLING  (8)
#define STM_MODE_EVT_RISING         (9)
#define STM_MODE_EVT_FALLING        (10)
#define STM_MODE_EVT_RISING_FALLING (11)
#define STM_MODE_IT_EVT_RESET       (12)

// High nibble = port number (0=A, 1=B, 2=C, 3=D, 4=E, 5=F, 6=G, 7=H)
// Low nibble  = pin number
#define STM_PORT(X) (((uint32_t)(X) >> 4) & 0xF)
#define STM_PIN(X)  ((uint32_t)(X) & 0xF)

typedef enum {
    PIN_INPUT,
    PIN_OUTPUT
} PinDirection;

typedef enum {
    PA_0  = 0x00,
    PA_1  = 0x01,
    PA_2  = 0x02,
    PA_3  = 0x03,
    PA_4  = 0x04,
    PA_5  = 0x05,
    PA_6  = 0x06,
    PA_7  = 0x07,
    PA_8  = 0x08,
    PA_9  = 0x09,
    PA_10 = 0x0A,
    PA_11 = 0x0B,
    PA_12 = 0x0C,
    PA_13 = 0x0D,
    PA_14 = 0x0E,
    PA_15 = 0x0F,

    PB_0  = 0x10,
    PB_1  = 0x11,
    PB_2  = 0x12,
    PB_3  = 0x13,
    PB_4  = 0x14,
    PB_5  = 0x15,
    PB_6  = 0x16,
    PB_7  = 0x17,
    PB_8  = 0x18,
    PB_9  = 0x19,
    PB_10 = 0x1A,
    PB_11 = 0x1B,
    PB_12 = 0x1C,
    PB_13 = 0x1D,
    PB_14 = 0x1E,
    PB_15 = 0x1F,

    PC_0  = 0x20,
    PC_1  = 0x21,
    PC_2  = 0x22,
    PC_3  = 0x23,
    PC_4  = 0x24,
    PC_5  = 0x25,
    PC_6  = 0x26,
    PC_7  = 0x27,
    PC_8  = 0x28,
    PC_9  = 0x29,
    PC_10 = 0x2A,
    PC_11 = 0x2B,
    PC_12 = 0x2C,
    PC_13 = 0x2D,
    PC_14 = 0x2E,
    PC_15 = 0x2F,

    PD_0  = 0x30,
    PD_1  = 0x31,
    PD_2  = 0x32,
    PD_3  = 0x33,
    PD_4  = 0x34,
    PD_5  = 0x35,
    PD_6  = 0x36,
    PD_7  = 0x37,
    PD_8  = 0x38,
    PD_9  = 0x39,
    PD_10 = 0x3A,
    PD_11 = 0x3B,
    PD_12 = 0x3C,
    PD_13 = 0x3D,
    PD_14 = 0x3E,
    PD_15 = 0x3F,
    
    PE_0  = 0x40,
    PE_1  = 0x41,
    PE_2  = 0x42,
    PE_3  = 0x43,
    PE_4  = 0x44,
    PE_5  = 0x45,
    PE_6  = 0x46,
    PE_7  = 0x47,
    PE_8  = 0x48,
    PE_9  = 0x49,
    PE_10 = 0x4A,
    PE_11 = 0x4B,
    PE_12 = 0x4C,
    PE_13 = 0x4D,
    PE_14 = 0x4E,
    PE_15 = 0x4F,
    
    PF_0  = 0x50,
    PF_1  = 0x51,
    PF_2  = 0x52,
    PF_3  = 0x53,
    PF_4  = 0x54,
    PF_5  = 0x55,
    PF_6  = 0x56,
    PF_7  = 0x57,
    PF_8  = 0x58,
    PF_9  = 0x59,
    PF_10 = 0x5A,
    PF_11 = 0x5B,
    PF_12 = 0x5C,
    PF_13 = 0x5D,
    PF_14 = 0x5E,
    PF_15 = 0x5F,
    
    PG_0  = 0x60,
    PG_1  = 0x61,
    PG_2  = 0x62,
    PG_3  = 0x63,
    PG_4  = 0x64,
    PG_5  = 0x65,
    PG_6  = 0x66,
    PG_7  = 0x67,
    PG_8  = 0x68,
    PG_9  = 0x69,
    PG_10 = 0x6A,
    PG_11 = 0x6B,
    PG_12 = 0x6C,
    PG_13 = 0x6D,
    PG_14 = 0x6E,
    PG_15 = 0x6F,
    
    PH_0  = 0x70,
    PH_1  = 0x71,
    PH_2  = 0x72,
    PH_3  = 0x73,
    PH_4  = 0x74,
    PH_5  = 0x75,
    PH_6  = 0x76,
    PH_7  = 0x77,
    PH_8  = 0x78,
    PH_9  = 0x79,
    PH_10 = 0x7A,
    PH_11 = 0x7B,
    PH_12 = 0x7C,
    PH_13 = 0x7D,
    PH_14 = 0x7E,
    PH_15 = 0x7F,

    // Arduino connector namings
    A0          = PA_0,
    A1          = PA_1,
    A2          = PA_4,
    A3          = PB_0,
    A4          = PC_1,
    A5          = PC_0,
    D0          = PA_3,
    D1          = PA_2,
    D2          = PA_10,
    D3          = PB_3,
    D4          = PB_5,
    D5          = PB_4,
    D6          = PB_10,
    D7          = PA_8,
    D8          = PA_9,
    D9          = PC_7,
    D10         = PB_6,
    D11         = PA_7,
    D12         = PA_6,
    D13         = PA_5,
    D14         = PB_9,
    D15         = PB_8,


    // Not connected
    NC = (uint32_t)0xFFFFFFFF
} PinName;



#ifdef __cplusplus
}
#endif

#endif

二、spi_api.h

/**
  ******************************************************************************
  * File Name          : spi_api.h
  * Description        : 
  ******************************************************************************
  */


#ifndef SPI_API_H
#define SPI_API_H


/*  include  ******************************/
#include "stm32f1xx.h"



void spi_init(SPI_HandleTypeDef *hspi,
              uint32_t mosi,
              uint32_t miso,
              uint32_t sck,
              uint32_t ssel,
              uint32_t nss);

void spi_free(SPI_HandleTypeDef *hspi);

void spi_format(SPI_HandleTypeDef *hspi,
                uint32_t databits,
                uint8_t  clk_mode,
                uint32_t slave);

void spi_baud(SPI_HandleTypeDef *hspi,uint32_t baud);

void spi_begin(SPI_HandleTypeDef *hspi);

void spi_end(SPI_HandleTypeDef *hspi);

void spi_transmit(SPI_HandleTypeDef *hspi,uint8_t *pdata,uint16_t size,uint32_t timeout);

void spi_receive(SPI_HandleTypeDef *hspi,uint8_t *pdata,uint16_t size,uint32_t timeout);

void spi_receive_it(SPI_HandleTypeDef *hspi,uint8_t *pdata,uint16_t size);

void spi_irq_set(SPI_HandleTypeDef *hspi,uint32_t preempt_prio,uint32_t sub_prio);

void spi_irq_enable(SPI_HandleTypeDef *hspi);

void spi_irq_disable(SPI_HandleTypeDef *hspi);


#endif

三、spi_api.c

/**
  ******************************************************************************
  * File Name          : spi_api.c
  * Description        : 
  ******************************************************************************
  */

#include "stm32f1xx.h"
#include "spi_api.h"
#include "pinnames.h"
#include "pinmap.h"
#include "iassert.h"
#include "ierror.h"


const static pinmap_t   SPI_MOSI_TAB[] = {
    {PA_7, GPIOA_BASE,SPI1_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
    {PB_15,GPIOB_BASE,SPI2_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
    {PB_5, GPIOB_BASE,SPI3_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
    {PC_12,GPIOC_BASE,SPI3_BASE,AFIO_MAPR_SPI3_REMAP,GPIO_MODE_AF_PP,GPIO_NOPULL},
    {NC,   NC,        NC,       0,                   NC,             NC}
};


const static pinmap_t   SPI_MISO_TAB[] = {
    {PA_6, GPIOA_BASE,SPI1_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
    {PB_14,GPIOB_BASE,SPI2_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
    {PB_4, GPIOB_BASE,SPI3_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
    {PC_11,GPIOC_BASE,SPI3_BASE,AFIO_MAPR_SPI3_REMAP,GPIO_MODE_AF_PP,GPIO_NOPULL},
    {NC,   NC,        NC,       0,                   NC,             NC}
};

const static pinmap_t   SPI_SCK_TAB[] = {
    {PA_5, GPIOA_BASE,SPI1_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
    {PB_13,GPIOB_BASE,SPI2_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
    {PB_3, GPIOB_BASE,SPI3_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
    {PC_10,GPIOC_BASE,SPI3_BASE,AFIO_MAPR_SPI3_REMAP,GPIO_MODE_AF_PP,GPIO_NOPULL},
    {NC,   NC,        NC,       0,                   NC,             NC}
};

const static pinmap_t   SPI_SSEL_TAB[] ={
    {PA_4, GPIOA_BASE,SPI1_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
    {PB_12,GPIOB_BASE,SPI2_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
    {PA_15,GPIOA_BASE,SPI3_BASE,0,GPIO_MODE_AF_PP,GPIO_NOPULL},
    {NC,   NC,        NC,       0,NC,             NC}
};

/* soft nss,根據實際使用情況修改 */
const static pinmap_t   SPI_CS_TAB[] = {
    {PA_8,GPIOA_BASE,SPI1_BASE,0,GPIO_MODE_OUTPUT_PP,GPIO_NOPULL},
    {PA_4,GPIOA_BASE,SPI3_BASE,0,GPIO_MODE_OUTPUT_PP,GPIO_NOPULL},
    {NC,  NC,        NC,       0,NC,                 NC         }
};



/* public variable ***************************************/
SPI_HandleTypeDef *hspi_instance[3] = {NULL,NULL,NULL};


/*  private **********************************************/






/**
  * biref    initialize spi peripher 
  * retval   none
  * hspi     - pointer to SPI_HandleTypeDef
  * mosi     - master out and slave input pin
  * miso     - msater in and slave out pin
  * sck      - spi sclk pin
  * ssel     - cs pin
  * nss      nss style
  *          -SPI_NSS_SOFT
  *          -SPI_NSS_HARD_INPUT,slave
  *          -SPI_NSS_HARD_OUTPUT,master
  */
void spi_init(SPI_HandleTypeDef *hspi,
              uint32_t mosi,
              uint32_t miso,
              uint32_t sck,
              uint32_t ssel,
              uint32_t nss)
{
    uint32_t spi_ssel;
    
    uint32_t spi_mosi = (uint32_t)pinmap_peripheral(mosi,SPI_MOSI_TAB);
    uint32_t spi_miso = (uint32_t)pinmap_peripheral(miso,SPI_MISO_TAB);
    uint32_t spi_sck  = (uint32_t)pinmap_peripheral(sck,SPI_SCK_TAB);
    if(nss == SPI_NSS_SOFT){
         spi_ssel = (uint32_t)pinmap_peripheral(ssel,SPI_CS_TAB);
    }else{
         spi_ssel = (uint32_t)pinmap_peripheral(ssel,SPI_SSEL_TAB);
    }
    
    uint32_t spi_data = (uint32_t)pinmap_merge(spi_mosi,spi_miso);
    uint32_t spi_cntl = (uint32_t)pinmap_merge(spi_sck,spi_ssel);
    
    uint32_t spi = (uint32_t)pinmap_merge(spi_data,spi_cntl);
    I_ASSERT(spi != (uint32_t)NC);
    
    hspi->Instance  = (SPI_TypeDef *)spi;
    
    if(spi == SPI1_BASE){
        __SPI1_CLK_ENABLE();
        hspi_instance[0] = hspi;
    }
    
    if(spi == SPI2_BASE){
        __SPI2_CLK_ENABLE();
        hspi_instance[1] = hspi;
    }
    
    if(spi == SPI3_BASE){
        __SPI3_CLK_ENABLE();
        hspi_instance[2] = hspi;
    }
    
    /* configurate spi pins */
    pinmap_pinout(mosi,SPI_MOSI_TAB);
    pinmap_pinout(miso,SPI_MISO_TAB);
    pinmap_pinout(sck,SPI_SCK_TAB);
    if(nss == SPI_NSS_SOFT){
        pinmap_pinout(ssel,SPI_CS_TAB);
        spi_end(hspi);
    }else{
        pinmap_pinout(ssel,SPI_SSEL_TAB);
    }
    
    hspi->Init.NSS  = nss;
    hspi->Init.Mode = SPI_MODE_MASTER;
    hspi->Init.Direction = SPI_DIRECTION_2LINES;
    hspi->Init.DataSize = SPI_DATASIZE_8BIT;
    hspi->Init.CLKPolarity = SPI_POLARITY_LOW;
    hspi->Init.CLKPhase = SPI_PHASE_1EDGE;
    hspi->Init.FirstBit = SPI_FIRSTBIT_MSB;
    hspi->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
    hspi->Init.TIMode = SPI_TIMODE_DISABLE;
    hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
    hspi->Init.CRCPolynomial = 10;
    
    HAL_SPI_Init(hspi);
    
    //__HAL_SPI_ENABLE(hspi);
}

void spi_free(SPI_HandleTypeDef *hspi)
{
    if(hspi == NULL)
        return;
    
    if(hspi->Instance == SPI1){
        __SPI1_FORCE_RESET();
        __SPI1_RELEASE_RESET();
        __SPI1_CLK_DISABLE();
    }
    
    if(hspi->Instance == SPI2){
        __SPI2_FORCE_RESET();
        __SPI2_RELEASE_RESET();
        __SPI2_CLK_DISABLE();
    }
    
    if(hspi->Instance == SPI3){
        __SPI3_FORCE_RESET();
        __SPI3_RELEASE_RESET();
        __SPI3_CLK_DISABLE();
    }
}

/**
  * hspi        --poiter to instance
  * databits    --data bit,SPI_DATASIZE_8BIT OR SPI_DATASIZE_16BIT
  * clk_mode    --clk mode, = 0,1,2,3
  * slave       --spi mode, 0=MASTER,1=SLAVE
  */
void spi_format(SPI_HandleTypeDef *hspi,
                uint32_t databits,
                uint8_t  clk_mode,
                uint32_t slave)
{
    hspi->Init.DataSize = databits;
    
    switch(clk_mode)
    {
    case 0:
        hspi->Init.CLKPolarity  = SPI_POLARITY_LOW;
        hspi->Init.CLKPhase     = SPI_PHASE_1EDGE;
        break;
    case 1:
        hspi->Init.CLKPolarity  = SPI_POLARITY_LOW;
        hspi->Init.CLKPhase     = SPI_PHASE_2EDGE;
        break;
    case 2:
        hspi->Init.CLKPolarity  = SPI_POLARITY_HIGH;
        hspi->Init.CLKPhase     = SPI_PHASE_1EDGE;
        break;
    case 3:
        hspi->Init.CLKPolarity  = SPI_POLARITY_HIGH;
        hspi->Init.CLKPhase     = SPI_PHASE_2EDGE;
        break;
    default:
        hspi->Init.CLKPolarity  = SPI_POLARITY_LOW;
        hspi->Init.CLKPhase     = SPI_PHASE_1EDGE;
        break;
    }
    
    if(hspi->Init.NSS != SPI_NSS_SOFT){
        hspi->Init.NSS = (slave) ? SPI_NSS_HARD_INPUT : SPI_NSS_HARD_OUTPUT;
    }
    
    hspi->Init.Mode = (slave) ? SPI_MODE_SLAVE : SPI_MODE_MASTER;
    
    HAL_SPI_Init(hspi);
}

/**
  * hspi    --point to  instance of spi
  * baud    -- baud rate prescaler,
            SPI_BAUDRATEPRESCALER_2,
            SPI_BAUDRATEPRESCALER_4,
            SPI_BAUDRATEPRESCALER_8,
            SPI_BAUDRATEPRESCALER_16,
            SPI_BAUDRATEPRESCALER_32,
            SPI_BAUDRATEPRESCALER_64,
            SPI_BAUDRATEPRESCALER_128,
            SPI_BAUDRATEPRESCALER_256
  */
void spi_baud(SPI_HandleTypeDef *hspi,uint32_t baud)
{
    hspi->Init.BaudRatePrescaler = baud;
    HAL_SPI_Init(hspi);
}

void spi_begin(SPI_HandleTypeDef *hspi)
{
    GPIO_TypeDef *port = NULL;
    uint32_t     gpio_pin;
    if(hspi == NULL)
        return;
    
    for(uint8_t i=0;SPI_CS_TAB[i].peripheral != NC;i++){
        if(hspi->Instance == (SPI_TypeDef *)SPI_CS_TAB[i].peripheral){
            port     = (GPIO_TypeDef *)SPI_CS_TAB[i].pin_port;
            gpio_pin = 1<BSRR = (uint32_t)gpio_pin<<16;
            return;
        }  
    }
    
    error("spi cs begin error\r\n");
}

void spi_end(SPI_HandleTypeDef *hspi)
{
    GPIO_TypeDef *port = NULL;
    uint32_t     gpio_pin;
    
    if(hspi == NULL)
        return;
    
    for(uint8_t i=0;SPI_CS_TAB[i].peripheral != NC;i++){
        if(hspi->Instance == (SPI_TypeDef *)SPI_CS_TAB[i].peripheral){
            port     = (GPIO_TypeDef *)SPI_CS_TAB[i].pin_port;
            gpio_pin = 1<BSRR = (uint32_t)gpio_pin;
            return;
        }  
    }
    
    error("spi cs end error\r\n");
}

void spi_transmit(SPI_HandleTypeDef *hspi,uint8_t *pdata,uint16_t size,uint32_t timeout)
{
    HAL_SPI_Transmit(hspi,pdata,size,timeout);
}

void spi_receive(SPI_HandleTypeDef *hspi,uint8_t *pdata,uint16_t size,uint32_t timeout)
{
    HAL_SPI_Receive(hspi,pdata,size,timeout);
}

void spi_receive_it(SPI_HandleTypeDef *hspi,uint8_t *pdata,uint16_t size)
{
    HAL_SPI_Receive_IT(hspi,pdata,size);
}

void spi_irq_set(SPI_HandleTypeDef *hspi,uint32_t preempt_prio,uint32_t sub_prio)
{
    IRQn_Type irq;
    
    if(hspi->Instance == SPI1)
        irq = SPI1_IRQn;
    
    if(hspi->Instance == SPI2)
        irq = SPI2_IRQn;
    
    if(hspi->Instance == SPI3)
        irq = SPI3_IRQn;
    
    HAL_NVIC_SetPriority(irq,preempt_prio,sub_prio);
    HAL_NVIC_EnableIRQ(irq);
}

void spi_irq_enable(SPI_HandleTypeDef *hspi)
{
    IRQn_Type irq;
    
    if(hspi->Instance == SPI1)
        irq = SPI1_IRQn;
    
    if(hspi->Instance == SPI2)
        irq = SPI2_IRQn;
    
    if(hspi->Instance == SPI3)
        irq = SPI3_IRQn;
    
    HAL_NVIC_EnableIRQ(irq);
}

void spi_irq_disable(SPI_HandleTypeDef *hspi)
{
    IRQn_Type irq;
    
    if(hspi->Instance == SPI1)
        irq = SPI1_IRQn;
    
    if(hspi->Instance == SPI2)
        irq = SPI2_IRQn;
    
    if(hspi->Instance == SPI3)
        irq = SPI3_IRQn;
    
    HAL_NVIC_DisableIRQ(irq);
}

四、舉例

數碼管顯示配置實例


#include “spi_api.h”


SPI_HandleTypeDef    led_spi;

void  main(void)

{

    spi_init(&led_spi,LED_SDI,LED_SDO,LED_SCK,LED_CS,SPI_NSS_SOFT);
    spi_format(&led_spi,SPI_DATASIZE_8BIT,0,0);
    spi_end(&led_spi);


發送代碼

    spi_begin(&led_spi);
    spi_transmit(&led_spi,(uint8_t*)ss_buf,SS_BUF_MAX,1000);
    spi_end(&led_spi);


while(1);

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章