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

IOC not working

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



Joined: 03 Dec 2013
Posts: 215

View user's profile Send private message

IOC not working
PostPosted: Wed Dec 26, 2018 3:35 pm     Reply with quote

Chip:18F46K42
Compiler: 5.082

IOC does not appear to work.

PIN_B5 has a 100K Pull up resistor to 3V3 and the signal is pulling the pin low about once every 1-2 seconds confirmed with scope.

I'm somewhat confused as the .h for the chip has
INT_IOC and INT_IOC_B5 Pin B5 is the pin I'm interested in checking.

I've tried several different combinations of
Code:

enable_interrupts(INT_IOC);
enable_interrupts(INT_IOC_B5);

the IOC does not function.

For test I tried
Code:
n1B5 = input(PIN_B5);

and sure enough B5 is changing, but of course I need the interrupt and can't reply on polling.

Has anyone been able to make the IOC work on this chip ?

Thanks

Code:

#include <18F46K42.h>
#device ADC=16

#FUSES NOWDT                  //No Watch Dog Timer
#FUSES NOBROWNOUT        //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or
                                          // B5(PIC18) used for I/O !

#use delay(crystal=12000000)

#define GREEN_LED_ON  output_high(PIN_C5)
#define GREEN_LED_OFF output_low(PIN_C5)

int8 g_n8PortB;

#INT_IOC
void  IOC_isr(void)
{
   g_n8PortB = input_b(); // read the port clear the IF
}

void main()
{
   int1 n1OldB5=0;
   int1 n1B5=0;
 

   enable_interrupts(INT_IOC);
   enable_interrupts(INT_IOC_B5);
       
   enable_interrupts(GLOBAL);

   n1OldB5 = n1B5;

   while(TRUE)
   {
     n1B5 = bit_test( g_n8PortB, 5 );
     
     // for test  n1B5 = input(PIN_B5); // works B5 is changing

     if ( n1B5 != n1OldB5 )
     {
        n1OldB5 = n1B5;
        if( n1B5 )
        {
           GREEN_LED_ON;
        }
        else
        {
           GREEN_LED_OFF;
        }
     }
   }
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Dec 27, 2018 12:04 am     Reply with quote

The 18F46K42.h file IOC definitions are incorrect in vs. 5.082.

To fix it, place this section of code just above main():
Code:

#define INT_IOC_B5_L2H  0x11200080  // IOC on rising edge on B5
#define INT_IOC_B5_H2L  0x21200080  // IOC on falling edge on B5
#undef  INT_IOC_B5
#define INT_IOC_B5      0x31200080  // IOC on either edge on B5

Choose one of those, only.

For example, if you want an IOC interrupt on either edge of B5, use this one:
Code:
enable_interrupts(INT_IOC_B5);

Don't use this:
Code:
enable_interrupts(INT_IOC);


Note: This fixes pin B5 IOC only. The other pins are wrong too.
And it's missing the individual edge #defines for all the other pins.

CCS support should be informed of this.
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Thu Dec 27, 2018 12:55 am     Reply with quote

Understand that the physical interrupt is INT_IOC.
So your handler should use this name.

The standard code is correctly setting up the interrupt, what they have omitted
is to setup the 'edge' register bits to set which edges the interrupt will
trigger on. These default to 'off' on boot, so the interrupt doesn't respond
to either edge... Sad
soonc



Joined: 03 Dec 2013
Posts: 215

View user's profile Send private message

Thanks I test it.
PostPosted: Thu Dec 27, 2018 9:05 am     Reply with quote

PCM programmer wrote:
The 18F46K42.h file IOC definitions are incorrect in vs. 5.082.

To fix it, place this section of code just above main():
Code:

#define INT_IOC_B5_L2H  0x11200080  // IOC on rising edge on B5
#define INT_IOC_B5_H2L  0x21200080  // IOC on falling edge on B5
#undef  INT_IOC_B5
#define INT_IOC_B5      0x31200080  // IOC on either edge on B5

Choose one of those, only.

For example, if you want an IOC interrupt on either edge of B5, use this one:
Code:
enable_interrupts(INT_IOC_B5);

Don't use this:
Code:
enable_interrupts(INT_IOC);


Note: This fixes pin B5 IOC only. The other pins are wrong too.
And it's missing the individual edge #defines for all the other pins.

CCS support should be informed of this.


Will test in about an hour and report back.
Thanks for the help.
soonc



Joined: 03 Dec 2013
Posts: 215

View user's profile Send private message

One more thing
PostPosted: Thu Dec 27, 2018 8:47 pm     Reply with quote

Just reading port B in the ISR does not clear the interrupt.
clear_interrupt(INT_IOC_B5); // Required when the interrupt is first enabled, and in the ISR.

Thanks for the help.

Code:

#include <18F46K42.h>
#device ADC=16

#FUSES NOWDT                  //No Watch Dog Timer
#FUSES NOBROWNOUT        //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or
                                          // B5(PIC18) used for I/O !

#use delay(crystal=12000000)

#define GREEN_LED_ON  output_high(PIN_C5)
#define GREEN_LED_OFF output_low(PIN_C5)

int8 g_n8PortB;

#INT_IOC
void  IOC_isr(void)
{
   g_n8PortB = input_b(); // read the port clear flag actually does not do that
                          // this code will work without reading port B
                          // Just clear the interrupt
   clear_interrupt(INT_IOC_B5); // Required
}

// Thanks PCM_Programmer
#define INT_IOC_B5_L2H  0x11200080  // IOC on rising edge on B5
#define INT_IOC_B5_H2L  0x21200080  // IOC on falling edge on B5
#undef  INT_IOC_B5
#define INT_IOC_B5      0x31200080  // IOC on either edge on B5

void main()
{
   int1 n1OldB5=0;
   int1 n1B5=0;

   enable_interrupts(INT_IOC_B5);
   clear_interrupt(INT_IOC_B5); // required or it hangs the entire chip
       
   enable_interrupts(GLOBAL);

   n1OldB5 = n1B5;

   while(TRUE)
   {
     n1B5 = bit_test( g_n8PortB, 5 );

     if ( n1B5 != n1OldB5 )
     {
        n1OldB5 = n1B5;
        if( n1B5 )
        {
           GREEN_LED_ON;
        }
        else
        {
           GREEN_LED_OFF;
        }
     }
   }
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Dec 28, 2018 3:09 am     Reply with quote

I sent a detailed bug report to CCS support, regarding the incorrect and
missing IOC constants for the K42-series PICs.
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