From 0a6cbe92b6bef26ff58bd362b8fb955b13a57b4d Mon Sep 17 00:00:00 2001 From: bsongis Date: Wed, 28 Nov 2012 18:04:18 +0000 Subject: [PATCH] [X9D] Small font added [X9D] Main view continued [Sky9x] Sounds selection again OK (thanks Scott for the report) --- src/Makefile | 14 +- src/bmp.cpp | 17 +- src/board_gruvin9x.cpp | 12 +- src/board_sky9x.cpp | 18 +- src/board_stock.cpp | 18 +- src/eeprom_arm.cpp | 5 +- src/font_small.lbm | 6 + src/font_small.xbm | 38 ++++ src/gtests.cpp | 4 +- src/lcd.cpp | 443 +++++---------------------------------- src/lcd.h | 14 +- src/logs.cpp | 2 +- src/main_views.cpp | 98 +++++---- src/menus.cpp | 8 +- src/model_menus.cpp | 91 +++++--- src/myeeprom.h | 26 ++- src/open9x.cpp | 10 +- src/open9x.h | 71 ++++--- src/pulses_arm.cpp | 2 +- src/pulses_avr.cpp | 4 +- src/sdcard.h | 3 + src/simpgmspace.cpp | 6 +- src/simu.cpp | 19 +- src/sky9x/lcd_driver.cpp | 296 ++++++++++++++++++++++++++ src/stock/lcd_driver.cpp | 128 +++++++++++ src/templates.cpp | 27 +-- src/translations.cpp | 6 + src/translations.h | 3 + src/translations/en.h | 2 + util/img2lbm.py | 9 + 30 files changed, 842 insertions(+), 558 deletions(-) create mode 100644 src/font_small.lbm create mode 100644 src/font_small.xbm create mode 100644 src/sky9x/lcd_driver.cpp create mode 100644 src/stock/lcd_driver.cpp diff --git a/src/Makefile b/src/Makefile index d6eed4013..ec5ba8168 100644 --- a/src/Makefile +++ b/src/Makefile @@ -449,6 +449,7 @@ ifeq ($(PCB), X9D) CPPDEFS += -DPCBX9D -DPCBSKY9X -DREVB -DCPUARM -DEEPROM_VARIANT=0 -DAUDIO -DHAPTIC -DPXX -DDSM2 -DDSM2_PPM -DROTARY_ENCODERS=1 -DLCD212 EXTRAINCDIRS += sky9x CoOS/kernel CoOS/portable BOARDSRC = board_sky9x.cpp + EXTRABOARDSRC += sky9x/lcd_driver.cpp SRC += sky9x/core_cm3.c sky9x/board_lowlevel.c sky9x/crt.c sky9x/vectors_sam3s.c SRC += CoOS/kernel/core.c CoOS/kernel/hook.c CoOS/kernel/task.c CoOS/kernel/event.c CoOS/kernel/time.c CoOS/kernel/timer.c CoOS/kernel/flag.c CoOS/kernel/mutex.c CoOS/kernel/serviceReq.c CoOS/portable/GCC/port.c CoOS/portable/arch.c SRC += sky9x/usb/device/core/USBD_UDP.c sky9x/usb/device/core/USBDDriver.c @@ -484,6 +485,7 @@ ifeq ($(PCB), SKY9X) CPPDEFS += -DPCBSKY9X -DCPUARM -DEEPROM_VARIANT=0 -DAUDIO -DHAPTIC -DRTCLOCK -DPXX -DDSM2 -DDSM2_PPM -DROTARY_ENCODERS=1 EXTRAINCDIRS += sky9x CoOS/kernel CoOS/portable BOARDSRC = board_sky9x.cpp + EXTRABOARDSRC += sky9x/lcd_driver.cpp SRC += sky9x/core_cm3.c sky9x/board_lowlevel.c sky9x/crt.c sky9x/vectors_sam3s.c SRC += CoOS/kernel/core.c CoOS/kernel/hook.c CoOS/kernel/task.c CoOS/kernel/event.c CoOS/kernel/time.c CoOS/kernel/timer.c CoOS/kernel/flag.c CoOS/kernel/mutex.c CoOS/kernel/serviceReq.c CoOS/portable/GCC/port.c CoOS/portable/arch.c SRC += sky9x/usb/device/core/USBD_UDP.c sky9x/usb/device/core/USBDDriver.c @@ -519,6 +521,7 @@ ifeq ($(PCB), GRUVIN9X) CPPDEFS += -DPCBGRUVIN9X -DEEPROM_VARIANT=0 -DAUDIO -DHAPTIC -DROTARY_ENCODERS=2 EXTRAINCDIRS += gruvin9x stock FatFs FatFs/option BOARDSRC += board_gruvin9x.cpp + EXTRABOARDSRC += stock/lcd_driver.cpp EEPROMSRC = eeprom_avr.cpp PULSESSRC = pulses_avr.cpp CPPSRC += stock/audio.cpp haptic.cpp @@ -545,8 +548,9 @@ ifeq ($(PCB), STD128) CPPDEFS += -DPCBSTD -DCPUM128 -DEEPROM_VARIANT=0x8000 EXTRAINCDIRS += stock BOARDSRC = board_stock.cpp + EXTRABOARDSRC += stock/lcd_driver.cpp EEPROMSRC = eeprom_avr.cpp - PULSESSRC = pulses_avr.cpp + PULSESSRC = pulses_avr.cpp ifeq ($(AUDIO), YES) CPPDEFS += -DAUDIO @@ -580,6 +584,7 @@ ifeq ($(PCB), STD) EXTRAINCDIRS += stock CPPDEFS += -DPCBSTD -DCPUM64 -DEEPROM_VARIANT=$(shell echo ${EEPROM_VARIANT} | bc) BOARDSRC = board_stock.cpp + EXTRABOARDSRC += stock/lcd_driver.cpp EEPROMSRC = eeprom_avr.cpp PULSESSRC = pulses_avr.cpp @@ -745,7 +750,7 @@ eep: $(TARGET).eep lss: $(TARGET).lss sym: $(TARGET).sym -lbm: font.lbm font_midsize.lbm font_dblsize.lbm sticks.lbm splash_9x.lbm splash_X9D.lbm asterisk.lbm +lbm: font.lbm font_small.lbm font_midsize.lbm font_dblsize.lbm sticks.lbm splash_9x.lbm splash_X9D.lbm asterisk.lbm # Build stamp-file stamp_header: @@ -793,6 +798,11 @@ font.lbm: font.xbm font_extra.xbm translations/font_se.xbm translations/font_de. $(IMG2LBM) translations/font_fr.xbm translations/font_fr.lbm 5x7 $(IMG2LBM) translations/font_es.xbm translations/font_es.lbm 5x7 +font_small.lbm: font_small.xbm + @echo + @echo "Convert font from xbm to lbm:" + $(IMG2LBM) $< $@ 4x6 + font_midsize.lbm: font_midsize.xbm @echo @echo "Convert font from xbm to lbm:" diff --git a/src/bmp.cpp b/src/bmp.cpp index 0ac67709e..d559de74c 100644 --- a/src/bmp.cpp +++ b/src/bmp.cpp @@ -143,15 +143,16 @@ const pm_char * bmpLoad(uint8_t *dest, const char *filename) f_close(&bmpFile); return SDCARD_ERROR(result); } + uint8_t * dst = dest + ((height-i-8)/8 * width); for (uint32_t j=0; j> 7) + ((buf[j+1*n] >> 7) << 1) + ((buf[j+2*n] >> 7) << 2) + ((buf[j+3*n] >> 7) << 3) + ((buf[j+4*n] >> 7) << 4) + ((buf[j+5*n] >> 7) << 5) + ((buf[j+6*n] >> 7) << 6) + ((buf[j+7*n] >> 7) << 7); - *dest++ = ((buf[j+0*n] >> 6) & 1) + (((buf[j+1*n] >> 6) & 1) << 1) + (((buf[j+2*n] >> 6) & 1) << 2) + (((buf[j+3*n] >> 6) & 1) << 3) + (((buf[j+4*n] >> 6) & 1) << 4) + (((buf[j+5*n] >> 6) & 1) << 5) + (((buf[j+6*n] >> 6) & 1) << 6) + (((buf[j+7*n] >> 6) & 1) << 7); - *dest++ = ((buf[j+0*n] >> 5) & 1) + (((buf[j+1*n] >> 5) & 1) << 1) + (((buf[j+2*n] >> 5) & 1) << 2) + (((buf[j+3*n] >> 5) & 1) << 3) + (((buf[j+4*n] >> 5) & 1) << 4) + (((buf[j+5*n] >> 5) & 1) << 5) + (((buf[j+6*n] >> 5) & 1) << 6) + (((buf[j+7*n] >> 5) & 1) << 7); - *dest++ = ((buf[j+0*n] >> 4) & 1) + (((buf[j+1*n] >> 4) & 1) << 1) + (((buf[j+2*n] >> 4) & 1) << 2) + (((buf[j+3*n] >> 4) & 1) << 3) + (((buf[j+4*n] >> 4) & 1) << 4) + (((buf[j+5*n] >> 4) & 1) << 5) + (((buf[j+6*n] >> 4) & 1) << 6) + (((buf[j+7*n] >> 4) & 1) << 7); - *dest++ = ((buf[j+0*n] >> 3) & 1) + (((buf[j+1*n] >> 3) & 1) << 1) + (((buf[j+2*n] >> 3) & 1) << 2) + (((buf[j+3*n] >> 3) & 1) << 3) + (((buf[j+4*n] >> 3) & 1) << 4) + (((buf[j+5*n] >> 3) & 1) << 5) + (((buf[j+6*n] >> 3) & 1) << 6) + (((buf[j+7*n] >> 3) & 1) << 7); - *dest++ = ((buf[j+0*n] >> 2) & 1) + (((buf[j+1*n] >> 2) & 1) << 1) + (((buf[j+2*n] >> 2) & 1) << 2) + (((buf[j+3*n] >> 2) & 1) << 3) + (((buf[j+4*n] >> 2) & 1) << 4) + (((buf[j+5*n] >> 2) & 1) << 5) + (((buf[j+6*n] >> 2) & 1) << 6) + (((buf[j+7*n] >> 2) & 1) << 7); - *dest++ = ((buf[j+0*n] >> 1) & 1) + (((buf[j+1*n] >> 1) & 1) << 1) + (((buf[j+2*n] >> 1) & 1) << 2) + (((buf[j+3*n] >> 1) & 1) << 3) + (((buf[j+4*n] >> 1) & 1) << 4) + (((buf[j+5*n] >> 1) & 1) << 5) + (((buf[j+6*n] >> 1) & 1) << 6) + (((buf[j+7*n] >> 1) & 1) << 7); - *dest++ = ((buf[j+0*n] >> 0) & 1) + (((buf[j+1*n] >> 0) & 1) << 1) + (((buf[j+2*n] >> 0) & 1) << 2) + (((buf[j+3*n] >> 0) & 1) << 3) + (((buf[j+4*n] >> 0) & 1) << 4) + (((buf[j+5*n] >> 0) & 1) << 5) + (((buf[j+6*n] >> 0) & 1) << 6) + (((buf[j+7*n] >> 0) & 1) << 7); + *dst++ = ~(((buf[j+0*n] >> 7) << 7) + ((buf[j+1*n] >> 7) << 6) + ((buf[j+2*n] >> 7) << 5) + ((buf[j+3*n] >> 7) << 4) + ((buf[j+4*n] >> 7) << 3) + ((buf[j+5*n] >> 7) << 2) + ((buf[j+6*n] >> 7) << 1) + ((buf[j+7*n] >> 7) << 0)); + *dst++ = ~((((buf[j+0*n] >> 6) & 1) << 7) + (((buf[j+1*n] >> 6) & 1) << 6) + (((buf[j+2*n] >> 6) & 1) << 5) + (((buf[j+3*n] >> 6) & 1) << 4) + (((buf[j+4*n] >> 6) & 1) << 3) + (((buf[j+5*n] >> 6) & 1) << 2) + (((buf[j+6*n] >> 6) & 1) << 1) + (((buf[j+7*n] >> 6) & 1) << 0)); + *dst++ = ~((((buf[j+0*n] >> 5) & 1) << 7) + (((buf[j+1*n] >> 5) & 1) << 6) + (((buf[j+2*n] >> 5) & 1) << 5) + (((buf[j+3*n] >> 5) & 1) << 4) + (((buf[j+4*n] >> 5) & 1) << 3) + (((buf[j+5*n] >> 5) & 1) << 2) + (((buf[j+6*n] >> 5) & 1) << 1) + (((buf[j+7*n] >> 5) & 1) << 0)); + *dst++ = ~((((buf[j+0*n] >> 4) & 1) << 7) + (((buf[j+1*n] >> 4) & 1) << 6) + (((buf[j+2*n] >> 4) & 1) << 5) + (((buf[j+3*n] >> 4) & 1) << 4) + (((buf[j+4*n] >> 4) & 1) << 3) + (((buf[j+5*n] >> 4) & 1) << 2) + (((buf[j+6*n] >> 4) & 1) << 1) + (((buf[j+7*n] >> 4) & 1) << 0)); + *dst++ = ~((((buf[j+0*n] >> 3) & 1) << 7) + (((buf[j+1*n] >> 3) & 1) << 6) + (((buf[j+2*n] >> 3) & 1) << 5) + (((buf[j+3*n] >> 3) & 1) << 4) + (((buf[j+4*n] >> 3) & 1) << 3) + (((buf[j+5*n] >> 3) & 1) << 2) + (((buf[j+6*n] >> 3) & 1) << 1) + (((buf[j+7*n] >> 3) & 1) << 0)); + *dst++ = ~((((buf[j+0*n] >> 2) & 1) << 7) + (((buf[j+1*n] >> 2) & 1) << 6) + (((buf[j+2*n] >> 2) & 1) << 5) + (((buf[j+3*n] >> 2) & 1) << 4) + (((buf[j+4*n] >> 2) & 1) << 3) + (((buf[j+5*n] >> 2) & 1) << 2) + (((buf[j+6*n] >> 2) & 1) << 1) + (((buf[j+7*n] >> 2) & 1) << 0)); + *dst++ = ~((((buf[j+0*n] >> 1) & 1) << 7) + (((buf[j+1*n] >> 1) & 1) << 6) + (((buf[j+2*n] >> 1) & 1) << 5) + (((buf[j+3*n] >> 1) & 1) << 4) + (((buf[j+4*n] >> 1) & 1) << 3) + (((buf[j+5*n] >> 1) & 1) << 2) + (((buf[j+6*n] >> 1) & 1) << 1) + (((buf[j+7*n] >> 1) & 1) << 0)); + *dst++ = ~((((buf[j+0*n] >> 0) & 1) << 7) + (((buf[j+1*n] >> 0) & 1) << 6) + (((buf[j+2*n] >> 0) & 1) << 5) + (((buf[j+3*n] >> 0) & 1) << 4) + (((buf[j+4*n] >> 0) & 1) << 3) + (((buf[j+5*n] >> 0) & 1) << 2) + (((buf[j+6*n] >> 0) & 1) << 1) + (((buf[j+7*n] >> 0) & 1) << 0)); } } break; diff --git a/src/board_gruvin9x.cpp b/src/board_gruvin9x.cpp index 122f139e3..24dea87f7 100644 --- a/src/board_gruvin9x.cpp +++ b/src/board_gruvin9x.cpp @@ -189,15 +189,15 @@ bool keyState(EnumKeys enuk) return keys[enuk].state() ? 1 : 0; switch(enuk){ - case SW_ElevDR: + case SW_ELE: result = PINC & (1<= displayBuf && (p) < DISPLAY_END) -#ifdef SIMU -bool lcd_refresh = true; -uint8_t lcd_buf[DISPLAY_W*DISPLAY_H/8]; -#endif - void lcd_clear() { memset(displayBuf, 0, sizeof(displayBuf)); @@ -66,11 +61,6 @@ void lcd_img(xcoord_t x, uint8_t y, const pm_uchar * img, uint8_t idx, uint8_t m uint8_t lcdLastPos; -#if defined(PCBSKY9X) -uint8_t lcdLock; -uint32_t lcdInputs; -#endif - void lcd_putcAtt(xcoord_t x, uint8_t y, const unsigned char c, LcdFlags mode) { uint8_t *p = &displayBuf[ y / 8 * DISPLAY_W + x ]; @@ -124,9 +114,9 @@ void lcd_putcAtt(xcoord_t x, uint8_t y, const unsigned char c, LcdFlags mode) * by ten bottom bytes (20 bytes per * char) */ q = &font_8x10[((uint16_t)c-0x20)*16]; for (int8_t i=9; i>=0; i--) { - // TODO? if (mode & CONDENSED && i<=1) break; uint8_t b1=0, b2=0; - if (i!=0 && i!= 9) { + if (mode & CONDENSED && i<=1) break; + if (i!=0 && i!=9) { b1 = pgm_read_byte(q++); /*top byte*/ b2 = pgm_read_byte(q++); /*top byte*/ } @@ -154,6 +144,26 @@ void lcd_putcAtt(xcoord_t x, uint8_t y, const unsigned char c, LcdFlags mode) } } } + else if (mode & SMLSIZE) { + q = &font_4x6[((uint16_t)c-0x20)*5+4]; + uint8_t ym8 = (y % 8); + p += 4; + for (int8_t i=4; i>=0; i--) { + uint8_t b = pgm_read_byte(q--); + if (inv) b = ~b & 0x7f; + + if (p> (8-ym8)))) + (b >> (8-ym8)); + } + } + p--; + } + } #endif else { uint8_t condense=0; @@ -230,6 +240,7 @@ void lcd_putsnAtt(xcoord_t x, uint8_t y, const pm_char * s, uint8_t len, LcdFlag x += FW; if (mode&DBLSIZE) x += FW-1; else if (mode&MIDSIZE) x += FW-3; + else if (mode&SMLSIZE) x -= 1; } else { x += (c*FW/2); @@ -316,7 +327,8 @@ void lcd_outdezNAtt(xcoord_t x, uint8_t y, int16_t val, LcdFlags flags, uint8_t fw += FWNUM; } else if (midsize) { - fw += FWNUM-1; + flags |= CONDENSED; + fw += FWNUM-2; } else { if (flags & LEFT) { @@ -542,14 +554,22 @@ void putsTime(xcoord_t x, uint8_t y, putstime_t tme, LcdFlags att, LcdFlags att2 qr = div(tme, 60); -#if defined(PCBSKY9X) +#if defined(PCBX9D) + if (att & MIDSIZE) { + div_t qr2 = div(qr.quot, 60); + LCD_2DOTS(x+2*8-5, y, att); + lcd_outdezNAtt(x, y, qr2.quot, att|LEADING0|LEFT, 2); + x += 2*8+2; + } +#define separator ':' +#elif defined(PCBSKY9X) + char separator = ':'; if (tme >= 3600 && (~att & DBLSIZE)) { qr = div(qr.quot, 60); - lcd_outdezAtt(x+2*FWNUM, y, qr.quot, att); - lcd_putcAtt(lcdLastPos-((att & DBLSIZE) ? 1 : 0), y, 'h', att&att2); - lcd_outdezNAtt(lcdLastPos+FW, y, qr.rem, att2|LEADING0|LEFT, 2); - return; + separator = 'h'; } +#else +#define separator ':' #endif uint8_t x2, x3; @@ -558,15 +578,21 @@ void putsTime(xcoord_t x, uint8_t y, putstime_t tme, LcdFlags att, LcdFlags att2 x3 = x+2*(FW+FWNUM)+FW-2; } else if (att&MIDSIZE) { - x2 = x+2*8-1; - x3 = x+2*8+7; + x2 = x+2*8-5; + x3 = x+2*8+2; } else { x2 = x+2*FWNUM-1; x3 = x+2*FWNUM-1+FW; } - lcd_putcAtt(x2, y, ':', att&att2); +#if defined(PCBX9D) + if (att&MIDSIZE) { + LCD_2DOTS(x2, y, att); + } + else +#endif + lcd_putcAtt(x2, y, separator, att&att2); lcd_outdezNAtt(x, y, qr.quot, att|LEADING0|LEFT, 2); lcd_outdezNAtt(x3, y, qr.rem, att2|LEADING0|LEFT, 2); } @@ -748,381 +774,6 @@ void putsRotaryEncoderMode(xcoord_t x, uint8_t y, uint8_t phase, uint8_t idx, Lc } #endif -#ifdef PCBSKY9X - -// LCD i/o pins -// LCD_RES PC27 -// LCD_CS1 PC26 -// LCD_E PC12 -// LCD_RnW PC13 -// LCD_A0 PC15 -// LCD_D0 PC0 -// LCD_D1 PC7 -// LCD_D2 PC6 -// LCD_D3 PC5 -// LCD_D4 PC4 -// LCD_D5 PC3 -// LCD_D6 PC2 -// LCD_D7 PC1 - -#define LCD_DATA 0x000000FFL -#ifdef REVB -#define LCD_A0 0x00000080L -#else -#define LCD_A0 0x00008000L -#endif -#define LCD_RnW 0x00002000L -#define LCD_E 0x00001000L -#define LCD_CS1 0x04000000L -#define LCD_RES 0x08000000L - -// Lookup table for prototype board -#ifndef REVB -const uint8_t Lcd_lookup[] = -{ -0x00,0x01,0x80,0x81,0x40,0x41,0xC0,0xC1,0x20,0x21,0xA0,0xA1,0x60,0x61,0xE0,0xE1, -0x10,0x11,0x90,0x91,0x50,0x51,0xD0,0xD1,0x30,0x31,0xB0,0xB1,0x70,0x71,0xF0,0xF1, -0x08,0x09,0x88,0x89,0x48,0x49,0xC8,0xC9,0x28,0x29,0xA8,0xA9,0x68,0x69,0xE8,0xE9, -0x18,0x19,0x98,0x99,0x58,0x59,0xD8,0xD9,0x38,0x39,0xB8,0xB9,0x78,0x79,0xF8,0xF9, -0x04,0x05,0x84,0x85,0x44,0x45,0xC4,0xC5,0x24,0x25,0xA4,0xA5,0x64,0x65,0xE4,0xE5, -0x14,0x15,0x94,0x95,0x54,0x55,0xD4,0xD5,0x34,0x35,0xB4,0xB5,0x74,0x75,0xF4,0xF5, -0x0C,0x0D,0x8C,0x8D,0x4C,0x4D,0xCC,0xCD,0x2C,0x2D,0xAC,0xAD,0x6C,0x6D,0xEC,0xED, -0x1C,0x1D,0x9C,0x9D,0x5C,0x5D,0xDC,0xDD,0x3C,0x3D,0xBC,0xBD,0x7C,0x7D,0xFC,0xFD, -0x02,0x03,0x82,0x83,0x42,0x43,0xC2,0xC3,0x22,0x23,0xA2,0xA3,0x62,0x63,0xE2,0xE3, -0x12,0x13,0x92,0x93,0x52,0x53,0xD2,0xD3,0x32,0x33,0xB2,0xB3,0x72,0x73,0xF2,0xF3, -0x0A,0x0B,0x8A,0x8B,0x4A,0x4B,0xCA,0xCB,0x2A,0x2B,0xAA,0xAB,0x6A,0x6B,0xEA,0xEB, -0x1A,0x1B,0x9A,0x9B,0x5A,0x5B,0xDA,0xDB,0x3A,0x3B,0xBA,0xBB,0x7A,0x7B,0xFA,0xFB, -0x06,0x07,0x86,0x87,0x46,0x47,0xC6,0xC7,0x26,0x27,0xA6,0xA7,0x66,0x67,0xE6,0xE7, -0x16,0x17,0x96,0x97,0x56,0x57,0xD6,0xD7,0x36,0x37,0xB6,0xB7,0x76,0x77,0xF6,0xF7, -0x0E,0x0F,0x8E,0x8F,0x4E,0x4F,0xCE,0xCF,0x2E,0x2F,0xAE,0xAF,0x6E,0x6F,0xEE,0xEF, -0x1E,0x1F,0x9E,0x9F,0x5E,0x5F,0xDE,0xDF,0x3E,0x3F,0xBE,0xBF,0x7E,0x7F,0xFE,0xFF -} ; -#endif - -void lcdSendCtl(uint8_t val) -{ - register Pio *pioptr ; -// register uint32_t x ; - -#ifdef REVB - pioptr = PIOC ; - pioptr->PIO_CODR = LCD_CS1 ; // Select LCD - PIOA->PIO_CODR = LCD_A0 ; - pioptr->PIO_CODR = LCD_RnW ; // Write - pioptr->PIO_ODSR = val ; -#else - pioptr = PIOC ; - pioptr->PIO_CODR = LCD_CS1 ; // Select LCD - pioptr->PIO_CODR = LCD_A0 ; // Control - pioptr->PIO_CODR = LCD_RnW ; // Write - pioptr->PIO_ODSR = Lcd_lookup[val] ; -#endif - - pioptr->PIO_SODR = LCD_E ; // Start E pulse - // Need a delay here (250nS) - TC0->TC_CHANNEL[0].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger) - while ( TC0->TC_CHANNEL[0].TC_CV < 9 ) // Value depends on MCK/2 (used 18MHz) - { - // Wait - } - pioptr->PIO_CODR = LCD_E ; // End E pulse -#ifdef REVB - PIOA->PIO_SODR = LCD_A0 ; // Data -#else - pioptr->PIO_SODR = LCD_A0 ; // Data -#endif - pioptr->PIO_SODR = LCD_CS1 ; // Deselect LCD -} - -void lcd_init() -{ - register Pio *pioptr ; - // /home/thus/txt/datasheets/lcd/KS0713.pdf - // ~/txt/flieger/ST7565RV17.pdf from http://www.glyn.de/content.asp?wdid=132&sid= - -#ifdef REVB - configure_pins( LCD_A0, PIN_ENABLE | PIN_LOW | PIN_OUTPUT | PIN_PORTA | PIN_NO_PULLUP ) ; - pioptr = PIOC ; - pioptr->PIO_PER = 0x0C0030FFL ; // Enable bits 27,26,13,12,7-0 - pioptr->PIO_CODR = LCD_E | LCD_RnW ; - pioptr->PIO_SODR = LCD_RES | LCD_CS1 ; - pioptr->PIO_OER = 0x0C0030FFL ; // Set bits 27,26,13,12,7-0 output - pioptr->PIO_OWER = 0x000000FFL ; // Allow write to ls 8 bits in ODSR -#else - pioptr = PIOC ; - pioptr->PIO_PER = 0x0C00B0FFL ; // Enable bits 27,26,15,13,12,7-0 - pioptr->PIO_CODR = LCD_E | LCD_RnW | LCD_A0 ; - pioptr->PIO_SODR = LCD_RES | LCD_CS1 ; - pioptr->PIO_OER = 0x0C00B0FFL ; // Set bits 27,26,15,13,12,7-0 output - pioptr->PIO_OWER = 0x000000FFL ; // Allow write to ls 8 bits in ODSR -#endif - - pioptr->PIO_CODR = LCD_RES ; // Reset LCD - TC0->TC_CHANNEL[0].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger) - while ( TC0->TC_CHANNEL[0].TC_CV < 200 ) // > 10us, Value depends on MCK/2 (used 18MHz) - { - // Wait - } - pioptr->PIO_SODR = LCD_RES ; // Remove LCD reset - TC0->TC_CHANNEL[0].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger) - while ( TC0->TC_CHANNEL[0].TC_CV < 27000 ) // 1500us, Value depends on MCK/2 (used 18MHz) - { - // Wait - } - lcdSendCtl(0xe2); //Initialize the internal functions - lcdSendCtl(0xae); //DON = 0: display OFF - lcdSendCtl(0xa1); //ADC = 1: reverse direction(SEG132->SEG1) - lcdSendCtl(0xA6); //REV = 0: non-reverse display - lcdSendCtl(0xA4); //EON = 0: normal display. non-entire - lcdSendCtl(0xA2); // Select LCD bias=0 - lcdSendCtl(0xC0); //SHL = 0: normal direction (COM1->COM64) - lcdSendCtl(0x2F); //Control power circuit operation VC=VR=VF=1 - lcdSendCtl(0x25); //Select int resistance ratio R2 R1 R0 =5 - lcdSendCtl(0x81); //Set reference voltage Mode - lcdSendCtl(0x22); // 24 SV5 SV4 SV3 SV2 SV1 SV0 = 0x18 - lcdSendCtl(0xAF); //DON = 1: display ON - // g_eeGeneral.contrast = 0x22; - -#ifdef REVB - pioptr->PIO_ODR = 0x0000003AL ; // Set bits 1, 3, 4, 5 input - pioptr->PIO_PUER = 0x0000003AL ; // Set bits 1, 3, 4, 5 with pullups - pioptr->PIO_ODSR = 0 ; // Drive D0 low -#else - pioptr->PIO_ODR = 0x0000003CL ; // Set bits 2, 3, 4, 5 input - pioptr->PIO_PUER = 0x0000003CL ; // Set bits 2, 3, 4, 5 with pullups - pioptr->PIO_ODSR = 0 ; // Drive D0 low -#endif -} - -void lcdSetRefVolt(uint8_t val) -{ -#ifndef SIMU - register Pio *pioptr ; - pioptr = PIOC ; - - // read the inputs, and lock the LCD lines - lcdInputs = PIOC->PIO_PDSR; // 6 LEFT, 5 RIGHT, 4 DOWN, 3 UP () - lcdLock = 1 ; - - pioptr->PIO_OER = 0x0C00B0FFL ; // Set bits 27,26,15,13,12,7-0 output - - lcdSendCtl(0x81); - if ( val == 0 ) - { - val = 0x22 ; - } - lcdSendCtl(val); - -#ifdef REVB - pioptr->PIO_ODR = 0x0000003AL ; // Set bits 1, 3, 4, 5 input - pioptr->PIO_PUER = 0x0000003AL ; // Set bits 1, 3, 4, 5 with pullups -#else - pioptr->PIO_ODR = 0x0000003CL ; // Set bits 2, 3, 4, 5 input - pioptr->PIO_PUER = 0x0000003CL ; // Set bits 2, 3, 4, 5 with pullups -#endif - - pioptr->PIO_ODSR = lcdInputs; // Drive D0 low - lcdLock = 0 ; -#endif -} - -#ifndef SIMU -void refreshDisplay() -{ - register Pio *pioptr; - register uint8_t *p = displayBuf; - register uint32_t y; - register uint32_t x; - register uint32_t z; - register uint32_t ebit; -#ifndef REVB - register uint8_t *lookup; - lookup = (uint8_t *) Lcd_lookup; -#endif - - ebit = LCD_E; - -#ifdef REVB - pioptr = PIOA; - pioptr->PIO_PER = 0x00000080; // Enable bit 7 (LCD-A0) - pioptr->PIO_OER = 0x00000080;// Set bit 7 output -#endif - - // read the inputs, and lock the LCD lines - lcdInputs = PIOC->PIO_PDSR; // 6 LEFT, 5 RIGHT, 4 DOWN, 3 UP () - lcdLock = 1 ; - - pioptr = PIOC; -#ifdef REVB - pioptr->PIO_OER = 0x0C0030FFL; // Set bits 27,26,15,13,12,7-0 output -#else - pioptr->PIO_OER = 0x0C00B0FFL; // Set bits 27,26,15,13,12,7-0 output -#endif - for (y = 0; y < 8; y++) { - lcdSendCtl(g_eeGeneral.optrexDisplay ? 0 : 0x04); - lcdSendCtl(0x10); //column addr 0 - lcdSendCtl(y | 0xB0); //page addr y - - pioptr->PIO_CODR = LCD_CS1; // Select LCD - PIOA->PIO_SODR = LCD_A0; // Data - pioptr->PIO_CODR = LCD_RnW; // Write - -#ifdef REVB - x = *p; -#else - x = lookup[*p]; -#endif - for (z = 0; z < DISPLAY_W; z += 1) { - -// The following 7 lines replaces by a lookup table -// x = __RBIT( *p++ ) ; -// x >>= 23 ; -// if ( x & 0x00000100 ) -// { -// x |= 1 ; -// } -// pioptr->PIO_ODSR = x ; - - pioptr->PIO_ODSR = x; - pioptr->PIO_SODR = ebit; // Start E pulse - // Need a delay here (250nS) - p += 1; -#ifdef REVB - x = *p; -#else - x = lookup[*p]; -#endif -// TC0->TC_CHANNEL[0].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger) -// while ( TC0->TC_CHANNEL[0].TC_CV < 3 ) // Value depends on MCK/2 (used 6MHz) -// { -// // Wait -// } - pioptr->PIO_CODR = ebit; // End E pulse - } - pioptr->PIO_SODR = LCD_CS1; // Deselect LCD - } - - pioptr->PIO_ODSR = 0xFF ; // Drive lines high -#ifdef REVB - pioptr->PIO_PUER = 0x0000003AL ; // Set bits 1, 3, 4, 5 with pullups - pioptr->PIO_ODR = 0x0000003AL ; // Set bits 1, 3, 4, 5 input -#else - pioptr->PIO_PUER = 0x0000003CL ; // Set bits 2, 3, 4, 5 with pullups - pioptr->PIO_ODR = 0x0000003CL ; // Set bits 2, 3, 4, 5 input -#endif - - pioptr->PIO_ODSR = lcdInputs; // Drive D0 low - lcdLock = 0; -} -#endif - -#else - -#define delay_1us() _delay_us(1) -void delay_1_5us(int ms) -{ - for(int i=0; iSEG1) - lcdSendCtl(0xA6); //REV = 0: non-reverse display - lcdSendCtl(0xA4); //EON = 0: normal display. non-entire - lcdSendCtl(0xA2); // Select LCD bias=0 - lcdSendCtl(0xC0); //SHL = 0: normal direction (COM1->COM64) - lcdSendCtl(0x2F); //Control power circuit operation VC=VR=VF=1 - lcdSendCtl(0x25); //Select int resistance ratio R2 R1 R0 =5 - lcdSendCtl(0x81); //Set reference voltage Mode - lcdSendCtl(0x22); // 24 SV5 SV4 SV3 SV2 SV1 SV0 = 0x18 - lcdSendCtl(0xAF); //DON = 1: display ON - g_eeGeneral.contrast = 0x22; - LCD_UNLOCK(); -} - -void lcdSetRefVolt(uint8_t val) -{ - LCD_LOCK(); - lcdSendCtl(0x81); - lcdSendCtl(val); - LCD_UNLOCK(); -} - -#ifndef SIMU -void refreshDisplay() -{ - LCD_LOCK(); - uint8_t *p=displayBuf; - for(uint8_t y=0; y < 8; y++) { - lcdSendCtl(0x04); - lcdSendCtl(0x10); //column addr 0 - lcdSendCtl( y | 0xB0); //page addr y - PORTC_LCD_CTRL &= ~(1<0; --x) { - PORTA_LCD_DAT = *p++; - PORTC_LCD_CTRL |= (1<= NUM_CSW/2 ? BITMAP_X+26 : 19) + 3*i) +#define VSWITCH_Y (DISPLAY_H-9) #else #define BOX_WIDTH 23 #define LBOX_CENTERX (DISPLAY_W/4 + 10) @@ -64,6 +67,8 @@ #define VBATTUNIT_X (VBATT_X-1) #define VBATTUNIT_Y (3*FH) #define REBOOT_X (20*FW-3) +#define VSWITCH_X(i) (16 + 3*i) +#define VSWITCH_Y (DISPLAY_H-8) #endif #define BAR_HEIGHT (BOX_WIDTH-1l) @@ -87,17 +92,7 @@ void doMainScreenGraphics() calibStickVert = -calibStickVert; lcd_square(RBOX_CENTERX+(calibratedStick[CONVERT_MODE(3+1)-1]*BOX_LIMIT/(2*RESX))-MARKER_WIDTH/2, RBOX_CENTERY-(calibStickVert*BOX_LIMIT/(2*RESX))-MARKER_WIDTH/2, MARKER_WIDTH, ROUND); -#if defined(PCBX9D) - for (uint8_t i=NUM_STICKS; iNUM_STICKS+1 ? DISPLAY_W-5 : 3); - int8_t y = (i%2 ? DISPLAY_H/2+1 : 1); - lcd_vline(x, y, DISPLAY_H/2-2); - lcd_vline(x+1, y, DISPLAY_H/2-2); - y += ((calibratedStick[i]+RESX)*(DISPLAY_H/2-4)/(RESX*2)); // calculate once per loop - lcd_vline(x-1, y, 2); - lcd_vline(x+2, y, 2); - } -#else +#if !defined(PCBX9D) // Optimization by Mike Blandford { uint8_t x, y, len ; // declare temporary variables @@ -135,7 +130,7 @@ void menuMainView(uint8_t event) { /* TODO if timer2 is OFF, it's possible to use this timer2 as in er9x... case EVT_KEY_BREAK(KEY_MENU): - if (view_base == e_timer2) { + if (view_base == VIEW_TIMER2) { Timer2_running = !Timer2_running; AUDIO_KEYPAD_UP(); } @@ -151,9 +146,9 @@ void menuMainView(uint8_t event) case EVT_KEY_BREAK(KEY_RIGHT): case EVT_KEY_BREAK(KEY_LEFT): - if (view_base <= e_inputs) { + if (view_base <= VIEW_INPUTS) { #if defined(PCBSKY9X) - if (view_base == e_inputs) + if (view_base == VIEW_INPUTS) g_eeGeneral.view ^= ALTERNATE_VIEW; else g_eeGeneral.view = (g_eeGeneral.view + (4*ALTERNATE_VIEW) + ((event==EVT_KEY_BREAK(KEY_LEFT)) ? -ALTERNATE_VIEW : ALTERNATE_VIEW)) % (4*ALTERNATE_VIEW); @@ -182,7 +177,7 @@ void menuMainView(uint8_t event) case EVT_KEY_BREAK(KEY_UP): case EVT_KEY_BREAK(KEY_DOWN): #endif - g_eeGeneral.view = (event == EVT_KEY_BREAK(KEY_UP) ? (view_base == MAIN_VIEW_MAX ? 0 : view_base + 1) : (view_base == 0 ? MAIN_VIEW_MAX : view_base - 1)); + g_eeGeneral.view = (event == EVT_KEY_BREAK(KEY_UP) ? (view_base == VIEW_COUNT-1 ? 0 : view_base+1) : (view_base == 0 ? VIEW_COUNT-1 : view_base-1)); eeDirty(EE_GENERAL); AUDIO_KEYPAD_UP(); break; @@ -221,9 +216,11 @@ void menuMainView(uint8_t event) s_gvar_timer = 0; } #endif - else if (view == e_timer2) { +#if !defined(LCD212) + else if (view == VIEW_TIMER2) { resetTimer(1); } +#endif else { resetTimer(0); } @@ -271,18 +268,28 @@ void menuMainView(uint8_t event) #if defined(LCD212) // Main timer if (g_model.timers[0].mode) { - LcdFlags att = MIDSIZE | (s_timerState[0]==TMR_BEEPING ? BLINK|INVERS : 0); - putsTime(TIMERS_X, 0, s_timerVal[0], att, att); - putsTmrMode(TIMERS_X-25, 4, g_model.timers[0].mode, SWCONDENSED); - if (g_model.timers[0].remanent) lcd_putc(TIMERS_X+42, 1, 'R'); + putsTime(TIMERS_X, 0, s_timerVal[0], MIDSIZE, MIDSIZE); + putsTmrMode(TIMERS_X-16, 5, g_model.timers[0].mode, SWCONDENSED|SMLSIZE); + if (g_model.timers[0].remanent) lcd_putcAtt(TIMERS_R, 1, 'R', SMLSIZE); + if (s_timerState[0]==TMR_BEEPING) { + lcd_hline(TIMERS_X-6, 2, 4); + // lcd_hline(TIMERS_X-6, 3, 4); + if (BLINK_ON_PHASE) + lcd_filled_rect(TIMERS_X-17, 0, 72, 12); + } } // Second timer if (g_model.timers[1].mode) { - LcdFlags att = MIDSIZE | (s_timerState[1]==TMR_BEEPING ? BLINK|INVERS : 0); - putsTime(TIMERS_X, (FH+3), s_timerVal[1], att, att); - putsTmrMode(TIMERS_X-25, FH+7, g_model.timers[1].mode, SWCONDENSED); - if (g_model.timers[1].remanent) lcd_putc(TIMERS_X+42, FH+4, 'R'); + putsTime(TIMERS_X, FH+3, s_timerVal[1], MIDSIZE, MIDSIZE); + putsTmrMode(TIMERS_X-16, FH+8, g_model.timers[1].mode, SWCONDENSED|SMLSIZE); + if (g_model.timers[1].remanent) lcd_putcAtt(TIMERS_R, FH+4, 'R', SMLSIZE); + if (s_timerState[1]==TMR_BEEPING) { + lcd_hline(TIMERS_X-6, FH+5, 4); + // lcd_hline(TIMERS_X-6, FH+6, 4); + if (BLINK_ON_PHASE) + lcd_filled_rect(TIMERS_X-17, FH+3, 72, 12); + } } #else // Main timer @@ -340,10 +347,23 @@ void menuMainView(uint8_t event) } #if defined(PCBX9D) - lcd_img(BITMAP_X, BITMAP_Y, modelBitmap, 0, 0); + for (uint8_t i=NUM_STICKS; iNUM_STICKS+1 ? DISPLAY_W-5 : 3); + int8_t y = (i%2 ? DISPLAY_H/2+1 : 1); + lcd_vline(x, y, DISPLAY_H/2-2); + lcd_vline(x+1, y, DISPLAY_H/2-2); + y += ((calibratedStick[i]+RESX)*(DISPLAY_H/2-4)/(RESX*2)); // calculate once per loop + lcd_vline(x-1, y, 2); + lcd_vline(x+2, y, 2); + } #endif - if (view_base < e_inputs) { +#if defined(LCD212) + if (view_base == VIEW_OUTPUTS) { + + } +#else + if (view_base < VIEW_INPUTS) { // scroll bar lcd_hlineStip(38, 34, 54, DOTTED); #if defined(PCBSKY9X) @@ -364,7 +384,7 @@ void menuMainView(uint8_t event) switch(view_base) { - case e_outputValues: + case VIEW_OUTPUTS_VALUES: x0 = (i%4*9+3)*FW/2; y0 = i/4*FH+40; #if defined (DECIMALS_DISPLAYED) @@ -374,7 +394,7 @@ void menuMainView(uint8_t event) #endif break; - case e_outputBars: + case VIEW_OUTPUTS_BARS: #define WBAR2 (50/2) x0 = i<4 ? DISPLAY_W/4+2 : DISPLAY_W*3/4-2; y0 = 38+(i%4)*5; @@ -395,8 +415,13 @@ void menuMainView(uint8_t event) } } } - else if (view_base == e_inputs) { - if (view == e_inputs) { +#endif + else if (view_base == VIEW_INPUTS) { +#if defined(PCBX9D) + lcd_img(BITMAP_X, BITMAP_Y, modelBitmap, 0, 0); +#endif + + if (view == VIEW_INPUTS) { // hardware inputs doMainScreenGraphics(); #if defined(PCBX9D) @@ -427,7 +452,7 @@ void menuMainView(uint8_t event) #endif } else { -#if defined(ROTARY_ENCODERS) +#if defined(PCBGRUVIN9X) && defined(ROTARY_ENCODERS) for (uint8_t i=0; i0) { int8_t swtch = getMovedSwitch(); if (swtch) { - if (newval == DSW_TRN && swtch == DSW_TRN) + if (newval == DSW(SW_TRN) && swtch == DSW(SW_TRN)) newval = -newval; else newval = swtch; @@ -749,7 +749,7 @@ const char * displayMenu(uint8_t event) } switch(event) { - case EVT_KEY_BREAK(KEY_UP): + case EVT_KEY_BREAK(KEY_MOVE_UP): if (s_menu_item > 0) s_menu_item--; else if (s_menu_offset > 0) { @@ -757,7 +757,7 @@ const char * displayMenu(uint8_t event) result = STR_UPDATE_LIST; } break; - case EVT_KEY_BREAK(KEY_DOWN): + case EVT_KEY_BREAK(KEY_MOVE_DOWN): if (s_menu_item < display_count - 1 && s_menu_offset + s_menu_item + 1 < s_menu_count) s_menu_item++; else if (s_menu_count > s_menu_offset + display_count) { @@ -765,7 +765,7 @@ const char * displayMenu(uint8_t event) result = STR_UPDATE_LIST; } break; - case EVT_KEY_BREAK(KEY_MENU): + case EVT_KEY_BREAK(KEY_ENTER): result = s_menu[s_menu_item]; // no break case EVT_KEY_BREAK(KEY_EXIT): diff --git a/src/model_menus.cpp b/src/model_menus.cpp index e53d6e2d0..25e6a220d 100644 --- a/src/model_menus.cpp +++ b/src/model_menus.cpp @@ -504,7 +504,7 @@ void menuModelSelect(uint8_t event) s_warning = eeBackupModel(sub); } else if (result == STR_RESTORE_MODEL || result == STR_UPDATE_LIST) { - if (!listSdFiles(MODELS_PATH, MODELS_EXT, 10, NULL)) { + if (!listSdFiles(MODELS_PATH, MODELS_EXT, sizeof(g_model.name), NULL)) { s_warning = STR_NO_MODELS_ON_SD; s_menu_flags = 0; } @@ -589,6 +589,7 @@ void editName(uint8_t x, uint8_t y, char *name, uint8_t size, uint8_t event, boo enum menuModelSetupItems { ITEM_MODEL_NAME, + IF_PCBX9D(ITEM_MODEL_BITMAP) ITEM_MODEL_TIMER1, ITEM_MODEL_TIMER2, ITEM_MODEL_EXTENDED_LIMITS, @@ -617,11 +618,18 @@ enum menuModelSetupItems { void menuModelSetup(uint8_t event) { +#if defined(PCBX9D) && defined(SDCARD) + uint8_t _event = event; + if (s_menu_count) { + event = 0; + } +#endif + lcd_outdezNAtt(7*FW,0,g_eeGeneral.currModel+1,INVERS+LEADING0,2); uint8_t protocol = g_model.protocol; -#ifdef DSM2 +#if defined(DSM2) if (event == EVT_KEY_LONG(KEY_EXIT)) s_rangecheck_mode = 0; #endif @@ -645,6 +653,25 @@ void menuModelSetup(uint8_t event) #endif break; +#if defined(PCBX9D) + case ITEM_MODEL_BITMAP: + lcd_putsLeft(y, STR_BITMAP); + if (ZLEN(g_model.bitmap) > 0) + lcd_putsnAtt(MODEL_SETUP_2ND_COLUMN, y, g_model.bitmap, sizeof(g_model.bitmap), attr); + else + lcd_putsiAtt(MODEL_SETUP_2ND_COLUMN, y, STR_VCSWFUNC, 0, attr); + if (attr && event==EVT_KEY_BREAK(KEY_ENTER)) { + s_editMode = 0; + _event = 0; + if (!listSdFiles(BITMAPS_PATH, BITMAPS_EXT, sizeof(g_model.bitmap), g_model.bitmap)) { + s_warning = STR_NO_BITMAPS_ON_SD; + s_menu_flags = 0; + } + } + + break; +#endif + case ITEM_MODEL_TIMER1: case ITEM_MODEL_TIMER2: { @@ -861,6 +888,26 @@ void menuModelSetup(uint8_t event) break; } } + +#if defined(PCBX9D) && defined(SDCARD) + if (s_menu_count) { + const char * result = displayMenu(_event); + if (result) { + if (result == STR_UPDATE_LIST) { + if (!listSdFiles(BITMAPS_PATH, BITMAPS_EXT, sizeof(g_model.bitmap), NULL)) { + s_warning = STR_NO_BITMAPS_ON_SD; + s_menu_flags = 0; + } + } + else { + // The user choosed a bmp file in the list + memcpy(g_model.bitmap, result, sizeof(g_model.bitmap)); + LOAD_MODEL_BITMAP(); + eeDirty(EE_MODEL); + } + } + } +#endif } static uint8_t s_currIdx; @@ -1896,14 +1943,6 @@ static uint8_t s_copySrcCh; #define EXPO_LINE_SELECT_POS 18 #endif -#if defined(PCBX9D) -#define KEY_MIX_MOVE_UP KEY_MINUS -#define KEY_MIX_MOVE_DOWN KEY_PLUS -#else -#define KEY_MIX_MOVE_UP KEY_UP -#define KEY_MIX_MOVE_DOWN KEY_DOWN -#endif - void menuModelExpoMix(uint8_t expo, uint8_t event) { #if defined(ROTARY_ENCODERS) @@ -1998,29 +2037,29 @@ void menuModelExpoMix(uint8_t expo, uint8_t event) return; } break; - case EVT_KEY_FIRST(KEY_MIX_MOVE_UP): - case EVT_KEY_REPT(KEY_MIX_MOVE_UP): - case EVT_KEY_FIRST(KEY_MIX_MOVE_DOWN): - case EVT_KEY_REPT(KEY_MIX_MOVE_DOWN): + case EVT_KEY_FIRST(KEY_MOVE_UP): + case EVT_KEY_REPT(KEY_MOVE_UP): + case EVT_KEY_FIRST(KEY_MOVE_DOWN): + case EVT_KEY_REPT(KEY_MOVE_DOWN): if (s_copyMode) { uint8_t key = (event & 0x1f); - uint8_t next_ofs = (key == KEY_MIX_MOVE_UP ? s_copyTgtOfs - 1 : s_copyTgtOfs + 1); + uint8_t next_ofs = (key == KEY_MOVE_UP ? s_copyTgtOfs - 1 : s_copyTgtOfs + 1); if (s_copyTgtOfs==0 && s_copyMode==COPY_MODE) { // insert a mix on the same channel (just above / just below) if (reachExpoMixCountLimit(expo)) break; copyExpoMix(expo, s_currIdx); - if (key==KEY_MIX_MOVE_DOWN) s_currIdx++; + if (key==KEY_MOVE_DOWN) s_currIdx++; else if (sub-s_pgOfs >= 6) s_pgOfs++; } else if (next_ofs==0 && s_copyMode==COPY_MODE) { // delete the mix deleteExpoMix(expo, s_currIdx); - if (key==KEY_MIX_MOVE_UP) s_currIdx--; + if (key==KEY_MOVE_UP) s_currIdx--; } else { // only swap the mix with its neighbor - if (!swapExpoMix(expo, s_currIdx, key==KEY_MIX_MOVE_UP)) break; + if (!swapExpoMix(expo, s_currIdx, key==KEY_MOVE_UP)) break; STORE_MODELVARS; } @@ -2458,7 +2497,7 @@ void menuModelCustomSwitchOne(uint8_t event) TITLE(STR_MENUCUSTOMSWITCH); CustomSwData * cs = cswaddress(s_currIdx); - uint8_t sw = DSW_SW1+s_currIdx; + uint8_t sw = DSW(SW_SW1)+s_currIdx; putsSwitches(14*FW, 0, sw, (getSwitch(sw, 0) ? BOLD : 0)); SIMPLE_SUBMENU_NOTITLE(CSW_FIELD_COUNT); @@ -2592,7 +2631,8 @@ void menuModelCustomSwitches(uint8_t event) CustomSwData * cs = cswaddress(k); // CSW name - uint8_t sw = DSW_SW1+k; + uint8_t sw = DSW(SW_SW1)+k; + putsSwitches(0, y, sw, (sub==k ? INVERS : 0) | (getSwitch(sw, 0) ? BOLD : 0)); if (cs->func > 0) { @@ -2642,7 +2682,7 @@ void menuModelCustomSwitches(uint8_t event) CustomSwData * cs = cswaddress(k); // CSW name - uint8_t sw = DSW_SW1+k; + uint8_t sw = DSW(SW_SW1)+k; putsSwitches(0, y, sw, getSwitch(sw, 0) ? BOLD : 0); // CSW func @@ -2808,13 +2848,14 @@ void menuModelCustomFunctions(uint8_t event) #endif #if defined(PCBSKY9X) && defined(SDCARD) else if (sd->func == FUNC_PLAY_TRACK || sd->func == FUNC_BACKGND_MUSIC) { - if (sd->param[0] && sd->param[1]) + if (ZLEN(sd->param)) lcd_putsnAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, sd->param, sizeof(sd->param), attr); else lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_VCSWFUNC, 0, attr); - if (active && event==EVT_KEY_BREAK(KEY_MENU)) { + if (active && event==EVT_KEY_BREAK(KEY_ENTER)) { s_editMode = 0; - if (!listSdFiles(SOUNDS_PATH, SOUNDS_EXT, 6, sd->param)) { + _event = 0; + if (!listSdFiles(SOUNDS_PATH, SOUNDS_EXT, sizeof(sd->param), sd->param)) { s_warning = STR_NO_SOUNDS_ON_SD; s_menu_flags = 0; } @@ -2906,7 +2947,7 @@ void menuModelCustomFunctions(uint8_t event) const char * result = displayMenu(_event); if (result) { if (result == STR_UPDATE_LIST) { - if (!listSdFiles(SOUNDS_PATH, SOUNDS_EXT, 6, NULL)) { + if (!listSdFiles(SOUNDS_PATH, SOUNDS_EXT, sizeof(g_model.funcSw[sub].param), NULL)) { s_warning = STR_NO_SOUNDS_ON_SD; s_menu_flags = 0; } diff --git a/src/myeeprom.h b/src/myeeprom.h index 4f32b4ea8..5757c6638 100644 --- a/src/myeeprom.h +++ b/src/myeeprom.h @@ -76,13 +76,21 @@ PACK(typedef struct t_FrSkyRSSIAlarm { int8_t value:6; }) FrSkyRSSIAlarm; +#if defined(LCD212) enum MainViews { - e_outputValues, - e_outputBars, - e_inputs, - e_timer2, - MAIN_VIEW_MAX = e_timer2 + VIEW_OUTPUTS, + VIEW_INPUTS, + VIEW_COUNT }; +#else +enum MainViews { + VIEW_OUTPUTS_VALUES, + VIEW_OUTPUTS_BARS, + VIEW_INPUTS, + VIEW_TIMER2, + VIEW_COUNT +}; +#endif enum BeeperMode { e_mode_quiet = -2, @@ -776,6 +784,12 @@ enum Dsm2Variants { #define BeepANACenter uint8_t #endif +#if defined(PCBX9D) +#define MODELDATA_EXTRA char bitmap[10] +#else +#define MODELDATA_EXTRA +#endif + PACK(typedef struct t_ModelData { char name[LEN_MODEL_NAME]; // must be first for eeLoadModelName TimerData timers[MAX_TIMERS]; @@ -814,6 +828,8 @@ PACK(typedef struct t_ModelData { ROTARY_ENCODER_ARRAY_EXTRA; + MODELDATA_EXTRA; + }) ModelData; extern EEGeneral g_eeGeneral; diff --git a/src/open9x.cpp b/src/open9x.cpp index 737ae95d0..c98af60ed 100644 --- a/src/open9x.cpp +++ b/src/open9x.cpp @@ -90,6 +90,14 @@ ModelData g_model; #if defined(PCBX9D) uint8_t modelBitmap[64*32/8]; +void loadModelBitmap() +{ + char lfn[] = BITMAPS_PATH "/xxxxxxxxxx.bmp"; + strncpy(lfn+sizeof(BITMAPS_PATH), g_model.bitmap, sizeof(g_model.bitmap)); + lfn[sizeof(BITMAPS_PATH)+sizeof(g_model.bitmap)] = '\0'; + strcat(lfn+sizeof(BITMAPS_PATH), BITMAPS_EXT); + bmpLoad(modelBitmap, lfn); +} #endif #if !defined(PCBSKY9X) @@ -161,7 +169,7 @@ char idx2char(int8_t idx) return ' '; } -#if defined(PCBX9D) +#if defined(CPUARM) uint8_t zlen(const char *str, uint8_t size) { while (size > 0) { diff --git a/src/open9x.h b/src/open9x.h index 0b159041b..ede6140c0 100644 --- a/src/open9x.h +++ b/src/open9x.h @@ -208,6 +208,10 @@ extern void board_init(); #if defined(PCBX9D) extern uint8_t modelBitmap[64*32/8]; +void loadModelBitmap(); +#define LOAD_MODEL_BITMAP() loadModelBitmap() +#else +#define LOAD_MODEL_BITMAP() #endif #if defined(DSM2) @@ -478,23 +482,48 @@ enum EnumKeys { SW_SH0, SW_SH2, #else - SW_ThrCt=SW_BASE, - SW_RuddDR, - SW_ElevDR, + SW_THR=SW_BASE, + SW_RUD, + SW_ELE, SW_ID0, SW_ID1, SW_ID2, - SW_AileDR, - SW_Gear, - SW_Trainer, + SW_AIL, + SW_GEA, + SW_TRN, #endif + + SW_SW1, + SW_SW2, + SW_SW3, + SW_SW4, + SW_SW5, + SW_SW6, + SW_SW7, + SW_SW8, + SW_SW9, + SW_SWA, + SW_SWB, + SW_SWC, }; +#define DSW(x) (1+(x)-SW_BASE) + #if defined(PCBX9D) #define KEY_RIGHT KEY_PLUS #define KEY_UP KEY_PLUS #define KEY_LEFT KEY_MINUS #define KEY_DOWN KEY_MINUS +/* mapping of 9x switches */ +#define SW_THR SW_SA2 +#define SW_RUD SW_SB2 +#define SW_ELE SW_SC2 +#define SW_ID0 SW_SD0 +#define SW_ID1 SW_SD1 +#define SW_ID2 SW_SD2 +#define SW_AIL SW_SF2 +#define SW_GEA SW_SG2 +#define SW_TRN SW_SH2 #else #define KEY_ENTER KEY_MENU #define KEY_PLUS KEY_RIGHT @@ -576,7 +605,7 @@ enum CswFunctions { #define NUM_POTS 4 #define NUM_SW_SRCRAW 8 #else -#define MAX_PSWITCH (SW_Trainer-SW_ThrCt+1) // 9 physical switches +#define MAX_PSWITCH (SW_TRN-SW_THR+1) // 9 physical switches #define NUM_POTS 3 #define NUM_SW_SRCRAW 1 #endif @@ -625,24 +654,6 @@ enum CswFunctions { #define NUM_XCHNPLAY (NUM_XCHNRAW+TELEM_DISPLAY_MAX) #endif -#define DSW_THR 1 -#define DSW_RUD 2 -#define DSW_ELE 3 -#define DSW_ID0 4 -#define DSW_ID1 5 -#define DSW_ID2 6 -#define DSW_AIL 7 -#define DSW_GEA 8 -#define DSW_TRN 9 -#define DSW_SW1 10 -#define DSW_SW2 11 -#define DSW_SW3 12 -#define DSW_SW4 13 -#define DSW_SW5 14 -#define DSW_SW6 15 -#define DSW_SWB 20 -#define DSW_SWC 21 - #define THRCHK_DEADBAND 16 #if defined(FSPLASH) || defined(XSPLASH) #define SPLASH_TIMEOUT (g_eeGeneral.splashMode == 0 ? 60000/*infinite=10mn*/ : ((4*100) * (g_eeGeneral.splashMode & 0x03))) @@ -1313,10 +1324,18 @@ void checkFlashOnBeep(); void putsTelemetryValue(uint8_t x, uint8_t y, int16_t val, uint8_t unit, uint8_t att); #endif -#if defined(PCBX9D) +#if defined(CPUARM) uint8_t zlen(const char *str, uint8_t size); #define ZLEN(s) zlen(s, sizeof(s)) #endif +#if defined(PCBX9D) +#define KEY_MOVE_UP KEY_MINUS +#define KEY_MOVE_DOWN KEY_PLUS +#else +#define KEY_MOVE_UP KEY_UP +#define KEY_MOVE_DOWN KEY_DOWN +#endif + #endif diff --git a/src/pulses_arm.cpp b/src/pulses_arm.cpp index 2c4f56340..5f2b56826 100644 --- a/src/pulses_arm.cpp +++ b/src/pulses_arm.cpp @@ -382,7 +382,7 @@ void setupPulsesDsm2(uint8_t chns) #if defined(PCBX9D) // TODO #else - if ((dsmDat[0] & BIND_BIT) && (!keyState(SW_Trainer))) dsmDat[0] &= ~BIND_BIT; // clear bind bit if trainer not pulled + if ((dsmDat[0] & BIND_BIT) && (!keyState(SW_TRN))) dsmDat[0] &= ~BIND_BIT; // clear bind bit if trainer not pulled #endif // TODO find a way to do that, FUNC SWITCH: if ((!(dsmDat[0] & BIND_BIT)) && getSwitch(MAX_DRSWITCH-1, 0, 0)) dsmDat[0] |= RANGECHECK_BIT; // range check function diff --git a/src/pulses_avr.cpp b/src/pulses_avr.cpp index 2e0341171..ee6387820 100644 --- a/src/pulses_avr.cpp +++ b/src/pulses_avr.cpp @@ -409,7 +409,7 @@ FORCEINLINE void setupPulsesDsm2() break; } if (s_bind_allowed) s_bind_allowed--; - if (s_bind_allowed && keyState(SW_Trainer)) + if (s_bind_allowed && keyState(SW_TRN)) { s_bind_mode = true; *ptr |= BIND_BIT; @@ -536,7 +536,7 @@ void setupPulsesDsm2() } if (s_bind_allowed) s_bind_allowed--; - if (s_bind_allowed && keyState(SW_Trainer)) + if (s_bind_allowed && keyState(SW_TRN)) { s_bind_mode = true; dsmDat[0] |= BIND_BIT; diff --git a/src/sdcard.h b/src/sdcard.h index db84bf45b..952e63f78 100644 --- a/src/sdcard.h +++ b/src/sdcard.h @@ -42,17 +42,20 @@ #define LOGS_PATH "." #define SOUNDS_PATH "." #define SYSTEM_SOUNDS_PATH "." +#define BITMAPS_PATH "." #else #define ROOT_PATH "/" #define MODELS_PATH "/9XMODELS" #define LOGS_PATH "/9XLOGS" // no trailing slash = important #define SOUNDS_PATH "/9XSOUNDS" // no trailing slash = important #define SYSTEM_SOUNDS_PATH "/9XSOUNDS/SYSTEM" // no trailing slash = important +#define BITMAPS_PATH MODELS_PATH #endif #define MODELS_EXT ".bin" #define LOGS_EXT ".csv" #define SOUNDS_EXT ".wav" +#define BITMAPS_EXT ".bmp" extern FATFS g_FATFS_Obj; diff --git a/src/simpgmspace.cpp b/src/simpgmspace.cpp index 796bc2026..fc1f78f02 100644 --- a/src/simpgmspace.cpp +++ b/src/simpgmspace.cpp @@ -66,7 +66,7 @@ sem_t *eeprom_write_sem; void setSwitch(int8_t swtch) { switch (swtch) { - case DSW_ID0: + case DSW(SW_ID0): #if defined(PCBSKY9X) PIOC->PIO_PDSR &= ~0x00004000; PIOC->PIO_PDSR |= 0x00000800; @@ -78,7 +78,7 @@ void setSwitch(int8_t swtch) pine &= ~(1<PIO_PDSR |= 0x00004800; #elif defined(PCBGRUVIN9X) @@ -89,7 +89,7 @@ void setSwitch(int8_t swtch) pine &= ~(1<PIO_PDSR &= ~0x00000800; PIOC->PIO_PDSR |= 0x00004000; diff --git a/src/simu.cpp b/src/simu.cpp index 8de963bcc..a0d6492ea 100644 --- a/src/simu.cpp +++ b/src/simu.cpp @@ -425,9 +425,9 @@ long Open9xSim::onTimeout(FXObject*,FXSelector,void*) } switch(id){ - case 0: setSwitch(DSW_ID0); break; - case 1: setSwitch(DSW_ID1); break; - case 2: setSwitch(DSW_ID2); break; + case 0: setSwitch(DSW(SW_ID0)); break; + case 1: setSwitch(DSW(SW_ID1)); break; + case 2: setSwitch(DSW(SW_ID2)); break; } } @@ -545,3 +545,16 @@ uint16_t anaIn(uint8_t chan) else return th9xSim->knobs[chan]->getValue(); } + +bool lcd_refresh = true; +uint8_t lcd_buf[DISPLAY_W*DISPLAY_H/8]; + +void lcdSetRefVolt(uint8_t val) +{ +} + +void refreshDisplay() +{ + memcpy(lcd_buf, displayBuf, sizeof(displayBuf)); + lcd_refresh = true; +} diff --git a/src/sky9x/lcd_driver.cpp b/src/sky9x/lcd_driver.cpp new file mode 100644 index 000000000..75c12a965 --- /dev/null +++ b/src/sky9x/lcd_driver.cpp @@ -0,0 +1,296 @@ +/* + * Authors (alphabetical order) + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * open9x is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "open9x.h" + +// LCD i/o pins +// LCD_RES PC27 +// LCD_CS1 PC26 +// LCD_E PC12 +// LCD_RnW PC13 +// LCD_A0 PC15 +// LCD_D0 PC0 +// LCD_D1 PC7 +// LCD_D2 PC6 +// LCD_D3 PC5 +// LCD_D4 PC4 +// LCD_D5 PC3 +// LCD_D6 PC2 +// LCD_D7 PC1 + +#define LCD_DATA 0x000000FFL +#ifdef REVB +#define LCD_A0 0x00000080L +#else +#define LCD_A0 0x00008000L +#endif +#define LCD_RnW 0x00002000L +#define LCD_E 0x00001000L +#define LCD_CS1 0x04000000L +#define LCD_RES 0x08000000L + +// Lookup table for prototype board +#ifndef REVB +const uint8_t Lcd_lookup[] = +{ +0x00,0x01,0x80,0x81,0x40,0x41,0xC0,0xC1,0x20,0x21,0xA0,0xA1,0x60,0x61,0xE0,0xE1, +0x10,0x11,0x90,0x91,0x50,0x51,0xD0,0xD1,0x30,0x31,0xB0,0xB1,0x70,0x71,0xF0,0xF1, +0x08,0x09,0x88,0x89,0x48,0x49,0xC8,0xC9,0x28,0x29,0xA8,0xA9,0x68,0x69,0xE8,0xE9, +0x18,0x19,0x98,0x99,0x58,0x59,0xD8,0xD9,0x38,0x39,0xB8,0xB9,0x78,0x79,0xF8,0xF9, +0x04,0x05,0x84,0x85,0x44,0x45,0xC4,0xC5,0x24,0x25,0xA4,0xA5,0x64,0x65,0xE4,0xE5, +0x14,0x15,0x94,0x95,0x54,0x55,0xD4,0xD5,0x34,0x35,0xB4,0xB5,0x74,0x75,0xF4,0xF5, +0x0C,0x0D,0x8C,0x8D,0x4C,0x4D,0xCC,0xCD,0x2C,0x2D,0xAC,0xAD,0x6C,0x6D,0xEC,0xED, +0x1C,0x1D,0x9C,0x9D,0x5C,0x5D,0xDC,0xDD,0x3C,0x3D,0xBC,0xBD,0x7C,0x7D,0xFC,0xFD, +0x02,0x03,0x82,0x83,0x42,0x43,0xC2,0xC3,0x22,0x23,0xA2,0xA3,0x62,0x63,0xE2,0xE3, +0x12,0x13,0x92,0x93,0x52,0x53,0xD2,0xD3,0x32,0x33,0xB2,0xB3,0x72,0x73,0xF2,0xF3, +0x0A,0x0B,0x8A,0x8B,0x4A,0x4B,0xCA,0xCB,0x2A,0x2B,0xAA,0xAB,0x6A,0x6B,0xEA,0xEB, +0x1A,0x1B,0x9A,0x9B,0x5A,0x5B,0xDA,0xDB,0x3A,0x3B,0xBA,0xBB,0x7A,0x7B,0xFA,0xFB, +0x06,0x07,0x86,0x87,0x46,0x47,0xC6,0xC7,0x26,0x27,0xA6,0xA7,0x66,0x67,0xE6,0xE7, +0x16,0x17,0x96,0x97,0x56,0x57,0xD6,0xD7,0x36,0x37,0xB6,0xB7,0x76,0x77,0xF6,0xF7, +0x0E,0x0F,0x8E,0x8F,0x4E,0x4F,0xCE,0xCF,0x2E,0x2F,0xAE,0xAF,0x6E,0x6F,0xEE,0xEF, +0x1E,0x1F,0x9E,0x9F,0x5E,0x5F,0xDE,0xDF,0x3E,0x3F,0xBE,0xBF,0x7E,0x7F,0xFE,0xFF +} ; +#endif + +void lcdSendCtl(uint8_t val) +{ + register Pio *pioptr ; +// register uint32_t x ; + +#ifdef REVB + pioptr = PIOC ; + pioptr->PIO_CODR = LCD_CS1 ; // Select LCD + PIOA->PIO_CODR = LCD_A0 ; + pioptr->PIO_CODR = LCD_RnW ; // Write + pioptr->PIO_ODSR = val ; +#else + pioptr = PIOC ; + pioptr->PIO_CODR = LCD_CS1 ; // Select LCD + pioptr->PIO_CODR = LCD_A0 ; // Control + pioptr->PIO_CODR = LCD_RnW ; // Write + pioptr->PIO_ODSR = Lcd_lookup[val] ; +#endif + + pioptr->PIO_SODR = LCD_E ; // Start E pulse + // Need a delay here (250nS) + TC0->TC_CHANNEL[0].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger) + while ( TC0->TC_CHANNEL[0].TC_CV < 9 ) // Value depends on MCK/2 (used 18MHz) + { + // Wait + } + pioptr->PIO_CODR = LCD_E ; // End E pulse +#ifdef REVB + PIOA->PIO_SODR = LCD_A0 ; // Data +#else + pioptr->PIO_SODR = LCD_A0 ; // Data +#endif + pioptr->PIO_SODR = LCD_CS1 ; // Deselect LCD +} + +void lcd_init() +{ + register Pio *pioptr ; + // /home/thus/txt/datasheets/lcd/KS0713.pdf + // ~/txt/flieger/ST7565RV17.pdf from http://www.glyn.de/content.asp?wdid=132&sid= + +#ifdef REVB + configure_pins( LCD_A0, PIN_ENABLE | PIN_LOW | PIN_OUTPUT | PIN_PORTA | PIN_NO_PULLUP ) ; + pioptr = PIOC ; + pioptr->PIO_PER = 0x0C0030FFL ; // Enable bits 27,26,13,12,7-0 + pioptr->PIO_CODR = LCD_E | LCD_RnW ; + pioptr->PIO_SODR = LCD_RES | LCD_CS1 ; + pioptr->PIO_OER = 0x0C0030FFL ; // Set bits 27,26,13,12,7-0 output + pioptr->PIO_OWER = 0x000000FFL ; // Allow write to ls 8 bits in ODSR +#else + pioptr = PIOC ; + pioptr->PIO_PER = 0x0C00B0FFL ; // Enable bits 27,26,15,13,12,7-0 + pioptr->PIO_CODR = LCD_E | LCD_RnW | LCD_A0 ; + pioptr->PIO_SODR = LCD_RES | LCD_CS1 ; + pioptr->PIO_OER = 0x0C00B0FFL ; // Set bits 27,26,15,13,12,7-0 output + pioptr->PIO_OWER = 0x000000FFL ; // Allow write to ls 8 bits in ODSR +#endif + + pioptr->PIO_CODR = LCD_RES ; // Reset LCD + TC0->TC_CHANNEL[0].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger) + while ( TC0->TC_CHANNEL[0].TC_CV < 200 ) // > 10us, Value depends on MCK/2 (used 18MHz) + { + // Wait + } + pioptr->PIO_SODR = LCD_RES ; // Remove LCD reset + TC0->TC_CHANNEL[0].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger) + while ( TC0->TC_CHANNEL[0].TC_CV < 27000 ) // 1500us, Value depends on MCK/2 (used 18MHz) + { + // Wait + } + lcdSendCtl(0xe2); //Initialize the internal functions + lcdSendCtl(0xae); //DON = 0: display OFF + lcdSendCtl(0xa1); //ADC = 1: reverse direction(SEG132->SEG1) + lcdSendCtl(0xA6); //REV = 0: non-reverse display + lcdSendCtl(0xA4); //EON = 0: normal display. non-entire + lcdSendCtl(0xA2); // Select LCD bias=0 + lcdSendCtl(0xC0); //SHL = 0: normal direction (COM1->COM64) + lcdSendCtl(0x2F); //Control power circuit operation VC=VR=VF=1 + lcdSendCtl(0x25); //Select int resistance ratio R2 R1 R0 =5 + lcdSendCtl(0x81); //Set reference voltage Mode + lcdSendCtl(0x22); // 24 SV5 SV4 SV3 SV2 SV1 SV0 = 0x18 + lcdSendCtl(0xAF); //DON = 1: display ON + // g_eeGeneral.contrast = 0x22; + +#ifdef REVB + pioptr->PIO_ODR = 0x0000003AL ; // Set bits 1, 3, 4, 5 input + pioptr->PIO_PUER = 0x0000003AL ; // Set bits 1, 3, 4, 5 with pullups + pioptr->PIO_ODSR = 0 ; // Drive D0 low +#else + pioptr->PIO_ODR = 0x0000003CL ; // Set bits 2, 3, 4, 5 input + pioptr->PIO_PUER = 0x0000003CL ; // Set bits 2, 3, 4, 5 with pullups + pioptr->PIO_ODSR = 0 ; // Drive D0 low +#endif +} + +void lcdSetRefVolt(uint8_t val) +{ + register Pio *pioptr ; + pioptr = PIOC ; + + // read the inputs, and lock the LCD lines + lcdInputs = PIOC->PIO_PDSR; // 6 LEFT, 5 RIGHT, 4 DOWN, 3 UP () + lcdLock = 1 ; + + pioptr->PIO_OER = 0x0C00B0FFL ; // Set bits 27,26,15,13,12,7-0 output + + lcdSendCtl(0x81); + if ( val == 0 ) + { + val = 0x22 ; + } + lcdSendCtl(val); + +#ifdef REVB + pioptr->PIO_ODR = 0x0000003AL ; // Set bits 1, 3, 4, 5 input + pioptr->PIO_PUER = 0x0000003AL ; // Set bits 1, 3, 4, 5 with pullups +#else + pioptr->PIO_ODR = 0x0000003CL ; // Set bits 2, 3, 4, 5 input + pioptr->PIO_PUER = 0x0000003CL ; // Set bits 2, 3, 4, 5 with pullups +#endif + + pioptr->PIO_ODSR = lcdInputs; // Drive D0 low + lcdLock = 0 ; +} + +void refreshDisplay() +{ + register Pio *pioptr; + register uint8_t *p = displayBuf; + register uint32_t y; + register uint32_t x; + register uint32_t z; + register uint32_t ebit; +#ifndef REVB + register uint8_t *lookup; + lookup = (uint8_t *) Lcd_lookup; +#endif + + ebit = LCD_E; + +#ifdef REVB + pioptr = PIOA; + pioptr->PIO_PER = 0x00000080; // Enable bit 7 (LCD-A0) + pioptr->PIO_OER = 0x00000080;// Set bit 7 output +#endif + + // read the inputs, and lock the LCD lines + lcdInputs = PIOC->PIO_PDSR; // 6 LEFT, 5 RIGHT, 4 DOWN, 3 UP () + lcdLock = 1 ; + + pioptr = PIOC; +#ifdef REVB + pioptr->PIO_OER = 0x0C0030FFL; // Set bits 27,26,15,13,12,7-0 output +#else + pioptr->PIO_OER = 0x0C00B0FFL; // Set bits 27,26,15,13,12,7-0 output +#endif + for (y = 0; y < 8; y++) { + lcdSendCtl(g_eeGeneral.optrexDisplay ? 0 : 0x04); + lcdSendCtl(0x10); //column addr 0 + lcdSendCtl(y | 0xB0); //page addr y + + pioptr->PIO_CODR = LCD_CS1; // Select LCD + PIOA->PIO_SODR = LCD_A0; // Data + pioptr->PIO_CODR = LCD_RnW; // Write + +#ifdef REVB + x = *p; +#else + x = lookup[*p]; +#endif + for (z = 0; z < DISPLAY_W; z += 1) { + +// The following 7 lines replaces by a lookup table +// x = __RBIT( *p++ ) ; +// x >>= 23 ; +// if ( x & 0x00000100 ) +// { +// x |= 1 ; +// } +// pioptr->PIO_ODSR = x ; + + pioptr->PIO_ODSR = x; + pioptr->PIO_SODR = ebit; // Start E pulse + // Need a delay here (250nS) + p += 1; +#ifdef REVB + x = *p; +#else + x = lookup[*p]; +#endif +// TC0->TC_CHANNEL[0].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger) +// while ( TC0->TC_CHANNEL[0].TC_CV < 3 ) // Value depends on MCK/2 (used 6MHz) +// { +// // Wait +// } + pioptr->PIO_CODR = ebit; // End E pulse + } + pioptr->PIO_SODR = LCD_CS1; // Deselect LCD + } + + pioptr->PIO_ODSR = 0xFF ; // Drive lines high +#ifdef REVB + pioptr->PIO_PUER = 0x0000003AL ; // Set bits 1, 3, 4, 5 with pullups + pioptr->PIO_ODR = 0x0000003AL ; // Set bits 1, 3, 4, 5 input +#else + pioptr->PIO_PUER = 0x0000003CL ; // Set bits 2, 3, 4, 5 with pullups + pioptr->PIO_ODR = 0x0000003CL ; // Set bits 2, 3, 4, 5 input +#endif + + pioptr->PIO_ODSR = lcdInputs; // Drive D0 low + lcdLock = 0; +} diff --git a/src/stock/lcd_driver.cpp b/src/stock/lcd_driver.cpp new file mode 100644 index 000000000..1ad10c03f --- /dev/null +++ b/src/stock/lcd_driver.cpp @@ -0,0 +1,128 @@ +/* + * Authors (alphabetical order) + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * open9x is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "open9x.h" + +#define delay_1us() _delay_us(1) +void delay_1_5us(int ms) +{ + for(int i=0; iSEG1) + lcdSendCtl(0xA6); //REV = 0: non-reverse display + lcdSendCtl(0xA4); //EON = 0: normal display. non-entire + lcdSendCtl(0xA2); // Select LCD bias=0 + lcdSendCtl(0xC0); //SHL = 0: normal direction (COM1->COM64) + lcdSendCtl(0x2F); //Control power circuit operation VC=VR=VF=1 + lcdSendCtl(0x25); //Select int resistance ratio R2 R1 R0 =5 + lcdSendCtl(0x81); //Set reference voltage Mode + lcdSendCtl(0x22); // 24 SV5 SV4 SV3 SV2 SV1 SV0 = 0x18 + lcdSendCtl(0xAF); //DON = 1: display ON + g_eeGeneral.contrast = 0x22; + LCD_UNLOCK(); +} + +void lcdSetRefVolt(uint8_t val) +{ + LCD_LOCK(); + lcdSendCtl(0x81); + lcdSendCtl(val); + LCD_UNLOCK(); +} + +void refreshDisplay() +{ + LCD_LOCK(); + uint8_t *p=displayBuf; + for(uint8_t y=0; y < 8; y++) { + lcdSendCtl(0x04); + lcdSendCtl(0x10); //column addr 0 + lcdSendCtl( y | 0xB0); //page addr y + PORTC_LCD_CTRL &= ~(1<0; --x) { + PORTA_LCD_DAT = *p++; + PORTC_LCD_CTRL |= (1<weight=-100; md->swtch=DSW_SWC; md->mltpx=MLTPX_REP; + md=setDest(ICC(STK_THR), MIXSRC_MAX); md->weight=-100; md->swtch=DSW(SW_SWC); md->mltpx=MLTPX_REP; md=setDest(13, MIXSRC_CH11+3); md->weight= 100; - md=setDest(13, MIXSRC_MAX); md->weight=-100; md->swtch=DSW_SWB; md->mltpx=MLTPX_REP; - md=setDest(13, MIXSRC_MAX); md->weight= 100; md->swtch=DSW_THR; md->mltpx=MLTPX_REP; + md=setDest(13, MIXSRC_MAX); md->weight=-100; md->swtch=DSW(SW_SWB); md->mltpx=MLTPX_REP; + md=setDest(13, MIXSRC_MAX); md->weight= 100; md->swtch=DSW(SW_THR); md->mltpx=MLTPX_REP; setSwitch(11, CS_VNEG, STK_THR, -99); setSwitch(12, CS_VPOS, 38, 0); break; @@ -194,15 +195,15 @@ void applyTemplate(uint8_t idx) md=setDest(ICC(STK_ELE), MIXSRC_CH9); md->weight=-100; md=setDest(ICC(STK_ELE), MIXSRC_CH11); md->carryTrim=TRIM_OFF; - md=setDest(ICC(STK_THR), MIXSRC_Thr); md->swtch=DSW_ID0; md->curveMode=MODE_CURVE; md->curveParam=CV(1); md->carryTrim=TRIM_OFF; - md=setDest(ICC(STK_THR), MIXSRC_Thr); md->swtch=DSW_ID1; md->curveMode=MODE_CURVE; md->curveParam=CV(2); md->carryTrim=TRIM_OFF; - md=setDest(ICC(STK_THR), MIXSRC_Thr); md->weight= 110; md->swtch=DSW_ID2; md->curveMode=MODE_CURVE; md->curveParam=CV(2); md->carryTrim=TRIM_OFF; - md=setDest(ICC(STK_THR), MIXSRC_MAX); md->weight=-125; md->swtch=DSW_THR; md->mltpx=MLTPX_REP; md->carryTrim=TRIM_OFF; + md=setDest(ICC(STK_THR), MIXSRC_Thr); md->swtch=DSW(SW_ID0); md->curveMode=MODE_CURVE; md->curveParam=CV(1); md->carryTrim=TRIM_OFF; + md=setDest(ICC(STK_THR), MIXSRC_Thr); md->swtch=DSW(SW_ID1); md->curveMode=MODE_CURVE; md->curveParam=CV(2); md->carryTrim=TRIM_OFF; + md=setDest(ICC(STK_THR), MIXSRC_Thr); md->weight= 110; md->swtch=DSW(SW_ID2); md->curveMode=MODE_CURVE; md->curveParam=CV(2); md->carryTrim=TRIM_OFF; + md=setDest(ICC(STK_THR), MIXSRC_MAX); md->weight=-125; md->swtch=DSW(SW_THR); md->mltpx=MLTPX_REP; md->carryTrim=TRIM_OFF; md=setDest(ICC(STK_RUD), MIXSRC_Rud); - md=setDest(4, MIXSRC_MAX); md->weight= 50; md->swtch=-DSW_GEA; md->carryTrim=TRIM_OFF; - md=setDest(4, MIXSRC_MAX); md->weight=-50; md->swtch= DSW_GEA; md->carryTrim=TRIM_OFF; + md=setDest(4, MIXSRC_MAX); md->weight= 50; md->swtch=-DSW(SW_GEA); md->carryTrim=TRIM_OFF; + md=setDest(4, MIXSRC_MAX); md->weight=-50; md->swtch= DSW(SW_GEA); md->carryTrim=TRIM_OFF; md=setDest(4, STK_P3); md->weight= 40; md->carryTrim=TRIM_OFF; md=setDest(5, MIXSRC_CH9); md->weight= -50; @@ -211,10 +212,10 @@ void applyTemplate(uint8_t idx) md=setDest(8, MIXSRC_Ele); md->weight= 60; md=setDest(9, MIXSRC_Ail); md->weight=-52; - md=setDest(10, MIXSRC_Thr); md->weight= 70; md->swtch=DSW_ID0; md->curveMode=MODE_CURVE; md->curveParam=CV(3); md->carryTrim=TRIM_OFF; - md=setDest(10, MIXSRC_Thr); md->weight= 70; md->swtch=DSW_ID1; md->curveMode=MODE_CURVE; md->curveParam=CV(4); md->carryTrim=TRIM_OFF; - md=setDest(10, MIXSRC_Thr); md->weight= 70; md->swtch=DSW_ID2; md->curveMode=MODE_CURVE; md->curveParam=CV(4); md->carryTrim=TRIM_OFF; - md=setDest(10, MIXSRC_Thr); md->swtch=DSW_THR; md->curveMode=MODE_CURVE; md->curveParam=CV(5); md->carryTrim=TRIM_OFF; md->mltpx=MLTPX_REP; + md=setDest(10, MIXSRC_Thr); md->weight= 70; md->swtch=DSW(SW_ID0); md->curveMode=MODE_CURVE; md->curveParam=CV(3); md->carryTrim=TRIM_OFF; + md=setDest(10, MIXSRC_Thr); md->weight= 70; md->swtch=DSW(SW_ID1); md->curveMode=MODE_CURVE; md->curveParam=CV(4); md->carryTrim=TRIM_OFF; + md=setDest(10, MIXSRC_Thr); md->weight= 70; md->swtch=DSW(SW_ID2); md->curveMode=MODE_CURVE; md->curveParam=CV(4); md->carryTrim=TRIM_OFF; + md=setDest(10, MIXSRC_Thr); md->swtch=DSW(SW_THR); md->curveMode=MODE_CURVE; md->curveParam=CV(5); md->carryTrim=TRIM_OFF; md->mltpx=MLTPX_REP; //Set up Curves setCurve(CURVE5(1), heli_ar1); diff --git a/src/translations.cpp b/src/translations.cpp index 3cd772e86..5514e9bfb 100644 --- a/src/translations.cpp +++ b/src/translations.cpp @@ -105,6 +105,7 @@ const pm_char STR_COPYINGMODEL[] PROGMEM = TR_COPYINGMODEL; const pm_char STR_MOVINGMODEL[] PROGMEM = TR_MOVINGMODEL; const pm_char STR_LOADINGMODEL[] PROGMEM = TR_LOADINGMODEL; const pm_char STR_NAME[] PROGMEM = TR_NAME; +const pm_char STR_BITMAP[] PROGMEM = TR_BITMAP; const pm_char STR_TIMER[] PROGMEM = TR_TIMER; const pm_char STR_ELIMITS[] PROGMEM = TR_ELIMITS; const pm_char STR_ETRIMS[] PROGMEM = TR_ETRIMS; @@ -350,6 +351,7 @@ const pm_char STR_SD_CARD[] PROGMEM = TR_SD_CARD; const pm_char STR_SDHC_CARD[] PROGMEM = TR_SDHC_CARD; const pm_char STR_NO_SOUNDS_ON_SD[] PROGMEM = TR_NO_SOUNDS_ON_SD; const pm_char STR_NO_MODELS_ON_SD[] PROGMEM = TR_NO_MODELS_ON_SD; +const pm_char STR_NO_BITMAPS_ON_SD[] PROGMEM = TR_NO_BITMAPS_ON_SD; const pm_char STR_PLAY_FILE[] PROGMEM = TR_PLAY_FILE; const pm_char STR_DELETE_FILE[] PROGMEM = TR_DELETE_FILE; const pm_char STR_COPY_FILE[] PROGMEM = TR_COPY_FILE; @@ -407,6 +409,10 @@ const pm_uchar font_10x14[] PROGMEM = { }; #if defined(PCBX9D) +const pm_uchar font_4x6[] PROGMEM = { +#include "font_small.lbm" +}; + const pm_uchar font_8x10[] PROGMEM = { #include "font_midsize.lbm" }; diff --git a/src/translations.h b/src/translations.h index 0414bc9a8..c26d1b479 100644 --- a/src/translations.h +++ b/src/translations.h @@ -222,6 +222,7 @@ extern const pm_char STR_COPYINGMODEL[]; extern const pm_char STR_MOVINGMODEL[]; extern const pm_char STR_LOADINGMODEL[]; extern const pm_char STR_NAME[]; +extern const pm_char STR_BITMAP[]; extern const pm_char STR_TIMER[]; extern const pm_char STR_ELIMITS[]; extern const pm_char STR_ETRIMS[]; @@ -422,6 +423,7 @@ extern const pm_uchar font_5x7[]; extern const pm_uchar font_10x14[]; #if defined(PCBX9D) +extern const pm_uchar font_4x6[]; extern const pm_uchar font_8x10[]; extern const pm_uchar font_5x7_extra[]; extern const pm_uchar font_10x14_extra[]; @@ -452,6 +454,7 @@ extern const pm_char STR_SD_CARD[]; extern const pm_char STR_SDHC_CARD[]; extern const pm_char STR_NO_SOUNDS_ON_SD[]; extern const pm_char STR_NO_MODELS_ON_SD[]; +extern const pm_char STR_NO_BITMAPS_ON_SD[]; extern const pm_char STR_PLAY_FILE[]; extern const pm_char STR_DELETE_FILE[]; extern const pm_char STR_COPY_FILE[]; diff --git a/src/translations/en.h b/src/translations/en.h index 701b26006..cdcf1f759 100644 --- a/src/translations/en.h +++ b/src/translations/en.h @@ -253,6 +253,7 @@ #define TR_MOVINGMODEL "Moving model..." #define TR_LOADINGMODEL "Loading model..." #define TR_NAME "Name" +#define TR_BITMAP "Bitmap" #define TR_TIMER "Timer" #define TR_ELIMITS "E.Limits" #define TR_ETRIMS "E.Trims" @@ -450,6 +451,7 @@ #define TR_SDHC_CARD "SD-HC CARD" #define TR_NO_SOUNDS_ON_SD "No Sounds on SD" #define TR_NO_MODELS_ON_SD "No Models on SD" +#define TR_NO_BITMAPS_ON_SD "No Bitmaps on SD" #define TR_PLAY_FILE "Play" #define TR_DELETE_FILE "Delete" #define TR_COPY_FILE "Copy" diff --git a/util/img2lbm.py b/util/img2lbm.py index 04280f7b0..f4bf21353 100644 --- a/util/img2lbm.py +++ b/util/img2lbm.py @@ -21,6 +21,15 @@ if sys.argv[3] == "img": value += 1 << z f.write("0x%02x," % value) f.write("\n") +elif sys.argv[3] == "4x6": + for y in range(0, height, 7): + for x in range(width): + value = 0 + for z in range(7): + if image.pixel(x, y+z) == Qt.qRgb(0, 0, 0): + value += 1 << z + f.write("0x%02x," % value) + f.write("\n") elif sys.argv[3] == "5x7": for y in range(0, height, 8): for x in range(width):