Rlp uart

Hi,

Does anyone have an example of UART in RLP on 4.3? I’m looking to run this on G120 (assuming it is faster?).

Cheers

There is a RLP sample on RS485, but this is identical for the uart part.
[url]https://www.ghielectronics.com/community/codeshare/entry/219[/url]

OK, thanks. My knowledge of C is limited so I will have to study the example carefully.

That is over 4 years old as well, so I’ll have to work out if any of the RLP implementation (on the native side) has changed.

Still, every day’s a school day! :think:

Does anyone know where I can find the relevant header files for UART on a G120? The link in that codeshare entry does not work.

Cheers

Edit; this one? https://www.lpcware.com/content/nxpfile/mcb1700-sample-code-bundle-lpc17xx-peripherals-using-keils-mdk-arm

LPC17xx should be good, G120 is LPC1788.

I have a few questions about the RS-485 example, if anyone has five minutes over a coffee to look at it? I’d be really grateful.

  1. Do I need to use GPIO pin 27 in the same way for UART? I think this is something that it specific to the RS-485 protocol because it is half-duplex?
  2. Would it make sense to move the work of the HCD_ReceiveByte function to the UART interrupt handler i.e. read from the receive register if the IIR value shows that there is receive data available? I’m thinking this could then fire an event in managed code
  3. What does the GlobalInterrupt do in the HCD_SendByte function? Why is it disabled before writing to the transmit register, then enabled again?
  4. Is data sent automatically after it is written to the transmit holding register (the UART interrupt then fires and the IIR values shows that the register is empty?)?
  5. How many bytes can be written to the transmit register? The example only writes one byte.
  6. When should FIFO be cleared/reset and why?
  7. RLP functions are called in the example using ‘RLPext->’. This is now ‘RLP->’ and has changed since this example was posted?

Thanks in advance.

@ cyberh0me - good questions!

You’re right that netmf is not the best option. This is mostly a learning exercise. I’d like to eventually move over to C/C++ and RLP seems to be a good taster and if I can do something faster too then that’s a bonus.

In case anyone is interested, this is the native code I’ve currently have working on a G120, also using the memory allocation trick that John(GHI) showed me recently (I haven’t tested the performance yet);

#define G120

 #include "RLP.h"
 #include "type.h"
 #include "uart.h"
 #include "lpc17xx.h"
 #include "stdbool.h"

/* UART definitions for UART 0 (COM1 in NETMF) */
 #define UART_IER        LPC_UART0->IER
 #define UART_IIR        LPC_UART0->IIR
 #define UART_LSR        LPC_UART0->LSR
 #define UART_THR        LPC_UART0->THR
 #define UART_RBR        LPC_UART0->RBR
 #define UART_FCR        LPC_UART0->FCR
 #define UART_INT        UART0_IRQn

void* ptr;
uint8_t* data;
uint8_t* length;

/**********************************************************************************
/* Interrupt Handler
/**/
void InterruptHandler(void * arg)
{
    uint8_t LSRValue;
    uint8_t IIRValue = UART_IIR;

    IIRValue >>= 1;        /* Skip pending bit in IIR */
    IIRValue &= 0x07;    /* Check bit 1~3, interrupt identification */

    if (IIRValue == IIR_THRE)    /* THRE, transmit holding register empty */
    {
        LSRValue = UART_LSR;    /* Check status in the LSR to see if valid data in U2THR or not */
    }
}

/**********************************************************************************
/* Initialise the driver.
/**/
bool HCD_Init()
{
    if (RLP->magic != RLP_EXT_MAGIC)
        return false;

    RLP->Interrupt.Uninstall(UART_INT);

    UART_IER = IER_THRE;    /* Enable UART2 interrupt */
    UART_FCR = 0x00;        /* Disable FIFO */

    /* Install interrupt handler */
    if (!RLP->Interrupt.Install(UART_INT, InterruptHandler, NULL))
        return false;

    return true;
}

/**********************************************************************************
/* Deinitialise the driver.
/**/
void HCD_Deinit()
{
    RLP->Interrupt.Uninstall(UART_INT);
}

/**********************************************************************************
/* Clear FIFO.
/**/
void HCD_ClearFifo()
{
    volatile uint8_t data;
    while (UART_LSR & LSR_RDR)
        data = UART_RBR;
}

/**********************************************************************************
/* Send a single byte over the UART port
/**/
void HCD_SendByte(uint8_t data)
{
    unsigned int status = RLP->Interrupt.IsGlobalInterruptEnabled();
    if (status > 0) RLP->Interrupt.GlobalInterruptDisable();
    UART_THR = data;
    if (status > 0) RLP->Interrupt.GlobalInterruptEnable();
    while (!(UART_LSR & LSR_TEMT));
    RLP->Delay(50);
}

/**********************************************************************************
/* called from managed code.
/**/
int InitCOM1(void** args)
{
    return HCD_Init();
}

/**********************************************************************************
/* called from managed code.
/**/
int DeinitCOM1(void** args)
{
    HCD_Deinit();
    return 1;
}

/**********************************************************************************
/* called from managed code.
/* sends the bytes from the data buffer, one at a time
/**/
int SendDataCOM1(void** args)
{
    uint8_t i;
    for (i = 0; i < *length; i++)
    {
        HCD_SendByte(data[i]);
    }
    return (int)i;
}

/**********************************************************************************
/* called from managed code.
/* initialises memory space to hold the data buffer
/**/
int InitCOMbuff(void** args) {
    ptr = RLP->malloc(64 + 1);

    if (!ptr)
        return 0;

    data = (uint8_t*)(ptr + 0);
    length = (uint8_t*)(ptr + 64);

    return (int)ptr;
}

/**********************************************************************************
/* called from managed code.
/* uninitialises memory space to hold the data buffer
/**/
int UninitCOMbuff(void** args) {
    RLP->free(ptr);

    return 0;
}

And some simple managed code to test it with;

SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
serialPort.Open();
            
var image = new RuntimeLoadableProcedures.ElfImage(Resources.GetBytes(Resources.BinaryResources.TemplateG120_43));
            
var init = image.FindFunction("InitCOM1");
var result = init.Invoke();
Debug.Print("InitCOM1 returned: " + result.ToString());

var initCOMbuffer = image.FindFunction("InitCOMbuff");
var bufferAddress = (uint)initCOMbuffer.Invoke();
Debug.Print("InitCOMbuff returned: " + bufferAddress.ToString());
if (bufferAddress == 0)
       throw new OutOfMemoryException();

var byteArray = new byte[65];
var toSend = "Man United are the best!! :-D";
Encoding.UTF8.GetBytes(toSend, 0, toSend.Length, byteArray, 0);
byteArray[64] = (byte)toSend.Length;

AddressSpace.Write(bufferAddress, byteArray);

var sendData = image.FindFunction("SendDataCOM1");
result = sendData.Invoke();
Debug.Print("SendDataCOM1 returned: " + result.ToString());
            
var deinit = image.FindFunction("DeinitCOM1");
result = deinit.Invoke();
Debug.Print("DeinitCOM1 returned: " + result.ToString());

var uninitCOMbuff = image.FindFunction("UninitCOMbuff");
result = uninitCOMbuff.Invoke();
Debug.Print("UninitCOMbuff returned: " + result.ToString());

serialPort.Close();