/*
 * File:   LEDPWM_main.s
 * Author: Tamas Nagy
 *
 * Created on 2015.09.20
 */
/**{Description}***************************************************************
	Use Output Compare module for makeing PWM to RP4/RB4 output
*/

	.include "p24Hxxxx.inc"
	
;--{Configuration bits}--------------------------------------------------------
	;Boot Segment may be written, no Boot program Flash segment
	config	__FBS, BSS_NO_BOOT_CODE & BWRP_WRPROTECT_OFF
	;User program memory is not write-protected, user program memory is not code-protected
	config	__FGS, GWRP_OFF & GCP_OFF
	;Internal Fast RC (FRC), start-up device with FRC
	;then automatically switch to user-selected oscillator source when ready
	config	__FOSCSEL, FNOSC_FRC & IESO_OFF
	;Primary Oscillator Disabled, OSC2 pin has digital I/O function, Allow Multiple Re-configurations
	;Both Clock Switching and Fail-Safe Clock Monitor are disabled
	config	__FOSC, POSCMD_NONE & OSCIOFNC_ON & IOL1WAY_OFF & FCKSM_CSDCMD
	;Watchdog Timer Postscaler: 1:1, WDT Prescaler: 1:32, Watchdog Timer in Non-Window mode, 
	;Watchdog timer always enabled
	config	__FWDT, WDTPOST_PS1 & WDTPRE_PR32 & WINDIS_OFF & FWDTEN_OFF
	;POR Timer Value: Disabled, I2C mapped to SDA1/SCL1 pins
	config	__FPOR, FPWRT_PWR1 & ALTI2C_OFF
	;Communicate on PGC2/EMUC2 and PGD2/EMUD2, JTAG is Disabled
	config	__FICD, ICS_PGD2 & JTAGEN_OFF
;..............................................................................
;Program Specific Constants (literals used in code)
;..............................................................................
;..............................................................................
;Global Declarations:
;..............................................................................

	.global	_wreg_init	;Provide global scope to _wreg_init routine
				;In order to call this routine from a C file,
				;place "wreg_init" in an "extern" declaration
				;in the C file.

	.global	__reset		;The label for the first line of code.

;..............................................................................
;Constants stored in Program space
;..............................................................................
;..............................................................................
;Uninitialized variables in data memory
;..............................................................................
;..............................................................................
;Uninitialized variables in Near data memory (Lower 8Kb of RAM)
;..............................................................................
;..............................................................................
;Code Section in Program Memory
;..............................................................................

.text				;Start of Code section
__reset:
	MOV	#__SP_init, W15      ;Initalize the Stack Pointer
	MOV	#__SPLIM_init, W0    ;Initialize the Stack Pointer Limit Register
	MOV	W0, SPLIM
	NOP			;Add NOP to follow SPLIM initialization

	CALL	_wreg_init          ;Call _wreg_init subroutine
				;Optionally use RCALL instead of CALL

_main:
;--{Configure Device clock}---------------------------------------------------
;To set or clear IOLOCK, a specific command sequence must be executed:
	mov	#0x0046, W0	; Internal FRC osc selected (7.37MHz)
	mov	W0, OSCCON
	
	mov	#0x0057, W0	
	mov	W0, OSCCON
	
	bclr	OSCCON, #IOLOCK	; Peripheral Pin Select is unlocked
				; write to peripheral pin select register is allowed
;--{Configure IO ports}--------------------------------------------------------
	clr	PORTA
	clr	LATA
	setm	TRISA		; All PORTA pins is input
	
	clr	PORTB
	clr	LATB
	mov	#0xFFEF, W0
	mov	W0, TRISB		; PORTB.4 is digital output, others is inputs
	
	mov	#0x0012, W0
	mov	W0, RPOR2		; PORTB.4 is selected OC1 (Output Capture 1)

;--{Configure Timer2 Period register}------------------------------------------
	mov	#460, W0		; Tcy=271,3ns, PWM freq= 1kHz, PR2= 460
	mov	W0, PR2
;--{Configure Output Capture1 (PWM function)}----------------------------------	
	clr	OC1RS		; Initialize OC1RS
	
	clr	OC1R		; Initialize OC1R
	
	mov	#0x0006, W0	; PWM funtion on OC1 pin, Timer2 is the clock source for Compare 1
	mov	W0, OC1CON
;--{Configure Timer2}----------------------------------------------------------	
	clr	TMR2		; Clear Timer2 counter
	
	mov	#0x0010, W0	; Time prescaler is 1:8, Internal clock source
	mov	W0, T2CON
	bset	T2CON, #TON	; Timer2 ON

;**{MAIN LOOP}*****************************************************************
_increment:
	call	_del6.5ms		; wait 6.5ms
	inc	OC1RS		; increment OC1RS
	mov	OC1RS, W1		; test OC1RS, if OC1RS = 461 then branch to _decrement
	mov	#461, W2		; else _increment again
	sub	W1, W2, W3
	bra	NZ, _increment
	
_decrement:
	call	_del6.5ms		; wait 6.5ms
	dec	OC1RS		; decrement OC1RS, if OC1RS = 0 then branch to _increment
	bra	NZ, _decrement
	bra	_increment
;..............................................................................
;Subroutine: 
;..............................................................................
;--{Initialization of W registers to 0x0000}-----------------------------------
_wreg_init:
	CLR	W0
	MOV	W0, W14
	REPEAT	#12
	MOV	W0, [++W14]
	CLR	W14
	RETURN
;--{500us delay}---------------------------------------------------------------	
_del6.5ms:		; 6.5ms delay
	repeat	#12000	; 24000 x 271,3ns = approx. 6.5ms
	nop
	repeat	#12000	
	nop
	nop
	return
	
;--------End of All Code Sections ---------------------------------------------

	.end			;End of program code in this file
