Skip to content

Instantly share code, notes, and snippets.

@philippeowagner
Forked from anonymous/miniTSos09.ino
Created August 8, 2024 08:02
Show Gist options
  • Save philippeowagner/d7b942e9f5a4f8888b15156322fd66e8 to your computer and use it in GitHub Desktop.
Save philippeowagner/d7b942e9f5a4f8888b15156322fd66e8 to your computer and use it in GitHub Desktop.
mini-TS OS v0.9
#define SSD1306_SDA 4
#define SSD1306_SCL 5
#define SSD1306_SA 
0x78  // Slave address
 
#define ENC_A 14
#define ENC_B 15
#define ENC_PORT PINC
 
int8_t test;
 
uint8_t oldbut;
uint8_t parmselect=0;
 
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
 
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
 
// Standard Arduino Pins
#define digitalPinToPortReg(P) \
(((P) >= 0 && (P) <= 7) ? &PORTD : (((P)
>= 8 && (P) <= 13) ? &PORTB : &PORTC))
#define digitalPinToDDRReg(P) \
(((P) >= 0 && (P) <= 7) ? &DDRD : (((P)
>= 8 && (P) <= 13) ? &DDRB : &DDRC))
#define digitalPinToPINReg(P) \
(((P) >= 0 && (P) <= 7) ? &PIND : (((P)
>= 8 && (P) <= 13) ? &PINB : &PINC))
#define digitalPinToBit(P) \
(((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8
&& (P) <= 13) ? (P) – 8 : (P) – 14))
 
#define digitalReadFast(P) bitRead(*digitalPinToPINReg(P),
digitalPinToBit(P))
                 
#define digitalWriteFast(P, V)
bitWrite(*digitalPinToPortReg(P), digitalPinToBit(P), (V))
 
const unsigned char PS_2 = (1 << ADPS0);;
const unsigned char PS_4 = (1 << ADPS1);
const unsigned char PS_8 = (1 << ADPS1) | (1 <<
ADPS0);
const unsigned char PS_16 = (1 << ADPS2);
const unsigned char PS_32 = (1 << ADPS2) | (1 <<
ADPS0);
const unsigned char PS_64 = (1 << ADPS2) | (1 <<
ADPS1);
const unsigned char PS_128 = (1 << ADPS2) | (1
<< ADPS1) | (1 << ADPS0);
 
// —————————————————————————-
 
#define DIGITAL_WRITE_HIGH(PORT) PORTC |= (1 << PORT)
#define DIGITAL_WRITE_LOW(PORT) PORTC &= ~(1 <<
PORT)
 
// —————————————————————————-
 
volatile uint8_t waveform[128] {
 
 
127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198,200,203,205,208,210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239,240,
 
242,243,244,245,247,248,249,249,250,251,252,252,253,253,253,254,254,254,254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,234,233,231,229,227,225,223,
 
221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,176,173,170,167,164,161,158,155,152,149,146,143,139,136,133,130
};
/* Standard ASCII 6×8 font */
const uint8_t ssd1306xled_font6x8 [] PROGMEM = {
  0x00, 0x00, 0x00,
0x00, 0x00, 0x00, // sp
  0x00, 0x00, 0x00,
0x2f, 0x00, 0x00, // !
  0x00, 0x00, 0x07,
0x00, 0x07, 0x00, // “
  0x00, 0x14, 0x7f,
0x14, 0x7f, 0x14, // #
  0x00, 0x24, 0x2a,
0x7f, 0x2a, 0x12, // $
  0x00, 0x62, 0x64,
0x08, 0x13, 0x23, // %
  0x00, 0x36, 0x49,
0x55, 0x22, 0x50, // &
  0x00, 0x00, 0x05,
0x03, 0x00, 0x00, // ‘
  0x00, 0x00, 0x1c,
0x22, 0x41, 0x00, // (
  0x00, 0x00, 0x41,
0x22, 0x1c, 0x00, // )
  0x00, 0x14, 0x08,
0x3E, 0x08, 0x14, // *
  0x00, 0x08, 0x08,
0x3E, 0x08, 0x08, // +
  0x00, 0x00, 0x00,
0xA0, 0x60, 0x00, // ,
  0x00, 0x08, 0x08,
0x08, 0x08, 0x08, // –
  0x00, 0x00, 0x60,
0x60, 0x00, 0x00, // .
  0x00, 0x20, 0x10,
0x08, 0x04, 0x02, // /
  0x00, 0x3E, 0x51,
0x49, 0x45, 0x3E, // 0
  0x00, 0x00, 0x42,
0x7F, 0x40, 0x00, // 1
  0x00, 0x42, 0x61,
0x51, 0x49, 0x46, // 2
  0x00, 0x21, 0x41,
0x45, 0x4B, 0x31, // 3
  0x00, 0x18, 0x14,
0x12, 0x7F, 0x10, // 4
  0x00, 0x27, 0x45,
0x45, 0x45, 0x39, // 5
  0x00, 0x3C, 0x4A,
0x49, 0x49, 0x30, // 6
  0x00, 0x01, 0x71,
0x09, 0x05, 0x03, // 7
  0x00, 0x36, 0x49,
0x49, 0x49, 0x36, // 8
  0x00, 0x06, 0x49,
0x49, 0x29, 0x1E, // 9
  0x00, 0x00, 0x36,
0x36, 0x00, 0x00, // :
  0x00, 0x00, 0x56,
0x36, 0x00, 0x00, // ;
  0x00, 0x08, 0x14,
0x22, 0x41, 0x00, // <
  0x00, 0x14, 0x14,
0x14, 0x14, 0x14, // =
  0x00, 0x00, 0x41,
0x22, 0x14, 0x08, // >
  0x00, 0x02, 0x01,
0x51, 0x09, 0x06, // ?
  0x00, 0x32, 0x49,
0x59, 0x51, 0x3E, // @
  0x00, 0x7C, 0x12,
0x11, 0x12, 0x7C, // A
  0x00, 0x7F, 0x49,
0x49, 0x49, 0x36, // B
  0x00, 0x3E, 0x41,
0x41, 0x41, 0x22, // C
  0x00, 0x7F, 0x41,
0x41, 0x22, 0x1C, // D
  0x00, 0x7F, 0x49,
0x49, 0x49, 0x41, // E
  0x00, 0x7F, 0x09,
0x09, 0x09, 0x01, // F
  0x00, 0x3E, 0x41,
0x49, 0x49, 0x7A, // G
  0x00, 0x7F, 0x08,
0x08, 0x08, 0x7F, // H
  0x00, 0x00, 0x41,
0x7F, 0x41, 0x00, // I
  0x00, 0x20, 0x40,
0x41, 0x3F, 0x01, // J
  0x00, 0x7F, 0x08,
0x14, 0x22, 0x41, // K
  0x00, 0x7F, 0x40,
0x40, 0x40, 0x40, // L
  0x00, 0x7F, 0x02,
0x0C, 0x02, 0x7F, // M
  0x00, 0x7F, 0x04,
0x08, 0x10, 0x7F, // N
  0x00, 0x3E, 0x41,
0x41, 0x41, 0x3E, // O
  0x00, 0x7F, 0x09,
0x09, 0x09, 0x06, // P
  0x00, 0x3E, 0x41,
0x51, 0x21, 0x5E, // Q
  0x00, 0x7F, 0x09,
0x19, 0x29, 0x46, // R
  0x00, 0x46, 0x49,
0x49, 0x49, 0x31, // S
  0x00, 0x01, 0x01,
0x7F, 0x01, 0x01, // T
  0x00, 0x3F, 0x40,
0x40, 0x40, 0x3F, // U
  0x00, 0x1F, 0x20,
0x40, 0x20, 0x1F, // V
  0x00, 0x3F, 0x40,
0x38, 0x40, 0x3F, // W
  0x00, 0x63, 0x14,
0x08, 0x14, 0x63, // X
  0x00, 0x07, 0x08,
0x70, 0x08, 0x07, // Y
  0x00, 0x61, 0x51,
0x49, 0x45, 0x43, // Z
  0x00, 0x00, 0x7F,
0x41, 0x41, 0x00, // [
  0x00, 0x55, 0x2A,
0x55, 0x2A, 0x55, // 55
  0x00, 0x00, 0x41,
0x41, 0x7F, 0x00, // ]
  0x00, 0x04, 0x02,
0x01, 0x02, 0x04, // ^
  0x00, 0x40, 0x40,
0x40, 0x40, 0x40, // _
  0x00, 0x00, 0x01,
0x02, 0x04, 0x00, // ‘
  0x00, 0x20, 0x54,
0x54, 0x54, 0x78, // a
  0x00, 0x7F, 0x48,
0x44, 0x44, 0x38, // b
  0x00, 0x38, 0x44,
0x44, 0x44, 0x20, // c
  0x00, 0x38, 0x44,
0x44, 0x48, 0x7F, // d
  0x00, 0x38, 0x54,
0x54, 0x54, 0x18, // e
  0x00, 0x08, 0x7E,
0x09, 0x01, 0x02, // f
  0x00, 0x18, 0xA4,
0xA4, 0xA4, 0x7C, // g
  0x00, 0x7F, 0x08,
0x04, 0x04, 0x78, // h
  0x00, 0x00, 0x44,
0x7D, 0x40, 0x00, // i
  0x00, 0x40, 0x80,
0x84, 0x7D, 0x00, // j
  0x00, 0x7F, 0x10,
0x28, 0x44, 0x00, // k
  0x00, 0x00, 0x41,
0x7F, 0x40, 0x00, // l
  0x00, 0x7C, 0x04,
0x18, 0x04, 0x78, // m
  0x00, 0x7C, 0x08,
0x04, 0x04, 0x78, // n
  0x00, 0x38, 0x44,
0x44, 0x44, 0x38, // o
  0x00, 0xFC, 0x24,
0x24, 0x24, 0x18, // p
  0x00, 0x18, 0x24,
0x24, 0x18, 0xFC, // q
  0x00, 0x7C, 0x08,
0x04, 0x04, 0x08, // r
  0x00, 0x48, 0x54,
0x54, 0x54, 0x20, // s
  0x00, 0x04, 0x3F,
0x44, 0x40, 0x20, // t
  0x00, 0x3C, 0x40,
0x40, 0x20, 0x7C, // u
  0x00, 0x1C, 0x20,
0x40, 0x20, 0x1C, // v
  0x00, 0x3C, 0x40,
0x30, 0x40, 0x3C, // w
  0x00, 0x44, 0x28,
0x10, 0x28, 0x44, // x
  0x00, 0x1C, 0xA0,
0xA0, 0xA0, 0x7C, // y
  0x00, 0x44, 0x64,
0x54, 0x4C, 0x44, // z
  0x14, 0x14, 0x14,
0x14, 0x14, 0x14, // horiz lines
};
 
/* Standard ASCII 8×16 font */
const uint8_t ssd1306xled_font8x16 [] PROGMEM = {
 
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
// SP0
 
0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,
// ! 1
 
0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
// ” 2
 
0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,
// # 3
 
0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,
// $ 4
 
0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,
// % 5
 
0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,
// & 6
 
0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
// ‘ 7
 
0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,
// ( 8
 
0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,
// ) 9
 
0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,
// * 10
 
0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,
// + 11
 
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,
// , 12
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
// – 13
 
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,
// . 14
 
0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,
// / 15
 
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,
// 0 16
 
0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,
// 1 17
 
0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,
// 2 18
 
0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,
// 3 19
 
0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,
// 4 20
 
0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,
// 5 21
 
0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,
// 6 22
 
0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,
// 7 23
 
0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,
// 8 24
 
0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,
// 9 25
 
0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,
// : 26
 
0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,
// ; 27
 
0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,
// < 28
 
0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,
// = 29
 
0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,
// > 30
 
0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,
// ? 31
  0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,
// @ 32
 
0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,
// A 33
 
0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,
// B 34
 
0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,
// C 35
 
0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,
// D 36
 
0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,
// E 37
 
0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,
// F 38
 
0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,
// G 39
 
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,
// H 40
 
0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,
// I 41
 
0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,
// J 42
 
0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,
// K 43
 
0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,
// L 44
 
0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,
// M 45
  0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,
// N 46
 
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,
// O 47
 
0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,
// P 48
 
0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,
// Q 49
 
0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,
// R 50
 
0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,
// S 51
 
0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,
// T 52
 
0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,
// U 53
 
0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,
// V 54
 
0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,
// W 55
 
0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,
// X 56
 
0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,
// Y 57
 
0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,
// Z 58
 
0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,
// [ 59
 
0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,
// \ 60
 
0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,
// ] 61
  0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
// ^ 62
 
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
// _ 63
 
0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
// ` 64
 
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,
// a 65
 
0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,
// b 66
 
0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,
// c 67
 
0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,
// d 68
 
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,
// e 69
 
0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,
// f 70
 
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,
// g 71
 
0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,
// h 72
 
0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,
// i 73
 
0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,
// j 74
 
0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,
// k 75
 
0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,
// l 76
 
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,
// m 77
 
0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,
// n 78
 
0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,
// o 79
 
0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,
// p 80
 
0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,
// q 81
 
0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,
// r 82
 
0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,
// s 83
 
0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,
// t 84
 
0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,
// u 85
 
0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,
// v 86
 
0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,
// w 87
 
0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,
// x 88
 
0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,
// y 89
  0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,
// z 90
 
0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,
// { 91
 
0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,
// | 92
 
0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,
// } 93
 
0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
// ~ 94
};
 
const uint8_t menu [] PROGMEM = {
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0x81, 0xBD, 0xBD,
0xBD, 0xC3, 0xFF, 0xC3, 0xBD, 0xBD, 0xBD, 0xDB, 0xFF, 0xC3,
0xBD, 0xBD, 0xBD, 0xC3, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0xBD,
0xBD, 0xBD, 0xC3, 0xFF, 0xC3, 0xBD,
0xBD, 0xBD, 0xDB, 0xFF, 0x81, 0xF5, 0xF5, 0xF5, 0xFD, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x81, 0xB5, 0xB5, 0xBD, 0xFF, 0x81, 0xFB, 0xF7, 0xEF,
0x81, 0xFF, 0xF9, 0xE7, 0x9F, 0xE7,
0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x00, 0x7E,
0x0A, 0x0A, 0x02, 0x00, 0x3C, 0x42,
0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E,
0x42, 0x42, 0x42, 0x3C, 0x00, 0x7E,
0x4A, 0x4A, 0x34, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x00, 0x7E, 0x0A,
0x0A, 0x02, 0x00, 0x7E, 0x0A, 0x1A, 0x2A, 0x44, 0x00, 0x3C,
0x42, 0x52, 0x22, 0x5C, 0x00, 0x00,
0x00, 0x00, 0x7E, 0x04, 0x08, 0x04, 0x7E, 0x00, 0x3C, 0x42,
0x42, 0x42, 0x3C, 0x00, 0x7E, 0x42,
0x42, 0x3C, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x7C, 0x0A, 0x0A,
0x0A, 0x7C, 0x00, 0x02, 0x02, 0x7E,
0x02, 0x02, 0x00, 0x02, 0x02, 0x7E, 0x02, 0x02, 0x00, 0x00,
0x00, 0x7E, 0x42, 0x42, 0x42, 0x3C,
0x00, 0x3C, 0x42, 0x42, 0x42, 0x24, 0x00, 0x06, 0x08, 0x78,
0x08, 0x06, 0x00, 0x00, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0x00
};
 
const uint8_t dial0[] PROGMEM = {
0xE0, 0x18, 0x04, 0x02, 0x02, 0x01, 0x01, 0x81, 0x01, 0x01,
0x02, 0x02, 0x04, 0x18, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x28, 0x24, 0x42, 0x41, 0x40, 0x40, 0x40,
0x20, 0x20, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial1[] PROGMEM = {
0xE0, 0x18, 0x04, 0x02, 0x02, 0x01, 0x81, 0x81, 0x01, 0x01,
0x02, 0x02, 0x04, 0x18, 0xE0, 0x00,
0x03, 0x0E, 0x12, 0x22, 0x21, 0x41, 0x40, 0x40, 0x40, 0x40,
0x20, 0x20, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial2[] PROGMEM = {
0xE0, 0x98, 0x84, 0x82, 0x82, 0x81, 0x81, 0x81, 0x01, 0x01,
0x02, 0x02, 0x04, 0x18, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x40, 0x40,
0x20, 0x20, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial3[] PROGMEM = {
0xE0, 0x18, 0x14, 0x22, 0x22, 0x41, 0x41, 0x81, 0x01, 0x01,
0x02, 0x02, 0x04, 0x18, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x40, 0x40,
0x20, 0x20, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial4[] PROGMEM = {
0xE0, 0x18, 0x04, 0x02, 0x06, 0x19, 0x61, 0x81, 0x01, 0x01,
0x02, 0x02, 0x04, 0x18, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x40, 0x40,
0x20, 0x20, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial5[] PROGMEM = {
0xE0, 0x18, 0x04, 0x02, 0x02, 0x01, 0x01, 0xFF, 0x01, 0x01,
0x02, 0x02, 0x04, 0x18, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x40, 0x40,
0x20, 0x20, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial6[] PROGMEM = {
0xE0, 0x18, 0x04, 0x02, 0x02, 0x01, 0x01, 0x81, 0x61, 0x19,
0x06, 0x02, 0x04, 0x18, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x40, 0x40,
0x20, 0x20, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial7[] PROGMEM = {
0xE0, 0x18, 0x04, 0x02, 0x02, 0x01, 0x01, 0x81, 0x41, 0x41,
0x22, 0x22, 0x14, 0x18, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x40, 0x40,
0x20, 0x20, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial8[] PROGMEM = {
0xE0, 0x18, 0x04, 0x02, 0x02, 0x01, 0x01, 0x81, 0x81, 0x81,
0x82, 0x82, 0x84, 0x98, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x40, 0x40,
0x20, 0x20, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial9[] PROGMEM = {
0xE0, 0x18, 0x04, 0x02, 0x02, 0x01, 0x01, 0x81, 0x01, 0x01,
0x02, 0x02, 0x04, 0x18, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x41, 0x41,
0x22, 0x22, 0x14, 0x0C, 0x03, 0x00
};
 
const uint8_t dial10[] PROGMEM = {
0xE0, 0x18, 0x04, 0x02, 0x02, 0x01, 0x01, 0x81, 0x01, 0x01,
0x02, 0x02, 0x04, 0x18, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x41, 0x42,
0x24, 0x28, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial0i[] PROGMEM = {
0xE0, 0x18, 0x04, 0x02, 0x02, 0x01, 0xE1, 0x21, 0xE1, 0x01,
0x02, 0x02, 0x04, 0x18, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x28, 0x24, 0x40, 0x43, 0x42, 0x43, 0x40,
0x20, 0x20, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial1i[] PROGMEM = {
0xE0, 0x18, 0x04, 0x02, 0x02, 0x01, 0x21, 0xE1, 0x01, 0x01,
0x02, 0x02, 0x04, 0x18, 0xE0, 0x00,
0x03, 0x0E, 0x12, 0x22, 0x21, 0x40, 0x40, 0x43, 0x40, 0x40,
0x20, 0x20, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial2i[] PROGMEM = {
0xE0, 0x98, 0x84, 0x82, 0x82, 0x01, 0xA1, 0xA1, 0xE1, 0x01,
0x02, 0x02, 0x04, 0x18, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x20, 0x20, 0x40, 0x43, 0x42, 0x42, 0x40,
0x20, 0x20, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial3i[] PROGMEM = {
0xE0, 0x18, 0x14, 0x22, 0x22, 0x01, 0xA1, 0xA1, 0xE1, 0x01,
0x02, 0x02, 0x04, 0x18, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x20, 0x20, 0x40, 0x42, 0x42, 0x43, 0x40,
0x20, 0x20, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial4i[] PROGMEM = {
0xE0, 0x18, 0x04, 0x02, 0x06, 0x09, 0xE1, 0x81, 0xE1, 0x01,
0x02, 0x02, 0x04, 0x18, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x43, 0x40,
0x20, 0x20, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial5i[] PROGMEM = {
0xE0, 0x18, 0x04, 0x02, 0x02, 0x01, 0xE1, 0xAF, 0xA1, 0x01,
0x02, 0x02, 0x04, 0x18, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x20, 0x20, 0x40, 0x42, 0x42, 0x43, 0x40,
0x20, 0x20, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial6i[] PROGMEM = {
0xE0, 0x18, 0x04, 0x02, 0x02, 0x01, 0xE1, 0xA1, 0xA1, 0x09,
0x06, 0x02, 0x04, 0x18, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x20, 0x20, 0x40, 0x43, 0x42, 0x43, 0x40,
0x20, 0x20, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial7i[] PROGMEM = {
0xE0, 0x18, 0x04, 0x02, 0x02, 0x01, 0x21, 0xA1, 0x61, 0x01,
0x22, 0x22, 0x14, 0x18, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x20, 0x20, 0x40, 0x40, 0x43, 0x40, 0x40,
0x20, 0x20, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial8i[] PROGMEM = {
0xE0, 0x18, 0x04, 0x02, 0x02, 0x01, 0xE1, 0xA1, 0xE1, 0x01,
0x82, 0x82, 0x84, 0x98, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x20, 0x20, 0x40, 0x43, 0x42, 0x43, 0x40,
0x20, 0x20, 0x10, 0x0C, 0x03, 0x00
};
 
const uint8_t dial9i[] PROGMEM = {
0xE0, 0x18, 0x04, 0x02, 0x02, 0x01, 0xE1, 0xA1, 0xE1, 0x01,
0x02, 0x02, 0x04, 0x18, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x20, 0x20, 0x40, 0x42, 0x42, 0x43, 0x40,
0x22, 0x22, 0x14, 0x0C, 0x03, 0x00
};
 
const uint8_t dial10i[] PROGMEM = {
0xE0, 0x18, 0x04, 0x02, 0x02, 0xE1, 0x01, 0x01, 0xE1, 0x21,
0xE2, 0x02, 0x04, 0x18, 0xE0, 0x00,
0x03, 0x0C, 0x10, 0x20, 0x20, 0x43, 0x40, 0x40, 0x43, 0x42,
0x27, 0x28, 0x10, 0x0C, 0x03, 0x00
};
 
//1,0594630944
uint16_t
NOTES[12]={8192>>1,8679>>1,9195>>1,9742>>1,10321>>1,10935>>1,11585>>1,12274>>1,13004>>1,13777>>1,14596>>1,15464>>1};
 
const uint8_t ATTrates[16]={
1,2,3,4,5,8,12,20,32,37,43,51,64,85,128,255};
 
const uint8_t RELrates[16]={
1,2,3,4,5,8,12,20,32,37,43,51,64,85,128,255};
const uint8_t sinetable[256] PROGMEM = {
 
0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31,
 
33,35,37,39,42,44,46,49,51,54,56,59,62,64,67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124,
 
127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198,200,203,205,208,210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239,240,
 
242,243,244,245,247,248,249,249,250,251,252,252,253,253,253,254,254,254,254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,234,233,231,229,227,225,223,
  221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,176,173,170,167,164,161,158,155,152,149,146,143,139,136,133,130,127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,78,
 
76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0
};
uint16_t envtick=549;
 
uint8_t capsenseCOLbase = 8; //Set capacitive touch Column
sensitivity
uint8_t capsenseROWbase = 6; //Set capacitive touch Row
sensitivity
uint8_t currentkey = 0;
uint8_t key;
uint8_t oldkeydown;
uint16_t COARSEPITCH;
volatile uint8_t DOUBLE=0;
 
int16_t volume=0;
uint8_t ENVsmoothing;
uint8_t envcnt=10;
 
uint8_t GATEIO=0; //0=Gate is output, 1=Gate is input
 
//——– Synth parameters ————–
volatile uint8_t VCA=255;         //VCA level 0-255
volatile uint8_t ATTACK=1;        // ENV Attack rate 0-255
volatile uint8_t RELEASE=1;       // ENV Release rate 0-255
volatile uint8_t ENVELOPE=0;      // ENV Shape
volatile uint8_t TRIG=0;          //MIDItrig 1=note ON
volatile uint16_t PDmod;          //Resonant Peak index
volatile uint8_t ENVamt;          //Resonant Peak envelope modulation
amount
volatile uint8_t PHASEamt;        //Resonant Peak bias
uint8_t ATTACKRATE=0;
uint8_t RELEASERATE=0;
//—————————————–
 
uint8_t otone1;
uint8_t otone2;
uint16_t phacc;
uint16_t pdacc;
uint8_t otone12;
uint8_t otone22;
uint16_t phacc2;
uint16_t pdacc2;
 
uint16_t FREQ=0;        
//DCO pitch
 
int16_t DCO;
int16_t ENV;
 
uint8_t k=0;
uint8_t z;
int8_t MUX=0;
 
void ssd1306_init(void)
{
  DDRC |= (1 <<
SSD1306_SDA); // Set port as output
  DDRC |= (1 <<
SSD1306_SCL); // Set port as output
 
  //for (uint8_t i =
0; i < sizeof (ssd1306_init_sequence); i++) {
  // 
ssd1306_send_command(pgm_read_byte(&ssd1306_init_sequence[i]));
  //}
 
ssd1306_send_command(0b10101110);                    // DISPLAYOFF           0xAE
 
ssd1306_send_command(0b11010101);                    // SETDISPLAYCLOCKDIV   0xD5
 
ssd1306_send_command(0b10000000);                    // the suggested ratio  0x80
  ssd1306_send_command(0b10101000);                    // SETMULTIPLEX         0xA8
 
ssd1306_send_command(0b00011111);                    // 1/32 duty            0x1F
 
ssd1306_send_command(0b11010011);                    // SETDISPLAYOFFSET     0xD3
  ssd1306_send_command(0b00000000);                    // no offset            0x00
 
ssd1306_send_command(0b01000000 | 0b0);              // SETSTARTLINE | 0x0   0x40 | 0x0 
line #0
   
  // Send the Set
Charge Pump and Set Pre-Charge Period commands
  ssd1306_send_command(0b10001101);                    // CHARGEPUMP           0x8D
 
ssd1306_send_command(0b00010100);                    // external VCC = 0x10
internal VCC = 0x14
   
  // Send the commands
to invert the display. This puts the display origin in the upper left corner.
 
ssd1306_send_command(0b10100001);                    // SEGREMAP remap
columns       0xA1
 
ssd1306_send_command(0b11001000);                    // COMSCANDEC remap the
rows    0xC8
   
  // Send the commands
to select sequential COM configuration. This makes the display memory
non-interleaved.
 
ssd1306_send_command(0b11011010);                    // SETCOMPINS           0xDA
 
ssd1306_send_command(0b00000010);                    //                      0x02
  
  ssd1306_send_command(0b10000001);                    // SETCONTRAST          0x81
 
ssd1306_send_command(0b10001111);                    //                      0x8F
   
 
ssd1306_send_command(0b11011001);                    // SETPRECHARGE         0xD9
 
ssd1306_send_command(0b11110001);                    //                      0xF1
   
 
ssd1306_send_command(0b11011011);                    // SETVCOMDETECT        0xDB
 
ssd1306_send_command(0b01000000);                    //                      0x40
 
ssd1306_send_command(0b00100000);                    // MEMORYMODE           0x20
 
ssd1306_send_command(0b00000000);                    // 0x0 act like ks0108  0x00
  // Command is
SETPAGEADDRESS(min,max), i.e;: 0x22, 0, 3
 
ssd1306_send_command(0b00100010);                          //
SETPAGEADDRESS       0x22
 
ssd1306_send_command(0b00000000);                          // min                  0x00
 
ssd1306_send_command(0b00000011);                          // max                  0x03
  ssd1306_send_command(0b10100100);                    // DISPLAYALLON_RESUME  0xA4
 
ssd1306_send_command(0b10100110);                    // NORMALDISPLAY        0xA6
  // Send Display On
command
 
ssd1306_send_command(0b10101111);                    // DISPLAYON            0xAF
}
 
void ssd1306_xfer_start(void)
{
 
DIGITAL_WRITE_HIGH(SSD1306_SCL); 
// Set to HIGH
 
DIGITAL_WRITE_HIGH(SSD1306_SDA); 
// Set to HIGH
 
DIGITAL_WRITE_LOW(SSD1306_SDA);  
// Set to LOW
 
DIGITAL_WRITE_LOW(SSD1306_SCL);  
// Set to LOW
}
 
void ssd1306_xfer_stop(void)
{
 
DIGITAL_WRITE_LOW(SSD1306_SCL);  
// Set to LOW
 
DIGITAL_WRITE_LOW(SSD1306_SDA);  
// Set to LOW
 
DIGITAL_WRITE_HIGH(SSD1306_SCL); 
// Set to HIGH
 
DIGITAL_WRITE_HIGH(SSD1306_SDA); 
// Set to HIGH
}
 
void ssd1306_send_byte(uint8_t byte)
{
  uint8_t i;
  for (i = 0; i <
8; i++)
  {
    if ((byte <<
i) & 0x80)
     
DIGITAL_WRITE_HIGH(SSD1306_SDA);
    else
     
DIGITAL_WRITE_LOW(SSD1306_SDA);
   
   
DIGITAL_WRITE_HIGH(SSD1306_SCL);
    DIGITAL_WRITE_LOW(SSD1306_SCL);
  }
 
DIGITAL_WRITE_HIGH(SSD1306_SDA);
 
DIGITAL_WRITE_HIGH(SSD1306_SCL);
 
DIGITAL_WRITE_LOW(SSD1306_SCL);
}
 
void ssd1306_send_command_start(void) {
 
ssd1306_xfer_start();
 
ssd1306_send_byte(SSD1306_SA);  //
Slave address, SA0=0
  ssd1306_send_byte(0x00);  // write command
}
 
void ssd1306_send_command_stop(void) {
  ssd1306_xfer_stop();
}
 
void ssd1306_send_command(uint8_t command)
{
 
ssd1306_send_command_start();
 
ssd1306_send_byte(command);
 
ssd1306_send_command_stop();
}
 
void ssd1306_send_data_start(void)
{
 
ssd1306_xfer_start();
 
ssd1306_send_byte(SSD1306_SA);
 
ssd1306_send_byte(0x40);  //write
data
}
 
void ssd1306_send_data_stop(void)
{
  ssd1306_xfer_stop();
}
 
void ssd1306_setpos(uint8_t x, uint8_t y)
{
  ssd1306_send_command_start();
 
ssd1306_send_byte(0xb0 + y);
 
ssd1306_send_byte(((x & 0xf0) >> 4) | 0x10); // | 0x10
  ssd1306_send_byte((x
& 0x0f) | 0x01); // | 0x01
 
ssd1306_send_command_stop();
}
 
void ssd1306_fillscreen(uint8_t fill)
{
uint8_t m,n;
  for (m = 0; m <
4; m++)
  {
   
ssd1306_send_command(0xb0 + m); // page0 – page1
   
ssd1306_send_command(0x00);   //
low column start address
   
ssd1306_send_command(0x10);   //
high column start address
   
ssd1306_send_data_start();
    for (n = 0; n <
128; n++)
    {
     
ssd1306_send_byte(fill);
    }
   
ssd1306_send_data_stop();
  }
}
 
void ssd1306_char_font6x8(char ch) {
  uint8_t i;
  uint8_t c = ch – 32;
 
ssd1306_send_data_start();
  for (i= 0; i < 6;
i++)
  {
   
ssd1306_send_byte(pgm_read_byte(&ssd1306xled_font6x8[c * 6 + i]));
  }
 
ssd1306_send_data_stop();
}
 
void ssd1306_string_font6x8(char *s) {
  while (*s) {
   
ssd1306_char_font6x8(*s++);
  }
}
 
void ssd1306_char_f8x16(uint8_t x, uint8_t y, char *s)
{
  uint8_t c, j, i = 0;
  while (*s)
  {
    c = *s – 32;
    if (x > 120)
    {
      x = 0;
      y++;
    }
    ssd1306_setpos(x,
y);
   
ssd1306_send_data_start();
    for (i = 0; i <
8; i++)
    {
     
ssd1306_send_byte(pgm_read_byte(&ssd1306xled_font8x16[c * 16 + i]));
    }
   
ssd1306_send_data_stop();
    ssd1306_setpos(x,
y + 1);
   
ssd1306_send_data_start();
    for (i = 0; i <
8; i++)
    {
     
ssd1306_send_byte(pgm_read_byte(&ssd1306xled_font8x16[c * 16 + i +
8]));
    }
   
ssd1306_send_data_stop();
    x += 8;
    s++;
  }
}
 
void ssd1306_value_f8x16(uint8_t x, uint8_t y, uint8_t
value) {
    uint8_t c, i = 0;
    c = (value/10) +
16;
    value =
value-(value/10)*10;
    if (x > 120)
    {
      x = 0;
      y++;
    }
    ssd1306_setpos(x,
y);
    ssd1306_send_data_start();
    for (i = 0; i <
8; i++)
    {
     
ssd1306_send_byte(pgm_read_byte(&ssd1306xled_font8x16[c * 16 + i]));
    }
   
ssd1306_send_data_stop();
    ssd1306_setpos(x,
y + 1);
   
ssd1306_send_data_start();
    for (i = 0; i <
8; i++)
    {
      ssd1306_send_byte(pgm_read_byte(&ssd1306xled_font8x16[c
* 16 + i + 8]));
    }
   
ssd1306_send_data_stop();
    x += 8;
    c = value + 16;
    if (x > 120)
    {
      x = 0;
      y++;
    }
    ssd1306_setpos(x,
y);
   
ssd1306_send_data_start();
    for (i = 0; i <
8; i++)
    {
     
ssd1306_send_byte(pgm_read_byte(&ssd1306xled_font8x16[c * 16 + i]));
    }
   
ssd1306_send_data_stop();
    ssd1306_setpos(x,
y + 1);
   
ssd1306_send_data_start();
    for (i = 0; i <
8; i++)
    {
      ssd1306_send_byte(pgm_read_byte(&ssd1306xled_font8x16[c
* 16 + i + 8]));
    }
   
ssd1306_send_data_stop();
}
 
void ssd1306_draw_bmp(uint8_t x0, uint8_t y0, uint8_t x1,
uint8_t y1, const uint8_t bitmap[])
{
  uint16_t j = 0;
  uint8_t y, x;
  if (y1 % 8 == 0) y =
y1 / 8;
  else y = y1 / 8 + 1;
  for (y = y0; y <
y1; y++)
  {
   
ssd1306_setpos(x0,y);
   
ssd1306_send_data_start();
    for (x = x0; x
< x1; x++)
    {
     
ssd1306_send_byte(pgm_read_byte(&bitmap[j++]));
    }
    ssd1306_send_data_stop();
  }
}
 
void ssd1306_draw_menu() {
  uint16_t j = 0;
  uint8_t y=0, x=0;
  uint8_t x0=0;
  uint8_t x1=128;
  uint8_t y0=0;
  uint8_t y1=4;
  if (y1 % 8 == 0) y =
y1 / 8;
  else y = y1 / 8 + 1;
  for (y = y0; y <
y1; y++)
  {
    ssd1306_setpos(x0,y);
   
ssd1306_send_data_start();
    for (x = x0; x
< x1; x++)
    {
     
ssd1306_send_byte(pgm_read_byte(&menu[j++]));
    }
   
ssd1306_send_data_stop();
  }
}
 
void ssd1306_draw_dial(uint8_t x, uint8_t y, uint8_t value)
{
    uint8_t j;
   
ssd1306_setpos(x,y);
   
ssd1306_send_data_start();
    for (j = 0; j <
16; j++) {
      if (value<10)
ssd1306_send_byte(pgm_read_byte(&dial0[j]));
      if
((value>9)&&(value<20))
ssd1306_send_byte(pgm_read_byte(&dial1[j]));
      if
((value>19)&&(value<30))
ssd1306_send_byte(pgm_read_byte(&dial2[j]));
      if
((value>29)&&(value<40))
ssd1306_send_byte(pgm_read_byte(&dial3[j]));
      if
((value>39)&&(value<50))
ssd1306_send_byte(pgm_read_byte(&dial4[j]));
      if
((value>49)&&(value<60)) ssd1306_send_byte(pgm_read_byte(&dial5[j]));
      if
((value>59)&&(value<70))
ssd1306_send_byte(pgm_read_byte(&dial6[j]));
      if
((value>69)&&(value<80))
ssd1306_send_byte(pgm_read_byte(&dial7[j]));
      if
((value>79)&&(value<90)) ssd1306_send_byte(pgm_read_byte(&dial8[j]));
      if
((value>89)&&(value<99))
ssd1306_send_byte(pgm_read_byte(&dial9[j]));
      if (value>98)
ssd1306_send_byte(pgm_read_byte(&dial10[j]));
    }
   
ssd1306_send_data_stop();
   
ssd1306_setpos(x,y+1);
   
ssd1306_send_data_start();
    for (j = 0; j < 16; j++) {
      if (value<10)
ssd1306_send_byte(pgm_read_byte(&dial0[j+16]));
      if
((value>9)&&(value<20))
ssd1306_send_byte(pgm_read_byte(&dial1[j+16]));
      if
((value>19)&&(value<30))
ssd1306_send_byte(pgm_read_byte(&dial2[j+16]));
      if
((value>29)&&(value<40))
ssd1306_send_byte(pgm_read_byte(&dial3[j+16]));
      if
((value>39)&&(value<50))
ssd1306_send_byte(pgm_read_byte(&dial4[j+16]));
      if ((value>49)&&(value<60))
ssd1306_send_byte(pgm_read_byte(&dial5[j+16]));
      if
((value>59)&&(value<70))
ssd1306_send_byte(pgm_read_byte(&dial6[j+16]));
      if
((value>69)&&(value<80))
ssd1306_send_byte(pgm_read_byte(&dial7[j+16]));
      if
((value>79)&&(value<90))
ssd1306_send_byte(pgm_read_byte(&dial8[j+16]));
      if
((value>89)&&(value<98))
ssd1306_send_byte(pgm_read_byte(&dial9[j+16]));
      if (value==99)
ssd1306_send_byte(pgm_read_byte(&dial10[j+16]));
    }
   
ssd1306_send_data_stop();
}
 
void ssd1306_draw_dial_inverted(uint8_t x, uint8_t y,
uint8_t value) {
    uint8_t j;
   
ssd1306_setpos(x,y);
   
ssd1306_send_data_start();
    for (j = 0; j <
16; j++) {
      if (value<10)
ssd1306_send_byte(pgm_read_byte(&dial0i[j]));
      if
((value>9)&&(value<20))
ssd1306_send_byte(pgm_read_byte(&dial1i[j]));
      if
((value>19)&&(value<30))
ssd1306_send_byte(pgm_read_byte(&dial2i[j]));
      if
((value>29)&&(value<40))
ssd1306_send_byte(pgm_read_byte(&dial3i[j]));
      if
((value>39)&&(value<50)) ssd1306_send_byte(pgm_read_byte(&dial4i[j]));
      if
((value>49)&&(value<60))
ssd1306_send_byte(pgm_read_byte(&dial5i[j]));
      if
((value>59)&&(value<70))
ssd1306_send_byte(pgm_read_byte(&dial6i[j]));
      if
((value>69)&&(value<80)) ssd1306_send_byte(pgm_read_byte(&dial7i[j]));
      if
((value>79)&&(value<90))
ssd1306_send_byte(pgm_read_byte(&dial8i[j]));
      if
((value>89)&&(value<99))
ssd1306_send_byte(pgm_read_byte(&dial9i[j]));
      if (value>98)
ssd1306_send_byte(pgm_read_byte(&dial10i[j]));
    }
   
ssd1306_send_data_stop();
   
ssd1306_setpos(x,y+1);
   
ssd1306_send_data_start();
    for (j = 0; j <
16; j++) {
      if (value<10)
ssd1306_send_byte(pgm_read_byte(&dial0i[j+16]));
      if
((value>9)&&(value<20)) ssd1306_send_byte(pgm_read_byte(&dial1i[j+16]));
      if
((value>19)&&(value<30))
ssd1306_send_byte(pgm_read_byte(&dial2i[j+16]));
      if
((value>29)&&(value<40))
ssd1306_send_byte(pgm_read_byte(&dial3i[j+16]));
      if
((value>39)&&(value<50)) ssd1306_send_byte(pgm_read_byte(&dial4i[j+16]));
      if
((value>49)&&(value<60))
ssd1306_send_byte(pgm_read_byte(&dial5i[j+16]));
      if
((value>59)&&(value<70))
ssd1306_send_byte(pgm_read_byte(&dial6i[j+16]));
      if
((value>69)&&(value<80))
ssd1306_send_byte(pgm_read_byte(&dial7i[j+16]));
      if
((value>79)&&(value<90))
ssd1306_send_byte(pgm_read_byte(&dial8i[j+16]));
      if
((value>89)&&(value<98))
ssd1306_send_byte(pgm_read_byte(&dial9i[j+16]));
      if (value==99)
ssd1306_send_byte(pgm_read_byte(&dial10i[j+16]));
    }
    ssd1306_send_data_stop();
}
 
ISR(TIMER0_COMPA_vect) {
 
    //——————– DCO
block ——————————————
       
    phacc+=FREQ;
    if (phacc &
0x8000) {
      phacc &=
0x7FFF;
      otone1+=2;
      pdacc+=PDmod;
    }
    if (!otone1)
pdacc=0;
   
otone2=(pdacc>>3)&255;
    uint8_t
env=(255-otone1);
   
DCO=((pgm_read_byte(&sinetable[otone2])+pgm_read_byte(&sinetable[(otone2+(127-env))&255])));
 
   
phacc2+=FREQ+DOUBLE;
    if (phacc2 &
0x8000) {
      phacc2 &=
0x7FFF;
      otone12+=2;
      pdacc2+=PDmod;
    }
    if (!otone12)
pdacc2=0;
   
otone22=(pdacc2>>3)&255;
    env=(255-otone12);
   
DCO+=((pgm_read_byte(&sinetable[otone22])+pgm_read_byte(&sinetable[(otone22+(127-env))&255])));
 
   
//—————————————————————————
   
  
 
    //—————— VCA block
————————————
    if
((ATTACK==255)&&(TRIG==1)) VCA=255;
    if (!(envcnt–)) {
      envcnt=20;
     if
(VCA<volume) VCA++;
     if
(VCA>volume) VCA–;
    }
    #define M(MX, MX1,
MX2) \
      asm volatile ( \
        “clr r26
\n\t”\
        “mulsu %B1,
%A2 \n\t”\
        “movw %A0, r0
\n\t”\
        “mul %A1, %A2
\n\t”\
        “add %A0, r1
\n\t”\
        “adc %B0, r26
\n\t”\
        “clr r1 \n\t”\
        : \
        “=&r” (MX)
\
        : \
        “a” (MX1), \
        “a” (MX2) \
        : \
        “r26″\
      )
     
      DCO>>=1;
      M(ENV,
(int16_t)DCO, VCA);
     
      OCR2A =
ENV>>1;   
 
   
  
//—————————————————————–
 
 if (!(envtick–)) {
  envtick=582;
   //——————— ENV block
———————————
   
    if
((TRIG==1)&&(volume<255)) {
      volume+=ATTACK;
      if
(volume>255) volume=255;
    }
    if
((TRIG==0)&&(volume>0)) {
      volume-=RELEASE;
      if (volume<0)
volume=0;
    }
   
   
//—————————————————————–
 
    //——— Resonant
Peak ENV modulation —————————————-
 
   
PDmod=((volume*ENVamt)>>8)+PHASEamt;
    if (PDmod>255)
PDmod=255;
   
   
//—————————————————————–
 
  }
}
int8_t read_encoder() {
  static int8_t
enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
  static uint8_t
old_AB;
  old_AB <<=
2;                   //remember previous
state
  old_AB |= ( ENC_PORT
& 0x03 );  //add current state
  return (
enc_states[( old_AB & 0x0f )]);
}
 
void setup() {
 
    OSCCAL=255;
 
    //Test if Gate
should be input or output
    pinMode(13,
INPUT_PULLUP); //Gate output
    if
(!digitalRead(13)) { //If gate is low on startup
      pinMode(13,
INPUT); //Gate is input
      pinMode(9,
INPUT);  //CV is input
      GATEIO=1; //Use
Gate as input
    }
    else {
      pinMode(13, OUTPUT);
//Gate is output
      pinMode(9,
OUTPUT);  //CV is output
      GATEIO=0; //Use
Gate as output
    }
 
    pinMode(11,
OUTPUT); //Audio output
 
    pinMode(ENC_A,
INPUT);
   
digitalWrite(ENC_A, HIGH);
    pinMode(ENC_B,
INPUT);
    digitalWrite(ENC_B,
HIGH);
 
   
pinMode(12,INPUT_PULLUP);
   
oldbut=digitalRead(12);
   
    // Set up Timer 1
to do PWM for the CV 1v/oct output.
 
    cli();
  TCCR1A =
      (1 <<
COM1A1)  |
      // Fast PWM
mode.
      (1 <<
WGM11);
  TCCR1B =
      // Fast PWM
mode.
      (1 <<
WGM12) | (1 << WGM13) |
      // No clock
prescaling (fastest possible
      // freq).
      (1 <<
CS11);
  OCR1A = 0;
  TIMSK1=0;
  OCR1AH = 2; //CV PWM
  OCR1AL = 128;
 
  ICR1H = 5; //CV
Frequency
  ICR1L = 0;
 
    //set timer0
interrupt at 35481Hz
    TCCR0A = 0;// set
entire TCCR0A register to 0
    TCCR0B = 0;// same
for TCCR0B
    TCNT0  = 0;//initialize counter value to 0
    // set compare
match register for 35481Hz increments
    OCR0A = 56;// =
35481Hz
    // turn on CTC
mode
    TCCR0A |= (1
<< WGM01);
    // Set CS01 and
CS00 bits for prescaler 8
    TCCR0B |= (0
<< CS02) | (1 << CS01) | (0 << CS00);  //8 prescaler
    // enable timer
compare interrupt
    TIMSK0 |= (1
<< OCIE0A);
  
    sei();
 
    // Set up Timer 2
to do pulse width on Pin 11
 
    // Use internal
clock
    ASSR &=
~(_BV(EXCLK) | _BV(AS2));
 
    // Set fast PWM
mode
    TCCR2A |=
_BV(WGM21) | _BV(WGM20);
    TCCR2B &=
~_BV(WGM22);
 
   
    // Do
non-inverting PWM on pin OC2A.
    // On the Arduino this is pin 11.
    TCCR2A = (TCCR2A |
_BV(COM2A1)) & ~_BV(COM2A0);
    TCCR2A &=
~(_BV(COM2B1) | _BV(COM2B0));
    // No prescaler
(p.158)
    TCCR2B = (TCCR2B
& ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
 
    // Set initial
pulse width to the first sample.
    OCR2A = 128;
 
    // set up the ADC
    uint16_t
dummy=analogRead(2);
    ADCSRA &=
~PS_128;  // remove bits set by Arduino
library
 
    // you can choose
a prescaler from above.
    // PS_16, PS_32,
PS_64 or PS_128
    ADCSRA |=
PS_128;    // set our own prescaler to
128
 
    ADMUX = 64;
    sbi(ADCSRA, ADSC);
 
    COARSEPITCH=512;
    DOUBLE=0;
    PHASEamt=64;
    ENVamt=124;
   
ATTACK=ATTrates[15];
   
RELEASE=RELrates[3];
 
    _delay_ms(40);
    ssd1306_init();
   
ssd1306_fillscreen(0x00);
   
ssd1306_char_f8x16(0, 0, ” mini-TS OS 1.0″);
   
ssd1306_char_f8x16(0, 2, “DSP Synthesizers”);
    _delay_ms(1500);
   
ssd1306_fillscreen(0x00);
   
ssd1306_draw_menu();
   
   
ssd1306_draw_dial(5, 2, 0);
    ssd1306_draw_dial(26,
2, 10);
   
ssd1306_draw_dial(48, 2, 20);
   
ssd1306_draw_dial(68, 2, 30);
   
ssd1306_draw_dial(88, 2, 40);
   
ssd1306_draw_dial(109, 2, 50);
}
 
//—————- Get the base frequency for the MIDI note —————
uint16_t MIDI2FREQ(uint8_t note) {
  uint8_t key=note%12;
  if (note<36)
return (NOTES[key]>>(1+(35-note)/12));
  if (note>47)
return (NOTES[key]<<((note-36)/12));
  return NOTES[key];
}
//————————————————————————-
 
//———- Capacitive Touch sensing —————————–
 
uint8_t capsensePORTD(uint8_t mask) {
   if
((mask&1)||(mask&2)) return 0; //Dont measure our MIDI pins
   PORTD &= 0x03;
//Ground the PCB surface
   DDRD  |= 0xFC;
   asm(“nop”);
   cli();
   DDRD &=
~(mask); //Turn selected pin to input
   PORTD |= mask;   //With pullup
   uint8_t cycles = 0;
   if      (PIND & mask) { cycles =  0;}
   else if (PIND &
mask) { cycles =  1;}
   else if (PIND &
mask) { cycles =  2;}
   else if (PIND &
mask) { cycles =  3;}
   else if (PIND &
mask) { cycles =  4;}
   else if (PIND &
mask) { cycles =  5;}
   else if (PIND &
mask) { cycles =  6;}
   else if (PIND &
mask) { cycles =  7;}
   else if (PIND &
mask) { cycles =  8;}
   else if (PIND &
mask) { cycles =  9;}
   else if (PIND &
mask) { cycles = 10;}
   else if (PIND &
mask) { cycles = 11;}
   else if (PIND &
mask) { cycles = 12;}
   else if (PIND &
mask) { cycles = 13;}
   else if (PIND &
mask) { cycles = 14;}
   else if (PIND &
mask) { cycles = 15;}
   else if (PIND &
mask) { cycles = 16;}
   sei();
   DDRD  |= 0xFC;
   PORTD &= 0x03;
//Ground the PCB surface
   return cycles;
//Return measured cycles
}
 
uint8_t capsensePORTB(uint8_t mask) {
   if
((mask&2)||(mask&8)||(mask&16)||(mask&32)) return 0; //Dont
measure our Audio and CV pins
   PORTB &= 0x3A;
//Ground the PCB surface
   DDRB  |= 0xC5;
   asm(“nop”);
   cli();
   DDRB &=
~(mask); //Turn selected pin to input
   PORTB |= mask;   //With pullup
   uint8_t cycles = 0;
   if      (PINB & mask) { cycles =  0;}
   else if (PINB &
mask) { cycles =  1;}
   else if (PINB &
mask) { cycles =  2;}
   else if (PINB &
mask) { cycles =  3;}
   else if (PINB &
mask) { cycles =  4;}
   else if (PINB &
mask) { cycles =  5;}
   else if (PINB &
mask) { cycles =  6;}
   else if (PINB &
mask) { cycles =  7;}
   else if (PINB &
mask) { cycles =  8;}
   else if (PINB &
mask) { cycles =  9;}
   else if (PINB &
mask) { cycles = 10;}
   else if (PINB &
mask) { cycles = 11;}
   else if (PINB &
mask) { cycles = 12;}
   else if (PINB &
mask) { cycles = 13;}
   else if (PINB &
mask) { cycles = 14;}
   else if (PINB &
mask) { cycles = 15;}
   else if (PINB &
mask) { cycles = 16;}
   sei();
   DDRB  |= 0xC5;
   PORTB &= 0x3A;
//Ground the PCB surface
   return cycles;
//Return measured cycles
}
 
//—————————————————————–
 
void loop() { 
 
  //—————— Key scanner
—————————–
  uint8_t keydown=0;
  uint8_t keydownC=0;
  uint8_t keydownR=0;
  uint8_t keycol=0;
  uint8_t keyrow=0;
  for (uint8_t
column=0;column<5;column++) {
   if
((column==0)&&(capsensePORTD(4)>capsenseCOLbase)) {
      keycol=column;
      keydownC=1;
    }
    if
((column==1)&&(capsensePORTD(8)>capsenseCOLbase)) {
      keycol=column;
      keydownC=1;
    }
    if
((column==2)&&(capsensePORTD(16)>capsenseCOLbase)) {
      keycol=column;
      keydownC=1;
    }
    if
((column==3)&&(capsensePORTB(64)>capsenseCOLbase)) {
      keycol=column;
      keydownC=1;
    }
    if
((column==4)&&(capsensePORTB(128)>capsenseCOLbase)) {
      keycol=column;
      keydownC=1;
    } 
  }
  for (uint8_t
row=0;row<5;row++) {
   if
((row==0)&&(capsensePORTD(32)>capsenseROWbase)) {
      keyrow=row;
      keydownR=1;
    }
    if
((row==1)&&(capsensePORTD(64)>capsenseROWbase)) {
      keyrow=row;
      keydownR=1;
    }
    if
((row==2)&&(capsensePORTD(128)>capsenseROWbase)) {
      keyrow=row;
      keydownR=1;
    }
    if
((row==3)&&(capsensePORTB(1)>capsenseROWbase)) {
      keyrow=row;
      keydownR=1;
    }
    if
((row==4)&&(capsensePORTB(4)>capsenseROWbase)) {
      keyrow=row;
      keydownR=1;
    } 
  }
 
  if
((keydownC)&&(keydownR)) {
   
key=(keyrow*5)+keycol;
    keydown=1;
  }
 
  if (!GATEIO)
FREQ=MIDI2FREQ(key+24+(COARSEPITCH/21.3125));
  if (GATEIO)
FREQ=MIDI2FREQ(((digitalRead(9)&1)*12)+key+24+(COARSEPITCH/21.3125));
  uint16_t
CVout=COARSEPITCH+(key*21.33);
  OCR1AH = (CVout>>8);
  OCR1AL =
CVout&255;
  if (!GATEIO)
digitalWrite(13,keydown);
  if (GATEIO)
TRIG=digitalRead(13)&1;
  if (!GATEIO)
TRIG=keydown;
 
 
//—————————————————————
 
  //————— ADC block
————————————-
/*
      if (!(ADCSRA
& 64)) {
        if (MUX==0)
COARSEPITCH=(ADCL+(ADCH<<8));
        if (MUX==1)
DOUBLE=(ADCL+(ADCH<<8))>>2;
        if (MUX==2)
PHASEamt=(((ADCL+(ADCH<<8)))>>3);
        if (MUX==3)
ENVamt=((ADCL+(ADCH<<8))>>3);
        if (MUX==4)
ATTACK=ATTrates[15-((ADCL+(ADCH<<8))>>6)];
        if (MUX==5)
RELEASE=RELrates[15-((ADCL+(ADCH<<8))>>6)];
        MUX++;
        if (MUX>5)
MUX=0;
        ADMUX = 64 |
MUX; //Select MUX
        sbi(ADCSRA,
ADSC); //start next conversation
      }
*/
  
//——————————————————————–
 
  uint8_t
butt=digitalRead(12);
  if (butt!=oldbut) {
    oldbut=butt;
    if (!butt) {
      parmselect++;
      if
(parmselect==6) parmselect=0;
     
ssd1306_draw_dial(5, 2, 0);
     
ssd1306_draw_dial(26, 2, (DOUBLE>>1)*0.8);
     
ssd1306_draw_dial(48, 2, PHASEamt*0.8);
     
ssd1306_draw_dial(68, 2, ENVamt*0.8);
     
ssd1306_draw_dial(88, 2, ATTACKRATE*0.8);
     
ssd1306_draw_dial(109, 2, RELEASERATE*0.8);
      //if
(parmselect==0) test=LFOamt;
      if
(parmselect==1) test=DOUBLE>>1;
      if
(parmselect==2) test=PHASEamt;
      if
(parmselect==3) test=ENVamt;
      if
(parmselect==4) test=ATTACKRATE;
      if
(parmselect==5) test=RELEASERATE;
    }
  }
 
 test+=read_encoder();
 if (test>124)
test=124;
 if (test<0)
test=0;
 if (parmselect==0)
ssd1306_draw_dial_inverted(5, 2, test*0.8);
 if (parmselect==1)
ssd1306_draw_dial_inverted(26, 2, test*0.8);
 if (parmselect==2)
ssd1306_draw_dial_inverted(48, 2, test*0.8);
 if (parmselect==3)
ssd1306_draw_dial_inverted(68, 2, test*0.8);
 if (parmselect==4)
ssd1306_draw_dial_inverted(88, 2, test*0.8);
 if (parmselect==5)
ssd1306_draw_dial_inverted(109, 2, test*0.8);
 //if (parmselect==0)
LFOamt=test;
 if (parmselect==1)
DOUBLE=test<<1;
 if (parmselect==2)
PHASEamt=test;
 if (parmselect==3)
ENVamt=test;
 if (parmselect==4)
ATTACK=ATTrates[15-(test>>3)];
 if (parmselect==4)
ATTACKRATE=test;
 if (parmselect==5)
RELEASE=RELrates[15-(test>>3)];
 if (parmselect==5)
RELEASERATE=test;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment