A twist to the computer that landed man on the moon. More information can be found at http://hackaday.io/project/294-Open-Source-DSKY
Dependencies: DS1302 keypad mbed
main.cpp
- Committer:
- VivaPenguinos
- Date:
- 2014-08-20
- Revision:
- 6:3019f2f7e9d4
- Parent:
- 5:5f08974ef8bb
- Child:
- 7:3d06d866878c
File content as of revision 6:3019f2f7e9d4:
/* Introduction MBED DSKY This is a personal project used developed by penguinos to mix old school technology with a modern twist. Version 0.06: August. 15 2014 NO_Light() function has now case 8 for Indicator lights - P00 Improvements - P06 CMC Power Down Completed - CMC_Powerdown() Added - CMC_PowerInput() Added Notable Credits: NASA! - Release of technical documentations regarding the AGC and DSKY Ron Burkley and Contributers of "Virtual AGC — AGS — LVDC — Gemini" - Providing Technical documentations, Source Code, explanations, and refrences on other sites to make this project successful Warning: This may contain author's crude language, and random thoughts. Software Licenses: Keypad.h - Author Copyrighted 2012 but it is under the Open Source License Agreement. Source: http://mbed.org/cookbook/Keypad DS1302.h - Open Source License Source: http://mbed.org/components/DS1302-Timekeeping-Chip/ Pin Usage: Real Time Clock SCLK PTC5 IO PTC4 CE PTC3 Keypad Row0 PTD4 Row1 PTA12 Row2 PTD3 Row3 PTA5 Col1 PTA13 Col2 PTD5 Col3 PTD0 Col4 PTD2 Shift Registers Latch PTC6 Clock PTC10 Data PTC11 Statues Indicator Uplink ACTY PTE5 NO ATT PTE4 STBY PTE3 KEY REL PTE2 OPP ERR PTB11 TEMP PTB10 GIMBAL LOCK PTB9 PROG PTB8 RESTART PTC12 TRACKER PTC13 R1+ PTC16 R2+ PTC17 R3+ PTA16 R1- PTA17 R2- PTE31 R3- PTC6 COMP ACTY PTC7 Push Button PRO_BUTT PTB1 CLR_BUTT PTB2 KEYREL_BUTT PTB3 Shift Registers Data: Because the project contains 11 shift registers, All data must be properly formatted before shifting out. each shift register controls 2 7 segments. R1_A [P_A | P_B] R1_B R1_C [V_A | V_B] [N_A | N_B] R1_D R1_E [R3_E | R3_D | R3_C | R3_B | R3_A] R2_A R2_B [R2_E | R2_D | R2_C | R2_B | R2_A] R2_C R2_D [R1_E | R1_D | R1_C | R1_B | R1_A] R2_E R3_A R3_B R3_C R3_D R3_E V_A V_B N_A N_B P_A P_B Program Added: P01 - PRELAUNCH OR SERVICE - INITIALIZATION PROGRAM P02 - PRELAUNCH OR SERVICE - GYROCOMPASSING PROGRAM Program In Progress (Not completed) P00 - CMC IDLING PROGRAM P06 - CMC POWER DOWN PROGRAM */ // For RTC #define SCLK PTC5 #define IO PTC4 #define CE PTC3 // Comment Line if DS1302 is already running #define INITIAL_RUN using namespace std; #include "mbed.h" #include "Keypad.h" // Keypad #include "DS1302.h" // RTC for DS1032 DS1302 clk(SCLK, IO, CE); //DS1302 clk(SCLK, IO, PTC3); //Declare Variables // int shift = 0; // Shift Data // In the Arduino Version it uses a String. Will use an Int instead to see if this works on Mbed int Verb_Number1 = 0; int Verb_Number2 = 0; int Noun_Number1 = 0; int Noun_Number2 = 0; int Enter_Number1 = 0; int Enter_Number2 = 0; int Verb; // DSKY Verb int Noun; // DSkY Noun int Enter; // DSKY Enter // For shift register use. Refer to shift register data for additional information. int R1_A = 0x0f; int R1_B = 0x0f; int R1_C = 0x0f; int R1_D = 0x0f; int R1_E = 0x0f; int R2_A = 0x0f; int R2_B = 0x0f; int R2_C = 0x0f; int R2_D = 0x0f; int R2_E = 0x0f; int R3_A = 0x0f; int R3_B = 0x0f; int R3_C = 0x0f; int R3_D = 0x0f; int R3_E = 0x0f; int V_A = 0x0f; int V_B = 0x0f; int N_A = 0x0f; int N_B = 0x0f; int P_A = 0x0f; int P_B = 0x0f; // For R use. int R_Pos = 0; int R_Neg = 0; int RA = 0; int RB = 0; int RC = 0; int RD = 0; int RE = 0; int RP = 0; int RVA = 0x0f; int RVB = 0x0f; int RVC = 0x0f; int RVD = 0x0f; int RVE = 0x0f; int R_Position = 1; int R1_Position = 1; int R2_Position = 1; int R3_Position = 1; int GET_Config_Time = 0; // For N Use. int NA = 0x0f; int NB = 0x0f; int N_Position = 1; // PC Variables (Future use) int IMUPWR = 1; // DSKY Variables int LAUNCHAZ = 0; // LAUNCH AZIMUTH int R1_COMP; // Keypad char Keytable[] = { '1', '2', '3', '+', // R0 '4', '5', '6', '-', // R1 '7', '8', '9', 'E', // R2 'V', '0', 'N', 'R', // R3 }; // C0 C1 C2 C3 // RTC Variables int TIME_VALUE = 1397702161; int Time_Difference = 0%60; // Button State int32_t Index = -1; // Button int State; // Function Declaration void Interruption(); void Verb_Button(); void Noun_Button(); void Enter_Button(); void compare(); void blinkAll(int amount, int delay);// Function that Blinks all LED void Shift(); // Function that shifts all data void R_GET(int R); // Grab inputs for Rows void N_GET(); // Grab inputs for Noun void NO_Light(int L); // Configures shift registers to 0 void PreLaunch_Gyrocompassing_Configure(); // For the inputs of the PreLaunch_Gyrocompassing void CMC_PowerInput(); // For the Inputs of the CMC_Powerdown(); int Button_Sort(int sort); // Function that sorts Verb Values int R_Concatenate(int C); // Used for concatenating information //void ShiftingOut(char myDataOut); // Program Names void Ground_Elapse_Time(); // Ground Elapse Time void Test_Lights(); // Test Lights void GET_Config(); // Configures Ground Elapse Time void CMC_Idle(); // P00 - CMC Idling Program void PreLaunch_Initialization(); // P01 - Prelaunch - Initialization Program void PreLaunch_Gyrocompassing(); // P02 - Prelaunch - Gyrocompassing Program void CMC_Powerdown(); // P06 - CMC Power Down Program int R1_Component(); // Load Component into R1 // CMC_Idle Variables // Time of State Vector Being Integrated int ToSSeconds = 0; int ToSMinutes = 0; int ToSHours = 0; // Temp Variables or functions. (This should generally have nothing every revision. Either remove or move the items) int PRO = 0; void CMC_Poweron(); int Button_Detect = 0; // Used for detecting button presses. // Pin modes for each pins DigitalOut LatchPin (PTC6); //Pin for ST_CP of 74HC595 Pin # 12 DigitalOut ClockPin (PTC10); //Pin for SH_CP of 74HC595 Pin # 11 DigitalOut DataPin (PTC11); //Pin for to DS of 74HC595 Pin # 14 // Indicator Lights DigitalOut UPLINK_ACTY (PTE5); DigitalOut NO_ATT (PTE4); DigitalOut STBY (PTE3); DigitalOut KEY_REL (PTE2); DigitalOut OPP_ERR (PTB11); DigitalOut TEMP (PTB10); DigitalOut GIMBAL_LOCK (PTB9); DigitalOut PROG (PTB8); DigitalOut RESTART (PTC12); DigitalOut TRACKER (PTC13); DigitalOut R1_POS (PTC16); DigitalOut R2_POS (PTC17); DigitalOut R3_POS (PTA16); DigitalOut R1_NEG (PTA17); DigitalOut R2_NEG (PTE31); DigitalOut R3_NEG (PTD6); DigitalOut COMP_ACTY (PTD7); // Push Buttons DigitalIn PRO_BUTT (PTB1); DigitalIn CLR_BUTT (PTB2); DigitalIn KEYREL_BUTT (PTB3); // LED DigitalOut myled(LED1); Serial pc(USBTX, USBRX); // tx, rx Serial Output to PC Enabling this WILL consume resources. Use only for debug unsigned concatenate(unsigned x, unsigned y); uint32_t cbAfterInput(uint32_t index) { Index = index; return 0; } int main() { pc.printf("Initialization...\n"); wait(1); pc.printf("Testing shift registers.\n"); blinkAll(4,1); pc.printf("Shift Register: PASS \n"); wait(1); pc.printf("Energizing keypad\n"); State = 1; // r0 r1 r2 r3 c0 c1 c2 c3 Keypad keypad(PTD4, PTA12, PTD3, PTA5, PTA13, PTD5, PTD0, PTD2, 20); keypad.attach(&cbAfterInput); keypad.start(); // energize the columns c0-c3 of the keypad pc.printf("Keypad: PASS \n"); pc.printf("Initialize RTC Clock. \n"); #ifdef INITIAL_RUN clk.set_time(TIME_VALUE); #endif //char storedByte = clk.recallByte(0); //clk.storeByte(0, storedByte + 1); pc.printf("RTC: PASS \n"); pc.printf("Welcome to DSKY!\n"); while (1) { // Input side // Keypad: __wfi(); if (Index >-1) { pc.printf("Interrupted"); pc.printf("Index:%d => Key:%c\r\n", Index, Keytable[Index]); if (Index == 12) { // Index 12 = Verb Button Verb_Button(); // Goes to Verb_Button } if (Index == 14) { // Index 14 = Noun Button Noun_Button(); // Goes to Noun_Button } if (Index == 11) { // Index 11 = Enter Button Enter_Button(); // Goes to Enter_Button } Index = -1; } // Button: if ((Button_Detect == 0) && (PRO_BUTT == 0)){ wait_ms(25); pc.printf("Pro Button Pressed\n"); } else if (CLR_BUTT == 0){ wait_ms(25); pc.printf("Clr Button Pressed\n"); } else if (KEYREL_BUTT == 0){ wait_ms(25); pc.printf("Key Rel Button Pressed\n"); } myled = PRO_BUTT; // Debug use only //pc.printf("%c", Keytable[Verb_Number1]); //pc.printf("%c", Keytable[Verb_Number2]); //pc.printf("%c", Keytable[Noun_Number1]); //pc.printf("%c", Keytable[Noun_Number2]); } } void Interruption() { pc.printf("Interrupted"); pc.printf("Index:%d => Key:%c\r\n", Index, Keytable[Index]); if (Index == 12) { // Index 12 = Verb Button Verb_Button(); // Goes to Verb_Button } if (Index == 14) { // Index 14 = Noun Button Noun_Button(); // Goes to Noun_Button } if (Index == 11) { // Index 11 = Enter Button Enter_Button(); // Goes to Enter_Button } Index = -1; } /* This function is used when the Verb Button has been pressed. Take the inputs of the button twice and determine if the buttons are integers. If other buttons are pressed send it to their perspective locations. */ void Verb_Button(){ Verbz: // Don't Ask // All Variables for Verb, Noun and Enter are zeroed out Verb_Number1 = 0; Verb_Number2 = 0; Noun_Number1 = 0; Noun_Number2 = 0; Enter_Number1 = 0; Enter_Number2 = 0; pc.printf("Please enter a Verb Number"); __wfi(); Verb_Number1 = Index; if (Verb_Number1 == 12){ // This is section is used on atleast one of the two Verb_Number variabels to prevent a Nestled If within if within if. goto Verbz; // Line 110 } else { V_A = Button_Sort(Verb_Number1); Shift(); } //pc.printf("%c", Verb_Number1); //pc.printf("%c", Keytable[Index]); __wfi(); Verb_Number2 = Index; V_B = Button_Sort(Verb_Number2); Shift(); //pc.printf("%c", Verb_Number2); //pc.printf("%c", Verb_Number1); //pc.printf("%c\n", Verb_Number2); } /* This Function is used when the Verb Button has been Pressed. Take the inputs of the button twice and determine if the buttons are integers. If other buttons are pressed send it to their perspective locations. */ void Noun_Button() { Nounz: pc.printf("Please enter a Noun Number"); __wfi(); Noun_Number1 = Index; if (Noun_Number1 == 14) {// This is section is used on atleast one of the two Noun_Number variabels to prevent a Nestled If within if within if. goto Nounz; } else{ N_A = Button_Sort(Noun_Number1); Shift(); } __wfi(); Noun_Number2 = Index; N_B = Button_Sort(Noun_Number2); Shift(); } /* This function is used wen the Enter button has been pressed. This function is a special circumstance since it will be checking both the Verb and Noun variables before entering variable to Enter. */ void Enter_Button() { Enterz: pc.printf("Checking Whether there is a variable stored in Noun or Verb 35\n"); if (Noun_Number1 == 0 && Noun_Number2 == 0 && Verb_Number1 != 2 && Verb_Number2 != 5){ // N00V35 // Test Lights pc.printf("Please enter a Enter Number"); __wfi(); Enter_Number1 = Index; if (Enter_Number1 == 11) { // This section is used on atleast one of the two Enter_Number variable to prevent a nestled if within if within if. goto Enterz; } else{ Button_Sort(Enter_Number1); } __wfi(); Enter_Number2 = Index; Button_Sort(Enter_Number2); } // This is for P00 else if(Noun_Number1 == 0 && Noun_Number2 == 0 && Verb_Number1 == 2 && Verb_Number2 == 8){ //N00V37 pc.printf("This is the P00 program \n"); pc.printf("Please enter a Enter Number\n"); //Noun_Number1 = 0x0f; //Noun_Number2 = 0x0f; NO_Light(5); Index = -1; do { N_GET(); V_A = 0x03; V_B = 0x07; N_GET(); Shift(); wait(.5); N_GET(); NO_Light(4); // No Light Verb NO_Light(5); N_GET(); NO_Light(5); Shift(); wait(.5); } while (N_Position != 3); V_A = 3; V_B = 7; N_A = Enter_Number1; N_B = Enter_Number2; Shift(); compare(); pc.printf("Out of P01, Waiting for Orders\n"); // pc.printf("V1 %d \n", Verb_Number1); // pc.printf("V2 %d \n", Verb_Number2); // pc.printf("N1 %d \n", Noun_Number1); // pc.printf("N2 %d \n", Noun_Number2); // pc.printf("E1 %d \n", Enter_Number1); // pc.printf("E2 %d \n", Enter_Number2); N_Position = 1; __wfi(); if (Index == 11) { // 11 = Enter Button pc.printf("Compare\n"); compare(); } else if (Index == 14) { Noun_Button(); } else if (Index == 12) { Verb_Button(); } Index = -1; } else {// (Noun_Number1 != 0 && Noun_Number2 != 0){ pc.printf("Check completed, Executing"); Index = -1; compare(); } } // This function is used to sort the button press for Verb and Noun. int Button_Sort(int Sort) { if (Sort == 0){ // Index 0 - Char 1 return 0x01; } else if (Sort == 1) { // Index 1 - Char 2 return 0x02; } else if (Sort == 2) { // Index 2 - Char 3 return 0x03; } else if (Sort == 3) { // Index 3 - Char + comparing the array number NOT what value in the array it is. Actual Array value is + pc.printf("+"); return 0x10; } else if (Sort == 4) { // Index 4 - Char 4 return 0x04; } else if (Sort == 5) { // Index 5 - Char 5 return 0x05; } else if (Sort == 6) { // Index 6 - Char 6 return 0x06; } else if (Sort == 7) { // Index 7 - Char - comparing the array number NOT what value in the array it is. Actual Array value is - pc.printf("-"); return 0x11; } else if (Sort == 8) { // Index 8 - Char 7 return 0x07; } else if (Sort == 9) { // Index 9 - Char 8 return 0x08; } else if (Sort == 10) { // Index 10 - Char 9 return 0x09; } else if (Sort == 12){ // Index 12 - Char V comparing the array number NOT what value in the array it is. Actual Array value is V Verb_Button(); } else if (Sort == 13) { // Index 13 - Char 0 return 0x00; } else if (Sort == 14) { // Index 14 - Char N comparing the array number NOT what value in the array it is. Actual Array value is N Noun_Button(); } else if (Sort == 15) { //comparing the array number NOT what value in the array it is. Actual Array value is R pc.printf("R"); } return 0; } // Compares the button to what program the DSKY should be running. This section will be inefficent until I can improve on my programming skills :] void compare() { if (Verb_Number1 == 0 && Verb_Number2 == 6 && Noun_Number1 == 2 && Noun_Number2 == 6 && Enter_Number1 == 0 && Enter_Number2 == 0) {// Verb 16, Noun 36, Enter 00 // Configure GET pc.printf("Display GET\n"); Ground_Elapse_Time(); } else if (Verb_Number1 == 2 && Verb_Number2 == 5 && Noun_Number1 == 0 && Noun_Number2 == 0 && Enter_Number1 == 0 && Enter_Number2 == 0) { // Verb 35 Noun 00 Enter 00 // Test Lights pc.printf("Testing Lights\n"); Test_Lights(); } else if (Verb_Number1 == 1 && Verb_Number2 == 5 && Noun_Number1 == 2 && Noun_Number2 == 6 && Enter_Number1 == 0 && Enter_Number2 == 0) { // Verb 25, Noun 36, Enter 00 // GET COnfiguration pc.printf("GET configuration\n"); GET_Config(); } else if (Verb_Number1 == 2 && Verb_Number2 == 8 && Noun_Number1 == 0 && Noun_Number2 == 0 && Enter_Number1 == 0 && Enter_Number2 == 0) { // Verb 37, Noun 00, Enter 00 // CMC Idling Program pc.printf("CMC Idling Program\n"); CMC_Idle(); } else if (Verb_Number1 == 2 && Verb_Number2 == 8 && Noun_Number1 == 0 && Noun_Number2 == 0 && Enter_Number1 == 0 && Enter_Number2 == 1) { // Verb 37, Noun 00, Enter 01 pc.printf("Prelaunch or Service - Initialization Program\n"); PreLaunch_Initialization(); } else if (Verb_Number1 == 2 && Verb_Number2 == 8 && Noun_Number1 == 0 && Noun_Number2 == 0 && Enter_Number1 == 0 && Enter_Number2 == 6) { pc.printf("CMC Power Down Program\n"); CMC_Powerdown(); } //else if (Verb_Number1 == 1 && Verb_Number2 == 0 && Noun_Number1 == 0 && Noun_Number2 == 0 && Enter_Number1 == 0 && Enter_Number2 == 0) { // Verb 21, Noun 00, Enter 00 // R1_Component(); //} else { pc.printf("Failed"); } } void ShiftingOut(int myDataOut) { // This shifts 8 bits out to the MSB first, The the rising edge of the clock, while clock idles low. // Internal Fucntions DataPin = 0; ClockPin = 0; int i= 0; int pinState; // Clears Everything within shift registers DataPin = 0; ClockPin = 0; for (i=3; i>= 0; i--) { ClockPin = 0; // Value passed to my data out if ( myDataOut & (1<<i)) { pinState = 1; myled = 1; //pc.printf("1"); } else { pinState = 0; myled = 0; //pc.printf("0"); } DataPin = pinState; ClockPin = 1; DataPin = 0; } //pc.printf("\n"); ClockPin = 0; DataPin = 1; } // This function is used for shifting all Shift_X variables into the 7 segment display. void Shift() { LatchPin = 0; ShiftingOut(P_B); ShiftingOut(P_A); ShiftingOut(V_B); ShiftingOut(V_A); ShiftingOut(N_B); ShiftingOut(N_A); ShiftingOut(R3_E); ShiftingOut(R3_D); ShiftingOut(R3_C); ShiftingOut(R3_B); ShiftingOut(R3_A); ShiftingOut(R2_E); ShiftingOut(R2_D); ShiftingOut(R2_C); ShiftingOut(R2_B); ShiftingOut(R2_A); ShiftingOut(R1_E); ShiftingOut(R1_D); ShiftingOut(R1_C); ShiftingOut(R1_B); ShiftingOut(R1_A); LatchPin = 1; } //blinks the whole registered based on the number of times you want to blink with a certain delay void blinkAll(int amount, int delay) { LatchPin = 0; // Before shift //ShiftingOut(0); //ShiftingOut(0); LatchPin = 1; // Done shift wait(0.2); for (int x = 0; x < amount; x++) { LatchPin = 0; pc.printf("sending\n"); for (int s = 0; s < 22; s++) { ShiftingOut(0x08); UPLINK_ACTY = 1; NO_ATT = 1; STBY = 1; KEY_REL = 1; OPP_ERR = 1; TEMP = 1; GIMBAL_LOCK = 1; PROG = 1; RESTART = 1; TRACKER = 1; R1_POS = 1; R2_POS = 1; R3_POS = 1; R1_NEG = 1; R2_NEG = 1; R3_NEG = 1; COMP_ACTY = 1; } LatchPin = 1; wait(delay); LatchPin = 0; for (int s = 0; s < 22; s++) { ShiftingOut(0x0f); UPLINK_ACTY = 0; NO_ATT = 0; STBY = 0; KEY_REL = 0; OPP_ERR = 0; TEMP = 0; GIMBAL_LOCK = 0; PROG = 0; RESTART = 0; TRACKER = 0; R1_POS = 0; R2_POS = 0; R3_POS = 0; R1_NEG = 0; R2_NEG = 0; R3_NEG = 0; COMP_ACTY = 0; } LatchPin = 1; wait(delay); } } // The Ground Elapse Time is refrence to range zero or the last integeral before liftoff. // Page CM-9 // 00XXX h // 000XX min // 0XX.XX s (Code current does not follow this format) void Ground_Elapse_Time() { NO_Light(7); // Clears all the 7 Segment first. // Displays V16N36 on the 7 segments V_A = 0x01; V_B = 0x06; N_A = 0x03; N_B = 0x06; Shift(); int GET_FLAG = 1; while(GET_FLAG == 1) { int minute = 0; int Seconds = 0; int Hours = 0; int minutemod = 0; // Minute Modulo int R1D = 0x00; int R1E = 0x00; int R2D = 0x00; int R2E = 0x00; int R3D = 0x00; int R3E = 0x00; time_t seconds = clk.time(NULL); pc.printf ("S = %d\n", seconds); Time_Difference = (seconds + GET_Config_Time) - TIME_VALUE; printf("TIME=%d \n", Time_Difference); // Displays time elapsed based on seconds elapsed. Hours = Time_Difference/3600; // Divide seconds by 3600 seconds Seconds = Time_Difference%60; // Get the remainder of time difference after 60 seconds minute = Time_Difference/60; // Divide the seconds by 3600 // Comments: 7 Segments Location minutemod = minute%60; // Get the remainder of the minutemod after 60 seconds R3D = (Hours%60)/10; // Get the modulo of the hour variable then divde by 10 to get single digit [][][][x][] R3E = Hours%10; // Get the modulo of the Hours variable by 10 to get single digit [][][][][x] R2D = minutemod/10; // Divide the minute variable by 10 to get single digit [][][][x][] R2E = minute%10; // Get the remainder of the minute variable to get single digit [][][][][x] R1D = Seconds/10; // Divide the seconds variable by 10 to get single digit [][][][x][] R1E = Time_Difference%10; // Get the remainder of the Time_Difference to get single digit [][][][][x] // Debug Use: // pc.printf("%d \n", minute); // pc.printf("%o \n", R2E); // pc.printf("%o \n", R2D); R3_E = R3E; R3_D = R3D; R1_E = R1E; R1_D = R1D; R2_E = R2E; R2_D = R2D; Shift(); //pc.printf("%i \n",(Time_Difference%10) + ((Time_Difference/10)<<4)); // Decimal to BCD //printf("Time as a basic string = %s\r", ctime(&seconds)); if (Index >-1) { GET_FLAG = 0; pc.printf("Interrupted"); pc.printf("Index:%d => Key:%c\r\n", Index, Keytable[Index]); if (Index == 12) { // Index 12 = Verb Button Verb_Button(); // Goes to Verb_Button GET_FLAG = 0; break; } else if (Index == 14) { // Index 14 = Noun Button Noun_Button(); // Goes to Noun_Button GET_FLAG = 0; break; } else if (Index == 11) { // Index 11 = Enter Button Enter_Button(); // Goes to Enter_Button GET_FLAG = 0; break; } Index = -1; GET_FLAG = 0; break; } wait(1); } } // This function tells the shift registers to not display anything on the 7 segments. The integer L is used to specificy which area to zero. // 1 = Row 1 // 2 = Row 2 // 3 = Row 3 // 4 = Verb // 5 = Nouns // 6 = Program Number // 7 = All lights off void NO_Light(int L) { switch(L) { case 1: R1_A = 0x0f; R1_B = 0x0f; R1_C = 0x0f; R1_D = 0x0f; R1_E = 0x0f; Shift(); case 2: R2_A = 0x0f; R2_B = 0x0f; R2_C = 0x0f; R2_D = 0x0f; R2_E = 0x0f; Shift(); case 3: R3_A = 0x0f; R3_B = 0x0f; R3_C = 0x0f; R3_D = 0x0f; R3_E = 0x0f; Shift(); case 4: V_A = 0x0f; V_B = 0x0f; Shift(); case 5: N_A = 0x0f; N_B = 0x0f; Shift(); case 6: P_A = 0x0f; P_B = 0x0f; Shift(); case 7: R1_A = 0x0f; R1_B = 0x0f; R1_C = 0x0f; R1_D = 0x0f; R1_E = 0x0f; R2_A = 0x0f; R2_B = 0x0f; R2_C = 0x0f; R2_D = 0x0f; R2_E = 0x0f; R3_A = 0x0f; R3_B = 0x0f; R3_C = 0x0f; R3_D = 0x0f; R3_E = 0x0f; V_A = 0x0f; V_B = 0x0f; N_A = 0x0f; N_B = 0x0f; P_A = 0x0f; P_B = 0x0f; Shift(); case 8: UPLINK_ACTY = 0; NO_ATT = 0; STBY = 0; KEY_REL = 0; OPP_ERR = 0; TEMP = 0; GIMBAL_LOCK = 0; PROG = 0; RESTART = 0; TRACKER = 0; R1_POS = 0; R2_POS = 0; R3_POS = 0; R1_NEG = 0; R2_NEG = 0; R3_NEG = 0; COMP_ACTY = 0; } } // Test lights is to make sure all the 7 segments and indicator lights worked prior to lift-off. void Test_Lights() { for(int x = 0; x < 7; x++) { R1_A = 0x08; R1_B = 0x08; R1_C = 0x08; R1_D = 0x08; R1_E = 0x08; R2_A = 0x08; R2_B = 0x08; R2_C = 0x08; R2_D = 0x08; R2_E = 0x08; R3_A = 0x08; R3_B = 0x08; R3_C = 0x08; R3_D = 0x08; R3_E = 0x08; V_A = 0x08; V_B = 0x08; N_A = 0x08; N_B = 0x08; P_A = 0x08; P_B = 0x08; Shift(); wait(1); V_A = 0x0f; V_B = 0x0f; N_A = 0x0f; N_B = 0x0f; Shift(); wait(1); } } // This configs the Ground Elapse Time // This portion of code converts the value retrived into seconds and replaces the value in the RTC module. // Process: // V25N36 // Displays V21N36 // +-00XXX 750 hours max (equates to 31.25 days) Longest Apollo mission was only 12 hours, 13 hours. So 750 Hours is more than enough. // Displays V22N36 // +-000XX 60 Minutes Max // Displays V23N36 // +-0XXXX 60 Seconds Max, Currently follows 000XX will change in future revisions void GET_Config() { int GET_Hours = 0; int GET_Minute = 0; int GET_Seconds = 0; // Configures Hours, Minutes, and Seconds for RTC NO_Light(3); do { NO_Light(3); pc.printf("Debug"); R_GET(3); V_A = 0x02; V_B = 0x01; N_A = 0x03; N_B = 0x06; R_GET(3); Shift(); wait(.5); R_GET(3); V_A = 0x0f; V_B = 0x0f; N_A = 0x0f; N_B = 0x0f; R_GET(3); Shift(); wait(.5); } while (R3_Position != 7); R_Position = 1; RVA = 0x0f; RVB = 0x0f; RVC = 0x0f; RVD = 0x0f; RVE = 0x0f; do { pc.printf("Debug R2"); R_GET(2); V_A = 0x02; V_B = 0x02; N_A = 0x03; N_B = 0x06; R_GET(2); Shift(); wait(.5); R_GET(2); V_A = 0x0f; V_B = 0x0f; N_A = 0x0f; N_B = 0x0f; R_GET(2); Shift(); wait(.5); } while(R2_Position != 7); R_Position = 1; RVA = 0x0f; RVB = 0x0f; RVC = 0x0f; RVD = 0x0f; RVE = 0x0f; do { pc.printf("Debug R1"); R_GET(1); V_A = 0x02; V_B = 0x03; N_A = 0x03; N_B = 0x06; R_GET(1); Shift(); wait(.5); R_GET(1); V_A = 0x0f; V_B = 0x0f; N_A = 0x0f; N_B = 0x0f; R_GET(1); Shift(); wait(.5); } while(R1_Position != 7); R_Position = 1; RVA = 0x0f; RVB = 0x0f; RVC = 0x0f; RVD = 0x0f; RVE = 0x0f; // The Actual Configuration of GET // Concatenate the values from each row based on it's value GET_Hours = R_Concatenate(3); GET_Minute = R_Concatenate(2); GET_Seconds = R_Concatenate(1); // Checks if value exceeds the Hours, Minute, and Seconds and verifies if Rows are in Positive if (GET_Hours > 750 or GET_Minute > 60 or GET_Seconds > 60 or R1_POS != 1 or R2_POS != 1 or R3_POS != 1) { pc.printf("Error! Check your Hours, Minute, and Seconds Value"); R3_Position = 1; GET_Config(); } else { pc.printf("Pass!, Going to configure RTC Now"); GET_Config_Time = GET_Hours * 3600; GET_Config_Time += GET_Minute * 60; GET_Config_Time += GET_Seconds; pc.printf("Time Conversion is %d", GET_Config_Time); } // Reconfigures the timee so the values can be resetted. #ifdef INITIAL_RUN clk.set_time(TIME_VALUE); #endif // Debug Use Only //pc.printf("%d\n", GET_Hours); //pc.printf("%d\n", GET_Minute); //pc.printf("%d\n", GET_Seconds); Ground_Elapse_Time(); } /* This is the CMC Idling Program Page CM-39 P00 - CMC IDLING PROGRAM Purpose: 1. To maintain the CMC in a condition of readiness for entry into other programs 2. To update the CSM and LM state vectors every four time steps. Assumptions: 1. This program is automatially selected by V96E, which may be done during any program. State vector integration is permanently inhibited following V96E. Normal integration functions will resume after selection of any program or extented verb. P00 Integration will resume when P00 is reselected. Usage of V96 can cause incorrect W-matrix and state vector synchronication. 2. Program changes are inhibited during integration periods and program alarm 1520sub(8) will occur if a chance is attempted when inhibited. Process: 1. User Input Verb 37 Enter 00 2. Display P00 3. Verb 06 Noun 38 4. Optional Display: 5. Verb 06 Noun 38 - 6. Time of State Vector being Integrated 00xxx hours 000xx minutes 0xx.xx seconds */ void CMC_Idle() { int CMC_Idle = 0; NO_Light(7); P_A = 0x00; P_B = 0x00; Shift(); do { __wfi(); if (Index == 12) { // Index 12 = Verb Button Verb_Button(); // Goes to Verb_Button }// Index == 12 if (Index == 14) { // Index 14 = Noun Button Noun_Button(); // Goes to Noun_Button }// Index == 14 if (Index == 11) { // Index 11 = Enter Button if (Verb_Number1 == 13 && Verb_Number2 == 6 && Noun_Number1 == 2 && Noun_Number2 == 9 && Enter_Number1 == 0 && Enter_Number2 == 0) { //V06N38E00 while(1) { // Time of State Vector Data. // Time of State Hours R3_E = ToSHours%10; R3_D = (ToSHours/10)%10; R3_C = (ToSHours/100)%10; R3_B = (ToSHours/1000)%10; R3_A = (ToSHours/10000)%10; // Time of State Minutes R2_E = ToSMinutes%10; R2_D = (ToSMinutes/10)%10; R2_C = (ToSMinutes/100)%10; R2_B = (ToSMinutes/1000)%10; R2_A = (ToSMinutes/10000)%10; // Time of State Seconds R3_E = ToSSeconds%10; R3_D = (ToSSeconds/10)%10; R3_C = (ToSSeconds/100)%10; R3_B = (ToSSeconds/1000)%10; R3_A = (ToSSeconds/10000)%10; wait(1); } } else { Enter_Button(); // Goes to Enter_Button }// Else statement }// Index == 11 Index = -1; } while(CMC_Idle == 0); }// void CMC_Idle() /* P01 - Prelaunch or Service - Initialization Program CM-39 Purpose: 1. To intialize the platform for the prelaunch programs. 2. To provide an initial stable member orientation for Gyrocompassing (P02) Assumptions: Erasble location has been Properly initialized. Azimuth, +1 Latitude, +1 LaunchAZ +1 IMU compenstaion parameters */ void PreLaunch_Initialization() { P_A = 0x00; P_B = 0x01; Shift(); if (IMUPWR == 1) { NO_ATT = 0; wait(9); pc.printf("Course Align IMU\n"); NO_ATT = 1; wait(10); pc.printf("Course Align IMU complete\n"); NO_ATT = 0; wait(2); PreLaunch_Gyrocompassing(); } else { // NO_ATT is off for 8 seconds, with one COMP_ACTY light. PROG = 1; wait(6); COMP_ACTY = 1; wait(0.5); COMP_ACTY = 0; wait(1.5); // NO_ATT is on for 6 seconds, No COMP_ACTY light. NO_ATT = 1; wait(6); NO_ATT = 0; P_A = 0x0f; P_B = 0x0f; Shift(); } } /* P02 - Prelaunch or Service - Gyrocompassing Program CM-39 Purpose: 1. Provide proper stable member orientation for launch Assumptions: 1. Program may be interuppted to perform the prelaunch or service - optical verification of gyrocompassing program (P03) 2. V75 will be keyed in and displaed during this program to permit crew backup of the liftoff discrete. 3. Program is automatically selected by the Initialization Program (P01). 4. This program has capability (Via V78E) to change the luanch azimuth of the stable memeber while gyrocompassing. Process: 1. After P01 is completed 2. Display P02 3. Flashing V06 N29 / Display LAUNCHAZ in R3 4. User input V21E 5. Flash V21N29 This is R1_Component May be for future use. 6. User inputs values for LAUNCHAZ 7. Flash V06 N29 / Display LAUNCHAZ in R3 8. Input Pro 9. Pulses Gyros Programming Notes: Void PreLaunch_Gyrocomapssing() and PreLaunch_Gyrocompassing_Configure() are tied together */ void PreLaunch_Gyrocompassing () { // Process 1 // Process 2 NO_Light(7); P_A = 0x00; P_B = 0x02; Shift(); Index = -1; R3_E = LAUNCHAZ%10; R3_D = (LAUNCHAZ/10)%10; R3_C = (LAUNCHAZ/100)%10; R3_B = (LAUNCHAZ/1000)%10; R3_A = (LAUNCHAZ/10000)%10; Shift(); while(1) { // Process 3; PreLaunch_Gyrocompassing_Configure(); COMP_ACTY = 1; PreLaunch_Gyrocompassing_Configure(); wait(0.5); PreLaunch_Gyrocompassing_Configure(); COMP_ACTY = 0; PreLaunch_Gyrocompassing_Configure(); wait(0.5); pc.printf("spam\n"); pc.printf("Index %d\n", Index); } // While 1 } // prelaunch configuration // This is used for the configuration of PreLaunch_Gyrocompassing(); // This has to be used since it awaits for the input of the astronauts. void PreLaunch_Gyrocompassing_Configure() { int Azimuth; while(1){ if (Index >-1) { if (Index == 12) { Verb_Button(); //For V21 use } if (Index == 11) { if (Verb_Number1 == 1 && Verb_Number2 == 0 && Noun_Number1 == 0 && Noun_Number2 == 0 && Enter_Number1 == 0 && Enter_Number2 == 0) { // Verb 21, Noun 00, Enter 00 //Flash V21N29 and Get user inputs under R3 // Process 5 and 6 Azimuth = R1_Component(); // Goes to R1 Component if(Azimuth < 90000 && R3_POS == 1 && R1_NEG == 0) { // Error Checking Checks if it's over 90000 or 90 degrees and that R3_POS is lit and not R3_NEG // If it passes LAUNCHAZ = Azimuth; PreLaunch_Gyrocompassing();// This is suppose to go to PreLaunch_Gyrocompassing }// if Azimuth = R1 else{ pc.printf("Failed"); } // Error checking } // V21 N00 E00 } // Enter BUtton if (Index == 99){ // This is Prog Button // Error checks just in case if (LAUNCHAZ > 0 && R3_POS == 1){ // Because there are no Phsyical Gyro's present, This section of code is just going to simulate gyros pulsing for (int x = 0; x > 21; x++){ pc.printf("Pulsing Gyros...\n"); COMP_ACTY = 1; wait(.5); COMP_ACTY = 0; wait(.5); }// Pulsing Gyro simulation pc.printf("Done!"); }// Prog Error checking }// Prog Button } // Index > -1 } // While(1) } // PreLaunh_Gyrocompassing_Configure(); /* P06 - CMC Power Down Program Purpose: 1. To transfer the CMC from the operate to the standby position Assumptions: 1. If the computer power is switched off, the AGC Update program (P27) would have to be done to update the state vector and computer clock time. 2. The AGC is capable of maintaining an accurate value of ground elapsed time (GET) for only 23 hours when in the standby mode. If the AGC is not brought out of the standby position to the running condition atleast once within 23 hours, the AGC value of get must be updated. 3. Once the program has been selected, the AGC must be put in standby. When P06 appears, the AGC will not honor a new program request (V37EXXE), a terminate (V34E), or an ENTER in response to the request for standby. Sequence of Events: 1. User Input V37E06 2. Flashing V50N25 R3 = 00062 3. PRO until standby light on 4. PRO until standby light off 5. Flashing V37 6. User input 00E (Select P00) 6.A No ATT Light of 90 Seconds 7. Go to P00 */ void CMC_Powerdown() { // Process 2 P_A = 0x00; P_B = 0x06; R3_E = 0x00; R3_D = 0x00; R3_C = 0x00; R3_B = 0x06; R3_A = 0x02; Shift(); while(1) { // Process 2 CMC_PowerInput(); V_A = 0x05; V_B = 0x00; N_A = 0x02; N_B = 0x05; Shift(); CMC_PowerInput(); wait(.5); CMC_PowerInput(); NO_Light(4); NO_Light(5); CMC_PowerInput(); wait(.5); }// While 1 }// CMC_Powerdown() void CMC_PowerInput() { int PowerInput = 0; if(PRO == 1) { NO_Light(7); NO_Light(8); // Process 3 STBY = 1; PRO = 0; do { if(PRO == 1) { // Process 4 STBY = 0; //N00V37 Noun_Number1 = 0; Noun_Number2 = 0; Verb_Number1 = 2; Verb_Number2 = 8; // Process 5-7 Enter_Button(); PowerInput = 1; }// 2nd PRO For turning on. }while (PowerInput == 0);// While 1 }//PRO == 1 } // Load Component 1 into R1 int R1_Component() { R1_POS = 0; R1_NEG = 0; Index = -1; do { R_GET(3); V_A = 0x02; V_B = 0x01; N_A = 0x02; N_B = 0x09; R_GET(3); Shift(); wait(.5); R_GET(3); NO_Light(4); NO_Light(5); R_GET(3); wait(.5); } while (R3_Position != 7); R_Position = 1; return R_Concatenate(3); } // This is used to concatenate Row 3, Useful for when verifying inputs. int R_Concatenate(int C) { // Used for concatenation only int RAB = 0; int RCD = 0; int RABCD = 0; int RABCDE = 0; // Actual Physical Interaces, Row Physical int RPA = 0; int RPB = 0; int RPC = 0; int RPD = 0; int RPE = 0; // This if Statement compares which rows to concatenate then replaces the variables with the correct one. if (C == 3) { RPA = R3_A; RPB = R3_B; RPC = R3_C; RPD = R3_D; RPE = R3_E; } if (C == 2) { RPA = R2_A; RPB = R3_B; RPC = R2_C; RPD = R2_D; RPE = R2_E; } if (C == 1) { RPA = R1_A; RPB = R1_B; RPC = R1_C; RPD = R1_D; RPE = R1_E; } RAB = concatenate(RPA, RPB); // R3A + R3B RCD = concatenate(RPC, RPD); // R3C + R3D RABCD = concatenate(RAB, RCD); // R3AB + R3CD RABCDE = concatenate(RABCD, RPE); // R3ABCD = R3E //Debug Use: //pc.printf("%d\n", RAB); //pc.printf("%d\n", RCD); //pc.printf("%d\n", RABCD); //pc.printf("%d\n", RABCDE); return RABCDE; } // Concatenate two Integers. Credits to Mooing Duck. http://stackoverflow.com/questions/12700497/how-to-concatenate-two-integers-in-c // Decided not modify the code to do 5 at a time since I can use it to concatenate the Verb, Noun, and Program Number. unsigned concatenate(unsigned x, unsigned y) { unsigned pow = 10; while(y >= pow) pow *= 10; return x * pow + y; } void R_GET(int R) { if (R == 3) { R3_POS = R_Pos; R3_NEG = R_Neg; R3_A = RVA; R3_B = RVB; R3_C = RVC; R3_D = RVD; R3_E = RVE; R3_Position = R_Position; } if (R == 2) { R2_POS = R_Pos; R2_NEG = R_Neg; R2_A = RVA; R2_B = RVB; R2_C = RVC; R2_D = RVD; R2_E = RVE; R2_Position = R_Position; } if (R == 1) { R1_POS = R_Pos; R1_NEG = R_Neg; R1_A = RVA; R1_B = RVB; R1_C = RVC; R1_D = RVD; R1_E = RVE; R1_Position = R_Position; } switch (R_Position) { case 1: if (Index >-1) { pc.printf("Plus-Minus\n"); RP = Button_Sort(Index); if (RP == 0x10) { R_Pos = 1; pc.printf("+"); } else if (RP == 0x11) { R_Neg = 1; } Index = -1; R_Position = 2; } case 2: if (Index >-1) { pc.printf("RA\n"); RA = Button_Sort(Index); RVA = RA; Shift(); Index = -1; R_Position = 3; } case 3: if (Index >-1) { pc.printf("RB\n"); RB = Button_Sort(Index); RVB = RB; Shift(); Index = -1; R_Position = 4; } case 4: if (Index >-1) { pc.printf("RC\n"); RC = Button_Sort(Index); RVC = RC; Shift(); Index = -1; R_Position = 5; } case 5: if (Index >-1) { pc.printf("RD\n"); RD = Button_Sort(Index); RVD = RD; Shift(); Index = -1; R_Position = 6; } case 6: if (Index >-1) { pc.printf("RE\n"); RE = Button_Sort(Index); RVE = RE; Shift(); Index = -1; R_Position = 7; } } } // When a value is required for Enter, The output is displayed via the Noun display Hence the Name N_GET not E_GET void N_GET() { N_A = NA; N_B = NB; switch (N_Position) { case 1: if (Index > -1) { pc.printf("NA\n"); NA = Button_Sort(Index); Enter_Number1 = NA; Shift(); Index = -1; N_Position = 2; } case 2: if (Index > -1) { pc.printf("NB\n"); NB = Button_Sort(Index); Enter_Number2 = NB; Shift(); Index = -1; N_Position = 3; } } }