Browse Source

Работа со входами

TelenkovDmitry 1 year ago
parent
commit
baa9f25852

BIN
doc/~$_модули_входов_выходов_редакция_4.doc


+ 162 - 0
fw/modules/io/input.c

@@ -0,0 +1,162 @@
+#include "at32f403a_407.h"
+#include "input.h"
+#include "FreeRTOS.h"
+#include "task.h"
+#include <stdio.h>
+
+in_t inputs[INPUT_NUMBER] = {
+    {GPIOB, GPIO_PINS_11, 1, GPIO_PORT_SOURCE_GPIOB, GPIO_PINS_SOURCE11, 0},
+    {GPIOB, GPIO_PINS_10, 1, GPIO_PORT_SOURCE_GPIOB, GPIO_PINS_SOURCE10, 0},
+    {GPIOB, GPIO_PINS_1,  1, GPIO_PORT_SOURCE_GPIOB, GPIO_PINS_SOURCE1,  0},
+    {GPIOB, GPIO_PINS_0,  1, GPIO_PORT_SOURCE_GPIOB, GPIO_PINS_SOURCE0,  0},
+    {GPIOA, GPIO_PINS_3,  1, GPIO_PORT_SOURCE_GPIOA, GPIO_PINS_SOURCE3,  0},
+    {GPIOA, GPIO_PINS_2,  1, GPIO_PORT_SOURCE_GPIOA, GPIO_PINS_SOURCE2,  0},
+    {GPIOA, GPIO_PINS_1,  1, GPIO_PORT_SOURCE_GPIOA, GPIO_PINS_SOURCE1,  0},
+    {GPIOA, GPIO_PINS_0,  1, GPIO_PORT_SOURCE_GPIOA, GPIO_PINS_SOURCE0,  0}
+};
+
+//
+void in_init(in_t *input)
+{
+    gpio_init_type gpio_init_struct;
+    exint_init_type exint_init_struct;
+
+    // Вход
+    if (input->mode == 0)
+    {
+        gpio_default_para_init(&gpio_init_struct);
+        
+        gpio_init_struct.gpio_pull           = GPIO_PULL_NONE;  
+        gpio_init_struct.gpio_mode           = GPIO_MODE_INPUT;  
+        gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
+        gpio_init_struct.gpio_pins           = input->pin;
+        gpio_init(input->port, &gpio_init_struct); 
+    }
+    // Счетный вход
+    else if (input->mode == 1)
+    {
+        
+    }
+
+}
+
+//
+void in_exint_init(void)
+{
+    exint_init_type exint_init_struct;
+    
+    gpio_exint_line_config(GPIO_PORT_SOURCE_GPIOB, GPIO_PINS_SOURCE11); // 11
+    gpio_exint_line_config(GPIO_PORT_SOURCE_GPIOB, GPIO_PINS_SOURCE10); // 10
+    gpio_exint_line_config(GPIO_PORT_SOURCE_GPIOB, GPIO_PINS_SOURCE1);  // 1
+    gpio_exint_line_config(GPIO_PORT_SOURCE_GPIOB, GPIO_PINS_SOURCE0);  // 0
+    gpio_exint_line_config(GPIO_PORT_SOURCE_GPIOA, GPIO_PINS_SOURCE3);  // 3
+    gpio_exint_line_config(GPIO_PORT_SOURCE_GPIOA, GPIO_PINS_SOURCE2);  // 2
+    gpio_exint_line_config(GPIO_PORT_SOURCE_GPIOA, GPIO_PINS_SOURCE1);  // 1
+    gpio_exint_line_config(GPIO_PORT_SOURCE_GPIOA, GPIO_PINS_SOURCE0);  // 0
+    
+    exint_default_para_init(&exint_init_struct);
+    
+    exint_init_struct.line_enable = TRUE;
+    exint_init_struct.line_mode = EXINT_LINE_INTERRUPUT;
+    //exint_init_struct.line_select = EXINT_LINE_0 | EXINT_LINE_1 | EXINT_LINE_2 |
+    //                                EXINT_LINE_3 | EXINT_LINE_10 | EXINT_LINE_11; 
+    
+    //exint_init_struct.line_select = EXINT_LINE_11 | EXINT_LINE_10 | EXINT_LINE_1; 
+    exint_init_struct.line_select = EXINT_LINE_1; 
+    
+    exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;
+    exint_init(&exint_init_struct);
+    
+    nvic_irq_enable(EXINT0_IRQn, 5, 0);
+    nvic_irq_enable(EXINT1_IRQn, 5, 0);
+    nvic_irq_enable(EXINT2_IRQn, 5, 0);
+    nvic_irq_enable(EXINT3_IRQn, 5, 0);
+    nvic_irq_enable(EXINT4_IRQn, 5, 0);
+    nvic_irq_enable(EXINT15_10_IRQn, 5, 0);
+}
+
+//
+void io_test(void)
+{
+    printf("IN_1: %u IN_2: %u IN_3: %u IN_4: %u IN_5: %u IN_6: %u IN_7: %u IN_8: %u\r\n", 
+           gpio_input_data_bit_read(inputs[0].port, inputs[0].pin),
+           gpio_input_data_bit_read(inputs[1].port, inputs[1].pin),
+           gpio_input_data_bit_read(inputs[2].port, inputs[2].pin),
+           gpio_input_data_bit_read(inputs[3].port, inputs[3].pin),
+           gpio_input_data_bit_read(inputs[4].port, inputs[4].pin),
+           gpio_input_data_bit_read(inputs[5].port, inputs[5].pin),
+           gpio_input_data_bit_read(inputs[6].port, inputs[6].pin), 
+           gpio_input_data_bit_read(inputs[7].port, inputs[7].pin));
+}
+
+//
+void input_task(void *params)
+{
+    for (;;)
+    {
+        for (int i = 0; i < INPUT_NUMBER; i++)
+        {
+            // Режим обычного входа
+            if (inputs[i].mode == 0)
+            {
+                input_state[i] = (uint16_t)gpio_input_data_bit_read(inputs[i].port, inputs[i].pin);
+            }
+        }
+            
+        vTaskDelay(100);
+    }
+}
+
+
+void EXINT0_IRQHandler(void)
+{
+    if(exint_flag_get(EXINT_LINE_0) != RESET)
+    {
+        exint_flag_clear(EXINT_LINE_0);
+    }
+}
+
+void EXINT1_IRQHandler(void)
+{
+    if(exint_flag_get(EXINT_LINE_1) != RESET)   // IN_3 GPIOB_1
+    {
+        exint_flag_clear(EXINT_LINE_1);
+    }
+}
+
+void EXINT2_IRQHandler(void)
+{
+    if(exint_flag_get(EXINT_LINE_0) != RESET)
+    {
+        exint_flag_clear(EXINT_LINE_0);
+    }
+}
+
+void EXINT3_IRQHandler(void)
+{
+    if(exint_flag_get(EXINT_LINE_0) != RESET)
+    {
+        exint_flag_clear(EXINT_LINE_0);
+    }
+}
+
+void EXINT4_IRQHandler(void)
+{
+    if(exint_flag_get(EXINT_LINE_0) != RESET)
+    {
+        exint_flag_clear(EXINT_LINE_0);
+    }
+}
+
+void EXINT15_10_IRQHandler(void)
+{
+    if (exint_flag_get(EXINT_LINE_10) != RESET)  // IN_2 GPIOB_10
+    {
+        exint_flag_clear(EXINT_LINE_10);
+    }
+    if (exint_flag_get(EXINT_LINE_11) != RESET)  // IN_1 GPIOB_11
+    {
+        exint_flag_clear(EXINT_LINE_11);
+    }
+    
+}

+ 24 - 0
fw/modules/io/input.h

@@ -0,0 +1,24 @@
+#ifndef __INPUT_H
+#define __INPUT_H
+
+
+#include "io.h"
+
+
+extern in_t inputs[];
+
+//
+void in_init(in_t *input);
+
+//
+void in_exint_init(void);
+
+//
+void io_test(void);
+
+//
+void input_task(void *params);
+
+
+#endif  // __INPUT_H
+

+ 70 - 0
fw/modules/io/io.c

@@ -2,6 +2,76 @@
 #include "io.h"
 #include "FreeRTOS.h"
 #include "task.h"
+#include "input.h"
+#include <stdio.h>
 
 
+uint16_t input_state[INPUT_NUMBER];     // состояние входа
 
+// -------------------------------------------------------------------------- //
+// Текущие параметры
+
+//uint16_t input_state[INPUT_NUMBER];     // состояние входа
+//uint32_t input_cnt[INPUT_NUMBER];       // счетчики входов
+
+
+//
+void io_port_init(void)
+{
+    crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
+    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
+    crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
+    crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);
+    crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE);
+    
+    crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
+    
+    io_tim_init();
+}
+
+
+//
+void io_input_init(void)
+{
+    for (int i = 0; i < INPUT_NUMBER; i++)
+    {
+        in_init(&inputs[i]);
+    }
+}
+
+// Таймер для антидребезга
+void io_tim_init(void)
+{
+    crm_clocks_freq_type crm_clocks_freq_struct = {0};
+    
+    crm_clocks_freq_get(&crm_clocks_freq_struct);
+    
+    nvic_irq_disable(TMR8_BRK_TMR12_IRQn);
+    
+    crm_periph_clock_enable(CRM_TMR12_PERIPH_CLOCK, TRUE);
+
+    // 1 Hz
+    tmr_base_init(TMR12, 9, (crm_clocks_freq_struct.ahb_freq / 10000) - 1);
+    tmr_cnt_dir_set(TMR12, TMR_COUNT_UP);
+    
+    NVIC_ClearPendingIRQ(TMR8_BRK_TMR12_IRQn);
+    nvic_irq_enable(TMR8_BRK_TMR12_IRQn, 5, 0);
+    
+    tmr_flag_clear(TMR12, TMR_OVF_FLAG);
+    tmr_interrupt_enable(TMR12, TMR_OVF_INT, FALSE);
+    tmr_counter_value_set(TMR12, 0);
+    tmr_counter_enable(TMR12, TRUE);  
+}
+
+
+void TMR8_BRK_TMR12_IRQHandler(void)
+{
+    //static int i = 0;
+    //static int cnt = 0;
+
+    if(tmr_flag_get(TMR12, TMR_OVF_FLAG) != RESET)
+    {
+        tmr_flag_clear(TMR12, TMR_OVF_FLAG);
+        
+    }
+}

+ 70 - 43
fw/modules/io/io.h

@@ -1,70 +1,97 @@
-#ifndef __MUX_H
-#define __MUX_H
+#ifndef __IO_H
+#define __IO_H
 
 
-//
-#define LED_NUMBER      28
+// Период опроса входов 100 мс
 
-#define LINE_0_SET      GPIOE->scr = GPIO_PINS_3
-#define LINE_0_RESET    GPIOE->clr = GPIO_PINS_3
+#define INPUT_NUMBER    8    // Количество входов
+#define OUTPUT_NUMBER   8    // Количество выходов
 
-#define LINE_1_SET      GPIOE->scr = GPIO_PINS_2
-#define LINE_1_RESET    GPIOE->clr = GPIO_PINS_2
+// Прочие параметры из других модулей для передачи по modbus
 
-#define LINE_2_SET      GPIOB->scr = GPIO_PINS_9
-#define LINE_2_RESET    GPIOB->clr = GPIO_PINS_9
+//uint32_t uptime;
 
-#define COL_1_SET      GPIOD->scr = GPIO_PINS_6
-#define COL_1_RESET    GPIOD->clr = GPIO_PINS_6
 
-#define COL_2_SET      GPIOD->scr = GPIO_PINS_7
-#define COL_2_RESET    GPIOD->clr = GPIO_PINS_7
+// -------------------------------------------------------------------------- //
 
-#define COL_3_SET      GPIOB->scr = GPIO_PINS_6
-#define COL_3_RESET    GPIOB->clr = GPIO_PINS_6
+//
+void io_port_init(void);
 
-#define COL_4_SET      GPIOB->scr = GPIO_PINS_7
-#define COL_4_RESET    GPIOB->clr = GPIO_PINS_7
+//
+void io_input_init(void);
 
+//
+void io_tim_init(void);
 
+// -------------------------------------------------------------------------- //
 
-typedef enum
+typedef struct 
 {
-    LED_OFF = 0, 
-    LED_ON,
-    LED_BLINK,
-    
-} led_state_t;
+    gpio_type *port;
+    uint16_t pin;
+    uint16_t mode;
+    gpio_port_source_type port_source;
+    uint16_t pin_source;
+    uint32_t deb_counter;
+      
+} in_t;
 
+// -------------------------------------------------------------------------- //
+// Текущие параметры
 
-typedef struct 
-{
-    char            label[8];
-    uint8_t         line[3];    // [line_0, line_1, line_2]
-    led_state_t     state;
-    uint32_t        cnt;
-    
-} mux_channel_t;
+extern uint16_t input_state[INPUT_NUMBER];     // состояние входа
 
+//uint32_t input_cnt[INPUT_NUMBER];       // счетчики входов
 
-//
-void mux_led_init(mux_channel_t *ch);
+//uint16_t output_state[INPUT_NUMBER];    // состояние выхода, 0 - норма, 1 - обрыв, 2 - КЗ
 
-//
-void mux_gpio_init(void);
 
-//
-void mux_led_proc(void);
+// -------------------------------------------------------------------------- //
+// Структуры настроек. Хранятся во внутренней памяти контроллера.
 
 //
-void mux_led_blink(void);
+typedef struct
+{
+    uint16_t mode;           // режим работы, 0 - вход, 1 - счетчик импульсов
+    uint16_t debounce_time;  // период антидребезга в мс
+} input_t;
 
-//
-void mux_led_test_init(void);
 
 //
-void mux_led_test_toggle(void);
+// контроль состояний - обрыв, КЗ, норма
+typedef struct
+{
+    uint16_t state;         // состояние выхода
+    uint16_t pwm;           // 
+    uint16_t mode;          // режим работы, 0 - выход, 1 - PWM
+    uint16_t smode_state;   // значение в безопасном режиме,
+                            // 0 - разомкнут, 1 - замкнут
+    uint16_t smode_pwm;     // значение PWM в безопасном режиме (%)
+    uint16_t normal_state;  // нормальное состояние выхода
+                            // 0 - разомкнут, 1 - замкнут
+} output_t;
+
+
+typedef struct
+{
+    uint16_t smode;         // безопасный режим 0 - включен, 1 - выключен
+    uint16_t com_timeout;    // время ожидания запроса от мастера
+} system_t;
+
+
+// Структура системных настроек
+typedef struct 
+{
+	uint16_t        model;			// Модель
+	uint32_t        proddate;		// Дата производства
+	uint32_t        serial;			// Серийный номер
+	uint8_t         fw_version[8];	// Версия ПО
+	uint8_t         test_state;		// Статус тестирования
+	
+} sys_settings_t;
+
+
 
 
-#endif  // __MUX_H
+#endif  // __IO_H
 

+ 40 - 20
fw/modules/modbus/modbus_params.c

@@ -1,46 +1,66 @@
 #include "at32f403a_407.h"
 #include "modbus_params.h"
+#include "io.h"
 #include <string.h>
 
 
 mb_param_t mb_param[MB_PARAM_MAX];
-uint16_t psw; // Пароль для установки системных настроек
-bool psw_ok = false;
-bool set_sys_settings_flag = false;
-//sys_settings_t temp_sys_settings;
-uint16_t temp_modbus_port;
-uint16_t temp_reley;
-const float null_float = 0.0;
-
-
-uint32_t u32_param = 123456789;
-uint16_t u16_param = 32768;
-float f_param = 1.23456;
 
 
 
 //
 void mb_init_params(void)
 {
-    mb_param[0].reg = 0x30;
-	mb_param[0].size = 2;
-	mb_param[0].param = (uint8_t*)&u32_param;
+    mb_param[0].reg = 0x0100;
+	mb_param[0].size = 1;
+	mb_param[0].param = (uint8_t*)&input_state[0];
 	mb_param[0].set_handler = NULL;
     mb_param[0].check_handler = mb_check_dummy;
     
-    mb_param[1].reg = 0x32;
+    mb_param[1].reg = 0x0101;
 	mb_param[1].size = 1;
-	mb_param[1].param = (uint8_t*)&u16_param;
+	mb_param[1].param = (uint8_t*)&input_state[1];
 	mb_param[1].set_handler = NULL;
     mb_param[1].check_handler = mb_check_dummy;
     
-    mb_param[2].reg = 0x33;
-	mb_param[2].size = 2;
-	mb_param[2].param = (uint8_t*)&f_param;
+    mb_param[2].reg = 0x0102;
+	mb_param[2].size = 1;
+	mb_param[2].param = (uint8_t*)&input_state[2];
 	mb_param[2].set_handler = NULL;
     mb_param[2].check_handler = mb_check_dummy;
+    
+    mb_param[3].reg = 0x0103;
+	mb_param[3].size = 1;
+	mb_param[3].param = (uint8_t*)&input_state[3];
+	mb_param[3].set_handler = NULL;
+    mb_param[3].check_handler = mb_check_dummy;
+    
+    mb_param[4].reg = 0x0104;
+	mb_param[4].size = 1;
+	mb_param[4].param = (uint8_t*)&input_state[4];
+	mb_param[4].set_handler = NULL;
+    mb_param[4].check_handler = mb_check_dummy;
+    
+    mb_param[5].reg = 0x0105;
+	mb_param[5].size = 1;
+	mb_param[5].param = (uint8_t*)&input_state[5];
+	mb_param[5].set_handler = NULL;
+    mb_param[5].check_handler = mb_check_dummy;
+    
+    mb_param[6].reg = 0x0106;
+	mb_param[6].size = 1;
+	mb_param[6].param = (uint8_t*)&input_state[6];
+	mb_param[6].set_handler = NULL;
+    mb_param[6].check_handler = mb_check_dummy;
+    
+    mb_param[7].reg = 0x0107;
+	mb_param[7].size = 1;
+	mb_param[7].param = (uint8_t*)&input_state[7];
+	mb_param[7].set_handler = NULL;
+    mb_param[7].check_handler = mb_check_dummy;
 }
 
+
 // Возвращает размер параметра в регистрах
 bool mb_find_param(uint16_t reg, uint16_t *index, uint16_t *size)
 {

+ 1 - 1
fw/modules/modbus/modbus_params.h

@@ -9,7 +9,7 @@
 #include <stdbool.h>
 
 
-#define MB_PARAM_MAX			3
+#define MB_PARAM_MAX			8
 
 
 //

+ 27 - 0
fw/user/main.c

@@ -16,6 +16,8 @@
 #include "extended_sram.h"
 #include "modbus.h"
 #include "common_gpio.h"
+#include "io.h"
+#include "input.h"
 #include <stdio.h>
 #include <stdbool.h>
 #include <string.h>
@@ -25,6 +27,7 @@
 void init_task(void *argument);
 void test_hw_task(void *argument);
 void soft_wdt(void *params);
+void test_gpio(void *params);
 
 void usb_clock48m_select(usb_clk48_s clk_s);
 
@@ -45,7 +48,11 @@ int main(void)
     
     uart_print_init(115200);
     
+    io_port_init();
+    in_exint_init();
     cm_gpio_init();
+       
+      
     
     printf("\n\n\n\nModule universal IO [FW %s] loading....\r\n\n", VERSION);
         
@@ -61,6 +68,10 @@ int main(void)
     
     xTaskCreate(test_hw_task, "hw_task", 2*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
     
+    //xTaskCreate(test_gpio, "gpio_task", 2*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
+    
+    xTaskCreate(input_task, "input_task", 2*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
+    
     taskEXIT_CRITICAL();
     
     vTaskStartScheduler();
@@ -91,6 +102,10 @@ void init_task(void *argument)
     // Тесты USB
     //usb_eth_init();
     
+    // Базовая инициализация входов
+    // TODO потом брать значения из настроек
+    io_input_init();
+    
     for (;;)
     {
         mux_led_proc();
@@ -125,6 +140,18 @@ void soft_wdt(void *params)
     }
 }
 
+//
+void test_gpio(void *params)
+{
+    (void)params;
+    
+    for (;;)
+    {
+        vTaskDelay(100);
+        io_test();
+    }
+}
+
 
 
 //

File diff suppressed because it is too large
+ 555 - 550
project/ewarm/module_universal_io.dep


+ 3 - 0
project/ewarm/module_universal_io.ewp

@@ -2155,6 +2155,9 @@
                 <file>
                     <name>$PROJ_DIR$\..\..\fw\modules\io\common_gpio.c</name>
                 </file>
+                <file>
+                    <name>$PROJ_DIR$\..\..\fw\modules\io\input.c</name>
+                </file>
                 <file>
                     <name>$PROJ_DIR$\..\..\fw\modules\io\io.c</name>
                 </file>

+ 3 - 0
project/ewarm/module_universal_io.ewt

@@ -2378,6 +2378,9 @@
                 <file>
                     <name>$PROJ_DIR$\..\..\fw\modules\io\common_gpio.c</name>
                 </file>
+                <file>
+                    <name>$PROJ_DIR$\..\..\fw\modules\io\input.c</name>
+                </file>
                 <file>
                     <name>$PROJ_DIR$\..\..\fw\modules\io\io.c</name>
                 </file>

Some files were not shown because too many files changed in this diff