Difference between revisions of "PIC32"
(→DMA) |
|||
(21 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | Some things I've learned about PIC32MX and MZ. | ||
==Tips== | ==Tips== | ||
− | ===MX is not MZ=== | + | ===MX is not MZ is not C is not MM=== |
− | + | For starters, there are two distinct PIC32 architectures. MX and MZ (let's forget about the rest). The reference manuals (Family Reference Manuals) that apply to MZ do not apply to MX. A simple thing to misunderstand for beginners. Use the reference manual that is mentioned in your Pic's particular datasheet. | |
− | === | + | |
+ | Then there is PIC32C (C == ARM Cortex), and some others... | ||
+ | |||
+ | ===PIC32 can be Power Hungry=== | ||
Check your voltage regulator if you find that your code keeps resetting, when in debug mode. I found that my resets were due to not enough power. The more peripherals you turn on, the more power you will need. This is one reason why code will work, then suddenly fail after adding functionality (say turning on DMA, or a constant UART stream) | Check your voltage regulator if you find that your code keeps resetting, when in debug mode. I found that my resets were due to not enough power. The more peripherals you turn on, the more power you will need. This is one reason why code will work, then suddenly fail after adding functionality (say turning on DMA, or a constant UART stream) | ||
+ | ===Read Registers Whilst Debugging=== | ||
+ | If you put just a register macro, e.g. U1STA; or U1MODE; in the code, and even if nothing happens to that register, it can be read by hovering over it while debugging. Useful to just type out a number of registers in the code, and then pause, and check them while debugging. | ||
+ | An example: | ||
+ | /*U1MODE; | ||
+ | U1STA; | ||
+ | IFS1; | ||
+ | IEC1; | ||
+ | RCON;*/ //Comment them out, otherwise they will generate asm in disassembler. | ||
+ | |||
+ | ===MPLAB X Tools - Debugger - Watches doesn't work for large arrays=== | ||
+ | The watch doesn't read the whole array. Export to CSV to see all values, or examine map file. MPLAB 5.25. Reference: https://www.microchip.com/forums/m790353.aspx | ||
+ | |||
+ | ===Atomic Operations on bits=== | ||
+ | See: | ||
+ | IFS4bits.DMA1IF = 0 //takes a few cycles, can cause problems | ||
+ | IFS4CLR = _IFS4_DMA1IF_MASK //takes one cycle. better. | ||
+ | |||
+ | ===Resets=== | ||
+ | ====Dest and Source Sizes==== | ||
+ | Incorrect Dest and Source sizes for DMA can cause resets. It will register as POR and BOR, but it's due to for example, the source of SPIxBUF being set to size 10 bytes, (which is incorrect, SPIxBUF can only be 1,2 or 4 bytes depending on settings). | ||
+ | ====Insufficient Power==== | ||
+ | Self explanatory. | ||
+ | ====_ISR Invalid Parameters==== | ||
+ | If you have an ISR (interrupt), and you pass IPL5SRS. Everything is working fine, then you change that to IPL2SRS, and you are in a reset loop. | ||
+ | Read the books mentioned below for more info. IPLxYYYY where x is 1-7 and YYYY is SRS or Soft. Not all combinations are possible. | ||
+ | |||
+ | ===DMA=== | ||
+ | ====DMA - If you CFORCE, and it finishes, you must CHEN again to CFORCE again==== | ||
+ | Subject. | ||
+ | ====Not all Pic32 have 16 bits of DMA memory==== | ||
+ | Earlier pics (PIC32MX440) only have 8 bits in DCHxSSIZ or DSIZ. If it only outputs 256 bytes, this is why. Check that register, because it's not mentioned anywhere else. | ||
+ | ====DMA Has Issues with editing a coherent buffer, maybe related to kseg1==== | ||
+ | Let's say you have a video buffer. 10000 bytes. You setup three for loops to edit the buffer at different increments. One might edit the first 8, then skip ahead to 24, edit that 8, then skip to 48 and edit that 8, etc... The second will edit the second 8 starting at 8, going to 16, and following a similar pattern as the previous. Finally you will have a third doing the same. What happens, is that the third overwrites everything with its values. | ||
+ | |||
+ | ===Prefetch Cache (MZ)=== | ||
+ | ====Cache can stop initialization of large variables when using them for DMA==== | ||
+ | Let's say you have a loop | ||
+ | for(x=0,x<10000,x++){ | ||
+ | array[x] = 0xFF; | ||
+ | } | ||
+ | If you have cache enabled (it's enabled by default on MZ) you will only get 6000 or so of the variables changed for DMA. If you go to debugging - watch - choose array[x] and export to csv, you will see all the values have 0xFF but the dma will output about 6000 of 0xFF and then 4000 of 0's or 1's. The solution is to disable the cache via http://web.archive.org/web/https;//microchipdeveloper.com/32bit:mz-cache-disable | ||
+ | |||
+ | Reference: http://web.archive.org/web/https://www.microchip.com/forums/m1116587.aspx | ||
+ | |||
+ | ==Code== | ||
+ | [[PIC32_Examples]] - scraps atm | ||
+ | |||
==Resources== | ==Resources== | ||
===Family Reference Manuals=== | ===Family Reference Manuals=== | ||
Line 9: | Line 60: | ||
===Peripheral Library Examples=== | ===Peripheral Library Examples=== | ||
There are a number of well commented (unlike most garbage online) examples that are ideal for someone learning about setup of pic32 peripherals in the Peripheral Libraries Examples. Link: https://people.ece.cornell.edu/land/courses/ece4760/PIC32/PLIB_examples/plib_examples/ | There are a number of well commented (unlike most garbage online) examples that are ideal for someone learning about setup of pic32 peripherals in the Peripheral Libraries Examples. Link: https://people.ece.cornell.edu/land/courses/ece4760/PIC32/PLIB_examples/plib_examples/ | ||
+ | ===Books=== | ||
+ | |||
+ | {{Electronics}} |
Latest revision as of 07:23, 5 November 2019
Some things I've learned about PIC32MX and MZ.
Tips
MX is not MZ is not C is not MM
For starters, there are two distinct PIC32 architectures. MX and MZ (let's forget about the rest). The reference manuals (Family Reference Manuals) that apply to MZ do not apply to MX. A simple thing to misunderstand for beginners. Use the reference manual that is mentioned in your Pic's particular datasheet.
Then there is PIC32C (C == ARM Cortex), and some others...
PIC32 can be Power Hungry
Check your voltage regulator if you find that your code keeps resetting, when in debug mode. I found that my resets were due to not enough power. The more peripherals you turn on, the more power you will need. This is one reason why code will work, then suddenly fail after adding functionality (say turning on DMA, or a constant UART stream)
Read Registers Whilst Debugging
If you put just a register macro, e.g. U1STA; or U1MODE; in the code, and even if nothing happens to that register, it can be read by hovering over it while debugging. Useful to just type out a number of registers in the code, and then pause, and check them while debugging. An example:
/*U1MODE; U1STA; IFS1; IEC1; RCON;*/ //Comment them out, otherwise they will generate asm in disassembler.
MPLAB X Tools - Debugger - Watches doesn't work for large arrays
The watch doesn't read the whole array. Export to CSV to see all values, or examine map file. MPLAB 5.25. Reference: https://www.microchip.com/forums/m790353.aspx
Atomic Operations on bits
See:
IFS4bits.DMA1IF = 0 //takes a few cycles, can cause problems IFS4CLR = _IFS4_DMA1IF_MASK //takes one cycle. better.
Resets
Dest and Source Sizes
Incorrect Dest and Source sizes for DMA can cause resets. It will register as POR and BOR, but it's due to for example, the source of SPIxBUF being set to size 10 bytes, (which is incorrect, SPIxBUF can only be 1,2 or 4 bytes depending on settings).
Insufficient Power
Self explanatory.
_ISR Invalid Parameters
If you have an ISR (interrupt), and you pass IPL5SRS. Everything is working fine, then you change that to IPL2SRS, and you are in a reset loop. Read the books mentioned below for more info. IPLxYYYY where x is 1-7 and YYYY is SRS or Soft. Not all combinations are possible.
DMA
DMA - If you CFORCE, and it finishes, you must CHEN again to CFORCE again
Subject.
Not all Pic32 have 16 bits of DMA memory
Earlier pics (PIC32MX440) only have 8 bits in DCHxSSIZ or DSIZ. If it only outputs 256 bytes, this is why. Check that register, because it's not mentioned anywhere else.
Let's say you have a video buffer. 10000 bytes. You setup three for loops to edit the buffer at different increments. One might edit the first 8, then skip ahead to 24, edit that 8, then skip to 48 and edit that 8, etc... The second will edit the second 8 starting at 8, going to 16, and following a similar pattern as the previous. Finally you will have a third doing the same. What happens, is that the third overwrites everything with its values.
Prefetch Cache (MZ)
Cache can stop initialization of large variables when using them for DMA
Let's say you have a loop
for(x=0,x<10000,x++){ array[x] = 0xFF; }
If you have cache enabled (it's enabled by default on MZ) you will only get 6000 or so of the variables changed for DMA. If you go to debugging - watch - choose array[x] and export to csv, you will see all the values have 0xFF but the dma will output about 6000 of 0xFF and then 4000 of 0's or 1's. The solution is to disable the cache via http://web.archive.org/web/https;//microchipdeveloper.com/32bit:mz-cache-disable
Reference: http://web.archive.org/web/https://www.microchip.com/forums/m1116587.aspx
Code
PIC32_Examples - scraps atm
Resources
Family Reference Manuals
Start here. These will be your required reading for any peripheral. The data sheets will also be required. With these two in hand, you should be able to flip almost any bit needed. Make sure you get the Reference manual for your particular implementation (MX or MZ).
Peripheral Library Examples
There are a number of well commented (unlike most garbage online) examples that are ideal for someone learning about setup of pic32 peripherals in the Peripheral Libraries Examples. Link: https://people.ece.cornell.edu/land/courses/ece4760/PIC32/PLIB_examples/plib_examples/
Books
|