This commit is contained in:
2022-11-13 22:53:56 +01:00
commit 0598c09364
1324 changed files with 4446777 additions and 0 deletions

View File

@@ -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];
}
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}
}
}

View File

@@ -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

View File

@@ -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);
*/
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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