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 CCS Technical Support

Fault Int_rda interrupt when save data into Rom - Pic18F8723

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



Joined: 07 Mar 2019
Posts: 3

View user's profile Send private message

Fault Int_rda interrupt when save data into Rom - Pic18F8723
PostPosted: Thu Mar 07, 2019 1:35 am     Reply with quote

Hi,
I am using rs232 communication between a pic18f8723 on master circuit and 16 pic16F886 on slave circuit through a mux16 using pic18F8723.
(master-mux16-16slave). The problem is when i save data into master rom, the uart port will stop working. The master pic could transfer data to slave pic and hmi but could not receive data from slave and hmi.
Please help.

Here is my source code on master:
Code:

#include <Master.h>
#include <Math.h>
#include "Global.c"
#include "Function.c"
#include "StateMachine.c"
#include "ProcessRx.c"

#INT_TIMER1
void  TIMER1_isr(void)
{
   set_timer1(TIMER1_REG);
   if(SERVO_ON) {     
      if(MAIN_STATE > 0) {
         if(PUL_COUNT < PUL_VALUE[MAIN_STATE]) {
            PUL_COUNT++;
         } else {
            MAIN_STATE++;
            PUL_COUNT = 0;
         }
         if(MAIN_STATE > STATE_DAC1)  {
            SERVO_ON = 0;
         }
      }   
      output_toggle(DRV_PUL);
   } else output_high(DRV_PUL);
}

#INT_TIMER2
void  TIMER2_isr(void)
{
   if(HMI_NOREP_REG == HMI_NO_REP) HMI_NOREP_FLAG = 1; else HMI_NOREP_REG++;
   if(HMI_FRE_REG   == HMI_UPDATE) HMI_FRE_FLAG = 1;   else HMI_FRE_REG++;
   if(STOPTIME_REG > 0) STOPTIME_REG --; else DELAY_FLAG = 1;
   if(CONNECTION_REG > 0) CONNECTION_REG--;
   if(BUZZER_REG == 0) BUZZER_REG = 2000; else BUZZER_REG--;
   if(DELAY_TIME == 0) {
      if(AUTOMATIC_RUN) CTL_SEC++;
      if(CTL_SEC >= 60) {
         CTL_SEC = 0; CTL_MIN++;
         if(CTL_MIN >= 60) {CTL_MIN = 0; CTL_HOUR++;}
      }
      if(TIME_STATE_REG > 0 ) TIME_STATE_REG--; else TIME_STA = 1;
      DELAY_TIME = 999;
   } else DELAY_TIME--;
   
   shift_left(&IN_START_REG,1,input(IN_START));
   shift_left(&IN_SENSOR_REG,1,input(IN_PRSEN));
   shift_left(&IN_CONTACT_REG,1,input(IN_CONTA));
   if(IN_SENSOR_REG == 0) SENSOR_ENA = 1;
   else if(IN_SENSOR_REG == 0xFF && SENSOR_ENA) SENSOR_EDGE = 1;   
   if(IN_CONTACT_REG == 0xF0) SENSOR_FAIL = 1;
   if(IN_SENSOR_REG == 0xF0 || IN_SENSOR_REG == 0x0F) SENSOR_FAIL = 0;
   if(MUX_TIMEOUT_REG > 0) MUX_TIMEOUT_REG--; else MUX_TIMEOUT_FLAG = 1;
   if(WDRX_REG > 0 ) {
      if(WDRX_REG == 1) {
         RX_COUNTER = 0;
         Rx_fifo_wr = 0;
         Rx_fifo_rd = 0;
         WDRX_REG = 0;
      } else WDRX_REG--;
   }
   if(WDRX2_REG > 0 ) {
      if(WDRX2_REG == 1) {
         RX2_COUNTER = 0;
         Rx2_fifo_wr = 0;
         Rx2_fifo_rd = 0;
         WDRX2_REG = 0;
      } else WDRX2_REG--;
   }
}

#INT_RDA
void  RDA_isr(void)
{
   RX_FIFO[Rx_fifo_wr] = getc(PORT1);
   if(Rx_fifo_wr < RX_FIFO_SIZE - 1) Rx_fifo_wr ++; else Rx_fifo_wr = 0;
}

#INT_TBE
void  TBE_isr(void)
{
   if (Tx_fifo_rd != Tx_fifo_wr) {
      putc(TX_FIFO[Tx_fifo_rd],PORT1);
      Tx_fifo_rd++;
   } else disable_interrupts(INT_TBE);
}

#INT_RDA2
void  RDA2_isr(void)
{
   RX2_FIFO[Rx2_fifo_wr] = getc(PORT2);
   if(Rx2_fifo_wr < RX2_FIFO_SIZE - 1) Rx2_fifo_wr ++; else Rx2_fifo_wr = 0;
}

#INT_TBE2
void  TBE2_isr(void)
{
   if (Tx2_fifo_rd != Tx2_fifo_wr) {
      putc(TX2_FIFO[Tx2_fifo_rd],PORT2);
      Tx2_fifo_rd++;
   } else disable_interrupts(INT_TBE2);
}

void main()
{
   setup_adc_ports(AN0,VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_2|ADC_TAD_MUL_0);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);      //6.5 ms overflow
   setup_timer_2(T2_DIV_BY_4,249,10);      //100 us overflow, 1.0 ms interrupt

   delay_ms(1000);
   init_param();
   init_HMI();
   enable_interrupts(INT_TIMER1);
   enable_interrupts(INT_TIMER2);
   enable_interrupts(INT_RDA);
   clear_interrupt(INT_TBE);
   enable_interrupts(INT_RDA2);
   clear_interrupt(INT_TBE2);
   enable_interrupts(GLOBAL);

   while(TRUE)
   {
      //TODO: User Code
     
      check_status();
      Main_StateMachine();
      if(IN_SENSOR_REG == 0) bit_set(HAND_CTL_ACT,1); else bit_clear(HAND_CTL_ACT,1);
      if(IN_CONTACT_REG == 0) bit_set(HAND_CTL_ACT,2); else bit_clear(HAND_CTL_ACT,2);
      if(MUX_TIMEOUT_FLAG) Process_Mux();
      Process_Rx();
      Process_Rx2();
      output_drv();
      if(HMI_FRE_FLAG && !HMI_NOREP_FLAG) Reply_HMI();
      if(PWR_ON) PowerOn_act();
   }
}

Here is source on slave:
Code:

#include <Slave.h>
#include <Math.h>
#include "Global.c"
#include "Function.c"

#INT_RDA
void  RDA_isr(void)
{
   RX_FIFO[Rx_fifo_wr] = getc();
   if(Rx_fifo_wr < RX_FIFO_SIZE - 1) Rx_fifo_wr ++; else Rx_fifo_wr = 0;
}

#INT_TIMER2
void  TIMER2_isr(void)
{
   if(WD_TIMER_REG == 1) {
      WD_TIMER_REG = 0;     
      Rx_fifo_rd = 0;
      Rx_fifo_wr = 0;
      RX_COUNTER = 0;
      DATA_FIFO[0] = 0;
      DATA_FIFO[1] = 0;
   } else {
      if(WD_TIMER_REG > 0) WD_TIMER_REG--;
   }   
   
   if(DELAY_REG > 0)         DELAY_REG--;   else DELAY_FLAG = 1;
   if(I2C_FRE_REG < I2C_FRE) I2C_FRE_REG++; else I2C_FRE_FLAG = 1;
   if(TIMEOUT_REG > 0) {     
      if (TIMEOUT_REG == 1) {
         bit_clear(OUT_DRIVER,0);
         DELAY_REG = PWOFF_PARAM;
         DELAY_FLAG = 0;
         TIMEOUT_REG = 0;
         MAIN_STATE = WAIT_STATE;
      }
      TIMEOUT_REG--;
   }
}

void main()
{
   delay_ms(100);
   init();
   setup_timer_2(T2_DIV_BY_1,199,10);      //100 us overflow, 1,0 ms interrupt   
   //setup_timer_2(T2_DIV_BY_4,124,10);      //100 us overflow, 1,0 ms interrupt   
   exe = 0;
   enable_interrupts(INT_RDA);
   enable_interrupts(INT_TIMER2);
   enable_interrupts(GLOBAL);

   while(TRUE)
   {
      //TODO: User Code
      process_Rx();
      switch(MAIN_STATE) {
         case PWUP_STATE:
            output_low(SSR_PIN);
            bit_set(OUT_STATUS,0);
            if(DELAY_FLAG) {
               CHN = 0;
               MAIN_STATE = INIT_STATE;
            }
            if(!bit_test(OUT_DRIVER,0)) {
               DELAY_REG = PWOFF_PARAM;
               DELAY_FLAG = 0;
               MAIN_STATE = WAIT_STATE;
            }
         break;
         case INIT_STATE:
            //Sel_chn(CHN);
            //i2c_pwrinit();
            delay_ms(10);
            if(CHN >= 7) {
               if(INIT_COUNT >= 10) {
                  CHN = 0;
                  I2C_RD_WR = 0;    // Write
                  MAIN_STATE = RUN_STATE;
                  SAMPLE_COUNT = 0;
               } else INIT_COUNT++;
            }
            if(CHN < 7) CHN++; else CHN = 0;
            if(!bit_test(OUT_DRIVER,0)) {
               DELAY_REG = PWOFF_PARAM;
               DELAY_FLAG = 0;
               MAIN_STATE = WAIT_STATE;
            }
         break;
         case RUN_STATE:
            if(I2C_FRE_FLAG) {
               I2C_FRE_REG = 0;
               I2C_FRE_FLAG = 0;
               Sel_chn(CHN);
               if(I2C_RD_WR) i2c_act_rd(CHN); else i2c_act_wr(CHN);
               if(CHN < 7) CHN++; else {I2C_RD_WR = ~I2C_RD_WR; CHN = 0;}
               if(SAMPLE_COUNT < SAMPLE) SAMPLE_COUNT++; else SAMPLE_COUNT = 0;
            }
            if(!bit_test(OUT_DRIVER,0)) {
               DELAY_REG = PWOFF_PARAM;
               DELAY_FLAG = 0;
               MAIN_STATE = WAIT_STATE;
            }
         break;
         case WAIT_STATE:
            if(DELAY_FLAG) MAIN_STATE = IDLE_STATE;
            if(bit_test(OUT_DRIVER,0)) {               
               CHN = 0;
               MAIN_STATE = RUN_STATE;
               SAMPLE_COUNT = 0;
            }
         break;         
         default:
            if(bit_test(OUT_DRIVER,0)) {               
               DELAY_REG = 2000;
               DELAY_FLAG = 0;
               MAIN_STATE = PWUP_STATE;
            } else {
               output_high(SSR_PIN);
               bit_clear(OUT_STATUS,0);
            }
         break;
      }     
   }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19569

View user's profile Send private message

PostPosted: Thu Mar 07, 2019 1:56 am     Reply with quote

You carefully don't show critical line. The #USE RS232.
This _must_ have the keyword 'ERRORS', or the UART will lockup, if
it receives data that is not handled. I suspect this is missing, and so the
UART stops working.
However the key thing that is 'causing' the actual problem, is that
once the 'unlock' sequence is started to write to memory, interrupts
have to be disabled, till the write. So serial communications need to stop
while a write occurs. If you look at the bootloader code, you will see
that once it receives a block to write, it sends a handshake to stop the
comms, while the write is actually performed.
With 'ERRORS' in the #USE RS232, missed byte(s) while the write takes
place, will no longer hang the UART, but your bus protocol will need to
be able to recover from one or more bytes having been lost.
Dat Bui



Joined: 07 Mar 2019
Posts: 3

View user's profile Send private message

PostPosted: Fri Mar 08, 2019 9:12 pm     Reply with quote

Ttelmah wrote:
You carefully don't show critical line. The #USE RS232.
This _must_ have the keyword 'ERRORS', or the UART will lockup, if
it receives data that is not handled. I suspect this is missing, and so the
UART stops working.
However the key thing that is 'causing' the actual problem, is that
once the 'unlock' sequence is started to write to memory, interrupts
have to be disabled, till the write. So serial communications need to stop
while a write occurs. If you look at the bootloader code, you will see
that once it receives a block to write, it sends a handshake to stop the
comms, while the write is actually performed.
With 'ERRORS' in the #USE RS232, missed byte(s) while the write takes
place, will no longer hang the UART, but your bus protocol will need to
be able to recover from one or more bytes having been lost.


Thanks for your answer,

The first thing is i already config
Code:

#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1)
#use rs232(baud=19200,parity=N,xmit=PIN_G1,rcv=PIN_G2,bits=8,stream=PORT2)

on other tap.

And the second thing, as I mention before, The UART are not completely stop working. The master pic could Write but not Read the data. Do you know how to fix it ?

P/S: Maybe some version of ccs devices.dat file isn't suitable for hardware int_rda interrupt. I don't know how to check my version is suitable or not. My version is 5.081.
Ttelmah



Joined: 11 Mar 2010
Posts: 19569

View user's profile Send private message

PostPosted: Sat Mar 09, 2019 1:22 am     Reply with quote

Yes, As I said, you do not have the keyword 'ERRORS' in your RS232
configuration.

If ERRORS is not there, the receive part of the UART will stop working, if a
character is missed. With ERRORS there the character will still be missed
but the receive part will be reset and continue working:
Code:

#use rs232(baud=19200, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8, ERRORS, stream=PORT1)
#use rs232(baud=19200, parity=N, xmit=PIN_G1, rcv=PIN_G2, bits=8, ERRORS stream=PORT2)


'ERRORS', _must_ always be used with the hardware UART, unless
_you_ are yourself explicitly resetting the error condition on the
UART. Repeat _must_. Otherwise if a character is not handled
the receive part of the UART _will_ stop working.
Dat Bui



Joined: 07 Mar 2019
Posts: 3

View user's profile Send private message

PostPosted: Tue Mar 12, 2019 12:18 am     Reply with quote

Ttelmah wrote:
Yes, As I said, you do not have the keyword 'ERRORS' in your RS232
configuration.

If ERRORS is not there, the receive part of the UART will stop working, if a
character is missed. With ERRORS there the character will still be missed
but the receive part will be reset and continue working:
Code:

#use rs232(baud=19200, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8, ERRORS, stream=PORT1)
#use rs232(baud=19200, parity=N, xmit=PIN_G1, rcv=PIN_G2, bits=8, ERRORS stream=PORT2)


'ERRORS', _must_ always be used with the hardware UART, unless
_you_ are yourself explicitly resetting the error condition on the
UART. Repeat _must_. Otherwise if a character is not handled
the receive part of the UART _will_ stop working.


Wow!!! Thanks for your advice, I fixed the problem =)))
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