Ejemplo n.º 1
0
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;
}