-
Notifications
You must be signed in to change notification settings - Fork 9.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #122 from commaai/gmbitbang
Gmbitbang
- Loading branch information
Showing
5 changed files
with
260 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
#define MAX_BITS_CAN_PACKET (64+44+25) | ||
|
||
// returns out_len | ||
int do_bitstuff(char *out, char *in, int in_len) { | ||
int last_bit = -1; | ||
int bit_cnt = 0; | ||
int j = 0; | ||
for (int i = 0; i < in_len; i++) { | ||
char bit = in[i]; | ||
out[j++] = bit; | ||
|
||
// do the stuffing | ||
if (bit == last_bit) { | ||
bit_cnt++; | ||
if (bit_cnt == 5) { | ||
// 5 in a row the same, do stuff | ||
last_bit = !bit; | ||
out[j++] = last_bit; | ||
bit_cnt = 1; | ||
} | ||
} else { | ||
// this is a new bit | ||
last_bit = bit; | ||
bit_cnt = 1; | ||
} | ||
} | ||
return j; | ||
} | ||
|
||
int append_crc(char *in, int in_len) { | ||
int crc = 0; | ||
for (int i = 0; i < in_len; i++) { | ||
crc <<= 1; | ||
if (in[i] ^ ((crc>>15)&1)) { | ||
crc = crc ^ 0x4599; | ||
} | ||
crc &= 0x7fff; | ||
} | ||
for (int i = 14; i >= 0; i--) { | ||
in[in_len++] = (crc>>i)&1; | ||
} | ||
return in_len; | ||
} | ||
|
||
int append_bits(char *in, int in_len, char *app, int app_len) { | ||
for (int i = 0; i < app_len; i++) { | ||
in[in_len++] = app[i]; | ||
} | ||
return in_len; | ||
} | ||
|
||
int append_int(char *in, int in_len, int val, int val_len) { | ||
for (int i = val_len-1; i >= 0; i--) { | ||
in[in_len++] = (val&(1<<i)) != 0; | ||
} | ||
return in_len; | ||
} | ||
|
||
int get_bit_message(char *out, CAN_FIFOMailBox_TypeDef *to_bang) { | ||
char pkt[MAX_BITS_CAN_PACKET]; | ||
char footer[] = { | ||
1, // CRC delimiter | ||
1, // ACK | ||
1, // ACK delimiter | ||
1,1,1,1,1,1,1, // EOF | ||
1,1,1, // IFS | ||
}; | ||
#define SPEEED 30 | ||
|
||
int len = 0; | ||
|
||
// test packet | ||
int dlc_len = to_bang->RDTR & 0xF; | ||
len = append_int(pkt, len, 0, 1); // Start-of-frame | ||
len = append_int(pkt, len, to_bang->RIR >> 21, 11); // Identifier | ||
len = append_int(pkt, len, 0, 3); // RTR+IDE+reserved | ||
len = append_int(pkt, len, dlc_len, 4); // Data length code | ||
|
||
// append data | ||
for (int i = 0; i < dlc_len; i++) { | ||
unsigned char dat = ((unsigned char *)(&(to_bang->RDLR)))[i]; | ||
len = append_int(pkt, len, dat, 8); | ||
} | ||
|
||
// append crc | ||
len = append_crc(pkt, len); | ||
|
||
// do bitstuffing | ||
len = do_bitstuff(out, pkt, len); | ||
|
||
// append footer | ||
len = append_bits(out, len, footer, sizeof(footer)); | ||
return len; | ||
} | ||
|
||
// hardware stuff below this line | ||
|
||
#ifdef PANDA | ||
|
||
void set_bitbanged_gmlan(int val) { | ||
if (val) { | ||
GPIOB->ODR |= (1 << 13); | ||
} else { | ||
GPIOB->ODR &= ~(1 << 13); | ||
} | ||
} | ||
|
||
void bitbang_gmlan(CAN_FIFOMailBox_TypeDef *to_bang) { | ||
puts("called bitbang_gmlan\n"); | ||
|
||
char pkt_stuffed[MAX_BITS_CAN_PACKET]; | ||
int len = get_bit_message(pkt_stuffed, to_bang); | ||
|
||
// actual bitbang loop | ||
set_bitbanged_gmlan(1); // recessive | ||
set_gpio_mode(GPIOB, 13, MODE_OUTPUT); | ||
enter_critical_section(); | ||
|
||
// wait for bus silent for 7 frames | ||
int silent_count = 0; | ||
while (silent_count < 7) { | ||
int read = get_gpio_input(GPIOB, 12); | ||
silent_count++; | ||
if (read == 0) { | ||
silent_count = 0; | ||
} | ||
int lwait = TIM2->CNT; | ||
while (get_ts_elapsed(TIM2->CNT, lwait) < SPEEED); | ||
} | ||
|
||
// 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 | ||
exit_critical_section(); | ||
set_gpio_mode(GPIOB, 13, MODE_INPUT); | ||
|
||
puts("bitbang done\n"); | ||
} | ||
|
||
#endif | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#!/usr/bin/env python | ||
import numpy as np | ||
import visa | ||
import matplotlib.pyplot as plt | ||
|
||
resources = visa.ResourceManager() | ||
print resources.list_resources() | ||
|
||
scope = resources.open_resource('USB0::0x1AB1::0x04CE::DS1ZA184652242::INSTR', timeout=2000, chunk_size=1024000) | ||
print(scope.query('*IDN?').strip()) | ||
|
||
#voltscale = scope.ask_for_values(':CHAN1:SCAL?')[0] | ||
#voltoffset = scope.ask_for_values(":CHAN1:OFFS?")[0] | ||
|
||
#scope.write(":STOP") | ||
scope.write(":WAV:POIN:MODE RAW") | ||
scope.write(":WAV:DATA? CHAN1")[10:] | ||
rawdata = scope.read_raw() | ||
data = np.frombuffer(rawdata, 'B') | ||
print data.shape | ||
|
||
s1 = data[0:650] | ||
s2 = data[650:] | ||
s1i = np.argmax(s1 > 100) | ||
s2i = np.argmax(s2 > 100) | ||
s1 = s1[s1i:] | ||
s2 = s2[s2i:] | ||
|
||
plt.plot(s1) | ||
plt.plot(s2) | ||
plt.show() | ||
#data = (data - 130.0 - voltoffset/voltscale*25) / 25 * voltscale | ||
|
||
print data | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#!/usr/bin/env python | ||
import time | ||
from panda import Panda | ||
|
||
p1 = Panda('430026000951363338383037') | ||
p2 = Panda('380016000551363338383037') | ||
|
||
# this is a test, no safety | ||
p1.set_safety_mode(Panda.SAFETY_ALLOUTPUT) | ||
p2.set_safety_mode(Panda.SAFETY_ALLOUTPUT) | ||
|
||
# get versions | ||
print(p1.get_version()) | ||
print(p2.get_version()) | ||
|
||
# this sets bus 2 to actually be GMLAN | ||
p2.set_gmlan(bus=2) | ||
|
||
# send w bitbang then without | ||
while 1: | ||
p1.set_gmlan(bus=None) | ||
p1.can_send(123, "\x01\x02\x03\x04\x05\x06\x07\x08", bus=3) | ||
p1.set_gmlan(bus=2) | ||
p1.can_send(123, "\x01\x02\x03\x04\x05\x06\x07\x08", bus=3) | ||
time.sleep(0.01) | ||
print p2.can_recv() | ||
exit(0) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#include <stdio.h> | ||
#include <stdint.h> | ||
|
||
typedef struct { | ||
uint32_t RIR; /*!< CAN receive FIFO mailbox identifier register */ | ||
uint32_t RDTR; /*!< CAN receive FIFO mailbox data length control and time stamp register */ | ||
uint32_t RDLR; /*!< CAN receive FIFO mailbox data low register */ | ||
uint32_t RDHR; /*!< CAN receive FIFO mailbox data high register */ | ||
} CAN_FIFOMailBox_TypeDef; | ||
|
||
#include "../../board/drivers/canbitbang.h" | ||
|
||
int main() { | ||
char out[300]; | ||
CAN_FIFOMailBox_TypeDef to_bang = {0}; | ||
to_bang.RIR = 20 << 21; | ||
to_bang.RDTR = 1; | ||
to_bang.RDLR = 1; | ||
|
||
int len = get_bit_message(out, &to_bang); | ||
printf("T:"); | ||
for (int i = 0; i < len; i++) { | ||
printf("%d", out[i]); | ||
} | ||
printf("\n"); | ||
printf("R:0000010010100000100010000010011110111010100111111111111111"); | ||
printf("\n"); | ||
return 0; | ||
} | ||
|
||
|
||
|