diff --git a/src/Makefile b/src/Makefile index e46466375..590a996fb 100755 --- a/src/Makefile +++ b/src/Makefile @@ -99,6 +99,8 @@ OBJ += $(wildcard $(BUILD)/$(WINC1500_DIR)/src/*.o) OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/, \ main.o \ xalloc.o \ + fb_stack.o \ + ff_wrapper.o \ array.o \ usbdbg.o \ sccb.o \ diff --git a/src/omv/Makefile b/src/omv/Makefile index 182315469..2c93886b8 100644 --- a/src/omv/Makefile +++ b/src/omv/Makefile @@ -2,6 +2,8 @@ SRCS += $(addprefix , \ main.c \ xalloc.c \ + fb_stack.c \ + ff_wrapper.c \ array.c \ usbdbg.c \ sccb.c \ diff --git a/src/omv/fb_stack.c b/src/omv/fb_stack.c new file mode 100644 index 000000000..75349b703 --- /dev/null +++ b/src/omv/fb_stack.c @@ -0,0 +1,58 @@ +/* + * This file is part of the OpenMV project. + * Copyright (c) 2013-2016 Kwabena W. Agyeman + * This work is licensed under the MIT license, see the file LICENSE for details. + * + * Interface for using extra frame buffer RAM as a stack. + * + */ +#include +#include "framebuffer.h" +#include "fb_stack.h" + +extern char _fs_cache; +static char *pointer = &_fs_cache; + +NORETURN static void fb_alloc_fail() +{ + nlr_raise(mp_obj_new_exception_msg(&mp_type_MemoryError, "Out of Memory!!!")); +} + +void fb_init() { + pointer = &_fs_cache; +} + +// returns null pointer without error if size==0 +void *fb_alloc(uint32_t size) { + if (!size) { + return NULL; + } + size=((size+sizeof(uint32_t)-1)/sizeof(uint32_t))*sizeof(uint32_t);// Round Up + char *result = pointer - size; + char *new_pointer = result - sizeof(uint32_t); + char *end_pointer = (char *)fb->pixels; // NULL (fb->bpp <= 0) + if ((fb->bpp == 1) || (fb->bpp == 2)) { // GRAYSCALE OR RGB565 + end_pointer += fb->w * fb->w * fb->bpp; + } else if (fb->bpp >= 3) { // JPEG + end_pointer += fb->bpp; + } + if (new_pointer < end_pointer) { + fb_alloc_fail(); + } + *((uint32_t *) new_pointer) = size + sizeof(uint32_t); // Save size. + pointer = new_pointer; + return result; +} + +// returns null pointer without error if size==0 +void *fb_alloc0(uint32_t size) { + void *mem = fb_alloc(size); + memset(mem, 0, size); + return mem; +} + +void fb_free() { + if (pointer < &_fs_cache) { + pointer += *((uint32_t *) pointer); // Get size and pop. + } +} diff --git a/src/omv/fb_stack.h b/src/omv/fb_stack.h new file mode 100644 index 000000000..b9895ec1c --- /dev/null +++ b/src/omv/fb_stack.h @@ -0,0 +1,16 @@ +/* + * This file is part of the OpenMV project. + * Copyright (c) 2013-2016 Kwabena W. Agyeman + * This work is licensed under the MIT license, see the file LICENSE for details. + * + * Interface for using extra frame buffer RAM as a stack. + * + */ +#ifndef __FB_STACK_H__ +#define __FB_STACK_H__ +#include +void fb_init(); +void *fb_alloc(uint32_t size); +void *fb_alloc0(uint32_t size); +void fb_free(); +#endif /* __FF_WRAPPER_H__ */ diff --git a/src/omv/ff_wrapper.c b/src/omv/ff_wrapper.c new file mode 100644 index 000000000..f4bf6d094 --- /dev/null +++ b/src/omv/ff_wrapper.c @@ -0,0 +1,57 @@ +/* + * This file is part of the OpenMV project. + * Copyright (c) 2013-2016 Kwabena W. Agyeman + * This work is licensed under the MIT license, see the file LICENSE for details. + * + * File System Helper Functions + * + */ +#include "ff_wrapper.h" + +int read_byte(FIL *fp, uint8_t *value) +{ + UINT bytes; FRESULT res = f_read(fp, value, sizeof(*value), &bytes); + return (bytes==sizeof(*value)) ? res : -1; +} + +int read_word(FIL *fp, uint16_t *value) +{ + UINT bytes; FRESULT res = f_read(fp, value, sizeof(*value), &bytes); + return (bytes==sizeof(*value)) ? res : -1; +} + +int read_long(FIL *fp, uint32_t *value) +{ + UINT bytes; FRESULT res = f_read(fp, value, sizeof(*value), &bytes); + return (bytes==sizeof(*value)) ? res : -1; +} + +int read_data(FIL *fp, void *data, UINT size) +{ + UINT bytes; FRESULT res = f_read(fp, data, size, &bytes); + return (bytes==size) ? res : -1; +} + +int write_byte(FIL *fp, uint8_t value) +{ + UINT bytes; FRESULT res = f_write(fp, &value, sizeof(value), &bytes); + return (bytes==sizeof(value)) ? res : -1; +} + +int write_word(FIL *fp, uint16_t value) +{ + UINT bytes; FRESULT res = f_write(fp, &value, sizeof(value), &bytes); + return (bytes==sizeof(value)) ? res : -1; +} + +int write_long(FIL *fp, uint32_t value) +{ + UINT bytes; FRESULT res = f_write(fp, &value, sizeof(value), &bytes); + return (bytes==sizeof(value)) ? res : -1; +} + +int write_data(FIL *fp, const void *data, UINT size) +{ + UINT bytes; FRESULT res = f_write(fp, data, size, &bytes); + return (bytes==size) ? res : -1; +} diff --git a/src/omv/ff_wrapper.h b/src/omv/ff_wrapper.h new file mode 100644 index 000000000..187c46adf --- /dev/null +++ b/src/omv/ff_wrapper.h @@ -0,0 +1,81 @@ +/* + * This file is part of the OpenMV project. + * Copyright (c) 2013-2016 Kwabena W. Agyeman + * This work is licensed under the MIT license, see the file LICENSE for details. + * + * File System Helper Functions + * + */ +#ifndef __FF_WRAPPER_H__ +#define __FF_WRAPPER_H__ +#include +#include + +#define READ_BYTE(fp, value) \ + ({ FRESULT _res = read_byte((fp), (value)); \ + if (_res != FR_OK) { f_close((fp)); return _res; } }) + +#define READ_BYTE_EXPECT(fp, value) \ + ({ uint8_t comp; FRESULT _res = read_byte((fp), &comp); \ + if (_res != FR_OK) { f_close((fp)); return _res; } \ + if (comp != (value)) { f_close((fp)); return -1; } }) + +#define READ_BYTE_IGNORE(fp) \ + ({ uint8_t value; FRESULT _res = read_byte((fp), &value); \ + if (_res != FR_OK) { f_close((fp)); return _res; } }) + +#define READ_WORD(fp, value) \ + ({ FRESULT _res = read_word((fp), (value)); \ + if (_res != FR_OK) { f_close((fp)); return _res; } }) + +#define READ_WORD_EXPECT(fp, value) \ + ({ uint16_t comp; FRESULT _res = read_word((fp), &comp); \ + if (_res != FR_OK) { f_close((fp)); return _res; } \ + if (comp != (value)) { f_close((fp)); return -1; } }) + +#define READ_WORD_IGNORE(fp) \ + ({ uint16_t value; FRESULT _res = read_word((fp), &value); \ + if (_res != FR_OK) { f_close((fp)); return _res; } }) + +#define READ_LONG(fp, value) \ + ({ FRESULT _res = read_long((fp), (value)); \ + if (_res != FR_OK) { f_close((fp)); return _res; } }) + +#define READ_LONG_EXPECT(fp, value) \ + ({ uint32_t comp; FRESULT _res = read_long((fp), &comp); \ + if (_res != FR_OK) { f_close((fp)); return _res; } \ + if (comp != (value)) { f_close((fp)); return -1; } }) + +#define READ_LONG_IGNORE(fp) \ + ({ uint32_t value; FRESULT _res = read_long((fp), &value); \ + if (_res != FR_OK) { f_close((fp)); return _res; } }) + +#define READ_DATA(fp, data, size) \ + ({ FRESULT _res = read_data((fp), (data), (size)); \ + if (_res != FR_OK) { f_close((fp)); return _res; } }) + +#define WRITE_BYTE(fp, value) \ + ({ FRESULT _res = write_byte((fp), (value)); \ + if (_res != FR_OK) { f_close((fp)); return _res; } }) + +#define WRITE_WORD(fp, value) \ + ({ FRESULT _res = write_word((fp), (value)); \ + if (_res != FR_OK) { f_close((fp)); return _res; } }) + +#define WRITE_LONG(fp, value) \ + ({ FRESULT _res = write_long((fp), (value)); \ + if (_res != FR_OK) { f_close((fp)); return _res; } }) + +#define WRITE_DATA(fp, data, size) \ + ({ FRESULT _res = write_data((fp), (data), (size)); \ + if (_res != FR_OK) { f_close((fp)); return _res; } }) + +int read_byte(FIL *fp, uint8_t *value); +int read_word(FIL *fp, uint16_t *value); +int read_long(FIL *fp, uint32_t *value); +int read_data(FIL *fp, void *data, UINT size); +int write_byte(FIL *fp, uint8_t value); +int write_word(FIL *fp, uint16_t value); +int write_long(FIL *fp, uint32_t value); +int write_data(FIL *fp, const void *data, UINT size); +#endif /* __FF_WRAPPER_H__ */