PDA

View Full Version : Help! Need Programming Help!


DubbleD
Mar 27, 2009, 04:26 PM
Hey Guys! I'm really new to programming PICs, I used to program in BASIC many years ago, but I'm having some trouble getting all my ducks in a row with the new stuff, so I need to ask some questions. I've built several of the navigation light projects out there and they're all great, but now I want to learn to do it myself, to make the program do exactly what I want it to do.

I found a program that was designed to flash a pair of LEDs, that I wanted to use for strobe lights on an RC aircraft. It flashed two different LEDs, each in a double-blink pattern, but for some reason they didn't blink at the same rate, so they would start out blinking in an alternating pattern, first one, then the other, but then after a few seconds they would actually be blinking in sync with each other, both at the same time, then they would gradually drift back apart for a while, and so on and so on. Not cool looking, watching them made my eyes cross, I was afraid I'd get hypnotized and crash. So I found a different program that also flashed two LEDs, one after another, but they only blinked once each, and they stayed on about 1/2 second each, too slow and too long to simulate aircraft strobes. I have managed to figure out the program enough to change the variable that controls the length of time each LED stays on, so I can make them both flash very quickly, like a strobe, but only once each, back and forth. I need to somehow interrupt the program with a loop that blinks each LED twice before switching to the other LED. Here is the portion of the program that controls the flash of the LEDs, and I'll try to give all the info about it I can think of.

;----------------------------------------------
;-------FLASH STROBE LIGHTS (T1;;STRB1;;STRB2;;TMR4)
K5_____DECFSZ TMR4,F
_______GOTO MAIN
_______MOVLW T1_______;RESTORE TMR4
_______MOVWF TMR4
_______BTFSS GPIO,STRB1
_______GOTO K6________;LSTA=0
_______BCF GPIO,STRB1__;LSTA=1
_______BSF GPIO,STRB2
_______GOTO MAIN
K6_____BSF GPIO,STRB1__;LSTA=0
_______BCF GPIO,STRB2
_______GOTO MAIN
;----------------------------------------------
_______END

Sorry about all the underlines-the forum wouldn't let me cut and paste from the .asm file, it ignored my spaces and kept cramming all the words next to each other, so I had to use underlines to make it readable.

T1 is the variable that controls how long the LED stays "on", TMR4 is the timer that controls (I think) how long it takes the program to loop around again, STRB1 and STRB2 are the two LEDs. As you can see, the program looks to see if STRB1 is set, if not then it goes to K6 and sets STRB1 and clears STRB2, then the program loops around and the next time through it does just the opposite, which makes the two LEDs flash alternately. I've discovered that the LED is actually "on" when the bit is cleared, (BCF GPIO,STRB1) is that correct??

OK, here's where I need HELP! I've experimented some by modifying the .asm file and re-compiling it, the compiler didn't report any errors and so I programmed my PIC with the new .hex file, but I got OSC errors and it rendered my chip unusable, so I'm running out of PICs! Here's what I'd like to be able to do......I want each LED to blink twice while the other LED remains off. I can get the blink rate to where it needs to be by adjusting the value of T1, but every time either LED is turned off, the other is turned on, so all I'm getting is a rapid, alternating flashing back and forth of both LEDs. I'm thinking I need to insert another variable that I can count up (INCF) or down (DECF) that will cause the program to bypass the line that turns the other LED on, and forces it to loop around and flash the same LED again, then the next time through maybe use the DECFSZ command to send it to the second section that flashes the opposite LED, and do the same thing in that section. But I can't figure out exactly where to put it or how. Does that make any sense? Can anybody help me with this? I've tried to do it but I'm making some kind of mistake that either causes it to not work, or worse yet frys my chip.

I know it's hard to help someone that doesn't understand any more than I do, so I apologize. I'm sure these are stupid questions to most of you guys, but I'm trying really hard to learn this stuff. I just this morning figured out how define my PIC and set the config fuses in the program so I wouldn't have to remember to do it manually before programming it. :D

Thanks if you can help.

DubbleD (Dumb and Dumber)

Malc C
Mar 27, 2009, 05:36 PM
The following code worked for me using a 12F675 PIC. I'm sure you can modify it to suit your needs. It basically double flashes three LEDs in sequence.. ie

flash,flash....flash,flash....flash,flash


list p=12F675
#include "p12f675.inc"

__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _CPD_OFF

del_lo equ 0x20
del_hi equ 0x21

org 0x00
nop
goto init

org 0x04
return

init
banksel 0x80 ;select upper register bank
clrf ANSEL ;make all I/O ports digital
movlw 0x0B
movwf TRISIO ;make GP4 and GP5 outputs
banksel 0x00 ;select lower register bank
clrf GPIO ;initialise all outputs
clrf del_lo ;initialise delay counter low byte
clrf del_hi ;initialise delay counter high byte

flash
bsf GPIO,4 ;set output GP4 high
movlw 0x45
movwf del_hi
call delay ;call the delay subroutine

bcf GPIO,4 ;set output GP4 low
movlw 0x45
movwf del_hi
call delay ;call the delay subroutine

bsf GPIO,4 ;set output GP4 high
movlw 0x45
movwf del_hi
call delay ;call the delay subroutine

bcf GPIO,4 ;set output GP4 low
movlw 0xFF
movwf del_hi
call delay ;call the delay subroutine


bsf GPIO,2 ;set output GP4 high
movlw 0x45
movwf del_hi
call delay ;call the delay subroutine

bcf GPIO,2 ;set output GP4 low
movlw 0x45
movwf del_hi
call delay ;call the delay subroutine

bsf GPIO,2 ;set output GP4 high
movlw 0x45
movwf del_hi
call delay ;call the delay subroutine

bcf GPIO,2 ;set output GP4 low
movlw 0xFF
movwf del_hi
call delay ;call the delay subroutine

bsf GPIO,5 ;set output GP4 high
movlw 0x45
movwf del_hi
call delay ;call the delay subroutine

bcf GPIO,5 ;set output GP4 low
movlw 0x45
movwf del_hi
call delay ;call the delay subroutine

bsf GPIO,5 ;set output GP4 high
movlw 0x45
movwf del_hi
call delay ;call the delay subroutine

bcf GPIO,5 ;set output GP4 low
movlw 0xFF
movwf del_hi
call delay ;call the delay subroutine

goto flash ;go back and do it again

delay
decfsz del_lo,f ;decrement the low order delay register
goto delay ;go back if it hasn't reached zero
decfsz del_hi,f ;decrement the high order delay register
goto delay ;go back if it hasn't reached zero
return ;return to where the subroutine was called

end


If you change the value of the line movlw 0x45 the delay rate between the flashes change

Hope this helps

DubbleD
Mar 27, 2009, 06:26 PM
Thanks Malc C, with a little more help I think I can make that work. I see that you have three different sections that output to pins 4,2, and 5, in that order, so I think I can handle changing the code to output to the pins I have empty for my strobes. Am I correct in thinking that if I want to change the amount of delay between the pairs of flashes, not between each flash, I would change the values of the "del_lo equ 0x20" and/or "del_hi equ 0x21" lines at the beginning of the program? The reason I'm asking is that if I don't, it seems like there would be a pause in my program between the flash cycles of my two strobes if I only use two of the three sections you have. Is that right?

One more question, what does the code after the del_lo and before the init section do? Is it important to the flash timing?

OK, I lied. Two more questions. Do I need to insert the "del_lo/del_hi" and "init" sections at the beginning of my program, or just at the beginning of the FLASH portion of my program?

Thanks for your help. I know these are really elemetary questions, but I think I'm learning something.

DD

Malc C
Mar 28, 2009, 09:25 AM
To be perfectly honest, its a long time since I got involved with that code. It was my first "tutorial" on assembly, and it sank in so much that I never used assembly again and switched to PicBASIC as, like you have a better understanding of the BASIC commands and logic. From memory the delay routine simply counts down a register until it reaches 0, so not sure on how to actually change the delay between each sets of flashes. I'm hoping some of the more experienced assembly coders here can chip in and offer you some advice.

The alternative would be to download and use the excellent Microbasic application and re-write your code in basic...

robe_uk
Mar 28, 2009, 12:16 PM
del_lo equ 0x20
del_hi equ 0x21 these two lines are defining general purpose RAM resistors used by the program for counters or the like.

org 0x00 Tells assembler program where to put the following code 0x00 is the start of code point for the 675
nop
goto init This tells program to goto init, which is the start of the program

org 0x04 0x04 is the interupt vector for the 675, if there was an interupt, which acts like a call command the next line just makes it return
return

OK, I lied. Two more questions. Do I need to insert the "del_lo/del_hi" and "init" sections at the beginning of my program, or just at the beginning of the FLASH portion of my program?

del_lo/del_hi = as above defining general RAM resistors, I tend to do the following,

cblock 0x20
del_lo
del_hi
etc....

endc

This lets me define general purpose registors quickly, check data sheets to see how many are available to you.

The init section is setting up ports etc and only has to be done once.

The way I tend to lay out a program is;

define processor and fuses
define my RAM registors
define things for assembler, ie if using PORTA is a servo output port I would write
#define servoport PORTA; or servoport equ PORTA, this means any time I refer to PORTA in my program I use servoport so if i change my mind and decide to use PORTB i only have to change one line of code.

Then I have my main program
Main:
call init ;initalize ports etc, only tends to be done once so at start of Main. which I put in a subroutine out of the way at bottom of code,
Mainloop: ;I tend to split everything into smaller sub routines and loop around calling them.
call checksomething
call do some maths
call output something
goto Mainloop


I have very limited programming knowledge (so hopefully those who do dont laugh to loudly at me :o )but know enough the assembly takes a lot of lines to do very little, am to lazy to learn 'c' or something

Alison F
Mar 28, 2009, 12:46 PM
Hi DD,

Have you seen the PICLIST site on the net? I found that really useful when I was starting out. http://www.piclist.com/techref/microchip/index.htm

I work with PICs for a living, and mostly once you have your basic construct and outline established then everything else goes on top. Here...

This is a cut down version btw, with most of my core code chopped out.


;------------------------------------------------------------------------------

;0.0.Project Summary

;------------------------------------------------------------------------------

;Immiediate release version: 0.06

;*

; _MCLRE_OFF

; _CP_ON

; _DATA_CP_ON





;------------------------------------------------------------------------------

;0.1.Compiler setup

;------------------------------------------------------------------------------

LIST P=16F627A, R=DEC ;16F627, decimal system

#include "P16F627A.INC" ;link pre-defines, standard EQU's etc.



;LIST P=16F648A, R=DEC ;16F627, decimal system

;#include "P16F648A.INC" ;link pre-defines, standard EQU's etc.



__idlocs 0x0061 ;give the chip an ID word number



;set the config/fuse string

__config _INTOSC_OSC_NOCLKOUT & _PWRTE_ON & _LVP_OFF & _WDT_OFF & _BOREN_ON & _MCLRE_OFF & _CP_ON & _DATA_CP_ON



ERRORLEVEL -302 ;remove message about using proper bank





;------------------------------------------------------------------------------

;0.2.Constants and equates

;------------------------------------------------------------------------------

;port assignments of the uart

RS232_RX_PORTB_ EQU 1

RS232_TX_PORTB_ EQU 2



;psx port assignments

PSX_DAT_PORTB_I_ EQU 7

PSX_CMD_PORTB_O_ EQU 4

PSX_CLK_PORTB_O_ EQU 6

PSX_ACK_PORTB_I_ EQU 5

PSX_ATN_PORTB_O_ EQU 3

PSX_MASK_TRISB_ EQU b'10100010'









;amiga mouse assignments

AMIGA_YB_PORTA_ EQU 7 ;RA7 - Pin 16 ;DTYPE - Pin 1

AMIGA_XA_PORTA_ EQU 0 ;RA0 - Pin 17 ;DTYPE - Pin 2

AMIGA_YA_PORTA_ EQU 4 ;RA4 - Pin 3 ;DTYPE - Pin 3

AMIGA_XB_PORTA_ EQU 3 ;RA3 - Pin 2 ;DTYPE - Pin 4

;AMIGA_MB_PORTA_ EQU 2 ;RA2 - Pin 1 ;DTYPE - Pin 5

;AMIGA_LB_PORTA_ EQU 6 ;RA6 - Pin 15 ;DTYPE - Pin 6

;AMIGA_RB_PORTA_ EQU 1 ;RA1 - Pin 18 ;DTYPE - Pin 9



;atari mouse assignments

ATARI_XB_PORTA_ EQU 7 ;RA7 - Pin 16 ;DTYPE - Pin 1

ATARI_XA_PORTA_ EQU 0 ;RA0 - Pin 17 ;DTYPE - Pin 2

ATARI_YA_PORTA_ EQU 4 ;RA4 - Pin 3 ;DTYPE - Pin 3

ATARI_YB_PORTA_ EQU 3 ;RA3 - Pin 2 ;DTYPE - Pin 4

ATARI_XB_PORTA_BIT_ EQU b'10000000' ;RA7 - Pin 16 ;DTYPE - Pin 1

ATARI_XA_PORTA_BIT_ EQU b'00000001' ;RA0 - Pin 17 ;DTYPE - Pin 2

ATARI_YA_PORTA_BIT_ EQU b'00010000' ;RA4 - Pin 3 ;DTYPE - Pin 3

ATARI_YB_PORTA_BIT_ EQU b'00001000' ;RA3 - Pin 2 ;DTYPE - Pin 4







;ATARI_LB_PORTA_ EQU 6 ;RA6 - Pin 15 ;DTYPE - Pin 6

;ATARI_RB_PORTA_ EQU 1 ;RA1 - Pin 18 ;DTYPE - Pin 9









;atari joystick assignments

ATARI_UP_PORTA_ EQU 7 ;RA7 - Pin 16 ;DTYPE - Pin 1

ATARI_DOWN_PORTA_ EQU 0 ;RA0 - Pin 17 ;DTYPE - Pin 2

ATARI_LEFT_PORTA_ EQU 4 ;RA4 - Pin 3 ;DTYPE - Pin 3

ATARI_RIGHT_PORTA_ EQU 3 ;RA3 - Pin 2 ;DTYPE - Pin 4

ATARI_BUT1_PORTA_ EQU 6 ;RA6 - Pin 15 ;DTYPE - Pin 6

ATARI_BUT2_PORTA_ EQU 1 ;RA1 - Pin 18 ;DTYPE - Pin 9

ATARI_BUT3_PORTA_ EQU 2 ;RA2 - Pin 1 ;DTYPE - Pin 5 (7800)



;psx button encoding

PSX_BYTE4_LEFT_ EQU 7

PSX_BYTE4_DOWN_ EQU 6

PSX_BYTE4_RIGHT_ EQU 5

PSX_BYTE4_UP_ EQU 4

PSX_BYTE4_START_ EQU 3

PSX_BYTE4_RIGHT_THUMB_ EQU 2

PSX_BYTE4_LEFT_THUMB_ EQU 1

PSX_BYTE4_SELECT_ EQU 0



PSX_BYTE5_L2_ EQU 7

PSX_BYTE5_R2_ EQU 6

PSX_BYTE5_L1_ EQU 5

PSX_BYTE5_R1_ EQU 4

PSX_BYTE5_TRIANGLE_ EQU 3

PSX_BYTE5_O_ EQU 2

PSX_BYTE5_X_ EQU 1

PSX_BYTE5_SQUARE_ EQU 0



;psx control flags

PSX_SELECT_CMD_FLAG_BUSY_ EQU 0

PSX_START_VAR_FLAG_BUSY_ EQU 1

PSX_ANALOGUE_MODE_ EQU 4

PSX_REPEAT_LEFTRIGHT_ EQU 5

PSX_REPEAT_TOGGLE_ EQU 6

PSX_REPEAT_TOGGLE_XOR_ EQU b'01000000'

PSX_COMMAND_AWAITING_ EQU 7



;EQU's relating to the rs232 messages stored in EEPROM

RS232_EE_MESSAGE_RESET_ EQU 1

RS232_EE_MESSAGE_MARKER_ EQU 7 ;this identifies the start of a message



;setup_config_flags_

SETUP_CONFIG_FLAG_ATARI_ EQU 0 ; -------x ;0x00 = 1 = ATARI ST Mouse , 0 = AMIGA

; ------x- ;0x01 =

; -----x-- ;0x02 =

; ----x--- ;0x03 =

; ---x---- ;0x04 =

; --x----- ;0x05 =

SETUP_CONFIG_FLAG_RIGHT_THUMB_ EQU 6 ; -x------ ;0x06 = 1 = LEFT THUMBSTICK , 0 = RIGHTTHUMBSTICK

SETUP_CONFIG_FLAG_PIN5_ EQU 7 ; x------- ;0x07 = Pin 5 / 7800 Enabled on DIGITAL

SETUP_CONFIG_FLAG_PIN5_XOR_ EQU b'10000000'

SETUP_CONFIG_FLAG_ATARI_XOR_ EQU b'00000001'

SETUP_CONFIG_FLAG_RT_THUMB_XOR_ EQU b'01000000'



;deciphering the PSX packets with mouse

MOUSE_FLAGS_RIGHT_ EQU 0x01 ; -------x ;1 = RIGHT, 0 = LEFT

MOUSE_FLAGS_UP_ EQU 0x02 ; ------x- ;1 = UP, 0 = DOWN

MOUSE_FLAGS_DIR_ EQU 0x03 ; -----x-- ;1 = RIGHT/DOWN, 0 = LEFT/UP

MOUSE_FLAGS_ANAL_THUMB_ EQU 0x04 ; -x------ ;1 = there was thumbstick movement

MOUSE_FLAGS_Y_MOVEMENT_ EQU 0x05 ; --x----- ;1 = there is y movement

MOUSE_FLAGS_X_MOVEMENT_ EQU 0x06 ; -x------ ;1 = there is x movement

MOUSE_FLAGS_ANALOGUE_ EQU 0x07 ; x------- ;1 = ANALOGUE



MOUSE_QA_STARTUP_ EQU b'01100110' ;initial quadrature position

MOUSE_QB_STARTUP_ EQU b'11001100' ;initial quadrature position



;quadrature delay values

MOUSE_DELAY_PAD_X_ EQU 5d

MOUSE_DELAY_PAD_Y_ EQU 5d

MOUSE_DELAY1_THUMB_X_ EQU 3d

MOUSE_DELAY1_THUMB_Y_ EQU 3d

MOUSE_DELAY2_THUMB_X_ EQU 2d

MOUSE_DELAY2_THUMB_Y_ EQU 2d

MOUSE_DELAY3_THUMB_X_ EQU 1d

MOUSE_DELAY3_THUMB_Y_ EQU 1d





;------------------------------------------------------------------------------

;0.3.Function Variables (80 bytes in bank 0, 20h-6Fh)

;------------------------------------------------------------------------------

;0020 to 002F (16 bytes)

CBLOCK 0x20

psx_tx_byte_ ;the byte to be transmitted

psx_rx_byte_ ;the byte being received

psx_rx_byte1_

psx_rx_byte2_ ;

psx_rx_byte3_ ;Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7 - PSX

psx_rx_byte4_ ;SLCT STRT UP RGHT DOWN LEFT

psx_rx_byte5_ ;L2 R2 L1 R1 /\ O X |_|

psx_rx_byte6_ ;RIGHT JOY, 0x00 = LEFT, 0xFF = RIGHT

psx_rx_byte7_ ;RIGHT JOY, 0x00 = UP, 0xFF = DOWN

psx_rx_byte8_ ;LEFT JOY, 0x00 = LEFT, 0xFF = RIGHT

psx_rx_byte9_ ;LEFT JOY, 0x00 = UP, 0xFF = DOWN

ENDC





;0030 to 003F (16 bytes)

CBLOCK 0x30

psx_byte4_tally_ ;we use this to gather our SELECT presses from the other buttons

psx_byte5_tally_ ;we use this to gather our SELECT presses from the fire buttons

psx_control_flags_ ; -------x ;0x00 = PSX_SELECT_CMD_FLAG_BUSY_

; ------x- ;0x01 = PSX_START_VAR_FLAG_BUSY_

; -----x-- ;0x02 =

; ----x--- ;0x03 =

; ---x---- ;0x04 = PSX_ANALOGUE_MODE_

; --x----- ;0x05 = PSX_REPEAT_LEFTRIGHT_

; -x------ ;0x06 = PSX_REPEAT_TOGGLE_

; x------- ;0x07 = PSX_COMMAND_AWAITING_



psx_byte4_select_cmd_ ;the command captured goes in here

psx_byte5_select_cmd_ ;the command captured goes in here

psx_byte4_start_var_ ;the variable captured goes in here

psx_byte5_start_var_ ;the variable captured goes in here

ENDC



;0040 to 004F (16 bytes)

CBLOCK 0x40

setup_button1_mask_ ;the following 9 bytes HAVE to always be here

setup_button2_mask_ ;as we're going to be writing straight into memory

setup_button3_mask_

setup_button1_repeat_mask_

setup_button2_repeat_mask_

setup_button3_repeat_mask_

setup_leftright_mask_

setup_repeat_rate_

setup_config_flags_

atari_tx_byte_ ;this byte is the shadow of PORTA

setup_mask_result_ ;we AND this with the current packet

setup_repeat_rate_counter_ ;this is what we compare to.



ENDC



;0050 to 005F (16 bytes)

CBLOCK 0x50

mouse_control_flags_ ; -------x ;0x00 = 0 = UP, 1 = DOWN

; ------x- ;0x01 = 0 = LEFT, 1 = RIGHT

; -----x-- ;0x02 =

; ----x--- ;0x03 =

; ---x---- ;0x04 =

; --x----- ;0x05 =

; -x------ ;0x06 =

; x------- ;0x07 = 0 = DIGITAL, 1 = ANALOGUE

mouse_pwm_xa_ ; these store the pwm quadrature counter

mouse_pwm_xb_ ; these store the pwm quadrature counter

mouse_pwm_ya_ ; these store the pwm quadrature counter

mouse_pwm_yb_ ; these store the pwm quadrature counter

mouse_delay_digital_x_ ; this is the delay applied to the digital pad

mouse_delay_digital_y_ ; this is the delay applied to the digital pad

mouse_delay_analogue_x_ ; this is the delay applied to the analogue stick

mouse_delay_analogue_y_ ; this is the delay applied to the analogue stick

mouse_value_thumb_x_ ;

mouse_value_thumb_y_ ;





ENDC



;------------------------------------------------------------------------------

;0.4.Global Variables (16 bytes in all banks, 70h-7Fh)

;------------------------------------------------------------------------------

;0070 to 007F (16 bytes)

CBLOCK 0x70

vec_pushed_w_buffer_ ;must be visible from every bank

vec_pushed_status_buffer_ ;must be visible from every bank

ee_byte_ ;must be visible from every bank

ee_pointer_ ;must be visible from every bank

bank1_pass_ ;must be visible from every bank

loop1_ ;must be visible from every bank

temp1_

rs232_byte_

rs232_ee_message_counter_

ENDC



;------------------------------------------------------------------------------

;1.0.Core Program Code begins (1024 bytes)

;------------------------------------------------------------------------------

ORG 0x000 ;(0d) 128bytes allocated

GOTO Start ;goto start of program



ORG 0x004 ;start of interupt vector

GOTO Interrupt_Vector





;------------------------------------------------------------------------------

;1.1.Start

;------------------------------------------------------------------------------

Start:

CLRW

CALL SETUP_LOAD_EEPROM ;load the SETUP0 defaults from EEPROM



CALL SETUP_VARS ;set everything to default start values, flags etc.

CALL SETUP_PORTS ;set the ports up, 7800 port etc.



MOVLW RS232_EE_MESSAGE_RESET_

CALL RS232_OUTPUT_EE_MESSAGE ;send our alive message



CALL SETUP_TMR0





;------------------------------------------------------------------------------

;1.2.Main

;-------------------------------------------------------------------------------

Main_loop_begins:

BTFSS psx_control_flags_, PSX_COMMAND_AWAITING_

GOTO Main_loop_ends



BCF INTCON, T0IE ;disable TIMER0 interrupt

BCF INTCON, GIE

BTFSS psx_byte4_select_cmd_, PSX_BYTE4_START_ ;is this an 01 command which doesn't have variables?

CALL CMD_HANDLER_01



BTFSC psx_byte4_select_cmd_, PSX_BYTE4_START_ ;is this an 09 command which does have variables?

CALL CMD_VAR_HANDLER_09



BCF psx_control_flags_, PSX_COMMAND_AWAITING_ ;don't come back here again



BSF INTCON, GIE

BSF INTCON, T0IE ;enable TIMER0 interrupt



Main_loop_ends:



GOTO Main_loop_begins





;------------------------------------------------------------------------------

;1.3.Interrupt Vector

;------------------------------------------------------------------------------

Interrupt_Vector:

Vec_push:

;W and STATUS will be pushed when these interrupts are branched to

MOVWF vec_pushed_w_buffer_ ;1;store W immiediately!!

MOVF STATUS, W ;store status

MOVWF vec_pushed_status_buffer_

BCF STATUS, RP0 ;ensure that we're actually in bank0 right now!!



CALL INT_SERVICE_INTERRUPTS ;we have to call as we need to pop afterwards

Vec_pop:

MOVF vec_pushed_status_buffer_, W ;in reverse order

MOVWF STATUS

MOVF vec_pushed_w_buffer_, W ;restore ready to return



RETFIE





;------------------------------------------------------------------------------

;1.4.Service Interrupts

;------------------------------------------------------------------------------

INT_SERVICE_INTERRUPTS

;all other interrupts we ignore, they shouldn't occur anyway



Int_service_disconnected:

CALL PSX_GET_PACKET

;If the controller is disconnected then 0xFF will be returned in psx_rx_byte_5

INCFSZ psx_rx_byte2_, F

GOTO Int_service_connected



MOVLW 'Q'

CALL RS232_SEND_BYTE



;MOVLW 0x11

;CALL RS232_OUTPUT_HEX_BYTE

;MOVLW 0x00

;CALL RS232_OUTPUT_HEX_BYTE

;CALL RS232_OUTPUT_CRLF

;CALL RS232_OUTPUT_CRLF





GOTO Int_service_disconnected

Int_service_connected:

DECF psx_rx_byte2_, F



;We have to decide here what to do.

;Firstly, is SELECT being pressed?

;If it is then we're not going to be doing anything else on this occasion.



;Ahhh, but have we already collected a command, and are now collecting the data?

;This bit is VERY important, as the only thing that can stop it now is START being pressed.

BTFSC psx_control_flags_, PSX_START_VAR_FLAG_BUSY_

GOTO Int_service_collecting_var



BTFSS psx_rx_byte4_, PSX_BYTE4_SELECT_ ;active low

GOTO Int_service_collecting_cmd ;go and collect a command



;We can also end up here if SELECT has just been released.

;psx_control_flags_, PSX_SELECT_FLAG_BUSY_ will still be set from when we were collecting the command

;Let's see if it's still set...

BTFSC psx_control_flags_, PSX_SELECT_CMD_FLAG_BUSY_ ;This will only be set if there's a new command waiting

GOTO Int_service_command_collected ;If it is, then go and do something about it!



;No, none of that lot up above, so let's carry on like we would 99% of the time



INCF setup_repeat_rate_counter_, F



MOVF setup_repeat_rate_, W ;this is our repeat rate to match against

XORWF setup_repeat_rate_counter_, W

BTFSC STATUS, Z

GOTO Int_service_repeat_toggle

GOTO Int_service_skip_repeat_toggle

Int_service_repeat_toggle:



MOVLW PSX_REPEAT_TOGGLE_XOR_

XORWF psx_control_flags_, F



CLRF setup_repeat_rate_counter_ ;start the counter again



;BTFSS psx_control_flags_, PSX_REPEAT_TOGGLE_

;MOVLW '0'

;BTFSC psx_control_flags_, PSX_REPEAT_TOGGLE_

;MOVLW '1'

;CALL RS232_SEND_BYTE

;MOVLW 'R'

;CALL RS232_SEND_BYTE



Int_service_skip_repeat_toggle:



BTFSS psx_control_flags_, PSX_ANALOGUE_MODE_ ;have we received an analogue packet?

GOTO Int_service_packet_is_digital

Int_service_packet_is_analogue:



CALL PSX_TO_MOUSE ;we're in analogue mode

BCF psx_control_flags_, PSX_ANALOGUE_MODE_ ;clear this occurance



GOTO Int_service_complete ;we're not gathering a command, so finish up



Int_service_packet_is_digital:

CALL PSX_TO_ATARI_JOY ;we're in digital mode



GOTO Int_service_complete ;we're not gathering a command, so finish up











Int_service_collecting_cmd:

CALL PSX_GATHER_SELECT_CMD_INPUT

GOTO Int_service_complete



Int_service_command_collected:

;We are here as a command has been collected

;So let's save that command

MOVF psx_byte4_tally_, W

MOVWF psx_byte4_select_cmd_

MOVF psx_byte5_tally_, W

MOVWF psx_byte5_select_cmd_

;We also won't be coming here again either

BCF psx_control_flags_, PSX_SELECT_CMD_FLAG_BUSY_ ;we won't come here again this time



;But is there variable data still to collect too before we finish here?

;If START "was" pressed, then yes there is

; CLRF psx_byte4_start_var_ ;these DO NOT have to actually be cleared here

; CLRF psx_byte5_start_var_ ;it's just that on RS232 it gets confusing if there's junk data!!



BTFSS psx_byte4_select_cmd_, PSX_BYTE4_START_

GOTO Int_service_command_ready



CLRF psx_byte5_tally_ ;clear the tally

CLRF psx_byte4_tally_

BSF psx_control_flags_, PSX_START_VAR_FLAG_BUSY_ ;

;Now we start collecting data next time round!!!!!



GOTO Int_service_complete



Int_service_collecting_var:

;We're here as we're collecting buttons

;The ONLY thing that can stop this is START

COMF psx_rx_byte5_, W

IORWF psx_byte5_tally_, F

COMF psx_rx_byte4_, W

IORWF psx_byte4_tally_, F



BTFSS psx_byte4_tally_, PSX_BYTE4_START_ ;Has START been pressed?

GOTO Int_service_complete

;Yes!!! It bloody well has!!



BCF psx_control_flags_, PSX_START_VAR_FLAG_BUSY_

MOVF psx_byte4_tally_, W

MOVWF psx_byte4_start_var_

MOVF psx_byte5_tally_, W

MOVWF psx_byte5_start_var_



;That's it!! We're done here!!!



Int_service_command_ready:



BSF psx_control_flags_, PSX_COMMAND_AWAITING_



Int_service_complete:



BCF INTCON, T0IF ;clear the TMR0 interrupt flag



RETURN


;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

;0.0.Setup, Support, and RS232 procedures begin (256 bytes)

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

ORG 0300H



;------------------------------------------------------------------------------

;Subroutine : PSX_GET_PACKET

;------------------------------------------------------------------------------

;Passed : N/A

;Valid : N/A

;Uses : psx_rx_byte1_ thru psx_rx_byte9_

;Returns : psx_rx_byte?_ contains valid bytes

;Error Code : W contains FF in event of disconnected controller

;Error Trapping : N/A

;Outline : Receives DIGITAL 5-Byte or ANALOGUE 8-Byte packets

;------------------------------------------------------------------------------

PSX_GET_PACKET

BSF PORTB, PSX_CLK_PORTB_O_ ;set CLOCK high

BSF PORTB, PSX_CMD_PORTB_O_ ;set COMMAND high

BCF PORTB, PSX_ATN_PORTB_O_ ;bring ATTENTION low, start



MOVLW 0x01 ;psx start command

MOVWF psx_tx_byte_

CALL PSX_RW_BYTE

MOVWF psx_rx_byte1_

MOVLW 0x42 ;psx request data command

MOVWF psx_tx_byte_

CALL PSX_RW_BYTE

MOVWF psx_rx_byte2_

MOVLW 0xFF ;CMD idle, no command

MOVWF psx_tx_byte_

CALL PSX_RW_BYTE

MOVWF psx_rx_byte3_

MOVLW 0xFF ;idle, no command

MOVWF psx_tx_byte_

CALL PSX_RW_BYTE

MOVWF psx_rx_byte4_

MOVLW 0xFF ;idle, no command

CALL PSX_RW_BYTE

MOVWF psx_rx_byte5_

;0x41 = digital, 2 bytes data

;0x53 = analogue green, 6 bytes data

;0x73 = analogue red, 6 bytes data

BTFSS psx_rx_byte2_, 0x01 ;test for analogue pad

GOTO Psx_get_packet_done



BSF psx_control_flags_, PSX_ANALOGUE_MODE_ ;set the flag to identify analogue mode



MOVLW 0xFF ;idle, no command

CALL PSX_RW_BYTE

MOVWF psx_rx_byte6_

MOVLW 0xFF ;idle, no command

CALL PSX_RW_BYTE

MOVWF psx_rx_byte7_

MOVLW 0xFF ;idle, no command

CALL PSX_RW_BYTE

MOVWF psx_rx_byte8_

MOVLW 0xFF ;idle, no command

CALL PSX_RW_BYTE

MOVWF psx_rx_byte9_

Psx_get_packet_done:

BSF PORTB, PSX_CLK_PORTB_O_ ;bring clock high

BSF PORTB, PSX_ATN_PORTB_O_ ;bring ATTENTION high, finish

RETURN





;------------------------------------------------------------------------------

;Subroutine : PSX_RW_BYTE

;------------------------------------------------------------------------------

;Passed : W contains byte to be transmitted

;Valid : N/A

;Uses : psx_tx_byte_ , psx_rx_byte_ , loop1_

;Returns : Byte received in W and psx_rx_byte_

;Error Code : N/A

;Error Trapping : N/A

;Outline : SPI style byte transfer

;------------------------------------------------------------------------------

PSX_RW_BYTE

MOVWF psx_tx_byte_



MOVLW 8d ;we will be transferring 8 bits

MOVWF loop1_

Psx_rw_byte_next_bit:

BCF PORTB, PSX_CLK_PORTB_O_ ;bring clock low



RRF psx_tx_byte_, F ;put transmitted data on bus

BTFSS STATUS, C

BCF PORTB, PSX_CMD_PORTB_O_

BTFSC STATUS, C

BSF PORTB, PSX_CMD_PORTB_O_



BSF PORTB, PSX_CLK_PORTB_O_ ;bring clock high



BCF STATUS, C

BTFSC PORTB, PSX_DAT_PORTB_I_ ;get received data from bus

BSF STATUS, C

RRF psx_rx_byte_, F



DECFSZ loop1_, F

GOTO Psx_rw_byte_next_bit ;next bit



BSF PORTB, PSX_CMD_PORTB_O_ ;set COMMAND high



MOVF psx_rx_byte_, W ;value returned to caller



RETURN





;------------------------------------------------------------------------------

;Subroutine : SETUP_PORTS

;------------------------------------------------------------------------------

;Passed : N/A

;Valid : N/A

;Uses :

;Returns : N/A

;Error Code : N/A

;Error Trapping : N/A

;Outline : Sets the ports up for first time use

;------------------------------------------------------------------------------

SETUP_PORTS

MOVLW b'00000111' ;07 into register, port A pins

MOVWF CMCON ;Comparators off, all pins digital I/O



MOVF setup_config_flags_, W

MOVWF ee_byte_ ;put into a bank 1 variable



CLRF PORTA ;all ports low by default

CLRF PORTB ;all ports low by default



BSF STATUS, RP0 ;0003h, 0005h, select RAM bank 1

BCF OPTION_REG, NOT_RBPU ;enable portb weak pull-ups, clear=enable

CLRF TRISA ;all pins as outputs by default

BTFSS ee_byte_, SETUP_CONFIG_FLAG_PIN5_

BSF TRISA, ATARI_BUT3_PORTA_ ;set as an input



MOVLW PSX_MASK_TRISB_

MOVWF TRISB



;Setup baud rate = 19200, No Parity, 1 Stop Bit

MOVLW 0x19 ;0x19=9600 bps, 0x0C=19200 bps, 0x06=38400

MOVWF SPBRG

MOVLW b'00100100' ;brgh = high (2)

MOVWF TXSTA ;enable async transmission, set brgh

BCF STATUS, RP0 ;0003h, 0005h, select RAM bank 0

MOVLW b'10010000' ;enable async reception

MOVWF RCSTA

;allow RS232 to settle

MOVF RCREG, W

MOVF RCREG, W

MOVF RCREG, W ;flush receive buffer



RETURN



;------------------------------------------------------------------------------

;Subroutine : SETUP_7800_PORT

;------------------------------------------------------------------------------

;Passed : N/A

;Valid : N/A

;Uses :

;Returns : N/A

;Error Code : N/A

;Error Trapping : N/A

;Outline : Sets the ports up for first time use

;------------------------------------------------------------------------------

SETUP_7800_PORT

MOVF setup_config_flags_, W

MOVWF ee_byte_ ;put into a bank 1 variable

BSF STATUS, RP0 ;0003h, 0005h, select RAM bank 1

BTFSS ee_byte_, SETUP_CONFIG_FLAG_PIN5_

BSF TRISA, ATARI_BUT3_PORTA_ ;set as an input

BTFSC ee_byte_, SETUP_CONFIG_FLAG_PIN5_

BCF TRISA, ATARI_BUT3_PORTA_ ;set as an output



BCF STATUS, RP0 ;0003h, 0005h, select RAM bank 0



RETURN





;------------------------------------------------------------------------------

;Subroutine : SETUP_VARS

;------------------------------------------------------------------------------

;Passed : N/A

;Valid : N/A

;Uses :

;Returns : N/A

;Error Code : N/A

;Error Trapping : N/A

;Outline : Resets variables to their default first time values

;------------------------------------------------------------------------------

SETUP_VARS

CLRF mouse_control_flags_

MOVLW MOUSE_QA_STARTUP_

MOVWF mouse_pwm_xa_

MOVWF mouse_pwm_ya_

MOVLW MOUSE_QB_STARTUP_

MOVWF mouse_pwm_xb_

MOVWF mouse_pwm_yb_



CLRF mouse_delay_digital_x_

CLRF mouse_delay_digital_y_

CLRF mouse_delay_analogue_x_

CLRF mouse_delay_analogue_y_



MOVLW MOUSE_DELAY1_THUMB_X_ ;This is the longest delay

MOVWF mouse_delay_analogue_x_

MOVLW MOUSE_DELAY1_THUMB_Y_ ;This is the longest delay

MOVWF mouse_delay_analogue_y_



CLRF psx_control_flags_

CLRF psx_byte4_start_var_

CLRF psx_byte5_start_var_

RETURN





;------------------------------------------------------------------------------

;Subroutine : SETUP_TMR0

;------------------------------------------------------------------------------

;Passed : N/A

;Valid : N/A

;Uses : TMR0 , BANK1 (PSA , PS2 , PS1 , PS0 , T0CS) T0IF , T0IE

;Returns : N/A

;Error Code : N/A

;Error Trapping : N/A

;Outline : Resets and starts TIMER0

;------------------------------------------------------------------------------

SETUP_TMR0

CLRF TMR0



BSF STATUS, RP0 ;must enter bank 1 for OPTION reg

BCF OPTION_REG, PSA ;prescaler assigned to TMR0, start the timer

BSF OPTION_REG, PS2 ;

BCF OPTION_REG, PS1 ;

BCF OPTION_REG, PS0 ;

BCF OPTION_REG, T0CS ;clear = on, set = off

BCF STATUS, RP0 ;return to bank 0



BCF INTCON, T0IF ;clear the TMR0 interrupt flag

BSF INTCON, T0IE ;0x05, enable TMR0 interrupts

BSF INTCON, GIE ;enable global interrupts, that's what this is



RETURN













; --------------------------------

; DUMPS MESSAGE IN EEPROM TO RS232

; --------------------------------

RS232_OUTPUT_EE_MESSAGE

MOVWF rs232_ee_message_counter_ ;store the message number which we are to retrieve



;set our starting location of eeprom

;we shall start with location 0 as we are searching for b'1000000'



MOVLW 0x48 ;the start of the messages in EEPROM

Rs232_find_ee_message:

MOVWF ee_pointer_

BSF STATUS, RP0 ;select Bank 1

MOVWF EEADR

BSF EECON1, RD ;EE Read

MOVF EEDATA, W ;store value in W

BCF STATUS, RP0 ;back to Bank 0



;W will contain the value just read from eeprom

MOVWF ee_byte_

BTFSS ee_byte_, RS232_EE_MESSAGE_MARKER_ ;RS232_EE_MESSAGE_MARKER_

GOTO Rs232_find_ee_message



;we are here as we have found a message!!

;is the message we have found the right one?

DECFSZ rs232_ee_message_counter_, F

GOTO Rs232_find_ee_message



;we are here as we have found our message number x

;the next byte to be read will be part of the message

;the message will be terminated by another marker b'1000000'

Rs232_read_next_ee_byte:

INCF ee_pointer_, F ;point to the next location

MOVF ee_pointer_, W ;put the current location into W

BSF STATUS, RP0 ;select Bank 1

MOVWF EEADR

BSF EECON1, RD ;EE Read

MOVF EEDATA, W ;store value in W

BCF STATUS, RP0 ;back to Bank 0



;W contains the byte

;is it a message marker?

MOVWF ee_byte_

BTFSC ee_byte_, 0x07 ;RS232_EE_MESSAGE_MARKER_

GOTO rs232_ee_message_complete



;no, it isn't a marker, so it is safe to send the byte to the rs232 port

;it is still contained in W, so is compatiable with the rs232 send procedure

CALL RS232_SEND_BYTE

GOTO Rs232_read_next_ee_byte

rs232_ee_message_complete:



RETURN



; --------------------------------

; OUTPUT BYTE TO RS232 PORT

; --------------------------------

RS232_SEND_BYTE

MOVWF TXREG ;load our value passed in W

BSF STATUS, RP0 ;enter ram page 1

Rs_tx_still_low:

BTFSS TXSTA, TRMT ;tranmission complete when high

GOTO Rs_tx_still_low

BCF STATUS,RP0 ;enter ram page 0



RETURN





; --------------------------------

; OUTPUT BYTE IN HEX TO RS232 PORT

; --------------------------------

RS232_OUTPUT_HEX_BYTE

MOVWF rs232_byte_ ;store our value

SWAPF rs232_byte_, F ;swap our nibble round

CALL RS232_CALC_HEX_NIBBLE

CALL RS232_SEND_BYTE ;Output the ascii character

SWAPF rs232_byte_, F ;swap our nibble round

CALL RS232_CALC_HEX_NIBBLE

CALL RS232_SEND_BYTE ;Output the ascii character



RETURN



; ----------------------------------

; OUTPUT NIBBLE IN HEX TO RS232 PORT

; ----------------------------------

RS232_CALC_HEX_NIBBLE

MOVLW 0x03

MOVWF PCLATH ;select the 4th bank of 256

MOVLW b'00001111'

ANDWF rs232_byte_, W

ADDWF PCL, F



RETLW '0'

RETLW '1'

RETLW '2'

RETLW '3'

RETLW '4'

RETLW '5'

RETLW '6'

RETLW '7'

RETLW '8'

RETLW '9'

RETLW 'A'

RETLW 'B'

RETLW 'C'

RETLW 'D'

RETLW 'E'

RETLW 'F'



RETURN



; --------------------------------

; SEND CR+LF

; --------------------------------

RS232_OUTPUT_CRLF

MOVLW 0x0D ;CR

CALL RS232_SEND_BYTE

MOVLW 0x0A ;LF

CALL RS232_SEND_BYTE





RETURN



;------------------------------------------------------------------------------

;Subroutine : SETUP_LOAD_EEPROM

;------------------------------------------------------------------------------

;Passed : W contains location to load

;Valid : 0d, 9d, 18d, 27d, 36d, 45d, 54d, 63d (0x00, 0x09, 0x12, 0x1B, 0x24, 0x2D, 0x36, 0x3F)

;Uses :

;Returns : N/A

;Error Code : N/A

;Error Trapping : N/A

;Outline :

;------------------------------------------------------------------------------

SETUP_LOAD_EEPROM

; setup_button1_mask_

; setup_button2_mask_

; setup_button3_mask_

; setup_button1_repeat_mask_

; setup_button2_repeat_mask_

; setup_button3_repeat_mask_

; setup_leftright_mask_

; setup_repeat_rate_

; setup_config_flags_



MOVWF ee_pointer_ ;This is where we load the first byte from

MOVLW 9d ;This is how many bytes we're going to be reading

MOVWF loop1_

MOVLW 0x40 ;the point in RAM where the buffer sits

MOVWF FSR



Setup_load_eeprom_another_byte:

MOVF ee_pointer_, W ;get the pointer

BSF STATUS, RP0 ;select Bank 1

MOVWF EEADR

BSF EECON1, RD ;EE Read

MOVF EEDATA, W ;store value in W

BCF STATUS, RP0 ;back to Bank 0

;We need to save W STRAIGHT into memory...

MOVWF INDF ;Indirect Addressing straight into memory

INCF FSR,F ;Point to the next point in RAM

INCF ee_pointer_, F

DECFSZ loop1_, F ;Get another one if necessary

GOTO Setup_load_eeprom_another_byte



RETURN



;------------------------------------------------------------------------------

;Subroutine : SETUP_SAVE_EEPROM

;------------------------------------------------------------------------------

;Passed : W contains location to save

;Valid : 0d, 9d, 18d, 27d, 36d, 45d, 54d, 63d (0x00, 0x09, 0x12, 0x1B, 0x24, 0x2D, 0x36, 0x3F)

;Uses :

;Returns : N/A

;Error Code : N/A

;Error Trapping : N/A

;Outline :

;------------------------------------------------------------------------------

SETUP_SAVE_EEPROM



MOVWF ee_pointer_ ;This is where we load the first byte from

MOVLW 9d ;This is how many bytes we're going to be reading

MOVWF loop1_

MOVLW 0x40 ;the point in RAM where the buffer sits

MOVWF FSR



Setup_save_eeprom_another_byte:

MOVF INDF, W ;get the data we're going to write

INCF FSR, F ;Point to the next point in RAM

BSF STATUS, RP0 ;Bank 1

MOVWF EEDATA ;the data

MOVF ee_pointer_, W ;get the pointer

MOVWF EEADR ;the address in EEPROM



BSF EECON1, WREN ;enable EE Write



MOVLW 0x55

MOVWF EECON2 ;write 55h

MOVLW 0xAA

MOVWF EECON2 ;write AAh

BSF EECON1, WR ;set WR bit



Setup_save_eeprom_wait: ;begin write

BTFSC EECON1, WR

GOTO Setup_save_eeprom_wait



BCF EECON1, WREN ;disable EE Write



INCF ee_pointer_, F

BCF STATUS, RP0 ;Bank 0



DECFSZ loop1_, F ;Get another one if necessary

GOTO Setup_save_eeprom_another_byte



RETURN





;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

;0.0.EEPROM data contents (128 bytes)

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

ORG 0x2100 ;(8448 dec)

; setup_button1_mask_ ;1

; setup_button2_mask_ ;2

; setup_button3_mask_ ;3

; setup_button1_repeat_mask_ ;4

; setup_button2_repeat_mask_ ;5

; setup_button3_repeat_mask_ ;6

; setup_leftright_mask_ ;7

; setup_repeat_rate_ ;8

; setup_config_flags_ ;9





; /\ ---------+ +--------- R1

; | |

; O -------+ | | +------- L1

; | | | |

; X -----+ | | | | +----- R2

; | | | | | |

; # ---+ | | | | | | +--- L2

; | | | | | | | |

; 0 0 0 0 0 0 0 0

;psx_rx_byte3_ ;Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7 - PSX

;psx_rx_byte4_ ;SLCT STRT UP RGHT DOWN LEFT

;psx_rx_byte5_ ;L2 R2 L1 R1 /\ O X |_|



BUTTON_SETUP_00_

DE b'01000000' ;1 CROSS

DE b'10000000' ;2 SQUARE

DE b'00010000' ;3 TRIANGLE

DE b'00001111' ;4 L1

DE b'00000000' ;5 R1

DE b'00000000' ;6

DE b'00000000' ;7 L2

DE b'00000111' ;8 32

DE b'00000000' ;9

BUTTON_SETUP_01_

DE b'01000000' ;1

DE b'10000000' ;2

DE b'00010000' ;3

DE b'00000101' ;4

DE b'00001010' ;5

DE b'00000000' ;6

DE b'00000000' ;7

DE b'00001111' ;8

DE b'01000000' ;9

BUTTON_SETUP_02_

DE b'11110000' ;1

DE b'00000000' ;2

DE b'00000000' ;3

DE b'00001111' ;4

DE b'00000000' ;5

DE b'00000000' ;6

DE b'00000000' ;7

DE b'00000111' ;8

DE b'00000000' ;9

BUTTON_SETUP_03_

DE b'01000000' ;1

DE b'10000000' ;2

DE b'00010000' ;3

DE b'00000100' ;4

DE b'00000001' ;5

DE b'00001000' ;6

DE b'00000100' ;7

DE b'00000111' ;8

DE b'01000001' ;9

; -------x ;0x00 = 0 = ATARI ST Mouse, 1 = AMIGA Mouse

; ------x- ;0x01 =

; -----x-- ;0x02 =

; ----x--- ;0x03 =

; ---x---- ;0x04 =

; --x----- ;0x05 =

; -x------ ;0x06 = 0 = LEFT THUMBSTICK , 1 = RIGHTTHUMBSTICK

; x------- ;0x07 = Pin 5 / 7800 Enabled on DIGITAL

BUTTON_SETUP_04_

DE b'01000000' ;1 CROSS

DE b'10000000' ;2 SQUARE

DE b'00010000' ;3 TRIANGLE

DE b'00001111' ;4 L1

DE b'00000000' ;5 R1

DE b'00000000' ;6

DE b'00000000' ;7 L2

DE b'00000111' ;8 32

DE b'00000000' ;9

BUTTON_SETUP_05_

DE b'01000000' ;1

DE b'10000000' ;2

DE b'00010000' ;3

DE b'00000101' ;4

DE b'00001010' ;5

DE b'00000000' ;6

DE b'00000000' ;7

DE b'00001111' ;8

DE b'01000000' ;9

BUTTON_SETUP_06_

DE b'11110000' ;1

DE b'00000000' ;2

DE b'00000000' ;3

DE b'00001111' ;4

DE b'00000000' ;5

DE b'00000000' ;6

DE b'00000000' ;7

DE b'00000111' ;8

DE b'00000000' ;9

BUTTON_SETUP_07_

DE b'01000000' ;1

DE b'10000000' ;2

DE b'00010000' ;3

DE b'00000100' ;4

DE b'00000001' ;5

DE b'00001000' ;6

DE b'00000100' ;7

DE b'00000111' ;8

DE b'01000001' ;9





RS_MSG_01_

DE b'10000000' ;the first bit indicates the beginning of a message

DE 0x0D ;CR

DE 0x0A ;LF

DE 'R'

DE 'E'

DE 'S'

DE 'E'

DE 'T'

DE '_'

DE '0'

DE '0'

DE '6'

DE 0x0D ;CR

DE 0x0A ;LF

RS_MSG_02_

DE b'10000000'

DE 0x0D ;CR

DE 0x0A ;LF

RS_MSG_03_

DE b'10000000'













;------------------------------------------------------------------------------

;0.0.PDIP/SOIC Package - 16F627A - 16F628A - 16F648A

;------------------------------------------------------------------------------

;

; 16F628A

; +-----\_/-----+

; RA2/AN2/VREF - | 1 18 | - RA1/AN1

; RA3/AN3/CMP1 - | 2 17 | - RA0/AN0

; RA4/TOCKI/CMP2 - | 3 16 | - RA7/OSC1/CLKIN

; RA5/MCLR/VPP - | 4 15 | - RA6/OSC2/CLKOUT

; VSS - | 5 14 | - VDD

; RB0/INT - | 6 13 | - RB7/T1OSI/PGD

; RB1/RX/DT - | 7 12 | - RB6/T1OSO/PGC

; RB2/TX/CK - | 8 11 | - RB5

; RB3/CCP1 - | 9 10 | - RB4/PGM

; +-------------+

;

; 16F628A

; +-----\_/-----+

; YB < | 1 18 | > RIGHT BUTTON

; YA < | 2 17 | > XA

; - | 3 16 | > XB

; - | 4 15 | > LEFT BUTTON

; GND - | 5 14 | - 5V

; - | 6 13 | ^ PS2_DATA_PORTB_LIVE_

; - | 7 12 | ^ PS2_CLOCK_PORTB_LIVE_

; TX < | 8 11 | ^ PS2_DATA_PORTB_TESTING_

; | 9 10 | ^ PS2_CLOCK_PORTB_TESTING_

; +-------------+
























END




Hope that helps to get you started somewhat. It's always easier to come back to. :)

rmteo
Mar 28, 2009, 02:08 PM
Download this BASIC compiler/simulator (it's free for 30 days), and test out your program in the simulator with the 8 LED's. You could be done in a matter of hours - or minutes, since you are already familiar with BASIC:
http://www.oshonsoft.com/pic.html

http://www.oshonsoft.com/picscreenshot.png

DubbleD
Mar 28, 2009, 10:39 PM
Thanks guys, it will take me some time to digest all this info.

robe uk: Thanks for your help, it helps me understand what some of the commands are really doing. I hope you don't mind me asking some more questions.

1. Is the org 0x00 command really necessary, or does that just ensure that the program will occupy memory from the beginning of the RAM? And does the org 0x04 do anything in this program? If so, what? And to what point does the return line send it?

2. When I try to add this code to my program, the del_lo and del_hi sections are causing me conflicts in the program that prevent it from compiling correctly, specifically it seems to be the clrf del_lo and clrf del_hi lines that initialize the counters. When I try to compile I get errors in the build that say that those lines are attempting to overwrite previously used memory addresses. If I put ; in front of them it compiles OK but the program doesn't work right. Do I just need to place them in a different register to prevent that? Are del_lo and del_hi something that is used by the program to count up or down like the FOR/NEXT loops we used to use in BASIC?

3. I already have a user register defined as "DELAY", and the subroutine named DELAY in Malc C's code also causes errors in compiling, so could I just rename the references to it to something else, like "PAUSE"?

I have a small amount of code already written that moves a servo from one side to the other with a significant delay, about 4 seconds from 1.0ms to 2.0ms. It also sets the bit on either GP4 or GP5 depending on which way the servo moves to turn on landing light LEDs. I've already assigned all the ports and stuff, and that part is working perfectly. I tried just pasting Malc C's code into mine, but it's creating conflicts that keeping it from compiling. I think I can make the new code flash the strobes just like I want them to if I can just figure out how to resolve them. I tried the new code by itself, and it works perfectly, too. I just have to figure out how to combine them.

BTW, Thanks ALison F for the link, I found a ton of material there I need to pour through.

And rmteo, I'll look at the compiler you suggested. Does it actually let you write in BASIC? I'd have to start all over I guess, but that might be good for future projects. Too much to learn, and I'm starting too late. ;)

rmteo
Mar 28, 2009, 11:35 PM
Yes, you write code in BASIC. Look at the window (at top left) for the BASIC compiler.

robe_uk
Mar 29, 2009, 08:18 AM
1. Is the org 0x00 command really necessary, or does that just ensure that the program will occupy memory from the beginning of the RAM? And does the org 0x04 do anything in this program? If so, what? And to what point does the return line send it?



0x00 is the reset vector used by the pic, ie when the pic is turned on or reset this is the first location it looks at, as there are only a few memory locations before 0x04 the interupt vector the only real code we put here is 'goto main', so i would say it is important as you want the pic to jump to the correct start loction.
The main program is at 0x21 so at the start of your main program you would do,

org 0x00
goto Main

org 0x04
return

cblock 0x20
define various things etc
endc

org 0x21
Main:
code
code


dont get mixed up with RAM memory and program memory

The org 0x04 is basically the same except this loction is where the pic jumps to when an interupt occurs.

I will look for some links to good info sites about programming pic when I get back to my main PC.

Rob

rich smith
Mar 29, 2009, 01:22 PM
1. Is the org 0x00 command really necessary

Not needed because you don't need interrupts to bllink LEDs. Program does not need to be anywhere near as complicated either.

dmccormick001
Mar 30, 2009, 10:37 AM
Thanks guys, I'm really learning a lot with your help. The links have been great because I can pick up little tidbits that, I guess because I'm familiar with BASIC, I can use to figure things out by trial and error. I'm really enjoying it.

Good news is that I've figured out how to accomplish at least part of what I wanted to do. The program does three different things, it slows a servo down for use as a retract or flap servo, it turns on landing lights when the servo moves, and it flashes the strobe constantly. Because it's always "looking" for an input to move the servo, I can't allow the part of the program that flashes the strobes to get hijacked by a subroutine or any kind of "delay" loop or it will cause the rest of the program to malfunction. The code was written in such a way that once it set or cleared the bit controlling the strobe LED, the whole program would continue to loop around with the LED on or off until it had looped a certain number of times, and then it would toggle the bit. I can change the speed of the flash by changing the variable controlling the number of loop cycles before it toggles, but it makes the LED flash instead of blink. The off time was the same as the on time, and no matter how fast or slow I made it, it didn't look right. So what I wanted to do was set the bit very briefly, like a flash, then clear it, and leave it clear for about 3-4 times longer than the flash, then set it again and repeat it. What I finally figured out how to do was to change the place at which the timer variable was restored. So now after the bit is cleared, I've added code to restore the timer with a new, larger variable amount, and after a little experimentation with the variables I've got it blinking just right! Once I figured out the logic of the program, it only took a few new lines of code to do it.

But I'm greedy, and what I really wanted was a double blink strobe, so now I'm trying to perfect adding a second timer and variable, so that it will set the bit once for a quick blink (like it does now), clear it briefly, blink it a second time quickly, and then clear it for a longer time to produce a scale-like double blink. I think I can do it, I've just got to scratch my head a little more.

Acetronics
Mar 30, 2009, 12:22 PM
Hi,

Correct me if I'm wrong ... but I think Mr CAM already did such a thing available, on the web ...

"Landtastic" called.

Hope it helps.

Alain

Malc C
Mar 30, 2009, 12:47 PM
LOL nothing like trying to re-invent the wheel :)

Dan Baldwin
Mar 30, 2009, 01:51 PM
Here's (http://www.rc-cam.com/ldtastic.htm) a link to RC-Cam's landtastic.

Dan

robe_uk
Mar 30, 2009, 05:54 PM
sometimes its nice to 'D'o 'I't 'Y'ourself just to see if you can, and its nice to learn along to way, here are a few links I promised earlier, am sure google will turn up more.
Rob

http://www.best-microcontroller-projects.com/12F675.html
http://www.winpicprog.co.uk/pic_tutorial.htm
http://www.dontronics.com/see.html
http://www.phanderson.com/PIC/index.html
http://www.gooligum.com.au/tut_baseline.html

DubbleD
Mar 31, 2009, 06:49 PM
I've actually built the Landtastic, and it worked great, exactly as it was supposed to. But I kinda wanted to play around a bit with the idea, and wanted to use some of the outputs of the PIC for some different things. One thing I wanted to do was to have one outpin HIGH for each direction of the servo's movement, so you could hook up landing lights that would come on correctly no matter how your flap channel is set up, without having to go through the programming sequence of the Landtastic. And I wanted to have two, asyncronous strobes, one on top and one on the bottom, so I started with the servo movement code, and went from there.

I'm proud to say I just last night figured it out and I have it working superbly with one strobe LED. I can alter the variables in the code to 1.change the speed of the servo's travel, 2. change the number of strobe flashes (1-blink, double-blink, etc.), 3.change the length of time between individual blinks and between the "pairs" or sets of flashes. The real trick was in figuring out where to decrement certain timers, and then where to restore them back to the right values to make the program do what I wanted it to do and keep looping around flashing while it still looked for servo input.

I've decided to go for broke now. I could be satisfied with just the one strobe, but now that I've got a handle on how to time it all, I'm going to add the second strobe and see if I can get it to double blink during the cycles while the first one is off. I've set it up so that I have defined separate variables for the length of the LED's ON state, the length of the pause between blinks, and the length of the pause between each pair of blinks. I think I can manipulate it so that while STRB1 is in the longer OFF state between it's two blinks, the other LED, STRB2, can be doing what STRB1 just got through doing. Sounds easy enough, don't it?!??

Just last week I couldn't even spell groprammer, and now I are one!

Thanks for all the explanations, advice, and links. I'm sure I'll have more.

DD

DubbleD
Apr 01, 2009, 11:09 PM
Hey guys, I need one more piece of advice. I can't find any reference in any of the manuals I've downloaded concerning some of the commands and their syntax/parameters. I have a list of some of the commands my PIC uses (PIC12F629), but there are several I don't see any info on. My compiler seems to accept some because the color changes on the command if it's a valid entry, but I can't figure out how I'm supposed to format the code. I need to enter a line in my program that says (in BASIC anyway) IF TMR8=0 GOTO xxxx. TMR8 is a timer I have set up in the define section and have initialized to "1" with a variable T8=1. That part compiles OK. The GOTO xxxx is a reference to a place in my code I want to branch to if TMR8 has counted down to zero. I have a line that decrements it at a certain point, but I can't branch it there, I need to do it in a different place. If I could make that IF....GOTO command work, I'd be home free. I know to add the ENDIF line after it, but my compiler gives me the error message that the GOTO is an "undefined character", and I don't know how to fix it. Can anybody help me figure it out? I'm hoping it's just a matter of syntax, because I really need to be able to read the value of the TMR8 register and branch if it's = zero.

Thanks if you can help!

DD