Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
geohot committed Apr 7, 2017
0 parents commit e07f9b1
Show file tree
Hide file tree
Showing 64 changed files with 37,461 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.pyc
.*.swp
*.o

7 changes: 7 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Copyright (c) 2016, Comma.ai, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Welcome to panda
======

[panda](http://github.com/commaai/panda) is the nicest universal car interface you've ever seen.

It supports 3x CAN, 2x LIN, and 1x GMLAN.

It uses an [STM32F413](http://www.st.com/en/microcontrollers/stm32f413-423.html?querycriteria=productId=LN2004) for low level stuff and an [ESP8266](https://en.wikipedia.org/wiki/ESP8266) for wifi. They are connected over high speed SPI, so the panda is actually capable of dumping the full contents of the busses over wifi, unlike every other dongle on amazon. ELM327 is weak, panda is strong.

It is 2nd gen hardware, reusing code and parts from the [NEO](https://github.com/commaai/neo) interface board.

Directory structure
------

- board -- Code that runs on the STM32
- boardesp -- Code that runs on the ESP8266
- lib -- Python userspace library for interfacing with the panda
- tests -- Tests and helper programs for panda

Usage
------

Programming the STM32
```
cd board
./get_sdk.sh
make
```

Programming the ESP
```
cd boardesp
./get_sdk.sh
make
```

Licensing
------

panda software is released under the MIT license. See LICENSE

11 changes: 11 additions & 0 deletions TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
== Needed ==
* Change the SPI interface to support all USB commands
* Support panda lib abstractly connecting over wifi or USB
* Refactor the Honda safety code to be universal

== Wanted ==
* Change USB to use interrupt endpoint instead of bulk for can recv
* Write elm327 emulator in boardesp/elm327.c and make it work with Torque
* Write a kernel driver to support socketcan. Kline as serial interfaces?
* Write a Windows J2534 DLL to support windows tools

Empty file added __init__.py
Empty file.
1 change: 1 addition & 0 deletions board/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
obj/*
10 changes: 10 additions & 0 deletions board/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# :set noet
PROJ_NAME = panda
CFLAGS = -g -O0 -Wall

CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m4
CFLAGS += -mhard-float -DSTM32F4 -DSTM32F413xx
STARTUP_FILE = startup_stm32f413xx

include build.mk

9 changes: 9 additions & 0 deletions board/Makefile.legacy
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# :set noet
PROJ_NAME = comma
CFLAGS = -g -O0 -Wall

CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m3
CFLAGS += -msoft-float -DSTM32F2 -DSTM32F205xx
STARTUP_FILE = startup_stm32f205xx

include build.mk
9 changes: 9 additions & 0 deletions board/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
== Building ==

./get_sdk.sh

dfu-util from
[email protected]:dsigma/dfu-util.git



Empty file added board/__init__.py
Empty file.
39 changes: 39 additions & 0 deletions board/adc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// ACCEL1 = ADC10
// ACCEL2 = ADC11
// VOLT_S = ADC12
// CURR_S = ADC13

#define ADCCHAN_ACCEL0 10
#define ADCCHAN_ACCEL1 11
#define ADCCHAN_VOLTAGE 12
#define ADCCHAN_CURRENT 13

void adc_init() {
// global setup
ADC->CCR = ADC_CCR_TSVREFE | ADC_CCR_VBATE;
//ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_EOCS | ADC_CR2_DDS;
ADC1->CR2 = ADC_CR2_ADON;

// long
//ADC1->SMPR1 = ADC_SMPR1_SMP10 | ADC_SMPR1_SMP11 | ADC_SMPR1_SMP12 | ADC_SMPR1_SMP13;
ADC1->SMPR1 = ADC_SMPR1_SMP12 | ADC_SMPR1_SMP13;
}

uint32_t adc_get(int channel) {

// includes length
//ADC1->SQR1 = 0;

// select channel
ADC1->JSQR = channel << 15;

//ADC1->CR1 = ADC_CR1_DISCNUM_0;
//ADC1->CR1 = ADC_CR1_EOCIE;

ADC1->SR &= ~(ADC_SR_JEOC);
ADC1->CR2 |= ADC_CR2_JSWSTART;
while (!(ADC1->SR & ADC_SR_JEOC));

return ADC1->JDR1;
}

22 changes: 22 additions & 0 deletions board/bootstub.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
void *_origin = 0x8004000;

#ifdef STM32F4
#define PANDA
#include "stm32f4xx.h"
#else
#include "stm32f2xx.h"
#endif

#include "early.h"

void __initialize_hardware_early() {
early();

// jump to flash
((void(*)()) _app_start[1])();
}

int main() {
return 0;
}

54 changes: 54 additions & 0 deletions board/build.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
CFLAGS += -I inc -nostdlib
CFLAGS += -Tstm32_flash.ld

CC = arm-none-eabi-gcc
OBJCOPY = arm-none-eabi-objcopy
OBJDUMP = arm-none-eabi-objdump

MACHINE = $(shell uname -m)
OS = $(shell uname -o)

ifeq ($(OS),GNU/Linux)
MACHINE := "$(MACHINE)-linux"
endif

# this pushes the unchangable bootstub too
all: obj/bootstub.$(PROJ_NAME).bin obj/$(PROJ_NAME).bin
./tools/enter_download_mode.py
./tools/dfu-util-$(MACHINE) -a 0 -s 0x08000000 -D obj/bootstub.$(PROJ_NAME).bin
./tools/dfu-util-$(MACHINE) -a 0 -s 0x08004000 -D obj/$(PROJ_NAME).bin
./tools/dfu-util-$(MACHINE) --reset-stm32 -a 0 -s 0x08000000

ota: obj/$(PROJ_NAME).bin
./tools/ota.py $<

ifneq ($(wildcard ../.git/HEAD),)
obj/gitversion.h: ../.git/HEAD ../.git/index
echo "const uint8_t gitversion[] = \"$(shell git rev-parse HEAD)\";" > $@
else
obj/gitversion.h:
echo "const uint8_t gitversion[] = \"RELEASE\";" > $@
endif

obj/bootstub.$(PROJ_NAME).o: bootstub.c early.h
$(CC) $(CFLAGS) -o $@ -c $<

obj/main.$(PROJ_NAME).o: main.c *.h obj/gitversion.h
$(CC) $(CFLAGS) -o $@ -c $<

obj/$(STARTUP_FILE).o: $(STARTUP_FILE).s
mkdir -p obj
$(CC) $(CFLAGS) -o $@ -c $<

obj/$(PROJ_NAME).bin: obj/$(STARTUP_FILE).o obj/main.$(PROJ_NAME).o
# hack
$(CC) -Wl,--section-start,.isr_vector=0x8004000 $(CFLAGS) -o obj/$(PROJ_NAME).elf $^
$(OBJCOPY) -v -O binary obj/$(PROJ_NAME).elf $@

obj/bootstub.$(PROJ_NAME).bin: obj/$(STARTUP_FILE).o obj/bootstub.$(PROJ_NAME).o
$(CC) $(CFLAGS) -o obj/bootstub.$(PROJ_NAME).elf $^
$(OBJCOPY) -v -O binary obj/bootstub.$(PROJ_NAME).elf $@

clean:
rm -f obj/*

112 changes: 112 additions & 0 deletions board/can.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
void can_init(CAN_TypeDef *CAN) {
// enable CAN busses
if (CAN == CAN1) {
#ifdef PANDA
// CAN1_EN
GPIOC->ODR &= ~(1 << 1);
#else
// CAN1_EN
GPIOB->ODR |= (1 << 3);
#endif
} else if (CAN == CAN2) {
#ifdef PANDA
// CAN2_EN
GPIOC->ODR &= ~(1 << 13);
#else
// CAN2_EN
GPIOB->ODR |= (1 << 4);
#endif
#ifdef CAN3
} else if (CAN == CAN3) {
// CAN3_EN
GPIOA->ODR &= ~(1 << 0);
#endif
}

CAN->MCR = CAN_MCR_TTCM | CAN_MCR_INRQ;
while((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK);

// PCLK = 24000000, 500000 is 48 clocks
// from http://www.bittiming.can-wiki.ino/
CAN->BTR = 0x001c0002;

// loopback mode for debugging
#ifdef CAN_LOOPBACK_MODE
CAN->BTR |= CAN_BTR_SILM | CAN_BTR_LBKM;
#endif

// reset
CAN->MCR = CAN_MCR_TTCM;

#define CAN_TIMEOUT 1000000
int tmp = 0;
while((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK && tmp < CAN_TIMEOUT) tmp++;

if (tmp == CAN_TIMEOUT) {
set_led(LED_BLUE, 1);
puts("CAN init FAILED!!!!!\n");
} else {
puts("CAN init done\n");
}

// accept all filter
CAN->FMR |= CAN_FMR_FINIT;

// no mask
CAN->sFilterRegister[0].FR1 = 0;
CAN->sFilterRegister[0].FR2 = 0;
CAN->sFilterRegister[14].FR1 = 0;
CAN->sFilterRegister[14].FR2 = 0;
CAN->FA1R |= 1 | (1 << 14);

CAN->FMR &= ~(CAN_FMR_FINIT);

// enable all CAN interrupts
CAN->IER = 0xFFFFFFFF;
//CAN->IER = CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_FMPIE1;
}

// CAN error
void can_sce(CAN_TypeDef *CAN) {
#ifdef DEBUG
if (CAN==CAN1) puts("CAN1: ");
if (CAN==CAN2) puts("CAN2: ");
#ifdef CAN3
if (CAN==CAN3) puts("CAN3: ");
#endif
puts("MSR:");
puth(CAN->MSR);
puts(" TSR:");
puth(CAN->TSR);
puts(" RF0R:");
puth(CAN->RF0R);
puts(" RF1R:");
puth(CAN->RF1R);
puts(" ESR:");
puth(CAN->ESR);
puts("\n");
#endif

// clear
//CAN->sTxMailBox[0].TIR &= ~(CAN_TI0R_TXRQ);
CAN->TSR |= CAN_TSR_ABRQ0;
//CAN->ESR |= CAN_ESR_LEC;
//CAN->MSR &= ~(CAN_MSR_ERRI);
CAN->MSR = CAN->MSR;
}

int can_cksum(uint8_t *dat, int len, int addr, int idx) {
int i;
int s = 0;
for (i = 0; i < len; i++) {
s += (dat[i] >> 4);
s += dat[i] & 0xF;
}
s += (addr>>0)&0xF;
s += (addr>>4)&0xF;
s += (addr>>8)&0xF;
s += idx;
s = 8-s;
return s&0xF;
}

16 changes: 16 additions & 0 deletions board/dac.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
void dac_init() {
// no buffers required since we have an opamp
//DAC->CR = DAC_CR_EN1 | DAC_CR_BOFF1 | DAC_CR_EN2 | DAC_CR_BOFF2;
DAC->DHR12R1 = 0;
DAC->DHR12R2 = 0;
DAC->CR = DAC_CR_EN1 | DAC_CR_EN2;
}

void dac_set(int channel, uint32_t value) {
if (channel == 0) {
DAC->DHR12R1 = value;
} else if (channel == 1) {
DAC->DHR12R2 = value;
}
}

Loading

0 comments on commit e07f9b1

Please sign in to comment.