10 Replies Latest reply on Jun 30, 2014 6:56 PM by jcardona

    puart_write() crashing on BCM20736?



      So I've been trying to update my one-wire PUART application to work with SDK 2.0.1 on a BCM20736, but haven't been able to get it to work.


      Here is the new code:


      odbol/broadcom-wiced-ble-uart at sdk2 · GitHub


      So I'm having a couple problems:


      1. Calling puart_write() the second time seems to crash the chip and it restarts. Set the ENABLE_CRASHING_ON_SEND_PUART define to 1 in hello_sensor.h to see this. (log is attached)
      2. Even when I disable the puart_write() crashing part, the puart_rxCb interrupt is never called when I send data from the Arduino.


      This similar code worked in SDK 1.1 with a BCM20732, so I'm wondering what I'm missing. All I did was update a few function calls according to the "uart_firmware_upgrade" example. Here's the diff: Comparing master...sdk2 · odbol/broadcom-wiced-ble-uart · GitHub


      A couple questions/avenues of investigation for the differences between SDK 1.1 and 2.0:


      1. Do I no longer need to call "bleprofile_PUARTRxOn()"?
      2. I also no longer call "devlpm_init()" before devlpm_registerForLowPowerQueries(). Could that be a problem?
      3. Do I need to use puart_setBaudrate() or can I just modify puart_UartConfig directly?
      4. If so, do I call puart_setBaudrate() before puart_init() or after?
      5. Will pin 25 for RX and 32 for TX still work on the BCM20736?



        • 1. Re: puart_write() crashing on BCM20736?

          Hi Tyler,

            Can you ensure that you call devlpm_init() as you had done prior?  This needs to be called before any other devlpm functions can be used.  Let us know if this fixes your issue.




          • 2. Re: puart_write() crashing on BCM20736?

            Hi Frank,


            I did try something similar to what userc_3543 is doing, following the example code from uart_firmware_upgrade/ws_upgrade_uart.c and no luck.  (I double-checked I was calling devlpm_init() gets called, as you suggest)


            I just need basic two-way serial communication between the host and the WICED for unit testing.  I'm using SDK2 with a 2073TAG and no luck.  I can get traces from the device (with ble_trace<N>()) to the host but none of the puart functions seems to work neither for writing (puart_printf, puart_write) nor receiving (puart_rxCb is never called).


            Is there any chance that someone reviews/updates the Peripheral UART Sample Code in the 'WICED Smart HW Interfaces' document for SDK 2.0?  This seems to be basic functionality that shouldn't require that much experimentation to get it working.





            • 3. Re: puart_write() crashing on BCM20736?



              I was finally able to have two-way serial communications between a host and the WICED tag using the peripheral UART.  Some things that I discovered along the way may be useful to you:


              1. The documented API for this functions seems incorrect.  They return 0 (FALSE) on success:


              /// (...)

              /// \return TRUE when successful; else FALSE.

              BOOL32 puart_selectUartPads(UINT8 rxdPortPin, UINT8 txdPortPin, UINT8 ctsPortPin, UINT8 rtsPortPin);


              /// (...)

              /// \return TRUE if valid; else FALSE.

              BOOL32 puart_checkRxdPortPin(UINT8 rxdPortPin);


              /// (...)

              /// \return TRUE if valid; else FALSE.

              BOOL32 puart_checkTxdPortPin(UINT8 txdPortPin);


              2. As documented in the HW Interfaces doc, disabling sleep is a must.  Without that the UART won't work.  The document mentions that only GPIOs can wake up the device when asleep.  It's surprising that one cannot configure the UART interrupt just as well, but I guess that's what it is.


              3. The peripheral UART is also connected to the FTDI chip, which makes it available to your development host as a second USB/serial port.  On Linux this would by /dev/ttyUSB1.  So testing the PUART functionality is much easier than having to attach a second device (Arduino, etc.)


              4. You can redirect all your ble_tracen output to the peripheral uart by editing:


              diff --git a/Wiced-Smart/spar/common/sparinit.c b/Wiced-Smart/spar/common/sparinit.c

              index 5128819..6f8f3b9 100755

              --- a/Wiced-Smart/spar/common/sparinit.c

              +++ b/Wiced-Smart/spar/common/sparinit.c

              @@ -67,7 +67,7 @@ void application_setup(void)

                   extern UINT8 *bleapp_sram_addr;

                   bleapp_sram_addr = (UINT8 *)0x200000;

                   bleapp_pre_init = application_init;

              -    BLE_APP_ENABLE_TRACING_ON_HCI_UART();

              +    BLE_APP_ENABLE_TRACING_ON_PUART();


              #ifdef RAMBUFENABLE




              And with all this new found knowledge, this is the configuration magic that worked for me:


              int XXX_uart_init(BLE_PROFILE_PUART_CFG *puart_cfg)




                  if (puart_checkRxdPortPin(puart_cfg->rxpin)) {

                      ble_trace1("\nFailed to set PUART RX pin %d", puart_cfg->rxpin);

                      return FALSE;



                  if (puart_checkRxdPortPin(puart_cfg->txpin)) {

                      ble_trace1("\nFailed to set PUART TX pin %d", puart_cfg->txpin);

                      return FALSE;



                  if (puart_selectUartPads(puart_cfg->rxpin, puart_cfg->txpin, 0x00, 0x00)) {

                      ble_trace0("\nFailed to select UartPads");

                      return FALSE;



                  puart_setBaudrate(0, 0, puart_cfg->baudrate);






                  devlpm_registerForLowPowerQueries(lpm_callback, 0);




                  /* set watermark to 1 byte - will interrupt on every byte received. */

                  P_UART_WATER_MARK_RX_LEVEL (1);


                  // Almost Full interrupt

                  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



                  return (TRUE);



              I hope that it helps.



              1 of 1 people found this helpful
              • 4. Re: puart_write() crashing on BCM20736?

                Ah, thanks for figuring out that the puart_checkRxdPortPin() functions return the opposite of what they should. That helps!


                Also, I found that the real bug was in the IDE: for some reason it was compiling a different file than the one in the project. I had two projects with a "uart_one_wire.c" file, and even though I was making all kinds of changes to the one in my project directory, it was using some other function definition from a different file. I changed the "uart_init()" function to be named "peripheral_uart_init()", and then it used the correct function and everything worked swimmingly. Not sure what's going on with that or where it was finding the other "uart_init()" function. Aren't compilers supposed to figure this stuff out for you?

                • 5. Re: puart_write() crashing on BCM20736?

                  Ah, yes, I was also hit by that problem.  I learned the hard way that you

                  can look at your platform's patch.symdefs to see what symbols are defined

                  in ROM and avoid them.  The linker should look at that file and report an

                  error, but it does not.



                  • 6. Re: puart_write() crashing on BCM20736?

                    jcardona: Thanks for writing up. We had tough time porting our puart interface from SDK-1.1.0 to SDK-2.0.1. Your writeup helped us a lot.

                    • 7. Re: puart_write() crashing on BCM20736?

                      According to a message that a Broadcom support engineer send me some time ago, puart_init() should be called after puart_selectUartPads().  Apparently the other order works for you, but it does seem reasonable to establish the configuration before turning on the driver.  I wonder if your setup would still work with puart_init() done later?

                      • 8. Re: puart_write() crashing on BCM20736?



                        Yes, it works if I move the call to puart_init() after puart_selectUartPads().  In fact, it also works if I comment out the calls to puart_selectUartPads(), puart_checkTxdPortPin and puart_checkRxdPortPin() altogether.

                        Go figure

                        • 9. Re: puart_write() crashing on BCM20736?

                          I’m not at all surprised that the calls to puart_check*xdPortPin() are unnecessary.  As I understand it, they don’t actually change any state, they only tell you whether or not the supplied pin numbers are valid.


                          Does your app work if you omit puart_init()?   Are you supplying a non-null BLE_PROFILE_PUART_CFG argument to bleapp_set_cfg() in your APPLICATION_INIT() ?  According to puart.h, if you do the PUART_CFG thing, explicitly calling puart_init() should be unnecessary.

                          • 10. Re: puart_write() crashing on BCM20736?



                            Yes, it does work if I omit puart_init(), and yes, I'm calling bleapp_set_cfg() with a valid BLE_PROFILE_PUART_CFG.  So yes, looks like half of the initialization code was unnecessary after all...