# tz's QMK todo list
## High-level list
In no particular order or priority.
* Community modules
* Pin/peripheral pre-configuration from json
* More introspection pre-work for adapting more stuff in flash (unicodemap, etc.)
* Rewrite NOR Flash driver to use SFDP, DDR/QDR
* littlefs / fatfs etc.
* SDcard support
* Ghoul rev2 / PCBA / QMK devkit
* Lich rev0
* Convert all QP handles to tokens
* XAP firmware consolidation
* XAP client
* SPI/I2C multi-bus abstractions
* SPI/I2C threadsafety
* Async Macros?
* Optional RAM write-through cache for SPI/I2C EEPROM reads
* QP region support
* QP transparency
* QP RGB/BGR switch
* Add `_pre` and `_post` hooks for all `_task` functions
## Bus safety
* **I2C/SPI mutual exclusion** required
* Multi-bus instances - I2C1, I2C2 etc.
* Rework Djinn/Ghoul rendering to secondary thread
* Add DMA MEM2MEM `memcpy()` for image data for framebuffers etc.
## Community modules
* `<qmk_firmware>/modules/xxxxxx` (format TBD)
* `info.json` and `keymap.json` gets support for `"modules": [ "drongocat" ]`
* Ordering of modules defines which order they're executed
* Codegen to add:
* `keyboard_pre_init_<module>`
* `keyboard_post_init_<module>`
* `process_record_<module>`
* `matrix_scan_<module>`
* `housekeeping_task_<module>`
* etc.
* Codegen also adds equivalent `xxxx_modules()` which invokes the above in order specified, the wrapper is added to normal location of original API hook
## Quantum Painter follow-up merges
* Optimise decoder etc. to do batching instead of doing one pixel at a time
* Image region support
* Allow for "transparent colour" embedded in images when working with framebuffers
* Multi-framebuffer manipulation to compose parallax scenes
* Render image to fbuf, rotate in-memory, render to next fbuf on top of bg, then stream final image to display at one point
## XAP
* See [XAP MVP](https://github.com/qmk/qmk_firmware/projects/4) project
* See [qmk/qmk_xap](https://github.com/qmk/qmk_xap)
* See [issue #11567](https://github.com/qmk/qmk_firmware/issues/11567)
* See [PR #13733](https://github.com/qmk/qmk_firmware/pull/13733)
## Data persistence (EEPROM) changes
* Need threadsafe bus work done!
* QMK erases as `0x00`, see if we can `^0xFF` to minimise writes
* Confirm what the `erase()` methodology is across drivers and platforms
* AVR doesn't do a full erase? Does it reset VIA keymaps?
* Add `nvm` API facade for all eeprom APIs that use actual datatypes/structs instead of `void*`
* Add ring fence so that we can swap out the lower-level APIs
* Update existing APIs where possible (external EEPROM, emulated etc.)
* May need different access pattern in order to deal with littlefs below -- bare bytewise offsets aren't the best
* optional RAM write-through cache for external EEPROM to minimise read latency
* depends on the size of the EEPROM
* already present on wear-leveling drivers
* ldscripts changes to preallocate an area of flash for emulated eeprom
* automatic assignment of different ldscript if using "vendor" driver?
* or validation of ldscript using known suffix like `__eeprom`?
* see if we can integrate [littlefs](https://github.com/littlefs-project/littlefs)
* partial file writes rewrite the whole file contents
* perhaps due to size -- 36 bytes of EEPROM possibly too small to "chunk" anyway
* needed for lua scripts and other dynamically uploadable stuff (QP images?)
## Hook simplifiers?
```c
#define QMK_DECLARE_TASK_PRE_POST(rettype, name, ...) \
void name##_pre(__VA_ARGS__); \
rettype name(__VA_ARGS__); \
void name##_post(__VA_ARGS__);
#define QMK_DEFINE_TASK_PRE_POST(rettype, name, params_in_parens, args_in_parens) \
__attribute__((weak)) void name##_pre params_in_parens {} \
static rettype name##_impl params_in_parens; \
__attribute__((weak)) void name##_post params_in_parens {} \
rettype name params_in_parens { \
name##_pre args_in_parens; \
rettype r = name##_impl args_in_parens; \
name##_post args_in_parens; \
return r; \
} \
static rettype name##_impl params_in_parens
#define QMK_DEFINE_TASK_PRE_POST_RETVOID(name, params_in_parens, args_in_parens) \
__attribute__((weak)) void name##_pre params_in_parens {} \
static void name##_impl params_in_parens; \
__attribute__((weak)) void name##_post params_in_parens {} \
void name params_in_parens { \
name##_pre args_in_parens; \
name##_impl args_in_parens; \
name##_post args_in_parens; \
} \
static void name##_impl params_in_parens
```