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.avrdragonPDI
@@ -214,261 +214,272 @@
AVR Dragontrue
+
+
+
+
+
+
+
+ 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.
+
+