aboutsummaryrefslogtreecommitdiffstats
path: root/quantum/process_keycode/process_magic.c
blob: 44dd5f0579552eef30319f0a8623359137a6cc5d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/* Copyright 2019 Jack Humbert
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "process_magic.h"

#ifdef AUDIO_ENABLE
#    ifndef AG_NORM_SONG
#        define AG_NORM_SONG SONG(AG_NORM_SOUND)
#    endif
#    ifndef AG_SWAP_SONG
#        define AG_SWAP_SONG SONG(AG_SWAP_SOUND)
#    endif
#    ifndef CG_NORM_SONG
#        define CG_NORM_SONG SONG(AG_NORM_SOUND)
#    endif
#    ifndef CG_SWAP_SONG
#        define CG_SWAP_SONG SONG(AG_SWAP_SOUND)
#    endif
float ag_norm_song[][2] = AG_NORM_SONG;
float ag_swap_song[][2] = AG_SWAP_SONG;
float cg_norm_song[][2] = CG_NORM_SONG;
float cg_swap_song[][2] = CG_SWAP_SONG;
#endif

/**
 * MAGIC actions (BOOTMAGIC without the boot)
 */
bool process_magic(uint16_t keycode, keyrecord_t *record) {
    // skip anything that isn't a keyup
    if (record->event.pressed) {
        switch (keycode) {
            case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_ALT_GUI:
            case MAGIC_SWAP_LCTL_LGUI ... MAGIC_EE_HANDS_RIGHT:
                /* keymap config */
                keymap_config.raw = eeconfig_read_keymap();
                switch (keycode) {
                    case MAGIC_SWAP_CONTROL_CAPSLOCK:
                        keymap_config.swap_control_capslock = true;
                        break;
                    case MAGIC_CAPSLOCK_TO_CONTROL:
                        keymap_config.capslock_to_control = true;
                        break;
                    case MAGIC_SWAP_LALT_LGUI:
                        keymap_config.swap_lalt_lgui = true;
                        break;
                    case MAGIC_SWAP_RALT_RGUI:
                        keymap_config.swap_ralt_rgui = true;
                        break;
                    case MAGIC_SWAP_LCTL_LGUI:
                        keymap_config.swap_lctl_lgui = true;
                        break;
                    case MAGIC_SWAP_RCTL_RGUI:
                        keymap_config.swap_rctl_rgui = true;
                        break;
                    case MAGIC_NO_GUI:
                        keymap_config.no_gui = true;
                        break;
                    case MAGIC_SWAP_GRAVE_ESC:
                        keymap_config.swap_grave_esc = true;
                        break;
                    case MAGIC_SWAP_BACKSLASH_BACKSPACE:
                        keymap_config.swap_backslash_backspace = true;
                        break;
                    case MAGIC_HOST_NKRO:
                        clear_keyboard();  // clear first buffer to prevent stuck keys
                        keymap_config.nkro = true;
                        break;
                    case MAGIC_SWAP_ALT_GUI:
                        keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = true;
#ifdef AUDIO_ENABLE
                        PLAY_SONG(ag_swap_song);
#endif
                        break;
                    case MAGIC_SWAP_CTL_GUI:
                        keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = true;
#ifdef AUDIO_ENABLE
                        PLAY_SONG(cg_swap_song);
#endif
                        break;
                    case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
                        keymap_config.swap_control_capslock = false;
                        break;
                    case MAGIC_UNCAPSLOCK_TO_CONTROL:
                        keymap_config.capslock_to_control = false;
                        break;
                    case MAGIC_UNSWAP_LALT_LGUI:
                        keymap_config.swap_lalt_lgui = false;
                        break;
                    case MAGIC_UNSWAP_RALT_RGUI:
                        keymap_config.swap_ralt_rgui = false;
                        break;
                    case MAGIC_UNSWAP_LCTL_LGUI:
                        keymap_config.swap_lctl_lgui = false;
                        break;
                    case MAGIC_UNSWAP_RCTL_RGUI:
                        keymap_config.swap_rctl_rgui = false;
                        break;
                    case MAGIC_UNNO_GUI:
                        keymap_config.no_gui = false;
                        break;
                    case MAGIC_UNSWAP_GRAVE_ESC:
                        keymap_config.swap_grave_esc = false;
                        break;
                    case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
                        keymap_config.swap_backslash_backspace = false;
                        break;
                    case MAGIC_UNHOST_NKRO:
                        clear_keyboard();  // clear first buffer to prevent stuck keys
                        keymap_config.nkro = false;
                        break;
                    case MAGIC_UNSWAP_ALT_GUI:
                        keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = false;
#ifdef AUDIO_ENABLE
                        PLAY_SONG(ag_norm_song);
#endif
                        break;
                    case MAGIC_UNSWAP_CTL_GUI:
                        keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = false;
#ifdef AUDIO_ENABLE
                        PLAY_SONG(cg_norm_song);
#endif
                        break;
                    case MAGIC_TOGGLE_ALT_GUI:
                        keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui;
                        keymap_config.swap_ralt_rgui = keymap_config.swap_lalt_lgui;
#ifdef AUDIO_ENABLE
                        if (keymap_config.swap_ralt_rgui) {
                            PLAY_SONG(ag_swap_song);
                        } else {
                            PLAY_SONG(ag_norm_song);
                        }
#endif
                        break;
                    case MAGIC_TOGGLE_CTL_GUI:
                        keymap_config.swap_lctl_lgui = !keymap_config.swap_lctl_lgui;
                        keymap_config.swap_rctl_rgui = keymap_config.swap_lctl_lgui;
#ifdef AUDIO_ENABLE
                        if (keymap_config.swap_rctl_rgui) {
                            PLAY_SONG(cg_swap_song);
                        } else {
                            PLAY_SONG(cg_norm_song);
                        }
#endif
                        break;
                    case MAGIC_TOGGLE_NKRO:
                        clear_keyboard();  // clear first buffer to prevent stuck keys
                        keymap_config.nkro = !keymap_config.nkro;
                        break;
                    case MAGIC_EE_HANDS_LEFT:
                        eeconfig_update_handedness(true);
                        break;
                    case MAGIC_EE_HANDS_RIGHT:
                        eeconfig_update_handedness(false);
                        break;
                }

                eeconfig_update_keymap(keymap_config.raw);
                clear_keyboard();  // clear to prevent stuck keys

                return false;
        }
    }

    // Not a magic keycode so continue processing
    return true;
}
ss="cm"> */ #include <string.h> #include "ch.h" #if (CH_CFG_USE_FACTORY == TRUE) || defined(__DOXYGEN__) /*===========================================================================*/ /* Module local definitions. */ /*===========================================================================*/ /* * Defaults on the best synchronization mechanism available. */ #if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__) #define F_LOCK() chMtxLock(&ch_factory.mtx) #define F_UNLOCK() chMtxUnlock(&ch_factory.mtx) #else #define F_LOCK() (void) chSemWait(&ch_factory.sem) #define F_UNLOCK() chSemSignal(&ch_factory.sem) #endif /*===========================================================================*/ /* Module exported variables. */ /*===========================================================================*/ /** * @brief Factory object static instance. * @note It is a global object because it could be accessed through * a specific debugger plugin. */ objects_factory_t ch_factory; /*===========================================================================*/ /* Module local types. */ /*===========================================================================*/ /*===========================================================================*/ /* Module local variables. */ /*===========================================================================*/ /*===========================================================================*/ /* Module local functions. */ /*===========================================================================*/ static inline void dyn_list_init(dyn_list_t *dlp) { dlp->next = (dyn_element_t *)dlp; } static dyn_element_t *dyn_list_find(const char *name, dyn_list_t *dlp) { dyn_element_t *p = dlp->next; while (p != (dyn_element_t *)dlp) { if (strncmp(p->name, name, CH_CFG_FACTORY_MAX_NAMES_LENGTH) == 0) { return p; } p = p->next; } return NULL; } static dyn_element_t *dyn_list_unlink(dyn_element_t *element, dyn_list_t *dlp) { dyn_element_t *prev = (dyn_element_t *)dlp; /* Scanning the list.*/ while (prev->next != (dyn_element_t *)dlp) { if (prev->next == element) { /* Found.*/ prev->next = element->next; return element; } /* Next element in the list.*/ prev = prev->next; } return NULL; } #if (CH_FACTORY_REQUIRES_HEAP == TRUE) || defined(__DOXYGEN__) static dyn_element_t *dyn_create_object_heap(const char *name, dyn_list_t *dlp, size_t size) { dyn_element_t *dep; chDbgCheck(name != NULL); /* Checking if an object with this name has already been created.*/ dep = dyn_list_find(name, dlp); if (dep != NULL) { return NULL; } /* Allocating space for the new buffer object.*/ dep = (dyn_element_t *)chHeapAlloc(NULL, size); if (dep == NULL) { return NULL; } /* Initializing object list element.*/ strncpy(dep->name, name, CH_CFG_FACTORY_MAX_NAMES_LENGTH); dep->refs = 1U; dep->next = dlp->next; /* Updating factory list.*/ dlp->next = dep; return dep; } static void dyn_release_object_heap(dyn_element_t *dep, dyn_list_t *dlp) { chDbgCheck(dep != NULL); chDbgAssert(dep->refs > 0U, "invalid references number"); dep->refs--; if (dep->refs == 0U) { dep = dyn_list_unlink(dep, dlp); chHeapFree((void *)dep); } } #endif /* CH_FACTORY_REQUIRES_HEAP == TRUE */ #if (CH_FACTORY_REQUIRES_POOLS == TRUE) || defined(__DOXYGEN__) static dyn_element_t *dyn_create_object_pool(const char *name, dyn_list_t *dlp, memory_pool_t *mp) { dyn_element_t *dep; chDbgCheck(name != NULL); /* Checking if an object object with this name has already been created.*/ dep = dyn_list_find(name, dlp); if (dep != NULL) { return NULL; } /* Allocating space for the new object.*/ dep = (dyn_element_t *)chPoolAlloc(mp); if (dep == NULL) { return NULL; } /* Initializing object list element.*/ strncpy(dep->name, name, CH_CFG_FACTORY_MAX_NAMES_LENGTH); dep->refs = 1U; dep->next = dlp->next; /* Updating factory list.*/ dlp->next = (dyn_element_t *)dep; return dep; } static void dyn_release_object_pool(dyn_element_t *dep, dyn_list_t *dlp, memory_pool_t *mp) { chDbgCheck(dep != NULL); chDbgAssert(dep->refs > 0U, "invalid references number"); dep->refs--; if (dep->refs == 0U) { dep = dyn_list_unlink(dep, dlp); chPoolFree(mp, (void *)dep); } } #endif /* CH_FACTORY_REQUIRES_POOLS == TRUE */ static dyn_element_t *dyn_find_object(const char *name, dyn_list_t *dlp) { dyn_element_t *dep; chDbgCheck(name != NULL); /* Checking if an object with this name has already been created.*/ dep = dyn_list_find(name, dlp); if (dep != NULL) { /* Increasing references counter.*/ dep->refs++; } return dep; } /*===========================================================================*/ /* Module exported functions. */ /*===========================================================================*/ /** * @brief Initializes the objects factory. * * @init */ void _factory_init(void) { #if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__) chMtxObjectInit(&ch_factory.mtx); #else chSemObjectInit(&ch_factory.sem, (cnt_t)1); #endif #if CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE dyn_list_init(&ch_factory.obj_list); chPoolObjectInit(&ch_factory.obj_pool, sizeof (registered_object_t), chCoreAllocAlignedI); #endif #if CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE dyn_list_init(&ch_factory.buf_list); #endif #if CH_CFG_FACTORY_SEMAPHORES == TRUE dyn_list_init(&ch_factory.sem_list); chPoolObjectInit(&ch_factory.sem_pool, sizeof (dyn_semaphore_t), chCoreAllocAlignedI); #endif #if CH_CFG_FACTORY_MAILBOXES == TRUE dyn_list_init(&ch_factory.mbx_list); #endif #if CH_CFG_FACTORY_OBJ_FIFOS == TRUE dyn_list_init(&ch_factory.fifo_list); #endif } #if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXIGEN__) /** * @brief Registers a generic object. * @post A reference to the registered object is returned and the * reference counter is initialized to one. * * @param[in] name name to be assigned to the registered object * @param[in] objp pointer to the object to be registered * * @return The reference to the registered object. * @retval NULL if the object to be registered cannot be allocated or * a registered object with the same name exists. * * @api */ registered_object_t *chFactoryRegisterObject(const char *name, void *objp) { registered_object_t *rop; F_LOCK(); rop = (registered_object_t *)dyn_create_object_pool(name, &ch_factory.obj_list, &ch_factory.obj_pool); if (rop != NULL) { /* Initializing registered object data.*/ rop->objp = objp; } F_UNLOCK(); return rop; } /** * @brief Retrieves a registered object. * @post A reference to the registered object is returned with the * reference counter increased by one. * * @param[in] name name of the registered object * * @return The reference to the found registered object. * @retval NULL if a registered object with the specified name * does not exist. * * @api */ registered_object_t *chFactoryFindObject(const char *name) { registered_object_t *rop; F_LOCK(); rop = (registered_object_t *)dyn_find_object(name, &ch_factory.obj_list); F_UNLOCK(); return rop; } /** * @brief Retrieves a registered object by pointer. * @post A reference to the registered object is returned with the * reference counter increased by one. * * @param[in] objp pointer to the object to be retrieved * * @return The reference to the found registered object. * @retval NULL if a registered object with the specified name * does not exist. * * @api */ registered_object_t *chFactoryFindObjectByPointer(void *objp) { registered_object_t *rop = (registered_object_t *)ch_factory.obj_list.next; F_LOCK(); while ((void *)rop != (void *)&ch_factory.obj_list) { if (rop->objp == objp) { rop->element.refs++; F_UNLOCK(); return rop; } rop = (registered_object_t *)rop->element.next; } F_UNLOCK(); return NULL; } /** * @brief Releases a registered object. * @details The reference counter of the registered object is decreased * by one, if reaches zero then the registered object memory * is freed. * @note The object itself is not freed, it could be static, only the * allocated list element is freed. * * @param[in] rop registered object reference * * @api */ void chFactoryReleaseObject(registered_object_t *rop){ F_LOCK(); dyn_release_object_pool(&rop->element, &ch_factory.obj_list, &ch_factory.obj_pool); F_UNLOCK(); } #endif /* CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE */ #if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXIGEN__) /** * @brief Creates a generic dynamic buffer object. * @post A reference to the dynamic buffer object is returned and the * reference counter is initialized to one. * @post The dynamic buffer object is filled with zeros. * * @param[in] name name to be assigned to the new dynamic buffer object * @param[in] size payload size of the dynamic buffer object to be created * * @return The reference to the created dynamic buffer object. * @retval NULL if the dynamic buffer object cannot be allocated or * a dynamic buffer object with the same name exists. * * @api */ dyn_buffer_t *chFactoryCreateBuffer(const char *name, size_t size) { dyn_buffer_t *dbp; F_LOCK(); dbp = (dyn_buffer_t *)dyn_create_object_heap(name, &ch_factory.buf_list, size); if (dbp != NULL) { /* Initializing buffer object data.*/ memset((void *)dbp->buffer, 0, size); } F_UNLOCK(); return dbp; } /** * @brief Retrieves a dynamic buffer object. * @post A reference to the dynamic buffer object is returned with the * reference counter increased by one. * * @param[in] name name of the dynamic buffer object * * @return The reference to the found dynamic buffer object. * @retval NULL if a dynamic buffer object with the specified name * does not exist. * * @api */ dyn_buffer_t *chFactoryFindBuffer(const char *name) { dyn_buffer_t *dbp; F_LOCK(); dbp = (dyn_buffer_t *)dyn_find_object(name, &ch_factory.buf_list); F_UNLOCK(); return dbp; } /** * @brief Releases a dynamic buffer object. * @details The reference counter of the dynamic buffer object is decreased * by one, if reaches zero then the dynamic buffer object memory * is freed. * * @param[in] dbp dynamic buffer object reference * * @api */ void chFactoryReleaseBuffer(dyn_buffer_t *dbp) { F_LOCK(); dyn_release_object_heap(&dbp->element, &ch_factory.buf_list); F_UNLOCK(); } #endif /* CH_CFG_FACTORY_GENERIC_BUFFERS = TRUE */ #if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__) /** * @brief Creates a dynamic semaphore object. * @post A reference to the dynamic semaphore object is returned and the * reference counter is initialized to one. * @post The dynamic semaphore object is initialized and ready to use. * * @param[in] name name to be assigned to the new dynamic semaphore object * @param[in] n dynamic semaphore object counter initialization value * * @return The reference to the created dynamic semaphore object. * @retval NULL if the dynamic semaphore object cannot be allocated or * a dynamic semaphore with the same name exists. * * @api */ dyn_semaphore_t *chFactoryCreateSemaphore(const char *name, cnt_t n) { dyn_semaphore_t *dsp; F_LOCK(); dsp = (dyn_semaphore_t *)dyn_create_object_pool(name, &ch_factory.sem_list, &ch_factory.sem_pool); if (dsp != NULL) { /* Initializing semaphore object dataa.*/ chSemObjectInit(&dsp->sem, n); } F_UNLOCK(); return dsp; } /** * @brief Retrieves a dynamic semaphore object. * @post A reference to the dynamic semaphore object is returned with the * reference counter increased by one. * * @param[in] name name of the dynamic semaphore object * * @return The reference to the found dynamic semaphore object. * @retval NULL if a dynamic semaphore object with the specified name * does not exist. * * @api */ dyn_semaphore_t *chFactoryFindSemaphore(const char *name) { dyn_semaphore_t *dsp; F_LOCK(); dsp = (dyn_semaphore_t *)dyn_find_object(name, &ch_factory.sem_list); F_UNLOCK(); return dsp; } /** * @brief Releases a dynamic semaphore object. * @details The reference counter of the dynamic semaphore object is decreased * by one, if reaches zero then the dynamic semaphore object memory * is freed. * * @param[in] dsp dynamic semaphore object reference * * @api */ void chFactoryReleaseSemaphore(dyn_semaphore_t *dsp) { F_LOCK(); dyn_release_object_pool(&dsp->element, &ch_factory.sem_list, &ch_factory.sem_pool); F_UNLOCK(); } #endif /* CH_CFG_FACTORY_SEMAPHORES = TRUE */ #if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXIGEN__) /** * @brief Creates a dynamic mailbox object. * @post A reference to the dynamic mailbox object is returned and the * reference counter is initialized to one. * @post The dynamic mailbox object is initialized and ready to use. * * @param[in] name name to be assigned to the new dynamic mailbox object * @param[in] n mailbox buffer size as number of messages * * @return The reference to the created dynamic mailbox object. * @retval NULL if the dynamic mailbox object cannot be allocated or * a dynamic mailbox object with the same name exists. * * @api */ dyn_mailbox_t *chFactoryCreateMailbox(const char *name, size_t n) { dyn_mailbox_t *dmp; F_LOCK(); dmp = (dyn_mailbox_t *)dyn_create_object_heap(name, &ch_factory.mbx_list, sizeof (dyn_mailbox_t) + (n * sizeof (msg_t))); if (dmp != NULL) { /* Initializing mailbox object data.*/ chMBObjectInit(&dmp->mbx, dmp->msgbuf, n); } F_UNLOCK(); return dmp; } /** * @brief Retrieves a dynamic mailbox object. * @post A reference to the dynamic mailbox object is returned with the * reference counter increased by one. * * @param[in] name name of the dynamic mailbox object * * @return The reference to the found dynamic mailbox object. * @retval NULL if a dynamic mailbox object with the specified name * does not exist. * * @api */ dyn_mailbox_t *chFactoryFindMailbox(const char *name) { dyn_mailbox_t *dmp; F_LOCK(); dmp = (dyn_mailbox_t *)dyn_find_object(name, &ch_factory.mbx_list); F_UNLOCK(); return dmp; } /** * @brief Releases a dynamic mailbox object. * @details The reference counter of the dynamic mailbox object is decreased * by one, if reaches zero then the dynamic mailbox object memory * is freed. * * @param[in] dmp dynamic mailbox object reference * * @api */ void chFactoryReleaseMailbox(dyn_mailbox_t *dmp) { F_LOCK(); dyn_release_object_heap(&dmp->element, &ch_factory.mbx_list); F_UNLOCK(); } #endif /* CH_CFG_FACTORY_MAILBOXES = TRUE */ #if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXIGEN__) /** * @brief Creates a dynamic "objects FIFO" object. * @post A reference to the dynamic "objects FIFO" object is returned and * the reference counter is initialized to one. * @post The dynamic "objects FIFO" object is initialized and ready to use. * * @param[in] name name to be assigned to the new dynamic "objects FIFO" * object * @param[in] objsize size of objects * @param[in] objn number of objects available * @param[in] objalign required objects alignment * @return The reference to the created dynamic "objects FIFO" * object. * @retval NULL if the dynamic "objects FIFO" object cannot be * allocated or a dynamic "objects FIFO" object with * the same name exists. * * @api */ dyn_objects_fifo_t *chFactoryCreateObjectsFIFO(const char *name, size_t objsize, size_t objn, unsigned objalign) { dyn_objects_fifo_t *dofp; F_LOCK(); dofp = (dyn_objects_fifo_t *)dyn_create_object_heap(name, &ch_factory.fifo_list, sizeof (dyn_objects_fifo_t) + (objn * sizeof (msg_t)) + (objn * objsize)); if (dofp != NULL) { /* Initializing mailbox object data.*/ chFifoObjectInit(&dofp->fifo, objsize, objn, objalign, (void *)&dofp->msgbuf[objn], dofp->msgbuf); } F_UNLOCK(); return dofp; } /** * @brief Retrieves a dynamic "objects FIFO" object. * @post A reference to the dynamic "objects FIFO" object is returned with * the reference counter increased by one. * * @param[in] name name of the dynamic "objects FIFO" object * * @return The reference to the found dynamic "objects FIFO" * object. * @retval NULL if a dynamic "objects FIFO" object with the specified * name does not exist. * * @api */ dyn_objects_fifo_t *chFactoryFindObjectsFIFO(const char *name) { dyn_objects_fifo_t *dofp; F_LOCK(); dofp = (dyn_objects_fifo_t *)dyn_find_object(name, &ch_factory.fifo_list); F_UNLOCK(); return dofp; } /** * @brief Releases a dynamic "objects FIFO" object. * @details The reference counter of the dynamic "objects FIFO" object is * decreased by one, if reaches zero then the dynamic "objects FIFO" * object memory is freed. * * @param[in] dofp dynamic "objects FIFO" object reference * * @api */ void chFactoryReleaseObjectsFIFO(dyn_objects_fifo_t *dofp) { F_LOCK(); dyn_release_object_heap(&dofp->element, &ch_factory.fifo_list); F_UNLOCK(); } #endif /* CH_CFG_FACTORY_MAILBOXES = TRUE */ #endif /* CH_CFG_USE_FACTORY == TRUE */ /** @} */