We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
We have bootstrap loader code as shown below:<br> <br>
void far vMainFunction(void) /******************************************************************************* Description: This the start of the code Inputs: NONE Outputs: NONE Globals: NONE *******************************************************************************/ { BYTE bLastByte; WORD uRamData; WORD *puRamPtr; // use 16 bit values BYTE idata *pbIramPtr; #pragma asm ADDRSEL1 DEFR 0FE18H DISWDT // Disable watchdog timer MOV SYSCON,#6184H // Stack size = 32 words, XRAM enabled NOP MOV DPP0,#0 // Set the data page pointer to point at 1st 4 pages MOV DPP1,#1 // which is all of internal memory MOV DPP2,#2 MOV DPP3,#3 NOP MOV ADDRSEL1,#0403H // CS1 active starting at 04'0000 (RAM) NOP MOV BUSCON0,#04AFH // CS is independent of write NOP MOV BUSCON1,#04AFH // CS is independent of write EINIT #pragma endasm // Set RS232 baudrate reload register, // Baud Rate = 20MHz / (16*2*[S0BG+1]). See (page 10-11) of Siemens C167 // Derivatives S0BG = 0x001F; // Baud Rate = 19.5264 KBaud /// Configure the serial link for: // 8-bit data asynchronous operation /// one stop bit /// divide clock by reload value + constant /// Disable receiver S0CON = 0x0011; // Setup the Rs232 output port P3 |= 0x0400; // set P3.10 output latch (TXD0) DP3 |= 0x0400; // set P3.10 direction control (TXD0 output) DP3 &= 0xF7FF; // reset P3.11 direction control (RXD0 input) // Enable the RS232 receiver S0R = 1; // Set ptr to start RAM address -> 0x40000 puRamPtr = (WORD *) RAM_START; // Check RAM -> 0x40000 - 0x40800 for ( puRamPtr = (WORD *) RAM_START, bLastByte = 0; puRamPtr <= RAM_END; puRamPtr++, bLastByte += 2 ) { // Store a pattern of n+1, n. For example; 0x01, 0x00 uRamData = bLastByte + ( (bLastByte + 1) << 8 ); // Put the WORD pattern into RAM *puRamPtr = uRamData; // See if the pattern was stored if (*puRamPtr != uRamData) { // RAM did not hold pattern, flag fault and lockup putbyte(RAM_MEMORY_ERROR); putbyte(0x5A); while(1); } } // RAM test passed, send indicator that FLASH loader download can begin putbyte(RAM_MEMORY_TEST_OK); // Load XRAM code -> continue loading FLASHLDR.SRE YES - ITSELF ! // This code loads all the code in FLASHLDR.C // The code is loaded to XRAM which is internal memory for ( pbIramPtr = (BYTE idata *)XRAM_START; pbIramPtr != (BYTE idata *)XRAM_END; pbIramPtr++ ) { // Wait for a byte to come in on the serial port while (! S0RIR); // Store the byte in XRAM bLastByte = S0RBUF; *pbIramPtr = bLastByte; // See if the byte was stored correctly if (bLastByte != *pbIramPtr) { // Store failed, send XRAM error and lockup putbyte(XRAM_WRITE_ERROR); while(1); } // Clear receive interrupt flag S0RIR = 0; } // Send the date and time through the serial port vSendDateAndTime(); // Running XRAM code, send write ready on the serial port putbyte(FLASH_MEMORY_WRITE_READY); // Erase the Flash, loaded by the code above vEraseFlash(); // Program the Flash vProgramFlash(); // Should never get here as software reset called in earlier process while(1); }/* vMainFunction() */
void vSendDateAndTime( ) /******************************************************************************* Description: This routine sends the date from the calendar chip to the serial port transmitter, waiting for the port to empty before sending the next character. Inputs: NONE Outputs: NONE Globals: NONE *******************************************************************************/ { BYTE bIndex; /* Initialize the calendar port I/O lines */ vInitCalendarPorts(); /* Read in the date from the calendar port */ vGetBcdDate( ); /* Send the date through the serial port */ for (bIndex=0; bIndex<=5; bIndex++) { vSendByte( bIndex ); } }/* vSendDateAndTime() */ void vInitCalendarPorts(void) /******************************************************************************* Description: This function initializes the EC300 port lines which interface with the calendar chip. Inputs: NONE Outputs: NONE Globals: NONE *******************************************************************************/ { /* Set the cal reset line (P3.7) as a push-pull input */ P3 &= CAL_RESET_OUT_LOW; ODP3 &= CAL_RESET_PUSH_PULL_MODE; DP3 &= CAL_RESET_INPUT; /* Set the cal io line (P3.6) as an open drain ouput, set output high */ P3 |= ~CAL_IO_OUT_LOW; P3 |= ~CAL_IO_PUSH_PULL_MODE; P3 |= ~CAL_IO_INPUT; /* Set the cal clock line (P3.5) as a push-pull output, set output low */ P3 &= CAL_CLK_OUT_LOW; ODP3 &= CAL_CLK_PUSH_PULL_MODE; DP3 |= ~CAL_CLK_INPUT; }/* vInitCalendarPorts() */
void vGetBcdDate( ) /******************************************************************************* Description: This function reads in the current date and time from the serial calendar chip. The serial calendar chip responds with data in the following order: Seconds, Minutes, Hours, Days, Months, Weeks, Years and Write Protect. This function discards the Write Protect responses. The data is loaded into an arrray as it comes in. No formatting is performed, the date is returned in BCD format. Inputs: pbDate - Array to load data to, offsets are as follows: [0] = BCD Seconds, 0x00-0x60 [1] = BCD Minutes, 0x00-0x60 [2] = BCD Hours, 0x00-0x24 [3] = BCD Days, 0x00-0x32 [4] = BCD Months, 0x00-0x12 [5] = BCD Years, 0x00-0x99 Outputs: NONE Globals: NONE *******************************************************************************/ { BYTE bData; /* Send out the original request for data*/ if ( bRequestCalendarChipData(READ_CALENDAR_CCR, SECOND_ADDRESS) ) { /* An acknowledge sequence was seen from the calendar chip, now get the data.*/ /* Read in seconds, send acknowledge*/ bData = bGetCalendarByte(); vSendAckToCalendarChip(); vSendByte( bData ); /* Read in minutes, send acknowledge*/ bData = bGetCalendarByte(); vSendAckToCalendarChip(); vSendByte( bData ); /* Read hours, send acknowledge*/ bData = bGetCalendarByte(); vSendAckToCalendarChip(); vSendByte( bData ); /* Read days, send acknowledge*/ bData = bGetCalendarByte(); vSendAckToCalendarChip(); vSendByte( bData ); /* Read months, send acknowledge*/ bData = bGetCalendarByte(); vSendAckToCalendarChip(); vSendByte( bData ); /* Read year data */ bData = bGetCalendarByte(); vSendByte( bData ); } else { vSendByte( 'X' ); } /* End communication sequence*/ vSendEtxToCalendarChip(); }/* vGetBcdDate() */
BYTE bRequestCalendarChipData(BYTE bCmd, WORD uAddress) /******************************************************************************* Description: This function reads data from the calendar chip. This is done through a Random read sequence as discussed on page 11 of XICOR X1226 data sheet. The protocol requires the EC300 to: A: Send Start bit and command with R/W set to 0 (write) B: Send MSbyte of address to read C: Read an ACK D: Send LSByte of address to read E: Read an ACK F: Send Start bit and command with R/W set to 1 (read) G: Read an ACK #$-URL:Xicor X1226 Data Sheet-$# Inputs: uAddress - Data address in the calendar chip (EEPROM or CCR). bCmd - READ_CALENDAR_CCR or READ_CALENDAR_EEPROM Outputs: TRUE if sequence was successful, FALSE otherwise Globals: NONE *******************************************************************************/ { BYTE bHiAddress; BYTE bLoAddress; BYTE bReturnCode; /* Assume the operation will be successful */ bReturnCode = TRUE; /* Create the start condition so that the calendar chip knows that a byte of data is forthcoming. A start condition occurs when the data line is pulled from high to low while the clock line is high.*/ vSendStartToCalendarChip(); /* Perform a dummy write operation to the slave address */ /* This is a CCR read sequence */ bHiAddress = CCR_1_ADDRESS; bLoAddress = (BYTE) (uAddress); vSendByteToCalendarChip(WRITE_CALENDAR_CCR); bReturnCode = bAckReceived(); /* Send out the high byte of the address to read */ if (bReturnCode == TRUE) { vSendByteToCalendarChip(bHiAddress); bReturnCode = bAckReceived(); } else { vSendByte( 'A' ); } /* Send out the low byte of the address to read */ if (bReturnCode == TRUE) { vSendByteToCalendarChip(bLoAddress); bReturnCode = bAckReceived(); } /* The dummy write has been completed, now send the data */ if (bReturnCode == TRUE) { /* Resend the start bit*/ vSendStartToCalendarChip(); /* Send out the read command (EEPROM read or CCR read) */ vSendByteToCalendarChip(bCmd); bReturnCode = bAckReceived(); } /* The request sequence is complete, return a status */ return( bReturnCode ); }/* bRequestCalendarChipData() */
void vSendByteToCalendarChip(BYTE bData) /******************************************************************************* Description: This function sends a byte of the data to the calendar chip. Inputs: bData - Byte of data to send to the calendar chip Outputs: NONE Globals: NONE *******************************************************************************/ { BYTE bPulses; BYTE bBitsToShift; /* If the clock line is high, bring it low to deactivate data line*/ if (P3 & ~CAL_CLK_OUT_LOW) { P3 &= CAL_CLK_OUT_LOW; WASTE_TIME } /* Make sure the data line is set for output*/ P3 |= ~CAL_IO_INPUT; /* Send out the data a bit at a time. MSbit gets sent first.*/ for (bPulses = MAX_PULSES; bPulses >= 1; bPulses--) { /* Make clock go low and delay*/ P3 &= CAL_CLK_OUT_LOW; WASTE_TIME /* Set a bit of data and delay*/ bBitsToShift = bPulses-1; if ( (bData >> bBitsToShift) & 0x01) { P3 |= ~CAL_IO_OUT_LOW; } else { P3 &= CAL_IO_OUT_LOW; } WASTE_TIME /* Make clock go high and delay, this transmits the bit to the chip*/ P3 |= ~CAL_CLK_OUT_LOW; WASTE_TIME } /* Make clock go low and delay, this deactivates the data line*/ P3 &= CAL_CLK_OUT_LOW; WASTE_TIME }/* vSendByteToCalendarChip() */
The answer is YES! I was able to talk to the serial calendar chip (through pins P3.5-P3.7) in boot strap loader mode. This will prove invaluable to us because we can now check the date for products in the field even if the flash program has been corrupted.