Use DMA for ws2812 data transmission
RGB_MATRIX for split keyboard is improved
This commit is contained in:
parent
a0fd310399
commit
8fd79c3475
2 changed files with 28 additions and 13 deletions
|
|
@ -68,7 +68,7 @@ inline static bool serial_read_pin(void) { return readPin(SOFT_SERIAL_PIN); }
|
|||
inline static void serial_low(void) { writePinLow(SOFT_SERIAL_PIN); }
|
||||
inline static void serial_high(void) { writePinHigh(SOFT_SERIAL_PIN); }
|
||||
|
||||
void interrupt_handler(uint gpio, uint32_t events);
|
||||
static void interrupt_handler(uint gpio, uint32_t events);
|
||||
|
||||
static PIO pio = pio0;
|
||||
static uint sm_tx, sm_rx;
|
||||
|
|
@ -144,7 +144,7 @@ void soft_serial_target_init(void) {
|
|||
}
|
||||
|
||||
// Used by the master to synchronize timing with the slave.
|
||||
static int __attribute__((noinline)) sync_recv(void) {
|
||||
static int __no_inline_not_in_flash_func(sync_recv)(void) {
|
||||
serial_input();
|
||||
|
||||
volatile uint64_t timeout = time_us_64() + 10000;
|
||||
|
|
@ -180,7 +180,7 @@ static int __attribute__((noinline)) sync_recv(void) {
|
|||
}
|
||||
|
||||
// Used by the slave to send a synchronization signal to the master.
|
||||
static void __attribute__((noinline)) sync_send(void) {
|
||||
static void __no_inline_not_in_flash_func(sync_send)(void) {
|
||||
serial_output();
|
||||
|
||||
serial_low();
|
||||
|
|
@ -220,7 +220,7 @@ static void serial_wait_send_complete(void) {
|
|||
}
|
||||
|
||||
// interrupt handle to be used by the slave device
|
||||
void interrupt_handler(uint gpio, uint32_t events) {
|
||||
static void __no_inline_not_in_flash_func(interrupt_handler)(uint gpio, uint32_t events) {
|
||||
if (gpio != SOFT_SERIAL_PIN || events != GPIO_IRQ_EDGE_FALL) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -339,7 +339,7 @@ void interrupt_handler(uint gpio, uint32_t events) {
|
|||
// TRANSACTION_NO_RESPONSE
|
||||
// TRANSACTION_DATA_ERROR
|
||||
// this code is very time dependent, so we need to disable interrupts
|
||||
int soft_serial_transaction(int sstd_index) {
|
||||
int __no_inline_not_in_flash_func(soft_serial_transaction)(int sstd_index) {
|
||||
if (sstd_index > NUM_TOTAL_TRANSACTIONS) return TRANSACTION_TYPE_ERROR;
|
||||
split_transaction_desc_t *trans = &split_transaction_table[sstd_index];
|
||||
if (!trans->status) return TRANSACTION_TYPE_ERROR; // not registered
|
||||
|
|
|
|||
|
|
@ -1,16 +1,21 @@
|
|||
// Copyright 2022 sekigon-gonnoc
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ws2812.h"
|
||||
#include "ws2812.pio.h"
|
||||
|
||||
#include "atomic_util.h"
|
||||
#include "pio_manager.h"
|
||||
#include "boards/pico_boards.h"
|
||||
|
||||
#include "pico/stdlib.h"
|
||||
#include "hardware/dma.h"
|
||||
|
||||
static PIO pio = pio0;
|
||||
static int sm = 0;
|
||||
static PIO pio = pio0;
|
||||
static int sm = 0;
|
||||
static int dma_ch = 1;
|
||||
|
||||
static int ws2812_init(void) {
|
||||
sm = pio_manager_get_empty_sm(pio);
|
||||
|
|
@ -27,6 +32,15 @@ static int ws2812_init(void) {
|
|||
|
||||
ws2812_program_init(pio, sm, offset, RGB_DI_PIN, 800000, false);
|
||||
|
||||
dma_channel_config conf = dma_channel_get_default_config(dma_ch);
|
||||
|
||||
channel_config_set_read_increment(&conf, true);
|
||||
channel_config_set_write_increment(&conf, false);
|
||||
channel_config_set_transfer_data_size(&conf, DMA_SIZE_32);
|
||||
channel_config_set_dreq(&conf, pio_get_dreq(pio, sm, true));
|
||||
|
||||
dma_channel_set_config(dma_ch, &conf, false);
|
||||
dma_channel_set_write_addr(dma_ch, &pio->txf[sm], false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -40,12 +54,13 @@ void ws2812_setleds(LED_TYPE *ledarray, uint16_t number_of_leds) {
|
|||
}
|
||||
}
|
||||
|
||||
printf("led %d %d %d\n", ledarray[0].r, ledarray[0].g, ledarray[0].b);
|
||||
|
||||
uint32_t leddata[RGBLED_NUM];
|
||||
for (int i = 0; i < number_of_leds; i++) {
|
||||
pio_sm_put_blocking(pio, sm,
|
||||
(((uint32_t)ledarray[i].r) << 16) |
|
||||
(((uint32_t)ledarray[i].g) << 24) |
|
||||
((uint32_t)ledarray[i].b << 8));
|
||||
leddata[i] = (((uint32_t)ledarray[i].g) << 24) |
|
||||
(((uint32_t)ledarray[i].r) << 16) |
|
||||
((uint32_t)ledarray[i].b << 8);
|
||||
}
|
||||
|
||||
dma_channel_transfer_from_buffer_now(dma_ch, leddata, number_of_leds);
|
||||
dma_channel_wait_for_finish_blocking(dma_ch);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue