Author Topic: Strange UART operation  (Read 744 times)

Offline neil

  • Sr. Member
  • ****
  • Posts: 425
    • View Profile
Strange UART operation
« on: February 03, 2020, 05:56:10 PM »
Hi Mark
  I am using the MCF52259 chip and been running the UART without any problems. I have been running at various speeds and parity, but I am communicating with a device that requires 9600N82  (2 stop bits).  I have only every had to set 1 stop bit,  so I set the config setting to :

tInterfaceParameters.Config = (CHAR_8 + parity + stop_bits +  CHAR_MODE);

where parity=0 and I set stop_bits to 0x20 . This worked well , but then I noticed that the stop bits value should have been 0x10. Since changing this to 0x10 it doesnt communicate properly. Looking at the registers the UMR12 and UMR22 is set to 0x7, indicating no parity with stop bits modified. When I set it to 0x10 (as it should be), both UMR12  and UMR22  are both set to 0xf .  Indicating multidrop in UMR11 and stop bit length of 0xf .  I thought it would be 2 for no parity? 

I can communicate with the device from my PC application with setting the serial port to 2 stop bits.  And to make it more strange. I can communicate  with my pc application from the mcf52259 by setting the stop_bits to 0x10.

Best Regards
Neil





Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3103
    • View Profile
    • uTasker
Re: Strange UART operation
« Reply #1 on: February 03, 2020, 07:05:10 PM »
Neil

This is the code that sets the values to the registers

    if (pars->Config & (RS232_ODD_PARITY | RS232_EVEN_PARITY)) {         // {104}
        if (pars->Config & RS232_ODD_PARITY) {                           // {104}
          *ucReg = (unsigned char)(UART_WITH_PARITY | ucBits | ODD_PARITY); // 7/8 bits - odd parity
        }
        else {
          *ucReg = (unsigned char)(UART_WITH_PARITY | ucBits);           // 7/8 bits - even parity
        }
    }
    else {
        *ucReg = (unsigned char)(UART_NO_PARITY | ucBits/* | 0x0f*/);  /* TEST MULTIDROP */             // 7/8 bits - no parity
    }

    if (pars->Config & TWO_STOPS) {                                      // {104} the mode register 2 has been selected by previous write
        ucBits = UART_TWO_STOP;
    }
    else if (pars->Config & ONE_HALF_STOPS) {                            // {104}
        ucBits = UART_ONE_HALF_STOP;
    }
    else {
        ucBits = UART_ONE_STOP;
    }


Note that there is a 0x0f there to test multi-drop mode. Is it possible that his is enabled in your version?

Regards

Mark

Offline neil

  • Sr. Member
  • ****
  • Posts: 425
    • View Profile
Re: Strange UART operation
« Reply #2 on: February 03, 2020, 07:07:26 PM »
Hi Mark
  No, it is like your bit of code below and is commented out.

Best Regards
Neil

Offline neil

  • Sr. Member
  • ****
  • Posts: 425
    • View Profile
Re: Strange UART operation
« Reply #3 on: February 03, 2020, 08:52:16 PM »
HI Mark
  I have attached a couple of screen shots. Im setting the uart to 9600N82 . 

The first snap shot (1.png) : Line highlighted is where I am stepping.
 UMR12 & UMR12= 0x13  . Sets 8 bits no partiy on UMR12 , setting 2 regs with one write.

The second snap shot (2.png) :
UMR12 & UMR22 = 0xf ;  This is what is in ucBits variable (pointed to by arrow). So previous value is overwritten.

I dont understand why both registers get sets to the same value at the same time. The second snapshot looks like its setting 2 stop bits, but it also sets UMR12 register. Why is this?
If its writing to 2 registers at the same time, why are both the same value?

Best Regards
Neil
« Last Edit: February 03, 2020, 09:33:05 PM by neil »

Offline neil

  • Sr. Member
  • ****
  • Posts: 425
    • View Profile
Re: Strange UART operation
« Reply #4 on: February 04, 2020, 12:08:55 PM »
Hi Mark
  I looked further into this issue, and slightly different the way to access the registers than other processors I have used. 

I see to access the UMR1n and UMR2n registers the reset mode register has to point to the UMR1n. I find it strange that when updating any of the UMR1n or UMR2n, the other register also updates with the same value. I tried the following to write and read to the 2 registers.

after the *ucReg = ucBits; line in your code I added the below so I can step through it.

TmpPtr=ucReg ; //when you accessed the UMR1n register I took a copy of the address.
ucReg = fnSelectChannel(Channel); 
*ucReg = UART_RESET_CMD_PTR; //reset mode register
 ucReg =TmpPtr; //point to  UMR1n
 *ucReg = 2; //place 2 into the register.  In the Register Window the 2 UMR1n and UMR2n changed to 2, which is weird
  *ucReg = 3; //place 3 into the UMR2n register.  In the Register Window the 2 UMR1n and UMR2n changed to 3, again which is weird

//now read the 2 registers
   ucReg = fnSelectChannel(Channel);
  *ucReg = UART_RESET_CMD_PTR; //reset mode register
ucReg =TmpPtr; //point to  UMR1n

Dta1=(unsigned char)*ucReg; //read UMR1n
Dta2=(unsigned char)*ucReg;//read UMR2n

Now Dta1 and DTA2 was equal to 3, which isnt correct.  This isnt what I expected , why is this?

Best Regards
Neil
« Last Edit: February 04, 2020, 12:10:46 PM by neil »

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3103
    • View Profile
    • uTasker
Re: Strange UART operation
« Reply #5 on: February 04, 2020, 05:41:22 PM »
Neil

I believe that you need to issue the RESET MODE REGISTER POINTER command before reading back the registers. If not it only reads back the UMR2n register, resulting in the same value being read no matter how often it is read.

Regards

Mark

Offline neil

  • Sr. Member
  • ****
  • Posts: 425
    • View Profile
Re: Strange UART operation
« Reply #6 on: February 04, 2020, 05:44:20 PM »
Mark
  After setting the values I had the instruction "*ucReg = UART_RESET_CMD_PTR; ", pointed the pointer to UMR1n ,then read in the registers . Is there anything else I have to do?

Neil

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3103
    • View Profile
    • uTasker
Re: Strange UART operation
« Reply #7 on: February 04, 2020, 07:25:35 PM »
Aaah, I missed it.

I know of nothing else that needs to be done for the reading of the two registers but I would advise using

Dta1=(volatile unsigned char)*ucReg; //read UMR1n
Dta2=(volatile unsigned char)*ucReg;//read UMR2n


to ensure that the compiler is not optimising out one of the reads.

Regards

Mark