b058c14 add build step for legacy board to CI
866dd85 Fix README (#133)
c2a0853 Hyundai safety: 593 also needs ot be modified
594863c Hyundai: added initial safety files which just fwd bus 0 to 2 and viceversa, except for lkas msgs
905a935 fixed pedal and legacy board builds: no float support
0a480ec moved interpolate function to safety header
d7bd473 Merge pull request #131 from appleguru/master
c0b1ef2 Example to get wifi password from panda over USB using python library
01c0383 Merge pull request #128 from appleguru/gmlan_gpio
f9a46e3 Match safety order from master
aafbe05 GMLAN GPIO Rebase
37df290 rename to gmlan_alt
git-subtree-dir: panda
git-subtree-split: b058c145709a93d56fbe764701962e7d97344ecf
old-commit-hash: c812915765
			
			
				commatwo_master
			
			
		
							parent
							
								
									bd445276f7
								
							
						
					
					
						commit
						ad3d504e3a
					
				
				 10 changed files with 386 additions and 242 deletions
			
			
		| @ -1,203 +0,0 @@ | |||||||
| #define MAX_BITS_CAN_PACKET (200) |  | ||||||
| 
 |  | ||||||
| // 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
 |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   int len = 0; |  | ||||||
| 
 |  | ||||||
|   // test packet
 |  | ||||||
|   int dlc_len = to_bang->RDTR & 0xF; |  | ||||||
|   len = append_int(pkt, len, 0, 1);    // Start-of-frame
 |  | ||||||
|   
 |  | ||||||
|   if (to_bang->RIR & 4) { |  | ||||||
|     // extended identifier
 |  | ||||||
|     len = append_int(pkt, len, to_bang->RIR >> 21, 11);  // Identifier
 |  | ||||||
|     len = append_int(pkt, len, 3, 2);    // SRR+IDE
 |  | ||||||
|     len = append_int(pkt, len, (to_bang->RIR >> 3) & ((1<<18)-1), 18);  // Identifier
 |  | ||||||
|     len = append_int(pkt, len, 0, 3);    // RTR+r1+r0
 |  | ||||||
|   } else { |  | ||||||
|     // standard identifier
 |  | ||||||
|     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); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| char pkt_stuffed[MAX_BITS_CAN_PACKET]; |  | ||||||
| int gmlan_sending = -1; |  | ||||||
| int gmlan_sendmax = -1; |  | ||||||
| 
 |  | ||||||
| int gmlan_silent_count = 0; |  | ||||||
| int gmlan_fail_count = 0; |  | ||||||
| #define REQUIRED_SILENT_TIME 10 |  | ||||||
| #define MAX_FAIL_COUNT 10 |  | ||||||
| 
 |  | ||||||
| void TIM4_IRQHandler(void) { |  | ||||||
|   if (TIM4->SR & TIM_SR_UIF && gmlan_sendmax != -1) { |  | ||||||
|     int read = get_gpio_input(GPIOB, 12); |  | ||||||
|     if (gmlan_silent_count < REQUIRED_SILENT_TIME) { |  | ||||||
|       if (read == 0) { |  | ||||||
|         gmlan_silent_count = 0; |  | ||||||
|       } else { |  | ||||||
|         gmlan_silent_count++; |  | ||||||
|       } |  | ||||||
|     } else if (gmlan_silent_count == REQUIRED_SILENT_TIME) { |  | ||||||
|       int retry = 0; |  | ||||||
|       // 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("GMLAN ERR: bus driven at "); |  | ||||||
|         puth(gmlan_sending); |  | ||||||
|         puts("\n"); |  | ||||||
|         retry = 1; |  | ||||||
|       } else if (read == 1 && gmlan_sending == (gmlan_sendmax-11)) {    // recessive during ACK
 |  | ||||||
|         puts("GMLAN ERR: didn't recv ACK\n"); |  | ||||||
|         retry = 1; |  | ||||||
|       } |  | ||||||
|       if (retry) { |  | ||||||
|         // reset sender (retry after 7 silent)
 |  | ||||||
|         set_bitbanged_gmlan(1); // recessive
 |  | ||||||
|         gmlan_silent_count = 0; |  | ||||||
|         gmlan_sending = 0; |  | ||||||
|         gmlan_fail_count++; |  | ||||||
|         if (gmlan_fail_count == MAX_FAIL_COUNT) { |  | ||||||
|           puts("GMLAN ERR: giving up send\n"); |  | ||||||
|         } |  | ||||||
|       } else { |  | ||||||
|         set_bitbanged_gmlan(pkt_stuffed[gmlan_sending]); |  | ||||||
|         gmlan_sending++; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     if (gmlan_sending == gmlan_sendmax || gmlan_fail_count == MAX_FAIL_COUNT) { |  | ||||||
|       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) { |  | ||||||
|   // TODO: make failure less silent
 |  | ||||||
|   if (gmlan_sendmax != -1) return; |  | ||||||
| 
 |  | ||||||
|   int len = get_bit_message(pkt_stuffed, to_bang); |  | ||||||
|   gmlan_fail_count = 0; |  | ||||||
|   gmlan_silent_count = 0; |  | ||||||
|   gmlan_sending = 0; |  | ||||||
|   gmlan_sendmax = len; |  | ||||||
| 
 |  | ||||||
|   // setup for bitbang loop
 |  | ||||||
|   set_bitbanged_gmlan(1); // recessive
 |  | ||||||
|   set_gpio_mode(GPIOB, 13, MODE_OUTPUT); |  | ||||||
| 
 |  | ||||||
|   // setup
 |  | ||||||
|   TIM4->PSC = 48-1;          // tick on 1 us
 |  | ||||||
|   TIM4->CR1 = TIM_CR1_CEN;   // enable
 |  | ||||||
|   TIM4->ARR = 30-1;          // 33.3 kbps
 |  | ||||||
| 
 |  | ||||||
|   // in case it's disabled
 |  | ||||||
|   NVIC_EnableIRQ(TIM4_IRQn); |  | ||||||
| 
 |  | ||||||
|   // run the interrupt
 |  | ||||||
|   TIM4->DIER = TIM_DIER_UIE; // update interrupt
 |  | ||||||
|   TIM4->SR = 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| @ -0,0 +1,276 @@ | |||||||
|  | #define GMLAN_TICKS_PER_SECOND 33300 //1sec @ 33.3kbps
 | ||||||
|  | #define GMLAN_TICKS_PER_TIMEOUT_TICKLE 500 //15ms @ 33.3kbps
 | ||||||
|  | #define GMLAN_HIGH 0 //0 is high on bus (dominant)
 | ||||||
|  | #define GMLAN_LOW 1 //1 is low on bus
 | ||||||
|  | 
 | ||||||
|  | #define DISABLED -1 | ||||||
|  | #define BITBANG 0 | ||||||
|  | #define GPIO_SWITCH 1 | ||||||
|  | 
 | ||||||
|  | #define MAX_BITS_CAN_PACKET (200) | ||||||
|  | 
 | ||||||
|  | int gmlan_alt_mode = DISABLED; 
 | ||||||
|  | 
 | ||||||
|  | // 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
 | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   int len = 0; | ||||||
|  | 
 | ||||||
|  |   // test packet
 | ||||||
|  |   int dlc_len = to_bang->RDTR & 0xF; | ||||||
|  |   len = append_int(pkt, len, 0, 1);    // Start-of-frame
 | ||||||
|  |   
 | ||||||
|  |   if (to_bang->RIR & 4) { | ||||||
|  |     // extended identifier
 | ||||||
|  |     len = append_int(pkt, len, to_bang->RIR >> 21, 11);  // Identifier
 | ||||||
|  |     len = append_int(pkt, len, 3, 2);    // SRR+IDE
 | ||||||
|  |     len = append_int(pkt, len, (to_bang->RIR >> 3) & ((1<<18)-1), 18);  // Identifier
 | ||||||
|  |     len = append_int(pkt, len, 0, 3);    // RTR+r1+r0
 | ||||||
|  |   } else { | ||||||
|  |     // standard identifier
 | ||||||
|  |     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; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #ifdef PANDA | ||||||
|  | 
 | ||||||
|  | void setup_timer4() { | ||||||
|  |   // setup
 | ||||||
|  |   TIM4->PSC = 48-1;          // tick on 1 us
 | ||||||
|  |   TIM4->CR1 = TIM_CR1_CEN;   // enable
 | ||||||
|  |   TIM4->ARR = 30-1;          // 33.3 kbps
 | ||||||
|  | 
 | ||||||
|  |   // in case it's disabled
 | ||||||
|  |   NVIC_EnableIRQ(TIM4_IRQn); | ||||||
|  | 
 | ||||||
|  |   // run the interrupt
 | ||||||
|  |   TIM4->DIER = TIM_DIER_UIE; // update interrupt
 | ||||||
|  |   TIM4->SR = 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int gmlan_timeout_counter = GMLAN_TICKS_PER_TIMEOUT_TICKLE; //GMLAN transceiver times out every 17ms held high; tickle every 15ms
 | ||||||
|  | int can_timeout_counter = GMLAN_TICKS_PER_SECOND; //1 second
 | ||||||
|  | 
 | ||||||
|  | int inverted_bit_to_send = GMLAN_HIGH; 
 | ||||||
|  | int gmlan_switch_below_timeout = -1; | ||||||
|  | int gmlan_switch_timeout_enable = 0; | ||||||
|  | 
 | ||||||
|  | void gmlan_switch_init(int timeout_enable) { | ||||||
|  |   gmlan_switch_timeout_enable = timeout_enable; | ||||||
|  |   gmlan_alt_mode = GPIO_SWITCH; | ||||||
|  |   gmlan_switch_below_timeout = 1; | ||||||
|  |   set_gpio_mode(GPIOB, 13, MODE_OUTPUT); | ||||||
|  |   
 | ||||||
|  |   setup_timer4(); | ||||||
|  |   
 | ||||||
|  |   inverted_bit_to_send = GMLAN_LOW; //We got initialized, set the output low
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void set_gmlan_digital_output(int to_set) { | ||||||
|  |   inverted_bit_to_send = to_set; | ||||||
|  |   /*
 | ||||||
|  |   puts("Writing "); | ||||||
|  |   puth(inverted_bit_to_send); | ||||||
|  |   puts("\n"); | ||||||
|  |   */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void reset_gmlan_switch_timeout(void) { | ||||||
|  |   can_timeout_counter = GMLAN_TICKS_PER_SECOND; | ||||||
|  |   gmlan_switch_below_timeout = 1; | ||||||
|  |   gmlan_alt_mode = GPIO_SWITCH; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void set_bitbanged_gmlan(int val) { | ||||||
|  |   if (val) { | ||||||
|  |     GPIOB->ODR |= (1 << 13); | ||||||
|  |   } else { | ||||||
|  |     GPIOB->ODR &= ~(1 << 13); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char pkt_stuffed[MAX_BITS_CAN_PACKET]; | ||||||
|  | int gmlan_sending = -1; | ||||||
|  | int gmlan_sendmax = -1; | ||||||
|  | 
 | ||||||
|  | int gmlan_silent_count = 0; | ||||||
|  | int gmlan_fail_count = 0; | ||||||
|  | #define REQUIRED_SILENT_TIME 10 | ||||||
|  | #define MAX_FAIL_COUNT 10 | ||||||
|  | 
 | ||||||
|  | void TIM4_IRQHandler(void) { | ||||||
|  |   if (gmlan_alt_mode == BITBANG) { | ||||||
|  |     if (TIM4->SR & TIM_SR_UIF && gmlan_sendmax != -1) { | ||||||
|  |       int read = get_gpio_input(GPIOB, 12); | ||||||
|  |       if (gmlan_silent_count < REQUIRED_SILENT_TIME) { | ||||||
|  |         if (read == 0) { | ||||||
|  |           gmlan_silent_count = 0; | ||||||
|  |         } else { | ||||||
|  |           gmlan_silent_count++; | ||||||
|  |         } | ||||||
|  |       } else if (gmlan_silent_count == REQUIRED_SILENT_TIME) { | ||||||
|  |         int retry = 0; | ||||||
|  |         // 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("GMLAN ERR: bus driven at "); | ||||||
|  |           puth(gmlan_sending); | ||||||
|  |           puts("\n"); | ||||||
|  |           retry = 1; | ||||||
|  |         } else if (read == 1 && gmlan_sending == (gmlan_sendmax-11)) {    // recessive during ACK
 | ||||||
|  |           puts("GMLAN ERR: didn't recv ACK\n"); | ||||||
|  |           retry = 1; | ||||||
|  |         } | ||||||
|  |         if (retry) { | ||||||
|  |           // reset sender (retry after 7 silent)
 | ||||||
|  |           set_bitbanged_gmlan(1); // recessive
 | ||||||
|  |           gmlan_silent_count = 0; | ||||||
|  |           gmlan_sending = 0; | ||||||
|  |           gmlan_fail_count++; | ||||||
|  |           if (gmlan_fail_count == MAX_FAIL_COUNT) { | ||||||
|  |             puts("GMLAN ERR: giving up send\n"); | ||||||
|  |           } | ||||||
|  |         } else { | ||||||
|  |           set_bitbanged_gmlan(pkt_stuffed[gmlan_sending]); | ||||||
|  |           gmlan_sending++; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       if (gmlan_sending == gmlan_sendmax || gmlan_fail_count == MAX_FAIL_COUNT) { | ||||||
|  |         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; | ||||||
|  |   } //bit bang mode
 | ||||||
|  | 
 | ||||||
|  |   else if (gmlan_alt_mode == GPIO_SWITCH) { | ||||||
|  |     if (TIM4->SR & TIM_SR_UIF && gmlan_switch_below_timeout != -1) { | ||||||
|  |       if (can_timeout_counter == 0 && gmlan_switch_timeout_enable) { | ||||||
|  |         //it has been more than 1 second since timeout was reset; disable timer and restore the GMLAN output
 | ||||||
|  |         set_gpio_output(GPIOB, 13, GMLAN_LOW); | ||||||
|  |         gmlan_switch_below_timeout = -1; | ||||||
|  |         gmlan_timeout_counter = GMLAN_TICKS_PER_TIMEOUT_TICKLE; | ||||||
|  |         gmlan_alt_mode = DISABLED; | ||||||
|  |       } | ||||||
|  |       else { | ||||||
|  |         can_timeout_counter--; | ||||||
|  |         if (gmlan_timeout_counter == 0) { | ||||||
|  |           //Send a 1 (bus low) every 15ms to reset the GMLAN transceivers timeout
 | ||||||
|  |           gmlan_timeout_counter = GMLAN_TICKS_PER_TIMEOUT_TICKLE; | ||||||
|  |           set_gpio_output(GPIOB, 13, GMLAN_LOW); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |           set_gpio_output(GPIOB, 13, inverted_bit_to_send); | ||||||
|  |           gmlan_timeout_counter--; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     TIM4->SR = 0; | ||||||
|  |   } //gmlan switch mode
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void bitbang_gmlan(CAN_FIFOMailBox_TypeDef *to_bang) { | ||||||
|  |   gmlan_alt_mode = BITBANG; | ||||||
|  |   // TODO: make failure less silent
 | ||||||
|  |   if (gmlan_sendmax != -1) return; | ||||||
|  | 
 | ||||||
|  |   int len = get_bit_message(pkt_stuffed, to_bang); | ||||||
|  |   gmlan_fail_count = 0; | ||||||
|  |   gmlan_silent_count = 0; | ||||||
|  |   gmlan_sending = 0; | ||||||
|  |   gmlan_sendmax = len; | ||||||
|  | 
 | ||||||
|  |   // setup for bitbang loop
 | ||||||
|  |   set_bitbanged_gmlan(1); // recessive
 | ||||||
|  |   set_gpio_mode(GPIOB, 13, MODE_OUTPUT); | ||||||
|  | 
 | ||||||
|  |   setup_timer4(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
| @ -0,0 +1,36 @@ | |||||||
|  | int hyundai_giraffe_switch_1 = 0;          // is giraffe switch 1 high?
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static void hyundai_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { | ||||||
|  | 
 | ||||||
|  |   int bus = (to_push->RDTR >> 4) & 0xF; | ||||||
|  |   // 832 is lkas cmd. If it is on bus 0, then giraffe switch 1 is high and we want stock
 | ||||||
|  |   if ((to_push->RIR>>21) == 832 && (bus == 0)) { | ||||||
|  |     hyundai_giraffe_switch_1 = 1; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void hyundai_init(int16_t param) { | ||||||
|  |   controls_allowed = 0; | ||||||
|  |   hyundai_giraffe_switch_1 = 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int hyundai_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { | ||||||
|  | 
 | ||||||
|  |   // forward camera to car and viceversa, excpet for lkas11 and mdps12
 | ||||||
|  |   if ((bus_num == 0 || bus_num == 2) && !hyundai_giraffe_switch_1) { | ||||||
|  |     int addr = to_fwd->RIR>>21; | ||||||
|  |     bool is_lkas_msg = (addr == 832 && bus_num == 2) || (addr == 593 && bus_num == 0); | ||||||
|  |     return is_lkas_msg? -1 : (uint8_t)(~bus_num & 0x2); | ||||||
|  |   } | ||||||
|  |   return -1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const safety_hooks hyundai_hooks = { | ||||||
|  |   .init = hyundai_init, | ||||||
|  |   .rx = hyundai_rx_hook, | ||||||
|  |   .tx = nooutput_tx_hook, | ||||||
|  |   .tx_lin = nooutput_tx_lin_hook, | ||||||
|  |   .ignition = default_ign_hook, | ||||||
|  |   .fwd = hyundai_fwd_hook, | ||||||
|  | }; | ||||||
| @ -0,0 +1,20 @@ | |||||||
|  | #!/usr/bin/env python | ||||||
|  | from panda import Panda | ||||||
|  | 
 | ||||||
|  | def get_panda_password(): | ||||||
|  |    | ||||||
|  |   try: | ||||||
|  |     print("Trying to connect to Panda over USB...") | ||||||
|  |     p = Panda() | ||||||
|  |      | ||||||
|  |   except AssertionError: | ||||||
|  |     print("USB connection failed") | ||||||
|  |     sys.exit(0) | ||||||
|  | 
 | ||||||
|  |   wifi = p.get_serial() | ||||||
|  |   #print('[%s]' % ', '.join(map(str, wifi))) | ||||||
|  |   print("SSID: " + wifi[0]) | ||||||
|  |   print("Password: " + wifi[1]) | ||||||
|  |    | ||||||
|  | if __name__ == "__main__": | ||||||
|  |   get_panda_password() | ||||||
					Loading…
					
					
				
		Reference in new issue