kopia lustrzana https://github.com/threeme3/usdx
Added SSD1306 library.
rodzic
572de94c53
commit
27d3ce7b95
527
QCX-SSB.ino
527
QCX-SSB.ino
|
@ -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)
|
||||
|
||||
*/
|
||||
|
|
Ładowanie…
Reference in New Issue