Implement 17-segment LEDs for clock (but not turning on the extra segments yet)
authorNick Downing <nick@ndcode.org>
Thu, 24 Mar 2022 10:19:34 +0000 (21:19 +1100)
committerNick Downing <nick@ndcode.org>
Thu, 24 Mar 2022 10:19:34 +0000 (21:19 +1100)
examples/board_clock_7seg/atmega168_clock_7seg.c
examples/board_clock_7seg/clock_7seg.c
examples/board_clock_7seg/led_17seg.py
n.sh

index 0df5299..01f59f3 100644 (file)
@@ -30,6 +30,8 @@
 #include "avr_mcu_section.h"
 AVR_MCU(F_CPU, "atmega168");
 
+#define USE_17SEG 1
+
 PIN_DEFINE(SRESET, D, PD4, 1);
 //PIN_DEFINE(SOE, D, PD6, 1);    // pwm AIN0/OC0A
 PIN_DEFINE(SLATCH, D, PD7, 1);
@@ -38,7 +40,6 @@ PIN_DEFINE(BSTART, C, PC0, 1);  // PCI6
 PIN_DEFINE(BSTOP, B, PB1, 1);  // PCI1
 PIN_DEFINE(BRESET, B, PB0, 1);  // PCI0
 
-
 #define  TICK_HZ          4
 
 enum {
@@ -119,7 +120,11 @@ enum EState {
 } ;
 
 uint8_t state = state_ShowTime | state_IncrementTime;
-uint8_t  digits[4];
+#if USE_17SEG
+uint32_t digits[4];
+#else
+uint8_t digits[4];
+#endif
 
 enum EDecimal {
   d_second = 0, d_10second, d_minute, d_10minute, d_hour, d_10hour, d_100hour, d_MAX
@@ -179,12 +184,37 @@ void decimalInc()
   }
 }
 
+#if USE_17SEG
+
+//   A1 A2
+// F H J K B
+//   G1 G2
+// E N M L C
+//   D1 D2   DP
+const uint16_t digits2led[10] = {
+  //NMLKJHGGFEDDCBAA
+  //      21  21  21
+  0b0000000011111111, // 0
+  0b0000000000001100, // 1
+  0b0000001101110111, // 2
+  0b0000001100111111, // 3
+  0b0000001110001100, // 4
+  0b0000001110111011, // 5
+  0b0000001111111011, // 6
+  0b0000000000001111, // 7
+  0b0000001111111111, // 8
+  0b0000001110001111, // 9
+};
+#define SEG_DP 0b10000000000000000L
+#define SEG_h 0b0000001111001000
+#else
 //   A
 // F   B
 //   G
 // E   C
 //   D   DP
-const uint8_t  digits2led[10]= {
+const uint8_t digits2led[10] = {
+  // GFEDCBA
   0b00111111, // 0
   0b00000110, // 1
   0b01011011, // 2
@@ -196,6 +226,9 @@ const uint8_t  digits2led[10]= {
   0b01111111, // 8
   0b01100111, // 9
 };
+#define SEG_DP 0b10000000
+#define SEG_h 0b01110100
+#endif
 
 struct {
   uint8_t b[16];  
@@ -326,20 +359,34 @@ void updateTimer()
   if (!(state & state_IncrementTime) || timer[delay_Second].delay <= 2) {
     switch (state & ~state_IncrementTime) {
       case state_ShowTime:
-        //digits[1] |= 0x80;
-        digits[2] |= 0x80;
+        //digits[1] |= SEG_DP;
+        digits[2] |= SEG_DP;
         break;
       case state_ShowHour:
         if (state & state_IncrementTime)
-          digits[0] |= 0x80;
+          digits[0] |= SEG_DP;
         break;
     }
   }       
   cli();
   // interupts are stopped here, so there is no race condition
   int restart = spi.out == spi.in;
+#if 0
+ digits[0] = 1;
+ digits[1] = 2;
+ digits[2] = 4;
+ digits[3] = 8;
+#endif
   for (uint8_t bi = 0; bi < 4; bi++)
+#if USE_17SEG
+  {
+    spi.b[spi.out++] = (uint8_t)(digits[bi] >> 16);
+    spi.b[spi.out++] = (uint8_t)(digits[bi] >> 8);
+    spi.b[spi.out++] = (uint8_t)digits[bi];
+  }
+#else
     spi.b[spi.out++] = digits[bi];
+#endif
   if (restart)
     spi_start();
   sei();
@@ -359,8 +406,8 @@ void updateTimerDisplay()
           digits[bi] = digits2led[decimal[bi]];
 
         if (!(state & state_IncrementTime)) {
-          //digits[1] |= 0x80;
-          digits[2] |= 0x80;          
+          //digits[1] |= SEG_DP;
+          digits[2] |= SEG_DP;
         }
       }  break;
       case state_ShowHour: {
@@ -383,7 +430,7 @@ void updateTimerDisplay()
         } else {
           digits[2] = digits2led[decimal[d_hour]];          
         }
-        digits[0] = 116; // 'h'
+        digits[0] = SEG_h; // hours
       }  break;
   //    case state_Sleep: {
         /* nothing to do */
index 370cab1..644fb75 100644 (file)
@@ -41,6 +41,8 @@
 #include "button.h"
 #include "hc595.h"
 
+#define USE_17SEG 1
+
 #define N_DIGITS 4
 #define ORIGIN_X 50.f
 #define ORIGIN_Y 50.f
@@ -57,11 +59,17 @@ button_t button[B_MAX]; // Start/Stop/Reset
 volatile int do_button_press[B_MAX] = {0};
 avr_t * avr = NULL;
 avr_vcd_t vcd_file;
-hc595_t shifter;
+#if USE_17SEG
+#define SHIFTERS_PER_DIGIT 3
+#else
+#define SHIFTERS_PER_DIGIT 1
+#endif
+#define N_SHIFTERS (N_DIGITS * SHIFTERS_PER_DIGIT)
+hc595_t shifters[N_SHIFTERS];
 
 int display_flag = 0;
-volatile uint32_t  display_bits = 0;
-volatile uint8_t  display_pwm = 0;
+volatile uint32_t display_bits[N_DIGITS];
+volatile uint8_t display_pwm = 0;
 
 int window;
 
@@ -73,7 +81,20 @@ int window;
  */
 void hc595_changed_hook(struct avr_irq_t * irq, uint32_t value, void * param)
 {
-  display_bits = value;
+#if 0
+ printf("shifters:\n");
+ for (int i = 0; i < N_SHIFTERS; ++i)
+  printf("%02x: %08x\n", i, shifters[i].value);
+ printf("\n");
+#endif
+  for (int i = 0; i < N_DIGITS; ++i)
+    display_bits[i] = shifters[i * SHIFTERS_PER_DIGIT].value;
+#if 0
+ printf("digits:\n");
+ for (int i = 0; i < N_DIGITS; ++i)
+  printf("%02x: %08x\n", i, display_bits[i]);
+ printf("\n");
+#endif
   display_flag++;
 }
 
@@ -106,17 +127,27 @@ void displayCB(void)    /* function called whenever redisplay needed */
     color_on = color_off;
 
   for (int di = 0; di < 4; di++) {
-    uint8_t digit = display_bits >> (di * 8);
-    
-    for (int i = 0; i < 8; i++) {  
-      glColor3f(0.f, digit & (1 << i) ? color_on : color_off, 0.f);
+    uint32_t bits = display_bits[di];
+
+#if USE_17SEG
+    for (int i = 0; i < 17; i++) {
+#else
+    for (int i = 0; i < 8; i++) {
+#endif
+      glColor3f(0.f, bits & (1 << i) ? color_on : color_off, 0.f);
       float x = ORIGIN_X + di * PITCH_X;
       float y = ORIGIN_Y;
 
       glBegin(GL_POLYGON); //GL_LINE_STRIP);
+#if USE_17SEG
+      int end = led_17seg_ptr[i + 1];
+      for (int j = led_17seg_ptr[i]; j < end; ++j)
+        glVertex2f(x + led_17seg[j][0], y + led_17seg[j][1]);
+#else
       int end = led_8seg_ptr[i + 1];
       for (int j = led_8seg_ptr[i]; j < end; ++j)
         glVertex2f(x + led_8seg[j][0], y + led_8seg[j][1]);
+#endif
       glEnd();
     }
   }
@@ -205,7 +236,8 @@ int main(int argc, char *argv[])
   //
   // initialize our 'peripherals'
   //
-  hc595_init(avr, &shifter);
+  for (int i = 0; i < N_SHIFTERS; ++i)
+    hc595_init(avr, shifters + i);
   
   button_init(avr, &button[B_START], "button.start");
   avr_connect_irq(
@@ -224,19 +256,23 @@ int main(int argc, char *argv[])
   avr_irq_t * i_mosi = avr_io_getirq(avr, AVR_IOCTL_SPI_GETIRQ(0), SPI_IRQ_OUTPUT),
       * i_reset = avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('D'), 4),
       * i_latch = avr_io_getirq(avr, AVR_IOCTL_IOPORT_GETIRQ('D'), 7);
-  avr_connect_irq(i_mosi, shifter.irq + IRQ_HC595_SPI_BYTE_IN);
-  avr_connect_irq(i_reset, shifter.irq + IRQ_HC595_IN_RESET);
-  avr_connect_irq(i_latch, shifter.irq + IRQ_HC595_IN_LATCH);
+  avr_irq_t * i_data = i_mosi;
+  for (int i = 0; i < N_SHIFTERS; ++i) {
+    avr_connect_irq(i_data, shifters[i].irq + IRQ_HC595_SPI_BYTE_IN);
+    avr_connect_irq(i_reset, shifters[i].irq + IRQ_HC595_IN_RESET);
+    avr_connect_irq(i_latch, shifters[i].irq + IRQ_HC595_IN_LATCH);
+    i_data = shifters[i].irq + IRQ_HC595_SPI_BYTE_OUT;
+  }
+  avr_irq_register_notify(
+    i_latch,
+    hc595_changed_hook, 
+    NULL);
 
   avr_irq_t * i_pwm = avr_io_getirq(avr, AVR_IOCTL_TIMER_GETIRQ('0'), TIMER_IRQ_OUT_PWM0);
   avr_irq_register_notify(
     i_pwm,
     pwm_changed_hook, 
     NULL);  
-  avr_irq_register_notify(
-    shifter.irq + IRQ_HC595_OUT,
-    hc595_changed_hook, 
-    NULL);
 
   // even if not setup at startup, activate gdb if crashing
   avr->gdb_port = 1234;
@@ -281,7 +317,7 @@ int main(int argc, char *argv[])
     "reset" );
 
   avr_vcd_add_signal(&vcd_file, 
-    shifter.irq + IRQ_HC595_OUT, 32 /* bits */ ,
+    i_latch, 32 /* bits */ ,
     "HC595" );
   avr_vcd_add_signal(&vcd_file, 
     i_pwm, 8 /* bits */ ,
index 5990677..bcd8a64 100755 (executable)
@@ -16,23 +16,23 @@ origin_y = 400.
 #   sed -ne 's/.* d=\(.*\)/  \1,/p' <led_17seg.svg
 # then reorder segments manually
 paths = [
-  "m 25.135417,47.625005 v 10.58333 H 6.6145817 L -1.6000005e-6,52.916665 6.6145817,47.625005 Z",
-  "M 31.75,7.9375003 V 44.979167 H 21.166667 V 7.9375003 Z",
-  "M 25.135417,-5.2916657 V 5.2916673 H 7.27604 l -7.9374999,-7.9375 1.0583333,-1.058333 1.0583333,-0.79375 1.0583332,-0.529167 1.0583333,-0.264583 z",
-  "m -2.6458348,-0.6614577 7.9374998,7.9375 V 44.979167 l -7.6067707,6.085417 -1.3229167,-1.05833 -0.8598958,-1.05834 -0.5291666,-1.32291 -0.2645834,-1.058338 2e-7,-42.9947907 0.2645833,-1.058333 0.5291667,-1.058334 0.7937499,-1.058333 z",
-  "M 9.5249976,7.9375003 18.520832,26.458332 v 18.520833 h -1.5875 l -8.9958342,-18.520833 2e-7,-18.5208317 z",
-  "m 27.781248,47.625007 v 10.58333 h 18.520834 l 6.614582,-5.29167 -6.614582,-5.29166 z",
-  "m 27.781248,-5.2916637 v 10.583333 h 17.859376 l 7.937499,-7.9375 -1.058333,-1.058333 -1.058334,-0.79375 -1.058332,-0.529167 -1.058333,-0.264583 z",
-  "m 55.562498,-0.6614557 -7.937499,7.9375 V 44.979169 l 7.60677,6.085417 1.322916,-1.058329 0.859896,-1.05834 0.529167,-1.32291 0.264583,-1.058338 V 3.5718773 l -0.264583,-1.058333 -0.529167,-1.058334 -0.79375,-1.058333 z",
-  "M 43.391666,7.9375023 34.395833,26.458334 v 18.520833 h 1.587499 L 44.979166,26.458334 V 7.9375023 Z",
-  "M 31.75,97.895828 V 60.854166 H 21.166667 v 37.041662 z",
-  "M 25.135417,111.12499 V 100.54166 H 7.2760392 l -7.9375,7.9375 1.058333,1.05833 1.058334,0.79375 1.058333,0.52917 1.058333,0.26458 z",
-  "m -2.6458358,106.49478 7.9375,-7.937495 V 60.854166 l -7.606771,-6.085417 -1.322916,1.05833 -0.859896,1.05834 -0.529167,1.32291 -0.264583,1.058337 v 42.994784 l 0.264583,1.05833 0.529167,1.05834 0.79375,1.05833 z",
-  "m 9.5249976,97.895828 8.9958344,-18.52083 v -18.52083 h -1.5875 l -8.9958348,18.52083 v 18.52083 z",
-  "m 27.781248,111.12499 v -10.58333 h 17.859376 l 7.937499,7.93749 -1.058333,1.05834 -1.058334,0.79375 -1.058332,0.52916 -1.058333,0.26459 z",
-  "M 55.562498,106.49478 47.624999,98.557283 V 60.854164 l 7.60677,-6.085417 1.322916,1.05833 0.859896,1.05834 0.529167,1.32291 0.264583,1.058337 v 42.994786 l -0.264583,1.05833 -0.529167,1.05833 -0.79375,1.05834 z",
-  "m 43.391666,97.895826 -8.995833,-18.52083 v -18.52083 h 1.587499 l 8.995834,18.52083 v 18.52083 z",
-  "m 69.849999,100.54166 1.852083,0.79375 1.5875,1.5875 0.79375,1.85209 v 2.11666 l -0.79375,1.85209 -1.5875,1.5875 -1.852083,0.79375 -2.116667,0 -1.852083,-0.79375 -1.5875,-1.5875 -0.79375,-1.85209 0,-2.11666 0.79375,-1.85208 1.5875,-1.5875 1.852083,-0.79376 z",
+  "M 25.135417,-5.2916657 V 5.2916673 H 7.27604 l -7.9374999,-7.9375 1.0583333,-1.058333 1.0583333,-0.79375 1.0583332,-0.529167 1.0583333,-0.264583 z", # A1
+  "m 27.781248,-5.2916637 v 10.583333 h 17.859376 l 7.937499,-7.9375 -1.058333,-1.058333 -1.058334,-0.79375 -1.058332,-0.529167 -1.058333,-0.264583 z", # A2
+  "m 55.562498,-0.6614557 -7.937499,7.9375 V 44.979169 l 7.60677,6.085417 1.322916,-1.058329 0.859896,-1.05834 0.529167,-1.32291 0.264583,-1.058338 V 3.5718773 l -0.264583,-1.058333 -0.529167,-1.058334 -0.79375,-1.058333 z", # B
+  "M 55.562498,106.49478 47.624999,98.557283 V 60.854164 l 7.60677,-6.085417 1.322916,1.05833 0.859896,1.05834 0.529167,1.32291 0.264583,1.058337 v 42.994786 l -0.264583,1.05833 -0.529167,1.05833 -0.79375,1.05834 z", # C
+  "M 25.135417,111.12499 V 100.54166 H 7.2760392 l -7.9375,7.9375 1.058333,1.05833 1.058334,0.79375 1.058333,0.52917 1.058333,0.26458 z", # D1
+  "m 27.781248,111.12499 v -10.58333 h 17.859376 l 7.937499,7.93749 -1.058333,1.05834 -1.058334,0.79375 -1.058332,0.52916 -1.058333,0.26459 z", # D2
+  "m -2.6458358,106.49478 7.9375,-7.937495 V 60.854166 l -7.606771,-6.085417 -1.322916,1.05833 -0.859896,1.05834 -0.529167,1.32291 -0.264583,1.058337 v 42.994784 l 0.264583,1.05833 0.529167,1.05834 0.79375,1.05833 z", # E
+  "m -2.6458348,-0.6614577 7.9374998,7.9375 V 44.979167 l -7.6067707,6.085417 -1.3229167,-1.05833 -0.8598958,-1.05834 -0.5291666,-1.32291 -0.2645834,-1.058338 2e-7,-42.9947907 0.2645833,-1.058333 0.5291667,-1.058334 0.7937499,-1.058333 z", # F
+  "m 25.135417,47.625005 v 10.58333 H 6.6145817 L -1.6000005e-6,52.916665 6.6145817,47.625005 Z", # G1
+  "m 27.781248,47.625007 v 10.58333 h 18.520834 l 6.614582,-5.29167 -6.614582,-5.29166 z", # G2
+  "M 9.5249976,7.9375003 18.520832,26.458332 v 18.520833 h -1.5875 l -8.9958342,-18.520833 2e-7,-18.5208317 z", # H
+  "M 31.75,7.9375003 V 44.979167 H 21.166667 V 7.9375003 Z", # J
+  "M 43.391666,7.9375023 34.395833,26.458334 v 18.520833 h 1.587499 L 44.979166,26.458334 V 7.9375023 Z", # K
+  "m 43.391666,97.895826 -8.995833,-18.52083 v -18.52083 h 1.587499 l 8.995834,18.52083 v 18.52083 z", # L
+  "M 31.75,97.895828 V 60.854166 H 21.166667 v 37.041662 z", # M
+  "m 9.5249976,97.895828 8.9958344,-18.52083 v -18.52083 h -1.5875 l -8.9958348,18.52083 v 18.52083 z", # N
+  "m 69.849999,100.54166 1.852083,0.79375 1.5875,1.5875 0.79375,1.85209 v 2.11666 l -0.79375,1.85209 -1.5875,1.5875 -1.852083,0.79375 -2.116667,0 -1.852083,-0.79375 -1.5875,-1.5875 -0.79375,-1.85209 0,-2.11666 0.79375,-1.85208 1.5875,-1.5875 1.852083,-0.79376 z", # DP
 ]
 
 led_17seg = []
diff --git a/n.sh b/n.sh
index 7ba53f4..614efec 100755 (executable)
--- a/n.sh
+++ b/n.sh
@@ -1,3 +1,3 @@
 #!/bin/sh
-apt install libelf-dev gcc-avr binutils-avr avr-libc gdb-avr avrdude freeglut3-dev
+#apt install libelf-dev gcc-avr binutils-avr avr-libc gdb-avr avrdude freeglut3-dev
 make install DESTDIR=$HOME