CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Firmware won't start after power off/on
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
wiseacre



Joined: 14 Jun 2012
Posts: 9

View user's profile Send private message

Firmware won't start after power off/on
PostPosted: Thu Jun 14, 2012 11:40 am     Reply with quote

I've got a really strange problem I've been unable to figure out, along with some help from a coworker. I've written a program (that still isn't fully complete, but working) that works just fine when I program the PIC. However, if I unplug power and then power the board back up, the program won't run. I've done this both with and without the debugger attached. If I try to reprogram the PIC after doing this, the code won't work. If I program another program onto the PIC, that program will work and then I can program my program and have it work. This second program that works will also start on power up just fine, which leads me to believe it's something in the code, but we've been working on this for days and have yet to figure it out. I don't have the code fully commented yet, but this is what I'm working with:

Code:

/*=================================================================
 Name        : StatusIndicatorLIghtsDisplay.c
 Author      : Valerie Halbur
 Copyright   : 2012 Mayo Foundation for Medical Education and Research
 Description : Status Indicator Lights Display Control Software
==================================================================
*/

#define DEV_BOARD

#include <18F2520.h>

// Select one of the these settings
//#FUSES NODEBUG               
#FUSES DEBUG                   

#device ICD=TRUE

#FUSES WDT                       //Watch Dog Timer
#FUSES WDT128                    //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                        //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPROTECT                 //Code not protected from reading
#FUSES NOBROWNOUT                //No brownout reset
#FUSES PUT                       //Power Up Timer
#FUSES NOCPD                     //No EE protection
#FUSES STVREN                    //Stack full/underflow will cause reset
#FUSES NOLVP                     //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                     //Program memory not write protected
#FUSES NOWRTD                    //Data EEPROM not write protected
#FUSES NOIESO                    //Internal External Switch Over mode disabled
#FUSES NOFCMEN                   //Fail-safe clock monitor disabled
#FUSES NOPBADEN                  //PORTB pins are configured as digital I/O on RESET
#FUSES NOWRTC                    //configuration not registers write protected
#FUSES NOWRTB                    //Boot block not write protected
#FUSES NOEBTR                    //Memory not protected from table reads
#FUSES NOEBTRB                   //Boot block not protected from table reads
#FUSES NOCPB                     //No Boot Block code protection
#FUSES LPT1OSC
#FUSES MCLR                      //Master Clear pin enabled


#include <StatusIndicatorLightsDisplay.h>

/* case sensitivity */
#case

#define Version "1.0.0"

#define 1MSCLICKS 1000  // 2000 = (.001 sec)/(4/CLOCKSP==8000000)
                       // Must be a divide by 4 somewhere

//  Number of Ticks in 1ms
#define TIMER001MS 65536-1MSCLICKS   // Interrupts on overflow


#include <string.h>
#include <stdlib.h>


// Stores the version
const char strVersion[] = Version;

#FUSES INTRC_IO
#define CLOCKSP 8000000
#use delay(clock=CLOCKSP,internal)

// These are stored during compile time. Each executable
//   has one copy of these variables.
char strCompileDate[] = __DATE__;
char strCompileTime[] = __TIME__;

/* setup the UART on port C pins 6 and 7 */
#USE RS232(BAUD=9600, UART1,PARITY=N,BITS=8,STREAM=PC,ERRORS)

//enable the i2c protocol
#use i2c(Master,Slow,sda=PIN_C4,scl=PIN_C3,restart_wdt)

#define XmtDataAvailable (XmtWriteIndex  != XmtReadIndex)  // indicates a char is available in Xmt ring buffer
#define RcvDataAvailable (RcvWriteIndex != RcvReadIndex)  // indicates a char is available in Rcv ring buffer


int8 CRC = 0;                        //Byte to store the calculated CRC
int8 Stations1_4 = 0;               //Byte to store the radio/phone status of stations 1-4
int8 Stations5_8 = 0;               //Byte to store the radio/phone status of stations 5-8
int8 Stations9_11 = 0;              //Byte to store the radio/phone status of stations 9-11
int8 Stations12_14 = 0;             //Byte to store the radio/phone status of stations 12-14
int8 RcvdCRC = 0;                   //Byte to store the received CRC to compare to what it should be

int16 ResponseTimeoutCounter = RESPONSE_TIMEOUT_RESET_COUNT;

bool bUpdateStatusFlag = FALSE;     //Flag to indicate the status needs to be updated
bool bQueryStatusFlag = FALSE;      //Flag to indicate the status only needs to be queried
bool bResponseTimeout = FALSE;

// Rcv Com Port Ring buffer
char    RcvComPortBuffer[MAX_NUM_RCV_CHARS];
//Searched through if there was a CRC error
char    RcvBackupComPortBuffer[MAX_NUM_RCV_CHARS];
// Read and write index always point to next place to read or write
// So buffer is empty if they are =. And is full if write index is
// one behind read index.
unsigned int RcvWriteIndex=0;
unsigned int RcvReadIndex=0;
unsigned int RcvBackupWriteIndex=0;
unsigned int RcvBackupReadIndex=0;
unsigned int RcvBackupCurrentIndex=0;

// Xmt Com Port Ring buffer
char    XmtComPortBuffer[MAX_NUM_XMT_CHARS];
// Read and write index always point to next place to read or write
// So buffer is empty if they are =. And is full if write index is
// one behind read index.
unsigned int XmtWriteIndex=0;
unsigned int XmtReadIndex=0;

//Used to make sure only one command is received at a time
int8 SendUpdateCounter = SEND_UPDATE_COUNTER_RESET_COUNT;
int8 RcvUpdateCounter = RCV_UPDATE_COUNTER_RESET_COUNT;
int8 SendQueryCounter = SEND_QUERY_COUNTER_RESET_COUNT;
int8 RcvQueryCounter = RCV_QUERY_COUNTER_RESET_COUNT;

char command = ' ';
char TempBuffer[33];


//============================================================================
// Name:        _wr_()
// Description  ISR for Empty Transmission Buffer
// Inputs:      Serial Port 1 interrupt
// Outputs:     External
// Return:      None
// Interaction: Reads chars from Xmt Com Port ring buffer and writes to com port
// ===========================================================================
#INT_TBE
void _wr_()
{
   if((SendUpdateCounter!=0)&&(SendQueryCounter!=0))
   {
      while(XmtDataAvailable)
      {
          // Read char from buffer & write to Com Port
          putc(*(char*)(XmtComPortBuffer+XmtReadIndex++));
                 
          // Check for modulo of index
          if (XmtReadIndex == MAX_NUM_XMT_CHARS)
          {
              XmtReadIndex = 0;
          }
          //If sending update information
         //Counter used to ensure only one command is sent
         if(bUpdateStatusFlag==TRUE)
         {
            SendUpdateCounter--;
         }
         //If sending query information
         //Counter used to ensure only one command is sent
         if(bQueryStatusFlag==TRUE)
         {
            SendQueryCounter--;
         }
      }
   }
   else
   {
      disable_interrupts(INT_TBE);
   }
   return;
}

//============================================================================
// Name:        _rd_()
// Description  ISR for Received chars on Com Port
// Inputs:      Serial Port 1 interrupt
// Outputs:     None
// Return:      None
// Interaction: Writes chars to Rcv Com Port Ring buffer
// ===========================================================================
#INT_RDA
void _rd_()
{
   ResetRcvUpdateCounter();
   ResetRcvQueryCounter();
   ResetResponseTimeoutCounter();
   bResponseTimeout = FALSE;
   //Loop until a full command response is received
   while((RcvUpdateCounter>0)&&(RcvQueryCounter>0)&&(bResponseTimeout == FALSE))
   {
      //If byte in receive buffer, otherwise wait until a new byte arrives
       if(kbhit(PC)== TRUE)
       {
           char ch=fgetc(PC);
           if (ch == '!')
           {
               bUpdateStatusFlag = TRUE;
               bQueryStatusFlag = FALSE;
           }
           else if (ch == '#')
           {
               bUpdateStatusFlag = FALSE;
               bQueryStatusFlag = TRUE;
           }
       
         unsigned int WorkingRcvWriteIndex=RcvWriteIndex;
   
         // Check for modulo
         if (++WorkingRcvWriteIndex == MAX_NUM_RCV_CHARS)
         {
             WorkingRcvWriteIndex = 0;
         }
         
         // Check for Buffer full. If full, dont write char
         if (WorkingRcvWriteIndex != RcvReadIndex)
         {
             // Write char to buffer
             *(char*)(RcvComPortBuffer+RcvWriteIndex) = ch;
             *(char*)(RcvBackupComPortBuffer+RcvWriteIndex) = ch;
             // Set it to new position
             RcvWriteIndex = WorkingRcvWriteIndex;
             RcvBackupWriteIndex = WorkingRcvWriteIndex;
         }
         //Only wait for more incoming data until a one command is received
         if(bUpdateStatusFlag==TRUE)
         {
            RcvUpdateCounter--;
         }
         if(bQueryStatusFlag==TRUE)
         {
            RcvQueryCounter--;
         }
      }
      else
      {
         if (--ResponseTimeoutCounter == 0)
         {
            bResponseTimeout = TRUE;
         }
      }
     
   }
    return;
}
//============================================================================
// Name:        Setup()
// Description  Initializes HW & SW
// Inputs:      None
// Outputs:     None
// Return:      None
// Interaction: Sets up ADC, timers, interrupts, ports
//             
// ===========================================================================
void setup()
{
   
    // Empty
    while(kbhit(PC))
    {
        fgetc(PC);
    }
   
    // This sets up which port to sample next. Obviously, only 1 choice
    //    here, so never has to change.
    set_adc_channel(0);
    delay_us(25);     
       
    setup_spi(FALSE);
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
    // Internal Clock, 8000000
    // Divide by 4 to get ips => 0.5 usec
    // 0.5 usec * 2 = 1 usec
    // for 1 ms = 2 usec * 500
    // For a 1 ms timer, set timer to 65566 - 500
   
    // Reset these flags in case it was a watchdog timeout & state unknown
    RcvWriteIndex=0;
    RcvReadIndex=0;
    XmtWriteIndex=0;
    XmtReadIndex=0;
   
   All_Lights_On();
   All_Lights_Off();
   
    //Make sure Xmit & Rcv RS232 buffers are empty
    RcvReadIndex=RcvWriteIndex;
    XmtReadIndex=XmtWriteIndex;
   
    enable_interrupts(INT_RDA);      // Enable Receive interrupt

   
    enable_interrupts(GLOBAL);   
   
    //Don't enable transmit buffer interrupt until data available in buffer
    disable_interrupts(INT_TBE);
   
    return;
}

void main()
{
   setup();

   for(;;)
   {
      if(RcvDataAvailable)
      {
         if (bResponseTimeout == TRUE)
         {
            while (RcvDataAvailable)
            {
               // Read Command from buffer
               command = *(char*)(RcvComPortBuffer+RcvReadIndex++);
            }
         }
         else
         {
           // Read Command from buffer
           command = *(char*)(RcvComPortBuffer+RcvReadIndex++);
         
           // Check for modulo of index
           if (RcvReadIndex == MAX_NUM_RCV_CHARS)
           {
               RcvReadIndex = 0;
           }
           
           if (command == '#')
           {
               QueryCommand();
           }
           else if (command == '!')
           {
               UpdateCommand();
           }
               
         }
      }
   }

}

void QueryCommand(void)
{
   ResetSendUpdateCounter();
   ResetRcvUpdateCounter();
   ResetSendQueryCounter();
   ResetRcvQueryCounter();
   CRC = 0;
   CalculateCRC(Stations1_4);
   CalculateCRC(Stations5_8);
   CalculateCRC(Stations9_11);
   CalculateCRC(Stations12_14);
   send_byte('#');
   send_byte(Stations1_4);
   send_byte(Stations5_8);
   send_byte(Stations9_11);
   send_byte(Stations12_14);
   send_byte(CRC);
   enable_interrupts(INT_TBE);

}

void UpdateCommand(void)
{
   //Read received values to compare to actual values
   Stations1_4 = *(char*)(RcvComPortBuffer+RcvReadIndex++);
   // Check for modulo of index
  if (RcvReadIndex == MAX_NUM_RCV_CHARS)
  {
      RcvReadIndex = 0;
  }
   Stations5_8 = *(char*)(RcvComPortBuffer+RcvReadIndex++);
   // Check for modulo of index
  if (RcvReadIndex == MAX_NUM_RCV_CHARS)
  {
      RcvReadIndex = 0;
  }
   Stations9_11 = *(char*)(RcvComPortBuffer+RcvReadIndex++);
   // Check for modulo of index
  if (RcvReadIndex == MAX_NUM_RCV_CHARS)
  {
      RcvReadIndex = 0;
  }
   Stations12_14 = *(char*)(RcvComPortBuffer+RcvReadIndex++);
   // Check for modulo of index
  if (RcvReadIndex == MAX_NUM_RCV_CHARS)
  {
      RcvReadIndex = 0;
  }
   RcvdCRC = *(char*)(RcvComPortBuffer+RcvReadIndex++);
   // Check for modulo of index
  if (RcvReadIndex == MAX_NUM_RCV_CHARS)
  {
      RcvReadIndex = 0;
  }
 
  //Calculate what received CRC should be with received data
   //to check for corruption of data
   CRC = 0;
   CalculateCRC(Stations1_4);
   CalculateCRC(Stations5_8);
   CalculateCRC(Stations9_11);
   CalculateCRC(Stations12_14);
   //if received CRC does not match with received data
   if (RcvdCRC != CRC)
   {
      //Parse through received data again to search for starting character
      //to attempt to get back in sync
      RcvBackupCurrentIndex = RcvBackupReadIndex;
      command = *(char*)(RcvBackupComPortBuffer+RcvBackupReadIndex++);
      // Check for modulo of index
     if (RcvBackupReadIndex == MAX_NUM_RCV_CHARS)
     {
         RcvBackupReadIndex = 0;
     }
     
      //while a starting character hasn't been found and we haven't searched
      //through the whole buffer yet
      while ((command != '#')&&(RcvBackupReadIndex != RcvBackupCurrentIndex))
      {
         if (RcvBackupReadIndex == MAX_NUM_RCV_CHARS)
        {
            RcvBackupReadIndex = 0;
        }
        command = *(char*)(RcvBackupComPortBuffer+RcvBackupReadIndex++);
      }
      //if a starting character was successfully found
      if (command == '#')
      {
         //read received values to compare to actual values one more time
         Stations1_4 = *(char*)(RcvBackupComPortBuffer+RcvBackupReadIndex++);
         // Check for modulo of index
        if (RcvBackupReadIndex == MAX_NUM_RCV_CHARS)
        {
            RcvBackupReadIndex = 0;
        }
         Stations5_8 = *(char*)(RcvBackupComPortBuffer+RcvBackupReadIndex++);
         // Check for modulo of index
        if (RcvBackupReadIndex == MAX_NUM_RCV_CHARS)
        {
            RcvBackupReadIndex = 0;
        }
         Stations9_11 = *(char*)(RcvBackupComPortBuffer+RcvBackupReadIndex++);
         // Check for modulo of index
        if (RcvBackupReadIndex == MAX_NUM_RCV_CHARS)
        {
            RcvBackupReadIndex = 0;
        }
         Stations12_14 = *(char*)(RcvBackupComPortBuffer+RcvBackupReadIndex++);
         // Check for modulo of index
        if (RcvBackupReadIndex == MAX_NUM_RCV_CHARS)
        {
            RcvBackupReadIndex = 0;
        }
         RcvdCRC = *(char*)(RcvBackupComPortBuffer+RcvBackupReadIndex++);
         // Check for modulo of index
        if (RcvBackupReadIndex == MAX_NUM_RCV_CHARS)
        {
            RcvBackupReadIndex = 0;
        }
         
         //Calculate what received CRC should be with received data
         //to check for corruption of data
         CRC = 0;
         CalculateCRC(Stations1_4);
         CalculateCRC(Stations5_8);
         CalculateCRC(Stations9_11);
         CalculateCRC(Stations12_14);
         //If CRC is still inaccurate, update sign data
         if (RcvdCRC != CRC)
         {
            ResetSendUpdateCounter();
            ResetRcvUpdateCounter();
            ResetSendQueryCounter();
            ResetRcvQueryCounter();
            send_byte('!');
            send_byte('N');
            send_byte(';');
            enable_interrupts(INT_TBE);
         }
      }
   }
   else
   {
      #ifdef DEV_BOARD
      Stations1_4 = Stations1_4^255;
      Stations5_8 = Stations5_8^255;
      Stations9_11 = Stations9_11^255;
      Stations12_14 = Stations12_14^255;
      #endif
      UpdateLights();
      #ifdef DEV_BOARD
      Stations1_4 = Stations1_4^255;
      Stations5_8 = Stations5_8^255;
      Stations9_11 = Stations9_11^255;
      Stations12_14 = Stations12_14^255;
      #endif
      ResetSendUpdateCounter();
      ResetRcvUpdateCounter();
      ResetSendQueryCounter();
      ResetRcvQueryCounter();
      send_byte('!');
      send_byte('Y');
      send_byte(';');
      enable_interrupts(INT_TBE);
   }
     
}

//-----------------------------------------------------------------------------
// Name: Init_Port_Extenders
//
// Parameters:    None
// Return Value:  None
//
// Initializes the i2c port extenders to all outputs and all ports at 0.
//
//-----------------------------------------------------------------------------
void Init_Port_Extenders(void)
{
                int     address;
                int     i;

    for(i=0;i<8;i++)
    {
        address = BASE_ADD + i*2;           // loop through each 9554A
        address = address & WRITE;          // ensure write bit is 0
        i2c_start();                        // start i2c cycle
        i2c_write(address);                 // device address for WRITE
       
        i2c_write(OUT_ADD);                 // access output port
        i2c_write(0);                       // all ports off       
        i2c_stop();

        i2c_start();       
        i2c_write(address);                 // device address for WRITE       
        i2c_write(CFG_ADD);                 // write to configuration register
        i2c_write(0);                       // all pins are output;
        i2c_stop();                         // stop i2c cycle
    }
}

//-----------------------------------------------------------------------------
// Name: SendPortData(int address,  int data)
//
// Parameters:    address     The device address
//                data        The data to write
// Return Value:  None
//
// This function sends the output data to the port.                         
// Address is between 0 and 0xFF.                             
// Data is from 0 to 7.
//
//-----------------------------------------------------------------------------
void SendPortData(int address,  int data)
{
   
    i2c_start();                        // start i2c cycle
    i2c_write(address);                 // device address for WRITE
       
    i2c_write(OUT_ADD);                 // access output port
    i2c_write(data);                    // turn on/off proper bits
   
    i2c_stop();

}

void UpdateLights(void)
{   
   int     i,address;
   
   for(i=0;i<4;i++)
   {
      address = BASE_ADD + i*2;           // loop through each 9554A
      address = address & WRITE;          // ensure write bit is 0
      switch (i)
      {
         case 0:
         SendPortData(address,Stations1_4);
         break;
         
         case 1:
         SendPortData(address,Stations5_8);
         break;
         
         case 2:
         SendPortData(address,Stations9_11);
         break;
         
         case 3:
         SendPortData(address,Stations12_14);
         break;
      }
   }
}

//=====================================================================
// Name:         CalculateCRC
// Description   Calculate the CRC to send with the data
// Inputs:       None
// Outputs:      None
// Return:       None           
// Interaction: 
// ====================================================================
void CalculateCRC(int data)
{
     int i = (data ^ CRC) & 0xFF;
   
     if(i & 1)
     {
       CRC ^= 0x5E;
     }
     if(i & 2)
     {
       CRC ^= 0xBC;
     }
     if(i & 4)
     {
       CRC ^= 0x61;
     }
     if(i & 8)
     {
       CRC ^= 0xC2;
     }
     if(i & 0x10)
     {
       CRC ^= 0x9D;
     }
     if(i & 0x20)
     {
       CRC ^= 0x23;
     }
     if(i & 0x40)
     {
       CRC ^= 0x46;
     }
     if(i & 0x80)
     {
       CRC ^= 0x8C;
     }
}

// ====================================================================
// Name:        GetCompileDate()
// Description: Used to retrieve the compile date of the executable
//             
// Inputs:      None
//                 
// Outputs:       None
//                 
// Return:      The Compile Data in a string
//           
// Interaction: None
// ====================================================================
//
char* GetCompileDateTime(void)
{
   char* strDateTime = &(TempBuffer[0]);
   strcpy(strDateTime,strCompileDate);
   strcpy(strDateTime+strlen(strDateTime),",");
   strcpy(strDateTime+strlen(strDateTime),strCompileTime);
   return strDateTime;
}

//=====================================================================
// Name:         WriteStringToXmitter
// Description   Parse through a string, adding each bit to the Xmt Buffer
// Inputs:       None
// Outputs:      None
// Return:       None           
// Interaction: 
// ====================================================================
void WriteStringToXmitter(char* strChars)
{
    int length = strlen(strChars);
   
    int i=0;
    for (i=0;i<length;i++)
    {
        send_byte(strChars[i]);
    }

    return;
}

//============================================================================
// Name:        send_byte(byte)
// Description  adds bytes to Xmt Buffer
// Inputs:      Byte to send
// Outputs:     None
// Return:      None
// Interaction: Enables transmit buffer interrupt
// ===========================================================================
void send_byte(txbyte)
{   
   unsigned int WorkingXmtWriteIndex=XmtWriteIndex;
   
    // Check for modulo of index
    if (++WorkingXmtWriteIndex == MAX_NUM_XMT_CHARS)
    {
        WorkingXmtWriteIndex = 0;
    }   

    // Check for Buffer full. If full, dont write char.
    if (WorkingXmtWriteIndex != XmtWriteIndex)
    {
        // Write Response to Buffer
        *(char*)(XmtComPortBuffer+XmtWriteIndex) = txbyte;
        // Set it to new location
        XmtWriteIndex=WorkingXmtWriteIndex;
    }
   
   return;
}

//-----------------------------------------------------------------------------
// Name: All_Lights_Off
//
// Parameters:    None
// Return Value:  None
//
// This function turns off all port bits.
//
//-----------------------------------------------------------------------------
void All_Lights_Off(void)
{
    int     address;
   int     i;

    for(i=0;i<4;i++)
    {
        address = BASE_ADD + i*2;           // loop through each 9554A
        address = address & WRITE;          // ensure write bit is 0
        SendPortData(address, LIGHTS_OFF);                 // device address for WRITE
       
    }   

}

//-----------------------------------------------------------------------------
// Name: All_Lights_On
//
// Parameters:    None
// Return Value:  None
//
// This function turns on all port bits.
//
//-----------------------------------------------------------------------------
void All_Lights_On(void)
{
   int     address;
   int     i;

    for(i=0;i<4;i++)
    {
        address = BASE_ADD + i*2;           // loop through each 9554A
        address = address & WRITE;          // ensure write bit is 0
        SendPortData(address, LIGHTS_ON);                 // device address for WRITE
       
    }   

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 14, 2012 11:45 am     Reply with quote

The first two things I would do to diagnose this problem are:

1. Disable the WDT (use the NOWDT fuse).

2. Remove these two lines:
#FUSES DEBUG
#device ICD=TRUE
wiseacre



Joined: 14 Jun 2012
Posts: 9

View user's profile Send private message

PostPosted: Thu Jun 14, 2012 1:04 pm     Reply with quote

Tried these and am still having the same problem.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 14, 2012 1:17 pm     Reply with quote

Remove NOBROWNOUT and add the BROWNOUT fuse.

What's your PIC's Vdd voltage ?

What's your programmer ?

And your compiler version ?
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu Jun 14, 2012 1:33 pm     Reply with quote

** what cha got on your MCLR pin ??

for sure is there no way is that pin getting a "program level" voltage applied during runtime ??
wiseacre



Joined: 14 Jun 2012
Posts: 9

View user's profile Send private message

PostPosted: Thu Jun 14, 2012 2:38 pm     Reply with quote

Used BROWNOUT fuse and still not working.

PIC Vdd voltage is 5.0V.

Programmer is CCSLoad using both ICD-U40 and ICD-U64.

CCSLoad software version: 4.037
firmware version: 2.93

no way the pin is getting program level voltage.
Ttelmah



Joined: 11 Mar 2010
Posts: 19447

View user's profile Send private message

PostPosted: Thu Jun 14, 2012 2:47 pm     Reply with quote

Other classic things are ground/power connections not properly made. Chip gets power from the ICD/programmer, but not when these are disconnected.

Best Wishes
wiseacre



Joined: 14 Jun 2012
Posts: 9

View user's profile Send private message

PostPosted: Thu Jun 14, 2012 2:49 pm     Reply with quote

Everything is connected properly. It works just fine with any other program, just not the one posted here.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 14, 2012 2:54 pm     Reply with quote

Also, you still didn't give your compiler version. It's at the top of the .LST
file, in your project directory. Example of version numbers:
http://www.ccsinfo.com/devices.php?page=versioninfo
wiseacre



Joined: 14 Jun 2012
Posts: 9

View user's profile Send private message

PostPosted: Thu Jun 14, 2012 2:59 pm     Reply with quote

Oops, my apologies. I copied it, just must've forgotten to paste it.

CCS PCH C Compiler, Version 4.132, xxxxx 14-Jun-12 15:40
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 14, 2012 3:07 pm     Reply with quote

Well, that version should be OK.

Hardware:
Did you design and build this board ? I mean the circuits and the PCB
board layout. Or did you buy it ?
If I had this problem, I would change out everything: The PIC, the board,
the programmer. If it's on a custom board, I would move it to a generic
Pic eval board, if possible. (Such as a 4-layer PicDem2-Plus, etc).

Software:
I would re-install the compiler.
I would strip down the program, removing most of the code, and see if
the problem still occurs. I would add short printf statements within
the program to identify where it's locking up.

This is actually done from a distance. I'm making all these statements
without having analyzed your posted code in detail.
Ttelmah



Joined: 11 Mar 2010
Posts: 19447

View user's profile Send private message

PostPosted: Fri Jun 15, 2012 1:30 am     Reply with quote

The code is too long for anybody to look through, especially since we don't 'know' what the external connections actually do.
However there are a couple of dangerous things:

Move the clock fuses, settings, and RS232 declarations _above_ all the includes. Anything that uses timings or RS232, _must_ have these loaded first. The 'safe' layout is:

1) Processor include
2) Fuses
3) Clock settings, RS232, I2C etc.
4) Now the global defines
5) Includes

Some parts can be swapped (the global defines can be after the includes, if the includes don't use any of them, but this is the 'reliable' layout.

You say other code works. Does the other code use the MCLR pin?. One obvious thing would be that this is pulled up by the ICD/programmer, and if there is no pull up on it on the board, then this code has 'MCLR' selected, and would not run...

The RS232 receive code has the classic "I'm going to bu&&er everything else up" design, sitting and effectively locking the processor from doing anything else, until the entire string is received. _Study how to buffer the RS232 and use this interrupt_. The interrupt says 'one character is waiting', and if you want other things to happen, the code in the ISR should just receive one character. If the RS232 line isn't properly connected this will hang the chip completely.
Move all the variable declarations to the start of function blocks. CCS won't complain, and will sometimes let them work, but the results _are unreliable_. Stick to conventional C declarations. Much safer. Also, CCS does not correctly allow values to be initialised with returns from functions at declare time.
If you perform an allocate and declare together:

int8 val=getc();

and do nothing else with 'val', you will get the compiler warning 'variable never used val', yet if instead you perform the declare and the call separately, no such warning, telling you that the compiler is not correctly handling the combined operation. This was a documented limitation of the old compiler, which in recent versions is meant to have been allowed, but still does _not_ work reliably. If you want your code to work, stick to declaring separately....

Best Wishes
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Fri Jun 15, 2012 4:40 am     Reply with quote

Quote:

// Select one of the these settings
//#FUSES NODEBUG
#FUSES DEBUG

#device ICD=TRUE


This will generate debug code. Debug code WILL NOT run standalone.

To solve this you need to do two things:

1. put the NODEBUG fuse setting in with the rest of the fuses. Do NOT change this to DEBUG. That will automatically be handled by the compiler/IDE.

I use this line with a comment to remind me:

#FUSES NODEBUG //No Debug mode for ICD - this is overridden by #device ICD=TRUE

2. Use #device ICD=TRUE for debug builds. Comment it out for standalone, i.e. normal, non-debug builds.

I have two projects for many of my projects: the top level .c file of both includes the main .c, the only difference being one has #device ICD=TRUE so generates a debug version, the other isn't and build normal, i.e. non-debug, code.

If you try and run debug code as standalone code it simply won't run, or at least your code won't. The debug monitor code will run, and sit waiting to talk to a debugger that isn't there.

Note that with IDC=TRUE the wdt and the brownout detection will be disabled (the compiler overrides the fuses for you). There may be other differences, but I can't remember them off hand.

RF Developer
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Fri Jun 15, 2012 7:04 am     Reply with quote

this statement has been bothering me

Quote:

If I try to reprogram the PIC after doing this, the code won't work.


reprogramming should result in a full erasure of the pic - this is the most troubling part of all.

i use an EPIC programmer with a nice code read back feature.

AFTER you get your pic into the failed state
have you tried to do a read back of it and COMPARE the hex file to the source you programmed ??

i'd be especially interested in whether the fuses match .......
AND are what you THINK they are
wiseacre



Joined: 14 Jun 2012
Posts: 9

View user's profile Send private message

PostPosted: Fri Jun 15, 2012 7:58 am     Reply with quote

PCM programmer wrote:
Well, that version should be OK.

Hardware:
Did you design and build this board ? I mean the circuits and the PCB
board layout. Or did you buy it ?
If I had this problem, I would change out everything: The PIC, the board,
the programmer. If it's on a custom board, I would move it to a generic
Pic eval board, if possible. (Such as a 4-layer PicDem2-Plus, etc).

Software:
I would re-install the compiler.
I would strip down the program, removing most of the code, and see if
the problem still occurs. I would add short printf statements within
the program to identify where it's locking up.

This is actually done from a distance. I'm making all these statements
without having analyzed your posted code in detail.


Hardware: I didn't design the board but a coworker did. We don't have a custom eval board with this PIC that I could move it to.

Software: No status change after all of this.


Ttelmah wrote:
The code is too long for anybody to look through, especially since we don't 'know' what the external connections actually do.
However there are a couple of dangerous things:

Move the clock fuses, settings, and RS232 declarations _above_ all the includes. Anything that uses timings or RS232, _must_ have these loaded first. The 'safe' layout is:

1) Processor include
2) Fuses
3) Clock settings, RS232, I2C etc.
4) Now the global defines
5) Includes

Some parts can be swapped (the global defines can be after the includes, if the includes don't use any of them, but this is the 'reliable' layout.

You say other code works. Does the other code use the MCLR pin?. One obvious thing would be that this is pulled up by the ICD/programmer, and if there is no pull up on it on the board, then this code has 'MCLR' selected, and would not run...

The RS232 receive code has the classic "I'm going to bu&&er everything else up" design, sitting and effectively locking the processor from doing anything else, until the entire string is received. _Study how to buffer the RS232 and use this interrupt_. The interrupt says 'one character is waiting', and if you want other things to happen, the code in the ISR should just receive one character. If the RS232 line isn't properly connected this will hang the chip completely.
Move all the variable declarations to the start of function blocks. CCS won't complain, and will sometimes let them work, but the results _are unreliable_. Stick to conventional C declarations. Much safer. Also, CCS does not correctly allow values to be initialised with returns from functions at declare time.
If you perform an allocate and declare together:

int8 val=getc();

and do nothing else with 'val', you will get the compiler warning 'variable never used val', yet if instead you perform the declare and the call separately, no such warning, telling you that the compiler is not correctly handling the combined operation. This was a documented limitation of the old compiler, which in recent versions is meant to have been allowed, but still does _not_ work reliably. If you want your code to work, stick to declaring separately....

Best Wishes


Reorganized everything and still the same problem. Yes, the other code uses the MCLR pin. It does have a pull up on the board.


RF_Developer wrote:
This will generate debug code. Debug code WILL NOT run standalone.

To solve this you need to do two things:

1. put the NODEBUG fuse setting in with the rest of the fuses. Do NOT change this to DEBUG. That will automatically be handled by the compiler/IDE.

I use this line with a comment to remind me:

#FUSES NODEBUG //No Debug mode for ICD - this is overridden by #device ICD=TRUE

2. Use #device ICD=TRUE for debug builds. Comment it out for standalone, i.e. normal, non-debug builds.

I have two projects for many of my projects: the top level .c file of both includes the main .c, the only difference being one has #device ICD=TRUE so generates a debug version, the other isn't and build normal, i.e. non-debug, code.

If you try and run debug code as standalone code it simply won't run, or at least your code won't. The debug monitor code will run, and sit waiting to talk to a debugger that isn't there.

Note that with IDC=TRUE the wdt and the brownout detection will be disabled (the compiler overrides the fuses for you). There may be other differences, but I can't remember them off hand.

RF Developer


I understand that. I have been running it just in debug mode to continue writing the code and had copied the code from that point. When I try and program the chip, I make sure I have the NODEBUG Fuse set. Thanks, though.



asmboy wrote:
this statement has been bothering me

Quote:


If I try to reprogram the PIC after doing this, the code won't work.


reprogramming should result in a full erasure of the pic - this is the most troubling part of all.

i use an EPIC programmer with a nice code read back feature.

AFTER you get your pic into the failed state
have you tried to do a read back of it and COMPARE the hex file to the source you programmed ??

I'd be especially interested in whether the fuses match .......
AND are what you THINK they are


I put the PIC in failed state, read back the hex file, compared it to the hex file I originally programmed the PIC with and they are very different. The failed state hex file includes most of the original hex file, but has a ton added to it as well. Most of it is 'FFFF', but other values are included as well.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group