Giter Site home page Giter Site logo

pic32mx-blink's Introduction

PIC32MX Blink

Introductory project for Microstick II with PIC32MX250F128B SPDIP (included with Microstick II in my case - not guaranteed - Microchip may change included chips).

It does this:

  • blinks on-board LED D6 (ON RA0, PIN2) using TMR1 interrupt. Interrupt rate is 10 Hz, LED blinking rate is 10/2 = 5 Hz (in my case measured rate was 5.0165 Hz)
  • toggles RA1, PIN3 every 1ms (1000 Hz) using Core Timer interrupt. So output frequency on RA1 should be 1000/2 = 500 Hz (measured 501.61 Hz)
    • Core Timer ticks every 2nd CPU cycle. System clock is 48 MHz, so Core Timer increments at 24 MHz. Interrupt is called when SYSTICK=24000 (see CORE_TIMER_INTERRUPT_PERIOD_VALUE=0x5dc0 (24000 decimal) in firmware\src\config\default\peripheral\coretimer\plib_coretimer.h)
    • look in firmware\src\config\default\peripheral\coretimer\plib_coretimer.c to understand implementation
    • NOTE: ARM has similar register called SYSTICK.

If you never used PIC32MX and/or Harmony code generator please look at this nice guide:

Requirements

Hardware requirements

  • Microstick II demo board
  • PIC32MX250F128B SPDIP inserted into socket U5 (included with board, should be default)
  • programming pins set 1 (Pin4 & Pin5): switch S1 in position A

NOTE: PIC32MX is MIPS32 M4K based CPU Core with peripherals from Microchip. Please see

Generally we can say that MIPS32 Assembler has similar attributes as ARM:

  • designed for compilers, not for manual coding
  • all instructions (at least those generated with XC32) are 32-bit wide (unless you use MIPS16e instructions set - possible but not default)
  • this causes some issues - because CPU is 32-bit, so loading 32-bit literal often means that there must be used 2 instructions (1st one loads 16-bit high value, and 2nd OR it with low 16-bit value)
  • assembler provides macro-instructions that accepts 32-bit literals and generate appropriate 2 instructions.
  • also literals are internally signed, so there is trickery when assembler load full 32-bit
  • please note that there is unfortunately different meaning for Word and Double-word sizes (because dsPIC is 16-bit but MIPS32 is 32-bit):
    • 16-bit value: dsPIC WORD = MIP32 half-word (H suffix)
    • 32-bit value: dsPIC DWORD (D) = MIPS32 word (default suffix)
    • at least Byte is same :-) (using B suffix on MIPS)

WARNING! Generated code for MIPS32 interrupts in "Software mode" may be quite inefficient when compared to these on dsPIC! Here is example of void __ISR(_TIMER_1_VECTOR, ipl1SOFT) TIMER_1_Handler (void) (using xc32-objdump -S output.elf command):

This example is using so called software instructions mode (ipl-x-SOFT keyword):

  • please see DS50002799C - 188 of c:\Program Files\Microchip\xc32\v4.30\docs\MPLAB-XC32-Compiler-UG-PIC32M-DS-50002799.pdf
Disassembly of section .text.TIMER_1_Handler:

9d000120 <TIMER_1_Handler>:

void __ISR(_TIMER_1_VECTOR, ipl1SOFT) TIMER_1_Handler (void)
{
; copy SP from previous register set (if used)
9d000120:	415de800 	rdpgpr	sp,sp
; move from Coprocessor C0: k0 := EPC
9d000124:	401a7000 	mfc0	k0,c0_epc
9d000128:	401b6000 	mfc0	k1,c0_status
; add immediate "unchecked": sp -= 120 ; no exception on overflow
9d00012c:	27bdff88 	addiu	sp,sp,-120
; store word:  [sp+116] := k0
9d000130:	afba0074 	sw	k0,116(sp)
9d000134:	401a6002 	mfc0	k0,c0_srsctl
9d000138:	afbb0070 	sw	k1,112(sp)
9d00013c:	afba006c 	sw	k0,108(sp)
; inserts bits from 0 reg to pos 1 and length 15
; this will zere-out bits 15 to 1 of k1 register
9d000140:	7c1b7844 	ins	k1,zero,0x1,0xf
; or immediate (set bit mask 0x400 of k1)
9d000144:	377b0400 	ori	k1,k1,0x400
; move to Coprocessor C0: C0 Status := k1
9d000148:	409b6000 	mtc0	k1,c0_status
; saving general registers on stack
; ra = return address (MIPS and ARM use dedicated register on call, not stack)
9d00014c:	afbf005c 	sw	ra,92(sp)
9d000150:	afbe0058 	sw	s8,88(sp)
9d000154:	afb90054 	sw	t9,84(sp)
9d000158:	afb80050 	sw	t8,80(sp)
9d00015c:	afaf004c 	sw	t7,76(sp)
9d000160:	afae0048 	sw	t6,72(sp)
9d000164:	afad0044 	sw	t5,68(sp)
9d000168:	afac0040 	sw	t4,64(sp)
9d00016c:	afab003c 	sw	t3,60(sp)
9d000170:	afaa0038 	sw	t2,56(sp)
9d000174:	afa90034 	sw	t1,52(sp)
9d000178:	afa80030 	sw	t0,48(sp)
9d00017c:	afa7002c 	sw	a3,44(sp)
9d000180:	afa60028 	sw	a2,40(sp)
9d000184:	afa50024 	sw	a1,36(sp)
9d000188:	afa40020 	sw	a0,32(sp)
9d00018c:	afa3001c 	sw	v1,28(sp)
9d000190:	afa20018 	sw	v0,24(sp)
9d000194:	afa10014 	sw	at,20(sp)
; move from LO (LO is lower 32-bit result of multiply:
; v0 := LO
9d000198:	00001012 	mflo	v0
9d00019c:	afa20064 	sw	v0,100(sp)
; move from HI (HI is higher 32-bit result of multiply)
9d0001a0:	00001810 	mfhi	v1
9d0001a4:	afa30060 	sw	v1,96(sp)
9d0001a8:	03a0f025 	move	s8,sp
    TIMER_1_InterruptHandler();
; "jump and link" equivalent of Call instruction
; However return address is not pushed to stack, but stored to ra register
9d0001ac:	0f400176 	jal	9d0005d8 <TIMER_1_InterruptHandler>
; fill "branch delay slot"
; MIPS actually process one additional instruction placed AFTER JUMP
; so this NOP is actually executed right before call to TIMER_1_InterruptHandler !
9d0001b0:	00000000 	nop
}
; SP := S8
9d0001b4:	03c0e825 	move	sp,s8
; Load Word: v0 := [sp+100]
9d0001b8:	8fa20064 	lw	v0,100(sp)
; move to LO: LO := v0
9d0001bc:	00400013 	mtlo	v0
9d0001c0:	8fa30060 	lw	v1,96(sp)
; move to HI: HI := v1
9d0001c4:	00600011 	mthi	v1
; restoring general registers from stack
9d0001c8:	8fbf005c 	lw	ra,92(sp)
9d0001cc:	8fbe0058 	lw	s8,88(sp)
9d0001d0:	8fb90054 	lw	t9,84(sp)
9d0001d4:	8fb80050 	lw	t8,80(sp)
9d0001d8:	8faf004c 	lw	t7,76(sp)
9d0001dc:	8fae0048 	lw	t6,72(sp)
9d0001e0:	8fad0044 	lw	t5,68(sp)
9d0001e4:	8fac0040 	lw	t4,64(sp)
9d0001e8:	8fab003c 	lw	t3,60(sp)
9d0001ec:	8faa0038 	lw	t2,56(sp)
9d0001f0:	8fa90034 	lw	t1,52(sp)
9d0001f4:	8fa80030 	lw	t0,48(sp)
9d0001f8:	8fa7002c 	lw	a3,44(sp)
9d0001fc:	8fa60028 	lw	a2,40(sp)
9d000200:	8fa50024 	lw	a1,36(sp)
9d000204:	8fa40020 	lw	a0,32(sp)
9d000208:	8fa3001c 	lw	v1,28(sp)
9d00020c:	8fa20018 	lw	v0,24(sp)
9d000210:	8fa10014 	lw	at,20(sp)
; disable interrupts
9d000214:	41606000 	di
; Execute Hazard Barrier
; this instructions ensures that CPU waits until
; all core changes are propagated and visible to next instructions
9d000218:	000000c0 	ehb
9d00021c:	8fba0074 	lw	k0,116(sp)
9d000220:	8fbb0070 	lw	k1,112(sp)
9d000224:	409a7000 	mtc0	k0,c0_epc
9d000228:	8fba006c 	lw	k0,108(sp)
9d00022c:	27bd0078 	addiu	sp,sp,120
9d000230:	409a6002 	mtc0	k0,c0_srsctl
;  Write to GPR in Previous Shadow Set
9d000234:	41dde800 	wrpgpr	sp,sp
9d000238:	409b6000 	mtc0	k1,c0_status
; Exception Return (applies also for Interrupts)
9d00023c:	42000018 	eret

There are two ways how to handle more interrupts:

  • using Shadow Set - quickly switching to other general registers set for interrupt (similar to some dsPIC chips) - ISR using SRS instead of SOFT clause.
  • Temporal proximity interrupt coalescing - interrupts are grouped and processed by single ISR (Interrupt Service Routine) - introduction is on DS61108B-page 8-31
  • please see PIC32MX Section 11 - Interrutps manual for many fine details including brief descritpion of Interrupt Service Routines (ISRs)

Here are MIPS32 resources I plan to study:

Software requirements

NOTE: To make MPLAB X IDE at least partially usable please uncheck this:

  • Tools -> Options -> Miscellaneous -> Files -> Enable auto-scanning of sources Otherwise it will hog CPU significantly...

Once you build this project there is also generated assembler listing using xc32-objdump -S in

firmware\mplabproj.X\dist\default\TARGET\mplabproj.X.TARGET.lst

pic32mx-blink's People

Contributors

hpaluch avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.