Skip to content
This repository was archived by the owner on Aug 21, 2019. It is now read-only.

Commit ccb79bf

Browse files
update v.0.5.1 # Threads
- Added Task support (simulated task manager). - Moved loop(), setup() function implementations to Simulation.cpp - Changed digitalWrite(), digitalRead(), etc. to be functions instead of members (reason for that was that i needed function pointers in my tasks, and doing it with ptr to methods was a bit complicated for me so i opted for simpler (but i quess maybe messier solution)). - Plans for future: Simulate working with registers/ports and figure out way to simulate interrupts.
1 parent 928a24c commit ccb79bf

9 files changed

Lines changed: 719 additions & 471 deletions

File tree

README.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
#UPDATE 5/25/2018
2+
- MAJOR update, i changed code almost completely. digitalRead, digitalWrite etc. are now functions instead of members.
3+
- Added Task support, optimized code a bit and fixed few bugs.
4+
5+
TODO (plans for future): To recreate somehow digitalRead, digitalWrite to be more working-with-registers like instead
6+
of current simple bool mPins solution. But this will be work in future because i'm currently busy.
7+
-------------------------------------------------------------------------------------------------------
8+
What you need to do:
9+
- Now if you want to write code you are gonna write it in Simulation.cpp, i seperated it from everything else
10+
so that you can focus only on setup() and loop() functions, just like when coding in arduino
11+
12+
--------------------------------------------------------------------------------------------------------------
13+
## BRIEF / GUIDE##
14+
115
In my school we are programming this semester in uC32 arduino, but i can't find that chipkit anywhere near me,
216
also i couln't find any simulators online, so i decided to make my own simulator,
317
and of course all in good old console! :D Still work in progres...

Simulation.cpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#include "Simulation.h"
2+
3+
using namespace das;
4+
5+
#define PIN_LED1 33
6+
#define PIN_LED2 27
7+
#define PIN_SW2 7
8+
9+
int blink1_id, blink2_id;
10+
unsigned long blink1_var;
11+
12+
unsigned short stat2 = TASK_DISABLE;
13+
unsigned long period1, period2;
14+
15+
void blink_task1(int id, void * tptr)
16+
{
17+
digitalWrite(PIN_LED1, !digitalRead(PIN_LED1)); // Toggle pin state
18+
}
19+
20+
void blink_task2(int id, void * tptr)
21+
{
22+
digitalWrite(PIN_LED2, !digitalRead(PIN_LED2)); // Toggle pin state
23+
}
24+
25+
void blink_task3(int id, void * tptr)
26+
{
27+
stat2 = getTaskState(blink2_id);
28+
if (digitalRead(PIN_SW2))
29+
{
30+
// SW2=ON, pokreni task2
31+
if (stat2 == TASK_DISABLE)
32+
{
33+
// postavi RANDOM vreme rasporedjivanja
34+
int rTime = random(1, 10) * 25;
35+
setTaskPeriod(blink2_id, rTime);
36+
setTaskState(blink2_id, TASK_ENABLE);
37+
}
38+
}
39+
else
40+
{
41+
if (stat2 == TASK_ENABLE)
42+
{
43+
setTaskState(blink2_id, TASK_DISABLE);
44+
digitalWrite(PIN_LED2, LOW);
45+
}
46+
}
47+
}
48+
49+
void Simulation::setup()
50+
{
51+
// initialize the digital pin as an output.
52+
pinMode(PIN_LED1, OUTPUT);
53+
pinMode(PIN_LED2, OUTPUT);
54+
55+
//create blink tasks
56+
blink1_id = createTask(blink_task1, 500, TASK_ENABLE, &blink1_var);
57+
blink2_id = createTask(blink_task2, 25, stat2, NULL);
58+
createTask(blink_task3, 1000, TASK_ENABLE, NULL);
59+
}
60+
61+
#define BTN4 37
62+
bool btn4, do_reset;
63+
long long time1;
64+
65+
void Simulation::loop()
66+
{
67+
delay(100);
68+
if (digitalRead(BTN4))
69+
{
70+
if (!btn4)
71+
{
72+
time1 = millis(); // oznaci vreme prve promene
73+
btn4 = true; // tranzicija 0->1
74+
}
75+
else
76+
{
77+
if (millis() - time1 > 2000)
78+
do_reset = true;
79+
}
80+
}
81+
else
82+
{
83+
btn4 = false;
84+
// uradi reset ako treba
85+
if (do_reset) {
86+
executeSoftReset(RUN_SKETCH_ON_BOOT);
87+
do_reset = false;
88+
}
89+
}
90+
}

Simulation.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
#include "das.h"
3+
#include "tasks.h"
4+
5+
class Simulation : protected ArduinoSimulation_uC32
6+
{
7+
public:
8+
/**
9+
Experiment with screen width, height, fontwidth and fontheight until you are satisfied with
10+
result
11+
*/
12+
Simulation(int width = 80, int height = 40, int fontw = 8, int fonth = 10) :
13+
ArduinoSimulation_uC32(width, height, fontw, fonth) {}
14+
public:
15+
void BeginSimulation() {
16+
Start();
17+
}
18+
private:
19+
20+
virtual void setup() override;
21+
virtual void loop() override;
22+
};
23+

das.cpp

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
#include "das.h"
2+
std::atomic<bool> m_bPins[MAX_UC32_BASIC_IO_PIN + 1];
3+
std::atomic<PIN_MODE> m_PinModes[MAX_UC32_BASIC_IO_PIN + 1];
4+
mutex m_muxPin;
5+
6+
chrono::steady_clock::time_point m_tpSimulationStarted;
7+
8+
/**
9+
Helper function that allows me to iterate through sw pins in a loop
10+
by returning their actual value. (SW1 == swIndex(1))
11+
@example: swIndex(1) will return value 2 (check enum PIN)
12+
*/
13+
int swIndex(int i) {
14+
Clip(i, 1, NUM_SW);
15+
switch (i) {
16+
case 1:
17+
return (int)SW1;
18+
case 2:
19+
return (int)SW2;
20+
case 3:
21+
return (int)SW3;
22+
case 4:
23+
return (int)SW4;
24+
default:
25+
return -1; // not found
26+
}
27+
}
28+
/**
29+
Helper function that allows me to iterate through btn pins in a loop
30+
by returning their actual value. (BTN1 == btnIndex(1))
31+
@example: btnIndex(1) will return value 4 (check enum PIN)
32+
*/
33+
int btnIndex(int i) {
34+
Clip(i, 1, NUM_BTN);
35+
switch (i) {
36+
case 1:
37+
return (int)BTN1;
38+
case 2:
39+
return (int)BTN2;
40+
case 3:
41+
return (int)BTN3;
42+
case 4:
43+
return (int)BTN4;
44+
default:
45+
return -1; // not found
46+
}
47+
}
48+
49+
50+
/**
51+
Resets arduino chipset with specific options
52+
@params supported : RUN_SKETCH_ON_BOOT - resets chipset
53+
note: ENTER_BOOTLOADER_ON_BOOT is not yet implemented
54+
*/
55+
void executeSoftReset(uint32_t options)
56+
{
57+
if (options == RUN_SKETCH_ON_BOOT)
58+
{
59+
for (int i = 0; i < MAX_UC32_BASIC_IO_PIN; ++i) {
60+
m_bPins[i].store(false);
61+
}
62+
m_tpSimulationStarted = chrono::steady_clock::now();
63+
}
64+
else if (options == ENTER_BOOTLOADER_ON_BOOT) {
65+
// ...
66+
}
67+
}
68+
69+
70+
/**
71+
Sets pin to certain mode (INPUT, OUTPUT, INPUT_PULLUP)
72+
@note: INPUT_PULLUP support is not yet implemented.
73+
It doesn't do anything in this current state of simulation class.
74+
*/
75+
void pinMode(int pin, PIN_MODE mode) {
76+
pinMode((PIN)pin, mode);
77+
}
78+
void pinMode(PIN pin, PIN_MODE mode) {
79+
m_PinModes[(int)pin].store(mode);
80+
}
81+
82+
/**
83+
Sets given 'pin' to 'value' (LOW, HIGH)
84+
@note: 'pin' given in params must be previously set to OUTPUT before
85+
calling this method. If it wasn't set on OUTPUT mode method will throw exception.
86+
(exception won't be thrown if m_bLearningMode is set to off)
87+
*/
88+
void digitalWrite(int pin, int value) {
89+
/*if (pin < 0 || pin > MAX_UC32_BASIC_IO_PIN) {
90+
wchar_t errBuff[100];
91+
wsprintf(errBuff, L" \"int digitalWrite(%d)\" : argument \"%d\" is invalid!", pin, pin);
92+
exit(Error(errBuff));
93+
}
94+
else {*/
95+
digitalWrite((PIN)pin, value);
96+
//}
97+
}
98+
99+
100+
void digitalWrite(PIN pin, int value)
101+
{
102+
/*if (m_bLearningMode && m_PinModes[(int)pin].load() != PIN_MODE::OUTPUT)
103+
{
104+
exit(Error(L"error: you called digital write on pin that had no OUTPUT mode set!"));
105+
}*/
106+
m_bPins[(int)pin].store(value > 0);
107+
}
108+
109+
/**
110+
Reads the state of pin. (ON/OFF)
111+
*/
112+
int digitalRead(int pin) {
113+
if (pin < 0 || pin > MAX_UC32_BASIC_IO_PIN) {
114+
wchar_t errBuff[100];
115+
wsprintf(errBuff, L" \"int digitalRead(%d)\" : argument \"%d\" is invalid!", pin, pin);
116+
//exit(Error(errBuff));
117+
exit(EXIT_FAILURE);
118+
}
119+
else {
120+
return m_bPins[pin].load() == true ? HIGH : LOW;
121+
}
122+
}
123+
124+
int digitalRead(PIN pin) {
125+
return m_bPins[(int)pin].load() == true ? HIGH : LOW;
126+
}
127+
128+
void delay(unsigned int ms) {
129+
this_thread::sleep_for(chrono::milliseconds(ms));
130+
}
131+
132+
/**
133+
Returns number less then 'howbig'
134+
*/
135+
long random(long howbig)
136+
{
137+
if (howbig > 0) {
138+
return random(0, howbig - 1);
139+
}
140+
return 0;
141+
}
142+
143+
/**
144+
Returns number from closed interval [howsmall, howbig]
145+
*/
146+
long random(long howsmall, long howbig)
147+
{
148+
if (howsmall > howbig) {
149+
std::swap(howsmall, howbig);
150+
}
151+
static default_random_engine generator((unsigned int)chrono::system_clock::now().time_since_epoch().count());
152+
uniform_int_distribution<long> distribution(howsmall, howbig);
153+
return distribution(generator);
154+
}
155+
156+
/**
157+
Returns number of milliseconds passed from the start of the simulation
158+
*/
159+
long long millis()
160+
{
161+
162+
auto timePassed = chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - m_tpSimulationStarted);
163+
return timePassed.count();
164+
}
165+
166+
/**
167+
Swaps variables with XOR (withouth bonus variable)
168+
*/
169+
static void Swap(int &x, int &y) {
170+
x ^= y;
171+
y ^= x;
172+
x ^= y;
173+
}
174+
175+
/**
176+
Rounds 'value' to closed interval ['lowerBoundary', 'higherBoundary']
177+
*/
178+
static void Clip(int &value, int lowerBoundary, int higherBoundary) {
179+
if (lowerBoundary > higherBoundary) {
180+
Swap(lowerBoundary, higherBoundary);
181+
}
182+
if (value < lowerBoundary) {
183+
value = lowerBoundary;
184+
}
185+
else if (value > higherBoundary) {
186+
value = higherBoundary;
187+
}
188+
}

0 commit comments

Comments
 (0)