X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=src%2Fstm%2Fao_lcd_stm.c;h=47246678210688e09c3794c877c71262979e2844;hp=0f9a8eb53ee4325ab2c55f24be7df6b413a9604d;hb=HEAD;hpb=304909b7534768bfc8da62954effb37ba86806ea diff --git a/src/stm/ao_lcd_stm.c b/src/stm/ao_lcd_stm.c index 0f9a8eb5..47246678 100644 --- a/src/stm/ao_lcd_stm.c +++ b/src/stm/ao_lcd_stm.c @@ -3,7 +3,8 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of @@ -18,6 +19,10 @@ #include #include +#ifndef LCD_DEBUG +#define LCD_DEBUG 0 +#endif + struct ao_lcd_segment { uint8_t reg; uint8_t bit; @@ -37,14 +42,14 @@ static struct stm_gpio *gpios[] = { &stm_gpioe }; -static inline int ao_lcd_stm_seg_enabled(int seg) { +static inline int ao_lcd_stm_seg_enabled(uint32_t seg) { if (seg < 32) return (AO_LCD_STM_SEG_ENABLED_0 >> seg) & 1; else return (AO_LCD_STM_SEG_ENABLED_1 >> (seg - 32)) & 1; } -static inline int ao_lcd_stm_com_enabled(int com) { +static inline int ao_lcd_stm_com_enabled(uint32_t com) { return (AO_LCD_STM_COM_ENABLED >> com) & 1; } @@ -253,12 +258,12 @@ ao_lcd_stm_fcr_sync(void) void ao_lcd_flush(void) { - cli(); + ao_arch_block_interrupts(); ao_lcd_update_active = 1; stm_lcd.sr = (1 << STM_LCD_SR_UDR); while (ao_lcd_update_active) ao_sleep(&ao_lcd_update_active); - sei(); + ao_arch_release_interrupts(); } void @@ -271,35 +276,59 @@ ao_lcd_clear(void) ao_lcd_flush(); } +#ifdef AO_SEGMENT_MAP +#if AO_LCD_PER_DIGIT +static const struct ao_lcd_map { + uint8_t com, seg; +} ao_lcd_map[AO_LCD_DIGITS * AO_LCD_SEGMENTS] = AO_SEGMENT_MAP; +#else +static const uint8_t ao_lcd_map[] = AO_SEGMENT_MAP; +#endif +#endif + void ao_lcd_set(uint8_t digit, uint8_t segment, uint8_t value) { uint8_t n; + uint8_t com, seg; - if (digit >= NCOM) - digit = NCOM-1; - if (segment >= NSEG) - segment = NSEG-1; +#ifdef AO_SEGMENT_MAP +#if AO_LCD_PER_DIGIT + n = (uint8_t) (digit * AO_LCD_SEGMENTS + segment); + com = ao_lcd_map[n].com; + seg = ao_lcd_map[n].seg; +#else + com = digit; + seg = ao_lcd_map[segment]; +#endif +#else + com = digit; + seg = segment; +#endif + if (com >= NCOM) + com = NCOM-1; + if (seg >= NSEG) + seg = NSEG-1; - n = (segment >> 5) & 1; +#if LCD_DEBUG + printf ("digit %d segment %d -> com %d seg %d\n", digit, segment, com, seg); +#endif + n = (seg >> 5) & 1; if (value) - stm_lcd.ram[digit * 2 + n] |= (1 << (segment & 0x1f)); + stm_lcd.ram[com * 2 + n] |= (1UL << (seg & 0x1f)); else - stm_lcd.ram[digit * 2 + n] &= ~(1 << (segment & 0x1f)); + stm_lcd.ram[com * 2 + n] &= ~(1UL << (seg & 0x1f)); } -#if 0 +#if LCD_DEBUG static void ao_lcd_stm_seg_set(void) { int com, seg, val; int n, bit; - ao_cmd_decimal(); - com = ao_cmd_lex_i; - ao_cmd_decimal(); - seg = ao_cmd_lex_u32; - ao_cmd_decimal(); - val = ao_cmd_lex_i; + com = ao_cmd_decimal(); + seg = ao_cmd_decimal(); + val = ao_cmd_decimal(); printf ("com: %d seg: %d val: %d\n", com, seg, val); ao_lcd_set(com, seg, val); ao_lcd_flush(); @@ -307,7 +336,7 @@ ao_lcd_stm_seg_set(void) static const struct ao_cmds ao_lcd_stm_cmds[] = { { ao_lcd_stm_seg_set, "s \0Set LCD segment" }, - { ao_lcd_clear, "C\0Clear LCD" }, + { ao_lcd_clear, "x\0Clear LCD" }, { 0, NULL }, }; #endif @@ -315,15 +344,14 @@ static const struct ao_cmds ao_lcd_stm_cmds[] = { void ao_lcd_stm_init(void) { - int s, c; - int r; + unsigned int s, c; uint32_t csr; - stm_rcc.ahbenr |= ((AO_LCD_STM_USES_GPIOA << STM_RCC_AHBENR_GPIOAEN) | - (AO_LCD_STM_USES_GPIOB << STM_RCC_AHBENR_GPIOBEN) | - (AO_LCD_STM_USES_GPIOC << STM_RCC_AHBENR_GPIOCEN) | - (AO_LCD_STM_USES_GPIOD << STM_RCC_AHBENR_GPIODEN) | - (AO_LCD_STM_USES_GPIOE << STM_RCC_AHBENR_GPIOEEN)); + stm_rcc.ahbenr |= (((uint32_t) AO_LCD_STM_USES_GPIOA << STM_RCC_AHBENR_GPIOAEN) | + ((uint32_t) AO_LCD_STM_USES_GPIOB << STM_RCC_AHBENR_GPIOBEN) | + ((uint32_t) AO_LCD_STM_USES_GPIOC << STM_RCC_AHBENR_GPIOCEN) | + ((uint32_t) AO_LCD_STM_USES_GPIOD << STM_RCC_AHBENR_GPIODEN) | + ((uint32_t) AO_LCD_STM_USES_GPIOE << STM_RCC_AHBENR_GPIOEEN)); stm_rcc.apb1enr |= (1 << STM_RCC_APB1ENR_LCDEN); @@ -411,7 +439,7 @@ ao_lcd_stm_init(void) stm_nvic_set_priority(STM_ISR_LCD_POS, AO_STM_NVIC_LOW_PRIORITY); /* All done */ -#if 0 +#if LCD_DEBUG ao_cmd_register(ao_lcd_stm_cmds); #endif }