Add more files to the repo.
authorWerner Koch <wk@gnupg.org>
Tue, 9 Aug 2011 19:32:16 +0000 (21:32 +0200)
committerWerner Koch <wk@gnupg.org>
Tue, 9 Aug 2011 19:32:16 +0000 (21:32 +0200)
The modulo-d-amp is the source code from an Elektor project.  Not all
files make any sense, they may be just something I used for testing.
The gnus and nnml files were used to convert a large set of nnml file
into Maildirs for use with an imapserver.

24 files changed:
atmegatest.c [new file with mode: 0644]
bbdb-vcard-export.el [new file with mode: 0644]
cp-nnml2maildir [new file with mode: 0644]
ebusnode1-ee.hex [new file with mode: 0644]
ebusnode1.c [new file with mode: 0644]
heating-daemon.c [new file with mode: 0644]
hkpstats.c [new file with mode: 0644]
modulo-d-amp/License.txt [new file with mode: 0644]
modulo-d-amp/Makefile [new file with mode: 0644]
modulo-d-amp/common.h [new file with mode: 0644]
modulo-d-amp/iic.c [new file with mode: 0644]
modulo-d-amp/iic.h [new file with mode: 0644]
modulo-d-amp/lcd.c [new file with mode: 0644]
modulo-d-amp/lcd.h [new file with mode: 0644]
modulo-d-amp/main.c [new file with mode: 0644]
modulo-d-amp/main.h [new file with mode: 0644]
modulo-d-amp/max9744.c [new file with mode: 0644]
modulo-d-amp/max9744.h [new file with mode: 0644]
modulo-d-amp/rc5.c [new file with mode: 0644]
modulo-d-amp/rc5.h [new file with mode: 0644]
modulo-d-amp/tda7449.c [new file with mode: 0644]
modulo-d-amp/tda7449.h [new file with mode: 0644]
mv-nnml2maildir [new file with mode: 0755]
readgnusmarks.c [new file with mode: 0644]

diff --git a/atmegatest.c b/atmegatest.c
new file mode 100644 (file)
index 0000000..6ce50e0
--- /dev/null
@@ -0,0 +1,949 @@
+/* atmegatest.c - Test code for an ATmega32 board
+   Copyright (C) 2010 Werner Koch
+   
+
+   This code uses some code lifted from heating-control.c.  All that
+   code has been been written from scratch. 
+
+   2010-02-08 wk  The LCD code has been written from scratch for
+                  heating-control.c
+
+   2010-09-20 wk  Use AT like commands to request data.  From
+                  heating-control.c.
+
+   2010-10-31 wk  Initial code for atmegattest.c
+
+  */
+
+
+/* Clock frequency in Hz. */
+#define F_CPU 8000000UL
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <util/delay.h>
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <avr/interrupt.h>
+#include <avr/eeprom.h>
+#include <avr/sleep.h>
+
+
+#define DIM(v)              (sizeof(v)/sizeof((v)[0]))
+
+
+/* Display definitions.  */
+#define LCD_DDR          DDRC         /* DDR for the LCD pins.   */
+#define LCD_PORT         PORTC        /* Port for the LCD pins.  */
+#define LCD_PIN          PINC         /* Pin for the LCD pins.   */
+#define LCD_RS_PIN       0            /* Pin # for RS.           */
+#define LCD_RW_PIN       1            /* Pin # for RW.           */
+#define LCD_E_PIN        2            /* Pin # for Enable line.  */
+#define LCD_DATA0_PIN    4            /* Pin # for data bit 0.   */
+#define LCD_DATA1_PIN    5            /* Pin # for data bit 1.   */
+#define LCD_DATA2_PIN    6            /* Pin # for data bit 2.   */
+#define LCD_DATA3_PIN    7            /* Pin # for data bit 3.   */
+#define LCD_DATA_MASK    0b11110000   /* Mask for the data pins. */ 
+#define LCD_PIN_MASK     0b11110111   /* Mask for all used pins. */ 
+
+/* Onewire definitions.  */
+#define ONEWIRE_DDR      DDRD
+#define ONEWIRE_PORT     PORTD
+#define ONEWIRE_PIN      PIND
+#define ONEWIRE_BIT      4
+
+
+
+/* UART defs.  */
+#define BAUD       9600ul
+#define UBRR_VAL   ((F_CPU+8*BAUD)/(16*BAUD)-1)
+#define BAUD_REAL  (F_CPU/(16*(UBRR_VAL+1)))
+#define BAUD_ERROR ((1000*BAUD_REAL)/BAUD)
+#if (BAUD_ERROR < 990 || BAUD_ERROR > 1010)
+# error computed baud rate out of range
+#endif
+
+
+
+/* The current time measured in seconds.  */
+volatile unsigned int current_time;
+
+/* /\* IR interrupt counter.  *\/ */
+/* volatile unsigned int ir_int_counter; */
+
+/* The current atcommand if any and a flag indicating that an AT
+   command is currently processed.  During the time of procewssing an
+   AT command all input is ignored.  */
+volatile char atcommand[16];
+volatile char run_atcommand;
+
+/* Set to one (e.g. the timer int) to wakeup the main loop.  */
+volatile char wakeup_main;
+
+/* Set to one to refresh the LCD readout.  */
+volatile char refresh_lcd;
+
+
+
+\f
+/* 
+    The LCD code. 
+ */
+static void lcd_load_user_glyphs (void);
+
+void lcd_delay_ms(uint8_t ms) {  _delay_ms (ms); }
+#define delay_ms(ms)      _delay_ms ((ms))
+
+/* Despite what the Displaytech docs and several examples say, the
+   disassembly of the original code of this program shows that 42
+   cycles are used.  We use the provided delay loop which runs at 3
+   cycles and ignore that gcc does need all the 7 cycles for the setup
+   (rcall, ldi, ret).  */
+#define _lcd_e_delay()   do { _delay_loop_1 (15); } while (0)
+#define _lcd_e_high()    do { LCD_PORT  |=  _BV(LCD_E_PIN); } while (0)
+#define _lcd_e_low()     do { LCD_PORT  &= ~_BV(LCD_E_PIN); } while (0)
+#define _lcd_e_toggle()  do {                  \
+                            _lcd_e_high ();    \
+                            _lcd_e_delay ();   \
+                            _lcd_e_low ();     \
+                         } while (0)
+#define _lcd_rw_high()   do { LCD_PORT |=  _BV(LCD_RW_PIN); } while (0)
+#define _lcd_rw_low()    do { LCD_PORT &= ~_BV(LCD_RW_PIN); } while (0)
+#define _lcd_rs_high()   do { LCD_PORT |=  _BV(LCD_RS_PIN); } while (0)
+#define _lcd_rs_low()    do { LCD_PORT &= ~_BV(LCD_RS_PIN); } while (0)
+#define _lcd_waitbusy()  do { while (_lcd_read (1) & 0x80); } while (0)
+
+/* Send a command to the LCD.  */
+#define lcd_command(cmd) do {                      \
+                              _lcd_waitbusy ();    \
+                              _lcd_write (cmd, 1); \
+                         } while (0)
+
+/* Write a data byte to the display.  */
+#define lcd_putc(c)      do {                      \
+                              _lcd_waitbusy ();    \
+                              _lcd_write (c, 0);   \
+                         } while (0)
+
+
+/* Clear the display.  */
+#define lcd_clear()  lcd_command (0x01);
+
+/* Got to the home position.  */
+#define lcd_home()   lcd_command (0x02);
+
+
+static uint8_t
+_lcd_read (uint8_t read_ctrl)
+{
+  uint8_t value = 0;
+
+  if (read_ctrl)
+    _lcd_rs_low (); 
+  else
+    _lcd_rs_high (); 
+  _lcd_rw_high ();
+
+  /* Configure data pins as input.  */
+  LCD_DDR &= ~LCD_DATA_MASK;
+
+  /* Read high nibble.  */
+  _lcd_e_high ();
+  _lcd_e_delay ();
+  if (bit_is_set (LCD_PIN, LCD_DATA0_PIN))
+    value |= 0x10;
+  if (bit_is_set (LCD_PIN, LCD_DATA1_PIN))
+    value |= 0x20;
+  if (bit_is_set (LCD_PIN, LCD_DATA2_PIN))
+    value |= 0x40;
+  if (bit_is_set (LCD_PIN, LCD_DATA3_PIN))
+    value |= 0x80;
+  _lcd_e_low ();
+
+  _lcd_e_delay ();
+
+  /* Read low nibble */
+  _lcd_e_high ();
+  _lcd_e_delay ();
+  if (bit_is_set (LCD_PIN, LCD_DATA0_PIN))
+    value |= 0x01;
+  if (bit_is_set (LCD_PIN, LCD_DATA1_PIN))
+    value |= 0x02;
+  if (bit_is_set (LCD_PIN, LCD_DATA2_PIN))
+    value |= 0x04;
+  if (bit_is_set (LCD_PIN, LCD_DATA3_PIN))
+    value |= 0x08;
+  _lcd_e_low ();
+
+  /* Set data bits to output and set them to high. */
+  LCD_PORT |= LCD_DATA_MASK;
+  LCD_DDR  |= LCD_DATA_MASK;
+
+  _lcd_rw_low ();
+  return value;
+}
+
+
+static void
+_lcd_write (uint8_t value, uint8_t write_ctrl)
+{
+  uint8_t data;
+
+  if (write_ctrl)
+    _lcd_rs_low ();
+  else
+    _lcd_rs_high ();
+  _lcd_rw_low ();
+
+  /* Configure data pins as output.  */
+  LCD_DDR |= LCD_DATA_MASK;
+
+  /* Write high nibble.  */
+  data = 0;
+  if ((value & 0x80))
+    data |= _BV (LCD_DATA3_PIN);
+  if ((value & 0x40))
+    data |= _BV (LCD_DATA2_PIN);
+  if ((value & 0x20))
+    data |= _BV (LCD_DATA1_PIN);
+  if ((value & 0x10))
+    data |= _BV (LCD_DATA0_PIN);
+  LCD_PORT &= ~LCD_DATA_MASK;
+  LCD_PORT |= data;
+  _lcd_e_toggle ();
+
+  /* Write low nibble.  */
+  data = 0;
+  if ((value & 0x08))
+    data |= _BV (LCD_DATA3_PIN);
+  if ((value & 0x04))
+    data |= _BV (LCD_DATA2_PIN);
+  if ((value & 0x02))
+    data |= _BV (LCD_DATA1_PIN);
+  if ((value & 0x01))
+    data |= _BV (LCD_DATA0_PIN);
+  LCD_PORT &= ~LCD_DATA_MASK;
+  LCD_PORT |= data;
+  _lcd_e_toggle ();
+
+  /* Set data bits to high. */
+  LCD_PORT |= LCD_DATA_MASK;
+}
+
+
+
+/* Init the LCD to 4 bit mode.  */
+void
+lcd_init (void)
+{
+  /* Configure all used pins as output and clear them.  */
+  LCD_PORT &= ~LCD_PIN_MASK;
+  LCD_DDR |= LCD_PIN_MASK;
+
+  /* RS is cleared to send a command; cmd = 0x03.
+     Command must be repeated two times.  */
+  lcd_delay_ms (15);
+  LCD_PORT |= (_BV (LCD_DATA1_PIN) | _BV (LCD_DATA0_PIN));
+  _lcd_e_toggle ();
+  lcd_delay_ms (5);
+  _lcd_e_toggle ();
+  lcd_delay_ms (1);
+  _lcd_e_toggle ();
+  lcd_delay_ms (1);
+
+  /* Select 4 bit mode.  */
+  LCD_PORT &= ~LCD_PIN_MASK;
+  LCD_PORT |= _BV (LCD_DATA1_PIN);
+  _lcd_e_toggle ();
+  lcd_delay_ms (1);
+
+  /* Set function: 4bit,     2 lines,  5x7.     */
+  /*               (bit 4=0) (bit 3=1) (bit2=0) */ 
+  lcd_command (0x20 | 8 );
+
+  /* Display off.  */
+  lcd_command (0x08);
+  /* Display clear.  */
+  lcd_command (0x01);
+  /* Entry mode set: increase cursor, display is not shifted */
+  /*                 (bit 1)          ( bit 0)               */
+  lcd_command (0x04 | 2 );
+
+  /* Display is now ready. Switch it on.  */
+
+  /* Display on/off: Display on, cursor off, blinking off.  */
+  /*                 (bit 2)     (bit 1)     (bit 0)        */
+  lcd_command (0x08 | 4 );
+
+  lcd_load_user_glyphs ();
+}
+
+
+/* Load our special glyphs (from heating-control.c).  */
+static void
+lcd_load_user_glyphs (void)
+{
+  static const PROGMEM char glyphs[5][8] =
+    {
+      { /* glyph 0 - moon */
+        0b0000000,
+        0b0000000,
+        0b0001110,  
+        0b0011110,
+        0b0011110,
+        0b0001110,
+        0b0000000,
+        0b0000000
+      },
+      { /* glyph 1 - sun */
+        0b0000100,
+        0b0010101,
+        0b0001110,
+        0b0010001,
+        0b0010001,
+        0b0001110,
+        0b0010101,
+        0b0000100
+      },
+      { /* glyph 2 - circle */
+        0b0000000,
+        0b0000000,
+        0b0001110,
+        0b0010001,
+        0b0010001,
+        0b0001110,
+        0b0000000,
+        0b0000000
+      },
+      { /* glyph 3 - up arrow */
+        0b0000000,
+        0b0000100,
+        0b0001110,
+        0b0010101,
+        0b0000100,
+        0b0000100,
+        0b0000100,
+        0b0000000
+      },
+      { /* glyph 4 - down arrow */
+        0b0000000,
+        0b0000100,
+        0b0000100,
+        0b0000100,
+        0b0010101,
+        0b0001110,
+        0b0000100,
+        0b0000000
+      }
+    };
+  unsigned char idx, g, row;
+
+  for (idx=0; idx < DIM (glyphs); idx++)
+    {
+      lcd_command ((0x80 | idx)); /* Set DDRAM address.  */
+      g = (0x40 | (idx * 8));     /* First Set CGRAM command. */
+      for (row=0; row < 8; row++)
+        {
+          lcd_command (g++);
+          lcd_putc (pgm_read_byte (&glyphs[idx][row]));
+        }
+    }
+}
+
+
+/* Set the next data write position to X,Y.  */
+void
+lcd_gotoxy (uint8_t x, uint8_t y)
+{
+  lcd_command (0x80 | ((y? 0x40:0) + x));
+}
+
+
+uint8_t
+lcd_getc (void)
+{
+  _lcd_waitbusy ();
+  return _lcd_read (0);
+}
+
+void
+lcd_puts (const char *s)
+{
+  uint8_t c;
+  
+  while ((c = *s++))
+    lcd_putc (c);
+}
+
+
+#define lcd_puts_P(s)  _lcd_puts_P (PSTR ((s)))
+void
+_lcd_puts_P (const char *progmem_s)
+{
+  uint8_t c;
+  
+  while ((c = pgm_read_byte (progmem_s++)))
+    lcd_putc (c);
+}
+
+
+
+\f
+#define lcd_int(w, a, p)   format_int (0, (w), (a), (p))
+#define uart_int(w, a, p)  format_int (1, (w), (a), (p))
+
+void
+uart_putc (char c)
+{
+  while (!bit_is_set (UCSRA, UDRE))
+    ;
+  UDR = c;
+}                                              
+
+
+void
+uart_puts (const char *s)
+{
+  uint8_t c;
+  
+  while ((c = *s++))
+    {
+      if (c == '\n')
+        uart_putc ('\r');
+      uart_putc (c);
+    }
+}
+
+#define uart_puts_P(s)  _uart_puts_P (PSTR ((s)))
+void
+_uart_puts_P (const char *progmem_s)
+{
+  uint8_t c;
+  
+  while ((c = pgm_read_byte (progmem_s++)))
+    {
+      if (c == '\n')
+        uart_putc ('\r');
+      uart_putc (c);
+    }
+}
+
+
+void
+do_putchar (char destination, char c)
+{
+  if (destination)
+    uart_putc (c);
+  else
+    lcd_putc (c);
+}                                              
+
+
+void
+format_int (char output, signed int value, signed char width,
+            signed char precision)
+{
+  unsigned int table[] = {0,1,10,100,1000,10000,32767};
+  signed char i;
+  unsigned char pos, zero;  
+  char nowidth = 0;
+   
+  if (width < 0)                         
+    {
+      width = - width;
+      if (value < 0) 
+        {
+          value = -value;
+          do_putchar (output, '-');
+        }
+      else
+        do_putchar (output, '+');                    
+    }
+  else if (!width)
+    {
+      width = 5;
+      nowidth = 1;
+      if (value < 0)
+        {
+          value = -value;
+          do_putchar (output, '-');
+        }
+    }
+
+  if (precision > width || width > 5)
+    {
+      for (i=0; i < width; i++)
+        do_putchar (output, '?');
+      return;                            
+    }
+  
+  if (value >= table[width + 1])     
+    {
+      for (i=0; i < width; i++)
+        do_putchar (output, '?');
+      return;                            
+    }
+  
+  zero = (precision < 0);
+  
+  for (i=width; i > 0; i--)
+    {
+      if (i == precision)
+        {
+          do_putchar (output, '.');
+          zero = 1;
+        } 
+      pos = '0' + (value / table[i]);
+      
+      if ((pos == '0') && !zero && i != 1)
+        {
+          if (!nowidth)
+            do_putchar (output, (i == precision+1)? '0':' ');
+        }
+      else
+        {
+          zero = 1;                        
+          do_putchar (output, pos);
+          value %= table[i];            
+        }
+    }   
+}
+
+
+/*
+   Interrupt service routines
+ */
+
+
+/* 1ms ticker interrupt service routine. */
+ISR (TIMER2_COMP_vect)
+{
+  static unsigned int clock; /* Milliseconds of the current minute.  */
+  
+  clock++;
+
+  if (clock == 1000) 
+   {
+     /* One second has passed.  Bump the current time.  */
+     current_time++; 
+     clock = 0; 
+   } 
+
+  /* Run the main loop every 35ms.  */
+  if (!(clock % 35))
+    {
+      wakeup_main = 1;
+
+      /* Request an LCD refresh every 350ms.  */
+      if (!(clock % 350))
+        refresh_lcd = 1;
+    }      
+
+}
+
+
+/* UART transmit interrupt service routine.  */
+ISR (USART_TXC_vect)
+{
+  /* Nothing to do.  */
+}
+
+
+/* UART receive interrupt service routine.  */
+ISR (USART_RXC_vect)
+{
+  static uint8_t state;
+  static uint8_t bufidx;
+  uint8_t c = UDR;
+
+  switch (state)
+    {
+    case 0:
+      if (c == '\r')
+        state = 1;
+      break;
+    case 4:
+      if (run_atcommand)
+        break;
+      state = 1;
+      /*FALLTHRU*/
+    case 1:
+      if (c == 'A' || c == 'a')
+        state = 2;
+      else if (c == '\n')
+        ;
+      else
+        state = 0;
+      break;
+    case 2: 
+      if (c == 'T' || c == 't')
+        {
+          state = 3;
+          bufidx = 0;
+        }
+      else if (c == '/') /* Repeat last command.  */
+        {
+          run_atcommand = 1;
+          state = 4;
+        }
+      else
+        state = 0;
+      break;
+    case 3:
+      if (c == '\r')
+        {
+          atcommand[bufidx] = 0;
+          run_atcommand = 1;
+          state = 4;
+        }
+      else if (bufidx < sizeof atcommand - 1)
+        atcommand[bufidx++] = c;
+      break;
+    }
+}
+
+
+/* Triggered by the infrared sensor.  */
+/* ISR (INT0_vect) */
+/* { */
+/*   ir_int_counter++; */
+/*   GIFR   |= 0x40; */
+/* } */
+
+\f
+/* 
+
+   Dallas One Wire Protocol
+
+ */
+
+#define _onewire_high()     do { ONEWIRE_PORT |=  _BV(ONEWIRE_BIT); } while (0)
+#define _onewire_low()      do { ONEWIRE_PORT &= ~_BV(ONEWIRE_BIT); } while (0)
+#define _onewire_read()     (!!(ONEWIRE_PIN & _BV(ONEWIRE_BIT)))
+#define _onewire_conf_out() do { ONEWIRE_DDR |= _BV(ONEWIRE_BIT); } while (0)
+#define _onewire_conf_in()  do { ONEWIRE_DDR &= ~_BV(ONEWIRE_BIT); } while (0)
+
+/* Reset the 1-Wire bus.  Return 0 on success.  */
+unsigned char 
+onewire_reset (void)
+{
+  unsigned char result;
+       
+  /* First disable the internal pull-up as we don't want it for the
+     read operations.  This is done by setting the port to 0.  */
+  _onewire_low ();
+  /* Now set the pin to output and keep it low for at least 480us.
+     This resets the bus. */
+  onewire_conf_out ();
+  delay_us (480);
+       
+  /* Set pin to input and wait for clients.  Clients are expected to
+     detect the rising edge which due to the external pull-up and
+     configuring the pin to input.  A client needs to wait for 15 to
+     60us before pulling the bus low for 60 to 240us to emit its
+     presence pulse.  */
+  ATOMIC_BLOCK (ATOMIC_FORCEON)
+    {
+      onewire_conf_in ();
+      delay_us (66);
+      result = _onewire_read ();
+    }
+  if (result)
+    return 1; /* No client pulled it down.  */
+
+  /* If RESULT is low a client pulled it down.  Check that the clients
+     release the pull down.  */
+  delay_us (480-66);
+  if (!_onewire_read ())
+    return 2; /* Nope.  */
+       
+  return 0; /* Success */
+}
+
+
+
+
+
+
+
+\f
+/* 
+   AT command handler
+
+*/
+
+
+/* Run an AT command found in ATCOMMAND.  Returns 0 on success or true
+   on error. */
+static char
+do_atcommand (void)
+{
+  static char cmd[16];
+  static char echo_mode;
+  uint8_t i, c;
+
+  for (i=0; (c=atcommand[i]) && i < sizeof cmd -1; i++)
+    cmd[i] = c;
+  cmd[i] = c;
+
+  if (echo_mode)
+    {
+      uart_puts_P ("AT");
+      uart_puts (cmd);
+      uart_puts_P ("\r\n");
+    }
+
+  if (!*cmd)
+    ;
+  else if (*cmd == 'i' || *cmd == 'I')
+    uart_puts_P ("Heating Control (AT&H for help)\r\n");
+  else if (*cmd == 'e' || *cmd == 'E')
+    echo_mode = (cmd[1] == '1');
+  else if (*cmd == '&')
+    {
+      if (cmd[1] == 'h' || cmd[1] == 'H')
+        {
+          uart_puts_P (" ATI  - info\r\n"
+                       " ATEn - switch local echo on/off\r\n"
+                       " AT&H - this help page\r\n"
+                       " AT+H - list history\r\n"
+                       " AT+C - list configuration\r\n"
+                       " AT+Ln - switch display light on/off\r\n"
+                       " AT+Mn - switch monitor mode on/off\r\n"
+                       " AT+TIME=<min> - set system time to MIN\r\n");
+        }
+      else
+        return 1;
+    }
+  else if (*cmd == '+')
+    {
+      if (cmd[1] == 'h' || cmd[1] == 'H')
+        ;
+      else if (cmd[1] == 'l' || cmd[1] == 'L')
+        ;
+      else if ((cmd[1] == 'c' || cmd[1] == 'C') && !cmd[2])
+        ;
+      else if (cmd[1] == 'm' || cmd[1] == 'M')
+        ;
+      else if (cmd[1] == 'T' && cmd[2] == 'I' && cmd[3] == 'M'
+               && cmd[4] == 'E' && cmd[5] == '=' && cmd[6])
+        ;
+      else
+        return 1;
+    }
+  else 
+    return 1;
+  return 0; /* Okay.  */
+}
+
+
+/*
+    Entry point
+ */
+int
+main (void)
+{
+  /* The port settings are lifted from heating-control.c, unconnected
+     devices removed and new devices added.  */
+
+
+  /* Port A: Pins 0..7 to input. 
+     PINA.7 = KEY-1
+     PINA.6 = KEY-2
+     PINA.5 = KEY-3
+     PINA.4 = KEY-4
+     PINA.3 = KEY-5
+     PINA.2 = ADC2 = PA-2
+     PINA.1 = ADC1 = PA-1
+     PINA.0 = ADC0 = AIN-1
+  */
+  PORTA = 0x00;
+  DDRA  = 0x00;
+
+  /* Port B: Pins 0..4 to output, pins 5..7 to input.
+     PINB.7  = SCK
+     PINB.6  = MISI
+     PINB.5  = MOSI
+     PORTB.4 = 
+     PORTB.3 = 
+     PORTB.2 = 
+     PORTB.1 = 
+     PORTB.0 = 
+  */
+  PORTB = 0x00;
+  DDRB  = 0x1f;
+
+  /* Port C: Pins 0..7 to input. 
+     PINC.7 = LCD_DATA3_PIN
+     PINC.6 = LCD_DATA2_PIN
+     PINC.5 = LCD_DATA1_PIN
+     PINC.4 = LCD_DATA0_PIN
+     PINC.3 = 
+     PINC.2 = LCD_EN
+     PINC.1 = LCD_RW
+     PINC.0 = LCD_RS
+  */
+  PORTC = 0x00;
+  DDRC  = 0x00;
+
+  /* Port D: Pins 0..7 to input.
+     PIND.7 = 
+     PIND.6 = 
+     PIND.5 = 
+     PIND.4 = OneWire
+     PIND.3 = 
+     PIND.2 = IR (SFH506, pin3) 
+     PIND.1 = TXD
+     PIND.0 = RXD
+  */
+  PORTD = 0x00;
+  DDRD  = 0x00;
+
+
+  /* Init timer/counter 0 to:
+   * Clock source: system clock.
+   * Clock value: timer 0 stopped.
+   * Mode: normal top = 0xff.
+   * OC0 output: disconnected.
+   */
+  TCCR0 = 0x02;
+  TCNT0 = 0x64;
+  OCR0  = 0x00;
+
+  /* Init timer/counter 1 to:
+   * Clock source: system clock.
+   * Clock value: timer 1 stopped
+   * Mode: normal top = 0xffff
+   * OC1A output: disconnected.
+   * OC1B output: disconnected.
+   * Noise canceler: off.
+   * Input capture on falling edge.
+   */
+  TCCR1A = 0x00;
+  TCCR1B = 0x00;
+  TCNT1H = 0x00;
+  TCNT1L = 0x00;
+  OCR1AH = 0x00;
+  OCR1AL = 0x00;
+  OCR1BH = 0x00;
+  OCR1BL = 0x00;
+
+  /* Init timer/counter 2 to:
+   * Clock source: system clock.
+   * Clock value: 125.000 kHz.
+   * Mode: normal top = 0xff.
+   * OC2 output: disconnected.
+   */
+  ASSR  = 0x00;
+  TCCR2 = 0x0c;
+  TCNT2 = 0x00;
+  OCR2  = 124;     /*  1ms  */
+
+  /* Init external interrupts.  */
+  /* GICR  |= 0x40;  /\* Enable Int0.  *\/ */
+  /* MCUCR |= 0x02;  /\* Trigger on falling edge.  *\/ */
+  /* GIFR  |= 0x40;  /\* Clear Int0 flag.  *\/ */
+#ifdef USE_TURN_PUSH
+  GICR  |= 0x80;  /* Enable Int1.  */
+  MCUCR |= 0x08;  /* Trigger on falling edge.  */
+  GIFR  |= 0x80;  /* Clear Int1 flag.  */
+#endif
+
+  /* Init timer/counter interrupts.  */
+  TIMSK = 0x80;
+
+  /* Set the UART: 8n1, async, rc and tx on, rx and tx ints enabled.
+     Baud rate set to the value computed from BAUD.  */
+  UCSRA = 0x00;
+  UCSRB = _BV(RXCIE) | _BV(TXCIE) | _BV(RXEN) | _BV(TXEN);
+  UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);
+  UBRRH = (UBRR_VAL >> 8);
+  UBRRL = (UBRR_VAL & 0xff);
+
+  /* Init the analog comparator:
+   * Analog comparator: off (ACSR.7 = 1)
+   * Input capture by timer/counter 1: off.
+   * Analog comparator output: off
+   */
+  ACSR  = 0x80;
+  SFIOR = 0x00;
+
+  /* Init the ADC:
+   * Enable, Single conversion.
+   * Prescaler = 64 (at 8Mhz => 125kHz).
+   */
+  ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1);
+
+  /* Prepare the LCD.  */
+  lcd_init ();
+
+  /*           1234567890123456 */
+  lcd_gotoxy (0, 0);
+  lcd_puts_P ("LCD Ready.");
+  delay_ms (1000);
+  lcd_clear ();
+
+  /* Enable interrupts.  */
+  sei ();
+
+  /* Main loop.  */
+  for (;;)
+   {
+     while (!wakeup_main)
+       {
+         set_sleep_mode (SLEEP_MODE_IDLE);
+         cli();
+         if (!wakeup_main)
+           {
+             sleep_enable ();
+             sei ();
+             sleep_cpu ();
+             sleep_disable ();
+           }
+         sei ();
+       }
+     wakeup_main = 0;
+
+     if (refresh_lcd)
+       {
+         lcd_gotoxy (0, 0);
+         lcd_int (current_time/3600, 2, 0);
+         lcd_putc (':');
+         lcd_int ((current_time/60)%60, 2, 0);
+         lcd_putc (':');
+         lcd_int (current_time%60, 2, 0);
+         lcd_puts_P ("  "); 
+         lcd_gotoxy (0, 1); 
+         lcd_puts_P ("Ta="); 
+         lcd_int (42, -2, 0); 
+         lcd_puts_P ("  "); 
+       }
+
+     if (run_atcommand)
+       {
+         if (do_atcommand ())
+           uart_puts_P ("ERROR\r\n");
+         else
+           uart_puts_P ("OK\r\n");
+         run_atcommand = 0;
+       }
+
+
+
+   }
+}
+
+
+/*
+Writing:
+ avrdude -c usbasp -pm32 -U flash:w:atmegatest.hex
+Fuse bits:
+ lfuse = 0xEF (8MHz crystal)
+ hfuse = 0xD1 (ie. disable JTAG)
+avrdude -c usbasp -pm32 -v -B 4 -U lfuse:w:0xEF:m
+avrdude -c usbasp -pm32 -v -B 4 -U hfuse:w:0xD1:m
+
+Local Variables:
+compile-command: "avr-gcc -Wall -Wno-pointer-sign -g -mmcu=atmega32 -Os -o atmegatest.elf atmegatest.c -lc ; avr-objcopy -O ihex -j .text -j .data  atmegatest.elf atmegatest.hex"
+End:
+*/
diff --git a/bbdb-vcard-export.el b/bbdb-vcard-export.el
new file mode 100644 (file)
index 0000000..2cda0b2
--- /dev/null
@@ -0,0 +1,244 @@
+;;; bbdb-vcard-export.el -- export BBDB as vCard files
+;; 
+;; Copyright (c) 2002 Jim Hourihan
+;; Copyright (c) 2005 Alex Schroeder
+;;
+;; bbdb-vcard-export.el 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; either version 2, or (at
+;; your option) any later version.
+;;
+;; This software 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+;;
+;; Author: Jim Hourihan <jimh@panix.com>
+;; Created: 2002-08-08
+;; Version: $Id: bbdb-vcard-export.el,v 1.3 2006/03/14 00:00:00 malcolmp Exp $
+;; Keywords: vcard ipod
+
+;;; Commentary
+
+;; I use this code to sync my ipod with bbdb under OS X. To do so:
+;;
+;;     M-x bbdb-vcard-export-update-all
+;;
+;; and enter `/Volumes/IPOD_NAME/Contacts/' at the prompt
+;;
+;; vCard documentated in RFC 2426 <http://www.faqs.org/rfcs/rfc2426.html>
+;; Value types documented in RFC 2425 <http://www.faqs.org/rfcs/rfc2425.html>
+
+;; The coding system used for writing the files is UTF-16 by default.
+;; To use anything else, use a prefix argument: C-u M-x
+;; bbdb-vcard-export-update-all.  You will be prompted for another
+;; coding system to use.  Latin-1 is probably a good choice.
+;; bbdb-file-coding-system's default value is iso-2022-7bit, which is
+;; probably useless for vCard exports.
+
+;;; Code:
+
+(require 'bbdb)
+
+; XEmacs prior to 21.5 is not dumped with replace-regexp-in-string.  In those
+; cases it can be found in the xemacs-base package.
+(eval-and-compile
+  (if (and (not (fboundp 'replace-regexp-in-string)) (featurep 'xemacs))
+      (require 'easy-mmode)))
+
+(defvar bbdb-translation-table
+  '(("mobile" . "cell")
+    ("handy"  . "cell")
+    ("office" . "work")
+    ("Mobile" . "cell")
+    ("Handy"  . "cell")
+    ("Office" . "work"))
+  "Translations of text items, typically for labels.")
+
+(defun bbdb-translate (str)
+  "Translate STR into some other string based on `bbdb-translation-table'."
+  (let ((translation (assoc str bbdb-translation-table)))
+    (if translation
+       (cdr translation)
+      str)))
+
+;; 2.3 Predefined VALUE Type Usage
+
+;;    The predefined data type values specified in [MIME-DIR] MUST NOT be
+;;    repeated in COMMA separated value lists except within the N,
+;;    NICKNAME, ADR and CATEGORIES value types.
+
+;;    The text value type defined in [MIME-DIR] is further restricted such
+;;    that any SEMI-COLON character (ASCII decimal 59) in the value MUST be
+;;    escaped with the BACKSLASH character (ASCII decimal 92).
+
+(defun bbdb-vcard-export-escape (str)
+  "Return a copy of STR with ; , and newlines escaped."
+  (setq str (bbdb-translate str)
+       str (or str ""); get rid of nil values
+       str (replace-regexp-in-string "\\(;\\|,\\|\\\\\\)" "\\\\\\1" str)
+       str (replace-regexp-in-string "\n" "\\\\n" str)))
+
+;; (insert (bbdb-vcard-export-escape "this is, not \\ or \n true"))
+
+(defun bbdb-vcard-export-several (list)
+  "Return a comma-separated list of escaped unique elements in LIST."
+  (let ((hash (make-hash-table :test 'equal))
+       result)
+    (dolist (item list)
+      (puthash (bbdb-vcard-export-escape item) t hash))
+    (maphash (lambda (key val)
+              (setq result (cons key result)))
+            hash)
+    (bbdb-join result ",")))
+
+;; The component values MUST be specified in
+;; their corresponding position. The structured type value corresponds,
+;; in sequence, to the post office box; the extended address; the street
+;; address; the locality (e.g., city); the region (e.g., state or
+;; province); the postal code; the country name. When a component value
+;; is missing, the associated component separator MUST still be
+;; specified.
+
+;; The text components are separated by the SEMI-COLON character (ASCII
+;; decimal 59). Where it makes semantic sense, individual text
+;; components can include multiple text values (e.g., a "street"
+;; component with multiple lines) separated by the COMMA character
+;; (ASCII decimal 44).
+(defun bbdb-vcard-export-address-string (address)
+  "Return the address string"
+  (let ((streets (bbdb-address-streets address))
+       (city (bbdb-address-city address))
+       (state (bbdb-address-state address))
+       (country (bbdb-address-country address))
+       (zip (bbdb-address-zip address)))
+    (concat 
+     "adr;type=" (bbdb-vcard-export-escape (bbdb-address-location address)) ":"
+     ";;" ;; no post office box, no extended address
+     (bbdb-vcard-export-several streets) ";"
+     (bbdb-vcard-export-escape city) ";"
+     (bbdb-vcard-export-escape state) ";"
+     (bbdb-vcard-export-escape zip) ";"
+     (bbdb-vcard-export-escape country))))
+
+(defun bbdb-vcard-export-record-insert-vcard (record)
+  "Insert a vcard formatted version of RECORD into the current buffer"
+  (let ((name (bbdb-record-name record))
+       (first-name (bbdb-record-firstname record))
+       (last-name (bbdb-record-lastname record))
+       (aka (bbdb-record-aka record))
+       (company (bbdb-record-company record))
+       (notes (bbdb-record-notes record))
+       (phones (bbdb-record-phones record))
+       (addresses (bbdb-record-addresses record))
+       (net (bbdb-record-net record))
+       (categories (bbdb-record-getprop
+                    record
+                    bbdb-define-all-aliases-field)))
+    (insert "begin:vcard\n"
+           "version:3.0\n")
+    ;; Specify the formatted text corresponding to the name of the
+    ;; object the vCard represents.  The property MUST be present in
+    ;; the vCard object.
+    (insert "fn:" (bbdb-vcard-export-escape name) "\n")
+    ;; Family Name, Given Name, Additional Names, Honorific
+    ;; Prefixes, and Honorific Suffixes
+    (when (or last-name first-name)
+      (insert "n:"
+             (bbdb-vcard-export-escape last-name) ";"  
+             (bbdb-vcard-export-escape first-name) ";;;\n"))
+    ;; Nickname of the object the vCard represents.  One or more text
+    ;; values separated by a COMMA character (ASCII decimal 44).
+    (when aka
+      (insert "nickname:" (bbdb-vcard-export-several aka) "\n"))
+    ;; FIXME: use face attribute for this one.
+    ;; PHOTO;ENCODING=b;TYPE=JPEG:MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcN
+    ;; AQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bm
+    ;; ljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZvcm1hdGlvbiBTeXN0
+
+    ;; FIXME: use birthday attribute if there is one.
+    ;; BDAY:1996-04-15
+    ;; BDAY:1953-10-15T23:10:00Z
+    ;; BDAY:1987-09-27T08:30:00-06:00
+
+    ;; A single structured text value consisting of components
+    ;; separated the SEMI-COLON character (ASCII decimal 59).  But
+    ;; BBDB doesn't use this.  So there's just one level:
+    (when company
+      (insert "org:" (bbdb-vcard-export-escape company) "\n"))
+    (when notes
+      (insert "note:" (bbdb-vcard-export-escape notes) "\n"))
+    (dolist (phone phones)
+      (insert "tel;type=" (bbdb-vcard-export-escape (bbdb-phone-location phone)) ":"
+             (bbdb-vcard-export-escape (bbdb-phone-string phone)) "\n"))
+    (dolist (address addresses)
+      (insert (bbdb-vcard-export-address-string address) "\n"))
+    (dolist (mail net)
+      (insert "email;type=internet:" (bbdb-vcard-export-escape mail) "\n"))
+    ;; Use CATEGORIES based on mail-alias.  One or more text values
+    ;; separated by a COMMA character (ASCII decimal 44).
+    (when categories
+      (insert "categories:" 
+             (bbdb-join (mapcar 'bbdb-vcard-export-escape
+                                (bbdb-split categories ",")) ",") "\n"))
+    (insert "end:vcard\n")))
+                   
+(defun bbdb-vcard-export-vcard-name-from-record (record)
+  "Come up with a vcard name given a record"
+  (let ((name (bbdb-record-name record))
+       (first-name (elt record 0))
+       (last-name (elt record 1)))
+    (concat first-name "_" last-name ".vcf")))
+
+(defun bbdb-vcard-export-make-vcard (record vcard-name)
+  "Make a record buffer and write it"
+  (let ((buffer (get-buffer-create "*bbdb-vcard-export*")))
+    (save-excursion
+      (set-buffer buffer)
+      (kill-region (point-min) (point-max))
+      (bbdb-vcard-export-record-insert-vcard record)
+      (write-region (point-min) (point-max) vcard-name))
+    (kill-buffer buffer)))
+
+(defun bbdb-vcard-do-record (record output-dir coding-system)
+  "Update the vcard of one bbdb record"
+  (setq coding-system (or coding-system 'utf-8))
+  (let ((coding-system-for-write coding-system))
+    (message "Updating %s" (bbdb-record-name record))
+    (bbdb-vcard-export-make-vcard 
+     record
+     (concat output-dir "/"
+            (bbdb-vcard-export-vcard-name-from-record record)))))
+
+(defun bbdb-vcard-export-update-all (output-dir coding-system)
+  "Update the vcard Contacts directory from the bbdb database"
+  (interactive "DDirectory to update: \nZCoding system: ")
+  (bbdb ".*" nil)
+  (dolist (record (bbdb-records))
+    (bbdb-vcard-do-record record output-dir coding-system)))
+
+(defun bbdb-vcard-export (regexp output-dir coding-system)
+  "Update the vcard Contacts directory from records matching REGEXP"
+  (interactive "sExport records matching: \nDDirectory to update: \nZCoding system: ")
+  (bbdb regexp nil)
+  (let ((notes (cons '* regexp)))
+    (dolist (record (bbdb-search (bbdb-records) regexp regexp regexp notes nil))
+      (message "Updating %s" (bbdb-record-name record))
+      (bbdb-vcard-do-record record output-dir coding-system))))
+
+(defun bbdb-vcard-export-current (output-dir coding-system)
+  "Update the vcard of the current record"
+  (interactive "DDirectory to update: \nZCoding system: ")
+  (let ((record (bbdb-current-record nil)))
+    (bbdb-vcard-do-record record output-dir coding-system)))
+
+(define-key bbdb-mode-map [(v)] 'bbdb-vcard-export-current)
+
+
+(provide 'bbdb-vcard-export)
+
+;;; bbdb-vcard-export.el ends here
diff --git a/cp-nnml2maildir b/cp-nnml2maildir
new file mode 100644 (file)
index 0000000..0cfec42
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+dir="$1"
+newdir="$2"
+
+[ -z $newdir ] && exit 1
+
+if [ ! -d "$newdir" ]; then
+  mkdir "$newdir"
+  chmod g-rx,o-rx "$newdir"
+  mkdir           "$newdir"/tmp "$newdir"/cur "$newdir"/new
+  chmod g-rx,o-rx "$newdir"/tmp "$newdir"/cur "$newdir"/new
+fi
+
+
+ls "$dir" | while read tmp dummy; do
+ digits=$(echo "$tmp" | sed  's/[^0-9]//g')
+ oldname="$dir/$tmp"
+ newname=${newdir}/cur/$(stat -c %Y.${digits}i%i.vigenere:2,S  "$oldname")
+ echo mv "$oldname" '->' "$newname" >&2
+ mv "$oldname" "$newname"
+done
+echo mv "$dir/.marks" $newdir/gnus-marks >&2
+mv "$dir/.marks" $newdir/gnus-marks
diff --git a/ebusnode1-ee.hex b/ebusnode1-ee.hex
new file mode 100644 (file)
index 0000000..6bd0a2a
--- /dev/null
@@ -0,0 +1,3 @@
+:02000004008179\r
+:040000000000112AC1\r
+:00000001FF\r
diff --git a/ebusnode1.c b/ebusnode1.c
new file mode 100644 (file)
index 0000000..c81b2c8
--- /dev/null
@@ -0,0 +1,483 @@
+/* ebusnode1.c - Elektor Bus Node using an ATmega88
+   Copyright (C) 2011 g10 Code GmbH
+
+
+   2011-06-01 wk  Initial code.
+
+  */
+
+
+/* Clock frequency in Hz. */
+#define F_CPU 16000000UL
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <util/delay.h>
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+#include <avr/interrupt.h>
+#include <avr/eeprom.h>
+#include <avr/sleep.h>
+
+
+#define DIM(v)              (sizeof(v)/sizeof((v)[0]))
+
+/* Key and LED definitions.  */
+#define KEY_Test    bit_is_set (PIND, PIND5)
+#define KEY_Exp     bit_is_set (PIND, PIND7)
+#define LED_Collision     (PORTD)
+#define LED_Collision_BIT (4)
+#define LED_Tx            (PORTD)
+#define LED_Tx_BIT        (6)
+
+
+/* UART defs.  */
+#define BAUD       9600ul
+#define UBRR_VAL   ((F_CPU+8*BAUD)/(16*BAUD)-1)
+#define BAUD_REAL  (F_CPU/(16*(UBRR_VAL+1)))
+#define BAUD_ERROR ((1000*BAUD_REAL)/BAUD)
+#if (BAUD_ERROR < 990 || BAUD_ERROR > 1010)
+# error computed baud rate out of range
+#endif
+
+/* We use timer 0 to detect the sync and error gaps during receive.
+   As with MODBus specs the sync gap T_g needs to be 3.5c and the
+   error gap T_e (gaps between bytes in a message longer than that are
+   considered an error) is 1.5c.  With 8n1 an octet is represented by
+   10 bits on the wire and it takes the time Tc.
+
+   |   Baud |    Tc |    Tg |    Te |    Tg |    Te |   Tg |   Te |
+   |        |  (ms) |  (ms) |  (ms) | c/256 | c/256 | c/64 | c/64 |
+   |--------+-------+-------+-------+-------+-------+------+------|
+   |   9600 |  1.04 |  3.65 |  1.56 |   228 |    97 |      |      |
+   |  19200 |  0.52 |  1.82 |  0.78 |   114 |    48 |      |      |
+   |  38400 |  0.26 |  0.91 |  0.39 |       |       |  228 |   97 |
+   |  57600 |  0.17 |  0.61 |  0.26 |       |       |  153 |   65 |
+   |  76800 |  0.13 |  0.46 |  0.20 |       |       |  115 |   50 |
+   | 115200 | 0.087 | 0.304 | 0.130 |       |       |   76 |   32 |
+*/
+#if BAUD == 9600
+# define T_x_PSCALE 256
+# define T_g_CMPVAL 228
+# define T_e_CMPVAL  97
+#elif BAUD == 19200
+# define T_x_PSCALE 256
+# define T_g_CMPVAL 114
+# define T_e_CMPVAL  48
+#elif BAUD == 38400
+# define T_x_PSCALE  64
+# define T_g_CMPVAL 228
+# define T_e_CMPVAL  97
+#elif BAUD == 57600
+# define T_x_PSCALE  64
+# define T_g_CMPVAL 153
+# define T_e_CMPVAL  65
+#elif BAUD == 76800
+# define T_x_PSCALE  64
+# define T_g_CMPVAL 115
+# define T_e_CMPVAL  50
+#elif BAUD == 115200
+# define T_x_PSCALE  64
+# define T_g_CMPVAL  76
+# define T_e_CMPVAL  32
+#else
+# error Specified baud rate not supported
+#endif
+
+
+
+\f
+/*
+   Application specific constants.
+ */
+
+/* We always work on 16 byte long messages.  */
+#define MSGSIZE 16
+/* The start byte which indicates the start of a new message.  */
+#define MSGSTARTBYTE 0xaa
+
+
+/* Typedefs.  */
+typedef unsigned char byte;
+
+/* EEPROM layout.  We keep configuration data at the start of the
+   eeprom but copy it on startup into the RAM for easier access. */
+struct
+{
+  uint16_t  reserved;
+  byte      nodeid_hi;
+  byte      nodeid_lo;
+} ee_config EEMEM;
+/* Other eeprom stuff should go here.  */
+
+/* End EEPROM.  */
+
+/* For fast access we copy some of the config data int the RAM.  */
+struct
+{
+  byte nodeid_lo;
+} config;
+
+/* The current time measured in seconds.  */
+volatile unsigned int current_time;
+
+volatile unsigned int frames_sent;
+volatile unsigned int frames_received;
+volatile unsigned int resyncs_done;
+
+
+
+/* Set to one (e.g. the timer int) to wakeup the main loop.  */
+volatile char wakeup_main;
+
+/* The buffer filled by an ISR with the message.  */
+static volatile byte rx_buffer[MSGSIZE];
+
+/* Flag indicating whether we are currently receiving a message.  */
+static volatile byte receiving;
+
+/* If true RX_BUFFER has a new message.  This flag is set by the ISR
+   and must be cleared by the main fucntion so that the ISR can
+   continue to work.  */
+static volatile byte rx_ready;
+
+static volatile byte send_flag;
+
+static volatile byte send_interval;
+
+\f
+
+/* Reset the gap timer (timer 0).  Note that this resets both
+   timers.  */
+static void
+reset_gap_timer (void)
+{
+  TCCR0B = 0x00;   /* Stop clock.  */
+  TIFR0  = _BV(OCF0A) | _BV(OCF0B);  /* Clear the flags.  */
+  TCNT0  = 0x00;   /* Clear timer/counter register.  */
+
+  /* Start the clock.  */
+#if T_x_PSCALE == 256
+  TCCR0B = 0x04;   /* Set prescaler to clk/256.  */
+#else
+  TCCR0B = 0x03;   /* Set prescaler to clk/64.  */
+#endif
+}
+
+
+static inline int
+t_g_reached (void)
+{
+  return !!(TIFR0 & _BV(OCF0A));
+}
+
+
+static inline int
+t_e_reached (void)
+{
+  return !!(TIFR0 & _BV(OCF0B));
+}
+
+
+
+\f
+/*
+   Interrupt service routines
+ */
+
+
+/* 1ms ticker interrupt service routine. */
+ISR (TIMER2_COMPA_vect)
+{
+  static unsigned int clock; /* Milliseconds of the current minute.  */
+
+  clock++;
+
+  if (clock == 1000)
+   {
+     /* One second has passed.  Bump the current time.  */
+     current_time++;
+     clock = 0;
+   }
+
+  /* Run the main loop every 250ms.  */
+  if (!(clock % send_interval))
+    {
+      send_flag = 1;
+      wakeup_main = 1;
+    }
+
+}
+
+
+/* UART tx complete interrupt service routine. */
+ISR (USART_TX_vect)
+{
+  /* Nothing to do.  */
+}
+
+
+/* UART receive complete interrupt service routine.  Note that we
+   always listen on the bus and thus also receive our own transmits.
+   This is useful so that we can easily detect collisions.  */
+ISR (USART_RX_vect)
+{
+  static byte idx;
+  byte c;
+
+  if (!receiving)
+    {
+      if (!t_g_reached ())
+        return;  /* Still waiting for the sync gap.  */
+
+      receiving = 1;
+      idx = 0;
+      reset_gap_timer ();
+    }
+
+  c = UDR0;
+
+  if (rx_ready) /* Overflow.  */
+    goto resync;
+
+  if (t_e_reached ()) /* Gap between octets in message too long.  */
+    goto resync;
+  reset_gap_timer ();
+
+  if (idx == 0 && c != MSGSTARTBYTE)
+    {
+      /* We are out of sync.  This might be due to a collission or
+         because we started to listen too late.  What we need to do is
+         to wait for the next sync gap.  */
+      goto resync;
+    }
+  if (idx >= MSGSIZE)
+    {
+      /* Message too long.  This is probably due to a collission.  */
+      goto resync;
+    }
+  rx_buffer[idx++] = c;
+  if (idx == MSGSIZE)
+    {
+      rx_ready = 1;
+      wakeup_main = 1;
+      receiving = 0;
+      frames_received++;
+      reset_gap_timer ();
+    }
+  return;
+
+ resync:
+  /* Collision or overflow.  */
+  resyncs_done++;
+  LED_Collision |= _BV(LED_Collision_BIT);
+  receiving = 0;
+  reset_gap_timer ();
+  return;
+}
+
+
+
+/* Send out byte C.  */
+static void
+send_byte (const byte c)
+{
+  /* Wait until transmit buffer is empty.  */
+  while (!bit_is_set (UCSR0A, UDRE0))
+    ;
+  /* Send the byte.  */
+  UDR0 = c;
+}
+
+
+
+static void
+send_message (byte recp_id, const byte *data)
+{
+  /* FIXME: Out logic does only work if we receive an octet from time
+     to time.  Without that we may get stuck while having received
+     only a part of a frame and thus we will never switch out of
+     receiving.  An ISR to handle the syncing is required.  */
+  while (receiving || !t_g_reached ())
+    ;
+
+  /* Switch TX LED on.  */
+  LED_Tx |= _BV(LED_Tx_BIT);
+
+  /* Before sending we need to clear the TCX bit by setting it.  */
+  UCSR0A |= _BV(TXC0);
+
+  /* Enable the LT1785 driver output (DE).  */
+  PORTD |= _BV(2);
+
+  send_byte (MSGSTARTBYTE);
+  send_byte (config.nodeid_lo);
+  send_byte (recp_id);
+  send_byte (current_time >> 8);
+  send_byte (current_time);
+  send_byte (frames_received >> 8);
+  send_byte (frames_received);
+  send_byte (frames_sent >> 8);
+  send_byte (frames_sent);
+  send_byte (resyncs_done >> 8);
+  send_byte (resyncs_done);
+  send_byte (9);
+  send_byte (10);
+  send_byte (11);
+  send_byte (12);
+  send_byte (13);
+
+  /* Wait until transmit is complete.  */
+  while (!bit_is_set (UCSR0A, TXC0))
+    ;
+  UCSR0A |= _BV(TXC0);
+
+  /* Now disable the LT1785 driver output (DE).  */
+  PORTD &= ~_BV(2);
+
+  /* To introduce the 3.5c gap we now continue sending dummy bytes
+     with DE disabled.  That allows us to do it without a timer with
+     the little disadvantage that the gap will be 4c.  However that is
+     allowed by the MODbus protocol from where we took this sync
+     feature.  */
+  UCSR0A |= _BV(TXC0);
+  send_byte (0xe0);
+  send_byte (0xe1);
+  send_byte (0xe2);
+  send_byte (0xe3);
+  while (!bit_is_set (UCSR0A, TXC0))
+    ;
+  UCSR0A |= _BV(TXC0);
+
+  LED_Tx &= ~_BV(LED_Tx_BIT); /* Switch TX LED off.  */
+  frames_sent++;
+}
+
+
+
+/* A new message has been received and we must now parse the message
+   quickly and see what to do.  We need to return as soon as possible,
+   so that the caller may re-enable the receiver.  */
+static void
+process_message (void)
+{
+  /* Is this a broadcast or is it directed to us.  If not we don't
+     need to care about it.  */
+
+}
+
+
+
+/*
+    Entry point
+ */
+int
+main (void)
+{
+  /* Port D configuration:
+     PIND.7 = Inp: KEY_Exp
+     PIND.6 = Out: LED_Exp
+     PIND.5 = Inp: KEY_Test
+     PIND.4 = Out: LED_Collision
+     PIND.3 = Out: LT1785-pin2 = !RE
+     PIND.2 = Out: LT1785-pin3 = DE
+     PIND.1 = TXD: LT1785-pin4 = DI
+     PIND.0 = RXD: LT1785-pin1 = RO
+  */
+  PORTD = _BV(7) | _BV(5);
+  DDRD  = _BV(6) | _BV(4) | _BV(3) | _BV(2) | _BV(1);
+
+  /* Set the UART: 8n1, async, rx and tx on, rx int enabled.
+     Baud rate set to the value computed from BAUD.  */
+  UCSR0A = 0x00;
+  UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0);
+  UCSR0C = _BV(UCSZ01) | _BV(UCSZ00);
+  UBRR0H = (UBRR_VAL >> 8) & 0x0f;
+  UBRR0L = (UBRR_VAL & 0xff);
+
+  /* Timer 0: We use this timer for the sync gap and error gap
+     detection during receive.  */
+  TCCR0A = 0x00;   /* Select normal mode.  */
+#if T_x_PSCALE == 256
+  TCCR0B = 0x04;   /* Set prescaler to clk/256.  */
+#else
+  TCCR0B = 0x03;   /* Set prescaler to clk/64.  */
+#endif
+  TIMSK0 = 0x00;   /* No interrupts so that we need to clear the TIFR0
+                      flags ourself.  */
+  OCR0A  = T_g_CMPVAL; /* Use this for T_g.  */
+  OCR0B  = T_e_CMPVAL; /* Use this for T_e.  */
+
+  /* Timer 1:  Not used.  */
+
+  /* Timer 2: 1ms ticker.  */
+  TCCR2A = 0x02;   /* Select CTC mode.  */
+  TCCR2B = 0x04;   /* Set prescaler to 64.  */
+  TCNT2 = 0x00;    /* Clear timer/counter register.  */
+  OCR2A  = 250;    /* Compare value for 1ms.  */
+  TIMSK2 = 0x02;   /* Set OCIE2A.  */
+
+  /* Copy some configuration data into the RAM.  */
+  config.nodeid_lo = eeprom_read_byte (&ee_config.nodeid_lo);
+
+  send_interval = 250;
+
+  /* Enable interrupts.  */
+  sei ();
+
+  /* Main loop.  */
+  for (;;)
+   {
+     while (!wakeup_main)
+       {
+         set_sleep_mode (SLEEP_MODE_IDLE);
+         cli();
+         if (!wakeup_main)
+           {
+             sleep_enable ();
+             sei ();
+             sleep_cpu ();
+             sleep_disable ();
+           }
+         sei ();
+       }
+     wakeup_main = 0;
+
+     if (rx_ready)
+       {
+         /* Reset the collission LED on the first correctly received
+            message.  */
+         LED_Collision &= ~_BV(LED_Collision_BIT);
+         /* Process the message.  */
+         process_message ();
+         /* Re-enable the receiver.  */
+         rx_ready = 0;
+       }
+
+     if (send_flag)
+       {
+         send_message (0, NULL);
+         send_flag = 0;
+       }
+
+     if (KEY_Test)
+       send_interval = 125;
+     if (KEY_Exp)
+       send_interval = 250;
+   }
+}
+
+
+/*
+Writing:
+ avrdude -c usbasp -pm88 -U flash:w:ebusnode1.hex
+Fuse bits:
+ lfuse = 0xFF (16MHz crystal)
+ hfuse = 0xD7 (ie. set EESAVE))
+avrdude -c usbasp -pm88 -v -B 4 -U lfuse:w:0xFF:m
+avrdude -c usbasp -pm88 -v -B 4 -U hfuse:w:0xD7:m
+
+Local Variables:
+compile-command: "avr-gcc -Wall -Wno-pointer-sign -g -mmcu=atmega88 -Os -o ebusnode1.elf ebusnode1.c -lc ; avr-objcopy -O ihex -j .text -j .data ebusnode1.elf ebusnode1.hex"
+End:
+*/
diff --git a/heating-daemon.c b/heating-daemon.c
new file mode 100644 (file)
index 0000000..96bc5cf
--- /dev/null
@@ -0,0 +1,242 @@
+/* heating-daemon.c - Collect data from heating-control.c
+ * Copyright (C) 2010 Werner Koch
+ *
+ * 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; either version 3 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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <assert.h>
+#include <termios.h>
+#include <unistd.h>
+
+#define PGM           "heating-daemon"
+#define PGM_VERSION   "0.0"
+#define PGM_BUGREPORT "wk@gnupg.org"
+
+/* Option flags. */
+static int verbose;
+static int debug;
+
+/* Error counter.  */
+static int any_error;
+
+
+/* Print diagnostic message and exit with failure. */
+static void
+die (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  fflush (stdout);
+  fprintf (stderr, "%s: ", PGM);
+
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+  putc ('\n', stderr);
+
+  exit (1);
+}
+
+
+/* Print diagnostic message. */
+static void
+err (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  any_error = 1;
+
+  fflush (stdout);
+  fprintf (stderr, "%s: ", PGM);
+
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+  putc ('\n', stderr);
+}
+
+/* Print a info message message. */
+static void
+inf (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  if (verbose)
+    {
+      fprintf (stderr, "%s: ", PGM);
+      
+      va_start (arg_ptr, format);
+      vfprintf (stderr, format, arg_ptr);
+      va_end (arg_ptr);
+      putc ('\n', stderr);
+    }
+}
+
+
+static FILE *
+open_line (void)
+{
+  FILE *fp;
+  int fd;
+  struct termios term;
+
+  /* FIXME get device lock.  */
+
+  fp = fopen ("/dev/ttyS0", "r+");
+  if (!fp || (fd = fileno (fp)) == -1)
+    die ("can't open `%s': %s", "/dev/ttyS0", strerror (errno));
+
+  if (tcgetattr (fd, &term))
+    die ("tcgetattr(%d) failed: %s", fd, strerror (errno));
+
+  term.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
+                    | INLCR | IGNCR | ICRNL | IXON);
+  term.c_oflag &= ~OPOST;
+  term.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
+  term.c_cflag &= ~(CSIZE | PARENB);
+  term.c_cflag |= CS8;
+
+  if (cfsetospeed (&term, B9600) || cfsetispeed (&term, B9600))
+    die ("setting terminal speed to 9600 failed: %s", strerror (errno));
+
+  if (tcsetattr (fd, TCSANOW, &term ) )
+    die ("tcsetattr(%d) failed: %s", fd, strerror (errno));
+
+  inf ("connected to '%s' at 9600bps", "/dev/ttyS0");
+
+  return fp;
+}
+
+
+static void
+run_loop (FILE *fp)
+{
+  char line[1024];
+  size_t len;
+  int c;
+
+  fseek (fp, 0L, SEEK_CUR);
+  fputs ("\r\n\r\nAT+M1\r\n", fp);
+  fseek (fp, 0L, SEEK_CUR);
+
+  while (fgets (line, sizeof line, fp))
+    {
+      len = strlen (line);
+      if (!len || line[len-1] != '\n')
+        {
+          err ("line too long - skipping");
+          while ((c = getc (fp)) != EOF && c != '\n')
+            ;
+          continue;
+        }
+      while (len && (line[len-1] == '\n' || line[len-1] == '\r'))
+        len--;
+      line[len] = 0;
+
+      if (*line && line[1] == ':')
+        {
+          fputs (line, stdout);
+          putchar ('\n');
+        }
+      else
+        inf ("message: %s", line);
+    }
+
+  if (ferror (fp))
+    err ("processing stopped due to a read error: %s", strerror (errno));
+  else
+    inf ("processing stopped due to an EOF");
+}
+
+
+
+static int
+show_usage (int ex)
+{
+  fputs ("Usage: " PGM "\n"
+         "Control the heating controller and collect data.\n\n"
+         "  --verbose      enable extra informational output\n"
+         "  --debug        enable additional debug output\n"
+         "  --help         display this help and exit\n\n"
+         "Report bugs to " PGM_BUGREPORT ".\n",
+         ex? stderr:stdout);
+  exit (ex);
+}
+
+
+int 
+main (int argc, char **argv)
+{
+  int last_argc = -1;
+  FILE *fp;
+
+  if (argc)
+    {
+      argc--; argv++;
+    }
+  while (argc && last_argc != argc )
+    {
+      last_argc = argc;
+      if (!strcmp (*argv, "--"))
+        {
+          argc--; argv++;
+          break;
+        }
+      else if (!strcmp (*argv, "--version"))
+        {
+          fputs (PGM " " PGM_VERSION "\n", stdout);
+          exit (0);
+        }
+      else if (!strcmp (*argv, "--help"))
+        {
+          show_usage (0);
+        }
+      else if (!strcmp (*argv, "--verbose"))
+        {
+          verbose = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--debug"))
+        {
+          verbose = debug = 1;
+          argc--; argv++;
+        }
+      else if (!strncmp (*argv, "--", 2))
+        show_usage (1);
+    }          
+
+  if (argc)
+    show_usage (1);
+
+  setvbuf (stdout, NULL, _IOLBF, 0);
+
+  fp = open_line ();
+  run_loop (fp);
+  fclose (fp);
+
+  return any_error? 1:0;
+}
+
+
+/*
+Local Variables:
+compile-command: "gcc -Wall -W -O2 -g -o heating-daemon heating-daemon.c"
+End:
+*/
diff --git a/hkpstats.c b/hkpstats.c
new file mode 100644 (file)
index 0000000..e5df238
--- /dev/null
@@ -0,0 +1,290 @@
+/* hkpstats.c - Report stats about an HPK keyserver pool
+ *     Copyright (C) 2009 Werner Koch
+ *
+ * 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; either version 3 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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <adns.h>
+
+
+#define PGM           "hkpstats"
+#define PGM_VERSION   "0.0"
+#define PGM_BUGREPORT "wk@gnupg.org"
+
+/* Option flags. */
+static int verbose;
+static int debug;
+
+/* Error counter.  */
+static int any_error;
+
+/* An object to keep track of each host. */
+struct host_s
+{
+  struct host_s *next;
+
+  const char *poolname;  /* Original poolname (e.g. "keys.gnupg.net") */
+  struct in_addr addr;   /* Its IP address.  */
+  char *addr_str;        /* Ditto but in human readabale format.  */
+
+  struct {
+    adns_query query;    /* Active query.  */
+  } help;
+};
+typedef struct host_s *host_t;
+
+
+
+/* Print diagnostic message and exit with failure. */
+static void
+die (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  fflush (stdout);
+  fprintf (stderr, "%s: ", PGM);
+
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+  putc ('\n', stderr);
+
+  exit (1);
+}
+
+
+/* Print diagnostic message. */
+static void
+err (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  any_error = 1;
+
+  fflush (stdout);
+  fprintf (stderr, "%s: ", PGM);
+
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+  putc ('\n', stderr);
+}
+
+/* Print a info message message. */
+static void
+inf (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  if (verbose)
+    {
+      fprintf (stderr, "%s: ", PGM);
+      
+      va_start (arg_ptr, format);
+      vfprintf (stderr, format, arg_ptr);
+      va_end (arg_ptr);
+      putc ('\n', stderr);
+    }
+}
+
+
+
+static void
+process_one_pool (adns_state adns_ctx, const char *poolname)
+{
+  adns_answer *answer = NULL;
+  int rridx;
+  host_t host;
+  host_t hostlist = NULL;
+  in rc;
+
+  inf ("collecting data for `%s'", poolname);
+  
+  if (adns_synchronous (adns_ctx, poolname,
+                        adns_r_a, adns_qf_quoteok_query,
+                        &answer) )
+    {
+      err ("DNS query for `%s' failed: %s", poolname, strerror (errno));
+      return;
+    }
+
+  if (answer->status != adns_s_ok) 
+    {
+      err ("DNS query for `%s' failed: %s (%s)", poolname, 
+           adns_strerror (answer->status),
+           adns_errabbrev (answer->status)); 
+      free (answer); 
+      return;
+    }
+  assert (answer->type == adns_r_a);
+
+  for (rridx=0; rridx < answer->nrrs; rridx++)
+    {
+      struct sockaddr_in sockaddr;
+      struct in_addr addr = answer->rrs.inaddr[rridx];
+      const char *s;
+
+      host = calloc (1, sizeof *host);
+      if (!host)
+        die ("out of core: %s", strerror (errno));
+      host->poolname = poolname;
+      host->addr = addr;
+      s = inet_ntoa (addr);
+      host->addr_str = strdup (s?s:"[none]");
+      if (!host->addr_str)
+        die ("out of core: %s", strerror (errno));
+        
+      inf ("IP=%s", host->addr_str);
+
+      memset (&sockaddr, 0,sizeof sockaddr);
+      sockaddr.sin_family = AF_INET; 
+      memcpy (&sockaddr.sin_addr, &addr, sizeof addr);
+      if (adns_submit_reverse (adns_ctx, (struct sockaddr *)&sockaddr,
+                               adns_r_ptr, 
+                               adns_qf_quoteok_cname | adns_qf_cname_loose,
+                               host, &host->help.query))
+        {
+          err ("DNS reverse lookup of `%s', %s failed: %s (%s)",
+               poolname, host->addr_str,
+               adns_strerror (answer->status),
+               adns_errabbrev (answer->status)); 
+          /*fixme: release_host (host);*/
+        }
+      else
+        {
+          host->next = hostlist;
+          hostlist = host;
+        }
+    }
+  free (answer);
+
+  if (!hostlist)
+    return;
+    
+  /* Wait until all hosts are resolved. */
+  for (;;)
+    {
+      adns_query query = NULL;  
+
+      rc = adns_check(adns_ctx, &query, &answer, &host);
+      if (!rc)
+        {
+
+
+        }
+      else if (err == EAGAIN) break;
+      if (err) {
+       fprintf(stderr, "%s: adns_wait/check: %s", progname, strerror(err));
+       exit(1);
+      }
+
+
+      for (host = hostlist; host; host = host->next)
+    {
+      if (!host->help.query)
+        continue;
+    }
+}
+
+
+static int
+show_usage (int ex)
+{
+  fputs ("Usage: " PGM " {pool}\n"
+         "Generate a report for all keyservers in the POOLs.\n\n"
+         "  --verbose      enable extra informational output\n"
+         "  --debug        enable additional debug output\n"
+         "  --help         display this help and exit\n\n"
+         "Example:  \"" PGM " keys.gnupg.net http-keys.gnupg.net\"\n\n"
+         "Report bugs to " PGM_BUGREPORT ".\n",
+         ex? stderr:stdout);
+  exit (ex);
+}
+
+
+int 
+main (int argc, char **argv)
+{
+  int last_argc = -1;
+  adns_state adns_ctx = NULL;
+
+  if (argc)
+    {
+      argc--; argv++;
+    }
+  while (argc && last_argc != argc )
+    {
+      last_argc = argc;
+      if (!strcmp (*argv, "--"))
+        {
+          argc--; argv++;
+          break;
+        }
+      else if (!strcmp (*argv, "--version"))
+        {
+          fputs (PGM " " PGM_VERSION "\n", stdout);
+          exit (0);
+        }
+      else if (!strcmp (*argv, "--help"))
+        {
+          show_usage (0);
+        }
+      else if (!strcmp (*argv, "--verbose"))
+        {
+          verbose = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--debug"))
+        {
+          verbose = debug = 1;
+          argc--; argv++;
+        }
+      else if (!strncmp (*argv, "--", 2))
+        show_usage (1);
+    }          
+
+  if (argc < 1)
+    show_usage (1);
+
+  if (adns_init (&adns_ctx, adns_if_none, stderr))
+    die ("error initializing ADNS: %s", strerror (errno));
+
+  /* Note: Firther own we keep shallow copies of argv; thus don't
+     modify them. */
+  for (; argc; argc--, argv++)
+    process_one_pool (adns_ctx, *argv);
+  
+  adns_finish (adns_ctx);
+
+
+  return any_error? 1:0;
+}
+
+
+/*
+Local Variables:
+compile-command: "gcc -Wall -W -O2 -g -o hkpstats -ladns hkpstats.c"
+End:
+*/
diff --git a/modulo-d-amp/License.txt b/modulo-d-amp/License.txt
new file mode 100644 (file)
index 0000000..82fa1da
--- /dev/null
@@ -0,0 +1,339 @@
+                   GNU GENERAL PUBLIC LICENSE\r
+                      Version 2, June 1991\r
+\r
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\r
+ Everyone is permitted to copy and distribute verbatim copies\r
+ of this license document, but changing it is not allowed.\r
+\r
+                           Preamble\r
+\r
+  The licenses for most software are designed to take away your\r
+freedom to share and change it.  By contrast, the GNU General Public\r
+License is intended to guarantee your freedom to share and change free\r
+software--to make sure the software is free for all its users.  This\r
+General Public License applies to most of the Free Software\r
+Foundation's software and to any other program whose authors commit to\r
+using it.  (Some other Free Software Foundation software is covered by\r
+the GNU Lesser General Public License instead.)  You can apply it to\r
+your programs, too.\r
+\r
+  When we speak of free software, we are referring to freedom, not\r
+price.  Our General Public Licenses are designed to make sure that you\r
+have the freedom to distribute copies of free software (and charge for\r
+this service if you wish), that you receive source code or can get it\r
+if you want it, that you can change the software or use pieces of it\r
+in new free programs; and that you know you can do these things.\r
+\r
+  To protect your rights, we need to make restrictions that forbid\r
+anyone to deny you these rights or to ask you to surrender the rights.\r
+These restrictions translate to certain responsibilities for you if you\r
+distribute copies of the software, or if you modify it.\r
+\r
+  For example, if you distribute copies of such a program, whether\r
+gratis or for a fee, you must give the recipients all the rights that\r
+you have.  You must make sure that they, too, receive or can get the\r
+source code.  And you must show them these terms so they know their\r
+rights.\r
+\r
+  We protect your rights with two steps: (1) copyright the software, and\r
+(2) offer you this license which gives you legal permission to copy,\r
+distribute and/or modify the software.\r
+\r
+  Also, for each author's protection and ours, we want to make certain\r
+that everyone understands that there is no warranty for this free\r
+software.  If the software is modified by someone else and passed on, we\r
+want its recipients to know that what they have is not the original, so\r
+that any problems introduced by others will not reflect on the original\r
+authors' reputations.\r
+\r
+  Finally, any free program is threatened constantly by software\r
+patents.  We wish to avoid the danger that redistributors of a free\r
+program will individually obtain patent licenses, in effect making the\r
+program proprietary.  To prevent this, we have made it clear that any\r
+patent must be licensed for everyone's free use or not licensed at all.\r
+\r
+  The precise terms and conditions for copying, distribution and\r
+modification follow.\r
+\r
+                   GNU GENERAL PUBLIC LICENSE\r
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\r
+\r
+  0. This License applies to any program or other work which contains\r
+a notice placed by the copyright holder saying it may be distributed\r
+under the terms of this General Public License.  The "Program", below,\r
+refers to any such program or work, and a "work based on the Program"\r
+means either the Program or any derivative work under copyright law:\r
+that is to say, a work containing the Program or a portion of it,\r
+either verbatim or with modifications and/or translated into another\r
+language.  (Hereinafter, translation is included without limitation in\r
+the term "modification".)  Each licensee is addressed as "you".\r
+\r
+Activities other than copying, distribution and modification are not\r
+covered by this License; they are outside its scope.  The act of\r
+running the Program is not restricted, and the output from the Program\r
+is covered only if its contents constitute a work based on the\r
+Program (independent of having been made by running the Program).\r
+Whether that is true depends on what the Program does.\r
+\r
+  1. You may copy and distribute verbatim copies of the Program's\r
+source code as you receive it, in any medium, provided that you\r
+conspicuously and appropriately publish on each copy an appropriate\r
+copyright notice and disclaimer of warranty; keep intact all the\r
+notices that refer to this License and to the absence of any warranty;\r
+and give any other recipients of the Program a copy of this License\r
+along with the Program.\r
+\r
+You may charge a fee for the physical act of transferring a copy, and\r
+you may at your option offer warranty protection in exchange for a fee.\r
+\r
+  2. You may modify your copy or copies of the Program or any portion\r
+of it, thus forming a work based on the Program, and copy and\r
+distribute such modifications or work under the terms of Section 1\r
+above, provided that you also meet all of these conditions:\r
+\r
+    a) You must cause the modified files to carry prominent notices\r
+    stating that you changed the files and the date of any change.\r
+\r
+    b) You must cause any work that you distribute or publish, that in\r
+    whole or in part contains or is derived from the Program or any\r
+    part thereof, to be licensed as a whole at no charge to all third\r
+    parties under the terms of this License.\r
+\r
+    c) If the modified program normally reads commands interactively\r
+    when run, you must cause it, when started running for such\r
+    interactive use in the most ordinary way, to print or display an\r
+    announcement including an appropriate copyright notice and a\r
+    notice that there is no warranty (or else, saying that you provide\r
+    a warranty) and that users may redistribute the program under\r
+    these conditions, and telling the user how to view a copy of this\r
+    License.  (Exception: if the Program itself is interactive but\r
+    does not normally print such an announcement, your work based on\r
+    the Program is not required to print an announcement.)\r
+\r
+These requirements apply to the modified work as a whole.  If\r
+identifiable sections of that work are not derived from the Program,\r
+and can be reasonably considered independent and separate works in\r
+themselves, then this License, and its terms, do not apply to those\r
+sections when you distribute them as separate works.  But when you\r
+distribute the same sections as part of a whole which is a work based\r
+on the Program, the distribution of the whole must be on the terms of\r
+this License, whose permissions for other licensees extend to the\r
+entire whole, and thus to each and every part regardless of who wrote it.\r
+\r
+Thus, it is not the intent of this section to claim rights or contest\r
+your rights to work written entirely by you; rather, the intent is to\r
+exercise the right to control the distribution of derivative or\r
+collective works based on the Program.\r
+\r
+In addition, mere aggregation of another work not based on the Program\r
+with the Program (or with a work based on the Program) on a volume of\r
+a storage or distribution medium does not bring the other work under\r
+the scope of this License.\r
+\r
+  3. You may copy and distribute the Program (or a work based on it,\r
+under Section 2) in object code or executable form under the terms of\r
+Sections 1 and 2 above provided that you also do one of the following:\r
+\r
+    a) Accompany it with the complete corresponding machine-readable\r
+    source code, which must be distributed under the terms of Sections\r
+    1 and 2 above on a medium customarily used for software interchange; or,\r
+\r
+    b) Accompany it with a written offer, valid for at least three\r
+    years, to give any third party, for a charge no more than your\r
+    cost of physically performing source distribution, a complete\r
+    machine-readable copy of the corresponding source code, to be\r
+    distributed under the terms of Sections 1 and 2 above on a medium\r
+    customarily used for software interchange; or,\r
+\r
+    c) Accompany it with the information you received as to the offer\r
+    to distribute corresponding source code.  (This alternative is\r
+    allowed only for noncommercial distribution and only if you\r
+    received the program in object code or executable form with such\r
+    an offer, in accord with Subsection b above.)\r
+\r
+The source code for a work means the preferred form of the work for\r
+making modifications to it.  For an executable work, complete source\r
+code means all the source code for all modules it contains, plus any\r
+associated interface definition files, plus the scripts used to\r
+control compilation and installation of the executable.  However, as a\r
+special exception, the source code distributed need not include\r
+anything that is normally distributed (in either source or binary\r
+form) with the major components (compiler, kernel, and so on) of the\r
+operating system on which the executable runs, unless that component\r
+itself accompanies the executable.\r
+\r
+If distribution of executable or object code is made by offering\r
+access to copy from a designated place, then offering equivalent\r
+access to copy the source code from the same place counts as\r
+distribution of the source code, even though third parties are not\r
+compelled to copy the source along with the object code.\r
+\r
+  4. You may not copy, modify, sublicense, or distribute the Program\r
+except as expressly provided under this License.  Any attempt\r
+otherwise to copy, modify, sublicense or distribute the Program is\r
+void, and will automatically terminate your rights under this License.\r
+However, parties who have received copies, or rights, from you under\r
+this License will not have their licenses terminated so long as such\r
+parties remain in full compliance.\r
+\r
+  5. You are not required to accept this License, since you have not\r
+signed it.  However, nothing else grants you permission to modify or\r
+distribute the Program or its derivative works.  These actions are\r
+prohibited by law if you do not accept this License.  Therefore, by\r
+modifying or distributing the Program (or any work based on the\r
+Program), you indicate your acceptance of this License to do so, and\r
+all its terms and conditions for copying, distributing or modifying\r
+the Program or works based on it.\r
+\r
+  6. Each time you redistribute the Program (or any work based on the\r
+Program), the recipient automatically receives a license from the\r
+original licensor to copy, distribute or modify the Program subject to\r
+these terms and conditions.  You may not impose any further\r
+restrictions on the recipients' exercise of the rights granted herein.\r
+You are not responsible for enforcing compliance by third parties to\r
+this License.\r
+\r
+  7. If, as a consequence of a court judgment or allegation of patent\r
+infringement or for any other reason (not limited to patent issues),\r
+conditions are imposed on you (whether by court order, agreement or\r
+otherwise) that contradict the conditions of this License, they do not\r
+excuse you from the conditions of this License.  If you cannot\r
+distribute so as to satisfy simultaneously your obligations under this\r
+License and any other pertinent obligations, then as a consequence you\r
+may not distribute the Program at all.  For example, if a patent\r
+license would not permit royalty-free redistribution of the Program by\r
+all those who receive copies directly or indirectly through you, then\r
+the only way you could satisfy both it and this License would be to\r
+refrain entirely from distribution of the Program.\r
+\r
+If any portion of this section is held invalid or unenforceable under\r
+any particular circumstance, the balance of the section is intended to\r
+apply and the section as a whole is intended to apply in other\r
+circumstances.\r
+\r
+It is not the purpose of this section to induce you to infringe any\r
+patents or other property right claims or to contest validity of any\r
+such claims; this section has the sole purpose of protecting the\r
+integrity of the free software distribution system, which is\r
+implemented by public license practices.  Many people have made\r
+generous contributions to the wide range of software distributed\r
+through that system in reliance on consistent application of that\r
+system; it is up to the author/donor to decide if he or she is willing\r
+to distribute software through any other system and a licensee cannot\r
+impose that choice.\r
+\r
+This section is intended to make thoroughly clear what is believed to\r
+be a consequence of the rest of this License.\r
+\r
+  8. If the distribution and/or use of the Program is restricted in\r
+certain countries either by patents or by copyrighted interfaces, the\r
+original copyright holder who places the Program under this License\r
+may add an explicit geographical distribution limitation excluding\r
+those countries, so that distribution is permitted only in or among\r
+countries not thus excluded.  In such case, this License incorporates\r
+the limitation as if written in the body of this License.\r
+\r
+  9. The Free Software Foundation may publish revised and/or new versions\r
+of the General Public License from time to time.  Such new versions will\r
+be similar in spirit to the present version, but may differ in detail to\r
+address new problems or concerns.\r
+\r
+Each version is given a distinguishing version number.  If the Program\r
+specifies a version number of this License which applies to it and "any\r
+later version", you have the option of following the terms and conditions\r
+either of that version or of any later version published by the Free\r
+Software Foundation.  If the Program does not specify a version number of\r
+this License, you may choose any version ever published by the Free Software\r
+Foundation.\r
+\r
+  10. If you wish to incorporate parts of the Program into other free\r
+programs whose distribution conditions are different, write to the author\r
+to ask for permission.  For software which is copyrighted by the Free\r
+Software Foundation, write to the Free Software Foundation; we sometimes\r
+make exceptions for this.  Our decision will be guided by the two goals\r
+of preserving the free status of all derivatives of our free software and\r
+of promoting the sharing and reuse of software generally.\r
+\r
+                           NO WARRANTY\r
+\r
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\r
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\r
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\r
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\r
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\r
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\r
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\r
+REPAIR OR CORRECTION.\r
+\r
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\r
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\r
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\r
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\r
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\r
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\r
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\r
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\r
+POSSIBILITY OF SUCH DAMAGES.\r
+\r
+                    END OF TERMS AND CONDITIONS\r
+\r
+           How to Apply These Terms to Your New Programs\r
+\r
+  If you develop a new program, and you want it to be of the greatest\r
+possible use to the public, the best way to achieve this is to make it\r
+free software which everyone can redistribute and change under these terms.\r
+\r
+  To do so, attach the following notices to the program.  It is safest\r
+to attach them to the start of each source file to most effectively\r
+convey the exclusion of warranty; and each file should have at least\r
+the "copyright" line and a pointer to where the full notice is found.\r
+\r
+    <one line to give the program's name and a brief idea of what it does.>\r
+    Copyright (C) <year>  <name of author>\r
+\r
+    This program is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License along\r
+    with this program; if not, write to the Free Software Foundation, Inc.,\r
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
+\r
+Also add information on how to contact you by electronic and paper mail.\r
+\r
+If the program is interactive, make it output a short notice like this\r
+when it starts in an interactive mode:\r
+\r
+    Gnomovision version 69, Copyright (C) year name of author\r
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\r
+    This is free software, and you are welcome to redistribute it\r
+    under certain conditions; type `show c' for details.\r
+\r
+The hypothetical commands `show w' and `show c' should show the appropriate\r
+parts of the General Public License.  Of course, the commands you use may\r
+be called something other than `show w' and `show c'; they could even be\r
+mouse-clicks or menu items--whatever suits your program.\r
+\r
+You should also get your employer (if you work as a programmer) or your\r
+school, if any, to sign a "copyright disclaimer" for the program, if\r
+necessary.  Here is a sample; alter the names:\r
+\r
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\r
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.\r
+\r
+  <signature of Ty Coon>, 1 April 1989\r
+  Ty Coon, President of Vice\r
+\r
+This General Public License does not permit incorporating your program into\r
+proprietary programs.  If your program is a subroutine library, you may\r
+consider it more useful to permit linking proprietary applications with the\r
+library.  If this is what you want to do, use the GNU Lesser General\r
+Public License instead of this License.\r
diff --git a/modulo-d-amp/Makefile b/modulo-d-amp/Makefile
new file mode 100644 (file)
index 0000000..c3cef0a
--- /dev/null
@@ -0,0 +1,525 @@
+# WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al.\r
+# Released to the Public Domain\r
+# Please read the make user manual!\r
+#\r
+# Additional material for this makefile was submitted by:\r
+#  Tim Henigan\r
+#  Peter Fleury\r
+#  Reiner Patommel\r
+#  Sander Pool\r
+#  Frederik Rouleau\r
+#  Markus Pfaff\r
+#\r
+# On command line:\r
+#\r
+# make all = Make software.\r
+#\r
+# make clean = Clean out built project files.\r
+#\r
+# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB).\r
+#\r
+# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio\r
+#                4.07 or greater).\r
+#\r
+# make program = Download the hex file to the device, using avrdude.  Please\r
+#                customize the avrdude settings below first!\r
+#\r
+# make filename.s = Just compile filename.c into the assembler code only\r
+#\r
+# To rebuild project do "make clean" then "make all".\r
+#\r
+# Compiler: AVR-GCC 4.2.2 / WinAVR 20071221\r
+\r
+############################### MCU-, Quarz u. Versionseinstellung ####################\r
+\r
+# MCU name\r
+MCU = atmega8\r
+\r
+# Processor frequency.\r
+#     This will define a symbol, F_CPU, in all source code files equal to the \r
+#     processor frequency. You can then use this symbol in your source code to \r
+#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done\r
+#     automatically to create a 32-bit value in your source code.\r
+F_CPU =  8000000\r
+\r
+#Projektname\r
+PRJNAME        = ClassD\r
+# Major Version\r
+VER_MAJOR = 01\r
+\r
+#Minor Version\r
+VER_MINOR = 00\r
+\r
+#TARDIR = ./target\r
+TARDIR = ./target/$(MCU)\r
+\r
+# Target file name (without extension).\r
+TARGET = $(TARDIR)/$(PRJNAME)V$(VER_MAJOR).$(VER_MINOR)\r
+\r
+# Output format. (can be srec, ihex, binary)\r
+FORMAT = ihex\r
+\r
+############################## Sourcefiles ##########################################\r
+\r
+# List C source files here. (C dependencies are automatically generated.)\r
+SRC = main.c\r
+SRC += iic.c max9744.c tda7449.c lcd.c rc5.c\r
+\r
+\r
+# List Assembler source files here.\r
+#     Make them always end in a capital .S.  Files ending in a lowercase .s\r
+#     will not be considered source files but generated files (assembler\r
+#     output from the compiler), and will be deleted upon "make clean"!\r
+#     Even though the DOS/Win* filesystem matches both .s and .S the same,\r
+#     it will preserve the spelling of the filenames, and gcc itself does\r
+#     care about how the name is spelled on its command-line.\r
+ASRC = \r
+\r
+\r
+# Optimization level, can be [0, 1, 2, 3, s]. \r
+#     0 = turn off optimization. s = optimize for size.\r
+#     (Note: 3 is not always the best optimization level. See avr-libc FAQ.)\r
+OPT = s\r
+\r
+\r
+# Debugging format.\r
+#     Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.\r
+#     AVR Studio 4.10 requires dwarf-2.\r
+#     AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.\r
+DEBUG = dwarf-2\r
+\r
+\r
+# List any extra directories to look for include files here.\r
+#     Each directory must be seperated by a space.\r
+#     Use forward slashes for directory separators.\r
+#     For a directory that has spaces, enclose it in quotes.\r
+EXTRAINCDIRS = \r
+\r
+\r
+# Compiler flag to set the C Standard level.\r
+#     c89   = "ANSI" C\r
+#     gnu89 = c89 plus GCC extensions\r
+#     c99   = ISO C99 standard (not yet fully implemented)\r
+#     gnu99 = c99 plus GCC extensions\r
+CSTANDARD = -std=gnu99\r
+\r
+\r
+# Place -D or -U options here\r
+CDEFS = -DF_CPU=$(F_CPU)UL -DVER_MAJOR=$(VER_MAJOR) -DVER_MINOR=$(VER_MINOR)\r
+\r
+\r
+# Place -I options here\r
+CINCS =\r
+\r
+#---------------- Compiler Options ----------------\r
+#  -g*:          generate debugging information\r
+#  -O*:          optimization level\r
+#  -f...:        tuning, see GCC manual and avr-libc documentation\r
+#  -Wall...:     warning level\r
+#  -Wa,...:      tell GCC to pass this to the assembler.\r
+#    -adhlns...: create assembler listing\r
+CFLAGS = -g$(DEBUG)\r
+CFLAGS += $(CDEFS) $(CINCS)\r
+CFLAGS += -O$(OPT)\r
+CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums\r
+CFLAGS += -Wall -Wstrict-prototypes\r
+CFLAGS += -Wa,-adhlns=$(<:.c=.lst)\r
+CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))\r
+CFLAGS += $(CSTANDARD)\r
+\r
+\r
+#---------------- Assembler Options ----------------\r
+#  -Wa,...:   tell GCC to pass this to the assembler.\r
+#  -ahlms:    create listing\r
+#  -gstabs:   have the assembler create line number information; note that\r
+#             for use in COFF files, additional information about filenames\r
+#             and function names needs to be present in the assembler source\r
+#             files -- see avr-libc docs [FIXME: not yet described there]\r
+#  -listing-cont-lines: Sets the maximum number of continuation lines of hex \r
+#       dump that will be displayed for a given single line of source input.\r
+ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs,--listing-cont-lines=100\r
+\r
+\r
+#---------------- Library Options ----------------\r
+# Minimalistic printf version\r
+#PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min\r
+\r
+# Floating point printf version (requires MATH_LIB = -lm below)\r
+#PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt\r
+\r
+# If this is left blank, then it will use the Standard printf version.\r
+PRINTF_LIB = \r
+#PRINTF_LIB = $(PRINTF_LIB_MIN)\r
+#PRINTF_LIB = $(PRINTF_LIB_FLOAT)\r
+\r
+\r
+# Minimalistic scanf version\r
+#SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min\r
+\r
+# Floating point + %[ scanf version (requires MATH_LIB = -lm below)\r
+#SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt\r
+\r
+# If this is left blank, then it will use the Standard scanf version.\r
+SCANF_LIB = \r
+#SCANF_LIB = $(SCANF_LIB_MIN)\r
+#SCANF_LIB = $(SCANF_LIB_FLOAT)\r
+\r
+\r
+MATH_LIB = -lm\r
+\r
+\r
+\r
+#---------------- External Memory Options ----------------\r
+\r
+# 64 KB of external RAM, starting after internal RAM (ATmega128!),\r
+# used for variables (.data/.bss) and heap (malloc()).\r
+#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff\r
+\r
+# 64 KB of external RAM, starting after internal RAM (ATmega128!),\r
+# only used for heap (malloc()).\r
+#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff\r
+\r
+EXTMEMOPTS =\r
+\r
+\r
+\r
+#---------------- Linker Options ----------------\r
+#  -Wl,...:     tell GCC to pass this to linker.\r
+#    -Map:      create map file\r
+#    --cref:    add cross reference to  map file\r
+#\r
+# Beispiel f. eigene Sektion:\r
+# LDFLAGS = -Wl,--section-start=.mySection=0x6000,-Map=$(TARGET).map,--cref\r
+# Im Programm dann:\r
+# const char version[6] __attribute__ ((section (".mySection"))) = {1,2,3,4,5,6};\r
+#\r
+LDFLAGS = -Wl,-Map=$(TARGET).map,--cref\r
+LDFLAGS += $(EXTMEMOPTS)\r
+LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)\r
+\r
+\r
+\r
+#---------------- Programming Options (avrdude) ----------------\r
+\r
+# Programming hardware: alf avr910 avrisp bascom bsd \r
+# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500\r
+#\r
+# Type: avrdude -c ?\r
+# to get a full listing.\r
+#\r
+#AVRDUDE_PROGRAMMER = stk500\r
+AVRDUDE_PROGRAMMER = avrispv2\r
+\r
+# com1 = serial port. Use lpt1 to connect to parallel port.\r
+#AVRDUDE_PORT = com1    # programmer connected to serial device\r
+AVRDUDE_PORT = usb\r
+\r
+AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex\r
+#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(OUTDIR)/$(TARGET).eep\r
+\r
+\r
+# Uncomment the following if you want avrdude's erase cycle counter.\r
+# Note that this counter needs to be initialized first using -Yn,\r
+# see avrdude manual.\r
+#AVRDUDE_ERASE_COUNTER = -y\r
+\r
+# Uncomment the following if you do /not/ wish a verification to be\r
+# performed after programming the device.\r
+#AVRDUDE_NO_VERIFY = -V\r
+\r
+# Increase verbosity level.  Please use this when submitting bug\r
+# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> \r
+# to submit bug reports.\r
+#AVRDUDE_VERBOSE = -v -v\r
+\r
+AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)\r
+AVRDUDE_FLAGS += -B 10\r
+#AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)\r
+AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)\r
+AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)\r
+\r
+\r
+\r
+#---------------- Debugging Options ----------------\r
+\r
+# For simulavr only - target MCU frequency.\r
+DEBUG_MFREQ = $(F_CPU)\r
+\r
+# Set the DEBUG_UI to either gdb or insight.\r
+# DEBUG_UI = gdb\r
+DEBUG_UI = insight\r
+\r
+# Set the debugging back-end to either avarice, simulavr.\r
+DEBUG_BACKEND = avarice\r
+#DEBUG_BACKEND = simulavr\r
+\r
+# GDB Init Filename.\r
+GDBINIT_FILE = __avr_gdbinit\r
+\r
+# When using avarice settings for the JTAG\r
+JTAG_DEV = /dev/com1\r
+\r
+# Debugging port used to communicate between GDB / avarice / simulavr.\r
+DEBUG_PORT = 4242\r
+\r
+# Debugging host used to communicate between GDB / avarice / simulavr, normally\r
+#     just set to localhost unless doing some sort of crazy debugging when \r
+#     avarice is running on a different computer.\r
+DEBUG_HOST = localhost\r
+\r
+\r
+\r
+#============================================================================\r
+\r
+\r
+# Define programs and commands.\r
+SHELL = sh\r
+CC = avr-gcc\r
+OBJCOPY = avr-objcopy\r
+OBJDUMP = avr-objdump\r
+SIZE = avr-size\r
+NM = avr-nm\r
+AVRDUDE = avrdude\r
+REMOVE = rm -f\r
+COPY = cp\r
+WINSHELL = cmd\r
+\r
+\r
+# Define Messages\r
+# English\r
+MSG_ERRORS_NONE = Errors: none\r
+MSG_BEGIN = -------- begin --------\r
+MSG_END = --------  end  --------\r
+MSG_SIZE_BEFORE = Size before: \r
+MSG_SIZE_AFTER = Size after:\r
+MSG_COFF = Converting to AVR COFF:\r
+MSG_EXTENDED_COFF = Converting to AVR Extended COFF:\r
+MSG_FLASH = Creating load file for Flash:\r
+MSG_EEPROM = Creating load file for EEPROM:\r
+MSG_EXTENDED_LISTING = Creating Extended Listing:\r
+MSG_SYMBOL_TABLE = Creating Symbol Table:\r
+MSG_LINKING = Linking:\r
+MSG_COMPILING = Compiling:\r
+MSG_ASSEMBLING = Assembling:\r
+MSG_CLEANING = Cleaning project:\r
+\r
+\r
+# Define all object files.\r
+OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) \r
+\r
+# Define all listing files.\r
+LST = $(SRC:.c=.lst) $(ASRC:.S=.lst) \r
+\r
+\r
+# Compiler flags to generate dependency files.\r
+GENDEPFLAGS = -MD -MP -MF $(TARDIR)\dep/$(@F).d\r
+\r
+\r
+# Combine all necessary flags and optional flags.\r
+# Add target processor to flags.\r
+ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)\r
+ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)\r
+\r
+\r
+\r
+# Default target.\r
+all: begin gccversion sizebefore mk_tardir build sizeafter end\r
+\r
+build: elf hex eep lss sym\r
+\r
+elf: $(TARGET).elf\r
+hex: $(TARGET).hex\r
+eep: $(TARGET).eep\r
+lss: $(TARGET).lss \r
+sym: $(TARGET).sym\r
+\r
+\r
+\r
+# Eye candy.\r
+# AVR Studio 3.x does not check make's exit code but relies on\r
+# the following magic strings to be generated by the compile job.\r
+begin:\r
+       @echo\r
+       @echo $(MSG_BEGIN)\r
+\r
+end:\r
+       @echo $(MSG_END)\r
+       @echo\r
+\r
+\r
+# Display size of file.\r
+HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex\r
+ELFSIZE = $(SIZE) --format=avr --mcu=$(MCU) $(TARGET).elf\r
+\r
+sizebefore:\r
+       @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \\r
+       2>/dev/null; echo; fi\r
+\r
+sizeafter:\r
+       @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \\r
+       2>/dev/null; echo; fi\r
+\r
+# Create MCU-depending target-Dir\r
+mk_tardir:\r
+       mkdir -p $(TARDIR)\r
+       mkdir -p $(TARDIR)\dep\r
+       mkdir -p $(TARDIR)\obj\r
+\r
+# Zip *.c, *.h, *.txt, *.hex, *.eep and VC6++ projectfiles\r
+# Be carefull if subdirs or other filetypes used - check that every file comes into the *.zip\r
+zip:\r
+       zip -r $(TARGET).zip $(SRC) $(SRC:.c=.h) $(ASRC) $(ASRC:.s=.h) *.h *.dsp *.dsw makefile *.txt $(TARGET).hex $(TARGET).eep\r
+       make clean\r
+\r
+# Display compiler version information.\r
+gccversion : \r
+       @$(CC) --version\r
+\r
+\r
+\r
+# Program the device.  \r
+program: $(TARGET).hex $(TARGET).eep\r
+       $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)\r
+\r
+\r
+# Generate avr-gdb config/init file which does the following:\r
+#     define the reset signal, load the target file, connect to target, and set \r
+#     a breakpoint at main().\r
+gdb-config: \r
+       @$(REMOVE) $(GDBINIT_FILE)\r
+       @echo define reset >> $(GDBINIT_FILE)\r
+       @echo SIGNAL SIGHUP >> $(GDBINIT_FILE)\r
+       @echo end >> $(GDBINIT_FILE)\r
+       @echo file $(TARGET).elf >> $(GDBINIT_FILE)\r
+       @echo target remote $(DEBUG_HOST):$(DEBUG_PORT)  >> $(GDBINIT_FILE)\r
+ifeq ($(DEBUG_BACKEND),simulavr)\r
+       @echo load  >> $(GDBINIT_FILE)\r
+endif  \r
+       @echo break main >> $(GDBINIT_FILE)\r
+       \r
+debug: gdb-config $(TARGET).elf\r
+ifeq ($(DEBUG_BACKEND), avarice)\r
+       @echo Starting AVaRICE - Press enter when "waiting to connect" message displays.\r
+       @$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \\r
+       $(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)\r
+       @$(WINSHELL) /c pause\r
+       \r
+else\r
+       @$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \\r
+       $(DEBUG_MFREQ) --port $(DEBUG_PORT)\r
+endif\r
+       @$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)\r
+       \r
+\r
+\r
+\r
+# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.\r
+COFFCONVERT=$(OBJCOPY) --debugging \\r
+--change-section-address .data-0x800000 \\r
+--change-section-address .bss-0x800000 \\r
+--change-section-address .noinit-0x800000 \\r
+--change-section-address .eeprom-0x810000\r
+\r
+\r
+coff: $(TARGET).elf\r
+       @echo\r
+       @echo $(MSG_COFF) $(TARGET).cof\r
+       $(COFFCONVERT) -O coff-avr $< $(TARGET).cof\r
+\r
+\r
+extcoff: $(TARGET).elf\r
+       @echo\r
+       @echo $(MSG_EXTENDED_COFF) $(TARGET).cof\r
+       $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof\r
+\r
+\r
+\r
+# Create final output files (.hex, .eep) from ELF output file.\r
+%.hex: %.elf\r
+       @echo\r
+       @echo $(MSG_FLASH) $@\r
+       $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@\r
+\r
+%.eep: %.elf\r
+       @echo\r
+       @echo $(MSG_EEPROM) $@\r
+       -$(OBJCOPY) -j .eeprom --set-section-flags .eeprom=alloc,load \\r
+       --change-section-lma .eeprom=0 -O $(FORMAT) $< $@\r
+\r
+# Create extended listing file from ELF output file.\r
+%.lss: %.elf\r
+       @echo\r
+       @echo $(MSG_EXTENDED_LISTING) $@\r
+       $(OBJDUMP) -h -S $< > $@\r
+\r
+# Create a symbol table from ELF output file.\r
+%.sym: %.elf\r
+       @echo\r
+       @echo $(MSG_SYMBOL_TABLE) $@\r
+       $(NM) -n $< > $@\r
+\r
+\r
+\r
+# Link: create ELF output file from object files.\r
+.SECONDARY : $(TARGET).elf\r
+.PRECIOUS : $(OBJ)\r
+%.elf: $(OBJ)\r
+       @echo\r
+       @echo $(MSG_LINKING) $@\r
+       $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)\r
+\r
+\r
+# Compile: create object files from C source files.\r
+%.o : %.c\r
+       @echo\r
+       @echo $(MSG_COMPILING) $<\r
+       $(CC) -c $(ALL_CFLAGS) $< -o $@ \r
+\r
+\r
+# Compile: create assembler files from C source files.\r
+%.s : %.c\r
+       $(CC) -S $(ALL_CFLAGS) $< -o $@\r
+\r
+\r
+# Assemble: create object files from assembler source files.\r
+%.o : %.S\r
+       @echo\r
+       @echo $(MSG_ASSEMBLING) $<\r
+       $(CC) -c $(ALL_ASFLAGS) $< -o $@\r
+\r
+# Create preprocessed source for use in sending a bug report.\r
+%.i : %.c\r
+       $(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@ \r
+\r
+\r
+# Target: clean project.\r
+clean: begin clean_list end\r
+\r
+clean_list :\r
+       @echo\r
+       @echo $(MSG_CLEANING)\r
+       $(REMOVE) $(TARGET).hex\r
+       $(REMOVE) $(TARGET).eep\r
+       $(REMOVE) $(TARGET).cof\r
+       $(REMOVE) $(TARGET).elf\r
+       $(REMOVE) $(TARGET).map\r
+       $(REMOVE) $(TARGET).sym\r
+       $(REMOVE) $(TARGET).lss\r
+       $(REMOVE) $(OBJ)\r
+       $(REMOVE) $(LST)\r
+       $(REMOVE) $(SRC:.c=.s)\r
+       $(REMOVE) $(SRC:.c=.d)\r
+       $(REMOVE) $(SRC:.c=.i)  \r
+       $(REMOVE) $(TARDIR)\dep/*\r
+\r
+\r
+\r
+# Include the dependency files.\r
+-include $($(TARDIR)\dep 2>/dev/null) $(wildcard $(TARDIR)\dep/*)\r
+\r
+\r
+# Listing of phony targets.\r
+.PHONY : all begin finish end sizebefore sizeafter gccversion \\r
+build elf hex eep lss sym coff extcoff \\r
+clean clean_list program debug gdb-config mk_tardir zip\r
+\r
diff --git a/modulo-d-amp/common.h b/modulo-d-amp/common.h
new file mode 100644 (file)
index 0000000..45d221e
--- /dev/null
@@ -0,0 +1,81 @@
+/*************************************************************************\r
+Author:    Frank Nitzsche\r
+License:   GNU GPL v2 (see License.txt)\r
+File:      common.h\r
+Version:   16.02.09\r
+Compiler:  AVR-GCC\r
+**************************************************************************/\r
+#ifndef COMMON_DEF\r
+#define COMMON_DEF\r
+\r
+#include <avr/io.h>\r
+\r
+/** \r
+ *  @name  AVR und PC kompatible Variablentypdefinitionen \r
+ */\r
+//@{\r
+/** 8-Bit-Variable vorzeichenlos*/\r
+typedef unsigned char U8;\r
+/** 8-Bit-Variable vorzeichenbehaftet */\r
+typedef signed char S8;\r
+/** der Vollständigkeit halber */\r
+typedef char CHAR;\r
+/** 16-Bit-Variable vorzeichenlos */\r
+typedef unsigned int U16;\r
+/** 16-Bit-Variable vorzeichenbehaftet */\r
+typedef signed short S16;\r
+/** 32-Bit-Variable vorzeichenlos */\r
+typedef unsigned long  U32;\r
+/** 32-Bit-Variable vorzeichenbehaftet */\r
+typedef signed long  S32;\r
+//@}\r
+\r
+typedef enum{\r
+   FALSE=(1!=1),\r
+   TRUE =(1==1),\r
+}BOOL;\r
+\r
+\r
+#ifndef  NULL\r
+#define  NULL ((void*) 0)\r
+#endif\r
+\r
+#define DIV3(x)   (((((((x>>1)+x)>>2)+x)>>2)+x)>>2)   //Real ~= x/2.977, 23MaschinenZyklen, bis 16Bit brauchbar\r
+\r
+/////////////////////////// Hardware ///////////////////////////////\r
+\r
+/**\r
+* @name HAL-Macros\r
+*/\r
+#define LOGIC_POSITIV 1\r
+#define LOGIC_NEGATIV 0\r
+\r
+/** Fires connected hardware, level might be Hi or Lo depending on logic type */\r
+#define PIN_ACTIV_INTERN(LogicType,Port,Pin) ( PORT##Port = LogicType? PORT##Port | (1<<Pin) : PORT##Port & ~(1<<Pin) )\r
+#define PIN_ACTIV(x) PIN_ACTIV_INTERN(x)\r
+\r
+/** Releases connected hardware, level might be Hi or Lo depending on logic type */\r
+#define PIN_PASSIV_INTERN(LogicType,Port,Pin) ( PORT##Port = LogicType? PORT##Port & ~(1<<Pin) : PORT##Port | (1<<Pin) )\r
+#define PIN_PASSIV(x) PIN_PASSIV_INTERN(x)\r
+\r
+/** Toggles the state from Hi to Lo and vice versa */\r
+#define PIN_TOGGLE_INTERN(LogicType,Port,Pin) (PORT##Port ^= (1<<Pin))\r
+#define PIN_TOGGLE(x) PIN_TOGGLE_INTERN(x)\r
+\r
+/** Reads the Input level, result is logic type depended */\r
+#define PIN_READ_INTERN(LogicType,Port,Pin) ( LogicType? PIN##Port & (1<<Pin)? 1: 0 : PIN##Port & (1<<Pin)? 0: 1 )\r
+#define PIN_READ(x) PIN_READ_INTERN(x)\r
+\r
+/** Initialises the Pin as output. Previous set Level won't be affected */\r
+#define PIN_INIT_INTERN(LogicType,Port,Pin) (DDR##Port |= (1<<Pin))\r
+#define PIN_INIT(x) PIN_INIT_INTERN(x)\r
+\r
+/** Initialises the Pin as Input and disables Pullup */\r
+#define PIN_FLOAT_INTERN(LogicType,Port,Pin) (DDR##Port &= ~(1<<Pin))\r
+#define PIN_FLOAT(x) PIN_FLOAT_INTERN(x); PIN_PASSIV_INTERN(x)\r
+\r
+/** Initialises the Pin as Input and enables Pullup */\r
+#define PIN_PULLUP_INTERN(LogicType,Port,Pin) (DDR##Port &= ~(1<<Pin); PORT##Port | (1<<Pin))\r
+#define PIN_PULLUP(x) PIN_PULLUP_INTERN(x)\r
+\r
+#endif /*COMMON_DEF*/\r
diff --git a/modulo-d-amp/iic.c b/modulo-d-amp/iic.c
new file mode 100644 (file)
index 0000000..737a60d
--- /dev/null
@@ -0,0 +1,133 @@
+/*************************************************************************\r
+Copyright: (c) 2009 Stange-Distribution Simone Stange, Berlin\r
+Contact:   info@obd-shop.com\r
+License:   GNU GPL v2 (see License.txt)\r
+Author:    Frank Nitzsche classd@beta-x.de\r
+File:      iic.c\r
+Version:   16.02.09\r
+Compiler:  AVR-GCC\r
+**************************************************************************/\r
+\r
+#include <util/twi.h>\r
+#include "iic.h"\r
+\r
+\r
+/*************************************************************************/\r
+void init_iic(U16 Khz){\r
+/*************************************************************************/\r
+   TWSR = 0;\r
+   TWBR = (F_CPU / Khz / 1000 - 16) / 2;\r
+}\r
+\r
+/*************************************************************************/\r
+BOOL start_iic(U8 address){\r
+   /*************************************************************************/\r
+   \r
+   U8 TwSt;\r
+   U8 Tout=MAX_ITER;\r
+   \r
+   while(Tout)\r
+   {\r
+      Tout--;\r
+      // send START condition\r
+      TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);\r
+      \r
+      // wait until transmission completed\r
+      while(!(TWCR & (1<<TWINT)));\r
+      \r
+      // check value of TWI Status Register. Mask prescaler bits.\r
+      TwSt = TW_STATUS & 0xF8;\r
+      if ( (TwSt != TW_START) && (TwSt != TW_REP_START)) continue;\r
+      \r
+      // send device address\r
+      TWDR = address;\r
+      TWCR = (1<<TWINT) | (1<<TWEN);\r
+      \r
+      // wail until transmission completed\r
+      while(!(TWCR & (1<<TWINT)));\r
+      \r
+      // check value of TWI Status Register. Mask prescaler bits.\r
+      TwSt = TW_STATUS & 0xF8;\r
+      if ( (TwSt == TW_MT_SLA_NACK )||(TwSt ==TW_MR_DATA_NACK) ) \r
+      {            \r
+           // device busy, send stop condition to terminate write operation \r
+         TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);\r
+               \r
+               // wait until stop condition is executed and bus released\r
+               while(TWCR & (1<<TWSTO));\r
+           \r
+           continue;\r
+      }\r
+      break;\r
+   }\r
+   \r
+   return (Tout > 0);   // TRUE -> Success\r
+}\r
+/*************************************************************************/\r
+int rep_start_iic(U8 address){\r
+/*************************************************************************/\r
+\r
+        /* Returnwerte:\r
+        * 0 -> Success\r
+        * 1 -> Problem when issuing start conditions\r
+        * 2 -> Problem when sending address\r
+        *      or no Device with specified address\r
+        */\r
+\r
+       TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);\r
+\r
+       while(!(TWCR & (1<<TWINT)));\r
+\r
+       if((TWSR & 0xF8) != TW_REP_START) return 1;\r
+\r
+\r
+       TWDR = address;\r
+       TWCR = (1<<TWINT) | (1<<TWEN);\r
+\r
+       while(!(TWCR & (1<<TWINT)));\r
+\r
+       if((TWSR & 0xF8) != TW_MR_SLA_ACK) return 2;\r
+\r
+       return 0;\r
+}\r
+\r
+/*************************************************************************/\r
+void stop_iic(void){\r
+/*************************************************************************/\r
+       TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);\r
+}\r
+\r
+/*************************************************************************/\r
+void write_iic(U8 data){\r
+/*************************************************************************/\r
+       TWDR = data;\r
+       TWCR = (1<<TWINT) | (1<<TWEN);\r
+\r
+       while(!(TWCR & (1<<TWINT)));\r
+}\r
+\r
+/*************************************************************************/\r
+U8 read_iic_ack(void){\r
+/*************************************************************************/\r
+        /* For all bytes except the last one\r
+        */\r
+       TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);\r
+\r
+       while(!(TWCR & (1<<TWINT)));\r
+\r
+       if((TWSR & 0xF8) == TW_MR_DATA_ACK) return TWDR;\r
+       return 1;\r
+}\r
+\r
+/*************************************************************************/\r
+U8 read_iic_nack(void){\r
+/*************************************************************************/\r
+        /* For the last byte\r
+        */\r
+       TWCR = (1<<TWINT) | (1<<TWEN);\r
+\r
+       while(!(TWCR & (1<<TWINT)));\r
+\r
+       if((TWSR & 0xF8) == TW_MR_DATA_NACK) return TWDR;\r
+       return 2;\r
+}\r
diff --git a/modulo-d-amp/iic.h b/modulo-d-amp/iic.h
new file mode 100644 (file)
index 0000000..f6b2fe0
--- /dev/null
@@ -0,0 +1,34 @@
+/*************************************************************************\r
+Copyright: (c) 2009 Stange-Distribution Simone Stange, Berlin\r
+Contact:   info@obd-shop.com\r
+License:   GNU GPL v2 (see License.txt)\r
+Author:    Frank Nitzsche classd@beta-x.de\r
+File:      iic.h\r
+Version:   16.02.09\r
+Compiler:  AVR-GCC\r
+**************************************************************************/\r
+#ifndef IIC_DEF\r
+#define IIC_DEF\r
+\r
+#include "common.h"\r
+\r
+#define MAX_ITER 10       // Cancel if slave not responds\r
+\r
+//////////////////////////////////////////////////////////////////////////\r
+void init_iic(U16 Khz);\r
+//////////////////////////////////////////////////////////////////////////\r
+BOOL start_iic(unsigned char address);      // TRUE if success\r
+//////////////////////////////////////////////////////////////////////////\r
+int rep_start_iic(unsigned char address);\r
+//////////////////////////////////////////////////////////////////////////\r
+void stop_iic(void);\r
+//////////////////////////////////////////////////////////////////////////\r
+void write_iic(U8 data);\r
+//////////////////////////////////////////////////////////////////////////\r
+U8 read_iic_ack(void);\r
+//////////////////////////////////////////////////////////////////////////\r
+U8 read_iic_nack(void);\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+#endif//IIC_DEF\r
diff --git a/modulo-d-amp/lcd.c b/modulo-d-amp/lcd.c
new file mode 100644 (file)
index 0000000..46bb6a2
--- /dev/null
@@ -0,0 +1,414 @@
+/*************************************************************************\r
+Copyright: (c) 2009 Stange-Distribution Simone Stange, Berlin\r
+Contact:   info@obd-shop.com\r
+License:   GNU GPL v2 (see License.txt)\r
+Author:    Frank Nitzsche classd@beta-x.de\r
+File:      lcd.c\r
+Version:   16.02.09\r
+Compiler:  AVR-GCC\r
+**************************************************************************/\r
+\r
+#include <inttypes.h>\r
+#include <avr/pgmspace.h>\r
+#include <util/delay.h>\r
+#include "lcd.h"\r
+\r
+\r
+/*\r
+** local functions\r
+*/\r
+\r
+\r
+/*************************************************************************\r
+delay_ms for a minimum of <ms> microseconds\r
+*************************************************************************/\r
+static void delay_ms(U16 ms){\r
+   while(ms){\r
+      _delay_ms(1);\r
+      ms--;\r
+   }\r
+}\r
+\r
+/*************************************************************************\r
+toggle Enable Pin to initiate write\r
+*************************************************************************/\r
+static void lcd_e_toggle(void)\r
+{\r
+   PIN_ACTIV(LCD_EN_IO);\r
+   asm volatile("nop");                                                                        \r
+   PIN_PASSIV(LCD_EN_IO);\r
+}\r
+\r
+/*************************************************************************\r
+loops while lcd is busy.\r
+*************************************************************************/\r
+static void lcd_waitbusy(void)\r
+{\r
+   delay_ms(2);   \r
+}\r
+\r
+/*************************************************************************\r
+Low-level function to write byte to LCD controller\r
+Input:    data   byte to write to LCD\r
+rs     1: write data    \r
+0: write instruction\r
+*************************************************************************/\r
+static void lcd_write(uint8_t data,uint8_t rs) \r
+{\r
+   if (rs) {   /* write data        (RS=1, RW=0) */\r
+      PIN_ACTIV(LCD_RS_IO);\r
+   }\r
+   else {    /* write instruction (RS=0, RW=0) */\r
+      PIN_PASSIV(LCD_RS_IO);\r
+   }\r
+   \r
+   /* output high nibble first */\r
+   PIN_PASSIV(LCD_D3_IO);\r
+   PIN_PASSIV(LCD_D2_IO);\r
+   PIN_PASSIV(LCD_D1_IO);\r
+   PIN_PASSIV(LCD_D0_IO);\r
+   if(data & 0x80) PIN_ACTIV(LCD_D3_IO);\r
+   if(data & 0x40) PIN_ACTIV(LCD_D2_IO);\r
+   if(data & 0x20) PIN_ACTIV(LCD_D1_IO);\r
+   if(data & 0x10) PIN_ACTIV(LCD_D0_IO);\r
+   lcd_e_toggle();\r
+   \r
+   /* output low nibble */\r
+   PIN_PASSIV(LCD_D3_IO);\r
+   PIN_PASSIV(LCD_D2_IO);\r
+   PIN_PASSIV(LCD_D1_IO);\r
+   PIN_PASSIV(LCD_D0_IO);\r
+   if(data & 0x08) PIN_ACTIV(LCD_D3_IO);\r
+   if(data & 0x04) PIN_ACTIV(LCD_D2_IO);\r
+   if(data & 0x02) PIN_ACTIV(LCD_D1_IO);\r
+   if(data & 0x01) PIN_ACTIV(LCD_D0_IO);\r
+   lcd_e_toggle();        \r
+}\r
+\r
+/**************************************************************************\r
+Send LCD controller instruction command\r
+**************************************************************************/\r
+static void lcd_command(uint8_t cmd){\r
+   lcd_waitbusy();\r
+   lcd_write(cmd,0);\r
+}\r
+\r
+\r
+/**************************************************************************\r
+Send data byte to LCD controller \r
+**************************************************************************/\r
+static void lcd_data(uint8_t data){\r
+   lcd_waitbusy();\r
+   lcd_write(data,1);\r
+}\r
+\r
+//Bargraph custom chars\r
+static const U8 CustomChar[][8] PROGMEM ={\r
+   {\r
+      0x10,   // ---10000     //Bit pattern 5x8\r
+      0x10,   // ---10000\r
+      0x10,   // ---10000\r
+      0x15,   // ---10101\r
+      0x10,   // ---10000\r
+      0x10,   // ---10000\r
+      0x10,   // ---10000\r
+      0x00,   // ---00000\r
+   },\r
+   {\r
+      0x18,   // ---11000\r
+      0x18,   // ---11000\r
+      0x18,   // ---11000\r
+      0x1D,   // ---11101\r
+      0x18,   // ---11000\r
+      0x18,   // ---11000\r
+      0x18,   // ---11000\r
+      0x00,   // ---00000\r
+   }, \r
+   {\r
+      0x1A,   // ---11010\r
+      0x1A,   // ---11010\r
+      0x1A,   // ---11010\r
+      0x1B,   // ---11011\r
+      0x1A,   // ---11010\r
+      0x1A,   // ---11010\r
+      0x1A,   // ---11010\r
+      0x00,   // ---00000\r
+   }, \r
+   {\r
+      0x1B,   // ---11011\r
+      0x1B,   // ---11011\r
+      0x1B,   // ---11011\r
+      0x1B,   // ---11011\r
+      0x1B,   // ---11011\r
+      0x1B,   // ---11011\r
+      0x1B,   // ---11011\r
+      0x00,   // ---00000\r
+   }, \r
+   {\r
+      0x0B,   // ---01011\r
+      0x0B,   // ---01011\r
+      0x0B,   // ---01011\r
+      0x1B,   // ---11011\r
+      0x0B,   // ---01011\r
+      0x0B,   // ---01011\r
+      0x0B,   // ---01011\r
+      0x00,   // ---00000\r
+   },       \r
+   {\r
+      0x03,   // ---00011\r
+      0x03,   // ---00011\r
+      0x03,   // ---00011\r
+      0x17,   // ---10111\r
+      0x03,   // ---00011\r
+      0x03,   // ---00011\r
+      0x03,   // ---00011\r
+      0x00,   // ---00000\r
+   }, \r
+   {\r
+      0x01,   // ---00001\r
+      0x01,   // ---00001\r
+      0x01,   // ---00001\r
+      0x15,   // ---10101\r
+      0x01,   // ---00001\r
+      0x01,   // ---00001\r
+      0x01,   // ---00001\r
+      0x00,   // ---00000\r
+   },             \r
+   {\r
+      0x00,   // ---00000\r
+      0x00,   // ---00000\r
+      0x00,   // ---00000\r
+      0x15,   // ---10101\r
+      0x00,   // ---00000\r
+      0x00,   // ---00000\r
+      0x00,   // ---00000\r
+      0x00,   // ---00000\r
+   }\r
+};\r
+\r
+/*************************************************************************/\r
+static void lcd_define_char(void){\r
+   U8 Cnt;\r
+   U8 ChrCnt;\r
+   register char c;\r
+   for(ChrCnt = 0; ChrCnt < (sizeof(CustomChar)/sizeof(CustomChar[0]) ); ChrCnt++){\r
+      lcd_command(0x28);   //Switch to InstructionTable (IS[2:1]=[0,0] 4Bit-Bus)\r
+      lcd_command((1<<LCD_CGRAM) + (ChrCnt<<3));   // CGRAM-Address, address = #0..7\r
+      for(Cnt=0;Cnt<8;Cnt++){\r
+         c = pgm_read_byte(&CustomChar[ChrCnt][Cnt]);\r
+         lcd_data(c);       // Write bit pattern\r
+      }\r
+   }\r
+}\r
+\r
+/*\r
+** PUBLIC FUNCTIONS \r
+*/\r
+\r
+\r
+/*************************************************************************\r
+Set cursor to specified position\r
+Input:    x  horizontal position  (0: left most position)\r
+y  vertical position    (0: first line)\r
+Returns:  none\r
+*************************************************************************/\r
+void lcd_gotoxy(uint8_t x, uint8_t y)\r
+{\r
+   if(y<LCD_LINES){\r
+      if ( y==0 )\r
+         lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x);\r
+      else if ( y==1)\r
+         lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+x);\r
+#if LCD_LINES == 3\r
+      else  /*y==2*/\r
+         lcd_command((1<<LCD_DDRAM)+LCD_START_LINE3+x);\r
+#endif\r
+   }\r
+}\r
+\r
+\r
+\r
+/*************************************************************************\r
+Clear display and set cursor to home position\r
+*************************************************************************/\r
+void lcd_clrscr(void)\r
+{\r
+   lcd_command(1<<LCD_CLR);\r
+}\r
+\r
+\r
+/*************************************************************************\r
+Set cursor to home position\r
+*************************************************************************/\r
+void lcd_home(void)\r
+{\r
+   lcd_command(1<<LCD_HOME);\r
+}\r
+\r
+\r
+/*************************************************************************\r
+Display character at current cursor position \r
+Input:    character to be displayed                                       \r
+Returns:  none\r
+*************************************************************************/\r
+void lcd_putc(char c)\r
+{\r
+   lcd_waitbusy();\r
+   lcd_write(c, 1);\r
+}\r
+\r
+\r
+/*************************************************************************\r
+Display string without auto linefeed \r
+Input:    string to be displayed\r
+Returns:  none\r
+*************************************************************************/\r
+void lcd_puts(const char *s)\r
+/* print string on lcd (no auto linefeed) */\r
+{\r
+   register char c;\r
+   \r
+   while ( (c = *s++) ) {\r
+      lcd_putc(c);\r
+   }\r
+}\r
+\r
+\r
+/*************************************************************************\r
+Display string from program memory without auto linefeed \r
+Input:     string from program memory be be displayed                                        \r
+Returns:   none\r
+*************************************************************************/\r
+void lcd_puts_p(const char *progmem_s)\r
+/* print string from program memory on lcd (no auto linefeed) */\r
+{\r
+   register char c;\r
+   \r
+   while ( (c = pgm_read_byte(progmem_s++)) ) {\r
+      lcd_putc(c);\r
+   }\r
+}\r
+\r
+\r
+/*************************************************************************\r
+Initialize display and select type of cursor \r
+Input:    dispAttr LCD_DISP_OFF            display off\r
+LCD_DISP_ON             display on, cursor off\r
+LCD_DISP_ON_CURSOR      display on, cursor on\r
+LCD_DISP_CURSOR_BLINK   display on, cursor on flashing\r
+Returns:  none\r
+*************************************************************************/\r
+void lcd_init(uint8_t dispAttr)\r
+{\r
+/*\r
+*  Initialize LCD to 4 bit I/O mode\r
+   */\r
+   /* configure all port bits as output */\r
+   PIN_INIT(LCD_RS_IO);\r
+   PIN_INIT(LCD_EN_IO);\r
+   PIN_INIT(LCD_D0_IO);\r
+   PIN_INIT(LCD_D1_IO);\r
+   PIN_INIT(LCD_D2_IO);\r
+   PIN_INIT(LCD_D3_IO);\r
+   \r
+   delay_ms((U16)20);        /* wait 40ms or more after power-on */\r
+   delay_ms((U16)20);\r
+   \r
+   lcd_command(0x30);//FunctioSet 8Bit/SPI\r
+   delay_ms(2);      // wait 2ms or more\r
+   lcd_command(0x30);//FunctioSet 8Bit/SPI\r
+   lcd_command(0x30);//FunctioSet 8Bit/SPI \r
+   lcd_command(0x20);//FunctioSet 4Bit\r
+   lcd_command(0x29);//FunctioSet 4Bit\r
+   lcd_command(LCD_BIAS);//BIAS  BS:1/4, \r
+   lcd_command(LCD_PWR);//Booster on/set Contrast(bit 5:4)\r
+   lcd_command(LCD_FOLLOW);//Spannungsfolger u. Verstärkung setzen\r
+   lcd_command(LCD_CNTRST);\r
+   lcd_command(LCD_DISP_ON);//Disp on\r
+   //lcd_command(0x01);//Clear, Cursor home\r
+   //delay_ms(2);      // wait 2ms or more\r
+   lcd_command(0x06);//Cursor Auto-Increment\r
+   \r
+   lcd_define_char();\r
+   \r
+   lcd_command(LCD_DISP_OFF);              /* display off                  */\r
+   lcd_clrscr();                           /* display clear                */ \r
+   lcd_command(LCD_MODE_DEFAULT);          /* set entry mode               */\r
+   lcd_command(dispAttr);                  /* display/cursor control       */\r
+}\r
+\r
+/*************************************************************************\r
+Shows a bargraph -100..+100% \r
+Input:     Value, starting position x,y, # of chars @100%, display a marker @0%\r
+Returns:   none\r
+*************************************************************************/\r
+void lcdBar(S8 Percent, U8 X, U8 Y, U8 MaxChr, BOOL MarkerAtZero){\r
+   U16  PixN;\r
+   U8   Blocks;\r
+   U8   BlockReminder;\r
+   U8   Space;\r
+   CHAR Chr;\r
+   BOOL IsNegativ = FALSE;\r
+   \r
+   if(Percent < -100)\r
+      Percent = -100;\r
+   if(Percent > 100)\r
+      Percent = 100;\r
+   \r
+   lcd_gotoxy(X,Y);\r
+   \r
+   if(Percent < 0){\r
+      IsNegativ = TRUE;\r
+      Percent = 100 - -1*Percent;\r
+   }\r
+   \r
+   PixN = (MaxChr*6 * (+1 * Percent) +50) / 100;\r
+   Blocks = PixN/6;\r
+   BlockReminder = PixN - Blocks * 6;\r
+   Space = MaxChr - Blocks;\r
+   \r
+   if(MarkerAtZero){\r
+      if( (Blocks == 0 && BlockReminder == 0) || (IsNegativ && MaxChr > Space) ){\r
+         lcd_putc(0);\r
+         MaxChr--;\r
+      }\r
+   }\r
+   \r
+   while(MaxChr){\r
+      if(IsNegativ == FALSE){\r
+         if(Blocks){\r
+            Chr=3;\r
+            Blocks--;\r
+         }\r
+         else if(BlockReminder){\r
+            if(BlockReminder == 1)\r
+               Chr=0;\r
+            else if(BlockReminder == 2 || BlockReminder == 3)\r
+               Chr=1;\r
+            else\r
+               Chr=2;\r
+            BlockReminder = 0;\r
+         }\r
+         else\r
+            Chr=7;\r
+      }\r
+      else{\r
+         if(MaxChr > Space)\r
+            Chr=7;\r
+         else if(BlockReminder){\r
+            if(BlockReminder == 1)\r
+               Chr=4;\r
+            else if(BlockReminder == 2 || BlockReminder == 3)\r
+               Chr=5;\r
+            else\r
+               Chr=6;\r
+            BlockReminder = 0;\r
+            \r
+         }\r
+         else\r
+            Chr=3;\r
+      }\r
+      lcd_putc(Chr);\r
+      MaxChr--;\r
+   }\r
+}
\ No newline at end of file
diff --git a/modulo-d-amp/lcd.h b/modulo-d-amp/lcd.h
new file mode 100644 (file)
index 0000000..703e538
--- /dev/null
@@ -0,0 +1,197 @@
+/*************************************************************************\r
+Copyright: (c) 2009 Stange-Distribution Simone Stange, Berlin\r
+Contact:   info@obd-shop.com\r
+License:   GNU GPL v2 (see License.txt)\r
+Author:    Frank Nitzsche classd@beta-x.de\r
+File:      lcd.h\r
+Version:   16.02.09\r
+Compiler:  AVR-GCC\r
+\r
+Prototypes are the same like the ones from Peter Fleury and Florian Scherb.\r
+I used their librarys extensive as draft. Therefore it should be easy to exchange\r
+this modul by their HD44780 or KS0073 compatible version.\r
+\r
+R/W line not supported. Tie to ground.\r
+\r
+Added:   Function lcdBar(..) - a bargraph visualization\r
+**************************************************************************/\r
+\r
+#ifndef LCD_H\r
+#define LCD_H\r
+\r
+#include "common.h"\r
+#include <inttypes.h>\r
+#include <avr/pgmspace.h>\r
+\r
+\r
+//////////////////////////////////////////////////////////////////////////\r
+//       User Config <Start>                                            //\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+/**\r
+ *  @name  Definitions for lcd voltage\r
+ */\r
+#define LCD_VOLTAGE        3        /** Select 5 for 5V or 3 for 3.3V */\r
+\r
+/** \r
+ *  @name  Definitions for Display Size \r
+ *  Change these definitions to adapt setting to your display\r
+ */\r
+#define LCD_LINES          3        /**< number of visible lines of the display */\r
+\r
+/** \r
+ *  @name  Definitions for connection \r
+ *  Change these definitions to adapt setting to your circuit\r
+ */\r
+\r
+#define LCD_D0_IO LOGIC_POSITIV,C,3 /**< port,bit for 4bit data bit 0 */\r
+#define LCD_D1_IO LOGIC_POSITIV,C,2 /**< port,bit for 4bit data bit 0 */\r
+#define LCD_D2_IO LOGIC_POSITIV,C,1 /**< port,bit for 4bit data bit 0 */\r
+#define LCD_D3_IO LOGIC_POSITIV,C,0 /**< port,bit for 4bit data bit 0 */\r
+#define LCD_RS_IO LOGIC_POSITIV,D,5 /**< port,bit for RS line         */\r
+#define LCD_EN_IO LOGIC_POSITIV,D,6 /**< port,bit for Enable line     */\r
+\r
+//////////////////////////////////////////////////////////////////////////\r
+//       User Config <End>                                              //\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+#define LCD_START_LINE1    0x00     /**< DDRAM address of first char of line 1  */\r
+#if LCD_LINES == 2\r
+   #define LCD_START_LINE2 0x40     /**< DDRAM address of first char of line 2  */\r
+#endif\r
+#if LCD_LINES == 3\r
+   #define LCD_START_LINE2 0x10     /**< DDRAM address of first char of line 2  */\r
+   #define LCD_START_LINE3 0x20     /**< DDRAM address of first char of line 3  */\r
+#endif\r
+\r
+/**\r
+ *  @name Definitions for LCD command instructions\r
+ *  The constants define the various LCD controller instructions which can be passed to the \r
+ *  function lcd_command(), see ST7036 data sheet for a complete description.\r
+ */\r
+\r
+/* instruction register bit positions, see HD44780U data sheet */\r
+#define LCD_CLR               0      /* DB0: clear display                  */\r
+#define LCD_HOME              1      /* DB1: return to home position        */\r
+#define LCD_ENTRY_MODE        2      /* DB2: set entry mode                 */\r
+#define LCD_ENTRY_INC         1      /*   DB1: 1=increment, 0=decrement     */\r
+#define LCD_ENTRY_SHIFT       0      /*   DB2: 1=display shift on           */\r
+#define LCD_ON                3      /* DB3: turn lcd/cursor on             */\r
+#define LCD_ON_DISPLAY        2      /*   DB2: turn display on              */\r
+#define LCD_ON_CURSOR         1      /*   DB1: turn cursor on               */\r
+#define LCD_ON_BLINK          0      /*     DB0: blinking cursor ?          */\r
+#define LCD_MOVE              4      /* DB4: move cursor/display            */\r
+#define LCD_MOVE_DISP         3      /*   DB3: move display (0-> cursor) ?  */\r
+#define LCD_MOVE_RIGHT        2      /*   DB2: move right (0-> left) ?      */\r
+#define LCD_FUNCTION          5      /* DB5: function set                   */\r
+#define LCD_FUNCTION_8BIT     4      /*   DB4: set 8BIT mode (0->4BIT mode) */\r
+#define LCD_FUNCTION_2LINES   3      /*   DB3: two lines (0->one line)      */\r
+#define LCD_FUNCTION_10DOTS   2      /*   DB2: 5x10 font (0->5x7 font)      */\r
+#define LCD_CGRAM             6      /* DB6: set CG RAM address             */\r
+#define LCD_DDRAM             7      /* DB7: set DD RAM address             */\r
+\r
+/* display on/off, cursor on/off, blinking char at cursor position */\r
+#define LCD_DISP_OFF             0x08   /* display off                            */\r
+#define LCD_DISP_ON              0x0C   /* display on, cursor off                 */\r
+#define LCD_DISP_ON_BLINK        0x0D   /* display on, cursor off, blink char     */\r
+#define LCD_DISP_ON_CURSOR       0x0E   /* display on, cursor on                  */\r
+#define LCD_DISP_ON_CURSOR_BLINK 0x0F   /* display on, cursor on, blink char      */\r
+\r
+\r
+#define LCD_MODE_DEFAULT     ((1<<LCD_ENTRY_MODE) | (1<<LCD_ENTRY_INC) )\r
+\r
+#if LCD_VOLTAGE == 5\r
+   #define LCD_BIAS     0x1d\r
+   #define LCD_PWR      0x50\r
+   #define LCD_FOLLOW   0x6c\r
+   #define LCD_CNTRST   0x77\r
+#else\r
+   #define LCD_BIAS     0x14\r
+   #define LCD_PWR      0x55\r
+   #define LCD_FOLLOW   0x6d\r
+   #define LCD_CNTRST   0x78\r
+#endif\r
+\r
+\r
+/** \r
+ *  @name Functions\r
+ */\r
+\r
+\r
+/**\r
+ @brief    Initialize display and select type of cursor\r
+ @param    dispAttr \b LCD_DISP_OFF display off\n\r
+                    \b LCD_DISP_ON display on, cursor off\n\r
+                    \b LCD_DISP_ON_CURSOR display on, cursor on\n\r
+                    \b LCD_DISP_ON_CURSOR_BLINK display on, cursor on flashing             \r
+ @return  none\r
+*/\r
+extern void lcd_init(uint8_t dispAttr);\r
+\r
+\r
+/**\r
+ @brief    Clear display and set cursor to home position\r
+ @param    void                                        \r
+ @return   none\r
+*/\r
+extern void lcd_clrscr(void);\r
+\r
+\r
+/**\r
+ @brief    Set cursor to home position\r
+ @param    void                                        \r
+ @return   none\r
+*/\r
+extern void lcd_home(void);\r
+\r
+\r
+/**\r
+ @brief    Set cursor to specified position\r
\r
+ @param    x horizontal position\n (0: left most position)\r
+ @param    y vertical position\n   (0: first line)\r
+ @return   none\r
+*/\r
+extern void lcd_gotoxy(uint8_t x, uint8_t y);\r
+\r
+\r
+/**\r
+ @brief    Display character at current cursor position\r
+ @param    c character to be displayed                                       \r
+ @return   none\r
+*/\r
+extern void lcd_putc(char c);\r
+\r
+\r
+/**\r
+ @brief    Display string without auto linefeed\r
+ @param    s string to be displayed                                        \r
+ @return   none\r
+*/\r
+extern void lcd_puts(const char *s);\r
+\r
+\r
+/**\r
+ @brief    Display string from program memory without auto linefeed\r
+ @param    s string from program memory be be displayed                                        \r
+ @return   none\r
+ @see      lcd_puts_P\r
+*/\r
+extern void lcd_puts_p(const char *progmem_s);\r
+\r
+/**\r
+ @brief    Shows a bargraph -100..+100% \r
\r
+ @param    Bargraph value, starting position x,y, Number of chars at 100%, display a marker at 0%\r
+ @return   none\r
+*/\r
+void lcdBar(S8 Percent, U8 X, U8 Y, U8 MaxChr, BOOL MarkerAtZero);\r
+\r
+/**\r
+ @brief macros for automatically storing string constant in program memory\r
+*/\r
+#define lcd_puts_P(__s)         lcd_puts_p(PSTR(__s))\r
+\r
+#endif //LCD_H\r
+\r
diff --git a/modulo-d-amp/main.c b/modulo-d-amp/main.c
new file mode 100644 (file)
index 0000000..504137c
--- /dev/null
@@ -0,0 +1,243 @@
+/*************************************************************************\r
+Copyright: (c) 2009 Stange-Distribution Simone Stange, Berlin\r
+Contact:   info@obd-shop.com\r
+License:   GNU GPL v2 (see License.txt)\r
+Author:    Frank Nitzsche classd@beta-x.de\r
+File:      main.c\r
+Version:   16.02.09\r
+Compiler:  AVR-GCC\r
+**************************************************************************/\r
+\r
+#include <avr/interrupt.h>\r
+#include "common.h"\r
+#include "main.h"\r
+#include "iic.h"\r
+#include "max9744.h"\r
+#include "tda7449.h"\r
+#include "lcd.h"\r
+#include "rc5.h"\r
+\r
+#define NIX  0\r
+#define VOL  1\r
+#define BASS 2\r
+#define TREB 3\r
+#define GAIN 4\r
+\r
+#define TEXT_URL "www.elektor.com"\r
+#define TEXT_TITLE "ClassD Amplifier"\r
+#define TEXT_VOLUME "Volume"\r
+#define TEXT_GAIN "Gain  "\r
+#define TEXT_BASS "Bass  "\r
+#define TEXT_TREBLE "Treble"\r
+\r
+static BOOL Flag10ms;      //10ms Tick\r
+//static U8   Showtime;      //Remaining visualisation time*10ms\r
+// changed to int to go above 2.55s ;-)\r
+static unsigned int Showtime;      //Remaining visualisation time*10ms\r
+static U8   RepeatDelay;   //Delay*10ms before accepting new RC5 command\r
+\r
+SIGNAL (SIG_OVERFLOW0){\r
+   TCNT0 = -78;            //78 Timerticks = 10ms\r
+   Flag10ms = TRUE;\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+//10ms Tick\r
+static void Timer0Init(void){\r
+   TCCR0 = 1<<CS02 ^ 1<<CS00; //F_CPU/1024\r
+   TIMSK |= 1<<TOIE0;         //Enable Interrupt\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+//Check received RC-word\r
+BOOL isKey(RC5_t *Rc5, U8 Adr, U8 Cmd){\r
+   return (Rc5->Adr == Adr && Rc5->Cmd == Cmd);\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+//Visualise sound setting\r
+static void showSoundValue(U8 Wich){\r
+   if(Wich == NIX)\r
+      return;\r
+   Showtime = 150;\r
+   S8 Val;\r
+\r
+#if LCD_LINES == 3\r
+   lcd_gotoxy(0,2);\r
+   lcd_puts_P(TEXT_URL);\r
+#endif\r
+\r
+   lcd_gotoxy(0,1);\r
+\r
+   if(Wich == VOL){\r
+      Val = max9744getVolPercent();\r
+      lcd_puts_P(TEXT_VOLUME);\r
+      lcdBar(Val,0,0,16,TRUE);\r
+   }\r
+   else if(Wich == GAIN){\r
+      RepeatDelay = 15;\r
+      Val = TDA7449getGain();\r
+      Val = Val*3 + 1+DIV3(Val);     //same like Val*3.3 - but avoids float\r
+      lcd_puts_P(TEXT_GAIN);\r
+      lcdBar(Val,0,0,16,TRUE);\r
+   }\r
+   else{\r
+      RepeatDelay = 25;\r
+      if(Wich == BASS){\r
+         Val = TDA7449getBass() * 7;   //14dB * 7 ~ 100%\r
+         lcd_puts_P(TEXT_BASS);\r
+      }\r
+      if(Wich == TREB){\r
+         Val = TDA7449getTreble() * 7;\r
+         lcd_puts_P(TEXT_TREBLE);\r
+      }\r
+      if(Val < 0){\r
+         lcdBar(Val,0,0,8,FALSE);\r
+         lcdBar(  0,8,0,8,TRUE);\r
+      }\r
+      else{\r
+         lcdBar(  0,0,0,8,FALSE);\r
+         lcdBar(Val,8,0,8,TRUE);\r
+      }\r
+   }\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+void\r
+display_standby_text (void)\r
+{\r
+#if LCD_LINES == 3\r
+   U8 n[4] = {'\0', '\0', '\0', '\0'};\r
+   S8 Val;\r
+   U8 i, q, r;\r
+#endif\r
+   lcd_puts_P(TEXT_TITLE);\r
+#if LCD_LINES == 3\r
+   lcd_gotoxy(0,2);\r
+   lcd_puts_P(TEXT_VOLUME": ");\r
+   // q&d way to display the volume\r
+   Val = max9744getVolPercent();\r
+   q = Val;\r
+   i = 0;\r
+   while (q >= 10) {\r
+     q = q / 10;\r
+     i++;\r
+   }\r
+   q = Val;\r
+   while (q >= 10) {\r
+     r = q % 10;\r
+     q = q / 10;\r
+     n[i] = '0' + r;\r
+     i--;\r
+   }\r
+   n[i] = '0' + q;\r
+   lcd_puts((char *)n);\r
+   lcd_puts("%   ");\r
+#endif\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+int\r
+main (void)\r
+{\r
+   RC5_t Rc5;\r
+   U8 ShowWichValue = NIX;\r
+   init_iic(100);\r
+   TDA7449init();\r
+   max9744init(MAX9744_FILTERLESS);\r
+   Timer0Init();\r
+\r
+   //Backlight\r
+   DDRB |= 1<<2;\r
+   PORTB|= 1<<2;\r
+   \r
+   max9744setVol(22);\r
+\r
+   lcd_init(LCD_DISP_ON);\r
+   initRc5();\r
+\r
+   sei();\r
+\r
+   // splash screen with URL, only displayed the first time and for 5s\r
+   Showtime = 500;\r
+   lcd_puts_P(TEXT_TITLE);\r
+#if LCD_LINES == 3\r
+   lcd_gotoxy(0,2);\r
+   lcd_puts_P(TEXT_URL);\r
+#endif\r
+   goto AGAIN2;\r
+\r
+AGAIN:\r
+\r
+   // standby display with volume value\r
+   display_standby_text();\r
+\r
+AGAIN2:\r
+\r
+   for(;;){\r
+\r
+      if(getRc5(&Rc5)){\r
+\r
+\r
+//////////////////////////////////////////////////////////////////////////\r
+         //Uncomment for displaying RC5 data\r
+/*\r
+         CHAR Txt[17];\r
+         lcd_gotoxy(0,0);\r
+         lcd_puts("Adr:            ");\r
+         lcd_gotoxy(4,0);\r
+         itoa(Rc5.Adr,Txt,10);\r
+         lcd_puts(Txt);\r
+\r
+         lcd_puts(" Cmd:");\r
+         itoa(Rc5.Cmd,Txt,10);\r
+         lcd_puts(Txt);\r
+*/\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+         if(isKey(&Rc5, VOL_P)){\r
+            max9744setVol(max9744getVol()+1);\r
+            ShowWichValue = VOL;\r
+         }\r
+         else if(isKey(&Rc5, VOL_M)){\r
+            max9744setVol(max9744getVol()-1);\r
+            ShowWichValue = VOL;\r
+         }\r
+         else if(isKey(&Rc5, BASS_P) && RepeatDelay == 0){\r
+            TDA7449setBass(TDA7449getBass()+2);\r
+            ShowWichValue = BASS;\r
+         }\r
+         else if(isKey(&Rc5, BASS_M) && RepeatDelay == 0){\r
+            TDA7449setBass(TDA7449getBass()-2);\r
+            ShowWichValue = BASS;\r
+         }\r
+         else if(isKey(&Rc5, TREB_P) && RepeatDelay == 0){\r
+            TDA7449setTreble(TDA7449getTreble()+2);\r
+            ShowWichValue = TREB;\r
+         }\r
+         else if(isKey(&Rc5, TREB_M) && RepeatDelay == 0){\r
+            TDA7449setTreble(TDA7449getTreble()-2);\r
+            ShowWichValue = TREB;\r
+         }\r
+         else if(isKey(&Rc5, GAIN_P) && RepeatDelay == 0){\r
+            TDA7449setGain(TDA7449getGain()+2);\r
+            ShowWichValue = GAIN;\r
+         }\r
+         else if(isKey(&Rc5, GAIN_M) && RepeatDelay == 0){\r
+            TDA7449setGain(TDA7449getGain()-2);\r
+            ShowWichValue = GAIN;\r
+         }\r
+         showSoundValue(ShowWichValue);\r
+         ShowWichValue = NIX;\r
+      }\r
+      \r
+      if(Flag10ms){\r
+         Flag10ms = FALSE;\r
+         if(Showtime){\r
+            Showtime--;\r
+            if(Showtime == 0){\r
+               lcd_clrscr();\r
+               goto AGAIN;\r
+            }\r
+         }\r
+         if(RepeatDelay)\r
+            RepeatDelay--;\r
+      }\r
+   }\r
+}
\ No newline at end of file
diff --git a/modulo-d-amp/main.h b/modulo-d-amp/main.h
new file mode 100644 (file)
index 0000000..3ef16b7
--- /dev/null
@@ -0,0 +1,32 @@
+/*************************************************************************\r
+Copyright: (c) 2009 Stange-Distribution Simone Stange, Berlin\r
+Contact:   info@obd-shop.com\r
+License:   GNU GPL v2 (see License.txt)\r
+Author:    Frank Nitzsche classd@beta-x.de\r
+File:      main.h\r
+Version:   16.02.09\r
+Compiler:  AVR-GCC\r
+**************************************************************************/\r
+\r
+\r
+//////////////////////////////////////////////////////////////////////////\r
+//       User Config <Start>                                            //\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+//Set RC5-Address and RC5-Command associated with Volume, Bass, Treble and Gain\r
+#define VOL_P  20,16\r
+#define VOL_M  20,17\r
+//#define BASS_P 20,26\r
+#define BASS_P 20,1\r
+//#define BASS_M 20,27\r
+#define BASS_M 20,4\r
+//#define TREB_P 20,59\r
+#define TREB_P 20,3\r
+//#define TREB_M 20,28\r
+#define TREB_M 20,6\r
+#define GAIN_P 20,52\r
+#define GAIN_M 20,50\r
+\r
+//////////////////////////////////////////////////////////////////////////\r
+//       User Config <End>                                              //\r
+//////////////////////////////////////////////////////////////////////////\r
diff --git a/modulo-d-amp/max9744.c b/modulo-d-amp/max9744.c
new file mode 100644 (file)
index 0000000..0a79d84
--- /dev/null
@@ -0,0 +1,61 @@
+/*************************************************************************\r
+Copyright: (c) 2009 Stange-Distribution Simone Stange, Berlin\r
+Contact:   info@obd-shop.com\r
+License:   GNU GPL v2 (see License.txt)\r
+Author:    Frank Nitzsche classd@beta-x.de\r
+File:      max9744.c\r
+Version:   16.02.09\r
+Compiler:  AVR-GCC\r
+**************************************************************************/\r
+\r
+#include <util/delay.h>\r
+#include "max9744.h"\r
+#include "iic.h"\r
+\r
+//Mirrors a MAX9744 register.\r
+static U8 Volume;\r
+\r
+//////////////////////////////////////////////////////////////////////////\r
+static void writeByteMax(uint8_t Val){\r
+   start_iic(MAX9744_WR_ADR);\r
+   write_iic(Val);\r
+   stop_iic();\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+void max9744init(U8 Mode){\r
+   PIN_INIT(MAX9744_SHDN_IO);\r
+   PIN_ACTIV(MAX9744_SHDN_IO);\r
+   _delay_ms(5);\r
+   PIN_PASSIV(MAX9744_SHDN_IO);\r
+   _delay_ms(5);\r
+\r
+   Mode &= 0x01;  //Mode must not exceed 1\r
+   writeByteMax(MAX9744_MODULATION | Mode);\r
+\r
+   Volume = 0;\r
+   writeByteMax(MAX9744_VOLUME_ABS | Volume);\r
+   \r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+void max9744shutDown(void){\r
+   PIN_ACTIV(MAX9744_SHDN_IO);\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+void max9744setVol(U8 Vol){\r
+   Volume = Vol;\r
+   if(Volume > 128)     //for catching decrement if Volume==0  like this: max9744setVol(max9744getVol()-1)\r
+      Volume = 0;\r
+   else if(Volume > 63) //for catching increment if Volume==63 like this: max9744setVol(max9744getVol()+1)\r
+      Volume = 63;\r
+   writeByteMax(MAX9744_VOLUME_ABS | Volume);\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+U8   max9744getVol(void){\r
+   return Volume;\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+U16  max9744getVolPercent(void){\r
+   U16 Tmp = Volume;\r
+   return ( (Tmp * 100 + 63/2) / 63);\r
+}\r
+\r
diff --git a/modulo-d-amp/max9744.h b/modulo-d-amp/max9744.h
new file mode 100644 (file)
index 0000000..d6ebfc2
--- /dev/null
@@ -0,0 +1,93 @@
+/*************************************************************************\r
+Copyright: (c) 2009 Stange-Distribution Simone Stange, Berlin\r
+Contact:   info@obd-shop.com\r
+License:   GNU GPL v2 (see License.txt)\r
+Author:    Frank Nitzsche classd@beta-x.de\r
+File:      max9744.h\r
+Version:   16.02.09\r
+Compiler:  AVR-GCC\r
+**************************************************************************/\r
+#ifndef MAX9744_H\r
+#define MAX9744_H\r
+\r
+//////////////////////////////////////////////////////////////////////////\r
+//       User Config <Start>                                            //\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+// Set to 1 if Pin ADDR1 is tied to Vcc\r
+#define MAX9744_A1_VCC 1\r
+\r
+// Set to 1 if Pin ADDR2 is tied to Vcc\r
+#define MAX9744_A2_VCC 1\r
+\r
+// Define Port/Pin connected with /SHDN\r
+#define MAX9744_SHDN_PORT D\r
+#define MAX9744_SHDN_PIN  3\r
+\r
+//////////////////////////////////////////////////////////////////////////\r
+//       User Config <End>                                              //\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+#include "common.h"\r
+\r
+/* \r
+Communication:\r
+  1. Master sends START condition\r
+  2. Master sends 7bits slave ID plus write bit (low)\r
+  3. Slave asserts ACK\r
+  4. Master sends 8 data bits\r
+  5. Slave asserts ACK (or NACK)\r
+  6. Master generates STOP condition\r
+\r
+Data byte:\r
+  A1, A0, V5, V4, V3, V2, V1, V0\r
+\r
+  A1,A0 V5..V0\r
+  ------------\r
+  00    xxxxxx    Volume\r
+  01    000000    Filterless modulation\r
+  01    000001    Classic PWM\r
+  10    ------    Reserved\r
+  11    000100    Volume +\r
+  11    000101    Volume -\r
+\r
+*/\r
+\r
+//Slave Address\r
+#if (MAX9744_A1_VCC && MAX9744_A2_VCC)\r
+   #define MAX9744_WR_ADR 0x96      // Slave address write MAX9744\r
+#elif(MAX9744_A1_VCC && !MAX9744_A2_VCC)\r
+   #define MAX9744_WR_ADR 0x94      // Slave address write MAX9744\r
+#elif(!MAX9744_A1_VCC && MAX9744_A2_VCC)\r
+   #define MAX9744_WR_ADR 0x92      // Slave address write MAX9744\r
+#else\r
+   #error "MAX9744 IIC disabled"\r
+#endif\r
+\r
+//A1,A0\r
+#define MAX9744_VOLUME_ABS 0x00\r
+#define MAX9744_VOLUME_REL 0xC0\r
+#define MAX9744_MODULATION 0x40\r
+\r
+//V5..V0\r
+#define MAX9744_FILTERLESS 0x00\r
+#define MAX9744_PWM        0x01\r
+#define MAX9744_VOL_INC    0x04\r
+#define MAX9744_VOL_DEC    0x05\r
+\r
+//Shutdown-Pin\r
+#define MAX9744_SHDN_IO LOGIC_NEGATIV, MAX9744_SHDN_PORT, MAX9744_SHDN_PIN\r
+\r
+\r
+//////////////////////////////////////////////////////////////////////////\r
+void max9744init(U8 Mode);    //Mode: {MAX9744_FILTERLESS, MAX9744_PWM}\r
+//////////////////////////////////////////////////////////////////////////\r
+void max9744shutDown(void);\r
+//////////////////////////////////////////////////////////////////////////\r
+void max9744setVol(U8 Vol);   //Vol: {0..63}\r
+//////////////////////////////////////////////////////////////////////////\r
+U8   max9744getVol(void);     //U8:  {0..63}\r
+//////////////////////////////////////////////////////////////////////////\r
+U16  max9744getVolPercent(void); //U16: {0..100} -> 0..100%\r
+\r
+#endif /*MAX9744_H*/\r
diff --git a/modulo-d-amp/rc5.c b/modulo-d-amp/rc5.c
new file mode 100644 (file)
index 0000000..2635c7b
--- /dev/null
@@ -0,0 +1,81 @@
+/*************************************************************************\r
+File:    rc5.c\r
+**************************************************************************/\r
+\r
+/************************************************************************/\r
+/*                                                                      */\r
+/*                      RC5 Remote Receiver                             */\r
+/*                                                                      */\r
+/*              Author: Peter Dannegger                                 */\r
+/*                      danni@specs.de                                  */\r
+/*                                                                      */\r
+/************************************************************************/\r
+\r
+/*************************************************************************\r
+Slightly modified: Frank Nitzsche classd@beta-x.de\r
+**************************************************************************/\r
+#include <avr/interrupt.h>\r
+#include "rc5.h"\r
+/** RC5 bittime constant */\r
+#define RC5TIME        1.778e-3 //msec\r
+\r
+#define PULSE_MIN      (U8)(F_CPU / 1024 * RC5TIME * 0.4 + 0.5) //@8Mhz\r
+#define PULSE_1_2      (U8)(F_CPU / 1024 * RC5TIME * 0.8 + 0.5)\r
+#define PULSE_MAX      (U8)(F_CPU / 1024 * RC5TIME * 1.2 + 0.5)\r
+\r
+#define        xRC5_IN  PINB\r
+#define        xRC5            PB0      // IR input low active\r
+\r
+U8  rc5_bit;               // bit value\r
+U8  rc5_time;              // count bit time\r
+U16 rc5_tmp;               // shift bits in\r
+U16 rc5_data;              // store result\r
+\r
+void initRc5(void){\r
+  TCCR2  = 1<<CS22^1<<CS21;//divide by 256\r
+  TIMSK |= 1<<TOIE2;                   //enable timer interrupt   \r
+  PORTB |= 1<<PB0;         //PU\r
+}\r
+\r
+/*************************************************************************\r
+Timer ISR - RC5 scannen\r
+**************************************************************************/\r
+SIGNAL (SIG_OVERFLOW2){\r
+  U16 tmp = rc5_tmp;                      // for faster access\r
+\r
+  TCNT2 = -4;                             // 4*256=1024 Zyklen\r
+  if( ++rc5_time > PULSE_MAX ){                           // count pulse time\r
+    if( !(tmp & 0x4000) && tmp & 0x2000 )      // only if 14 bits received\r
+      rc5_data = tmp;\r
+    tmp = 0;\r
+  }\r
+\r
+  if( (rc5_bit ^ xRC5_IN) & 1<<xRC5 ){         // change detect\r
+    rc5_bit = ~rc5_bit;                                         // 0x00 -> 0xFF -> 0x00\r
+\r
+    if( rc5_time < PULSE_MIN ){                           // to short\r
+      tmp = 0;\r
+    }\r
+\r
+    if( !tmp || rc5_time > PULSE_1_2 ){   // start or long pulse time\r
+      if( !(tmp & 0x4000) )                          // not to many bits\r
+        tmp <<= 1;                                         // shift\r
+      if( !(rc5_bit & 1<<xRC5) )                     // inverted bit\r
+        tmp |= 1;                                             // insert new bit\r
+      rc5_time = 0;                                        // count next pulse time\r
+    }\r
+  }\r
+\r
+  rc5_tmp = tmp;\r
+}\r
+\r
+BOOL getRc5(RC5_t *Rc5){\r
+   cli();\r
+   U16 i = rc5_data;\r
+   rc5_data = 0;\r
+   sei();\r
+   Rc5->Tgl = i >> 11 & 1;\r
+   Rc5->Adr = i >> 6 & 0x1F;\r
+   Rc5->Cmd = (i & 0x3F) | ((~i >> 6) & 0x40);\r
+   return(i!=0);\r
+}\r
diff --git a/modulo-d-amp/rc5.h b/modulo-d-amp/rc5.h
new file mode 100644 (file)
index 0000000..f7f4134
--- /dev/null
@@ -0,0 +1,41 @@
+/*************************************************************************\r
+Copyright: (c) 2009 Stange-Distribution Simone Stange, Berlin\r
+Contact:   info@obd-shop.com\r
+License:   GNU GPL v2 (see License.txt)\r
+Author:    Frank Nitzsche classd@beta-x.de\r
+File:      rc5.h\r
+Version:   16.02.09\r
+Compiler:  AVR-GCC\r
+**************************************************************************/\r
+\r
+#ifndef RC5_H\r
+#define RC5_H\r
+\r
+#include "common.h"\r
+\r
+/* RC5:\r
+\r
+14 Bit word:\r
+\r
+| 1 | -C6 | T | A4 | A3 | A2 | A1 | A0 | C5 | C4 | C3 | C2 | C1 | C0 |\r
+  |    |    |    \------------------/     \-----------------------/\r
+  |    |    |           Address                    Command\r
+  |    |   Toggle\r
+  |   inverted Commandbit\r
+ Startbit\r
+\r
+Bit  duration = 1.778ms\r
+Word duration = 24.889ms\r
+Word repetition (pressed key) = 113.778ms\r
+\r
+*/\r
+typedef struct{\r
+   U8 Adr;\r
+   U8 Cmd;\r
+   U8 Tgl;\r
+}RC5_t;\r
+\r
+BOOL getRc5(RC5_t*);\r
+void initRc5(void);\r
+\r
+#endif//RC5_H\r
diff --git a/modulo-d-amp/tda7449.c b/modulo-d-amp/tda7449.c
new file mode 100644 (file)
index 0000000..9d8545d
--- /dev/null
@@ -0,0 +1,113 @@
+/*************************************************************************\r
+Copyright: (c) 2009 Stange-Distribution Simone Stange, Berlin\r
+Contact:   info@obd-shop.com\r
+License:   GNU GPL v2 (see License.txt)\r
+Author:    Frank Nitzsche classd@beta-x.dee\r
+File:      tda7449.c\r
+Version:   16.02.09\r
+Compiler:  AVR-GCC\r
+**************************************************************************/\r
+\r
+#include "tda7449.h"\r
+\r
+//Mirrors the TDA7449 register in native format.\r
+static U8 Volume;\r
+static U8 Attenuation[2];\r
+static U8 Bass;\r
+static U8 Treble;\r
+static U8 Gain;\r
+\r
+#define ATT_LEFT  0\r
+#define ATT_RIGHT 1\r
+\r
+#include "iic.h"\r
+\r
+//////////////////////////////////////////////////////////////////////////\r
+static void writeByteTda(U8 Sub, U8 Val){\r
+   start_iic(TDA7449_WR_ADR);\r
+   write_iic(Sub);\r
+   write_iic(Val);\r
+   stop_iic();\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+static S8 convertSoundNative2dB(U8 Native){\r
+   S8 Temp = 7 - (Native & 0x07);\r
+   Temp *= 2;\r
+   //if native value means >=0\r
+   if(Native & 0x08)\r
+      return  Temp;\r
+   //if native value means < 0\r
+   else\r
+      return -Temp;\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+static U8 convertSounddB2Native(S8 DB){\r
+   U8 Temp = 0x08;\r
+   DB /= 2; \r
+   \r
+   if(DB < 0){\r
+      Temp = 0;\r
+      DB *= -1;\r
+   }\r
+   \r
+   if(DB > 7)\r
+      DB = 7;\r
+\r
+   Temp += (7-DB);\r
+\r
+   return Temp;\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+void TDA7449init(void){\r
+   Volume = 0;                      // = -0dB, adjust if desired\r
+   writeByteTda(TDA7449_VOLUME, Volume);\r
+\r
+   Attenuation[ATT_LEFT]  = 6;      // = -6dB, adjust if desired\r
+   writeByteTda(TDA7449_ATT_LEFT,  Attenuation[ATT_LEFT] );\r
+   Attenuation[ATT_RIGHT] = 6;      // = -6dB, adjust if desired\r
+   writeByteTda(TDA7449_ATT_RIGHT, Attenuation[ATT_RIGHT]);\r
+\r
+   TDA7449setBass(0);               // =  0dB, adjust if desired\r
+   TDA7449setTreble(0);             // =  0dB, adjust if desired\r
+\r
+   Gain = 0;                        // = +0dB, adjust if desired\r
+   writeByteTda(TDA7449_INP_GAIN, Gain);\r
+\r
+   TDA7449setInput(TDA7449_INP2);\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+void TDA7449setInput(U8 Inp){\r
+   writeByteTda(TDA7449_INP_SEL, Inp);\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+void TDA7449setBass(S8 B){\r
+   Bass = convertSounddB2Native(B);\r
+   writeByteTda(TDA7449_BASS, Bass);\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+void TDA7449setTreble(S8 T){\r
+   Treble = convertSounddB2Native(T);\r
+   writeByteTda(TDA7449_TREBLE, Treble);\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+void TDA7449setGain(U8 G){\r
+   if(G > 128)     //for catching decrement if Volume==0  like this: max9744setVol(max9744getVol()-1)\r
+      G = 0;\r
+   else if(G > 30) //for catching increment if Volume==63 like this: max9744setVol(max9744getVol()+1)\r
+      G = 30;\r
+   Gain = G/2;\r
+   writeByteTda(TDA7449_INP_GAIN, Gain);\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+S8   TDA7449getBass(void){\r
+   return convertSoundNative2dB(Bass);\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+S8   TDA7449getTreble(void){\r
+   return convertSoundNative2dB(Treble);\r
+}\r
+//////////////////////////////////////////////////////////////////////////\r
+U8   TDA7449getGain(void){\r
+   return Gain*2;\r
+}\r
+\r
diff --git a/modulo-d-amp/tda7449.h b/modulo-d-amp/tda7449.h
new file mode 100644 (file)
index 0000000..dc4333d
--- /dev/null
@@ -0,0 +1,65 @@
+/*************************************************************************\r
+Copyright: (c) 2009 Stange-Distribution Simone Stange, Berlin\r
+Contact:   info@obd-shop.com\r
+License:   GNU GPL v2 (see License.txt)\r
+Author:    Frank Nitzsche classd@beta-x.de\r
+File:      tda7449.h\r
+Version:   16.02.09\r
+Compiler:  AVR-GCC\r
+**************************************************************************/\r
+\r
+#ifndef TDA7449_H\r
+#define TDA7449_H\r
+\r
+#include "common.h"\r
+\r
+/* \r
+Communication:\r
+  1. Master sends START condition\r
+  2. Master sends 7bits slave ID plus write bit (low)\r
+  3. Slave asserts ACK\r
+  4. Master sends Subaddress + B\r
+  5. Slave asserts ACK (or NACK)\r
+  6. Master sends Data_1..Data_n <--.  (more than one if B=1=Autoincrement)\r
+  7. Slave asserts ACK (or NACK) ---'\r
+  6. Master generates STOP condition\r
+*/\r
+\r
+//Slave address write\r
+#define TDA7449_WR_ADR     0x88\r
+\r
+//Subaddress "Autoincrement"\r
+#define TDA7449_B          0x10\r
+//Subaddress "Function"\r
+#define TDA7449_INP_SEL    0x00\r
+#define TDA7449_INP_GAIN   0x01\r
+#define TDA7449_VOLUME     0x02\r
+#define TDA7449_BASS       0x04\r
+#define TDA7449_TREBLE     0x05\r
+#define TDA7449_ATT_RIGHT  0x06\r
+#define TDA7449_ATT_LEFT   0x07\r
+\r
+//Input selection\r
+#define TDA7449_INP1       0x03\r
+#define TDA7449_INP2       0x02\r
+\r
+\r
+//////////////////////////////////////////////////////////////////////////\r
+void TDA7449init(void);\r
+//////////////////////////////////////////////////////////////////////////\r
+void TDA7449setInput(U8);        // {TDA7449_INP1, TDA7449_INP2}\r
+//////////////////////////////////////////////////////////////////////////\r
+void TDA7449setBass(S8);         // {-14,-12,..+12,+14} [dB]\r
+//////////////////////////////////////////////////////////////////////////\r
+void TDA7449setTreble(S8);       // {-14,-12,..+12,+14} [dB]\r
+//////////////////////////////////////////////////////////////////////////\r
+void TDA7449setGain(U8);         // {0,2,4,...26,28,30} [dB]\r
+//////////////////////////////////////////////////////////////////////////\r
+S8   TDA7449getBass(void);       // {-14,-12,..+12,+14} [dB]\r
+//////////////////////////////////////////////////////////////////////////\r
+S8   TDA7449getTreble(void);     // {-14,-12,..+12,+14} [dB]\r
+//////////////////////////////////////////////////////////////////////////\r
+U8   TDA7449getGain(void);       // {0,2,4,...26,28,30} [dB]\r
+\r
+\r
+#endif//TDA7449_H\r
diff --git a/mv-nnml2maildir b/mv-nnml2maildir
new file mode 100755 (executable)
index 0000000..84404ba
--- /dev/null
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+set -e
+
+dir="$1"
+newdir="$2"
+hostname=$(hostname)
+
+if ! $HOME/w/misc-scripts/readgnusmarks --version >/dev/null 2>&1; then
+    echo "the readgnusmarks tool is missing" >&2
+    exit 2
+fi
+
+[ -z $newdir ] && exit 1
+
+if [ ! -d "$newdir" ]; then
+  mkdir "$newdir"
+  chmod 2700 "$newdir"
+  mkdir      "$newdir"/tmp "$newdir"/cur "$newdir"/new
+  chmod 2700 "$newdir"/tmp "$newdir"/cur "$newdir"/new
+fi
+
+newdir=$(cd "$newdir" && pwd)
+
+cd $dir
+if [ ! -f .marks ]; then
+    echo ".marks file missing" >&2
+    exit 1
+fi
+
+script=$(tempfile)
+
+ls | $HOME/w/misc-scripts/readgnusmarks --verbose .marks "$newdir" >$script
+
+echo "moving $(cat $script | wc -l) files to $newdir" >&2
+sh $script
+rm $script
+
+
+
+
+
diff --git a/readgnusmarks.c b/readgnusmarks.c
new file mode 100644 (file)
index 0000000..bf42b64
--- /dev/null
@@ -0,0 +1,403 @@
+/* readgnusmarks.c - Helper to convert nnml to Maildir
+ *     Copyright (C) 2009 Werner Koch
+ *
+ * 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; either version 3 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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+#include <time.h>
+
+#define PGM           "readgnusmarks"
+#define PGM_VERSION   "0.0"
+#define PGM_BUGREPORT "wk@gnupg.org"
+
+/* Option flags. */
+static int verbose;
+static int debug;
+static const char *outputdir;
+
+/* Error counter.  */
+static int any_error;
+
+
+typedef struct
+{
+  unsigned int in_use:1;
+  unsigned int seen:1;
+  unsigned int replied:1;
+  unsigned int passed:1;
+  unsigned int flagged:1;
+} flags_t;
+
+/* Number of flags we currently support.  If one ever needs to process
+   messages with nnnml file number higher an additional data structure
+   is required.  */
+#define MAX_FLAGS 300000
+
+/* An array of flags and a value indicating the allocated numer of
+   elements.  */
+static flags_t *flagarray;
+static size_t flagarraysize;
+
+
+
+/* Print diagnostic message and exit with failure. */
+static void
+die (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  fflush (stdout);
+  fprintf (stderr, "%s: ", PGM);
+
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+  putc ('\n', stderr);
+
+  exit (1);
+}
+
+
+/* Print diagnostic message. */
+static void
+err (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  any_error = 1;
+
+  fflush (stdout);
+  fprintf (stderr, "%s: ", PGM);
+
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+  putc ('\n', stderr);
+}
+
+/* Print an info message. */
+static void
+inf (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  if (!verbose)
+    return;
+
+  fflush (stdout);
+  fprintf (stderr, "%s: ", PGM);
+
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+  putc ('\n', stderr);
+}
+
+
+
+static void
+set_mark (int num, int action)
+{
+  if (!action)
+    return;
+
+  if (num < 0 || (size_t)num >= flagarraysize)
+    die ("nnml file number %d too high; maximum is %lu", 
+         num, (unsigned long)flagarraysize);
+
+  flagarray[num].in_use = 1;
+  switch (action)
+    {
+    case 'S': flagarray[num].seen = 1; break;
+    case 'R': flagarray[num].replied = 1; break;
+    case 'P': flagarray[num].passed = 1; break;
+    case 'F': flagarray[num].flagged = 1; break;
+    }
+}
+
+
+
+
+
+static void
+read_marks (const char *fname)
+{
+  FILE *fp;
+  int c;
+  int level = 0;
+  int wait_for_action = 0;
+  char token[50];
+  size_t tokenidx = 0;
+  int action = 0;
+  int num, n_from, n_to, cons_state;
+
+  fp = fopen (fname, "r");
+  if (!fp)
+    die ("failed to open `%s': %s", fname, strerror (errno));
+
+  while ((c = getc (fp)) != EOF)
+    {
+      if (!isascii (c))
+        die ("non ascii character found in `%s' - can't proceed", fname);
+      if (isspace (c))
+        ;
+      else if (level < 0)
+        die ("garbage at end of `%s' - can't proceed", fname);
+      else if (c == ')')
+        ;
+      else if (c == '(')
+        {
+          level++;
+          if (level > 3)
+            die ("nesting too deep in `%s' - can't proceed", fname);
+          if (wait_for_action && level == 3)
+            die ("action missing in `%s' - can't proceed", fname);
+          wait_for_action = (level == 2);
+          if (level == 3)
+            cons_state = n_from = n_to = 0;
+          tokenidx = 0;
+        }
+      else
+        {
+          if (tokenidx+1 >= sizeof token)
+            die ("token too long in `%s' - can't proceed", fname);
+          token[tokenidx++] = c;
+          continue;
+        }
+      
+      token[tokenidx] = 0;
+      if (tokenidx)
+        {
+          tokenidx = 0;
+          if (wait_for_action)
+            {
+              wait_for_action = 0;
+              inf ("got action token `%s'", token);
+              if (!strcmp (token, "read"))
+                action = 'S';
+              else if (!strcmp (token, "reply"))
+                action = 'R';
+              else if (!strcmp (token, "forward"))
+                action = 'P';
+              else if (!strcmp (token, "tick"))
+                action = 'F';
+              else if (!strcmp (token, "save")
+                       ||!strcmp (token, "dormant")
+                       ||!strcmp (token, "killed"))
+                {
+                  inf ("action '%s' in `%s' - ignored", token, fname);
+                  action = 0;
+                }
+              else 
+                {
+                  err ("unknown action '%s' in `%s' - skipped", token, fname);
+                  action = 0;
+                }
+            }
+          else if (level == 2)
+            {
+              num = atoi (token);
+              if (num < 1)
+                err ("bad number `%s' in `%s' - skipped", token, fname);
+              else
+                set_mark (num, action);
+            }
+          else if (level == 3)
+            {
+              if (*token == '.' && !token[1] && cons_state == 1)
+                cons_state++;
+              else
+                {
+                  num = atoi (token);
+                  if (num < 1)
+                    err ("bad number `%s' in `%s' - skipped", token, fname);
+                  else if (!cons_state)
+                    {
+                      cons_state++;
+                      n_from = num;
+                    }
+                  else if (cons_state == 2)
+                    {
+                      cons_state++;
+                      n_to = num;
+                      if (n_to < n_from)
+                        err ("invalid range in `%s'", fname);
+                      for (num = n_from; num <= n_to; num++)
+                        set_mark (num, action);
+                    }
+                  else
+                    err ("too many numbers in cons `%s' - skipped", fname);
+                }
+            }
+        }
+      if (c == ')')
+        level--;
+    }
+  if (ferror (fp))
+    die ("failed to read `%s': %s", fname, strerror (errno));
+
+  fclose (fp);
+}
+
+
+static void
+process_input (void)
+{
+  char oldname[1024];
+  char newname[1024+50];
+  size_t n;
+  const char *s;
+  char *endp;
+  int num;
+  int counter = 0;
+
+  while (fgets (oldname, sizeof oldname, stdin))
+    {
+      n = strlen (oldname);
+      if (n && oldname[n-1] == '\n')
+        oldname[--n] = 0;
+      s = oldname;
+      num = (int)strtol (s, &endp, 10);
+      if (num < 1 || *endp != '\0')
+        {
+          err ("bad file name structure '%s' - skipped", oldname);
+          continue;
+        }
+      if (num < 0 || (size_t)num >= flagarraysize)
+        {
+          err ("nnml file number %d in `%s' too high - skipped", num, oldname);
+          continue;
+        }
+
+      snprintf (newname, sizeof newname-50, "%s/cur/%lu.%d-%d", 
+                outputdir,
+                (unsigned long)time (NULL), num, ++counter);
+
+      strcat (newname, ":2,");
+      if (flagarray[num].in_use)
+        {
+           if (flagarray[num].flagged)
+             strcat (newname, "F");
+           if (flagarray[num].passed)
+             strcat (newname, "P");
+           if (flagarray[num].replied)
+             strcat (newname, "R");
+           if (flagarray[num].seen)
+             strcat (newname, "S");
+        }
+      if ( !strcmp (oldname, newname) )
+        {
+          inf ("file `%s' not moved", oldname);
+          continue;
+        }
+      printf ("mv '%s' '%s'\n", oldname, newname); 
+    }
+  if (ferror (stdin))
+    die ("error reading from stdin: %s", strerror (errno));
+}
+
+
+
+
+static int
+show_usage (int ex)
+{
+  fputs ("Usage: " PGM " <MARKSFILE> [OUTDIR]\n"
+         "Read an nnml .marks file and rename Maildir files from stdin\n\n"
+         "  --verbose      enable extra informational output\n"
+         "  --debug        enable additional debug output\n"
+         "  --help         display this help and exit\n\n"
+         "This tool is used with the mv-nnml2maildir script.\n"
+         "Report bugs to " PGM_BUGREPORT ".\n",
+         ex? stderr:stdout);
+  exit (ex);
+}
+
+
+int 
+main (int argc, char **argv)
+{
+  int last_argc = -1;
+
+  if (argc)
+    {
+      argc--; argv++;
+    }
+  while (argc && last_argc != argc )
+    {
+      last_argc = argc;
+      if (!strcmp (*argv, "--"))
+        {
+          argc--; argv++;
+          break;
+        }
+      else if (!strcmp (*argv, "--version"))
+        {
+          fputs (PGM " " PGM_VERSION "\n", stdout);
+          exit (0);
+        }
+      else if (!strcmp (*argv, "--help"))
+        {
+          show_usage (0);
+        }
+      else if (!strcmp (*argv, "--verbose"))
+        {
+          verbose = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--debug"))
+        {
+          verbose = debug = 1;
+          argc--; argv++;
+        }
+      else if (!strncmp (*argv, "--", 2))
+        show_usage (1);
+    }          
+
+  if (argc < 1 || argc > 2 )
+    show_usage (1);
+  if (argc == 2)
+    outputdir = argv[1];
+  else
+    outputdir = ".";
+
+  flagarraysize = MAX_FLAGS;
+  flagarray = calloc (flagarraysize, sizeof *flagarray);
+  if (!flagarray)
+    die ("out of core: %s", strerror (errno));
+
+  read_marks (*argv);
+  
+  process_input ();
+
+  free (flagarray);
+
+  return any_error? 1:0;
+}
+
+
+/*
+Local Variables:
+compile-command: "gcc -Wall -W -O2 -g -o readgnusmarks readgnusmarks.c"
+End:
+*/