This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Bootstrap Loader Question - Access to general purpose IO

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() */
<br>
We would like to access general IO pins P3.5,<br>
P3.6, and P3.7 during the loading process. We would like access to those pins so that we can communicate with a clock calendar chip.<br>
<br>
My question is as follows: during boot strap loading, are the general IO pins accessible or not? I can't seem to get access to the pins through the boot load functions (looking at the pins with a scope I see nothing happening...)<br>
<br>

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.