CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

DMX Routines from asm to CCS Compiler 18f4620

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
laserdave



Joined: 11 Jul 2009
Posts: 2

View user's profile Send private message

DMX Routines from asm to CCS Compiler 18f4620
PostPosted: Sun Aug 30, 2009 4:10 am     Reply with quote

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







PostPosted: Sun Aug 30, 2009 8:20 am     Reply with quote

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







PostPosted: Sun Aug 30, 2009 8:24 am     Reply with quote

(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

View user's profile Send private message

PostPosted: Sun Aug 30, 2009 2:57 pm     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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