summaryrefslogtreecommitdiff
path: root/platforms/chibios/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'platforms/chibios/drivers')
-rw-r--r--platforms/chibios/drivers/analog.c111
-rw-r--r--platforms/chibios/drivers/audio_dac.h34
-rw-r--r--platforms/chibios/drivers/audio_dac_additive.c48
-rw-r--r--platforms/chibios/drivers/audio_pwm_hardware.c8
-rw-r--r--platforms/chibios/drivers/i2c_master.c47
-rw-r--r--platforms/chibios/drivers/i2c_master.h18
-rw-r--r--platforms/chibios/drivers/serial.c12
-rw-r--r--platforms/chibios/drivers/spi_master.c14
-rw-r--r--platforms/chibios/drivers/uart.c70
-rw-r--r--platforms/chibios/drivers/uart.h194
-rw-r--r--platforms/chibios/drivers/uart_serial.c65
-rw-r--r--platforms/chibios/drivers/uart_sio.c77
-rw-r--r--platforms/chibios/drivers/ws2812_bitbang.c23
-rw-r--r--platforms/chibios/drivers/ws2812_pwm.c3
14 files changed, 508 insertions, 216 deletions
diff --git a/platforms/chibios/drivers/analog.c b/platforms/chibios/drivers/analog.c
index bf84ce8f76..fb146df936 100644
--- a/platforms/chibios/drivers/analog.c
+++ b/platforms/chibios/drivers/analog.c
@@ -31,7 +31,15 @@
#endif
#if STM32_ADCV3_OVERSAMPLING
-# error "STM32 ADCV3 Oversampling is not supported at this time."
+// Apparently all ADCV3 chips that support oversampling (STM32L4xx, STM32L4xx+,
+// STM32G4xx, STM32WB[35]x) have errata like “Wrong ADC result if conversion
+// done late after calibration or previous conversion”; the workaround is to
+// perform a dummy conversion and discard its result. STM32G4xx chips also
+// have the “ADC channel 0 converted instead of the required ADC channel”
+// errata, one workaround for which is also to perform a dummy conversion.
+# define ADC_DUMMY_CONVERSIONS_AT_START 1
+#else
+# define ADC_DUMMY_CONVERSIONS_AT_START 0
#endif
// Otherwise assume V3
@@ -76,8 +84,10 @@
#ifndef ADC_COUNT
# if defined(RP2040) || defined(STM32F0XX) || defined(STM32F1XX) || defined(STM32F4XX) || defined(GD32VF103) || defined(WB32F3G71xx) || defined(WB32FQ95xx)
# define ADC_COUNT 1
-# elif defined(STM32F3XX)
+# elif defined(STM32F3XX) || defined(STM32G4XX)
# define ADC_COUNT 4
+# elif defined(STM32L4XX)
+# define ADC_COUNT 3
# else
# error "ADC_COUNT has not been set for this ARM microcontroller."
# endif
@@ -89,13 +99,24 @@
# error "The ARM ADC implementation currently only supports reading one channel at a time."
#endif
+// Add dummy conversions as extra channels (this would work only on chips that
+// have multiple channel index fields instead of a channel mask, but all chips
+// that need that workaround are like that).
+#define ADC_TOTAL_CHANNELS (ADC_DUMMY_CONVERSIONS_AT_START + ADC_NUM_CHANNELS)
+
#ifndef ADC_BUFFER_DEPTH
# define ADC_BUFFER_DEPTH 1
#endif
// For more sampling rate options, look at hal_adc_lld.h in ChibiOS
-#ifndef ADC_SAMPLING_RATE
-# define ADC_SAMPLING_RATE ADC_SMPR_SMP_1P5
+#if !defined(ADC_SAMPLING_RATE) && !defined(RP2040)
+# if defined(ADC_SMPR_SMP_1P5)
+# define ADC_SAMPLING_RATE ADC_SMPR_SMP_1P5
+# elif defined(ADC_SMPR_SMP_2P5) // STM32L4XX, STM32L4XXP, STM32G4XX, STM32WBXX
+# define ADC_SAMPLING_RATE ADC_SMPR_SMP_2P5
+# else
+# error "Cannot determine the default ADC_SAMPLING_RATE for this MCU."
+# endif
#endif
// Options are 12, 10, 8, and 6 bit.
@@ -108,7 +129,7 @@
#endif
static ADCConfig adcCfg = {};
-static adcsample_t sampleBuffer[ADC_NUM_CHANNELS * ADC_BUFFER_DEPTH];
+static adcsample_t sampleBuffer[ADC_TOTAL_CHANNELS * ADC_BUFFER_DEPTH];
// Initialize to max number of ADCs, set to empty object to initialize all to false.
static bool adcInitialized[ADC_COUNT] = {};
@@ -116,7 +137,7 @@ static bool adcInitialized[ADC_COUNT] = {};
// TODO: add back TR handling???
static ADCConversionGroup adcConversionGroup = {
.circular = FALSE,
- .num_channels = (uint16_t)(ADC_NUM_CHANNELS),
+ .num_channels = (uint16_t)(ADC_TOTAL_CHANNELS),
#if defined(USE_ADCV1)
.cfgr1 = ADC_CFGR1_CONT | ADC_RESOLUTION,
.smpr = ADC_SAMPLING_RATE,
@@ -240,6 +261,74 @@ __attribute__((weak)) adc_mux pinToMux(pin_t pin) {
case C5: return TO_MUX( ADC_CHANNEL_IN15, 0 );
// STM32F103x[C-G] in 144-pin packages also have analog inputs on F6...F10, but they are on ADC3, and the
// ChibiOS ADC driver for STM32F1xx currently supports only ADC1, therefore these pins are not usable.
+#elif defined(STM32L4XX)
+ case A0: return TO_MUX( ADC_CHANNEL_IN5, 0 ); // Can also be ADC2 in some cases
+ case A1: return TO_MUX( ADC_CHANNEL_IN6, 0 ); // Can also be ADC2 in some cases
+ case A2: return TO_MUX( ADC_CHANNEL_IN7, 0 ); // Can also be ADC2
+ case A3: return TO_MUX( ADC_CHANNEL_IN8, 0 ); // Can also be ADC2
+ case A4: return TO_MUX( ADC_CHANNEL_IN9, 0 ); // Can also be ADC2
+ case A5: return TO_MUX( ADC_CHANNEL_IN10, 0 ); // Can also be ADC2
+ case A6: return TO_MUX( ADC_CHANNEL_IN11, 0 ); // Can also be ADC2
+ case A7: return TO_MUX( ADC_CHANNEL_IN12, 0 ); // Can also be ADC2
+ case B0: return TO_MUX( ADC_CHANNEL_IN15, 0 ); // Can also be ADC2
+ case B1: return TO_MUX( ADC_CHANNEL_IN16, 0 ); // Can also be ADC2
+ case C0: return TO_MUX( ADC_CHANNEL_IN1, 0 ); // Can also be ADC2 or ADC3
+ case C1: return TO_MUX( ADC_CHANNEL_IN2, 0 ); // Can also be ADC2 or ADC3
+ case C2: return TO_MUX( ADC_CHANNEL_IN3, 0 ); // Can also be ADC2 or ADC3
+ case C3: return TO_MUX( ADC_CHANNEL_IN4, 0 ); // Can also be ADC2 or ADC3
+ case C4: return TO_MUX( ADC_CHANNEL_IN13, 0 ); // Can also be ADC2
+ case C5: return TO_MUX( ADC_CHANNEL_IN14, 0 ); // Can also be ADC2
+# if STM32_HAS_GPIOF && STM32_ADC_USE_ADC3
+ case F3: return TO_MUX( ADC_CHANNEL_IN6, 2 );
+ case F4: return TO_MUX( ADC_CHANNEL_IN7, 2 );
+ case F5: return TO_MUX( ADC_CHANNEL_IN8, 2 );
+ case F6: return TO_MUX( ADC_CHANNEL_IN9, 2 );
+ case F7: return TO_MUX( ADC_CHANNEL_IN10, 2 );
+ case F8: return TO_MUX( ADC_CHANNEL_IN11, 2 );
+ case F9: return TO_MUX( ADC_CHANNEL_IN12, 2 );
+ case F10: return TO_MUX( ADC_CHANNEL_IN13, 2 );
+# endif
+#elif defined(STM32G4XX)
+ case A0: return TO_MUX( ADC_CHANNEL_IN1, 0 ); // Can also be ADC2
+ case A1: return TO_MUX( ADC_CHANNEL_IN2, 0 ); // Can also be ADC2
+ case A2: return TO_MUX( ADC_CHANNEL_IN3, 0 );
+ case A3: return TO_MUX( ADC_CHANNEL_IN4, 0 );
+ case A4: return TO_MUX( ADC_CHANNEL_IN17, 1 );
+ case A5: return TO_MUX( ADC_CHANNEL_IN13, 1 );
+ case A6: return TO_MUX( ADC_CHANNEL_IN3, 1 );
+ case A7: return TO_MUX( ADC_CHANNEL_IN4, 1 );
+ case B0: return TO_MUX( ADC_CHANNEL_IN15, 0 ); // Can also be ADC3
+ case B1: return TO_MUX( ADC_CHANNEL_IN12, 0 ); // Can also be ADC3
+ case B2: return TO_MUX( ADC_CHANNEL_IN12, 1 );
+ case B11: return TO_MUX( ADC_CHANNEL_IN14, 0 ); // Can also be ADC2
+ case B12: return TO_MUX( ADC_CHANNEL_IN11, 0 ); // Can also be ADC4
+ case B13: return TO_MUX( ADC_CHANNEL_IN5, 2 );
+ case B14: return TO_MUX( ADC_CHANNEL_IN5, 0 ); // Can also be ADC4
+ case B15: return TO_MUX( ADC_CHANNEL_IN15, 1 ); // Can also be ADC4
+ case C0: return TO_MUX( ADC_CHANNEL_IN6, 0 ); // Can also be ADC2
+ case C1: return TO_MUX( ADC_CHANNEL_IN7, 0 ); // Can also be ADC2
+ case C2: return TO_MUX( ADC_CHANNEL_IN8, 0 ); // Can also be ADC2
+ case C3: return TO_MUX( ADC_CHANNEL_IN9, 0 ); // Can also be ADC2
+ case C4: return TO_MUX( ADC_CHANNEL_IN5, 1 );
+ case C5: return TO_MUX( ADC_CHANNEL_IN11, 1 );
+ case D8: return TO_MUX( ADC_CHANNEL_IN12, 3 );
+ case D9: return TO_MUX( ADC_CHANNEL_IN13, 3 );
+ case D10: return TO_MUX( ADC_CHANNEL_IN7, 2 ); // Can also be ADC4
+ case D11: return TO_MUX( ADC_CHANNEL_IN8, 2 ); // Can also be ADC4
+ case D12: return TO_MUX( ADC_CHANNEL_IN9, 2 ); // Can also be ADC4
+ case D13: return TO_MUX( ADC_CHANNEL_IN10, 2 ); // Can also be ADC4
+ case D14: return TO_MUX( ADC_CHANNEL_IN11, 2 ); // Can also be ADC4
+ case E5: return TO_MUX( ADC_CHANNEL_IN2, 3 );
+ case E7: return TO_MUX( ADC_CHANNEL_IN4, 2 );
+ case E8: return TO_MUX( ADC_CHANNEL_IN6, 2 ); // Can also be ADC4
+ case E9: return TO_MUX( ADC_CHANNEL_IN2, 2 );
+ case E10: return TO_MUX( ADC_CHANNEL_IN14, 2 ); // Can also be ADC4
+ case E11: return TO_MUX( ADC_CHANNEL_IN15, 2 ); // Can also be ADC4
+ case E12: return TO_MUX( ADC_CHANNEL_IN16, 2 ); // Can also be ADC4
+ case E13: return TO_MUX( ADC_CHANNEL_IN3, 2 );
+ case E14: return TO_MUX( ADC_CHANNEL_IN1, 3 );
+ case F0: return TO_MUX( ADC_CHANNEL_IN10, 0 );
+ case F1: return TO_MUX( ADC_CHANNEL_IN10, 1 );
#elif defined(RP2040)
case 26U: return TO_MUX(0, 0);
case 27U: return TO_MUX(1, 0);
@@ -306,7 +395,11 @@ int16_t adc_read(adc_mux mux) {
#elif defined(RP2040)
adcConversionGroup.channel_mask = 1 << mux.input;
#else
- adcConversionGroup.sqr[0] = ADC_SQR1_SQ1_N(mux.input);
+ adcConversionGroup.sqr[0] = ADC_SQR1_SQ1_N(mux.input)
+# if ADC_DUMMY_CONVERSIONS_AT_START >= 1
+ | ADC_SQR1_SQ2_N(mux.input)
+# endif
+ ;
#endif
ADCDriver* targetDriver = intToADCDriver(mux.adc);
@@ -321,9 +414,9 @@ int16_t adc_read(adc_mux mux) {
#if defined(USE_ADCV2) || defined(RP2040)
// fake 12-bit -> N-bit scale
- return (*sampleBuffer) >> (12 - ADC_RESOLUTION);
+ return (sampleBuffer[ADC_DUMMY_CONVERSIONS_AT_START]) >> (12 - ADC_RESOLUTION);
#else
// already handled as part of adcConvert
- return *sampleBuffer;
+ return sampleBuffer[ADC_DUMMY_CONVERSIONS_AT_START];
#endif
}
diff --git a/platforms/chibios/drivers/audio_dac.h b/platforms/chibios/drivers/audio_dac.h
index 07cd622ead..2f62d12934 100644
--- a/platforms/chibios/drivers/audio_dac.h
+++ b/platforms/chibios/drivers/audio_dac.h
@@ -24,11 +24,6 @@
#endif
/**
- * Size of the dac_buffer arrays. All must be the same size.
- */
-#define AUDIO_DAC_BUFFER_SIZE 256U
-
-/**
* Highest value allowed sample value.
* since the DAC is limited to 12 bit, the absolute max is 0xfff = 4095U;
@@ -97,6 +92,35 @@
#endif
/**
+ * Size of the dac_buffer array. This controls the length of the runtime buffer
+ * which accumulates the data to be sent to the DAC every few milliseconds, and
+ * it does not need to correspond to the length of the wavetable for the chosen
+ * waveform defined by AUDIO_DAC_SAMPLE_WAVEFORM_* in the additive DAC driver.
+ * By default, this is set to be as close to 3.3 ms as possible, giving 300 DAC
+ * interrupts per second. Any smaller and the interrupt load gets too heavy and
+ * this results in crackling due to buffer underrun in the additive DAC driver;
+ * too large and the RAM (additive driver) or flash (basic driver) usage may be
+ * too high, causing build failures, and matrix scanning is liable to have long
+ * periodic pauses that delay key presses or releases or fully lose short taps.
+ * Large buffers also cause notes to take longer to stop after they should from
+ * music mode or MIDI input.
+ * This should be a power of 2 for maximum compatibility.
+ */
+#ifndef AUDIO_DAC_BUFFER_SIZE
+# if AUDIO_DAC_SAMPLE_RATE < 5100U
+# define AUDIO_DAC_BUFFER_SIZE 16U
+# elif AUDIO_DAC_SAMPLE_RATE < 9900U
+# define AUDIO_DAC_BUFFER_SIZE 32U
+# elif AUDIO_DAC_SAMPLE_RATE < 19500U
+# define AUDIO_DAC_BUFFER_SIZE 64U
+# elif AUDIO_DAC_SAMPLE_RATE < 38700U
+# define AUDIO_DAC_BUFFER_SIZE 128U
+# else
+# define AUDIO_DAC_BUFFER_SIZE 256U
+# endif
+#endif
+
+/**
* The number of tones that can be played simultaneously. If too high a value
* is used here, the keyboard will freeze and glitch-out when that many tones
* are being played.
diff --git a/platforms/chibios/drivers/audio_dac_additive.c b/platforms/chibios/drivers/audio_dac_additive.c
index 26e044b048..d6fde42b68 100644
--- a/platforms/chibios/drivers/audio_dac_additive.c
+++ b/platforms/chibios/drivers/audio_dac_additive.c
@@ -53,35 +53,39 @@
#ifdef AUDIO_DAC_SAMPLE_WAVEFORM_SINE
/* one full sine wave over [0,2*pi], but shifted up one amplitude and left pi/4; for the samples to start at 0
*/
-static const dacsample_t dac_buffer_sine[AUDIO_DAC_BUFFER_SIZE] = {
+static const dacsample_t dac_buffer_sine[] = {
// 256 values, max 4095
0x0, 0x1, 0x2, 0x6, 0xa, 0xf, 0x16, 0x1e, 0x27, 0x32, 0x3d, 0x4a, 0x58, 0x67, 0x78, 0x89, 0x9c, 0xb0, 0xc5, 0xdb, 0xf2, 0x10a, 0x123, 0x13e, 0x159, 0x175, 0x193, 0x1b1, 0x1d1, 0x1f1, 0x212, 0x235, 0x258, 0x27c, 0x2a0, 0x2c6, 0x2ed, 0x314, 0x33c, 0x365, 0x38e, 0x3b8, 0x3e3, 0x40e, 0x43a, 0x467, 0x494, 0x4c2, 0x4f0, 0x51f, 0x54e, 0x57d, 0x5ad, 0x5dd, 0x60e, 0x63f, 0x670, 0x6a1, 0x6d3, 0x705, 0x737, 0x769, 0x79b, 0x7cd, 0x800, 0x832, 0x864, 0x896, 0x8c8, 0x8fa, 0x92c, 0x95e, 0x98f, 0x9c0, 0x9f1, 0xa22, 0xa52, 0xa82, 0xab1, 0xae0, 0xb0f, 0xb3d, 0xb6b, 0xb98, 0xbc5, 0xbf1, 0xc1c, 0xc47, 0xc71, 0xc9a, 0xcc3, 0xceb, 0xd12, 0xd39, 0xd5f, 0xd83, 0xda7, 0xdca, 0xded, 0xe0e, 0xe2e, 0xe4e, 0xe6c, 0xe8a, 0xea6, 0xec1, 0xedc, 0xef5, 0xf0d, 0xf24, 0xf3a, 0xf4f, 0xf63, 0xf76, 0xf87, 0xf98, 0xfa7, 0xfb5, 0xfc2, 0xfcd, 0xfd8, 0xfe1, 0xfe9, 0xff0, 0xff5, 0xff9, 0xffd, 0xffe,
- 0xfff, 0xffe, 0xffd, 0xff9, 0xff5, 0xff0, 0xfe9, 0xfe1, 0xfd8, 0xfcd, 0xfc2, 0xfb5, 0xfa7, 0xf98, 0xf87, 0xf76, 0xf63, 0xf4f, 0xf3a, 0xf24, 0xf0d, 0xef5, 0xedc, 0xec1, 0xea6, 0xe8a, 0xe6c, 0xe4e, 0xe2e, 0xe0e, 0xded, 0xdca, 0xda7, 0xd83, 0xd5f, 0xd39, 0xd12, 0xceb, 0xcc3, 0xc9a, 0xc71, 0xc47, 0xc1c, 0xbf1, 0xbc5, 0xb98, 0xb6b, 0xb3d, 0xb0f, 0xae0, 0xab1, 0xa82, 0xa52, 0xa22, 0x9f1, 0x9c0, 0x98f, 0x95e, 0x92c, 0x8fa, 0x8c8, 0x896, 0x864, 0x832, 0x800, 0x7cd, 0x79b, 0x769, 0x737, 0x705, 0x6d3, 0x6a1, 0x670, 0x63f, 0x60e, 0x5dd, 0x5ad, 0x57d, 0x54e, 0x51f, 0x4f0, 0x4c2, 0x494, 0x467, 0x43a, 0x40e, 0x3e3, 0x3b8, 0x38e, 0x365, 0x33c, 0x314, 0x2ed, 0x2c6, 0x2a0, 0x27c, 0x258, 0x235, 0x212, 0x1f1, 0x1d1, 0x1b1, 0x193, 0x175, 0x159, 0x13e, 0x123, 0x10a, 0xf2, 0xdb, 0xc5, 0xb0, 0x9c, 0x89, 0x78, 0x67, 0x58, 0x4a, 0x3d, 0x32, 0x27, 0x1e, 0x16, 0xf, 0xa, 0x6, 0x2, 0x1};
+ 0xfff, 0xffe, 0xffd, 0xff9, 0xff5, 0xff0, 0xfe9, 0xfe1, 0xfd8, 0xfcd, 0xfc2, 0xfb5, 0xfa7, 0xf98, 0xf87, 0xf76, 0xf63, 0xf4f, 0xf3a, 0xf24, 0xf0d, 0xef5, 0xedc, 0xec1, 0xea6, 0xe8a, 0xe6c, 0xe4e, 0xe2e, 0xe0e, 0xded, 0xdca, 0xda7, 0xd83, 0xd5f, 0xd39, 0xd12, 0xceb, 0xcc3, 0xc9a, 0xc71, 0xc47, 0xc1c, 0xbf1, 0xbc5, 0xb98, 0xb6b, 0xb3d, 0xb0f, 0xae0, 0xab1, 0xa82, 0xa52, 0xa22, 0x9f1, 0x9c0, 0x98f, 0x95e, 0x92c, 0x8fa, 0x8c8, 0x896, 0x864, 0x832, 0x800, 0x7cd, 0x79b, 0x769, 0x737, 0x705, 0x6d3, 0x6a1, 0x670, 0x63f, 0x60e, 0x5dd, 0x5ad, 0x57d, 0x54e, 0x51f, 0x4f0, 0x4c2, 0x494, 0x467, 0x43a, 0x40e, 0x3e3, 0x3b8, 0x38e, 0x365, 0x33c, 0x314, 0x2ed, 0x2c6, 0x2a0, 0x27c, 0x258, 0x235, 0x212, 0x1f1, 0x1d1, 0x1b1, 0x193, 0x175, 0x159, 0x13e, 0x123, 0x10a, 0xf2, 0xdb, 0xc5, 0xb0, 0x9c, 0x89, 0x78, 0x67, 0x58, 0x4a, 0x3d, 0x32, 0x27, 0x1e, 0x16, 0xf, 0xa, 0x6, 0x2, 0x1,
+};
#endif // AUDIO_DAC_SAMPLE_WAVEFORM_SINE
#ifdef AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE
-static const dacsample_t dac_buffer_triangle[AUDIO_DAC_BUFFER_SIZE] = {
+static const dacsample_t dac_buffer_triangle[] = {
// 256 values, max 4095
0x0, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0x100, 0x120, 0x140, 0x160, 0x180, 0x1a0, 0x1c0, 0x1e0, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0, 0x400, 0x420, 0x440, 0x460, 0x480, 0x4a0, 0x4c0, 0x4e0, 0x500, 0x520, 0x540, 0x560, 0x580, 0x5a0, 0x5c0, 0x5e0, 0x600, 0x620, 0x640, 0x660, 0x680, 0x6a0, 0x6c0, 0x6e0, 0x700, 0x720, 0x740, 0x760, 0x780, 0x7a0, 0x7c0, 0x7e0, 0x800, 0x81f, 0x83f, 0x85f, 0x87f, 0x89f, 0x8bf, 0x8df, 0x8ff, 0x91f, 0x93f, 0x95f, 0x97f, 0x99f, 0x9bf, 0x9df, 0x9ff, 0xa1f, 0xa3f, 0xa5f, 0xa7f, 0xa9f, 0xabf, 0xadf, 0xaff, 0xb1f, 0xb3f, 0xb5f, 0xb7f, 0xb9f, 0xbbf, 0xbdf, 0xbff, 0xc1f, 0xc3f, 0xc5f, 0xc7f, 0xc9f, 0xcbf, 0xcdf, 0xcff, 0xd1f, 0xd3f, 0xd5f, 0xd7f, 0xd9f, 0xdbf, 0xddf, 0xdff, 0xe1f, 0xe3f, 0xe5f, 0xe7f, 0xe9f, 0xebf, 0xedf, 0xeff, 0xf1f, 0xf3f, 0xf5f, 0xf7f, 0xf9f, 0xfbf, 0xfdf,
- 0xfff, 0xfdf, 0xfbf, 0xf9f, 0xf7f, 0xf5f, 0xf3f, 0xf1f, 0xeff, 0xedf, 0xebf, 0xe9f, 0xe7f, 0xe5f, 0xe3f, 0xe1f, 0xdff, 0xddf, 0xdbf, 0xd9f, 0xd7f, 0xd5f, 0xd3f, 0xd1f, 0xcff, 0xcdf, 0xcbf, 0xc9f, 0xc7f, 0xc5f, 0xc3f, 0xc1f, 0xbff, 0xbdf, 0xbbf, 0xb9f, 0xb7f, 0xb5f, 0xb3f, 0xb1f, 0xaff, 0xadf, 0xabf, 0xa9f, 0xa7f, 0xa5f, 0xa3f, 0xa1f, 0x9ff, 0x9df, 0x9bf, 0x99f, 0x97f, 0x95f, 0x93f, 0x91f, 0x8ff, 0x8df, 0x8bf, 0x89f, 0x87f, 0x85f, 0x83f, 0x81f, 0x800, 0x7e0, 0x7c0, 0x7a0, 0x780, 0x760, 0x740, 0x720, 0x700, 0x6e0, 0x6c0, 0x6a0, 0x680, 0x660, 0x640, 0x620, 0x600, 0x5e0, 0x5c0, 0x5a0, 0x580, 0x560, 0x540, 0x520, 0x500, 0x4e0, 0x4c0, 0x4a0, 0x480, 0x460, 0x440, 0x420, 0x400, 0x3e0, 0x3c0, 0x3a0, 0x380, 0x360, 0x340, 0x320, 0x300, 0x2e0, 0x2c0, 0x2a0, 0x280, 0x260, 0x240, 0x220, 0x200, 0x1e0, 0x1c0, 0x1a0, 0x180, 0x160, 0x140, 0x120, 0x100, 0xe0, 0xc0, 0xa0, 0x80, 0x60, 0x40, 0x20};
+ 0xfff, 0xfdf, 0xfbf, 0xf9f, 0xf7f, 0xf5f, 0xf3f, 0xf1f, 0xeff, 0xedf, 0xebf, 0xe9f, 0xe7f, 0xe5f, 0xe3f, 0xe1f, 0xdff, 0xddf, 0xdbf, 0xd9f, 0xd7f, 0xd5f, 0xd3f, 0xd1f, 0xcff, 0xcdf, 0xcbf, 0xc9f, 0xc7f, 0xc5f, 0xc3f, 0xc1f, 0xbff, 0xbdf, 0xbbf, 0xb9f, 0xb7f, 0xb5f, 0xb3f, 0xb1f, 0xaff, 0xadf, 0xabf, 0xa9f, 0xa7f, 0xa5f, 0xa3f, 0xa1f, 0x9ff, 0x9df, 0x9bf, 0x99f, 0x97f, 0x95f, 0x93f, 0x91f, 0x8ff, 0x8df, 0x8bf, 0x89f, 0x87f, 0x85f, 0x83f, 0x81f, 0x800, 0x7e0, 0x7c0, 0x7a0, 0x780, 0x760, 0x740, 0x720, 0x700, 0x6e0, 0x6c0, 0x6a0, 0x680, 0x660, 0x640, 0x620, 0x600, 0x5e0, 0x5c0, 0x5a0, 0x580, 0x560, 0x540, 0x520, 0x500, 0x4e0, 0x4c0, 0x4a0, 0x480, 0x460, 0x440, 0x420, 0x400, 0x3e0, 0x3c0, 0x3a0, 0x380, 0x360, 0x340, 0x320, 0x300, 0x2e0, 0x2c0, 0x2a0, 0x280, 0x260, 0x240, 0x220, 0x200, 0x1e0, 0x1c0, 0x1a0, 0x180, 0x160, 0x140, 0x120, 0x100, 0xe0, 0xc0, 0xa0, 0x80, 0x60, 0x40, 0x20,
+};
#endif // AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE
#ifdef AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE
-static const dacsample_t dac_buffer_square[AUDIO_DAC_BUFFER_SIZE] = {
- [0 ... AUDIO_DAC_BUFFER_SIZE / 2 - 1] = AUDIO_DAC_OFF_VALUE, // first and
- [AUDIO_DAC_BUFFER_SIZE / 2 ... AUDIO_DAC_BUFFER_SIZE - 1] = AUDIO_DAC_SAMPLE_MAX, // second half
+static const dacsample_t dac_buffer_square[] = {
+ AUDIO_DAC_OFF_VALUE, // first and
+ AUDIO_DAC_SAMPLE_MAX, // second steps
};
#endif // AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE
/*
// four steps: 0, 1/3, 2/3 and 1
-static const dacsample_t dac_buffer_staircase[AUDIO_DAC_BUFFER_SIZE] = {
- [0 ... AUDIO_DAC_BUFFER_SIZE/3 -1 ] = 0,
- [AUDIO_DAC_BUFFER_SIZE / 4 ... AUDIO_DAC_BUFFER_SIZE / 2 -1 ] = AUDIO_DAC_SAMPLE_MAX / 3,
- [AUDIO_DAC_BUFFER_SIZE / 2 ... 3 * AUDIO_DAC_BUFFER_SIZE / 4 -1 ] = 2 * AUDIO_DAC_SAMPLE_MAX / 3,
- [3 * AUDIO_DAC_BUFFER_SIZE / 4 ... AUDIO_DAC_BUFFER_SIZE -1 ] = AUDIO_DAC_SAMPLE_MAX,
+static const dacsample_t dac_buffer_staircase[] = {
+ 0,
+ AUDIO_DAC_SAMPLE_MAX / 3,
+ 2 * AUDIO_DAC_SAMPLE_MAX / 3,
+ AUDIO_DAC_SAMPLE_MAX,
}
*/
#ifdef AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID
-static const dacsample_t dac_buffer_trapezoid[AUDIO_DAC_BUFFER_SIZE] = {0x0, 0x1f, 0x7f, 0xdf, 0x13f, 0x19f, 0x1ff, 0x25f, 0x2bf, 0x31f, 0x37f, 0x3df, 0x43f, 0x49f, 0x4ff, 0x55f, 0x5bf, 0x61f, 0x67f, 0x6df, 0x73f, 0x79f, 0x7ff, 0x85f, 0x8bf, 0x91f, 0x97f, 0x9df, 0xa3f, 0xa9f, 0xaff, 0xb5f, 0xbbf, 0xc1f, 0xc7f, 0xcdf, 0xd3f, 0xd9f, 0xdff, 0xe5f, 0xebf, 0xf1f, 0xf7f, 0xfdf, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
- 0xfff, 0xfdf, 0xf7f, 0xf1f, 0xebf, 0xe5f, 0xdff, 0xd9f, 0xd3f, 0xcdf, 0xc7f, 0xc1f, 0xbbf, 0xb5f, 0xaff, 0xa9f, 0xa3f, 0x9df, 0x97f, 0x91f, 0x8bf, 0x85f, 0x7ff, 0x79f, 0x73f, 0x6df, 0x67f, 0x61f, 0x5bf, 0x55f, 0x4ff, 0x49f, 0x43f, 0x3df, 0x37f, 0x31f, 0x2bf, 0x25f, 0x1ff, 0x19f, 0x13f, 0xdf, 0x7f, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
+static const dacsample_t dac_buffer_trapezoid[] = {
+ 0x0, 0x1f, 0x7f, 0xdf, 0x13f, 0x19f, 0x1ff, 0x25f, 0x2bf, 0x31f, 0x37f, 0x3df, 0x43f, 0x49f, 0x4ff, 0x55f, 0x5bf, 0x61f, 0x67f, 0x6df, 0x73f, 0x79f, 0x7ff, 0x85f, 0x8bf, 0x91f, 0x97f, 0x9df, 0xa3f, 0xa9f, 0xaff, 0xb5f, 0xbbf, 0xc1f, 0xc7f, 0xcdf, 0xd3f, 0xd9f, 0xdff, 0xe5f, 0xebf, 0xf1f, 0xf7f, 0xfdf, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff, 0xfff,
+ 0xfff, 0xfdf, 0xf7f, 0xf1f, 0xebf, 0xe5f, 0xdff, 0xd9f, 0xd3f, 0xcdf, 0xc7f, 0xc1f, 0xbbf, 0xb5f, 0xaff, 0xa9f, 0xa3f, 0x9df, 0x97f, 0x91f, 0x8bf, 0x85f, 0x7ff, 0x79f, 0x73f, 0x6df, 0x67f, 0x61f, 0x5bf, 0x55f, 0x4ff, 0x49f, 0x43f, 0x3df, 0x37f, 0x31f, 0x2bf, 0x25f, 0x1ff, 0x19f, 0x13f, 0xdf, 0x7f, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+};
#endif // AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID
static dacsample_t dac_buffer[AUDIO_DAC_BUFFER_SIZE];
@@ -124,20 +128,30 @@ __attribute__((weak)) uint16_t dac_value_generate(void) {
uint_fast16_t value = 0;
float frequency = 0.0f;
+#if defined(AUDIO_DAC_SAMPLE_WAVEFORM_SINE)
+ const size_t wavetable_length = ARRAY_SIZE(dac_buffer_sine);
+#elif defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE)
+ const size_t wavetable_length = ARRAY_SIZE(dac_buffer_triangle);
+#elif defined(AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID)
+ const size_t wavetable_length = ARRAY_SIZE(dac_buffer_trapezoid);
+#elif defined(AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE)
+ const size_t wavetable_length = ARRAY_SIZE(dac_buffer_square);
+#endif
+
for (size_t i = 0; i < active_tones_snapshot_length; i++) {
/* Note: a user implementation does not have to rely on the active_tones_snapshot, but
* could directly query the active frequencies through audio_get_processed_frequency */
frequency = active_tones_snapshot[i];
float new_dac_if = dac_if[i];
- new_dac_if += frequency * ((float)AUDIO_DAC_BUFFER_SIZE / AUDIO_DAC_SAMPLE_RATE * 2.0f / 3.0f);
+ new_dac_if += frequency * ((float)wavetable_length / AUDIO_DAC_SAMPLE_RATE * 2.0f / 3.0f);
/*Note: the 2/3 are necessary to get the correct frequencies on the
* DAC output (as measured with an oscilloscope), since the gpt
* timer runs with 3*AUDIO_DAC_SAMPLE_RATE; and the DAC callback
* is called twice per conversion.*/
- while (new_dac_if >= AUDIO_DAC_BUFFER_SIZE)
- new_dac_if -= AUDIO_DAC_BUFFER_SIZE;
+ while (new_dac_if >= wavetable_length)
+ new_dac_if -= wavetable_length;
dac_if[i] = new_dac_if;
// Wavetable generation/lookup
diff --git a/platforms/chibios/drivers/audio_pwm_hardware.c b/platforms/chibios/drivers/audio_pwm_hardware.c
index 40d891326f..21b5c6892c 100644
--- a/platforms/chibios/drivers/audio_pwm_hardware.c
+++ b/platforms/chibios/drivers/audio_pwm_hardware.c
@@ -22,6 +22,12 @@
# define AUDIO_PWM_COUNTER_FREQUENCY 100000
#endif
+#ifndef AUDIO_PWM_COMPLEMENTARY_OUTPUT
+# define AUDIO_PWM_OUTPUT_MODE PWM_OUTPUT_ACTIVE_HIGH
+#else
+# define AUDIO_PWM_OUTPUT_MODE PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH
+#endif
+
extern bool playing_note;
extern bool playing_melody;
extern uint8_t note_timbre;
@@ -29,7 +35,7 @@ extern uint8_t note_timbre;
static PWMConfig pwmCFG = {.frequency = AUDIO_PWM_COUNTER_FREQUENCY, /* PWM clock frequency */
.period = 2,
.callback = NULL,
- .channels = {[(AUDIO_PWM_CHANNEL - 1)] = {.mode = PWM_OUTPUT_ACTIVE_HIGH, .callback = NULL}}};
+ .channels = {[(AUDIO_PWM_CHANNEL - 1)] = {.mode = AUDIO_PWM_OUTPUT_MODE, .callback = NULL}}};
static float channel_1_frequency = 0.0f;
diff --git a/platforms/chibios/drivers/i2c_master.c b/platforms/chibios/drivers/i2c_master.c
index 7c49f9d005..ad11d850dd 100644
--- a/platforms/chibios/drivers/i2c_master.c
+++ b/platforms/chibios/drivers/i2c_master.c
@@ -1,5 +1,6 @@
/* Copyright 2018 Jack Humbert
* Copyright 2018 Yiancar
+ * Copyright 2023 customMK
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -90,8 +91,6 @@
# endif
#endif
-static uint8_t i2c_address;
-
static const I2CConfig i2cconfig = {
#if defined(USE_I2CV1_CONTRIB)
I2C1_CLOCK_SPEED,
@@ -125,7 +124,7 @@ static i2c_status_t i2c_epilogue(const msg_t status) {
// From ChibiOS HAL: "After a timeout the driver must be stopped and
// restarted because the bus is in an uncertain state." We also issue that
// hard stop in case of any error.
- i2c_stop();
+ i2cStop(&I2C_DRIVER);
return status == MSG_TIMEOUT ? I2C_STATUS_TIMEOUT : I2C_STATUS_ERROR;
}
@@ -150,28 +149,19 @@ __attribute__((weak)) void i2c_init(void) {
}
}
-i2c_status_t i2c_start(uint8_t address) {
- i2c_address = address;
- i2cStart(&I2C_DRIVER, &i2cconfig);
- return I2C_STATUS_SUCCESS;
-}
-
i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout) {
- i2c_address = address;
i2cStart(&I2C_DRIVER, &i2cconfig);
- msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, 0, 0, TIME_MS2I(timeout));
+ msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (address >> 1), data, length, 0, 0, TIME_MS2I(timeout));
return i2c_epilogue(status);
}
i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) {
- i2c_address = address;
i2cStart(&I2C_DRIVER, &i2cconfig);
- msg_t status = i2cMasterReceiveTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, TIME_MS2I(timeout));
+ msg_t status = i2cMasterReceiveTimeout(&I2C_DRIVER, (address >> 1), data, length, TIME_MS2I(timeout));
return i2c_epilogue(status);
}
-i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) {
- i2c_address = devaddr;
+i2c_status_t i2c_write_register(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) {
i2cStart(&I2C_DRIVER, &i2cconfig);
uint8_t complete_packet[length + 1];
@@ -180,12 +170,11 @@ i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data,
}
complete_packet[0] = regaddr;
- msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), complete_packet, length + 1, 0, 0, TIME_MS2I(timeout));
+ msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (devaddr >> 1), complete_packet, length + 1, 0, 0, TIME_MS2I(timeout));
return i2c_epilogue(status);
}
-i2c_status_t i2c_writeReg16(uint8_t devaddr, uint16_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) {
- i2c_address = devaddr;
+i2c_status_t i2c_write_register16(uint8_t devaddr, uint16_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) {
i2cStart(&I2C_DRIVER, &i2cconfig);
uint8_t complete_packet[length + 2];
@@ -195,25 +184,27 @@ i2c_status_t i2c_writeReg16(uint8_t devaddr, uint16_t regaddr, const uint8_t* da
complete_packet[0] = regaddr >> 8;
complete_packet[1] = regaddr & 0xFF;
- msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), complete_packet, length + 2, 0, 0, TIME_MS2I(timeout));
+ msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (devaddr >> 1), complete_packet, length + 2, 0, 0, TIME_MS2I(timeout));
return i2c_epilogue(status);
}
-i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) {
- i2c_address = devaddr;
+i2c_status_t i2c_read_register(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) {
i2cStart(&I2C_DRIVER, &i2cconfig);
- msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), &regaddr, 1, data, length, TIME_MS2I(timeout));
+ msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (devaddr >> 1), &regaddr, 1, data, length, TIME_MS2I(timeout));
return i2c_epilogue(status);
}
-i2c_status_t i2c_readReg16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) {
- i2c_address = devaddr;
+i2c_status_t i2c_read_register16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) {
i2cStart(&I2C_DRIVER, &i2cconfig);
uint8_t register_packet[2] = {regaddr >> 8, regaddr & 0xFF};
- msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), register_packet, 2, data, length, TIME_MS2I(timeout));
+ msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (devaddr >> 1), register_packet, 2, data, length, TIME_MS2I(timeout));
return i2c_epilogue(status);
}
-void i2c_stop(void) {
- i2cStop(&I2C_DRIVER);
-}
+__attribute__((weak)) i2c_status_t i2c_ping_address(uint8_t address, uint16_t timeout) {
+ // ChibiOS does not provide low level enough control to check for an ack.
+ // Best effort instead tries reading register 0 which will either succeed or timeout.
+ // This approach may produce false negative results for I2C devices that do not respond to a register 0 read request.
+ uint8_t data = 0;
+ return i2c_readReg(address, 0, &data, sizeof(data), timeout);
+} \ No newline at end of file
diff --git a/platforms/chibios/drivers/i2c_master.h b/platforms/chibios/drivers/i2c_master.h
index deee7ecc08..132ffd14c0 100644
--- a/platforms/chibios/drivers/i2c_master.h
+++ b/platforms/chibios/drivers/i2c_master.h
@@ -26,6 +26,13 @@
#include <stdint.h>
+// ### DEPRECATED - DO NOT USE ###
+#define i2c_writeReg(devaddr, regaddr, data, length, timeout) i2c_write_register(devaddr, regaddr, data, length, timeout)
+#define i2c_writeReg16(devaddr, regaddr, data, length, timeout) i2c_write_register16(devaddr, regaddr, data, length, timeout)
+#define i2c_readReg(devaddr, regaddr, data, length, timeout) i2c_read_register(devaddr, regaddr, data, length, timeout)
+#define i2c_readReg16(devaddr, regaddr, data, length, timeout) i2c_read_register16(devaddr, regaddr, data, length, timeout)
+// ###############################
+
typedef int16_t i2c_status_t;
#define I2C_STATUS_SUCCESS (0)
@@ -33,11 +40,10 @@ typedef int16_t i2c_status_t;
#define I2C_STATUS_TIMEOUT (-2)
void i2c_init(void);
-i2c_status_t i2c_start(uint8_t address);
i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout);
i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
-i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
-i2c_status_t i2c_writeReg16(uint8_t devaddr, uint16_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
-i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
-i2c_status_t i2c_readReg16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
-void i2c_stop(void);
+i2c_status_t i2c_write_register(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
+i2c_status_t i2c_write_register16(uint8_t devaddr, uint16_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
+i2c_status_t i2c_read_register(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
+i2c_status_t i2c_read_register16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
+i2c_status_t i2c_ping_address(uint8_t address, uint16_t timeout);
diff --git a/platforms/chibios/drivers/serial.c b/platforms/chibios/drivers/serial.c
index f199716a2b..fa8481d2dc 100644
--- a/platforms/chibios/drivers/serial.c
+++ b/platforms/chibios/drivers/serial.c
@@ -62,25 +62,25 @@ inline static void serial_delay_blip(void) {
wait_us(1);
}
inline static void serial_output(void) {
- setPinOutput(SOFT_SERIAL_PIN);
+ gpio_set_pin_output(SOFT_SERIAL_PIN);
}
inline static void serial_input(void) {
- setPinInputHigh(SOFT_SERIAL_PIN);
+ gpio_set_pin_input_high(SOFT_SERIAL_PIN);
}
inline static bool serial_read_pin(void) {
- return !!readPin(SOFT_SERIAL_PIN);
+ return !!gpio_read_pin(SOFT_SERIAL_PIN);
}
inline static void serial_low(void) {
- writePinLow(SOFT_SERIAL_PIN);
+ gpio_write_pin_low(SOFT_SERIAL_PIN);
}
inline static void serial_high(void) {
- writePinHigh(SOFT_SERIAL_PIN);
+ gpio_write_pin_high(SOFT_SERIAL_PIN);
}
void interrupt_handler(void *arg);
// Use thread + palWaitLineTimeout instead of palSetLineCallback
-// - Methods like setPinOutput and palEnableLineEvent/palDisableLineEvent
+// - Methods like gpio_set_pin_output and palEnableLineEvent/palDisableLineEvent
// cause the interrupt to lock up, which would limit to only receiving data...
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {
diff --git a/platforms/chibios/drivers/spi_master.c b/platforms/chibios/drivers/spi_master.c
index 481a2e422a..57fc53d49f 100644
--- a/platforms/chibios/drivers/spi_master.c
+++ b/platforms/chibios/drivers/spi_master.c
@@ -32,12 +32,12 @@ __attribute__((weak)) void spi_init(void) {
is_initialised = true;
// Try releasing special pins for a short time
- setPinInput(SPI_SCK_PIN);
+ gpio_set_pin_input(SPI_SCK_PIN);
if (SPI_MOSI_PIN != NO_PIN) {
- setPinInput(SPI_MOSI_PIN);
+ gpio_set_pin_input(SPI_MOSI_PIN);
}
if (SPI_MISO_PIN != NO_PIN) {
- setPinInput(SPI_MISO_PIN);
+ gpio_set_pin_input(SPI_MISO_PIN);
}
chThdSleepMilliseconds(10);
@@ -271,10 +271,10 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
#if SPI_SELECT_MODE == SPI_SELECT_MODE_PAD
spiConfig.ssport = PAL_PORT(slavePin);
spiConfig.sspad = PAL_PAD(slavePin);
- setPinOutput(slavePin);
+ gpio_set_pin_output(slavePin);
#elif SPI_SELECT_MODE == SPI_SELECT_MODE_NONE
if (slavePin != NO_PIN) {
- setPinOutput(slavePin);
+ gpio_set_pin_output(slavePin);
}
#else
# error "Unsupported SPI_SELECT_MODE"
@@ -284,7 +284,7 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
spiSelect(&SPI_DRIVER);
#if SPI_SELECT_MODE == SPI_SELECT_MODE_NONE
if (slavePin != NO_PIN) {
- writePinLow(slavePin);
+ gpio_write_pin_low(slavePin);
}
#endif
@@ -319,7 +319,7 @@ void spi_stop(void) {
if (spiStarted) {
#if SPI_SELECT_MODE == SPI_SELECT_MODE_NONE
if (currentSlavePin != NO_PIN) {
- writePinHigh(currentSlavePin);
+ gpio_write_pin_high(currentSlavePin);
}
#endif
spiUnselect(&SPI_DRIVER);
diff --git a/platforms/chibios/drivers/uart.c b/platforms/chibios/drivers/uart.c
deleted file mode 100644
index 39a59dd445..0000000000
--- a/platforms/chibios/drivers/uart.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright 2021
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-#include "uart.h"
-
-#if defined(MCU_KINETIS)
-static SerialConfig serialConfig = {SERIAL_DEFAULT_BITRATE};
-#elif defined(WB32F3G71xx) || defined(WB32FQ95xx)
-static SerialConfig serialConfig = {SERIAL_DEFAULT_BITRATE, SD1_WRDLEN, SD1_STPBIT, SD1_PARITY, SD1_ATFLCT};
-#else
-static SerialConfig serialConfig = {SERIAL_DEFAULT_BITRATE, SD1_CR1, SD1_CR2, SD1_CR3};
-#endif
-
-void uart_init(uint32_t baud) {
- static bool is_initialised = false;
-
- if (!is_initialised) {
- is_initialised = true;
-
-#if defined(MCU_KINETIS)
- serialConfig.sc_speed = baud;
-#else
- serialConfig.speed = baud;
-#endif
-
-#if defined(USE_GPIOV1)
- palSetLineMode(SD1_TX_PIN, SD1_TX_PAL_MODE);
- palSetLineMode(SD1_RX_PIN, SD1_RX_PAL_MODE);
-#else
- palSetLineMode(SD1_TX_PIN, PAL_MODE_ALTERNATE(SD1_TX_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST);
- palSetLineMode(SD1_RX_PIN, PAL_MODE_ALTERNATE(SD1_RX_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST);
-#endif
- sdStart(&SERIAL_DRIVER, &serialConfig);
- }
-}
-
-void uart_write(uint8_t data) {
- sdPut(&SERIAL_DRIVER, data);
-}
-
-uint8_t uart_read(void) {
- msg_t res = sdGet(&SERIAL_DRIVER);
-
- return (uint8_t)res;
-}
-
-void uart_transmit(const uint8_t *data, uint16_t length) {
- sdWrite(&SERIAL_DRIVER, data, length);
-}
-
-void uart_receive(uint8_t *data, uint16_t length) {
- sdRead(&SERIAL_DRIVER, data, length);
-}
-
-bool uart_available(void) {
- return !sdGetWouldBlock(&SERIAL_DRIVER);
-}
diff --git a/platforms/chibios/drivers/uart.h b/platforms/chibios/drivers/uart.h
index 16983072ce..c1945575f1 100644
--- a/platforms/chibios/drivers/uart.h
+++ b/platforms/chibios/drivers/uart.h
@@ -1,18 +1,7 @@
-/* Copyright 2021
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
+// Copyright 2024 Stefan Kerkmann
+// Copyright 2021 QMK
+// Copyright 2024 Stefan Kerkmann
+// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
@@ -24,93 +13,188 @@
#include "gpio.h"
#include "chibios_config.h"
-#ifndef SERIAL_DRIVER
-# define SERIAL_DRIVER SD1
+// ======== DEPRECATED DEFINES - DO NOT USE ========
+#ifdef SERIAL_DRIVER
+# define UART_DRIVER SERIAL_DRIVER
+#endif
+#ifdef SD1_TX_PIN
+# define UART_TX_PIN SD1_TX_PIN
+#endif
+#ifdef SD1_RX_PIN
+# define UART_RX_PIN SD1_RX_PIN
+#endif
+#ifdef SD1_CTS_PIN
+# define UART_CTS_PIN SD1_CTS_PIN
+#endif
+#ifdef SD1_RTS_PIN
+# define UART_RTS_PIN SD1_RTS_PIN
+#endif
+#ifdef SD1_TX_PAL_MODE
+# define UART_TX_PAL_MODE SD1_TX_PAL_MODE
+#endif
+#ifdef SD1_RX_PAL_MODE
+# define UART_RX_PAL_MODE SD1_RX_PAL_MODE
+#endif
+#ifdef SD1_CTS_PAL_MODE
+# define UART_RTS_PAL_MODE SD1_CTS_PAL_MODE
+#endif
+#ifdef SD1_RTS_PAL_MODE
+# define UART_TX_PAL_MODE SD1_RTS_PAL_MODE
+#endif
+#ifdef SD1_CR1
+# define UART_CR1 SD1_CR1
+#endif
+#ifdef SD1_CR2
+# define UART_CR2 SD1_CR2
+#endif
+#ifdef SD1_CR3
+# define UART_CR3 SD1_CR3
+#endif
+#ifdef SD1_WRDLEN
+# define UART_WRDLEN SD1_WRDLEN
+#endif
+#ifdef SD1_STPBIT
+# define UART_STPBIT SD1_STPBIT
+#endif
+#ifdef SD1_PARITY
+# define UART_PARITY SD1_PARITY
+#endif
+#ifdef SD1_ATFLCT
+# define UART_ATFLCT SD1_ATFLCT
+#endif
+// ========
+
+#ifndef UART_DRIVER
+# if (HAL_USE_SERIAL == TRUE)
+# define UART_DRIVER SD1
+# elif (HAL_USE_SIO == TRUE)
+# define UART_DRIVER SIOD1
+# endif
#endif
-#ifndef SD1_TX_PIN
-# define SD1_TX_PIN A9
+#ifndef UART_TX_PIN
+# define UART_TX_PIN A9
#endif
-#ifndef SD1_RX_PIN
-# define SD1_RX_PIN A10
+#ifndef UART_RX_PIN
+# define UART_RX_PIN A10
#endif
-#ifndef SD1_CTS_PIN
-# define SD1_CTS_PIN A11
+#ifndef UART_CTS_PIN
+# define UART_CTS_PIN A11
#endif
-#ifndef SD1_RTS_PIN
-# define SD1_RTS_PIN A12
+#ifndef UART_RTS_PIN
+# define UART_RTS_PIN A12
#endif
#ifdef USE_GPIOV1
-# ifndef SD1_TX_PAL_MODE
-# define SD1_TX_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL
+# ifndef UART_TX_PAL_MODE
+# define UART_TX_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL
# endif
-# ifndef SD1_RX_PAL_MODE
-# define SD1_RX_PAL_MODE PAL_MODE_INPUT
+# ifndef UART_RX_PAL_MODE
+# define UART_RX_PAL_MODE PAL_MODE_INPUT
# endif
-# ifndef SD1_CTS_PAL_MODE
-# define SD1_CTS_PAL_MODE PAL_MODE_INPUT
+# ifndef UART_CTS_PAL_MODE
+# define UART_CTS_PAL_MODE PAL_MODE_INPUT
# endif
-# ifndef SD1_RTS_PAL_MODE
-# define SD1_RTS_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL
+# ifndef UART_RTS_PAL_MODE
+# define UART_RTS_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL
# endif
#else
-# ifndef SD1_TX_PAL_MODE
-# define SD1_TX_PAL_MODE 7
+# ifndef UART_TX_PAL_MODE
+# define UART_TX_PAL_MODE 7
# endif
-# ifndef SD1_RX_PAL_MODE
-# define SD1_RX_PAL_MODE 7
+# ifndef UART_RX_PAL_MODE
+# define UART_RX_PAL_MODE 7
# endif
-# ifndef SD1_CTS_PAL_MODE
-# define SD1_CTS_PAL_MODE 7
+# ifndef UART_CTS_PAL_MODE
+# define UART_CTS_PAL_MODE 7
# endif
-# ifndef SD1_RTS_PAL_MODE
-# define SD1_RTS_PAL_MODE 7
+# ifndef UART_RTS_PAL_MODE
+# define UART_RTS_PAL_MODE 7
# endif
#endif
-#ifndef SD1_CR1
-# define SD1_CR1 0
+#ifndef UART_CR1
+# define UART_CR1 0
#endif
-#ifndef SD1_CR2
-# define SD1_CR2 0
+#ifndef UART_CR2
+# define UART_CR2 0
#endif
-#ifndef SD1_CR3
-# define SD1_CR3 0
+#ifndef UART_CR3
+# define UART_CR3 0
#endif
-#ifndef SD1_WRDLEN
-# define SD1_WRDLEN 3
+#ifndef UART_WRDLEN
+# define UART_WRDLEN 3
#endif
-#ifndef SD1_STPBIT
-# define SD1_STPBIT 0
+#ifndef UART_STPBIT
+# define UART_STPBIT 0
#endif
-#ifndef SD1_PARITY
-# define SD1_PARITY 0
+#ifndef UART_PARITY
+# define UART_PARITY 0
#endif
-#ifndef SD1_ATFLCT
-# define SD1_ATFLCT 0
+#ifndef UART_ATFLCT
+# define UART_ATFLCT 0
#endif
+/**
+ * @brief Initialize the UART driver. This function must be called only once,
+ * before any of the below functions can be called.
+ *
+ * @param baud The baud rate to transmit and receive at. This may depend on the
+ * device you are communicating with. Common values are 1200, 2400, 4800, 9600,
+ * 19200, 38400, 57600, and 115200.
+ */
void uart_init(uint32_t baud);
+/**
+ * @brief Transmit a single byte.
+ *
+ * @param data The byte to transmit.
+ */
void uart_write(uint8_t data);
+/**
+ * @brief Receive a single byte.
+ *
+ * @return uint8_t The byte read from the receive buffer. This function will
+ * block if the buffer is empty (ie. no data to read).
+ */
uint8_t uart_read(void);
+/**
+ * @brief Transmit multiple bytes.
+ *
+ * @param data A pointer to the data to write from.
+ * @param length The number of bytes to write. Take care not to overrun the
+ * length of `data`.
+ */
void uart_transmit(const uint8_t *data, uint16_t length);
+/**
+ * @brief Receive multiple bytes.
+ *
+ * @param data A pointer to the buffer to read into.
+ * @param length The number of bytes to read. Take care not to overrun the
+ * length of `data`.
+ */
void uart_receive(uint8_t *data, uint16_t length);
+/**
+ * @brief Return whether the receive buffer contains data. Call this function
+ * to determine if `uart_read()` will return data immediately.
+ *
+ * @return true If there is data available to read.
+ * @return false If there is no data available to read.
+ */
bool uart_available(void);
diff --git a/platforms/chibios/drivers/uart_serial.c b/platforms/chibios/drivers/uart_serial.c
new file mode 100644
index 0000000000..6aff4eae47
--- /dev/null
+++ b/platforms/chibios/drivers/uart_serial.c
@@ -0,0 +1,65 @@
+// Copyright 2024 Stefan Kerkmann (@KarlK90)
+// Copyright 2021 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "uart.h"
+
+#if defined(MCU_KINETIS)
+static SerialConfig serialConfig = {SERIAL_DEFAULT_BITRATE};
+#elif defined(WB32F3G71xx) || defined(WB32FQ95xx)
+static SerialConfig serialConfig = {
+ SERIAL_DEFAULT_BITRATE, UART_WRDLEN, UART_STPBIT, UART_PARITY, UART_ATFLCT,
+};
+#else
+static SerialConfig serialConfig = {
+ SERIAL_DEFAULT_BITRATE,
+ UART_CR1,
+ UART_CR2,
+ UART_CR3,
+};
+#endif
+
+void uart_init(uint32_t baud) {
+ static bool is_initialised = false;
+
+ if (is_initialised) {
+ return;
+ }
+ is_initialised = true;
+
+#if defined(MCU_KINETIS)
+ serialConfig.sc_speed = baud;
+#else
+ serialConfig.speed = baud;
+#endif
+
+#if defined(USE_GPIOV1)
+ palSetLineMode(UART_TX_PIN, UART_TX_PAL_MODE);
+ palSetLineMode(UART_RX_PIN, UART_RX_PAL_MODE);
+#else
+ palSetLineMode(UART_TX_PIN, PAL_MODE_ALTERNATE(UART_TX_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST);
+ palSetLineMode(UART_RX_PIN, PAL_MODE_ALTERNATE(UART_RX_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST);
+#endif
+
+ sdStart(&UART_DRIVER, &serialConfig);
+}
+
+void uart_write(uint8_t data) {
+ sdPut(&UART_DRIVER, data);
+}
+
+uint8_t uart_read(void) {
+ return (uint8_t)sdGet(&UART_DRIVER);
+}
+
+void uart_transmit(const uint8_t *data, uint16_t length) {
+ sdWrite(&UART_DRIVER, data, length);
+}
+
+void uart_receive(uint8_t *data, uint16_t length) {
+ sdRead(&UART_DRIVER, data, length);
+}
+
+bool uart_available(void) {
+ return !sdGetWouldBlock(&UART_DRIVER);
+}
diff --git a/platforms/chibios/drivers/uart_sio.c b/platforms/chibios/drivers/uart_sio.c
new file mode 100644
index 0000000000..ebf51ae5a8
--- /dev/null
+++ b/platforms/chibios/drivers/uart_sio.c
@@ -0,0 +1,77 @@
+// Copyright 2024 Stefan Kerkmann (@KarlK90)
+// Copyright 2021 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "uart.h"
+
+#if defined(MCU_RP)
+// 38400 baud, 8 data bits, 1 stop bit, no parity, no flow control
+static SIOConfig sioConfig = {
+ .baud = SIO_DEFAULT_BITRATE,
+ .UARTLCR_H = (UART_UARTLCR_H_WLEN_8BITS | UART_UARTLCR_H_FEN),
+ .UARTCR = 0U,
+ .UARTIFLS = (UART_UARTIFLS_RXIFLSEL_1_8F | UART_UARTIFLS_TXIFLSEL_1_8E),
+ .UARTDMACR = 0U,
+};
+#else
+static SIOConfig sioConfig = {
+ .baud = SIO_DEFAULT_BITRATE,
+# if defined(MCU_STM32) && defined(CHIBIOS_HAL_USARTv3)
+ .presc = USART_PRESC1,
+# endif
+ .cr1 = UART_CR1,
+ .cr2 = UART_CR2,
+ .cr3 = UART_CR3,
+};
+#endif
+
+void uart_init(uint32_t baud) {
+ static bool is_initialised = false;
+
+ if (is_initialised) {
+ return;
+ }
+ is_initialised = true;
+
+ sioConfig.baud = baud;
+
+#if defined(USE_GPIOV1)
+ palSetLineMode(UART_TX_PIN, UART_TX_PAL_MODE);
+ palSetLineMode(UART_RX_PIN, UART_RX_PAL_MODE);
+#else
+ palSetLineMode(UART_TX_PIN, PAL_MODE_ALTERNATE(UART_TX_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST);
+ palSetLineMode(UART_RX_PIN, PAL_MODE_ALTERNATE(UART_RX_PAL_MODE) | PAL_OUTPUT_TYPE_PUSHPULL | PAL_OUTPUT_SPEED_HIGHEST);
+#endif
+
+ sioStart(&UART_DRIVER, &sioConfig);
+}
+
+void uart_write(uint8_t data) {
+ chnPutTimeout(&UART_DRIVER, data, TIME_INFINITE);
+}
+
+uint8_t uart_read(void) {
+ msg_t result = chnGetTimeout(&UART_DRIVER, TIME_INFINITE);
+
+ if (sioHasRXErrorsX(&UART_DRIVER)) {
+ sioGetAndClearErrors(&UART_DRIVER);
+ }
+
+ return (uint8_t)result;
+}
+
+void uart_transmit(const uint8_t *data, uint16_t length) {
+ chnWrite(&UART_DRIVER, data, length);
+}
+
+void uart_receive(uint8_t *data, uint16_t length) {
+ chnRead(&UART_DRIVER, data, length);
+
+ if (sioHasRXErrorsX(&UART_DRIVER)) {
+ sioGetAndClearErrors(&UART_DRIVER);
+ }
+}
+
+bool uart_available() {
+ return !sioIsRXEmptyX(&UART_DRIVER);
+}
diff --git a/platforms/chibios/drivers/ws2812_bitbang.c b/platforms/chibios/drivers/ws2812_bitbang.c
index 883a845d88..1ed87c4381 100644
--- a/platforms/chibios/drivers/ws2812_bitbang.c
+++ b/platforms/chibios/drivers/ws2812_bitbang.c
@@ -3,18 +3,23 @@
#include "gpio.h"
#include "chibios_config.h"
+// DEPRECATED - DO NOT USE
+#if defined(NOP_FUDGE)
+# define WS2812_BITBANG_NOP_FUDGE NOP_FUDGE
+#endif
+
/* Adapted from https://github.com/bigjosh/SimpleNeoPixelDemo/ */
-#ifndef NOP_FUDGE
+#ifndef WS2812_BITBANG_NOP_FUDGE
# if defined(STM32F0XX) || defined(STM32F1XX) || defined(GD32VF103) || defined(STM32F3XX) || defined(STM32F4XX) || defined(STM32L0XX) || defined(WB32F3G71xx) || defined(WB32FQ95xx)
-# define NOP_FUDGE 0.4
+# define WS2812_BITBANG_NOP_FUDGE 0.4
# else
# if defined(RP2040)
# error "Please use `vendor` WS2812 driver for RP2040"
# else
-# error "NOP_FUDGE configuration required"
+# error "WS2812_BITBANG_NOP_FUDGE configuration required"
# endif
-# define NOP_FUDGE 1 // this just pleases the compile so the above error is easier to spot
+# define WS2812_BITBANG_NOP_FUDGE 1 // this just pleases the compile so the above error is easier to spot
# endif
#endif
@@ -33,7 +38,7 @@
#endif
#define NUMBER_NOPS 6
-#define CYCLES_PER_SEC (CPU_CLOCK / NUMBER_NOPS * NOP_FUDGE)
+#define CYCLES_PER_SEC (CPU_CLOCK / NUMBER_NOPS * WS2812_BITBANG_NOP_FUDGE)
#define NS_PER_SEC (1000000000L) // Note that this has to be SIGNED since we want to be able to check for negative values of derivatives
#define NS_PER_CYCLE (NS_PER_SEC / CYCLES_PER_SEC)
#define NS_TO_CYCLES(n) ((n) / NS_PER_CYCLE)
@@ -57,15 +62,15 @@ void sendByte(uint8_t byte) {
// using something like wait_ns(is_one ? T1L : T0L) here throws off timings
if (is_one) {
// 1
- writePinHigh(WS2812_DI_PIN);
+ gpio_write_pin_high(WS2812_DI_PIN);
wait_ns(WS2812_T1H);
- writePinLow(WS2812_DI_PIN);
+ gpio_write_pin_low(WS2812_DI_PIN);
wait_ns(WS2812_T1L);
} else {
// 0
- writePinHigh(WS2812_DI_PIN);
+ gpio_write_pin_high(WS2812_DI_PIN);
wait_ns(WS2812_T0H);
- writePinLow(WS2812_DI_PIN);
+ gpio_write_pin_low(WS2812_DI_PIN);
wait_ns(WS2812_T0L);
}
}
diff --git a/platforms/chibios/drivers/ws2812_pwm.c b/platforms/chibios/drivers/ws2812_pwm.c
index 440687bd72..6bba22767f 100644
--- a/platforms/chibios/drivers/ws2812_pwm.c
+++ b/platforms/chibios/drivers/ws2812_pwm.c
@@ -48,9 +48,6 @@
#ifndef WS2812_PWM_COMPLEMENTARY_OUTPUT
# define WS2812_PWM_OUTPUT_MODE PWM_OUTPUT_ACTIVE_HIGH
#else
-# if !STM32_PWM_USE_ADVANCED
-# error "WS2812_PWM_COMPLEMENTARY_OUTPUT requires STM32_PWM_USE_ADVANCED == TRUE"
-# endif
# define WS2812_PWM_OUTPUT_MODE PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH
#endif