Deluge Firmware 1.3.0
Build date: 2025.04.16
Loading...
Searching...
No Matches
pic.h
1#pragma once
2#include "definitions_cxx.hpp"
3#include "gui/colour/colour.h"
4#include "util/misc.h"
5#include <array>
6#include <cstddef>
7#include <cstdint>
8#include <functional>
9#include <initializer_list>
10#include <optional>
11#include <stdint.h>
12
13extern "C" {
14#include "RZA1/cpu_specific.h"
15#include "RZA1/mtu/mtu.h"
16#include "RZA1/system/iodefines/dmac_iodefine.h"
17#include "RZA1/uart/sio_char.h"
18#include "drivers/uart/uart.h"
19}
20
25class PIC {
26 static constexpr uint32_t kUartFullSpeedPadsHz = 200000; // 400000 glitches sometimes, especially if you zoom lots
27
28 enum class Message : uint8_t {
29 NONE = 0,
30
31 SET_COLOUR_FOR_TWO_COLUMNS = 1,
32 /* 9 of these (8 pairs of main pads, 1 pair of side pads)*/
33
34 SET_FLASH_COLOR = 10,
35
36 SET_DEBOUNCE_TIME = 18,
37 SET_REFRESH_TIME = 19,
38
39 SET_GOLD_KNOB_0_INDICATORS = 20,
40 SET_GOLD_KNOB_1_INDICATORS = 21,
41 RESEND_BUTTON_STATES = 22,
42 SET_FLASH_LENGTH = 23,
43 SET_PAD_FLASHING = 24,
44
45 SET_LED_OFF = 152,
46 SET_LED_ON = 188,
47
48 UPDATE_SEVEN_SEGMENT_DISPLAY = 224,
49 SET_UART_SPEED = 225,
50
51 SET_SCROLL_ROW = 228,
52
53 SET_SCROLL_LEFT = 236,
54 SET_SCROLL_RIGHT,
55 SET_SCROLL_RIGHT_FULL,
56 SET_SCROLL_LEFT_FULL,
57
58 DONE_SENDING_ROWS = 240,
59
60 SET_SCROLL_UP = 241,
61 SET_SCROLL_DOWN = 242,
62
63 SET_DIMMER_INTERVAL = 243,
64 SET_MIN_INTERRUPT_INTERVAL = 244,
65 REQUEST_FIRMWARE_VERSION = 245,
66 ENABLE_OLED = 247,
67 SELECT_OLED = 248,
68 DESELECT_OLED = 249,
69 SET_DC_LOW = 250,
70 SET_DC_HIGH = 251,
71
72 };
73
74public:
78 enum class Response : uint8_t { // Technically matches Message except in some spots????
79 NONE = 0,
80
81 UNKNOWN_BOOT_RESPONSE = 129,
82
83 RESET_SETTINGS = 175,
84 FIRMWARE_VERSION_NEXT = 245,
85 UNKNOWN_OLED_RELATED_COMMAND = 246,
86 SET_DC_HIGH = 251,
87
88 NEXT_PAD_OFF = 252,
89 UNKNOWN_BREAK = 253,
90 NO_PRESSES_HAPPENING = 254,
91 };
92 static constexpr Response kPadAndButtonMessagesEnd{180};
93
97 static void setupForPads() { uartSetBaudRate(UART_CHANNEL_PIC, kUartFullSpeedPadsHz); }
98
107 static void setColourForTwoColumns(size_t idx, const std::array<RGB, kDisplayHeight * 2>& colours) {
108 send(util::to_underlying(Message::SET_COLOUR_FOR_TWO_COLUMNS) + idx);
109 for (const RGB& colour : colours) {
110 send(colour);
111 }
112 }
113
121 static void setDebounce(uint8_t time_ms) { send(Message::SET_DEBOUNCE_TIME, time_ms); }
122
129 static void setGoldKnobIndicator(bool which, const std::array<uint8_t, kNumGoldKnobIndicatorLEDs>& indicator) {
130 Message knob = which ? Message::SET_GOLD_KNOB_1_INDICATORS : Message::SET_GOLD_KNOB_0_INDICATORS;
131 send(knob, indicator);
132 }
133
134 static void setLEDOff(size_t idx) { send(util::to_underlying(Message::SET_LED_OFF) + idx); }
135 static void setLEDOn(size_t idx) { send(util::to_underlying(Message::SET_LED_ON) + idx); }
136
140 static void resendButtonStates() { send(Message::RESEND_BUTTON_STATES); }
141
142 static void setMinInterruptInterval(uint8_t time_ms) { send(Message::SET_MIN_INTERRUPT_INTERVAL, time_ms); }
143 static void setFlashLength(uint8_t time_ms) { send(Message::SET_FLASH_LENGTH, time_ms); }
144
145 static void setUARTSpeed() {
146 uint8_t speed = 4000000.0f / kUartFullSpeedPadsHz - 0.5f; // Speed is 4MHz / (x + 1)
147 send(Message::SET_UART_SPEED, speed);
148 }
149
150 static void flashMainPad(size_t idx) { send(util::to_underlying(Message::SET_PAD_FLASHING) + idx); }
151
158 static void flashMainPadWithColourIdx(size_t idx, int32_t colour_idx) {
159 send(util::to_underlying(Message::SET_FLASH_COLOR) + colour_idx);
160 flashMainPad(idx);
161 }
162
163 static void update7SEG(const std::array<uint8_t, kNumericDisplayLength>& display) {
164 send(Message::UPDATE_SEVEN_SEGMENT_DISPLAY, display);
165 }
166
167 static void enableOLED() { send(Message::ENABLE_OLED); }
168 static void selectOLED() { send(Message::SELECT_OLED); }
169 static void deselectOLED() { send(Message::DESELECT_OLED); }
170 static void setDCLow() { send(Message::SET_DC_LOW); }
171 static void setDCHigh() { send(Message::SET_DC_HIGH); }
172
173 static void requestFirmwareVersion() { send(Message::REQUEST_FIRMWARE_VERSION); }
174
175 static void sendColour(const RGB& colour) { send(colour); }
176
177 static void setRefreshTime(uint8_t time_ms) { send(Message::SET_REFRESH_TIME, time_ms); }
178 static void setDimmerInterval(uint8_t interval) { send(Message::SET_DIMMER_INTERVAL, interval); }
179
187 static void sendScrollRow(size_t idx, RGB colour) {
188 send(util::to_underlying(Message::SET_SCROLL_ROW) + idx);
189 send(colour);
190 }
191
192 static void setupHorizontalScroll(uint8_t bitflags) {
193 send(util::to_underlying(Message::SET_SCROLL_LEFT) + bitflags);
194 }
195
196 static void doVerticalScroll(bool direction, const std::array<RGB, kDisplayWidth + kSideBarWidth>& colours) {
197 Message msg = direction ? Message::SET_SCROLL_UP : Message::SET_SCROLL_DOWN;
198 send(msg, colours);
199 }
200
201 static void doneSendingRows() { send(Message::DONE_SENDING_ROWS); }
202
206 static void flush() { uartFlushIfNotSending(UART_ITEM_PIC); }
207
211 static void waitForFlush() {
212 while (!(DMACn(PIC_TX_DMA_CHANNEL).CHSTAT_n & (1 << 6))) {}
213 }
214
220 static Response read() {
221 uint8_t value;
222 uartGetChar(UART_ITEM_PIC, (char*)&value);
223 return Response{value};
224 }
225
230 static Response read(uint32_t timeout) {
231 uint16_t timeWaitBegan = *TCNT[TIMER_SYSTEM_FAST];
232 while ((uint16_t)(*TCNT[TIMER_SYSTEM_FAST] - timeWaitBegan) < timeout) {
233 Response value = PIC::read();
234 if (value != Response::NONE) {
235 return value;
236 }
237 }
238 return Response::NONE;
239 }
240
248 static int32_t read(uint32_t timeout, std::function<int32_t(Response)> handler) {
249 uint16_t timeWaitBegan = *TCNT[TIMER_SYSTEM_FAST];
250 int32_t result = 1; // error with failure by default
251 while ((uint16_t)(*TCNT[TIMER_SYSTEM_FAST] - timeWaitBegan) < timeout) {
252 result = handler(PIC::read());
253 if (result != 0) {
254 return result;
255 }
256 }
257 return result;
258 }
259
260private:
264 template <typename... Bytes>
265 inline static void send(Message msg, Bytes... bytes) {
266 send(msg);
267 for (const uint8_t byte : {bytes...}) {
268 send(byte);
269 }
270 }
271
275 template <typename T, size_t size>
276 inline static void send(Message msg, const std::array<T, size>& bytes) {
277 send(msg);
278 for (auto byte : bytes) {
279 send(byte);
280 }
281 }
282
286 inline static void send(Message msg) { send(util::to_underlying(msg)); }
287
291 inline static void send(const RGB& colour) {
292 send(colour.r);
293 send(colour.g);
294 send(colour.b);
295 }
296
300 inline static void send(uint8_t msg) {
301 intptr_t writePos = uartItems[UART_ITEM_PIC].txBufferWritePos;
302 volatile char* uncached_tx_buf = (volatile char*)(picTxBuffer + UNCACHED_MIRROR_OFFSET);
303 uncached_tx_buf[writePos] = msg;
304 uartItems[UART_ITEM_PIC].txBufferWritePos += 1;
305 uartItems[UART_ITEM_PIC].txBufferWritePos &= (PIC_TX_BUFFER_SIZE - 1);
306 }
307};
The static class for interacting with the PIC peripheral.
Definition pic.h:25
static void setupForPads()
Change the UART baud rate to the output speed safe for rapid pad updates.
Definition pic.h:97
static void flashMainPadWithColourIdx(size_t idx, int32_t colour_idx)
Flash a pad using the PIC's built-in timer and colour system.
Definition pic.h:158
static void setGoldKnobIndicator(bool which, const std::array< uint8_t, kNumGoldKnobIndicatorLEDs > &indicator)
This sets the indicator for the gold knobs,.
Definition pic.h:129
static int32_t read(uint32_t timeout, std::function< int32_t(Response)> handler)
Fetch a response from the PIC, using a callback handler.
Definition pic.h:248
static void send(const RGB &colour)
Send a single colour.
Definition pic.h:291
static void setDebounce(uint8_t time_ms)
Set the PIC's debounce time in milliseconds. This prevents extra keypresses from happening when the s...
Definition pic.h:121
static void send(uint8_t msg)
Send a byte. This was originally bufferPICUart()
Definition pic.h:300
static Response read(uint32_t timeout)
Fetch a response from the PIC (blocking)
Definition pic.h:230
static void sendScrollRow(size_t idx, RGB colour)
This is used to make smooth scrolling on the horizontal axis, by filling up an 8-pixel framebuffer on...
Definition pic.h:187
static Response read()
Read a single response from the PIC.
Definition pic.h:220
static void waitForFlush()
Wait for the last flush() operation to complete (blocking)
Definition pic.h:211
static void setColourForTwoColumns(size_t idx, const std::array< RGB, kDisplayHeight *2 > &colours)
Set the Colour for two columns of leds.
Definition pic.h:107
static void send(Message msg, const std::array< T, size > &bytes)
Send a message followed by all the objects in the provided array.
Definition pic.h:276
static void send(Message msg)
Send a single message.
Definition pic.h:286
static void resendButtonStates()
Request that the PIC resend all button states.
Definition pic.h:140
static void send(Message msg, Bytes... bytes)
Send a message and a variable number of following bytes.
Definition pic.h:265
Response
The response received from the PIC.
Definition pic.h:78
static void flush()
Flush the UART buffer if it's not already being done.
Definition pic.h:206
This class represents the colour format most used by the Deluge globally.
Definition rgb.h:14
channel_type b
Blue channel.
Definition rgb.h:34
channel_type r
Red channel.
Definition rgb.h:28
channel_type g
Green channel.
Definition rgb.h:31