Maker Pro
Maker Pro

indirect addressing problem on 16f628

S

Sambo

Jan 1, 1970
0
I thought I have alredy stepped through indirrect addressing code in MPLAB (unless it was flash rom code not sure), but as far as I canb determine, it should be emulated in the debugger.
Unfortunately nothing is being stored in the buffer ( Status.7 = 0...???. )
Although, RP0 is set INDF and FSR are in all banks.

;************************** DEBUG CODE ************************
; setup buffer pointers to point near the end of buffer
movlw -5
addwf buff_end, w
movwf buff_head
movwf buff_tail

send_test_message: ; if baudrate changed, main loop starts here send 9-0 digits
movlw 0x39 ; prepare ASCII of '9'
movwf temp3
send_next_byte:
movfw temp3
call place_byte_in_output_buffer
movlw 0x30
subwf temp3, w
btfsc STATUS, Z
goto main_loop
decf temp3
goto send_next_byte
..
..
place_byte_in_output_buffer:
; pointers - test write/read advance

movwf temp1
; test if head + 1 is equal tail , if so buffer is full!!!
; first test if it hits end of buffer
movfw buff_head
addlw 1
movwf new_buff_head
; movwf temp2
subwf buff_end, w
btfsc STATUS, Z
goto head_hit_end
; now test it against the tail pointer
movfw new_buff_head
subwf buff_tail, w
btfsc STATUS, Z
goto buffer_full
goto place_character

head_hit_end:
; head will be pointing to beginning - is tail currently pointing to the beginning?
movfw buff_tail
subwf buff_start, w
btfsc STATUS, Z
goto buffer_full
movfw buff_start
movwf new_buff_head
place_character:
movfw buff_head
movwf FSR
movfw temp1
movwf INDF
movfw new_buff_head
movwf buff_head

character_qued_for_output:
bcf STATUS, C
return

buffer_full:
bsf STATUS, C
return


Any thoughts?

Sam.
 
N

News.Individual.NET

Jan 1, 1970
0
Sambo said:
I thought I have alredy stepped through indirrect addressing code in
MPLAB (unless it was flash rom code not sure), but as far as I canb
determine, it should be emulated in the debugger.
Unfortunately nothing is being stored in the buffer ( Status.7 =
0...???. ) Although, RP0 is set INDF and FSR are in all banks.
Yes, INDF and FSR are mapped to all banks. Are you sure *your* registers
are in the correct bank?
In the MPLAB, under Special Function Registers, you can't see the
contents of INDF. You can see it if you load it into W and look at W.

hjf

--
 
S

Sambo

Jan 1, 1970
0
News.Individual.NET said:
Yes, INDF and FSR are mapped to all banks. Are you sure *your* registers
are in the correct bank?
In the MPLAB, under Special Function Registers, you can't see the
contents of INDF. You can see it if you load it into W and look at W.

hjf
As it turns out MPLAB seams to only work properly if you are addressing them (FSR and INDF)
in bank 0 that means that I either have another problem in outputing logic or my internal OSC is too far off after 10 characters. ( my first test message from flash rom although not through the circular buffer )
I'll try inserting one bit delay between chars untill it goes to circuit board where it is not going to be that much hassle to put crystal.

All the storage in that piece of code is in the common memory(0x70-).

cheers, Sam
 
H

Hernán Freschi

Jan 1, 1970
0
All the storage in that piece of code is in the common memory(0x70-).

Have you tried adding dec 128 to the base address? In Bank 1, can't
access 0x70, you have to access F0h, to read/write what's on 0x70h --the
common memory.

hjf
 
S

Sambo

Jan 1, 1970
0
Hernán Freschi said:
Have you tried adding dec 128 to the base address? In Bank 1, can't
access 0x70, you have to access F0h, to read/write what's on 0x70h --the
common memory.

hjf
Is it april first already? You are joking right?
it is a banked design, one can only address locations between 0 and 7f.
The only (stupid) reason why registes outside of bank 0 are defined with
more than 7 bits is so they can print warnings ( I guess), instead of having
separate table indicating what registers are in what banks.
Before I found the include files I started to write my own and later this was
the first think that struck me.

However I am still not having any luck even after adding a substantial delay.
For a long time I was stuck, untill I realized the problem was with Hyperterm
no longer working ( at 9600). When I finaly tried the serial sample
'http://www.oz1bxm.dk/PIC/628uart.htm" worked fine even in Hyperterm.
When I set it to 2400 last time I checked I got "?>>>READ" instead of
"?>>>READY." in Hyperterm, what made me believe the frequency is off.
With a MSC++ 5.0 sample terminal program I get the full first message but another
message (9-0) placed in the circular buffer is not comming out.

Here is the full code if anyone wants to try it.

----------------------------------------------------
;**********************************************************************
; This file is a basic code template for object module code *
; generation on the PICmicro PIC16F628A. This file contains the *
; basic code building blocks to build upon. As a project minimum *
; the 16F628A.lkr file will also be required for this file to *
; correctly build. The .lkr files are located in the MPLAB *
; directory. *
; *
; If interrupts are not used all code presented between the *
; code section "INT_VECTOR and code section "MAIN" can be removed. *
; In addition the variable assignments for 'w_temp' and *
; 'status_temp' can be removed. *
; *
; If interrupts are used, as in this template file, the 16F628A.lkr *
; file will need to be modified as follows: Remove the lines *
; CODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTED *
; and *
; SECTION NAME=STARTUP ROM=vectors *
; and change the start address of the page0 section from 0x5 to 0x0 *
; *
; Refer to the MPASM User's Guide for additional information on *
; features of the assembler and linker (Document DS33014). *
; *
; Refer to the respective PICmicro data sheet for additional *
; information on the instruction set. *
; *
;**********************************************************************
; *
; Filename: xxx.asm *
; Date: *
; File Version: *
; *
; Author: *
; Company: *
; *
; *
;**********************************************************************
; *
; Files required: *
; 16F628A.lkr (modified) *
; *
; *
;**********************************************************************
; *
; Notes: *
; *
; *
; *
; *
;**********************************************************************

list p=16F628A ; list directive to define processor
#include <p16F628A.inc> ; processor specific variable definitions

errorlevel -302 ; suppress message 302 from list file


__CONFIG _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT


; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See data sheet for additional information on configuration word settings.



;***** VARIABLE DEFINITIONS (examples)

; example of using Shared Uninitialized Data Section
INT_VAR UDATA 0x20
timer1_prescaler res 1 ; /start
PB7_old_val res 1
PB7_new_val res 1
timer_lo res 1
timer_hi res 1
timer1_timeouts res 1
ResultsA res 1 ; port A outputs
; 0 - 0, 1, 2, 3, 4, 6 characters in output buffer
; 1 -
; 2 -
; 3 -
; 4 -
; 5 - VPP/!MCLR always input
; 6 -
; 7 - baud rate input HI/LO (BRGH bit)

ResultsB res 1 ; port B outputs
; 0 - timer read hickup indicator
; 1 - Async RX
; 2 - Async Tx
; 3 - ?IR output? not yet implemented
; 4 - PGM
; 5 - IR input
; 6 - PGC
; 7 - PGD
DD_PA equ 0xa0
DD_PB equ 0xf2

;###################################################################################
; Commands from the serial port precceded by 00 AA sync chars
; Read or write registers
; 101 00001 read register specified in following byte
; 101 00010 write register specified in following byte with data in next additional byte

;
sync_OK res 1 ; set to 0 when 0 received incremented when AA received
Last_command res 1 ; if sync is 1 store bytes
Command_data1 res 1 ; usualy address
Command_data2 res 1 ; usualy data value

Free_ram:

INT_VAR_SHR UDATA_SHR 0x71
w_temp res 1 ; variable used for context saving
status_temp res 1 ; variable used for context saving

temp1 res 1 ; used by place_byte_in_output_buffer
temp2 res 1 ; used by place_byte_in_output_buffer
temp3 res 1
buff_head res 1 ; points to where new data is stored
buff_tail res 1 ; points to which byte is next to be transmited ( read advance )
buff_start res 1 ;
buff_end res 1
new_buff_head res 1
TX_char_count res 1
TX_max_char_count res 1
;**********************************************************************
RESET_VECTOR CODE 0x000 ; processor reset vector
goto main ; go to beginning of program


INT_VECTOR CODE 0x004 ; interrupt vector location
movwf w_temp ; save off current W register contents
swapf STATUS, w ; move status register into W register
movwf status_temp ; save off contents of STATUS register

; isr code can go here or be located as a call subroutine elsewhere
banksel INTCON
btfss INTCON, 0
goto portB_no_change
movfw PORTB
andlw 0x80
movwf PB7_new_val
subwf PB7_old_val, f
btfsc STATUS, Z
goto int_done
movfw TMR1H
movwf timer_hi
movfw TMR1L
movwf timer_lo
movf TMR1H, w ; Read high byte
SUBWF timer_hi, W ; Sub 1st read with
; 2nd read
BTFSC STATUS, Z ; Is result = 0
GOTO done_reading_timer ; Good 16-bit read
bsf ResultsB, 0
decf timer_hi
done_reading_timer:
clrf TMR1H
clrf TMR1L
clrf timer1_timeouts
; output the data to the Async output buffer
; test if change is L/H or H/L
btfss PB7_new_val, 5
goto bit_end
bsf timer_hi, 7 ; slap the bit start indicator into the highest bit
movfw timer_hi
call place_byte_in_output_buffer
movfw timer_lo
call place_byte_in_output_buffer
goto data_output_complete
bit_end:
bcf timer_hi, 7 ; slap the bit end indicator into the highest bit
movfw timer_hi
call place_byte_in_output_buffer
movfw timer_lo
call place_byte_in_output_buffer
data_output_complete:

portB_no_change:
btfss PIR1, TMR1IF ; did timer 1 overflow?
goto timer1_service_done
bcf PIR1, TMR1IF
; clear a byte somewhere?
incf timer1_timeouts
movlw 14
subwf timer1_timeouts, f
btfss STATUS, C
goto timer1_service_done
clrf timer1_timeouts
incf timer1_timeouts
bcf ResultsB, 0 ; clear timer read faulup indicator

timer1_service_done:

int_done:
swapf status_temp, w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp, f
swapf w_temp, w ; restore pre-isr W register contents
; bsf ResultsB, 3
retfie ; return from interrupt

place_byte_in_output_buffer:
; pointers - test write/read advance

movwf temp1
; test if head + 1 is equal tail , if so buffer is full!!!
; first test if it hits end of buffer
movfw buff_head
addlw 1
movwf new_buff_head
; movwf temp2
subwf buff_end, w
btfsc STATUS, Z
goto head_hit_end
; now test it against the tail pointer
movfw new_buff_head
subwf buff_tail, w
btfsc STATUS, Z
goto buffer_full
goto place_character

head_hit_end:
; head will be pointing to beginning - is tail currently pointing to the beginning?
movfw buff_tail
subwf buff_start, w
btfsc STATUS, Z
goto buffer_full
movfw buff_start
movwf new_buff_head
place_character:
movfw buff_head
movwf FSR
movfw temp1
movwf INDF
movfw new_buff_head
movwf buff_head

character_qued_for_output:
bcf STATUS, C
return

buffer_full:
bsf STATUS, C
return

main
; remaining code goes here
bcf STATUS, RP0 ; RAM PAGE 0
bcf STATUS, RP1 ; RAM PAGE 0

movlw 7 ; turn comparator off
movwf CMCON

movlw 0x00
movwf PORTA
movlw 0x04
movwf PORTB

banksel OPTION_REG
bcf OPTION_REG, NOT_RBPU
bsf STATUS, RP0 ; RAM PAGE 1
movlw 0x0f ; high speed int osc, POR and BOR
movwf PCON
movlw DD_PA
movwf TRISA ; PA5, PA7 inputs

movlw DD_PB ; RB7-RB4 and RB1(RX)=input, others output
movwf TRISB
banksel PORTB
movlw 0x04
movwf PORTB
movwf ResultsB
movwf PORTA
movwf ResultsA
banksel T1CON
movlw 0x21 ; prescale /4, enable timer
movwf T1CON
clrf T1CON
movwf timer1_prescaler
movlw 0x30
andwf timer1_prescaler
;;? movlw 0xc8 ; enable global interrupts, peripheral interrupts, interrupt on change of port B
;;? movwf INTCON
bsf STATUS, RP0 ; RAM PAGE 1
;;? bsf PIE1, TMR1IE ; enable timer 1 interrupts, timeout clears any in-progrees IR character reception??

; ------------------------------------
; SET BAUD RATE TO COMMUNICATE WITH PC
; ------------------------------------
; Boot Baud Rate = 9600, No Parity, 1 Stop Bit
;
banksel SPBRG
movlw 0x19 ; 0x19=9600 bps (0x0C=19200 bps)
movwf SPBRG
movlw b'00100000' ; brgh(2) = high
movwf TXSTA ; enable Async Transmission, set brgh

bcf STATUS, RP0 ; RAM PAGE 0
movlw b'10010000' ; enable Async Reception and continuous receive
movwf RCSTA
; bsf PIR1, TXIF ; set tx reg empty interrupt flag

bcf STATUS, RP0 ; RAM PAGE 0
call check_baud_rate_input
clrf temp1
settle decfsz temp1,F
goto settle


; setup the circular buffers
movlw Free_ram
addlw 10
andlw 0f0
movwf buff_start
movwf buff_head
movwf buff_tail
movlw 70
movwf buff_end

bsf ResultsA, 3
bsf PORTA, 3
bcf STATUS, RP0 ; bank 0
movlw 0x23
movwf TXREG
bsf STATUS, RP0 ; bank 1
clrf EEADR
get_next_char

bsf STATUS, RP0 ; Bank1
bsf EECON1, RD ; EE Read
movfw EEDATA
wait_trans_complete:
bcf STATUS, RP0 ; bank 0
btfss PIR1, TXIF ; (1) transmission is complete if hi
goto wait_trans_complete
movwf TXREG ; send data in W
bsf ResultsA, 2
bsf PORTA, 2
sublw 0
btfsc STATUS, Z
goto ready_mess_done
bsf STATUS, RP0 ; Bank1
incf EEADR
goto get_next_char
ready_mess_done:
bcf STATUS, RP0
bcf ResultsA, 4
bcf PORTA, 4


;************************** DEBUG CODE ************************
; setup buffer pointers to point near the end of buffer
movlw -5
addwf buff_end, w
movwf buff_head
movwf buff_tail
send_test_message: ; if baudrate changed, main loop starts here send 9-0 digits
movlw 0x39 ; prepare ASCII of '9'
movwf temp3
send_next_byte:
movfw temp3
call place_byte_in_output_buffer
movlw 0x30
subwf temp3, w
btfsc STATUS, Z
goto main_loop
decf temp3
goto send_next_byte

clrf temp3
;************************ END DEBUG CODE **********************
main_loop:
; first see if there is any data in the transmit buffer
; and calculate the number of bytes in there for performance monitoring
; otherwise it can be all dumped and transmit_data called blindly.

movfw buff_tail
subwf buff_head, w
btfsc STATUS, Z
goto check_for_incoming_data
btfsc STATUS, C
goto was_positive
movwf TX_char_count
movfw buff_end
addwf TX_char_count
movfw buff_start
subwf TX_char_count
goto calc_count_done
was_positive:
movwf TX_char_count
calc_count_done:
movfw TX_max_char_count
subwf TX_char_count, w
btfss STATUS, C
goto new_char_count_max_done
movfw TX_char_count
movwf TX_max_char_count
new_char_count_max_done:
; debug_code: generate inter character spacing
incf temp3
btfss STATUS, Z
goto check_for_incoming_data
movlw 0x80

call transmit_data


; poll async receive for commands
check_for_incoming_data:

check_for_commands:


; if OK to change baudrate ie UART shift reg empty, timer 1 timed out ( at least once )
; command not being received (sync received)
; !!! CURRENTLY just DOIT !!!
call check_baud_rate_input


movfw ResultsB
movwf PORTB

goto main_loop ; loop forever, remove this instruction, for test only

transmit_data:
;********************************************************************
; Transfer byte from cyrcular output buffer into transmit register
; if transmit register flag ( TXIF in PIR1 )indicates it is empty
; inputs: no direct input
; outputs: flag Z= 0 indicates byte was transfered
; 1 uart full/busy or no bytes in output buffer
;********************************************************************
; see if we can transmit
bcf STATUS, RP0 ; RAM PAGE 0
btfss PIR1, TXIF ; is transmit reg empty
goto no_data_to_transmit ; check UART for data

; is there anything in the buffer?
movfw buff_head
subwf buff_tail, w
btfsc STATUS, Z
goto no_data_to_transmit
place_in_TX_REG:
movfw buff_tail
incf buff_tail
movwf FSR
movfw INDF
bsf STATUS, RP0 ; bank 1
movwf TXREG
bcf STATUS, RP0 ; bank 0
movfw buff_end
subwf buff_tail, w
btfss STATUS, Z
goto tail_pointer_OK
movfw buff_start
movwf buff_tail
tail_pointer_OK:

bcf STATUS, Z
return
no_data_to_transmit: ; or chanel not yet free
bsf STATUS, Z
return

check_baud_rate_input:
;*****************************************************
; read external input and reflect it in TXSTA, BRGH
;*****************************************************

bcf STATUS, RP0 ; RAM PAGE 0
btfss PORTA, 7
goto set_low_BRGH
bsf STATUS, RP0 ; RAM PAGE 1
bsf TXSTA, BRGH
goto check_baud_rate_input_done
set_low_BRGH:
bsf STATUS, RP0 ; RAM PAGE 1
bcf TXSTA, BRGH

check_baud_rate_input_done:
bcf STATUS, RP0 ; RAM PAGE 0
return

; initialize eeprom locations
EE CODE 0x2100
DE ">>>READY."
DE 0


END ; directive 'end of program'
-----------------------------------------------------------------

The test circuit

A0 - open
A1 - open
A2 - open
A3 - open
A4 - open
A5 - 2.4K to Vdd
A6 - open
A7 - 20K to Vdd ( baud- select )
B0 - open
B1 - 1.6K to vdd ( AURT input )
B2 - to ttl input of MAX232 CPE
B3 - open
B4 - to b5
B5 - to B6
B6 - to B7
B7 - 10K to Vdd

The only possibly out of spec thing (with the MAX232), I used 10uF caps.
When I used this chip in a circuit over 10 years ago, a circuit I modelled on
used 22uf, while checking recently, various models indicated 100nf or 1uf,
but no specifics for MAX232CPE.

( I should realy hook up for in circuit programming I may even get better than 1 in 10
success rate, lol)

Cheers, Sam
 
H

Hernán Freschi

Jan 1, 1970
0
Is it april first already? You are joking right?
OK, you don't need to be an ass about it, you know? Remember: YOUR
project is not working. You're the loser who can't send characters on
the serial port of a 628. Anyway, **** you.

hjf
 
Top