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

5.074 HIGH ints & PIC18F25K40 bug [SOLVED]

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



Joined: 24 Jun 2004
Posts: 1908

View user's profile Send private message

5.074 HIGH ints & PIC18F25K40 bug [SOLVED]
PostPosted: Fri Aug 25, 2017 6:57 pm     Reply with quote

Just a warning, 5.074 will enable an interrupt designated as high when you enable a low priority interrupt. I found the behaviour with CCP1 (high) being automatically enabled when I enabled timer 2's interrupt. PIC18F25K40.

And to top off this gem of a day, I finally got my CCS order of 2 bare development boards today, 17 days after I ordered them. Canada Post took 12 days to clear the package through customs. Anyway, when I opened it I found that I'm missing one of the boards I paid for.

Never should have got out of bed this morning.


Last edited by newguy on Mon Aug 28, 2017 10:24 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19518

View user's profile Send private message

PostPosted: Sat Aug 26, 2017 8:17 am     Reply with quote

Er. Not that I can see.

Code:

....................    enable_interrupts(GLOBAL);
01C0:  MOVLW  C0
01C2:  IORWF  FF2,F
....................    enable_interrupts(INT_TIMER2);
01C4:  MOVLB  E
01C6:  BSF    xC6.1


It is only setting bit 1, EC6, which is Timer2 interrupt enable.

This is compiled for your chip with 5.074.

HIGH INTS is enabled, and CCP1 is set as high priority:
Code:

#include <main25K.h>
#device HIGH_INTS=TRUE
#USE DELAY (CRYSTAL=20Mhz)

#INT_CCP1 HIGH
void int_ccp(void)
{


}

#INT_TIMER2
void int_tick(void)
{


}


void main()
{
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_TIMER2);
   //etc...

newguy



Joined: 24 Jun 2004
Posts: 1908

View user's profile Send private message

PostPosted: Sat Aug 26, 2017 9:30 am     Reply with quote

On Monday I have to strip down my program to the bare minimum, but some combination of what I'm setting is also setting the CCP1 interrupt to enabled, but only if the HIGH is also set.

When 5.074 was released I was actually relieved because I had to do a lot of juggling to get things to work with 5.073 and the 25K40. I installed it, compiled, programmed my PIC, and.....it hung. ....Screw it, I'm reverting. No time to dig. ...Until yesterday when I was having the really weird hardware issues, so in desperation I compiled a completely stripped down version with 5.074 and tried that, and it hung too. Then I dug in a bit, because why not, I'm already annoyed.

I had stripped down the code to do the initializations (hardware and variables), but then completely stripped out the "running functions" and just put an initial serial transmit of a single character before the while() loop, and in the loop, I put another serial transmit of a different character & delay.

If global interrupts were enabled, the code would hang - initial character would appear, but not the 2nd (certainly not repeating). Comment out the global enable and it ran fine.

Okay, I had two interrupts enabled - RDA and timer 2. Commented out RDA (put the global back in), and...still hung. Put RDA back in and commented out timer 2 - runs fine. Okay, why? High ints - that's the only "weird" interrupt stuff I'm doing, so I commented out the #device high ints line and also the HIGH in the ccp1 interrupt. Runs fine. Weird because I'm not only NOT enabling the ccp1 interrupt, I'm not even powering the ccp1 peripheral. Really. This is a low power project and I'm setting its PMD bit to 1 initially. In this stripped down version it's not powered at all.

As I said, Monday I'll strip it back to bare minimum and post something that demonstrates the problem. 5.073 runs fine but 5.074 hangs if the high ints option is used.
newguy



Joined: 24 Jun 2004
Posts: 1908

View user's profile Send private message

PostPosted: Mon Aug 28, 2017 7:40 am     Reply with quote

This demonstrates the problem. Compile with 5.073 and it runs (initial transmission of 'r' followed by reads of port B every 250ms), and if you compile with 5.074, it hangs. All that emerges is the initial 'r'. Comment out the high ints declaration (and the HIGH in the CCP1 interrupt), and it runs with 5.074.

Code:
#include <18F25K40.h>
#device ADC=10
#device HIGH_INTS=TRUE

#FUSES HS                       //High speed Osc (> 4MHz for PCM/PCH)
#FUSES RSTOSC_EXT_PLL           //On Power-up clock running from External with PLL
#FUSES NOCLKOUT                 //I/O function on OSC2
#FUSES CKS                      //Clock Switching Enabled
#FUSES MCLR                     //Master Clear pin enabled
#FUSES PUT                      //Power Up Timer
#FUSES NOLPBOR                  //Low-Power Brownout reset is disabled
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES BORV28                   //Brownout reset at 2.8V
#FUSES ZCDDIS                   //Zero-cross detect circuit is disabled at POR
#FUSES NOPPS1WAY                //Allows reconfiguration of peripheral pins
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDTSW                    //Watch Dog Timer Postscale settable in software
#FUSES WDTWIN_SW                //Watchdog Window is settable in software
#FUSES WDTCLK_SW                //WDT clock source settable in software
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTC                   //Configuration registers not write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOSCANE                  //Scanner module is not available for use
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOCPD                    //No EE protection
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads

#use delay(clock=64000000,crystal=16000000)

#opt compress

#case

#use fast_io(A)
#use fast_io(B)
#use fast_io(C)

// v5.073 compiler bug workaround inclusions begin
#byte T6CON=getenv("SFR:T6CON") // timer 6 control register - necessary because compiler wasn't disabling timer 6
#byte T4CON=getenv("SFR:T4CON") // timer 4 control register - necessary because compiler wasn't disabling timer 4
#byte RC2PPS=getenv("SFR:RC2PPS") // PIN_C2 output peripheral pin select register - CCP2 output
#byte RC5PPS=getenv("SFR:RC5PPS") // PIN_C5 output peripheral pin select register - MSSP data output
#byte RC6PPS=getenv("SFR:RC6PPS") // PIN_C6 output peripheral pin select register - UART TX output
#byte RB5PPS=getenv("SFR:RB5PPS") // PIN_B5 output peripheral pin select register - either manual or CCP1
#byte CCP1PPS=getenv("SFR:CCP1PPS") // CCP1 input pin select register
#byte RA0PPS=getenv("SFR:RA0PPS")
#byte RX1PPS=getenv("SFR:RXPPS") // UART RX pin select register (note name discrepancy because apparently neither CCS nor MC follow the names specified in the data sheet)
#define MSSP_DATA_MANUAL_CONTROL             0
#define MSSP_DATA_MSSP_CONTROL               14
#define SIGNAL_SENSORS_MANUAL_CONTROL        0
#define SIGNAL_SENSORS_CCP2_CONTROL          6
#define CCP1_TO_PIN_B5                       13
#define UART_TRANSMIT                        9
#define UART_RECEIVE_TO_PIN_C7               23
#byte BAUD1CON=getenv("SFR:BAUD1CON") // UART baud rate divisor register
#byte TX1STA=getenv("SFR:TX1STA") // UART TX status register
#byte RC1STA=getenv("SFR:RC1STA") // UART RX status register
#byte SP1BRGL=getenv("SFR:SP1BRGL") // UART low baud rate register
#define TX1STA_value                         0xa2
#define RC1STA_value                         0x90
#define SP1BRGL_value                        103
// 16 MHz clock / (16 * (103 + 1)) = 9615.4 BAUD, 0.16% high - well within spec
#byte TX1REG=getenv("SFR:TX1REG")
#byte RC1REG=getenv("SFR:RC1REG")
#byte CPUDOZE=getenv("SFR:CPUDOZE")
// v5.073 compiler but workaround inclusions end

#byte PRODH=getenv("SFR:PRODH")
#byte PMD0=getenv("SFR:PMD0")
#byte PMD1=getenv("SFR:PMD1")
#bit TMR6MD=PMD1.6
#bit TMR5MD=PMD1.5
#bit TMR4MD=PMD1.4
#bit TMR3MD=PMD1.3
#bit TMR2MD=PMD1.2
#bit TMR1MD=PMD1.1
#bit TMR0MD=PMD1.0
#byte PMD2=getenv("SFR:PMD2")
#bit ADCMD=PMD2.5
#byte PMD3=getenv("SFR:PMD3")
#bit CCP2MD=PMD3.1
#bit CCP1MD=PMD3.0
#byte PMD4=getenv("SFR:PMD4")
#bit UART1MD=PMD4.6
#byte PMD5=getenv("SFR:PMD5")
#byte CCPTMRS=getenv("SFR:CCPTMRS")
#byte CCP1CON=getenv("SFR:CCP1CON")
#bit CCP1ENABLE=CCP1CON.7
#byte CCP2CON=getenv("SFR:CCP2CON")
#bit CCP2ENABLE=CCP2CON.7
#byte T5GCON=getenv("SFR:T5GCON")
#byte T5CLK=getenv("SFR:T5CLK")
#byte T5CON=getenv("SFR:T5CON")
#byte T6PR=getenv("SFR:T6PR")
#byte T6CLK=getenv("SFR:T6CLK")
#byte TMR0H=getenv("SFR:TMR0H")
#byte TMR0L=getenv("SFR:TMR0L")
#byte SSP1BUF=getenv("SFR:SSP1BUF")
#byte ANSELA=getenv("SFR:ANSELA")
#byte ANSELB=getenv("SFR:ANSELB")
#byte ANSELC=getenv("SFR:ANSELC")
#byte T1GPPS=getenv("SFR:T1GPPS")
#byte PPSLOCK=getenv("SFR:PPSLOCK")

#define TX_BUFFER_SIZE                          256
#define RX_BUFFER_SIZE                          128

struct {
   int1 tx_in_progress_flag;
   int1 message_rxd_flag;
   unsigned int8 num_rxd_messages;
   unsigned int8 tx_buffer[TX_BUFFER_SIZE];
   unsigned int8 rx_buffer[RX_BUFFER_SIZE];
} comm;

unsigned int8 *comm_tx_rd_pointer;
unsigned int8 *comm_tx_wr_pointer;
unsigned int8 *comm_rx_rd_pointer;
unsigned int8 *comm_rx_wr_pointer;

struct {
   int1 fired_flag;
} tenms_timer;

void bputc(unsigned int8 c) {
   *comm_tx_wr_pointer = c;
   if (++comm_tx_wr_pointer == (&comm.tx_buffer[0] + TX_BUFFER_SIZE)) {
      comm_tx_wr_pointer = &comm.tx_buffer[0];
   }
   if (comm.tx_in_progress_flag == FALSE) {
      comm.tx_in_progress_flag = TRUE;
      enable_interrupts(INT_TBE); // enable the transmit buffer empty interrupt
   }
}

#int_CCP1 HIGH
void ccp1_isr(void) {
   
}

#int_TIMER2
void timer2_isr(void) {
   tenms_timer.fired_flag = TRUE;
}

#int_RDA
void rda_isr(void) {
   unsigned int8 c;
   
   c = RC1REG;
   *comm_rx_wr_pointer = c;
   if (++comm_rx_wr_pointer == (&comm.rx_buffer[0] + RX_BUFFER_SIZE)) {
      comm_rx_wr_pointer = &comm.rx_buffer[0];
   }
   if (c == 0x0d) {
      comm.num_rxd_messages++;
      comm.message_rxd_flag = TRUE;
   }
}

#int_TBE
void tbe_isr(void) {
   if (comm_tx_rd_pointer != comm_tx_wr_pointer) { // ...if there's more in the buffer to transmit...
      TX1REG = *comm_tx_rd_pointer;
      if (++comm_tx_rd_pointer == (&comm.tx_buffer[0] + TX_BUFFER_SIZE)) {
         comm_tx_rd_pointer = &comm.tx_buffer[0];
      }
      if (comm_tx_rd_pointer == comm_tx_wr_pointer) {
         comm.tx_in_progress_flag = FALSE;
         disable_interrupts(INT_TBE);
      }
   }
   else { // no more characters in the buffer - disable the interrupt
      comm.tx_in_progress_flag = FALSE;
      disable_interrupts(INT_TBE);
   }
}

void main(void) {
   // kill all peripherals...
   PMD0 = 0x7b; // ...except the peripheral clock distribution network and EEPROM
   PMD1 = 0xff;
   PMD2 = 0xff;
   PMD3 = 0xff;
   PMD4 = 0xbf; // ...except the UART
   PMD5 = 0xff;
   
   bit_clear(BAUD1CON, 3); // 8 bit baud rate generator, not 16
   SP1BRGL = SP1BRGL_value;
   TX1STA = TX1STA_value;
   RC1STA = RC1STA_value;
   RC6PPS = UART_TRANSMIT;
   RX1PPS = UART_RECEIVE_TO_PIN_C7;
   ANSELC = 0x00; // all digital
   output_c(0x41); // set outputs first
   set_tris_c(0x80); // set proper directions on the port
   
   ANSELB = 0x00; // all digital
   output_b(0x00); // set outputs first
   set_tris_b(0x20); // finally set proper directions on the port
   
   comm.tx_in_progress_flag = FALSE;
   comm.message_rxd_flag = FALSE;
   comm.num_rxd_messages = 0;
   
   comm_tx_rd_pointer = &comm.tx_buffer[0];
   comm_tx_wr_pointer = &comm.tx_buffer[0];
   
   comm_rx_rd_pointer = &comm.rx_buffer[0];
   comm_rx_wr_pointer = &comm.rx_buffer[0];
   
   tenms_timer.fired_flag = FALSE;
   
   TMR2MD = 0;
   delay_cycles(3);
   setup_timer_2(T2_CLK_INTERNAL | T2_DIV_BY_128, 249, 5); // start timer 2 with a 10ms overflow/interrupt
   enable_interrupts(INT_TIMER2);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   
   TX1REG = 'r';
   
   while (TRUE) {
      printf(bputc, "%x\n\r", input_b());
      delay_ms(125);
      output_toggle(PIN_C2);
      delay_ms(125);
     
   }
}
newguy



Joined: 24 Jun 2004
Posts: 1908

View user's profile Send private message

PostPosted: Mon Aug 28, 2017 10:25 am     Reply with quote

CCS just sent me an updated DLL which fixed the issue. I imagine that the fix will be rolled into 5.075, whenever that's released.
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