initial
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "adc.h"
|
||||
|
||||
adcSim::adcSim()
|
||||
{
|
||||
ADCSRA.setCallback(DELEGATE(registerDelegate, adcSim, *this, ADC_ADCSRA_callback));
|
||||
for(unsigned int n=0;n<16;n++)
|
||||
adcValue[n] = 0;
|
||||
}
|
||||
|
||||
adcSim::~adcSim()
|
||||
{
|
||||
}
|
||||
|
||||
void adcSim::ADC_ADCSRA_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
if ((newValue & _BV(ADEN)) && (newValue & _BV(ADSC)))
|
||||
{ //Start ADC conversion
|
||||
int idx = ADMUX & (_BV(MUX4)|_BV(MUX3)|_BV(MUX2)|_BV(MUX1)|_BV(MUX0));
|
||||
if (ADCSRB & _BV(MUX5))
|
||||
idx += 8;
|
||||
|
||||
ADC = adcValue[idx];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef ADC_SIM_H
|
||||
#define ADC_SIM_H
|
||||
|
||||
#include "base.h"
|
||||
|
||||
class adcSim : public simBaseComponent
|
||||
{
|
||||
public:
|
||||
adcSim();
|
||||
virtual ~adcSim();
|
||||
|
||||
int adcValue[16];
|
||||
|
||||
private:
|
||||
void ADC_ADCSRA_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
};
|
||||
|
||||
#endif//I2C_SIM_H
|
||||
@@ -0,0 +1,141 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "arduinoIO.h"
|
||||
|
||||
#define PA 1
|
||||
#define PB 2
|
||||
#define PC 3
|
||||
#define PD 4
|
||||
#define PE 5
|
||||
#define PF 6
|
||||
#define PG 7
|
||||
#define PH 8
|
||||
#define PJ 10
|
||||
#define PK 11
|
||||
#define PL 12
|
||||
|
||||
arduinoIOSim::arduinoIOSim()
|
||||
{
|
||||
PORTA.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTA_callback));
|
||||
PORTB.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTB_callback));
|
||||
PORTC.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTC_callback));
|
||||
PORTD.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTD_callback));
|
||||
PORTE.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTE_callback));
|
||||
PORTF.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTF_callback));
|
||||
PORTG.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTG_callback));
|
||||
PORTH.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTH_callback));
|
||||
PORTJ.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTJ_callback));
|
||||
PORTK.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTK_callback));
|
||||
PORTL.setCallback(DELEGATE(registerDelegate, arduinoIOSim, *this, IO_PORTL_callback));
|
||||
|
||||
for(unsigned int n=0; n<11*8; n++)
|
||||
portIdxToPinNr[n] = -1;
|
||||
for(unsigned int n=0; n<NUM_DIGITAL_PINS; n++)
|
||||
{
|
||||
if (digital_pin_to_port_PGM[n] == NOT_A_PORT)
|
||||
continue;
|
||||
int idx = digital_pin_to_port_PGM[n] * 8;
|
||||
int mask = digital_pin_to_bit_mask_PGM[n];
|
||||
for(unsigned int i=0;i<8;i++)
|
||||
if (mask == _BV(i)) idx += i;
|
||||
portIdxToPinNr[idx] = n;
|
||||
}
|
||||
}
|
||||
arduinoIOSim::~arduinoIOSim()
|
||||
{
|
||||
}
|
||||
|
||||
void arduinoIOSim::registerPortCallback(int portNr, ioDelegate func)
|
||||
{
|
||||
if (portNr < 0 || portNr >= NUM_DIGITAL_PINS)
|
||||
return;
|
||||
ioWriteDelegate[portNr] = func;
|
||||
}
|
||||
|
||||
void arduinoIOSim::checkPinChange(int portID, uint8_t oldValue, uint8_t newValue)
|
||||
{
|
||||
uint8_t change = oldValue ^ newValue;
|
||||
if (change)
|
||||
{
|
||||
for(unsigned int i=0;i<8;i++)
|
||||
{
|
||||
if (change & _BV(i))
|
||||
{
|
||||
int pinNr = portIdxToPinNr[portID * 8 + i];
|
||||
if (pinNr >= 0)
|
||||
ioWriteDelegate[pinNr](pinNr, newValue & _BV(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void arduinoIOSim::IO_PORTA_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PA, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTB_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PB, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTC_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PC, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTD_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PD, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTE_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PE, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTF_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PF, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTG_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PG, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTH_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PH, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTJ_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PJ, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTK_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PK, oldValue, newValue);
|
||||
}
|
||||
void arduinoIOSim::IO_PORTL_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
checkPinChange(PL, oldValue, newValue);
|
||||
}
|
||||
|
||||
bool readOutput(int arduinoPinNr)
|
||||
{
|
||||
uint8_t bit = digitalPinToBitMask(arduinoPinNr);
|
||||
uint8_t port = digitalPinToPort(arduinoPinNr);
|
||||
|
||||
if (port == NOT_A_PORT) return false;
|
||||
|
||||
AVRRegistor* out = portOutputRegister(port);
|
||||
|
||||
return (*out) & bit;
|
||||
}
|
||||
|
||||
void writeInput(int arduinoPinNr, bool value)
|
||||
{
|
||||
uint8_t bit = digitalPinToBitMask(arduinoPinNr);
|
||||
uint8_t port = digitalPinToPort(arduinoPinNr);
|
||||
|
||||
if (port == NOT_A_PIN) return;
|
||||
|
||||
AVRRegistor* in = portInputRegister(port);
|
||||
if (value)
|
||||
(*in) |= bit;
|
||||
else
|
||||
(*in) &=~bit;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef ARDUINO_IO_SIM_H
|
||||
#define ARDUINO_IO_SIM_H
|
||||
|
||||
#include "base.h"
|
||||
#include "delegate.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
typedef delegate<int, bool> ioDelegate;
|
||||
|
||||
class arduinoIOSim : public simBaseComponent
|
||||
{
|
||||
public:
|
||||
arduinoIOSim();
|
||||
virtual ~arduinoIOSim();
|
||||
|
||||
void registerPortCallback(int portNr, ioDelegate func);
|
||||
private:
|
||||
int portIdxToPinNr[13*8];
|
||||
ioDelegate ioWriteDelegate[NUM_DIGITAL_PINS];
|
||||
|
||||
void IO_PORTA_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTB_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTC_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTD_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTE_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTF_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTG_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTH_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTJ_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTK_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void IO_PORTL_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
|
||||
void checkPinChange(int portID, uint8_t oldValue, uint8_t newValue);
|
||||
};
|
||||
|
||||
bool readOutput(int arduinoPinNr);
|
||||
void writeInput(int arduinoPinNr, bool value);
|
||||
|
||||
#endif//ARDUINO_IO_SIM_H
|
||||
@@ -0,0 +1,209 @@
|
||||
#include <SDL/SDL.h>
|
||||
#include "base.h"
|
||||
|
||||
#define DRAW_SCALE 3
|
||||
|
||||
extern SDL_Surface *screen;
|
||||
std::vector<simBaseComponent*> simComponentList;
|
||||
|
||||
static const uint8_t lcd_font[] = {
|
||||
// font data
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x00'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x01'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x02'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x03'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x04'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x05'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x06'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x07'
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x08'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x09'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x0A'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x0B'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x0C'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x0D'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x0E'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x0F'
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x10'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x11'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x12'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x13'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x14'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x15'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x16'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x17'
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x18'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x19'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x1A'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x1B'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x1C'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x1D'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x1E'
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// '\x1F'
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,// (space)
|
||||
0x00, 0x00, 0x5F, 0x00, 0x00,// !
|
||||
0x00, 0x07, 0x00, 0x07, 0x00,// "
|
||||
0x14, 0x7F, 0x14, 0x7F, 0x14,// #
|
||||
0x24, 0x2A, 0x7F, 0x2A, 0x12,// $
|
||||
0x23, 0x13, 0x08, 0x64, 0x62,// %
|
||||
0x36, 0x49, 0x55, 0x22, 0x50,// &
|
||||
0x00, 0x05, 0x03, 0x00, 0x00,// '
|
||||
0x00, 0x1C, 0x22, 0x41, 0x00,// (
|
||||
0x00, 0x41, 0x22, 0x1C, 0x00,// )
|
||||
0x08, 0x2A, 0x1C, 0x2A, 0x08,// *
|
||||
0x08, 0x08, 0x3E, 0x08, 0x08,// +
|
||||
0x00, 0x50, 0x30, 0x00, 0x00,// ,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08,// -
|
||||
0x00, 0x60, 0x60, 0x00, 0x00,// .
|
||||
0x20, 0x10, 0x08, 0x04, 0x02,// /
|
||||
0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
|
||||
0x00, 0x42, 0x7F, 0x40, 0x00,// 1
|
||||
0x42, 0x61, 0x51, 0x49, 0x46,// 2
|
||||
0x21, 0x41, 0x45, 0x4B, 0x31,// 3
|
||||
0x18, 0x14, 0x12, 0x7F, 0x10,// 4
|
||||
0x27, 0x45, 0x45, 0x45, 0x39,// 5
|
||||
0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
|
||||
0x01, 0x71, 0x09, 0x05, 0x03,// 7
|
||||
0x36, 0x49, 0x49, 0x49, 0x36,// 8
|
||||
0x06, 0x49, 0x49, 0x29, 0x1E,// 9
|
||||
0x00, 0x36, 0x36, 0x00, 0x00,// :
|
||||
0x00, 0x56, 0x36, 0x00, 0x00,// ;
|
||||
0x00, 0x08, 0x14, 0x22, 0x41,// <
|
||||
0x14, 0x14, 0x14, 0x14, 0x14,// =
|
||||
0x41, 0x22, 0x14, 0x08, 0x00,// >
|
||||
0x02, 0x01, 0x51, 0x09, 0x06,// ?
|
||||
0x32, 0x49, 0x79, 0x41, 0x3E,// @
|
||||
0x7E, 0x11, 0x11, 0x11, 0x7E,// A
|
||||
0x7F, 0x49, 0x49, 0x49, 0x36,// B
|
||||
0x3E, 0x41, 0x41, 0x41, 0x22,// C
|
||||
0x7F, 0x41, 0x41, 0x22, 0x1C,// D
|
||||
0x7F, 0x49, 0x49, 0x49, 0x41,// E
|
||||
0x7F, 0x09, 0x09, 0x01, 0x01,// F
|
||||
0x3E, 0x41, 0x41, 0x51, 0x32,// G
|
||||
0x7F, 0x08, 0x08, 0x08, 0x7F,// H
|
||||
0x00, 0x41, 0x7F, 0x41, 0x00,// I
|
||||
0x20, 0x40, 0x41, 0x3F, 0x01,// J
|
||||
0x7F, 0x08, 0x14, 0x22, 0x41,// K
|
||||
0x7F, 0x40, 0x40, 0x40, 0x40,// L
|
||||
0x7F, 0x02, 0x04, 0x02, 0x7F,// M
|
||||
0x7F, 0x04, 0x08, 0x10, 0x7F,// N
|
||||
0x3E, 0x41, 0x41, 0x41, 0x3E,// O
|
||||
0x7F, 0x09, 0x09, 0x09, 0x06,// P
|
||||
0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
|
||||
0x7F, 0x09, 0x19, 0x29, 0x46,// R
|
||||
0x46, 0x49, 0x49, 0x49, 0x31,// S
|
||||
0x01, 0x01, 0x7F, 0x01, 0x01,// T
|
||||
0x3F, 0x40, 0x40, 0x40, 0x3F,// U
|
||||
0x1F, 0x20, 0x40, 0x20, 0x1F,// V
|
||||
0x7F, 0x20, 0x18, 0x20, 0x7F,// W
|
||||
0x63, 0x14, 0x08, 0x14, 0x63,// X
|
||||
0x03, 0x04, 0x78, 0x04, 0x03,// Y
|
||||
0x61, 0x51, 0x49, 0x45, 0x43,// Z
|
||||
0x00, 0x00, 0x7F, 0x41, 0x41,// [
|
||||
0x02, 0x04, 0x08, 0x10, 0x20,// "\"
|
||||
0x41, 0x41, 0x7F, 0x00, 0x00,// ]
|
||||
0x04, 0x02, 0x01, 0x02, 0x04,// ^
|
||||
0x40, 0x40, 0x40, 0x40, 0x40,// _
|
||||
0x00, 0x01, 0x02, 0x04, 0x00,// `
|
||||
0x20, 0x54, 0x54, 0x54, 0x78,// a
|
||||
0x7F, 0x48, 0x44, 0x44, 0x38,// b
|
||||
0x38, 0x44, 0x44, 0x44, 0x20,// c
|
||||
0x38, 0x44, 0x44, 0x48, 0x7F,// d
|
||||
0x38, 0x54, 0x54, 0x54, 0x18,// e
|
||||
0x08, 0x7E, 0x09, 0x01, 0x02,// f
|
||||
0x08, 0x14, 0x54, 0x54, 0x3C,// g
|
||||
0x7F, 0x08, 0x04, 0x04, 0x78,// h
|
||||
0x00, 0x44, 0x7D, 0x40, 0x00,// i
|
||||
0x20, 0x40, 0x44, 0x3D, 0x00,// j
|
||||
0x00, 0x7F, 0x10, 0x28, 0x44,// k
|
||||
0x00, 0x41, 0x7F, 0x40, 0x00,// l
|
||||
0x7C, 0x04, 0x18, 0x04, 0x78,// m
|
||||
0x7C, 0x08, 0x04, 0x04, 0x78,// n
|
||||
0x38, 0x44, 0x44, 0x44, 0x38,// o
|
||||
0x7C, 0x14, 0x14, 0x14, 0x08,// p
|
||||
0x08, 0x14, 0x14, 0x18, 0x7C,// q
|
||||
0x7C, 0x08, 0x04, 0x04, 0x08,// r
|
||||
0x48, 0x54, 0x54, 0x54, 0x20,// s
|
||||
0x04, 0x3F, 0x44, 0x40, 0x20,// t
|
||||
0x3C, 0x40, 0x40, 0x20, 0x7C,// u
|
||||
0x1C, 0x20, 0x40, 0x20, 0x1C,// v
|
||||
0x3C, 0x40, 0x30, 0x40, 0x3C,// w
|
||||
0x44, 0x28, 0x10, 0x28, 0x44,// x
|
||||
0x0C, 0x50, 0x50, 0x50, 0x3C,// y
|
||||
0x44, 0x64, 0x54, 0x4C, 0x44,// z
|
||||
0x00, 0x08, 0x36, 0x41, 0x00,// {
|
||||
0x00, 0x00, 0x7F, 0x00, 0x00,// |
|
||||
0x00, 0x41, 0x36, 0x08, 0x00,// }
|
||||
0x08, 0x08, 0x2A, 0x1C, 0x08,// ->
|
||||
0x08, 0x1C, 0x2A, 0x08, 0x08 // <-
|
||||
};
|
||||
|
||||
void drawString(const int x, const int y, const char* str, uint32_t color)
|
||||
{
|
||||
int _x = x;
|
||||
while(*str)
|
||||
{
|
||||
drawChar(_x, y, *str, color);
|
||||
str++;
|
||||
_x += 6;
|
||||
}
|
||||
}
|
||||
|
||||
void drawChar(const int x, const int y, const char c, uint32_t color)
|
||||
{
|
||||
SDL_Rect rect;
|
||||
for(unsigned int n=0; n<5; n++)
|
||||
{
|
||||
int bits = lcd_font[c * 5 + n];
|
||||
for(unsigned int m=0; m<8; m++)
|
||||
{
|
||||
rect.x = x * DRAW_SCALE + n * DRAW_SCALE;
|
||||
rect.y = y * DRAW_SCALE + m * DRAW_SCALE;
|
||||
rect.w = DRAW_SCALE;
|
||||
rect.h = DRAW_SCALE;
|
||||
if (bits & (1L << m))
|
||||
SDL_FillRect(screen, &rect, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawStringSmall(const int x, const int y, const char* str, uint32_t color)
|
||||
{
|
||||
int _x = x;
|
||||
while(*str)
|
||||
{
|
||||
drawCharSmall(_x, y, *str, color);
|
||||
str++;
|
||||
_x += 6 / DRAW_SCALE;
|
||||
}
|
||||
}
|
||||
|
||||
void drawCharSmall(const int x, const int y, const char c, uint32_t color)
|
||||
{
|
||||
SDL_Rect rect;
|
||||
for(unsigned int n=0; n<5; n++)
|
||||
{
|
||||
int bits = lcd_font[c * 5 + n];
|
||||
for(unsigned int m=0; m<8; m++)
|
||||
{
|
||||
rect.x = x * DRAW_SCALE + n;
|
||||
rect.y = y * DRAW_SCALE + m;
|
||||
rect.w = 1;
|
||||
rect.h = 1;
|
||||
if (bits & (1L << m))
|
||||
SDL_FillRect(screen, &rect, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawRect(const int x, const int y, const int w, const int h, uint32_t color)
|
||||
{
|
||||
SDL_Rect rect = {x * DRAW_SCALE, y * DRAW_SCALE, w * DRAW_SCALE, h * DRAW_SCALE};
|
||||
if (rect.w == 0) rect.w = 1;
|
||||
if (rect.h == 0) rect.h = 1;
|
||||
SDL_FillRect(screen, &rect, color);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef SIM_BASE_H
|
||||
#define SIM_BASE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
class simBaseComponent;
|
||||
extern std::vector<simBaseComponent*> simComponentList;
|
||||
|
||||
class simBaseComponent
|
||||
{
|
||||
public:
|
||||
simBaseComponent() : drawPosX(-1), drawPosY(-1) {simComponentList.push_back(this);}
|
||||
virtual ~simBaseComponent() {}
|
||||
|
||||
virtual void tick() {}//Called about every ms
|
||||
void doDraw() { if (drawPosX > -1) draw(drawPosX, drawPosY); }
|
||||
virtual void draw(int x, int y) {}//Called every screen draw (~25ms)
|
||||
|
||||
simBaseComponent* setDrawPosition(int x, int y) { drawPosX = x; drawPosY = y; return this; }
|
||||
private:
|
||||
int drawPosX, drawPosY;
|
||||
};
|
||||
|
||||
void drawRect(const int x, const int y, const int w, const int h, uint32_t color);
|
||||
void drawString(const int x, const int y, const char* str, uint32_t color);
|
||||
void drawChar(const int x, const int y, const char c, uint32_t color);
|
||||
void drawStringSmall(const int x, const int y, const char* str, uint32_t color);
|
||||
void drawCharSmall(const int x, const int y, const char c, uint32_t color);
|
||||
|
||||
#endif//SIM_BASE_H
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifndef DELEGATE_H
|
||||
#define DELEGATE_H
|
||||
|
||||
#include <stddef.h>
|
||||
/* Here be dragons... */
|
||||
|
||||
template<typename A0=void, typename A1=void>
|
||||
class delegate
|
||||
{
|
||||
public:
|
||||
delegate() : object_ptr(NULL), stub_ptr(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T, void (T::*TMethod)(A0 a0, A1 a1)>
|
||||
static delegate from_method(T* object_ptr)
|
||||
{
|
||||
delegate d;
|
||||
d.object_ptr = object_ptr;
|
||||
d.stub_ptr = &method_stub<T, TMethod>;
|
||||
return d;
|
||||
}
|
||||
|
||||
void operator()(A0 a0, A1 a1) const
|
||||
{
|
||||
if (!object_ptr)
|
||||
return;
|
||||
return stub_ptr(object_ptr, a0, a1);
|
||||
}
|
||||
|
||||
operator bool() const { return object_ptr != NULL; }
|
||||
|
||||
private:
|
||||
typedef void (*stub_type)(void* object_ptr, A0 a0, A1 a1);
|
||||
|
||||
void* object_ptr;
|
||||
stub_type stub_ptr;
|
||||
|
||||
template <class T, void (T::*TMethod)(A0 a0, A1 a1)>
|
||||
static void method_stub(void* object_ptr, A0 a0, A1 a1)
|
||||
{
|
||||
T* p = static_cast<T*>(object_ptr);
|
||||
return (p->*TMethod)(a0, a1);
|
||||
}
|
||||
};
|
||||
|
||||
#define DELEGATE(DelegateType, Type, Object, Method) (DelegateType::from_method<Type, &Type::Method>(&Object))
|
||||
|
||||
#endif//DELEGATE_H
|
||||
@@ -0,0 +1,114 @@
|
||||
#include "display_HD44780.h"
|
||||
#include "arduinoIO.h"
|
||||
|
||||
displayHD44780Sim::displayHD44780Sim(arduinoIOSim* arduinoIO, int rsPinNr, int enablePinNr, int d4PinNr, int d5PinNr, int d6PinNr, int d7PinNr)
|
||||
{
|
||||
this->rsPin = rsPinNr;
|
||||
this->enablePin = enablePinNr;
|
||||
this->d4Pin = d4PinNr;
|
||||
this->d5Pin = d5PinNr;
|
||||
this->d6Pin = d6PinNr;
|
||||
this->d7Pin = d7PinNr;
|
||||
|
||||
readUpper = true;
|
||||
writeData = true;
|
||||
dataPos = 0;
|
||||
memset(data, ' ', 0x80);
|
||||
arduinoIO->registerPortCallback(enablePinNr, DELEGATE(ioDelegate, displayHD44780Sim, *this, enablePinUpdate));
|
||||
}
|
||||
displayHD44780Sim::~displayHD44780Sim()
|
||||
{
|
||||
}
|
||||
|
||||
void displayHD44780Sim::draw(int x, int y)
|
||||
{
|
||||
int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
|
||||
for(unsigned int y=0; y<4; y++)
|
||||
{
|
||||
for(unsigned int x=0; x<20; x++)
|
||||
{
|
||||
char c = data[x+row_offsets[y]];
|
||||
|
||||
drawRect(x* 6, y * 9, 5, 8, 0x202080);
|
||||
|
||||
if (c < 8)
|
||||
{
|
||||
for(unsigned int m=0; m<8; m++)
|
||||
{
|
||||
int bits = customFontData[c * 8 + m];
|
||||
for(unsigned int n=0; n<5; n++)
|
||||
{
|
||||
if (bits & _BV(4-n))
|
||||
drawRect(x * 6 + n, y * 9 + m, 1, 1, 0xAAAAEE);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
drawChar(x * 6, y * 9, c, 0xAAAAEE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void displayHD44780Sim::enablePinUpdate(int pinNr, bool high)
|
||||
{
|
||||
if (!high) return;
|
||||
|
||||
int n = 0;
|
||||
if (readOutput(d4Pin)) n |= _BV(0);
|
||||
if (readOutput(d5Pin)) n |= _BV(1);
|
||||
if (readOutput(d6Pin)) n |= _BV(2);
|
||||
if (readOutput(d7Pin)) n |= _BV(3);
|
||||
bool rs = readOutput(rsPin);
|
||||
|
||||
if (readUpper || rs != upperRS)
|
||||
{
|
||||
upperBits = n;
|
||||
readUpper = false;
|
||||
upperRS = rs;
|
||||
return;
|
||||
}
|
||||
readUpper = true;
|
||||
|
||||
n |= upperBits << 4;
|
||||
|
||||
if (!rs)
|
||||
{
|
||||
if (n == 0x01)//LCD_CLEARDISPLAY
|
||||
{
|
||||
memset(data, ' ', 0x80);
|
||||
dataPos = 0;
|
||||
writeData = true;
|
||||
}else if (n == 0x02)//LCD_RETURNHOME
|
||||
{
|
||||
dataPos = 0;
|
||||
writeData = true;
|
||||
}else if ((n & 0xFC) == 0x04)//LCD_ENTRYMODESET
|
||||
{
|
||||
}else if ((n & 0xF8) == 0x08)//LCD_DISPLAYCONTROL
|
||||
{
|
||||
}else if ((n & 0xF0) == 0x10)//LCD_CURSORSHIFT
|
||||
{
|
||||
}else if ((n & 0xE0) == 0x20)//LCD_FUNCTIONSET
|
||||
{
|
||||
}else if ((n & 0xC0) == 0x40)//LCD_SETCGRAMADDR
|
||||
{
|
||||
dataPos = (n & 0x3F);
|
||||
writeData = false;
|
||||
}else if (n & 0x80)//LCD_SETDDRAMADDR
|
||||
{
|
||||
dataPos = (n & 0x7F);
|
||||
writeData = true;
|
||||
}else{
|
||||
printf("Unknown HD44780 command: %02x\n", n);
|
||||
}
|
||||
}else{
|
||||
if (writeData)
|
||||
{
|
||||
data[dataPos] = n;
|
||||
dataPos = (dataPos + 1) % 0x80;
|
||||
}else{
|
||||
customFontData[dataPos] = n;
|
||||
dataPos = (dataPos + 1) % 0x40;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef DISPLAY_HD44780_SIM_H
|
||||
#define DISPLAY_HD44780_SIM_H
|
||||
|
||||
#include "base.h"
|
||||
#include "arduinoIO.h"
|
||||
|
||||
class displayHD44780Sim : public simBaseComponent
|
||||
{
|
||||
public:
|
||||
displayHD44780Sim(arduinoIOSim* arduinoIO, int rsPinNr, int enablePinNr, int d4PinNr, int d5PinNr, int d6PinNr, int d7PinNr);
|
||||
virtual ~displayHD44780Sim();
|
||||
|
||||
virtual void draw(int x, int y);
|
||||
private:
|
||||
int rsPin;
|
||||
int enablePin;
|
||||
int d4Pin;
|
||||
int d5Pin;
|
||||
int d6Pin;
|
||||
int d7Pin;
|
||||
|
||||
bool readUpper;
|
||||
bool upperRS;
|
||||
int upperBits;
|
||||
|
||||
bool writeData;
|
||||
int dataPos;
|
||||
char data[0x80];
|
||||
char customFontData[0x40];
|
||||
|
||||
void enablePinUpdate(int pinNr, bool high);
|
||||
};
|
||||
|
||||
#endif//STEPPER_SIM_H
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "display_SSD1309.h"
|
||||
|
||||
displaySDD1309Sim::displaySDD1309Sim(i2cSim* i2c, int id)
|
||||
{
|
||||
i2c->registerDevice(id, DELEGATE(i2cMessageDelegate, displaySDD1309Sim, *this, processMessage));
|
||||
lcd_data_pos = 0;
|
||||
}
|
||||
|
||||
displaySDD1309Sim::~displaySDD1309Sim()
|
||||
{
|
||||
}
|
||||
|
||||
void displaySDD1309Sim::processMessage(uint8_t* message, int length)
|
||||
{
|
||||
if (message[1] == 0x40)
|
||||
{
|
||||
//Data
|
||||
for(int n=2;n<length;n++)
|
||||
{
|
||||
lcd_data[lcd_data_pos] = message[n];
|
||||
lcd_data_pos = (lcd_data_pos + 1) % 1024;
|
||||
}
|
||||
}else if (message[1] == 0x00)
|
||||
{
|
||||
//Command
|
||||
for(int n=2;n<length;n++)
|
||||
{
|
||||
if ((message[n] & 0xF0) == 0x00)
|
||||
{
|
||||
lcd_data_pos = (lcd_data_pos & 0xFF0) | (message[n] & 0x0F);
|
||||
}else if ((message[n] & 0xF0) == 0x10)
|
||||
{
|
||||
lcd_data_pos = (lcd_data_pos & 0xF8F) | ((message[n] & 0x07) << 4);
|
||||
}else if ((message[n] & 0xF0) == 0xB0)
|
||||
{
|
||||
lcd_data_pos = (lcd_data_pos & 0x07F) | ((message[n] & 0x0F) << 7);
|
||||
}else if (message[n] == 0x20) { /*LCD_COMMAND_SET_ADDRESSING_MODE*/
|
||||
}else if (message[n] == 0x40) { /*Set start line*/
|
||||
}else if (message[n] == 0x81) { /*LCD_COMMAND_CONTRAST*/ n++;
|
||||
}else if (message[n] == 0xA1) { /*Segment remap*/
|
||||
}else if (message[n] == 0xA4) { /*LCD_COMMAND_FULL_DISPLAY_ON_DISABLE*/
|
||||
}else if (message[n] == 0xA5) { /*LCD_COMMAND_FULL_DISPLAY_ON_ENABLE*/
|
||||
}else if (message[n] == 0xA8) { /*Multiplex ratio*/ n++;
|
||||
}else if (message[n] == 0xC8) { /*COM scan output direction*/
|
||||
}else if (message[n] == 0xD3) { /*Display offset*/ n++;
|
||||
}else if (message[n] == 0xD5) { /*Display clock divider/freq*/ n++;
|
||||
}else if (message[n] == 0xD9) { /*Precharge period*/ n++;
|
||||
}else if (message[n] == 0xDA) { /*COM pins hardware configuration*/ n++;
|
||||
}else if (message[n] == 0xDB) { /*VCOMH Deslect level*/ n++;
|
||||
}else if (message[n] == 0xDF) { /*LCD_COMMAND_LOCK_COMMANDS*/ n++;
|
||||
}else if (message[n] == 0xAE) { //Display OFF
|
||||
}else if (message[n] == 0xAF) { //Display ON
|
||||
}else{
|
||||
printf("Unknown LCD CMD: %02x\n", message[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define LCD_GFX_WIDTH 128
|
||||
#define LCD_GFX_HEIGHT 64
|
||||
void displaySDD1309Sim::draw(int x, int y)
|
||||
{
|
||||
drawRect(x, y, LCD_GFX_WIDTH + 2, LCD_GFX_HEIGHT + 2, 0xFFFFFF);
|
||||
drawRect(x+1, y+1, LCD_GFX_WIDTH, LCD_GFX_HEIGHT, 0x101010);
|
||||
for(int _y=0;_y<64;_y++)
|
||||
{
|
||||
for(int _x=0;_x<128;_x++)
|
||||
{
|
||||
if (lcd_data[_x + (_y/8) * LCD_GFX_WIDTH] & _BV(_y%8))
|
||||
{
|
||||
drawRect(x+_x+1, y+_y+1, 1, 1, 0x8080FF);
|
||||
drawRect(x+_x+1, y+_y+1, 0, 1, 0x8080AF);
|
||||
drawRect(x+_x+1, y+_y+1, 1, 0, 0x8080AF);
|
||||
}else{
|
||||
drawRect(x+_x+1, y+_y+1, 0, 1, 0x202020);
|
||||
drawRect(x+_x+1, y+_y+1, 1, 0, 0x202020);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
SDL_LockSurface(screen);
|
||||
for(int y=0;y<64;y++)
|
||||
{
|
||||
for(int _y=0;_y<DRAW_SCALE;_y++)
|
||||
{
|
||||
uint32_t* pix = ((uint32_t*)screen->pixels) + screen->pitch / 4 * (y * DRAW_SCALE + _y + DRAW_SCALE);
|
||||
for(int _n=0;_n<DRAW_SCALE;_n++)
|
||||
*pix++ = 0xFFFFFF;
|
||||
for(int x=0;x<128;x++)
|
||||
{
|
||||
for(int _n=0;_n<DRAW_SCALE;_n++)
|
||||
{
|
||||
if (_n == 0 || _y == 0)
|
||||
*pix++ = (lcd_data[x + (y/8) * LCD_GFX_WIDTH] & _BV(y%8)) ? 0x8080AF : 0x101010;
|
||||
else
|
||||
*pix++ = (lcd_data[x + (y/8) * LCD_GFX_WIDTH] & _BV(y%8)) ? 0x8080FF : 0x202020;
|
||||
}
|
||||
}
|
||||
for(int _n=0;_n<DRAW_SCALE;_n++)
|
||||
*pix++ = 0xFFFFFF;
|
||||
}
|
||||
}
|
||||
for(int _y=0;_y<DRAW_SCALE;_y++)
|
||||
{
|
||||
uint32_t* pix = ((uint32_t*)screen->pixels) + screen->pitch / 4 * (_y);
|
||||
uint32_t* pix2 = ((uint32_t*)screen->pixels) + screen->pitch / 4 * (64 * DRAW_SCALE + _y + DRAW_SCALE);
|
||||
for(int x=0;x<130;x++)
|
||||
for(int _n=0;_n<DRAW_SCALE;_n++)
|
||||
{
|
||||
*pix++ = 0xFFFFFF;
|
||||
*pix2++ = 0xFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UnlockSurface(screen);
|
||||
*/
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef DISPLAY_SSD1309_SIM_H
|
||||
#define DISPLAY_SSD1309_SIM_H
|
||||
|
||||
#include "i2c.h"
|
||||
|
||||
class displaySDD1309Sim : public simBaseComponent
|
||||
{
|
||||
public:
|
||||
displaySDD1309Sim(i2cSim* i2c, int id = 0x78);
|
||||
virtual ~displaySDD1309Sim();
|
||||
|
||||
virtual void draw(int x, int y);
|
||||
private:
|
||||
void processMessage(uint8_t* message, int length);
|
||||
|
||||
int lcd_data_pos;
|
||||
uint8_t lcd_data[1024];
|
||||
};
|
||||
|
||||
#endif//DISPLAY_SSD1309_SIM_H
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "heater.h"
|
||||
#include "arduinoIO.h"
|
||||
|
||||
heaterSim::heaterSim(int heaterPinNr, adcSim* adc, int temperatureADCNr, float heaterStrength)
|
||||
{
|
||||
this->heaterPinNr = heaterPinNr;
|
||||
this->adc = adc;
|
||||
this->temperatureADCNr = temperatureADCNr;
|
||||
this->heaterStrength = heaterStrength;
|
||||
|
||||
this->temperature = 20;
|
||||
}
|
||||
|
||||
heaterSim::~heaterSim()
|
||||
{
|
||||
}
|
||||
|
||||
void heaterSim::tick()
|
||||
{
|
||||
if (readOutput(heaterPinNr))
|
||||
temperature += 0.03 * heaterStrength;
|
||||
else if (temperature > 20)
|
||||
temperature -= 0.03 * heaterStrength;
|
||||
adc->adcValue[temperatureADCNr] = 231 + temperature * 81 / 100;//Not accurate, but accurate enough.
|
||||
}
|
||||
|
||||
void heaterSim::draw(int x, int y)
|
||||
{
|
||||
char buffer[32];
|
||||
sprintf(buffer, "%iC", int(temperature));
|
||||
drawString(x, y, buffer, 0xFFFFFF);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef HEATER_SIM_H
|
||||
#define HEATER_SIM_H
|
||||
|
||||
#include "base.h"
|
||||
#include "adc.h"
|
||||
|
||||
class heaterSim : public simBaseComponent
|
||||
{
|
||||
public:
|
||||
heaterSim(int heaterPinNr, adcSim* adc, int temperatureADCNr, float heaterStrength = 1.0);
|
||||
virtual ~heaterSim();
|
||||
|
||||
virtual void tick();
|
||||
virtual void draw(int x, int y);
|
||||
private:
|
||||
float temperature;
|
||||
float heaterStrength;
|
||||
|
||||
int heaterPinNr;
|
||||
adcSim* adc;
|
||||
int temperatureADCNr;
|
||||
};
|
||||
|
||||
#endif//I2C_SIM_H
|
||||
@@ -0,0 +1,59 @@
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "i2c.h"
|
||||
|
||||
i2cSim::i2cSim()
|
||||
{
|
||||
TWCR.setCallback(DELEGATE(registerDelegate, i2cSim, *this, I2C_TWCR_callback));
|
||||
}
|
||||
|
||||
i2cSim::~i2cSim()
|
||||
{
|
||||
}
|
||||
|
||||
void i2cSim::I2C_TWCR_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
if ((oldValue ^ newValue) == _BV(TWIE) && (newValue & _BV(TWIE)))
|
||||
return;
|
||||
if ((newValue & _BV(TWINT)) && (newValue & _BV(TWEN)))
|
||||
{
|
||||
if (newValue & _BV(TWSTA))
|
||||
{
|
||||
if (i2cMessagePos > 0)
|
||||
{
|
||||
if (i2cDevice[i2cMessage[0]])
|
||||
i2cDevice[i2cMessage[0]](i2cMessage, i2cMessagePos);
|
||||
else
|
||||
printf("i2c message to unknown device ID: %02x\n", i2cMessage[0]);
|
||||
}
|
||||
i2cMessagePos = 0;
|
||||
i2cMessage[0] = 0xFF;
|
||||
TWSR = 0x08;
|
||||
} else if (newValue & _BV(TWSTO))
|
||||
{
|
||||
if (i2cDevice[i2cMessage[0]])
|
||||
i2cDevice[i2cMessage[0]](i2cMessage, i2cMessagePos);
|
||||
else
|
||||
printf("i2c message to unknown device ID: %02x\n", i2cMessage[0]);
|
||||
i2cMessagePos = 0;
|
||||
newValue &=~_BV(TWINT);
|
||||
newValue &=~_BV(TWSTO);
|
||||
TWSR = 0x00;
|
||||
}else{
|
||||
i2cMessage[i2cMessagePos] = TWDR;
|
||||
i2cMessagePos++;
|
||||
TWDR = 0x00;
|
||||
if (TWSR == 0x08)
|
||||
TWSR = 0x18;
|
||||
else if (TWSR == 0x18)
|
||||
TWSR = 0x28;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void i2cSim::registerDevice(int id, i2cMessageDelegate func)
|
||||
{
|
||||
if (id < 0 || id > 255)
|
||||
return;
|
||||
i2cDevice[id] = func;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef I2C_SIM_H
|
||||
#define I2C_SIM_H
|
||||
|
||||
#include "base.h"
|
||||
|
||||
typedef delegate<uint8_t*, int> i2cMessageDelegate;
|
||||
|
||||
class i2cSim : public simBaseComponent
|
||||
{
|
||||
public:
|
||||
i2cSim();
|
||||
virtual ~i2cSim();
|
||||
|
||||
void registerDevice(int id, i2cMessageDelegate func);
|
||||
|
||||
void I2C_TWCR_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
private:
|
||||
int i2cMessagePos;
|
||||
uint8_t i2cMessage[2048];
|
||||
i2cMessageDelegate i2cDevice[256];
|
||||
};
|
||||
|
||||
#endif//I2C_SIM_H
|
||||
@@ -0,0 +1,68 @@
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "led_PCA9632.h"
|
||||
|
||||
ledPCA9632Sim::ledPCA9632Sim(i2cSim* i2c, int id)
|
||||
{
|
||||
i2c->registerDevice(id, DELEGATE(i2cMessageDelegate, ledPCA9632Sim, *this, processMessage));
|
||||
}
|
||||
|
||||
ledPCA9632Sim::~ledPCA9632Sim()
|
||||
{
|
||||
}
|
||||
|
||||
void ledPCA9632Sim::processMessage(uint8_t* message, int length)
|
||||
{
|
||||
int regAddr = message[1] & 0x0F;
|
||||
for(int n=2; n<length; n++)
|
||||
{
|
||||
switch(regAddr)
|
||||
{
|
||||
case 0x00://MODE1
|
||||
break;
|
||||
case 0x01://MODE2
|
||||
break;
|
||||
case 0x02://PWM0
|
||||
pwm[0] = message[n];
|
||||
break;
|
||||
case 0x03://PWM1
|
||||
pwm[1] = message[n];
|
||||
break;
|
||||
case 0x04://PWM2
|
||||
pwm[2] = message[n];
|
||||
break;
|
||||
case 0x05://PWM3
|
||||
pwm[3] = message[n];
|
||||
break;
|
||||
case 0x06://GRPPWM
|
||||
break;
|
||||
case 0x07://GRPFREQ
|
||||
break;
|
||||
case 0x08://LEDOUT
|
||||
ledout = message[n];
|
||||
break;
|
||||
default:
|
||||
printf("LED: %02x: %02x\n", regAddr, message[n]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (message[1] & 0x80)
|
||||
{
|
||||
regAddr++;
|
||||
if (regAddr > 0x0C)
|
||||
regAddr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ledPCA9632Sim::draw(int x, int y)
|
||||
{
|
||||
int r=0,g=0,b=0;
|
||||
if ((ledout & 0x03) == 1) r = 0xff;
|
||||
if ((ledout & 0x03) == 2) r = pwm[0];
|
||||
if (((ledout >> 2) & 0x03) == 1) g = 0xff;
|
||||
if (((ledout >> 2) & 0x03) == 2) g = pwm[1];
|
||||
if (((ledout >> 4) & 0x03) == 1) b = 0xff;
|
||||
if (((ledout >> 4) & 0x03) == 2) b = pwm[2];
|
||||
drawRect(x, y, 128, 3, r << 16 | g << 8 | b);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef LED_PCA9532_SIM_H
|
||||
#define LED_PCA9532_SIM_H
|
||||
|
||||
#include "i2c.h"
|
||||
|
||||
class ledPCA9632Sim : public simBaseComponent
|
||||
{
|
||||
public:
|
||||
ledPCA9632Sim(i2cSim* i2c, int id = 0xC0);
|
||||
virtual ~ledPCA9632Sim();
|
||||
|
||||
virtual void draw(int x, int y);
|
||||
private:
|
||||
void processMessage(uint8_t* message, int length);
|
||||
|
||||
int pwm[4];
|
||||
int ledout;
|
||||
};
|
||||
|
||||
|
||||
#endif//LED_PCA9532_SIM_H
|
||||
@@ -0,0 +1,270 @@
|
||||
#include <dirent.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
#include "sdcard.h"
|
||||
#include "../../Marlin/SdFatStructs.h"
|
||||
|
||||
sdcardSimulation::sdcardSimulation(const char* basePath, int errorRate)
|
||||
: errorRate(errorRate)
|
||||
{
|
||||
this->basePath = basePath;
|
||||
|
||||
SPDR.setCallback(DELEGATE(registerDelegate, sdcardSimulation, *this, ISP_SPDR_callback));
|
||||
|
||||
sd_state = 0;
|
||||
sd_buffer_pos = 0;
|
||||
}
|
||||
|
||||
sdcardSimulation::~sdcardSimulation()
|
||||
{
|
||||
}
|
||||
|
||||
static const uint16_t crctab[] = {
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
|
||||
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
|
||||
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
|
||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
|
||||
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
|
||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
|
||||
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
|
||||
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
|
||||
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
|
||||
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
|
||||
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
|
||||
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
|
||||
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
|
||||
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
|
||||
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
|
||||
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
|
||||
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
|
||||
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
|
||||
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
|
||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
|
||||
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
|
||||
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
|
||||
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
|
||||
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
|
||||
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
|
||||
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
|
||||
};
|
||||
static uint16_t CRC_CCITT(const uint8_t* data, size_t n) {
|
||||
uint16_t crc = 0;
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
crc = crctab[(crc >> 8 ^ data[i]) & 0XFF] ^ (crc << 8);
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
FILE* simFile;
|
||||
//Total crappy fake FAT32 simulation, works for 1 file, sort of.
|
||||
void sdcardSimulation::read_sd_block(int nr)
|
||||
{
|
||||
memset(sd_buffer, 0, 512);
|
||||
switch(nr)
|
||||
{
|
||||
case 0x000:{//MBR
|
||||
mbr_t* mbr = (mbr_t*)sd_buffer;
|
||||
mbr->part[0].boot = 0;
|
||||
mbr->part[0].totalSectors = 0x200000;
|
||||
mbr->part[0].firstSector = 1;
|
||||
}break;
|
||||
case 0x001:{//fat32_boot_t
|
||||
fat32_boot_t* boot = (fat32_boot_t*)sd_buffer;
|
||||
boot->bytesPerSector = 512;
|
||||
boot->fatCount = 1;
|
||||
boot->reservedSectorCount = 1;
|
||||
boot->sectorsPerCluster = 1;
|
||||
boot->sectorsPerFat32 = 0x400;
|
||||
boot->rootDirEntryCount = 0;
|
||||
boot->fat32RootCluster = 1;
|
||||
}break;
|
||||
case 0x002:{//FAT32 for root dir entries
|
||||
uint32_t* fat32 = (uint32_t*)sd_buffer;
|
||||
for(uint8_t n=0;n<128;n++)
|
||||
fat32[n] = 0X0FFFFFF8;
|
||||
for(uint8_t n=0;n<128;n++)
|
||||
fat32[n] = n + 1;
|
||||
fat32[127] = 0X0FFFFFF8;
|
||||
}break;
|
||||
default:
|
||||
if (nr >= 0x401 && nr < 0x500) //root directory: dir_t
|
||||
{
|
||||
dir_t* dir = (dir_t*)sd_buffer;
|
||||
|
||||
DIR* dh = opendir(basePath);
|
||||
struct dirent *entry;
|
||||
int idx = 0;
|
||||
int reqIdx = nr - 0x401;
|
||||
while((entry=readdir(dh))!=NULL)
|
||||
{
|
||||
if (entry->d_name[0] == '.')
|
||||
continue;
|
||||
if (idx == reqIdx)
|
||||
break;
|
||||
idx++;
|
||||
}
|
||||
if (entry == NULL)
|
||||
return;
|
||||
|
||||
const char* namePtr = entry->d_name;
|
||||
|
||||
int fatNr = 0;
|
||||
while(*namePtr)
|
||||
{
|
||||
vfat_t *vfat = (vfat_t*)dir;
|
||||
vfat->firstClusterLow = 0;
|
||||
vfat->sequenceNumber = 0x41 + fatNr;
|
||||
for(unsigned int n=0;n<5&&*namePtr;n++)
|
||||
vfat->name1[n*2] = *namePtr++;
|
||||
for(unsigned int n=0;n<6&&*namePtr;n++)
|
||||
vfat->name2[n*2] = *namePtr++;
|
||||
for(unsigned int n=0;n<2&&*namePtr;n++)
|
||||
vfat->name3[n*2] = *namePtr++;
|
||||
vfat->attributes = DIR_ATT_LONG_NAME;
|
||||
dir++;
|
||||
fatNr++;
|
||||
}
|
||||
|
||||
dir->attributes = 0;
|
||||
memcpy(dir->name, "FAKEFILEXCO", 8+3);
|
||||
if (strrchr(entry->d_name, '.'))
|
||||
dir->name[8] = toupper(strrchr(entry->d_name, '.')[1]);
|
||||
dir->firstClusterHigh = 0;
|
||||
dir->firstClusterLow = 256;
|
||||
if (simFile == NULL)
|
||||
simFile = fopen("c:/models/Box_20x20x10.gcode", "rb");
|
||||
fseek(simFile, 0, SEEK_END);
|
||||
dir->fileSize = ftell(simFile);
|
||||
fseek(simFile, 0, SEEK_SET);
|
||||
|
||||
dir++;
|
||||
fatNr++;
|
||||
|
||||
closedir(dh);
|
||||
|
||||
while(fatNr < 16)
|
||||
{
|
||||
dir->attributes = DIR_ATT_HIDDEN;
|
||||
dir->name[0] = DIR_NAME_DELETED;
|
||||
|
||||
dir++;
|
||||
fatNr++;
|
||||
}
|
||||
}
|
||||
else if (nr >= 4 && nr < 0x400)
|
||||
{
|
||||
//FAT32 tables for file, just link to the next block
|
||||
uint32_t* fat32 = (uint32_t*)sd_buffer;
|
||||
for(uint8_t n=0;n<128;n++)
|
||||
fat32[n] = (nr-2) * 128 + n + 1;
|
||||
}
|
||||
else if (nr >= 0x500 && nr < 0x20000)
|
||||
{
|
||||
//Actual data blocks
|
||||
fseek(simFile, (nr - 0x501) * 512, SEEK_SET);
|
||||
fread(sd_buffer, 512, 1, simFile);
|
||||
}else{
|
||||
memset(sd_buffer, 0xFF, 512);
|
||||
printf("Read SD?: %x\n", nr);
|
||||
//exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t crc = CRC_CCITT(sd_buffer, 512);
|
||||
sd_buffer[512] = crc >> 8;
|
||||
sd_buffer[513] = crc;
|
||||
}
|
||||
|
||||
void sdcardSimulation::ISP_SPDR_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
if (errorRate && (rand() % errorRate) == 0)
|
||||
newValue = rand();
|
||||
if ((PING & _BV(2)))
|
||||
{
|
||||
//No card inserted, return 0xFF
|
||||
newValue = 0xFF;
|
||||
SPSR |= _BV(SPIF);//Mark transfer finished
|
||||
return;
|
||||
}
|
||||
switch(sd_state)
|
||||
{
|
||||
case 0://Read CMD
|
||||
case 2://Read ACMD
|
||||
sd_buffer[sd_buffer_pos++] = newValue;
|
||||
if (sd_buffer_pos == 1 && (sd_buffer[0] & 0xC0) != 0x40)
|
||||
sd_buffer_pos = 0;
|
||||
if (sd_buffer_pos == 6) // 1 cmd, 4 param, 1 crc
|
||||
sd_state += 1;
|
||||
break;
|
||||
case 1://Return status of CMD
|
||||
sd_state = 0;
|
||||
sd_buffer_pos = 0;
|
||||
|
||||
switch(sd_buffer[0] & 0x3F)
|
||||
{
|
||||
case 0x00://CMD0 - GO_IDLE_STATE
|
||||
newValue = 0x01; //Report R1_IDLE_STATE
|
||||
break;
|
||||
case 0x08://CMD8 - SEND_IF_COND
|
||||
newValue = 0x04; //Report R1_ILLEGAL_COMMAND
|
||||
break;
|
||||
case 0x0C://CMD12 - STOP_TRANSMISSION
|
||||
newValue = 0x01; //Report R1_IDLE_STATE
|
||||
break;
|
||||
case 0x11://CMD17 - READ_SINGLE_BLOCK
|
||||
newValue = 0x00;//R1_READY_STATE
|
||||
sd_read_block_nr = (sd_buffer[1] << 24) | (sd_buffer[2] << 16) | (sd_buffer[3] << 8) | (sd_buffer[4] << 0);
|
||||
read_sd_block(sd_read_block_nr >> 9);
|
||||
sd_state = 10;
|
||||
sd_buffer_pos = 0;
|
||||
break;
|
||||
case 0x37://CMD55 - APP_CMD
|
||||
sd_state = 2;
|
||||
break;
|
||||
default:
|
||||
printf("SD CMD: %02x %02x %02x %02x %02x %02x\n", sd_buffer[0] & 0x3F, sd_buffer[1], sd_buffer[2], sd_buffer[3], sd_buffer[4], sd_buffer[5]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3://Return status of ACMD
|
||||
sd_state = 0;
|
||||
sd_buffer_pos = 0;
|
||||
|
||||
switch(sd_buffer[0] & 0x3F)
|
||||
{
|
||||
case 0x29://ACMD41 - SD_SEND_OP_COMD
|
||||
newValue = 0x00;//R1_READY_STATE
|
||||
break;
|
||||
default:
|
||||
printf("SD ACMD: %02x %02x %02x %02x %02x %02x\n", sd_buffer[0] & 0x3F, sd_buffer[1], sd_buffer[2], sd_buffer[3], sd_buffer[4], sd_buffer[5]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 10://READ BLOCK
|
||||
if (sd_buffer_pos == 0)
|
||||
newValue = 0xFE;//DATA_START_BLOCK
|
||||
else
|
||||
newValue = sd_buffer[sd_buffer_pos-1];
|
||||
|
||||
sd_buffer_pos++;
|
||||
if (sd_buffer_pos == 512 + 1 + 2)
|
||||
{
|
||||
sd_state = 0;
|
||||
sd_buffer_pos = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
//Introduce random errors in SD communication
|
||||
if (errorRate && (rand() % errorRate) == 0)
|
||||
newValue = rand();
|
||||
|
||||
//Mark transfer finished
|
||||
SPSR |= _BV(SPIF);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef SDCARD_SIM_H
|
||||
#define SDCARD_SIM_H
|
||||
|
||||
#include "base.h"
|
||||
|
||||
class sdcardSimulation : public simBaseComponent
|
||||
{
|
||||
private:
|
||||
const char* basePath;
|
||||
public:
|
||||
sdcardSimulation(const char* basePath, int errorRate=0);
|
||||
virtual ~sdcardSimulation();
|
||||
|
||||
void ISP_SPDR_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void read_sd_block(int nr);
|
||||
|
||||
int sd_state;
|
||||
uint8_t sd_buffer[1024];
|
||||
int sd_buffer_pos;
|
||||
int sd_read_block_nr;
|
||||
int errorRate;
|
||||
};
|
||||
|
||||
#endif//SDCARD_SIM_H
|
||||
@@ -0,0 +1,49 @@
|
||||
#include <avr/io.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "serial.h"
|
||||
|
||||
serialSim::serialSim()
|
||||
{
|
||||
UCSR0A.setCallback(DELEGATE(registerDelegate, serialSim, *this, UART_UCSR0A_callback));
|
||||
UDR0.setCallback(DELEGATE(registerDelegate, serialSim, *this, UART_UDR0_callback));
|
||||
|
||||
UCSR0A = 0;
|
||||
|
||||
recvLine = 0;
|
||||
recvPos = 0;
|
||||
memset(recvBuffer, '\0', sizeof(recvBuffer));
|
||||
}
|
||||
|
||||
serialSim::~serialSim()
|
||||
{
|
||||
}
|
||||
|
||||
void serialSim::UART_UCSR0A_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
//Always mark "write ready" flag, so the serial code never waits.
|
||||
newValue |= _BV(UDRE0);
|
||||
}
|
||||
void serialSim::UART_UDR0_callback(uint8_t oldValue, uint8_t& newValue)
|
||||
{
|
||||
recvBuffer[recvLine][recvPos] = newValue;
|
||||
recvPos++;
|
||||
if (recvPos == 80 || newValue == '\n')
|
||||
{
|
||||
recvPos = 0;
|
||||
recvLine++;
|
||||
if (recvLine == SERIAL_LINE_COUNT)
|
||||
{
|
||||
for(unsigned int n=0; n<SERIAL_LINE_COUNT-1;n++)
|
||||
memcpy(recvBuffer[n], recvBuffer[n+1], 80);
|
||||
recvLine--;
|
||||
memset(recvBuffer[recvLine], '\0', 80);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void serialSim::draw(int x, int y)
|
||||
{
|
||||
for(unsigned int n=0; n<SERIAL_LINE_COUNT;n++)
|
||||
drawStringSmall(x, y+n*3, recvBuffer[n], 0xFFFFFF);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef SERIAL_SIM_H
|
||||
#define SERIAL_SIM_H
|
||||
|
||||
#include "base.h"
|
||||
|
||||
#define SERIAL_LINE_COUNT 30
|
||||
class serialSim : public simBaseComponent
|
||||
{
|
||||
public:
|
||||
serialSim();
|
||||
virtual ~serialSim();
|
||||
|
||||
virtual void draw(int x, int y);
|
||||
|
||||
private:
|
||||
int recvLine, recvPos;
|
||||
char recvBuffer[SERIAL_LINE_COUNT][80];
|
||||
|
||||
void UART_UCSR0A_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
void UART_UDR0_callback(uint8_t oldValue, uint8_t& newValue);
|
||||
};
|
||||
|
||||
#endif//SERIAL_SIM_H
|
||||
@@ -0,0 +1,59 @@
|
||||
#include "stepper.h"
|
||||
#include "arduinoIO.h"
|
||||
|
||||
stepperSim::stepperSim(arduinoIOSim* arduinoIO, int enablePinNr, int stepPinNr, int dirPinNr, bool invertDir)
|
||||
{
|
||||
this->minStepValue = -1;
|
||||
this->maxStepValue = -1;
|
||||
this->stepValue = 0;
|
||||
this->minEndstopPin = -1;
|
||||
this->maxEndstopPin = -1;
|
||||
|
||||
this->invertDir = invertDir;
|
||||
this->enablePin = enablePinNr;
|
||||
this->stepPin = stepPinNr;
|
||||
this->dirPin = dirPinNr;
|
||||
|
||||
arduinoIO->registerPortCallback(stepPinNr, DELEGATE(ioDelegate, stepperSim, *this, stepPinUpdate));
|
||||
}
|
||||
stepperSim::~stepperSim()
|
||||
{
|
||||
}
|
||||
|
||||
void stepperSim::stepPinUpdate(int pinNr, bool high)
|
||||
{
|
||||
if (high)//Only step on high->low transition.
|
||||
return;
|
||||
if (readOutput(enablePin))
|
||||
return;
|
||||
if (readOutput(dirPin) == invertDir)
|
||||
stepValue --;
|
||||
else
|
||||
stepValue ++;
|
||||
if (minStepValue == -1)
|
||||
return;
|
||||
if (stepValue < minStepValue)
|
||||
stepValue = minStepValue;
|
||||
if (stepValue > maxStepValue)
|
||||
stepValue = maxStepValue;
|
||||
if (minEndstopPin > -1)
|
||||
writeInput(minEndstopPin, stepValue != minStepValue);
|
||||
if (maxEndstopPin > -1)
|
||||
writeInput(maxEndstopPin, stepValue != maxStepValue);
|
||||
}
|
||||
|
||||
void stepperSim::setEndstops(int minEndstopPinNr, int maxEndstopPinNr)
|
||||
{
|
||||
minEndstopPin = minEndstopPinNr;
|
||||
maxEndstopPin = maxEndstopPinNr;
|
||||
|
||||
writeInput(minEndstopPin, stepValue != minStepValue);
|
||||
writeInput(maxEndstopPin, stepValue != maxStepValue);
|
||||
}
|
||||
|
||||
void stepperSim::draw(int x, int y)
|
||||
{
|
||||
char buffer[32];
|
||||
sprintf(buffer, "%i steps", int(stepValue));
|
||||
drawString(x, y, buffer, 0xFFFFFF);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef STEPPER_SIM_H
|
||||
#define STEPPER_SIM_H
|
||||
|
||||
#include "base.h"
|
||||
#include "arduinoIO.h"
|
||||
|
||||
class stepperSim : public simBaseComponent
|
||||
{
|
||||
private:
|
||||
int minStepValue;
|
||||
int maxStepValue;
|
||||
int stepValue;
|
||||
bool invertDir;
|
||||
int enablePin, stepPin, dirPin;
|
||||
int minEndstopPin, maxEndstopPin;
|
||||
public:
|
||||
stepperSim(arduinoIOSim* arduinoIO, int enablePinNr, int stepPinNr, int dirPinNr, bool invertDir);
|
||||
virtual ~stepperSim();
|
||||
|
||||
virtual void draw(int x, int y);
|
||||
|
||||
void setRange(int minValue, int maxValue) { minStepValue = minValue; maxStepValue = maxValue; stepValue = (maxValue + minValue) / 2; }
|
||||
void setEndstops(int minEndstopPinNr, int maxEndstopPinNr);
|
||||
int getPosition() { return stepValue; }
|
||||
private:
|
||||
void stepPinUpdate(int pinNr, bool high);
|
||||
};
|
||||
|
||||
#endif//STEPPER_SIM_H
|
||||
Reference in New Issue
Block a user