diff --git a/.gitignore b/.gitignore index f95adc8..9373deb 100644 --- a/.gitignore +++ b/.gitignore @@ -78,3 +78,17 @@ atmel*.* *.png *.xslt + +# ctags +tags + +# Project Specific +V2X_Firmware/debug\.log + +# config folder ignored +# explanation: though necessary files live in the Config folder, they should be +# handled by the Atmel Software Framework Wizard/Explorer tools included +# with Atmel Studio, to ensure proper ASF modules have been loaded. Please read +# the included "V2X project setup" pdf for instructions on managing ASF modules. +V2X_Firmware/src/[Cc]onfig/ + diff --git a/README.md b/README.md index 3c746a1..3a9e879 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,60 @@ # rvi_v2x_firmware -This repo contains the Firmware design files for the JLR OSTC V2X project. Firmware for an open source CAN/OBD2/2G/3G/GPS/Accelerometer with Power sequencing of RaspberryPi 2B host with RVI node installed. -Tools in use: Atmel Studio 7 - Primary software IDE. Available at http://www.atmel.com/tools/ATMELSTUDIO.aspx AVR Draggon - in-circuit programmer and debugger. Available at http://www.atmel.com/tools/AVRDRAGON.aspx FOXIT - PDF printer and viewer. Available at https://www.foxitsoftware.com/products/pdf-reader/ V2X development Hardware - OSTC prototype device. +## Description -Primary Development by Jesse Banks - jbanks2@jaguarlandrover.com Other Contributions from UCSD ECE191 Students Jaguar Land Rover OSTC - Portland, Oregon 2015-2016 \ No newline at end of file +This repo contains the firmware source and design files for the JLR OSTC V2X +project, an open source hardware device equipped with +* CAN/OBD2 interface +* 2G/3G/GPS/GSM modem +* Accelerometer + +This project, and its associated firmware and hardware, are under ongoing +development through the joint efforts of +* [Jaguar Land Rover Open Software Technology Center +(https://github.com/PDXostc)](https://github.com/PDXostc) and the +* [GENIVI Alliance (https://github.com/GENIVI)](https://github.com/GENIVI) + +Hardware repo can be found at +[https://github.com/PDXostc/rvi_v2x_hardware](https://github.com/PDXostc/rvi_v2x_hardware). + +> At the time of writing, current [firmware version 0.2](insert-link-here) +> intended to be used with the [hardware 2.1 release](https://github.com/PDXostc/rvi_v2x_hardware/commit/71e0d74038f05f68dc1f46546d6cc1ff5eac84f3). + +Usage profile suggests pairing with a RaspberryPi host with +[RVI node](https://github.com/GENIVI/rvi_lib) +installed, for telemetry preprocessing and automated control. Suggested host +software is located with the +[GENIVI Smart Cities pilot project yocto layer](https://github.com/GENIVI/meta-smart-cities-pilot) +and +[GENIVI Smart Cities application](https://github.com/GENIVI/meta-smart-cities-pilot). +Use of this software is not required for operation, but can provide a certain +reference implementation. + +## Installation + +Please see the [*V2X-project-setup.pdf*](V2X-project-setup.pdf) for instructions +on correctly setting up the project in the Atmel environment and with the +[Atmel Software Framework](http://www.atmel.com/tools/avrsoftwareframework.aspx). + +Tips for use in the field can be found in the [Support Manual](field-support-manual.md), +located in this repo. + +Tools in use: +* [Atmel Studio 7 - Primary software + IDE](http://www.atmel.com/tools/ATMELSTUDIO.aspx) +* [AVR Dragon - in-circuit programmer and + debugger](http://www.atmel.com/tools/avrdragon.aspx) +* [FOXIT - PDF printer and + viewer](https://www.foxitsoftware.com/products/pdf-reader/) +* [V2X development hardware](https://github.com/PDXostc/rvi_v2x_hardware), OSTC + prototype device + +## Contributors + +Primary Development by Jesse Banks - jbanks2@jaguarlandrover.com. + +Other Contributions from UCSD ECE191 Students Jaguar Land Rover OSTC - Portland, +Oregon 2015-2016. + +Current release maintained by Steve Miller - [smiller6 at +jaguarlandrover.com](smiller6@jaguarlandrover.com) \ No newline at end of file diff --git a/V2X project setup.pdf b/V2X-project-setup.pdf similarity index 100% rename from V2X project setup.pdf rename to V2X-project-setup.pdf diff --git a/V2X_Firmware/V2X.cproj b/V2X_Firmware/V2X.cproj index 4081a0e..bac57b5 100644 --- a/V2X_Firmware/V2X.cproj +++ b/V2X_Firmware/V2X.cproj @@ -29,175 +29,175 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + com.atmel.avrdbg.tool.avrdragon PDI @@ -214,261 +214,272 @@ AVR Dragon true + + + + + + + + com.atmel.avrdbg.tool.simulator + + + Simulator + - -mmcu=atxmega128a4u -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\gcc\dev\atxmega128a4u" - True - True - True - True - False - - - NDEBUG - IOPORT_XMEGA_COMPAT - BOARD=USER_BOARD - - - - - %24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\include - ../common/applications/user_application/user_board/config - ../src/config - ../src - ../src/ASF/common/services/calendar - ../src/ASF/common/services/hugemem - ../src/ASF/common/services/storage/ctrl_access - ../src/ASF/xmega/drivers/ac - ../src/ASF/xmega/drivers/cpu - ../src/ASF/xmega/drivers/dma - ../src/ASF/xmega/drivers/nvm - ../src/ASF/xmega/drivers/pmic - ../src/ASF/xmega/drivers/rtc - ../src/ASF/xmega/drivers/sleep - ../src/ASF/xmega/drivers/spi - ../src/ASF/xmega/drivers/tc - ../src/ASF/xmega/drivers/wdt - ../src/ASF/xmega/services/pwm - ../src/ASF/common/drivers/nvm - ../src/ASF/common/services/clock - ../src/ASF/common/services/delay - ../src/ASF/common/services/gpio - ../src/ASF/common/services/ioport - ../src/ASF/common/services/serial/xmega_usart - ../src/ASF/common/services/serial - ../src/ASF/common/services/sleepmgr - ../src/ASF/common/services/spi/xmega_spi - ../src/ASF/common/services/spi - ../src/ASF/common/services/usb - ../src/ASF/common/services/usb/class/cdc - ../src/ASF/common/services/usb/class/cdc/device - ../src/ASF/common/services/usb/udc - ../src/ASF/common/utils/stdio/stdio_serial - ../src/ASF/common/utils/stdio/stdio_usb - ../src/ASF/thirdparty/wireless/addons/sio2host/usb - ../src/ASF/xmega/drivers/adc - ../src/ASF/xmega/drivers/usart - ../src/ASF/xmega/drivers/usb - ../src/ASF/common/services/cpu - ../src/ASF/common/boards/user_board - ../src/ASF/common/boards - ../src/ASF/xmega/utils/preprocessor - ../src/ASF/xmega/utils - ../src/ASF/common/utils - - - Optimize for size (-Os) - -fdata-sections - True - True - True - -std=gnu99 -fno-strict-aliasing -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax - - - libm - - - -Wl,--relax - -mrelax -DBOARD=USER_BOARD - - - ../common/applications/user_application/user_board/config - ../src/config - ../src - ../src/ASF/common/services/calendar - ../src/ASF/common/services/hugemem - ../src/ASF/common/services/storage/ctrl_access - ../src/ASF/xmega/drivers/ac - ../src/ASF/xmega/drivers/cpu - ../src/ASF/xmega/drivers/dma - ../src/ASF/xmega/drivers/nvm - ../src/ASF/xmega/drivers/pmic - ../src/ASF/xmega/drivers/rtc - ../src/ASF/xmega/drivers/sleep - ../src/ASF/xmega/drivers/spi - ../src/ASF/xmega/drivers/tc - ../src/ASF/xmega/drivers/wdt - ../src/ASF/xmega/services/pwm - ../src/ASF/common/drivers/nvm - ../src/ASF/common/services/clock - ../src/ASF/common/services/delay - ../src/ASF/common/services/gpio - ../src/ASF/common/services/ioport - ../src/ASF/common/services/serial/xmega_usart - ../src/ASF/common/services/serial - ../src/ASF/common/services/sleepmgr - ../src/ASF/common/services/spi/xmega_spi - ../src/ASF/common/services/spi - ../src/ASF/common/services/usb - ../src/ASF/common/services/usb/class/cdc - ../src/ASF/common/services/usb/class/cdc/device - ../src/ASF/common/services/usb/udc - ../src/ASF/common/utils/stdio/stdio_serial - ../src/ASF/common/utils/stdio/stdio_usb - ../src/ASF/thirdparty/wireless/addons/sio2host/usb - ../src/ASF/xmega/drivers/adc - ../src/ASF/xmega/drivers/usart - ../src/ASF/xmega/drivers/usb - ../src/ASF/common/services/cpu - ../src/ASF/common/boards/user_board - ../src/ASF/common/boards - ../src/ASF/xmega/utils/preprocessor - ../src/ASF/xmega/utils - ../src/ASF/common/utils - - - + -mmcu=atxmega128a4u -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\gcc\dev\atxmega128a4u" + True + True + True + True + False + + + NDEBUG + IOPORT_XMEGA_COMPAT + BOARD=USER_BOARD + + + + + %24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\include + ../common/applications/user_application/user_board/config + ../src/config + ../src + ../src/ASF/common/services/calendar + ../src/ASF/common/services/hugemem + ../src/ASF/common/services/storage/ctrl_access + ../src/ASF/xmega/drivers/ac + ../src/ASF/xmega/drivers/cpu + ../src/ASF/xmega/drivers/dma + ../src/ASF/xmega/drivers/nvm + ../src/ASF/xmega/drivers/pmic + ../src/ASF/xmega/drivers/rtc + ../src/ASF/xmega/drivers/sleep + ../src/ASF/xmega/drivers/spi + ../src/ASF/xmega/drivers/tc + ../src/ASF/xmega/drivers/wdt + ../src/ASF/xmega/services/pwm + ../src/ASF/common/drivers/nvm + ../src/ASF/common/services/clock + ../src/ASF/common/services/delay + ../src/ASF/common/services/gpio + ../src/ASF/common/services/ioport + ../src/ASF/common/services/serial/xmega_usart + ../src/ASF/common/services/serial + ../src/ASF/common/services/sleepmgr + ../src/ASF/common/services/spi/xmega_spi + ../src/ASF/common/services/spi + ../src/ASF/common/services/usb + ../src/ASF/common/services/usb/class/cdc + ../src/ASF/common/services/usb/class/cdc/device + ../src/ASF/common/services/usb/udc + ../src/ASF/common/utils/stdio/stdio_serial + ../src/ASF/common/utils/stdio/stdio_usb + ../src/ASF/thirdparty/wireless/addons/sio2host/usb + ../src/ASF/xmega/drivers/adc + ../src/ASF/xmega/drivers/usart + ../src/ASF/xmega/drivers/usb + ../src/ASF/common/services/cpu + ../src/ASF/common/boards/user_board + ../src/ASF/common/boards + ../src/ASF/xmega/utils/preprocessor + ../src/ASF/xmega/utils + ../src/ASF/common/utils + + + Optimize for size (-Os) + -fdata-sections + True + True + True + -std=gnu99 -fno-strict-aliasing -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax + + + libm + + + -Wl,--relax + -mrelax -DBOARD=USER_BOARD + + + ../common/applications/user_application/user_board/config + ../src/config + ../src + ../src/ASF/common/services/calendar + ../src/ASF/common/services/hugemem + ../src/ASF/common/services/storage/ctrl_access + ../src/ASF/xmega/drivers/ac + ../src/ASF/xmega/drivers/cpu + ../src/ASF/xmega/drivers/dma + ../src/ASF/xmega/drivers/nvm + ../src/ASF/xmega/drivers/pmic + ../src/ASF/xmega/drivers/rtc + ../src/ASF/xmega/drivers/sleep + ../src/ASF/xmega/drivers/spi + ../src/ASF/xmega/drivers/tc + ../src/ASF/xmega/drivers/wdt + ../src/ASF/xmega/services/pwm + ../src/ASF/common/drivers/nvm + ../src/ASF/common/services/clock + ../src/ASF/common/services/delay + ../src/ASF/common/services/gpio + ../src/ASF/common/services/ioport + ../src/ASF/common/services/serial/xmega_usart + ../src/ASF/common/services/serial + ../src/ASF/common/services/sleepmgr + ../src/ASF/common/services/spi/xmega_spi + ../src/ASF/common/services/spi + ../src/ASF/common/services/usb + ../src/ASF/common/services/usb/class/cdc + ../src/ASF/common/services/usb/class/cdc/device + ../src/ASF/common/services/usb/udc + ../src/ASF/common/utils/stdio/stdio_serial + ../src/ASF/common/utils/stdio/stdio_usb + ../src/ASF/thirdparty/wireless/addons/sio2host/usb + ../src/ASF/xmega/drivers/adc + ../src/ASF/xmega/drivers/usart + ../src/ASF/xmega/drivers/usb + ../src/ASF/common/services/cpu + ../src/ASF/common/boards/user_board + ../src/ASF/common/boards + ../src/ASF/xmega/utils/preprocessor + ../src/ASF/xmega/utils + ../src/ASF/common/utils + + + - -mmcu=atxmega128a4u -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\gcc\dev\atxmega128a4u" - True - True - True - True - False - - - DEBUG - IOPORT_XMEGA_COMPAT - BOARD=USER_BOARD - - - - - %24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\include - ../common/applications/user_application/user_board/config - ../src/config - ../src - ../src/ASF/common/services/calendar - ../src/ASF/common/services/hugemem - ../src/ASF/common/services/storage/ctrl_access - ../src/ASF/xmega/drivers/ac - ../src/ASF/xmega/drivers/cpu - ../src/ASF/xmega/drivers/dma - ../src/ASF/xmega/drivers/nvm - ../src/ASF/xmega/drivers/pmic - ../src/ASF/xmega/drivers/rtc - ../src/ASF/xmega/drivers/sleep - ../src/ASF/xmega/drivers/spi - ../src/ASF/xmega/drivers/tc - ../src/ASF/xmega/drivers/wdt - ../src/ASF/xmega/services/pwm - ../src/ASF/common/drivers/nvm - ../src/ASF/common/services/clock - ../src/ASF/common/services/delay - ../src/ASF/common/services/gpio - ../src/ASF/common/services/ioport - ../src/ASF/common/services/serial/xmega_usart - ../src/ASF/common/services/serial - ../src/ASF/common/services/sleepmgr - ../src/ASF/common/services/spi/xmega_spi - ../src/ASF/common/services/spi - ../src/ASF/common/services/usb - ../src/ASF/common/services/usb/class/cdc - ../src/ASF/common/services/usb/class/cdc/device - ../src/ASF/common/services/usb/udc - ../src/ASF/common/utils/stdio/stdio_serial - ../src/ASF/common/utils/stdio/stdio_usb - ../src/ASF/thirdparty/wireless/addons/sio2host/usb - ../src/ASF/xmega/drivers/adc - ../src/ASF/xmega/drivers/usart - ../src/ASF/xmega/drivers/usb - ../src/ASF/common/services/cpu - ../src/ASF/common/boards/user_board - ../src/ASF/common/boards - ../src/ASF/xmega/utils/preprocessor - ../src/ASF/xmega/utils - ../src/ASF/common/utils - - - Optimize (-O1) - -fdata-sections - True - True - Maximum (-g3) - True - -std=gnu99 -fno-strict-aliasing -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax - - - libm - - - -Wl,--relax - -mrelax -DBOARD=USER_BOARD - - - ../common/applications/user_application/user_board/config - ../src/config - ../src - ../src/ASF/common/services/calendar - ../src/ASF/common/services/hugemem - ../src/ASF/common/services/storage/ctrl_access - ../src/ASF/xmega/drivers/ac - ../src/ASF/xmega/drivers/cpu - ../src/ASF/xmega/drivers/dma - ../src/ASF/xmega/drivers/nvm - ../src/ASF/xmega/drivers/pmic - ../src/ASF/xmega/drivers/rtc - ../src/ASF/xmega/drivers/sleep - ../src/ASF/xmega/drivers/spi - ../src/ASF/xmega/drivers/tc - ../src/ASF/xmega/drivers/wdt - ../src/ASF/xmega/services/pwm - ../src/ASF/common/drivers/nvm - ../src/ASF/common/services/clock - ../src/ASF/common/services/delay - ../src/ASF/common/services/gpio - ../src/ASF/common/services/ioport - ../src/ASF/common/services/serial/xmega_usart - ../src/ASF/common/services/serial - ../src/ASF/common/services/sleepmgr - ../src/ASF/common/services/spi/xmega_spi - ../src/ASF/common/services/spi - ../src/ASF/common/services/usb - ../src/ASF/common/services/usb/class/cdc - ../src/ASF/common/services/usb/class/cdc/device - ../src/ASF/common/services/usb/udc - ../src/ASF/common/utils/stdio/stdio_serial - ../src/ASF/common/utils/stdio/stdio_usb - ../src/ASF/thirdparty/wireless/addons/sio2host/usb - ../src/ASF/xmega/drivers/adc - ../src/ASF/xmega/drivers/usart - ../src/ASF/xmega/drivers/usb - ../src/ASF/common/services/cpu - ../src/ASF/common/boards/user_board - ../src/ASF/common/boards - ../src/ASF/xmega/utils/preprocessor - ../src/ASF/xmega/utils - ../src/ASF/common/utils - - - Default (-Wa,-g) - + -mmcu=atxmega128a4u -B "%24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\gcc\dev\atxmega128a4u" + True + True + True + True + False + + + DEBUG + IOPORT_XMEGA_COMPAT + BOARD=USER_BOARD + + + + + %24(PackRepoDir)\atmel\XMEGAA_DFP\1.0.36\include + ../common/applications/user_application/user_board/config + ../src/config + ../src + ../src/ASF/common/services/calendar + ../src/ASF/common/services/hugemem + ../src/ASF/common/services/storage/ctrl_access + ../src/ASF/xmega/drivers/ac + ../src/ASF/xmega/drivers/cpu + ../src/ASF/xmega/drivers/dma + ../src/ASF/xmega/drivers/nvm + ../src/ASF/xmega/drivers/pmic + ../src/ASF/xmega/drivers/rtc + ../src/ASF/xmega/drivers/sleep + ../src/ASF/xmega/drivers/spi + ../src/ASF/xmega/drivers/tc + ../src/ASF/xmega/drivers/wdt + ../src/ASF/xmega/services/pwm + ../src/ASF/common/drivers/nvm + ../src/ASF/common/services/clock + ../src/ASF/common/services/delay + ../src/ASF/common/services/gpio + ../src/ASF/common/services/ioport + ../src/ASF/common/services/serial/xmega_usart + ../src/ASF/common/services/serial + ../src/ASF/common/services/sleepmgr + ../src/ASF/common/services/spi/xmega_spi + ../src/ASF/common/services/spi + ../src/ASF/common/services/usb + ../src/ASF/common/services/usb/class/cdc + ../src/ASF/common/services/usb/class/cdc/device + ../src/ASF/common/services/usb/udc + ../src/ASF/common/utils/stdio/stdio_serial + ../src/ASF/common/utils/stdio/stdio_usb + ../src/ASF/thirdparty/wireless/addons/sio2host/usb + ../src/ASF/xmega/drivers/adc + ../src/ASF/xmega/drivers/usart + ../src/ASF/xmega/drivers/usb + ../src/ASF/common/services/cpu + ../src/ASF/common/boards/user_board + ../src/ASF/common/boards + ../src/ASF/xmega/utils/preprocessor + ../src/ASF/xmega/utils + ../src/ASF/common/utils + + + -fdata-sections + True + True + Maximum (-g3) + True + -std=gnu99 -fno-strict-aliasing -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax + + + libm + + + -Wl,--relax + -mrelax -DBOARD=USER_BOARD + + + ../common/applications/user_application/user_board/config + ../src/config + ../src + ../src/ASF/common/services/calendar + ../src/ASF/common/services/hugemem + ../src/ASF/common/services/storage/ctrl_access + ../src/ASF/xmega/drivers/ac + ../src/ASF/xmega/drivers/cpu + ../src/ASF/xmega/drivers/dma + ../src/ASF/xmega/drivers/nvm + ../src/ASF/xmega/drivers/pmic + ../src/ASF/xmega/drivers/rtc + ../src/ASF/xmega/drivers/sleep + ../src/ASF/xmega/drivers/spi + ../src/ASF/xmega/drivers/tc + ../src/ASF/xmega/drivers/wdt + ../src/ASF/xmega/services/pwm + ../src/ASF/common/drivers/nvm + ../src/ASF/common/services/clock + ../src/ASF/common/services/delay + ../src/ASF/common/services/gpio + ../src/ASF/common/services/ioport + ../src/ASF/common/services/serial/xmega_usart + ../src/ASF/common/services/serial + ../src/ASF/common/services/sleepmgr + ../src/ASF/common/services/spi/xmega_spi + ../src/ASF/common/services/spi + ../src/ASF/common/services/usb + ../src/ASF/common/services/usb/class/cdc + ../src/ASF/common/services/usb/class/cdc/device + ../src/ASF/common/services/usb/udc + ../src/ASF/common/utils/stdio/stdio_serial + ../src/ASF/common/utils/stdio/stdio_usb + ../src/ASF/thirdparty/wireless/addons/sio2host/usb + ../src/ASF/xmega/drivers/adc + ../src/ASF/xmega/drivers/usart + ../src/ASF/xmega/drivers/usb + ../src/ASF/common/services/cpu + ../src/ASF/common/boards/user_board + ../src/ASF/common/boards + ../src/ASF/xmega/utils/preprocessor + ../src/ASF/xmega/utils + ../src/ASF/common/utils + + + Default (-Wa,-g) + diff --git a/V2X_Firmware/src/V2X/V2X_board.h b/V2X_Firmware/src/V2X/V2X_board.h index a615705..9b7a78a 100644 --- a/V2X_Firmware/src/V2X/V2X_board.h +++ b/V2X_Firmware/src/V2X/V2X_board.h @@ -1,7 +1,7 @@ /** * \file V2X_board.h * - * \brief V2X power sequencer board definition XMEGA128A4U + * \brief V2X power sequencer board definition XMEGA128A4U * * Author: Jesse Banks (jbanks2) */ @@ -21,14 +21,50 @@ extern "C" { * @{ */ +/* Board revision options */ +#define REV_12 (12) +#define REV_20 (20) + +/* Board revision in use */ +#define V2X_REV (REV_20) + /** Name string macro */ -#define BOARD_NAME "RVI_V2X_Version_1.2" +#if V2X_REV == REV_12 + #define BOARD_NAME "RVI_V2X_Version_1.2" +#elif V2X_REV >= REV_20 +/* REV20: board name change */ + #define BOARD_NAME "RVI_V2X_Version_2.0" +#endif /** @} */ +/* Defines for SIMCOM GSM chip on board. Compile time choice. + */ +#define SIMCOM_SIM5320A (0) +#define SIMCOM_SIM7100A (1) +//#define SIMCOM SIMCOM_SIM7100A +#define SIMCOM SIMCOM_SIM5320A + +/* Configure SIMCOM to start the GPS automatically, without explicit instruction + */ +#define GPS_AUTO + +/** \name 3v3 power pin definition + * Activate to maintain power to CPU + */ +#if V2X_REV >= REV_20 +#define PWR_3V3_PIN IOPORT_CREATE_PIN(PORTA,4) +#define PWR_3V3_ACTIVE true +#define PWR_3V3_INACTIVE !PWR_3V3_ACTIVE +#endif + /** \name LED0 definitions * net: SEQ_LED3 or "PWR" LED * @{ */ -#define LED0_PIN IOPORT_CREATE_PIN(PORTB, 0) +#if V2X_REV <= REV_12 +#define LED0_PIN IOPORT_CREATE_PIN(PORTB,0) +#elif V2X_REV >= REV_20 +#define LED0_PIN IOPORT_CREATE_PIN(PORTE,2) +#endif #define LED0_ACTIVE true #define LED0_INACTIVE !LED0_ACTIVE /** @} */ @@ -36,15 +72,23 @@ extern "C" { /** \name LED1 definitions * net: SEQ_LED1 or "M2M" LED * @{ */ -#define LED1_PIN IOPORT_CREATE_PIN(PORTA, 6) +#if V2X_REV <= REV_12 +#define LED1_PIN IOPORT_CREATE_PIN(PORTA,6) +#elif V2X_REV >= REV_20 +#define LED1_PIN IOPORT_CREATE_PIN(PORTE,1) +#endif #define LED1_ACTIVE true #define LED1_INACTIVE !LED0_ACTIVE /** @} */ /** \name LED2 definitions - * net: SEQ_LED3 or "GPS" LED + * net: SEQ_LED2 or "GPS" LED * @{ */ -#define LED2_PIN IOPORT_CREATE_PIN(PORTA, 7) +#if V2X_REV <= REV_12 +#define LED2_PIN IOPORT_CREATE_PIN(PORTA,7) +#elif V2X_REV >= REV_20 +#define LED2_PIN IOPORT_CREATE_PIN(PORTE,3) +#endif #define LED2_ACTIVE true #define LED2_INACTIVE !LED0_ACTIVE /** @} */ @@ -94,9 +138,10 @@ extern "C" { /** \name SW0 definitions * @{ */ -#define SW0_PIN IOPORT_CREATE_PIN(PORTA, 0) +#define SW0_PIN IOPORT_CREATE_PIN(PORTA,0) #define SW0_ACTIVE true #define SW0_INACTIVE !SW0_ACTIVE +#define SW0_INT_VECT_0 PORTA_INT0_vect /** @} */ /** @@ -113,7 +158,7 @@ extern "C" { /** \name SW1 definitions * @{ */ -#define SW1_PIN IOPORT_CREATE_PIN(PORTD, 5) +#define SW1_PIN IOPORT_CREATE_PIN(PORTD,5) #define SW1_ACTIVE FALSE #define SW1_INACTIVE !SW1_ACTIVE /** @} */ @@ -132,6 +177,11 @@ extern "C" { #define BUTTON_COUNT 2 + +#if V2X_REV == REV_12 +/* DELETEME: Quite possibly, the whole buffer switcheroo is not needed anymore, + * can probably eliminate the whole buffer setup + * */ /** * \name Serial Buffer #0 definitions * @@ -146,17 +196,21 @@ extern "C" { /** \name BUF0 definitions * @{ */ -#define BUF0_PIN IOPORT_CREATE_PIN(PORTB, 2) +#define BUF0_PIN IOPORT_CREATE_PIN(PORTB,2) #define BUF0_ACTIVE true #define BUF0_INACTIVE !BUF0_ACTIVE /** @} */ +/* Revision 1.2 uses FTDI chip for primary routing. Control must be selected + * specifically by either the FDTI or the Atmel. Revision 2.0 removes the FDTI + * chip. + */ /** - * \name Serial Buffer #1 definitions - * - * Makes FTDI active communicator with ELM/STN device - * - * @{ */ +* \name Serial Buffer #1 definitions +* +* Makes FTDI active communicator with ELM/STN device +* +* @{ */ #define BUF_1_NAME "Buffer FTDI Active" #define BUF_1_PIN BUF1_PIN #define BUF_1_ACTIVE BUF1_ACTIVE @@ -164,22 +218,26 @@ extern "C" { /** @} */ /** \name BUF1 definitions - * @{ */ -#define BUF1_PIN IOPORT_CREATE_PIN(PORTB, 3) +* @{ */ +#define BUF1_PIN IOPORT_CREATE_PIN(PORTB,3) #define BUF1_ACTIVE true #define BUF1_INACTIVE !BUF1_ACTIVE /** @} */ /** Number of on-board buttons */ +/* DELETEME: this can probably just be eliminated */ #define BUFFER_COUNT 2 +#define BUFFER_COUNT 1 +#endif /** \name CP0 definitions * @{ */ -#define CP0_PIN IOPORT_CREATE_PIN(PORTA, 1) +#define CP0_PIN IOPORT_CREATE_PIN(PORTA,1) #define CP0_ACTIVE true #define CP0_INACTIVE !CP0_ACTIVE /** @} */ +#if V2X_REV <= REV_12 /** * \name Charge Pump #0 definitions * @@ -195,14 +253,24 @@ extern "C" { /** Number of on-board buttons */ #define CHARGEPUMP_COUNT 1 +#endif /** \name Signal pin definitions * @{ */ +#if V2X_REV <= REV_12 #define EXT1_PIN_ACL_INT2 IOPORT_CREATE_PIN(PORTA,2) #define EXT1_PIN_ACL_INT1 IOPORT_CREATE_PIN(PORTA,3) +#elif V2X_REV >= REV_20 +#define EXT1_PIN_ACL_INT2 IOPORT_CREATE_PIN(PORTA,1) +#define EXT1_PIN_ACL_INT1 IOPORT_CREATE_PIN(PORTA,2) +#endif +#if V2X_REV <= REV_12 #define EXT1_PIN_HUB_STATUS IOPORT_CREATE_PIN(PORTA,4) -#define EXT1_PIN_HUB_SUSPEND IOPORT_CREATE_PIN(PORTE,5) +#define EXT1_PIN_HUB_SUSPEND IOPORT_CREATE_PIN(PORTA,5) +/* DELETEME: HUB_STATUS unnecessary without FTDI in the mix */ +#endif +#define EXT1_PIN_HUB_STATUS IOPORT_CREATE_PIN(PORTA,3) #define EXT1_PIN_HOST_SHORT_CIRCUIT IOPORT_CREATE_PIN(PORTB,1) #define EXT1_PIN_SR_CLEAR IOPORT_CREATE_PIN(PORTC,0) #define EXT1_PIN_SR_LATCH IOPORT_CREATE_PIN(PORTC,1) @@ -212,10 +280,14 @@ extern "C" { #define EXT1_PIN_SPI_MOSI IOPORT_CREATE_PIN(PORTC,5) #define EXT1_PIN_SPI_MISO IOPORT_CREATE_PIN(PORTC,6) #define EXT1_PIN_SPI_SCK IOPORT_CREATE_PIN(PORTC,7) +#if V2X_REV <= REV_12 #define EXT1_PIN_HUB_SDA IOPORT_CREATE_PIN(PORTE,0) #define EXT1_PIN_HUB_SCL IOPORT_CREATE_PIN(PORTE,1) +#endif +#if V2X_REV <= REV_12 #define EXT1_PIN_ACL_RXD IOPORT_CREATE_PIN(PORTE,2) //RX SIGNAL (PORT E RXD0) FROM SEQ TO FTDI FOR ACCEL AT INTERFACE #define EXT1_PIN_ACL_TXD IOPORT_CREATE_PIN(PORTE,3) //TX SIGNAL (PORT E TXD0) FROM SEQ TO FTDI FOR ACCEL AT INTERFACE +#endif #define EXT1_PIN_SIM_WAKE IOPORT_CREATE_PIN(PORTD,0) #define EXT1_PIN_SIM_NETWORK IOPORT_CREATE_PIN(PORTD,1) #define EXT1_PIN_SIM_TXD IOPORT_CREATE_PIN(PORTE,2) //TX SIGNAL (PORT D RXD0) FROM SIM MODULE @@ -223,8 +295,13 @@ extern "C" { #define EXT1_PIN_SIM_PWR IOPORT_CREATE_PIN(PORTD,4) #define EXT1_PIN_SEQ_RXD IOPORT_CREATE_PIN(PORTD,6) //RX SIGNAL (PORT D RXD1) FROM FTDI MODULE FOR SEQ AT INTERFACE, ALSO USB DM #define EXT1_PIN_SEQ_TXD IOPORT_CREATE_PIN(PORTD,7) //TX SIGNAL (PORT D TXD1) TO FTDI MODULE FOR SEQ AT INTERFACE, ALSO USB DP +/* FIXME: Add definition for HUB_PWR_PRT1 pin, on PORTA,3 ?? */ /** @} */ +/* FIXME: Is the following TWI definition incorrect, or irrelevant? + * Incorrect because (there may not actually be a TWI device on PORTA)? + * Irrelevant because we do not use TWI device>? + */ /** \name TWI definitions * @{ @@ -237,6 +314,8 @@ extern "C" { #define TWI_DATA_LENGTH 8 /** @} */ +#if V2X_REV <= REV_12 +/*DELETEME: These are likely superfluous */ /** \name Extension header #1 USART definitions * @{ */ @@ -246,17 +325,19 @@ extern "C" { #define EXT1_ACL_USART &USARTE0 /** @} */ +/*DELETEME: Doubly superfluous */ /** \name Extension header #1 SPI definitions * @{ */ #define EXT1_SPI_MODULE &SPIC - + /** @} */ /** \name Extension header #2 SPI definitions * @{ */ #define EXT1_SPI_MODULE &SPIC - +#endif + /** @} */ /*! \name SPI Connections of external ADXL345 Accelerometer @@ -276,11 +357,15 @@ extern "C" { #define ACL_SPI_CLK_MASK SYSCLK_PORT_C //! @} -/*! \name Shift Register Connections +/*! \name Shift Register Connections * * This is used for power and reset sequencing * */ +#if V2X_REV <= REV_12 +/* Revision 1.2 features two shift registers, accommodating a 16 bit field for + * the following power signals. Note: order is relevant! + */ enum power_sequence_outputs { ENABLE_3V3 = 0, ENABLE_3V3B , @@ -297,35 +382,50 @@ enum power_sequence_outputs { ENABLE_SIM_RESET , ENABLE_SIM_RF_OFF , ENABLE_SIM_VBUS , - ENABLE_FTDI_RESET + ENABLE_FTDI_RESET }; +#elif V2X_REV >= REV_20 +/* Revision 2.0 uses only a single shift register, accommodating an 8 bit field + * for the following power signals. Note: order is relevant! + */ + enum power_sequence_outputs { + ENABLE_4V1 = 0 + , ENABLE_5V0 + , ENABLE_5V0B + , ENABLE_CAN_SLEEP + , ENABLE_CAN_RESET + , ENABLE_SIM_PWR_ON + , ENABLE_SIM_RESET + , ENABLE_SIM_WAKE + }; +#endif #define SR_SPI &SPIC //! @} -#define USART USARTC0 -#define USART_RX_Vect USARTC0_RXC_vect -#define USART_DRE_Vect USARTC0_DRE_vect -#define USART_SYSCLK SYSCLK_USART0 -#define USART_PORT PORTC -#define USART_PORT_PIN_TX (1<<3) // PC3 (TXE0) -#define USART_PORT_PIN_RX (1<<2) // PC2 (RXE0) -#define USART_PORT_SYSCLK SYSCLK_PORT_C +#define USART USARTC0 +#define USART_RX_Vect USARTC0_RXC_vect +#define USART_DRE_Vect USARTC0_DRE_vect +#define USART_SYSCLK SYSCLK_USART0 +#define USART_PORT PORTC +#define USART_PORT_PIN_TX (1<<3) +#define USART_PORT_PIN_RX (1<<2) +#define USART_PORT_SYSCLK SYSCLK_PORT_C #define USART_BAUDRATE 9600 #define USART_CHAR_LENGTH USART_CHSIZE_8BIT_gc #define USART_PARITY USART_PMODE_DISABLED_gc #define USART_STOP_BIT false -#define USART_SIM USARTD0 -#define USART_SIM_RX_Vect USARTD0_RXC_vect -#define USART_SIM_DRE_Vect USARTD0_DRE_vect -#define USART_SIM_SYSCLK SYSCLK_USART0 -#define USART_SIM_PORT PORTD -#define USART_SIM_PORT_PIN_TX (1<<3) // PC3 (TXE0) -#define USART_SIM_PORT_PIN_RX (1<<2) // PC2 (RXE0) +#define USART_SIM USARTD0 +#define USART_SIM_RX_Vect USARTD0_RXC_vect +#define USART_SIM_DRE_Vect USARTD0_DRE_vect +#define USART_SIM_SYSCLK SYSCLK_USART0 +#define USART_SIM_PORT PORTD +#define USART_SIM_PORT_PIN_TX (1<<3) +#define USART_SIM_PORT_PIN_RX (1<<2) #define USART_SIM_PORT_SYSCLK SYSCLK_PORT_D - + #define USART_SIM_BAUDRATE 115200 #define USART_SIM_CHAR_LENGTH USART_CHSIZE_8BIT_gc #define USART_SIM_PARITY USART_PMODE_DISABLED_gc diff --git a/V2X_Firmware/src/V2X/V2X_button.c b/V2X_Firmware/src/V2X/V2X_button.c index 956918a..e39adfc 100644 --- a/V2X_Firmware/src/V2X/V2X_button.c +++ b/V2X_Firmware/src/V2X/V2X_button.c @@ -3,13 +3,14 @@ * * Created: 2/12/2016 12:46:27 PM * Author: jbanks2 - */ + */ #include "V2X.h" uint32_t pressed_at; Bool button_pressed; -int delta; +Bool button_check_flag = false; +int button_delta; void button_init(void) { int x = 0; @@ -21,28 +22,86 @@ void button_init(void) { } delay_ms(1); } - button_pressed = false; + button_pressed = false; } void button_service(void) { if (button_pressed != button_read()) { //has the button state changes since last time? switch (button_pressed) { case true: //button was released (previously pressed), figure out ho long - delta = time_get() - pressed_at; //calc press duration + button_delta = time_get() - pressed_at; //calc press duration menu_send_BTN(); usb_tx_string_P(PSTR("RELEASE:")); // report to CMD interface - menu_print_int(delta); + menu_print_int(button_delta); menu_send_n_st(); button_pressed = false; //note the button was released + button_check_flag = true; //flag button for checking break; case false: //button was pressed, capture press time + // reset delta + button_delta = 0; pressed_at = time_get(); //store press time button_pressed = true; //hold button state menu_send_BTN(); usb_tx_string_P(PSTR("PRESS")); //report press event to CMD menu_send_n_st(); break; - } - + } + } -} \ No newline at end of file +} + +Bool check_button(void) { + return button_check_flag; +} + +Bool button_reset_check(void) { + button_check_flag = false; +} + +int button_get_delta(void) { + return button_delta; +} + + +void button_reset_delta(void) +{ + button_delta = 0; +} + +#if V2X_REV >= REV_20 +void handle_button_check(int sec) { + if (sec >= 5) + { + // do hard power off + usb_tx_string_P(PSTR("Power Off")); + PWR_host_stop(); + PWR_can_stop(); + PWR_gsm_stop(); + ACL_set_sample_off(); + PWR_shutdown(); + } else if (sec >= 3) + { + usb_tx_string_P(PSTR("Power 3v Only")); + // do 3v only + PWR_host_stop(); + PWR_5_stop(); + ACL_set_sample_off(); + PWR_4_stop(); + // maybe we'd like to force the leds to update here, just in case... + led_1_off(); + led_2_off(); + } else if (sec >= 1) + { + // full power mode + PWR_4_start(); + usb_tx_string_P(PSTR("Power Full")); + udd_attach(); + ACL_set_sample_on(); + GSM_modem_init(); + CAN_elm_init(); + PWR_host_start(); + } + button_reset_delta(); +} +#endif diff --git a/V2X_Firmware/src/V2X/V2X_button.h b/V2X_Firmware/src/V2X/V2X_button.h index ec7c8f5..a6b9840 100644 --- a/V2X_Firmware/src/V2X/V2X_button.h +++ b/V2X_Firmware/src/V2X/V2X_button.h @@ -3,31 +3,43 @@ * * Created: 2/12/2016 12:46:38 PM * Author: jbanks2 - */ + */ #ifndef V2X_BUTTON_H_ #define V2X_BUTTON_H_ +int button_delta; +Bool button_check_flag; + /** * @def button_init - * @brief waits to start the board until the button is released + * @brief waits to start the board until the button is released * @brief sets "pressed" to false as init **/ void button_init(void); /** * @def button_read - * @brief detection of Button state + * @brief detection of Button state * returns "true" if button depressed **/ inline static bool button_read(void) {return ioport_get_pin_level(SW0_PIN);} /** * @def button_service - * @brief check Button state process changes reportr state to CMD interface + * @brief check Button state process changes reporter state to CMD interface * returns "true" if button depressed **/ void button_service(void); +Bool check_button(void); + +Bool button_reset_check(void); + +int button_get_delta(void); + +void button_reset_delta(void); + +void handle_button_check(int sec); #endif /* V2X_BUTTON_H_ */ \ No newline at end of file diff --git a/V2X_Firmware/src/V2X/V2X_control.c b/V2X_Firmware/src/V2X/V2X_control.c index 0bb75db..bc853d8 100644 --- a/V2X_Firmware/src/V2X/V2X_control.c +++ b/V2X_Firmware/src/V2X/V2X_control.c @@ -165,6 +165,13 @@ void job_coordinator (void) { if (job_check_timeout(SYS_CAN_CTL)) { CAN_stop_snoop(); } +#if V2X_REV >= REV_20 + if (job_check_timeout(SYS_PWR)) + { + handle_button_check(button_get_delta()); + job_clear_timeout(SYS_PWR); + } +#endif //more jobs to add //compare GPS coordinates to trigger alarm/host //compare ACL data to trigger alarm/host diff --git a/V2X_Firmware/src/V2X/V2X_control.h b/V2X_Firmware/src/V2X/V2X_control.h index 358f0f0..a1818d8 100644 --- a/V2X_Firmware/src/V2X/V2X_control.h +++ b/V2X_Firmware/src/V2X/V2X_control.h @@ -55,7 +55,8 @@ enum system_switch { SYS_CAN = 0, //used for direct control of CAN SYS_GSM, //used for direct control of GSM SYS_CAN_CTL, //used for CTL passthrough of CAN - SYS_CTL //stand alone sequence jobs, wake host, etc. + SYS_CTL, //stand alone sequence jobs, wake host, etc. + SYS_PWR }; /** diff --git a/V2X_Firmware/src/V2X/V2X_gsm.c b/V2X_Firmware/src/V2X/V2X_gsm.c index 2a502fd..6fd946f 100644 --- a/V2X_Firmware/src/V2X/V2X_gsm.c +++ b/V2X_Firmware/src/V2X/V2X_gsm.c @@ -3,7 +3,7 @@ * * Created: 2/12/2016 11:01:08 AM * Author: jbanks2 - */ + */ #include "V2X.h" @@ -64,7 +64,7 @@ ISR(USART_SIM_RX_Vect) } ISR(USART_SIM_DRE_Vect) -{ +{ if (CTL_bytes_to_send(&GSM, BUFFER_OUT)) { //if bytes left to send USART_SIM.DATA = CTL_next_byte(&GSM, BUFFER_OUT); } else { //clean up @@ -111,25 +111,50 @@ void GSM_control (char * responce_buffer) { void GSM_control_check (char * responce_buffer){ switch (GSM_subsequence_state) { + /*This power check is actually not optimal for supporting both board versions + /* ...In Rev20 the SIM is not the only thing on the 4v rail, so we can't rely + /*on the operational convention of it being disabled/enabled as a check + /* for the SIM's absolute state + /* + /* Works fine for Rev1.2, needs help on Rev2.0. + */ case GSM_subssequence_1: //check module power - if (PWR_query((1<>>:Power up GSM\r")); //does not need end of string, exits through menu PWR_gsm_start(); +#if SIMCOM == SIMCOM_SIM5320A GSM_subsequence_state = GSM_subssequence_2; job_set_timeout(SYS_GSM, 10); //give SIM module 10 seconds to start +#elif SIMCOM == SIMCOM_SIM7100A + GSM_subsequence_state = GSM_subssequence_3; //skip 2, 7100a doesn't appear to have "START" + job_set_timeout(SYS_GSM, 25); //give SIM module 25 seconds to start +#endif } +#elif V2X_REV >= REV_20 + usb_tx_string_P(PSTR("\rCTL>>>:Power up GSM\r")); //does not need end of string, exits through menu + PWR_gsm_start(); + GSM_subsequence_state = GSM_subssequence_3; + job_set_timeout(SYS_GSM, 20); //give SIM module 10 seconds to start +#endif break; +#if SIMCOM == SIMCOM_SIM5320A + /* 7100a does not appear to send the START message, so has real trouble + /* with this step. This appears to be why just sending the machine to subsequence_3 + /* has been more reliable with the new version + */ case GSM_subssequence_2: //Module clean boot, look for "start" if (strcmp_P(responce_buffer, PSTR("START")) == 0) { GSM_subsequence_state = GSM_subssequence_3; //got expected response, go to next step GSM_control_check(responce_buffer); - } + } job_check_fail(SYS_GSM); break; - case GSM_subssequence_3: //check for SIM power LED state +#endif + case GSM_subssequence_3: //check for SIM power state if (sim_power_status()) { menu_send_CTL(); usb_tx_string_P(PSTR("GSM is powered\r>")); @@ -138,10 +163,9 @@ void GSM_control_check (char * responce_buffer){ } else { //try a reset menu_send_CTL(); usb_tx_string_P(PSTR("GSM rebooting\r>")); - PWR_gsm_stop(); PWR_gsm_start(); - GSM_subsequence_state = GSM_subssequence_2; - job_set_timeout(SYS_GSM, 10); //give SIM module 10 seconds to start + GSM_subsequence_state = GSM_subssequence_3; // Check for power again + job_set_timeout(SYS_GSM, 20); //give SIM module 20 seconds to start } break; case GSM_subssequence_6: //check for command responce @@ -157,7 +181,7 @@ void GSM_control_check (char * responce_buffer){ GSM_subsequence_state = GSM_subssequence_1; //got expected response, go to next step GSM_sequence_state = GSM_state_start; GSM_control(responce_buffer); //start next state - } + } job_check_fail(SYS_GSM); break; case GSM_subssequence_FAIL: @@ -184,8 +208,8 @@ void GSM_control_start (char * responce_buffer){ usb_tx_string_P(PSTR("GSM Echo off\r>")); GSM_subsequence_state = GSM_subssequence_3; //move to response state GSM_control(responce_buffer); - } - job_check_fail(SYS_GSM); + } + job_check_fail(SYS_GSM); break; case GSM_subssequence_3: CTL_add_string_to_buffer_P(&GSM, BUFFER_OUT, PSTR("ATI\r")); //compose message @@ -199,7 +223,12 @@ void GSM_control_start (char * responce_buffer){ usb_tx_string_P(PSTR("SIM5320A device detected\r>")); job_set_timeout(SYS_GSM, 2); GSM_subsequence_state = GSM_subssequence_5; //got expected response, go to next step - } else if (strcmp_P(responce_buffer, PSTR("OK")) == 0){ //did not see matching device ID + } else if (strcmp_P(responce_buffer, PSTR("Model: SIMCOM_SIM7100A")) == 0) { //got new version of simcom chip + menu_send_CTL(); + usb_tx_string_P(PSTR("SIM7100A device detected\r>")); + job_set_timeout(SYS_GSM, 2); + GSM_subsequence_state = GSM_subssequence_5; //got expected response, go to next step + } else if (strcmp_P(responce_buffer, PSTR("OK")) == 0) { //did not see matching device ID GSM_subsequence_state = GSM_subssequence_FAIL; job_clear_timeout(SYS_GSM); GSM_control(responce_buffer); @@ -208,6 +237,11 @@ void GSM_control_start (char * responce_buffer){ break; case GSM_subssequence_5: clear_buffer(stng); + /* Operational divergence SIMCOM 5320a vs 7100a + * 5320a stores prints out "IMEI: ..." + * 7100a prints out "IMEISV: ..." + */ +#if SIMCOM == SIMCOM_SIM5320A for (int i = 0; i < 5; i++) {stng[i] = responce_buffer[i];} //move first 4 to compare if (strcmp_P(stng, PSTR("IMEI:")) == 0) { clear_buffer(imei); @@ -218,6 +252,18 @@ void GSM_control_start (char * responce_buffer){ job_set_timeout(SYS_GSM, 2); GSM_subsequence_state = GSM_subssequence_6; //got expected response, go to next step } +#elif SIMCOM == SIMCOM_SIM7100A + for (int i = 0; i < 7; i++) {stng[i] = responce_buffer[i];} //move first 6 to compare + if (strcmp_P(stng, PSTR("IMEISV:")) == 0) { + clear_buffer(imei); + strcat(imei, responce_buffer+8); + menu_send_CTL(); + usb_tx_string_P(PSTR("IMEISV captured ")); + menu_send_n_st(); + job_set_timeout(SYS_GSM, 2); + GSM_subsequence_state = GSM_subssequence_6; //got expected response, go to next step + } +#endif job_check_fail(SYS_GSM); break; case GSM_subssequence_6: @@ -280,7 +326,14 @@ void GSM_time_sync (char * responce_buffer) { break; case GSM_subssequence_2: for (int i = 0; i < 10; i++) {stng[i] = responce_buffer[i];} //move first 10 to compare + // format for this string is altered in simcom version + // 5320a: "+CGPSINFO:,,,,,,,," == [10] ',' + // 7100a: "+CGPSINFO: ,,,,,,,," == [11] ',' +#if SIMCOM == SIMCOM_SIM5320A if (strcmp_P(stng, PSTR("+CGPSINFO:")) == 0 && responce_buffer[10] != ',') { +#elif SIMCOM == SIMCOM_SIM7100A + if (strcmp_P(stng, PSTR("+CGPSINFO:")) == 0 && responce_buffer[11] != ',') { +#endif GSM_parse_gps_info(responce_buffer); GSM_subsequence_state = GSM_subssequence_3; job_set_timeout(SYS_GSM, 2); @@ -290,7 +343,7 @@ void GSM_time_sync (char * responce_buffer) { case GSM_subssequence_3: if (strcmp_P(responce_buffer, PSTR("OK")) == 0) { GSM_sequence_state = GSM_state_idle; - + job_clear_timeout(SYS_GSM); } job_check_fail(SYS_GSM); @@ -309,11 +362,11 @@ void show_buffer(char * buffer) { usb_tx_string_P(PSTR("\"")); usb_cdc_send_string(USB_CMD, buffer); usb_tx_string_P(PSTR("\"")); - + } void GSM_parse_gps_info (char * responce_buffer) { - + char * start_ptr = strchr(responce_buffer, ':') + 1; for (int i = 0; start_ptr[i] != ','; i++) { latitude[i] = start_ptr[i]; //copy lat string @@ -340,13 +393,13 @@ void GSM_parse_gps_info (char * responce_buffer) { for (int i = 0; start_ptr[i] != ','; i++) { time[i] = start_ptr[i]; //copy time string } - + if (atoi(date) != 0) { //this logic wont work on Jan 1 2100 time_set_by_strings(date, time); menu_send_CTL(); usb_tx_string_P(PSTR("GPS time sync @ ")); time_print_human_readable(); - menu_send_n_st(); + menu_send_n_st(); } } @@ -356,4 +409,24 @@ void GSM_control_fail (void) { char * GSM_get_imei (void) { return &imei; +} + +void GSM_command_power_off(void) { + CTL_add_string_to_buffer_P(&GSM, BUFFER_OUT, PSTR("AT+CPOF\r")); //compose message + CTL_mark_for_processing(&GSM, BUFFER_OUT); +} + +void GSM_command_enable_gps_auto(int enable) { + switch(enable) { + case 0: + CTL_add_string_to_buffer_P(&GSM, BUFFER_OUT, PSTR("AT+CGPSAUTO=0\r")); //compose message + break; + + case 1: + CTL_add_string_to_buffer_P(&GSM, BUFFER_OUT, PSTR("AT+CGPSAUTO=1\r")); //compose message + break; + + default: + break; + } } \ No newline at end of file diff --git a/V2X_Firmware/src/V2X/V2X_gsm.h b/V2X_Firmware/src/V2X/V2X_gsm.h index dcd221d..e964e41 100644 --- a/V2X_Firmware/src/V2X/V2X_gsm.h +++ b/V2X_Firmware/src/V2X/V2X_gsm.h @@ -3,7 +3,7 @@ * * Created: 2/12/2016 11:01:18 AM * Author: jbanks2 - */ + */ #ifndef V2X_GSM_H_ @@ -11,20 +11,20 @@ /** * @def simcard_status - * @brief detection of SIMCARD by socket switch - * returns "true" if SIMCARD installed + * @brief detection of SIMCARD by socket switch + * returns "true" if SIMCARD installed **/ inline static bool simcard_status(void) {return 1-ioport_get_pin_level(SW1_PIN);} /** * @def sim_power_status - * @brief detection of SIMCARD by socket switch - * returns "true" if SIMCARD installed + * @brief detection of SIM module by pin + * returns "true" if SIM module is powered **/ inline static bool sim_power_status(void) {return ioport_get_pin_level(EXT1_PIN_SIM_PWR);} /** * @def sim_net_status - * @brief detection of SIMCARD by socket switch - * returns "true" if SIMCARD installed + * @brief detection of SIM network status pin + * returns "true" if SIM network pin detected **/ inline static bool sim_net_status(void) {return ioport_get_pin_level(EXT1_PIN_SIM_NETWORK);} @@ -87,7 +87,7 @@ enum GSM_sequence_states { GSM_state_time_get, GSM_state_wake_host }; - + /** * @def GSM_sequence_states * @brief generic switch for moving through control substates @@ -105,7 +105,7 @@ enum GSM_subsequence_states { GSM_subssequence_10, GSM_subssequence_FAIL }; - + /** * @def GSM_control * @brief head of the controller sequencer, sends calls into corect module @@ -153,6 +153,13 @@ void GSM_time_job (void); */ void GSM_time_sync (char * responce_buffer); +/** + * @def GSM_command_enable_gps_auto + * @brief send command to enable gps auto start in SIMCOM + * @param enable integer 0/1 to disable/enable respectively + */ +void GSM_command_enable_gps_auto(int enable); + /** * @def GSM_parse_gps_info * @brief takes GPS string parses into usable sections @@ -173,4 +180,9 @@ void GSM_control_fail (void); */ char * GSM_get_imei (void); +/** + *@def GSM_power_off + *@brief send a shutdown command to the gsm + */ +void GSM_command_power_off(void); #endif /* V2X_GSM_H_ */ \ No newline at end of file diff --git a/V2X_Firmware/src/V2X/V2X_init.c b/V2X_Firmware/src/V2X/V2X_init.c index 77a77c2..f297145 100644 --- a/V2X_Firmware/src/V2X/V2X_init.c +++ b/V2X_Firmware/src/V2X/V2X_init.c @@ -11,8 +11,12 @@ uint8_t reset_flags = RESET_NONE; void pin_init(void) { +#if V2X_REV <= REV_12 + /* DELETEME: HUB_STATUS unnecessary without FTDI in the mix */ ioport_configure_pin(EXT1_PIN_HUB_STATUS , IOPORT_DIR_INPUT ); ioport_configure_pin(EXT1_PIN_HUB_SUSPEND , IOPORT_DIR_INPUT ); //NON_REM[0] USB hub Boot Strapping option, strapped by resistor +#endif + ioport_configure_pin(EXT1_PIN_HUB_STATUS , IOPORT_DIR_INPUT ); ioport_configure_pin(EXT1_PIN_HOST_SHORT_CIRCUIT , IOPORT_DIR_INPUT ); ioport_configure_pin(EXT1_PIN_CAN_TXD , IOPORT_DIR_INPUT ); @@ -29,11 +33,15 @@ void pin_init(void) ioport_configure_pin(EXT1_PIN_SR_CLEAR , IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH ); ioport_configure_pin(EXT1_PIN_SR_LATCH , IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW ); +#if V2X_REV <= REV_12 ioport_configure_pin(EXT1_PIN_HUB_SDA , IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH ); //1 for NON_REM[1] USB hub Boot Strapping option ioport_configure_pin(EXT1_PIN_HUB_SCL , IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW ); //0 for CFG_SEL USB hub Boot Strapping option +#endif +#if V2X_REV <= REV_12 ioport_configure_pin(EXT1_PIN_ACL_RXD , IOPORT_DIR_INPUT ); ioport_configure_pin(EXT1_PIN_ACL_TXD , IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH ); +#endif ioport_configure_pin(EXT1_PIN_SIM_WAKE , IOPORT_DIR_INPUT ); ioport_configure_pin(EXT1_PIN_SIM_NETWORK , IOPORT_DIR_INPUT ); @@ -41,21 +49,42 @@ void pin_init(void) //ioport_configure_pin(EXT1_PIN_SIM_TXD , IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH ); //ioport_configure_pin(EXT1_PIN_SIM_RXD , IOPORT_DIR_INPUT ); - ioport_configure_pin(EXT1_PIN_SIM_PWR , IOPORT_DIR_INPUT ); + ioport_configure_pin(EXT1_PIN_SIM_PWR , IOPORT_DIR_INPUT ); ioport_configure_pin(EXT1_PIN_SEQ_RXD , IOPORT_DIR_INPUT ); ioport_configure_pin(EXT1_PIN_SEQ_TXD , IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH ); - ioport_configure_pin(LED_0_PIN , IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW ); - ioport_configure_pin(LED_1_PIN , IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW ); - ioport_configure_pin(LED_2_PIN , IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW ); +//high here turns leds off because of inverse logic in rev 2.0 + ioport_configure_pin(LED_0_PIN , IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH ); + ioport_configure_pin(LED_1_PIN , IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH ); + ioport_configure_pin(LED_2_PIN , IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH ); - ioport_configure_pin(BUTTON_0_PIN , IOPORT_DIR_INPUT ); + ioport_configure_pin(BUTTON_0_PIN , IOPORT_DIR_INPUT | IOPORT_SENSE_FALLING); ioport_configure_pin(BUTTON_1_PIN , IOPORT_DIR_INPUT | IOPORT_PULL_UP ); //NON_REM[1] USB hub Boot Strapping option + #if V2X_REV <= REV_12 +/* REV_20: don't use this pin at all, let it default to input */ ioport_configure_pin(BUF0_PIN , IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW ); //blocks atmel serial path to CAN through buffer + /* only use FDTI buffer in previous revision */ ioport_configure_pin(BUF1_PIN , IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW ); //enables FTDI serial path to CAN through buffer + #endif + #if V2X_REV <= REV_12 + /* Revision 1.2: + * Use charge pump for powering leds + */ ioport_configure_pin(CHARGEPUMP_0_PIN , IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW ); + #endif +#if V2X_REV >= REV_20 + /* 3v3 pin init, low by default... */ + ioport_configure_pin(PWR_3V3_PIN , IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH ); +#endif + +} + +void enable_v2x_interrupts(void) { + // PORTA.PIN0CTRL = (PORT_ISC_RISING_gc); // set port to sense rising edge + PORTA.INT0MASK = (0x01); // select PA0 for INT source + PORTA.INTCTRL |= PORT_INT0LVL_MED_gc; // enable interrupt 0 at medium } /* This function is meant to contain board-specific initialization code @@ -65,13 +94,14 @@ void pin_init(void) void v2x_board_init(void) { irq_initialize_vectors(); - pmic_init(); sysclk_init(); //configure clock sources for core and USB sleepmgr_init(); // Initialize the sleep manager ioport_init(); //Initializes the IOPORT service pin_init(); //whole chip pin init, modes and initial conditions spi_start(); //start SPI driver PWR_init(); //sets SR to default states - holds power up + enable_v2x_interrupts(); + pmic_init(); cpu_irq_enable(); eeprom_init(); //verifies eeprom safe for use menu_init(); //loads menu settings @@ -80,9 +110,14 @@ void v2x_board_init(void) ACL_init(); //configures, but does not start sampling GSM_usart_init(); //starts direct serial channel to the SIM module CAN_uart_start(); //starts direct serial channel to the ELM module - canbus_serial_routing(AVR_ROUTING); //cause the serial 3-state buffer to route the serial path from the ELM to the FTDI +#if V2X_REV <= REV_12 + /* Only applies to buffers. Not needed Rev 2.0 */ + canbus_serial_routing(AVR_ROUTING); //cause the serial 3-state buffer to route the serial path from the ELM to the FTDI +#endif udc_start(); //start stack and vbus monitoring +#if V2X_REV <= REV_12 PWR_hub_start(); //connect the hub to the computer +#endif //autostart all systems delay_ms(500); @@ -90,6 +125,10 @@ void v2x_board_init(void) CAN_elm_init(); ACL_set_sample_on(); PWR_host_start(); +#ifdef GPS_AUTO + //send gps auto start command + GSM_command_enable_gps_auto(1); +#endif } void reset_processor(void) { @@ -97,9 +136,10 @@ void reset_processor(void) { if (reset_flags & (1<")); delay_s(3); - CCP = 0xd8; //enable write protected registers - RST_CTRL = true; //force SW reset + // use write protected inteface to software reset + ccp_write_io((uint8_t *)&RST.CTRL, RST_SWRST_bm); } +#if V2X_REV <= REV_12 if (reset_flags & (1<")); delay_s(3); @@ -109,6 +149,18 @@ void reset_processor(void) { delay_s(1); reset_flags &= ~(1<")); @@ -120,8 +172,9 @@ void reset_processor(void) { if (reset_flags & (1<")); - PWR_gsm_stop(); - delay_ms(100); + // Forces reset of GSM + PWR_gsm_reset(); + delay_ms(500); GSM_modem_init(); reset_flags &= ~(1<= REV_20 +/* Revision 2.0: + * LED pins have been remapped from the ADC (analog-digital) channel ports to + * OC (output compare). Currently, the pins are driven completely in software, + * on update, which is undesireable and inefficient. + * In the future, the LEDs should be driven by using PWM from Timer0, so that + * updates are sent only when necessary, and the LEDs are driven by hardware + * peripheral. + */ +#endif + +#if V2X_REV <= REV_12 /** * @def charge_pump_toggle * @brief Causes the pin driving the charge pump circuit to toggle state HIGH<>LOW **/ inline static void charge_pump_toggle(void) {gpio_toggle_pin(CHARGEPUMP_0_PIN); } +#endif +#if V2X_REV <= REV_12 /** * @def led_0_on * @brief Causes the pin driving the RED POWER LED to turn ON @@ -25,7 +39,7 @@ inline static void led_0_on (void) {gpio_set_pin_high(LED_0_PIN); } * @def led_0_off * @brief Causes the pin driving the RED POWER LED to turn OFF **/ -inline static void led_0_off (void) {gpio_set_pin_low(LED_0_PIN); } +inline static void led_0_off (void) {gpio_set_pin_low(LED_0_PIN); } /** * @def led_1_on @@ -51,6 +65,46 @@ inline static void led_2_on (void) {gpio_set_pin_high(LED_2_PIN); } **/ inline static void led_2_off (void) {gpio_set_pin_low(LED_2_PIN); } +#elif V2X_REV >= REV_20 + +/** + * @def led_0_on + * @brief Causes the pin driving the RED POWER LED to turn ON + **/ +inline static void led_0_on (void) {gpio_set_pin_low(LED_0_PIN); } + +/** + * @def led_0_off + * @brief Causes the pin driving the RED POWER LED to turn OFF + **/ +inline static void led_0_off (void) {gpio_set_pin_high(LED_0_PIN); } + +/** + * @def led_1_on + * @brief Causes the pin driving the GREEN GSM LED to turn ON + **/ +inline static void led_1_on (void) {gpio_set_pin_low(LED_1_PIN); } + +/** + * @def led_1_off + * @brief Causes the pin driving the GREEN GSM LED to turn OFF + **/ +inline static void led_1_off (void) {gpio_set_pin_high(LED_1_PIN); } + +/** + * @def led_2_on + * @brief Causes the pin driving the BLUE GPS LED to turn ON + **/ +inline static void led_2_on (void) {gpio_set_pin_low(LED_2_PIN); } + +/** + * @def led_2_off + * @brief Causes the pin driving the BLUE GPS LED to turn OFF + **/ +inline static void led_2_off (void) {gpio_set_pin_high(LED_2_PIN); } + +#endif + /** * @def led_update * @brief Updates the leds diff --git a/V2X_Firmware/src/V2X/V2X_menu.c b/V2X_Firmware/src/V2X/V2X_menu.c index 2073b4c..791718f 100644 --- a/V2X_Firmware/src/V2X/V2X_menu.c +++ b/V2X_Firmware/src/V2X/V2X_menu.c @@ -3,7 +3,7 @@ * * Created: 2/23/2016 9:00:14 AM * Author: jbanks2 - */ + */ #include "V2X.h" #include "ctype.h" @@ -23,7 +23,10 @@ void menu_add_to_command(char value) { CMD_buffer[leng-1] = '\0'; //null out the last char } } else if (value > 0x20 && value < 0x7E ) { //if in ascii set - strcat(CMD_buffer, &value); //store to buffer + char char_str[2] = {'?','\0'}; + char_str[0] = value; + strcat(CMD_buffer, char_str); //store to buffer + } } @@ -34,10 +37,15 @@ void menu_main(void) { if (CMD_buffer[0] == 'v' && CMD_buffer[1] == 'x') { switch(CMD_buffer[2]) { case 'i': //information - usb_tx_string_P(PSTR("Vehicle to Everything (V2X) RVI Node 2016\rOpen source hardware and software\rHW Rev1.2 \rSW Rev0.1\r")); +#if V2X_REV <= REV_12 + usb_tx_string_P(PSTR("Vehicle to Everything (V2X) RVI Node 2016\r\nOpen source hardware and software\r\nHW Rev1.2 \r\nSW Rev0.1\r\n")); + break; +#elif V2X_REV >= REV_20 + usb_tx_string_P(PSTR("Vehicle to Everything (V2X) RVI Node 2016\r\nOpen source hardware and software\r\nHW Rev2.0 \r\nSW Rev0.2\r\n")); break; +#endif case 'j': //Jaguar - usb_tx_string_P(PSTR("\r\r ,ggp@@@@mgg,,\r,$Q$(`S@@$;g$$$$$@$@@gg,\r;gP'$@gg)$$@@$@@@$(L$$||$$@g,\r `g$P` ``*%@@@P`)Eg|||lLLL||$Bgg,\r ` ,gg$$@gg,`$..``$Z$$$$$EB$$@g,\r @P`pgg$$$||`)gggg;,, |$$$|$$$@g,\r 9w& '*^^` ``*P#9BB00000$$$@|`$$$g|Sg,\r *$@@L ```T$W~)%g,\r *%@gg,,,,, 5/Sw, ,\r ```` ` `9g `9g,``*^|'\r `#g,`)h\r\r Developed at Jaguar Land Rover OSCT. Portland OR 2016\r")); + usb_tx_string_P(PSTR("\r\n\r\n ,ggp@@@@mgg,,\r\n,$Q$(`S@@$;g$$$$$@$@@gg,\r\n;gP'$@gg)$$@@$@@@$(L$$||$$@g,\r\n `g$P` ``*%@@@P`)Eg|||lLLL||$Bgg,\r\n ` ,gg$$@gg,`$..``$Z$$$$$EB$$@g,\r\n @P`pgg$$$||`)gggg;,, |$$$|$$$@g,\r\n 9w& '*^^` ``*P#9BB00000$$$@|`$$$g|Sg,\r\n *$@@L ```T$W~)%g,\r\n *%@gg,,,,, 5/Sw, ,\r\n ```` ` `9g `9g,``*^|'\r\n `#g,`)h\r\n\r\n Developed at Jaguar Land Rover OSCT. Portland OR 2016\r\n")); break; case 'q': menu_status(); @@ -63,17 +71,17 @@ void menu_main(void) { case 'v': //toggle verbose setting verbose = !verbose; nvm_eeprom_write_byte(EE_verbose,verbose); - usb_tx_string_PV(PSTR("Verbose is ON")); + usb_tx_string_PV(PSTR("Verbose is ON\r\n")); break; case '?': //timer functions default: - usb_tx_string_P(PSTR("*** Main Menu ***\rI: Device information\rA: Accelerometer menu(ACL)\rC: ELM327 menu(CAN)\rM: SIM Modem menu(GSM)\rP: Power menu\rT: Timer menu\rQ: Query system status\rV: Toggle verbose messages\rR: Reboot\r")); + usb_tx_string_P(PSTR("*** Main Menu ***\r\nI: Device information\r\nA: Accelerometer menu(ACL)\r\nC: ELM327 menu(CAN)\r\nM: SIM Modem menu(GSM)\r\nP: Power menu\r\nT: Timer menu\r\nQ: Query system status\r\nV: Toggle verbose messages\r\nR: Reboot\r\n")); break; } }else{ - usb_tx_string_PV(PSTR("All commands start VX\r")); + usb_tx_string_PV(PSTR("All commands start VX\r\n")); } - clear_buffer(CMD_buffer); //clear the buffer for next command + clear_buffer(CMD_buffer); //clear the buffer for next command menu_send_n_st(); } @@ -89,7 +97,7 @@ void menu_accel (void) { usb_tx_string_PV(PSTR("Accelerometer started")); break; case 'i': - usb_tx_string_P(PSTR("V2X uses the ADXL345 accelerometer from Analog Devices\r")); + usb_tx_string_P(PSTR("V2X uses the ADXL345 accelerometer from Analog Devices\r\n")); break; case 'q': menu_accel_status(); @@ -105,7 +113,7 @@ void menu_accel (void) { case 's': //sample rate speed = atoi(CMD_buffer+4); if (speed > 3199) { - ACL_set_rate(ACL_RATE_3200); + ACL_set_rate(ACL_RATE_3200); usb_tx_string_PV(PSTR("Set to 3200Hz")); }else if (speed > 1599) { ACL_set_rate(ACL_RATE_1600); @@ -140,7 +148,7 @@ void menu_accel (void) { }else if (speed > 0) { ACL_set_rate(ACL_RATE_1); usb_tx_string_PV(PSTR("Set to 1Hz")); - }else { + }else { usb_tx_string_P(PSTR("ERROR: Out of range, try again.")); } break; @@ -161,7 +169,7 @@ void menu_accel (void) { usb_tx_string_PV(PSTR("+/-2G Range")); }else {menu_send_out_of_range();} break; - + case 'x': case 'y': case 'z': @@ -207,60 +215,61 @@ void menu_accel (void) { } else { ACL_take_sample(sample); } - ACL_data_to_string(sample, CMD_buffer); + ACL_data_to_string(sample, CMD_buffer); for (int i = 0; i < strlen(CMD_buffer); i++) {usb_cdc_send_byte(USB_CMD, CMD_buffer[i]);} } else { - usb_tx_string_P(PSTR("ERROR: Not currently sampling, use VXAE\r"));} - + usb_tx_string_P(PSTR("ERROR: Not currently sampling, use VXAE\r\n"));} + break; case 'f': if (CMD_buffer[4] == '0') { ACL_set_full_resolution(0); - usb_tx_string_PV(PSTR("10bit resolution, scale changes with 'G' range\r")); + usb_tx_string_PV(PSTR("10bit resolution, scale changes with 'G' range\r\n")); } else if (CMD_buffer[4] == '1') { ACL_set_full_resolution(1); - usb_tx_string_PV(PSTR("Full resolution, 4mg/bit\r")); + usb_tx_string_PV(PSTR("Full resolution, 4mg/bit\r\n")); } else {menu_send_q();} break; - case '?': + case '?': default: - usb_tx_string_P(PSTR("*** Accelerometer Menu ***\rE: Enable\rD: Disable\rR: Restart\rI: Subsystem Information\rQ: Query status\rG: Get last Sample\rSn: Set sample rate in HZ (1, 3, 6, 12, 25, 50, 100, 200, 400, 800)\rWn: Set \"G\" Range (2, 4, 8, 16)\rFn: Full range (1: full 0: 10bit)\rXn: Set X offset (+/-127)\rYn: Set Y offset\rZn: Set Z offset\r")); + usb_tx_string_P(PSTR("*** Accelerometer Menu ***\r\nE: Enable\r\nD: Disable\r\nR: Restart\r\nI: Subsystem Information\r\nQ: Query status\r\nG: Get last Sample\r\nSn: Set sample rate in HZ (1, 3, 6, 12, 25, 50, 100, 200, 400, 800)\r\nWn: Set \"G\" Range (2, 4, 8, 16)\r\nFn: Full range (1: full 0: 10bit)\r\nXn: Set X offset (+/-127)\r\nYn: Set Y offset\r\nZn: Set Z offset\r\n")); break; } } void menu_modem (void) { - int i; + int i; switch (CMD_buffer[3]) { - case 'd': + case 'd': PWR_gsm_stop(); //disable - usb_tx_string_PV(PSTR("GSM is off\r")); + usb_tx_string_PV(PSTR("GSM shutdown\r\n")); break; case 'e': //enable modem - usb_tx_string_PV(PSTR("GSM Start pending")); + usb_tx_string_PV(PSTR("GSM Start pending\r\n")); GSM_modem_init(); break; case 'r': //reset reset_trigger_GSM(); - usb_tx_string_PV(PSTR("GSM restarting")); + usb_tx_string_PV(PSTR("GSM RESET\r\n")); break; case 'q': menu_modem_status(); break; case 'i': - usb_tx_string_P(PSTR("V2X uses the SIM5320A 3G GSM modem + GPS receiver by SIMCOM\r")); + usb_tx_string_P(PSTR("V2X uses the SIM5320A 3G or SIM7100a 4G GSM modem + GPS receiver by SIMCOM\r\n")); break; case 'x': - strcat_P(CMD_buffer, PSTR("\r\n")); //put these char at the end of the string + // FIXME: please verify that the newline is actually warranted here + strcat_P(CMD_buffer, PSTR("\r")); //put these char at the end of the string GSM_add_string_to_buffer(BUFFER_OUT, &CMD_buffer[4]); //send it on to the modem GSM_mark_for_processing(BUFFER_OUT); //initiate send break; case '?': default: - usb_tx_string_P(PSTR("*** Modem Menu ***\rE: Enable\rD: Disable\rR: Restart\rI: Subsystem Information\rQ: Query status\rX: AT Command Pass through\r")); + usb_tx_string_P(PSTR("*** Modem Menu ***\r\nE: Enable\r\nD: Disable\r\nR: RESET. Emergency use.\r\nI: Subsystem Information\r\nQ: Query status\r\nX: AT Command Pass through\r\n")); break; } } @@ -270,33 +279,33 @@ void menu_can (void) { char buffer[EE_CAN_ARRAY_SIZE+1]; switch (CMD_buffer[3]) { case 'd': //disable; - usb_tx_string_PV(PSTR("CAN is off\r")); + usb_tx_string_PV(PSTR("CAN is off\r\n")); PWR_can_stop(); PWR_is_5_needed(); break; case 'e': //enable - usb_tx_string_PV(PSTR("CAN Starting\r")); + usb_tx_string_PV(PSTR("CAN Starting\r\n")); CAN_elm_init(); break; case 'r': //reset - usb_tx_string_PV(PSTR("CAN restarting\r")); + usb_tx_string_PV(PSTR("CAN restarting\r\n")); reset_trigger_CAN(); break; case 'q': //query menu_can_status(); break; case 'i': //info - usb_tx_string_P(PSTR("V2X uses the STN1110 CANbus interface from Scantool\rThe STN1110 is compliant with the ELM327 V1.3\r")); + usb_tx_string_P(PSTR("V2X uses the STN1110 CANbus interface from Scantool\r\nThe STN1110 is compliant with the ELM327 V1.3\r\n")); break; case 'x': //pass command - strcat_P(CMD_buffer, PSTR("\r")); - + strcat_P(CMD_buffer, PSTR("\r\n")); + CAN_add_string_to_buffer(BUFFER_OUT, CMD_buffer+4); CAN_mark_for_processing(BUFFER_OUT); CAN_start_snoop(); break; case 's': //save string to eeprom - //strcat_P(CMD_buffer, PSTR("\r")); + //strcat_P(CMD_buffer, PSTR("\r\n")); eeprom_store_CAN_string(CMD_buffer+4); break; case 'w': //what is stored in EE? @@ -308,7 +317,7 @@ void menu_can (void) { break; case '?': default: - usb_tx_string_P(PSTR("*** CANbus Menu ***\rE: Enable\rD: Disable\rR: Restart\rS: Store config string to EE\rA: Execute config string in EE\rW: Display config string in EE\rI: Subsystem Information\rQ: Query status\r")); + usb_tx_string_P(PSTR("*** CANbus Menu ***\r\nE: Enable\r\nD: Disable\r\nR: Restart\r\nS: Store config string to EE\r\nA: Execute config string in EE\r\nW: Display config string in EE\r\nI: Subsystem Information\r\nQ: Query status\r\n")); break; } } @@ -317,26 +326,47 @@ void menu_power (void) { switch (CMD_buffer[3]) { case 'd': //disable power switch (CMD_buffer[4]) { +#if V2X_REV <= REV_12 case '3': //3v usb_tx_string_PV(PSTR("Disabling 3V supply")); PWR_turn_off((1<= REV_20 + /* DEBUG: DELETEME: Explicit test of 3v switching for use ONLY DURING TESTING + * while the power ouptut is properly disabled + */ + case '3': + usb_tx_string_PV(PSTR("Disabling 3v pin")); + PWR_3_stop(); + break; +#endif + case '4': //4v usb_tx_string_PV(PSTR("Disabling 4V supply")); +#if V2X_REV <= REV_12 PWR_turn_off((1<= REV_20 + PWR_4_stop(); +#endif break; case '5': //5v usb_tx_string_PV(PSTR("Disabling 5V supply")); - PWR_turn_off((1<= REV_20 + case 'a': // disable all. shutdown. + PWR_shutdown(); break; +#endif default: menu_send_q(); break; @@ -344,15 +374,31 @@ void menu_power (void) { break; //disable power case 'e': //enable power switch (CMD_buffer[4]) { +#if V2X_REV <= REV_12 case '3': //3v usb_tx_string_PV(PSTR("Enabling 3V supply")); PWR_turn_on((1<= REV_20 + /* DEBUG: DELETEME: Explicit test of 3v switching for use ONLY DURING TESTING + * while the power ouptut is properly disabled + */ + case '3': + usb_tx_string_PV(PSTR("Enabling 3v pin")); + PWR_3_start(); + break; +#endif + case '4': //4v usb_tx_string_PV(PSTR("Enabling 4V supply")); +#if V2X_REV <= REV_12 PWR_turn_on((1<= REV_20 + PWR_4_start(); +#endif break; case '5': //5v usb_tx_string_PV(PSTR("Enabling 5V supply")); @@ -361,15 +407,14 @@ void menu_power (void) { break; case 'h': //host usb_tx_string_PV(PSTR("Enabling Host power supply")); - PWR_turn_on((1<")); -} +void menu_send_n_st(void) {usb_tx_string_P(PSTR("\r\n>")); +} -void menu_send_out_of_range(void) {usb_tx_string_P(PSTR("ERROR: out of range\r")); +void menu_send_out_of_range(void) {usb_tx_string_P(PSTR("ERROR: out of range\r\n")); } void menu_send_GSM(void) {usb_tx_string_P(PSTR("GSM>:")); @@ -465,10 +510,10 @@ void menu_send_GSM(void) {usb_tx_string_P(PSTR("GSM>:")); void menu_send_CTL(void) {usb_tx_string_P(PSTR("CTL>:")); } - + void menu_send_CAN(void) {usb_tx_string_P(PSTR("CAN>:")); } - + void menu_send_BTN(void) {usb_tx_string_P(PSTR("BTN>:")); } @@ -476,7 +521,7 @@ Bool menu_verbose(void) { return verbose; } -void menu_print_int(long value) { +void menu_print_int(long value) { char c_buf[13]; ltoa(value, c_buf, 10); int i = 0; //clear the pointer @@ -503,12 +548,14 @@ void usb_tx_string_PV(const char *data) { } void menu_lockup (void) { - char msg[] = "AVR>>RESET:\r"; + char msg[] = "AVR>>RESET:\r\n"; usb_cdc_send_string(USB_CMD, msg); usb_cdc_send_string(USB_ACL, msg); usb_cdc_send_string(USB_CAN, msg); delay_s(1); +#if V2X_REV <= REV_12 PWR_hub_stop(); +#endif delay_s(1); RST_CTRL = true; //force SW reset } @@ -560,10 +607,18 @@ void menu_can_status(void) { } void menu_power_status(void) { +#if V2X_REV <= REV_12 usb_tx_string_P(PSTR("3V3=")); if (PWR_query((1<= REV_20 + usb_tx_string_P(PSTR("3V3=")); + if (ioport_get_pin_level(PWR_3V3_PIN)==true) + {menu_send_1();} + else {menu_send_0();} +#endif usb_tx_string_P(PSTR("4V1=")); if (PWR_query((1<= REV_20 + + /* Need to drive high 3v3_EN signal here, to ensure CPU operation. + * A later check will turn off 3v if we have chosen to enable 4v + */ + PWR_3_start(); + #endif PWR_clear(); // Clear shift register PWR_latch(); // Latch all internal registers to output power_control_state = POWER_CONTROL_DEFAULT_VALUE; + #if V2X_REV >= REV_20 + /* Additional check, if 4v was enabled by default config, please disable 3v */ + PWR_3_is_needed(); + #endif PWR_push(); //update shift register state delay_ms(100); //allow power to stabilize } @@ -32,26 +43,38 @@ void PWR_clear(void) } void PWR_push(void) { //uses shift_register_state to update the shift register +#if V2X_REV <= REV_12 +/* With 2 shift registers, it is necessary to copy the power control values into + * 2 packets, with MSB written first, so that the 2 byte sequence lands on the + * register outputs in the proper order. + */ uint8_t data[2]; data[1] = power_control_state & 0xff; - data[0] = (power_control_state >> 8) & 0xff; + data[0] = (power_control_state >> 8) & 0xff; spi_write_packet(SR_SPI, data, 2); +#elif V2X_REV >= REV_20 + /* We should be able to send the single byte to the single shift register, + * as long as the bit order has been respected. + */ + spi_write_packet(SR_SPI, &power_control_state, 1); +#endif PWR_latch(); } -void PWR_turn_on (uint16_t pins_mask) { //updates the power state variable but does not update shift register +void PWR_turn_on (SHIFT_REGISTER_TYPE pins_mask) { //updates the power state variable but does not update shift register power_control_state |= pins_mask; } -void PWR_turn_off(uint16_t pins_mask) { //updates the power state variable but does not update shift register +void PWR_turn_off(SHIFT_REGISTER_TYPE pins_mask) { //updates the power state variable but does not update shift register power_control_state &= ~(pins_mask); } -Bool PWR_query(uint16_t mask) { +Bool PWR_query(SHIFT_REGISTER_TYPE mask) { if ((power_control_state & mask) != 0) {return true;} else {return false;} } +#if V2X_REV <= REV_12 void PWR_hub_start(void) { PWR_turn_on((1<= REV_20 +/* 3 volt power pin manipulation + * Use with caution! 3v should only be enabled when not using 4v + * When transitioning to 3v power only, enable 3v immediately before disabling + * 4v. + */ +void PWR_3_start(void) { + gpio_set_pin_high(PWR_3V3_PIN); +} + +/* 3 volt power pin manipulation + * Use with caution! Please disable 3v immediately after enabling 4v. + * Disabling 3v AND 4v will result in power loss to CPU. V2X system will + * require manual restart. + */ + +void PWR_3_stop(void) { + gpio_set_pin_low(PWR_3V3_PIN); +} + +void PWR_3_is_needed(void) { + /* Check to see if 3v should be switched off due to 4v being enabled + * One might expect that we'd provide for turning 3v on here as well. + * Testing has shown however, that manipulation of the 3v is timing critical, + * and should take place exactly when we mean it to. This is intended only + * as a safety check to ensure the 4v and 3v don't fight. + * */ + if (power_control_state & (1<= REV_20 + // GSM_command_power_off(); + PWR_turn_on(1<= REV_20 + PWR_turn_on(1<= REV_20 +#define SHIFT_REGISTER_TYPE uint8_t +#endif + /** * @def shift_register_state * @brief variable that holds the current power state. */ -volatile uint16_t power_control_state; +volatile SHIFT_REGISTER_TYPE power_control_state; /** * @def STATE_DEFAULT_VALUE * @brief default power state. enables 3v3 only */ -#define POWER_CONTROL_DEFAULT_VALUE (1<= REV_20 +#define POWER_CONTROL_DEFAULT_VALUE (1<= REV_20 +/** + * @def PWR_3_start + * @brief enable 3v pin + */ +void PWR_3_start(void); + +/** + * @def PWR_3_stop + * @brief disable 3v pin + */ +void PWR_3_stop(void); + +/** + * @def PWR_3_is_needed + * @brief check if 3v pin should be disabled + */ +void PWR_3_is_needed(void); + +/** + * @def PWR_4_start + * @brief Enable 4v power supply, disabling 3v pin + */ +void PWR_4_start(void); + +/** + * @def PWR_4_stop + * @brief Disable 4v power supply, after enabling 3v pin to keep CPU alive + */ +void PWR_4_stop(void); + +/** + * @def PWR_shutdown + * @brief Disable all power. Manual restart of board required. + */ +void PWR_shutdown(void); + +#endif + +/** + * @def PWR_5_stop + * @brief stop 5v rail + */ +void PWR_5_stop (void); /** * @def PWR_is_5_needed @@ -104,6 +183,12 @@ void PWR_host_start(void); */ void PWR_host_stop(void); +/** + * @def PWR_5_stop + * @brief disables the 5v completely +*/ +void PWR_5_stop(void); + /** * @def PWR_can_stop * @brief disables the ELM with hardware reset pin turns off 5v rail if unused @@ -118,14 +203,20 @@ void PWR_can_start (void); /** * @def GSM_start - * @brief sends a sequence to enable the SIM5320 module + * @brief sends a sequence to enable the SIM module */ void PWR_gsm_start(void); /** - * @def power_sim_reset - * @brief sends a sequence to disable the SIM5320 module + * @def PWR_gsm_stop + * @brief sends a sequence to disable the SIM module */ void PWR_gsm_stop(void); +/** + * @def power_sim_reset + * @brief Forces reset of the SIM module. Please use sparingly, with caution. + */ +void PWR_gsm_reset(void); + #endif /* V2X_DRIVERS_H_ */ \ No newline at end of file diff --git a/V2X_Firmware/src/V2X/V2X_uart.c b/V2X_Firmware/src/V2X/V2X_uart.c index 7962ccf..9783c5c 100644 --- a/V2X_Firmware/src/V2X/V2X_uart.c +++ b/V2X_Firmware/src/V2X/V2X_uart.c @@ -3,22 +3,29 @@ * * Created: 2/12/2016 10:34:41 AM * Author: jbanks2 - */ + */ #include "V2X.h" +#if V2X_REV <= REV_12 +/* DELETEME: Likely get rid of this entirely, like the aforementioned buffer cases */ void canbus_serial_routing(uint8_t source) { gpio_set_pin_low(BUF0_PIN); + + /* use FTDI by default */ gpio_set_pin_low(BUF1_PIN); if (source == FTDI_ROUTING) {gpio_set_pin_high(BUF1_PIN);} else /*(source == AVR_ROUTING)*/ {gpio_set_pin_high(BUF0_PIN);} + /* use Atmel */ + gpio_set_pin_high(BUF0_PIN); } +#endif void uart_config(uint8_t port, usb_cdc_line_coding_t * cfg) { if (port != USB_CAN) {return;} - + uint8_t reg_ctrlc; uint16_t bsel; @@ -120,7 +127,8 @@ void uart_rx_notify(uint8_t port) //message received over USB // || (data >= '0' && data <= '9') //numbers // || (data >= 'A' && data <= 'Z') //capitals // || (data >= 'a' && data <= 'z')) { //lower case - if (data >= 0x20 && data <= 0x7F || data == '\r' || data == 8) { +// + if (data >= 0x20 && data <= 0x7F || data == '\r' || data == '\n' || data == 8) { if (!udi_cdc_multi_is_tx_ready(port)) { //is TX ready udi_cdc_multi_signal_overrun(port); //no } else {udi_cdc_multi_putc(port, data);} //push char to loop back @@ -130,11 +138,11 @@ void uart_rx_notify(uint8_t port) //message received over USB } else { //was a standard character that should be stored in the buffer menu_add_to_command(data); } -// } else { //there was a special character -// //run through the buffer until it is empty -// while (udi_cdc_multi_is_rx_ready(port)) { -// data = udi_cdc_multi_getc(port); -// } + } else { //there was a special character + //run through the buffer until it is empty + while (udi_cdc_multi_is_rx_ready(port)) { + data = udi_cdc_multi_getc(port); + } } } }else if (port == USB_ACL) { //loop back @@ -148,7 +156,7 @@ void uart_rx_notify(uint8_t port) //message received over USB } else if (data == 'r' || data == 'R') { reset_trigger_SYSTEM(); } - udi_cdc_multi_putc(port, data); + udi_cdc_multi_putc(port, data); } } } @@ -159,8 +167,8 @@ ISR(USART_RX_Vect) uint8_t value = USART.DATA; if (CAN_is_controlled() || CAN_is_snooping() || usb_cdc_is_active(USB_CAN) == false) { CAN_new_data(value); - } - + } + if (usb_cdc_is_active(USB_CAN) == true){ //host is on, send over USB if (0 != (USART.STATUS & (USART_FERR_bm | USART_BUFOVF_bm))) { @@ -180,8 +188,8 @@ ISR(USART_DRE_Vect) { if (CAN_is_controlled() || CAN_is_snooping() || !usb_cdc_is_active(USB_CAN) == true) { //can controller needs to send data CAN_send_data(); - } - + } + if (usb_cdc_is_active(USB_CAN) == true){ //usb is in control // Data from USB if (udi_cdc_is_rx_ready()) { diff --git a/V2X_Firmware/src/V2X/V2X_uart.h b/V2X_Firmware/src/V2X/V2X_uart.h index 6c9303e..c0961dc 100644 --- a/V2X_Firmware/src/V2X/V2X_uart.h +++ b/V2X_Firmware/src/V2X/V2X_uart.h @@ -3,7 +3,7 @@ * * Created: 2/12/2016 10:34:20 AM * Author: jbanks2 - */ + */ #ifndef V2X_UART_H_ @@ -14,8 +14,10 @@ * @brief The two states the serial buffer can have **/ enum buffer_routing{ - AVR_ROUTING = 0, - FTDI_ROUTING + AVR_ROUTING = 0 +#if V2X_REV <= REV_12 + , FTDI_ROUTING +#endif }; /** diff --git a/V2X_Firmware/src/V2X/V2X_usb.c b/V2X_Firmware/src/V2X/V2X_usb.c index c92f345..a4b6949 100644 --- a/V2X_Firmware/src/V2X/V2X_usb.c +++ b/V2X_Firmware/src/V2X/V2X_usb.c @@ -41,30 +41,30 @@ void usb_cdc_set_dtr(uint8_t port, bool b_enable) if (b_enable) { // Host terminal has open COM if (port == USB_CAN) { - led_0_on(); + //led_0_on(); CAN_uart_stop(); // close direct path uart_open(port); // Open USB passthrough communication }else if (port == USB_CMD) { - led_1_on(); + //led_1_on(); menu_send_n_st(); //start Hayes CMD interface }else if (port == USB_ACL) { - led_2_on(); + //led_2_on(); //enable ACL //ACL_sample_on(); } } else { // Host terminal has close COM if (port == USB_CAN) { //change can from pass through to direct mode - led_0_off(); + //led_0_off(); uart_close(port); // close USB passthrough communication CAN_uart_start(); // open direct path }else if (port == USB_CMD) { - led_1_off(); + //led_1_off(); //start Hayes interface }else if (port == USB_ACL) { - led_2_off(); + //led_2_off(); //disable ACL //ACL_sample_off(); } diff --git a/V2X_Firmware/src/V2X/extra_files/conf_board.h b/V2X_Firmware/src/V2X/extra_files/conf_board.h index 8460b4b..94cea4c 100644 --- a/V2X_Firmware/src/V2X/extra_files/conf_board.h +++ b/V2X_Firmware/src/V2X/extra_files/conf_board.h @@ -1,11 +1,11 @@ /** - * \file clock_conf.h + * \file conf_board.h * * \brief Initial firmware for V2X bring up * * Author: Jesse Banks (jbanks2) * - * Usage: move this file to src/config/clock_conf.h by replacing the existing file. + * Usage: move this file to src/config/conf_board.h by replacing the existing file. */ #ifndef CONF_BOARD_H diff --git a/V2X_Firmware/src/V2X/extra_files/conf_usb.h b/V2X_Firmware/src/V2X/extra_files/conf_usb.h index 3c33369..c350fe1 100644 --- a/V2X_Firmware/src/V2X/extra_files/conf_usb.h +++ b/V2X_Firmware/src/V2X/extra_files/conf_usb.h @@ -1,11 +1,11 @@ /** - * \file clock_conf.h + * \file conf_usb.h * * \brief Initial firmware for V2X bring up * * Author: Jesse Banks (jbanks2) * - * Usage: move this file to src/config/clock_conf.h by replacing the existing file. + * Usage: move this file to src/config/conf_usb.h by replacing the existing file. */ #ifndef _CONF_USB_H_ diff --git a/V2X_Firmware/src/main.c b/V2X_Firmware/src/main.c index 682f762..d8b9465 100644 --- a/V2X_Firmware/src/main.c +++ b/V2X_Firmware/src/main.c @@ -33,16 +33,80 @@ int main () while (1){ sleepmgr_enter_sleep(); //go to sleep until interrupt + #if V2X_REV <= REV_12 charge_pump_toggle(); //charge pump pin needs toggled to create boost voltage for LEDs + #endif reset_processor(); //look for pending resets - button_service(); //SCAN and report the button + #if V2X_REV <= REV_12 charge_pump_toggle(); //charge pump pin needs toggled to create boost voltage for LEDs + #endif job_coordinator(); //schedule new jobs if needed GSM_process_buffer(); //handle any pending jobs for GSM CAN_process_buffer(); //handle any pending jobs for CAN + #if V2X_REV <= REV_12 charge_pump_toggle(); //charge pump pin needs toggled to create boost voltage for LEDs + #endif if (usb_cdc_is_active(USB_ACL)) //if host listening, {report_accel_data();} //create and send accel data + #if V2X_REV <= REV_12 charge_pump_toggle(); //charge pump pin needs toggled to create boost voltage for LEDs + #endif + led_update(); } } +#if V2X_REV >= REV_20 +/* Interrupt service routine for our button, on currently found on PORTA0 + * Because this pin is shared with other interesting pins, namely 3v, we + * have to be careful about what we do with the interrupt. + * Before proceeding, we check the state of the button pin, ensuring we are + * reacting to button press. If so, we want to disable the 3v as quickly as + * possible, so that the 4v and 3v are not fighting. + * This routine will sense the state of the button, and will not exit until + * release. Upon release, it reports the time held, and schedules a job to + * react to the button press in (1) second. + * If 3v was enabled when we entered it is enabled again before exit, so the + * Atmel will stay alive, but 3v is checked against the 4v enable a final time + * to ensure proper power state when leaving this routine. + */ +ISR(SW0_INT_VECT_0) +{ + if (ioport_get_pin_level(PWR_3V3_PIN) == true) + { + usb_tx_string_P(PSTR("**3v is UP!**\r")); + } + // do we need to make sure that it was actually the button that got us here? + if (ioport_get_pin_level(SW0_PIN) == SW0_ACTIVE) + { + // ask if 3v is up when the button was pressed + + bool en_3v = ioport_get_pin_level(PWR_3V3_PIN); + + //disable 3v while button down, so 3 and 4 don't fight + PWR_3_stop(); + + /* Hold in interrupt while pin tests held + * service timer and increment time held + * When released, exit the interrupt routine and report time held + * (call the button push consequence routine) + */ + while (ioport_get_pin_level(SW0_PIN) == SW0_ACTIVE) + { + button_service(); //call service and record time + } + + button_service(); //call service and final delta + + // handle_button_check(button_get_delta()); + job_set_timeout(SYS_PWR, 1); + + // if 3v was up when we entered, and 4v is NOT enabled, turn it right back on + if (en_3v == true); + { + PWR_3_start(); + } + // double check if 3 should be enabled before leaving, just in case + PWR_3_is_needed(); + } + +} +#endif diff --git a/field-support-manual.md b/field-support-manual.md new file mode 100644 index 0000000..4491af8 --- /dev/null +++ b/field-support-manual.md @@ -0,0 +1,501 @@ +# V2X Field Support Documentation + +> Work in progress. Some entries may be incomplete or missing. + +This documentation is intended to cover common V2X board use cases in the field. + +Please note that the documentation will include some information specific to the +GENIVI Smart-Cities project. + +> ## Vehicle Safety Warning +> * Do not attempt maintenance, operation, troubleshooting, or anything in this +> manual while the vehicle is in motion or operation. +> * Use of the V2X board and any related hardware or software is entirely at +> your own risk. The authors and maintainers assume no responsibility or +> liability whatsoever for any injury or damage to property anywhere, ever. +> * As a powered device, the V2X could drain a vehicle battery. Turn off the +> device when turning off the vehicle. Disconnect the device when leaving the +> vehicle unattaned. + +## Contents +* [V2X board description](#v2x-board-description) +* [Requiremments for Nominal V2X Operation](#requirements-v2x) + * [Power / OBD](#requirements-power) + * [GPS / network antenna](#requirements-gps) + * [SIM card](#requirements-sim) +* [Requirements for smart-cities](#requirements-smart-cities) + * [Host computer](#requirements-host-computer) + * [Raspberry Pi](#requirements-raspberry-pi) + * [GENIVI Yocto image](#requirements-yocto) + * [Smart Cities application](#requirements-smart-cities-application) +* [Hardware setup](#hardware-setup) + * [Cable connection](#cable-connection) + * [Case enclosure and mounting](#case-enclosure-and-mounting) + * [Sim card insertion instructions](#sim-card-instructions) + * [Bench Power Supply](#bench-power-supply) +* [Startup procedure](#startup-procedure) + * [Power requirements](#power-requirements) + * [Battery warning](#battery-warning) + * [Nominal light states](#nominal-light-states) + * [Nominal smart cities](#nominal-smart-cities) +* [Shutdown procedure](#shutdown-procedure) + * [Button power off](#button-power-off) + * [Button failure or fallback procedure](#button-failure) + * [When all else fails](#when-fails) + * [Command options for power off (see also command set)](#command-power-off) +* [V2X Interface and Control](#runtime-operation) + * [Communication Ports](#communication-ports) + * [Linux](#communication-ports-linux) + * [Windows](#communication-ports-windows) + * [Smart-cities interaction](#smart-cities-interaction) + * [Cellular](#cellular-operations) + * [Verification](#verification) + * [Toubleshooting](#troubleshooting) +* [V2X Command set](#v2x-command-set) +* [Firmware upgrade](#firmware-upgrade) + * [Tools required](#firmware-tools-required) + * [Programmer/Debugger](#tools-programmer) + * [Programmer Connection](#programmer-connection) + * [Example: AVR Dragon](#programmer-connection-dragon) + * [Procedure](#firmware-procedure) + * [Atmel Studio](#firmware-atmel-studio) + * [AVRDUDE](#firmware-avrdude) + +## V2X Board Description + +The Vehicle-to-Everything (V2X) board is a telemetry aggregation and delivery +device. It provides access to: + +* Accelerometer +* CAN/OBD interface via STN110/ELM327 +* GPS (requires antenna) +* GSM network connectivity, via SIMCOM chipset (requires 3g antenna, 3g SIM + card) +* Power over USB for host computer + +Configuration and operation can be handled manually, but the device is intended +to be complemented by a host computer for automated operation. + +## Requirements for Nominal V2X Operation + +### Power / OBD + +At minimum, the V2X requires a 12v power supply. Power requirements are met by a +standard OBDII-to-serial connection. + +> Please note: The board will draw power while in operation even if the vehicle +> engine is not engaged. Low power / suspend mode is not yet supported in +> firmware. It is recommended to power off the V2X board while vehicle is not in +> operation. + +### GPS / network antenna + +GPS and cellular network connections require a combination GPS/GSM 3g antenna. + +### SIM card + +Celllar network connectivity requires a properly provisioned SIM card. + + +## Requirements for Smart Cities + +### Host Computer + +#### Raspberry Pi + +#### GENIVI Yocto image + +#### Smart Cities application + +## Hardware setup + +> TODO: links to external hardware required + +> Please note: SIM card should be inserted before board is powered on, and it is +> likely easier to do so before connecting cables. + +Need: + +* V2X Board +* OBDII to serial cable +* GPS/GSM antenna +* (2) Micro USB to USB cables + +### Cable connection + +1. Connect OBDII-serial cable into vehicle OBDII port (under dash) and the V2X + serial port. +2. Connect GPS/GSM antenna cables. + > Typical configuration requires attaching + >* "gold" head to port marked "**GPS Antenna**" + >* "silver" head to port marked "**3g Cellular Network Antenna**" + + > Incorrectly reversing this connection will inhibit GPS signal, and should + be one of the first things to check if no GPS signal is observed. + +3. Connect USB cable from port on board marked (Host PWR) to host computer micro + usb power supply port. This will supply power to host computer (Raspberry Pi + or other). +4. Connect micro USB from port on board marked (Host DATA) to free USB port on + host computer. This is the line of communication between the board and the + host. + +> TODO: Pictures! + +### Case enclosure and mounting + +> TODO: Pictures! + +### Sim card insertion instructions + +> TODO: Pictures! + +Proper SIM card alignment is critical to cellular network operation. + +Please insert SIM card so that +* Gold contacts face TOWARDS the board +* Chipped edge of card leads into the socket +* Fully inserted card will engage the spring lock + +To remove the card, push in until the spring lock releases, and the card will be +ejected partially from the slot. + +>TODO: Do we need a diagram for this? + +### Bench Power Supply + +In lieu of an OBD2 connection, the V2X can be powered by any cable that meets the +power pinout requirements of the OBD2->DB9 standard. + +The V2X requires power through the DB9 connection. For bench testing, we use a +simple spliced cable, terminated DB9 at the V2X board and using either: positive +and ground wires running to a bench supply; barrel jack from wall supply. In +either case please ensure a 12v constant supply. + +Our simple cable terminates on the DB9 end with +* *Power* - pin 9 +* *GND* - pin 2 + +Note that the above configuration is just a power supply and will of course not +support any CAN traffic. + +For full pinout, refer to the table below. + +**Pinning:** + +| Pin Description | OBDII | DB9 | +|----------------- |-------|-----| +| J1850 BUS+ | 2 | 7 | +| Chassis Ground | 4 | 2 | +| Signal Ground | 5 | 1 | +| CAN High J-2284 | 6 | 3 | +| ISO 9141-2 K Line| 7 | 4 | +| J1850 BUS- | 10 | 6 | +| CAN Low J-2284 | 14 | 5 | +| ISO 9141-2 L Line| 15 | 8 | +| Battery Power | 16 | 9 | + +## Startup procedure + +1. Press red button. The driver is configured to bring all components to full + power. Please allow some seconds for host computer start and application + initialization. + +When the host comes on line and connects to the V2X, the lights (red, blue, +green) on board should be visible. + +### Power requirements + +V2X requires constant 12v power supply to sustain operation. Very informal +testing shows average draw of ~0.15 amps during normal operation, with no host +computer connected. When V2X is supplying power to a host such as a Raspberry Pi +3 with attached touch screen, power draw is ~0.6 amps. + +> #### Battery warning +> As noted above, the V2X firmware does not yet support low power / standby +state. If left powered when vehicle is off, the vehicle battery could be drained +significantly. Please power off the V2X when disengaging the vehicle. Note that +powering off the V2X will also power off the host computer. + +### Nominal light states + +Currently, the firmware drives the three on board LEDs respective to GSM modem +status. + +* Red: SIM card insertion status. + - Active: SIM card is inserted (properly) + - Inactive: SIM card missing or inserted improperly + +* Blue: GSM power status. + - Active: SIMCOM chipset is powered + +* Green: GSM network state. + - Steady: no network operator registered. + - 800ms blink: operator selected, no network connection dialed. + - 200ms blink: network connction dialed. + +A steady green light likely indicates that the signal quality is not sufficient +to register and attach to the desired network operator. + +> Please note: A bug currently exists in the driver that can produce a state +where the LEDs are not updated with the correct frequency if the host has not +actively communicated with the board for some time. Until this issue is resolved, +the host should use a scripted means of occaisionally contacting the V2X control +port. The distro built for Smart Cities contains a work around service for this +issue. + +If the lights are not visible, this should indicate the device is not powered. + +### Smart Cities Application + +In addition, the color of the time and date lines under the GENIVI logo indicate +the status of GPS and RVI, respectively. + +When GPS is active, the text displaying the time will be white. If the time is +displayed in pink text, GPS is in an error status. Check the connection or move +the vehicle to a location with a clear view of the sky. + +When RVI is active, the date will be displayed in white text. If the date text +is pink, check that the SIM card is properly installed and activated. If the +date text is blue, contact [TBD] to verify that the RVI server is up and +running. + +## Shutdown procedure + +Shutdown is currently handled by cutting power to systems; there are multiple +methods available. + +### Button power off + +The button on the V2X board can be used to control the power states. + +Hold button for longer than N seconds and release. + +* \> 1 second: Turn on all board components (including Host) +* \> 3 seconds: Turn off all board components (including Host), only Atmel CPU + will retain power +* \> 5 seconds: Turn off V2X board + +> While no LEDs currently dedicated to indicating power state of the board +> itself, powering off the board will deactivate the LEDs. + +### Button failure or fallback procedure + +V2X board supports a command set over a USB-serial port. + +> TODO: Later section with details on using command set for power management and +troubleshooting. + +### When all else fails + +Disconnect the board from the OBD port to cut power. Allow a few seconds, then +reconnect. Use the button repower the system. + +### Command options for power off (see also command set) + +> TODO: Describe contacting the V2X control port, and commands that can be used +for power state manipulation. + +### Nominal smart cities + +The Smart Cities application should initialize automatically after host system +start. + +## V2X Interface and Control + +> TODO: com/serial port description + +A host computer can communicate with the components on board the device, via the +virtual ports mounted over USB. The exact arrangement and details of these ports +depend on the operating system of the host computer. + +### Communication ports + +> Depending on operating system, arrangement of the virtual ports is at the +> mercy of whatever order they are mounted in. This means that the serial port +> for a particular device may not remain consistent. It is encouraged for the +> host computer to use a rules system (like `udev` in Linux) to map consistent +> port aliases. + +#### Linux + +The common port mounting arrangement observed in Linux: + +* `/dev/ttyACM0` -> STN110/ELM327 CAN chip +* `/dev/ttyACM1` -> V2X control port (VX command set) +* `/dev/ttyACM2` -> Accelerometer data stream (and secret reset back channel) +* `/dev/ttyUSB0` -> SIMCOM diagnostic port (unused) +* `/dev/ttyUSB1` -> GPS stream +* `/dev/ttyUSB2` -> GSM modem AT command port (PPP dialer should use this for + internet connection) +* `/dev/ttyUSB3` -> SIMCOM AT control (AT command set) + +#### Windows + +On Windows, the arrangement is slightly less intuitive, and the ports require a +driver to be installed. The requisite files, *atmel_devices_cdc.cat* and +*atmel_devices_cdc.inf* are available in the Atmel Software Framework, [on +Atmel's site](http://www.atmel.com/tools/avrsoftwareframework.aspx), +[Microchip](http://www.atmel.com/tools/avrsoftwareframework.aspx), or bundled +with Atmel Studio. + +Communication with the SIMCOM chip requires drivers appropriate to the operating +system version. Repository is available +[here](http://simcom.ee/documents/?dir=SIM5320). + +Common port mounting arrangement observed in Windows (designated by name, as +COM is determined at runtime: + +* `Ports (COM & LPT)` +* ->`Communication Device Class ASF example3, COM1` -> STN110/ELM327 CAN chip +* ->`Communication Device Class ASF example3, COM2` -> V2X control port (VX + command set) +* ->`Communication Device Class ASF example3, COM3` -> Accelerometer data stream + (and secret reset back channel) +* ->`Qualcomm HS-USB Diagnostics 9000` -> SIMCOM diagnostic port (unused) +* ->`Qualcomm HS-USB NMEA 9000` -> GPS stream +* ->`Sim Tech HS-USB AT Port 9000` -> SIMCOM AT control (AT command set) +* `Modems` +* ->`Qualcomm HS-USB Modem 9000` -> GSM modem AT command port (PPP dialer should + use this for + +### Verification +### Toubleshooting +## V2X Command set + +> TODO: Include V2X command set + +| Command | Submodule | Action | Description | +|--------------|-----------|--------|--------------------------------| +| VXAD | A | D | Disable the accelerometer +| VXAE | A | E | Enable the accelerometer +| VXAI | A | I | Accelerometer device information +| VXAQ | A | Q | Accelerometer state query +| VXAR | A | R | Restart the Accelerometer +| VXASxxx | A | Sxxxx | Change the sample rate to xxx 1,3,6,12,25,50,100,200,400,800,1600,3200 +| VXAXxxx | A | Xxxxx | Accelerometer X axis offset (zero) -127 to 127 Number confirmed +| VXAYxxx | A | Yxxxx | Accelerometer Y axis offset (zero) -127 to 127 Number confirmed +| VXAZxxx | A | Zxxxx | Accelerometer Z axis offset (zero) -127 to 127 Number confirmed +| VXAG | A | G | Get single Accelerometer sample +| VXARxx | A | Rxx | Set G-range +| VXCD | C | D | Disable the CAN interface +| VXCE | C | E | Enable the CAN interface +| VXCI | C | I | CANbus device information +| VXCQ | C | Q | CAN state information +| VXCR | C | R | Restart the CAN +| VXI | I | | V2X Device Information +| VXMD | M | D | Disable the Modem +| VXME | M | E | Enable the Modem +| VXMI | M | I | Modem device information +| VXMQ | M | Q | Modem state query +| VXMR | M | R | Rerestart the Modem +| VXPD3 | P | D3 | Disable the 3V power supply +| VXPD4 | P | D4 | Disable the 4V power supply +| VXPD5 | P | D5 | Disable the 5V power supply +| VXPDH | P | DH | Disable the Host power port +| VXPDDx | P | DDx | Disable host with delay x: seconds +| VXPE3 | P | E3 | Enable the 3V power supply +| VXPE4 | P | E4 | Enable the 4V power supply +| VXPE5 | P | E5 | Enable the 5V power supply +| VXPEH | P | EH | Enable the Host power port +| VXPQ | P | Q | Power state query "3V3=x, 4V1=x, 5V0=x, HOST=x" 1=on 0=off +| VXW | W | | Wake up event query +| VXQ | Q | | Whole system status query All other query results rolled into one +| VXTD | T | D | disable wakeup timers +| VXTWxxxx | x | | Wxxxxx Wakeup timer set for xxxxx seconds from now +| VXR | R | | V2X board reset +| VXS | S | | SIMCARD check "SIMCARD=x" 1=in 0=out + +## Firmware upgrade + +> TODO: section should describe firmware, locations, etc, as well as tools. + +The V2X firmware is in ongoing development. Unfortunately there is no easy (or +remote) way to upgrade the firmware; instead development tools are required. + +Using a hardware programmer and a software utility, the V2X device can be +flashed with new firmware. + +> Recent firmware releases should be available on the repo. + +> TODO: Make releases available and link to them here. + +If you wish to compile an image from source, firmware image should be compiled +into a *.hex* format. The AVR toolchain is available for +[Linux](http://www.atmel.com/toolsATMELAVRTOOLCHAINFORLINUX.aspx), +[Windows](http://www.atmel.com/tools/atmelavrtoolchainforwindows.aspx), and +comes bundled in [Atmel Studio](http://www.atmel.com/microsite/atmel-studio/). + +### Tools required + +#### Programmer/Debugger + +A plethora of hardware programming/debugger solutions are available. The AVR +Dragon is one such device. + +[AVR Dragon product page](http://www.atmel.com/tools/avrdragon.aspx) + +> TODO: AVR Dragon or compatible debugging board + +### Programmer Connection to the V2X Board + +#### Example: AVR Dragon + +* Connect one end of the programming ribbon cable to the Dragon board on the set + of pins marked *1 ISP 5*. Ensure that the red stripe on the ribbon is aligned + with the *1* on the pin port. +* Connect the other end of the cable to the set of pins marked *PDI* on top of + the V2X board. Align the connector so that the red stripe is closest to the + bottom corner nearest the *PDI* marking. + +> TODO: image of proper connection + +To check if the cable has been correctly connected and aligned, use programming +software to read the voltage of the device while the board is powered. The +voltage should read **3.2v**. + +### Firmware Upgrade Procedure + +> During the flashing process, power must be maintained to the board. A constant +> 12v power supply is required. In the current hardware revision, the 4v rail +> must be held high by pressing and holding the button prior to and during the +> flashing process. + +#### Atmel Studio + +> A full reiteration of the programming instructions for the board are currently +> out of scope of this document. + +Atmel Studio supports an easy programming interface for loading firmware .hex +files onto the board. + +[Atmel Studio Programming Dialog +documentation](http://www.atmel.com/webdoc/atmelstudio/atmelstudio.AVRStudio.ProgrammingDialog.Introduction.html) + +#### AVRDUDE + +AVRDude is a cross platform (Linux/Windows) programming software utility. + + +[AVRDUDE Documentation](http://nongnu.askapache.com/avrdude/avrdude-doc-6.3.pdf) + +Please read the above documentation for details and options for using AVRDUDE. + +Ultimately, the usage will boil down to something like this: + +``` +avrdude -p x128a4u -c -e -U flash:w:.hex +``` +## Links and Resources + +## FAQ + +**Q**: Why does the OBU occasionally take longer to boot or appear to reboot +several times when starting up + +**A**: There is an issue with the graphics compositor in the GENIVI Development +Platform and it occasionally does not load properly. Normally, this would cause +a command line to appear instead of the GUI. We have created a workaround to +detect this condition and reload the compositor. A bug has been logged. + +