Author Topic: PIC32MX Noob in need of some help  (Read 6606 times)

0 Members and 1 Guest are viewing this topic.

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: PIC32MX Noob in need of some help
« Reply #25 on: October 20, 2017, 10:39:45 am »
That is required by the compiler's built-in libraries.. e.g. to implement any kind of delay you have to know the frequency you are running at
 

Offline Howardlong

  • Super Contributor
  • ***
  • Posts: 5319
  • Country: gb
Re: PIC32MX Noob in need of some help
« Reply #26 on: October 20, 2017, 10:50:38 pm »
No I just read the appropriate part of the datasheet.
Thank you very much. If I have any questions regarding this I'll ask here.

Another question: do I need to define any kind of frequency macro? Like
Code: [Select]
#define FCY 40000000 or something similar or I only need to configure the "fuses" the right way?

Not on XC32, sorry that was just me coming straight off a PIC24 project, in XC16 they have a couple of macros that use FCY. It’s still useful to have somewhere clear in your code showing what frequency you think you should be running at, you can use it to derive many things such as baud rates and PWM. Sorry for the confusion, but feel free to use it anyway!
 
The following users thanked this post: JPortici

Offline MAntunesTopic starter

  • Regular Contributor
  • *
  • Posts: 99
  • Country: pt
Re: PIC32MX Noob in need of some help
« Reply #27 on: October 22, 2017, 03:14:31 pm »
Thank you very much.
So, using the OSCIOFNC bit I was able send the clock to a pin and here is the result:



40MHZ on pin10 so I think it's all running fine.

Another question I have is about interrupts. Do I need to configure any register to enable interrupts?

Code: [Select]
void __ISR([Vector Number], ipl[Priority Number]) Arbitrary_Function_Name(void){
    // Do stuff...
    // Clear interrupt flag
}

About the handler: I know what to put in the [Vector Number] argument, I just need to search for it in the datasheet. But what about the ipl[Priority Number]? Is it related to the interrupt priority?

Would this be an appropriate handler? I can't get it to compile on MPLAB X:

Code: [Select]
//I configured the interrupt priority to be 4
void __ISR(_TIMER_1_VECTOR,4) _Timer1IntHandler(void)
{
    LATAbits.LATA0 ^= 1;
    IFS0bits.T1IF = 0;
}


Thanks in advance.

EDIT:
I've been searching and found the bit for enabling multi vector interrupts (INTCONbits.MVEC). My doubts about the handler are still here, unfortunately.
I'll attach my code below.
« Last Edit: October 22, 2017, 03:57:55 pm by MAntunes »
 

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: PIC32MX Noob in need of some help
« Reply #28 on: October 22, 2017, 04:06:00 pm »
Hi, don't put your config settings in a header file. They should be inside a single *.c source file
 

Online mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13748
  • Country: gb
    • Mike's Electric Stuff
Re: PIC32MX Noob in need of some help
« Reply #29 on: October 22, 2017, 06:02:00 pm »
I think there are some examples in the XC32 install dir - there will probably be one for interrupts.
The declaration looks like for example
void __ISR(_EXTERNAL_4_VECTOR,IPL7SOFT) vsint(void)

And the setup :

 INTCONSET=_INTCON_MVEC_MASK;
 IFS0CLR=_IFS0_INT4IF_MASK;
 IPC4bits.INT4IP=7;
 IEC0bits.INT4IE=1; 


__builtin_enable_interrupts();   


To clear int flags you should use IFS0CLR=_IFS0_T1IF_MASK  rather than IFSxbits.xxIF=0 to avoid atomicity issues, especially if clearing int flags in the foreground. Not usually an issue but a major PITA to track down when it does bite you.
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline MAntunesTopic starter

  • Regular Contributor
  • *
  • Posts: 99
  • Country: pt
Re: PIC32MX Noob in need of some help
« Reply #30 on: October 22, 2017, 08:17:14 pm »
Hi, don't put your config settings in a header file. They should be inside a single *.c source file
Why? I've always put the config settings in and .h file and all worked fine.
Any special reason?

Thank you Mike.
I've seen that the declaration of the handler function is in the "sys/attribs.h" file.
Any way to define it in my configuration file?
And what about IPLxSRS vs IPLxSOFT vs IPLxAUTO? What is the diference? I got the following error:

Code: [Select]
Timer_Example.c:50:1: warning: Interrupt priority IPL4 is deprecated. Specify as 'IPL4{AUTO|SOFT|SRS|SAVEALL}' instead. [enabled by default]
To clear int flags you should use IFS0CLR=_IFS0_T1IF_MASK  rather than IFSxbits.xxIF=0 to avoid atomicity issues, especially if clearing int flags in the foreground. Not usually an issue but a major PITA to track down when it does bite you.
What do you mean by atomicity issues?

 

Online mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13748
  • Country: gb
    • Mike's Electric Stuff
Re: PIC32MX Noob in need of some help
« Reply #31 on: October 22, 2017, 09:11:55 pm »
SRS is the shadow register set. This speeds up interrupt handling by swapping the context into shadow registers instead of saving on the stack.
Unfortunately the SRS is not implemented on the 32MX1/2 devices ( From memory I think it is on the 32MM, and the larger devices), but the header files haven't been designed to warn you if you try to use them on parts where they don't exist - the SRS constant shouldn't be defined in the header files for these parts

Atomicity :
Using IFSxbits.xxx compiles to a read, mask the flag and write, and therefore non atomic ( interruptable).

Consider this situation
 Foreground task uses Timer 1, which it polls for overflow using the T1IF flag.
When it sees it set, it does whatever it needs to do, and clears the flag using IFS0bits.T1IF=0;

This will compile to something like this
  temp=IFS0
  temp=temp AND NOT <T1 bitmask>
  IFS0=temp

This will appear to work just fine.  Until that rare event of an interrupt whose flag lives in the same IFS register happening in the same machine cycle as the first read.
 
Let's say the Interrupt uses T2IF.
FG task reads IFS0 into temp, and at exactly the same time, the T2 interrupt happens
IFS0 now T1IF and T2IF set, and this is copied into temp
The next instruction cycle, the interrupt is serviced, which clears T2IF and returns to FG task
The FG task clears T1IF in temp, but temp also has T2IF still set as it was read before the int happened.
FG task rewrites IFS0 with T2IF set, causing a second, spurious T2 interrupt.

This spurious T2 interrupt may or may not be a problem, depending on your code. 
But if it is, and assuming the occurrence is random,and  T1 int happens every 10mS, then at 48MHz the probability of it occurring is one in 480,000 T2 interrupts. 

Needless to say this can result in those "once in a blue moon" type errors that can be a nightmare to track down. Fairly unlikely to happen with just timer events, but when one of the events is asynchronous ( e.g. serial receive) it is quite possible.

If the foreground task had used IFS0CLR, which is an atomic, non-interruptable operation, this can't happen.

Although it may appear that the interrupt could could safely use a non-atomic operation, it's still a bad idea as at some point you might have a higher priority interrupt, maybe not in this project, but several ones down teh line when you wonder why your old, reliable code has suddenly started misbehaving once every few minutes, hours or days.

This was why I needed to rush out and buy a scope in the middle of doing an install in Hong Kong a couple of years ago. I never saw any problems when testing at home, but once we had a big installation  of about 10,000 LED nodes, and a random one of them would blink every few seconds.

Since then I've always used xxxSET and xxxCLR.

There can also be similar issues if you are accessing things like LAT registers in both FG and int code

What's annoying is that if the compiler was smarter, it ought to be able to compile xxxbits.xx=0 into the corresponding xxxCLR operation . Unfortunately Microchip seem to be spending all their time on the shit-show that is Harmony.





 
« Last Edit: October 22, 2017, 09:16:32 pm by mikeselectricstuff »
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline MAntunesTopic starter

  • Regular Contributor
  • *
  • Posts: 99
  • Country: pt
Re: PIC32MX Noob in need of some help
« Reply #32 on: October 23, 2017, 09:34:22 am »
Thank you Mike. I think I understood it. You've been a great help!

Ended up including the "sys/attribs.h" where the interrupt handlers are defined and began using the IFSxCLR for clearing the interrups flags. All worked fine.

Since then I've always used xxxSET and xxxCLR.

Do you use it for everything or only for handling interrupts?

I'll leave my code attached so anyone can see it.

 

Online mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13748
  • Country: gb
    • Mike's Electric Stuff
Re: PIC32MX Noob in need of some help
« Reply #33 on: October 23, 2017, 09:55:51 am »
Since then I've always used xxxSET and xxxCLR.

Do you use it for everything or only for handling interrupts?

Anywhere that there is a SET/CLR register I'd usually use it - that's why it's there. The big risk is that you re-use code where it didn't matter for something where it does.
It can make defining things like pins slightly more involved then, e.g. instead of
 redled=1
you end up with
 redled_on
and 
 redled_off

Though I'm sure someone with better C macro-fu could come up with a way to make it nicer
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline Howardlong

  • Super Contributor
  • ***
  • Posts: 5319
  • Country: gb
Re: PIC32MX Noob in need of some help
« Reply #34 on: October 25, 2017, 05:13:08 pm »
It’d be nice if they’d gone to the trouble of extending the ....bits nomenclature to the set/clr/inv virtual SFRs too.

Regarding the (mis)use of, say, IFS0bits.T1IF, for example, the problem is that in unit testing with a single interrupt enabled you’ll be unlikely to see any problem. It’s only when you come to integrating your handiwork, when potentially several interrupts are enabled sharing the same IFS register, that every once in a while your system misbehaves. You might, for example, decide to change from one timer to another, and the problem starts happening, or appears to go away.

From experience, it’s incredibly difficult to fathom until you realise where the interaction is.
 

Online mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13748
  • Country: gb
    • Mike's Electric Stuff
Re: PIC32MX Noob in need of some help
« Reply #35 on: October 25, 2017, 08:49:07 pm »
It’d be nice if they’d gone to the trouble of extending the ....bits nomenclature to the set/clr/inv virtual SFRs too.

Regarding the (mis)use of, say, IFS0bits.T1IF, for example, the problem is that in unit testing with a single interrupt enabled you’ll be unlikely to see any problem. It’s only when you come to integrating your handiwork, when potentially several interrupts are enabled sharing the same IFS register, that every once in a while your system misbehaves. You might, for example, decide to change from one timer to another, and the problem starts happening, or appears to go away.

From experience, it’s incredibly difficult to fathom until you realise where the interaction is.
It only needs one int and one FG task updating the same IFSx to potentially be an issue.
One thing you do get to recognise with experience , is that ( assuming it doesn't just crash) after a while of observing, you see something happenning  very infrequently but with a fairly consistent probability. This generally distinguishes it from things like hardware data errors, which tend to be more more pattern-dependent, bursty or influenced by cable length etc.
 
Once you recognise this low but consistent probability of occurrence , you can start tweaking the frequency of the stimulus to see what makes a difference. The very low probability tells you pretty much immediately it's a "tiny window of vulnerability" type of thing.
In the case of the Hong Kong jib, by sending a very high framerate to a very limited number of LED nodes, instead of all of them at a normal rate, I could make it happen often enough to debug in my hotel room on a small piece instead of on-site, at night in the shopping centre.
I'd probably have figured it out eventually,  but I absolutely had to get it fixed the following night, and knew that by having a scope I could put test pulses out at every possible stage of the code until I'd narrowed it down. I think it was an hour or so round trip to go buy a scope, and half an hour to find the problem.
 
I subsequently had a similar issue (with old recycled code in a new application), and spotted the pattern very quickly purely from the rate of ocurrence.
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf