A low cost DIY sound pressure level sensor for enabling environmental noise awareness. https://lukasschwarz.org/noise-sensor
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

1136 lines
35 KiB

  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.c
  5. * @brief : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
  10. * All rights reserved.</center></h2>
  11. *
  12. * This software component is licensed by ST under BSD 3-Clause license,
  13. * the "License"; You may not use this file except in compliance with the
  14. * License. You may obtain a copy of the License at:
  15. * opensource.org/licenses/BSD-3-Clause
  16. *
  17. ******************************************************************************
  18. */
  19. /* USER CODE END Header */
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "main.h"
  22. /* Private includes ----------------------------------------------------------*/
  23. /* USER CODE BEGIN Includes */
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <stdlib.h>
  27. #include <math.h>
  28. #include <arduinoFFT.h>
  29. #include <SX1278.h>
  30. #include <correction_values.h>
  31. /* USER CODE END Includes */
  32. /* Private typedef -----------------------------------------------------------*/
  33. /* USER CODE BEGIN PTD */
  34. /* USER CODE END PTD */
  35. /* Private define ------------------------------------------------------------*/
  36. /* USER CODE BEGIN PD */
  37. #define VERBOSE // print debug messages via USART
  38. #define VERY_VERBOSE
  39. #define I2C_RX 0
  40. #define I2C_TX 1
  41. #define DEVICE_COUNT 5
  42. // FFT things
  43. #define START_BIN 3
  44. #define FFT_BINS 512 // Actually usable bins after FFT
  45. #define SAMPLE_SIZE (FFT_BINS * 2)
  46. #define BUFSIZE (SAMPLE_SIZE * 4)
  47. // Audio stuff
  48. #define MIC_OFFSET_DB 2
  49. #define MIC_REF_DB 94.0
  50. #define MIC_SENSITIVITY -26
  51. #define MIC_SNR 65
  52. #define MIC_BITS 16
  53. #define MIC_OVERLOAD 120
  54. #define MIC_NOISE_FLOOR (MIC_REF_DB - MIC_SNR)
  55. // Power stuff
  56. #define DROPOUT_VOLTAGE (3.3 + 0.25) // For a load of approx. 50 mA and LP2950ACZ-3.3G
  57. #define BAT_VOLTAGE_CHECK_INTERVAL 60000 // ms
  58. #define BAT_VOLTAGE_CHECK_TOLERANCE 500 // ms
  59. #define BAT_FIELD_SIZE 1
  60. #define BAT_LOW_THRESHOLD DROPOUT_VOLTAGE - 0.4 // This seems odd but below the drop out voltage, MCU and LoRa will still work
  61. #define BAT_MEASUREMENT_CYCLES 10 // Measure over 10 iterations to avoid one-offs.
  62. // LoRa stuff
  63. #define LORA_SYNC_WORD 0x2AF69A00
  64. #define LORA_TIMEOUT 200
  65. #define LORA_HEADER_LENGTH sizeof(LORA_SYNC_WORD) / 2 // divide by two because we use a uint16_t (2 byte) buffer
  66. // just fine (min. 1.8V) so we can go a bit lower for longer battery life.
  67. #define LORA_BEACON_SIZE 10
  68. /* USER CODE END PD */
  69. /* Private macro -------------------------------------------------------------*/
  70. /* USER CODE BEGIN PM */
  71. /* USER CODE END PM */
  72. /* Private variables ---------------------------------------------------------*/
  73. ADC_HandleTypeDef hadc1;
  74. DMA_HandleTypeDef hdma_adc1;
  75. I2C_HandleTypeDef hi2c2;
  76. I2S_HandleTypeDef hi2s1;
  77. DMA_HandleTypeDef hdma_spi1_rx;
  78. SPI_HandleTypeDef hspi2;
  79. TIM_HandleTypeDef htim2;
  80. UART_HandleTypeDef huart4;
  81. /* USER CODE BEGIN PV */
  82. // TODO CHECK
  83. constexpr double MIC_REF_AMPL = pow(10, double(MIC_SENSITIVITY)/20) * (pow(2, (MIC_BITS - 1)) - 1);
  84. char msg[64];
  85. uint8_t ret;
  86. uint16_t i2s_dma_buf[BUFSIZE];
  87. uint32_t adc_buf[3];
  88. double vReal[SAMPLE_SIZE];
  89. double vImag[SAMPLE_SIZE];
  90. volatile bool adc_ready;
  91. volatile uint32_t adc_avg;
  92. volatile float bat_voltage_avg;
  93. bool got_i2c_setup_message;
  94. volatile bool got_beacon;
  95. volatile bool flip_buffer;
  96. volatile bool tx_due;
  97. volatile uint8_t adc_counter;
  98. volatile uint8_t tick_count = LORA_HEADER_LENGTH;
  99. uint8_t verbosity;
  100. uint8_t i2c_tx_counter;
  101. uint16_t lora_beacon_rx_buffer[5];
  102. uint16_t i2c_tx_buffer[1024];
  103. uint16_t first_sync_message[5];
  104. // Capitalized means "const" but we cannot make them real const as that doesn't work with the protcol.
  105. uint8_t PACKET_LENGTH;
  106. uint8_t LORA_PACKET_SIZE;
  107. uint16_t TX_OFFSET;
  108. uint16_t TICK_COUNT;
  109. uint16_t measured_values1[63]; // TODO
  110. uint16_t measured_values2[63];
  111. uint32_t TICK_DURATION_US;
  112. volatile uint8_t device_id;
  113. char i2c_rx_buffer[4];
  114. /* USER CODE END PV */
  115. /* Private function prototypes -----------------------------------------------*/
  116. void SystemClock_Config(void);
  117. static void MX_GPIO_Init(void);
  118. static void MX_DMA_Init(void);
  119. static void MX_ADC1_Init(void);
  120. static void MX_I2S1_Init(void);
  121. static void MX_SPI2_Init(void);
  122. static void MX_I2C2_Init(void);
  123. static void MX_USART4_UART_Init(void);
  124. static void MX_TIM2_Init(void);
  125. /* USER CODE BEGIN PFP */
  126. /* USER CODE END PFP */
  127. /* Private user code ---------------------------------------------------------*/
  128. /* USER CODE BEGIN 0 */
  129. SX1278_hw_t SX1278_hw;
  130. SX1278_t SX1278;
  131. void PrintVector(double *vData, uint16_t bufferSize, uint8_t scaleType) {
  132. for (uint16_t i = 0; i < bufferSize; i++) // First two bins are not meaningful.
  133. {
  134. char buf[10];
  135. char buf2[bufferSize];
  136. double abscissa;
  137. /* Print abscissa value */
  138. switch (scaleType)
  139. {
  140. case 0:
  141. abscissa = (i * 1.0);
  142. break;
  143. case 1:
  144. abscissa = ((i * 1.0) / hi2s1.Init.AudioFreq);
  145. break;
  146. case 2:
  147. abscissa = ((i * 1.0 * hi2s1.Init.AudioFreq) / SAMPLE_SIZE);
  148. break;
  149. default:
  150. break;
  151. }
  152. sprintf(buf, "%.4f", abscissa);
  153. HAL_UART_Transmit(&huart4, (uint8_t *) buf, strlen(buf), 100);
  154. if(scaleType==2) {
  155. HAL_UART_Transmit(&huart4, (uint8_t *) " Hz", 3, 100);
  156. }
  157. HAL_UART_Transmit(&huart4, (uint8_t *) " ", 1, 100);
  158. sprintf(buf2, "%.4f, %.4f dB\n", vData[i], (20 * log10(vData[i])));
  159. HAL_UART_Transmit(&huart4, (uint8_t *) buf2, strlen(buf2), 100);
  160. }
  161. HAL_UART_Transmit(&huart4, (uint8_t *) "\n", 1, 100);
  162. }
  163. /**
  164. * Helper function to split the LoRa sync word from the device ID in a LoRa message.
  165. */
  166. _Bool IsOwnLoraPacket(uint16_t *buf) {
  167. if (buf[0] == (LORA_SYNC_WORD >> 16) && (buf[1] & 0xff00) == (uint16_t) (LORA_SYNC_WORD) ) {
  168. return 1;
  169. }
  170. return 0;
  171. }
  172. uint8_t GetDeviceId(uint16_t *buf) {
  173. return (buf[1] & 0x00ff);
  174. }
  175. /*
  176. * Do FFT on the filled arrays, calculate RMS and return the A-weighted dB value.
  177. */
  178. uint16_t GetDBA(double *vReal, double *vImag) {
  179. arduinoFFT fft = arduinoFFT(vReal, vImag, SAMPLE_SIZE, hi2s1.Init.AudioFreq);
  180. fft.Windowing(FFT_WIN_TYP_HANN, FFT_FORWARD);
  181. fft.Compute(FFT_FORWARD);
  182. fft.ComplexToMagnitude();
  183. double squared_sum = 0;
  184. for (uint16_t i = START_BIN; i < FFT_BINS; i++) {
  185. squared_sum += (pow(vReal[i], 2) * CORRECTION_VALUES[i]); // Parseval's Theorem
  186. }
  187. double rms = 1.63 * sqrt(2.0 * squared_sum / (SAMPLE_SIZE * SAMPLE_SIZE)); // https://de.mathworks.com/matlabcentral/answers/372516-calculate-windowing-correction-factor
  188. double dbA = MIC_OFFSET_DB + MIC_REF_DB + 20 * log10(rms / MIC_REF_AMPL);
  189. // We can't measure below that as the noise from the microphone is louder than the ambient sound itself.
  190. if (dbA <= MIC_NOISE_FLOOR) {
  191. dbA = MIC_NOISE_FLOOR;
  192. } else if (dbA >= MIC_OVERLOAD) {
  193. dbA = MIC_OVERLOAD;
  194. }
  195. return (dbA * 10); // Make a fixed point from the double. Give us one decimal point of precision which is plenty.
  196. }
  197. /* USER CODE END 0 */
  198. /**
  199. * @brief The application entry point.
  200. * @retval int
  201. */
  202. int main(void)
  203. {
  204. /* USER CODE BEGIN 1 */
  205. /* USER CODE END 1 */
  206. /* MCU Configuration--------------------------------------------------------*/
  207. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  208. HAL_Init();
  209. /* USER CODE BEGIN Init */
  210. /* USER CODE END Init */
  211. /* Configure the system clock */
  212. SystemClock_Config();
  213. /* USER CODE BEGIN SysInit */
  214. /* USER CODE END SysInit */
  215. /* Initialize all configured peripherals */
  216. MX_GPIO_Init();
  217. MX_DMA_Init();
  218. MX_ADC1_Init();
  219. MX_I2S1_Init();
  220. MX_SPI2_Init();
  221. MX_I2C2_Init();
  222. MX_USART4_UART_Init();
  223. MX_TIM2_Init();
  224. /* USER CODE BEGIN 2 */
  225. #ifdef VERBOSE
  226. verbosity = 1;
  227. #endif
  228. #ifdef VERY_VERBOSE
  229. verbosity = 2;
  230. #endif
  231. //SX1278_hw.dio0.port = DIO0_GPIO_Port;
  232. //SX1278_hw.dio0.pin = DIO0_;
  233. SX1278_hw.dio0.port = GPIOB;
  234. SX1278_hw.dio0.pin = GPIO_PIN_0;
  235. SX1278_hw.nss.port = NSS_GPIO_Port;
  236. SX1278_hw.nss.pin = NSS_Pin;
  237. SX1278_hw.reset.port = RESET_GPIO_Port;
  238. SX1278_hw.reset.pin = RESET_Pin;
  239. SX1278_hw.spi = &hspi2;
  240. SX1278.hw = &SX1278_hw;
  241. SX1278_init(&SX1278, 866000000, SX1278_POWER_14DBM, SX1278_LORA_SF_8, SX1278_LORA_BW_250KHZ, SX1278_LORA_CR_4_5, SX1278_LORA_CRC_EN, 60);
  242. HAL_I2S_Receive_DMA(&hi2s1, (uint16_t *) i2s_dma_buf, BUFSIZE/2);
  243. // This would work just fine without DMA but multiple channels don't work in polling mode.
  244. HAL_TIM_Base_Start(&htim2);
  245. HAL_ADC_Start_DMA(&hadc1, adc_buf, hadc1.Init.NbrOfConversion);
  246. while (!adc_ready);
  247. adc_ready = 0;
  248. HAL_ADC_Stop_DMA(&hadc1);
  249. uint32_t adc_value = adc_buf[0];
  250. if (verbosity >= 2) {
  251. sprintf(msg, "%lu %lu\n", adc_buf[0], adc_buf[1]);
  252. HAL_UART_Transmit(&huart4, (uint8_t *) msg, strlen(msg), 100);
  253. }
  254. if (adc_value <= 400) { // LOW
  255. device_id = 4;
  256. } else if (adc_value >= 600 && adc_value <= 1400) { // 3V3 -- 10k -- 3k3 -- GND
  257. device_id = 1;
  258. } else if (adc_value >= 1600 && adc_value <= 2400) { // 3V3 -- 10k -- 10k -- GND
  259. device_id = 2;
  260. } else if (adc_value >= 2600 && adc_value <= 3400) { // 3V3 -- 10k -- 33k -- GND
  261. device_id = 3;
  262. } else if (adc_value >= 3600) { // HIGH
  263. device_id = 0; // Master
  264. HAL_I2C_EnableListen_IT(&hi2c2);
  265. }
  266. if (device_id == 0) {
  267. while (!got_i2c_setup_message) { HAL_UART_Transmit(&huart4, (uint8_t *) "wait for i2c\n", 13, 100); }
  268. got_i2c_setup_message = 0;
  269. TICK_COUNT = i2c_rx_buffer[1];
  270. TICK_DURATION_US = i2c_rx_buffer[2] * 1000000; // Seconds to µs.
  271. TX_OFFSET = i2c_rx_buffer[3]; // In ticks
  272. PACKET_LENGTH = (TICK_COUNT + LORA_HEADER_LENGTH + BAT_FIELD_SIZE);
  273. LORA_PACKET_SIZE = PACKET_LENGTH * 2;
  274. first_sync_message[0] = (uint16_t) (LORA_SYNC_WORD >> 16);
  275. first_sync_message[1] = (uint16_t) (LORA_SYNC_WORD | device_id);
  276. first_sync_message[2] = TICK_COUNT; // Tick count
  277. first_sync_message[3] = i2c_rx_buffer[2]; // Tick duration
  278. first_sync_message[4] = TX_OFFSET; // Tx offset
  279. if (verbosity >= 1) {
  280. sprintf(msg, "tc: %u, td: %u, tx_offs: %u\n", first_sync_message[2], i2c_rx_buffer[2], first_sync_message[4]);
  281. HAL_UART_Transmit(&huart4, (uint8_t *) msg, strlen(msg), 100);
  282. }
  283. }
  284. uint16_t lora_rx_buffer[PACKET_LENGTH];
  285. if (verbosity >= 1) {
  286. sprintf(msg, "My device ID is %u\n", device_id);
  287. HAL_UART_Transmit(&huart4, (uint8_t *) msg, strlen(msg), 100);
  288. }
  289. /* USER CODE END 2 */
  290. /* Infinite loop */
  291. /* USER CODE BEGIN WHILE */
  292. while (1)
  293. {
  294. // Master
  295. if (device_id == 0) {
  296. __HAL_TIM_SET_COUNTER(&htim2, 0);
  297. // Send a sync beacon at the start of every "period".
  298. if (tick_count == 2) {
  299. SX1278_LoRaEntryTx(&SX1278, LORA_BEACON_SIZE, LORA_TIMEOUT);
  300. HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
  301. SX1278_LoRaTxPacket(&SX1278, (uint8_t *) &first_sync_message, LORA_BEACON_SIZE, LORA_TIMEOUT);
  302. //SX1278_LoRaTxPacket(&SX1278, (uint8_t *) &measured_values1, 4, LORA_TIMEOUT);
  303. HAL_UART_Transmit(&huart4, (uint8_t *) first_sync_message, LORA_BEACON_SIZE, 100);
  304. if (verbosity >= 1) {
  305. HAL_UART_Transmit(&huart4, (uint8_t *) "\nsent beacon\n", 13, 100);
  306. } else if (verbosity >= 2) {
  307. HAL_UART_Transmit(&huart4, (uint8_t *) first_sync_message, 10, 100);
  308. }
  309. HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
  310. // Change back to Rx again.
  311. SX1278_LoRaEntryRx(&SX1278, LORA_PACKET_SIZE, LORA_TIMEOUT);
  312. }
  313. for (volatile uint16_t i = 0; i < BUFSIZE; i += 4) {
  314. vReal[i/4] = abs(65535 - i2s_dma_buf[i]);
  315. vImag[i/4] = 0;
  316. }
  317. // For the master, one buffer is enough. No need to flip.
  318. measured_values1[tick_count] = GetDBA(vReal, vImag);
  319. if (verbosity >= 2) {
  320. sprintf(msg, "fill array %u\n", tick_count);
  321. HAL_UART_Transmit(&huart4, (uint8_t *) msg, strlen(msg), 100);
  322. }
  323. //sprintf(msg, "array[%u]: %u\n", tick_count, i2c_tx_buffer[tick_count]);
  324. //HAL_UART_Transmit(&huart4, (uint8_t *) msg, strlen(msg), 100);
  325. tick_count++;
  326. if (tick_count == PACKET_LENGTH - BAT_FIELD_SIZE) { // Last measurement, now wait for I²C
  327. bool debug_sent = 0;
  328. while (!got_i2c_setup_message) {
  329. if (verbosity >= 1 && !debug_sent) {
  330. HAL_UART_Transmit(&huart4, (uint8_t *) "Waiting for I2C\n", 16, 100);
  331. debug_sent = 1;
  332. }
  333. }
  334. if (verbosity >= 1) {
  335. HAL_UART_Transmit(&huart4, (uint8_t *) "Got I2C sync\n", 13, 100);
  336. }
  337. memcpy(&i2c_tx_buffer[0], &measured_values1, LORA_PACKET_SIZE);
  338. TICK_COUNT = i2c_rx_buffer[1];
  339. TICK_DURATION_US = i2c_rx_buffer[2] * 1000000; // Seconds to µs.
  340. TX_OFFSET = i2c_rx_buffer[3]; // In ticks
  341. PACKET_LENGTH = (TICK_COUNT + LORA_HEADER_LENGTH + BAT_FIELD_SIZE);
  342. LORA_PACKET_SIZE = PACKET_LENGTH * 2;
  343. first_sync_message[0] = (uint16_t) (LORA_SYNC_WORD >> 16);
  344. first_sync_message[1] = (uint16_t) (LORA_SYNC_WORD | device_id);
  345. first_sync_message[2] = TICK_COUNT; // Tick count
  346. first_sync_message[3] = i2c_rx_buffer[2]; // Tick duration
  347. first_sync_message[4] = TX_OFFSET; // Tx offset
  348. got_i2c_setup_message = 0;
  349. tick_count = LORA_HEADER_LENGTH;
  350. sprintf(msg, "tickcountreset %u, gotmsg %u\n", tick_count, got_i2c_setup_message);
  351. HAL_UART_Transmit(&huart4, (uint8_t *) msg, strlen(msg), 100);
  352. } else {
  353. while (__HAL_TIM_GET_COUNTER(&htim2) < TICK_DURATION_US) {
  354. ret = SX1278_LoRaRxPacket(&SX1278);
  355. // Only accept packages within our expected length to avoid buffer overflows.
  356. if (ret > 0 && ret <= LORA_PACKET_SIZE) {
  357. memset(lora_rx_buffer, 0, sizeof lora_rx_buffer);
  358. SX1278_read(&SX1278, (uint8_t*) lora_rx_buffer, LORA_PACKET_SIZE);
  359. if (IsOwnLoraPacket(lora_rx_buffer)) {
  360. HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
  361. uint8_t devid = GetDeviceId(lora_rx_buffer);
  362. memcpy(&i2c_tx_buffer[devid * PACKET_LENGTH], &lora_rx_buffer, LORA_PACKET_SIZE);
  363. if (verbosity >= 1) {
  364. sprintf(msg, "Rx %u bytes: ", sizeof(lora_rx_buffer));
  365. HAL_UART_Transmit(&huart4, (uint8_t *) msg, strlen(msg), 100);
  366. HAL_UART_Transmit(&huart4, (uint8_t *) lora_rx_buffer, LORA_PACKET_SIZE, 100);
  367. HAL_UART_Transmit(&huart4, (uint8_t *) "\n", 1, 100);
  368. }
  369. HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
  370. break; // No need to check again as no two Rx can happen within one tick.
  371. }
  372. }
  373. }
  374. }
  375. while (__HAL_TIM_GET_COUNTER(&htim2) < TICK_DURATION_US) {
  376. // Just wait.
  377. }
  378. } else {
  379. if (!got_beacon) {
  380. SX1278_LoRaEntryRx(&SX1278, 4, LORA_TIMEOUT);
  381. }
  382. while (!got_beacon) {
  383. ret = SX1278_LoRaRxPacket(&SX1278);
  384. if (verbosity >= 2) { HAL_UART_Transmit(&huart4, (uint8_t *) "awaiting beacon\n", 16, 100); }
  385. if (ret > 0 && ret <= LORA_BEACON_SIZE) {
  386. HAL_UART_Transmit(&huart4, (uint8_t *) lora_beacon_rx_buffer, LORA_BEACON_SIZE, 100);
  387. SX1278_read(&SX1278, (uint8_t*) lora_beacon_rx_buffer, LORA_BEACON_SIZE);
  388. // Beacons only come from the master (device_id == 0)
  389. if (IsOwnLoraPacket(lora_beacon_rx_buffer) && GetDeviceId(lora_beacon_rx_buffer) == 0) {
  390. TICK_COUNT = lora_beacon_rx_buffer[2];
  391. TICK_DURATION_US = lora_beacon_rx_buffer[3] * 1000000;
  392. TX_OFFSET = lora_beacon_rx_buffer[4];
  393. PACKET_LENGTH = (TICK_COUNT + LORA_HEADER_LENGTH + BAT_FIELD_SIZE);
  394. LORA_PACKET_SIZE = PACKET_LENGTH * 2;
  395. got_beacon = 1;
  396. if (verbosity >= 2) {
  397. sprintf(msg, "tc: %u, td: %lu, offs: %u\n", TICK_COUNT, TICK_DURATION_US, TX_OFFSET);
  398. HAL_UART_Transmit(&huart4, (uint8_t *) msg, strlen(msg), 100);
  399. HAL_UART_Transmit(&huart4, (uint8_t *) lora_beacon_rx_buffer, LORA_BEACON_SIZE, 100);
  400. HAL_UART_Transmit(&huart4, (uint8_t *) "\n", 1, 100);
  401. }
  402. break;
  403. }
  404. }
  405. HAL_Delay(150); // Going at full throttle just pisses away power.
  406. }
  407. sprintf(msg, "tc: %u, td: %lu, offs: %u\n", TICK_COUNT, TICK_DURATION_US, TX_OFFSET);
  408. HAL_UART_Transmit(&huart4, (uint8_t *) msg, strlen(msg), 100);
  409. // Use the first 4 bytes as LoRa sync word and device ID.
  410. measured_values1[0] = (uint16_t) (LORA_SYNC_WORD >> 16);
  411. measured_values2[0] = (uint16_t) (LORA_SYNC_WORD >> 16);
  412. measured_values1[1] = (uint16_t) (LORA_SYNC_WORD | device_id);
  413. measured_values2[1] = (uint16_t) (LORA_SYNC_WORD | device_id);
  414. // Battery state.
  415. measured_values1[PACKET_LENGTH - 1] = 0x0000;
  416. measured_values2[PACKET_LENGTH - 1] = 0x0000;
  417. __HAL_TIM_SET_COUNTER(&htim2, 0);
  418. // TICK_COUNT / 2 avoids measurement during Tx which drops the voltage a fair bit.
  419. if (device_id != 0 && tick_count == (TICK_COUNT / 2)) {
  420. HAL_ADC_Start_DMA(&hadc1, adc_buf, hadc1.Init.NbrOfConversion);
  421. while (!adc_ready);
  422. adc_ready = 0;
  423. HAL_ADC_Stop_DMA(&hadc1);
  424. adc_avg += adc_buf[1];
  425. adc_counter++;
  426. if (adc_counter == BAT_MEASUREMENT_CYCLES) {
  427. HAL_ADCEx_Calibration_Start(&hadc1); // As per data sheet this needs to happen while the ADC is not running.
  428. uint32_t cal = HAL_ADCEx_Calibration_GetValue(&hadc1) / 2; // Returns an offset we add to the measurement later on.
  429. adc_avg /= adc_counter;
  430. bat_voltage_avg = ((adc_avg + cal) * 1.212 / adc_buf[2]) * 2; // 1.212 is the VREFINT voltage as per data sheet.
  431. if (verbosity >= 2) {
  432. sprintf(msg, "V_BAT: %.4f, ADC: %lu\n", bat_voltage_avg, adc_avg);
  433. HAL_UART_Transmit(&huart4, (uint8_t *) msg, strlen(msg), 100);
  434. }
  435. if (bat_voltage_avg <= DROPOUT_VOLTAGE) {
  436. measured_values1[PACKET_LENGTH - BAT_FIELD_SIZE] = 0xffff;
  437. measured_values2[PACKET_LENGTH - BAT_FIELD_SIZE] = 0xffff;
  438. if (verbosity >= 1) {
  439. sprintf(msg, "V_BAT: %.3f V below %.3f V, flipped battery bits\n", bat_voltage_avg, BAT_LOW_THRESHOLD);
  440. HAL_UART_Transmit(&huart4, (uint8_t *) msg, strlen(msg), 100);
  441. }
  442. }
  443. bat_voltage_avg = 0;
  444. adc_avg = 0;
  445. adc_counter = 0;
  446. }
  447. }
  448. if (verbosity >= 2) {
  449. sprintf(msg, "tc: %u, tx_due: %u\n", tick_count, tx_due);
  450. HAL_UART_Transmit(&huart4, (uint8_t *) msg, strlen(msg), 100);
  451. }
  452. // Wait for device ID times offset with sending to avoid overlapping transmissions at the master node.
  453. if ( tx_due && tick_count == (LORA_HEADER_LENGTH - 1 + (device_id * TX_OFFSET)) ) {
  454. //HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
  455. if (flip_buffer) {
  456. SX1278_LoRaTxPacket(&SX1278, (uint8_t *) &measured_values1, LORA_PACKET_SIZE, LORA_TIMEOUT);
  457. if (verbosity >= 1) { HAL_UART_Transmit(&huart4, (uint8_t *) "sent arr. 1\n", 12, 100); }
  458. } else {
  459. SX1278_LoRaTxPacket(&SX1278, (uint8_t *) &measured_values2, LORA_PACKET_SIZE, LORA_TIMEOUT);
  460. if (verbosity >= 1) { HAL_UART_Transmit(&huart4, (uint8_t *) "sent arr. 2\n", 12, 100); }
  461. }
  462. //HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
  463. tx_due = 0;
  464. }
  465. for (volatile uint16_t i = 0; i < BUFSIZE; i += 4) {
  466. vReal[i/4] = abs(65535 - i2s_dma_buf[i]);
  467. vImag[i/4] = 0;
  468. }
  469. // Alternate between two buffers to allow sending while another buffer is being written to.
  470. if (flip_buffer) {
  471. measured_values2[tick_count] = GetDBA(vReal, vImag);
  472. if (verbosity >= 2) {
  473. sprintf(msg, "fill array 1: %u\n", tick_count);
  474. HAL_UART_Transmit(&huart4, (uint8_t *) msg, strlen(msg), 100);
  475. }
  476. } else {
  477. measured_values1[tick_count] = GetDBA(vReal, vImag);
  478. if (verbosity >= 2) {
  479. sprintf(msg, "fill array 1: %u\n", tick_count);
  480. HAL_UART_Transmit(&huart4, (uint8_t *) msg, strlen(msg), 100);
  481. }
  482. }
  483. // One tick before expecting the sync beacon we switch to Rx. We could've done this earlier
  484. // but keeping the LoRa module in Rx mode uses up a lot of power.
  485. if (tick_count == ( PACKET_LENGTH - BAT_FIELD_SIZE - 2 ) ) {
  486. SX1278_LoRaEntryRx(&SX1278, 4, LORA_TIMEOUT);
  487. if (verbosity >= 2) { HAL_UART_Transmit(&huart4, (uint8_t *) "switch to rx\n", 13, 100); }
  488. }
  489. tick_count++;
  490. // TODO This could probably be done in the while !beacon loop.
  491. // TODO Update setup values should they change.
  492. // All measurements are done and we're waiting for the sync beacon to start the cycle again.
  493. while ( __HAL_TIM_GET_COUNTER(&htim2) < (TICK_DURATION_US) || tick_count == (PACKET_LENGTH - BAT_FIELD_SIZE ) ) {
  494. ret = SX1278_LoRaRxPacket(&SX1278);
  495. if (ret > 0 && ret <= LORA_BEACON_SIZE) {
  496. memset(lora_beacon_rx_buffer, 0, sizeof lora_beacon_rx_buffer);
  497. SX1278_read(&SX1278, (uint8_t*) lora_beacon_rx_buffer, LORA_BEACON_SIZE);
  498. if (verbosity >= 2) { HAL_UART_Transmit(&huart4, (uint8_t *) lora_beacon_rx_buffer, sizeof(lora_beacon_rx_buffer), 100); }
  499. // Beacons only come from the master (device_id == 0)
  500. if (IsOwnLoraPacket(lora_beacon_rx_buffer) && GetDeviceId(lora_beacon_rx_buffer) == 0) {
  501. if (verbosity >= 1) { HAL_UART_Transmit(&huart4, (uint8_t *) "rx beacon\n", 10, 100); }
  502. flip_buffer ^= 1; // Flip the flip_buffer bit.
  503. tick_count = LORA_HEADER_LENGTH;
  504. uint8_t new_tick_count = lora_beacon_rx_buffer[2];
  505. uint32_t new_tick_duration = lora_beacon_rx_buffer[3] * 1000000;
  506. uint8_t new_tx_offset = lora_beacon_rx_buffer[4];
  507. // If one of these values changes, don't send the last packet as it's not adhering to the new parameters anymore.
  508. if (new_tick_count != TICK_COUNT || new_tick_duration != TICK_DURATION_US || new_tx_offset != TX_OFFSET) {
  509. tx_due = 0;
  510. HAL_UART_Transmit(&huart4, (uint8_t *) "values changed, don't send\n", 27, 100);
  511. } else {
  512. tx_due = 1;
  513. }
  514. if (verbosity >= 2) { HAL_UART_Transmit(&huart4, (uint8_t *) "flip\n", 6, 100); }
  515. TICK_COUNT = new_tick_count;
  516. TICK_DURATION_US = new_tick_duration;
  517. TX_OFFSET = new_tx_offset;
  518. PACKET_LENGTH = (TICK_COUNT + LORA_HEADER_LENGTH + BAT_FIELD_SIZE);
  519. LORA_PACKET_SIZE = PACKET_LENGTH * 2;
  520. HAL_UART_Transmit(&huart4, (uint8_t *) "\n", 1, 100);
  521. while (__HAL_TIM_GET_COUNTER(&htim2) < (TICK_DURATION_US)); // Some µs might be left.
  522. // Switch back to Tx right here as it saves power.
  523. SX1278_entryLoRa(&SX1278);
  524. SX1278_LoRaEntryTx(&SX1278, LORA_PACKET_SIZE, LORA_TIMEOUT);
  525. break;
  526. }
  527. }
  528. }
  529. }
  530. /*
  531. }
  532. */
  533. /* USER CODE END WHILE */
  534. /* USER CODE BEGIN 3 */
  535. }
  536. /* USER CODE END 3 */
  537. }
  538. /**
  539. * @brief System Clock Configuration
  540. * @retval None
  541. */
  542. void SystemClock_Config(void)
  543. {
  544. RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  545. RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  546. RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
  547. /** Configure the main internal regulator output voltage
  548. */
  549. HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
  550. /** Initializes the RCC Oscillators according to the specified parameters
  551. * in the RCC_OscInitTypeDef structure.
  552. */
  553. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  554. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  555. RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
  556. RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  557. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  558. if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  559. {
  560. Error_Handler();
  561. }
  562. /** Initializes the CPU, AHB and APB buses clocks
  563. */
  564. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  565. |RCC_CLOCKTYPE_PCLK1;
  566. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  567. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  568. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  569. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  570. {
  571. Error_Handler();
  572. }
  573. /** Initializes the peripherals clocks
  574. */
  575. PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2S1|RCC_PERIPHCLK_ADC;
  576. PeriphClkInit.I2s1ClockSelection = RCC_I2S1CLKSOURCE_SYSCLK;
  577. PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_SYSCLK;
  578. if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  579. {
  580. Error_Handler();
  581. }
  582. }
  583. /**
  584. * @brief ADC1 Initialization Function
  585. * @param None
  586. * @retval None
  587. */
  588. static void MX_ADC1_Init(void)
  589. {
  590. /* USER CODE BEGIN ADC1_Init 0 */
  591. /* USER CODE END ADC1_Init 0 */
  592. ADC_ChannelConfTypeDef sConfig = {0};
  593. /* USER CODE BEGIN ADC1_Init 1 */
  594. /* USER CODE END ADC1_Init 1 */
  595. /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
  596. */
  597. hadc1.Instance = ADC1;
  598. hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  599. hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  600. hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  601. hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  602. hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  603. hadc1.Init.LowPowerAutoWait = DISABLE;
  604. hadc1.Init.LowPowerAutoPowerOff = DISABLE;
  605. hadc1.Init.ContinuousConvMode = DISABLE;
  606. hadc1.Init.NbrOfConversion = 3;
  607. hadc1.Init.DiscontinuousConvMode = DISABLE;
  608. hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  609. hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  610. hadc1.Init.DMAContinuousRequests = ENABLE;
  611. hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  612. hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_1CYCLE_5;
  613. hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_1CYCLE_5;
  614. hadc1.Init.OversamplingMode = DISABLE;
  615. hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
  616. if (HAL_ADC_Init(&hadc1) != HAL_OK)
  617. {
  618. Error_Handler();
  619. }
  620. /** Configure Regular Channel
  621. */
  622. sConfig.Channel = ADC_CHANNEL_2;
  623. sConfig.Rank = ADC_REGULAR_RANK_1;
  624. sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
  625. if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  626. {
  627. Error_Handler();
  628. }
  629. /** Configure Regular Channel
  630. */
  631. sConfig.Channel = ADC_CHANNEL_9;
  632. sConfig.Rank = ADC_REGULAR_RANK_2;
  633. if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  634. {
  635. Error_Handler();
  636. }
  637. /** Configure Regular Channel
  638. */
  639. sConfig.Channel = ADC_CHANNEL_VREFINT;
  640. sConfig.Rank = ADC_REGULAR_RANK_3;
  641. if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  642. {
  643. Error_Handler();
  644. }
  645. /* USER CODE BEGIN ADC1_Init 2 */
  646. /* USER CODE END ADC1_Init 2 */
  647. }
  648. /**
  649. * @brief I2C2 Initialization Function
  650. * @param None
  651. * @retval None
  652. */
  653. static void MX_I2C2_Init(void)
  654. {
  655. /* USER CODE BEGIN I2C2_Init 0 */
  656. /* USER CODE END I2C2_Init 0 */
  657. /* USER CODE BEGIN I2C2_Init 1 */
  658. /* USER CODE END I2C2_Init 1 */
  659. hi2c2.Instance = I2C2;
  660. hi2c2.Init.Timing = 0x0010061A;
  661. hi2c2.Init.OwnAddress1 = 120;
  662. hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  663. hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  664. hi2c2.Init.OwnAddress2 = 0;
  665. hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  666. hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  667. hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  668. if (HAL_I2C_Init(&hi2c2) != HAL_OK)
  669. {
  670. Error_Handler();
  671. }
  672. /** Configure Analogue filter
  673. */
  674. if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
  675. {
  676. Error_Handler();
  677. }
  678. /** Configure Digital filter
  679. */
  680. if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK)
  681. {
  682. Error_Handler();
  683. }
  684. /* USER CODE BEGIN I2C2_Init 2 */
  685. if (HAL_GPIO_ReadPin(I2C_Address_GPIO_Port, I2C_Address_Pin) == GPIO_PIN_SET) { // Jumper open, internal pull up
  686. hi2c2.Init.OwnAddress1 = 120;
  687. } else { // Jumper closed, pulled to GND
  688. hi2c2.Init.OwnAddress1 = 122;
  689. }
  690. if (HAL_I2C_Init(&hi2c2) != HAL_OK)
  691. {
  692. Error_Handler();
  693. }
  694. /* USER CODE END I2C2_Init 2 */
  695. }
  696. /**
  697. * @brief I2S1 Initialization Function
  698. * @param None
  699. * @retval None
  700. */
  701. static void MX_I2S1_Init(void)
  702. {
  703. /* USER CODE BEGIN I2S1_Init 0 */
  704. /* USER CODE END I2S1_Init 0 */
  705. /* USER CODE BEGIN I2S1_Init 1 */
  706. /* USER CODE END I2S1_Init 1 */
  707. hi2s1.Instance = SPI1;
  708. hi2s1.Init.Mode = I2S_MODE_MASTER_RX;
  709. hi2s1.Init.Standard = I2S_STANDARD_PHILIPS;
  710. hi2s1.Init.DataFormat = I2S_DATAFORMAT_24B;
  711. hi2s1.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
  712. hi2s1.Init.AudioFreq = I2S_AUDIOFREQ_22K;
  713. hi2s1.Init.CPOL = I2S_CPOL_LOW;
  714. if (HAL_I2S_Init(&hi2s1) != HAL_OK)
  715. {
  716. Error_Handler();
  717. }
  718. /* USER CODE BEGIN I2S1_Init 2 */
  719. /* USER CODE END I2S1_Init 2 */
  720. }
  721. /**
  722. * @brief SPI2 Initialization Function
  723. * @param None
  724. * @retval None
  725. */
  726. static void MX_SPI2_Init(void)
  727. {
  728. /* USER CODE BEGIN SPI2_Init 0 */
  729. /* USER CODE END SPI2_Init 0 */
  730. /* USER CODE BEGIN SPI2_Init 1 */
  731. /* USER CODE END SPI2_Init 1 */
  732. /* SPI2 parameter configuration*/
  733. hspi2.Instance = SPI2;
  734. hspi2.Init.Mode = SPI_MODE_MASTER;
  735. hspi2.Init.Direction = SPI_DIRECTION_2LINES;
  736. hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
  737. hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
  738. hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
  739. hspi2.Init.NSS = SPI_NSS_SOFT;
  740. hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  741. hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
  742. hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
  743. hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  744. hspi2.Init.CRCPolynomial = 7;
  745. hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  746. hspi2.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
  747. if (HAL_SPI_Init(&hspi2) != HAL_OK)
  748. {
  749. Error_Handler();
  750. }
  751. /* USER CODE BEGIN SPI2_Init 2 */
  752. /* USER CODE END SPI2_Init 2 */
  753. }
  754. /**
  755. * @brief TIM2 Initialization Function
  756. * @param None
  757. * @retval None
  758. */
  759. static void MX_TIM2_Init(void)
  760. {
  761. /* USER CODE BEGIN TIM2_Init 0 */
  762. /* USER CODE END TIM2_Init 0 */
  763. TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  764. TIM_MasterConfigTypeDef sMasterConfig = {0};
  765. /* USER CODE BEGIN TIM2_Init 1 */
  766. /* USER CODE END TIM2_Init 1 */
  767. htim2.Instance = TIM2;
  768. htim2.Init.Prescaler = 16-1;
  769. htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  770. htim2.Init.Period = 4294967295;
  771. htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  772. htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  773. if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  774. {
  775. Error_Handler();
  776. }
  777. sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  778. if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  779. {
  780. Error_Handler();
  781. }
  782. sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  783. sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  784. if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  785. {
  786. Error_Handler();
  787. }
  788. /* USER CODE BEGIN TIM2_Init 2 */
  789. /* USER CODE END TIM2_Init 2 */
  790. }
  791. /**
  792. * @brief USART4 Initialization Function
  793. * @param None
  794. * @retval None
  795. */
  796. static void MX_USART4_UART_Init(void)
  797. {
  798. /* USER CODE BEGIN USART4_Init 0 */
  799. /* USER CODE END USART4_Init 0 */
  800. /* USER CODE BEGIN USART4_Init 1 */
  801. /* USER CODE END USART4_Init 1 */
  802. huart4.Instance = USART4;
  803. huart4.Init.BaudRate = 115200;
  804. huart4.Init.WordLength = UART_WORDLENGTH_8B;
  805. huart4.Init.StopBits = UART_STOPBITS_1;
  806. huart4.Init.Parity = UART_PARITY_NONE;
  807. huart4.Init.Mode = UART_MODE_TX;
  808. huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  809. huart4.Init.OverSampling = UART_OVERSAMPLING_16;
  810. huart4.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  811. huart4.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  812. huart4.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  813. if (HAL_UART_Init(&huart4) != HAL_OK)
  814. {
  815. Error_Handler();
  816. }
  817. /* USER CODE BEGIN USART4_Init 2 */
  818. /* USER CODE END USART4_Init 2 */
  819. }
  820. /**
  821. * Enable DMA controller clock
  822. */
  823. static void MX_DMA_Init(void)
  824. {
  825. /* DMA controller clock enable */
  826. __HAL_RCC_DMA1_CLK_ENABLE();
  827. /* DMA interrupt init */
  828. /* DMA1_Channel1_IRQn interrupt configuration */
  829. HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
  830. HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
  831. /* DMA1_Channel2_3_IRQn interrupt configuration */
  832. HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0);
  833. HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
  834. }
  835. /**
  836. * @brief GPIO Initialization Function
  837. * @param None
  838. * @retval None
  839. */
  840. static void MX_GPIO_Init(void)
  841. {
  842. GPIO_InitTypeDef GPIO_InitStruct = {0};
  843. /* GPIO Ports Clock Enable */
  844. __HAL_RCC_GPIOA_CLK_ENABLE();
  845. __HAL_RCC_GPIOB_CLK_ENABLE();
  846. __HAL_RCC_GPIOC_CLK_ENABLE();
  847. /*Configure GPIO pin Output Level */
  848. HAL_GPIO_WritePin(NSS_GPIO_Port, NSS_Pin, GPIO_PIN_SET);
  849. /*Configure GPIO pin Output Level */
  850. HAL_GPIO_WritePin(GPIOA, LED_Pin|RESET_Pin, GPIO_PIN_RESET);
  851. /*Configure GPIO pins : NSS_Pin LED_Pin RESET_Pin */
  852. GPIO_InitStruct.Pin = NSS_Pin|LED_Pin|RESET_Pin;
  853. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  854. GPIO_InitStruct.Pull = GPIO_NOPULL;
  855. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  856. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  857. /*Configure GPIO pin : PB0 */
  858. GPIO_InitStruct.Pin = GPIO_PIN_0;
  859. GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  860. GPIO_InitStruct.Pull = GPIO_NOPULL;
  861. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  862. /*Configure GPIO pin : I2C_Address_Pin */
  863. GPIO_InitStruct.Pin = I2C_Address_Pin;
  864. GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  865. GPIO_InitStruct.Pull = GPIO_PULLUP;
  866. HAL_GPIO_Init(I2C_Address_GPIO_Port, &GPIO_InitStruct);
  867. }
  868. /* USER CODE BEGIN 4 */
  869. void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) {
  870. HAL_I2C_DisableListen_IT(hi2c);
  871. if (TransferDirection == I2C_TX) {
  872. HAL_I2C_Slave_Transmit_IT(hi2c, (uint8_t *) &i2c_tx_buffer[i2c_tx_counter * PACKET_LENGTH], LORA_PACKET_SIZE);
  873. i2c_tx_counter++;
  874. } else if (TransferDirection == I2C_RX) {
  875. HAL_I2C_Slave_Receive_IT(hi2c, (uint8_t *) i2c_rx_buffer, sizeof(i2c_rx_buffer)); // The Arduino lib sends an extra byte in the beginning.
  876. }
  877. }
  878. void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c) {
  879. if (i2c_tx_counter == DEVICE_COUNT) {
  880. i2c_tx_counter = 0;
  881. memset(i2c_tx_buffer, 0, sizeof i2c_tx_buffer);
  882. }
  883. HAL_I2C_EnableListen_IT(hi2c);
  884. }
  885. void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) {
  886. got_i2c_setup_message = 1;
  887. HAL_I2C_EnableListen_IT(hi2c);
  888. }
  889. void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
  890. adc_ready = 1;
  891. }
  892. /* USER CODE END 4 */
  893. /**
  894. * @brief This function is executed in case of error occurrence.
  895. * @retval None
  896. */
  897. void Error_Handler(void)
  898. {
  899. /* USER CODE BEGIN Error_Handler_Debug */
  900. /* User can add his own implementation to report the HAL error return state */
  901. /* USER CODE END Error_Handler_Debug */
  902. }
  903. #ifdef USE_FULL_ASSERT
  904. /**
  905. * @brief Reports the name of the source file and the source line number
  906. * where the assert_param error has occurred.
  907. * @param file: pointer to the source file name
  908. * @param line: assert_param error line source number
  909. * @retval None
  910. */
  911. void assert_failed(uint8_t *file, uint32_t line)
  912. {
  913. /* USER CODE BEGIN 6 */
  914. /* User can add his own implementation to report the file name and line number,
  915. tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  916. /* USER CODE END 6 */
  917. }
  918. #endif /* USE_FULL_ASSERT */
  919. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/