From 1ce5395b64f3417743f3e772ca37dbd2f2af3736 Mon Sep 17 00:00:00 2001 From: MacRsh Date: Sat, 9 Dec 2023 00:47:25 +0800 Subject: [PATCH] =?UTF-8?q?1.=E6=96=B0=E5=A2=9E=E5=86=85=E5=AD=98=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E6=96=87=E6=A1=A3=E3=80=82=202.=E6=9A=82=E6=97=B6?= =?UTF-8?q?=E7=A7=BB=E9=99=A4module=E7=9B=AE=E5=BD=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- document/mem_manager.md | 217 ++++++++++++++++++++ module/etask/etask.c | 392 ------------------------------------- module/etask/etask.h | 81 -------- module/hx711/hx711.c | 215 -------------------- module/hx711/hx711.h | 59 ------ module/icm20602/icm20602.c | 300 ---------------------------- module/icm20602/icm20602.h | 103 ---------- 7 files changed, 217 insertions(+), 1150 deletions(-) create mode 100644 document/mem_manager.md delete mode 100644 module/etask/etask.c delete mode 100644 module/etask/etask.h delete mode 100644 module/hx711/hx711.c delete mode 100644 module/hx711/hx711.h delete mode 100644 module/icm20602/icm20602.c delete mode 100644 module/icm20602/icm20602.h diff --git a/document/mem_manager.md b/document/mem_manager.md new file mode 100644 index 0000000..6cbc6e5 --- /dev/null +++ b/document/mem_manager.md @@ -0,0 +1,217 @@ +# 动态内存管理 + +## 主要功能: +- 内存块的动态分配 - 根据应用的请求,从未分配内存块中选择一个块进行分配。 +- 内存块的释放回收 - 当块不再需要时,将其释放并标记为未分配状态。 +- 已分配与未分配块记录 - 使用链表或数组等数据结构实时跟踪各状态块的信息。 +- 内存块合并 - 在释放块后,检查相邻块状态,若均未分配则合并为一个大块减少碎片。 + +## 内存合并的思路 + +### 前合并的情况: + +``` +(START) -> (内存块A, size=5) -> (内存块B, size=3) + +插入内存块C(size=2),发现C紧邻A,且A在前,则: + +(START) -> (内存块A+C, size=5+2=7) -> (内存块B, size=3) +``` + +### 后合并的情况: +``` +(START) -> (内存块A, size=5) -> (内存块B, size=3) -> (内存块C, size=2) + +插入内存块D(size=3),发现D紧邻B,且B在后,则: + +(START) -> (内存块A, size=5) -> (内存块D+B, size=3+3=6) -> (内存块C, size=2) +``` +### 不合并的情况: + +``` +(START) -> (内存块A, size=5) -> (内存块B, size=3) -> (内存块C, size=2) + +插入内存块D(size=1),D在A和B之间且都不相连,则: + +(START) -> (内存块A, size=5) -> (内存块D, size=1) -> (内存块B, size=3) -> (内存块C, size=2) +``` + +## 创建内存数组 + +创建静态数组,用来作为内存管理分配的内存。 + +```c +/* 定义4K空间 */ +#define MR_CFG_HEAP_SIZE (4 * 1024) +static uint8_t heap_mem[MR_CFG_HEAP_SIZE] = {0}; +``` + +## 创建内存管理结构体 + +定义内存块,由下一块内存块指针、内存块大小、内存分配标志位组成。 + +- 下一块内存块指针:用于实现链式内存块存储,表示下一个内存块的地址。 +- 内存块大小:记录该内存块的大小。 +- 内存分配标志位:使用1比特来表示内存块当前的状态,0表示未分配,1表示已分配。 + +```c +#define MR_HEAP_BLOCK_FREE (0) +#define MR_HEAP_BLOCK_ALLOCATED (1) +#define MR_HEAP_BLOCK_MIN_SIZE (sizeof(struct mr_heap_block) << 1) + +static struct mr_heap_block +{ + struct mr_heap_block *next; + uint32_t size: 31; + uint32_t allocated: 1; +} heap_start = {MR_NULL, 0, MR_HEAP_BLOCK_FREE}; +``` + +## 初始化内存管理 + +为内存初始化内存块,将整块内存作为单个内存块。 + +```c +int mr_heap_init(void) +{ + struct mr_heap_block *first_block = (struct mr_heap_block *)&heap_mem; + + /* 初始化内存块(消耗一个 sizeof(struct mr_heap_block)) */ + first_block->next = MR_NULL; + first_block->size = sizeof(heap_mem) - sizeof(struct mr_heap_block); + first_block->allocated = MR_HEAP_BLOCK_FREE; + + /* 初始化起始内存块,启动内存管理 */ + heap_start.next = first_block; + return MR_EOK; +} +``` + +## 分配内存 + +```c + void *mr_malloc(size_t size) +{ + struct mr_heap_block *block_prev = &heap_start; + struct mr_heap_block *block = block_prev->next; + void *memory = MR_NULL; + size_t residual = 0; + + /* 检查需要申请的内存过小、内存过大,以及内存管理器中还有无内存 */ + if ((size == 0) || (size > (UINT32_MAX >> 1) || (block == MR_NULL))) + { + return MR_NULL; + } + + /* 字节向上做4对齐 */ + size = mr_align4_up(size); + + /* 找到符合内存分配大小的内存块 */ + while (block->size < size) + { + if (block->next == MR_NULL) + { + return MR_NULL; + } + /* 脱离合理的内存块 */ + block_prev = block; + block = block->next; + } + /* 断开内存块链接 */ + block_prev->next = block->next; + + /* 生成新的内存块并返回内存 */ + memory = (void *)((uint8_t *)block) + sizeof(struct mr_heap_block); + /* 剩余内存大小*/ + residual = block->size - size; + + /* 设置被分配的内存块 */ + block->size = size; + block->next = MR_NULL; + block->allocated = MR_HEAP_BLOCK_ALLOCATED; + + /* 检测是否够空间生成新的内存块 (MR_HEAP_BLOCK_MIN_SIZE)左移两位等于2倍,需要有大于2个内存块大小,才生成新的内存块 */ + if (residual > MR_HEAP_BLOCK_MIN_SIZE) + { + struct mr_heap_block *new_block = (struct mr_heap_block *)(((uint8_t *)memory) + size); + + /* 设置新内存块 */ + new_block->size = residual - sizeof(struct mr_heap_block); + new_block->next = MR_NULL; + new_block->allocated = MR_HEAP_BLOCK_FREE; + + /* 将内存块插入到内存块链表中 */ + heap_insert_block(new_block); + } + + return memory; +} +``` + +## 释放内存 + +```c +void mr_free(void *memory) +{ + /* 判断内存是否为有效 */ + if (memory != MR_NULL) + { + struct mr_heap_block *block = (struct mr_heap_block *)((uint8_t *)memory - sizeof(struct mr_heap_block)); + + /* 检查内存块是否可以释放 */ + if (block->allocated == MR_HEAP_BLOCK_ALLOCATED && block->size != 0) + { + block->allocated = MR_HEAP_BLOCK_FREE; + + /* 将内存块插入到内存块链表中 */ + heap_insert_block(block); + } + } +} +``` + +## 插入内存块 + +```c +void heap_insert_block(struct mr_heap_block *block) +{ + struct mr_heap_block *block_prev = &heap_start; + + /* 搜索前一内存块 */ + while (((block_prev->next != MR_NULL) && ((uint32_t)block_prev->next < (uint32_t)block))) + { + block_prev = block_prev->next; + } + + if (block_prev->next != MR_NULL) + { + /* 如果前一内存块与需要插入的内存块相连则向前合并 */ + if ((void *)(((uint8_t *)block_prev) + sizeof(struct mr_heap_block) + block_prev->size) == (void *)block) + { + block_prev->size += block->size + sizeof(struct mr_heap_block); + block = block_prev; + } + + /* 如果需要插入的内存块与后一内存块于相连则向后合并 */ + if ((void *)(((uint8_t *)block) + sizeof(struct mr_heap_block) + block->size) == (void *)block_prev->next) + { + block->size += block_prev->next->size + sizeof(struct mr_heap_block); + block->next = block_prev->next->next; + + /* 判断当前内存块是否插入*/ + if (block != block_prev) + { + block_prev->next = block; + block = block_prev; + } + } + } + + /* 若内存块未插入,则插入内存块 */ + if (block != block_prev) + { + block->next = block_prev->next; + block_prev->next = block; + } +} +``` \ No newline at end of file diff --git a/module/etask/etask.c b/module/etask/etask.c deleted file mode 100644 index 1c685cd..0000000 --- a/module/etask/etask.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * @copyright (c) 2023, MR Development Team - * - * @license SPDX-License-Identifier: Apache-2.0 - * - * @date 2023-11-17 MacRsh First version - */ - -#include "etask.h" - -#ifdef MR_USING_ETASK - -static struct mr_etask _etask = {0}; - -struct mr_event -{ - struct mr_avl list; - struct mr_list tlist; - union - { - struct - { - uint32_t timer: 1; - uint32_t hard: 1; - uint32_t oneshot: 1; - }; - uint32_t _sflags: 3; - } sflags; - uint32_t interval: 29; - uint32_t timeout; - - int (*cb)(struct mr_etask *et, void *args); - void *args; -}; - -static void etask_timing(struct mr_etask *etask, struct mr_event *event, uint32_t time) -{ - struct mr_list *list = MR_NULL; - - if (event->sflags.timer == MR_DISABLE) - { - return; - } - - if (time == 0) - { - /* Disable interrupt */ - mr_interrupt_disable(); - - /* Insert the event into the etask list */ - mr_avl_remove(&etask->list, &event->list); - if (mr_list_is_empty(&etask->tlist) == MR_TRUE) - { - mr_list_remove(&event->tlist); - } - - /* Enable interrupt */ - mr_interrupt_enable(); - - /* Free the event */ - mr_free(event); - return; - } - - event->interval = (event->sflags.oneshot == MR_ENABLE) ? 0 : time; - event->timeout = etask->tick + time; - - /* Disable interrupt */ - mr_interrupt_disable(); - - /* Insert the event into the etask timer-list */ - for (list = etask->tlist.next; list != &etask->tlist; list = list->next) - { - struct mr_event *be_insert = (struct mr_event *)mr_container_of(list, struct mr_event, tlist); - - if (event->timeout < be_insert->timeout) - { - mr_list_insert_before(&be_insert->tlist, &event->tlist); - break; - } - } - if (mr_list_is_empty(&event->tlist) == MR_TRUE) - { - mr_list_insert_before(&etask->tlist, &event->tlist); - } - - /* Enable interrupt */ - mr_interrupt_enable(); -} - -static void mr_etask_free_event(struct mr_avl *tree) -{ - if (tree->left_child != MR_NULL) - { - mr_etask_free_event(tree->left_child); - tree->left_child = MR_NULL; - } - - if (tree->right_child != MR_NULL) - { - mr_etask_free_event(tree->right_child); - tree->right_child = MR_NULL; - } - - struct mr_event *event = (struct mr_event *)mr_container_of(tree, struct mr_event, list); - mr_free(event); -} - -void etask_init(struct mr_etask *etask, void *pool, size_t size) -{ - mr_assert(etask->magic != MR_MAGIC_NUMBER); - mr_assert((pool != MR_NULL) || (size == 0)); - - /* Initialize the fields */ - etask->magic = MR_MAGIC_NUMBER; - etask->tick = 0; - mr_ringbuf_init(&etask->queue, pool, size); - etask->list = MR_NULL; - mr_list_init(&etask->tlist); - etask->state = MR_NULL; -} - -void etask_uninit(struct mr_etask *etask) -{ - mr_assert(etask->magic == MR_MAGIC_NUMBER); - - /* Free the queue */ - mr_free(etask->queue.buffer); - mr_ringbuf_init(&etask->queue, MR_NULL, 0); - mr_etask_free_event(etask->list); - etask->list = MR_NULL; - mr_list_init(&etask->tlist); - etask->state = MR_NULL; -} - -void etask_tick_update(struct mr_etask *etask) -{ - struct mr_list *list = MR_NULL; - - etask->tick++; - - for (list = etask->tlist.next; list != &etask->tlist; list = list->next) - { - struct mr_event *event = (struct mr_event *)mr_container_of(list, struct mr_event, tlist); - - /* Check whether the current tick is larger than the timeout */ - if ((etask->tick - event->timeout) >= UINT16_MAX) - { - break; - } - - /* Remove a timeout event */ - list = list->prev; - mr_list_remove(&event->tlist); - - /* Call the callback */ - if (event->sflags.hard == MR_ENABLE) - { - event->cb(etask, event->args); - } else - { - etask_wakeup(etask, event->list.value, MR_ETASK_WFLAG_DELAY); - } - - /* Update the timing */ - etask_timing(etask, event, event->interval); - } -} - -void etask_handle(struct mr_etask *etask) -{ - size_t count = 0; - uint32_t id = 0; - - mr_assert(etask != MR_NULL); - - /* Get the number of current events */ - count = mr_ringbuf_get_data_size(&etask->queue); - - /* Read the event id from the queue */ - while (count != 0) - { - /* Read the event id */ - count -= mr_ringbuf_read(&etask->queue, &id, sizeof(id)); - - /* Find the event */ - struct mr_event *event = (struct mr_event *)mr_avl_find(etask->list, id); - if (event == MR_NULL) - { - continue; - } - - /* Call the event callback */ - event->cb(etask, event->args); - } - - if (etask->state != MR_NULL) - { - struct mr_event *event = (struct mr_event *)etask->state; - - /* Call the state callback */ - event->cb(etask, event->args); - } -} - -int etask_start(struct mr_etask *etask, - uint32_t id, - uint8_t sflags, - size_t time, - int (*cb)(struct mr_etask *et, void *args), - void *args) -{ - struct mr_event *event = MR_NULL; - - mr_assert(etask != MR_NULL); - mr_assert(((sflags & MR_ETASK_SFLAG_TIMER) != MR_ETASK_SFLAG_TIMER) || time != 0); - mr_assert(cb != MR_NULL); - - /* Check if the event already exists */ - if (mr_avl_find(etask->list, id) != MR_NULL) - { - return MR_EBUSY; - } - - /* Allocate the event */ - event = (struct mr_event *)mr_malloc(sizeof(struct mr_event)); - if (event == MR_NULL) - { - return MR_ENOMEM; - } - - /* Initialize the fields */ - mr_avl_init(&event->list, id); - mr_list_init(&event->tlist); - event->sflags._sflags = sflags; - event->cb = cb; - event->args = args; - - /* Disable interrupt */ - mr_interrupt_disable(); - - /* Insert the event into the etask list */ - mr_avl_insert(&(etask->list), &(event->list)); - - /* Enable interrupt */ - mr_interrupt_enable(); - - /* Start the timer */ - etask_timing(etask, event, time); - return MR_EOK; -} - -int etask_stop(struct mr_etask *etask, uint32_t id) -{ - struct mr_event *event = MR_NULL; - - mr_assert(etask != MR_NULL); - - /* Check if the event already exists */ - event = (struct mr_event *)mr_avl_find(etask->list, id); - if (event == MR_NULL) - { - return MR_ENOTFOUND; - } - - /* Disable interrupt */ - mr_interrupt_disable(); - - /* Insert the event into the etask list */ - mr_avl_remove(&etask->list, &event->list); - if (mr_list_is_empty(&etask->tlist) == MR_FALSE) - { - mr_list_remove(&event->tlist); - } - - /* Enable interrupt */ - mr_interrupt_enable(); - - /* Free the event */ - mr_free(event); - return MR_EOK; -} - -int etask_wakeup(struct mr_etask *etask, uint32_t id, uint8_t wflag) -{ - mr_assert(etask != MR_NULL); - mr_assert(wflag == MR_ETASK_WFLAG_DELAY || wflag == MR_ETASK_WFLAG_NOW || wflag == MR_ETASK_WFLAG_STATE); - - if (wflag == MR_ETASK_WFLAG_DELAY) - { - if (mr_ringbuf_write(&etask->queue, &id, sizeof(id)) != sizeof(id)) - { - return MR_EBUSY; - } - } else - { - struct mr_event *event = (struct mr_event *)mr_avl_find(etask->list, id); - if (event == MR_NULL) - { - return MR_ENOTFOUND; - } - - if (wflag == MR_ETASK_WFLAG_NOW) - { - /* Call the event callback */ - event->cb(etask, event->args); - } else - { - /* Set the state machine */ - etask->state = (void *)event; - } - } - return MR_EOK; -} - -/** - * @brief This function initializes the etask module. - * - * @param pool The queue pool of the etask. - * @param size The size of the queue pool. - */ -void mr_etask_init(void *pool, size_t size) -{ - etask_init(&_etask, pool, size); -} - -/** - * @brief This function uninitializes the etask module. - */ -void mr_etask_uninit(void) -{ - etask_uninit(&_etask); -} - -/** - * @brief This function updates the etask module tick. - */ -void mr_etask_tick_update(void) -{ - etask_tick_update(&_etask); -} - -/** - * @brief This function handles events of the etask queue. - */ -void mr_etask_handle(void) -{ - etask_handle(&_etask); -} - -/** - * @brief This function starts an event. - * - * @param id The id of the event. - * @param sflags The start flags of the event. - * @param time The time of the event. - * @param cb The callback function of the event. - * @param args The arguments of the callback function. - * - * @return MR_ERR_OK on success, otherwise an error code. - */ -int mr_etask_start(uint32_t id, uint8_t sflags, size_t time, int (*cb)(struct mr_etask *et, void *args), void *args) -{ - return etask_start(&_etask, id, sflags, time, cb, args); -} - -/** - * @brief This function stops an event. - * - * @param id The id of the event. - * - * @return MR_ERR_OK on success, otherwise an error code. - */ -int mr_etask_stop(uint32_t id) -{ - return etask_stop(&_etask, id); -} - -/** - * @brief This function wakes up an event. - * - * @param id The id of the event. - * @param wflag The wakeup flag of the event. - * - * @return MR_ERR_OK on success, otherwise an error code. - */ -int mr_etask_wakeup(uint32_t id, uint8_t wflag) -{ - return etask_wakeup(&_etask, id, wflag); -} - -#endif /* MR_USING_ETASK */ \ No newline at end of file diff --git a/module/etask/etask.h b/module/etask/etask.h deleted file mode 100644 index fa16479..0000000 --- a/module/etask/etask.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * @copyright (c) 2023, MR Development Team - * - * @license SPDX-License-Identifier: Apache-2.0 - * - * @date 2023-11-17 MacRsh First version - */ - -#ifndef _ETASK_H_ -#define _ETASK_H_ - -#include "include/mr_api.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifdef MR_USING_ETASK - -/** -* @brief Etask start flag -*/ -#define MR_ETASK_SFLAG_EVENT (0x00) /* Event */ -#define MR_ETASK_SFLAG_TIMER (0x01) /* Timer */ -#define MR_ETASK_SFLAG_HARD (0x02) /* Hard */ -#define MR_ETASK_SFLAG_SOFT (0x00) /* Soft */ -#define MR_ETASK_SFLAG_ONESHOT (0x04) /* One shot */ -#define MR_ETASK_SFLAG_PERIODIC (0x00) /* Periodic */ - -/** - * @brief Etask wakeup flag - */ -#define MR_ETASK_WFLAG_NOW (0x00) /* Wakeup immediately */ -#define MR_ETASK_WFLAG_DELAY (0x01) /* Wakeup after delay */ -#define MR_ETASK_WFLAG_STATE (0x02) /* Wakeup by state */ - -/** - * @brief Etask - */ -struct mr_etask -{ - uint32_t magic; /* Magic */ - uint32_t tick; /* Tick */ - struct mr_ringbuf queue; /* Queue */ - struct mr_avl *list; /* Event list */ - struct mr_list tlist; /* Timing list */ - void *state; /* State */ -}; - -/** - * @addtogroup Etask - * @{ - */ -void mr_etask_init(void *pool, size_t size); -void mr_etask_uninit(void); -void mr_etask_tick_update(void); -void mr_etask_handle(void); -int mr_etask_start(uint32_t id, uint8_t sflags, size_t time, int (*cb)(struct mr_etask *et, void *args), void *args); -int mr_etask_stop(uint32_t id); -int mr_etask_wakeup(uint32_t id, uint8_t wflag); - -void etask_init(struct mr_etask *etask, void *pool, size_t size); -void etask_uninit(struct mr_etask *etask); -void etask_tick_update(struct mr_etask *etask); -void etask_handle(struct mr_etask *etask); -int etask_start(struct mr_etask *etask, - uint32_t id, - uint8_t sflags, - size_t time, - int (*cb)(struct mr_etask *et, void *args), - void *args); -int etask_stop(struct mr_etask *etask, uint32_t id); -int etask_wakeup(struct mr_etask *etask, uint32_t id, uint8_t wflag); -/** @} */ -#endif /* MR_USING_ETASK */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _ETASK_H_ */ diff --git a/module/hx711/hx711.c b/module/hx711/hx711.c deleted file mode 100644 index f376d03..0000000 --- a/module/hx711/hx711.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * @copyright (c) 2023, MR Development Team - * - * @license SPDX-License-Identifier: Apache-2.0 - * - * @date 2023-11-17 MacRsh First version - */ - -#include "hx711.h" - -#ifdef MR_USING_HX711 - -#if !defined(MR_USING_PIN) -#error "Please define MR_USING_PIN. Otherwise HX711 will not work." -#else - -#include "include/device/pin.h" - -static void hx711_set_sck(struct mr_hx711 *hx711, uint8_t value) -{ - mr_dev_ioctl(hx711->desc, MR_CTL_SET_OFFSET, &hx711->sck_pin); - mr_dev_write(hx711->desc, &value, sizeof(value)); -} - -static uint8_t hx711_get_dout(struct mr_hx711 *hx711) -{ - uint8_t value = 0; - - mr_dev_ioctl(hx711->desc, MR_CTL_SET_OFFSET, &hx711->dout_pin); - mr_dev_read(hx711->desc, &value, sizeof(value)); - return value; -} - -static uint32_t hx711_get_value(struct mr_hx711 *hx711) -{ - uint32_t value = 0; - int i = 0; - - /* Start the conversion */ - hx711_set_sck(hx711, 0); - mr_delay_us(1); - while (hx711_get_dout(hx711) != 0) - { - i++; - if (i > UINT16_MAX) - { - return 0; - } - } - - /* Get the value */ - for (i = 0; i < 24; i++) - { - hx711_set_sck(hx711, 1); - value <<= 1; - mr_delay_us(1); - hx711_set_sck(hx711, 0); - if (hx711_get_dout(hx711) == 1) - { - value++; - } - mr_delay_us(1); - } - hx711_set_sck(hx711, 1); - value = value ^ 0x800000; - mr_delay_us(1); - hx711_set_sck(hx711, 0); - - /* Filter the value */ - mr_bits_clr(value, (1 << hx711->filter_bits) - 1); - return value; -} - -static int mr_hx711_open(struct mr_dev *dev) -{ - struct mr_hx711 *hx711 = (struct mr_hx711 *)dev; - - hx711->desc = mr_dev_open("pin", MR_OFLAG_RDWR); - if (hx711->desc < 0) - { - return hx711->desc; - } - - /* Set the sck pin mode */ - mr_dev_ioctl(hx711->desc, MR_CTL_PIN_SET_NUMBER, &hx711->sck_pin); - mr_dev_ioctl(hx711->desc, MR_CTL_PIN_SET_MODE, mr_make_local(int, MR_PIN_MODE_OUTPUT)); - - /* Set the dout pin mode */ - mr_dev_ioctl(hx711->desc, MR_CTL_PIN_SET_NUMBER, &hx711->dout_pin); - mr_dev_ioctl(hx711->desc, MR_CTL_PIN_SET_MODE, mr_make_local(int, MR_PIN_MODE_INPUT_UP)); - return MR_EOK; -} - -static int mr_hx711_close(struct mr_dev *dev) -{ - struct mr_hx711 *hx711 = (struct mr_hx711 *)dev; - - /* Reset the sck pin mode */ - mr_dev_ioctl(hx711->desc, MR_CTL_PIN_SET_NUMBER, &hx711->sck_pin); - mr_dev_ioctl(hx711->desc, MR_CTL_PIN_SET_MODE, mr_make_local(int, MR_PIN_MODE_NONE)); - - /* Reset the dout pin mode */ - mr_dev_ioctl(hx711->desc, MR_CTL_PIN_SET_NUMBER, &hx711->dout_pin); - mr_dev_ioctl(hx711->desc, MR_CTL_PIN_SET_MODE, mr_make_local(int, MR_PIN_MODE_NONE)); - - mr_dev_close(hx711->desc); - hx711->desc = -1; - return MR_EOK; -} - -static ssize_t mr_hx711_read(struct mr_dev *dev, int off, void *buf, size_t size, int async) -{ - struct mr_hx711 *hx711 = (struct mr_hx711 *)dev; - uint32_t *rd_buf = (uint32_t *)buf; - ssize_t rd_size = 0; - - mr_bits_clr(size, sizeof(*rd_buf) - 1); - for (rd_size = 0; rd_size < size; rd_size += sizeof(*rd_buf)) - { - uint32_t value = hx711_get_value(hx711); - *rd_buf = (value > hx711->self_cal) ? (value - hx711->self_cal) : 0; - rd_buf++; - } - return rd_size; -} - -static int mr_hx711_ioctl(struct mr_dev *dev, int off, int cmd, void *args) -{ - struct mr_hx711 *hx711 = (struct mr_hx711 *)dev; - - switch (cmd) - { - case MR_CTL_HX711_SET_FILTER_BITS: - { - if (args != MR_NULL) - { - int filter = *(int *)args; - hx711->filter_bits = filter; - return MR_EOK; - } - return MR_EINVAL; - } - case MR_CTL_HX711_SET_SELF_CAL: - { - hx711->self_cal = hx711_get_value(hx711); - return MR_EOK; - } - - case MR_CTL_HX711_GET_FILTER_BITS: - { - if (args != MR_NULL) - { - *(int *)args = hx711->filter_bits; - return MR_EOK; - } - return MR_EINVAL; - } - case MR_CTL_HX711_GET_SELF_CAL: - { - if (args != MR_NULL) - { - *(uint32_t *)args = hx711->self_cal; - return MR_EOK; - } - return MR_EINVAL; - } - - default: - { - return MR_ENOTSUP; - } - } -} - -/** - * @brief This function register a hx711 module. - * - * @param hx711 The hx711 module. - * @param name The name of the hx711 module. - * @param sck_pin The sck pin of the hx711 module. - * @param dout_pin The dout pin of the hx711 module. - * - * @return MR_EOK on success, otherwise an error code. - */ -int mr_hx711_register(struct mr_hx711 *hx711, const char *name, int sck_pin, int dout_pin) -{ - static struct mr_dev_ops ops = - { - mr_hx711_open, - mr_hx711_close, - mr_hx711_read, - MR_NULL, - mr_hx711_ioctl, - MR_NULL - }; - - mr_assert(hx711 != MR_NULL); - mr_assert(name != MR_NULL); - mr_assert(sck_pin >= 0); - mr_assert(dout_pin >= 0); - - /* Initialize the fields */ - hx711->filter_bits = 0; - hx711->self_cal = 0; - hx711->sck_pin = sck_pin; - hx711->dout_pin = dout_pin; - hx711->desc = -1; - - /* Register the hx711 */ - return mr_dev_register(&hx711->dev, name, Mr_Dev_Type_ADC, MR_SFLAG_RDONLY | MR_SFLAG_NONDRV, &ops, MR_NULL); -} - -#endif /* MR_USING_PIN */ - -#endif /* MR_USING_HX711 */ diff --git a/module/hx711/hx711.h b/module/hx711/hx711.h deleted file mode 100644 index 9a62e55..0000000 --- a/module/hx711/hx711.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * @copyright (c) 2023, MR Development Team - * - * @license SPDX-License-Identifier: Apache-2.0 - * - * @date 2023-11-17 MacRsh First version - */ - -#ifndef _HX711_H_ -#define _HX711_H_ - -#include "include/mr_api.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifdef MR_USING_HX711 - -/** - * @brief HX711 command. - */ -#define MR_CTL_HX711_SET_FILTER_BITS ((0x01|0x80) << 16) /**< Set filter bits */ -#define MR_CTL_HX711_SET_SELF_CAL ((0x02|0x80) << 16) /**< Set self calibration */ -#define MR_CTL_HX711_GET_FILTER_BITS ((0x01|0x00) << 16) /**< Get filter bits */ -#define MR_CTL_HX711_GET_SELF_CAL ((0x02|0x00) << 16) /**< Get self calibration */ - -/** - * @brief HX711 data type. - */ -typedef uint32_t mr_hx711_data_t; /**< HX711 read data type */ - -/** - * @brief Hx711 structure. - */ -struct mr_hx711 -{ - struct mr_dev dev; /**< Device */ - - int filter_bits; /**< Filter bits */ - uint32_t self_cal; /**< Self calibration */ - int sck_pin; /**< SCK pin */ - int dout_pin; /**< DOUT pin */ - int desc; /**< Descriptor */ -}; - -/** - * @addtogroup HX711. - * @{ - */ -int mr_hx711_register(struct mr_hx711 *hx711, const char *name, int sck_pin, int dout_pin); -/** @} */ -#endif /* MR_USING_HX711 */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _HX711_H_ */ diff --git a/module/icm20602/icm20602.c b/module/icm20602/icm20602.c deleted file mode 100644 index ef7fc12..0000000 --- a/module/icm20602/icm20602.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * @copyright (c) 2023, MR Development Team - * - * @license SPDX-License-Identifier: Apache-2.0 - * - * @date 2023-11-17 MacRsh First version - */ - -#include "icm20602.h" - -#ifdef MR_USING_ICM20602 - -#define ICM20602_SMPLRT_DIV (0x19) -#define ICM20602_CONFIG (0x1A) -#define ICM20602_GYRO_CONFIG (0x1B) -#define ICM20602_ACCEL_CONFIG (0x1C) -#define ICM20602_ACCEL_CONFIG_2 (0x1D) -#define ICM20602_ACCEL_XOUT_H (0x3B) -#define ICM20602_GYRO_XOUT_H (0x43) -#define ICM20602_PWR_MGMT_1 (0x6B) -#define ICM20602_PWR_MGMT_2 (0x6C) -#define ICM20602_WHO_AM_I (0x75) - -static void icm20602_write_reg(struct mr_icm20602 *icm20602, uint8_t reg, uint8_t data) -{ - mr_dev_ioctl(icm20602->desc, MR_CTL_SET_OFFSET, mr_make_local(int, reg)); - mr_dev_write(icm20602->desc, &data, sizeof(data)); -} - -static uint8_t icm20602_read_reg(struct mr_icm20602 *icm20602, uint8_t reg) -{ - uint8_t data = 0; - - mr_dev_ioctl(icm20602->desc, MR_CTL_SET_OFFSET, mr_make_local(int, reg | 0x80)); - mr_dev_read(icm20602->desc, &data, sizeof(data)); - return data; -} - -static ssize_t icm20602_read_regs(struct mr_icm20602 *icm20602, uint8_t reg, uint8_t *buf, size_t size) -{ - mr_dev_ioctl(icm20602->desc, MR_CTL_SET_OFFSET, mr_make_local(int, reg | 0x80)); - return mr_dev_read(icm20602->desc, buf, size); -} - -static int icm20602_self_check(struct mr_icm20602 *icm20602) -{ - size_t count = 0; - - for (count = 0; count < 200; count++) - { - if (icm20602_read_reg(icm20602, ICM20602_WHO_AM_I) == 0x12) - { - return MR_TRUE; - } - } - return MR_FALSE; -} - -static int icm20602_config(struct mr_icm20602 *icm20602, struct mr_icm20602_config *config) -{ - switch (config->acc_range) - { - case MR_ICM20602_ACC_RANGE_2G: - { - icm20602_write_reg(icm20602, ICM20602_ACCEL_CONFIG, 0x00); - break; - } - case MR_ICM20602_ACC_RANGE_4G: - { - icm20602_write_reg(icm20602, ICM20602_ACCEL_CONFIG, 0x08); - break; - } - case MR_ICM20602_ACC_RANGE_8G: - { - icm20602_write_reg(icm20602, ICM20602_ACCEL_CONFIG, 0x10); - break; - } - case MR_ICM20602_ACC_RANGE_16G: - { - icm20602_write_reg(icm20602, ICM20602_ACCEL_CONFIG, 0x18); - break; - } - - default: - { - return MR_ENOTSUP; - } - } - - switch (config->gyro_range) - { - case MR_ICM20602_GYRO_RANGE_250DPS: - { - icm20602_write_reg(icm20602, ICM20602_GYRO_CONFIG, 0x00); - break; - } - case MR_ICM20602_GYRO_RANGE_500DPS: - { - icm20602_write_reg(icm20602, ICM20602_GYRO_CONFIG, 0x08); - break; - } - case MR_ICM20602_GYRO_RANGE_1000DPS: - { - icm20602_write_reg(icm20602, ICM20602_GYRO_CONFIG, 0x10); - break; - } - case MR_ICM20602_GYRO_RANGE_2000DPS: - { - icm20602_write_reg(icm20602, ICM20602_GYRO_CONFIG, 0x18); - break; - } - - default: - { - return MR_ENOTSUP; - } - } - icm20602->config = *config; - return MR_EOK; -} - -static int mr_icm20602_open(struct mr_dev *dev) -{ - struct mr_icm20602 *icm20602 = (struct mr_icm20602 *)dev; - char full_name[MR_CFG_NAME_MAX * 2 + 1] = {0}; - struct mr_spi_config config = MR_SPI_CONFIG_DEFAULT; - size_t i = 0; - - /* Open the icm20602 spi-device */ - int ret = mr_dev_get_full_name(dev, full_name, sizeof(full_name)); - if (ret != MR_EOK) - { - return ret; - } - icm20602->desc = mr_dev_open(full_name, MR_OFLAG_RDWR); - if (icm20602->desc < 0) - { - return icm20602->desc; - } - config.baud_rate = 10 * 1000 * 1000; - mr_dev_ioctl(icm20602->desc, MR_CTL_SET_CONFIG, &config); - - /* Self check */ - if (icm20602_self_check(icm20602) == MR_FALSE) - { - mr_log("%s self check failed", dev->name); - return MR_ENOTFOUND; - } - - /* Restart */ - icm20602_write_reg(icm20602, ICM20602_PWR_MGMT_1, 0x80); - mr_delay_ms(10); - for (i = 0; i < 200; i++) - { - if (icm20602_read_reg(icm20602, ICM20602_PWR_MGMT_1) == 0x41) - { - break; - } - } - if (i == 200) - { - mr_log("%s restart failed\r\n", dev->name); - return MR_ENOTFOUND; - } - - /* Init config */ - icm20602_write_reg(icm20602, ICM20602_PWR_MGMT_1, 0x01); - icm20602_write_reg(icm20602, ICM20602_PWR_MGMT_2, 0x00); - icm20602_write_reg(icm20602, ICM20602_CONFIG, 0x01); - icm20602_write_reg(icm20602, ICM20602_SMPLRT_DIV, 0x07); - - ret = icm20602_config(icm20602, &icm20602->config); - if (ret != MR_EOK) - { - mr_log("%s init config failed\r\n", dev->name); - return ret; - } - icm20602_write_reg(icm20602, ICM20602_ACCEL_CONFIG_2, 0x03); - - return MR_EOK; -} - -static int mr_icm20602_close(struct mr_dev *dev) -{ - struct mr_icm20602 *icm20602 = (struct mr_icm20602 *)dev; - - /* Close the icm20602 spi-device */ - mr_dev_close(icm20602->desc); - icm20602->desc = -1; - - return MR_EOK; -} - -static ssize_t mr_icm20602_read(struct mr_dev *dev, int off, void *buf, size_t size, int async) -{ - struct mr_icm20602 *icm20602 = (struct mr_icm20602 *)dev; - struct mr_icm20602_data *rd_buf = (struct mr_icm20602_data *)buf; - uint8_t reg = (off == MR_ICM20602_ACC_OFFSET) ? ICM20602_ACCEL_XOUT_H : ICM20602_GYRO_XOUT_H; - ssize_t rd_size = 0; - - if ((off != MR_ICM20602_ACC_OFFSET) && (off != MR_ICM20602_GYRO_OFFSET)) - { - return MR_EINVAL; - } - - mr_bits_clr(size, sizeof(*rd_buf) - 1); - for (rd_size = 0; rd_size < size; rd_size += sizeof(*rd_buf)) - { - uint8_t axis_buf[6] = {0}; - icm20602_read_regs(icm20602, reg, axis_buf, sizeof(axis_buf)); - rd_buf->x = (int16_t)((axis_buf[0] << 8) | axis_buf[1]); - rd_buf->y = (int16_t)((axis_buf[2] << 8) | axis_buf[3]); - rd_buf->z = (int16_t)((axis_buf[4] << 8) | axis_buf[5]); - } - return rd_size; -} - -static int mr_icm20602_ioctl(struct mr_dev *dev, int off, int cmd, void *args) -{ - struct mr_icm20602 *icm20602 = (struct mr_icm20602 *)dev; - - switch (cmd) - { - case MR_CTL_SET_CONFIG: - { - if (args != MR_NULL) - { - struct mr_icm20602_config *config = (struct mr_icm20602_config *)args; - - return icm20602_config(icm20602, config); - } - return MR_EINVAL; - } - - case MR_CTL_GET_CONFIG: - { - if (args != MR_NULL) - { - struct mr_icm20602_config *config = (struct mr_icm20602_config *)args; - - *config = icm20602->config; - return MR_EOK; - } - return MR_EINVAL; - } - - default: - { - return MR_ENOTSUP; - } - } -} - -/** - * @brief This function register a icm20602 module. - * - * @param icm20602 The icm20602 module. - * @param name The name of the icm20602 module. - * @param cs_pin The cs pin of the icm20602 module. - * @param bus_name The spi-bus name of the icm20602 module. - * - * @return MR_EOK on success, otherwise an error code. - */ -int mr_icm20602_register(struct mr_icm20602 *icm20602, const char *name, int cs_pin, const char *bus_name) -{ - static struct mr_dev_ops ops = - { - mr_icm20602_open, - mr_icm20602_close, - mr_icm20602_read, - MR_NULL, - mr_icm20602_ioctl, - MR_NULL - }; - struct mr_icm20602_config default_config = MR_ICM20602_CONFIG_DEFAULT; - char cat_name[MR_CFG_NAME_MAX + MR_CFG_NAME_MAX + 1] = {0}; - int ret = 0; - - mr_assert(icm20602 != MR_NULL); - mr_assert(name != MR_NULL); - mr_assert(cs_pin >= 0); - mr_assert(bus_name != MR_NULL); - - /* Register the spi-device */ - sprintf(cat_name, "%s/%s", bus_name, name); - ret = mr_spi_dev_register(&icm20602->spi_dev, cat_name, cs_pin, MR_SPI_CS_ACTIVE_LOW); - if (ret != MR_EOK) - { - return ret; - } - - /* Initialize the fields */ - icm20602->config = default_config; - icm20602->desc = -1; - - /* Register the icm20602 */ - return mr_dev_register(&icm20602->dev, name, Mr_Dev_Type_Sensor, MR_SFLAG_RDONLY | MR_SFLAG_NONDRV, &ops, MR_NULL); -} - -#endif /* MR_USING_ICM20602 */ diff --git a/module/icm20602/icm20602.h b/module/icm20602/icm20602.h deleted file mode 100644 index 5fa6193..0000000 --- a/module/icm20602/icm20602.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * @copyright (c) 2023, MR Development Team - * - * @license SPDX-License-Identifier: Apache-2.0 - * - * @date 2023-11-17 MacRsh First version - */ - -#ifndef _ICM20602_H_ -#define _ICM20602_H_ - -#include "include/mr_api.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifdef MR_USING_ICM20602 - -#if !defined(MR_USING_SPI) -#undef MR_USING_ICM20602 -#error "Please define MR_USING_SPI. Otherwise ICM20602 will not work." -#else - -#include "include/device/spi.h" - -/** - * @brief ICM20602 acc Range. - */ -#define MR_ICM20602_ACC_RANGE_2G (2) /**< 2G */ -#define MR_ICM20602_ACC_RANGE_4G (4) /**< 4G */ -#define MR_ICM20602_ACC_RANGE_8G (8) /**< 8G */ -#define MR_ICM20602_ACC_RANGE_16G (16) /**< 16G */ - -/** - * @brief ICM20602 gyro Range. - */ -#define MR_ICM20602_GYRO_RANGE_250DPS (250) /**< 250DPS */ -#define MR_ICM20602_GYRO_RANGE_500DPS (500) /**< 500DPS */ -#define MR_ICM20602_GYRO_RANGE_1000DPS (1000) /**< 1000DPS */ -#define MR_ICM20602_GYRO_RANGE_2000DPS (2000) /**< 2000DPS */ - -/** - * @def ICM20602 default config. - */ -#define MR_ICM20602_CONFIG_DEFAULT \ -{ \ - MR_ICM20602_ACC_RANGE_8G, \ - MR_ICM20602_GYRO_RANGE_2000DPS, \ -} - -/** - * @brief ICM20602 config structure. - */ -struct mr_icm20602_config -{ - uint16_t acc_range; /**< Acc range */ - uint16_t gyro_range; /**< Gyro range */ -}; - -/** - * @brief ICM20602 offset. - */ -#define MR_ICM20602_ACC_OFFSET (0x00) /**< Acc offset */ -#define MR_ICM20602_GYRO_OFFSET (0x01) /**< Gyro offset */ - -/** - * @brief ICM20602 data type. - */ -typedef struct mr_icm20602_data -{ - int16_t x; /**< X axis */ - int16_t y; /**< Y axis */ - int16_t z; /**< Z axis */ -} mr_icm20602_data_t; /**< ICM20602 read data type */ - -/** - * @brief ICM20602 structure. - */ -struct mr_icm20602 -{ - struct mr_dev dev; /**< Device */ - - struct mr_spi_dev spi_dev; /**< SPI device */ - struct mr_icm20602_config config; /**< Config */ - int desc; /**< Descriptor */ -}; - -/** - * @addtogroup ICM20602. - * @{ - */ -int mr_icm20602_register(struct mr_icm20602 *icm20602, const char *name, int cs_pin, const char *bus_name); -/** @} */ -#endif /* MR_USING_SPI */ - -#endif /* MR_USING_ICM20602 */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _ICM20602_H_ */