summaryrefslogtreecommitdiff
path: root/src/main-data.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main-data.c')
-rw-r--r--src/main-data.c397
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