📄 ethloop.c
字号:
//
// Enable-write command
//
outport( ( IO_BASE + PP_POINTER ), 0x0040 );
outport( ( IO_BASE + PP_DATA ), 0x00F0);
//
// Wait until SIBUSY is clear
//
for (;;) {
outport( (IO_BASE + PP_POINTER), 0x0136);
if(((temp=inport(IO_BASE + PP_DATA)) & 0x0100) == 0) break;
}
// Write the outWord Value to EEPROM
outport( (IO_BASE + PP_POINTER), 0x0042);
outport((IO_BASE + PP_DATA), outword);
//
// Write command
//
outport( ( IO_BASE + PP_POINTER ), 0x0040 );
outport( ( IO_BASE + PP_DATA ), (0x0100 + EE_word_offset));
//
// Wait until SIBUSY is clear
//
for (;;) {
outport( (IO_BASE + PP_POINTER), 0x0136);
if(((temp=inport(IO_BASE + PP_DATA)) & 0x0100) == 0) break;
}
//
// Disable-write command
//
outport( ( IO_BASE + PP_POINTER ), 0x0040 );
outport( ( IO_BASE + PP_DATA ), 0x0000);
//
// Wait until SIBUSY is clear
//
for (;;) {
outport( (IO_BASE + PP_POINTER), 0x0136);
if(((temp=inport(IO_BASE + PP_DATA)) & 0x0100) == 0) break;
}
//
// Read back what is written command
//
outport( ( IO_BASE + PP_POINTER ), 0x0040 );
outport( ( IO_BASE + PP_DATA ), (0x0200 + EE_word_offset));
//
// Wait until SIBUSY is clear
//
for (;;) {
outport( (IO_BASE + PP_POINTER), 0x0136);
if(((temp=inport(IO_BASE + PP_DATA)) & 0x0100) == 0) break;
}
//
// Delay for a while
//
for (j=0; j<30000; j++);
//
// Read back and return word
//
outport( (IO_BASE + PP_POINTER), 0x0042);
temp=inport(IO_BASE + PP_DATA);
return(temp);
}
/**************************************************************************
* parse_lines()
**************************************************************************/
void parse_lines(char *StrArray[])
{
char *line, *stopstring, c;
int i;
line_cnt = 0;
crnt_word = 0;
blk_count = 0;
while( StrArray[line_cnt] != 0) {
line=StrArray[line_cnt];
line_cnt++;
for( i= 0; isspace(c = line[i]) && c != '\n'; i++)
; /* skip white space */
if( line[i] == '\n')
; /* stop processing if end of line */
else if ( line[i] == ';')
; /* ignore rest of line -- it's a commnet */
else if (line[i] == '$')
process_directive(&line[i+1]);
else if(isxdigit(line[i])) {
if( blk_count) {
EE_data[crnt_word++] = (unsigned short int) strtoul( &line[i], &stopstring, 16 );
blocks[blk_count - 1].w_count += 1;
}
else {
printf("Error: data word before address specified\n");
return;
}
}
else {
printf("Error in script file input line %d\n",line_cnt);
return;
}
}
}
/**************************************************************************
* process_directive(()
**************************************************************************/
void process_directive(char *s)
{
char c, t;
c = s[0];
//
// c is the first character of the command
//
switch( c ) {
//
// 'A' is a command to get the address
case 'A': case 'a':
blocks[blk_count].ee_addr = get_ee_addr(s);
blocks[blk_count].w_count = 0;
++blk_count;
break;
//
// 'C' is a checksum command
//
case 'C': case 'c':
//
// Find out what type of checksum
t = get_chksum_type(s);
if(t)
//
// Call the appropriate checksum routine based on the checksum command.
//
switch (t) {
case 'B': case 'b':
EE_data[crnt_word] = chksum (chksum_base, crnt_word - chksum_base);
blocks[blk_count - 1].w_count += 1;
++crnt_word;
chksum_state = OUT;
break;
case 'W': case 'w':
EE_data[crnt_word] = word_chksum (chksum_base, crnt_word - chksum_base);
blocks[blk_count - 1].w_count += 1;
++crnt_word;
chksum_state = OUT;
break;
case 'L': case 'l':
EE_data[crnt_word] = 0x0A00 ^ LFSR_chksum(chksum_base, crnt_word - chksum_base);
blocks[blk_count - 1].w_count += 1;
++crnt_word;
chksum_state = OUT;
break;
case 'P': case 'p':
PnP_chksum (chksum_base, crnt_word - chksum_base);
chksum_state = OUT;
break;
default:
printf("$CHKSUM command not recognized: line %d\n",line_cnt);
return;
break;
}
//
// Else, returned NULL so it's a start tag
else {
if(chksum_state == IN) {
printf("Error in script file input line %d\n",line_cnt);
return;
}
chksum_state = IN;
chksum_base = crnt_word;
}
break;
case 'I': case 'i':
EE_data[crnt_word] = byte_swap(ia_word[0]);
blocks[blk_count - 1].w_count += 1;
++crnt_word;
EE_data[crnt_word] = byte_swap(ia_word[1]);
blocks[blk_count - 1].w_count += 1;
++crnt_word;
EE_data[crnt_word] = byte_swap(ia_word[2]);
blocks[blk_count - 1].w_count += 1;
++crnt_word;
break;
case 'S': case 's':
EE_data[crnt_word] = sn_word[1];
blocks[blk_count - 1].w_count += 1;
++crnt_word;
EE_data[crnt_word] = sn_word[0];
blocks[blk_count - 1].w_count += 1;
++crnt_word;
break;
default:
printf("Error in script file input line %d\n",line_cnt);
exit(1);
break;
}
}
/**************************************************************************
* get_chksum_type()
**************************************************************************/
char get_chksum_type(char *s)
{
char *c;
c = strpbrk(s,"=");
//
// look for = sign -- means it's an end tag
//
if( c ) {
c = strpbrk(s,"bBwWlLpP");
//
// Return chksum type
//
return c[0];
}
else
//
// "=" sign not found -- assume it's a start tag
//
return 0;
}
/**************************************************************************
* get_ee_addr()
**************************************************************************/
unsigned short int get_ee_addr(char *s)
{
char *stopstring;
int i;
for( i=0; s[i] != '='; i++)
i++;
//
// Move past directive text
//
while(isspace(s[++i]));
//
// Move to first digit
//
return ( (unsigned short int) strtoul( &s[i], &stopstring, 16 ) );
}
/**************************************************************************
* Checksum():
*
* Returns a checksum "word" based on all "bytes" in a block. Blk_lenght is
* actual number of bytes to sum. Checksum is returned in high byte of word.
**************************************************************************/
unsigned short int chksum (unsigned short int base, unsigned short int word_cnt)
{
unsigned short int i, sum = 0;
for(i=0; i < word_cnt; i++) {
sum += ((EE_data[base] & 0xFF) + (EE_data[base] >> 8));
++base;
}
sum = ~sum + 1;
return sum << 8;
}
/**************************************************************************
* PnP_chksum()
**************************************************************************/
void PnP_chksum(unsigned short int base, unsigned short int word_cnt)
{
unsigned short int i, sum = 0;
//
// don't calc with word that has end tag
//
--word_cnt;
for(i=0; i < word_cnt; i++) {
sum += ((EE_data[base] & 0xFF) + (EE_data[base] >> 8));
++base;
}
//
// Add byte following the LFSR checksum and end tag
//
sum = sum + 0xA + 0x79;
if( (EE_data[crnt_word - 1] & 0xFF) == 0x79) { /* end tag in low byte */
sum = ~sum + 1;
i = (sum << 8) ^ 0x79; /* sum79 */
EE_data[crnt_word - 1] = i; /* put sum in high byte of prev word */
}
//
// Else, Assume end tag in high byte of prev word
//
else {
sum = sum + (EE_data[crnt_word - 1] & 0xFF); /* add the low byte */
sum = ~sum + 1;
EE_data[crnt_word] = sum & 0xFF; /* put in low byte of crnt word -- pad with 00 in hb */
blocks[blk_count - 1].w_count += 1;
++crnt_word;
}
}
/**************************************************************************
* ord_chksum Routine
* Returns a checksum word based on all 16-bit words in a block of data.
***************************************************************************/
unsigned short int word_chksum (unsigned short int base,
unsigned short int word_cnt)
{
unsigned short int i, sum = 0;
for(i=0; i < word_cnt; i++)
sum += EE_data[base++];
return (sum = ~sum + 1);
}
/**************************************************************************
* LFSR_chksum Routine
* Returns 8-bit Linear Feedback Shift Register checksum on all bytes
* in a block of 16-bit words. Words are assumed to be organized
* little-endian.
***************************************************************************/
unsigned char LFSR_chksum(unsigned short int base, unsigned short int word_cnt)
{
unsigned char LFSR, byte_ctr, bits, XORvalue, byte, i, j = 0;
unsigned char bytes[0xFF];
for(i=0; i < word_cnt; i++) {
bytes[j++] = (unsigned char)(EE_data[base] & 0xFF); /* convert words to byte stream */
bytes[j++] = (unsigned char)(EE_data[base++] >> 8);
}
LFSR = 0x6A;
word_cnt = word_cnt << 1; /* adjust word count to bytes */
for (byte_ctr = 0; byte_ctr < word_cnt; byte_ctr++) {
byte = bytes[byte_ctr];
for (bits = 0; bits < 8; bits++) {
XORvalue = ( (LFSR & 3 ) == 1 || (LFSR & 3) == 2) ? 1 : 0;
LFSR = LFSR >> 1;
if (XORvalue ^ (byte & 1))
LFSR |= 0x80;
byte = byte >> 1;
}
}
return(LFSR);
}
/**************************************************************************
* byte_swap()
**************************************************************************/
unsigned short int byte_swap(unsigned short int word)
{
//
// Byte swap the word
//
return ( (word << 8) + (word >> 8) );
}
/**************************************************************************
* burn_it() Burn into EEPROM
**************************************************************************/
int burn_it(void)
{
unsigned short int i, j,k, temp;
i = 0;
crnt_word = 0;
while(i < blk_count) {
for(j=0; j < blocks[i].w_count; j++) {
k=blocks[i].ee_addr+j;
temp=writeEE(k, EE_data[crnt_word]);
if ( temp != EE_data[crnt_word]) {
printf("Error! Burn_it(): EE_Addr=%d, ReadBackData=%x, ShouldBe=%x\n\n",
k,temp,EE_data[crnt_word]);
return(FAILURE);
}
crnt_word++;
}
i++;
}
return(SUCCESS);
}
/**************************************************************************
* readBack()
**************************************************************************/
void readBack(void)
{
unsigned short int i,j,k, temp;
i = 0;
crnt_word = 0;
while(i < blk_count) {
for(j=0; j < blocks[i].w_count; j++) {
k = blocks[i].ee_addr + j;
temp = readEE(k);
if ( temp != EE_data[crnt_word]) {
printf("\nError: EEPROM test fail! \n");
printf("Error! ReadBack(): EE_Addr=%d, ReadBackData=%x, ShouldBe=%x\n\n",
k,temp,EE_data[crnt_word]);
return;
}
crnt_word++;
}
i++;
}
printf("EEPROM Test Completed Successfully! \n");
return ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -