1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
import { buildHex } from './compile';
import { AVRRunner } from './execute';
import { formatTime } from './format-time';
import './index.css';
import { LED } from './led';
let editor: any;
const BLINK_CODE = `
// Green LED connected to LED_BUILTIN,
// Red LED connected to pin 12. Enjoy!
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(500);
}`.trim();
// Load Editor
declare var window: any;
declare var monaco: any;
window.require.config({
paths: { vs: 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.18.0/min/vs' }
});
window.require(['vs/editor/editor.main'], () => {
editor = monaco.editor.create(document.querySelector('.code-editor'), {
value: BLINK_CODE,
language: 'cpp',
minimap: { enabled: false }
});
});
// Set up LEDs
const leds = document.querySelector('.leds');
const led13 = new LED({ color: 'green', lightColor: '#80ff80' });
const led12 = new LED({ color: 'red', lightColor: '#ff8080' });
leds.appendChild(led13.el);
leds.appendChild(led12.el);
// Set up toolbar
let runner: AVRRunner;
const runButton = document.querySelector('#run-button');
runButton.addEventListener('click', compileAndRun);
const stopButton = document.querySelector('#stop-button');
stopButton.addEventListener('click', stopCode);
const statusLabel = document.querySelector('#status-label');
const compilerOutputText = document.querySelector('#compiler-output-text');
function executeProgram(hex: string) {
runner = new AVRRunner(hex);
const MHZ = 16000000;
// Hook to PORTB register
runner.portB.addListener((value) => {
const D12bit = 1 << 4;
const D13bit = 1 << 5;
led12.value = value & D12bit ? true : false;
led13.value = value & D13bit ? true : false;
});
runner.execute((cpu) => {
const time = formatTime(cpu.cycles / MHZ);
statusLabel.textContent = 'Simulation time: ' + time;
});
}
async function compileAndRun() {
led12.value = false;
led13.value = false;
runButton.setAttribute('disabled', '1');
try {
statusLabel.textContent = 'Compiling...';
const result = await buildHex(editor.getModel().getValue());
compilerOutputText.textContent = result.stderr || result.stdout;
if (result.hex) {
compilerOutputText.textContent += '\nProgram running...';
stopButton.removeAttribute('disabled');
executeProgram(result.hex);
} else {
runButton.removeAttribute('disabled');
}
} catch (err) {
runButton.removeAttribute('disabled');
alert('Failed: ' + err);
} finally {
statusLabel.textContent = '';
}
}
function stopCode() {
stopButton.setAttribute('disabled', '1');
runButton.removeAttribute('disabled');
if (runner) {
runner.stop();
runner = null;
}
}
|