How to control fine PWM on AI64?

DMA works…I saw in the docs. there was a small section on it and there are PRUs and DSPs.

I am not a fan of PRUs since I cannot do much w/ them so far.

DSPs on the BBAI-64 are out of my league for now and the Cortex-R5s I have not been able to make work. I know some other people on this forum have had success w/ the Cortex-R5s.

GPIO is a route too. I mean you can turn on the GPIO for a period while it is 1 and then off for a period.

So, three bytes or 24 bits of on and off. 0s and 1s…okay.

Memory Mapping should work, like you were discussing.

Now, using PWM in memory mapping may be complicated. I am not sure how you can achieve the feat.

Also, there was another project I found a while back called SimpPRU: Digital Read - simpPRU

The PRU Cookbook is another route and there may be a large LED project listed in it. I need to double check.

1 Like

Thank you so much. @silver2row

  • Note _ I/O with devmem2, simpPRU

@ALEX_PARK I am afraid you will not be able to control the addressable LEDs using a PWM. As you have found you can’t switch the duty cycle fast enough to get the different pulse widths required.

I have just had a quick search to see how the Pi does this, quite interesting as far as I can see. The timing for LED strips is pretty fussy and you are not going to achieve it by using a standard PWM.

Looking at how the Pi does it, there is maybe the option of using SPI and clocking it at a higher frequency and then writing out several bytes to generate your bit pattern. Potentially this would work but not the most efficient way to do it. You also need to fit the whole string into 1 DMA transfer or risk losing the timing.

The Pi code uses 3 SPI bits to set one LED bit, so clocking out 110b from the SPI gives you a 1 and clocking 100b gives a 0.

This only works if you can set the SPI clock to the correct frequency. The Pi can achieve this, however it may not be possible on the AI64. It will all depend on base clock frequency and the various divisors used to set the clock.

I would say your best option for doing this sort of thing is to make use of the PRU’s. Unfortunately documentation is pretty lacking for the AI64. There is at least 1 PRU driver for the BBB family of boards.

While the AI64 has PRUs (in fact it has more) I doubt the code will work as is on the AI64. In fact I doubt this would work on a recent BBB either as it uses UIO to talk to the PRUs which has been deprecated. Neither git repo has been touched for many years.

The PRU’s are certainly the best way to do this sort of thing. While the Pi driver I saw claims to be able to do 2 strings of 2700 LEDS, You really do not want to drive such a long string as the update rate will be terrible if you want to do any sort of animation effects.

By contrast the BBB PRU code can drive 48 strings of 512 LEDs at 30 FPS for a total of 24576 LEDS.

On the AI64 you may also be able to do this using I2S to clock out bits but it is not going to be easy. Probably your easiest route to get this working is to use SPI assuming you can get the correct SPI clock frequency.

1 Like

Thank you.
I gave up on PWM and turned to SPI, I was setting up an overlay.

debian@BeagleBone-AI64:/sys/class/spi_master/spi0$ sudo beagle-version 
[sudo] password for debian: 
dogtag:[ Debian Bullseye Xfce Image 2023-08-05]
bootloader:[/dev/mmcblk0boot0]:[tiboot3.bin]:[U-Boot SPL 2021.01-gea96725b (Apr 05 2023 - 22:07:31 +0000)]
bootloader:[/dev/mmcblk0]:[/boot/firmware/tiboot3.bin]:[U-Boot SPL 2021.01-gea96725b (Aug 03 2023 - 15:43:32 +0000)]
bootloader:[/dev/mmcblk0]:[/boot/firmware/tispl.bin]:[U-Boot SPL 2021.01-gea96725b (Aug 03 2023 - 15:43:32 +0000)]
bootloader:[/dev/mmcblk0]:[/boot/firmware/u-boot.img]:[U-Boot 2021.01-gea96725b (Aug 03 2023 - 15:43:32 +0000)]
bootloader:[/dev/mmcblk1]:[/boot/firmware/tiboot3.bin]:[U-Boot SPL 2021.01-gea96725b (Aug 03 2023 - 15:43:32 +0000)]
bootloader:[/dev/mmcblk1]:[/boot/firmware/tispl.bin]:[U-Boot SPL 2021.01-gea96725b (Aug 03 2023 - 15:43:32 +0000)]
bootloader:[/dev/mmcblk1]:[/boot/firmware/u-boot.img]:[U-Boot 2021.01-gea96725b (Aug 03 2023 - 15:43:32 +0000)]
UBOOT: Booted Device-Tree:[k3-j721e-beagleboneai64.dts]
UBOOT: Loaded Overlay:[BONE-SPI0_1.kernel]
UBOOT: Loaded Overlay:[BONE-SPI1_0.kernel]
pkg check: to individually upgrade run: [sudo apt install --only-upgrade <pkg>]
cmdline:[root=/dev/mmcblk1p2 ro rootfstype=ext4 rootwait net.ifnames=0 quiet]
dmesg | grep optee
[    0.862287] optee: probing for conduit method.

BONE-SPI0_1.kernel Loaded.

not found

debian@BeagleBone-AI64:/sys/class/spi_master/spi0$ tree /dev/bone
|-- pwm
`-- uart
    `-- 0 -> ../../ttyS2

I need to set something up more.

If you run


Is the spidev driver loaded ?

debian@BeagleBone-AI64:~$ lsmod | grep spi
gb_spi                 20480  0
gb_gbphy               20480  4 gb_spi,gb_uart,gb_i2c,gb_gpio
gb_spilib              16384  2 gb_spi,gb_firmware
greybus               118784  13 gb_bootrom,gb_spi,gb_raw,gb_log,gb_hid,gb_netlink,gb_uart,gb_i2c,gb_firmware,gb_gbphy,gb_gpio,gb_loopback,gb_spilib

Is it loaded?

doesn’t look like it, can you try

modprobe spidev

I think it is spidev

ebian@BeagleBone-AI64:~$ modprobe spidev
debian@BeagleBone-AI64:~$ sudo su
root@BeagleBone-AI64:/home/debian# modprobe spidev

not found… :frowning:


debian@BeagleBone-AI64:~$ sudo insmod /lib/modules/5.10.168-ti-arm64-r108/kernel/drivers/spi/spidev.ko.xz
insmod: ERROR: could not insert module /lib/modules/5.10.168-ti-arm64-r108/kernel/drivers/spi/spidev.ko.xz: File exists

modprobe doesn’t output anything if there are no errors.

check with lsmod again.

it works fine on my AI64

debian@BeagleBone-AI64:~$ tree /dev/bone
|-- pwm
`-- uart
    `-- 0 -> ../../ttyS2

2 directories, 1 file
debian@BeagleBone-AI64:~$ lsmod
Module                  Size  Used by
xt_conntrack           16384  1
nft_chain_nat          16384  3
xt_MASQUERADE          20480  1
nf_nat                 40960  2 nft_chain_nat,xt_MASQUERADE
nf_conntrack_netlink    49152  0
nf_conntrack          143360  4 xt_conntrack,nf_nat,nf_conntrack_netlink,xt_MASQUERADE
nf_defrag_ipv6         24576  1 nf_conntrack
nf_defrag_ipv4         16384  1 nf_conntrack
xfrm_user              40960  1
xfrm_algo              16384  1 xfrm_user
nft_counter            16384  15
xt_addrtype            16384  2
nft_compat             20480  4
nf_tables             184320  43 nft_compat,nft_counter,nft_chain_nat
nfnetlink              20480  4 nft_compat,nf_conntrack_netlink,nf_tables
br_netfilter           32768  0
bridge                217088  1 br_netfilter
stp                    20480  1 bridge
llc                    20480  2 bridge,stp
aufs                  241664  0
af_alg                 28672  0
bnep                   28672  2
rpmsg_char             24576  0
btusb                  65536  0
btrtl                  24576  1 btusb
btbcm                  24576  1 btusb
btintel                28672  1 btusb
bluetooth             598016  28 btrtl,btintel,btbcm,bnep,btusb
virtio_rpmsg_bus       24576  0
cdns_csi2rx            24576  0
v4l2_fwnode            24576  1 cdns_csi2rx
ti_k3_r5_remoteproc    32768  0
at24                   24576  0
iwlmvm                286720  0
mac80211              749568  1 iwlmvm
libarc4                16384  1 mac80211
ti_am335x_adc          24576  0
iwlwifi               237568  1 iwlmvm
cfg80211              704512  3 iwlmvm,iwlwifi,mac80211
irq_pruss_intc         20480  0
vxe_enc               274432  0
sa2ul                  40960  0
vxd_dec               282624  0
authenc                16384  1 sa2ul
pvrsrvkm             1236992  0
j721e_csi2rx           28672  0
ti_k3_dsp_remoteproc    24576  0
videobuf2_dma_sg       24576  2 vxe_enc,vxd_dec
pci_endpoint_test      24576  0
videobuf2_dma_contig    24576  2 j721e_csi2rx,vxd_dec
v4l2_mem2mem           28672  2 vxe_enc,vxd_dec
extcon_usbc_tusb322    20480  0
rti_wdt                20480  0
uio_pdrv_genirq        20480  0
uio                    24576  1 uio_pdrv_genirq
gb_uart                24576  0
gb_spi                 20480  0
gb_raw                 16384  0
gb_netlink             16384  0
gb_loopback            28672  0
gb_log                 20480  0
gb_i2c                 20480  0
gb_hid                 20480  0
gb_gpio                24576  0
gb_gbphy               20480  4 gb_spi,gb_uart,gb_i2c,gb_gpio
gb_firmware            36864  0
gb_spilib              16384  2 gb_spi,gb_firmware
gb_bootrom             20480  0
greybus               118784  13 gb_bootrom,gb_spi,gb_raw,gb_log,gb_hid,gb_netlink,gb_uart,gb_i2c,gb_firmware,gb_gbphy,gb_gpio,gb_loopback,gb_spilib
wpanusb                24576  0
ieee802154_socket      28672  0
mac802154              77824  1 wpanusb
ieee802154             81920  2 ieee802154_socket,mac802154
pru_rproc              28672  0
icss_iep               24576  0
ti_j721e_cpsw_virt_mac    36864  0
crct10dif_ce           20480  1
rpmsg_kdrv             24576  1 ti_j721e_cpsw_virt_mac
ti_am335x_tscadc       20480  1 ti_am335x_adc
pruss                  20480  1 pru_rproc
cdns_dphy              16384  0

It’s not easy… :sweat:

My guess would be that greybus and the associated drivers is maybe preventing the spidev driver from loading.

Like I say it loads fine on my AI64, but I don’t have any of that greybus stuff loaded


spidev. Okay. There are SPI overlays too (I think). I will double check.



Let me share a recent update.

success control LED STRIP by SPI.

I want to control only one LED, but only two LEDs are controlled. :frowning:
This seems to be a problem with my code.

Anyway, here’s what I did with SPI that I couldn’t do with PWM.

Thank you @silver2row @benedict.hewson

1 Like


So, if they are addressable, maybe using the onboard chip could prove useful. For instance, if the address of the Blue LED is 0x55 (or whatever), it may be available for programming the singular Blue LED.

What chip is on the LED array?


P.S. If you have a schematic of the LED and datasheet, this will be very useful. For instance, trying to alter specific hardware will, like @benedict.hewson says, need specific technologies being used. I know he did not really say that idea but when we thought of PWM as a resource, we were ported to another technology to handle such a build of program(s).

I will search through some ideas and see if I can get your LED datasheet once you provide the type and model number.

1 Like


I have a WS2813 and checked the datasheet I found on the internet and challenged it.

WS2813.PDF (770.7 KB)

I referenced the Raspberry Pi’s neopixel module and saw that it works with PWM in the link below.
(I compared the raspberry waveforms on the oscilloscope).

This was challenging because instead of simply controlling the LEDs with PWM, we had to generate 0 and 1 codes and control 24 bits of RGB, 8 bits each.

1 Like


I think from what the .pdf states, the working voltage is 5v. Are you sure you want to use the 3.3v pins on the BBAI-64 to control the modes of the LED strips?


P.S. Also, I see they have external circuitry for their “set up” of ideas.

C1 is external filter capacitor, its value of 100NF. I would use a voltage regulator of sorts. I see it says operating voltage for the LEDs is 3.7v to 5v. The pins on the BBAI-64 are for 3.3v use only. It may damage the board. Heads up…also. I would get another form of LED. I am not hating on the way they make it easy to connect their LEDs. I would just provide more info. in the form of data on what or how things should work.


I found a digikey site that has this info. and more (I think):

I use the 5V output from P9_E3 and know that pin P9_3 is 3.3V.

Does voltage a factor in controlling it?

1 Like

Yes and No,

The board cannot handle reverse polarity of 5v into any pin that is directly accessing the TDA4VM (I think). The am335x and BBB was this way. Let me check the board profile so I can see. bbl!

Connectors — BeagleBoard Documentation shows what I am discussing. I am not sure if this interrupts your ability to handle the LED strip but I just wanted you to be careful.

This means, 5v is bad and 3.3v is good for pins being output too. If there was some reverse movement of current to the pin by accident or on purpose, the pin would be damaged or worse. The board could end up broken w/ the chip busted.

I say no too. I say no b/c you can use a voltage translator. 5v to 3.3v converter would suffice…


P.S. I am reading the datasheet still. There is a ws2813b too and some other forms. I found Seeed Studio on Digikey’s site has some of the b versions too. Anyway, I am missing the point of this datasheet.

1 Like

I am getting power from VSYS_5V on P9_E3, but if for some reason the 5V output from there goes to pin P9_21, which is the SPI input, I could have a problem.

Am I understanding this correctly?

The other devices I use in my header are using 3.3V, so I haven’t had any issues, but I’ll have to think about the 5V device you mentioned a bit more.

Thanks for the advice. @silver2row

1 Like

Right…I am out of line for discussing the E3 connector pin on the BBAI-64 since I have not researched it more but in dealing w/ older boards and mixing logic, I have always suffered unless other circuitry is in fact placed.


I will look over the schematic and docs. again on the BBAI-64 but I think that those 5v pins are used for USB or something so far but I need to read more into it.


P.S. I just wanted to mention it in case something odd happens that cannot be described b/c of the board dying out from mixing logic w/out safeguards.

So, I am guessing here primarily on serdes ideas but I know too little about it all. The two pins are USB 1, 2, and then sys_5v"o" or out, and then GND like it is for USB usage or something. Serialization and deserialization (serdes) may give ideas but I cannot be certain. This is false in the way I am discussing it.

I am sure we will all learn in time. Hopefully something nifty comes out of this idea…

How are the addressable LEDs coming along?

Did you use the first or second schematic on porting it to the BBAI-64? Maybe two way for serdes? I am clueless now. Okay and I am out for now!

1 Like