Mercurial > public > ostc4
diff Small_CPU/Src/spi.c @ 38:5f11787b4f42
include in ostc4 repository
author | heinrichsweikamp |
---|---|
date | Sat, 28 Apr 2018 11:52:34 +0200 |
parents | |
children | cd298de33783 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Small_CPU/Src/spi.c Sat Apr 28 11:52:34 2018 +0200 @@ -0,0 +1,435 @@ +/** + ****************************************************************************** + * @file spi.c + * @author heinrichs weikamp gmbh + * @version V0.0.1 + * @date 16-Sept-2014 + * @brief Source code for spi control + * + @verbatim + ============================================================================== + ##### How to use ##### + ============================================================================== + @endverbatim + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2014 heinrichs weikamp</center></h2> + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "spi.h" +//#include "gpio.h" + +/* USER CODE BEGIN 0 */ +#include "scheduler.h" + +extern void GPIO_new_DEBUG_LOW(void); +extern void GPIO_new_DEBUG_HIGH(void); + + +uint8_t data_error = 0; +uint32_t data_error_time = 0; + +static void SPI_Error_Handler(void); + +/* USER CODE END 0 */ + +static uint8_t SPI_check_header_and_footer_ok(void); + +SPI_HandleTypeDef hspi1; +SPI_HandleTypeDef hspi3; + +DMA_HandleTypeDef hdma_tx; +DMA_HandleTypeDef hdma_rx; + +// SPI3 init function +void MX_SPI3_Init(void) +{ + hspi3.Instance = SPI3; + hspi3.Init.Mode = SPI_MODE_MASTER; + hspi3.Init.Direction = SPI_DIRECTION_2LINES; + hspi3.Init.DataSize = SPI_DATASIZE_8BIT; + hspi3.Init.CLKPolarity = SPI_POLARITY_HIGH; + hspi3.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi3.Init.NSS = SPI_NSS_SOFT; + hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; + hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi3.Init.TIMode = SPI_TIMODE_DISABLED; + hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; + hspi3.Init.CRCPolynomial = 7; + HAL_SPI_Init(&hspi3); +} + +void MX_SPI3_DeInit(void) +{ + HAL_SPI_DeInit(&hspi3); +} + +uint8_t SPI3_ButtonAdjust(uint8_t *arrayInput, uint8_t *arrayOutput) +{ + HAL_StatusTypeDef status; + uint8_t answer[10]; + uint8_t rework[10]; + uint8_t wait = 0; + + rework[0] = 0xFF; + for(int i = 0; i < 3; i++) + { + // limiter + if(arrayInput[i] == 0xFF) + arrayInput[i] = 0xFE; + if(arrayInput[i] >= 15) + { + // copy - auslöse-schwelle + rework[i+1] = arrayInput[i]; + // wieder-scharf-schalte-schwelle + rework[i+3+1] = arrayInput[i] - 10; + } + else + if(arrayInput[i] >= 10) + { + // copy - auslöse-schwelle + rework[i+1] = arrayInput[i]; + // wieder-scharf-schalte-schwelle + rework[i+3+1] = arrayInput[i] - 5; + } + else + { + // copy - auslöse-schwelle + rework[i+1] = 7; + // wieder-scharf-schalte-schwelle + rework[i+3+1] = 6; + } + } + + status = HAL_OK; /* = 0 */ + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9,GPIO_PIN_SET); + for(int i=0;i<7;i++) + { + for(int iiii = 0; iiii < 400; iiii++) + wait++; + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9,GPIO_PIN_RESET); + for(int iiii = 0; iiii < 400; iiii++) + wait++; + status += HAL_SPI_TransmitReceive(&hspi3, &rework[i], &answer[i], 1,20); + for(int iiii = 0; iiii < 400; iiii++) + wait++; + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9,GPIO_PIN_SET); + } + + if(status == HAL_OK) + { + for(int i = 0; i < 3; i++) + { + arrayOutput[i] = answer[i+2]; // first not, return of 0xFF not + } + return 1; + } + else + + return 0; +} + + +// SPI5 init function +void MX_SPI1_Init(void) +{ + hspi1.Instance = SPI1; + hspi1.Init.Mode = SPI_MODE_SLAVE; + hspi1.Init.Direction = SPI_DIRECTION_2LINES; + hspi1.Init.DataSize = SPI_DATASIZE_8BIT; + hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; + hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi1.Init.NSS = SPI_NSS_HARD_INPUT;//SPI_NSS_SOFT; + hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128; + hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi1.Init.TIMode = SPI_TIMODE_DISABLED; + hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;//_DISABLED; _ENABLED; + hspi1.Init.CRCPolynomial = 7; + HAL_SPI_Init(&hspi1); +} + +void MX_SPI_DeInit(void) +{ + HAL_SPI_DeInit(&hspi1); +} + + +void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) +{ + + GPIO_InitTypeDef GPIO_InitStruct; + + if(hspi->Instance==SPI1) + { + // Peripheral clock enable + __SPI1_CLK_ENABLE(); + __GPIOA_CLK_ENABLE(); + //SPI1 GPIO Configuration + //PA4 ------> SPI1_CS + //PA5 ------> SPI1_SCK + //PA6 ------> SPI1_MISO + //PA7 ------> SPI1_MOSI + + GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7; +// GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM; + GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + //##-3- Configure the DMA streams ########################################## + // Configure the DMA handler for Transmission process + hdma_tx.Instance = DMA2_Stream3; + hdma_tx.Init.Channel = DMA_CHANNEL_3; + hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; + hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_tx.Init.MemInc = DMA_MINC_ENABLE; + hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_tx.Init.Mode = DMA_NORMAL; + hdma_tx.Init.Priority = DMA_PRIORITY_LOW; + hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + hdma_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; + hdma_tx.Init.MemBurst = DMA_MBURST_INC4; + hdma_tx.Init.PeriphBurst = DMA_PBURST_INC4; + + HAL_DMA_Init(&hdma_tx); + + // Associate the initialized DMA handle to the the SPI handle + __HAL_LINKDMA(hspi, hdmatx, hdma_tx); + + // Configure the DMA handler for Transmission process + hdma_rx.Instance = DMA2_Stream0; + hdma_rx.Init.Channel = DMA_CHANNEL_3; + hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_rx.Init.MemInc = DMA_MINC_ENABLE; + hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_rx.Init.Mode = DMA_NORMAL; + hdma_rx.Init.Priority = DMA_PRIORITY_HIGH; + hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + hdma_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; + hdma_rx.Init.MemBurst = DMA_MBURST_INC4; + hdma_rx.Init.PeriphBurst = DMA_PBURST_INC4; + + HAL_DMA_Init(&hdma_rx); + + // Associate the initialized DMA handle to the the SPI handle + __HAL_LINKDMA(hspi, hdmarx, hdma_rx); + + //##-4- Configure the NVIC for DMA ######################################### + //NVIC configuration for DMA transfer complete interrupt (SPI3_RX) + HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 1, 0); + HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); + + // NVIC configuration for DMA transfer complete interrupt (SPI1_TX) + HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 1, 1); + HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn); + } + else + if(hspi->Instance==SPI3) + { + __GPIOC_CLK_ENABLE(); + __SPI3_CLK_ENABLE(); + + //SPI1 GPIO Configuration + //PC10 ------> SPI3_SCK + //PC11 ------> SPI3_MISO + //PC12 ------> SPI3_MOSI + //PA15 ------> SPI3_NSS (official) + //PC9 ------> SPI3_NSS (hw) + + GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FAST; + GPIO_InitStruct.Alternate = GPIO_AF6_SPI3; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_9; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_LOW; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9,GPIO_PIN_SET); + } +} + +void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi){ + if(hspi->Instance==SPI1) + { + __SPI1_FORCE_RESET(); + __SPI1_RELEASE_RESET(); + + //SPI1 GPIO Configuration + //PA5 ------> SPI1_SCK + //PA6 ------> SPI1_MISO + //PA7 ------> SPI1_MOSI + + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7); + + HAL_DMA_DeInit(&hdma_tx); + HAL_DMA_DeInit(&hdma_rx); + + HAL_NVIC_DisableIRQ(DMA2_Stream3_IRQn); + HAL_NVIC_DisableIRQ(DMA2_Stream0_IRQn); + } + else + if(hspi->Instance==SPI3) + { + __SPI3_FORCE_RESET(); + __SPI3_RELEASE_RESET(); + + //SPI1 GPIO Configuration + //PC10 ------> SPI3_SCK + //PC11 ------> SPI3_MISO + //PC12 ------> SPI3_MOSI + //PA15 ------> SPI3_NSS (official) + //PC9 ------> SPI3_NSS (hw) + HAL_GPIO_DeInit(GPIOC, GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12); + } +} + +void SPI_synchronize_with_Master(void) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + __GPIOA_CLK_ENABLE(); + /**SPI1 GPIO Configuration + PA5 ------> SPI1_SCK + */ + GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_LOW; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + HAL_Delay(10); + while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4) == 0); + HAL_Delay(10); + while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) == 1); + HAL_Delay(50); +} + + +void SPI_Start_single_TxRx_with_Master(void) +{ + uint8_t * pOutput; + + if(global.dataSendToSlave.getDeviceDataNow) + { + global.dataSendToSlave.getDeviceDataNow = 0; + pOutput = (uint8_t*)&(global.deviceDataSendToMaster); + } + else + { + pOutput = (uint8_t*)&(global.dataSendToMaster); + } + + if(HAL_SPI_TransmitReceive_DMA(&hspi1,pOutput, (uint8_t*)&(global.dataSendToSlave), EXCHANGE_BUFFERSIZE+1) != HAL_OK) + { + // Transfer error in transmission process + SPI_Error_Handler(); + } +} + + +void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) +{ + global.check_sync_not_running = 0; + /* stop data exchange? */ + if(global.mode == MODE_SHUTDOWN) + { + global.mode = MODE_SLEEP; + global.dataSendToSlavePending = 0; + global.dataSendToSlaveIsValid = 1; + global.dataSendToSlaveIsNotValidCount = 0; + return; + } + + /* data consistent? */ + if(SPI_check_header_and_footer_ok()) + { + GPIO_new_DEBUG_HIGH(); + global.dataSendToSlaveIsValid = 1; + global.dataSendToSlaveIsNotValidCount = 0; + } + else + { + GPIO_new_DEBUG_LOW(); + global.dataSendToSlaveIsValid = 0; + global.dataSendToSlaveIsNotValidCount++; + } + global.dataSendToMaster.power_on_reset = 0; + global.deviceDataSendToMaster.power_on_reset = 0; + /* no i2c or other time critical threads? */ + if(global.dataSendToSlaveIsValid) + { + if(!global.dataSendToSlaveStopEval) + { + scheduleSpecial_Evaluate_DataSendToSlave(); + } + else + { + global.dataSendToSlavePending = 1; + } + } + else + { + global.dataSendToSlavePending = 0; + } + + /* restart SPI */ + if(hspi == &hspi1) + { + if(global.dataSendToSlaveIsValid) + SPI_Start_single_TxRx_with_Master(); + } +} + + +static uint8_t SPI_check_header_and_footer_ok(void) +{ + if(global.dataSendToSlave.header.checkCode[0] != 0xBB) + return 0; + if(global.dataSendToSlave.header.checkCode[1] != 0x01) + return 0; + if(global.dataSendToSlave.header.checkCode[2] != 0x01) + return 0; + if(global.dataSendToSlave.header.checkCode[3] != 0xBB) + return 0; + if(global.dataSendToSlave.footer.checkCode[0] != 0xF4) + return 0; + if(global.dataSendToSlave.footer.checkCode[1] != 0xF3) + return 0; + if(global.dataSendToSlave.footer.checkCode[2] != 0xF2) + return 0; + if(global.dataSendToSlave.footer.checkCode[3] != 0xF1) + return 0; + + return 1; +} + +static void SPI_Error_Handler(void) +{ + while(1) + { + } +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/