Skip to content

Commit

Permalink
use timer for can bitbanging
Browse files Browse the repository at this point in the history
  • Loading branch information
geohot committed Jun 11, 2018
1 parent cb92733 commit e214477
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 47 deletions.
98 changes: 55 additions & 43 deletions board/drivers/canbitbang.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion board/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
7 changes: 4 additions & 3 deletions tests/gmbitbang/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

0 comments on commit e214477

Please sign in to comment.