Skip to content

Commit f459992

Browse files
committed
ws2812: add support for 160MHz cortex-m processors
This adds hardware timing support for driving WS2812 LEDs on Cortex-M microcontrollers running at 160MHz (such as the STM32U585). - Updated `go:generate` directive to include 160MHz. - Generated the corresponding `ws2812_writeByte160` assembly routine. - Added a switch case in `WriteByte` to handle generic 160MHz processors. Signed-off-by: deadprogram <ron@hybridgroup.com>
1 parent 62663c1 commit f459992

3 files changed

Lines changed: 385 additions & 1 deletion

File tree

ws2812/ws2812-asm_cortexm.go

Lines changed: 381 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,377 @@ void ws2812_writeByte150(char c, uint32_t *portSet, uint32_t *portClear, uint32_
12811281
[portClear]"m"(*portClear));
12821282
}
12831283
1284+
__attribute__((always_inline))
1285+
void ws2812_writeByte160(char c, uint32_t *portSet, uint32_t *portClear, uint32_t maskSet, uint32_t maskClear) {
1286+
// Timings:
1287+
// T0H: 56 - 58 cycles or 350.0ns - 362.5ns
1288+
// T1H: 168 - 170 cycles or 1050.0ns - 1062.5ns
1289+
// TLD: 184 - cycles or 1150.0ns -
1290+
uint32_t value = (uint32_t)c << 24;
1291+
char i = 8;
1292+
__asm__ __volatile__(
1293+
"1: @ send_bit\n"
1294+
"\t str %[maskSet], %[portSet] @ [2] T0H and T0L start here\n"
1295+
"\t nop\n"
1296+
"\t nop\n"
1297+
"\t nop\n"
1298+
"\t nop\n"
1299+
"\t nop\n"
1300+
"\t nop\n"
1301+
"\t nop\n"
1302+
"\t nop\n"
1303+
"\t nop\n"
1304+
"\t nop\n"
1305+
"\t nop\n"
1306+
"\t nop\n"
1307+
"\t nop\n"
1308+
"\t nop\n"
1309+
"\t nop\n"
1310+
"\t nop\n"
1311+
"\t nop\n"
1312+
"\t nop\n"
1313+
"\t nop\n"
1314+
"\t nop\n"
1315+
"\t nop\n"
1316+
"\t nop\n"
1317+
"\t nop\n"
1318+
"\t nop\n"
1319+
"\t nop\n"
1320+
"\t nop\n"
1321+
"\t nop\n"
1322+
"\t nop\n"
1323+
"\t nop\n"
1324+
"\t nop\n"
1325+
"\t nop\n"
1326+
"\t nop\n"
1327+
"\t nop\n"
1328+
"\t nop\n"
1329+
"\t nop\n"
1330+
"\t nop\n"
1331+
"\t nop\n"
1332+
"\t nop\n"
1333+
"\t nop\n"
1334+
"\t nop\n"
1335+
"\t nop\n"
1336+
"\t nop\n"
1337+
"\t nop\n"
1338+
"\t nop\n"
1339+
"\t nop\n"
1340+
"\t nop\n"
1341+
"\t nop\n"
1342+
"\t nop\n"
1343+
"\t nop\n"
1344+
"\t nop\n"
1345+
"\t nop\n"
1346+
"\t nop\n"
1347+
"\t lsls %[value], #1 @ [1]\n"
1348+
"\t bcs.n 2f @ [1/3] skip_store\n"
1349+
"\t str %[maskClear], %[portClear] @ [2] T0H -> T0L transition\n"
1350+
"\t2: @ skip_store\n"
1351+
"\t nop\n"
1352+
"\t nop\n"
1353+
"\t nop\n"
1354+
"\t nop\n"
1355+
"\t nop\n"
1356+
"\t nop\n"
1357+
"\t nop\n"
1358+
"\t nop\n"
1359+
"\t nop\n"
1360+
"\t nop\n"
1361+
"\t nop\n"
1362+
"\t nop\n"
1363+
"\t nop\n"
1364+
"\t nop\n"
1365+
"\t nop\n"
1366+
"\t nop\n"
1367+
"\t nop\n"
1368+
"\t nop\n"
1369+
"\t nop\n"
1370+
"\t nop\n"
1371+
"\t nop\n"
1372+
"\t nop\n"
1373+
"\t nop\n"
1374+
"\t nop\n"
1375+
"\t nop\n"
1376+
"\t nop\n"
1377+
"\t nop\n"
1378+
"\t nop\n"
1379+
"\t nop\n"
1380+
"\t nop\n"
1381+
"\t nop\n"
1382+
"\t nop\n"
1383+
"\t nop\n"
1384+
"\t nop\n"
1385+
"\t nop\n"
1386+
"\t nop\n"
1387+
"\t nop\n"
1388+
"\t nop\n"
1389+
"\t nop\n"
1390+
"\t nop\n"
1391+
"\t nop\n"
1392+
"\t nop\n"
1393+
"\t nop\n"
1394+
"\t nop\n"
1395+
"\t nop\n"
1396+
"\t nop\n"
1397+
"\t nop\n"
1398+
"\t nop\n"
1399+
"\t nop\n"
1400+
"\t nop\n"
1401+
"\t nop\n"
1402+
"\t nop\n"
1403+
"\t nop\n"
1404+
"\t nop\n"
1405+
"\t nop\n"
1406+
"\t nop\n"
1407+
"\t nop\n"
1408+
"\t nop\n"
1409+
"\t nop\n"
1410+
"\t nop\n"
1411+
"\t nop\n"
1412+
"\t nop\n"
1413+
"\t nop\n"
1414+
"\t nop\n"
1415+
"\t nop\n"
1416+
"\t nop\n"
1417+
"\t nop\n"
1418+
"\t nop\n"
1419+
"\t nop\n"
1420+
"\t nop\n"
1421+
"\t nop\n"
1422+
"\t nop\n"
1423+
"\t nop\n"
1424+
"\t nop\n"
1425+
"\t nop\n"
1426+
"\t nop\n"
1427+
"\t nop\n"
1428+
"\t nop\n"
1429+
"\t nop\n"
1430+
"\t nop\n"
1431+
"\t nop\n"
1432+
"\t nop\n"
1433+
"\t nop\n"
1434+
"\t nop\n"
1435+
"\t nop\n"
1436+
"\t nop\n"
1437+
"\t nop\n"
1438+
"\t nop\n"
1439+
"\t nop\n"
1440+
"\t nop\n"
1441+
"\t nop\n"
1442+
"\t nop\n"
1443+
"\t nop\n"
1444+
"\t nop\n"
1445+
"\t nop\n"
1446+
"\t nop\n"
1447+
"\t nop\n"
1448+
"\t nop\n"
1449+
"\t nop\n"
1450+
"\t nop\n"
1451+
"\t nop\n"
1452+
"\t nop\n"
1453+
"\t nop\n"
1454+
"\t nop\n"
1455+
"\t nop\n"
1456+
"\t nop\n"
1457+
"\t nop\n"
1458+
"\t nop\n"
1459+
"\t nop\n"
1460+
"\t nop\n"
1461+
"\t nop\n"
1462+
"\t nop\n"
1463+
"\t str %[maskClear], %[portClear] @ [2] T1H -> T1L transition\n"
1464+
"\t nop\n"
1465+
"\t nop\n"
1466+
"\t nop\n"
1467+
"\t nop\n"
1468+
"\t nop\n"
1469+
"\t nop\n"
1470+
"\t nop\n"
1471+
"\t nop\n"
1472+
"\t nop\n"
1473+
"\t nop\n"
1474+
"\t nop\n"
1475+
"\t nop\n"
1476+
"\t nop\n"
1477+
"\t nop\n"
1478+
"\t nop\n"
1479+
"\t nop\n"
1480+
"\t nop\n"
1481+
"\t nop\n"
1482+
"\t nop\n"
1483+
"\t nop\n"
1484+
"\t nop\n"
1485+
"\t nop\n"
1486+
"\t nop\n"
1487+
"\t nop\n"
1488+
"\t nop\n"
1489+
"\t nop\n"
1490+
"\t nop\n"
1491+
"\t nop\n"
1492+
"\t nop\n"
1493+
"\t nop\n"
1494+
"\t nop\n"
1495+
"\t nop\n"
1496+
"\t nop\n"
1497+
"\t nop\n"
1498+
"\t nop\n"
1499+
"\t nop\n"
1500+
"\t nop\n"
1501+
"\t nop\n"
1502+
"\t nop\n"
1503+
"\t nop\n"
1504+
"\t nop\n"
1505+
"\t nop\n"
1506+
"\t nop\n"
1507+
"\t nop\n"
1508+
"\t nop\n"
1509+
"\t nop\n"
1510+
"\t nop\n"
1511+
"\t nop\n"
1512+
"\t nop\n"
1513+
"\t nop\n"
1514+
"\t nop\n"
1515+
"\t nop\n"
1516+
"\t nop\n"
1517+
"\t nop\n"
1518+
"\t nop\n"
1519+
"\t nop\n"
1520+
"\t nop\n"
1521+
"\t nop\n"
1522+
"\t nop\n"
1523+
"\t nop\n"
1524+
"\t nop\n"
1525+
"\t nop\n"
1526+
"\t nop\n"
1527+
"\t nop\n"
1528+
"\t nop\n"
1529+
"\t nop\n"
1530+
"\t nop\n"
1531+
"\t nop\n"
1532+
"\t nop\n"
1533+
"\t nop\n"
1534+
"\t nop\n"
1535+
"\t nop\n"
1536+
"\t nop\n"
1537+
"\t nop\n"
1538+
"\t nop\n"
1539+
"\t nop\n"
1540+
"\t nop\n"
1541+
"\t nop\n"
1542+
"\t nop\n"
1543+
"\t nop\n"
1544+
"\t nop\n"
1545+
"\t nop\n"
1546+
"\t nop\n"
1547+
"\t nop\n"
1548+
"\t nop\n"
1549+
"\t nop\n"
1550+
"\t nop\n"
1551+
"\t nop\n"
1552+
"\t nop\n"
1553+
"\t nop\n"
1554+
"\t nop\n"
1555+
"\t nop\n"
1556+
"\t nop\n"
1557+
"\t nop\n"
1558+
"\t nop\n"
1559+
"\t nop\n"
1560+
"\t nop\n"
1561+
"\t nop\n"
1562+
"\t nop\n"
1563+
"\t nop\n"
1564+
"\t nop\n"
1565+
"\t nop\n"
1566+
"\t nop\n"
1567+
"\t nop\n"
1568+
"\t nop\n"
1569+
"\t nop\n"
1570+
"\t nop\n"
1571+
"\t nop\n"
1572+
"\t nop\n"
1573+
"\t nop\n"
1574+
"\t nop\n"
1575+
"\t nop\n"
1576+
"\t nop\n"
1577+
"\t nop\n"
1578+
"\t nop\n"
1579+
"\t nop\n"
1580+
"\t nop\n"
1581+
"\t nop\n"
1582+
"\t nop\n"
1583+
"\t nop\n"
1584+
"\t nop\n"
1585+
"\t nop\n"
1586+
"\t nop\n"
1587+
"\t nop\n"
1588+
"\t nop\n"
1589+
"\t nop\n"
1590+
"\t nop\n"
1591+
"\t nop\n"
1592+
"\t nop\n"
1593+
"\t nop\n"
1594+
"\t nop\n"
1595+
"\t nop\n"
1596+
"\t nop\n"
1597+
"\t nop\n"
1598+
"\t nop\n"
1599+
"\t nop\n"
1600+
"\t nop\n"
1601+
"\t nop\n"
1602+
"\t nop\n"
1603+
"\t nop\n"
1604+
"\t nop\n"
1605+
"\t nop\n"
1606+
"\t nop\n"
1607+
"\t nop\n"
1608+
"\t nop\n"
1609+
"\t nop\n"
1610+
"\t nop\n"
1611+
"\t nop\n"
1612+
"\t nop\n"
1613+
"\t nop\n"
1614+
"\t nop\n"
1615+
"\t nop\n"
1616+
"\t nop\n"
1617+
"\t nop\n"
1618+
"\t nop\n"
1619+
"\t nop\n"
1620+
"\t nop\n"
1621+
"\t nop\n"
1622+
"\t nop\n"
1623+
"\t nop\n"
1624+
"\t nop\n"
1625+
"\t nop\n"
1626+
"\t nop\n"
1627+
"\t nop\n"
1628+
"\t nop\n"
1629+
"\t nop\n"
1630+
"\t nop\n"
1631+
"\t nop\n"
1632+
"\t nop\n"
1633+
"\t nop\n"
1634+
"\t nop\n"
1635+
"\t nop\n"
1636+
"\t nop\n"
1637+
"\t nop\n"
1638+
"\t nop\n"
1639+
"\t nop\n"
1640+
"\t nop\n"
1641+
"\t nop\n"
1642+
"\t nop\n"
1643+
"\t subs %[i], #1 @ [1]\n"
1644+
"\t beq.n 3f @ [1/3] end\n"
1645+
"\t b 1b @ [1/3] send_bit\n"
1646+
"\t3: @ end\n"
1647+
: [value]"+r"(value),
1648+
[i]"+r"(i)
1649+
: [maskSet]"r"(maskSet),
1650+
[portSet]"m"(*portSet),
1651+
[maskClear]"r"(maskClear),
1652+
[portClear]"m"(*portClear));
1653+
}
1654+
12841655
__attribute__((always_inline))
12851656
void ws2812_writeByte168(char c, uint32_t *portSet, uint32_t *portClear, uint32_t maskSet, uint32_t maskClear) {
12861657
// Timings:
@@ -2192,6 +2563,16 @@ func (d Device) writeByte150(c byte) {
21922563
interrupt.Restore(mask)
21932564
}
21942565

2566+
func (d Device) writeByte160(c byte) {
2567+
portSet, maskSet := d.Pin.PortMaskSet()
2568+
portClear, maskClear := d.Pin.PortMaskClear()
2569+
2570+
mask := interrupt.Disable()
2571+
C.ws2812_writeByte160(C.char(c), (*C.uint32_t)(unsafe.Pointer(portSet)), (*C.uint32_t)(unsafe.Pointer(portClear)), C.uint32_t(maskSet), C.uint32_t(maskClear))
2572+
2573+
interrupt.Restore(mask)
2574+
}
2575+
21952576
func (d Device) writeByte168(c byte) {
21962577
portSet, maskSet := d.Pin.PortMaskSet()
21972578
portClear, maskClear := d.Pin.PortMaskClear()

0 commit comments

Comments
 (0)