diff --git a/.vscode/settings.json b/.vscode/settings.json index 7c8e8d0dc..3aac17916 100755 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -151,7 +151,30 @@ "variant": "c", "soft_iic.h": "c", "sysinfo.h": "c", - "u_sleep.h": "c" + "u_sleep.h": "c", + "hmi_user_uart.h": "c", + "usart3.h": "c", + "u_local_thread.h": "c", + "string": "c", + "string_view": "c", + "vector": "c", + "cstddef": "c", + "usart2.h": "c", + "hmi_lcd_process.h": "c", + "stdlib.h": "c", + "auto_close.h": "c", + "u_sys.h": "c", + "relay.h": "c", + "spi1.h": "c", + "led.h": "c", + "adc.h": "c", + "w25q64.h": "c", + "__bit_reference": "c", + "unordered_map": "c", + "__strerror.h": "c", + "sstream": "c", + "u_drv.h": "c", + "__node_handle": "c" }, "cortex-debug.showRTOS": false, "cortex-debug.variableUseNaturalFormat": false, diff --git a/mkrtos_knl/CMakeLists.txt b/mkrtos_knl/CMakeLists.txt index 5d84e1dae..9ebf22670 100755 --- a/mkrtos_knl/CMakeLists.txt +++ b/mkrtos_knl/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.13) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} \ -Werror \ --D__MPU_PRESENT=1 -DUSE_STDPERIPH_DRIVER=1 -DSTM32F10X_XL \ +-D__MPU_PRESENT=1 -DUSE_STDPERIPH_DRIVER=1 \ -DKNL_OFFSET=$ENV{KEN_OFFSET} \ -DKNL_TEXT=$ENV{KNL_TEXT} \ -DINIT_OFFSET=$ENV{INIT_OFFSET} \ @@ -13,6 +13,13 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} \ -Wno-unused-variable \ ") set(CMAKE_ASM_FLAGS ${CMAKE_C_FLAGS}) + + +if (${BOARD_NAME} STREQUAL "STM32F1x") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSTM32F10X_XL ") +elseif(${BOARD_NAME} STREQUAL "STM32F2x" ) +endif() + message(编译参数:${CMAKE_C_FLAGS}) add_subdirectory(arch) add_subdirectory(drivers) diff --git a/mkrtos_knl/arch/armv7m/core_it.c b/mkrtos_knl/arch/armv7m/core_it.c index 57d11f506..5e6f5042f 100755 --- a/mkrtos_knl/arch/armv7m/core_it.c +++ b/mkrtos_knl/arch/armv7m/core_it.c @@ -187,27 +187,27 @@ void UsageFault_Handler(void) printk("%s\n", __FUNCTION__); if (SCB->CFSR & (1 << 16)) { - printk("未定义指令错误\n"); + printk("Undefined instruction error\n"); } if (SCB->CFSR & (1 << 17)) { - printk("试图切换到错误的状态\n"); + printk("Trying to switch to the wrong state\n"); } if (SCB->CFSR & (1 << 18)) { - printk("试图执行EXC_RETURN错误的异常\n"); + printk("An exception attempting to execute an EXC_RETURN error\n"); } if (SCB->CFSR & (1 << 19)) { - printk("试图执行协处理器指令\n"); + printk("An attempt was made to execute a coprocessor instruction\n"); } if (SCB->CFSR & (1 << 24)) { - printk("产生了非对其访问错误\n"); + printk("A non-access error was generated\n"); } if (SCB->CFSR & (1 << 25)) { - printk("除零错误\n"); + printk("Division by zero error\n"); } /* Go to infinite loop when Usage Fault exception occurs */ // while (1) diff --git a/mkrtos_knl/inc/knl/irq_sender.h b/mkrtos_knl/inc/knl/irq_sender.h index 387f89e97..be6579ce6 100644 --- a/mkrtos_knl/inc/knl/irq_sender.h +++ b/mkrtos_knl/inc/knl/irq_sender.h @@ -25,5 +25,5 @@ typedef struct irq_sender } irq_sender_t; void irq_sender_init(irq_sender_t *irq); -int irq_sender_wait(irq_sender_t *irq, thread_t *th); +int irq_sender_wait(irq_sender_t *irq, thread_t *th, int flags); void irq_sender_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag, entry_frame_t *f); diff --git a/mkrtos_knl/inc/lib/fcntl.h b/mkrtos_knl/inc/lib/fcntl.h new file mode 100644 index 000000000..bc4cef5a9 --- /dev/null +++ b/mkrtos_knl/inc/lib/fcntl.h @@ -0,0 +1,4 @@ +#pragma once + +#define O_NONBLOCK 04000 +#define O_NDELAY O_NONBLOCK diff --git a/mkrtos_knl/knl/irq_sender.c b/mkrtos_knl/knl/irq_sender.c index a0af298f2..4fdbe597f 100644 --- a/mkrtos_knl/knl/irq_sender.c +++ b/mkrtos_knl/knl/irq_sender.c @@ -18,6 +18,7 @@ #include #include #include +#include /** * @brief irq sender的操作号 * @@ -54,7 +55,7 @@ static void irq_tigger(irq_entry_t *irq) * @param th * @return int */ -int irq_sender_wait(irq_sender_t *irq, thread_t *th) +int irq_sender_wait(irq_sender_t *irq, thread_t *th, int flags) { umword_t status = cpulock_lock(); @@ -63,23 +64,35 @@ int irq_sender_wait(irq_sender_t *irq, thread_t *th) irq->wait_thread = th; if (irq->irq_cn > 0) { - irq->irq_cn = 0; cpulock_set(status); + irq->irq_cn = 0; + irq->wait_thread = NULL; } else { - thread_suspend(irq->wait_thread); + int ret = 0; + + if (!(flags & O_NONBLOCK)) + { + thread_suspend(irq->wait_thread); + ret = 0; + } + else + { + ret = -EAGAIN; + } cpulock_set(status); + irq->irq_cn = 0; irq->wait_thread = NULL; + return ret; } - irq->irq_cn = 0; return 0; } else { cpulock_set(status); - return -EACCES; + return -EAGAIN; } } static bool_t irq_sender_unbind(irq_sender_t *irq, int irq_no) @@ -140,7 +153,7 @@ void irq_sender_syscall(kobject_t *kobj, syscall_prot_t sys_p, msg_tag_t in_tag, case WAIT_IRQ: { ref_counter_inc(&th->ref); - int ret = irq_sender_wait(irq, th); + int ret = irq_sender_wait(irq, th, f->r[1]); ref_counter_dec_and_release(&th->ref, &irq->kobj); //! 引用计数+1 tag = msg_tag_init4(0, 0, 0, ret); } diff --git a/mkrtos_knl/knl/log.c b/mkrtos_knl/knl/log.c index d812ec493..89a4c16c9 100755 --- a/mkrtos_knl/knl/log.c +++ b/mkrtos_knl/knl/log.c @@ -68,7 +68,7 @@ static int log_read_data(log_t *log, uint8_t *data, int len) if (c < 0 && i == 0) { - int ret = irq_sender_wait(&log->kobj, thread_get_current()); + int ret = irq_sender_wait(&log->kobj, thread_get_current(), 0); if (ret < 0) { return ret; diff --git a/mkrtos_knl/knl/map.c b/mkrtos_knl/knl/map.c index 695a9205a..7599e3b6b 100755 --- a/mkrtos_knl/knl/map.c +++ b/mkrtos_knl/knl/map.c @@ -1,12 +1,12 @@ /** * @file map.c * @author zhangzheng (1358745329@qq.com) - * @brief + * @brief * @version 0.1 * @date 2023-09-29 - * + * * @copyright Copyright (c) 2023 - * + * */ #include "map.h" #include "types.h" @@ -28,14 +28,14 @@ bool_t obj_map_root(kobject_t *kobj, obj_space_t *obj_space, ram_limit_t *ram, v } /** * @brief 从源映射到目的,如果目的中已经存在,则先解除目的映射然后在影视 - * - * @param dst_space - * @param src_space - * @param dst_inx - * @param src_inx - * @param ram - * @param del_attrs - * @return int + * + * @param dst_space + * @param src_space + * @param dst_inx + * @param src_inx + * @param ram + * @param del_attrs + * @return int */ int obj_map_src_dst(obj_space_t *dst_space, obj_space_t *src_space, obj_handler_t dst_inx, obj_handler_t src_inx, @@ -52,7 +52,8 @@ int obj_map_src_dst(obj_space_t *dst_space, obj_space_t *src_space, return -ENOENT; } - if (obj_space_lookup_kobj(dst_space, dst_inx)) { //!< 已经存在则解除注释 + if (obj_space_lookup_kobj(dst_space, dst_inx)) + { //!< 已经存在则解除注释 obj_unmap(dst_space, vpage_create3(0, 0, dst_inx), del_list); } @@ -101,10 +102,11 @@ void obj_unmap(obj_space_t *obj_space, vpage_t vpage, kobj_del_list_t *del_list) { //!< 代表删除所有 obj_map_entry_t *pos; + again: slist_foreach(pos, &kobj->mappable.node, node) { - slist_del(&entry->node); + slist_del(&pos->node); entry->obj = NULL; // 删除一个 kobj->mappable.map_cnt--; @@ -115,6 +117,7 @@ void obj_unmap(obj_space_t *obj_space, vpage_t vpage, kobj_del_list_t *del_list) kobj_del_list_add(del_list, &kobj->del_node); } } + goto again; } } else diff --git a/mkrtos_knl/knl/scheduler.c b/mkrtos_knl/knl/scheduler.c index db48c23f7..e7aa4dac5 100755 --- a/mkrtos_knl/knl/scheduler.c +++ b/mkrtos_knl/knl/scheduler.c @@ -18,7 +18,10 @@ umword_t sched_reset = 0; void scheduler_reset(void) { + scheduler_t *sched = scheduler_get_current(); + sched_reset = 0; + sched->cur_sche = NULL; } scheduler_t *scheduler_get_current(void) diff --git a/mkrtos_knl/knl/task.c b/mkrtos_knl/knl/task.c index cd3860142..5e0e6b588 100755 --- a/mkrtos_knl/knl/task.c +++ b/mkrtos_knl/knl/task.c @@ -38,7 +38,7 @@ int task_alloc_base_ram(task_t *tk, ram_limit_t *lim, size_t size) void *ram = mpu_ram_alloc(&tk->mm_space, lim, size + THREAD_MSG_BUG_LEN); if (!ram) { - printk("申请进程内存失败.\n"); + printk("Failed to request process memory.\n"); return -ENOMEM; } mm_space_set_ram_block(&tk->mm_space, ram, size + THREAD_MSG_BUG_LEN); @@ -168,10 +168,9 @@ static void task_release_stage2(kobject_t *kobj) mm_limit_free_align(tk->lim, tk->mm_space.mm_block, tk->mm_space.mm_block_size); mm_limit_free(tk->lim, tk); // if (cur_tk == tk) - { - thread_sched(); - } - scheduler_reset(); + // { + thread_sched(); + // } // mm_trace(); printk("release tk %x\n", tk); } diff --git a/mkrtos_knl/knl/thread.c b/mkrtos_knl/knl/thread.c index 6531effca..747379307 100755 --- a/mkrtos_knl/knl/thread.c +++ b/mkrtos_knl/knl/thread.c @@ -91,10 +91,11 @@ static void thread_release_stage2(kobject_t *kobj) printk("release thread 0x%x\n", kobj); mm_limit_free_align(th->lim, kobj, THREAD_BLOCK_SIZE); - // if (cur_th == th) - // { - thread_sched(); - // } + if (cur_th == th) + { + thread_sched(); + scheduler_reset(); + } } /** diff --git a/mkrtos_knl/knl/thread_knl.c b/mkrtos_knl/knl/thread_knl.c index 912140006..9af40c078 100755 --- a/mkrtos_knl/knl/thread_knl.c +++ b/mkrtos_knl/knl/thread_knl.c @@ -84,6 +84,7 @@ static void knl_init_2(void) assert(obj_map_root(kobj, &init_task->obj_space, &root_factory_get()->limit, vpage_create3(KOBJ_ALL_RIGHTS, 0, i))); } } + init_thread->sche.prio = 2; thread_ready(init_thread, FALSE); } INIT_STAGE2(knl_init_2); diff --git a/mkrtos_user/lib/CMakeLists.txt b/mkrtos_user/lib/CMakeLists.txt index a14d7fd4a..eb920e4a0 100644 --- a/mkrtos_user/lib/CMakeLists.txt +++ b/mkrtos_user/lib/CMakeLists.txt @@ -9,6 +9,7 @@ set(CMAKE_ASM_FLAGS ${CMAKE_C_FLAGS}) add_subdirectory(sys) add_subdirectory(sys_util) add_subdirectory(sys_svr) +add_subdirectory(stm32f1_bsp) add_subdirectory(libc_backend) add_subdirectory(mlibc) add_subdirectory(cpio) diff --git a/mkrtos_user/lib/mlibc/include/stdlib.h b/mkrtos_user/lib/mlibc/include/stdlib.h index 475190bfa..7a806d735 100644 --- a/mkrtos_user/lib/mlibc/include/stdlib.h +++ b/mkrtos_user/lib/mlibc/include/stdlib.h @@ -2,7 +2,8 @@ #define _STDLIB_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #include @@ -12,7 +13,9 @@ extern "C" { #elif defined(__cplusplus) #define NULL 0L #else -#define NULL ((void*)0) +#ifndef NULL +#define NULL ((void *)0) +#endif #endif #define __NEED_size_t @@ -20,147 +23,151 @@ extern "C" { #include -int atoi (const char *); -long atol (const char *); -long long atoll (const char *); -double atof (const char *); + int atoi(const char *); + long atol(const char *); + long long atoll(const char *); + double atof(const char *); -float strtof (const char *__restrict, char **__restrict); -double strtod (const char *__restrict, char **__restrict); -long double strtold (const char *__restrict, char **__restrict); + float strtof(const char *__restrict, char **__restrict); + double strtod(const char *__restrict, char **__restrict); + long double strtold(const char *__restrict, char **__restrict); -long strtol (const char *__restrict, char **__restrict, int); -unsigned long strtoul (const char *__restrict, char **__restrict, int); -long long strtoll (const char *__restrict, char **__restrict, int); -unsigned long long strtoull (const char *__restrict, char **__restrict, int); + long strtol(const char *__restrict, char **__restrict, int); + unsigned long strtoul(const char *__restrict, char **__restrict, int); + long long strtoll(const char *__restrict, char **__restrict, int); + unsigned long long strtoull(const char *__restrict, char **__restrict, int); -int rand (void); -void srand (unsigned); + int rand(void); + void srand(unsigned); -void *malloc (size_t); -void *calloc (size_t, size_t); -void *realloc (void *, size_t); -void free (void *); -void *aligned_alloc(size_t, size_t); + void *malloc(size_t); + void *calloc(size_t, size_t); + void *realloc(void *, size_t); + void free(void *); + void *aligned_alloc(size_t, size_t); -_Noreturn void abort (void); -int atexit (void (*) (void)); -_Noreturn void exit (int); -_Noreturn void _Exit (int); -int at_quick_exit (void (*) (void)); -_Noreturn void quick_exit (int); + _Noreturn void abort(void); + int atexit(void (*)(void)); + _Noreturn void exit(int); + _Noreturn void _Exit(int); + int at_quick_exit(void (*)(void)); + _Noreturn void quick_exit(int); -char *getenv (const char *); + char *getenv(const char *); -int system (const char *); + int system(const char *); -void *bsearch (const void *, const void *, size_t, size_t, int (*)(const void *, const void *)); -void qsort (void *, size_t, size_t, int (*)(const void *, const void *)); + void *bsearch(const void *, const void *, size_t, size_t, int (*)(const void *, const void *)); + void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); -int abs (int); -long labs (long); -long long llabs (long long); + int abs(int); + long labs(long); + long long llabs(long long); -typedef struct { int quot, rem; } div_t; -typedef struct { long quot, rem; } ldiv_t; -typedef struct { long long quot, rem; } lldiv_t; + typedef struct + { + int quot, rem; + } div_t; + typedef struct + { + long quot, rem; + } ldiv_t; + typedef struct + { + long long quot, rem; + } lldiv_t; -div_t div (int, int); -ldiv_t ldiv (long, long); -lldiv_t lldiv (long long, long long); + div_t div(int, int); + ldiv_t ldiv(long, long); + lldiv_t lldiv(long long, long long); -int mblen (const char *, size_t); -int mbtowc (wchar_t *__restrict, const char *__restrict, size_t); -int wctomb (char *, wchar_t); -size_t mbstowcs (wchar_t *__restrict, const char *__restrict, size_t); -size_t wcstombs (char *__restrict, const wchar_t *__restrict, size_t); + int mblen(const char *, size_t); + int mbtowc(wchar_t *__restrict, const char *__restrict, size_t); + int wctomb(char *, wchar_t); + size_t mbstowcs(wchar_t *__restrict, const char *__restrict, size_t); + size_t wcstombs(char *__restrict, const wchar_t *__restrict, size_t); #define EXIT_FAILURE 1 #define EXIT_SUCCESS 0 -size_t __ctype_get_mb_cur_max(void); + size_t __ctype_get_mb_cur_max(void); #define MB_CUR_MAX (__ctype_get_mb_cur_max()) #define RAND_MAX (0x7fffffff) +#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) -#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ - || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ - || defined(_BSD_SOURCE) +#define WNOHANG 1 +#define WUNTRACED 2 -#define WNOHANG 1 -#define WUNTRACED 2 - -#define WEXITSTATUS(s) (((s) & 0xff00) >> 8) -#define WTERMSIG(s) ((s) & 0x7f) +#define WEXITSTATUS(s) (((s)&0xff00) >> 8) +#define WTERMSIG(s) ((s)&0x7f) #define WSTOPSIG(s) WEXITSTATUS(s) #define WIFEXITED(s) (!WTERMSIG(s)) -#define WIFSTOPPED(s) ((short)((((s)&0xffff)*0x10001U)>>8) > 0x7f00) -#define WIFSIGNALED(s) (((s)&0xffff)-1U < 0xffu) +#define WIFSTOPPED(s) ((short)((((s)&0xffff) * 0x10001U) >> 8) > 0x7f00) +#define WIFSIGNALED(s) (((s)&0xffff) - 1U < 0xffu) -int posix_memalign (void **, size_t, size_t); -int setenv (const char *, const char *, int); -int unsetenv (const char *); -int mkstemp (char *); -int mkostemp (char *, int); -char *mkdtemp (char *); -int getsubopt (char **, char *const *, char **); -int rand_r (unsigned *); + int posix_memalign(void **, size_t, size_t); + int setenv(const char *, const char *, int); + int unsetenv(const char *); + int mkstemp(char *); + int mkostemp(char *, int); + char *mkdtemp(char *); + int getsubopt(char **, char *const *, char **); + int rand_r(unsigned *); #endif - -#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ - || defined(_BSD_SOURCE) -char *realpath (const char *__restrict, char *__restrict); -long int random (void); -void srandom (unsigned int); -char *initstate (unsigned int, char *, size_t); -char *setstate (char *); -int putenv (char *); -int posix_openpt (int); -int grantpt (int); -int unlockpt (int); -char *ptsname (int); -char *l64a (long); -long a64l (const char *); -void setkey (const char *); -double drand48 (void); -double erand48 (unsigned short [3]); -long int lrand48 (void); -long int nrand48 (unsigned short [3]); -long mrand48 (void); -long jrand48 (unsigned short [3]); -void srand48 (long); -unsigned short *seed48 (unsigned short [3]); -void lcong48 (unsigned short [7]); +#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) + char *realpath(const char *__restrict, char *__restrict); + long int random(void); + void srandom(unsigned int); + char *initstate(unsigned int, char *, size_t); + char *setstate(char *); + int putenv(char *); + int posix_openpt(int); + int grantpt(int); + int unlockpt(int); + char *ptsname(int); + char *l64a(long); + long a64l(const char *); + void setkey(const char *); + double drand48(void); + double erand48(unsigned short[3]); + long int lrand48(void); + long int nrand48(unsigned short[3]); + long mrand48(void); + long jrand48(unsigned short[3]); + void srand48(long); + unsigned short *seed48(unsigned short[3]); + void lcong48(unsigned short[7]); #endif #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) #include -char *mktemp (char *); -int mkstemps (char *, int); -int mkostemps (char *, int, int); -void *valloc (size_t); -void *memalign(size_t, size_t); -int getloadavg(double *, int); -int clearenv(void); -#define WCOREDUMP(s) ((s) & 0x80) + char *mktemp(char *); + int mkstemps(char *, int); + int mkostemps(char *, int, int); + void *valloc(size_t); + void *memalign(size_t, size_t); + int getloadavg(double *, int); + int clearenv(void); +#define WCOREDUMP(s) ((s)&0x80) #define WIFCONTINUED(s) ((s) == 0xffff) -void *reallocarray (void *, size_t, size_t); -void qsort_r (void *, size_t, size_t, int (*)(const void *, const void *, void *), void *); + void *reallocarray(void *, size_t, size_t); + void qsort_r(void *, size_t, size_t, int (*)(const void *, const void *, void *), void *); #endif #ifdef _GNU_SOURCE -int ptsname_r(int, char *, size_t); -char *ecvt(double, int, int *, int *); -char *fcvt(double, int, int *, int *); -char *gcvt(double, int, char *); -char *secure_getenv(const char *); -struct __locale_struct; -float strtof_l(const char *__restrict, char **__restrict, struct __locale_struct *); -double strtod_l(const char *__restrict, char **__restrict, struct __locale_struct *); -long double strtold_l(const char *__restrict, char **__restrict, struct __locale_struct *); + int ptsname_r(int, char *, size_t); + char *ecvt(double, int, int *, int *); + char *fcvt(double, int, int *, int *); + char *gcvt(double, int, char *); + char *secure_getenv(const char *); + struct __locale_struct; + float strtof_l(const char *__restrict, char **__restrict, struct __locale_struct *); + double strtod_l(const char *__restrict, char **__restrict, struct __locale_struct *); + long double strtold_l(const char *__restrict, char **__restrict, struct __locale_struct *); #endif #if defined(_LARGEFILE64_SOURCE) diff --git a/mkrtos_user/lib/mlibc/obj/include/bits/syscall.h b/mkrtos_user/lib/mlibc/obj/include/bits/syscall.h index ff3e2d380..6c607664e 100644 --- a/mkrtos_user/lib/mlibc/obj/include/bits/syscall.h +++ b/mkrtos_user/lib/mlibc/obj/include/bits/syscall.h @@ -79,7 +79,7 @@ #define __NR_stat 106 #define __NR_lstat 107 #define __NR_fstat 108 -#define __NR_vhangup 111 +#define __NR_vhangup 447//111 #define __NR_wait4 114 #define __NR_swapoff 115 #define __NR_sysinfo 116 @@ -404,7 +404,7 @@ #define __ARM_NR_cacheflush 0x0f0002 #define __ARM_NR_usr26 0x0f0003 #define __ARM_NR_usr32 0x0f0004 -#define __ARM_NR_set_tls 0x447//0x0f0005 +#define __ARM_NR_set_tls 111//0x0f0005 #define __ARM_NR_get_tls 0x0f0006 #define SYS_restart_syscall 0 diff --git a/mkrtos_user/lib/mlibc/src/errno/strerror.c b/mkrtos_user/lib/mlibc/src/errno/strerror.c index 7f926432b..89a7d762f 100644 --- a/mkrtos_user/lib/mlibc/src/errno/strerror.c +++ b/mkrtos_user/lib/mlibc/src/errno/strerror.c @@ -5,13 +5,15 @@ /* mips has one error code outside of the 8-bit range due to a * historical typo, so we just remap it. */ -#if EDQUOT==1133 +#if EDQUOT == 1133 #define EDQUOT_ORIG 1133 -#undef EDQUOT +#undef EDQUOT #define EDQUOT 109 #endif -static const struct errmsgstr_t { +static const struct errmsgstr_t +{ +#ifdef NO_LITTLE_MODE #define E(n, s) char str##n[sizeof(s)]; #include "__strerror.h" #undef E @@ -19,24 +21,34 @@ static const struct errmsgstr_t { #define E(n, s) s, #include "__strerror.h" #undef E +#endif }; static const unsigned short errmsgidx[] = { +#ifdef NO_LITTLE_MODE #define E(n, s) [n] = offsetof(struct errmsgstr_t, str##n), #include "__strerror.h" #undef E +#endif }; char *__strerror_l(int e, locale_t loc) { +#ifdef NO_LITTLE_MODE const char *s; #ifdef EDQUOT_ORIG - if (e==EDQUOT) e=0; - else if (e==EDQUOT_ORIG) e=EDQUOT; + if (e == EDQUOT) + e = 0; + else if (e == EDQUOT_ORIG) + e = EDQUOT; #endif - if (e >= sizeof errmsgidx / sizeof *errmsgidx) e = 0; + if (e >= sizeof errmsgidx / sizeof *errmsgidx) + e = 0; s = (char *)&errmsgstr + errmsgidx[e]; return (char *)LCTRANS(s, LC_MESSAGES, loc); +#else + return "error."; +#endif } char *strerror(int e) diff --git a/mkrtos_user/lib/stm32f1_bsp/CMakeLists.txt b/mkrtos_user/lib/stm32f1_bsp/CMakeLists.txt new file mode 100644 index 000000000..5f1caaf89 --- /dev/null +++ b/mkrtos_user/lib/stm32f1_bsp/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required(VERSION 3.13) + + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_STDPERIPH_DRIVER=1 -DSTM32F10X_XL \ +-fPIC -n -pie -fpie -fpic -msingle-pic-base -mno-pic-data-is-text-relative \ +-Wl,--gc-sections -D__dietlibc__ -D__arm__ -D__WORDSIZE=32 -D__ARM_ARCH_7M__ \ +" ) +set(CMAKE_ASM_FLAGS ${CMAKE_C_FLAGS}) + + +file(GLOB_RECURSE deps *.c *.S) +add_library( + stm32f1_bsp + STATIC + ${deps} +) +target_include_directories( + stm32f1_bsp + PUBLIC + ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/stm32f1_bsp/inc + ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/stm32f1_bsp/core_inc + ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys/inc + ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/cpio + + ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/arch/arm/ + ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/arch/generic + ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/obj/src/internal + ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/src/include + ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/src/internal + ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/obj/include + ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/include +) +target_link_libraries( + stm32f1_bsp + PUBLIC + sys + muslc + cpio +) +add_dependencies(stm32f1_bsp sys) +add_dependencies(stm32f1_bsp muslc) + + diff --git a/mkrtos_user/server/app/bsp/core_inc/arm_common_tables.h b/mkrtos_user/lib/stm32f1_bsp/core_inc/arm_common_tables.h similarity index 100% rename from mkrtos_user/server/app/bsp/core_inc/arm_common_tables.h rename to mkrtos_user/lib/stm32f1_bsp/core_inc/arm_common_tables.h diff --git a/mkrtos_user/server/app/bsp/core_inc/arm_math.h b/mkrtos_user/lib/stm32f1_bsp/core_inc/arm_math.h similarity index 100% rename from mkrtos_user/server/app/bsp/core_inc/arm_math.h rename to mkrtos_user/lib/stm32f1_bsp/core_inc/arm_math.h diff --git a/mkrtos_user/server/app/bsp/core_inc/cmsis_gcc.h b/mkrtos_user/lib/stm32f1_bsp/core_inc/cmsis_gcc.h similarity index 100% rename from mkrtos_user/server/app/bsp/core_inc/cmsis_gcc.h rename to mkrtos_user/lib/stm32f1_bsp/core_inc/cmsis_gcc.h diff --git a/mkrtos_user/server/app/bsp/core_inc/core_cm3.h b/mkrtos_user/lib/stm32f1_bsp/core_inc/core_cm3.h similarity index 100% rename from mkrtos_user/server/app/bsp/core_inc/core_cm3.h rename to mkrtos_user/lib/stm32f1_bsp/core_inc/core_cm3.h diff --git a/mkrtos_user/server/app/bsp/core_inc/core_cm4.h b/mkrtos_user/lib/stm32f1_bsp/core_inc/core_cm4.h similarity index 100% rename from mkrtos_user/server/app/bsp/core_inc/core_cm4.h rename to mkrtos_user/lib/stm32f1_bsp/core_inc/core_cm4.h diff --git a/mkrtos_user/server/app/bsp/core_inc/core_cm4_simd.h b/mkrtos_user/lib/stm32f1_bsp/core_inc/core_cm4_simd.h similarity index 100% rename from mkrtos_user/server/app/bsp/core_inc/core_cm4_simd.h rename to mkrtos_user/lib/stm32f1_bsp/core_inc/core_cm4_simd.h diff --git a/mkrtos_user/server/app/bsp/core_inc/core_cmFunc.h b/mkrtos_user/lib/stm32f1_bsp/core_inc/core_cmFunc.h similarity index 100% rename from mkrtos_user/server/app/bsp/core_inc/core_cmFunc.h rename to mkrtos_user/lib/stm32f1_bsp/core_inc/core_cmFunc.h diff --git a/mkrtos_user/server/app/bsp/core_inc/core_cmInstr.h b/mkrtos_user/lib/stm32f1_bsp/core_inc/core_cmInstr.h similarity index 100% rename from mkrtos_user/server/app/bsp/core_inc/core_cmInstr.h rename to mkrtos_user/lib/stm32f1_bsp/core_inc/core_cmInstr.h diff --git a/mkrtos_user/server/app/bsp/core_inc/core_cmSimd.h b/mkrtos_user/lib/stm32f1_bsp/core_inc/core_cmSimd.h similarity index 100% rename from mkrtos_user/server/app/bsp/core_inc/core_cmSimd.h rename to mkrtos_user/lib/stm32f1_bsp/core_inc/core_cmSimd.h diff --git a/mkrtos_user/server/app/bsp/core_inc/mpu_armv7.h b/mkrtos_user/lib/stm32f1_bsp/core_inc/mpu_armv7.h similarity index 100% rename from mkrtos_user/server/app/bsp/core_inc/mpu_armv7.h rename to mkrtos_user/lib/stm32f1_bsp/core_inc/mpu_armv7.h diff --git a/mkrtos_user/server/app/bsp/inc/misc.h b/mkrtos_user/lib/stm32f1_bsp/inc/misc.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/misc.h rename to mkrtos_user/lib/stm32f1_bsp/inc/misc.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32_sys.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32_sys.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32_sys.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32_sys.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_adc.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_adc.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_adc.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_adc.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_bkp.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_bkp.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_bkp.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_bkp.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_can.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_can.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_can.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_can.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_cec.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_cec.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_cec.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_cec.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_conf.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_conf.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_conf.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_conf.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_crc.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_crc.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_crc.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_crc.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_dac.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_dac.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_dac.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_dac.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_dbgmcu.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_dbgmcu.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_dbgmcu.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_dbgmcu.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_dma.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_dma.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_dma.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_dma.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_exti.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_exti.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_exti.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_exti.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_flash.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_flash.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_flash.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_flash.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_fsmc.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_fsmc.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_fsmc.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_fsmc.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_gpio.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_gpio.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_gpio.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_gpio.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_i2c.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_i2c.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_i2c.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_i2c.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_it.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_it.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_it.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_it.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_iwdg.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_iwdg.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_iwdg.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_iwdg.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_pwr.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_pwr.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_pwr.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_pwr.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_rcc.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_rcc.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_rcc.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_rcc.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_rtc.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_rtc.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_rtc.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_rtc.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_sdio.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_sdio.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_sdio.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_sdio.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_spi.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_spi.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_spi.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_spi.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_tim.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_tim.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_tim.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_tim.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_usart.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_usart.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_usart.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_usart.h diff --git a/mkrtos_user/server/app/bsp/inc/stm32f10x_wwdg.h b/mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_wwdg.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/stm32f10x_wwdg.h rename to mkrtos_user/lib/stm32f1_bsp/inc/stm32f10x_wwdg.h diff --git a/mkrtos_user/server/app/bsp/inc/system_stm32f10x.h b/mkrtos_user/lib/stm32f1_bsp/inc/system_stm32f10x.h similarity index 100% rename from mkrtos_user/server/app/bsp/inc/system_stm32f10x.h rename to mkrtos_user/lib/stm32f1_bsp/inc/system_stm32f10x.h diff --git a/mkrtos_user/server/app/bsp/src/misc.c b/mkrtos_user/lib/stm32f1_bsp/src/misc.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/misc.c rename to mkrtos_user/lib/stm32f1_bsp/src/misc.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_adc.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_adc.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_adc.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_adc.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_bkp.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_bkp.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_bkp.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_bkp.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_can.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_can.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_can.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_can.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_cec.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_cec.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_cec.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_cec.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_crc.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_crc.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_crc.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_crc.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_dac.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_dac.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_dac.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_dac.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_dbgmcu.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_dbgmcu.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_dbgmcu.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_dbgmcu.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_dma.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_dma.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_dma.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_dma.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_exti.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_exti.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_exti.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_exti.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_flash.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_flash.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_flash.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_flash.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_fsmc.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_fsmc.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_fsmc.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_fsmc.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_gpio.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_gpio.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_gpio.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_gpio.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_i2c.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_i2c.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_i2c.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_i2c.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_iwdg.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_iwdg.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_iwdg.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_iwdg.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_pwr.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_pwr.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_pwr.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_pwr.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_rcc.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_rcc.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_rcc.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_rcc.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_rtc.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_rtc.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_rtc.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_rtc.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_sdio.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_sdio.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_sdio.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_sdio.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_spi.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_spi.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_spi.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_spi.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_tim.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_tim.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_tim.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_tim.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_usart.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_usart.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_usart.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_usart.c diff --git a/mkrtos_user/server/app/bsp/src/stm32f10x_wwdg.c b/mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_wwdg.c similarity index 100% rename from mkrtos_user/server/app/bsp/src/stm32f10x_wwdg.c rename to mkrtos_user/lib/stm32f1_bsp/src/stm32f10x_wwdg.c diff --git a/mkrtos_user/lib/sys/inc/u_irq_sender.h b/mkrtos_user/lib/sys/inc/u_irq_sender.h index b16e0f6f1..4c8e212ce 100644 --- a/mkrtos_user/lib/sys/inc/u_irq_sender.h +++ b/mkrtos_user/lib/sys/inc/u_irq_sender.h @@ -3,5 +3,5 @@ #include "u_types.h" msg_tag_t uirq_bind(obj_handler_t obj_inx, umword_t irq_no, umword_t prio_sub_pre); -msg_tag_t uirq_wait(obj_handler_t obj_inx); +msg_tag_t uirq_wait(obj_handler_t obj_inx, int flags); msg_tag_t uirq_ack(obj_handler_t obj_inx, umword_t irq_no); \ No newline at end of file diff --git a/mkrtos_user/lib/sys/inc/u_sys.h b/mkrtos_user/lib/sys/inc/u_sys.h index cf006ad93..24a5d547a 100644 --- a/mkrtos_user/lib/sys/inc/u_sys.h +++ b/mkrtos_user/lib/sys/inc/u_sys.h @@ -1,7 +1,7 @@ #pragma once #include "u_types.h" - +#include "u_prot.h" typedef struct sys_info { umword_t sys_tick; @@ -9,3 +9,10 @@ typedef struct sys_info } sys_info_t; msg_tag_t sys_read_info(obj_handler_t obj, sys_info_t *info); + +#define sys_read_tick() ({ \ + sys_info_t info; \ + \ + sys_read_info(SYS_PROT, &info); \ + info.sys_tick; \ +}) diff --git a/mkrtos_user/lib/sys/src/u_irq_sender.c b/mkrtos_user/lib/sys/src/u_irq_sender.c index 9db643d8f..e4043f43d 100644 --- a/mkrtos_user/lib/sys/src/u_irq_sender.c +++ b/mkrtos_user/lib/sys/src/u_irq_sender.c @@ -37,13 +37,13 @@ msg_tag_t uirq_bind(obj_handler_t obj_inx, umword_t irq_no, umword_t prio_sub_pr return tag; } -msg_tag_t uirq_wait(obj_handler_t obj_inx) +msg_tag_t uirq_wait(obj_handler_t obj_inx, int flags) { register volatile umword_t r0 asm("r0"); syscall(syscall_prot_create(WAIT_IRQ, IRQ_PROT, obj_inx), 0, - 0, + flags, 0, 0, 0, diff --git a/mkrtos_user/lib/sys_svr/inc/ns_types.h b/mkrtos_user/lib/sys_svr/inc/ns_types.h index ebfce2570..a9a66f8e1 100644 --- a/mkrtos_user/lib/sys_svr/inc/ns_types.h +++ b/mkrtos_user/lib/sys_svr/inc/ns_types.h @@ -2,7 +2,7 @@ #include "u_types.h" #include "u_rpc_svr.h" #define NAMESPACE_PATH_LEN 32 -#define NAMESAPCE_NR 32 +#define NAMESAPCE_NR 8 typedef struct namespace_entry { diff --git a/mkrtos_user/lib/sys_util/inc/u_drv.h b/mkrtos_user/lib/sys_util/inc/u_drv.h new file mode 100644 index 000000000..b5a4f3aed --- /dev/null +++ b/mkrtos_user/lib/sys_util/inc/u_drv.h @@ -0,0 +1,4 @@ + +#pragma once + +int u_drv_init(void); diff --git a/mkrtos_user/lib/sys_util/inc/u_local_thread.h b/mkrtos_user/lib/sys_util/inc/u_local_thread.h new file mode 100644 index 000000000..f0ed45418 --- /dev/null +++ b/mkrtos_user/lib/sys_util/inc/u_local_thread.h @@ -0,0 +1,6 @@ +#pragma once + +#include "u_types.h" +#include "u_hd_man.h" + +int thread_create(int prio, void *(*fn)(void *arg), umword_t stack_top, obj_handler_t *ret_hd); diff --git a/mkrtos_user/lib/sys_util/src/u_drv.c b/mkrtos_user/lib/sys_util/src/u_drv.c new file mode 100644 index 000000000..818d4555a --- /dev/null +++ b/mkrtos_user/lib/sys_util/src/u_drv.c @@ -0,0 +1,19 @@ + + +#include "u_types.h" +#include "u_prot.h" +#include "u_mm.h" +#include "u_sleep.h" + +int u_drv_init(void) +{ + msg_tag_t tag; + u_sleep_init(); + + tag = mm_align_alloc(MM_PROT, (void *)0x40000000, 0x50000000 - 0x40000000); + if (msg_tag_get_val(tag) < 0) + { + return msg_tag_get_val(tag); + } + return 0; +} diff --git a/mkrtos_user/lib/sys_util/src/u_hd_man.c b/mkrtos_user/lib/sys_util/src/u_hd_man.c index d60c584b7..04f15c858 100644 --- a/mkrtos_user/lib/sys_util/src/u_hd_man.c +++ b/mkrtos_user/lib/sys_util/src/u_hd_man.c @@ -7,9 +7,9 @@ #include #define HANDLER_START_INX 10 //!< fd开始的值,前10个内核保留 -#define HANDLER_MAX_NR 64 //!< 单个task最大支持的hd数量 +#define HANDLER_MAX_NR 96 //!< 单个task最大支持的hd数量 -static umword_t bitmap_handler_alloc[HANDLER_MAX_NR / WORD_BYTES]; +static umword_t bitmap_handler_alloc[HANDLER_MAX_NR / WORD_BITS]; static pthread_spinlock_t lock; void hanlder_pre_alloc(obj_handler_t inx) @@ -18,7 +18,7 @@ void hanlder_pre_alloc(obj_handler_t inx) umword_t word_offset = inx / WORD_BITS; umword_t bits_offset = inx % WORD_BITS; - if (word_offset >= (HANDLER_MAX_NR / WORD_BYTES)) + if (word_offset >= (HANDLER_MAX_NR / WORD_BITS)) { return; } @@ -62,7 +62,7 @@ void handler_free(obj_handler_t hd_inx) umword_t word_offset = hd_inx / WORD_BITS; umword_t bits_offset = hd_inx % WORD_BITS; - if (word_offset >= (HANDLER_MAX_NR / WORD_BYTES)) + if (word_offset >= (HANDLER_MAX_NR / WORD_BITS)) { return; } diff --git a/mkrtos_user/lib/sys_util/src/u_local_thread.c b/mkrtos_user/lib/sys_util/src/u_local_thread.c new file mode 100644 index 000000000..91cdd5db6 --- /dev/null +++ b/mkrtos_user/lib/sys_util/src/u_local_thread.c @@ -0,0 +1,47 @@ +#include "u_log.h" +#include "u_prot.h" +#include "u_mm.h" +#include "u_factory.h" +#include "u_thread.h" +#include "u_task.h" +#include "u_ipc.h" +#include "u_hd_man.h" +#include + +int thread_create(int prio, void *(*fn)(void *arg), umword_t stack_top, obj_handler_t *ret_hd) +{ + obj_handler_t th1_hd; + th1_hd = handler_alloc(); + if (th1_hd == HANDLER_INVALID) + { + return -ENOMEM; + } + msg_tag_t tag = factory_create_thread(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, th1_hd)); + if (msg_tag_get_prot(tag) < 0) + { + return msg_tag_get_prot(tag); + } + tag = thread_exec_regs(th1_hd, (umword_t)fn, stack_top, RAM_BASE(), 0); + if (msg_tag_get_prot(tag) < 0) + { + handler_free_umap(th1_hd); + return msg_tag_get_prot(tag); + } + tag = thread_bind_task(th1_hd, TASK_THIS); + if (msg_tag_get_prot(tag) < 0) + { + handler_free_umap(th1_hd); + return msg_tag_get_prot(tag); + } + tag = thread_run(th1_hd, prio); + if (msg_tag_get_prot(tag) < 0) + { + handler_free_umap(th1_hd); + return msg_tag_get_prot(tag); + } + if (ret_hd) + { + *ret_hd = th1_hd; + } + return 0; +} diff --git a/mkrtos_user/lib/sys_util/src/u_sleep.c b/mkrtos_user/lib/sys_util/src/u_sleep.c index 7c7c21f56..69f19122e 100644 --- a/mkrtos_user/lib/sys_util/src/u_sleep.c +++ b/mkrtos_user/lib/sys_util/src/u_sleep.c @@ -7,11 +7,15 @@ #include "u_factory.h" #include #include -static obj_handler_t hd; +static obj_handler_t hd = HANDLER_INVALID; void u_sleep_init(void) { msg_tag_t tag; + if (hd != HANDLER_INVALID) + { + return; + } hd = handler_alloc(); assert(hd != HANDLER_INVALID); tag = factory_create_ipc(FACTORY_PROT, vpage_create_raw3(KOBJ_ALL_RIGHTS, 0, hd)); diff --git a/mkrtos_user/server/app/CMakeLists.txt b/mkrtos_user/server/app/CMakeLists.txt index a1913aadc..8bc4dbda3 100644 --- a/mkrtos_user/server/app/CMakeLists.txt +++ b/mkrtos_user/server/app/CMakeLists.txt @@ -16,6 +16,7 @@ target_link_libraries(app.elf sys sys_util sys_svr + stm32f1_bsp ${GCC_LIB_PATH}/libgcc.a ) target_include_directories( @@ -35,8 +36,10 @@ target_include_directories( ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/obj/include ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/include - ${CMAKE_SOURCE_DIR}/mkrtos_user/server/app/bsp/core_inc - ${CMAKE_SOURCE_DIR}/mkrtos_user/server/app/bsp/inc + ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/stm32f1_bsp/inc + ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/stm32f1_bsp/core_inc + ${CMAKE_SOURCE_DIR}/mkrtos_user/server/app/hmi_lcd + ${CMAKE_SOURCE_DIR}/mkrtos_user/server/app/util ) add_dependencies(app.elf muslc diff --git a/mkrtos_user/server/app/drv/adc.c b/mkrtos_user/server/app/drv/adc.c new file mode 100644 index 000000000..a2693c143 --- /dev/null +++ b/mkrtos_user/server/app/drv/adc.c @@ -0,0 +1,80 @@ + +#include "adc.h" + +#define ADC1_DR_Address ((uint32_t)0x4001244C) +__IO uint16_t ADCConvertedValue[6]; + +void adc_init(void) +{ + ADC_InitTypeDef ADC_InitStructure; + DMA_InitTypeDef DMA_InitStructure; + GPIO_InitTypeDef GPIO_InitStructure; + /* Enable DMA1 clock */ + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); + + /* Enable ADC1 and GPIOC clock */ + RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; + GPIO_Init(GPIOB, &GPIO_InitStructure); + /* DMA1 channel1 configuration ----------------------------------------------*/ + DMA_DeInit(DMA1_Channel1); + DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; + DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADCConvertedValue; + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; + DMA_InitStructure.DMA_BufferSize = 4; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; + DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; + DMA_Init(DMA1_Channel1, &DMA_InitStructure); + + /* Enable DMA1 channel1 */ + DMA_Cmd(DMA1_Channel1, ENABLE); + + /* ADC1 configuration ------------------------------------------------------*/ + ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; + ADC_InitStructure.ADC_ScanConvMode = ENABLE; + ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; + ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; + ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; + ADC_InitStructure.ADC_NbrOfChannel = 4; + ADC_Init(ADC1, &ADC_InitStructure); + + /* ADC1 regular channels configuration */ + ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5); + ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_239Cycles5); + ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 3, ADC_SampleTime_239Cycles5); + ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 4, ADC_SampleTime_239Cycles5); + // ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 5, ADC_SampleTime_239Cycles5); + // ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 6, ADC_SampleTime_239Cycles5); + + /* Enable ADC1 DMA */ + ADC_DMACmd(ADC1, ENABLE); + + /* Enable ADC1 */ + ADC_Cmd(ADC1, ENABLE); + + /* Enable ADC1 reset calibration register */ + ADC_ResetCalibration(ADC1); + /* Check the end of ADC1 reset calibration register */ + while (ADC_GetResetCalibrationStatus(ADC1)) + ; + + /* Start ADC1 calibration */ + ADC_StartCalibration(ADC1); + /* Check the end of ADC1 calibration */ + while (ADC_GetCalibrationStatus(ADC1)) + ; + + /* Start ADC1 Software Conversion */ + ADC_SoftwareStartConvCmd(ADC1, ENABLE); +} diff --git a/mkrtos_user/server/app/drv/adc.h b/mkrtos_user/server/app/drv/adc.h new file mode 100644 index 000000000..73146ffd3 --- /dev/null +++ b/mkrtos_user/server/app/drv/adc.h @@ -0,0 +1,11 @@ +#pragma once + +#include "stm32_sys.h" + +extern __IO uint16_t ADCConvertedValue[6]; + +// 得到输出电压 mV +#define ADC_OUT_V(a) (((a) / 4096.0f * 3300) * 2) + +void adc_init(void); + diff --git a/mkrtos_user/server/app/drv/drv.c b/mkrtos_user/server/app/drv/drv.c index e7f31fb37..0e65e8d88 100644 --- a/mkrtos_user/server/app/drv/drv.c +++ b/mkrtos_user/server/app/drv/drv.c @@ -3,22 +3,34 @@ #include "u_prot.h" #include "u_mm.h" #include "u_sleep.h" +#include "u_drv.h" + #include "led.h" #include "relay.h" #include "soft_iic.h" #include "spl06.h" +#include "adc.h" +#include "usart3.h" +#include "usart2.h" +#include "uart4.h" +#include "uart5.h" +#include "input_ck.h" +#include "wk2xx_hw.h" #include void drv_init(void) { - msg_tag_t tag; - u_sleep_init(); - - tag = mm_align_alloc(MM_PROT, (void *)0x40000000, 0x50000000 - 0x40000000); - assert(msg_tag_get_val(tag) >= 0); - + u_drv_init(); led_init(); relay_init(); IIC_Init(); + adc_init(); + init_usart3(115200); + init_usart2(115200); + init_uart4(115200); + init_uart5(115200); + ext_input_check(); + wk2xx_hw_init(); + spl0601_init(); } diff --git a/mkrtos_user/server/app/drv/input_ck.c b/mkrtos_user/server/app/drv/input_ck.c new file mode 100644 index 000000000..91d102be1 --- /dev/null +++ b/mkrtos_user/server/app/drv/input_ck.c @@ -0,0 +1,18 @@ + +#include "input_ck.h" +#include "stm32_sys.h" +void ext_input_check(void) +{ + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE); + PWR_BackupAccessCmd(ENABLE); /* 允许修改RTC和后备寄存器*/ + RCC_LSEConfig(RCC_LSE_OFF); /* 关闭外部低速时钟,PC14+PC15可以用作普通IO*/ + BKP_TamperPinCmd(DISABLE); /* 关闭入侵检测功能,PC13可以用作普通IO*/ + + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_Init(GPIOC, &GPIO_InitStructure); + + PWR_BackupAccessCmd(DISABLE); /* 禁止修改RTC和后备寄存器*/ +} diff --git a/mkrtos_user/server/app/drv/input_ck.h b/mkrtos_user/server/app/drv/input_ck.h new file mode 100644 index 000000000..3d516a155 --- /dev/null +++ b/mkrtos_user/server/app/drv/input_ck.h @@ -0,0 +1,2 @@ + +void ext_input_check(void); diff --git a/mkrtos_user/server/app/drv/spi2.c b/mkrtos_user/server/app/drv/spi2.c new file mode 100644 index 000000000..20fa9d0c5 --- /dev/null +++ b/mkrtos_user/server/app/drv/spi2.c @@ -0,0 +1,82 @@ +#include "spi2.h" +#include "stm32_sys.h" +// 以下是SPI模块的初始化代码,配置成主机模式,访问SD Card/W25Q64/NRF24L01 +// SPI口初始化 +// 这里针是对SPI2的初始化 +u8 SPI2_ReadWriteByte(u8 TxData); +void SPI2_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + SPI_InitTypeDef SPI_InitStructure; + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // PORTB时钟使能 + RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); // SPI3时钟使能 + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); + GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // PB3/4/5复用推挽输出 + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(GPIOB, &GPIO_InitStructure); // 初始化GPIOB + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // PB3/4/5复用推挽输出 + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(GPIOB, &GPIO_InitStructure); // 初始化GPIOB + + GPIO_SetBits(GPIOB, GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15); // PB3/4/5上拉 + + SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // 设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工 + SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // 设置SPI工作模式:设置为主SPI + SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // 设置SPI的数据大小:SPI发送接收8位帧结构 + SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // 串行同步时钟的空闲状态为高电平 + SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // 串行同步时钟的第二个跳变沿(上升或下降)数据被采样 + SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制 + SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; // 定义波特率预分频的值:波特率预分频值为256 + SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // 指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 + SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC值计算的多项式 + SPI_Init(SPI2, &SPI_InitStructure); // 根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器 + + SPI_Cmd(SPI2, ENABLE); // 使能SPI外设 + + SPI2_ReadWriteByte(0xff); // 启动传输 +} +// SPI 速度设置函数 +// SpeedSet: +// SPI_BaudRatePrescaler_2 2分频 +// SPI_BaudRatePrescaler_8 8分频 +// SPI_BaudRatePrescaler_16 16分频 +// SPI_BaudRatePrescaler_256 256分频 + +void SPI2_SetSpeed(u8 SPI_BaudRatePrescaler) +{ + // assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler)); + SPI2->CR1 &= 0XFFC7; + SPI2->CR1 |= SPI_BaudRatePrescaler; // 设置SPI2速度 + SPI_Cmd(SPI2, ENABLE); +} + +// SPIx 读写一个字节 +// TxData:要写入的字节 +// 返回值:读取到的字节 +u8 SPI2_ReadWriteByte(u8 TxData) +{ + u8 retry = 0; + while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) // 检查指定的SPI标志位设置与否:发送缓存空标志位 + { + retry++; + if (retry > 200) + return 0; + } + SPI_I2S_SendData(SPI2, TxData); // 通过外设SPIx发送一个数据 + retry = 0; + + while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) // 检查指定的SPI标志位设置与否:接受缓存非空标志位 + { + retry++; + if (retry > 200) + return 0; + } + return SPI_I2S_ReceiveData(SPI2); // 返回通过SPIx最近接收的数据 +} diff --git a/mkrtos_user/server/app/drv/spi2.h b/mkrtos_user/server/app/drv/spi2.h new file mode 100644 index 000000000..cd2b88669 --- /dev/null +++ b/mkrtos_user/server/app/drv/spi2.h @@ -0,0 +1,9 @@ +#pragma once +#include "stm32_sys.h" + +#define SPI_CS_L() GPIO_ResetBits(GPIOB, GPIO_Pin_3) +#define SPI_CS_H() GPIO_SetBits(GPIOB, GPIO_Pin_3) + +void SPI2_Init(void); // 初始化SPI口 +void SPI2_SetSpeed(u8 SpeedSet); // 设置SPI速度 +u8 SPI2_ReadWriteByte(u8 TxData); // SPI总线读写一个字节 diff --git a/mkrtos_user/server/app/drv/sysinfo.c b/mkrtos_user/server/app/drv/sysinfo.c index b47ef7394..ff0a2b66b 100644 --- a/mkrtos_user/server/app/drv/sysinfo.c +++ b/mkrtos_user/server/app/drv/sysinfo.c @@ -1,6 +1,12 @@ #include "sysinfo.h" + +#include "fs_cli.h" +#include +#include +#include +#include #include -sys_info_t sys_info = {0}; +uapp_sys_info_t sys_info = {0}; static pthread_spinlock_t lock; @@ -12,3 +18,42 @@ void sys_info_unlock(void) { pthread_spin_unlock(&lock); } + +int sys_info_save(void) +{ + int fd = fs_open("/sys_info.bin", O_CREAT | O_RDONLY, 0777); + if (fd < 0) + { + return fd; + } + sys_info_lock(); + int wlen = fs_write(fd, &sys_info, sizeof(sys_info)); + if (wlen != sizeof(sys_info)) + { + sys_info_unlock(); + fs_close(fd); + return -1; + } + sys_info_unlock(); + fs_close(fd); + return 0; +} +int sys_info_read(void) +{ + int fd = fs_open("/sys_info.bin", O_CREAT | O_WRONLY, 0777); + if (fd < 0) + { + return fd; + } + sys_info_lock(); + int wlen = fs_read(fd, &sys_info, sizeof(sys_info)); + if (wlen != sizeof(sys_info)) + { + sys_info_unlock(); + fs_close(fd); + return -1; + } + sys_info_unlock(); + fs_close(fd); + return 0; +} diff --git a/mkrtos_user/server/app/drv/sysinfo.h b/mkrtos_user/server/app/drv/sysinfo.h index 17353c171..685ce22ff 100644 --- a/mkrtos_user/server/app/drv/sysinfo.h +++ b/mkrtos_user/server/app/drv/sysinfo.h @@ -1,4 +1,4 @@ - +#pragma once #include "u_types.h" #define CTRL_IO_NUM 10 @@ -20,9 +20,12 @@ typedef struct uint8_t netID; uint8_t devID; -} sys_info_t; +} uapp_sys_info_t; -extern sys_info_t sys_info; +extern uapp_sys_info_t sys_info; void sys_info_lock(void); void sys_info_unlock(void); + +int sys_info_save(void); +int sys_info_read(void); diff --git a/mkrtos_user/server/app/drv/uart4.c b/mkrtos_user/server/app/drv/uart4.c new file mode 100644 index 000000000..5b63d73d1 --- /dev/null +++ b/mkrtos_user/server/app/drv/uart4.c @@ -0,0 +1,109 @@ + +#include "uart4.h" +#include "cmd_queue.h" +#include "u_factory.h" +#include "u_irq_sender.h" +#include "u_prot.h" +#include "u_hd_man.h" +#include "u_local_thread.h" +#include "u_sleep.h" +#include +#include +static obj_handler_t irq_obj; + +#define IRQ_THREAD_PRIO 3 +#define STACK_SIZE 512 +static __attribute__((aligned(8))) uint8_t stack0[STACK_SIZE]; + +static void *UART4_IRQHandler(void *arg); + +void init_uart4(u32 baudRate) +{ + GPIO_InitTypeDef GPIO_InitStructure = {0}; + USART_InitTypeDef USART_InitStructure = {0}; + NVIC_InitTypeDef NVIC_InitStructure = {0}; + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // 使能GPIOC时钟 + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); // 使能串口3时钟 + + USART_DeInit(UART4); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 设置PA2为复用推挽输出 + GPIO_Init(GPIOC, &GPIO_InitStructure); + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 设置PA3为浮空输入 + GPIO_Init(GPIOC, &GPIO_InitStructure); + GPIO_SetBits(GPIOC, GPIO_Pin_10); + + USART_InitStructure.USART_BaudRate = baudRate; // 设置串口波特率为115200 + USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 字长为8位数据格式 + USART_InitStructure.USART_StopBits = USART_StopBits_1; // 1个停止位 + USART_InitStructure.USART_Parity = USART_Parity_No; // 无奇偶校验位 + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件流控制 + USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // 发送和接收模式 + USART_Init(UART4, &USART_InitStructure); // 初始化串口 + + // NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn; + // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级为1 + // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 子优先级为1 + // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能 + // NVIC_Init(&NVIC_InitStructure); // 中断优先级初始化 + + USART_Cmd(UART4, ENABLE); // 使能串口 + USART_ITConfig(UART4, USART_IT_RXNE, ENABLE); // 开启中断 + USART_ClearITPendingBit(UART4, USART_IT_RXNE); + + irq_obj = handler_alloc(); + assert(irq_obj != HANDLER_INVALID); + msg_tag_t tag = factory_create_irq_sender(FACTORY_PROT, vpage_create_raw3(0, 0, irq_obj)); + assert(msg_tag_get_val(tag) >= 0); + uirq_bind(irq_obj, UART4_IRQn, (1 << 16) | 1); + + int ret = thread_create(IRQ_THREAD_PRIO, UART4_IRQHandler, (umword_t)(stack0 + STACK_SIZE), NULL); + assert(ret >= 0); +} +static void *UART4_IRQHandler(void *arg) +{ + while (1) + { + msg_tag_t tag = uirq_wait(irq_obj, 0); + if (msg_tag_get_val(tag) >= 0) + { + if (USART_GetITStatus(UART4, USART_IT_RXNE) != RESET) + { + USART_ClearITPendingBit(UART4, USART_IT_RXNE); // 清除中断标志 + uint8_t data = USART_ReceiveData(UART4); + // queue_push(data); + // uart4_send_byte(data); + } + uirq_ack(irq_obj, UART4_IRQn); + } + // u_sleep_ms(1); + } + return NULL; +} +void uart4_send_byte(u8 byte) +{ + while (USART_GetFlagStatus(UART4, USART_FLAG_TXE) == RESET) + ; + USART_SendData(UART4, byte); + while (USART_GetFlagStatus(UART4, USART_FLAG_TXE) == RESET) + ; +} +void uart4_send_bytes(u8 *bytes, int len) +{ + int i; + for (i = 0; i < len; i++) + { + uart4_send_byte(bytes[i]); + } +} +void uart4_send_string(char *string) +{ + while (*string) + { + uart4_send_byte(*string++); + } +} diff --git a/mkrtos_user/server/app/drv/uart4.h b/mkrtos_user/server/app/drv/uart4.h new file mode 100644 index 000000000..773d4f7dd --- /dev/null +++ b/mkrtos_user/server/app/drv/uart4.h @@ -0,0 +1,7 @@ +#pragma once + +#include "stm32_sys.h" +void init_uart4(u32 baudRate); +void uart4_send_string(char *string); +void uart4_send_bytes(u8 *bytes, int len); +void uart4_send_byte(u8 byte); diff --git a/mkrtos_user/server/app/drv/uart5.c b/mkrtos_user/server/app/drv/uart5.c new file mode 100644 index 000000000..adbe04e79 --- /dev/null +++ b/mkrtos_user/server/app/drv/uart5.c @@ -0,0 +1,109 @@ + +#include "uart5.h" +#include "cmd_queue.h" +#include "u_factory.h" +#include "u_irq_sender.h" +#include "u_prot.h" +#include "u_hd_man.h" +#include "u_local_thread.h" +#include "u_sleep.h" +#include +#include +static obj_handler_t irq_obj; + +#define IRQ_THREAD_PRIO 3 +#define STACK_SIZE 512 +static __attribute__((aligned(8))) uint8_t stack0[STACK_SIZE]; + +static void *UART5_IRQHandler(void *arg); + +void init_uart5(u32 baudRate) +{ + GPIO_InitTypeDef GPIO_InitStructure = {0}; + USART_InitTypeDef USART_InitStructure = {0}; + NVIC_InitTypeDef NVIC_InitStructure = {0}; + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // 使能GPIOC时钟 + RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE); // 使能串口3时钟 + + USART_DeInit(UART5); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 设置PA2为复用推挽输出 + GPIO_Init(GPIOC, &GPIO_InitStructure); + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 设置PA3为浮空输入 + GPIO_Init(GPIOC, &GPIO_InitStructure); + GPIO_SetBits(GPIOC, GPIO_Pin_10); + + USART_InitStructure.USART_BaudRate = baudRate; // 设置串口波特率为115200 + USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 字长为8位数据格式 + USART_InitStructure.USART_StopBits = USART_StopBits_1; // 1个停止位 + USART_InitStructure.USART_Parity = USART_Parity_No; // 无奇偶校验位 + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件流控制 + USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // 发送和接收模式 + USART_Init(UART5, &USART_InitStructure); // 初始化串口 + + // NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn; + // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级为1 + // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 子优先级为1 + // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能 + // NVIC_Init(&NVIC_InitStructure); // 中断优先级初始化 + + USART_Cmd(UART5, ENABLE); // 使能串口 + USART_ITConfig(UART5, USART_IT_RXNE, ENABLE); // 开启中断 + USART_ClearITPendingBit(UART5, USART_IT_RXNE); + + irq_obj = handler_alloc(); + assert(irq_obj != HANDLER_INVALID); + msg_tag_t tag = factory_create_irq_sender(FACTORY_PROT, vpage_create_raw3(0, 0, irq_obj)); + assert(msg_tag_get_val(tag) >= 0); + uirq_bind(irq_obj, UART5_IRQn, (1 << 16) | 1); + + int ret = thread_create(IRQ_THREAD_PRIO, UART5_IRQHandler, (umword_t)(stack0 + STACK_SIZE), NULL); + assert(ret >= 0); +} +static void *UART5_IRQHandler(void *arg) +{ + while (1) + { + msg_tag_t tag = uirq_wait(irq_obj, 0); + if (msg_tag_get_val(tag) >= 0) + { + if (USART_GetITStatus(UART5, USART_IT_RXNE) != RESET) + { + USART_ClearITPendingBit(UART5, USART_IT_RXNE); // 清除中断标志 + uint8_t data = USART_ReceiveData(UART5); + // queue_push(data); + // uart5_send_byte(data); + } + uirq_ack(irq_obj, UART5_IRQn); + } + // u_sleep_ms(1); + } + return NULL; +} +void uart5_send_byte(u8 byte) +{ + while (USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET) + ; + USART_SendData(UART5, byte); + while (USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET) + ; +} +void uart5_send_bytes(u8 *bytes, int len) +{ + int i; + for (i = 0; i < len; i++) + { + uart5_send_byte(bytes[i]); + } +} +void uart5_send_string(char *string) +{ + while (*string) + { + uart5_send_byte(*string++); + } +} diff --git a/mkrtos_user/server/app/drv/uart5.h b/mkrtos_user/server/app/drv/uart5.h new file mode 100644 index 000000000..c4fbd6c48 --- /dev/null +++ b/mkrtos_user/server/app/drv/uart5.h @@ -0,0 +1,7 @@ +#pragma once + +#include "stm32_sys.h" +void init_uart5(u32 baudRate); +void uart5_send_string(char *string); +void uart5_send_bytes(u8 *bytes, int len); +void uart5_send_byte(u8 byte); diff --git a/mkrtos_user/server/app/drv/usart2.c b/mkrtos_user/server/app/drv/usart2.c new file mode 100644 index 000000000..b1e0c55a9 --- /dev/null +++ b/mkrtos_user/server/app/drv/usart2.c @@ -0,0 +1,166 @@ +#include "usart2.h" +#include "stm32_sys.h" +#include "u_factory.h" +#include "u_irq_sender.h" +#include "u_prot.h" +#include "u_hd_man.h" +#include "u_local_thread.h" +#include "u_sleep.h" +#include +#include + +static obj_handler_t irq_obj; + +#define IRQ_THREAD_PRIO 3 +#define STACK_SIZE 512 +static __attribute__((aligned(8))) uint8_t stack0[STACK_SIZE]; +static void *USART2_IRQHandler(void *arg); + +void init_usart2(u32 BaudRate) +{ + USART_InitTypeDef USART_InitStructure; + GPIO_InitTypeDef GPIO_InitStructure; + NVIC_InitTypeDef NVIC_InitStruct; + /* Enable GPIO clock */ + RCC_APB2PeriphClockCmd( + RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_Init(GPIOA, &GPIO_InitStructure); + GPIO_SetBits(GPIOA, GPIO_Pin_3); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + USART_InitStructure.USART_BaudRate = BaudRate; + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_Parity = USART_Parity_No; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; + /* Configure USARTz */ + USART_Init(USART2, &USART_InitStructure); + USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); + USART_Cmd(USART2, ENABLE); + + // 设置中断优先级 + // NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn; + // NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; + // NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; + // NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2; + // NVIC_Init(&NVIC_InitStruct); + + irq_obj = handler_alloc(); + assert(irq_obj != HANDLER_INVALID); + msg_tag_t tag = factory_create_irq_sender(FACTORY_PROT, vpage_create_raw3(0, 0, irq_obj)); + assert(msg_tag_get_val(tag) >= 0); + uirq_bind(irq_obj, USART2_IRQn, (1 << 16) | 1); + + int ret = thread_create(IRQ_THREAD_PRIO, USART2_IRQHandler, (umword_t)(stack0 + STACK_SIZE), NULL); + assert(ret >= 0); +} + +void usart2_send_byte(u8 byte) +{ + while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET) + ; + USART_SendData(USART2, byte); +} +void usart2_send_bytes(u8 *bytes, int len) +{ + int i; + for (i = 0; i < len; i++) + { + usart2_send_byte(bytes[i]); + } +} +void usart2_send_string(char *string) +{ + while (*string) + { + usart2_send_byte(*string++); + } +} + +u8 usart2_data[USART2_RECV_CACHE_MAX_LEN] = {0}; +u16 usart2_count = 0; +u8 usart2_flag = 0; +u8 usart2_step = 0; +u8 usart2_over_timer = 0; + +static void *USART2_IRQHandler(void *arg) +{ + while (1) + { + msg_tag_t tag = uirq_wait(irq_obj, 0); + if (msg_tag_get_val(tag) >= 0) + { + if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) + { + uint8_t data = USART_ReceiveData(USART2); + usart2_over_timer = 0; + if (usart2_flag == 0) + { + usart2_data[usart2_count] = data; + + if (usart2_data[usart2_count] == '\r') + { + usart2_step = 1; + } + else if (usart2_data[usart2_count] == '\n') + { + usart2_step = 2; + } + else + { + usart2_step = 0; + } + usart2_count++; + if (usart2_count >= USART2_RECV_CACHE_MAX_LEN || usart2_step == 2) + { + usart2_flag = 1; // 接收完成 + usart2_loop(); + } + } + } + uirq_ack(irq_obj, USART3_IRQn); + } + } +} + +void usart2_over_time_check(void) +{ + usart2_over_timer++; + if (usart2_over_timer >= 15 && usart2_count != 0) + { + usart2_flag = 1; + usart2_over_timer = 0; + } +} + +usart_recv_data_fun usart_recv_data_cb = 0x00; + +void usart2_set_recv_data_cb(usart_recv_data_fun usart_recv_fun) +{ + usart_recv_data_cb = usart_recv_fun; +} + +void usart2_loop(void) +{ + if (usart2_flag == 1) + { + if (usart2_count > 0) + { + if (usart_recv_data_cb != 0x00) + { + usart_recv_data_cb(usart2_data, usart2_count); + } + usart2_count = 0; + usart2_flag = 0; + } + } +} diff --git a/mkrtos_user/server/app/drv/usart2.h b/mkrtos_user/server/app/drv/usart2.h new file mode 100644 index 000000000..790c28bd2 --- /dev/null +++ b/mkrtos_user/server/app/drv/usart2.h @@ -0,0 +1,17 @@ +#pragma once +#include "stm32_sys.h" + +#define USART2_RECV_CACHE_MAX_LEN 256 + +typedef void (*usart_recv_data_fun)(u8 *data, u16 len); + +void init_usart2(u32 BaudRate); +void usart2_set_recv_data_cb(usart_recv_data_fun usart_recv_fun); + +void usart2_over_time_check(void); + +void usart2_send_byte(u8 byte); +void usart2_send_bytes(u8 *bytes, int len); +void usart2_send_string(char *string); + +void usart2_loop(void); diff --git a/mkrtos_user/server/app/drv/usart3.c b/mkrtos_user/server/app/drv/usart3.c new file mode 100644 index 000000000..494144d38 --- /dev/null +++ b/mkrtos_user/server/app/drv/usart3.c @@ -0,0 +1,109 @@ + +#include "usart3.h" +#include "cmd_queue.h" +#include "u_factory.h" +#include "u_irq_sender.h" +#include "u_prot.h" +#include "u_hd_man.h" +#include "u_local_thread.h" +#include "u_sleep.h" +#include +#include +static obj_handler_t irq_obj; + +#define IRQ_THREAD_PRIO 3 +#define STACK_SIZE 512 +static __attribute__((aligned(8))) uint8_t stack0[STACK_SIZE]; + +static void *USART3_IRQHandler(void *arg); + +void init_usart3(u32 baudRate) +{ + GPIO_InitTypeDef GPIO_InitStructure = {0}; + USART_InitTypeDef USART_InitStructure = {0}; + NVIC_InitTypeDef NVIC_InitStructure = {0}; + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 使能GPIOC时钟 + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); // 使能串口3时钟 + + USART_DeInit(USART3); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 设置PA2为复用推挽输出 + GPIO_Init(GPIOB, &GPIO_InitStructure); + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 设置PA3为浮空输入 + GPIO_Init(GPIOB, &GPIO_InitStructure); + GPIO_SetBits(GPIOB, GPIO_Pin_10); + + USART_InitStructure.USART_BaudRate = baudRate; // 设置串口波特率为115200 + USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 字长为8位数据格式 + USART_InitStructure.USART_StopBits = USART_StopBits_1; // 1个停止位 + USART_InitStructure.USART_Parity = USART_Parity_No; // 无奇偶校验位 + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件流控制 + USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // 发送和接收模式 + USART_Init(USART3, &USART_InitStructure); // 初始化串口 + + // NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; + // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级为1 + // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 子优先级为1 + // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // IRQ通道使能 + // NVIC_Init(&NVIC_InitStructure); // 中断优先级初始化 + + USART_Cmd(USART3, ENABLE); // 使能串口 + USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); // 开启中断 + USART_ClearITPendingBit(USART3, USART_IT_RXNE); + + irq_obj = handler_alloc(); + assert(irq_obj != HANDLER_INVALID); + msg_tag_t tag = factory_create_irq_sender(FACTORY_PROT, vpage_create_raw3(0, 0, irq_obj)); + assert(msg_tag_get_val(tag) >= 0); + uirq_bind(irq_obj, USART3_IRQn, (1 << 16) | 1); + + int ret = thread_create(IRQ_THREAD_PRIO, USART3_IRQHandler, (umword_t)(stack0 + STACK_SIZE), NULL); + assert(ret >= 0); +} +static void *USART3_IRQHandler(void *arg) +{ + while (1) + { + msg_tag_t tag = uirq_wait(irq_obj, 0); + if (msg_tag_get_val(tag) >= 0) + { + if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) + { + USART_ClearITPendingBit(USART3, USART_IT_RXNE); // 清除中断标志 + uint8_t data = USART_ReceiveData(USART3); + queue_push(data); + usart3_send_byte(data); + } + uirq_ack(irq_obj, USART3_IRQn); + } + // u_sleep_ms(1); + } + return NULL; +} +void usart3_send_byte(u8 byte) +{ + while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET) + ; + USART_SendData(USART3, byte); + while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET) + ; +} +void usart3_send_bytes(u8 *bytes, int len) +{ + int i; + for (i = 0; i < len; i++) + { + usart3_send_byte(bytes[i]); + } +} +void usart3_send_string(char *string) +{ + while (*string) + { + usart3_send_byte(*string++); + } +} diff --git a/mkrtos_user/server/app/drv/usart3.h b/mkrtos_user/server/app/drv/usart3.h new file mode 100644 index 000000000..badedb0c4 --- /dev/null +++ b/mkrtos_user/server/app/drv/usart3.h @@ -0,0 +1,7 @@ +#pragma once + +#include "stm32_sys.h" +void init_usart3(u32 baudRate); +void usart3_send_string(char *string); +void usart3_send_bytes(u8 *bytes, int len); +void usart3_send_byte(u8 byte); diff --git a/mkrtos_user/server/app/drv/wk2xx.h b/mkrtos_user/server/app/drv/wk2xx.h new file mode 100644 index 000000000..3f64fc2fc --- /dev/null +++ b/mkrtos_user/server/app/drv/wk2xx.h @@ -0,0 +1,162 @@ +#pragma once +#include "stm32_sys.h" + +// 定义函数 + +// #define TPT_UART3_Enable() USART_ITConfig(USART3,USART_IT_RXNE,ENABLE); +// #define TPT_UART3_Disable() USART_ITConfig(USART3,USART_IT_RXNE,DISABLE); + +#define WK2XXX_GENA 0X00 +#define WK2XXX_GRST 0X01 +#define WK2XXX_GMUT 0X02 +#define WK2XXX_GIER 0X10 +#define WK2XXX_GIFR 0X11 +#define WK2XXX_GPDIR 0X21 +#define WK2XXX_GPDAT 0X31 +// wkxxxx slave uarts rigister address defines + +#define WK2XXX_SPAGE 0X03 +// PAGE0 +#define WK2XXX_SCR 0X04 +#define WK2XXX_LCR 0X05 +#define WK2XXX_FCR 0X06 +#define WK2XXX_SIER 0X07 +#define WK2XXX_SIFR 0X08 +#define WK2XXX_TFCNT 0X09 +#define WK2XXX_RFCNT 0X0A +#define WK2XXX_FSR 0X0B +#define WK2XXX_LSR 0X0C +#define WK2XXX_FDAT 0X0D +#define WK2XXX_FWCR 0X0E +#define WK2XXX_RS485 0X0F +// PAGE1 +#define WK2XXX_BAUD1 0X04 +#define WK2XXX_BAUD0 0X05 +#define WK2XXX_PRES 0X06 +#define WK2XXX_RFTL 0X07 +#define WK2XXX_TFTL 0X08 +#define WK2XXX_FWTH 0X09 +#define WK2XXX_FWTL 0X0A +#define WK2XXX_XON1 0X0B +#define WK2XXX_XOFF1 0X0C +#define WK2XXX_SADR 0X0D +#define WK2XXX_SAEN 0X0E +#define WK2XXX_RTSDLY 0X0F + +// WK串口扩展芯片的寄存器的位定义 +// wkxxx register bit defines +// GENA +#define WK2XXX_UT4EN 0x08 +#define WK2XXX_UT3EN 0x04 +#define WK2XXX_UT2EN 0x02 +#define WK2XXX_UT1EN 0x01 +// GRST +#define WK2XXX_UT4SLEEP 0x80 +#define WK2XXX_UT3SLEEP 0x40 +#define WK2XXX_UT2SLEEP 0x20 +#define WK2XXX_UT1SLEEP 0x10 +#define WK2XXX_UT4RST 0x08 +#define WK2XXX_UT3RST 0x04 +#define WK2XXX_UT2RST 0x02 +#define WK2XXX_UT1RST 0x01 +// GIER +#define WK2XXX_UT4IE 0x08 +#define WK2XXX_UT3IE 0x04 +#define WK2XXX_UT2IE 0x02 +#define WK2XXX_UT1IE 0x01 +// GIFR +#define WK2XXX_UT4INT 0x08 +#define WK2XXX_UT3INT 0x04 +#define WK2XXX_UT2INT 0x02 +#define WK2XXX_UT1INT 0x01 +// SPAGE +#define WK2XXX_SPAGE0 0x00 +#define WK2XXX_SPAGE1 0x01 +// SCR +#define WK2XXX_SLEEPEN 0x04 +#define WK2XXX_TXEN 0x02 +#define WK2XXX_RXEN 0x01 +// LCR +#define WK2XXX_BREAK 0x20 +#define WK2XXX_IREN 0x10 +#define WK2XXX_PAEN 0x08 +#define WK2XXX_PAM1 0x04 +#define WK2XXX_PAM0 0x02 +#define WK2XXX_STPL 0x01 +// FCR +// SIER +#define WK2XXX_FERR_IEN 0x80 +#define WK2XXX_CTS_IEN 0x40 +#define WK2XXX_RTS_IEN 0x20 +#define WK2XXX_XOFF_IEN 0x10 +#define WK2XXX_TFEMPTY_IEN 0x08 +#define WK2XXX_TFTRIG_IEN 0x04 +#define WK2XXX_RXOUT_IEN 0x02 +#define WK2XXX_RFTRIG_IEN 0x01 +// SIFR +#define WK2XXX_FERR_INT 0x80 +#define WK2XXX_CTS_INT 0x40 +#define WK2XXX_RTS_INT 0x20 +#define WK2XXX_XOFF_INT 0x10 +#define WK2XXX_TFEMPTY_INT 0x08 +#define WK2XXX_TFTRIG_INT 0x04 +#define WK2XXX_RXOVT_INT 0x02 +#define WK2XXX_RFTRIG_INT 0x01 + +// TFCNT +// RFCNT +// FSR +#define WK2XXX_RFOE 0x80 +#define WK2XXX_RFBI 0x40 +#define WK2XXX_RFFE 0x20 +#define WK2XXX_RFPE 0x10 +#define WK2XXX_RDAT 0x08 +#define WK2XXX_TDAT 0x04 +#define WK2XXX_TFULL 0x02 +#define WK2XXX_TBUSY 0x01 +// LSR +#define WK2XXX_OE 0x08 +#define WK2XXX_BI 0x04 +#define WK2XXX_FE 0x02 +#define WK2XXX_PE 0x01 +// FWCR +// RS485 +// 常用波特率宏定义 +enum WKBaud +{ + B600, + B1200, + B2400, + B4800, + B9600, + B19200, + B38400, + B76800, + B1800, + B3600, + B7200, + B14400, + B28800, + B57600, + B115200, + B230400 +}; + +/////函数部分 +void WK_RstInit(void); +void WkWriteGReg(unsigned char greg, unsigned char dat); +u8 WkReadGReg(unsigned char greg); +void WkWriteSReg(u8 port, u8 sreg, u8 dat); +u8 WkReadSReg(u8 port, u8 sreg); +void WkWriteSFifo(u8 port, u8 *dat, int num); +void WkReadSFifo(u8 port, u8 *rec, int num); + +void Wk_Init(u8 port); +void Wk_DeInit(u8 port); +void Wk_SetBaud(u8 port, enum WKBaud baud); +int wk_TxChars(u8 port, int len, u8 *sendbuf); +int wk_TxLen(u8 port); +int wk_RxChars(u8 port, u8 *recbuf); +void WK_RS485(u8 port); +void WK_RTSCTS(u8 port); +void wk_wait_tx_done(int inx); diff --git a/mkrtos_user/server/app/drv/wk2xx_hw.c b/mkrtos_user/server/app/drv/wk2xx_hw.c new file mode 100644 index 000000000..f979f3ad4 --- /dev/null +++ b/mkrtos_user/server/app/drv/wk2xx_hw.c @@ -0,0 +1,114 @@ +#include "u_factory.h" +#include "u_irq_sender.h" +#include "u_prot.h" +#include "u_hd_man.h" +#include "u_local_thread.h" +#include "u_sleep.h" + +#include "wk2xx_hw.h" +#include "spi2.h" +#include "delay.h" +#include "wk2xx.h" +#include +// #include "MDM_RTU_Serial.h" +static obj_handler_t irq_obj; + +#define IRQ_THREAD_PRIO 3 +#define STACK_SIZE 512 +static __attribute__((aligned(8))) uint8_t stack0[STACK_SIZE]; +static void *exti_12_irq(void *arg); + +void wk2xx_hw_init(void) +{ + EXTI_InitTypeDef EXTI_InitStructure; + NVIC_InitTypeDef NVIC_InitStructure; + GPIO_InitTypeDef GPIO_InitStructure; + SPI2_Init(); + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + GPIO_ResetBits(GPIOB, GPIO_Pin_6); + delay_us(100); + GPIO_SetBits(GPIOB, GPIO_Pin_6); + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource12); + + EXTI_InitStructure.EXTI_Line = EXTI_Line12; + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; + EXTI_InitStructure.EXTI_LineCmd = ENABLE; + EXTI_Init(&EXTI_InitStructure); + + // NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; + // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00; + // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; + // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + // NVIC_Init(&NVIC_InitStructure); + irq_obj = handler_alloc(); + assert(irq_obj != HANDLER_INVALID); + msg_tag_t tag = factory_create_irq_sender(FACTORY_PROT, vpage_create_raw3(0, 0, irq_obj)); + assert(msg_tag_get_val(tag) >= 0); + uirq_bind(irq_obj, EXTI15_10_IRQn, (0 << 16) | 1); + + int ret = thread_create(IRQ_THREAD_PRIO, exti_12_irq, (umword_t)(stack0 + STACK_SIZE), NULL); + assert(ret >= 0); +} +u8 wk_recv_buf[4][256] = {0}; +static void *exti_12_irq(void *arg) +{ + while (1) + { + msg_tag_t tag = uirq_wait(irq_obj, 0); + if (msg_tag_get_val(tag) >= 0) + { + int recv_len = 0; + if (EXTI_GetFlagStatus(EXTI_Line12) != RESET) + { + if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12) == 0) + { + u8 intr_reg = WkReadGReg(WK2XXX_GIFR) & 0xf; + + // 获取那个设备产生的中断 + switch (intr_reg) + { + case WK2XXX_UT1IE: + recv_len = wk_RxChars(1, wk_recv_buf[0]); + break; + case WK2XXX_UT2IE: + // 485 + recv_len = wk_RxChars(2, wk_recv_buf[1]); + for (int i = 0; i < recv_len; i++) + { + // MDMSerialRecvByte(wk_recv_buf[1][i]);TODO: + } + break; + case WK2XXX_UT3IE: + recv_len = wk_RxChars(3, wk_recv_buf[2]); + break; + case WK2XXX_UT4IE: + // 485 + recv_len = wk_RxChars(4, wk_recv_buf[3]); + for (int i = 0; i < recv_len; i++) + { + // MDMSerialRecvByte(wk_recv_buf[3][i]);TODO: + } + break; + } + } + // 清除中断位 + EXTI_ClearITPendingBit(EXTI_Line12); + } + uirq_ack(irq_obj, EXTI15_10_IRQn); + } + } +} diff --git a/mkrtos_user/server/app/drv/wk2xx_hw.h b/mkrtos_user/server/app/drv/wk2xx_hw.h new file mode 100644 index 000000000..3c5184a8d --- /dev/null +++ b/mkrtos_user/server/app/drv/wk2xx_hw.h @@ -0,0 +1,7 @@ +#ifndef _WK2XX_HW_H__ +#define _WK2XX_HW_H__ + +#include "wk2xx.h" +void wk2xx_hw_init(void); + +#endif diff --git a/mkrtos_user/server/app/drv/wk2xx_spi.c b/mkrtos_user/server/app/drv/wk2xx_spi.c new file mode 100644 index 000000000..bff28370c --- /dev/null +++ b/mkrtos_user/server/app/drv/wk2xx_spi.c @@ -0,0 +1,384 @@ +#include "wk2xx.h" +#include "delay.h" +#include "spi2.h" + +/***************************WkWriteGReg***********************************/ +// 函数功能:写全局寄存器函数(前提是该寄存器可写, +// 某些寄存器如果你写1,可能会自动置1,具体见数据手册) +// 参数: +// greg:为全局寄存器的地址 +// dat:为写入寄存器的数据 +//***********************************************************************/ +void WkWriteGReg(unsigned char greg, unsigned char dat) +{ + u8 cmd; + cmd = 0 | greg; + SPI_CS_L(); // 拉低cs信号 + SPI2_ReadWriteByte(cmd); // 写指令,对于指令的构成见数据手册 + SPI2_ReadWriteByte(dat); // 写数据 + SPI_CS_H(); // 拉高cs信号 +} +/****************************WkReadGReg***********************************/ +// 函数功能:读全局寄存器 +// 参数: +// greg:为全局寄存器的地址 +// rec:返回的寄存器值 +//***********************************************************************/ +u8 WkReadGReg(unsigned char greg) +{ + u8 cmd, rec; + cmd = 0x40 | greg; + SPI_CS_L(); // 拉低cs信号 + SPI2_ReadWriteByte(cmd); // 写指令,对于指令的构成见数据手册 + rec = SPI2_ReadWriteByte(0); // 写数据 + SPI_CS_H(); // 拉高cs信号 + return rec; +} + +/**************************WkWriteSReg***********************************/ +// 函数功能: +// 参数:port:为子串口 +// sreg:为子串口寄存器 +// dat:为写入寄存器的数据 +// 注意:在子串口被打通的情况下,向FDAT写入的数据会通过TX引脚输出 +//**********************************************************************/ +void WkWriteSReg(u8 port, u8 sreg, u8 dat) +{ + u8 cmd; + cmd = 0x0 | ((port - 1) << 4) | sreg; + SPI_CS_L(); // 拉低cs信号 + SPI2_ReadWriteByte(cmd); // 写指令,对于指令的构成见数据手册 + SPI2_ReadWriteByte(dat); // 写数据 + SPI_CS_H(); // 拉高cs信号 +} + +/**************************WkReadSReg***********************************/ +// 函数功能:读子串口寄存器 +// 参数:port为子串口端口号 +// sreg:为子串口寄存器地址 +// rec:返回的寄存器值 +//**********************************************************************/ +u8 WkReadSReg(u8 port, u8 sreg) +{ + u8 cmd, rec; + cmd = 0x40 | ((port - 1) << 4) | sreg; + SPI_CS_L(); // 拉低cs信号 + SPI2_ReadWriteByte(cmd); // 写指令,对于指令的构成见数据手册 + rec = SPI2_ReadWriteByte(0); // 写数据 + SPI_CS_H(); // 拉高cs信号 + return rec; +} +/************************WkWriteSFifo***********************************/ +// 函数功能:向子串口fifo写入需要发送的数据 +// 参数:port:为子串口 +// *dat:写入数据 +// num:为写入数据的个数,单次不超过256 +// 注意:通过该方式写入的数据,被直接写入子串口的缓存FIFO,然后被发送 +//*********************************************************************/ +void WkWriteSFifo(u8 port, u8 *dat, int num) +{ + u8 cmd; + int i; + cmd = 0x80 | ((port - 1) << 4); + if (num > 0) + { + SPI_CS_L(); // 拉低cs信号 + SPI2_ReadWriteByte(cmd); // 写指令,对于指令构成见数据手册 + for (i = 0; i < num; i++) + { + SPI2_ReadWriteByte(*(dat + i)); // 写数据 + } + SPI_CS_H(); // 拉高cs信号 + } +} + +/************************WkReadSFifo***********************************/ +// 函数功能:从子串口的fifo中读出接收到的数据 +// 参数:port:为子串口 +// *rec:接收到的数据 +// num:读出的数据个数。 +// 注意:通过该方式读出子串口缓存中的数据。单次不能超过256 +//*********************************************************************/ +void WkReadSFifo(u8 port, u8 *rec, int num) +{ + u8 cmd; + int n; + cmd = 0xc0 | ((port - 1) << 4); + if (num > 0) + { + SPI_CS_L(); // 拉低cs信号 + SPI2_ReadWriteByte(cmd); + for (n = 0; n < num; n++) + { + *(rec + n) = SPI2_ReadWriteByte(0); + } + SPI_CS_H(); // 拉高cs信号 + } +} + +void WK_ISR(void) +{ +} + +/*******WkInit*******************************************/ +// 函数功能:初始化子串口 +/*******************************************************/ +void Wk_Init(u8 port) +{ + u8 gena, grst, gier, sier, scr; + // 使能子串口时钟 + gena = WkReadGReg(WK2XXX_GENA); + gena = gena | (1 << (port - 1)); + WkWriteGReg(WK2XXX_GENA, gena); + // 软件复位子串口 + grst = WkReadGReg(WK2XXX_GRST); + grst = grst | (1 << (port - 1)); + WkWriteGReg(WK2XXX_GRST, grst); + // 使能串口总中断 + gier = WkReadGReg(WK2XXX_GIER); + gier = gier | (1 << (port - 1)); + WkWriteGReg(WK2XXX_GIER, gier); + // 使能子串口接收触点中断和超时中断 + sier = WkReadSReg(port, WK2XXX_SIER); + sier |= WK2XXX_RFTRIG_IEN | WK2XXX_RXOUT_IEN; + WkWriteSReg(port, WK2XXX_SIER, sier); + // 初始化FIFO和设置固定中断触点 + WkWriteSReg(port, WK2XXX_FCR, 0XFF); + // 设置任意中断触点,如果下面的设置有效, + // 那么上面FCR寄存器中断的固定中断触点将失效 + WkWriteSReg(port, WK2XXX_SPAGE, 1); // 切换到page1 + WkWriteSReg(port, WK2XXX_RFTL, 255); // 设置接收触点为256个字节 + WkWriteSReg(port, WK2XXX_TFTL, 255); // 设置发送触点为256个字节 + WkWriteSReg(port, WK2XXX_SPAGE, 0); // 切换到page0 + // 使能子串口的发送和接收使能 + scr = WkReadSReg(port, WK2XXX_SCR); + scr |= WK2XXX_TXEN | WK2XXX_RXEN; + WkWriteSReg(port, WK2XXX_SCR, scr); +} + +/******************************Wk_DeInit*******************************************/ +// 函数功能:初始化子串口 +/*********************************************************************************/ +void Wk_DeInit(u8 port) +{ + u8 gena, grst, gier; + // 关闭子串口总时钟 + gena = WkReadGReg(WK2XXX_GENA); + gena = gena & (~(1 << (port - 1))); + WkWriteGReg(WK2XXX_GENA, gena); + // 使能子串口总中断 + gier = WkReadGReg(WK2XXX_GIER); + gier = gier & (~(1 << (port - 1))); + WkWriteGReg(WK2XXX_GIER, gier); + // 软件复位子串口 + grst = WkReadGReg(WK2XXX_GRST); + grst = grst | (1 << (port - 1)); + WkWriteGReg(WK2XXX_GRST, grst); +} + +/**************************Wk_SetBaud*******************************************************/ +// 函数功能:设置子串口波特率函数、此函数中波特率的匹配值是根据11.0592Mhz下的外部晶振计算的 +// port:子串口号 +// baud:波特率大小.波特率表示方式, +/**************************Wk2114SetBaud*******************************************************/ +void Wk_SetBaud(u8 port, enum WKBaud baud) +{ + unsigned char baud1, baud0, pres, scr; + // 如下波特率相应的寄存器值,是在外部时钟为11.0592mhz的情况下计算所得,如果使用其他晶振,需要重新计算 + switch (baud) + { + case B600: + baud1 = 0x4; + baud0 = 0x7f; + pres = 0; + break; + case B1200: + baud1 = 0x2; + baud0 = 0x3F; + pres = 0; + break; + case B2400: + baud1 = 0x1; + baud0 = 0x1f; + pres = 0; + break; + case B4800: + baud1 = 0x00; + baud0 = 0x8f; + pres = 0; + break; + case B9600: + baud1 = 0x00; + baud0 = 0x47; + pres = 0; + break; + case B19200: + baud1 = 0x00; + baud0 = 0x23; + pres = 0; + break; + case B38400: + baud1 = 0x00; + baud0 = 0x11; + pres = 0; + break; + case B76800: + baud1 = 0x00; + baud0 = 0x08; + pres = 0; + break; + case B1800: + baud1 = 0x01; + baud0 = 0x7f; + pres = 0; + break; + case B3600: + baud1 = 0x00; + baud0 = 0xbf; + pres = 0; + break; + case B7200: + baud1 = 0x00; + baud0 = 0x5f; + pres = 0; + break; + case B14400: + baud1 = 0x00; + baud0 = 0x2f; + pres = 0; + break; + case B28800: + baud1 = 0x00; + baud0 = 0x17; + pres = 0; + break; + case B57600: + baud1 = 0x00; + baud0 = 0x0b; + pres = 0; + break; + case B115200: + baud1 = 0x00; + baud0 = 0x05; + pres = 0; + break; + case B230400: + baud1 = 0x00; + baud0 = 0x02; + pres = 0; + break; + default: + baud1 = 0x00; + baud0 = 0x00; + pres = 0; + } + // 关掉子串口收发使能 + scr = WkReadSReg(port, WK2XXX_SCR); + WkWriteSReg(port, WK2XXX_SCR, 0); + // 设置波特率相关寄存器 + WkWriteSReg(port, WK2XXX_SPAGE, 1); // 切换到page1 + WkWriteSReg(port, WK2XXX_BAUD1, baud1); + WkWriteSReg(port, WK2XXX_BAUD0, baud0); + WkWriteSReg(port, WK2XXX_PRES, pres); + WkWriteSReg(port, WK2XXX_SPAGE, 0); // 切换到page0 + // 使能子串口收发使能 + WkWriteSReg(port, WK2XXX_SCR, scr); +} +/**************************WK_TxLen*******************************************/ +// 函数功能:获取子串口发送FIFO剩余空间长度 +// port:端口号 +// 返回值:发送FIFO剩余空间长度 +/**************************WK_Len********************************************/ +int wk_TxLen(u8 port) +{ + u8 fsr, tfcnt; + int len = 0; + fsr = WkReadSReg(port, WK2XXX_FSR); + tfcnt = WkReadSReg(port, WK2XXX_TFCNT); + if (fsr & WK2XXX_TFULL) + { + len = 0; + } + else + { + len = 256 - tfcnt; + } + return len; +} + +/**************************WK_TxChars*******************************************/ +// 函数功能:通过子串口发送固定长度数据 +// port:端口号 +// len:单次发送长度不超过256 +// +/**************************WK_TxChars********************************************/ +int wk_TxChars(u8 port, int len, u8 *sendbuf) +{ + +#if 1 + WkWriteSFifo(port, sendbuf, len); // 通过fifo方式发送数据 +#else + int num = len; + for (num = 0; num < len; num++) + { + WkWriteSReg(port, WK2XXX_FDAT, *(sendbuf + num)); + } +#endif + return 0; +} + +/**************************WK_RxChars*******************************************/ +// 函数功能:读取子串口fifo中的数据 +// port:端口号 +// recbuf:接收到的数据 +// 返回值:接收数据的长度 +/**************************WK_RxChars********************************************/ +int wk_RxChars(u8 port, u8 *recbuf) +{ + u8 fsr = 0, rfcnt = 0, rfcnt2 = 0, sifr = 0; + int len = 0; + sifr = WkReadSReg(port, WK2XXX_SIFR); + + if ((sifr & WK2XXX_RFTRIG_INT) || (sifr & WK2XXX_RXOVT_INT)) // 有接收中断和接收超时中断 + { + fsr = WkReadSReg(port, WK2XXX_FSR); + rfcnt = WkReadSReg(port, WK2XXX_RFCNT); + rfcnt2 = WkReadSReg(port, WK2XXX_RFCNT); + // printf("rfcnt=0x%x.\n",rfcnt); + /*判断fifo中数据个数*/ + if (fsr & WK2XXX_RDAT) + { + if (!(rfcnt2 >= rfcnt)) + { + rfcnt = rfcnt2; + } + len = (rfcnt == 0) ? 256 : rfcnt; + } +#if 1 + WkReadSFifo(port, recbuf, len); +#else + for (n = 0; n < len; n++) + *(recbuf + n) = WkReadSReg(port, WK2XXX_FDAT); +#endif + return len; + } + else + { + len = 0; + return len; + } +} + +void wk_wait_tx_done(int inx) +{ + // 等待发送完成 + while (1) + { + u8 fsr_reg = WkReadSReg(inx, WK2XXX_FSR); + if ((fsr_reg & WK2XXX_TDAT) == 0) + { + break; + } + } + delay_ms(2); +} diff --git a/mkrtos_user/server/app/hmi_lcd/cmd_process.h b/mkrtos_user/server/app/hmi_lcd/cmd_process.h new file mode 100644 index 000000000..441b5c205 --- /dev/null +++ b/mkrtos_user/server/app/hmi_lcd/cmd_process.h @@ -0,0 +1,179 @@ + +#ifndef _CMD_PROCESS_H +#define _CMD_PROCESS_H +#include "hmi_driver.h" +#include "stm32_sys.h" + +#define NOTIFY_TOUCH_PRESS 0X01 // 触摸屏按下通知 +#define NOTIFY_TOUCH_RELEASE 0X03 // 触摸屏松开通知 +#define NOTIFY_WRITE_FLASH_OK 0X0C // 写FLASH成功 +#define NOTIFY_WRITE_FLASH_FAILD 0X0D // 写FLASH失败 +#define NOTIFY_READ_FLASH_OK 0X0B // 读FLASH成功 +#define NOTIFY_READ_FLASH_FAILD 0X0F // 读FLASH失败 +#define NOTIFY_MENU 0X14 // 菜单事件通知 +#define NOTIFY_TIMER 0X43 // 定时器超时通知 +#define NOTIFY_CONTROL 0XB1 // 控件更新通知 +#define NOTIFY_READ_RTC 0XF7 // 读取RTC时间 +#define MSG_GET_CURRENT_SCREEN 0X01 // 画面ID变化通知 +#define MSG_GET_DATA 0X11 // 控件数据通知 +#define NOTIFY_HandShake 0X55 // 握手通知 + +#define PTR2U16(PTR) ((((uint8_t *)(PTR))[0] << 8) | ((uint8_t *)(PTR))[1]) // 从缓冲区取16位数据 +#define PTR2U32(PTR) ((((uint8_t *)(PTR))[0] << 24) | (((uint8_t *)(PTR))[1] << 16) | \ + (((uint8_t *)(PTR))[2] << 8) | ((uint8_t *)(PTR))[3]) // 从缓冲区取32位数据 + +enum CtrlType +{ + kCtrlUnknown = 0x0, + kCtrlButton = 0x10, // 按钮 + kCtrlText, // 文本 + kCtrlProgress, // 进度条 + kCtrlSlider, // 滑动条 + kCtrlMeter, // 仪表 + kCtrlDropList, // 下拉列表 + kCtrlAnimation, // 动画 + kCtrlRTC, // 时间显示 + kCtrlGraph, // 曲线图控件 + kCtrlTable, // 表格控件 + kCtrlMenu, // 菜单控件 + kCtrlSelector, // 选择控件 + kCtrlQRCode, // 二维码 +}; + +#pragma pack(push) +#pragma pack(1) // 按字节对齐 + +typedef struct +{ + uint8_t cmd_head; // 帧头 + + uint8_t cmd_type; // 命令类型(UPDATE_CONTROL) + uint8_t ctrl_msg; // CtrlMsgType-指示消息的类型 + uint16_t screen_id; // 产生消息的画面ID + uint16_t control_id; // 产生消息的控件ID + uint8_t control_type; // 控件类型 + + uint8_t param[256]; // 可变长度参数,最多256个字节 + + uint8_t cmd_tail[4]; // 帧尾 +} CTRL_MSG, *PCTRL_MSG; + +#pragma pack(pop) + +/*! + * \brief 握手通知 + */ +void NOTIFYHandShake(void); + +/*! + * \brief 消息处理流程 + * \param msg 待处理消息 + * \param size 消息长度 + */ +void ProcessMessage(PCTRL_MSG msg, uint16_t size); +/*! + * \brief 画面切换通知 + * \details 当前画面改变时(或调用GetScreen),执行此函数 + * \param screen_id 当前画面ID + */ +void NotifyScreen(uint16_t screen_id); +/*! + * \brief 触摸坐标事件响应 + * \param press 1按下触摸屏,3松开触摸屏 + * \param x x坐标 + * \param y y坐标 + */ +void NotifyTouchXY(uint8_t press, uint16_t x, uint16_t y); + +/*! + * \brief 按钮控件通知 + * \details 当按钮状态改变(或调用GetControlValue)时,执行此函数 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param state 按钮状态:0弹起,1按下 + */ +void NotifyButton(uint16_t screen_id, uint16_t control_id, uint8_t state); +/*! + * \brief 文本控件通知 + * \details 当文本通过键盘更新(或调用GetControlValue)时,执行此函数 + * \details 文本控件的内容以字符串形式下发到MCU,如果文本控件内容是浮点值, + * \details 则需要在此函数中将下发字符串重新转回浮点值。 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param str 文本控件内容 + */ +void NotifyText(uint16_t screen_id, uint16_t control_id, uint8_t *str); +/*! + * \brief 进度条控件通知 + * \details 调用GetControlValue时,执行此函数 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 值 + */ +void NotifyProgress(uint16_t screen_id, uint16_t control_id, uint32_t value); +/*! + * \brief 滑动条控件通知 + * \details 当滑动条改变(或调用GetControlValue)时,执行此函数 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 值 + */ +void NotifySlider(uint16_t screen_id, uint16_t control_id, uint32_t value); +/*! + * \brief 仪表控件通知 + * \details 调用GetControlValue时,执行此函数 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 值 + */ +void NotifyMeter(uint16_t screen_id, uint16_t control_id, uint32_t value); +/*! + * \brief 菜单控件通知 + * \details 当菜单项按下或松开时,执行此函数 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param item 菜单项索引 + * \param state 按钮状态:0松开,1按下 + */ +void NotifyMenu(uint16_t screen_id, uint16_t control_id, uint8_t item, uint8_t state); + +/*! + * \brief 选择控件通知 + * \details 当选择控件变化时,执行此函数 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param item 当前选项 + */ +void NotifySelector(uint16_t screen_id, uint16_t control_id, uint8_t item); +/*! + * \brief 定时器超时通知处理 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void NotifyTimer(uint16_t screen_id, uint16_t control_id); +/*! + * \brief 读取用户FLASH状态返回 + * \param status 0失败,1成功 + * \param _data 返回数据 + * \param length 数据长度 + */ +void NotifyReadFlash(uint8_t status, uint8_t *_data, uint16_t length); + +/*! + * \brief 写用户FLASH状态返回 + * \param status 0失败,1成功 + */ +void NotifyWriteFlash(uint8_t status); +/*! + * \brief 读取RTC时间,注意返回的是BCD码 + * \param year 年(BCD) + * \param month 月(BCD) + * \param week 星期(BCD) + * \param day 日(BCD) + * \param hour 时(BCD) + * \param minute 分(BCD) + * \param second 秒(BCD) + */ +void NotifyReadRTC(uint8_t year, uint8_t month, uint8_t week, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second); + +#endif diff --git a/mkrtos_user/server/app/hmi_lcd/cmd_queue.c b/mkrtos_user/server/app/hmi_lcd/cmd_queue.c new file mode 100644 index 000000000..4f0f3d077 --- /dev/null +++ b/mkrtos_user/server/app/hmi_lcd/cmd_queue.c @@ -0,0 +1,101 @@ + +#include "cmd_queue.h" + +#define CMD_HEAD 0XEE // 帧头 +#define CMD_TAIL 0XFFFCFFFF // 帧尾 + +typedef struct _QUEUE +{ + qsize _head; // 队列头 + qsize _tail; // 队列尾 + qdata _data[QUEUE_MAX_SIZE]; // 队列数据缓存区 +} QUEUE; + +static QUEUE que = {0, 0, 0}; // 指令队列 +static uint32_t cmd_state = 0; // 队列帧尾检测状态 +static qsize cmd_pos = 0; // 当前指令指针位置 + +/*! + * \brief 清空指令数据 + */ +void queue_reset() +{ + que._head = que._tail = 0; + cmd_pos = cmd_state = 0; +} +/*! + * \brief 添加指令数据 + * \detial 串口接收的数据,通过此函数放入指令队列 + * \param _data 指令数据 + */ +void queue_push(qdata _data) +{ + qsize pos = (que._head + 1) % QUEUE_MAX_SIZE; + if (pos != que._tail) // 非满状态 + { + que._data[que._head] = _data; + que._head = pos; + } +} + +// 从队列中取一个数据 +static void queue_pop(qdata *_data) +{ + if (que._tail != que._head) // 非空状态 + { + *_data = que._data[que._tail]; + que._tail = (que._tail + 1) % QUEUE_MAX_SIZE; + } +} + +// 获取队列中有效数据个数 +static qsize queue_size() +{ + return ((que._head + QUEUE_MAX_SIZE - que._tail) % QUEUE_MAX_SIZE); +} +/*! + * \brief 从指令队列中取出一条完整的指令 + * \param cmd 指令接收缓存区 + * \param buf_len 指令接收缓存区大小 + * \return 指令长度,0表示队列中无完整指令 + */ +qsize queue_find_cmd(qdata *buffer, qsize buf_len) +{ + qsize cmd_size = 0; + qdata _data = 0; + + while (queue_size() > 0) + { + // 取一个数据 + queue_pop(&_data); + + if (cmd_pos == 0 && _data != CMD_HEAD) // 指令第一个字节必须是帧头,否则跳过 + { + continue; + } + // LED2_ON; + if (cmd_pos < buf_len) // 防止缓冲区溢出 + buffer[cmd_pos++] = _data; + + cmd_state = ((cmd_state << 8) | _data); // 拼接最后4个字节,组成一个32位整数 + + // 最后4个字节与帧尾匹配,得到完整帧 + if (cmd_state == CMD_TAIL) + { + // LED2_ON; + cmd_size = cmd_pos; // 指令字节长度 + cmd_state = 0; // 重新检测帧尾巴 + cmd_pos = 0; // 复位指令指针 + +#if (CRC16_ENABLE) + // 去掉指令头尾EE,尾FFFCFFFF共计5个字节,只计算数据部分CRC + if (!CheckCRC16(buffer + 1, cmd_size - 5)) // CRC校验 + return 0; + + cmd_size -= 2; // 去掉CRC16(2字节) +#endif + return cmd_size; + } + } + return 0; // 没有形成完整的一帧 +} diff --git a/mkrtos_user/server/app/hmi_lcd/cmd_queue.h b/mkrtos_user/server/app/hmi_lcd/cmd_queue.h new file mode 100644 index 000000000..f2524baff --- /dev/null +++ b/mkrtos_user/server/app/hmi_lcd/cmd_queue.h @@ -0,0 +1,30 @@ + + +#ifndef _CMD_QUEUE +#define _CMD_QUEUE +#include "hmi_driver.h" + +typedef unsigned char qdata; +typedef unsigned short qsize; + +/*! + * \brief 清空指令数据 + */ +extern void queue_reset(void); + +/*! + * \brief 添加指令数据 + * \detial 串口接收的数据,通过此函数放入指令队列 + * \param _data 指令数据 + */ +extern void queue_push(qdata _data); + +/*! + * \brief 从指令队列中取出一条完整的指令 + * \param cmd 指令接收缓存区 + * \param buf_len 指令接收缓存区大小 + * \return 指令长度,0表示队列中无完整指令 + */ +extern qsize queue_find_cmd(qdata *cmd, qsize buf_len); + +#endif diff --git a/mkrtos_user/server/app/hmi_lcd/hmi_driver.c b/mkrtos_user/server/app/hmi_lcd/hmi_driver.c new file mode 100644 index 000000000..4527de165 --- /dev/null +++ b/mkrtos_user/server/app/hmi_lcd/hmi_driver.c @@ -0,0 +1,2016 @@ +/************************************版权申明******************************************** +** 广州大彩光电科技有限公司 +** http://www.gz-dc.com +**-----------------------------------文件信息-------------------------------------------- +** 文件名称: hmi_driver.c +** 修改时间: 2018-05-18 +** 文件说明: 用户MCU串口驱动函数库 +** 技术支持: Tel: 020-82186683 Email: hmi@gz-dc.com Web:www.gz-dc.com +-------------------------------------------------------------------------------------- +----------------------------------------------------------------------------------------*/ +#include "hmi_driver.h" + +#define TX_8(P1) SEND_DATA((P1)&0xFF) // 发送单个字节 +#define TX_8N(P, N) SendNU8((uint8_t *)P, N) // 发送N个字节 +#define TX_16(P1) \ + TX_8((P1) >> 8); \ + TX_8(P1) // 发送16位整数 +#define TX_16N(P, N) SendNU16((uint16_t *)P, N) // 发送N个16位整数 +#define TX_32(P1) \ + TX_16((P1) >> 16); \ + TX_16((P1)&0xFFFF) // 发送32位整数 + +#if (CRC16_ENABLE) + +static uint16_t _crc16 = 0xffff; +/*! + * \brief 检查数据是否符合CRC16校验 + * \param buffer 待校验的数据 + * \param n 数据长度,包含CRC16 + * \param pcrc 校验码 + */ +static void AddCRC16(uint8_t *buffer, uint16_t n, uint16_t *pcrc) +{ + uint16_t i, j, carry_flag, a; + + for (i = 0; i < n; i++) + { + *pcrc = *pcrc ^ buffer[i]; + for (j = 0; j < 8; j++) + { + a = *pcrc; + carry_flag = a & 0x0001; + *pcrc = *pcrc >> 1; + if (carry_flag == 1) + *pcrc = *pcrc ^ 0xa001; + } + } +} +/*! + * \brief 检查数据是否符合CRC16校验 + * \param buffer 待校验的数据,末尾存储CRC16 + * \param n 数据长度,包含CRC16 + * \return 校验通过返回1,否则返回0 + */ +uint16_t CheckCRC16(uint8_t *buffer, uint16_t n) +{ + uint16_t crc0 = 0x0; + uint16_t crc1 = 0xffff; + + if (n >= 2) + { + crc0 = ((buffer[n - 2] << 8) | buffer[n - 1]); + AddCRC16(buffer, n - 2, &crc1); + } + + return (crc0 == crc1); +} +/*! + * \brief 发送一个字节 + * \param c + */ +void SEND_DATA(uint8_t c) +{ + AddCRC16(&c, 1, &_crc16); + SendChar(c); +} +/*! + * \brief 帧头 + */ +void BEGIN_CMD() +{ + TX_8(0XEE); + _crc16 = 0XFFFF; // 开始计算CRC16 +} +/*! + * \brief 帧尾 + */ +void END_CMD() +{ + uint16_t crc16 = _crc16; + TX_16(crc16); // 发送CRC16 + TX_32(0XFFFCFFFF); +} + +#else // NO CRC16 + +#define SEND_DATA(P) SendChar(P) // 发送一个字节 +#define BEGIN_CMD() TX_8(0XEE) // 帧头 +#define END_CMD() TX_32(0XFFFCFFFF) // 帧尾 + +#endif +/*! + * \brief 延时 + * \param n 延时时间(毫秒单位) + */ +void DelayMS(unsigned int n) +{ + int i, j; + for (i = n; i > 0; i--) + for (j = 1000; j > 0; j--) + ; +} +/*! + * \brief 串口发送送字符串 + * \param 字符串 + */ +void SendStrings(uint8_t *str) +{ + while (*str) + { + TX_8(*str); + str++; + } +} +/*! + * \brief 串口发送送N个字节 + * \param 个数 + */ +void SendNU8(uint8_t *pData, uint16_t nDataLen) +{ + uint16_t i = 0; + for (; i < nDataLen; ++i) + { + TX_8(pData[i]); + } +} +/*! + * \brief 串口发送送N个16位的数据 + * \param 个数 + */ +void SendNU16(uint16_t *pData, uint16_t nDataLen) +{ + uint16_t i = 0; + for (; i < nDataLen; ++i) + { + TX_16(pData[i]); + } +} +/*! + * \brief 发送握手命令 + */ +void SetHandShake() +{ + BEGIN_CMD(); + TX_8(0x04); + END_CMD(); +} + +/*! + * \brief 设置前景色 + * \param color 前景色 + */ +void SetFcolor(uint16_t color) +{ + BEGIN_CMD(); + TX_8(0x41); + TX_16(color); + END_CMD(); +} +/*! + * \brief 设置背景色 + * \param color 背景色 + */ +void SetBcolor(uint16_t color) +{ + BEGIN_CMD(); + TX_8(0x42); + TX_16(color); + END_CMD(); +} +/*! + * \brief 获取 + * \param color 背景色 + */ +void ColorPicker(uint8_t mode, uint16_t x, uint16_t y) +{ + BEGIN_CMD(); + TX_8(0xA3); + TX_8(mode); + TX_16(x); + TX_16(y); + END_CMD(); +} +/*! + * \brief 清除画面 + */ +void GUI_CleanScreen() +{ + BEGIN_CMD(); + TX_8(0x01); + END_CMD(); +} +/*! + * \brief 设置文字间隔 + * \param x_w 横向间隔 + * \param y_w 纵向间隔 + */ +void SetTextSpace(uint8_t x_w, uint8_t y_w) +{ + BEGIN_CMD(); + TX_8(0x43); + TX_8(x_w); + TX_8(y_w); + END_CMD(); +} +/*! + * \brief 设置文字显示限制 + * \param enable 是否启用限制 + * \param width 宽度 + * \param height 高度 + */ +void SetFont_Region(uint8_t enable, uint16_t width, uint16_t height) +{ + BEGIN_CMD(); + TX_8(0x45); + TX_8(enable); + TX_16(width); + TX_16(height); + END_CMD(); +} +/*! + * \brief 设置过滤色 + * \param fillcolor_dwon 颜色下界 + * \param fillcolor_up 颜色上界 + */ +void SetFilterColor(uint16_t fillcolor_dwon, uint16_t fillcolor_up) +{ + BEGIN_CMD(); + TX_8(0x44); + TX_16(fillcolor_dwon); + TX_16(fillcolor_up); + END_CMD(); +} + +/*! + * \brief 设置过滤色 + * \param x 位置X坐标 + * \param y 位置Y坐标 + * \param back 颜色上界 + * \param font 字体 + * \param strings 字符串内容 + */ +void DisText(uint16_t x, uint16_t y, uint8_t back, uint8_t font, uint8_t *strings) +{ + BEGIN_CMD(); + TX_8(0x20); + TX_16(x); + TX_16(y); + TX_8(back); + TX_8(font); + SendStrings(strings); + END_CMD(); +} +/*! + * \brief 显示光标 + * \param enable 是否显示 + * \param x 位置X坐标 + * \param y 位置Y坐标 + * \param width 宽度 + * \param height 高度 + */ +void DisCursor(uint8_t enable, uint16_t x, uint16_t y, uint8_t width, uint8_t height) +{ + BEGIN_CMD(); + TX_8(0x21); + TX_8(enable); + TX_16(x); + TX_16(y); + TX_8(width); + TX_8(height); + END_CMD(); +} +/*! + * \brief 显示全屏图片 + * \param image_id 图片索引 + * \param masken 是否启用透明掩码 + */ +void DisFull_Image(uint16_t image_id, uint8_t masken) +{ + BEGIN_CMD(); + TX_8(0x31); + TX_16(image_id); + TX_8(masken); + END_CMD(); +} +/*! + * \brief 指定位置显示图片 + * \param x 位置X坐标 + * \param y 位置Y坐标 + * \param image_id 图片索引 + * \param masken 是否启用透明掩码 + */ +void DisArea_Image(uint16_t x, uint16_t y, uint16_t image_id, uint8_t masken) +{ + BEGIN_CMD(); + TX_8(0x32); + TX_16(x); + TX_16(y); + TX_16(image_id); + TX_8(masken); + END_CMD(); +} +/*! + * \brief 显示裁剪图片 + * \param x 位置X坐标 + * \param y 位置Y坐标 + * \param image_id 图片索引 + * \param image_x 图片裁剪位置X坐标 + * \param image_y 图片裁剪位置Y坐标 + * \param image_l 图片裁剪长度 + * \param image_w 图片裁剪高度 + * \param masken 是否启用透明掩码 + */ +void DisCut_Image(uint16_t x, uint16_t y, uint16_t image_id, uint16_t image_x, uint16_t image_y, uint16_t image_l, uint16_t image_w, uint8_t masken) +{ + BEGIN_CMD(); + TX_8(0x33); + TX_16(x); + TX_16(y); + TX_16(image_id); + TX_16(image_x); + TX_16(image_y); + TX_16(image_l); + TX_16(image_w); + TX_8(masken); + END_CMD(); +} +/*! + * \brief 显示GIF动画 + * \param x 位置X坐标 + * \param y 位置Y坐标 + * \param flashimage_id 图片索引 + * \param enable 是否显示 + * \param playnum 播放次数 + */ +void DisFlashImage(uint16_t x, uint16_t y, uint16_t flashimage_id, uint8_t enable, uint8_t playnum) +{ + BEGIN_CMD(); + TX_8(0x80); + TX_16(x); + TX_16(y); + TX_16(flashimage_id); + TX_8(enable); + TX_8(playnum); + END_CMD(); +} +/*! + * \brief 画点 + * \param x 位置X坐标 + * \param y 位置Y坐标 + */ +void GUI_Dot(uint16_t x, uint16_t y) +{ + BEGIN_CMD(); + TX_8(0x50); + TX_16(x); + TX_16(y); + END_CMD(); +} +/*! + * \brief 画线 + * \param x0 起始位置X坐标 + * \param y0 起始位置Y坐标 + * \param x1 结束位置X坐标 + * \param y1 结束位置Y坐标 + */ +void GUI_Line(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) +{ + BEGIN_CMD(); + TX_8(0x51); + TX_16(x0); + TX_16(y0); + TX_16(x1); + TX_16(y1); + END_CMD(); +} + +/*! + * \brief 画折线 + * \param mode 模式 + * \param dot 数据点 + * \param dot_cnt 点数 + */ +void GUI_ConDots(uint8_t mode, uint16_t *dot, uint16_t dot_cnt) +{ + BEGIN_CMD(); + TX_8(0x63); + TX_8(mode); + TX_16N(dot, dot_cnt * 2); + END_CMD(); +} + +/*! + * \brief x坐标等距使用前景色连线 + * \param x 横坐标 + * \param x_space 距离 + * \param dot_y 一组纵轴坐标 + * \param dot_cnt 纵坐标个数 + */ +void GUI_ConSpaceDots(uint16_t x, uint16_t x_space, uint16_t *dot_y, uint16_t dot_cnt) +{ + BEGIN_CMD(); + TX_8(0x59); + TX_16(x); + TX_16(x_space); + TX_16N(dot_y, dot_cnt); + END_CMD(); +} +/*! + * \brief 按照坐标偏移量用前景色连线 + * \param x 横坐标 + * \param y 纵距离 + * \param dot_offset 偏移量 + * \param dot_cnt 偏移量个数 + */ +void GUI_FcolorConOffsetDots(uint16_t x, uint16_t y, uint16_t *dot_offset, uint16_t dot_cnt) +{ + BEGIN_CMD(); + TX_8(0x75); + TX_16(x); + TX_16(y); + TX_16N(dot_offset, dot_cnt); + END_CMD(); +} +/*! + * \brief 按照坐标偏移量用背景色连线 + * \param x 横坐标 + * \param y 纵距离 + * \param dot_offset 偏移量 + * \param dot_cnt 偏移量个数 + */ +void GUI_BcolorConOffsetDots(uint16_t x, uint16_t y, uint8_t *dot_offset, uint16_t dot_cnt) +{ + BEGIN_CMD(); + TX_8(0x76); + TX_16(x); + TX_16(y); + TX_16N(dot_offset, dot_cnt); + END_CMD(); +} +/*! + * \brief 自动调节背光亮度 + * \param enable 使能 + * \param bl_off_level 待机亮度 + * \param bl_on_level 激活亮度 + * \param bl_on_time 偏移量个数 + */ +void SetPowerSaving(uint8_t enable, uint8_t bl_off_level, uint8_t bl_on_level, uint8_t bl_on_time) +{ + BEGIN_CMD(); + TX_8(0x77); + TX_8(enable); + TX_8(bl_off_level); + TX_8(bl_on_level); + TX_8(bl_on_time); + END_CMD(); +} +/*! + * \brief 将制定的多个坐标点用前景色连接起来 + * \param dot 坐标点 + * \param dot_cnt 偏移量个数 + */ +void GUI_FcolorConDots(uint16_t *dot, uint16_t dot_cnt) +{ + BEGIN_CMD(); + TX_8(0x68); + TX_16N(dot, dot_cnt * 2); + END_CMD(); +} +/*! + * \brief 将制定的多个坐标点用背景色连接起来 + * \param dot 坐标点 + * \param dot_cnt 偏移量个数 + */ +void GUI_BcolorConDots(uint16_t *dot, uint16_t dot_cnt) +{ + BEGIN_CMD(); + TX_8(0x69); + TX_16N(dot, dot_cnt * 2); + END_CMD(); +} +/*! + * \brief 画空心圆 + * \param x0 圆心位置X坐标 + * \param y0 圆心位置Y坐标 + * \param r 半径 + */ +void GUI_Circle(uint16_t x, uint16_t y, uint16_t r) +{ + BEGIN_CMD(); + TX_8(0x52); + TX_16(x); + TX_16(y); + TX_16(r); + END_CMD(); +} +/*! + * \brief 画实心圆 + * \param x0 圆心位置X坐标 + * \param y0 圆心位置Y坐标 + * \param r 半径 + */ +void GUI_CircleFill(uint16_t x, uint16_t y, uint16_t r) +{ + BEGIN_CMD(); + TX_8(0x53); + TX_16(x); + TX_16(y); + TX_16(r); + END_CMD(); +} +/*! + * \brief 画弧线 + * \param x0 圆心位置X坐标 + * \param y0 圆心位置Y坐标 + * \param r 半径 + * \param sa 起始角度 + * \param ea 终止角度 + */ +void GUI_Arc(uint16_t x, uint16_t y, uint16_t r, uint16_t sa, uint16_t ea) +{ + BEGIN_CMD(); + TX_8(0x67); + TX_16(x); + TX_16(y); + TX_16(r); + TX_16(sa); + TX_16(ea); + END_CMD(); +} +/*! + * \brief 画空心矩形 + * \param x0 起始位置X坐标 + * \param y0 起始位置Y坐标 + * \param x1 结束位置X坐标 + * \param y1 结束位置Y坐标 + */ +void GUI_Rectangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) +{ + BEGIN_CMD(); + TX_8(0x54); + TX_16(x0); + TX_16(y0); + TX_16(x1); + TX_16(y1); + END_CMD(); +} +/*! + * \brief 画实心矩形 + * \param x0 起始位置X坐标 + * \param y0 起始位置Y坐标 + * \param x1 结束位置X坐标 + * \param y1 结束位置Y坐标 + */ +void GUI_RectangleFill(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) +{ + BEGIN_CMD(); + TX_8(0x55); + TX_16(x0); + TX_16(y0); + TX_16(x1); + TX_16(y1); + END_CMD(); +} +/*! + * \brief 画空心椭圆 + * \param x0 起始位置X坐标 + * \param y0 起始位置Y坐标 + * \param x1 结束位置X坐标 + * \param y1 结束位置Y坐标 + */ +void GUI_Ellipse(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) +{ + BEGIN_CMD(); + TX_8(0x56); + TX_16(x0); + TX_16(y0); + TX_16(x1); + TX_16(y1); + END_CMD(); +} +/*! + * \brief 画实心椭圆 + * \param x0 起始位置X坐标 + * \param y0 起始位置Y坐标 + * \param x1 结束位置X坐标 + * \param y1 结束位置Y坐标 + */ +void GUI_EllipseFill(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) +{ + BEGIN_CMD(); + TX_8(0x57); + TX_16(x0); + TX_16(y0); + TX_16(x1); + TX_16(y1); + END_CMD(); +} +/*! + * \brief 画线 + * \param x0 起始位置X坐标 + * \param y0 起始位置Y坐标 + * \param x1 结束位置X坐标 + * \param y1 结束位置Y坐标 + */ +void SetBackLight(uint8_t light_level) +{ + BEGIN_CMD(); + TX_8(0x60); + TX_8(light_level); + END_CMD(); +} + +/*! + * \brief 蜂鸣器设置 + * \time time 持续时间(毫秒单位) + */ +void SetBuzzer(uint8_t time) +{ + BEGIN_CMD(); + TX_8(0x61); + TX_8(time); + END_CMD(); +} + +void GUI_AreaInycolor(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) +{ + BEGIN_CMD(); + TX_8(0x65); + TX_16(x0); + TX_16(y0); + TX_16(x1); + TX_16(y1); + END_CMD(); +} +/*! + * \brief 触摸屏设置 + * \param enable 触摸使能 + * \param beep_on 触摸蜂鸣器 + * \param work_mode 触摸工作模式:0按下就上传,1松开才上传,2不断上传坐标值,3按下和松开均上传数据 + * \param press_calibration 连续点击触摸屏20下校准触摸屏:0禁用,1启用 + */ +void SetTouchPaneOption(uint8_t enbale, uint8_t beep_on, uint8_t work_mode, uint8_t press_calibration) +{ + uint8_t options = 0; + + if (enbale) + options |= 0x01; + if (beep_on) + options |= 0x02; + if (work_mode) + options |= (work_mode << 2); + if (press_calibration) + options |= (press_calibration << 5); + + BEGIN_CMD(); + TX_8(0x70); + TX_8(options); + END_CMD(); +} +/*! + * \brief 校准触摸屏 + */ +void CalibrateTouchPane() +{ + BEGIN_CMD(); + TX_8(0x72); + END_CMD(); +} +/*! + * \brief 触摸屏测试 + */ +void TestTouchPane() +{ + BEGIN_CMD(); + TX_8(0x73); + END_CMD(); +} + +/*! + * \brief 锁定设备配置,锁定之后需要解锁,才能修改波特率、触摸屏、蜂鸣器工作方式 + */ +void LockDeviceConfig(void) +{ + BEGIN_CMD(); + TX_8(0x09); + TX_8(0xDE); + TX_8(0xED); + TX_8(0x13); + TX_8(0x31); + END_CMD(); +} + +/*! + * \brief 解锁设备配置 + */ +void UnlockDeviceConfig(void) +{ + BEGIN_CMD(); + TX_8(0x08); + TX_8(0xA5); + TX_8(0x5A); + TX_8(0x5F); + TX_8(0xF5); + END_CMD(); +} +/*! +* \brief 修改串口屏的波特率 +* \details 波特率选项范围[0~14],对应实际波特率 +{1200,2400,4800,9600,19200,38400,57600,115200,1000000,2000000,218750,437500,875000,921800,2500000} +* \param option 波特率选项 +*/ +void SetCommBps(uint8_t option) +{ + BEGIN_CMD(); + TX_8(0xA0); + TX_8(option); + END_CMD(); +} +/*! + * \brief 设置当前写入图层 + * \details 一般用于实现双缓存效果(绘图时避免闪烁): + * \details uint8_t layer = 0; + * \details WriteLayer(layer); 设置写入层 + * \details ClearLayer(layer); 使图层变透明 + * \details 添加一系列绘图指令 + * \details DisText(100,100,0,4,"hello hmi!!!"); + * \details DisplyLayer(layer); 切换显示层 + * \details layer = (layer+1)%2; 双缓存切换 + * \see DisplyLayer + * \see ClearLayer + * \param layer 图层编号 + */ +void WriteLayer(uint8_t layer) +{ + BEGIN_CMD(); + TX_8(0xA1); + TX_8(layer); + END_CMD(); +} +/*! + * \brief 设置当前显示图层 + * \param layer 图层编号 + */ +void DisplyLayer(uint8_t layer) +{ + BEGIN_CMD(); + TX_8(0xA2); + TX_8(layer); + END_CMD(); +} +/*! + * \brief 拷贝图层 + * \param src_layer 原始图层 + * \param dest_layer 目标图层 + */ +void CopyLayer(uint8_t src_layer, uint8_t dest_layer) +{ + BEGIN_CMD(); + TX_8(0xA4); + TX_8(src_layer); + TX_8(dest_layer); + END_CMD(); +} +/*! + * \brief 清除图层,使图层变成透明 + * \param layer 图层编号 + */ +void ClearLayer(uint8_t layer) +{ + BEGIN_CMD(); + TX_8(0x05); + TX_8(layer); + END_CMD(); +} + +void GUI_DispRTC(uint8_t enable, uint8_t mode, uint8_t font, uint16_t color, uint16_t x, uint16_t y) +{ + BEGIN_CMD(); + TX_8(0x85); + TX_8(enable); + TX_8(mode); + TX_8(font); + TX_16(color); + TX_16(x); + TX_16(y); + END_CMD(); +} +/*! + * \brief 写数据到串口屏用户存储区 + * \param startAddress 起始地址 + * \param length 字节数 + * \param _data 待写入的数据 + */ +void WriteUserFlash(uint32_t startAddress, uint16_t length, uint8_t *_data) +{ + BEGIN_CMD(); + TX_8(0x87); + TX_32(startAddress); + TX_8N(_data, length); + END_CMD(); +} +/*! + * \brief 从串口屏用户存储区读取数据 + * \param startAddress 起始地址 + * \param length 字节数 + */ +void ReadUserFlash(uint32_t startAddress, uint16_t length) +{ + BEGIN_CMD(); + TX_8(0x88); + TX_32(startAddress); + TX_16(length); + END_CMD(); +} +/*! + * \brief 获取当前画面 + */ +void GetScreen(uint16_t screen_id) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x01); + END_CMD(); +} +/*! + * \brief 设置当前画面 + * \param screen_id 画面ID + */ +void SetScreen(uint16_t screen_id) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x00); + TX_16(screen_id); + END_CMD(); +} +/*! + * \brief 禁用\启用画面更新 + * \details 禁用\启用一般成对使用,用于避免闪烁、提高刷新速度 + * \details 用法: + * \details SetScreenUpdateEnable(0);//禁止更新 + * \details 一系列更新画面的指令 + * \details SetScreenUpdateEnable(1);//立即更新 + * \param enable 0禁用,1启用 + */ +void SetScreenUpdateEnable(uint8_t enable) +{ + BEGIN_CMD(); + TX_8(0xB3); + TX_8(enable); + END_CMD(); +} +/*! + * \brief 设置控件输入焦点 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param focus 是否具有输入焦点 + */ +void SetControlFocus(uint16_t screen_id, uint16_t control_id, uint8_t focus) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x02); + TX_16(screen_id); + TX_16(control_id); + TX_8(focus); + END_CMD(); +} +/*! + * \brief 显示\隐藏控件 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param visible 是否显示 + */ +void SetControlVisiable(uint16_t screen_id, uint16_t control_id, uint8_t visible) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x03); + TX_16(screen_id); + TX_16(control_id); + TX_8(visible); + END_CMD(); +} +/*! + * \brief 设置触摸控件使能 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param enable 控件是否使能 + */ +void SetControlEnable(uint16_t screen_id, uint16_t control_id, uint8_t enable) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x04); + TX_16(screen_id); + TX_16(control_id); + TX_8(enable); + END_CMD(); +} +/*! + * \brief 设置按钮状态 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 按钮状态 + */ +void SetButtonValue(uint16_t screen_id, uint16_t control_id, uint8_t state) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x10); + TX_16(screen_id); + TX_16(control_id); + TX_8(state); + END_CMD(); +} +/*! + * \brief 设置文本值 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param str 文本值 + */ +void SetTextValue(uint16_t screen_id, uint16_t control_id, uint8_t *str) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x10); + TX_16(screen_id); + TX_16(control_id); + SendStrings(str); + END_CMD(); +} + +#if FIRMWARE_VER >= 908 +/*! + * \brief 设置文本为整数值,要求FIRMWARE_VER>=908 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 文本数值 + * \param sign 0-无符号,1-有符号 + * \param fill_zero 数字位数,不足时左侧补零 + */ +void SetTextInt32(uint16_t screen_id, uint16_t control_id, int32_t value, uint8_t sign, uint8_t fill_zero) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x07); + TX_16(screen_id); + TX_16(control_id); + TX_8(sign ? 0X01 : 0X00); + TX_8((fill_zero & 0x0f) | 0x80); + TX_32(value); + END_CMD(); +} +/*! + * \brief 设置文本单精度浮点值,要求FIRMWARE_VER>=908 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 文本数值 + * \param precision 小数位数 + * \param show_zeros 为1时,显示末尾0 + */ +void SetTextFloat(uint16_t screen_id, uint16_t control_id, float value, uint8_t precision, uint8_t show_zeros) +{ + uint8_t i = 0; + + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x07); + TX_16(screen_id); + TX_16(control_id); + TX_8(0x02); + TX_8((precision & 0x0f) | (show_zeros ? 0x80 : 0x00)); + + for (i = 0; i < 4; ++i) + { + // 需要区分大小端 +#if (0) + TX_8(((uint8_t *)&value)[i]); +#else + TX_8(((uint8_t *)&value)[3 - i]); +#endif + } + END_CMD(); +} +#endif +/*! + * \brief 设置进度值 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 数值 + */ +void SetProgressValue(uint16_t screen_id, uint16_t control_id, uint32_t value) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x10); + TX_16(screen_id); + TX_16(control_id); + TX_32(value); + END_CMD(); +} +/*! + * \brief 设置仪表值 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 数值 + */ +void SetMeterValue(uint16_t screen_id, uint16_t control_id, uint32_t value) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x10); + TX_16(screen_id); + TX_16(control_id); + TX_32(value); + END_CMD(); +} +/*! + * \brief 设置仪表值 + * \param screen_id 画面ID + * \param control_id 图片控件ID + * \param value 数值 + */ +void Set_picMeterValue(uint16_t screen_id, uint16_t control_id, uint16_t value) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x10); + TX_16(screen_id); + TX_16(control_id); + TX_16(value); + END_CMD(); +} +/*! + * \brief 设置滑动条 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 数值 + */ + +void SetSliderValue(uint16_t screen_id, uint16_t control_id, uint32_t value) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x10); + TX_16(screen_id); + TX_16(control_id); + TX_32(value); + END_CMD(); +} + +void SetSliderRangValue(uint16_t screen_id, uint16_t control_id, uint32_t start, uint32_t end) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x10); + TX_16(screen_id); + TX_16(control_id); + TX_16(start); + TX_16(end); + END_CMD(); +} +/*! + * \brief 设置选择控件 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param item 当前选项 + */ +void SetSelectorValue(uint16_t screen_id, uint16_t control_id, uint8_t item) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x10); + TX_16(screen_id); + TX_16(control_id); + TX_8(item); + END_CMD(); +} +/*! + * \brief 获取控件值 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void GetControlValue(uint16_t screen_id, uint16_t control_id) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x11); + TX_16(screen_id); + TX_16(control_id); + END_CMD(); +} + +/*! + * \brief 开始播放动画 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void AnimationStart(uint16_t screen_id, uint16_t control_id) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x20); + TX_16(screen_id); + TX_16(control_id); + END_CMD(); +} + +/*! + * \brief 停止播放动画 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void AnimationStop(uint16_t screen_id, uint16_t control_id) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x21); + TX_16(screen_id); + TX_16(control_id); + END_CMD(); +} +/*! + * \brief 暂停播放动画 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void AnimationPause(uint16_t screen_id, uint16_t control_id) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x22); + TX_16(screen_id); + TX_16(control_id); + END_CMD(); +} +/*! + * \brief 播放制定帧 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param frame_id 帧ID + */ +void AnimationPlayFrame(uint16_t screen_id, uint16_t control_id, uint8_t frame_id) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x23); + TX_16(screen_id); + TX_16(control_id); + TX_8(frame_id); + END_CMD(); +} +/*! + * \brief 播放上一帧 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void AnimationPlayPrev(uint16_t screen_id, uint16_t control_id) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x24); + TX_16(screen_id); + TX_16(control_id); + END_CMD(); +} +/*! + * \brief 播放下一帧 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void AnimationPlayNext(uint16_t screen_id, uint16_t control_id) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x25); + TX_16(screen_id); + TX_16(control_id); + END_CMD(); +} +/*! + * \brief 曲线控件-添加通道 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param channel 通道号 + * \param color 颜色 + */ +void GraphChannelAdd(uint16_t screen_id, uint16_t control_id, uint8_t channel, uint16_t color) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x30); + TX_16(screen_id); + TX_16(control_id); + TX_8(channel); + TX_16(color); + END_CMD(); +} +/*! + * \brief 曲线控件-删除通道 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param channel 通道号 + */ +void GraphChannelDel(uint16_t screen_id, uint16_t control_id, uint8_t channel) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x31); + TX_16(screen_id); + TX_16(control_id); + TX_8(channel); + END_CMD(); +} +/*! + * \brief 曲线控件-添加数据 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param channel 通道号 + * \param pData 曲线数据 + * \param nDataLen 数据个数 + */ +void GraphChannelDataAdd(uint16_t screen_id, uint16_t control_id, uint8_t channel, uint8_t *pData, uint16_t nDataLen) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x32); + TX_16(screen_id); + TX_16(control_id); + TX_8(channel); + TX_16(nDataLen); + TX_8N(pData, nDataLen); + END_CMD(); +} +/*! + * \brief 曲线控件-清除数据 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param channel 通道号 + */ +void GraphChannelDataClear(uint16_t screen_id, uint16_t control_id, uint8_t channel) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x33); + TX_16(screen_id); + TX_16(control_id); + TX_8(channel); + END_CMD(); +} +/*! + * \brief 曲线控件-设置视图窗口 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param x_offset 水平偏移 + * \param x_mul 水平缩放系数 + * \param y_offset 垂直偏移 + * \param y_mul 垂直缩放系数 + */ +void GraphSetViewport(uint16_t screen_id, uint16_t control_id, int16_t x_offset, uint16_t x_mul, int16_t y_offset, uint16_t y_mul) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x34); + TX_16(screen_id); + TX_16(control_id); + TX_16(x_offset); + TX_16(x_mul); + TX_16(y_offset); + TX_16(y_mul); + END_CMD(); +} +/*! + * \brief 开始批量更新 + * \param screen_id 画面ID + */ +void BatchBegin(uint16_t screen_id) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x12); + TX_16(screen_id); +} +/*! + * \brief 批量更新按钮控件 + * \param control_id 控件ID + * \param value 数值 + */ +void BatchSetButtonValue(uint16_t control_id, uint8_t state) +{ + TX_16(control_id); + TX_16(1); + TX_8(state); +} +/*! + * \brief 批量更新进度条控件 + * \param control_id 控件ID + * \param value 数值 + */ +void BatchSetProgressValue(uint16_t control_id, uint32_t value) +{ + TX_16(control_id); + TX_16(4); + TX_32(value); +} + +/*! + * \brief 批量更新滑动条控件 + * \param control_id 控件ID + * \param value 数值 + */ +void BatchSetSliderValue(uint16_t control_id, uint32_t value) +{ + TX_16(control_id); + TX_16(4); + TX_32(value); +} +/*! + * \brief 批量更新仪表控件 + * \param control_id 控件ID + * \param value 数值 + */ +void BatchSetMeterValue(uint16_t control_id, uint32_t value) +{ + TX_16(control_id); + TX_16(4); + TX_32(value); +} +/*! + * \brief 计算字符串长度 + */ +uint32_t GetStringLen(uint8_t *str) +{ + uint8_t *p = str; + while (*str) + { + str++; + } + + return (str - p); +} +/*! + * \brief 批量更新文本控件 + * \param control_id 控件ID + * \param strings 字符串 + */ +void BatchSetText(uint16_t control_id, uint8_t *strings) +{ + TX_16(control_id); + TX_16(GetStringLen(strings)); + SendStrings(strings); +} +/*! + * \brief 批量更新动画\图标控件 + * \param control_id 控件ID + * \param frame_id 帧ID + */ +void BatchSetFrame(uint16_t control_id, uint16_t frame_id) +{ + TX_16(control_id); + TX_16(2); + TX_16(frame_id); +} + +#if FIRMWARE_VER >= 908 + +/*! + * \brief 批量设置控件可见 + * \param control_id 控件ID + * \param visible 帧ID + */ +void BatchSetVisible(uint16_t control_id, uint8_t visible) +{ + TX_16(control_id); + TX_8(1); + TX_8(visible); +} +/*! + * \brief 批量设置控件使能 + * \param control_id 控件ID + * \param enable 帧ID + */ +void BatchSetEnable(uint16_t control_id, uint8_t enable) +{ + TX_16(control_id); + TX_8(2); + TX_8(enable); +} + +#endif +/*! + * \brief 结束批量更新 + */ +void BatchEnd() +{ + END_CMD(); +} +/*! + * \brief 设置倒计时控件 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param timeout 倒计时(秒) + */ +void SeTimer(uint16_t screen_id, uint16_t control_id, uint32_t timeout) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x40); + TX_16(screen_id); + TX_16(control_id); + TX_32(timeout); + END_CMD(); +} +/*! + * \brief 开启倒计时控件 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void StartTimer(uint16_t screen_id, uint16_t control_id) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x41); + TX_16(screen_id); + TX_16(control_id); + END_CMD(); +} +/*! + * \brief 停止倒计时控件 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void StopTimer(uint16_t screen_id, uint16_t control_id) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x42); + TX_16(screen_id); + TX_16(control_id); + END_CMD(); +} +/*! + * \brief 暂停倒计时控件 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void PauseTimer(uint16_t screen_id, uint16_t control_id) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x44); + TX_16(screen_id); + TX_16(control_id); + END_CMD(); +} +/*! + * \brief 设置控件背景色 + * \details 支持控件:进度条、文本 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param color 背景色 + */ +void SetControlBackColor(uint16_t screen_id, uint16_t control_id, uint16_t color) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x18); + TX_16(screen_id); + TX_16(control_id); + TX_16(color); + END_CMD(); +} +/*! + * \brief 设置控件前景色 + * \details 支持控件:进度条 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param color 前景色 + */ +void SetControlForeColor(uint16_t screen_id, uint16_t control_id, uint16_t color) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x19); + TX_16(screen_id); + TX_16(control_id); + TX_16(color); + END_CMD(); +} +/*! + * \brief 显示\隐藏弹出菜单控件 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param show 是否显示,为0时focus_control_id无效 + * \param focus_control_id 关联的文本控件(菜单控件的内容输出到文本控件) + */ +void ShowPopupMenu(uint16_t screen_id, uint16_t control_id, uint8_t show, uint16_t focus_control_id) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x13); + TX_16(screen_id); + TX_16(control_id); + TX_8(show); + TX_16(focus_control_id); + END_CMD(); +} +/*! + * \brief 显示\隐藏系统键盘 + * \param show 0隐藏,1显示 + * \param x 键盘显示位置X坐标 + * \param y 键盘显示位置Y坐标 + * \param type 0小键盘,1全键盘 + * \param option 0正常字符,1密码,2时间设置 + * \param max_len 键盘录入字符长度限制 + */ +void ShowKeyboard(uint8_t show, uint16_t x, uint16_t y, uint8_t type, uint8_t option, uint8_t max_len) +{ + BEGIN_CMD(); + TX_8(0x86); + TX_8(show); + TX_16(x); + TX_16(y); + TX_8(type); + TX_8(option); + TX_8(max_len); + END_CMD(); +} + +#if FIRMWARE_VER >= 921 +/*! + * \brief 多语言设置 + * \param ui_lang 用户界面语言0~9 + * \param sys_lang 系统键盘语言-0中文,1英文 + */ +void SetLanguage(uint8_t ui_lang, uint8_t sys_lang) +{ + uint8_t lang = ui_lang; + if (sys_lang) + lang |= 0x80; + + BEGIN_CMD(); + TX_8(0xC1); + TX_8(lang); + TX_8(0xC1 + lang); // 校验,防止意外修改语言 + END_CMD(); +} +#endif + +#if FIRMWARE_VER >= 921 +/*! + * \brief 开始保存控件数值到FLASH + * \param version 数据版本号,可任意指定,高16位为主版本号,低16位为次版本号 + * \param address 数据在用户存储区的存放地址,注意防止地址重叠、冲突 + */ +void FlashBeginSaveControl(uint32_t version, uint32_t address) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0xAA); + TX_32(version); + TX_32(address); +} + +/*! + * \brief 保存某个控件的数值到FLASH + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void FlashSaveControl(uint16_t screen_id, uint16_t control_id) +{ + TX_16(screen_id); + TX_16(control_id); +} +/*! + * \brief 保存某个控件的数值到FLASH + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void FlashEndSaveControl() +{ + END_CMD(); +} +/*! + * \brief 从FLASH中恢复控件数据 + * \param version 数据版本号,主版本号必须与存储时一致,否则会加载失败 + * \param address 数据在用户存储区的存放地址 + */ +void FlashRestoreControl(uint32_t version, uint32_t address) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0xAB); + TX_32(version); + TX_32(address); + END_CMD(); +} + +#endif + +#if FIRMWARE_VER >= 921 +/*! + * \brief 设置历史曲线采样数据值(单字节,uint8_t或int8) + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 采样点数据 + * \param channel 通道数 + */ +void HistoryGraph_SetValueInt8(uint16_t screen_id, uint16_t control_id, uint8_t *value, uint8_t channel) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x60); + TX_16(screen_id); + TX_16(control_id); + TX_8N(value, channel); + END_CMD(); +} +/*! + * \brief 设置历史曲线采样数据值(双字节,uint16_t或int16) + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 采样点数据 + * \param channel 通道数 + */ +void HistoryGraph_SetValueInt16(uint16_t screen_id, uint16_t control_id, uint16_t *value, uint8_t channel) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x60); + TX_16(screen_id); + TX_16(control_id); + TX_16N(value, channel); + END_CMD(); +} +/*! + * \brief 设置历史曲线采样数据值(四字节,uint32_t_t或int32_t) + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 采样点数据 + * \param channel 通道数 + */ +void HistoryGraph_SetValueInt32(uint16_t screen_id, uint16_t control_id, uint32_t *value, uint8_t channel) +{ + uint8_t i = 0; + + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x60); + TX_16(screen_id); + TX_16(control_id); + + for (; i < channel; ++i) + { + TX_32(value[i]); + } + + END_CMD(); +} +/*! + * \brief 设置历史曲线采样数据值(单精度浮点数) + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 采样点数据 + * \param channel 通道数 + */ +void HistoryGraph_SetValueFloat(uint16_t screen_id, uint16_t control_id, float *value, uint8_t channel) +{ + uint8_t i = 0; + uint32_t tmp = 0; + + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x60); + TX_16(screen_id); + TX_16(control_id); + + for (; i < channel; ++i) + { + tmp = *(uint32_t *)(value + i); + TX_32(tmp); + } + + END_CMD(); +} +/*! + * \brief 允许或禁止历史曲线采样 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param enable 0-禁止,1-允许 + */ +void HistoryGraph_EnableSampling(uint16_t screen_id, uint16_t control_id, uint8_t enable) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x61); + TX_16(screen_id); + TX_16(control_id); + TX_8(enable); + END_CMD(); +} +/*! + * \brief 显示或隐藏历史曲线通道 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param channel 通道编号 + * \param show 0-隐藏,1-显示 + */ +void HistoryGraph_ShowChannel(uint16_t screen_id, uint16_t control_id, uint8_t channel, uint8_t show) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x62); + TX_16(screen_id); + TX_16(control_id); + TX_8(channel); + TX_8(show); + END_CMD(); +} +/*! + * \brief 设置历史曲线时间长度(即采样点数) + * \param screen_id 画面ID + * \param control_id 控件ID + * \param sample_count 一屏显示的采样点数 + */ +void HistoryGraph_SetTimeLength(uint16_t screen_id, uint16_t control_id, uint16_t sample_count) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x63); + TX_16(screen_id); + TX_16(control_id); + TX_8(0x00); + TX_16(sample_count); + END_CMD(); +} + +/*! + * \brief 历史曲线缩放到全屏 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void HistoryGraph_SetTimeFullScreen(uint16_t screen_id, uint16_t control_id) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x63); + TX_16(screen_id); + TX_16(control_id); + TX_8(0x01); + END_CMD(); +} +/*! + * \brief 设置历史曲线缩放比例系数 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param zoom 缩放百分比(zoom>100%时水平方向缩小,反正放大) + * \param max_zoom 缩放限制,一屏最多显示采样点数 + * \param min_zoom 缩放限制,一屏最少显示采样点数 + */ +void HistoryGraph_SetTimeZoom(uint16_t screen_id, uint16_t control_id, uint16_t zoom, uint16_t max_zoom, uint16_t min_zoom) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x63); + TX_16(screen_id); + TX_16(control_id); + TX_8(0x02); + TX_16(zoom); + TX_16(max_zoom); + TX_16(min_zoom); + END_CMD(); +} + +#endif + +#if SD_FILE_EN +/*! + * \brief 检测SD卡是否插入 + */ +void SD_IsInsert(void) +{ + BEGIN_CMD(); + TX_8(0x36); + TX_8(0x01); + END_CMD(); +} +/*! + * \brief 打开或创建文件 + * \param filename 文件名称(仅ASCII编码) + * \param mode 模式,可选组合模式如上FA_XXXX + */ +void SD_CreateFile(uint8_t *filename, uint8_t mode) +{ + BEGIN_CMD(); + TX_8(0x36); + TX_8(0x05); + TX_8(mode); + SendStrings(filename); + END_CMD(); +} +/*! + * \brief 以当前时间创建文件,例如:20161015083000.txt + * \param ext 文件后缀,例如 txt + */ +void SD_CreateFileByTime(uint8_t *ext) +{ + BEGIN_CMD(); + TX_8(0x36); + TX_8(0x02); + SendStrings(ext); + END_CMD(); +} +/*! + * \brief 在当前文件末尾写入数据 + * \param buffer 数据 + * \param dlc 数据长度 + */ +void SD_WriteFile(uint8_t *buffer, uint16_t dlc) +{ + BEGIN_CMD(); + TX_8(0x36); + TX_8(0x03); + TX_16(dlc); + TX_8N(buffer, dlc); + END_CMD(); +} +/*! + * \brief 读取当前文件 + * \param offset 文件位置偏移 + * \param dlc 数据长度 + */ +void SD_ReadFile(uint32_t offset, uint16_t dlc) +{ + BEGIN_CMD(); + TX_8(0x36); + TX_8(0x07); + TX_32(offset); + TX_16(dlc); + END_CMD(); +} + +/*! + * \brief 获取当前文件长度 + */ +void SD_GetFileSize() +{ + BEGIN_CMD(); + TX_8(0x36); + TX_8(0x06); + END_CMD(); +} +/*! + * \brief 关闭当前文件 + */ +void SD_CloseFile() +{ + BEGIN_CMD(); + TX_8(0x36); + TX_8(0x04); + END_CMD(); +} + +#endif // SD_FILE_EN +/*! + * \brief 记录控件-触发警告 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 告警值 + * \param time 告警产生的时间,为0时使用屏幕内部时间 + */ +void Record_SetEvent(uint16_t screen_id, uint16_t control_id, uint16_t value, uint8_t *time) +{ + uint8_t i = 0; + + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x50); + TX_16(screen_id); + TX_16(control_id); + TX_16(value); + + if (time) + { + for (i = 0; i < 7; ++i) + TX_8(time[i]); + } + + END_CMD(); +} +/*! + * \brief 记录控件-解除警告 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 告警值 + * \param time 告警解除的时间,为0时使用屏幕内部时间 + */ +void Record_ResetEvent(uint16_t screen_id, uint16_t control_id, uint16_t value, uint8_t *time) +{ + uint8_t i = 0; + + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x51); + TX_16(screen_id); + TX_16(control_id); + TX_16(value); + + if (time) + { + for (i = 0; i < 7; ++i) + TX_8(time[i]); + } + + END_CMD(); +} +/*! + * \brief 记录控件- 添加常规记录 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param record 一条记录(字符串),子项通过分号隔开,例如:第一项;第二项;第三项; + */ +void Record_Add(uint16_t screen_id, uint16_t control_id, uint8_t *record) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x52); + TX_16(screen_id); + TX_16(control_id); + + SendStrings(record); + + END_CMD(); +} +/*! + * \brief 记录控件-清除记录数据 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void Record_Clear(uint16_t screen_id, uint16_t control_id) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x53); + TX_16(screen_id); + TX_16(control_id); + END_CMD(); +} +/*! + * \brief 记录控件-设置记录显示偏移 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param offset 显示偏移,滚动条位置 + */ +void Record_SetOffset(uint16_t screen_id, uint16_t control_id, uint16_t offset) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x54); + TX_16(screen_id); + TX_16(control_id); + TX_16(offset); + END_CMD(); +} +/*! + * \brief 记录控件-获取当前记录数目 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void Record_GetCount(uint16_t screen_id, uint16_t control_id) +{ + BEGIN_CMD(); + TX_8(0xB1); + TX_8(0x55); + TX_16(screen_id); + TX_16(control_id); + END_CMD(); +} +/*! + * \brief 读取屏幕RTC时间 + */ +void ReadRTC(void) +{ + BEGIN_CMD(); + TX_8(0x82); + END_CMD(); +} + +/*! + * \brief 播放音乐 + * \param buffer 十六进制的音乐路径及名字 + */ +void PlayMusic(uint8_t *buffer) +{ + uint8_t i = 0; + + BEGIN_CMD(); + if (buffer) + { + for (i = 0; i < 19; ++i) + TX_8(buffer[i]); + } + END_CMD(); +} diff --git a/mkrtos_user/server/app/hmi_lcd/hmi_driver.h b/mkrtos_user/server/app/hmi_lcd/hmi_driver.h new file mode 100644 index 000000000..36d41979d --- /dev/null +++ b/mkrtos_user/server/app/hmi_lcd/hmi_driver.h @@ -0,0 +1,921 @@ +/*! + * \file hmi_driver.h + * \brief 串口屏驱动文件 + * \version 1.0 + * \date 2012-2018 + * \copyright 广州大彩光电科技有限公司 + */ + +#ifndef _HMI_DRIVER_ +#define _HMI_DRIVER_ + +#define FIRMWARE_VER 921 // 保持此固件版本号与真实屏幕一致,确保新增功能可用 +#define CRC16_ENABLE 1 // 如果需要CRC16校验功能,修改此宏为1(此时需要在VisualTFT工程中配CRC校验) +#define CMD_MAX_SIZE 128 // 单条指令大小,根据需要调整,尽量设置大一些 +#define QUEUE_MAX_SIZE 512 // 指令接收缓冲区大小,根据需要调整,尽量设置大一些 + +#define SD_FILE_EN 0 + +#include "hmi_user_uart.h" + +/*! + * \brief 检查数据是否符合CRC16校验 + * \param buffer 待校验的数据,末尾存储CRC16 + * \param n 数据长度,包含CRC16 + * \return 校验通过返回1,否则返回0 + */ +uint16_t CheckCRC16(uint8_t *buffer, uint16_t n); + +/*! + * \brief 延时 + * \param n 延时时间(毫秒单位) + */ +void DelayMS(unsigned int n); + +/*! + * \brief 锁定设备配置,锁定之后需要解锁,才能修改波特率、触摸屏、蜂鸣器工作方式 + */ +void LockDeviceConfig(void); + +/*! + * \brief 解锁设备配置 + */ +void UnlockDeviceConfig(void); + +/*! +* \brief 修改串口屏的波特率 +* \details 波特率选项范围[0~14],对应实际波特率 +{1200,2400,4800,9600,19200,38400,57600,115200,1000000,2000000,218750,437500,875000,921800,2500000} +* \param option 波特率选项 +*/ +void SetCommBps(uint8_t option); + +/*! + * \brief 发送握手命令 + */ +void SetHandShake(void); + +/*! + * \brief 设置前景色 + * \param color 前景色 + */ +void SetFcolor(uint16_t color); + +/*! + * \brief 设置背景色 + * \param color 背景色 + */ +void SetBcolor(uint16_t color); + +/*! + * \brief 清除画面 + */ +void GUI_CleanScreen(void); + +/*! + * \brief 设置文字间隔 + * \param x_w 横向间隔 + * \param y_w 纵向间隔 + */ +void SetTextSpace(uint8_t x_w, uint8_t y_w); + +/*! + * \brief 设置文字显示限制 + * \param enable 是否启用限制 + * \param width 宽度 + * \param height 高度 + */ +void SetFont_Region(uint8_t enable, uint16_t width, uint16_t height); + +/*! + * \brief 设置过滤色 + * \param fillcolor_dwon 颜色下界 + * \param fillcolor_up 颜色上界 + */ +void SetFilterColor(uint16_t fillcolor_dwon, uint16_t fillcolor_up); + +/*! + * \brief 设置过滤色 + * \param x 位置X坐标 + * \param y 位置Y坐标 + * \param back 颜色上界 + * \param font 字体 + * \param strings 字符串内容 + */ +void DisText(uint16_t x, uint16_t y, uint8_t back, uint8_t font, uint8_t *strings); + +/*! + * \brief 显示光标 + * \param enable 是否显示 + * \param x 位置X坐标 + * \param y 位置Y坐标 + * \param width 宽度 + * \param height 高度 + */ +void DisCursor(uint8_t enable, uint16_t x, uint16_t y, uint8_t width, uint8_t height); + +/*! + * \brief 显示全屏图片 + * \param image_id 图片索引 + * \param masken 是否启用透明掩码 + */ +void DisFull_Image(uint16_t image_id, uint8_t masken); + +/*! + * \brief 指定位置显示图片 + * \param x 位置X坐标 + * \param y 位置Y坐标 + * \param image_id 图片索引 + * \param masken 是否启用透明掩码 + */ +void DisArea_Image(uint16_t x, uint16_t y, uint16_t image_id, uint8_t masken); + +/*! + * \brief 显示裁剪图片 + * \param x 位置X坐标 + * \param y 位置Y坐标 + * \param image_id 图片索引 + * \param image_x 图片裁剪位置X坐标 + * \param image_y 图片裁剪位置Y坐标 + * \param image_l 图片裁剪长度 + * \param image_w 图片裁剪高度 + * \param masken 是否启用透明掩码 + */ +void DisCut_Image(uint16_t x, uint16_t y, uint16_t image_id, uint16_t image_x, uint16_t image_y, + uint16_t image_l, uint16_t image_w, uint8_t masken); + +/*! + * \brief 显示GIF动画 + * \param x 位置X坐标 + * \param y 位置Y坐标 + * \param flashimage_id 图片索引 + * \param enable 是否显示 + * \param playnum 播放次数 + */ +void DisFlashImage(uint16_t x, uint16_t y, uint16_t flashimage_id, uint8_t enable, uint8_t playnum); + +/*! + * \brief 画点 + * \param x 位置X坐标 + * \param y 位置Y坐标 + */ +void GUI_Dot(uint16_t x, uint16_t y); + +/*! + * \brief 画线 + * \param x0 起始位置X坐标 + * \param y0 起始位置Y坐标 + * \param x1 结束位置X坐标 + * \param y1 结束位置Y坐标 + */ +void GUI_Line(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); + +/*! + * \brief 画折线 + * \param mode 模式 + * \param dot 数据点 + * \param dot_cnt 点数 + */ +void GUI_ConDots(uint8_t mode, uint16_t *dot, uint16_t dot_cnt); + +/*! + * \brief 画空心圆 + * \param x0 圆心位置X坐标 + * \param y0 圆心位置Y坐标 + * \param r 半径 + */ +void GUI_Circle(uint16_t x0, uint16_t y0, uint16_t r); + +/*! + * \brief 画实心圆 + * \param x0 圆心位置X坐标 + * \param y0 圆心位置Y坐标 + * \param r 半径 + */ +void GUI_CircleFill(uint16_t x0, uint16_t y0, uint16_t r); + +/*! + * \brief 画弧线 + * \param x0 圆心位置X坐标 + * \param y0 圆心位置Y坐标 + * \param r 半径 + * \param sa 起始角度 + * \param ea 终止角度 + */ +void GUI_Arc(uint16_t x, uint16_t y, uint16_t r, uint16_t sa, uint16_t ea); + +/*! + * \brief 画空心矩形 + * \param x0 起始位置X坐标 + * \param y0 起始位置Y坐标 + * \param x1 结束位置X坐标 + * \param y1 结束位置Y坐标 + */ +void GUI_Rectangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); + +/*! + * \brief 画实心矩形 + * \param x0 起始位置X坐标 + * \param y0 起始位置Y坐标 + * \param x1 结束位置X坐标 + * \param y1 结束位置Y坐标 + */ +void GUI_RectangleFill(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); + +/*! + * \brief 画空心椭圆 + * \param x0 起始位置X坐标 + * \param y0 起始位置Y坐标 + * \param x1 结束位置X坐标 + * \param y1 结束位置Y坐标 + */ +void GUI_Ellipse(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); + +/*! + * \brief 画实心椭圆 + * \param x0 起始位置X坐标 + * \param y0 起始位置Y坐标 + * \param x1 结束位置X坐标 + * \param y1 结束位置Y坐标 + */ +void GUI_EllipseFill(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); + +/*! + * \brief 画线 + * \param x0 起始位置X坐标 + * \param y0 起始位置Y坐标 + * \param x1 结束位置X坐标 + * \param y1 结束位置Y坐标 + */ +void SetBackLight(uint8_t light_level); + +/*! + * \brief 蜂鸣器设置 + * \time time 持续时间(毫秒单位) + */ +void SetBuzzer(uint8_t time); + +/*! + * \brief 触摸屏设置 + * \param enable 触摸使能 + * \param beep_on 触摸蜂鸣器 + * \param work_mode 触摸工作模式:0按下就上传,1松开才上传,2不断上传坐标值,3按下和松开均上传数据 + * \param press_calibration 连续点击触摸屏20下校准触摸屏:0禁用,1启用 + */ +void SetTouchPaneOption(uint8_t enbale, uint8_t beep_on, uint8_t work_mode, uint8_t press_calibration); + +/*! + * \brief 校准触摸屏 + */ +void CalibrateTouchPane(void); + +/*! + * \brief 触摸屏测试 + */ +void TestTouchPane(void); + +/*! + * \brief 设置当前写入图层 + * \details 一般用于实现双缓存效果(绘图时避免闪烁): + * \details uint8_t layer = 0; + * \details WriteLayer(layer); 设置写入层 + * \details ClearLayer(layer); 使图层变透明 + * \details 添加一系列绘图指令 + * \details DisText(100,100,0,4,"hello hmi!!!"); + * \details DisplyLayer(layer); 切换显示层 + * \details layer = (layer+1)%2; 双缓存切换 + * \see DisplyLayer + * \see ClearLayer + * \param layer 图层编号 + */ +void WriteLayer(uint8_t layer); + +/*! + * \brief 设置当前显示图层 + * \param layer 图层编号 + */ +void DisplyLayer(uint8_t layer); + +/*! + * \brief 清除图层,使图层变成透明 + * \param layer 图层编号 + */ +void ClearLayer(uint8_t layer); + +/*! + * \brief 写数据到串口屏用户存储区 + * \param startAddress 起始地址 + * \param length 字节数 + * \param _data 待写入的数据 + */ +void WriteUserFlash(uint32_t startAddress, uint16_t length, uint8_t *_data); + +/*! + * \brief 从串口屏用户存储区读取数据 + * \param startAddress 起始地址 + * \param length 字节数 + */ +void ReadUserFlash(uint32_t startAddress, uint16_t length); + +/*! + * \brief 拷贝图层 + * \param src_layer 原始图层 + * \param dest_layer 目标图层 + */ +void CopyLayer(uint8_t src_layer, uint8_t dest_layer); + +/*! + * \brief 设置当前画面 + * \param screen_id 画面ID + */ +void SetScreen(uint16_t screen_id); + +/*! + * \brief 获取当前画面 + */ +void GetScreen(uint16_t screen_id); + +/*! + * \brief 禁用\启用画面更新 + * \details 禁用\启用一般成对使用,用于避免闪烁、提高刷新速度 + * \details 用法: + * \details SetScreenUpdateEnable(0);//禁止更新 + * \details 一系列更新画面的指令 + * \details SetScreenUpdateEnable(1);//立即更新 + * \param enable 0禁用,1启用 + */ +void SetScreenUpdateEnable(uint8_t enable); + +/*! + * \brief 设置控件输入焦点 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param focus 是否具有输入焦点 + */ +void SetControlFocus(uint16_t screen_id, uint16_t control_id, uint8_t focus); + +/*! + * \brief 显示\隐藏控件 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param visible 是否显示 + */ +void SetControlVisiable(uint16_t screen_id, uint16_t control_id, uint8_t visible); + +/*! + * \brief 设置触摸控件使能 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param enable 控件是否使能 + */ +void SetControlEnable(uint16_t screen_id, uint16_t control_id, uint8_t enable); + +/*! + * \brief 获取控件值 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void GetControlValue(uint16_t screen_id, uint16_t control_id); + +/*! + * \brief 设置按钮状态 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 按钮状态 + */ +void SetButtonValue(uint16_t screen_id, uint16_t control_id, uint8_t value); + +/*! + * \brief 设置文本值 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param str 文本值 + */ +void SetTextValue(uint16_t screen_id, uint16_t control_id, uint8_t *str); + +#if FIRMWARE_VER >= 908 + +/*! + * \brief 设置文本为整数值,要求FIRMWARE_VER>=908 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 文本数值 + * \param sign 0-无符号,1-有符号 + * \param fill_zero 数字位数,不足时左侧补零 + */ +void SetTextInt32(uint16_t screen_id, uint16_t control_id, int32_t value, uint8_t sign, uint8_t fill_zero); + +/*! + * \brief 设置文本单精度浮点值,要求FIRMWARE_VER>=908 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 文本数值 + * \param precision 小数位数 + * \param show_zeros 为1时,显示末尾0 + */ +void SetTextFloat(uint16_t screen_id, uint16_t control_id, float value, uint8_t precision, uint8_t show_zeros); + +#endif + +/*! + * \brief 设置进度值 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 数值 + */ +void SetProgressValue(uint16_t screen_id, uint16_t control_id, uint32_t value); + +/*! + * \brief 设置仪表值 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 数值 + */ +void SetMeterValue(uint16_t screen_id, uint16_t control_id, uint32_t value); + +/*! + * \brief 设置仪表值 + * \param screen_id 画面ID + * \param control_id 图片控件ID + * \param value 数值 + */ +void Set_picMeterValue(uint16_t screen_id, uint16_t control_id, uint16_t value); + +/*! + * \brief 设置滑动条 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 数值 + */ + +void SetSliderValue(uint16_t screen_id, uint16_t control_id, uint32_t value); + +void SetSliderRangValue(uint16_t screen_id, uint16_t control_id, uint32_t start, uint32_t end); +/*! + * \brief 设置选择控件 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param item 当前选项 + */ +void SetSelectorValue(uint16_t screen_id, uint16_t control_id, uint8_t item); + +/*! + * \brief 开始播放动画 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void AnimationStart(uint16_t screen_id, uint16_t control_id); + +/*! + * \brief 停止播放动画 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void AnimationStop(uint16_t screen_id, uint16_t control_id); + +/*! + * \brief 暂停播放动画 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void AnimationPause(uint16_t screen_id, uint16_t control_id); + +/*! + * \brief 播放制定帧 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param frame_id 帧ID + */ +void AnimationPlayFrame(uint16_t screen_id, uint16_t control_id, uint8_t frame_id); + +/*! + * \brief 播放上一帧 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void AnimationPlayPrev(uint16_t screen_id, uint16_t control_id); + +/*! + * \brief 播放下一帧 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void AnimationPlayNext(uint16_t screen_id, uint16_t control_id); + +/*! + * \brief 曲线控件-添加通道 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param channel 通道号 + * \param color 颜色 + */ +void GraphChannelAdd(uint16_t screen_id, uint16_t control_id, uint8_t channel, uint16_t color); + +/*! + * \brief 曲线控件-删除通道 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param channel 通道号 + */ +void GraphChannelDel(uint16_t screen_id, uint16_t control_id, uint8_t channel); + +/*! + * \brief 曲线控件-添加数据 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param channel 通道号 + * \param pData 曲线数据 + * \param nDataLen 数据个数 + */ +void GraphChannelDataAdd(uint16_t screen_id, uint16_t control_id, uint8_t channel, uint8_t *pData, uint16_t nDataLen); + +/*! + * \brief 曲线控件-清除数据 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param channel 通道号 + */ +void GraphChannelDataClear(uint16_t screen_id, uint16_t control_id, uint8_t channel); + +/*! + * \brief 曲线控件-设置视图窗口 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param x_offset 水平偏移 + * \param x_mul 水平缩放系数 + * \param y_offset 垂直偏移 + * \param y_mul 垂直缩放系数 + */ +void GraphSetViewport(uint16_t screen_id, uint16_t control_id, int16_t x_offset, uint16_t x_mul, int16_t y_offset, uint16_t y_mul); + +/*! + * \brief 开始批量更新 + * \param screen_id 画面ID + */ +void BatchBegin(uint16_t screen_id); + +/*! + * \brief 批量更新按钮控件 + * \param control_id 控件ID + * \param value 数值 + */ +void BatchSetButtonValue(uint16_t control_id, uint8_t state); + +/*! + * \brief 批量更新进度条控件 + * \param control_id 控件ID + * \param value 数值 + */ +void BatchSetProgressValue(uint16_t control_id, uint32_t value); + +/*! + * \brief 批量更新滑动条控件 + * \param control_id 控件ID + * \param value 数值 + */ +void BatchSetSliderValue(uint16_t control_id, uint32_t value); + +/*! + * \brief 批量更新仪表控件 + * \param control_id 控件ID + * \param value 数值 + */ +void BatchSetMeterValue(uint16_t control_id, uint32_t value); + +/*! + * \brief 计算字符串长度 + */ +uint32_t GetStringLen(uint8_t *str); + +/*! + * \brief 批量更新文本控件 + * \param control_id 控件ID + * \param strings 字符串 + */ +void BatchSetText(uint16_t control_id, uint8_t *strings); + +/*! + * \brief 批量更新动画\图标控件 + * \param control_id 控件ID + * \param frame_id 帧ID + */ +void BatchSetFrame(uint16_t control_id, uint16_t frame_id); + +#if FIRMWARE_VER >= 921 + +/*! + * \brief 批量设置控件可见 + * \param control_id 控件ID + * \param visible 帧ID + */ +void BatchSetVisible(uint16_t control_id, uint8_t visible); + +/*! + * \brief 批量设置控件使能 + * \param control_id 控件ID + * \param enable 帧ID + */ +void BatchSetEnable(uint16_t control_id, uint8_t enable); + +#endif + +/*! + * \brief 结束批量更新 + */ +void BatchEnd(void); + +/*! + * \brief 设置倒计时控件 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param timeout 倒计时(秒) + */ +void SeTimer(uint16_t screen_id, uint16_t control_id, uint32_t timeout); + +/*! + * \brief 开启倒计时控件 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void StartTimer(uint16_t screen_id, uint16_t control_id); + +/*! + * \brief 停止倒计时控件 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void StopTimer(uint16_t screen_id, uint16_t control_id); + +/*! + * \brief 暂停倒计时控件 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void PauseTimer(uint16_t screen_id, uint16_t control_id); + +/*! + * \brief 设置控件背景色 + * \details 支持控件:进度条、文本 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param color 背景色 + */ +void SetControlBackColor(uint16_t screen_id, uint16_t control_id, uint16_t color); + +/*! + * \brief 设置控件前景色 + * \details 支持控件:进度条 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param color 前景色 + */ +void SetControlForeColor(uint16_t screen_id, uint16_t control_id, uint16_t color); + +/*! + * \brief 显示\隐藏弹出菜单控件 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param show 是否显示,为0时focus_control_id无效 + * \param focus_control_id 关联的文本控件(菜单控件的内容输出到文本控件) + */ +void ShowPopupMenu(uint16_t screen_id, uint16_t control_id, uint8_t show, uint16_t focus_control_id); + +/*! + * \brief 显示\隐藏系统键盘 + * \param show 0隐藏,1显示 + * \param x 键盘显示位置X坐标 + * \param y 键盘显示位置Y坐标 + * \param type 0小键盘,1全键盘 + * \param option 0正常字符,1密码,2时间设置 + * \param max_len 键盘录入字符长度限制 + */ +void ShowKeyboard(uint8_t show, uint16_t x, uint16_t y, uint8_t type, uint8_t option, uint8_t max_len); + +#if FIRMWARE_VER >= 914 +/*! + * \brief 多语言设置 + * \param ui_lang 用户界面语言0~9 + * \param sys_lang 系统键盘语言-0中文,1英文 + */ +void SetLanguage(uint8_t ui_lang, uint8_t sys_lang); +#endif + +#if FIRMWARE_VER >= 917 +/*! + * \brief 开始保存控件数值到FLASH + * \param version 数据版本号,可任意指定,高16位为主版本号,低16位为次版本号 + * \param address 数据在用户存储区的存放地址,注意防止地址重叠、冲突 + */ +void FlashBeginSaveControl(uint32_t version, uint32_t address); + +/*! + * \brief 保存某个控件的数值到FLASH + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void FlashSaveControl(uint16_t screen_id, uint16_t control_id); + +/*! + * \brief 保存结束 + */ +void FlashEndSaveControl(void); + +/*! + * \brief 从FLASH中恢复控件数据 + * \param version 数据版本号,主版本号必须与存储时一致,否则会加载失败 + * \param address 数据在用户存储区的存放地址 + */ +void FlashRestoreControl(uint32_t version, uint32_t address); +#endif + +#if FIRMWARE_VER >= 921 +/*! + * \brief 设置历史曲线采样数据值(单字节,uint8_t或int8) + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 采样点数据 + * \param channel 通道数 + */ +void HistoryGraph_SetValueInt8(uint16_t screen_id, uint16_t control_id, uint8_t *value, uint8_t channel); + +/*! + * \brief 设置历史曲线采样数据值(双字节,uint16_t或int16) + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 采样点数据 + * \param channel 通道数 + */ +void HistoryGraph_SetValueInt16(uint16_t screen_id, uint16_t control_id, uint16_t *value, uint8_t channel); + +/*! + * \brief 设置历史曲线采样数据值(四字节,uint32_t或int32) + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 采样点数据 + * \param channel 通道数 + */ +void HistoryGraph_SetValueInt32(uint16_t screen_id, uint16_t control_id, uint32_t *value, uint8_t channel); + +/*! + * \brief 设置历史曲线采样数据值(单精度浮点数) + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 采样点数据 + * \param channel 通道数 + */ +void HistoryGraph_SetValueFloat(uint16_t screen_id, uint16_t control_id, float *value, uint8_t channel); + +/*! + * \brief 允许或禁止历史曲线采样 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param enable 0-禁止,1-允许 + */ +void HistoryGraph_EnableSampling(uint16_t screen_id, uint16_t control_id, uint8_t enable); + +/*! + * \brief 显示或隐藏历史曲线通道 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param channel 通道编号 + * \param show 0-隐藏,1-显示 + */ +void HistoryGraph_ShowChannel(uint16_t screen_id, uint16_t control_id, uint8_t channel, uint8_t show); + +/*! + * \brief 设置历史曲线时间长度(即采样点数) + * \param screen_id 画面ID + * \param control_id 控件ID + * \param sample_count 一屏显示的采样点数 + */ +void HistoryGraph_SetTimeLength(uint16_t screen_id, uint16_t control_id, uint16_t sample_count); + +/*! + * \brief 历史曲线缩放到全屏 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void HistoryGraph_SetTimeFullScreen(uint16_t screen_id, uint16_t control_id); + +/*! + * \brief 设置历史曲线缩放比例系数 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param zoom 缩放百分比(zoom>100%时水平方向缩小,反正放大) + * \param max_zoom 缩放限制,一屏最多显示采样点数 + * \param min_zoom 缩放限制,一屏最少显示采样点数 + */ +void HistoryGraph_SetTimeZoom(uint16_t screen_id, uint16_t control_id, uint16_t zoom, uint16_t max_zoom, uint16_t min_zoom); +#endif + +#if SD_FILE_EN +/*! + * \brief 检测SD卡是否插入 + */ +void SD_IsInsert(void); + +#define FA_READ 0x01 // 可读取 +#define FA_WRITE 0x02 // 可写入 +#define FA_CREATE_NEW 0x04 // 创建新文件,如果文件已经存在,则返回失败 +#define FA_CREATE_ALWAYS 0x08 // 创建新文件,如果文件已经存在,则覆盖 +#define FA_OPEN_EXISTING 0x00 // 打开文件,如果文件不存在,则返回失败 +#define FA_OPEN_ALWAYS 0x10 // 打开文件,如果文件不存在,则创建新文件 + +/*! + * \brief 打开或创建文件 + * \param filename 文件名称(仅ASCII编码) + * \param mode 模式,可选组合模式如上FA_XXXX + */ +void SD_CreateFile(uint8_t *filename, uint8_t mode); + +/*! + * \brief 以当前时间创建文件,例如:20161015083000.txt + * \param ext 文件后缀,例如 txt + */ +void SD_CreateFileByTime(uint8_t *ext); + +/*! + * \brief 在当前文件末尾写入数据 + * \param buffer 数据 + * \param dlc 数据长度 + */ +void SD_WriteFile(uint8_t *buffer, uint16_t dlc); + +/*! + * \brief 读取当前文件 + * \param offset 文件位置偏移 + * \param dlc 数据长度 + */ +void SD_ReadFile(uint32_t offset, uint16_t dlc); + +/*! + * \brief 获取当前文件长度 + */ +void SD_GetFileSize(); + +/*! + * \brief 关闭当前文件 + */ +void SD_CloseFile(); +#endif + +/*! + * \brief 记录控件-触发警告 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 告警值 + * \param time 告警产生的时间,为0时使用屏幕内部时间 + */ +void Record_SetEvent(uint16_t screen_id, uint16_t control_id, uint16_t value, uint8_t *time); + +/*! + * \brief 记录控件-解除警告 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param value 告警值 + * \param time 告警解除的时间,为0时使用屏幕内部时间 + */ +void Record_ResetEvent(uint16_t screen_id, uint16_t control_id, uint16_t value, uint8_t *time); + +/*! + * \brief 记录控件- 添加常规记录 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param record 一条记录(字符串),子项通过分号隔开,例如:第一项;第二项;第三项; + */ +void Record_Add(uint16_t screen_id, uint16_t control_id, uint8_t *record); + +/*! + * \brief 记录控件-清除记录数据 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void Record_Clear(uint16_t screen_id, uint16_t control_id); + +/*! + * \brief 记录控件-设置记录显示偏移 + * \param screen_id 画面ID + * \param control_id 控件ID + * \param offset 显示偏移,滚动条位置 + */ +void Record_SetOffset(uint16_t screen_id, uint16_t control_id, uint16_t offset); + +/*! + * \brief 记录控件-获取当前记录数目 + * \param screen_id 画面ID + * \param control_id 控件ID + */ +void Record_GetCount(uint16_t screen_id, uint16_t control_id); + +/*! + * \brief 读取屏幕RTC时间 + */ +void ReadRTC(void); + +/*! + * \brief 播放音乐 + * \param buffer 十六进制的音乐路径及名字 + */ +void PlayMusic(uint8_t *buffer); + +#endif //_HMI_DRIVER_ diff --git a/mkrtos_user/server/app/hmi_lcd/hmi_lcd_process.c b/mkrtos_user/server/app/hmi_lcd/hmi_lcd_process.c new file mode 100644 index 000000000..8bd89b4ca --- /dev/null +++ b/mkrtos_user/server/app/hmi_lcd/hmi_lcd_process.c @@ -0,0 +1,580 @@ + + +// #include "hmi_lcd_process.h" +// #include "stm32_sys.h" +// // #include "tim3.h" +// #include "sysinfo.h" +// // #include "save_info.h" +// #include "led.h" +// #include "relay.h" +// // #include "music_control.h" +// #include "auto_close.h" +// #include "u_sys.h" +// #include "led.h" +// #include +// #include + +// // 刷新时间 +// #define HIM_LCD_TIME_100MS 200 +// // LCD串口接收BUF +// uint8_t cmd_buffer[CMD_MAX_SIZE]; // 指令缓存 + +// /*! +// * \brief 消息处理流程 +// * \param msg 待处理消息 +// * \param size 消息长度 +// */ +// void ProcessMessage(PCTRL_MSG msg, uint16_t size) +// { +// uint8_t cmd_type = msg->cmd_type; // 指令类型 +// uint8_t ctrl_msg = msg->ctrl_msg; // 消息的类型 +// uint8_t control_type = msg->control_type; // 控件类型 +// uint16_t screen_id = PTR2U16(&msg->screen_id); // 画面ID +// uint16_t control_id = PTR2U16(&msg->control_id); // 控件ID +// uint32_t value = PTR2U32(msg->param); // 数值 +// switch (cmd_type) +// { +// case NOTIFY_TOUCH_PRESS: // 触摸屏按下 +// case NOTIFY_TOUCH_RELEASE: // 触摸屏松开 +// NotifyTouchXY(cmd_buffer[1], PTR2U16(cmd_buffer + 2), PTR2U16(cmd_buffer + 4)); +// break; +// case NOTIFY_WRITE_FLASH_OK: // 写FLASH成功 +// NotifyWriteFlash(1); +// break; +// case NOTIFY_WRITE_FLASH_FAILD: // 写FLASH失败 +// NotifyWriteFlash(0); +// break; +// case NOTIFY_READ_FLASH_OK: // 读取FLASH成功 +// NotifyReadFlash(1, cmd_buffer + 2, size - 6); // 去除帧头帧尾 +// break; +// case NOTIFY_READ_FLASH_FAILD: // 读取FLASH失败 +// NotifyReadFlash(0, 0, 0); +// break; +// case NOTIFY_READ_RTC: // 读取RTC时间 +// NotifyReadRTC(cmd_buffer[2], cmd_buffer[3], cmd_buffer[4], cmd_buffer[5], cmd_buffer[6], cmd_buffer[7], cmd_buffer[8]); +// break; +// case NOTIFY_CONTROL: +// { +// if (ctrl_msg == MSG_GET_CURRENT_SCREEN) // 画面ID变化通知 +// { +// NotifyScreen(screen_id); // 画面切换调动的函数 +// } +// else +// { +// switch (control_type) +// { +// case kCtrlButton: // 按钮控件 +// NotifyButton(screen_id, control_id, msg->param[1]); +// break; +// case kCtrlText: // 文本控件 +// NotifyText(screen_id, control_id, msg->param); +// break; +// case kCtrlProgress: // 进度条控件 +// NotifyProgress(screen_id, control_id, value); +// break; +// case kCtrlSlider: // 滑动条控件 +// NotifySlider(screen_id, control_id, value); +// break; +// case kCtrlMeter: // 仪表控件 +// NotifyMeter(screen_id, control_id, value); +// break; +// case kCtrlMenu: // 菜单控件 +// NotifyMenu(screen_id, control_id, msg->param[0], msg->param[1]); +// break; +// case kCtrlSelector: // 选择控件 +// NotifySelector(screen_id, control_id, msg->param[0]); +// break; +// case kCtrlRTC: // 倒计时控件 +// NotifyTimer(screen_id, control_id); +// break; +// default: +// break; +// } +// } +// break; +// } +// case NOTIFY_HandShake: // 握手通知 +// NOTIFYHandShake(); +// break; +// default: +// break; +// } +// } + +// void LCD_SW_2PAGE() +// { +// SetTextInt32(1, 2, sys_info.target_val, 1, 0); +// SetTextInt32(1, 15, sys_info.netID, 1, 0); +// SetTextInt32(1, 20, sys_info.devID, 1, 0); +// SetTextInt32(1, 32, sys_info.auto_ctrl_tick[0] / 1000 / 10, 1, 0); +// SetTextInt32(1, 33, sys_info.auto_ctrl_tick[1] / 1000 / 10, 1, 0); +// SetTextInt32(1, 35, sys_info.auto_ctrl_tick[2] / 1000 / 10, 1, 0); +// SetTextInt32(1, 34, sys_info.auto_ctrl_tick[3] / 1000 / 10, 1, 0); +// SetTextInt32(1, 11, sys_info.auto_ctrl_tick[4] / 1000 / 10, 1, 0); +// SetTextInt32(1, 14, sys_info.auto_ctrl_tick[5] / 1000 / 10, 1, 0); +// } +// /*! +// * \brief 握手通知 +// */ +// void NOTIFYHandShake() +// { +// } + +// /*! +// * \brief 画面切换通知 +// * \details 当前画面改变时(或调用GetScreen),执行此函数 +// * \param screen_id 当前画面ID +// */ +// void NotifyScreen(uint16_t screen_id) +// { +// } + +// /*! +// * \brief 触摸坐标事件响应 +// * \param press 1按下触摸屏,3松开触摸屏 +// * \param x x坐标 +// * \param y y坐标 +// */ +// void NotifyTouchXY(uint8_t press, uint16_t x, uint16_t y) +// { +// // TODO: 添加用户代码 +// } + +// void SilderSetValue(u8 index, u16 value) +// { +// } + +// void RelaySetButtonValue(u8 index, u8 value) +// { +// } +// static u32 timer_tick_last_ui_update = 0; + +// u8 up_down_flag[2] = {0}; + +// int ctrl_vs(int inx, int state) +// { +// switch (inx) +// { +// case 0: +// // delay_ms(500); +// // music_mode(0, ADUIO_DEV_MODE); +// relay_ctrl(0, state); +// break; +// case 1: +// relay_ctrl(1, state); +// break; +// case 2: +// relay_ctrl(2, state); +// break; +// case 3: +// relay_ctrl(3, state); +// break; +// case 4: +// relay_ctrl(4, state); +// break; +// case 5: +// break; +// } +// return 0; +// } +// int vis_vs(int inx, int state) +// { +// switch (inx) +// { +// case 0: +// SetButtonValue(0, 22, state); +// break; +// case 1: +// SetButtonValue(0, 23, state); +// break; +// case 2: +// SetButtonValue(0, 24, state); +// break; +// case 3: +// SetButtonValue(0, 36, state); +// break; +// case 4: +// SetButtonValue(0, 37, state); +// break; +// case 5: +// break; +// } +// return 0; +// } +// void LCD_init(void) +// { +// for (int i = 0; i < CTRL_IO_NUM; i++) +// { +// io_ctrl_reg(i, ctrl_vs, vis_vs); +// } +// } +// /*! +// * \brief 按钮控件通知 +// * \details 当按钮状态改变(或调用GetControlValue)时,执行此函数 +// * \param screen_id 画面ID +// * \param control_id 控件ID +// * \param state 按钮状态:0弹起,1按下 +// */ +// void NotifyButton(uint16_t screen_id, uint16_t control_id, uint8_t state) +// { + +// if (screen_id == 0) +// { +// switch (control_id) +// { +// case 22: +// io_ctrl(0, state); +// break; +// case 23: +// io_ctrl(1, state); +// break; +// case 24: +// io_ctrl(2, state); +// break; +// case 36: +// io_ctrl(3, state); +// break; +// case 37: +// io_ctrl(4, state); +// break; + +// case 25: // 模式 +// music_mode_next(0); +// break; +// case 26: // 上一曲 +// if (state == 0) +// { +// if (up_down_flag[0] == 0) +// { +// music_up(0); +// } +// else +// { +// up_down_flag[0] = 0; +// } +// } +// else if (state == 2) +// { +// music_volume_add(0); +// up_down_flag[0] = 1; +// } +// break; +// case 27: // 暂停 +// music_pause(0); +// break; +// case 28: // 下一曲 +// if (state == 0) +// { +// if (up_down_flag[0] == 0) +// { +// music_down(0); +// } +// else +// { +// up_down_flag[0] = 0; +// } +// } +// else if (state == 2) +// { +// music_volume_sub(0); +// up_down_flag[0] = 1; +// } +// break; +// case 125: // 模式 +// music_mode_next(1); +// break; +// case 126: // 上一曲 +// if (state == 0) +// { +// if (up_down_flag[1] == 0) +// { +// music_up(1); +// } +// else +// { +// up_down_flag[1] = 0; +// } +// } +// else if (state == 2) +// { +// music_volume_add(1); +// up_down_flag[1] = 1; +// } +// break; +// case 127: // 暂停 +// music_pause(1); +// break; +// case 128: // 下一曲 +// if (state == 0) +// { +// if (up_down_flag[1] == 0) +// { +// music_down(1); +// } +// else +// { +// up_down_flag[1] = 0; +// } +// } +// else if (state == 2) +// { +// music_volume_sub(1); +// up_down_flag[1] = 1; +// } +// break; +// case 52: +// LCD_SW_2PAGE(); +// break; +// } +// } +// else if (screen_id == 1) +// { +// switch (control_id) +// { +// case 16: + +// break; +// } +// } +// } + +// void NotifyText(uint16_t screen_id, uint16_t control_id, uint8_t *str) +// { +// if (screen_id == 1) +// { +// switch (control_id) +// { +// case 2: +// sys_info.target_val = atoi((char *)str); +// break; +// case 32: +// sys_info.auto_ctrl_tick[0] = atoi((char *)str) * 10 * 1000; +// break; +// case 33: +// sys_info.auto_ctrl_tick[1] = atoi((char *)str) * 10 * 1000; +// break; +// case 35: +// sys_info.auto_ctrl_tick[2] = atoi((char *)str) * 10 * 1000; +// break; +// case 34: +// sys_info.auto_ctrl_tick[3] = atoi((char *)str) * 10 * 1000; +// break; +// case 11: +// sys_info.auto_ctrl_tick[4] = atoi((char *)str) * 10 * 1000; +// break; +// case 14: +// sys_info.auto_ctrl_tick[5] = atoi((char *)str) * 10 * 1000; +// break; +// case 22: +// bluetooth_name_set(0, (char *)str); +// break; +// case 15: // 网络id +// sys_info.netID = atoi((char *)str); +// break; +// case 20: +// sys_info.devID = atoi((char *)str); +// break; +// } +// } +// sys_write_info(); +// } + +// /*! +// * \brief 进度条控件通知 +// * \details 调用GetControlValue时,执行此函数 +// * \param screen_id 画面ID +// * \param control_id 控件ID +// * \param value 值 +// */ +// void NotifyProgress(uint16_t screen_id, uint16_t control_id, uint32_t value) +// { +// // TODO: 添加用户代码 +// } + +// /*! +// * \brief 滑动条控件通知 +// * \details 当滑动条改变(或调用GetControlValue)时,执行此函数 +// * \param screen_id 画面ID +// * \param control_id 控件ID +// * \param value 值 +// */ +// void NotifySlider(uint16_t screen_id, uint16_t control_id, uint32_t value) +// { +// if (screen_id == 0) +// { +// if (control_id == 2) +// { /*音量*/ +// music_volume_set(0, value); +// } +// if (control_id == 129) +// { /*音量*/ +// music_volume_set(1, value); +// } +// } +// } + +// /*! +// * \brief 仪表控件通知 +// * \details 调用GetControlValue时,执行此函数 +// * \param screen_id 画面ID +// * \param control_id 控件ID +// * \param value 值 +// */ +// void NotifyMeter(uint16_t screen_id, uint16_t control_id, uint32_t value) +// { +// // TODO: 添加用户代码 +// } + +// /*! +// * \brief 菜单控件通知 +// * \details 当菜单项按下或松开时,执行此函数 +// * \param screen_id 画面ID +// * \param control_id 控件ID +// * \param item 菜单项索引 +// * \param state 按钮状态:0松开,1按下 +// */ +// void NotifyMenu(uint16_t screen_id, uint16_t control_id, uint8_t item, uint8_t state) +// { +// // TODO: 添加用户代码 +// } + +// /*! +// * \brief 选择控件通知 +// * \details 当选择控件变化时,执行此函数 +// * \param screen_id 画面ID +// * \param control_id 控件ID +// * \param item 当前选项 +// */ +// void NotifySelector(uint16_t screen_id, uint16_t control_id, uint8_t item) +// { +// } + +// /*! +// * \brief 定时器超时通知处理 +// * \param screen_id 画面ID +// * \param control_id 控件ID +// */ +// void NotifyTimer(uint16_t screen_id, uint16_t control_id) +// { +// } + +// /*! +// * \brief 读取用户FLASH状态返回 +// * \param status 0失败,1成功 +// * \param _data 返回数据 +// * \param length 数据长度 +// */ +// void NotifyReadFlash(uint8_t status, uint8_t *_data, uint16_t length) +// { +// // TODO: 添加用户代码 +// } + +// /*! +// * \brief 写用户FLASH状态返回 +// * \param status 0失败,1成功 +// */ +// void NotifyWriteFlash(uint8_t status) +// { +// // TODO: 添加用户代码 +// } + +// /*! +// * \brief 读取RTC时间,注意返回的是BCD码 +// * \param year 年(BCD) +// * \param month 月(BCD) +// * \param week 星期(BCD) +// * \param day 日(BCD) +// * \param hour 时(BCD) +// * \param minute 分(BCD) +// * \param second 秒(BCD) +// */ +// void NotifyReadRTC(uint8_t year, uint8_t month, uint8_t week, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) +// { +// // sec =(0xff & (second>>4))*10 +(0xf & second); //BCD码转十进制 +// // years =(0xff & (year>>4))*10 +(0xf & year); +// // months =(0xff & (month>>4))*10 +(0xf & month); +// // weeks =(0xff & (week>>4))*10 +(0xf & week); +// // days =(0xff & (day>>4))*10 +(0xf & day); +// // hours =(0xff & (hour>>4))*10 +(0xf & hour); +// // minutes =(0xff & (minute>>4))*10 +(0xf & minute); +// } + +// /*! +// * \brief 更新数据 +// */ +// void UpdateUI(void) +// { +// u16 show_val; +// u8 i = 0; +// int temp_val = 0; +// qsize size = 0; +// // 串口屏处理 +// size = queue_find_cmd(cmd_buffer, CMD_MAX_SIZE); // 从缓冲区中获取一条指令 +// if (size > 0) +// { +// ProcessMessage((PCTRL_MSG)cmd_buffer, size); // 指令处理 +// } +// if (sys_read_tick() - timer_tick_last_ui_update < +// HIM_LCD_TIME_100MS) +// { +// return; +// } + +// ////////////////////////////////////////////////////设置温度 +// temp_val = sys_info.temp[0]; +// temp_val = (((float)(temp_val + 40)) / 120.f) * 360; +// SetSliderValue(0, 7, temp_val); +// SetTextInt32(0, 20, sys_info.temp[0], 1, 0); // 设置文本值 + +// temp_val = sys_info.temp[1]; +// temp_val = (((float)(temp_val + 40)) / 120.f) * 360; +// SetSliderValue(0, 5, temp_val); +// SetTextInt32(0, 19, (sys_info.temp[1]), 1, 0); // 设置文本值 + +// temp_val = sys_info.temp[2]; +// temp_val = (((float)(temp_val + 40)) / 120.f) * 360; +// SetSliderValue(0, 4, temp_val); +// SetTextInt32(0, 18, (sys_info.temp[2]), 1, 0); // 设置文本值 + +// temp_val = sys_info.temp[3]; +// temp_val = (((float)(temp_val + 40)) / 120.f) * 360; +// SetSliderValue(0, 8, temp_val); +// SetTextInt32(0, 21, (sys_info.temp[3]), 1, 0); // 设置文本值 + +// /////////////////////////////////////////////////////设置噪声 +// temp_val = sys_info.noise[0]; +// temp_val = (((float)(temp_val)) / 140.f) * 360; +// SetSliderValue(0, 1, temp_val); +// SetTextInt32(0, 29, sys_info.noise[0], 1, 0); // 设置文本值 + +// temp_val = sys_info.noise[1]; +// temp_val = (((float)(temp_val)) / 140.f) * 360; +// SetSliderValue(0, 6, temp_val); +// SetTextInt32(0, 17, sys_info.noise[1], 1, 0); // 设置文本值 + +// temp_val = sys_info.noise[2]; +// temp_val = (((float)(temp_val)) / 140.f) * 360; +// SetSliderValue(0, 32, temp_val); +// SetTextInt32(0, 34, sys_info.noise[2], 1, 0); // 设置文本值 + +// /// 分贝温度 +// temp_val = sys_info.noise_temp[0]; +// temp_val = (((float)(temp_val + 40)) / 120.f) * 360; +// SetSliderValue(0, 44, temp_val); +// SetTextInt32(0, 53, (sys_info.noise_temp[0]), 1, 0); // 设置文本值 + +// temp_val = sys_info.noise_temp[1]; +// temp_val = (((float)(temp_val + 40)) / 120.f) * 360; +// SetSliderValue(0, 45, temp_val); +// SetTextInt32(0, 54, (sys_info.noise_temp[1]), 1, 0); // 设置文本值 + +// temp_val = sys_info.noise_temp[2]; +// temp_val = (((float)(temp_val + 40)) / 120.f) * 360; +// SetSliderValue(0, 39, temp_val); +// SetTextInt32(0, 41, (sys_info.noise_temp[2]), 1, 0); // 设置文本值 + +// // SetTextInt32(0, 100, ABS(sys_info.noise[0] - sys_info.noise[1]), 1, 0); + +// timer_tick_last_ui_update = sys_read_tick(); +// toogle_led_0(); +// } diff --git a/mkrtos_user/server/app/hmi_lcd/hmi_lcd_process.h b/mkrtos_user/server/app/hmi_lcd/hmi_lcd_process.h new file mode 100644 index 000000000..8e6644e3b --- /dev/null +++ b/mkrtos_user/server/app/hmi_lcd/hmi_lcd_process.h @@ -0,0 +1,13 @@ +#pragma once + +#include "hmi_driver.h" +#include "hmi_user_uart.h" +#include "cmd_queue.h" +#include "cmd_process.h" + +void SilderSetValue(u8 index, u16 value); +void RelaySetButtonValue(u8 index, u8 value); +void ProcessMessage(PCTRL_MSG msg, uint16_t size); +void UpdateUI(void); + +void LCD_init(void); diff --git a/mkrtos_user/server/app/hmi_lcd/hmi_user_uart.c b/mkrtos_user/server/app/hmi_lcd/hmi_user_uart.c new file mode 100644 index 000000000..6f43a754a --- /dev/null +++ b/mkrtos_user/server/app/hmi_lcd/hmi_user_uart.c @@ -0,0 +1,12 @@ +#include "hmi_user_uart.h" +#include "cmd_queue.h" +#include "usart3.h" +/*! + * \brief 发送1个字节 + * \param t 发送的字节 + */ +void SendChar(uint8_t t) +{ + // usart1_send_byte(t); + usart3_send_byte(t); +} diff --git a/mkrtos_user/server/app/hmi_lcd/hmi_user_uart.h b/mkrtos_user/server/app/hmi_lcd/hmi_user_uart.h new file mode 100644 index 000000000..f91e75f2e --- /dev/null +++ b/mkrtos_user/server/app/hmi_lcd/hmi_user_uart.h @@ -0,0 +1,14 @@ + +#ifndef _USER_UART__ +#define _USER_UART__ +#include "stm32_sys.h" + +/***************************************************************** + * 名 称: SendChar() + * 功 能: 发送1个字节 + * 入口参数: t 发送的字节 + * 出口参数: 无 + *****************************************************************/ +void SendChar(uint8_t t); + +#endif diff --git a/mkrtos_user/server/app/src/heap_stack.c b/mkrtos_user/server/app/src/heap_stack.c index adf16de7a..d1a220345 100644 --- a/mkrtos_user/server/app/src/heap_stack.c +++ b/mkrtos_user/server/app/src/heap_stack.c @@ -1,5 +1,5 @@ -#define HEAP_SIZE 2 * 1024 +#define HEAP_SIZE 0 * 1024 #define STACK_SIZE 1024 * 2 #if defined(__CC_ARM) diff --git a/mkrtos_user/server/app/src/main.c b/mkrtos_user/server/app/src/main.c index 17701906c..ac1158f8a 100644 --- a/mkrtos_user/server/app/src/main.c +++ b/mkrtos_user/server/app/src/main.c @@ -16,20 +16,33 @@ #include "test.h" #include "spl06.h" #include "sysinfo.h" +#include "usart3.h" #include #include - +#include "temp_cal.h" int main(int argc, char *args[]) { - drv_init(); printf("argc:%d args[0]:%s\n", argc, args[0]); + drv_init(); + u_sleep_ms(100); + sys_info.devID = 12; + sys_info_save(); + sys_info.devID = 0; + sys_info_read(); + assert(sys_info.devID == 12); ulog_write_str(u_get_global_env()->log_hd, "app start..\n"); relay_test(); while (1) { user_spl0601_get(); - u_sleep_ms(500); - printf("temp:%d press:%d\n", (int)(sys_info.board_temp), (int)(sys_info.pressure)); + temps_cal(); + u_sleep_ms(1000); + printf("temp:%f press:%f\n", (sys_info.board_temp), (sys_info.pressure)); + for (int i = 0; i < 4; i++) + { + printf("tmp%d:%f\n", i, sys_info.temp[i]); + } + usart3_send_string("usart3..\n"); toogle_led_0(); } return 0; diff --git a/mkrtos_user/server/app/util/auto_close.c b/mkrtos_user/server/app/util/auto_close.c new file mode 100644 index 000000000..a7b662c20 --- /dev/null +++ b/mkrtos_user/server/app/util/auto_close.c @@ -0,0 +1,64 @@ + +#include "stm32_sys.h" +#include "sysinfo.h" +// #include "tim3.h" +#include "u_sys.h" +#include "auto_close.h" + +u32 _start_tick[CTRL_IO_NUM] = {0}; +u32 _io_status[CTRL_IO_NUM] = {0}; +u8 _io_en[CTRL_IO_NUM] = {0}; + +_ctrl_func ctrl_func[CTRL_IO_NUM] = {0}; +_ctrl_func ctrl_visual_func[CTRL_IO_NUM] = {0}; +/** + * 控制调用 + */ +void io_ctrl(int inx, int state) +{ + if (state) + { + _io_status[inx] = state; + _start_tick[inx] = sys_read_tick(); + _io_en[inx] = 1; + } + else + { + _io_en[inx] = 0; + _io_status[inx] = state; + } + if (ctrl_func[inx]) + { + ctrl_func[inx](inx, state); + } +} +void io_ctrl_visual(int inx, int state) +{ + if (ctrl_visual_func[inx]) + { + ctrl_visual_func[inx](inx, state); + } +} +void io_ctrl_reg(int inx, _ctrl_func ctrl_f, _ctrl_func ctrl_visual_f) +{ + ctrl_func[inx] = ctrl_f; + ctrl_visual_func[inx] = ctrl_visual_f; +} +void io_ctrl_loop(void) +{ + + for (int i = 0; i < CTRL_IO_NUM; i++) + { + if (!_io_en[i]) + { + continue; + } + if ( + sys_info.auto_ctrl_tick[i] != 0 && + sys_read_tick() - _start_tick[i] >= sys_info.auto_ctrl_tick[i]) + { + io_ctrl(i, 0); // 关闭io + io_ctrl_visual(i, 0); + } + } +} diff --git a/mkrtos_user/server/app/util/auto_close.h b/mkrtos_user/server/app/util/auto_close.h new file mode 100644 index 000000000..cae5d6860 --- /dev/null +++ b/mkrtos_user/server/app/util/auto_close.h @@ -0,0 +1,10 @@ +#pragma once + +#include "sysinfo.h" + +typedef int (*_ctrl_func)(int inx, int state); + +void io_ctrl_reg(int inx, _ctrl_func ctrl_f, _ctrl_func ctrl_visual_f); +void io_ctrl_loop(void); +void io_ctrl(int inx, int state); +void io_ctrl_visual(int inx, int state); diff --git a/mkrtos_user/server/app/util/temp_cal.c b/mkrtos_user/server/app/util/temp_cal.c new file mode 100644 index 000000000..c94b08c56 --- /dev/null +++ b/mkrtos_user/server/app/util/temp_cal.c @@ -0,0 +1,81 @@ + +#include "adc.h" +#include "temp_cal.h" +#include "sysinfo.h" +#include + +// Rt = R *EXP(B*(1/T1-1/T2)) +// 这里T1和T2指的是K度即开尔文温度,K度=273.15(绝对温度)+摄氏度;其中T2=(273.15+25) +// Rt 是热敏电阻在T1温度下的阻值; +// R是热敏电阻在T2常温下的标称阻值; +// B值是热敏电阻的重要参数; +// EXP是e的n次方; + +const float Rp = 10000.0; // 10K +const float T2 = (273.15 + 25.0); // T2 +const float Bx = 3950.0; // B +const float Ka = 273.15; + +// 根据电阻值计算温度值 +float get_temp(int resistor) +{ + float Rt; + float temp; + + Rt = resistor; + // like this R=5000, T2=273.15+25,B=3470, RT=5000*EXP(3470*(1/T1-1/(273.15+25)), + temp = Rt / Rp; + temp = log(temp); // ln(Rt/Rp) + temp /= Bx; // ln(Rt/Rp)/B + temp += (1 / T2); + temp = 1 / (temp); + temp -= Ka; + return temp; +} + +#define RES_CAL(a) ((double)((a)) / (((3.3 - a) / 10000.0))) + +#define TEMPS_NUMBET 4 // 六路温度 + +#define TEP_CAP_COUNT 50 // 15次平均 + +u32 adc_cap_val[TEMPS_NUMBET] = {0}; +u16 adc_count = 0; +void temps_cal(void) +{ + u8 i; + for (i = 0; i < TEMPS_NUMBET; i++) + { + adc_cap_val[i] += ADCConvertedValue[i]; + } + adc_count++; + if (adc_count >= TEP_CAP_COUNT) + { + adc_count = 0; + for (i = 0; i < TEMPS_NUMBET; i++) + { + adc_cap_val[i] /= TEP_CAP_COUNT; + } + sys_info.temp[0] = get_temp(RES_CAL(((double)adc_cap_val[0] / 4096.) * 3.3)); + sys_info.temp[1] = get_temp(RES_CAL(((double)adc_cap_val[1] / 4096.) * 3.3)); + sys_info.temp[2] = get_temp(RES_CAL(((double)adc_cap_val[2] / 4096.) * 3.3)); + sys_info.temp[3] = get_temp(RES_CAL(((double)adc_cap_val[3] / 4096.) * 3.3)); + sys_info.temp[4] = get_temp(RES_CAL(((double)adc_cap_val[4] / 4096.) * 3.3)); + sys_info.temp[5] = get_temp(RES_CAL(((double)adc_cap_val[5] / 4096.) * 3.3)); + for (i = 0; i < TEMPS_NUMBET; i++) + { + if (sys_info.temp[i] < TEMP_MIN_VAL) + { + sys_info.temp[i] = TEMP_MIN_VAL; + } + else if (sys_info.temp[i] > TEMP_MAX_VAL) + { + sys_info.temp[i] = TEMP_MAX_VAL; + } + } + for (i = 0; i < TEMPS_NUMBET; i++) + { + adc_cap_val[i] = 0; + } + } +} diff --git a/mkrtos_user/server/app/util/temp_cal.h b/mkrtos_user/server/app/util/temp_cal.h new file mode 100644 index 000000000..65793c6c2 --- /dev/null +++ b/mkrtos_user/server/app/util/temp_cal.h @@ -0,0 +1,8 @@ +#pragma once + +#include "stm32_sys.h" + +#define TEMP_MAX_VAL 100 +#define TEMP_MIN_VAL -40 + +void temps_cal(void); diff --git a/mkrtos_user/server/fs/fatfs/CMakeLists.txt b/mkrtos_user/server/fs/fatfs/CMakeLists.txt index 10361332b..f9894a984 100644 --- a/mkrtos_user/server/fs/fatfs/CMakeLists.txt +++ b/mkrtos_user/server/fs/fatfs/CMakeLists.txt @@ -1,6 +1,15 @@ cmake_minimum_required(VERSION 3.13) -file(GLOB deps ff15/source/*.c *.c) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_STDPERIPH_DRIVER=1 -DSTM32F10X_XL ") + +file( + GLOB deps + ff15/source/*.c + ext_disk_drv/*.c + *.c +) + +list(REMOVE_ITEM deps mkrtos_user/server/fs/fatfs/ram_disk_drv/*.*) add_executable( fatfs.elf @@ -14,6 +23,7 @@ target_link_libraries( sys sys_util sys_svr + stm32f1_bsp ${GCC_LIB_PATH}/libgcc.a ) target_include_directories( @@ -32,6 +42,10 @@ target_include_directories( ${CMAKE_SOURCE_DIR}/mkrtos_user/server/fs/fatfs/ff15/source ${CMAKE_SOURCE_DIR}/mkrtos_user/server/fs/fatfs + + ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/stm32f1_bsp/inc + ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/stm32f1_bsp/core_inc + ${CMAKE_SOURCE_DIR}/mkrtos_user/server/fs/fatfs/ext_disk_drv ) add_dependencies( fatfs.elf @@ -39,6 +53,7 @@ add_dependencies( muslc sys sys_util + stm32f1_bsp ) set_target_properties( fatfs.elf PROPERTIES LINK_FLAGS diff --git a/mkrtos_user/server/fs/fatfs/ext_disk_drv/diskio.c b/mkrtos_user/server/fs/fatfs/ext_disk_drv/diskio.c new file mode 100644 index 000000000..05dee6bd9 --- /dev/null +++ b/mkrtos_user/server/fs/fatfs/ext_disk_drv/diskio.c @@ -0,0 +1,166 @@ +/*-----------------------------------------------------------------------*/ +/* Low level disk I/O module SKELETON for FatFs (C)ChaN, 2019 */ +/*-----------------------------------------------------------------------*/ +/* If a working storage control module is available, it should be */ +/* attached to the FatFs via a glue function rather than modifying it. */ +/* This is an example of glue functions to attach various exsisting */ +/* storage control modules to the FatFs module with a defined API. */ +/*-----------------------------------------------------------------------*/ + +#include "ff.h" /* Obtains integer types */ +#include "diskio.h" /* Declarations of disk functions */ +#include "w25q64.h" +#include +/* Definitions of physical drive number for each drive */ +#define DEV_EXT_FLASH 0 /* Example: Map Ramdisk to physical drive 0 */ + +#define FLASH_SECTOR_SIZE 4096 +u16 FLASH_SECTOR_COUNT = 2048; // W25Q64,前12M字节给FATFS占用 +#define FLASH_BLOCK_SIZE 1 // 每个BLOCK有8个扇区 +/*-----------------------------------------------------------------------*/ +/* Get Drive Status */ +/*-----------------------------------------------------------------------*/ + +DSTATUS disk_status( + BYTE pdrv /* Physical drive nmuber to identify the drive */ +) +{ + DSTATUS stat; + int result; + + switch (pdrv) + { + case DEV_EXT_FLASH: + result = 0; + if (W25QXX_ReadID() != W25Q64) + { + stat = RES_ERROR; + } + else + { + stat = RES_OK; + } + return stat; + } + return STA_NOINIT; +} + +/*-----------------------------------------------------------------------*/ +/* Inidialize a Drive */ +/*-----------------------------------------------------------------------*/ + +DSTATUS disk_initialize( + BYTE pdrv /* Physical drive nmuber to identify the drive */ +) +{ + DSTATUS stat; + int result; + + switch (pdrv) + { + case DEV_EXT_FLASH: + result = 0; + W25QXX_Init(); + // translate the reslut code here + return disk_status(pdrv); + } + return STA_NOINIT; +} + +/*-----------------------------------------------------------------------*/ +/* Read Sector(s) */ +/*-----------------------------------------------------------------------*/ + +DRESULT disk_read( + BYTE pdrv, /* Physical drive nmuber to identify the drive */ + BYTE *buff, /* Data buffer to store read data */ + LBA_t sector, /* Start sector in LBA */ + UINT count /* Number of sectors to read */ +) +{ + DRESULT res; + + switch (pdrv) + { + case DEV_EXT_FLASH: + for (; count > 0; count--) + { + W25QXX_Read(buff, sector * FLASH_SECTOR_SIZE, FLASH_SECTOR_SIZE); + sector++; + buff += FLASH_SECTOR_SIZE; + } + return 0; + } + + return RES_PARERR; +} + +/*-----------------------------------------------------------------------*/ +/* Write Sector(s) */ +/*-----------------------------------------------------------------------*/ + +#if FF_FS_READONLY == 0 + +DRESULT disk_write( + BYTE pdrv, /* Physical drive nmuber to identify the drive */ + const BYTE *buff, /* Data to be written */ + LBA_t sector, /* Start sector in LBA */ + UINT count /* Number of sectors to write */ +) +{ + int result; + + switch (pdrv) + { + case DEV_EXT_FLASH: + for (; count > 0; count--) + { + W25QXX_Erase_Sector(sector); // 擦除这个扇区 + W25QXX_Write_NoCheck((u8 *)buff, sector * FLASH_SECTOR_SIZE, FLASH_SECTOR_SIZE); + sector++; + buff += FLASH_SECTOR_SIZE; + } + return 0; + } + + return RES_PARERR; +} + +#endif + +/*-----------------------------------------------------------------------*/ +/* Miscellaneous Functions */ +/*-----------------------------------------------------------------------*/ + +DRESULT disk_ioctl( + BYTE pdrv, /* Physical drive nmuber (0..) */ + BYTE cmd, /* Control code */ + void *buff /* Buffer to send/receive control data */ +) +{ + DRESULT res; + int result; + + switch (pdrv) + { + case DEV_EXT_FLASH: + switch (cmd) + { // fatfs内核使用cmd调用 + case GET_SECTOR_COUNT: // sector count, 传入sect_cnt + *(DWORD *)buff = FLASH_SECTOR_COUNT; + return RES_OK; + case GET_SECTOR_SIZE: // sector size, 传入block size(SD),单位bytes + *(DWORD *)buff = FLASH_SECTOR_SIZE; + return RES_OK; + case GET_BLOCK_SIZE: // block size, 由上文可得,对于SD2.0卡最大8192,最小 1 + *(DWORD *)buff = FLASH_BLOCK_SIZE; // 单位为 sector(FatFs) + return RES_OK; + case CTRL_SYNC: // 同步命令,貌似FatFs内核用来判断写操作是否完成 + return RES_OK; + } + default: + // printf("No device %d.\n", pdrv); + break; + } + return RES_PARERR; // 默认返回参数错误 +} diff --git a/mkrtos_user/server/fs/fatfs/ff15/source/diskio.h b/mkrtos_user/server/fs/fatfs/ext_disk_drv/diskio.h similarity index 100% rename from mkrtos_user/server/fs/fatfs/ff15/source/diskio.h rename to mkrtos_user/server/fs/fatfs/ext_disk_drv/diskio.h diff --git a/mkrtos_user/server/fs/fatfs/ext_disk_drv/spi1.c b/mkrtos_user/server/fs/fatfs/ext_disk_drv/spi1.c new file mode 100644 index 000000000..13945cd8a --- /dev/null +++ b/mkrtos_user/server/fs/fatfs/ext_disk_drv/spi1.c @@ -0,0 +1,58 @@ +#include "stm32_sys.h" // Device header +#include "spi1.h" +void MySPI_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); + RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); + + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + GPIO_SetBits(GPIOB, GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7); // PB13/14/15上拉 + + SPI_InitTypeDef SPI_InitStructure; + SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // 设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工 + SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // 设置SPI工作模式:设置为主SPI + SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // 设置SPI的数据大小:SPI发送接收8位帧结构 + SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; // 串行同步时钟的空闲状态为高电平 + SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // 串行同步时钟的第二个跳变沿(上升或下降)数据被采样 + SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制 + SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; // 定义波特率预分频的值:波特率预分频值为256 + SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // 指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 + SPI_InitStructure.SPI_CRCPolynomial = 7; // CRC值计算的多项式 + SPI_Init(SPI1, &SPI_InitStructure); + + SPI_Cmd(SPI1, ENABLE); + MySPI_SwapByte(0xff); +} + +void MySPI_SetSpeed(uint8_t SPI_BaudRatePrescaler) +{ + assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler)); + SPI1->CR1 &= 0XFFC7; + SPI1->CR1 |= SPI_BaudRatePrescaler; // 设置SPI2速度 + SPI_Cmd(SPI1, ENABLE); +} +uint8_t MySPI_SwapByte(uint8_t ByteSend) +{ + u8 retry = 0; + while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) // 检查指定的SPI标志位设置与否:发送缓存空标志位 + { + retry++; + if (retry > 200) + return 0; + } + SPI_I2S_SendData(SPI1, ByteSend); // 通过外设SPIx发送一个数据 + retry = 0; + + while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) // 检查指定的SPI标志位设置与否:接受缓存非空标志位 + { + retry++; + if (retry > 200) + return 0; + } + return SPI_I2S_ReceiveData(SPI1); // 返回通过SPIx最近接收的数据 +} diff --git a/mkrtos_user/server/fs/fatfs/ext_disk_drv/spi1.h b/mkrtos_user/server/fs/fatfs/ext_disk_drv/spi1.h new file mode 100644 index 000000000..bc76abdec --- /dev/null +++ b/mkrtos_user/server/fs/fatfs/ext_disk_drv/spi1.h @@ -0,0 +1,5 @@ +#pragma once + +void MySPI_Init(void); +void MySPI_SetSpeed(uint8_t SPI_BaudRatePrescaler); +uint8_t MySPI_SwapByte(uint8_t ByteSend); diff --git a/mkrtos_user/server/fs/fatfs/ext_disk_drv/w25q64.c b/mkrtos_user/server/fs/fatfs/ext_disk_drv/w25q64.c new file mode 100644 index 000000000..efefa3983 --- /dev/null +++ b/mkrtos_user/server/fs/fatfs/ext_disk_drv/w25q64.c @@ -0,0 +1,268 @@ +#include "stm32_sys.h" // Device header +#include "spi1.h" +#include "w25q64.h" + +u16 W25QXX_TYPE = W25Q64; // 默认是W25Q128 + +// 4Kbytes为一个Sector +// 16个扇区为1个Block +// W25Q128 +// 容量为16M字节,共有128个Block,4096个Sector + +// 初始化SPI FLASH的IO口 +void W25QXX_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // PORTB时钟使能 + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; // PA4 推挽 + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出 + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(GPIOA, &GPIO_InitStructure); + GPIO_SetBits(GPIOA, GPIO_Pin_4); + + W25QXX_CS = 1; // SPI FLASH不选中 + MySPI_Init(); // 初始化SPI + MySPI_SetSpeed(SPI_BaudRatePrescaler_2); // 设置为18M时钟,高速模式 + W25QXX_TYPE = W25QXX_ReadID(); // 读取FLASH ID. +} + +// 读取W25QXX的状态寄存器 +// BIT7 6 5 4 3 2 1 0 +// SPR RV TB BP2 BP1 BP0 WEL BUSY +// SPR:默认0,状态寄存器保护位,配合WP使用 +// TB,BP2,BP1,BP0:FLASH区域写保护设置 +// WEL:写使能锁定 +// BUSY:忙标记位(1,忙;0,空闲) +// 默认:0x00 +u8 W25QXX_ReadSR(void) +{ + u8 byte = 0; + W25QXX_CS = 0; // 使能器件 + MySPI_SwapByte(W25X_ReadStatusReg); // 发送读取状态寄存器命令 + byte = MySPI_SwapByte(0Xff); // 读取一个字节 + W25QXX_CS = 1; // 取消片选 + return byte; +} +// 写W25QXX状态寄存器 +// 只有SPR,TB,BP2,BP1,BP0(bit 7,5,4,3,2)可以写!!! +void W25QXX_Write_SR(u8 sr) +{ + W25QXX_CS = 0; // 使能器件 + MySPI_SwapByte(W25X_WriteStatusReg); // 发送写取状态寄存器命令 + MySPI_SwapByte(sr); // 写入一个字节 + W25QXX_CS = 1; // 取消片选 +} +// W25QXX写使能 +// 将WEL置位 +void W25QXX_Write_Enable(void) +{ + W25QXX_CS = 0; // 使能器件 + MySPI_SwapByte(W25X_WriteEnable); // 发送写使能 + W25QXX_CS = 1; // 取消片选 +} +// W25QXX写禁止 +// 将WEL清零 +void W25QXX_Write_Disable(void) +{ + W25QXX_CS = 0; // 使能器件 + MySPI_SwapByte(W25X_WriteDisable); // 发送写禁止指令 + W25QXX_CS = 1; // 取消片选 +} +// 读取芯片ID +// 返回值如下: +// 0XEF13,表示芯片型号为W25Q80 +// 0XEF14,表示芯片型号为W25Q16 +// 0XEF15,表示芯片型号为W25Q32 +// 0XEF16,表示芯片型号为W25Q64 +// 0XEF17,表示芯片型号为W25Q128 +u16 W25QXX_ReadID(void) +{ + u16 Temp = 0; + W25QXX_CS = 0; + MySPI_SwapByte(0x90); // 发送读取ID命令 + MySPI_SwapByte(0x00); + MySPI_SwapByte(0x00); + MySPI_SwapByte(0x00); + Temp |= MySPI_SwapByte(0xFF) << 8; + Temp |= MySPI_SwapByte(0xFF); + W25QXX_CS = 1; + return Temp; +} +// 读取SPI FLASH +// 在指定地址开始读取指定长度的数据 +// pBuffer:数据存储区 +// ReadAddr:开始读取的地址(24bit) +// NumByteToRead:要读取的字节数(最大65535) +void W25QXX_Read(u8 *pBuffer, u32 ReadAddr, u16 NumByteToRead) +{ + u16 i; + W25QXX_CS = 0; // 使能器件 + MySPI_SwapByte(W25X_ReadData); // 发送读取命令 + MySPI_SwapByte((u8)((ReadAddr) >> 16)); // 发送24bit地址 + MySPI_SwapByte((u8)((ReadAddr) >> 8)); + MySPI_SwapByte((u8)ReadAddr); + for (i = 0; i < NumByteToRead; i++) + { + pBuffer[i] = MySPI_SwapByte(0XFF); // 循环读数 + } + W25QXX_CS = 1; +} +// SPI在一页(0~65535)内写入少于256个字节的数据 +// 在指定地址开始写入最大256字节的数据 +// pBuffer:数据存储区 +// WriteAddr:开始写入的地址(24bit) +// NumByteToWrite:要写入的字节数(最大256),该数不应该超过该页的剩余字节数!!! +void W25QXX_Write_Page(u8 *pBuffer, u32 WriteAddr, u16 NumByteToWrite) +{ + u16 i; + W25QXX_Write_Enable(); // SET WEL + W25QXX_CS = 0; // 使能器件 + MySPI_SwapByte(W25X_PageProgram); // 发送写页命令 + MySPI_SwapByte((u8)((WriteAddr) >> 16)); // 发送24bit地址 + MySPI_SwapByte((u8)((WriteAddr) >> 8)); + MySPI_SwapByte((u8)WriteAddr); + for (i = 0; i < NumByteToWrite; i++) + MySPI_SwapByte(pBuffer[i]); // 循环写数 + W25QXX_CS = 1; // 取消片选 + W25QXX_Wait_Busy(); // 等待写入结束 +} +// 无检验写SPI FLASH +// 必须确保所写的地址范围内的数据全部为0XFF,否则在非0XFF处写入的数据将失败! +// 具有自动换页功能 +// 在指定地址开始写入指定长度的数据,但是要确保地址不越界! +// pBuffer:数据存储区 +// WriteAddr:开始写入的地址(24bit) +// NumByteToWrite:要写入的字节数(最大65535) +// CHECK OK +void W25QXX_Write_NoCheck(u8 *pBuffer, u32 WriteAddr, u16 NumByteToWrite) +{ + u16 pageremain; + pageremain = 256 - WriteAddr % 256; // 单页剩余的字节数 + if (NumByteToWrite <= pageremain) + pageremain = NumByteToWrite; // 不大于256个字节 + while (1) + { + W25QXX_Write_Page(pBuffer, WriteAddr, pageremain); + if (NumByteToWrite == pageremain) + break; // 写入结束了 + else // NumByteToWrite>pageremain + { + pBuffer += pageremain; + WriteAddr += pageremain; + + NumByteToWrite -= pageremain; // 减去已经写入了的字节数 + if (NumByteToWrite > 256) + pageremain = 256; // 一次可以写入256个字节 + else + pageremain = NumByteToWrite; // 不够256个字节了 + } + }; +} +// 写SPI FLASH +// 在指定地址开始写入指定长度的数据 +// 该函数带擦除操作! +// pBuffer:数据存储区 +// WriteAddr:开始写入的地址(24bit) +// NumByteToWrite:要写入的字节数(最大65535) +// u8 W25QXX_BUFFER[4096]; +// void W25QXX_Write(u8 *pBuffer, u32 WriteAddr, u16 NumByteToWrite) +// { +// u32 secpos; +// u16 secoff; +// u16 secremain; +// u16 i; +// u8 *W25QXX_BUF; +// W25QXX_BUF = W25QXX_BUFFER; +// secpos = WriteAddr / 4096; // 扇区地址 +// secoff = WriteAddr % 4096; // 在扇区内的偏移 +// secremain = 4096 - secoff; // 扇区剩余空间大小 +// // printf("ad:%X,nb:%X\r\n",WriteAddr,NumByteToWrite);//测试用 +// if (NumByteToWrite <= secremain) +// secremain = NumByteToWrite; // 不大于4096个字节 +// while (1) +// { +// W25QXX_Read(W25QXX_BUF, secpos * 4096, 4096); // 读出整个扇区的内容 +// for (i = 0; i < secremain; i++) // 校验数据 +// { +// if (W25QXX_BUF[secoff + i] != 0XFF) +// break; // 需要擦除 +// } +// if (i < secremain) // 需要擦除 +// { +// W25QXX_Erase_Sector(secpos); // 擦除这个扇区 +// for (i = 0; i < secremain; i++) // 复制 +// { +// W25QXX_BUF[i + secoff] = pBuffer[i]; +// } +// W25QXX_Write_NoCheck(W25QXX_BUF, secpos * 4096, 4096); // 写入整个扇区 +// } +// else +// W25QXX_Write_NoCheck(pBuffer, WriteAddr, secremain); // 写已经擦除了的,直接写入扇区剩余区间. +// if (NumByteToWrite == secremain) +// break; // 写入结束了 +// else // 写入未结束 +// { +// secpos++; // 扇区地址增1 +// secoff = 0; // 偏移位置为0 + +// pBuffer += secremain; // 指针偏移 +// WriteAddr += secremain; // 写地址偏移 +// NumByteToWrite -= secremain; // 字节数递减 +// if (NumByteToWrite > 4096) +// secremain = 4096; // 下一个扇区还是写不完 +// else +// secremain = NumByteToWrite; // 下一个扇区可以写完了 +// } +// }; +// } +// 擦除整个芯片 +// 等待时间超长... +void W25QXX_Erase_Chip(void) +{ + W25QXX_Write_Enable(); // SET WEL + W25QXX_Wait_Busy(); + W25QXX_CS = 0; // 使能器件 + MySPI_SwapByte(W25X_ChipErase); // 发送片擦除命令 + W25QXX_CS = 1; // 取消片选 + W25QXX_Wait_Busy(); // 等待芯片擦除结束 +} +// 擦除一个扇区 +// Dst_Addr:扇区地址 根据实际容量设置 +// 擦除一个山区的最少时间:150ms +void W25QXX_Erase_Sector(u32 Dst_Addr) +{ + // 监视falsh擦除情况,测试用 + Dst_Addr *= 4096; + W25QXX_Write_Enable(); // SET WEL + W25QXX_Wait_Busy(); + W25QXX_CS = 0; // 使能器件 + MySPI_SwapByte(W25X_SectorErase); // 发送扇区擦除指令 + MySPI_SwapByte((u8)((Dst_Addr) >> 16)); // 发送24bit地址 + MySPI_SwapByte((u8)((Dst_Addr) >> 8)); + MySPI_SwapByte((u8)Dst_Addr); + W25QXX_CS = 1; // 取消片选 + W25QXX_Wait_Busy(); // 等待擦除完成 +} +// 等待空闲 +void W25QXX_Wait_Busy(void) +{ + while ((W25QXX_ReadSR() & 0x01) == 0x01) + ; // 等待BUSY位清空 +} +// 进入掉电模式 +void W25QXX_PowerDown(void) +{ + W25QXX_CS = 0; // 使能器件 + MySPI_SwapByte(W25X_PowerDown); // 发送掉电命令 + W25QXX_CS = 1; // 取消片选 + // delay_us(3); // 等待TPD +} +// 唤醒 +void W25QXX_WAKEUP(void) +{ + W25QXX_CS = 0; // 使能器件 + MySPI_SwapByte(W25X_ReleasePowerDown); // send W25X_PowerDown command 0xAB + W25QXX_CS = 1; // 取消片选 + // delay_us(3); // 等待TRES1 +} diff --git a/mkrtos_user/server/fs/fatfs/ext_disk_drv/w25q64.h b/mkrtos_user/server/fs/fatfs/ext_disk_drv/w25q64.h new file mode 100644 index 000000000..3607b82e1 --- /dev/null +++ b/mkrtos_user/server/fs/fatfs/ext_disk_drv/w25q64.h @@ -0,0 +1,53 @@ +#pragma once +#include "stm32_sys.h" +// W25X系列/Q系列芯片列表 +// W25Q80 ID 0XEF13 +// W25Q16 ID 0XEF14 +// W25Q32 ID 0XEF15 +// W25Q64 ID 0XEF16 +// W25Q128 ID 0XEF17 +#define W25Q80 0XEF13 +#define W25Q16 0XEF14 +#define W25Q32 0XEF15 +#define W25Q64 0XEF16 +#define W25Q128 0XEF17 + +extern u16 W25QXX_TYPE; // 定义W25QXX芯片型号 + +#define W25QXX_CS PAout(4) // W25QXX的片选信号 + +//////////////////////////////////////////////////////////////////////////// + +// 指令表 +#define W25X_WriteEnable 0x06 +#define W25X_WriteDisable 0x04 +#define W25X_ReadStatusReg 0x05 +#define W25X_WriteStatusReg 0x01 +#define W25X_ReadData 0x03 +#define W25X_FastReadData 0x0B +#define W25X_FastReadDual 0x3B +#define W25X_PageProgram 0x02 +#define W25X_BlockErase 0xD8 +#define W25X_SectorErase 0x20 +#define W25X_ChipErase 0xC7 +#define W25X_PowerDown 0xB9 +#define W25X_ReleasePowerDown 0xAB +#define W25X_DeviceID 0xAB +#define W25X_ManufactDeviceID 0x90 +#define W25X_JedecDeviceID 0x9F + +void W25QXX_Init(void); +u16 W25QXX_ReadID(void); // 读取FLASH ID +u8 W25QXX_ReadSR(void); // 读取状态寄存器 +void W25QXX_Write_SR(u8 sr); // 写状态寄存器 +void W25QXX_Write_Enable(void); // 写使能 +void W25QXX_Write_Disable(void); // 写保护 +void W25QXX_Write_NoCheck(u8 *pBuffer, u32 WriteAddr, u16 NumByteToWrite); +void W25QXX_Read(u8 *pBuffer, u32 ReadAddr, u16 NumByteToRead); // 读取flash +void W25QXX_Write_Page(u8 *pBuffer, u32 WriteAddr, u16 NumByteToWrite); +void W25QXX_Write(u8 *pBuffer, u32 WriteAddr, u16 NumByteToWrite); // 写入flash +void W25QXX_Erase_Chip(void); // 整片擦除 +void W25QXX_Erase_Sector(u32 Dst_Addr); // 扇区擦除 +void W25QXX_Wait_Busy(void); // 等待空闲 +void W25QXX_PowerDown(void); // 进入掉电模式 +void W25QXX_WAKEUP(void); // 唤醒 \ No newline at end of file diff --git a/mkrtos_user/server/fs/fatfs/ff15/source/ffconf.h b/mkrtos_user/server/fs/fatfs/ff15/source/ffconf.h index 5b76a0086..79575d122 100644 --- a/mkrtos_user/server/fs/fatfs/ff15/source/ffconf.h +++ b/mkrtos_user/server/fs/fatfs/ff15/source/ffconf.h @@ -171,7 +171,7 @@ #define FF_STR_VOLUME_ID 0 -#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3" +#define FF_VOLUME_STRS "FLASH","RAM","NAND","CF","SD","SD2","USB","USB2","USB3" /* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings. / When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive / number in the path name. FF_VOLUME_STRS defines the volume ID strings for each @@ -193,8 +193,8 @@ / function will be available. */ -#define FF_MIN_SS 512 -#define FF_MAX_SS 512 +#define FF_MIN_SS 4096 +#define FF_MAX_SS 4096 /* This set of options configures the range of sector size to be supported. (512, / 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and / harddisk, but a larger value may be required for on-board flash memory and some diff --git a/mkrtos_user/server/fs/fatfs/fs_rpc.c b/mkrtos_user/server/fs/fatfs/fs_rpc.c index 675c9b764..3eab384f3 100644 --- a/mkrtos_user/server/fs/fatfs/fs_rpc.c +++ b/mkrtos_user/server/fs/fatfs/fs_rpc.c @@ -1,8 +1,11 @@ #include "u_rpc.h" #include "u_rpc_svr.h" #include "fs_svr.h" -#include #include "ff.h" +#include "u_log.h" +#include "u_env.h" +#include +#include static fs_t fs; void fs_svr_init(obj_handler_t ipc) @@ -15,9 +18,14 @@ typedef struct file_desc FIL fp; } file_desc_t; -#define FILE_DESC_NR 3 +#define FILE_DESC_NR 1 static file_desc_t files[FILE_DESC_NR]; +void *file_temp_buf_get(void) +{ + return (void *)(&files[0]); +} + static file_desc_t *alloc_file(int *fd) { for (int i = 0; i < FILE_DESC_NR; i++) @@ -45,7 +53,7 @@ static file_desc_t *file_get(int fd) int fs_svr_open(const char *path, int flags, int mode) { - printf("open %s.\n", path); + // printf("open %s.\n", path); int fd; file_desc_t *file = alloc_file(&fd); @@ -53,11 +61,39 @@ int fs_svr_open(const char *path, int flags, int mode) { return -ENOMEM; } - FRESULT ret = f_open(&file->fp, path, mode); + int new_mode = 0; + + switch (flags & O_ACCMODE) + { + case O_RDWR: + new_mode |= FA_READ; + new_mode |= FA_WRITE; + break; + case O_RDONLY: + new_mode |= FA_READ; + break; + case O_WRONLY: + new_mode |= FA_WRITE; + break; + } + if ((flags & O_CREAT) && (flags & O_EXCL)) + { + new_mode |= FA_CREATE_NEW; + } + else if ((flags & O_CREAT)) + { + new_mode |= FA_OPEN_ALWAYS; + } + if (flags & O_APPEND) + { + new_mode |= FA_OPEN_APPEND; + } + + FRESULT ret = f_open(&file->fp, path, new_mode); if (ret != FR_OK) { - printf("open fail..\n"); + ulog_write_str(u_get_global_env()->log_hd, "open fail..\n"); free_file(fd); } diff --git a/mkrtos_user/server/fs/fatfs/fs_rpc.h b/mkrtos_user/server/fs/fatfs/fs_rpc.h index 97a025e99..ccebef7a8 100644 --- a/mkrtos_user/server/fs/fatfs/fs_rpc.h +++ b/mkrtos_user/server/fs/fatfs/fs_rpc.h @@ -2,4 +2,4 @@ void fs_svr_init(obj_handler_t ipc); void fs_svr_loop(void); - +void *file_temp_buf_get(void); diff --git a/mkrtos_user/server/fs/fatfs/heap_stack.c b/mkrtos_user/server/fs/fatfs/heap_stack.c index 2f21cffba..700c5a16d 100644 --- a/mkrtos_user/server/fs/fatfs/heap_stack.c +++ b/mkrtos_user/server/fs/fatfs/heap_stack.c @@ -1,5 +1,5 @@ -#define HEAP_SIZE 4 +#define HEAP_SIZE 0 #define STACK_SIZE 1024 * 2 #if defined(__CC_ARM) diff --git a/mkrtos_user/server/fs/fatfs/main.c b/mkrtos_user/server/fs/fatfs/main.c index cb4b774a5..f85fe6646 100644 --- a/mkrtos_user/server/fs/fatfs/main.c +++ b/mkrtos_user/server/fs/fatfs/main.c @@ -2,24 +2,32 @@ #include "ns_cli.h" #include "u_rpc_svr.h" #include "u_prot.h" +#include "u_env.h" +#include "u_drv.h" #include "fs_rpc.h" #include #include #include static FATFS fs; -static BYTE buff[512]; static MKFS_PARM defopt = {FM_ANY, 0, 0, 0}; int main(int args, char *argv[]) { + u_drv_init(); + obj_handler_t ipc_hd; + int ret = rpc_creaite_bind_ipc(THREAD_MAIN, NULL, &ipc_hd); + assert(ret >= 0); + ns_register("fs", ipc_hd); + + fs_svr_init(ipc_hd); FRESULT res = f_mount(&fs, "0:", 1); if (res != FR_OK) { - res = f_mkfs("0:", &defopt, buff, 512); // 第三个参数可以设置成NULL,默认使用heap memory + res = f_mkfs("0:", &defopt, file_temp_buf_get(), FF_MAX_SS); // 第三个参数可以设置成NULL,默认使用heap memory if (res != FR_OK) { - printf("f_mkfs err.\n"); + ulog_write_str(u_get_global_env()->log_hd, "f_mkfs err.\n"); while (1) ; } @@ -28,19 +36,14 @@ int main(int args, char *argv[]) res = f_mount(&fs, "0:", 1); if (res != FR_OK) { - printf("f_mount err.\n"); + ulog_write_str(u_get_global_env()->log_hd, "f_mount err.\n"); while (1) ; } } } - printf("mount success\n"); - obj_handler_t ipc_hd; - int ret = rpc_creaite_bind_ipc(THREAD_MAIN, NULL, &ipc_hd); - assert(ret >= 0); - ns_register("fs", ipc_hd); + ulog_write_str(u_get_global_env()->log_hd, "mount success\n"); - fs_svr_init(ipc_hd); fs_svr_loop(); while (1) ; diff --git a/mkrtos_user/server/fs/fatfs/ff15/source/diskio.c b/mkrtos_user/server/fs/fatfs/ram_disk_drv/diskio.c similarity index 96% rename from mkrtos_user/server/fs/fatfs/ff15/source/diskio.c rename to mkrtos_user/server/fs/fatfs/ram_disk_drv/diskio.c index ab314f4ae..3223c6ab8 100644 --- a/mkrtos_user/server/fs/fatfs/ff15/source/diskio.c +++ b/mkrtos_user/server/fs/fatfs/ram_disk_drv/diskio.c @@ -9,7 +9,7 @@ #include "ff.h" /* Obtains integer types */ #include "diskio.h" /* Declarations of disk functions */ -#include "ram_disk.h" +// #include "ram_disk.h" #include /* Definitions of physical drive number for each drive */ #define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */ diff --git a/mkrtos_user/server/fs/fatfs/ram_disk_drv/diskio.h b/mkrtos_user/server/fs/fatfs/ram_disk_drv/diskio.h new file mode 100644 index 000000000..c22afaa5f --- /dev/null +++ b/mkrtos_user/server/fs/fatfs/ram_disk_drv/diskio.h @@ -0,0 +1,77 @@ +/*-----------------------------------------------------------------------/ +/ Low level disk interface modlue include file (C)ChaN, 2019 / +/-----------------------------------------------------------------------*/ + +#ifndef _DISKIO_DEFINED +#define _DISKIO_DEFINED + +#ifdef __cplusplus +extern "C" { +#endif + +/* Status of Disk Functions */ +typedef BYTE DSTATUS; + +/* Results of Disk Functions */ +typedef enum { + RES_OK = 0, /* 0: Successful */ + RES_ERROR, /* 1: R/W Error */ + RES_WRPRT, /* 2: Write Protected */ + RES_NOTRDY, /* 3: Not Ready */ + RES_PARERR /* 4: Invalid Parameter */ +} DRESULT; + + +/*---------------------------------------*/ +/* Prototypes for disk control functions */ + + +DSTATUS disk_initialize (BYTE pdrv); +DSTATUS disk_status (BYTE pdrv); +DRESULT disk_read (BYTE pdrv, BYTE* buff, LBA_t sector, UINT count); +DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count); +DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); + + +/* Disk Status Bits (DSTATUS) */ + +#define STA_NOINIT 0x01 /* Drive not initialized */ +#define STA_NODISK 0x02 /* No medium in the drive */ +#define STA_PROTECT 0x04 /* Write protected */ + + +/* Command code for disk_ioctrl fucntion */ + +/* Generic command (Used by FatFs) */ +#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */ +#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */ +#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */ +#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */ +#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */ + +/* Generic command (Not used by FatFs) */ +#define CTRL_POWER 5 /* Get/Set power status */ +#define CTRL_LOCK 6 /* Lock/Unlock media removal */ +#define CTRL_EJECT 7 /* Eject media */ +#define CTRL_FORMAT 8 /* Create physical format on the media */ + +/* MMC/SDC specific ioctl command */ +#define MMC_GET_TYPE 10 /* Get card type */ +#define MMC_GET_CSD 11 /* Get CSD */ +#define MMC_GET_CID 12 /* Get CID */ +#define MMC_GET_OCR 13 /* Get OCR */ +#define MMC_GET_SDSTAT 14 /* Get SD status */ +#define ISDIO_READ 55 /* Read data form SD iSDIO register */ +#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */ +#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */ + +/* ATA/CF specific ioctl command */ +#define ATA_GET_REV 20 /* Get F/W revision */ +#define ATA_GET_MODEL 21 /* Get model name */ +#define ATA_GET_SN 22 /* Get serial number */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mkrtos_user/server/fs/fatfs/ram_disk.c b/mkrtos_user/server/fs/fatfs/ram_disk_drv/ram_disk.c similarity index 100% rename from mkrtos_user/server/fs/fatfs/ram_disk.c rename to mkrtos_user/server/fs/fatfs/ram_disk_drv/ram_disk.c diff --git a/mkrtos_user/server/fs/fatfs/ram_disk.h b/mkrtos_user/server/fs/fatfs/ram_disk_drv/ram_disk.h similarity index 100% rename from mkrtos_user/server/fs/fatfs/ram_disk.h rename to mkrtos_user/server/fs/fatfs/ram_disk_drv/ram_disk.h diff --git a/mkrtos_user/server/init/src/main.c b/mkrtos_user/server/init/src/main.c index f32aa5816..5ba89df5d 100644 --- a/mkrtos_user/server/init/src/main.c +++ b/mkrtos_user/server/init/src/main.c @@ -42,22 +42,24 @@ int main(int argc, char *args[]) int ret = rpc_creaite_bind_ipc(THREAD_MAIN, NULL, &ipc_hd); assert(ret >= 0); env.ns_hd = ipc_hd; + namespace_init(ipc_hd); - // ret = app_load("fatfs", &env); - // if (ret < 0) - // { - // printf("app load fail, 0x%x\n", ret); - // } ret = app_load("app", &env); if (ret < 0) + { + printf("app load fail, 0x%x\n", ret); + // ulog_write_str(LOG_PROT, "app load fail.\n"); + } + ret = app_load("fatfs", &env); + if (ret < 0) { printf("app load fail, 0x%x\n", ret); } - namespace_init(ipc_hd); namespace_loop(); - task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, TASK_THIS)); // 删除当前task,以及申请得所有对象 - printf("exit init.\n"); + // task_unmap(TASK_THIS, vpage_create_raw3(KOBJ_DELETE_RIGHT, 0, TASK_THIS)); // 删除当前task,以及申请得所有对象 + // printf("exit init.\n"); + // ulog_write_str(LOG_PROT, "app load fail.\n"); return 0; } diff --git a/mkrtos_user/server/shell/test/fs_test.c b/mkrtos_user/server/shell/test/fs_test.c index 72c5edc42..fdcc1e9f4 100644 --- a/mkrtos_user/server/shell/test/fs_test.c +++ b/mkrtos_user/server/shell/test/fs_test.c @@ -8,7 +8,7 @@ void fs_test(void) { char tmp[4] = "123"; - int fd = fs_open("/test", 0, 0x1 | 0x2 | 0x8); + int fd = fs_open("/test", O_CREAT | O_RDWR, 0777); assert(fd >= 0); int wlen = fs_write(fd, tmp, 4); assert(wlen == 4);