|
|
View previous topic :: View next topic |
Author |
Message |
laserdave
Joined: 11 Jul 2009 Posts: 2
|
DMX Routines from asm to CCS Compiler 18f4620 |
Posted: Sun Aug 30, 2009 4:10 am |
|
|
My first post
DMX TRANSMIT OK:
I am working on a new project which involves the reception and transmission of DMX.I have initially based my project on the code in Microchips application AN1076. The code is written in assembler for the 18F24J10. I made some minor changes to use the 18F4620, both transmit and receive routines build with MPLAB and work well. I then built a C wrapper around the transmit routine and build it using the CCS compiler (latest version), again his worked fine.I then ported the code to C and again the transmit routines is fine.
DMX RECEIVE ERROR:
The problem is with the DMX receive routine it works fine build under MPLAB as true assembler but when I either put a C wrapper around it Or produce come very simple C loop to test for receive data then a framing error it always get stuck in a framing error loop (FERR always =0).
Any ideas on how why as to the difference of the MPLAB or CCS enviroment or problems with the 18F4620.
I have found a couple of examples in the DMX forum and I have similar problems with FERR. what I do know with all this is AN1076 app assembler
code works fine under MPLAB
portdefines.h
Code: |
#byte POSTINC0= 0xFEE
#byte STATUS= 0xFD8
#byte TRISC= 0xF94
#byte TXSTA= 0xFAC
#byte RCSTA= 0xFAB
#byte RCREG= 0xFAE
#byte SPBRG= 0xFAF
#byte SPBRGH= 0xFB0
#byte CCP2CON= 0xFBA
#byte T2CON= 0xFCA
#byte PR2= 0xFCB
#byte BAUDCON= 0xFB8
#byte PORTC= 0xF82
#byte PIR1= 0xF9E
#byte PIE1= 0xF9D
#BIT TX9 = TXSTA.6
#BIT TXEN = TXSTA.5
#BIT SYNC = TXSTA.4
#BIT BRGH = TXSTA.2
#BIT SPEN = RCSTA.7
#BIT RX9 = RCSTA.6
#BIT SREN = RCSTA.5
#BIT CREN = RCSTA.4
#BIT FERR = RCSTA.2
#BIT OERR = RCSTA.1
#BIT TXIE = PIE1.4
#BIT RCIE = PIE1.5
#BIT RCIF = PIR1.5
|
Code: |
#include <main.h>
#include <portdefines.h>
#fuses NOWDT,PUT,STVREN,NOXINST,NOCPD,HS,NOFCMEN,NOIESO
#ZERO_RAM
#define CLOCK_FREQUENCY 20000000
#use delay(clock=20000000)
static int CountH;
static int CountL;
static char RxBuffer;
Setup_Rx_Serial () {
#asm
;Clear the receive buffer
lfsr 0,RxBuffer
CBloop:
clrf POSTINC0
incf CountL,F
btfss STATUS,0
bra CBloop
incf CountH,F
btfss CountH,1
bra CBloop
; Setup EUSART
bsf TRISC,7 ; allow the EUSART RX to control pin RC7
bsf TRISC,6 ; allow the EUSART TX to control pin RC6
movlw 0x04 ; Disable transmission
movwf TXSTA
movlw 0x90
movwf RCSTA ; enable serial port and reception
bsf BAUDCON,3 ; Enable UART for 16-bit Asyn operation
clrf SPBRGH ; CLEAR high baud rate
movlw 0x12 ; Baud rate is 250KHz for 20MHz Osc. freq.
movwf SPBRG
;Setup PWM module
movlw 0x0c ; configure CCP2 for PWM mode
movwf CCP2CON
;Timer2 control
movlw 0x04 ; enable Timer2, select a prescale of 1:1
movwf T2CON
;PWM period
movlw 0xFF ; 256 x .25us = 64us period
movwf PR2
; init I/O
movlw 0xfd
movwf TRISC
#endasm
}
Receive_DMX () {
#asm
Rx_Start:
; first loop, synchronizing with the transmitter
WaitBreak:
btfsc PIR1,5 ; if a byte is received correctly
movf RCREG,W ; discard it
btfss RCSTA,2 ; else
;NEVER GETS PASSED HERE KEEPS IN WAITBREAK LOOP
bra WaitBreak ; continue waiting until a frame error is detected
movf RCREG,W ; read the Receive buffer to clear the error condition
; second loop, waiting for the START code
WaitForStart:
btfss PIR1,5 ; wait until a byte is correctly received
bra WaitForStart
btfsc RCSTA,2
bra WaitForStart
movf RCREG,W
; check for the START code value, if it is not 0, ignore the rest of the frame
andlw 0xff
bnz Rx_Start ; ignore the rest of the frame if not zero
; init receive counter and buffer pointer
clrf CountL
clrf CountH
lfsr 0,RxBuffer
; third loop, receiving 512 bytes of data
WaitForData:
btfsc RCSTA,2 ; if a new framing error is detected (error or short frame)
bra RXend ; the rest of the frame is ignored and a new synchronization
; is attempted
btfss PIR1,5 ; wait until a byte is correctly received
bra WaitForData ;
movf RCREG,W
MoveData:
movwf POSTINC0 ; move the received data to the buffer
; (auto-incrementing pointer)
incf CountL,F ; increment 16-bit counter
btfss STATUS,0
bra WaitForData
incf CountH,F
btfss CountH,1 ; check if 512 bytes of data received
bra WaitForData
RXend:
bra WaitBreak
lfsr 0,RxBuffer ; use indirect pointer 0 to address the receiver buffer
GetData:
;movlw LOW(0) ; add the offset for the select channel
;addwf FSR0L,F
;movlw HIGH(0)
;addwfc FSR0H,F
;movff INDF0,CCPR2L ; retrieve the data and assign MSB to control PWM2
#endasm
}
main()
{
Setup_Rx_Serial ();
//main loop
do
{
//our loop code here
output_low (PIN_C1);
Receive_DMX();
output_high (PIN_C1);
}
while(1);
} |
|
|
|
Ttelmah Guest
|
|
Posted: Sun Aug 30, 2009 8:20 am |
|
|
The obvious thing 'wrong', is the baud rate setting byte. With this wrong, a 'good' character will never be received.....
20MHz/250000 = 80
80/4 = 20 decimal required for BRG
0x14....
Best Wishes |
|
|
Ttelmah Guest
|
|
Posted: Sun Aug 30, 2009 8:24 am |
|
|
(remember the byte used by the BRG, is this -1, so 0x13).
With 0x12, you are dividing by 76, to give operation at 263Khz.
Best Wishes |
|
|
laserdave
Joined: 11 Jul 2009 Posts: 2
|
|
Posted: Sun Aug 30, 2009 2:57 pm |
|
|
Many thanks for your reply. I thought I may have overlooked something simple,but unfortunately it was not the case. You may be correct on the baud rate divisor but that is not the only problem. As I said this code was originally in assembler microchip AN1076 and that had a divisor of 18 decimal. I tried rebuilding the assembler divisor 0x12,13&14 and DMX seems quite tolerant and still works with all values(Pulsar Lighting Desk). As a final try I tried your sugestion with the C ported assembler and it still doesnt play ball. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|