📄 mp3init.c
字号:
*AVR_DDRG |= bitpattern; // then the one bit of interest set to output
*AVR_PORTG |= TESTMASKG; // all portG testable bits set high (for inputs their pullups enabled)
*AVR_PORTG &= ~bitpattern; // then the one (output) bit of interest is driven low
errorc = ReadPortsExpectHigh (TESTMASKA, TESTMASKB, TESTMASKC, TESTMASKD, TESTMASKE, TESTMASKF, (~bitpattern)&TESTMASKG);
if (errorc) {
uart0_putwaitPROGstr(PSTR("ERROR - Apparent pin short. Port G output value was 0x"));
UART_PutHexWaitC(~bitpattern);
uart0_putwaitPROGstr(PSTR(". Unexpected pin low found on "));
PrintTestPortError(errorc);
return;
}
bitpattern >>= 1; // test the next bit; next one to the RIGHT
}
*AVR_DDRG &= ~TESTMASKG; // wrapup: make testable port bits all inputs (0=input, 1=output)
*AVR_PORTG |= TESTMASKG; // wrapup: pull-up resistors enabled for those input pins
// Next test. Drive all the testable output bits low. Then read them all to ensure they're all low.
// Wrapup by setting all the bits to inputs afterwards.
// The rationale behind this test is that if a pin is tied to VCC, there's a chance this test will
// catch it. A slim chance perhaps, but still a chance. Driving a pin low if it's tied to VCC
// can cause damage, so perform this test as quickly as possible.
*AVR_PORTA &= ~TESTMASKA;
*AVR_PORTB &= ~TESTMASKB;
*AVR_PORTC &= ~TESTMASKC;
*AVR_PORTD &= ~TESTMASKD;
*AVR_PORTE &= ~TESTMASKE;
*AVR_PORTF &= ~TESTMASKF;
*AVR_PORTG &= ~TESTMASKG; // define all of the testable bits as low
*AVR_DDRA |= TESTMASKA;
*AVR_DDRB |= TESTMASKB;
*AVR_DDRC |= TESTMASKC;
*AVR_DDRD |= TESTMASKD;
*AVR_DDRE |= TESTMASKE;
*AVR_DDRF |= TESTMASKF;
*AVR_DDRG |= TESTMASKG; // then make them outputs - physical pins are now driven low
// Now check they all read low, and report an error if any read as high.
errorc = ReadPortsExpectLow (TESTMASKA, TESTMASKB, TESTMASKC, TESTMASKD, TESTMASKE, TESTMASKF, (~bitpattern)&TESTMASKG);
if (errorc) {
uart0_putwaitPROGstr(PSTR("ERROR - pin tied high. "));
PrintTestPortError(errorc);
}
// Wrapup - set all those testable port pins back to inputs again.
*AVR_DDRA &= ~TESTMASKA;
*AVR_DDRB &= ~TESTMASKB;
*AVR_DDRC &= ~TESTMASKC;
*AVR_DDRD &= ~TESTMASKD;
*AVR_DDRE &= ~TESTMASKE;
*AVR_DDRF &= ~TESTMASKF;
*AVR_DDRG &= ~TESTMASKG;
*AVR_PORTA |= TESTMASKA; // pull-up resistors enabled for those input pins
*AVR_PORTB |= TESTMASKB;
*AVR_PORTC |= TESTMASKC;
*AVR_PORTD |= TESTMASKD;
*AVR_PORTE |= TESTMASKE;
*AVR_PORTF |= TESTMASKF;
*AVR_PORTG |= TESTMASKG;
// All tests are now complete.
uart0_putwaitPROGstr(PSTR("AVR Ports Bits Tests Completed.\r\n"));
}
void PrintTestPortError (u08 errorcode)
// This simple routine just prints, out the debug port, the return error code initially provided
// by ReadPortsExpectHigh, below. It decodes the error code so that it's shown on the debug port
// screen in a more user-friendly manner. The format is, for example: Port E Bit number 3
{
uart0_putwaitPROGstr(PSTR("Port "));
UART_TxCharWaitC( (errorcode>>4)+'A'-1 );
uart0_putwaitPROGstr(PSTR(" Bit number "));
UART_TxCharWaitC( (errorcode&0x0f)+'0' );
uart0_putwaitPROGstr(PSTR("\r\n"));
}
u08 ReadPortsExpectHigh (u08 MaskPA, u08 MaskPB, u08 MaskPC, u08 MaskPD, u08 MaskPE, u08 MaskPF, u08 MaskPG)
// This routine reads the value of the 7 Mega128 I/O Ports. By default it "expects" all of the port bits
// for each port to be "1". Unless the mask bit says "0", in which case that bit is ignored (masked out).
// So, an "ideal mask" is 0xff, which means the calling function expects all bits for that port to be high.
// For another example, if MaskPB==0xe0, this means the calling function expects the top 3 bits of port B
// to be 1's, and the lower 5 bits are "don't care".
//
// If everything is as expected (non-masked port bits are high), this routine returns 0.
// In the case of an error, this routine returns an 8-bit value where the high 4 bits correspond to the
// port, as follows:
// 1 = Port A
// 2 = Port B
// 3 = Port C
// 4 = Port D
// 5 = Port E
// 6 = Port F
// 7 = Port G
// and the low 4 bits correspond to the bit number that was in error (zero when it was expected to be 1),
// as follows:
// 0 = bit 0
// ...
// 7 = bit 7
// This routine only returns a single error. If multiple bits are in error, this routine only returns
// the details of the first error it finds.
{
u08 PortNum, ExpectZeros, BitCount;
// This routine just tests each of the 7 ports. It it detects a high bit it does a goto to the
// error reporting part. Otherwise it just keeps stepping down until it returns 0 at the end.
// Note that it inverts the reads of the ports, ie it converts an "expect ones" to an "expect zeros".
PortNum = 0x10; // port A
ExpectZeros = (~(*AVR_PINA)) & MaskPA; // read port, invert, mask
if (ExpectZeros) goto error;
PortNum = 0x20; // port B
ExpectZeros = (~(*AVR_PINB)) & MaskPB; // read port, invert, mask
if (ExpectZeros) goto error;
PortNum = 0x30; // port C
ExpectZeros = (~(*AVR_PINC)) & MaskPC; // read port, invert, mask
if (ExpectZeros) goto error;
PortNum = 0x40; // port D
ExpectZeros = (~(*AVR_PIND)) & MaskPD; // read port, invert, mask
if (ExpectZeros) goto error;
PortNum = 0x50; // port E
ExpectZeros = (~(*AVR_PINE)) & MaskPE; // read port, invert, mask
if (ExpectZeros) goto error;
PortNum = 0x60; // port F
ExpectZeros = (~(*AVR_PINF)) & MaskPF; // read port, invert, mask
if (ExpectZeros) goto error;
PortNum = 0x70; // port G
ExpectZeros = (~(*AVR_PING)) & MaskPG; // read port, invert, mask
if (ExpectZeros) goto error;
// Execute here if all ports read OK. Return 0.
return 0;
// Execute here if an error was detected. Port number is already in PortNum. We do need to determine
// which bit is the unexpected "1" in ExpectZeros. If there is more than one "1" in ExpectZeros
// we'll only report one of them. (We only get here if ExpectZeros is non-zero.)
error:
BitCount = 0;
while ( (ExpectZeros&0x01) == 0 ) { // is the low bit zero?
ExpectZeros >>= 1; // yes - shift byte to the right, to test next bit
BitCount++; // and increment the bit counter
} // Repeat until low bit is a 1.
return PortNum | BitCount;
}
u08 ReadPortsExpectLow (u08 MaskPA, u08 MaskPB, u08 MaskPC, u08 MaskPD, u08 MaskPE, u08 MaskPF, u08 MaskPG)
// Exactly the same as ReadPortsExpectHigh() above, but this one is expecting the port bits to read low.
// Read the comments for the routine above for masks descriptions.
{
u08 PortNum, ExpectZeros, BitCount;
PortNum = 0x10; // port A
ExpectZeros = (*AVR_PINA) & MaskPA; // read port, mask
if (ExpectZeros) goto error; // error if there's a high bit in there
PortNum = 0x20; // port B
ExpectZeros = (*AVR_PINB) & MaskPB; // read port, mask
if (ExpectZeros) goto error; // error if there's a high bit in there
PortNum = 0x30; // port C
ExpectZeros = (*AVR_PINC) & MaskPC; // read port, mask
if (ExpectZeros) goto error; // error if there's a high bit in there
PortNum = 0x40; // port D
ExpectZeros = (*AVR_PIND) & MaskPD; // read port, mask
if (ExpectZeros) goto error; // error if there's a high bit in there
PortNum = 0x50; // port E
ExpectZeros = (*AVR_PINE) & MaskPE; // read port, mask
if (ExpectZeros) goto error; // error if there's a high bit in there
PortNum = 0x60; // port F
ExpectZeros = (*AVR_PINF) & MaskPF; // read port, mask
if (ExpectZeros) goto error; // error if there's a high bit in there
PortNum = 0x70; // port G
ExpectZeros = (*AVR_PING) & MaskPG; // read port, mask
if (ExpectZeros) goto error; // error if there's a high bit in there
// Execute here if all ports read OK. Return 0.
return 0;
// Execute here if an error was detected. Port number is already in PortNum. We do need to determine
// which bit is the unexpected "1" in ExpectZeros. If there is more than one "1" in ExpectZeros
// we'll only report one of them. (We only get here if ExpectZeros is non-zero.)
error:
BitCount = 0;
while ( (ExpectZeros&0x01) == 0 ) { // is the low bit zero?
ExpectZeros >>= 1; // yes - shift byte to the right, to test next bit
BitCount++; // and increment the bit counter
} // Repeat until low bit is a 1.
return PortNum | BitCount;
}
void TestHarddisk (void)
// This routine performs some tests of the harddisk. It must be plugged in to function.
// It's called from the debug port menu.
{
u08 temp, temp2;
uart0_putwaitPROGstr(PSTR("Commencing Harddisk Tests.\r\n"));
// First test. Wait for drive to be not busy. Print debug info while waiting.
uart0_putwaitPROGstr(PSTR("Waiting for drive not busy. "));
uart0_putwaitPROGstr(PSTR("Drive status register: 0x"));
UART_PutHexWaitC(IDE_read8_C(0x7f));
while ( IDE_read8_C(0x7f) & 0x80 ); // wait until drive says it's not busy (wait for top bit to clear)
uart0_putwaitPROGstr(PSTR("\r\nOK, drive no longer busy.\r\n"));
// Next test. Read from both the Status register and the Alternate Status registers,
// and compare them. Complain if they're not the same. This is a "read test"; used to
// determine if the player can read from the IDE bus. If this test fails, look for
// bus read problems. Running TestReadHarddisk() below, can be useful for helping
// to find the problem.
temp = IDE_read8_C(0x7f); // read Status register
temp2 = IDE_read8_C(0xb7); // read Alternate Status register
if (temp != temp2) {
uart0_putwaitPROGstr(PSTR("ERROR: Status and Alternate Status registers not the same.\r\n"));
uart0_putwaitPROGstr(PSTR("Status register: 0x"));
UART_PutHexWaitC(temp);
uart0_putwaitPROGstr(PSTR(" Alternate Status register: 0x"));
UART_PutHexWaitC(temp2);
uart0_putwaitPROGstr(PSTR("\r\nA typical Status register value is 0x50.\r\n"));
}
// Next test. Write some data into the sector count register, and the four sector number
// registers, then verify by reading it back. Report error if any problems. This is
// basically a "write test". If the board passed the read test above, but failed this test,
// there's possibly a write problem (like the /WR signal) with the IDE bus. Running the
// TestWriteHarddisk() routine, below, can be helpful for finding the problem.
IDE_Write8_C(0x57, 0xaa); // write to sector count register
IDE_Write8_C(0x5f, 0x55); // write to first sector number register
IDE_Write8_C(0x67, 0x0f); // second sector number
IDE_Write8_C(0x6f, 0xf0); // third sector number
IDE_Write8_C(0x77, 0xec); // sdh register; final sector number
if ((temp=IDE_read8_C(0x57)) != 0xaa) {
uart0_putwaitPROGstr(PSTR("ERROR confirming sector count register, address 0x57.\r\n"));
uart0_putwaitPROGstr(PSTR("Data written was 0xAA. Data read was 0x"));
UART_PutHexWaitC(temp);
uart0_putwaitPROGstr(PSTR(".\r\n"));
}
// All tests completed.
uart0_putwaitPROGstr(PSTR("Harddisk Tests Completed.\r\n"));
}
void TestWriteHarddisk (void)
// This test does continuous writes to the harddisk. Useful so you can put a scope
// on the IDE bus and see if it's working correctly.
{
uart0_putwaitPROGstr(PSTR("Writing 0xAA's to the Sector Count Register forever.\r\n"));
while (1)
IDE_Write8_C(0x57, 0xaa); // write to sector count register
}
void TestReadHarddisk (void)
// This test does continuous reads of the harddisk. Useful so you can put a scope
// on the IDE bus and see if it's working correctly.
{
uart0_putwaitPROGstr(PSTR("Reading the Status Register forever.\r\n"));
while (1)
IDE_read8_C(0x7f); // read from the Status register
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -