static void MENU_update(void) { static const far rom char *values[] = { (ROMCHAR)"OFF", (ROMCHAR)"ON", }; static const far rom char *formats[] = { (ROMCHAR)" STEREO ", (ROMCHAR)" BASS BOOST ", (ROMCHAR)" RDS ", (ROMCHAR)" ABOUT " }; memset(menu[0].title, ' ', 16); memset(menu[1].title, ' ', 16); memset(menu[2].title, ' ', 16); strcpypgm2ram(menu[0].title, formats[0]); strcpypgm2ram(menu[1].title, formats[1]); strcpypgm2ram(menu[2].title, formats[2]); strcpypgm2ram(menu[3].title, formats[3]); strcatpgm2ram(menu[0].title, values[!(mem_data->flags & RDA_FLAG_MONO)]); strcatpgm2ram(menu[1].title, values[(mem_data->flags & RDA_FLAG_BASS) == RDA_FLAG_BASS]); strcatpgm2ram(menu[2].title, values[(mem_data->flags & RDA_FLAG_RDS) == RDA_FLAG_RDS]); }
void Keyboard(void) { static char* c = g_tx_queue; if (SwitchIsPressed()) { g_tx_queue[0] = 0; if (g_config_mode) { ++g_lgtm_strings_idx; if (g_lgtm_strings_idx >= NUM_LGTM_STRINGS) g_lgtm_strings_idx = 0; EEADR = 0; EEDATA = g_lgtm_strings_idx; EECON1bits.EEPGD = 0; EECON1bits.CFGS = 0; EECON1bits.WREN = 1; EECON2 = 0x55; EECON2 = 0xAA; EECON1bits.WR = 1; strcatpgm2ram(g_tx_queue, CFG_MODE_STR); } strcatpgm2ram(g_tx_queue, LGTM_STRINGS[g_lgtm_strings_idx]); c = g_tx_queue; } // Check if the IN endpoint is not busy, and if it isn't check if we want to // send keystroke data to the host. if (!HIDTxHandleBusy(g_usb_handle_in)) { memset(hid_report_in, 0, sizeof(hid_report_in)); if (*c) { HIDKey key; key = AsciiToHid(*c); ++c; hid_report_in[0] = key.modifier; hid_report_in[2] = key.code; } // Send the 8 byte packet over USB to the host. g_usb_handle_in = HIDTxPacket(HID_EP, (BYTE*)hid_report_in, 0x08); } // Check if any data was sent from the PC to the keyboard device. Report // descriptor allows // host to send 1 byte of data. Bits 0-4 are LED states, bits 5-7 are unused // pad bits. // The host can potentially send this OUT report data through the HID OUT // endpoint (EP1 OUT), // or, alternatively, the host may try to send LED state information by // sending a // SET_REPORT control transfer on EP0. See the USBHIDCBSetReportHandler() // function. if (!HIDRxHandleBusy(g_usb_handle_out)) { // Do something useful with the data now. Data is in the OutBuffer[0]. // Num Lock LED state is in Bit0. // if (hid_report_out[0] & 0x01) // Make LED1 and LED2 match Num Lock // state. g_usb_handle_out = HIDRxPacket(HID_EP, (BYTE*)&hid_report_out, 1); } return; }
void net_msg_alert(void) { char *p; delay100(2); net_msg_start(); strcpypgm2ram(net_scratchpad,(char const rom far*)"MP-0 PA"); switch (car_chargemode) { case 0x00: strcatpgm2ram(net_scratchpad,(char const rom far *)"Standard - "); // Charge Mode Standard break; case 0x01: strcatpgm2ram(net_scratchpad,(char const rom far *)"Storage - "); // Storage break; case 0x03: strcatpgm2ram(net_scratchpad,(char const rom far *)"Range - "); // Range break; case 0x04: strcatpgm2ram(net_scratchpad,(char const rom far *)"Performance - "); // Performance } switch (car_chargestate) { case 0x01: strcatpgm2ram(net_scratchpad,(char const rom far *)"Charging"); // Charge State Charging break; case 0x02: strcatpgm2ram(net_scratchpad,(char const rom far *)"Charging, Topping off"); // Topping off break; case 0x04: strcatpgm2ram(net_scratchpad,(char const rom far *)"Charging Done"); // Done break; default: strcatpgm2ram(net_scratchpad,(char const rom far *)"Charging Stopped"); // Stopped } strcatpgm2ram(net_scratchpad,(char const rom far *)"\rIdeal Range: "); // Ideal Range p = par_get(PARAM_MILESKM); if (*p == 'M') // Kmh or Miles sprintf(net_msg_scratchpad, (rom far char*)"%u mi", car_idealrange); // Miles else sprintf(net_msg_scratchpad, (rom far char*)"%u Km", (unsigned int) ((float) car_idealrange * 1.609)); // Kmh strcat((char*)net_scratchpad,net_msg_scratchpad); strcatpgm2ram(net_scratchpad,(char const rom far *)" SOC: "); sprintf(net_msg_scratchpad, (rom far char*)"%u%%", car_SOC); // 95% strcat(net_scratchpad,net_msg_scratchpad); net_msg_encode_puts(); net_msg_send(); }
void net_msg_tpms(void) { char k; long p; int b,a; if ((car_tpms_t[0]==0)&&(car_tpms_t[1]==0)&& (car_tpms_t[2]==0)&&(car_tpms_t[3]==0)) return; // No TPMS, no report strcpypgm2ram(net_scratchpad,(char const rom far*)"MP-0 W"); for (k=0;k<4;k++) { if (car_tpms_t[k]>0) { p = (long)((float)car_tpms_p[k]/0.2755); b = (p / 10); a = (p % 10); sprintf(net_msg_scratchpad, (rom far char*)"%d.%d,%d,", b,a,(int)(car_tpms_t[k]-40)); strcat(net_scratchpad,net_msg_scratchpad); } else { strcatpgm2ram(net_scratchpad, (rom far char*)"0,0,"); } } net_scratchpad[strlen(net_scratchpad)-1] = 0; // Remove trailing ',' net_msg_encode_puts(); }
void net_msg_stat(void) { char *p; strcpypgm2ram(net_scratchpad,(char const rom far*)"MP-0 S"); p = par_get(PARAM_MILESKM); sprintf(net_msg_scratchpad,(rom far char*)"%d,%s,%d,%d,",car_SOC,p,car_linevoltage,car_chargecurrent); strcat(net_scratchpad,net_msg_scratchpad); switch (car_chargestate) { case 0x01: strcatpgm2ram(net_scratchpad,(char const rom far*)"charging,"); // Charge State Charging break; case 0x02: strcatpgm2ram(net_scratchpad,(char const rom far*)"topoff,"); // Topping off break; case 0x04: strcatpgm2ram(net_scratchpad,(char const rom far*)"done,"); // Done break; default: strcatpgm2ram(net_scratchpad,(char const rom far*)"stopped,"); // Stopped } switch (car_chargemode) { case 0x00: strcatpgm2ram(net_scratchpad,(char const rom far*)"standard,"); // Charge Mode Standard break; case 0x01: strcatpgm2ram(net_scratchpad,(char const rom far*)"storage,"); // Storage break; case 0x03: strcatpgm2ram(net_scratchpad,(char const rom far*)"range,"); // Range break; case 0x04: strcatpgm2ram(net_scratchpad,(char const rom far*)"performance,"); // Performance default: strcatpgm2ram(net_scratchpad,(char const rom far*)","); } if (*p == 'M') // Kmh or Miles sprintf(net_msg_scratchpad, (rom far char*)"%u,", car_idealrange); else sprintf(net_msg_scratchpad, (rom far char*)"%u,", (unsigned int) ((float) car_idealrange * 1.609)); strcat(net_scratchpad,net_msg_scratchpad); if (*p == 'M') // Kmh or Miles sprintf(net_msg_scratchpad, (rom far char*)"%u", car_estrange); else sprintf(net_msg_scratchpad, (rom far char*)"%u", (unsigned int) ((float) car_estrange * 1.609)); strcat(net_scratchpad,net_msg_scratchpad); net_msg_encode_puts(); }
void net_msg_forward_sms(char *caller, char *SMS) { //Server not ready, stop sending //TODO: store this message inside buffer, resend it when server is connected if ((net_msg_serverok == 0)||(net_msg_sendpending)>0) return; delay100(2); net_msg_start(); strcpypgm2ram(net_scratchpad,(char const rom far*)"MP-0 PA"); strcatpgm2ram(net_scratchpad,(char const rom far*)"SMS FROM: "); strcat(net_scratchpad, caller); strcatpgm2ram(net_scratchpad,(char const rom far*)" - MSG: "); SMS[70]=0; // Hacky limit on the max size of an SMS forwarded strcat(net_scratchpad, SMS); net_msg_encode_puts(); net_msg_send(); }
// Receive a NET msg from the OVMS server void net_msg_in(char* msg) { int k; if (net_msg_serverok == 0) { if (memcmppgm2ram(msg, (char const rom far*)"MP-S 0 ", 7) == 0) { net_msg_server_welcome(msg+7); } return; // otherwise ignore it } // Ok, we've got an encrypted message waiting for work. // The following is a nasty hack because base64decode doesn't like incoming // messages of length divisible by 4, and is really expecting a CRLF // terminated string, so we give it one... strcatpgm2ram(msg,(char const rom far*)"\r\n"); k = base64decode(msg,net_scratchpad); RC4_crypt(&rx_crypto1, &rx_crypto2, net_scratchpad, k); if (memcmppgm2ram(net_scratchpad, (char const rom far*)"MP-0 ", 5) == 0) { msg = net_scratchpad+5; switch (*msg) { case 'A': // PING strcpypgm2ram(net_scratchpad,(char const rom far*)"MP-0 a"); if (net_msg_sendpending==0) { net_msg_start(); net_msg_encode_puts(); net_msg_send(); } break; case 'Z': // PEER connection if (msg[1] != '0') { net_apps_connected = 1; if (net_msg_sendpending==0) { net_msg_start(); net_msg_stat(); net_msg_gps(); net_msg_tpms(); net_msg_firmware(); net_msg_environment(); net_msg_send(); } } else { net_apps_connected = 0; } break; } } }
void net_msg_gps(void) { strcpypgm2ram(net_scratchpad,(char const rom far*)"MP-0 L"); format_latlon(car_latitude,net_msg_scratchpad); strcat(net_scratchpad,net_msg_scratchpad); strcatpgm2ram(net_scratchpad,(char const rom far*)","); format_latlon(car_longitude,net_msg_scratchpad); strcat(net_scratchpad,net_msg_scratchpad); net_msg_encode_puts(); }
// Receive a NET msg from the OVMS server void net_msg_in(char* msg) { int k; char s; if (net_msg_serverok == 0) { if (memcmppgm2ram(msg, (char const rom far*)"MP-S 0 ", 7) == 0) { net_msg_server_welcome(msg+7); net_granular_tick = 3590; // Nasty hack to force a status transmission in 10 seconds } return; // otherwise ignore it } // Ok, we've got an encrypted message waiting for work. // The following is a nasty hack because base64decode doesn't like incoming // messages of length divisible by 4, and is really expecting a CRLF // terminated string, so we give it one... CHECKPOINT(0x40) if (((strlen(msg)*4)/3) >= (NET_BUF_MAX-3)) { // Quick exit to reset link if incoming message is too big net_state_enter(NET_STATE_DONETINIT); return; } strcatpgm2ram(msg,(char const rom far*)"\r\n"); k = base64decode(msg,net_scratchpad); CHECKPOINT(0x41) RC4_crypt(&rx_crypto1, &rx_crypto2, net_scratchpad, k); if (memcmppgm2ram(net_scratchpad, (char const rom far*)"MP-0 ", 5) != 0) { net_state_enter(NET_STATE_DONETINIT); return; } msg = net_scratchpad+5; if ((*msg == 'E')&&(msg[1]=='M')) { // A paranoid-mode message from the server (or, more specifically, app) // The following is a nasty hack because base64decode doesn't like incoming // messages of length divisible by 4, and is really expecting a CRLF // terminated string, so we give it one... msg += 2; // Now pointing to the code just before encrypted paranoid message strcatpgm2ram(msg,(char const rom far*)"\r\n"); k = base64decode(msg+1,net_msg_scratchpad+1); RC4_setup(&pm_crypto1, &pm_crypto2, pdigest, MD5_SIZE); for (k=0;k<1024;k++) { net_scratchpad[0] = 0; RC4_crypt(&pm_crypto1, &pm_crypto2, net_scratchpad, 1); } RC4_crypt(&pm_crypto1, &pm_crypto2, net_msg_scratchpad+1, k); net_msg_scratchpad[0] = *msg; // The code // The message is now out of paranoid mode... msg = net_msg_scratchpad; } CHECKPOINT(0x42) switch (*msg) { case 'A': // PING strcpypgm2ram(net_scratchpad,(char const rom far*)"MP-0 a"); if (net_msg_sendpending==0) { net_msg_start(); net_msg_encode_puts(); net_msg_send(); } break; case 'Z': // PEER connection if (msg[1] != '0') { net_apps_connected = 1; if (net_msg_sendpending==0) { net_msg_start(); net_msgp_stat(0); net_msgp_gps(0); net_msgp_tpms(0); net_msgp_firmware(0); net_msgp_environment(0); net_msg_send(); } } else { net_apps_connected = 0; } break; case 'h': // Historical data acknowledgement #ifdef OVMS_LOGGINGMODULE logging_ack(atoi(msg+1)); #endif // #ifdef OVMS_LOGGINGMODULE break; case 'C': // COMMAND net_msg_cmd_in(msg+1); if (net_msg_sendpending==0) net_msg_cmd_do(); break; } }
/***************************************************************************** Function: void PingDemo(void) Summary: Demonstrates use of the ICMP (Ping) client. Description: This function implements a simple ICMP client. The function is called periodically by the stack, and it checks if BUTTON0 has been pressed. If the button is pressed, the function sends an ICMP Echo Request (Ping) to a Microchip web server. The round trip time is displayed on the UART when the response is received. This function can be used as a model for applications requiring Ping capabilities to check if a host is reachable. Precondition: TCP is initialized. Parameters: None Returns: None ***************************************************************************/ void PingDemo(void) { static enum { SM_HOME = 0, SM_GET_ICMP_RESPONSE } PingState = SM_HOME; static uint32_t Timer; int32_t ret; switch(PingState) { case SM_HOME: // Send a ping request out if the user pushes BUTTON0 (right-most one) if(BUTTON0_IO == 0u) { // Don't ping flood: wait at least 1 second between ping requests if(TickGet() - Timer > 1ul*TICK_SECOND) { // Obtain ownership of the ICMP module if(!ICMPBeginUsage()) break; // Update anti-ping flood timer Timer = TickGet(); // Send ICMP echo request #if defined(STACK_USE_DNS) ICMPSendPingToHostROM((ROM uint8_t*)HOST_TO_PING); #else ICMPSendPing(AppConfig.MyGateway.Val); #endif PingState = SM_GET_ICMP_RESPONSE; } } break; case SM_GET_ICMP_RESPONSE: // Get the status of the ICMP module ret = ICMPGetReply(); if(ret == -2) { // Do nothing: still waiting for echo break; } else if(ret == -1) { // Request timed out #if defined(USE_LCD) memcpypgm2ram((void*)&LCDText[16], (ROM void *)"Ping timed out", 15); LCDUpdate(); #endif PingState = SM_HOME; } else if(ret == -3) { // DNS address not resolvable #if defined(USE_LCD) memcpypgm2ram((void*)&LCDText[16], (ROM void *)"Can't resolve IP", 16); LCDUpdate(); #endif PingState = SM_HOME; } else { // Echo received. Time elapsed is stored in ret (Tick units). #if defined(USE_LCD) memcpypgm2ram((void*)&LCDText[16], (ROM void *)"Reply: ", 7); uitoa((uint16_t)TickConvertToMilliseconds((uint32_t)ret), &LCDText[16+7]); strcatpgm2ram((char*)&LCDText[16+7], "ms"); LCDUpdate(); #endif PingState = SM_HOME; } // Finished with the ICMP module, release it so other apps can begin using it ICMPEndUsage(); break; } }
Zone_States CheckEOL (int ZoneID, WORD* ADval) { char AN0String[7]; char DebugTemp[7]; int PlexerDevice, BinaryValue; // Disable all analogue multiplexer PLEXERA_S_IO = 1; // High = disabled PLEXERB_S_IO = 1; PLEXERC_S_IO = 1; // Select the analogue multiplexer PlexerDevice = ZoneID / 8; BinaryValue = ZoneID - ((ZoneID / 8) * 8); // The value can now be expressed as a 3 bit value if (PlexerDevice == 0) { PLEXERA_S_IO = 0; //enable this device PLEXERA_2_IO = ((BinaryValue / 4 > 0)?TRUE:FALSE); BinaryValue -= (BinaryValue / 4) * 4; PLEXERA_1_IO = ((BinaryValue / 2 > 0)?TRUE:FALSE); BinaryValue -= (BinaryValue / 2) * 2; PLEXERA_0_IO = ((BinaryValue > 0)?TRUE:FALSE); } // PlexerDevice ==0 else if (PlexerDevice == 1) { PLEXERB_S_IO = 0; //enable this device PLEXERB_2_IO = BinaryValue / 4; BinaryValue -= (BinaryValue / 4) * 4; PLEXERB_1_IO = BinaryValue / 2; BinaryValue -= (BinaryValue / 2) * 2; PLEXERB_0_IO = BinaryValue; } // PlexerDevice == 1 else if (PlexerDevice == 2) { PLEXERC_S_IO = 0; //enable this device PLEXERC_2_IO = BinaryValue / 4; BinaryValue -= (BinaryValue / 4) * 4; PLEXERC_1_IO = BinaryValue / 2; BinaryValue -= (BinaryValue / 2) * 2; PLEXERC_0_IO = BinaryValue; } // PlexerDevice == 2 else { #if defined(DEBUG_UART) putrsUART((ROM char*)" !!! CheckEOL is out of range !!!!! "); #endif *ADval = 0; return StateNormal; } //60 ns delay is required for the Multiplexer to swith analogue channels //Nop();Nop();Nop();Nop();Nop(); // Select A/D channel AN4 ADCON0 = 0b00010000; // ADON = On(1), GO/DONE = Idle (0), AN4 selected (0100), not used (0), calibration off (0) ADCON0bits.ADON = 1; ADCON0bits.GO = 1; // Wait until A/D conversion is done while(ADCON0bits.GO); // Convert 10-bit value into ASCII string *ADval = (WORD)ADRES; uitoa(*ADval, AN0String); if (ZoneID == 1) { memset(LCDText, '\0', 32); if (strlen(AN0String) < (unsigned int)4 ) strcatpgm2ram(AN0String, (rom char *) " "); if (strlen(AN0String) < (unsigned int)4 ) strcatpgm2ram(AN0String, (rom char *) " "); if (strlen(AN0String) < (unsigned int)4 ) strcatpgm2ram(AN0String, (rom char *) " "); strcat(LCDText, AN0String); strcatpgm2ram(LCDText, (rom char *) "->"); } if ( (*ADval >= (WORD)(EOLNORMAL - EOLTOLERANCE)) && (*ADval <= (WORD)(EOLNORMAL + EOLTOLERANCE))) { if (ZoneID == 1) { strcatpgm2ram(LCDText, (rom char *) "Normal"); LCDUpdate(); } // Need to consider if the zone is Normaly Open or Normaly Closed if (ZoneConfig[ZoneID].IsNO == FALSE) return StateNormal; else return StateTrigger; } else if ( (*ADval >= (WORD)(EOLTRIGGER - EOLTOLERANCE)) && (*ADval <= (WORD)(EOLTRIGGER + EOLTOLERANCE))) { if (ZoneID == 1) { strcatpgm2ram(LCDText, (rom char *) "Trigger"); LCDUpdate(); } // Need to consider if the zone is Normaly Open or Normaly Closed if (ZoneConfig[ZoneID].IsNO == FALSE) return StateTrigger; else return StateNormal; } else { if (ZoneID == 1) { strcatpgm2ram(LCDText, (rom char *) "Tamper"); LCDUpdate(); } return StateTamper; } } // CheckEOL
void main(void) { static nabto_main_setup* nms; static char versionString[NABTO_DEVICE_VERSION_MAX_SIZE]; static char idString[NABTO_DEVICE_NAME_MAX_SIZE]; #if NABTO_ENABLE_UCRYPTO static const far rom uint8_t dummySharedSecret[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; static const far rom uint8_t* sharedSecret; #endif // <editor-fold desc="Load information from bootloader and application data areas."> // Clear the global TCP/IP data structure and load it with the boards unique preprogrammed MAC address. memset((void*) &AppConfig, 0x00, sizeof (AppConfig)); memcpypgm2ram(&AppConfig.MyMACAddr, (const __ROM uint8_t*) bootloaderData.version1.mac, 6); if(bootloaderData.base.bootloaderDataVersion == 1) { strcpypgm2ram(idString, (const far rom char*) bootloaderData.version1.serialNumber); strcatpgm2ram(idString, ".nabduino.net"); #if NABTO_ENABLE_UCRYPTO // sharedSecret = applicationData.sharedSecret; // the old pre-bootloader-version-2 way of storing the shared secret - obsolete! #endif } else if(bootloaderData.base.bootloaderDataVersion == 2) { hardwareVersion = (uint8_t) bootloaderData.version2.hardwareVersionMajor; hardwareVersion <<= 8; hardwareVersion |= (uint8_t) bootloaderData.version2.hardwareVersionMinor; if(hardwareVersion == 0x0004) { hardwareVersionIndex = 0; // first version of the board that was released. } else if(hardwareVersion == 0x0102) { hardwareVersionIndex = 1; // second version of the board that was released (yes we jumped from 0.4 beta to 1.2). } else if(hardwareVersion == 0x0103) { hardwareVersionIndex = 2; // third version of the board } strcpypgm2ram(idString, (const far rom char*) bootloaderData.version2.deviceId); strcatpgm2ram(idString, (const far rom char*) bootloaderData.version2.productDomain); #if NABTO_ENABLE_UCRYPTO sharedSecret = bootloaderData.version2.sharedSecret; #endif } else { // unsupported version so it's probably safe to assume that bootloader data has been wiped - please fill in the appropriate values for your Nabduino board hardwareVersionIndex = 0; // hardware version 0.4 = 0, v1.2 = 1, v1.3 = 2 AppConfig.MyMACAddr.v[0] = 0xBC; // Nabto owned MAC OUI is BC:A4:E1 AppConfig.MyMACAddr.v[1] = 0xA4; AppConfig.MyMACAddr.v[2] = 0xE1; AppConfig.MyMACAddr.v[3] = 0x00; AppConfig.MyMACAddr.v[4] = 0x00; AppConfig.MyMACAddr.v[5] = 0x00; // If using more than one Nabduino on the same network make this byte unique for each board strcpypgm2ram(idString, "XXX"); // replace XXX with the id of the Nabduino board strcatpgm2ram(idString, ".nabduino.net"); #if NABTO_ENABLE_UCRYPTO sharedSecret = dummySharedSecret; #endif } // </editor-fold> // Initialize IOs etc. taking into account the hardware version. hal_initialize(); // Initialize the platform (timing, TCP/IP stack, DHCP and some PIC18 specific stuff) platform_initialize(); network_initialize(); nms = unabto_init_context(); nms->id = (const char*) idString; // build version string: <application SVN version>/<bootloader SVN version>/<hardware major version>.<hardware minor version> itoa(RELEASE_MINOR, versionString); strcatpgm2ram(versionString + strlen(versionString), "/"); itoa(bootloaderData.base.buildVersion, versionString + strlen(versionString)); strcatpgm2ram(versionString + strlen(versionString), "/"); itoa(hardwareVersion >> 8, versionString + strlen(versionString)); strcatpgm2ram(versionString + strlen(versionString), "."); itoa(hardwareVersion & 0xff, versionString + strlen(versionString)); nms->version = (const char*) versionString; #if NABTO_ENABLE_UCRYPTO memcpypgm2ram(nms->presharedKey, (const __ROM void*) sharedSecret, 16); nms->secureAttach = true; nms->secureData = true; nms->cryptoSuite = CRYPT_W_AES_CBC_HMAC_SHA256; #endif setup((char**) &nms->url); unabto_init(); while(1) { hal_tick(); platform_tick(); network_tick(); unabto_tick(); loop(); } }