From 374a63bc0c8c7e81cf69c6a14fd1b8aa7dcb5c38 Mon Sep 17 00:00:00 2001 From: Adam Prochazka Date: Sun, 9 Apr 2023 23:48:05 +0200 Subject: [PATCH] More optimalizations and multithreading - 1FPS --- Firmware/Core/Cam/Cam.c | 135 ++++++++++++- Firmware/Core/Inc/main.h | 36 ++-- Firmware/Core/Inc/stm32l4xx_it.h | 1 + Firmware/Core/Src/main.c | 145 ++++++++------ Firmware/Core/Src/stm32l4xx_hal_msp.c | 6 + Firmware/Core/Src/stm32l4xx_it.c | 67 ++++--- Firmware/Makefile | 278 +++++++++++++------------- Firmware/Probe.ioc | 6 +- Receiver/Makefile | 2 +- Receiver/Receiver.cpp | 8 +- Receiver/main.cpp | 11 +- Receiver/main.hpp | 3 +- 12 files changed, 432 insertions(+), 266 deletions(-) diff --git a/Firmware/Core/Cam/Cam.c b/Firmware/Core/Cam/Cam.c index 69e6841..944331d 100644 --- a/Firmware/Core/Cam/Cam.c +++ b/Firmware/Core/Cam/Cam.c @@ -132,39 +132,149 @@ void Cam_Init(I2C_HandleTypeDef *hi2c, SPI_HandleTypeDef *hspi) Cam_I2C_write(hi2c, (uint16_t)0x3621, 0x10); // REGISTER FOR CORRECT MIRROR FUNCTION Cam_I2C_write(hi2c, (uint16_t)0x3801, 0xb0); // TIMING HORIZONTAL START - ALSO FOR MIRROR Cam_I2C_write(hi2c, (uint16_t)0x4407, 0x04); // COMPRESSION CONTROL + Cam_I2C_write(hi2c, (uint16_t)0x5000, 0xFF); + + + Cam_I2C_write_bulk(hi2c, ov5642_1024x768); + + // Setup camera, H-sync: High, V-sync:high, Sensor_delay: no Delay, FIFO_mode:FIFO enabled, power_mode:Low_power + Cam_SPI_write(hspi, 0x03, 0x02); + Cam_SPI_write(hspi, 0x01, 0x00); // Capture Control Register - Set to capture n+1 frames + + HAL_Delay(5); + /* + Cam_I2C_write(hi2c, (uint16_t)0x3008, 0x80); + + Cam_I2C_write_bulk(hi2c, OV5642_QVGA_Preview); + + HAL_Delay(100); + + Cam_I2C_write_bulk(hi2c, OV5642_JPEG_Capture_QSXGA); //Cam_I2C_write_bulk(hi2c, ov5642_320x240); - //Cam_I2C_write_bulk(hi2c, ov5642_640x480); + + HAL_Delay(100); - Cam_I2C_write_bulk(hi2c, ov5642_1280x960); + //Cam_I2C_write_bulk(hi2c, OV5642_720P_Video_setting); + + Cam_I2C_write(hi2c, (uint16_t)0x3818, 0xa8); // TIMING CONTROL - ENABLE COMPRESSION, THUMBNAIL MODE DISABLE, VERTICAL FLIP, MIRROR + Cam_I2C_write(hi2c, (uint16_t)0x3621, 0x10); // REGISTER FOR CORRECT MIRROR FUNCTION + Cam_I2C_write(hi2c, (uint16_t)0x3801, 0xb0); // TIMING HORIZONTAL START - ALSO FOR MIRROR + //Cam_I2C_write(hi2c, (uint16_t)0x4407, 0x04); // COMPRESSION CONTROL + Cam_I2C_write(hi2c, (uint16_t)0x4407, 0x04); // COMPRESSION CONTROL + //Cam_I2C_write(hi2c, (uint16_t)0x5888, 0x01); + Cam_I2C_write(hi2c, (uint16_t)0x5000, 0xFF); + // Setup camera, H-sync: High, V-sync:high, Sensor_delay: no Delay, FIFO_mode:FIFO enabled, power_mode:Low_power Cam_SPI_write(hspi, 0x03, 0x02); + + Cam_I2C_write_bulk(hi2c, ov5642_320x240); + //Cam_I2C_write_bulk(hi2c, ov5642_1024x768); + + + Cam_SPI_write(hspi, 0x04, 0x01); + Cam_SPI_write(hspi, 0x01, 0x00); // Capture Control Register - Set to capture n+1 frames HAL_Delay(5); + */ } void Cam_Refresh(I2C_HandleTypeDef *hi2c, SPI_HandleTypeDef *hspi){ - Cam_I2C_write(hi2c, (uint16_t)0x3008, 0x80); + /*Cam_I2C_write(hi2c, (uint16_t)0x3008, 0x80); Cam_I2C_write_bulk(hi2c, OV5642_QVGA_Preview); Cam_I2C_write_bulk(hi2c, OV5642_JPEG_Capture_QSXGA); - //Cam_I2C_write_bulk(hi2c, OV5642_720P_Video_setting); + Cam_I2C_write(hi2c, (uint16_t)0x3818, 0xa8); // TIMING CONTROL - ENABLE COMPRESSION, THUMBNAIL MODE DISABLE, VERTICAL FLIP, MIRROR + Cam_I2C_write(hi2c, (uint16_t)0x3621, 0x10); // REGISTER FOR CORRECT MIRROR FUNCTION + Cam_I2C_write(hi2c, (uint16_t)0x3801, 0xb0); // TIMING HORIZONTAL START - ALSO FOR MIRROR + Cam_I2C_write(hi2c, (uint16_t)0x4407, 0x04); // COMPRESSION CONTROL + + Cam_I2C_write_bulk(hi2c, ov5642_1280x960); + + // Setup camera, H-sync: High, V-sync:high, Sensor_delay: no Delay, FIFO_mode:FIFO enabled, power_mode:Low_power + Cam_SPI_write(hspi, 0x03, 0x02); + Cam_SPI_write(hspi, 0x01, 0x00); // Capture Control Register - Set to capture n+1 frames + + HAL_Delay(5);*/ + + // SAFE TO REMOVE + //Cam_I2C_write(hi2c, (uint16_t)0x3008, 0x80); + + Cam_I2C_write_bulk(hi2c, OV5642_QVGA_Preview); + + Cam_I2C_write_bulk(hi2c, OV5642_JPEG_Capture_QSXGA); Cam_I2C_write(hi2c, (uint16_t)0x3818, 0xa8); // TIMING CONTROL - ENABLE COMPRESSION, THUMBNAIL MODE DISABLE, VERTICAL FLIP, MIRROR Cam_I2C_write(hi2c, (uint16_t)0x3621, 0x10); // REGISTER FOR CORRECT MIRROR FUNCTION Cam_I2C_write(hi2c, (uint16_t)0x3801, 0xb0); // TIMING HORIZONTAL START - ALSO FOR MIRROR Cam_I2C_write(hi2c, (uint16_t)0x4407, 0x04); // COMPRESSION CONTROL + Cam_I2C_write(hi2c, (uint16_t)0x5000, 0xFF); - //Cam_I2C_write_bulk(hi2c, ov5642_320x240); - //ov5642_1024x768 Cam_I2C_write_bulk(hi2c, ov5642_1024x768); - // Setup camera, H-sync: High, V-sync:high, Sensor_delay: no Delay, FIFO_mode:FIFO enabled, power_mode:Low_power Cam_SPI_write(hspi, 0x03, 0x02); + + + // Brightness 4 + Cam_I2C_write(hi2c, (uint16_t)0x5001, 0xff); + Cam_I2C_write(hi2c, (uint16_t)0x5589, 0x30); + Cam_I2C_write(hi2c, (uint16_t)0x5580, 0x04); + Cam_I2C_write(hi2c, (uint16_t)0x558a, 0x00); + //Cam_I2C_write(hi2c, (uint16_t)0x558a, 0x08); + + //Contrast 0 + //Cam_I2C_write(hi2c, (uint16_t)0x5587, 0xff); + //Cam_I2C_write(hi2c, (uint16_t)0x5588, 0xff); + + /* + // Exposure _17 + Cam_I2C_write(hi2c, (uint16_t)0x3a0f, 0x10); + Cam_I2C_write(hi2c, (uint16_t)0x3a10, 0x08); + Cam_I2C_write(hi2c, (uint16_t)0x3a1b, 0x10); + Cam_I2C_write(hi2c, (uint16_t)0x3a1e, 0x08); + Cam_I2C_write(hi2c, (uint16_t)0x3a11, 0x20); + Cam_I2C_write(hi2c, (uint16_t)0x3a1f, 0x10); + + + + //Exposure 17 v2 + Cam_I2C_write(hi2c, (uint16_t)0x3a0f, 0x60); + Cam_I2C_write(hi2c, (uint16_t)0x3a10, 0x58); + Cam_I2C_write(hi2c, (uint16_t)0x3a11, 0xa0); + Cam_I2C_write(hi2c, (uint16_t)0x3a1b, 0x60); + Cam_I2C_write(hi2c, (uint16_t)0x3a1e, 0x58); + Cam_I2C_write(hi2c, (uint16_t)0x3a1f, 0x20); + */ + + // Exposure Manual + Cam_I2C_write(hi2c, (uint16_t)0x3503, 0x3); + Cam_I2C_write(hi2c, (uint16_t)0x350C, 0xFF); + Cam_I2C_write(hi2c, (uint16_t)0x350D, 0xFF); + + Cam_I2C_write(hi2c, (uint16_t)0x3500, 0x0); + Cam_I2C_write(hi2c, (uint16_t)0x3501, 0x00); + Cam_I2C_write(hi2c, (uint16_t)0x3502, 0x0f); + + //Gain MAX + Cam_I2C_write(hi2c, (uint16_t)0x350A, 0x0); + Cam_I2C_write(hi2c, (uint16_t)0x350B, 0x35); + Cam_I2C_write(hi2c, (uint16_t)0x3508, 0x0); + Cam_I2C_write(hi2c, (uint16_t)0x3509, 0x35); + + // AWB + Cam_I2C_write(hi2c, (uint16_t)0x3406, 0x1); + + Cam_I2C_write(hi2c, (uint16_t)0x3400, 0xf); + Cam_I2C_write(hi2c, (uint16_t)0x3401, 0xff); + Cam_I2C_write(hi2c, (uint16_t)0x3402, 0xf); + Cam_I2C_write(hi2c, (uint16_t)0x3403, 0x7f); + Cam_I2C_write(hi2c, (uint16_t)0x3404, 0xf); + Cam_I2C_write(hi2c, (uint16_t)0x3405, 0xff); + Cam_SPI_write(hspi, 0x01, 0x00); // Capture Control Register - Set to capture n+1 frames HAL_Delay(5); @@ -200,12 +310,12 @@ void Cam_Start_Capture(SPI_HandleTypeDef *hspi) Cam_SPI_write(hspi, 0x04, FIFO_Reg_Clear_Flags); // Reset FIFO Read Pointer Cam_SPI_write(hspi, 0x04, FIFO_Reg_Clear_Flags); */ - Cam_SPI_write(hspi, 0x04, 0x01); // Start capture - Cam_SPI_write(hspi, 0x04, 0x01); // Start capture + Cam_SPI_write(hspi, 0x04, 0x01); + Cam_SPI_write(hspi, 0x04, 0x01); - HAL_Delay(1); + HAL_Delay(10); Cam_SPI_write(hspi, 0x04, 0x02); // Start capture - HAL_Delay(1); + HAL_Delay(10); } void Cam_Wait_Capture_Done(SPI_HandleTypeDef *hspi) @@ -229,6 +339,9 @@ void Cam_Start_Burst_Read(SPI_HandleTypeDef *hspi) Cam_SPI_write(hspi, 0x04, FIFO_Reg_Clear_Flags); */ + Cam_SPI_write(hspi, 0x04, 0x01); + Cam_SPI_write(hspi, 0x04, 0x01); + uint8_t BURST_FIFO_READ = 0x3c; uint8_t empty = 0x00; diff --git a/Firmware/Core/Inc/main.h b/Firmware/Core/Inc/main.h index 7cdf4c1..20ed300 100644 --- a/Firmware/Core/Inc/main.h +++ b/Firmware/Core/Inc/main.h @@ -23,12 +23,10 @@ #define __MAIN_H #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif /* Includes ------------------------------------------------------------------*/ -#define USE_HAL_DRIVER #include "stm32l4xx_hal.h" /* Private includes ----------------------------------------------------------*/ @@ -45,25 +43,25 @@ extern "C" // #include "portable/st/synopsys/dcd_synopsys.c" // #include "portable/st/synopsys/synopsys_common.h" - /* USER CODE END Includes */ +/* USER CODE END Includes */ - /* Exported types ------------------------------------------------------------*/ - /* USER CODE BEGIN ET */ +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ - /* USER CODE END ET */ +/* USER CODE END ET */ - /* Exported constants --------------------------------------------------------*/ - /* USER CODE BEGIN EC */ +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ - /* USER CODE END EC */ +/* USER CODE END EC */ - /* Exported macro ------------------------------------------------------------*/ - /* USER CODE BEGIN EM */ +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ - /* USER CODE END EM */ +/* USER CODE END EM */ - /* Exported functions prototypes ---------------------------------------------*/ - void Error_Handler(void); +/* Exported functions prototypes ---------------------------------------------*/ +void Error_Handler(void); /* USER CODE BEGIN EFP */ @@ -87,9 +85,11 @@ extern "C" #define LD3_Pin GPIO_PIN_3 #define LD3_GPIO_Port GPIOB - /* USER CODE BEGIN Private defines */ - - /* USER CODE END Private defines */ +/* USER CODE BEGIN Private defines */ +#define CDC_BUFF_SIZE 10048 +#define CDC_FRAME_SIZE 64 +#define CDC_FRAME_DELAY 1 +/* USER CODE END Private defines */ #ifdef __cplusplus } diff --git a/Firmware/Core/Inc/stm32l4xx_it.h b/Firmware/Core/Inc/stm32l4xx_it.h index e92c4ea..f9f33dc 100644 --- a/Firmware/Core/Inc/stm32l4xx_it.h +++ b/Firmware/Core/Inc/stm32l4xx_it.h @@ -57,6 +57,7 @@ void PendSV_Handler(void); void SysTick_Handler(void); void DMA1_Channel2_IRQHandler(void); void DMA1_Channel3_IRQHandler(void); +void SPI1_IRQHandler(void); void USART2_IRQHandler(void); void USB_IRQHandler(void); /* USER CODE BEGIN EFP */ diff --git a/Firmware/Core/Src/main.c b/Firmware/Core/Src/main.c index e9d071c..f4ba136 100644 --- a/Firmware/Core/Src/main.c +++ b/Firmware/Core/Src/main.c @@ -18,7 +18,7 @@ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" -#include "images.h" + /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "tusb.h" @@ -47,8 +47,6 @@ DMA_HandleTypeDef hdma_spi1_tx; UART_HandleTypeDef huart2; - - PCD_HandleTypeDef hpcd_USB_FS; /* USER CODE BEGIN PV */ @@ -62,7 +60,6 @@ int SPI_Rx_Done_Flag = 0; /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); - static void MX_DMA_Init(void); static void MX_USART2_UART_Init(void); static void MX_SPI1_Init(void); @@ -221,13 +218,25 @@ int send_CDC_Bulk(){ return 1; } */ +void SysTick_Init(void) +{ + SysTick_Config(SystemCoreClock / 10000); // Set SysTick interrupt to occur every 100us +} + +void delay_us(uint32_t us) +{ + uint32_t start = SysTick->VAL; + uint32_t ticks = us * 10; + + while ((start - SysTick->VAL) < ticks); +} /* USER CODE END 0 */ /** - * @brief The application entry point. - * @retval int - */ + * @brief The application entry point. + * @retval int + */ int main(void) { /* USER CODE BEGIN 1 */ @@ -271,13 +280,15 @@ int main(void) // Wait for power stabilization //HAL_Delay(1000); - #define CDC_BUFF_SIZE 10000 + tud_task(); int last_sent_idx = 0; int buff_stop_idx = 0; uint16_t image_size = 0; uint8_t cdc_buff[CDC_BUFF_SIZE]; + Cam_Init(&hi2c1, &hspi1); + /* USER CODE END 2 */ /* Infinite loop */ @@ -288,6 +299,8 @@ int main(void) if(buff_stop_idx >= (int)image_size){ + LED_Off(); + buff_stop_idx = 0; last_sent_idx = 0; @@ -298,7 +311,7 @@ int main(void) tud_task(); - Cam_Init(&hi2c1, &hspi1); + Cam_Refresh(&hi2c1, &hspi1); tud_task(); @@ -309,6 +322,8 @@ int main(void) image_size = Cam_FIFO_length(&hspi1); Cam_Start_Burst_Read(&hspi1); + LED_On(); + continue; //HAL_SPI_Receive(&hspi1, cdc_buff, CDC_BUFF_SIZE, HAL_MAX_DELAY); @@ -331,16 +346,17 @@ int main(void) int current_sending_idx = 0; do{ tud_task(); - - tud_cdc_write(&cdc_buff[current_sending_idx], 50); + tud_cdc_write(&cdc_buff[current_sending_idx], CDC_FRAME_SIZE); + current_sending_idx = current_sending_idx + CDC_FRAME_SIZE; + last_sent_idx = last_sent_idx + CDC_FRAME_SIZE; tud_cdc_write_flush(); - current_sending_idx = current_sending_idx + 50; - last_sent_idx = last_sent_idx + 50; - HAL_Delay(3); + //Delay between sends + int i = 0; + for(;i<4000;i++); } while(last_sent_idx < buff_stop_idx); - LED_On(); + /* USER CODE END WHILE */ @@ -350,25 +366,25 @@ int main(void) } /** - * @brief System Clock Configuration - * @retval None - */ + * @brief System Clock Configuration + * @retval None + */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Configure the main internal regulator output voltage - */ + */ if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) { Error_Handler(); } /** Initializes the RCC Oscillators according to the specified parameters - * in the RCC_OscInitTypeDef structure. - */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSI; + * in the RCC_OscInitTypeDef structure. + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; @@ -385,8 +401,9 @@ void SystemClock_Config(void) } /** Initializes the CPU, AHB and APB buses clocks - */ - RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; @@ -399,10 +416,10 @@ void SystemClock_Config(void) } /** - * @brief I2C1 Initialization Function - * @param None - * @retval None - */ + * @brief I2C1 Initialization Function + * @param None + * @retval None + */ static void MX_I2C1_Init(void) { @@ -428,14 +445,14 @@ static void MX_I2C1_Init(void) } /** Configure Analogue filter - */ + */ if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK) { Error_Handler(); } /** Configure Digital filter - */ + */ if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK) { Error_Handler(); @@ -443,13 +460,14 @@ static void MX_I2C1_Init(void) /* USER CODE BEGIN I2C1_Init 2 */ /* USER CODE END I2C1_Init 2 */ + } /** - * @brief SPI1 Initialization Function - * @param None - * @retval None - */ + * @brief SPI1 Initialization Function + * @param None + * @retval None + */ static void MX_SPI1_Init(void) { @@ -468,7 +486,7 @@ static void MX_SPI1_Init(void) hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; - hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128; + hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; @@ -482,13 +500,14 @@ static void MX_SPI1_Init(void) /* USER CODE BEGIN SPI1_Init 2 */ /* USER CODE END SPI1_Init 2 */ + } /** - * @brief USART2 Initialization Function - * @param None - * @retval None - */ + * @brief USART2 Initialization Function + * @param None + * @retval None + */ static void MX_USART2_UART_Init(void) { @@ -516,13 +535,14 @@ static void MX_USART2_UART_Init(void) /* USER CODE BEGIN USART2_Init 2 */ /* USER CODE END USART2_Init 2 */ + } /** - * @brief USB Initialization Function - * @param None - * @retval None - */ + * @brief USB Initialization Function + * @param None + * @retval None + */ static void MX_USB_PCD_Init(void) { @@ -548,11 +568,12 @@ static void MX_USB_PCD_Init(void) /* USER CODE BEGIN USB_Init 2 */ /* USER CODE END USB_Init 2 */ + } /** - * Enable DMA controller clock - */ + * Enable DMA controller clock + */ static void MX_DMA_Init(void) { @@ -566,13 +587,14 @@ static void MX_DMA_Init(void) /* DMA1_Channel3_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn); + } /** - * @brief GPIO Initialization Function - * @param None - * @retval None - */ + * @brief GPIO Initialization Function + * @param None + * @retval None + */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; @@ -586,7 +608,7 @@ static void MX_GPIO_Init(void) HAL_GPIO_WritePin(DEBUG_LED_GPIO_Port, DEBUG_LED_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(GPIOB, CHIP_SELECT_Pin | LD3_Pin, GPIO_PIN_RESET); + HAL_GPIO_WritePin(GPIOB, CHIP_SELECT_Pin|LD3_Pin, GPIO_PIN_RESET); /*Configure GPIO pin : DEBUG_LED_Pin */ GPIO_InitStruct.Pin = DEBUG_LED_Pin; @@ -596,11 +618,12 @@ static void MX_GPIO_Init(void) HAL_GPIO_Init(DEBUG_LED_GPIO_Port, &GPIO_InitStruct); /*Configure GPIO pins : CHIP_SELECT_Pin LD3_Pin */ - GPIO_InitStruct.Pin = CHIP_SELECT_Pin | LD3_Pin; + GPIO_InitStruct.Pin = CHIP_SELECT_Pin|LD3_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + } /* USER CODE BEGIN 4 */ @@ -617,9 +640,9 @@ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) /* USER CODE END 4 */ /** - * @brief This function is executed in case of error occurrence. - * @retval None - */ + * @brief This function is executed in case of error occurrence. + * @retval None + */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ @@ -631,14 +654,14 @@ void Error_Handler(void) /* USER CODE END Error_Handler_Debug */ } -#ifdef USE_FULL_ASSERT +#ifdef USE_FULL_ASSERT /** - * @brief Reports the name of the source file and the source line number - * where the assert_param error has occurred. - * @param file: pointer to the source file name - * @param line: assert_param error line source number - * @retval None - */ + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ diff --git a/Firmware/Core/Src/stm32l4xx_hal_msp.c b/Firmware/Core/Src/stm32l4xx_hal_msp.c index d522d80..3decb60 100644 --- a/Firmware/Core/Src/stm32l4xx_hal_msp.c +++ b/Firmware/Core/Src/stm32l4xx_hal_msp.c @@ -221,6 +221,9 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) __HAL_LINKDMA(hspi,hdmatx,hdma_spi1_tx); + /* SPI1 interrupt Init */ + HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(SPI1_IRQn); /* USER CODE BEGIN SPI1_MspInit 1 */ /* USER CODE END SPI1_MspInit 1 */ @@ -254,6 +257,9 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) /* SPI1 DMA DeInit */ HAL_DMA_DeInit(hspi->hdmarx); HAL_DMA_DeInit(hspi->hdmatx); + + /* SPI1 interrupt DeInit */ + HAL_NVIC_DisableIRQ(SPI1_IRQn); /* USER CODE BEGIN SPI1_MspDeInit 1 */ /* USER CODE END SPI1_MspDeInit 1 */ diff --git a/Firmware/Core/Src/stm32l4xx_it.c b/Firmware/Core/Src/stm32l4xx_it.c index 4cd6411..811991e 100644 --- a/Firmware/Core/Src/stm32l4xx_it.c +++ b/Firmware/Core/Src/stm32l4xx_it.c @@ -57,6 +57,7 @@ /* External variables --------------------------------------------------------*/ extern DMA_HandleTypeDef hdma_spi1_rx; extern DMA_HandleTypeDef hdma_spi1_tx; +extern SPI_HandleTypeDef hspi1; extern UART_HandleTypeDef huart2; extern PCD_HandleTypeDef hpcd_USB_FS; /* USER CODE BEGIN EV */ @@ -67,8 +68,8 @@ extern PCD_HandleTypeDef hpcd_USB_FS; /* Cortex-M4 Processor Interruption and Exception Handlers */ /******************************************************************************/ /** - * @brief This function handles Non maskable interrupt. - */ + * @brief This function handles Non maskable interrupt. + */ void NMI_Handler(void) { /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ @@ -82,8 +83,8 @@ void NMI_Handler(void) } /** - * @brief This function handles Hard fault interrupt. - */ + * @brief This function handles Hard fault interrupt. + */ void HardFault_Handler(void) { /* USER CODE BEGIN HardFault_IRQn 0 */ @@ -97,8 +98,8 @@ void HardFault_Handler(void) } /** - * @brief This function handles Memory management fault. - */ + * @brief This function handles Memory management fault. + */ void MemManage_Handler(void) { /* USER CODE BEGIN MemoryManagement_IRQn 0 */ @@ -112,8 +113,8 @@ void MemManage_Handler(void) } /** - * @brief This function handles Prefetch fault, memory access fault. - */ + * @brief This function handles Prefetch fault, memory access fault. + */ void BusFault_Handler(void) { /* USER CODE BEGIN BusFault_IRQn 0 */ @@ -127,8 +128,8 @@ void BusFault_Handler(void) } /** - * @brief This function handles Undefined instruction or illegal state. - */ + * @brief This function handles Undefined instruction or illegal state. + */ void UsageFault_Handler(void) { /* USER CODE BEGIN UsageFault_IRQn 0 */ @@ -142,8 +143,8 @@ void UsageFault_Handler(void) } /** - * @brief This function handles System service call via SWI instruction. - */ + * @brief This function handles System service call via SWI instruction. + */ void SVC_Handler(void) { /* USER CODE BEGIN SVCall_IRQn 0 */ @@ -155,8 +156,8 @@ void SVC_Handler(void) } /** - * @brief This function handles Debug monitor. - */ + * @brief This function handles Debug monitor. + */ void DebugMon_Handler(void) { /* USER CODE BEGIN DebugMonitor_IRQn 0 */ @@ -168,8 +169,8 @@ void DebugMon_Handler(void) } /** - * @brief This function handles Pendable request for system service. - */ + * @brief This function handles Pendable request for system service. + */ void PendSV_Handler(void) { /* USER CODE BEGIN PendSV_IRQn 0 */ @@ -181,8 +182,8 @@ void PendSV_Handler(void) } /** - * @brief This function handles System tick timer. - */ + * @brief This function handles System tick timer. + */ void SysTick_Handler(void) { /* USER CODE BEGIN SysTick_IRQn 0 */ @@ -202,8 +203,8 @@ void SysTick_Handler(void) /******************************************************************************/ /** - * @brief This function handles DMA1 channel2 global interrupt. - */ + * @brief This function handles DMA1 channel2 global interrupt. + */ void DMA1_Channel2_IRQHandler(void) { /* USER CODE BEGIN DMA1_Channel2_IRQn 0 */ @@ -216,8 +217,8 @@ void DMA1_Channel2_IRQHandler(void) } /** - * @brief This function handles DMA1 channel3 global interrupt. - */ + * @brief This function handles DMA1 channel3 global interrupt. + */ void DMA1_Channel3_IRQHandler(void) { /* USER CODE BEGIN DMA1_Channel3_IRQn 0 */ @@ -230,8 +231,22 @@ void DMA1_Channel3_IRQHandler(void) } /** - * @brief This function handles USART2 global interrupt. - */ + * @brief This function handles SPI1 global interrupt. + */ +void SPI1_IRQHandler(void) +{ + /* USER CODE BEGIN SPI1_IRQn 0 */ + + /* USER CODE END SPI1_IRQn 0 */ + HAL_SPI_IRQHandler(&hspi1); + /* USER CODE BEGIN SPI1_IRQn 1 */ + + /* USER CODE END SPI1_IRQn 1 */ +} + +/** + * @brief This function handles USART2 global interrupt. + */ void USART2_IRQHandler(void) { /* USER CODE BEGIN USART2_IRQn 0 */ @@ -244,8 +259,8 @@ void USART2_IRQHandler(void) } /** - * @brief This function handles USB event interrupt through EXTI line 17. - */ + * @brief This function handles USB event interrupt through EXTI line 17. + */ void USB_IRQHandler(void) { /* USER CODE BEGIN USB_IRQn 0 */ diff --git a/Firmware/Makefile b/Firmware/Makefile index e454dcb..55cfd22 100644 --- a/Firmware/Makefile +++ b/Firmware/Makefile @@ -1,139 +1,139 @@ -SHELL=/bin/bash - -.PHONY: all build build-container cmake format format-linux flash-stlink flash-jlink format-container shell image build-container clean clean-image clean-all -############################### Native Makefile ############################### - -PROJECT_NAME ?= Probe -BUILD_DIR ?= build -FIRMWARE := $(BUILD_DIR)/$(PROJECT_NAME).bin -BUILD_TYPE ?= Debug -PLATFORM = $(if $(OS),$(OS),$(shell uname -s)) - -ifeq ($(PLATFORM),Windows_NT) - BUILD_SYSTEM ?= MinGW Makefiles -else - ifeq ($(PLATFORM),Linux) - BUILD_SYSTEM ?= Unix Makefiles - else - @echo "Unsuported platform" - exit 1 - endif -endif - -all: build - -build: cmake - $(MAKE) -C $(BUILD_DIR) --no-print-directory - -cmake: $(BUILD_DIR)/Makefile - -$(BUILD_DIR)/Makefile: CMakeLists.txt - cmake \ - -G "$(BUILD_SYSTEM)" \ - -B$(BUILD_DIR) \ - -DPROJECT_NAME=$(PROJECT_NAME) \ - -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) \ - -DDUMP_ASM=OFF - -# Formats all user modified source files (add ones that are missing) -# SRCS := $(shell find Project -name '*.[ch]' -or -name '*.[ch]pp') Core/Src/main.c -SRCS := $(shell find Core -name '*.[ch]' -or -name '*.[ch]pp') Core/Src/main.c -format: $(addsuffix .format,$(SRCS)) -%.format: % - clang-format -i $< - -# Formats all CubeMX generated sources to unix style - removes \r from line endings -# Add any new directories, like Middlewares and hidden files -HIDDEN_FILES := .mxproject .project .cproject -FOUND_HIDDEN_FILES := $(shell for f in $(HIDDEN_FILES);do if [[ -e $$f ]]; then echo $$f;fi; done) -FORMAT_LINUX := $(shell find Core Drivers -name '*' -type f; find . -name '*.ioc') $(FOUND_HIDDEN_FILES) - -format-linux: $(addsuffix .format-linux,$(FORMAT_LINUX)) -%.format-linux: % - $(if $(filter $(PLATFORM),Linux),dos2unix -q $<,) - -# Device specific! -DEVICE ?= STM32F407VG - -flash-st: build - st-flash --reset write $(FIRMWARE) 0x08000000 - -$(BUILD_DIR)/jlink-script: - touch $@ - @echo device $(DEVICE) > $@ - @echo si 1 >> $@ - @echo speed 4000 >> $@ - @echo loadfile $(FIRMWARE),0x08000000 >> $@ - @echo -e "r\ng\nqc" >> $@ - -flash-jlink: build | $(BUILD_DIR)/jlink-script - JLinkExe -commanderScript $(BUILD_DIR)/jlink-script - -clean: - rm -rf $(BUILD_DIR) - -################################## Container ################################## - -UID ?= $(shell id -u) -GID ?= $(shell id -g) -USER ?= $(shell id -un) -GROUP ?= $(if $(filter $(PLATFORM), Windows_NT),$(shell id -un),$(shell id -gn)) - -ifeq ($(PLATFORM),Windows_NT) - WIN_PREFIX = winpty - WORKDIR_PATH = "//workdir" - WORKDIR_VOLUME = "/$$(pwd -W):/workdir" -else - WORKDIR_PATH = /workdir - WORKDIR_VOLUME = "$$(pwd):/workdir" -endif - -CONTAINER_TOOL ?= docker -CONTAINER_FILE := Dockerfile -IMAGE_NAME := fedora-arm-embedded-dev -CONTAINER_NAME := fedora-arm-embedded-dev - -NEED_IMAGE = $(shell $(CONTAINER_TOOL) image inspect $(IMAGE_NAME) 2> /dev/null > /dev/null || echo image) -# usefull if you have a always running container in the background: NEED_CONTAINER = $(shell $(CONTAINER_TOOL) container inspect $(CONTAINER_NAME) 2> /dev/null > /dev/null || echo container) -PODMAN_ARG = $(if $(filter $(CONTAINER_TOOL), podman),--userns=keep-id,) -CONTAINER_RUN = $(WIN_PREFIX) $(CONTAINER_TOOL) run \ - --name $(CONTAINER_NAME) \ - --rm \ - -it \ - $(PODMAN_ARG) \ - -v $(WORKDIR_VOLUME) \ - -w $(WORKDIR_PATH) \ - --security-opt label=disable \ - --hostname $(CONTAINER_NAME) \ - $(IMAGE_NAME) - -build-container: $(NEED_IMAGE) - $(CONTAINER_RUN) bash -lc 'make -j$(shell nproc)' - -format-container: - $(CONTAINER_RUN) bash -lc 'make format -j$(shell nproc)' - -format-linux-container: - $(CONTAINER_RUN) bash -lc 'make format-linux' - -shell: - $(CONTAINER_RUN) bash -l - -image: $(CONTAINER_FILE) - $(CONTAINER_TOOL) build \ - -t $(IMAGE_NAME) \ - -f=$(CONTAINER_FILE) \ - --build-arg UID=$(UID) \ - --build-arg GID=$(GID) \ - --build-arg USERNAME=$(USER) \ - --build-arg GROUPNAME=$(GROUP) \ - . - -clean-image: - $(CONTAINER_TOOL) container rm -f $(CONTAINER_NAME) 2> /dev/null > /dev/null || true - $(CONTAINER_TOOL) image rmi -f $(IMAGE_NAME) 2> /dev/null > /dev/null || true - -clean-all: clean clean-image - -flash: - openocd -f interface/stlink.cfg -f target/stm32l4x.cfg -c "program build/Probe.bin verify reset exit 0x08000000" +SHELL=/bin/bash + +.PHONY: all build build-container cmake format format-linux flash-stlink flash-jlink format-container shell image build-container clean clean-image clean-all +############################### Native Makefile ############################### + +PROJECT_NAME ?= Probe +BUILD_DIR ?= build +FIRMWARE := $(BUILD_DIR)/$(PROJECT_NAME).bin +BUILD_TYPE ?= Debug +PLATFORM = $(if $(OS),$(OS),$(shell uname -s)) + +ifeq ($(PLATFORM),Windows_NT) + BUILD_SYSTEM ?= MinGW Makefiles +else + ifeq ($(PLATFORM),Linux) + BUILD_SYSTEM ?= Unix Makefiles + else + @echo "Unsuported platform" + exit 1 + endif +endif + +all: build + +build: cmake + $(MAKE) -C $(BUILD_DIR) --no-print-directory + +cmake: $(BUILD_DIR)/Makefile + +$(BUILD_DIR)/Makefile: CMakeLists.txt + cmake \ + -G "$(BUILD_SYSTEM)" \ + -B$(BUILD_DIR) \ + -DPROJECT_NAME=$(PROJECT_NAME) \ + -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) \ + -DDUMP_ASM=OFF + +# Formats all user modified source files (add ones that are missing) +# SRCS := $(shell find Project -name '*.[ch]' -or -name '*.[ch]pp') Core/Src/main.c +SRCS := $(shell find Core -name '*.[ch]' -or -name '*.[ch]pp') Core/Src/main.c +format: $(addsuffix .format,$(SRCS)) +%.format: % + clang-format -i $< + +# Formats all CubeMX generated sources to unix style - removes \r from line endings +# Add any new directories, like Middlewares and hidden files +HIDDEN_FILES := .mxproject .project .cproject +FOUND_HIDDEN_FILES := $(shell for f in $(HIDDEN_FILES);do if [[ -e $$f ]]; then echo $$f;fi; done) +FORMAT_LINUX := $(shell find Core Drivers -name '*' -type f; find . -name '*.ioc') $(FOUND_HIDDEN_FILES) + +format-linux: $(addsuffix .format-linux,$(FORMAT_LINUX)) +%.format-linux: % + $(if $(filter $(PLATFORM),Linux),dos2unix -q $<,) + +# Device specific! +DEVICE ?= STM32F407VG + +flash-st: build + st-flash --reset write $(FIRMWARE) 0x08000000 + +$(BUILD_DIR)/jlink-script: + touch $@ + @echo device $(DEVICE) > $@ + @echo si 1 >> $@ + @echo speed 4000 >> $@ + @echo loadfile $(FIRMWARE),0x08000000 >> $@ + @echo -e "r\ng\nqc" >> $@ + +flash-jlink: build | $(BUILD_DIR)/jlink-script + JLinkExe -commanderScript $(BUILD_DIR)/jlink-script + +clean: + rm -rf $(BUILD_DIR) + +################################## Container ################################## + +UID ?= $(shell id -u) +GID ?= $(shell id -g) +USER ?= $(shell id -un) +GROUP ?= $(if $(filter $(PLATFORM), Windows_NT),$(shell id -un),$(shell id -gn)) + +ifeq ($(PLATFORM),Windows_NT) + WIN_PREFIX = winpty + WORKDIR_PATH = "//workdir" + WORKDIR_VOLUME = "/$$(pwd -W):/workdir" +else + WORKDIR_PATH = /workdir + WORKDIR_VOLUME = "$$(pwd):/workdir" +endif + +CONTAINER_TOOL ?= docker +CONTAINER_FILE := Dockerfile +IMAGE_NAME := fedora-arm-embedded-dev +CONTAINER_NAME := fedora-arm-embedded-dev + +NEED_IMAGE = $(shell $(CONTAINER_TOOL) image inspect $(IMAGE_NAME) 2> /dev/null > /dev/null || echo image) +# usefull if you have a always running container in the background: NEED_CONTAINER = $(shell $(CONTAINER_TOOL) container inspect $(CONTAINER_NAME) 2> /dev/null > /dev/null || echo container) +PODMAN_ARG = $(if $(filter $(CONTAINER_TOOL), podman),--userns=keep-id,) +CONTAINER_RUN = $(WIN_PREFIX) $(CONTAINER_TOOL) run \ + --name $(CONTAINER_NAME) \ + --rm \ + -it \ + $(PODMAN_ARG) \ + -v $(WORKDIR_VOLUME) \ + -w $(WORKDIR_PATH) \ + --security-opt label=disable \ + --hostname $(CONTAINER_NAME) \ + $(IMAGE_NAME) + +build-container: $(NEED_IMAGE) + $(CONTAINER_RUN) bash -lc 'make -j$(shell nproc)' + +format-container: + $(CONTAINER_RUN) bash -lc 'make format -j$(shell nproc)' + +format-linux-container: + $(CONTAINER_RUN) bash -lc 'make format-linux' + +shell: + $(CONTAINER_RUN) bash -l + +image: $(CONTAINER_FILE) + $(CONTAINER_TOOL) build \ + -t $(IMAGE_NAME) \ + -f=$(CONTAINER_FILE) \ + --build-arg UID=$(UID) \ + --build-arg GID=$(GID) \ + --build-arg USERNAME=$(USER) \ + --build-arg GROUPNAME=$(GROUP) \ + . + +clean-image: + $(CONTAINER_TOOL) container rm -f $(CONTAINER_NAME) 2> /dev/null > /dev/null || true + $(CONTAINER_TOOL) image rmi -f $(IMAGE_NAME) 2> /dev/null > /dev/null || true + +clean-all: clean clean-image + +flash: + openocd -f interface/stlink.cfg -f target/stm32l4x.cfg -c "program build/Probe.bin verify reset exit 0x08000000" diff --git a/Firmware/Probe.ioc b/Firmware/Probe.ioc index a404136..2a3c9ef 100644 --- a/Firmware/Probe.ioc +++ b/Firmware/Probe.ioc @@ -74,6 +74,7 @@ NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 +NVIC.SPI1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.SysTick_IRQn=true\:0\:0\:true\:false\:true\:true\:true\:false NVIC.USART2_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true @@ -160,6 +161,7 @@ ProjectManager.PreviousToolchain= ProjectManager.ProjectBuild=false ProjectManager.ProjectFileName=Probe.ioc ProjectManager.ProjectName=Probe +ProjectManager.ProjectStructure= ProjectManager.RegisterCallBack= ProjectManager.StackSize=0x400 ProjectManager.TargetToolchain=Makefile @@ -225,8 +227,8 @@ RCC.VCOInputFreq_Value=16000000 RCC.VCOOutputFreq_Value=160000000 RCC.VCOSAI1OutputFreq_Value=128000000 RCC.WatchDogFreq_Value=32000 -SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_128 -SPI1.CalculateBaudRate=625.0 KBits/s +SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_32 +SPI1.CalculateBaudRate=2.5 MBits/s SPI1.DataSize=SPI_DATASIZE_8BIT SPI1.Direction=SPI_DIRECTION_2LINES SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,BaudRatePrescaler,NSSPMode diff --git a/Receiver/Makefile b/Receiver/Makefile index d2e6738..4daf9d6 100644 --- a/Receiver/Makefile +++ b/Receiver/Makefile @@ -1,5 +1,5 @@ CC = g++ -CFLAGS = -pthread -std=c++11 -Wall -Wextra -pedantic +CFLAGS = -pthread -std=c++11 -Wall -Wextra -pedantic -O3 LDLIBS = -lSDL2 -lSDL2_image SRCS = $(wildcard *.cpp) diff --git a/Receiver/Receiver.cpp b/Receiver/Receiver.cpp index e03a1ee..4ac8770 100644 --- a/Receiver/Receiver.cpp +++ b/Receiver/Receiver.cpp @@ -64,7 +64,6 @@ int Receiver::readCdcData(uint8_t (*character)[CDC_FRAME_SIZE]) { std::cerr << "Error in read" << std::endl; return -1; } - #if 0 // PRINT WHAT IS RECEIVED for(int i = 0; i tempVec{}; - Receiver::readCdcData(&character); - int i = -1; do { Receiver::readCdcData(&character); @@ -186,15 +182,17 @@ void Receiver::bufferToDisplay(){ currentBufferIndexMutex.lock(); int buffIdx = currentBufferIndex; currentBufferIndexMutex.unlock(); - std::cout << buffIdx << std::endl; switch(buffIdx){ case 0: + std::cout << buffer1.size() << std::endl; dis->vectorToTexture(&buffer1); break; case 1: + std::cout << buffer2.size() << std::endl; dis->vectorToTexture(&buffer2); break; case 2: + std::cout << buffer3.size() << std::endl; dis->vectorToTexture(&buffer3); break; default: diff --git a/Receiver/main.cpp b/Receiver/main.cpp index f8d93d9..56c0138 100644 --- a/Receiver/main.cpp +++ b/Receiver/main.cpp @@ -32,11 +32,18 @@ void windowFlipThread(Displayer * displayerPtr){ displayerPtr->flipThroughTextures(); } +void WrapperBufferToDisplay(Receiver ** receiverPtr){ + (*receiverPtr)->bufferToDisplay(); +} + void receiverLoop(Receiver ** receiverPtr){ + std::vector displayThreads; while(1){ + (*receiverPtr)->fillBuffer(); - (*receiverPtr)->bufferToDisplay(); - std::this_thread::sleep_for(std::chrono::milliseconds(3)); + + std::thread t2(WrapperBufferToDisplay, receiverPtr); + t2.detach(); } } diff --git a/Receiver/main.hpp b/Receiver/main.hpp index 05aae11..07cd3b5 100644 --- a/Receiver/main.hpp +++ b/Receiver/main.hpp @@ -15,4 +15,5 @@ #include #include -#define CDC_FRAME_SIZE 50 \ No newline at end of file +#define CDC_FRAME_SIZE 64 +#define CDC_FRAME_DELAY 1