1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-15 04:15:26 +03:00

Taranis LCD functions refactoring

This commit is contained in:
bsongis 2014-07-04 11:46:34 +02:00
parent 83614359aa
commit 4ffb9f69c6
17 changed files with 785 additions and 610 deletions

View file

@ -76,7 +76,8 @@ namespace Open9xGruvin9x {
#include "radio/src/gui/view_main.cpp"
#include "radio/src/gui/view_statistics.cpp"
#include "radio/src/gui/view_telemetry.cpp"
#include "radio/src/lcd.cpp"
#include "radio/src/lcd_common.cpp"
#include "radio/src/lcd_default.cpp"
#include "radio/src/keys.cpp"
#include "radio/src/targets/simu/simpgmspace.cpp"
#include "radio/src/templates.cpp"

View file

@ -77,7 +77,8 @@ namespace OpenTxM128 {
#include "radio/src/gui/view_main.cpp"
#include "radio/src/gui/view_statistics.cpp"
#include "radio/src/gui/view_telemetry.cpp"
#include "radio/src/lcd.cpp"
#include "radio/src/lcd_common.cpp"
#include "radio/src/lcd_default.cpp"
#include "radio/src/keys.cpp"
#include "radio/src/targets/simu/simpgmspace.cpp"
#include "radio/src/templates.cpp"

View file

@ -81,7 +81,8 @@ namespace OpenTxM64 {
#include "radio/src/gui/view_main.cpp"
#include "radio/src/gui/view_statistics.cpp"
#include "radio/src/gui/view_telemetry.cpp"
#include "radio/src/lcd.cpp"
#include "radio/src/lcd_common.cpp"
#include "radio/src/lcd_default.cpp"
#include "radio/src/keys.cpp"
#include "radio/src/targets/simu/simpgmspace.cpp"
#include "radio/src/telemetry/frsky.cpp"

View file

@ -92,7 +92,8 @@ namespace Open9xSky9x {
#include "radio/src/gui/view_telemetry.cpp"
#include "radio/src/gui/view_about.cpp"
#include "radio/src/gui/view_text.cpp"
#include "radio/src/lcd.cpp"
#include "radio/src/lcd_common.cpp"
#include "radio/src/lcd_default.cpp"
#include "radio/src/logs.cpp"
#include "radio/src/targets/sky9x/keys_driver.cpp"
#include "radio/src/keys.cpp"

View file

@ -99,7 +99,8 @@ inline int geteepromsize() {
#include "radio/src/gui/view_telemetry.cpp"
#include "radio/src/gui/view_text.cpp"
#include "radio/src/gui/view_about.cpp"
#include "radio/src/lcd.cpp"
#include "radio/src/lcd_common.cpp"
#include "radio/src/lcd_taranis.cpp"
#include "radio/src/logs.cpp"
#include "radio/src/rtc.cpp"
#include "radio/src/targets/taranis/keys_driver.cpp"

View file

@ -122,18 +122,18 @@ class lcdWidget : public QWidget {
}
unsigned int previousDepth = 0xFF;
const int planSize = (lcdWidth * ((lcdHeight+7) / 8));
for (int y=0; y<lcdHeight; y++) {
unsigned int idx = (y/8)*lcdWidth;
unsigned int idx = (y*lcdDepth/8)*lcdWidth;
unsigned int mask = (1 << (y%8));
for (int x=0; x<lcdWidth; x++, idx++) {
if (lcdDepth == 1) {
if (lcdBuf[idx] & mask)
if (lcdBuf[idx] & mask) {
p.drawRect(2*x, 2*y, 1, 1);
}
}
else {
unsigned int z = (((lcdBuf[idx] & mask) ? 0x1 : 0) + ((lcdBuf[planSize+idx] & mask) ? 0x2 : 0) + ((lcdBuf[2*planSize+idx] & mask) ? 0x4 : 0) + ((lcdBuf[3*planSize+idx] & mask) ? 0x8 : 0));
unsigned int z = (y & 1) ? (lcdBuf[idx] >> 4) : (lcdBuf[idx] & 0x0F);
if (z) {
if (z != previousDepth) {
previousDepth = z;

View file

@ -329,6 +329,7 @@ ifeq ($(PCB), $(filter $(PCB), STD 9X 9XR))
BOARDSRC = targets/stock/board_stock.cpp
EXTRABOARDSRC = targets/stock/lcd_driver.cpp targets/common_avr/telemetry_driver.cpp
EEPROMSRC = eeprom_common.cpp eeprom_rlc.cpp
LCDSRC = lcd_common.cpp lcd_default.cpp
PULSESSRC = pulses/pulses_avr.cpp
ifeq ($(PCB), 9XR)
@ -392,6 +393,7 @@ ifeq ($(PCB), $(filter $(PCB), STD128 9X128 9XR128))
BOARDSRC = targets/stock/board_stock.cpp
EXTRABOARDSRC = targets/stock/lcd_driver.cpp targets/common_avr/telemetry_driver.cpp
EEPROMSRC = eeprom_common.cpp eeprom_rlc.cpp
LCDSRC = lcd_common.cpp lcd_default.cpp
PULSESSRC = pulses/pulses_avr.cpp
ifeq ($(PCB), 9XR128)
@ -451,6 +453,7 @@ ifeq ($(PCB), $(filter $(PCB), 9X2561))
BOARDSRC = targets/stock/board_stock.cpp
EXTRABOARDSRC = targets/stock/lcd_driver.cpp targets/common_avr/telemetry_driver.cpp
EEPROMSRC = eeprom_common.cpp eeprom_rlc.cpp
LCDSRC = lcd_common.cpp lcd_default.cpp
PULSESSRC = pulses/pulses_avr.cpp
ifeq ($(PCB), 9XR2561)
@ -511,6 +514,7 @@ ifeq ($(PCB), GRUVIN9X)
BOARDSRC = targets/gruvin9x/board_gruvin9x.cpp
EXTRABOARDSRC = targets/stock/lcd_driver.cpp targets/common_avr/telemetry_driver.cpp
EEPROMSRC = eeprom_common.cpp eeprom_rlc.cpp
LCDSRC = lcd_common.cpp lcd_default.cpp
PULSESSRC = pulses/pulses_avr.cpp
CPPSRC += audio_avr.cpp haptic.cpp
@ -549,6 +553,7 @@ ifeq ($(PCB), MEGA2560)
BOARDSRC = targets/mega2560/board_mega2560.cpp
EXTRABOARDSRC = targets/mega2560/lcd_driver_ST7565R.cpp targets/common_avr/telemetry_driver.cpp
EEPROMSRC = eeprom_common.cpp eeprom_rlc.cpp
LCDSRC = lcd_common.cpp lcd_default.cpp
PULSESSRC = pulses/pulses_avr.cpp
CPPSRC += audio_avr.cpp
@ -605,6 +610,7 @@ ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO))
SRC += targets/sky9x/usb/common/core/USBEndpointDescriptor.c targets/sky9x/usb/common/core/USBGenericRequest.c targets/sky9x/usb/common/core/USBFeatureRequest.c targets/sky9x/usb/common/core/USBInterfaceRequest.c targets/sky9x/usb/common/core/USBGetDescriptorRequest.c targets/sky9x/usb/common/core/USBSetAddressRequest.c targets/sky9x/usb/common/core/USBSetConfigurationRequest.c targets/sky9x/usb/common/core/USBConfigurationDescriptor.c targets/sky9x/usb/common/core/USBGenericDescriptor.c
SRC += targets/sky9x/MEDSdcard.c
EEPROMSRC = eeprom_common.cpp eeprom_raw.cpp eeprom_conversions.cpp
LCDSRC = lcd_common.cpp lcd_default.cpp
PULSESSRC = pulses/pulses_arm.cpp pulses/ppm_arm.cpp pulses/pxx_arm.cpp pulses/dsm2_arm.cpp
CPPSRC += audio_arm.cpp haptic.cpp gui/view_about.cpp gui/view_text.cpp
CPPSRC += targets/sky9x/telemetry_driver.cpp targets/sky9x/second_serial_driver.cpp targets/sky9x/pwr_driver.cpp targets/sky9x/adc_driver.cpp targets/sky9x/eeprom_driver.cpp targets/sky9x/pulses_driver.cpp targets/sky9x/keys_driver.cpp targets/sky9x/audio_driver.cpp targets/sky9x/buzzer_driver.cpp targets/sky9x/haptic_driver.cpp targets/sky9x/sdcard_driver.cpp targets/sky9x/massstorage.cpp
@ -674,6 +680,7 @@ ifeq ($(PCB), TARANIS)
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 += targets/taranis/pwr_driver.c targets/taranis/usb_driver.c
EEPROMSRC = eeprom_common.cpp eeprom_rlc.cpp eeprom_conversions.cpp
LCDSRC = lcd_common.cpp lcd_taranis.cpp
PULSESSRC = pulses/pulses_arm.cpp pulses/ppm_arm.cpp pulses/pxx_arm.cpp
CPPSRC += audio_arm.cpp
CPPSRC += targets/taranis/pulses_driver.cpp targets/taranis/keys_driver.cpp targets/taranis/adc_driver.cpp targets/taranis/trainer_driver.cpp targets/taranis/audio_driver.cpp targets/taranis/uart3_driver.cpp targets/taranis/telemetry_driver.cpp
@ -790,7 +797,7 @@ else
TTS_SRC = $(shell sh -c "if test -f $(STD_TTS_SRC); then echo $(STD_TTS_SRC); else echo translations/tts_en.cpp; fi")
endif
CPPSRC += opentx.cpp strhelpers.cpp $(PULSESSRC) switches.cpp curves.cpp mixer.cpp stamp.cpp gui/menus.cpp gui/menu_model.cpp gui/menu_general.cpp gui/view_main.cpp gui/view_statistics.cpp $(EEPROMSRC) lcd.cpp keys.cpp maths.cpp translations.cpp fonts.cpp $(TTS_SRC)
CPPSRC += opentx.cpp strhelpers.cpp $(PULSESSRC) switches.cpp curves.cpp mixer.cpp stamp.cpp gui/menus.cpp gui/menu_model.cpp gui/menu_general.cpp gui/view_main.cpp gui/view_statistics.cpp $(EEPROMSRC) $(LCDSRC) keys.cpp maths.cpp translations.cpp fonts.cpp $(TTS_SRC)
# Debugging format.
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.

View file

@ -159,23 +159,19 @@ const pm_char * bmpLoad(uint8_t *bmp, const char *filename, const xcoord_t width
switch (depth) {
case 1:
n = w/8;
for (uint32_t i=0; i<h; i+=8) {
result = f_read(&bmpFile, buf, n*8, &read);
if (result != FR_OK || read != n*8) {
for (uint32_t i=0; i<h; i+=2) {
result = f_read(&bmpFile, buf, n*2, &read);
if (result != FR_OK || read != n*2) {
f_close(&bmpFile);
return SDCARD_ERROR(result);
}
uint8_t * dst = dest + 4*((h-i-8)/8 * w);
for (uint32_t j=0; j<n; j++) {
#define PUSH_4BYTES(x) *dst = *(dst+1) = *(dst+2) = *(dst+3) = (x); dst += 4
PUSH_4BYTES(~(((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)));
PUSH_4BYTES(~((((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)));
PUSH_4BYTES(~((((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)));
PUSH_4BYTES(~((((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)));
PUSH_4BYTES(~((((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)));
PUSH_4BYTES(~((((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)));
PUSH_4BYTES(~((((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)));
PUSH_4BYTES(~((((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)));
for (uint32_t j=0; j<w; j++) {
uint8_t * dst = dest + (h-i-2)/2 * w + j;
if (!(buf[j/8] & (1<<(7-(j%8)))))
*dst |= 0xF0;
if (!(buf[n+j/8] & (1<<(7-(j%8)))))
*dst |= 0x0F;
}
}
break;
@ -187,19 +183,20 @@ const pm_char * bmpLoad(uint8_t *bmp, const char *filename, const xcoord_t width
f_close(&bmpFile);
return SDCARD_ERROR(result);
}
uint8_t mask = 1 << (i%8);
for (uint32_t j=0; j<w/2; j++) {
uint8_t * dst = dest + (i/8)*w*4 + j*8;
uint8_t val = palette[(buf[j] >> 4) & 0x0F];
*(dst+0) = ((*(dst+0)) & (~mask)) + ((val & 0x1) ? 0 : mask);
*(dst+1) = ((*(dst+1)) & (~mask)) + ((val & 0x2) ? 0 : mask);
*(dst+2) = ((*(dst+2)) & (~mask)) + ((val & 0x4) ? 0 : mask);
*(dst+3) = ((*(dst+3)) & (~mask)) + ((val & 0x8) ? 0 : mask);
val = palette[buf[j] & 0x0F];
*(dst+4) = ((*(dst+4)) & (~mask)) + ((val & 0x1) ? 0 : mask);
*(dst+5) = ((*(dst+5)) & (~mask)) + ((val & 0x2) ? 0 : mask);
*(dst+6) = ((*(dst+6)) & (~mask)) + ((val & 0x4) ? 0 : mask);
*(dst+7) = ((*(dst+7)) & (~mask)) + ((val & 0x8) ? 0 : mask);
uint8_t * dst = dest + (i/2)*w + j*2;
if (i & 1) {
uint8_t val = palette[(buf[j] >> 4) & 0x0F] << 4;
*dst |= val ^ 0xF0;
val = palette[buf[j] & 0x0F] << 4;
*(dst+1) |= val ^ 0xF0;
}
else {
uint8_t val = palette[(buf[j] >> 4) & 0x0F];
*dst |= val ^ 0x0F;
val = palette[buf[j] & 0x0F];
*(dst+1) |= val ^ 0x0F;
}
}
}
break;
@ -212,33 +209,3 @@ const pm_char * bmpLoad(uint8_t *bmp, const char *filename, const xcoord_t width
f_close(&bmpFile);
return 0;
}
void lcd_bmp(xcoord_t x, uint8_t y, const pm_uchar * img, uint8_t offset, uint8_t width)
{
const pm_uchar *q = img;
#if LCD_W >= 260
xcoord_t w = pgm_read_byte(q++);
if (w == 255) w += pgm_read_byte(q++);
#else
uint8_t w = pgm_read_byte(q++);
#endif
if (!width) width = w;
uint8_t hb = (pgm_read_byte(q++)+7)/8;
q += 4*offset;
for (uint8_t yb = 0; yb < hb; yb++) {
uint8_t *p = &displayBuf[ (y / 8 + yb) * LCD_W + x ];
for (xcoord_t i=0; i<width; i++) {
for (uint8_t plan=0; plan<4; plan++) {
uint8_t b = pgm_read_byte(q++);
uint8_t ym8 = (y & 0x07);
uint8_t *pp = p + plan*DISPLAY_PLAN_SIZE;
LCD_BYTE_FILTER_PLAN(pp, ~(0xff << ym8), b << ym8);
if (ym8) {
uint8_t *r = pp + LCD_W;
LCD_BYTE_FILTER_PLAN(r, ~(0xff >> (8-ym8)), b >> (8-ym8));
}
}
p++;
}
}
}

View file

@ -168,7 +168,8 @@ CPPSRC = ../targets/taranis/lcd_driver.cpp \
../targets/taranis/diskio.cpp \
../targets/taranis/usbd_usr.cpp \
../targets/taranis/usbd_storage_msd.cpp \
../lcd.cpp \
../lcd_common.cpp \
../lcd_taranis.cpp \
../keys.cpp \
../fonts.cpp \
../strhelpers.cpp \

View file

@ -143,15 +143,18 @@
#define DISPLAY_PLAN_SIZE (LCD_W*((LCD_H+7)/8))
#if defined(PCBTARANIS)
#define DISPLAY_BUF_SIZE (4*DISPLAY_PLAN_SIZE)
#define DISPLAY_BUF_SIZE (4*DISPLAY_PLAN_SIZE)
#else
#define DISPLAY_BUF_SIZE DISPLAY_PLAN_SIZE
#define DISPLAY_BUF_SIZE DISPLAY_PLAN_SIZE
#endif
extern uint8_t displayBuf[DISPLAY_BUF_SIZE];
extern uint8_t lcdLastPos;
extern uint8_t lcdNextPos;
#define DISPLAY_END (displayBuf + DISPLAY_BUF_SIZE)
#define ASSERT_IN_DISPLAY(p) assert((p) >= displayBuf && (p) < DISPLAY_END)
#if defined(PCBSTD) && defined(VOICE)
extern volatile uint8_t LcdLock ;
#endif
@ -285,24 +288,6 @@ void lcdRefresh();
#define LCD_LOCKED() 0
#endif
#define LCD_BYTE_FILTER_PLAN(p, keep, add) *(p) = (*(p) & (keep)) | (add)
#if defined(PCBTARANIS)
#define LCD_BYTE_FILTER(p, keep, add) \
do { \
if (!(flags & GREY(1))) \
LCD_BYTE_FILTER_PLAN(p, keep, add); \
if (!(flags & GREY(2))) \
LCD_BYTE_FILTER_PLAN((p+DISPLAY_PLAN_SIZE), keep, add); \
if (!(flags & GREY(4))) \
LCD_BYTE_FILTER_PLAN((p+2*DISPLAY_PLAN_SIZE), keep, add); \
if (!(flags & GREY(8))) \
LCD_BYTE_FILTER_PLAN((p+3*DISPLAY_PLAN_SIZE), keep, add); \
} while (0)
#else
#define LCD_BYTE_FILTER(p, keep, add) LCD_BYTE_FILTER_PLAN(p, keep, add)
#endif
char * strAppend(char * dest, const char * source);
char * strAppendDate(char * str, bool time=false);

View file

@ -37,8 +37,6 @@
#include "opentx.h"
uint8_t displayBuf[DISPLAY_BUF_SIZE];
#define DISPLAY_END (displayBuf+DISPLAY_PLAN_SIZE)
#define ASSERT_IN_DISPLAY(p) assert((p) >= displayBuf && (p) < DISPLAY_END)
#if defined(LUA)
bool lcd_locked = false;
@ -53,111 +51,7 @@ uint8_t lcdLastPos;
uint8_t lcdNextPos;
#if defined(CPUARM)
void lcdPutPattern(xcoord_t x, uint8_t y, const uint8_t * pattern, uint8_t width, uint8_t height, LcdFlags flags)
{
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
uint8_t *end = &displayBuf[ y / 8 * LCD_W + LCD_W ];
bool blink = false;
bool inv = false;
if (flags & BLINK) {
if (BLINK_ON_PHASE) {
if (flags & INVERS)
inv = true;
else {
blink = true;
}
}
}
else if (flags & INVERS) {
inv = true;
}
// we need to work on the previous byte when INVERS
p--;
for (int8_t i=0; i<width+2 && p<end; i++) {
uint8_t lines = (height+7)/8;
assert(lines <= 5);
uint8_t b[5] = { 0 };
if (i==0) {
if (x==0 || !inv) {
lcdNextPos++;
p++;
continue;
}
}
else if (i<=width) {
uint8_t skip = true;
for (uint8_t j=0; j<lines; j++) {
b[j] = pgm_read_byte(pattern++); /*top byte*/
if (b[j] != 0xff) {
skip = false;
}
}
if (skip) {
if (flags & FIXEDWIDTH) {
for (uint8_t j=0; j<lines; j++) {
b[j] = 0;
}
}
else {
continue;
}
}
if ((flags & CONDENSED) && i==2) {
/*condense the letter by skipping column 3 */
continue;
}
}
const uint8_t ym8 = (y & 0x07);
const uint8_t keepref = (1 << ((height&0x07)+1)) - 1;
uint8_t * dest = p;
for (uint8_t j=0; j<lines+1; j++) {
if (dest < DISPLAY_END) {
uint8_t b1=0, b2=0, keep=0;
if (j>0) {
b1 = b[j-1] >> (8-ym8);
}
else {
keep = ~(keepref << ym8);
}
if (j<lines) {
if (inv) {
b[j] = ~b[j];
if (j==lines-1) {
if (height >= 10)
b[j] &= 1 + (keepref << 1);
else
b[j] &= keepref;
}
}
b2 = b[j] << ym8;
}
else {
keep = ~(keepref >> (8-ym8));
}
if (!blink) {
LCD_BYTE_FILTER(dest, keep, b1|b2);
}
dest += LCD_W;
}
}
if (inv && height<8) {
if (ym8)
lcd_mask(p, 0x01 << (ym8-1), FORCE);
else if (y) {
ASSERT_IN_DISPLAY(p - LCD_W);
lcd_mask(p - LCD_W, 0x80, FORCE);
}
}
p++;
lcdNextPos++;
}
}
void lcdPutPattern(xcoord_t x, uint8_t y, const uint8_t * pattern, uint8_t width, uint8_t height, LcdFlags flags);
void lcd_putcAtt(xcoord_t x, uint8_t y, const unsigned char c, LcdFlags flags)
{
#if !defined(BOOT)
@ -192,7 +86,7 @@ void lcd_putcAtt(xcoord_t x, uint8_t y, const unsigned char c, LcdFlags flags)
/* each letter consists of ten top bytes followed by
* by ten bottom bytes (20 bytes per * char) */
q = &font_10x14[((uint16_t)c_remapped)*20];
lcdPutPattern(x, y, q, 10, 14, flags);
lcdPutPattern(x, y, q, 10, 16, flags);
}
else if (flags & XXLSIZE) {
q = &font_22x38_num[((uint16_t)c-'0'+5)*110];
@ -200,7 +94,7 @@ void lcd_putcAtt(xcoord_t x, uint8_t y, const unsigned char c, LcdFlags flags)
}
else if (flags & MIDSIZE) {
q = &font_8x10[((uint16_t)c-0x20)*16];
lcdPutPattern(x, y, q, 8, 10, flags);
lcdPutPattern(x, y, q, 8, 12, flags);
}
else if (flags & SMLSIZE) {
q = (c < 0xc0 ? &font_4x6[(c-0x20)*5] : &font_4x6_extra[(c-0xc0)*5]);
@ -220,156 +114,6 @@ void lcd_putcAtt(xcoord_t x, uint8_t y, const unsigned char c, LcdFlags flags)
lcdPutPattern(x, y, q, 5, 7, flags);
}
}
#else
void lcd_putcAtt(xcoord_t x, uint8_t y, const unsigned char c, LcdFlags flags)
{
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
const pm_uchar *q = &font_5x7[(c-0x20)*5];
lcdNextPos = x-1;
p--;
bool inv = false;
if (flags & BLINK) {
if (BLINK_ON_PHASE) {
if (flags & INVERS)
inv = true;
else {
return;
}
}
}
else if (flags & INVERS) {
inv = true;
}
unsigned char c_remapped = 0;
#if defined(BOLD_SPECIFIC_FONT)
if (flags & (DBLSIZE+BOLD)) {
#else
if (flags & DBLSIZE) {
#endif
// To save space only some DBLSIZE and BOLD chars are available
// c has to be remapped. All non existing chars mapped to 0 (space)
if (c>=',' && c<=':')
c_remapped = c - ',' + 1;
else if (c>='A' && c<='Z')
c_remapped = c - 'A' + 16;
else if (c>='a' && c<='z')
c_remapped = c - 'a' + 42;
else if (c=='_')
c_remapped = 4;
#if defined(BOLD_SPECIFIC_FONT)
else if (c!=' ')
flags &= ~BOLD;
#endif
#if defined(BOLD_SPECIFIC_FONT)
}
if (flags & DBLSIZE) {
#endif
/* each letter consists of ten top bytes followed by
* by ten bottom bytes (20 bytes per * char) */
q = &font_10x14[((uint16_t)c_remapped)*20];
for (int8_t i=0; i<=11; i++) {
uint8_t b1=0, b2=0;
if (!i) {
if (!x || !inv) {
lcdNextPos++;
p++;
continue;
}
}
else if (i <= 10) {
b1 = pgm_read_byte(q++); /*top byte*/
b2 = pgm_read_byte(q++);
}
if ((b1 & b2) == 0xff) continue;
if (inv) {
b1 = ~b1;
b2 = ~b2;
}
if(&p[LCD_W+1] < DISPLAY_END) {
ASSERT_IN_DISPLAY(p);
ASSERT_IN_DISPLAY(p+LCD_W);
LCD_BYTE_FILTER(p, 0, b1);
LCD_BYTE_FILTER(p+LCD_W, 0, b2);
p++;
lcdNextPos++;
}
}
}
else {
const uint8_t ym8 = (y & 0x07);
#if defined(BOLD_FONT)
#if defined(BOLD_SPECIFIC_FONT)
if (flags & BOLD) {
q = &font_5x7_B[(c_remapped)*5];
}
#else
uint8_t bb = 0;
if (inv) bb = 0xff;
#endif
#endif
uint8_t *lineEnd = &displayBuf[ y / 8 * LCD_W + LCD_W ];
for (int8_t i=0; i<=6; i++) {
uint8_t b = 0;
if (i==0) {
if (!x || !inv) {
lcdNextPos++;
p++;
continue;
}
}
else if (i <= 5) {
b = pgm_read_byte(q++);
}
if (b == 0xff) {
if (flags & FIXEDWIDTH)
b = 0;
else
continue;
}
if (inv) b = ~b;
if ((flags & CONDENSED) && i==2) {
/*condense the letter by skipping column 3 */
continue;
}
#if defined(BOLD_FONT) && !defined(BOLD_SPECIFIC_FONT)
if (flags & BOLD) {
uint8_t a;
if (inv)
a = b & bb;
else
a = b | bb;
bb = b;
b = a;
}
#endif
if (p<DISPLAY_END && p<lineEnd) {
ASSERT_IN_DISPLAY(p);
uint8_t mask = ~(0xff << ym8);
LCD_BYTE_FILTER(p, mask, b << ym8);
if (ym8) {
uint8_t *r = p + LCD_W;
if (r<DISPLAY_END)
LCD_BYTE_FILTER(r, ~mask, b >> (8-ym8));
}
if (inv && (ym8 == 1)) *p |= 0x01;
}
p++;
lcdNextPos++;
}
}
}
#endif
void lcd_putc(xcoord_t x, uint8_t y, const unsigned char c)
@ -662,94 +406,6 @@ void lcd_outdezNAtt(xcoord_t x, uint8_t y, lcdint_t val, LcdFlags flags, uint8_t
}
#endif
#if defined(PCBTARANIS)
void lcd_mask(uint8_t *p, uint8_t mask, LcdFlags att)
{
ASSERT_IN_DISPLAY(p);
if ((att&FILL_WHITE) && ((*p&mask) || (*(p+DISPLAY_PLAN_SIZE)&mask) || (*(p+2*DISPLAY_PLAN_SIZE)&mask) || (*(p+3*DISPLAY_PLAN_SIZE)&mask))) {
return;
}
if (!(att & GREY(1))) {
if (att & FORCE)
*p |= mask;
else if (att & ERASE)
*p &= ~mask;
else
*p ^= mask;
}
p += DISPLAY_PLAN_SIZE;
if (!(att & GREY(2))) {
if (att & FORCE)
*p |= mask;
else if (att & ERASE)
*p &= ~mask;
else
*p ^= mask;
}
p += DISPLAY_PLAN_SIZE;
if (!(att & GREY(4))) {
if (att & FORCE)
*p |= mask;
else if (att & ERASE)
*p &= ~mask;
else
*p ^= mask;
}
p += DISPLAY_PLAN_SIZE;
if (!(att & GREY(8))) {
if (att & FORCE)
*p |= mask;
else if (att & ERASE)
*p &= ~mask;
else
*p ^= mask;
}
}
#else
void lcd_mask(uint8_t *p, uint8_t mask, LcdFlags att)
{
ASSERT_IN_DISPLAY(p);
if (att & FORCE)
*p |= mask;
else if (att & ERASE)
*p &= ~mask;
else
*p ^= mask;
}
#endif
void lcd_plot(xcoord_t x, uint8_t y, LcdFlags att)
{
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
if (p<DISPLAY_END)
lcd_mask(p, BITMASK(y%8), att);
}
void lcd_hlineStip(xcoord_t x, uint8_t y, xcoord_t w, uint8_t pat, LcdFlags att)
{
if (y >= LCD_H) return;
if (x+w > LCD_W) { w = LCD_W - x; }
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
uint8_t msk = BITMASK(y%8);
while(w--) {
if(pat&1) {
lcd_mask(p, msk, att);
pat = (pat >> 1) | 0x80;
}
else {
pat = pat >> 1;
}
p++;
}
}
void lcd_hline(xcoord_t x, uint8_t y, xcoord_t w, LcdFlags att)
{
lcd_hlineStip(x, y, w, 0xff, att);
@ -798,98 +454,11 @@ void lcd_line(xcoord_t x1, int8_t y1, xcoord_t x2, int8_t y2, uint8_t pat, LcdFl
}
#endif
#if defined(CPUM64)
void lcd_vlineStip(xcoord_t x, int8_t y, int8_t h, uint8_t pat)
{
if (x >= LCD_W) return;
if (h<0) { y+=h; h=-h; }
if (y<0) { h+=y; y=0; }
if (y+h > LCD_H) { h = LCD_H - y; }
if (pat==DOTTED && !(y%2))
pat = ~pat;
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
y = (y & 0x07);
if (y) {
ASSERT_IN_DISPLAY(p);
*p ^= ~(BITMASK(y)-1) & pat;
p += LCD_W;
h -= 8-y;
}
while (h>0) {
ASSERT_IN_DISPLAY(p);
*p ^= pat;
p += LCD_W;
h -= 8;
}
if (h < 0) h += 8;
if (h) {
p -= LCD_W;
ASSERT_IN_DISPLAY(p);
*p ^= ~(BITMASK(h)-1) & pat;
}
}
#else
// allows the att parameter...
void lcd_vlineStip(xcoord_t x, int8_t y, int8_t h, uint8_t pat, LcdFlags att)
{
if (x >= LCD_W) return;
#if defined(CPUARM)
// should never happen on 9X
if (y >= LCD_H) return;
#endif
if (h<0) { y+=h; h=-h; }
if (y<0) { h+=y; y=0; }
if (y+h > LCD_H) { h = LCD_H - y; }
if (pat==DOTTED && !(y%2))
pat = ~pat;
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
y = (y & 0x07);
if (y) {
ASSERT_IN_DISPLAY(p);
uint8_t msk = ~(BITMASK(y)-1);
h -= 8-y;
if (h < 0)
msk -= ~(BITMASK(8+h)-1);
lcd_mask(p, msk & pat, att);
p += LCD_W;
}
while (h>=8) {
ASSERT_IN_DISPLAY(p);
lcd_mask(p, pat, att);
p += LCD_W;
h -= 8;
}
if (h>0) {
ASSERT_IN_DISPLAY(p);
lcd_mask(p, (BITMASK(h)-1) & pat, att);
}
}
#endif
void lcd_vline(xcoord_t x, int8_t y, int8_t h)
{
lcd_vlineStip(x, y, h, SOLID);
}
void lcd_invert_line(int8_t y)
{
uint8_t *p = &displayBuf[y * LCD_W];
for (xcoord_t x=0; x<LCD_W; x++) {
ASSERT_IN_DISPLAY(p);
#if defined(PCBTARANIS)
*(p+3*DISPLAY_PLAN_SIZE) ^= 0xff;
*(p+2*DISPLAY_PLAN_SIZE) ^= 0xff;
*(p+DISPLAY_PLAN_SIZE) ^= 0xff;
#endif
*p++ ^= 0xff;
}
}
void lcd_rect(xcoord_t x, uint8_t y, xcoord_t w, uint8_t h, uint8_t pat, LcdFlags att)
{
lcd_vlineStip(x, y, h, pat);
@ -1431,45 +1000,9 @@ void putsTelemetryChannel(xcoord_t x, uint8_t y, uint8_t channel, lcdint_t val,
}
#endif
void lcd_img(xcoord_t x, uint8_t y, const pm_uchar * img, uint8_t idx, LcdFlags att)
{
const pm_uchar *q = img;
#if LCD_W >= 260
xcoord_t w = pgm_read_byte(q++);
if (w == 255) w += pgm_read_byte(q++);
#else
uint8_t w = pgm_read_byte(q++);
#endif
uint8_t hb = (pgm_read_byte(q++)+7)/8;
bool inv = (att & INVERS) ? true : (att & BLINK ? BLINK_ON_PHASE : false);
q += idx*w*hb;
for (uint8_t yb = 0; yb < hb; yb++) {
uint8_t *p = &displayBuf[ (y / 8 + yb) * LCD_W + x ];
for (xcoord_t i=0; i<w; i++){
uint8_t b = pgm_read_byte(q);
q++;
ASSERT_IN_DISPLAY(p);
#if defined(PCBTARANIS)
uint8_t val = inv ? ~b : b;
if (!(att & GREY(1)))
*p = val;
if (!(att & GREY(2)))
*(p+DISPLAY_PLAN_SIZE) = val;
if (!(att & GREY(4)))
*(p+2*DISPLAY_PLAN_SIZE) = val;
if (!(att & GREY(8)))
*(p+3*DISPLAY_PLAN_SIZE) = val;
p++;
#else
*p++ = inv ? ~b : b;
#endif
}
}
}
void lcdSetContrast()
{
lcdSetRefVolt(g_eeGeneral.contrast);
}
#endif // !defined(BOOT)
#endif

441
radio/src/lcd_default.cpp Executable file
View file

@ -0,0 +1,441 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx 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 "opentx.h"
#define LCD_BYTE_FILTER(p, keep, add) *(p) = (*(p) & (keep)) | (add)
#if defined(CPUARM)
void lcdPutPattern(xcoord_t x, uint8_t y, const uint8_t * pattern, uint8_t width, uint8_t height, LcdFlags flags)
{
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
uint8_t *end = &displayBuf[ y / 8 * LCD_W + LCD_W ];
bool blink = false;
bool inv = false;
if (flags & BLINK) {
if (BLINK_ON_PHASE) {
if (flags & INVERS)
inv = true;
else {
blink = true;
}
}
}
else if (flags & INVERS) {
inv = true;
}
for (int8_t i=0; i<width+2 && p<end; i++) {
uint8_t lines = (height+7)/8;
assert(lines <= 5);
uint8_t b[5] = { 0 };
if (i==0) {
if (x==0 || !inv) {
lcdNextPos++;
continue;
}
else {
// we need to work on the previous byte when INVERS
p--;
}
}
else if (i<=width) {
uint8_t skip = true;
for (uint8_t j=0; j<lines; j++) {
b[j] = pgm_read_byte(pattern++); /*top byte*/
if (b[j] != 0xff) {
skip = false;
}
}
if (skip) {
if (flags & FIXEDWIDTH) {
for (uint8_t j=0; j<lines; j++) {
b[j] = 0;
}
}
else {
continue;
}
}
if ((flags & CONDENSED) && i==2) {
/*condense the letter by skipping column 3 */
continue;
}
}
const uint8_t ym8 = (y & 0x07);
const uint8_t keepref = (1 << ((height&0x07)+1)) - 1;
uint8_t * dest = p;
for (uint8_t j=0; j<lines+1; j++) {
if (dest < DISPLAY_END) {
uint8_t b1=0, b2=0, keep=0;
if (j>0) {
b1 = b[j-1] >> (8-ym8);
}
else {
keep = ~(keepref << ym8);
}
if (j<lines) {
if (inv) {
b[j] = ~b[j];
if (j==lines-1) {
if (height >= 10)
b[j] &= 1 + (keepref << 1);
else
b[j] &= keepref;
}
}
b2 = b[j] << ym8;
}
else {
keep = ~(keepref >> (8-ym8));
}
if (!blink) {
LCD_BYTE_FILTER(dest, keep, b1|b2);
}
dest += LCD_W;
}
}
if (inv && height<8) {
if (ym8)
lcd_mask(p, 0x01 << (ym8-1), FORCE);
else if (y) {
ASSERT_IN_DISPLAY(p - LCD_W);
lcd_mask(p - LCD_W, 0x80, FORCE);
}
}
p++;
lcdNextPos++;
}
}
#else
void lcd_putcAtt(xcoord_t x, uint8_t y, const unsigned char c, LcdFlags flags)
{
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
const pm_uchar *q = &font_5x7[(c-0x20)*5];
lcdNextPos = x-1;
p--;
bool inv = false;
if (flags & BLINK) {
if (BLINK_ON_PHASE) {
if (flags & INVERS)
inv = true;
else {
return;
}
}
}
else if (flags & INVERS) {
inv = true;
}
unsigned char c_remapped = 0;
#if defined(BOLD_SPECIFIC_FONT)
if (flags & (DBLSIZE+BOLD)) {
#else
if (flags & DBLSIZE) {
#endif
// To save space only some DBLSIZE and BOLD chars are available
// c has to be remapped. All non existing chars mapped to 0 (space)
if (c>=',' && c<=':')
c_remapped = c - ',' + 1;
else if (c>='A' && c<='Z')
c_remapped = c - 'A' + 16;
else if (c>='a' && c<='z')
c_remapped = c - 'a' + 42;
else if (c=='_')
c_remapped = 4;
#if defined(BOLD_SPECIFIC_FONT)
else if (c!=' ')
flags &= ~BOLD;
#endif
#if defined(BOLD_SPECIFIC_FONT)
}
if (flags & DBLSIZE) {
#endif
/* each letter consists of ten top bytes followed by
* by ten bottom bytes (20 bytes per * char) */
q = &font_10x14[((uint16_t)c_remapped)*20];
for (int8_t i=0; i<=11; i++) {
uint8_t b1=0, b2=0;
if (!i) {
if (!x || !inv) {
lcdNextPos++;
p++;
continue;
}
}
else if (i <= 10) {
b1 = pgm_read_byte(q++); /*top byte*/
b2 = pgm_read_byte(q++);
}
if ((b1 & b2) == 0xff) continue;
if (inv) {
b1 = ~b1;
b2 = ~b2;
}
if(&p[LCD_W+1] < DISPLAY_END) {
ASSERT_IN_DISPLAY(p);
ASSERT_IN_DISPLAY(p+LCD_W);
LCD_BYTE_FILTER(p, 0, b1);
LCD_BYTE_FILTER(p+LCD_W, 0, b2);
p++;
lcdNextPos++;
}
}
}
else {
const uint8_t ym8 = (y & 0x07);
#if defined(BOLD_FONT)
#if defined(BOLD_SPECIFIC_FONT)
if (flags & BOLD) {
q = &font_5x7_B[(c_remapped)*5];
}
#else
uint8_t bb = 0;
if (inv) bb = 0xff;
#endif
#endif
uint8_t *lineEnd = &displayBuf[ y / 8 * LCD_W + LCD_W ];
for (int8_t i=0; i<=6; i++) {
uint8_t b = 0;
if (i==0) {
if (!x || !inv) {
lcdNextPos++;
p++;
continue;
}
}
else if (i <= 5) {
b = pgm_read_byte(q++);
}
if (b == 0xff) {
if (flags & FIXEDWIDTH)
b = 0;
else
continue;
}
if (inv) b = ~b;
if ((flags & CONDENSED) && i==2) {
/*condense the letter by skipping column 3 */
continue;
}
#if defined(BOLD_FONT) && !defined(BOLD_SPECIFIC_FONT)
if (flags & BOLD) {
uint8_t a;
if (inv)
a = b & bb;
else
a = b | bb;
bb = b;
b = a;
}
#endif
if (p<DISPLAY_END && p<lineEnd) {
ASSERT_IN_DISPLAY(p);
uint8_t mask = ~(0xff << ym8);
LCD_BYTE_FILTER(p, mask, b << ym8);
if (ym8) {
uint8_t *r = p + LCD_W;
if (r<DISPLAY_END)
LCD_BYTE_FILTER(r, ~mask, b >> (8-ym8));
}
if (inv && (ym8 == 1)) *p |= 0x01;
}
p++;
lcdNextPos++;
}
}
}
#endif
void lcd_mask(uint8_t *p, uint8_t mask, LcdFlags att)
{
ASSERT_IN_DISPLAY(p);
if (att & FORCE)
*p |= mask;
else if (att & ERASE)
*p &= ~mask;
else
*p ^= mask;
}
void lcd_plot(xcoord_t x, uint8_t y, LcdFlags att)
{
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
if (p<DISPLAY_END)
lcd_mask(p, BITMASK(y%8), att);
}
void lcd_hlineStip(xcoord_t x, uint8_t y, xcoord_t w, uint8_t pat, LcdFlags att)
{
if (y >= LCD_H) return;
if (x+w > LCD_W) { w = LCD_W - x; }
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
uint8_t msk = BITMASK(y%8);
while (w--) {
if(pat&1) {
lcd_mask(p, msk, att);
pat = (pat >> 1) | 0x80;
}
else {
pat = pat >> 1;
}
p++;
}
}
#if defined(CPUM64)
void lcd_vlineStip(xcoord_t x, int8_t y, int8_t h, uint8_t pat)
{
if (x >= LCD_W) return;
if (h<0) { y+=h; h=-h; }
if (y<0) { h+=y; y=0; }
if (y+h > LCD_H) { h = LCD_H - y; }
if (pat==DOTTED && !(y%2))
pat = ~pat;
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
y = (y & 0x07);
if (y) {
ASSERT_IN_DISPLAY(p);
*p ^= ~(BITMASK(y)-1) & pat;
p += LCD_W;
h -= 8-y;
}
while (h>0) {
ASSERT_IN_DISPLAY(p);
*p ^= pat;
p += LCD_W;
h -= 8;
}
if (h < 0) h += 8;
if (h) {
p -= LCD_W;
ASSERT_IN_DISPLAY(p);
*p ^= ~(BITMASK(h)-1) & pat;
}
}
#else
// allows the att parameter...
void lcd_vlineStip(xcoord_t x, int8_t y, int8_t h, uint8_t pat, LcdFlags att)
{
if (x >= LCD_W) return;
#if defined(CPUARM)
// should never happen on 9X
if (y >= LCD_H) return;
#endif
if (h<0) { y+=h; h=-h; }
if (y<0) { h+=y; y=0; }
if (y+h > LCD_H) { h = LCD_H - y; }
if (pat==DOTTED && !(y%2))
pat = ~pat;
uint8_t *p = &displayBuf[ y / 8 * LCD_W + x ];
y = (y & 0x07);
if (y) {
ASSERT_IN_DISPLAY(p);
uint8_t msk = ~(BITMASK(y)-1);
h -= 8-y;
if (h < 0)
msk -= ~(BITMASK(8+h)-1);
lcd_mask(p, msk & pat, att);
p += LCD_W;
}
while (h>0) {
ASSERT_IN_DISPLAY(p);
lcd_mask(p, pat, att);
p += LCD_W;
h -= 8;
}
if (h>0) {
ASSERT_IN_DISPLAY(p);
lcd_mask(p, (BITMASK(h)-1) & pat, att);
}
}
#endif
void lcd_invert_line(int8_t y)
{
uint8_t *p = &displayBuf[y * LCD_W];
for (xcoord_t x=0; x<LCD_W; x++) {
ASSERT_IN_DISPLAY(p);
*p++ ^= 0xff;
}
}
#if !defined(BOOT)
void lcd_img(xcoord_t x, uint8_t y, const pm_uchar * img, uint8_t idx, LcdFlags att)
{
const pm_uchar *q = img;
#if LCD_W >= 260
xcoord_t w = pgm_read_byte(q++);
if (w == 255) w += pgm_read_byte(q++);
#else
uint8_t w = pgm_read_byte(q++);
#endif
uint8_t hb = (pgm_read_byte(q++)+7)/8;
bool inv = (att & INVERS) ? true : (att & BLINK ? BLINK_ON_PHASE : false);
q += idx*w*hb;
for (uint8_t yb = 0; yb < hb; yb++) {
uint8_t *p = &displayBuf[ (y / 8 + yb) * LCD_W + x ];
for (xcoord_t i=0; i<w; i++){
uint8_t b = pgm_read_byte(q);
q++;
ASSERT_IN_DISPLAY(p);
*p++ = inv ? ~b : b;
}
}
}
#endif

246
radio/src/lcd_taranis.cpp Executable file
View file

@ -0,0 +1,246 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx 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 "opentx.h"
void lcdPutPattern(xcoord_t x, uint8_t y, const uint8_t * pattern, uint8_t width, uint8_t height, LcdFlags flags)
{
bool blink = false;
bool inv = false;
if (flags & BLINK) {
if (BLINK_ON_PHASE) {
if (flags & INVERS)
inv = true;
else {
blink = true;
}
}
}
else if (flags & INVERS) {
inv = true;
}
uint8_t lines = (height+7)/8;
assert(lines <= 5);
for (int8_t i=0; i<width+2; i++) {
if (x<LCD_W) {
uint8_t b[5] = { 0 };
if (i==0) {
if (x==0 || !inv) {
lcdNextPos++;
continue;
}
else {
x--;
}
}
else if (i<=width) {
uint8_t skip = true;
for (uint8_t j=0; j<lines; j++) {
b[j] = pgm_read_byte(pattern++); /*top byte*/
if (b[j] != 0xff) {
skip = false;
}
}
if (skip) {
if (flags & FIXEDWIDTH) {
for (uint8_t j=0; j<lines; j++) {
b[j] = 0;
}
}
else {
continue;
}
}
if ((flags & CONDENSED) && i==2) {
/*condense the letter by skipping column 3 */
continue;
}
}
for (int8_t j=-1; j<=height; j++) {
bool plot;
if (j < 0 || j == height) {
plot = false;
if (j<0 && !inv) continue;
}
else {
uint8_t line = (j / 8);
uint8_t pixel = (j % 8);
plot = b[line] & (1 << pixel);
}
if (inv) plot = !plot;
if (!blink) {
lcd_plot(x, y+j, plot ? FORCE : ERASE);
}
}
}
x++;
lcdNextPos++;
}
}
void lcd_mask(uint8_t *p, uint8_t mask, LcdFlags att)
{
ASSERT_IN_DISPLAY(p);
if (att&FILL_WHITE) {
// TODO I could remove this, it's used for the top bar
if (*p & 0x0F) mask &= 0xF0;
if (*p & 0xF0) mask &= 0x0F;
}
if (att & FORCE) {
*p |= mask;
}
else if (att & ERASE) {
*p &= ~mask;
}
else {
*p ^= mask;
}
}
#define PIXEL_GREY_MASK(y, att) (((y) & 1) ? (0xF0 - (GREY_MASK(att) >> 8)) : (0x0F - (GREY_MASK(att) >> 12)))
void lcd_plot(xcoord_t x, uint8_t y, LcdFlags att)
{
uint8_t *p = &displayBuf[ y / 2 * LCD_W + x ];
uint8_t mask = PIXEL_GREY_MASK(y, att);
if (p<DISPLAY_END) {
lcd_mask(p, mask, att);
}
}
void lcd_hlineStip(xcoord_t x, uint8_t y, xcoord_t w, uint8_t pat, LcdFlags att)
{
if (y >= LCD_H) return;
if (x+w > LCD_W) { w = LCD_W - x; }
uint8_t *p = &displayBuf[ y / 2 * LCD_W + x ];
uint8_t mask = PIXEL_GREY_MASK(y, att);
while (w--) {
if (pat&1) {
lcd_mask(p, mask, att);
pat = (pat >> 1) | 0x80;
}
else {
pat = pat >> 1;
}
p++;
}
}
void lcd_vlineStip(xcoord_t x, int8_t y, int8_t h, uint8_t pat, LcdFlags att)
{
if (x >= LCD_W) return;
if (y >= LCD_H) return;
if (h<0) { y+=h; h=-h; }
if (y<0) { h+=y; y=0; }
if (y+h > LCD_H) { h = LCD_H - y; }
if (pat==DOTTED && !(y%2)) {
pat = ~pat;
}
while (h--) {
if (pat & 1) {
lcd_plot(x, y, att);
pat = (pat >> 1) | 0x80;
}
else {
pat = pat >> 1;
}
y++;
}
}
void lcd_invert_line(int8_t y)
{
uint8_t *p = &displayBuf[y * 4 * LCD_W];
for (xcoord_t x=0; x<LCD_W*4; x++) {
ASSERT_IN_DISPLAY(p);
*p++ ^= 0xff;
}
}
#if !defined(BOOT)
void lcd_img(xcoord_t x, uint8_t y, const pm_uchar * img, uint8_t idx, LcdFlags att)
{
const pm_uchar *q = img;
uint8_t w = pgm_read_byte(q++);
uint8_t hb = (pgm_read_byte(q++)+7) / 8;
bool inv = (att & INVERS) ? true : (att & BLINK ? BLINK_ON_PHASE : false);
q += idx*w*hb;
for (uint8_t yb = 0; yb < hb; yb++) {
for (xcoord_t i=0; i<w; i++) {
uint8_t b = pgm_read_byte(q++);
uint8_t val = inv ? ~b : b;
for (int k=0; k<8; k++) {
if (val & (1<<k)) {
lcd_plot(x+i, y+yb*8+k, 0);
}
}
}
}
}
void lcd_bmp(xcoord_t x, uint8_t y, const pm_uchar * img, uint8_t offset, uint8_t width)
{
const pm_uchar *q = img;
uint8_t w = pgm_read_byte(q++);
if (!width) width = w;
uint8_t rows = (pgm_read_byte(q++) + 1) / 2;
for (uint8_t row=0; row<rows; row++) {
q = img + 2 + row*w + offset;
uint8_t *p = &displayBuf[(row + (y/2)) * LCD_W + x];
for (xcoord_t i=0; i<width; i++) {
uint8_t b = pgm_read_byte(q++);
if (y & 1) {
*p = (*p & 0x0f) + ((b & 0x0f) << 4);
*(p+LCD_W) = (*(p+LCD_W) & 0xf0) + ((b & 0xf0) >> 4);
}
else {
*p = b;
}
p++;
}
}
}
#endif

View file

@ -59,7 +59,7 @@ class Open9xSim: public FXMainWindow
long onTimeout(FXObject*,FXSelector,void*);
void makeSnapshot(const FXDrawable* drawable);
void doEvents();
void refreshDiplay();
void refreshDisplay();
private:
FXImage *bmp;
@ -283,7 +283,7 @@ long Open9xSim::onTimeout(FXObject*, FXSelector, void*)
}
per10ms();
refreshDiplay();
refreshDisplay();
getApp()->addTimeout(this, 2, 10);
return 0;
}
@ -294,7 +294,7 @@ long Open9xSim::onTimeout(FXObject*, FXSelector, void*)
#define BL_COLOR FXRGB(150,200,152)
#endif
void Open9xSim::refreshDiplay()
void Open9xSim::refreshDisplay()
{
if (lcd_refresh) {
lcd_refresh = false;
@ -305,9 +305,8 @@ void Open9xSim::refreshDiplay()
for (int x=0;x<LCD_W;x++) {
for (int y=0; y<LCD_H; y++) {
#if defined(PCBTARANIS)
#define PALETTE_IDX(p, x, mask) ((((p)[(x)] & (mask)) ? 0x1 : 0) + (((p)[DISPLAY_PLAN_SIZE+(x)] & (mask)) ? 0x2 : 0) + (((p)[2*DISPLAY_PLAN_SIZE+(x)] & (mask)) ? 0x4 : 0) + (((p)[3*DISPLAY_PLAN_SIZE+(x)] & (mask)) ? 0x8 : 0))
uint8_t mask = (1 << (y%8));
uint32_t z = PALETTE_IDX(lcd_buf, (y/8)*LCD_W+x, mask);
uint8_t * p = & lcd_buf[y / 2 * LCD_W + x];
uint8_t z = (y & 1) ? (*p >> 4) : (*p & 0x0F);
if (z) {
FXColor color;
if (IS_BACKLIGHT_ON())
@ -346,7 +345,7 @@ void doFxEvents()
{
//puts("doFxEvents");
th9xSim->getApp()->runOneEvent(false);
th9xSim->refreshDiplay();
th9xSim->refreshDisplay();
}
int main(int argc,char **argv)

View file

@ -111,9 +111,6 @@ void Set_Address(u8 x, u8 y)
WriteCommand(((y>>4)&0x0F)|0x70); //Set Row Address MSB RA [7:4]
}
#define PALETTE_IDX(p, x, mask) (((p[x] & mask) ? 0x1 : 0) + ((p[DISPLAY_PLAN_SIZE+x] & mask) ? 0x2 : 0) + ((p[2*DISPLAY_PLAN_SIZE+x] & mask) ? 0x4 : 0) + ((p[3*DISPLAY_PLAN_SIZE+x] & mask) ? 0x8 : 0))
const uint8_t lcdPalette[4] = { 0, 0x03, 0x06, 0x0F };
#define LCD_WRITE_BIT(bit) \
if (bit) \
LCD_MOSI_HIGH(); \
@ -127,9 +124,7 @@ const uint8_t lcdPalette[4] = { 0, 0x03, 0x06, 0x0F };
void lcdRefresh()
{
for (uint32_t y=0; y<LCD_H; y+=2) {
uint8_t *p = &displayBuf[(y>>3)*LCD_W];
uint8_t mask = (1 << (y%8));
uint8_t mask2 = (1 << (1+(y%8)));
uint8_t *p = &displayBuf[y/2 * LCD_W];
Set_Address(0, y/2);
AspiCmd(0xAF);
@ -139,18 +134,15 @@ void lcdRefresh()
LCD_NCS_LOW();
for (uint32_t x=0; x<LCD_W; x++) {
uint8_t a = p[3*DISPLAY_PLAN_SIZE+x] ;
uint8_t b = p[2*DISPLAY_PLAN_SIZE+x] ;
uint8_t c = p[DISPLAY_PLAN_SIZE+x] ;
uint8_t d = p[x] ;
LCD_WRITE_BIT(a & mask2);
LCD_WRITE_BIT(b & mask2);
LCD_WRITE_BIT(c & mask2);
LCD_WRITE_BIT(d & mask2);
LCD_WRITE_BIT(a & mask);
LCD_WRITE_BIT(b & mask);
LCD_WRITE_BIT(c & mask);
LCD_WRITE_BIT(d & mask);
uint8_t a = p[x] ;
LCD_WRITE_BIT(a & 0x80);
LCD_WRITE_BIT(a & 0x40);
LCD_WRITE_BIT(a & 0x20);
LCD_WRITE_BIT(a & 0x10);
LCD_WRITE_BIT(a & 0x08);
LCD_WRITE_BIT(a & 0x04);
LCD_WRITE_BIT(a & 0x02);
LCD_WRITE_BIT(a & 0x01);
}
LCD_NCS_HIGH();
@ -163,8 +155,7 @@ void lcdRefresh()
void lcdRefresh()
{
for (uint32_t y=0; y<LCD_H; y++) {
uint8_t *p = &displayBuf[(y>>3)*LCD_W];
uint8_t mask = (1 << (y%8));
uint8_t *p = &displayBuf[y/2 * LCD_W];
Set_Address(0, y);
AspiCmd(0xAF);
@ -174,10 +165,13 @@ void lcdRefresh()
LCD_NCS_LOW();
for (uint32_t x=0; x<LCD_W; x++) {
LCD_WRITE_BIT(p[3*DISPLAY_PLAN_SIZE+x] & mask);
LCD_WRITE_BIT(p[2*DISPLAY_PLAN_SIZE+x] & mask);
LCD_WRITE_BIT(p[DISPLAY_PLAN_SIZE+x] & mask);
LCD_WRITE_BIT(p[x] & mask);
uint8_t b = p[x];
if (y & 1)
b >>= 4;
LCD_WRITE_BIT(b & 0x01);
LCD_WRITE_BIT(b & 0x02);
LCD_WRITE_BIT(b & 0x04);
LCD_WRITE_BIT(b & 0x08);
}
LCD_NCS_HIGH();

View file

@ -990,25 +990,25 @@ void doPaint(QPainter & p)
#if defined(PCBTARANIS)
unsigned int previousDepth = 0xFF;
const int planSize = (LCD_W * ((LCD_H+7) / 8));
#endif
for (int y=0; y<LCD_H; y++) {
unsigned int idx = (y/8)*LCD_W;
#if defined(PCBTARANIS)
unsigned int idx = (y/2) * LCD_W;
#else
unsigned int idx = (y/8) * LCD_W;
unsigned int mask = (1 << (y%8));
#endif
for (int x=0; x<LCD_W; x++, idx++) {
#if !defined(PCBTARANIS)
if (lcd_buf[idx] & mask) {
p.drawPoint(x, y);
}
#else
unsigned int z = (((lcd_buf[idx] & mask) ? 0x1 : 0) + ((lcd_buf[planSize+idx] & mask) ? 0x2 : 0) + ((lcd_buf[2*planSize+idx] & mask) ? 0x4 : 0) + ((lcd_buf[3*planSize+idx] & mask) ? 0x8 : 0));
unsigned int z = (y & 1) ? (lcd_buf[idx] >> 4) : (lcd_buf[idx] & 0x0F);
if (z) {
if (z != previousDepth) {
previousDepth = z;
//if (lightEnable)
// rgb = qRgb(_r-(z*_r)/15, _g-(z*_g)/15, _b-(z*_b)/15);
//else
rgb = qRgb(161-(z*161)/15, 161-(z*161)/15, 161-(z*161)/15);
p.setPen(rgb);
p.setBrush(QBrush(rgb));

View file

@ -43,22 +43,19 @@ elif what == "img":
f.write("0x%02x," % value)
f.write("\n")
elif what == "bmp":
rows = 1
colors = []
if len(sys.argv) > 4:
rows = int(sys.argv[4])
f.write("%d,%d,\n" % (width, height/rows))
for y in range(0, height, 8):
f.write("%d,%d,\n" % (width, height))
for y in range(0, height, 2):
for x in range(width):
values = [255, 255, 255, 255]
for z in range(8):
if y+z < height:
gray = Qt.qGray(image.pixel(x, y+z))
for i in range(4):
if (gray & (1<<(4+i))):
values[i] -= 1 << z
for value in values:
f.write("0x%02x," % value)
value = 0xFF;
gray1 = Qt.qGray(image.pixel(x, y))
gray2 = Qt.qGray(image.pixel(x, y+1))
for i in range(4):
if (gray1 & (1<<(4+i))):
value -= 1<<i
if (gray2 & (1<<(4+i))):
value -= 1<<(4+i)
f.write("0x%02x," % value)
f.write("\n")
elif what == "03x05":
for y in range(0, height, 5):