-#include <iostream>
-#define LENGTH 21
-
-
-void print(int (*image)[LENGTH][LENGTH]);
-
-int main() {
- int QR[LENGTH][LENGTH];
-
- for (int i{0}; i < LENGTH; ++i) {
- for (int j{0}; j < LENGTH; ++j) {
- QR[i][j] = 0;
- }
- }
-
- print(&QR);
-
-
- return 0;
-}
-
-
-void print(int (*image)[LENGTH][LENGTH]){
- for (int i{0}; i < LENGTH; ++i) {
- for (int j{0}; j < LENGTH; ++j) {
- std::cout << (*image)[i][j];
- }
- std::cout << std::endl;
- }
-}
+#include "main.h"\r
+#include <vector>\r
+#include "stm32f4xx_hal.h"\r
+#include <iostream>\r
+// I2C and DMA Handles\r
+I2C_HandleTypeDef hi2c1;\r
+DMA_HandleTypeDef hdma_i2c1_tx;\r
+DMA_HandleTypeDef hdma_i2c1_rx;\r
+DMA_HandleTypeDef hdma;\r
+const int WIDTH{50};\r
+const int HEIGHT{50};\r
+\r
+// Image Data Buffer\r
+uint8_t imageData[WIDTH * HEIGHT * 2]; // Adjust the size as needed (YUV422: 2 bytes per pixel)\r
+std::vector<std::vector<uint8_t>> grayscaleImage(HEIGHT, std::vector<uint8_t>(WIDTH)); // 2D vector to store Y values\r
+\r
+// Function Prototypes\r
+void SystemClock_Config(void);\r
+void GPIO_Init(void);\r
+void I2C_Init(void);\r
+void DMA_Init(void);\r
+void captureImage(void);\r
+void processImage(void);\r
+void Error_Handler(void){\r
+ while(1){\r
+ std::cout<<"error has occurred";\r
+ }\r
+};\r
+\r
+\r
+\r
+int main(void) {\r
+ // Initialize the HAL Library\r
+ HAL_Init();\r
+\r
+ // Configure the system clock\r
+ SystemClock_Config();\r
+\r
+ // Initialize GPIO, I2C, and DMA\r
+ GPIO_Init();\r
+ I2C_Init();\r
+ DMA_Init();\r
+\r
+ // Reset the camera module\r
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); // Assert reset\r
+ HAL_Delay(100);\r
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET); // Deassert reset\r
+ HAL_Delay(100);\r
+\r
+ // Main loop\r
+ while (1) {\r
+ captureImage();\r
+ processImage();\r
+ }\r
+}\r
+\r
+void SystemClock_Config(void) {\r
+ RCC_OscInitTypeDef RCC_OscInitStruct = {0};\r
+ RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};\r
+\r
+ __HAL_RCC_PWR_CLK_ENABLE();\r
+ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);\r
+\r
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;\r
+ RCC_OscInitStruct.HSIState = RCC_HSI_ON;\r
+ RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;\r
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;\r
+ RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;\r
+ RCC_OscInitStruct.PLL.PLLM = 16;\r
+ RCC_OscInitStruct.PLL.PLLN = 336;\r
+ RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;\r
+ RCC_OscInitStruct.PLL.PLLQ = 4;\r
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {\r
+ Error_Handler();\r
+ }\r
+\r
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK |\r
+ RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;\r
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;\r
+ RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;\r
+ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;\r
+ RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;\r
+ if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) {\r
+ Error_Handler();\r
+ }\r
+}\r
+\r
+void GPIO_Init(void) {\r
+ GPIO_InitTypeDef GPIO_InitStruct = {0};\r
+\r
+ __HAL_RCC_GPIOA_CLK_ENABLE();\r
+ __HAL_RCC_GPIOB_CLK_ENABLE();\r
+\r
+ // Configure HREF (PA0) and VSYNC (PA1) as inputs\r
+ GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;\r
+ GPIO_InitStruct.Mode = GPIO_MODE_INPUT;\r
+ GPIO_InitStruct.Pull = GPIO_NOPULL;\r
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;\r
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);\r
+\r
+ // Configure PWDN (PA2) and RST (PA3) as outputs\r
+ GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;\r
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;\r
+ GPIO_InitStruct.Pull = GPIO_NOPULL;\r
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;\r
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);\r
+\r
+ // Configure DCLK (PA6) as input\r
+ GPIO_InitStruct.Pin = GPIO_PIN_6;\r
+ GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // Adjust as necessary\r
+ GPIO_InitStruct.Pull = GPIO_NOPULL;\r
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;\r
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);\r
+\r
+ // Configure SDA (PB9) and SCL (PB8) for I2C\r
+ GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;\r
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;\r
+ GPIO_InitStruct.Pull = GPIO_PULLUP;\r
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;\r
+ GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;\r
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);\r
+\r
+ // Configure D0-D7 (PB0-PB7) as inputs\r
+ GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 |\r
+ GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;\r
+ GPIO_InitStruct.Mode = GPIO_MODE_INPUT;\r
+ GPIO_InitStruct.Pull = GPIO_NOPULL;\r
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;\r
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);\r
+}\r
+\r
+void I2C_Init(void) {\r
+ hi2c1.Instance = I2C1;\r
+ hi2c1.Init.ClockSpeed = 100000;\r
+ hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;\r
+ hi2c1.Init.OwnAddress1 = 0;\r
+ hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;\r
+ hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;\r
+ hi2c1.Init.OwnAddress2 = 0;\r
+ hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;\r
+ hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;\r
+\r
+ if (HAL_I2C_Init(&hi2c1) != HAL_OK) {\r
+ Error_Handler();\r
+ }\r
+}\r
+\r
+void DMA_Init(void) {\r
+ __HAL_RCC_DMA1_CLK_ENABLE();\r
+\r
+ // Configure DMA for I2C TX\r
+ hdma_i2c1_tx.Instance = DMA1_Stream6;\r
+ hdma_i2c1_tx.Init.Channel = DMA_CHANNEL_1;\r
+ hdma_i2c1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;\r
+ hdma_i2c1_tx.Init.PeriphInc = DMA_PINC_DISABLE;\r
+ hdma_i2c1_tx.Init.MemInc = DMA_MINC_ENABLE;\r
+ hdma_i2c1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;\r
+ hdma_i2c1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;\r
+ hdma_i2c1_tx.Init.Mode = DMA_NORMAL;\r
+ hdma_i2c1_tx.Init.Priority = DMA_PRIORITY_LOW;\r
+ hdma_i2c1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;\r
+\r
+ if (HAL_DMA_Init(&hdma_i2c1_tx) != HAL_OK) {\r
+ Error_Handler();\r
+ }\r
+\r
+ // Link DMA to I2C TX\r
+ __HAL_LINKDMA(&hi2c1, hdmatx, hdma_i2c1_tx);\r
+\r
+ // Configure DMA for I2C RX\r
+ hdma_i2c1_rx.Instance = DMA1_Stream0;\r
+ hdma_i2c1_rx.Init.Channel = DMA_CHANNEL_1;\r
+ hdma_i2c1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;\r
+ hdma_i2c1_rx.Init.PeriphInc = DMA_PINC_DISABLE;\r
+ hdma_i2c1_rx.Init.MemInc = DMA_MINC_ENABLE;\r
+ hdma_i2c1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;\r
+ hdma_i2c1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;\r
+ hdma_i2c1_rx.Init.Mode = DMA_NORMAL;\r
+ hdma_i2c1_rx.Init.Priority = DMA_PRIORITY_HIGH;\r
+ hdma_i2c1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;\r
+\r
+ if (HAL_DMA_Init(&hdma_i2c1_rx) != HAL_OK) {\r
+ Error_Handler();\r
+ }\r
+\r
+ // Link DMA to I2C RX\r
+ __HAL_LINKDMA(&hi2c1, hdmarx, hdma_i2c1_rx);\r
+}\r
+void captureImage(void) {\r
+ // Enable PWDN pin to power up the camera module\r
+ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);\r
+ HAL_Delay(10); // Ensure the camera module is powered up\r
+\r
+ // Wait for VSYNC to go high to start a new frame\r
+ while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET);\r
+\r
+ int row = 0, col = 0;\r
+ // Start capturing image data line by line\r
+ while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_SET) { // While VSYNC is high\r
+ while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET) { // While HREF is high (valid data lines)\r
+ // Read data from D0-D7 on GPIOB\r
+ uint8_t pixelData =\r
+ (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) << 0) |\r
+ (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) << 1) |\r
+ (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) << 2) |\r
+ (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_3) << 3) |\r
+ (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4) << 4) |\r
+ (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5) << 5) |\r
+ (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) << 6) |\r
+ (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) << 7);\r
+\r
+ // Store the pixel data in the image buffer\r
+ imageData[row * WIDTH + col] = pixelData;\r
+\r
+ // Increment the column count\r
+ col++;\r
+ if (col >= WIDTH) {\r
+ col = 0;\r
+ row++;\r
+ }\r
+\r
+ // Ensure row doesn't exceed the image size\r
+ if (row >= HEIGHT) {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+\r
+\r
+\r
+void processImage(void) {\r
+ int index = 0;\r
+\r
+ // Iterate through each row and column of the image buffer\r
+ for (int row = 0; row < HEIGHT; row++) {\r
+ for (int col = 0; col < WIDTH; col++) {\r
+ // Extract the Y (luminance) value from the YUV422 format\r
+ uint8_t Y = imageData[index];\r
+\r
+ // Store the Y value in the grayscaleImage 2D vector\r
+ grayscaleImage[row][col] = Y;\r
+ std::cout<<grayscaleImage[row][col];\r
+ // Move to the next pixel (Y component is every other byte in YUV422)\r
+ index += 2;\r
+ }\r
+ std::cout<<std::endl;\r
+ }\r
+}\r
+\r
+\r