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

USART 2 interrupt service not working on 18f8722

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
NEUTRONJOHN
Guest







USART 2 interrupt service not working on 18f8722
PostPosted: Thu Sep 24, 2009 1:23 am     Reply with quote

I am having trouble getting an interrupt to fire on USART2 with a 9th bit protocol....similar code works fine in other applications.
I can see Transmit_STB() working after detection of the INT0IF, the other controller I am talking to answers...but I never see an interrupt generated, PIN_D4 or D5 never goes high. Once into the routine it would validate the 1st address byte is correct, etc. , and accept the rest of the response, but it never gets there.

I have played with using SFRs directly and setting the Baud rate directly...but no joy.

I apologize for the LONG code segment...any help is appreciated: PCWH version is 4.092.
Code:

#use delay(clock=40M, oscillator=10M)
#use rs232(UART1,baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS,STREAM=HOST)
#use rs232(UART2,baud=115200,parity=N,xmit=PIN_G1,rcv=PIN_G2,bits=9,ERRORS,STREAM=STB)


#include <Telem_TEST1.h>
#include <Telem_TEST_vars.h>

// SubRoutine Templates
void SPI_Service(void);
void Transmit_STB(void);
void Receive_STB(void);
void Save_STB(void);
void Xmit_ULink(void);
void InitQ(void);



#int_RDA
void  RDA_isr(void)
{
// handler for input commands from the Host PC would go here...
}


//**************************************************************************
// STB Serial ISR
//
//  Receive Interrupt - when address bit is set                       
//    in 1st xmission matches the BoardAddress                       
//**************************************************************************

#int_RDA2
void  RDA2_isr(void)
{
int CS;

output_high(PIN_D4);        // SET WHEN WE GET A SERIAL INTERRUPT
NewPacket = 0;
SerialError = 0;
ReceivedAddress = RCREG2;      //get byte from receive buffer, CHECK FOR ALL LEGAL ADDRESSES
if ( ReceivedAddress == 30 )
   {
   output_high(PIN_D5);     // for debug!!!! Set while wating for next byte
   NewPacket = 1;       //set flag for new packet is coming
   ADDEN2 = 0;           //allow receiver to get the rest of the packet
   output_low(PIN_D5);
   Buff[0] = ReceivedAddress;  //shove address into 1st slot...
//Receive packet size High Byte
   Tout = RecvTimeout;
   while(RC2IF == 0)        //wait for next byte in receiver
     {
     Tout--;
     output_high(PIN_D5);     // for debug!!!!Set while wating for next byte
     if(Tout == 0)
         {
         SerialError = 130;           //Timeout error
         goto ErrorTest;
         }
     }
   output_low(PIN_D5);              // for debug!!!! 2nd byte arrived
   Buff[1] = RCREG2;                  //get size byte from serial port
// Receive packet size Low byte   
   Tout = RecvTimeout;
   while(RC2IF == 0)                    //wait for next byte in receiver
     {
     Tout--;
     output_high(PIN_D5);     // for debug!!!!Set while wating for next byte
     if(Tout == 0)
         {
         SerialError = 130;           //Timeout error
         goto ErrorTest;
         }
     }
   output_low(PIN_D5);     // for debug!!!!last size byte arrived
   Buff[2] = RCREG2;                    //get byte from serial port
   RecvPacketSize = Buff[2];       //add size and checksum to packet size
// --- receive packet
   RecvPointer = 3;       //position pointer at first byte
// receive rest of packet past the packet size bytes.....   
   while(RecvPointer < (RecvPacketSize+1))
     {
     Tout = RecvTimeout;
     while(RC2IF == 0)
       {
       Tout--;
       output_high(PIN_D5);     // for debug!!!!Set while wating for next byte
       if(Tout == 0)
          {
          SerialError = 130;            //Timeout error = 0x82
          goto ErrorTest;
          }
       }
     output_low(PIN_D5);            // for debug!!!! next byte here
     Buff[RecvPointer] = RCREG2;     //save packet data in buffer array
     RecvPointer++;
     }// end of while RCVpointer <= RecvPacetsize
     CS = 0;
     RecvPointer = 1;
     while(RecvPointer < Buff[2])
      {
      CS = CS + Buff[RecvPointer];
      RecvPointer++;
      }
   CS = ~(CS) + 1;       //CheckSum is now 2's complement     
   RecvPacketSize = Buff[2];
   if (CS != Buff[RecvPacketSize])
      {
      SerialError = 129;                  //checksum error = 0x81
      }
   }// End of IF Rc'd addr = Board Address

ErrorTest:
ADDEN2 = 1;                    //enable interrupt when address bit is set
output_low(PIN_D4);        // clr when doen with ISR
}// end of RDA2 ISR


void main()
{
   
   setup_adc_ports(AN0_TO_AN5|VREF_VREF);
   setup_adc(ADC_CLOCK_INTERNAL|ADC_TAD_MUL_20);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_spi2(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   //setup_timer_0(RTCC_OFF );
   setup_timer_0(RTCC_INTERNAL);   
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED, 0,1);
   setup_timer_3(T3_DISABLED);
   setup_timer_4(T4_DISABLED, 0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_low_volt_detect(FALSE);


// Ninth bit protocol set-up USART2
   
   SYNC2 = 0;                        //Select Async mode USART2
   SPEN2 = 1;                        //Enable Serial port USART2
   BRGH2 = 1;                        //Set for High Baud rate 
   BRG16_2 = 1;
   SPBRG2 = 86;                      // Set up BAUD rate = 115.2, actual - 114.943 kB 
   SPBRGH2 = 0;                      // high byte set to zero
   CREN2 = 1;                        //Rx Enable   
   TX9D2 = 0;                        //9th bit of transmitted data is always low
   TX92 = 1;                         //Enable 9-bit transmits
   RX92 = 1;                         //Enable 9-bit receives
   ADDEN2 = 1;                       //enables interrupt when address bit is set   
   RC2IE = 1;                        //Rx USART2 interrupt Enable
   CB = RCREG2;                      //3x read to clear out RX Reg and 2 byte FIFO 
   CB = RCREG2;
   CB = RCREG2;



   set_tris_a(0xFF);    // all inputs
   set_tris_b(0xFF);    // all inputs
   set_tris_c(0x80);    //Set up for UART1 = HOST_PC on C7(Rx)Input and C6 (TX) and all others are outputs
   set_tris_d(0);       //All outputs to drive diodes and diagnostics
   set_tris_e(0xFF);    // all inputs
   set_tris_f(0xFF);    // all inputs
   set_tris_g(0xFE);    // all inputs except TX2
   set_tris_h(0xFF);    // all inputs
   set_tris_j(0);       // all Outputs, for later development
 

//   setup_uart(115200, HOST_PC);
//   setup_uart(115200, STB);
//Setup_Oscillator parameter not selected from Intr Oscillator Config tab
// Crive pin D0 high to turn on diode D1   
   output_high(PIN_D0);       //Turn on D1 to signify we made it this far!!!
   output_high(PIN_D1);
   output_high(PIN_D2);
   output_high(PIN_D3); 
   output_high(PIN_D4);
   output_high(PIN_D5);
   output_high(PIN_D6);
   output_high(PIN_D7);
   delay_ms(100);
   output_low(PIN_D1);   
   output_low(PIN_D2);   
   output_low(PIN_D3);   
   output_low(PIN_D4);
   output_low(PIN_D5);
   output_low(PIN_D6); 
   output_low(PIN_D7);   
   Timer0_Clk = 0;
   BankSwapTimer = 0;

// Interrupt Set-up   
   //enable_interrupts(INT_RDA);;
   clear_interrupt(INT_RDA2);   
   enable_interrupts(INT_RDA2);
   //enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);
   Checksum = 0;
//   setup_wdt(WDT_ON);        // Set up WDT for 512 x 4 msec - or 2.048 sec
//   restart_wdt();
// Q set-up
   maxQ = 1000;
   InitQ();                         //Reset circular buffer   

//******************************************************************************
//  Main Loop
//******************************************************************************
   while (1)
   {
//   restart_wdt();
   output_toggle(PIN_D7);           //loop monitor

//When a packet is received on the tool bus, NewPacket is set.
//Process received packet and reply.
  if(SWAP)                      // respond to 1 seconds bank swap INT0
      {
      output_high(PIN_D6);
      SWAP = 0;                      // Clear INT flag
      delay_us(25);
      output_low(PIN_D6);
//add rest of code here...
     
  /****** Get NEAR DATA **********************************************/
//      if(SPI_BYTE) SPI_Service();
      T_Buff[0] = 30;                     //address for SHORT SPACE
      T_Buff[1] = 0;                      //hi byte of packet size
      T_Buff[2] = 5;                      //low byte of packet size
      T_Buff[3] = 20;                     //send counts
      T_Buff[4] = 133;                    //send 133 gates
      Transmit_STB();                     //transmit packet over tool bus
//      if(SPI_BYTE) SPI_Service();
      ExpectedSize = 272;                 //= address echo (byte) + byte cound
                                          // (word) + cmd echo (byte) + 266 data
                                          // (bytes) + temp (byte) + status
                                          // (byte) + checksum (byte) - 1
      SerialError = 0;
      //delay_us(250);
      //Receive_STB();                      //receive STB packet assume done by ISR???
      BusStatus_A = SerialError;
      //Save_STB();                         //write packet to FIFO buffer
                                          //After all STB transactions and Buffer
                                          // saves are done...Xmit FIFO Up   
      //Xmit_ULink();                       //Xmit the contents of the Data Q
      //enable_interrupts(INT_EXT);
      }//end of SWAP Detect
   if (NewPacket)
      {
      Save_STB();
      }
       
  // 1x per second do diagnostic xmit, TMRO disabled for now   
   if (Timer0_Clk >= 100)   
      {// check for one second to elapse
      Timer0_Clk = 0;               //clear 1 second timer for next time...
      //fputs( "| HI !|",HOST);
      output_toggle(PIN_D0);       //Toggle the D0 D1 pin pattern
      rs232_errors = 0;            // clear errors just to clear warning...
      }
  //  delay_us(25);                // Add arbitrarry delay to slow down the main loop to better simulate a tool controller 
   }//end of MAIN LOOP
   
}// Program end

/********************************************************************
*  Transmit STB Packet                                              *
********************************************************************/
void Transmit_STB(void)
   {
   CREN2 = 0;                        //turn off receiver   
   T = RCREG2;                         //RCREG buffer is 2 deep, 1x
   T = RCREG2;                         //2x
   T = RCREG2;                         //and once more with feeling....   
   output_high(PIN_D6);
   PacketSize = make16(T_Buff[1],T_Buff[2]);
   Checksum = 0;
   for(RecvPointer = 1; RecvPointer < PacketSize; RecvPointer++)
      {
      Checksum = Checksum + T_Buff[RecvPointer];
      }
   T_Buff[PacketSize] = ~Checksum + 1;
//restart_wdt();
   TX9D2 = 1;                        //set address bit
   TXREG2 = T_Buff[0];               //send address
   while(!TRMT2);                     //wait till transmitter buffer is empty
   TX9D2 = 0;                        //clear address bit for data

   for(RecvPointer = 1; RecvPointer <= PacketSize; RecvPointer++)
      {
      TXREG2 = T_Buff[RecvPointer];  //move byte to transmit buffer
      while(!TRMT2);                  //wait till transmitter buffer is empty
      }
   CREN2 = 1;                          //enable receiver         
   output_low(PIN_D6);   
   }//end of Transmit_STB


[color=green][/color]


ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Sep 24, 2009 5:23 am     Reply with quote

Your post is large and I don't really understand your problem, but here are a few thoughts:

1) Are you sure your processor is running at 40MHz?
The code is incomplete (missing #fuses) and there is the suspicious line:
Code:
//Setup_Oscillator parameter not selected from Intr Oscillator Config tab


2) You are manually configuring the outputs using set_tris(). Be aware that by default the CCS compiler will manage the TRIS registers for you unless you define '#use fast_io'.

3)
Code:
   set_tris_g(0xFE);    // all inputs except TX2
TX2 is at pin G1, you have made G0 an output. (0xFE == 0b1111 1110)
Tip: use binary notation instead of hex:
Code:
   set_tris_g(0b11111101);    // all inputs except TX2


4) You are configuring UART2 by manually setting all register bits. You haven't posted the register declarations so we can't check, but I'm too lazy anyway. I like the CCS configuration much better. Have you tried comparing the generated code (*.lst) with your bit settings?
NeutronJohn
Guest







PostPosted: Thu Sep 24, 2009 2:46 pm     Reply with quote

Thanks for the reply.
I tried your suggestions about #use fast_io and TRIS...but had no effect.

I found my principle ISR issue was I was counting on the 9th bit to be set on the slave response. which it never is...when I clear the ADDEN2, to not expect a 9th bit set...I start getting ISRs firing...so that's one problem down

Some terms:

master = 18F8772 code I am having trouble with receiving responses in now...

Slave: same 18F8772 processor with a "slave" programmed in that DOES use the 9-bit address detect mode...has been working for many months across several PIC processors.

NOW - here's the problem that I've had all along (which you may be on to something with) I check to see if the slave response address = the address the master calls, matches...and I am never getting a match, even though I know the slave code works....
I had this routine set up initially as "in-line" code just using the RC2IF to see when the RCREG2 had a character to grab...it grabs the 1st character, but never sees a match...so in (sort of) desperation, after trying manual baud rate set-ups...I thought I'd try an ISR...well I've basically got the same problem.

So...maybe I do have a processor speed issue or baud rate set-up issue.
Not sure how far off is since I have been seeing the delay_us and other delays I use to create pulses are "close" to correct length, just have not tried to time them exactly.

I'm gonna try to send out a toggle and see how accurate they are...I've had folks tell me NEVER count on them being accurate as they are susceptible to ISRs changing their lengths,and other pitfalls, etc. so I'm gonna just use a tight main loop and a toggle...

Any other ideas welcome...this "simple" problem has cost me some DAYS now that I don't have to lose...I have project WAY overdue because of this stupidity.

Thanks again...
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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