mirror of
https://github.com/dragonpilot/dragonpilot.git
synced 2026-06-12 10:24:14 +08:00
Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5cf91d0496 | ||
|
|
6fee0bdb2d | ||
|
|
e40c161125 | ||
|
|
97eb55cc55 | ||
|
|
65134be0d1 | ||
|
|
dbf71a23aa | ||
|
|
7fec3db1d6 | ||
|
|
26b573c1d0 | ||
|
|
5ec1e7307e | ||
|
|
8bc36b7f21 | ||
|
|
3b909eb693 | ||
|
|
57e39c4472 | ||
|
|
ff7672339c | ||
|
|
6e824a2c22 | ||
|
|
32fa49e093 | ||
|
|
2250eac58f | ||
|
|
97be6b3a0e | ||
|
|
942655c947 | ||
|
|
615db3f7fd | ||
|
|
0bb75c5389 | ||
|
|
7b5ee81d2d | ||
|
|
7fe46f1e1d | ||
|
|
50c0d1c9da | ||
|
|
6dbf544d06 | ||
|
|
41e3a0f699 | ||
|
|
c5d8aec28b | ||
|
|
4653a9aef0 | ||
|
|
ab3492bb90 | ||
|
|
ed7cbb3866 | ||
|
|
a30626cfe3 | ||
|
|
d2c087b3e2 | ||
|
|
0a747f991d | ||
|
|
f5a1e86d85 | ||
|
|
693bcb0f83 | ||
|
|
0d0daed86e | ||
|
|
95a349abcc | ||
|
|
c6ba5dc539 | ||
|
|
6c3afeec0f | ||
|
|
29c58b4588 | ||
|
|
ecc565aa3f | ||
|
|
db61810f98 | ||
|
|
48f203ad5b | ||
|
|
6ab4ac2dfb | ||
|
|
9cb3c7b6e6 | ||
|
|
adaa4ed350 | ||
|
|
a64b9aa9b8 | ||
|
|
0138eca61d | ||
|
|
139a40de29 |
28
.gitignore
vendored
Normal file
28
.gitignore
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
.DS_Store
|
||||
.tags
|
||||
.ipynb_checkpoints
|
||||
model2.png
|
||||
|
||||
*.d
|
||||
*.pyc
|
||||
*.pyo
|
||||
.*.swp
|
||||
.*.swo
|
||||
.*.un~
|
||||
*.o
|
||||
*.so
|
||||
*.a
|
||||
*.clb
|
||||
*.class
|
||||
*.pyxbldc
|
||||
*.vcd
|
||||
config.json
|
||||
clcache
|
||||
|
||||
board/obj/
|
||||
selfdrive/boardd/boardd
|
||||
selfdrive/logcatd/logcatd
|
||||
selfdrive/proclogd/proclogd
|
||||
selfdrive/ui/ui
|
||||
/src/
|
||||
|
||||
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
[submodule "panda"]
|
||||
path = panda
|
||||
url = https://github.com/commaai/panda.git
|
||||
[submodule "opendbc"]
|
||||
path = opendbc
|
||||
url = https://github.com/commaai/opendbc.git
|
||||
12
.travis.yml
Normal file
12
.travis.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
sudo: required
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
install:
|
||||
- docker build -t tmppilot -f Dockerfile.openpilot .
|
||||
|
||||
script:
|
||||
- docker run --rm
|
||||
-v "$(pwd)"/selfdrive/test/plant/out:/tmp/openpilot/selfdrive/test/plant/out
|
||||
tmppilot /bin/sh -c 'cd /tmp/openpilot/selfdrive/test/plant && ./runtest.sh'
|
||||
6
Makefile
Normal file
6
Makefile
Normal file
@@ -0,0 +1,6 @@
|
||||
.PHONY: all
|
||||
|
||||
# TODO: Add a global build system to openpilot
|
||||
all:
|
||||
cd /data/openpilot/selfdrive && PYTHONPATH=/data/openpilot PREPAREONLY=1 /data/openpilot/selfdrive/manager.py
|
||||
|
||||
39
README.md
39
README.md
@@ -7,53 +7,52 @@ Currently it performs the functions of Adaptive Cruise Control (ACC) and Lane Ke
|
||||
|
||||
The openpilot codebase has been written to be concise and enable rapid prototyping. We look forward to your contributions - improving real vehicle automation has never been easier.
|
||||
|
||||
Here are [some](https://www.youtube.com/watch?v=9OwTJFuDI7g) [videos](https://www.youtube.com/watch?v=64Wvt5pYQmE) [of](https://www.youtube.com/watch?v=6IW7Nejsr3A) [it](https://www.youtube.com/watch?v=-VN1YcC83nA) [running](https://www.youtube.com/watch?v=EQJZvVeihZk). And a really cool [tutorial](https://www.youtube.com/watch?v=PwOnsT2UW5o).
|
||||
|
||||
Hardware
|
||||
------
|
||||
|
||||
Right now openpilot supports the [neo research platform](http://github.com/commaai/neo) for vehicle control. We'd like to support [Open Source Car Control](https://github.com/PolySync/OSCC) as well.
|
||||
Right now openpilot supports the [neo research platform](http://github.com/commaai/neo) for vehicle control. We'd like to support other platforms as well.
|
||||
|
||||
To install it on the NEO:
|
||||
|
||||
```bash
|
||||
# Requires working adb in PATH
|
||||
cd installation
|
||||
./install.sh
|
||||
```
|
||||
Install openpilot on a neo device by entering ``https://openpilot.comma.ai`` during NEOS setup.
|
||||
|
||||
Supported Cars
|
||||
------
|
||||
|
||||
- Acura ILX 2016 with AcuraWatch Plus
|
||||
- Limitations: Due to use of the cruise control for gas, it can only be enabled above 25 mph
|
||||
- Due to use of the cruise control for gas, it can only be enabled above 25 mph
|
||||
|
||||
- Honda Civic 2016 Touring Edition
|
||||
- Limitations: Due to limitations in steering firmware, steering is disabled below 18 mph
|
||||
- Honda Civic 2016 with Honda Sensing
|
||||
- Due to limitations in steering firmware, steering is disabled below 12 mph
|
||||
|
||||
- Honda CR-V Touring 2015-2016 (very alpha!)
|
||||
- Can only be enabled above 25 mph
|
||||
|
||||
Directory structure
|
||||
------
|
||||
|
||||
- board -- Code that runs on the USB interface board
|
||||
- cereal -- The messaging spec used for all logs on the phone
|
||||
- common -- Library like functionality we've developed here
|
||||
- dbcs -- Files showing how to interpret data from cars
|
||||
- installation -- Installation on the neo platform
|
||||
- opendbc -- Files showing how to interpret data from cars
|
||||
- panda -- Code used to communicate on CAN and LIN
|
||||
- phonelibs -- Libraries used on the phone
|
||||
- selfdrive -- Code needed to drive the car
|
||||
- assets -- Fonts for ui
|
||||
- boardd -- Daemon to talk to the board
|
||||
- calibrationd -- Camera calibration server
|
||||
- car -- Code that talks to the car and implements CarInterface
|
||||
- common -- Shared C/C++ code for the daemons
|
||||
- controls -- Python controls (PID loops etc) for the car
|
||||
- debug -- Tools to help you debug and do car ports
|
||||
- logcatd -- Android logcat as a service
|
||||
- loggerd -- Logger and uploader of car data
|
||||
- proclogd -- Logs information from proc
|
||||
- radar -- Code that talks to the radar and implements RadarInterface
|
||||
- sensord -- IMU / GPS interface code
|
||||
- test/plant -- Car simulator running code through virtual maneuvers
|
||||
- ui -- The UI
|
||||
- visiond -- embedded vision pipeline
|
||||
|
||||
To understand how the services interact, see `common/services.py`
|
||||
To understand how the services interact, see `selfdrive/service_list.yaml`
|
||||
|
||||
Testing on PC
|
||||
------
|
||||
@@ -72,11 +71,9 @@ More extensive testing infrastructure and simulation environments are coming soo
|
||||
Adding Car Support
|
||||
------
|
||||
|
||||
It should be relatively easy to add support for the Honda CR-V Touring. The brake message is the same. Steering has a slightly different message with a different message id. Sniff CAN while using LKAS to find it.
|
||||
comma.ai offers [bounties](http://comma.ai/bounties.html) for adding additional car support.
|
||||
|
||||
The Honda Accord uses different signaling for the steering and probably requires new hardware.
|
||||
|
||||
Adding other manufacturers besides Honda/Acura is doable but will be more of an undertaking.
|
||||
CR-V Touring support came in through this program. Chevy Volt is close. Accord is close as well.
|
||||
|
||||
User Data / chffr Account / Crash Reporting
|
||||
------
|
||||
@@ -97,7 +94,7 @@ We welcome both pull requests and issues on
|
||||
[github](http://github.com/commaai/openpilot). See the TODO file for a list of
|
||||
good places to start.
|
||||
|
||||
Want to get paid to work on openpilot? [comma.ai is hiring](http://comma.ai/hiring.html)
|
||||
Want to get paid to work on openpilot? [comma.ai is hiring](http://comma.ai/positions.html)
|
||||
|
||||
Licensing
|
||||
------
|
||||
|
||||
71
RELEASES.md
71
RELEASES.md
@@ -1,3 +1,74 @@
|
||||
Version 0.3.3 (2017-06-28)
|
||||
===========================
|
||||
* Improved model trained on more data
|
||||
* Alpha CR-V support thanks to energee and johnnwvs!
|
||||
* Using the opendbc project for DBC files
|
||||
* Minor performance improvements
|
||||
* UI update thanks to pjlao307
|
||||
* Power off button
|
||||
* 6% more torque on the Civic
|
||||
|
||||
Version 0.3.2 (2017-05-22)
|
||||
===========================
|
||||
* Minor stability bugfixes
|
||||
* Added metrics and rear view mirror disable to settings
|
||||
* Update model with more crowdsourced data
|
||||
|
||||
Version 0.3.1 (2017-05-17)
|
||||
===========================
|
||||
* visiond stability bugfix
|
||||
* Add logging for angle and flashing
|
||||
|
||||
Version 0.3.0 (2017-05-12)
|
||||
===========================
|
||||
* Add CarParams struct to improve the abstraction layer
|
||||
* Refactor visiond IPC to support multiple clients
|
||||
* Add raw GPS and beginning support for navigation
|
||||
* Improve model in visiond using crowdsourced data
|
||||
* Add improved system logging to diagnose instability
|
||||
* Rewrite baseui in React Native
|
||||
* Moved calibration to the cloud
|
||||
|
||||
Version 0.2.9 (2017-03-01)
|
||||
===========================
|
||||
* Retain compatibility with NEOS v1
|
||||
|
||||
Version 0.2.8 (2017-02-27)
|
||||
===========================
|
||||
* Fix bug where frames were being dropped in minute 71
|
||||
|
||||
Version 0.2.7 (2017-02-08)
|
||||
===========================
|
||||
* Better performance and pictures at night
|
||||
* Fix ptr alignment issue in boardd
|
||||
* Fix brake error light, fix crash if too cold
|
||||
|
||||
Version 0.2.6 (2017-01-31)
|
||||
===========================
|
||||
* Fix bug in visiond model execution
|
||||
|
||||
Version 0.2.5 (2017-01-30)
|
||||
===========================
|
||||
* Fix race condition in manager
|
||||
|
||||
Version 0.2.4 (2017-01-27)
|
||||
===========================
|
||||
* OnePlus 3T support
|
||||
* Enable installation as NEOS app
|
||||
* Various minor bugfixes
|
||||
|
||||
Version 0.2.3 (2017-01-11)
|
||||
===========================
|
||||
* Reduce space usage by 80%
|
||||
* Add better logging
|
||||
* Add Travis CI
|
||||
|
||||
Version 0.2.2 (2017-01-10)
|
||||
===========================
|
||||
* Board triggers started signal on CAN messages
|
||||
* Improved autoexposure
|
||||
* Handle out of space, improve upload status
|
||||
|
||||
Version 0.2.1 (2016-12-14)
|
||||
===========================
|
||||
* Performance improvements, removal of more numpy
|
||||
|
||||
BIN
apk/com.baseui.apk
Normal file
BIN
apk/com.baseui.apk
Normal file
Binary file not shown.
@@ -1,43 +0,0 @@
|
||||
# :set noet
|
||||
PROJ_NAME = comma
|
||||
|
||||
CFLAGS = -g -O0 -Wall
|
||||
CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m3
|
||||
CFLAGS += -msoft-float -DSTM32F2 -DSTM32F205xx
|
||||
CFLAGS += -I inc -nostdlib
|
||||
CFLAGS += -Tstm32_flash.ld
|
||||
|
||||
CC = arm-none-eabi-gcc
|
||||
OBJCOPY = arm-none-eabi-objcopy
|
||||
OBJDUMP = arm-none-eabi-objdump
|
||||
|
||||
MACHINE = $(shell uname -m)
|
||||
|
||||
all: obj/$(PROJ_NAME).bin
|
||||
#$(OBJDUMP) -d obj/$(PROJ_NAME).elf
|
||||
./tools/enter_download_mode.py
|
||||
./tools/dfu-util-$(MACHINE) -a 0 -s 0x08000000 -D $<
|
||||
./tools/dfu-util-$(MACHINE) --reset-stm32 -a 0 -s 0x08000000
|
||||
|
||||
ifneq ($(wildcard ../.git/HEAD),)
|
||||
obj/gitversion.h: ../.git/HEAD ../.git/index
|
||||
echo "const uint8_t gitversion[] = \"$(shell git rev-parse HEAD)\";" > $@
|
||||
else
|
||||
obj/gitversion.h:
|
||||
echo "const uint8_t gitversion[] = \"RELEASE\";" > $@
|
||||
endif
|
||||
|
||||
obj/main.o: main.c *.h obj/gitversion.h
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
obj/startup_stm32f205xx.o: startup_stm32f205xx.s
|
||||
mkdir -p obj
|
||||
$(CC) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
obj/$(PROJ_NAME).bin: obj/startup_stm32f205xx.o obj/main.o
|
||||
$(CC) $(CFLAGS) -o obj/$(PROJ_NAME).elf $^
|
||||
$(OBJCOPY) -v -O binary obj/$(PROJ_NAME).elf $@
|
||||
|
||||
clean:
|
||||
rm -f obj/*
|
||||
|
||||
38
board/adc.h
38
board/adc.h
@@ -1,38 +0,0 @@
|
||||
// ACCEL1 = ADC10
|
||||
// ACCEL2 = ADC11
|
||||
// VOLT_S = ADC12
|
||||
// CURR_S = ADC13
|
||||
|
||||
#define ADCCHAN_ACCEL0 10
|
||||
#define ADCCHAN_ACCEL1 11
|
||||
#define ADCCHAN_VOLTAGE 12
|
||||
#define ADCCHAN_CURRENT 13
|
||||
|
||||
void adc_init() {
|
||||
// global setup
|
||||
ADC->CCR = ADC_CCR_TSVREFE | ADC_CCR_VBATE;
|
||||
//ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_EOCS | ADC_CR2_DDS;
|
||||
ADC1->CR2 = ADC_CR2_ADON;
|
||||
|
||||
// long
|
||||
ADC1->SMPR1 = ADC_SMPR1_SMP10 | ADC_SMPR1_SMP11 | ADC_SMPR1_SMP12 | ADC_SMPR1_SMP13;
|
||||
}
|
||||
|
||||
uint32_t adc_get(int channel) {
|
||||
|
||||
// includes length
|
||||
//ADC1->SQR1 = 0;
|
||||
|
||||
// select channel
|
||||
ADC1->JSQR = channel << 15;
|
||||
|
||||
//ADC1->CR1 = ADC_CR1_DISCNUM_0;
|
||||
//ADC1->CR1 = ADC_CR1_EOCIE;
|
||||
|
||||
ADC1->SR &= ~(ADC_SR_JEOC);
|
||||
ADC1->CR2 |= ADC_CR2_JSWSTART;
|
||||
while (!(ADC1->SR & ADC_SR_JEOC));
|
||||
|
||||
return ADC1->JDR1;
|
||||
}
|
||||
|
||||
75
board/can.h
75
board/can.h
@@ -1,75 +0,0 @@
|
||||
void can_init(CAN_TypeDef *CAN) {
|
||||
CAN->MCR = CAN_MCR_TTCM | CAN_MCR_INRQ;
|
||||
while((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK);
|
||||
puts("CAN initting\n");
|
||||
|
||||
// PCLK = 24000000, 500000 is 48 clocks
|
||||
// from http://www.bittiming.can-wiki.ino/
|
||||
CAN->BTR = 0x001c0002;
|
||||
|
||||
// loopback mode for debugging
|
||||
#ifdef CAN_LOOPBACK_MODE
|
||||
CAN->BTR |= CAN_BTR_SILM | CAN_BTR_LBKM;
|
||||
#endif
|
||||
|
||||
// reset
|
||||
CAN->MCR = CAN_MCR_TTCM;
|
||||
while((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK);
|
||||
puts("CAN init done\n");
|
||||
|
||||
// accept all filter
|
||||
CAN->FMR |= CAN_FMR_FINIT;
|
||||
|
||||
// no mask
|
||||
CAN->sFilterRegister[0].FR1 = 0;
|
||||
CAN->sFilterRegister[0].FR2 = 0;
|
||||
CAN->sFilterRegister[14].FR1 = 0;
|
||||
CAN->sFilterRegister[14].FR2 = 0;
|
||||
CAN->FA1R |= 1 | (1 << 14);
|
||||
|
||||
CAN->FMR &= ~(CAN_FMR_FINIT);
|
||||
|
||||
// enable all CAN interrupts
|
||||
CAN->IER = 0xFFFFFFFF;
|
||||
//CAN->IER = CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_FMPIE1;
|
||||
}
|
||||
|
||||
// CAN error
|
||||
void can_sce(CAN_TypeDef *CAN) {
|
||||
#ifdef DEBUG
|
||||
puts("MSR:");
|
||||
puth(CAN->MSR);
|
||||
puts(" TSR:");
|
||||
puth(CAN->TSR);
|
||||
puts(" RF0R:");
|
||||
puth(CAN->RF0R);
|
||||
puts(" RF1R:");
|
||||
puth(CAN->RF1R);
|
||||
puts(" ESR:");
|
||||
puth(CAN->ESR);
|
||||
puts("\n");
|
||||
#endif
|
||||
|
||||
// clear
|
||||
//CAN->sTxMailBox[0].TIR &= ~(CAN_TI0R_TXRQ);
|
||||
CAN->TSR |= CAN_TSR_ABRQ0;
|
||||
//CAN->ESR |= CAN_ESR_LEC;
|
||||
//CAN->MSR &= ~(CAN_MSR_ERRI);
|
||||
CAN->MSR = CAN->MSR;
|
||||
}
|
||||
|
||||
int can_cksum(uint8_t *dat, int len, int addr, int idx) {
|
||||
int i;
|
||||
int s = 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
s += (dat[i] >> 4);
|
||||
s += dat[i] & 0xF;
|
||||
}
|
||||
s += (addr>>0)&0xF;
|
||||
s += (addr>>4)&0xF;
|
||||
s += (addr>>8)&0xF;
|
||||
s += idx;
|
||||
s = 8-s;
|
||||
return s&0xF;
|
||||
}
|
||||
|
||||
16
board/dac.h
16
board/dac.h
@@ -1,16 +0,0 @@
|
||||
void dac_init() {
|
||||
// no buffers required since we have an opamp
|
||||
//DAC->CR = DAC_CR_EN1 | DAC_CR_BOFF1 | DAC_CR_EN2 | DAC_CR_BOFF2;
|
||||
DAC->DHR12R1 = 0;
|
||||
DAC->DHR12R2 = 0;
|
||||
DAC->CR = DAC_CR_EN1 | DAC_CR_EN2;
|
||||
}
|
||||
|
||||
void dac_set(int channel, uint32_t value) {
|
||||
if (channel == 0) {
|
||||
DAC->DHR12R1 = value;
|
||||
} else if (channel == 1) {
|
||||
DAC->DHR12R2 = value;
|
||||
}
|
||||
}
|
||||
|
||||
1211
board/inc/core_cm3.h
1211
board/inc/core_cm3.h
File diff suppressed because it is too large
Load Diff
@@ -1,609 +0,0 @@
|
||||
/**************************************************************************//**
|
||||
* @file core_cmFunc.h
|
||||
* @brief CMSIS Cortex-M Core Function Access Header File
|
||||
* @version V2.10
|
||||
* @date 26. July 2011
|
||||
*
|
||||
* @note
|
||||
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* ARM Limited (ARM) is supplying this software for use with Cortex-M
|
||||
* processor based microcontrollers. This file can be freely distributed
|
||||
* within development tools that are supporting such ARM based processors.
|
||||
*
|
||||
* @par
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
||||
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
||||
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
|
||||
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __CORE_CMFUNC_H
|
||||
#define __CORE_CMFUNC_H
|
||||
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
/** \ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||
/* ARM armcc specific functions */
|
||||
|
||||
#if (__ARMCC_VERSION < 400677)
|
||||
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||
#endif
|
||||
|
||||
/* intrinsic void __enable_irq(); */
|
||||
/* intrinsic void __disable_irq(); */
|
||||
|
||||
/** \brief Get Control Register
|
||||
|
||||
This function returns the content of the Control Register.
|
||||
|
||||
\return Control Register value
|
||||
*/
|
||||
static __INLINE uint32_t __get_CONTROL(void)
|
||||
{
|
||||
register uint32_t __regControl __ASM("control");
|
||||
return(__regControl);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Control Register
|
||||
|
||||
This function writes the given value to the Control Register.
|
||||
|
||||
\param [in] control Control Register value to set
|
||||
*/
|
||||
static __INLINE void __set_CONTROL(uint32_t control)
|
||||
{
|
||||
register uint32_t __regControl __ASM("control");
|
||||
__regControl = control;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get ISPR Register
|
||||
|
||||
This function returns the content of the ISPR Register.
|
||||
|
||||
\return ISPR Register value
|
||||
*/
|
||||
static __INLINE uint32_t __get_IPSR(void)
|
||||
{
|
||||
register uint32_t __regIPSR __ASM("ipsr");
|
||||
return(__regIPSR);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get APSR Register
|
||||
|
||||
This function returns the content of the APSR Register.
|
||||
|
||||
\return APSR Register value
|
||||
*/
|
||||
static __INLINE uint32_t __get_APSR(void)
|
||||
{
|
||||
register uint32_t __regAPSR __ASM("apsr");
|
||||
return(__regAPSR);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get xPSR Register
|
||||
|
||||
This function returns the content of the xPSR Register.
|
||||
|
||||
\return xPSR Register value
|
||||
*/
|
||||
static __INLINE uint32_t __get_xPSR(void)
|
||||
{
|
||||
register uint32_t __regXPSR __ASM("xpsr");
|
||||
return(__regXPSR);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Process Stack Pointer
|
||||
|
||||
This function returns the current value of the Process Stack Pointer (PSP).
|
||||
|
||||
\return PSP Register value
|
||||
*/
|
||||
static __INLINE uint32_t __get_PSP(void)
|
||||
{
|
||||
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||
return(__regProcessStackPointer);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Process Stack Pointer
|
||||
|
||||
This function assigns the given value to the Process Stack Pointer (PSP).
|
||||
|
||||
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||
*/
|
||||
static __INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||
__regProcessStackPointer = topOfProcStack;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Main Stack Pointer
|
||||
|
||||
This function returns the current value of the Main Stack Pointer (MSP).
|
||||
|
||||
\return MSP Register value
|
||||
*/
|
||||
static __INLINE uint32_t __get_MSP(void)
|
||||
{
|
||||
register uint32_t __regMainStackPointer __ASM("msp");
|
||||
return(__regMainStackPointer);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Main Stack Pointer
|
||||
|
||||
This function assigns the given value to the Main Stack Pointer (MSP).
|
||||
|
||||
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||
*/
|
||||
static __INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||
{
|
||||
register uint32_t __regMainStackPointer __ASM("msp");
|
||||
__regMainStackPointer = topOfMainStack;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Priority Mask
|
||||
|
||||
This function returns the current state of the priority mask bit from the Priority Mask Register.
|
||||
|
||||
\return Priority Mask value
|
||||
*/
|
||||
static __INLINE uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
register uint32_t __regPriMask __ASM("primask");
|
||||
return(__regPriMask);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Priority Mask
|
||||
|
||||
This function assigns the given value to the Priority Mask Register.
|
||||
|
||||
\param [in] priMask Priority Mask
|
||||
*/
|
||||
static __INLINE void __set_PRIMASK(uint32_t priMask)
|
||||
{
|
||||
register uint32_t __regPriMask __ASM("primask");
|
||||
__regPriMask = (priMask);
|
||||
}
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Enable FIQ
|
||||
|
||||
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __enable_fault_irq __enable_fiq
|
||||
|
||||
|
||||
/** \brief Disable FIQ
|
||||
|
||||
This function disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __disable_fault_irq __disable_fiq
|
||||
|
||||
|
||||
/** \brief Get Base Priority
|
||||
|
||||
This function returns the current value of the Base Priority register.
|
||||
|
||||
\return Base Priority register value
|
||||
*/
|
||||
static __INLINE uint32_t __get_BASEPRI(void)
|
||||
{
|
||||
register uint32_t __regBasePri __ASM("basepri");
|
||||
return(__regBasePri);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Base Priority
|
||||
|
||||
This function assigns the given value to the Base Priority register.
|
||||
|
||||
\param [in] basePri Base Priority value to set
|
||||
*/
|
||||
static __INLINE void __set_BASEPRI(uint32_t basePri)
|
||||
{
|
||||
register uint32_t __regBasePri __ASM("basepri");
|
||||
__regBasePri = (basePri & 0xff);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Fault Mask
|
||||
|
||||
This function returns the current value of the Fault Mask register.
|
||||
|
||||
\return Fault Mask register value
|
||||
*/
|
||||
static __INLINE uint32_t __get_FAULTMASK(void)
|
||||
{
|
||||
register uint32_t __regFaultMask __ASM("faultmask");
|
||||
return(__regFaultMask);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Fault Mask
|
||||
|
||||
This function assigns the given value to the Fault Mask register.
|
||||
|
||||
\param [in] faultMask Fault Mask value to set
|
||||
*/
|
||||
static __INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||
{
|
||||
register uint32_t __regFaultMask __ASM("faultmask");
|
||||
__regFaultMask = (faultMask & (uint32_t)1);
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
#if (__CORTEX_M == 0x04)
|
||||
|
||||
/** \brief Get FPSCR
|
||||
|
||||
This function returns the current value of the Floating Point Status/Control register.
|
||||
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
static __INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
return(__regfpscr);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set FPSCR
|
||||
|
||||
This function assigns the given value to the Floating Point Status/Control register.
|
||||
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
static __INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
__regfpscr = (fpscr);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M == 0x04) */
|
||||
|
||||
|
||||
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||
/* IAR iccarm specific functions */
|
||||
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||
/* GNU gcc specific functions */
|
||||
|
||||
/** \brief Enable IRQ Interrupts
|
||||
|
||||
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __enable_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsie i");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Disable IRQ Interrupts
|
||||
|
||||
This function disables IRQ interrupts by setting the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __disable_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsid i");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Control Register
|
||||
|
||||
This function returns the content of the Control Register.
|
||||
|
||||
\return Control Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_CONTROL(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, control" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Control Register
|
||||
|
||||
This function writes the given value to the Control Register.
|
||||
|
||||
\param [in] control Control Register value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __set_CONTROL(uint32_t control)
|
||||
{
|
||||
__ASM volatile ("MSR control, %0" : : "r" (control) );
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get ISPR Register
|
||||
|
||||
This function returns the content of the ISPR Register.
|
||||
|
||||
\return ISPR Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_IPSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get APSR Register
|
||||
|
||||
This function returns the content of the APSR Register.
|
||||
|
||||
\return APSR Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_APSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get xPSR Register
|
||||
|
||||
This function returns the content of the xPSR Register.
|
||||
|
||||
\return xPSR Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_xPSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Process Stack Pointer
|
||||
|
||||
This function returns the current value of the Process Stack Pointer (PSP).
|
||||
|
||||
\return PSP Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PSP(void)
|
||||
{
|
||||
register uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Process Stack Pointer
|
||||
|
||||
This function assigns the given value to the Process Stack Pointer (PSP).
|
||||
|
||||
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) );
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Main Stack Pointer
|
||||
|
||||
This function returns the current value of the Main Stack Pointer (MSP).
|
||||
|
||||
\return MSP Register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_MSP(void)
|
||||
{
|
||||
register uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Main Stack Pointer
|
||||
|
||||
This function assigns the given value to the Main Stack Pointer (MSP).
|
||||
|
||||
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||
{
|
||||
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) );
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Priority Mask
|
||||
|
||||
This function returns the current state of the priority mask bit from the Priority Mask Register.
|
||||
|
||||
\return Priority Mask value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, primask" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Priority Mask
|
||||
|
||||
This function assigns the given value to the Priority Mask Register.
|
||||
|
||||
\param [in] priMask Priority Mask
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __set_PRIMASK(uint32_t priMask)
|
||||
{
|
||||
__ASM volatile ("MSR primask, %0" : : "r" (priMask) );
|
||||
}
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Enable FIQ
|
||||
|
||||
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __enable_fault_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsie f");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Disable FIQ
|
||||
|
||||
This function disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __disable_fault_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsid f");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Base Priority
|
||||
|
||||
This function returns the current value of the Base Priority register.
|
||||
|
||||
\return Base Priority register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_BASEPRI(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Base Priority
|
||||
|
||||
This function assigns the given value to the Base Priority register.
|
||||
|
||||
\param [in] basePri Base Priority value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __set_BASEPRI(uint32_t value)
|
||||
{
|
||||
__ASM volatile ("MSR basepri, %0" : : "r" (value) );
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get Fault Mask
|
||||
|
||||
This function returns the current value of the Fault Mask register.
|
||||
|
||||
\return Fault Mask register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FAULTMASK(void)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Fault Mask
|
||||
|
||||
This function assigns the given value to the Fault Mask register.
|
||||
|
||||
\param [in] faultMask Fault Mask value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||
{
|
||||
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
#if (__CORTEX_M == 0x04)
|
||||
|
||||
/** \brief Get FPSCR
|
||||
|
||||
This function returns the current value of the Floating Point Status/Control register.
|
||||
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
|
||||
return(result);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set FPSCR
|
||||
|
||||
This function assigns the given value to the Floating Point Status/Control register.
|
||||
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) );
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M == 0x04) */
|
||||
|
||||
|
||||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||
/* TASKING carm specific functions */
|
||||
|
||||
/*
|
||||
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||
* Please use "carm -?i" to get an up to date list of all instrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/*@} end of CMSIS_Core_RegAccFunctions */
|
||||
|
||||
|
||||
#endif /* __CORE_CMFUNC_H */
|
||||
@@ -1,585 +0,0 @@
|
||||
/**************************************************************************//**
|
||||
* @file core_cmInstr.h
|
||||
* @brief CMSIS Cortex-M Core Instruction Access Header File
|
||||
* @version V2.10
|
||||
* @date 19. July 2011
|
||||
*
|
||||
* @note
|
||||
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* ARM Limited (ARM) is supplying this software for use with Cortex-M
|
||||
* processor based microcontrollers. This file can be freely distributed
|
||||
* within development tools that are supporting such ARM based processors.
|
||||
*
|
||||
* @par
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
||||
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
||||
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
|
||||
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __CORE_CMINSTR_H
|
||||
#define __CORE_CMINSTR_H
|
||||
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
||||
Access to dedicated instructions
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||
/* ARM armcc specific functions */
|
||||
|
||||
#if (__ARMCC_VERSION < 400677)
|
||||
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief No Operation
|
||||
|
||||
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
#define __NOP __nop
|
||||
|
||||
|
||||
/** \brief Wait For Interrupt
|
||||
|
||||
Wait For Interrupt is a hint instruction that suspends execution
|
||||
until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFI __wfi
|
||||
|
||||
|
||||
/** \brief Wait For Event
|
||||
|
||||
Wait For Event is a hint instruction that permits the processor to enter
|
||||
a low-power state until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFE __wfe
|
||||
|
||||
|
||||
/** \brief Send Event
|
||||
|
||||
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
#define __SEV __sev
|
||||
|
||||
|
||||
/** \brief Instruction Synchronization Barrier
|
||||
|
||||
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or
|
||||
memory, after the instruction has been completed.
|
||||
*/
|
||||
#define __ISB() __isb(0xF)
|
||||
|
||||
|
||||
/** \brief Data Synchronization Barrier
|
||||
|
||||
This function acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
#define __DSB() __dsb(0xF)
|
||||
|
||||
|
||||
/** \brief Data Memory Barrier
|
||||
|
||||
This function ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
#define __DMB() __dmb(0xF)
|
||||
|
||||
|
||||
/** \brief Reverse byte order (32 bit)
|
||||
|
||||
This function reverses the byte order in integer value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __REV __rev
|
||||
|
||||
|
||||
/** \brief Reverse byte order (16 bit)
|
||||
|
||||
This function reverses the byte order in two unsigned short values.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
static __INLINE __ASM uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
rev16 r0, r0
|
||||
bx lr
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order in signed short value
|
||||
|
||||
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
static __INLINE __ASM int32_t __REVSH(int32_t value)
|
||||
{
|
||||
revsh r0, r0
|
||||
bx lr
|
||||
}
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Reverse bit order of value
|
||||
|
||||
This function reverses the bit order of the given value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __RBIT __rbit
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief STR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive STR command for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXB(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief STR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive STR command for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXH(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief STR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive STR command for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXW(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief Remove the exclusive lock
|
||||
|
||||
This function removes the exclusive lock which is created by LDREX.
|
||||
|
||||
*/
|
||||
#define __CLREX __clrex
|
||||
|
||||
|
||||
/** \brief Signed Saturate
|
||||
|
||||
This function saturates a signed value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT __ssat
|
||||
|
||||
|
||||
/** \brief Unsigned Saturate
|
||||
|
||||
This function saturates an unsigned value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT __usat
|
||||
|
||||
|
||||
/** \brief Count leading zeros
|
||||
|
||||
This function counts the number of leading zeros of a data value.
|
||||
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ __clz
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
|
||||
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||
/* IAR iccarm specific functions */
|
||||
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
|
||||
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||
/* GNU gcc specific functions */
|
||||
|
||||
/** \brief No Operation
|
||||
|
||||
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __NOP(void)
|
||||
{
|
||||
__ASM volatile ("nop");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Wait For Interrupt
|
||||
|
||||
Wait For Interrupt is a hint instruction that suspends execution
|
||||
until one of a number of events occurs.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __WFI(void)
|
||||
{
|
||||
__ASM volatile ("wfi");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Wait For Event
|
||||
|
||||
Wait For Event is a hint instruction that permits the processor to enter
|
||||
a low-power state until one of a number of events occurs.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __WFE(void)
|
||||
{
|
||||
__ASM volatile ("wfe");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Send Event
|
||||
|
||||
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __SEV(void)
|
||||
{
|
||||
__ASM volatile ("sev");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Instruction Synchronization Barrier
|
||||
|
||||
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or
|
||||
memory, after the instruction has been completed.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __ISB(void)
|
||||
{
|
||||
__ASM volatile ("isb");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Data Synchronization Barrier
|
||||
|
||||
This function acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __DSB(void)
|
||||
{
|
||||
__ASM volatile ("dsb");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Data Memory Barrier
|
||||
|
||||
This function ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __DMB(void)
|
||||
{
|
||||
__ASM volatile ("dmb");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order (32 bit)
|
||||
|
||||
This function reverses the byte order in integer value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order (16 bit)
|
||||
|
||||
This function reverses the byte order in two unsigned short values.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order in signed short value
|
||||
|
||||
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE int32_t __REVSH(int32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
|
||||
return((int32_t)result);
|
||||
}
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Reverse bit order of value
|
||||
|
||||
This function reverses the bit order of the given value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint8_t __LDREXB(volatile uint8_t *addr)
|
||||
{
|
||||
uint8_t result;
|
||||
|
||||
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint16_t __LDREXH(volatile uint16_t *addr)
|
||||
{
|
||||
uint16_t result;
|
||||
|
||||
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __LDREXW(volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive STR command for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive STR command for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive STR command for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Remove the exclusive lock
|
||||
|
||||
This function removes the exclusive lock which is created by LDREX.
|
||||
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE void __CLREX(void)
|
||||
{
|
||||
__ASM volatile ("clrex");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Signed Saturate
|
||||
|
||||
This function saturates a signed value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
|
||||
/** \brief Unsigned Saturate
|
||||
|
||||
This function saturates an unsigned value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
|
||||
/** \brief Count leading zeros
|
||||
|
||||
This function counts the number of leading zeros of a data value.
|
||||
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) static __INLINE uint8_t __CLZ(uint32_t value)
|
||||
{
|
||||
uint8_t result;
|
||||
|
||||
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
|
||||
|
||||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||
/* TASKING carm specific functions */
|
||||
|
||||
/*
|
||||
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||
|
||||
#endif /* __CORE_CMINSTR_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,197 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f2xx.h
|
||||
* @author MCD Application Team
|
||||
* @version V2.0.1
|
||||
* @date 25-March-2014
|
||||
* @brief CMSIS STM32F2xx Device Peripheral Access Layer Header File.
|
||||
*
|
||||
* The file is the unique include file that the application programmer
|
||||
* is using in the C source code, usually in main.c. This file contains:
|
||||
* - Configuration section that allows to select:
|
||||
* - The STM32F2xx device used in the target application
|
||||
* - To use or not the peripheral's drivers in application code(i.e.
|
||||
* code will be based on direct access to peripheral's registers
|
||||
* rather than drivers API), this option is controlled by
|
||||
* "#define USE_HAL_DRIVER"
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32f2xx
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __STM32F2xx_H
|
||||
#define __STM32F2xx_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/** @addtogroup Library_configuration_section
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Uncomment the line below according to the target STM32 device used in your
|
||||
application
|
||||
*/
|
||||
|
||||
#if !defined (STM32F205xx) && !defined (STM32F215xx) && !defined (STM32F207xx) && !defined (STM32F217xx)
|
||||
|
||||
/* #define STM32F205xx */ /*!< STM32Fxx Devices */
|
||||
/* #define STM32F215xx */ /*!< STM32Fxx Devices */
|
||||
/* #define STM32F207xx */ /*!< STM32Fxx Devices */
|
||||
/* #define STM32F217xx */ /*!< STM32Fxx Devices */
|
||||
|
||||
#endif
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to switch between these
|
||||
devices, you can define the device in your toolchain compiler preprocessor.
|
||||
*/
|
||||
#if !defined (USE_HAL_DRIVER)
|
||||
/**
|
||||
* @brief Comment the line below if you will not use the peripherals drivers.
|
||||
In this case, these drivers will not be included and the application code will
|
||||
be based on direct access to peripherals registers
|
||||
*/
|
||||
/*#define USE_HAL_DRIVER */
|
||||
#endif /* USE_HAL_DRIVER */
|
||||
|
||||
/**
|
||||
* @brief CMSIS Device version number V2.0.1
|
||||
*/
|
||||
#define __STM32F2xx_CMSIS_DEVICE_VERSION_MAIN (0x02) /*!< [31:24] main version */
|
||||
#define __STM32F2xx_CMSIS_DEVICE_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */
|
||||
#define __STM32F2xx_CMSIS_DEVICE_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */
|
||||
#define __STM32F2xx_CMSIS_DEVICE_VERSION_RC (0x00) /*!< [7:0] release candidate */
|
||||
#define __STM32F2xx_CMSIS_DEVICE_VERSION ((__CMSIS_DEVICE_VERSION_MAIN << 24)\
|
||||
|(__CMSIS_DEVICE_HAL_VERSION_SUB1 << 16)\
|
||||
|(__CMSIS_DEVICE_HAL_VERSION_SUB2 << 8 )\
|
||||
|(__CMSIS_DEVICE_HAL_VERSION_RC))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Device_Included
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(STM32F205xx)
|
||||
#include "stm32f205xx.h"
|
||||
#elif defined(STM32F215xx)
|
||||
#include "stm32f215xx.h"
|
||||
#elif defined(STM32F207xx)
|
||||
#include "stm32f207xx.h"
|
||||
#elif defined(STM32F217xx)
|
||||
#include "stm32f217xx.h"
|
||||
#else
|
||||
#error "Please select first the target STM32F2xx device used in your application (in stm32f2xx.h file)"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Exported_types
|
||||
* @{
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
RESET = 0,
|
||||
SET = !RESET
|
||||
} FlagStatus, ITStatus;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DISABLE = 0,
|
||||
ENABLE = !DISABLE
|
||||
} FunctionalState;
|
||||
#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ERROR = 0,
|
||||
SUCCESS = !ERROR
|
||||
} ErrorStatus;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup Exported_macro
|
||||
* @{
|
||||
*/
|
||||
#define SET_BIT(REG, BIT) ((REG) |= (BIT))
|
||||
|
||||
#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
|
||||
|
||||
#define READ_BIT(REG, BIT) ((REG) & (BIT))
|
||||
|
||||
#define CLEAR_REG(REG) ((REG) = (0x0))
|
||||
|
||||
#define WRITE_REG(REG, VAL) ((REG) = (VAL))
|
||||
|
||||
#define READ_REG(REG) ((REG))
|
||||
|
||||
#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
|
||||
|
||||
#define POSITION_VAL(VAL) (__CLZ(__RBIT(VAL)))
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __STM32F2xx_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -1,99 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32f2xx.h
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.0
|
||||
* @date 18-April-2011
|
||||
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Header File.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32f2xx_system
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Define to prevent recursive inclusion
|
||||
*/
|
||||
#ifndef __SYSTEM_STM32F2XX_H
|
||||
#define __SYSTEM_STM32F2XX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @addtogroup STM32F2xx_System_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup STM32F2xx_System_Exported_types
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F2xx_System_Exported_Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F2xx_System_Exported_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F2xx_System_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern void SystemInit(void);
|
||||
extern void SystemCoreClockUpdate(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__SYSTEM_STM32F2XX_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
|
||||
226
board/libc.h
226
board/libc.h
@@ -1,226 +0,0 @@
|
||||
#define min(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a < _b ? _a : _b; })
|
||||
|
||||
#define max(a,b) \
|
||||
({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a > _b ? _a : _b; })
|
||||
|
||||
#define __DIV(_PCLK_, _BAUD_) (((_PCLK_)*25)/(4*(_BAUD_)))
|
||||
#define __DIVMANT(_PCLK_, _BAUD_) (__DIV((_PCLK_), (_BAUD_))/100)
|
||||
#define __DIVFRAQ(_PCLK_, _BAUD_) (((__DIV((_PCLK_), (_BAUD_)) - (__DIVMANT((_PCLK_), (_BAUD_)) * 100)) * 16 + 50) / 100)
|
||||
#define __USART_BRR(_PCLK_, _BAUD_) ((__DIVMANT((_PCLK_), (_BAUD_)) << 4)|(__DIVFRAQ((_PCLK_), (_BAUD_)) & 0x0F))
|
||||
|
||||
#define GPIO_AF2_TIM3 ((uint8_t)0x02) /* TIM3 Alternate Function mapping */
|
||||
#define GPIO_AF7_USART2 ((uint8_t)0x07) /* USART2 Alternate Function mapping */
|
||||
#define GPIO_AF7_USART3 ((uint8_t)0x07) /* USART3 Alternate Function mapping */
|
||||
#define GPIO_AF9_CAN1 ((uint8_t)0x09) /* CAN1 Alternate Function mapping */
|
||||
#define GPIO_AF10_OTG_FS ((uint8_t)0xA) /* OTG_FS Alternate Function mapping */
|
||||
#define GPIO_AF12_OTG_HS_FS ((uint8_t)0xC) /* OTG HS configured in FS */
|
||||
|
||||
#ifdef OLD_BOARD
|
||||
#define USART USART2
|
||||
#else
|
||||
#define USART USART3
|
||||
#endif
|
||||
|
||||
|
||||
// **** shitty libc ****
|
||||
|
||||
void clock_init() {
|
||||
#ifdef USE_INTERNAL_OSC
|
||||
// enable internal oscillator
|
||||
RCC->CR |= RCC_CR_HSION;
|
||||
while ((RCC->CR & RCC_CR_HSIRDY) == 0);
|
||||
#else
|
||||
// enable external oscillator
|
||||
RCC->CR |= RCC_CR_HSEON;
|
||||
while ((RCC->CR & RCC_CR_HSERDY) == 0);
|
||||
#endif
|
||||
|
||||
// divide shit
|
||||
RCC->CFGR = RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_PPRE1_DIV4;
|
||||
#ifdef USE_INTERNAL_OSC
|
||||
RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 |
|
||||
RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLSRC_HSI;
|
||||
#else
|
||||
RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 |
|
||||
RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLSRC_HSE;
|
||||
#endif
|
||||
|
||||
// start PLL
|
||||
RCC->CR |= RCC_CR_PLLON;
|
||||
while ((RCC->CR & RCC_CR_PLLRDY) == 0);
|
||||
|
||||
// Configure Flash prefetch, Instruction cache, Data cache and wait state
|
||||
// *** without this, it breaks ***
|
||||
FLASH->ACR = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS;
|
||||
|
||||
// switch to PLL
|
||||
RCC->CFGR |= RCC_CFGR_SW_PLL;
|
||||
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
|
||||
|
||||
// *** running on PLL ***
|
||||
|
||||
// enable GPIOB, UART2, CAN, USB clock
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_CAN1EN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_CAN2EN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_DACEN;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
||||
RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
|
||||
//RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
|
||||
|
||||
// turn on alt USB
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_OTGHSEN;
|
||||
|
||||
// fix interrupt vectors
|
||||
}
|
||||
|
||||
// board specific
|
||||
void gpio_init() {
|
||||
// analog mode
|
||||
GPIOC->MODER = GPIO_MODER_MODER3 | GPIO_MODER_MODER2 |
|
||||
GPIO_MODER_MODER1 | GPIO_MODER_MODER0;
|
||||
|
||||
// FAN on C9, aka TIM3_CH4
|
||||
#ifdef OLD_BOARD
|
||||
GPIOC->MODER |= GPIO_MODER_MODER9_1;
|
||||
GPIOC->AFR[1] = GPIO_AF2_TIM3 << ((9-8)*4);
|
||||
#else
|
||||
GPIOC->MODER |= GPIO_MODER_MODER8_1;
|
||||
GPIOC->AFR[1] = GPIO_AF2_TIM3 << ((8-8)*4);
|
||||
#endif
|
||||
// IGNITION on C13
|
||||
|
||||
// set mode for LEDs and CAN
|
||||
GPIOB->MODER = GPIO_MODER_MODER10_0 | GPIO_MODER_MODER11_0;
|
||||
// CAN 2
|
||||
GPIOB->MODER |= GPIO_MODER_MODER5_1 | GPIO_MODER_MODER6_1;
|
||||
// CAN 1
|
||||
GPIOB->MODER |= GPIO_MODER_MODER8_1 | GPIO_MODER_MODER9_1;
|
||||
// CAN enables
|
||||
GPIOB->MODER |= GPIO_MODER_MODER3_0 | GPIO_MODER_MODER4_0;
|
||||
|
||||
// set mode for SERIAL and USB (DAC should be configured to in)
|
||||
GPIOA->MODER = GPIO_MODER_MODER2_1 | GPIO_MODER_MODER3_1;
|
||||
GPIOA->AFR[0] = GPIO_AF7_USART2 << (2*4) | GPIO_AF7_USART2 << (3*4);
|
||||
|
||||
// GPIOC USART3
|
||||
GPIOC->MODER |= GPIO_MODER_MODER10_1 | GPIO_MODER_MODER11_1;
|
||||
GPIOC->AFR[1] |= GPIO_AF7_USART3 << ((10-8)*4) | GPIO_AF7_USART3 << ((11-8)*4);
|
||||
|
||||
if (USBx == USB_OTG_FS) {
|
||||
GPIOA->MODER |= GPIO_MODER_MODER11_1 | GPIO_MODER_MODER12_1;
|
||||
GPIOA->OSPEEDR = GPIO_OSPEEDER_OSPEEDR11 | GPIO_OSPEEDER_OSPEEDR12;
|
||||
GPIOA->AFR[1] = GPIO_AF10_OTG_FS << ((11-8)*4) | GPIO_AF10_OTG_FS << ((12-8)*4);
|
||||
}
|
||||
|
||||
GPIOA->PUPDR = GPIO_PUPDR_PUPDR2_0 | GPIO_PUPDR_PUPDR3_0;
|
||||
|
||||
// set mode for CAN / USB_HS pins
|
||||
GPIOB->AFR[0] = GPIO_AF9_CAN1 << (5*4) | GPIO_AF9_CAN1 << (6*4);
|
||||
GPIOB->AFR[1] = GPIO_AF9_CAN1 << ((8-8)*4) | GPIO_AF9_CAN1 << ((9-8)*4);
|
||||
|
||||
if (USBx == USB_OTG_HS) {
|
||||
GPIOB->AFR[1] |= GPIO_AF12_OTG_HS_FS << ((15-8)*4) | GPIO_AF12_OTG_HS_FS << ((14-8)*4);
|
||||
GPIOB->MODER |= GPIO_MODER_MODER14_1 | GPIO_MODER_MODER15_1;
|
||||
}
|
||||
|
||||
GPIOB->OSPEEDR = GPIO_OSPEEDER_OSPEEDR14 | GPIO_OSPEEDER_OSPEEDR15;
|
||||
|
||||
// enable CAN busses
|
||||
GPIOB->ODR |= (1 << 3) | (1 << 4);
|
||||
|
||||
// enable OTG out tied to ground
|
||||
GPIOA->ODR = 0;
|
||||
GPIOA->MODER |= GPIO_MODER_MODER1_0;
|
||||
|
||||
// enable USB power tied to +
|
||||
GPIOA->ODR |= 1;
|
||||
GPIOA->MODER |= GPIO_MODER_MODER0_0;
|
||||
}
|
||||
|
||||
void uart_init() {
|
||||
// enable uart and tx+rx mode
|
||||
USART->CR1 = USART_CR1_UE;
|
||||
USART->BRR = __USART_BRR(24000000, 115200);
|
||||
USART->CR1 |= USART_CR1_TE | USART_CR1_RE;
|
||||
USART->CR2 = USART_CR2_STOP_0 | USART_CR2_STOP_1;
|
||||
// ** UART is ready to work **
|
||||
|
||||
// enable interrupts
|
||||
USART->CR1 |= USART_CR1_RXNEIE;
|
||||
}
|
||||
|
||||
void delay(int a) {
|
||||
volatile int i;
|
||||
for (i=0;i<a;i++);
|
||||
}
|
||||
|
||||
void putch(const char a) {
|
||||
while (!(USART->SR & USART_SR_TXE));
|
||||
USART->DR = a;
|
||||
}
|
||||
|
||||
int puts(const char *a) {
|
||||
for (;*a;a++) {
|
||||
if (*a == '\n') putch('\r');
|
||||
putch(*a);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void puth(unsigned int i) {
|
||||
int pos;
|
||||
char c[] = "0123456789abcdef";
|
||||
for (pos = 28; pos != -4; pos -= 4) {
|
||||
putch(c[(i >> pos) & 0xF]);
|
||||
}
|
||||
}
|
||||
|
||||
void puth2(unsigned int i) {
|
||||
int pos;
|
||||
char c[] = "0123456789abcdef";
|
||||
for (pos = 4; pos != -4; pos -= 4) {
|
||||
putch(c[(i >> pos) & 0xF]);
|
||||
}
|
||||
}
|
||||
|
||||
void hexdump(void *a, int l) {
|
||||
int i;
|
||||
for (i=0;i<l;i++) {
|
||||
if (i != 0 && (i&0xf) == 0) puts("\n");
|
||||
puth2(((unsigned char*)a)[i]);
|
||||
puts(" ");
|
||||
}
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
void *memset(void *str, int c, unsigned int n) {
|
||||
int i;
|
||||
for (i = 0; i < n; i++) {
|
||||
*((uint8_t*)str) = c;
|
||||
++str;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
void *memcpy(void *dest, const void *src, unsigned int n) {
|
||||
int i;
|
||||
// TODO: make not slow
|
||||
for (i = 0; i < n; i++) {
|
||||
((uint8_t*)dest)[i] = *(uint8_t*)src;
|
||||
++src;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
504
board/main.c
504
board/main.c
@@ -1,504 +0,0 @@
|
||||
//#define DEBUG
|
||||
//#define CAN_LOOPBACK_MODE
|
||||
//#define USE_INTERNAL_OSC
|
||||
//#define OLD_BOARD
|
||||
//#define ENABLE_CURRENT_SENSOR
|
||||
|
||||
#define USB_VID 0xbbaa
|
||||
#define USB_PID 0xddcc
|
||||
|
||||
// *** end config ***
|
||||
|
||||
#include "stm32f2xx.h"
|
||||
#include "obj/gitversion.h"
|
||||
|
||||
#define ENTER_BOOTLOADER_MAGIC 0xdeadbeef
|
||||
uint32_t enter_bootloader_mode;
|
||||
|
||||
USB_OTG_GlobalTypeDef *USBx = USB_OTG_FS;
|
||||
|
||||
#include "libc.h"
|
||||
#include "adc.h"
|
||||
#include "timer.h"
|
||||
#include "usb.h"
|
||||
#include "can.h"
|
||||
|
||||
// debug safety check: is controls allowed?
|
||||
int controls_allowed = 0;
|
||||
int gas_interceptor_detected = 0;
|
||||
|
||||
// ********************* instantiate queues *********************
|
||||
|
||||
#define FIFO_SIZE 0x100
|
||||
typedef struct {
|
||||
uint8_t w_ptr;
|
||||
uint8_t r_ptr;
|
||||
CAN_FIFOMailBox_TypeDef elems[FIFO_SIZE];
|
||||
} can_ring;
|
||||
|
||||
can_ring can_rx_q = { .w_ptr = 0, .r_ptr = 0 };
|
||||
can_ring can_tx1_q = { .w_ptr = 0, .r_ptr = 0 };
|
||||
can_ring can_tx2_q = { .w_ptr = 0, .r_ptr = 0 };
|
||||
|
||||
// ********************* interrupt safe queue *********************
|
||||
|
||||
inline int pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
|
||||
if (q->w_ptr != q->r_ptr) {
|
||||
*elem = q->elems[q->r_ptr];
|
||||
q->r_ptr += 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int push(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
|
||||
uint8_t next_w_ptr = q->w_ptr + 1;
|
||||
if (next_w_ptr != q->r_ptr) {
|
||||
q->elems[q->w_ptr] = *elem;
|
||||
q->w_ptr = next_w_ptr;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ***************************** CAN *****************************
|
||||
|
||||
void process_can(CAN_TypeDef *CAN, can_ring *can_q, int can_number) {
|
||||
#ifdef DEBUG
|
||||
puts("process CAN TX\n");
|
||||
#endif
|
||||
|
||||
// add successfully transmitted message to my fifo
|
||||
if ((CAN->TSR & CAN_TSR_TXOK0) == CAN_TSR_TXOK0) {
|
||||
CAN_FIFOMailBox_TypeDef to_push;
|
||||
to_push.RIR = CAN->sTxMailBox[0].TIR;
|
||||
to_push.RDTR = (CAN->sTxMailBox[0].TDTR & 0xFFFF000F) | ((can_number+2) << 4);
|
||||
to_push.RDLR = CAN->sTxMailBox[0].TDLR;
|
||||
to_push.RDHR = CAN->sTxMailBox[0].TDHR;
|
||||
push(&can_rx_q, &to_push);
|
||||
}
|
||||
|
||||
// check for empty mailbox
|
||||
CAN_FIFOMailBox_TypeDef to_send;
|
||||
if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) {
|
||||
if (pop(can_q, &to_send)) {
|
||||
|
||||
// BRAKE: safety check
|
||||
if ((to_send.RIR>>21) == 0x1FA) {
|
||||
if (controls_allowed) {
|
||||
to_send.RDLR &= 0xFFFFFF3F;
|
||||
} else {
|
||||
to_send.RDLR &= 0xFFFF0000;
|
||||
}
|
||||
}
|
||||
|
||||
// STEER: safety check
|
||||
if ((to_send.RIR>>21) == 0xE4) {
|
||||
if (controls_allowed) {
|
||||
to_send.RDLR &= 0xFFFFFFFF;
|
||||
} else {
|
||||
to_send.RDLR &= 0xFFFF0000;
|
||||
}
|
||||
}
|
||||
|
||||
// GAS: safety check
|
||||
if ((to_send.RIR>>21) == 0x200) {
|
||||
if (controls_allowed) {
|
||||
to_send.RDLR &= 0xFFFFFFFF;
|
||||
} else {
|
||||
to_send.RDLR &= 0xFFFF0000;
|
||||
}
|
||||
}
|
||||
|
||||
// only send if we have received a packet
|
||||
CAN->sTxMailBox[0].TDLR = to_send.RDLR;
|
||||
CAN->sTxMailBox[0].TDHR = to_send.RDHR;
|
||||
CAN->sTxMailBox[0].TDTR = to_send.RDTR;
|
||||
CAN->sTxMailBox[0].TIR = to_send.RIR;
|
||||
}
|
||||
}
|
||||
|
||||
// clear interrupt
|
||||
CAN->TSR |= CAN_TSR_RQCP0;
|
||||
}
|
||||
|
||||
// send more, possible for these to not trigger?
|
||||
void CAN1_TX_IRQHandler() {
|
||||
process_can(CAN1, &can_tx1_q, 1);
|
||||
}
|
||||
|
||||
void CAN2_TX_IRQHandler() {
|
||||
process_can(CAN2, &can_tx2_q, 0);
|
||||
}
|
||||
|
||||
// board enforces
|
||||
// in-state
|
||||
// accel set/resume
|
||||
// out-state
|
||||
// cancel button
|
||||
|
||||
|
||||
// all commands: brake and steering
|
||||
// if controls_allowed
|
||||
// allow all commands up to limit
|
||||
// else
|
||||
// block all commands that produce actuation
|
||||
|
||||
// CAN receive handlers
|
||||
void can_rx(CAN_TypeDef *CAN, int can_number) {
|
||||
while (CAN->RF0R & CAN_RF0R_FMP0) {
|
||||
// add to my fifo
|
||||
CAN_FIFOMailBox_TypeDef to_push;
|
||||
to_push.RIR = CAN->sFIFOMailBox[0].RIR;
|
||||
// top 16-bits is the timestamp
|
||||
to_push.RDTR = (CAN->sFIFOMailBox[0].RDTR & 0xFFFF000F) | (can_number << 4);
|
||||
to_push.RDLR = CAN->sFIFOMailBox[0].RDLR;
|
||||
to_push.RDHR = CAN->sFIFOMailBox[0].RDHR;
|
||||
|
||||
// state machine to enter and exit controls
|
||||
// 0x1A6 for the ILX, 0x296 for the Civic Touring
|
||||
if ((to_push.RIR>>21) == 0x1A6 || (to_push.RIR>>21) == 0x296) {
|
||||
int buttons = (to_push.RDLR & 0xE0) >> 5;
|
||||
if (buttons == 4 || buttons == 3) {
|
||||
controls_allowed = 1;
|
||||
} else if (buttons == 2) {
|
||||
controls_allowed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// exit controls on brake press
|
||||
if ((to_push.RIR>>21) == 0x17C) {
|
||||
// bit 50
|
||||
if (to_push.RDHR & 0x200000) {
|
||||
controls_allowed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// exit controls on gas press if interceptor
|
||||
if ((to_push.RIR>>21) == 0x201) {
|
||||
gas_interceptor_detected = 1;
|
||||
int gas = ((to_push.RDLR & 0xFF) << 8) | ((to_push.RDLR & 0xFF00) >> 8);
|
||||
if (gas > 328) {
|
||||
controls_allowed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// exit controls on gas press if no interceptor
|
||||
if (!gas_interceptor_detected) {
|
||||
if ((to_push.RIR>>21) == 0x17C) {
|
||||
if (to_push.RDLR & 0xFF) {
|
||||
controls_allowed = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
push(&can_rx_q, &to_push);
|
||||
|
||||
// next
|
||||
CAN->RF0R |= CAN_RF0R_RFOM0;
|
||||
}
|
||||
}
|
||||
|
||||
void CAN1_RX0_IRQHandler() {
|
||||
//puts("CANRX1");
|
||||
//delay(10000);
|
||||
can_rx(CAN1, 1);
|
||||
}
|
||||
|
||||
void CAN2_RX0_IRQHandler() {
|
||||
//puts("CANRX0");
|
||||
//delay(10000);
|
||||
can_rx(CAN2, 0);
|
||||
}
|
||||
|
||||
void CAN1_SCE_IRQHandler() {
|
||||
//puts("CAN1_SCE\n");
|
||||
can_sce(CAN1);
|
||||
}
|
||||
|
||||
void CAN2_SCE_IRQHandler() {
|
||||
//puts("CAN2_SCE\n");
|
||||
can_sce(CAN2);
|
||||
}
|
||||
|
||||
// ***************************** serial port *****************************
|
||||
|
||||
void USART_IRQHandler(void) {
|
||||
puts("S");
|
||||
|
||||
// echo characters
|
||||
if (USART->SR & USART_SR_RXNE) {
|
||||
char rcv = USART->DR;
|
||||
putch(rcv);
|
||||
|
||||
// jump to DFU flash
|
||||
if (rcv == 'z') {
|
||||
enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC;
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USART2_IRQHandler(void) {
|
||||
USART_IRQHandler();
|
||||
}
|
||||
|
||||
void USART3_IRQHandler(void) {
|
||||
USART_IRQHandler();
|
||||
}
|
||||
|
||||
// ***************************** USB port *****************************
|
||||
|
||||
int get_health_pkt(void *dat) {
|
||||
struct {
|
||||
uint32_t voltage;
|
||||
uint32_t current;
|
||||
uint8_t started;
|
||||
uint8_t controls_allowed;
|
||||
uint8_t gas_interceptor_detected;
|
||||
} *health = dat;
|
||||
health->voltage = adc_get(ADCCHAN_VOLTAGE);
|
||||
#ifdef ENABLE_CURRENT_SENSOR
|
||||
health->current = adc_get(ADCCHAN_CURRENT);
|
||||
#else
|
||||
health->current = 0;
|
||||
#endif
|
||||
health->started = (GPIOC->IDR & (1 << 13)) != 0;
|
||||
health->controls_allowed = controls_allowed;
|
||||
health->gas_interceptor_detected = gas_interceptor_detected;
|
||||
return sizeof(*health);
|
||||
}
|
||||
|
||||
void set_fan_speed(int fan_speed) {
|
||||
#ifdef OLD_BOARD
|
||||
TIM3->CCR4 = fan_speed;
|
||||
#else
|
||||
TIM3->CCR3 = fan_speed;
|
||||
#endif
|
||||
}
|
||||
|
||||
void usb_cb_ep1_in(int len) {
|
||||
CAN_FIFOMailBox_TypeDef reply[4];
|
||||
|
||||
int ilen = 0;
|
||||
while (ilen < min(len/0x10, 4) && pop(&can_rx_q, &reply[ilen])) ilen++;
|
||||
|
||||
#ifdef DEBUG
|
||||
puts("FIFO SENDING ");
|
||||
puth(ilen);
|
||||
puts("\n");
|
||||
#endif
|
||||
|
||||
USB_WritePacket((void *)reply, ilen*0x10, 1);
|
||||
}
|
||||
|
||||
void usb_cb_ep2_out(uint8_t *usbdata, int len) {
|
||||
}
|
||||
|
||||
// send on CAN
|
||||
void usb_cb_ep3_out(uint8_t *usbdata, int len) {
|
||||
int dpkt = 0;
|
||||
for (dpkt = 0; dpkt < len; dpkt += 0x10) {
|
||||
uint32_t *tf = (uint32_t*)(&usbdata[dpkt]);
|
||||
|
||||
int flags = tf[1] >> 4;
|
||||
CAN_TypeDef *CAN;
|
||||
can_ring *can_q;
|
||||
int can_number = 0;
|
||||
if (flags & 1) {
|
||||
CAN=CAN1;
|
||||
can_q = &can_tx1_q;
|
||||
can_number = 1;
|
||||
} else {
|
||||
CAN=CAN2;
|
||||
can_q = &can_tx2_q;
|
||||
}
|
||||
|
||||
// add CAN packet to send queue
|
||||
CAN_FIFOMailBox_TypeDef to_push;
|
||||
to_push.RDHR = tf[3];
|
||||
to_push.RDLR = tf[2];
|
||||
to_push.RDTR = tf[1] & 0xF;
|
||||
to_push.RIR = tf[0];
|
||||
push(can_q, &to_push);
|
||||
|
||||
process_can(CAN, can_q, can_number);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void usb_cb_control_msg() {
|
||||
uint8_t resp[0x20];
|
||||
int resp_len;
|
||||
switch (setup.b.bRequest) {
|
||||
case 0xd1:
|
||||
enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC;
|
||||
NVIC_SystemReset();
|
||||
break;
|
||||
case 0xd2:
|
||||
resp_len = get_health_pkt(resp);
|
||||
USB_WritePacket(resp, resp_len, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
case 0xd3:
|
||||
set_fan_speed(setup.b.wValue.w);
|
||||
USB_WritePacket(0, 0, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
case 0xd6: // GET_VERSION
|
||||
USB_WritePacket(gitversion, min(sizeof(gitversion), setup.b.wLength.w), 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
case 0xd8: // RESET
|
||||
NVIC_SystemReset();
|
||||
break;
|
||||
default:
|
||||
puts("NO HANDLER ");
|
||||
puth(setup.b.bRequest);
|
||||
puts("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OTG_FS_IRQHandler(void) {
|
||||
NVIC_DisableIRQ(OTG_FS_IRQn);
|
||||
//__disable_irq();
|
||||
usb_irqhandler();
|
||||
//__enable_irq();
|
||||
NVIC_EnableIRQ(OTG_FS_IRQn);
|
||||
}
|
||||
|
||||
void OTG_HS_IRQHandler(void) {
|
||||
//puts("HS_IRQ\n");
|
||||
NVIC_DisableIRQ(OTG_FS_IRQn);
|
||||
//__disable_irq();
|
||||
usb_irqhandler();
|
||||
//__enable_irq();
|
||||
NVIC_EnableIRQ(OTG_FS_IRQn);
|
||||
}
|
||||
|
||||
void ADC_IRQHandler(void) {
|
||||
puts("ADC_IRQ\n");
|
||||
}
|
||||
|
||||
// ***************************** main code *****************************
|
||||
|
||||
void __initialize_hardware_early() {
|
||||
// set USB power + and OTG mode
|
||||
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
|
||||
|
||||
// enable OTG out tied to ground
|
||||
GPIOA->ODR = 0;
|
||||
GPIOA->MODER |= GPIO_MODER_MODER1_0;
|
||||
|
||||
// enable USB power tied to +
|
||||
GPIOA->ODR |= 1;
|
||||
GPIOA->MODER |= GPIO_MODER_MODER0_0;
|
||||
|
||||
// enable pull DOWN on OTG_FS_DP
|
||||
// must be done a while before reading it
|
||||
GPIOA->PUPDR = GPIO_PUPDR_PUPDR12_1;
|
||||
|
||||
if (enter_bootloader_mode == ENTER_BOOTLOADER_MAGIC) {
|
||||
enter_bootloader_mode = 0;
|
||||
void (*bootloader)(void) = (void (*)(void)) (*((uint32_t *)0x1fff0004));
|
||||
|
||||
// jump to bootloader
|
||||
bootloader();
|
||||
|
||||
// LOOP
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
// init devices
|
||||
clock_init();
|
||||
|
||||
// test the USB choice before GPIO init
|
||||
if (GPIOA->IDR & (1 << 12)) {
|
||||
USBx = USB_OTG_HS;
|
||||
}
|
||||
|
||||
gpio_init();
|
||||
uart_init();
|
||||
usb_init();
|
||||
can_init(CAN1);
|
||||
can_init(CAN2);
|
||||
adc_init();
|
||||
|
||||
// timer for fan PWM
|
||||
#ifdef OLD_BOARD
|
||||
TIM3->CCMR2 = TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1;
|
||||
TIM3->CCER = TIM_CCER_CC4E;
|
||||
#else
|
||||
TIM3->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1;
|
||||
TIM3->CCER = TIM_CCER_CC3E;
|
||||
#endif
|
||||
|
||||
// max value of the timer
|
||||
// 64 makes it above the audible range
|
||||
//TIM3->ARR = 64;
|
||||
|
||||
// 10 prescale makes it below the audible range
|
||||
timer_init(TIM3, 10);
|
||||
|
||||
// set PWM
|
||||
set_fan_speed(65535);
|
||||
|
||||
puts("**** INTERRUPTS ON ****\n");
|
||||
__disable_irq();
|
||||
NVIC_EnableIRQ(USART2_IRQn);
|
||||
NVIC_EnableIRQ(USART3_IRQn);
|
||||
NVIC_EnableIRQ(OTG_FS_IRQn);
|
||||
NVIC_EnableIRQ(OTG_HS_IRQn);
|
||||
NVIC_EnableIRQ(ADC_IRQn);
|
||||
// CAN has so many interrupts!
|
||||
|
||||
NVIC_EnableIRQ(CAN1_TX_IRQn);
|
||||
NVIC_EnableIRQ(CAN1_RX0_IRQn);
|
||||
NVIC_EnableIRQ(CAN1_SCE_IRQn);
|
||||
|
||||
NVIC_EnableIRQ(CAN2_TX_IRQn);
|
||||
NVIC_EnableIRQ(CAN2_RX0_IRQn);
|
||||
NVIC_EnableIRQ(CAN2_SCE_IRQn);
|
||||
__enable_irq();
|
||||
|
||||
|
||||
// LED should keep on blinking all the time
|
||||
while (1) {
|
||||
#ifdef DEBUG
|
||||
puts("** blink ");
|
||||
puth(can_rx_q.r_ptr); puts(" "); puth(can_rx_q.w_ptr); puts(" ");
|
||||
puth(can_tx1_q.r_ptr); puts(" "); puth(can_tx1_q.w_ptr); puts(" ");
|
||||
puth(can_tx2_q.r_ptr); puts(" "); puth(can_tx2_q.w_ptr); puts("\n");
|
||||
#endif
|
||||
|
||||
/*puts("voltage: "); puth(adc_get(ADCCHAN_VOLTAGE)); puts(" ");
|
||||
puts("current: "); puth(adc_get(ADCCHAN_CURRENT)); puts("\n");*/
|
||||
|
||||
// set LED to be controls allowed
|
||||
GPIOB->ODR = (GPIOB->ODR | (1 << 11)) & ~(controls_allowed << 11);
|
||||
|
||||
// blink the other LED if in FS mode
|
||||
if (USBx == USB_OTG_FS) {
|
||||
GPIOB->ODR |= (1 << 10);
|
||||
}
|
||||
delay(1000000);
|
||||
GPIOB->ODR &= ~(1 << 10);
|
||||
delay(1000000);
|
||||
|
||||
if (GPIOC->IDR & (1 << 13)) {
|
||||
// turn on fan at half speed
|
||||
set_fan_speed(32768);
|
||||
} else {
|
||||
// turn off fan
|
||||
set_fan_speed(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,511 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file startup_stm32f205xx.s
|
||||
* @author MCD Application Team
|
||||
* @version V2.0.1
|
||||
* @date 25-March-2014
|
||||
* @brief STM32F205xx Devices vector table for Atollic TrueSTUDIO toolchain.
|
||||
* This module performs:
|
||||
* - Set the initial SP
|
||||
* - Set the initial PC == Reset_Handler,
|
||||
* - Set the vector table entries with the exceptions ISR address
|
||||
* - Branches to main in the C library (which eventually
|
||||
* calls main()).
|
||||
* After Reset the Cortex-M3 processor is in Thread mode,
|
||||
* priority is Privileged, and the Stack is set to Main.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m3
|
||||
.thumb
|
||||
|
||||
.global g_pfnVectors
|
||||
.global Default_Handler
|
||||
|
||||
/* start address for the initialization values of the .data section.
|
||||
defined in linker script */
|
||||
.word _sidata
|
||||
/* start address for the .data section. defined in linker script */
|
||||
.word _sdata
|
||||
/* end address for the .data section. defined in linker script */
|
||||
.word _edata
|
||||
/* start address for the .bss section. defined in linker script */
|
||||
.word _sbss
|
||||
/* end address for the .bss section. defined in linker script */
|
||||
.word _ebss
|
||||
/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
|
||||
|
||||
/**
|
||||
* @brief This is the code that gets called when the processor first
|
||||
* starts execution following a reset event. Only the absolutely
|
||||
* necessary set is performed, after which the application
|
||||
* supplied main() routine is called.
|
||||
* @param None
|
||||
* @retval : None
|
||||
*/
|
||||
|
||||
.section .text.Reset_Handler
|
||||
.weak Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
bl __initialize_hardware_early
|
||||
ldr sp, =_estack /* set stack pointer */
|
||||
|
||||
/* Copy the data segment initializers from flash to SRAM */
|
||||
movs r1, #0
|
||||
b LoopCopyDataInit
|
||||
|
||||
CopyDataInit:
|
||||
ldr r3, =_sidata
|
||||
ldr r3, [r3, r1]
|
||||
str r3, [r0, r1]
|
||||
adds r1, r1, #4
|
||||
|
||||
LoopCopyDataInit:
|
||||
ldr r0, =_sdata
|
||||
ldr r3, =_edata
|
||||
adds r2, r0, r1
|
||||
cmp r2, r3
|
||||
bcc CopyDataInit
|
||||
ldr r2, =_sbss
|
||||
b LoopFillZerobss
|
||||
/* Zero fill the bss segment. */
|
||||
FillZerobss:
|
||||
movs r3, #0
|
||||
str r3, [r2], #4
|
||||
|
||||
LoopFillZerobss:
|
||||
ldr r3, = _ebss
|
||||
cmp r2, r3
|
||||
bcc FillZerobss
|
||||
|
||||
/* Call the clock system intitialization function.*/
|
||||
/* bl SystemInit */
|
||||
/* Call static constructors */
|
||||
/* bl __libc_init_array */
|
||||
/* Call the application's entry point.*/
|
||||
bl main
|
||||
bx lr
|
||||
.size Reset_Handler, .-Reset_Handler
|
||||
|
||||
/**
|
||||
* @brief This is the code that gets called when the processor receives an
|
||||
* unexpected interrupt. This simply enters an infinite loop, preserving
|
||||
* the system state for examination by a debugger.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
.section .text.Default_Handler,"ax",%progbits
|
||||
Default_Handler:
|
||||
Infinite_Loop:
|
||||
b Infinite_Loop
|
||||
.size Default_Handler, .-Default_Handler
|
||||
/******************************************************************************
|
||||
*
|
||||
* The minimal vector table for a Cortex M3. Note that the proper constructs
|
||||
* must be placed on this to ensure that it ends up at physical address
|
||||
* 0x0000.0000.
|
||||
*
|
||||
*******************************************************************************/
|
||||
.section .isr_vector,"a",%progbits
|
||||
.type g_pfnVectors, %object
|
||||
.size g_pfnVectors, .-g_pfnVectors
|
||||
|
||||
|
||||
|
||||
g_pfnVectors:
|
||||
.word _estack
|
||||
.word Reset_Handler
|
||||
|
||||
.word NMI_Handler
|
||||
.word HardFault_Handler
|
||||
.word MemManage_Handler
|
||||
.word BusFault_Handler
|
||||
.word UsageFault_Handler
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word SVC_Handler
|
||||
.word DebugMon_Handler
|
||||
.word 0
|
||||
.word PendSV_Handler
|
||||
.word SysTick_Handler
|
||||
|
||||
/* External Interrupts */
|
||||
.word WWDG_IRQHandler /* Window WatchDog */
|
||||
.word PVD_IRQHandler /* PVD through EXTI Line detection */
|
||||
.word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */
|
||||
.word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */
|
||||
.word FLASH_IRQHandler /* FLASH */
|
||||
.word RCC_IRQHandler /* RCC */
|
||||
.word EXTI0_IRQHandler /* EXTI Line0 */
|
||||
.word EXTI1_IRQHandler /* EXTI Line1 */
|
||||
.word EXTI2_IRQHandler /* EXTI Line2 */
|
||||
.word EXTI3_IRQHandler /* EXTI Line3 */
|
||||
.word EXTI4_IRQHandler /* EXTI Line4 */
|
||||
.word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */
|
||||
.word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */
|
||||
.word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */
|
||||
.word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */
|
||||
.word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */
|
||||
.word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */
|
||||
.word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */
|
||||
.word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */
|
||||
.word CAN1_TX_IRQHandler /* CAN1 TX */
|
||||
.word CAN1_RX0_IRQHandler /* CAN1 RX0 */
|
||||
.word CAN1_RX1_IRQHandler /* CAN1 RX1 */
|
||||
.word CAN1_SCE_IRQHandler /* CAN1 SCE */
|
||||
.word EXTI9_5_IRQHandler /* External Line[9:5]s */
|
||||
.word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */
|
||||
.word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */
|
||||
.word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */
|
||||
.word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
|
||||
.word TIM2_IRQHandler /* TIM2 */
|
||||
.word TIM3_IRQHandler /* TIM3 */
|
||||
.word TIM4_IRQHandler /* TIM4 */
|
||||
.word I2C1_EV_IRQHandler /* I2C1 Event */
|
||||
.word I2C1_ER_IRQHandler /* I2C1 Error */
|
||||
.word I2C2_EV_IRQHandler /* I2C2 Event */
|
||||
.word I2C2_ER_IRQHandler /* I2C2 Error */
|
||||
.word SPI1_IRQHandler /* SPI1 */
|
||||
.word SPI2_IRQHandler /* SPI2 */
|
||||
.word USART1_IRQHandler /* USART1 */
|
||||
.word USART2_IRQHandler /* USART2 */
|
||||
.word USART3_IRQHandler /* USART3 */
|
||||
.word EXTI15_10_IRQHandler /* External Line[15:10]s */
|
||||
.word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */
|
||||
.word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */
|
||||
.word TIM8_BRK_TIM12_IRQHandler /* TIM8 Break and TIM12 */
|
||||
.word TIM8_UP_TIM13_IRQHandler /* TIM8 Update and TIM13 */
|
||||
.word TIM8_TRG_COM_TIM14_IRQHandler /* TIM8 Trigger and Commutation and TIM14 */
|
||||
.word TIM8_CC_IRQHandler /* TIM8 Capture Compare */
|
||||
.word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */
|
||||
.word FSMC_IRQHandler /* FSMC */
|
||||
.word SDIO_IRQHandler /* SDIO */
|
||||
.word TIM5_IRQHandler /* TIM5 */
|
||||
.word SPI3_IRQHandler /* SPI3 */
|
||||
.word UART4_IRQHandler /* UART4 */
|
||||
.word UART5_IRQHandler /* UART5 */
|
||||
.word TIM6_DAC_IRQHandler /* TIM6 and DAC1&2 underrun errors */
|
||||
.word TIM7_IRQHandler /* TIM7 */
|
||||
.word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */
|
||||
.word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */
|
||||
.word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */
|
||||
.word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */
|
||||
.word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word CAN2_TX_IRQHandler /* CAN2 TX */
|
||||
.word CAN2_RX0_IRQHandler /* CAN2 RX0 */
|
||||
.word CAN2_RX1_IRQHandler /* CAN2 RX1 */
|
||||
.word CAN2_SCE_IRQHandler /* CAN2 SCE */
|
||||
.word OTG_FS_IRQHandler /* USB OTG FS */
|
||||
.word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */
|
||||
.word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */
|
||||
.word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */
|
||||
.word USART6_IRQHandler /* USART6 */
|
||||
.word I2C3_EV_IRQHandler /* I2C3 event */
|
||||
.word I2C3_ER_IRQHandler /* I2C3 error */
|
||||
.word OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */
|
||||
.word OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */
|
||||
.word OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */
|
||||
.word OTG_HS_IRQHandler /* USB OTG HS */
|
||||
.word 0 /* Reserved */
|
||||
.word 0 /* Reserved */
|
||||
.word HASH_RNG_IRQHandler /* Hash and Rng */
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Provide weak aliases for each Exception handler to the Default_Handler.
|
||||
* As they are weak aliases, any function with the same name will override
|
||||
* this definition.
|
||||
*
|
||||
*******************************************************************************/
|
||||
.weak NMI_Handler
|
||||
.thumb_set NMI_Handler,Default_Handler
|
||||
|
||||
.weak HardFault_Handler
|
||||
.thumb_set HardFault_Handler,Default_Handler
|
||||
|
||||
.weak MemManage_Handler
|
||||
.thumb_set MemManage_Handler,Default_Handler
|
||||
|
||||
.weak BusFault_Handler
|
||||
.thumb_set BusFault_Handler,Default_Handler
|
||||
|
||||
.weak UsageFault_Handler
|
||||
.thumb_set UsageFault_Handler,Default_Handler
|
||||
|
||||
.weak SVC_Handler
|
||||
.thumb_set SVC_Handler,Default_Handler
|
||||
|
||||
.weak DebugMon_Handler
|
||||
.thumb_set DebugMon_Handler,Default_Handler
|
||||
|
||||
.weak PendSV_Handler
|
||||
.thumb_set PendSV_Handler,Default_Handler
|
||||
|
||||
.weak SysTick_Handler
|
||||
.thumb_set SysTick_Handler,Default_Handler
|
||||
|
||||
.weak WWDG_IRQHandler
|
||||
.thumb_set WWDG_IRQHandler,Default_Handler
|
||||
|
||||
.weak PVD_IRQHandler
|
||||
.thumb_set PVD_IRQHandler,Default_Handler
|
||||
|
||||
.weak TAMP_STAMP_IRQHandler
|
||||
.thumb_set TAMP_STAMP_IRQHandler,Default_Handler
|
||||
|
||||
.weak RTC_WKUP_IRQHandler
|
||||
.thumb_set RTC_WKUP_IRQHandler,Default_Handler
|
||||
|
||||
.weak FLASH_IRQHandler
|
||||
.thumb_set FLASH_IRQHandler,Default_Handler
|
||||
|
||||
.weak RCC_IRQHandler
|
||||
.thumb_set RCC_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI0_IRQHandler
|
||||
.thumb_set EXTI0_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI1_IRQHandler
|
||||
.thumb_set EXTI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI2_IRQHandler
|
||||
.thumb_set EXTI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI3_IRQHandler
|
||||
.thumb_set EXTI3_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI4_IRQHandler
|
||||
.thumb_set EXTI4_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream0_IRQHandler
|
||||
.thumb_set DMA1_Stream0_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream1_IRQHandler
|
||||
.thumb_set DMA1_Stream1_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream2_IRQHandler
|
||||
.thumb_set DMA1_Stream2_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream3_IRQHandler
|
||||
.thumb_set DMA1_Stream3_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream4_IRQHandler
|
||||
.thumb_set DMA1_Stream4_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream5_IRQHandler
|
||||
.thumb_set DMA1_Stream5_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream6_IRQHandler
|
||||
.thumb_set DMA1_Stream6_IRQHandler,Default_Handler
|
||||
|
||||
.weak ADC_IRQHandler
|
||||
.thumb_set ADC_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN1_TX_IRQHandler
|
||||
.thumb_set CAN1_TX_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN1_RX0_IRQHandler
|
||||
.thumb_set CAN1_RX0_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN1_RX1_IRQHandler
|
||||
.thumb_set CAN1_RX1_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN1_SCE_IRQHandler
|
||||
.thumb_set CAN1_SCE_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI9_5_IRQHandler
|
||||
.thumb_set EXTI9_5_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_BRK_TIM9_IRQHandler
|
||||
.thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_UP_TIM10_IRQHandler
|
||||
.thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_TRG_COM_TIM11_IRQHandler
|
||||
.thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_CC_IRQHandler
|
||||
.thumb_set TIM1_CC_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM2_IRQHandler
|
||||
.thumb_set TIM2_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM3_IRQHandler
|
||||
.thumb_set TIM3_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM4_IRQHandler
|
||||
.thumb_set TIM4_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C1_EV_IRQHandler
|
||||
.thumb_set I2C1_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C1_ER_IRQHandler
|
||||
.thumb_set I2C1_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C2_EV_IRQHandler
|
||||
.thumb_set I2C2_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C2_ER_IRQHandler
|
||||
.thumb_set I2C2_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI1_IRQHandler
|
||||
.thumb_set SPI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI2_IRQHandler
|
||||
.thumb_set SPI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART1_IRQHandler
|
||||
.thumb_set USART1_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART2_IRQHandler
|
||||
.thumb_set USART2_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART3_IRQHandler
|
||||
.thumb_set USART3_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI15_10_IRQHandler
|
||||
.thumb_set EXTI15_10_IRQHandler,Default_Handler
|
||||
|
||||
.weak RTC_Alarm_IRQHandler
|
||||
.thumb_set RTC_Alarm_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_FS_WKUP_IRQHandler
|
||||
.thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_BRK_TIM12_IRQHandler
|
||||
.thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_UP_TIM13_IRQHandler
|
||||
.thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_TRG_COM_TIM14_IRQHandler
|
||||
.thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM8_CC_IRQHandler
|
||||
.thumb_set TIM8_CC_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Stream7_IRQHandler
|
||||
.thumb_set DMA1_Stream7_IRQHandler,Default_Handler
|
||||
|
||||
.weak FSMC_IRQHandler
|
||||
.thumb_set FSMC_IRQHandler,Default_Handler
|
||||
|
||||
.weak SDIO_IRQHandler
|
||||
.thumb_set SDIO_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM5_IRQHandler
|
||||
.thumb_set TIM5_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI3_IRQHandler
|
||||
.thumb_set SPI3_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART4_IRQHandler
|
||||
.thumb_set UART4_IRQHandler,Default_Handler
|
||||
|
||||
.weak UART5_IRQHandler
|
||||
.thumb_set UART5_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM6_DAC_IRQHandler
|
||||
.thumb_set TIM6_DAC_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM7_IRQHandler
|
||||
.thumb_set TIM7_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream0_IRQHandler
|
||||
.thumb_set DMA2_Stream0_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream1_IRQHandler
|
||||
.thumb_set DMA2_Stream1_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream2_IRQHandler
|
||||
.thumb_set DMA2_Stream2_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream3_IRQHandler
|
||||
.thumb_set DMA2_Stream3_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream4_IRQHandler
|
||||
.thumb_set DMA2_Stream4_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN2_TX_IRQHandler
|
||||
.thumb_set CAN2_TX_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN2_RX0_IRQHandler
|
||||
.thumb_set CAN2_RX0_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN2_RX1_IRQHandler
|
||||
.thumb_set CAN2_RX1_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN2_SCE_IRQHandler
|
||||
.thumb_set CAN2_SCE_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_FS_IRQHandler
|
||||
.thumb_set OTG_FS_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream5_IRQHandler
|
||||
.thumb_set DMA2_Stream5_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream6_IRQHandler
|
||||
.thumb_set DMA2_Stream6_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA2_Stream7_IRQHandler
|
||||
.thumb_set DMA2_Stream7_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART6_IRQHandler
|
||||
.thumb_set USART6_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C3_EV_IRQHandler
|
||||
.thumb_set I2C3_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C3_ER_IRQHandler
|
||||
.thumb_set I2C3_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_HS_EP1_OUT_IRQHandler
|
||||
.thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_HS_EP1_IN_IRQHandler
|
||||
.thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_HS_WKUP_IRQHandler
|
||||
.thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler
|
||||
|
||||
.weak OTG_HS_IRQHandler
|
||||
.thumb_set OTG_HS_IRQHandler,Default_Handler
|
||||
|
||||
.weak HASH_RNG_IRQHandler
|
||||
.thumb_set HASH_RNG_IRQHandler,Default_Handler
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
*****************************************************************************
|
||||
**
|
||||
** File : stm32_flash.ld
|
||||
**
|
||||
** Abstract : Linker script for STM32F407VG Device with
|
||||
** 1024KByte FLASH, 192KByte RAM
|
||||
**
|
||||
** Set heap size, stack size and stack location according
|
||||
** to application requirements.
|
||||
**
|
||||
** Set memory bank area and size if external memory is used.
|
||||
**
|
||||
** Target : STMicroelectronics STM32
|
||||
**
|
||||
** Environment : Atollic TrueSTUDIO(R)
|
||||
**
|
||||
** Distribution: The file is distributed “as is,” without any warranty
|
||||
** of any kind.
|
||||
**
|
||||
** (c)Copyright Atollic AB.
|
||||
** You may use this file as-is or modify it according to the needs of your
|
||||
** project. Distribution of this file (unmodified or modified) is not
|
||||
** permitted. Atollic AB permit registered Atollic TrueSTUDIO(R) users the
|
||||
** rights to distribute the assembled, compiled & linked contents of this
|
||||
** file as part of an application binary file, provided that it is built
|
||||
** using the Atollic TrueSTUDIO(R) toolchain.
|
||||
**
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
/* Entry Point */
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
/* Highest address of the user mode stack */
|
||||
_estack = 0x20020000; /* end of 128K RAM on AHB bus*/
|
||||
|
||||
/* Generate a link error if heap and stack don't fit into RAM */
|
||||
_Min_Heap_Size = 0; /* required amount of heap */
|
||||
_Min_Stack_Size = 0x400; /* required amount of stack */
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
|
||||
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
|
||||
}
|
||||
|
||||
/* Define output sections */
|
||||
SECTIONS
|
||||
{
|
||||
/* The startup code goes first into FLASH */
|
||||
.isr_vector :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector)) /* Startup code */
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
|
||||
/* The program code and other data goes into FLASH */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text) /* .text sections (code) */
|
||||
*(.text*) /* .text* sections (code) */
|
||||
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||
*(.glue_7) /* glue arm to thumb code */
|
||||
*(.glue_7t) /* glue thumb to arm code */
|
||||
*(.eh_frame)
|
||||
|
||||
KEEP (*(.init))
|
||||
KEEP (*(.fini))
|
||||
|
||||
. = ALIGN(4);
|
||||
_etext = .; /* define a global symbols at end of code */
|
||||
_exit = .;
|
||||
} >FLASH
|
||||
|
||||
|
||||
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
|
||||
.ARM : {
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
__exidx_end = .;
|
||||
} >FLASH
|
||||
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array*))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
} >FLASH
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array*))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
} >FLASH
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(.fini_array*))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
} >FLASH
|
||||
|
||||
/* used by the startup to initialize data */
|
||||
_sidata = .;
|
||||
|
||||
/* Initialized data sections goes into RAM, load LMA copy after code */
|
||||
.data : AT ( _sidata )
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_sdata = .; /* create a global symbol at data start */
|
||||
*(.data) /* .data sections */
|
||||
*(.data*) /* .data* sections */
|
||||
|
||||
. = ALIGN(4);
|
||||
_edata = .; /* define a global symbol at data end */
|
||||
} >RAM
|
||||
|
||||
/* Uninitialized data section */
|
||||
. = ALIGN(4);
|
||||
.bss :
|
||||
{
|
||||
/* This is used by the startup in order to initialize the .bss secion */
|
||||
_sbss = .; /* define a global symbol at bss start */
|
||||
__bss_start__ = _sbss;
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
|
||||
. = ALIGN(4);
|
||||
_ebss = .; /* define a global symbol at bss end */
|
||||
__bss_end__ = _ebss;
|
||||
} >RAM
|
||||
|
||||
/* User_heap_stack section, used to check that there is enough RAM left */
|
||||
._user_heap_stack :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
PROVIDE ( end = . );
|
||||
PROVIDE ( _end = . );
|
||||
. = . + _Min_Heap_Size;
|
||||
. = . + _Min_Stack_Size;
|
||||
. = ALIGN(4);
|
||||
} >RAM
|
||||
|
||||
/* MEMORY_bank1 section, code must be located here explicitly */
|
||||
/* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */
|
||||
.memory_b1_text :
|
||||
{
|
||||
*(.mb1text) /* .mb1text sections (code) */
|
||||
*(.mb1text*) /* .mb1text* sections (code) */
|
||||
*(.mb1rodata) /* read-only data (constants) */
|
||||
*(.mb1rodata*)
|
||||
} >MEMORY_B1
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
void timer_init(TIM_TypeDef *TIM, int psc) {
|
||||
TIM->PSC = psc-1;
|
||||
TIM->DIER = TIM_DIER_UIE;
|
||||
TIM->CR1 = TIM_CR1_CEN;
|
||||
TIM->SR = 0;
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
import usb1
|
||||
import time
|
||||
import traceback
|
||||
|
||||
if __name__ == "__main__":
|
||||
context = usb1.USBContext()
|
||||
|
||||
for device in context.getDeviceList(skip_on_error=True):
|
||||
if device.getVendorID() == 0xbbaa and device.getProductID()&0xFF00 == 0xdd00:
|
||||
print "found device"
|
||||
handle = device.open()
|
||||
handle.claimInterface(0)
|
||||
|
||||
try:
|
||||
handle.controlWrite(usb1.TYPE_VENDOR | usb1.RECIPIENT_DEVICE, 0xd1, 0, 0, '')
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
print "expected error, exiting cleanly"
|
||||
time.sleep(1)
|
||||
510
board/usb.h
510
board/usb.h
@@ -1,510 +0,0 @@
|
||||
// **** supporting defines ****
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__IO uint32_t HPRT;
|
||||
}
|
||||
USB_OTG_HostPortTypeDef;
|
||||
|
||||
#define USBx_HOST ((USB_OTG_HostTypeDef *)((uint32_t)USBx + USB_OTG_HOST_BASE))
|
||||
#define USBx_HOST_PORT ((USB_OTG_HostPortTypeDef *)((uint32_t)USBx + USB_OTG_HOST_PORT_BASE))
|
||||
#define USBx_DEVICE ((USB_OTG_DeviceTypeDef *)((uint32_t)USBx + USB_OTG_DEVICE_BASE))
|
||||
#define USBx_INEP(i) ((USB_OTG_INEndpointTypeDef *)((uint32_t)USBx + USB_OTG_IN_ENDPOINT_BASE + (i)*USB_OTG_EP_REG_SIZE))
|
||||
#define USBx_OUTEP(i) ((USB_OTG_OUTEndpointTypeDef *)((uint32_t)USBx + USB_OTG_OUT_ENDPOINT_BASE + (i)*USB_OTG_EP_REG_SIZE))
|
||||
#define USBx_DFIFO(i) *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_FIFO_BASE + (i) * USB_OTG_FIFO_SIZE)
|
||||
#define USBx_PCGCCTL *(__IO uint32_t *)((uint32_t)USBx + USB_OTG_PCGCCTL_BASE)
|
||||
|
||||
#define USB_REQ_GET_STATUS 0x00
|
||||
#define USB_REQ_CLEAR_FEATURE 0x01
|
||||
#define USB_REQ_SET_FEATURE 0x03
|
||||
#define USB_REQ_SET_ADDRESS 0x05
|
||||
#define USB_REQ_GET_DESCRIPTOR 0x06
|
||||
#define USB_REQ_SET_DESCRIPTOR 0x07
|
||||
#define USB_REQ_GET_CONFIGURATION 0x08
|
||||
#define USB_REQ_SET_CONFIGURATION 0x09
|
||||
#define USB_REQ_GET_INTERFACE 0x0A
|
||||
#define USB_REQ_SET_INTERFACE 0x0B
|
||||
#define USB_REQ_SYNCH_FRAME 0x0C
|
||||
|
||||
#define USB_DESC_TYPE_DEVICE 1
|
||||
#define USB_DESC_TYPE_CONFIGURATION 2
|
||||
#define USB_DESC_TYPE_STRING 3
|
||||
#define USB_DESC_TYPE_INTERFACE 4
|
||||
#define USB_DESC_TYPE_ENDPOINT 5
|
||||
#define USB_DESC_TYPE_DEVICE_QUALIFIER 6
|
||||
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7
|
||||
|
||||
#define STS_GOUT_NAK 1
|
||||
#define STS_DATA_UPDT 2
|
||||
#define STS_XFER_COMP 3
|
||||
#define STS_SETUP_COMP 4
|
||||
#define STS_SETUP_UPDT 6
|
||||
|
||||
#define USBD_FS_TRDT_VALUE 5
|
||||
|
||||
// interfaces
|
||||
void usb_cb_control_msg();
|
||||
void usb_cb_ep1_in(int len);
|
||||
void usb_cb_ep2_out(uint8_t *usbdata, int len);
|
||||
void usb_cb_ep3_out(uint8_t *usbdata, int len);
|
||||
|
||||
uint8_t device_desc[] = {
|
||||
0x12,0x01,0x00,0x01,
|
||||
0xFF,0xFF,0xFF,0x40,
|
||||
(USB_VID>>0)&0xFF,(USB_VID>>8)&0xFF,
|
||||
(USB_PID>>0)&0xFF,(USB_PID>>8)&0xFF,
|
||||
0x00,0x22,0x00,0x00,
|
||||
0x00,0x01};
|
||||
|
||||
uint8_t configuration_desc[] = {
|
||||
0x09, 0x02, 0x27, 0x00,
|
||||
0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
// interface 0
|
||||
0x09, 0x04, 0x00, 0x00,
|
||||
0x03, 0xff, 0xFF, 0xFF,
|
||||
0x00,
|
||||
// endpoint 1, read CAN
|
||||
0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00,
|
||||
// endpoint 2, AES load
|
||||
0x07, 0x05, 0x02, 0x02, 0x10, 0x00, 0x00,
|
||||
// endpoint 3, send CAN
|
||||
0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00,
|
||||
};
|
||||
|
||||
typedef union
|
||||
{
|
||||
uint16_t w;
|
||||
struct BW
|
||||
{
|
||||
uint8_t msb;
|
||||
uint8_t lsb;
|
||||
}
|
||||
bw;
|
||||
}
|
||||
uint16_t_uint8_t;
|
||||
|
||||
|
||||
typedef union _USB_Setup
|
||||
{
|
||||
uint32_t d8[2];
|
||||
|
||||
struct _SetupPkt_Struc
|
||||
{
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bRequest;
|
||||
uint16_t_uint8_t wValue;
|
||||
uint16_t_uint8_t wIndex;
|
||||
uint16_t_uint8_t wLength;
|
||||
} b;
|
||||
}
|
||||
USB_Setup_TypeDef;
|
||||
|
||||
// current packet
|
||||
USB_Setup_TypeDef setup;
|
||||
uint8_t usbdata[0x100];
|
||||
|
||||
// packet read and write
|
||||
|
||||
void *USB_ReadPacket(void *dest, uint16_t len) {
|
||||
uint32_t i=0;
|
||||
uint32_t count32b = (len + 3) / 4;
|
||||
|
||||
for ( i = 0; i < count32b; i++, dest += 4 ) {
|
||||
// packed?
|
||||
*(__attribute__((__packed__)) uint32_t *)dest = USBx_DFIFO(0);
|
||||
}
|
||||
return ((void *)dest);
|
||||
}
|
||||
|
||||
void USB_WritePacket(const uint8_t *src, uint16_t len, uint32_t ep) {
|
||||
#ifdef DEBUG
|
||||
puts("writing ");
|
||||
hexdump(src, len);
|
||||
#endif
|
||||
uint32_t count32b = 0, i = 0;
|
||||
count32b = (len + 3) / 4;
|
||||
|
||||
// bullshit
|
||||
USBx_INEP(ep)->DIEPTSIZ = (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) | (len & USB_OTG_DIEPTSIZ_XFRSIZ);
|
||||
USBx_INEP(ep)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
|
||||
|
||||
// load the FIFO
|
||||
for (i = 0; i < count32b; i++, src += 4) {
|
||||
USBx_DFIFO(ep) = *((__attribute__((__packed__)) uint32_t *)src);
|
||||
}
|
||||
}
|
||||
|
||||
void usb_reset() {
|
||||
// unmask endpoint interrupts, so many sets
|
||||
USBx_DEVICE->DAINT = 0xFFFFFFFF;
|
||||
USBx_DEVICE->DAINTMSK = 0xFFFFFFFF;
|
||||
//USBx_DEVICE->DOEPMSK = (USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_EPDM);
|
||||
//USBx_DEVICE->DIEPMSK = (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM | USB_OTG_DIEPMSK_ITTXFEMSK);
|
||||
//USBx_DEVICE->DIEPMSK = (USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM | USB_OTG_DIEPMSK_EPDM);
|
||||
|
||||
// all interrupts for debugging
|
||||
USBx_DEVICE->DIEPMSK = 0xFFFFFFFF;
|
||||
USBx_DEVICE->DOEPMSK = 0xFFFFFFFF;
|
||||
|
||||
// clear interrupts
|
||||
USBx_INEP(0)->DIEPINT = 0xFF;
|
||||
USBx_OUTEP(0)->DOEPINT = 0xFF;
|
||||
|
||||
// unset the address
|
||||
USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
|
||||
|
||||
// set up USB FIFOs
|
||||
// RX start address is fixed to 0
|
||||
USBx->GRXFSIZ = 0x40;
|
||||
|
||||
// 0x100 to offset past GRXFSIZ
|
||||
USBx->DIEPTXF0_HNPTXFSIZ = (0x40 << 16) | 0x40;
|
||||
|
||||
// EP1, massive
|
||||
USBx->DIEPTXF[0] = (0x40 << 16) | 0x80;
|
||||
|
||||
// flush TX fifo
|
||||
USBx->GRSTCTL = USB_OTG_GRSTCTL_TXFFLSH | USB_OTG_GRSTCTL_TXFNUM_4;
|
||||
while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
|
||||
// flush RX FIFO
|
||||
USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
|
||||
while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
|
||||
|
||||
// no global NAK
|
||||
USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
|
||||
|
||||
// ready to receive setup packets
|
||||
USBx_OUTEP(0)->DOEPTSIZ = USB_OTG_DOEPTSIZ_STUPCNT | (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) | (3 * 8);
|
||||
}
|
||||
|
||||
void usb_setup() {
|
||||
uint8_t resp[0x20];
|
||||
// setup packet is ready
|
||||
switch (setup.b.bRequest) {
|
||||
case USB_REQ_SET_CONFIGURATION:
|
||||
// enable other endpoints, has to be here?
|
||||
USBx_INEP(1)->DIEPCTL = (0x40 & USB_OTG_DIEPCTL_MPSIZ) | (2 << 18) | (1 << 22) |
|
||||
USB_OTG_DIEPCTL_SD0PID_SEVNFRM | USB_OTG_DIEPCTL_USBAEP;
|
||||
USBx_INEP(1)->DIEPINT = 0xFF;
|
||||
|
||||
USBx_OUTEP(2)->DOEPTSIZ = (1 << 19) | 0x10;
|
||||
USBx_OUTEP(2)->DOEPCTL = (0x10 & USB_OTG_DOEPCTL_MPSIZ) | (2 << 18) |
|
||||
USB_OTG_DOEPCTL_SD0PID_SEVNFRM | USB_OTG_DOEPCTL_USBAEP;
|
||||
USBx_OUTEP(2)->DOEPINT = 0xFF;
|
||||
|
||||
USBx_OUTEP(3)->DOEPTSIZ = (1 << 19) | 0x40;
|
||||
USBx_OUTEP(3)->DOEPCTL = (0x40 & USB_OTG_DOEPCTL_MPSIZ) | (2 << 18) |
|
||||
USB_OTG_DOEPCTL_SD0PID_SEVNFRM | USB_OTG_DOEPCTL_USBAEP;
|
||||
USBx_OUTEP(3)->DOEPINT = 0xFF;
|
||||
|
||||
// mark ready to receive
|
||||
USBx_OUTEP(2)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
|
||||
USBx_OUTEP(3)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
|
||||
|
||||
USB_WritePacket(0, 0, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
case USB_REQ_SET_ADDRESS:
|
||||
// set now?
|
||||
USBx_DEVICE->DCFG |= ((setup.b.wValue.w & 0x7f) << 4);
|
||||
|
||||
#ifdef DEBUG
|
||||
puts(" set address\n");
|
||||
#endif
|
||||
|
||||
|
||||
USB_WritePacket(0, 0, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
|
||||
break;
|
||||
case USB_REQ_GET_DESCRIPTOR:
|
||||
switch (setup.b.wValue.bw.lsb) {
|
||||
case USB_DESC_TYPE_DEVICE:
|
||||
//puts(" writing device descriptor\n");
|
||||
|
||||
// setup transfer
|
||||
USB_WritePacket(device_desc, min(sizeof(device_desc), setup.b.wLength.w), 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
|
||||
//puts("D");
|
||||
break;
|
||||
case USB_DESC_TYPE_CONFIGURATION:
|
||||
USB_WritePacket(configuration_desc, min(sizeof(configuration_desc), setup.b.wLength.w), 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
default:
|
||||
// nothing here?
|
||||
USB_WritePacket(0, 0, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case USB_REQ_GET_STATUS:
|
||||
// empty resp?
|
||||
resp[0] = 0;
|
||||
resp[1] = 0;
|
||||
USB_WritePacket((void*)&resp, 2, 0);
|
||||
USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
break;
|
||||
default:
|
||||
usb_cb_control_msg();
|
||||
}
|
||||
}
|
||||
|
||||
void usb_init() {
|
||||
// internal PHY set before reset
|
||||
USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
|
||||
|
||||
// full speed PHY, do reset and remove power down
|
||||
puth(USBx->GRSTCTL);
|
||||
puts(" resetting PHY\n");
|
||||
while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0);
|
||||
puts("AHB idle\n");
|
||||
|
||||
// reset PHY here?
|
||||
USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
|
||||
while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
|
||||
puts("reset done\n");
|
||||
|
||||
// power up the PHY
|
||||
USBx->GCCFG = USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS;
|
||||
|
||||
// be a device, slowest timings
|
||||
//USBx->GUSBCFG = USB_OTG_GUSBCFG_FDMOD | USB_OTG_GUSBCFG_PHYSEL | USB_OTG_GUSBCFG_TRDT | USB_OTG_GUSBCFG_TOCAL;
|
||||
USBx->GUSBCFG = USB_OTG_GUSBCFG_FDMOD | USB_OTG_GUSBCFG_PHYSEL;
|
||||
USBx->GUSBCFG |= (uint32_t)((USBD_FS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT);
|
||||
//USBx->GUSBCFG = USB_OTG_GUSBCFG_PHYSEL | USB_OTG_GUSBCFG_TRDT | USB_OTG_GUSBCFG_TOCAL;
|
||||
|
||||
// **** for debugging, doesn't seem to work ****
|
||||
//USBx->GUSBCFG |= USB_OTG_GUSBCFG_CTXPKT;
|
||||
|
||||
// reset PHY clock
|
||||
USBx_PCGCCTL = 0;
|
||||
|
||||
// enable the fancy OTG things
|
||||
USBx->GUSBCFG |= USB_OTG_GUSBCFG_HNPCAP | USB_OTG_GUSBCFG_SRPCAP;
|
||||
|
||||
USBx_DEVICE->DCFG = USB_OTG_DCFG_NZLSOHSK | USB_OTG_DCFG_DSPD;
|
||||
//USBx_DEVICE->DCFG = USB_OTG_DCFG_DSPD;
|
||||
|
||||
// setup USB interrupts
|
||||
// all interrupts except TXFIFO EMPTY
|
||||
//USBx->GINTMSK = 0xFFFFFFFF & ~(USB_OTG_GINTMSK_NPTXFEM | USB_OTG_GINTMSK_PTXFEM | USB_OTG_GINTSTS_SOF | USB_OTG_GINTSTS_EOPF);
|
||||
USBx->GINTMSK = 0xFFFFFFFF & ~(USB_OTG_GINTMSK_NPTXFEM | USB_OTG_GINTMSK_PTXFEM);
|
||||
|
||||
USBx->GAHBCFG = USB_OTG_GAHBCFG_GINT;
|
||||
USBx->GINTSTS = 0;
|
||||
}
|
||||
|
||||
// ***************************** USB port *****************************
|
||||
|
||||
void usb_irqhandler(void) {
|
||||
USBx->GINTMSK = 0;
|
||||
|
||||
unsigned int gintsts = USBx->GINTSTS;
|
||||
|
||||
// gintsts SUSPEND? 04008428
|
||||
#ifdef DEBUG
|
||||
unsigned int daint = USBx_DEVICE->DAINT;
|
||||
puth(gintsts);
|
||||
puts(" ep ");
|
||||
puth(daint);
|
||||
puts(" USB interrupt!\n");
|
||||
#endif
|
||||
|
||||
if (gintsts & USB_OTG_GINTSTS_ESUSP) {
|
||||
puts("ESUSP detected\n");
|
||||
}
|
||||
|
||||
if (gintsts & USB_OTG_GINTSTS_USBRST) {
|
||||
puts("USB reset\n");
|
||||
usb_reset();
|
||||
}
|
||||
|
||||
if (gintsts & USB_OTG_GINTSTS_ENUMDNE) {
|
||||
puts("enumeration done ");
|
||||
// Full speed, ENUMSPD
|
||||
puth(USBx_DEVICE->DSTS);
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
if (gintsts & USB_OTG_GINTSTS_OTGINT) {
|
||||
puts("OTG int:");
|
||||
puth(USBx->GOTGINT);
|
||||
puts("\n");
|
||||
|
||||
// getting ADTOCHG
|
||||
USBx->GOTGINT = USBx->GOTGINT;
|
||||
}
|
||||
|
||||
// RX FIFO first
|
||||
if (gintsts & USB_OTG_GINTSTS_RXFLVL) {
|
||||
// 1. Read the Receive status pop register
|
||||
volatile unsigned int rxst = USBx->GRXSTSP;
|
||||
|
||||
#ifdef DEBUG
|
||||
puts(" RX FIFO:");
|
||||
puth(rxst);
|
||||
puts(" status: ");
|
||||
puth((rxst & USB_OTG_GRXSTSP_PKTSTS) >> 17);
|
||||
puts(" len: ");
|
||||
puth((rxst & USB_OTG_GRXSTSP_BCNT) >> 4);
|
||||
puts("\n");
|
||||
#endif
|
||||
|
||||
|
||||
if (((rxst & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT) {
|
||||
int endpoint = (rxst & USB_OTG_GRXSTSP_EPNUM);
|
||||
int len = (rxst & USB_OTG_GRXSTSP_BCNT) >> 4;
|
||||
USB_ReadPacket(&usbdata, len);
|
||||
#ifdef DEBUG
|
||||
puts(" data ");
|
||||
puth(len);
|
||||
puts("\n");
|
||||
hexdump(&usbdata, len);
|
||||
#endif
|
||||
|
||||
if (endpoint == 2) {
|
||||
usb_cb_ep2_out(usbdata, len);
|
||||
}
|
||||
|
||||
if (endpoint == 3) {
|
||||
usb_cb_ep3_out(usbdata, len);
|
||||
}
|
||||
} else if (((rxst & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT) {
|
||||
USB_ReadPacket(&setup, 8);
|
||||
#ifdef DEBUG
|
||||
puts(" setup ");
|
||||
hexdump(&setup, 8);
|
||||
puts("\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (gintsts & USB_OTG_GINTSTS_HPRTINT) {
|
||||
// host
|
||||
puts("HPRT:");
|
||||
puth(USBx_HOST_PORT->HPRT);
|
||||
puts("\n");
|
||||
if (USBx_HOST_PORT->HPRT & USB_OTG_HPRT_PCDET) {
|
||||
USBx_HOST_PORT->HPRT |= USB_OTG_HPRT_PRST;
|
||||
USBx_HOST_PORT->HPRT |= USB_OTG_HPRT_PCDET;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (gintsts & USB_OTG_GINTSTS_BOUTNAKEFF) {
|
||||
// no global NAK, why is this getting set?
|
||||
#ifdef DEBUG
|
||||
puts("GLOBAL NAK\n");
|
||||
#endif
|
||||
USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK | USB_OTG_DCTL_CGINAK;
|
||||
}
|
||||
|
||||
if (gintsts & USB_OTG_GINTSTS_SRQINT) {
|
||||
// we want to do "A-device host negotiation protocol" since we are the A-device
|
||||
puts("start request\n");
|
||||
//USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
|
||||
//USBx_HOST_PORT->HPRT = USB_OTG_HPRT_PPWR | USB_OTG_HPRT_PENA;
|
||||
}
|
||||
|
||||
// out endpoint hit
|
||||
if (gintsts & USB_OTG_GINTSTS_OEPINT) {
|
||||
#ifdef DEBUG
|
||||
puts(" 0:");
|
||||
puth(USBx_OUTEP(0)->DOEPINT);
|
||||
puts(" 2:");
|
||||
puth(USBx_OUTEP(2)->DOEPINT);
|
||||
puts(" 3:");
|
||||
puth(USBx_OUTEP(3)->DOEPINT);
|
||||
puts(" ");
|
||||
puth(USBx_OUTEP(3)->DOEPCTL);
|
||||
puts(" 4:");
|
||||
puth(USBx_OUTEP(4)->DOEPINT);
|
||||
puts(" OUT ENDPOINT\n");
|
||||
#endif
|
||||
|
||||
if (USBx_OUTEP(2)->DOEPINT & USB_OTG_DOEPINT_XFRC) {
|
||||
#ifdef DEBUG
|
||||
puts(" OUT2 PACKET XFRC\n");
|
||||
#endif
|
||||
USBx_OUTEP(2)->DOEPTSIZ = (1 << 19) | 0x10;
|
||||
USBx_OUTEP(2)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
|
||||
}
|
||||
|
||||
if (USBx_OUTEP(3)->DOEPINT & USB_OTG_DOEPINT_XFRC) {
|
||||
#ifdef DEBUG
|
||||
puts(" OUT3 PACKET XFRC\n");
|
||||
#endif
|
||||
USBx_OUTEP(3)->DOEPTSIZ = (1 << 19) | 0x40;
|
||||
USBx_OUTEP(3)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
|
||||
} else if (USBx_OUTEP(3)->DOEPINT & 0x2000) {
|
||||
#ifdef DEBUG
|
||||
puts(" OUT3 PACKET WTF\n");
|
||||
#endif
|
||||
// if NAK was set trigger this, unknown interrupt
|
||||
USBx_OUTEP(3)->DOEPTSIZ = (1 << 19) | 0x40;
|
||||
USBx_OUTEP(3)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
|
||||
} else if (USBx_OUTEP(3)->DOEPINT) {
|
||||
puts("OUTEP3 error ");
|
||||
puth(USBx_OUTEP(3)->DOEPINT);
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
if (USBx_OUTEP(0)->DOEPINT & USB_OTG_DIEPINT_XFRC) {
|
||||
// ready for next packet
|
||||
USBx_OUTEP(0)->DOEPTSIZ = USB_OTG_DOEPTSIZ_STUPCNT | (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) | (1 * 8);
|
||||
}
|
||||
|
||||
// respond to setup packets
|
||||
if (USBx_OUTEP(0)->DOEPINT & USB_OTG_DOEPINT_STUP) {
|
||||
usb_setup();
|
||||
}
|
||||
|
||||
USBx_OUTEP(0)->DOEPINT = USBx_OUTEP(0)->DOEPINT;
|
||||
USBx_OUTEP(2)->DOEPINT = USBx_OUTEP(2)->DOEPINT;
|
||||
USBx_OUTEP(3)->DOEPINT = USBx_OUTEP(3)->DOEPINT;
|
||||
}
|
||||
|
||||
|
||||
// in endpoint hit
|
||||
if (gintsts & USB_OTG_GINTSTS_IEPINT) {
|
||||
#ifdef DEBUG
|
||||
puts(" ");
|
||||
puth(USBx_INEP(0)->DIEPINT);
|
||||
puts(" ");
|
||||
puth(USBx_INEP(1)->DIEPINT);
|
||||
puts(" IN ENDPOINT\n");
|
||||
#endif
|
||||
|
||||
// this happens first
|
||||
if (USBx_INEP(1)->DIEPINT & USB_OTG_DIEPINT_XFRC) {
|
||||
#ifdef DEBUG
|
||||
puts(" IN PACKET SEND\n");
|
||||
#endif
|
||||
//USBx_DEVICE->DIEPEMPMSK = ~(1 << 1);
|
||||
}
|
||||
|
||||
// *** IN token received when TxFIFO is empty
|
||||
if (USBx_INEP(1)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) {
|
||||
#ifdef DEBUG
|
||||
puts(" IN PACKET QUEUE\n");
|
||||
#endif
|
||||
// TODO: always assuming max len, can we get the length?
|
||||
usb_cb_ep1_in(0x40);
|
||||
}
|
||||
|
||||
// clear interrupts
|
||||
USBx_INEP(0)->DIEPINT = USBx_INEP(0)->DIEPINT;
|
||||
USBx_INEP(1)->DIEPINT = USBx_INEP(1)->DIEPINT;
|
||||
}
|
||||
|
||||
|
||||
// clear all interrupts
|
||||
USBx_DEVICE->DAINT = USBx_DEVICE->DAINT;
|
||||
USBx->GINTSTS = USBx->GINTSTS;
|
||||
|
||||
USBx->GINTMSK = 0xFFFFFFFF & ~(USB_OTG_GINTMSK_NPTXFEM | USB_OTG_GINTMSK_PTXFEM | USB_OTG_GINTSTS_SOF | USB_OTG_GINTSTS_EOPF);
|
||||
}
|
||||
|
||||
1
cereal/.gitignore
vendored
Normal file
1
cereal/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
gen
|
||||
4
cereal/Makefile
Normal file
4
cereal/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
-include build_from_src.mk
|
||||
|
||||
release:
|
||||
@echo "cereal: this is a release"
|
||||
38
cereal/build_from_src.mk
Normal file
38
cereal/build_from_src.mk
Normal file
@@ -0,0 +1,38 @@
|
||||
SRCS := log.capnp car.capnp
|
||||
|
||||
GENS := gen/c/car.capnp.c gen/c/log.capnp.c gen/c/c++.capnp.h gen/c/java.capnp.h \
|
||||
gen/cpp/car.capnp.c++ gen/cpp/log.capnp.c++
|
||||
|
||||
# Dont build java on the phone...
|
||||
UNAME_M := $(shell uname -m)
|
||||
ifeq ($(UNAME_M),x86_64)
|
||||
GENS += gen/java/Car.java gen/java/Log.java
|
||||
endif
|
||||
|
||||
.PHONY: all
|
||||
all: $(GENS)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf gen
|
||||
|
||||
gen/c/%.capnp.c: %.capnp
|
||||
@echo "[ CAPNPC C ] $@"
|
||||
mkdir -p gen/c/
|
||||
capnpc '$<' -o c:gen/c/
|
||||
|
||||
gen/cpp/%.capnp.c++: %.capnp
|
||||
@echo "[ CAPNPC C++ ] $@"
|
||||
mkdir -p gen/cpp/
|
||||
capnpc '$<' -o c++:gen/cpp/
|
||||
|
||||
gen/java/Car.java gen/java/Log.java: $(SRCS)
|
||||
@echo "[ CAPNPC java ] $@"
|
||||
mkdir -p gen/java/
|
||||
capnpc $^ -o java:gen/java
|
||||
|
||||
# c-capnproto needs some empty headers
|
||||
gen/c/c++.capnp.h gen/c/java.capnp.h:
|
||||
mkdir -p gen/c/
|
||||
touch '$@'
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
using Cxx = import "c++.capnp";
|
||||
$Cxx.namespace("cereal");
|
||||
|
||||
using Java = import "java.capnp";
|
||||
$Java.package("ai.comma.openpilot.cereal");
|
||||
$Java.outerClassname("Car");
|
||||
|
||||
@0x8e2af1e708af8b8d;
|
||||
|
||||
# ******* main car state @ 100hz *******
|
||||
@@ -170,3 +174,29 @@ struct CarControl {
|
||||
}
|
||||
}
|
||||
|
||||
# ****** car param ******
|
||||
|
||||
struct CarParams {
|
||||
carName @0: Text;
|
||||
radarName @1: Text;
|
||||
carFingerprint @11: Text;
|
||||
|
||||
enableSteer @2: Bool;
|
||||
enableGas @3: Bool;
|
||||
enableBrake @4: Bool;
|
||||
enableCruise @5: Bool;
|
||||
|
||||
# things about the car in the manual
|
||||
wheelBase @6: Float32; # in meters
|
||||
steerRatio @7: Float32;
|
||||
|
||||
# things we can derive
|
||||
slipFactor @8: Float32;
|
||||
|
||||
# Kp and Ki for the lateral control
|
||||
steerKp @9: Float32;
|
||||
steerKi @10: Float32;
|
||||
|
||||
# TODO: Kp and Ki for long control, perhaps not needed?
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,667 +0,0 @@
|
||||
#ifndef CAPN_F3B1F17E25A4285B
|
||||
#define CAPN_F3B1F17E25A4285B
|
||||
/* AUTO GENERATED - DO NOT EDIT */
|
||||
#include <capnp_c.h>
|
||||
|
||||
#if CAPN_VERSION != 1
|
||||
#error "version mismatch between capnp_c.h and generated code"
|
||||
#endif
|
||||
|
||||
#include "c++.capnp.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct cereal_InitData;
|
||||
struct cereal_FrameData;
|
||||
struct cereal_GPSNMEAData;
|
||||
struct cereal_SensorEventData;
|
||||
struct cereal_SensorEventData_SensorVec;
|
||||
struct cereal_CanData;
|
||||
struct cereal_ThermalData;
|
||||
struct cereal_HealthData;
|
||||
struct cereal_LiveUI;
|
||||
struct cereal_Live20Data;
|
||||
struct cereal_Live20Data_LeadData;
|
||||
struct cereal_LiveCalibrationData;
|
||||
struct cereal_LiveTracks;
|
||||
struct cereal_Live100Data;
|
||||
struct cereal_LiveEventData;
|
||||
struct cereal_ModelData;
|
||||
struct cereal_ModelData_PathData;
|
||||
struct cereal_ModelData_LeadData;
|
||||
struct cereal_ModelData_ModelSettings;
|
||||
struct cereal_CalibrationFeatures;
|
||||
struct cereal_EncodeIndex;
|
||||
struct cereal_AndroidLogEntry;
|
||||
struct cereal_LogRotate;
|
||||
struct cereal_Event;
|
||||
|
||||
typedef struct {capn_ptr p;} cereal_InitData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_FrameData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_GPSNMEAData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_SensorEventData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_SensorEventData_SensorVec_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_CanData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_ThermalData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_HealthData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_LiveUI_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_Live20Data_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_Live20Data_LeadData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_LiveCalibrationData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_LiveTracks_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_Live100Data_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_LiveEventData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_ModelData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_ModelData_PathData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_ModelData_LeadData_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_ModelData_ModelSettings_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_CalibrationFeatures_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_EncodeIndex_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_AndroidLogEntry_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_LogRotate_ptr;
|
||||
typedef struct {capn_ptr p;} cereal_Event_ptr;
|
||||
|
||||
typedef struct {capn_ptr p;} cereal_InitData_list;
|
||||
typedef struct {capn_ptr p;} cereal_FrameData_list;
|
||||
typedef struct {capn_ptr p;} cereal_GPSNMEAData_list;
|
||||
typedef struct {capn_ptr p;} cereal_SensorEventData_list;
|
||||
typedef struct {capn_ptr p;} cereal_SensorEventData_SensorVec_list;
|
||||
typedef struct {capn_ptr p;} cereal_CanData_list;
|
||||
typedef struct {capn_ptr p;} cereal_ThermalData_list;
|
||||
typedef struct {capn_ptr p;} cereal_HealthData_list;
|
||||
typedef struct {capn_ptr p;} cereal_LiveUI_list;
|
||||
typedef struct {capn_ptr p;} cereal_Live20Data_list;
|
||||
typedef struct {capn_ptr p;} cereal_Live20Data_LeadData_list;
|
||||
typedef struct {capn_ptr p;} cereal_LiveCalibrationData_list;
|
||||
typedef struct {capn_ptr p;} cereal_LiveTracks_list;
|
||||
typedef struct {capn_ptr p;} cereal_Live100Data_list;
|
||||
typedef struct {capn_ptr p;} cereal_LiveEventData_list;
|
||||
typedef struct {capn_ptr p;} cereal_ModelData_list;
|
||||
typedef struct {capn_ptr p;} cereal_ModelData_PathData_list;
|
||||
typedef struct {capn_ptr p;} cereal_ModelData_LeadData_list;
|
||||
typedef struct {capn_ptr p;} cereal_ModelData_ModelSettings_list;
|
||||
typedef struct {capn_ptr p;} cereal_CalibrationFeatures_list;
|
||||
typedef struct {capn_ptr p;} cereal_EncodeIndex_list;
|
||||
typedef struct {capn_ptr p;} cereal_AndroidLogEntry_list;
|
||||
typedef struct {capn_ptr p;} cereal_LogRotate_list;
|
||||
typedef struct {capn_ptr p;} cereal_Event_list;
|
||||
|
||||
enum cereal_EncodeIndex_Type {
|
||||
cereal_EncodeIndex_Type_bigBoxLossless = 0,
|
||||
cereal_EncodeIndex_Type_fullHEVC = 1,
|
||||
cereal_EncodeIndex_Type_bigBoxHEVC = 2
|
||||
};
|
||||
extern int32_t cereal_logVersion;
|
||||
|
||||
struct cereal_InitData {
|
||||
capn_ptr kernelArgs;
|
||||
capn_text gctx;
|
||||
capn_text dongleId;
|
||||
};
|
||||
|
||||
static const size_t cereal_InitData_word_count = 0;
|
||||
|
||||
static const size_t cereal_InitData_pointer_count = 3;
|
||||
|
||||
static const size_t cereal_InitData_struct_bytes_count = 24;
|
||||
|
||||
struct cereal_FrameData {
|
||||
uint32_t frameId;
|
||||
uint32_t encodeId;
|
||||
uint64_t timestampEof;
|
||||
int32_t frameLength;
|
||||
int32_t integLines;
|
||||
int32_t globalGain;
|
||||
capn_data image;
|
||||
};
|
||||
|
||||
static const size_t cereal_FrameData_word_count = 4;
|
||||
|
||||
static const size_t cereal_FrameData_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_FrameData_struct_bytes_count = 40;
|
||||
|
||||
struct cereal_GPSNMEAData {
|
||||
int64_t timestamp;
|
||||
uint64_t localWallTime;
|
||||
capn_text nmea;
|
||||
};
|
||||
|
||||
static const size_t cereal_GPSNMEAData_word_count = 2;
|
||||
|
||||
static const size_t cereal_GPSNMEAData_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_GPSNMEAData_struct_bytes_count = 24;
|
||||
enum cereal_SensorEventData_which {
|
||||
cereal_SensorEventData_acceleration = 0,
|
||||
cereal_SensorEventData_magnetic = 1,
|
||||
cereal_SensorEventData_orientation = 2,
|
||||
cereal_SensorEventData_gyro = 3
|
||||
};
|
||||
|
||||
struct cereal_SensorEventData {
|
||||
int32_t version;
|
||||
int32_t sensor;
|
||||
int32_t type;
|
||||
int64_t timestamp;
|
||||
enum cereal_SensorEventData_which which;
|
||||
union {
|
||||
cereal_SensorEventData_SensorVec_ptr acceleration;
|
||||
cereal_SensorEventData_SensorVec_ptr magnetic;
|
||||
cereal_SensorEventData_SensorVec_ptr orientation;
|
||||
cereal_SensorEventData_SensorVec_ptr gyro;
|
||||
};
|
||||
};
|
||||
|
||||
static const size_t cereal_SensorEventData_word_count = 3;
|
||||
|
||||
static const size_t cereal_SensorEventData_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_SensorEventData_struct_bytes_count = 32;
|
||||
|
||||
struct cereal_SensorEventData_SensorVec {
|
||||
capn_list32 v;
|
||||
int8_t status;
|
||||
};
|
||||
|
||||
static const size_t cereal_SensorEventData_SensorVec_word_count = 1;
|
||||
|
||||
static const size_t cereal_SensorEventData_SensorVec_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_SensorEventData_SensorVec_struct_bytes_count = 16;
|
||||
|
||||
struct cereal_CanData {
|
||||
uint32_t address;
|
||||
uint16_t busTime;
|
||||
capn_data dat;
|
||||
int8_t src;
|
||||
};
|
||||
|
||||
static const size_t cereal_CanData_word_count = 1;
|
||||
|
||||
static const size_t cereal_CanData_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_CanData_struct_bytes_count = 16;
|
||||
|
||||
struct cereal_ThermalData {
|
||||
uint16_t cpu0;
|
||||
uint16_t cpu1;
|
||||
uint16_t cpu2;
|
||||
uint16_t cpu3;
|
||||
uint16_t mem;
|
||||
uint16_t gpu;
|
||||
uint32_t bat;
|
||||
};
|
||||
|
||||
static const size_t cereal_ThermalData_word_count = 2;
|
||||
|
||||
static const size_t cereal_ThermalData_pointer_count = 0;
|
||||
|
||||
static const size_t cereal_ThermalData_struct_bytes_count = 16;
|
||||
|
||||
struct cereal_HealthData {
|
||||
uint32_t voltage;
|
||||
uint32_t current;
|
||||
unsigned started : 1;
|
||||
unsigned controlsAllowed : 1;
|
||||
unsigned gasInterceptorDetected : 1;
|
||||
};
|
||||
|
||||
static const size_t cereal_HealthData_word_count = 2;
|
||||
|
||||
static const size_t cereal_HealthData_pointer_count = 0;
|
||||
|
||||
static const size_t cereal_HealthData_struct_bytes_count = 16;
|
||||
|
||||
struct cereal_LiveUI {
|
||||
unsigned rearViewCam : 1;
|
||||
capn_text alertText1;
|
||||
capn_text alertText2;
|
||||
float awarenessStatus;
|
||||
};
|
||||
|
||||
static const size_t cereal_LiveUI_word_count = 1;
|
||||
|
||||
static const size_t cereal_LiveUI_pointer_count = 2;
|
||||
|
||||
static const size_t cereal_LiveUI_struct_bytes_count = 24;
|
||||
|
||||
struct cereal_Live20Data {
|
||||
capn_list64 canMonoTimes;
|
||||
uint64_t mdMonoTime;
|
||||
uint64_t ftMonoTime;
|
||||
capn_list32 warpMatrix;
|
||||
float angleOffset;
|
||||
int8_t calStatus;
|
||||
int32_t calCycle;
|
||||
int8_t calPerc;
|
||||
cereal_Live20Data_LeadData_ptr leadOne;
|
||||
cereal_Live20Data_LeadData_ptr leadTwo;
|
||||
float cumLagMs;
|
||||
};
|
||||
|
||||
static const size_t cereal_Live20Data_word_count = 4;
|
||||
|
||||
static const size_t cereal_Live20Data_pointer_count = 4;
|
||||
|
||||
static const size_t cereal_Live20Data_struct_bytes_count = 64;
|
||||
|
||||
struct cereal_Live20Data_LeadData {
|
||||
float dRel;
|
||||
float yRel;
|
||||
float vRel;
|
||||
float aRel;
|
||||
float vLead;
|
||||
float aLead;
|
||||
float dPath;
|
||||
float vLat;
|
||||
float vLeadK;
|
||||
float aLeadK;
|
||||
unsigned fcw : 1;
|
||||
unsigned status : 1;
|
||||
};
|
||||
|
||||
static const size_t cereal_Live20Data_LeadData_word_count = 6;
|
||||
|
||||
static const size_t cereal_Live20Data_LeadData_pointer_count = 0;
|
||||
|
||||
static const size_t cereal_Live20Data_LeadData_struct_bytes_count = 48;
|
||||
|
||||
struct cereal_LiveCalibrationData {
|
||||
capn_list32 warpMatrix;
|
||||
int8_t calStatus;
|
||||
int32_t calCycle;
|
||||
int8_t calPerc;
|
||||
};
|
||||
|
||||
static const size_t cereal_LiveCalibrationData_word_count = 1;
|
||||
|
||||
static const size_t cereal_LiveCalibrationData_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_LiveCalibrationData_struct_bytes_count = 16;
|
||||
|
||||
struct cereal_LiveTracks {
|
||||
int32_t trackId;
|
||||
float dRel;
|
||||
float yRel;
|
||||
float vRel;
|
||||
float aRel;
|
||||
float timeStamp;
|
||||
float status;
|
||||
float currentTime;
|
||||
unsigned stationary : 1;
|
||||
unsigned oncoming : 1;
|
||||
};
|
||||
|
||||
static const size_t cereal_LiveTracks_word_count = 5;
|
||||
|
||||
static const size_t cereal_LiveTracks_pointer_count = 0;
|
||||
|
||||
static const size_t cereal_LiveTracks_struct_bytes_count = 40;
|
||||
|
||||
struct cereal_Live100Data {
|
||||
uint64_t canMonoTime;
|
||||
capn_list64 canMonoTimes;
|
||||
uint64_t l20MonoTime;
|
||||
uint64_t mdMonoTime;
|
||||
float vEgo;
|
||||
float aEgo;
|
||||
float vPid;
|
||||
float vTargetLead;
|
||||
float upAccelCmd;
|
||||
float uiAccelCmd;
|
||||
float yActual;
|
||||
float yDes;
|
||||
float upSteer;
|
||||
float uiSteer;
|
||||
float aTargetMin;
|
||||
float aTargetMax;
|
||||
float jerkFactor;
|
||||
float angleSteers;
|
||||
int32_t hudLead;
|
||||
float cumLagMs;
|
||||
unsigned enabled : 1;
|
||||
unsigned steerOverride : 1;
|
||||
float vCruise;
|
||||
unsigned rearViewCam : 1;
|
||||
capn_text alertText1;
|
||||
capn_text alertText2;
|
||||
float awarenessStatus;
|
||||
};
|
||||
|
||||
static const size_t cereal_Live100Data_word_count = 13;
|
||||
|
||||
static const size_t cereal_Live100Data_pointer_count = 3;
|
||||
|
||||
static const size_t cereal_Live100Data_struct_bytes_count = 128;
|
||||
|
||||
struct cereal_LiveEventData {
|
||||
capn_text name;
|
||||
int32_t value;
|
||||
};
|
||||
|
||||
static const size_t cereal_LiveEventData_word_count = 1;
|
||||
|
||||
static const size_t cereal_LiveEventData_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_LiveEventData_struct_bytes_count = 16;
|
||||
|
||||
struct cereal_ModelData {
|
||||
uint32_t frameId;
|
||||
cereal_ModelData_PathData_ptr path;
|
||||
cereal_ModelData_PathData_ptr leftLane;
|
||||
cereal_ModelData_PathData_ptr rightLane;
|
||||
cereal_ModelData_LeadData_ptr lead;
|
||||
cereal_ModelData_ModelSettings_ptr settings;
|
||||
};
|
||||
|
||||
static const size_t cereal_ModelData_word_count = 1;
|
||||
|
||||
static const size_t cereal_ModelData_pointer_count = 5;
|
||||
|
||||
static const size_t cereal_ModelData_struct_bytes_count = 48;
|
||||
|
||||
struct cereal_ModelData_PathData {
|
||||
capn_list32 points;
|
||||
float prob;
|
||||
float std;
|
||||
};
|
||||
|
||||
static const size_t cereal_ModelData_PathData_word_count = 1;
|
||||
|
||||
static const size_t cereal_ModelData_PathData_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_ModelData_PathData_struct_bytes_count = 16;
|
||||
|
||||
struct cereal_ModelData_LeadData {
|
||||
float dist;
|
||||
float prob;
|
||||
float std;
|
||||
};
|
||||
|
||||
static const size_t cereal_ModelData_LeadData_word_count = 2;
|
||||
|
||||
static const size_t cereal_ModelData_LeadData_pointer_count = 0;
|
||||
|
||||
static const size_t cereal_ModelData_LeadData_struct_bytes_count = 16;
|
||||
|
||||
struct cereal_ModelData_ModelSettings {
|
||||
uint16_t bigBoxX;
|
||||
uint16_t bigBoxY;
|
||||
uint16_t bigBoxWidth;
|
||||
uint16_t bigBoxHeight;
|
||||
capn_list32 boxProjection;
|
||||
capn_list32 yuvCorrection;
|
||||
};
|
||||
|
||||
static const size_t cereal_ModelData_ModelSettings_word_count = 1;
|
||||
|
||||
static const size_t cereal_ModelData_ModelSettings_pointer_count = 2;
|
||||
|
||||
static const size_t cereal_ModelData_ModelSettings_struct_bytes_count = 24;
|
||||
|
||||
struct cereal_CalibrationFeatures {
|
||||
uint32_t frameId;
|
||||
capn_list32 p0;
|
||||
capn_list32 p1;
|
||||
capn_list8 status;
|
||||
};
|
||||
|
||||
static const size_t cereal_CalibrationFeatures_word_count = 1;
|
||||
|
||||
static const size_t cereal_CalibrationFeatures_pointer_count = 3;
|
||||
|
||||
static const size_t cereal_CalibrationFeatures_struct_bytes_count = 32;
|
||||
|
||||
struct cereal_EncodeIndex {
|
||||
uint32_t frameId;
|
||||
enum cereal_EncodeIndex_Type type;
|
||||
uint32_t encodeId;
|
||||
int32_t segmentNum;
|
||||
uint32_t segmentId;
|
||||
};
|
||||
|
||||
static const size_t cereal_EncodeIndex_word_count = 3;
|
||||
|
||||
static const size_t cereal_EncodeIndex_pointer_count = 0;
|
||||
|
||||
static const size_t cereal_EncodeIndex_struct_bytes_count = 24;
|
||||
|
||||
struct cereal_AndroidLogEntry {
|
||||
uint8_t id;
|
||||
uint64_t ts;
|
||||
uint8_t priority;
|
||||
int32_t pid;
|
||||
int32_t tid;
|
||||
capn_text tag;
|
||||
capn_text message;
|
||||
};
|
||||
|
||||
static const size_t cereal_AndroidLogEntry_word_count = 3;
|
||||
|
||||
static const size_t cereal_AndroidLogEntry_pointer_count = 2;
|
||||
|
||||
static const size_t cereal_AndroidLogEntry_struct_bytes_count = 40;
|
||||
|
||||
struct cereal_LogRotate {
|
||||
int32_t segmentNum;
|
||||
capn_text path;
|
||||
};
|
||||
|
||||
static const size_t cereal_LogRotate_word_count = 1;
|
||||
|
||||
static const size_t cereal_LogRotate_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_LogRotate_struct_bytes_count = 16;
|
||||
enum cereal_Event_which {
|
||||
cereal_Event_initData = 0,
|
||||
cereal_Event_frame = 1,
|
||||
cereal_Event_gpsNMEA = 2,
|
||||
cereal_Event_sensorEventDEPRECATED = 3,
|
||||
cereal_Event_can = 4,
|
||||
cereal_Event_thermal = 5,
|
||||
cereal_Event_live100 = 6,
|
||||
cereal_Event_liveEventDEPRECATED = 7,
|
||||
cereal_Event_model = 8,
|
||||
cereal_Event_features = 9,
|
||||
cereal_Event_sensorEvents = 10,
|
||||
cereal_Event_health = 11,
|
||||
cereal_Event_live20 = 12,
|
||||
cereal_Event_liveUIDEPRECATED = 13,
|
||||
cereal_Event_encodeIdx = 14,
|
||||
cereal_Event_liveTracks = 15,
|
||||
cereal_Event_sendcan = 16,
|
||||
cereal_Event_logMessage = 17,
|
||||
cereal_Event_liveCalibration = 18,
|
||||
cereal_Event_androidLogEntry = 19
|
||||
};
|
||||
|
||||
struct cereal_Event {
|
||||
uint64_t logMonoTime;
|
||||
enum cereal_Event_which which;
|
||||
union {
|
||||
cereal_InitData_ptr initData;
|
||||
cereal_FrameData_ptr frame;
|
||||
cereal_GPSNMEAData_ptr gpsNMEA;
|
||||
cereal_SensorEventData_ptr sensorEventDEPRECATED;
|
||||
cereal_CanData_list can;
|
||||
cereal_ThermalData_ptr thermal;
|
||||
cereal_Live100Data_ptr live100;
|
||||
cereal_LiveEventData_list liveEventDEPRECATED;
|
||||
cereal_ModelData_ptr model;
|
||||
cereal_CalibrationFeatures_ptr features;
|
||||
cereal_SensorEventData_list sensorEvents;
|
||||
cereal_HealthData_ptr health;
|
||||
cereal_Live20Data_ptr live20;
|
||||
cereal_LiveUI_ptr liveUIDEPRECATED;
|
||||
cereal_EncodeIndex_ptr encodeIdx;
|
||||
cereal_LiveTracks_list liveTracks;
|
||||
cereal_CanData_list sendcan;
|
||||
capn_text logMessage;
|
||||
cereal_LiveCalibrationData_ptr liveCalibration;
|
||||
cereal_AndroidLogEntry_ptr androidLogEntry;
|
||||
};
|
||||
};
|
||||
|
||||
static const size_t cereal_Event_word_count = 2;
|
||||
|
||||
static const size_t cereal_Event_pointer_count = 1;
|
||||
|
||||
static const size_t cereal_Event_struct_bytes_count = 24;
|
||||
|
||||
cereal_InitData_ptr cereal_new_InitData(struct capn_segment*);
|
||||
cereal_FrameData_ptr cereal_new_FrameData(struct capn_segment*);
|
||||
cereal_GPSNMEAData_ptr cereal_new_GPSNMEAData(struct capn_segment*);
|
||||
cereal_SensorEventData_ptr cereal_new_SensorEventData(struct capn_segment*);
|
||||
cereal_SensorEventData_SensorVec_ptr cereal_new_SensorEventData_SensorVec(struct capn_segment*);
|
||||
cereal_CanData_ptr cereal_new_CanData(struct capn_segment*);
|
||||
cereal_ThermalData_ptr cereal_new_ThermalData(struct capn_segment*);
|
||||
cereal_HealthData_ptr cereal_new_HealthData(struct capn_segment*);
|
||||
cereal_LiveUI_ptr cereal_new_LiveUI(struct capn_segment*);
|
||||
cereal_Live20Data_ptr cereal_new_Live20Data(struct capn_segment*);
|
||||
cereal_Live20Data_LeadData_ptr cereal_new_Live20Data_LeadData(struct capn_segment*);
|
||||
cereal_LiveCalibrationData_ptr cereal_new_LiveCalibrationData(struct capn_segment*);
|
||||
cereal_LiveTracks_ptr cereal_new_LiveTracks(struct capn_segment*);
|
||||
cereal_Live100Data_ptr cereal_new_Live100Data(struct capn_segment*);
|
||||
cereal_LiveEventData_ptr cereal_new_LiveEventData(struct capn_segment*);
|
||||
cereal_ModelData_ptr cereal_new_ModelData(struct capn_segment*);
|
||||
cereal_ModelData_PathData_ptr cereal_new_ModelData_PathData(struct capn_segment*);
|
||||
cereal_ModelData_LeadData_ptr cereal_new_ModelData_LeadData(struct capn_segment*);
|
||||
cereal_ModelData_ModelSettings_ptr cereal_new_ModelData_ModelSettings(struct capn_segment*);
|
||||
cereal_CalibrationFeatures_ptr cereal_new_CalibrationFeatures(struct capn_segment*);
|
||||
cereal_EncodeIndex_ptr cereal_new_EncodeIndex(struct capn_segment*);
|
||||
cereal_AndroidLogEntry_ptr cereal_new_AndroidLogEntry(struct capn_segment*);
|
||||
cereal_LogRotate_ptr cereal_new_LogRotate(struct capn_segment*);
|
||||
cereal_Event_ptr cereal_new_Event(struct capn_segment*);
|
||||
|
||||
cereal_InitData_list cereal_new_InitData_list(struct capn_segment*, int len);
|
||||
cereal_FrameData_list cereal_new_FrameData_list(struct capn_segment*, int len);
|
||||
cereal_GPSNMEAData_list cereal_new_GPSNMEAData_list(struct capn_segment*, int len);
|
||||
cereal_SensorEventData_list cereal_new_SensorEventData_list(struct capn_segment*, int len);
|
||||
cereal_SensorEventData_SensorVec_list cereal_new_SensorEventData_SensorVec_list(struct capn_segment*, int len);
|
||||
cereal_CanData_list cereal_new_CanData_list(struct capn_segment*, int len);
|
||||
cereal_ThermalData_list cereal_new_ThermalData_list(struct capn_segment*, int len);
|
||||
cereal_HealthData_list cereal_new_HealthData_list(struct capn_segment*, int len);
|
||||
cereal_LiveUI_list cereal_new_LiveUI_list(struct capn_segment*, int len);
|
||||
cereal_Live20Data_list cereal_new_Live20Data_list(struct capn_segment*, int len);
|
||||
cereal_Live20Data_LeadData_list cereal_new_Live20Data_LeadData_list(struct capn_segment*, int len);
|
||||
cereal_LiveCalibrationData_list cereal_new_LiveCalibrationData_list(struct capn_segment*, int len);
|
||||
cereal_LiveTracks_list cereal_new_LiveTracks_list(struct capn_segment*, int len);
|
||||
cereal_Live100Data_list cereal_new_Live100Data_list(struct capn_segment*, int len);
|
||||
cereal_LiveEventData_list cereal_new_LiveEventData_list(struct capn_segment*, int len);
|
||||
cereal_ModelData_list cereal_new_ModelData_list(struct capn_segment*, int len);
|
||||
cereal_ModelData_PathData_list cereal_new_ModelData_PathData_list(struct capn_segment*, int len);
|
||||
cereal_ModelData_LeadData_list cereal_new_ModelData_LeadData_list(struct capn_segment*, int len);
|
||||
cereal_ModelData_ModelSettings_list cereal_new_ModelData_ModelSettings_list(struct capn_segment*, int len);
|
||||
cereal_CalibrationFeatures_list cereal_new_CalibrationFeatures_list(struct capn_segment*, int len);
|
||||
cereal_EncodeIndex_list cereal_new_EncodeIndex_list(struct capn_segment*, int len);
|
||||
cereal_AndroidLogEntry_list cereal_new_AndroidLogEntry_list(struct capn_segment*, int len);
|
||||
cereal_LogRotate_list cereal_new_LogRotate_list(struct capn_segment*, int len);
|
||||
cereal_Event_list cereal_new_Event_list(struct capn_segment*, int len);
|
||||
|
||||
void cereal_read_InitData(struct cereal_InitData*, cereal_InitData_ptr);
|
||||
void cereal_read_FrameData(struct cereal_FrameData*, cereal_FrameData_ptr);
|
||||
void cereal_read_GPSNMEAData(struct cereal_GPSNMEAData*, cereal_GPSNMEAData_ptr);
|
||||
void cereal_read_SensorEventData(struct cereal_SensorEventData*, cereal_SensorEventData_ptr);
|
||||
void cereal_read_SensorEventData_SensorVec(struct cereal_SensorEventData_SensorVec*, cereal_SensorEventData_SensorVec_ptr);
|
||||
void cereal_read_CanData(struct cereal_CanData*, cereal_CanData_ptr);
|
||||
void cereal_read_ThermalData(struct cereal_ThermalData*, cereal_ThermalData_ptr);
|
||||
void cereal_read_HealthData(struct cereal_HealthData*, cereal_HealthData_ptr);
|
||||
void cereal_read_LiveUI(struct cereal_LiveUI*, cereal_LiveUI_ptr);
|
||||
void cereal_read_Live20Data(struct cereal_Live20Data*, cereal_Live20Data_ptr);
|
||||
void cereal_read_Live20Data_LeadData(struct cereal_Live20Data_LeadData*, cereal_Live20Data_LeadData_ptr);
|
||||
void cereal_read_LiveCalibrationData(struct cereal_LiveCalibrationData*, cereal_LiveCalibrationData_ptr);
|
||||
void cereal_read_LiveTracks(struct cereal_LiveTracks*, cereal_LiveTracks_ptr);
|
||||
void cereal_read_Live100Data(struct cereal_Live100Data*, cereal_Live100Data_ptr);
|
||||
void cereal_read_LiveEventData(struct cereal_LiveEventData*, cereal_LiveEventData_ptr);
|
||||
void cereal_read_ModelData(struct cereal_ModelData*, cereal_ModelData_ptr);
|
||||
void cereal_read_ModelData_PathData(struct cereal_ModelData_PathData*, cereal_ModelData_PathData_ptr);
|
||||
void cereal_read_ModelData_LeadData(struct cereal_ModelData_LeadData*, cereal_ModelData_LeadData_ptr);
|
||||
void cereal_read_ModelData_ModelSettings(struct cereal_ModelData_ModelSettings*, cereal_ModelData_ModelSettings_ptr);
|
||||
void cereal_read_CalibrationFeatures(struct cereal_CalibrationFeatures*, cereal_CalibrationFeatures_ptr);
|
||||
void cereal_read_EncodeIndex(struct cereal_EncodeIndex*, cereal_EncodeIndex_ptr);
|
||||
void cereal_read_AndroidLogEntry(struct cereal_AndroidLogEntry*, cereal_AndroidLogEntry_ptr);
|
||||
void cereal_read_LogRotate(struct cereal_LogRotate*, cereal_LogRotate_ptr);
|
||||
void cereal_read_Event(struct cereal_Event*, cereal_Event_ptr);
|
||||
|
||||
void cereal_write_InitData(const struct cereal_InitData*, cereal_InitData_ptr);
|
||||
void cereal_write_FrameData(const struct cereal_FrameData*, cereal_FrameData_ptr);
|
||||
void cereal_write_GPSNMEAData(const struct cereal_GPSNMEAData*, cereal_GPSNMEAData_ptr);
|
||||
void cereal_write_SensorEventData(const struct cereal_SensorEventData*, cereal_SensorEventData_ptr);
|
||||
void cereal_write_SensorEventData_SensorVec(const struct cereal_SensorEventData_SensorVec*, cereal_SensorEventData_SensorVec_ptr);
|
||||
void cereal_write_CanData(const struct cereal_CanData*, cereal_CanData_ptr);
|
||||
void cereal_write_ThermalData(const struct cereal_ThermalData*, cereal_ThermalData_ptr);
|
||||
void cereal_write_HealthData(const struct cereal_HealthData*, cereal_HealthData_ptr);
|
||||
void cereal_write_LiveUI(const struct cereal_LiveUI*, cereal_LiveUI_ptr);
|
||||
void cereal_write_Live20Data(const struct cereal_Live20Data*, cereal_Live20Data_ptr);
|
||||
void cereal_write_Live20Data_LeadData(const struct cereal_Live20Data_LeadData*, cereal_Live20Data_LeadData_ptr);
|
||||
void cereal_write_LiveCalibrationData(const struct cereal_LiveCalibrationData*, cereal_LiveCalibrationData_ptr);
|
||||
void cereal_write_LiveTracks(const struct cereal_LiveTracks*, cereal_LiveTracks_ptr);
|
||||
void cereal_write_Live100Data(const struct cereal_Live100Data*, cereal_Live100Data_ptr);
|
||||
void cereal_write_LiveEventData(const struct cereal_LiveEventData*, cereal_LiveEventData_ptr);
|
||||
void cereal_write_ModelData(const struct cereal_ModelData*, cereal_ModelData_ptr);
|
||||
void cereal_write_ModelData_PathData(const struct cereal_ModelData_PathData*, cereal_ModelData_PathData_ptr);
|
||||
void cereal_write_ModelData_LeadData(const struct cereal_ModelData_LeadData*, cereal_ModelData_LeadData_ptr);
|
||||
void cereal_write_ModelData_ModelSettings(const struct cereal_ModelData_ModelSettings*, cereal_ModelData_ModelSettings_ptr);
|
||||
void cereal_write_CalibrationFeatures(const struct cereal_CalibrationFeatures*, cereal_CalibrationFeatures_ptr);
|
||||
void cereal_write_EncodeIndex(const struct cereal_EncodeIndex*, cereal_EncodeIndex_ptr);
|
||||
void cereal_write_AndroidLogEntry(const struct cereal_AndroidLogEntry*, cereal_AndroidLogEntry_ptr);
|
||||
void cereal_write_LogRotate(const struct cereal_LogRotate*, cereal_LogRotate_ptr);
|
||||
void cereal_write_Event(const struct cereal_Event*, cereal_Event_ptr);
|
||||
|
||||
void cereal_get_InitData(struct cereal_InitData*, cereal_InitData_list, int i);
|
||||
void cereal_get_FrameData(struct cereal_FrameData*, cereal_FrameData_list, int i);
|
||||
void cereal_get_GPSNMEAData(struct cereal_GPSNMEAData*, cereal_GPSNMEAData_list, int i);
|
||||
void cereal_get_SensorEventData(struct cereal_SensorEventData*, cereal_SensorEventData_list, int i);
|
||||
void cereal_get_SensorEventData_SensorVec(struct cereal_SensorEventData_SensorVec*, cereal_SensorEventData_SensorVec_list, int i);
|
||||
void cereal_get_CanData(struct cereal_CanData*, cereal_CanData_list, int i);
|
||||
void cereal_get_ThermalData(struct cereal_ThermalData*, cereal_ThermalData_list, int i);
|
||||
void cereal_get_HealthData(struct cereal_HealthData*, cereal_HealthData_list, int i);
|
||||
void cereal_get_LiveUI(struct cereal_LiveUI*, cereal_LiveUI_list, int i);
|
||||
void cereal_get_Live20Data(struct cereal_Live20Data*, cereal_Live20Data_list, int i);
|
||||
void cereal_get_Live20Data_LeadData(struct cereal_Live20Data_LeadData*, cereal_Live20Data_LeadData_list, int i);
|
||||
void cereal_get_LiveCalibrationData(struct cereal_LiveCalibrationData*, cereal_LiveCalibrationData_list, int i);
|
||||
void cereal_get_LiveTracks(struct cereal_LiveTracks*, cereal_LiveTracks_list, int i);
|
||||
void cereal_get_Live100Data(struct cereal_Live100Data*, cereal_Live100Data_list, int i);
|
||||
void cereal_get_LiveEventData(struct cereal_LiveEventData*, cereal_LiveEventData_list, int i);
|
||||
void cereal_get_ModelData(struct cereal_ModelData*, cereal_ModelData_list, int i);
|
||||
void cereal_get_ModelData_PathData(struct cereal_ModelData_PathData*, cereal_ModelData_PathData_list, int i);
|
||||
void cereal_get_ModelData_LeadData(struct cereal_ModelData_LeadData*, cereal_ModelData_LeadData_list, int i);
|
||||
void cereal_get_ModelData_ModelSettings(struct cereal_ModelData_ModelSettings*, cereal_ModelData_ModelSettings_list, int i);
|
||||
void cereal_get_CalibrationFeatures(struct cereal_CalibrationFeatures*, cereal_CalibrationFeatures_list, int i);
|
||||
void cereal_get_EncodeIndex(struct cereal_EncodeIndex*, cereal_EncodeIndex_list, int i);
|
||||
void cereal_get_AndroidLogEntry(struct cereal_AndroidLogEntry*, cereal_AndroidLogEntry_list, int i);
|
||||
void cereal_get_LogRotate(struct cereal_LogRotate*, cereal_LogRotate_list, int i);
|
||||
void cereal_get_Event(struct cereal_Event*, cereal_Event_list, int i);
|
||||
|
||||
void cereal_set_InitData(const struct cereal_InitData*, cereal_InitData_list, int i);
|
||||
void cereal_set_FrameData(const struct cereal_FrameData*, cereal_FrameData_list, int i);
|
||||
void cereal_set_GPSNMEAData(const struct cereal_GPSNMEAData*, cereal_GPSNMEAData_list, int i);
|
||||
void cereal_set_SensorEventData(const struct cereal_SensorEventData*, cereal_SensorEventData_list, int i);
|
||||
void cereal_set_SensorEventData_SensorVec(const struct cereal_SensorEventData_SensorVec*, cereal_SensorEventData_SensorVec_list, int i);
|
||||
void cereal_set_CanData(const struct cereal_CanData*, cereal_CanData_list, int i);
|
||||
void cereal_set_ThermalData(const struct cereal_ThermalData*, cereal_ThermalData_list, int i);
|
||||
void cereal_set_HealthData(const struct cereal_HealthData*, cereal_HealthData_list, int i);
|
||||
void cereal_set_LiveUI(const struct cereal_LiveUI*, cereal_LiveUI_list, int i);
|
||||
void cereal_set_Live20Data(const struct cereal_Live20Data*, cereal_Live20Data_list, int i);
|
||||
void cereal_set_Live20Data_LeadData(const struct cereal_Live20Data_LeadData*, cereal_Live20Data_LeadData_list, int i);
|
||||
void cereal_set_LiveCalibrationData(const struct cereal_LiveCalibrationData*, cereal_LiveCalibrationData_list, int i);
|
||||
void cereal_set_LiveTracks(const struct cereal_LiveTracks*, cereal_LiveTracks_list, int i);
|
||||
void cereal_set_Live100Data(const struct cereal_Live100Data*, cereal_Live100Data_list, int i);
|
||||
void cereal_set_LiveEventData(const struct cereal_LiveEventData*, cereal_LiveEventData_list, int i);
|
||||
void cereal_set_ModelData(const struct cereal_ModelData*, cereal_ModelData_list, int i);
|
||||
void cereal_set_ModelData_PathData(const struct cereal_ModelData_PathData*, cereal_ModelData_PathData_list, int i);
|
||||
void cereal_set_ModelData_LeadData(const struct cereal_ModelData_LeadData*, cereal_ModelData_LeadData_list, int i);
|
||||
void cereal_set_ModelData_ModelSettings(const struct cereal_ModelData_ModelSettings*, cereal_ModelData_ModelSettings_list, int i);
|
||||
void cereal_set_CalibrationFeatures(const struct cereal_CalibrationFeatures*, cereal_CalibrationFeatures_list, int i);
|
||||
void cereal_set_EncodeIndex(const struct cereal_EncodeIndex*, cereal_EncodeIndex_list, int i);
|
||||
void cereal_set_AndroidLogEntry(const struct cereal_AndroidLogEntry*, cereal_AndroidLogEntry_list, int i);
|
||||
void cereal_set_LogRotate(const struct cereal_LogRotate*, cereal_LogRotate_list, int i);
|
||||
void cereal_set_Event(const struct cereal_Event*, cereal_Event_list, int i);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
28
cereal/java.capnp
Normal file
28
cereal/java.capnp
Normal file
@@ -0,0 +1,28 @@
|
||||
# Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
|
||||
# Licensed under the MIT License:
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
@0xc5f1af96651f70ea;
|
||||
|
||||
annotation package @0x9ee4c8f803b3b596 (file) : Text;
|
||||
# Name of the package, such as "org.example.foo", in which the generated code will reside.
|
||||
|
||||
annotation outerClassname @0x9b066bb4881f7cd3 (file) : Text;
|
||||
# Name of the outer class that will wrap the generated code.
|
||||
687
cereal/log.capnp
687
cereal/log.capnp
@@ -1,14 +1,100 @@
|
||||
using Cxx = import "c++.capnp";
|
||||
$Cxx.namespace("cereal");
|
||||
|
||||
using Java = import "java.capnp";
|
||||
$Java.package("ai.comma.openpilot.cereal");
|
||||
$Java.outerClassname("Log");
|
||||
|
||||
using Car = import "car.capnp";
|
||||
|
||||
@0xf3b1f17e25a4285b;
|
||||
|
||||
const logVersion :Int32 = 1;
|
||||
|
||||
struct Map(Key, Value) {
|
||||
entries @0 :List(Entry);
|
||||
struct Entry {
|
||||
key @0 :Key;
|
||||
value @1 :Value;
|
||||
}
|
||||
}
|
||||
|
||||
struct InitData {
|
||||
kernelArgs @0 :List(Text);
|
||||
gctx @1 :Text;
|
||||
dongleId @2 :Text;
|
||||
|
||||
deviceType @3 :DeviceType;
|
||||
version @4 :Text;
|
||||
|
||||
androidBuildInfo @5 :AndroidBuildInfo;
|
||||
androidSensors @6 :List(AndroidSensor);
|
||||
chffrAndroidExtra @7 :ChffrAndroidExtra;
|
||||
|
||||
pandaInfo @8 :PandaInfo;
|
||||
|
||||
dirty @9 :Bool;
|
||||
|
||||
enum DeviceType {
|
||||
unknown @0;
|
||||
neo @1;
|
||||
chffrAndroid @2;
|
||||
}
|
||||
|
||||
struct AndroidBuildInfo {
|
||||
board @0 :Text;
|
||||
bootloader @1 :Text;
|
||||
brand @2 :Text;
|
||||
device @3 :Text;
|
||||
display @4 :Text;
|
||||
fingerprint @5 :Text;
|
||||
hardware @6 :Text;
|
||||
host @7 :Text;
|
||||
id @8 :Text;
|
||||
manufacturer @9 :Text;
|
||||
model @10 :Text;
|
||||
product @11 :Text;
|
||||
radioVersion @12 :Text;
|
||||
serial @13 :Text;
|
||||
supportedAbis @14 :List(Text);
|
||||
tags @15 :Text;
|
||||
time @16 :Int64;
|
||||
type @17 :Text;
|
||||
user @18 :Text;
|
||||
|
||||
versionCodename @19 :Text;
|
||||
versionRelease @20 :Text;
|
||||
versionSdk @21 :Int32;
|
||||
versionSecurityPatch @22 :Text;
|
||||
}
|
||||
|
||||
struct AndroidSensor {
|
||||
id @0 :Int32;
|
||||
name @1 :Text;
|
||||
vendor @2 :Text;
|
||||
version @3 :Int32;
|
||||
handle @4 :Int32;
|
||||
type @5 :Int32;
|
||||
maxRange @6 :Float32;
|
||||
resolution @7 :Float32;
|
||||
power @8 :Float32;
|
||||
minDelay @9 :Int32;
|
||||
fifoReservedEventCount @10 :UInt32;
|
||||
fifoMaxEventCount @11 :UInt32;
|
||||
stringType @12 :Text;
|
||||
maxDelay @13 :Int32;
|
||||
}
|
||||
|
||||
struct ChffrAndroidExtra {
|
||||
allCameraCharacteristics @0 :Map(Text, Text);
|
||||
}
|
||||
|
||||
struct PandaInfo {
|
||||
hasPanda @0: Bool;
|
||||
dongleId @1: Text;
|
||||
stVersion @2: Text;
|
||||
espVersion @3: Text;
|
||||
}
|
||||
}
|
||||
|
||||
struct FrameData {
|
||||
@@ -19,6 +105,27 @@ struct FrameData {
|
||||
integLines @4 :Int32;
|
||||
globalGain @5 :Int32;
|
||||
image @6 :Data;
|
||||
|
||||
frameType @7 :FrameType;
|
||||
timestampSof @8 :UInt64;
|
||||
|
||||
androidCaptureResult @9 :AndroidCaptureResult;
|
||||
|
||||
enum FrameType {
|
||||
unknown @0;
|
||||
neo @1;
|
||||
chffrAndroid @2;
|
||||
}
|
||||
|
||||
struct AndroidCaptureResult {
|
||||
sensitivity @0 :Int32;
|
||||
frameDuration @1 :Int64;
|
||||
exposureTime @2 :Int64;
|
||||
rollingShutterSkew @3 :UInt64;
|
||||
colorCorrectionTransform @4 :List(Int32);
|
||||
colorCorrectionGains @5 :List(Float32);
|
||||
displayRotation @6 :Int8;
|
||||
}
|
||||
}
|
||||
|
||||
struct GPSNMEAData {
|
||||
@@ -38,12 +145,60 @@ struct SensorEventData {
|
||||
magnetic @5 :SensorVec;
|
||||
orientation @6 :SensorVec;
|
||||
gyro @7 :SensorVec;
|
||||
pressure @9 :SensorVec;
|
||||
}
|
||||
source @8 :SensorSource;
|
||||
|
||||
struct SensorVec {
|
||||
v @0 :List(Float32);
|
||||
status @1 :Int8;
|
||||
}
|
||||
|
||||
enum SensorSource {
|
||||
android @0;
|
||||
iOS @1;
|
||||
fiber @2;
|
||||
velodyne @3; # Velodyne IMU
|
||||
}
|
||||
}
|
||||
|
||||
# android struct GpsLocation
|
||||
struct GpsLocationData {
|
||||
# Contains GpsLocationFlags bits.
|
||||
flags @0 :UInt16;
|
||||
|
||||
# Represents latitude in degrees.
|
||||
latitude @1 :Float64;
|
||||
|
||||
# Represents longitude in degrees.
|
||||
longitude @2 :Float64;
|
||||
|
||||
# Represents altitude in meters above the WGS 84 reference ellipsoid.
|
||||
altitude @3 :Float64;
|
||||
|
||||
# Represents speed in meters per second.
|
||||
speed @4 :Float32;
|
||||
|
||||
# Represents heading in degrees.
|
||||
bearing @5 :Float32;
|
||||
|
||||
# Represents expected accuracy in meters.
|
||||
accuracy @6 :Float32;
|
||||
|
||||
# Timestamp for the location fix.
|
||||
# Milliseconds since January 1, 1970.
|
||||
timestamp @7 :Int64;
|
||||
|
||||
source @8 :SensorSource;
|
||||
|
||||
enum SensorSource {
|
||||
android @0;
|
||||
iOS @1;
|
||||
car @2;
|
||||
velodyne @3; # Velodyne IMU
|
||||
fusion @4;
|
||||
external @5;
|
||||
}
|
||||
}
|
||||
|
||||
struct CanData {
|
||||
@@ -61,6 +216,11 @@ struct ThermalData {
|
||||
mem @4 :UInt16;
|
||||
gpu @5 :UInt16;
|
||||
bat @6 :UInt32;
|
||||
|
||||
# not thermal
|
||||
freeSpace @7 :Float32;
|
||||
batteryPercent @8 :Int16;
|
||||
batteryStatus @9: Text;
|
||||
}
|
||||
|
||||
struct HealthData {
|
||||
@@ -70,6 +230,7 @@ struct HealthData {
|
||||
started @2 :Bool;
|
||||
controlsAllowed @3 :Bool;
|
||||
gasInterceptorDetected @4 :Bool;
|
||||
startedSignalDetected @5 :Bool;
|
||||
}
|
||||
|
||||
struct LiveUI {
|
||||
@@ -116,6 +277,9 @@ struct LiveCalibrationData {
|
||||
calStatus @1 :Int8;
|
||||
calCycle @2 :Int32;
|
||||
calPerc @3 :Int8;
|
||||
|
||||
# Maps car space to normalized image space.
|
||||
extrinsicMatrix @4 :List(Float32);
|
||||
}
|
||||
|
||||
struct LiveTracks {
|
||||
@@ -134,8 +298,8 @@ struct LiveTracks {
|
||||
struct Live100Data {
|
||||
canMonoTime @16 :UInt64;
|
||||
canMonoTimes @21 :List(UInt64);
|
||||
l20MonoTime @17 :UInt64;
|
||||
mdMonoTime @18 :UInt64;
|
||||
l20MonoTimeDEPRECATED @17 :UInt64;
|
||||
mdMonoTimeDEPRECATED @18 :UInt64;
|
||||
|
||||
vEgo @0 :Float32;
|
||||
aEgoDEPRECATED @1 :Float32;
|
||||
@@ -150,7 +314,7 @@ struct Live100Data {
|
||||
aTargetMin @10 :Float32;
|
||||
aTargetMax @11 :Float32;
|
||||
jerkFactor @12 :Float32;
|
||||
angleSteers @13 :Float32;
|
||||
angleSteers @13 :Float32; # Steering angle in degrees.
|
||||
hudLeadDEPRECATED @14 :Int32;
|
||||
cumLagMs @15 :Float32;
|
||||
|
||||
@@ -163,6 +327,8 @@ struct Live100Data {
|
||||
alertText1 @24 :Text;
|
||||
alertText2 @25 :Text;
|
||||
awarenessStatus @26 :Float32;
|
||||
|
||||
angleOffset @27 :Float32;
|
||||
}
|
||||
|
||||
struct LiveEventData {
|
||||
@@ -218,13 +384,16 @@ struct EncodeIndex {
|
||||
encodeId @2 :UInt32;
|
||||
# minute long segment this frame is in
|
||||
segmentNum @3 :Int32;
|
||||
# index into camera file in segment from 0
|
||||
# index into camera file in segment in presentation order
|
||||
segmentId @4 :UInt32;
|
||||
# index into camera file in segment in encode order
|
||||
segmentIdEncode @5 :UInt32;
|
||||
|
||||
enum Type {
|
||||
bigBoxLossless @0; # rcamera.mkv
|
||||
fullHEVC @1; # fcamera.hevc
|
||||
bigBoxHEVC @2; # bcamera.hevc
|
||||
chffrAndroidH264 @3; # camera
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,8 +412,505 @@ struct LogRotate {
|
||||
path @1 :Text;
|
||||
}
|
||||
|
||||
struct Plan {
|
||||
# lateral, 3rd order polynomial
|
||||
lateralValid @0: Bool;
|
||||
dPoly @1 :List(Float32);
|
||||
|
||||
# longitudinal
|
||||
longitudinalValid @2: Bool;
|
||||
vTarget @3 :Float32;
|
||||
aTargetMin @4 :Float32;
|
||||
aTargetMax @5 :Float32;
|
||||
jerkFactor @6 :Float32;
|
||||
hasLead @7 :Bool;
|
||||
}
|
||||
|
||||
struct LiveLocationData {
|
||||
status @0: UInt8;
|
||||
|
||||
# 3D fix
|
||||
lat @1: Float64;
|
||||
lon @2: Float64;
|
||||
alt @3: Float32; # m
|
||||
|
||||
# speed
|
||||
speed @4: Float32; # m/s
|
||||
|
||||
# NED velocity components
|
||||
vNED @5: List(Float32);
|
||||
|
||||
# roll, pitch, heading (x,y,z)
|
||||
roll @6: Float32; # WRT to center of earth?
|
||||
pitch @7: Float32; # WRT to center of earth?
|
||||
heading @8: Float32; # WRT to north?
|
||||
|
||||
# what are these?
|
||||
wanderAngle @9: Float32;
|
||||
trackAngle @10: Float32;
|
||||
|
||||
# car frame -- https://upload.wikimedia.org/wikipedia/commons/f/f5/RPY_angles_of_cars.png
|
||||
|
||||
# gyro, in car frame, deg/s
|
||||
gyro @11: List(Float32);
|
||||
|
||||
# accel, in car frame, m/s^2
|
||||
accel @12: List(Float32);
|
||||
|
||||
accuracy @13: Accuracy;
|
||||
|
||||
struct Accuracy {
|
||||
pNEDError @0: List(Float32);
|
||||
vNEDError @1: List(Float32);
|
||||
rollError @2: Float32;
|
||||
pitchError @3: Float32;
|
||||
headingError @4: Float32;
|
||||
ellipsoidSemiMajorError @5: Float32;
|
||||
ellipsoidSemiMinorError @6: Float32;
|
||||
ellipsoidOrientationError @7: Float32;
|
||||
}
|
||||
}
|
||||
|
||||
struct EthernetPacket {
|
||||
pkt @0 :Data;
|
||||
ts @1: Float32;
|
||||
}
|
||||
|
||||
struct NavUpdate {
|
||||
isNavigating @0 :Bool;
|
||||
curSegment @1 :Int32;
|
||||
segments @2 :List(Segment);
|
||||
|
||||
struct LatLng {
|
||||
lat @0 :Float64;
|
||||
lng @1 :Float64;
|
||||
}
|
||||
|
||||
struct Segment {
|
||||
from @0 :LatLng;
|
||||
to @1 :LatLng;
|
||||
updateTime @2 :Int32;
|
||||
distance @3 :Int32;
|
||||
crossTime @4 :Int32;
|
||||
exitNo @5 :Int32;
|
||||
instruction @6 :Instruction;
|
||||
|
||||
parts @7 :List(LatLng);
|
||||
|
||||
enum Instruction {
|
||||
turnLeft @0;
|
||||
turnRight @1;
|
||||
keepLeft @2;
|
||||
keepRight @3;
|
||||
straight @4;
|
||||
roundaboutExitNumber @5;
|
||||
roundaboutExit @6;
|
||||
roundaboutTurnLeft @7;
|
||||
unkn8 @8;
|
||||
roundaboutStraight @9;
|
||||
unkn10 @10;
|
||||
roundaboutTurnRight @11;
|
||||
unkn12 @12;
|
||||
roundaboutUturn @13;
|
||||
unkn14 @14;
|
||||
arrive @15;
|
||||
exitLeft @16;
|
||||
exitRight @17;
|
||||
unkn18 @18;
|
||||
uturn @19;
|
||||
# ...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct CellInfo {
|
||||
timestamp @0 :UInt64;
|
||||
repr @1 :Text; # android toString() for now
|
||||
}
|
||||
|
||||
struct WifiScan {
|
||||
bssid @0 :Text;
|
||||
ssid @1 :Text;
|
||||
capabilities @2 :Text;
|
||||
frequency @3 :Int32;
|
||||
level @4 :Int32;
|
||||
timestamp @5 :Int64;
|
||||
|
||||
centerFreq0 @6 :Int32;
|
||||
centerFreq1 @7 :Int32;
|
||||
channelWidth @8 :ChannelWidth;
|
||||
operatorFriendlyName @9 :Text;
|
||||
venueName @10 :Text;
|
||||
is80211mcResponder @11 :Bool;
|
||||
passpoint @12 :Bool;
|
||||
|
||||
distanceCm @13 :Int32;
|
||||
distanceSdCm @14 :Int32;
|
||||
|
||||
enum ChannelWidth {
|
||||
w20Mhz @0;
|
||||
w40Mhz @1;
|
||||
w80Mhz @2;
|
||||
w160Mhz @3;
|
||||
w80Plus80Mhz @4;
|
||||
}
|
||||
}
|
||||
|
||||
struct AndroidGnss {
|
||||
union {
|
||||
measurements @0 :Measurements;
|
||||
navigationMessage @1 :NavigationMessage;
|
||||
}
|
||||
|
||||
struct Measurements {
|
||||
clock @0 :Clock;
|
||||
measurements @1 :List(Measurement);
|
||||
|
||||
struct Clock {
|
||||
timeNanos @0 :Int64;
|
||||
hardwareClockDiscontinuityCount @1 :Int32;
|
||||
|
||||
hasTimeUncertaintyNanos @2 :Bool;
|
||||
timeUncertaintyNanos @3 :Float64;
|
||||
|
||||
hasLeapSecond @4 :Bool;
|
||||
leapSecond @5 :Int32;
|
||||
|
||||
hasFullBiasNanos @6 :Bool;
|
||||
fullBiasNanos @7 :Int64;
|
||||
|
||||
hasBiasNanos @8 :Bool;
|
||||
biasNanos @9 :Float64;
|
||||
|
||||
hasBiasUncertaintyNanos @10 :Bool;
|
||||
biasUncertaintyNanos @11 :Float64;
|
||||
|
||||
hasDriftNanosPerSecond @12 :Bool;
|
||||
driftNanosPerSecond @13 :Float64;
|
||||
|
||||
hasDriftUncertaintyNanosPerSecond @14 :Bool;
|
||||
driftUncertaintyNanosPerSecond @15 :Float64;
|
||||
}
|
||||
|
||||
struct Measurement {
|
||||
svId @0 :Int32;
|
||||
constellation @1 :Constellation;
|
||||
|
||||
timeOffsetNanos @2 :Float64;
|
||||
state @3 :Int32;
|
||||
receivedSvTimeNanos @4 :Int64;
|
||||
receivedSvTimeUncertaintyNanos @5 :Int64;
|
||||
cn0DbHz @6 :Float64;
|
||||
pseudorangeRateMetersPerSecond @7 :Float64;
|
||||
pseudorangeRateUncertaintyMetersPerSecond @8 :Float64;
|
||||
accumulatedDeltaRangeState @9 :Int32;
|
||||
accumulatedDeltaRangeMeters @10 :Float64;
|
||||
accumulatedDeltaRangeUncertaintyMeters @11 :Float64;
|
||||
|
||||
hasCarrierFrequencyHz @12 :Bool;
|
||||
carrierFrequencyHz @13 :Float32;
|
||||
hasCarrierCycles @14 :Bool;
|
||||
carrierCycles @15 :Int64;
|
||||
hasCarrierPhase @16 :Bool;
|
||||
carrierPhase @17 :Float64;
|
||||
hasCarrierPhaseUncertainty @18 :Bool;
|
||||
carrierPhaseUncertainty @19 :Float64;
|
||||
hasSnrInDb @20 :Bool;
|
||||
snrInDb @21 :Float64;
|
||||
|
||||
multipathIndicator @22 :MultipathIndicator;
|
||||
|
||||
enum Constellation {
|
||||
unknown @0;
|
||||
gps @1;
|
||||
sbas @2;
|
||||
glonass @3;
|
||||
qzss @4;
|
||||
beidou @5;
|
||||
galileo @6;
|
||||
}
|
||||
|
||||
enum State {
|
||||
unknown @0;
|
||||
codeLock @1;
|
||||
bitSync @2;
|
||||
subframeSync @3;
|
||||
towDecoded @4;
|
||||
msecAmbiguous @5;
|
||||
symbolSync @6;
|
||||
gloStringSync @7;
|
||||
gloTodDecoded @8;
|
||||
bdsD2BitSync @9;
|
||||
bdsD2SubframeSync @10;
|
||||
galE1bcCodeLock @11;
|
||||
galE1c2ndCodeLock @12;
|
||||
galE1bPageSync @13;
|
||||
sbasSync @14;
|
||||
}
|
||||
|
||||
enum MultipathIndicator {
|
||||
unknown @0;
|
||||
detected @1;
|
||||
notDetected @2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct NavigationMessage {
|
||||
type @0 :Int32;
|
||||
svId @1 :Int32;
|
||||
messageId @2 :Int32;
|
||||
submessageId @3 :Int32;
|
||||
data @4 :Data;
|
||||
status @5 :Status;
|
||||
|
||||
enum Status {
|
||||
unknown @0;
|
||||
parityPassed @1;
|
||||
parityRebuilt @2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct QcomGnss {
|
||||
logTs @0 :UInt64;
|
||||
union {
|
||||
measurementReport @1 :MeasurementReport;
|
||||
clockReport @2 :ClockReport;
|
||||
}
|
||||
|
||||
struct MeasurementReport {
|
||||
source @0 :Source;
|
||||
|
||||
fCount @1 :UInt32;
|
||||
|
||||
gpsWeek @2 :UInt16;
|
||||
glonassCycleNumber @3 :UInt8;
|
||||
glonassNumberOfDays @4 :UInt16;
|
||||
|
||||
milliseconds @5 :UInt32;
|
||||
timeBias @6 :Float32;
|
||||
clockTimeUncertainty @7 :Float32;
|
||||
clockFrequencyBias @8 :Float32;
|
||||
clockFrequencyUncertainty @9 :Float32;
|
||||
|
||||
sv @10 :List(SV);
|
||||
|
||||
enum Source {
|
||||
gps @0;
|
||||
glonass @1;
|
||||
}
|
||||
|
||||
struct SV {
|
||||
svId @0 :UInt8;
|
||||
observationState @2 :SVObservationState;
|
||||
observations @3 :UInt8;
|
||||
goodObservations @4 :UInt8;
|
||||
gpsParityErrorCount @5 :UInt16;
|
||||
glonassFrequencyIndex @1 :Int8;
|
||||
glonassHemmingErrorCount @6 :UInt8;
|
||||
filterStages @7 :UInt8;
|
||||
carrierNoise @8 :UInt16;
|
||||
latency @9 :Int16;
|
||||
predetectIntegration @10 :UInt8;
|
||||
postdetections @11 :UInt16;
|
||||
|
||||
unfilteredMeasurementIntegral @12 :UInt32;
|
||||
unfilteredMeasurementFraction @13 :Float32;
|
||||
unfilteredTimeUncertainty @14 :Float32;
|
||||
unfilteredSpeed @15 :Float32;
|
||||
unfilteredSpeedUncertainty @16 :Float32;
|
||||
measurementStatus @17 :MeasurementStatus;
|
||||
multipathEstimate @18 :UInt32;
|
||||
azimuth @19 :Float32;
|
||||
elevation @20 :Float32;
|
||||
carrierPhaseCyclesIntegral @21 :Int32;
|
||||
carrierPhaseCyclesFraction @22 :UInt16;
|
||||
fineSpeed @23 :Float32;
|
||||
fineSpeedUncertainty @24 :Float32;
|
||||
cycleSlipCount @25 :UInt8;
|
||||
|
||||
struct MeasurementStatus {
|
||||
subMillisecondIsValid @0 :Bool;
|
||||
subBitTimeIsKnown @1 :Bool;
|
||||
satelliteTimeIsKnown @2 :Bool;
|
||||
bitEdgeConfirmedFromSignal @3 :Bool;
|
||||
measuredVelocity @4 :Bool;
|
||||
fineOrCoarseVelocity @5 :Bool;
|
||||
lockPointValid @6 :Bool;
|
||||
lockPointPositive @7 :Bool;
|
||||
lastUpdateFromDifference @8 :Bool;
|
||||
lastUpdateFromVelocityDifference @9 :Bool;
|
||||
strongIndicationOfCrossCorelation @10 :Bool;
|
||||
tentativeMeasurement @11 :Bool;
|
||||
measurementNotUsable @12 :Bool;
|
||||
sirCheckIsNeeded @13 :Bool;
|
||||
probationMode @14 :Bool;
|
||||
|
||||
glonassMeanderBitEdgeValid @15 :Bool;
|
||||
glonassTimeMarkValid @16 :Bool;
|
||||
|
||||
gpsRoundRobinRxDiversity @17 :Bool;
|
||||
gpsRxDiversity @18 :Bool;
|
||||
gpsLowBandwidthRxDiversityCombined @19 :Bool;
|
||||
gpsHighBandwidthNu4 @20 :Bool;
|
||||
gpsHighBandwidthNu8 @21 :Bool;
|
||||
gpsHighBandwidthUniform @22 :Bool;
|
||||
gpsMultipathIndicator @23 :Bool;
|
||||
|
||||
imdJammingIndicator @24 :Bool;
|
||||
lteB13TxJammingIndicator @25 :Bool;
|
||||
freshMeasurementIndicator @26 :Bool;
|
||||
|
||||
multipathEstimateIsValid @27 :Bool;
|
||||
directionIsValid @28 :Bool;
|
||||
}
|
||||
|
||||
enum SVObservationState {
|
||||
idle @0;
|
||||
search @1;
|
||||
searchVerify @2;
|
||||
bitEdge @3;
|
||||
trackVerify @4;
|
||||
track @5;
|
||||
restart @6;
|
||||
dpo @7;
|
||||
glo10msBe @8;
|
||||
glo10msAt @9;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct ClockReport {
|
||||
hasFCount @0 :Bool;
|
||||
fCount @1 :UInt32;
|
||||
|
||||
hasGpsWeekNumber @2 :Bool;
|
||||
gpsWeekNumber @3 :UInt16;
|
||||
hasGpsMilliseconds @4 :Bool;
|
||||
gpsMilliseconds @5 :UInt32;
|
||||
gpsTimeBias @6 :Float32;
|
||||
gpsClockTimeUncertainty @7 :Float32;
|
||||
gpsClockSource @8 :UInt8;
|
||||
|
||||
hasGlonassYear @9 :Bool;
|
||||
glonassYear @10 :UInt8;
|
||||
hasGlonassDay @11 :Bool;
|
||||
glonassDay @12 :UInt16;
|
||||
hasGlonassMilliseconds @13 :Bool;
|
||||
glonassMilliseconds @14 :UInt32;
|
||||
glonassTimeBias @15 :Float32;
|
||||
glonassClockTimeUncertainty @16 :Float32;
|
||||
glonassClockSource @17 :UInt8;
|
||||
|
||||
bdsWeek @18 :UInt16;
|
||||
bdsMilliseconds @19 :UInt32;
|
||||
bdsTimeBias @20 :Float32;
|
||||
bdsClockTimeUncertainty @21 :Float32;
|
||||
bdsClockSource @22 :UInt8;
|
||||
|
||||
galWeek @23 :UInt16;
|
||||
galMilliseconds @24 :UInt32;
|
||||
galTimeBias @25 :Float32;
|
||||
galClockTimeUncertainty @26 :Float32;
|
||||
galClockSource @27 :UInt8;
|
||||
|
||||
clockFrequencyBias @28 :Float32;
|
||||
clockFrequencyUncertainty @29 :Float32;
|
||||
frequencySource @30 :UInt8;
|
||||
gpsLeapSeconds @31 :UInt8;
|
||||
gpsLeapSecondsUncertainty @32 :UInt8;
|
||||
gpsLeapSecondsSource @33 :UInt8;
|
||||
|
||||
gpsToGlonassTimeBiasMilliseconds @34 :Float32;
|
||||
gpsToGlonassTimeBiasMillisecondsUncertainty @35 :Float32;
|
||||
gpsToBdsTimeBiasMilliseconds @36 :Float32;
|
||||
gpsToBdsTimeBiasMillisecondsUncertainty @37 :Float32;
|
||||
bdsToGloTimeBiasMilliseconds @38 :Float32;
|
||||
bdsToGloTimeBiasMillisecondsUncertainty @39 :Float32;
|
||||
gpsToGalTimeBiasMilliseconds @40 :Float32;
|
||||
gpsToGalTimeBiasMillisecondsUncertainty @41 :Float32;
|
||||
galToGloTimeBiasMilliseconds @42 :Float32;
|
||||
galToGloTimeBiasMillisecondsUncertainty @43 :Float32;
|
||||
galToBdsTimeBiasMilliseconds @44 :Float32;
|
||||
galToBdsTimeBiasMillisecondsUncertainty @45 :Float32;
|
||||
|
||||
hasRtcTime @46 :Bool;
|
||||
systemRtcTime @47 :UInt32;
|
||||
fCountOffset @48 :UInt32;
|
||||
lpmRtcCount @49 :UInt32;
|
||||
clockResets @50 :UInt32;
|
||||
}
|
||||
}
|
||||
|
||||
struct LidarPts {
|
||||
r @0 :List(UInt16); # uint16 m*500.0
|
||||
theta @1 :List(UInt16); # uint16 deg*100.0
|
||||
reflect @2 :List(UInt8); # uint8 0-255
|
||||
|
||||
# For storing out of file.
|
||||
idx @3 :UInt64;
|
||||
|
||||
# For storing in file
|
||||
pkt @4 :Data;
|
||||
}
|
||||
|
||||
struct ProcLog {
|
||||
cpuTimes @0 :List(CPUTimes);
|
||||
mem @1 :Mem;
|
||||
procs @2 :List(Process);
|
||||
|
||||
struct Process {
|
||||
pid @0 :Int32;
|
||||
name @1 :Text;
|
||||
state @2 :UInt8;
|
||||
ppid @3 :Int32;
|
||||
|
||||
cpuUser @4 :Float32;
|
||||
cpuSystem @5 :Float32;
|
||||
cpuChildrenUser @6 :Float32;
|
||||
cpuChildrenSystem @7 :Float32;
|
||||
priority @8 :Int64;
|
||||
nice @9 :Int32;
|
||||
numThreads @10 :Int32;
|
||||
startTime @11 :Float64;
|
||||
|
||||
memVms @12 :UInt64;
|
||||
memRss @13 :UInt64;
|
||||
|
||||
processor @14 :Int32;
|
||||
|
||||
cmdline @15 :List(Text);
|
||||
exe @16 :Text;
|
||||
}
|
||||
|
||||
struct CPUTimes {
|
||||
cpuNum @0 :Int64;
|
||||
user @1 :Float32;
|
||||
nice @2 :Float32;
|
||||
system @3 :Float32;
|
||||
idle @4 :Float32;
|
||||
iowait @5 :Float32;
|
||||
irq @6 :Float32;
|
||||
softirq @7 :Float32;
|
||||
}
|
||||
|
||||
struct Mem {
|
||||
total @0 :UInt64;
|
||||
free @1 :UInt64;
|
||||
available @2 :UInt64;
|
||||
buffers @3 :UInt64;
|
||||
cached @4 :UInt64;
|
||||
active @5 :UInt64;
|
||||
inactive @6 :UInt64;
|
||||
shared @7 :UInt64;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct Event {
|
||||
# in nanoseconds?
|
||||
logMonoTime @0 :UInt64;
|
||||
|
||||
union {
|
||||
@@ -268,5 +934,18 @@ struct Event {
|
||||
logMessage @18 :Text;
|
||||
liveCalibration @19 :LiveCalibrationData;
|
||||
androidLogEntry @20 :AndroidLogEntry;
|
||||
gpsLocation @21 :GpsLocationData;
|
||||
carState @22 :Car.CarState;
|
||||
carControl @23 :Car.CarControl;
|
||||
plan @24 :Plan;
|
||||
liveLocation @25 :LiveLocationData;
|
||||
ethernetData @26 :List(EthernetPacket);
|
||||
navUpdate @27 :NavUpdate;
|
||||
cellInfo @28 :List(CellInfo);
|
||||
wifiScan @29 :List(WifiScan);
|
||||
androidGnss @30 :AndroidGnss;
|
||||
qcomGnss @31 :QcomGnss;
|
||||
lidarPts @32 :LidarPts;
|
||||
procLog @33 :ProcLog;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
import requests
|
||||
|
||||
def api_get(endpoint, method='GET', timeout=None, **params):
|
||||
from selfdrive.version import version
|
||||
|
||||
def api_get(endpoint, method='GET', timeout=None, access_token=None, **params):
|
||||
backend = "https://api.commadotai.com/"
|
||||
|
||||
params['_version'] = "OPENPILOTv0.2"
|
||||
headers = {}
|
||||
if access_token is not None:
|
||||
headers['Authorization'] = "JWT "+access_token
|
||||
|
||||
headers['User-Agent'] = "openpilot-" + version
|
||||
|
||||
return requests.request(method, backend+endpoint, timeout=timeout, headers = headers, params=params)
|
||||
|
||||
return requests.request(method, backend+endpoint, timeout=timeout, params=params)
|
||||
|
||||
@@ -7,6 +7,8 @@ if os.getenv("NOLOG"):
|
||||
pass
|
||||
def bind_user(**kwargs):
|
||||
pass
|
||||
def bind_extra(**kwargs):
|
||||
pass
|
||||
def install():
|
||||
pass
|
||||
else:
|
||||
@@ -21,6 +23,9 @@ else:
|
||||
def bind_user(**kwargs):
|
||||
client.user_context(kwargs)
|
||||
|
||||
def bind_extra(**kwargs):
|
||||
client.extra_context(kwargs)
|
||||
|
||||
def install():
|
||||
# installs a sys.excepthook
|
||||
__excepthook__ = sys.excepthook
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import re
|
||||
import bitstring
|
||||
from binascii import hexlify
|
||||
import struct
|
||||
from collections import namedtuple
|
||||
|
||||
def int_or_float(s):
|
||||
@@ -16,7 +16,8 @@ DBCSignal = namedtuple(
|
||||
|
||||
class dbc(object):
|
||||
def __init__(self, fn):
|
||||
self.txt = open(fn).read().split("\n")
|
||||
with open(fn) as f:
|
||||
self.txt = f.read().split("\n")
|
||||
self._warned_addresses = set()
|
||||
|
||||
# regexps from https://github.com/ebroecker/canmatrix/blob/master/canmatrix/importdbc.py
|
||||
@@ -35,6 +36,7 @@ class dbc(object):
|
||||
for i in range(0, 64, 8):
|
||||
for j in range(7, -1, -1):
|
||||
self.bits.append(i+j)
|
||||
self.bits_index = dict(zip(self.bits, range(64)))
|
||||
|
||||
for l in self.txt:
|
||||
l = l.strip()
|
||||
@@ -101,7 +103,7 @@ class dbc(object):
|
||||
if s.is_little_endian:
|
||||
ss = s.start_bit
|
||||
else:
|
||||
ss = self.bits.index(s.start_bit)
|
||||
ss = self.bits_index[s.start_bit]
|
||||
|
||||
|
||||
if s.is_signed:
|
||||
@@ -133,6 +135,7 @@ class dbc(object):
|
||||
|
||||
Returns (None, None) if the message could not be decoded.
|
||||
"""
|
||||
|
||||
if arr is None:
|
||||
out = {}
|
||||
else:
|
||||
@@ -150,7 +153,9 @@ class dbc(object):
|
||||
print name
|
||||
|
||||
blen = 8*len(x[2])
|
||||
x2_int = int(hexlify(x[2]), 16)
|
||||
|
||||
st = x[2].rjust(8, '\x00')
|
||||
le, be = None, None
|
||||
|
||||
for s in msg[1]:
|
||||
if arr is not None and s[0] not in arr:
|
||||
@@ -159,11 +164,18 @@ class dbc(object):
|
||||
# big or little endian?
|
||||
# see http://vi-firmware.openxcplatform.com/en/master/config/bit-numbering.html
|
||||
if s[3] is False:
|
||||
ss = self.bits.index(s[1])
|
||||
ss = self.bits_index[s[1]]
|
||||
if be is None:
|
||||
be = struct.unpack(">Q", st)[0]
|
||||
x2_int = be
|
||||
data_bit_pos = (blen - (ss + s[2]))
|
||||
else:
|
||||
if le is None:
|
||||
le = struct.unpack("<Q", st)[0]
|
||||
x2_int = le
|
||||
ss = s[1]
|
||||
data_bit_pos = ss
|
||||
|
||||
data_bit_pos = (blen - (ss + s[2]))
|
||||
if data_bit_pos < 0:
|
||||
continue
|
||||
ival = (x2_int >> data_bit_pos) & ((1 << (s[2])) - 1)
|
||||
@@ -172,12 +184,13 @@ class dbc(object):
|
||||
ival -= (1<<s[2])
|
||||
|
||||
# control the offset
|
||||
ival = (ival + s[6])*s[5]
|
||||
if debug:
|
||||
print "%40s %2d %2d %7.2f %s" % (s[0], s[1], s[2], ival, s[-1])
|
||||
ival = (ival * s[5]) + s[6]
|
||||
#if debug:
|
||||
# print "%40s %2d %2d %7.2f %s" % (s[0], s[1], s[2], ival, s[-1])
|
||||
|
||||
if arr is None:
|
||||
out[s[0]] = ival
|
||||
else:
|
||||
out[arr.index(s[0])] = ival
|
||||
return name, out
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
"""Classes for filtering discrete time signals."""
|
||||
import numpy as np
|
||||
|
||||
|
||||
class FirstOrderLowpassFilter(object):
|
||||
def __init__(self, fc, dt, x1=0):
|
||||
self.kf = 2 * np.pi * fc * dt / (1 + 2 * np.pi * fc * dt)
|
||||
self.x1 = x1
|
||||
|
||||
def __call__(self, x):
|
||||
self.x1 = (1 - self.kf) * self.x1 + self.kf * x
|
||||
|
||||
# If previous or current is NaN, reset filter.
|
||||
if np.isnan(self.x1):
|
||||
self.x1 = x
|
||||
|
||||
return self.x1
|
||||
134
common/fingerprints.py
Normal file
134
common/fingerprints.py
Normal file
@@ -0,0 +1,134 @@
|
||||
|
||||
_FINGERPRINTS = {
|
||||
"ACURA ILX 2016 ACURAWATCH PLUS": {
|
||||
1024L: 5, 513L: 5, 1027L: 5, 1029L: 8, 929L: 4, 1057L: 5, 777L: 8, 1034L: 5, 1036L: 8, 398L: 3, 399L: 7, 145L: 8, 660L: 8, 985L: 3, 923L: 2, 542L: 7, 773L: 7, 800L: 8, 432L: 7, 419L: 8, 420L: 8, 1030L: 5, 422L: 8, 808L: 8, 428L: 8, 304L: 8, 819L: 7, 821L: 5, 57L: 3, 316L: 8, 545L: 4, 464L: 8, 1108L: 8, 597L: 8, 342L: 6, 983L: 8, 344L: 8, 804L: 8, 1039L: 8, 476L: 4, 892L: 8, 490L: 8, 1064L: 7, 882L: 2, 884L: 7, 887L: 8, 888L: 8, 380L: 8, 1365L: 5,
|
||||
# sent messages
|
||||
0xe4: 5, 0x1fa: 8, 0x200: 3, 0x30c: 8, 0x33d: 5,
|
||||
},
|
||||
"HONDA CIVIC 2016 TOURING": {
|
||||
1024L: 5, 513L: 5, 1027L: 5, 1029L: 8, 777L: 8, 1036L: 8, 1039L: 8, 1424L: 5, 401L: 8, 148L: 8, 662L: 4, 985L: 3, 795L: 8, 773L: 7, 800L: 8, 545L: 6, 420L: 8, 806L: 8, 808L: 8, 1322L: 5, 427L: 3, 428L: 8, 304L: 8, 432L: 7, 57L: 3, 450L: 8, 929L: 8, 330L: 8, 1302L: 8, 464L: 8, 1361L: 5, 1108L: 8, 597L: 8, 470L: 2, 344L: 8, 804L: 8, 399L: 7, 476L: 7, 1633L: 8, 487L: 4, 892L: 8, 490L: 8, 493L: 5, 884L: 8, 891L: 8, 380L: 8, 1365L: 5,
|
||||
# sent messages
|
||||
0xe4: 5, 0x1fa: 8, 0x200: 3, 0x30c: 8, 0x33d: 5, 0x35e: 8, 0x39f: 8,
|
||||
},
|
||||
"HONDA ACCORD 2016 TOURING": {
|
||||
1024L: 5, 929L: 8, 1027L: 5, 773L: 7, 1601L: 8, 777L: 8, 1036L: 8, 398L: 3, 1039L: 8, 401L: 8, 145L: 8, 1424L: 5, 660L: 8, 661L: 4, 918L: 7, 985L: 3, 923L: 2, 542L: 7, 927L: 8, 800L: 8, 545L: 4, 420L: 8, 422L: 8, 808L: 8, 426L: 8, 1029L: 8, 432L: 7, 57L: 3, 316L: 8, 829L: 5, 1600L: 5, 1089L: 8, 1057L: 5, 780L: 8, 1088L: 8, 464L: 8, 1108L: 8, 597L: 8, 342L: 6, 983L: 8, 344L: 8, 804L: 8, 476L: 4, 1296L: 3, 891L: 8, 1125L: 8, 487L: 4, 892L: 8, 490L: 8, 871L: 8, 1064L: 7, 882L: 2, 884L: 8, 506L: 8, 507L: 1, 380L: 8, 1365L: 5
|
||||
},
|
||||
"HONDA CR-V 2016 TOURING": {
|
||||
57L: 3, 145L: 8, 316L: 8, 340L: 8, 342L: 6, 344L: 8, 380L: 8, 398L: 3, 399L: 6, 401L: 8, 420L: 8, 422L: 8, 426L: 8, 432L: 7, 464L: 8, 474L: 5, 476L: 4, 487L: 4, 490L: 8, 493L: 3, 507L: 1, 542L: 7, 545L: 4, 597L: 8, 660L: 8, 661L: 4, 773L: 7, 777L: 8, 800L: 8, 804L: 8, 808L: 8, 882L: 2, 884L: 7, 888L: 8, 891L: 8, 892L: 8, 923L: 2, 929L: 8, 983L: 8, 985L: 3, 1024L: 5, 1027L: 5, 1029L: 8, 1033L: 5, 1036L: 8, 1039L: 8, 1057L: 5, 1064L: 7, 1108L: 8, 1125L: 8, 1296L: 8, 1365L: 5, 1424L: 5, 1600L: 5, 1601L: 8,
|
||||
# sent messages
|
||||
0x194: 4, 0x1fa: 8, 0x30c: 8, 0x33d: 5,
|
||||
}
|
||||
}
|
||||
|
||||
def eliminate_incompatible_cars(msg, candidate_cars):
|
||||
"""Removes cars that could not have sent msg.
|
||||
|
||||
Inputs:
|
||||
msg: A cereal/log CanData message from the car.
|
||||
candidate_cars: A list of cars to consider.
|
||||
|
||||
Returns:
|
||||
A list containing the subset of candidate_cars that could have sent msg.
|
||||
"""
|
||||
compatible_cars = []
|
||||
for car_name in candidate_cars:
|
||||
adr = msg.address
|
||||
if msg.src != 0 or (adr in _FINGERPRINTS[car_name] and
|
||||
_FINGERPRINTS[car_name][adr] == len(msg.dat)):
|
||||
compatible_cars.append(car_name)
|
||||
else:
|
||||
pass
|
||||
#isin = adr in _FINGERPRINTS[car_name]
|
||||
#print "eliminate", car_name, hex(adr), isin, len(msg.dat), msg.dat.encode("hex")
|
||||
return compatible_cars
|
||||
|
||||
def all_known_cars():
|
||||
"""Returns a list of all known car strings."""
|
||||
return _FINGERPRINTS.keys()
|
||||
|
||||
# **** for use live only ****
|
||||
def fingerprint(logcan):
|
||||
import selfdrive.messaging as messaging
|
||||
from cereal import car
|
||||
from common.realtime import sec_since_boot
|
||||
import os
|
||||
if os.getenv("SIMULATOR") is not None or logcan is None:
|
||||
# send message
|
||||
ret = car.CarParams.new_message()
|
||||
|
||||
ret.carName = "simulator"
|
||||
ret.radarName = "nidec"
|
||||
ret.carFingerprint = "THE LOW QUALITY SIMULATOR"
|
||||
|
||||
ret.enableSteer = True
|
||||
ret.enableBrake = True
|
||||
ret.enableGas = True
|
||||
ret.enableCruise = False
|
||||
|
||||
ret.wheelBase = 2.67
|
||||
ret.steerRatio = 15.3
|
||||
ret.slipFactor = 0.0014
|
||||
|
||||
ret.steerKp, ret.steerKi = 12.0, 1.0
|
||||
return ret
|
||||
|
||||
print "waiting for fingerprint..."
|
||||
brake_only = True
|
||||
|
||||
candidate_cars = all_known_cars()
|
||||
finger = {}
|
||||
st = None
|
||||
while 1:
|
||||
for a in messaging.drain_sock(logcan, wait_for_one=True):
|
||||
if st is None:
|
||||
st = sec_since_boot()
|
||||
for can in a.can:
|
||||
# pedal
|
||||
if can.address == 0x201 and can.src == 0:
|
||||
brake_only = False
|
||||
if can.src == 0:
|
||||
finger[can.address] = len(can.dat)
|
||||
candidate_cars = eliminate_incompatible_cars(can, candidate_cars)
|
||||
|
||||
# if we only have one car choice and it's been 100ms since we got our first message, exit
|
||||
if len(candidate_cars) == 1 and st is not None and (sec_since_boot()-st) > 0.1:
|
||||
break
|
||||
elif len(candidate_cars) == 0:
|
||||
print map(hex, finger.keys())
|
||||
raise Exception("car doesn't match any fingerprints")
|
||||
|
||||
print "fingerprinted", candidate_cars[0]
|
||||
|
||||
# send message
|
||||
ret = car.CarParams.new_message()
|
||||
|
||||
ret.carName = "honda"
|
||||
ret.radarName = "nidec"
|
||||
ret.carFingerprint = candidate_cars[0]
|
||||
|
||||
ret.enableSteer = True
|
||||
ret.enableBrake = True
|
||||
ret.enableGas = not brake_only
|
||||
ret.enableCruise = brake_only
|
||||
#ret.enableCruise = False
|
||||
|
||||
ret.wheelBase = 2.67
|
||||
ret.steerRatio = 15.3
|
||||
ret.slipFactor = 0.0014
|
||||
|
||||
if candidate_cars[0] == "HONDA CIVIC 2016 TOURING":
|
||||
ret.steerKp, ret.steerKi = 12.0, 1.0
|
||||
elif candidate_cars[0] == "ACURA ILX 2016 ACURAWATCH PLUS":
|
||||
if not brake_only:
|
||||
# assuming if we have an interceptor we also have a torque mod
|
||||
ret.steerKp, ret.steerKi = 6.0, 0.5
|
||||
else:
|
||||
ret.steerKp, ret.steerKi = 12.0, 1.0
|
||||
elif candidate_cars[0] == "HONDA ACCORD 2016 TOURING":
|
||||
ret.steerKp, ret.steerKi = 12.0, 1.0
|
||||
elif candidate_cars[0] == "HONDA CR-V 2016 TOURING":
|
||||
ret.steerKp, ret.steerKi = 6.0, 0.5
|
||||
else:
|
||||
raise ValueError("unsupported car %s" % candidate_cars[0])
|
||||
|
||||
return ret
|
||||
@@ -8,6 +8,14 @@ from threading import local
|
||||
from collections import OrderedDict
|
||||
from contextlib import contextmanager
|
||||
|
||||
def json_handler(obj):
|
||||
# if isinstance(obj, (datetime.date, datetime.time)):
|
||||
# return obj.isoformat()
|
||||
return repr(obj)
|
||||
|
||||
def json_robust_dumps(obj):
|
||||
return json.dumps(obj, default=json_handler)
|
||||
|
||||
class SwagFormatter(logging.Formatter):
|
||||
def __init__(self, swaglogger):
|
||||
logging.Formatter.__init__(self, None, '%a %b %d %H:%M:%S %Z %Y')
|
||||
@@ -15,12 +23,7 @@ class SwagFormatter(logging.Formatter):
|
||||
self.swaglogger = swaglogger
|
||||
self.host = socket.gethostname()
|
||||
|
||||
def json_handler(self, obj):
|
||||
# if isinstance(obj, (datetime.date, datetime.time)):
|
||||
# return obj.isoformat()
|
||||
return repr(obj)
|
||||
|
||||
def format(self, record):
|
||||
def format_dict(self, record):
|
||||
record_dict = OrderedDict()
|
||||
|
||||
if isinstance(record.msg, dict):
|
||||
@@ -50,9 +53,10 @@ class SwagFormatter(logging.Formatter):
|
||||
record_dict['threadName'] = record.threadName
|
||||
record_dict['created'] = record.created
|
||||
|
||||
# asctime = self.formatTime(record, self.datefmt)
|
||||
return record_dict
|
||||
|
||||
return json.dumps(record_dict, default=self.json_handler)
|
||||
def format(self, record):
|
||||
return json_robust_dumps(self.format_dict(record))
|
||||
|
||||
_tmpfunc = lambda: 0
|
||||
_srcfile = os.path.normcase(_tmpfunc.__code__.co_filename)
|
||||
|
||||
289
common/params.py
Executable file
289
common/params.py
Executable file
@@ -0,0 +1,289 @@
|
||||
#!/usr/bin/env python
|
||||
"""ROS has a parameter server, we have files.
|
||||
|
||||
The parameter store is a persistent key value store, implemented as a directory with a writer lock.
|
||||
On Android, we store params under params_dir = /data/params. The writer lock is a file
|
||||
"<params_dir>/.lock" taken using flock(), and data is stored in a directory symlinked to by
|
||||
"<params_dir>/d".
|
||||
|
||||
Each key, value pair is stored as a file with named <key> with contents <value>, located in
|
||||
<params_dir>/d/<key>
|
||||
|
||||
Readers of a single key can just open("<params_dir>/d/<key>") and read the file contents.
|
||||
Readers who want a consistent snapshot of multiple keys should take the lock.
|
||||
|
||||
Writers should take the lock before modifying anything. Writers should also leave the DB in a
|
||||
consistent state after a crash. The implementation below does this by copying all params to a temp
|
||||
directory <params_dir>/<tmp>, then atomically symlinking <params_dir>/<d> to <params_dir>/<tmp>
|
||||
before deleting the old <params_dir>/<d> directory.
|
||||
|
||||
Writers that only modify a single key can simply take the lock, then swap the corresponding value
|
||||
file in place without messing with <params_dir>/d.
|
||||
"""
|
||||
import time
|
||||
import os
|
||||
import errno
|
||||
import sys
|
||||
import shutil
|
||||
import fcntl
|
||||
import tempfile
|
||||
from enum import Enum
|
||||
|
||||
def mkdirs_exists_ok(path):
|
||||
try:
|
||||
os.makedirs(path)
|
||||
except OSError:
|
||||
if not os.path.isdir(path):
|
||||
raise
|
||||
|
||||
class TxType(Enum):
|
||||
PERSISTANT = 1
|
||||
CLEAR_ON_MANAGER_START = 2
|
||||
CLEAR_ON_CAR_START = 3
|
||||
|
||||
class UnknownKeyName(Exception):
|
||||
pass
|
||||
|
||||
keys = {
|
||||
# written: manager
|
||||
# read: loggerd, uploaderd, baseui
|
||||
"DongleId": TxType.PERSISTANT,
|
||||
"AccessToken": TxType.PERSISTANT,
|
||||
"Version": TxType.PERSISTANT,
|
||||
"GitCommit": TxType.PERSISTANT,
|
||||
"GitBranch": TxType.PERSISTANT,
|
||||
# written: baseui
|
||||
# read: ui, controls
|
||||
"IsMetric": TxType.PERSISTANT,
|
||||
"IsRearViewMirror": TxType.PERSISTANT,
|
||||
# written: visiond
|
||||
# read: visiond
|
||||
"CalibrationParams": TxType.PERSISTANT,
|
||||
# written: visiond
|
||||
# read: visiond, ui
|
||||
"CloudCalibration": TxType.PERSISTANT,
|
||||
# written: controlsd
|
||||
# read: radard
|
||||
"CarParams": TxType.CLEAR_ON_CAR_START}
|
||||
|
||||
|
||||
class FileLock(object):
|
||||
def __init__(self, path, create):
|
||||
self._path = path
|
||||
self._create = create
|
||||
self._fd = None
|
||||
|
||||
def acquire(self):
|
||||
self._fd = os.open(self._path, os.O_CREAT if self._create else 0)
|
||||
fcntl.flock(self._fd, fcntl.LOCK_EX)
|
||||
|
||||
def release(self):
|
||||
if self._fd is not None:
|
||||
os.close(self._fd)
|
||||
self._fd = None
|
||||
|
||||
|
||||
class DBAccessor(object):
|
||||
def __init__(self, path):
|
||||
self._path = path
|
||||
self._vals = None
|
||||
|
||||
def keys(self):
|
||||
self._check_entered()
|
||||
return self._vals.keys()
|
||||
|
||||
def get(self, key):
|
||||
self._check_entered()
|
||||
try:
|
||||
return self._vals[key]
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
def _get_lock(self, create):
|
||||
lock = FileLock(os.path.join(self._path, ".lock"), create)
|
||||
lock.acquire()
|
||||
return lock
|
||||
|
||||
def _read_values_locked(self):
|
||||
"""Callers should hold a lock while calling this method."""
|
||||
vals = {}
|
||||
try:
|
||||
data_path = self._data_path()
|
||||
keys = os.listdir(data_path)
|
||||
for key in keys:
|
||||
with open(os.path.join(data_path, key), "rb") as f:
|
||||
vals[key] = f.read()
|
||||
except (OSError, IOError) as e:
|
||||
# Either the DB hasn't been created yet, or somebody wrote a bug and left the DB in an
|
||||
# inconsistent state. Either way, return empty.
|
||||
if e.errno == errno.ENOENT:
|
||||
return {}
|
||||
|
||||
return vals
|
||||
|
||||
def _data_path(self):
|
||||
return os.path.join(self._path, "d")
|
||||
|
||||
def _check_entered(self):
|
||||
if self._vals is None:
|
||||
raise Exception("Must call __enter__ before using DB")
|
||||
|
||||
|
||||
class DBReader(DBAccessor):
|
||||
def __enter__(self):
|
||||
try:
|
||||
lock = self._get_lock(False)
|
||||
except OSError as e:
|
||||
# Do not create lock if it does not exist.
|
||||
if e.errno == errno.ENOENT:
|
||||
self._vals = {}
|
||||
return self
|
||||
|
||||
try:
|
||||
# Read everything.
|
||||
self._vals = self._read_values_locked()
|
||||
return self
|
||||
finally:
|
||||
lock.release()
|
||||
|
||||
def __exit__(self, type, value, traceback): pass
|
||||
|
||||
|
||||
class DBWriter(DBAccessor):
|
||||
def __init__(self, path):
|
||||
super(DBWriter, self).__init__(path)
|
||||
self._lock = None
|
||||
self._prev_umask = None
|
||||
|
||||
def put(self, key, value):
|
||||
self._vals[key] = value
|
||||
|
||||
def delete(self, key):
|
||||
self._vals.pop(key, None)
|
||||
|
||||
def __enter__(self):
|
||||
mkdirs_exists_ok(self._path)
|
||||
|
||||
# Make sure we can write and that permissions are correct.
|
||||
self._prev_umask = os.umask(0)
|
||||
|
||||
try:
|
||||
os.chmod(self._path, 0o777)
|
||||
self._lock = self._get_lock(True)
|
||||
self._vals = self._read_values_locked()
|
||||
except:
|
||||
os.umask(self._prev_umask)
|
||||
self._prev_umask = None
|
||||
raise
|
||||
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
self._check_entered()
|
||||
|
||||
try:
|
||||
old_data_path = None
|
||||
new_data_path = None
|
||||
tempdir_path = tempfile.mkdtemp(prefix=".tmp", dir=self._path)
|
||||
try:
|
||||
# Write back all keys.
|
||||
os.chmod(tempdir_path, 0o777)
|
||||
for k, v in self._vals.items():
|
||||
with open(os.path.join(tempdir_path, k), "wb") as f:
|
||||
f.write(v)
|
||||
|
||||
data_path = self._data_path()
|
||||
try:
|
||||
old_data_path = os.path.join(self._path, os.readlink(data_path))
|
||||
except (OSError, IOError) as e:
|
||||
# NOTE(mgraczyk): If other DB implementations have bugs, this could cause
|
||||
# copies to be left behind, but we still want to overwrite.
|
||||
pass
|
||||
|
||||
new_data_path = "{}.link".format(tempdir_path)
|
||||
os.symlink(os.path.basename(tempdir_path), new_data_path)
|
||||
os.rename(new_data_path, data_path)
|
||||
# TODO(mgraczyk): raise useful error when values are bad.
|
||||
except:
|
||||
shutil.rmtree(tempdir_path)
|
||||
if new_data_path is not None:
|
||||
os.remove(new_data_path)
|
||||
raise
|
||||
|
||||
# Keep holding the lock while we clean up the old data.
|
||||
if old_data_path is not None:
|
||||
shutil.rmtree(old_data_path)
|
||||
finally:
|
||||
os.umask(self._prev_umask)
|
||||
self._prev_umask = None
|
||||
|
||||
# Always release the lock.
|
||||
self._lock.release()
|
||||
self._lock = None
|
||||
|
||||
|
||||
|
||||
class JSDB(object):
|
||||
def __init__(self, fn):
|
||||
self._fn = fn
|
||||
|
||||
def begin(self, write=False):
|
||||
if write:
|
||||
return DBWriter(self._fn)
|
||||
else:
|
||||
return DBReader(self._fn)
|
||||
|
||||
class Params(object):
|
||||
def __init__(self, db='/data/params'):
|
||||
self.env = JSDB(db)
|
||||
|
||||
def _clear_keys_with_type(self, tx_type):
|
||||
with self.env.begin(write=True) as txn:
|
||||
for key in keys:
|
||||
if keys[key] == tx_type:
|
||||
txn.delete(key)
|
||||
|
||||
def manager_start(self):
|
||||
self._clear_keys_with_type(TxType.CLEAR_ON_MANAGER_START)
|
||||
|
||||
def car_start(self):
|
||||
self._clear_keys_with_type(TxType.CLEAR_ON_CAR_START)
|
||||
|
||||
def get(self, key, block=False):
|
||||
if key not in keys:
|
||||
raise UnknownKeyName(key)
|
||||
|
||||
while 1:
|
||||
with self.env.begin() as txn:
|
||||
ret = txn.get(key)
|
||||
if not block or ret is not None:
|
||||
break
|
||||
# is polling really the best we can do?
|
||||
time.sleep(0.05)
|
||||
return ret
|
||||
|
||||
def put(self, key, dat):
|
||||
if key not in keys:
|
||||
raise UnknownKeyName(key)
|
||||
|
||||
with self.env.begin(write=True) as txn:
|
||||
txn.put(key, dat)
|
||||
print "set", key
|
||||
|
||||
if __name__ == "__main__":
|
||||
params = Params()
|
||||
if len(sys.argv) > 2:
|
||||
params.put(sys.argv[1], sys.argv[2])
|
||||
else:
|
||||
for k in keys:
|
||||
pp = params.get(k)
|
||||
if pp is None:
|
||||
print k, "is None"
|
||||
elif all(ord(c) < 128 and ord(c) >= 32 for c in pp):
|
||||
print k, pp
|
||||
else:
|
||||
print k, pp.encode("hex")
|
||||
|
||||
# Test multiprocess:
|
||||
# seq 0 100000 | xargs -P20 -I{} python common/params.py DongleId {} && sleep 0.05
|
||||
# while python common/params.py DongleId; do sleep 0.05; done
|
||||
26
common/profiler.py
Normal file
26
common/profiler.py
Normal file
@@ -0,0 +1,26 @@
|
||||
from common.realtime import sec_since_boot
|
||||
|
||||
class Profiler(object):
|
||||
def __init__(self, enabled=False):
|
||||
self.enabled = enabled
|
||||
self.cp = []
|
||||
self.start_time = sec_since_boot()
|
||||
self.last_time = self.start_time
|
||||
|
||||
def checkpoint(self, name):
|
||||
if not self.enabled:
|
||||
return
|
||||
tt = sec_since_boot()
|
||||
self.cp.append((name, tt - self.last_time))
|
||||
self.last_time = tt
|
||||
|
||||
def display(self):
|
||||
if not self.enabled:
|
||||
return
|
||||
print "******* Profiling *******"
|
||||
tot = 0.0
|
||||
for n, ms in self.cp:
|
||||
print "%30s: %7.2f" % (n, ms*1000.0)
|
||||
tot += ms
|
||||
print " TOTAL: %7.2f" % (tot*1000.0)
|
||||
|
||||
@@ -1,42 +1,52 @@
|
||||
"""Utilities for reading real time clocks and keeping soft real time constraints."""
|
||||
import os
|
||||
import time
|
||||
import ctypes
|
||||
import platform
|
||||
import threading
|
||||
import subprocess
|
||||
import multiprocessing
|
||||
import os
|
||||
|
||||
CLOCK_MONOTONIC_RAW = 4 # see <linux/time.h>
|
||||
from cffi import FFI
|
||||
ffi = FFI()
|
||||
ffi.cdef("""
|
||||
|
||||
typedef int clockid_t;
|
||||
struct timespec {
|
||||
long tv_sec; /* Seconds. */
|
||||
long tv_nsec; /* Nanoseconds. */
|
||||
};
|
||||
int clock_gettime (clockid_t clk_id, struct timespec *tp);
|
||||
|
||||
long syscall(long number, ...);
|
||||
|
||||
"""
|
||||
)
|
||||
libc = ffi.dlopen(None)
|
||||
|
||||
|
||||
# see <linux/time.h>
|
||||
CLOCK_MONOTONIC_RAW = 4
|
||||
CLOCK_BOOTTIME = 7
|
||||
|
||||
class timespec(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('tv_sec', ctypes.c_long),
|
||||
('tv_nsec', ctypes.c_long),
|
||||
]
|
||||
if hasattr(libc, 'clock_gettime'):
|
||||
c_clock_gettime = libc.clock_gettime
|
||||
|
||||
tlocal = threading.local()
|
||||
def clock_gettime(clk_id):
|
||||
if not hasattr(tlocal, 'ts'):
|
||||
tlocal.ts = ffi.new('struct timespec *')
|
||||
|
||||
try:
|
||||
libc = ctypes.CDLL('libc.so', use_errno=True)
|
||||
except OSError:
|
||||
try:
|
||||
libc = ctypes.CDLL('libc.so.6', use_errno=True)
|
||||
except OSError:
|
||||
libc = None
|
||||
ts = tlocal.ts
|
||||
|
||||
if libc is not None:
|
||||
libc.clock_gettime.argtypes = [ctypes.c_int, ctypes.POINTER(timespec)]
|
||||
|
||||
def clock_gettime(clk_id):
|
||||
if platform.system() == "darwin":
|
||||
# TODO: fix this
|
||||
r = c_clock_gettime(clk_id, ts)
|
||||
if r != 0:
|
||||
raise OSError("clock_gettime")
|
||||
return ts.tv_sec + ts.tv_nsec * 1e-9
|
||||
else:
|
||||
# hack. only for OS X < 10.12
|
||||
def clock_gettime(clk_id):
|
||||
return time.time()
|
||||
else:
|
||||
t = timespec()
|
||||
if libc.clock_gettime(clk_id, ctypes.pointer(t)) != 0:
|
||||
errno_ = ctypes.get_errno()
|
||||
raise OSError(errno_, os.strerror(errno_))
|
||||
return t.tv_sec + t.tv_nsec * 1e-9
|
||||
|
||||
def monotonic_time():
|
||||
return clock_gettime(CLOCK_MONOTONIC_RAW)
|
||||
@@ -47,7 +57,7 @@ def sec_since_boot():
|
||||
|
||||
def set_realtime_priority(level):
|
||||
if os.getuid() != 0:
|
||||
print "not setting priority, not root"
|
||||
print("not setting priority, not root")
|
||||
return
|
||||
if platform.machine() == "x86_64":
|
||||
NR_gettid = 186
|
||||
@@ -80,15 +90,22 @@ class Ratekeeper(object):
|
||||
|
||||
# Maintain loop rate by calling this at the end of each loop
|
||||
def keep_time(self):
|
||||
self.monitor_time()
|
||||
lagged = self.monitor_time()
|
||||
if self._remaining > 0:
|
||||
time.sleep(self._remaining)
|
||||
return lagged
|
||||
|
||||
# this only monitor the cumulative lag, but does not enforce a rate
|
||||
def monitor_time(self):
|
||||
lagged = False
|
||||
remaining = self._next_frame_time - sec_since_boot()
|
||||
self._next_frame_time += self._interval
|
||||
if remaining < -self._print_delay_threshold:
|
||||
print self._process_name, "lagging by", round(-remaining * 1000, 2), "ms"
|
||||
print("%s lagging by %.2f ms" % (self._process_name, -remaining * 1000))
|
||||
lagged = True
|
||||
self._frame += 1
|
||||
self._remaining = remaining
|
||||
return lagged
|
||||
|
||||
if __name__ == "__main__":
|
||||
print sec_since_boot()
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
# TODO: these port numbers are hardcoded in c, fix this
|
||||
|
||||
# LogRotate: 8001 is a PUSH PULL socket between loggerd and visiond
|
||||
|
||||
class Service(object):
|
||||
def __init__(self, port, should_log):
|
||||
self.port = port
|
||||
self.should_log = should_log
|
||||
|
||||
# all ZMQ pub sub
|
||||
service_list = {
|
||||
# frame syncing packet
|
||||
"frame": Service(8002, True),
|
||||
# accel, gyro, and compass
|
||||
"sensorEvents": Service(8003, True),
|
||||
# GPS data, also global timestamp
|
||||
"gpsNMEA": Service(8004, True),
|
||||
# CPU+MEM+GPU+BAT temps
|
||||
"thermal": Service(8005, True),
|
||||
# List(CanData), list of can messages
|
||||
"can": Service(8006, True),
|
||||
"live100": Service(8007, True),
|
||||
# random events we want to log
|
||||
#"liveEvent": Service(8008, True),
|
||||
"model": Service(8009, True),
|
||||
"features": Service(8010, True),
|
||||
"health": Service(8011, True),
|
||||
"live20": Service(8012, True),
|
||||
#"liveUI": Service(8014, True),
|
||||
"encodeIdx": Service(8015, True),
|
||||
"liveTracks": Service(8016, True),
|
||||
"sendcan": Service(8017, True),
|
||||
"logMessage": Service(8018, True),
|
||||
"liveCalibration": Service(8019, True),
|
||||
"androidLog": Service(8020, True),
|
||||
}
|
||||
|
||||
# manager -- base process to manage starting and stopping of all others
|
||||
# subscribes: health
|
||||
# publishes: thermal
|
||||
|
||||
# **** processes that communicate with the outside world ****
|
||||
|
||||
# boardd -- communicates with the car
|
||||
# subscribes: sendcan
|
||||
# publishes: can, health
|
||||
|
||||
# sensord -- publishes the IMU and GPS
|
||||
# publishes: sensorEvents, gpsNMEA
|
||||
|
||||
# visiond -- talks to the cameras, runs the model, saves the videos
|
||||
# subscribes: liveCalibration, sensorEvents
|
||||
# publishes: frame, encodeIdx, model, features
|
||||
|
||||
# **** stateful data transformers ****
|
||||
|
||||
# controlsd -- actually drives the car
|
||||
# subscribes: can, thermal, model, live20
|
||||
# publishes: sendcan, live100
|
||||
|
||||
# radard -- processes the radar data
|
||||
# subscribes: can, live100, model
|
||||
# publishes: live20, liveTracks
|
||||
|
||||
# calibrationd -- places the camera box
|
||||
# subscribes: features, live100
|
||||
# publishes: liveCalibration
|
||||
|
||||
# **** LOGGING SERVICE ****
|
||||
|
||||
# loggerd
|
||||
# subscribes: EVERYTHING
|
||||
|
||||
# **** NON VITAL SERVICES ****
|
||||
|
||||
# ui
|
||||
# subscribes: live100, live20, liveCalibration, model, (raw frames)
|
||||
|
||||
# uploader
|
||||
# communicates through file system with loggerd
|
||||
|
||||
# logmessaged -- central logging service, can log to cloud
|
||||
# publishes: logMessage
|
||||
|
||||
# logcatd -- fetches logcat info from android
|
||||
# publishes: androidLog
|
||||
|
||||
9
common/testing.py
Normal file
9
common/testing.py
Normal file
@@ -0,0 +1,9 @@
|
||||
import os
|
||||
from nose.tools import nottest
|
||||
|
||||
def phone_only(x):
|
||||
if os.path.isfile("/init.qcom.rc"):
|
||||
return x
|
||||
else:
|
||||
return nottest(x)
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
import os
|
||||
DBC_PATH = os.path.dirname(os.path.abspath(__file__))
|
||||
@@ -1,295 +0,0 @@
|
||||
VERSION ""
|
||||
|
||||
|
||||
NS_ :
|
||||
NS_DESC_
|
||||
CM_
|
||||
BA_DEF_
|
||||
BA_
|
||||
VAL_
|
||||
CAT_DEF_
|
||||
CAT_
|
||||
FILTER
|
||||
BA_DEF_DEF_
|
||||
EV_DATA_
|
||||
ENVVAR_DATA_
|
||||
SGTYPE_
|
||||
SGTYPE_VAL_
|
||||
BA_DEF_SGTYPE_
|
||||
BA_SGTYPE_
|
||||
SIG_TYPE_REF_
|
||||
VAL_TABLE_
|
||||
SIG_GROUP_
|
||||
SIG_VALTYPE_
|
||||
SIGTYPE_VALTYPE_
|
||||
BO_TX_BU_
|
||||
BA_DEF_REL_
|
||||
BA_REL_
|
||||
BA_DEF_DEF_REL_
|
||||
BU_SG_REL_
|
||||
BU_EV_REL_
|
||||
BU_BO_REL_
|
||||
SG_MUL_VAL_
|
||||
|
||||
BS_:
|
||||
|
||||
BO_ 0x039 XXX: 3 XXX
|
||||
|
||||
BO_ 0x091 XXX: 8 XXX
|
||||
SG_ LAT_ACCEL : 0|10@1+ (0.02,-512) [-20|20] "m/s2" Vector__XXX
|
||||
|
||||
BO_ 0x0E4 STEERING_CONTROL: 5 ADAS
|
||||
SG_ STEER_TORQUE : 0|16@1- (1,0) [-3840|3840] "" Vector__XXX
|
||||
SG_ STEER_TORQUE_REQUEST : 16|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ SET_ME_X00 : 17|7@1+ (1,0) [0|127] "" Vector__XXX
|
||||
SG_ SET_ME_X00 : 24|8@1+ (1,0) [0|0] "" Vector__XXX
|
||||
SG_ COUNTER : 34|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 36|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x130 GAS_PEDAL2: 8 PCM
|
||||
SG_ ENGINE_TORQUE_ESTIMATE : 0|16@1- (1,0) [-1000|1000] "Nm" Vector__XXX
|
||||
SG_ ENGINE_TORQUE_REQUEST : 16|16@1- (1,0) [-1000|1000] "Nm" Vector__XXX
|
||||
SG_ CAR_GAS : 32|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
|
||||
BO_ 0x13C GAS_PEDAL: 8 PCM
|
||||
SG_ CAR_GAS : 32|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
|
||||
BO_ 0x156 STEERING_SENSORS: 6 EPS
|
||||
SG_ STEER_ANGLE : 0|16@1- (-0.1,0) [-500|500] "deg" Vector__XXX
|
||||
SG_ STEER_ANGLE_RATE : 16|16@1- (1,0) [-3000|3000] "deg/s" Vector__XXX
|
||||
SG_ COUNTER : 42|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 44|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x158 POWERTRAIN_DATA: 8 PCM
|
||||
SG_ XMISSION_SPEED : 0|16@1+ (0.002759506,0) [0|70] "m/s" Vector__XXX
|
||||
SG_ ENGINE_RPM : 16|16@1+ (1,0) [0|15000] "rpm" Vector__XXX
|
||||
SG_ XMISSION_SPEED2 : 32|16@1+ (0.002759506,0) [0|70] "m/s" Vector__XXX
|
||||
SG_ COUNTER : 58|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x17C POWERTRAIN_DATA2: 8 PCM
|
||||
SG_ PEDAL_GAS : 0|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ ENGINE_RPM : 16|16@1+ (1,0) [0|15000] "rpm" Vector__XXX
|
||||
SG_ GAS_PRESSED : 32|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ ACC_STATUS : 33|1@1+ (1,0) [0|1] "rpm" Vector__XXX
|
||||
SG_ BOH_17C : 34|5@1+ (1,0) [0|1] "rpm" Vector__XXX
|
||||
SG_ BRAKE_LIGHTS_ON : 39|1@1+ (1,0) [0|1] "rpm" Vector__XXX
|
||||
SG_ BOH2_17C : 40|10@1+ (1,0) [0|1] "rpm" Vector__XXX
|
||||
SG_ BRAKE_PRESSED : 50|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ BOH3_17C : 51|5@1+ (1,0) [0|1] "rpm" Vector__XXX
|
||||
SG_ COUNTER : 58|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x18E XXX: 3 XXX
|
||||
|
||||
BO_ 0x18F STEER_STATUS: 7 EPS
|
||||
SG_ STEER_TORQUE_SENSOR : 0|16@1- (1,0) [-31000|31000] "tbd" Vector__XXX
|
||||
SG_ STEER_TORQUE_MOTOR : 16|16@1- (1,0) [-31000|31000] "tbd" Vector__XXX
|
||||
SG_ STEER_STATUS : 32|4@1+ (1,0) [0|15] "" Vector__XXX
|
||||
SG_ STEER_CONTROL_ACTIVE : 36|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ COUNTER : 50|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 52|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x1A3 GEARBOX: 8 PCM
|
||||
SG_ GEAR : 0|8@1+ (1,0) [0|256] "" Vector__XXX
|
||||
SG_ GEAR_SHIFTER : 36|4@1+ (1,0) [0|15] "" Vector__XXX
|
||||
SG_ COUNTER : 58|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x1A4 VSA_STATUS: 8 VSA
|
||||
SG_ USER_BRAKE : 0|16@1+ (0.015625,-103) [0|1000] "" Vector__XXX
|
||||
SG_ ESP_DISABLED : 27|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ COUNTER : 58|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x1A6 SCM_BUTTONS: 8 SCM
|
||||
SG_ CRUISE_BUTTONS : 0|3@1+ (1,0) [0|7] "" Vector__XXX
|
||||
SG_ LIGHTS_SETTING : 6|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ MAIN_ON : 40|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ CRUISE_SETTING : 44|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ COUNTER : 58|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x1AC XXX: 8 XXX
|
||||
|
||||
BO_ 0x1B0 STANDSTILL: 7 VSA
|
||||
SG_ WHEELS_MOVING : 11|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ BRAKE_ERROR_1 : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ BRAKE_ERROR_2 : 14|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ COUNTER : 50|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 52|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x1D0 WHEEL_SPEEDS: 8 VSA
|
||||
SG_ WHEEL_SPEED_FL : 0|15@1+ (0.002759506,0) [0|70] "m/s" Vector__XXX
|
||||
SG_ WHEEL_SPEED_FR : 15|15@1+ (0.002759506,0) [0|70] "m/s" Vector__XXX
|
||||
SG_ WHEEL_SPEED_RL : 30|15@1+ (0.002759506,0) [0|70] "m/s" Vector__XXX
|
||||
SG_ WHEEL_SPEED_RR : 45|15@1+ (0.002759506,0) [0|70] "m/s" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x1DC XXX: 4 XXX
|
||||
|
||||
BO_ 0x1EA VEHICLE_DYNAMICS: 8 VSA
|
||||
SG_ LONG_ACCEL : 16|16@1- (0.0015384,0) [-20|20] "m/s2" Vector__XXX
|
||||
|
||||
BO_ 0x1FA BRAKE_COMMAND: 8 ADAS
|
||||
SG_ COMPUTER_BRAKE : 0|10@1+ (0.003906248,0) [0|1] "" Vector__XXX
|
||||
SG_ ZEROS_BOH : 10|5@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ COMPUTER_BRAKE_REQUEST : 15|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ CRUISE_BOH2 : 16|3@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ CRUISE_OVERRIDE : 19|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ CRUISE_BOH3 : 20|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ CRUISE_FAULT_CMD : 21|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ CRUISE_CANCEL_CMD : 22|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ COMPUTER_BRAKE_REQUEST_2 : 23|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ CRUISE_BOH4 : 24|8@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ BRAKE_LIGHTS : 32|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ CRUISE_BOH5 : 33|7@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ CHIME : 40|3@1+ (1,0) [0|7] "" Vector__XXX
|
||||
SG_ CRUISE_BOH6 : 43|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ FCW : 44|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CRUISE_BOH7 : 46|10@1+ (1,0) [0|0] "" Vector__XXX
|
||||
SG_ COUNTER : 58|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x200 GAS_COMMAND: 3 ADAS
|
||||
SG_ GAS_COMMAND : 0|16@1+ (0.253984064,-328) [0|1] "" Vector__XXX
|
||||
SG_ COUNTER : 18|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 20|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x201 GAS_SENSOR: 5 ADAS
|
||||
SG_ INTERCEPTOR_GAS : 0|16@1+ (0.253984064,-328) [0|1] "" Vector__XXX
|
||||
SG_ INTERCEPTOR_GAS2 : 16|16@1+ (0.126992032,-656) [0|1] "" Vector__XXX
|
||||
SG_ COUNTER : 34|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 36|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x21E XXX: 7 XXX
|
||||
BO_ 0x221 XXX: 4 XXX
|
||||
|
||||
BO_ 0x255 ROUGH_WHEEL_SPEED: 8 VSA
|
||||
SG_ WHEEL_SPEED_FL : 0|8@1+ (1,0) [0|255] "mph" Vector__XXX
|
||||
SG_ WHEEL_SPEED_FR : 8|8@1+ (1,0) [0|255] "mph" Vector__XXX
|
||||
SG_ WHEEL_SPEED_RL : 16|8@1+ (1,0) [0|255] "mph" Vector__XXX
|
||||
SG_ WHEEL_SPEED_RR : 24|8@1+ (1,0) [0|255] "mph" Vector__XXX
|
||||
SG_ SET_TO_X55 : 32|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ SET_TO_X55 : 40|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
|
||||
BO_ 0x294 SCM_COMMANDS: 8 SCM
|
||||
SG_ RIGHT_BLINKER : 1|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LEFT_BLINKER : 2|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ WIPERS_SPEED : 3|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x305 SEATBELT_STATUS: 7 BDY
|
||||
SG_ SEATBELT_DRIVER_LAMP : 0|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ SEATBELT_DRIVER_LATCHED : 10|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ COUNTER : 50|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 52|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x309 XXX: 8 XXX
|
||||
|
||||
BO_ 0x30C ACC_HUD: 8 ADAS
|
||||
SG_ PCM_SPEED : 0|16@1+ (0.002763889,0) [0|100] "m/s" Vector__XXX
|
||||
SG_ PCM_GAS : 16|7@1+ (1,0) [0|127] "" Vector__XXX
|
||||
SG_ ZEROS_BOH : 23|1@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ CRUISE_SPEED : 24|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ DTC_MODE : 32|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ BOH : 33|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ ACC_PROBLEM : 34|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ FCM_OFF : 35|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ BOH_2 : 36|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ FCM_PROBLEM : 37|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ RADAR_OBSTRUCTED : 38|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ ENABLE_MINI_CAR : 39|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ SET_ME_X03 : 40|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ HUD_LEAD : 42|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ BOH_3 : 44|1@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ BOH_4 : 45|1@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ BOH_5 : 46|1@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CRUISE_CONTROL_LABEL : 47|1@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ HUD_DISTANCE_3 : 51|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ COUNTER : 58|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x320 XXX: 8 XXX
|
||||
|
||||
BO_ 0x324 CRUISE: 8 PCM
|
||||
SG_ ENGINE_TEMPERATURE : 0|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ BOH : 8|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ TRIP_FUEL_CONSUMED : 16|16@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ CRUISE_SPEED_PCM : 32|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ BOH2 : 40|8@1- (1,0) [0|255] "" Vector__XXX
|
||||
SG_ BOH3 : 48|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ COUNTER : 58|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x328 XXX: 8 XXX
|
||||
BO_ 0x333 XXX: 7 XXX
|
||||
BO_ 0x335 XXX: 5 XXX
|
||||
|
||||
BO_ 0x33D LKAS_HUD_2: 5 ADAS
|
||||
SG_ CAM_TEMP_HIGH : 0|1@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ BOH : 1|7@1+ (1,0) [0|127] "" Vector__XXX
|
||||
SG_ DASHED_LANES : 9|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ DTC : 10|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LKAS_PROBLEM : 11|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LKAS_OFF : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ SOLID_LANES : 13|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LDW_RIGHT : 14|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ STEERING_REQUIRED : 15|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ BOH : 16|2@1+ (1,0) [0|4] "" Vector__XXX
|
||||
SG_ LDW_PROBLEM : 18|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ BEEP : 22|2@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LDW_ON : 27|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LDW_OFF : 28|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ CLEAN_WINDSHIELD : 29|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ SET_ME_X48 : 24|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ COUNTER : 34|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 36|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
|
||||
BO_ 0x372 XXX: 2 XXX
|
||||
|
||||
BO_ 0x374 XXX: 7 XXX
|
||||
BO_ 0x377 XXX: 8 XXX
|
||||
BO_ 0x378 XXX: 8 XXX
|
||||
BO_ 0x37C XXX: 8 XXX
|
||||
BO_ 0x39B XXX: 2 XXX
|
||||
BO_ 0x3A1 XXX: 4 XXX
|
||||
BO_ 0x3D7 XXX: 8 XXX
|
||||
BO_ 0x3D9 XXX: 3 XXX
|
||||
BO_ 0x400 XXX: 5 XXX
|
||||
BO_ 0x403 XXX: 5 XXX
|
||||
|
||||
BO_ 0x405 DOORS_STATUS: 8 BDY
|
||||
SG_ DOOR_OPEN_FL : 34|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ DOOR_OPEN_FR : 33|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ DOOR_OPEN_RL : 32|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ DOOR_OPEN_RR : 47|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ COUNTER : 58|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x406 XXX: 5 VSA
|
||||
BO_ 0x40A XXX: 5 XXX
|
||||
BO_ 0x40C XXX: 8 XXX
|
||||
BO_ 0x40F XXX: 8 XXX
|
||||
BO_ 0x421 XXX: 5 EPS
|
||||
BO_ 0x428 XXX: 7 XXX
|
||||
BO_ 0x454 XXX: 8 XXX
|
||||
BO_ 0x555 XXX: 5 XXX
|
||||
BO_ 0x640 XXX: 5 XXX
|
||||
BO_ 0x641 XXX: 8 XXX
|
||||
|
||||
VAL_ 0x1A6 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none";
|
||||
VAL_ 0x1A6 CRUISE_SETTING 3 "distance_adj" 2 "tbd" 1 "lkas_button" 0 "none";
|
||||
VAL_ 0x30C HUD_LEAD 3 "no_car" 2 "solid_car" 1 "dashed_car" 0 "no_car";
|
||||
VAL_ 0x1A6 LIGHTS_SETTING 3 "high_beam" 2 "low_beam" 1 "position" 0 "no_lights";
|
||||
VAL_ 0x18F STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal";
|
||||
VAL_ 0x1A3 GEAR_SHIFTER 10 "S" 4 "D" 3 "N" 2 "R" 1 "P";
|
||||
VAL_ 0x33D BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep";
|
||||
VAL_ 0x1FA CHIME 4 "double_chime" 3 "single_chime" 2 "continuous_chime" 1 "repeating_chime" 0 "no_chime";
|
||||
VAL_ 0x1FA FCW 3 "fcw" 2 "fcw" 1 "fcw" 0 "no_fcw";
|
||||
|
||||
CM_ SG_ 0x1A3 GEAR "10 = reverse, 11 = transition";
|
||||
CM_ SG_ 0x324 CRUISE_SPEED_ECHO "255 = no speed";
|
||||
CM_ SG_ 0x33D CRUISE_SPEED "255 = no speed";
|
||||
CM_ SG_ 0x1EA LONG_ACCEL "wheel speed derivative, noisy and zero snapping";
|
||||
CM_ SG_ 0x33D BEEP "beeps are pleasant, chimes are for warnngs etc...";
|
||||
@@ -1,175 +0,0 @@
|
||||
VERSION ""
|
||||
|
||||
|
||||
NS_ :
|
||||
NS_DESC_
|
||||
CM_
|
||||
BA_DEF_
|
||||
BA_
|
||||
VAL_
|
||||
CAT_DEF_
|
||||
CAT_
|
||||
FILTER
|
||||
BA_DEF_DEF_
|
||||
EV_DATA_
|
||||
ENVVAR_DATA_
|
||||
SGTYPE_
|
||||
SGTYPE_VAL_
|
||||
BA_DEF_SGTYPE_
|
||||
BA_SGTYPE_
|
||||
SIG_TYPE_REF_
|
||||
VAL_TABLE_
|
||||
SIG_GROUP_
|
||||
SIG_VALTYPE_
|
||||
SIGTYPE_VALTYPE_
|
||||
BO_TX_BU_
|
||||
BA_DEF_REL_
|
||||
BA_REL_
|
||||
BA_DEF_DEF_REL_
|
||||
BU_SG_REL_
|
||||
BU_EV_REL_
|
||||
BU_BO_REL_
|
||||
SG_MUL_VAL_
|
||||
|
||||
BS_:
|
||||
|
||||
|
||||
BO_ 0x300 VEHICLE_STATE: 8 ADAS
|
||||
SG_ SET_ME_XF9 : 0|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ VEHICLE_SPEED : 8|8@1+ (1,0) [0|255] "kph" Vector__XXX
|
||||
|
||||
BO_ 0x301 VEHICLE_STATE2: 8 ADAS
|
||||
SG_ SET_ME_0F18510 : 0|28@1+ (1,0) [0|268435455] "" Vector__XXX
|
||||
SG_ SET_ME_25A0000 : 28|28@1+ (1,0) [0|268435455] "" Vector__XXX
|
||||
|
||||
BO_ 0x400 XXX: 8 RADAR
|
||||
|
||||
BO_ 0x410 XXX: 8 RADAR
|
||||
|
||||
BO_ 0x411 XXX: 8 RADAR
|
||||
|
||||
BO_ 0x412 XXX: 8 RADAR
|
||||
|
||||
BO_ 0x413 XXX: 8 RADAR
|
||||
|
||||
BO_ 0x414 XXX: 8 RADAR
|
||||
|
||||
BO_ 0x415 XXX: 8 RADAR
|
||||
|
||||
BO_ 0x416 XXX: 8 RADAR
|
||||
|
||||
BO_ 0x417 XXX: 8 RADAR
|
||||
|
||||
BO_ 0x420 XXX: 8 RADAR
|
||||
|
||||
BO_ 0x421 XXX: 8 RADAR
|
||||
|
||||
BO_ 0x422 XXX: 8 RADAR
|
||||
|
||||
BO_ 0x423 XXX: 8 RADAR
|
||||
|
||||
BO_ 0x424 XXX: 8 RADAR
|
||||
|
||||
BO_ 0x430 TRACK_0: 8 RADAR
|
||||
SG_ LONG_DIST : 0|12@1+ (0.0625,0) [0|255.5] "m" Vector__XXX
|
||||
SG_ NEW_TRACK : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LAT_DIST : 14|10@1- (0.0625,0) [0|63.5] "m" Vector__XXX
|
||||
SG_ REL_SPEED : 24|12@1- (0.03125,0) [0|127.5] "m/s" Vector__XXX
|
||||
|
||||
BO_ 0x431 TRACK_1: 8 RADAR
|
||||
SG_ LONG_DIST : 0|12@1+ (0.0625,0) [0|255.5] "m" Vector__XXX
|
||||
SG_ NEW_TRACK : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LAT_DIST : 14|10@1- (0.0625,0) [0|63.5] "m" Vector__XXX
|
||||
SG_ REL_SPEED : 24|12@1- (0.03125,0) [0|127.5] "m/s" Vector__XXX
|
||||
|
||||
BO_ 0x432 TRACK_2: 8 RADAR
|
||||
SG_ LONG_DIST : 0|12@1+ (0.0625,0) [0|255.5] "m" Vector__XXX
|
||||
SG_ NEW_TRACK : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LAT_DIST : 14|10@1- (0.0625,0) [0|63.5] "m" Vector__XXX
|
||||
SG_ REL_SPEED : 24|12@1- (0.03125,0) [0|127.5] "m/s" Vector__XXX
|
||||
|
||||
BO_ 0x433 TRACK_3: 8 RADAR
|
||||
SG_ LONG_DIST : 0|12@1+ (0.0625,0) [0|255.5] "m" Vector__XXX
|
||||
SG_ NEW_TRACK : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LAT_DIST : 14|10@1- (0.0625,0) [0|63.5] "m" Vector__XXX
|
||||
SG_ REL_SPEED : 24|12@1- (0.03125,0) [0|127.5] "m/s" Vector__XXX
|
||||
|
||||
BO_ 0x434 TRACK_4: 8 RADAR
|
||||
SG_ LONG_DIST : 0|12@1+ (0.0625,0) [0|255.5] "m" Vector__XXX
|
||||
SG_ NEW_TRACK : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LAT_DIST : 14|10@1- (0.0625,0) [0|63.5] "m" Vector__XXX
|
||||
SG_ REL_SPEED : 24|12@1- (0.03125,0) [0|127.5] "m/s" Vector__XXX
|
||||
|
||||
BO_ 0x435 TRACK_5: 8 RADAR
|
||||
SG_ LONG_DIST : 0|12@1+ (0.0625,0) [0|255.5] "m" Vector__XXX
|
||||
SG_ NEW_TRACK : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LAT_DIST : 14|10@1- (0.0625,0) [0|63.5] "m" Vector__XXX
|
||||
SG_ REL_SPEED : 24|12@1- (0.03125,0) [0|127.5] "m/s" Vector__XXX
|
||||
|
||||
BO_ 0x436 TRACK_6: 8 RADAR
|
||||
SG_ LONG_DIST : 0|12@1+ (0.0625,0) [0|255.5] "m" Vector__XXX
|
||||
SG_ NEW_TRACK : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LAT_DIST : 14|10@1- (0.0625,0) [0|63.5] "m" Vector__XXX
|
||||
SG_ REL_SPEED : 24|12@1- (0.03125,0) [0|127.5] "m/s" Vector__XXX
|
||||
|
||||
BO_ 0x437 TRACK_7: 8 RADAR
|
||||
SG_ LONG_DIST : 0|12@1+ (0.0625,0) [0|255.5] "m" Vector__XXX
|
||||
SG_ NEW_TRACK : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LAT_DIST : 14|10@1- (0.0625,0) [0|63.5] "m" Vector__XXX
|
||||
SG_ REL_SPEED : 24|12@1- (0.03125,0) [0|127.5] "m/s" Vector__XXX
|
||||
|
||||
BO_ 0x438 TRACK_8: 8 RADAR
|
||||
SG_ LONG_DIST : 0|12@1+ (0.0625,0) [0|255.5] "m" Vector__XXX
|
||||
SG_ NEW_TRACK : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LAT_DIST : 14|10@1- (0.0625,0) [0|63.5] "m" Vector__XXX
|
||||
SG_ REL_SPEED : 24|12@1- (0.03125,0) [0|127.5] "m/s" Vector__XXX
|
||||
|
||||
BO_ 0x439 TRACK_9: 8 RADAR
|
||||
SG_ LONG_DIST : 0|12@1+ (0.0625,0) [0|255.5] "m" Vector__XXX
|
||||
SG_ NEW_TRACK : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LAT_DIST : 14|10@1- (0.0625,0) [0|63.5] "m" Vector__XXX
|
||||
SG_ REL_SPEED : 24|12@1- (0.03125,0) [0|127.5] "m/s" Vector__XXX
|
||||
|
||||
BO_ 0x440 TRACK_10: 8 RADAR
|
||||
SG_ LONG_DIST : 0|12@1+ (0.0625,0) [0|255.5] "m" Vector__XXX
|
||||
SG_ NEW_TRACK : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LAT_DIST : 14|10@1- (0.0625,0) [0|63.5] "m" Vector__XXX
|
||||
SG_ REL_SPEED : 24|12@1- (0.03125,0) [0|127.5] "m/s" Vector__XXX
|
||||
|
||||
BO_ 0x441 TRACK_11: 8 RADAR
|
||||
SG_ LONG_DIST : 0|12@1+ (0.0625,0) [0|255.5] "m" Vector__XXX
|
||||
SG_ NEW_TRACK : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LAT_DIST : 14|10@1- (0.0625,0) [0|63.5] "m" Vector__XXX
|
||||
SG_ REL_SPEED : 24|12@1- (0.03125,0) [0|127.5] "m/s" Vector__XXX
|
||||
|
||||
BO_ 0x442 TRACK_12: 8 RADAR
|
||||
SG_ LONG_DIST : 0|12@1+ (0.0625,0) [0|255.5] "m" Vector__XXX
|
||||
SG_ NEW_TRACK : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LAT_DIST : 14|10@1- (0.0625,0) [0|63.5] "m" Vector__XXX
|
||||
SG_ REL_SPEED : 24|12@1- (0.03125,0) [0|127.5] "m/s" Vector__XXX
|
||||
|
||||
BO_ 0x443 TRACK_13: 8 RADAR
|
||||
SG_ LONG_DIST : 0|12@1+ (0.0625,0) [0|255.5] "m" Vector__XXX
|
||||
SG_ NEW_TRACK : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LAT_DIST : 14|10@1- (0.0625,0) [0|63.5] "m" Vector__XXX
|
||||
SG_ REL_SPEED : 24|12@1- (0.03125,0) [0|127.5] "m/s" Vector__XXX
|
||||
|
||||
BO_ 0x444 TRACK_14: 8 RADAR
|
||||
SG_ LONG_DIST : 0|12@1+ (0.0625,0) [0|255.5] "m" Vector__XXX
|
||||
SG_ NEW_TRACK : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LAT_DIST : 14|10@1- (0.0625,0) [0|63.5] "m" Vector__XXX
|
||||
SG_ REL_SPEED : 24|12@1- (0.03125,0) [0|127.5] "m/s" Vector__XXX
|
||||
|
||||
BO_ 0x445 TRACK_15: 8 RADAR
|
||||
SG_ LONG_DIST : 0|12@1+ (0.0625,0) [0|255.5] "m" Vector__XXX
|
||||
SG_ NEW_TRACK : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LAT_DIST : 14|10@1- (0.0625,0) [0|63.5] "m" Vector__XXX
|
||||
SG_ REL_SPEED : 24|12@1- (0.03125,0) [0|127.5] "m/s" Vector__XXX
|
||||
|
||||
BO_ 0x4FF XXX: 8 RADAR
|
||||
|
||||
BO_ 0x500 XXX: 8 RADAR
|
||||
|
||||
BO_ 0x510 XXX: 8 RADAR
|
||||
|
||||
BO_ 0x511 XXX: 8 RADAR
|
||||
@@ -1,319 +0,0 @@
|
||||
VERSION ""
|
||||
|
||||
|
||||
NS_ :
|
||||
NS_DESC_
|
||||
CM_
|
||||
BA_DEF_
|
||||
BA_
|
||||
VAL_
|
||||
CAT_DEF_
|
||||
CAT_
|
||||
FILTER
|
||||
BA_DEF_DEF_
|
||||
EV_DATA_
|
||||
ENVVAR_DATA_
|
||||
SGTYPE_
|
||||
SGTYPE_VAL_
|
||||
BA_DEF_SGTYPE_
|
||||
BA_SGTYPE_
|
||||
SIG_TYPE_REF_
|
||||
VAL_TABLE_
|
||||
SIG_GROUP_
|
||||
SIG_VALTYPE_
|
||||
SIGTYPE_VALTYPE_
|
||||
BO_TX_BU_
|
||||
BA_DEF_REL_
|
||||
BA_REL_
|
||||
BA_DEF_DEF_REL_
|
||||
BU_SG_REL_
|
||||
BU_EV_REL_
|
||||
BU_BO_REL_
|
||||
SG_MUL_VAL_
|
||||
|
||||
BS_:
|
||||
|
||||
BO_ 0x039 XXX: 3 XXX
|
||||
|
||||
BO_ 0x94 XXX: 8 XXX
|
||||
SG_ LAT_ACCEL : 0|10@1+ (0.02,-512) [-20|20] "m/s2" Vector__XXX
|
||||
SG_ LONG_ACCEL : 31|9@1- (-0.02,0) [-20|20] "m/s2" Vector__XXX
|
||||
|
||||
BO_ 0x0E4 STEERING_CONTROL: 5 ADAS
|
||||
SG_ STEER_TORQUE : 0|16@1- (1,0) [-3840|3840] "" Vector__XXX
|
||||
SG_ STEER_TORQUE_REQUEST : 16|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ SET_ME_X00 : 17|7@1+ (1,0) [0|127] "" Vector__XXX
|
||||
SG_ SET_ME_X00_2 : 24|8@1+ (1,0) [0|0] "" Vector__XXX
|
||||
SG_ CHECKSUM : 32|4@1+ (1,0) [0|15] "" Vector__XXX
|
||||
SG_ COUNTER : 38|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x130 GAS_PEDAL2: 8 PCM
|
||||
SG_ ENGINE_TORQUE_ESTIMATE : 0|16@1- (1,0) [-1000|1000] "Nm" Vector__XXX
|
||||
SG_ ENGINE_TORQUE_REQUEST : 16|16@1- (1,0) [-1000|1000] "Nm" Vector__XXX
|
||||
SG_ CAR_GAS : 32|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
|
||||
BO_ 0x14A STEERING_SENSORS: 8 EPS
|
||||
SG_ STEER_ANGLE : 0|16@1- (-0.1,0) [-500|500] "deg" Vector__XXX
|
||||
SG_ STEER_ANGLE_RATE : 16|16@1- (-1,0) [-3000|3000] "deg/s" Vector__XXX
|
||||
SG_ STEER_ANGLE_OFFSET : 32|8@1- (-0.1,0) [-128|127] "deg" Vector__XXX
|
||||
SG_ STEER_WHEEL_ANGLE : 40|16@1- (-0.1,0) [-500|500] "deg" Vector__XXX
|
||||
SG_ COUNTER : 58|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x158 POWERTRAIN_DATA: 8 PCM
|
||||
SG_ XMISSION_SPEED : 0|16@1+ (0.002759506,0) [0|70] "m/s" Vector__XXX
|
||||
SG_ ENGINE_RPM : 16|16@1+ (1,0) [0|15000] "rpm" Vector__XXX
|
||||
SG_ XMISSION_SPEED2 : 32|16@1+ (0.002759506,0) [0|70] "m/s" Vector__XXX
|
||||
SG_ COUNTER : 58|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x17C POWERTRAIN_DATA2: 8 PCM
|
||||
SG_ PEDAL_GAS : 0|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ ENGINE_RPM : 16|16@1+ (1,0) [0|15000] "rpm" Vector__XXX
|
||||
SG_ GAS_PRESSED : 32|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ ACC_STATUS : 33|1@1+ (1,0) [0|1] "rpm" Vector__XXX
|
||||
SG_ BOH_17C : 34|5@1+ (1,0) [0|1] "rpm" Vector__XXX
|
||||
SG_ BRAKE_LIGHTS_ON : 39|1@1+ (1,0) [0|1] "rpm" Vector__XXX
|
||||
SG_ BOH2_17C : 40|10@1+ (1,0) [0|1] "rpm" Vector__XXX
|
||||
SG_ BRAKE_PRESSED : 50|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ BOH3_17C : 51|5@1+ (1,0) [0|1] "rpm" Vector__XXX
|
||||
SG_ COUNTER : 58|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x18F STEER_STATUS: 7 EPS
|
||||
SG_ STEER_TORQUE_SENSOR : 0|16@1- (1,0) [-31000|31000] "tbd" Vector__XXX
|
||||
SG_ STEER_TORQUE_MOTOR : 16|16@1- (1,0) [-31000|31000] "tbd" Vector__XXX
|
||||
SG_ STEER_STATUS : 32|4@1+ (1,0) [0|15] "" Vector__XXX
|
||||
SG_ STEER_CONTROL_ACTIVE : 36|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ COUNTER : 50|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 52|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x191 GEARBOX: 8 PCM
|
||||
SG_ GEAR_SHIFTER : 2|6@1+ (1,0) [0|63] "" Vector__XXX
|
||||
SG_ GEAR : 36|4@1+ (1,0) [0|15] "" Vector__XXX
|
||||
SG_ COUNTER : 58|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x1A4 VSA_STATUS: 8 VSA
|
||||
SG_ USER_BRAKE : 0|16@1+ (0.015625,-103) [0|1000] "" Vector__XXX
|
||||
SG_ ESP_DISABLED : 27|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ COUNTER : 58|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x1AB XXX: 3 VSA
|
||||
|
||||
BO_ 0x1AC XXX: 8 XXX
|
||||
|
||||
BO_ 0x1B0 STANDSTILL: 7 VSA
|
||||
SG_ WHEELS_MOVING : 11|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ BRAKE_ERROR_1 : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ BRAKE_ERROR_2 : 14|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ COUNTER : 50|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 52|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x1C2 XXX: 8 EPB
|
||||
SG_ EPB_ACTIVE : 4|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ EPB_STATE : 26|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x1D0 WHEEL_SPEEDS: 8 VSA
|
||||
SG_ WHEEL_SPEED_FL : 0|15@1+ (0.002759506,0) [0|70] "m/s" Vector__XXX
|
||||
SG_ WHEEL_SPEED_FR : 15|15@1+ (0.002759506,0) [0|70] "m/s" Vector__XXX
|
||||
SG_ WHEEL_SPEED_RL : 30|15@1+ (0.002759506,0) [0|70] "m/s" Vector__XXX
|
||||
SG_ WHEEL_SPEED_RR : 45|15@1+ (0.002759506,0) [0|70] "m/s" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x1D6 XXX: 2 VSA
|
||||
|
||||
BO_ 0x1DC XXX: 7 XXX
|
||||
|
||||
BO_ 0x1E7 XXX: 4 VSA
|
||||
SG_ BRAKE_PRESSURE1 : 0|10@1+ (0.015625,-103) [0|1000] "" Vector__XXX
|
||||
SG_ BRAKE_PRESSURE2 : 14|10@1+ (0.015625,-103) [0|1000] "" Vector__XXX
|
||||
|
||||
BO_ 0x1EA VEHICLE_DYNAMICS: 8 VSA
|
||||
SG_ LONG_ACCEL : 16|16@1- (0.0015384,0) [-20|20] "m/s2" Vector__XXX
|
||||
|
||||
BO_ 0x1ED XXX: 5 VSA
|
||||
|
||||
BO_ 0x1FA BRAKE_COMMAND: 8 ADAS
|
||||
SG_ COMPUTER_BRAKE : 0|10@1+ (0.003906248,0) [0|1.0] "" Vector__XXX
|
||||
SG_ ZEROS_BOH : 10|5@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ COMPUTER_BRAKE_REQUEST : 15|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ CRUISE_BOH2 : 16|3@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ CRUISE_OVERRIDE : 19|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ CRUISE_BOH3 : 20|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ CRUISE_FAULT_CMD : 21|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ CRUISE_CANCEL_CMD : 22|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ COMPUTER_BRAKE_REQUEST_2 : 23|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ SET_ME_0X80 : 24|8@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ BRAKE_LIGHTS : 32|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ CRUISE_STATES : 33|7@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ CHIME : 40|3@1+ (1,0) [0|7] "" Vector__XXX
|
||||
SG_ ZEROS_BOH6 : 43|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ FCW : 44|1@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ ZEROS_BOH3 : 45|2@1+ (1,0) [0|0] "" Vector__XXX
|
||||
SG_ FCW2 : 47|1@1+ (1,0) [0|0] "" Vector__XXX
|
||||
SG_ ZEROS_BOH4 : 48|8@1+ (1,0) [0|0] "" Vector__XXX
|
||||
SG_ COUNTER : 58|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x200 GAS_COMMAND: 3 ADAS
|
||||
SG_ GAS_COMMAND : 0|16@1+ (0.253984064,-328) [0|1] "" Vector__XXX
|
||||
SG_ COUNTER : 18|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 20|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x201 GAS_SENSOR: 5 ADAS
|
||||
SG_ INTERCEPTOR_GAS : 0|16@1+ (0.253984064,-328) [0|1] "" Vector__XXX
|
||||
SG_ INTERCEPTOR_GAS2 : 16|16@1+ (0.126992032,-656) [0|1] "" Vector__XXX
|
||||
SG_ COUNTER : 34|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 36|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x221 XXX: 6 XXX
|
||||
|
||||
BO_ 0x255 ROUGH_WHEEL_SPEED: 8 VSA
|
||||
SG_ WHEEL_SPEED_FL : 0|8@1+ (1,0) [0|255] "mph" Vector__XXX
|
||||
SG_ WHEEL_SPEED_FR : 8|8@1+ (1,0) [0|255] "mph" Vector__XXX
|
||||
SG_ WHEEL_SPEED_RL : 16|8@1+ (1,0) [0|255] "mph" Vector__XXX
|
||||
SG_ WHEEL_SPEED_RR : 24|8@1+ (1,0) [0|255] "mph" Vector__XXX
|
||||
SG_ SET_TO_X55 : 32|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ SET_TO_X55 : 40|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
|
||||
BO_ 0x296 CRUISE_BUTTONS: 4 SCM
|
||||
SG_ CRUISE_BUTTONS : 0|3@1+ (1,0) [0|7] "" Vector__XXX
|
||||
SG_ CRUISE_SETTING : 4|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x305 SEATBELT_STATUS: 7 BDY
|
||||
SG_ SEATBELT_DRIVER_LAMP : 0|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ SEATBELT_DRIVER_LATCHED : 10|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ COUNTER : 50|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 52|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x309 XXX: 8 XXX
|
||||
|
||||
BO_ 0x30C ACC_HUD: 8 ADAS
|
||||
SG_ PCM_SPEED : 0|16@1+ (0.002763889,0) [0|100] "m/s" Vector__XXX
|
||||
SG_ PCM_GAS : 16|7@1+ (1,0) [0|127] "" Vector__XXX
|
||||
SG_ ZEROS_BOH : 23|1@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ CRUISE_SPEED : 24|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ DTC_MODE : 32|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ BOH : 33|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ ACC_PROBLEM : 34|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ FCM_OFF : 35|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ BOH_2 : 36|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ FCM_PROBLEM : 37|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ RADAR_OBSTRUCTED : 38|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ ENABLE_MINI_CAR : 39|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ HUD_DISTANCE : 40|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ HUD_LEAD : 42|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ BOH_3 : 44|1@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ BOH_4 : 45|1@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ BOH_5 : 46|1@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CRUISE_CONTROL_LABEL : 47|1@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ COUNTER : 58|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x31B XXX: 8 XXX
|
||||
|
||||
BO_ 0x320 XXX: 8 XXX
|
||||
|
||||
BO_ 0x324 CRUISE: 8 PCM
|
||||
SG_ ENGINE_TEMPERATURE : 0|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ BOH : 8|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ TRIP_FUEL_CONSUMED : 16|16@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ CRUISE_SPEED_PCM : 32|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ BOH2 : 40|8@1- (1,0) [0|255] "" Vector__XXX
|
||||
SG_ BOH3 : 48|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ COUNTER : 58|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x326 SCM_FEEDBACK: 8 SCM
|
||||
SG_ CMBS_BUTTON : 17|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ MAIN_ON : 27|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ RIGHT_BLINKER : 28|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LEFT_BLINKER : 29|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
|
||||
|
||||
BO_ 0x328 XXX: 8 XXX
|
||||
|
||||
BO_ 0x33D LKAS_HUD_2: 5 ADAS
|
||||
SG_ CAM_TEMP_HIGH : 0|1@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ BOH : 1|7@1+ (1,0) [0|127] "" Vector__XXX
|
||||
SG_ DASHED_LANES : 9|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ DTC : 10|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LKAS_PROBLEM : 11|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LKAS_OFF : 12|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ SOLID_LANES : 13|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LDW_RIGHT : 14|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ STEERING_REQUIRED : 15|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ BOH : 16|2@1+ (1,0) [0|4] "" Vector__XXX
|
||||
SG_ LDW_PROBLEM : 18|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ BEEP : 22|2@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LDW_ON : 27|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LDW_OFF : 28|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ CLEAN_WINDSHIELD : 29|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ SET_ME_X48 : 24|8@1+ (1,0) [0|255] "" Vector__XXX
|
||||
SG_ COUNTER : 34|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 36|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x35E XXX: 8 ADAS
|
||||
SG_ UI_ALERTS : 0|56@1+ (1,0) [0|127] "" Vector__XXX
|
||||
|
||||
BO_ 0x374 XXX: 8 XXX
|
||||
BO_ 0x37B XXX: 8 XXX
|
||||
BO_ 0x37C XXX: 8 XXX
|
||||
|
||||
BO_ 0x39F XXX: 8 ADAS
|
||||
SG_ ZEROS_BOH : 0|17@1+ (1,0) [0|127] "" Vector__XXX
|
||||
SG_ APPLY_BRAKES_FOR_CANC : 16|1@1+ (1,0) [0|15] "" Vector__XXX
|
||||
SG_ ZEROS_BOH2 : 17|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ RESUME_INSTRUCTION : 18|1@1+ (1,0) [0|15] "" Vector__XXX
|
||||
SG_ ACC_ALERTS : 19|5@1+ (1,0) [0|15] "" Vector__XXX
|
||||
SG_ ZEROS_BOH2 : 24|8@1+ (1,0) [0|127] "" Vector__XXX
|
||||
SG_ LEAD_SPEED : 32|9@1+ (1,0) [0|127] "" Vector__XXX
|
||||
SG_ LEAD_STATE : 41|3@1+ (1,0) [0|127] "" Vector__XXX
|
||||
SG_ LEAD_DISTANCE : 44|5@1+ (1,0) [0|31] "" Vector__XXX
|
||||
SG_ ZEROS_BOH3 : 49|7@1+ (1,0) [0|127] "" Vector__XXX
|
||||
|
||||
BO_ 0x3A1 XXX: 8 XXX
|
||||
BO_ 0x3D9 XXX: 3 XXX
|
||||
BO_ 0x400 XXX: 5 XXX
|
||||
BO_ 0x403 XXX: 5 XXX
|
||||
|
||||
BO_ 0x405 DOORS_STATUS: 8 BDY
|
||||
SG_ DOOR_OPEN_FL : 34|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ DOOR_OPEN_FR : 33|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ DOOR_OPEN_RL : 32|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ DOOR_OPEN_RR : 47|1@1+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ COUNTER : 58|2@1+ (1,0) [0|3] "" Vector__XXX
|
||||
SG_ CHECKSUM : 60|4@1+ (1,0) [0|3] "" Vector__XXX
|
||||
|
||||
BO_ 0x40C XXX: 8 XXX
|
||||
BO_ 0x40F XXX: 8 XXX
|
||||
BO_ 0x454 XXX: 8 XXX
|
||||
BO_ 0x516 XXX: 8 XXX
|
||||
BO_ 0x52A XXX: 5 XXX
|
||||
BO_ 0x551 XXX: 5 XXX
|
||||
BO_ 0x555 XXX: 5 XXX
|
||||
BO_ 0x590 XXX: 5 XXX
|
||||
BO_ 0x640 XXX: 5 XXX
|
||||
BO_ 0x641 XXX: 8 XXX
|
||||
BO_ 0x661 XXX: 8 XXX
|
||||
|
||||
VAL_ 0x296 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none";
|
||||
VAL_ 0x296 CRUISE_SETTING 3 "distance_adj" 2 "tbd" 1 "lkas_button" 0 "none";
|
||||
VAL_ 0x33D HUD_LEAD 3 "acc_off" 2 "solid_car" 1 "dashed_car" 0 "no_car";
|
||||
VAL_ 0x1A6 LIGHTS_SETTING 3 "high_beam" 2 "low_beam" 1 "position" 0 "no_lights";
|
||||
VAL_ 0x18F STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal";
|
||||
VAL_ 0x191 GEAR_SHIFTER 32 "L" 16 "S" 8 "D" 4 "N" 2 "R" 1 "P";
|
||||
VAL_ 0x33D BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep";
|
||||
VAL_ 0x1FA CHIME 4 "double_chime" 3 "single_chime" 2 "continuous_chime" 1 "repeating_chime" 0 "no_chime";
|
||||
VAL_ 0x1C2 EPB_STATE 3 "engaged" 2 "disengaging" 1 "engaging" 0 "disengaged";
|
||||
VAL_ 0x326 CMBS_BUTTON 3 "pressed" 0 "released";
|
||||
VAL_ 0x39F ACC_ALERTS 29 "esp_active_acc_canceled" 10 "b_pedal_applied" 9 "speed_too_low" 8 "speed_too_high" 7 "p_brake_applied" 6 "gear_no_d" 5 "seatbelt" 4 "too_steep_downhill" 3 "too_steep_uphill" 2 "too_close" 1 "no_vehicle_ahead";
|
||||
VAL_ 0x30C CRUISE_SPEED 255 "no_speed" 252 "stopped";
|
||||
|
||||
CM_ SG_ 0x1A3 GEAR "10 = reverse, 11 = transition";
|
||||
CM_ SG_ 0x324 CRUISE_SPEED_PCM "255 = no speed";
|
||||
CM_ SG_ 0x30C CRUISE_SPEED "255 = no speed";
|
||||
CM_ SG_ 0x1EA LONG_ACCEL "wheel speed derivative, noisy and zero snapping";
|
||||
CM_ SG_ 0x33D BEEP "beeps are pleasant, chimes are for warnngs etc...";
|
||||
@@ -1,29 +0,0 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
# enable wifi access point for debugging only!
|
||||
#service call wifi 37 i32 0 i32 1 # WifiService.setWifiApEnabled(null, true)
|
||||
|
||||
# use the openpilot ro key
|
||||
export GIT_SSH_COMMAND="ssh -i /data/data/com.termux/files/id_rsa_openpilot_ro"
|
||||
|
||||
# check out the openpilot repo
|
||||
if [ ! -d /data/openpilot ]; then
|
||||
cd /tmp
|
||||
git clone git@github.com:commaai/openpilot.git -b release
|
||||
mv /tmp/openpilot /data/openpilot
|
||||
fi
|
||||
|
||||
# enter openpilot directory
|
||||
cd /data/openpilot
|
||||
|
||||
# removed automatic update from openpilot
|
||||
#git pull
|
||||
|
||||
# start manager
|
||||
cd selfdrive
|
||||
mkdir -p /sdcard/realdata
|
||||
PYTHONPATH=/data/openpilot ./manager.py
|
||||
|
||||
# if broken, keep on screen error
|
||||
while true; do sleep 1; done
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAy/ZlYE/iHHjhbSvCnBm5Zsq5GPpVugLXFHai/doqyfRxErop
|
||||
/g1TIRhzK3mkHRYRN7H0L9whogwoIVr5CldoxU49FDnNbVHNimScNrL4LprRWjq6
|
||||
dRmCVoxMpLHZTyX1jIkcHsMr7klcUnssyeQO2pWvZv0ZC67wM7G20r7+ZLdEa0Ck
|
||||
MBh8JYhDaZx2xvYtTnt6vKMmFVE5+zW/+wDVma3a4r9pG9s0+r0wCl8CUuJ+yDhR
|
||||
mzNkPJ5mJCMx99AI6k4Gq9Vsng8/35b6Azh3TucPaXOLK7yPnL3YBKUa0PpR7IRH
|
||||
+OKkVCH+LL7tcPFSqPPVy/pUTBdEUROjJdSHxwIDAQABAoIBAQCxBgUM56h3T89Q
|
||||
AoghFg6dkdu/Ox8GmAp231UuAJncuMUfHObvcj8xXVgwZp4zBIEjFte6ZlPmoqh9
|
||||
8sht2lm7zeEjWdvbQwGjWRlgPEs9n++OYaSNl/tRBOpMk3Ppxydst1/prznE0nVH
|
||||
vVKtU7w0qXAYchm30zj1lQv5s/12CTGmnpQatbo5X488RfCfv2zFX1h+lEWF8ycL
|
||||
eZRi8z6l8h2Y+JLyEwPCmR+gR6XtosZ/ECQcTknavqLqdr7NbYYfOo3JfHCUtpJa
|
||||
8s7m0VFhMuxFFCl1sV0eMzAynJYNVz45DyaKpr2b/2YAGY8fn96FxaWv1xw1xTkK
|
||||
c5+wStwJAoGBAOjQpLZ1qGa4GwXzeHoDsGFpGgY9ug6af0M23c8O42fJHAwYkk7r
|
||||
Qeo4SSBddoSfo3jdchFLo59+m3qyTKpjkph7NBBCEwaCvX3heStDIMZEWX0IOV5y
|
||||
iJD/D6EXSqFmXCUUaudX2OxlaHguA0yOEx9s/5uUJrvaIHbBAOpYyar1AoGBAOBG
|
||||
MJp+EA3e1Zx/VszD2Tdxn8V0DAwvy9WIEqZuG689S/Sk5GnA4m2L8Txv0xAHFvLv
|
||||
JpF7Zn9AoFXGpjf9P0FF53cpjEYn9f+uK84j1HOL/6R7Nj9rcS5yL2PCP1ZHymw6
|
||||
xOXl3oZa1YtYE6jfvXUaOb8Z7y8gaStP763sXmpLAoGBAM1WSBANUcvXES58gIPN
|
||||
ASHJGwTqKFF8/kV//L4EuZjuDWi1u0UTxX0Yy5ZaGI/8ZKfTWCnc9qFTfzoGTAvz
|
||||
6nXGJDM6s6EIaqy90qrPd/amje7y8/ZTOhP4ggZojpAvwZGKoocMOey1vCBTJOG+
|
||||
ZStQbVkAn/EK/5r9uxr12FiJAoGAH9UWlPcLpExamWnhkhLCRAJWoRoFk708+0Pj
|
||||
EchTGZ5jp4e3++KqwM26Ic/lb0LyWOzk1oVjWPB9UW9urEe/sK4RWnKFPHfzjKTW
|
||||
Bt5DC1t1n4z1eC7x05vVah1qC/8IljAJPnBQE1XVNX/82l1XcMWWKK+vqUq6YrFn
|
||||
3ZHNHN0CgYA3uUVWqW37vfJuk0MJBkQSqMo5Y5TPlCt4b1ebkdhlM4v/N+iuiPiC
|
||||
PBhjP1MLeudkJvzllt4YvNWLerCKpMWuw7Zvy5uzFEsqOrVlzfnyWqqqYbYjHe9f
|
||||
Ef0/yXKuGJajs54Ts6Xrm0+elVUu//pEuf6NI96Ehctqz8/BqGqAtw==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# move files into place
|
||||
adb push files/id_rsa_openpilot_ro /tmp/id_rsa_openpilot_ro
|
||||
adb shell mv /tmp/id_rsa_openpilot_ro /data/data/com.termux/files/
|
||||
|
||||
# moving continue into place runs the continue script
|
||||
adb push files/continue.sh /tmp/continue.sh
|
||||
adb shell mv /tmp/continue.sh /data/data/com.termux/files/
|
||||
|
||||
1
opendbc
Submodule
1
opendbc
Submodule
Submodule opendbc added at d584cdd46c
1
panda
Submodule
1
panda
Submodule
Submodule panda added at 5409c51041
426
phonelibs/capnp-c/include/capnp_c.h
Normal file
426
phonelibs/capnp-c/include/capnp_c.h
Normal file
@@ -0,0 +1,426 @@
|
||||
/* vim: set sw=8 ts=8 sts=8 noet: */
|
||||
/* capnp_c.h
|
||||
*
|
||||
* Copyright (C) 2013 James McKaskill
|
||||
* Copyright (C) 2014 Steve Dee
|
||||
*
|
||||
* This software may be modified and distributed under the terms
|
||||
* of the MIT license. See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
#ifndef CAPNP_C_H
|
||||
#define CAPNP_C_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#if defined(unix) && !defined(__APPLE__)
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
// ssize_t is not defined in stdint.h in MSVC.
|
||||
#ifdef _MSC_VER
|
||||
typedef intmax_t ssize_t;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
|
||||
#define CAPN_INLINE static inline
|
||||
#else
|
||||
#define CAPN_INLINE static
|
||||
#endif
|
||||
|
||||
#define CAPN_VERSION 1
|
||||
|
||||
/* struct capn is a common structure shared between segments in the same
|
||||
* session/context so that far pointers between segments will be created.
|
||||
*
|
||||
* lookup is used to lookup segments by id when derefencing a far pointer
|
||||
*
|
||||
* create is used to create or lookup an alternate segment that has at least
|
||||
* sz available (ie returned seg->len + sz <= seg->cap)
|
||||
*
|
||||
* create_local is used to create a segment for the copy tree and should be
|
||||
* allocated in the local memory space.
|
||||
*
|
||||
* Allocated segments must be zero initialized.
|
||||
*
|
||||
* create and lookup can be NULL if you don't need multiple segments and don't
|
||||
* want to support copying
|
||||
*
|
||||
* seglist and copylist are linked lists which can be used to free up segments
|
||||
* on cleanup, but should not be modified by the user.
|
||||
*
|
||||
* lookup, create, create_local, and user can be set by the user. Other values
|
||||
* should be zero initialized.
|
||||
*/
|
||||
struct capn {
|
||||
/* user settable */
|
||||
struct capn_segment *(*lookup)(void* /*user*/, uint32_t /*id */);
|
||||
struct capn_segment *(*create)(void* /*user*/, uint32_t /*id */, int /*sz*/);
|
||||
struct capn_segment *(*create_local)(void* /*user*/, int /*sz*/);
|
||||
void *user;
|
||||
/* zero initialized, user should not modify */
|
||||
uint32_t segnum;
|
||||
struct capn_tree *copy;
|
||||
struct capn_tree *segtree;
|
||||
struct capn_segment *seglist, *lastseg;
|
||||
struct capn_segment *copylist;
|
||||
};
|
||||
|
||||
/* struct capn_tree is a rb tree header used internally for the segment id
|
||||
* lookup and copy tree */
|
||||
struct capn_tree {
|
||||
struct capn_tree *parent, *link[2];
|
||||
unsigned int red : 1;
|
||||
};
|
||||
|
||||
struct capn_tree *capn_tree_insert(struct capn_tree *root, struct capn_tree *n);
|
||||
|
||||
/* struct capn_segment contains the information about a single segment.
|
||||
*
|
||||
* capn points to a struct capn that is shared between segments in the
|
||||
* same session
|
||||
*
|
||||
* id specifies the segment id, used for far pointers
|
||||
*
|
||||
* data specifies the segment data. This should not move after creation.
|
||||
*
|
||||
* len specifies the current segment length. This is 0 for a blank
|
||||
* segment.
|
||||
*
|
||||
* cap specifies the segment capacity.
|
||||
*
|
||||
* When creating new structures len will be incremented until it reaces cap,
|
||||
* at which point a new segment will be requested via capn->create. The
|
||||
* create callback can either create a new segment or expand an existing
|
||||
* one by incrementing cap and returning the expanded segment.
|
||||
*
|
||||
* data, len, and cap must all by 8 byte aligned
|
||||
*
|
||||
* data, len, cap, and user should all set by the user. Other values
|
||||
* should be zero initialized.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
__declspec(align(64))
|
||||
#endif
|
||||
struct capn_segment {
|
||||
struct capn_tree hdr;
|
||||
struct capn_segment *next;
|
||||
struct capn *capn;
|
||||
uint32_t id;
|
||||
/* user settable */
|
||||
char *data;
|
||||
size_t len, cap;
|
||||
void *user;
|
||||
};
|
||||
|
||||
enum CAPN_TYPE {
|
||||
CAPN_NULL = 0,
|
||||
CAPN_STRUCT = 1,
|
||||
CAPN_LIST = 2,
|
||||
CAPN_PTR_LIST = 3,
|
||||
CAPN_BIT_LIST = 4,
|
||||
CAPN_FAR_POINTER = 5,
|
||||
};
|
||||
|
||||
struct capn_ptr {
|
||||
unsigned int type : 4;
|
||||
unsigned int has_ptr_tag : 1;
|
||||
unsigned int is_list_member : 1;
|
||||
unsigned int is_composite_list : 1;
|
||||
unsigned int datasz : 19;
|
||||
unsigned int ptrs : 16;
|
||||
int len;
|
||||
char *data;
|
||||
struct capn_segment *seg;
|
||||
};
|
||||
|
||||
struct capn_text {
|
||||
int len;
|
||||
const char *str;
|
||||
struct capn_segment *seg;
|
||||
};
|
||||
|
||||
typedef struct capn_ptr capn_ptr;
|
||||
typedef struct capn_text capn_text;
|
||||
typedef struct {capn_ptr p;} capn_data;
|
||||
typedef struct {capn_ptr p;} capn_list1;
|
||||
typedef struct {capn_ptr p;} capn_list8;
|
||||
typedef struct {capn_ptr p;} capn_list16;
|
||||
typedef struct {capn_ptr p;} capn_list32;
|
||||
typedef struct {capn_ptr p;} capn_list64;
|
||||
|
||||
struct capn_msg {
|
||||
struct capn_segment *seg;
|
||||
uint64_t iface;
|
||||
uint16_t method;
|
||||
capn_ptr args;
|
||||
};
|
||||
|
||||
/* capn_append_segment appends a segment to a session */
|
||||
void capn_append_segment(struct capn*, struct capn_segment*);
|
||||
|
||||
capn_ptr capn_root(struct capn *c);
|
||||
void capn_resolve(capn_ptr *p);
|
||||
|
||||
#define capn_len(list) ((list).p.type == CAPN_FAR_POINTER ? (capn_resolve(&(list).p), (list).p.len) : (list).p.len)
|
||||
|
||||
/* capn_getp|setp functions get/set ptrs in list/structs
|
||||
* off is the list index or pointer index in a struct
|
||||
* capn_setp will copy the data, create far pointers, etc if the target
|
||||
* is in a different segment/context.
|
||||
* Both of these will use/return inner pointers for composite lists.
|
||||
*/
|
||||
capn_ptr capn_getp(capn_ptr p, int off, int resolve);
|
||||
int capn_setp(capn_ptr p, int off, capn_ptr tgt);
|
||||
|
||||
capn_text capn_get_text(capn_ptr p, int off, capn_text def);
|
||||
capn_data capn_get_data(capn_ptr p, int off);
|
||||
int capn_set_text(capn_ptr p, int off, capn_text tgt);
|
||||
|
||||
/* capn_get* functions get data from a list
|
||||
* The length of the list is given by p->size
|
||||
* off specifies how far into the list to start
|
||||
* sz indicates the number of elements to get
|
||||
* The function returns the number of elements read or -1 on an error.
|
||||
* off must be byte aligned for capn_getv1
|
||||
*/
|
||||
int capn_get1(capn_list1 p, int off);
|
||||
uint8_t capn_get8(capn_list8 p, int off);
|
||||
uint16_t capn_get16(capn_list16 p, int off);
|
||||
uint32_t capn_get32(capn_list32 p, int off);
|
||||
uint64_t capn_get64(capn_list64 p, int off);
|
||||
int capn_getv1(capn_list1 p, int off, uint8_t *data, int sz);
|
||||
int capn_getv8(capn_list8 p, int off, uint8_t *data, int sz);
|
||||
int capn_getv16(capn_list16 p, int off, uint16_t *data, int sz);
|
||||
int capn_getv32(capn_list32 p, int off, uint32_t *data, int sz);
|
||||
int capn_getv64(capn_list64 p, int off, uint64_t *data, int sz);
|
||||
|
||||
/* capn_set* functions set data in a list
|
||||
* off specifies how far into the list to start
|
||||
* sz indicates the number of elements to write
|
||||
* The function returns the number of elemnts written or -1 on an error.
|
||||
* off must be byte aligned for capn_setv1
|
||||
*/
|
||||
int capn_set1(capn_list1 p, int off, int v);
|
||||
int capn_set8(capn_list8 p, int off, uint8_t v);
|
||||
int capn_set16(capn_list16 p, int off, uint16_t v);
|
||||
int capn_set32(capn_list32 p, int off, uint32_t v);
|
||||
int capn_set64(capn_list64 p, int off, uint64_t v);
|
||||
int capn_setv1(capn_list1 p, int off, const uint8_t *data, int sz);
|
||||
int capn_setv8(capn_list8 p, int off, const uint8_t *data, int sz);
|
||||
int capn_setv16(capn_list16 p, int off, const uint16_t *data, int sz);
|
||||
int capn_setv32(capn_list32 p, int off, const uint32_t *data, int sz);
|
||||
int capn_setv64(capn_list64 p, int off, const uint64_t *data, int sz);
|
||||
|
||||
/* capn_new_* functions create a new object
|
||||
* datasz is in bytes, ptrs is # of pointers, sz is # of elements in the list
|
||||
* On an error a CAPN_NULL pointer is returned
|
||||
*/
|
||||
capn_ptr capn_new_string(struct capn_segment *seg, const char *str, ssize_t sz);
|
||||
capn_ptr capn_new_struct(struct capn_segment *seg, int datasz, int ptrs);
|
||||
capn_ptr capn_new_interface(struct capn_segment *seg, int datasz, int ptrs);
|
||||
capn_ptr capn_new_ptr_list(struct capn_segment *seg, int sz);
|
||||
capn_ptr capn_new_list(struct capn_segment *seg, int sz, int datasz, int ptrs);
|
||||
capn_list1 capn_new_list1(struct capn_segment *seg, int sz);
|
||||
capn_list8 capn_new_list8(struct capn_segment *seg, int sz);
|
||||
capn_list16 capn_new_list16(struct capn_segment *seg, int sz);
|
||||
capn_list32 capn_new_list32(struct capn_segment *seg, int sz);
|
||||
capn_list64 capn_new_list64(struct capn_segment *seg, int sz);
|
||||
|
||||
/* capn_read|write* functions read/write struct values
|
||||
* off is the offset into the structure in bytes
|
||||
* Rarely should these be called directly, instead use the generated code.
|
||||
* Data must be xored with the default value
|
||||
* These are inlined
|
||||
*/
|
||||
CAPN_INLINE uint8_t capn_read8(capn_ptr p, int off);
|
||||
CAPN_INLINE uint16_t capn_read16(capn_ptr p, int off);
|
||||
CAPN_INLINE uint32_t capn_read32(capn_ptr p, int off);
|
||||
CAPN_INLINE uint64_t capn_read64(capn_ptr p, int off);
|
||||
CAPN_INLINE int capn_write1(capn_ptr p, int off, int val);
|
||||
CAPN_INLINE int capn_write8(capn_ptr p, int off, uint8_t val);
|
||||
CAPN_INLINE int capn_write16(capn_ptr p, int off, uint16_t val);
|
||||
CAPN_INLINE int capn_write32(capn_ptr p, int off, uint32_t val);
|
||||
CAPN_INLINE int capn_write64(capn_ptr p, int off, uint64_t val);
|
||||
|
||||
/* capn_init_malloc inits the capn struct with a create function which
|
||||
* allocates segments on the heap using malloc
|
||||
*
|
||||
* capn_init_(fp|mem) inits by reading segments in from the file/memory buffer
|
||||
* in serialized form (optionally packed). It will then setup the create
|
||||
* function ala capn_init_malloc so that further segments can be created.
|
||||
*
|
||||
* capn_free frees all the segment headers and data created by the create
|
||||
* function setup by capn_init_*
|
||||
*/
|
||||
void capn_init_malloc(struct capn *c);
|
||||
int capn_init_fp(struct capn *c, FILE *f, int packed);
|
||||
int capn_init_mem(struct capn *c, const uint8_t *p, size_t sz, int packed);
|
||||
|
||||
/* capn_write_(fp|mem) writes segments to the file/memory buffer in
|
||||
* serialized form and returns the number of bytes written.
|
||||
*/
|
||||
/* TODO */
|
||||
/*int capn_write_fp(struct capn *c, FILE *f, int packed);*/
|
||||
int capn_write_fd(struct capn *c, ssize_t (*write_fd)(int fd, void *p, size_t count), int fd, int packed);
|
||||
int capn_write_mem(struct capn *c, uint8_t *p, size_t sz, int packed);
|
||||
|
||||
void capn_free(struct capn *c);
|
||||
void capn_reset_copy(struct capn *c);
|
||||
|
||||
/* Inline functions */
|
||||
|
||||
|
||||
CAPN_INLINE uint8_t capn_flip8(uint8_t v) {
|
||||
return v;
|
||||
}
|
||||
CAPN_INLINE uint16_t capn_flip16(uint16_t v) {
|
||||
#if defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN)
|
||||
return v;
|
||||
#elif defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN) && \
|
||||
defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8
|
||||
return __builtin_bswap16(v);
|
||||
#else
|
||||
union { uint16_t u; uint8_t v[2]; } s;
|
||||
s.v[0] = (uint8_t)v;
|
||||
s.v[1] = (uint8_t)(v>>8);
|
||||
return s.u;
|
||||
#endif
|
||||
}
|
||||
CAPN_INLINE uint32_t capn_flip32(uint32_t v) {
|
||||
#if defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN)
|
||||
return v;
|
||||
#elif defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN) && \
|
||||
defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8
|
||||
return __builtin_bswap32(v);
|
||||
#else
|
||||
union { uint32_t u; uint8_t v[4]; } s;
|
||||
s.v[0] = (uint8_t)v;
|
||||
s.v[1] = (uint8_t)(v>>8);
|
||||
s.v[2] = (uint8_t)(v>>16);
|
||||
s.v[3] = (uint8_t)(v>>24);
|
||||
return s.u;
|
||||
#endif
|
||||
}
|
||||
CAPN_INLINE uint64_t capn_flip64(uint64_t v) {
|
||||
#if defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN)
|
||||
return v;
|
||||
#elif defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN) && \
|
||||
defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8
|
||||
return __builtin_bswap64(v);
|
||||
#else
|
||||
union { uint64_t u; uint8_t v[8]; } s;
|
||||
s.v[0] = (uint8_t)v;
|
||||
s.v[1] = (uint8_t)(v>>8);
|
||||
s.v[2] = (uint8_t)(v>>16);
|
||||
s.v[3] = (uint8_t)(v>>24);
|
||||
s.v[4] = (uint8_t)(v>>32);
|
||||
s.v[5] = (uint8_t)(v>>40);
|
||||
s.v[6] = (uint8_t)(v>>48);
|
||||
s.v[7] = (uint8_t)(v>>56);
|
||||
return s.u;
|
||||
#endif
|
||||
}
|
||||
|
||||
CAPN_INLINE int capn_write1(capn_ptr p, int off, int val) {
|
||||
if (off >= p.datasz*8) {
|
||||
return -1;
|
||||
} else if (val) {
|
||||
uint8_t tmp = (uint8_t)(1 << (off & 7));
|
||||
((uint8_t*) p.data)[off >> 3] |= tmp;
|
||||
return 0;
|
||||
} else {
|
||||
uint8_t tmp = (uint8_t)(~(1 << (off & 7)));
|
||||
((uint8_t*) p.data)[off >> 3] &= tmp;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
CAPN_INLINE uint8_t capn_read8(capn_ptr p, int off) {
|
||||
return off+1 <= p.datasz ? capn_flip8(*(uint8_t*) (p.data+off)) : 0;
|
||||
}
|
||||
CAPN_INLINE int capn_write8(capn_ptr p, int off, uint8_t val) {
|
||||
if (off+1 <= p.datasz) {
|
||||
*(uint8_t*) (p.data+off) = capn_flip8(val);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
CAPN_INLINE uint16_t capn_read16(capn_ptr p, int off) {
|
||||
return off+2 <= p.datasz ? capn_flip16(*(uint16_t*) (p.data+off)) : 0;
|
||||
}
|
||||
CAPN_INLINE int capn_write16(capn_ptr p, int off, uint16_t val) {
|
||||
if (off+2 <= p.datasz) {
|
||||
*(uint16_t*) (p.data+off) = capn_flip16(val);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
CAPN_INLINE uint32_t capn_read32(capn_ptr p, int off) {
|
||||
return off+4 <= p.datasz ? capn_flip32(*(uint32_t*) (p.data+off)) : 0;
|
||||
}
|
||||
CAPN_INLINE int capn_write32(capn_ptr p, int off, uint32_t val) {
|
||||
if (off+4 <= p.datasz) {
|
||||
*(uint32_t*) (p.data+off) = capn_flip32(val);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
CAPN_INLINE uint64_t capn_read64(capn_ptr p, int off) {
|
||||
return off+8 <= p.datasz ? capn_flip64(*(uint64_t*) (p.data+off)) : 0;
|
||||
}
|
||||
CAPN_INLINE int capn_write64(capn_ptr p, int off, uint64_t val) {
|
||||
if (off+8 <= p.datasz) {
|
||||
*(uint64_t*) (p.data+off) = capn_flip64(val);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
union capn_conv_f32 {
|
||||
uint32_t u;
|
||||
float f;
|
||||
};
|
||||
|
||||
union capn_conv_f64 {
|
||||
uint64_t u;
|
||||
double f;
|
||||
};
|
||||
|
||||
CAPN_INLINE float capn_to_f32(uint32_t v) {
|
||||
union capn_conv_f32 u;
|
||||
u.u = v;
|
||||
return u.f;
|
||||
}
|
||||
CAPN_INLINE double capn_to_f64(uint64_t v) {
|
||||
union capn_conv_f64 u;
|
||||
u.u = v;
|
||||
return u.f;
|
||||
}
|
||||
CAPN_INLINE uint32_t capn_from_f32(float v) {
|
||||
union capn_conv_f32 u;
|
||||
u.f = v;
|
||||
return u.u;
|
||||
}
|
||||
CAPN_INLINE uint64_t capn_from_f64(double v) {
|
||||
union capn_conv_f64 u;
|
||||
u.f = v;
|
||||
return u.u;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1381
phonelibs/json/src/json.c
Normal file
1381
phonelibs/json/src/json.c
Normal file
File diff suppressed because it is too large
Load Diff
117
phonelibs/json/src/json.h
Normal file
117
phonelibs/json/src/json.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
Copyright (C) 2011 Joseph A. Adams (joeyadams3.14159@gmail.com)
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CCAN_JSON_H
|
||||
#define CCAN_JSON_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
typedef enum {
|
||||
JSON_NULL,
|
||||
JSON_BOOL,
|
||||
JSON_STRING,
|
||||
JSON_NUMBER,
|
||||
JSON_ARRAY,
|
||||
JSON_OBJECT,
|
||||
} JsonTag;
|
||||
|
||||
typedef struct JsonNode JsonNode;
|
||||
|
||||
struct JsonNode
|
||||
{
|
||||
/* only if parent is an object or array (NULL otherwise) */
|
||||
JsonNode *parent;
|
||||
JsonNode *prev, *next;
|
||||
|
||||
/* only if parent is an object (NULL otherwise) */
|
||||
char *key; /* Must be valid UTF-8. */
|
||||
|
||||
JsonTag tag;
|
||||
union {
|
||||
/* JSON_BOOL */
|
||||
bool bool_;
|
||||
|
||||
/* JSON_STRING */
|
||||
char *string_; /* Must be valid UTF-8. */
|
||||
|
||||
/* JSON_NUMBER */
|
||||
double number_;
|
||||
|
||||
/* JSON_ARRAY */
|
||||
/* JSON_OBJECT */
|
||||
struct {
|
||||
JsonNode *head, *tail;
|
||||
} children;
|
||||
};
|
||||
};
|
||||
|
||||
/*** Encoding, decoding, and validation ***/
|
||||
|
||||
JsonNode *json_decode (const char *json);
|
||||
char *json_encode (const JsonNode *node);
|
||||
char *json_encode_string (const char *str);
|
||||
char *json_stringify (const JsonNode *node, const char *space);
|
||||
void json_delete (JsonNode *node);
|
||||
|
||||
bool json_validate (const char *json);
|
||||
|
||||
/*** Lookup and traversal ***/
|
||||
|
||||
JsonNode *json_find_element (JsonNode *array, int index);
|
||||
JsonNode *json_find_member (JsonNode *object, const char *key);
|
||||
|
||||
JsonNode *json_first_child (const JsonNode *node);
|
||||
|
||||
#define json_foreach(i, object_or_array) \
|
||||
for ((i) = json_first_child(object_or_array); \
|
||||
(i) != NULL; \
|
||||
(i) = (i)->next)
|
||||
|
||||
/*** Construction and manipulation ***/
|
||||
|
||||
JsonNode *json_mknull(void);
|
||||
JsonNode *json_mkbool(bool b);
|
||||
JsonNode *json_mkstring(const char *s);
|
||||
JsonNode *json_mknumber(double n);
|
||||
JsonNode *json_mkarray(void);
|
||||
JsonNode *json_mkobject(void);
|
||||
|
||||
void json_append_element(JsonNode *array, JsonNode *element);
|
||||
void json_prepend_element(JsonNode *array, JsonNode *element);
|
||||
void json_append_member(JsonNode *object, const char *key, JsonNode *value);
|
||||
void json_prepend_member(JsonNode *object, const char *key, JsonNode *value);
|
||||
|
||||
void json_remove_from_parent(JsonNode *node);
|
||||
|
||||
/*** Debugging ***/
|
||||
|
||||
/*
|
||||
* Look for structure and encoding problems in a JsonNode or its descendents.
|
||||
*
|
||||
* If a problem is detected, return false, writing a description of the problem
|
||||
* to errmsg (unless errmsg is NULL).
|
||||
*/
|
||||
bool json_check(const JsonNode *node, char errmsg[256]);
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,6 @@
|
||||
Cython==0.24.1
|
||||
bitstring==3.1.5
|
||||
fastcluster==1.1.21
|
||||
h5py==2.6.0
|
||||
libusb1==1.5.0
|
||||
pycapnp==0.5.9
|
||||
pyzmq==15.4.0
|
||||
@@ -9,4 +8,5 @@ raven==5.23.0
|
||||
requests==2.10.0
|
||||
setproctitle==1.1.10
|
||||
simplejson==3.8.2
|
||||
pyyaml==3.12
|
||||
-e git+https://github.com/commaai/le_python.git#egg=Logentries
|
||||
|
||||
@@ -2,6 +2,7 @@ CC = clang
|
||||
CXX = clang++
|
||||
|
||||
ARCH := $(shell uname -m)
|
||||
OS := $(shell uname -o)
|
||||
|
||||
PHONELIBS = ../../phonelibs
|
||||
|
||||
@@ -19,29 +20,37 @@ ZMQ_LIBS = -L$(PHONELIBS)/zmq/aarch64/lib \
|
||||
-l:libczmq.a -l:libzmq.a \
|
||||
-lgnustl_shared
|
||||
|
||||
CEREAL_FLAGS = -I$(PHONELIBS)/capnp-cpp/include
|
||||
CEREAL_LIBS = -L$(PHONELIBS)/capnp-cpp/aarch64/lib/ \
|
||||
-l:libcapnp.a -l:libkj.a
|
||||
CEREAL_OBJS = ../../cereal/gen/c/log.capnp.o
|
||||
JSON_FLAGS = -I$(PHONELIBS)/json/src
|
||||
|
||||
EXTRA_LIBS = -lusb
|
||||
|
||||
ifeq ($(ARCH),x86_64)
|
||||
ZMQ_LIBS = -L$(HOME)/drive/external/zmq/lib/ \
|
||||
-l:libczmq.a -l:libzmq.a
|
||||
CEREAL_LIBS = -L$(HOME)/drive/external/capnp/lib/ \
|
||||
-l:libcapnp.a -l:libkj.a
|
||||
ifeq ($(OS),GNU/Linux)
|
||||
# for Drive PX2
|
||||
ZMQ_LIBS = -lczmq -lzmq
|
||||
CEREAL_LIBS = -lcapnp -lkj -lcapnp_c
|
||||
EXTRA_LIBS = -lusb-1.0 -lpthread
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),x86_64)
|
||||
ZMQ_LIBS = -L$(HOME)/one/external/zmq/lib/ \
|
||||
-l:libczmq.a -l:libzmq.a
|
||||
CEREAL_LIBS = -L$(HOME)/one/external/capnp/lib/ \
|
||||
-l:libcapnp.a -l:libcapnp_c.a -l:libkj.a
|
||||
EXTRA_LIBS = -lusb-1.0 -lpthread
|
||||
endif
|
||||
|
||||
.PHONY: all
|
||||
all: boardd
|
||||
|
||||
include ../common/cereal.mk
|
||||
|
||||
OBJS = boardd.o \
|
||||
log.capnp.o
|
||||
../common/swaglog.o \
|
||||
$(PHONELIBS)/json/src/json.o \
|
||||
$(CEREAL_OBJS)
|
||||
|
||||
DEPS := $(OBJS:.o=.d)
|
||||
|
||||
all: boardd
|
||||
|
||||
boardd: $(OBJS)
|
||||
@echo "[ LINK ] $@"
|
||||
$(CXX) -fPIC -o '$@' $^ \
|
||||
@@ -53,18 +62,21 @@ boardd.o: boardd.cc
|
||||
@echo "[ CXX ] $@"
|
||||
$(CXX) $(CXXFLAGS) \
|
||||
-I$(PHONELIBS)/android_system_core/include \
|
||||
$(CEREAL_FLAGS) \
|
||||
$(CEREAL_CFLAGS) \
|
||||
$(CEREAL_CXXFLAGS) \
|
||||
$(ZMQ_FLAGS) \
|
||||
-I../ \
|
||||
-I../../ \
|
||||
-c -o '$@' '$<'
|
||||
|
||||
|
||||
log.capnp.o: ../../cereal/gen/cpp/log.capnp.c++
|
||||
@echo "[ CXX ] $@"
|
||||
$(CXX) $(CXXFLAGS) $(CEREAL_FLAGS) \
|
||||
-c -o '$@' '$<'
|
||||
|
||||
%.o: %.c
|
||||
@echo "[ CC ] $@"
|
||||
$(CC) $(CFLAGS) -MMD \
|
||||
-Iinclude -I.. -I../.. \
|
||||
$(CEREAL_CFLAGS) \
|
||||
$(ZMQ_FLAGS) \
|
||||
$(JSON_FLAGS) \
|
||||
-c -o '$@' '$<'
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <capnp/serialize.h>
|
||||
#include "cereal/gen/cpp/log.capnp.h"
|
||||
|
||||
#include "common/swaglog.h"
|
||||
#include "common/timing.h"
|
||||
|
||||
int do_exit = 0;
|
||||
@@ -29,18 +30,12 @@ libusb_device_handle *dev_handle;
|
||||
pthread_mutex_t usb_lock;
|
||||
|
||||
bool spoofing_started = false;
|
||||
bool fake_send = false;
|
||||
|
||||
// double the FIFO size
|
||||
#define RECV_SIZE (0x1000)
|
||||
#define TIMEOUT 0
|
||||
|
||||
#define DEBUG_BOARDD
|
||||
#ifdef DEBUG_BOARDD
|
||||
#define DPRINTF(fmt, ...) printf("boardd: " fmt, ## __VA_ARGS__)
|
||||
#else
|
||||
#define DPRINTF(fmt, ...)
|
||||
#endif
|
||||
|
||||
bool usb_connect() {
|
||||
int err;
|
||||
|
||||
@@ -53,14 +48,36 @@ bool usb_connect() {
|
||||
err = libusb_claim_interface(dev_handle, 0);
|
||||
if (err != 0) { return false; }
|
||||
|
||||
// power off ESP
|
||||
libusb_control_transfer(dev_handle, 0xc0, 0xd9, 0, 0, NULL, 0, TIMEOUT);
|
||||
|
||||
// forward CAN1 to CAN3...soon
|
||||
//libusb_control_transfer(dev_handle, 0xc0, 0xdd, 1, 2, NULL, 0, TIMEOUT);
|
||||
|
||||
// set UART modes for Honda Accord
|
||||
for (int uart = 2; uart <= 3; uart++) {
|
||||
// 9600 baud
|
||||
libusb_control_transfer(dev_handle, 0xc0, 0xe1, uart, 9600, NULL, 0, TIMEOUT);
|
||||
// even parity
|
||||
libusb_control_transfer(dev_handle, 0xc0, 0xe2, uart, 1, NULL, 0, TIMEOUT);
|
||||
// callback 1
|
||||
libusb_control_transfer(dev_handle, 0xc0, 0xe3, uart, 1, NULL, 0, TIMEOUT);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void usb_retry_connect() {
|
||||
LOG("attempting to connect");
|
||||
while (!usb_connect()) { usleep(100*1000); }
|
||||
LOGW("connected to board");
|
||||
}
|
||||
|
||||
void handle_usb_issue(int err, const char func[]) {
|
||||
DPRINTF("usb error %d \"%s\" in %s\n", err, libusb_strerror((enum libusb_error)err), func);
|
||||
LOGE("usb error %d \"%s\" in %s", err, libusb_strerror((enum libusb_error)err), func);
|
||||
if (err == -4) {
|
||||
while (!usb_connect()) { DPRINTF("attempting to connect\n"); usleep(100*1000); }
|
||||
LOGE("lost connection");
|
||||
usb_retry_connect();
|
||||
}
|
||||
// TODO: check other errors, is simply retrying okay?
|
||||
}
|
||||
@@ -77,7 +94,7 @@ void can_recv(void *s) {
|
||||
do {
|
||||
err = libusb_bulk_transfer(dev_handle, 0x81, (uint8_t*)data, RECV_SIZE, &recv, TIMEOUT);
|
||||
if (err != 0) { handle_usb_issue(err, __func__); }
|
||||
if (err == -8) { DPRINTF("overflow got 0x%x\n", recv); };
|
||||
if (err == -8) { LOGE("overflow got 0x%x", recv); };
|
||||
|
||||
// timeout is okay to exit, recv still happened
|
||||
if (err == -7) { break; }
|
||||
@@ -110,7 +127,7 @@ void can_recv(void *s) {
|
||||
canData[i].setBusTime(data[i*4+1] >> 16);
|
||||
int len = data[i*4+1]&0xF;
|
||||
canData[i].setDat(kj::arrayPtr((uint8_t*)&data[i*4+2], len));
|
||||
canData[i].setSrc((data[i*4+1] >> 4) & 3);
|
||||
canData[i].setSrc((data[i*4+1] >> 4) & 0xf);
|
||||
}
|
||||
|
||||
// send to can
|
||||
@@ -123,12 +140,14 @@ void can_health(void *s) {
|
||||
int cnt;
|
||||
|
||||
// copied from board/main.c
|
||||
struct health {
|
||||
struct __attribute__((packed)) health {
|
||||
uint32_t voltage;
|
||||
uint32_t current;
|
||||
uint8_t started;
|
||||
uint8_t controls_allowed;
|
||||
uint8_t gas_interceptor_detected;
|
||||
uint8_t started_signal_detected;
|
||||
uint8_t started_alt;
|
||||
} health;
|
||||
|
||||
// recv from board
|
||||
@@ -157,6 +176,7 @@ void can_health(void *s) {
|
||||
}
|
||||
healthData.setControlsAllowed(health.controls_allowed);
|
||||
healthData.setGasInterceptorDetected(health.gas_interceptor_detected);
|
||||
healthData.setStartedSignalDetected(health.started_signal_detected);
|
||||
|
||||
// send to health
|
||||
auto words = capnp::messageToFlatArray(msg);
|
||||
@@ -174,8 +194,10 @@ void can_send(void *s) {
|
||||
err = zmq_msg_recv(&msg, s, 0);
|
||||
assert(err >= 0);
|
||||
|
||||
// format for board
|
||||
auto amsg = kj::arrayPtr((const capnp::word*)zmq_msg_data(&msg), zmq_msg_size(&msg));
|
||||
// format for board, make copy due to alignment issues, will be freed on out of scope
|
||||
auto amsg = kj::heapArray<capnp::word>((zmq_msg_size(&msg) / sizeof(capnp::word)) + 1);
|
||||
memcpy(amsg.begin(), zmq_msg_data(&msg), zmq_msg_size(&msg));
|
||||
|
||||
capnp::FlatArrayMessageReader cmsg(amsg);
|
||||
cereal::Event::Reader event = cmsg.getRoot<cereal::Event>();
|
||||
int msg_count = event.getCan().size();
|
||||
@@ -197,8 +219,6 @@ void can_send(void *s) {
|
||||
memcpy(&send[i*4+2], cmsg.getDat().begin(), cmsg.getDat().size());
|
||||
}
|
||||
|
||||
//DPRINTF("got send message: %d\n", msg_count);
|
||||
|
||||
// release msg
|
||||
zmq_msg_close(&msg);
|
||||
|
||||
@@ -206,10 +226,12 @@ void can_send(void *s) {
|
||||
int sent;
|
||||
pthread_mutex_lock(&usb_lock);
|
||||
|
||||
do {
|
||||
err = libusb_bulk_transfer(dev_handle, 3, (uint8_t*)send, msg_count*0x10, &sent, TIMEOUT);
|
||||
if (err != 0 || msg_count*0x10 != sent) { handle_usb_issue(err, __func__); }
|
||||
} while(err != 0);
|
||||
if (!fake_send) {
|
||||
do {
|
||||
err = libusb_bulk_transfer(dev_handle, 3, (uint8_t*)send, msg_count*0x10, &sent, TIMEOUT);
|
||||
if (err != 0 || msg_count*0x10 != sent) { handle_usb_issue(err, __func__); }
|
||||
} while(err != 0);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&usb_lock);
|
||||
|
||||
@@ -221,7 +243,7 @@ void can_send(void *s) {
|
||||
// **** threads ****
|
||||
|
||||
void *can_send_thread(void *crap) {
|
||||
DPRINTF("start send thread\n");
|
||||
LOGD("start send thread");
|
||||
|
||||
// sendcan = 8017
|
||||
void *context = zmq_ctx_new();
|
||||
@@ -237,7 +259,7 @@ void *can_send_thread(void *crap) {
|
||||
}
|
||||
|
||||
void *can_recv_thread(void *crap) {
|
||||
DPRINTF("start recv thread\n");
|
||||
LOGD("start recv thread");
|
||||
|
||||
// can = 8006
|
||||
void *context = zmq_ctx_new();
|
||||
@@ -254,7 +276,7 @@ void *can_recv_thread(void *crap) {
|
||||
}
|
||||
|
||||
void *can_health_thread(void *crap) {
|
||||
DPRINTF("start health thread\n");
|
||||
LOGD("start health thread");
|
||||
|
||||
// health = 8011
|
||||
void *context = zmq_ctx_new();
|
||||
@@ -274,40 +296,36 @@ int set_realtime_priority(int level) {
|
||||
struct sched_param sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sched_priority = level;
|
||||
return sched_setscheduler(gettid(), SCHED_FIFO, &sa);
|
||||
return sched_setscheduler(getpid(), SCHED_FIFO, &sa);
|
||||
}
|
||||
|
||||
int main() {
|
||||
int err;
|
||||
printf("boardd: starting boardd\n");
|
||||
LOGW("starting boardd");
|
||||
|
||||
// set process priority
|
||||
err = set_realtime_priority(4);
|
||||
printf("boardd: setpriority returns %d\n", err);
|
||||
LOG("setpriority returns %d", err);
|
||||
|
||||
// check the environment
|
||||
if (getenv("STARTED")) {
|
||||
spoofing_started = true;
|
||||
}
|
||||
|
||||
// connect to the board
|
||||
if (getenv("FAKESEND")) {
|
||||
fake_send = true;
|
||||
}
|
||||
|
||||
// init libusb
|
||||
err = libusb_init(&ctx);
|
||||
assert(err == 0);
|
||||
libusb_set_debug(ctx, 3);
|
||||
|
||||
// TODO: duplicate code from error handling
|
||||
while (!usb_connect()) { DPRINTF("attempting to connect\n"); usleep(100*1000); }
|
||||
// connect to the board
|
||||
usb_retry_connect();
|
||||
|
||||
/*int config;
|
||||
err = libusb_get_configuration(dev_handle, &config);
|
||||
assert(err == 0);
|
||||
DPRINTF("configuration is %d\n", config);*/
|
||||
|
||||
/*err = libusb_set_interface_alt_setting(dev_handle, 0, 0);
|
||||
assert(err == 0);*/
|
||||
|
||||
// create threads
|
||||
|
||||
pthread_t can_health_thread_handle;
|
||||
err = pthread_create(&can_health_thread_handle, NULL,
|
||||
can_health_thread, NULL);
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
import os
|
||||
import struct
|
||||
import zmq
|
||||
import time
|
||||
|
||||
import selfdrive.messaging as messaging
|
||||
from common.realtime import Ratekeeper
|
||||
from common.services import service_list
|
||||
from selfdrive.services import service_list
|
||||
from selfdrive.swaglog import cloudlog
|
||||
|
||||
# USB is optional
|
||||
@@ -56,7 +57,7 @@ def __parse_can_buffer(dat):
|
||||
for j in range(0, len(dat), 0x10):
|
||||
ddat = dat[j:j+0x10]
|
||||
f1, f2 = struct.unpack("II", ddat[0:8])
|
||||
ret.append((f1 >> 21, f2>>16, ddat[8:8+(f2&0xF)], (f2>>4)&3))
|
||||
ret.append((f1 >> 21, f2>>16, ddat[8:8+(f2&0xF)], (f2>>4)&0xF))
|
||||
return ret
|
||||
|
||||
def can_send_many(arr):
|
||||
@@ -109,7 +110,7 @@ def boardd_mock_loop():
|
||||
|
||||
while 1:
|
||||
tsc = messaging.drain_sock(logcan, wait_for_one=True)
|
||||
snds = map(can_capnp_to_can_list, tsc)
|
||||
snds = map(lambda x: can_capnp_to_can_list(x.can), tsc)
|
||||
snd = []
|
||||
for s in snds:
|
||||
snd += s
|
||||
@@ -122,6 +123,19 @@ def boardd_mock_loop():
|
||||
|
||||
#print can_msgs
|
||||
|
||||
def boardd_test_loop():
|
||||
can_init()
|
||||
cnt = 0
|
||||
while 1:
|
||||
can_send_many([[0xbb,0,"\xaa\xaa\xaa\xaa",0], [0xaa,0,"\xaa\xaa\xaa\xaa"+struct.pack("!I", cnt),1]])
|
||||
#can_send_many([[0xaa,0,"\xaa\xaa\xaa\xaa",0]])
|
||||
#can_send_many([[0xaa,0,"\xaa\xaa\xaa\xaa",1]])
|
||||
# recv @ 100hz
|
||||
can_msgs = can_recv()
|
||||
print "got %d" % (len(can_msgs))
|
||||
time.sleep(0.01)
|
||||
cnt += 1
|
||||
|
||||
# *** main loop ***
|
||||
def boardd_loop(rate=200):
|
||||
rk = Ratekeeper(rate)
|
||||
@@ -162,13 +176,15 @@ def boardd_loop(rate=200):
|
||||
# send can if we have a packet
|
||||
tsc = messaging.recv_sock(sendcan)
|
||||
if tsc is not None:
|
||||
can_send_many(can_capnp_to_can_list(tsc))
|
||||
can_send_many(can_capnp_to_can_list(tsc.sendcan))
|
||||
|
||||
rk.keep_time()
|
||||
|
||||
def main(gctx=None):
|
||||
if os.getenv("MOCK") is not None:
|
||||
boardd_mock_loop()
|
||||
elif os.getenv("BOARDTEST") is not None:
|
||||
boardd_test_loop()
|
||||
else:
|
||||
boardd_loop()
|
||||
|
||||
|
||||
@@ -1,208 +0,0 @@
|
||||
import numpy as np
|
||||
|
||||
import common.filters as filters
|
||||
from selfdrive.controls.lib.latcontrol import calc_curvature
|
||||
|
||||
|
||||
# Calibration Status
|
||||
class CalibStatus(object):
|
||||
INCOMPLETE = 0
|
||||
VALID = 1
|
||||
INVALID = 2
|
||||
|
||||
|
||||
def line_intersection(line1, line2, no_int_sub = [0,0]):
|
||||
xdiff = (line1[0][0] - line1[1][0], line2[0][0] - line2[1][0])
|
||||
ydiff = (line1[0][1] - line1[1][1], line2[0][1] - line2[1][1])
|
||||
|
||||
def det(a, b):
|
||||
return a[0] * b[1] - a[1] * b[0]
|
||||
|
||||
div = det(xdiff, ydiff)
|
||||
if div == 0:
|
||||
# since we are in float domain, this should really never happen
|
||||
return no_int_sub
|
||||
|
||||
d = (det(*line1), det(*line2))
|
||||
x = det(d, xdiff) / div
|
||||
y = det(d, ydiff) / div
|
||||
return [x, y]
|
||||
|
||||
def points_inside_hit_box(pts, box):
|
||||
"""Determine which points lie inside a box.
|
||||
|
||||
Inputs:
|
||||
pts: An nx2 array of points to hit test.
|
||||
box: An array [[x_left, y_top], [x_right, y_bottom]] describing a box to
|
||||
use for hit testing.
|
||||
Returns:
|
||||
A logical array with true for every member of pts inside box.
|
||||
"""
|
||||
hits = np.all(np.logical_and(pts > box[0, :], pts < box[1, :]), axis=1)
|
||||
return hits
|
||||
|
||||
def warp_points(pt_s, warp_matrix):
|
||||
# pt_s are the source points, nx2 array.
|
||||
pt_d = np.dot(warp_matrix[:, :2], pt_s.T) + warp_matrix[:, 2][:, np.newaxis]
|
||||
|
||||
# divide by third dimension for representation in image space.
|
||||
return (pt_d[:2, :] / pt_d[2, :]).T
|
||||
|
||||
class ViewCalibrator(object):
|
||||
def __init__(self, box_size, big_box_size, vp_r, warp_matrix_start, vp_f=None, cal_cycle=0, cal_status=0):
|
||||
self.calibration_threshold = 3000
|
||||
self.box_size = box_size
|
||||
self.big_box_size = big_box_size
|
||||
|
||||
self.warp_matrix_start = warp_matrix_start
|
||||
self.vp_r = list(vp_r)
|
||||
|
||||
if vp_f is None:
|
||||
self.vp_f = list(vp_r)
|
||||
else:
|
||||
self.vp_f = list(vp_f)
|
||||
|
||||
# slow filter fot the vanishing point
|
||||
vp_fr = 0.005 # Hz, slow filter
|
||||
self.dt = 0.05 # camera runs at 20Hz
|
||||
|
||||
self.update_warp_matrix()
|
||||
|
||||
self.vp_x_filter = filters.FirstOrderLowpassFilter(vp_fr, self.dt, self.vp_f[0])
|
||||
self.vp_y_filter = filters.FirstOrderLowpassFilter(vp_fr, self.dt, self.vp_f[1])
|
||||
|
||||
self.cal_cycle = cal_cycle
|
||||
self.cal_status = cal_status
|
||||
self.cal_perc = int(np.minimum(self.cal_cycle*100./self.calibration_threshold, 100))
|
||||
|
||||
def vanishing_point_process(self, old_ps, new_ps, v_ego, steer_angle, VP):
|
||||
# correct diffs by yaw rate
|
||||
cam_fov = 23.06*np.pi/180. # deg
|
||||
curvature = calc_curvature(v_ego, steer_angle, VP)
|
||||
yaw_rate = curvature * v_ego
|
||||
hor_angle_shift = yaw_rate * self.dt * self.box_size[0] / cam_fov
|
||||
old_ps += [hor_angle_shift, 0] # old points have moved in the image due to yaw rate
|
||||
|
||||
pos_ps = [None]*len(new_ps)
|
||||
for ii in range(len(old_ps)):
|
||||
xo = old_ps[ii][0]
|
||||
yo = old_ps[ii][1]
|
||||
yn = new_ps[ii][1]
|
||||
|
||||
# don't consider points with low flow in y
|
||||
if abs(yn - yo) > 1:
|
||||
if xo > (self.vp_f[0] + 20):
|
||||
pos_ps[ii] = 'r' # right lane point
|
||||
elif xo < (self.vp_f[0] - 20):
|
||||
pos_ps[ii] = 'l' # left lane point
|
||||
|
||||
# intersect all the right lines with the left lines
|
||||
idxs_l = [i for i, x in enumerate(pos_ps) if x == 'l']
|
||||
idxs_r = [i for i, x in enumerate(pos_ps) if x == 'r']
|
||||
|
||||
old_ps_l, new_ps_l = old_ps[idxs_l], new_ps[idxs_l]
|
||||
old_ps_r, new_ps_r = old_ps[idxs_r], new_ps[idxs_r]
|
||||
# return None if there is one side with no lines, the speed is low or the steer angle is high
|
||||
if len(old_ps_l) == 0 or len(old_ps_r) == 0 or v_ego < 20 or abs(steer_angle) > 5:
|
||||
return None
|
||||
|
||||
int_ps = [[None] * len(old_ps_r)] * len(old_ps_l)
|
||||
for ll in range(len(old_ps_l)):
|
||||
for rr in range(len(old_ps_r)):
|
||||
old_p_l, old_p_r, new_p_l, new_p_r = old_ps_l[ll], old_ps_r[
|
||||
rr], new_ps_l[ll], new_ps_r[rr]
|
||||
line_l = [[old_p_l[0], old_p_l[1]], [new_p_l[0], new_p_l[1]]]
|
||||
line_r = [[old_p_r[0], old_p_r[1]], [new_p_r[0], new_p_r[1]]]
|
||||
int_ps[ll][rr] = line_intersection(
|
||||
line_l, line_r, no_int_sub=self.vp_f)
|
||||
# saturate outliers that are too far from the estimated vp
|
||||
int_ps[ll][rr][0] = np.clip(int_ps[ll][rr][0], self.vp_f[0] - 20, self.vp_f[0] + 20)
|
||||
int_ps[ll][rr][1] = np.clip(int_ps[ll][rr][1], self.vp_f[1] - 30, self.vp_f[1] + 30)
|
||||
vp = np.mean(np.mean(np.array(int_ps), axis=0), axis=0)
|
||||
|
||||
return vp
|
||||
|
||||
def calibration_validity(self):
|
||||
# this function sanity checks that the small box is contained in the big box.
|
||||
# otherwise the warp function will generate black spots on the small box
|
||||
cp = np.asarray([[0, 0],
|
||||
[self.box_size[0], 0],
|
||||
[self.box_size[0], self.box_size[1]],
|
||||
[0, self.box_size[1]]])
|
||||
|
||||
cpw = warp_points(cp, self.warp_matrix)
|
||||
|
||||
# pixel margin for validity hysteresys:
|
||||
# - if calibration is good, keep it good until small box is inside the big box
|
||||
# - if calibration isn't good, then make it good again if small box is in big box with margin
|
||||
margin_px = 0 if self.cal_status == CalibStatus.VALID else 5
|
||||
big_hit_box = np.asarray(
|
||||
[[margin_px, margin_px],
|
||||
[self.big_box_size[0], self.big_box_size[1] - margin_px]])
|
||||
|
||||
cpw_outside_big_box = np.logical_not(points_inside_hit_box(cpw, big_hit_box))
|
||||
return not np.any(cpw_outside_big_box)
|
||||
|
||||
|
||||
def get_calibration_hit_box(self):
|
||||
"""Returns an axis-aligned hit box in canonical image space.
|
||||
Points which do not fall within this box should not be used for
|
||||
calibration.
|
||||
|
||||
Returns:
|
||||
An array [[x_left, y_top], [x_right, y_bottom]] describing a box inside
|
||||
which all calibration points should lie.
|
||||
"""
|
||||
# We mainly care about feature from lanes, so removed points from sky.
|
||||
y_filter = 50.
|
||||
return np.asarray([[0, y_filter], [self.box_size[0], self.box_size[1]]])
|
||||
|
||||
|
||||
def update_warp_matrix(self):
|
||||
translation_matrix = np.asarray(
|
||||
[[1, 0, self.vp_f[0] - self.vp_r[0]],
|
||||
[0, 1, self.vp_f[1] - self.vp_r[1]],
|
||||
[0, 0, 1]])
|
||||
self.warp_matrix = np.dot(translation_matrix, self.warp_matrix_start)
|
||||
self.warp_matrix_inv = np.linalg.inv(self.warp_matrix)
|
||||
|
||||
def calibration(self, p0, p1, st, v_ego, steer_angle, VP):
|
||||
# convert to np array first thing
|
||||
p0 = np.asarray(p0)
|
||||
p1 = np.asarray(p1)
|
||||
st = np.asarray(st)
|
||||
|
||||
p0 = p0.reshape((-1,2))
|
||||
p1 = p1.reshape((-1,2))
|
||||
|
||||
# filter out pts with bad status
|
||||
p0 = p0[st==1]
|
||||
p1 = p1[st==1]
|
||||
|
||||
calib_hit_box = self.get_calibration_hit_box()
|
||||
# remove all the points outside the small box and above the horizon line
|
||||
good_idxs = points_inside_hit_box(
|
||||
warp_points(p0, self.warp_matrix_inv), calib_hit_box)
|
||||
p0 = p0[good_idxs]
|
||||
p1 = p1[good_idxs]
|
||||
|
||||
# print("unwarped points: {}".format(warp_points(p0, self.warp_matrix_inv)))
|
||||
# print("good_idxs {}:".format(good_idxs))
|
||||
|
||||
# get instantaneous vp
|
||||
vp = self.vanishing_point_process(p0, p1, v_ego, steer_angle, VP)
|
||||
|
||||
if vp is not None:
|
||||
# filter the vanishing point
|
||||
self.vp_f = [self.vp_x_filter(vp[0]), self.vp_y_filter(vp[1])]
|
||||
self.cal_cycle += 1
|
||||
|
||||
if not self.calibration_validity():
|
||||
self.cal_status = CalibStatus.INVALID
|
||||
else:
|
||||
# 10 minutes @5Hz TODO: make this threshold function of convergency speed
|
||||
self.cal_status = CalibStatus.VALID
|
||||
#self.cal_status = CalibStatus.VALID if self.cal_cycle > self.calibration_threshold else CalibStatus.INCOMPLETE
|
||||
self.cal_perc = int(np.minimum(self.cal_cycle*100./self.calibration_threshold, 100))
|
||||
|
||||
self.update_warp_matrix()
|
||||
@@ -1,116 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import numpy as np
|
||||
import zmq
|
||||
|
||||
from common.services import service_list
|
||||
import selfdrive.messaging as messaging
|
||||
from selfdrive.config import ImageParams, VehicleParams
|
||||
from selfdrive.calibrationd.calibration import ViewCalibrator, CalibStatus
|
||||
|
||||
CALIBRATION_FILE = "/sdcard/calibration_param"
|
||||
|
||||
def load_calibration(gctx):
|
||||
# calibration initialization
|
||||
I = ImageParams()
|
||||
vp_guess = None
|
||||
|
||||
if gctx is not None:
|
||||
warp_matrix_start = np.array(
|
||||
gctx['calibration']["initial_homography"]).reshape(3, 3)
|
||||
big_box_size = [560, 304]
|
||||
else:
|
||||
warp_matrix_start = np.array([[1., 0., I.SX_R],
|
||||
[0., 1., I.SY_R],
|
||||
[0., 0., 1.]])
|
||||
big_box_size = [640, 480]
|
||||
|
||||
# translate the vanishing point into phone image space
|
||||
vp_box = (I.VPX_R-I.SX_R, I.VPY_R-I.SY_R)
|
||||
vp_trans = np.dot(warp_matrix_start, vp_box+(1.,))
|
||||
vp_img = (vp_trans[0]/vp_trans[2], vp_trans[1]/vp_trans[2])
|
||||
|
||||
# load calibration data
|
||||
if os.path.isfile(CALIBRATION_FILE):
|
||||
# if the calibration file exist, start from the last cal values
|
||||
with open(CALIBRATION_FILE, "r") as cal_file:
|
||||
data = [float(l.strip()) for l in cal_file.readlines()]
|
||||
calib = ViewCalibrator((I.X, I.Y),
|
||||
big_box_size,
|
||||
vp_img,
|
||||
warp_matrix_start,
|
||||
vp_f=[data[2], data[3]],
|
||||
cal_cycle=data[0],
|
||||
cal_status=data[1])
|
||||
|
||||
if calib.cal_status == CalibStatus.INCOMPLETE:
|
||||
print "CALIBRATION IN PROGRESS", calib.cal_cycle
|
||||
else:
|
||||
print "NO CALIBRATION FILE"
|
||||
calib = ViewCalibrator((I.X, I.Y),
|
||||
big_box_size,
|
||||
vp_img,
|
||||
warp_matrix_start,
|
||||
vp_f=vp_guess)
|
||||
|
||||
return calib
|
||||
|
||||
def calibrationd_thread(gctx):
|
||||
context = zmq.Context()
|
||||
|
||||
features = messaging.sub_sock(context, service_list['features'].port)
|
||||
live100 = messaging.sub_sock(context, service_list['live100'].port)
|
||||
|
||||
livecalibration = messaging.pub_sock(context, service_list['liveCalibration'].port)
|
||||
|
||||
# subscribe to stats about the car
|
||||
VP = VehicleParams(False)
|
||||
|
||||
v_ego = None
|
||||
|
||||
calib = load_calibration(gctx)
|
||||
last_cal_cycle = calib.cal_cycle
|
||||
|
||||
while 1:
|
||||
# calibration at the end so it does not delay radar processing above
|
||||
ft = messaging.recv_sock(features, wait=True)
|
||||
|
||||
# get latest here
|
||||
l100 = messaging.recv_sock(live100)
|
||||
if l100 is not None:
|
||||
v_ego = l100.live100.vEgo
|
||||
steer_angle = l100.live100.angleSteers
|
||||
|
||||
if v_ego is None:
|
||||
continue
|
||||
|
||||
p0 = ft.features.p0
|
||||
p1 = ft.features.p1
|
||||
st = ft.features.status
|
||||
|
||||
calib.calibration(p0, p1, st, v_ego, steer_angle, VP)
|
||||
|
||||
# write a new calibration every 100 cal cycle
|
||||
if calib.cal_cycle - last_cal_cycle >= 100:
|
||||
print "writing cal", calib.cal_cycle
|
||||
with open(CALIBRATION_FILE, "w") as cal_file:
|
||||
cal_file.write(str(calib.cal_cycle)+'\n')
|
||||
cal_file.write(str(calib.cal_status)+'\n')
|
||||
cal_file.write(str(calib.vp_f[0])+'\n')
|
||||
cal_file.write(str(calib.vp_f[1])+'\n')
|
||||
last_cal_cycle = calib.cal_cycle
|
||||
|
||||
warp_matrix = map(float, calib.warp_matrix.reshape(9).tolist())
|
||||
dat = messaging.new_message()
|
||||
dat.init('liveCalibration')
|
||||
dat.liveCalibration.warpMatrix = warp_matrix
|
||||
dat.liveCalibration.calStatus = calib.cal_status
|
||||
dat.liveCalibration.calCycle = calib.cal_cycle
|
||||
dat.liveCalibration.calPerc = calib.cal_perc
|
||||
livecalibration.send(dat.to_bytes())
|
||||
|
||||
def main(gctx=None):
|
||||
calibrationd_thread(gctx)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,12 +0,0 @@
|
||||
fingerprints = {
|
||||
"ACURA ILX 2016 ACURAWATCH PLUS": {
|
||||
1024L: 5, 513L: 5, 1027L: 5, 1029L: 8, 929L: 4, 1057L: 5, 777L: 8, 1034L: 5, 1036L: 8, 398L: 3, 399L: 7, 145L: 8, 660L: 8, 985L: 3, 923L: 2, 542L: 7, 773L: 7, 800L: 8, 432L: 7, 419L: 8, 420L: 8, 1030L: 5, 422L: 8, 808L: 8, 428L: 8, 304L: 8, 819L: 7, 821L: 5, 57L: 3, 316L: 8, 545L: 4, 464L: 8, 1108L: 8, 597L: 8, 342L: 6, 983L: 8, 344L: 8, 804L: 8, 1039L: 8, 476L: 4, 892L: 8, 490L: 8, 1064L: 7, 882L: 2, 884L: 7, 887L: 8, 888L: 8, 380L: 8, 1365L: 5,
|
||||
# sent messages
|
||||
0xe4: 5, 0x1fa: 8, 0x200: 3, 0x30c: 8, 0x33d: 4,
|
||||
},
|
||||
"HONDA CIVIC 2016 TOURING": {
|
||||
1024L: 5, 513L: 5, 1027L: 5, 1029L: 8, 777L: 8, 1036L: 8, 1039L: 8, 1424L: 5, 401L: 8, 148L: 8, 662L: 4, 985L: 3, 795L: 8, 773L: 7, 800L: 8, 545L: 6, 420L: 8, 806L: 8, 808L: 8, 1322L: 5, 427L: 3, 428L: 8, 304L: 8, 432L: 7, 57L: 3, 450L: 8, 929L: 8, 330L: 8, 1302L: 8, 464L: 8, 1361L: 5, 1108L: 8, 597L: 8, 470L: 2, 344L: 8, 804L: 8, 399L: 7, 476L: 7, 1633L: 8, 487L: 4, 892L: 8, 490L: 8, 493L: 5, 884L: 8, 891L: 8, 380L: 8, 1365L: 5,
|
||||
# sent messages
|
||||
0xe4: 5, 0x1fa: 8, 0x200: 3, 0x30c: 8, 0x33d: 5, 0x35e: 8, 0x39f: 8,
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import os
|
||||
import dbcs
|
||||
import opendbc
|
||||
from collections import defaultdict
|
||||
|
||||
from selfdrive.car.honda.hondacan import fix
|
||||
@@ -19,13 +19,12 @@ class CANParser(object):
|
||||
# monitored.
|
||||
# - frequency is the frequency at which health should be monitored.
|
||||
|
||||
self.msgs_ck = [check[0] for check in checks]
|
||||
self.frqs = [check[1] for check in checks]
|
||||
self.msgs_ck = set([check[0] for check in checks])
|
||||
self.frqs = dict(checks)
|
||||
self.can_valid = False # start with False CAN assumption
|
||||
self.msgs_upd = [] # list of updated messages
|
||||
# list of received msg we want to monitor counter and checksum for
|
||||
# read dbc file
|
||||
self.can_dbc = dbc(os.path.join(dbcs.DBC_PATH, dbc_f))
|
||||
self.can_dbc = dbc(os.path.join(opendbc.DBC_PATH, dbc_f))
|
||||
# initialize variables to initial values
|
||||
self.vl = {} # signal values
|
||||
self.ts = {} # time stamp recorded in log
|
||||
@@ -55,14 +54,16 @@ class CANParser(object):
|
||||
self._message_indices[x].append(i)
|
||||
|
||||
def update_can(self, can_recv):
|
||||
self.msgs_upd = []
|
||||
msgs_upd = []
|
||||
cn_vl_max = 5 # no more than 5 wrong counter checks
|
||||
|
||||
self.sec_since_boot_cached = sec_since_boot()
|
||||
|
||||
# we are subscribing to PID_XXX, else data from USB
|
||||
for msg, ts, cdat, _ in can_recv:
|
||||
idxs = self._message_indices[msg]
|
||||
if idxs:
|
||||
self.msgs_upd.append(msg)
|
||||
msgs_upd.append(msg)
|
||||
# read the entire message
|
||||
out = self.can_dbc.decode((msg, 0, cdat))[1]
|
||||
# checksum check
|
||||
@@ -74,7 +75,7 @@ class CANParser(object):
|
||||
msg_vl = fix(ck_portion, msg)
|
||||
# compare recalculated vs received checksum
|
||||
if msg_vl != cdat:
|
||||
print hex(msg), "CHECKSUM FAIL"
|
||||
print "CHECKSUM FAIL: " + hex(msg)
|
||||
self.ck[msg] = False
|
||||
self.ok[msg] = False
|
||||
# counter check
|
||||
@@ -89,11 +90,12 @@ class CANParser(object):
|
||||
self.cn_vl[msg] -= 1 # counter check passed
|
||||
# message status is invalid if we received too many wrong counter values
|
||||
if self.cn_vl[msg] >= cn_vl_max:
|
||||
print "COUNTER WRONG: " + hex(msg)
|
||||
self.ok[msg] = False
|
||||
|
||||
# update msg time stamps and counter value
|
||||
self.ts[msg] = ts
|
||||
self.ct[msg] = sec_since_boot()
|
||||
self.ct[msg] = self.sec_since_boot_cached
|
||||
self.cn[msg] = cn
|
||||
self.cn_vl[msg] = min(max(self.cn_vl[msg], 0), cn_vl_max)
|
||||
|
||||
@@ -106,7 +108,7 @@ class CANParser(object):
|
||||
sg = self._sgs[ii]
|
||||
self.vl[msg][sg] = out[sg]
|
||||
|
||||
# for each message, check if it's too long since last time we received it
|
||||
# for each message, check if it's too long since last time we received it
|
||||
self._check_dead_msgs()
|
||||
|
||||
# assess overall can validity: if there is one relevant message invalid, then set can validity flag to False
|
||||
@@ -115,9 +117,11 @@ class CANParser(object):
|
||||
#print "CAN INVALID!"
|
||||
self.can_valid = False
|
||||
|
||||
return msgs_upd
|
||||
|
||||
def _check_dead_msgs(self):
|
||||
### input:
|
||||
## simple stuff for now: msg is not valid if a message isn't received for 10 consecutive steps
|
||||
for msg in set(self._msgs):
|
||||
if msg in self.msgs_ck and sec_since_boot() - self.ct[msg] > 10./self.frqs[self.msgs_ck.index(msg)]:
|
||||
if msg in self.msgs_ck and self.sec_since_boot_cached - self.ct[msg] > 10./self.frqs[msg]:
|
||||
self.ok[msg] = False
|
||||
|
||||
@@ -4,7 +4,39 @@ import common.numpy_fast as np
|
||||
from common.realtime import sec_since_boot
|
||||
from selfdrive.config import CruiseButtons
|
||||
from selfdrive.boardd.boardd import can_list_to_can_capnp
|
||||
from selfdrive.controls.lib.drive_helpers import actuator_hystereses, rate_limit
|
||||
from selfdrive.controls.lib.drive_helpers import rate_limit
|
||||
from common.numpy_fast import clip, interp
|
||||
|
||||
def actuator_hystereses(final_brake, braking, brake_steady, v_ego, civic):
|
||||
# hyst params... TODO: move these to VehicleParams
|
||||
brake_hyst_on = 0.055 if civic else 0.1 # to activate brakes exceed this value
|
||||
brake_hyst_off = 0.005 # to deactivate brakes below this value
|
||||
brake_hyst_gap = 0.01 # don't change brake command for small ocilalitons within this value
|
||||
|
||||
#*** histeresys logic to avoid brake blinking. go above 0.1 to trigger
|
||||
if (final_brake < brake_hyst_on and not braking) or final_brake < brake_hyst_off:
|
||||
final_brake = 0.
|
||||
braking = final_brake > 0.
|
||||
|
||||
# for small brake oscillations within brake_hyst_gap, don't change the brake command
|
||||
if final_brake == 0.:
|
||||
brake_steady = 0.
|
||||
elif final_brake > brake_steady + brake_hyst_gap:
|
||||
brake_steady = final_brake - brake_hyst_gap
|
||||
elif final_brake < brake_steady - brake_hyst_gap:
|
||||
brake_steady = final_brake + brake_hyst_gap
|
||||
final_brake = brake_steady
|
||||
|
||||
if not civic:
|
||||
brake_on_offset_v = [.25, .15] # min brake command on brake activation. below this no decel is perceived
|
||||
brake_on_offset_bp = [15., 30.] # offset changes VS speed to not have too abrupt decels at high speeds
|
||||
# offset the brake command for threshold in the brake system. no brake torque perceived below it
|
||||
brake_on_offset = interp(v_ego, brake_on_offset_bp, brake_on_offset_v)
|
||||
brake_offset = brake_on_offset - brake_hyst_on
|
||||
if final_brake > 0.0:
|
||||
final_brake += brake_offset
|
||||
|
||||
return final_brake, braking, brake_steady
|
||||
|
||||
class AH:
|
||||
#[alert_idx, value]
|
||||
@@ -23,7 +55,7 @@ def process_hud_alert(hud_alert):
|
||||
fcw_display = 0
|
||||
steer_required = 0
|
||||
acc_alert = 0
|
||||
if hud_alert == AH.NONE: # no alert
|
||||
if hud_alert == AH.NONE: # no alert
|
||||
pass
|
||||
elif hud_alert == AH.FCW: # FCW
|
||||
fcw_display = hud_alert[1]
|
||||
@@ -55,6 +87,10 @@ class CarController(object):
|
||||
snd_beep, snd_chime):
|
||||
""" Controls thread """
|
||||
|
||||
# TODO: Make the accord work.
|
||||
if CS.accord:
|
||||
return
|
||||
|
||||
# *** apply brake hysteresis ***
|
||||
final_brake, self.braking, self.brake_steady = actuator_hystereses(final_brake, self.braking, self.brake_steady, CS.v_ego, CS.civic)
|
||||
|
||||
@@ -90,7 +126,7 @@ class CarController(object):
|
||||
#print chime, alert_id, hud_alert
|
||||
fcw_display, steer_required, acc_alert = process_hud_alert(hud_alert)
|
||||
|
||||
hud = HUDData(int(pcm_accel), int(hud_v_cruise), 0x41, hud_car,
|
||||
hud = HUDData(int(pcm_accel), int(hud_v_cruise), 0x01, hud_car,
|
||||
0xc1, 0x41, hud_lanes + steer_required,
|
||||
int(snd_beep), 0x48, (snd_chime << 5) + fcw_display, acc_alert)
|
||||
|
||||
@@ -104,13 +140,18 @@ class CarController(object):
|
||||
tt = sec_since_boot()
|
||||
GAS_MAX = 1004
|
||||
BRAKE_MAX = 1024/4
|
||||
STEER_MAX = 0xF00
|
||||
if CS.civic:
|
||||
STEER_MAX = 0x1000
|
||||
elif CS.crv:
|
||||
STEER_MAX = 0x300 # CR-V only uses 12-bits and requires a lower value
|
||||
else:
|
||||
STEER_MAX = 0xF00
|
||||
GAS_OFFSET = 328
|
||||
|
||||
# steer torque is converted back to CAN reference (positive when steering right)
|
||||
apply_gas = int(np.clip(final_gas*GAS_MAX, 0, GAS_MAX-1))
|
||||
apply_brake = int(np.clip(final_brake*BRAKE_MAX, 0, BRAKE_MAX-1))
|
||||
apply_steer = int(np.clip(-final_steer*STEER_MAX, -STEER_MAX, STEER_MAX))
|
||||
apply_gas = int(clip(final_gas*GAS_MAX, 0, GAS_MAX-1))
|
||||
apply_brake = int(clip(final_brake*BRAKE_MAX, 0, BRAKE_MAX-1))
|
||||
apply_steer = int(clip(-final_steer*STEER_MAX, -STEER_MAX, STEER_MAX))
|
||||
|
||||
# no gas if you are hitting the brake or the user is
|
||||
if apply_gas > 0 and (apply_brake != 0 or CS.brake_pressed):
|
||||
@@ -156,8 +197,12 @@ class CarController(object):
|
||||
can_sends = []
|
||||
|
||||
# Send steering command.
|
||||
idx = frame % 4
|
||||
can_sends.append(hondacan.create_steering_control(apply_steer, idx))
|
||||
if CS.accord:
|
||||
idx = frame % 2
|
||||
can_sends.append(hondacan.create_accord_steering_control(apply_steer, idx))
|
||||
else:
|
||||
idx = frame % 4
|
||||
can_sends.extend(hondacan.create_steering_control(apply_steer, CS.crv, idx))
|
||||
|
||||
# Send gas and brake commands.
|
||||
if (frame % 2) == 0:
|
||||
@@ -166,7 +211,7 @@ class CarController(object):
|
||||
hondacan.create_brake_command(apply_brake, pcm_override,
|
||||
pcm_cancel_cmd, hud.chime, idx))
|
||||
if not CS.brake_only:
|
||||
# send exactly zero if apply_gas is zero. Interceptor will send the max between read value and apply_gas.
|
||||
# send exactly zero if apply_gas is zero. Interceptor will send the max between read value and apply_gas.
|
||||
# This prevents unexpected pedal range rescaling
|
||||
gas_amount = (apply_gas + GAS_OFFSET) * (apply_gas > 0)
|
||||
can_sends.append(hondacan.create_gas_command(gas_amount, idx))
|
||||
@@ -174,17 +219,16 @@ class CarController(object):
|
||||
# Send dashboard UI commands.
|
||||
if (frame % 10) == 0:
|
||||
idx = (frame/10) % 4
|
||||
can_sends.extend(hondacan.create_ui_commands(pcm_speed, hud, CS.civic, idx))
|
||||
can_sends.extend(hondacan.create_ui_commands(pcm_speed, hud, CS.civic, CS.accord, CS.crv, idx))
|
||||
|
||||
# radar at 20Hz, but these msgs need to be sent at 50Hz on ilx (seems like an Acura bug)
|
||||
if CS.civic:
|
||||
if CS.civic or CS.accord or CS.crv:
|
||||
radar_send_step = 5
|
||||
else:
|
||||
radar_send_step = 2
|
||||
|
||||
if (frame % radar_send_step) == 0:
|
||||
idx = (frame/radar_send_step) % 4
|
||||
can_sends.extend(hondacan.create_radar_commands(CS.v_ego, CS.civic, idx))
|
||||
can_sends.extend(hondacan.create_radar_commands(CS.v_ego, CS.civic, CS.accord, CS.crv, idx))
|
||||
|
||||
sendcan.send(can_list_to_can_capnp(can_sends, msgtype='sendcan').to_bytes())
|
||||
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
import numpy as np
|
||||
import common.numpy_fast as np
|
||||
|
||||
import selfdrive.messaging as messaging
|
||||
from selfdrive.boardd.boardd import can_capnp_to_can_list
|
||||
from selfdrive.config import VehicleParams
|
||||
from common.realtime import sec_since_boot
|
||||
|
||||
from selfdrive.car.fingerprints import fingerprints
|
||||
from selfdrive.car.honda.can_parser import CANParser
|
||||
|
||||
def get_can_parser(civic, brake_only):
|
||||
def get_can_parser(CP):
|
||||
# this function generates lists for signal, messages and initial values
|
||||
if civic:
|
||||
if CP.carFingerprint == "HONDA CIVIC 2016 TOURING":
|
||||
dbc_f = 'honda_civic_touring_2016_can.dbc'
|
||||
signals = [
|
||||
("XMISSION_SPEED", 0x158, 0),
|
||||
@@ -62,7 +59,7 @@ def get_can_parser(civic, brake_only):
|
||||
(0x405, 3),
|
||||
]
|
||||
|
||||
else:
|
||||
elif CP.carFingerprint == "ACURA ILX 2016 ACURAWATCH PLUS":
|
||||
dbc_f = 'acura_ilx_2016_can.dbc'
|
||||
signals = [
|
||||
("XMISSION_SPEED", 0x158, 0),
|
||||
@@ -113,72 +110,139 @@ def get_can_parser(civic, brake_only):
|
||||
(0x324, 10),
|
||||
(0x405, 3),
|
||||
]
|
||||
|
||||
elif CP.carFingerprint == "HONDA ACCORD 2016 TOURING":
|
||||
dbc_f = 'honda_accord_touring_2016_can.dbc'
|
||||
signals = [
|
||||
("XMISSION_SPEED", 0x158, 0),
|
||||
("WHEEL_SPEED_FL", 0x1d0, 0),
|
||||
("WHEEL_SPEED_FR", 0x1d0, 0),
|
||||
("WHEEL_SPEED_RL", 0x1d0, 0),
|
||||
("STEER_ANGLE", 0x156, 0),
|
||||
#("STEER_TORQUE_SENSOR", 0x18f, 0),
|
||||
("GEAR", 0x191, 0),
|
||||
("WHEELS_MOVING", 0x1b0, 1),
|
||||
("DOOR_OPEN_FL", 0x405, 1),
|
||||
("DOOR_OPEN_FR", 0x405, 1),
|
||||
("DOOR_OPEN_RL", 0x405, 1),
|
||||
("DOOR_OPEN_RR", 0x405, 1),
|
||||
("CRUISE_SPEED_PCM", 0x324, 0),
|
||||
("SEATBELT_DRIVER_LAMP", 0x305, 1),
|
||||
("SEATBELT_DRIVER_LATCHED", 0x305, 0),
|
||||
("BRAKE_PRESSED", 0x17c, 0),
|
||||
#("CAR_GAS", 0x130, 0),
|
||||
("PEDAL_GAS", 0x17C, 0),
|
||||
("CRUISE_BUTTONS", 0x1a6, 0),
|
||||
("ESP_DISABLED", 0x1a4, 1),
|
||||
("HUD_LEAD", 0x30c, 0),
|
||||
("USER_BRAKE", 0x1a4, 0),
|
||||
#("STEER_STATUS", 0x18f, 5),
|
||||
("WHEEL_SPEED_RR", 0x1d0, 0),
|
||||
("BRAKE_ERROR_1", 0x1b0, 1),
|
||||
("BRAKE_ERROR_2", 0x1b0, 1),
|
||||
("GEAR_SHIFTER", 0x191, 0),
|
||||
("MAIN_ON", 0x1a6, 0),
|
||||
("ACC_STATUS", 0x17c, 0),
|
||||
("PEDAL_GAS", 0x17c, 0),
|
||||
("CRUISE_SETTING", 0x1a6, 0),
|
||||
("LEFT_BLINKER", 0x294, 0),
|
||||
("RIGHT_BLINKER", 0x294, 0),
|
||||
("COUNTER", 0x324, 0),
|
||||
("ENGINE_RPM", 0x17C, 0)
|
||||
]
|
||||
checks = [
|
||||
(0x156, 100),
|
||||
(0x158, 100),
|
||||
(0x17c, 100),
|
||||
#(0x1a3, 50),
|
||||
(0x1a4, 50),
|
||||
(0x1a6, 50),
|
||||
(0x1b0, 50),
|
||||
(0x1d0, 50),
|
||||
(0x305, 10),
|
||||
(0x324, 10),
|
||||
(0x405, 3),
|
||||
]
|
||||
elif CP.carFingerprint == "HONDA CR-V 2016 TOURING":
|
||||
dbc_f = 'honda_crv_touring_2016_can.dbc'
|
||||
signals = [
|
||||
("XMISSION_SPEED", 0x158, 0),
|
||||
("WHEEL_SPEED_FL", 0x1d0, 0),
|
||||
("WHEEL_SPEED_FR", 0x1d0, 0),
|
||||
("WHEEL_SPEED_RL", 0x1d0, 0),
|
||||
("STEER_ANGLE", 0x156, 0),
|
||||
("STEER_TORQUE_SENSOR", 0x18f, 0),
|
||||
("GEAR", 0x191, 0),
|
||||
("WHEELS_MOVING", 0x1b0, 1),
|
||||
("DOOR_OPEN_FL", 0x405, 1),
|
||||
("DOOR_OPEN_FR", 0x405, 1),
|
||||
("DOOR_OPEN_RL", 0x405, 1),
|
||||
("DOOR_OPEN_RR", 0x405, 1),
|
||||
("CRUISE_SPEED_PCM", 0x324, 0),
|
||||
("SEATBELT_DRIVER_LAMP", 0x305, 1),
|
||||
("SEATBELT_DRIVER_LATCHED", 0x305, 0),
|
||||
("BRAKE_PRESSED", 0x17c, 0),
|
||||
#("CAR_GAS", 0x130, 0),
|
||||
("CRUISE_BUTTONS", 0x1a6, 0),
|
||||
("ESP_DISABLED", 0x1a4, 1),
|
||||
("HUD_LEAD", 0x30c, 0),
|
||||
("USER_BRAKE", 0x1a4, 0),
|
||||
("STEER_STATUS", 0x18f, 5),
|
||||
("WHEEL_SPEED_RR", 0x1d0, 0),
|
||||
("BRAKE_ERROR_1", 0x1b0, 1),
|
||||
("BRAKE_ERROR_2", 0x1b0, 1),
|
||||
("GEAR_SHIFTER", 0x191, 0),
|
||||
("MAIN_ON", 0x1a6, 0),
|
||||
("ACC_STATUS", 0x17c, 0),
|
||||
("PEDAL_GAS", 0x17c, 0),
|
||||
("CRUISE_SETTING", 0x1a6, 0),
|
||||
("LEFT_BLINKER", 0x294, 0),
|
||||
("RIGHT_BLINKER", 0x294, 0),
|
||||
("COUNTER", 0x324, 0),
|
||||
("ENGINE_RPM", 0x17C, 0)
|
||||
]
|
||||
checks = [
|
||||
(0x156, 100),
|
||||
(0x158, 100),
|
||||
(0x17c, 100),
|
||||
(0x191, 100),
|
||||
(0x1a3, 50),
|
||||
(0x1a4, 50),
|
||||
(0x1a6, 50),
|
||||
(0x1b0, 50),
|
||||
(0x1d0, 50),
|
||||
(0x305, 10),
|
||||
(0x324, 10),
|
||||
(0x405, 3),
|
||||
]
|
||||
# add gas interceptor reading if we are using it
|
||||
if not brake_only:
|
||||
if CP.enableGas:
|
||||
signals.append(("INTERCEPTOR_GAS", 0x201, 0))
|
||||
checks.append((0x201, 50))
|
||||
|
||||
return CANParser(dbc_f, signals, checks)
|
||||
|
||||
def fingerprint(logcan):
|
||||
print "waiting for fingerprint..."
|
||||
brake_only = True
|
||||
|
||||
finger = {}
|
||||
st = None
|
||||
while 1:
|
||||
possible_cars = []
|
||||
for a in messaging.drain_sock(logcan, wait_for_one=True):
|
||||
if st is None:
|
||||
st = sec_since_boot()
|
||||
for adr, _, msg, idx in can_capnp_to_can_list(a.can):
|
||||
# pedal
|
||||
if adr == 0x201 and idx == 0:
|
||||
brake_only = False
|
||||
if idx == 0:
|
||||
finger[adr] = len(msg)
|
||||
|
||||
# check for a single match
|
||||
for f in fingerprints:
|
||||
is_possible = True
|
||||
for adr in finger:
|
||||
# confirm all messages we have seen match
|
||||
if adr not in fingerprints[f] or fingerprints[f][adr] != finger[adr]:
|
||||
#print "mismatch", f, adr
|
||||
is_possible = False
|
||||
break
|
||||
if is_possible:
|
||||
possible_cars.append(f)
|
||||
|
||||
# if we only have one car choice and it's been 100ms since we got our first message, exit
|
||||
if len(possible_cars) == 1 and st is not None and (sec_since_boot()-st) > 0.1:
|
||||
break
|
||||
elif len(possible_cars) == 0:
|
||||
print finger
|
||||
raise Exception("car doesn't match any fingerprints")
|
||||
|
||||
print "fingerprinted", possible_cars[0]
|
||||
return brake_only, possible_cars[0]
|
||||
|
||||
class CarState(object):
|
||||
def __init__(self, logcan):
|
||||
self.torque_mod = False
|
||||
self.brake_only, self.car_type = fingerprint(logcan)
|
||||
|
||||
# assuming if you have a pedal interceptor you also have a torque mod
|
||||
if not self.brake_only:
|
||||
self.torque_mod = True
|
||||
|
||||
if self.car_type == "HONDA CIVIC 2016 TOURING":
|
||||
def __init__(self, CP, logcan):
|
||||
self.civic = False
|
||||
self.accord = False
|
||||
self.crv = False
|
||||
if CP.carFingerprint == "HONDA CIVIC 2016 TOURING":
|
||||
self.civic = True
|
||||
elif self.car_type == "ACURA ILX 2016 ACURAWATCH PLUS":
|
||||
elif CP.carFingerprint == "ACURA ILX 2016 ACURAWATCH PLUS":
|
||||
self.civic = False
|
||||
elif CP.carFingerprint == "HONDA ACCORD 2016 TOURING":
|
||||
# fake civic
|
||||
self.accord = True
|
||||
elif CP.carFingerprint == "HONDA CR-V 2016 TOURING":
|
||||
self.crv = True
|
||||
else:
|
||||
raise ValueError("unsupported car %s" % self.car_type)
|
||||
raise ValueError("unsupported car %s" % CP.carFingerprint)
|
||||
|
||||
self.brake_only = CP.enableCruise
|
||||
self.CP = CP
|
||||
|
||||
# initialize can parser
|
||||
self.cp = get_can_parser(self.civic, self.brake_only)
|
||||
self.cp = get_can_parser(CP)
|
||||
|
||||
self.user_gas, self.user_gas_pressed = 0., 0
|
||||
|
||||
@@ -192,12 +256,6 @@ class CarState(object):
|
||||
# TODO: actually make this work
|
||||
self.a_ego = 0.
|
||||
|
||||
# speed in UI is shown as few % higher
|
||||
self.ui_speed_fudge = 1.01 if self.civic else 1.025
|
||||
|
||||
# load vehicle params
|
||||
self.VP = VehicleParams(self.civic, self.brake_only, self.torque_mod)
|
||||
|
||||
def update(self, can_pub_main):
|
||||
cp = self.cp
|
||||
cp.update_can(can_pub_main)
|
||||
@@ -230,10 +288,14 @@ class CarState(object):
|
||||
# error 7 (permanent)
|
||||
#self.steer_error = cp.vl[0x18F]['STEER_STATUS'] in [5,7]
|
||||
# whitelist instead of blacklist, safer at the expense of disengages
|
||||
self.steer_error = cp.vl[0x18F]['STEER_STATUS'] not in [0,2,4,6]
|
||||
self.steer_not_allowed = cp.vl[0x18F]['STEER_STATUS'] != 0
|
||||
if cp.vl[0x18F]['STEER_STATUS'] != 0:
|
||||
print cp.vl[0x18F]['STEER_STATUS']
|
||||
if self.accord:
|
||||
self.steer_error = False
|
||||
self.steer_not_allowed = False
|
||||
else:
|
||||
self.steer_error = cp.vl[0x18F]['STEER_STATUS'] not in [0,2,4,6]
|
||||
self.steer_not_allowed = cp.vl[0x18F]['STEER_STATUS'] != 0
|
||||
if cp.vl[0x18F]['STEER_STATUS'] != 0:
|
||||
print cp.vl[0x18F]['STEER_STATUS']
|
||||
self.brake_error = cp.vl[0x1B0]['BRAKE_ERROR_1'] or cp.vl[0x1B0]['BRAKE_ERROR_2']
|
||||
self.esp_disabled = cp.vl[0x1A4]['ESP_DISABLED']
|
||||
# calc best v_ego estimate, by averaging two opposite corners
|
||||
@@ -243,10 +305,11 @@ class CarState(object):
|
||||
# blend in transmission speed at low speed, since it has more low speed accuracy
|
||||
self.v_weight = np.interp(self.v_wheel, v_weight_bp, v_weight_v)
|
||||
self.v_ego = (1. - self.v_weight) * cp.vl[0x158]['XMISSION_SPEED'] + self.v_weight * self.v_wheel
|
||||
if not self.brake_only:
|
||||
if self.CP.enableGas:
|
||||
# this is a hack
|
||||
self.user_gas = cp.vl[0x201]['INTERCEPTOR_GAS']
|
||||
self.user_gas_pressed = self.user_gas > 0 # this works because interceptor read < 0 when pedal position is 0. Once calibrated, this will change
|
||||
#print user_gas, user_gas_pressed
|
||||
#print self.user_gas, self.user_gas_pressed
|
||||
if self.civic:
|
||||
self.gear_shifter = cp.vl[0x191]['GEAR_SHIFTER']
|
||||
self.angle_steers = cp.vl[0x14A]['STEER_ANGLE']
|
||||
@@ -258,6 +321,28 @@ class CarState(object):
|
||||
self.blinker_on = cp.vl[0x326]['LEFT_BLINKER'] or cp.vl[0x326]['RIGHT_BLINKER']
|
||||
self.left_blinker_on = cp.vl[0x326]['LEFT_BLINKER']
|
||||
self.right_blinker_on = cp.vl[0x326]['RIGHT_BLINKER']
|
||||
elif self.accord:
|
||||
self.gear_shifter = cp.vl[0x191]['GEAR_SHIFTER']
|
||||
self.angle_steers = cp.vl[0x156]['STEER_ANGLE']
|
||||
self.gear = 0 # TODO: accord has CVT... needs rev engineering
|
||||
self.cruise_setting = cp.vl[0x1A6]['CRUISE_SETTING']
|
||||
self.cruise_buttons = cp.vl[0x1A6]['CRUISE_BUTTONS']
|
||||
self.main_on = cp.vl[0x1A6]['MAIN_ON']
|
||||
self.gear_shifter_valid = self.gear_shifter in [1,8] # TODO: 1/P allowed for debug
|
||||
self.blinker_on = cp.vl[0x294]['LEFT_BLINKER'] or cp.vl[0x294]['RIGHT_BLINKER']
|
||||
self.left_blinker_on = cp.vl[0x294]['LEFT_BLINKER']
|
||||
self.right_blinker_on = cp.vl[0x294]['RIGHT_BLINKER']
|
||||
elif self.crv:
|
||||
self.gear_shifter = cp.vl[0x191]['GEAR_SHIFTER']
|
||||
self.angle_steers = cp.vl[0x156]['STEER_ANGLE']
|
||||
self.gear = cp.vl[0x191]['GEAR']
|
||||
self.cruise_setting = cp.vl[0x1A6]['CRUISE_SETTING']
|
||||
self.cruise_buttons = cp.vl[0x1A6]['CRUISE_BUTTONS']
|
||||
self.main_on = cp.vl[0x1A6]['MAIN_ON']
|
||||
self.gear_shifter_valid = self.gear_shifter in [1,8] # TODO: 1/P allowed for debug
|
||||
self.blinker_on = cp.vl[0x294]['LEFT_BLINKER'] or cp.vl[0x294]['RIGHT_BLINKER']
|
||||
self.left_blinker_on = cp.vl[0x294]['LEFT_BLINKER']
|
||||
self.right_blinker_on = cp.vl[0x294]['RIGHT_BLINKER']
|
||||
else:
|
||||
self.gear_shifter = cp.vl[0x1A3]['GEAR_SHIFTER']
|
||||
self.angle_steers = cp.vl[0x156]['STEER_ANGLE']
|
||||
@@ -269,14 +354,22 @@ class CarState(object):
|
||||
self.blinker_on = cp.vl[0x294]['LEFT_BLINKER'] or cp.vl[0x294]['RIGHT_BLINKER']
|
||||
self.left_blinker_on = cp.vl[0x294]['LEFT_BLINKER']
|
||||
self.right_blinker_on = cp.vl[0x294]['RIGHT_BLINKER']
|
||||
self.car_gas = cp.vl[0x130]['CAR_GAS']
|
||||
if self.accord:
|
||||
# on the accord, this doesn't seem to include cruise control
|
||||
self.car_gas = cp.vl[0x17C]['PEDAL_GAS']
|
||||
self.steer_override = False
|
||||
elif self.crv:
|
||||
# like accord, crv doesn't include cruise control
|
||||
self.car_gas = cp.vl[0x17C]['PEDAL_GAS']
|
||||
self.steer_override = abs(cp.vl[0x18F]['STEER_TORQUE_SENSOR']) > 1200
|
||||
else:
|
||||
self.car_gas = cp.vl[0x130]['CAR_GAS']
|
||||
self.steer_override = abs(cp.vl[0x18F]['STEER_TORQUE_SENSOR']) > 1200
|
||||
self.brake_pressed = cp.vl[0x17C]['BRAKE_PRESSED']
|
||||
self.user_brake = cp.vl[0x1A4]['USER_BRAKE']
|
||||
self.standstill = not cp.vl[0x1B0]['WHEELS_MOVING']
|
||||
self.steer_override = abs(cp.vl[0x18F]['STEER_TORQUE_SENSOR']) > 1200
|
||||
self.v_cruise_pcm = cp.vl[0x324]['CRUISE_SPEED_PCM']
|
||||
self.pcm_acc_status = cp.vl[0x17C]['ACC_STATUS']
|
||||
self.pedal_gas = cp.vl[0x17C]['PEDAL_GAS']
|
||||
self.hud_lead = cp.vl[0x30C]['HUD_LEAD']
|
||||
self.counter_pcm = cp.vl[0x324]['COUNTER']
|
||||
|
||||
|
||||
@@ -44,15 +44,45 @@ def create_gas_command(gas_amount, idx):
|
||||
msg = struct.pack("!H", gas_amount)
|
||||
return make_can_msg(0x200, msg, idx, 0)
|
||||
|
||||
def create_steering_control(apply_steer, idx):
|
||||
"""Creates a CAN message for the Honda DBC STEERING_CONTROL."""
|
||||
msg = struct.pack("!h", apply_steer) + ("\x80\x00" if apply_steer != 0 else "\x00\x00")
|
||||
return make_can_msg(0xe4, msg, idx, 0)
|
||||
def create_accord_steering_control(apply_steer, idx):
|
||||
# TODO: doesn't work for some reason
|
||||
if apply_steer == 0:
|
||||
dat = [0, 0, 0x40, 0]
|
||||
else:
|
||||
dat = [0,0,0,0]
|
||||
rp = np.clip(apply_steer/0xF, -0xFF, 0xFF)
|
||||
if rp < 0:
|
||||
rp += 512
|
||||
dat[0] |= (rp >> 5) & 0xf
|
||||
dat[1] |= (rp) & 0x1f
|
||||
if idx == 1:
|
||||
dat[0] |= 0x20
|
||||
dat[1] |= 0x20 # always
|
||||
dat[3] = -(dat[0]+dat[1]+dat[2]) & 0x7f
|
||||
|
||||
def create_ui_commands(pcm_speed, hud, civic, idx):
|
||||
# not first byte
|
||||
dat[1] |= 0x80
|
||||
dat[2] |= 0x80
|
||||
dat[3] |= 0x80
|
||||
dat = ''.join(map(chr, dat))
|
||||
|
||||
return [0,0,dat,8]
|
||||
|
||||
def create_steering_control(apply_steer, crv, idx):
|
||||
"""Creates a CAN message for the Honda DBC STEERING_CONTROL."""
|
||||
commands = []
|
||||
if crv:
|
||||
msg_0x194 = struct.pack("!h", apply_steer << 4) + ("\x80" if apply_steer != 0 else "\x00")
|
||||
commands.append(make_can_msg(0x194, msg_0x194, idx, 0))
|
||||
else:
|
||||
msg_0xe4 = struct.pack("!h", apply_steer) + ("\x80\x00" if apply_steer != 0 else "\x00\x00")
|
||||
commands.append(make_can_msg(0xe4, msg_0xe4, idx, 0))
|
||||
return commands
|
||||
|
||||
def create_ui_commands(pcm_speed, hud, civic, accord, crv, idx):
|
||||
"""Creates an iterable of CAN messages for the UIs."""
|
||||
commands = []
|
||||
pcm_speed_real = np.clip(int(round(pcm_speed / 0.002763889)), 0,
|
||||
pcm_speed_real = np.clip(int(round(pcm_speed / 0.002759506)), 0,
|
||||
64000) # conversion factor from dbc file
|
||||
msg_0x30c = struct.pack("!HBBBBB", pcm_speed_real, hud.pcm_accel,
|
||||
hud.v_cruise, hud.X2, hud.car, hud.X4)
|
||||
@@ -63,24 +93,35 @@ def create_ui_commands(pcm_speed, hud, civic, idx):
|
||||
if civic: # 2 more msgs
|
||||
msg_0x35e = chr(0) * 7
|
||||
commands.append(make_can_msg(0x35e, msg_0x35e, idx, 0))
|
||||
if civic or accord:
|
||||
msg_0x39f = (
|
||||
chr(0) * 2 + chr(hud.acc_alert) + chr(0) + chr(0xff) + chr(0x7f) + chr(0)
|
||||
)
|
||||
commands.append(make_can_msg(0x39f, msg_0x39f, idx, 0))
|
||||
return commands
|
||||
|
||||
def create_radar_commands(v_ego, civic, idx):
|
||||
def create_radar_commands(v_ego, civic, accord, crv, idx):
|
||||
"""Creates an iterable of CAN messages for the radar system."""
|
||||
commands = []
|
||||
v_ego_kph = np.clip(int(round(v_ego * CV.MS_TO_KPH)), 0, 255)
|
||||
speed = struct.pack('!B', v_ego_kph)
|
||||
|
||||
msg_0x300 = ("\xf9" + speed + "\x8a\xd0" +\
|
||||
("\x20" if idx == 0 or idx == 3 else "\x00") +\
|
||||
"\x00\x00")
|
||||
("\x20" if idx == 0 or idx == 3 else "\x00") +\
|
||||
"\x00\x00")
|
||||
if civic:
|
||||
msg_0x301 = "\x02\x38\x44\x32\x4f\x00\x00"
|
||||
# add 8 on idx.
|
||||
commands.append(make_can_msg(0x300, msg_0x300, idx + 8, 1))
|
||||
elif accord:
|
||||
# 0300( 768)( 69) f9008ad0100000ef
|
||||
# 0301( 769)( 69) 0ed8522256000029
|
||||
msg_0x301 = "\x0e\xd8\x52\x22\x56\x00\x00"
|
||||
# add 0xc on idx? WTF is this?
|
||||
commands.append(make_can_msg(0x300, msg_0x300, idx + 0xc, 1))
|
||||
elif crv:
|
||||
msg_0x301 = "\x00\x00\x50\x02\x51\x00\x00"
|
||||
commands.append(make_can_msg(0x300, msg_0x300, idx, 1))
|
||||
else:
|
||||
msg_0x301 = "\x0f\x18\x51\x02\x5a\x00\x00"
|
||||
commands.append(make_can_msg(0x300, msg_0x300, idx, 1))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
import time
|
||||
import numpy as np
|
||||
import common.numpy_fast as np
|
||||
|
||||
from selfdrive.config import Conversions as CV
|
||||
from selfdrive.car.honda.carstate import CarState
|
||||
@@ -10,7 +10,7 @@ from selfdrive.boardd.boardd import can_capnp_to_can_list
|
||||
from cereal import car
|
||||
|
||||
import zmq
|
||||
from common.services import service_list
|
||||
from selfdrive.services import service_list
|
||||
import selfdrive.messaging as messaging
|
||||
|
||||
# Car button codes
|
||||
@@ -37,32 +37,36 @@ class BP:
|
||||
|
||||
|
||||
class CarInterface(object):
|
||||
def __init__(self, read_only=False):
|
||||
context = zmq.Context()
|
||||
self.logcan = messaging.sub_sock(context, service_list['can'].port)
|
||||
def __init__(self, CP, logcan, sendcan=None):
|
||||
self.logcan = logcan
|
||||
self.CP = CP
|
||||
|
||||
self.frame = 0
|
||||
self.can_invalid_count = 0
|
||||
|
||||
# *** init the major players ***
|
||||
self.CS = CarState(self.logcan)
|
||||
self.CS = CarState(CP, self.logcan)
|
||||
|
||||
# sending if read only is False
|
||||
if not read_only:
|
||||
self.sendcan = messaging.pub_sock(context, service_list['sendcan'].port)
|
||||
if sendcan is not None:
|
||||
self.sendcan = sendcan
|
||||
self.CC = CarController()
|
||||
|
||||
def getVehicleParams(self):
|
||||
return self.CS.VP
|
||||
if self.CS.accord:
|
||||
self.accord_msg = []
|
||||
|
||||
# returns a car.CarState
|
||||
def update(self):
|
||||
# ******************* do can recv *******************
|
||||
can_pub_main = []
|
||||
canMonoTimes = []
|
||||
|
||||
for a in messaging.drain_sock(self.logcan):
|
||||
canMonoTimes.append(a.logMonoTime)
|
||||
can_pub_main.extend(can_capnp_to_can_list(a.can, [0,2]))
|
||||
if self.CS.accord:
|
||||
self.accord_msg.extend(can_capnp_to_can_list(a.can, [9]))
|
||||
self.accord_msg = self.accord_msg[-1:]
|
||||
self.CS.update(can_pub_main)
|
||||
|
||||
# create message
|
||||
@@ -77,7 +81,7 @@ class CarInterface(object):
|
||||
|
||||
# gas pedal
|
||||
ret.gas = self.CS.car_gas / 256.0
|
||||
if self.CS.VP.brake_only:
|
||||
if not self.CP.enableGas:
|
||||
ret.gasPressed = self.CS.pedal_gas > 0
|
||||
else:
|
||||
ret.gasPressed = self.CS.user_gas_pressed
|
||||
@@ -89,8 +93,24 @@ class CarInterface(object):
|
||||
# steering wheel
|
||||
# TODO: units
|
||||
ret.steeringAngle = self.CS.angle_steers
|
||||
ret.steeringTorque = self.CS.cp.vl[0x18F]['STEER_TORQUE_SENSOR']
|
||||
ret.steeringPressed = self.CS.steer_override
|
||||
|
||||
if self.CS.accord:
|
||||
# TODO: move this into the CAN parser
|
||||
ret.steeringTorque = 0
|
||||
if len(self.accord_msg) > 0:
|
||||
aa = map(lambda x: ord(x)&0x7f, self.accord_msg[0][2])
|
||||
if len(aa) != 5 or (-(aa[0]+aa[1]+aa[2]+aa[3]))&0x7f != aa[4]:
|
||||
print "ACCORD MSG BAD LEN OR CHECKSUM!"
|
||||
# TODO: throw an error here?
|
||||
else:
|
||||
st = ((aa[0]&0xF) << 5) + (aa[1]&0x1F)
|
||||
if st >= 256:
|
||||
st = -(512-st)
|
||||
ret.steeringTorque = st
|
||||
ret.steeringPressed = abs(ret.steeringTorque) > 20
|
||||
else:
|
||||
ret.steeringTorque = self.CS.cp.vl[0x18F]['STEER_TORQUE_SENSOR']
|
||||
ret.steeringPressed = self.CS.steer_override
|
||||
|
||||
# cruise state
|
||||
ret.cruiseState.enabled = self.CS.pcm_acc_status != 0
|
||||
@@ -192,7 +212,7 @@ class CarInterface(object):
|
||||
hud_v_cruise = 255
|
||||
|
||||
hud_alert = {
|
||||
"none": AH.NONE,
|
||||
"none": AH.NONE,
|
||||
"fcw": AH.FCW,
|
||||
"steerRequired": AH.STEER,
|
||||
"brakePressed": AH.BRAKE_PRESSED,
|
||||
@@ -226,13 +246,3 @@ class CarInterface(object):
|
||||
|
||||
self.frame += 1
|
||||
return not (c.enabled and not self.CC.controls_allowed)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
CI = CarInterface(read_only=True)
|
||||
while 1:
|
||||
cs = CI.update()
|
||||
print(chr(27) + "[2J")
|
||||
print cs
|
||||
time.sleep(0.1)
|
||||
|
||||
|
||||
19
selfdrive/common/cereal.mk
Normal file
19
selfdrive/common/cereal.mk
Normal file
@@ -0,0 +1,19 @@
|
||||
CEREAL_CFLAGS = -I$(PHONELIBS)/capnp-c/include
|
||||
CEREAL_CXXFLAGS = -I$(PHONELIBS)/capnp-cpp/include
|
||||
ifeq ($(CEREAL_LIBS),)
|
||||
CEREAL_LIBS = -L$(PHONELIBS)/capnp-cpp/aarch64/lib/ \
|
||||
-L$(PHONELIBS)/capnp-c/aarch64/lib/ \
|
||||
-l:libcapn.a -l:libcapnp.a -l:libkj.a
|
||||
endif
|
||||
CEREAL_OBJS = ../../cereal/gen/c/log.capnp.o ../../cereal/gen/c/car.capnp.o
|
||||
|
||||
log.capnp.o: ../../cereal/gen/cpp/log.capnp.c++
|
||||
@echo "[ CXX ] $@"
|
||||
$(CXX) $(CXXFLAGS) $(CEREAL_CXXFLAGS) \
|
||||
-c -o '$@' '$<'
|
||||
|
||||
car.capnp.o: ../../cereal/gen/cpp/car.capnp.c++
|
||||
@echo "[ CXX ] $@"
|
||||
$(CXX) $(CXXFLAGS) $(CEREAL_CXXFLAGS) \
|
||||
-c -o '$@' '$<'
|
||||
|
||||
@@ -33,8 +33,12 @@ struct FramebufferState {
|
||||
EGLContext context;
|
||||
};
|
||||
|
||||
extern "C" void framebuffer_set_power(FramebufferState *s, int mode) {
|
||||
SurfaceComposerClient::setDisplayPowerMode(s->dtoken, mode);
|
||||
}
|
||||
|
||||
extern "C" FramebufferState* framebuffer_init(
|
||||
const char* name, int32_t layer,
|
||||
const char* name, int32_t layer, int alpha,
|
||||
EGLDisplay *out_display, EGLSurface *out_surface,
|
||||
int *out_w, int *out_h) {
|
||||
status_t status;
|
||||
@@ -53,6 +57,7 @@ extern "C" FramebufferState* framebuffer_init(
|
||||
assert(status == 0);
|
||||
|
||||
int orientation = 3; // rotate framebuffer 270 degrees
|
||||
//int orientation = 1; // rotate framebuffer 90 degrees
|
||||
if(orientation == 1 || orientation == 3) {
|
||||
int temp = s->dinfo.h;
|
||||
s->dinfo.h = s->dinfo.w;
|
||||
@@ -81,6 +86,7 @@ extern "C" FramebufferState* framebuffer_init(
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_ALPHA_SIZE, alpha ? 8 : 0,
|
||||
EGL_DEPTH_SIZE, 0,
|
||||
EGL_STENCIL_SIZE, 8,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
|
||||
|
||||
@@ -10,12 +10,41 @@ extern "C" {
|
||||
typedef struct FramebufferState FramebufferState;
|
||||
|
||||
FramebufferState* framebuffer_init(
|
||||
const char* name, int32_t layer,
|
||||
const char* name, int32_t layer, int alpha,
|
||||
EGLDisplay *out_display, EGLSurface *out_surface,
|
||||
int *out_w, int *out_h);
|
||||
|
||||
void framebuffer_set_power(FramebufferState *s, int mode);
|
||||
|
||||
/* Display power modes */
|
||||
enum {
|
||||
/* The display is turned off (blanked). */
|
||||
HWC_POWER_MODE_OFF = 0,
|
||||
/* The display is turned on and configured in a low power state
|
||||
* that is suitable for presenting ambient information to the user,
|
||||
* possibly with lower fidelity than normal but greater efficiency. */
|
||||
HWC_POWER_MODE_DOZE = 1,
|
||||
/* The display is turned on normally. */
|
||||
HWC_POWER_MODE_NORMAL = 2,
|
||||
/* The display is configured as in HWC_POWER_MODE_DOZE but may
|
||||
* stop applying frame buffer updates from the graphics subsystem.
|
||||
* This power mode is effectively a hint from the doze dream to
|
||||
* tell the hardware that it is done drawing to the display for the
|
||||
* time being and that the display should remain on in a low power
|
||||
* state and continue showing its current contents indefinitely
|
||||
* until the mode changes.
|
||||
*
|
||||
* This mode may also be used as a signal to enable hardware-based doze
|
||||
* functionality. In this case, the doze dream is effectively
|
||||
* indicating that the hardware is free to take over the display
|
||||
* and manage it autonomously to implement low power always-on display
|
||||
* functionality. */
|
||||
HWC_POWER_MODE_DOZE_SUSPEND = 3,
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
71
selfdrive/common/glutil.c
Normal file
71
selfdrive/common/glutil.c
Normal file
@@ -0,0 +1,71 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <GLES3/gl3.h>
|
||||
|
||||
#include "glutil.h"
|
||||
|
||||
GLuint load_shader(GLenum shaderType, const char *src) {
|
||||
GLint status = 0, len = 0;
|
||||
GLuint shader;
|
||||
|
||||
if (!(shader = glCreateShader(shaderType)))
|
||||
return 0;
|
||||
|
||||
glShaderSource(shader, 1, &src, NULL);
|
||||
glCompileShader(shader);
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||
|
||||
if (status)
|
||||
return shader;
|
||||
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
|
||||
if (len) {
|
||||
char *msg = (char*)malloc(len);
|
||||
if (msg) {
|
||||
glGetShaderInfoLog(shader, len, NULL, msg);
|
||||
msg[len-1] = 0;
|
||||
fprintf(stderr, "error compiling shader:\n%s\n", msg);
|
||||
free(msg);
|
||||
}
|
||||
}
|
||||
glDeleteShader(shader);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLuint load_program(const char *vert_src, const char *frag_src) {
|
||||
GLuint vert, frag, prog;
|
||||
GLint status = 0, len = 0;
|
||||
|
||||
if (!(vert = load_shader(GL_VERTEX_SHADER, vert_src)))
|
||||
return 0;
|
||||
if (!(frag = load_shader(GL_FRAGMENT_SHADER, frag_src)))
|
||||
goto fail_frag;
|
||||
if (!(prog = glCreateProgram()))
|
||||
goto fail_prog;
|
||||
|
||||
glAttachShader(prog, vert);
|
||||
glAttachShader(prog, frag);
|
||||
glLinkProgram(prog);
|
||||
|
||||
glGetProgramiv(prog, GL_LINK_STATUS, &status);
|
||||
if (status)
|
||||
return prog;
|
||||
|
||||
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
|
||||
if (len) {
|
||||
char *buf = (char*) malloc(len);
|
||||
if (buf) {
|
||||
glGetProgramInfoLog(prog, len, NULL, buf);
|
||||
buf[len-1] = 0;
|
||||
fprintf(stderr, "error linking program:\n%s\n", buf);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
glDeleteProgram(prog);
|
||||
fail_prog:
|
||||
glDeleteShader(frag);
|
||||
fail_frag:
|
||||
glDeleteShader(vert);
|
||||
return 0;
|
||||
}
|
||||
8
selfdrive/common/glutil.h
Normal file
8
selfdrive/common/glutil.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef COMMON_GLUTIL_H
|
||||
#define COMMON_GLUTIL_H
|
||||
|
||||
#include <GLES3/gl3.h>
|
||||
GLuint load_shader(GLenum shaderType, const char *src);
|
||||
GLuint load_program(const char *vert_src, const char *frag_src);
|
||||
|
||||
#endif
|
||||
@@ -1,13 +0,0 @@
|
||||
#ifndef COMMON_MUTEX_H
|
||||
#define COMMON_MUTEX_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
static inline void mutex_init_reentrant(pthread_mutex_t *mutex) {
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(mutex, &attr);
|
||||
}
|
||||
|
||||
#endif
|
||||
129
selfdrive/common/params.c
Normal file
129
selfdrive/common/params.c
Normal file
@@ -0,0 +1,129 @@
|
||||
#include "selfdrive/common/params.h"
|
||||
|
||||
#include "selfdrive/common/util.h"
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <sys/file.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int write_db_value(const char* params_path, const char* key, const char* value,
|
||||
size_t value_size) {
|
||||
int lock_fd = -1;
|
||||
int tmp_fd = -1;
|
||||
int result;
|
||||
char tmp_path[1024];
|
||||
char path[1024];
|
||||
|
||||
// Write value to temp.
|
||||
result =
|
||||
snprintf(tmp_path, sizeof(tmp_path), "%s/.tmp_value_XXXXXX", params_path);
|
||||
if (result < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
tmp_fd = mkstemp(tmp_path);
|
||||
const ssize_t bytes_written = write(tmp_fd, value, value_size);
|
||||
if (bytes_written != value_size) {
|
||||
result = -20;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = snprintf(path, sizeof(path), "%s/.lock", params_path);
|
||||
if (result < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
lock_fd = open(path, 0);
|
||||
|
||||
result = snprintf(path, sizeof(path), "%s/d/%s", params_path, key);
|
||||
if (result < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Take lock.
|
||||
result = flock(lock_fd, LOCK_EX);
|
||||
if (result < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Move temp into place.
|
||||
result = rename(tmp_path, path);
|
||||
if (result < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// fsync to force persist the changes.
|
||||
result = fsync(tmp_fd);
|
||||
cleanup:
|
||||
// Release lock.
|
||||
if (lock_fd >= 0) {
|
||||
close(lock_fd);
|
||||
}
|
||||
if (tmp_fd >= 0) {
|
||||
if (result < 0) {
|
||||
remove(tmp_path);
|
||||
}
|
||||
close(tmp_fd);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int read_db_value(const char* params_path, const char* key, char** value,
|
||||
size_t* value_sz) {
|
||||
int lock_fd = -1;
|
||||
int result;
|
||||
char path[1024];
|
||||
|
||||
result = snprintf(path, sizeof(path), "%s/.lock", params_path);
|
||||
if (result < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
lock_fd = open(path, 0);
|
||||
|
||||
result = snprintf(path, sizeof(path), "%s/d/%s", params_path, key);
|
||||
if (result < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Take lock.
|
||||
result = flock(lock_fd, LOCK_EX);
|
||||
if (result < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Read value.
|
||||
// TODO(mgraczyk): If there is a lot of contention, we can release the lock
|
||||
// after opening the file, before reading.
|
||||
*value = read_file(path, value_sz);
|
||||
if (*value == NULL) {
|
||||
result = -22;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Remove one for null byte.
|
||||
if (value_sz != NULL) {
|
||||
*value_sz -= 1;
|
||||
}
|
||||
result = 0;
|
||||
|
||||
cleanup:
|
||||
// Release lock.
|
||||
if (lock_fd >= 0) {
|
||||
close(lock_fd);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void read_db_value_blocking(const char* params_path, const char* key,
|
||||
char** value, size_t* value_sz) {
|
||||
while (1) {
|
||||
const int result = read_db_value(params_path, key, value, value_sz);
|
||||
if (result == 0) {
|
||||
return;
|
||||
} else {
|
||||
// Sleep for 0.1 seconds.
|
||||
usleep(100000);
|
||||
}
|
||||
}
|
||||
}
|
||||
35
selfdrive/common/params.h
Normal file
35
selfdrive/common/params.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef _SELFDRIVE_COMMON_PARAMS_H_
|
||||
#define _SELFDRIVE_COMMON_PARAMS_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int write_db_value(const char* params_path, const char* key, const char* value,
|
||||
size_t value_size);
|
||||
|
||||
// Reads a value from the params database.
|
||||
// Inputs:
|
||||
// params_path: The path of the database, eg /sdcard/params.
|
||||
// key: The key to read.
|
||||
// value: A pointer where a newly allocated string containing the db value will
|
||||
// be written.
|
||||
// value_sz: A pointer where the size of value will be written. Does not
|
||||
// include the NULL terminator.
|
||||
//
|
||||
// Returns: Negative on failure, otherwise 0.
|
||||
int read_db_value(const char* params_path, const char* key, char** value,
|
||||
size_t* value_sz);
|
||||
|
||||
// Reads a value from the params database, blocking until successful.
|
||||
// Inputs are the same as read_db_value.
|
||||
void read_db_value_blocking(const char* params_path, const char* key,
|
||||
char** value, size_t* value_sz);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // _SELFDRIVE_COMMON_PARAMS_H_
|
||||
@@ -1,3 +1,5 @@
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
@@ -10,6 +12,7 @@
|
||||
#include <json.h>
|
||||
|
||||
#include "common/timing.h"
|
||||
#include "common/version.h"
|
||||
|
||||
#include "swaglog.h"
|
||||
|
||||
@@ -19,22 +22,49 @@ typedef struct LogState {
|
||||
JsonNode *ctx_j;
|
||||
void *zctx;
|
||||
void *sock;
|
||||
int print_level;
|
||||
} LogState;
|
||||
|
||||
static LogState s = {
|
||||
.lock = PTHREAD_MUTEX_INITIALIZER,
|
||||
};
|
||||
|
||||
static void cloudlog_bind_locked(const char* k, const char* v) {
|
||||
json_append_member(s.ctx_j, k, json_mkstring(v));
|
||||
}
|
||||
|
||||
static void cloudlog_init() {
|
||||
if (s.inited) return;
|
||||
s.ctx_j = json_mkobject();
|
||||
s.zctx = zmq_ctx_new();
|
||||
s.sock = zmq_socket(s.zctx, ZMQ_PUSH);
|
||||
zmq_connect(s.sock, "ipc:///tmp/logmessage");
|
||||
|
||||
s.print_level = CLOUDLOG_WARNING;
|
||||
const char* print_level = getenv("LOGPRINT");
|
||||
if (print_level) {
|
||||
if (strcmp(print_level, "debug") == 0) {
|
||||
s.print_level = CLOUDLOG_DEBUG;
|
||||
} else if (strcmp(print_level, "info") == 0) {
|
||||
s.print_level = CLOUDLOG_INFO;
|
||||
} else if (strcmp(print_level, "warning") == 0) {
|
||||
s.print_level = CLOUDLOG_WARNING;
|
||||
}
|
||||
}
|
||||
|
||||
// openpilot bindings
|
||||
char* dongle_id = getenv("DONGLE_ID");
|
||||
if (dongle_id) {
|
||||
cloudlog_bind_locked("dongle_id", dongle_id);
|
||||
}
|
||||
cloudlog_bind_locked("version", OPENPILOT_VERSION);
|
||||
bool dirty = !getenv("CLEAN");
|
||||
json_append_member(s.ctx_j, "dirty", json_mkbool(dirty));
|
||||
|
||||
s.inited = true;
|
||||
}
|
||||
|
||||
void cloudlog_e(int levelnum, const char* filename, int lineno, const char* func, const char* srctime,
|
||||
void cloudlog_e(int levelnum, const char* filename, int lineno, const char* func,
|
||||
const char* fmt, ...) {
|
||||
pthread_mutex_lock(&s.lock);
|
||||
cloudlog_init();
|
||||
@@ -50,7 +80,7 @@ void cloudlog_e(int levelnum, const char* filename, int lineno, const char* func
|
||||
return;
|
||||
}
|
||||
|
||||
if (levelnum >= CLOUDLOG_PRINT_LEVEL) {
|
||||
if (levelnum >= s.print_level) {
|
||||
printf("%s: %s\n", filename, msg_buf);
|
||||
}
|
||||
|
||||
@@ -63,7 +93,6 @@ void cloudlog_e(int levelnum, const char* filename, int lineno, const char* func
|
||||
json_append_member(log_j, "filename", json_mkstring(filename));
|
||||
json_append_member(log_j, "lineno", json_mknumber(lineno));
|
||||
json_append_member(log_j, "funcname", json_mkstring(func));
|
||||
json_append_member(log_j, "srctime", json_mkstring(srctime));
|
||||
json_append_member(log_j, "created", json_mknumber(seconds_since_epoch()));
|
||||
|
||||
char* log_s = json_encode(log_j);
|
||||
@@ -85,6 +114,6 @@ void cloudlog_e(int levelnum, const char* filename, int lineno, const char* func
|
||||
void cloudlog_bind(const char* k, const char* v) {
|
||||
pthread_mutex_lock(&s.lock);
|
||||
cloudlog_init();
|
||||
json_append_member(s.ctx_j, k, json_mkstring(v));
|
||||
cloudlog_bind_locked(k, v);
|
||||
pthread_mutex_unlock(&s.lock);
|
||||
}
|
||||
|
||||
@@ -7,15 +7,21 @@
|
||||
#define CLOUDLOG_ERROR 40
|
||||
#define CLOUDLOG_CRITICAL 50
|
||||
|
||||
#define CLOUDLOG_PRINT_LEVEL CLOUDLOG_WARNING
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void cloudlog_e(int levelnum, const char* filename, int lineno, const char* func, const char* srctime,
|
||||
void cloudlog_e(int levelnum, const char* filename, int lineno, const char* func,
|
||||
const char* fmt, ...) /*__attribute__ ((format (printf, 6, 7)))*/;
|
||||
|
||||
void cloudlog_bind(const char* k, const char* v);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define cloudlog(lvl, fmt, ...) cloudlog_e(lvl, __FILE__, __LINE__, \
|
||||
__func__, __DATE__ " " __TIME__, \
|
||||
__func__, \
|
||||
fmt, ## __VA_ARGS__)
|
||||
|
||||
#define LOGD(fmt, ...) cloudlog(CLOUDLOG_DEBUG, fmt, ## __VA_ARGS__)
|
||||
|
||||
@@ -13,7 +13,13 @@ static inline uint64_t nanos_since_boot() {
|
||||
static inline double millis_since_boot() {
|
||||
struct timespec t;
|
||||
clock_gettime(CLOCK_BOOTTIME, &t);
|
||||
return t.tv_sec * 1000.0 + t.tv_nsec / 1000000.0;
|
||||
return t.tv_sec * 1000.0 + t.tv_nsec * 1e-6;
|
||||
}
|
||||
|
||||
static inline double seconds_since_boot() {
|
||||
struct timespec t;
|
||||
clock_gettime(CLOCK_BOOTTIME, &t);
|
||||
return (double)t.tv_sec + t.tv_nsec * 1e-9;;
|
||||
}
|
||||
|
||||
static inline uint64_t nanos_since_epoch() {
|
||||
@@ -25,7 +31,7 @@ static inline uint64_t nanos_since_epoch() {
|
||||
static inline double seconds_since_epoch() {
|
||||
struct timespec t;
|
||||
clock_gettime(CLOCK_REALTIME, &t);
|
||||
return (double)t.tv_sec + t.tv_nsec / 1000000000.0;
|
||||
return (double)t.tv_sec + t.tv_nsec * 1e-9;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,15 +1,50 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/poll.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include "touch.h"
|
||||
|
||||
static int find_dev() {
|
||||
int err;
|
||||
|
||||
int ret = -1;
|
||||
|
||||
DIR *dir = opendir("/dev/input");
|
||||
assert(dir);
|
||||
struct dirent* de = NULL;
|
||||
while ((de = readdir(dir))) {
|
||||
if (strncmp(de->d_name, "event", 5)) continue;
|
||||
|
||||
int fd = openat(dirfd(dir), de->d_name, O_RDONLY);
|
||||
assert(fd >= 0);
|
||||
|
||||
char name[128] = {0};
|
||||
err = ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name);
|
||||
assert(err >= 0);
|
||||
|
||||
unsigned long ev_bits[8] = {0};
|
||||
err = ioctl(fd, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits);
|
||||
assert(err >= 0);
|
||||
|
||||
if (strncmp(name, "synaptics", 9) == 0 && ev_bits[0] == 0xb) {
|
||||
ret = fd;
|
||||
break;
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void touch_init(TouchState *s) {
|
||||
// synaptics touch screen on oneplus 3
|
||||
s->fd = open("/dev/input/event4", O_RDONLY);
|
||||
s->fd = find_dev();
|
||||
assert(s->fd >= 0);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
#ifndef TOUCH_H
|
||||
#define TOUCH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct TouchState {
|
||||
int fd;
|
||||
int last_x, last_y;
|
||||
@@ -9,4 +13,8 @@ typedef struct TouchState {
|
||||
void touch_init(TouchState *s);
|
||||
int touch_poll(TouchState *s, int *out_x, int *out_y);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
27
selfdrive/common/util.c
Normal file
27
selfdrive/common/util.c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
void* read_file(const char* path, size_t* out_len) {
|
||||
FILE* f = fopen(path, "r");
|
||||
if (!f) {
|
||||
return NULL;
|
||||
}
|
||||
fseek(f, 0, SEEK_END);
|
||||
long f_len = ftell(f);
|
||||
rewind(f);
|
||||
|
||||
char* buf = malloc(f_len + 1);
|
||||
assert(buf);
|
||||
memset(buf, 0, f_len + 1);
|
||||
size_t num_read = fread(buf, f_len, 1, f);
|
||||
assert(num_read == 1);
|
||||
fclose(f);
|
||||
|
||||
if (out_len) {
|
||||
*out_len = f_len + 1;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
@@ -19,4 +19,8 @@
|
||||
|
||||
#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
||||
// Returns NULL on failure, otherwise the NULL-terminated file contents.
|
||||
void* read_file(const char* path, size_t* out_len);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
65
selfdrive/common/utilpp.h
Normal file
65
selfdrive/common/utilpp.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifndef UTILPP_H
|
||||
#define UTILPP_H
|
||||
|
||||
#include <cstdio>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
||||
namespace util {
|
||||
|
||||
inline bool starts_with(std::string s, std::string prefix) {
|
||||
return s.compare(0, prefix.size(), prefix) == 0;
|
||||
}
|
||||
|
||||
template<typename ... Args>
|
||||
inline std::string string_format( const std::string& format, Args ... args ) {
|
||||
size_t size = snprintf( nullptr, 0, format.c_str(), args ... ) + 1;
|
||||
std::unique_ptr<char[]> buf( new char[ size ] );
|
||||
snprintf( buf.get(), size, format.c_str(), args ... );
|
||||
return std::string( buf.get(), buf.get() + size - 1 );
|
||||
}
|
||||
|
||||
inline std::string read_file(std::string fn) {
|
||||
std::ifstream t(fn);
|
||||
std::stringstream buffer;
|
||||
buffer << t.rdbuf();
|
||||
return buffer.str();
|
||||
}
|
||||
|
||||
inline std::string tohex(const uint8_t* buf, size_t buf_size) {
|
||||
std::unique_ptr<char[]> hexbuf(new char[buf_size*2+1]);
|
||||
for (int i=0; i<buf_size; i++) {
|
||||
sprintf(&hexbuf[i*2], "%02x", buf[i]);
|
||||
}
|
||||
hexbuf[buf_size*2] = 0;
|
||||
return std::string(hexbuf.get(), hexbuf.get() + buf_size*2);
|
||||
}
|
||||
|
||||
inline std::string base_name(std::string const & path) {
|
||||
size_t pos = path.find_last_of("/");
|
||||
if (pos == std::string::npos) return path;
|
||||
return path.substr(pos + 1);
|
||||
}
|
||||
|
||||
inline std::string dir_name(std::string const & path) {
|
||||
size_t pos = path.find_last_of("/");
|
||||
if (pos == std::string::npos) return "";
|
||||
return path.substr(0, pos);
|
||||
}
|
||||
|
||||
inline std::string readlink(std::string path) {
|
||||
char buff[PATH_MAX];
|
||||
ssize_t len = ::readlink(path.c_str(), buff, sizeof(buff)-1);
|
||||
if (len != -1) {
|
||||
buff[len] = '\0';
|
||||
return std::string(buff);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
1
selfdrive/common/version.h
Normal file
1
selfdrive/common/version.h
Normal file
@@ -0,0 +1 @@
|
||||
#define OPENPILOT_VERSION "0.3.3"
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
@@ -115,13 +116,124 @@ int vipc_recv(int fd, VisionPacket *out_p) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vipc_send(int fd, const VisionPacket p2) {
|
||||
assert(p2.num_fds <= VIPC_MAX_FDS);
|
||||
int vipc_send(int fd, const VisionPacket *p2) {
|
||||
assert(p2->num_fds <= VIPC_MAX_FDS);
|
||||
|
||||
VisionPacketWire p = {
|
||||
.type = p2.type,
|
||||
.d = p2.d,
|
||||
.type = p2->type,
|
||||
.d = p2->d,
|
||||
};
|
||||
return sendrecv_with_fds(true, fd, (void*)&p, sizeof(p), (int*)p2.fds, p2.num_fds, NULL);
|
||||
return sendrecv_with_fds(true, fd, (void*)&p, sizeof(p), (int*)p2->fds, p2->num_fds, NULL);
|
||||
}
|
||||
|
||||
void visionbufs_load(VisionBuf *bufs, const VisionStreamBufs *stream_bufs,
|
||||
int num_fds, const int* fds) {
|
||||
for (int i=0; i<num_fds; i++) {
|
||||
if (bufs[i].addr) {
|
||||
munmap(bufs[i].addr, bufs[i].len);
|
||||
bufs[i].addr = NULL;
|
||||
close(bufs[i].fd);
|
||||
}
|
||||
bufs[i].fd = fds[i];
|
||||
bufs[i].len = stream_bufs->buf_len;
|
||||
bufs[i].addr = mmap(NULL, bufs[i].len,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, bufs[i].fd, 0);
|
||||
// printf("b %d %zu -> %p\n", bufs[i].fd, bufs[i].len, bufs[i].addr);
|
||||
assert(bufs[i].addr != MAP_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int visionstream_init(VisionStream *s, VisionStreamType type, bool tbuffer, VisionStreamBufs *out_bufs_info) {
|
||||
int err;
|
||||
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
||||
s->last_idx = -1;
|
||||
|
||||
s->ipc_fd = vipc_connect();
|
||||
if (s->ipc_fd < 0) return -1;
|
||||
|
||||
VisionPacket p = {
|
||||
.type = VIPC_STREAM_SUBSCRIBE,
|
||||
.d = { .stream_sub = {
|
||||
.type = type,
|
||||
.tbuffer = tbuffer,
|
||||
}, },
|
||||
};
|
||||
err = vipc_send(s->ipc_fd, &p);
|
||||
if (err < 0) {
|
||||
close(s->ipc_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
VisionPacket rp;
|
||||
err = vipc_recv(s->ipc_fd, &rp);
|
||||
if (err <= 0) {
|
||||
close(s->ipc_fd);
|
||||
return -1;
|
||||
}
|
||||
assert(rp.type = VIPC_STREAM_BUFS);
|
||||
assert(rp.d.stream_bufs.type == type);
|
||||
|
||||
s->bufs_info = rp.d.stream_bufs;
|
||||
|
||||
s->num_bufs = rp.num_fds;
|
||||
s->bufs = calloc(s->num_bufs, sizeof(VisionBuf));
|
||||
assert(s->bufs);
|
||||
|
||||
visionbufs_load(s->bufs, &rp.d.stream_bufs, s->num_bufs, rp.fds);
|
||||
|
||||
if (out_bufs_info) {
|
||||
*out_bufs_info = s->bufs_info;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
VisionBuf* visionstream_get(VisionStream *s, VisionBufExtra *out_extra) {
|
||||
int err;
|
||||
|
||||
VisionPacket rp;
|
||||
err = vipc_recv(s->ipc_fd, &rp);
|
||||
if (err <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
assert(rp.type == VIPC_STREAM_ACQUIRE);
|
||||
|
||||
if (s->last_idx >= 0) {
|
||||
VisionPacket rep = {
|
||||
.type = VIPC_STREAM_RELEASE,
|
||||
.d = { .stream_rel = {
|
||||
.type = rp.d.stream_acq.type,
|
||||
.idx = s->last_idx,
|
||||
}}
|
||||
};
|
||||
err = vipc_send(s->ipc_fd, &rep);
|
||||
if (err <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
s->last_idx = rp.d.stream_acq.idx;
|
||||
assert(s->last_idx < s->num_bufs);
|
||||
|
||||
if (out_extra) {
|
||||
*out_extra = rp.d.stream_acq.extra;
|
||||
}
|
||||
|
||||
return &s->bufs[s->last_idx];
|
||||
}
|
||||
|
||||
void visionstream_destroy(VisionStream *s) {
|
||||
for (int i=0; i<s->num_bufs; i++) {
|
||||
if (s->bufs[i].addr) {
|
||||
munmap(s->bufs[i].addr, s->bufs[i].len);
|
||||
s->bufs[i].addr = NULL;
|
||||
close(s->bufs[i].fd);
|
||||
}
|
||||
}
|
||||
if (s->bufs) free(s->bufs);
|
||||
close(s->ipc_fd);
|
||||
}
|
||||
|
||||
@@ -1,39 +1,71 @@
|
||||
#ifndef VISIONIPC_H
|
||||
#define VISIONIPC_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define VIPC_SOCKET_PATH "/tmp/vision_socket"
|
||||
#define VIPC_MAX_FDS 64
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define VISION_INVALID 0
|
||||
#define VISION_UI_SUBSCRIBE 1
|
||||
#define VISION_UI_BUFS 2
|
||||
#define VISION_UI_ACQUIRE 3
|
||||
#define VISION_UI_RELEASE 4
|
||||
typedef enum VisionIPCPacketType {
|
||||
VIPC_INVALID = 0,
|
||||
VIPC_STREAM_SUBSCRIBE,
|
||||
VIPC_STREAM_BUFS,
|
||||
VIPC_STREAM_ACQUIRE,
|
||||
VIPC_STREAM_RELEASE,
|
||||
} VisionIPCPacketType;
|
||||
|
||||
typedef struct VisionUIBufs {
|
||||
int width, height, stride;
|
||||
int front_width, front_height, front_stride;
|
||||
typedef enum VisionStreamType {
|
||||
VISION_STREAM_UI_BACK,
|
||||
VISION_STREAM_UI_FRONT,
|
||||
VISION_STREAM_YUV,
|
||||
VISION_STREAM_MAX,
|
||||
} VisionStreamType;
|
||||
|
||||
typedef struct VisionUIInfo {
|
||||
int big_box_x, big_box_y;
|
||||
int big_box_width, big_box_height;
|
||||
int transformed_width, transformed_height;
|
||||
|
||||
int front_box_x, front_box_y;
|
||||
int front_box_width, front_box_height;
|
||||
} VisionUIInfo;
|
||||
|
||||
typedef struct VisionStreamBufs {
|
||||
VisionStreamType type;
|
||||
|
||||
int width, height, stride;
|
||||
size_t buf_len;
|
||||
int num_bufs;
|
||||
size_t front_buf_len;
|
||||
int num_front_bufs;
|
||||
} VisionUIBufs;
|
||||
|
||||
union {
|
||||
VisionUIInfo ui_info;
|
||||
} buf_info;
|
||||
} VisionStreamBufs;
|
||||
|
||||
typedef struct VisionBufExtra {
|
||||
uint32_t frame_id; // only for yuv
|
||||
} VisionBufExtra;
|
||||
|
||||
typedef union VisionPacketData {
|
||||
VisionUIBufs ui_bufs;
|
||||
struct {
|
||||
bool front;
|
||||
VisionStreamType type;
|
||||
bool tbuffer;
|
||||
} stream_sub;
|
||||
VisionStreamBufs stream_bufs;
|
||||
struct {
|
||||
VisionStreamType type;
|
||||
int idx;
|
||||
} ui_acq, ui_rel;
|
||||
VisionBufExtra extra;
|
||||
} stream_acq;
|
||||
struct {
|
||||
VisionStreamType type;
|
||||
int idx;
|
||||
} stream_rel;
|
||||
} VisionPacketData;
|
||||
|
||||
typedef struct VisionPacket {
|
||||
@@ -43,8 +75,34 @@ typedef struct VisionPacket {
|
||||
int fds[VIPC_MAX_FDS];
|
||||
} VisionPacket;
|
||||
|
||||
int vipc_connect();
|
||||
int vipc_connect(void);
|
||||
int vipc_recv(int fd, VisionPacket *out_p);
|
||||
int vipc_send(int fd, const VisionPacket p);
|
||||
int vipc_send(int fd, const VisionPacket *p);
|
||||
|
||||
typedef struct VisionBuf {
|
||||
int fd;
|
||||
size_t len;
|
||||
void* addr;
|
||||
} VisionBuf;
|
||||
void visionbufs_load(VisionBuf *bufs, const VisionStreamBufs *stream_bufs,
|
||||
int num_fds, const int* fds);
|
||||
|
||||
|
||||
|
||||
typedef struct VisionStream {
|
||||
int ipc_fd;
|
||||
int last_idx;
|
||||
int num_bufs;
|
||||
VisionStreamBufs bufs_info;
|
||||
VisionBuf *bufs;
|
||||
} VisionStream;
|
||||
|
||||
int visionstream_init(VisionStream *s, VisionStreamType type, bool tbuffer, VisionStreamBufs *out_bufs_info);
|
||||
VisionBuf* visionstream_get(VisionStream *s, VisionBufExtra *out_extra);
|
||||
void visionstream_destroy(VisionStream *s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,7 +10,7 @@ class Conversions:
|
||||
KNOTS_TO_MS = 1/1.9438
|
||||
MS_TO_KNOTS = 1.9438
|
||||
|
||||
# Car tecode decimal minutes into decimal degrees, can work with numpy arrays as input
|
||||
# Car decode decimal minutes into decimal degrees, can work with numpy arrays as input
|
||||
@staticmethod
|
||||
def dm2d(dm):
|
||||
degs = np.round(dm/100.)
|
||||
@@ -56,19 +56,3 @@ class UIParams:
|
||||
car_back = 1.8796 * lidar_zoom
|
||||
car_color = 110
|
||||
|
||||
class VehicleParams:
|
||||
def __init__(self, civic, brake_only=False, torque_mod=False):
|
||||
if civic:
|
||||
self.wheelbase = 2.67
|
||||
self.steer_ratio = 15.3
|
||||
self.slip_factor = 0.0014
|
||||
self.civic = True
|
||||
else:
|
||||
self.wheelbase = 2.67 # from http://www.edmunds.com/acura/ilx/2016/sedan/features-specs/
|
||||
self.steer_ratio = 15.3 # from http://www.edmunds.com/acura/ilx/2016/road-test-specs/
|
||||
self.slip_factor = 0.0014
|
||||
self.civic = False
|
||||
self.brake_only = brake_only
|
||||
self.torque_mod = torque_mod
|
||||
self.ui_speed_fudge = 1.01 if self.civic else 1.025
|
||||
|
||||
|
||||
@@ -1,33 +1,27 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import zmq
|
||||
import numpy as np
|
||||
import selfdrive.messaging as messaging
|
||||
|
||||
from cereal import car
|
||||
from cereal import car, log
|
||||
|
||||
from selfdrive.swaglog import cloudlog
|
||||
from common.numpy_fast import clip
|
||||
from common.fingerprints import fingerprint
|
||||
|
||||
from selfdrive.config import Conversions as CV
|
||||
from common.services import service_list
|
||||
from selfdrive.services import service_list
|
||||
from common.realtime import sec_since_boot, set_realtime_priority, Ratekeeper
|
||||
from common.profiler import Profiler
|
||||
from common.params import Params
|
||||
|
||||
from selfdrive.controls.lib.drive_helpers import learn_angle_offset
|
||||
|
||||
from selfdrive.controls.lib.longcontrol import LongControl
|
||||
from selfdrive.controls.lib.latcontrol import LatControl
|
||||
|
||||
from selfdrive.controls.lib.pathplanner import PathPlanner
|
||||
from selfdrive.controls.lib.adaptivecruise import AdaptiveCruise
|
||||
|
||||
from selfdrive.controls.lib.alertmanager import AlertManager
|
||||
|
||||
car_type = os.getenv("CAR")
|
||||
if car_type is not None:
|
||||
exec('from selfdrive.car.'+car_type+'.interface import CarInterface')
|
||||
else:
|
||||
from selfdrive.car.honda.interface import CarInterface
|
||||
|
||||
V_CRUISE_MAX = 144
|
||||
V_CRUISE_MIN = 8
|
||||
V_CRUISE_DELTA = 8
|
||||
@@ -37,24 +31,40 @@ def controlsd_thread(gctx, rate=100): #rate in Hz
|
||||
# *** log ***
|
||||
context = zmq.Context()
|
||||
live100 = messaging.pub_sock(context, service_list['live100'].port)
|
||||
carstate = messaging.pub_sock(context, service_list['carState'].port)
|
||||
carcontrol = messaging.pub_sock(context, service_list['carControl'].port)
|
||||
|
||||
thermal = messaging.sub_sock(context, service_list['thermal'].port)
|
||||
live20 = messaging.sub_sock(context, service_list['live20'].port)
|
||||
model = messaging.sub_sock(context, service_list['model'].port)
|
||||
health = messaging.sub_sock(context, service_list['health'].port)
|
||||
plan_sock = messaging.sub_sock(context, service_list['plan'].port)
|
||||
|
||||
# connects to can and sendcan
|
||||
CI = CarInterface()
|
||||
VP = CI.getVehicleParams()
|
||||
logcan = messaging.sub_sock(context, service_list['can'].port)
|
||||
|
||||
PP = PathPlanner(model)
|
||||
AC = AdaptiveCruise(live20)
|
||||
# connects to can
|
||||
CP = fingerprint(logcan)
|
||||
|
||||
# import the car from the fingerprint
|
||||
cloudlog.info("controlsd is importing %s", CP.carName)
|
||||
exec('from selfdrive.car.'+CP.carName+'.interface import CarInterface')
|
||||
|
||||
sendcan = messaging.pub_sock(context, service_list['sendcan'].port)
|
||||
CI = CarInterface(CP, logcan, sendcan)
|
||||
|
||||
# write CarParams
|
||||
params = Params()
|
||||
params.put("CarParams", CP.to_bytes())
|
||||
|
||||
AM = AlertManager()
|
||||
|
||||
LoC = LongControl()
|
||||
LaC = LatControl()
|
||||
|
||||
# fake plan
|
||||
plan = log.Plan.new_message()
|
||||
plan.lateralValid = False
|
||||
plan.longitudinalValid = False
|
||||
last_plan_time = 0
|
||||
|
||||
# controls enabled state
|
||||
enabled = False
|
||||
last_enable_request = 0
|
||||
@@ -64,6 +74,7 @@ def controlsd_thread(gctx, rate=100): #rate in Hz
|
||||
|
||||
# rear view camera state
|
||||
rear_view_toggle = False
|
||||
rear_view_allowed = bool(params.get("IsRearViewMirror"))
|
||||
|
||||
v_cruise_kph = 255
|
||||
|
||||
@@ -72,16 +83,31 @@ def controlsd_thread(gctx, rate=100): #rate in Hz
|
||||
|
||||
soft_disable_timer = None
|
||||
|
||||
# Is cpu temp too high to enable?
|
||||
overtemp = False
|
||||
free_space = 1.0
|
||||
|
||||
# start the loop
|
||||
set_realtime_priority(2)
|
||||
|
||||
rk = Ratekeeper(rate, print_delay_threshold=2./1000)
|
||||
while 1:
|
||||
cur_time = sec_since_boot()
|
||||
prof = Profiler()
|
||||
|
||||
# read CAN
|
||||
CS = CI.update()
|
||||
|
||||
prof.checkpoint("CarInterface")
|
||||
|
||||
# broadcast carState
|
||||
cs_send = messaging.new_message()
|
||||
cs_send.init('carState')
|
||||
cs_send.carState = CS # copy?
|
||||
carstate.send(cs_send.to_bytes())
|
||||
|
||||
prof.checkpoint("CarState")
|
||||
|
||||
# did it request to enable?
|
||||
enable_request, enable_condition = False, False
|
||||
|
||||
@@ -104,7 +130,7 @@ def controlsd_thread(gctx, rate=100): #rate in Hz
|
||||
|
||||
# button presses for rear view
|
||||
if b.type == "leftBlinker" or b.type == "rightBlinker":
|
||||
if b.pressed:
|
||||
if b.pressed and rear_view_allowed:
|
||||
rear_view_toggle = True
|
||||
else:
|
||||
rear_view_toggle = False
|
||||
@@ -112,7 +138,7 @@ def controlsd_thread(gctx, rate=100): #rate in Hz
|
||||
if b.type == "altButton1" and b.pressed:
|
||||
rear_view_toggle = not rear_view_toggle
|
||||
|
||||
if not VP.brake_only and enabled and not b.pressed:
|
||||
if not CP.enableCruise and enabled and not b.pressed:
|
||||
if b.type == "accelCruise":
|
||||
v_cruise_kph = v_cruise_kph - (v_cruise_kph % V_CRUISE_DELTA) + V_CRUISE_DELTA
|
||||
elif b.type == "decelCruise":
|
||||
@@ -120,12 +146,14 @@ def controlsd_thread(gctx, rate=100): #rate in Hz
|
||||
v_cruise_kph = clip(v_cruise_kph, V_CRUISE_MIN, V_CRUISE_MAX)
|
||||
|
||||
if not enabled and b.type in ["accelCruise", "decelCruise"] and not b.pressed:
|
||||
enable_request = True
|
||||
enable_request = True
|
||||
|
||||
# do disable on button down
|
||||
if b.type == "cancel" and b.pressed:
|
||||
AM.add("disable", enabled)
|
||||
|
||||
prof.checkpoint("Buttons")
|
||||
|
||||
# *** health checking logic ***
|
||||
hh = messaging.recv_sock(health)
|
||||
if hh is not None:
|
||||
@@ -138,24 +166,25 @@ def controlsd_thread(gctx, rate=100): #rate in Hz
|
||||
# thermal data, checked every second
|
||||
td = messaging.recv_sock(thermal)
|
||||
if td is not None:
|
||||
cpu_temps = [td.thermal.cpu0, td.thermal.cpu1, td.thermal.cpu2,
|
||||
td.thermal.cpu3, td.thermal.mem, td.thermal.gpu]
|
||||
# check overtemp
|
||||
if any(t > 950 for t in cpu_temps):
|
||||
AM.add("overheat", enabled)
|
||||
# Check temperature.
|
||||
overtemp = any(
|
||||
t > 950
|
||||
for t in (td.thermal.cpu0, td.thermal.cpu1, td.thermal.cpu2,
|
||||
td.thermal.cpu3, td.thermal.mem, td.thermal.gpu))
|
||||
# under 15% of space free
|
||||
free_space = td.thermal.freeSpace
|
||||
|
||||
# *** getting model logic ***
|
||||
PP.update(cur_time, CS.vEgo)
|
||||
|
||||
if rk.frame % 5 == 2:
|
||||
# *** run this at 20hz again ***
|
||||
angle_offset = learn_angle_offset(enabled, CS.vEgo, angle_offset, np.asarray(PP.d_poly), LaC.y_des, CS.steeringPressed)
|
||||
prof.checkpoint("Health")
|
||||
|
||||
# disable if the pedals are pressed while engaged, this is a user disable
|
||||
if enabled:
|
||||
if CS.gasPressed or CS.brakePressed:
|
||||
AM.add("disable", enabled)
|
||||
|
||||
# how did we get into this state?
|
||||
if CP.enableCruise and not CS.cruiseState.enabled:
|
||||
AM.add("cruiseDisabled", enabled)
|
||||
|
||||
if enable_request:
|
||||
# check for pressed pedals
|
||||
if CS.gasPressed or CS.brakePressed:
|
||||
@@ -165,53 +194,70 @@ def controlsd_thread(gctx, rate=100): #rate in Hz
|
||||
print "enabled pressed at", cur_time
|
||||
last_enable_request = cur_time
|
||||
|
||||
if VP.brake_only:
|
||||
# don't engage with less than 15% free
|
||||
if free_space < 0.15:
|
||||
AM.add("outOfSpace", enabled)
|
||||
enable_request = False
|
||||
|
||||
if CP.enableCruise:
|
||||
enable_condition = ((cur_time - last_enable_request) < 0.2) and CS.cruiseState.enabled
|
||||
else:
|
||||
enable_condition = enable_request
|
||||
|
||||
if CP.enableCruise and CS.cruiseState.enabled:
|
||||
v_cruise_kph = CS.cruiseState.speed * CV.MS_TO_KPH
|
||||
|
||||
prof.checkpoint("AdaptiveCruise")
|
||||
|
||||
# *** what's the plan ***
|
||||
new_plan = messaging.recv_sock(plan_sock)
|
||||
if new_plan is not None:
|
||||
plan = new_plan.plan
|
||||
plan = plan.as_builder() # plan can change in controls
|
||||
last_plan_time = cur_time
|
||||
|
||||
# check plan for timeout
|
||||
if cur_time - last_plan_time > 0.5:
|
||||
plan.lateralValid = False
|
||||
plan.longitudinalValid = False
|
||||
|
||||
# gives 18 seconds before decel begins (w 6 minute timeout)
|
||||
if awareness_status < -0.05:
|
||||
plan.aTargetMax = min(plan.aTargetMax, -0.2)
|
||||
plan.aTargetMin = min(plan.aTargetMin, plan.aTargetMax)
|
||||
|
||||
if enable_request or enable_condition or enabled:
|
||||
# add all alerts from car
|
||||
for alert in CS.errors:
|
||||
AM.add(alert, enabled)
|
||||
|
||||
if AC.dead:
|
||||
if not plan.longitudinalValid:
|
||||
AM.add("radarCommIssue", enabled)
|
||||
|
||||
if PP.dead:
|
||||
AM.add("modelCommIssue", enabled)
|
||||
if not plan.lateralValid:
|
||||
# If the model is not broadcasting, assume that it is because
|
||||
# the user has uploaded insufficient data for calibration.
|
||||
# Other cases that would trigger this are rare and unactionable by the user.
|
||||
AM.add("dataNeeded", enabled)
|
||||
|
||||
if enable_condition and not enabled and not AM.alertPresent():
|
||||
print "*** enabling controls"
|
||||
if overtemp:
|
||||
AM.add("overheat", enabled)
|
||||
|
||||
# beep for enabling
|
||||
AM.add("enable", enabled)
|
||||
|
||||
# enable both lateral and longitudinal controls
|
||||
enabled = True
|
||||
|
||||
# on activation, let's always set v_cruise from where we are, even if PCM ACC is active
|
||||
v_cruise_kph = int(round(max(CS.vEgo * CV.MS_TO_KPH * VP.ui_speed_fudge, V_CRUISE_ENABLE_MIN)))
|
||||
|
||||
# 6 minutes driver you're on
|
||||
awareness_status = 1.0
|
||||
|
||||
# reset the PID loops
|
||||
LaC.reset()
|
||||
# start long control at actual speed
|
||||
LoC.reset(v_pid = CS.vEgo)
|
||||
|
||||
if VP.brake_only and CS.cruiseState.enabled:
|
||||
v_cruise_kph = CS.cruiseState.speed * CV.MS_TO_KPH
|
||||
|
||||
# *** put the adaptive in adaptive cruise control ***
|
||||
AC.update(cur_time, CS.vEgo, CS.steeringAngle, LoC.v_pid, awareness_status, VP)
|
||||
# *** angle offset learning ***
|
||||
if rk.frame % 5 == 2 and plan.lateralValid:
|
||||
# *** run this at 20hz again ***
|
||||
angle_offset = learn_angle_offset(enabled, CS.vEgo, angle_offset, plan.dPoly, LaC.y_des, CS.steeringPressed)
|
||||
|
||||
# *** gas/brake PID loop ***
|
||||
final_gas, final_brake = LoC.update(enabled, CS.vEgo, v_cruise_kph, AC.v_target_lead, AC.a_target, AC.jerk_factor, VP)
|
||||
final_gas, final_brake = LoC.update(enabled, CS.vEgo, v_cruise_kph,
|
||||
plan.vTarget,
|
||||
[plan.aTargetMin, plan.aTargetMax],
|
||||
plan.jerkFactor, CP)
|
||||
|
||||
# *** steering PID loop ***
|
||||
final_steer, sat_flag = LaC.update(enabled, CS.vEgo, CS.steeringAngle, CS.steeringPressed, PP.d_poly, angle_offset, VP)
|
||||
final_steer, sat_flag = LaC.update(enabled, CS.vEgo, CS.steeringAngle, CS.steeringPressed, plan.dPoly, angle_offset, CP)
|
||||
|
||||
prof.checkpoint("PID")
|
||||
|
||||
# ***** handle alerts ****
|
||||
# send a "steering required alert" if saturation count has reached the limit
|
||||
@@ -232,7 +278,26 @@ def controlsd_thread(gctx, rate=100): #rate in Hz
|
||||
soft_disable_timer -= 1
|
||||
else:
|
||||
soft_disable_timer = None
|
||||
|
||||
|
||||
if enable_condition and not enabled and not AM.alertPresent():
|
||||
print "*** enabling controls"
|
||||
|
||||
# beep for enabling
|
||||
AM.add("enable", enabled)
|
||||
|
||||
# enable both lateral and longitudinal controls
|
||||
enabled = True
|
||||
|
||||
# on activation, let's always set v_cruise from where we are, even if PCM ACC is active
|
||||
v_cruise_kph = int(round(max(CS.vEgo * CV.MS_TO_KPH, V_CRUISE_ENABLE_MIN)))
|
||||
|
||||
# 6 minutes driver you're on
|
||||
awareness_status = 1.0
|
||||
|
||||
# reset the PID loops
|
||||
LaC.reset()
|
||||
# start long control at actual speed
|
||||
LoC.reset(v_pid = CS.vEgo)
|
||||
|
||||
# *** push the alerts to current ***
|
||||
alert_text_1, alert_text_2, visual_alert, audible_alert = AM.process_alerts(cur_time)
|
||||
@@ -247,14 +312,20 @@ def controlsd_thread(gctx, rate=100): #rate in Hz
|
||||
CC.steeringTorque = float(final_steer)
|
||||
|
||||
CC.cruiseControl.override = True
|
||||
CC.cruiseControl.cancel = bool((not VP.brake_only) or (not enabled and CS.cruiseState.enabled)) # always cancel if we have an interceptor
|
||||
CC.cruiseControl.speedOverride = float((LoC.v_pid - .3) if (VP.brake_only and final_brake == 0.) else 0.0)
|
||||
CC.cruiseControl.accelOverride = float(AC.a_pcm)
|
||||
CC.cruiseControl.cancel = bool((not CP.enableCruise) or (not enabled and CS.cruiseState.enabled)) # always cancel if we have an interceptor
|
||||
|
||||
# brake discount removes a sharp nonlinearity
|
||||
brake_discount = (1.0 - clip(final_brake*3., 0.0, 1.0))
|
||||
CC.cruiseControl.speedOverride = float(max(0.0, ((LoC.v_pid - .5) * brake_discount)) if CP.enableCruise else 0.0)
|
||||
|
||||
#CC.cruiseControl.accelOverride = float(AC.a_pcm)
|
||||
# TODO: fix this
|
||||
CC.cruiseControl.accelOverride = float(1.0)
|
||||
|
||||
CC.hudControl.setSpeed = float(v_cruise_kph * CV.KPH_TO_MS)
|
||||
CC.hudControl.speedVisible = enabled
|
||||
CC.hudControl.lanesVisible = enabled
|
||||
CC.hudControl.leadVisible = bool(AC.has_lead)
|
||||
CC.hudControl.leadVisible = plan.hasLead
|
||||
|
||||
CC.hudControl.visualAlert = visual_alert
|
||||
CC.hudControl.audibleAlert = audible_alert
|
||||
@@ -263,6 +334,14 @@ def controlsd_thread(gctx, rate=100): #rate in Hz
|
||||
if not CI.apply(CC):
|
||||
AM.add("controlsFailed", enabled)
|
||||
|
||||
# broadcast carControl
|
||||
cc_send = messaging.new_message()
|
||||
cc_send.init('carControl')
|
||||
cc_send.carControl = CC # copy?
|
||||
carcontrol.send(cc_send.to_bytes())
|
||||
|
||||
prof.checkpoint("CarControl")
|
||||
|
||||
# ***** publish state to logger *****
|
||||
|
||||
# publish controls state at 100Hz
|
||||
@@ -270,15 +349,13 @@ def controlsd_thread(gctx, rate=100): #rate in Hz
|
||||
dat.init('live100')
|
||||
|
||||
# show rear view camera on phone if in reverse gear or when button is pressed
|
||||
dat.live100.rearViewCam = ('reverseGear' in CS.errors) or rear_view_toggle
|
||||
dat.live100.rearViewCam = ('reverseGear' in CS.errors and rear_view_allowed) or rear_view_toggle
|
||||
dat.live100.alertText1 = alert_text_1
|
||||
dat.live100.alertText2 = alert_text_2
|
||||
dat.live100.awarenessStatus = max(awareness_status, 0.0) if enabled else 0.0
|
||||
|
||||
# what packets were used to process
|
||||
dat.live100.canMonoTimes = list(CS.canMonoTimes)
|
||||
dat.live100.mdMonoTime = PP.logMonoTime
|
||||
dat.live100.l20MonoTime = AC.logMonoTime
|
||||
|
||||
# if controls is enabled
|
||||
dat.live100.enabled = enabled
|
||||
@@ -301,22 +378,27 @@ def controlsd_thread(gctx, rate=100): #rate in Hz
|
||||
dat.live100.uiSteer = float(LaC.Ui_steer)
|
||||
|
||||
# processed radar state, should add a_pcm?
|
||||
dat.live100.vTargetLead = float(AC.v_target_lead)
|
||||
dat.live100.aTargetMin = float(AC.a_target[0])
|
||||
dat.live100.aTargetMax = float(AC.a_target[1])
|
||||
dat.live100.jerkFactor = float(AC.jerk_factor)
|
||||
dat.live100.vTargetLead = float(plan.vTarget)
|
||||
dat.live100.aTargetMin = float(plan.aTargetMin)
|
||||
dat.live100.aTargetMax = float(plan.aTargetMax)
|
||||
dat.live100.jerkFactor = float(plan.jerkFactor)
|
||||
|
||||
# log learned angle offset
|
||||
dat.live100.angleOffset = float(angle_offset)
|
||||
|
||||
# lag
|
||||
dat.live100.cumLagMs = -rk.remaining*1000.
|
||||
|
||||
live100.send(dat.to_bytes())
|
||||
|
||||
prof.checkpoint("Live100")
|
||||
|
||||
# *** run loop at fixed rate ***
|
||||
rk.keep_time()
|
||||
if rk.keep_time():
|
||||
prof.display()
|
||||
|
||||
def main(gctx=None):
|
||||
controlsd_thread(gctx, 100)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
@@ -19,13 +19,13 @@ def calc_cruise_accel_limits(v_ego):
|
||||
_A_TOTAL_MAX_V = [1.5, 1.9, 3.2]
|
||||
_A_TOTAL_MAX_BP = [0., 20., 40.]
|
||||
|
||||
def limit_accel_in_turns(v_ego, angle_steers, a_target, a_pcm, VP):
|
||||
def limit_accel_in_turns(v_ego, angle_steers, a_target, a_pcm, CP):
|
||||
#*** this function returns a limited long acceleration allowed, depending on the existing lateral acceleration
|
||||
# this should avoid accelerating when losing the target in turns
|
||||
deg_to_rad = np.pi / 180. # from can reading to rad
|
||||
|
||||
a_total_max = interp(v_ego, _A_TOTAL_MAX_BP, _A_TOTAL_MAX_V)
|
||||
a_y = v_ego**2 * angle_steers * deg_to_rad / (VP.steer_ratio * VP.wheelbase)
|
||||
a_y = v_ego**2 * angle_steers * deg_to_rad / (CP.steerRatio * CP.wheelBase)
|
||||
a_x_allowed = math.sqrt(max(a_total_max**2 - a_y**2, 0.))
|
||||
|
||||
a_target[1] = min(a_target[1], a_x_allowed)
|
||||
@@ -168,8 +168,9 @@ def calc_acc_accel_limits(d_lead, d_des, v_ego, v_pid, v_lead, v_rel, a_lead,
|
||||
a_lead_contr, a_target[1])
|
||||
# second call of calc_positive_accel_limit is used to limit the pcm throttle
|
||||
# control (only useful when we don't control throttle directly)
|
||||
a_pcm = calc_positive_accel_limit(d_lead, d_des, v_ego, v_rel, v_ego, v_rel,
|
||||
v_coast, v_target, a_lead_contr, a_pcm)
|
||||
a_pcm = calc_positive_accel_limit(d_lead, d_des, v_ego, v_rel, v_ego,
|
||||
v_rel, v_coast, v_target,
|
||||
a_lead_contr, a_pcm)
|
||||
|
||||
#*** compute max decel ***
|
||||
v_offset = 1. # assume the car is 1m/s slower
|
||||
@@ -236,20 +237,9 @@ def calc_ttc(d_rel, v_rel, a_rel, v_lead):
|
||||
return ttc
|
||||
|
||||
|
||||
def limit_accel_driver_awareness(v_ego, a_target, a_pcm, awareness_status):
|
||||
decel_bp = [0. , 40.]
|
||||
decel_v = [-0.3, -0.2]
|
||||
decel = interp(v_ego, decel_bp, decel_v)
|
||||
# gives 18 seconds before decel begins (w 6 minute timeout)
|
||||
if awareness_status < -0.05:
|
||||
a_target[1] = min(a_target[1], decel)
|
||||
a_target[0] = min(a_target[1], a_target[0])
|
||||
a_pcm = 0.
|
||||
return a_target, a_pcm
|
||||
|
||||
MAX_SPEED_POSSIBLE = 55.
|
||||
|
||||
def compute_speed_with_leads(v_ego, angle_steers, v_pid, l1, l2, awareness_status, VP):
|
||||
def compute_speed_with_leads(v_ego, angle_steers, v_pid, l1, l2, CP):
|
||||
# drive limits
|
||||
# TODO: Make lims function of speed (more aggressive at low speed).
|
||||
a_lim = [-3., 1.5]
|
||||
@@ -263,7 +253,7 @@ def compute_speed_with_leads(v_ego, angle_steers, v_pid, l1, l2, awareness_statu
|
||||
a_pcm = 1
|
||||
|
||||
#*** limit max accel in sharp turns
|
||||
a_target, a_pcm = limit_accel_in_turns(v_ego, angle_steers, a_target, a_pcm, VP)
|
||||
a_target, a_pcm = limit_accel_in_turns(v_ego, angle_steers, a_target, a_pcm, CP)
|
||||
jerk_factor = 0.
|
||||
|
||||
if l1 is not None and l1.status:
|
||||
@@ -305,8 +295,6 @@ def compute_speed_with_leads(v_ego, angle_steers, v_pid, l1, l2, awareness_statu
|
||||
jerk_factor = calc_jerk_factor(l1.dRel, l1.vRel)
|
||||
|
||||
# force coasting decel if driver hasn't been controlling car in a while
|
||||
a_target, a_pcm = limit_accel_driver_awareness(v_ego, a_target, a_pcm, awareness_status)
|
||||
|
||||
return v_target_lead, a_target, a_pcm, jerk_factor
|
||||
|
||||
|
||||
@@ -317,7 +305,7 @@ class AdaptiveCruise(object):
|
||||
self.l1, self.l2 = None, None
|
||||
self.logMonoTime = 0
|
||||
self.dead = True
|
||||
def update(self, cur_time, v_ego, angle_steers, v_pid, awareness_status, VP):
|
||||
def update(self, cur_time, v_ego, angle_steers, v_pid, CP):
|
||||
l20 = messaging.recv_sock(self.live20)
|
||||
if l20 is not None:
|
||||
self.l1 = l20.live20.leadOne
|
||||
@@ -331,5 +319,5 @@ class AdaptiveCruise(object):
|
||||
self.dead = True
|
||||
|
||||
self.v_target_lead, self.a_target, self.a_pcm, self.jerk_factor = \
|
||||
compute_speed_with_leads(v_ego, angle_steers, v_pid, self.l1, self.l2, awareness_status, VP)
|
||||
compute_speed_with_leads(v_ego, angle_steers, v_pid, self.l1, self.l2, CP)
|
||||
self.has_lead = self.v_target_lead != MAX_SPEED_POSSIBLE
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from cereal import car
|
||||
from selfdrive.swaglog import cloudlog
|
||||
|
||||
class ET:
|
||||
ENABLE = 0
|
||||
@@ -24,7 +25,7 @@ class alert(object):
|
||||
tst = car.CarControl.new_message()
|
||||
tst.hudControl.visualAlert = self.visual_alert
|
||||
tst.hudControl.audibleAlert = self.audible_alert
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return self.alert_text_1 + "/" + self.alert_text_2 + " " + str(self.alert_type) + " " + str(self.visual_alert) + " " + str(self.audible_alert)
|
||||
|
||||
@@ -54,11 +55,17 @@ class AlertManager(object):
|
||||
"doorOpen": alert("Take Control Immediately","Door Open", ET.SOFT_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
|
||||
"seatbeltNotLatched": alert("Take Control Immediately","Seatbelt Unlatched", ET.SOFT_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
|
||||
"espDisabled": alert("Take Control Immediately","ESP Off", ET.SOFT_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
|
||||
"wrongCarMode": alert("Comma Unavailable","Main Switch Off", ET.NO_ENTRY, None, None, .4, 0., 3.),
|
||||
"cruiseDisabled": alert("Take Control Immediately","Cruise Is Off", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
|
||||
"wrongCarMode": alert("Comma Unavailable","Main Switch Off", ET.NO_ENTRY, None, "chimeDouble", .4, 0., 3.),
|
||||
"outOfSpace": alert("Comma Unavailable","Out of Space", ET.NO_ENTRY, None, "chimeDouble", .4, 0., 3.),
|
||||
"dataNeeded": alert("Comma Unavailable","Data needed for calibration. Upload drive, try again", ET.NO_ENTRY, None, "chimeDouble", .4, 0., 3.),
|
||||
"ethicalDilemma": alert("Take Control Immediately","Ethical Dilemma Detected", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
|
||||
"startup": alert("Always Keep Hands on Wheel","Be Ready to Take Over Any Time", ET.NO_ENTRY, None, None, 0., 0., 15.),
|
||||
}
|
||||
def __init__(self):
|
||||
self.activealerts = []
|
||||
self.current_alert = None
|
||||
self.add("startup", False)
|
||||
|
||||
def alertPresent(self):
|
||||
return len(self.activealerts) > 0
|
||||
@@ -70,7 +77,8 @@ class AlertManager(object):
|
||||
return len(self.activealerts) > 0 and self.activealerts[0].alert_type >= ET.IMMEDIATE_DISABLE
|
||||
|
||||
def add(self, alert_type, enabled = True):
|
||||
this_alert = self.alerts[str(alert_type)]
|
||||
alert_type = str(alert_type)
|
||||
this_alert = self.alerts[alert_type]
|
||||
|
||||
# downgrade the alert if we aren't enabled
|
||||
if not enabled and this_alert.alert_type > ET.NO_ENTRY:
|
||||
@@ -80,6 +88,12 @@ class AlertManager(object):
|
||||
if enabled and this_alert.alert_type < ET.WARNING:
|
||||
return
|
||||
|
||||
# if new alert is different, log it
|
||||
if self.current_alert is None or self.current_alert.alert_text_2 != this_alert.alert_text_2:
|
||||
cloudlog.event('alert_add',
|
||||
alert_type=alert_type,
|
||||
enabled=enabled)
|
||||
|
||||
self.activealerts.append(this_alert)
|
||||
self.activealerts.sort()
|
||||
|
||||
@@ -106,6 +120,10 @@ class AlertManager(object):
|
||||
alert_text_1 = self.current_alert.alert_text_1
|
||||
alert_text_2 = self.current_alert.alert_text_2
|
||||
|
||||
# disable current alert
|
||||
if self.alert_start_time + max(self.current_alert.duration_sound, self.current_alert.duration_hud_alert, self.current_alert.duration_text) < cur_time:
|
||||
self.current_alert = None
|
||||
|
||||
# reset
|
||||
self.activealerts = []
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import numpy as np
|
||||
from common.numpy_fast import clip, interp
|
||||
from common.numpy_fast import clip
|
||||
|
||||
def rate_limit(new_value, last_value, dw_step, up_step):
|
||||
return clip(new_value, last_value + dw_step, last_value + up_step)
|
||||
@@ -21,33 +20,3 @@ def learn_angle_offset(lateral_control, v_ego, angle_offset, d_poly, y_des, stee
|
||||
|
||||
return angle_offset
|
||||
|
||||
def actuator_hystereses(final_brake, braking, brake_steady, v_ego, civic):
|
||||
# hyst params... TODO: move these to VehicleParams
|
||||
brake_hyst_on = 0.055 if civic else 0.1 # to activate brakes exceed this value
|
||||
brake_hyst_off = 0.005 # to deactivate brakes below this value
|
||||
brake_hyst_gap = 0.01 # don't change brake command for small ocilalitons within this value
|
||||
|
||||
#*** histeresys logic to avoid brake blinking. go above 0.1 to trigger
|
||||
if (final_brake < brake_hyst_on and not braking) or final_brake < brake_hyst_off:
|
||||
final_brake = 0.
|
||||
braking = final_brake > 0.
|
||||
|
||||
# for small brake oscillations within brake_hyst_gap, don't change the brake command
|
||||
if final_brake == 0.:
|
||||
brake_steady = 0.
|
||||
elif final_brake > brake_steady + brake_hyst_gap:
|
||||
brake_steady = final_brake - brake_hyst_gap
|
||||
elif final_brake < brake_steady - brake_hyst_gap:
|
||||
brake_steady = final_brake + brake_hyst_gap
|
||||
final_brake = brake_steady
|
||||
|
||||
if not civic:
|
||||
brake_on_offset_v = [.25, .15] # min brake command on brake activation. below this no decel is perceived
|
||||
brake_on_offset_bp = [15., 30.] # offset changes VS speed to not have too abrupt decels at high speeds
|
||||
# offset the brake command for threshold in the brake system. no brake torque perceived below it
|
||||
brake_on_offset = interp(v_ego, brake_on_offset_bp, brake_on_offset_v)
|
||||
brake_offset = brake_on_offset - brake_hyst_on
|
||||
if final_brake > 0.0:
|
||||
final_brake += brake_offset
|
||||
|
||||
return final_brake, braking, brake_steady
|
||||
|
||||
@@ -2,10 +2,10 @@ import math
|
||||
import numpy as np
|
||||
from common.numpy_fast import clip
|
||||
|
||||
def calc_curvature(v_ego, angle_steers, VP, angle_offset=0):
|
||||
def calc_curvature(v_ego, angle_steers, CP, angle_offset=0):
|
||||
deg_to_rad = np.pi/180.
|
||||
angle_steers_rad = (angle_steers - angle_offset) * deg_to_rad
|
||||
curvature = angle_steers_rad/(VP.steer_ratio * VP.wheelbase * (1. + VP.slip_factor * v_ego**2))
|
||||
curvature = angle_steers_rad/(CP.steerRatio * CP.wheelBase * (1. + CP.slipFactor * v_ego**2))
|
||||
return curvature
|
||||
|
||||
def calc_d_lookahead(v_ego):
|
||||
@@ -13,32 +13,29 @@ def calc_d_lookahead(v_ego):
|
||||
# howfar we look ahead is function of speed
|
||||
offset_lookahead = 1.
|
||||
coeff_lookahead = 4.4
|
||||
# sqrt on speed is needed to keep, for a given curvature, the y_offset
|
||||
# sqrt on speed is needed to keep, for a given curvature, the y_offset
|
||||
# proportional to speed. Indeed, y_offset is prop to d_lookahead^2
|
||||
# 26m at 25m/s
|
||||
d_lookahead = offset_lookahead + math.sqrt(max(v_ego, 0)) * coeff_lookahead
|
||||
return d_lookahead
|
||||
|
||||
def calc_lookahead_offset(v_ego, angle_steers, d_lookahead, VP, angle_offset):
|
||||
def calc_lookahead_offset(v_ego, angle_steers, d_lookahead, CP, angle_offset):
|
||||
#*** this function return teh lateral offset given the steering angle, speed and the lookahead distance
|
||||
curvature = calc_curvature(v_ego, angle_steers, VP, angle_offset)
|
||||
curvature = calc_curvature(v_ego, angle_steers, CP, angle_offset)
|
||||
|
||||
# clip is to avoid arcsin NaNs due to too sharp turns
|
||||
y_actual = d_lookahead * np.tan(np.arcsin(np.clip(d_lookahead * curvature, -0.999, 0.999))/2.)
|
||||
return y_actual, curvature
|
||||
|
||||
def pid_lateral_control(v_ego, y_actual, y_des, Ui_steer, steer_max,
|
||||
steer_override, sat_count, enabled, half_pid, rate):
|
||||
steer_override, sat_count, enabled, Kp, Ki, rate):
|
||||
|
||||
sat_count_rate = 1./rate
|
||||
sat_count_limit = 0.8 # after 0.8s of continuous saturation, an alert will be sent
|
||||
sat_count_limit = 0.8 # after 0.8s of continuous saturation, an alert will be sent
|
||||
|
||||
error_steer = y_des - y_actual
|
||||
Ui_unwind_speed = 0.3/rate #.3 per second
|
||||
if not half_pid:
|
||||
Kp, Ki = 12.0, 1.0
|
||||
else:
|
||||
Kp, Ki = 6.0, .5 # 2x limit in ILX
|
||||
|
||||
Up_steer = error_steer*Kp
|
||||
Ui_steer_new = Ui_steer + error_steer*Ki * 1./rate
|
||||
output_steer_new = Ui_steer_new + Up_steer
|
||||
@@ -99,7 +96,7 @@ class LatControl(object):
|
||||
def reset(self):
|
||||
self.Ui_steer = 0.
|
||||
|
||||
def update(self, enabled, v_ego, angle_steers, steer_override, d_poly, angle_offset, VP):
|
||||
def update(self, enabled, v_ego, angle_steers, steer_override, d_poly, angle_offset, CP):
|
||||
rate = 100
|
||||
|
||||
steer_max = 1.0
|
||||
@@ -109,14 +106,14 @@ class LatControl(object):
|
||||
|
||||
# calculate actual offset at the lookahead point
|
||||
self.y_actual, _ = calc_lookahead_offset(v_ego, angle_steers,
|
||||
d_lookahead, VP, angle_offset)
|
||||
d_lookahead, CP, angle_offset)
|
||||
|
||||
# desired lookahead offset
|
||||
self.y_des = np.polyval(d_poly, d_lookahead)
|
||||
|
||||
output_steer, self.Up_steer, self.Ui_steer, self.lateral_control_sat, self.sat_count, sat_flag = pid_lateral_control(
|
||||
v_ego, self.y_actual, self.y_des, self.Ui_steer, steer_max,
|
||||
steer_override, self.sat_count, enabled, VP.torque_mod, rate)
|
||||
steer_override, self.sat_count, enabled, CP.steerKp, CP.steerKi, rate)
|
||||
|
||||
final_steer = clip(output_steer, -steer_max, steer_max)
|
||||
return final_steer, sat_flag
|
||||
|
||||
@@ -96,7 +96,7 @@ def pid_long_control(v_ego, v_pid, Ui_accel_cmd, gas_max, brake_max, jerk_factor
|
||||
Kp = interp(v_ego, _KP_BP, _KP_V)
|
||||
Ki = interp(v_ego, _kI_BP, _kI_V)
|
||||
|
||||
# scle Kp and Ki by jerk factor drom drive_thread
|
||||
# scale Kp and Ki by jerk factor from drive_thread
|
||||
Kp = (1. + jerk_factor)*Kp
|
||||
Ki = (1. + jerk_factor)*Ki
|
||||
|
||||
@@ -155,7 +155,7 @@ class LongControl(object):
|
||||
self.Ui_accel_cmd = 0.
|
||||
self.v_pid = v_pid
|
||||
|
||||
def update(self, enabled, v_ego, v_cruise, v_target_lead, a_target, jerk_factor, VP):
|
||||
def update(self, enabled, v_ego, v_cruise, v_target_lead, a_target, jerk_factor, CP):
|
||||
brake_max_bp = [0., 5., 20., 100.] # speeds
|
||||
brake_max_v = [1.0, 1.0, 0.8, 0.8] # values
|
||||
|
||||
@@ -163,12 +163,12 @@ class LongControl(object):
|
||||
brake_max = interp(v_ego, brake_max_bp, brake_max_v)
|
||||
|
||||
# TODO: not every time
|
||||
if VP.brake_only:
|
||||
gas_max = 0
|
||||
else:
|
||||
if CP.enableGas:
|
||||
gas_max_bp = [0., 100.] # speeds
|
||||
gas_max_v = [0.6, 0.6] # values
|
||||
gas_max = interp(v_ego, gas_max_bp, gas_max_v)
|
||||
else:
|
||||
gas_max = 0
|
||||
|
||||
overshoot_allowance = 2.0 # overshoot allowed when changing accel sign
|
||||
|
||||
@@ -177,7 +177,7 @@ class LongControl(object):
|
||||
|
||||
# limit max target speed based on cruise setting:
|
||||
v_cruise_mph = round(v_cruise * CV.KPH_TO_MPH) # what's displayed in mph on the IC
|
||||
v_target = min(v_target_lead, v_cruise_mph * CV.MPH_TO_MS / VP.ui_speed_fudge)
|
||||
v_target = min(v_target_lead, v_cruise_mph * CV.MPH_TO_MS)
|
||||
|
||||
max_speed_delta_up = a_target[1]*1.0/rate
|
||||
max_speed_delta_down = a_target[0]*1.0/rate
|
||||
@@ -211,7 +211,7 @@ class LongControl(object):
|
||||
self.v_pid = v_target
|
||||
|
||||
# to avoid too much wind up on acceleration, limit positive speed error
|
||||
if not VP.brake_only:
|
||||
if CP.enableGas:
|
||||
max_speed_error = interp(v_ego, _MAX_SPEED_ERROR_BP, _MAX_SPEED_ERROR_V)
|
||||
self.v_pid = min(self.v_pid, v_ego + max_speed_error)
|
||||
|
||||
|
||||
@@ -3,10 +3,17 @@ import numpy as np
|
||||
|
||||
from common.numpy_fast import interp
|
||||
import selfdrive.messaging as messaging
|
||||
X_PATH = np.arange(0.0, 50.0)
|
||||
|
||||
def model_polyfit(points):
|
||||
return np.polyfit(X_PATH, map(float, points), 3)
|
||||
|
||||
def compute_path_pinv():
|
||||
deg = 3
|
||||
x = np.arange(50.0)
|
||||
X = np.vstack(tuple(x**n for n in range(deg, -1, -1))).T
|
||||
pinv = np.linalg.pinv(X)
|
||||
return pinv
|
||||
|
||||
def model_polyfit(points, path_pinv):
|
||||
return np.dot(path_pinv, map(float, points))
|
||||
|
||||
# lane width http://safety.fhwa.dot.gov/geometric/pubs/mitigationstrategies/chapter3/3_lanewidth.cfm
|
||||
_LANE_WIDTH_V = [3., 3.8]
|
||||
@@ -40,24 +47,26 @@ class PathPlanner(object):
|
||||
self.last_model = 0.
|
||||
self.logMonoTime = 0
|
||||
self.lead_dist, self.lead_prob, self.lead_var = 0, 0, 1
|
||||
self._path_pinv = compute_path_pinv()
|
||||
|
||||
def update(self, cur_time, v_ego):
|
||||
md = messaging.recv_sock(self.model)
|
||||
|
||||
if md is not None:
|
||||
self.logMonoTime = md.logMonoTime
|
||||
p_poly = model_polyfit(md.model.path.points) # predicted path
|
||||
p_prob = 1. # model does not tell this probability yet, so set to 1 for now
|
||||
l_poly = model_polyfit(md.model.leftLane.points) # left line
|
||||
l_prob = md.model.leftLane.prob # left line prob
|
||||
r_poly = model_polyfit(md.model.rightLane.points) # right line
|
||||
r_prob = md.model.rightLane.prob # right line prob
|
||||
p_poly = model_polyfit(md.model.path.points, self._path_pinv) # predicted path
|
||||
l_poly = model_polyfit(md.model.leftLane.points, self._path_pinv) # left line
|
||||
r_poly = model_polyfit(md.model.rightLane.points, self._path_pinv) # right line
|
||||
|
||||
p_prob = 1. # model does not tell this probability yet, so set to 1 for now
|
||||
l_prob = md.model.leftLane.prob # left line prob
|
||||
r_prob = md.model.rightLane.prob # right line prob
|
||||
|
||||
self.lead_dist = md.model.lead.dist
|
||||
self.lead_prob = md.model.lead.prob
|
||||
self.lead_var = md.model.lead.std**2
|
||||
|
||||
#*** compute target path ***
|
||||
# compute target path
|
||||
self.d_poly, _, _ = calc_desired_path(l_poly, r_poly, p_poly, l_prob, r_prob, p_prob, v_ego)
|
||||
|
||||
self.last_model = cur_time
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user