Merge panda subtree

pull/183/head
Vehicle Researcher 7 years ago
commit b68f3f7781
  1. 2
      panda/VERSION
  2. 4
      panda/board/build.mk
  3. 10
      panda/board/drivers/drivers.h
  4. 85
      panda/board/drivers/uart.h
  5. 6
      panda/board/gpio.h
  6. 24
      panda/board/main.c
  7. 6
      panda/board/safety.h
  8. 4
      panda/board/safety/safety_defaults.h
  9. 2
      panda/board/safety/safety_elm327.h
  10. 2
      panda/board/safety/safety_honda.h
  11. 13
      panda/board/safety/safety_toyota.h
  12. 40
      panda/examples/isotp.py
  13. 14
      panda/python/__init__.py
  14. 1
      panda/tests/location_listener.py

@ -1 +1 @@
v1.0.4 v1.0.6

@ -17,7 +17,7 @@ DFU_UTIL = "dfu-util"
# this no longer pushes the bootstub # this no longer pushes the bootstub
flash: obj/$(PROJ_NAME).bin flash: obj/$(PROJ_NAME).bin
PYTHONPATH=../ python -c "from panda import Panda; Panda().flash('obj/$(PROJ_NAME).bin')" PYTHONPATH=../ python -c "from python import Panda; Panda().flash('obj/$(PROJ_NAME).bin')"
ota: obj/$(PROJ_NAME).bin ota: obj/$(PROJ_NAME).bin
curl http://192.168.0.10/stupdate --upload-file $< curl http://192.168.0.10/stupdate --upload-file $<
@ -26,7 +26,7 @@ bin: obj/$(PROJ_NAME).bin
# this flashes everything # this flashes everything
recover: obj/bootstub.$(PROJ_NAME).bin obj/$(PROJ_NAME).bin recover: obj/bootstub.$(PROJ_NAME).bin obj/$(PROJ_NAME).bin
-PYTHONPATH=../ python -c "from panda import Panda; Panda().reset(enter_bootloader=True)" -PYTHONPATH=../ python -c "from python import Panda; Panda().reset(enter_bootloader=True)"
sleep 1.0 sleep 1.0
$(DFU_UTIL) -d 0483:df11 -a 0 -s 0x08004000 -D obj/$(PROJ_NAME).bin $(DFU_UTIL) -d 0483:df11 -a 0 -s 0x08004000 -D obj/$(PROJ_NAME).bin
$(DFU_UTIL) -d 0483:df11 -a 0 -s 0x08000000:leave -D obj/bootstub.$(PROJ_NAME).bin $(DFU_UTIL) -d 0483:df11 -a 0 -s 0x08000000:leave -D obj/bootstub.$(PROJ_NAME).bin

@ -57,13 +57,13 @@ void usb_cb_enumeration_complete();
// ********************* UART ********************* // ********************* UART *********************
// IRQs: USART1, USART2, USART3, UART5 // IRQs: USART1, USART2, USART3, UART5
#define FIFO_SIZE 0x100 #define FIFO_SIZE 0x400
typedef struct uart_ring { typedef struct uart_ring {
uint8_t w_ptr_tx; uint16_t w_ptr_tx;
uint8_t r_ptr_tx; uint16_t r_ptr_tx;
uint8_t elems_tx[FIFO_SIZE]; uint8_t elems_tx[FIFO_SIZE];
uint8_t w_ptr_rx; uint16_t w_ptr_rx;
uint8_t r_ptr_rx; uint16_t r_ptr_rx;
uint8_t elems_rx[FIFO_SIZE]; uint8_t elems_rx[FIFO_SIZE];
USART_TypeDef *uart; USART_TypeDef *uart;
void (*callback)(struct uart_ring*); void (*callback)(struct uart_ring*);

@ -52,7 +52,7 @@ void uart_ring_process(uart_ring *q) {
if (q->w_ptr_tx != q->r_ptr_tx) { if (q->w_ptr_tx != q->r_ptr_tx) {
if (sr & USART_SR_TXE) { if (sr & USART_SR_TXE) {
q->uart->DR = q->elems_tx[q->r_ptr_tx]; q->uart->DR = q->elems_tx[q->r_ptr_tx];
q->r_ptr_tx += 1; q->r_ptr_tx = (q->r_ptr_tx + 1) % FIFO_SIZE;
} else { } else {
// push on interrupt later // push on interrupt later
q->uart->CR1 |= USART_CR1_TXEIE; q->uart->CR1 |= USART_CR1_TXEIE;
@ -64,11 +64,13 @@ void uart_ring_process(uart_ring *q) {
if (sr & USART_SR_RXNE || sr & USART_SR_ORE) { if (sr & USART_SR_RXNE || sr & USART_SR_ORE) {
uint8_t c = q->uart->DR; // TODO: can drop packets uint8_t c = q->uart->DR; // TODO: can drop packets
uint8_t next_w_ptr = q->w_ptr_rx + 1; if (q != &esp_ring) {
if (next_w_ptr != q->r_ptr_rx) { uint16_t next_w_ptr = (q->w_ptr_rx + 1) % FIFO_SIZE;
q->elems_rx[q->w_ptr_rx] = c; if (next_w_ptr != q->r_ptr_rx) {
q->w_ptr_rx = next_w_ptr; q->elems_rx[q->w_ptr_rx] = c;
if (q->callback) q->callback(q); q->w_ptr_rx = next_w_ptr;
if (q->callback) q->callback(q);
}
} }
} }
@ -92,7 +94,7 @@ int getc(uart_ring *q, char *elem) {
enter_critical_section(); enter_critical_section();
if (q->w_ptr_rx != q->r_ptr_rx) { if (q->w_ptr_rx != q->r_ptr_rx) {
*elem = q->elems_rx[q->r_ptr_rx]; *elem = q->elems_rx[q->r_ptr_rx];
q->r_ptr_rx += 1; q->r_ptr_rx = (q->r_ptr_rx + 1) % FIFO_SIZE;
ret = 1; ret = 1;
} }
exit_critical_section(); exit_critical_section();
@ -102,10 +104,10 @@ int getc(uart_ring *q, char *elem) {
int injectc(uart_ring *q, char elem) { int injectc(uart_ring *q, char elem) {
int ret = 0; int ret = 0;
uint8_t next_w_ptr; uint16_t next_w_ptr;
enter_critical_section(); enter_critical_section();
next_w_ptr = q->w_ptr_rx + 1; next_w_ptr = (q->w_ptr_rx + 1) % FIFO_SIZE;
if (next_w_ptr != q->r_ptr_rx) { if (next_w_ptr != q->r_ptr_rx) {
q->elems_rx[q->w_ptr_rx] = elem; q->elems_rx[q->w_ptr_rx] = elem;
q->w_ptr_rx = next_w_ptr; q->w_ptr_rx = next_w_ptr;
@ -118,10 +120,10 @@ int injectc(uart_ring *q, char elem) {
int putc(uart_ring *q, char elem) { int putc(uart_ring *q, char elem) {
int ret = 0; int ret = 0;
uint8_t next_w_ptr; uint16_t next_w_ptr;
enter_critical_section(); enter_critical_section();
next_w_ptr = q->w_ptr_tx + 1; next_w_ptr = (q->w_ptr_tx + 1) % FIFO_SIZE;
if (next_w_ptr != q->r_ptr_tx) { if (next_w_ptr != q->r_ptr_tx) {
q->elems_tx[q->w_ptr_tx] = elem; q->elems_tx[q->w_ptr_tx] = elem;
q->w_ptr_tx = next_w_ptr; q->w_ptr_tx = next_w_ptr;
@ -159,6 +161,51 @@ void uart_set_baud(USART_TypeDef *u, int baud) {
} }
} }
#define USART1_DMA_LEN 0x20
char usart1_dma[USART1_DMA_LEN];
void uart_dma_drain() {
uart_ring *q = &esp_ring;
enter_critical_section();
if (DMA2->HISR & DMA_HISR_TCIF5 || DMA2->HISR & DMA_HISR_HTIF5 || DMA2_Stream5->NDTR != USART1_DMA_LEN) {
// disable DMA
q->uart->CR3 &= ~USART_CR3_DMAR;
DMA2_Stream5->CR &= ~DMA_SxCR_EN;
while (DMA2_Stream5->CR & DMA_SxCR_EN);
int i;
for (i = 0; i < USART1_DMA_LEN - DMA2_Stream5->NDTR; i++) {
char c = usart1_dma[i];
uint16_t next_w_ptr = (q->w_ptr_rx + 1) % FIFO_SIZE;
if (next_w_ptr != q->r_ptr_rx) {
q->elems_rx[q->w_ptr_rx] = c;
q->w_ptr_rx = next_w_ptr;
}
}
// reset DMA len
DMA2_Stream5->NDTR = USART1_DMA_LEN;
// clear interrupts
DMA2->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5;
//DMA2->HIFCR = DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5;
// enable DMA
DMA2_Stream5->CR |= DMA_SxCR_EN;
q->uart->CR3 |= USART_CR3_DMAR;
}
exit_critical_section();
}
void DMA2_Stream5_IRQHandler(void) {
//set_led(LED_BLUE, 1);
uart_dma_drain();
//set_led(LED_BLUE, 0);
}
void uart_init(USART_TypeDef *u, int baud) { void uart_init(USART_TypeDef *u, int baud) {
// enable uart and tx+rx mode // enable uart and tx+rx mode
u->CR1 = USART_CR1_UE; u->CR1 = USART_CR1_UE;
@ -170,9 +217,23 @@ void uart_init(USART_TypeDef *u, int baud) {
// ** UART is ready to work ** // ** UART is ready to work **
// enable interrupts // enable interrupts
u->CR1 |= USART_CR1_RXNEIE; if (u != USART1) {
u->CR1 |= USART_CR1_RXNEIE;
}
if (u == USART1) { if (u == USART1) {
// DMA2, stream 2, channel 3
DMA2_Stream5->M0AR = (uint32_t)usart1_dma;
DMA2_Stream5->NDTR = USART1_DMA_LEN;
DMA2_Stream5->PAR = (uint32_t)&(USART1->DR);
// channel4, increment memory, periph -> memory, enable
DMA2_Stream5->CR = DMA_SxCR_CHSEL_2 | DMA_SxCR_MINC | DMA_SxCR_HTIE | DMA_SxCR_TCIE | DMA_SxCR_EN;
// this one uses DMA receiver
u->CR3 = USART_CR3_DMAR;
NVIC_EnableIRQ(DMA2_Stream5_IRQn);
NVIC_EnableIRQ(USART1_IRQn); NVIC_EnableIRQ(USART1_IRQn);
} else if (u == USART2) { } else if (u == USART2) {
NVIC_EnableIRQ(USART2_IRQn); NVIC_EnableIRQ(USART2_IRQn);

@ -15,6 +15,7 @@ int has_external_debug_serial = 0;
int is_giant_panda = 0; int is_giant_panda = 0;
int is_entering_bootmode = 0; int is_entering_bootmode = 0;
int revision = PANDA_REV_AB; int revision = PANDA_REV_AB;
int is_grey_panda = 0;
int detect_with_pull(GPIO_TypeDef *GPIO, int pin, int mode) { int detect_with_pull(GPIO_TypeDef *GPIO, int pin, int mode) {
set_gpio_mode(GPIO, pin, MODE_INPUT); set_gpio_mode(GPIO, pin, MODE_INPUT);
@ -45,9 +46,14 @@ void detect() {
// check if the ESP is trying to put me in boot mode // check if the ESP is trying to put me in boot mode
is_entering_bootmode = !detect_with_pull(GPIOB, 0, PULL_UP); is_entering_bootmode = !detect_with_pull(GPIOB, 0, PULL_UP);
// check if it's a grey panda by seeing if the SPI lines are floating
// TODO: is this reliable?
is_grey_panda = !(detect_with_pull(GPIOA, 4, PULL_DOWN) | detect_with_pull(GPIOA, 5, PULL_DOWN) | detect_with_pull(GPIOA, 6, PULL_DOWN) | detect_with_pull(GPIOA, 7, PULL_DOWN));
#else #else
// need to do this for early detect // need to do this for early detect
is_giant_panda = 0; is_giant_panda = 0;
is_grey_panda = 0;
revision = PANDA_REV_AB; revision = PANDA_REV_AB;
is_entering_bootmode = 0; is_entering_bootmode = 0;
#endif #endif

@ -175,6 +175,11 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
puts(" err: "); puth(can_err_cnt); puts(" err: "); puth(can_err_cnt);
puts("\n"); puts("\n");
break; break;
// **** 0xc1: is grey panda
case 0xc1:
resp[0] = is_grey_panda;
resp_len = 1;
break;
// **** 0xd0: fetch serial number // **** 0xd0: fetch serial number
case 0xd0: case 0xd0:
#ifdef PANDA #ifdef PANDA
@ -229,6 +234,8 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
case 0xd9: case 0xd9:
if (setup->b.wValue.w == 1) { if (setup->b.wValue.w == 1) {
set_esp_mode(ESP_ENABLED); set_esp_mode(ESP_ENABLED);
} else if (setup->b.wValue.w == 2) {
set_esp_mode(ESP_BOOTMODE);
} else { } else {
set_esp_mode(ESP_DISABLED); set_esp_mode(ESP_DISABLED);
} }
@ -267,7 +274,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
// and it's blocked over WiFi // and it's blocked over WiFi
// Allow ELM security mode to be set over wifi. // Allow ELM security mode to be set over wifi.
if (hardwired || setup->b.wValue.w == SAFETY_NOOUTPUT || setup->b.wValue.w == SAFETY_ELM327) { if (hardwired || setup->b.wValue.w == SAFETY_NOOUTPUT || setup->b.wValue.w == SAFETY_ELM327) {
safety_set_mode(setup->b.wValue.w); safety_set_mode(setup->b.wValue.w, (int16_t)setup->b.wIndex.w);
switch (setup->b.wValue.w) { switch (setup->b.wValue.w) {
case SAFETY_NOOUTPUT: case SAFETY_NOOUTPUT:
can_silent = ALL_CAN_SILENT; can_silent = ALL_CAN_SILENT;
@ -304,6 +311,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) {
case 0xe0: case 0xe0:
ur = get_ring_by_number(setup->b.wValue.w); ur = get_ring_by_number(setup->b.wValue.w);
if (!ur) break; if (!ur) break;
if (ur == &esp_ring) uart_dma_drain();
// read // read
while ((resp_len < min(setup->b.wLength.w, MAX_RESP_LEN)) && while ((resp_len < min(setup->b.wLength.w, MAX_RESP_LEN)) &&
getc(ur, (char*)&resp[resp_len])) { getc(ur, (char*)&resp[resp_len])) {
@ -489,6 +497,7 @@ int main() {
#endif #endif
puts(has_external_debug_serial ? " real serial\n" : " USB serial\n"); puts(has_external_debug_serial ? " real serial\n" : " USB serial\n");
puts(is_giant_panda ? " GIANTpanda detected\n" : " not GIANTpanda\n"); puts(is_giant_panda ? " GIANTpanda detected\n" : " not GIANTpanda\n");
puts(is_grey_panda ? " gray panda detected!\n" : " white panda\n");
puts(is_entering_bootmode ? " ESP wants bootmode\n" : " no bootmode\n"); puts(is_entering_bootmode ? " ESP wants bootmode\n" : " no bootmode\n");
gpio_init(); gpio_init();
@ -500,9 +509,12 @@ int main() {
} }
#ifdef PANDA #ifdef PANDA
// enable ESP uart if (is_grey_panda) {
uart_init(USART1, 115200); uart_init(USART1, 9600);
} else {
// enable ESP uart
uart_init(USART1, 115200);
}
// enable LIN // enable LIN
uart_init(UART5, 10400); uart_init(UART5, 10400);
UART5->CR2 |= USART_CR2_LINEN; UART5->CR2 |= USART_CR2_LINEN;
@ -522,7 +534,7 @@ int main() {
usb_init(); usb_init();
// default to silent mode to prevent issues with Ford // default to silent mode to prevent issues with Ford
safety_set_mode(SAFETY_NOOUTPUT); safety_set_mode(SAFETY_NOOUTPUT, 0);
can_silent = ALL_CAN_SILENT; can_silent = ALL_CAN_SILENT;
can_init_all(); can_init_all();
@ -552,6 +564,8 @@ int main() {
for (cnt=0;;cnt++) { for (cnt=0;;cnt++) {
can_live = pending_can_live; can_live = pending_can_live;
//puth(usart1_dma); puts(" "); puth(DMA2_Stream5->M0AR); puts(" "); puth(DMA2_Stream5->NDTR); puts("\n");
#ifdef PANDA #ifdef PANDA
int current = adc_get(ADCCHAN_CURRENT); int current = adc_get(ADCCHAN_CURRENT);

@ -2,7 +2,7 @@ void safety_rx_hook(CAN_FIFOMailBox_TypeDef *to_push);
int safety_tx_hook(CAN_FIFOMailBox_TypeDef *to_send); int safety_tx_hook(CAN_FIFOMailBox_TypeDef *to_send);
int safety_tx_lin_hook(int lin_num, uint8_t *data, int len); int safety_tx_lin_hook(int lin_num, uint8_t *data, int len);
typedef void (*safety_hook_init)(); typedef void (*safety_hook_init)(int16_t param);
typedef void (*rx_hook)(CAN_FIFOMailBox_TypeDef *to_push); typedef void (*rx_hook)(CAN_FIFOMailBox_TypeDef *to_push);
typedef int (*tx_hook)(CAN_FIFOMailBox_TypeDef *to_send); 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);
@ -60,11 +60,11 @@ const safety_hook_config safety_hook_registry[] = {
#define HOOK_CONFIG_COUNT (sizeof(safety_hook_registry)/sizeof(safety_hook_config)) #define HOOK_CONFIG_COUNT (sizeof(safety_hook_registry)/sizeof(safety_hook_config))
int safety_set_mode(uint16_t mode) { int safety_set_mode(uint16_t mode, int16_t param) {
for (int i = 0; i < HOOK_CONFIG_COUNT; i++) { for (int i = 0; i < HOOK_CONFIG_COUNT; i++) {
if (safety_hook_registry[i].id == mode) { if (safety_hook_registry[i].id == mode) {
current_hooks = safety_hook_registry[i].hooks; current_hooks = safety_hook_registry[i].hooks;
if (current_hooks->init) current_hooks->init(); if (current_hooks->init) current_hooks->init(param);
return 0; return 0;
} }
} }

@ -2,7 +2,7 @@ void default_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {}
// *** no output safety mode *** // *** no output safety mode ***
static void nooutput_init() { static void nooutput_init(int16_t param) {
controls_allowed = 0; controls_allowed = 0;
} }
@ -23,7 +23,7 @@ const safety_hooks nooutput_hooks = {
// *** all output safety mode *** // *** all output safety mode ***
static void alloutput_init() { static void alloutput_init(int16_t param) {
controls_allowed = 1; controls_allowed = 1;
} }

@ -27,7 +27,7 @@ static int elm327_tx_lin_hook(int lin_num, uint8_t *data, int len) {
return true; return true;
} }
static void elm327_init() { static void elm327_init(int16_t param) {
controls_allowed = 1; controls_allowed = 1;
} }

@ -115,7 +115,7 @@ static int honda_tx_lin_hook(int lin_num, uint8_t *data, int len) {
return true; return true;
} }
static void honda_init() { static void honda_init(int16_t param) {
controls_allowed = 0; controls_allowed = 0;
} }

@ -9,7 +9,7 @@ const int32_t MAX_TORQUE = 1500; // max torque cmd allowed ever
// packet is sent at 100hz, so this limit is 1000/sec // packet is sent at 100hz, so this limit is 1000/sec
const int32_t MAX_RATE_UP = 10; // ramp up slow const int32_t MAX_RATE_UP = 10; // ramp up slow
const int32_t MAX_RATE_DOWN = 25; // ramp down fast const int32_t MAX_RATE_DOWN = 25; // ramp down fast
const int32_t MAX_TORQUE_ERROR = 500; // max torque cmd in excess of torque motor const int32_t MAX_TORQUE_ERROR = 350; // max torque cmd in excess of torque motor
// real time torque limit to prevent controls spamming // real time torque limit to prevent controls spamming
// the real time limit is 1500/sec // the real time limit is 1500/sec
@ -22,6 +22,7 @@ const int16_t MIN_ACCEL = -3000; // 3.0 m/s2
// global actuation limit state // global actuation limit state
int actuation_limits = 1; // by default steer limits are imposed int actuation_limits = 1; // by default steer limits are imposed
int16_t dbc_eps_torque_factor = 100; // conversion factor for STEER_TORQUE_EPS in %: see dbc file
// state of torque limits // state of torque limits
int16_t desired_torque_last = 0; // last desired steer torque int16_t desired_torque_last = 0; // last desired steer torque
@ -31,10 +32,10 @@ uint32_t ts_last = 0;
static void toyota_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { static void toyota_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {
// get eps motor torque (0.66 factor in dbc) // get eps motor torque (0.66 factor in dbc)
if ((to_push->RIR>>21) == 0x260) { if ((to_push->RIR>>21) == 0x260) {
int16_t torque_meas_new = (((to_push->RDHR) & 0xFF00) | ((to_push->RDHR >> 16) & 0xFF)); int torque_meas_new = (((to_push->RDHR) & 0xFF00) | ((to_push->RDHR >> 16) & 0xFF));
// increase torque_meas by 1 to be conservative on rounding // increase torque_meas by 1 to be conservative on rounding
torque_meas_new = (torque_meas_new / 3 + (torque_meas_new > 0 ? 1 : -1)) * 2; torque_meas_new = (torque_meas_new * dbc_eps_torque_factor / 100) + (torque_meas_new > 0 ? 1 : -1);
// shift the array // shift the array
for (int i = sizeof(torque_meas)/sizeof(torque_meas[0]) - 1; i > 0; i--) { for (int i = sizeof(torque_meas)/sizeof(torque_meas[0]) - 1; i > 0; i--) {
@ -154,9 +155,10 @@ static int toyota_tx_lin_hook(int lin_num, uint8_t *data, int len) {
return true; return true;
} }
static void toyota_init() { static void toyota_init(int16_t param) {
controls_allowed = 0; controls_allowed = 0;
actuation_limits = 1; actuation_limits = 1;
dbc_eps_torque_factor = param;
} }
const safety_hooks toyota_hooks = { const safety_hooks toyota_hooks = {
@ -166,9 +168,10 @@ const safety_hooks toyota_hooks = {
.tx_lin = toyota_tx_lin_hook, .tx_lin = toyota_tx_lin_hook,
}; };
static void toyota_nolimits_init() { static void toyota_nolimits_init(int16_t param) {
controls_allowed = 0; controls_allowed = 0;
actuation_limits = 0; actuation_limits = 0;
dbc_eps_torque_factor = param;
} }
const safety_hooks toyota_nolimits_hooks = { const safety_hooks toyota_nolimits_hooks = {

@ -9,7 +9,27 @@ def msg(x):
assert False assert False
return ret.ljust(8, "\x00") return ret.ljust(8, "\x00")
def isotp_send(panda, x, addr, bus=0): kmsgs = []
def recv(panda, cnt, addr, nbus):
global kmsgs
ret = []
while len(ret) < cnt:
kmsgs += panda.can_recv()
nmsgs = []
for ids, ts, dat, bus in kmsgs:
if ids == addr and bus == nbus and len(ret) < cnt:
ret.append(dat)
else:
# leave around
nmsgs.append((ids, ts, dat, bus))
kmsgs = nmsgs[-256:]
return map(str, ret)
def isotp_send(panda, x, addr, bus=0, recvaddr=None):
if recvaddr is None:
recvaddr = addr+8
if len(x) <= 7: if len(x) <= 7:
panda.can_send(addr, msg(x), bus) panda.can_send(addr, msg(x), bus)
else: else:
@ -24,25 +44,9 @@ def isotp_send(panda, x, addr, bus=0):
# actually send # actually send
panda.can_send(addr, ss, bus) panda.can_send(addr, ss, bus)
rr = recv(panda, 1, addr+8, bus)[0] rr = recv(panda, 1, recvaddr, bus)[0]
panda.can_send_many([(addr, None, s, 0) for s in sends]) panda.can_send_many([(addr, None, s, 0) for s in sends])
kmsgs = []
def recv(panda, cnt, addr, nbus):
global kmsgs
ret = []
while len(ret) < cnt:
kmsgs += panda.can_recv()
nmsgs = []
for ids, ts, dat, bus in kmsgs:
if ids == addr and bus == nbus and len(ret) < cnt:
ret.append(dat)
else:
pass
kmsgs = nmsgs
return map(str, ret)
def isotp_recv(panda, addr, bus=0, sendaddr=None): def isotp_recv(panda, addr, bus=0, sendaddr=None):
msg = recv(panda, 1, addr, bus)[0] msg = recv(panda, 1, addr, bus)[0]

@ -18,6 +18,8 @@ __version__ = '0.0.6'
BASEDIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../") BASEDIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../")
DEBUG = os.getenv("PANDADEBUG") is not None
# *** wifi mode *** # *** wifi mode ***
def build_st(target, mkfile="Makefile"): def build_st(target, mkfile="Makefile"):
@ -34,7 +36,10 @@ def parse_can_buffer(dat):
address = f1 >> 3 address = f1 >> 3
else: else:
address = f1 >> 21 address = f1 >> 21
ret.append((address, f2>>16, ddat[8:8+(f2&0xF)], (f2>>4)&0xFF)) dddat = ddat[8:8+(f2&0xF)]
if DEBUG:
print(" R %x: %s" % (address, str(dddat).encode("hex")))
ret.append((address, f2>>16, dddat, (f2>>4)&0xFF))
return ret return ret
class PandaWifiStreaming(object): class PandaWifiStreaming(object):
@ -369,6 +374,8 @@ class Panda(object):
extended = 4 extended = 4
for addr, _, dat, bus in arr: for addr, _, dat, bus in arr:
assert len(dat) <= 8 assert len(dat) <= 8
if DEBUG:
print(" W %x: %s" % (addr, dat.encode("hex")))
if addr >= 0x800: if addr >= 0x800:
rir = (addr << 3) | transmit | extended rir = (addr << 3) | transmit | extended
else: else:
@ -425,7 +432,10 @@ class Panda(object):
return b''.join(ret) return b''.join(ret)
def serial_write(self, port_number, ln): def serial_write(self, port_number, ln):
return self._handle.bulkWrite(2, struct.pack("B", port_number) + ln) ret = 0
for i in range(0, len(ln), 0x20):
ret += self._handle.bulkWrite(2, struct.pack("B", port_number) + ln[i:i+0x20])
return ret
def serial_clear(self, port_number): def serial_clear(self, port_number):
"""Clears all messages (tx and rx) from the specified internal uart """Clears all messages (tx and rx) from the specified internal uart

@ -27,7 +27,6 @@ if __name__ == "__main__":
print ser.read(1024) print ser.read(1024)
# upping baud rate # upping baud rate
# 460800 has issues
baudrate = 460800 baudrate = 460800
print "upping baud rate" print "upping baud rate"

Loading…
Cancel
Save