From e21447765efbe806d0a18158f823aa5628e197ac Mon Sep 17 00:00:00 2001 From: George Hotz Date: Mon, 11 Jun 2018 10:06:10 -0700 Subject: [PATCH] use timer for can bitbanging --- board/drivers/canbitbang.h | 98 +++++++++++++++++++++----------------- board/gpio.h | 2 +- tests/gmbitbang/test.py | 7 +-- 3 files changed, 60 insertions(+), 47 deletions(-) diff --git a/board/drivers/canbitbang.h b/board/drivers/canbitbang.h index 61ea9f3e04c431..77164e26aee390 100644 --- a/board/drivers/canbitbang.h +++ b/board/drivers/canbitbang.h @@ -115,57 +115,69 @@ void set_bitbanged_gmlan(int val) { } } +char pkt_stuffed[MAX_BITS_CAN_PACKET]; +int gmlan_sending = -1; +int gmlan_sendmax = -1; +int gmlan_silent_count = -1; + +void TIM4_IRQHandler(void) { + if (TIM4->SR & TIM_SR_UIF && gmlan_sendmax != -1) { + int read = get_gpio_input(GPIOB, 12); + if (gmlan_silent_count != -1 && gmlan_silent_count < 7) { + if (read == 0) { + gmlan_silent_count = 0; + } else { + gmlan_silent_count++; + } + } else if (gmlan_silent_count == 7) { + // in send loop + if (gmlan_sending > 0 && // not first bit + (read == 0 && pkt_stuffed[gmlan_sending-1] == 1) && // bus wrongly dominant + gmlan_sending != (gmlan_sendmax-11)) { //not ack bit + puts("ERR: bus driven at "); + puth(gmlan_sending); + puts("\n"); + gmlan_sendmax = -1; // exit + } else { + set_bitbanged_gmlan(pkt_stuffed[gmlan_sending]); + gmlan_sending++; + } + if (gmlan_sending == gmlan_sendmax || gmlan_sendmax == -1) { + set_bitbanged_gmlan(1); // recessive + set_gpio_mode(GPIOB, 13, MODE_INPUT); + TIM4->DIER = 0; // no update interrupt + TIM4->CR1 = 0; // disable timer + gmlan_sendmax = -1; // exit + } + } + } + TIM4->SR = 0; +} + void bitbang_gmlan(CAN_FIFOMailBox_TypeDef *to_bang) { - char pkt_stuffed[MAX_BITS_CAN_PACKET]; - int len = get_bit_message(pkt_stuffed, to_bang); + // TODO: make failure less silent + if (gmlan_sendmax != -1) return; - // TODO: interrupts are disabled for a long time... - enter_critical_section(); + int len = get_bit_message(pkt_stuffed, to_bang); + gmlan_silent_count = 0; + gmlan_sending = 0; + gmlan_sendmax = len; - // actual bitbang loop + // setup for bitbang loop set_bitbanged_gmlan(1); // recessive set_gpio_mode(GPIOB, 13, MODE_OUTPUT); - // 33.3 kbps - #define SPEEED 30 + // setup + TIM4->PSC = 48-1; // tick on 1 us + TIM4->CR1 = TIM_CR1_CEN; // enable + TIM4->ARR = 30-1; // 33.3 kbps - // wait for bus silent for 7 frames - int silent_count = 0; - while (silent_count < 7) { - if (silent_count > 0) { - // bit time delay - int lwait = TIM2->CNT; - while (get_ts_elapsed(TIM2->CNT, lwait) < SPEEED); - } - - // check for silent - int read = get_gpio_input(GPIOB, 12); - silent_count++; - if (read == 0) { - silent_count = 0; - } - } + // in case it's disabled + NVIC_EnableIRQ(TIM4_IRQn); - // send my message with optional failure - int last = 1; - int init = TIM2->CNT; - for (int i = 0; i < len; i++) { - while (get_ts_elapsed(TIM2->CNT, init) < (SPEEED*i)); - int read = get_gpio_input(GPIOB, 12); - if ((read == 0 && last == 1) && i != (len-11)) { - puts("ERR: bus driven at "); - puth(i); - puts("\n"); - goto fail; - } - set_bitbanged_gmlan(pkt_stuffed[i]); - last = pkt_stuffed[i]; - } - -fail: - set_bitbanged_gmlan(1); // recessive - set_gpio_mode(GPIOB, 13, MODE_INPUT); - exit_critical_section(); + // run the interrupt + TIM4->DIER = TIM_DIER_UIE; // update interrupt + TIM4->SR = 0; } #endif diff --git a/board/gpio.h b/board/gpio.h index 7b2812e7b4a1e7..6112f6f887c703 100644 --- a/board/gpio.h +++ b/board/gpio.h @@ -119,7 +119,7 @@ void periph_init() { RCC->APB1ENR |= RCC_APB1ENR_DACEN; RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; - //RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; + RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; RCC->APB2ENR |= RCC_APB2ENR_USART1EN; RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN; RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; diff --git a/tests/gmbitbang/test.py b/tests/gmbitbang/test.py index 556be59530d522..652ac1ddd8ad24 100755 --- a/tests/gmbitbang/test.py +++ b/tests/gmbitbang/test.py @@ -22,11 +22,12 @@ #dat = "\x01\x02" dat = "\x01\x02\x03\x04\x05\x06\x07\x08" while 1: + iden += 1 p1.set_gmlan(bus=None) p1.can_send(iden, dat, bus=3) - p1.set_gmlan(bus=2) - p1.can_send(iden, dat, bus=3) + #p1.set_gmlan(bus=2) + #p1.can_send(iden, dat, bus=3) time.sleep(0.01) print p2.can_recv() - exit(0) + #exit(0)