From bd09883eee51345a5437434a010bccaa3c979112 Mon Sep 17 00:00:00 2001 From: George Hotz Date: Tue, 27 Feb 2018 20:06:47 -0800 Subject: [PATCH 1/7] comma pedal is building --- board/config.h | 4 + board/drivers/can.h | 4 + board/drivers/drivers.h | 2 +- board/gpio.h | 11 +- board/pedal/.gitignore | 1 + board/pedal/Makefile | 32 ++++++ board/pedal/README | 6 + board/pedal/main.c | 241 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 298 insertions(+), 3 deletions(-) create mode 100644 board/pedal/.gitignore create mode 100644 board/pedal/Makefile create mode 100644 board/pedal/README create mode 100644 board/pedal/main.c diff --git a/board/config.h b/board/config.h index e83429980d4163..b671adab6bcf73 100644 --- a/board/config.h +++ b/board/config.h @@ -14,11 +14,15 @@ #define USB_VID 0xbbaa +#ifdef PEDAL +#define USB_PID 0xdd00 +#else #ifdef BOOTSTUB #define USB_PID 0xddee #else #define USB_PID 0xddcc #endif +#endif #include #define NULL ((void*)0) diff --git a/board/drivers/can.h b/board/drivers/can.h index 39958b03175ef2..da1226f3f3864f 100644 --- a/board/drivers/can.h +++ b/board/drivers/can.h @@ -372,6 +372,8 @@ void can_rx(uint8_t can_number) { } } +#ifndef CUSTOM_CAN_INTERRUPTS + void CAN1_TX_IRQHandler() { process_can(0); } void CAN1_RX0_IRQHandler() { can_rx(0); } void CAN1_SCE_IRQHandler() { can_sce(CAN1); } @@ -386,6 +388,8 @@ void CAN3_RX0_IRQHandler() { can_rx(2); } void CAN3_SCE_IRQHandler() { can_sce(CAN3); } #endif +#endif + void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number) { if (safety_tx_hook(to_push)) { if (bus_number < BUS_MAX) { diff --git a/board/drivers/drivers.h b/board/drivers/drivers.h index ce1e860ceb8a80..d3409d60994eed 100644 --- a/board/drivers/drivers.h +++ b/board/drivers/drivers.h @@ -88,7 +88,7 @@ uint32_t adc_get(int channel); // ********************* DAC ********************* void dac_init(); -uint32_t dac_set(int channel, uint32_t value); +void dac_set(int channel, uint32_t value); // ********************* TIMER ********************* diff --git a/board/gpio.h b/board/gpio.h index 775a88df54c00c..ac3b93612a7d30 100644 --- a/board/gpio.h +++ b/board/gpio.h @@ -72,8 +72,15 @@ void clock_init() { RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLSRC_HSE; #else - RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 | - RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLSRC_HSE; + #ifdef PEDAL + // comma pedal has a 16mhz crystal + RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 | + RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLSRC_HSE; + #else + // NEO board has a 8mhz crystal + RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 | + RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLSRC_HSE; + #endif #endif // start PLL diff --git a/board/pedal/.gitignore b/board/pedal/.gitignore new file mode 100644 index 00000000000000..94053f2925089b --- /dev/null +++ b/board/pedal/.gitignore @@ -0,0 +1 @@ +obj/* diff --git a/board/pedal/Makefile b/board/pedal/Makefile new file mode 100644 index 00000000000000..ed0ccbd3b031fc --- /dev/null +++ b/board/pedal/Makefile @@ -0,0 +1,32 @@ +# :set noet +PROJ_NAME = comma + +CFLAGS = -O2 -Wall -std=gnu11 +CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m3 +CFLAGS += -msoft-float -DSTM32F2 -DSTM32F205xx +CFLAGS += -I ../inc -I ../ -nostdlib +CFLAGS += -T../stm32_flash.ld + +CC = arm-none-eabi-gcc +OBJCOPY = arm-none-eabi-objcopy +OBJDUMP = arm-none-eabi-objdump + +all: obj/$(PROJ_NAME).bin + #$(OBJDUMP) -d obj/$(PROJ_NAME).elf + dfu-util -d 0483:df11 -a 0 -s 0x08000000:leave -D $< + +obj/main.o: main.c ../*.h + mkdir -p obj + $(CC) $(CFLAGS) -o $@ -c $< + +obj/startup_stm32f205xx.o: ../startup_stm32f205xx.s + mkdir -p obj + $(CC) $(CFLAGS) -o $@ -c $< + +obj/$(PROJ_NAME).bin: obj/startup_stm32f205xx.o obj/main.o + $(CC) $(CFLAGS) -o obj/$(PROJ_NAME).elf $^ + $(OBJCOPY) -v -O binary obj/$(PROJ_NAME).elf $@ + +clean: + rm -f obj/* + diff --git a/board/pedal/README b/board/pedal/README new file mode 100644 index 00000000000000..06a386b1e7fe64 --- /dev/null +++ b/board/pedal/README @@ -0,0 +1,6 @@ +This is the firmware for the comma pedal. It borrows a lot from panda. + +The comma pedal is a gas pedal interceptor for Honda/Acura. It allows you to "virtually" press the pedal. + +This is the open source software. Open source hardware coming soon. + diff --git a/board/pedal/main.c b/board/pedal/main.c new file mode 100644 index 00000000000000..8fb45be3dca086 --- /dev/null +++ b/board/pedal/main.c @@ -0,0 +1,241 @@ +//#define DEBUG +//#define CAN_LOOPBACK_MODE +//#define USE_INTERNAL_OSC + +#define PEDAL + +#include "../config.h" + +#include "drivers/drivers.h" + +#include "drivers/llgpio.h" +#include "gpio.h" + +#define CUSTOM_CAN_INTERRUPTS + +#include "libc.h" +#include "safety.h" +#include "drivers/adc.h" +#include "drivers/uart.h" +#include "drivers/dac.h" +#include "drivers/can.h" +#include "drivers/timer.h" + +#define CAN CAN1 + +#define PEDAL_USB + +#ifdef PEDAL_USB + #include "drivers/usb.h" +#endif + +#define ENTER_BOOTLOADER_MAGIC 0xdeadbeef +uint32_t enter_bootloader_mode; + +void __initialize_hardware_early() { + if (enter_bootloader_mode == ENTER_BOOTLOADER_MAGIC) { + enter_bootloader_mode = 0; + void (*bootloader)(void) = (void (*)(void)) (*((uint32_t *)0x1fff0004)); + bootloader(); + + // LOOP + while(1); + } +} + +// ********************* serial debugging ********************* + +void debug_ring_callback(uart_ring *ring) { + char rcv; + while (getc(ring, &rcv)) { + putc(ring, rcv); + } +} + +#ifdef PEDAL_USB + +int usb_cb_ep1_in(uint8_t *usbdata, int len, int hardwired) { return 0; } +void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired) {} +void usb_cb_ep3_out(uint8_t *usbdata, int len, int hardwired) {} +void usb_cb_enumeration_complete() {} + +int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { + int resp_len = 0; + uart_ring *ur = NULL; + switch (setup->b.bRequest) { + // **** 0xe0: uart read + case 0xe0: + ur = get_ring_by_number(setup->b.wValue.w); + if (!ur) break; + if (ur == &esp_ring) uart_dma_drain(); + // read + while ((resp_len < min(setup->b.wLength.w, MAX_RESP_LEN)) && + getc(ur, (char*)&resp[resp_len])) { + ++resp_len; + } + break; + } + return resp_len; +} + +#endif + +// ***************************** honda can checksum ***************************** + +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; +} + +// ***************************** can port ***************************** + +// addresses to be used on CAN +#define CAN_GAS_INPUT 0x200 +#define CAN_GAS_OUTPUT 0x201 + +void CAN1_TX_IRQHandler() { + // clear interrupt + CAN->TSR |= CAN_TSR_RQCP0; +} + +uint16_t gas_set = 0; +uint32_t timeout = 0; +uint32_t current_index = 0; + +void CAN1_RX0_IRQHandler() { + while (CAN->RF0R & CAN_RF0R_FMP0) { + #ifdef DEBUG + puts("CAN RX\n"); + #endif + uint32_t address = CAN->sFIFOMailBox[0].RIR>>21; + if (address == CAN_GAS_INPUT) { + uint8_t *dat = (uint8_t *)&CAN->sFIFOMailBox[0].RDLR; + uint16_t value = (dat[0] << 8) | dat[1]; + uint8_t index = (dat[2] >> 4) & 3; + if (can_cksum(dat, 2, CAN_GAS_INPUT, index) == (dat[2] & 0xF)) { + if (((current_index+1)&3) == index) { + // TODO: set and start timeout + #ifdef DEBUG + puts("setting gas "); + puth(value); + puts("\n"); + #endif + gas_set = value; + timeout = 0; + } + // TODO: better lockout? prevents same spam + current_index = index; + } + } + // next + CAN->RF0R |= CAN_RF0R_RFOM0; + } +} + +void CAN1_SCE_IRQHandler() { + can_sce(CAN); +} + +int pdl0, pdl1; +int pkt_idx = 0; + +void TIM3_IRQHandler() { + #ifdef DEBUG + puth(TIM3->CNT); + puts(" "); + puth(pdl0); + puts(" "); + puth(pdl1); + puts("\n"); + #endif + + // check timer for sending the user pedal and clearing the CAN + if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) { + uint8_t *dat = (uint8_t *)&CAN->sTxMailBox[0].TDLR; + CAN->sTxMailBox[0].TDLR = (((pdl0>>8)&0xFF)<<0) | + (((pdl0>>0)&0xFF)<<8) | + (((pdl1>>8)&0xFF)<<16) | + (((pdl1>>0)&0xFF)<<24); + CAN->sTxMailBox[0].TDHR = can_cksum(dat, 4, CAN_GAS_OUTPUT, pkt_idx) | (pkt_idx << 4); + CAN->sTxMailBox[0].TDTR = 5; // len of packet is 4 + CAN->sTxMailBox[0].TIR = (CAN_GAS_OUTPUT << 21) | 1; + ++pkt_idx; + pkt_idx &= 3; + } else { + // old can packet hasn't sent! + // TODO: do something? + #ifdef DEBUG + puts("CAN MISS\n"); + #endif + } + + + // blink the other LED + GPIOB->ODR |= (1 << 11); + + TIM3->SR = 0; + + // up timeout for gas set + timeout++; +} + +// ***************************** main code ***************************** + +void pedal() { + // read/write + pdl0 = adc_get(ADCCHAN_ACCEL0); + pdl1 = adc_get(ADCCHAN_ACCEL1); + + // write the pedal to the DAC + if (timeout < 10) { + dac_set(0, max(gas_set, pdl0)); + dac_set(1, max(gas_set*2, pdl1)); + } else { + dac_set(0, pdl0); + dac_set(1, pdl1); + } +} + +int main() { + // init devices + clock_init(); + gpio_init(); + + // pedal stuff + dac_init(); + can_init(1); + adc_init(); + + // 48mhz / 65536 ~= 732 + timer_init(TIM3, 15); + + puts("**** INTERRUPTS ON ****\n"); + __disable_irq(); + + NVIC_EnableIRQ(CAN1_TX_IRQn); + NVIC_EnableIRQ(CAN1_RX0_IRQn); + NVIC_EnableIRQ(CAN1_SCE_IRQn); + + NVIC_EnableIRQ(TIM3_IRQn); + __enable_irq(); + + // main pedal loop + uint64_t cnt = 0; + for (cnt=0;;cnt++) { + pedal(); + set_led(LED_GREEN, (cnt&0xFFFF) < 0x8000); + } + + return 0; +} + From 8d4d7631469f2f5b9db0557314fa30a6b940e140 Mon Sep 17 00:00:00 2001 From: George Hotz Date: Tue, 27 Feb 2018 20:14:27 -0800 Subject: [PATCH 2/7] debug console works --- board/config.h | 4 ---- board/gpio.h | 3 ++- board/pedal/main.c | 15 +++++++++++---- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/board/config.h b/board/config.h index b671adab6bcf73..e83429980d4163 100644 --- a/board/config.h +++ b/board/config.h @@ -14,15 +14,11 @@ #define USB_VID 0xbbaa -#ifdef PEDAL -#define USB_PID 0xdd00 -#else #ifdef BOOTSTUB #define USB_PID 0xddee #else #define USB_PID 0xddcc #endif -#endif #include #define NULL ((void*)0) diff --git a/board/gpio.h b/board/gpio.h index ac3b93612a7d30..dd96f16d88afa9 100644 --- a/board/gpio.h +++ b/board/gpio.h @@ -450,9 +450,10 @@ void early() { if (enter_bootloader_mode == ENTER_BOOTLOADER_MAGIC) { + #ifdef PANDA set_esp_mode(ESP_DISABLED); + #endif set_led(LED_GREEN, 1); - jump_to_bootloader(); } diff --git a/board/pedal/main.c b/board/pedal/main.c index 8fb45be3dca086..e4415164cd460a 100644 --- a/board/pedal/main.c +++ b/board/pedal/main.c @@ -7,7 +7,6 @@ #include "../config.h" #include "drivers/drivers.h" - #include "drivers/llgpio.h" #include "gpio.h" @@ -207,10 +206,18 @@ void pedal() { } int main() { + __disable_irq(); + // init devices clock_init(); + periph_init(); gpio_init(); +#ifdef PEDAL_USB + // enable USB + usb_init(); +#endif + // pedal stuff dac_init(); can_init(1); @@ -219,14 +226,14 @@ int main() { // 48mhz / 65536 ~= 732 timer_init(TIM3, 15); - puts("**** INTERRUPTS ON ****\n"); - __disable_irq(); - + // needed? NVIC_EnableIRQ(CAN1_TX_IRQn); NVIC_EnableIRQ(CAN1_RX0_IRQn); NVIC_EnableIRQ(CAN1_SCE_IRQn); NVIC_EnableIRQ(TIM3_IRQn); + + puts("**** INTERRUPTS ON ****\n"); __enable_irq(); // main pedal loop From ccaa310b687c5b268dac50a73294416e8f9921fa Mon Sep 17 00:00:00 2001 From: George Hotz Date: Tue, 27 Feb 2018 21:35:42 -0800 Subject: [PATCH 3/7] don't build with usb --- board/pedal/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/pedal/main.c b/board/pedal/main.c index e4415164cd460a..1082f135e7afb5 100644 --- a/board/pedal/main.c +++ b/board/pedal/main.c @@ -22,7 +22,7 @@ #define CAN CAN1 -#define PEDAL_USB +//#define PEDAL_USB #ifdef PEDAL_USB #include "drivers/usb.h" From eb1fd75cb97e261db9088fd6dadebeb0b9571091 Mon Sep 17 00:00:00 2001 From: George Hotz Date: Tue, 27 Feb 2018 21:42:24 -0800 Subject: [PATCH 4/7] add PEDAL adc sets --- board/gpio.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/board/gpio.h b/board/gpio.h index dd96f16d88afa9..13eddfccb79b42 100644 --- a/board/gpio.h +++ b/board/gpio.h @@ -292,6 +292,14 @@ void gpio_init() { set_gpio_mode(GPIOC, 2, MODE_ANALOG); set_gpio_mode(GPIOC, 3, MODE_ANALOG); +#ifdef PEDAL + // comma pedal has inputs on C0 and C1 + set_gpio_mode(GPIOC, 0, MODE_ANALOG); + set_gpio_mode(GPIOC, 1, MODE_ANALOG); + // DAC outputs on A4 and A5 + // apparently they don't need GPIO setup +#endif + // C8: FAN aka TIM3_CH4 set_gpio_alternate(GPIOC, 8, GPIO_AF2_TIM3); From 631ea9f246d3c3d8b92aac077de197fd573fe61c Mon Sep 17 00:00:00 2001 From: George Hotz Date: Tue, 27 Feb 2018 21:49:38 -0800 Subject: [PATCH 5/7] better refactor --- board/pedal/main.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/board/pedal/main.c b/board/pedal/main.c index 1082f135e7afb5..1128a7d8f27ce8 100644 --- a/board/pedal/main.c +++ b/board/pedal/main.c @@ -148,6 +148,8 @@ void CAN1_SCE_IRQHandler() { int pdl0, pdl1; int pkt_idx = 0; +int led_value = 0; + void TIM3_IRQHandler() { #ifdef DEBUG puth(TIM3->CNT); @@ -179,8 +181,9 @@ void TIM3_IRQHandler() { } - // blink the other LED - GPIOB->ODR |= (1 << 11); + // blink the LED + set_led(LED_GREEN, led_value); + led_value = !led_value; TIM3->SR = 0; @@ -237,10 +240,8 @@ int main() { __enable_irq(); // main pedal loop - uint64_t cnt = 0; - for (cnt=0;;cnt++) { + while (1) { pedal(); - set_led(LED_GREEN, (cnt&0xFFFF) < 0x8000); } return 0; From aa622bcef2089bbdd42def24b4033a33d10449bf Mon Sep 17 00:00:00 2001 From: George Hotz Date: Tue, 27 Feb 2018 21:51:50 -0800 Subject: [PATCH 6/7] init values --- board/pedal/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/pedal/main.c b/board/pedal/main.c index 1128a7d8f27ce8..4836ad7e0e715e 100644 --- a/board/pedal/main.c +++ b/board/pedal/main.c @@ -145,7 +145,7 @@ void CAN1_SCE_IRQHandler() { can_sce(CAN); } -int pdl0, pdl1; +int pdl0 = 0, pdl1 = 0; int pkt_idx = 0; int led_value = 0; From 8a6f44bb0797d1885c25c41fbe38b652743c6347 Mon Sep 17 00:00:00 2001 From: Firmware Batman Date: Thu, 1 Mar 2018 10:55:02 -0800 Subject: [PATCH 7/7] pedal is sending messages --- board/gpio.h | 9 +++++++-- board/pedal/main.c | 5 ++++- tests/can_printer.py | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/board/gpio.h b/board/gpio.h index 13eddfccb79b42..7b2812e7b4a1e7 100644 --- a/board/gpio.h +++ b/board/gpio.h @@ -139,8 +139,13 @@ void set_can_enable(CAN_TypeDef *CAN, int enabled) { // CAN1_EN set_gpio_output(GPIOC, 1, !enabled); #else - // CAN1_EN - set_gpio_output(GPIOB, 3, enabled); + #ifdef PEDAL + // CAN1_EN (not flipped) + set_gpio_output(GPIOB, 3, !enabled); + #else + // CAN1_EN + set_gpio_output(GPIOB, 3, enabled); + #endif #endif } else if (CAN == CAN2) { #ifdef PANDA diff --git a/board/pedal/main.c b/board/pedal/main.c index 4836ad7e0e715e..d49f04601778f1 100644 --- a/board/pedal/main.c +++ b/board/pedal/main.c @@ -223,9 +223,12 @@ int main() { // pedal stuff dac_init(); - can_init(1); adc_init(); + // init can + can_silent = ALL_CAN_LIVE; + can_init_all(); + // 48mhz / 65536 ~= 732 timer_init(TIM3, 15); diff --git a/tests/can_printer.py b/tests/can_printer.py index a74a548109269b..fe1ea42e79d4f4 100755 --- a/tests/can_printer.py +++ b/tests/can_printer.py @@ -28,7 +28,7 @@ def can_printer(): if sec_since_boot() - lp > 0.1: dd = chr(27) + "[2J" dd += "%5.2f\n" % (sec_since_boot() - start) - for k,v in sorted(zip(msgs.keys(), map(lambda x: x[-1].encode("hex"), msgs.values()))): + for k,v in sorted(zip(msgs.keys(), map(lambda x: str(x[-1]).encode("hex"), msgs.values()))): dd += "%s(%6d) %s\n" % ("%04X(%4d)" % (k,k),len(msgs[k]), v) print(dd) lp = sec_since_boot()