int main(void){ TExaS_Init(SSI0_Real_Nokia5110_Scope); // set system clock to 80 MHz DisableInterrupts(); Random_Init(1); Nokia5110_Init(); Nokia5110_ClearBuffer(); Nokia5110_DisplayBuffer(); SysTick_Init(); // initialize Timer2 after Nokia5110_Init because of // error-prone registers operations (old and new registers // are not working good together) // 80MHz/11,025 cycles, which is about 7256 Timer2_Init(7256); Ports_Init(); InitSprites(NumberOfEnemies); RestartGame(); // Countdown, after which all interrupts are enabled! // print 3 Nokia5110_ClearBuffer(); Nokia5110_PrintBMP(28, 41, _my_Countdown_03, 0); Nokia5110_DisplayBuffer(); Delay100ms(3); // print 2 Nokia5110_ClearBuffer(); Nokia5110_PrintBMP(28, 41, _my_Countdown_02, 0); Nokia5110_DisplayBuffer(); Delay100ms(3); // print 1 Nokia5110_ClearBuffer(); Nokia5110_PrintBMP(28, 41, _my_Countdown_01, 0); Nokia5110_DisplayBuffer(); Delay100ms(3); // print GO Nokia5110_ClearBuffer(); Nokia5110_PrintBMP(28, 41, _my_Countdown_GO, 0); Nokia5110_DisplayBuffer(); Delay100ms(3); EnableInterrupts(); while(1){ if (Flag == 1) { Nokia5110_DisplayBuffer(); Flag = 0; } } }
int SIMMElectricalTest_Run(void (*errorHandler)(uint8_t, uint8_t)) { // Returns number of errors found int numErrors = 0; // Pins we have determined are shorted to ground // (We have to ignore them during the second phase of the test) SIMMElectricalTest_ResetGroundShorts(); Ports_Init(); // Give everything a bit of time to settle down DelayMS(DELAY_SETTLE_TIME_MS); // First check for anything shorted to ground. Set all lines as inputs with a weak pull-up resistor. // Then read the values back and check for any zeros. This would indicate a short to ground. Ports_SetAddressDDR(0); Ports_SetDataDDR(0); Ports_SetCSDDR(false); Ports_SetOEDDR(false); Ports_SetWEDDR(false); Ports_AddressPullups_RMW(SIMM_ADDRESS_PINS_MASK, SIMM_ADDRESS_PINS_MASK); Ports_DataPullups_RMW(SIMM_DATA_PINS_MASK, SIMM_DATA_PINS_MASK); Ports_SetCSPullup(true); Ports_SetOEPullup(true); Ports_SetWEPullup(true); DelayMS(DELAY_SETTLE_TIME_MS); uint8_t curPin = 0; uint8_t i; // Read the address pins back first of all uint32_t readback = Ports_ReadAddress(); if (readback != SIMM_ADDRESS_PINS_MASK) { // Check each bit for a LOW which would indicate a short to ground for (i = 0; i <= SIMM_HIGHEST_ADDRESS_LINE; i++) { // Did we find a low bit? if (!(readback & 1)) { // That means this pin is shorted to ground. // So notify the caller that we have a ground short on this pin errorHandler(curPin, GROUND_FAIL_INDEX); // Add it to our internal list of ground shorts also. SIMMElectricalTest_AddGroundShort(curPin); // And of course increment the error counter. numErrors++; } // No matter what, though, move on to the next bit and pin. readback >>= 1; curPin++; } } // Repeat the exact same process for the data pins readback = Ports_ReadData(); if (readback != SIMM_DATA_PINS_MASK) { for (i = 0; i <= SIMM_HIGHEST_DATA_LINE; i++) { if (!(readback & 1)) // failure here? { errorHandler(curPin, GROUND_FAIL_INDEX); SIMMElectricalTest_AddGroundShort(curPin); numErrors++; } readback >>= 1; curPin++; } } // Check chip select in the same way... if (!Ports_ReadCS()) { errorHandler(curPin, GROUND_FAIL_INDEX); SIMMElectricalTest_AddGroundShort(curPin); numErrors++; } curPin++; // Output enable... if (!Ports_ReadOE()) { errorHandler(curPin, GROUND_FAIL_INDEX); SIMMElectricalTest_AddGroundShort(curPin); numErrors++; } curPin++; // Write enable... if (!Ports_ReadWE()) { errorHandler(curPin, GROUND_FAIL_INDEX); SIMMElectricalTest_AddGroundShort(curPin); numErrors++; } curPin++; // Doesn't need to be here, but for consistency I'm leaving it. // OK, now we know which lines are shorted to ground. // We need to keep that in mind, because those lines will now show as shorted // to ALL other lines...ignore them during tests to find other independent shorts // Now, check each individual line vs. all other lines on the SIMM for any shorts between them ElectricalTestStage curStage = TestingAddressLines; int x = 0; // Counter of what address or data pin we're on. Not used for control lines. uint8_t testPin = 0; // What pin we are currently testing all other pins against. // x is only a counter inside the address or data pins. // testPin is a total counter of ALL pins. while (curStage != DoneTesting) { // Set one pin to output a 0. // Set all other pins as inputs with pull-ups. // Then read back all the other pins. If any of them read back as 0, // it means they are shorted to the pin we set as an output. // If we're testing address lines right now, set the current address line // as an output (and make it output a LOW). // Set all other address lines as inputs with pullups. if (curStage == TestingAddressLines) { uint32_t addressLineMask = (1UL << x); // mask of the address pin we're testing Ports_SetAddressDDR(addressLineMask); // set it as an output and all other address pins as inputs Ports_AddressOut_RMW(0, addressLineMask); // set the output pin to output "0" without affecting the input pins Ports_AddressPullups_RMW(SIMM_ADDRESS_PINS_MASK, ~addressLineMask); // turn on the pullups on all input pins } else { // If not testing an address line, set all address pins as inputs with pullups. // All the other stages follow the same pattern so I won't bother commenting them. Ports_SetAddressDDR(0); Ports_AddressPullups_RMW(SIMM_ADDRESS_PINS_MASK, SIMM_ADDRESS_PINS_MASK); } // Do the same thing for data lines... if (curStage == TestingDataLines) { uint32_t dataLineMask = (1UL << x); Ports_SetDataDDR(dataLineMask); Ports_DataOut_RMW(0, dataLineMask); Ports_DataPullups_RMW(SIMM_DATA_PINS_MASK, ~dataLineMask); } else { Ports_SetDataDDR(0); Ports_DataPullups_RMW(SIMM_DATA_PINS_MASK, SIMM_DATA_PINS_MASK); } // Chip select... if (curStage == TestingCS) { Ports_SetCSDDR(true); Ports_SetCSOut(false); } else { Ports_SetCSDDR(false); Ports_SetCSPullup(true); } // Output enable... if (curStage == TestingOE) { Ports_SetOEDDR(true); Ports_SetOEOut(false); } else { Ports_SetOEDDR(false); Ports_SetOEPullup(true); } // And write enable. if (curStage == TestingWE) { Ports_SetWEDDR(true); Ports_SetWEOut(false); } else { Ports_SetWEDDR(false); Ports_SetWEPullup(true); } // OK, so now we have set up all lines as needed. Exactly one pin is outputting a 0, and all other pins // are inputs with pull-ups enabled. Read back all the lines, and if any pin reads back as 0, // it means that pin is shorted to the pin we are testing (overpowering its pullup) // However, because we test each pin against every other pin, any short would appear twice. // Once as "pin 1 is shorted to pin 2" and once as "pin 2 is shorted to pin 1". To avoid // that annoyance, I only check each combination of two pins once. You'll see below // how I do this by testing to ensure curPin > testPin. DelayMS(DELAY_SETTLE_TIME_MS); // Now keep a count of how many pins we have actually checked during THIS test. curPin = 0; // Read back the address data to see if any shorts were found readback = Ports_ReadAddress(); // Count any shorted pins for (i = 0; i <= SIMM_HIGHEST_ADDRESS_LINE; i++) { // failure here? if ((curPin > testPin) && // We haven't already checked this combination of pins (don't test pin against itself either) !(readback & 1) && // It's showing as low (which indicates a short) !SIMMElectricalTest_IsGroundShort(curPin)) // And it's not recorded as a short to ground { // Send it out as an error notification and increase error counter errorHandler(testPin, curPin); numErrors++; } // No matter what, move on to the next bit and pin readback >>= 1; curPin++; } // Same thing for data pins readback = Ports_ReadData(); // Count any shorted pins for (i = 0; i <= SIMM_HIGHEST_DATA_LINE; i++) { // failure here? if ((curPin > testPin) && // We haven't already checked this combination of pins (don't test pin against itself either) !(readback & 1) && // It's showing as low (which indicates a short) !SIMMElectricalTest_IsGroundShort(curPin)) // And it's not recorded as a short to ground { errorHandler(testPin, curPin); numErrors++; } readback >>= 1; curPin++; } // And chip select... if ((curPin > testPin) && !Ports_ReadCS() && !SIMMElectricalTest_IsGroundShort(curPin)) { errorHandler(testPin, curPin); numErrors++; } curPin++; // Output enable... if ((curPin > testPin) && !Ports_ReadOE() && !SIMMElectricalTest_IsGroundShort(curPin)) { errorHandler(testPin, curPin); numErrors++; } curPin++; // And write enable if ((curPin > testPin) && !Ports_ReadWE() && !SIMMElectricalTest_IsGroundShort(curPin)) { errorHandler(testPin, curPin); numErrors++; } curPin++; // Not needed, kept for consistency // Finally, move on to the next stage if needed. if (curStage == TestingAddressLines) { // If we've exhausted all address lines, move on to the next stage // (and reset the pin counter to 0) if (++x > SIMM_HIGHEST_ADDRESS_LINE) { curStage++; x = 0; } } else if (curStage == TestingDataLines) { // If we've exhausted all data lines, move on to the next stage // (don't bother resetting the pin counter -- the other stages don't use it) if (++x > SIMM_HIGHEST_DATA_LINE) { curStage++; } } else { curStage++; } // Move on to test the next pin testPin++; } // Restore to a normal state. Disable any pull-ups, return CS/OE/WE to outputs, // deassert them all, set data as an input, set address as an input, // assert CS and OE. Should be a pretty normal state. // To start, make everything an input so we can disable pullups. Ports_SetCSDDR(false); Ports_SetOEDDR(false); Ports_SetWEDDR(false); Ports_SetAddressDDR(0); Ports_SetDataDDR(0); // Disable pullups Ports_SetCSPullup(false); Ports_SetOEPullup(false); Ports_SetWEPullup(false); Ports_AddressPullups_RMW(0, SIMM_ADDRESS_PINS_MASK); Ports_DataPullups_RMW(0, SIMM_DATA_PINS_MASK); // Set control lines to deasserted outputs (remember ON is deasserted) Ports_SetCSDDR(true); Ports_SetOEDDR(true); Ports_SetWEDDR(true); Ports_SetCSOut(true); Ports_SetOEOut(true); Ports_SetWEOut(true); // Set address lines to outputs and set the outputted address to zero Ports_SetAddressDDR(SIMM_ADDRESS_PINS_MASK); Ports_SetAddressOut(0); // Leave data lines as inputs...(they're already inputs so do nothing...) // Now assert CS and OE so we're in normal "read" mode Ports_SetCSOut(false); Ports_SetOEOut(false); // Now that the final state is restored, return the number of errors found return numErrors; }