forked from yesco/esp-lisp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tlisp.ccc
222 lines (183 loc) · 6.42 KB
/
tlisp.ccc
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
/* Distributed under Mozilla Public Licence 2.0 */
/* https://www.mozilla.org/en-US/MPL/2.0/ */
/* 2016-08-14 (C) Jonas S Karlsson, [email protected] */
/* "test" driver for "unix" */
/* provides alt implementations to esplisp.c */
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <ctype.h>
#include "lisp.h"
#include "compat.h"
#include <dirent.h>
// dummies
void gpio_enable(int pin, int state) {}
void gpio_write(int pin, int value) {}
int gpio_read(int pin) { return 0; }
void interrupt_init (int pin, int changeType) {}
int getInterruptCount(int pin, int mode) { return -1; }
void checkInterrupts(int (*cb)(int pin, uint32 clicked, uint32 count, uint32 last)) {}
// memory profiling stuff
unsigned int lastClock = 0;
int lastMem = 0;
// TODO: use this! mcheck, mcheck_check_all, mcheck_pedantic, mprobe - heap consistency checking
// http://www.gnu.org/software/libc/manual/html_node/Heap-Consistency-Checking.html#Heap-Consistency-Checking
// http://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.html#Hooks-for-Malloc
// http://www.gnu.org/software/libc/manual/html_node/Obstacks.html#Obstacks
// http://stackoverflow.com/questions/10472929/gettotalmemory-allocation-in-c
// http://stackoverflow.com/questions/910172/track-c-memory-allocations
void print_memory_info(int verbose) {
report_allocs(verbose);
int clk = clock();
int ms = (int)((clk - lastClock) * 1000 / CLOCKS_PER_SEC);
int mem = 0;
if (verbose == 2)
printf("=== free=%u USED=%u bytes TIME=%d ms ===\n", mem, lastMem-mem, ms);
else if (verbose == 1) {
if (mem) printf("free=%u ", mem);
if (lastMem-mem) printf("USED=%u bytes ", lastMem-mem);
if (ms) printf("TIME=%d ms ", ms);
printf("\n");
}
lastClock = clk;
lastMem = mem;
}
int clock_ms() {
static const int clocks_per_ms = CLOCKS_PER_SEC / 1000;
return (int)(clock()) / clocks_per_ms;
}
unsigned int time_ms() {
struct timeval t;
gettimeofday(&t, NULL);
return t.tv_usec/1000 + t.tv_sec * 1000;
}
// TODO: make it run idle function...
int delay_ms(int ms) {
int start = time_ms();
usleep(ms * 1000);
return time_ms() - start;
}
unsigned int randomized() {
struct timeval t;
gettimeofday(&t, NULL);
return (unsigned int)(t.tv_usec * t.tv_sec);
}
void connect_wifi(char* ssid, char* password) { /* dummy */ }
// on linux, this is "non-blocking" as in it doesn't detect characters as typed
// but they are buffered, however, none are available until you press RETURN.
// http://cc.byexamples.com/2007/04/08/non-blocking-user-input-in-loop-without-ncurses/
// http://stackoverflow.com/questions/448944/c-non-blocking-keyboard-input
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <termios.h>
int nonblock_getch() {
static int first = 1;
static struct termios orig_termios;
void reset_terminal_mode() {
tcsetattr(0, TCSANOW, &orig_termios);
}
if (first) {
tcgetattr(0, &orig_termios);
atexit(reset_terminal_mode);
first = 0;
}
struct termios new_termios;
memcpy(&new_termios, &orig_termios, sizeof(new_termios));
// essentially, make it raw
cfmakeraw(&new_termios);
new_termios.c_iflag &= ~ICRNL;
new_termios.c_iflag &= ~IGNCR;
new_termios.c_oflag |= OPOST;
tcsetattr(0, TCSANOW, &new_termios);
// kbdhit
struct timeval tv = { 0L, 0L };
fd_set fds;
FD_ZERO(&fds);
FD_SET(0, &fds);
int r = 0;
// read if have
if (select(1, &fds, NULL, NULL, &tv)) {
unsigned char c;
if ((r = read(0, &c, sizeof(c))) > 0)
r = c;
}
return r;
}
//////////////////////////////////////////////////////////////////////
// simulate flash in RAM! (including EOR flash overwrite)
// TODO: verify "correctness" compared to esp8266 truth, but works othewise
//uint32 flash_memory[SPI_FLASH_SIZE_MB/SPI_FLASH_SEC_SIZE] = {0xffffffff};
//uint32 flash_memory[SPI_FLASH_SIZE_MB/SPI_FLASH_SEC_SIZE] = {0xbadbeef};
// easier to implement using char*! but maybe it should be uint32 to be more correct
unsigned char flash_memory[SPI_FLASH_SIZE_BYTES - FS_ADDRESS] = {0xff};
// TODO: store in file
int sdk_spi_flash_erase_sector(int sec) {
int addr = sec * SPI_FLASH_SEC_SIZE;
addr -= FS_ADDRESS;
int i;
for(i = 0; i < SPI_FLASH_SEC_SIZE; i++) {
flash_memory[addr + i] = 0xff;
//printf(" [ERASE: %x: %x] \n", addr + i, 0xff);
}
return SPI_FLASH_RESULT_OK;
}
int sdk_spi_flash_write(int addr, uint32* data, int len) {
len = (len + 3) & ~3; // TODO: if addr !% 4 then non correct?
unsigned char* dst = &flash_memory[addr - FS_ADDRESS];
unsigned char* src = (void*)data;
while (len-- > 0) {
unsigned char s = *src, d = *dst;
unsigned char v = ~(~*src++ | ~*dst); // or of 0s!
*dst++ = v;
printf(" [WRITE %x: %x ...] \n", dst - flash_memory - 1, v);
}
return SPI_FLASH_RESULT_OK;
}
int sdk_spi_flash_read(int addr, uint32* data, int len) {
len = (len + 3) & ~3; // TODO: if addr !% 4 then non correct?
unsigned char* src = &flash_memory[addr - FS_ADDRESS];
unsigned char* dst = (void*)data;
while (len-- > 0) {
uint32 d = *dst++ = *src++;
//printf(" [READ %x: %x] \n", src - flash_memory - 1, d);
}
return SPI_FLASH_RESULT_OK;
}
//////////////////////////////////////////////////////////////////////
void sig_handler(int signo) {
clear();
printf("\n%%received SIG%d\n", signo);
print_detailed_stack();
if (signo == 15 || signo == SIGINT) {
printf("\n\n%%received SIG%d... exiting...\n", signo);
exit(signo);
}
}
int main() {
if (signal(SIGTERM, sig_handler) == SIG_ERR) {
printf("\n%%Can't define SIGTERM handler!\nignoring...\n\n");
}
if (signal(SIGINT, sig_handler) == SIG_ERR) {
printf("\n%%Can't define SIGINTR handler!\nignoring...\n\n");
}
if (signal(SIGQUIT, sig_handler) == SIG_ERR) {
printf("\n%%Can't define SIGQUIT handler!\nignoring...\n\n");
}
if (signal(SIGUSR1, sig_handler) == SIG_ERR) {
printf("\n%%Can't define SIGUSR1 handler!\nignoring...\n\n");
}
if (signal(SIGTSTP, sig_handler) == SIG_ERR) {
printf("\n%%Can't define SIGTSTP handler!\nignoring...\n\n");
}
lastClock = clock();
lastMem = 0;
setbuf(stdin, NULL);
setbuf(stdout, NULL);
lisp env = lisp_init();
lisp_run(&env);
}