mirror of
				https://github.com/halleysfifthinc/Toyota-AVC-LAN
				synced 2025-10-28 00:47:29 +00:00 
			
		
		
		
	Add muteing functionality and avoid unnecessary work when muted
This commit is contained in:
		
							parent
							
								
									dea335af7f
								
							
						
					
					
						commit
						b0b3d9f34e
					
				
							
								
								
									
										165
									
								
								src/avclandrv.c
									
									
									
									
									
								
							
							
						
						
									
										165
									
								
								src/avclandrv.c
									
									
									
									
									
								
							| @ -309,13 +309,11 @@ void AVCLAN_init() { | |||||||
|   loop_until_bit_is_clear(RTC_PITSTATUS, RTC_CTRLBUSY_bp); |   loop_until_bit_is_clear(RTC_PITSTATUS, RTC_CTRLBUSY_bp); | ||||||
|   RTC.PITCTRLA = RTC_PERIOD_CYC32768_gc | RTC_PITEN_bm; |   RTC.PITCTRLA = RTC_PERIOD_CYC32768_gc | RTC_PITEN_bm; | ||||||
| 
 | 
 | ||||||
|   // Set PA4 and PC0 as outputs
 |  | ||||||
|   PORTA.DIRSET = PIN4_bm; |  | ||||||
|   PORTC.DIRSET = PIN0_bm; |  | ||||||
| 
 |  | ||||||
|   // Set bus output pins to idle
 |   // Set bus output pins to idle
 | ||||||
|   AVC_SET_LOGICAL_1(); |   AVC_SET_LOGICAL_1(); | ||||||
| 
 | 
 | ||||||
|  |   AVCLAN_muteDevice(0); // unmute AVCLAN bus TX
 | ||||||
|  | 
 | ||||||
|   answerReq = cm_Null; |   answerReq = cm_Null; | ||||||
| 
 | 
 | ||||||
|   cd_status.cd1 = 1; |   cd_status.cd1 = 1; | ||||||
| @ -368,6 +366,33 @@ ISR(RTC_PIT_vect) { | |||||||
|   RTC.PITINTFLAGS |= RTC_PI_bm; |   RTC.PITINTFLAGS |= RTC_PI_bm; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Mute device TX on AVCLAN bus
 | ||||||
|  | void AVCLAN_muteDevice(uint8_t mute) { | ||||||
|  |   if (mute) { | ||||||
|  |     // clang-format off
 | ||||||
|  |     __asm__ __volatile__("cbi %[vporta_dir], 4; \n\t" | ||||||
|  |                          "cbi %[vportc_dir], 0; \n\t" | ||||||
|  |                          :: | ||||||
|  |                          [vporta_dir] "I"(_SFR_IO_ADDR(VPORTA_DIR)), | ||||||
|  |                          [vportc_dir] "I"(_SFR_IO_ADDR(VPORTC_DIR))); | ||||||
|  |     // clang-format on
 | ||||||
|  |   } else { | ||||||
|  |     // clang-format off
 | ||||||
|  |     __asm__ __volatile__("sbi %[vporta_dir], 4; \n\t" | ||||||
|  |                          "sbi %[vportc_dir], 0; \n\t" | ||||||
|  |                          :: | ||||||
|  |                          [vporta_dir] "I"(_SFR_IO_ADDR(VPORTA_DIR)), | ||||||
|  |                          [vportc_dir] "I"(_SFR_IO_ADDR(VPORTC_DIR))); | ||||||
|  |     // clang-format on
 | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Returns true if device TX is muted on AVCLAN bus
 | ||||||
|  | uint8_t AVCLAN_ismuted() { | ||||||
|  |   return (((VPORTA_DIR & PIN4_bm) | (VPORTA_DIR & PIN0_bm)) == 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Set AVC bus to `val` (logical 1 or 0) for `period` ticks of TCB1
 | ||||||
| void set_AVC_logic_for(uint8_t val, uint16_t period) { | void set_AVC_logic_for(uint8_t val, uint16_t period) { | ||||||
|   TCB1.CNT = 0; |   TCB1.CNT = 0; | ||||||
|   if (val) { |   if (val) { | ||||||
| @ -646,7 +671,7 @@ uint8_t AVCLAN_readframe() { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // is this command for me ?
 |   // is this command for me ?
 | ||||||
|   for_me = (frame.peripheral_addr == CD_ID); |   for_me = !AVCLAN_ismuted() && (frame.peripheral_addr == CD_ID); | ||||||
| 
 | 
 | ||||||
|   if (for_me) |   if (for_me) | ||||||
|     AVCLAN_sendbit_ACK(); |     AVCLAN_sendbit_ACK(); | ||||||
| @ -731,72 +756,75 @@ uint8_t AVCLAN_readframe() { | |||||||
|   if (printAllFrames) |   if (printAllFrames) | ||||||
|     AVCLAN_printframe(&frame, printBinary); |     AVCLAN_printframe(&frame, printBinary); | ||||||
| 
 | 
 | ||||||
|   if (for_me) { |   if (!AVCLAN_ismuted()) { | ||||||
|     if (CheckCmd(&frame, stat1, sizeof(stat1))) { |     if (for_me) { | ||||||
|       answerReq = cm_Status1; |       if (CheckCmd(&frame, stat1, sizeof(stat1))) { | ||||||
|       return 1; |         answerReq = cm_Status1; | ||||||
|     } |         return 1; | ||||||
|     if (CheckCmd(&frame, stat2, sizeof(stat2))) { |       } | ||||||
|       answerReq = cm_Status2; |       if (CheckCmd(&frame, stat2, sizeof(stat2))) { | ||||||
|       return 1; |         answerReq = cm_Status2; | ||||||
|     } |         return 1; | ||||||
|     if (CheckCmd(&frame, stat3, sizeof(stat3))) { |       } | ||||||
|       answerReq = cm_Status3; |       if (CheckCmd(&frame, stat3, sizeof(stat3))) { | ||||||
|       return 1; |         answerReq = cm_Status3; | ||||||
|     } |         return 1; | ||||||
|     if (CheckCmd(&frame, stat4, sizeof(stat4))) { |       } | ||||||
|       answerReq = cm_Status4; |       if (CheckCmd(&frame, stat4, sizeof(stat4))) { | ||||||
|       return 1; |         answerReq = cm_Status4; | ||||||
|     } |         return 1; | ||||||
|     // if (CheckCmd((uint8_t*)stat5)) {
 |       } | ||||||
|     //   answerReq = cm_Status5;
 |       // if (CheckCmd((uint8_t*)stat5)) {
 | ||||||
|     //   return 1;
 |       //   answerReq = cm_Status5;
 | ||||||
|     // }
 |       //   return 1;
 | ||||||
|  |       // }
 | ||||||
| 
 | 
 | ||||||
|     if (CheckCmd(&frame, play_req1, sizeof(play_req1))) { |       if (CheckCmd(&frame, play_req1, sizeof(play_req1))) { | ||||||
|       answerReq = cm_PlayReq1; |         answerReq = cm_PlayReq1; | ||||||
|       return 1; |         return 1; | ||||||
|     } |       } | ||||||
|     if (CheckCmd(&frame, play_req2, sizeof(play_req2))) { |       if (CheckCmd(&frame, play_req2, sizeof(play_req2))) { | ||||||
|       answerReq = cm_PlayReq2; |         answerReq = cm_PlayReq2; | ||||||
|       return 1; |         return 1; | ||||||
|     } |       } | ||||||
|     if (CheckCmd(&frame, play_req3, sizeof(play_req3))) { |       if (CheckCmd(&frame, play_req3, sizeof(play_req3))) { | ||||||
|       answerReq = cm_PlayReq3; |         answerReq = cm_PlayReq3; | ||||||
|       return 1; |         return 1; | ||||||
|     } |       } | ||||||
|     if (CheckCmd(&frame, stop_req, sizeof(stop_req))) { |       if (CheckCmd(&frame, stop_req, sizeof(stop_req))) { | ||||||
|       answerReq = cm_StopReq; |         answerReq = cm_StopReq; | ||||||
|       return 1; |         return 1; | ||||||
|     } |       } | ||||||
|     if (CheckCmd(&frame, stop_req2, sizeof(stop_req2))) { |       if (CheckCmd(&frame, stop_req2, sizeof(stop_req2))) { | ||||||
|       answerReq = cm_StopReq2; |         answerReq = cm_StopReq2; | ||||||
|       return 1; |         return 1; | ||||||
|     } |       } | ||||||
|   } else { // broadcast check
 |     } else { // broadcast check
 | ||||||
| 
 | 
 | ||||||
|     if (CheckCmd(&frame, lan_playit, sizeof(lan_playit))) { |       if (CheckCmd(&frame, lan_playit, sizeof(lan_playit))) { | ||||||
|       answerReq = cm_PlayIt; |         answerReq = cm_PlayIt; | ||||||
|       return 1; |         return 1; | ||||||
|     } |       } | ||||||
|     if (CheckCmd(&frame, lan_check, sizeof(lan_check))) { |       if (CheckCmd(&frame, lan_check, sizeof(lan_check))) { | ||||||
|       answerReq = cm_Check; |         answerReq = cm_Check; | ||||||
|       CMD_CHECK.data[4] = frame.data[3]; |         CMD_CHECK.data[4] = frame.data[3]; | ||||||
|       return 1; |         return 1; | ||||||
|     } |       } | ||||||
|     if (CheckCmd(&frame, lan_reg, sizeof(lan_reg))) { |       if (CheckCmd(&frame, lan_reg, sizeof(lan_reg))) { | ||||||
|       answerReq = cm_Register; |         answerReq = cm_Register; | ||||||
|       return 1; |         return 1; | ||||||
|     } |       } | ||||||
|     if (CheckCmd(&frame, lan_init, sizeof(lan_init))) { |       if (CheckCmd(&frame, lan_init, sizeof(lan_init))) { | ||||||
|       answerReq = cm_Init; |         answerReq = cm_Init; | ||||||
|       return 1; |         return 1; | ||||||
|     } |       } | ||||||
|     if (CheckCmd(&frame, lan_stat1, sizeof(lan_stat1))) { |       if (CheckCmd(&frame, lan_stat1, sizeof(lan_stat1))) { | ||||||
|       answerReq = cm_Status1; |         answerReq = cm_Status1; | ||||||
|       return 1; |         return 1; | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  | 
 | ||||||
|   answerReq = cm_Null; |   answerReq = cm_Null; | ||||||
|   return 1; |   return 1; | ||||||
| } | } | ||||||
| @ -839,6 +867,9 @@ AVCLAN_frame_t *AVCLAN_parseframe(const uint8_t *bytes, uint8_t len) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint8_t AVCLAN_sendframe(const AVCLAN_frame_t *frame) { | uint8_t AVCLAN_sendframe(const AVCLAN_frame_t *frame) { | ||||||
|  |   if (AVCLAN_ismuted()) | ||||||
|  |     return 1; | ||||||
|  | 
 | ||||||
|   STOPEvent; |   STOPEvent; | ||||||
| 
 | 
 | ||||||
|   // wait for free line
 |   // wait for free line
 | ||||||
|  | |||||||
| @ -120,7 +120,6 @@ typedef struct AVCLAN_KnownMessage_struct { | |||||||
| } AVCLAN_KnownMessage_t; | } AVCLAN_KnownMessage_t; | ||||||
| 
 | 
 | ||||||
| typedef struct AVCLAN_frame_struct { | typedef struct AVCLAN_frame_struct { | ||||||
|   uint8_t valid; |  | ||||||
|   MSG_TYPE_t broadcast;     // 0 for broadcast messages
 |   MSG_TYPE_t broadcast;     // 0 for broadcast messages
 | ||||||
|   uint16_t controller_addr; // formerly "master"
 |   uint16_t controller_addr; // formerly "master"
 | ||||||
|   uint16_t peripheral_addr; // formerly "slave"
 |   uint16_t peripheral_addr; // formerly "slave"
 | ||||||
| @ -129,6 +128,9 @@ typedef struct AVCLAN_frame_struct { | |||||||
|   uint8_t *data; |   uint8_t *data; | ||||||
| } AVCLAN_frame_t; | } AVCLAN_frame_t; | ||||||
| 
 | 
 | ||||||
|  | void AVCLAN_init(); | ||||||
|  | void AVCLAN_muteDevice(uint8_t mute); | ||||||
|  | 
 | ||||||
| uint8_t AVCLAN_readframe(); | uint8_t AVCLAN_readframe(); | ||||||
| uint8_t AVCLAN_sendframe(const AVCLAN_frame_t *frame); | uint8_t AVCLAN_sendframe(const AVCLAN_frame_t *frame); | ||||||
| 
 | 
 | ||||||
| @ -137,7 +139,6 @@ uint8_t AVCLAN_responseNeeded(); | |||||||
| void AVCLAN_printframe(const AVCLAN_frame_t *frame, uint8_t binary); | void AVCLAN_printframe(const AVCLAN_frame_t *frame, uint8_t binary); | ||||||
| AVCLAN_frame_t *AVCLAN_parseframe(const uint8_t *bytes, uint8_t len); | AVCLAN_frame_t *AVCLAN_parseframe(const uint8_t *bytes, uint8_t len); | ||||||
| 
 | 
 | ||||||
| void AVCLAN_init(); |  | ||||||
| void AVCLan_Send_Status(); | void AVCLan_Send_Status(); | ||||||
| void AVCLan_Register(); | void AVCLan_Register(); | ||||||
| uint8_t AVCLan_SendAnswer(); | uint8_t AVCLan_SendAnswer(); | ||||||
|  | |||||||
| @ -32,6 +32,7 @@ | |||||||
| 
 | 
 | ||||||
| uint8_t echoCharacters; | uint8_t echoCharacters; | ||||||
| uint8_t readBinary; | uint8_t readBinary; | ||||||
|  | uint8_t muteBus; | ||||||
| uint8_t readkey; | uint8_t readkey; | ||||||
| 
 | 
 | ||||||
| const char const *offon[] = {"OFF", "ON"}; | const char const *offon[] = {"OFF", "ON"}; | ||||||
| @ -143,6 +144,13 @@ int main() { | |||||||
|           RS232_Print(offon[echoCharacters]); |           RS232_Print(offon[echoCharacters]); | ||||||
|           RS232_Print("\n"); |           RS232_Print("\n"); | ||||||
|           break; |           break; | ||||||
|  |         case 'm': // Mute mockingboard device on AVCLAN bus
 | ||||||
|  |           muteBus ^= 1; | ||||||
|  |           AVCLAN_muteDevice(muteBus); | ||||||
|  |           RS232_Print("Mute device: "); | ||||||
|  |           RS232_Print(offon[muteBus]); | ||||||
|  |           RS232_Print("\n"); | ||||||
|  |           break; | ||||||
|         case 'b': |         case 'b': | ||||||
|         case 'B': // Beep
 |         case 'B': // Beep
 | ||||||
|           // answerReq = cm_Beep;
 |           // answerReq = cm_Beep;
 | ||||||
| @ -277,9 +285,11 @@ void print_help() { | |||||||
|   RS232_Print("S - read sequence\n" |   RS232_Print("S - read sequence\n" | ||||||
|               "W - send command\n" |               "W - send command\n" | ||||||
|               "Q - send broadcast\n" |               "Q - send broadcast\n" | ||||||
|  |               "m - Toggle mute for mockingboard bus activity\n" | ||||||
|               "l - Toggle message logging\n" |               "l - Toggle message logging\n" | ||||||
|               "k - Toggle character echo\n" |               "k - Toggle character echo\n" | ||||||
|               "R/r - register device\n" |               "R/r - register device\n" | ||||||
|  |               "X/x - Turn binary ON or OFF, respectively\n" | ||||||
|               "B - Beep\n" |               "B - Beep\n" | ||||||
|               "v - Toggle verbose logging\n" |               "v - Toggle verbose logging\n" | ||||||
| #ifdef SOFTWARE_DEBUG | #ifdef SOFTWARE_DEBUG | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user