/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_exti.h"
#include "stm32f10x_spi.h"
#include "delay.h"
/* Private constants -----------------------------------------------------------*/
#define WIFI_SPI_MASTER // or #define WIFI_SPI_SLAVE
#define WIFI_SPI SPI2
#define TIP_WIFI_SPI_GRP GPIOB
#define TIP_WIFI_NSS_PIN GPIO_Pin_10
#define TIP_WIFI_SCK_PIN GPIO_Pin_13
#define TIP_WIFI_MISO_PIN GPIO_Pin_14
#define TIP_WIFI_MOSI_PIN GPIO_Pin_15
#define TIP_WIFI_IRQ_PORT_SRC GPIO_PortSourceGPIOB
#define TIP_WIFI_IRQ_PIN_SRC GPIO_PinSource10
#define TIP_WIFI_IRQ_EXTI_LINE EXTI_Line10
#define TIP_WIFI_IRQ_EXTI_CHN EXTI15_10_IRQn
#define BufferSize 128
#define SPI_DMA DMA1
#define SPI_DMA_CLK RCC_AHBPeriph_DMA1
#define SPI_Rx_DMA_Channel DMA1_Channel4
#define SPI_Rx_DMA_FLAG DMA1_FLAG_TC4
#define SPI_Tx_DMA_Channel DMA1_Channel5
#define SPI_Tx_DMA_FLAG DMA1_FLAG_TC5
/* Private typedef -------------------------------------------------------------*/
/* Private macro --------------------------------------------------------------*/
#ifdef WIFI_SPI_SLAVE
#define SLV2MST_CS GPIO_SetBits(TIP_WIFI_SPI_GRP,TIP_WIFI_NSS_PIN)
#define SLV2MST_NCS GPIO_ResetBits(TIP_WIFI_SPI_GRP,TIP_WIFI_NSS_PIN)
#endif /* WIFI_SPI_SLAVE */
/* Private variable -------------------------------------------------------------*/
uint8_t usb_rx_count = 0;
uint8_t usb_rx_buf[BufferSize] = {0};
uint8_t usb_flag = 0;
uint8_t spi_rx_flag = 0;
uint8_t spi_rx_count = 0;
uint8_t spi_rx_buf[BufferSize] = {0};
uint8_t spi_tx_flag = 0;
uint8_t dma_tx_available = 1;
DMA_InitTypeDef DMA_InitStructure_Tx;
/* Private functions prototype ----------------------------------------------------*/
/* Private functions ------------------------------------------------------------*/
void RccInit(void)
{
ErrorStatus HSEStartUpStatus;
/* RCC system reset(for debug purpose) */
RCC_DeInit();
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
{
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
/* Enable PLL */
RCC_PLLCmd(ENABLE);
/* Wait till PLL is ready */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
}
void GpioInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIOA, GPIOB, GPIOC and AFIO clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC , ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE);
/* SPI2 : SCK, MISO and MOSI */
#ifdef WIFI_SPI_MASTER
GPIO_InitStructure.GPIO_Pin = TIP_WIFI_SCK_PIN | TIP_WIFI_MOSI_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(TIP_WIFI_SPI_GRP, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = TIP_WIFI_MISO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(TIP_WIFI_SPI_GRP, &GPIO_InitStructure);
//NSS SPI_NSS_Soft
GPIO_InitStructure.GPIO_Pin = TIP_WIFI_NSS_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(TIP_WIFI_SPI_GRP, &GPIO_InitStructure);
#else
GPIO_InitStructure.GPIO_Pin = TIP_WIFI_SCK_PIN | TIP_WIFI_MOSI_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(TIP_WIFI_SPI_GRP, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = TIP_WIFI_MISO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(TIP_WIFI_SPI_GRP, &GPIO_InitStructure);
//NSS SPI_NSS_Soft
GPIO_InitStructure.GPIO_Pin = TIP_WIFI_NSS_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(TIP_WIFI_SPI_GRP, &GPIO_InitStructure);
GPIO_ResetBits(TIP_WIFI_SPI_GRP,TIP_WIFI_NSS_PIN);
#endif
}
void DmaInit(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* SPI_MASTER_Rx_DMA_Channel configuration ---------------------------------*/
DMA_DeInit(SPI_Rx_DMA_Channel);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&WIFI_SPI->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)spi_rx_buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = BufferSize;
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_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(SPI_Rx_DMA_Channel, &DMA_InitStructure);
/* SPI_MASTER_Tx_DMA_Channel configuration ---------------------------------*/
DMA_DeInit(SPI_Tx_DMA_Channel);
DMA_InitStructure_Tx.DMA_PeripheralBaseAddr = (uint32_t)(&WIFI_SPI->DR);
DMA_InitStructure_Tx.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure_Tx.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure_Tx.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure_Tx.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure_Tx.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure_Tx.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure_Tx.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure_Tx.DMA_M2M = DMA_M2M_Disable;
}
void NvicInit(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
#ifdef WIFI_SPI_MASTER
EXTI_InitTypeDef EXTI_InitStructure;
#endif /* WIFI_SPI_MASTER */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
#ifdef WIFI_SPI_MASTER
/* EXTI NVIC configuration*/
NVIC_InitStructure.NVIC_IRQChannel = TIP_WIFI_IRQ_EXTI_CHN;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
GPIO_EXTILineConfig(TIP_WIFI_IRQ_PORT_SRC, TIP_WIFI_IRQ_PIN_SRC);
EXTI_InitStructure.EXTI_Line = TIP_WIFI_IRQ_EXTI_LINE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //EXTI
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //failling edge triger
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //enable exti
EXTI_Init(&EXTI_InitStructure);
#endif /* WIFI_SPI_MASTER */
/*SPI NVIC configuration*/
NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* DMA NVIC configuration*/
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void TIPSpiDmaInit(void)
{
SPI_InitTypeDef SPI_InitStructure;
RccInit();
GpioInit();
DmaInit();
NvicInit();
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); //APB1
SPI_Cmd(WIFI_SPI, DISABLE);
/* SPI configuration */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //Full-duplex
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //master mode
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8bit
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //SCK idle low
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //SCK sampling begin at first clock edge
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // software generate NSS
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; //baudrate control SYSCLK/4
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB; //first bit is most segnificant bit
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC calculation value 7
SPI_Init(WIFI_SPI, &SPI_InitStructure);
#ifdef WIFI_SPI_SLAVE
SPI_I2S_ITConfig(WIFI_SPI, SPI_I2S_IT_RXNE, ENABLE);
#endif
SPI_Cmd(WIFI_SPI, ENABLE);
}
bool TIPSpiDmaSend(uint8_t* buf, uint8_t len)
{
/* DMA1 Channel (triggered by USART_Tx event) Config */
DMA_Cmd(SPI_Tx_DMA_Channel, DISABLE);
SPI_I2S_DMACmd(WIFI_SPI, SPI_I2S_DMAReq_Tx, DISABLE);
SPI_Cmd(WIFI_SPI, DISABLE);
DMA_DeInit(SPI_Tx_DMA_Channel); /*needs deInit before Init*/
DMA_InitStructure_Tx.DMA_MemoryBaseAddr = (uint32_t)buf;
DMA_InitStructure_Tx.DMA_BufferSize = len;
DMA_Init(SPI_Tx_DMA_Channel, &DMA_InitStructure_Tx);
#ifdef WIFI_SPI_SLAVE
SLV2MST_CS;
#endif /* WIFI_SPI_SLAVE */
/* Enable DMA1 Channel_Tx */
DMA_Cmd(SPI_Tx_DMA_Channel, ENABLE);
SPI_I2S_DMACmd(WIFI_SPI, SPI_I2S_DMAReq_Tx, ENABLE);
DMA_ITConfig(SPI_Tx_DMA_Channel, DMA_IT_TC, ENABLE);
/* Enable the WIFI_SPI */
SPI_Cmd(WIFI_SPI, ENABLE);
dma_tx_available = 0;
return TRUE;
}
int main(void)
{
uint8_t count = 0;
TIPUSBInit();
TIPSpiDmaInit();
for(;;)
{
if(usb_flag)
{
usb_flag = 0;
TIPSpiDmaSend(usb_rx_buf,usb_rx_count);
}
if(spi_rx_flag)
{
delay_ms(100);
USBSend(spi_rx_buf,BufferSize-DMA_GetCurrDataCounter(SPI_Rx_DMA_Channel));
spi_rx_flag = 0;
}
}
}
/*******************************************************************************
* Function Name : SPI2_IRQHandler
* Description : This function handles SPI2 global interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SPI2_IRQHandler(void)
{
if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) != RESET)
{
if(!spi_rx_flag)
{
spi_rx_flag = 1;
SPI_I2S_DMACmd(WIFI_SPI, SPI_I2S_DMAReq_Rx, ENABLE);
}
}
}
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(TIP_WIFI_IRQ_EXTI_LINE) != RESET)
{
if(GPIO_ReadInputDataBit(TIP_WIFI_SPI_GRP,TIP_WIFI_NSS_PIN)==Bit_SET) /*it is a raising edge, begin of transition*/
{
SPI_I2S_DMACmd(WIFI_SPI, SPI_I2S_DMAReq_Rx, ENABLE);
spi_rx_flag = 1;
}
else /*it is a falling edge, end of transition*/
{
SPI_I2S_DMACmd(WIFI_SPI, SPI_I2S_DMAReq_Rx, DISABLE);
spi_rx_flag = 0;
}
EXTI_ClearITPendingBit(TIP_WIFI_IRQ_EXTI_LINE);
}
}
void EXTI1_IRQHandler(void)
{
if(EXTI_GetITStatus(TIP_WIFI_IRQ_EXTI_LINE) != RESET)
{
if(GPIO_ReadInputDataBit(TIP_WIFI_SPI_GRP,TIP_WIFI_NSS_PIN)==Bit_SET) /*it is a raising edge, begin of transition*/
{
spi_rx_flag = 1;
}
else /*it is a falling edge, end of transition*/
{
spi_rx_flag = 0;
}
EXTI_ClearITPendingBit(TIP_WIFI_IRQ_EXTI_LINE);
}
}
/*******************************************************************************
* Function Name : DMA1_Channel4_IRQHandler
* Description : This function handles DMA1 Channel 4 interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void DMA1_Channel4_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_IT_TC4))
DMA_ClearFlag(DMA1_FLAG_TC4);
}
/*******************************************************************************
* Function Name : DMA1_Channel5_IRQHandler
* Description : This function handles DMA1 Channel 5 interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void DMA1_Channel5_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_IT_TC5))
DMA_ClearFlag(DMA1_FLAG_TC5);
dma_tx_available = 1;
#ifdef WIFI_SPI_SLAVE
SLV2MST_NCS;
#endif /* WIFI_SPI_SLAVE */
}