/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * *

© Copyright (c) 2020 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include #include #include #include "handshake.pb.h" #include "devices.h" #include "config.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ #define device_MDR s2m_MDR_response #define GET_IDX_FROM_ADDR(i2c_addr) i2c_addr-1 #define GET_BIT_FROM_IDX(a, b) a[b>>5]&(1<<(b%32)) #define SET_BIT_FROM_IDX(a, b) a[b>>5]|=(1<<(b%32)) #define COUNTOF(__BUFFER__) (sizeof(__BUFFER__) / sizeof(*(__BUFFER__))) #define I2C_ADDRESS 0x05 /* Macro to toggle between master and slave firmware */ /* #define MASTER */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ I2C_HandleTypeDef hi2c1; UART_HandleTypeDef huart1; /* USER CODE BEGIN PV */ _subscriptions gsubs[10]; int subs_idx = 0; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_I2C1_Init(void); static void MX_USART1_UART_Init(void); /* USER CODE BEGIN PFP */ bool encode_subscription_callback(pb_ostream_t *ostream, const pb_field_t *field, void * const *arg); bool decode_subscriptions_callback(pb_istream_t *istream, const pb_field_t *field, void **args); /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_I2C1_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ #ifdef TESTING_ENABLE #ifdef MASTER uint8_t reset_string[] = "\r\n\n==========MASTER RESET=========\r\n\n"; HAL_UART_Transmit(&huart1, reset_string, sizeof(reset_string), 100); #else uint8_t reset_string[] = "\r\n\n==========SLAVE RESET=========\r\n\n"; HAL_UART_Transmit(&huart1, reset_string, sizeof(reset_string), 100); #endif /* MASTER */ #endif /* TESTING_ENABLE */ #ifdef MASTER uint8_t MDR_req_buf[64], debug_buf[128] = {0}, term[]="\r\n"; m2s_MDR_request MDR_req_message; pb_ostream_t MDR_req_stream = pb_ostream_from_buffer(MDR_req_buf, sizeof(MDR_req_buf)); MDR_req_message.record_type = 7; /* Placeholder for default record type */ if(!pb_encode(&MDR_req_stream, m2s_MDR_request_fields, &MDR_req_message)) { #ifdef DEBUG_ENABLE uint8_t err_buf[] = "MDR reqest encoding error\r\n"; HAL_UART_Transmit(&huart1, err_buf, sizeof(err_buf), 100); #endif /* DEBUG_ENABLE */ Error_Handler(); } uint16_t enc_size = MDR_req_stream.bytes_written; #ifdef TESTING_ENABLE sprintf((char*)debug_buf, "Encoded length: %d\r\n", enc_size); HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); memset(debug_buf, 0, 128); uint8_t bufbuf[] = "MDR req buffer: "; HAL_UART_Transmit(&huart1, bufbuf, sizeof(bufbuf), 100); for(int x=0; x 1000) { break; } } #ifdef TESTING_ENABLE uint8_t bufbuf2[] = "MDR ACK buffer: "; HAL_UART_Transmit(&huart1, bufbuf2, sizeof(bufbuf2), 100); for (int x=0; x<2; x++) { sprintf((char*)debug_buf+x, "%x|", MDR_ACK_buf[x]); } HAL_UART_Transmit(&huart1, debug_buf, 2, 100); HAL_UART_Transmit(&huart1, term, 2, 100); memset(debug_buf, 0, 128); #endif /* TESTING_ENABLE */ uint32_t MDR_len = 0; pb_istream_t MDR_ACK_istream = pb_istream_from_buffer(MDR_ACK_buf, 2); s2m_MDR_req_ACK MDR_ACK; if (!pb_decode(&MDR_ACK_istream, s2m_MDR_req_ACK_fields, &MDR_ACK)) { #ifdef DEBUG_ENABLE uint8_t errbuf[] = "MDR ACK decoding error\r\n"; HAL_UART_Transmit(&huart1, errbuf, sizeof(errbuf), 100); #endif /* DEBUG_ENABLE */ } else { MDR_len = MDR_ACK.MDR_res_length; #ifdef TESTING_ENABLE sprintf((char*)debug_buf, "Got MDR message length: %ld\r\n", MDR_ACK.MDR_res_length); HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); memset(debug_buf, 0, 128); #endif /* TESTING_ENABLE */ } uint8_t MDR_CTS_buf[8] = {0}; m2s_MDR_res_CTS MDR_CTS; pb_ostream_t MDR_CTS_ostream = pb_ostream_from_buffer(MDR_CTS_buf, sizeof(MDR_CTS_buf)); MDR_CTS.timeout = 100; if (!pb_encode(&MDR_CTS_ostream, m2s_MDR_res_CTS_fields, &MDR_CTS)) { #ifdef DEBUG_ENABLE sprintf((char*)debug_buf, "MDR encoding error\r\n"); HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); memset(debug_buf, 0, 128); #endif } #ifdef TESTING_ENABLE sprintf((char*)debug_buf, "CTS size: %d\r\n", MDR_CTS_ostream.bytes_written); HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); memset(debug_buf, 0, 128); uint8_t ctsbuf[] = "\tCTS buffer: "; for(int x=0; x<2; x++) { sprintf((char*)debug_buf+x, "%x", MDR_CTS_buf[x]); } HAL_UART_Transmit(&huart1, ctsbuf, sizeof(ctsbuf), 100); HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); HAL_UART_Transmit(&huart1, term, 2, 100); memset(debug_buf, 0, 128); #endif /* TESTING_ENABLE */ if (HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)I2C_ADDRESS, (uint8_t*)MDR_CTS_buf, 2, 10000) != HAL_OK) { #ifdef DEBUG_ENABLE sprintf((char*)debug_buf, "Unable to send MDR CTS. I2C error: %ld\r\n", HAL_I2C_GetError(&hi2c1)); HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); memset(debug_buf, 0, 128); #endif /* DEBUG_ENABLE */ } HAL_GPIO_TogglePin(led_GPIO_Port, led_Pin); uint8_t MDR_buf[256]; AF_error_counter = 0; while (HAL_I2C_Master_Receive(&hi2c1, (uint8_t)I2C_ADDRESS, (uint8_t*)MDR_buf, MDR_len, 1000) != HAL_OK) { if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF) { #ifdef DEBUG_ENABLE sprintf((char*)debug_buf, "Unable to get MDR. I2C error: %ld\r\n", HAL_I2C_GetError(&hi2c1)); HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); memset(debug_buf, 0, 128); #endif /* DEBUG_ENABLE */ break; } AF_error_counter++; /* if (++AF_error_counter > 1000) { */ /* break; */ /* } */ } #ifdef TESTING_ENABLE sprintf((char*)debug_buf, "MDR trials: %ld\r\n", AF_error_counter); HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); memset(debug_buf, 0, 128); #endif #ifdef TESTING_ENABLE uint8_t mdrbuf[] = "Got MDR: "; for (int x=0; xtag == s2m_MDR_response_subscriptions_tag) { for (int x=0; x<2; x++) { _subscriptions subs; subs.module_id = x+10*x; subs.i2c_address = x+1; subs.has_entity_id=false; subs.has_module_class=false; subs.has_module_id=true; subs.has_i2c_address=true; if(!pb_encode_tag_for_field(ostream, field)){ printf("ERR1\n"); return false; } if(!pb_encode_submessage(ostream, _subscriptions_fields, &subs)){ printf("ERR2\n"); return false; } } } else{ return false; } return true; } bool decode_subscriptions_callback(pb_istream_t *istream, const pb_field_t *field, void **args) { _subscriptions subs; if(!pb_decode(istream, _subscriptions_fields, &subs)) { return false; } else { /* Parse all fields if they're included */ if (subs.has_module_id) gsubs[subs_idx].module_id = subs.module_id; if (subs.has_entity_id) gsubs[subs_idx].entity_id = subs.entity_id; if (subs.has_module_class) gsubs[subs_idx].module_class = subs.module_class; if (subs.has_i2c_address) gsubs[subs_idx].i2c_address = subs.i2c_address; subs_idx++; subs_idx%=10; return true; } } /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ while (1) { HAL_GPIO_TogglePin(led_GPIO_Port, led_Pin); HAL_Delay(1000); } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/