diff options
Diffstat (limited to 'src/main-data.c')
| -rw-r--r-- | src/main-data.c | 397 |
1 files changed, 390 insertions, 7 deletions
diff --git a/src/main-data.c b/src/main-data.c index 4314e9e..5f45562 100644 --- a/src/main-data.c +++ b/src/main-data.c @@ -23,6 +23,7 @@ #include "config.h" #include "dataflow.h" #include "handshake.pb.h" +#include "data.pb.h" /* Private Macros */ #define device_MDR s2m_MDR_response @@ -45,6 +46,7 @@ device_info_t *device_info[BUS_DEVICE_LIMIT] = {NULL}; subscription_info_t* subs_info[BUS_DEVICE_LIMIT]; uint32_t allocated[4]={0}; uint8_t dev_sts[BUS_DEVICE_LIMIT] = {OFFLINE}; +uint8_t data_idx; /* Function prototypes */ void SystemClock_Config(void); @@ -54,12 +56,12 @@ static void MX_USART1_UART_Init(void); bool decode_subscriptions_callback(pb_istream_t *istream, const pb_field_t *field, void **args); hs_status_t handshake(uint32_t i2c_addr); -dataflow_status_t device_dataflow(uint8_t i2c_addr); +dataflow_status_t device_dataflow(uint8_t i2c_addr, uint32_t SOR_code); bool todo_hs_or_not_todo_hs(uint8_t i2c_addr); state_t get_state_from_hs_status(uint16_t device_addr, hs_status_t hs_status); bool encode_subscription_callback(pb_ostream_t *ostream, const pb_field_t *field, void * const *arg); - - +bool encode_datapoint_callback(pb_ostream_t *ostream, const pb_field_t *field, void * const *arg); +bool decode_data_callback(pb_istream_t *istream, const pb_field_t *field, void **args); /** * @brief The application entry point. * @retval int @@ -118,10 +120,103 @@ int main(void) device_info[dev_idx]->MDR = module_MDR; /* dataflow */ + device_dataflow(0x05, 1); #else /* Slave code*/ { - + uint8_t SOR_buf[m2s_SOR_size] = {0}, debug_buf[128], term[]="\r\n"; + if (HAL_I2C_Slave_Receive(&hi2c1, (uint8_t*)SOR_buf, m2s_SOR_size, 10000) != HAL_OK) { + sprintf((char*)debug_buf, "Failed to get SOR\r\n"); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + } + else { + sprintf((char*)debug_buf, "Got SOR\r\n"); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + } + m2s_SOR SOR_message; + pb_istream_t SOR_istream = pb_istream_from_buffer(SOR_buf, 2); + if (!pb_decode(&SOR_istream, m2s_SOR_fields, &SOR_message)) { + sprintf((char*)debug_buf, "SOR decode error\r\n"); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + } + else { + sprintf((char*)debug_buf, "SOR decoded; code: %ld\r\n", SOR_message.SOR_code); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + } + + if (SOR_message.SOR_code == 1) { + uint8_t data_buf[128]; + size_t data_enc_size; + s2m_data data; + data.datapoints.funcs.encode = encode_datapoint_callback; + pb_ostream_t data_ostream = pb_ostream_from_buffer(data_buf, sizeof(data_buf)); + if (!pb_encode(&data_ostream, s2m_data_fields, &data)) { + sprintf((char*)debug_buf, "Data encoding error\r\n"); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + Error_Handler(); + } + data_enc_size = data_ostream.bytes_written; + + s2m_DOC doc = s2m_DOC_init_zero; + uint8_t doc_buf[s2m_DOC_size]; + doc.DOC_code = 5; + doc.tx_length = data_enc_size; + pb_ostream_t doc_ostream = pb_ostream_from_buffer(doc_buf, 4); + + if (!pb_encode(&doc_ostream, s2m_DOC_fields, &doc)) { + sprintf((char*)debug_buf, "DOC encoding error\r\n"); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + Error_Handler(); + } + + sprintf((char*)debug_buf, "s2m_DOC encoded length: %d\r\n", doc_ostream.bytes_written); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + + if (HAL_I2C_Slave_Transmit(&hi2c1, (uint8_t*)doc_buf, 4, 10000) != HAL_OK) { + sprintf((char*)debug_buf, "DOC I2C send error: %ld\r\n", HAL_I2C_GetError(&hi2c1)); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + Error_Handler(); + } + else { + sprintf((char*)debug_buf, "SENT DOC\r\n"); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + } + + uint8_t CTS_buf[8]; + + if (HAL_I2C_Slave_Receive(&hi2c1, (uint8_t*)CTS_buf, 2, 10000) != HAL_OK) { + sprintf((char*)debug_buf, "Failed to get CTS: %ld\r\n", HAL_I2C_GetError(&hi2c1)); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + Error_Handler(); + } + else { + sprintf((char*)debug_buf, "Got CTS\r\n"); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + } + + if (HAL_I2C_Slave_Transmit(&hi2c1, (uint8_t*)data_buf, data_enc_size, 10000) != HAL_OK) { + sprintf((char*)debug_buf, "Data I2C send error: %ld\r\n", HAL_I2C_GetError(&hi2c1)); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + Error_Handler(); + } + else { + sprintf((char*)debug_buf, "SENT DATA\r\n"); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + } + } } #endif /* MASTER */ @@ -430,11 +525,251 @@ __DEBUG_BLOCK_END: return hs_sts; } -dataflow_status_t device_dataflow(uint8_t i2c_addr) +dataflow_status_t device_dataflow(uint8_t i2c_addr, uint32_t SOR_code) { - uint8_t dev_idx = GET_IDX_FROM_ADDR(i2c_addr); - dataflow_status_t status; + uint8_t dev_idx = GET_IDX_FROM_ADDR(i2c_addr); + dataflow_status_t df_status = DF_IDLE; + + uint8_t *SOR_buf, *DOC_buf, *CTS_buf, *data_buf; + uint32_t AF_error_counter = 0; + uint32_t data_len = 0; + _datapoint datapoints[16]; + m2s_SOR SOR_message = m2s_SOR_init_default; + s2m_DOC DOC_message = s2m_DOC_init_zero; + /* TODO Add default values to the CTS message in proto */ + m2s_CTS CTS_message = m2s_CTS_init_default; + s2m_data data_message = s2m_data_init_zero; +#if defined(TESTING_ENABLE) || defined(DEBUG_ENABLE) + uint8_t debug_buf[128]; +#endif +#ifdef TESTING_ENABLE + uint8_t term[] = "\r\n"; +#endif + + while (df_status != DF_SUCCESS && df_status != DF_FAIL) { + switch (df_status) { + case (DF_IDLE): + { + SOR_buf = malloc(sizeof(m2s_SOR)); + pb_ostream_t SOR_stream = pb_ostream_from_buffer(SOR_buf, sizeof(SOR_buf)); + SOR_message.SOR_code = SOR_code; + if (!pb_encode(&SOR_stream, m2s_SOR_fields, &SOR_message)) { + df_status = DF_FAIL; +#ifdef DEBUG_ENABLE + goto __DF_SOR_ENC_FAIL; + __DF_SOR_ENC_FAIL_END: + __asm__("nop"); +#endif + } + else { + if (HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr, (uint8_t*)SOR_buf, + m2s_SOR_size, 10000) != HAL_OK) { + df_status = DF_FAIL; +#ifdef DEBUG_ENABLE + goto __DF_SOR_I2C_ERROR; + __DF_SOR_I2C_ERROR_END: + __asm__("nop"); +#endif + } + else { + if (SOR_code == SLAVE_TX) { + df_status = DF_RX_DOC; + } + else if (SOR_code == SLAVE_RX_DATAPOINT) { + /* TODO */ + } + else if (SOR_code == SLAVE_RX_COMMAND) { + /* TODO */ + } + } + } + break; + } + case (DF_RX_DOC): + { + DOC_buf = (uint8_t*)malloc(4); + AF_error_counter = 0; + while (HAL_I2C_Master_Receive(&hi2c1, (uint16_t)i2c_addr, + (uint8_t*)DOC_buf, 4, 1000) != HAL_OK) { + if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF) { + df_status = DF_FAIL; +#ifdef DEBUG_ENABLE + goto __DF_DOC_I2C_ERROR; + __DF_DOC_I2C_ERROR_END: + __asm__("nop"); +#endif + break; + } + else if (++AF_error_counter > 4000) { + df_status = DF_FAIL; + break; + } + } + if (df_status != DF_FAIL) { + pb_istream_t DOC_istream = pb_istream_from_buffer(DOC_buf, 4); + if (!pb_decode(&DOC_istream, s2m_DOC_fields, &DOC_message)) { + df_status = DF_FAIL; +#ifdef DEBUG_ENABLE + goto __DF_DOC_DECODE_ERROR; + __DF_DOC_DECODE_ERROR_END: + __asm__("nop"); +#endif + } + else { + if (DOC_message.DOC_code == DATA) { + df_status = DF_CTS; + data_len = DOC_message.tx_length; + } + else if (DOC_message.DOC_code == CMD_UNICAST) { + /* TODO */ + } + else if (DOC_message.DOC_code == CMD_MULTICAST) { + /* TODO */ + } + else if (DOC_message.DOC_code == CMD_BROADCAST) { + /* TODO */ + } + } + } + break; + } + case (DF_CTS): + { + CTS_buf = (uint8_t*)malloc(8); + pb_ostream_t CTS_ostream = pb_ostream_from_buffer(CTS_buf, 8); + CTS_message.timeout = 100; + + if (!pb_encode(&CTS_ostream, m2s_CTS_fields, &CTS_message)) { + df_status = DF_FAIL; +#ifdef DEBUG_ENABLE + goto __DF_CTS_ENC_FAIL; + __DF_CTS_ENC_FAIL_END: + __asm__("nop"); +#endif + } + else { + HAL_Delay(100); + if (HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr, (uint8_t*)CTS_buf, + 2, 10000) != HAL_OK) { + df_status = DF_FAIL; +#ifdef DEBUG_ENABLE + goto __DF_CTS_I2C_ERROR; + __DF_CTS_I2C_ERROR_END: + __asm__("nop"); +#endif + } + else { + if (DOC_message.DOC_code == DATA) { + df_status = DF_RX_DATA; + } + else { + /* TODO */ + } + } + } + break; + } + case (DF_RX_DATA): + { + data_buf = (uint8_t*)malloc(128); + AF_error_counter = 0; + while (HAL_I2C_Master_Receive(&hi2c1, (uint16_t)i2c_addr, + (uint8_t*)data_buf, data_len, 10000) != HAL_OK) { + if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF) { + df_status = DF_FAIL; +#ifdef DEBUG_ENABLE + goto __DF_DATA_I2C_ERROR; + __DF_DATA_I2C_ERROR_END: + __asm__("nop"); +#endif + break; + } + else if (++AF_error_counter > 1500) { + df_status = DF_FAIL; + break; + } + } + if (df_status != DF_FAIL) { + data_idx = 0; + data_message.datapoints.funcs.decode = decode_data_callback; + data_message.datapoints.arg = (void*)datapoints; + pb_istream_t data_istream = pb_istream_from_buffer(data_buf, data_len); + if (!pb_decode(&data_istream, s2m_data_fields, &data_message)) { + df_status = DF_FAIL; +#ifdef DEBUG_ENABLE + goto __DF_DATA_DECODE_ERROR; + __DF_DATA_DECODE_ERROR_END: + __asm__("nop"); +#endif + } + else { + df_status = DF_SUCCESS; + } + } + break; + } + } + } + +#ifdef TESTING_ENABLE + { + goto __DF_TESTING_BLOCK_END; + + __DF_TESTING_BLOCK_END: + __asm__("nop"); + } +#endif + +#ifdef DEBUG_ENABLE + { + goto __DF_DEBUG_BLOCK_END; + __DF_SOR_ENC_FAIL: + sprintf((char*)debug_buf, "SOR encoding error\r\n"); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + goto __DF_SOR_ENC_FAIL_END; + __DF_SOR_I2C_ERROR: + sprintf((char*)debug_buf, "Unable to send SOR request. I2C error: %ld\r\n", HAL_I2C_GetError(&hi2c1)); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + goto __DF_SOR_I2C_ERROR_END; + __DF_DOC_I2C_ERROR: + sprintf((char*)debug_buf, "Unable to receive DOC. I2C error: %ld\r\n", HAL_I2C_GetError(&hi2c1)); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + goto __DF_DOC_I2C_ERROR_END; + __DF_DOC_DECODE_ERROR: + sprintf((char*)debug_buf, "DOC decoding error\r\n"); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + goto __DF_DOC_DECODE_ERROR_END; + __DF_CTS_ENC_FAIL: + sprintf((char*)debug_buf, "CTS encoding error\r\n"); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + goto __DF_CTS_ENC_FAIL_END; + __DF_CTS_I2C_ERROR: + sprintf((char*)debug_buf, "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); + goto __DF_CTS_I2C_ERROR_END; + __DF_DATA_I2C_ERROR: + sprintf((char*)debug_buf, "Unable to receive data. I2C error: %ld\r\n", HAL_I2C_GetError(&hi2c1)); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + goto __DF_DATA_I2C_ERROR_END; + __DF_DATA_DECODE_ERROR: + sprintf((char*)debug_buf, "Data decoding error\r\n"); + HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100); + memset(debug_buf, 0, 128); + goto __DF_DATA_DECODE_ERROR_END; + __DF_DEBUG_BLOCK_END: + __asm__("nop"); + } +#endif + + return df_status; } bool decode_subscriptions_callback(pb_istream_t *istream, const pb_field_t *field, void **args) @@ -536,6 +871,54 @@ bool encode_subscription_callback(pb_ostream_t *ostream, const pb_field_t *field return true; } +bool encode_datapoint_callback(pb_ostream_t *ostream, const pb_field_t *field, void * const *arg) +{ + if (ostream != NULL && field->tag == s2m_data_datapoints_tag) { + for (int i = 0; i < 4; i++) { + _datapoint datapoint = _datapoint_init_zero; + datapoint.entity_id = 1; + datapoint.data = 20.70+((float)i/100); + if (!pb_encode_tag_for_field(ostream, field)) + return false; + if (!pb_encode_submessage(ostream, _datapoint_fields, &datapoint)) + return false; + } + } + else + return false; + return true; +} + +bool decode_data_callback(pb_istream_t *istream, const pb_field_t *field, void **args) +{ + _datapoint loc_datapoint = _datapoint_init_zero; + _datapoint *datapoint = *args; + + if (!pb_decode(istream, _datapoint_fields, &loc_datapoint)) + return false; + + datapoint[data_idx].data = datapoint[data_idx].entity_id = 0; + + datapoint[data_idx].entity_id = loc_datapoint.entity_id; + datapoint[data_idx].data = loc_datapoint.data; + + if (loc_datapoint.has_channel_id) { + datapoint[data_idx].has_channel_id = true; + datapoint[data_idx].channel_id = loc_datapoint.channel_id; + } + if (loc_datapoint.has_unit_id) { + datapoint[data_idx].has_unit_id = true; + datapoint[data_idx].unit_id = loc_datapoint.unit_id; + } + if (loc_datapoint.has_timestamp) { + datapoint[data_idx].has_timestamp = true; + datapoint[data_idx].timestamp = loc_datapoint.timestamp; + } + + data_idx++; + return true; +} + /** * @brief System Clock Configuration * @retval None |
