summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--data.proto83
-rw-r--r--handshake.proto9
-rw-r--r--lib/nanopb/pb.h (renamed from src/pb.h)0
-rw-r--r--lib/nanopb/pb_common.c (renamed from src/pb_common.c)0
-rw-r--r--lib/nanopb/pb_common.h (renamed from src/pb_common.h)0
-rw-r--r--lib/nanopb/pb_decode.c (renamed from src/pb_decode.c)0
-rw-r--r--lib/nanopb/pb_decode.h (renamed from src/pb_decode.h)0
-rw-r--r--lib/nanopb/pb_encode.c (renamed from src/pb_encode.c)0
-rw-r--r--lib/nanopb/pb_encode.h (renamed from src/pb_encode.h)0
-rw-r--r--makefile88
-rw-r--r--ports/stm32f4/STM32F401CCUx_FLASH.ld (renamed from STM32F401CCUx_FLASH.ld)0
-rw-r--r--ports/stm32f4/STM32F405RGTx_FLASH.ld209
-rw-r--r--ports/stm32f4/makefile41
-rw-r--r--ports/stm32f4/startup_stm32f401xc.s (renamed from startup_stm32f401xc.s)0
-rw-r--r--ports/stm32f4/startup_stm32f405xx.s516
-rw-r--r--src/config.h16
-rw-r--r--src/data.pb.c38
-rw-r--r--src/data.pb.h181
-rw-r--r--src/dataflow.h46
-rw-r--r--src/devices.h3
-rw-r--r--src/master.c (renamed from src/main.c)798
-rw-r--r--src/slave.c463
23 files changed, 2117 insertions, 377 deletions
diff --git a/.gitignore b/.gitignore
index ca19639..6a8c4a9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,4 +11,5 @@ uctrl-firmware.txt
*.o
*.bin
*~
-MDK-ARM/ \ No newline at end of file
+MDK-ARM/
+tmp.org \ No newline at end of file
diff --git a/data.proto b/data.proto
new file mode 100644
index 0000000..1506fb0
--- /dev/null
+++ b/data.proto
@@ -0,0 +1,83 @@
+// Protocol for Dataflow
+
+syntax = "proto2";
+
+
+/*
+* SOR codes
+*
+* |------|----------------------|
+* | Code | Instruction |
+* | 1 | TX from slave |
+* | 2 | RX datapoint |
+* | 3 | RX command |
+* |------|----------------------|
+*
+*/
+
+message m2s_SOR {
+ required uint32 SOR_code = 1 [default=1];
+
+ /* If master wants slave to receive something, it also puts the rx length in the SOR */
+ optional uint32 rx_length = 2;
+}
+
+
+/* DOC Codes
+*
+* |------|----------------------|
+* | Code | Instruction |
+* | 1 | Unicast command |
+* | 2 | Multicast command |
+* | 3 | Broadcast command |
+* | 4 | Reserved |
+* | 5 | Data |
+* |------|----------------------|
+*
+*/
+
+message s2m_DOC {
+ /* If master wants to receive something from the slave, the slave specifies whether
+ it is sending a command or data */
+ required uint32 DOC_code = 1 [default=1];
+
+ /* Also encode the length of the next transmission */
+ required uint32 tx_length = 2 [default=0];
+
+}
+
+message m2s_CTS {
+ required uint32 timeout = 1;
+}
+
+/* Commands when SOR code is 3 */
+message m2s_command {
+ optional uint32 source_module_id = 1 [default=1];
+ optional uint32 source_i2c_address = 2 [default=1];
+
+ optional bytes cmd_bytes = 3;
+ optional string cmd_str = 4;
+}
+
+/* Commands from slave */
+message s2m_command {
+ optional uint32 dest_module_id = 1;
+ repeated uint32 dest_module_id_multicast = 2;
+
+ optional bytes cmd_bytes = 3;
+ optional string cmd_str = 4;
+}
+
+message _datapoint {
+ required uint32 entity_id = 1 [default=0];
+ required double data = 2 [default=0];
+
+ optional uint32 channel_id = 3 [default=1];
+ optional uint32 unit_id = 4 [default=1];
+ optional int32 timestamp = 5 [default=1];
+
+}
+
+message s2m_data {
+ repeated _datapoint datapoints = 1;
+} \ No newline at end of file
diff --git a/handshake.proto b/handshake.proto
index 611e600..4009a2e 100644
--- a/handshake.proto
+++ b/handshake.proto
@@ -9,6 +9,15 @@ message m2s_MDR_request {
required uint32 record_type = 1;
}
+message s2m_MDR_req_ACK {
+ // ACK the MDR request with the length of MDR response
+ required uint32 MDR_res_length = 1;
+}
+
+message m2s_MDR_res_CTS {
+ required uint32 timeout = 1;
+}
+
message _subscriptions {
optional uint32 module_id = 1 [default=0];
optional uint32 entity_id = 2 [default=0];
diff --git a/src/pb.h b/lib/nanopb/pb.h
index fc0f387..fc0f387 100644
--- a/src/pb.h
+++ b/lib/nanopb/pb.h
diff --git a/src/pb_common.c b/lib/nanopb/pb_common.c
index dfc5a05..dfc5a05 100644
--- a/src/pb_common.c
+++ b/lib/nanopb/pb_common.c
diff --git a/src/pb_common.h b/lib/nanopb/pb_common.h
index 47fa2c9..47fa2c9 100644
--- a/src/pb_common.h
+++ b/lib/nanopb/pb_common.h
diff --git a/src/pb_decode.c b/lib/nanopb/pb_decode.c
index f936412..f936412 100644
--- a/src/pb_decode.c
+++ b/lib/nanopb/pb_decode.c
diff --git a/src/pb_decode.h b/lib/nanopb/pb_decode.h
index b64d95a..b64d95a 100644
--- a/src/pb_decode.h
+++ b/lib/nanopb/pb_decode.h
diff --git a/src/pb_encode.c b/lib/nanopb/pb_encode.c
index 409fec3..409fec3 100644
--- a/src/pb_encode.c
+++ b/lib/nanopb/pb_encode.c
diff --git a/src/pb_encode.h b/lib/nanopb/pb_encode.h
index 88e246a..88e246a 100644
--- a/src/pb_encode.h
+++ b/lib/nanopb/pb_encode.h
diff --git a/makefile b/makefile
index cd3ad1a..a6914cc 100644
--- a/makefile
+++ b/makefile
@@ -1,18 +1,4 @@
-##########################################################################################################################
-# File automatically-generated by tool: [projectgenerator] version: [3.5.2] date: [Mon Mar 23 16:58:19 EDT 2020]
-##########################################################################################################################
-
-# ------------------------------------------------
-# Generic Makefile (based on gcc)
-#
-# ChangeLog :
-# 2017-02-10 - Several enhancements + project update mode
-# 2015-07-22 - first version
-# ------------------------------------------------
-
-######################################
-# target
-######################################
+# Target also determines which file is being compiled
TARGET = master
@@ -34,34 +20,14 @@ BUILD_DIR = build
######################################
# source
######################################
-# C sources
+# C sources for all ports
C_SOURCES = \
src/main-rtos.c \
-src/stm32f4xx_it.c \
-src/stm32f4xx_hal_msp.c \
-src/system_stm32f4xx.c \
-src/pb_decode.c \
-src/pb_encode.c \
-src/pb_common.c \
+lib/nanopb/pb_decode.c \
+lib/nanopb/pb_encode.c \
+lib/nanopb/pb_common.c \
src/handshake.pb.c \
-lib/f4/stm32f4xx_hal_i2c.c \
-lib/f4/stm32f4xx_hal_i2c_ex.c \
-lib/f4/stm32f4xx_hal_rcc.c \
-lib/f4/stm32f4xx_hal_rcc_ex.c \
-lib/f4/stm32f4xx_hal_flash.c \
-lib/f4/stm32f4xx_hal_flash_ex.c \
-lib/f4/stm32f4xx_hal_flash_ramfunc.c \
-lib/f4/stm32f4xx_hal_gpio.c \
-lib/f4/stm32f4xx_hal_dma_ex.c \
-lib/f4/stm32f4xx_hal_dma.c \
-lib/f4/stm32f4xx_hal_pwr.c \
-lib/f4/stm32f4xx_hal_pwr_ex.c \
-lib/f4/stm32f4xx_hal_cortex.c \
-lib/f4/stm32f4xx_hal.c \
-lib/f4/stm32f4xx_hal_exti.c \
-lib/f4/stm32f4xx_hal_tim.c \
-lib/f4/stm32f4xx_hal_tim_ex.c \
-lib/f4/stm32f4xx_hal_uart.c \
+src/data.pb.c \
lib/freertos/tasks.c \
lib/freertos/list.c \
lib/freertos/queue.c \
@@ -70,10 +36,8 @@ lib/freertos/event_groups.c \
lib/freertos/timers.c \
lib/freertos/memmang/heap_4.c
-# ASM sources
-ASM_SOURCES = \
-startup_stm32f401xc.s
-
+# set the main C source based on whether we're compiling the master or slave
+C_SOURCES+=$(addprefix src/, $(TARGET).c)
#######################################
# binaries
@@ -98,39 +62,25 @@ BIN = $(CP) -O binary -S
#######################################
# CFLAGS
#######################################
-# cpu
-CPU = -mcpu=cortex-m4
-
-# fpu
-FPU = -mfpu=fpv4-sp-d16
-
-# float-abi
-FLOAT-ABI = -mfloat-abi=hard
-
-# mcu
-MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)
-
# macros for gcc
# AS defines
AS_DEFS =
-# C defines
-C_DEFS = \
--DUSE_HAL_DRIVER \
--DSTM32F401xC
-
-
# AS includes
AS_INCLUDES =
-# C includes
+# General C includes for all ports. Since CMSIS is being included, that means this is restricted to ARM ports
C_INCLUDES = \
-Isrc \
--Ilib/f4 \
--Ilib/f4/Legacy \
-Ilib/cmsis \
--Ilib/cmsis/f4 \
-Ilib/freertos/include
+-Ilib/nanopb
+
+# Define the chip we're building for and include its makefile
+PORT = stm32f4
+PORT_DIR = ports/$(PORT)
+include $(PORT_DIR)/makefile
+ASM_SOURCES=$(PORT_DIR)/$(ASM_FILE)
# compile gcc flags
ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
@@ -141,21 +91,19 @@ ifeq ($(DEBUG), 1)
CFLAGS += -g -gdwarf-2
endif
-
# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
-
#######################################
# LDFLAGS
#######################################
# link script
-LDSCRIPT = STM32F401CCUx_FLASH.ld
+# LDSCRIPT = STM32F401CCUx_FLASH.ld
# libraries
LIBS = -lc -lm -lnosys
LIBDIR =
-LDFLAGS = $(MCU) -specs=nosys.specs -specs=nano.specs -u _printf_float -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections
+LDFLAGS = $(MCU) -specs=nosys.specs -specs=nano.specs -u _printf_float -T$(PORT_DIR)/$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections
# default action: build all
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin
diff --git a/STM32F401CCUx_FLASH.ld b/ports/stm32f4/STM32F401CCUx_FLASH.ld
index 4f0561c..4f0561c 100644
--- a/STM32F401CCUx_FLASH.ld
+++ b/ports/stm32f4/STM32F401CCUx_FLASH.ld
diff --git a/ports/stm32f4/STM32F405RGTx_FLASH.ld b/ports/stm32f4/STM32F405RGTx_FLASH.ld
new file mode 100644
index 0000000..cfa7433
--- /dev/null
+++ b/ports/stm32f4/STM32F405RGTx_FLASH.ld
@@ -0,0 +1,209 @@
+/*
+******************************************************************************
+**
+
+** File : LinkerScript.ld
+**
+** Author : Auto-generated by System Workbench for STM32
+**
+** Abstract : Linker script for STM32F405RGTx series
+** 1024Kbytes FLASH and 128Kbytes RAM
+**
+** Set heap size, stack size and stack location according
+** to application requirements.
+**
+** Set memory bank area and size if external memory is used.
+**
+** Target : STMicroelectronics STM32
+**
+** Distribution: The file is distributed “as is,” without any warranty
+** of any kind.
+**
+*****************************************************************************
+** @attention
+**
+** <h2><center>&copy; COPYRIGHT(c) 2019 STMicroelectronics</center></h2>
+**
+** Redistribution and use in source and binary forms, with or without modification,
+** are permitted provided that the following conditions are met:
+** 1. Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+** 2. Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+** 3. Neither the name of STMicroelectronics nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+*****************************************************************************
+*/
+
+/* Entry Point */
+ENTRY(Reset_Handler)
+
+/* Highest address of the user mode stack */
+_estack = 0x20020000; /* end of RAM */
+/* Generate a link error if heap and stack don't fit into RAM */
+_Min_Heap_Size = 0x200; /* required amount of heap */
+_Min_Stack_Size = 0x400; /* required amount of stack */
+
+/* Specify the memory areas */
+MEMORY
+{
+RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
+CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
+FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
+}
+
+/* Define output sections */
+SECTIONS
+{
+ /* The startup code goes first into FLASH */
+ .isr_vector :
+ {
+ . = ALIGN(4);
+ KEEP(*(.isr_vector)) /* Startup code */
+ . = ALIGN(4);
+ } >FLASH
+
+ /* The program code and other data goes into FLASH */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text) /* .text sections (code) */
+ *(.text*) /* .text* sections (code) */
+ *(.glue_7) /* glue arm to thumb code */
+ *(.glue_7t) /* glue thumb to arm code */
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ . = ALIGN(4);
+ _etext = .; /* define a global symbols at end of code */
+ } >FLASH
+
+ /* Constant data goes into FLASH */
+ .rodata :
+ {
+ . = ALIGN(4);
+ *(.rodata) /* .rodata sections (constants, strings, etc.) */
+ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
+ . = ALIGN(4);
+ } >FLASH
+
+ .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
+ .ARM : {
+ __exidx_start = .;
+ *(.ARM.exidx*)
+ __exidx_end = .;
+ } >FLASH
+
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array*))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >FLASH
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array*))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ } >FLASH
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array*))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } >FLASH
+
+ /* used by the startup to initialize data */
+ _sidata = LOADADDR(.data);
+
+ /* Initialized data sections goes into RAM, load LMA copy after code */
+ .data :
+ {
+ . = ALIGN(4);
+ _sdata = .; /* create a global symbol at data start */
+ *(.data) /* .data sections */
+ *(.data*) /* .data* sections */
+
+ . = ALIGN(4);
+ _edata = .; /* define a global symbol at data end */
+ } >RAM AT> FLASH
+
+ _siccmram = LOADADDR(.ccmram);
+
+ /* CCM-RAM section
+ *
+ * IMPORTANT NOTE!
+ * If initialized variables will be placed in this section,
+ * the startup code needs to be modified to copy the init-values.
+ */
+ .ccmram :
+ {
+ . = ALIGN(4);
+ _sccmram = .; /* create a global symbol at ccmram start */
+ *(.ccmram)
+ *(.ccmram*)
+
+ . = ALIGN(4);
+ _eccmram = .; /* create a global symbol at ccmram end */
+ } >CCMRAM AT> FLASH
+
+
+ /* Uninitialized data section */
+ . = ALIGN(4);
+ .bss :
+ {
+ /* This is used by the startup in order to initialize the .bss secion */
+ _sbss = .; /* define a global symbol at bss start */
+ __bss_start__ = _sbss;
+ *(.bss)
+ *(.bss*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = .; /* define a global symbol at bss end */
+ __bss_end__ = _ebss;
+ } >RAM
+
+ /* User_heap_stack section, used to check that there is enough RAM left */
+ ._user_heap_stack :
+ {
+ . = ALIGN(8);
+ PROVIDE ( end = . );
+ PROVIDE ( _end = . );
+ . = . + _Min_Heap_Size;
+ . = . + _Min_Stack_Size;
+ . = ALIGN(8);
+ } >RAM
+
+
+
+ /* Remove information from the standard libraries */
+ /DISCARD/ :
+ {
+ libc.a ( * )
+ libm.a ( * )
+ libgcc.a ( * )
+ }
+
+ .ARM.attributes 0 : { *(.ARM.attributes) }
+}
+
+
diff --git a/ports/stm32f4/makefile b/ports/stm32f4/makefile
new file mode 100644
index 0000000..5a32ead
--- /dev/null
+++ b/ports/stm32f4/makefile
@@ -0,0 +1,41 @@
+# Makefile for the STM32F4 port
+
+# These variables are dependent on the target MCU
+LDSCRIPT=STM32F405RGTx_FLASH.ld
+ASM_FILE=startup_stm32f405xx.s
+C_DEFS += \
+-DSTM32F405xx
+
+FLOAT-ABI = -mfloat-abi=hard
+CPU = -mcpu=cortex-m4
+FPU = -mfpu=fpv4-sp-d16
+MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)
+
+# Library files common to all F4 MCUs
+C_SOURCES += \
+lib/f4/stm32f4xx_hal_i2c.c \
+lib/f4/stm32f4xx_hal_i2c_ex.c \
+lib/f4/stm32f4xx_hal_rcc.c \
+lib/f4/stm32f4xx_hal_rcc_ex.c \
+lib/f4/stm32f4xx_hal_flash.c \
+lib/f4/stm32f4xx_hal_flash_ex.c \
+lib/f4/stm32f4xx_hal_flash_ramfunc.c \
+lib/f4/stm32f4xx_hal_gpio.c \
+lib/f4/stm32f4xx_hal_dma_ex.c \
+lib/f4/stm32f4xx_hal_dma.c \
+lib/f4/stm32f4xx_hal_pwr.c \
+lib/f4/stm32f4xx_hal_pwr_ex.c \
+lib/f4/stm32f4xx_hal_cortex.c \
+lib/f4/stm32f4xx_hal.c \
+lib/f4/stm32f4xx_hal_exti.c \
+lib/f4/stm32f4xx_hal_tim.c \
+lib/f4/stm32f4xx_hal_tim_ex.c \
+lib/f4/stm32f4xx_hal_uart.c \
+src/stm32f4xx_it.c \
+src/stm32f4xx_hal_msp.c \
+src/system_stm32f4xx.c \
+
+C_INCLUDES += \
+-Ilib/f4 \
+-Ilib/f4/Legacy \
+-Ilib/cmsis/f4 \
diff --git a/startup_stm32f401xc.s b/ports/stm32f4/startup_stm32f401xc.s
index c4078d3..c4078d3 100644
--- a/startup_stm32f401xc.s
+++ b/ports/stm32f4/startup_stm32f401xc.s
diff --git a/ports/stm32f4/startup_stm32f405xx.s b/ports/stm32f4/startup_stm32f405xx.s
new file mode 100644
index 0000000..b2ad563
--- /dev/null
+++ b/ports/stm32f4/startup_stm32f405xx.s
@@ -0,0 +1,516 @@
+/**
+ ******************************************************************************
+ * @file startup_stm32f405xx.s
+ * @author MCD Application Team
+ * @brief STM32F405xx Devices vector table for GCC based toolchains.
+ * This module performs:
+ * - Set the initial SP
+ * - Set the initial PC == Reset_Handler,
+ * - Set the vector table entries with the exceptions ISR address
+ * - Branches to main in the C library (which eventually
+ * calls main()).
+ * After Reset the Cortex-M4 processor is in Thread mode,
+ * priority is Privileged, and the Stack is set to Main.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2017 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+ .syntax unified
+ .cpu cortex-m4
+ .fpu softvfp
+ .thumb
+
+.global g_pfnVectors
+.global Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word _sidata
+/* start address for the .data section. defined in linker script */
+.word _sdata
+/* end address for the .data section. defined in linker script */
+.word _edata
+/* start address for the .bss section. defined in linker script */
+.word _sbss
+/* end address for the .bss section. defined in linker script */
+.word _ebss
+/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
+
+/**
+ * @brief This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ * @param None
+ * @retval : None
+*/
+
+ .section .text.Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+ ldr sp, =_estack /* set stack pointer */
+
+/* Copy the data segment initializers from flash to SRAM */
+ movs r1, #0
+ b LoopCopyDataInit
+
+CopyDataInit:
+ ldr r3, =_sidata
+ ldr r3, [r3, r1]
+ str r3, [r0, r1]
+ adds r1, r1, #4
+
+LoopCopyDataInit:
+ ldr r0, =_sdata
+ ldr r3, =_edata
+ adds r2, r0, r1
+ cmp r2, r3
+ bcc CopyDataInit
+ ldr r2, =_sbss
+ b LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+ movs r3, #0
+ str r3, [r2], #4
+
+LoopFillZerobss:
+ ldr r3, = _ebss
+ cmp r2, r3
+ bcc FillZerobss
+
+/* Call the clock system intitialization function.*/
+ bl SystemInit
+/* Call static constructors */
+ bl __libc_init_array
+/* Call the application's entry point.*/
+ bl main
+ bx lr
+.size Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief This is the code that gets called when the processor receives an
+ * unexpected interrupt. This simply enters an infinite loop, preserving
+ * the system state for examination by a debugger.
+ * @param None
+ * @retval None
+*/
+ .section .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+ b Infinite_Loop
+ .size Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+*******************************************************************************/
+ .section .isr_vector,"a",%progbits
+ .type g_pfnVectors, %object
+ .size g_pfnVectors, .-g_pfnVectors
+
+
+
+g_pfnVectors:
+ .word _estack
+ .word Reset_Handler
+
+ .word NMI_Handler
+ .word HardFault_Handler
+ .word MemManage_Handler
+ .word BusFault_Handler
+ .word UsageFault_Handler
+ .word 0
+ .word 0
+ .word 0
+ .word 0
+ .word SVC_Handler
+ .word DebugMon_Handler
+ .word 0
+ .word PendSV_Handler
+ .word SysTick_Handler
+
+ /* External Interrupts */
+ .word WWDG_IRQHandler /* Window WatchDog */
+ .word PVD_IRQHandler /* PVD through EXTI Line detection */
+ .word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */
+ .word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */
+ .word FLASH_IRQHandler /* FLASH */
+ .word RCC_IRQHandler /* RCC */
+ .word EXTI0_IRQHandler /* EXTI Line0 */
+ .word EXTI1_IRQHandler /* EXTI Line1 */
+ .word EXTI2_IRQHandler /* EXTI Line2 */
+ .word EXTI3_IRQHandler /* EXTI Line3 */
+ .word EXTI4_IRQHandler /* EXTI Line4 */
+ .word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */
+ .word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */
+ .word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */
+ .word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */
+ .word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */
+ .word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */
+ .word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */
+ .word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */
+ .word CAN1_TX_IRQHandler /* CAN1 TX */
+ .word CAN1_RX0_IRQHandler /* CAN1 RX0 */
+ .word CAN1_RX1_IRQHandler /* CAN1 RX1 */
+ .word CAN1_SCE_IRQHandler /* CAN1 SCE */
+ .word EXTI9_5_IRQHandler /* External Line[9:5]s */
+ .word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */
+ .word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */
+ .word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */
+ .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
+ .word TIM2_IRQHandler /* TIM2 */
+ .word TIM3_IRQHandler /* TIM3 */
+ .word TIM4_IRQHandler /* TIM4 */
+ .word I2C1_EV_IRQHandler /* I2C1 Event */
+ .word I2C1_ER_IRQHandler /* I2C1 Error */
+ .word I2C2_EV_IRQHandler /* I2C2 Event */
+ .word I2C2_ER_IRQHandler /* I2C2 Error */
+ .word SPI1_IRQHandler /* SPI1 */
+ .word SPI2_IRQHandler /* SPI2 */
+ .word USART1_IRQHandler /* USART1 */
+ .word USART2_IRQHandler /* USART2 */
+ .word USART3_IRQHandler /* USART3 */
+ .word EXTI15_10_IRQHandler /* External Line[15:10]s */
+ .word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */
+ .word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */
+ .word TIM8_BRK_TIM12_IRQHandler /* TIM8 Break and TIM12 */
+ .word TIM8_UP_TIM13_IRQHandler /* TIM8 Update and TIM13 */
+ .word TIM8_TRG_COM_TIM14_IRQHandler /* TIM8 Trigger and Commutation and TIM14 */
+ .word TIM8_CC_IRQHandler /* TIM8 Capture Compare */
+ .word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */
+ .word FSMC_IRQHandler /* FSMC */
+ .word SDIO_IRQHandler /* SDIO */
+ .word TIM5_IRQHandler /* TIM5 */
+ .word SPI3_IRQHandler /* SPI3 */
+ .word UART4_IRQHandler /* UART4 */
+ .word UART5_IRQHandler /* UART5 */
+ .word TIM6_DAC_IRQHandler /* TIM6 and DAC1&2 underrun errors */
+ .word TIM7_IRQHandler /* TIM7 */
+ .word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */
+ .word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */
+ .word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */
+ .word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */
+ .word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word CAN2_TX_IRQHandler /* CAN2 TX */
+ .word CAN2_RX0_IRQHandler /* CAN2 RX0 */
+ .word CAN2_RX1_IRQHandler /* CAN2 RX1 */
+ .word CAN2_SCE_IRQHandler /* CAN2 SCE */
+ .word OTG_FS_IRQHandler /* USB OTG FS */
+ .word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */
+ .word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */
+ .word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */
+ .word USART6_IRQHandler /* USART6 */
+ .word I2C3_EV_IRQHandler /* I2C3 event */
+ .word I2C3_ER_IRQHandler /* I2C3 error */
+ .word OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */
+ .word OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */
+ .word OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */
+ .word OTG_HS_IRQHandler /* USB OTG HS */
+ .word 0 /* Reserved */
+ .word 0 /* Reserved */
+ .word HASH_RNG_IRQHandler /* Hash and Rng */
+ .word FPU_IRQHandler /* FPU */
+
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+ .weak NMI_Handler
+ .thumb_set NMI_Handler,Default_Handler
+
+ .weak HardFault_Handler
+ .thumb_set HardFault_Handler,Default_Handler
+
+ .weak MemManage_Handler
+ .thumb_set MemManage_Handler,Default_Handler
+
+ .weak BusFault_Handler
+ .thumb_set BusFault_Handler,Default_Handler
+
+ .weak UsageFault_Handler
+ .thumb_set UsageFault_Handler,Default_Handler
+
+ .weak SVC_Handler
+ .thumb_set SVC_Handler,Default_Handler
+
+ .weak DebugMon_Handler
+ .thumb_set DebugMon_Handler,Default_Handler
+
+ .weak PendSV_Handler
+ .thumb_set PendSV_Handler,Default_Handler
+
+ .weak SysTick_Handler
+ .thumb_set SysTick_Handler,Default_Handler
+
+ .weak WWDG_IRQHandler
+ .thumb_set WWDG_IRQHandler,Default_Handler
+
+ .weak PVD_IRQHandler
+ .thumb_set PVD_IRQHandler,Default_Handler
+
+ .weak TAMP_STAMP_IRQHandler
+ .thumb_set TAMP_STAMP_IRQHandler,Default_Handler
+
+ .weak RTC_WKUP_IRQHandler
+ .thumb_set RTC_WKUP_IRQHandler,Default_Handler
+
+ .weak FLASH_IRQHandler
+ .thumb_set FLASH_IRQHandler,Default_Handler
+
+ .weak RCC_IRQHandler
+ .thumb_set RCC_IRQHandler,Default_Handler
+
+ .weak EXTI0_IRQHandler
+ .thumb_set EXTI0_IRQHandler,Default_Handler
+
+ .weak EXTI1_IRQHandler
+ .thumb_set EXTI1_IRQHandler,Default_Handler
+
+ .weak EXTI2_IRQHandler
+ .thumb_set EXTI2_IRQHandler,Default_Handler
+
+ .weak EXTI3_IRQHandler
+ .thumb_set EXTI3_IRQHandler,Default_Handler
+
+ .weak EXTI4_IRQHandler
+ .thumb_set EXTI4_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream0_IRQHandler
+ .thumb_set DMA1_Stream0_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream1_IRQHandler
+ .thumb_set DMA1_Stream1_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream2_IRQHandler
+ .thumb_set DMA1_Stream2_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream3_IRQHandler
+ .thumb_set DMA1_Stream3_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream4_IRQHandler
+ .thumb_set DMA1_Stream4_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream5_IRQHandler
+ .thumb_set DMA1_Stream5_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream6_IRQHandler
+ .thumb_set DMA1_Stream6_IRQHandler,Default_Handler
+
+ .weak ADC_IRQHandler
+ .thumb_set ADC_IRQHandler,Default_Handler
+
+ .weak CAN1_TX_IRQHandler
+ .thumb_set CAN1_TX_IRQHandler,Default_Handler
+
+ .weak CAN1_RX0_IRQHandler
+ .thumb_set CAN1_RX0_IRQHandler,Default_Handler
+
+ .weak CAN1_RX1_IRQHandler
+ .thumb_set CAN1_RX1_IRQHandler,Default_Handler
+
+ .weak CAN1_SCE_IRQHandler
+ .thumb_set CAN1_SCE_IRQHandler,Default_Handler
+
+ .weak EXTI9_5_IRQHandler
+ .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+ .weak TIM1_BRK_TIM9_IRQHandler
+ .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler
+
+ .weak TIM1_UP_TIM10_IRQHandler
+ .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler
+
+ .weak TIM1_TRG_COM_TIM11_IRQHandler
+ .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler
+
+ .weak TIM1_CC_IRQHandler
+ .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+ .weak TIM2_IRQHandler
+ .thumb_set TIM2_IRQHandler,Default_Handler
+
+ .weak TIM3_IRQHandler
+ .thumb_set TIM3_IRQHandler,Default_Handler
+
+ .weak TIM4_IRQHandler
+ .thumb_set TIM4_IRQHandler,Default_Handler
+
+ .weak I2C1_EV_IRQHandler
+ .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+ .weak I2C1_ER_IRQHandler
+ .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+ .weak I2C2_EV_IRQHandler
+ .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+ .weak I2C2_ER_IRQHandler
+ .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+ .weak SPI1_IRQHandler
+ .thumb_set SPI1_IRQHandler,Default_Handler
+
+ .weak SPI2_IRQHandler
+ .thumb_set SPI2_IRQHandler,Default_Handler
+
+ .weak USART1_IRQHandler
+ .thumb_set USART1_IRQHandler,Default_Handler
+
+ .weak USART2_IRQHandler
+ .thumb_set USART2_IRQHandler,Default_Handler
+
+ .weak USART3_IRQHandler
+ .thumb_set USART3_IRQHandler,Default_Handler
+
+ .weak EXTI15_10_IRQHandler
+ .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+ .weak RTC_Alarm_IRQHandler
+ .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+ .weak OTG_FS_WKUP_IRQHandler
+ .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
+
+ .weak TIM8_BRK_TIM12_IRQHandler
+ .thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler
+
+ .weak TIM8_UP_TIM13_IRQHandler
+ .thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler
+
+ .weak TIM8_TRG_COM_TIM14_IRQHandler
+ .thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler
+
+ .weak TIM8_CC_IRQHandler
+ .thumb_set TIM8_CC_IRQHandler,Default_Handler
+
+ .weak DMA1_Stream7_IRQHandler
+ .thumb_set DMA1_Stream7_IRQHandler,Default_Handler
+
+ .weak FSMC_IRQHandler
+ .thumb_set FSMC_IRQHandler,Default_Handler
+
+ .weak SDIO_IRQHandler
+ .thumb_set SDIO_IRQHandler,Default_Handler
+
+ .weak TIM5_IRQHandler
+ .thumb_set TIM5_IRQHandler,Default_Handler
+
+ .weak SPI3_IRQHandler
+ .thumb_set SPI3_IRQHandler,Default_Handler
+
+ .weak UART4_IRQHandler
+ .thumb_set UART4_IRQHandler,Default_Handler
+
+ .weak UART5_IRQHandler
+ .thumb_set UART5_IRQHandler,Default_Handler
+
+ .weak TIM6_DAC_IRQHandler
+ .thumb_set TIM6_DAC_IRQHandler,Default_Handler
+
+ .weak TIM7_IRQHandler
+ .thumb_set TIM7_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream0_IRQHandler
+ .thumb_set DMA2_Stream0_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream1_IRQHandler
+ .thumb_set DMA2_Stream1_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream2_IRQHandler
+ .thumb_set DMA2_Stream2_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream3_IRQHandler
+ .thumb_set DMA2_Stream3_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream4_IRQHandler
+ .thumb_set DMA2_Stream4_IRQHandler,Default_Handler
+
+ .weak CAN2_TX_IRQHandler
+ .thumb_set CAN2_TX_IRQHandler,Default_Handler
+
+ .weak CAN2_RX0_IRQHandler
+ .thumb_set CAN2_RX0_IRQHandler,Default_Handler
+
+ .weak CAN2_RX1_IRQHandler
+ .thumb_set CAN2_RX1_IRQHandler,Default_Handler
+
+ .weak CAN2_SCE_IRQHandler
+ .thumb_set CAN2_SCE_IRQHandler,Default_Handler
+
+ .weak OTG_FS_IRQHandler
+ .thumb_set OTG_FS_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream5_IRQHandler
+ .thumb_set DMA2_Stream5_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream6_IRQHandler
+ .thumb_set DMA2_Stream6_IRQHandler,Default_Handler
+
+ .weak DMA2_Stream7_IRQHandler
+ .thumb_set DMA2_Stream7_IRQHandler,Default_Handler
+
+ .weak USART6_IRQHandler
+ .thumb_set USART6_IRQHandler,Default_Handler
+
+ .weak I2C3_EV_IRQHandler
+ .thumb_set I2C3_EV_IRQHandler,Default_Handler
+
+ .weak I2C3_ER_IRQHandler
+ .thumb_set I2C3_ER_IRQHandler,Default_Handler
+
+ .weak OTG_HS_EP1_OUT_IRQHandler
+ .thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler
+
+ .weak OTG_HS_EP1_IN_IRQHandler
+ .thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler
+
+ .weak OTG_HS_WKUP_IRQHandler
+ .thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler
+
+ .weak OTG_HS_IRQHandler
+ .thumb_set OTG_HS_IRQHandler,Default_Handler
+
+ .weak HASH_RNG_IRQHandler
+ .thumb_set HASH_RNG_IRQHandler,Default_Handler
+
+ .weak FPU_IRQHandler
+ .thumb_set FPU_IRQHandler,Default_Handler
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
diff --git a/src/config.h b/src/config.h
index 059c0d3..ad035c9 100644
--- a/src/config.h
+++ b/src/config.h
@@ -4,3 +4,19 @@
/* Enable testing mode */
#define TESTING_ENABLE 1
+
+/* Buffer size for routing */
+#define ROUTING_BUFSIZE 128
+
+/**
+ * \def MASTER_I2C_BUS_INTERVAL
+ * \brief General interval value used by master in milliseconds
+ *
+ * Master uses this value to introduce delays on the I2C bus in order to reduce I2C timeout values.
+ * The optimum interval is usually dependent on I2C bus configuration on the hardware. Testing and debug UART
+ * operations will also affect this value.
+ * If unforeseen I2C timeout issues are encountered on master side, this value should be increased to suit the
+ * hardware.
+ *
+*/
+#define MASTER_I2C_BUS_INTERVAL 150
diff --git a/src/data.pb.c b/src/data.pb.c
new file mode 100644
index 0000000..fb1e203
--- /dev/null
+++ b/src/data.pb.c
@@ -0,0 +1,38 @@
+/* Automatically generated nanopb constant definitions */
+/* Generated by nanopb-0.4.2-dev */
+
+#include "data.pb.h"
+#if PB_PROTO_HEADER_VERSION != 40
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+PB_BIND(m2s_SOR, m2s_SOR, AUTO)
+
+
+PB_BIND(s2m_DOC, s2m_DOC, AUTO)
+
+
+PB_BIND(m2s_CTS, m2s_CTS, AUTO)
+
+
+PB_BIND(m2s_command, m2s_command, AUTO)
+
+
+PB_BIND(s2m_command, s2m_command, AUTO)
+
+
+PB_BIND(_datapoint, _datapoint, AUTO)
+
+
+PB_BIND(s2m_data, s2m_data, AUTO)
+
+
+
+#ifndef PB_CONVERT_DOUBLE_FLOAT
+/* On some platforms (such as AVR), double is really float.
+ * To be able to encode/decode double on these platforms, you need.
+ * to define PB_CONVERT_DOUBLE_FLOAT in pb.h or compiler command line.
+ */
+PB_STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES)
+#endif
+
diff --git a/src/data.pb.h b/src/data.pb.h
new file mode 100644
index 0000000..cc271a3
--- /dev/null
+++ b/src/data.pb.h
@@ -0,0 +1,181 @@
+/* Automatically generated nanopb header */
+/* Generated by nanopb-0.4.2-dev */
+
+#ifndef PB_DATA_PB_H_INCLUDED
+#define PB_DATA_PB_H_INCLUDED
+#include <pb.h>
+
+#if PB_PROTO_HEADER_VERSION != 40
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Struct definitions */
+typedef struct _s2m_data {
+ pb_callback_t datapoints;
+} s2m_data;
+
+typedef struct __datapoint {
+ uint32_t entity_id;
+ double data;
+ bool has_channel_id;
+ uint32_t channel_id;
+ bool has_unit_id;
+ uint32_t unit_id;
+ bool has_timestamp;
+ int32_t timestamp;
+} _datapoint;
+
+typedef struct _m2s_CTS {
+ uint32_t timeout;
+} m2s_CTS;
+
+typedef struct _m2s_SOR {
+ uint32_t SOR_code;
+ bool has_rx_length;
+ uint32_t rx_length;
+} m2s_SOR;
+
+typedef struct _m2s_command {
+ bool has_source_module_id;
+ uint32_t source_module_id;
+ bool has_source_i2c_address;
+ uint32_t source_i2c_address;
+ pb_callback_t cmd_bytes;
+ pb_callback_t cmd_str;
+} m2s_command;
+
+typedef struct _s2m_DOC {
+ uint32_t DOC_code;
+ uint32_t tx_length;
+} s2m_DOC;
+
+typedef struct _s2m_command {
+ bool has_dest_module_id;
+ uint32_t dest_module_id;
+ pb_callback_t dest_module_id_multicast;
+ pb_callback_t cmd_bytes;
+ pb_callback_t cmd_str;
+} s2m_command;
+
+
+/* Initializer values for message structs */
+#define m2s_SOR_init_default {1u, false, 0}
+#define s2m_DOC_init_default {1u, 0u}
+#define m2s_CTS_init_default {0}
+#define m2s_command_init_default {false, 1u, false, 1u, {{NULL}, NULL}, {{NULL}, NULL}}
+#define s2m_command_init_default {false, 0, {{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}}
+#define _datapoint_init_default {0u, 0, false, 1u, false, 1u, false, 1}
+#define s2m_data_init_default {{{NULL}, NULL}}
+#define m2s_SOR_init_zero {0, false, 0}
+#define s2m_DOC_init_zero {0, 0}
+#define m2s_CTS_init_zero {0}
+#define m2s_command_init_zero {false, 0, false, 0, {{NULL}, NULL}, {{NULL}, NULL}}
+#define s2m_command_init_zero {false, 0, {{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}}
+#define _datapoint_init_zero {0, 0, false, 0, false, 0, false, 0}
+#define s2m_data_init_zero {{{NULL}, NULL}}
+
+/* Field tags (for use in manual encoding/decoding) */
+#define s2m_data_datapoints_tag 1
+#define _datapoint_entity_id_tag 1
+#define _datapoint_data_tag 2
+#define _datapoint_channel_id_tag 3
+#define _datapoint_unit_id_tag 4
+#define _datapoint_timestamp_tag 5
+#define m2s_CTS_timeout_tag 1
+#define m2s_SOR_SOR_code_tag 1
+#define m2s_SOR_rx_length_tag 2
+#define m2s_command_source_module_id_tag 1
+#define m2s_command_source_i2c_address_tag 2
+#define m2s_command_cmd_bytes_tag 3
+#define m2s_command_cmd_str_tag 4
+#define s2m_DOC_DOC_code_tag 1
+#define s2m_DOC_tx_length_tag 2
+#define s2m_command_dest_module_id_tag 1
+#define s2m_command_dest_module_id_multicast_tag 2
+#define s2m_command_cmd_bytes_tag 3
+#define s2m_command_cmd_str_tag 4
+
+/* Struct field encoding specification for nanopb */
+#define m2s_SOR_FIELDLIST(X, a) \
+X(a, STATIC, REQUIRED, UINT32, SOR_code, 1) \
+X(a, STATIC, OPTIONAL, UINT32, rx_length, 2)
+#define m2s_SOR_CALLBACK NULL
+#define m2s_SOR_DEFAULT (const pb_byte_t*)"\x08\x01\x00"
+
+#define s2m_DOC_FIELDLIST(X, a) \
+X(a, STATIC, REQUIRED, UINT32, DOC_code, 1) \
+X(a, STATIC, REQUIRED, UINT32, tx_length, 2)
+#define s2m_DOC_CALLBACK NULL
+#define s2m_DOC_DEFAULT (const pb_byte_t*)"\x08\x01\x10\x00\x00"
+
+#define m2s_CTS_FIELDLIST(X, a) \
+X(a, STATIC, REQUIRED, UINT32, timeout, 1)
+#define m2s_CTS_CALLBACK NULL
+#define m2s_CTS_DEFAULT NULL
+
+#define m2s_command_FIELDLIST(X, a) \
+X(a, STATIC, OPTIONAL, UINT32, source_module_id, 1) \
+X(a, STATIC, OPTIONAL, UINT32, source_i2c_address, 2) \
+X(a, CALLBACK, OPTIONAL, BYTES, cmd_bytes, 3) \
+X(a, CALLBACK, OPTIONAL, STRING, cmd_str, 4)
+#define m2s_command_CALLBACK pb_default_field_callback
+#define m2s_command_DEFAULT (const pb_byte_t*)"\x08\x01\x10\x01\x00"
+
+#define s2m_command_FIELDLIST(X, a) \
+X(a, STATIC, OPTIONAL, UINT32, dest_module_id, 1) \
+X(a, CALLBACK, REPEATED, UINT32, dest_module_id_multicast, 2) \
+X(a, CALLBACK, OPTIONAL, BYTES, cmd_bytes, 3) \
+X(a, CALLBACK, OPTIONAL, STRING, cmd_str, 4)
+#define s2m_command_CALLBACK pb_default_field_callback
+#define s2m_command_DEFAULT NULL
+
+#define _datapoint_FIELDLIST(X, a) \
+X(a, STATIC, REQUIRED, UINT32, entity_id, 1) \
+X(a, STATIC, REQUIRED, DOUBLE, data, 2) \
+X(a, STATIC, OPTIONAL, UINT32, channel_id, 3) \
+X(a, STATIC, OPTIONAL, UINT32, unit_id, 4) \
+X(a, STATIC, OPTIONAL, INT32, timestamp, 5)
+#define _datapoint_CALLBACK NULL
+#define _datapoint_DEFAULT (const pb_byte_t*)"\x08\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x18\x01\x20\x01\x28\x01\x00"
+
+#define s2m_data_FIELDLIST(X, a) \
+X(a, CALLBACK, REPEATED, MESSAGE, datapoints, 1)
+#define s2m_data_CALLBACK pb_default_field_callback
+#define s2m_data_DEFAULT NULL
+#define s2m_data_datapoints_MSGTYPE _datapoint
+
+extern const pb_msgdesc_t m2s_SOR_msg;
+extern const pb_msgdesc_t s2m_DOC_msg;
+extern const pb_msgdesc_t m2s_CTS_msg;
+extern const pb_msgdesc_t m2s_command_msg;
+extern const pb_msgdesc_t s2m_command_msg;
+extern const pb_msgdesc_t _datapoint_msg;
+extern const pb_msgdesc_t s2m_data_msg;
+
+/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
+#define m2s_SOR_fields &m2s_SOR_msg
+#define s2m_DOC_fields &s2m_DOC_msg
+#define m2s_CTS_fields &m2s_CTS_msg
+#define m2s_command_fields &m2s_command_msg
+#define s2m_command_fields &s2m_command_msg
+#define _datapoint_fields &_datapoint_msg
+#define s2m_data_fields &s2m_data_msg
+
+/* Maximum encoded size of messages (where known) */
+#define m2s_SOR_size 12
+#define s2m_DOC_size 12
+#define m2s_CTS_size 6
+/* m2s_command_size depends on runtime parameters */
+/* s2m_command_size depends on runtime parameters */
+#define _datapoint_size 38
+/* s2m_data_size depends on runtime parameters */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
diff --git a/src/dataflow.h b/src/dataflow.h
new file mode 100644
index 0000000..d39126e
--- /dev/null
+++ b/src/dataflow.h
@@ -0,0 +1,46 @@
+
+/*
+ *
+ * Dataflow Status Enumeration
+ *
+ * This typedef governs the dataflow state machine. Enums should be self explanatory
+ *
+ * TODO Handle other DF pathways for slave RX datapoint and slave RX command
+ *
+ * |------------+-----+----------------------------------------+---------------------+-------------------------|
+ * | Status | Int | Status Invariant | Action | Next Status |
+ * |------------+-----+----------------------------------------+---------------------+-------------------------|
+ * | DF_IDLE | 0 | Ready to send m2s_SOR | Send m2s_SOR | DF_RX_DOC or ??? |
+ * | DF_RX_DOC | 1 | Sent m2s_SOR; ready to receive s2m_DOC | Receive s2m_DOC | DF_CTS |
+ * | DF_CTS | 2 | Received m2s_SOR; ready to send DF_CTS | Send m2s_CTS | DF_RX_DATA or DF_RX_CMD |
+ * | DF_RX_DATA | 3 | Sent m2s_CTS; receive s2m_data | Receive s2m_data | DF_SUCCESS |
+ * | DF_RX_CMD | 4 | sent m2s_CTS receive s2m_command | Receive s2m_command | DF_SUCCESS |
+ * |------------+-----+----------------------------------------+---------------------+-------------------------|
+ *
+ *
+*/
+
+typedef enum dataflow_status {
+ DF_IDLE = 0,
+ DF_RX_DOC = 1,
+ DF_CTS = 2,
+ DF_RX_DATA = 3,
+ DF_RX_CMD = 4,
+ DF_SUCCESS = 5,
+ DF_FAIL = 6,
+ DF_LEN_TX = 7
+} dataflow_status_t;
+
+typedef enum SOR_codes {
+ SLAVE_TX = 1,
+ SLAVE_RX_DATAPOINT = 2,
+ SLAVE_RX_COMMAND = 3
+} SOR_codes_t;
+
+typedef enum DOC_codes {
+ CMD_UNICAST = 1,
+ CMD_MULTICAST = 2,
+ CMD_BROADCAST = 3,
+ RESERVED = 4,
+ DATA = 0x5
+} DOC_codes_t;
diff --git a/src/devices.h b/src/devices.h
index ef4e65b..b2cb825 100644
--- a/src/devices.h
+++ b/src/devices.h
@@ -12,12 +12,13 @@ typedef struct _device_info {
uint32_t subscriptions[4]; /* Subscriptions by this device */
} device_info_t;
+/* TODO These IDs could be represented as a single 8-bit integer */
typedef struct _subscription_info {
uint8_t module_ids[128];
uint8_t entity_ids[128];
uint8_t module_class[3];
uint8_t i2c_address[128];
- uint8_t mod_idx, entity_idx, class_idx, i2c_idx;
+ uint8_t mod_idx, entity_idx, class_idx, i2c_idx;
} subscription_info_t;
typedef enum hs_status {
diff --git a/src/main.c b/src/master.c
index 9a98fd4..c627a45 100644
--- a/src/main.c
+++ b/src/master.c
@@ -1,4 +1,3 @@
-/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
@@ -16,25 +15,28 @@
/* Library includes */
#include <pb_encode.h>
#include <pb_decode.h>
-#include "handshake.pb.h"
/* Project includes */
+#include "main.h"
#include "devices.h"
#include "config.h"
-#include "main.h"
+#include "dataflow.h"
+#include "handshake.pb.h"
+#include "data.pb.h"
/* Private Macros */
#define device_MDR s2m_MDR_response
-#define GET_IDX_FROM_ADDR(i2c_addr) i2c_addr-1
+#define GET_IDX_FROM_ADDR(i2c_addr) (i2c_addr>>1)-1
+#define GET_ADDR_FROM_IDX(idx) (idx+1)<<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
-#define BUS_DEVICE_LIMIT 128
+/* #define I2C_ADDRESS 0x05 */
+#define BUS_DEVICE_LIMIT 16
/* Macro to toggle between master and slave firmware */
-/* #define MASTER */
+#define MASTER
/* Private globals */
I2C_HandleTypeDef hi2c1;
@@ -44,6 +46,13 @@ 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;
+
+_datapoint routing_buffer[ROUTING_BUFSIZE];
+/* Index information for each datapoint */
+uint8_t routing_idx_buffer[ROUTING_BUFSIZE];
+/* Pointer to tail of both data and idx buffers */
+uint32_t routing_ptr = 0;
/* Function prototypes */
void SystemClock_Config(void);
@@ -51,12 +60,16 @@ static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
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, uint32_t SOR_code, uint8_t routing_buf_idx);
+bool routing(void);
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 decode_subscriptions_callback(pb_istream_t *istream, const pb_field_t *field, void **args);
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);
+bool master_encode_MDR_callback(pb_ostream_t *ostream, const pb_field_t *field, void * const *arg);
/**
* @brief The application entry point.
@@ -86,174 +99,37 @@ int main(void)
HAL_UART_Transmit(&huart1, reset_string, sizeof(reset_string), 100);
#endif /* MASTER */
#endif /* TESTING_ENABLE */
-
-#ifdef MASTER
- hs_status_t hs_status;
- for (int curr_addr=0; curr_addr < 10; curr_addr++) {
- if (todo_hs_or_not_todo_hs(curr_addr)) {
- hs_status = handshake(curr_addr);
- dev_sts[GET_IDX_FROM_ADDR(curr_addr)] = get_state_from_hs_status(curr_addr, hs_status);
- }
- }
-
-#else /* Slave code*/
- {
- uint8_t MDR_buf[128], debug_buf[128], term[]="\r\n";
- size_t MDR_enc_size;
- s2m_MDR_response res;
- res.MDR_version=1.1;
- res.module_id = 1;
- res.module_class=1;
- res.entity_id=32;
-
- res.subscriptions.funcs.encode=encode_subscription_callback;
- pb_ostream_t ostream = pb_ostream_from_buffer(MDR_buf, sizeof(MDR_buf));
- if(!pb_encode(&ostream, s2m_MDR_response_fields, &res)){
-#ifdef DEBUG_ENABLE
- uint8_t err_buf[] = "MDR encoding error\r\n";
- HAL_UART_Transmit(&huart1, err_buf, sizeof(err_buf), 100);
-#endif
- while(1) {
- HAL_GPIO_TogglePin(led_GPIO_Port, led_Pin);
- HAL_Delay(500);
- }
- }
- MDR_enc_size = ostream.bytes_written;
-#ifdef TESTING_ENABLE
- sprintf((char*)debug_buf, "MDR Encoded size: %d\r\n", MDR_enc_size);
- HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
- memset(debug_buf, 0, 128);
-
- uint8_t bufbuf[] = "MDR Buffer: ";
- HAL_UART_Transmit(&huart1, bufbuf, sizeof(bufbuf), 100);
- for(int x=0; x<MDR_enc_size; x++) {
- sprintf((char*)debug_buf+x, "%x", MDR_buf[x]);
- }
- HAL_UART_Transmit(&huart1, debug_buf, MDR_enc_size, 100);
- HAL_UART_Transmit(&huart1, term, 2, 100);
- memset(debug_buf, 0, 128);
-#endif
-
- uint8_t MDR_ACK_buf[8] = {0};
- s2m_MDR_req_ACK ack;
- ack.MDR_res_length = MDR_enc_size;
- pb_ostream_t MDR_ack_ostream = pb_ostream_from_buffer(MDR_ACK_buf,
- sizeof(MDR_ACK_buf));
- if(!pb_encode(&MDR_ack_ostream, s2m_MDR_req_ACK_fields, &ack)) {
-#ifdef DEBUG_ENABLE
- uint8_t errbuf[] = "MDR ACK encoding error\r\n";
- HAL_UART_Transmit(&huart1, errbuf, sizeof(errbuf), 100);
-#endif /* DEBUG_ENABLE */
- while(1) {
- HAL_GPIO_TogglePin(led_GPIO_Port, led_Pin);
- HAL_Delay(500);
+
+ uint8_t priority_counter = 0, debug_buf[128];
+ /* Handshake */
+ while (1) {
+ if (priority_counter == 0) {
+ hs_status_t hs_status;
+ /* for (uint8_t curr_addr=5; curr_addr == 5; curr_addr++) { */
+ for (uint8_t curr_addr=0x1; curr_addr <= BUS_DEVICE_LIMIT; curr_addr++) {
+ if (todo_hs_or_not_todo_hs(curr_addr)) {
+ hs_status = handshake(curr_addr);
+ dev_sts[GET_IDX_FROM_ADDR(curr_addr)] = get_state_from_hs_status(curr_addr, hs_status);
+ }
}
}
- size_t MDR_ack_size = MDR_ack_ostream.bytes_written;
-#ifdef TESTING_ENABLE
- sprintf((char*)debug_buf, "MDR ACK Encoded size: %d\r\n", MDR_ack_size);
- HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
- memset(debug_buf, 0, 128);
-#endif /* TESTING_ENABLE */
-
- uint8_t MDR_req_buf[8];
- m2s_MDR_request MDR_req;
-
- if (HAL_I2C_Slave_Receive(&hi2c1, (uint8_t*)MDR_req_buf, 2, 10000) != HAL_OK) {
-#ifdef DEBUG_ENABLE
- uint8_t debug_buf[] = "Failed to get MDR req\r\n";
- HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
-#endif /* DEBUG_ENABLE */
- }
-#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]);
+ else if (priority_counter == 5 && routing_ptr > 0) {
+ routing();
}
- HAL_UART_Transmit(&huart1, debug_buf, MDR_enc_size, 100);
- HAL_UART_Transmit(&huart1, term, 2, 100);
- memset(debug_buf, 0, 128);
-#endif
-
- pb_istream_t MDR_req_istream = pb_istream_from_buffer(MDR_req_buf, 2);
- if(!pb_decode(&MDR_req_istream, m2s_MDR_request_fields, &MDR_req)) {
-#ifdef DEBUG_ENABLE
- uint8_t errbuf[] = "MDR request decoding error\r\n";
- HAL_UART_Transmit(&huart1, errbuf, sizeof(errbuf), 100);
-#endif /* DEBUG_ENABLE */
- }
-
-#ifdef TESTING_ENABLE
- sprintf((char*)debug_buf, "Got requested record type: %ld\r\n", MDR_req.record_type);
- HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
- memset(debug_buf, 0, 128);
-#endif /* TESTING_ENABLE */
-
- HAL_GPIO_TogglePin(led_GPIO_Port, led_Pin);
-
- if (HAL_I2C_Slave_Transmit(&hi2c1, (uint8_t*)MDR_ACK_buf, s2m_MDR_req_ACK_size, 10000) != HAL_OK) {
-#ifdef DEBUG_ENABLE
- sprintf((char*)debug_buf, "Unable to send MDR ACK. 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 */
+ else {
+ for (int device_idx = 0; device_idx < BUS_DEVICE_LIMIT-1; device_idx++) {
+ if (dev_sts[device_idx] == REGISTERED) {
+ device_dataflow(GET_ADDR_FROM_IDX(device_idx), SLAVE_TX, 0);
+ }
+ }
}
+ priority_counter = ((priority_counter+1)%10);
- uint8_t MDR_CTS_buf[8];
- m2s_MDR_res_CTS MDR_CTS;
-
- if (HAL_I2C_Slave_Receive(&hi2c1, (uint8_t*)MDR_CTS_buf, 2, 10000) != HAL_OK) {
-#ifdef DEBUG_ENABLE
- sprintf((char*)debug_buf, "Failed to get MDR CTS\r\n");
- HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
- memset(debug_buf, 0, 128);
-#endif /* DEBUG_ENABLE */
- }
-#ifdef TESTING_ENABLE
- uint8_t ctsbuf[] = "Got CTS 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);
+ sprintf((char*)debug_buf, "routing ptr: %ld\r\n", routing_ptr);
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 */
-
- pb_istream_t MDR_CTS_istream = pb_istream_from_buffer(MDR_CTS_buf, 2);
- if (!pb_decode(&MDR_CTS_istream, m2s_MDR_res_CTS_fields, &MDR_CTS)) {
-#ifdef DEBUG_ENABLE
- sprintf((char*)debug_buf, "Failed to decode MDR CTS\r\n");
- HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
- memset(debug_buf, 0, 128);
-#endif /* DEBUG_ENABLE */
- Error_Handler();
- }
-
- uint32_t MDR_timeout = MDR_CTS.timeout;
- if (HAL_I2C_Slave_Transmit(&hi2c1, (uint8_t*)MDR_buf, MDR_enc_size, 10000) !=
- HAL_OK) {
-#ifdef DEBUG_ENABLE
- sprintf((char*)debug_buf, "Unable to send 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 */
- }
- else {
- sprintf((char*)debug_buf, "Successfully sent MDR\r\n");
- HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
- memset(debug_buf, 0, 128);
- }
- }
-#endif /* MASTER */
-
- while (1)
- {
-
- }
+ }
}
hs_status_t handshake(uint32_t i2c_addr)
@@ -262,68 +138,44 @@ hs_status_t handshake(uint32_t i2c_addr)
/* Handshake variables */
uint8_t hs_sts = IDLE;
- uint8_t *MDR_req_buf, *MDR_ACK_buf, *MDR_CTS_buf, *MDR_buf;
+ uint8_t *MDR_buf;
uint32_t AF_error_counter = 0;
uint32_t dev_idx = GET_IDX_FROM_ADDR(i2c_addr);
- uint32_t MDR_len = 0;
+ uint16_t MDR_len = 0;
- m2s_MDR_request MDR_req_message;
- s2m_MDR_req_ACK MDR_ACK;
- m2s_MDR_res_CTS MDR_CTS;
- s2m_MDR_response MDR_res_message;
+ s2m_MDR_response MDR_res_message = s2m_MDR_response_init_default;
#if defined(TESTING_ENABLE) || defined(DEBUG_ENABLE)
uint8_t debug_buf[128];
#endif
#ifdef TESTING_ENABLE
uint8_t term[] = "\r\n";
- size_t MDR_req_size, MDR_CTS_size;
#endif
while (hs_sts != HS_FAILED && hs_sts != HS_REGISTERED) {
switch (hs_sts) {
case (IDLE):
{
- MDR_req_buf = malloc(8);
- pb_ostream_t MDR_req_stream = pb_ostream_from_buffer(MDR_req_buf, 2);
- MDR_req_message.record_type = 7; /* Placeholder for default record type */
- if(!pb_encode(&MDR_req_stream, m2s_MDR_request_fields, &MDR_req_message)) {
+ uint8_t MDR_req_buf[2] = {0x0, 0x1};
+ if (HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr, MDR_req_buf, 2, 10000) != HAL_OK) {
hs_sts = HS_FAILED;
#ifdef DEBUG_ENABLE
- goto __MDR_REQ_ENC_FAIL;
- __MDR_REQ_ENC_FAIL_END:
+ goto __HS_MDR_REQ_I2C_ERROR;
+ __HS_MDR_REQ_I2C_ERROR_END:
__asm__("nop");
#endif
}
else {
-#ifdef TESTING_ENABLE
- MDR_req_size = MDR_req_stream.bytes_written;
- goto __HS_IDLE_TESTING;
- __HS_IDLE_TESTING_END:
- __asm__("nop");
-#endif
- if (HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr, (uint8_t*)MDR_req_buf,
- MDR_req_buf_len, 10000) != HAL_OK) {
- hs_sts = HS_FAILED;
-#ifdef DEBUG_ENABLE
- goto __HS_MDR_REQ_I2C_ERROR;
- __HS_MDR_REQ_I2C_ERROR_END:
- __asm__("nop");
-#endif
- }
- else {
- hs_sts = HS_MDR_ACK;
- }
- free(MDR_req_buf);
- break;
+ hs_sts = HS_MDR_ACK;
}
+ break;
}
case (HS_MDR_ACK):
{
- MDR_ACK_buf = malloc(8);
+ HAL_Delay(MASTER_I2C_BUS_INTERVAL);
+ uint8_t MDR_ACK_buf[2] = {0x0, 0x0};
AF_error_counter = 0;
- while (HAL_I2C_Master_Receive(&hi2c1, (uint16_t)i2c_addr, (uint8_t*)MDR_ACK_buf,
- s2m_MDR_req_ACK_size, 100) != HAL_OK) {
+ while (HAL_I2C_Master_Receive(&hi2c1, (uint16_t)i2c_addr, MDR_ACK_buf, 2, 100) != HAL_OK) {
if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF) {
hs_sts = HS_FAILED;
}
@@ -340,62 +192,32 @@ hs_status_t handshake(uint32_t i2c_addr)
}
}
if (hs_sts != HS_FAILED) {
- pb_istream_t MDR_ACK_istream = pb_istream_from_buffer(MDR_ACK_buf, 2);
- if (!pb_decode(&MDR_ACK_istream, s2m_MDR_req_ACK_fields, &MDR_ACK)) {
- hs_sts = HS_FAILED;
-#ifdef DEBUG_ENABLE
- goto __MDR_ACK_DEC_ERROR;
- __MDR_ACK_DEC_ERROR_END:
- __asm__("nop");
-#endif
+ uint8_t ACK_flag = MDR_ACK_buf[1];
+ if (ACK_flag == 0xFF) {
+ MDR_len = MDR_ACK_buf[0];
+ hs_sts = HS_MDR_CTS;
}
else {
- MDR_len = MDR_ACK.MDR_res_length;
- hs_sts = HS_MDR_CTS;
-#ifdef TESTING_ENABLE
- goto __HS_MDR_ACK_TESTING;
- __HS_MDR_ACK_TESTING_END:
- __asm__("nop");
-#endif
+ hs_sts = HS_FAILED;
}
- free(MDR_ACK_buf);
}
break;
}
case (HS_MDR_CTS):
{
- MDR_CTS_buf = (uint8_t*)malloc(8);
- 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)) {
+ uint8_t MDR_CTS_buf[2] = {0x0, 0x02};
+ if (HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr, MDR_CTS_buf, 2, 10000) != HAL_OK) {
hs_sts = HS_FAILED;
#ifdef DEBUG_ENABLE
- goto __MDR_CTS_ENC_ERROR;
- __MDR_CTS_ENC_ERROR_END:
+ goto __HS_CTS_I2C_ERROR;
+ __HS_CTS_I2C_ERROR_END:
__asm__("nop");
#endif
}
else {
-#ifdef TESTING_ENABLE
- MDR_CTS_size = MDR_CTS_ostream.bytes_written;
- goto __HS_MDR_CTS_TESTING;
- __HS_MDR_CTS_TESTING_END:
- __asm__("nop");
-#endif
- if (HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr,
- (uint8_t*)MDR_CTS_buf, 2, 10000) != HAL_OK) {
- hs_sts = HS_FAILED;
-#ifdef DEBUG_ENABLE
- goto __HS_CTS_I2C_ERROR;
- __HS_CTS_I2C_ERROR_END:
- __asm__("nop");
-#endif
- }
- else {
- hs_sts = HS_MDR_MDR;
- free(MDR_CTS_buf);
- }
+ hs_sts = HS_MDR_MDR;
}
+
break;
}
case (HS_MDR_MDR):
@@ -428,6 +250,7 @@ hs_status_t handshake(uint32_t i2c_addr)
MDR_res_message.subscriptions.arg = (void*)dev_idx;
pb_istream_t MDR_res_stream = pb_istream_from_buffer(MDR_buf, MDR_len);
if (!pb_decode(&MDR_res_stream, s2m_MDR_response_fields, &MDR_res_message)) {
+ hs_sts = HS_FAILED;
#ifdef DEBUG_ENABLE
goto __HS_MDR_DEC_ERROR;
__HS_MDR_DEC_ERROR_END:
@@ -440,49 +263,22 @@ hs_status_t handshake(uint32_t i2c_addr)
__MDR_DEC_TESTING_END:
__asm__("nop");
#endif
+ device_info[dev_idx] = malloc(sizeof(device_info_t));
+ device_info[dev_idx]->i2c_addr = i2c_addr;
+ device_info[dev_idx]->device_id = dev_idx;
+ device_info[dev_idx]->MDR = MDR_res_message;
+
hs_sts = HS_REGISTERED;
}
}
break;
}
}
-
}
#ifdef TESTING_ENABLE
{
goto __TESTING_BLOCK_END;
- __HS_IDLE_TESTING:
- sprintf((char*)debug_buf, "MDR req length: %d\r\n", MDR_req_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<MDR_req_size; x++) {
- sprintf((char*)debug_buf+x, "%x", MDR_req_buf[x]);
- }
- HAL_UART_Transmit(&huart1, debug_buf, MDR_req_size, 100);
- HAL_UART_Transmit(&huart1, term, 2, 100);
- memset(debug_buf, 0, 128);
- goto __HS_IDLE_TESTING_END;
- __HS_MDR_ACK_TESTING:
- 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);
- goto __HS_MDR_ACK_TESTING_END;
- __HS_MDR_CTS_TESTING:
- sprintf((char*)debug_buf, "CTS size: %d\r\n", MDR_CTS_size);
- 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);
- goto __HS_MDR_CTS_TESTING_END;
__HS_MDR_MDR_TESTING:
for (int x=0; x<MDR_len; x++) {
sprintf((char*)debug_buf+x, "%x", MDR_buf[x]);
@@ -507,13 +303,8 @@ __TESTING_BLOCK_END:
#ifdef DEBUG_ENABLE
{
goto __DEBUG_BLOCK_END;
- __MDR_REQ_ENC_FAIL:
- sprintf((char*)debug_buf, "MDR reqest encoding error\r\n");
- HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
- memset(debug_buf, 0, 128);
- goto __MDR_REQ_ENC_FAIL_END;
__HS_MDR_REQ_I2C_ERROR:
- sprintf((char*)debug_buf, "Unable to send MDR request. I2C error: %ld\r\n", HAL_I2C_GetError(&hi2c1));
+ sprintf((char*)debug_buf, "Unable to send MDR request to %lx. I2C error: %ld\r\n", i2c_addr, HAL_I2C_GetError(&hi2c1));
HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
memset(debug_buf, 0, 128);
goto __HS_MDR_REQ_I2C_ERROR_END;
@@ -522,16 +313,6 @@ __TESTING_BLOCK_END:
HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
memset(debug_buf, 0, 128);
goto __HS_MDR_ACK_I2C_ERROR_END;
- __MDR_ACK_DEC_ERROR:
- sprintf((char*)debug_buf, "MDR ACK decoding error\r\n");
- HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
- memset(debug_buf, 0, 128);
- goto __MDR_ACK_DEC_ERROR_END;
- __MDR_CTS_ENC_ERROR:
- sprintf((char*)debug_buf, "MDR encoding error\r\n");
- HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
- memset(debug_buf, 0, 128);
- goto __MDR_CTS_ENC_ERROR_END;
__HS_CTS_I2C_ERROR:
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);
@@ -541,20 +322,371 @@ __TESTING_BLOCK_END:
sprintf((char*)debug_buf, "Unable to get MDR. I2C error: %ld\n\tError counter: %ld\r\n", HAL_I2C_GetError(&hi2c1), AF_error_counter);
HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
memset(debug_buf, 0, 128);
- goto __HS_MDR_I2C_ERROR_END;
+ goto __HS_MDR_I2C_ERROR_END;
+ __HS_MDR_DEC_ERROR:
+ sprintf((char*)debug_buf, "MDR decode error\r\n");
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+ goto __HS_MDR_DEC_ERROR_END;
+ __DEBUG_BLOCK_END:
+ __asm__("nop");
}
-__HS_MDR_DEC_ERROR:
- sprintf((char*)debug_buf, "MDR decode error\r\n");
- HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
- memset(debug_buf, 0, 128);
- goto __HS_MDR_DEC_ERROR_END;
-__DEBUG_BLOCK_END:
- __asm__("nop");
#endif
return hs_sts;
}
+dataflow_status_t device_dataflow(uint8_t i2c_addr, uint32_t SOR_code, uint8_t rbuf_data_idx)
+{
+ uint8_t dev_idx = GET_IDX_FROM_ADDR(i2c_addr);
+ dataflow_status_t df_status = DF_IDLE;
+
+ uint8_t DOC_buf[4];
+ uint8_t *data_buf;
+ uint32_t AF_error_counter = 0;
+ uint32_t data_len = 0;
+ _datapoint datapoints[16];
+
+ /* TODO Add default values to the CTS message in proto */
+ 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):
+ {
+ HAL_Delay(MASTER_I2C_BUS_INTERVAL);
+ uint8_t SOR_buf[2] = {SOR_code, 0x0};
+ if (HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr, SOR_buf, 2, 500) != 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 */
+ df_status = DF_LEN_TX;
+ }
+ else if (SOR_code == SLAVE_RX_COMMAND) {
+ /* TODO */
+ }
+ }
+ break;
+ }
+
+
+ case (DF_RX_DOC):
+ {
+ HAL_Delay(MASTER_I2C_BUS_INTERVAL);
+ AF_error_counter = 0;
+ while (HAL_I2C_Master_Receive(&hi2c1, (uint16_t)i2c_addr,
+ (uint8_t*)DOC_buf, 4, 10000) != 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 > 1500) {
+ df_status = DF_FAIL;
+ break;
+ }
+ }
+ if (df_status != DF_FAIL) {
+ if (DOC_buf[1] == DATA) {
+ df_status = DF_CTS;
+ data_len = DOC_buf[3];
+ }
+ else if (DOC_buf[1] == CMD_UNICAST) {
+ /* TODO */
+ }
+ else if (DOC_buf[1] == CMD_MULTICAST) {
+ /* TODO */
+ }
+ else if (DOC_buf[1] == CMD_BROADCAST) {
+ /* TODO */
+ }
+ else {
+ df_status = DF_FAIL;
+ }
+ }
+ break;
+ }
+ case (DF_CTS):
+ {
+ HAL_Delay(MASTER_I2C_BUS_INTERVAL);
+ uint8_t CTS_buf[2] = {0x2, 0xFF};
+ if (HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr, 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_buf[1] == DATA) {
+ df_status = DF_RX_DATA;
+ }
+ else {
+ /* TODO RX CMD stuff */
+ }
+ }
+ break;
+ }
+ case (DF_RX_DATA):
+ {
+ HAL_Delay(MASTER_I2C_BUS_INTERVAL);
+ sprintf((char*)debug_buf, "data len: %ld\r\n", data_len);
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+
+ 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, 1000) != 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 {
+ /* This could be done in the callback itself */
+ for (int i = 0; i < data_idx && routing_ptr < ROUTING_BUFSIZE; i++) {
+ routing_idx_buffer[routing_ptr] = dev_idx;
+ routing_buffer[routing_ptr++] = datapoints[i];
+ }
+ df_status = DF_SUCCESS;
+ }
+ }
+ break;
+ }
+ case (DF_LEN_TX):
+ {
+ HAL_Delay(MASTER_I2C_BUS_INTERVAL);
+ /* TODO error checking */
+ /* Will need to package datapoint and MDR to know their lengths
+ Once cached, will not need to do this */
+
+ /* Do this after handshake to cache ================================================== */
+ uint8_t MDR_buf[128], data_buf[128], CTS_buf[2];
+ uint8_t src_device_idx = routing_idx_buffer[rbuf_data_idx];
+ s2m_MDR_response data_src_MDR = device_info[src_device_idx]->MDR;
+ pb_ostream_t MDR_ostream = pb_ostream_from_buffer(MDR_buf, sizeof(MDR_buf));
+ data_src_MDR.subscriptions.funcs.encode=master_encode_MDR_callback;
+ pb_encode(&MDR_ostream, s2m_MDR_response_fields, &data_src_MDR);
+ uint8_t MDR_len = MDR_ostream.bytes_written;
+ /* =================================================================================== */
+
+ _datapoint data = routing_buffer[rbuf_data_idx];
+ pb_ostream_t data_ostream = pb_ostream_from_buffer(data_buf, sizeof(data_buf));
+ pb_encode(&data_ostream, _datapoint_fields, &data);
+ uint8_t data_len = data_ostream.bytes_written;
+
+ uint8_t data_MDR_len_buf[4] = {0, MDR_len, 0, data_len};
+
+ AF_error_counter = 0;
+ while (HAL_I2C_Master_Receive(&hi2c1, (uint16_t)i2c_addr, CTS_buf, 2, 10000) != HAL_OK) {
+ if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF) {
+ df_status = DF_FAIL;
+ }
+ if (++AF_error_counter > 3000) {
+ df_status = DF_FAIL;
+ }
+ if (df_status == DF_FAIL) {
+ sprintf((char*)debug_buf, "Failed to get LEN CTS\r\n");
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+ break;
+ }
+ }
+
+ HAL_Delay(MASTER_I2C_BUS_INTERVAL);
+ if (df_status != DF_FAIL &&
+ HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr, data_MDR_len_buf, 4, 10000) == HAL_OK) {
+ sprintf((char*)debug_buf, "MDR len: %d data len: %d SENT\r\n", MDR_len, data_len);
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+ }
+ else {
+ sprintf((char*)debug_buf, "Failed to send lengths\r\n");
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+ }
+ AF_error_counter = 0;
+ while (df_status != DF_FAIL &&
+ HAL_I2C_Master_Receive(&hi2c1, (uint16_t)i2c_addr, CTS_buf, 2, 10000) != HAL_OK) {
+ if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF) {
+ df_status = DF_FAIL;
+ }
+ if (++AF_error_counter > 3000) {
+ df_status = DF_FAIL;
+ }
+ if (df_status == DF_FAIL) {
+ sprintf((char*)debug_buf, "Failed to get TX CTS\r\n");
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+ break;
+ }
+ }
+
+
+#ifdef TESTING_ENABLE
+ uint8_t buf_title[64];
+ sprintf((char*)buf_title, "MDR buffer: ");
+ HAL_UART_Transmit(&huart1, buf_title, sizeof(buf_title), 100);
+ memset(buf_title, 0, 64);
+ for(int x=0; x<MDR_len; x++)
+ sprintf((char*)debug_buf+x, "%x", MDR_buf[x]);
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ HAL_UART_Transmit(&huart1, term, 2, 100);
+ memset(debug_buf, 0, 128);
+
+ sprintf((char*)buf_title, "Data buffer: ");
+ HAL_UART_Transmit(&huart1, buf_title, sizeof(buf_title), 100);
+ memset(buf_title, 0, 64);
+ for(int x=0; x<data_len; x++)
+ sprintf((char*)debug_buf+x, "%x", data_buf[x]);
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ HAL_UART_Transmit(&huart1, term, 2, 100);
+ memset(debug_buf, 0, 128);
+#endif
+
+ if (df_status != DF_FAIL &&
+ HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr, MDR_buf, MDR_len, 10000) == HAL_OK &&
+ HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)i2c_addr, data_buf, data_len, 10000) == HAL_OK) {
+ sprintf((char*)debug_buf, "Data and MDR SENT\r\n");
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+
+ df_status = DF_SUCCESS;
+ }
+ break;
+ }
+ case DF_SUCCESS:
+ case DF_FAIL:
+ 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_I2C_ERROR:
+ sprintf((char*)debug_buf, "Unable to send SOR request to %d. I2C error: %ld\r\n",
+ i2c_addr, 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_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 routing(void)
+{
+ /* This table holds information on where to send each datapoint in the routing buffer */
+ uint32_t routing_table[ROUTING_BUFSIZE][4] = {{0, 0}};
+
+ /* Build table with routing information */
+ for (uint8_t rbuf_data_idx = 0; rbuf_data_idx < routing_ptr; rbuf_data_idx++) {
+ uint8_t src_module_idx = routing_idx_buffer[rbuf_data_idx];
+ for (uint8_t dev_idx = 0; dev_idx < BUS_DEVICE_LIMIT; dev_idx++) {
+ if (!(GET_BIT_FROM_IDX(allocated, dev_idx)&&1)) { // No module at this index
+ continue;
+ }
+ bool alloc = false;
+ for (uint8_t dev_sub_idx = 0; dev_sub_idx < subs_info[dev_idx]->mod_idx && !alloc; dev_sub_idx++) {
+ if (subs_info[dev_idx]->module_ids[dev_sub_idx] == device_info[src_module_idx]->MDR.module_id) {
+ SET_BIT_FROM_IDX(routing_table[rbuf_data_idx], dev_idx);
+ alloc = true;
+ }
+ }
+ /* TODO entity ID, I2C addr and class routing, should go in the if condition above */
+ }
+ }
+
+ for (uint8_t rbuf_data_idx = 0; rbuf_data_idx < routing_ptr; rbuf_data_idx++) {
+ for (uint8_t device_idx = 0; device_idx < BUS_DEVICE_LIMIT; device_idx++) {
+ if (GET_BIT_FROM_IDX(allocated, device_idx) &&
+ GET_BIT_FROM_IDX(routing_table[rbuf_data_idx], device_idx)) {
+ device_dataflow(GET_ADDR_FROM_IDX(device_idx), SLAVE_RX_DATAPOINT, rbuf_data_idx);
+ }
+ }
+ }
+
+ /* Reset the routing pointer, since all data in buffer should have been routed */
+ routing_ptr = 0;
+ return true;
+}
+
bool decode_subscriptions_callback(pb_istream_t *istream, const pb_field_t *field, void **args)
{
_subscriptions subs;
@@ -569,7 +701,7 @@ bool decode_subscriptions_callback(pb_istream_t *istream, const pb_field_t *fiel
}
if(!pb_decode(istream, _subscriptions_fields, &subs))
- return false;
+ return false;
/* Parse all fields if they're included */
if (subs.has_module_id)
@@ -596,7 +728,7 @@ bool todo_hs_or_not_todo_hs(uint8_t i2c_addr)
case NO_HS:
case CONNECTED:
case FAILED:
- case OFFLINE:
+ case OFFLINE:
do_hs = true;
break;
case REGISTERED:
@@ -627,6 +759,14 @@ state_t get_state_from_hs_status(uint16_t device_addr, hs_status_t hs_status)
return device_state;
}
+bool master_encode_MDR_callback(pb_ostream_t *ostream, const pb_field_t *field, void * const *arg)
+{
+ if (!pb_encode_tag_for_field(ostream, field)) {
+ return false;
+ }
+ return true;
+}
+
bool encode_subscription_callback(pb_ostream_t *ostream, const pb_field_t *field, void * const *arg)
{
if(ostream!=NULL && field->tag == s2m_MDR_response_subscriptions_tag) {
@@ -654,6 +794,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
@@ -702,12 +890,12 @@ static void MX_I2C1_Init(void)
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
- hi2c1.Init.OwnAddress1 = I2C_ADDRESS;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0xFF;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
+ /* hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_ENABLE; */
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
diff --git a/src/slave.c b/src/slave.c
new file mode 100644
index 0000000..4722c51
--- /dev/null
+++ b/src/slave.c
@@ -0,0 +1,463 @@
+/**
+******************************************************************************
+* @file : main.c
+* @brief : Main program body
+******************************************************************************
+* @attention
+*
+*
+******************************************************************************
+*/
+
+/* Standard library includes */
+#include <stdio.h>
+
+/* Library includes */
+#include <pb_encode.h>
+#include <pb_decode.h>
+
+/* Project includes */
+#include "main.h"
+#include "devices.h"
+#include "config.h"
+#include "dataflow.h"
+#include "handshake.pb.h"
+#include "data.pb.h"
+
+/* Private Macros */
+#define device_MDR s2m_MDR_response
+#define GET_IDX_FROM_ADDR(i2c_addr) i2c_addr-1
+#define GET_ADDR_FROM_IDX(idx) idx+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 0x07<<1
+#define BUS_DEVICE_LIMIT 128
+
+/* Macro to toggle between master and slave firmware */
+
+/* Private globals */
+I2C_HandleTypeDef hi2c1;
+UART_HandleTypeDef huart1;
+
+/* 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);
+
+bool decode_subscriptions_callback(pb_istream_t *istream, const pb_field_t *field, void **args);
+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);
+bool handshake(void);
+/**
+ * @brief The application entry point.
+ * @retval int
+ */
+int main(void)
+{
+ /* MCU Configuration */
+
+ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
+ HAL_Init();
+
+ /* Configure the system clock */
+ SystemClock_Config();
+
+ /* Initialize all configured peripherals */
+ MX_GPIO_Init();
+ MX_I2C1_Init();
+ MX_USART1_UART_Init();
+
+ uint8_t reset_string[] = "\r\n\n==========SLAVE RESET=========\r\n\n";
+ HAL_UART_Transmit(&huart1, reset_string, sizeof(reset_string), 100);
+
+
+ while (handshake() == false);
+ uint8_t SOR_buf[2] = {0}, debug_buf[128];
+ HAL_Delay(1000);
+ while (1) {
+
+ if (HAL_I2C_Slave_Receive(&hi2c1, (uint8_t*)SOR_buf, 2, 500) != 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);
+ continue;
+ }
+ else {
+ sprintf((char*)debug_buf, "Got SOR\r\n");
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+ }
+
+ if (SOR_buf[0] == 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);
+ continue;
+ }
+ data_enc_size = data_ostream.bytes_written;
+ uint8_t doc_buf[4] = {0x0, 0x5, 0x0, data_enc_size};
+ 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);
+ continue;
+ }
+ 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[2] = {0x0, 0x0};
+ 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);
+ continue;
+ }
+ else {
+ sprintf((char*)debug_buf, "Got CTS: %d\r\n", CTS_buf[0]);
+ 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);
+ continue;
+ }
+ else {
+ sprintf((char*)debug_buf, "SENT DATA\r\n");
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+ }
+ }
+ else if (SOR_buf[0] == 2) {
+ uint8_t CTS_buf[] = {0x0, 0x1};
+ uint8_t len_buf[4], *MDR_buf, *data_buf;
+ /* _datapoint datapoints[16]; */
+
+ HAL_I2C_Slave_Transmit(&hi2c1, CTS_buf, 2, 10000);
+ sprintf((char*)debug_buf, "Sent CTS\r\n");
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+
+ HAL_I2C_Slave_Receive(&hi2c1, len_buf, 4, 1000);
+
+ uint16_t MDR_len = len_buf[1]+(len_buf[0]<<8);
+ MDR_buf = malloc(MDR_len);
+ uint16_t data_len = len_buf[3]+(len_buf[2]<<8);
+ data_buf = malloc(data_len);
+
+ sprintf((char*)debug_buf, "Got lengths. MDR: %d, data: %d\r\n", MDR_len, data_len);
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+
+ HAL_I2C_Slave_Transmit(&hi2c1, CTS_buf, 2, 10000);
+ HAL_I2C_Slave_Receive(&hi2c1, MDR_buf, MDR_len, 10000);
+ HAL_I2C_Slave_Receive(&hi2c1, data_buf, data_len, 10000);
+
+ _datapoint datapoint_message;
+ s2m_MDR_response MDR_message;
+ pb_istream_t MDR_istream = pb_istream_from_buffer(MDR_buf, MDR_len);
+ pb_istream_t data_istream = pb_istream_from_buffer(data_buf, data_len);
+
+ pb_decode(&MDR_istream, s2m_MDR_response_fields, &MDR_message);
+ pb_decode(&data_istream, _datapoint_fields, &datapoint_message);
+
+ sprintf((char*)debug_buf, "Got data from %ld, running version %f\r\n\tdata 0: %f\r\n", MDR_message.module_id, MDR_message.MDR_version, datapoint_message.data);
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+ }
+ }
+}
+
+
+bool handshake(void)
+{
+ uint8_t MDR_buf[128], debug_buf[128], term[]="\r\n";
+ size_t MDR_enc_size;
+ s2m_MDR_response res;
+ res.MDR_version = 0.1;
+ res.module_id = 4;
+ res.module_class = 2;
+ res.entity_id=1;
+
+ res.subscriptions.funcs.encode=encode_subscription_callback;
+ pb_ostream_t ostream = pb_ostream_from_buffer(MDR_buf, sizeof(MDR_buf));
+ if(!pb_encode(&ostream, s2m_MDR_response_fields, &res)) {
+#ifdef DEBUG_ENABLE
+ uint8_t err_buf[] = "MDR encoding error\r\n";
+ HAL_UART_Transmit(&huart1, err_buf, sizeof(err_buf), 100);
+#endif
+ return false;
+ }
+ MDR_enc_size = ostream.bytes_written;
+
+#ifdef TESTING_ENABLE
+ sprintf((char*)debug_buf, "MDR Encoded size: %d\r\n", MDR_enc_size);
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+
+ uint8_t bufbuf[] = "MDR Buffer: ";
+ HAL_UART_Transmit(&huart1, bufbuf, sizeof(bufbuf), 100);
+ for(int x=0; x<MDR_enc_size; x++) {
+ sprintf((char*)debug_buf+x, "%x", MDR_buf[x]);
+ }
+ HAL_UART_Transmit(&huart1, debug_buf, MDR_enc_size, 100);
+ HAL_UART_Transmit(&huart1, term, 2, 100);
+ memset(debug_buf, 0, 128);
+#endif
+
+ uint8_t MDR_ACK_buf[2] = {MDR_enc_size, 0xFF};
+ uint8_t MDR_req_buf[2] = {0x0, 0x0};
+
+ if (HAL_I2C_Slave_Receive(&hi2c1, (uint8_t*)MDR_req_buf, 2, 10000) != HAL_OK) {
+#ifdef DEBUG_ENABLE
+ uint8_t debug_buf[] = "Failed to get MDR req\r\n";
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+#endif
+ return false;
+ }
+
+#ifdef TESTING_ENABLE
+ sprintf((char*)debug_buf, "Got requested record type: %d\r\n", MDR_req_buf[1]);
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+#endif
+
+ if (HAL_I2C_Slave_Transmit(&hi2c1, (uint8_t*)MDR_ACK_buf, 2, 10000) != HAL_OK) {
+#ifdef DEBUG_ENABLE
+ sprintf((char*)debug_buf, "Unable to send MDR ACK. 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
+ return false;
+ }
+
+ uint8_t MDR_CTS_buf[2] = {0x0, 0x0};
+
+ if (HAL_I2C_Slave_Receive(&hi2c1, (uint8_t*)MDR_CTS_buf, 2, 10000) != HAL_OK) {
+#ifdef DEBUG_ENABLE
+ sprintf((char*)debug_buf, "Failed to get MDR CTS\r\n");
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+#endif
+ return false;
+ }
+
+ if (HAL_I2C_Slave_Transmit(&hi2c1, (uint8_t*)MDR_buf, MDR_enc_size, 10000) != HAL_OK) {
+#ifdef DEBUG_ENABLE
+ sprintf((char*)debug_buf, "Unable to send 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
+ return false;
+ }
+#ifdef DEBUG_ENABLE
+ sprintf((char*)debug_buf, "Successfully sent MDR\r\n");
+ HAL_UART_Transmit(&huart1, debug_buf, sizeof(debug_buf), 100);
+ memset(debug_buf, 0, 128);
+#endif
+
+ /* TODO Final ACK from master */
+ return true;
+}
+
+
+bool encode_subscription_callback(pb_ostream_t *ostream, const pb_field_t *field, void * const *arg)
+{
+ if(ostream!=NULL && field->tag == s2m_MDR_response_subscriptions_tag) {
+ for (int x=0; x<5; x++) {
+ _subscriptions subs;
+ subs.module_id = x+1;
+ subs.has_module_id=true;
+ subs.has_entity_id=false;
+ subs.has_module_class=false;
+ subs.has_i2c_address=false;
+ if(!pb_encode_tag_for_field(ostream, field)) {
+ return false;
+ }
+ if(!pb_encode_submessage(ostream, _subscriptions_fields, &subs)) {
+ return false;
+ }
+ }
+ }
+ else{
+ return false;
+ }
+ 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;
+}
+
+/**
+ * @brief System Clock Configuration
+ * @retval None
+ */
+void SystemClock_Config(void)
+{
+ RCC_OscInitTypeDef RCC_OscInitStruct = {0};
+ RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
+
+ /** Configure the main internal regulator output voltage
+ */
+ __HAL_RCC_PWR_CLK_ENABLE();
+ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
+ /** Initializes the CPU, AHB and APB busses clocks
+ */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
+ RCC_OscInitStruct.HSIState = RCC_HSI_ON;
+ RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ /** Initializes the CPU, AHB and APB busses clocks
+ */
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
+ |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
+ RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
+ RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+
+ if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
+ {
+ Error_Handler();
+ }
+}
+
+/**
+ * @brief I2C1 Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_I2C1_Init(void)
+{
+ hi2c1.Instance = I2C1;
+ hi2c1.Init.ClockSpeed = 100000;
+ hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
+ hi2c1.Init.OwnAddress1 = I2C_ADDRESS;
+ hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
+ hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
+ hi2c1.Init.OwnAddress2 = 0xFF;
+ hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
+ hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
+ /* hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_ENABLE; */
+ if (HAL_I2C_Init(&hi2c1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+}
+
+/**
+ * @brief USART1 Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_USART1_UART_Init(void)
+{
+ huart1.Instance = USART1;
+ huart1.Init.BaudRate = 9600;
+ huart1.Init.WordLength = UART_WORDLENGTH_8B;
+ huart1.Init.StopBits = UART_STOPBITS_1;
+ huart1.Init.Parity = UART_PARITY_NONE;
+ huart1.Init.Mode = UART_MODE_TX_RX;
+ huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+ huart1.Init.OverSampling = UART_OVERSAMPLING_16;
+ if (HAL_UART_Init(&huart1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+}
+
+/**
+ * @brief GPIO Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_GPIO_Init(void)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+ /* GPIO Ports Clock Enable */
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOH_CLK_ENABLE();
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+
+ /*Configure GPIO pin Output Level */
+ HAL_GPIO_WritePin(led_GPIO_Port, led_Pin, GPIO_PIN_RESET);
+
+ /*Configure GPIO pin : led_Pin */
+ GPIO_InitStruct.Pin = led_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ HAL_GPIO_Init(led_GPIO_Port, &GPIO_InitStruct);
+
+}
+
+/**
+ * @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 */