Skip to content

Commit e214477

Browse files
committed
use timer for can bitbanging
1 parent cb92733 commit e214477

File tree

3 files changed

+60
-47
lines changed

3 files changed

+60
-47
lines changed

board/drivers/canbitbang.h

+55-43
Original file line numberDiff line numberDiff line change
@@ -115,57 +115,69 @@ void set_bitbanged_gmlan(int val) {
115115
}
116116
}
117117

118+
char pkt_stuffed[MAX_BITS_CAN_PACKET];
119+
int gmlan_sending = -1;
120+
int gmlan_sendmax = -1;
121+
int gmlan_silent_count = -1;
122+
123+
void TIM4_IRQHandler(void) {
124+
if (TIM4->SR & TIM_SR_UIF && gmlan_sendmax != -1) {
125+
int read = get_gpio_input(GPIOB, 12);
126+
if (gmlan_silent_count != -1 && gmlan_silent_count < 7) {
127+
if (read == 0) {
128+
gmlan_silent_count = 0;
129+
} else {
130+
gmlan_silent_count++;
131+
}
132+
} else if (gmlan_silent_count == 7) {
133+
// in send loop
134+
if (gmlan_sending > 0 && // not first bit
135+
(read == 0 && pkt_stuffed[gmlan_sending-1] == 1) && // bus wrongly dominant
136+
gmlan_sending != (gmlan_sendmax-11)) { //not ack bit
137+
puts("ERR: bus driven at ");
138+
puth(gmlan_sending);
139+
puts("\n");
140+
gmlan_sendmax = -1; // exit
141+
} else {
142+
set_bitbanged_gmlan(pkt_stuffed[gmlan_sending]);
143+
gmlan_sending++;
144+
}
145+
if (gmlan_sending == gmlan_sendmax || gmlan_sendmax == -1) {
146+
set_bitbanged_gmlan(1); // recessive
147+
set_gpio_mode(GPIOB, 13, MODE_INPUT);
148+
TIM4->DIER = 0; // no update interrupt
149+
TIM4->CR1 = 0; // disable timer
150+
gmlan_sendmax = -1; // exit
151+
}
152+
}
153+
}
154+
TIM4->SR = 0;
155+
}
156+
118157
void bitbang_gmlan(CAN_FIFOMailBox_TypeDef *to_bang) {
119-
char pkt_stuffed[MAX_BITS_CAN_PACKET];
120-
int len = get_bit_message(pkt_stuffed, to_bang);
158+
// TODO: make failure less silent
159+
if (gmlan_sendmax != -1) return;
121160

122-
// TODO: interrupts are disabled for a long time...
123-
enter_critical_section();
161+
int len = get_bit_message(pkt_stuffed, to_bang);
162+
gmlan_silent_count = 0;
163+
gmlan_sending = 0;
164+
gmlan_sendmax = len;
124165

125-
// actual bitbang loop
166+
// setup for bitbang loop
126167
set_bitbanged_gmlan(1); // recessive
127168
set_gpio_mode(GPIOB, 13, MODE_OUTPUT);
128169

129-
// 33.3 kbps
130-
#define SPEEED 30
170+
// setup
171+
TIM4->PSC = 48-1; // tick on 1 us
172+
TIM4->CR1 = TIM_CR1_CEN; // enable
173+
TIM4->ARR = 30-1; // 33.3 kbps
131174

132-
// wait for bus silent for 7 frames
133-
int silent_count = 0;
134-
while (silent_count < 7) {
135-
if (silent_count > 0) {
136-
// bit time delay
137-
int lwait = TIM2->CNT;
138-
while (get_ts_elapsed(TIM2->CNT, lwait) < SPEEED);
139-
}
140-
141-
// check for silent
142-
int read = get_gpio_input(GPIOB, 12);
143-
silent_count++;
144-
if (read == 0) {
145-
silent_count = 0;
146-
}
147-
}
175+
// in case it's disabled
176+
NVIC_EnableIRQ(TIM4_IRQn);
148177

149-
// send my message with optional failure
150-
int last = 1;
151-
int init = TIM2->CNT;
152-
for (int i = 0; i < len; i++) {
153-
while (get_ts_elapsed(TIM2->CNT, init) < (SPEEED*i));
154-
int read = get_gpio_input(GPIOB, 12);
155-
if ((read == 0 && last == 1) && i != (len-11)) {
156-
puts("ERR: bus driven at ");
157-
puth(i);
158-
puts("\n");
159-
goto fail;
160-
}
161-
set_bitbanged_gmlan(pkt_stuffed[i]);
162-
last = pkt_stuffed[i];
163-
}
164-
165-
fail:
166-
set_bitbanged_gmlan(1); // recessive
167-
set_gpio_mode(GPIOB, 13, MODE_INPUT);
168-
exit_critical_section();
178+
// run the interrupt
179+
TIM4->DIER = TIM_DIER_UIE; // update interrupt
180+
TIM4->SR = 0;
169181
}
170182

171183
#endif

board/gpio.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ void periph_init() {
119119
RCC->APB1ENR |= RCC_APB1ENR_DACEN;
120120
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
121121
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
122-
//RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
122+
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
123123
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
124124
RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
125125
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;

tests/gmbitbang/test.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@
2222
#dat = "\x01\x02"
2323
dat = "\x01\x02\x03\x04\x05\x06\x07\x08"
2424
while 1:
25+
iden += 1
2526
p1.set_gmlan(bus=None)
2627
p1.can_send(iden, dat, bus=3)
27-
p1.set_gmlan(bus=2)
28-
p1.can_send(iden, dat, bus=3)
28+
#p1.set_gmlan(bus=2)
29+
#p1.can_send(iden, dat, bus=3)
2930
time.sleep(0.01)
3031
print p2.can_recv()
31-
exit(0)
32+
#exit(0)
3233

0 commit comments

Comments
 (0)