use timer for can bitbanging

This commit is contained in:
George Hotz 2018-06-11 10:06:10 -07:00
parent cb927337da
commit e21447765e
3 changed files with 60 additions and 47 deletions

View File

@ -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];
// TODO: make failure less silent
if (gmlan_sendmax != -1) return;
int len = get_bit_message(pkt_stuffed, to_bang);
gmlan_silent_count = 0;
gmlan_sending = 0;
gmlan_sendmax = len;
// TODO: interrupts are disabled for a long time...
enter_critical_section();
// 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);
}
// in case it's disabled
NVIC_EnableIRQ(TIM4_IRQn);
// check for silent
int read = get_gpio_input(GPIOB, 12);
silent_count++;
if (read == 0) {
silent_count = 0;
}
}
// 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

View File

@ -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;

View File

@ -22,11 +22,12 @@ iden = 18000
#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)