main.cpp
1 /* USER CODE BEGIN Header */ 2 /** 3 ****************************************************************************** 4 * @file : main.c 5 * @brief : Main program body 6 ****************************************************************************** 7 * @attention 8 * 9 * Copyright (c) 2025 STMicroelectronics. 10 * All rights reserved. 11 * 12 * This software is licensed under terms that can be found in the LICENSE file 13 * in the root directory of this software component. 14 * If no LICENSE file comes with this software, it is provided AS-IS. 15 * 16 ****************************************************************************** 17 */ 18 /* USER CODE END Header */ 19 /* Includes ------------------------------------------------------------------*/ 20 #include "main.h" 21 #include "usb_device.h" 22 #include "USBHandler.h" 23 #include "usbd_cdc_if.h" 24 #include "adar1000.h" 25 #include "ADAR1000_Manager.h" 26 extern "C" { 27 #include "ad9523.h" 28 } 29 #include "no_os_delay.h" 30 #include "no_os_alloc.h" 31 #include "no_os_print_log.h" 32 #include "no_os_error.h" 33 #include "no_os_units.h" 34 #include "no_os_dma.h" 35 #include "no_os_spi.h" 36 #include "no_os_uart.h" 37 #include "no_os_util.h" 38 #include <stdint.h> 39 #include <errno.h> 40 #include <math.h> 41 #include <stdio.h> 42 #include <string.h> 43 #include <inttypes.h> 44 #include <iostream> 45 #include <vector> 46 #include "stm32_spi.h" 47 #include "stm32_delay.h" 48 #include "TinyGPSPlus.h" 49 extern "C" { 50 #include "GY_85_HAL.h" 51 } 52 #include "BMP180.h" 53 extern "C" { 54 #include "platform_noos_stm32.h" 55 } 56 extern "C" { 57 58 #include "adf4382a_manager.h" 59 #include "adf4382.h" 60 #include "no_os_delay.h" 61 #include "no_os_error.h" 62 #include "diag_log.h" 63 } 64 #include <cmath> 65 #include "DAC5578.h" 66 #include "ADS7830.h" 67 #include "gps_handler.h" 68 69 #include "stm32f7xx_hal.h" 70 71 72 73 74 /* Private includes ----------------------------------------------------------*/ 75 /* USER CODE BEGIN Includes */ 76 77 /* USER CODE END Includes */ 78 79 /* Private typedef -----------------------------------------------------------*/ 80 /* USER CODE BEGIN PTD */ 81 82 83 /* USER CODE END PTD */ 84 85 /* Private define ------------------------------------------------------------*/ 86 /* USER CODE BEGIN PD */ 87 88 89 /* -------- GPIO index mapping for no-OS interface -------- */ 90 #define GPIO_IDX_TX_CS 0 91 #define GPIO_IDX_RX_CS 1 92 #define GPIO_IDX_TX_DELSTR 2 93 #define GPIO_IDX_TX_DELADJ 3 94 #define GPIO_IDX_RX_DELSTR 4 95 #define GPIO_IDX_RX_DELADJ 5 96 #define GPIO_IDX_TX_CE 6 97 #define GPIO_IDX_RX_CE 7 98 #define GPIO_IDX_SW_SYNC 8 99 100 /* USER CODE END PD */ 101 102 /* Private macro -------------------------------------------------------------*/ 103 /* USER CODE BEGIN PM */ 104 105 /* USER CODE END PM */ 106 107 /* Private variables ---------------------------------------------------------*/ 108 109 I2C_HandleTypeDef hi2c1; 110 I2C_HandleTypeDef hi2c2; 111 I2C_HandleTypeDef hi2c3; 112 113 SPI_HandleTypeDef hspi1; 114 SPI_HandleTypeDef hspi4; 115 116 TIM_HandleTypeDef htim1; 117 TIM_HandleTypeDef htim3; // B15 fix: DELADJ PWM timer (CH2=TX, CH3=RX) 118 119 UART_HandleTypeDef huart5; 120 UART_HandleTypeDef huart3; 121 122 /* USER CODE BEGIN PV */ 123 // The TinyGPSPlus object 124 TinyGPSPlus gps; 125 126 // Global data structures 127 GPS_Data_t current_gps_data = {0}; 128 129 // Global USB handler 130 USBHandler usbHandler; 131 extern USBD_HandleTypeDef hUsbDeviceFS; 132 133 // Buffer for USB reception 134 uint8_t usb_rx_buffer[64]; 135 136 //IMU variable 137 GY85_t imu; 138 139 float Pitch_Sensor, Yaw_Sensor, Roll_Sensor; 140 141 float abias[3] = {-0.108, -0.038, -0.006}, gbias[3] = {-10, 6, -12}, mbias[3]={0.0,0.0,0.0}; 142 float M11=1.0, M12=-0.0, M13=0.0, 143 M21=0.0, M22=1.0, M23=0.0, 144 M31=0.0, M32=-0.0, M33=1.0; 145 float ax, ay, az, gx, gy, gz, mx, my, mz,mxc,myc,mzc; // variables to hold latest sensor data values 146 float q[4] = {1.0f, 0.0f, 0.0f, 0.0f}; // vector to hold quaternion 147 float temperature; 148 float Mag_Declination = -0.61; //0° 149 150 float RxAcc,RyAcc,RzAcc; 151 float Rate_Ayz_1,Rate_Axz_1,Rate_Axy_1; 152 float Axz_1,Ayz_1,Axy_1, Axz_0,Ayz_0,Axy_0; 153 float RxEst_0,RyEst_0,RzEst_0, RxEst_1,RyEst_1,RzEst_1,Azr_Est; 154 float RxGyro,RyGyro,RzGyro, R_Est; 155 156 unsigned long now_timeperiod; 157 unsigned long lasttime_timeperiod = 0; 158 int Time_Period = 0; 159 160 //Barometer BMP180 161 162 /*resolution: 163 BMP180_ULTRALOWPOWER - pressure oversampled 1 time & power consumption 3μA 164 BMP180_STANDARD - pressure oversampled 2 times & power consumption 5μA 165 BMP180_HIGHRES - pressure oversampled 4 times & power consumption 7μA 166 BMP180_ULTRAHIGHRES - pressure oversampled 8 times & power consumption 12μA, library default 167 */ 168 BMP180 myBMP(BMP180_ULTRAHIGHRES); 169 float RADAR_Altitude; 170 171 //GPS 172 double RADAR_Longitude = 0; 173 double RADAR_Latitude = 0; 174 175 extern uint8_t GUI_start_flag_received; 176 177 178 //RADAR 179 // Radar parameters 180 const int m_max = 32; // Number of chirps per beam position 181 const int n_max = 31; // Number of beam positions 182 const float T1 = 30.0f; // Chirp duration in microseconds 183 const float PRI1 = 167.0f; // Pulse repetition interval in microseconds 184 const float T2 = 0.5f; // Short chirp duration in microseconds 185 const float PRI2 = 175.0f; // Short PRI in microseconds 186 const float Guard = 175.4f; // Guard time in microseconds 187 188 uint8_t m = 1; // m = N° of chirp/ position = 16 (made of T1 and PRF1)+ Guard = 175µs +16 (made of T2 and PRF2) 189 uint8_t n = 1; // n =[1-31] N° of elevations/azimuth 190 uint8_t y = 1;// y = N° of azimuths/revolution = 50 controlled by a microcontroller connected to a stepper motor 191 uint8_t y_max = 50;// y = N° of azimuths/revolution 192 uint64_t IF_freq = 120000000ULL;//120MHz 193 194 #define PowerAmplifier 1 195 196 //Stepper Motor 197 float Stepper_steps = 200.0f;//step per revolution 198 199 // DAC5578 handles (RF Power Amplifier DAC controlling Vg) 200 DAC5578_HandleTypeDef hdac1, hdac2; 201 /* Phase accumulators */ 202 float phase_dac1[8] = {0}; 203 float phase_dac2[8] = {0}; 204 const uint32_t sampleRate = 370; // Sample rate in Hz 205 const uint32_t period = 2700; // Period in microseconds 206 uint8_t DAC_val = 126; 207 208 // ADC handles (RF Power Amplifier ADC measuring Idq) 209 ADS7830_HandleTypeDef hadc1, hadc2; 210 uint8_t adc1_readings[8] = {0}; 211 uint8_t adc2_readings[8] = {0}; 212 float Idq_reading[16]={0.0f}; 213 214 /* [GAP-3 FIX 2] Hardware IWDG watchdog handle 215 * Prescaler=256, Reload=500 → timeout ≈ 4.096 s from 32 kHz LSI. 216 * If the main loop stalls, the MCU resets automatically. */ 217 IWDG_HandleTypeDef hiwdg; 218 219 220 // Global manager instance ADF4382A 221 ADF4382A_Manager lo_manager; 222 extern SPI_HandleTypeDef hspi4; 223 224 //ADAR1000 225 226 ADAR1000Manager adarManager; 227 static uint8_t matrix1[15][16]; 228 static uint8_t matrix2[15][16]; 229 static uint8_t vector_0[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 230 231 /* Radar parameters 232 const int m_max = 32; // Number of chirps per beam position 233 const int n_max = 31; // Number of beam positions 234 const float T1 = 30.0f; // Chirp duration in microseconds 235 const float PRI1 = 167.0f; // Pulse repetition interval in microseconds 236 const float T2 = 0.5f; // Short chirp duration in microseconds 237 const float T2 = 175.0f; // Short PRI in microseconds 238 const float Guard = 175.40f; // Guard time in microseconds*/ 239 240 //Temperature Sensors 241 ADS7830_HandleTypeDef hadc3; 242 float Temperature_1 = 0.0f, Temperature_2 = 0.0f, Temperature_3 = 0.0f, Temperature_4 = 0.0f; 243 float Temperature_5 = 0.0f, Temperature_6 = 0.0f, Temperature_7 = 0.0f, Temperature_8 = 0.0f; 244 245 // Phase differences for 31 beam positions 246 const float phase_differences[31] = { 247 160.0f, 80.0f, 53.333f, 40.0f, 32.0f, 26.667f, 22.857f, 20.0f, 17.778f, 16.0f, 248 14.545f, 13.333f, 12.308f, 11.429f, 10.667f, 0.0f, 249 -10.667f, -11.429f, -12.308f, -13.333f, -14.545f, -16.0f, -17.778f, -20.0f, 250 -22.857f, -26.667f, -32.0f, -40.0f, -53.333f, -80.0f, -160.0f 251 }; 252 253 // Convenience HAL wrappers for AD9523 control pins (GPIOF as you said) 254 static inline void AD9523_PD(bool v) { HAL_GPIO_WritePin(GPIOF, AD9523_PD_Pin, v ? GPIO_PIN_SET : GPIO_PIN_RESET); } 255 static inline void AD9523_REF_SEL(bool v) { HAL_GPIO_WritePin(GPIOF, AD9523_REF_SEL_Pin, v ? GPIO_PIN_SET : GPIO_PIN_RESET); } 256 static inline void AD9523_SYNC_PULSE(void) { HAL_GPIO_WritePin(GPIOF, AD9523_SYNC_Pin, GPIO_PIN_SET); HAL_Delay(1); HAL_GPIO_WritePin(GPIOF, AD9523_SYNC_Pin, GPIO_PIN_RESET); } 257 static inline void AD9523_RESET_ASSERT() { HAL_GPIO_WritePin(GPIOF, AD9523_RESET_Pin, GPIO_PIN_RESET); } // check polarity 258 static inline void AD9523_RESET_RELEASE() { HAL_GPIO_WritePin(GPIOF, AD9523_RESET_Pin, GPIO_PIN_SET); } 259 static inline void AD9523_CS(bool v) { HAL_GPIO_WritePin(GPIOF, AD9523_CS_Pin, v ? GPIO_PIN_SET : GPIO_PIN_RESET); } 260 static inline void AD9523_EEPROM_SEL(bool v){ HAL_GPIO_WritePin(GPIOF, AD9523_EEPROM_SEL_Pin, v ? GPIO_PIN_SET : GPIO_PIN_RESET); } 261 262 /* USER CODE END PV */ 263 264 /* Private function prototypes -----------------------------------------------*/ 265 void SystemClock_Config(void); 266 void PeriphCommonClock_Config(void); 267 static void MPU_Config(void); 268 static void MX_GPIO_Init(void); 269 static void MX_TIM1_Init(void); 270 static void MX_TIM3_Init(void); // B15 fix: DELADJ PWM timer init 271 static void MX_I2C1_Init(void); 272 static void MX_I2C2_Init(void); 273 static void MX_I2C3_Init(void); 274 static void MX_SPI1_Init(void); 275 static void MX_SPI4_Init(void); 276 static void MX_UART5_Init(void); 277 static void MX_USART3_UART_Init(void); 278 static void MX_IWDG_Init(void); /* GAP-3 FIX 2: hardware watchdog */ 279 /* USER CODE BEGIN PFP */ 280 281 // Function prototypes 282 void systemPowerUpSequence(); 283 void systemPowerDownSequence(); 284 void initializeBeamMatrices(); 285 void runRadarPulseSequence(); 286 void executeChirpSequence(int num_chirps, uint32_t T1, uint32_t PRI1, uint32_t T2, uint32_t PRI2); 287 void printSystemStatus(); 288 289 ////////////////////////////////////////////// 290 ////////////////////micros()////////////////// 291 ////////////////////////////////////////////// 292 unsigned long micros(void){ 293 unsigned long Micros = __HAL_TIM_GET_COUNTER(&htim1); 294 return Micros; //Clock TIM1 -> AHB/APB1 is set to 72MHz/presc+1 presc = 71 295 } 296 297 ////////////////////////////////////////////// 298 //////////////////Delay_us()////////////////// 299 ////////////////////////////////////////////// 300 301 void delay_us(volatile uint32_t us){ 302 __HAL_TIM_SET_COUNTER(&htim1,0); // set the counter value a 303 while (__HAL_TIM_GET_COUNTER(&htim1) < us); // //Clock TIMx -> AHB/APB1 is set to 72MHz/presc+1 presc = 71 304 } 305 306 ////////////////////////////////////////////// 307 //////////////////delay_ns()////////////////// 308 ////////////////////////////////////////////// 309 void delay_ns(uint32_t nanoseconds) 310 { 311 // Get the starting cycle count 312 uint32_t start_cycles = DWT->CYCCNT; 313 314 // Convert nanoseconds to the number of CPU clock cycles 315 // Use `SystemCoreClock` to get the current CPU frequency. 316 // Use 64-bit math to prevent overflow for large nanosecond values. 317 uint32_t cycles = (uint32_t)(((uint64_t)nanoseconds * SystemCoreClock) / 1000000000); 318 319 // Busy-wait until the required number of cycles has passed 320 while ((DWT->CYCCNT - start_cycles) < cycles); 321 } 322 323 ////////////////////////////////////////////// 324 //////////////////////RADAR/////////////////// 325 ////////////////////////////////////////////// 326 uint8_t degreesTo7BitPhase(float degrees) { 327 // Normalize to 0-360 range 328 while(degrees < 0) degrees += 360.0f; 329 while(degrees >= 360.0f) degrees -= 360.0f; 330 331 // Convert to 7-bit (0-127) 332 uint8_t phase_7bit = (uint8_t)((degrees / 360.0f) * 128.0f); 333 334 return phase_7bit % 128; 335 } 336 337 extern "C" { 338 339 // USB CDC receive callback (called by STM32 HAL) 340 void CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) { 341 DIAG("USB", "CDC_Receive_FS callback: %lu bytes received", *Len); 342 // Process received USB data 343 usbHandler.processUSBData(Buf, *Len); 344 345 // Prepare for next reception 346 USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &usb_rx_buffer[0]); 347 USBD_CDC_ReceivePacket(&hUsbDeviceFS); 348 } 349 } 350 351 void systemPowerUpSequence() { 352 DIAG_SECTION("PWR: systemPowerUpSequence"); 353 uint8_t msg[] = "Starting Power Up Sequence...\r\n"; 354 HAL_UART_Transmit(&huart3, msg, sizeof(msg)-1, 1000); 355 356 // Step 1: Initialize ADTR1107 power sequence 357 DIAG("PWR", "Step 1: initializeADTR1107Sequence()"); 358 if (!adarManager.initializeADTR1107Sequence()) { 359 DIAG_ERR("PWR", "ADTR1107 power sequence FAILED -- calling Error_Handler()"); 360 uint8_t err[] = "ERROR: ADTR1107 power sequence failed!\r\n"; 361 HAL_UART_Transmit(&huart3, err, sizeof(err)-1, 1000); 362 Error_Handler(); 363 } 364 DIAG("PWR", "Step 1 OK: ADTR1107 sequence complete"); 365 366 // Step 2: Initialize all ADAR1000 devices 367 DIAG("PWR", "Step 2: initializeAllDevices()"); 368 if (!adarManager.initializeAllDevices()) { 369 DIAG_ERR("PWR", "ADAR1000 initialization FAILED -- calling Error_Handler()"); 370 uint8_t err[] = "ERROR: ADAR1000 initialization failed!\r\n"; 371 HAL_UART_Transmit(&huart3, err, sizeof(err)-1, 1000); 372 Error_Handler(); 373 } 374 DIAG("PWR", "Step 2 OK: All ADAR1000 devices initialized"); 375 376 // Step 3: Perform system calibration 377 DIAG("PWR", "Step 3: performSystemCalibration()"); 378 if (!adarManager.performSystemCalibration()) { 379 DIAG_WARN("PWR", "System calibration returned issues (non-fatal)"); 380 uint8_t warn[] = "WARNING: System calibration issues\r\n"; 381 HAL_UART_Transmit(&huart3, warn, sizeof(warn)-1, 1000); 382 } else { 383 DIAG("PWR", "Step 3 OK: System calibration passed"); 384 } 385 386 // Step 4: Set to safe TX mode 387 DIAG("PWR", "Step 4: setAllDevicesTXMode()"); 388 adarManager.setAllDevicesTXMode(); 389 DIAG("PWR", "Step 4 OK: All devices set to TX mode"); 390 391 uint8_t success[] = "Power Up Sequence Completed Successfully\r\n"; 392 HAL_UART_Transmit(&huart3, success, sizeof(success)-1, 1000); 393 DIAG("PWR", "systemPowerUpSequence COMPLETE"); 394 } 395 396 void systemPowerDownSequence() { 397 DIAG_SECTION("PWR: systemPowerDownSequence"); 398 uint8_t msg[] = "Starting Power Down Sequence...\r\n"; 399 HAL_UART_Transmit(&huart3, msg, sizeof(msg)-1, 1000); 400 401 // Step 1: Set all devices to RX mode (safest state) 402 DIAG("PWR", "Step 1: setAllDevicesRXMode()"); 403 adarManager.setAllDevicesRXMode(); 404 HAL_Delay(10); 405 406 // Step 2: Disable PA power supplies 407 DIAG("PWR", "Step 2: Disable PA 5V supplies (EN_P_5V0_PA1/PA2/PA3 LOW)"); 408 HAL_GPIO_WritePin(EN_P_5V0_PA1_GPIO_Port, EN_P_5V0_PA1_Pin | EN_P_5V0_PA2_Pin | EN_P_5V0_PA3_Pin, GPIO_PIN_RESET); 409 HAL_Delay(10); 410 411 // Step 3: Set PA biases to safe values 412 DIAG("PWR", "Step 3: Setting PA bias to safe value 0x20 on all 4 devices, 4 channels each"); 413 for (uint8_t dev = 0; dev < 4; dev++) { 414 adarManager.adarWrite(dev, REG_PA_CH1_BIAS_ON, 0x20, BROADCAST_OFF); 415 adarManager.adarWrite(dev, REG_PA_CH2_BIAS_ON, 0x20, BROADCAST_OFF); 416 adarManager.adarWrite(dev, REG_PA_CH3_BIAS_ON, 0x20, BROADCAST_OFF); 417 adarManager.adarWrite(dev, REG_PA_CH4_BIAS_ON, 0x20, BROADCAST_OFF); 418 } 419 HAL_Delay(10); 420 421 // Step 4: Disable LNA power supply 422 DIAG("PWR", "Step 4: Disable LNA 3.3V supply (EN_P_3V3_ADTR LOW)"); 423 HAL_GPIO_WritePin(EN_P_3V3_ADTR_GPIO_Port, EN_P_3V3_ADTR_Pin, GPIO_PIN_RESET); 424 HAL_Delay(10); 425 426 // Step 5: Set LNA bias to safe value 427 DIAG("PWR", "Step 5: Setting LNA bias to 0x00 on all 4 devices"); 428 for (uint8_t dev = 0; dev < 4; dev++) { 429 adarManager.adarWrite(dev, REG_LNA_BIAS_ON, 0x00, BROADCAST_OFF); 430 } 431 HAL_Delay(10); 432 433 // Step 6: Disable switch power supplies 434 DIAG("PWR", "Step 6: Disable switch supplies (EN_P_3V3_VDD_SW, EN_P_3V3_SW LOW)"); 435 HAL_GPIO_WritePin(EN_P_3V3_VDD_SW_GPIO_Port, EN_P_3V3_VDD_SW_Pin, GPIO_PIN_RESET); 436 HAL_GPIO_WritePin(EN_P_3V3_SW_GPIO_Port, EN_P_3V3_SW_Pin, GPIO_PIN_RESET); 437 HAL_Delay(10); 438 439 uint8_t success[] = "Power Down Sequence Completed\r\n"; 440 HAL_UART_Transmit(&huart3, success, sizeof(success)-1, 1000); 441 DIAG("PWR", "systemPowerDownSequence COMPLETE"); 442 } 443 444 void initializeBeamMatrices() { 445 uint8_t msg[] = "Initializing Beam Matrices...\r\n"; 446 HAL_UART_Transmit(&huart3, msg, sizeof(msg)-1, 1000); 447 448 // Matrix1: Positions 1-15 (positive phase differences) 449 for(int beam_pos = 0; beam_pos < 15; beam_pos++) { 450 float phase_diff_degrees = phase_differences[beam_pos]; 451 452 for(int element = 0; element < 16; element++) { 453 float cumulative_phase_degrees = element * phase_diff_degrees; 454 matrix1[beam_pos][element] = degreesTo7BitPhase(cumulative_phase_degrees); 455 } 456 } 457 458 // Matrix2: Positions 17-31 (negative phase differences) 459 for(int beam_pos = 0; beam_pos < 15; beam_pos++) { 460 float phase_diff_degrees = phase_differences[beam_pos + 16]; 461 462 for(int element = 0; element < 16; element++) { 463 float cumulative_phase_degrees = element * phase_diff_degrees; 464 matrix2[beam_pos][element] = degreesTo7BitPhase(cumulative_phase_degrees); 465 } 466 } 467 468 // Vector_0: Position 16 (zero phase - broadside) 469 for(int element = 0; element < 16; element++) { 470 vector_0[element] = 0; // 0 in 7-bit = 0° phase 471 } 472 473 uint8_t done[] = "Beam Matrices Initialized\r\n"; 474 HAL_UART_Transmit(&huart3, done, sizeof(done)-1, 1000); 475 } 476 477 void executeChirpSequence(int num_chirps, float T1, float PRI1, float T2, float PRI2) { 478 // NOTE: No per-chirp DIAG — this is a us/ns timing-critical path. 479 // Only log entry params for post-mortem analysis. 480 DIAG("SYS", "executeChirpSequence: num_chirps=%d T1=%.2f PRI1=%.2f T2=%.2f PRI2=%.2f", 481 num_chirps, T1, PRI1, T2, PRI2); 482 // First chirp sequence (microsecond timing) 483 for(int i = 0; i < num_chirps; i++) { 484 HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_8); // New chirp signal to FPGA 485 adarManager.pulseTXMode(); 486 delay_us((uint32_t)T1); 487 adarManager.pulseRXMode(); 488 delay_us((uint32_t)(PRI1 - T1)); 489 } 490 491 delay_us((uint32_t)Guard); 492 493 // Second chirp sequence (nanosecond timing) 494 for(int i = 0; i < num_chirps; i++) { 495 HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_8); // New chirp signal to FPGA 496 adarManager.pulseTXMode(); 497 delay_ns((uint32_t)(T2 * 1000)); 498 adarManager.pulseRXMode(); 499 delay_ns((uint32_t)((PRI2 - T2) * 1000)); 500 501 } 502 } 503 504 void runRadarPulseSequence() { 505 static int sequence_count = 0; 506 char msg[50]; 507 508 snprintf(msg, sizeof(msg), "Starting RADAR Sequence #%d\r\n", ++sequence_count); 509 HAL_UART_Transmit(&huart3, (uint8_t*)msg, strlen(msg), 1000); 510 DIAG("SYS", "runRadarPulseSequence #%d: m_max=%d n_max=%d y_max=%d", 511 sequence_count, m_max, n_max, y_max); 512 513 // Configure for fast switching 514 DIAG("BF", "Enabling fast-switch mode for beam sweep"); 515 adarManager.setFastSwitchMode(true); 516 517 int m = 1; // Chirp counter 518 int n = 1; // Beam Elevation position counter 519 int y = 1; // Beam Azimuth counter 520 521 // Main beam steering sequence 522 for(int beam_pos = 0; beam_pos < 15; beam_pos++) { 523 HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_9);// Notify FPGA of elevation change 524 DIAG("SYS", "Beam pos %d/15: elevation GPIO toggle, patterns matrix1/vector_0/matrix2", beam_pos); 525 // Pattern 1: matrix1 (positive steering angles) 526 adarManager.setCustomBeamPattern16(matrix1[beam_pos], ADAR1000Manager::BeamDirection::TX); 527 adarManager.setCustomBeamPattern16(matrix1[beam_pos], ADAR1000Manager::BeamDirection::RX); 528 529 executeChirpSequence(m_max/2, T1, PRI1, T2, PRI2); 530 m += m_max/2; 531 532 // Pattern 2: vector_0 (broadside) 533 adarManager.setCustomBeamPattern16(vector_0, ADAR1000Manager::BeamDirection::TX); 534 adarManager.setCustomBeamPattern16(vector_0, ADAR1000Manager::BeamDirection::RX); 535 536 executeChirpSequence(m_max/2, T1, PRI1, T2, PRI2); 537 m += m_max/2; 538 539 // Pattern 3: matrix2 (negative steering angles) 540 adarManager.setCustomBeamPattern16(matrix2[beam_pos], ADAR1000Manager::BeamDirection::TX); 541 adarManager.setCustomBeamPattern16(matrix2[beam_pos], ADAR1000Manager::BeamDirection::RX); 542 543 executeChirpSequence(m_max/2, T1, PRI1, T2, PRI2); 544 m += m_max/2; 545 546 // Reset chirp counter if needed 547 if(m > m_max) m = 1; 548 549 n++; 550 if(n > n_max) n = 1; 551 552 } 553 554 HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_10);//Tell FPGA that there is a new azimuth 555 DIAG("SYS", "Azimuth GPIO toggle (GPIOD pin 10), stepping motor"); 556 557 y++; if(y>y_max)y=1; 558 //Rotate stepper to next y position 559 for(int k= 0;k<(int)(Stepper_steps/y_max);k++){ 560 HAL_GPIO_WritePin(STEPPER_CLK_P_GPIO_Port, STEPPER_CLK_P_Pin, GPIO_PIN_SET); 561 delay_us(500); 562 HAL_GPIO_WritePin(STEPPER_CLK_P_GPIO_Port, STEPPER_CLK_P_Pin, GPIO_PIN_RESET); 563 delay_us(500); 564 } 565 DIAG("MOT", "Stepper moved %d steps for azimuth position y=%d", (int)(Stepper_steps/y_max), y); 566 567 568 569 snprintf(msg, sizeof(msg), "RADAR Sequence #%d Completed\r\n", sequence_count); 570 HAL_UART_Transmit(&huart3, (uint8_t*)msg, strlen(msg), 1000); 571 DIAG("SYS", "runRadarPulseSequence #%d COMPLETE", sequence_count); 572 } 573 574 575 576 577 void printSystemStatus() { 578 char status_msg[100]; 579 580 // Print device status 581 for(int i = 0; i < 4; i++) { 582 if(adarManager.verifyDeviceCommunication(i)) { 583 float temp = adarManager.readTemperature(i); 584 snprintf(status_msg, sizeof(status_msg), 585 "ADAR1000 #%d: OK, Temperature: %.1fC\r\n", i+1, temp); 586 HAL_UART_Transmit(&huart3, (uint8_t*)status_msg, strlen(status_msg), 1000); 587 } else { 588 snprintf(status_msg, sizeof(status_msg), 589 "ADAR1000 #%d: COMMUNICATION ERROR\r\n", i+1); 590 HAL_UART_Transmit(&huart3, (uint8_t*)status_msg, strlen(status_msg), 1000); 591 } 592 } 593 594 // Print matrix info 595 snprintf(status_msg, sizeof(status_msg), 596 "Beam Matrices: 31 positions, %d chirps/position\r\n", m_max); 597 HAL_UART_Transmit(&huart3, (uint8_t*)status_msg, strlen(status_msg), 1000); 598 } 599 600 /***************************************************************/ 601 /**********************SYSTEM ERROR HANDLER*********************/ 602 /***************************************************************/ 603 604 typedef enum { 605 ERROR_NONE = 0, 606 ERROR_AD9523_CLOCK, 607 ERROR_ADF4382_TX_UNLOCK, 608 ERROR_ADF4382_RX_UNLOCK, 609 ERROR_ADAR1000_COMM, 610 ERROR_ADAR1000_TEMP, 611 ERROR_IMU_COMM, 612 ERROR_BMP180_COMM, 613 ERROR_GPS_COMM, 614 ERROR_RF_PA_OVERCURRENT, 615 ERROR_RF_PA_BIAS, 616 ERROR_STEPPER_MOTOR, 617 ERROR_FPGA_COMM, 618 ERROR_POWER_SUPPLY, 619 ERROR_TEMPERATURE_HIGH, 620 ERROR_MEMORY_ALLOC, 621 ERROR_WATCHDOG_TIMEOUT 622 } SystemError_t; 623 624 static SystemError_t last_error = ERROR_NONE; 625 static uint32_t error_count = 0; 626 static bool system_emergency_state = false; 627 628 // Error handler function 629 SystemError_t checkSystemHealth(void) { 630 SystemError_t current_error = ERROR_NONE; 631 632 // 1. Check AD9523 Clock Generator 633 static uint32_t last_clock_check = 0; 634 if (HAL_GetTick() - last_clock_check > 5000) { 635 GPIO_PinState s0 = HAL_GPIO_ReadPin(AD9523_STATUS0_GPIO_Port, AD9523_STATUS0_Pin); 636 GPIO_PinState s1 = HAL_GPIO_ReadPin(AD9523_STATUS1_GPIO_Port, AD9523_STATUS1_Pin); 637 DIAG_GPIO("CLK", "AD9523 STATUS0", s0); 638 DIAG_GPIO("CLK", "AD9523 STATUS1", s1); 639 if (s0 == GPIO_PIN_RESET || s1 == GPIO_PIN_RESET) { 640 current_error = ERROR_AD9523_CLOCK; 641 DIAG_ERR("CLK", "AD9523 clock health check FAILED (STATUS0=%d STATUS1=%d)", s0, s1); 642 } 643 last_clock_check = HAL_GetTick(); 644 } 645 646 // 2. Check ADF4382 Lock Status 647 bool tx_locked, rx_locked; 648 if (ADF4382A_CheckLockStatus(&lo_manager, &tx_locked, &rx_locked) == ADF4382A_MANAGER_OK) { 649 if (!tx_locked) { 650 current_error = ERROR_ADF4382_TX_UNLOCK; 651 DIAG_ERR("LO", "Health check: TX LO UNLOCKED"); 652 } 653 if (!rx_locked) { 654 current_error = ERROR_ADF4382_RX_UNLOCK; 655 DIAG_ERR("LO", "Health check: RX LO UNLOCKED"); 656 } 657 } 658 659 // 3. Check ADAR1000 Communication and Temperature 660 for (int i = 0; i < 4; i++) { 661 if (!adarManager.verifyDeviceCommunication(i)) { 662 current_error = ERROR_ADAR1000_COMM; 663 DIAG_ERR("BF", "Health check: ADAR1000 #%d comm FAILED", i); 664 break; 665 } 666 667 float temp = adarManager.readTemperature(i); 668 if (temp > 85.0f) { 669 current_error = ERROR_ADAR1000_TEMP; 670 DIAG_ERR("BF", "Health check: ADAR1000 #%d OVERTEMP %.1fC > 85C", i, temp); 671 break; 672 } 673 } 674 675 // 4. Check IMU Communication 676 static uint32_t last_imu_check = 0; 677 if (HAL_GetTick() - last_imu_check > 10000) { 678 if (!GY85_Update(&imu)) { 679 current_error = ERROR_IMU_COMM; 680 DIAG_ERR("IMU", "Health check: GY85_Update() FAILED"); 681 } 682 last_imu_check = HAL_GetTick(); 683 } 684 685 // 5. Check BMP180 Communication 686 static uint32_t last_bmp_check = 0; 687 if (HAL_GetTick() - last_bmp_check > 15000) { 688 double pressure = myBMP.getPressure(); 689 if (pressure < 30000.0 || pressure > 110000.0 || isnan(pressure)) { 690 current_error = ERROR_BMP180_COMM; 691 DIAG_ERR("SYS", "Health check: BMP180 pressure out of range: %.0f", pressure); 692 } 693 last_bmp_check = HAL_GetTick(); 694 } 695 696 // 6. Check GPS Communication 697 static uint32_t last_gps_fix = 0; 698 if (gps.location.isUpdated()) { 699 last_gps_fix = HAL_GetTick(); 700 } 701 if (HAL_GetTick() - last_gps_fix > 30000) { 702 current_error = ERROR_GPS_COMM; 703 DIAG_WARN("SYS", "Health check: GPS no fix for >30s"); 704 } 705 706 // 7. Check RF Power Amplifier Current 707 if (PowerAmplifier) { 708 for (int i = 0; i < 16; i++) { 709 if (Idq_reading[i] > 2.5f) { 710 current_error = ERROR_RF_PA_OVERCURRENT; 711 DIAG_ERR("PA", "Health check: PA ch%d OVERCURRENT Idq=%.3fA > 2.5A", i, Idq_reading[i]); 712 break; 713 } 714 if (Idq_reading[i] < 0.1f) { 715 current_error = ERROR_RF_PA_BIAS; 716 DIAG_ERR("PA", "Health check: PA ch%d BIAS FAULT Idq=%.3fA < 0.1A", i, Idq_reading[i]); 717 break; 718 } 719 } 720 } 721 722 // 8. Check System Temperature 723 if (temperature > 75.0f) { 724 current_error = ERROR_TEMPERATURE_HIGH; 725 DIAG_ERR("SYS", "Health check: System OVERTEMP %.1fC > 75C", temperature); 726 } 727 728 // 9. Simple watchdog check 729 static uint32_t last_health_check = 0; 730 if (HAL_GetTick() - last_health_check > 60000) { 731 current_error = ERROR_WATCHDOG_TIMEOUT; 732 DIAG_ERR("SYS", "Health check: Watchdog timeout (>60s since last check)"); 733 } 734 last_health_check = HAL_GetTick(); 735 736 if (current_error != ERROR_NONE) { 737 DIAG_ERR("SYS", "checkSystemHealth returning error code %d", current_error); 738 } 739 return current_error; 740 } 741 742 // Error recovery function 743 void attemptErrorRecovery(SystemError_t error) { 744 DIAG_SECTION("SYS: attemptErrorRecovery"); 745 DIAG("SYS", "Attempting recovery from error code %d", error); 746 char recovery_msg[80]; 747 snprintf(recovery_msg, sizeof(recovery_msg), 748 "Attempting recovery from error: %d\r\n", error); 749 HAL_UART_Transmit(&huart3, (uint8_t*)recovery_msg, strlen(recovery_msg), 1000); 750 751 switch (error) { 752 case ERROR_ADF4382_TX_UNLOCK: 753 case ERROR_ADF4382_RX_UNLOCK: 754 // Re-initialize LO 755 DIAG("LO", "Recovery: Re-initializing LO manager (SYNC_METHOD_TIMED)"); 756 ADF4382A_Manager_Init(&lo_manager, SYNC_METHOD_TIMED); 757 HAL_Delay(100); 758 DIAG("LO", "Recovery: LO re-init complete"); 759 break; 760 761 case ERROR_ADAR1000_COMM: 762 // Reset ADAR1000 communication 763 DIAG("BF", "Recovery: Re-initializing all ADAR1000 devices"); 764 adarManager.initializeAllDevices(); 765 HAL_Delay(50); 766 DIAG("BF", "Recovery: ADAR1000 re-init complete"); 767 break; 768 769 case ERROR_IMU_COMM: 770 // Re-initialize IMU 771 DIAG("IMU", "Recovery: Re-initializing GY85 IMU"); 772 GY85_Init(); 773 HAL_Delay(100); 774 DIAG("IMU", "Recovery: IMU re-init complete"); 775 break; 776 777 case ERROR_GPS_COMM: 778 // GPS will auto-recover when signal returns 779 DIAG("SYS", "Recovery: GPS error -- no action (auto-recover on signal)"); 780 break; 781 782 default: 783 // For other errors, just log and continue 784 DIAG_WARN("SYS", "Recovery: No specific handler for error %d", error); 785 break; 786 } 787 788 snprintf(recovery_msg, sizeof(recovery_msg), 789 "Recovery attempt completed.\r\n"); 790 HAL_UART_Transmit(&huart3, (uint8_t*)recovery_msg, strlen(recovery_msg), 1000); 791 DIAG("SYS", "attemptErrorRecovery COMPLETE"); 792 } 793 794 //////////////////////////////////////////////////////////////////////////////// 795 //:::::RF POWER AMPLIFIER DAC5578 Emergency stop function using CLR pin///////// 796 //////////////////////////////////////////////////////////////////////////////// 797 void Emergency_Stop(void) { 798 DIAG_ERR("PA", ">>> EMERGENCY_STOP ACTIVATED <<<"); 799 /* Immediately clear all DAC outputs to zero using hardware CLR */ 800 DIAG_ERR("PA", "Clearing DAC1 outputs via CLR pin"); 801 DAC5578_ActivateClearPin(&hdac1); 802 DIAG_ERR("PA", "Clearing DAC2 outputs via CLR pin"); 803 DAC5578_ActivateClearPin(&hdac2); 804 805 /* [GAP-3 FIX 1] Cut RF and PA power rails — DAC CLR alone is not enough. 806 * With gate voltage cleared but VDD still energized, PAs can self-bias 807 * or oscillate. Disable everything in fast-to-slow order: 808 * 1. TX mixers (stop RF immediately) 809 * 2. PA 5V per-element supplies 810 * 3. PA 5.5V bulk supply 811 * 4. RFPA VDD enable 812 */ 813 DIAG_ERR("PA", "Disabling TX mixers (GPIOD pin 11 LOW)"); 814 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_11, GPIO_PIN_RESET); 815 816 DIAG_ERR("PA", "Cutting PA 5V supplies (PA1/PA2/PA3 LOW)"); 817 HAL_GPIO_WritePin(EN_P_5V0_PA1_GPIO_Port, EN_P_5V0_PA1_Pin, GPIO_PIN_RESET); 818 HAL_GPIO_WritePin(EN_P_5V0_PA2_GPIO_Port, EN_P_5V0_PA2_Pin, GPIO_PIN_RESET); 819 HAL_GPIO_WritePin(EN_P_5V0_PA3_GPIO_Port, EN_P_5V0_PA3_Pin, GPIO_PIN_RESET); 820 821 DIAG_ERR("PA", "Cutting PA 5.5V supply (EN_P_5V5_PA LOW)"); 822 HAL_GPIO_WritePin(EN_P_5V5_PA_GPIO_Port, EN_P_5V5_PA_Pin, GPIO_PIN_RESET); 823 824 DIAG_ERR("PA", "Disabling RFPA VDD (EN_DIS_RFPA_VDD LOW)"); 825 HAL_GPIO_WritePin(EN_DIS_RFPA_VDD_GPIO_Port, EN_DIS_RFPA_VDD_Pin, GPIO_PIN_RESET); 826 827 DIAG_ERR("PA", "All PA rails cut -- entering infinite hold loop (manual reset required)"); 828 /* Keep outputs cleared until reset. 829 * MUST refresh IWDG here — otherwise the watchdog would reset the MCU, 830 * re-running startup code which re-energizes PA rails. */ 831 while (1) { 832 HAL_IWDG_Refresh(&hiwdg); 833 HAL_Delay(100); 834 } 835 } 836 837 // Error response function 838 void handleSystemError(SystemError_t error) { 839 if (error == ERROR_NONE) return; 840 841 error_count++; 842 last_error = error; 843 DIAG_ERR("SYS", "handleSystemError: error=%d error_count=%lu", error, error_count); 844 845 char error_msg[100]; 846 const char* error_strings[] = { 847 "No error", 848 "AD9523 Clock failure", 849 "ADF4382 TX LO unlocked", 850 "ADF4382 RX LO unlocked", 851 "ADAR1000 communication error", 852 "ADAR1000 temperature high", 853 "IMU communication error", 854 "BMP180 communication error", 855 "GPS communication lost", 856 "RF PA overcurrent detected", 857 "RF PA bias fault", 858 "Stepper motor fault", 859 "FPGA communication error", 860 "Power supply fault", 861 "System temperature high", 862 "Memory allocation failed", 863 "Watchdog timeout" 864 }; 865 866 snprintf(error_msg, sizeof(error_msg), 867 "ERROR #%d: %s (Count: %lu)\r\n", 868 error, error_strings[error], error_count); 869 HAL_UART_Transmit(&huart3, (uint8_t*)error_msg, strlen(error_msg), 1000); 870 871 // Blink LED pattern based on error code 872 DIAG("SYS", "Blinking LED3 %d times for error code %d", (error % 5) + 1, error); 873 for (int i = 0; i < (error % 5) + 1; i++) { 874 HAL_GPIO_TogglePin(LED_3_GPIO_Port, LED_3_Pin); 875 HAL_Delay(200); 876 } 877 878 // Critical errors trigger emergency shutdown 879 if (error >= ERROR_RF_PA_OVERCURRENT && error <= ERROR_POWER_SUPPLY) { 880 DIAG_ERR("SYS", "CRITICAL ERROR (code %d: %s) -- initiating Emergency_Stop()", error, error_strings[error]); 881 snprintf(error_msg, sizeof(error_msg), 882 "CRITICAL ERROR! Initiating emergency shutdown.\r\n"); 883 HAL_UART_Transmit(&huart3, (uint8_t*)error_msg, strlen(error_msg), 1000); 884 885 /* [GAP-3 FIX 5] Set flag BEFORE Emergency_Stop() — the function 886 * never returns (infinite loop), so the line after it was dead code. */ 887 system_emergency_state = true; 888 Emergency_Stop(); 889 /* NOTREACHED — Emergency_Stop() loops forever */ 890 } 891 892 // For non-critical errors, attempt recovery 893 if (!system_emergency_state) { 894 DIAG("SYS", "Non-critical error -- attempting recovery"); 895 attemptErrorRecovery(error); 896 } 897 } 898 899 900 // System health monitoring function 901 bool checkSystemHealthStatus(void) { 902 SystemError_t error = checkSystemHealth(); 903 904 if (error != ERROR_NONE) { 905 DIAG_ERR("SYS", "checkSystemHealthStatus: error detected (code %d), calling handleSystemError()", error); 906 handleSystemError(error); 907 908 // If we're in emergency state or too many errors, shutdown 909 if (system_emergency_state || error_count > 10) { 910 DIAG_ERR("SYS", "checkSystemHealthStatus returning FALSE (emergency=%s error_count=%lu)", 911 system_emergency_state ? "true" : "false", error_count); 912 return false; 913 } 914 } 915 916 return true; 917 } 918 919 // Get system status for GUI 920 // Get system status for GUI with 8 temperature variables 921 void getSystemStatusForGUI(char* status_buffer, size_t buffer_size) { 922 char temp_buffer[200]; 923 char final_status[500] = "System Status: "; 924 925 // Basic status 926 if (system_emergency_state) { 927 strcat(final_status, "EMERGENCY_STOP|"); 928 } else { 929 strcat(final_status, "NORMAL|"); 930 } 931 932 // Error information 933 snprintf(temp_buffer, sizeof(temp_buffer), "LastError:%d|ErrorCount:%lu|", 934 last_error, error_count); 935 strcat(final_status, temp_buffer); 936 937 // Sensor status 938 snprintf(temp_buffer, sizeof(temp_buffer), "IMU:%.1f,%.1f,%.1f|GPS:%.6f,%.6f|ALT:%.1f|", 939 Pitch_Sensor, Roll_Sensor, Yaw_Sensor, 940 RADAR_Latitude, RADAR_Longitude, RADAR_Altitude); 941 strcat(final_status, temp_buffer); 942 943 // LO Status 944 bool tx_locked, rx_locked; 945 ADF4382A_CheckLockStatus(&lo_manager, &tx_locked, &rx_locked); 946 snprintf(temp_buffer, sizeof(temp_buffer), "LO_TX:%s|LO_RX:%s|", 947 tx_locked ? "LOCKED" : "UNLOCKED", 948 rx_locked ? "LOCKED" : "UNLOCKED"); 949 strcat(final_status, temp_buffer); 950 951 // Temperature readings (8 variables) 952 // You'll need to populate these temperature values from your sensors 953 // For now, I'll show how to format them - replace with actual temperature readings 954 Temperature_1 = ADS7830_Measure_SingleEnded(&hadc3, 0); 955 Temperature_2 = ADS7830_Measure_SingleEnded(&hadc3, 1); 956 Temperature_3 = ADS7830_Measure_SingleEnded(&hadc3, 2); 957 Temperature_4 = ADS7830_Measure_SingleEnded(&hadc3, 3); 958 Temperature_5 = ADS7830_Measure_SingleEnded(&hadc3, 4); 959 Temperature_6 = ADS7830_Measure_SingleEnded(&hadc3, 5); 960 Temperature_7 = ADS7830_Measure_SingleEnded(&hadc3, 6); 961 Temperature_8 = ADS7830_Measure_SingleEnded(&hadc3, 7); 962 963 // Format all 8 temperature variables 964 snprintf(temp_buffer, sizeof(temp_buffer), 965 "T1:%.1f|T2:%.1f|T3:%.1f|T4:%.1f|T5:%.1f|T6:%.1f|T7:%.1f|T8:%.1f|", 966 Temperature_1, Temperature_2, Temperature_3, Temperature_4, 967 Temperature_5, Temperature_6, Temperature_7, Temperature_8); 968 strcat(final_status, temp_buffer); 969 970 // RF Power Amplifier status (if enabled) 971 if (PowerAmplifier) { 972 float avg_current = 0.0f; 973 for (int i = 0; i < 16; i++) { 974 avg_current += Idq_reading[i]; 975 } 976 avg_current /= 16.0f; 977 978 snprintf(temp_buffer, sizeof(temp_buffer), "PA_AvgCurrent:%.2f|PA_Enabled:%d|", 979 avg_current, PowerAmplifier); 980 strcat(final_status, temp_buffer); 981 } 982 983 // Radar operation status 984 snprintf(temp_buffer, sizeof(temp_buffer), "BeamPos:%d|Azimuth:%d|ChirpCount:%d|", 985 n, y, m); 986 strcat(final_status, temp_buffer); 987 988 // Copy to output buffer 989 strncpy(status_buffer, final_status, buffer_size - 1); 990 status_buffer[buffer_size - 1] = '\0'; 991 } 992 993 /* ---------- UART printing helpers (Bug #8 FIXED: uncommented) ---------- */ 994 static void uart_print(const char *msg) 995 { 996 HAL_UART_Transmit(&huart3, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY); 997 } 998 999 static void uart_println(const char *msg) 1000 { 1001 HAL_UART_Transmit(&huart3, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY); 1002 const char crlf[] = "\r\n"; 1003 HAL_UART_Transmit(&huart3, (uint8_t*)crlf, 2, HAL_MAX_DELAY); 1004 } 1005 1006 /* ---------- Helper delay wrappers ---------- */ 1007 static inline void delay_ms(uint32_t ms) { HAL_Delay(ms); } 1008 1009 1010 1011 // This custom version of delay() ensures that the gps object 1012 // is being "fed". 1013 static void smartDelay(unsigned long ms) 1014 { 1015 uint32_t start = HAL_GetTick(); 1016 uint8_t ch; 1017 1018 do { 1019 // While there is new data available in UART (non-blocking) 1020 if (HAL_UART_Receive(&huart5, &ch, 1, 0) == HAL_OK) { 1021 gps.encode(ch); // Pass received byte to TinyGPS++ equivalent parser 1022 } 1023 } while (HAL_GetTick() - start < ms); 1024 } 1025 1026 // Small helper to enable DWT cycle counter for microdelay 1027 static void DWT_Init(void) 1028 { 1029 // Enable DWT CYCCNT 1030 CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; 1031 DWT->CYCCNT = 0; 1032 DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; 1033 } 1034 1035 // Configure and program AD9523 via no-os driver 1036 static int configure_ad9523(void) 1037 { 1038 int32_t ret; 1039 struct ad9523_dev *dev = NULL; 1040 1041 static struct ad9523_platform_data pdata; 1042 memset(&pdata, 0, sizeof(pdata)); 1043 1044 // VCXO + refs 1045 pdata.vcxo_freq = 100000000; // 100 MHz VCXO on OSC_IN 1046 pdata.refa_diff_rcv_en = 0; // REFA 10 MHz single-ended 1047 pdata.refb_diff_rcv_en = 0; // REFB 100 MHz single-ended 1048 pdata.osc_in_diff_en = 0; 1049 1050 // PLL1: keep bypass disabled so VCXO can be used as reference cleanup if desired 1051 pdata.pll1_bypass_en = 0; 1052 pdata.refa_r_div = 1; 1053 pdata.refb_r_div = 1; 1054 1055 // PLL2: 100 MHz PFD (R2=1), N = 36 to get VCO = 3.6 GHz 1056 pdata.pll2_ndiv_a_cnt = 0; 1057 pdata.pll2_ndiv_b_cnt = 9; // 4*9 + 0 = 36 1058 pdata.pll2_r2_div = 0; // R2=1 1059 pdata.pll2_charge_pump_current_nA = 3500; // example 1060 1061 // Loop filters: reasonable starting values from examples 1062 pdata.rpole2 = RPOLE2_900_OHM; 1063 pdata.rzero = RZERO_2000_OHM; 1064 pdata.cpole1 = CPOLE1_24_PF; 1065 pdata.rzero_bypass_en = 0; 1066 1067 // Channels array (must allocate AD9523_NUM_CHAN entries) 1068 static struct ad9523_channel_spec channels[AD9523_NUM_CHAN]; 1069 pdata.channels = channels; 1070 pdata.num_channels = AD9523_NUM_CHAN; 1071 1072 // Initialize channels to disabled defaults 1073 for (int i=0; i<AD9523_NUM_CHAN; ++i) { 1074 channels[i].channel_num = i; 1075 channels[i].driver_mode = TRISTATE; 1076 channels[i].channel_divider = 0; 1077 channels[i].divider_phase = 0; 1078 channels[i].use_alt_clock_src = 0; 1079 channels[i].output_dis = 1; 1080 } 1081 1082 // Map your required outputs (3.6 GHz PLL2) 1083 // OUT0 = ADF4382A_TX= 300 MHz LVDS ( /12 ) 1084 channels[0].channel_divider = 12; 1085 channels[0].driver_mode = LVDS_7mA; 1086 channels[0].divider_phase = 0; 1087 channels[0].output_dis = 0; 1088 1089 // OUT1 = ADF4382A_RX = 300 MHz LVDS (phase aligned with OUT0) 1090 channels[1].channel_divider = 12; 1091 channels[1].driver_mode = LVDS_7mA; 1092 channels[1].divider_phase = 0; 1093 channels[1].output_dis = 0; 1094 1095 // OUT4 = ADC = 400 MHz LVDS ( /9 ) 1096 channels[4].channel_divider = 9; 1097 channels[4].driver_mode = LVDS_7mA; 1098 channels[4].divider_phase = 0; 1099 channels[4].output_dis = 0; 1100 1101 // OUT5 = FPGA_ADC = 400 MHz LVDS (phase aligned with OUT4) 1102 channels[5].channel_divider = 9; 1103 channels[5].driver_mode = LVDS_7mA; 1104 channels[5].divider_phase = 0; 1105 channels[5].output_dis = 0; 1106 1107 // OUT6 = FPGA_SYSTEM_CLOCK = 100 MHz LVCMOS ( /36 ) 1108 channels[6].channel_divider = 36; 1109 channels[6].driver_mode = CMOS_CONF1; 1110 channels[6].divider_phase = 0; 1111 channels[6].output_dis = 0; 1112 1113 // OUT7 = FPGA_TEST_CLOCK = 20 MHz LVCMOS ( /180 ) 1114 channels[7].channel_divider = 180; 1115 channels[7].driver_mode = CMOS_CONF1; 1116 channels[7].divider_phase = 0; 1117 channels[7].output_dis = 0; 1118 1119 // OUT8 = SYNC_TX = 60 MHz LVDS ( /60 ) 1120 channels[8].channel_divider = 60; 1121 channels[8].driver_mode = LVDS_4mA; 1122 channels[8].divider_phase = 0; 1123 channels[8].output_dis = 0; 1124 1125 // OUT9 = SYNC_RX = 60 MHz LVDS (phase aligned with OUT8) 1126 channels[9].channel_divider = 60; 1127 channels[9].driver_mode = LVDS_4mA; 1128 channels[9].divider_phase = 0; 1129 channels[9].output_dis = 0; 1130 1131 // OUT10 = DAC = 120 MHz LVCMOS ( /30 ) 1132 channels[10].channel_divider = 30; 1133 channels[10].driver_mode = CMOS_CONF1; 1134 channels[10].divider_phase = 0; 1135 channels[10].output_dis = 0; 1136 1137 // OUT11 = FPGA_DAC = 120 MHz LVCMOS (phase aligned with OUT10) 1138 channels[11].channel_divider = 30; 1139 channels[11].driver_mode = CMOS_CONF1; 1140 channels[11].divider_phase = 0; 1141 channels[11].output_dis = 0; 1142 1143 // Fill ad9523 init param 1144 struct ad9523_init_param init_param; 1145 memset(&init_param, 0, sizeof(init_param)); 1146 1147 // SPI init (no_os type) 1148 init_param.spi_init.max_speed_hz = 10000000; // 10 MHz SPI 1149 init_param.spi_init.chip_select = 0; 1150 init_param.spi_init.mode = NO_OS_SPI_MODE_0; 1151 init_param.spi_init.platform_ops = &stm32_spi_ops; 1152 init_param.spi_init.extra = &hspi4; // pass HAL handle via extra 1153 1154 1155 init_param.pdata = &pdata; 1156 1157 DIAG_SECTION("AD9523 CONFIGURE"); 1158 DIAG("CLK", "VCXO=%lu Hz, PLL2 N=%d (4*%d+%d)=%d, R2=%d", 1159 (unsigned long)pdata.vcxo_freq, 1160 4 * pdata.pll2_ndiv_b_cnt + pdata.pll2_ndiv_a_cnt, 1161 pdata.pll2_ndiv_b_cnt, pdata.pll2_ndiv_a_cnt, 1162 4 * pdata.pll2_ndiv_b_cnt + pdata.pll2_ndiv_a_cnt, 1163 pdata.pll2_r2_div); 1164 DIAG("CLK", "Enabled channels: 0,1(/12=300M) 4,5(/9=400M) 6(/36=100M) 7(/180=20M) 8,9(/60=60M) 10,11(/30=120M)"); 1165 1166 // init ad9523 defaults (fills any missing pdata defaults) 1167 DIAG("CLK", "Calling ad9523_init() -- fills pdata defaults"); 1168 ad9523_init(&init_param); 1169 1170 /* [Bug #2 FIXED] Removed first ad9523_setup() call that was here. 1171 * It wrote to the chip while still in reset — writes were lost. 1172 * Only the post-reset setup call below is needed. */ 1173 1174 // Bring AD9523 out of reset 1175 DIAG("CLK", "Releasing AD9523 reset (AD9523_RESET_RELEASE)"); 1176 AD9523_RESET_RELEASE(); 1177 HAL_Delay(5); 1178 DIAG("CLK", "AD9523 reset released, waited 5 ms"); 1179 1180 // Select REFB (100MHz) using REF_SEL pin (true selects REFB here) 1181 DIAG("CLK", "Selecting REFB (100 MHz) via REF_SEL pin"); 1182 AD9523_REF_SEL(true); 1183 1184 // Call setup which uses no_os_spi to write registers, io_update, calibrate, sync 1185 DIAG("CLK", "Calling ad9523_setup() -- post-reset configuration"); 1186 uint32_t setup_start = HAL_GetTick(); 1187 ret = ad9523_setup(&dev, &init_param); 1188 DIAG("CLK", "ad9523_setup() returned %ld (took %lu ms)", 1189 (long)ret, (unsigned long)(HAL_GetTick() - setup_start)); 1190 if (ret != 0) { 1191 // handle error: lock missing or SPI error 1192 DIAG_ERR("CLK", "ad9523_setup() FAILED (ret=%ld) -- lock missing or SPI error", (long)ret); 1193 return -1; 1194 } 1195 1196 // Final check 1197 DIAG("CLK", "Checking AD9523 status (PLL lock, etc.)"); 1198 ret = ad9523_status(dev); 1199 DIAG("CLK", "ad9523_status() returned %ld", (long)ret); 1200 if (ret != 0) { 1201 // log/handle 1202 DIAG_ERR("CLK", "AD9523 status check FAILED (ret=%ld)", (long)ret); 1203 return -1; 1204 } 1205 1206 // optionally manual sync 1207 DIAG("CLK", "Triggering manual ad9523_sync()"); 1208 ad9523_sync(dev); 1209 DIAG("CLK", "AD9523 configuration complete -- all outputs should be active"); 1210 1211 // keep device pointer globally if needed (dev) 1212 return 0; 1213 } 1214 1215 //////////////////////////////////////////////////////////////////////////////// 1216 //////////////////////////////ADAR1000////////////////////////////////////////// 1217 //////////////////////////////////////////////////////////////////////////////// 1218 // Alternative approach using the beam sequence feature 1219 void setupBeamSequences(ADAR1000Manager& manager) { 1220 std::vector<ADAR1000Manager::BeamConfig> tx_sequence; 1221 std::vector<ADAR1000Manager::BeamConfig> rx_sequence; 1222 1223 // Create beam configurations for each pattern 1224 // Matrix1 sequences (14 steps) 1225 for(int i = 0; i < 14; i++) { 1226 ADAR1000Manager::BeamConfig tx_config; 1227 ADAR1000Manager::BeamConfig rx_config; 1228 1229 // Calculate angles or use your matrix directly 1230 // For now, we'll use a placeholder angle and set phases manually later 1231 tx_config.angle_degrees = 0; // This would be calculated from your matrix 1232 rx_config.angle_degrees = 0; 1233 1234 // Copy phase settings from matrix1 1235 for(int ch = 0; ch < 16; ch++) { 1236 if(ch < 4) { 1237 tx_config.phase_settings[ch] = matrix1[i][ch]; 1238 rx_config.phase_settings[ch] = matrix1[i][ch]; 1239 } 1240 } 1241 1242 tx_sequence.push_back(tx_config); 1243 rx_sequence.push_back(rx_config); 1244 } 1245 1246 // You would similarly add the zero phase and matrix2 sequences 1247 1248 // Note: The beam sequence feature in the manager currently uses calculated phases 1249 // You might need to modify the manager to support pre-calculated phase arrays 1250 } 1251 void setCustomBeamPattern(ADAR1000Manager& manager, uint8_t phase_pattern[16]) { 1252 // Set TX phases for all 4 ADAR1000 devices 1253 for(int dev = 0; dev < 4; dev++) { 1254 for(int ch = 0; ch < 4; ch++) { 1255 uint8_t phase = phase_pattern[dev * 4 + ch]; 1256 manager.adarSetTxPhase(dev, ch + 1, phase, BROADCAST_OFF); 1257 } 1258 } 1259 1260 // Set RX phases for all 4 ADAR1000 devices 1261 for(int dev = 0; dev < 4; dev++) { 1262 for(int ch = 0; ch < 4; ch++) { 1263 uint8_t phase = phase_pattern[dev * 4 + ch]; 1264 manager.adarSetRxPhase(dev, ch + 1, phase, BROADCAST_OFF); 1265 } 1266 } 1267 } 1268 1269 void initializeBeamMatricesWithSteeringAngles() { 1270 const float wavelength = 0.02857f; // 10.5 GHz wavelength in meters 1271 const float element_spacing = wavelength / 2.0f; 1272 1273 // Calculate steering angles from phase differences 1274 float steering_angles[31]; 1275 for(int i = 0; i < 31; i++) { 1276 float phase_diff_rad = phase_differences[i] * M_PI / 180.0f; 1277 steering_angles[i] = asin((phase_diff_rad * wavelength) / (2 * M_PI * element_spacing)) * 180.0f / M_PI; 1278 } 1279 1280 // Matrix1: Positive angles (positions 1-15) 1281 for(int beam_pos = 0; beam_pos < 15; beam_pos++) { 1282 float angle = steering_angles[beam_pos]; 1283 1284 for(int element = 0; element < 16; element++) { 1285 // Calculate phase shift for linear array 1286 float phase_shift_rad = (2 * M_PI * element_spacing * element * sin(angle * M_PI / 180.0f)) / wavelength; 1287 float phase_degrees = phase_shift_rad * 180.0f / M_PI; 1288 1289 // Wrap to 0-360 degrees 1290 while(phase_degrees < 0) phase_degrees += 360; 1291 while(phase_degrees >= 360) phase_degrees -= 360; 1292 1293 matrix1[beam_pos][element] = (uint8_t)((phase_degrees / 360.0f) * 128); 1294 } 1295 } 1296 1297 // Matrix2: Negative angles (positions 17-31) 1298 for(int beam_pos = 0; beam_pos < 15; beam_pos++) { 1299 float angle = steering_angles[beam_pos + 16]; 1300 1301 for(int element = 0; element < 16; element++) { 1302 float phase_shift_rad = (2 * M_PI * element_spacing * element * sin(angle * M_PI / 180.0f)) / wavelength; 1303 float phase_degrees = phase_shift_rad * 180.0f / M_PI; 1304 1305 while(phase_degrees < 0) phase_degrees += 360; 1306 while(phase_degrees >= 360) phase_degrees -= 360; 1307 1308 matrix2[beam_pos][element] = (uint8_t)((phase_degrees / 360.0f) * 128); 1309 } 1310 } 1311 } 1312 1313 1314 1315 /* USER CODE END PFP */ 1316 1317 /* Private user code ---------------------------------------------------------*/ 1318 /* USER CODE BEGIN 0 */ 1319 1320 /* USER CODE END 0 */ 1321 1322 /** 1323 * @brief The application entry point. 1324 * @retval int 1325 */ 1326 int main(void) 1327 { 1328 1329 /* USER CODE BEGIN 1 */ 1330 1331 /* USER CODE END 1 */ 1332 1333 /* MPU Configuration--------------------------------------------------------*/ 1334 MPU_Config(); 1335 1336 /* MCU Configuration--------------------------------------------------------*/ 1337 1338 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ 1339 HAL_Init(); 1340 1341 /* USER CODE BEGIN Init */ 1342 1343 /* USER CODE END Init */ 1344 1345 /* Configure the system clock */ 1346 SystemClock_Config(); 1347 1348 /* Configure the peripherals common clocks */ 1349 PeriphCommonClock_Config(); 1350 1351 /* USER CODE BEGIN SysInit */ 1352 1353 1354 /* USER CODE END SysInit */ 1355 1356 /* Initialize all configured peripherals */ 1357 MX_GPIO_Init(); 1358 MX_TIM1_Init(); 1359 MX_TIM3_Init(); // B15 fix: init DELADJ PWM timer before LO manager uses it 1360 MX_I2C1_Init(); 1361 MX_I2C2_Init(); 1362 MX_I2C3_Init(); 1363 MX_SPI1_Init(); 1364 MX_SPI4_Init(); 1365 MX_UART5_Init(); 1366 MX_USART3_UART_Init(); 1367 MX_USB_DEVICE_Init(); 1368 MX_IWDG_Init(); /* GAP-3 FIX 2: start hardware watchdog (~4 s timeout) */ 1369 /* USER CODE BEGIN 2 */ 1370 1371 HAL_TIM_Base_Start(&htim1); 1372 1373 /* --- Enable DWT cycle counter for accurate microsecond delays --- */ 1374 DWT_Init(); 1375 1376 DIAG_SECTION("SYSTEM INIT"); 1377 DIAG("SYS", "DWT cycle counter initialized, TIM1 started"); 1378 DIAG("SYS", "HAL tick at init start: %lu ms", (unsigned long)HAL_GetTick()); 1379 1380 //Wait for OCXO 3mn 1381 DIAG("CLK", "OCXO warmup starting -- waiting 180 s (3 min)"); 1382 uint32_t ocxo_start = HAL_GetTick(); 1383 /* [GAP-3 FIX 2] Cannot use HAL_Delay(180000) — IWDG would reset MCU. 1384 * Instead loop in 1-second steps, kicking the watchdog each iteration. */ 1385 for (int ocxo_sec = 0; ocxo_sec < 180; ocxo_sec++) { 1386 HAL_IWDG_Refresh(&hiwdg); 1387 HAL_Delay(1000); 1388 } 1389 DIAG_ELAPSED("CLK", "OCXO warmup", ocxo_start); 1390 1391 DIAG_SECTION("AD9523 POWER SEQUENCING"); 1392 DIAG("PWR", "Asserting AD9523 reset (pin LOW)"); 1393 HAL_GPIO_WritePin(AD9523_RESET_GPIO_Port,AD9523_RESET_Pin,GPIO_PIN_RESET); 1394 1395 //Power sequencing AD9523 1396 DIAG("PWR", "Enabling 1.8V clock rail"); 1397 HAL_GPIO_WritePin(EN_P_1V8_CLOCK_GPIO_Port,EN_P_1V8_CLOCK_Pin,GPIO_PIN_SET); 1398 HAL_Delay(100); 1399 DIAG("PWR", "Enabling 3.3V clock rail"); 1400 HAL_GPIO_WritePin(EN_P_3V3_CLOCK_GPIO_Port,EN_P_3V3_CLOCK_Pin,GPIO_PIN_SET); 1401 HAL_Delay(100); 1402 DIAG("PWR", "Releasing AD9523 reset (pin HIGH)"); 1403 HAL_GPIO_WritePin(AD9523_RESET_GPIO_Port,AD9523_RESET_Pin,GPIO_PIN_SET); 1404 HAL_Delay(100); 1405 DIAG("PWR", "AD9523 power sequencing complete -- all rails up, reset released"); 1406 1407 //Set planned Clocks on AD9523 1408 /* 1409 o Channel 0 = 300MHz LVDS (ADF4382 TX) 1410 o Channel 1 = 300MHz LVDS (ADF4382 RX) (Phase aligned with Channel 0) 1411 o Channel 4 = 400MHz LVDS (ADC) 1412 o Channel 5 = 400MHz LVDS (FPGA_ADC)(Phase aligned with Channel 4) 1413 o Channel 6 = 100MHz LVCMOS (FPGA system clock) 1414 o Channel 7 = 20MHz LVCMOS (FPGA test) 1415 o Channel 8 = 60MHz LVDS (ADF4382 TX sync) 1416 o Channel 9 = 60MHz LVDS (ADF4382 RX sync)(Phase aligned with Channel 8) 1417 o Channel 10 = 120MHz LVCMOS 1418 o Channel 11 = 120MHz LVCMOS (Phase aligned with Channel 10) 1419 */ 1420 1421 1422 // Ensure stm32_spi.c and stm32_delay.c are compiled and linked 1423 1424 DIAG("CLK", "Calling configure_ad9523()..."); 1425 uint32_t ad9523_cfg_start = HAL_GetTick(); 1426 if (configure_ad9523() != 0) { 1427 // configuration error - handle as needed 1428 DIAG_ERR("CLK", "configure_ad9523() FAILED -- entering infinite halt loop"); 1429 while (1) { HAL_Delay(1000); } 1430 } 1431 DIAG_ELAPSED("CLK", "configure_ad9523()", ad9523_cfg_start); 1432 DIAG("CLK", "AD9523 configured successfully"); 1433 1434 //Power sequencing FPGA 1435 DIAG_SECTION("FPGA POWER SEQUENCING"); 1436 DIAG("PWR", "Enabling 1.0V FPGA rail"); 1437 HAL_GPIO_WritePin(EN_P_1V0_FPGA_GPIO_Port,EN_P_1V0_FPGA_Pin,GPIO_PIN_SET); 1438 HAL_Delay(100); 1439 DIAG("PWR", "Enabling 1.8V FPGA rail"); 1440 HAL_GPIO_WritePin(EN_P_1V8_FPGA_GPIO_Port,EN_P_1V8_FPGA_Pin,GPIO_PIN_SET); 1441 HAL_Delay(100); 1442 DIAG("PWR", "Enabling 3.3V FPGA rail"); 1443 HAL_GPIO_WritePin(EN_P_3V3_FPGA_GPIO_Port,EN_P_3V3_FPGA_Pin,GPIO_PIN_SET); 1444 HAL_Delay(100); 1445 DIAG("PWR", "FPGA power sequencing complete -- 1.0V -> 1.8V -> 3.3V"); 1446 1447 1448 // Initialize module IMU 1449 DIAG_SECTION("IMU INIT (GY-85)"); 1450 DIAG("IMU", "Initializing GY-85 IMU..."); 1451 if (!GY85_Init()) { 1452 DIAG_ERR("IMU", "GY85_Init() FAILED -- calling Error_Handler()"); 1453 Error_Handler(); 1454 } 1455 DIAG("IMU", "GY-85 initialized OK, running 10 calibration samples"); 1456 for(int i=0; i<10;i++){ 1457 if (!GY85_Update(&imu)) { 1458 Error_Handler(); 1459 } 1460 1461 ax = imu.ax; 1462 ay = imu.ay; 1463 az = imu.az; 1464 gx = -imu.gx; 1465 gy = -imu.gy; 1466 gz = imu.gz; 1467 mx = imu.mx; 1468 my = imu.my; 1469 mz = imu.mz; 1470 1471 ax *= 6.10351e-5; //2.0 / 32768.0; 1472 ay *= 6.10351e-5; 1473 az *= 6.10351e-5; 1474 1475 ax -= abias[0]; // Convert to g's, remove accelerometer biases 1476 ay -= abias[1]; 1477 az -= abias[2]; 1478 1479 gx *= 0.0152588f; //500.0 / 32768.0; 1480 gy *= 0.0152588f; 1481 gz *= 0.0152588f; 1482 1483 gx -= gbias[0]; // Convert to degrees per seconds, remove gyro biases 1484 gy -= gbias[1]; 1485 gz -= gbias[2]; 1486 1487 mx *= 6.10351e-5; //2.0 / 32768.0; 1488 my *= 6.10351e-5; 1489 mz *= 6.10351e-5; 1490 1491 mxc = M11*(mx-mbias[0]) + M12*(my-mbias[1]) +M13*(mz-mbias[2]); 1492 myc = M21*(mx-mbias[0]) + M22*(my-mbias[1]) +M23*(mz-mbias[2]); 1493 mzc = M31*(mx-mbias[0]) + M32*(my-mbias[1]) +M33*(mz-mbias[2]); 1494 1495 mx = mxc; 1496 my = myc; 1497 mz = mzc; 1498 1499 float norm = sqrt((mx*mx) + (my*my) + (mz*mz)); 1500 mx /=norm; 1501 my /=norm; 1502 mz /=norm; 1503 1504 /***************************************************************/ 1505 /*********************IMU Complementary Filter******************/ 1506 /***************************************************************/ 1507 RxAcc = ax; 1508 RyAcc = ay; 1509 RzAcc = az; 1510 1511 Rate_Ayz_1 = gx; 1512 Rate_Axz_1 = gy; 1513 Rate_Axy_1 = gz; 1514 1515 Rate_Ayz_1 = Rate_Ayz_1*0.01745;//Convertion from °/s to Radians/s 1516 Rate_Axz_1 = Rate_Axz_1*0.01745; 1517 Rate_Axy_1 = Rate_Axy_1*0.01745; 1518 1519 /*Combining Accelerometer & Gyroscope Data*/ 1520 Axz_0 = atan2(RxEst_0,RzEst_0); 1521 Ayz_0 = atan2(RyEst_0,RzEst_0); 1522 Axy_0 = atan2(RxEst_0,RyEst_0); 1523 1524 now_timeperiod = micros(); 1525 1526 Time_Period = now_timeperiod - lasttime_timeperiod; 1527 1528 Axz_1= Axz_0 + Rate_Axz_1*Time_Period*0.000001; 1529 Ayz_1= Ayz_0 + Rate_Ayz_1*Time_Period*0.000001; 1530 Axy_1= Axy_0 + Rate_Axy_1*Time_Period*0.000001; 1531 1532 lasttime_timeperiod = now_timeperiod; 1533 1534 RxGyro = sin(Axz_1)/(sqrt(1.0 + cos(Axz_1)*cos(Axz_1) * tan(Ayz_1)*tan(Ayz_1))); 1535 RyGyro = sin(Ayz_1)/(sqrt(1.0 + cos(Ayz_1)*cos(Ayz_1) * tan(Axz_1)*tan(Axz_1))); 1536 if(RzEst_0 >= 0){ 1537 RzGyro = 1.0*sqrt(1 - RxGyro*RxGyro - RyGyro*RyGyro); 1538 } 1539 else { 1540 RzGyro = -1*sqrt(1 - RxGyro*RxGyro - RyGyro*RyGyro); 1541 } 1542 1543 RxEst_1 = RxAcc*0.5 + RxGyro*0.5 ;// Weight of Gyro. over Acc. 1544 RyEst_1 = RyAcc*0.5 + RyGyro*0.5 ; 1545 RzEst_1 = RzAcc*0.5 + RzGyro*0.5 ; 1546 1547 R_Est = sqrt(RxEst_1*RxEst_1+RyEst_1*RyEst_1+RzEst_1*RzEst_1); 1548 1549 Pitch_Sensor = atan2(RxEst_1,sqrt(RyEst_1*RyEst_1)+(RzEst_1*RzEst_1))*180/PI; 1550 Roll_Sensor = atan2(RyEst_1,sqrt(RxEst_1*RxEst_1)+(RzEst_1*RzEst_1))*180/PI; 1551 1552 float magRawX = mx*cos(Pitch_Sensor*PI/180.0f) - mz*sin(Pitch_Sensor*PI/180.0f); 1553 float magRawY = mx*sin(Roll_Sensor*PI/180.0f)*sin(Pitch_Sensor*PI/180.0f) + my*cos(Roll_Sensor*PI/180.0f)- mz*sin(Roll_Sensor*PI/180.0f)*cos(Pitch_Sensor*PI/180.0f); 1554 Yaw_Sensor = (180*atan2(magRawY,magRawX)/PI) - Mag_Declination; 1555 1556 if(Yaw_Sensor<0)Yaw_Sensor+=360; 1557 RxEst_0 = RxEst_1; 1558 RyEst_0 = RyEst_1; 1559 RzEst_0 = RzEst_1; 1560 1561 HAL_Delay(300); 1562 1563 } 1564 1565 /////////////////////////////////////////////////////////////////////////////////// 1566 ///////////////////////////////////BAROMETER BMP180//////////////////////////////// 1567 /////////////////////////////////////////////////////////////////////////////////// 1568 DIAG_SECTION("BAROMETER INIT (BMP180)"); 1569 DIAG("IMU", "Reading 5 barometer samples for altitude baseline"); 1570 for(int i = 0; i<5 ; i++){ 1571 float BMP_Perssure = myBMP.getPressure(); 1572 RADAR_Altitude = 44330*(1-(pow((BMP_Perssure/101325),(1/5.255)))); 1573 HAL_Delay(100); 1574 } 1575 DIAG("IMU", "Barometer init complete, RADAR_Altitude baseline set"); 1576 1577 /////////////////////////////////////////////////////////////////////////////////// 1578 ///////////////////////////////////////ADF4382///////////////////////////////////// 1579 /////////////////////////////////////////////////////////////////////////////////// 1580 DIAG_SECTION("ADF4382A LO INIT"); 1581 printf("Starting ADF4382A Radar LO System...\n"); 1582 printf("Using SPI4 with TIMED SYNCHRONIZATION (60 MHz clocks)\n"); 1583 1584 // Initialize LO manager with TIMED synchronization 1585 DIAG("LO", "Calling ADF4382A_Manager_Init(sync=SYNC_METHOD_TIMED)"); 1586 uint32_t lo_init_start = HAL_GetTick(); 1587 int ret = ADF4382A_Manager_Init(&lo_manager, SYNC_METHOD_TIMED); 1588 DIAG("LO", "ADF4382A_Manager_Init returned %d (took %lu ms)", 1589 ret, (unsigned long)(HAL_GetTick() - lo_init_start)); 1590 1591 /* [Bug #4 FIXED] Check init return code BEFORE calling phase shift. 1592 * Previously SetPhaseShift/Strobe were called before this check. */ 1593 if (ret != ADF4382A_MANAGER_OK) { 1594 printf("LO Manager initialization failed: %d\n", ret); 1595 DIAG_ERR("LO", "Manager init FAILED (ret=%d) -- calling Error_Handler()", ret); 1596 Error_Handler(); 1597 } 1598 1599 // Set phase shift (e.g., 500 ps for TX, 500 ps for RX) 1600 int ps_ret = ADF4382A_SetPhaseShift(&lo_manager, 500, 500); 1601 DIAG("LO", "ADF4382A_SetPhaseShift(500, 500) returned %d", ps_ret); 1602 1603 // Strobe to apply phase shifts 1604 int strobe_tx_ret = ADF4382A_StrobePhaseShift(&lo_manager, 0); // TX device 1605 int strobe_rx_ret = ADF4382A_StrobePhaseShift(&lo_manager, 1); // RX device 1606 DIAG("LO", "StrobePhaseShift TX returned %d, RX returned %d", strobe_tx_ret, strobe_rx_ret); 1607 1608 // Check initial lock status 1609 bool tx_locked, rx_locked; 1610 DIAG("LO", "Checking initial lock status..."); 1611 ret = ADF4382A_CheckLockStatus(&lo_manager, &tx_locked, &rx_locked); 1612 if (ret == ADF4382A_MANAGER_OK) { 1613 printf("Initial Lock Status - TX: %s, RX: %s\n", 1614 tx_locked ? "LOCKED" : "UNLOCKED", 1615 rx_locked ? "LOCKED" : "UNLOCKED"); 1616 DIAG("LO", "Initial lock: TX=%s RX=%s", tx_locked ? "LOCKED" : "UNLOCKED", rx_locked ? "LOCKED" : "UNLOCKED"); 1617 } else { 1618 DIAG_ERR("LO", "CheckLockStatus returned %d", ret); 1619 } 1620 // Wait for both LOs to lock 1621 DIAG("LO", "Entering lock-wait loop (max 10 s = 100 x 100 ms)"); 1622 uint32_t lock_wait_start = HAL_GetTick(); 1623 uint32_t lock_timeout = 0; 1624 while (!(tx_locked && rx_locked) && lock_timeout < 100) { 1625 HAL_Delay(100); 1626 ADF4382A_CheckLockStatus(&lo_manager, &tx_locked, &rx_locked); 1627 lock_timeout++; 1628 1629 if (lock_timeout % 10 == 0) { 1630 printf("Waiting for LO lock... TX: %s, RX: %s\n", 1631 tx_locked ? "LOCKED" : "UNLOCKED", 1632 rx_locked ? "LOCKED" : "UNLOCKED"); 1633 DIAG("LO", "Lock poll #%lu: TX=%s RX=%s", 1634 (unsigned long)lock_timeout, 1635 tx_locked ? "LOCKED" : "UNLOCKED", 1636 rx_locked ? "LOCKED" : "UNLOCKED"); 1637 } 1638 } 1639 DIAG_ELAPSED("LO", "Lock wait loop", lock_wait_start); 1640 1641 if (tx_locked && rx_locked) { 1642 printf("Both LOs locked successfully!\n"); 1643 printf("Synchronization ready - 60 MHz clocks on SYNCP/SYNCN pins\n"); 1644 DIAG("LO", "Both LOs LOCKED after %lu iterations", (unsigned long)lock_timeout); 1645 // - 60 MHz phase-aligned clocks on SYNCP/SYNCN pins 1646 // - SYNC pin connected for triggering 1647 1648 // When ready to synchronize: 1649 DIAG("LO", "Calling TriggerTimedSync to pulse sw_sync on both PLLs"); 1650 ADF4382A_TriggerTimedSync(&lo_manager); 1651 // At this point, the SYNC pin can be toggled to trigger synchronization 1652 } else { 1653 printf("LO lock timeout! TX: %s, RX: %s\n", 1654 tx_locked ? "LOCKED" : "UNLOCKED", 1655 rx_locked ? "LOCKED" : "UNLOCKED"); 1656 DIAG_ERR("LO", "Lock TIMEOUT after %lu iterations! TX=%s RX=%s", 1657 (unsigned long)lock_timeout, 1658 tx_locked ? "LOCKED" : "UNLOCKED", 1659 rx_locked ? "LOCKED" : "UNLOCKED"); 1660 } 1661 1662 // check if there is a lock via direct GPIO (independent of register read above) 1663 DIAG("LO", "Direct GPIO lock detect pins:"); 1664 DIAG_GPIO("LO", "ADF4382_TX_LKDET", ADF4382_TX_LKDET_GPIO_Port, ADF4382_TX_LKDET_Pin); 1665 DIAG_GPIO("LO", "ADF4382_RX_LKDET", ADF4382_RX_LKDET_GPIO_Port, ADF4382_RX_LKDET_Pin); 1666 if(HAL_GPIO_ReadPin (ADF4382_TX_LKDET_GPIO_Port, ADF4382_TX_LKDET_Pin)) 1667 { 1668 // Set The LED_1 ON! 1669 HAL_GPIO_WritePin(LED_1_GPIO_Port, LED_1_Pin, GPIO_PIN_SET); 1670 DIAG("LO", "TX lock detected via GPIO -- LED_1 ON"); 1671 } 1672 else 1673 { 1674 // Else .. Turn LED_1 OFF! 1675 HAL_GPIO_WritePin(LED_1_GPIO_Port, LED_1_Pin, GPIO_PIN_RESET); 1676 DIAG_WARN("LO", "TX NOT locked via GPIO -- LED_1 OFF"); 1677 } 1678 1679 if(HAL_GPIO_ReadPin (ADF4382_RX_LKDET_GPIO_Port, ADF4382_RX_LKDET_Pin)) 1680 { 1681 // Set The LED_2 ON! 1682 HAL_GPIO_WritePin(LED_2_GPIO_Port, LED_2_Pin, GPIO_PIN_SET); 1683 DIAG("LO", "RX lock detected via GPIO -- LED_2 ON"); 1684 } 1685 else 1686 { 1687 // Else .. Turn LED_2 OFF! 1688 HAL_GPIO_WritePin(LED_2_GPIO_Port, LED_2_Pin, GPIO_PIN_RESET); 1689 DIAG_WARN("LO", "RX NOT locked via GPIO -- LED_2 OFF"); 1690 } 1691 1692 1693 ////////////////////////////////////////////////////////////////////////////////////// 1694 /////////////////////////////////////ADAR1000///////////////////////////////////////// 1695 ////////////////////////////////////////////////////////////////////////////////////// 1696 1697 //Power sequencing ADAR1000 1698 DIAG_SECTION("ADAR1000 POWER SEQUENCING"); 1699 1700 //Tell FPGA to turn off TX RF signal by disabling Mixers 1701 DIAG("BF", "Disabling TX mixers (GPIOD pin 11 LOW)"); 1702 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_11, GPIO_PIN_RESET); 1703 1704 DIAG("PWR", "Enabling 3.3V ADAR12 + ADAR34 rails"); 1705 HAL_GPIO_WritePin(EN_P_3V3_ADAR12_GPIO_Port,EN_P_3V3_ADAR12_Pin,GPIO_PIN_SET); 1706 HAL_GPIO_WritePin(EN_P_3V3_ADAR34_GPIO_Port,EN_P_3V3_ADAR34_Pin,GPIO_PIN_SET); 1707 HAL_Delay(500); 1708 DIAG("PWR", "Enabling 5.0V ADAR rail"); 1709 HAL_GPIO_WritePin(EN_P_5V0_ADAR_GPIO_Port,EN_P_5V0_ADAR_Pin,GPIO_PIN_SET); 1710 HAL_Delay(500); 1711 DIAG("PWR", "ADAR1000 power sequencing complete"); 1712 1713 // System startup message 1714 uint8_t startup_msg[] = "Starting Phased Array RADAR System...\r\n"; 1715 HAL_UART_Transmit(&huart3, startup_msg, sizeof(startup_msg)-1, 1000); 1716 1717 DIAG("BF", "Calling systemPowerUpSequence()"); 1718 // Power up sequence 1719 systemPowerUpSequence(); 1720 1721 DIAG("BF", "Calling initializeBeamMatrices()"); 1722 // Initialize beam matrices 1723 initializeBeamMatrices(); 1724 1725 // Print system status 1726 printSystemStatus(); 1727 DIAG("SYS", "System init complete -- entering main loop"); 1728 1729 ////////////////////////////////////////////////////////////////////////////////////// 1730 //////////////////////////////////////////GPS///////////////////////////////////////// 1731 ////////////////////////////////////////////////////////////////////////////////////// 1732 for(int i=0; i<10;i++){ 1733 smartDelay(1000); 1734 RADAR_Longitude = gps.location.lng(); 1735 RADAR_Latitude = gps.location.lat(); 1736 } 1737 1738 //move Stepper to position 1 = 0° 1739 HAL_GPIO_WritePin(STEPPER_CW_P_GPIO_Port, STEPPER_CW_P_Pin, GPIO_PIN_RESET);//Set stepper motor spinning direction to CCW 1740 //Point Stepper to North 1741 for(int i= 0;i<(int)(Yaw_Sensor*Stepper_steps/360);i++){ 1742 HAL_GPIO_WritePin(STEPPER_CLK_P_GPIO_Port, STEPPER_CLK_P_Pin, GPIO_PIN_SET); 1743 delay_us(500); 1744 HAL_GPIO_WritePin(STEPPER_CLK_P_GPIO_Port, STEPPER_CLK_P_Pin, GPIO_PIN_RESET); 1745 delay_us(500); 1746 } 1747 1748 /***************************************************************/ 1749 /**********wait for GUI start flag and Send Lat/Long/alt********/ 1750 /***************************************************************/ 1751 1752 GPS_Data_t gps_data; 1753 // Binary packet structure: 1754 // [Header 4 bytes][Latitude 8 bytes][Longitude 8 bytes][Altitude 4 bytes][Pitch 4 bytes][CRC 2 bytes] 1755 gps_data = {RADAR_Latitude, RADAR_Longitude, RADAR_Altitude, Pitch_Sensor, HAL_GetTick()}; 1756 if (!GPS_SendBinaryToGUI(&gps_data)) { 1757 const uint8_t gps_send_error[] = "GPS binary send failed\r\n"; 1758 HAL_UART_Transmit(&huart3, (uint8_t*)gps_send_error, sizeof(gps_send_error) - 1, 1000); 1759 } 1760 1761 // Check if start flag was received and settings are ready 1762 do{ 1763 if (usbHandler.isStartFlagReceived() && 1764 usbHandler.getState() == USBHandler::USBState::READY_FOR_DATA) { 1765 1766 const RadarSettings& settings = usbHandler.getSettings(); 1767 1768 // Use the settings to configure your radar system 1769 /* 1770 settings.getSystemFrequency(); 1771 settings.getChirpDuration1(); 1772 settings.getChirpDuration2(); 1773 settings.getChirpsPerPosition(); 1774 settings.getFreqMin(); 1775 settings.getFreqMax(); 1776 settings.getPRF1(); 1777 settings.getPRF2(); 1778 settings.getMaxDistance(); 1779 */ 1780 1781 1782 } 1783 }while(!usbHandler.isStartFlagReceived()); 1784 1785 /***************************************************************/ 1786 /************RF Power Amplifier Powering up sequence************/ 1787 /***************************************************************/ 1788 if(PowerAmplifier){ 1789 DIAG_SECTION("PA: RF Power Amplifier power-up sequence"); 1790 /* Initialize DACs */ 1791 /* DAC1: Address 0b1001000 = 0x48 */ 1792 DIAG("PA", "Initializing DAC1 (I2C1, addr=0x48, 8-bit)"); 1793 if (!DAC5578_Init(&hdac1, &hi2c1, 0x48, 8, 1794 DAC_1_VG_LDAC_GPIO_Port, DAC_1_VG_LDAC_Pin, 1795 DAC_1_VG_CLR_GPIO_Port, DAC_1_VG_CLR_Pin)) { 1796 DIAG_ERR("PA", "DAC1 init FAILED -- calling Error_Handler()"); 1797 Error_Handler(); 1798 } 1799 DIAG("PA", "DAC1 init OK"); 1800 1801 /* DAC2: Address 0b1001001 = 0x49 */ 1802 DIAG("PA", "Initializing DAC2 (I2C1, addr=0x49, 8-bit)"); 1803 if (!DAC5578_Init(&hdac2, &hi2c1, 0x49, 8, 1804 DAC_2_VG_LDAC_GPIO_Port, DAC_2_VG_LDAC_Pin, 1805 DAC_2_VG_CLR_GPIO_Port, DAC_2_VG_CLR_Pin)) { 1806 DIAG_ERR("PA", "DAC2 init FAILED -- calling Error_Handler()"); 1807 Error_Handler(); 1808 } 1809 DIAG("PA", "DAC2 init OK"); 1810 1811 /* Configure clear code behavior */ 1812 DIAG("PA", "Setting clear code to ZERO on both DACs"); 1813 DAC5578_SetClearCode(&hdac1, DAC5578_CLR_CODE_ZERO); // Clear to 0V on CLR pulse 1814 DAC5578_SetClearCode(&hdac2, DAC5578_CLR_CODE_ZERO); // Clear to 0V on CLR pulse 1815 1816 /* Configure LDAC so all channels update simultaneously on hardware LDAC */ 1817 DIAG("PA", "Setting LDAC mask=0xFF on both DACs (all channels respond)"); 1818 DAC5578_SetupLDAC(&hdac1, 0xFF); // All channels respond to LDAC 1819 DAC5578_SetupLDAC(&hdac2, 0xFF); // All channels respond to LDAC 1820 1821 //set Vg [1-8] to -3.98V -> input opamp = 1.63058V->126(8bits) 1822 DIAG("PA", "Writing initial DAC_val=%d to DAC1 channels 0-7", DAC_val); 1823 for(int channel = 0; channel < 8; channel++){ 1824 DAC5578_WriteAndUpdateChannelValue(&hdac1, channel, DAC_val); 1825 } 1826 1827 //set Vg [9-16] to -3.98V -> input opamp = 1.63058V->126(8bits) 1828 DIAG("PA", "Writing initial DAC_val=%d to DAC2 channels 0-7", DAC_val); 1829 for(int channel = 0; channel < 8; channel++){ 1830 DAC5578_WriteAndUpdateChannelValue(&hdac2, channel, DAC_val); 1831 } 1832 1833 /* Optional: Use hardware LDAC for simultaneous update of all channels */ 1834 DIAG("PA", "Pulsing LDAC on both DACs for simultaneous update"); 1835 HAL_GPIO_WritePin(DAC_1_VG_LDAC_GPIO_Port, DAC_1_VG_LDAC_Pin, GPIO_PIN_RESET); 1836 HAL_GPIO_WritePin(DAC_2_VG_LDAC_GPIO_Port, DAC_2_VG_LDAC_Pin, GPIO_PIN_RESET); 1837 HAL_Delay(1); 1838 HAL_GPIO_WritePin(DAC_1_VG_LDAC_GPIO_Port, DAC_1_VG_LDAC_Pin, GPIO_PIN_SET); 1839 HAL_GPIO_WritePin(DAC_2_VG_LDAC_GPIO_Port, DAC_2_VG_LDAC_Pin, GPIO_PIN_SET); 1840 1841 //Enable RF Power Amplifier VDD = 22V 1842 DIAG("PA", "Enabling RFPA VDD=22V (EN_DIS_RFPA_VDD HIGH)"); 1843 HAL_GPIO_WritePin(EN_DIS_RFPA_VDD_GPIO_Port, EN_DIS_RFPA_VDD_Pin, GPIO_PIN_SET); 1844 1845 /* Initialize ADCs with correct addresses */ 1846 /* ADC1: Address 0x48, Single-Ended mode, Internal Ref ON + ADC ON */ 1847 DIAG("PA", "Initializing ADC1 (I2C2, addr=0x48, single-ended, ref+adc ON)"); 1848 if (!ADS7830_Init(&hadc1, &hi2c2, 0x48, 1849 ADS7830_SDMODE_SINGLE, ADS7830_PDIRON_ADON)) { 1850 DIAG_ERR("PA", "ADC1 init FAILED -- calling Error_Handler()"); 1851 Error_Handler(); 1852 } 1853 DIAG("PA", "ADC1 init OK"); 1854 1855 /* ADC2: Address 0x4A, Single-Ended mode, Internal Ref ON + ADC ON */ 1856 DIAG("PA", "Initializing ADC2 (I2C2, addr=0x4A, single-ended, ref+adc ON)"); 1857 if (!ADS7830_Init(&hadc2, &hi2c2, 0x4A, 1858 ADS7830_SDMODE_SINGLE, ADS7830_PDIRON_ADON)) { 1859 DIAG_ERR("PA", "ADC2 init FAILED -- calling Error_Handler()"); 1860 Error_Handler(); 1861 } 1862 DIAG("PA", "ADC2 init OK"); 1863 1864 /* Read all 8 channels from ADC1 and calculate Idq */ 1865 DIAG("PA", "Reading initial Idq from ADC1 channels 0-7"); 1866 for (uint8_t channel = 0; channel < 8; channel++) { 1867 adc1_readings[channel] = ADS7830_Measure_SingleEnded(&hadc1, channel); 1868 Idq_reading[channel]= (3.3/255)*adc1_readings[channel]/(50*0.005);//Idq=Vadc/(GxRshunt)//G_INA241A3=50;Rshunt=5mOhms 1869 DIAG("PA", " ADC1 ch%d: raw=%d Idq=%.3fA", channel, adc1_readings[channel], Idq_reading[channel]); 1870 } 1871 1872 /* Read all 8 channels from ADC2 and calculate Idq*/ 1873 DIAG("PA", "Reading initial Idq from ADC2 channels 0-7"); 1874 for (uint8_t channel = 0; channel < 8; channel++) { 1875 adc2_readings[channel] = ADS7830_Measure_SingleEnded(&hadc2, channel); 1876 Idq_reading[channel+8]= (3.3/255)*adc2_readings[channel]/(50*0.005);//Idq=Vadc/(GxRshunt)//G_INA241A3=50;Rshunt=5mOhms 1877 DIAG("PA", " ADC2 ch%d: raw=%d Idq=%.3fA", channel, adc2_readings[channel], Idq_reading[channel+8]); 1878 } 1879 1880 DIAG("PA", "Starting Idq calibration loop for DAC1 channels 0-7 (target=1.680A)"); 1881 for (uint8_t channel = 0; channel < 8; channel++){ 1882 uint8_t safety_counter = 0; 1883 DAC_val = 126; // Reset for each channel 1884 1885 do { 1886 if (safety_counter++ > 50) { // Prevent infinite loop 1887 DIAG_WARN("PA", " DAC1 ch%d: safety limit reached (50 iterations), DAC_val=%d Idq=%.3fA", 1888 channel, DAC_val, Idq_reading[channel]); 1889 break; 1890 } 1891 DAC_val = DAC_val - 4; 1892 DAC5578_WriteAndUpdateChannelValue(&hdac1, channel, DAC_val); 1893 adc1_readings[channel] = ADS7830_Measure_SingleEnded(&hadc1, channel); 1894 Idq_reading[channel] = (3.3/255) * adc1_readings[channel] / (50 * 0.005); 1895 } while (DAC_val > 38 && abs(Idq_reading[channel] - 1.680) > 0.2); // B12 fix: loop while FAR from target 1896 DIAG("PA", " DAC1 ch%d calibrated: DAC_val=%d Idq=%.3fA iters=%d", 1897 channel, DAC_val, Idq_reading[channel], safety_counter); 1898 } 1899 1900 DIAG("PA", "Starting Idq calibration loop for DAC2 channels 0-7 (target=1.680A)"); 1901 for (uint8_t channel = 0; channel < 8; channel++){ 1902 uint8_t safety_counter = 0; 1903 DAC_val = 126; // Reset for each channel 1904 1905 do { 1906 if (safety_counter++ > 50) { // Prevent infinite loop 1907 DIAG_WARN("PA", " DAC2 ch%d: safety limit reached (50 iterations), DAC_val=%d Idq=%.3fA", 1908 channel, DAC_val, Idq_reading[channel+8]); 1909 break; 1910 } 1911 DAC_val = DAC_val - 4; 1912 DAC5578_WriteAndUpdateChannelValue(&hdac2, channel, DAC_val); 1913 adc2_readings[channel] = ADS7830_Measure_SingleEnded(&hadc2, channel); // B13 fix: was adc1_readings 1914 Idq_reading[channel+8] = (3.3/255) * adc2_readings[channel] / (50 * 0.005); 1915 } while (DAC_val > 38 && abs(Idq_reading[channel+8] - 1.680) > 0.2); // B12 fix: loop while FAR from target 1916 DIAG("PA", " DAC2 ch%d calibrated: DAC_val=%d Idq=%.3fA iters=%d", 1917 channel, DAC_val, Idq_reading[channel+8], safety_counter); 1918 } 1919 DIAG("PA", "PA IDQ calibration sequence COMPLETE"); 1920 } 1921 1922 //RESET FPGA 1923 DIAG("FPGA", "Resetting FPGA (GPIOD pin 12: LOW -> 10ms -> HIGH)"); 1924 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET); 1925 HAL_Delay(10); 1926 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET); 1927 DIAG("FPGA", "FPGA reset complete"); 1928 1929 1930 1931 //Tell FPGA to apply TX RF by enabling Mixers 1932 DIAG("FPGA", "Enabling TX mixers (GPIOD pin 11 HIGH)"); 1933 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_11, GPIO_PIN_SET); 1934 1935 /* T°C sensor TMP37 ADC3: Address 0x49, Single-Ended mode, Internal Ref ON + ADC ON */ 1936 DIAG("SYS", "Initializing temperature sensor ADC3 (I2C2, addr=0x49, TMP37)"); 1937 if (!ADS7830_Init(&hadc3, &hi2c2, 0x49, 1938 ADS7830_SDMODE_SINGLE, ADS7830_PDIRON_ADON)) { 1939 DIAG_ERR("SYS", "Temperature sensor ADC3 init FAILED -- calling Error_Handler()"); 1940 Error_Handler(); 1941 } 1942 DIAG("SYS", "Temperature sensor ADC3 init OK"); 1943 1944 /***************************************************************/ 1945 /************************ERRORS HANDLERS************************/ 1946 /***************************************************************/ 1947 1948 // Initialize error handler system 1949 DIAG("SYS", "Initializing error handler: clearing error_count, last_error, emergency_state"); 1950 error_count = 0; 1951 last_error = ERROR_NONE; 1952 system_emergency_state = false; 1953 1954 /***************************************************************/ 1955 /*********************SEND TO GUI STATUS************************/ 1956 /***************************************************************/ 1957 1958 // Send initial status to GUI 1959 DIAG("USB", "Sending initial system status to GUI via USB CDC"); 1960 char initial_status[500]; 1961 getSystemStatusForGUI(initial_status, sizeof(initial_status)); 1962 // Send via USB to GUI 1963 CDC_Transmit_FS((uint8_t*)initial_status, strlen(initial_status)); 1964 DIAG("USB", "Initial status sent (%d bytes)", (int)strlen(initial_status)); 1965 1966 DIAG("SYS", "=== INIT COMPLETE -- entering main loop ==="); 1967 1968 1969 1970 1971 1972 1973 // main loop 1974 1975 /* USER CODE END 2 */ 1976 1977 /* Infinite loop */ 1978 /* USER CODE BEGIN WHILE */ 1979 while (1) 1980 { 1981 ////////////////////////////////////////////////////////////////////////////////////// 1982 //////////////////////// Check system health at the start of each loop//////////////// 1983 ////////////////////////////////////////////////////////////////////////////////////// 1984 1985 if (!checkSystemHealthStatus()) { 1986 // System is in bad state, enter safe mode 1987 //Tell FPGA to turn off TX RF signal by disabling Mixers 1988 DIAG_ERR("SYS", "checkSystemHealthStatus() FAILED -- entering SAFE MODE"); 1989 DIAG("SYS", "Disabling TX mixers (GPIOD pin 11 LOW)"); 1990 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_11, GPIO_PIN_RESET); 1991 DIAG("SYS", "Calling systemPowerDownSequence()"); 1992 systemPowerDownSequence(); 1993 1994 char emergency_msg[] = "SYSTEM IN SAFE MODE - Manual intervention required\r\n"; 1995 HAL_UART_Transmit(&huart3, (uint8_t*)emergency_msg, strlen(emergency_msg), 1000); 1996 DIAG_ERR("SYS", "SAFE MODE ACTIVE -- blinking all LEDs, waiting for system_emergency_state clear"); 1997 1998 // Blink all LEDs to indicate safe mode 1999 while (system_emergency_state) { 2000 HAL_GPIO_TogglePin(LED_1_GPIO_Port, LED_1_Pin); 2001 HAL_GPIO_TogglePin(LED_2_GPIO_Port, LED_2_Pin); 2002 HAL_GPIO_TogglePin(LED_3_GPIO_Port, LED_3_Pin); 2003 HAL_GPIO_TogglePin(LED_4_GPIO_Port, LED_4_Pin); 2004 } 2005 DIAG("SYS", "Exited safe mode blink loop -- system_emergency_state cleared"); 2006 } 2007 ////////////////////////////////////////////////////////////////////////////////////// 2008 ////////////////////////// Monitor ADF4382A lock status periodically////////////////// 2009 ////////////////////////////////////////////////////////////////////////////////////// 2010 2011 // Monitor lock status periodically 2012 static uint32_t last_check = 0; 2013 if (HAL_GetTick() - last_check > 5000) { 2014 ADF4382A_CheckLockStatus(&lo_manager, &tx_locked, &rx_locked); 2015 2016 if (!tx_locked || !rx_locked) { 2017 printf("LO Lock Lost! TX: %s, RX: %s\n", 2018 tx_locked ? "LOCKED" : "UNLOCKED", 2019 rx_locked ? "LOCKED" : "UNLOCKED"); 2020 DIAG_ERR("LO", "Lock LOST in main loop! TX=%s RX=%s", 2021 tx_locked ? "LOCKED" : "UNLOCKED", 2022 rx_locked ? "LOCKED" : "UNLOCKED"); 2023 DIAG_GPIO("LO", "TX_LKDET (direct)", ADF4382_TX_LKDET_GPIO_Port, ADF4382_TX_LKDET_Pin); 2024 DIAG_GPIO("LO", "RX_LKDET (direct)", ADF4382_RX_LKDET_GPIO_Port, ADF4382_RX_LKDET_Pin); 2025 } else { 2026 DIAG("LO", "Lock poll OK: TX=LOCKED RX=LOCKED"); 2027 } 2028 2029 last_check = HAL_GetTick(); 2030 } 2031 ////////////////////////////////////////////////////////////////////////////////////// 2032 ////////////////////////// Monitor Temperature Sensors periodically////////////////// 2033 ////////////////////////////////////////////////////////////////////////////////////// 2034 /* Read all 8 channels from ADC2 and calculate Idq*/ 2035 // Monitor T°C periodically 2036 static uint32_t last_check1 = 0; 2037 if (HAL_GetTick() - last_check1 > 5000) { 2038 //TMP37 3.3V-->165°C & ADS7830 3.3V-->255 => Temperature_n °C = ADC_val_n * 165/255 2039 Temperature_1 = ADS7830_Measure_SingleEnded(&hadc3, 0)*0.64705f; 2040 Temperature_2 = ADS7830_Measure_SingleEnded(&hadc3, 1)*0.64705f; 2041 Temperature_3 = ADS7830_Measure_SingleEnded(&hadc3, 2)*0.64705f; 2042 Temperature_4 = ADS7830_Measure_SingleEnded(&hadc3, 3)*0.64705f; 2043 Temperature_5 = ADS7830_Measure_SingleEnded(&hadc3, 4)*0.64705f; 2044 Temperature_6 = ADS7830_Measure_SingleEnded(&hadc3, 5)*0.64705f; 2045 Temperature_7 = ADS7830_Measure_SingleEnded(&hadc3, 6)*0.64705f; 2046 Temperature_8 = ADS7830_Measure_SingleEnded(&hadc3, 7)*0.64705f; 2047 2048 DIAG("PA", "Temps: T1=%.1f T2=%.1f T3=%.1f T4=%.1f T5=%.1f T6=%.1f T7=%.1f T8=%.1f", 2049 (double)Temperature_1, (double)Temperature_2, (double)Temperature_3, (double)Temperature_4, 2050 (double)Temperature_5, (double)Temperature_6, (double)Temperature_7, (double)Temperature_8); 2051 2052 /* [GAP-3 FIX 3] Populate `temperature` with hottest sensor reading. 2053 * checkSystemHealth() uses `temperature` for the >75 °C overtemp check; 2054 * previously it was uninitialized. */ 2055 { 2056 float temps[8] = { Temperature_1, Temperature_2, Temperature_3, Temperature_4, 2057 Temperature_5, Temperature_6, Temperature_7, Temperature_8 }; 2058 temperature = temps[0]; 2059 for (int ti = 1; ti < 8; ti++) { 2060 if (temps[ti] > temperature) temperature = temps[ti]; 2061 } 2062 DIAG("PA", "System temperature (max of 8 sensors) = %.1f C", (double)temperature); 2063 } 2064 2065 //(20 mV/°C on TMP37) QPA2962 RF amplifier Operating Temp. Range, TBASE min−40 normal+25 max+85 °C 2066 int Max_Temp = 25; 2067 if((Temperature_1>Max_Temp)||(Temperature_2>Max_Temp)||(Temperature_3>Max_Temp)||(Temperature_4>Max_Temp) 2068 ||(Temperature_5>Max_Temp)||(Temperature_6>Max_Temp)||(Temperature_7>Max_Temp)||(Temperature_8>Max_Temp)) 2069 { 2070 HAL_GPIO_WritePin(EN_DIS_COOLING_GPIO_Port, EN_DIS_COOLING_Pin, GPIO_PIN_SET); 2071 DIAG_WARN("PA", "Over-temp detected (>%d C) -- cooling ENABLED", Max_Temp); 2072 } 2073 else{ 2074 HAL_GPIO_WritePin(EN_DIS_COOLING_GPIO_Port, EN_DIS_COOLING_Pin, GPIO_PIN_RESET); 2075 } 2076 2077 /* [GAP-3 FIX 4] Periodic IDQ re-read — the Idq_reading[] array was only 2078 * populated during startup/calibration. checkSystemHealth() compares 2079 * stale values for overcurrent (>2.5 A) and bias fault (<0.1 A) checks. 2080 * Re-read all 16 channels every 5 s alongside temperature. */ 2081 if (PowerAmplifier) { 2082 DIAG("PA", "Periodic IDQ re-read (ADC1 + ADC2, 16 channels)"); 2083 for (uint8_t ch = 0; ch < 8; ch++) { 2084 adc1_readings[ch] = ADS7830_Measure_SingleEnded(&hadc1, ch); 2085 Idq_reading[ch] = (3.3f/255.0f) * adc1_readings[ch] / (50.0f * 0.005f); 2086 } 2087 for (uint8_t ch = 0; ch < 8; ch++) { 2088 adc2_readings[ch] = ADS7830_Measure_SingleEnded(&hadc2, ch); 2089 Idq_reading[ch + 8] = (3.3f/255.0f) * adc2_readings[ch] / (50.0f * 0.005f); 2090 } 2091 DIAG("PA", "IDQ[0..3]=%.3f %.3f %.3f %.3f [4..7]=%.3f %.3f %.3f %.3f", 2092 (double)Idq_reading[0], (double)Idq_reading[1], 2093 (double)Idq_reading[2], (double)Idq_reading[3], 2094 (double)Idq_reading[4], (double)Idq_reading[5], 2095 (double)Idq_reading[6], (double)Idq_reading[7]); 2096 DIAG("PA", "IDQ[8..11]=%.3f %.3f %.3f %.3f [12..15]=%.3f %.3f %.3f %.3f", 2097 (double)Idq_reading[8], (double)Idq_reading[9], 2098 (double)Idq_reading[10], (double)Idq_reading[11], 2099 (double)Idq_reading[12], (double)Idq_reading[13], 2100 (double)Idq_reading[14], (double)Idq_reading[15]); 2101 } 2102 2103 2104 /* [BUG #6 FIXED] Was 'last_check' — now correctly writes 'last_check1' 2105 * so the temperature timer runs independently of the lock-check timer. */ 2106 last_check1 = HAL_GetTick(); 2107 } 2108 ////////////////////////////////////////////////////////////////////////////////////// 2109 /////////////////////////////////////ADAR1000///////////////////////////////////////// 2110 ////////////////////////////////////////////////////////////////////////////////////// 2111 //phase_step = 0 => phase = 0° 2112 //phase_step = 127 => phase = 360° 2113 //steering angle (rad)= arcsin(phase_dif/Pi) 2114 2115 runRadarPulseSequence(); 2116 2117 /* [GAP-3 FIX 2] Kick hardware watchdog — if we don't reach here within 2118 * ~4 s, the IWDG resets the MCU automatically. */ 2119 HAL_IWDG_Refresh(&hiwdg); 2120 2121 // Optional: Add system monitoring here 2122 // Check temperatures, power levels, etc. 2123 2124 2125 /* USER CODE END WHILE */ 2126 2127 2128 2129 2130 /* USER CODE BEGIN 3 */ 2131 } 2132 /* USER CODE END 3 */ 2133 } 2134 2135 /** 2136 * @brief System Clock Configuration 2137 * @retval None 2138 */ 2139 void SystemClock_Config(void) 2140 { 2141 RCC_OscInitTypeDef RCC_OscInitStruct = {0}; 2142 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; 2143 2144 /** Configure LSE Drive Capability 2145 */ 2146 HAL_PWR_EnableBkUpAccess(); 2147 2148 /** Configure the main internal regulator output voltage 2149 */ 2150 __HAL_RCC_PWR_CLK_ENABLE(); 2151 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3); 2152 2153 /** Initializes the RCC Oscillators according to the specified parameters 2154 * in the RCC_OscInitTypeDef structure. 2155 */ 2156 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; 2157 RCC_OscInitStruct.HSEState = RCC_HSE_ON; 2158 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; 2159 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; 2160 RCC_OscInitStruct.PLL.PLLM = 25; 2161 RCC_OscInitStruct.PLL.PLLN = 144; 2162 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; 2163 RCC_OscInitStruct.PLL.PLLQ = 3; 2164 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) 2165 { 2166 Error_Handler(); 2167 } 2168 2169 /** Initializes the CPU, AHB and APB buses clocks 2170 */ 2171 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK 2172 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; 2173 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; 2174 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; 2175 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; 2176 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; 2177 2178 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) 2179 { 2180 Error_Handler(); 2181 } 2182 } 2183 2184 /** 2185 * @brief Peripherals Common Clock Configuration 2186 * @retval None 2187 */ 2188 void PeriphCommonClock_Config(void) 2189 { 2190 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; 2191 2192 /** Initializes the peripherals clock 2193 */ 2194 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_TIM; 2195 PeriphClkInitStruct.TIMPresSelection = RCC_TIMPRES_ACTIVATED; 2196 2197 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) 2198 { 2199 Error_Handler(); 2200 } 2201 } 2202 2203 /** 2204 * @brief I2C1 Initialization Function 2205 * @param None 2206 * @retval None 2207 */ 2208 static void MX_I2C1_Init(void) 2209 { 2210 2211 /* USER CODE BEGIN I2C1_Init 0 */ 2212 2213 /* USER CODE END I2C1_Init 0 */ 2214 2215 /* USER CODE BEGIN I2C1_Init 1 */ 2216 2217 /* USER CODE END I2C1_Init 1 */ 2218 hi2c1.Instance = I2C1; 2219 hi2c1.Init.Timing = 0x00808CD2; 2220 hi2c1.Init.OwnAddress1 = 0; 2221 hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; 2222 hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; 2223 hi2c1.Init.OwnAddress2 = 0; 2224 hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK; 2225 hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; 2226 hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; 2227 if (HAL_I2C_Init(&hi2c1) != HAL_OK) 2228 { 2229 Error_Handler(); 2230 } 2231 2232 /** Configure Analogue filter 2233 */ 2234 if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK) 2235 { 2236 Error_Handler(); 2237 } 2238 2239 /** Configure Digital filter 2240 */ 2241 if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK) 2242 { 2243 Error_Handler(); 2244 } 2245 /* USER CODE BEGIN I2C1_Init 2 */ 2246 2247 /* USER CODE END I2C1_Init 2 */ 2248 2249 } 2250 2251 /** 2252 * @brief I2C2 Initialization Function 2253 * @param None 2254 * @retval None 2255 */ 2256 static void MX_I2C2_Init(void) 2257 { 2258 2259 /* USER CODE BEGIN I2C2_Init 0 */ 2260 2261 /* USER CODE END I2C2_Init 0 */ 2262 2263 /* USER CODE BEGIN I2C2_Init 1 */ 2264 2265 /* USER CODE END I2C2_Init 1 */ 2266 hi2c2.Instance = I2C2; 2267 hi2c2.Init.Timing = 0x00808CD2; 2268 hi2c2.Init.OwnAddress1 = 0; 2269 hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; 2270 hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; 2271 hi2c2.Init.OwnAddress2 = 0; 2272 hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK; 2273 hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; 2274 hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; 2275 if (HAL_I2C_Init(&hi2c2) != HAL_OK) 2276 { 2277 Error_Handler(); 2278 } 2279 2280 /** Configure Analogue filter 2281 */ 2282 if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK) 2283 { 2284 Error_Handler(); 2285 } 2286 2287 /** Configure Digital filter 2288 */ 2289 if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK) 2290 { 2291 Error_Handler(); 2292 } 2293 /* USER CODE BEGIN I2C2_Init 2 */ 2294 2295 /* USER CODE END I2C2_Init 2 */ 2296 2297 } 2298 2299 /** 2300 * @brief I2C3 Initialization Function 2301 * @param None 2302 * @retval None 2303 */ 2304 static void MX_I2C3_Init(void) 2305 { 2306 2307 /* USER CODE BEGIN I2C3_Init 0 */ 2308 2309 /* USER CODE END I2C3_Init 0 */ 2310 2311 /* USER CODE BEGIN I2C3_Init 1 */ 2312 2313 /* USER CODE END I2C3_Init 1 */ 2314 hi2c3.Instance = I2C3; 2315 hi2c3.Init.Timing = 0x00808CD2; 2316 hi2c3.Init.OwnAddress1 = 0; 2317 hi2c3.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; 2318 hi2c3.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; 2319 hi2c3.Init.OwnAddress2 = 0; 2320 hi2c3.Init.OwnAddress2Masks = I2C_OA2_NOMASK; 2321 hi2c3.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; 2322 hi2c3.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; 2323 if (HAL_I2C_Init(&hi2c3) != HAL_OK) 2324 { 2325 Error_Handler(); 2326 } 2327 2328 /** Configure Analogue filter 2329 */ 2330 if (HAL_I2CEx_ConfigAnalogFilter(&hi2c3, I2C_ANALOGFILTER_ENABLE) != HAL_OK) 2331 { 2332 Error_Handler(); 2333 } 2334 2335 /** Configure Digital filter 2336 */ 2337 if (HAL_I2CEx_ConfigDigitalFilter(&hi2c3, 0) != HAL_OK) 2338 { 2339 Error_Handler(); 2340 } 2341 /* USER CODE BEGIN I2C3_Init 2 */ 2342 2343 /* USER CODE END I2C3_Init 2 */ 2344 2345 } 2346 2347 /** 2348 * @brief SPI1 Initialization Function 2349 * @param None 2350 * @retval None 2351 */ 2352 static void MX_SPI1_Init(void) 2353 { 2354 2355 /* USER CODE BEGIN SPI1_Init 0 */ 2356 2357 /* USER CODE END SPI1_Init 0 */ 2358 2359 /* USER CODE BEGIN SPI1_Init 1 */ 2360 2361 /* USER CODE END SPI1_Init 1 */ 2362 /* SPI1 parameter configuration*/ 2363 hspi1.Instance = SPI1; 2364 hspi1.Init.Mode = SPI_MODE_MASTER; 2365 hspi1.Init.Direction = SPI_DIRECTION_2LINES; 2366 hspi1.Init.DataSize = SPI_DATASIZE_8BIT; 2367 hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; 2368 hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; 2369 hspi1.Init.NSS = SPI_NSS_SOFT; 2370 hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; 2371 hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; 2372 hspi1.Init.TIMode = SPI_TIMODE_DISABLE; 2373 hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; 2374 hspi1.Init.CRCPolynomial = 7; 2375 hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; 2376 hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE; 2377 if (HAL_SPI_Init(&hspi1) != HAL_OK) 2378 { 2379 Error_Handler(); 2380 } 2381 /* USER CODE BEGIN SPI1_Init 2 */ 2382 2383 /* USER CODE END SPI1_Init 2 */ 2384 2385 } 2386 2387 /** 2388 * @brief SPI4 Initialization Function 2389 * @param None 2390 * @retval None 2391 */ 2392 static void MX_SPI4_Init(void) 2393 { 2394 2395 /* USER CODE BEGIN SPI4_Init 0 */ 2396 2397 /* USER CODE END SPI4_Init 0 */ 2398 2399 /* USER CODE BEGIN SPI4_Init 1 */ 2400 2401 /* USER CODE END SPI4_Init 1 */ 2402 /* SPI4 parameter configuration*/ 2403 hspi4.Instance = SPI4; 2404 hspi4.Init.Mode = SPI_MODE_MASTER; 2405 hspi4.Init.Direction = SPI_DIRECTION_2LINES; 2406 hspi4.Init.DataSize = SPI_DATASIZE_8BIT; 2407 hspi4.Init.CLKPolarity = SPI_POLARITY_LOW; 2408 hspi4.Init.CLKPhase = SPI_PHASE_1EDGE; 2409 hspi4.Init.NSS = SPI_NSS_SOFT; 2410 hspi4.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; 2411 hspi4.Init.FirstBit = SPI_FIRSTBIT_MSB; 2412 hspi4.Init.TIMode = SPI_TIMODE_DISABLE; 2413 hspi4.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; 2414 hspi4.Init.CRCPolynomial = 7; 2415 hspi4.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; 2416 hspi4.Init.NSSPMode = SPI_NSS_PULSE_ENABLE; 2417 if (HAL_SPI_Init(&hspi4) != HAL_OK) 2418 { 2419 Error_Handler(); 2420 } 2421 /* USER CODE BEGIN SPI4_Init 2 */ 2422 2423 /* USER CODE END SPI4_Init 2 */ 2424 2425 } 2426 2427 /** 2428 * @brief TIM1 Initialization Function 2429 * @param None 2430 * @retval None 2431 */ 2432 static void MX_TIM1_Init(void) 2433 { 2434 2435 /* USER CODE BEGIN TIM1_Init 0 */ 2436 2437 /* USER CODE END TIM1_Init 0 */ 2438 2439 TIM_ClockConfigTypeDef sClockSourceConfig = {0}; 2440 TIM_MasterConfigTypeDef sMasterConfig = {0}; 2441 2442 /* USER CODE BEGIN TIM1_Init 1 */ 2443 2444 /* USER CODE END TIM1_Init 1 */ 2445 htim1.Instance = TIM1; 2446 htim1.Init.Prescaler = 71; 2447 htim1.Init.CounterMode = TIM_COUNTERMODE_UP; 2448 htim1.Init.Period = 0xffff-1; 2449 htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; 2450 htim1.Init.RepetitionCounter = 0; 2451 htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; 2452 if (HAL_TIM_Base_Init(&htim1) != HAL_OK) 2453 { 2454 Error_Handler(); 2455 } 2456 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; 2457 if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) 2458 { 2459 Error_Handler(); 2460 } 2461 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; 2462 sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET; 2463 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; 2464 if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) 2465 { 2466 Error_Handler(); 2467 } 2468 /* USER CODE BEGIN TIM1_Init 2 */ 2469 2470 /* USER CODE END TIM1_Init 2 */ 2471 2472 } 2473 2474 /** 2475 * @brief TIM3 Initialization Function — DELADJ PWM for ADF4382A phase shift 2476 * CH2 = TX DELADJ, CH3 = RX DELADJ 2477 * Period (ARR) = 999 → 1000 counts matching DELADJ_MAX_DUTY_CYCLE 2478 * Prescaler = 71 → 1 MHz tick @ 72 MHz APB1 → 1 kHz PWM frequency 2479 * @param None 2480 * @retval None 2481 */ 2482 static void MX_TIM3_Init(void) 2483 { 2484 /* B15 fix: provide htim3 definition so adf4382a_manager.c extern resolves */ 2485 2486 TIM_ClockConfigTypeDef sClockSourceConfig = {0}; 2487 TIM_MasterConfigTypeDef sMasterConfig = {0}; 2488 TIM_OC_InitTypeDef sConfigOC = {0}; 2489 2490 htim3.Instance = TIM3; 2491 htim3.Init.Prescaler = 71; // 72 MHz / (71+1) = 1 MHz tick 2492 htim3.Init.CounterMode = TIM_COUNTERMODE_UP; 2493 htim3.Init.Period = 999; // ARR = 999 → 1000 counts = DELADJ_MAX_DUTY_CYCLE 2494 htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; 2495 htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; 2496 if (HAL_TIM_Base_Init(&htim3) != HAL_OK) 2497 { 2498 Error_Handler(); 2499 } 2500 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; 2501 if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK) 2502 { 2503 Error_Handler(); 2504 } 2505 if (HAL_TIM_PWM_Init(&htim3) != HAL_OK) 2506 { 2507 Error_Handler(); 2508 } 2509 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; 2510 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; 2511 if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) 2512 { 2513 Error_Handler(); 2514 } 2515 sConfigOC.OCMode = TIM_OCMODE_PWM1; 2516 sConfigOC.Pulse = 0; // Start with 0% duty cycle 2517 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; 2518 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; 2519 // Configure CH2 (TX DELADJ) 2520 if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) 2521 { 2522 Error_Handler(); 2523 } 2524 // Configure CH3 (RX DELADJ) 2525 if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) 2526 { 2527 Error_Handler(); 2528 } 2529 } 2530 2531 /** 2532 * @brief UART5 Initialization Function 2533 * @param None 2534 * @retval None 2535 */ 2536 static void MX_UART5_Init(void) 2537 { 2538 2539 /* USER CODE BEGIN UART5_Init 0 */ 2540 2541 /* USER CODE END UART5_Init 0 */ 2542 2543 /* USER CODE BEGIN UART5_Init 1 */ 2544 2545 /* USER CODE END UART5_Init 1 */ 2546 huart5.Instance = UART5; 2547 huart5.Init.BaudRate = 9600; 2548 huart5.Init.WordLength = UART_WORDLENGTH_8B; 2549 huart5.Init.StopBits = UART_STOPBITS_1; 2550 huart5.Init.Parity = UART_PARITY_NONE; 2551 huart5.Init.Mode = UART_MODE_TX_RX; 2552 huart5.Init.HwFlowCtl = UART_HWCONTROL_NONE; 2553 huart5.Init.OverSampling = UART_OVERSAMPLING_16; 2554 huart5.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; 2555 huart5.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; 2556 if (HAL_UART_Init(&huart5) != HAL_OK) 2557 { 2558 Error_Handler(); 2559 } 2560 /* USER CODE BEGIN UART5_Init 2 */ 2561 2562 /* USER CODE END UART5_Init 2 */ 2563 2564 } 2565 2566 /** 2567 * @brief USART3 Initialization Function 2568 * @param None 2569 * @retval None 2570 */ 2571 static void MX_USART3_UART_Init(void) 2572 { 2573 2574 /* USER CODE BEGIN USART3_Init 0 */ 2575 2576 /* USER CODE END USART3_Init 0 */ 2577 2578 /* USER CODE BEGIN USART3_Init 1 */ 2579 2580 /* USER CODE END USART3_Init 1 */ 2581 huart3.Instance = USART3; 2582 huart3.Init.BaudRate = 115200; 2583 huart3.Init.WordLength = UART_WORDLENGTH_8B; 2584 huart3.Init.StopBits = UART_STOPBITS_1; 2585 huart3.Init.Parity = UART_PARITY_NONE; 2586 huart3.Init.Mode = UART_MODE_TX_RX; 2587 huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE; 2588 huart3.Init.OverSampling = UART_OVERSAMPLING_16; 2589 huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; 2590 huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; 2591 if (HAL_UART_Init(&huart3) != HAL_OK) 2592 { 2593 Error_Handler(); 2594 } 2595 /* USER CODE BEGIN USART3_Init 2 */ 2596 2597 /* USER CODE END USART3_Init 2 */ 2598 2599 } 2600 2601 /** 2602 * @brief GPIO Initialization Function 2603 * @param None 2604 * @retval None 2605 */ 2606 static void MX_GPIO_Init(void) 2607 { 2608 GPIO_InitTypeDef GPIO_InitStruct = {0}; 2609 /* USER CODE BEGIN MX_GPIO_Init_1 */ 2610 2611 /* USER CODE END MX_GPIO_Init_1 */ 2612 2613 /* GPIO Ports Clock Enable */ 2614 __HAL_RCC_GPIOE_CLK_ENABLE(); 2615 __HAL_RCC_GPIOC_CLK_ENABLE(); 2616 __HAL_RCC_GPIOF_CLK_ENABLE(); 2617 __HAL_RCC_GPIOH_CLK_ENABLE(); 2618 __HAL_RCC_GPIOA_CLK_ENABLE(); 2619 __HAL_RCC_GPIOG_CLK_ENABLE(); 2620 __HAL_RCC_GPIOB_CLK_ENABLE(); 2621 __HAL_RCC_GPIOD_CLK_ENABLE(); 2622 2623 /*Configure GPIO pin Output Level */ 2624 HAL_GPIO_WritePin(GPIOF, AD9523_PD_Pin|AD9523_REF_SEL_Pin|AD9523_SYNC_Pin|AD9523_RESET_Pin 2625 |AD9523_CS_Pin|AD9523_EEPROM_SEL_Pin|LED_1_Pin|LED_2_Pin 2626 |LED_3_Pin|LED_4_Pin, GPIO_PIN_RESET); 2627 2628 /*Configure GPIO pin Output Level */ 2629 HAL_GPIO_WritePin(GPIOA, ADAR_1_CS_3V3_Pin|ADAR_2_CS_3V3_Pin|ADAR_3_CS_3V3_Pin|ADAR_4_CS_3V3_Pin, GPIO_PIN_RESET); 2630 2631 /*Configure GPIO pin Output Level */ 2632 HAL_GPIO_WritePin(GPIOG, EN_P_5V0_PA1_Pin|EN_P_5V0_PA2_Pin|EN_P_5V0_PA3_Pin|EN_P_5V5_PA_Pin 2633 |EN_P_1V8_CLOCK_Pin|EN_P_3V3_CLOCK_Pin|ADF4382_RX_DELADJ_Pin|ADF4382_RX_DELSTR_Pin 2634 |ADF4382_RX_CE_Pin|ADF4382_RX_CS_Pin|ADF4382_TX_DELSTR_Pin|ADF4382_TX_DELADJ_Pin 2635 |ADF4382_TX_CS_Pin|ADF4382_TX_CE_Pin, GPIO_PIN_RESET); 2636 2637 /*Configure GPIO pin Output Level */ 2638 HAL_GPIO_WritePin(GPIOE, EN_P_1V0_FPGA_Pin|EN_P_1V8_FPGA_Pin|EN_P_3V3_FPGA_Pin|EN_P_5V0_ADAR_Pin 2639 |EN_P_3V3_ADAR12_Pin|EN_P_3V3_ADAR34_Pin|EN_P_3V3_ADTR_Pin|EN_P_3V3_SW_Pin 2640 |EN_P_3V3_VDD_SW_Pin, GPIO_PIN_RESET); 2641 2642 /*Configure GPIO pin Output Level */ 2643 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 2644 |STEPPER_CW_P_Pin|STEPPER_CLK_P_Pin|EN_DIS_RFPA_VDD_Pin|EN_DIS_COOLING_Pin, GPIO_PIN_RESET); 2645 2646 /*Configure GPIO pin Output Level */ 2647 HAL_GPIO_WritePin(GPIOB, DAC_1_VG_CLR_Pin|DAC_1_VG_LDAC_Pin|DAC_2_VG_CLR_Pin|DAC_2_VG_LDAC_Pin, GPIO_PIN_RESET); 2648 2649 /*Configure GPIO pins : AD9523_PD_Pin AD9523_REF_SEL_Pin AD9523_SYNC_Pin AD9523_RESET_Pin 2650 AD9523_CS_Pin AD9523_EEPROM_SEL_Pin LED_1_Pin LED_2_Pin 2651 LED_3_Pin LED_4_Pin */ 2652 GPIO_InitStruct.Pin = AD9523_PD_Pin|AD9523_REF_SEL_Pin|AD9523_SYNC_Pin|AD9523_RESET_Pin 2653 |AD9523_CS_Pin|AD9523_EEPROM_SEL_Pin|LED_1_Pin|LED_2_Pin 2654 |LED_3_Pin|LED_4_Pin; 2655 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 2656 GPIO_InitStruct.Pull = GPIO_NOPULL; 2657 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; 2658 HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); 2659 2660 /*Configure GPIO pins : AD9523_STATUS0_Pin AD9523_STATUS1_Pin */ 2661 GPIO_InitStruct.Pin = AD9523_STATUS0_Pin|AD9523_STATUS1_Pin; 2662 GPIO_InitStruct.Mode = GPIO_MODE_INPUT; 2663 GPIO_InitStruct.Pull = GPIO_NOPULL; 2664 HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); 2665 2666 /*Configure GPIO pins : ADAR_1_CS_3V3_Pin ADAR_2_CS_3V3_Pin ADAR_3_CS_3V3_Pin ADAR_4_CS_3V3_Pin */ 2667 GPIO_InitStruct.Pin = ADAR_1_CS_3V3_Pin|ADAR_2_CS_3V3_Pin|ADAR_3_CS_3V3_Pin|ADAR_4_CS_3V3_Pin; 2668 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 2669 GPIO_InitStruct.Pull = GPIO_NOPULL; 2670 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; 2671 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 2672 2673 /*Configure GPIO pins : EN_P_5V0_PA1_Pin EN_P_5V0_PA2_Pin EN_P_5V0_PA3_Pin EN_P_5V5_PA_Pin 2674 EN_P_1V8_CLOCK_Pin EN_P_3V3_CLOCK_Pin ADF4382_RX_DELADJ_Pin ADF4382_RX_DELSTR_Pin 2675 ADF4382_RX_CE_Pin ADF4382_RX_CS_Pin ADF4382_TX_DELSTR_Pin ADF4382_TX_DELADJ_Pin 2676 ADF4382_TX_CS_Pin ADF4382_TX_CE_Pin */ 2677 GPIO_InitStruct.Pin = EN_P_5V0_PA1_Pin|EN_P_5V0_PA2_Pin|EN_P_5V0_PA3_Pin|EN_P_5V5_PA_Pin 2678 |EN_P_1V8_CLOCK_Pin|EN_P_3V3_CLOCK_Pin|ADF4382_RX_DELADJ_Pin|ADF4382_RX_DELSTR_Pin 2679 |ADF4382_RX_CE_Pin|ADF4382_RX_CS_Pin|ADF4382_TX_DELSTR_Pin|ADF4382_TX_DELADJ_Pin 2680 |ADF4382_TX_CS_Pin|ADF4382_TX_CE_Pin; 2681 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 2682 GPIO_InitStruct.Pull = GPIO_NOPULL; 2683 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; 2684 HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); 2685 2686 /*Configure GPIO pins : EN_P_1V0_FPGA_Pin EN_P_1V8_FPGA_Pin EN_P_3V3_FPGA_Pin EN_P_5V0_ADAR_Pin 2687 EN_P_3V3_ADAR12_Pin EN_P_3V3_ADAR34_Pin EN_P_3V3_ADTR_Pin EN_P_3V3_SW_Pin 2688 EN_P_3V3_ADAR12EN_P_3V3_VDD_SW_Pin */ 2689 GPIO_InitStruct.Pin = EN_P_1V0_FPGA_Pin|EN_P_1V8_FPGA_Pin|EN_P_3V3_FPGA_Pin|EN_P_5V0_ADAR_Pin 2690 |EN_P_3V3_ADAR12_Pin|EN_P_3V3_ADAR34_Pin|EN_P_3V3_ADTR_Pin|EN_P_3V3_SW_Pin 2691 |EN_P_3V3_VDD_SW_Pin; 2692 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 2693 GPIO_InitStruct.Pull = GPIO_NOPULL; 2694 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; 2695 HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); 2696 2697 /*Configure GPIO pins : PD8 PD9 PD10 PD11 2698 STEPPER_CW_P_Pin STEPPER_CLK_P_Pin EN_DIS_RFPA_VDD_Pin EN_DIS_COOLING_Pin */ 2699 GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12 2700 |STEPPER_CW_P_Pin|STEPPER_CLK_P_Pin|EN_DIS_RFPA_VDD_Pin|EN_DIS_COOLING_Pin; 2701 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 2702 GPIO_InitStruct.Pull = GPIO_NOPULL; 2703 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; 2704 HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); 2705 2706 /*Configure GPIO pins : PD12 PD13 PD14 PD15 */ 2707 GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15; 2708 GPIO_InitStruct.Mode = GPIO_MODE_INPUT; 2709 GPIO_InitStruct.Pull = GPIO_NOPULL; 2710 HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); 2711 2712 /*Configure GPIO pins : ADF4382_RX_LKDET_Pin ADF4382_TX_LKDET_Pin */ 2713 GPIO_InitStruct.Pin = ADF4382_RX_LKDET_Pin|ADF4382_TX_LKDET_Pin; 2714 GPIO_InitStruct.Mode = GPIO_MODE_INPUT; 2715 GPIO_InitStruct.Pull = GPIO_NOPULL; 2716 HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); 2717 2718 /*Configure GPIO pins : MAG_DRDY_Pin ACC_INT_Pin GYR_INT_Pin */ 2719 GPIO_InitStruct.Pin = MAG_DRDY_Pin|ACC_INT_Pin|GYR_INT_Pin; 2720 GPIO_InitStruct.Mode = GPIO_MODE_INPUT; 2721 GPIO_InitStruct.Pull = GPIO_NOPULL; 2722 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 2723 2724 /*Configure GPIO pins : DAC_1_VG_CLR_Pin DAC_1_VG_LDAC_Pin DAC_2_VG_CLR_Pin DAC_2_VG_LDAC_Pin */ 2725 GPIO_InitStruct.Pin = DAC_1_VG_CLR_Pin|DAC_1_VG_LDAC_Pin|DAC_2_VG_CLR_Pin|DAC_2_VG_LDAC_Pin; 2726 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 2727 GPIO_InitStruct.Pull = GPIO_NOPULL; 2728 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; 2729 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 2730 2731 /* USER CODE BEGIN MX_GPIO_Init_2 */ 2732 2733 /* USER CODE END MX_GPIO_Init_2 */ 2734 } 2735 2736 /* USER CODE BEGIN 4 */ 2737 /* ============================================================ 2738 * DEVICE INITIALIZATION 2739 * ============================================================ */ 2740 2741 /** 2742 * [GAP-3 FIX 2] Initialize Independent Watchdog (IWDG). 2743 * 2744 * LSI clock ≈ 32 kHz. 2745 * Prescaler = 256 → IWDG counter clock ≈ 125 Hz (8 ms/tick). 2746 * Reload = 500 → timeout ≈ 500 × 8 ms = 4.0 s. 2747 * 2748 * The main loop must call HAL_IWDG_Refresh() within this window 2749 * or the MCU hard-resets — protecting against firmware hangs when 2750 * PA rails may be energized. 2751 */ 2752 static void MX_IWDG_Init(void) 2753 { 2754 hiwdg.Instance = IWDG; 2755 hiwdg.Init.Prescaler = IWDG_PRESCALER_256; 2756 hiwdg.Init.Reload = 500; 2757 hiwdg.Init.Window = IWDG_WINDOW_DISABLE; 2758 if (HAL_IWDG_Init(&hiwdg) != HAL_OK) { 2759 DIAG_ERR("SYS", "IWDG init FAILED -- continuing without hardware watchdog"); 2760 } else { 2761 DIAG("SYS", "IWDG hardware watchdog started (timeout ~4s)"); 2762 } 2763 } 2764 2765 2766 2767 /* USER CODE END 4 */ 2768 2769 /* MPU Configuration */ 2770 2771 void MPU_Config(void) 2772 { 2773 MPU_Region_InitTypeDef MPU_InitStruct = {0}; 2774 2775 /* Disables the MPU */ 2776 HAL_MPU_Disable(); 2777 2778 /** Initializes and configures the Region and the memory to be protected 2779 */ 2780 MPU_InitStruct.Enable = MPU_REGION_ENABLE; 2781 MPU_InitStruct.Number = MPU_REGION_NUMBER0; 2782 MPU_InitStruct.BaseAddress = 0x0; 2783 MPU_InitStruct.Size = MPU_REGION_SIZE_4GB; 2784 MPU_InitStruct.SubRegionDisable = 0x87; 2785 MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; 2786 MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS; 2787 MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE; 2788 MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; 2789 MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; 2790 MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; 2791 2792 HAL_MPU_ConfigRegion(&MPU_InitStruct); 2793 /* Enables the MPU */ 2794 HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); 2795 2796 } 2797 2798 /** 2799 * @brief This function is executed in case of error occurrence. 2800 * @retval None 2801 */ 2802 void Error_Handler(void) 2803 { 2804 /* USER CODE BEGIN Error_Handler_Debug */ 2805 /* User can add his own implementation to report the HAL error return state */ 2806 __disable_irq(); 2807 while (1) 2808 { 2809 } 2810 /* USER CODE END Error_Handler_Debug */ 2811 } 2812 2813 #ifdef USE_FULL_ASSERT 2814 /** 2815 * @brief Reports the name of the source file and the source line number 2816 * where the assert_param error has occurred. 2817 * @param file: pointer to the source file name 2818 * @param line: assert_param error line source number 2819 * @retval None 2820 */ 2821 void assert_failed(uint8_t *file, uint32_t line) 2822 { 2823 /* USER CODE BEGIN 6 */ 2824 /* User can add his own implementation to report the file name and line number, 2825 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ 2826 /* USER CODE END 6 */ 2827 } 2828 #endif /* USE_FULL_ASSERT */