Kaynağa Gözat

first attempt, bone only

Juraj Ďuďák 2 yıl önce
ebeveyn
işleme
14e23bb38b
8 değiştirilmiş dosya ile 759 ekleme ve 0 silme
  1. 46 0
      Inc/mcu_platform.h
  2. 23 0
      Inc/nbus_app.h
  3. 33 0
      Inc/nbus_cmd.h
  4. 121 0
      Inc/nbus_config.h.default
  5. 17 0
      Inc/nbus_impl.h
  6. 294 0
      Inc/nbus_types.h
  7. 188 0
      Src/nbus_app.c
  8. 37 0
      Src/nbus_impl.c

+ 46 - 0
Inc/mcu_platform.h

@@ -0,0 +1,46 @@
+/**
+  * @file           mcu_platform.h
+  * @author			Juraj Dudak
+  * @brief			závislosti na knižnicich HAL pre špeficifkú platgormu
+*/
+
+#ifndef __MCU_PLATFORM_H__
+#define __MCU_PLATFORM_H__
+
+#if defined(STM32F100xB) || defined(STM32F100xE) || defined(STM32F101x6) || defined(STM32F101xB)                       \
+    || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F102x6) || defined(STM32F102xB)                    \
+    || defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)
+#include "stm32f1xx.h"
+#define STM32F1
+#endif
+
+#if defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || defined(STM32F038xx)                       \
+    || defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F051x8) || defined(STM32F058xx)                    \
+    || defined(STM32F070x6) || defined(STM32F070xB) || defined(STM32F071xB) || defined(STM32F072xB)                    \
+    || defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC)
+#include "stm32f0xx.h"
+#define STM32F0
+#endif // defined
+
+
+#if defined(STM32L011xx) || defined(STM32L021xx) || defined(STM32L031xx) || defined(STM32L041xx)                       \
+    || defined(STM32L051xx) || defined(STM32L052xx) || defined(STM32L053xx) || defined(STM32L061xx)                    \
+    || defined(STM32L062xx) || defined(STM32L063xx) || defined(STM32L071xx) || defined(STM32L072xx)                    \
+    || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx)
+#include "stm32l0xx.h"
+#define STM32L0
+#endif // defined
+
+#if defined(STM32F301x8) || defined(STM32F302x8) || defined(STM32F318xx) || defined(STM32F302xC)                       \
+    || defined(STM32F303xC) || defined(STM32F358xx) || defined(STM32F303x8) || defined(STM32F334x8)                    \
+    || defined(STM32F328xx) || defined(STM32F302xE) || defined(STM32F303xE) || defined(STM32F398xx)                    \
+    || defined(STM32F373xC) || defined(STM32F378xx)
+#include "stm32f3xx.h"
+#define STM32F3
+#endif // defined
+#if defined(STM32L432xx)
+#include "stm32l4xx.h"
+#include "stm32l4xx_hal.h"
+#endif
+
+#endif

+ 23 - 0
Inc/nbus_app.h

@@ -0,0 +1,23 @@
+/**
+ * @file  nbus_app.h
+ *
+ * @brief Zakladna kostra nBus protokolu.
+ *
+ */
+#ifndef __NBUS_APP_H__
+#define __NBUS_APP_H__
+
+#include "nbus_types.h"
+#include "nbus_impl.h"
+#include "nbus_cmd.h"
+
+void nbus_init(Peripheral_typeDef *periph);
+void nbus_cb_UART_RX(UART_HandleTypeDef *huart);
+void nbus_cb_TIM_periodElapsed(TIM_HandleTypeDef *htim);
+void receiveOneByte();
+void process_request();
+
+void nbus_stack(void);
+
+#endif
+

+ 33 - 0
Inc/nbus_cmd.h

@@ -0,0 +1,33 @@
+/**
+  ******************************************************************************
+  * @file    nbus_cmd.h
+  * @author  Juraj Dudak
+  * @version v.1
+  * @date    27-October-2023
+  * @brief   Deklaracie kodov funckií protokolu nBUS.
+  ******************************************************************************
+  * @attention
+  *
+  *
+  ******************************************************************************
+  */
+
+#ifndef NBUS_CMD_H
+#define NBUS_CMD_H
+
+
+#define CMD_VERSION		0x00
+#define CMD_ECHO 		0x01
+#define CMD_STOP		0x02
+#define CMD_START		0x03
+#define CMD_PARAM		0x04
+#define CMD_SENSOR_CNT  0x05
+#define CMD_SLEEP		0x06
+#define CMD_WAKEUP		0x07
+#define CMD_CALIBRATE	0x09
+#define CMD_RESET		0x0A
+#define CMD_STORE		0x0B
+#define CMD_DATA		0x0C
+#define CMD_SYNC		0x0D
+
+#endif

+ 121 - 0
Inc/nbus_config.h.default

@@ -0,0 +1,121 @@
+/**
+ * @file  ubus_config.h
+ *
+ * @brief Konfigurácia protokolu uBUS
+ * @author Juraj Dudak
+ * @date 20.12.2022
+ */
+
+/** @addtogroup Firmware
+  * @{
+  */
+
+/** @addtogroup Implementácia_uBUS
+  *
+  * @{
+  */
+
+/** @addtogroup Konfigurácia
+  * @brief Konfigurácia komunikačného zásobníka uBUS, súbor ubus_config.h
+  *
+  * @{
+  *
+  * ## Základné nastavenia
+  *
+  * Základné naastavenie konfigurácie je potrebné urobiť pri konfiguráciu použitého MCU. Pri konfigurácii MCU je potrebné nastaviť:
+  *
+  * - želanú frekvenciu jadra.
+  * - aktivovať komunikažné rozhranie USART
+  *   - povoliť prerušenie na USART
+  *   - v prípade aktivácie nastavenia USE_USART_DMA_TX, pridať DMA kanál pre smer TX
+  * - aktivovať základný časovať TIM (TIM6 alebo TIM7)
+  *   - povoliť prerušenie na použitom časovači.
+  * - GPIO pin procesora, ktorý bude použitý pre svetelnú signalizáciu
+  */
+
+#ifndef __UBUS_CONFIG_H__
+#define __UBUS_CONFIG_H__
+
+/** @brief Základná komunikačná rýchlosť modulu. */
+#define UART_BAUDRATE 19200
+
+/** @brief Parita pre komunikačné rozhanie.
+ *
+ * Povolené hodnoty:  UART_PARITY_EVEN, UART_PARITY_ODD, UART_PARITY_NONE. Default: UART_PARITY_EVEN
+ */
+#define UBUS_UART_PARITY UART_PARITY_EVEN
+
+/**
+* @brief Rodina dosky, resp. typové označenie meracieho modulu.
+*
+* Maximálna povolená dĺžka sú 4 znaky.
+*/
+#define FW_FAMILY "TEST"
+
+/**
+* @brief Globalne povoluje resp zakazuje použitie možnosti šifrovania komunikácie.
+*
+* Vypnutie RSA šifrovania ušetrí cca 2kB.
+*/
+#define ENABLE_RSA 1
+
+/**
+* @brief Globalne povoluje resp zakazuje vypoctu pomocou tabulky CRC.
+*
+* Vypnutím direktívy sa zmnčí pamäťová náročnosť FLASH (asi o 600 B) ale spomalí sa výpočet CRC prijímaného a odosielaného paketu.
+*/
+#define USE_FAST_CRC 1
+
+/**
+* @brief Určuje, či sa použije hardvérové riadenie zbernice RS485.
+*/
+#define USE_SW_485 1
+
+/**
+* @brief Spôsob odoslania odpovede (blokujúci/DMA).
+*
+* 0 - blokujuci spôsob, 1- neblokujúci spôsob pomocou DMA. Využitie neblokujúcej komunikácie má význam
+* len pri BULK dátovom prenose, kedy ako odpoveď na požiadavku o prebos väčšieho množstva dát (4kB) sa odošle viecero rámcov za sebou.
+*/
+#define USE_USART_DMA_TX 0
+
+/**
+* @brief UART Timeout - pri jeho vypsani sa doska restartuje.
+*
+* Podmienka restaru, bude ze do doby vyprsania timeoutu nebude ziadna komunikacia na rozhrani UART.
+* hodnota = minuty + offset 35s
+*/
+#define UART_WATCHDOG 30 * 60 * 1000 + 35000
+
+/**
+* @brief Podpora pre formát Qm.n pre namerané dáta.
+*
+* Touto direktívou sa zapne práca s typom float.
+*/
+#define QFORMAT_SUPPORT_ENABLE 1
+
+/**
+ * @brief Umožní monitorovanie prevádzkovýách napätí meracieho modulu.
+ *
+ * Ak je monitorovaine aktivované, vyžaduje sa aby v konfigurácii modulu uBUS bolo aktivované rozhranie ADC.
+ */
+#define SELF_MONITORING 0
+
+/** @brief Aktivuje sub-slave 14 (0xE) - driver 1-wire. Implementácia je v súbore ubus_dev_E.c */
+//#define UBUS_CHANNEL_E
+/** @brief Aktivuje sub-slave 15 - pamäť konfigurácie (0xF). Implementácia je v súbore ubus_dev_F.c */
+#define UBUS_CHANNEL_F
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#endif

+ 17 - 0
Inc/nbus_impl.h

@@ -0,0 +1,17 @@
+/**
+ * @file  nbus_impl.h
+ *
+ * @brief Zakladna implementacia prikazov nBus protokolu.
+ *
+ */
+#ifndef __NBUS_IMPL_H__
+#define __NBUS_IMPL_H__
+
+#include "nbus_types.h"
+#include "nbus_cmd.h"
+
+//nBusCommandType_t get_request_type();
+nBus_functionCode_t* nbus_unicastToModule(nBus_TypeDef *nBus, nBus_functionCode_t *code);
+void nbus_broadcast(nBus_TypeDef *nBus, nBusCommandType_t request_type);
+#endif
+

+ 294 - 0
Inc/nbus_types.h

@@ -0,0 +1,294 @@
+/**
+ * @file  nbus_types.h
+ *
+ * @brief Definícia dátových štruktúr v protokolu nBUS
+ * @author Juraj Dudak
+ */
+
+#ifndef __NBUS_TYPES_H
+#define __NBUS_TYPES_H
+
+#include <stdint.h>
+#include "mcu_platform.h"
+#include "nbus_config.h"
+
+/**
+* @brief Počet bajtov v pakete, ktoré tvoria réžiu.
+*/
+#define META_SIZE 5
+
+/**
+ * @brief Maximálna veľkosť dátovej časti v pakete.
+ */
+#define PAYLOAD_SIZE 128
+
+/**
+ * @brief Maximálna veľkosť komunikačného bufferu.
+ */
+#define BUFF_SIZE (PAYLOAD_SIZE + META_SIZE)
+
+
+/**
+* @brief Symbolické konštanty pre príznak pripravenosti dát
+*/
+typedef enum {
+    /** Dáta nie sú pripravené. */
+    DATA_EMPTY,
+    /** Dáta sú pripravené. */
+    DATA_READY,
+    /** Dáta sú chybné. */
+    DATA_ERROR,
+} DataReadyTypedef;
+
+/**
+ * @brief Definícia GPIO pinu na platforma STM32.
+ */
+typedef struct {
+    /** GPIO port */
+    GPIO_TypeDef* port;
+    /** číslo pinu na zvolenom porte */
+    uint16_t pin;
+} McuPin_typeDef;
+
+
+/**
+ * @brief Definícia periférií pre protokol uBUS.
+ */
+typedef struct {
+    /** @brief Handler pre rozhranie UART */
+    UART_HandleTypeDef* huart;
+
+    /**
+    * @brief Časovač pre detekciu timeoutu na UART.
+    */
+    TIM_HandleTypeDef* uart_timer;
+
+    // doplnkove periferie
+
+#if SELF_MONITORING == 1
+    // in case of error in this place, set the macro SELF_MONITORING to 0
+    /**
+     * @brief ADC periféria pre monitorovanie vnúterného stavu modulu.
+     *
+     * Táto vlastnosť je aktívna len v prípade ak má makro SELF_MONITORING hodnotu 1
+     */
+    ADC_HandleTypeDef* adc;
+#else
+    void* adc;
+#endif
+
+    /**
+     * @brief Definícia pinu pre signalizačnú LED diódu
+     */
+    McuPin_typeDef* led;
+
+#if USE_SW_485 == 1
+    /**
+     * @brief Definícia pinu riadenie smeru komunikácie RS485.
+     *
+     * Táto vlastnosť je aktívna len v prípade ak má makro USE_SW_485 hodnotu 1
+     */
+    McuPin_typeDef* rs485De;
+#else
+    void* rs485De;
+#endif
+
+} Peripheral_typeDef;
+
+
+
+typedef struct __attribute__((packed)) {
+	uint8_t function : 5;
+	uint8_t notReadWrite : 1;
+    uint8_t reserve : 1;
+    uint8_t error : 1;
+} nBus_functionCode_t;
+
+
+#define REQUEST_GET	0
+#define REQUEST_SET 1
+
+typedef struct __attribute__((packed)) {
+	uint8_t address : 5;
+	uint8_t type : 3;
+} nBus_sensorByte_t;
+
+
+
+typedef enum {
+	UART_RX_1B,
+	UART_RX_PAYLOAD,
+	UART_RECEIVED
+} nBus_Uart_RX_state;
+
+
+/**
+* @brief Určuje typ nBUS príkazu.
+*/
+typedef enum {
+    /**
+    * Funckia, resp. príkaz určený konkrétny koncový senzor.
+    */
+    UNICAST_TO_SENSOR,
+    /**
+    * Funckia, resp. príkaz určený konkrétny koncový senzor.
+    */
+    UNICAST_TO_MODULE,
+	BROADCAST_SPECIFIC_SENSORS,
+	BROADCAST_GLOBAL
+} nBusCommandType_t;
+
+typedef enum {
+	NO_RESPONSE,
+	SEND_RESPONSE
+
+}nBus_response_t;
+
+
+/**
+* @brief Základná štruktúra protokolu nBUS.
+*
+* Obsahuje stavové a funkčné premenné zabezpečujúce správnu implementáciu komunikácie.
+*/
+typedef struct {
+    /**
+    * @brief Prijímací buffer nBUS.
+    */
+    uint8_t rx_buffer[BUFF_SIZE]; // buffer prijatych znakov
+
+    /** @brief  pomocny RX buffer  */
+    uint8_t tmp_buffer[1];
+
+    /**
+    * @brief Index pre prijímací buffer nBUS.
+    */
+    volatile uint16_t rx_buffer_index; // buffer prijatych znakov
+
+    /**
+    * @brief Odosielací buffer uBUS.
+    */
+    uint8_t tx_buffer[BUFF_SIZE]; // buffer odosielanych znakov
+
+    /**
+    * @brief Dĺžka prijatej správy
+    */
+    uint8_t volatile rx_length; // usart flag - obsahuje pocet prijatych byte
+
+    /**
+    * @brief Dĺžka odosielanej správy
+    */
+    uint16_t volatile tx_length; // usart flag - obsahuje pocet vysielanych byte
+
+    /**
+    * @brief Prvy bajt adresy zariadenia slave
+    */
+    volatile uint8_t addressModule;
+
+    /**
+    * @brief Druhy bajt adresy zariadenia slave
+    */
+    volatile nBus_sensorByte_t sensorInfo;
+
+    nBus_functionCode_t function_code;
+    volatile nBusCommandType_t request_type;
+
+
+    /** @brief Flag pre signalizaciu ukoncenia primu dat cez UART. */
+    volatile nBus_Uart_RX_state uart_state;
+
+    nBus_response_t send_response;
+
+    /** @brief CRC8 sucet pre datovy ramec */
+    volatile uint8_t CRC8;
+
+    /**
+     * @brief Periférie protokolu uBUS.
+     */
+    Peripheral_typeDef* periph;
+
+#if USE_USART_DMA_TX == 1
+    /**
+     * @brief Príznak ukončenia odoslania dát cez DMA
+     *
+     * Vlastnosť existuje, len ak má makro USE_USART_DMA_TX hodnotu 1
+     */
+    volatile uint8_t flag_UartTxCplt_DMA;
+#endif
+
+} nBus_TypeDef;
+
+
+
+/**
+* @brief Určuje typ uBUS príkazu pre koncove slave zariadenie.
+*/
+typedef enum {
+    /**
+    * všeobecný príkaz, dáta sú uložené v konfigurácii (FLASH)
+    */
+    COMMAND_SLAVE_GENERAL,
+    /**
+    * špecifický príkaz (state, reset, set/get value/param). Pracuje sa s koncovým senzorom. Obsluja poziadavky je v module pre daný senzor.
+    */
+    COMMAND_SLAVE_SPECIFIC,
+} UnicastSlaveCommandType;
+
+/**
+* @brief Určuje stav komunikačnej vrstvy
+*/
+typedef enum {
+    /**
+    * Dáta sú prijaté a pripravené na spracovanie.
+    */
+    UART_DATA_READY,
+    /**
+    * Nie je prijatý žiadny príkaz na spracovanie.
+    */
+    UART_DATA_EMPTY,
+} UART_DataState;
+
+/**
+* @brief Určuje stav senzora
+*/
+typedef enum {
+    /**
+    * Zariadenie je pripojene a pripravene
+    */
+    DEVICE_READY,
+    /**
+    * Zariadenie sa nedetekovalo
+    */
+    DEVICE_ERROR,
+} DeviceReady_TypeDef;
+
+
+
+
+
+/**
+* @TODO prerobit na nBUS
+* @brief Pripraví chybovú odpoveď prorokolu nBus.
+*
+* Vo funkcii sa nastaví aj správna dĺžka odpovede.
+* @param error_code chybový kód odpovede
+*/
+#define error_response(error_code)                                                                                     \
+    {                                                                                                                  \
+        uBus.sb_length = META_SIZE + 1;                                                                                \
+        uBus.send_buff[2] = uBus.send_buff[2] | FLAG_ERROR;                                                            \
+        uBus.send_buff[3] = error_code;                                                                                \
+    }
+
+#endif
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */

+ 188 - 0
Src/nbus_app.c

@@ -0,0 +1,188 @@
+#include "nbus_app.h"
+
+nBus_TypeDef nBus;
+
+
+static uint8_t const crc8x_table[] = {
+    0x00, 0x31, 0x62, 0x53, 0xc4, 0xf5, 0xa6, 0x97, 0xb9, 0x88, 0xdb, 0xea, 0x7d,
+    0x4c, 0x1f, 0x2e, 0x43, 0x72, 0x21, 0x10, 0x87, 0xb6, 0xe5, 0xd4, 0xfa, 0xcb,
+    0x98, 0xa9, 0x3e, 0x0f, 0x5c, 0x6d, 0x86, 0xb7, 0xe4, 0xd5, 0x42, 0x73, 0x20,
+    0x11, 0x3f, 0x0e, 0x5d, 0x6c, 0xfb, 0xca, 0x99, 0xa8, 0xc5, 0xf4, 0xa7, 0x96,
+    0x01, 0x30, 0x63, 0x52, 0x7c, 0x4d, 0x1e, 0x2f, 0xb8, 0x89, 0xda, 0xeb, 0x3d,
+    0x0c, 0x5f, 0x6e, 0xf9, 0xc8, 0x9b, 0xaa, 0x84, 0xb5, 0xe6, 0xd7, 0x40, 0x71,
+    0x22, 0x13, 0x7e, 0x4f, 0x1c, 0x2d, 0xba, 0x8b, 0xd8, 0xe9, 0xc7, 0xf6, 0xa5,
+    0x94, 0x03, 0x32, 0x61, 0x50, 0xbb, 0x8a, 0xd9, 0xe8, 0x7f, 0x4e, 0x1d, 0x2c,
+    0x02, 0x33, 0x60, 0x51, 0xc6, 0xf7, 0xa4, 0x95, 0xf8, 0xc9, 0x9a, 0xab, 0x3c,
+    0x0d, 0x5e, 0x6f, 0x41, 0x70, 0x23, 0x12, 0x85, 0xb4, 0xe7, 0xd6, 0x7a, 0x4b,
+    0x18, 0x29, 0xbe, 0x8f, 0xdc, 0xed, 0xc3, 0xf2, 0xa1, 0x90, 0x07, 0x36, 0x65,
+    0x54, 0x39, 0x08, 0x5b, 0x6a, 0xfd, 0xcc, 0x9f, 0xae, 0x80, 0xb1, 0xe2, 0xd3,
+    0x44, 0x75, 0x26, 0x17, 0xfc, 0xcd, 0x9e, 0xaf, 0x38, 0x09, 0x5a, 0x6b, 0x45,
+    0x74, 0x27, 0x16, 0x81, 0xb0, 0xe3, 0xd2, 0xbf, 0x8e, 0xdd, 0xec, 0x7b, 0x4a,
+    0x19, 0x28, 0x06, 0x37, 0x64, 0x55, 0xc2, 0xf3, 0xa0, 0x91, 0x47, 0x76, 0x25,
+    0x14, 0x83, 0xb2, 0xe1, 0xd0, 0xfe, 0xcf, 0x9c, 0xad, 0x3a, 0x0b, 0x58, 0x69,
+    0x04, 0x35, 0x66, 0x57, 0xc0, 0xf1, 0xa2, 0x93, 0xbd, 0x8c, 0xdf, 0xee, 0x79,
+    0x48, 0x1b, 0x2a, 0xc1, 0xf0, 0xa3, 0x92, 0x05, 0x34, 0x67, 0x56, 0x78, 0x49,
+    0x1a, 0x2b, 0xbc, 0x8d, 0xde, 0xef, 0x82, 0xb3, 0xe0, 0xd1, 0x46, 0x77, 0x24,
+    0x15, 0x3b, 0x0a, 0x59, 0x68, 0xff, 0xce, 0x9d, 0xac};
+
+
+uint8_t crc8x_fast(uint8_t crc, void const *mem, uint16_t len) {
+	uint8_t const *data = mem;
+    if (data == NULL)
+        return 0xff;
+    crc &= 0xff;
+    while (len--)
+        crc = crc8x_table[crc ^ *data++];
+    return crc;
+}
+
+void nbus_init(Peripheral_typeDef *periph){
+  nBus.periph = periph;
+
+  HAL_TIM_RegisterCallback(nBus.periph->uart_timer, HAL_TIM_PERIOD_ELAPSED_CB_ID, nbus_cb_TIM_periodElapsed);
+  HAL_UART_RegisterCallback(nBus.periph->huart, HAL_UART_RX_COMPLETE_CB_ID, nbus_cb_UART_RX);
+
+  nBus.rx_length = 0;
+
+  // init restart timer
+  nBus.uart_state = UART_RX_1B;
+  HAL_TIM_Base_Start_IT(periph->uart_timer);
+  HAL_TIM_Base_Stop_IT(periph->uart_timer);
+
+}
+
+inline void receiveOneByte(){
+	HAL_UART_Receive_IT(nBus.periph->huart, nBus.rx_buffer, 1);
+	nBus.uart_state = UART_RX_1B;
+}
+
+inline static void receiveNBytes(uint8_t n){
+	nBus.rx_length = n;
+	HAL_UART_Receive_IT(nBus.periph->huart, nBus.rx_buffer, nBus.rx_length);
+	nBus.uart_state = UART_RX_PAYLOAD;
+}
+
+inline static void send_response(){
+	if(nBus.send_response == SEND_RESPONSE) {
+		nBus.tx_buffer[0] -= 1;
+		HAL_UART_Transmit_DMA(nBus.periph->huart, nBus.tx_buffer, nBus.tx_length);
+	}
+}
+
+void nbus_cb_UART_RX(UART_HandleTypeDef *huart){
+	if(nBus.uart_state == UART_RX_PAYLOAD) {
+		nBus.uart_state = UART_RECEIVED;
+		HAL_GPIO_WritePin(nBus.periph->led->port, nBus.periph->led->pin, GPIO_PIN_RESET);
+		HAL_TIM_Base_Stop_IT(nBus.periph->uart_timer);
+	}
+
+	if(nBus.uart_state == UART_RX_1B) {
+		HAL_GPIO_WritePin(nBus.periph->led->port, nBus.periph->led->pin, GPIO_PIN_SET);
+		receiveNBytes(nBus.rx_buffer[0]);
+
+		HAL_TIM_Base_Stop_IT(nBus.periph->uart_timer);
+		nBus.periph->uart_timer->Instance->CNT = 1;
+		HAL_TIM_Base_Start_IT(nBus.periph->uart_timer);
+	}
+
+}
+
+void nbus_cb_TIM_periodElapsed(TIM_HandleTypeDef *htim) {
+	if(nBus.uart_state == UART_RX_PAYLOAD) {
+		HAL_TIM_Base_Stop_IT(nBus.periph->uart_timer);
+		HAL_UART_AbortReceive_IT(nBus.periph->huart);
+		receiveOneByte();
+	}
+}
+
+static nBusCommandType_t get_request_type(){
+
+	nBus.addressModule = nBus.rx_buffer[0];
+	nBus.sensorInfo = *(const nBus_sensorByte_t*)&nBus.rx_buffer[1];
+	nBus.function_code = *(const nBus_functionCode_t*)&nBus.rx_buffer[2];
+
+	if(nBus.sensorInfo.address != 0 && nBus.addressModule !=0 ){
+		nBus.request_type = UNICAST_TO_SENSOR;
+		return UNICAST_TO_SENSOR;
+	}
+
+	if(nBus.sensorInfo.address == 0 && nBus.addressModule !=0 ){
+		nBus.request_type = UNICAST_TO_MODULE;
+		return UNICAST_TO_MODULE;
+	}
+
+	if(nBus.sensorInfo.address != 0 && nBus.addressModule == 0 ){
+		nBus.request_type = BROADCAST_SPECIFIC_SENSORS;
+		return BROADCAST_SPECIFIC_SENSORS;
+	}
+
+	nBus.request_type = BROADCAST_GLOBAL;
+	return BROADCAST_GLOBAL;
+}
+
+void process_request(){
+	nBusCommandType_t request_type = get_request_type();
+	nBus_functionCode_t *fc = &nBus.function_code;
+	nBus.send_response = SEND_RESPONSE;
+
+	nBus.tx_buffer[0] = 0;
+	nBus.tx_buffer[1] = nBus.rx_buffer[0];	// Module address
+	nBus.tx_buffer[2] = nBus.rx_buffer[1];	// Sensor address
+
+	uint8_t crcC = crc8x_fast(0x00, nBus.rx_buffer, nBus.rx_length-1);
+	if(crcC != nBus.rx_buffer[nBus.rx_length-1]){
+		nBus.send_response = NO_RESPONSE;
+		return;
+	}
+
+	// paket nie je adresovany tomuto modulu
+	if(nBus.addressModule != MODULE_ADDRESS) {
+		nBus.send_response = NO_RESPONSE;
+		return;
+	}
+
+	// spracovanie broadcast komunikacie
+	if((request_type == BROADCAST_SPECIFIC_SENSORS || request_type == BROADCAST_GLOBAL)) {
+		nbus_broadcast(&nBus, request_type);
+		return;
+	}
+
+	if(nBus.function_code.notReadWrite == REQUEST_GET) {
+		fc->error = 1;
+		nBus.tx_length = META_SIZE;
+
+		if(request_type == UNICAST_TO_SENSOR) {
+
+		}
+
+		if(request_type == UNICAST_TO_MODULE) {
+			fc = nbus_unicastToModule(&nBus, fc);
+		}
+
+		nBus.tx_buffer[3] = *(uint8_t*)&fc;
+		nBus.tx_buffer[nBus.tx_length-1] = crc8x_fast(0x00, &nBus.tx_buffer[1], nBus.tx_length-2);
+		nBus.tx_buffer[0] = nBus.tx_length;
+
+	} else {
+
+	}
+
+}
+
+void nbus_stack(void){
+	receiveOneByte();
+
+	while(1){
+		if(nBus.uart_state == UART_RECEIVED){
+			//HAL_TIM_Base_Stop_IT(nBus.periph->uart_timer);
+
+			process_request();
+
+			// ready for next receiving
+			receiveOneByte();
+
+			send_response();
+		}
+	}
+
+}

+ 37 - 0
Src/nbus_impl.c

@@ -0,0 +1,37 @@
+#include "nbus_impl.h"
+
+extern nBus_TypeDef nBus;
+
+
+nBus_functionCode_t* nbus_unicastToModule(nBus_TypeDef *nbus, nBus_functionCode_t *code){
+	if(nbus->function_code.function == CMD_VERSION) {
+		nbus->tx_buffer[4] = '0';
+		nbus->tx_buffer[5] = '.';
+		nbus->tx_buffer[6] = '1';
+		nbus->tx_length += 3;
+		code->error = 0;
+	}
+
+	if(nbus->function_code.function == CMD_ECHO) {
+		for(uint8_t i=3 ; i<nbus->rx_length-1 ; i++){
+			nbus->tx_buffer[i+1] = nbus->rx_buffer[i];
+		}
+		nbus->tx_length += (nbus->rx_length-4);
+		code->error = 0;
+	}
+
+	return code;
+}
+
+
+void nbus_broadcast(nBus_TypeDef *nbus, nBusCommandType_t request_type){
+	if(request_type == BROADCAST_SPECIFIC_SENSORS) {
+
+	}
+
+	if(request_type == BROADCAST_GLOBAL) {
+
+	}
+
+	nbus->send_response = NO_RESPONSE;
+}