From 2df2697107d7873232c31a25a6947711b0903edb Mon Sep 17 00:00:00 2001
From: Max Christian Pohle
Date: Mon, 27 Jul 2015 15:12:22 +0200
Subject: latest running version from march 2011, not having been in repo
 before, dcf77 working, mp3 playback and two display types are supported

---
 src/inc/spi/dev/audio_vs1011.c | 173 +++++++++++++++++++++++++++++++++++++++++
 src/inc/spi/dev/audio_vs1011.h |  91 ++++++++++++++++++++++
 src/inc/spi/dev/display_dogm.c |  39 ++++++++++
 src/inc/spi/dev/display_dogm.h |  31 ++++++++
 src/inc/spi/dev/petit          |   1 +
 src/inc/spi/spi.c              |  56 +++++++++++++
 src/inc/spi/spi.h              |  37 +++++++++
 7 files changed, 428 insertions(+)
 create mode 100755 src/inc/spi/dev/audio_vs1011.c
 create mode 100755 src/inc/spi/dev/audio_vs1011.h
 create mode 100755 src/inc/spi/dev/display_dogm.c
 create mode 100755 src/inc/spi/dev/display_dogm.h
 create mode 160000 src/inc/spi/dev/petit
 create mode 100755 src/inc/spi/spi.c
 create mode 100755 src/inc/spi/spi.h

(limited to 'src/inc/spi')

diff --git a/src/inc/spi/dev/audio_vs1011.c b/src/inc/spi/dev/audio_vs1011.c
new file mode 100755
index 0000000..ad44654
--- /dev/null
+++ b/src/inc/spi/dev/audio_vs1011.c
@@ -0,0 +1,173 @@
+#include "audio_vs1011.h"
+/// inline void audio_vs1011_setVolume(unsigned char left, unsigned char right)
+/// { audio_vs1011_cmd(SCI_VOL, left, right); }
+
+void audio_vs1011_init()
+{
+  // [initialize pins and ports]
+  DDRC  |= ((1<<PC1) | (1<<PC2) | (1<<PC4)); // XCS/XDCS/RESET
+  DDRC  &= ~(1<<PC3); // DREQ
+  //DDRA  |=  (1<<PA6); // activate O-Port A6 as [XCS]
+  //DDRC  |=  (1<<PC6); // activate O-Port C6 as [XDCS]
+  //DDRD  |=  (1<<PD6); // activate O-Port D6 as [RESET]
+  //DDRD  &= ~(1<<PD5); // activate I-Port D5 as [DREQ]
+
+
+  // pins...
+  /// PORTA |= (1<<PA6);
+  /// PORTC |= (1<<PC6);
+  PORTC |= (1<<PC3);        // enable pullup resistor for [DREQ]
+  audio_vs1011_exit_xcs();  // activate XCS: deactivate vs1011-cmd-line
+  audio_vs1011_exit_xdcs(); // activate XDCS: deactivate vs1011-data-line
+
+  // [reset vs1011]
+  // this ensures, that it finds XCS and XDCS in proper state (see below)
+  /// PORTD &= ~(1<<PD6); // <reset>
+  // Wait for at least 10 ms after startup (required!!)
+  // then make GPIO an output signal and set it to 1...
+  /// _delay_ms(20);
+  PORTC |= (1<<PC4);  // </reset>
+  /// _delay_ms(20);
+
+  // wait until DREQ is set- so chip has rebooted from reset...
+  wait4dreq();
+
+  // [set vs1011 to 'new-mode']
+  // where xdcs is driven low, before you want to send mp3-data or test-bits
+  // where xcs is driven low to send SCI-commands.
+  // and both together may not been activated, why we started with resetting
+  // after having configured those output-ports.
+  audio_vs1011_cmd(SCI_MODE, (SM_SDINEW | SM_TESTS));
+
+  // [set clock-frequency...]
+  // formular:
+  //     32768{if clock doubler}
+  //   + (F_CRYSTAL{crystals frequency in Hz} / 2000{const})
+  //   = 0x9770 for a 12MHz-crystal (with clock-doubler), so send:
+  /// audio_vs1011_cmd(SCI_CLOCKF, 0x98, 0x00);
+  /// stdout_put_uint(uart_putc, ((F_CPU / 2000) | SC_CLK2X));
+  /// stdout_put_string(uart_putc, "\t< clock freq for vs1011\n");
+
+  audio_vs1011_cmd(SCI_CLOCKF, ((F_CPU / 2000) | SC_CLK2X));
+  audio_vs1011_cmd(SCI_AUDATA, 44100);
+
+  /*
+  spi_setspeed(SPICLK_FAST);
+  int q;
+  for(q=0; q<=30000; q++)
+    spi_putc(0x00);
+  spi_setspeed(SPICLK_DEFAULT);
+  // wait for at least 11000 clock cycles...
+  */
+
+  // wait until DREQ is set- so chip has rebooted from reset...
+  wait4dreq();
+
+
+  /// spi_putc(0xFF);
+
+  audio_vs1011_setVolume(1, 1); // left and right both to 100%=0xFF
+  /// _delay_ms(250);
+
+  /// stdout_put_string(uart_putc, "clock frequency set!\n");
+}
+
+
+void audio_vs1011_setVolume(const unsigned char left, const unsigned char right)
+{
+  //uint16_t volume = right + (256 * left);
+  /// stdout_put_uint(uart_putc, volume);
+  /// stdout_put_string(uart_putc, "\t< new volume for vs1011\n");
+  audio_vs1011_cmd(SCI_VOL, ((uint16_t) right) + ((uint16_t) left * 256));
+}
+
+void audio_vs1011_test_volume()
+{
+  audio_vs1011_setVolume(0, 0); // left and right to 0%=0x00 -> standby
+  _delay_ms(250);
+  audio_vs1011_setVolume(255, 255); // left and right both to 100%=0xFF
+  _delay_ms(250);
+}
+
+void audio_vs1011_test_sine()
+{
+  static const unsigned char sinetest[] = {0x53, 0xEF, 0x6E, 0x30, 0x0, 0x0, 0x0, 0x0};
+  static const unsigned char testexit[] = {'E', 'x', 'i', 't', 0x0, 0x0, 0x0, 0x0};
+
+  /// audio_vs1011_setVolume(255, 255); // left and right both to 100%=0xFF
+  /// stdout_put_string(uart_putc, "activating sine-test...\n");
+  audio_vs1011_dat(sinetest, sizeof(sinetest));
+  _delay_ms(250);
+
+  /// stdout_put_string(uart_putc, "deactivating sine-test...\n");
+  audio_vs1011_dat(testexit, sizeof(testexit));
+  _delay_ms(250);
+  /// audio_vs1011_setVolume(255, 255); // left and right both to 100%=0xFF
+}
+
+/*
+void audio_vs1011_test_eeprom()
+{
+  unsigned char block[512];
+  eeprom_read_block((void*) &block, (const void*) 0, 512);
+
+  int i,q;
+  for(i=0; i<512; i+=32)
+  {
+    audio_vs1011_enable();
+    loop_until_bit_is_set(PIND, PD5);
+    for(q=0; q<32; q++)
+      spi_putc(block[i+q]);
+    audio_vs1011_disable();
+ }
+  loop_until_bit_is_set(PIND, PD5);
+ _delay_ms(500);
+}
+*/
+
+void audio_vs1011_dat(const unsigned char* dat, const unsigned char size)
+{
+  audio_vs1011_enable();
+  unsigned char i;
+  for(i=0; i<size; i++)
+    spi_putc(dat[i]);
+  audio_vs1011_disable();
+}
+
+
+/*
+unsigned char audio_vs1011_stream(unsigned char (*readfn)())
+{
+  audio_vs1011_enable();
+  register unsigned char i;
+  for(i=0; i<32; i++)
+    spi_putc(readfn());
+  audio_vs1011_disable();
+  audio_vs1011_waitDREQ();
+  return 32;
+}*/
+
+
+
+
+void audio_vs1011_cmd(const unsigned char cmd, uint16_t dat)
+{
+  loop_until_bit_is_set(PIND, PD5);
+  /// audio_vs1011_enable();
+  //PORTA &= ~(1<<PA6); // <XCS>
+  audio_vs1011_init_xcs();
+  spi_putc(VS_WRITE);
+  spi_putc(cmd);
+  spi_putc((dat >> 8) & 0xFF);
+  spi_putc((dat >> 0) & 0xFF);
+  //PORTA |=  (1<<PA6); // </XCS>
+  audio_vs1011_exit_xcs();
+  spi_putc(0);
+  spi_putc(0);
+  spi_putc(0);
+  spi_putc(0);
+  /// audio_vs1011_disable();
+  /// _delay_ms(1);       // << wait to make sure vs1011 got the message
+  _delay_ms(5);
+  loop_until_bit_is_set(PIND, PD5); // << wait for DREQ to become ready again
+}
diff --git a/src/inc/spi/dev/audio_vs1011.h b/src/inc/spi/dev/audio_vs1011.h
new file mode 100755
index 0000000..ec97550
--- /dev/null
+++ b/src/inc/spi/dev/audio_vs1011.h
@@ -0,0 +1,91 @@
+#ifndef AUDIO_VS1011_H
+#define AUDIO_VS1011_H
+
+  #include <avr/io.h>
+  #include <util/delay.h>
+  #include <inttypes.h>
+  #include <avr/eeprom.h>
+
+  #include "../spi.h"
+  /// #include "../../uart/uart.h"
+  /// #include "../../stdout.h"
+
+
+  #define audio_vs1011_enable()  PORTC &= ~(1<<PC6); // <XDCS>
+  #define audio_vs1011_disable() PORTC |=  (1<<PC6); // </XDCS>
+  #define audio_vs1011_isDREQ()  (PIND & (1<<PD5))
+  #define audio_vs1011_waitDREQ(); loop_until_bit_is_set(PIND, PD5);
+
+
+  // [OPERATIONS]
+  #define VS_WRITE 0x2
+  #define VS_READ  0x3
+
+
+  // [SCI REGISTERS] - page 29
+  #define SCI_MODE        0x0 // Mode control
+  #define SCI_STATUS      0x1 // Status of VS1011e
+  #define SCI_BASS        0x2 // Built-in bass/treble enhancer
+  #define SCI_CLOCKF      0x3 // Clock freq + multiplier
+  #define SCI_DECODE_TIME 0x4 // Decode time in seconds
+  #define SCI_AUDATA      0x5 // Misc. audio data
+  #define SCI_WRAM        0x6 // RAM write/read
+  #define SCI_WRAMADDR    0x7 // Base address for RAM write/read
+  #define SCI_HDAT0       0x8 // Stream header data 0
+  #define SCI_HDAT1       0x9 // Stream header data 1
+  #define SCI_AIADDR      0xA // Start address of application
+  #define SCI_VOL         0xB // Volume control
+  #define SCI_AICTRL0     0xC // Application control register 0
+  #define SCI_AICTRL1     0xD // Application control register 1
+  #define SCI_AICTRL2     0xE // Application control register 2
+  #define SCI_AICTRL3     0xF // Application control register 3
+
+  // [VALUES::SCI_MODE]
+  #define SM_DIFF       0x1    // Differential
+  #define SM_LAYER12    0x2    // Allow MPEG layers I & II
+  #define SM_RESET      0x4    // Soft reset
+  #define SM_OUTOFWAV   0x8    // Jump out of WAV decoding
+  #define SM_SETTOZERO1 0x10   // set to zero
+  #define SM_TESTS      0x20   // Allow SDI tests
+  #define SM_STREAM     0x40   // Stream mode
+  #define SM_SETTOZERO2 0x80   // set to zero
+
+  #define SM_DACT       0x100  // DCLK active edge
+  #define SM_SDIORD     0x200  // SDI bit order
+  #define SM_SDISHARE   0x400  // Share SPI chip select
+  #define SM_SDINEW     0x800  // VS1002 native SPI modes
+  #define SM_SETTOZERO3 0x1000 // set to zero
+
+  // [VALUES::SCI_CLOCKF]
+  #define SC_CLK2X      0x8000 // clock doubler
+
+  #define audio_vs1011_init_xcs()    PORTC &= ~(1<<PC1)  // <XCS>
+  #define audio_vs1011_exit_xcs()    PORTC |=  (1<<PC1); // </XCS>
+
+  #define audio_vs1011_init_xdcs()   PORTC &= ~(1<<PC2)  // <XCS>
+  #define audio_vs1011_exit_xdcs()   PORTC |=  (1<<PC2); // </XCS>
+
+  #define wait4dreq() loop_until_bit_is_set(PINC, PC3);  // <DREQ></DREQ>
+
+
+  /// void audio_vs1011_cmd(const unsigned char sci_cmd, const unsigned char hdata,
+    /// const unsigned char ldata);
+  void audio_vs1011_init();
+  void audio_vs1011_cmd(const unsigned char cmd, uint16_t dat);
+  void audio_vs1011_setVolume(const unsigned char left, const unsigned char right);
+
+  //void audio_vs1011_dat(const unsigned char dat[32]);
+  void audio_vs1011_dat(const unsigned char* dat, const unsigned char size);
+  /// unsigned char audio_vs1011_stream(unsigned char (*readfn)());
+  void audio_vs1011_test_sine();
+  void audio_vs1011_test_volume();
+  /// void audio_vs1011_test_eeprom();
+  /// void audio_vs1011_enable();
+  /// void audio_vs1011_disable();
+  /// char audio_vs1011_isDREQ();
+
+
+  /// void audio_vs1011_test_softreset();
+
+
+#endif
diff --git a/src/inc/spi/dev/display_dogm.c b/src/inc/spi/dev/display_dogm.c
new file mode 100755
index 0000000..a655769
--- /dev/null
+++ b/src/inc/spi/dev/display_dogm.c
@@ -0,0 +1,39 @@
+#include "display_dogm.h"
+
+void display_dogm_init()
+{
+  //DDRA |= (1<<PA7); // activate portA for display
+  //DDRC |= (1<<PC7); // activate portC for display
+  DDRD  |= (1<<PD7) | (1<<PD6);
+  PORTD |= (1<<PD7) | (1<<PD6);
+
+  // Wait time >40mS after VDD stable
+  _delay_ms(50); // 10ms for safty
+
+  display_dogm_exec(CMD_FUNCTION_SET);
+  display_dogm_exec(CMD_FUNCTION_SET);
+  display_dogm_exec(CMD_CONTRAST_SET);
+  display_dogm_exec(CMD_POWER_CONTROL);
+  display_dogm_exec(CMD_FOLLOWER_CONTROL);
+  display_dogm_exec(CMD_DISPLAY_ONOFF);
+  display_dogm_exec(CMD_ENTRY_MODE_SET);
+  display_dogm_exec(CMD_DISPLAY_CLEAR);
+}
+
+void display_dogm_putc(char c)
+{
+  PORTD &= ~(1<<PD7); // chip select: activate display
+  PORTD |=  (1<<PD6); // L=Commandmode, H=Datamode
+  spi_putc(c);
+  _delay_us(40);      // try and error value (you get chinese chars? increase!)
+  PORTD |=  (1<<PD7); // chip select: deactivate display
+}
+
+void display_dogm_exec(char c)
+{
+  PORTD &= ~(1<<PD7); // chip select: activate display
+  PORTD &= ~(1<<PD6); // L=Commandmode, H=Datamode
+  spi_putc(c);
+  _delay_ms(4);       // time the longest command takes on display
+  PORTD |=  (1<<PD7); // chip select: deactivate display
+}
diff --git a/src/inc/spi/dev/display_dogm.h b/src/inc/spi/dev/display_dogm.h
new file mode 100755
index 0000000..d9cf560
--- /dev/null
+++ b/src/inc/spi/dev/display_dogm.h
@@ -0,0 +1,31 @@
+#ifndef DISPLAY_DOGM_H
+#define DISPLAY_DOGM_H
+
+  #include <avr/io.h>
+  #include <util/delay.h>
+  #include "../spi.h"
+
+  #define CONTAST              3
+
+  #define CMD_FUNCTION_SET          32 + 16 + 8 + 0 + 1
+  #define CMD_POWER_CONTROL    64 +  0 + 16 + 0 + 4 + CONTAST
+  #define CMD_FOLLOWER_CONTROL 0x6E
+
+  #define CMD_ENTRY_MODE_SET   4 + 2 + 0
+  #define CMD_DISPLAY_HOME     0 + 2 + 0
+  #define CMD_DISPLAY_CLEAR    0 + 0 + 1
+
+  #define CMD_CONTRAST_SET     0x7F
+  #define CMD_FUNCTION_SET2    0x38
+  #define CMD_DISPLAY_ONOFF    0x0C
+  #define CMD_DISPLAY_POS      0x80
+
+  //#define display_dogm_enable()  PORTD &= ~(1<<PD7); PORTD |=  (1<<PD6); // <XDCS>
+  //#define display_dogm_disable() PORTD |=  (1<<PD7); PORTD &= ~(1<<PD6); // </XDCS>
+
+
+  void display_dogm_init();
+  void display_dogm_putc(char);
+  void display_dogm_exec(char);
+
+#endif
diff --git a/src/inc/spi/dev/petit b/src/inc/spi/dev/petit
new file mode 160000
index 0000000..b110953
--- /dev/null
+++ b/src/inc/spi/dev/petit
@@ -0,0 +1 @@
+Subproject commit b1109539d5d34b62849d67a65ce244fcb1d0f5e5
diff --git a/src/inc/spi/spi.c b/src/inc/spi/spi.c
new file mode 100755
index 0000000..b04fe7e
--- /dev/null
+++ b/src/inc/spi/spi.c
@@ -0,0 +1,56 @@
+#include "spi.h"
+
+void spi_init()
+{
+  // setup SPI-Port
+  DDR_SPI   = (1<<DD_MOSI) | (1<<DD_SS) | (1<<DD_SCK);
+  PORT_SPI |=  (1<<DD_SS);
+
+  // SPI Control Register (SPCR)
+  // SPI Enable=1 | Data Order=LSB | SPI_Master=1 (!make SS stay HIGH!)
+  // SPCR |= (1<<SPE) | (1<<DORD) | (1<<MSTR) | (1<<CPOL) | (1<<CPHA) | (1<<SPR1) | (1<<SPR0);
+  // (1<<DORD) - would be LSB-mode (, but we need MSB-mode!)
+  SPCR  = (1<<SPE) | (1<<MSTR); //  (1<<SPR1) | (1<<SPR0)
+  spi_setspeed(SPICLK_DEFAULT);
+  // setup SPI options
+  /// SPSR &= ~(1<<SPI2X); // do not use SPI speed-doubler
+}
+
+void spi_setspeed(SPICLK speed)
+{
+  if(speed < 4) // nominal clock speeds
+  {
+    SPSR &= ~(1<<SPI2X); // do not use SPI speed-doubler
+    SPCR |= speed;
+  }
+  else // use SPI2X
+  {
+    SPSR |= (1<<SPI2X);  // use SPI speed-doubler
+    SPCR |= (speed - 0x4);
+  }
+  _delay_ms(2);
+}
+
+void spi_putc(unsigned char c)
+{
+  /// uart_putc('>');
+  /// uart_putc(c);
+  /// uart_putc('\n');
+  SPDR = c;
+  loop_until_bit_is_set(SPSR, SPIF);
+  /// stdout_put_string(uart_putc, "- [done]\n");
+}
+
+unsigned char spi_getc()
+{
+  SPDR = 0xFF; // init receive register with value
+  /* Wait for reception complete */
+  while(!(SPSR & (1<<SPIF)));
+  /* Return data register */
+  return SPDR;
+  /// unsigned char c = SPDR;
+  /// uart_putc('<');
+  /// uart_putc(c);
+  /// uart_putc('\n');
+  /// return c;
+}
diff --git a/src/inc/spi/spi.h b/src/inc/spi/spi.h
new file mode 100755
index 0000000..bb92cac
--- /dev/null
+++ b/src/inc/spi/spi.h
@@ -0,0 +1,37 @@
+#ifndef SPI_H
+#define SPI_H
+
+  #include <avr/io.h>
+  #include <util/delay.h>
+  #include "../uart/uart.h"
+  #include "../stdout.h"
+
+  #define SPICLK_DEFAULT  SPICLK_64
+  #define SPICLK_FAST     SPICLK_X2
+
+  #define PORT_SPI        PORTB
+  #define DDR_SPI         DDRB
+  #define DD_SS           DDB4
+  #define DD_MOSI         DDB5
+  #define DD_MISO         DDB6
+  #define DD_SCK          DDB7
+
+  typedef enum
+  {
+    SPICLK_4,   // vv nominal clk-speeds
+    SPICLK_16,
+    SPICLK_64,
+    SPICLK_128,
+    SPICLK_X2,   // vv with SPI2x
+    SPICLK_X32,
+    SPICLK_X64
+  } SPICLK;
+
+
+  void spi_init();
+  void spi_putc(unsigned char c);
+  unsigned char spi_getc();
+  void spi_setspeed(SPICLK speed);
+
+
+#endif
-- 
cgit v1.2.3