update and test with rpi zero 2

This commit is contained in:
2025-05-12 17:53:09 +02:00
parent c1fb89271c
commit 4b3b2d1772
73 changed files with 215772 additions and 2600 deletions

View File

@@ -164,11 +164,13 @@ int chan_num;
// Convert RGB text string into integer data, for given channel
// Return number of data points for this channel
int str_rgb(char *s, int rgbs[][LED_NCHANS], int chan) {
int str_rgb(char *s, int rgbs[][LED_NCHANS], int chan)
{
int i = 0;
char *p;
while (chan < LED_NCHANS && i < CHAN_MAXLEDS && hexdig(*s) >= 0) {
while (chan < LED_NCHANS && i < CHAN_MAXLEDS && hexdig(*s) >= 0)
{
rgbs[i++][chan] = strtoul(s, &p, 16);
s = *p ? p + 1 : p;
}
@@ -177,19 +179,24 @@ int str_rgb(char *s, int rgbs[][LED_NCHANS], int chan) {
// Set Tx data for 8 or 16 chans, 1 LED per chan, given 1 RGB val per chan
// Logic 1 is 0.8us high, 0.4 us low, logic 0 is 0.4us high, 0.8us low
void set_color(uint32_t rgb, TXDATA_T *txd) {
void set_color(uint32_t rgb, TXDATA_T *txd)
{
int msk;
// For each bit of the 24-bit RGB values..
for (size_t n = 0; n < LED_NBITS; n++) {
for (size_t n = 0; n < LED_NBITS; n++)
{
// Mask to convert RGB to GRB, M.S bit first
msk = n == 0 ? 0x800000 : n == 8 ? 0x8000 : n == 16 ? 0x80 : msk >> 1;
msk = n == 0 ? 0x800000 : n == 8 ? 0x8000
: n == 16 ? 0x80
: msk >> 1;
// 1st byte or word is a high pulse on all lines
txd[0] = (TXDATA_T)0xffff;
// 2nd has high or low bits from data
// 3rd is a low pulse
txd[1] = txd[2] = 0;
if (rgb & msk) {
if (rgb & msk)
{
txd[1] = (TXDATA_T)0xffff;
}
txd += BIT_NPULSES;
@@ -198,19 +205,24 @@ void set_color(uint32_t rgb, TXDATA_T *txd) {
// Set Tx data for 8 or 16 chans, 1 LED per chan, given 1 RGB val per chan
// Logic 1 is 0.8us high, 0.4 us low, logic 0 is 0.4us high, 0.8us low
void rgb_txdata(int *rgbs, TXDATA_T *txd) {
void rgb_txdata(int *rgbs, TXDATA_T *txd)
{
int i, n, msk;
// For each bit of the 24-bit RGB values..
for (n = 0; n < LED_NBITS; n++) {
for (n = 0; n < LED_NBITS; n++)
{
// Mask to convert RGB to GRB, M.S bit first
msk = n == 0 ? 0x800000 : n == 8 ? 0x8000 : n == 16 ? 0x80 : msk >> 1;
msk = n == 0 ? 0x800000 : n == 8 ? 0x8000
: n == 16 ? 0x80
: msk >> 1;
// 1st byte or word is a high pulse on all lines
txd[0] = (TXDATA_T)0xffff;
// 2nd has high or low bits from data
// 3rd is a low pulse
txd[1] = txd[2] = 0;
for (i = 0; i < LED_NCHANS; i++) {
for (i = 0; i < LED_NCHANS; i++)
{
if (rgbs[i] & msk)
txd[1] |= (1 << i);
}
@@ -219,25 +231,30 @@ void rgb_txdata(int *rgbs, TXDATA_T *txd) {
}
// Swap adjacent bytes in transmit data
void swap_bytes(void *data, int len) {
void swap_bytes(void *data, int len)
{
uint16_t *wp = (uint16_t *)data;
len = (len + 1) / 2;
while (len-- > 0) {
while (len-- > 0)
{
*wp = __builtin_bswap16(*wp);
wp++;
}
}
// Return hex digit value, -ve if not hex
int hexdig(char c) {
int hexdig(char c)
{
c = toupper(c);
return ((c >= '0' && c <= '9') ? c - '0' : (c >= 'A' && c <= 'F') ? c - 'A' + 10 : -1);
return ((c >= '0' && c <= '9') ? c - '0' : (c >= 'A' && c <= 'F') ? c - 'A' + 10
: -1);
}
// Map GPIO, DMA and SMI registers into virtual mem (user space)
// If any of these fail, program will be terminate_smid
void map_devices(void) {
void map_devices(void)
{
map_periph(&gpio_regs, (void *)GPIO_BASE, PAGE_SIZE);
map_periph(&dma_regs, (void *)DMA_BASE, PAGE_SIZE);
map_periph(&clk_regs, (void *)CLK_BASE, PAGE_SIZE);
@@ -245,16 +262,19 @@ void map_devices(void) {
}
// Catastrophic failure in initial setup
void fail(char *s) {
void fail(char *s)
{
printf(s);
terminate_smi(0);
}
// Free memory segments and exit
void terminate_smi(int sig) {
void terminate_smi(int sig)
{
int i;
printf("Closing\n");
if (gpio_regs.virt) {
if (gpio_regs.virt)
{
for (i = 0; i < LED_NCHANS; i++)
gpio_mode(LED_D0_PIN + i, GPIO_IN);
}
@@ -270,7 +290,8 @@ void terminate_smi(int sig) {
// Initialise SMI, given data width, time step, and setup/hold/strobe counts
// Step value is in nanoseconds: even numbers, 2 to 30
void init_smi(int ledChan, int ns, int setup, int strobe, int hold) {
void init_smi(int ledChan, int ns, int setup, int strobe, int hold)
{
int width = ledChan > 8 ? SMI_16_BITS : SMI_8_BITS;
int i, divi = ns / 2;
@@ -286,7 +307,8 @@ void init_smi(int ledChan, int ns, int setup, int strobe, int hold) {
smi_dcd = (SMI_DCD_REG *)REG32(smi_regs, SMI_DCD);
smi_cs->value = smi_l->value = smi_a->value = 0;
smi_dsr->value = smi_dsw->value = smi_dcs->value = smi_dca->value = 0;
if (*REG32(clk_regs, CLK_SMI_DIV) != divi << 12) {
if (*REG32(clk_regs, CLK_SMI_DIV) != divi << 12)
{
*REG32(clk_regs, CLK_SMI_CTL) = CLK_PASSWD | (1 << 5);
usleep(10);
while (*REG32(clk_regs, CLK_SMI_CTL) & (1 << 7))
@@ -313,7 +335,8 @@ void init_smi(int ledChan, int ns, int setup, int strobe, int hold) {
}
// Set up SMI transfers using DMA
void setup_smi_dma(MEM_MAP *mp, int nsamp, TXDATA_T **txdata) {
void setup_smi_dma(MEM_MAP *mp, int nsamp, TXDATA_T **txdata)
{
DMA_CB *cbs = mp->virt;
*txdata = (TXDATA_T *)(cbs + 1);
@@ -331,7 +354,8 @@ void setup_smi_dma(MEM_MAP *mp, int nsamp, TXDATA_T **txdata) {
}
// Start SMI DMA transfers
void start_smi(MEM_MAP *mp) {
void start_smi(MEM_MAP *mp)
{
DMA_CB *cbs = mp->virt;
start_dma(mp, DMA_CHAN, &cbs[0], 0);