Added SSD1306 library.

experimental
guido 2020-01-20 10:40:53 +01:00
rodzic 572de94c53
commit 27d3ce7b95
1 zmienionych plików z 510 dodań i 17 usunięć

Wyświetl plik

@ -81,6 +81,493 @@ public: // LCD1602 display in 4-bit mode, RS is pull-up and kept low when idle
void noDisplay(){ cmd(0x08); }
void createChar(uint8_t l, uint8_t glyph[]){ cmd(0x40 | ((l & 0x7) << 3)); for(int i = 0; i != 8; i++) write(glyph[i]); }
};
class I2C_ {
public:
#define _DELAY() for(uint8_t i = 0; i != 4; i++) asm("nop"); // 4=731kb/s
#define _I2C_SDA (1<<0) // (1 << 4) // PC4
#define _I2C_SCL (1<<1) // (1 << 5) // PC5
#define _I2C_INIT() _I2C_SDA_HI(); _I2C_SCL_HI(); DDRD |= (_I2C_SDA | _I2C_SCL);
#define _I2C_SDA_HI() PORTD |= _I2C_SDA; _DELAY();
#define _I2C_SDA_LO() PORTD &= ~_I2C_SDA; _DELAY();
#define _I2C_SCL_HI() PORTD |= _I2C_SCL; _DELAY();
#define _I2C_SCL_LO() PORTD &= ~_I2C_SCL; _DELAY();
#define _I2C_START() _I2C_SDA_LO(); _I2C_SCL_LO(); _I2C_SDA_HI();
#define _I2C_STOP() _I2C_SCL_HI(); _I2C_SDA_HI();
#define _I2C_SUSPEND() //_I2C_SDA_LO(); // SDA_LO to allow re-use as output port
#define _SendBit(data, bit) \
if(data & 1 << bit){ \
_I2C_SDA_HI(); \
} else { \
_I2C_SDA_LO(); \
} \
_I2C_SCL_HI(); \
_I2C_SCL_LO();
inline void start(){ _I2C_INIT(); _I2C_START(); };
inline void stop() { _I2C_STOP(); _I2C_SUSPEND(); };
inline void SendByte(uint8_t data){
_SendBit(data, 7);
_SendBit(data, 6);
_SendBit(data, 5);
_SendBit(data, 4);
_SendBit(data, 3);
_SendBit(data, 2);
_SendBit(data, 1);
_SendBit(data, 0);
_I2C_SDA_HI(); // recv ACK
_DELAY(); //
_I2C_SCL_HI();
_I2C_SCL_LO();
}
void SendRegister(uint8_t addr, uint8_t* data, uint8_t n){
start();
SendByte(addr << 1);
while(n--) SendByte(*data++);
stop();
}
//void SendRegister(uint8_t addr, uint8_t val){ SendRegister(addr, &val, 1); }
void begin(){};
void beginTransmission(uint8_t addr){ start(); SendByte(addr << 1); };
bool write(uint8_t byte){ SendByte(byte); return 1; };
uint8_t endTransmission(){ stop(); return 0; };
};
I2C_ Wire;
//#include <Wire.h>
/* // 6x8 technoblogy font
const uint8_t font[]PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x5F, 0x00, 0x00, 0x00,
0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00,
0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00,
0x23, 0x13, 0x08, 0x64, 0x62, 0x00,
0x36, 0x49, 0x56, 0x20, 0x50, 0x00,
0x00, 0x08, 0x07, 0x03, 0x00, 0x00,
0x00, 0x1C, 0x22, 0x41, 0x00, 0x00,
0x00, 0x41, 0x22, 0x1C, 0x00, 0x00,
0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00,
0x08, 0x08, 0x3E, 0x08, 0x08, 0x00,
0x00, 0x80, 0x70, 0x30, 0x00, 0x00,
0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
0x20, 0x10, 0x08, 0x04, 0x02, 0x00,
0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00,
0x00, 0x42, 0x7F, 0x40, 0x00, 0x00,
0x72, 0x49, 0x49, 0x49, 0x46, 0x00,
0x21, 0x41, 0x49, 0x4D, 0x33, 0x00,
0x18, 0x14, 0x12, 0x7F, 0x10, 0x00,
0x27, 0x45, 0x45, 0x45, 0x39, 0x00,
0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00,
0x41, 0x21, 0x11, 0x09, 0x07, 0x00,
0x36, 0x49, 0x49, 0x49, 0x36, 0x00,
0x46, 0x49, 0x49, 0x29, 0x1E, 0x00,
0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x00, 0x40, 0x34, 0x00, 0x00, 0x00,
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,
0x14, 0x14, 0x14, 0x14, 0x14, 0x00,
0x00, 0x41, 0x22, 0x14, 0x08, 0x00,
0x02, 0x01, 0x59, 0x09, 0x06, 0x00,
0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00,
0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00,
0x7F, 0x49, 0x49, 0x49, 0x36, 0x00,
0x3E, 0x41, 0x41, 0x41, 0x22, 0x00,
0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00,
0x7F, 0x49, 0x49, 0x49, 0x41, 0x00,
0x7F, 0x09, 0x09, 0x09, 0x01, 0x00,
0x3E, 0x41, 0x41, 0x51, 0x73, 0x00,
0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00,
0x00, 0x41, 0x7F, 0x41, 0x00, 0x00,
0x20, 0x40, 0x41, 0x3F, 0x01, 0x00,
0x7F, 0x08, 0x14, 0x22, 0x41, 0x00,
0x7F, 0x40, 0x40, 0x40, 0x40, 0x00,
0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00,
0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00,
0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00,
0x7F, 0x09, 0x09, 0x09, 0x06, 0x00,
0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00,
0x7F, 0x09, 0x19, 0x29, 0x46, 0x00,
0x26, 0x49, 0x49, 0x49, 0x32, 0x00,
0x03, 0x01, 0x7F, 0x01, 0x03, 0x00,
0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00,
0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00,
0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00,
0x63, 0x14, 0x08, 0x14, 0x63, 0x00,
0x03, 0x04, 0x78, 0x04, 0x03, 0x00,
0x61, 0x59, 0x49, 0x4D, 0x43, 0x00,
0x00, 0x7F, 0x41, 0x41, 0x41, 0x00,
0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
0x00, 0x41, 0x41, 0x41, 0x7F, 0x00,
0x04, 0x02, 0x01, 0x02, 0x04, 0x00,
0x40, 0x40, 0x40, 0x40, 0x40, 0x00,
0x00, 0x03, 0x07, 0x08, 0x00, 0x00,
0x20, 0x54, 0x54, 0x78, 0x40, 0x00,
0x7F, 0x28, 0x44, 0x44, 0x38, 0x00,
0x38, 0x44, 0x44, 0x44, 0x28, 0x00,
0x38, 0x44, 0x44, 0x28, 0x7F, 0x00,
0x38, 0x54, 0x54, 0x54, 0x18, 0x00,
0x00, 0x08, 0x7E, 0x09, 0x02, 0x00,
0x18, 0xA4, 0xA4, 0x9C, 0x78, 0x00,
0x7F, 0x08, 0x04, 0x04, 0x78, 0x00,
0x00, 0x44, 0x7D, 0x40, 0x00, 0x00,
0x20, 0x40, 0x40, 0x3D, 0x00, 0x00,
0x7F, 0x10, 0x28, 0x44, 0x00, 0x00,
0x00, 0x41, 0x7F, 0x40, 0x00, 0x00,
0x7C, 0x04, 0x78, 0x04, 0x78, 0x00,
0x7C, 0x08, 0x04, 0x04, 0x78, 0x00,
0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
0xFC, 0x18, 0x24, 0x24, 0x18, 0x00,
0x18, 0x24, 0x24, 0x18, 0xFC, 0x00,
0x7C, 0x08, 0x04, 0x04, 0x08, 0x00,
0x48, 0x54, 0x54, 0x54, 0x24, 0x00,
0x04, 0x04, 0x3F, 0x44, 0x24, 0x00,
0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00,
0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00,
0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00,
0x44, 0x28, 0x10, 0x28, 0x44, 0x00,
0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00,
0x44, 0x64, 0x54, 0x4C, 0x44, 0x00,
0x00, 0x08, 0x36, 0x41, 0x00, 0x00,
0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
0x00, 0x41, 0x36, 0x08, 0x00, 0x00,
0x02, 0x01, 0x02, 0x04, 0x02, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };
#define FONT_W 12//6
#define FONT_H 2
#define FONT_STRETCHV 1
#define FONT_STRETCHH 1//0
*/
// C64 real
const uint8_t font[]PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x4f, 0x4f, 0x00, 0x00, 0x00,
0x00, 0x07, 0x07, 0x00, 0x00, 0x07, 0x07, 0x00,
0x14, 0x7f, 0x7f, 0x14, 0x14, 0x7f, 0x7f, 0x14,
0x00, 0x24, 0x2e, 0x6b, 0x6b, 0x3a, 0x12, 0x00,
0x00, 0x63, 0x33, 0x18, 0x0c, 0x66, 0x63, 0x00,
0x00, 0x32, 0x7f, 0x4d, 0x4d, 0x77, 0x72, 0x50,
0x00, 0x00, 0x00, 0x04, 0x06, 0x03, 0x01, 0x00,
0x00, 0x00, 0x1c, 0x3e, 0x63, 0x41, 0x00, 0x00,
0x00, 0x00, 0x41, 0x63, 0x3e, 0x1c, 0x00, 0x00,
0x08, 0x2a, 0x3e, 0x1c, 0x1c, 0x3e, 0x2a, 0x08,
0x00, 0x08, 0x08, 0x3e, 0x3e, 0x08, 0x08, 0x00,
0x00, 0x00, 0x80, 0xe0, 0x60, 0x00, 0x00, 0x00,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00,
0x00, 0x40, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02,
0x00, 0x3e, 0x7f, 0x49, 0x45, 0x7f, 0x3e, 0x00,
0x00, 0x40, 0x44, 0x7f, 0x7f, 0x40, 0x40, 0x00,
0x00, 0x62, 0x73, 0x51, 0x49, 0x4f, 0x46, 0x00,
0x00, 0x22, 0x63, 0x49, 0x49, 0x7f, 0x36, 0x00,
0x00, 0x18, 0x18, 0x14, 0x16, 0x7f, 0x7f, 0x10,
0x00, 0x27, 0x67, 0x45, 0x45, 0x7d, 0x39, 0x00,
0x00, 0x3e, 0x7f, 0x49, 0x49, 0x7b, 0x32, 0x00,
0x00, 0x03, 0x03, 0x79, 0x7d, 0x07, 0x03, 0x00,
0x00, 0x36, 0x7f, 0x49, 0x49, 0x7f, 0x36, 0x00,
0x00, 0x26, 0x6f, 0x49, 0x49, 0x7f, 0x3e, 0x00,
0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0xe4, 0x64, 0x00, 0x00, 0x00,
0x00, 0x08, 0x1c, 0x36, 0x63, 0x41, 0x41, 0x00,
0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00,
0x00, 0x41, 0x41, 0x63, 0x36, 0x1c, 0x08, 0x00,
0x00, 0x02, 0x03, 0x51, 0x59, 0x0f, 0x06, 0x00,
0x00, 0x3e, 0x7f, 0x41, 0x4d, 0x4f, 0x2e, 0x00,
0x00, 0x7c, 0x7e, 0x0b, 0x0b, 0x7e, 0x7c, 0x00,
0x00, 0x7f, 0x7f, 0x49, 0x49, 0x7f, 0x36, 0x00,
0x00, 0x3e, 0x7f, 0x41, 0x41, 0x63, 0x22, 0x00,
0x00, 0x7f, 0x7f, 0x41, 0x63, 0x3e, 0x1c, 0x00,
0x00, 0x7f, 0x7f, 0x49, 0x49, 0x41, 0x41, 0x00,
0x00, 0x7f, 0x7f, 0x09, 0x09, 0x01, 0x01, 0x00,
0x00, 0x3e, 0x7f, 0x41, 0x49, 0x7b, 0x3a, 0x00,
0x00, 0x7f, 0x7f, 0x08, 0x08, 0x7f, 0x7f, 0x00,
0x00, 0x00, 0x41, 0x7f, 0x7f, 0x41, 0x00, 0x00,
0x00, 0x20, 0x60, 0x41, 0x7f, 0x3f, 0x01, 0x00,
0x00, 0x7f, 0x7f, 0x1c, 0x36, 0x63, 0x41, 0x00,
0x00, 0x7f, 0x7f, 0x40, 0x40, 0x40, 0x40, 0x00,
0x00, 0x7f, 0x7f, 0x06, 0x0c, 0x06, 0x7f, 0x7f,
0x00, 0x7f, 0x7f, 0x0e, 0x1c, 0x7f, 0x7f, 0x00,
0x00, 0x3e, 0x7f, 0x41, 0x41, 0x7f, 0x3e, 0x00,
0x00, 0x7f, 0x7f, 0x09, 0x09, 0x0f, 0x06, 0x00,
0x00, 0x1e, 0x3f, 0x21, 0x61, 0x7f, 0x5e, 0x00,
0x00, 0x7f, 0x7f, 0x19, 0x39, 0x6f, 0x46, 0x00,
0x00, 0x26, 0x6f, 0x49, 0x49, 0x7b, 0x32, 0x00,
0x00, 0x01, 0x01, 0x7f, 0x7f, 0x01, 0x01, 0x00,
0x00, 0x3f, 0x7f, 0x40, 0x40, 0x7f, 0x3f, 0x00,
0x00, 0x1f, 0x3f, 0x60, 0x60, 0x3f, 0x1f, 0x00,
0x00, 0x7f, 0x7f, 0x30, 0x18, 0x30, 0x7f, 0x7f,
0x00, 0x63, 0x77, 0x1c, 0x1c, 0x77, 0x63, 0x00,
0x00, 0x07, 0x0f, 0x78, 0x78, 0x0f, 0x07, 0x00,
0x00, 0x61, 0x71, 0x59, 0x4d, 0x47, 0x43, 0x00,
0x00, 0x00, 0x7f, 0x7f, 0x41, 0x41, 0x00, 0x00,
0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x40,
0x00, 0x00, 0x41, 0x41, 0x7f, 0x7f, 0x00, 0x00,
0x00, 0x08, 0x0c, 0xfe, 0xfe, 0x0c, 0x08, 0x00,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x00, 0x01, 0x03, 0x06, 0x04, 0x00, 0x00, 0x00,
0x00, 0x20, 0x74, 0x54, 0x54, 0x7c, 0x78, 0x00,
0x00, 0x7e, 0x7e, 0x48, 0x48, 0x78, 0x30, 0x00,
0x00, 0x38, 0x7c, 0x44, 0x44, 0x44, 0x00, 0x00,
0x00, 0x30, 0x78, 0x48, 0x48, 0x7e, 0x7e, 0x00,
0x00, 0x38, 0x7c, 0x54, 0x54, 0x5c, 0x18, 0x00,
0x00, 0x00, 0x08, 0x7c, 0x7e, 0x0a, 0x0a, 0x00,
0x00, 0x98, 0xbc, 0xa4, 0xa4, 0xfc, 0x7c, 0x00,
0x00, 0x7e, 0x7e, 0x08, 0x08, 0x78, 0x70, 0x00,
0x00, 0x00, 0x48, 0x7a, 0x7a, 0x40, 0x00, 0x00,
0x00, 0x00, 0x80, 0x80, 0x80, 0xfa, 0x7a, 0x00,
0x00, 0x7e, 0x7e, 0x10, 0x38, 0x68, 0x40, 0x00,
0x00, 0x00, 0x42, 0x7e, 0x7e, 0x40, 0x00, 0x00,
0x00, 0x7c, 0x7c, 0x18, 0x38, 0x1c, 0x7c, 0x78,
0x00, 0x7c, 0x7c, 0x04, 0x04, 0x7c, 0x78, 0x00,
0x00, 0x38, 0x7c, 0x44, 0x44, 0x7c, 0x38, 0x00,
0x00, 0xfc, 0xfc, 0x24, 0x24, 0x3c, 0x18, 0x00,
0x00, 0x18, 0x3c, 0x24, 0x24, 0xfc, 0xfc, 0x00,
0x00, 0x7c, 0x7c, 0x04, 0x04, 0x0c, 0x08, 0x00,
0x00, 0x48, 0x5c, 0x54, 0x54, 0x74, 0x24, 0x00,
0x00, 0x04, 0x04, 0x3e, 0x7e, 0x44, 0x44, 0x00,
0x00, 0x3c, 0x7c, 0x40, 0x40, 0x7c, 0x7c, 0x00,
0x00, 0x1c, 0x3c, 0x60, 0x60, 0x3c, 0x1c, 0x00,
0x00, 0x1c, 0x7c, 0x70, 0x38, 0x70, 0x7c, 0x1c,
0x00, 0x44, 0x6c, 0x38, 0x38, 0x6c, 0x44, 0x00,
0x00, 0x9c, 0xbc, 0xa0, 0xe0, 0x7c, 0x3c, 0x00,
0x00, 0x44, 0x64, 0x74, 0x5c, 0x4c, 0x44, 0x00,
0x00, 0x08, 0x3e, 0x77, 0x41, 0x41, 0x00, 0x00,
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
0x00, 0x00, 0x41, 0x41, 0x77, 0x3e, 0x08, 0x00,
0x00, 0x04, 0x02, 0x02, 0x04, 0x04, 0x02, 0x00
};
#define FONT_W 8
#define FONT_H 2
#define FONT_STRETCHV 1
#define FONT_STRETCHH 0
/* //16x8 C-64 kind of
const uint8_t font[]PROGMEM = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0x20
0x00,0x06,0x5F,0x5F,0x06,0x00,0x00,0x00, // 0x21
0x00,0x07,0x07,0x00,0x07,0x07,0x00,0x00, // 0x22
0x14,0x7F,0x7F,0x14,0x7F,0x7F,0x14,0x00, // 0x23
0x24,0x2E,0x6B,0x6B,0x3A,0x12,0x00,0x00, // 0x24
0x46,0x66,0x30,0x18,0x0C,0x66,0x62,0x00, // 0x25
0x30,0x7A,0x4F,0x5D,0x37,0x7A,0x48,0x00, // 0x26
0x04,0x07,0x03,0x00,0x00,0x00,0x00,0x00, // 0x27
0x00,0x1C,0x3E,0x63,0x41,0x00,0x00,0x00, // 0x28
0x00,0x41,0x63,0x3E,0x1C,0x00,0x00,0x00, // 0x29
0x08,0x2A,0x3E,0x1C,0x1C,0x3E,0x2A,0x08, // 0x2A
0x08,0x08,0x3E,0x3E,0x08,0x08,0x00,0x00, // 0x2B
0x00,0xA0,0xE0,0x60,0x00,0x00,0x00,0x00, // 0x2C
0x08,0x08,0x08,0x08,0x08,0x08,0x00,0x00, // 0x2D
0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x00, // 0x2E
0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00, // 0x2F
0x3E,0x7F,0x59,0x4D,0x7F,0x3E,0x00,0x00, // 0x30
0x42,0x42,0x7F,0x7F,0x40,0x40,0x00,0x00, // 0x31
0x62,0x73,0x59,0x49,0x6F,0x66,0x00,0x00, // 0x32
0x22,0x63,0x49,0x49,0x7F,0x36,0x00,0x00, // 0x33
0x18,0x1C,0x16,0x13,0x7F,0x7F,0x10,0x00, // 0x34
0x27,0x67,0x45,0x45,0x7D,0x39,0x00,0x00, // 0x35
0x3C,0x7E,0x4B,0x49,0x79,0x30,0x00,0x00, // 0x36
0x03,0x63,0x71,0x19,0x0F,0x07,0x00,0x00, // 0x37
0x36,0x7F,0x49,0x49,0x7F,0x36,0x00,0x00, // 0x38
0x06,0x4F,0x49,0x69,0x3F,0x1E,0x00,0x00, // 0x39
0x00,0x00,0x6C,0x6C,0x00,0x00,0x00,0x00, // 0x3A
0x00,0xA0,0xEC,0x6C,0x00,0x00,0x00,0x00, // 0x3B
0x08,0x1C,0x36,0x63,0x41,0x00,0x00,0x00, // 0x3C
0x14,0x14,0x14,0x14,0x14,0x14,0x00,0x00, // 0x3D
0x00,0x41,0x63,0x36,0x1C,0x08,0x00,0x00, // 0x3E
0x02,0x03,0x51,0x59,0x0F,0x06,0x00,0x00, // 0x3F
0x3E,0x7F,0x41,0x5D,0x5D,0x1F,0x1E,0x00, // 0x40
0x7C,0x7E,0x13,0x13,0x7E,0x7C,0x00,0x00, // 0x41
0x41,0x7F,0x7F,0x49,0x49,0x7F,0x36,0x00, // 0x42
0x1C,0x3E,0x63,0x41,0x41,0x63,0x22,0x00, // 0x43
0x41,0x7F,0x7F,0x41,0x63,0x7F,0x1C,0x00, // 0x44
0x41,0x7F,0x7F,0x49,0x5D,0x41,0x63,0x00, // 0x45
0x41,0x7F,0x7F,0x49,0x1D,0x01,0x03,0x00, // 0x46
0x1C,0x3E,0x63,0x41,0x51,0x73,0x72,0x00, // 0x47
0x7F,0x7F,0x08,0x08,0x7F,0x7F,0x00,0x00, // 0x48
0x00,0x41,0x7F,0x7F,0x41,0x00,0x00,0x00, // 0x49
0x30,0x70,0x40,0x41,0x7F,0x3F,0x01,0x00, // 0x4A
0x41,0x7F,0x7F,0x08,0x1C,0x77,0x63,0x00, // 0x4B
0x41,0x7F,0x7F,0x41,0x40,0x60,0x70,0x00, // 0x4C
0x7F,0x7F,0x06,0x0C,0x06,0x7F,0x7F,0x00, // 0x4D
0x7F,0x7F,0x06,0x0C,0x18,0x7F,0x7F,0x00, // 0x4E
0x1C,0x3E,0x63,0x41,0x63,0x3E,0x1C,0x00, // 0x4F
0x41,0x7F,0x7F,0x49,0x09,0x0F,0x06,0x00, // 0x50
0x1E,0x3F,0x21,0x71,0x7F,0x5E,0x00,0x00, // 0x51
0x41,0x7F,0x7F,0x19,0x39,0x6F,0x46,0x00, // 0x52
0x26,0x67,0x4D,0x59,0x7B,0x32,0x00,0x00, // 0x53
0x03,0x41,0x7F,0x7F,0x41,0x03,0x00,0x00, // 0x54
0x7F,0x7F,0x40,0x40,0x7F,0x7F,0x00,0x00, // 0x55
0x1F,0x3F,0x60,0x60,0x3F,0x1F,0x00,0x00, // 0x56
0x7F,0x7F,0x30,0x18,0x30,0x7F,0x7F,0x00, // 0x57
0x63,0x77,0x1C,0x08,0x1C,0x77,0x63,0x00, // 0x58
0x07,0x4F,0x78,0x78,0x4F,0x07,0x00,0x00, // 0x59
0x67,0x73,0x59,0x4D,0x47,0x63,0x71,0x00, // 0x5A
0x00,0x7F,0x7F,0x41,0x41,0x00,0x00,0x00, // 0x5B
0x01,0x03,0x06,0x0C,0x18,0x30,0x60,0x00, // 0x5C
0x00,0x41,0x41,0x7F,0x7F,0x00,0x00,0x00, // 0x5D
0x08,0x0C,0x06,0x03,0x06,0x0C,0x08,0x00, // 0x5E
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, // 0x5F
0x00,0x00,0x03,0x07,0x04,0x00,0x00,0x00, // 0x60
0x20,0x74,0x54,0x54,0x3C,0x78,0x40,0x00, // 0x61
0x41,0x3F,0x7F,0x44,0x44,0x7C,0x38,0x00, // 0x62
0x38,0x7C,0x44,0x44,0x6C,0x28,0x00,0x00, // 0x63
0x30,0x78,0x48,0x49,0x3F,0x7F,0x40,0x00, // 0x64
0x38,0x7C,0x54,0x54,0x5C,0x18,0x00,0x00, // 0x65
0x48,0x7E,0x7F,0x49,0x03,0x02,0x00,0x00, // 0x66
0x98,0xBC,0xA4,0xA4,0xF8,0x7C,0x04,0x00, // 0x67
0x41,0x7F,0x7F,0x08,0x04,0x7C,0x78,0x00, // 0x68
0x00,0x44,0x7D,0x7D,0x40,0x00,0x00,0x00, // 0x69
0x40,0xC4,0x84,0xFD,0x7D,0x00,0x00,0x00, // 0x6A
0x41,0x7F,0x7F,0x10,0x38,0x6C,0x44,0x00, // 0x6B
0x00,0x41,0x7F,0x7F,0x40,0x00,0x00,0x00, // 0x6C
0x7C,0x7C,0x0C,0x18,0x0C,0x7C,0x78,0x00, // 0x6D
0x7C,0x7C,0x04,0x04,0x7C,0x78,0x00,0x00, // 0x6E
0x38,0x7C,0x44,0x44,0x7C,0x38,0x00,0x00, // 0x6F
0x84,0xFC,0xF8,0xA4,0x24,0x3C,0x18,0x00, // 0x70
0x18,0x3C,0x24,0xA4,0xF8,0xFC,0x84,0x00, // 0x71
0x44,0x7C,0x78,0x44,0x1C,0x18,0x00,0x00, // 0x72
0x48,0x5C,0x54,0x54,0x74,0x24,0x00,0x00, // 0x73
0x00,0x04,0x3E,0x7F,0x44,0x24,0x00,0x00, // 0x74
0x3C,0x7C,0x40,0x40,0x3C,0x7C,0x40,0x00, // 0x75
0x1C,0x3C,0x60,0x60,0x3C,0x1C,0x00,0x00, // 0x76
0x3C,0x7C,0x60,0x30,0x60,0x7C,0x3C,0x00, // 0x77
0x44,0x6C,0x38,0x10,0x38,0x6C,0x44,0x00, // 0x78
0x9C,0xBC,0xA0,0xA0,0xFC,0x7C,0x00,0x00, // 0x79
0x4C,0x64,0x74,0x5C,0x4C,0x64,0x00,0x00, // 0x7A
0x08,0x08,0x3E,0x77,0x41,0x41,0x00,0x00, // 0x7B
0x00,0x00,0x00,0x77,0x77,0x00,0x00,0x00, // 0x7C
0x41,0x41,0x77,0x3E,0x08,0x08,0x00,0x00, // 0x7D
0x02,0x03,0x01,0x03,0x02,0x03,0x01,0x00, // 0x7E
0x78,0x7C,0x46,0x43,0x46,0x7C,0x78,0x00}; // 0x7F
#define FONT_W 8
#define FONT_H 2
#define FONT_STRETCHV 1
#define FONT_STRETCHH 0
*/
static const uint8_t ssd1306_init_sequence [] PROGMEM = { // Initialization Sequence
// 0xAE, // Display OFF (sleep mode)
0x20, 0b10, // Set Memory Addressing Mode
// 00=Horizontal Addressing Mode; 01=Vertical Addressing Mode;
// 10=Page Addressing Mode (RESET); 11=Invalid
// 0xB0, // Set Page Start Address for Page Addressing Mode, 0-7
0xC8, // Set COM Output Scan Direction. Flip Veritically.
// 0x00, // Set low nibble of column address
// 0x10, // Set high nibble of column address
0x40, // Set display start line address
0x81, /*32*/ 0x7F, // Set contrast control register
0xA1, // Set Segment Re-map. A0=column 0 mapped to SEG0; A1=column 127 mapped to SEG0. Flip Horizontally
0xA6, // Set display mode. A6=Normal; A7=Inverse
0xA8, 0x1F, // Set multiplex ratio(1 to 64)
0xA4, // Output RAM to Display
// 0xA4=Output follows RAM content; 0xA5,Output ignores RAM content
0xD3, 0x00, // Set display offset. 00 = no offset
0xD5, 0x80, // --set display clock divide ratio/oscillator frequency
0xD9, 0xF1, // 0xF1=brighter //0x22, // Set pre-charge period
0xDA, 0x02, // Set com pins hardware configuration
// 0xDB, 0x40, //0x20, // --set vcomh 0x20 = 0.77xVcc
0x8D, 0x14, // Set DC-DC enable
0xAF, // Display ON
};
class SSD1306Device: public Print {
public:
#define SSD1306_ADDR 0x3C // Slave address
#define SSD1306_PAGES 4
#define SSD1306_COMMAND 0x00
#define SSD1306_DATA 0x40
uint8_t oledX = 0, oledY = 0;
uint8_t renderingFrame = 0xB0;
bool wrap = false;
void begin(uint8_t cols, uint8_t rows, uint8_t charsize = 0){
Wire.begin();
Wire.beginTransmission(SSD1306_ADDR); Wire.write(SSD1306_COMMAND);
for (uint8_t i = 0; i < sizeof(ssd1306_init_sequence); i++) {
Wire.write(pgm_read_byte(&ssd1306_init_sequence[i]));
}
Wire.endTransmission();
delayMicroseconds(100);
}
void noCursor(){}
void cursor(){}
void noDisplay(){}
void createChar(uint8_t l, uint8_t glyph[]){}
void _setCursor(uint8_t x, uint8_t y) { oledX = x; oledY = y;
Wire.beginTransmission(SSD1306_ADDR); Wire.write(SSD1306_COMMAND);
Wire.write(renderingFrame | (oledY & 0x07));
Wire.write(0x10 | ((oledX & 0xf0) >> 4));
Wire.write(oledX & 0x0f);
Wire.endTransmission();
}
void setCursor(uint8_t x, uint8_t y) { _setCursor(x * FONT_W, y * FONT_H); }
void newLine() {
oledY+=FONT_H;
if (oledY > SSD1306_PAGES - FONT_H) {
oledY = SSD1306_PAGES - FONT_H;
}
setCursor(0, oledY);
}
size_t write(byte c) {
if((c == '\n') || (oledX > ((uint8_t)128 - FONT_W))) {
if(wrap) newLine();
return 1;
}
uint16_t offset = ((uint16_t)c - ' ') * FONT_W/(FONT_STRETCHH+1) * FONT_H;
uint8_t line = FONT_H;
do
{
if(FONT_STRETCHV) offset = ((uint16_t)c - ' ') * FONT_W/(FONT_STRETCHH+1) * FONT_H/(2*FONT_STRETCHV);
Wire.beginTransmission(SSD1306_ADDR); Wire.write(SSD1306_DATA);
for (uint8_t i = 0; i < (FONT_W/(FONT_STRETCHH+1)); i++) {
uint8_t b = pgm_read_byte(&(font[offset++]));
if(FONT_STRETCHV){
uint8_t b2 = 0;
if(line > 1) for(int i = 0; i!=4; i++) b2 |=/* ! */(b & (1<<i)) ? (1<<(i*2)) | (1<<(i*2)+1): 0x00;
else for(int i = 0; i!=4; i++) b2 |=/* ! */(b & (1<<(i+4))) ? (1<<(i*2)) | (1<<(i*2)+1): 0x00;
Wire.write(b2);
if(FONT_STRETCHH) Wire.write(b2);
} else { Wire.write(b); if(FONT_STRETCHH) Wire.write(b); }
}
Wire.endTransmission();
if (FONT_H == 1) {
oledX+=FONT_W;
}
else {
if (line > 1) {
_setCursor(oledX, oledY + 1);
}
else {
_setCursor(oledX + FONT_W, oledY - (FONT_H - 1));
}
}
}
while (--line);
return 1;
}
void bitmap(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, const uint8_t bitmap[]) {
uint16_t j = 0;
for (uint8_t y = y0; y < y1; y++) {
_setCursor(x0, y);
Wire.beginTransmission(SSD1306_ADDR); Wire.write(SSD1306_DATA);
for (uint8_t x = x0; x < x1; x++) {
Wire.write(pgm_read_byte(&bitmap[j++]));
}
Wire.endTransmission();
}
setCursor(0, 0);
}
};
//SSD1306Device lcd;
LCD lcd;
//#include <LiquidCrystal.h>
//LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
@ -269,15 +756,15 @@ public:
inline void FAST freq_calc_fast(int16_t df) // note: relies on cached variables: _msb128, _msa128min512, _div, _fout, fxtal
{
#define _MSC 0x80000 //0x80000: 98% CPU load 0xFFFFF: 114% CPU load
uint32_t msb128 = _msb128 + ((int64_t)(_div * (int32_t)df) * _MSC * 128) / fxtal;
//#define _MSC 0x80000 //0x80000: 98% CPU load 0xFFFFF: 114% CPU load
//uint32_t msb128 = _msb128 + ((int64_t)(_div * (int32_t)df) * _MSC * 128) / fxtal;
//#define _MSC 0xFFFFF // Old algorithm 114% CPU load
//#define _MSC 0xFFFFF // Old algorithm 114% CPU load, shortcut for a fixed fxtal=27e6
//register uint32_t xmsb = (_div * (_fout + (int32_t)df)) % fxtal; // xmsb = msb * fxtal/(128 * _MSC);
//uint32_t msb128 = xmsb * 5*(32/32) - (xmsb/32); // msb128 = xmsb * 159/32, where 159/32 = 128 * 0xFFFFF / fxtal; fxtal=27e6
//#define _MSC (27004800/128) // 114% CPU load perfect alignment
//uint32_t msb128 = (_div * (_fout + (int32_t)df)) % fxtal;
#define _MSC (27004800/128) // 114% CPU load perfect alignment
uint32_t msb128 = (_div * (_fout + (int32_t)df)) % fxtal;
uint32_t msp1 = _msa128min512 + msb128 / _MSC; // = 128 * _msa + msb128 / _MSC - 512;
uint32_t msp2 = msb128 % _MSC; // = msb128 - msb128/_MSC * _MSC;
@ -708,9 +1195,9 @@ volatile int8_t volume = 8;
void dsp_tx()
{ // jitter dependent things first
ADCSRA |= (1 << ADSC); // start next ADC conversion (trigger ADC interrupt if ADIE flag is set)
OCR1BL = amp; // submit amplitude to PWM register (actually this is done in advance (about 140us) of phase-change, so that phase-delays in key-shaping circuit filter can settle)
//OCR1BL = amp; // submit amplitude to PWM register (actually this is done in advance (about 140us) of phase-change, so that phase-delays in key-shaping circuit filter can settle)
si5351.SendPLLBRegisterBulk(); // submit frequency registers to SI5351 over 731kbit/s I2C (transfer takes 64/731 = 88us, then PLL-loopfilter probably needs 50us to stabalize)
//OCR1BL = amp; // submit amplitude to PWM register (takes about 1/32125 = 31us+/-31us to propagate) -> amplitude-phase-alignment error is about 30-50us
OCR1BL = amp; // submit amplitude to PWM register (takes about 1/32125 = 31us+/-31us to propagate) -> amplitude-phase-alignment error is about 30-50us
int16_t adc = ADC - 512; // current ADC sample 10-bits analog input, NOTE: first ADCL, then ADCH
int16_t df = ssb(adc >> MIC_ATTEN); // convert analog input into phase-shifts (carrier out by periodic frequency shifts)
si5351.freq_calc_fast(df); // calculate SI5351 registers based on frequency shift and carrier frequency
@ -1001,10 +1488,8 @@ inline int16_t slow_dsp(int16_t ac)
if(agc) ac = process_agc(ac);
ac = ac >> (16-volume);
if(nr) ac = process_nr(ac);
if(filt) ac = filt_var(ac);
if(mode == CW){
if(filt) ac = ac << 2;
if(filt) ac = filt_var(ac) << 2;
if(mode == CW){
if(cwdec){ // CW decoder enabled?
char ch = cw(ac >> 0);
if(ch){
@ -1386,7 +1871,7 @@ char blanks[] = " ";
#define lcd_blanks() lcd.print(blanks);
#define N_FONTS 8
const byte font[N_FONTS][8] PROGMEM = {
const byte fonts[N_FONTS][8] PROGMEM = {
{ 0b01000, // 1; logo
0b00100,
0b01010,
@ -1873,8 +2358,8 @@ void setup()
lcd.begin(16, 2); // Init LCD
for(i = 0; i != N_FONTS; i++){ // Init fonts
pgm_cache_item(font[i], 8);
lcd.createChar(0x01 + i, /*font[i]*/_item);
pgm_cache_item(fonts[i], 8);
lcd.createChar(0x01 + i, /*fonts[i]*/_item);
}
// Test if QCX has DSP/SDR capability: SIDETONE output disconnected from AUDIO2
@ -2107,8 +2592,8 @@ void loop()
for(; digitalRead(BUTTONS);){ // until released, or encoder is turned while longpress
if(encoder_val && event == PL){ event = PT; break; }
wdt_reset();
}
event |= (v < 862) ? BL : (v < 1023) ? BR : BE; // determine which button pressed based on threshold levels
} // Max. voltages at ADC3 for buttons L,R,E: 3.76V;4.55V;5V, thresholds are in center
event |= (v < (4.2 * 1024.0 / 5.0)) ? BL : (v < (4.8 * 1024.0 / 5.0)) ? BR : BE; // determine which button pressed based on threshold levels
} else { // hack: fast forward handling
event = (event&0xf0) | ((encoder_val) ? PT : PL); // only alternate bewteen push-long/turn when applicable
}
@ -2390,13 +2875,21 @@ faster RX-TX switch to support CW
clock
qcx API demo code
scan
si5351 simplification aka https://groups.io/g/BITX20/files/KE7ER/si5351bx_0_0.ino
unwanted VOX feedback in DSP mode
move last bit of arrays into flash? https://www.microchip.com/webdoc/AVRLibcReferenceManual/FAQ_1faq_rom_array.html
remove floats
Multiple ADC conversion and avg in TX path
u-law in RX path: http://dystopiancode.blogspot.com/2012/02/pcm-law-and-u-law-companding-algorithms.html
Arduino library?
1. RX bias offset correction by measurement avg, 2. charge decoupling cap. by resetting to 0V and setting 5V for a certain amount of (charge) time
Analyse assembly:
/home/guido/Downloads/arduino-1.8.10/hardware/tools/avr/bin/avr-g++ -S -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10810 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/guido/Downloads/arduino-1.8.10/hardware/arduino/avr/cores/arduino -I/home/guido/Downloads/arduino-1.8.10/hardware/arduino/avr/variants/standard /tmp/arduino_build_483134/sketch/QCX-SSB.ino.cpp -o /tmp/arduino_build_483134/sketch/QCX-SSB.ino.cpp.txt
Rewire/code I/Q clk pins so that a Div/1 and Div/2 scheme is used instead of 0 and 90 degrees phase shift
10,11,13,12 10,11,12,13 (pin)
Q- I+ Q+ I- Q- I+ Q+ I-
90 deg.shift div/2@S1(pin2)
*/