4 #pragma message "Compiling UARTBus host application with clock speed: " SX(F_CPU) 9 volatile uint8_t reset_flag;
11 void (*app_int_handler)(
void*);
13 void ubh_provide_dispatch_interrupt(
void* from)
15 if(NULL != app_int_handler)
17 app_int_handler(from);
36 uint8_t crc8(uint8_t* data, uint8_t length);
37 bool send_packet_priv(int16_t to, uint8_t ns, uint8_t* data, uint8_t size);
41 int neg = req->procPtr;
43 int size = rpc_append_size(args, parts);
49 uint8_t* d = (uint8_t*) alloca(size+neg);
51 for(uint8_t i=0;i<neg;++i)
53 d[i] = req->payload[i];
56 rpc_append_arr(d+neg, size, args, parts);
58 return send_packet_priv(req->from, 0, d, size+neg);
72 il_reply_arr(req, req->payload+req->procPtr, req->size - req->procPtr);
78 if(0 != (req->size - req->procPtr))
80 il_reply(req, 1, ubh_impl_set_user_led(req->payload[req->procPtr]));
126 il_reply(req, 1, rando());
129 void* RPC_FUNCTIONS_BASIC[] =
132 (
void*) rpc_basic_ping,
133 (
void*) rpc_basic_replay,
134 (
void*) rpc_basic_user_led,
135 (
void*) rpc_basic_get_time,
136 (
void*) rpc_basic_random
141 void rpc_bootloader_power_function(
struct rpc_request* req)
143 if(0 == (req->size - req->procPtr))
145 il_reply(req, 1, EINVAL);
149 switch(req->payload[req->procPtr])
151 case 0: ubh_impl_wdt_start(
false);
while(1){}
152 case 1:
asm (
"jmp 0x00");
158 void rpc_bootloader_get_var(
struct rpc_request* req)
160 if(0 == (req->size - req->procPtr))
162 il_reply(req, 1, EINVAL);
167 switch(req->payload[req->procPtr])
169 case 0: res = app_run;
break;
171 case 2: res = reset_flag;
break;
172 case 3: res = ubh_impl_has_app();
break;
173 default: res = 0;
break;
175 il_reply(req, 1, res);
179 void rpc_bootloader_set_var(
struct rpc_request* req)
181 if((req->size - req->procPtr) < 2)
183 il_reply(req, 1, EINVAL);
187 uint8_t val = req->payload[req->procPtr+1];
188 switch(req->payload[req->procPtr])
190 case 0: app_run = (bool) val;
break;
192 case 2: reset_flag = (uint8_t) val;
break;
201 void rpc_bootloader_read_code(
struct rpc_request* req)
203 uint8_t* data = req->payload+ req->procPtr;
204 uint16_t base = data[0] << 8 | data[1];
205 uint8_t s = (uint8_t) data[2];
211 uint8_t* rec = (uint8_t*) alloca(s+2);
216 uint8_t read = ubh_impl_read_code(base, s, &rec[2]);
218 il_reply_arr(req, rec, s+2);
223 uint8_t flash_stage = 0;
226 uint16_t flash_crnt_address = 0;
227 uint8_t* flash_tmp = NULL;
232 il_reply(req, 2, 0, flash_stage);
240 il_reply(req, 1, EALREADY);
243 flash_tmp = (uint8_t*) ubh_impl_go_upload_and_allocate_program_tmp_storage();
244 if(NULL == flash_tmp)
246 il_reply(req, 1, ENOMEM);
252 flash_crnt_address = (uint16_t) APP_START_ADDRESS;
261 il_reply(req, 2, ((flash_crnt_address >> 8) & 0xff), flash_crnt_address & 0xff);
265 void fill_flash(uint8_t *buf, uint16_t size)
267 uint8_t page_size = ubh_impl_get_program_page_size();
268 for(uint16_t i = 0;i<size;++i)
271 flash_tmp[flash_crnt_address % page_size] = buf[i];
272 ++flash_crnt_address;
275 if(0 == flash_crnt_address % page_size)
277 ubh_impl_write_program_page
279 (flash_crnt_address-1) & ~(page_size-1),
290 uint8_t* data = req->payload + req->procPtr;
291 uint8_t size = req->size - req->procPtr;
294 il_reply(req, 1, ENOTCONN);
300 il_reply(req, 1, EBADMSG);
304 if(flash_crnt_address < 0x1f00)
306 il_reply(req, 1, EFAULT);
310 if(data[0] != ((flash_crnt_address >> 8) & 0xff) || data[1] != (flash_crnt_address & 0xff))
312 il_reply(req, 1, ENXIO);
316 fill_flash(data+2, size-2);
318 il_reply(req, 3, 0, (flash_crnt_address >> 8) & 0xff, flash_crnt_address & 0xff);
326 il_reply(req, 1, EBADFD);
330 if(flash_crnt_address < 0x1f00)
332 il_reply(req, 1, EFAULT);
336 uint8_t page_size = ubh_impl_get_program_page_size();
339 if(0 != flash_crnt_address % page_size)
341 ubh_impl_write_program_page
343 flash_crnt_address & ~(page_size-1),
345 (flash_crnt_address & (page_size-1))
355 void* BOOTLOADER_FLASH_FUNCTIONS[] =
358 (
void*) blf_get_flash_stage,
359 (
void*) blf_start_flash,
360 (
void*) blf_get_next_addr,
361 (
void*) blf_push_code,
368 dispatch_function_chain(BOOTLOADER_FLASH_FUNCTIONS, req);
372 void* RPC_FUNCTIONS_BOOTLOADER[] =
375 (
void*) rpc_bootloader_power_function,
376 (
void*) rpc_bootloader_get_var,
377 (
void*) rpc_bootloader_set_var,
378 (
void*) rpc_bootloader_read_code,
379 (
void*) rpc_bootloader_flash,
384 void* RPC_FUNCTIONS_DEBUG[] =
394 void* RPC_FUNCTIONS_TRANSACTION[] =
402 void* RPC_NS_FUNCTIONS[] =
407 RPC_FUNCTIONS_BOOTLOADER,
409 RPC_FUNCTIONS_TRANSACTION,
414 dispatch_descriptor_chain(RPC_NS_FUNCTIONS, req);
421 uint8_t received_data[MAX_PACKET_SIZE];
424 uint8_t send_data[MAX_PACKET_SIZE];
426 void (*app_dispatch)(
struct rpc_request* req) = NULL;
437 #ifndef EXTERNAL_SEND_PACKET_PRIV 439 bool send_packet_priv(int16_t to, uint8_t NS, uint8_t* data, uint8_t size)
442 if(0 != send_size || size >= MAX_PACKET_SIZE-4)
450 if((add = ub_pack_16_value(to, send_data, MAX_PACKET_SIZE)) < 1)
457 if((add = ub_pack_16_value(BUS_ADDRESS, send_data+ep, MAX_PACKET_SIZE-ep)) < 1)
467 for(
int i=0;i<size;++i)
469 send_data[ep+i] = data[i];
471 send_data[ep+size] = crc8(send_data, ep+size);
472 send_size = size+ep+1;
474 #ifdef UBH_CALLBACK_ENQUEUE_PACKET 475 ubh_callback_enqueue_packet();
490 uint8_t ns = req->payload[req->procPtr];
492 if(req->from >= 0 && 0 < ns && ns < 32)
496 else if(NULL != app_dispatch && (32 <= ns || 0 == ns))
502 volatile bool received =
false;
504 void try_dispatch_received_packet()
514 if(crc8(received_data, received_ep-1) == received_data[received_ep-1])
523 req.reply = rpc_response;
524 if((add = ub_unpack_16_value(&req.to, received_data, received_ep-1)) < 1)
531 if((add = ub_unpack_16_value(&req.from, received_data+ep, received_ep-1-ep)) < 1)
538 req.size = received_ep-ep-1;
540 req.payload = (uint8_t*) alloca(req.size);
541 for(
int i=0;i<req.size;++i)
543 req.payload[i] = received_data[ep+i];
551 if(req.to < 1 || BUS_ADDRESS == req.to)
558 #ifdef UBH_DEBUG_BROADCAST_PACKET_WITH_BAD_CRC 561 received_data[received_ep] = crc8(received_data, received_ep-1);
562 send_packet_priv(-10, 0, received_data, received_ep+1);
574 bool may_send_packet()
576 return 0 == send_size;
579 uint8_t get_max_packet_size()
581 return MAX_PACKET_SIZE;
584 void register_packet_dispatch(
void (*addr)(
struct rpc_request* req))
599 ubh_impl_wdt_checkpoint();
601 ubh_impl_wdt_checkpoint();
613 (
void*) register_packet_dispatch,
614 (
void*) may_send_packet,
615 (
void*) send_packet_priv,
616 (
void*) get_max_packet_size,
623 __attribute__((section(
".host_table")))
void** getHostTable()
630 bool afterMicro(uint32_t* last_time, uint32_t timeMicro)
632 if(*last_time + timeMicro < micros())
634 *last_time = micros();
642 void busSignalOnline(uint8_t powerOnMode, uint8_t softMode)
647 send_packet_priv(-1, 0, (uint8_t*) p,
sizeof(p));
651 #define bb(x, y) x?(0x1 <<y):0 655 reset_flag = ubh_impl_get_power_state();
658 app_run = reset_flag != 8;
669 (ubh_impl_has_app()?1:0)
673 #ifdef DEBUG_TIME_AT_BOOT 676 ubh_impl_set_user_led(1);
677 uint32_t t = micros();
678 while(!afterMicro(&t, 1000000));
679 ubh_impl_set_user_led(0);
685 uint32_t t = micros();
686 while(!afterMicro(&t, 500000))
688 ubh_impl_wdt_checkpoint();
695 ubh_impl_wdt_start(
true);
701 if(app_run && ubh_impl_has_app())
703 ubh_impl_call_app(first);