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.

PROCESSOR-SDK-AM335X: Extend Beaglebone Black UART capabilities via PRUs

Part Number: PROCESSOR-SDK-AM335X

Hi, I am using a Beaglebone Black and already using the 4.5 Hardware UARTs. Now, I need to extend the number of UART ports and thought of using the 3 UARTs per PRUs to get more than 4 UARTs.

I fail to find any resource that could clarify this possibility. I mean, is it even possible to use PRU-software-UARTs along with the 4.5 Hardware UARTs? If yes, how should I go about it ? Most PRU examples belabor on the FTDI/UART usage to replace printf.

I am using Linux drivers for PRU instead of CCS.

  • Hi Prashant,

    The PRU-software-UART is independent from the hardware UART. You can use them in a same project. Please refer to the following document for details of the PRU-software-UART.

    https://software-dl.ti.com/processor-sdk-linux/esd/AM335X/08_02_00_24/exports/docs/linux/Foundational_Components/PRU-ICSS/Linux_Drivers/pru-sw-uart.html

  • The mentioned document is really poor in content. It doesn't; touch any of the UART aspect properly. The AM335x manual is a far better resource for it but I found some information lacking in it too. I referred to the PRU-Cookbook by Yoder and it redirected me to some pru-uart sample by ti. I still can't understand how and where are the RX and TX pins defined. For e.g. in the cookbook sample, Yoder uses UART1 (P9_24 and P26) but other samples use custom pins configured using `config-pin` linux utility. In one example, a user configured P9_18 and P9_19 as TX and RX but I can't understand how to differentiate between TX and RX in the code, as it is nowhere mentioned.

  • I thought you use Linux on Beaglebone Black, don't you? You just need to boot Processor SDK Linux default filesystem image on BBB with am335x-boneblack-prusuart.dtb, then the PRU SW UART ports are ready for use in Linux, your application just opens /dev/ttysPRU<x> as how the regular UART is used. Why do you need to differentiate TX & RX in your code?

  • The uarts are not visible as `/dev/ttysPRU<x>` and I am still able to use `P9_18` and `P9_17` as TX and RX. I had to determine that `P9_18` is TX by using loopback and dumping the results to Hardware UART 1 (P9_26). But I can't do this for all pins that claim to support PRU_UART. So I am looking for a way to determine which other pins can be used as TX and RX (other than the Hardware UARTs).

  • Did you build am335x-boneblack-pruswuart.dtb and use it to boot the BBB?

    am335x-boneblack-pruswuart.dts describes all the PRU SW UART pins.

  • No, I didn't mess with the device tree. I simply enabled overlays.. by uncommenting this in the

    `boot/uEnv.txt` 

    ###Master Enable
    enable_uboot_overlays=1

    I did find some .dtb files in the /boot/ section and even tried to decompile one into .dts but it didn't find am335x-boneblack-pruswuart.dts

    --- 

    This also leads to another problem I am facing. I don't know how to use all 3 PRU-UARTS (per PRU), together simultaneously. Can you also share some snippets./samples relating to it ?

  • Thanks for the device tree source. I assume that the we can replace these pins with P9_17 and P9_18, etc ?  


    Also, can you share some knowledge on how can I send some data to PRU_UART2 after I receive it from PRU_UART1 or 3 ? I can't find any mention of UART selection in any of the sample code. 

  • Thanks for the device tree source. I assume that the we can replace these pins with P9_17 and P9_18, etc ?  

    Please check the BBB schematics and AM335x Datasheet. P9_17 is ball A16, which is not an PRU GPIO pin, so you cannot use it for PRU SW UART.

    Also, can you share some knowledge on how can I send some data to PRU_UART2 after I receive it from PRU_UART1 or 3 ? I can't find any mention of UART selection in any of the sample code. 

    How do you receive data from PRU UART1 or 3? Just do the similar sequence except changing read() to write().

  • Actually, I am able to use `P9_17 and P9_18` as shown in the sample here. I don't understand how it's configured as a sw-uart by default. My `/uEnv.txt` is as follows:

    #Docs: http://elinux.org/Beagleboard:U-boot_partitioning_layout_2.0
    
    uname_r=4.19.94-ti-r42
    #uuid=
    #dtb=
    
    ###U-Boot Overlays###
    ###Documentation: http://elinux.org/Beagleboard:BeagleBoneBlack_Debian#U-Boot_Overlays
    ###Master Enable
    enable_uboot_overlays=1
    ###
    ###Overide capes with eeprom
    uboot_overlay_addr0=/lib/firmware/BB-UART1-00A0.dtbo
    uboot_overlay_addr1=/lib/firmware/BB-UART2-00A0.dtbo
    uboot_overlay_addr2=/lib/firmware/BB-UART4-00A0.dtbo
    uboot_overlay_addr3=/lib/firmware/BB-UART5-00A0.dtbo
    ###
    ###Additional custom capes
    #uboot_overlay_addr4=/lib/firmware/<file4>.dtbo
    #uboot_overlay_addr5=/lib/firmware/<file5>.dtbo
    #uboot_overlay_addr6=/lib/firmware/<file6>.dtbo
    #uboot_overlay_addr7=/lib/firmware/<file7>.dtbo
    ###
    ###Custom Cape
    #dtb_overlay=/lib/firmware/<file8>.dtbo
    ###
    ###Disable auto loading of virtual capes (emmc/video/wireless/adc)
    #disable_uboot_overlay_emmc=1
    #disable_uboot_overlay_video=1
    disable_uboot_overlay_audio=1
    #disable_uboot_overlay_wireless=1
    #disable_uboot_overlay_adc=1
    ###
    ###PRUSS OPTIONS
    ###pru_rproc (4.14.x-ti kernel)
    #uboot_overlay_pru=/lib/firmware/AM335X-PRU-RPROC-4-14-TI-00A0.dtbo
    ###pru_rproc (4.19.x-ti kernel)
    uboot_overlay_pru=/lib/firmware/AM335X-PRU-RPROC-4-19-TI-00A0.dtbo
    ###pru_uio (4.14.x-ti, 4.19.x-ti & mainline/bone kernel)
    #uboot_overlay_pru=/lib/firmware/AM335X-PRU-UIO-00A0.dtbo
    ###
    ###Cape Universal Enable
    enable_uboot_cape_universal=1
    ###
    ###Debug: disable uboot autoload of Cape
    #disable_uboot_overlay_addr0=1
    #disable_uboot_overlay_addr1=1
    #disable_uboot_overlay_addr2=1
    #disable_uboot_overlay_addr3=1
    ###
    ###U-Boot fdt tweaks... (60000 = 384KB)
    #uboot_fdt_buffer=0x60000
    ###U-Boot Overlays###
    
    cmdline=coherent_pool=1M net.ifnames=0 lpj=1990656 rng_core.default_quality=100 quiet
    
    #In the event of edid real failures, uncomment this next line:
    #cmdline=coherent_pool=1M net.ifnames=0 lpj=1990656 rng_core.default_quality=100 quiet video=HDMI-A-1:1024x768@60e
    
    ##enable Generic eMMC Flasher:
    #cmdline=init=/opt/scripts/tools/eMMC/init-eMMC-flasher-v3.sh
    
    cape_enable=capemgr.enable_partno=BB-UART1,BB-UART2,BB-UART4,BB-UART5

    How do you receive data from PRU UART1 or 3? Just do the similar sequence except changing read() to write().

    The code doesn't mention any pin in the code and that's what creates confusion here. You can see the code here

  • We have been talking about two completely different things. I quickly reviewed the sample link you provided, it uses the dedicated PRU HW UART module, while I was talking about the PRU SW UART, which uses a PRU firmware to bitbang the PRU GPIO pins to simulate UARTs, because that is what you referred in your first post above.

  • Uh... I didn't know `P9_17 and P9_18` were HW UARTs. Why can't I find them on the pinout ? 

    Also, this means that all the pru_uart examples use HW_UARTs and are of no help to me... How should I proceed ?