diff --git a/src/sk6812.c b/src/sk6812.c index 4f7693c..f5af1f8 100644 --- a/src/sk6812.c +++ b/src/sk6812.c @@ -1,30 +1,53 @@ -#include -#include -#include +#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include +#include +#include #include "logger.h" #include "sk6812.h" int sk6812_init(struct sk6812_ctx *ctx, uint32_t gpio_idx, void *phys_baseptr, uint32_t num_modules) { - // TODO: - // - map memory - // - setup GPIO + /* + * Setup memory map for LED memory. + */ + size_t mapsize = num_modules*sizeof(uint32_t); + size_t pagesize = (size_t)getpagesize(); + + if((mapsize % pagesize) != 0) { + mapsize = pagesize * (mapsize / pagesize + 1); + } + + ctx->devmem_fd = open("/dev/mem", O_RDWR|O_SYNC); + if(ctx->devmem_fd == -1) { + LOG(LVL_ERR, "sk6812: open(/dev/mem) failed: %s.", strerror(errno)); + return -1; + } + + ctx->memptr = (struct sk6812_memory*)mmap(0, mapsize, PROT_READ|PROT_WRITE, MAP_SHARED, ctx->devmem_fd, (off_t)phys_baseptr); + if(ctx->memptr == MAP_FAILED) { + LOG(LVL_ERR, "sk6812: mmap(0x%08X) failed: %s.", phys_baseptr, strerror(errno)); + close(ctx->devmem_fd); + return -1; + } + + ctx->mapped_size = mapsize; + + // write number of modules to mapped memory + ctx->memptr->num_leds = num_modules; return 0; } void sk6812_shutdown(struct sk6812_ctx *ctx) { - // TODO: - // - unmap memory + munmap(ctx->memptr, ctx->mapped_size); + close(ctx->devmem_fd); } void sk6812_set_colour(struct sk6812_ctx *ctx, uint32_t module, uint8_t red, uint8_t green, uint8_t blue, uint8_t white) diff --git a/src/sk6812.h b/src/sk6812.h index c2e01af..77b19b8 100644 --- a/src/sk6812.h +++ b/src/sk6812.h @@ -13,6 +13,8 @@ struct sk6812_ctx { struct sk6812_memory *memptr; char *gpio_value_path; + int devmem_fd; + size_t mapped_size; }; int sk6812_init(struct sk6812_ctx *ctx, uint32_t gpio_idx, void *phys_baseptr, uint32_t num_modules);