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/ws2812_bitbang.c8
-rw-r--r--platforms/chibios/drivers/ws2812_pwm.c3
10 files changed, 217 insertions, 86 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/ws2812_bitbang.c b/platforms/chibios/drivers/ws2812_bitbang.c
index 883a845d88..593377068b 100644
--- a/platforms/chibios/drivers/ws2812_bitbang.c
+++ b/platforms/chibios/drivers/ws2812_bitbang.c
@@ -57,15 +57,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