1282e8f5a cap libusb1 version in setup (#183) 64bcc89a9 Subaru: 545 msg must be generated 9159df9a5 Merge branch '0.5.10-chyrsler' f8ab74a1c L-line relay (#166) 11c4cdcc4 Cleanup leftover jenkins command 22572d949 Fix Jenkins build dockerfiles with same name 1d2f8f0ab Jenkins (#179) f383eee96 Power saving: wake on RX and don't print durint IRQ 9540db744 Chrysler safety: better to mention messages we don't want to forward 104950264 chrysler: forward bus 0 to bus 2 (#177) 4276c380e Additional Power saving (#170) git-subtree-dir: panda git-subtree-split: 1282e8f5a0904b1aaa50f382db2e27f20e74a154pull/3/head
							parent
							
								
									27ef9f2236
								
							
						
					
					
						commit
						3c25760cc9
					
				
				 37 changed files with 947 additions and 107 deletions
			
			
		@ -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" | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					  } | 
				
			||||||
 | 
					} | 
				
			||||||
@ -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 | 
				
			||||||
@ -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; | 
				
			||||||
 | 
					  } | 
				
			||||||
 | 
					} | 
				
			||||||
@ -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 | 
				
			||||||
@ -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 | 
				
			||||||
 | 
				
			|||||||
@ -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)) | 
				
			||||||
					Loading…
					
					
				
		Reference in new issue