📄 prodtest.c
字号:
/*
* prodtest.c
*
* This application is loaded as a module in the flash and executed if the
* bootstrap loader determines that the board is in test mode (currently
* triggered by sensing a loop back cable between COM0 to COM1)
*
* Prodtest first sets the 7 segment display to 8 (all segments ON.) It will
* then update the 7 segment display based on the setting of User DIP
* switches (SW5) each time User Int0 switch (SW3) is pressed.
*
* Setting the switch to 0XF (all on) will break out of this loop. The module
* then tests the user RAM region. If an error is detected, it will light
* only LED D2 and wait for the user to press User Int0.
*/
#include "uhal.h"
#include "segdisp.h"
#include "module.h"
#define EnableInterrupt( n ) ( *(volatile unsigned *)INTMSK &= ~(1 << n) )
#define DisableInterrupt( n ) ( *(volatile unsigned *)INTMSK |= (1 << n) )
#define SWITCH_MASK (0xF)
/* Interrupt controller defines, SW3 is tied to external INT0 */
#define INT_SW3_MASK (1)
#define INT_SW3_NUM (0)
/* IO controller defines for SW3 */
#define IO_ENABLE_INT0 (1 << 4)
#define IO_ACTIVE_HIGH_INT0 (1 << 3)
#define IO_RISING_EDGE_INT0 (1)
#define FALL_THROUGH_VALUE (0xF)
/* Forward references */
unsigned poll_dipSwitch( void );
void test_mem( void );
void SetLEDs( unsigned val );
extern const unsigned numeric_display[];
unsigned cmain( void )
{
SetLEDs( 0xf );
/* Turn on 7 segment display */
*(volatile unsigned *)IOPMOD |= SEG_MASK;
/* disable interrupts, but pending bit wil still be set by an active
interrupt */
EnableInterrupt( INT_SW3_NUM );
DisableInterrupt( INT_GLOBAL );
*(volatile unsigned *)IOPCON = IO_ENABLE_INT0 | IO_ACTIVE_HIGH_INT0 |
IO_RISING_EDGE_INT0;
while ( 1 )
{
unsigned Switch;
while ( 0 == ( (1 << INT_SW3_NUM ) & *(volatile unsigned *)INTPND) )
{
;
} /* wait till we sense the switch */
*(volatile unsigned *)INTPND |= INT_SW3_MASK; /* clear interrupt */
Switch = poll_dipSwitch();
if ( FALL_THROUGH_VALUE == Switch )
{
break;
}
} /* end while wait for fall through value in switch */
/* Do memory test */
test_mem();
DisableInterrupt( INT_SW3_NUM );
EnableInterrupt( INT_GLOBAL );
return( 0 ); /* Callback function for this module */
}
void BogusCall( void )
{
cmain();
}
unsigned poll_dipSwitch( void )
{
unsigned ioData, Switch;
Switch = SWITCH_MASK & *(unsigned *)IOPDATA;
SetLEDs( Switch );
ioData = numeric_display[Switch];
*(volatile unsigned *)IOPDATA &= ~SEG_MASK;
*(volatile unsigned *)IOPDATA |= ioData;
return( Switch );
}
void SetLEDs( unsigned val )
{
*(volatile unsigned *)IOPDATA &= ~ALL_LEDS;
*(volatile unsigned *)IOPDATA |= val << 4;
}
#define MEMTEST_START (0x8000)
#define MEMTEST_DIV (0x00010000)
#define MEMTEST_END (0x00070000)
#define MEM_PAT_0 (0xE7FFE853)
#define MEM_PAT_1 (0xE7FFE950)
#define MEM_PAT_2 (0xE7FFEA51)
#define MEM_PAT_3 (0xE7FFEB52)
const unsigned mem_pat[] = { MEM_PAT_0, MEM_PAT_1, MEM_PAT_2, MEM_PAT_3 };
void test_mem( void )
{
unsigned i;
U8 *pByteRead, *pByteWrite;
U16 *pHalfRead, *pHalfWrite;
unsigned *pRead, *pWrite;
pRead = pWrite = (unsigned *)MEMTEST_START;
while ( pWrite < (unsigned *)(MEMTEST_DIV) )
{
for ( i = 0; i < ( sizeof(mem_pat) / sizeof(mem_pat[0]) ); i++ )
{
*pWrite++ = mem_pat[i];
}
}
while ( pWrite < (unsigned *)MEMTEST_END )
{
pByteRead = (U8 *)pRead;
pByteWrite = (U8 *)pWrite;
for ( i = 0; i < 16; i++ )
{
*pByteWrite++ = *pByteRead++;
}
pHalfRead = (U16 *)pByteRead;
pHalfWrite = (U16 *)pByteWrite;
for ( i = 0; i < 8; i++ )
{
*pHalfWrite++ = *pHalfRead++;
}
pRead = (unsigned *)pHalfRead;
pWrite = (unsigned *)pHalfWrite;
for ( i = 0; i < 8; i++ )
{
*pWrite++ = *pRead++;
}
} /* end while the pattern is read and written in various sizes */
pRead = (unsigned *)MEMTEST_START;
i=0;
while ( pRead < (unsigned *)MEMTEST_END )
{
if ( *pRead++ != mem_pat[i++])
{
--pRead;
SetLEDs( 0x4 ); /* Set only RED LED */
/* Place an indicator of the type memory acces failed */
if ( pRead < (unsigned *)MEMTEST_DIV )
{
i = 2;
}
else
{
i = ((unsigned)(pRead)) & 0x3F;
if ( i < 32 )
{
i = (i < 16)? 8 : 6; /* 8 or 16 bit access */
}
else
i = 2; /* 32 bit access failed */
}
*(volatile unsigned *)IOPDATA &= ~SEG_MASK;
*(volatile unsigned *)IOPDATA |= numeric_display[i];
while ( 0 == ( (1 << INT_SW3_NUM ) & *(volatile unsigned *)INTPND) )
{
;
} /* wait till we sense the switch */
break; /* exit the test */
}
i %= 4;
}
/* mem test sucessful */
} /* end of memory test */
const unsigned numeric_display[] = { DISP_0, DISP_1, DISP_2, DISP_3, DISP_4,
DISP_5, DISP_6, DISP_7, DISP_8, DISP_9,
DISP_A, DISP_b, DISP_C, DISP_d, DISP_E,
DISP_F };
const char timestamp[] = "ProductionTest v1.0 " __DATE__ " " __TIME__ "";
const ModuleHeader ModuleHead = {
MODULE_MAGIC, /* magic field */
FACTORY_FLAG,
MAJOR_VERSION, /* major version = current version */
MINOR_VERSION, /* minor version = current version */
0, /* checksum - done later - set to 0 now */
Image$$RO$$Base, /* ro_base */
Image$$RO$$Limit, /* ro_limit */
Image$$RW$$Base, /* rw_base */
Image$$ZI$$Base, /* zi_base */
Image$$ZI$$Limit, /* zi_limit */
&ModuleHead, /* 'self' */
(StartCode)cmain, /* entry */
0, /* No init code */
0, /* No final code */
0, /* No service code */
"ProductionTest", /* title */
(char *)×tamp[0], /* help string */
0,
0,
0
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -