Merge panda subtree
commit
7834995df4
|
@ -0,0 +1,3 @@
|
||||||
|
.git
|
||||||
|
.DS_Store
|
||||||
|
boardesp/esp-open-sdk
|
|
@ -0,0 +1,64 @@
|
||||||
|
FROM ubuntu:16.04
|
||||||
|
ENV PYTHONUNBUFFERED 1
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
autoconf \
|
||||||
|
automake \
|
||||||
|
bash \
|
||||||
|
bison \
|
||||||
|
bzip2 \
|
||||||
|
curl \
|
||||||
|
dfu-util \
|
||||||
|
flex \
|
||||||
|
g++ \
|
||||||
|
gawk \
|
||||||
|
gcc \
|
||||||
|
git \
|
||||||
|
gperf \
|
||||||
|
help2man \
|
||||||
|
iputils-ping \
|
||||||
|
libexpat-dev \
|
||||||
|
libstdc++-arm-none-eabi-newlib \
|
||||||
|
libtool \
|
||||||
|
libtool-bin \
|
||||||
|
libusb-1.0-0 \
|
||||||
|
make \
|
||||||
|
ncurses-dev \
|
||||||
|
network-manager \
|
||||||
|
python-dev \
|
||||||
|
python-serial \
|
||||||
|
sed \
|
||||||
|
texinfo \
|
||||||
|
unrar-free \
|
||||||
|
unzip \
|
||||||
|
wget \
|
||||||
|
build-essential \
|
||||||
|
python-dev \
|
||||||
|
python-pip \
|
||||||
|
screen \
|
||||||
|
vim \
|
||||||
|
wget \
|
||||||
|
wireless-tools
|
||||||
|
|
||||||
|
RUN pip install --upgrade pip==18.0
|
||||||
|
|
||||||
|
COPY requirements.txt /tmp/
|
||||||
|
RUN pip install -r /tmp/requirements.txt
|
||||||
|
|
||||||
|
RUN mkdir -p /home/batman
|
||||||
|
ENV HOME /home/batman
|
||||||
|
|
||||||
|
ENV PYTHONPATH /tmp:$PYTHONPATH
|
||||||
|
|
||||||
|
COPY ./boardesp/get_sdk_ci.sh /tmp/panda/boardesp/
|
||||||
|
|
||||||
|
RUN useradd --system -s /sbin/nologin pandauser
|
||||||
|
RUN mkdir -p /tmp/panda/boardesp/esp-open-sdk
|
||||||
|
RUN chown pandauser /tmp/panda/boardesp/esp-open-sdk
|
||||||
|
USER pandauser
|
||||||
|
RUN cd /tmp/panda/boardesp && ./get_sdk_ci.sh
|
||||||
|
USER root
|
||||||
|
|
||||||
|
COPY ./xx/pandaextra /tmp/pandaextra
|
||||||
|
|
||||||
|
ADD ./panda.tar.gz /tmp/panda
|
|
@ -0,0 +1,55 @@
|
||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
environment {
|
||||||
|
AUTHOR = """${sh(
|
||||||
|
returnStdout: true,
|
||||||
|
script: "git --no-pager show -s --format='%an' ${GIT_COMMIT}"
|
||||||
|
).trim()}"""
|
||||||
|
|
||||||
|
DOCKER_IMAGE_TAG = "panda:build-${env.BUILD_ID}"
|
||||||
|
DOCKER_NAME = "panda-test-${env.BUILD_ID}"
|
||||||
|
}
|
||||||
|
stages {
|
||||||
|
stage('Build Docker Image') {
|
||||||
|
steps {
|
||||||
|
timeout(time: 60, unit: 'MINUTES') {
|
||||||
|
script {
|
||||||
|
sh 'git clone --no-checkout --depth 1 git@github.com:commaai/xx.git || true'
|
||||||
|
sh 'cd xx && git fetch origin && git checkout origin/master -- pandaextra && cd ..' // Needed for certs for panda flashing
|
||||||
|
sh 'git archive -v -o panda.tar.gz --format=tar.gz HEAD'
|
||||||
|
dockerImage = docker.build("${env.DOCKER_IMAGE_TAG}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Test Dev Build') {
|
||||||
|
steps {
|
||||||
|
lock(resource: "Pandas", inversePrecedence: true, quantity:1){
|
||||||
|
timeout(time: 60, unit: 'MINUTES') {
|
||||||
|
sh "docker run --name ${env.DOCKER_NAME} --privileged --volume /dev/bus/usb:/dev/bus/usb --volume /var/run/dbus:/var/run/dbus --net host ${env.DOCKER_IMAGE_TAG} bash -c 'cd /tmp/panda; ./run_automated_tests.sh '"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Test EON Build') {
|
||||||
|
steps {
|
||||||
|
lock(resource: "Pandas", inversePrecedence: true, quantity:1){
|
||||||
|
timeout(time: 60, unit: 'MINUTES') {
|
||||||
|
sh "docker cp ${env.DOCKER_NAME}:/tmp/panda/nosetests.xml test_results_dev.xml"
|
||||||
|
sh "touch EON && docker cp EON ${env.DOCKER_NAME}:/EON"
|
||||||
|
sh "docker start -a ${env.DOCKER_NAME}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
post {
|
||||||
|
always {
|
||||||
|
script {
|
||||||
|
sh "docker cp ${env.DOCKER_NAME}:/tmp/panda/nosetests.xml test_results_EON.xml"
|
||||||
|
sh "docker rm ${env.DOCKER_NAME}"
|
||||||
|
}
|
||||||
|
junit "test_results*.xml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1 +1 @@
|
||||||
v1.2.0
|
v1.2.1
|
|
@ -3,6 +3,8 @@
|
||||||
#define ALL_CAN_BUT_MAIN_SILENT 0xFE
|
#define ALL_CAN_BUT_MAIN_SILENT 0xFE
|
||||||
#define ALL_CAN_LIVE 0
|
#define ALL_CAN_LIVE 0
|
||||||
|
|
||||||
|
#include "lline_relay.h"
|
||||||
|
|
||||||
int can_live = 0, pending_can_live = 0, can_loopback = 0, can_silent = ALL_CAN_SILENT;
|
int can_live = 0, pending_can_live = 0, can_loopback = 0, can_silent = ALL_CAN_SILENT;
|
||||||
|
|
||||||
// ********************* instantiate queues *********************
|
// ********************* instantiate queues *********************
|
||||||
|
@ -23,6 +25,11 @@ can_buffer(tx2_q, 0x100)
|
||||||
can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q};
|
can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef PANDA
|
||||||
|
// Forward declare
|
||||||
|
void power_save_reset_timer();
|
||||||
|
#endif
|
||||||
|
|
||||||
// ********************* interrupt safe queue *********************
|
// ********************* interrupt safe queue *********************
|
||||||
|
|
||||||
int can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
|
int can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem) {
|
||||||
|
@ -213,7 +220,7 @@ void can_init(uint8_t can_number) {
|
||||||
CAN->FMR &= ~(CAN_FMR_FINIT);
|
CAN->FMR &= ~(CAN_FMR_FINIT);
|
||||||
|
|
||||||
// enable certain CAN interrupts
|
// enable certain CAN interrupts
|
||||||
CAN->IER |= CAN_IER_TMEIE | CAN_IER_FMPIE0;
|
CAN->IER |= CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_WKUIE;
|
||||||
|
|
||||||
switch (can_number) {
|
switch (can_number) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -293,7 +300,6 @@ void can_set_gmlan(int bus) {
|
||||||
void can_sce(CAN_TypeDef *CAN) {
|
void can_sce(CAN_TypeDef *CAN) {
|
||||||
enter_critical_section();
|
enter_critical_section();
|
||||||
|
|
||||||
can_err_cnt += 1;
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (CAN==CAN1) puts("CAN1: ");
|
if (CAN==CAN1) puts("CAN1: ");
|
||||||
if (CAN==CAN2) puts("CAN2: ");
|
if (CAN==CAN2) puts("CAN2: ");
|
||||||
|
@ -315,16 +321,32 @@ void can_sce(CAN_TypeDef *CAN) {
|
||||||
|
|
||||||
uint8_t can_number = CAN_NUM_FROM_CANIF(CAN);
|
uint8_t can_number = CAN_NUM_FROM_CANIF(CAN);
|
||||||
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
|
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
|
||||||
if (can_autobaud_enabled[bus_number] && (CAN->ESR & CAN_ESR_LEC)) {
|
|
||||||
can_autobaud_speed_increment(can_number);
|
if (CAN->MSR & CAN_MSR_WKUI) {
|
||||||
can_set_speed(can_number);
|
//Waking from sleep
|
||||||
|
#ifdef DEBUG
|
||||||
|
puts("WAKE\n");
|
||||||
|
#endif
|
||||||
|
set_can_enable(CAN, 1);
|
||||||
|
CAN->MSR &= ~(CAN_MSR_WKUI);
|
||||||
|
CAN->MSR = CAN->MSR;
|
||||||
|
#ifdef PANDA
|
||||||
|
power_save_reset_timer();
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
can_err_cnt += 1;
|
||||||
|
|
||||||
|
|
||||||
|
if (can_autobaud_enabled[bus_number] && (CAN->ESR & CAN_ESR_LEC)) {
|
||||||
|
can_autobaud_speed_increment(can_number);
|
||||||
|
can_set_speed(can_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear current send
|
||||||
|
CAN->TSR |= CAN_TSR_ABRQ0;
|
||||||
|
CAN->MSR &= ~(CAN_MSR_ERRI);
|
||||||
|
CAN->MSR = CAN->MSR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear current send
|
|
||||||
CAN->TSR |= CAN_TSR_ABRQ0;
|
|
||||||
CAN->MSR &= ~(CAN_MSR_ERRI);
|
|
||||||
CAN->MSR = CAN->MSR;
|
|
||||||
|
|
||||||
exit_critical_section();
|
exit_critical_section();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,6 +354,9 @@ void can_sce(CAN_TypeDef *CAN) {
|
||||||
|
|
||||||
void process_can(uint8_t can_number) {
|
void process_can(uint8_t can_number) {
|
||||||
if (can_number == 0xff) return;
|
if (can_number == 0xff) return;
|
||||||
|
#ifdef PANDA
|
||||||
|
power_save_reset_timer();
|
||||||
|
#endif
|
||||||
|
|
||||||
enter_critical_section();
|
enter_critical_section();
|
||||||
|
|
||||||
|
@ -375,6 +400,13 @@ void process_can(uint8_t can_number) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (can_pop(can_queues[bus_number], &to_send)) {
|
if (can_pop(can_queues[bus_number], &to_send)) {
|
||||||
|
if (CAN->MCR & CAN_MCR_SLEEP) {
|
||||||
|
set_can_enable(CAN, 1);
|
||||||
|
CAN->MCR &= ~(CAN_MCR_SLEEP);
|
||||||
|
CAN->MCR |= CAN_MCR_INRQ;
|
||||||
|
while((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK);
|
||||||
|
CAN->MCR &= ~(CAN_MCR_INRQ);
|
||||||
|
}
|
||||||
can_tx_cnt += 1;
|
can_tx_cnt += 1;
|
||||||
// only send if we have received a packet
|
// only send if we have received a packet
|
||||||
CAN->sTxMailBox[0].TDLR = to_send.RDLR;
|
CAN->sTxMailBox[0].TDLR = to_send.RDLR;
|
||||||
|
@ -390,6 +422,9 @@ void process_can(uint8_t can_number) {
|
||||||
// CAN receive handlers
|
// CAN receive handlers
|
||||||
// blink blue when we are receiving CAN messages
|
// blink blue when we are receiving CAN messages
|
||||||
void can_rx(uint8_t can_number) {
|
void can_rx(uint8_t can_number) {
|
||||||
|
#ifdef PANDA
|
||||||
|
power_save_reset_timer();
|
||||||
|
#endif
|
||||||
CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number);
|
CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number);
|
||||||
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
|
uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number);
|
||||||
while (CAN->RF0R & CAN_RF0R_FMP0) {
|
while (CAN->RF0R & CAN_RF0R_FMP0) {
|
||||||
|
@ -420,14 +455,16 @@ void can_rx(uint8_t can_number) {
|
||||||
|
|
||||||
// forwarding (panda only)
|
// forwarding (panda only)
|
||||||
#ifdef PANDA
|
#ifdef PANDA
|
||||||
int bus_fwd_num = can_forwarding[bus_number] != -1 ? can_forwarding[bus_number] : safety_fwd_hook(bus_number, &to_push);
|
if ((get_lline_status() != 0) || !relay_control) { //Relay engaged or relay isn't controlled, allow fwd
|
||||||
if (bus_fwd_num != -1) {
|
int bus_fwd_num = can_forwarding[bus_number] != -1 ? can_forwarding[bus_number] : safety_fwd_hook(bus_number, &to_push);
|
||||||
CAN_FIFOMailBox_TypeDef to_send;
|
if (bus_fwd_num != -1) {
|
||||||
to_send.RIR = to_push.RIR | 1; // TXRQ
|
CAN_FIFOMailBox_TypeDef to_send;
|
||||||
to_send.RDTR = to_push.RDTR;
|
to_send.RIR = to_push.RIR | 1; // TXRQ
|
||||||
to_send.RDLR = to_push.RDLR;
|
to_send.RDTR = to_push.RDTR;
|
||||||
to_send.RDHR = to_push.RDHR;
|
to_send.RDLR = to_push.RDLR;
|
||||||
can_send(&to_send, bus_fwd_num);
|
to_send.RDHR = to_push.RDHR;
|
||||||
|
can_send(&to_send, bus_fwd_num);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
#ifdef PANDA
|
||||||
|
|
||||||
|
int relay_control = 0; // True if relay is controlled through l-line
|
||||||
|
|
||||||
|
/* Conrol a relay connected to l-line pin */
|
||||||
|
|
||||||
|
// 160us cycles, 1 high, 25 low
|
||||||
|
|
||||||
|
volatile int turn_on_relay = 0;
|
||||||
|
volatile int on_cycles = 25;
|
||||||
|
|
||||||
|
//5s timeout
|
||||||
|
#define LLINE_TIMEOUT_CYCLES 31250
|
||||||
|
volatile int timeout_cycles = LLINE_TIMEOUT_CYCLES;
|
||||||
|
|
||||||
|
void TIM5_IRQHandler(void) {
|
||||||
|
if (TIM5->SR & TIM_SR_UIF) {
|
||||||
|
on_cycles--;
|
||||||
|
timeout_cycles--;
|
||||||
|
if (timeout_cycles == 0) {
|
||||||
|
turn_on_relay = 0;
|
||||||
|
}
|
||||||
|
if (on_cycles > 0) {
|
||||||
|
if (turn_on_relay) {
|
||||||
|
set_gpio_output(GPIOC, 10, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
set_gpio_output(GPIOC, 10, 1);
|
||||||
|
on_cycles = 25;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TIM5->ARR = 160-1;
|
||||||
|
TIM5->SR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lline_relay_init (void) {
|
||||||
|
set_lline_output(0);
|
||||||
|
relay_control = 1;
|
||||||
|
set_gpio_output(GPIOC, 10, 1);
|
||||||
|
|
||||||
|
// setup
|
||||||
|
TIM5->PSC = 48-1; // tick on 1 us
|
||||||
|
TIM5->CR1 = TIM_CR1_CEN; // enable
|
||||||
|
TIM5->ARR = 50-1; // 50 us
|
||||||
|
TIM5->DIER = TIM_DIER_UIE; // update interrupt
|
||||||
|
TIM5->CNT = 0;
|
||||||
|
|
||||||
|
NVIC_EnableIRQ(TIM5_IRQn);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
puts("INIT LLINE\n");
|
||||||
|
puts(" SR ");
|
||||||
|
putui(TIM5->SR);
|
||||||
|
puts(" PSC ");
|
||||||
|
putui(TIM5->PSC);
|
||||||
|
puts(" CR1 ");
|
||||||
|
putui(TIM5->CR1);
|
||||||
|
puts(" ARR ");
|
||||||
|
putui(TIM5->ARR);
|
||||||
|
puts(" DIER ");
|
||||||
|
putui(TIM5->DIER);
|
||||||
|
puts(" SR ");
|
||||||
|
putui(TIM5->SR);
|
||||||
|
puts(" CNT ");
|
||||||
|
putui(TIM5->CNT);
|
||||||
|
puts("\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void lline_relay_release (void) {
|
||||||
|
set_lline_output(0);
|
||||||
|
relay_control = 0;
|
||||||
|
puts("RELEASE LLINE\n");
|
||||||
|
set_gpio_alternate(GPIOC, 10, GPIO_AF7_USART3);
|
||||||
|
NVIC_DisableIRQ(TIM5_IRQn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_lline_output(int to_set) {
|
||||||
|
timeout_cycles = LLINE_TIMEOUT_CYCLES;
|
||||||
|
turn_on_relay = to_set;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_lline_status() {
|
||||||
|
return turn_on_relay;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -120,6 +120,8 @@ void periph_init() {
|
||||||
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
|
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
|
||||||
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
|
||||||
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
|
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
|
||||||
|
RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;
|
||||||
|
RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;
|
||||||
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
|
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
|
||||||
RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
|
RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
|
||||||
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
|
||||||
|
@ -390,7 +392,9 @@ void gpio_init() {
|
||||||
set_gpio_output(GPIOA, 14, 1);
|
set_gpio_output(GPIOA, 14, 1);
|
||||||
|
|
||||||
// C10,C11: L-Line setup on USART 3
|
// C10,C11: L-Line setup on USART 3
|
||||||
set_gpio_alternate(GPIOC, 10, GPIO_AF7_USART3);
|
// LLine now used for relay output
|
||||||
|
set_gpio_output(GPIOC, 10, 1);
|
||||||
|
//set_gpio_alternate(GPIOC, 10, GPIO_AF7_USART3);
|
||||||
set_gpio_alternate(GPIOC, 11, GPIO_AF7_USART3);
|
set_gpio_alternate(GPIOC, 11, GPIO_AF7_USART3);
|
||||||
set_gpio_pullup(GPIOC, 11, PULL_UP);
|
set_gpio_pullup(GPIOC, 11, PULL_UP);
|
||||||
#endif
|
#endif
|
||||||
|
@ -475,4 +479,3 @@ void early() {
|
||||||
enter_bootloader_mode = ENTER_SOFTLOADER_MAGIC;
|
enter_bootloader_mode = ENTER_SOFTLOADER_MAGIC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include "drivers/spi.h"
|
#include "drivers/spi.h"
|
||||||
#include "drivers/timer.h"
|
#include "drivers/timer.h"
|
||||||
|
|
||||||
|
#include "power_saving.h"
|
||||||
|
|
||||||
|
|
||||||
// ***************************** fan *****************************
|
// ***************************** fan *****************************
|
||||||
|
|
||||||
|
@ -141,6 +143,7 @@ void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired) {
|
||||||
uart_ring *ur = get_ring_by_number(usbdata[0]);
|
uart_ring *ur = get_ring_by_number(usbdata[0]);
|
||||||
if (!ur) return;
|
if (!ur) return;
|
||||||
if ((usbdata[0] < 2) || safety_tx_lin_hook(usbdata[0]-2, usbdata+1, len-1)) {
|
if ((usbdata[0] < 2) || safety_tx_lin_hook(usbdata[0]-2, usbdata+1, len-1)) {
|
||||||
|
if (ur == &esp_ring) power_save_reset_timer();
|
||||||
for (int i = 1; i < len; i++) while (!putc(ur, usbdata[i]));
|
for (int i = 1; i < len; i++) while (!putc(ur, usbdata[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,6 +163,14 @@ void usb_cb_ep3_out(uint8_t *usbdata, int len, int hardwired) {
|
||||||
|
|
||||||
uint8_t bus_number = (to_push.RDTR >> 4) & CAN_BUS_NUM_MASK;
|
uint8_t bus_number = (to_push.RDTR >> 4) & CAN_BUS_NUM_MASK;
|
||||||
can_send(&to_push, bus_number);
|
can_send(&to_push, bus_number);
|
||||||
|
|
||||||
|
#ifdef PANDA
|
||||||
|
// Enable relay on can message if allowed.
|
||||||
|
// Temporary until OP has support for relay
|
||||||
|
if (safety_relay_hook()) {
|
||||||
|
set_lline_output(1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,6 +452,16 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// **** 0xf3: set l-line relay
|
||||||
|
case 0xf3:
|
||||||
|
{
|
||||||
|
#ifdef PANDA
|
||||||
|
if (safety_relay_hook()) {
|
||||||
|
set_lline_output(setup->b.wValue.w == 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
puts("NO HANDLER ");
|
puts("NO HANDLER ");
|
||||||
puth(setup->b.bRequest);
|
puth(setup->b.bRequest);
|
||||||
|
@ -572,6 +593,9 @@ int main() {
|
||||||
#ifdef PANDA
|
#ifdef PANDA
|
||||||
spi_init();
|
spi_init();
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef DEBUG
|
||||||
|
puts("DEBUG ENABLED\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
// set PWM
|
// set PWM
|
||||||
fan_init();
|
fan_init();
|
||||||
|
@ -581,6 +605,8 @@ int main() {
|
||||||
|
|
||||||
__enable_irq();
|
__enable_irq();
|
||||||
|
|
||||||
|
power_save_init();
|
||||||
|
|
||||||
// if the error interrupt is enabled to quickly when the CAN bus is active
|
// if the error interrupt is enabled to quickly when the CAN bus is active
|
||||||
// something bad happens and you can't connect to the device over USB
|
// something bad happens and you can't connect to the device over USB
|
||||||
delay(10000000);
|
delay(10000000);
|
||||||
|
|
|
@ -295,6 +295,7 @@ int main() {
|
||||||
puts("**** INTERRUPTS ON ****\n");
|
puts("**** INTERRUPTS ON ****\n");
|
||||||
__enable_irq();
|
__enable_irq();
|
||||||
|
|
||||||
|
|
||||||
// main pedal loop
|
// main pedal loop
|
||||||
while (1) {
|
while (1) {
|
||||||
pedal();
|
pedal();
|
||||||
|
@ -302,4 +303,3 @@ int main() {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
#define POWER_SAVE_STATUS_DISABLED 0
|
||||||
|
//Moving to enabled, but can wakeup not yet enabled
|
||||||
|
#define POWER_SAVE_STATUS_SWITCHING 1
|
||||||
|
#define POWER_SAVE_STATUS_ENABLED 2
|
||||||
|
|
||||||
|
volatile int power_save_status = POWER_SAVE_STATUS_DISABLED;
|
||||||
|
|
||||||
|
void power_save_enable(void) {
|
||||||
|
power_save_status = POWER_SAVE_STATUS_SWITCHING;
|
||||||
|
puts("Saving power\n");
|
||||||
|
//Turn off can transciever
|
||||||
|
set_can_enable(CAN1, 0);
|
||||||
|
set_can_enable(CAN2, 0);
|
||||||
|
#ifdef PANDA
|
||||||
|
set_can_enable(CAN3, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Turn off GMLAN
|
||||||
|
set_gpio_output(GPIOB, 14, 0);
|
||||||
|
set_gpio_output(GPIOB, 15, 0);
|
||||||
|
|
||||||
|
#ifdef PANDA
|
||||||
|
//Turn off LIN K
|
||||||
|
if (revision == PANDA_REV_C) {
|
||||||
|
set_gpio_output(GPIOB, 7, 0); // REV C
|
||||||
|
} else {
|
||||||
|
set_gpio_output(GPIOB, 4, 0); // REV AB
|
||||||
|
}
|
||||||
|
// LIN L
|
||||||
|
set_gpio_output(GPIOA, 14, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (is_grey_panda) {
|
||||||
|
char* UBLOX_SLEEP_MSG = "\xb5\x62\x06\x04\x04\x00\x01\x00\x08\x00\x17\x78";
|
||||||
|
int len = 12;
|
||||||
|
uart_ring *ur = get_ring_by_number(1);
|
||||||
|
for (int i = 0; i < len; i++) while (!putc(ur, UBLOX_SLEEP_MSG[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Setup timer for can enable
|
||||||
|
TIM6->PSC = 48-1; // tick on 1 us
|
||||||
|
|
||||||
|
TIM6->ARR = 12; // 12us
|
||||||
|
// Enable, One-Pulse Mode, Only overflow interrupt
|
||||||
|
TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM | TIM_CR1_URS;
|
||||||
|
TIM6->EGR = TIM_EGR_UG;
|
||||||
|
TIM6->CR1 |= TIM_CR1_CEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void power_save_enable_can_wake(void) {
|
||||||
|
// CAN Automatic Wake must be done a little while after the sleep
|
||||||
|
// On some cars turning off the can transciver can trigger the wakeup
|
||||||
|
power_save_status = POWER_SAVE_STATUS_ENABLED;
|
||||||
|
puts("Turning can off\n");
|
||||||
|
CAN1->MCR |= CAN_MCR_SLEEP;
|
||||||
|
CAN1->MCR |= CAN_MCR_AWUM;
|
||||||
|
|
||||||
|
CAN2->MCR |= CAN_MCR_SLEEP;
|
||||||
|
CAN2->MCR |= CAN_MCR_AWUM;
|
||||||
|
#ifdef PANDA
|
||||||
|
CAN3->MCR |= CAN_MCR_SLEEP;
|
||||||
|
CAN3->MCR |= CAN_MCR_AWUM;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//set timer back
|
||||||
|
TIM6->PSC = 48000-1; // tick on 1 ms
|
||||||
|
TIM6->ARR = 10000; // 10s
|
||||||
|
// Enable, One-Pulse Mode, Only overflow interrupt
|
||||||
|
TIM6->CR1 = TIM_CR1_OPM | TIM_CR1_URS;
|
||||||
|
TIM6->EGR = TIM_EGR_UG;
|
||||||
|
}
|
||||||
|
|
||||||
|
void power_save_disable(void) {
|
||||||
|
power_save_status = POWER_SAVE_STATUS_DISABLED;
|
||||||
|
puts("not Saving power\n");
|
||||||
|
TIM6->CR1 |= TIM_CR1_CEN; //Restart timer
|
||||||
|
TIM6->CNT = 0;
|
||||||
|
|
||||||
|
//Turn on can
|
||||||
|
set_can_enable(CAN1, 1);
|
||||||
|
set_can_enable(CAN2, 1);
|
||||||
|
|
||||||
|
#ifdef PANDA
|
||||||
|
set_can_enable(CAN3, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Turn on GMLAN
|
||||||
|
set_gpio_output(GPIOB, 14, 1);
|
||||||
|
set_gpio_output(GPIOB, 15, 1);
|
||||||
|
|
||||||
|
#ifdef PANDA
|
||||||
|
//Turn on LIN K
|
||||||
|
if (revision == PANDA_REV_C) {
|
||||||
|
set_gpio_output(GPIOB, 7, 1); // REV C
|
||||||
|
} else {
|
||||||
|
set_gpio_output(GPIOB, 4, 1); // REV AB
|
||||||
|
}
|
||||||
|
// LIN L
|
||||||
|
set_gpio_output(GPIOA, 14, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (is_grey_panda) {
|
||||||
|
char* UBLOX_WAKE_MSG = "\xb5\x62\x06\x04\x04\x00\x01\x00\x09\x00\x18\x7a";
|
||||||
|
int len = 12;
|
||||||
|
uart_ring *ur = get_ring_by_number(1);
|
||||||
|
for (int i = 0; i < len; i++) while (!putc(ur, UBLOX_WAKE_MSG[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
//set timer back
|
||||||
|
TIM6->PSC = 48000-1; // tick on 1 ms
|
||||||
|
TIM6->ARR = 10000; // 10s
|
||||||
|
// Enable, One-Pulse Mode, Only overflow interrupt
|
||||||
|
TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM | TIM_CR1_URS;
|
||||||
|
TIM6->EGR = TIM_EGR_UG;
|
||||||
|
TIM6->CR1 |= TIM_CR1_CEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Reset timer when activity
|
||||||
|
void power_save_reset_timer() {
|
||||||
|
TIM6->CNT = 0;
|
||||||
|
if (power_save_status != POWER_SAVE_STATUS_DISABLED){
|
||||||
|
power_save_disable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void power_save_init(void) {
|
||||||
|
puts("Saving power init\n");
|
||||||
|
TIM6->PSC = 48000-1; // tick on 1 ms
|
||||||
|
|
||||||
|
|
||||||
|
TIM6->ARR = 10000; // 10s
|
||||||
|
// Enable, One-Pulse Mode, Only overflow interrupt
|
||||||
|
TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM | TIM_CR1_URS;
|
||||||
|
TIM6->EGR = TIM_EGR_UG;
|
||||||
|
NVIC_EnableIRQ(TIM6_DAC_IRQn);
|
||||||
|
puts("Saving power init done\n");
|
||||||
|
TIM6->DIER = TIM_DIER_UIE;
|
||||||
|
TIM6->CR1 |= TIM_CR1_CEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TIM6_DAC_IRQHandler(void) {
|
||||||
|
//Timeout switch to power saving mode.
|
||||||
|
if (TIM6->SR & TIM_SR_UIF) {
|
||||||
|
TIM6->SR = 0;
|
||||||
|
#ifdef EON
|
||||||
|
if (power_save_status == POWER_SAVE_STATUS_DISABLED) {
|
||||||
|
power_save_enable();
|
||||||
|
} else if (power_save_status == POWER_SAVE_STATUS_SWITCHING) {
|
||||||
|
power_save_enable_can_wake();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
TIM6->CR1 |= TIM_CR1_CEN;
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,10 @@ int driver_limit_check(int val, int val_last, struct sample_t *val_driver,
|
||||||
int rt_rate_limit_check(int val, int val_last, const int MAX_RT_DELTA);
|
int rt_rate_limit_check(int val, int val_last, const int MAX_RT_DELTA);
|
||||||
#ifdef PANDA
|
#ifdef PANDA
|
||||||
float interpolate(struct lookup_t xy, float x);
|
float interpolate(struct lookup_t xy, float x);
|
||||||
|
|
||||||
|
void lline_relay_init (void);
|
||||||
|
void lline_relay_release (void);
|
||||||
|
void set_lline_output(int to_set);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef void (*safety_hook_init)(int16_t param);
|
typedef void (*safety_hook_init)(int16_t param);
|
||||||
|
@ -37,6 +41,7 @@ typedef int (*tx_hook)(CAN_FIFOMailBox_TypeDef *to_send);
|
||||||
typedef int (*tx_lin_hook)(int lin_num, uint8_t *data, int len);
|
typedef int (*tx_lin_hook)(int lin_num, uint8_t *data, int len);
|
||||||
typedef int (*ign_hook)();
|
typedef int (*ign_hook)();
|
||||||
typedef int (*fwd_hook)(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd);
|
typedef int (*fwd_hook)(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd);
|
||||||
|
typedef int (*relay_hook)();
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
safety_hook_init init;
|
safety_hook_init init;
|
||||||
|
@ -45,6 +50,7 @@ typedef struct {
|
||||||
tx_hook tx;
|
tx_hook tx;
|
||||||
tx_lin_hook tx_lin;
|
tx_lin_hook tx_lin;
|
||||||
fwd_hook fwd;
|
fwd_hook fwd;
|
||||||
|
relay_hook relay;
|
||||||
} safety_hooks;
|
} safety_hooks;
|
||||||
|
|
||||||
// This can be set by the safety hooks.
|
// This can be set by the safety hooks.
|
||||||
|
@ -91,6 +97,10 @@ int safety_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||||
return current_hooks->fwd(bus_num, to_fwd);
|
return current_hooks->fwd(bus_num, to_fwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int safety_relay_hook(void) {
|
||||||
|
return current_hooks->relay();
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t id;
|
uint16_t id;
|
||||||
const safety_hooks *hooks;
|
const safety_hooks *hooks;
|
||||||
|
|
|
@ -115,6 +115,9 @@ static int cadillac_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||||
static void cadillac_init(int16_t param) {
|
static void cadillac_init(int16_t param) {
|
||||||
controls_allowed = 0;
|
controls_allowed = 0;
|
||||||
cadillac_ign = 0;
|
cadillac_ign = 0;
|
||||||
|
#ifdef PANDA
|
||||||
|
lline_relay_release();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cadillac_ign_hook() {
|
static int cadillac_ign_hook() {
|
||||||
|
@ -128,4 +131,5 @@ const safety_hooks cadillac_hooks = {
|
||||||
.tx_lin = nooutput_tx_lin_hook,
|
.tx_lin = nooutput_tx_lin_hook,
|
||||||
.ignition = cadillac_ign_hook,
|
.ignition = cadillac_ign_hook,
|
||||||
.fwd = alloutput_fwd_hook,
|
.fwd = alloutput_fwd_hook,
|
||||||
|
.relay = nooutput_relay_hook,
|
||||||
};
|
};
|
||||||
|
|
|
@ -127,6 +127,9 @@ static int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||||
|
|
||||||
static void chrysler_init(int16_t param) {
|
static void chrysler_init(int16_t param) {
|
||||||
chrysler_camera_detected = 0;
|
chrysler_camera_detected = 0;
|
||||||
|
#ifdef PANDA
|
||||||
|
lline_relay_release();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int chrysler_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
static int chrysler_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||||
|
@ -150,4 +153,5 @@ const safety_hooks chrysler_hooks = {
|
||||||
.tx_lin = nooutput_tx_lin_hook,
|
.tx_lin = nooutput_tx_lin_hook,
|
||||||
.ignition = default_ign_hook,
|
.ignition = default_ign_hook,
|
||||||
.fwd = chrysler_fwd_hook,
|
.fwd = chrysler_fwd_hook,
|
||||||
|
.relay = nooutput_relay_hook,
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,6 +8,9 @@ int default_ign_hook() {
|
||||||
|
|
||||||
static void nooutput_init(int16_t param) {
|
static void nooutput_init(int16_t param) {
|
||||||
controls_allowed = 0;
|
controls_allowed = 0;
|
||||||
|
#ifdef PANDA
|
||||||
|
lline_relay_release();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nooutput_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
static int nooutput_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||||
|
@ -22,6 +25,10 @@ static int nooutput_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nooutput_relay_hook(int to_set) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const safety_hooks nooutput_hooks = {
|
const safety_hooks nooutput_hooks = {
|
||||||
.init = nooutput_init,
|
.init = nooutput_init,
|
||||||
.rx = default_rx_hook,
|
.rx = default_rx_hook,
|
||||||
|
@ -29,12 +36,16 @@ const safety_hooks nooutput_hooks = {
|
||||||
.tx_lin = nooutput_tx_lin_hook,
|
.tx_lin = nooutput_tx_lin_hook,
|
||||||
.ignition = default_ign_hook,
|
.ignition = default_ign_hook,
|
||||||
.fwd = nooutput_fwd_hook,
|
.fwd = nooutput_fwd_hook,
|
||||||
|
.relay = nooutput_relay_hook,
|
||||||
};
|
};
|
||||||
|
|
||||||
// *** all output safety mode ***
|
// *** all output safety mode ***
|
||||||
|
|
||||||
static void alloutput_init(int16_t param) {
|
static void alloutput_init(int16_t param) {
|
||||||
controls_allowed = 1;
|
controls_allowed = 1;
|
||||||
|
#ifdef PANDA
|
||||||
|
lline_relay_release();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int alloutput_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
static int alloutput_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||||
|
@ -49,6 +60,10 @@ static int alloutput_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int alloutput_relay_hook(int to_set) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const safety_hooks alloutput_hooks = {
|
const safety_hooks alloutput_hooks = {
|
||||||
.init = alloutput_init,
|
.init = alloutput_init,
|
||||||
.rx = default_rx_hook,
|
.rx = default_rx_hook,
|
||||||
|
@ -56,4 +71,5 @@ const safety_hooks alloutput_hooks = {
|
||||||
.tx_lin = alloutput_tx_lin_hook,
|
.tx_lin = alloutput_tx_lin_hook,
|
||||||
.ignition = default_ign_hook,
|
.ignition = default_ign_hook,
|
||||||
.fwd = alloutput_fwd_hook,
|
.fwd = alloutput_fwd_hook,
|
||||||
|
.relay = alloutput_relay_hook,
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,4 +42,5 @@ const safety_hooks elm327_hooks = {
|
||||||
.tx_lin = elm327_tx_lin_hook,
|
.tx_lin = elm327_tx_lin_hook,
|
||||||
.ignition = default_ign_hook,
|
.ignition = default_ign_hook,
|
||||||
.fwd = elm327_fwd_hook,
|
.fwd = elm327_fwd_hook,
|
||||||
|
.relay = nooutput_relay_hook,
|
||||||
};
|
};
|
||||||
|
|
|
@ -90,4 +90,5 @@ const safety_hooks ford_hooks = {
|
||||||
.tx_lin = nooutput_tx_lin_hook,
|
.tx_lin = nooutput_tx_lin_hook,
|
||||||
.ignition = default_ign_hook,
|
.ignition = default_ign_hook,
|
||||||
.fwd = nooutput_fwd_hook,
|
.fwd = nooutput_fwd_hook,
|
||||||
|
.relay = nooutput_relay_hook,
|
||||||
};
|
};
|
||||||
|
|
|
@ -228,6 +228,9 @@ static int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) {
|
||||||
static void gm_init(int16_t param) {
|
static void gm_init(int16_t param) {
|
||||||
controls_allowed = 0;
|
controls_allowed = 0;
|
||||||
gm_ignition_started = 0;
|
gm_ignition_started = 0;
|
||||||
|
#ifdef PANDA
|
||||||
|
lline_relay_release();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gm_ign_hook() {
|
static int gm_ign_hook() {
|
||||||
|
@ -241,5 +244,5 @@ const safety_hooks gm_hooks = {
|
||||||
.tx_lin = nooutput_tx_lin_hook,
|
.tx_lin = nooutput_tx_lin_hook,
|
||||||
.ignition = gm_ign_hook,
|
.ignition = gm_ign_hook,
|
||||||
.fwd = nooutput_fwd_hook,
|
.fwd = nooutput_fwd_hook,
|
||||||
|
.relay = nooutput_relay_hook,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -48,5 +48,6 @@ const safety_hooks gm_ascm_hooks = {
|
||||||
.tx_lin = nooutput_tx_lin_hook,
|
.tx_lin = nooutput_tx_lin_hook,
|
||||||
.ignition = default_ign_hook,
|
.ignition = default_ign_hook,
|
||||||
.fwd = gm_ascm_fwd_hook,
|
.fwd = gm_ascm_fwd_hook,
|
||||||
|
.relay = nooutput_relay_hook,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -136,6 +136,9 @@ static void honda_init(int16_t param) {
|
||||||
controls_allowed = 0;
|
controls_allowed = 0;
|
||||||
bosch_hardware = false;
|
bosch_hardware = false;
|
||||||
honda_alt_brake_msg = false;
|
honda_alt_brake_msg = false;
|
||||||
|
#ifdef PANDA
|
||||||
|
lline_relay_release();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void honda_bosch_init(int16_t param) {
|
static void honda_bosch_init(int16_t param) {
|
||||||
|
@ -143,6 +146,9 @@ static void honda_bosch_init(int16_t param) {
|
||||||
bosch_hardware = true;
|
bosch_hardware = true;
|
||||||
// Checking for alternate brake override from safety parameter
|
// Checking for alternate brake override from safety parameter
|
||||||
honda_alt_brake_msg = param == 1 ? true : false;
|
honda_alt_brake_msg = param == 1 ? true : false;
|
||||||
|
#ifdef PANDA
|
||||||
|
lline_relay_release();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int honda_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
static int honda_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||||
|
@ -176,6 +182,7 @@ const safety_hooks honda_hooks = {
|
||||||
.tx_lin = nooutput_tx_lin_hook,
|
.tx_lin = nooutput_tx_lin_hook,
|
||||||
.ignition = default_ign_hook,
|
.ignition = default_ign_hook,
|
||||||
.fwd = honda_fwd_hook,
|
.fwd = honda_fwd_hook,
|
||||||
|
.relay = nooutput_relay_hook,
|
||||||
};
|
};
|
||||||
|
|
||||||
const safety_hooks honda_bosch_hooks = {
|
const safety_hooks honda_bosch_hooks = {
|
||||||
|
@ -185,4 +192,5 @@ const safety_hooks honda_bosch_hooks = {
|
||||||
.tx_lin = nooutput_tx_lin_hook,
|
.tx_lin = nooutput_tx_lin_hook,
|
||||||
.ignition = default_ign_hook,
|
.ignition = default_ign_hook,
|
||||||
.fwd = honda_bosch_fwd_hook,
|
.fwd = honda_bosch_fwd_hook,
|
||||||
|
.relay = nooutput_relay_hook,
|
||||||
};
|
};
|
||||||
|
|
|
@ -152,6 +152,9 @@ static int hyundai_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||||
static void hyundai_init(int16_t param) {
|
static void hyundai_init(int16_t param) {
|
||||||
controls_allowed = 0;
|
controls_allowed = 0;
|
||||||
hyundai_giraffe_switch_2 = 0;
|
hyundai_giraffe_switch_2 = 0;
|
||||||
|
#ifdef PANDA
|
||||||
|
lline_relay_release();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const safety_hooks hyundai_hooks = {
|
const safety_hooks hyundai_hooks = {
|
||||||
|
@ -161,4 +164,5 @@ const safety_hooks hyundai_hooks = {
|
||||||
.tx_lin = nooutput_tx_lin_hook,
|
.tx_lin = nooutput_tx_lin_hook,
|
||||||
.ignition = default_ign_hook,
|
.ignition = default_ign_hook,
|
||||||
.fwd = hyundai_fwd_hook,
|
.fwd = hyundai_fwd_hook,
|
||||||
|
.relay = nooutput_relay_hook,
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,6 +14,11 @@ int subaru_desired_torque_last = 0;
|
||||||
uint32_t subaru_ts_last = 0;
|
uint32_t subaru_ts_last = 0;
|
||||||
struct sample_t subaru_torque_driver; // last few driver torques measured
|
struct sample_t subaru_torque_driver; // last few driver torques measured
|
||||||
|
|
||||||
|
static void subaru_init(int16_t param) {
|
||||||
|
#ifdef PANDA
|
||||||
|
lline_relay_init();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void subaru_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
|
static void subaru_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
|
||||||
int bus_number = (to_push->RDTR >> 4) & 0xFF;
|
int bus_number = (to_push->RDTR >> 4) & 0xFF;
|
||||||
|
@ -100,6 +105,7 @@ static int subaru_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||||
|
|
||||||
// forward CAN 0 > 1
|
// forward CAN 0 > 1
|
||||||
if (bus_num == 0) {
|
if (bus_num == 0) {
|
||||||
|
|
||||||
return 2; // ES CAN
|
return 2; // ES CAN
|
||||||
}
|
}
|
||||||
// forward CAN 1 > 0, except ES_LKAS
|
// forward CAN 1 > 0, except ES_LKAS
|
||||||
|
@ -113,6 +119,10 @@ static int subaru_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||||
if (addr == 0x122) {
|
if (addr == 0x122) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
// ES Distance
|
||||||
|
if (addr == 545) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0; // Main CAN
|
return 0; // Main CAN
|
||||||
}
|
}
|
||||||
|
@ -122,10 +132,11 @@ static int subaru_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const safety_hooks subaru_hooks = {
|
const safety_hooks subaru_hooks = {
|
||||||
.init = nooutput_init,
|
.init = subaru_init,
|
||||||
.rx = subaru_rx_hook,
|
.rx = subaru_rx_hook,
|
||||||
.tx = subaru_tx_hook,
|
.tx = subaru_tx_hook,
|
||||||
.tx_lin = nooutput_tx_lin_hook,
|
.tx_lin = nooutput_tx_lin_hook,
|
||||||
.ignition = default_ign_hook,
|
.ignition = default_ign_hook,
|
||||||
.fwd = subaru_fwd_hook,
|
.fwd = subaru_fwd_hook,
|
||||||
|
.relay = alloutput_relay_hook,
|
||||||
};
|
};
|
||||||
|
|
|
@ -230,6 +230,9 @@ static void tesla_init(int16_t param)
|
||||||
controls_allowed = 0;
|
controls_allowed = 0;
|
||||||
tesla_ignition_started = 0;
|
tesla_ignition_started = 0;
|
||||||
gmlan_switch_init(1); //init the gmlan switch with 1s timeout enabled
|
gmlan_switch_init(1); //init the gmlan switch with 1s timeout enabled
|
||||||
|
#ifdef PANDA
|
||||||
|
lline_relay_release();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tesla_ign_hook()
|
static int tesla_ign_hook()
|
||||||
|
@ -284,4 +287,5 @@ const safety_hooks tesla_hooks = {
|
||||||
.tx_lin = tesla_tx_lin_hook,
|
.tx_lin = tesla_tx_lin_hook,
|
||||||
.ignition = tesla_ign_hook,
|
.ignition = tesla_ign_hook,
|
||||||
.fwd = tesla_fwd_hook,
|
.fwd = tesla_fwd_hook,
|
||||||
|
.relay = nooutput_relay_hook,
|
||||||
};
|
};
|
||||||
|
|
|
@ -160,6 +160,9 @@ static void toyota_init(int16_t param) {
|
||||||
toyota_giraffe_switch_1 = 0;
|
toyota_giraffe_switch_1 = 0;
|
||||||
toyota_camera_forwarded = 0;
|
toyota_camera_forwarded = 0;
|
||||||
toyota_dbc_eps_torque_factor = param;
|
toyota_dbc_eps_torque_factor = param;
|
||||||
|
#ifdef PANDA
|
||||||
|
lline_relay_release();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int toyota_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
static int toyota_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) {
|
||||||
|
@ -181,6 +184,7 @@ const safety_hooks toyota_hooks = {
|
||||||
.tx_lin = nooutput_tx_lin_hook,
|
.tx_lin = nooutput_tx_lin_hook,
|
||||||
.ignition = default_ign_hook,
|
.ignition = default_ign_hook,
|
||||||
.fwd = toyota_fwd_hook,
|
.fwd = toyota_fwd_hook,
|
||||||
|
.relay = nooutput_relay_hook,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void toyota_nolimits_init(int16_t param) {
|
static void toyota_nolimits_init(int16_t param) {
|
||||||
|
@ -189,6 +193,9 @@ static void toyota_nolimits_init(int16_t param) {
|
||||||
toyota_giraffe_switch_1 = 0;
|
toyota_giraffe_switch_1 = 0;
|
||||||
toyota_camera_forwarded = 0;
|
toyota_camera_forwarded = 0;
|
||||||
toyota_dbc_eps_torque_factor = param;
|
toyota_dbc_eps_torque_factor = param;
|
||||||
|
#ifdef PANDA
|
||||||
|
lline_relay_release();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const safety_hooks toyota_nolimits_hooks = {
|
const safety_hooks toyota_nolimits_hooks = {
|
||||||
|
@ -198,4 +205,5 @@ const safety_hooks toyota_nolimits_hooks = {
|
||||||
.tx_lin = nooutput_tx_lin_hook,
|
.tx_lin = nooutput_tx_lin_hook,
|
||||||
.ignition = default_ign_hook,
|
.ignition = default_ign_hook,
|
||||||
.fwd = toyota_fwd_hook,
|
.fwd = toyota_fwd_hook,
|
||||||
|
.relay = nooutput_relay_hook,
|
||||||
};
|
};
|
||||||
|
|
|
@ -152,5 +152,5 @@ const safety_hooks toyota_ipas_hooks = {
|
||||||
.tx_lin = nooutput_tx_lin_hook,
|
.tx_lin = nooutput_tx_lin_hook,
|
||||||
.ignition = default_ign_hook,
|
.ignition = default_ign_hook,
|
||||||
.fwd = toyota_fwd_hook,
|
.fwd = toyota_fwd_hook,
|
||||||
|
.relay = nooutput_relay_hook,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
git clone --recursive https://github.com/pfalcon/esp-open-sdk.git
|
||||||
|
cd esp-open-sdk
|
||||||
|
git checkout 03f5e898a059451ec5f3de30e7feff30455f7cec
|
||||||
|
LD_LIBRARY_PATH="" make STANDALONE=y
|
|
@ -182,6 +182,7 @@ class Panda(object):
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
if wait == False or self._handle != None:
|
if wait == False or self._handle != None:
|
||||||
break
|
break
|
||||||
|
context = usb1.USBContext() #New context needed so new devices show up
|
||||||
assert(self._handle != None)
|
assert(self._handle != None)
|
||||||
print("connected")
|
print("connected")
|
||||||
|
|
||||||
|
@ -280,11 +281,14 @@ class Panda(object):
|
||||||
if reconnect:
|
if reconnect:
|
||||||
self.reconnect()
|
self.reconnect()
|
||||||
|
|
||||||
def recover(self):
|
def recover(self, timeout=None):
|
||||||
self.reset(enter_bootloader=True)
|
self.reset(enter_bootloader=True)
|
||||||
|
t_start = time.time()
|
||||||
while len(PandaDFU.list()) == 0:
|
while len(PandaDFU.list()) == 0:
|
||||||
print("waiting for DFU...")
|
print("waiting for DFU...")
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
if timeout is not None and (time.time() - t_start) > timeout:
|
||||||
|
return False
|
||||||
|
|
||||||
dfu = PandaDFU(PandaDFU.st_serial_to_dfu_serial(self._serial))
|
dfu = PandaDFU(PandaDFU.st_serial_to_dfu_serial(self._serial))
|
||||||
dfu.recover()
|
dfu.recover()
|
||||||
|
@ -292,6 +296,7 @@ class Panda(object):
|
||||||
# reflash after recover
|
# reflash after recover
|
||||||
self.connect(True, True)
|
self.connect(True, True)
|
||||||
self.flash()
|
self.flash()
|
||||||
|
return True
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def flash_ota_st():
|
def flash_ota_st():
|
||||||
|
@ -300,8 +305,9 @@ class Panda(object):
|
||||||
return ret==0
|
return ret==0
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def flash_ota_wifi():
|
def flash_ota_wifi(release=False):
|
||||||
ret = os.system("cd %s && make clean && make ota" % (os.path.join(BASEDIR, "boardesp")))
|
release_str = "RELEASE=1" if release else ""
|
||||||
|
ret = os.system("cd {} && make clean && {} make ota".format(os.path.join(BASEDIR, "boardesp"),release_str))
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
return ret==0
|
return ret==0
|
||||||
|
|
||||||
|
@ -386,10 +392,17 @@ class Panda(object):
|
||||||
elif bus in [Panda.GMLAN_CAN2, Panda.GMLAN_CAN3]:
|
elif bus in [Panda.GMLAN_CAN2, Panda.GMLAN_CAN3]:
|
||||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xdb, 1, bus, b'')
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xdb, 1, bus, b'')
|
||||||
|
|
||||||
|
def set_lline_relay(self, enable):
|
||||||
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf3, int(enable), 0, b'')
|
||||||
|
|
||||||
def set_can_loopback(self, enable):
|
def set_can_loopback(self, enable):
|
||||||
# set can loopback mode for all buses
|
# set can loopback mode for all buses
|
||||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe5, int(enable), 0, b'')
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xe5, int(enable), 0, b'')
|
||||||
|
|
||||||
|
def set_can_enable(self, bus_num, enable):
|
||||||
|
# sets the can transciever enable pin
|
||||||
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xf4, int(bus_num), int(enable), b'')
|
||||||
|
|
||||||
def set_can_speed_kbps(self, bus, speed):
|
def set_can_speed_kbps(self, bus, speed):
|
||||||
self._handle.controlWrite(Panda.REQUEST_OUT, 0xde, bus, int(speed*10), b'')
|
self._handle.controlWrite(Panda.REQUEST_OUT, 0xde, bus, int(speed*10), b'')
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
libusb1
|
libusb1 == 1.6.6
|
||||||
hexdump
|
hexdump
|
||||||
pycrypto
|
pycrypto
|
||||||
tqdm
|
tqdm
|
||||||
|
nose
|
||||||
|
parameterized
|
||||||
|
requests
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
PYTHONPATH="." nosetests -x -s tests/automated/$1*.py
|
TEST_FILENAME=${TEST_FILENAME:-nosetests.xml}
|
||||||
|
if [ ! -f "/EON" ]; then
|
||||||
|
TESTSUITE_NAME="Panda_Test-EON"
|
||||||
|
else
|
||||||
|
TESTSUITE_NAME="Panda_Test-DEV"
|
||||||
|
fi
|
||||||
|
|
||||||
|
PYTHONPATH="." nosetests -v --with-xunit --xunit-file=./$TEST_FILENAME --xunit-testsuite-name=$TESTSUITE_NAME -s tests/automated/$1*.py
|
||||||
|
|
|
@ -46,7 +46,7 @@ setup(
|
||||||
platforms='any',
|
platforms='any',
|
||||||
license='MIT',
|
license='MIT',
|
||||||
install_requires=[
|
install_requires=[
|
||||||
'libusb1 >= 1.6.4',
|
'libusb1 == 1.6.6',
|
||||||
'hexdump >= 3.3',
|
'hexdump >= 3.3',
|
||||||
'pycrypto >= 2.6.1',
|
'pycrypto >= 2.6.1',
|
||||||
'tqdm >= 4.14.0',
|
'tqdm >= 4.14.0',
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
import os
|
import os
|
||||||
from panda import Panda
|
from panda import Panda
|
||||||
|
from helpers import panda_color_to_serial, test_white_and_grey
|
||||||
|
|
||||||
def test_recover():
|
@test_white_and_grey
|
||||||
p = Panda()
|
@panda_color_to_serial
|
||||||
p.recover()
|
def test_recover(serial=None):
|
||||||
|
p = Panda(serial=serial)
|
||||||
|
assert p.recover(timeout=30)
|
||||||
|
|
||||||
def test_flash():
|
@test_white_and_grey
|
||||||
p = Panda()
|
@panda_color_to_serial
|
||||||
|
def test_flash(serial=None):
|
||||||
|
p = Panda(serial=serial)
|
||||||
p.flash()
|
p.flash()
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,16 @@ import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
from panda import Panda
|
from panda import Panda
|
||||||
from nose.tools import timed, assert_equal, assert_less, assert_greater
|
from nose.tools import assert_equal, assert_less, assert_greater
|
||||||
from helpers import time_many_sends, connect_wo_esp
|
from helpers import time_many_sends, connect_wo_esp, test_white_and_grey, panda_color_to_serial
|
||||||
|
|
||||||
SPEED_NORMAL = 500
|
SPEED_NORMAL = 500
|
||||||
SPEED_GMLAN = 33.3
|
SPEED_GMLAN = 33.3
|
||||||
|
|
||||||
def test_can_loopback():
|
@test_white_and_grey
|
||||||
p = connect_wo_esp()
|
@panda_color_to_serial
|
||||||
|
def test_can_loopback(serial=None):
|
||||||
|
p = connect_wo_esp(serial)
|
||||||
|
|
||||||
# enable output mode
|
# enable output mode
|
||||||
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||||
|
@ -42,8 +44,10 @@ def test_can_loopback():
|
||||||
assert 0x1aa == sr[0][0] == lb[0][0]
|
assert 0x1aa == sr[0][0] == lb[0][0]
|
||||||
assert "message" == sr[0][2] == lb[0][2]
|
assert "message" == sr[0][2] == lb[0][2]
|
||||||
|
|
||||||
def test_safety_nooutput():
|
@test_white_and_grey
|
||||||
p = connect_wo_esp()
|
@panda_color_to_serial
|
||||||
|
def test_safety_nooutput(serial=None):
|
||||||
|
p = connect_wo_esp(serial)
|
||||||
|
|
||||||
# enable output mode
|
# enable output mode
|
||||||
p.set_safety_mode(Panda.SAFETY_NOOUTPUT)
|
p.set_safety_mode(Panda.SAFETY_NOOUTPUT)
|
||||||
|
@ -59,8 +63,10 @@ def test_safety_nooutput():
|
||||||
r = p.can_recv()
|
r = p.can_recv()
|
||||||
assert len(r) == 0
|
assert len(r) == 0
|
||||||
|
|
||||||
def test_reliability():
|
@test_white_and_grey
|
||||||
p = connect_wo_esp()
|
@panda_color_to_serial
|
||||||
|
def test_reliability(serial=None):
|
||||||
|
p = connect_wo_esp(serial)
|
||||||
|
|
||||||
LOOP_COUNT = 100
|
LOOP_COUNT = 100
|
||||||
MSG_COUNT = 100
|
MSG_COUNT = 100
|
||||||
|
@ -97,8 +103,10 @@ def test_reliability():
|
||||||
sys.stdout.write("P")
|
sys.stdout.write("P")
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
def test_throughput():
|
@test_white_and_grey
|
||||||
p = connect_wo_esp()
|
@panda_color_to_serial
|
||||||
|
def test_throughput(serial=None):
|
||||||
|
p = connect_wo_esp(serial)
|
||||||
|
|
||||||
# enable output mode
|
# enable output mode
|
||||||
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||||
|
@ -120,8 +128,10 @@ def test_throughput():
|
||||||
|
|
||||||
print("loopback 100 messages at speed %d, comp speed is %.2f, percent %.2f" % (speed, comp_kbps, saturation_pct))
|
print("loopback 100 messages at speed %d, comp speed is %.2f, percent %.2f" % (speed, comp_kbps, saturation_pct))
|
||||||
|
|
||||||
def test_gmlan():
|
@test_white_and_grey
|
||||||
p = connect_wo_esp()
|
@panda_color_to_serial
|
||||||
|
def test_gmlan(serial=None):
|
||||||
|
p = connect_wo_esp(serial)
|
||||||
|
|
||||||
if p.legacy:
|
if p.legacy:
|
||||||
return
|
return
|
||||||
|
@ -135,7 +145,7 @@ def test_gmlan():
|
||||||
p.set_can_speed_kbps(1, SPEED_NORMAL)
|
p.set_can_speed_kbps(1, SPEED_NORMAL)
|
||||||
p.set_can_speed_kbps(2, SPEED_NORMAL)
|
p.set_can_speed_kbps(2, SPEED_NORMAL)
|
||||||
p.set_can_speed_kbps(3, SPEED_GMLAN)
|
p.set_can_speed_kbps(3, SPEED_GMLAN)
|
||||||
|
|
||||||
# set gmlan on CAN2
|
# set gmlan on CAN2
|
||||||
for bus in [Panda.GMLAN_CAN2, Panda.GMLAN_CAN3, Panda.GMLAN_CAN2, Panda.GMLAN_CAN3]:
|
for bus in [Panda.GMLAN_CAN2, Panda.GMLAN_CAN3, Panda.GMLAN_CAN2, Panda.GMLAN_CAN3]:
|
||||||
p.set_gmlan(bus)
|
p.set_gmlan(bus)
|
||||||
|
@ -150,8 +160,10 @@ def test_gmlan():
|
||||||
|
|
||||||
print("%d: %.2f kbps vs %.2f kbps" % (bus, comp_kbps_gmlan, comp_kbps_normal))
|
print("%d: %.2f kbps vs %.2f kbps" % (bus, comp_kbps_gmlan, comp_kbps_normal))
|
||||||
|
|
||||||
def test_gmlan_bad_toggle():
|
@test_white_and_grey
|
||||||
p = connect_wo_esp()
|
@panda_color_to_serial
|
||||||
|
def test_gmlan_bad_toggle(serial=None):
|
||||||
|
p = connect_wo_esp(serial)
|
||||||
|
|
||||||
if p.legacy:
|
if p.legacy:
|
||||||
return
|
return
|
||||||
|
@ -178,9 +190,10 @@ def test_gmlan_bad_toggle():
|
||||||
|
|
||||||
|
|
||||||
# this will fail if you have hardware serial connected
|
# this will fail if you have hardware serial connected
|
||||||
def test_serial_debug():
|
@test_white_and_grey
|
||||||
p = connect_wo_esp()
|
@panda_color_to_serial
|
||||||
|
def test_serial_debug(serial=None):
|
||||||
|
p = connect_wo_esp(serial)
|
||||||
junk = p.serial_read(Panda.SERIAL_DEBUG)
|
junk = p.serial_read(Panda.SERIAL_DEBUG)
|
||||||
p.call_control_api(0xc0)
|
p.call_control_api(0xc0)
|
||||||
assert(p.serial_read(Panda.SERIAL_DEBUG).startswith("can "))
|
assert(p.serial_read(Panda.SERIAL_DEBUG).startswith("can "))
|
||||||
|
|
||||||
|
|
|
@ -1,33 +1,60 @@
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
from panda import Panda
|
from panda import Panda
|
||||||
from helpers import connect_wifi
|
from helpers import connect_wifi, test_white, test_white_and_grey, panda_color_to_serial
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
def test_get_serial():
|
@test_white_and_grey
|
||||||
p = Panda()
|
@panda_color_to_serial
|
||||||
|
def test_get_serial(serial=None):
|
||||||
|
p = Panda(serial)
|
||||||
print(p.get_serial())
|
print(p.get_serial())
|
||||||
|
|
||||||
def test_get_serial_in_flash_mode():
|
@test_white_and_grey
|
||||||
p = Panda()
|
@panda_color_to_serial
|
||||||
|
def test_get_serial_in_flash_mode(serial=None):
|
||||||
|
p = Panda(serial)
|
||||||
p.reset(enter_bootstub=True)
|
p.reset(enter_bootstub=True)
|
||||||
assert(p.bootstub)
|
assert(p.bootstub)
|
||||||
print(p.get_serial())
|
print(p.get_serial())
|
||||||
p.reset()
|
p.reset()
|
||||||
|
|
||||||
def test_connect_wifi():
|
@test_white
|
||||||
connect_wifi()
|
@panda_color_to_serial
|
||||||
|
def test_connect_wifi(serial=None):
|
||||||
|
connect_wifi(serial)
|
||||||
|
|
||||||
def test_flash_wifi():
|
@test_white
|
||||||
Panda.flash_ota_wifi()
|
@panda_color_to_serial
|
||||||
connect_wifi()
|
def test_flash_wifi(serial=None):
|
||||||
|
connect_wifi(serial)
|
||||||
|
assert Panda.flash_ota_wifi(release=True), "OTA Wifi Flash Failed"
|
||||||
|
connect_wifi(serial)
|
||||||
|
|
||||||
def test_wifi_flash_st():
|
@test_white
|
||||||
Panda.flash_ota_st()
|
@panda_color_to_serial
|
||||||
|
def test_wifi_flash_st(serial=None):
|
||||||
|
connect_wifi(serial)
|
||||||
|
assert Panda.flash_ota_st(), "OTA ST Flash Failed"
|
||||||
|
connected = False
|
||||||
|
st = time.time()
|
||||||
|
while not connected and (time.time() - st) < 20:
|
||||||
|
try:
|
||||||
|
p = Panda(serial=serial)
|
||||||
|
p.get_serial()
|
||||||
|
connected = True
|
||||||
|
except:
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
def test_webpage_fetch():
|
if not connected:
|
||||||
|
assert False, "Panda failed to connect on USB after flashing"
|
||||||
|
|
||||||
|
@test_white
|
||||||
|
@panda_color_to_serial
|
||||||
|
def test_webpage_fetch(serial=None):
|
||||||
|
connect_wifi(serial)
|
||||||
r = requests.get("http://192.168.0.10/")
|
r = requests.get("http://192.168.0.10/")
|
||||||
print(r.text)
|
print(r.text)
|
||||||
|
|
||||||
assert "This is your comma.ai panda" in r.text
|
assert "This is your comma.ai panda" in r.text
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import time
|
import time
|
||||||
from panda import Panda
|
from panda import Panda
|
||||||
from helpers import time_many_sends, connect_wifi
|
from helpers import time_many_sends, connect_wifi, test_white, panda_color_to_serial
|
||||||
from nose.tools import timed, assert_equal, assert_less, assert_greater
|
from nose.tools import timed, assert_equal, assert_less, assert_greater
|
||||||
|
|
||||||
def test_get_serial_wifi():
|
@test_white
|
||||||
connect_wifi()
|
@panda_color_to_serial
|
||||||
|
def test_get_serial_wifi(serial=None):
|
||||||
|
connect_wifi(serial)
|
||||||
|
|
||||||
p = Panda("WIFI")
|
p = Panda("WIFI")
|
||||||
print(p.get_serial())
|
print(p.get_serial())
|
||||||
|
|
||||||
def test_throughput():
|
@test_white
|
||||||
p = Panda()
|
@panda_color_to_serial
|
||||||
|
def test_throughput(serial=None):
|
||||||
|
connect_wifi(serial)
|
||||||
|
p = Panda(serial)
|
||||||
|
|
||||||
# enable output mode
|
# enable output mode
|
||||||
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||||
|
@ -24,7 +29,7 @@ def test_throughput():
|
||||||
for speed in [100,250,500,750,1000]:
|
for speed in [100,250,500,750,1000]:
|
||||||
# set bus 0 speed to speed
|
# set bus 0 speed to speed
|
||||||
p.set_can_speed_kbps(0, speed)
|
p.set_can_speed_kbps(0, speed)
|
||||||
time.sleep(0.05)
|
time.sleep(0.1)
|
||||||
|
|
||||||
comp_kbps = time_many_sends(p, 0)
|
comp_kbps = time_many_sends(p, 0)
|
||||||
|
|
||||||
|
@ -35,8 +40,11 @@ def test_throughput():
|
||||||
|
|
||||||
print("WIFI loopback 100 messages at speed %d, comp speed is %.2f, percent %.2f" % (speed, comp_kbps, saturation_pct))
|
print("WIFI loopback 100 messages at speed %d, comp speed is %.2f, percent %.2f" % (speed, comp_kbps, saturation_pct))
|
||||||
|
|
||||||
def test_recv_only():
|
@test_white
|
||||||
p = Panda()
|
@panda_color_to_serial
|
||||||
|
def test_recv_only(serial=None):
|
||||||
|
connect_wifi(serial)
|
||||||
|
p = Panda(serial)
|
||||||
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||||
p.set_can_loopback(True)
|
p.set_can_loopback(True)
|
||||||
pwifi = Panda("WIFI")
|
pwifi = Panda("WIFI")
|
||||||
|
@ -49,4 +57,3 @@ def test_recv_only():
|
||||||
saturation_pct = (comp_kbps/speed) * 100.0
|
saturation_pct = (comp_kbps/speed) * 100.0
|
||||||
|
|
||||||
print("HT WIFI loopback %d messages at speed %d, comp speed is %.2f, percent %.2f" % (msg_count, speed, comp_kbps, saturation_pct))
|
print("HT WIFI loopback %d messages at speed %d, comp speed is %.2f, percent %.2f" % (msg_count, speed, comp_kbps, saturation_pct))
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
from helpers import time_many_sends, connect_wifi
|
from helpers import time_many_sends, connect_wifi, test_white, panda_color_to_serial
|
||||||
from panda import Panda, PandaWifiStreaming
|
from panda import Panda, PandaWifiStreaming
|
||||||
from nose.tools import timed, assert_equal, assert_less, assert_greater
|
from nose.tools import timed, assert_equal, assert_less, assert_greater
|
||||||
|
|
||||||
def test_udp_doesnt_drop():
|
@test_white
|
||||||
connect_wifi()
|
@panda_color_to_serial
|
||||||
|
def test_udp_doesnt_drop(serial=None):
|
||||||
|
connect_wifi(serial)
|
||||||
|
|
||||||
p = Panda()
|
p = Panda(serial)
|
||||||
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
p.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||||
p.set_can_loopback(True)
|
p.set_can_loopback(True)
|
||||||
|
|
||||||
|
@ -18,6 +20,7 @@ def test_udp_doesnt_drop():
|
||||||
break
|
break
|
||||||
|
|
||||||
for msg_count in [1, 100]:
|
for msg_count in [1, 100]:
|
||||||
|
saturation_pcts = []
|
||||||
for i in range({1: 0x80, 100: 0x20}[msg_count]):
|
for i in range({1: 0x80, 100: 0x20}[msg_count]):
|
||||||
pwifi.kick()
|
pwifi.kick()
|
||||||
|
|
||||||
|
@ -31,9 +34,33 @@ def test_udp_doesnt_drop():
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
else:
|
else:
|
||||||
print("UDP WIFI loopback %d messages at speed %d, comp speed is %.2f, percent %.2f" % (msg_count, speed, comp_kbps, saturation_pct))
|
print("UDP WIFI loopback %d messages at speed %d, comp speed is %.2f, percent %.2f" % (msg_count, speed, comp_kbps, saturation_pct))
|
||||||
assert_greater(saturation_pct, 40)
|
assert_greater(saturation_pct, 20) #sometimes the wifi can be slow...
|
||||||
assert_less(saturation_pct, 100)
|
assert_less(saturation_pct, 100)
|
||||||
print("")
|
saturation_pcts.append(saturation_pct)
|
||||||
|
if len(saturation_pcts) > 0:
|
||||||
|
assert_greater(sum(saturation_pcts)/len(saturation_pcts), 60)
|
||||||
|
|
||||||
|
time.sleep(5)
|
||||||
|
usb_ok_cnt = 0
|
||||||
|
REQ_USB_OK_CNT = 500
|
||||||
|
st = time.time()
|
||||||
|
msg_id = 0x1bb
|
||||||
|
bus = 0
|
||||||
|
last_missing_msg = 0
|
||||||
|
while usb_ok_cnt < REQ_USB_OK_CNT and (time.time() - st) < 40:
|
||||||
|
p.can_send(msg_id, "message", bus)
|
||||||
|
time.sleep(0.01)
|
||||||
|
r = [1]
|
||||||
|
missing = True
|
||||||
|
while len(r) > 0:
|
||||||
|
r = p.can_recv()
|
||||||
|
r = filter(lambda x: x[3] == bus and x[0] == msg_id, r)
|
||||||
|
if len(r) > 0:
|
||||||
|
missing = False
|
||||||
|
usb_ok_cnt += len(r)
|
||||||
|
if missing:
|
||||||
|
last_missing_msg = time.time()
|
||||||
|
et = time.time() - st
|
||||||
|
last_missing_msg = last_missing_msg - st
|
||||||
|
print("waited {} for panda to recv can on usb, {} msgs, last missing at {}".format(et, usb_ok_cnt, last_missing_msg))
|
||||||
|
assert usb_ok_cnt >= REQ_USB_OK_CNT, "Unable to recv can on USB after UDP"
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
from __future__ import print_function
|
||||||
|
import time
|
||||||
|
from panda import Panda
|
||||||
|
from nose.tools import assert_equal, assert_less, assert_greater
|
||||||
|
from helpers import time_many_sends, test_two_panda, panda_color_to_serial
|
||||||
|
|
||||||
|
@test_two_panda
|
||||||
|
@panda_color_to_serial
|
||||||
|
def test_send_recv(serial_sender=None, serial_reciever=None):
|
||||||
|
p_send = Panda(serial_sender)
|
||||||
|
p_recv = Panda(serial_reciever)
|
||||||
|
|
||||||
|
p_send.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||||
|
p_send.set_can_loopback(False)
|
||||||
|
|
||||||
|
p_recv.set_can_loopback(False)
|
||||||
|
|
||||||
|
assert not p_send.legacy
|
||||||
|
assert not p_recv.legacy
|
||||||
|
|
||||||
|
p_send.can_send_many([(0x1ba, 0, "message", 0)]*2)
|
||||||
|
time.sleep(0.05)
|
||||||
|
p_recv.can_recv()
|
||||||
|
p_send.can_recv()
|
||||||
|
|
||||||
|
busses = [0,1,2]
|
||||||
|
|
||||||
|
for bus in busses:
|
||||||
|
for speed in [100, 250, 500, 750, 1000]:
|
||||||
|
p_send.set_can_speed_kbps(bus, speed)
|
||||||
|
p_recv.set_can_speed_kbps(bus, speed)
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
comp_kbps = time_many_sends(p_send, bus, p_recv, two_pandas=True)
|
||||||
|
|
||||||
|
saturation_pct = (comp_kbps/speed) * 100.0
|
||||||
|
assert_greater(saturation_pct, 80)
|
||||||
|
assert_less(saturation_pct, 100)
|
||||||
|
|
||||||
|
print("two pandas bus {}, 100 messages at speed {:4d}, comp speed is {:7.2f}, percent {:6.2f}".format(bus, speed, comp_kbps, saturation_pct))
|
||||||
|
|
||||||
|
@test_two_panda
|
||||||
|
@panda_color_to_serial
|
||||||
|
def test_latency(serial_sender=None, serial_reciever=None):
|
||||||
|
p_send = Panda(serial_sender)
|
||||||
|
p_recv = Panda(serial_reciever)
|
||||||
|
|
||||||
|
p_send.set_safety_mode(Panda.SAFETY_ALLOUTPUT)
|
||||||
|
p_send.set_can_loopback(False)
|
||||||
|
|
||||||
|
p_recv.set_can_loopback(False)
|
||||||
|
|
||||||
|
assert not p_send.legacy
|
||||||
|
assert not p_recv.legacy
|
||||||
|
|
||||||
|
p_send.set_can_speed_kbps(0, 100)
|
||||||
|
p_recv.set_can_speed_kbps(0, 100)
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
p_send.can_send_many([(0x1ba, 0, "testmsg", 0)]*10)
|
||||||
|
time.sleep(0.05)
|
||||||
|
p_recv.can_recv()
|
||||||
|
p_send.can_recv()
|
||||||
|
|
||||||
|
busses = [0,1,2]
|
||||||
|
|
||||||
|
for bus in busses:
|
||||||
|
for speed in [100, 250, 500, 750, 1000]:
|
||||||
|
p_send.set_can_speed_kbps(bus, speed)
|
||||||
|
p_recv.set_can_speed_kbps(bus, speed)
|
||||||
|
time.sleep(0.1)
|
||||||
|
#clear can buffers
|
||||||
|
r = [1]
|
||||||
|
while len(r) > 0:
|
||||||
|
r = p_send.can_recv()
|
||||||
|
r = [1]
|
||||||
|
while len(r) > 0:
|
||||||
|
r = p_recv.can_recv()
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
latencies = []
|
||||||
|
comp_kbps_list = []
|
||||||
|
saturation_pcts = []
|
||||||
|
|
||||||
|
num_messages = 100
|
||||||
|
|
||||||
|
for i in range(num_messages):
|
||||||
|
st = time.time()
|
||||||
|
p_send.can_send(0x1ab, "message", bus)
|
||||||
|
r = []
|
||||||
|
while len(r) < 1 and (time.time() - st) < 5:
|
||||||
|
r = p_recv.can_recv()
|
||||||
|
et = time.time()
|
||||||
|
r_echo = []
|
||||||
|
while len(r_echo) < 1 and (time.time() - st) < 10:
|
||||||
|
r_echo = p_send.can_recv()
|
||||||
|
|
||||||
|
if len(r) == 0 or len(r_echo) == 0:
|
||||||
|
print("r: {}, r_echo: {}".format(r, r_echo))
|
||||||
|
|
||||||
|
assert_equal(len(r),1)
|
||||||
|
assert_equal(len(r_echo),1)
|
||||||
|
|
||||||
|
et = (et - st)*1000.0
|
||||||
|
comp_kbps = (1+11+1+1+1+4+8*8+15+1+1+1+7) / et
|
||||||
|
latency = et - ((1+11+1+1+1+4+8*8+15+1+1+1+7) / speed)
|
||||||
|
|
||||||
|
assert_less(latency, 5.0)
|
||||||
|
|
||||||
|
saturation_pct = (comp_kbps/speed) * 100.0
|
||||||
|
latencies.append(latency)
|
||||||
|
comp_kbps_list.append(comp_kbps)
|
||||||
|
saturation_pcts.append(saturation_pct)
|
||||||
|
|
||||||
|
average_latency = sum(latencies)/num_messages
|
||||||
|
assert_less(average_latency, 1.0)
|
||||||
|
average_comp_kbps = sum(comp_kbps_list)/num_messages
|
||||||
|
average_saturation_pct = sum(saturation_pcts)/num_messages
|
||||||
|
|
||||||
|
print("two pandas bus {}, {} message average at speed {:4d}, latency is {:5.3f}ms, comp speed is {:7.2f}, percent {:6.2f}"\
|
||||||
|
.format(bus, num_messages, speed, average_latency, average_comp_kbps, average_saturation_pct))
|
|
@ -4,12 +4,34 @@ import time
|
||||||
import random
|
import random
|
||||||
import subprocess
|
import subprocess
|
||||||
import requests
|
import requests
|
||||||
|
from functools import wraps
|
||||||
from panda import Panda
|
from panda import Panda
|
||||||
from nose.tools import timed, assert_equal, assert_less, assert_greater
|
from nose.tools import timed, assert_equal, assert_less, assert_greater
|
||||||
|
from parameterized import parameterized, param
|
||||||
|
|
||||||
def connect_wo_esp():
|
test_white_and_grey = parameterized([param(panda_color="White"),
|
||||||
|
param(panda_color="Grey")])
|
||||||
|
test_white = parameterized([param(panda_color="White")])
|
||||||
|
test_grey = parameterized([param(panda_color="Grey")])
|
||||||
|
test_two_panda = parameterized([param(panda_color=["Grey", "White"]),
|
||||||
|
param(panda_color=["White", "Grey"])])
|
||||||
|
|
||||||
|
_serials = {}
|
||||||
|
def get_panda_serial(is_grey=None):
|
||||||
|
global _serials
|
||||||
|
if is_grey not in _serials:
|
||||||
|
for serial in Panda.list():
|
||||||
|
p = Panda(serial=serial)
|
||||||
|
if is_grey is None or p.is_grey() == is_grey:
|
||||||
|
_serials[is_grey] = serial
|
||||||
|
return serial
|
||||||
|
raise IOError("Panda not found. is_grey: {}".format(is_grey))
|
||||||
|
else:
|
||||||
|
return _serials[is_grey]
|
||||||
|
|
||||||
|
def connect_wo_esp(serial=None):
|
||||||
# connect to the panda
|
# connect to the panda
|
||||||
p = Panda()
|
p = Panda(serial=serial)
|
||||||
|
|
||||||
# power down the ESP
|
# power down the ESP
|
||||||
p.set_esp_power(False)
|
p.set_esp_power(False)
|
||||||
|
@ -20,15 +42,28 @@ def connect_wo_esp():
|
||||||
|
|
||||||
return p
|
return p
|
||||||
|
|
||||||
def connect_wifi():
|
def connect_wifi(serial=None):
|
||||||
p = Panda()
|
p = Panda(serial=serial)
|
||||||
|
p.set_esp_power(True)
|
||||||
dongle_id, pw = p.get_serial()
|
dongle_id, pw = p.get_serial()
|
||||||
assert(dongle_id.isalnum())
|
assert(dongle_id.isalnum())
|
||||||
_connect_wifi(dongle_id, pw)
|
_connect_wifi(dongle_id, pw)
|
||||||
|
|
||||||
|
FNULL = open(os.devnull, 'w')
|
||||||
def _connect_wifi(dongle_id, pw, insecure_okay=False):
|
def _connect_wifi(dongle_id, pw, insecure_okay=False):
|
||||||
ssid = str("panda-" + dongle_id)
|
ssid = str("panda-" + dongle_id)
|
||||||
|
|
||||||
|
r = subprocess.call(["ping", "-W", "4", "-c", "1", "192.168.0.10"], stdout=FNULL, stderr=subprocess.STDOUT)
|
||||||
|
if not r:
|
||||||
|
#Can already ping, try connecting on wifi
|
||||||
|
try:
|
||||||
|
p = Panda("WIFI")
|
||||||
|
p.get_serial()
|
||||||
|
print("Already connected")
|
||||||
|
return
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
print("WIFI: connecting to %s" % ssid)
|
print("WIFI: connecting to %s" % ssid)
|
||||||
|
|
||||||
while 1:
|
while 1:
|
||||||
|
@ -39,8 +74,8 @@ def _connect_wifi(dongle_id, pw, insecure_okay=False):
|
||||||
cnt = 0
|
cnt = 0
|
||||||
MAX_TRIES = 10
|
MAX_TRIES = 10
|
||||||
while cnt < MAX_TRIES:
|
while cnt < MAX_TRIES:
|
||||||
print "WIFI: scanning %d" % cnt
|
print("WIFI: scanning %d" % cnt)
|
||||||
os.system("sudo iwlist %s scanning > /dev/null" % wlan_interface)
|
os.system("iwlist %s scanning > /dev/null" % wlan_interface)
|
||||||
os.system("nmcli device wifi rescan")
|
os.system("nmcli device wifi rescan")
|
||||||
wifi_scan = filter(lambda x: ssid in x, subprocess.check_output(["nmcli","dev", "wifi", "list"]).split("\n"))
|
wifi_scan = filter(lambda x: ssid in x, subprocess.check_output(["nmcli","dev", "wifi", "list"]).split("\n"))
|
||||||
if len(wifi_scan) != 0:
|
if len(wifi_scan) != 0:
|
||||||
|
@ -51,45 +86,107 @@ def _connect_wifi(dongle_id, pw, insecure_okay=False):
|
||||||
assert cnt < MAX_TRIES
|
assert cnt < MAX_TRIES
|
||||||
if "-pair" in wifi_scan[0]:
|
if "-pair" in wifi_scan[0]:
|
||||||
os.system("nmcli d wifi connect %s-pair" % (ssid))
|
os.system("nmcli d wifi connect %s-pair" % (ssid))
|
||||||
|
connect_cnt = 0
|
||||||
|
MAX_TRIES = 20
|
||||||
|
while connect_cnt < MAX_TRIES:
|
||||||
|
connect_cnt += 1
|
||||||
|
r = subprocess.call(["ping", "-W", "4", "-c", "1", "192.168.0.10"], stdout=FNULL, stderr=subprocess.STDOUT)
|
||||||
|
if r:
|
||||||
|
print("Waiting for panda to ping...")
|
||||||
|
time.sleep(0.1)
|
||||||
|
else:
|
||||||
|
break
|
||||||
if insecure_okay:
|
if insecure_okay:
|
||||||
break
|
break
|
||||||
# fetch webpage
|
# fetch webpage
|
||||||
print "connecting to insecure network to secure"
|
print("connecting to insecure network to secure")
|
||||||
r = requests.get("http://192.168.0.10/")
|
try:
|
||||||
|
r = requests.get("http://192.168.0.10/")
|
||||||
|
except requests.ConnectionError:
|
||||||
|
r = requests.get("http://192.168.0.10/")
|
||||||
assert r.status_code==200
|
assert r.status_code==200
|
||||||
|
|
||||||
print "securing"
|
print("securing")
|
||||||
try:
|
try:
|
||||||
r = requests.get("http://192.168.0.10/secure", timeout=0.01)
|
r = requests.get("http://192.168.0.10/secure", timeout=0.01)
|
||||||
except requests.exceptions.Timeout:
|
except requests.exceptions.Timeout:
|
||||||
|
print("timeout http request to secure")
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
os.system("nmcli d wifi connect %s password %s" % (ssid, pw))
|
ret = os.system("nmcli d wifi connect %s password %s" % (ssid, pw))
|
||||||
break
|
if os.WEXITSTATUS(ret) == 0:
|
||||||
|
#check ping too
|
||||||
|
ping_ok = False
|
||||||
|
connect_cnt = 0
|
||||||
|
MAX_TRIES = 10
|
||||||
|
while connect_cnt < MAX_TRIES:
|
||||||
|
connect_cnt += 1
|
||||||
|
r = subprocess.call(["ping", "-W", "4", "-c", "1", "192.168.0.10"], stdout=FNULL, stderr=subprocess.STDOUT)
|
||||||
|
if r:
|
||||||
|
print("Waiting for panda to ping...")
|
||||||
|
time.sleep(0.1)
|
||||||
|
else:
|
||||||
|
ping_ok = True
|
||||||
|
break
|
||||||
|
if ping_ok:
|
||||||
|
break
|
||||||
|
|
||||||
# TODO: confirm that it's connected to the right panda
|
# TODO: confirm that it's connected to the right panda
|
||||||
|
|
||||||
def time_many_sends(p, bus, precv=None, msg_count=100, msg_id=None):
|
def time_many_sends(p, bus, precv=None, msg_count=100, msg_id=None, two_pandas=False):
|
||||||
if precv == None:
|
if precv == None:
|
||||||
precv = p
|
precv = p
|
||||||
if msg_id == None:
|
if msg_id == None:
|
||||||
msg_id = random.randint(0x100, 0x200)
|
msg_id = random.randint(0x100, 0x200)
|
||||||
|
if p == precv and two_pandas:
|
||||||
|
raise ValueError("Cannot have two pandas that are the same panda")
|
||||||
|
|
||||||
st = time.time()
|
st = time.time()
|
||||||
p.can_send_many([(msg_id, 0, "\xaa"*8, bus)]*msg_count)
|
p.can_send_many([(msg_id, 0, "\xaa"*8, bus)]*msg_count)
|
||||||
r = []
|
r = []
|
||||||
|
r_echo = []
|
||||||
|
r_len_expected = msg_count if two_pandas else msg_count*2
|
||||||
|
r_echo_len_exected = msg_count if two_pandas else 0
|
||||||
|
|
||||||
while len(r) < (msg_count*2) and (time.time() - st) < 3:
|
while len(r) < r_len_expected and (time.time() - st) < 5:
|
||||||
r.extend(precv.can_recv())
|
r.extend(precv.can_recv())
|
||||||
|
et = time.time()
|
||||||
|
if two_pandas:
|
||||||
|
while len(r_echo) < r_echo_len_exected and (time.time() - st) < 10:
|
||||||
|
r_echo.extend(p.can_recv())
|
||||||
|
|
||||||
sent_echo = filter(lambda x: x[3] == 0x80 | bus and x[0] == msg_id, r)
|
sent_echo = filter(lambda x: x[3] == 0x80 | bus and x[0] == msg_id, r)
|
||||||
loopback_resp = filter(lambda x: x[3] == bus and x[0] == msg_id, r)
|
sent_echo.extend(filter(lambda x: x[3] == 0x80 | bus and x[0] == msg_id, r_echo))
|
||||||
|
resp = filter(lambda x: x[3] == bus and x[0] == msg_id, r)
|
||||||
|
|
||||||
|
leftovers = filter(lambda x: (x[3] != 0x80 | bus and x[3] != bus) or x[0] != msg_id, r)
|
||||||
|
assert_equal(len(leftovers), 0)
|
||||||
|
|
||||||
|
assert_equal(len(resp), msg_count)
|
||||||
assert_equal(len(sent_echo), msg_count)
|
assert_equal(len(sent_echo), msg_count)
|
||||||
assert_equal(len(loopback_resp), msg_count)
|
|
||||||
|
|
||||||
et = (time.time()-st)*1000.0
|
et = (et-st)*1000.0
|
||||||
comp_kbps = (1+11+1+1+1+4+8*8+15+1+1+1+7)*msg_count / et
|
comp_kbps = (1+11+1+1+1+4+8*8+15+1+1+1+7)*msg_count / et
|
||||||
|
|
||||||
return comp_kbps
|
return comp_kbps
|
||||||
|
|
||||||
|
|
||||||
|
def panda_color_to_serial(fn):
|
||||||
|
@wraps(fn)
|
||||||
|
def wrapper(panda_color=None, **kwargs):
|
||||||
|
pandas_is_grey = []
|
||||||
|
if panda_color is not None:
|
||||||
|
if not isinstance(panda_color, list):
|
||||||
|
panda_color = [panda_color]
|
||||||
|
panda_color = [s.lower() for s in panda_color]
|
||||||
|
for p in panda_color:
|
||||||
|
if p is None:
|
||||||
|
pandas_is_grey.append(None)
|
||||||
|
elif p in ["grey", "gray"]:
|
||||||
|
pandas_is_grey.append(True)
|
||||||
|
elif p in ["white"]:
|
||||||
|
pandas_is_grey.append(False)
|
||||||
|
else:
|
||||||
|
raise ValueError("Invalid Panda Color {}".format(p))
|
||||||
|
return fn(*[get_panda_serial(is_grey) for is_grey in pandas_is_grey], **kwargs)
|
||||||
|
return wrapper
|
||||||
|
|
|
@ -246,3 +246,12 @@ void reset_gmlan_switch_timeout(void){
|
||||||
|
|
||||||
void gmlan_switch_init(int timeout_enable){
|
void gmlan_switch_init(int timeout_enable){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lline_relay_init (void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void lline_relay_release (void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_lline_output(int to_set) {
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue