uint getMaxCustomEventSize() { #define COUNT_CUSTOM_EVENT(eventType, dataType)\ if(maxCustomEventSize < sizeof(dataType)) maxCustomEventSize = sizeof(dataType); uint maxCustomEventSize = 0; CUSTOM_EVENTS(COUNT_CUSTOM_EVENT); DUMPHEX(maxCustomEventSize); maxCustomEventSize = (maxCustomEventSize+0x3) & (~0x3); // align to sizeof(int) return maxCustomEventSize; }
void Logging() { ///. Logging /// Logging is a useful technique to trace the flow of the code and examine results. In /// this tutorial we will be using logging extensively, so let us start tutorial with the /// explanation of logging. /// In debug mode and with default settings, macro `LOG` puts string into output log file. /// Log file is placed into 'config-directory', which by default is .exe directory in Win32 /// and ~/.upp/appname in POSIX. /// In TheIDE, you can access the log using 'Debug'/'View the log file Alt+L'. LOG("Hello world"); /// You can log values of various types, as long as they have `AsString` function defined /// You can chain values in single `LOG` using `operator<<`: int x = 123; LOG("Value of x is " << x); /// As it is very common to log a value of single variable, `DUMP` macro provides a useful /// shortcut, creating a log line with the variable name and value: DUMP(x); /// To get the value in hexadecimal code, you can use `LOGHEX` / `DUMPHEX` DUMPHEX(x); String h = "foo"; DUMPHEX(h); /// To log the value of a container (or generic Range), you can either use normal /// `LOG` / `DUMP`: Vector<int> v = { 1, 2, 3 }; DUMP(v); /// or you can use DUMPC for multi-line output: DUMPC(v); /// For maps, use DUMPM: VectorMap<int, String> map = { { 1, "one" }, { 2, "two" } }; DUMP(map); /// DUMPM(map); /// All normal `LOG`s are removed in release mode. If you need to log things in release mode, /// you need to use `LOG`/`DUMP` variant with '`R`' prefix (`RLOG`, `RDUMP`, `RDUMPHEX`...): RLOG("This will be logged in release mode too!"); /// Sort of opposite situation is when adding temporary `LOG`s to the code for debugging. In /// that case, '`D`' prefixed variants (`DLOG`, `DDUMP`, `DDUMPHEX`...) are handy - these cause /// compile error in release mode, so will not get forgotten in the code past the release: DLOG("This would not compile in release mode."); /// The last flavor of `LOG` you can encounter while reading U++ sources is the one prefixed /// with '`L`'. This one is not actually defined in U++ library and is just a convention. On /// the start of file, there is usually something like: #define LLOG(x) // DLOG(x) /// and by uncommenting the body part, you can activate the logging in that particular file. /// While logging to .log file is default, there are various ways how to affect logging, /// for example following line adjusts logging to output the log both to the console and /// .log file: #if 0 StdLogSetup(LOG_COUT|LOG_FILE); #endif /// }
int handle_packet_setup(struct ep_buf *ep) { #define REQUEST_TYPE ((1<<6)|(1<<5)) #define REQUEST_TYPE_STDARD 0 #define REQUEST_TYPE_CLASS ((0<<6)|(1<<5)) #define REQUEST_TYPE_VENDOR ((1<<6)|(0<<5)) #define REQUEST_TYPE_RESERVED ((1<<6)|(1<<5)) int send_len; //<---------------------- rt_uint8_t bmRequestType; rt_uint8_t bRequest; rt_uint16_t wValue; rt_uint16_t wIndex; rt_uint16_t wLength; bmRequestType = ep->buffer[0]; bRequest = ep->buffer[1]; wValue = net2host_16bit(&ep->buffer[2]); wIndex = net2host_16bit(&ep->buffer[4]); wLength = net2host_16bit(&ep->buffer[6]); DUMPHEX(ep->buffer, ep->len); if (bmRequestType & 0x80) { //IN switch (bmRequestType & REQUEST_TYPE) { case REQUEST_TYPE_STDARD: TRACE("USB input stdard reqeust:"); switch(bRequest) { case GET_STATUS : TRACE("get_status\n"); break; case CLEAR_FEATURE : TRACE("clear_feature\n"); break; case SET_FEATURE : TRACE("set_feature\n"); break; case SET_ADDRESS : TRACE("set_address\n"); break; case GET_DESCRIPTOR : { TRACE("get_descriptor: "); switch (wValue >> 8) // descriptor type; { case DESC_DEVICE: { TRACE("device_desc\n"); RT_ASSERT(send_len <= 64); //FIXME ep_send(0, DeviceDesc.desc, DeviceDesc.len); break; } case DESC_CONFIGURATION: TRACE("config_desc [%d]\n", ConfigDesc.len); //send_len = MIN(wLength, ConfigDesc.len); //RT_ASSERT(send_len <= 64); //FIXME //ep_send(0, ConfigDesc.desc, send_len); send_status.ep = 0; send_status.total = MIN(ConfigDesc.len, wLength); send_len = MIN(send_status.total, EP0_PACKET_SIZE); ep_send(0, ConfigDesc.desc, send_len); send_status.sent = send_len; send_status.buf =ConfigDesc.desc; break; case DESC_STRING: TRACE("string_desc:%d-->",(wValue & 0xFF)); if ((wValue & 0xFF) < 4) { static u8 str_buf[256]; static const struct descriptor * p; TRACE("%s\n", str_desc_name_table[wValue & 0xFF]); p = &StringDescTable[(wValue & 0xFF)]; memcpy(str_buf, p->desc, p->len); str_buf[0] = p->len; RT_ASSERT(p->len <= 64); ep_send(0, str_buf, p->len); } else { TRACE("-->bad argument!\n"); } break; case DESC_INTERFACE: TRACE("interface_desc\n"); break; case DESC_ENDPOINT: TRACE("endpoint_desc\n"); break; case DESC_REPORT: TRACE("report_desc [%d]\n", wIndex); //FIXME: refine code if (wIndex >= sizeof(ReportDesc)/sizeof(ReportDesc[0])) { TRACE("\t\t-->invalid number\n"); break; } send_status.ep = 0; send_status.total = ReportDesc[wIndex].len; send_len = MIN(ReportDesc[wIndex].len, EP0_PACKET_SIZE); ep_send(0, ReportDesc[wIndex].desc, send_len); send_status.sent = send_len; send_status.buf = ReportDesc[wIndex].desc; break; default: TRACE("<%d> unknown_desc!\n", wValue >> 8); break; } break; } case SET_DESCRIPTOR : TRACE("set_descriptor\n"); break; case GET_CONFIGURATION : TRACE("get_configuration\n"); break; case SET_CONFIGURATION : TRACE("set_configration\n"); break; case GET_INTERFACE : TRACE("get_interface\n"); break; case SET_INTERFACE : TRACE("set_interface\n"); break; case SYNCH_FRAME : TRACE("synch_frame\n"); break; default: TRACE("unkown!\n"); break; } break; case REQUEST_TYPE_CLASS: TRACE("USB input Class qeuset:"); switch(bRequest) { case GET_REPORT: TRACE("GET_REPORT\n"); break; case GET_IDLE: TRACE("GET_IDLE\n"); break; case GET_PROTOCOL: TRACE("GET_PROTOCOL\n"); break; case SET_REPORT: TRACE("SET_REPORT\n"); break; case SET_IDLE: TRACE("SET_IDLE\n"); break; case SET_PROTOCOL: TRACE("SET_PROTOCOL\n"); break; //for CDC class case CDC_GET_LINE_CODING: TRACE("CDC_GET_LINE_CODING [%d]\n", wLength); { #define UART_BSP 115200 static char vcom_line_coding[7] = { // dwDTERate 4Bytes UART_BSP & 0xFF, UART_BSP >> 8, UART_BSP >> 16, UART_BSP >> 24, 0, // bCharFormat 0, // bParityType 8, // bDataBits }; RT_ASSERT(wLength < EP0_PACKET_SIZE); ep_send(0, vcom_line_coding, wLength); } break; default: TRACE("bad request!\n"); break; } break; case REQUEST_TYPE_VENDOR: TRACE("USB input Vendor qeuset\n"); break; case REQUEST_TYPE_RESERVED: TRACE("USB input Reserved qeuset\n"); break; } } else { //OUT switch (bmRequestType & REQUEST_TYPE)