V2.4
This commit is contained in:
@@ -0,0 +1,247 @@
|
||||
/*********************************************************************
|
||||
* File Name : spi.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2023/8/15
|
||||
* Description : file for spi.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2023 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "spi.h"
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI1_Init
|
||||
*
|
||||
* @brief Initialize SPI1
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI1_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||||
SPI_InitTypeDef SPI_InitStructure = {0};
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
|
||||
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
|
||||
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
|
||||
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
|
||||
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
|
||||
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
|
||||
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
|
||||
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
|
||||
SPI_InitStructure.SPI_CRCPolynomial = 7;
|
||||
SPI_Init(SPI1, &SPI_InitStructure);
|
||||
|
||||
SPI_Cmd(SPI1, ENABLE);
|
||||
|
||||
SPI1->HSCR = 1;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI1_Read_DMA_Init
|
||||
*
|
||||
* @brief Initialize DMA for SPI1, In this condition every time send 0XFF to read data
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI1_Read_DMA_Init()
|
||||
{
|
||||
static uint32_t DummyByte = 0xff;
|
||||
DMA_InitTypeDef DMA_InitStructure = {0};
|
||||
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
|
||||
|
||||
// Tx
|
||||
DMA_DeInit(SPI1_DMA_TX_CH);
|
||||
|
||||
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DATAR;
|
||||
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&DummyByte;
|
||||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
|
||||
DMA_InitStructure.DMA_BufferSize = 0;
|
||||
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
|
||||
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
||||
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
|
||||
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
|
||||
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
||||
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
||||
DMA_Init(SPI1_DMA_TX_CH, &DMA_InitStructure);
|
||||
|
||||
// Rx
|
||||
DMA_DeInit(SPI1_DMA_RX_CH);
|
||||
|
||||
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DATAR;
|
||||
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)NULL;
|
||||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
|
||||
DMA_InitStructure.DMA_BufferSize = 0;
|
||||
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||||
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
||||
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
|
||||
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
|
||||
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
||||
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
||||
DMA_Init(SPI1_DMA_RX_CH, &DMA_InitStructure);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI1_Read_DMA
|
||||
*
|
||||
* @brief read data from SPI1 via DMA
|
||||
*
|
||||
* @param data - the data to recive
|
||||
* len - read length
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI1_Read_DMA(uint8_t* data, uint16_t len)
|
||||
{
|
||||
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET)
|
||||
;
|
||||
DMA_Cmd(SPI1_DMA_TX_CH, DISABLE);
|
||||
DMA_Cmd(SPI1_DMA_RX_CH, DISABLE);
|
||||
DMA_ClearFlag(DMA1_FLAG_TC3);
|
||||
DMA_ClearFlag(DMA1_FLAG_TC3);
|
||||
SPI1_DMA_TX_CH->CNTR = len;
|
||||
|
||||
SPI1_DMA_RX_CH->MADDR = (uint32_t)data;
|
||||
SPI1_DMA_RX_CH->CNTR = len;
|
||||
|
||||
DMA_Cmd(SPI1_DMA_TX_CH, ENABLE);
|
||||
DMA_Cmd(SPI1_DMA_RX_CH, ENABLE);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI2_Init
|
||||
*
|
||||
* @brief Initialize SPI2
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI2_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||||
SPI_InitTypeDef SPI_InitStructure = {0};
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
|
||||
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
|
||||
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
|
||||
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
|
||||
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
|
||||
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
|
||||
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
|
||||
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
|
||||
SPI_InitStructure.SPI_CRCPolynomial = 7;
|
||||
SPI_Init(SPI2, &SPI_InitStructure);
|
||||
|
||||
SPI_Cmd(SPI2, ENABLE);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI2_DMA_Init
|
||||
*
|
||||
* @brief Initialize DMA for SPI2
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI2_DMA_Init()
|
||||
{
|
||||
DMA_InitTypeDef DMA_InitStructure = {0};
|
||||
|
||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
|
||||
|
||||
DMA_DeInit(SPI2_DMA_TX_CH);
|
||||
|
||||
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI2->DATAR;
|
||||
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)NULL;
|
||||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
|
||||
DMA_InitStructure.DMA_BufferSize = 0;
|
||||
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||||
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
|
||||
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
|
||||
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
|
||||
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
||||
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
||||
DMA_Init(SPI2_DMA_TX_CH, &DMA_InitStructure);
|
||||
|
||||
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI2_Write
|
||||
*
|
||||
* @brief send one byte
|
||||
*
|
||||
* @param data - the data to send
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI2_Write(uint8_t data)
|
||||
{
|
||||
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET)
|
||||
;
|
||||
SPI_I2S_SendData(SPI2, data);
|
||||
|
||||
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET)
|
||||
;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI2_Write_DMA
|
||||
*
|
||||
* @brief send a lot of data
|
||||
*
|
||||
* @param data - the data to be send
|
||||
* len - the length of data
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI2_Write_DMA(uint8_t* data, uint16_t len)
|
||||
{
|
||||
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET)
|
||||
;
|
||||
|
||||
DMA_Cmd(SPI2_DMA_TX_CH, DISABLE);
|
||||
DMA_ClearFlag(SPI2_DMA_TC_FLAG);
|
||||
SPI2_DMA_TX_CH->MADDR = (uint32_t)data;
|
||||
SPI2_DMA_TX_CH->CNTR = len;
|
||||
SPI2_DMA_TX_CH->CFGR = 0x2090;
|
||||
|
||||
DMA_Cmd(SPI2_DMA_TX_CH, ENABLE);
|
||||
}
|
||||
Reference in New Issue
Block a user