uartpic24

UTXEN will not set


The chip is PIC24FJ256GB210

The #UTXEN bit on UART #3 will not set.

It sets fine on UART #1, using the exact same instruction sequence. Same thing for UART #2.

WORKS...

 096E6  204000     mov.w #0x400,0x0000            111:           Mov     #Uart_1_Status_Control_Pattern, W0      ;Defined in CONSTANT.INC file
 096E8  881110     mov.w 0x0000,0x0222            112:           Mov     W0, U1STA                               ;ibid, page 230 Reg 17-2

FAILS...

09748  204000     mov.w #0x400,0x0000            248:           Mov.W   #Uart_3_Status_Control_Pattern, W0              ;Defined in CONSTANT.INC file
0974A  881290     mov.w 0x0000,0x0252            249:           Mov.W   W0, U3STA                                       ;ibid, page 230, Reg 17-2

So I thought, "ah, it's a single bit that I want, and the full word move on top of all the read-only bits is somehow causing the problem. I'll just do a single bit set".

No, still won't set that bit.

FAILS...

 09754  A84253     bset.b 0x0253,#2               256:      Bset.W  U3STA, #UTXEN                   ;DEBUG DEBUG DEBUG Date: 2013-02-18  Time: 11:37:07 

--UPDATE--

I am able to set the bit in MpLab. What's the difference ?

I am really confused. What else could be involved here that prevents that bit from being set ?


Solution

  • The Error

    Along with the UART Status register, there is a corresponding UART Mode register for each UART in the PIC24 that I'm using.

    In this case, its name is U3MODE.

    There is a "UART Enable" bit in that corresponding mode register

    In this case that bit is called UARTEN, which is (according to my documentation for this specific PIC) the high order bit.

    According to the file p24FJ256GB210.inc which I use to assemble this, they have it defined like this...

        .equiv UARTEN,  0x000F
    

    If that bit in the U3MODE register is not set before you try to set the UTXEN bit in the corresponding status register (in this case the U3STA register), then the status register will not change its value the way you want.

    The Fix

    Set the UARTEN bit in the U3MODE register first, then you can set the UTXEN bit in the U3STA register.

    The Code Example

    I've copied from the disassembly window here to give both the source, and the actual hex values, and the physical hex encoding of each instruction.

    The labels are actually just contstants that I made up; code that works, code you can read; that sort of idea. You can see their values in the disassembly sections of each instruction.

    The big deal in this case is to make sure that the high order bit of the U3MODE register before you try to set the bits in the U3STA register.

    This fixed this problem.

                                                                                 ;-------------------------------------
                                                                                 ; --- THIS MUST COME FIRST ---
                                                                                 ;
    280080  mov.w #0x8008,0x0000  Mov.W   #Uart_3_Mode_Pattern, W0            ;Defined in Constant.Inc File
    881280  mov.w 0x0000,0x0250   Mov.W   W0, U3MODE                          ;Documented in Manual DS39975A, p. 228, Register 17-1
                                                                                 ;
                                                                                 ; --- IN ORDER FOR THIS TO WORK ---
                                                                                 ;
    204000  mov.w #0x400,0x0000   Mov.W   #Uart_3_Status_Control_Pattern, W0  ;Defined in CONSTANT.INC file
    881290  mov.w 0x0000,0x0252   Mov.W   W0, U3STA                           ;Manual DS39975A, page 230, Reg 17-2