jtemples wrote:What if you don't enable interrupts during the write?
Well, that is interesting. When I move the INTCON.GIE = 1 down to below the wait for WR, nothing hangs. But why should that be? The datasheet shows enabling interrupts immediately after setting WR. I suppose something in my ISR could touch the EEPROM registers, but my ISR does not seem to do that. I have no references to EEPROM registers in my ISR. Here is my ISR, which processes Tx, Rx, CCP1, and Timer1 overflow interrupts:
- Code: Select all
if(PIR1.RCIF) //..RCREG1 is full. RCIF will be cleared when RCREG is read
{
isrChar = RCREG; //..this clears RCIF
isrHandleRcvdChar();
}
if(TxNextToSend < TxEnd)
{
isrChar = TxBuf[TxNextToSend];
{
PIE1.TXIE = 1; //..in case we got here because of some other interrupt..
if(PIR1.TXIF)
{
TXREG = isrChar;
TxNextToSend++;
}
}
}
else
{
PIE1.TXIE = 0;
}
if(PIR1.CCP1IF) //..input capture event
{
if(mainState.firstCaptureDone == 0)
{
PrevCCPR1 = CCPR1;
mainState.firstCaptureDone = 1;
mainState.lastCaptureDone = 0;
}
else if (mainState.lastCaptureDone == 0)
{
PeriodDelta16 = CCPR1 - PrevCCPR1; //..Every 256 x 16 oscillations.
mainState.lastCaptureDone = 1;
}
PIR1.CCP1IF = 0;
} //..end of CCP capture interrupt..
if(PIR1.TMR1IF)
{
PIR1.TMR1IF = 0;
Timer1OverflowCount++;
} //..end of TMR1 overflow
#asm
RETFIE ;..fast return restores registers
#endasm
Edit update: Here is some new data. Instead of keeping all interrupts off during the entire write to EEPROM, I tried using the PIE1 register to selectively enable interrupts, as follows:
- Code: Select all
void WriteEEdata(unsigned int addr, unsigned int data)
{
int savedPIE;
EEADR = addr;
EEDATA = data;
EECON1.EEPGD = 0;
EECON1.CFGS = 0;
EECON1.WREN = 1;
INTCON.GIE = 0; //..*** Interrupts Disabled ***
savedPIE = PIE1;
PIE1 = 0;
//PIE1.RCIE = 1; //..THIS KILLS IT.
EECON2 = 0x55;
EECON2 = 0xaa;
EECON1.WR = 1; //..begins the write..
INTCON.GIE = 1; //..*** Interrupts Enabled ***
EECON1.WREN = 0;
while( EECON1.WR ) {;} //..wait for write to finish
PIE1 = savedPIE;
}
When I uncomment the PIE1.RCIE = 1, the second call to WriteEEdata hangs as before. And I know what might be causing that RC interrupt. The serial command that kicked off this write to EEPROM was sent from a terminal program that sends both a CR and the LF when I hit Enter. The PIC parses the CR as the command termination and begins the write to EEPROM. But the LF arrives shortly after (at 2400 baud). My ISR is supposed to discard characters that are not part of its protocol, so I don't know why an extra LF arriving should cause any problem to the WriteEEdata.