From 2983da24b294ffda0b4dd70ea9fdce5f1febb0d9 Mon Sep 17 00:00:00 2001 From: Robert Fisk Date: Fri, 16 Oct 2015 23:42:47 +1300 Subject: [PATCH] Changed Upstream and Downstream SPI transfers back to DMA. DMA works correctly now, either because SPI is in 16-bit mode, or because I found all the other bugs! Doubled SPI baudrate to 10.5Mbps. Transfer speed now limited (again) by Downstream's lack of FIFO buffering in the USB host controller. Also disabled DMA transaction half-complete interrupt in stm32f4xx_hal_dma.c, as it wasn't doing anything useful. --- .../Src/stm32f4xx_hal_dma.c | 2 +- Downstream/Inc/interrupts.h | 6 +- Downstream/Src/downstream_spi.c | 42 +++++------ Downstream/Src/hal_msp.c | 42 +++++++++-- Downstream/Src/interrupts.c | 25 ++++--- Downstream/Src/usbh_config.c | 2 +- .../Src/stm32f4xx_hal_dma.c | 2 +- Upstream/Inc/board_config.h | 8 +-- Upstream/Inc/interrupts.h | 10 +-- Upstream/Inc/upstream_spi.h | 3 +- Upstream/Src/hal_msp.c | 50 ++++++++++--- Upstream/Src/interrupts.c | 29 ++++---- Upstream/Src/main.c | 8 +-- Upstream/Src/upstream_spi.c | 70 +++++-------------- Upstream/Src/usbd_config.c | 2 +- 15 files changed, 172 insertions(+), 129 deletions(-) diff --git a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c index b899d85..e138c6a 100644 --- a/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c +++ b/Downstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c @@ -407,7 +407,7 @@ HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TC); /* Enable the Half transfer complete interrupt */ - __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT); +// __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT); /* Enable the transfer Error interrupt */ __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TE); diff --git a/Downstream/Inc/interrupts.h b/Downstream/Inc/interrupts.h index 2ae4ba4..1dd3f3c 100644 --- a/Downstream/Inc/interrupts.h +++ b/Downstream/Inc/interrupts.h @@ -46,9 +46,9 @@ /* Exported constants --------------------------------------------------------*/ #define INT_PRIORITY_SYSTICK 2 -//#define INT_PRIORITY_SPI_DMA 10 -#define INT_PRIORITY_SPI 8 //Interrupt-based SPI must be highest priority! -#define INT_PRIORITY_OTG_FS 10 +#define INT_PRIORITY_SPI_DMA 10 +//#define INT_PRIORITY_SPI 8 //Interrupt-based SPI must be highest priority! +#define INT_PRIORITY_USB 10 /* Exported macro ------------------------------------------------------------*/ diff --git a/Downstream/Src/downstream_spi.c b/Downstream/Src/downstream_spi.c index 48adc16..21a3325 100644 --- a/Downstream/Src/downstream_spi.c +++ b/Downstream/Src/downstream_spi.c @@ -177,10 +177,10 @@ void Downstream_PrepareReceivePacketSize(DownstreamPacketTypeDef* freePacket) } CurrentWorkingPacket = freePacket; CurrentWorkingPacket->Length16 = 0; - if (HAL_SPI_TransmitReceive_IT(&Hspi1, - (uint8_t*)&CurrentWorkingPacket->Length16, - (uint8_t*)&CurrentWorkingPacket->Length16, - 2) != HAL_OK) //We only need to read one word, but the peripheral library freaks out... + if (HAL_SPI_TransmitReceive_DMA(&Hspi1, + (uint8_t*)&CurrentWorkingPacket->Length16, + (uint8_t*)&CurrentWorkingPacket->Length16, + 2) != HAL_OK) //We only need to read one word, but the peripheral library freaks out... { DOWNSTREAM_SPI_FREAKOUT; return; @@ -232,10 +232,10 @@ HAL_StatusTypeDef Downstream_TransmitPacket(DownstreamPacketTypeDef* packetToWri DownstreamInterfaceState = DOWNSTREAM_INTERFACE_TX_SIZE_WAIT; CurrentWorkingPacket = packetToWrite; - if (HAL_SPI_TransmitReceive_IT(&Hspi1, - (uint8_t*)&CurrentWorkingPacket->Length16, - (uint8_t*)&TemporaryIncomingPacketLength, - 2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out... + if (HAL_SPI_TransmitReceive_DMA(&Hspi1, + (uint8_t*)&CurrentWorkingPacket->Length16, + (uint8_t*)&TemporaryIncomingPacketLength, + 2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out... { DOWNSTREAM_SPI_FREAKOUT; return HAL_ERROR; @@ -274,7 +274,7 @@ void Downstream_SPIProcess(void) //Finished transmitting packet size if (DownstreamInterfaceState == DOWNSTREAM_INTERFACE_TX_SIZE_WAIT) { - if (TemporaryIncomingPacketLength != 0) + if ((uint16_t)TemporaryIncomingPacketLength != 0) { //Currently we just freak out if Upstream sends us an unexpected command. //Theoretically we could reset our downstream state machine and accept the new command... @@ -283,10 +283,10 @@ void Downstream_SPIProcess(void) } DownstreamInterfaceState = DOWNSTREAM_INTERFACE_TX_PACKET_WAIT; - if (HAL_SPI_TransmitReceive_IT(&Hspi1, - &CurrentWorkingPacket->CommandClass, - &CurrentWorkingPacket->CommandClass, - ((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK) + if (HAL_SPI_TransmitReceive_DMA(&Hspi1, + &CurrentWorkingPacket->CommandClass, + &CurrentWorkingPacket->CommandClass, + ((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK) { DOWNSTREAM_SPI_FREAKOUT; return; @@ -306,10 +306,10 @@ void Downstream_SPIProcess(void) DownstreamInterfaceState = DOWNSTREAM_INTERFACE_TX_SIZE_WAIT; CurrentWorkingPacket = NextTxPacket; NextTxPacket = NULL; - if (HAL_SPI_TransmitReceive_IT(&Hspi1, - (uint8_t*)&CurrentWorkingPacket->Length16, - (uint8_t*)&TemporaryIncomingPacketLength, - 2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out... + if (HAL_SPI_TransmitReceive_DMA(&Hspi1, + (uint8_t*)&CurrentWorkingPacket->Length16, + (uint8_t*)&TemporaryIncomingPacketLength, + 2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out... { DOWNSTREAM_SPI_FREAKOUT; return; @@ -336,10 +336,10 @@ void Downstream_SPIProcess(void) return; } DownstreamInterfaceState = DOWNSTREAM_INTERFACE_RX_PACKET_WAIT; - if (HAL_SPI_TransmitReceive_IT(&Hspi1, - &CurrentWorkingPacket->CommandClass, - &CurrentWorkingPacket->CommandClass, - ((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK) + if (HAL_SPI_TransmitReceive_DMA(&Hspi1, + &CurrentWorkingPacket->CommandClass, + &CurrentWorkingPacket->CommandClass, + ((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK) { DOWNSTREAM_SPI_FREAKOUT; return; diff --git a/Downstream/Src/hal_msp.c b/Downstream/Src/hal_msp.c index 4bc59d3..157391e 100644 --- a/Downstream/Src/hal_msp.c +++ b/Downstream/Src/hal_msp.c @@ -59,7 +59,7 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) if(hspi->Instance==SPI1) { __SPI1_CLK_ENABLE(); -// __DMA2_CLK_ENABLE(); + __DMA2_CLK_ENABLE(); /**SPI1 GPIO Configuration PA4 ------> SPI_NSS @@ -84,9 +84,39 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(UPSTREAM_TX_REQUEST_PORT, &GPIO_InitStruct); - //Interrupt-based SPI now! - HAL_NVIC_SetPriority(SPI1_IRQn, INT_PRIORITY_SPI, 0); - HAL_NVIC_EnableIRQ(SPI1_IRQn); + /* Peripheral DMA init*/ + hdma_spi1_rx.Instance = DMA2_Stream2; + hdma_spi1_rx.Init.Channel = DMA_CHANNEL_3; + hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE; + hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; + hdma_spi1_rx.Init.Mode = DMA_NORMAL; + hdma_spi1_rx.Init.Priority = DMA_PRIORITY_MEDIUM; + hdma_spi1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + HAL_DMA_Init(&hdma_spi1_rx); + __HAL_LINKDMA(hspi,hdmarx,hdma_spi1_rx); + + hdma_spi1_tx.Instance = DMA2_Stream3; + hdma_spi1_tx.Init.Channel = DMA_CHANNEL_3; + hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; + hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE; + hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; + hdma_spi1_tx.Init.Mode = DMA_NORMAL; + hdma_spi1_tx.Init.Priority = DMA_PRIORITY_MEDIUM; + hdma_spi1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + HAL_DMA_Init(&hdma_spi1_tx); + __HAL_LINKDMA(hspi,hdmatx,hdma_spi1_tx); + + /* DMA interrupt init */ + HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, INT_PRIORITY_SPI_DMA, 0); + HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn); + HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, INT_PRIORITY_SPI_DMA, 0); + HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn); + } } @@ -104,6 +134,10 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) PA7 ------> SPI1_MOSI */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7); + + /* Peripheral DMA DeInit*/ + HAL_DMA_DeInit(hspi->hdmarx); + HAL_DMA_DeInit(hspi->hdmatx); } } diff --git a/Downstream/Src/interrupts.c b/Downstream/Src/interrupts.c index 411f8ba..15e0f01 100644 --- a/Downstream/Src/interrupts.c +++ b/Downstream/Src/interrupts.c @@ -43,10 +43,8 @@ /* External variables --------------------------------------------------------*/ extern HCD_HandleTypeDef hhcd_USB_OTG_FS; -extern SPI_HandleTypeDef Hspi1; - -//extern DMA_HandleTypeDef hdma_spi1_rx; -//extern DMA_HandleTypeDef hdma_spi1_tx; +extern DMA_HandleTypeDef hdma_spi1_rx; +extern DMA_HandleTypeDef hdma_spi1_tx; /******************************************************************************/ /* Cortex-M4 Processor Interruption and Exception Handlers */ @@ -69,17 +67,26 @@ void SysTick_Handler(void) /******************************************************************************/ -void SPI1_IRQHandler(void) + +void DMA2_Stream2_IRQHandler(void) { - SPI_INT_ACTIVE_ON; - HAL_SPI_IRQHandler(&Hspi1); - SPI_INT_ACTIVE_OFF; + //SPI_INT_ACTIVE_ON; + HAL_DMA_IRQHandler(&hdma_spi1_rx); + //SPI_INT_ACTIVE_OFF; } +void DMA2_Stream3_IRQHandler(void) +{ + //SPI_INT_ACTIVE_ON; + HAL_DMA_IRQHandler(&hdma_spi1_tx); + //SPI_INT_ACTIVE_OFF; +} void OTG_FS_IRQHandler(void) { - HAL_HCD_IRQHandler(&hhcd_USB_OTG_FS); + SPI_INT_ACTIVE_ON; + HAL_HCD_IRQHandler(&hhcd_USB_OTG_FS); + SPI_INT_ACTIVE_OFF; } diff --git a/Downstream/Src/usbh_config.c b/Downstream/Src/usbh_config.c index cf23d88..2421772 100644 --- a/Downstream/Src/usbh_config.c +++ b/Downstream/Src/usbh_config.c @@ -67,7 +67,7 @@ void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd) __USB_OTG_FS_CLK_ENABLE(); /* Peripheral interrupt init*/ - HAL_NVIC_SetPriority(OTG_FS_IRQn, INT_PRIORITY_OTG_FS, 0); + HAL_NVIC_SetPriority(OTG_FS_IRQn, INT_PRIORITY_USB, 0); HAL_NVIC_EnableIRQ(OTG_FS_IRQn); } } diff --git a/Upstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c b/Upstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c index a965390..c95e23d 100755 --- a/Upstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c +++ b/Upstream/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c @@ -408,7 +408,7 @@ HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TC); /* Enable the Half transfer complete interrupt */ - __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT); +// __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT); /* Enable the transfer Error interrupt */ __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TE); diff --git a/Upstream/Inc/board_config.h b/Upstream/Inc/board_config.h index b4fc59d..e576c57 100644 --- a/Upstream/Inc/board_config.h +++ b/Upstream/Inc/board_config.h @@ -34,10 +34,10 @@ #define FAULT_LED_ON STAT_LED_ON #define FAULT_LED_OFF STAT_LED_OFF -#define SPI_INT_ACTIVE_PIN GPIO_PIN_5 /////////Temporary indicator of SPI activity -#define SPI_INT_ACTIVE_PORT GPIOB -#define SPI_INT_ACTIVE_ON SPI_INT_ACTIVE_PORT->BSRR = (SPI_INT_ACTIVE_PIN << BSRR_SHIFT_HIGH) -#define SPI_INT_ACTIVE_OFF SPI_INT_ACTIVE_PORT->BSRR = (SPI_INT_ACTIVE_PIN << BSRR_SHIFT_LOW) +#define INT_ACTIVE_PIN GPIO_PIN_5 /////////Temporary indicator of SPI activity +#define INT_ACTIVE_PORT GPIOB +#define INT_ACTIVE_ON INT_ACTIVE_PORT->BSRR = (INT_ACTIVE_PIN << BSRR_SHIFT_HIGH) +#define INT_ACTIVE_OFF INT_ACTIVE_PORT->BSRR = (INT_ACTIVE_PIN << BSRR_SHIFT_LOW) #define SPI1_NSS_PIN GPIO_PIN_4 #define SPI1_NSS_PORT GPIOA diff --git a/Upstream/Inc/interrupts.h b/Upstream/Inc/interrupts.h index 1946eae..eace701 100755 --- a/Upstream/Inc/interrupts.h +++ b/Upstream/Inc/interrupts.h @@ -51,9 +51,9 @@ * A lower priority value indicates a higher priority. */ #define INT_PRIORITY_SYSTICK 2 -#define INT_PRIORITY_SPI 8 //SPI is more important than USB now! -#define INT_PRIORITY_OTG_FS 10 -#define INT_PRIORITY_EXT3I INT_PRIORITY_OTG_FS +#define INT_PRIORITY_SPI_DMA 10 //SPI is more important than USB now! +#define INT_PRIORITY_USB 10 +#define INT_PRIORITY_EXT3I INT_PRIORITY_USB /* Exported macro ------------------------------------------------------------*/ @@ -61,8 +61,8 @@ void OTG_FS_IRQHandler(void); void SysTick_Handler(void); -//void DMA2_Stream2_IRQHandler(void); -//void DMA2_Stream3_IRQHandler(void); +void DMA2_Stream2_IRQHandler(void); +void DMA2_Stream3_IRQHandler(void); void EXTI3_IRQHandler(void); diff --git a/Upstream/Inc/upstream_spi.h b/Upstream/Inc/upstream_spi.h index 73b1ef1..0bd610e 100644 --- a/Upstream/Inc/upstream_spi.h +++ b/Upstream/Inc/upstream_spi.h @@ -62,7 +62,7 @@ PacketBusyTypeDef; typedef struct { PacketBusyTypeDef Busy; //Everything after Busy should be word-aligned - uint16_t Length16 __ALIGN_END; //Packet length includes CommandClass, Command, and Data + uint16_t Length16 __ALIGN_END; //Packet length includes CommandClass, Command, and Data uint8_t CommandClass; uint8_t Command; uint8_t Data[MSC_MEDIA_PACKET]; //Should (must?) be word-aligned, for USB copy routine @@ -82,7 +82,6 @@ void Upstream_ReleasePacket(UpstreamPacketTypeDef* packetToRelease); HAL_StatusTypeDef Upstream_TransmitPacket(UpstreamPacketTypeDef* packetToWrite); HAL_StatusTypeDef Upstream_ReceivePacket(SpiPacketReceivedCallbackTypeDef callback); void Upstream_TxOkInterrupt(void); -void Upstream_SPIProcess_InterruptSafe(void); void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi); void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi); diff --git a/Upstream/Src/hal_msp.c b/Upstream/Src/hal_msp.c index bffb17d..d5da64f 100755 --- a/Upstream/Src/hal_msp.c +++ b/Upstream/Src/hal_msp.c @@ -41,8 +41,8 @@ #include "board_config.h" -//DMA_HandleTypeDef spiTxDmaHandle; -//DMA_HandleTypeDef spiRxDmaHandle; +DMA_HandleTypeDef spiTxDmaHandle; +DMA_HandleTypeDef spiRxDmaHandle; /** @@ -61,13 +61,12 @@ void HAL_MspInit(void) void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) { - GPIO_InitTypeDef GPIO_InitStruct; if(hspi->Instance==SPI1) { /* Peripheral clock enable */ __HAL_RCC_SPI1_CLK_ENABLE(); -// __HAL_RCC_DMA2_CLK_ENABLE(); + __HAL_RCC_DMA2_CLK_ENABLE(); /**SPI1 GPIO Configuration PA4 ------> GPIO manual slave select @@ -96,9 +95,39 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) HAL_NVIC_SetPriority(EXTI3_IRQn, INT_PRIORITY_EXT3I, 0); HAL_NVIC_EnableIRQ(EXTI3_IRQn); - //Interrupt-based SPI now! - HAL_NVIC_SetPriority(SPI1_IRQn, INT_PRIORITY_SPI, 0); - HAL_NVIC_EnableIRQ(SPI1_IRQn); + //Prepare Tx DMA stream + hspi->hdmatx = &spiTxDmaHandle; + spiTxDmaHandle.Instance = DMA2_Stream3; + spiTxDmaHandle.Parent = hspi; + spiTxDmaHandle.Init.Channel = DMA_CHANNEL_3; + spiTxDmaHandle.Init.Direction = DMA_MEMORY_TO_PERIPH; + spiTxDmaHandle.Init.PeriphInc = DMA_PINC_DISABLE; + spiTxDmaHandle.Init.MemInc = DMA_MINC_ENABLE; + spiTxDmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + spiTxDmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; + spiTxDmaHandle.Init.Mode = DMA_NORMAL; + spiTxDmaHandle.Init.Priority = DMA_PRIORITY_MEDIUM; + spiTxDmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + HAL_DMA_Init(&spiTxDmaHandle); + HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, INT_PRIORITY_SPI_DMA, 0); + HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn); + + //Prepare Rx DMA stream + hspi->hdmarx = &spiRxDmaHandle; + spiRxDmaHandle.Instance = DMA2_Stream2; + spiRxDmaHandle.Parent = hspi; + spiRxDmaHandle.Init.Channel = DMA_CHANNEL_3; + spiRxDmaHandle.Init.Direction = DMA_PERIPH_TO_MEMORY; + spiRxDmaHandle.Init.PeriphInc = DMA_PINC_DISABLE; + spiRxDmaHandle.Init.MemInc = DMA_MINC_ENABLE; + spiRxDmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + spiRxDmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; + spiRxDmaHandle.Init.Mode = DMA_NORMAL; + spiRxDmaHandle.Init.Priority = DMA_PRIORITY_MEDIUM; + spiRxDmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + HAL_DMA_Init(&spiRxDmaHandle); + HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, INT_PRIORITY_SPI_DMA, 0); + HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn); } } @@ -109,7 +138,7 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) { /* Peripheral clock disable */ __HAL_RCC_SPI1_CLK_DISABLE(); -// __HAL_RCC_DMA2_CLK_DISABLE(); + __HAL_RCC_DMA2_CLK_DISABLE(); /**SPI1 GPIO Configuration PA4 ------> SPI1_NSS @@ -118,6 +147,11 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) PA7 ------> SPI1_MOSI */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7); + HAL_DMA_DeInit(&spiTxDmaHandle); + HAL_DMA_DeInit(&spiRxDmaHandle); + + HAL_NVIC_DisableIRQ(DMA2_Stream3_IRQn); + HAL_NVIC_DisableIRQ(DMA2_Stream2_IRQn); } } diff --git a/Upstream/Src/interrupts.c b/Upstream/Src/interrupts.c index 2b7ad36..d950891 100755 --- a/Upstream/Src/interrupts.c +++ b/Upstream/Src/interrupts.c @@ -48,10 +48,8 @@ /* External variables --------------------------------------------------------*/ extern PCD_HandleTypeDef hpcd_USB_OTG_FS; -extern SPI_HandleTypeDef Hspi1; - -//extern DMA_HandleTypeDef spiTxDmaHandle; -//extern DMA_HandleTypeDef spiRxDmaHandle; +extern DMA_HandleTypeDef spiTxDmaHandle; +extern DMA_HandleTypeDef spiRxDmaHandle; /******************************************************************************/ @@ -74,6 +72,20 @@ void OTG_FS_IRQHandler(void) HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); } +void DMA2_Stream2_IRQHandler(void) +{ + INT_ACTIVE_ON; + HAL_DMA_IRQHandler(&spiRxDmaHandle); + INT_ACTIVE_OFF; +} + +void DMA2_Stream3_IRQHandler(void) +{ + INT_ACTIVE_ON; + HAL_DMA_IRQHandler(&spiTxDmaHandle); + INT_ACTIVE_OFF; +} + void EXTI3_IRQHandler(void) { __HAL_GPIO_EXTI_CLEAR_IT(DOWNSTREAM_TX_OK_PIN); @@ -83,14 +95,5 @@ void EXTI3_IRQHandler(void) ///////////////////////// -//As SPI DMA doesn't work when the USB peripheral is active, -//we are forced to use interrupts. This must be higher priority than USB. -void SPI1_IRQHandler(void) -{ - SPI_INT_ACTIVE_ON; - HAL_SPI_IRQHandler(&Hspi1); - SPI_INT_ACTIVE_OFF; -} - /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Upstream/Src/main.c b/Upstream/Src/main.c index 1d2a9fd..5342664 100755 --- a/Upstream/Src/main.c +++ b/Upstream/Src/main.c @@ -71,7 +71,7 @@ int main(void) while (1) { - Upstream_SPIProcess_InterruptSafe(); + } } @@ -156,11 +156,11 @@ void GPIO_Init(void) STAT_LED_OFF; //SPI_INT_ACTIVE indicator - GPIO_InitStruct.Pin = SPI_INT_ACTIVE_PIN; + GPIO_InitStruct.Pin = INT_ACTIVE_PIN; //GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; //GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(SPI_INT_ACTIVE_PORT, &GPIO_InitStruct); - SPI_INT_ACTIVE_OFF; + HAL_GPIO_Init(INT_ACTIVE_PORT, &GPIO_InitStruct); + INT_ACTIVE_OFF; } /* USER CODE BEGIN 4 */ diff --git a/Upstream/Src/upstream_spi.c b/Upstream/Src/upstream_spi.c index b6aff2f..e318075 100644 --- a/Upstream/Src/upstream_spi.c +++ b/Upstream/Src/upstream_spi.c @@ -31,7 +31,6 @@ SpiPacketReceivedCallbackTypeDef ReceivePacketCallback = NULL; //Indicates some uint32_t TemporaryIncomingPacketLength; //We don't actually care about what Downstream sends us when we are transmitting. We just need somewhere to put it so that our own packet length is not overwritten. uint8_t TxOkInterruptReceived = 0; -uint8_t SpiInterruptCompleted = 0; uint8_t SentCommandClass; uint8_t SentCommand; @@ -41,7 +40,6 @@ void Upstream_BeginTransmitPacketBody(void); HAL_StatusTypeDef Upstream_CheckBeginPacketReception(void); void Upstream_BeginReceivePacketSize(UpstreamPacketTypeDef* freePacket); void Upstream_BeginReceivePacketBody(void); -void Upstream_SPIProcess(void); @@ -58,7 +56,7 @@ void Upstream_InitSPI(void) Hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; Hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; Hspi1.Init.NSS = SPI_NSS_SOFT; - Hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; //42MHz APB2 / 32 = 1.3Mbaud + Hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; //42MHz APB2 / 4 = 10.5Mbaud Hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; Hspi1.Init.TIMode = SPI_TIMODE_DISABLED; Hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_ENABLED; @@ -231,37 +229,6 @@ HAL_StatusTypeDef Upstream_TransmitPacket(UpstreamPacketTypeDef* packetToWrite) //at SPI1 interrupt priority. Assume *hspi points to our hspi1. //We TxRx our outgoing packet because the SPI hardware freaks out if we only Tx it :-/ void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) -{ - SpiInterruptCompleted = 1; - - //Elevate priority here to stop EXT3I sneaking in - //before we have a chance to process UpstreamInterfaceState change. - __set_BASEPRI(INT_PRIORITY_OTG_FS << (8 - __NVIC_PRIO_BITS)); -} - - - -//Preemption protection wrapper around Upstream_SPIProcess() -//We must protect against preemption by USB and EXT3 interrupts at priority 10! -void Upstream_SPIProcess_InterruptSafe(void) -{ - //This is done on SPI interrupt callback... - //__set_BASEPRI(INT_PRIORITY_OTG_FS << (8 - __NVIC_PRIO_BITS)); - - if (SpiInterruptCompleted == 0) - { - return; - } - SpiInterruptCompleted = 0; - Upstream_SPIProcess(); - __set_BASEPRI(0); -} - - - -//Called from main(). -//Must be protected against preemption by USB and EXT3 interrupts at priority 10! -void Upstream_SPIProcess(void) { SpiPacketReceivedCallbackTypeDef tempPacketCallback; UpstreamPacketTypeDef* tempPacketToFree; @@ -475,10 +442,10 @@ void Upstream_BeginTransmitPacketSize(void) { UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_SIZE; SPI1_NSS_ASSERT; - if (HAL_SPI_TransmitReceive_IT(&Hspi1, - (uint8_t*)&CurrentWorkingPacket->Length16, - (uint8_t*)&TemporaryIncomingPacketLength, - 2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out... + if (HAL_SPI_TransmitReceive_DMA(&Hspi1, + (uint8_t*)&CurrentWorkingPacket->Length16, + (uint8_t*)&TemporaryIncomingPacketLength, + 2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out... { UPSTREAM_SPI_FREAKOUT; } @@ -490,10 +457,10 @@ void Upstream_BeginTransmitPacketBody(void) UpstreamInterfaceState = UPSTREAM_INTERFACE_TX_PACKET; SPI1_NSS_ASSERT; - if (HAL_SPI_TransmitReceive_IT(&Hspi1, - &CurrentWorkingPacket->CommandClass, - &CurrentWorkingPacket->CommandClass, - ((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK) + if (HAL_SPI_TransmitReceive_DMA(&Hspi1, + &CurrentWorkingPacket->CommandClass, + &CurrentWorkingPacket->CommandClass, + ((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK) { UPSTREAM_SPI_FREAKOUT; } @@ -516,13 +483,12 @@ void Upstream_BeginReceivePacketSize(UpstreamPacketTypeDef* freePacket) } UpstreamInterfaceState = UPSTREAM_INTERFACE_RX_SIZE; CurrentWorkingPacket = freePacket; - CurrentWorkingPacket->Length16 = 0; //Our RX buffer is used by HAL_SPI_Receive_DMA as dummy TX data, we set Length to 0 so downstream will know this is a dummy packet. + CurrentWorkingPacket->Length16 = 0; //Our RX buffer is used by HAL_SPI_TransmitReceive_DMA as dummy TX data, we set Length to 0 so downstream will know this is a dummy packet. SPI1_NSS_ASSERT; - TemporaryIncomingPacketLength = 0; - if (HAL_SPI_TransmitReceive_IT(&Hspi1, - (uint8_t*)&TemporaryIncomingPacketLength, - (uint8_t*)&CurrentWorkingPacket->Length16, - 2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out... + if (HAL_SPI_TransmitReceive_DMA(&Hspi1, + (uint8_t*)&CurrentWorkingPacket->Length16, + (uint8_t*)&CurrentWorkingPacket->Length16, + 2) != HAL_OK) //We only need to write one word, but the peripheral library freaks out... { UPSTREAM_SPI_FREAKOUT; } @@ -533,10 +499,10 @@ void Upstream_BeginReceivePacketBody(void) { UpstreamInterfaceState = UPSTREAM_INTERFACE_RX_PACKET; SPI1_NSS_ASSERT; - if (HAL_SPI_TransmitReceive_IT(&Hspi1, - &CurrentWorkingPacket->CommandClass, - &CurrentWorkingPacket->CommandClass, - ((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK) + if (HAL_SPI_TransmitReceive_DMA(&Hspi1, + &CurrentWorkingPacket->CommandClass, + &CurrentWorkingPacket->CommandClass, + ((CurrentWorkingPacket->Length16 < 2) ? 2 : CurrentWorkingPacket->Length16)) != HAL_OK) { UPSTREAM_SPI_FREAKOUT; } diff --git a/Upstream/Src/usbd_config.c b/Upstream/Src/usbd_config.c index efe7bd1..79d9132 100755 --- a/Upstream/Src/usbd_config.c +++ b/Upstream/Src/usbd_config.c @@ -79,7 +79,7 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd) GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - HAL_NVIC_SetPriority(OTG_FS_IRQn, INT_PRIORITY_OTG_FS, 0); + HAL_NVIC_SetPriority(OTG_FS_IRQn, INT_PRIORITY_USB, 0); HAL_NVIC_EnableIRQ(OTG_FS_IRQn); /* USER CODE BEGIN USB_OTG_FS_MspInit 1 */