Menu

Setup HW UART port in PIC 18F47Q43

ikonsgr74
13 hours ago
9 hours ago
  • ikonsgr74

    ikonsgr74 - 13 hours ago

    I'm trying to migrate a code i have for PIC 18F47Q10 to PIC 18F47Q43. I manage to make all needed updates (mostly declare different names for PPS and CLC's) and code is compiled without errors, but for some reason the hw UART port doesn't seem to work (i got no response to either output or input).
    This is the code i use, regarding USART setup, for PIC 18F47Q10 which works ok:

    #chip 18F47q10, 64
    #option explicit
    
        #startup InitPPS, 85
        #define PPSToolPart 18f47q10
    function
        #define USART2_BAUD_RATE 115200
        #define BUFFER_SIZE 2900
        #define USART2_DELAY 0 ms
        #define USART2_BLOCKING
        Sub InitPPS
         UNLOCKPPS
        RX2PPS = 0x0009    'RB1 > RX2
        RB2PPS = 0x000B    'TX2 > RB2
            LOCKPPS
        End Sub
          On Interrupt UsartRX2Ready Call readUSART
    

    And this is the modified code for PIC 18F47Q43:

    #chip 18F47q43, 64
    #option explicit
    
        #startup InitPPS, 85
        #define PPSToolPart 18f47q43
    function
        #define USART2_BAUD_RATE 115200
        #define BUFFER_SIZE 2900
        #define USART2_DELAY 0 ms
        #define USART2_BLOCKING
        Sub InitPPS
         UNLOCKPPS
           RB2PPS = 0x0023    // TX2 > RB2
          U2RXPPS = 0x0009    // RB1 > RX2
          LOCKPPS
        End Sub
          On Interrupt UART2ReceiveInterrupt Call readUSART
    

    For the conversion i used PPS and CLC Designer tools, and for the name of the Interrupt routine (to place received byte into a ring buffer) i consulted the 18F47Q43.dat file in gcbasic\chipdata folder.
    And this is the ASM code i got for INITUSART function, for PIC 18F47Q10:

     ;Source: usart.h (1242)
    INITUSART
    ;Set the default value for USART handler - required when more than one USART
    ;comport = SCRIPT_DEFAULT_COMPORT
        movlw   1
        movwf   COMPORT,ACCESS
    ;PIC USART 2 Init
    ;Set baud rate
    ;SPBRG2 = SPBRGL_TEMP2
        movlw   137
        banksel SPBRG2
        movwf   SPBRG2,BANKED
    ;SPBRGH2 = SPBRGH_TEMP2
        clrf    SPBRGH2,BANKED
    ;BAUD2CON_BRG16 = BRG16_TEMP2
        bsf BAUD2CON,BRG16,BANKED
    ;TX2STA_BRGH = BRGH_TEMP2
        bsf TX2STA,BRGH,BANKED
    ;Enable async mode
    ;Set TX2STA_SYNC Off
        bcf TX2STA,SYNC,BANKED
    ;Set RC2STA_SPEN On
        bsf RC2STA,SPEN,BANKED
    ;Enable Continuous Receive and Transmit Enable bit
    ;Set RC2STA_CREN On
        bsf RC2STA,CREN,BANKED
    ;Set TX2STA_TXEN On
        bsf TX2STA,TXEN,BANKED
        banksel 0
        return 
    

    And for PIC 18F47Q43:

    ;Source: usart.h (1242)
    INITUSART
    ;Set the default value for USART handler - required when more than one USART
    ;comport = SCRIPT_DEFAULT_COMPORT
        movlw   1
        movwf   COMPORT,ACCESS
    ;PIC USART 2 Init
    ;U2BRGH=SPBRGH_TEMP2
        banksel U2BRGH
        clrf    U2BRGH,BANKED
    ;U2BRGL=SPBRGL_TEMP2
        movlw   137
        movwf   U2BRGL,BANKED
    ;U2BRGS = BRGS2_SCRIPT
        bsf U2CON0,U2BRGS,BANKED
    ;ON_U2CON1=1
        bsf U2CON1,ON_U2CON1,BANKED
    ;U2TXEN=1
        bsf U2CON0,U2TXEN,BANKED
    ;U2RXEN=1
        bsf U2CON0,U2RXEN,BANKED
        banksel 0
        return
    
     

    Last edit: ikonsgr74 13 hours ago
  • Anobium

    Anobium - 12 hours ago

    The PPS and the ASM all looks correct. I was comparing here to MPLAB.

    So do the following. Do the basic work ?

    Remove the interrupt. Use a simple get data send data. Does that work ?

        #chip 18F47q43, 64
    #option explicit
    
        #startup InitPPS, 85
        #define PPSToolPart 18f47q43
    
        #define USART2_BAUD_RATE 115200
        #define USART2_DELAY OFF
        #define USART2_BLOCKING
        Sub InitPPS
         UNLOCKPPS
          // PPS is correct.
           RB2PPS = 0x0023    // TX2 > RB2
           U2RXPPS = 0x0009    // RB1 > RX2    
          LOCKPPS
        End Sub
    
        // Not really needed but for testing
        Comport = 2
    
        Do
          If USART2HasData Then
    
            // Send the RX to the TX 
            HserPrint HSerReceiveFrom(2), 2 
          End If
        Loop
    
     
  • Anobium

    Anobium - 12 hours ago

    The PPS and the ASM all looks correct. I was comparing here to MPLAB.

    So do the following. Do the basic work ?

    Remove the interrupt. Use a simple get data send data. Does that work ?

        #chip 18F47q43, 64
    #option explicit
    
        #startup InitPPS, 85
        #define PPSToolPart 18f47q43
    
        #define USART2_BAUD_RATE 115200
        #define USART2_DELAY OFF
        #define USART2_BLOCKING
        Sub InitPPS
         UNLOCKPPS
          // PPS is correct.
           RB2PPS = 0x0023    // TX2 > RB2
           U2RXPPS = 0x0009    // RB1 > RX2    
          LOCKPPS
        End Sub
    
        // Not really needed but for testing
        Comport = 2
    
        Do
          If USART2HasData Then
    
            // Send the RX to the TX 
            HserPrint HSerReceiveFrom(2), 2 
          End If
        Loop
    
     
  • ikonsgr74

    ikonsgr74 - 11 hours ago

    I connect the board with PIC to an amstrad cpc. Using a usb2serial cable (which is verified that works ok) i tried this code instead:

    RESTART:
       If USART2HasData Then
          data_buf=HSerReceive2
            // Send the RX to the TX
            hsersend data_buf,2
            wait 500 ms
            ;HserPrint HSerReceiveFrom(2), 2
    
          End If
    goto restart
    

    The good news is that whenever i send a character to the Amstrad (e.g. PIC's usart port), i get a respond back, BUT not with the character i sent, instead i always get ÿÿ characters as respond to PC terminal...
    Exactly the same behavior i got whe i use HserPrint HSerReceiveFrom(2), 2 instead of hsersend data_buf,2.
    port speed is set to 115200bps at both ends, and it's the only speed in terminal that i get a respond, so most probable baud rate is correctly set.
    Does this give any clue?

     

    Last edit: ikonsgr74 11 hours ago
  • ikonsgr74

    ikonsgr74 - 11 hours ago

    I just try the above code but without the wait. I try to send many characters and USART responds back with the same number of characters, but again are completely irrelevant and not the same every time! For example:
    I sent 3 times '12345' and i got in response:
    ¿ÿ÷¿
    o»÷÷
     ßû¿
    Even when i send i single same char i got a different respond each time, for example i sent 3 times '2' and got:
    ÷
    ¿
    ÿ

     

    Last edit: ikonsgr74 11 hours ago
  • Anobium

    Anobium - 10 hours ago

    Baud Rate calcs.

    MPLAB 64Mhz at 115k
    ~~~
    // BRGL 138;
    U2BRGL = 0x8A;

    // BRGH 0; 
    U2BRGH = 0x00;
    
    GCBASIC  64Mhz at 115k
    

    ;U2BRGH=SPBRGH_TEMP2
    banksel U2BRGH
    clrf U2BRGH,BANKED = 0
    ;U2BRGL=SPBRGL_TEMP2
    movlw 137
    movwf U2BRGL,BANKED = 137

    So, I think the baud rate is correct.
    
    -----------------------------
    
    The setting of Tx, Rx, En and Baud Rate Generator Speed Select look correct.  These all set U2CON0 and U2CON1.
    
    ----------------------
    
    The OSCFreq looks correct. As this impacts the USART this is an important check.  You can inspect the OSCFreq by changing the OSCout in the config and checking with a scope.
    
    --------------------
    
    So, need to rule out the existing INIT and the Recieve. Try this or a variant of this.  This will recieve and send back the data.
    
    What happens ?
    

    chip 18F47q43, 64

    option explicit

    #startup InitPPS, 85
    #define PPSToolPart 18f47q43
    
    #define USART2_BAUD_RATE 115200
    #define USART2_DELAY OFF
    #define USART2_BLOCKING
    Sub InitPPS
     UNLOCKPPS
      // PPS is correct.
       RB2PPS = 0x0023    // TX2 > RB2
       U2RXPPS = 0x0009    // RB1 > RX2    
      LOCKPPS
    End Sub
    
    // Set the UART2 module to the options selected in the user interface.
    
    // P1L 0; 
    U2P1L = 0x00;
    
    // P2L 0; 
    U2P2L = 0x00;
    
    // P3L 0; 
    U2P3L = 0x00;
    
    // BRGS high speed; MODE Asynchronous 8-bit mode; RXEN enabled; TXEN enabled; ABDEN disabled; 
    U2CON0 = 0xB0;
    
    // RXBIMD Set RXBKIF on rising RX input; BRKOVR disabled; WUE disabled; SENDB disabled; ON enabled; 
    U2CON1 = 0x80;
    
    // TXPOL not inverted; FLO off; RXPOL not inverted; RUNOVF RX input shifter stops all activity; STP Transmit 1Stop bit, receiver verifies first Stop bit; 
    U2CON2 = 0x00;
    
    // BRGL 138; 
    U2BRGL = 0x8A;
    
    // BRGH 0; 
    U2BRGH = 0x00;
    
    // STPMD in middle of first Stop bit; TXWRE No error; 
    U2FIFO = 0x00;
    
    // ABDIF Auto-baud not enabled or not complete; WUIF WUE not enabled by software; ABDIE disabled; 
    U2UIR = 0x00;
    
    // ABDOVF Not overflowed; TXCIF 0; RXBKIF No Break detected; RXFOIF not overflowed; CERIF No Checksum error; 
    U2ERRIR = 0x00;
    
    // TXCIE disabled; FERIE disabled; TXMTIE disabled; ABDOVE disabled; CERIE disabled; RXFOIE disabled; PERIE disabled; RXBKIE disabled; 
    U2ERRIE = 0x00;
    
    
    Do
      If USART2HasData Then
    
        // Send the RX to the TX 
        Wait While TX2IF = Off
        U2TXB = U2RXB 
      End If
    Loop
    

    ~~~

     
  • ikonsgr74

    ikonsgr74 - 10 hours ago

    YES! That worked straight!

     
  • Anobium

    Anobium - 9 hours ago

    Ok.

    Isolate the issue by removing the special init. Leave the do-loop. Does the standard init work?

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.