From 7b944113aa6de5bd5a63d9ed1855222809d63844 Mon Sep 17 00:00:00 2001 From: Wintermate Date: Mon, 7 Oct 2013 19:21:41 +0200 Subject: [PATCH] Sprites --- Makefile | 2 +- drivers/fatfs/ffconf.h | 38 ++-- lcd/display.c | 33 ++- lcd/display_r0ket.c | 488 ----------------------------------------- lcd/sprite.c | 117 ++++++++++ lcd/sprite.h | 27 +++ main.c | 155 ++++++++----- 7 files changed, 287 insertions(+), 573 deletions(-) delete mode 100644 lcd/display_r0ket.c create mode 100644 lcd/sprite.c create mode 100644 lcd/sprite.h diff --git a/Makefile b/Makefile index b1f7810..0685d8b 100644 --- a/Makefile +++ b/Makefile @@ -172,7 +172,7 @@ OBJS += sysinit.o pwm.o iap.o VPATH += lcd -OBJS += display.o +OBJS += display.o sprite.o VPATH += dataflash OBJS += at45db041d.o iobase.o diskio.o diff --git a/drivers/fatfs/ffconf.h b/drivers/fatfs/ffconf.h index 3453ad1..8575532 100644 --- a/drivers/fatfs/ffconf.h +++ b/drivers/fatfs/ffconf.h @@ -15,19 +15,19 @@ / Function and Buffer Configurations /----------------------------------------------------------------------------*/ -#define _FS_TINY 1 /* 0 or 1 */ +#define _FS_TINY 1 /* 0 or 1 */ /* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system / object instead of the sector buffer in the individual file object for file / data transfer. This reduces memory consumption 512 bytes each file object. */ -#define _FS_READONLY CFG_SDCARD_READONLY // 0 /* 0 or 1 */ +#define _FS_READONLY 1 //CFG_SDCARD_READONLY // 0 /* 0 or 1 */ /* Setting _FS_READONLY to 1 defines read only configuration. This removes / writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename, / f_truncate and useless f_getfree. */ -#define _FS_MINIMIZE 0 /* 0, 1, 2 or 3 */ +#define _FS_MINIMIZE 1 /* 0, 1, 2 or 3 */ /* The _FS_MINIMIZE option defines minimization level to remove some functions. / / 0: Full function. @@ -37,15 +37,15 @@ / 3: f_lseek is removed in addition to level 2. */ -#define _USE_STRFUNC 0 /* 0, 1 or 2 */ +#define _USE_STRFUNC 0 /* 0, 1 or 2 */ /* To enable string functions, set _USE_STRFUNC to 1 or 2. */ -#define _USE_MKFS 0 /* 0 or 1 */ +#define _USE_MKFS 0 /* 0 or 1 */ /* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */ -#define _USE_FORWARD 0 /* 0 or 1 */ +#define _USE_FORWARD 0 /* 0 or 1 */ /* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */ @@ -54,7 +54,7 @@ / Locale and Namespace Configurations /----------------------------------------------------------------------------*/ -#define _CODE_PAGE 858 +#define _CODE_PAGE 1 /* The _CODE_PAGE specifies the OEM code page to be used on the target system. / Incorrect setting of the code page can cause a file open failure. / @@ -83,12 +83,12 @@ / 857 - Turkish (OEM) / 862 - Hebrew (OEM) / 874 - Thai (OEM, Windows) -/ 1 - ASCII only (Valid for non LFN cfg.) +/ 1 - ASCII only (Valid for non LFN cfg.) */ -#define _USE_LFN 0 /* 0, 1 or 2 */ -#define _MAX_LFN 64 /* Maximum LFN length to handle (12 to 255) */ +#define _USE_LFN 0 /* 0, 1 or 2 */ +#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ /* The _USE_LFN option switches the LFN support. / / 0: Disable LFN. _MAX_LFN and _LFN_UNICODE have no effect. @@ -100,13 +100,13 @@ / to the project. */ -#define _LFN_UNICODE 0 /* 0 or 1 */ +#define _LFN_UNICODE 0 /* 0 or 1 */ /* To switch the character code set on FatFs API to Unicode, / enable LFN feature and set _LFN_UNICODE to 1. */ -#define _FS_RPATH 0 /* 0 or 1 */ +#define _FS_RPATH 1 /* 0 or 1 */ /* When _FS_RPATH is set to 1, relative path feature is enabled and f_chdir, / f_chdrive function are available. / Note that output of the f_readdir fnction is affected by this option. */ @@ -117,11 +117,11 @@ / Physical Drive Configurations /----------------------------------------------------------------------------*/ -#define _DRIVES 1 +#define _DRIVES 1 /* Number of volumes (logical drives) to be used. */ -#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */ +#define _MAX_SS 512 /* 512, 1024, 2048 or 4096 */ /* Maximum sector size to be handled. / Always set 512 for memory card and hard disk but a larger value may be / required for floppy disk (512/1024) and optical disk (512/2048). @@ -129,7 +129,7 @@ / to the disk_ioctl function. */ -#define _MULTI_PARTITION 0 /* 0 or 1 */ +#define _MULTI_PARTITION 0 /* 0 or 1 */ /* When _MULTI_PARTITION is set to 0, each volume is bound to the same physical / drive number and can mount only first primaly partition. When it is set to 1, / each volume is tied to the partitions listed in Drives[]. */ @@ -140,7 +140,7 @@ / System Configurations /----------------------------------------------------------------------------*/ -#define _WORD_ACCESS 0 /* 0 or 1 */ +#define _WORD_ACCESS 1 /* 0 or 1 */ /* The _WORD_ACCESS option defines which access method is used to the word / data on the FAT volume. / @@ -153,9 +153,9 @@ / performance and code size. */ -#define _FS_REENTRANT 0 /* 0 or 1 */ -#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */ -#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */ +#define _FS_REENTRANT 0 /* 0 or 1 */ +#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */ +#define _SYNC_t HANDLE /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */ /* The _FS_REENTRANT option switches the reentrancy of the FatFs module. / / 0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect. diff --git a/lcd/display.c b/lcd/display.c index 4849753..cb91904 100644 --- a/lcd/display.c +++ b/lcd/display.c @@ -8,7 +8,20 @@ #include +#ifdef CFG_USBMSC +#include + +static uint32_t usbintstatus; +#endif + static void lcd_select() { +#ifdef CFG_USBMSC + if(usbMSCenabled) { + usbintstatus = USB_DEVINTEN; + USB_DEVINTEN = 0; + } +#endif + /* the LCD requires 9-Bit frames */ uint32_t configReg = ( SSP_SSP0CR0_DSS_9BIT // Data size = 9-bit | SSP_SSP0CR0_FRF_SPI // Frame format = SPI @@ -24,6 +37,12 @@ static void lcd_deselect() { | SSP_SSP0CR0_FRF_SPI // Frame format = SPI | SSP_SSP0CR0_SCR_8); // Serial clock rate = 8 SSP_SSP0CR0 = configReg; + +#ifdef CFG_USBMSC + if(usbMSCenabled) { + USB_DEVINTEN = usbintstatus; + } +#endif } static inline void lcd_write(uint16_t frame) { @@ -85,12 +104,12 @@ void badge_display_init(void) { * 10: set x address (upper bits): X[6-4] = 0 */ static uint8_t const initseq[]= { 0xE2, 0xAF, // Display ON - // 0xA1, // Mirror-X - 0xc8, // mirror-y - 0xa7, // invert (1 = black) - 0xA4, 0x2F, - 0xB0, 0x10, - 0x9f, 0x24 }; + // 0xA1, // Mirror-X + 0xc8, // mirror-y + 0xa7, // invert (1 = black) + 0xA4, 0x2F, + 0xB0, 0x10, + 0x9f, 0x24 }; for(uint8_t i = 0; i < sizeof(initseq); ++i){ lcd_write_command(initseq[i]); systickDelay(5); @@ -106,7 +125,7 @@ void badge_framebuffer_flush(badge_framebuffer const *fb) { lcd_write_command(0x10); lcd_write_command(0x00); - + for(int i = 0; i < 9 * 96; ++i) { lcd_write_data(fb->data[0][i]); } diff --git a/lcd/display_r0ket.c b/lcd/display_r0ket.c deleted file mode 100644 index 8d2d29c..0000000 --- a/lcd/display_r0ket.c +++ /dev/null @@ -1,488 +0,0 @@ -#include - -#include -#include -#include "lpc134x.h" -#include "core/ssp/ssp.h" -#include "gpio/gpio.h" -#include "basic/basic.h" -#include "basic/config.h" -#include "usb/usbmsc.h" - - -#define DISPLAY_N1200 0 -#define DISPLAY_N1600 1 - -#define MODE 8 /* 8 or 16 */ - -#if MODE == 8 -#define putpix(x) _helper_pixel8(x) -#define px_INIT_MODE 2 -#define px_PACK(r,g,b) COLORPACK_RGB332(r,g,b) -#define px_type uint8_t -#else - #if MODE == 12 - #define putpix(x) _helper_pixel12(x) - #define px_INIT_MODE 3 - #define px_PACK(r,g,b) COLORPACK_RGB444(r,g,b) - #define px_type uint16_t - #else - #define putpix(x) _helper_pixel16(x) - #define px_INIT_MODE 5 - #define px_PACK(r,g,b) COLORPACK_RGB565(r,g,b) - #define px_type uint16_t - #endif -#endif - -/**************************************************************************/ -/* Utility routines to manage nokia display */ -/**************************************************************************/ - -uint8_t lcdBuffer[RESX*RESY_B]; -uint32_t intstatus; // Caches USB interrupt state - // (need to disable MSC while displaying) -uint8_t displayType; - -#define TYPE_CMD 0 -#define TYPE_DATA 1 - -static void lcd_select() { -#if CFG_USBMSC - if(usbMSCenabled){ - intstatus=USB_DEVINTEN; - USB_DEVINTEN=0; - }; -#endif - /* the LCD requires 9-Bit frames */ - uint32_t configReg = ( SSP_SSP0CR0_DSS_9BIT // Data size = 9-bit - | SSP_SSP0CR0_FRF_SPI // Frame format = SPI - | SSP_SSP0CR0_SCR_8); // Serial clock rate = 8 - SSP_SSP0CR0 = configReg; - gpioSetValue(RB_LCD_CS, 0); -} - -static void lcd_deselect() { - gpioSetValue(RB_LCD_CS, 1); - /* reset the bus to 8-Bit frames that everyone else uses */ - uint32_t configReg = ( SSP_SSP0CR0_DSS_8BIT // Data size = 8-bit - | SSP_SSP0CR0_FRF_SPI // Frame format = SPI - | SSP_SSP0CR0_SCR_8); // Serial clock rate = 8 - SSP_SSP0CR0 = configReg; -#if CFG_USBMSC - if(usbMSCenabled){ - USB_DEVINTEN=intstatus; - }; -#endif -} - -static void lcdWrite(uint8_t cd, uint8_t data) { - uint16_t frame = 0x0; - - frame = cd << 8; - frame |= data; - - while ((SSP_SSP0SR & (SSP_SSP0SR_TNF_NOTFULL | SSP_SSP0SR_BSY_BUSY)) != SSP_SSP0SR_TNF_NOTFULL); - SSP_SSP0DR = frame; - while ((SSP_SSP0SR & (SSP_SSP0SR_BSY_BUSY|SSP_SSP0SR_RNE_NOTEMPTY)) != SSP_SSP0SR_RNE_NOTEMPTY); - /* clear the FIFO */ - frame = SSP_SSP0DR; -} - -#define CS 2,1 -#define SCK 2,11 -#define SDA 0,9 -#define RST 2,2 - -uint8_t lcdRead(uint8_t data) -{ - uint32_t op211cache=IOCON_PIO2_11; - uint32_t op09cache=IOCON_PIO0_9; - uint32_t dircache=GPIO_GPIO2DIR; - IOCON_PIO2_11=IOCON_PIO2_11_FUNC_GPIO|IOCON_PIO2_11_MODE_PULLUP; - IOCON_PIO0_9=IOCON_PIO0_9_FUNC_GPIO|IOCON_PIO0_9_MODE_PULLUP; - gpioSetDir(SCK, 1); - - uint8_t i; - - gpioSetDir(SDA, 1); - gpioSetValue(SCK, 0); - gpioSetValue(CS, 0); - delayms(1); - - gpioSetValue(SDA, 0); - gpioSetValue(SCK, 1); - delayms(1); - - for(i=0; i<8; i++){ - gpioSetValue(SCK, 0); - delayms(1); - if( data & 0x80 ) - gpioSetValue(SDA, 1); - else - gpioSetValue(SDA, 0); - data <<= 1; - gpioSetValue(SCK, 1); - delayms(1); - } - uint8_t ret = 0; - - gpioSetDir(SDA, 0); - for(i=0; i<8; i++){ - gpioSetValue(SCK, 0); - delayms(1); - ret <<= 1; - ret |= gpioGetValue(SDA); - gpioSetValue(SCK, 1); - delayms(1); - } - gpioSetValue(SCK, 0); - - gpioSetValue(CS, 1); - gpioSetDir(SDA, 1); - IOCON_PIO2_11=op211cache; - IOCON_PIO0_9=op09cache; - GPIO_GPIO2DIR=dircache; - delayms(1); - return ret; -} - - -void lcdInit(void) { - int id; - - sspInit(0, sspClockPolarity_Low, sspClockPhase_RisingEdge); - - gpioSetValue(RB_LCD_CS, 1); - gpioSetValue(RB_LCD_RST, 1); - - gpioSetDir(RB_LCD_CS, gpioDirection_Output); - gpioSetDir(RB_LCD_RST, gpioDirection_Output); - - delayms(100); - gpioSetValue(RB_LCD_RST, 0); - delayms(100); - gpioSetValue(RB_LCD_RST, 1); - delayms(100); - - id=lcdRead(220); // ID3 - - if(id==14) - displayType=DISPLAY_N1600; - else /* ID3 == 48 */ - displayType=DISPLAY_N1200; - -/* Small Nokia 1200 LCD docs: - * clear/ set - * on 0xae / 0xaf - * invert 0xa6 / 0xa7 - * mirror-x 0xA0 / 0xA1 - * mirror-y 0xc7 / 0xc8 - * - * 0x20+x contrast (0=black - 0x2e) - * 0x40+x offset in rows from top (-0x7f) - * 0x80+x contrast? (0=black -0x9f?) - * 0xd0+x black lines from top? (-0xdf?) - * - */ - lcd_select(); - - if(displayType==DISPLAY_N1200){ - /* Decoded: - * E2: Internal reset - * AF: Display on/off: DON = 1 - * A1: undefined? - * A4: all on/normal: DAL = 0 - * 2F: charge pump on/off: PC = 1 - * B0: set y address: Y[0-3] = 0 - * 10: set x address (upper bits): X[6-4] = 0 - */ - static uint8_t initseq[]= { 0xE2,0xAF, // Display ON - 0xA1, // Mirror-X - 0xA4, 0x2F, 0xB0, 0x10}; - int i = 0; - while(i> 1; - } - } - lcd_deselect(); -} - -void lcdFill(char f){ - memset(lcdBuffer,f,RESX*RESY_B); -#if 0 - int x; - for(x=0;x RESX || y<0 || y > RESY) - return; - char y_byte = (RESY-(y+1)) / 8; - char y_off = (RESY-(y+1)) % 8; - char byte = lcdBuffer[y_byte*RESX+(RESX-(x+1))]; - if (f) { - byte |= (1 << y_off); - } else { - byte &= ~(1 << y_off); - } - lcdBuffer[y_byte*RESX+(RESX-(x+1))] = byte; -} - -bool lcdGetPixel(char x, char y){ - char y_byte = (RESY-(y+1)) / 8; - char y_off = (RESY-(y+1)) % 8; - char byte = lcdBuffer[y_byte*RESX+(RESX-(x+1))]; - return byte & (1 << y_off); -} - -// Color display helper functions -static inline void _helper_pixel8(uint8_t color1){ - lcdWrite(TYPE_DATA, color1); -} - -static void _helper_pixel12(uint16_t color){ - static char odd=0; - static char rest; - if(odd){ - lcdWrite(TYPE_DATA,(rest<<4) | (color>>8)); - lcdWrite(TYPE_DATA,color&0xff); - }else{ - lcdWrite(TYPE_DATA,(color>>4)&0xff); - rest=(color&0x0f); - }; - odd=1-odd; -} - -static void _helper_pixel16(uint16_t color){ - lcdWrite(TYPE_DATA,color>>8); - lcdWrite(TYPE_DATA,color&0xFF); -} - -#define COLORPACK_RGB565(r,g,b) (((r&0xF8) << 8) | ((g&0xFC)<<3) | ((b&0xF8) >> 3)) -#define COLORPACK_RGB444(r,g,b) ( ((r&0xF0)<<4) | (g&0xF0) | ((b&0xF0)>>4) ) -#define COLORPACK_RGB332(r,g,b) ( (((r>>5)&0x7)<<5) | (((g>>5)&0x7)<<2) | ((b>>6)&0x3) ) - -static const px_type COLOR_FG = px_PACK(0x00, 0x00, 0x00); -static const px_type COLOR_BG = px_PACK(0xff, 0xff, 0xff); - -void lcdDisplay(void) { - char byte; - lcd_select(); - - if(displayType==DISPLAY_N1200){ - lcdWrite(TYPE_CMD,0xB0); - lcdWrite(TYPE_CMD,0x10); - lcdWrite(TYPE_CMD,0x00); - uint16_t i,page; - for(page=0; page0;y--){ - for(x=RESX;x>0;x--){ - if(GLOBAL(lcdmirror)) - px=lcdGetPixel(RESX-x,y-1); - else - px=lcdGetPixel(x-1,y-1); - - if((!px)^(!GLOBAL(lcdinvert))) { - putpix(COLOR_FG); /* foreground */ - } else { - putpix(COLOR_BG); /* background */ - } - } - } - }; - lcd_deselect(); -} - -void lcdRefresh() __attribute__ ((weak, alias ("lcdDisplay"))); - -inline void lcdInvert(void) { - GLOBAL(lcdinvert)=!GLOBAL(lcdinvert); -} - -void lcdSetContrast(int c) { - lcd_select(); - if(displayType==DISPLAY_N1200){ - if(c<0x1F) - lcdWrite(TYPE_CMD,0x80+c); - }else{ /* displayType==DISPLAY_N1600 */ - if(c<0x40) { - lcdWrite(TYPE_CMD,0x25); - lcdWrite(TYPE_DATA,4*c); - }; - } - lcd_deselect(); -} - -void lcdSetInvert(int c) { - lcd_select(); - /* it doesn't harm N1600, save space */ -// if(displayType==DISPLAY_N1200) - lcdWrite(TYPE_CMD,(c&1)+0xa6); - lcd_deselect(); -} - -/* deprecated */ -void __attribute__((__deprecated__)) lcdToggleFlag(int flag) { - if(flag==LCD_MIRRORX) - GLOBAL(lcdmirror)=!GLOBAL(lcdmirror); - if(flag==LCD_INVERTED) - GLOBAL(lcdinvert)=!GLOBAL(lcdinvert); -} - -void lcdShiftH(bool right, bool wrap) { - uint8_t tmp; - for (int yb = 0; yb 0; y--){ - lcdBuffer[x+(y*RESX)] = (lcdBuffer[x+(y*RESX)] << 1) |( lcdBuffer[x+((y-1)*RESX)] >> 7); - } - lcdBuffer[x] = ( lcdBuffer[x] << 1) | ((tmp[x]>>3)&1); - } - - } else { - if (wrap) - memmove(tmp,lcdBuffer,RESX); - else - memset(tmp,0,RESX); - for (int x = 0; x> 1) |( lcdBuffer[x+((y+1)*RESX)] << 7); - } - lcdBuffer[x+((RESY_B-1)*RESX)] = ( lcdBuffer[x+((RESY_B-1)*RESX)] >> 1) | ((tmp[x]<<3)&8); - } - } -} - -void lcdShift(int x, int y, bool wrap) { - bool dir=true; - - if(x<0){ - dir=false; - x=-x; - }; - - while(x-->0) - lcdShiftH(dir, wrap); - - if(y<0){ - dir=false; - y=-y; - }else{ - dir=true; - }; - - while(y>=8){ - y-=8; - lcdShiftV8(dir, wrap); - }; - - while(y-->0) - lcdShiftV(dir, wrap); -} - diff --git a/lcd/sprite.c b/lcd/sprite.c new file mode 100644 index 0000000..cb815fc --- /dev/null +++ b/lcd/sprite.c @@ -0,0 +1,117 @@ +#include "sprite.h" + +//#include +#include +#include +#include + +typedef struct { + uint8_t const *data_ptr; + uint8_t left_in_byte; +} sprite_column_iterator; + +static inline int8_t i8min( int8_t x, int8_t y) { return x < y ? x : y; } +static inline int8_t i8max( int8_t x, int8_t y) { return x < y ? y : x; } +static inline uint8_t u8min(uint8_t x, uint8_t y) { return x < y ? x : y; } +static inline uint8_t u8max(uint8_t x, uint8_t y) { return x < y ? y : x; } + +static inline sprite_column_iterator sprite_column_iterator_init(badge_sprite const *sprite, uint8_t xskip) { + sprite_column_iterator result = { sprite->data, CHAR_BIT }; + + if(xskip != 0) { + int skip_bits = (xskip * sprite->height); + + result.data_ptr += skip_bits / CHAR_BIT; + result.left_in_byte = CHAR_BIT - skip_bits % 8; + } + + return result; +} + +static inline uint32_t sprite_column_iterator_pop(sprite_column_iterator *iter, uint8_t height) { + uint32_t column = 0; + + if(iter->left_in_byte > height) { + column = *iter->data_ptr >> (CHAR_BIT - iter->left_in_byte) & ((1 << height) - 1); + iter->left_in_byte -= height; + } else { + column = *iter->data_ptr >> (CHAR_BIT - iter->left_in_byte); + + uint8_t shlen = iter->left_in_byte; + uint8_t n; + + for(n = height - shlen; n >= CHAR_BIT; n -= CHAR_BIT) { + column |= *++iter->data_ptr << shlen; + shlen += CHAR_BIT; + } + + column |= (*++iter->data_ptr & ((1 << n) - 1)) << shlen; + iter->left_in_byte = CHAR_BIT - n; + } + + return column; +} + +void badge_framebuffer_blt(badge_framebuffer *fb, + int8_t x, + int8_t y, + badge_sprite const *sprite, + unsigned flags) +{ + if(y >= BADGE_DISPLAY_HEIGHT || + x >= BADGE_DISPLAY_WIDTH || + y <= -sprite->height || + x <= -sprite->width) { + // Nichts zu tun. + return; + } + + int8_t y_major = y / BADGE_DISPLAY_STRIPE_HEIGHT - (y < 0); + uint8_t y_minor = (uint8_t) (y - y_major * BADGE_DISPLAY_STRIPE_HEIGHT); + + int8_t xmove; + int8_t xcursor; + int8_t xend; + uint8_t xskip; + + if(flags & BADGE_BLT_MIRRORED) { + xmove = -1; + xcursor = i8min(x + sprite->width, BADGE_DISPLAY_WIDTH) - 1; + xend = i8max(x, 0) - 1; + xskip = x + sprite->width - xcursor - 1; + } else { + xmove = 1; + xcursor = i8max(x, 0); + xend = i8min(x + sprite->width, BADGE_DISPLAY_WIDTH); + xskip = xcursor - x; + } + + sprite_column_iterator col_iter = sprite_column_iterator_init(sprite, xskip); + + while(xcursor != xend) { + uint32_t column = sprite_column_iterator_pop(&col_iter, sprite->height); + +/* + assert(xcursor >= 0); + assert(xcursor < BADGE_DISPLAY_WIDTH); +*/ + + if(y_major >= 0) { + fb->data[y_major][xcursor] |= (uint8_t) column << y_minor; + } + + uint8_t stripe_max = u8min((sprite->height + y_minor - 1) / BADGE_DISPLAY_STRIPE_HEIGHT, + BADGE_DISPLAY_STRIPE_COUNT - y_major - 1); + + for(uint8_t stripe_ptr = i8max(1, -y_major); stripe_ptr <= stripe_max; ++stripe_ptr) { +/* + assert(y_major + stripe_ptr >= 0); + assert(y_major + stripe_ptr < BADGE_DISPLAY_STRIPE_COUNT); +*/ + + fb->data[y_major + stripe_ptr][xcursor] |= (uint8_t) (column >> (stripe_ptr * BADGE_DISPLAY_STRIPE_HEIGHT - y_minor)); + } + + xcursor += xmove; + } +} diff --git a/lcd/sprite.h b/lcd/sprite.h new file mode 100644 index 0000000..3a3aba8 --- /dev/null +++ b/lcd/sprite.h @@ -0,0 +1,27 @@ +#ifndef INCLUDED_BADGE2013_MOCKUP_SPRITE_H +#define INCLUDED_BADGE2013_MOCKUP_SPRITE_H + +#include "display.h" +#include + +enum { + BADGE_SPRITE_MAX_WIDTH = 32 +}; + +typedef struct { + uint8_t width; + uint8_t height; + uint8_t const *data; +} badge_sprite; + +enum { + BADGE_BLT_MIRRORED = 1 +}; + +void badge_framebuffer_blt(badge_framebuffer *fb, + int8_t x, + int8_t y, + badge_sprite const *sprite, + unsigned flags); + +#endif diff --git a/main.c b/main.c index d0dfce7..4cdd2cc 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,5 @@ /**************************************************************************/ -/*! +/*! @file main.c @author K. Townsend (microBuilder.eu) @@ -52,8 +52,10 @@ #endif #include "lcd/display.h" +#include "lcd/sprite.h" #include "r0ketports.h" +#include "drivers/fatfs/ff.h" uint8_t getInputRaw(void) { uint8_t result = BTN_NONE; @@ -100,7 +102,7 @@ void backlightInit(void) { /* Enable PWM0 */ TMR_TMR16B1PWMC = TMR_TMR16B1PWMC_PWM0_ENABLED; - + // Enable Step-UP gpioSetDir(RB_PWR_LCDBL, gpioDirection_Output); gpioSetValue(RB_PWR_LCDBL, 0); @@ -115,14 +117,14 @@ void rbInit() { // TODO FIXME more power init needed ? chrg + volt input ? // enable external vcc gpioSetDir(RB_PWR_GOOD, gpioDirection_Output); - gpioSetValue (RB_PWR_GOOD, 0); + gpioSetValue (RB_PWR_GOOD, 0); // Disable USB Connect (we don't want USB by default) gpioSetDir(USB_CONNECT, gpioDirection_Output); gpioSetValue(USB_CONNECT, 1); static uint8_t ports[] = { RB_BTN0, RB_BTN1, RB_BTN2, RB_BTN3, RB_BTN4, - RB_LED0, RB_LED1, RB_LED2, + RB_LED0, RB_LED1, RB_LED2, RB_SPI_SS0, RB_SPI_SS1, RB_SPI_SS2, RB_SPI_SS3, RB_SPI_SS4, RB_SPI_SS5, RB_HB0, RB_HB1, RB_HB2, @@ -147,7 +149,7 @@ void rbInit() { // prepare LEDs IOCON_JTAG_TDI_PIO0_11 &= ~IOCON_JTAG_TDI_PIO0_11_FUNC_MASK; - IOCON_JTAG_TDI_PIO0_11 |= IOCON_JTAG_TDI_PIO0_11_FUNC_GPIO; + IOCON_JTAG_TDI_PIO0_11 |= IOCON_JTAG_TDI_PIO0_11_FUNC_GPIO; while( i<16 ){ gpioSetDir(ports[i],ports[i+1], gpioDirection_Output); @@ -161,16 +163,16 @@ void rbInit() { // prepare lcd // TODO FIXME more init needed ? gpioSetDir(RB_LCD_BL, gpioDirection_Output); - gpioSetValue (RB_LCD_BL, 0); + gpioSetValue (RB_LCD_BL, 0); // Set P0.0 to GPIO RB_PWR_LCDBL_IO&= ~RB_PWR_LCDBL_IO_FUNC_MASK; - RB_PWR_LCDBL_IO|= RB_PWR_LCDBL_IO_FUNC_GPIO; + RB_PWR_LCDBL_IO|= RB_PWR_LCDBL_IO_FUNC_GPIO; gpioSetDir(RB_PWR_LCDBL, gpioDirection_Input); gpioSetPullup(&RB_PWR_LCDBL_IO, gpioPullupMode_Inactive); // prepare SPI/SS - // TODO FIXME init miso/mosi/sck somehow ? + // TODO FIXME init miso/mosi/sck somehow ? // prepare hackerbus while(i