[Taranis X9E] Top LCD now working. Only timer can be configured (top

line)
This commit is contained in:
bsongis
2015-03-07 20:16:56 +01:00
parent 91ee3e8d46
commit 850caf741a
5 changed files with 302 additions and 11 deletions
+20 -1
View File
@@ -82,6 +82,9 @@ enum menuModelTelemetryItems {
ITEM_TELEMETRY_TOP_BAR_LABEL,
ITEM_TELEMETRY_TOP_BAR_VOLTAGE,
ITEM_TELEMETRY_TOP_BAR_ALTITUDE,
#if defined(REV9E)
ITEM_TELEMETRY_TOP_LCD_TIMER,
#endif
ITEM_TELEMETRY_SCREEN_LABEL1,
ITEM_TELEMETRY_SCREEN_LINE1,
ITEM_TELEMETRY_SCREEN_LINE2,
@@ -433,9 +436,15 @@ void onTelemetryScriptFileSelectionMenu(const char *result)
}
#endif
#if defined(REV9E)
#define TOPLCD_ROWS 0,
#else
#define TOPLCD_ROWS
#endif
void menuModelTelemetry(uint8_t event)
{
MENU(STR_MENUTELEMETRY, menuTabModel, e_Telemetry, ITEM_TELEMETRY_MAX, { TELEMETRY_TYPE_ROWS RSSI_ROWS SENSORS_ROWS USRDATA_ROWS CASE_VARIO(LABEL(Vario)) CASE_VARIO(0) CASE_VARIO(VARIO_RANGE_ROWS) LABEL(TopBar), 0, 0, TELEMETRY_SCREEN_ROWS(0), TELEMETRY_SCREEN_ROWS(1), CASE_CPUARM(TELEMETRY_SCREEN_ROWS(2)) CASE_CPUARM(TELEMETRY_SCREEN_ROWS(3)) });
MENU(STR_MENUTELEMETRY, menuTabModel, e_Telemetry, ITEM_TELEMETRY_MAX, { TELEMETRY_TYPE_ROWS RSSI_ROWS SENSORS_ROWS USRDATA_ROWS CASE_VARIO(LABEL(Vario)) CASE_VARIO(0) CASE_VARIO(VARIO_RANGE_ROWS) LABEL(TopBar), 0, 0, TOPLCD_ROWS TELEMETRY_SCREEN_ROWS(0), TELEMETRY_SCREEN_ROWS(1), CASE_CPUARM(TELEMETRY_SCREEN_ROWS(2)) CASE_CPUARM(TELEMETRY_SCREEN_ROWS(3)) });
int sub = m_posVert;
@@ -579,6 +588,16 @@ void menuModelTelemetry(uint8_t event)
}
break;
#if defined(REV9E)
case ITEM_TELEMETRY_TOP_LCD_TIMER:
lcd_putsLeft(y, "Top LCD Timer");
putsStrIdx(TELEM_COL2, y, "Timer", g_model.topLcdTimer+1, attr);
if (attr) {
g_model.topLcdTimer = checkIncDec(event, g_model.topLcdTimer, 0, MAX_TIMERS-1, EE_MODEL);
}
break;
#endif
case ITEM_TELEMETRY_SCREEN_LABEL1:
case ITEM_TELEMETRY_SCREEN_LABEL2:
case ITEM_TELEMETRY_SCREEN_LABEL3:
+9 -2
View File
@@ -187,8 +187,15 @@ void perMain()
lcdRefresh();
#if defined(REV9E)
topLcdRefresh();
#if defined(REV9E) && !defined(SIMU)
topLcdRefreshStart();
setTopFirstTimer(getValue(MIXSRC_FIRST_TIMER+g_model.topLcdTimer));
setTopSecondTimer(g_eeGeneral.globalTimer + sessionTimer);
setTopRssi(TELEMETRY_RSSI());
setTopBatteryValue(g_vbat100mV);
int state = 5 * (g_vbat100mV - g_eeGeneral.vBatMin - 90) / (30 + g_eeGeneral.vBatMax - g_eeGeneral.vBatMin);
setTopBatteryState(state);
topLcdRefreshEnd();
#endif
}
+4
View File
@@ -2137,6 +2137,10 @@ PACK(typedef struct {
MODELDATA_EXTRA
ARM_FIELD(TelemetrySensor telemetrySensors[TELEM_VALUES_MAX])
#if defined(PCBTARANIS) && defined(REV9E)
uint8_t topLcdTimer;
#endif
}) ModelData;
extern EEGeneral g_eeGeneral;
+7 -1
View File
@@ -317,7 +317,13 @@ int bt_read(void *buffer, int len);
// Top LCD driver
#if defined(REV9E)
void topLcdInit(void);
void topLcdRefresh(void);
void topLcdRefreshStart(void);
void topLcdRefreshEnd(void);
void setTopFirstTimer(uint32_t value);
void setTopSecondTimer(uint32_t value);
void setTopRssi(uint32_t rssi);
void setTopBatteryState(uint32_t state);
void setTopBatteryValue(uint32_t volts);
#endif
#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE)
+262 -7
View File
@@ -34,7 +34,12 @@
*
*/
uint8_t top_lcd_data[16] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
const uint8_t TimeLCDsegs[] = { 0xAF, 0x06, 0x6D, 0x4F, 0xC6, 0xCB, 0xEB, 0x0E, 0xEF, 0xCF };
const uint8_t RssiLCDsegs[] = { 0xFA, 0x60, 0xBC, 0xF4, 0x66, 0xD6, 0xDE, 0x70, 0xFE, 0xF6 };
const uint8_t OpTimeLCDsegs[] = { 0x5F, 0x06, 0x6B, 0x2F, 0x36, 0x3D, 0x7D, 0x07, 0x7F, 0x3F };
uint8_t Ht1621Data1[11] = { 0 };
uint8_t Ht1621Data2[7] = { 0 };
void delay1_7us()
{
@@ -117,14 +122,19 @@ void ht1621WrData(uint8_t data, uint8_t count)
void ht1621WrAllData(uint8_t chip, uint8_t *pData)
{
if (chip)
int len;
if (chip) {
len = sizeof(Ht1621Data2);
CS2_LOW;
else
}
else {
len = sizeof(Ht1621Data1);
CS1_LOW;
}
delay1_7us();
ht1621WrData(0xa0, 3);
ht1621WrData(0, 6); // HT1621 6 bit,left 2 bit;
for (int i=0; i<16; i++) {
for (int i=0; i<len; i++) {
ht1621WrData(*pData++, 8);
}
if (chip)
@@ -134,6 +144,98 @@ void ht1621WrAllData(uint8_t chip, uint8_t *pData)
delay1_7us();
}
#if 0
void initTimerTopLcd()
{
// Timer12
RCC->APB1ENR |= RCC_APB1ENR_TIM12EN ; // Enable clock
TIM12->ARR = 17 ; // 1.7uS
TIM12->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 10000000 - 1 ; // 0.1uS from 30MHz
TIM12->CCER = 0 ;
TIM12->CCMR1 = 0 ;
TIM12->EGR = 0 ;
TIM12->CR1 = 5 ;
// TIM12->DIER |= 1 ;
NVIC_SetPriority(TIM8_BRK_TIM12_IRQn, 2 ) ;
NVIC_EnableIRQ(TIM8_BRK_TIM12_IRQn) ;
}
extern "C" void TIM8_BRK_TIM12_IRQHandler()
{
struct t_top_lcd_control *pc ;
TIM12->SR &= ~TIM_SR_UIF ;
pc = &TopLcdControl ;
if ( pc->state == TOP_LCD_CKLOW )
{
WR_LOW ; //PRESENT 100 COMMAND CODE
if ((*pc->data & 0x80) !=0)
{
DATA_HIGH ;
}
else
{
DATA_LOW ;
}
*pc->data <<= 1 ;
pc->state = TOP_LCD_CKHI ;
}
else if ( pc->state == TOP_LCD_CKHI )
{
WR_HIGH ;
if ( --pc->count == 0 )
{
pc->state = TOP_LCD_END ;
}
else
{
pc->state = TOP_LCD_CKLOW ;
}
}
else if ( pc->state == TOP_LCD_END )
{
if ( pc->chip )
{
CS2_HIGH ;
pc->state = TOP_LCD_IDLE ;
TIM12->DIER &= ~1 ;
}
else
{
CS1_HIGH ;
pc->chip = 1 ;
pc->data = pc->data2 ;
pc->count = pc->count2 ;
pc->state = TOP_LCD_IDLE ;
}
}
else if ( pc->state == TOP_LCD_IDLE )
{
WR_HIGH;
if ( pc->chip ) CS2_LOW ; else CS1_LOW ;
pc->state = TOP_LCD_1CKLOW ;
}
else if ( pc->state == TOP_LCD_1CKLOW )
{
WR_LOW ;
DATA_HIGH ; // First 1 bit
pc->state = TOP_LCD_1CKHI ;
}
else if ( pc->state == TOP_LCD_1CKHI )
{
WR_HIGH ;
if ( --pc->count == 0 )
{
pc->state = TOP_LCD_END ;
}
else
{
pc->state = TOP_LCD_CKLOW ;
}
}
}
#endif
void topLcdInit()
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_VA, ENABLE);
@@ -154,10 +256,163 @@ void topLcdInit()
ht1621SendCommand(1, 0x03);
ht1621SendCommand(1, 0x01);
ht1621SendCommand(1, 0x29);
topLcdRefreshStart();
topLcdRefreshEnd();
}
void topLcdRefresh()
void setTopFirstTimer(uint32_t value)
{
ht1621WrAllData(0, top_lcd_data);
ht1621WrAllData(1, top_lcd_data);
div_t qr = div(value, 60);
uint32_t r = qr.rem;
qr = div(qr.quot, 10) ;
Ht1621Data1[0] |= TimeLCDsegs[qr.quot] ;
Ht1621Data1[1] |= TimeLCDsegs[qr.rem] ;
qr = div(r, 10) ;
Ht1621Data1[2] |= TimeLCDsegs[qr.quot] | 0x10 ; // ":"
Ht1621Data1[3] |= TimeLCDsegs[qr.rem] | 0x10 ; // "Operation Time"
}
/*void setTopFirstTimer(uint32_t value)
{
div_t qr ;
uint32_t r ;
qr = div(value, 60) ;
r = qr.rem ;
qr = div(qr.quot, 10);
Ht1621Data1[1] |= TimeLCDsegs[qr.quot] ;
Ht1621Data1[2] |= TimeLCDsegs[qr.rem] ;
qr = div(r, 10) ;
Ht1621Data1[3] |= TimeLCDsegs[qr.quot] | 0x10 ; // ":"
Ht1621Data1[4] |= TimeLCDsegs[qr.rem] | 0x10 ; // "Operation Time"
}*/
void setTopRssiValue(uint32_t rssi)
{
div_t qr = div(rssi, 10);
uint32_t r = 0;
if (qr.quot > 9) {
r = 1;
qr.quot -= 10;
}
Ht1621Data2[2] |= r ? RssiLCDsegs[1] : 0;
Ht1621Data2[1] |= (r || qr.quot) ? RssiLCDsegs[qr.quot] : 0;
Ht1621Data2[0] |= RssiLCDsegs[qr.rem];
}
void setTopRssiBar(uint32_t rssi)
{
if (rssi > 42)
Ht1621Data2[2] |= 1 ;
if (rssi > 45)
Ht1621Data2[1] |= 1 ;
if (rssi > 50)
Ht1621Data2[0] |= 1 ;
if (rssi > 60)
Ht1621Data2[3] |= 0x10 ;
if (rssi > 70)
Ht1621Data2[3] |= 0x20 ;
if (rssi > 80)
Ht1621Data2[3] |= 0x40 ;
if (rssi > 90)
Ht1621Data2[3] |= 0x80 ;
}
void setTopRssi(uint32_t rssi)
{
Ht1621Data1[4] |= 0x10; // "RSSI"
Ht1621Data2[3] |= 0x01; // "dB"
Ht1621Data2[4] |= 0x01; // Horizontal line
setTopRssiValue(rssi);
setTopRssiBar(rssi);
}
void setTopBatteryState(uint32_t state)
{
Ht1621Data1[4] |= 0x40; // Battery border
if (state > 0)
Ht1621Data1[7] |= 0x80 ;
if (state > 1)
Ht1621Data1[9] |= 0x80 ;
if (state > 2)
Ht1621Data1[5] |= 0x80 ;
if (state > 3)
Ht1621Data1[10] |= 0x80 ;
if (state > 4)
Ht1621Data1[4] |= 0x80 ;
}
void setTopBatteryValue(uint32_t volts)
{
div_t qr ;
uint32_t r = 0 ;
uint32_t segs ;
qr = div(volts, 10) ;
if (qr.quot > 9) {
r = 1 ;
qr.quot -= 10 ;
}
segs = r ? RssiLCDsegs[1] : 0 ;
Ht1621Data2[3] |= ((segs & 7) << 1);
Ht1621Data2[4] |= segs & 0xF0 ;
segs = (r || qr.quot) ? RssiLCDsegs[qr.quot] : 0 ;
Ht1621Data2[4] |= (segs & 0x0E);
Ht1621Data2[5] |= segs & 0xF0 ;
segs = RssiLCDsegs[qr.rem] ;
Ht1621Data2[5] |= (segs & 0x0E) | 1; // Decimal point
Ht1621Data2[6] |= segs & 0xF0 ;
Ht1621Data1[4] |= 0x20; // "V"
}
void setTopSecondTimer(uint32_t value)
{
div_t qr ;
uint32_t segs ;
uint32_t segs2 ;
qr = div(value, 60);
uint32_t secs = qr.rem;
qr = div(qr.quot, 60);
uint32_t mins = qr.rem;
uint32_t hours = qr.quot;
qr = div(secs, 10) ;
segs = OpTimeLCDsegs[qr.rem] ;
Ht1621Data1[4] |= (segs & 0x0F) | 0x70 ;
segs &= 0x70 ;
segs2 = OpTimeLCDsegs[qr.quot] ;
Ht1621Data1[5] |= segs | (segs2 & 0x0F) ;
qr = div(mins, 10) ;
segs = OpTimeLCDsegs[qr.rem] ;
segs2 &= 0x70 ;
Ht1621Data1[6] |= segs2 | (segs & 0x0F) | 0x80 ; // ":"
segs &= 0x70 ;
segs2 = OpTimeLCDsegs[qr.quot] ;
Ht1621Data1[7] |= segs | (segs2 & 0x0F) ;
qr = div(hours, 10) ;
segs = OpTimeLCDsegs[qr.rem] ;
segs2 &= 0x70 ;
Ht1621Data1[8] |= segs2 | (segs & 0x0F) | 0x80 ; // ":"
segs &= 0x70 ;
segs2 = OpTimeLCDsegs[qr.quot] ;
Ht1621Data1[9] |= segs | (segs2 & 0x0F) ;
Ht1621Data1[10] |= segs2 & 0xF0 ;
}
void topLcdRefreshStart()
{
memset(Ht1621Data1, 0, sizeof(Ht1621Data1));
memset(Ht1621Data2, 0, sizeof(Ht1621Data2));
}
void topLcdRefreshEnd()
{
ht1621WrAllData(0, Ht1621Data1);
ht1621WrAllData(1, Ht1621Data2);
}