Advertisement
Nanne118

STM32 DSP code

May 9th, 2019
455
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 12.17 KB | None | 0 0
  1. /* USER CODE BEGIN Header */
  2. /**
  3.   ******************************************************************************
  4.   * @file           : main.c
  5.   * @brief          : Main program body
  6.   ******************************************************************************
  7.   * @attention
  8.   *
  9.   * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
  10.   * All rights reserved.</center></h2>
  11.   *
  12.   * This software component is licensed by ST under BSD 3-Clause license,
  13.   * the "License"; You may not use this file except in compliance with the
  14.   * License. You may obtain a copy of the License at:
  15.   *                        opensource.org/licenses/BSD-3-Clause
  16.   *
  17.   ******************************************************************************
  18.   */
  19. /* USER CODE END Header */
  20.  
  21. /* Includes ------------------------------------------------------------------*/
  22. #include "main.h"
  23. #include <stdio.h>
  24. #include <stdbool.h>
  25. #include "arm_math.h"                   // ARM::CMSIS:DSP
  26. #include <core_cm4.h>
  27. #include <stm32f4xx.h>
  28. //#include <ARMCM4.h>
  29.  
  30. #define __CMSIS_GENERIC
  31. #define CMSIS_device_header.h
  32.  
  33. /* Private includes ----------------------------------------------------------*/
  34. /* USER CODE BEGIN Includes */
  35.  
  36. /* USER CODE END Includes */
  37.  
  38. /* Private typedef -----------------------------------------------------------*/
  39. /* USER CODE BEGIN PTD */
  40.  
  41. /* USER CODE END PTD */
  42.  
  43. /* Private define ------------------------------------------------------------*/
  44. /* USER CODE BEGIN PD */
  45.  
  46. /* USER CODE END PD */
  47.  
  48. /* Private macro -------------------------------------------------------------*/
  49. /* USER CODE BEGIN PM */
  50.  
  51. /* USER CODE END PM */
  52.  
  53. /* Private variables ---------------------------------------------------------*/
  54. ADC_HandleTypeDef hadc1;
  55. DMA_HandleTypeDef hdma_adc1;
  56.  
  57. UART_HandleTypeDef huart2;
  58.  
  59. // can I move the arm_rfft_fast_instance_f32 S; here or does this get removed upon re-init?
  60.  
  61. /* USER CODE BEGIN PV */
  62.  
  63. /* USER CODE END PV */
  64.  
  65. /* Private function prototypes -----------------------------------------------*/
  66. void SystemClock_Config(void);
  67. static void MX_GPIO_Init(void);
  68. static void MX_DMA_Init(void);
  69. static void MX_ADC1_Init(void);
  70. static void MX_USART2_UART_Init(void);
  71. /* USER CODE BEGIN PFP */
  72.  
  73. /* USER CODE END PFP */
  74.  
  75. /* Private user code ---------------------------------------------------------*/
  76. /* USER CODE BEGIN 0 */
  77.    
  78.     #define samples 1024 // for fft take power of 2: 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192.
  79.     #define buffer_length (samples * 3)
  80.        
  81.        
  82. //  arm_rfft_fast_instance_f32 S; // instance structure for floating-point RFFT function
  83.    
  84.        
  85.     bool conversionPaused = 0; // Start off with conversion running, pause it after conversion, resume it after DSP
  86.     volatile uint32_t adc_buffer[buffer_length]; // volatile type, because it will be modified in an ISR
  87.    
  88.     int32_t x_cnt, y_cnt, z_cnt = 0;
  89.     float Bx[samples], By[samples], Bz[samples]; //arrays that hold the sample values, input
  90.     float DSPx[samples], DSPy[samples], DSPz[samples];  // arrays that hold the FFT values, output
  91.    
  92.     uint8_t msg1[25] = "Conversion complete!\n\r"; // debug message 1, to be send over UART / COM
  93.     uint8_t msg2[25] = "Conversion paused!\n\r"; // debug message 2, to be send over UART / COM
  94.            
  95.            
  96.     void  HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) // Callback when the HAL transfer is complete, i.e. the buffer has been filled up
  97.     {
  98.         if (hadc->Instance == ADC1 && !conversionPaused) // Only run the data conversion when the conversion is not paused
  99.         {
  100.             conversionPaused = 1; // Pause the conversion, so the data gathering is paused (avoids sample data overwrite) and we can invoke the DSP to be run
  101.             for(int i = 0; i<buffer_length/3; i++) // Only run it for 1/3th of buffer_length, as we take 3 buffer values per iteration loop
  102.             {
  103.                 Bx[i] = ((3.3-0)/4096) * adc_buffer[0+3*i]; //Bx values on 0, 3, 6, 9, 12, etc.
  104.                 By[i] = ((3.3-0)/4096) * adc_buffer[1+3*i]; //By values on 1, 4, 7, 10, 13, etc.
  105.                 Bz[i] = ((3.3-0)/4096) * adc_buffer[2+3*i]; //Bz values on 2, 5, 8, 11, 14, etc.
  106.             }
  107.             HAL_UART_Transmit(&huart2, msg1, 25, 100); // Conversion complete msg:  (transmit where, what data, how many characters, timeout)
  108.         }
  109.     }
  110. /* USER CODE END 0 */
  111.  
  112. /**
  113.   * @brief  The application entry point.
  114.   * @retval int
  115.   */
  116. int main(void)
  117. {
  118.   /* USER CODE BEGIN 1 */
  119.  
  120.   /* USER CODE END 1 */
  121.  
  122.   /* MCU Configuration--------------------------------------------------------*/
  123.  
  124.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  125.   HAL_Init();
  126.  
  127.   /* USER CODE BEGIN Init */
  128.  
  129.   /* USER CODE END Init */
  130.  
  131.   /* Configure the system clock */
  132.   SystemClock_Config();
  133.  
  134.   /* USER CODE BEGIN SysInit */
  135.  
  136.   /* USER CODE END SysInit */
  137.  
  138.   /* Initialize all configured peripherals */
  139.   MX_GPIO_Init();
  140.   MX_DMA_Init();
  141.   MX_ADC1_Init();
  142.   MX_USART2_UART_Init();
  143.   /* USER CODE BEGIN 2 */
  144.    
  145.     HAL_ADC_Start_DMA (&hadc1, (uint32_t*) adc_buffer, buffer_length);
  146.  
  147.   /* USER CODE END 2 */
  148.  
  149.   /* Infinite loop */
  150.   /* USER CODE BEGIN WHILE */
  151.  
  152.     while (1) // Necessary for the CPU to loop and invoke the data transfer ConvCpltCallback
  153.   {
  154.     /* USER CODE END WHILE */
  155.  
  156.     /* USER CODE BEGIN 3 */
  157.        
  158.         if(conversionPaused) // when the conversion is paused, run the DSP on the CPU
  159.         {
  160.             HAL_UART_Transmit(&huart2, msg2, 25, 100);
  161.            
  162.             //DSP GOES HERE -----------------------------------------
  163.            
  164.            
  165.            
  166. //          arm_rfft_fast_init_f32(&S, samples); //Init the RFFT: point to prev. defined structreference, give length
  167.            
  168. //          arm_rfft_fast_f32(&S, Bx, DSPx, 0); //Process data through RFFT module, for x: (refstruct, input, output, 0 for RFFT or 1 for RIFFT)
  169. //          arm_rfft_fast_f32(&S, By, DSPy, 0); //Process data through RFFT module, for y
  170. //          arm_rfft_fast_f32(&S, Bz, DSPz, 0); //Process data through RFFT module, for z
  171.            
  172. //          arm_abs_f32(DSPx+1,&sNyqTEMPx,1);
  173. //          DSPx[1] = 0;
  174. //          arm_abs_f32(DSPx+1,&sNyqTEMPy,1);
  175. //          DSPy[1] = 0;
  176. //          arm_abs_f32(DSPx+1,&sNyqTEMPz,1);
  177. //          DSPz[1] = 0;
  178.            
  179. //          arm_cmplx_mag_f32(DSPx, DSPx, samples/2);
  180. //          DSPx[samples/2] = sNyqTEMPx;
  181. //          arm_cmplx_mag_f32(DSPy, DSPy, samples/2);
  182. //          DSPy[samples/2] = sNyqTEMPy;
  183. //          arm_cmplx_mag_f32(DSPz, DSPz, samples/2);
  184. //          DSPz[samples/2] = sNyqTEMPz;
  185.            
  186. //          arm_max_f32(DSPx[1], (samples/2)-1, &maxvalue, &maxindex);
  187.            
  188.             //conversionPaused = 1; // DSP has been run, results are released, get back to the data gathering phase
  189.         }
  190.        
  191.   }
  192.   /* USER CODE END 3 */
  193. }
  194.  
  195. /**
  196.   * @brief System Clock Configuration
  197.   * @retval None
  198.   */
  199. void SystemClock_Config(void)
  200. {
  201.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  202.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  203.  
  204.   /** Configure the main internal regulator output voltage
  205.   */
  206.   __HAL_RCC_PWR_CLK_ENABLE();
  207.   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  208.   /** Initializes the CPU, AHB and APB busses clocks
  209.   */
  210.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  211.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  212.   RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  213.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  214.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  215.   RCC_OscInitStruct.PLL.PLLM = 8;
  216.   RCC_OscInitStruct.PLL.PLLN = 100;
  217.   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  218.   RCC_OscInitStruct.PLL.PLLQ = 4;
  219.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  220.   {
  221.     Error_Handler();
  222.   }
  223.   /** Initializes the CPU, AHB and APB busses clocks
  224.   */
  225.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  226.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  227.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  228.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  229.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  230.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  231.  
  232.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
  233.   {
  234.     Error_Handler();
  235.   }
  236. }
  237.  
  238. /**
  239.   * @brief ADC1 Initialization Function
  240.   * @param None
  241.   * @retval None
  242.   */
  243. static void MX_ADC1_Init(void)
  244. {
  245.  
  246.   /* USER CODE BEGIN ADC1_Init 0 */
  247.  
  248.   /* USER CODE END ADC1_Init 0 */
  249.  
  250.   ADC_ChannelConfTypeDef sConfig = {0};
  251.  
  252.   /* USER CODE BEGIN ADC1_Init 1 */
  253.  
  254.   /* USER CODE END ADC1_Init 1 */
  255.   /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
  256.   */
  257.   hadc1.Instance = ADC1;
  258.   hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV8;
  259.   hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  260.   hadc1.Init.ScanConvMode = ENABLE;
  261.   hadc1.Init.ContinuousConvMode = ENABLE;
  262.   hadc1.Init.DiscontinuousConvMode = DISABLE;
  263.   hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  264.   hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  265.   hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  266.   hadc1.Init.NbrOfConversion = 3;
  267.   hadc1.Init.DMAContinuousRequests = ENABLE;
  268.   hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  269.   if (HAL_ADC_Init(&hadc1) != HAL_OK)
  270.   {
  271.     Error_Handler();
  272.   }
  273.   /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  274.   */
  275.   sConfig.Channel = ADC_CHANNEL_0;
  276.   sConfig.Rank = 1;
  277.   sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
  278.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  279.   {
  280.     Error_Handler();
  281.   }
  282.   /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  283.   */
  284.   sConfig.Channel = ADC_CHANNEL_1;
  285.   sConfig.Rank = 2;
  286.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  287.   {
  288.     Error_Handler();
  289.   }
  290.   /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  291.   */
  292.   sConfig.Channel = ADC_CHANNEL_4;
  293.   sConfig.Rank = 3;
  294.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  295.   {
  296.     Error_Handler();
  297.   }
  298.   /* USER CODE BEGIN ADC1_Init 2 */
  299.  
  300.   /* USER CODE END ADC1_Init 2 */
  301.  
  302. }
  303.  
  304. /**
  305.   * @brief USART2 Initialization Function
  306.   * @param None
  307.   * @retval None
  308.   */
  309. static void MX_USART2_UART_Init(void)
  310. {
  311.  
  312.   /* USER CODE BEGIN USART2_Init 0 */
  313.  
  314.   /* USER CODE END USART2_Init 0 */
  315.  
  316.   /* USER CODE BEGIN USART2_Init 1 */
  317.  
  318.   /* USER CODE END USART2_Init 1 */
  319.   huart2.Instance = USART2;
  320.   huart2.Init.BaudRate = 9600;
  321.   huart2.Init.WordLength = UART_WORDLENGTH_8B;
  322.   huart2.Init.StopBits = UART_STOPBITS_1;
  323.   huart2.Init.Parity = UART_PARITY_NONE;
  324.   huart2.Init.Mode = UART_MODE_TX_RX;
  325.   huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  326.   huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  327.   if (HAL_UART_Init(&huart2) != HAL_OK)
  328.   {
  329.     Error_Handler();
  330.   }
  331.   /* USER CODE BEGIN USART2_Init 2 */
  332.  
  333.   /* USER CODE END USART2_Init 2 */
  334.  
  335. }
  336.  
  337. /**
  338.   * Enable DMA controller clock
  339.   */
  340. static void MX_DMA_Init(void)
  341. {
  342.   /* DMA controller clock enable */
  343.   __HAL_RCC_DMA2_CLK_ENABLE();
  344.  
  345.   /* DMA interrupt init */
  346.   /* DMA2_Stream0_IRQn interrupt configuration */
  347.   HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
  348.   HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
  349.  
  350. }
  351.  
  352. /**
  353.   * @brief GPIO Initialization Function
  354.   * @param None
  355.   * @retval None
  356.   */
  357. static void MX_GPIO_Init(void)
  358. {
  359.  
  360.   /* GPIO Ports Clock Enable */
  361.   __HAL_RCC_GPIOH_CLK_ENABLE();
  362.   __HAL_RCC_GPIOA_CLK_ENABLE();
  363.  
  364. }
  365.  
  366. /* USER CODE BEGIN 4 */
  367.  
  368. /* USER CODE END 4 */
  369.  
  370. /**
  371.   * @brief  This function is executed in case of error occurrence.
  372.   * @retval None
  373.   */
  374. void Error_Handler(void)
  375. {
  376.   /* USER CODE BEGIN Error_Handler_Debug */
  377.   /* User can add his own implementation to report the HAL error return state */
  378.  
  379.   /* USER CODE END Error_Handler_Debug */
  380. }
  381.  
  382. #ifdef  USE_FULL_ASSERT
  383. /**
  384.   * @brief  Reports the name of the source file and the source line number
  385.   *         where the assert_param error has occurred.
  386.   * @param  file: pointer to the source file name
  387.   * @param  line: assert_param error line source number
  388.   * @retval None
  389.   */
  390. void assert_failed(uint8_t *file, uint32_t line)
  391. {
  392.   /* USER CODE BEGIN 6 */
  393.   /* User can add his own implementation to report the file name and line number,
  394.      tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  395.   /* USER CODE END 6 */
  396. }
  397. #endif /* USE_FULL_ASSERT */
  398.  
  399. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement