Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: MAX7219pot MCP23S17 mbed
Fork of POT_V_1_0 by
main.cpp
00001 /*Board configuration 00002 >>>>>place JP5 to E5V side to use external 5V supply 00003 >>>>>Remove jumper link SB13,SB14 usb uart debug disabled 00004 >>>>>Place jumper link SB62,SB63...uart PA2,PA3 enabled by these jumper links 00005 */ 00006 00007 #include "mbed.h" 00008 #include "pot.h" 00009 #include "max7219.h" 00010 #include "MCP23S17.h" 00011 00012 using namespace std; 00013 00014 //------------------------------------ 00015 // Hyperterminal configuration 00016 // 9600 bauds, 8-bit data, no parity 00017 //------------------------------------ 00018 Serial UART(SERIAL_TX, SERIAL_RX); 00019 00020 //timer instances creation// 00021 Ticker pot_HB; 00022 Ticker HB_Ticker; 00023 Ticker flash_Ticker; 00024 Ticker R_A_Ticker; 00025 Ticker CMD_Ticker; 00026 //Ticker DIR_Ticker; //function changed to Up-Down Rpm counts 00027 Ticker HB_fail; 00028 Ticker RTC_ticker; 00029 Ticker led_refresh; 00030 Timeout timeout; 00031 00032 //SPI instances creation// 00033 SPI _SPI2(SPI2_MOSI, SPI2_MISO, SPI2_SCK); //for displays max7219 00034 SPI _SPI3(SPI3_MOSI, SPI3_MISO, SPI3_SCK); //for keyscan mcp23s17 00035 00036 //class object instances for key I/O expander and segment driver// 00037 MCP23S17 mcp23s17_1(1,_SPI3, SPI3_CS1,SPI3_RST); //class MCP23S17 object instance for mcp23s17 IC-1 key detection 00038 MCP23S17 mcp23s17_2(2,_SPI3, SPI3_CS2,SPI3_RST); //class MCP23S17 object instance for mcp23s17 IC-2 key detection 00039 Max7219 max7219(SPI2_MOSI, SPI2_MISO, SPI2_SCK,SPI2_CS1); //object instance for seven segment drivers 00040 max7219_configuration_t DEVICE1, DEVICE2; 00041 //interrupts definations 00042 InterruptIn int_A(INT_A); //8commands 00043 InterruptIn int_B(INT_B); //4 3commands+1ack 00044 InterruptIn int_C(INT_C); //4(3 controls(INC+,DEC-,TEST)+1 req) enbaled for all 00045 00046 //chip select definations for max7219 & mcp23s17 as digitalout pins// 00047 DigitalOut cs_disp1(SPI2_CS1); 00048 DigitalOut cs_disp2(SPI2_CS2); //max7219 00049 DigitalOut cs_key1(SPI3_CS1); 00050 DigitalOut cs_key2(SPI3_CS2); //mcp23s17 00051 00052 DigitalOut Drive_En(TX_EN); //uart driver enable 00053 00054 //discrete outputs definations buzzer and hooter 00055 DigitalOut buzzer(BUZ); 00056 DigitalOut hooter(HTR); 00057 00058 00059 int err_ALL,sync_count,Hrs_1,Hrs_2, Mins_1, Mins_2, current_cmd, current_status,current_status_dir; 00060 int addr, req,ack, send_ADDR, rcvd_ADDR, ach_S,ach_M,test_cnt,req_ADDR,ack_ADDR, err_ID, err_Status; 00061 int rpm_data[4] = {0,0,0,0}; //digits 0-3 00062 int last_entry[4] = {0,0,0,0}; //digits 0-3 00063 00064 00065 uint8_t spi_error,no_pot_connected,num_bytes,ticker_count,ticker_count_fast,norm_count,set_bit; 00066 00067 00068 //int dir, last_dir; 00069 int checksum_send_byte,checksum_rcvd_byte; 00070 00071 char pot_Addr,addr_ID; 00072 00073 float HB_timer,duty_cycle,sync_time; 00074 00075 bool device_ERR,pot_Error, norm_op; 00076 bool toggle,test,toggle_fast,display_flash; 00077 bool key_CMD,key_CTRL,key_SET; 00078 bool HB_rcvd, HB_ack_rcvd, REQ_rcvd, BROADCAST_rcvd, ACK_rcvd,time_RCVD; 00079 00080 bool DIR_cmd,DIR_cmd_ack,DIR_cmd_ack_send; 00081 bool RPM_cmd,RPM_cmd_ack,RPM_cmd_ack_send; 00082 00083 bool HB_send, CMD_send, BROADCAST_send, REQ_send, ACK_send; 00084 00085 bool ENTER_ACK_key,DIR_key,REQ_key,ACK_key,disp_clear; 00086 00087 bool switch_CH, pot_MCR_err, pot_ER_err, ACH_SW_over; 00088 bool data_fail,disp_test; 00089 00090 int device_addr = -1; 00091 00092 char valid; 00093 char valid_sentence[8] = {'A', 'A','A','A','A','A','A','A'}; 00094 char rx_buf[RX_BUFFER_SIZE+1]; 00095 char tx_buf[TX_BUFFER_SIZE+1]; 00096 char RTC_buffer[5] = {1,2,3,4,0}; 00097 00098 DigitalOut LED_CMD_ACK(_CMD_ACK); //ack command in slave devices only 00099 DigitalOut LED_CTRL[2] = {_REQ,_ACK}; //control transfer 00100 //DigitalOut LED_DIR[2] = {_AHEAD,_ASTERN}; //dir command 00101 DigitalOut LED_ACH[8] = {_WH,_BRDG,_MCR,_ER,_WP,_WS,_OPS,_ASP}; //active channels 00102 00103 //DigitalOut myled(PB_13); //for internal test LED1 00104 00105 PwmOut mypwm(_PWM); 00106 00107 struct _POT 00108 { 00109 int slave_ID; 00110 int err_cnt; 00111 bool err_status; 00112 }; 00113 struct _POT* POT=NULL; 00114 00115 enum AddrID 00116 { 00117 pot_Master = 1, 00118 pot_Submaster, 00119 pot_Slave_MCR, 00120 pot_Slave_ER, 00121 pot_Listner_WP, 00122 pot_Listner_WS, 00123 pot_Listner_OPS, 00124 pot_Listner_ASP = 8 00125 }; 00126 00127 enum LED_STATUS 00128 { 00129 OFF = 0, 00130 ON, 00131 _FLASH = 2 00132 }; 00133 LED_STATUS led_cmd_ack; //only in slave devices 00134 LED_STATUS led_ctrl[2]; 00135 //LED_STATUS led_dir[2]; 00136 LED_STATUS led_ach[8]; 00137 00138 enum KEY 00139 { 00140 ZERO = 0, 00141 ONE, 00142 TWO, 00143 THREE, 00144 FOUR, 00145 FIVE, 00146 SIX, 00147 SEVEN, 00148 EIGHT, 00149 NINE, 00150 FALSE0 = 10 00151 }; 00152 enum KEY num_KEY; 00153 00154 enum CTRL 00155 { 00156 REQ_ = 1, 00157 ACK_ = 2, 00158 FALSE1= 3 00159 00160 }; 00161 enum CTRL ctrl_KEY; 00162 00163 enum UP_DOWN 00164 { 00165 UP_key=1, 00166 DOWN_key, 00167 FALSE2 = 3 00168 }; 00169 enum UP_DOWN up_down_KEY; 00170 00171 /* 00172 enum direction_KEY 00173 { 00174 AHEAD = 1, 00175 ASTERN, 00176 FALSE2 = 3 00177 }; 00178 enum direction_KEY dir_KEY; 00179 */ 00180 00181 enum display_KEY 00182 { 00183 clr_ENTRY = 0, //CE 00184 clr_ALL, //C, all data turns to zero 00185 ENTER_ACK, //enter in case of master and ACK in case of slaves/repeaters 00186 FALSE3 = 3 00187 }; 00188 enum display_KEY disp_KEY; 00189 00190 enum SET 00191 { 00192 INC=0, 00193 DEC, 00194 TEST, 00195 FALSE4 = 4 00196 }; 00197 enum SET set_KEY; 00198 00199 enum CHANNEL 00200 { 00201 ch_A=1, 00202 ch_B, 00203 ch_C, 00204 ch_D=4 00205 }; //keyscan channelA,B,C,Dof MCP23s17 1& 2 respectively 00206 enum CHANNEL ch; 00207 00208 00209 /************************************************************************************** 00210 EOT RTC display update FUNCTIONS 00211 **************************************************************************************/ 00212 void RTC_display(char* digits) 00213 { 00214 for(uint8_t i = 0; i <= 3; i++) //to write all the four digits 00215 { 00216 if(i == 1) 00217 RTC_buffer[i] = RTC_buffer[i]|0b10000000; // to inc 00218 else 00219 __nop(); 00220 max7219.write_digit(1, i+1, *(digits+i)); //device 2, digit 1-4 ,data 0x01 00221 } 00222 } 00223 00224 /************************************************************************************** 00225 EOT RTC read FUNCTION 00226 **************************************************************************************/ 00227 void read_RTC() 00228 { 00229 time_t seconds = time(NULL); 00230 strftime(RTC_buffer, 5, "%H%M\n", localtime(&seconds)); 00231 wait_ms(5); 00232 RTC_display(RTC_buffer); 00233 wait_ms(1); 00234 } 00235 00236 /************************************************************************************** 00237 EOT CHECK LED STATUS FUNCTION 00238 **************************************************************************************/ 00239 void update_led() 00240 { 00241 if(++ticker_count == 25) //25x20 = 500ms 00242 { 00243 ticker_count = 0; 00244 toggle = !toggle; //normal cmd flash 00245 } 00246 else 00247 __nop(); 00248 00249 if(++ticker_count_fast == 10) //20x10 =200 00250 { 00251 ticker_count_fast = 0; 00252 toggle_fast = !toggle_fast; //error flashing 00253 } 00254 else 00255 __nop(); 00256 00257 if(test) 00258 { 00259 LED_CMD_ACK = ON; //in slave only 00260 00261 for(uint8_t i=0;i<=1;i++) //control 00262 { 00263 LED_CTRL[i] = ON; 00264 } 00265 00266 /* 00267 for(uint8_t i=0;i<=1;i++) // dir control 00268 { 00269 LED_DIR[i] = ON; /////////////////working here 00270 } 00271 */ 00272 00273 for(uint8_t i=0;i<=7;i++) //active channel 00274 { 00275 LED_ACH[i] = ON; //duty cycle 10% 00276 } 00277 max7219.set_display_test(); //all on 00278 wait_us(1); 00279 disp_test = true; 00280 } 00281 else 00282 { 00283 if(disp_test) 00284 { 00285 disp_test = false; 00286 max7219.clear_display_test(); //normal operation 00287 } 00288 else 00289 __nop(); 00290 00291 if(led_cmd_ack == ON) //status update LED_CMD_ACK 00292 LED_CMD_ACK = ON; 00293 else 00294 __nop(); 00295 00296 if(led_cmd_ack == OFF) 00297 LED_CMD_ACK = OFF; 00298 else 00299 __nop(); 00300 00301 if(led_cmd_ack == _FLASH) 00302 { 00303 if(toggle) 00304 LED_CMD_ACK= ON; 00305 else 00306 LED_CMD_ACK = OFF; 00307 } 00308 else 00309 __nop(); 00310 00311 for(uint8_t i=0;i<=1;i++) //status update LED_CTRL 00312 { 00313 if(led_ctrl[i] == ON) 00314 LED_CTRL[i] = ON; 00315 else 00316 __nop(); 00317 00318 if(led_ctrl[i] == OFF) 00319 LED_CTRL[i] = OFF; //duty cycle 10% 00320 else 00321 __nop(); 00322 00323 if(led_ctrl[i] == _FLASH) 00324 { 00325 if(toggle) 00326 LED_CTRL[i]= ON; 00327 else 00328 LED_CTRL[i] = OFF; 00329 } 00330 else 00331 __nop(); 00332 } 00333 /* 00334 for(uint8_t i=0;i<=1;i++) //status update LED_CTRL 00335 { 00336 if(led_dir[i] == ON) 00337 LED_DIR[i] = ON; 00338 else 00339 __nop(); 00340 00341 if(led_dir[i] == OFF) 00342 LED_DIR[i] = OFF; //duty cycle 10% 00343 else 00344 __nop(); 00345 00346 if(led_dir[i] == _FLASH) 00347 { 00348 if(toggle) 00349 LED_DIR[i]= ON; 00350 else 00351 LED_DIR[i] = OFF; 00352 } 00353 else 00354 __nop(); 00355 } 00356 */ 00357 00358 for(uint8_t i=0;i<=7;i++) //status update LED_ACH 00359 { 00360 if(led_ach[i] == ON) 00361 LED_ACH[i] = ON; //duty cycle 10% 00362 else 00363 __nop(); 00364 00365 if(led_ach[i] == OFF) 00366 LED_ACH[i] = OFF; //duty cycle 10 00367 else 00368 __nop(); 00369 00370 if(led_ach[i] == _FLASH) 00371 { 00372 if(toggle_fast) 00373 LED_ACH[i]= ON; 00374 else 00375 LED_ACH[i] = OFF; 00376 } 00377 else 00378 __nop(); 00379 } 00380 } 00381 if(display_flash) //if command executed or command received 00382 { 00383 if(toggle) 00384 max7219.enable_device(2); //enable device 1 or normal mode 00385 else 00386 max7219.disable_device(2); //shutdown mode 00387 } 00388 else if(!device_ERR) //specific device is not in error device 00389 max7219.enable_device(2); //enable device 1 or normal mode; 00390 else 00391 __nop(); 00392 } 00393 00394 /************************************************************************************** 00395 POT State Machines FUNCTIONS 00396 **************************************************************************************/ 00397 void HB_State_Machine() //run at an interval of 10ms,event driven start stop 00398 { 00399 static int hb_state_cnt = 0; 00400 if(HB_send) 00401 { 00402 HB_send = false; 00403 hb_state_cnt = 0; 00404 } 00405 else 00406 __nop(); 00407 00408 if(HB_ack_rcvd) 00409 { 00410 HB_ack_rcvd = false; 00411 HB_Ticker.detach(); 00412 POT[device_addr].err_cnt = 0; 00413 if(POT[device_addr].err_status) //if that specific device is in error before but revert back to healthy state 00414 { 00415 POT[device_addr].err_status = false; 00416 err_Status = 0; 00417 err_ID = POT[device_addr].slave_ID; 00418 00419 set_bit = (uint8_t)1<<(err_ID-1); 00420 err_ALL = err_ALL^set_bit; //bitwise XOR 00421 00422 BROADCAST_send = true; // to tell all device that error diminished 00423 switch_CH = true; // to tell specific device abot active channels and rpm data 00424 if(POT[device_addr].slave_ID == pot_Slave_MCR) 00425 { 00426 pot_MCR_err = false; 00427 if(pot_ER_err) 00428 { 00429 ach_S = pot_Slave_MCR; 00430 switch_CH = true; //automatic takeover if ER is already faulty 00431 } 00432 else 00433 __nop(); 00434 } 00435 else 00436 __nop(); 00437 00438 if(POT[device_addr].slave_ID == pot_Slave_ER) 00439 { 00440 pot_ER_err = false; 00441 if(pot_MCR_err) 00442 { 00443 ach_S = pot_Slave_ER; 00444 switch_CH = true; //automatic takeover if ER is already faulty 00445 } 00446 else 00447 __nop(); 00448 } 00449 else 00450 __nop(); 00451 } 00452 else 00453 { 00454 POT[device_addr].err_status = false; 00455 hb_state_cnt = 0; 00456 err_Status = 0; 00457 00458 if((POT[device_addr].slave_ID == ach_S)&&(led_ach[send_ADDR - 1] != ON)) 00459 led_ach[send_ADDR - 1] = ON; 00460 else if((POT[device_addr].slave_ID != ach_S)&&(led_ach[send_ADDR - 1] != OFF)) 00461 led_ach[send_ADDR - 1] = OFF; 00462 else 00463 __nop(); 00464 00465 if((addr_ID == ach_M)&&(led_ach[ach_M-1] != ON)) 00466 led_ach[ach_M-1] = ON; 00467 else if((addr_ID != ach_M)&&(led_ach[ach_M-1] != OFF)) 00468 led_ach[ach_M-1] = OFF; 00469 else 00470 __nop(); 00471 } 00472 } 00473 else 00474 { 00475 if(++hb_state_cnt >= 5) //if HB_response not arrived till 50ms 00476 { 00477 hb_state_cnt=0; 00478 HB_Ticker.detach(); 00479 00480 if((++POT[device_addr].err_cnt >= 5)&&(!POT[device_addr].err_status)) //specific device in error state after 05 hb response missing 00481 { 00482 POT[device_addr].err_cnt = 0; 00483 led_ach[send_ADDR - 1] = _FLASH; 00484 err_ID = POT[device_addr].slave_ID; 00485 00486 set_bit = (uint8_t)1<<(err_ID-1); 00487 err_ALL = err_ALL|set_bit; //bitwise OR 00488 00489 POT[device_addr].err_status = true; 00490 err_Status = 1; 00491 BROADCAST_send = true; //broadcast needed to be sent 00492 if(POT[device_addr].slave_ID == pot_Slave_MCR) //means MCR fail 00493 { 00494 pot_MCR_err = true; 00495 if(ach_S == pot_Slave_MCR) 00496 { 00497 if(!pot_ER_err) //automatic changeover if ER healthy 00498 { 00499 ach_S = pot_Slave_ER; 00500 switch_CH = true; //transfer all slaves the new active slave 00501 } 00502 else 00503 { 00504 pot_Error = true; 00505 ach_S = 9; 00506 switch_CH = true; //both start flashing for ER nd MCR in all slaves 00507 } 00508 } 00509 else 00510 __nop(); 00511 } 00512 else 00513 __nop(); 00514 00515 if(POT[device_addr].slave_ID == pot_Slave_ER) 00516 { 00517 pot_ER_err = true; 00518 if(ach_S == pot_Slave_ER) 00519 { 00520 if(!pot_MCR_err) //automatic changeover if MCR healthy 00521 { 00522 ach_S = pot_Slave_MCR; 00523 switch_CH = true; 00524 } 00525 else 00526 { 00527 pot_Error = true; 00528 ach_S = 9; 00529 switch_CH = true; //both start flashing for all MCR nd ER 00530 } 00531 } 00532 else 00533 __nop(); 00534 } 00535 else 00536 __nop(); 00537 } 00538 else 00539 __nop(); 00540 } 00541 else 00542 __nop(); 00543 } 00544 } 00545 00546 void CMD_State_Machine() //function run periodcally in all connected devices on bus 00547 { 00548 static int cmd_state_cnt=0; 00549 00550 if(RPM_cmd_ack) //PEOTX,CMD received in Master/SUB_Master, non Active Slave & Listner 00551 { 00552 for(uint8_t i = 0; i <=3; i++) 00553 { 00554 last_entry[i] = rpm_data[i]; //data saved to last entery 00555 } 00556 for(uint8_t i = 5; i <=8; i++) 00557 { 00558 max7219.write_digit(1,i,last_entry[i-5]); //last entery displayed 00559 } 00560 if(addr_ID == ach_M) 00561 { 00562 mcp23s17_1.gpintena(0xff); //ACK key interrupts disabled 00563 wait_us(1); 00564 mcp23s17_1.gpintenb(0xff); //ACK key interrupts disabled 00565 wait_us(1); 00566 disp_clear = true; 00567 } 00568 else if(addr_ID == ach_S) 00569 { 00570 int_B.rise(NULL); //all key functions/interrupt disabled for PORTA,B 00571 wait_us(1); 00572 mcp23s17_1.gpintenb(0x00); //interrupts disabled 00573 wait_us(1); 00574 } 00575 else 00576 __nop(); 00577 00578 led_cmd_ack = ON; 00579 current_status = 1; //display steady 00580 cmd_state_cnt = 0; 00581 RPM_cmd = false; 00582 RPM_cmd_ack = false; 00583 display_flash = false; 00584 buzzer = OFF; 00585 hooter = OFF; 00586 CMD_Ticker.detach(); //cmd state machine ticker stopped in all devices 00587 } 00588 else if(++cmd_state_cnt >= 12) //Hotter ON after 3sec 00589 { 00590 if((hooter == OFF)&&(addr_ID == ach_S)) //if hooter still off 00591 { 00592 cmd_state_cnt = 0; 00593 hooter = ON; 00594 /* if(++cmd_state_cnt >= 96) //still command ack not recived for 24 sec 00595 { 00596 LED_CMD[cmd].OFF(); //command suspended 00597 buzzer = OFF; 00598 hooter = OFF; 00599 int_A.rise(NULL); 00600 int_A.rise(NULL); 00601 CMD_ticker.detach(); //timer stoped in all connected devices if ack not received in 3sec 00602 } */ 00603 } 00604 else 00605 __nop(); 00606 } 00607 else 00608 __nop(); 00609 } 00610 00611 void R_A_Statemachine() 00612 { 00613 static int state_cnt = 0; 00614 if(++state_cnt >= 60) //REQ not acknowledged for 30 sec, leds turn off, timer stopped 00615 { 00616 state_cnt = 0; 00617 REQ_rcvd = false; //clear any pending request 00618 R_A_Ticker.detach(); 00619 /* 00620 if(addr_ID != ach_M) // TODO 00621 { 00622 int_B.rise(NULL); 00623 mcp23s17_1.gpintenb(0x00); //portb of mcp1 keys disabled related to ACK 00624 wait_us(10); 00625 } 00626 else 00627 __nop(); 00628 */ 00629 00630 led_ctrl[REQ_-1] = OFF; 00631 led_ctrl[ACK_-1] = OFF; 00632 } 00633 else 00634 __nop(); 00635 00636 if(ACK_rcvd) //active channel switchover true only after acknowledge receive 00637 { 00638 ACK_rcvd = false; 00639 led_ctrl[REQ_-1] = OFF; 00640 if(addr_ID == pot_Master) 00641 { 00642 if(ack_ADDR == 3 || ack_ADDR == 4) 00643 { 00644 if(ach_S == pot_Slave_MCR) 00645 ach_S = pot_Slave_ER; 00646 else if(ach_S == pot_Slave_ER) 00647 ach_S = pot_Slave_MCR; 00648 } 00649 else 00650 __nop(); 00651 00652 if(ack_ADDR == 2 || ack_ADDR == 1) 00653 { 00654 if(ach_M == pot_Master) 00655 ach_M = pot_Submaster; 00656 else if(ach_M == pot_Submaster) 00657 ach_M = pot_Master; 00658 } 00659 else 00660 __nop(); 00661 00662 switch_CH = true; 00663 state_cnt = 0; 00664 R_A_Ticker.detach(); 00665 } 00666 else 00667 { 00668 state_cnt = 0; 00669 R_A_Ticker.detach(); 00670 } 00671 } 00672 else 00673 __nop(); 00674 } 00675 00676 //Direction function changed to RPM Up-Down Counter so Dir_state_machine function not required 00677 /* 00678 void DIR_state_machine(void) 00679 { 00680 static int dir_state_cnt = 0; 00681 if(DIR_cmd_ack) 00682 { 00683 DIR_cmd = false; 00684 DIR_cmd_ack = false; 00685 current_status_dir = 1; //steady 00686 led_dir[dir-1] = ON; //led direction acknowledged turn steady 00687 buzzer = OFF; //buzzer Off 00688 hooter = OFF; 00689 DIR_Ticker.detach(); 00690 } 00691 else 00692 { 00693 if((++dir_state_cnt >= 12) && (hooter == OFF)) //direction command not ack for 03 sec 00694 { 00695 hooter = ON; 00696 dir_state_cnt = 0; 00697 } 00698 else 00699 __nop(); 00700 } 00701 } 00702 */ 00703 00704 void HB_fail_state_machine() 00705 { 00706 static uint8_t fail_count = 0; 00707 if(HB_rcvd) 00708 { 00709 HB_rcvd = false; 00710 device_ERR = false; 00711 } 00712 else if(++fail_count >=3) // if max 07 number of connected eots 7x3=21, it takes 150x21=3.150 sec to alarm 00713 { 00714 fail_count = 0; 00715 //led_dir[dir-1] = OFF; //current command if any turned OFF 00716 led_cmd_ack = OFF; 00717 display_flash = false; 00718 device_ERR = true; 00719 max7219.disable_device(2); //shutdown mode 00720 wait_ms(2); 00721 if(addr_ID != ach_M) 00722 { 00723 for(uint8_t i = 0; i <=7; i++) 00724 { 00725 led_ach[i] = OFF; //all other active chnnels leds or device errors 00726 } 00727 led_ach[addr_ID - 1] = _FLASH; //specific device is in error flshes only 00728 } 00729 HB_fail.detach(); 00730 } 00731 } 00732 00733 void NUMERIC_handler(uint8_t key_ID) //function sacnning all the 0-9 and up-down number keys 00734 { 00735 uint8_t num; 00736 num = key_ID; 00737 if(key_ID != FALSE0) 00738 { 00739 if(((ach_M == pot_Master) && (addr_ID == pot_Master)) || ((ach_M == pot_Submaster) && (addr_ID == pot_Submaster))) //for Master 00740 { 00741 if(disp_clear) //if last command has been acknowledged 00742 { 00743 for (uint8_t j = 0; j < 4; j++) 00744 { 00745 rpm_data[j] = 0; //clear rpm_data to enter new values 00746 } 00747 disp_clear = false; 00748 } 00749 else 00750 __nop(); 00751 00752 for (uint8_t j = 0; j < 4; j++) 00753 { 00754 rpm_data[j] = rpm_data[j + 1]; //at every key press array shift to left 00755 } 00756 00757 rpm_data[3] = num; //new value be updated at place of digit 4 00758 00759 for (uint8_t j = 1; j <= 4; j++) 00760 { 00761 max7219.write_digit(2,j,rpm_data[j-1]); 00762 } 00763 } 00764 else 00765 __nop(); 00766 } 00767 else 00768 __nop(); 00769 } 00770 00771 00772 void CTRL_handler(uint8_t CTRL_ID) //handle control transfer 00773 { 00774 if(CTRL_ID != FALSE1) 00775 { 00776 if((addr_ID == pot_Slave_MCR) || (addr_ID == pot_Slave_ER)) 00777 { 00778 if((CTRL_ID == REQ_)&&(!REQ_rcvd)) //if no request has been received 00779 { 00780 req = REQ_; //req data updated 0 here, same int values as in enum 00781 REQ_key = true; 00782 led_ctrl[REQ_-1] = _FLASH; //req led flash starts 00783 R_A_Ticker.attach(&R_A_Statemachine,0.5); 00784 } 00785 else 00786 __nop(); 00787 00788 if((CTRL_ID == ACK_)&& (REQ_rcvd)) 00789 { 00790 REQ_rcvd = false; 00791 ack = ACK_; //ack data updated 2 here 00792 ACK_key = true; 00793 int_B.rise(NULL); //interrupt disabled 00794 wait_us(10); 00795 mcp23s17_1.gpintenb(0x00); //ACK key interrupts disabled 00796 wait_us(10); 00797 led_ctrl[ACK_-1] = OFF; //ack led turns off 00798 R_A_Ticker.detach(); 00799 } 00800 else 00801 __nop(); 00802 } 00803 } 00804 else 00805 __nop(); //then do nothing 00806 } 00807 00808 void UP_DOWN_handler(uint8_t key_ID) 00809 { 00810 if(key_ID != FALSE2) 00811 { 00812 if(((ach_M == pot_Master) && (addr_ID == pot_Master)) || ((ach_M == pot_Submaster) && (addr_ID == pot_Submaster))) //for Master 00813 { 00814 if(key_ID == UP_key) 00815 { 00816 rpm_data[3]++; 00817 if(rpm_data[3] == 10) 00818 { 00819 rpm_data[3] = 0; 00820 rpm_data[2]++; 00821 if(rpm_data[2] == 10) 00822 { 00823 rpm_data[2] = 0; 00824 rpm_data[1]++; 00825 if(rpm_data[1] == 10) 00826 { 00827 rpm_data[1] = 0; 00828 rpm_data[0]++; 00829 if(rpm_data[0] == 10) 00830 rpm_data[0] = 9; 00831 else 00832 __nop(); 00833 } 00834 else 00835 __nop(); 00836 } 00837 else 00838 __nop(); 00839 } 00840 else 00841 __nop(); 00842 } 00843 else if(key_ID == DOWN_key) 00844 { 00845 rpm_data[3]--; 00846 if(rpm_data[3] == 0) 00847 { 00848 rpm_data[3] = 0; 00849 rpm_data[2]--; 00850 if(rpm_data[2] == 0) 00851 { 00852 rpm_data[2] = 0; 00853 rpm_data[1]--; 00854 if(rpm_data[1] == 0) 00855 { 00856 rpm_data[1] = 0; 00857 rpm_data[0]--; 00858 if(rpm_data[0] == 0) 00859 rpm_data[0] = 0; 00860 else 00861 __nop(); 00862 } 00863 else 00864 __nop(); 00865 } 00866 else 00867 __nop(); 00868 } 00869 else 00870 __nop(); 00871 00872 } 00873 else 00874 __nop(); 00875 00876 for (uint8_t j = 1; j <= 4; j++) 00877 { 00878 max7219.write_digit(2,j,rpm_data[j-1]); //update data to display 00879 } 00880 } 00881 else 00882 __nop(); 00883 } 00884 else 00885 __nop(); 00886 00887 } 00888 00889 //functon not required as DiR keys change to UP-down RPM 00890 /* 00891 void DIR_handler(uint8_t DIR_ID) //handle control transfer 00892 { 00893 if(DIR_ID != FALSE2) 00894 { 00895 if(addr_ID == ach_M) 00896 { 00897 current_status_dir = 2; //flash 00898 led_dir[dir-1] = OFF; 00899 dir = DIR_ID; 00900 led_dir[dir-1] = _FLASH; //led direction AHEAD start flashing 00901 buzzer = ON; //buzzer ON 00902 DIR_cmd = true; // dir cmd needs to be sent 00903 } 00904 else 00905 __nop(); 00906 00907 if (addr_ID == ach_S) 00908 { 00909 if((dir == DIR_ID)&&(DIR_cmd)) //direction command is received 00910 { 00911 current_status_dir = 1; 00912 led_dir[dir-1] = OFF; 00913 dir = DIR_ID; 00914 led_dir[dir-1] = ON; //led direction AHEAD start flashing 00915 buzzer = OFF; //buzzer OFF 00916 DIR_key = true; //dir ack will be sent in response to HB 00917 } 00918 else 00919 __nop(); 00920 } 00921 else 00922 __nop(); 00923 } 00924 else 00925 __nop(); //then do nothing 00926 } 00927 */ 00928 00929 void DISP_handler(uint8_t DISP_ID) //handle control transfer 00930 { 00931 uint8_t disp_key; 00932 disp_key = DISP_ID; 00933 if(DISP_ID != FALSE3) 00934 { 00935 switch(disp_key) 00936 { 00937 case clr_ENTRY: //CE,elete only last/4th digit and shift others digits towards right/4th digit 00938 if(addr_ID == ach_M) 00939 { 00940 for (uint8_t j = 3; j > 0; j--) 00941 { 00942 rpm_data[j] = rpm_data[j - 1]; //at every key press array shift to left 00943 } 00944 rpm_data[0] = 0; 00945 00946 for (uint8_t j = 1; j <= 4; j++) 00947 { 00948 max7219.write_digit(2,j,rpm_data[j-1]); 00949 } 00950 } 00951 else 00952 { 00953 __nop(); 00954 } 00955 break; 00956 00957 case clr_ALL: 00958 if(addr_ID == ach_M) 00959 { //C delete all digits in DS1 and show last entered value 00960 for (uint8_t j = 0; j <=3; j++) 00961 { 00962 rpm_data[j] = 0; //at every key press array shift to left 00963 } 00964 for (uint8_t j = 1; j <= 4; j++) // all digits turns to zero 00965 { 00966 max7219.write_digit(2,j,rpm_data[j-1]); 00967 } 00968 } 00969 else 00970 { 00971 __nop(); 00972 } 00973 break; 00974 00975 case ENTER_ACK: //work as Enter in master and CMD ACK in slave 00976 if((addr_ID == ach_S)&&(RPM_cmd)) //RPM command ack needs to be sent 00977 { 00978 RPM_cmd = false; 00979 display_flash = false; 00980 buzzer = OFF; 00981 int_B.rise(NULL); 00982 wait_us(10); 00983 mcp23s17_1.gpintenb(0x00); //ACK key interrupts disabled 00984 wait_us(10); 00985 ENTER_ACK_key = true; //flashing display1 turned steady //RPM command acknowledged by active slave 00986 } 00987 else if (addr_ID == ach_M) //in case of active masters 00988 { 00989 int RPM_set = 0; //disp1 start flashing, and data sent over UART for all digits 1-4 00990 RPM_set = (rpm_data[0]*1000) + (rpm_data[1]*100) + (rpm_data[2]*10) + rpm_data[3]; 00991 if(RPM_set>Max_RPM) 00992 { 00993 for (uint8_t j = 0; j <=3; j++) 00994 { 00995 rpm_data[j] = 0; //at every key press array shift to left 00996 } 00997 for (uint8_t j = 1; j <= 4; j++) // all digits turns to zero 00998 { 00999 max7219.write_digit(2,j,rpm_data[j-1]); 01000 } 01001 } 01002 else 01003 { 01004 display_flash = true; //display starts flashing 01005 mcp23s17_1.gpintena(0x00); //ACK key interrupts disabled 01006 wait_us(10); 01007 mcp23s17_1.gpintenb(0x00); //ACK key interrupts disabled 01008 wait_us(10); 01009 current_status = 2; //flash 01010 buzzer = ON; 01011 RPM_cmd = true; //command need to be send 01012 } 01013 } 01014 else 01015 { 01016 __nop(); 01017 } 01018 break; 01019 01020 default: 01021 __nop(); 01022 break; 01023 } 01024 } 01025 else 01026 __nop(); //then do nothing 01027 } 01028 01029 /****************************************************************** 01030 function to set brightness of leds and seven segment 01031 ******************************************************************/ 01032 void SET_handler(uint8_t Set_ID) 01033 { 01034 if(Set_ID != FALSE2) 01035 { 01036 switch(Set_ID) 01037 { 01038 case INC: 01039 duty_cycle = mypwm.read(); //as duty cycle decreases creases brightnes increases 01040 if( duty_cycle > 0.02f) 01041 { 01042 duty_cycle = duty_cycle-0.01f; 01043 mypwm.write(duty_cycle); 01044 } 01045 else 01046 { 01047 duty_cycle = 0.01f; 01048 } 01049 if(DEVICE1.intensity < 14) 01050 { 01051 DEVICE1.intensity ++; //intensity modified 01052 DEVICE2.intensity ++; 01053 max7219.set_intensity(DEVICE1); //updating brightness value of DEVICE1 01054 max7219.set_intensity(DEVICE2); //updating brightness value of DEVICE2 01055 } 01056 else 01057 { 01058 DEVICE1.intensity =15; 01059 DEVICE2.intensity =15; 01060 max7219.set_intensity(DEVICE1); //updating brightness value of DEVICE1 01061 max7219.set_intensity(DEVICE2); //updating brightness value of DEVICE2 01062 } 01063 break; 01064 01065 case DEC: 01066 duty_cycle = mypwm.read(); 01067 if( duty_cycle < 0.98f) //as duty cycle increases brightnes decreases 01068 { 01069 duty_cycle = duty_cycle+0.01f; 01070 mypwm.write(duty_cycle); 01071 } 01072 else 01073 { 01074 duty_cycle = 0.99f; 01075 } 01076 if(DEVICE1.intensity > 2) 01077 { 01078 DEVICE1.intensity --; //intensity modified 01079 DEVICE2.intensity --; 01080 max7219.set_intensity(DEVICE1); //updating brightness value of DEVICE1 01081 max7219.set_intensity(DEVICE2); //updating brightness value of DEVICE2 01082 } 01083 else 01084 { 01085 DEVICE1.intensity =1; 01086 DEVICE2.intensity =1; //minimum brightnes 01087 max7219.set_intensity(DEVICE1); //updating brightness value of DEVICE1 01088 max7219.set_intensity(DEVICE2); //updating brightness value of DEVICE2 01089 } 01090 break; 01091 01092 case TEST: 01093 test_cnt++; 01094 if(test_cnt <= 1) 01095 test = true; 01096 else if(test_cnt >= 2) 01097 { 01098 test = false; 01099 test_cnt = 0; 01100 } 01101 else 01102 __nop(); 01103 break; 01104 01105 default: 01106 __nop(); 01107 break; 01108 } 01109 } 01110 else 01111 __nop(); 01112 } 01113 /************************************************************************************** 01114 POT SPI Data Read KEY FUNCTIONS 01115 **************************************************************************************/ 01116 unsigned char read_KEY_SPI(int CH) 01117 { 01118 char _key; 01119 switch(CH) 01120 { 01121 case 1: 01122 wait_ms(1); 01123 _key = mcp23s17_1.intcapa(); // read(INTCAPA_ADDR); 01124 wait_ms(1); 01125 break; 01126 01127 case 2: 01128 wait_ms(1); 01129 _key=mcp23s17_1.intcapb(); 01130 wait_ms(1); 01131 break; 01132 01133 case 3: 01134 wait_ms(1); 01135 _key=mcp23s17_2.intcapa(); 01136 wait_ms(1); 01137 break; 01138 case 4: 01139 wait_ms(1); 01140 _key = mcp23s17_2.gpiob(); //address read PORTB of chip2 01141 wait_ms(1); 01142 break; 01143 default: 01144 _key = 0; 01145 break; 01146 } 01147 return(_key); 01148 } 01149 01150 void read_KEY_A() //function check status of PORTA of MCP23S17 (1) chip 01151 { 01152 char key_status = 0; 01153 num_KEY = FALSE0; 01154 key_status = read_KEY_SPI(ch_A); //to read portA of mcp23s17(1) 01155 if(key_status != 0xff) //means some key must have been pressed 01156 { 01157 switch(key_status) 01158 { 01159 case 0xfe: //0xfe GPA0 01160 num_KEY = ZERO; 01161 break; 01162 case 0xfd: //0xfd GPA1 01163 num_KEY = ONE; 01164 break; 01165 case 0xfb: //0xfb GPA2 01166 num_KEY = TWO; 01167 break; 01168 case 0xf7: //0xf7 GPA3 01169 num_KEY = THREE; 01170 break; 01171 case 0xef: //0xef GPA4 01172 num_KEY = FOUR; 01173 break; 01174 case 0xdf: //0xdf GPA5 01175 num_KEY = FIVE; 01176 break; 01177 case 0xbf: //0xbf GPA6 01178 num_KEY = SIX; 01179 break; 01180 case 0x7f: //0x7f GPA7 01181 num_KEY = SEVEN; 01182 break; 01183 default: 01184 num_KEY = FALSE0; 01185 break; 01186 } 01187 NUMERIC_handler(num_KEY); 01188 } 01189 } 01190 01191 void read_KEY_B() 01192 { 01193 char key_status = 0; 01194 num_KEY = FALSE0; 01195 ctrl_KEY = FALSE1; 01196 //dir_KEY = FALSE2; /not required 01197 up_down_KEY = FALSE2; 01198 disp_KEY = FALSE3; 01199 01200 key_status = read_KEY_SPI(ch_B); //to read portBof mcp23s17(1) 01201 if(key_status != 0xff) 01202 { 01203 switch(key_status) 01204 { 01205 case 0xfe: //0xfe GPA0 01206 num_KEY = EIGHT; 01207 NUMERIC_handler(num_KEY); 01208 break; 01209 case 0xfd: //0xfd GPA1 01210 num_KEY = NINE; 01211 NUMERIC_handler(num_KEY); 01212 break; 01213 case 0xfb: //0xfb GPA2 01214 up_down_KEY = UP_key; //dir_KEY = AHEAD; /not required now 01215 UP_DOWN_handler(up_down_KEY); //DIR_handler(dir_KEY); /not required now 01216 break; 01217 case 0xf7: //0xf7 GPA3 01218 up_down_KEY = DOWN_key; //dir_KEY = ASTERN; /not required now 01219 UP_DOWN_handler(up_down_KEY); //DIR_handler(dir_KEY); /not required now 01220 break; 01221 case 0xef: //0xef GPA4 01222 ctrl_KEY = ACK_; 01223 CTRL_handler(ctrl_KEY); 01224 break; 01225 case 0xdf: //0xdf GPA5 01226 disp_KEY = clr_ENTRY; //CE 01227 DISP_handler(disp_KEY); 01228 break; 01229 case 0xbf: //0xbf GPA6 01230 disp_KEY = clr_ALL; //C 01231 DISP_handler(disp_KEY); 01232 break; 01233 case 0x7f: //0x7f GPA7 01234 disp_KEY = ENTER_ACK; 01235 DISP_handler(disp_KEY); 01236 break; 01237 default: 01238 num_KEY = FALSE0; 01239 ctrl_KEY = FALSE1; 01240 //dir_KEY = FALSE2; 01241 up_down_KEY = FALSE2; 01242 disp_KEY = FALSE3; 01243 break; 01244 } 01245 } 01246 } 01247 void read_KEY_C() 01248 { 01249 char key_status = 0; 01250 ctrl_KEY = FALSE1; 01251 set_KEY = FALSE4; 01252 key_status = read_KEY_SPI(ch_C); //to read portA of mcp23s17(2) 01253 if(key_status != 0xff) 01254 { 01255 if(key_status==0xfe) 01256 { 01257 ctrl_KEY = REQ_; //control transfer REQ button pressed 01258 CTRL_handler(ctrl_KEY); 01259 } 01260 else 01261 { 01262 if(key_status==0xfd) 01263 set_KEY = INC; //setting key INC 01264 else if(key_status==0xfb) 01265 set_KEY = DEC; //setting key DEC 01266 else if(key_status==0xf7) 01267 set_KEY = TEST; //setting key TEST 01268 else 01269 { 01270 set_KEY = FALSE4; //setting key TEST 01271 ctrl_KEY = FALSE1; 01272 } 01273 01274 SET_handler(set_KEY); 01275 } 01276 } 01277 } 01278 01279 01280 /************************************************************************************** 01281 POT Serial Data Out FUNCTIONS 01282 **************************************************************************************/ 01283 uint8_t get_checksum(const char *sentence) 01284 { 01285 const char *n = sentence + 1; // Plus one, skip '$' 01286 uint8_t chk = 0; 01287 01288 /* While current char isn't '*' or sentence ending (newline) */ 01289 while (('*' != *n) &&(NMEA_END_CHAR_1 != *n)) 01290 { 01291 if ('\0' == *n || n - sentence > NMEA_MAX_LENGTH) 01292 { 01293 /* Sentence too long or short */ 01294 chk = 0; 01295 } 01296 chk ^= (uint8_t) *n; 01297 n++; 01298 } 01299 return chk; 01300 } 01301 01302 void resp_HB(uint8_t seq) //presentees(submaster,slaves,listeners will respond back to the HB along with REQ and CMD ack status 01303 { 01304 switch(seq) 01305 { 01306 case 0: 01307 sprintf(tx_buf,"$PPOTA,%u,%c*", addr_ID,valid); 01308 checksum_send_byte = get_checksum(tx_buf); 01309 sprintf(tx_buf,"$PPOTA,%u,%c*%u",addr_ID,valid,checksum_send_byte); 01310 break; 01311 case 1: 01312 sprintf(tx_buf,"$PPOTR,%u,%u,%c*", addr_ID, REQ_,'A'); 01313 checksum_send_byte = get_checksum(tx_buf); 01314 sprintf(tx_buf,"$PPOTR,%u,%u,%c*%u",addr_ID,REQ_,'A',checksum_send_byte); 01315 break; 01316 case 2: 01317 sprintf(tx_buf,"$PPOTK,%u,%u,%c*", addr_ID, ACK_,'A'); 01318 checksum_send_byte = get_checksum(tx_buf); 01319 sprintf(tx_buf,"$PPOTK,%u,%u,%c*%u",addr_ID, ACK_,'A',checksum_send_byte); 01320 break; 01321 default: 01322 __nop(); //sprintf(tx_buf,"$PPOTA,%u,%c", addr_ID, valid); 01323 break; 01324 } 01325 Drive_En = 1; 01326 UART.printf("%s\r\n",tx_buf); 01327 wait_ms(2); 01328 Drive_En = 0; 01329 } 01330 01331 void send_ack_CMD(uint8_t cmd_t) 01332 { 01333 sprintf(tx_buf,"$PPOTX,%u,%c*", addr_ID,'A'); 01334 checksum_send_byte = get_checksum(tx_buf); 01335 sprintf(tx_buf,"$PPOTX,%u,%c*%u",addr_ID,'A',checksum_send_byte); 01336 Drive_En = 1; 01337 UART.printf("%s\r\n",tx_buf); 01338 wait_ms(2); 01339 Drive_En = 0; 01340 } 01341 01342 void send_RPM(uint8_t _adr) 01343 { 01344 sprintf(tx_buf,"$PPOTC,%u,%u,%u,%u,%u,%c*", _adr, rpm_data[0],rpm_data[1],rpm_data[2],rpm_data[3],'A'); 01345 checksum_send_byte = get_checksum(tx_buf); 01346 sprintf(tx_buf,"$PPOTC,%u,%u,%u,%u,%u,%c*%u",_adr, rpm_data[0],rpm_data[1],rpm_data[2],rpm_data[3],'A',checksum_send_byte); 01347 Drive_En = 1; 01348 UART.printf("%s\r\n",tx_buf); 01349 wait_ms(2); 01350 Drive_En = 0; 01351 } 01352 01353 /* 01354 void send_DIR(uint8_t _adr) //addr 1-8 of leds,error=1 or 0(no error) 01355 { 01356 sprintf(tx_buf,"$PPOTD,%u,%u,%c*",_adr,dir,'A'); // dir is 1 for ahead, 2 for astern 01357 checksum_send_byte = get_checksum(tx_buf); 01358 sprintf(tx_buf,"$PPOTD,%u,%u,%c*%u",_adr,dir,'A',checksum_send_byte); 01359 Drive_En = 1; 01360 UART.printf("%s\r\n",tx_buf); 01361 wait_ms(2); 01362 Drive_En = 0; 01363 } 01364 */ 01365 01366 void send_HB(uint8_t _adr) //master will send the heartbeat to all presentees at periodic intervals 01367 { 01368 sprintf(tx_buf,"$PPOTH,%u,%c*", _adr,'A'); 01369 checksum_send_byte = get_checksum(tx_buf); 01370 sprintf(tx_buf,"$PPOTH,%u,%c*%u",_adr,'A',checksum_send_byte); 01371 Drive_En = 1; 01372 UART.printf("%s\r\n",tx_buf); 01373 wait_ms(2); 01374 Drive_En = 0; 01375 } 01376 01377 void send_BROADCAST() //addr 1-8 of leds,error=1 or 0(no error) 01378 { 01379 sprintf(tx_buf,"$PPOTB,%u,%u,%c*",err_ALL,err_Status,'A'); 01380 checksum_send_byte = get_checksum(tx_buf); 01381 sprintf(tx_buf,"$PPOTB,%u,%u,%c*%u",err_ALL,err_Status,'A',checksum_send_byte); 01382 Drive_En = 1; 01383 UART.printf("%s\r\n",tx_buf); 01384 wait_ms(2); 01385 Drive_En = 0; 01386 BROADCAST_send=false; 01387 } 01388 /** Function will send ac-M, ac-S, rpm-data(04digits), cmd_state)**/ 01389 void send_ACH() 01390 { 01391 sprintf(tx_buf,"$PPOTS,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%c*", ach_M, ach_S, rpm_data[0],rpm_data[1],rpm_data[2],rpm_data[3],last_entry[0],last_entry[1],last_entry[2],last_entry[3],current_status,'A'); 01392 checksum_send_byte = get_checksum(tx_buf); 01393 sprintf(tx_buf,"$PPOTS,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%c,*%u", ach_M, ach_S, rpm_data[0],rpm_data[1],rpm_data[2],rpm_data[3],last_entry[0],last_entry[1],last_entry[2],last_entry[3],current_status,'A',checksum_send_byte); 01394 Drive_En = 1; 01395 UART.printf("%s\r\n",tx_buf); 01396 wait_ms(2); 01397 Drive_En = 0; 01398 } 01399 01400 void ask_TIME() 01401 { 01402 Hrs_1 = Hrs_2 = Mins_1 = Mins_2 = 0; 01403 sprintf(tx_buf,"$PPOTQ,%u,%u,%u,%u,%c*", Hrs_1,Hrs_2, Mins_1, Mins_2,'A'); //querry to CPU for time 01404 checksum_send_byte = get_checksum(tx_buf); 01405 sprintf(tx_buf,"$PPOTQ,%u,%u,%u,%u,%c*%u", Hrs_1,Hrs_2, Mins_1, Mins_2,'A',checksum_send_byte); 01406 Drive_En = 1; 01407 UART.printf("%s\r\n",tx_buf); 01408 wait_ms(2); 01409 Drive_En = 0; 01410 } 01411 01412 /************************************************************************************** 01413 EOT Serial Data In FUNCTIONS 01414 **************************************************************************************/ 01415 void rcvd_HB() //all devices check for HB along with req response for all presentees 01416 { 01417 if(rcvd_ADDR == addr_ID) //addr_ID self address received 01418 { 01419 HB_rcvd = true; 01420 if(addr_ID > pot_Slave_ER) 01421 { //all listners replied with 01422 resp_HB(0); //normal HB response 01423 } 01424 else //in case of active slave 01425 { 01426 if(ENTER_ACK_key) //RPM ACK key is detected at active slave only 01427 { 01428 send_ack_CMD(1); 01429 RPM_cmd_ack = true; 01430 ENTER_ACK_key = false; 01431 } 01432 /* 01433 else if(DIR_key) //dir ack key detected at active slave 01434 { 01435 DIR_key = false; 01436 DIR_cmd_ack_send = true; 01437 send_ack_CMD(2); 01438 } 01439 */ 01440 else if(REQ_key) 01441 { 01442 REQ_key = false; 01443 resp_HB(1); //req and ack status data in req=1 and ack=2 if true 01444 } 01445 else if(ACK_key) 01446 { 01447 ACK_key = false; 01448 resp_HB(2); //req and ack status data in req=1 and ack=2 if true 01449 } 01450 else 01451 resp_HB(0); //req and ack status data in req=1 and ack=2 if true 01452 } 01453 HB_fail.attach(&HB_fail_state_machine,1); 01454 } 01455 else 01456 __nop(); 01457 } 01458 01459 void resp_rcvd_HB() //master and active/passive slaves check HB response along with req/ack commands 01460 { 01461 static uint8_t checksum_flt[8] = {0,0,0,0,0,0,0,0}; 01462 static bool checksum_err[8] = {false,false,false,false,false,false,false,false}; 01463 if(addr_ID == pot_Master) //only master will be able to monitor status of all eots connected 01464 { 01465 if(send_ADDR == rcvd_ADDR) //valid broadcast not received 01466 { 01467 if(valid_sentence[rcvd_ADDR] == 'A') 01468 { 01469 HB_ack_rcvd = true; 01470 checksum_err[rcvd_ADDR] = false; 01471 checksum_flt[rcvd_ADDR] = 0; 01472 } 01473 else if((valid_sentence[rcvd_ADDR] == 'V')&&(++checksum_flt[rcvd_ADDR]<=3)) 01474 { 01475 HB_ack_rcvd = true; 01476 BROADCAST_send = true; //again broadcast 01477 switch_CH = true; //send active channels again 01478 } 01479 else if((valid_sentence[rcvd_ADDR] == 'V')&&(checksum_flt[rcvd_ADDR]>3)&&(!checksum_err[rcvd_ADDR])) 01480 { 01481 HB_ack_rcvd = false; 01482 checksum_err[rcvd_ADDR] = true; 01483 } 01484 else 01485 __nop(); 01486 01487 } 01488 else 01489 HB_ack_rcvd = false; 01490 } 01491 else 01492 __nop(); 01493 } 01494 01495 void rcvd_ACH() 01496 { 01497 led_ach[ach_M-1] = ON; 01498 if(current_status == 2) 01499 { 01500 led_cmd_ack = _FLASH; 01501 max7219.enable_device(2); 01502 display_flash = true; 01503 } 01504 else if(current_status == 1) 01505 { 01506 led_cmd_ack = ON; 01507 max7219.enable_device(2); 01508 display_flash = false; 01509 } 01510 else 01511 { 01512 led_cmd_ack = OFF; 01513 max7219.enable_device(2); 01514 } 01515 /* 01516 if(current_status_dir == 2) 01517 { 01518 led_dir[dir-1] = _FLASH; 01519 } 01520 else if(current_status_dir == 1) 01521 { 01522 led_dir[dir-1] = ON; 01523 } 01524 else 01525 { 01526 led_dir[dir-1] = OFF; 01527 } 01528 */ 01529 for(uint8_t i = 1; i <= 4 ; i++) //current cmd information 01530 { 01531 max7219.write_digit(2,i,rpm_data[i-1]); //device 2 digits 1-4 //data 0 means left most digit will be blank bcoz no decode mode is used 01532 } 01533 01534 for(uint8_t i = 5; i <=8; i++) //last command executed 01535 { 01536 max7219.write_digit(1,i,last_entry[i-5]); //last cmd 0000 01537 } 01538 01539 if(ach_S != 9) 01540 { 01541 if(ach_S == pot_Slave_MCR) 01542 { 01543 led_ach[pot_Slave_MCR -1] = ON; 01544 if(led_ach[pot_Slave_ER -1] == ON) 01545 led_ach[pot_Slave_ER -1] = OFF; //ER off 01546 else 01547 __nop(); 01548 } 01549 else if(ach_S == pot_Slave_ER) 01550 { 01551 led_ach[pot_Slave_ER -1] = ON; //ER ON 01552 if(led_ach[pot_Slave_MCR -1] == ON) 01553 led_ach[pot_Slave_MCR -1] = OFF; //ER off 01554 else 01555 __nop(); 01556 } 01557 else 01558 __nop(); 01559 01560 if((RPM_cmd || DIR_cmd)&& (addr_ID == ach_S)) // cmd ack not received before its failure control shifted to another slave 01561 { //all key functions enabled for PORTB in active slave only 01562 int_B.rise(&read_KEY_B); 01563 wait_us(10); 01564 mcp23s17_1.gpintenb(0xff); //ff 01565 wait_us(10); 01566 } 01567 else 01568 __nop(); 01569 } 01570 else 01571 { 01572 led_ach[pot_Slave_MCR-1] = _FLASH; 01573 led_ach[pot_Slave_ER-1] = _FLASH; 01574 } 01575 } 01576 01577 void rcvd_rpm_CMD() //all devices check for received command 01578 { 01579 led_cmd_ack = _FLASH; //ack cmd led start flashing 01580 for(uint8_t i = 0; i <= 3 ; i++) 01581 { 01582 max7219.write_digit(2,i+1,rpm_data[i]); //device 2 digits 1-4 //data 0 means left most digit will be blank bcoz no decode mode is used 01583 } 01584 wait_us(10); 01585 buzzer = ON; 01586 display_flash = true; //display start flashing //buzzer on 01587 01588 if(ach_S == addr_ID) 01589 { 01590 int_B.rise(&read_KEY_B); 01591 wait_us(10); 01592 mcp23s17_1.gpintenb(0xff); //ff 01593 wait_us(10); //portc is always enbaled in all cases and PORTA is enabled only for active master 01594 } 01595 else 01596 { 01597 __nop(); 01598 } 01599 CMD_Ticker.attach(&CMD_State_Machine,0.25); //state machine timer started in all connected devices except master 01600 } 01601 /* 01602 void rcvd_dir_CMD() //all devices check for received command 01603 { 01604 DIR_cmd = true; 01605 led_dir[last_dir-1] = OFF; 01606 led_dir[dir-1] = _FLASH; //led flash started 01607 buzzer = ON; //buzzer on 01608 last_dir = dir; //HB-cmd ack pending with "A" 01609 if(ach_S == addr_ID) 01610 { 01611 int_B.rise(&read_KEY_B); //enable portb interupts 01612 mcp23s17_1.gpintenb(0xff); //ff 01613 wait_us(10); 01614 } 01615 DIR_Ticker.attach(&DIR_state_machine,0.25); 01616 } 01617 */ 01618 01619 void rcvd_BROADCAST() 01620 { 01621 for(uint8_t i = 0 ; i <= 7 ; i++) 01622 { 01623 if(((uint8_t)1<<i) & (uint8_t)err_ALL) 01624 { 01625 led_ach[i] = _FLASH; 01626 } 01627 else if(led_ach[i] != ON) 01628 { 01629 led_ach[i]= OFF; 01630 } 01631 else 01632 __nop(); 01633 } 01634 } 01635 01636 void rcvd_TIME() 01637 { 01638 uint8_t Hrs,Mins; 01639 struct tm t; 01640 Hrs = 10*Hrs_1+Hrs_2; 01641 Mins = 10*Mins_1+Mins_2; 01642 t.tm_year = 2018-1900; 01643 t.tm_mon = 5; 01644 t.tm_mday = 16; 01645 t.tm_hour = Hrs; 01646 t.tm_min = Mins; 01647 t.tm_sec = 51; 01648 set_time((time_t)mktime(&t)); 01649 wait_ms(1); 01650 read_RTC(); 01651 wait_ms(1); 01652 time_RCVD = true; 01653 } 01654 01655 void at_timeout() 01656 { 01657 timeout.detach(); 01658 data_fail = true; 01659 } 01660 01661 void read_SERIAL() 01662 { 01663 char rcvd_char; 01664 char rcvd_valid; 01665 //int cmd_t; 01666 uint8_t checksum_calculated; 01667 timeout.attach(&at_timeout,0.100); //100ms timeout 01668 data_fail = false; 01669 while(UART.readable() && (num_bytes < RX_BUFFER_SIZE)&&(!data_fail)) 01670 { 01671 rcvd_char = UART.getc(); 01672 if(rcvd_char == '$') //first character 01673 num_bytes = 0; 01674 else 01675 __nop(); 01676 01677 rx_buf[num_bytes] = rcvd_char; 01678 num_bytes++; 01679 if(rcvd_char == '\n') //last character received 01680 { 01681 timeout.detach(); 01682 strtok(rx_buf,","); 01683 if(strcmp(rx_buf,"$PPOTH") == 0) //* present submaster,Slaves or lsitners receive HB *// 01684 { 01685 sscanf(strtok (NULL,","),"%u", &rcvd_ADDR); //address of connected device 01686 sscanf(strtok (NULL,"*"),"%c", &rcvd_valid); //sentence validity char 01687 sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte); 01688 sprintf(rx_buf,"$PPOTH,%u,%c*",rcvd_ADDR,rcvd_valid); 01689 checksum_calculated = get_checksum(rx_buf); 01690 if(checksum_calculated == checksum_rcvd_byte) 01691 { 01692 rcvd_HB(); //valid sentence received 01693 } 01694 else 01695 __nop(); //valid sentence receivedrcvd_HB(); //set flag when Heartbeat received 01696 } 01697 else if(strcmp(rx_buf,"$PPOTA") == 0) //* Master,submaster and Slaves receive heartbeat resp *// 01698 { 01699 sscanf(strtok (NULL,","),"%u", &rcvd_ADDR); 01700 sscanf(strtok (NULL,"*"),"%c", &rcvd_valid); 01701 sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte); 01702 sprintf(rx_buf,"$PPOTA,%u,%c*",rcvd_ADDR,rcvd_valid); 01703 checksum_calculated = get_checksum(rx_buf); 01704 if(checksum_calculated == checksum_rcvd_byte) 01705 { 01706 valid_sentence[rcvd_ADDR] = rcvd_valid; 01707 resp_rcvd_HB(); //valid sentence received 01708 } 01709 else 01710 __nop(); 01711 } 01712 else if(strcmp(rx_buf,"$PPOTB") == 0) //* submaster,Slaves or listener receive broadcast *// 01713 { 01714 sscanf(strtok (NULL,","), "%u", &err_ALL); //device in error with addr_ID = err_ID 01715 sscanf(strtok (NULL,","), "%u",&err_Status); 01716 sscanf(strtok (NULL,"*"),"%c", &rcvd_valid); //sentence validity char 01717 sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte); 01718 sprintf(rx_buf,"$PPOTB,%u,%u,%c*",err_ALL,err_Status,rcvd_valid); 01719 checksum_calculated = get_checksum(rx_buf); 01720 if(checksum_calculated == checksum_rcvd_byte) 01721 { //valid sentence received 01722 valid = 'A'; 01723 rcvd_BROADCAST(); 01724 } 01725 else 01726 valid = 'V'; //not valid 01727 } 01728 else if(strcmp(rx_buf,"$PPOTC") == 0) //* submaster,Slaves or listener receive CMD *// 01729 { 01730 sscanf(strtok (NULL,","), "%u", &rcvd_ADDR); //cmd extracted 01731 sscanf(strtok (NULL,","), "%u", &rpm_data[0]); //rpm data digit 1 and soon 01732 sscanf(strtok (NULL,","), "%u", &rpm_data[1]); 01733 sscanf(strtok (NULL,","), "%u", &rpm_data[2]); 01734 sscanf(strtok (NULL,","), "%u",&rpm_data[3]); 01735 sscanf(strtok (NULL,"*"),"%c", &rcvd_valid); //sentence validity char 01736 sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte); 01737 sprintf(rx_buf,"$PPOTC,%u,%u,%u,%u,%u,%c*",rcvd_ADDR,rpm_data[0],rpm_data[1],rpm_data[2],rpm_data[3],rcvd_valid); 01738 checksum_calculated = get_checksum(rx_buf); 01739 if(checksum_calculated == checksum_rcvd_byte) 01740 { 01741 valid = 'A'; 01742 RPM_cmd = true; // in all devices who receive RPM command 01743 rcvd_rpm_CMD(); 01744 } 01745 else 01746 valid = 'V'; 01747 } 01748 /* 01749 else if(strcmp(rx_buf,"$PPOTD") == 0) //present submaster,Slaves or lsitners receive HB 01750 { 01751 sscanf(strtok (NULL,","), "%u", &rcvd_ADDR); //address of connected device 01752 sscanf(strtok (NULL,","), "%u",&dir); // 1 for ahead and 2 for astern 01753 sscanf(strtok (NULL,"*"),"%c", &rcvd_valid); //sentence validity char 01754 sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte); 01755 sprintf(rx_buf,"$PPOTD,%u,%u,%c*",rcvd_ADDR,dir,rcvd_valid); 01756 checksum_calculated = get_checksum(rx_buf); 01757 if(checksum_calculated == checksum_rcvd_byte) 01758 { 01759 valid = 'A'; 01760 DIR_cmd = true; 01761 rcvd_dir_CMD(); 01762 } 01763 else 01764 valid = 'V'; //set flag when Heartbeat received 01765 } 01766 */ 01767 else if(strcmp(rx_buf,"$PPOTX") == 0) //* Master,submaster,Slave or listners receive CMD acknowledge *// 01768 { 01769 sscanf(strtok (NULL,","), "%u", &rcvd_ADDR); //address extracted 01770 //sscanf(strtok (NULL,","), "%u",&cmd_t); 01771 sscanf(strtok (NULL,"*"),"%c", &rcvd_valid); //sentence validity char 01772 sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte); 01773 sprintf(rx_buf,"$PPOTX,%u,%c*",rcvd_ADDR,rcvd_valid); 01774 checksum_calculated = get_checksum(rx_buf); 01775 if(checksum_calculated == checksum_rcvd_byte) 01776 { 01777 valid = 'A'; 01778 RPM_cmd_ack = true; 01779 } 01780 else 01781 valid = 'V'; // not valid sentence received; 01782 } 01783 else if(strcmp(rx_buf,"$PPOTS") == 0) //*active channel status recieved *// 01784 { 01785 sscanf(strtok (NULL,","), "%u", &ach_M); //cmd extracted 01786 sscanf(strtok (NULL,","), "%u", &ach_S); 01787 sscanf(strtok (NULL,","), "%u", &rpm_data[0]); 01788 sscanf(strtok (NULL,","), "%u", &rpm_data[1]); 01789 sscanf(strtok (NULL,","), "%u", &rpm_data[2]); 01790 sscanf(strtok (NULL,","), "%u", &rpm_data[3]); 01791 sscanf(strtok (NULL,","), "%u", &last_entry[0]); 01792 sscanf(strtok (NULL,","), "%u", &last_entry[1]); 01793 sscanf(strtok (NULL,","), "%u", &last_entry[2]); 01794 sscanf(strtok (NULL,","), "%u", &last_entry[3]); 01795 //sscanf(strtok (NULL,","), "%u", &dir); 01796 sscanf(strtok (NULL,","), "%u", ¤t_status); 01797 //sscanf(strtok (NULL,","),"%u", ¤t_status_dir); 01798 sscanf(strtok (NULL,"*"),"%c", &rcvd_valid); //sentence validity char 01799 sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte); 01800 sprintf(rx_buf,"$PPOTS,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%c*",ach_M,ach_S,rpm_data[0],rpm_data[1],rpm_data[2],rpm_data[3],last_entry[0],last_entry[1],last_entry[2],last_entry[3],current_status,rcvd_valid); 01801 checksum_calculated = get_checksum(rx_buf); 01802 if(checksum_calculated == checksum_rcvd_byte) 01803 { 01804 valid = 'A'; //valid sentence received 01805 rcvd_ACH(); 01806 } 01807 else 01808 valid = 'V'; 01809 } 01810 else if(strcmp(rx_buf,"$PPOTR") == 0) //* control transfer request arrived*// 01811 { 01812 sscanf(strtok (NULL,","),"%u", &rcvd_ADDR); 01813 sscanf(strtok (NULL,","),"%u", &req); //e.g $R req or $K ack 01814 sscanf(strtok (NULL,"*"),"%c", &rcvd_valid); //sentence validity char 01815 sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte); 01816 if(addr_ID <= pot_Slave_ER) 01817 { 01818 sprintf(rx_buf,"$PPOTR,%u,%u,%c*",rcvd_ADDR,req,rcvd_valid); 01819 checksum_calculated = get_checksum(rx_buf); 01820 if(checksum_calculated == checksum_rcvd_byte) 01821 { 01822 valid = 'A'; 01823 REQ_rcvd = true; 01824 req_ADDR = rcvd_ADDR; 01825 if(((rcvd_ADDR == pot_Master) && (addr_ID == pot_Submaster)) || ((rcvd_ADDR == pot_Submaster) && (addr_ID == pot_Master))) 01826 { 01827 int_B.rise(&read_KEY_B); //to enable ACK key interrupt 01828 wait_us(10); 01829 mcp23s17_1.gpintenb(0xff); // portb of mcp1 ACK key enabled 01830 wait_us(10); 01831 led_ctrl[ACK_-1] = _FLASH; //ack led blink 01832 } 01833 else 01834 __nop(); 01835 01836 if(((rcvd_ADDR == pot_Slave_MCR) && (addr_ID == pot_Slave_ER)) || ((rcvd_ADDR == pot_Slave_ER) && (addr_ID == pot_Slave_MCR))) 01837 { 01838 int_B.rise(&read_KEY_B); //to enable ACK key interrupt 01839 wait_us(10); 01840 mcp23s17_1.gpintenb(0xff); //portb of mcp1 ACK key enabled 01841 wait_us(10); 01842 led_ctrl[ACK_-1] = _FLASH; //ack led blink 01843 } 01844 else 01845 __nop(); 01846 01847 R_A_Ticker.attach(&R_A_Statemachine,0.5); 01848 } 01849 else 01850 valid = 'V'; 01851 } 01852 else 01853 __nop(); 01854 } 01855 else if(strcmp(rx_buf,"$PPOTK") == 0) //* Master,submaster,Slave or listners REQ acknowledge *// 01856 { 01857 sscanf(strtok (NULL,","), "%u", &rcvd_ADDR); 01858 sscanf(strtok (NULL,","),"%u", &ack); //e.g $R req or $K ack 01859 sscanf(strtok (NULL,"*"),"%c", &rcvd_valid); 01860 sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte); 01861 01862 if(addr_ID <= pot_Slave_ER) 01863 { 01864 sprintf(rx_buf,"$PPOTK,%u,%u,%c*",rcvd_ADDR,ack,rcvd_valid); 01865 checksum_calculated = get_checksum(rx_buf); 01866 if(checksum_calculated == checksum_rcvd_byte) 01867 { 01868 valid = 'A'; 01869 ack_ADDR = rcvd_ADDR; 01870 ACK_rcvd = true; 01871 //ACH_SW_over = true; 01872 01873 if(((rcvd_ADDR == pot_Master) && (addr_ID == pot_Submaster)) || ((rcvd_ADDR == pot_Submaster) && (addr_ID == pot_Master))) 01874 { 01875 led_ctrl[ACK_-1] = OFF; 01876 //R_A_Ticker.detach(); 01877 } 01878 else if(((rcvd_ADDR == pot_Slave_ER) && (addr_ID == pot_Slave_MCR)) || ((rcvd_ADDR == pot_Slave_MCR) && (addr_ID == pot_Slave_ER))) 01879 { 01880 led_ctrl[ACK_-1] = OFF; 01881 //R_A_Ticker.detach(); 01882 } 01883 else 01884 __nop(); 01885 } 01886 else 01887 valid = 'V'; 01888 } 01889 else 01890 __nop(); 01891 } 01892 else if(strcmp(rx_buf,"$PPOTT") == 0) //* submaster,Slaves or listener receive CMD *// 01893 { 01894 sscanf(strtok (NULL,","), "%u", &Hrs_1); //cmd extracted 01895 sscanf(strtok (NULL,","), "%u", &Hrs_2); 01896 sscanf(strtok (NULL,","), "%u", &Mins_1); 01897 sscanf(strtok (NULL,","),"%u", &Mins_2); 01898 sscanf(strtok (NULL,"*"),"%c", &rcvd_valid); //sentence validity char 01899 sscanf(strtok (NULL,","),"%u", &checksum_rcvd_byte); 01900 sprintf(rx_buf,"$PPOTT,%u,%u,%u,%u,%c*",Hrs_1,Hrs_2,Mins_1,Mins_2,rcvd_valid); 01901 checksum_calculated = get_checksum(rx_buf); 01902 if(checksum_calculated == checksum_rcvd_byte) 01903 { 01904 valid = 'A'; 01905 rcvd_TIME(); 01906 } 01907 else 01908 valid = 'V'; 01909 } 01910 else 01911 __nop(); 01912 } 01913 else 01914 __nop(); 01915 } 01916 } 01917 01918 /********END of FUNCTION****************/ 01919 01920 /************************************************************************************** 01921 EOT Handler FUNCTIONS 01922 **************************************************************************************/ 01923 void HB_handler() //function run periodically within active master only 01924 { 01925 if(++sync_count >= sync_time) 01926 { 01927 time_RCVD = false; 01928 norm_op = false; 01929 sync_count = 0; 01930 ask_TIME(); //master will send querry for GPS time 01931 } 01932 else if(time_RCVD || norm_op) //as all receive time update normal operation starts 01933 { 01934 if(ach_M == pot_Master) 01935 { 01936 device_addr++; 01937 if(device_addr == no_pot_connected) //max no-pot-conneted = 7 01938 device_addr = 0; 01939 } 01940 else 01941 __nop(); 01942 /*else if(ach_M == eot_Submaster) 01943 { 01944 if(device_addr==2) 01945 { 01946 device_addr=3; 01947 } 01948 else 01949 { 01950 device_addr++; 01951 if(device_addr>NO_MAX_EOT) 01952 device_addr=1; 01953 } 01954 } 01955 */ 01956 01957 send_ADDR = POT[device_addr].slave_ID; 01958 01959 if(RPM_cmd) 01960 { 01961 send_RPM(send_ADDR); 01962 RPM_cmd = false; //cmd to be send with current running address and cmd value 01963 wait_ms(2); 01964 //HB_Ticker.attach(&HB_State_Machine,0.010); 01965 CMD_Ticker.attach(&CMD_State_Machine,0.25); //CMD_state_machine ticker started 01966 } 01967 /* 01968 else if(DIR_cmd) 01969 { 01970 send_DIR(send_ADDR); 01971 DIR_cmd = false; //cmd to be send with current running address and cmd value 01972 wait_ms(2); 01973 //HB_Ticker.attach(&HB_State_Machine,0.010); 01974 //DIR_Ticker.attach(&DIR_state_machine,0.25); //CMD_state_machine ticker started 01975 } 01976 */ 01977 else if(BROADCAST_send) 01978 { 01979 send_BROADCAST(); //broadcast needed err_ID nd err_Status 01980 BROADCAST_send = false; 01981 wait_ms(2); 01982 } 01983 else if(switch_CH) //active channel switch over happened 01984 { 01985 send_ACH(); //active channel changeover 01986 switch_CH = false; 01987 wait_ms(2); 01988 } 01989 01990 else 01991 { 01992 send_HB(send_ADDR); //hb is to be going on 01993 HB_Ticker.attach(&HB_State_Machine,0.015); //HB_state_machine timer started 01994 } 01995 } 01996 else if(++norm_count >= 5) 01997 { 01998 norm_count = 0; 01999 if(!time_RCVD) 02000 norm_op = true; 02001 else 02002 __nop(); 02003 } 02004 else 02005 __nop(); 02006 } 02007 02008 /************************************************************************************** 02009 POT config and address Read FUNCTIONS 02010 **************************************************************************************/ 02011 void read_POT_ADDR() //function give present eots and no. of connected eots 02012 { 02013 pot_Addr = read_KEY_SPI(ch_D); 02014 if(pot_Addr==0xff) //if 0xff it means no addressing done 02015 pot_Error=true; 02016 else if(pot_Addr!=0xff) 02017 { 02018 for( uint8_t i=0;i<=7;i++) 02019 { 02020 if(((1 << i) & pot_Addr)== 0) // to check which bit of eot_Addr register is '0' 02021 { 02022 if(i==0) // bit 0 means master present and soon 02023 { 02024 addr_ID = pot_Master; 02025 ach_M = pot_Master; 02026 for(i = 1 ; i <= 7 ; i++) 02027 { 02028 if((((uint8_t)1<<i) & pot_Addr) == 0) 02029 { 02030 switch(i) 02031 { 02032 case 1: 02033 POT[no_pot_connected].slave_ID = pot_Submaster; 02034 POT[no_pot_connected].err_cnt=0; 02035 POT[no_pot_connected].err_status=false; 02036 no_pot_connected++; 02037 break; 02038 case 2: 02039 ach_S = pot_Slave_MCR; 02040 POT[no_pot_connected].slave_ID = pot_Slave_MCR; 02041 POT[no_pot_connected].err_cnt=0; 02042 POT[no_pot_connected].err_status=false; 02043 no_pot_connected++; 02044 break; 02045 case 3: 02046 if(ach_S == pot_Slave_MCR) //if MCR ispresent 02047 __nop(); 02048 else 02049 { //if MCR is not present 02050 ach_S = pot_Slave_ER; 02051 } 02052 POT[no_pot_connected].slave_ID = pot_Slave_ER; 02053 POT[no_pot_connected].err_cnt = 0; 02054 POT[no_pot_connected].err_status=false; 02055 no_pot_connected++; 02056 break; 02057 case 4: 02058 POT[no_pot_connected].slave_ID = pot_Listner_WP; 02059 POT[no_pot_connected].err_cnt = 0; 02060 POT[no_pot_connected].err_status=false; 02061 no_pot_connected++; 02062 break; 02063 case 5: 02064 POT[no_pot_connected].slave_ID = pot_Listner_WS; 02065 POT[no_pot_connected].err_cnt=0; 02066 POT[no_pot_connected].err_status=false; 02067 no_pot_connected++; 02068 break; 02069 case 6: 02070 POT[no_pot_connected].slave_ID = pot_Listner_OPS; 02071 POT[no_pot_connected].err_cnt=0; 02072 POT[no_pot_connected].err_status=false; 02073 no_pot_connected++; 02074 break; 02075 case 7: 02076 POT[no_pot_connected].slave_ID = pot_Listner_ASP; 02077 POT[no_pot_connected].err_cnt=0; 02078 POT[no_pot_connected].err_status=false; 02079 no_pot_connected++; 02080 break; 02081 } 02082 } 02083 } 02084 if(no_pot_connected <=0) 02085 pot_Error = true; 02086 else 02087 pot_Error = false; 02088 } 02089 else 02090 { 02091 switch(i) 02092 { 02093 case 1: 02094 { 02095 addr_ID = pot_Submaster; 02096 ach_S = pot_Slave_MCR; 02097 led_ach[ach_S-1] = ON; 02098 break; 02099 } 02100 case 2: 02101 { 02102 addr_ID = pot_Slave_MCR; 02103 ach_S = pot_Slave_MCR; 02104 led_ach[ach_S-1] = ON; 02105 break; 02106 } 02107 case 3: 02108 { 02109 addr_ID = pot_Slave_ER; 02110 ach_S = pot_Slave_MCR; 02111 led_ach[ach_S-1] = ON; 02112 break; 02113 } 02114 case 4: 02115 { 02116 addr_ID = pot_Listner_WP; 02117 ach_S = pot_Slave_MCR; 02118 led_ach[ach_S-1] = ON; 02119 break; 02120 } 02121 case 5: 02122 { 02123 addr_ID = pot_Listner_WS; 02124 ach_S = pot_Slave_MCR; 02125 led_ach[ach_S-1] = ON; 02126 break; 02127 } 02128 case 6: 02129 { 02130 addr_ID = pot_Listner_OPS; 02131 ach_S = pot_Slave_MCR; 02132 led_ach[ach_S-1] = ON; 02133 break; 02134 } 02135 case 7: 02136 { 02137 addr_ID = pot_Listner_ASP; 02138 ach_S = pot_Slave_MCR; 02139 led_ach[ach_S-1] = ON; 02140 break; 02141 } 02142 default: 02143 pot_Error = true; 02144 } 02145 } 02146 } 02147 } 02148 } 02149 } 02150 02151 void interrupt_init() 02152 { 02153 int_A.mode(PullUp); 02154 wait_ms(1); 02155 int_B.mode(PullUp); 02156 wait_ms(1); 02157 int_C.mode(PullUp); 02158 wait_ms(1); 02159 } 02160 02161 void Uart_init() 02162 { 02163 UART.baud(9600); 02164 UART.format(8,SerialBase::None,1); 02165 wait_ms(1); 02166 } 02167 02168 void Led_init() 02169 { 02170 02171 LED_CMD_ACK = ON; 02172 wait_ms(1); 02173 02174 for(uint8_t i=0;i<=1;i++) //ctrl led intialisation 02175 { 02176 LED_CTRL[i] = ON; 02177 wait_ms(1); 02178 } 02179 /* 02180 for(uint8_t i=0;i<=1;i++) //ctrl led intialisation 02181 { 02182 LED_DIR[i] = ON; 02183 wait_ms(1); 02184 } 02185 */ 02186 for(uint8_t i=0; i<=7;i++) //ach led initialisation 02187 { 02188 LED_ACH[i] = ON ; 02189 wait_ms(1); 02190 } 02191 02192 wait(1); 02193 02194 LED_CMD_ACK = OFF; 02195 led_cmd_ack = OFF; 02196 wait_ms(1); 02197 02198 for(uint8_t i=0;i<=1;i++) //ctrl led turned off 02199 { 02200 LED_CTRL[i] = OFF; 02201 led_ctrl[i] = OFF; 02202 wait_ms(1); 02203 } 02204 /* 02205 for(uint8_t i=0;i<=1;i++) //ctrl led intialisation 02206 { 02207 LED_DIR[i] = OFF; 02208 led_dir[i] = OFF; 02209 wait_ms(1); 02210 } 02211 */ 02212 for(uint8_t i=0; i<=7;i++) //ach led turned off 02213 { 02214 LED_ACH[i] = OFF; 02215 led_ach[i] = OFF; 02216 wait_ms(1); 02217 } 02218 } 02219 02220 void pwm_init() 02221 { 02222 mypwm.period_ms(10); //initialy 20ms 02223 wait_us(1); 02224 mypwm.write(.10); //10%duty cycle more bright with less duty cycle 02225 wait_us(1); 02226 } 02227 02228 void mcp23s17_init() 02229 { 02230 //device1 configuration 02231 mcp23s17_1.reset(); //reset on power-up 02232 wait_ms(1); 02233 mcp23s17_2.reset(); //reset on power-up 02234 wait_ms(1); 02235 mcp23s17_1.iocon(0x2a); 02236 wait_ms(1); 02237 mcp23s17_2.iocon(0x2a); 02238 wait_ms(1); 02239 mcp23s17_1.iodira(0xff); //set 8-bits PORTA as inputs 02240 wait_ms(1); 02241 mcp23s17_1.iodirb(0xff); //set 8-bits PORTB as inputs 02242 wait_ms(1); 02243 mcp23s17_1.ipola(0x00); 02244 wait_ms(1); 02245 mcp23s17_1.ipolb(0x00); 02246 wait_ms(1); 02247 mcp23s17_1.gpintena(0x00); //initially disabled 02248 wait_ms(1); 02249 mcp23s17_1.gpintenb(0x00); 02250 wait_ms(1); 02251 mcp23s17_1.defvala(0xff); 02252 wait_ms(1); 02253 mcp23s17_1.defvalb(0xff); 02254 wait_ms(1); 02255 mcp23s17_1.intcona(0x00); //bank0,mirror disabled, SEQOP disabled, slew rate disabled,HAEN enabled,open drain enabled,interrupt active high,not allowed 02256 wait_ms(1); 02257 mcp23s17_1.intconb(0x00); 02258 wait_ms(1); 02259 mcp23s17_1.gppua(0xff); 02260 wait_ms(1); 02261 mcp23s17_1.gppub(0xff); 02262 wait_ms(1); 02263 02264 //device2 configuration 02265 02266 mcp23s17_2.iodira(0xff); //set 8-bits PORTA as inputs 02267 wait_ms(1); 02268 mcp23s17_2.iodirb(0xff); //set 8-bits PORTb as inputs 02269 wait_ms(1); 02270 mcp23s17_2.ipola(0x00); 02271 wait_ms(1); 02272 mcp23s17_2.ipolb(0x00); 02273 wait_ms(1); 02274 mcp23s17_2.gpintena(0xff); //initially 0xff will be always enabled req/inc/dec/test 02275 wait_ms(1); 02276 mcp23s17_2.gpintenb(0x00); //interrupts disabled for address PORT 02277 wait_ms(1); 02278 mcp23s17_2.defvala(0xff); 02279 wait_ms(1); 02280 mcp23s17_2.defvalb(0xff); 02281 wait_ms(1); 02282 mcp23s17_2.intcona(0x00); //bank0,mirror disabled, SEQOP disabled, slew rate disabled,HAEN enabled,open drain enabled,interrupt active high,not allowed 02283 wait_ms(1); 02284 mcp23s17_2.intconb(0x00); 02285 wait_ms(1); 02286 mcp23s17_2.gppua(0xff); 02287 wait_ms(1); 02288 mcp23s17_2.gppub(0xff); 02289 wait_ms(1); 02290 mcp23s17_1.intcapa(); //dummy read performed to clear any interrupt on power up 02291 wait_ms(1); 02292 mcp23s17_1.intcapb(); 02293 wait_ms(1); 02294 mcp23s17_2.intcapa(); 02295 wait_ms(1); 02296 02297 } 02298 02299 void Spi3_init() //for mcp23s17 02300 { 02301 _SPI3.format(8,0); //8bit,mode 0 02302 _SPI3.frequency(1000000); //1mhz 02303 wait_ms(1); 02304 } 02305 02306 void RTC_init() 02307 { 02308 read_RTC(); 02309 wait_ms(1); 02310 RTC_display(RTC_buffer); 02311 wait_ms(1); 02312 } 02313 02314 void SetDateTime 02315 ( int year = 0 02316 ,int mon = 0 02317 ,int day = 0 02318 ,int hour = 0 02319 ,int min = 0 02320 ,int sec = 0 02321 ) 02322 { 02323 struct tm Clock; 02324 Clock.tm_year = year - 1900; 02325 Clock.tm_mon = mon; 02326 Clock.tm_mday = day; 02327 Clock.tm_hour = hour; 02328 Clock.tm_min = min; 02329 Clock.tm_sec = sec; 02330 time_t epoch = mktime(&Clock); 02331 set_time(epoch); //time set 02332 } 02333 02334 void max7219_init() 02335 { 02336 max7219.set_num_devices(2); //total 02 no. of devices 02337 DEVICE1.device_number = 0x01; 02338 DEVICE1.decode_mode = 0xff; //bcd decode mode 02339 DEVICE1.intensity = 0x01; //Max7219::MAX7219_INTENSITY_8, 02340 DEVICE1.scan_limit = 0x07; // 1-4 digits RTC,5-8 digits last cmd RPM 02341 wait_ms(1); 02342 DEVICE2.device_number = 0x02; // 02343 DEVICE2.decode_mode = 0xff; //bcd decode mode 02344 DEVICE2.intensity = 0x01; //Max7219::MAX7219_INTENSITY_8, //intensity moderate 02345 DEVICE2.scan_limit = 0x03; //1-4 digits current 02346 wait_ms(1); 02347 02348 max7219.init_device(DEVICE1); //DEVICE 1 configured as per above settings 02349 wait_ms(1); 02350 max7219.enable_device(1); //normal operation 02351 wait_ms(1); 02352 max7219.init_device(DEVICE2); //DEVICE 2 configured as per above settings 02353 wait_ms(1); 02354 max7219.enable_device(2); //normal operation 02355 wait_ms(1); 02356 max7219.set_display_test(); //all on 02357 wait(1); 02358 max7219.clear_display_test(); //normal operation 02359 wait_ms(1); 02360 for(uint8_t i=1; i<=4; i++) 02361 { 02362 max7219.write_digit(1, i, 0x00); //device 1 RTC, digit 1-4 ,data 0x01 02363 wait_us(100); 02364 } 02365 wait_ms(100); 02366 02367 for(uint8_t i=4; i<=8; i++) 02368 { 02369 max7219.write_digit(1, i, 0x00); //device 1 last cmd, digit 4-8 ,data 0x01 02370 wait_us(100); 02371 } 02372 wait_ms(100); 02373 for(uint8_t i=1; i<=4;i++) 02374 { 02375 max7219.write_digit(2, i, 0x00); //device 2 current CMD, digits 1-4 ,data 0x01 02376 } 02377 wait_ms(100); 02378 } 02379 02380 void Spi2_init() // for max7219 02381 { 02382 _SPI2.format(16,0); //16bit,mode 0 02383 _SPI2.frequency(1000000); //1mhz 02384 wait_ms(1); 02385 } 02386 02387 void Discrete_init() 02388 { 02389 buzzer = ON; 02390 hooter = ON; //on 02391 wait(1); // one second delay 02392 buzzer = OFF; 02393 hooter = OFF; //off 02394 } 02395 02396 void Parameters_init() 02397 { 02398 /*intialization of all bool data types indicating different error flags */ 02399 pot_Error = false; 02400 device_ERR = false; 02401 pot_MCR_err = false; 02402 pot_ER_err = false; 02403 test = false; 02404 toggle = false; 02405 toggle_fast = false; 02406 display_flash = false; 02407 norm_op = false; 02408 02409 /*intialization of all bool data types indicating flag on key press interruption */ 02410 key_CMD = false; 02411 key_CTRL = false; 02412 key_SET = false; 02413 REQ_key = false; 02414 ACK_key = false; 02415 RPM_cmd = false; //if true RPM command is raised 02416 DIR_cmd = false; //if true DIR command is raised 02417 ENTER_ACK_key = false; 02418 disp_clear = false; 02419 02420 /*intialization of all bool data types indicating flags while serial receive */ 02421 RPM_cmd_ack = false; 02422 HB_ack_rcvd = false; 02423 BROADCAST_rcvd = false; 02424 HB_rcvd = false; 02425 REQ_rcvd = false; 02426 ACK_rcvd = false; 02427 time_RCVD = false; 02428 data_fail = false; 02429 02430 /*intialization of all bool data types indicating flags while serial transmit */ 02431 BROADCAST_send = false; 02432 RPM_cmd_ack_send = false; 02433 DIR_cmd_ack_send = false; 02434 REQ_send = false; 02435 ACK_send = false; 02436 HB_send = false; 02437 02438 /*intialization of all bool data types indicating active channel changeover*/ 02439 test=false; 02440 disp_test = false; 02441 ACH_SW_over = switch_CH = false; 02442 02443 display_flash = false; 02444 02445 /*intialization of all int data types*/ 02446 addr = req = ack = ach_S = ach_M = duty_cycle = sync_count = 0; 02447 pot_Addr = addr_ID = send_ADDR = rcvd_ADDR = req_ADDR = ack_ADDR = 0; 02448 test_cnt = err_ID = err_Status = ticker_count = ticker_count_fast = current_status = current_status_dir= 0; 02449 spi_error = set_bit = err_ALL = no_pot_connected = norm_count = Hrs_1 = Hrs_2 = Mins_1 = Mins_2 = 0; 02450 checksum_send_byte = checksum_rcvd_byte = 0; 02451 02452 //dir = last_dir = 0; 02453 HB_timer =0; 02454 sync_time = 0; 02455 num_bytes = 0; 02456 02457 device_addr = -1; 02458 valid = 'A'; 02459 02460 POT = new _POT[NO_MAX_POT]; 02461 } 02462 02463 void POT_INIT() 02464 { 02465 Parameters_init(); 02466 wait_ms(1); 02467 02468 Discrete_init(); 02469 wait_ms(1); 02470 02471 Spi2_init(); 02472 wait_ms(1); 02473 02474 max7219_init(); 02475 wait_ms(1); 02476 02477 SetDateTime(2017,11,16,16,45,40); // set default date and time 02478 wait_ms(1); 02479 02480 RTC_init(); 02481 wait_ms(1); 02482 02483 Spi3_init(); 02484 wait_ms(1); 02485 02486 mcp23s17_init(); 02487 wait_ms(1); 02488 02489 pwm_init(); 02490 wait_ms(1); 02491 02492 Led_init(); 02493 wait_ms(1); 02494 02495 Uart_init(); 02496 wait_ms(1); 02497 02498 read_POT_ADDR(); 02499 wait_ms(1); 02500 02501 interrupt_init(); 02502 wait_ms(1); 02503 02504 if((addr_ID == pot_Master)&&(!pot_Error)) //if addres of master eot found, by default master 02505 { 02506 wait(10); //wait for 10sec,as MCU take time to read time from GPS 02507 led_ach[ach_M-1] = ON; 02508 int_A.rise(&read_KEY_A); //all key functions enabled for PORTA,B,C 02509 int_B.rise(&read_KEY_B); 02510 int_C.rise(&read_KEY_C); 02511 wait_ms(2); 02512 mcp23s17_1.gpintena(0xff); //interrupts enabled 02513 wait_us(100); 02514 mcp23s17_1.gpintenb(0xff); //ff 02515 wait_us(100); 02516 HB_timer = 1.0/no_pot_connected; 02517 sync_time = 3600/HB_timer; // 3600.0/HB_timer; required 02518 pot_HB.attach(&HB_handler,HB_timer); // 02519 wait_ms(1); 02520 UART.attach( &read_SERIAL); //receive interrupt enabled 02521 wait_ms(1); 02522 ask_TIME(); //send enquiry to Central power unit for time setting 02523 wait_ms(2); 02524 send_ACH(); 02525 wait_ms(2); 02526 } 02527 else if(pot_Submaster <= addr_ID <= pot_Listner_ASP) 02528 { 02529 wait(1); 02530 led_ach[0] = ON; //by default master led turns on 02531 int_A.rise(NULL); //all key functions/interrupt disabled for PORTA,B 02532 int_B.rise(NULL); 02533 int_C.rise(&read_KEY_C); //only PORTC needs to be intialized in other all cases,inc,dec,tst,req 02534 wait_ms(1); 02535 UART.attach( &read_SERIAL); //receive interrupt enabled 02536 wait_ms(1); 02537 } 02538 else if(pot_Error) 02539 { 02540 int_A.rise(NULL); 02541 int_B.rise(NULL); 02542 int_C.rise(NULL); 02543 pot_Error = true; 02544 //return(-1); 02545 } 02546 else 02547 { 02548 __nop(); 02549 } 02550 } 02551 02552 int main() 02553 { 02554 POT_INIT(); 02555 02556 led_refresh.attach(&update_led , 0.020); //refresh rate 20ms 02557 wait_ms(2); 02558 02559 RTC_ticker.attach(&read_RTC , 59); //after 60 sec 02560 wait_ms(2); 02561 02562 while(1) 02563 { 02564 } 02565 }
Generated on Sat Jul 16 2022 04:20:55 by
1.7.2
