WEAK void backlight_thread(LCD_MODULE *lcd) { ALLOCATE_SIGNAL(SIG_BACKLIGHT_TASK); PIO_CfgOutput1(lcd->pins[BKLT_PIN_INDX]); while(1) { PIO_SetOutput(lcd->pins[BKLT_PIN_INDX]); if(tsk_wait_signal(SIG_BACKLIGHT_TASK, backlight_time )) continue; if(backlight_time) { // reduce the current consumption to 5% int t = 20; while(!tsk_test_signal(SIG_BACKLIGHT_TASK)) { PIO_SetOutput(lcd->pins[BKLT_PIN_INDX]); tsk_sleep(t); PIO_ClrOutput(lcd->pins[BKLT_PIN_INDX]); tsk_sleep(20 - t--); if(!t) t=1; } } tsk_get_signal(SIG_BACKLIGHT_TASK); } }
/** * Initiate a connection to a remote port and address with timeout * @param ip_adr * @param port * @param timeout * @return */ NET_CODE CSocket::connect(const char* ip_adr, unsigned int port, unsigned int timeout) { NET_CODE result = NET_IDLE; if(complete()) { src.as_charptr = (char*) ip_adr; dst.as_int = port; set_res_cmd(SOCK_CMD_CONNECT_ADR); if(timeout) { tsk_start_handle(); if(tsk_wait_signal(signal, timeout)) { res &= ~FLG_SIGNALED; if(res == RES_OK) result = NET_OK; else result = error; } else tsk_cancel(); } else { tsk_start_and_wait(); if(res == RES_OK) result = NET_OK; else result = error; } } return (result); }
/** * Time limited locked write * @param buf * @param l * @param time * @return */ RES_CODE CHandle::tsk_write_locked(const void * buf, unsigned int l, unsigned int time) { if(complete()) { //handle is idle and open len = l; set_res_cmd(CMD_WRITE|FLAG_LOCK); src.as_voidptr = (void*)buf; tsk_start_handle(); if(tsk_wait_signal(signal, time)) res &= ~FLG_SIGNALED; else tsk_cancel(); } return (res); }
/** * Time limited locked read * @param buf * @param l * @param time * @return */ RES_CODE CHandle::tsk_read_locked(void * buf, unsigned int l, unsigned int time) { if(complete()) { //handle is idle and open len = l; set_res_cmd((CMD_READ|FLAG_LOCK)); dst.as_voidptr = buf; tsk_start_handle(); if(tsk_wait_signal(signal, time)) res &= ~FLG_SIGNALED; else tsk_cancel(); } return (res); }
/** * Accept a connection request. * @param timeout * @return */ NET_CODE CSocket::accept(CSocket* new_sock, unsigned int timeout) { if(complete()) { dst.as_voidptr = new_sock; set_res_cmd(SOCK_CMD_ACCEPT); tsk_start_handle(); if(tsk_wait_signal(signal, timeout)) { res &= ~FLG_SIGNALED; } else tsk_cancel(); } return (res); }
NET_CODE esp8266_module::wifi_esp8266_init_net(CSocket * sock) { NET_CODE res; CSTRING cmd; wifi_AP_t AP; uint32_t sig = 0; bool found; res = wifi_send_cmd("+CIFSR", 50); for(int i =0; i < 5; i++) { found = false; cmd_state |= WIFI_CMD_STATE_ROW_STOP; res = wifi_send_cmd("+CWLAP", 15); cmd_state &= ~WIFI_CMD_STATE_ROW_STOP; do { if(sig) { process_input(sig, "+CWLAP"); res = cmd_state; } if (res >= WIFI_CMD_STATE_OK) break; if(res & WIFI_CMD_STATE_RETURNED) { cmd_state = res & ~WIFI_CMD_STATE_RETURNED; if(!found) { res = wifi_on_get_AP(this, sock, &AP); if(res == RES_OK) found = true; } row_start = 0; row_end = 0; } sig = tsk_resume_wait_signal(rcv_hnd.signal); } while(sig); if(cmd_state & WIFI_CMD_STATE_OK) { if(!found) res = NET_ERR_WIFI_NET_NAME; else res = NET_OK; break; } } if (res != NET_OK) return wifi_error(res); // If the wifi is already connected to a network different than the one // requested - return NET_IDLE - unavailable if (NET_OK == wifi_get_network_name(cmd)) { if (0 != strcmp(cmd.c_str(), AP.name.c_str())) { return NET_IDLE; } } cmd.format("+CWJAP=\"%s\",\"%s\"", AP.name.c_str(), AP.pass.c_str()); for(int i=0; i < 3; i++) { res = wifi_send_cmd(cmd.c_str(), 50); if (WIFI_CMD_STATE_OK == res) { res = wifi_send_cmd("+CIFSR", 50); if (WIFI_CMD_STATE_ROK == res) { connected_network_name = AP.name; return NET_OK; } break; } } return NET_ERR_WIFI_REGISTER; if (WIFI_CMD_STATE_OK == res) { res = wifi_send_cmd("+CIFSR", 50); if (WIFI_CMD_STATE_ROK == res) { connected_network_name = AP.name; wifi_send_cmd("+CIPSTART=\"TCP\",\"www.tmos-arm.com\",80", 50); //wifi_send_cmd("+CIPSTART=\"TCP\",\"192.168.147.100\",6112", 50); cmd.clear(); cmd.append("+CIPSEND="); cmd.appendf("%d", strlen(message) + 1); wifi_send_cmd(cmd.c_str(), 200); // make sure the handle is working if it is open while(rcv_hnd.res < FLG_BUSY) { process_input(0, NULL); } wifi_sleep(20); //(the recommended value is at least 20 ms) // make sure no URC is coming and the buf is empty if( cmd_state & WIFI_CMD_STATE_STARTED) { if (tsk_wait_signal(rcv_hnd.signal, 8192)) { do { process_input(rcv_hnd.signal, NULL); } while ( (cmd_state & WIFI_CMD_STATE_STARTED) && tsk_resume_wait_signal(rcv_hnd.signal) ); } } //start clean cmd_state &= (WIFI_CMD_STATE_ROW_STOP | WIFI_CMD_STATE_HND); row_start = row_end = 0; snd_hnd.tsk_write(message, strlen(message) + 1, WIFI_WRITE_TOT); return NET_OK; } } return wifi_net_error(res); }
void usbdrv_thread(USB_DRV_INFO drv_info) { CHandle helper; CHandle req_hnd; USBGenericRequest request; bool requested = false; unsigned int sig=0; ALLOCATE_SIGNAL(USB_DRIVER_SIG); helper.tsk_safe_open(drv_info->info.drv_index, 0); helper.tsk_start_command(NULL, 0); req_hnd.tsk_safe_open(drv_info->info.drv_index, USB_DRV_MODE(EPT_0, EPT_0)); while(1) { sig |= tsk_get_signal(SIGNAL_ANY); // 2) get waiting clients if(sig & helper.signal) { HANDLE client; sig ^= helper.signal; helper.res &= ~FLG_SIGNALED; client = (HANDLE)helper.dst.as_voidptr; if(client) { RES_CODE res; res = ((USB_API_FUNC)client->src.as_voidptr)(drv_info, client); if(res & FLG_SIGNALED) { tsk_HND_SET_STATUS(client, res); } } helper.tsk_start_command(NULL, 0); } if(sig & req_hnd.signal) { sig ^= req_hnd.signal; req_hnd.res &= ~FLG_SIGNALED; #if USB_ENABLE_DEVICE TRACE1_USB(" | req:"); if(req_hnd.res == RES_OK) { drv_info->drv_data->device.RequestHandler(drv_info, &request, &req_hnd); } else #endif { TRACE_USB(" res %x", req_hnd.res); tsk_sleep(5); } requested = false; } if(!requested) { #if USB_ENABLE_HOST if(sig == USB_DRIVER_SIG) { if(drv_info->drv_data->otg_h_sig & OTG_H_SIG_CON) { do { sig = atomic_fetch((volatile int*)&drv_info->drv_data->otg_h_sig); sig &= ~OTG_H_SIG_CON; } while(atomic_store((volatile int*)&drv_info->drv_data->otg_h_sig, sig)); //wait 1s for connect for(int retries =0; retries <10; ++retries) { if(drv_info->drv_data->otg_flags & USB_OTG_FLG_HOST_RST) break; sig = tsk_wait_signal(USB_DRIVER_SIG, 100); if (sig) break; } if( !(drv_info->drv_data->otg_h_sig & OTG_H_SIG_RST)) { usb_api_otg_off(drv_info, NULL); } } if(drv_info->drv_data->otg_h_sig & OTG_H_SIG_RST) { do { sig = atomic_fetch((volatile int*)&drv_info->drv_data->otg_h_sig); sig &= ~OTG_H_SIG_RST; } while(atomic_store((volatile int*)&drv_info->drv_data->otg_h_sig, sig)); if(drv_info->drv_data->otg_flags & USB_OTG_FLG_HOST_RST) { RES_CODE res; // Reset requested for(int retries =0; retries <3; ++retries) { tsk_sleep(100); res = usb_host_reset_bus(drv_info, &req_hnd); if( res == RES_OK) break; } // if(res != RES_OK) // usb_api_otg_off(drv_info, NULL); } } if(drv_info->drv_data->otg_h_sig & OTG_H_SIG_RESUME) { do { sig = atomic_fetch((volatile int*)&drv_info->drv_data->otg_h_sig); sig &= ~OTG_H_SIG_RESUME; } while(atomic_store((volatile int*)&drv_info->drv_data->otg_h_sig, sig)); usb_hal_host_resume(drv_info); } sig = 0; } if(drv_info->drv_data->otg_flags & USB_OTG_FLG_DEV_OK) { req_hnd.mode.as_ushort[1] = drv_info->drv_data->drv_state_cnt; #endif req_hnd.tsk_start_read(&request, 8); TRACE_USB_NAME(drv_info); TRACE1_USB(" st req:"); requested = true; #if USB_ENABLE_HOST } #endif } } }
void gui_thread(GUI_DRIVER_INFO* drv_info) { unsigned int res, tmp, redraw; WINDOW win; WINDOW top; WINDOW desktop; //main_dlg; CHandle key_hnd; CHandle gui_hnd; //prevent these signals not to be used from task handles ALLOCATE_SIGNAL(SIG_GUI_TASK); //wait for static constructors (lcd object) while(!detect_displays(drv_info)) tsk_sleep(10); // start desktop while( !(desktop = tsk_new_window(maindlg_cb)) ) { tsk_sleep(10); } desktop->next = NULL; top = desktop; desktop->rect.x1 = drv_info->lcd[0]->size_x; desktop->rect.y1 = drv_info->lcd[0]->size_y; for(int i=0; i<GUI_DISPLAYS; i++) { if(drv_info->lcd[i]) { #if GUI_DISPLAYS > 1 desktop->displays |= (1<<i); #endif drv_info->lcd[i]->lcd_init((GUI_CB)splashdlg_cb); } } tsk_sleep(3000); init_main_menu(); // start key handle key_hnd.tsk_safe_open(KEY_DRV_INDX, 0); key_hnd.src.as_int = 0; key_hnd.tsk_start_read(&key_hnd.src.as_int, 1); // start gui handle gui_hnd.tsk_safe_open(GUI_DRV_INDX, 0); //mode = 1 - control handle gui_hnd.tsk_start_read(NULL, 0); for(;;) { res = tsk_wait_signal(-1u, 1000 - (CURRENT_TIME %1000)); redraw = res>>8;; if(!res) redraw = 0xFF; // 1) get waiting objects if(res & gui_hnd.signal) { drv_info->lcd[0]->backlight_signal(); gui_hnd.res &= ~FLG_SIGNALED; win = (WINDOW)gui_hnd.dst.as_voidptr; if(win) { top->next = win; do { top = (WINDOW)top->next; top->rect.x1 = desktop->rect.x1; top->rect.y1 = desktop->rect.y1; top->callback(NULL , WM_INIT); #if GUI_DISPLAYS > 1 redraw |= top->displays; #endif } while( top->next ); } gui_hnd.tsk_start_read(NULL, 0); #if GUI_DISPLAYS == 1 redraw |= 1; #endif } // 2) check keyboard if(res & key_hnd.signal) { drv_info->lcd[0]->backlight_signal(); key_hnd.res &= ~FLG_SIGNALED; //send to top tmp = top->callback(key_hnd.src.as_int , WM_KEY); if(tmp & FLG_BUSY) //FLG_BUSY returned to redraw { tmp ^= FLG_BUSY; #if GUI_DISPLAYS > 1 redraw |= top->displays; #else redraw |= 1; #endif } top->mode1 = tmp; key_hnd.tsk_start_read(&key_hnd.src.as_int, 1); } // 3) command loop top = NULL; win = desktop; do { // check for pending commands if(win->mode0 & FLG_OK) { locked_clr_byte(&win->mode0, FLG_OK); tmp = win->callback(win->dst.as_int, WM_USER); if(tmp & FLG_BUSY) //FLG_BUSY returned to redraw { tmp ^= FLG_BUSY; #if GUI_DISPLAYS > 1 redraw |= win->displays; #else redraw |= 1; #endif } win->mode1 |= tmp; } //check for complete (close object) if(top && ((win->mode0 | win->mode1) & FLG_SIGNALED) ) { top->next = win->next; #if GUI_DISPLAYS > 1 redraw |= win->displays; #else redraw |= 1; #endif usr_HND_SET_STATUS(win, win->mode1 | FLG_SIGNALED); win = (WINDOW)top->next; } else { top = win; win = (WINDOW)win->next; } } while (win ); // 3) draw loop for(int i=0; i<GUI_DISPLAYS; i++) { if( (redraw & (1<<i)) && drv_info->lcd[i]) { drv_info->lcd[i]->redraw_screen(desktop); } } } }