puart strange behaviour.

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Hi All,

My fight with puart continues. Now I try to have repeatable and correct output from it.

What I do:

uint8_t send_frame(uint8_t ID, uint8_t *data, uint8_t len) {
    int i=0;
    if(len>8) return 0;
    puart_write(0x55);
    puart_write(id_to_protected_id(ID));
    puart_synchronousWrite(data, len);
    puart_write(frame_checksum(data, len));
}

the call looks something like this:

uint8_t data[] = {0, 0};

send_frame(0, data, sizeof(data));


What I should get on puart output is:

0x55, 0x80, 0x00, 0x00, 0xff

And this is what I sometimes get. But more often than not what I get is - look at the picture in attachment.

What is this BREAK doing there? How to get it out of there? I really, really, really cannot have it this way.

Any ideas?

BR,

M.W.

0 Likes
1 Solution
Anonymous
Not applicable

Hello Marcin,

Can you use the uart_firmware_upgrade app as a starting point:

pastedImage_0.png

Thanks

JT

View solution in original post

0 Likes
9 Replies
Anonymous
Not applicable

m.wolcendorf

1.  What baud rate did you configure?

2.  Did you configure the Flow Control (SoC ONLY)?

Thanks

JT

0 Likes
Anonymous
Not applicable

Sorry not to mention that (although you can see the speed in the picture); the port has been set to 19200bps and there is no flow control.

How could flow control affect the serial port so it would stop transmitting mid-byte? I have examples where the puart stops while transmitting 1, and then resumes after ~30ms, and transmits the rest of the byte (it's easier to see while transmitting non-zeroes).

I suspect the PUART being a soft-uart, and something (like BLE) boggling up the timings. But this is just a wild guess.

BR,

M.W.

0 Likes

Just to try out a few things. Perhaps you can set the buad rate to the max at 115200bps. Observe the effect with and without flow control. One should expect better reliability with flow control. And our flow control is hw based with two additional physical pins, cts and rts.

0 Likes
Anonymous
Not applicable

Setting the higher speed for test is not a problem, but the target software will have to live with 19200.

I am at a loss how using the flow control could help me - it is not reception I am having problems with, it is sending. If the other side is ready to receive - and it always is - who is going to tell the transmitter that it is ready to transmit? Or - to put it another way - what condition should stop the transmitter from transmitting if the target of the transmission is ready to receive?

Besides - the target application does not have a flow control, so all of it has to work reliably without one.

I will see if 115200 suffers from this issue, and report back.

BR,

M.W.

0 Likes
Anonymous
Not applicable

The 115200 has the same issue. There is a break sequence (or rather a puart stuck at 0 bit) of ~12ms in place of the 4'th byte.
See the attached picture. Screenshot_2015-05-21_0_113955.png

0 Likes

bluetooth_mdw

Are you trying to block the part from going to sleep until you verify that the FIFO is empty?  Someone else here was doing something similar, but I can't seem to find the thread.

I think this is the right thread: Re: Peripheral UART missing bytes

The general idea is:

    if (!P_UART_RX_FIFO_NOT_EMPTY() &&
P_UART_TX_FIFO_IS_EMPTY())

        return ~0;
        // Allow sleep, let FW choose
time to sleep, if TX and RX FIFOs are empty

    else

       return 0;  
      // Disable sleep if either is not empty.

gsbhoot1020

0 Likes
Anonymous
Not applicable

Thank you for the answer. However, it does not solve anything.

OK, what I do :

APPLICATION_INIT()
{
    bleapp_set_cfg((UINT8 *)gatt_database,
                   gatt_database_len,
                   (void *)&app_cfg,
                   (void *)/**/&app_puart_cfg/** /NULL/**/,
                   (void *)&app_gpio_cfg,
                   app_create);
    serial_bridge_init(&app_puart_cfg);
}

Now - I cannot substitute the app_puart_cfg with NULL and make all the configuration in serial_bridge_init, because it does not work (I get "1F" transmitted over and over again, and this is not what I want).

Here is what I put in the serial port initialisation (taken directly from example PDF, MMP920732HW-AN101-R.pdf):

void serial_bridge_init(const BLE_PROFILE_PUART_CFG *puart_cfg)
{
    extern puart_UartConfig puart_config;
    // Do all other app initializations.
    // Set the baud rate we want to use. Default is 115200.
    puart_config.baudrate = puart_cfg -> baudrate;
    // Select the uart pins for RXD, TXD and optionally CTS and RTS.
    // If hardware flow control is not required like here, set these
    // pins to 0x00. See Table 1 and Table 2 for valid options.
    puart_selectUartPads(puart_cfg -> rxpin, puart_cfg -> txpin, 0x00, 0x00);
    // Initialize the peripheral uart driver
    puart_init();
    // Since we are not configuring CTS and RTS here, turn off
    // hardware flow control. If HW flow control is used, then
    // puart_flowOff should not be invoked.
    puart_setBaudrate(0, 0, puart_cfg -> baudrate);
    puart_flowOff();
    devlpm_init();
    devlpm_registerForLowPowerQueries(puart_lpm_allowed, 0);
    /* BEGIN - puart interrupt
       The following lines enable interrupt when one (or more) bytes
       are received over the peripheral uart interface. This is optional.
       In the absence of this, the app is expected to poll the peripheral
       uart to pull out received bytes.  */
    // clear interrupt
    P_UART_INT_CLEAR(P_UART_ISR_RX_AFF_MASK);
    // set watermark to 1 byte - will interrupt on every byte received.
    // how to change it? How to get the interrupt to appear after half of the
    // fifo is full, and still get all the bytes, when it is not?
    P_UART_WATER_MARK_RX_LEVEL (1);
    // enable UART interrupt in the Main Interrupt Controller and RX Almost Full in the UART
    // Interrupt Controller
    P_UART_INT_ENABLE |= P_UART_ISR_RX_AFF_MASK;
    // Set callback function to app callback function.
    puart_rxCb = application_puart_interrupt_callback;
    // Enable the CPU level interrupt
    puart_enableInterrupt();
    /* END - puart interrupt */
    // print a string message assuming that the device connected
    // to the peripheral uart can handle this string.
    //puart_print("Application initialization complete!");
}

Now - this piece of code suggests, that puart_lpm_allowed will be called when the device is about to go to sleep. And the transmission problems should be gone. Sure like hell:

UINT32 puart_lpm_allowed(LowPowerModePollType type, uint32_t context) {
    for(;;);
    return 0;
}

This is the function, and all works like it did before - the UART transmits funny data, and continuously.

If I remove the "for(;;);" loop above - the same.

I wouldn't like to complain too much, but:

1) the devlpm_* is not documented in the API documentation coming with the WICED-Smart-SDK,

2) the examples are not in sync with what SDK IDE would generate, which makes all the attempts to search for help slightly schizophrenic,

3) the suggested work-arounds do not work, because God knows if I do it right, since 1) & 2).

Guys at Broadcom - I know you are busy and bothered by those pesky clients who want to use your BLE, but so am I; so maybe to avoid further waste of time we could have an example that actually works, instead of make me impersonate Sherlock?
I mean - serial communication is not a rocket science; it should just work!

0 Likes

I will attempt to escalate this internally.

david_armour

0 Likes
Anonymous
Not applicable

Hello Marcin,

Can you use the uart_firmware_upgrade app as a starting point:

pastedImage_0.png

Thanks

JT

0 Likes