started with nucleo support
[mTask.git] / int / nucleo-f767-blinky / src / main.c
1 #include <stdbool.h>
2 #include <stdint.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 #ifdef STM32F767xx
7 #include "stm32f7xx_hal.h"
8 #include "gpio.h"
9 #include "usart.h"
10 #else
11 #include <stdio.h>
12 #include <netdb.h>
13 #include <netinet/in.h>
14 #include <signal.h>
15 #include <sys/socket.h>
16 #include <sys/time.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19 #endif
20
21 #include "interpret.h"
22 #include "mTaskSymbols.h"
23 #include "sds.h"
24 #include "task.h"
25 #include "misc.h"
26
27 #define MSG_GET_TASK 't'
28 #define MSG_DEL_TASK 'd'
29 #define MSG_SDS_SPEC 's'
30 #define MSG_SDS_UPD 'u'
31
32 void _exit(int i){
33 while(1);
34 }
35
36 //Globals
37 #ifdef STM32F767xx
38 volatile char uartf = 0;
39 #else
40 struct timeval tv1;
41 int sock_fd = -1;
42 int fd = -1;
43 int *argc;
44 char **argv;
45 #endif
46 uint8_t bt;
47
48 #define SET_LED_RED GPIOB->BSRR = GPIO_PIN_14
49 #define RESET_LED_RED GPIOB->BSRR = GPIO_PIN_14 << 16
50
51 #define SET_LED_BLUE GPIOB->BSRR = GPIO_PIN_7
52 #define RESET_LED_BLUE GPIOB->BSRR = GPIO_PIN_7 << 16
53
54 #define SET_LED_GREEN GPIOB->BSRR = GPIO_PIN_0
55 #define RESET_LED_GREEN GPIOB->BSRR = GPIO_PIN_0 << 16
56
57 long millis() {
58 #ifdef STM32F767xx
59 return HAL_GetTick();
60 #else
61 if (gettimeofday(&tv1, NULL) == -1)
62 pdie("gettimeofday");
63 return tv1.tv_sec*1000 + tv1.tv_usec/1000;
64 #endif
65 }
66
67 bool input_available(){
68 #ifdef STM32F767xx
69 return true;
70 #else
71 struct timeval tv;
72 fd_set fds;
73 tv.tv_sec = 0;
74 tv.tv_usec = 0;
75 FD_ZERO(&fds);
76 FD_SET(fd, &fds);
77 if (select(fd+1, &fds, NULL, NULL, &tv) == -1)
78 pdie("select");
79 return FD_ISSET(fd, &fds);
80 #endif
81 }
82
83 uint8_t read_byte()
84 {
85 #ifdef STM32F767xx
86 HAL_UART_Receive(&huart3, &bt, 1, 1000);
87 return 0;
88 #else
89 read(fd, &bt, 1);
90 return bt;
91 #endif
92 }
93
94 void write_byte(uint8_t b)
95 {
96 #ifdef STM32F767xx
97 HAL_UART_Transmit_DMA(&huart3, &b, 1);
98 #else
99 write(fd, &b, 1);
100 #endif
101 }
102
103 void delay(int ms)
104 {
105 #ifdef STM32F767xx
106 HAL_Delay(ms);
107 #else
108 usleep(ms*1000);
109 #endif
110 }
111
112 #ifndef STM32F767xx
113 void killHandler(int i)
114 {
115 printf("%i caught, Bye...\n", i);
116 exit(1);
117 }
118 #endif
119
120 #ifdef STM32F767xx
121 void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle)
122 {
123 uartf=1;
124 }
125 #endif
126
127 void read_message()
128 {
129 //Find next task
130 uint8_t c = read_byte();
131 debug("Receiving input: %c\n", c);
132 switch(c){
133 case MSG_SDS_SPEC:
134 debug("Receiving an sds\n");
135 sds_register();
136 break;
137 case MSG_SDS_UPD:
138 debug("Receiving an sds\n");
139 //TODO do something with the return value
140 sds_update();
141 break;
142 case MSG_DEL_TASK:
143 debug("Receiving a delete task request\n");
144 task_delete();
145 break;
146 case MSG_GET_TASK:
147 debug("Receiving a task\n");
148 c = task_register();
149 break;
150 case '\n':
151 break;
152 default:
153 debug("Unknown message: %X\n", c);
154 }
155 }
156
157 void usage(FILE *o, char *arg0){
158 fprintf(o, "Usage: %s [opts]\n\nOptions\n"
159 "-p PORT Custom port number, default: 8123\n" , arg0);
160 }
161
162 void setup()
163 {
164 #ifdef STM32F767xx
165 #else
166 int port = 8123, opti = 1;
167 //Register signal handler
168 if(signal(SIGINT, killHandler) == SIG_ERR){
169 die("Couldn't register signal handler...\n");
170 }
171 if(signal(SIGTERM, killHandler) == SIG_ERR){
172 die("Couldn't register signal handler...\n");
173 }
174 //Command line arguments
175 while(opti < *argc){
176 if(strcmp((*argv)+opti, "-h") == 0){
177 usage(stdout, argv[0]);
178 exit(EXIT_SUCCESS);
179 } else if(strcmp(argv[opti], "-p") == 0 && opti+1<*argc){
180 port = atoi(argv[++opti]);
181 if(port < 1)
182 die("Port numbers are > 1\n");
183 } else {
184 usage(stderr, argv[0]);
185 exit(EXIT_FAILURE);
186 }
187 opti++;
188 }
189
190 //Open file descriptors
191 struct sockaddr_in sa;
192
193 memset(&sa, 0, sizeof(sa));
194 sa.sin_family = AF_INET;
195 sa.sin_addr.s_addr = INADDR_ANY;
196 sa.sin_port = htons(port);
197
198 if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
199 pdie("socket");
200 if(bind(sock_fd, (struct sockaddr*)&sa, sizeof(sa)) == -1)
201 pdie("bind");
202 if(listen(sock_fd, 10) == -1)
203 pdie("listen");
204
205 printf("Listening on %d\n", port);
206 fflush(stdout);
207 if((fd = accept(sock_fd, (struct sockaddr*)NULL, NULL)) == -1)
208 pdie("accept");
209 #endif
210
211 //Initialize systems
212 sds_init();
213 task_init();
214 }
215
216 void loop()
217 {
218 int ct;
219 long cyclestart;
220 struct task *curtask;
221 if(input_available())
222 read_message();
223 //Run tasks
224 cyclestart = millis();
225 for(ct = 0; ct<MAXTASKS; ct++){
226 //See whether the task is even in use
227 if((curtask = task_get(ct)) == NULL){
228 // debug("Task %d not implemented\n", ct);
229 continue;
230 }
231 //See whether the task interval has passed
232 if(cyclestart-curtask->lastrun < curtask->interval){
233 // debug("Task %d not scheduled\n", ct);
234 continue;
235 }
236 #ifdef DEBUG
237 printf("Current task to run: %d\n", ct);
238 getchar();
239 #endif
240 run_task(curtask);
241 }
242 debug("Waiting for 500ms\n");
243 delay(500);
244 debug("done waiting\n");
245 write_byte('\n');
246 }
247
248 #ifdef STM32F767xx
249 int main1(void)
250 #else
251 int main(int ac, char *av[])
252 #endif
253 {
254 #ifndef STM32F767xx
255 argc = &ac;
256 argv = av;
257 #endif
258 setup();
259
260 write_byte('\n');
261
262 while(true){
263 //Check for new tasks
264 loop();
265 }
266 return 0;
267 }