Terminal output working, but not input

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Terminal output working, but not input

Jump to solution
1,768 Views
dyspn
Contributor III

Hello,

 

On my board using the MCF52230 I'm using the QSPI's tertiary function as URXD1/UTXD1. I've made sure to change all the settings to set it to the right UART port and stuff. I can call printf() and it will appear in my terminal. The problem is when I call scanf() it hangs and waits for input, but I type a string and hit enter and I don't receive anything back. Really confused why it isn't working, so any help would be beneficial.

 

Here's what the code looks like.

char str[64] = "Test";   MCF_GPIO_PQSPAR = 0x0F; //Set QSPI to tertiary function URXD1/UTDX1 #if (CONSOLE_IO_SUPPORT || ENABLE_UART_SUPPORT)      printf("Enter stuff: "); //Appears in terminal      scanf(" %s",str); //Then nothing happens when I enter a string (can't see what I'm typing unless I have echo on)      printf("You entered %s",str); //Never get to this point, since I'm apparently not receiving anything  

 

I've tried the same thing with uart_putchar, and uart_getchar. Same thing happens. uart_putchar will work, but I won't get anything back when entering a char with uart_getchar.

 

It loops like the code is getting stuck on this loop in uart_getchar, and me inputting stuff into the terminal isn't letting me get out of it.

char uart_getchar (int channel) {    /* Wait until character has been received */     while (!(MCF_UART_USR(channel) & MCF_UART_USR_RXRDY))      {         //Getting stuck in this loop!     };     return (char)MCF_UART_URB(channel); }

 

Thanks!

Labels (1)
0 Kudos
1 Solution
1,407 Views
dyspn
Contributor III

Sooo.... checked to see if I could see the pin changing state, which I couldn't. Hardware designer says that doesn't make sense and scopes it again. I say what pin I'm using, pin 25, he then tells me that I've been using the wrong pin. The boards input is connected to pin 27, which doesn't even have a receive function. Apparently that was the pin that he scoped the first time and told me it was hitting it. I just assumed he was scoping the one that I was using. I was using the right transceiver pin, which is why it was working.

Rewired to use UART0, works perfectly.

Sigh...

View solution in original post

0 Kudos
13 Replies
1,407 Views
dyspn
Contributor III

Actually, I just realized, I'm not even sure the value I initialized it to (0x0F) is the right one to configure it for the tertiary function. It would explain why it's pretty much not working at all. Anyone know if that's the right value, or do I need to change it? I noticed that the transmit worked with 0xF0 as well, so it might be that the value I'm using is wrong.

0 Kudos
1,407 Views
TomE
Specialist II

> I'm not even sure the value I initialized it to (0x0F) is the right one to configure it for the tertiary function.

Section "14.6.5.2 Quad-Function Pin Assignment Registers" says "The fields are described in Table 14-7, which applies to all quad-function registers."

Tom

0 Kudos
1,407 Views
TomE
Specialist II

> MCF_GPIO_PQSPAR = 0x0F;

From Table 14-7, "0" selects GPIO and "1, 2, 3" select Secondary, Tertiary, Quaternary.

PORTQS has seven pins on it. You're setting PQSPAR (16 bit) to 0x000F, selecting pins 7-to-0 as 0,0,0,0,0,3,3. That corresponds to:

PORTQS0 = 3 = QSPI_DOUT / CANTX / UTXD1     / PQS(0)

PORTQS1 = 3 = QSPI_DIN  / CANRX / URXD1     / PQS(1)

PORTQS2 = 0 = QSPI_CLK  / SCL   / URTS1     / PQS(2)

PORTQS3 = 0 = QSPI_CS0  / SDA   / UCTS1     / PQS(3)

PORTQS4 = 0 = QSPI_CS1  / -     / FEC_TXEN  / PQS(4)

PORTQS5 = 0 = QSPI_CS2  / -     / FEC_TXCLK / PQS(5)

PORTQS6 = 0 = QSPI_CS3  / SYNCA / SYNCB     / PQS(6)

That's all fine as long as you weren't using the QSPI, I2C or Ethernet for anything.

You should post your UART configuration code. You might have UCSR1[RCS] set wrong.

Have you sent a (RECEIVER_ENABLE" command to UCR1 to enable it?

Are you getting any other (error) bits set in USR1?

Have you followed "26.5.2 UART Module Initialization Sequence" to the letter?

If the above doesn't work, time to check the hardware. I'd suggest that you reprogram PQSPAR to a GPIO, make sure it is an input, and then write some code that reads the port bit corresponding to URXD1. Have it print a line when the state changes (from 0 to 1 and 1 to 0). Then run that program and see if the code can see the port pin changing state when you send data, or when you just pull the receiver pin hi or low.

A suggestion on a different topic. Don't use scanf("%s", ...) in any code you write. If you do that by accident it might cost you a job interview. scanf("%63s", buf) is better, but "fgets(buf, sizeof(buf), stdin)" is preferable.

C's "bad" functions vs. their "good" alternatives - Stack Overflow

Tom

0 Kudos
1,407 Views
dyspn
Contributor III

I mean, I'm just using the UART code that gets created when you make a project. So, I'm not really sure why it wouldn't be working.

void uart_init(int channel, unsigned long systemClockKHz, unsigned long baudRate)

{

/*

* Initialize UART for serial communications

*/

register uint16 ubgs;

#if UART_SUPPORT_TYPE==UART_54451

uint32 vco;

uint32 divider;

uint32 bus_clk;

divider = ((MCF_CLOCK_PCR & 0x000000F0) >> 4) + 1;

vco = ((MCF_CLOCK_PCR >> 24) * systemClockKHz * 1000);

bus_clk = (vco / divider);

#endif

/*

* Reset Transmitter

*/

MCF_UART_UCR(channel) = MCF_UART_UCR_RESET_TX;

/*

* Reset Receiver

*/

MCF_UART_UCR(channel) = MCF_UART_UCR_RESET_RX;

/*

* Reset Mode Register

*/

MCF_UART_UCR(channel) = MCF_UART_UCR_RESET_MR;

/*

* No parity, 8-bits per character

*/

MCF_UART_UMR(channel) = (0

| MCF_UART_UMR_PM_NONE

| MCF_UART_UMR_BC_8 );

/*

* No echo or loopback, 1 stop bit

*/

MCF_UART_UMR(channel) = (0

| MCF_UART_UMR_CM_NORMAL

| MCF_UART_UMR_SB_STOP_BITS_1);

/*

* Set Rx and Tx baud by SYSTEM CLOCK

*/

MCF_UART_UCSR(channel) = (0

| MCF_UART_UCSR_RCS_SYS_CLK

| MCF_UART_UCSR_TCS_SYS_CLK);

/*

* Mask all UART interrupts

*/

MCF_UART_UIMR(channel) = 0;

/*

* Calculate baud settings

*/

#if UART_SUPPORT_TYPE==UART_54451

ubgs = (uint16)(((bus_clk >> 5) + (baudRate >> 1)) / baudRate);

#else

ubgs = (uint16)((systemClockKHz * 1000)/(baudRate * 32));

#endif

#if UART_SUPPORT_TYPE==UART_DIVIDER || UART_SUPPORT_TYPE == UART_5407

MCF_UART_UDU(channel) = (uint8)((ubgs & 0xFF00) >> 8);

MCF_UART_UDL(channel) = (uint8)(ubgs & 0x00FF);

#else /* UART_SUPPORT_TYPE!=UART_DIVIDER */

MCF_UART_UBG1(channel) = (uint8)((ubgs & 0xFF00) >> 8);

MCF_UART_UBG2(channel) = (uint8)(ubgs & 0x00FF);

#endif /* UART_SUPPORT_TYPE==UART_DIVIDER */

/*

* Enable receiver and transmitter

*/

MCF_UART_UCR(channel) = (0

| MCF_UART_UCR_TX_ENABLED

| MCF_UART_UCR_RX_ENABLED);

0 Kudos
1,407 Views
TomE
Specialist II

> I mean, I'm just using the UART code that gets created when you make a project.

Make a project with what, you haven't said? If it is a problems with the "project making thing" then there's probably a more appropriate forum for that software. This forum is mainly about the hardware.

> So, I'm not really sure why it wouldn't be working.

Welcome to programming and debugging. If it was easy we wouldn't need these forums. Have you compared the code you just included against:

>> Have you followed "26.5.2 UART Module Initialization Sequence" to the letter?

Have you followed my other suggestions?

Tom

0 Kudos
1,407 Views
dyspn
Contributor III

Also, I found this footnote "The use of an external PHY limits ADC, interrupt, and QSPI functionality. It also disables the UART0/1 and timer pins." Which might explain my problem, since there is a external PHY on the board...

Could that be the issue? Is there a way to turn off the external PHY, and would that allow me to use the UARTS?

0 Kudos
1,407 Views
TomE
Specialist II

> On my board

You haven't said what board that is, so I can't read the schematic from here (or download it or anything :-).

Is it a development board or a production board? If the former, then read the manual for that board. If the latter, then you should ask the designer.

You didn't say where that footnote is, which makes it hard to find what it was referring to. OK, Google found a match in the Data Sheet.


How come the board has an external PHY and also has a Serial Port connection? Or have you soldered some wires to pins on the board in an attempt to add a serial port? If it is a development board with a PHY and a serial port, then there's probably a documented way to use one option or the other, so you should read the manual for that board.

Tom

0 Kudos
1,406 Views
dyspn
Contributor III

Sorry, should have clarified. It's a custom board using the MCF52230, and it needs the serial and external phy, since it will sort of a translator between a serial device and the ethernet side. There's a connector that goes into the QSPI pins that I'm using for the serial. I tried disabling the external phy, but that didn't seem to do much.

We used a scope on it, and we can see the input hitting the receiver pin, so it doesn't look like it's hardware.

I've narrowed it down to an issue with MCF_UART_USR(channel), it's in the uart_getchar while statement with RXRDY. I printed them, and MCF_UART_USR(channel) is printing 0, while RXRDY is printing 1. I'm not sure if that means that the status register isn't even on, or it's throwing an error and just never getting out of the loop. But if that were the case, I'm not sure why the transmit would work fine but not the receiver, since the loop with MCF_UART_USR(channel) and TXRDY goes perfectly fine. I guess it's not taking in the values at all, I've put multiple printf statements and don't ever see anything change with input from me.

If the external phy is actually disabling the UART0/1, I don't think the trasmitter would even work? Not sure. Considering just moving to a software UART since I haven't come across any kind of fix for this.

0 Kudos
1,407 Views
TomE
Specialist II

> it needs the serial and external phy,

The chip comes with an internal Ethernet PHY and the pin assignment assumes you are using that. if you need an external PHY to connect a multiport switch chip, or optical ethernet, then you lose lots of other functionality, including UARTs 0 and 1.

You still have UART 2 available on Port C, so you should be using that instead.


Why are you even trying to program UART0 when the decision has already been made to use those pins for Ethernet?

> We used a scope on it, and we can see the input hitting the receiver pin,

That's good. Try reprogramming the pin as a GPIO as I suggested and see if the code can see the pin changing state. Is it the right polarity?

> MCF_UART_USR(channel) is printing 0, while RXRDY is printing 1.

RXRDY is a constant defined in a header somewhere. You don't need to print it. You should find the sources for ALL of those macros and see what they are really doing.

"MCF_UART_USR(channel) is printing 0" means none of the status bits are getting set. It isn't receiving anything, or isn't enabled to receive.


Type "MCF_UART_USR" into the Search Box at top right and read through the 11 or so hits. Someone else may have had the same problem years ago.

> If the external phy is actually disabling the UART0/1, I don't think the trasmitter would even work? Not sure.

The external PHY doesn't disable the UARTS. Your hardware designer DECIDES to use an external PHY, and therefore knows about all the other hardware that can't be used because the pins are now unavailable. He tells the programmer. The programmer then has to program all of the PxxPAR registers to assign the pins to the appropriate hardware-decided functions. That's why I said about your writing 0x0f to PSPAR: "That's all fine as long as you weren't using the QSPI, I2C or Ethernet for anything.".

By writing that value, you as a programmer have forced the pin state for all those other functions. If you only wanted to set the UART RX and TX pins you should have read that register, masked out the UART pins and then added in the new values. In your case that can be simplified to "MCF_GPIO_PQSPAR |= 0x0F;".

> If the external phy is actually disabling the UART0/1,

The external PHY will be driving levels into the pins it is connected to which prevent them being used as outputs from the CPU and prevents your feeding other inputs into those pins. Unless it has a feature that lets you disable those pins somehow. But why would you want to, you have to use UART2 anyway.

0 Kudos
1,407 Views
dyspn
Contributor III

You're right. The hardware designer told me the wrong thing, and said it was a external phy when it wasn't. Going to try your suggestion of testing by reprogramming it as a GPIO, and a few other things. I've searched quite a bit, and I haven't found anyone else that has had the same issue, or at least not with the same solution I need.

>It isn't receiving anything, or isn't enabled to receive.

That's...interesting. I guess my assumption was right. My code has it enabled to receive, right? So now I need to figure out why it isn't receiving anything.

Thanks

0 Kudos
1,407 Views
TomE
Specialist II

You can try to use the "Local Loopback" mode to see if you it can receive its own transmissions.

You can use the "Remote Loopback" to see if the pins are connected up properly.

Tom

0 Kudos
1,408 Views
dyspn
Contributor III

Sooo.... checked to see if I could see the pin changing state, which I couldn't. Hardware designer says that doesn't make sense and scopes it again. I say what pin I'm using, pin 25, he then tells me that I've been using the wrong pin. The boards input is connected to pin 27, which doesn't even have a receive function. Apparently that was the pin that he scoped the first time and told me it was hitting it. I just assumed he was scoping the one that I was using. I was using the right transceiver pin, which is why it was working.

Rewired to use UART0, works perfectly.

Sigh...

0 Kudos
1,407 Views
dyspn
Contributor III

It's the code that is generated when you create a project in CodeWarrior. The code follows the UART Module Initialization Sequence, and it seems to work since the transmitter does at least. Just not sure if it's a hardware issue or not, since if one's working and both are configured the same then the other should be as well. I don't see any reason in the code for it to not be.

And I haven't been able to follow your other suggestions yet, don't have access to the board again until Monday.

Thanks

0 Kudos