reorganize

This commit is contained in:
Kizarm 2025-01-25 12:21:08 +01:00
parent b8f0033a15
commit 97ce195c49
34 changed files with 33 additions and 27 deletions

2
.gitignore vendored
View file

@ -8,6 +8,8 @@
*.hex *.hex
*.map *.map
*.elf *.elf
*.o
*.so
*/midi/melody.c */midi/melody.c
*/midi/miditone.c */midi/miditone.c
*/midi/ton/gen */midi/ton/gen

4
V203F6P6/README.md Normal file
View file

@ -0,0 +1,4 @@
# V203R6
Koupil jsem na ALI pár levných procesorů CH32V203F6P6,
tak jsem se rozhodl je vyzkoušet. Má to méně paměti (32K flash, 10K ram),
ořezané periferie, ale na pokusy by to mohlo stačit.

View file

@ -4,7 +4,7 @@
/* C++ interface (jako callback v C) */ /* C++ interface (jako callback v C) */
template<typename T> class OneWay { template<typename T> class OneWay {
public: public:
virtual unsigned Send (T * const ptr, const unsigned len, const bool low = false) = 0; virtual unsigned Send (T * const ptr, const unsigned len) = 0;
}; };
#endif // ONEWAY_H #endif // ONEWAY_H

View file

@ -3,14 +3,14 @@
#include "system.h" #include "system.h"
#include "gpio.h" #include "gpio.h"
extern "C" { extern "C" {
extern const unsigned table []; extern const unsigned table []; // generováno linux/graph.py
}; };
static FIFO<uint32_t, NUMLEDS> ring; static FIFO<uint32_t, FIFOLEN> ring;
static ws2812b driver(ring); static ws2812b driver(ring);
static SpiClass spi (driver); static SpiClass spi (driver);
static GpioClass led (GPIOB, 8); static GpioClass led (GPIOB, 8);
static constexpr unsigned timeout = 5'000u; static constexpr unsigned timeout = 10'000u;
int main () { int main () {
led << true; led << true;

View file

@ -41,20 +41,19 @@ static void InitPins () noexcept {
void SpiClass::drq() { void SpiClass::drq() {
if (!driver) return; if (!driver) return;
DMA1_Type::INTFR_DEF state (DMA1.INTFR); DMA1_Type::INTFR_DEF state (DMA1.INTFR);
if (state.B.HTIF3) { /*if (state.B.HTIF3) {
DMA1.INTFCR.B.CHTIF3 = SET; // clear half DMA1.INTFCR.B.CHTIF3 = SET; // clear half
driver->Send (ptrl, HALF_LEN, true); } */
}
if (state.B.TCIF3) { if (state.B.TCIF3) {
DMA1.INTFCR.B.CTCIF3 = SET; // clear complete DMA1.INTFCR.B.CTCIF3 = SET; // clear complete
//driver->Send (ptrh, HALF_LEN, false); // reset driver->Send (ptrh, LEDS_LEN);
} }
} }
SpiClass::SpiClass(OneWay<uint8_t> & base) noexcept : driver (& base), ptrl (buffer), ptrh (buffer + HALF_LEN) { SpiClass::SpiClass(OneWay<uint8_t> & base) noexcept : driver (& base), ptrl (buffer), ptrh (buffer + PADDING) {
pSpiInstance = this; pSpiInstance = this;
for (unsigned n=0u; n<FULL_LEN; n++) buffer[n] = 0u; for (unsigned n=0u; n<FULL_LEN; n++) buffer[n] = 0u;
Color * ptr = reinterpret_cast<Color*>(ptrl); Color * ptr = reinterpret_cast<Color*>(ptrh);
const OneColor oz(0x00); const OneColor oz(0x00);
for (unsigned n=0; n<NUMLEDS; n++) { for (unsigned n=0; n<NUMLEDS; n++) {
Color & c = ptr [n]; Color & c = ptr [n];
@ -83,7 +82,7 @@ void SpiClass::Init() {
r.B.MINC = SET; // memory increment r.B.MINC = SET; // memory increment
r.B.MSIZE = 0u; // 8-bit r.B.MSIZE = 0u; // 8-bit
r.B.PSIZE = 0u; // 8-bit r.B.PSIZE = 0u; // 8-bit
r.B.HTIE = SET; // INT Enable HALF //r.B.HTIE = SET; // INT Enable HALF
r.B.TCIE = SET; // INT Enable FULL r.B.TCIE = SET; // INT Enable FULL
r.B.CIRC = SET; // Circular MODE r.B.CIRC = SET; // Circular MODE
// Enable DMA Channel 1 // Enable DMA Channel 1
@ -99,7 +98,7 @@ void SpiClass::Init() {
r.B.SSI = SET; r.B.SSI = SET;
r.B.LSBFIRST = SET; r.B.LSBFIRST = SET;
/* 2.25 MHz - 1bit = 444 ns /* 2.25 MHz - 1bit = 444 ns
* 1 LED 9 x 8 x 0.444 = 32 us DMA celkem 16 x 32 = 0.512 ms * 1 LED => 9 x 8 x 0.444 = 32 us DMA celkem (10 + 4) x 32 = 0.448 ms
* */ * */
r.B.BR = FPCLK_64; r.B.BR = FPCLK_64;
return r.R; return r.R;

View file

@ -4,8 +4,9 @@
#include "ws2812b.h" #include "ws2812b.h"
/** /**
*/ */
static constexpr unsigned HALF_LEN = NUMLEDS * sizeof (Color); static constexpr unsigned PADDING = 10 * sizeof (Color);
static constexpr unsigned FULL_LEN = 2 * HALF_LEN; static constexpr unsigned LEDS_LEN = NUMLEDS * sizeof (Color);
static constexpr unsigned FULL_LEN = PADDING + LEDS_LEN;
class SpiClass { class SpiClass {
OneWay<uint8_t> * driver; OneWay<uint8_t> * driver;

View file

@ -37,7 +37,7 @@ unsigned OneColor::to_string(char * ptr, const int m) {
ws2812b::ws2812b (FIFO<uint32_t,8> & r) noexcept : OneWay (), ring(r) { ws2812b::ws2812b (FIFO<uint32_t,8> & r) noexcept : OneWay (), ring(r) {
} }
unsigned int ws2812b::Send (uint8_t * const ptr, const unsigned int len, const bool low) { unsigned int ws2812b::Send (uint8_t * const ptr, const unsigned int len) {
uint32_t cmd; uint32_t cmd;
while (ring.Read(cmd)) { while (ring.Read(cmd)) {
const Entry ne (cmd); const Entry ne (cmd);

View file

@ -27,25 +27,25 @@ union Entry {
uint32_t number; uint32_t number;
explicit Entry (const uint32_t e) noexcept { number = e; } explicit Entry (const uint32_t e) noexcept { number = e; }
}; };
/***************************************************************************/ /*************************************************************************************/
static constexpr unsigned NUMLEDS = 8u; static constexpr unsigned NUMLEDS = 4u;
/***************************************************************************/ static constexpr unsigned FIFOLEN = 8u; // min. depth je 8, jinak mocnina 2 >= NUMLEDS
/*************************************************************************************/
/** @class ws2812b /** @class ws2812b
* @brief Driver pro WS2812B * @brief Driver pro WS2812B
* On ten driver je trochu divný. Běží nad SPI s použitím pinu MOSI, 1 bit barvy * On ten driver je trochu divný. Běží nad SPI s použitím pinu MOSI, 1 bit barvy
* jsou 3 bity SPI. Funguje to tak, že SPI běží přes DMA v cirkulárním módu, tedy * jsou 3 bity SPI. Funguje to tak, že SPI běží přes DMA v cirkulárním módu, tedy
* pořád, v 1. polovině si vybere z fronty ring data a uloží je do buferu ve správném * pořád, v 1. části dělá "reset", tedy časování rámce (vysílá nuly).
* tvaru, 2. polovina dělá "reset", tedy časování rámce (vysílá nuly). * V 2. části si vybere z fronty ring data a uloží je do buferu ve správném
* tvaru. Využívá se toho, že přerušení přijde na konci a naplnění daty
* netrvá dlouho, takže se přepisuje jen část, která se nevysílá.
* Fronta byla použita (celkem zbytečně) protože zatím netuším jaká data posílat. * Fronta byla použita (celkem zbytečně) protože zatím netuším jaká data posílat.
* To, že celá 2. polovina je zabrána pro reset je také volovina, ale ničemu to nevadí
* a je to jednoduché. Šlo by dát reset na začátek a v přerušení na konci do buferu
* nasypat data - nebude to trvat tak dlouho aby DMA začalo posílat data pro LED.
* */ * */
class ws2812b : public OneWay<uint8_t> { class ws2812b : public OneWay<uint8_t> {
FIFO<uint32_t,8> & ring; FIFO<uint32_t,FIFOLEN> & ring;
public: public:
explicit ws2812b (FIFO<uint32_t,8> & r) noexcept; explicit ws2812b (FIFO<uint32_t,FIFOLEN> & r) noexcept;
unsigned int Send (uint8_t * const ptr, const unsigned int len, const bool low = false) override; unsigned int Send (uint8_t * const ptr, const unsigned int len) override;
protected: protected:
}; };

Binary file not shown.

Binary file not shown.