November 16 2004
Much work is being done on my PIC Projects. Check the latest in the main news section.April 27 2004
After struggling with Salvo, RTL8019AS, PIC18F6680, Hitech PICC18 and a new board, for the last month, I can tell you that I need a break.However, (as you all know) there is no rest for the weary. So, Here is the detailed news. First of all, I tried reading the NIC registers from the interrupt routine. This turned out to be a major problem. So this is a no-no:
// // High Priority vector // #pragma interrupt_level 0 void interrupt HighISR(void) { BYTE s; // // The NIC gets the highest priority. // This could get to be a VERY busy handler. // We MUST keep latency to a minimum. if( (INT0IE) && (INT0IF) ) { s=NICGetP(ISR); // We need to save the ISR value NICPutP(ISR, s); // Whatever the reason was, we reset the interrupt // Now, reset the PIC Interrupt flag. // The earlyest we do this, the better. INT0IF=0; OSSignalMsgQ(MSG_GOT_PAK_MAC, (OStypeMsgP) 1); } }This was a nightmare. I was getting consistent bad data from the NIC and everything was messed up. I tried to fix it in many different ways but nothing worked. As per Andrew Kalman's suggestion (the man who wrote Salvo), I tried this:
// // High Priority vector // #pragma interrupt_level 1 void interrupt HighISR(void) { // // The NIC gets the highest priority. // This could get to be a VERY busy handler. // We MUST keep latency to a minimum. if( (INT0IE) && (INT0IF) ) { highISRactivity=TRUE; // Now, reset the PIC Interrupt flag. // The earlyest we do this, the better. INT0IF=0; } }When, the main code takes over it does:
113 // 114 // Start the multitasking loop 115 // 116 for(;;) { 117 if( highISRactivity || RB0 ) { // RB0 High indicates a NIC pending interrupt 118 if( highISRactivity ) { 119 GIEH=0; // Disable interrupts 120 highISRactivity=FALSE; // Reset FLAG 121 GIEH=1; // Enable interrupts 122 } 123 s=NICGet(ISR); // We need to save the ISR value 124 NICPut(ISR, s); // Whatever the reason was, we reset the interrupt 125 if( s & 0x1f ) { // RDC, OVW, TXE, RXE, PTX, PRX 126 // 127 // It is important that we check for errors first. The last thing we want 128 // is to send a bad packet through the state machine 129 if( s & 0x1c ) { 130 MACPacketRXBuf[MACPacketIX]=s; // Save the ISR value to the MAC_ISR qu 131 // Let's send the error to the appropriate routine 132 OSProtect(); 133 OSSignalMsgQ(MSG_GOT_MACERR, (OStypeMsgP) &MACPacketRXBuf[MACPacketIX]); 134 OSUnprotect(); 135 if( ++MACPacketIX > MAX_PRX_BUFZ ) { 136 MACPacketIX=0; 137 } 138 } 139 else { 140 if( (s & 0x02) ) { // bit 2 is packet transmited with no error 141 ISR_TX_Done=1; 142 } 143 if( (s & 0x01) ) { // bit 1 is packet received with no errors 144 LED2_blink; 145 OSProtect(); // Time Start 146 OSSignalMsgQ(MSG_GOT_PAK_MAC, (OStypeMsgP) 1); 147 OSUnprotect(); // Time Stop 15us 148 } 149 } 150 } 151 } 152 OSSched(); 153 }This is what it's all about. One month of hardcore programming, debugging and no sleep. Now, I am planning to send Andrew a thank you note, since he gave me a heads up on doing the NIC I/O in the main loop.
One very useful piece of equipment is a Time Interval Analyzer. I use it for timing code segments. I have an HP5370A and a HP5370B and they are both great for this sort of thing.
In order for this to work, I use I/O pins RA5 and RA6. To time a piece of code do:
RA6=0;RA5=0; RA5=1; RA5=0; mycode; RA6=1; RA6=0;I put the start channel on RA5 and the stop channel on RA6. The TI Analyzer will read out the time interval. This is great for checking if your code is doing what it's supposed to do. It is also very simple since you don't have to count cycles. Well worth the price!