This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

EK-TM4C1294XL: Telent to serial bridge requires GPIO actuation in design based on the TIVA TM4C1294XL Enet_s2e application using TivaWare, lwip and FreeRTOS.

Part Number: EK-TM4C1294XL

 I have telnet attempting to talk to a serial port on a custom board (based on the TIVA TM4C1294XL Enet_s2e application). This is basically the EK-TM4C1294XL with a additional serial port at Port c, pins 5,6,7 (UCA0). The same board is setup to bridge data from the USB to the same serial port. The serial port requires a GPIO actuated to transmit (Port C pin5). The USB to serial bridge works fine. In fact I see data on the telnet port when the USB to serial bridge  is talking (in either direction). In order to get the Telent to send data to the serial port I have to actuate the GPIO pin. Using the smae software in the telnet side that I use with the serial port messes up many telnet values.

    When SerialSend() in telent.c sends a character to the TX FIFO it does not actuated the TEST_485_EN. If I take the code from the serial_task.c routine that performs the same function successfully, it badly messes up the telnet code. ui32Port, which should be 0 or 1 goes to a large bogus number. I imagine the assert statement disables all IO at that point. Commenting out the two ROM_GPIOPinWrite statements returns everything back to normal?? Guess I could bit bang th UCAx??? control registers.

serial.c, which is only called only by telnet:

============================================================

void SerialSend(uint32_t ui32Port, uint8_t ui8Char)
{

    ASSERT(ui32Port < MAX_S2E_PORTS);    // Check the arguments.

    //
    // Disable the UART transmit interrupt while determining how to handle this
    // character.  Failure to do so could result in the loss of this character,
    // or stalled output due to this character being placed into the UART
    // transmit buffer but never transferred out into the UART FIFO.
    //
    UARTIntDisable(g_ui32UARTBase[ui32Port], UART_INT_TX);

    if(RingBufEmpty(&g_sTxBuf[ui32Port]) && (UARTSpaceAvail(g_ui32UARTBase[ui32Port])))
    {
       // ROM_GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_5, 1);   // SET 485 TALK HERE GAA 03Nov2017
       UARTCharPut(g_ui32UARTBase[ui32Port], ui8Char);     // Write this character directly into the FIFO.
       // ROM_GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_5, 0);   // CLR 485 listen HERE GAA 03Nov2017
    }
   else if(!RingBufFull(&g_sTxBuf[ui32Port]))              // See if there is room in the transmit buffer.
    {
       RingBufWriteOne(&g_sTxBuf[ui32Port], ui8Char);      // Put this character into the transmit buffer.
    }


    UARTIntEnable(g_ui32UARTBase[ui32Port], UART_INT_TX);   // Enable the UART transmit interrupt.
}

============================================================

The SerialTask() which blocks waiting on events from the serial ISR uses this approach successfully:

============================================================static void SerialTask(void *pvParameters)
{
    tSerialEvent sEvent;

   while(1)                                                          // Loop forever.
    {
      xQueueReceive(g_QueSerial, (void*) &sEvent, portMAX_DELAY);    // Block until a message is put in queue by the interrupt handler.

      if(sEvent.eEventType == RX)
        {
           if((g_sParameters.sPort[sEvent.ui8Port].ui8Flags &        // If Telnet protocol is enabled, check for incoming IAC character,
                PORT_FLAG_PROTOCOL) == PORT_PROTOCOL_TELNET)
              {
                if((sEvent.ui8Char == TELNET_IAC) &&                 // If this is a Telnet IAC character, write it twice.
                   (RingBufFree(&g_sRxBuf[sEvent.ui8Port]) >= 2))
                   {
                    RingBufWriteOne(&g_sRxBuf[sEvent.ui8Port], sEvent.ui8Char);
                    RingBufWriteOne(&g_sRxBuf[sEvent.ui8Port], sEvent.ui8Char);
                    }

                else if((sEvent.ui8Char != TELNET_IAC) &&                 // If not a Telnet IAC character, only write it once.
                        (RingBufFree(&g_sRxBuf[sEvent.ui8Port]) >= 1))
                    {
                    RingBufWriteOne(&g_sRxBuf[sEvent.ui8Port], sEvent.ui8Char);
                   }
             }
            else                                                            // If not Telnet, then only write the data once.
              {
                RingBufWriteOne(&g_sRxBuf[sEvent.ui8Port], sEvent.ui8Char);
               }
       }

            else                                                            // Check if it's a TX interrupt
             {

            while(!RingBufEmpty(&g_sTxBuf[sEvent.ui8Port]) &&               // Loop while there is space in the transmit FIFO
                  UARTSpaceAvail(g_ui32UARTBase[sEvent.ui8Port]))
            {
                ROM_GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_5, 1);           // SET 485 TALK HERE
                UARTCharPut(g_ui32UARTBase[sEvent.ui8Port],
                RingBufReadOne(&g_sTxBuf[sEvent.ui8Port]));     // Write the next character into the transmit FIFO.
                ROM_GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_5, 0);           // CLR 485 listen HERE
            }
        }
    }
}

  • Hi Garry,

    Gary Armstrong said:
    ROM_GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_5, 1);   // SET 485 TALK HERE GAA 03Nov2017

      If you want to set PC5 high then you will need to write ROM_GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_5, GPIO_PIN_5) instead or equivalent to ROM_GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_5, 0x20).

  • Thank you for replying. I'll make the change when I get to work Monday.

    I'm curious why the presence of ROM_GPIOPinWrite() messes up ui32Port variable in the telent task? I imagine the assert call at the beginning of SerialSend() disables the GPIO library or the GPIO ports??

    ASSERT(ui32Port < MAX_S2E_PORTS); // Check the arguments.

    The UARTCharPut() writes directly to the UART and the UART should transit at that point but it does not?? TM4C1294 Data Sht p.1175

    UARTCharPut(g_ui32UARTBase[ui32Port], ui8Char); // Write this character directly into the FIFO.


    Why do these calls work in the SerialTask() but not in Serial (under the telent task)??? I can put the scope on the respective pin and the pin is being toggled is toggled in the serial task. Cant help but think this has to do with the include files.
  • Found the reference to the GPIOPinWrite() function in the Drivers Lib Users Guide, p.280. Looks like the call is correct. There again it works at another location in the code. Haven't found the ROM version of that call ROM_GPIOPinWrite(). Not sure what the difference is...
    14.2.3.46 GPIOPinWrite
    Writes a value to the specified pin(s).
    Prototype:
    void
    GPIOPinWrite(uint32_t ui32Port, uint8_t ui8Pins, uint8_t ui8Val)
    Parameters:
    ui32Port is the base address of the GPIO port.
    ui8Pins is the bit-packed representation of the pin(s).
    ui8Val is the value to write to the pin(s).
    Description:
    Writes the corresponding bit values to the output pin(s) specified by ui8Pins. Writing to a pin
    configured as an input pin has no effect.
    The pin(s) are specified using a bit-packed byte, where each bit that is set identifies the pin to
    be accessed, and where bit 0 of the byte represents GPIO port pin 0, bit 1 represents GPIO
    port pin 1, and so on.
    Returns:
    None.
  • Hi Gary,
    Think of the ui8Pins as a gate/mask to propagate the value that you want to output onto the pins. If GPIO_PIN_5(0x20) is the mask to open the gate for writing to the pin 5 then if you want to set the pin you will need to provide the ui8Val with 0x20 in order to set GPIO_PIN_5 high.

    What is the MAX_S2E_PORTS you define for and what is the ui32Port you pass as the argument into the SerialSend()?
  • MAX_S2E_Ports = 2. The ENET_S2E project is designed for two channels of communication using telnet ports 23 and 26 and UARTs 3 and 4, The design has been modified to use UART5 on channel 1 (Telnet port 26) so ui32Port should always be 1.Really not sure why ui32Port is messed up, possibly a stack problem?? I discovered that I incorrectly thought that UART5 was working, but it is not. So my original statement that UARTPut, and ROM_GPIOPinWrite() was working in the serial task but not in the telnet task is incorrect. It looks like the UART comm is bad every where. I have a new EK-TM4C1294XL LaunchPad and will download the latest code today so I can observe a working system. I have inherited this project from  a disgruntle engineer that has left the company.

  • The  new launchpad works with no sw modifications, not sure what my predecessor did to mess the other design up so bad.????