Author Topic: PIC ASM moving from Absolute to Relocatable mode  (Read 4068 times)

0 Members and 1 Guest are viewing this topic.

Offline blewisjrTopic starter

  • Frequent Contributor
  • **
  • Posts: 301
PIC ASM moving from Absolute to Relocatable mode
« on: May 02, 2013, 08:31:20 pm »
Hello Everyone,

I asked this question on the Microchip Forums but have not gotten a response yet so I decided to take a shot here as well.
Obviously I started to learn PIC ASM through Absolute Mode as this is what the tutorials which came with my PICKit used.
As I start to move to my own projects I realized I want a little more organization to the code as the projects iterate to larger firmware applications which helps design reusable code pieces across projects.  To do this efficiently will less problems I found PIC ASM also supports Relocatable asm where the linker decides where to place everything in memory while still leaving you the ability to control where something goes if you have to.

I did come across one issue that I have resolved which had to do with program entry.
The Microchip documentation did a
Reset code 0x0000
This actually generated an error saying reset was an op code so I modified the code to use
reset_vec: code 0x0000

To learn this new style of development I decided to return to the simple hello world blink led application.
If anyone here has experience with PIC relocatable asm I am essentially looking for some best practices and tip to help me with the transition.

The best way I can find for you to make suggestions would be to evaluate my hello world and show me where I made mistakes and how it could be done in a best practice way.  Yes the code works perfectly but that does not mean I am doing things correctly in a way that would aid the transition.

Code: [Select]
; =============================================================================
; Project:   Hello World
; Author:   
; Chip:      PIC16F1829
; Assembler: MPASM v5.49
; Date:      5/2/2013
; =============================================================================
; =============================================================================
; A simple program to blink an LED at a rate of approx. 1/2 second.
; =============================================================================
    #include <p16f1829.inc>

    ; Configure chip fuses
    #define CFG1A _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF
    #define CFG1B _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF

    __CONFIG _CONFIG1, CFG1A & CFG1B
    __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_ON & _LVP_OFF

    radix dec

    errorlevel -302                     ; turn off not in bank 0 warning

; =========================================================================
; Shared cross bank data
; =========================================================================
    udata_shr
cnt1 res 1
cnt2 res 1

; =========================================================================
; Start up code
; =========================================================================
reset_vec: code 0x0000                  ; Reset vector
    pagesel start
    goto start

    code
start:
    movlw B'00111000'                   ; Set cpu clock to 500kHZ
    banksel OSCCON                      ; bank1
    movwf   OSCCON                      ; Move w reg to OSCCON
    movlw 0                             ; Set cnt2 = 0
    movwf cnt2

    bcf TRISC, 0                        ; In bank1 set PORTC0 as output
    banksel LATC                        ; bank2
    bsf LATC, 0                         ; Turn on PORTC0 LED
    call delay_500ms                    ; 500ms Delay
    bcf LATC, 0                         ; Turn off PORTC0 LED
    call delay_500ms                    ; 500ms Delay
    bra start                           ; Loop forever

; =============================================================================
; 500ms Delay loop actual speed is 0.50180 seconds.
; Uses the equation {[(3 * cnt1 + 5) * cnt2] + 4} * 8uS
; cnt1 = 80 and cnt2 = 256
; =============================================================================
delay_500ms:
outer:
    movlw 80                            ; Set cnt1 = 80
    movwf cnt1
inner:
    decfsz cnt1, f                      ; Decrement cnt1 if zero skip branch
    bra inner

    decfsz cnt2, f                      ; Decrement cnt2 if zero skip branch
    bra outer
    return

    end
 

Offline croberts

  • Regular Contributor
  • *
  • Posts: 94
  • Country: us
Re: PIC ASM moving from Absolute to Relocatable mode
« Reply #1 on: May 03, 2013, 12:46:32 am »
Hello blewisjr

Usually the user memory shared space is reserved for interrupt context saving so you may want to get used to having variables in one of the banks and use banksel as required in case you want to do some interrupt routines. Software timers are a great way to do timers. You use Timer0 to generate an interrupt when it rolls over from ff to 00 and then do a combination of prescaling and loading a Timer0 start value to get the interrupt interval you want. The interrupt routine decrements the counters to 0 and then leaves them there and they are loaded with the desired time in your routines. You test them for 0 to get the desired time. If you are interested I can give you a template and some flowcharts.
 

Offline blewisjrTopic starter

  • Frequent Contributor
  • **
  • Posts: 301
Re: PIC ASM moving from Absolute to Relocatable mode
« Reply #2 on: May 03, 2013, 02:10:59 am »
No need for flowcharts I understand I can use a timer for this.  I did this more as a quick and dirty check to see if I understand the core concepts of relocatable mode asm.  Not even sure if I am going to use the PIC for this project yet.  Thanks for that tip I can see why udata_shr could be very advantageous to interrupt register saving being that it can be accessed from any bank.  Surprisingly this little excursion program taught me a lot about using the gnu assembler on avr instead of Atmel's because the gnu assembler is purely relocatable.  Again thanks for the tip.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf