#include #include /* Internal cache, used like chained list. @note: The KEYSC have 6 key data 16-bits registers this is why we used 6 * 16 = 96 cache slots. */ struct keycache_s keycache[96]; struct keycache_s *keylist; //--- // Private functions //--- /* keycache_alloc() : Try to alloc a new keycache node */ static struct keycache_s *keycache_alloc(int keycode, int keyframe) { void *node; cpu_atomic_start(); node = NULL; for (int i = 0; i < 96 ; ++i) { if (keycache[i].keycode == KEY_UNUSED) { keycache[i].keycode = keycode; keycache[i].keyframe = keyframe; keycache[i].repeated = 0; node = &keycache[i]; break; } } cpu_atomic_end(); return (node); } //--- // Secret entries //--- /* keycache_init() : keycache constructor */ void keycache_init(void) { for (int i = 0; i < 96 ; ++i) { keycache[i].keycode = KEY_UNUSED; keycache[i].next = NULL; } keylist = NULL; } //--- // Public API //--- /* keycache_update() : Add / update key code node */ void keycache_update(int row, int column, uint8_t keyframe) { struct keycache_s *node; uint8_t keycode; keycode = KEYCODE_GEN(row, column); cpu_atomic_start(); node = keylist; while (node != NULL) { if (node->keycode == keycode) { node->keyframe = keyframe; break; } node = node->next; } if (node == NULL) { node = keycache_alloc(keycode, keyframe); if (node != NULL) { node->next = keylist; keylist = node; } } cpu_atomic_end(); } /* keycache_clean() : Remove dirty node */ void keycache_clean(int keyframe) { struct keycache_s **current_node; cpu_atomic_start(); current_node = &keylist; while (*current_node != NULL) { if ((*current_node)->keyframe != keyframe) { (*current_node)->keycode = KEY_UNUSED; *current_node = (*current_node)->next; continue; } (*current_node)->repeated = (*current_node)->repeated + 1; current_node = &(*current_node)->next; } cpu_atomic_end(); }