Ver código fonte

Merge branch 'uart_rx_idle' into 'main'

modify to use HAL_UARTEx_ReceiveToIdle_DMA

See merge request sensorical/fw/nbus!2
Juraj Ďuďák 1 ano atrás
pai
commit
a8872cc8bd
3 arquivos alterados com 152 adições e 67 exclusões
  1. 1 2
      Inc/nbus_app.h
  2. 83 10
      Inc/nbus_types.h
  3. 68 55
      Src/nbus_app.c

+ 1 - 2
Inc/nbus_app.h

@@ -25,11 +25,10 @@ extern "C"
 
 void nbus_init(nBusAppInterface_t *interface, nBusPlatformInterface_t *hw);
 void nbus_init_app(void *hw_interface, void *hw_config);
-void nbus_set_app_callback(void (*cb)());
 void nbus_stack(void);
 void nbus_init_memory_driver(nBus_MemoryDriver *memDriver, uint16_t capacity);
 
-void nbus_cb_UART_RX(void);
+void nbus_cb_UART_RX(int);
 void nbus_cb_TIM_periodElapsed(void);
 
 #ifdef __cplusplus

+ 83 - 10
Inc/nbus_types.h

@@ -28,8 +28,6 @@
  */
 #define BUFF_SIZE (PAYLOAD_SIZE + META_SIZE)
 
-#define CMD_FLAG_GET	1
-#define CMD_FLAG_SET	0
 /**
 * @brief Symbolické konštanty pre príznak pripravenosti dát
 */
@@ -43,11 +41,21 @@ typedef enum {
 } DataReadyTypedef;
 
 
-
+/**
+ * @brief Definuje význam bytu FC v požiadavke. Bajt FC má index 2 v RX bufferi.
+ * bit 7: príznak chyby
+ * bit 6: rezervovaný
+ * bit 5: ~r/w príznak pr zápis údajov
+ * bt 4-0: kód funkcie.
+ */
 typedef struct __attribute__((packed)) {
+	/** Kód funkcie. Bit 0..4 */
 	uint8_t function : 5;
+	/** Príznak pre zápis údajov. Bit 5 */
 	uint8_t notReadWrite : 1;
+	/** Rezervoané. Bit 6 */
     uint8_t reserve : 1;
+    /** Príznak chyby. Bit 7 */
     uint8_t error : 1;
 } nBus_functionCode_t;
 
@@ -55,16 +63,30 @@ typedef struct __attribute__((packed)) {
 #define REQUEST_GET	0
 #define REQUEST_SET 1
 
+/**
+ * @brief Definuje význam bytu ADR v požiadavke. Bajt ADR má index 0 v RX bufferi.
+ * Baj obsahuje adresu koncového senzora (bit 0..4) a typ senzora (bit 5-7)
+ */
 typedef struct __attribute__((packed)) {
+	/** Adresa pripojeného senzora. Povolené adresy 1..31. Pozícia v ADR byte: 0..4*/
 	uint8_t address : 5;
+	/** Definuje typ senora: vstup/výstup.
+	 * bit 7: 0-výstupné zariadenia, 1-vstupné zariadenia
+	 */
 	uint8_t type : 3;
 } nBus_sensorByte_t;
 
 
+/**
+ * @brief Stavy komunikačného rozhrania počas behu programu.
+ */
 typedef enum {
-	UART_RX_1B,
-	UART_RX_PAYLOAD,
-	UART_RECEIVED
+	/** Čaká sa na príjem dát. Nasledujúci stav: UART_RX_RECEIVING */
+	UART_RX_WAIT,
+	/** Dáta sa prijímajú. Nasledujúci stav: UART_RX_RECEIVED */
+	UART_RX_RECEIVING,
+	/** Dáta sú prijané, v ďašom cykle sa budú spracovať. Nasledujúci stav: UART_RX_WAIT*/
+	UART_RX_RECEIVED
 } nBus_Uart_RX_state;
 
 
@@ -80,12 +102,24 @@ typedef enum {
     * Funckia, resp. príkaz určený konkrétny koncový senzor.
     */
     UNICAST_TO_MODULE,
+	/**
+  	 * Funckia, resp. príkaz určený špecifické senzory.
+ 	 */
 	BROADCAST_SPECIFIC_SENSORS,
+	/**
+  	 * Funckia, resp. príkaz určený pre všetky moduly.
+ 	 */
 	BROADCAST_GLOBAL
 } nBusCommandType_t;
 
+
+/**
+ * @brief Určuje typ odpovede na požiadavku.
+ */
 typedef enum {
+	/** Na požiadavku sa nebude odpovedať. Zvyčajte pri BROADCAST požiadavke. */
 	NO_RESPONSE,
+	/** Na požiadavku sa bude odpovedať. Zvyčajte pri UNICAST požiadavke. */
 	SEND_RESPONSE
 
 }nBus_response_t;
@@ -97,16 +131,55 @@ typedef enum {
 } nBusMeasurementActive_t;
 
 
+/**
+ * @brief Dátová štruktúra pre implementáciu základných funkcií na aplikačnej úrovni.
+ * Komunikačný zásobník nBus je HW nezávislá implementácia komunikačného protokolu. Pre zabezpečenie
+ * elementárnych akcií je potrebné tieto akcie implementovať na konkrétnej hardvérovej platforme.
+ * Jedná sa o:
+ * - uart_receive: naštartovanie procesu prijímania dát s uvedením max dĺžky
+ * - uart_transmit: odoslaneie odpovede
+ * - led_on/led_off/led_toggle: ovládani dignalizačnej LED diódy
+ * - delay_ms: blokujúca pauza
+ * - loop_callback: interný callback pre signalizáciu externých udalostí z aplikácie.
+ */
 typedef struct{
+	/**
+	 * @brief Spustenie príjmu dát na vstunom komunikačnom rozhraní (UART, ..).
+	 * 1 parameter: pointer na pole, kde sa uložia načítané dáta.
+	 * 2 parameter: maximálna dĺžka načítaných dát.
+	 * @note Načíranie dát musí byť asynchrónne. Celé načítanie musí manažovať aplikácia.
+	 * Po úspešnom načítaní musí aplikácia zavolať funkciu nbus_cb_UART_RX(dataI); @see nbus_cb_UART_RX
+	 */
 	void (*uart_receive)(uint8_t *, int);
-	void (*uart_transmit)(uint8_t *, int );
-	void (*uart_abort_receive)();
+	/**
+	 * @brief Odoslanie odpovede cez komunikačné rozhranie.
+	 * 1 parameter: dáta na odoslanie
+	 * 2 parameter: počet abjtov na odoslanie
+	 */
+	void (*uart_transmit)(uint8_t *, int);
+	/**
+	 * @brief Zapnutie signalizácie
+	 */
 	void (*led_on)(void);
+	/**
+	 * @brief Vypnutie signalizácie
+	 */
 	void (*led_off)(void);
+	/**
+	 * @brief Zmena stavu signalizácie
+	 */
 	void (*led_toggle)(void);
-	void (*timer_uart_start)(int);
-	void (*timer_uart_stop)(void);
+	/**
+	 * @brief Blokujúca pauza [ms].
+	 */
 	void (*delay_ms)(uint8_t);
+	/**
+	 * Callback protokolu nBus pre signalizáciu udalostí. Tento callback sa v protokole nBus spúšťa každú iteráciu v hlavnej slučke.
+	 * Stav aplikácie uruje návratová hodnota tohto callbacku:
+	 * 0 - žiadna udalosť nenastala
+	 * 1 - signál pre pripravenosť dát z pripojených senzorov. Hodnota 1 spôsobí prečítanie dát z pripojeného sensora (nBus.interface->read())
+	 * 2 - signál oznamujúci ukončenie načítania vstupných dát cez komunikačné rozhranie. Je to signál pre ukočenie načítania, ktoré bolo sputené cez uart_receive
+	 */
 	uint8_t (*loop_callback)(void);
 
 }nBusPlatformInterface_t;

+ 68 - 55
Src/nbus_app.c

@@ -1,4 +1,5 @@
 #include "nbus_app.h"
+#include <string.h>
 
 nBus_TypeDef nBus;
 
@@ -38,17 +39,8 @@ static uint8_t crc8x_fast(void const *mem, uint16_t len) {
 }
 
 
-inline static void receiveOneByte(){
-	nBus.hw_platform->uart_abort_receive();
-	nBus.hw_platform->uart_receive(nBus.rx_buffer, 1);
-	nBus.uart_state = UART_RX_1B;
-	nBus.rx_length = 1;
-}
-
-inline static void receiveNBytes(uint8_t n){
-	nBus.rx_length = n;
-	nBus.hw_platform->uart_receive(nBus.rx_buffer, nBus.rx_length);
-	nBus.uart_state = UART_RX_PAYLOAD;
+inline static void receivePacket(void){
+	nBus.hw_platform->uart_receive(nBus.rx_buffer, 64);
 }
 
 inline static void send_response(){
@@ -156,40 +148,7 @@ static void process_request(){
 
 }
 
-/* -------------------------------------------------------- */
-/* ----------------------- CALLBACKS----------------------- */
-/* -------------------------------------------------------- */
-
-void nbus_cb_UART_RX(void){
-	if(nBus.uart_state == UART_RX_PAYLOAD) {
-		nBus.uart_state = UART_RECEIVED;
-		nBus.hw_platform->timer_uart_stop();
-	}
-
-	if(nBus.uart_state == UART_RX_1B) {
-		nBus.hw_platform->led_on();
-		if(nBus.rx_buffer[0] > 0) {
-			receiveNBytes(nBus.rx_buffer[0]);
-			nBus.hw_platform->timer_uart_stop();
-			nBus.hw_platform->timer_uart_start(nBus.rx_buffer[0]);
-		} else {
-			receiveOneByte();
-		}
-	}
-
-}
-
-
-void nbus_cb_TIM_periodElapsed(void) {
-	if(nBus.uart_state == UART_RX_PAYLOAD) {
-		nBus.hw_platform->led_off();
-		nBus.hw_platform->timer_uart_stop();
-		nBus.hw_platform->uart_abort_receive();
-		receiveOneByte();
-	}
-}
-
-void nbus_blink_LED(uint8_t delay) {
+static void nbus_blink_LED(uint8_t delay) {
 	nBus.hw_platform->led_on();
 	nBus.hw_platform->delay_ms(delay);
 	nBus.hw_platform->led_off();
@@ -200,10 +159,34 @@ void nbus_blink_LED(uint8_t delay) {
 	nBus.hw_platform->delay_ms(delay);
 }
 
+/* -------------------------------------------------------- */
+/* ----------------------- CALLBACKS----------------------- */
+/* -------------------------------------------------------- */
+
+/**
+ * @brief UART receive complete.
+ * This callback have to valled from application, when RX data is ready.
+ * @param int size Size of received packet
+ * Received packet is located in uBus.rx_buffer
+ */
+void nbus_cb_UART_RX(int size){
+	nBus.rx_length = size;
+	nBus.uart_state = UART_RX_RECEIVED;
+}
+
+
 /* -------------------------------------------------------- */
 /* ------------------ PUBLIC FUNCTIONS-------------------- */
 /* -------------------------------------------------------- */
 
+/**
+ * @brief Initialize of nBus stack
+ * @param interface Driver for module application.
+ * 		Every application have to implement base functions as Init, Reset, GetData, SetData, GetParam, SetParam, .... @see nBusAppInterface_t
+ * 		These are application dependent functions.
+ * @param hw Application level implementation of base functions (uart_receive, uart_transmit, led_on/off/toggle, ...).
+ * 		These are MCU dependent functions.
+ */
 void nbus_init(nBusAppInterface_t *interface, nBusPlatformInterface_t *hw){
   nBus.hw_platform = hw;
 
@@ -211,37 +194,62 @@ void nbus_init(nBusAppInterface_t *interface, nBusPlatformInterface_t *hw){
   nBus.data_timebase = 0;
   nBus.measure_active = MEASURE_STOPPED;
 
-  // init restart timer
-  nBus.uart_state = UART_RX_1B;
-  nBus.hw_platform->timer_uart_start(100);	 // dummy value
-  nBus.hw_platform->timer_uart_stop();
+  nBus.uart_state = UART_RX_WAIT;
 
   nBus.interface = interface;
-  receiveOneByte();
+
+  receivePacket();
 
 }
 
+/**
+ * @brief Initialize concrete application, if it is needed.
+ * This function call "init()" function from nBusPlatformInterface_t, and this function is implemented in concrete application.
+ * @param hw_interface Pointer to hardware definition structure. In STM32 it can be hSPI, hUART, hADC, ...
+ * @param hw_config configuration for hardware structure object.
+ */
 void nbus_init_app(void *hw_interface, void *hw_config){
 	nBus.interface->init(hw_interface, hw_config);
 }
 
+/**
+ * @brief Init memory driver for storing module/sensor parameters.
+ * Implementation of memory driver is independent from nBus. To provide nonvolatile parameters store, is nneded implement this driver.
+ * @param memDriver Memory driver for bas operation: read/write 1/2/4 byte from/to memory
+ * @param capacity TBD
+ * @todo imeplement capacity parameter
+ */
 void nbus_init_memory_driver(nBus_MemoryDriver *memDriver, uint16_t capacity){
 	nbus_memory_init(memDriver);
 	nBus.memoryInterface = getnbusMemoryInterface();
 	nbus_blink_LED(100);
 }
 
+/**
+ * @brief Run protocol stack.
+ * This is infinity protocol loop.
+ * When stack is started (or reset) it blink as boot sign.
+ *
+ * Content of loop:
+ * - if data was received: process request. Determine addressee and type of request
+ * - execute request or discard request
+ * - send response (only for unicast requests)
+ *
+ * In each iteration, the state of application flags are performed. The state of application is noticed from loop_callback() (if it is defined).
+ * Meaning of return values:
+ * - 0 - No event occurs,
+ * - 1 - data from connected sensors are prepared, it will be read with read() function automatically.
+ * - 2 - communication error/timeout. The reception of packed process will be reset.
+ */
 void nbus_stack(void){
 
 	nbus_blink_LED(50);
 
 	while(1){
-		if(nBus.uart_state == UART_RECEIVED){
+		if(nBus.uart_state == UART_RX_RECEIVED){
 
 			process_request();
-
-			// ready for next receiving
-			receiveOneByte();
+			nBus.uart_state = UART_RX_WAIT;
 
 			send_response();
 #if MODULE_MASTER == 1
@@ -250,8 +258,13 @@ void nbus_stack(void){
 		}
 
 		if (nBus.hw_platform->loop_callback != NULL) {
-			if (nBus.hw_platform->loop_callback() == 1){
+			switch (nBus.hw_platform->loop_callback()){
+			case 1:
 				nBus.interface->read();
+				break;
+			case 2:
+				nBus.uart_state = UART_RX_WAIT;
+				break;
 			}
 		}
 	}