summaryrefslogtreecommitdiff
path: root/drivers/chibios
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/chibios')
-rw-r--r--drivers/chibios/analog.c57
-rw-r--r--drivers/chibios/ws2812_pwm.c11
-rw-r--r--drivers/chibios/ws2812_spi.c45
3 files changed, 100 insertions, 13 deletions
diff --git a/drivers/chibios/analog.c b/drivers/chibios/analog.c
index 2b3872afbb..b1081623d3 100644
--- a/drivers/chibios/analog.c
+++ b/drivers/chibios/analog.c
@@ -101,7 +101,11 @@
// Options are 12, 10, 8, and 6 bit.
#ifndef ADC_RESOLUTION
-# define ADC_RESOLUTION ADC_CFGR1_RES_10BIT
+# ifdef ADC_CFGR_RES_10BITS // ADCv3, ADCv4
+# define ADC_RESOLUTION ADC_CFGR_RES_10BITS
+# else // ADCv1, ADCv5, or the bodge for ADCv2 above
+# define ADC_RESOLUTION ADC_CFGR1_RES_10BIT
+# endif
#endif
static ADCConfig adcCfg = {};
@@ -161,8 +165,8 @@ __attribute__((weak)) adc_mux pinToMux(pin_t pin) {
case B0: return TO_MUX( ADC_CHANNEL_IN12, 2 );
case B1: return TO_MUX( ADC_CHANNEL_IN1, 2 );
case B2: return TO_MUX( ADC_CHANNEL_IN12, 1 );
- case B12: return TO_MUX( ADC_CHANNEL_IN2, 3 );
- case B13: return TO_MUX( ADC_CHANNEL_IN3, 3 );
+ case B12: return TO_MUX( ADC_CHANNEL_IN3, 3 );
+ case B13: return TO_MUX( ADC_CHANNEL_IN5, 2 );
case B14: return TO_MUX( ADC_CHANNEL_IN4, 3 );
case B15: return TO_MUX( ADC_CHANNEL_IN5, 3 );
case C0: return TO_MUX( ADC_CHANNEL_IN6, 0 ); // Can also be ADC2
@@ -189,11 +193,52 @@ __attribute__((weak)) adc_mux pinToMux(pin_t pin) {
case E15: return TO_MUX( ADC_CHANNEL_IN2, 3 );
case F2: return TO_MUX( ADC_CHANNEL_IN10, 0 ); // Can also be ADC2
case F4: return TO_MUX( ADC_CHANNEL_IN5, 0 );
-#elif defined(STM32F4XX) // TODO: add all pins
+#elif defined(STM32F4XX)
case A0: return TO_MUX( ADC_CHANNEL_IN0, 0 );
- //case A1: return TO_MUX( ADC_CHANNEL_IN1, 0 );
-#elif defined(STM32F1XX) // TODO: add all pins
+ case A1: return TO_MUX( ADC_CHANNEL_IN1, 0 );
+ case A2: return TO_MUX( ADC_CHANNEL_IN2, 0 );
+ case A3: return TO_MUX( ADC_CHANNEL_IN3, 0 );
+ case A4: return TO_MUX( ADC_CHANNEL_IN4, 0 );
+ case A5: return TO_MUX( ADC_CHANNEL_IN5, 0 );
+ case A6: return TO_MUX( ADC_CHANNEL_IN6, 0 );
+ case A7: return TO_MUX( ADC_CHANNEL_IN7, 0 );
+ case B0: return TO_MUX( ADC_CHANNEL_IN8, 0 );
+ case B1: return TO_MUX( ADC_CHANNEL_IN9, 0 );
+ case C0: return TO_MUX( ADC_CHANNEL_IN10, 0 );
+ case C1: return TO_MUX( ADC_CHANNEL_IN11, 0 );
+ case C2: return TO_MUX( ADC_CHANNEL_IN12, 0 );
+ case C3: return TO_MUX( ADC_CHANNEL_IN13, 0 );
+ case C4: return TO_MUX( ADC_CHANNEL_IN14, 0 );
+ case C5: return TO_MUX( ADC_CHANNEL_IN15, 0 );
+# if STM32_ADC_USE_ADC3
+ case F3: return TO_MUX( ADC_CHANNEL_IN9, 2 );
+ case F4: return TO_MUX( ADC_CHANNEL_IN14, 2 );
+ case F5: return TO_MUX( ADC_CHANNEL_IN15, 2 );
+ case F6: return TO_MUX( ADC_CHANNEL_IN4, 2 );
+ case F7: return TO_MUX( ADC_CHANNEL_IN5, 2 );
+ case F8: return TO_MUX( ADC_CHANNEL_IN6, 2 );
+ case F9: return TO_MUX( ADC_CHANNEL_IN7, 2 );
+ case F10: return TO_MUX( ADC_CHANNEL_IN8, 2 );
+# endif
+#elif defined(STM32F1XX)
case A0: return TO_MUX( ADC_CHANNEL_IN0, 0 );
+ case A1: return TO_MUX( ADC_CHANNEL_IN1, 0 );
+ case A2: return TO_MUX( ADC_CHANNEL_IN2, 0 );
+ case A3: return TO_MUX( ADC_CHANNEL_IN3, 0 );
+ case A4: return TO_MUX( ADC_CHANNEL_IN4, 0 );
+ case A5: return TO_MUX( ADC_CHANNEL_IN5, 0 );
+ case A6: return TO_MUX( ADC_CHANNEL_IN6, 0 );
+ case A7: return TO_MUX( ADC_CHANNEL_IN7, 0 );
+ case B0: return TO_MUX( ADC_CHANNEL_IN8, 0 );
+ case B1: return TO_MUX( ADC_CHANNEL_IN9, 0 );
+ case C0: return TO_MUX( ADC_CHANNEL_IN10, 0 );
+ case C1: return TO_MUX( ADC_CHANNEL_IN11, 0 );
+ case C2: return TO_MUX( ADC_CHANNEL_IN12, 0 );
+ case C3: return TO_MUX( ADC_CHANNEL_IN13, 0 );
+ case C4: return TO_MUX( ADC_CHANNEL_IN14, 0 );
+ 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.
#endif
}
diff --git a/drivers/chibios/ws2812_pwm.c b/drivers/chibios/ws2812_pwm.c
index 140120d488..e6af55b6b3 100644
--- a/drivers/chibios/ws2812_pwm.c
+++ b/drivers/chibios/ws2812_pwm.c
@@ -27,6 +27,15 @@
# error "please consult your MCU's datasheet and specify in your config.h: #define WS2812_DMAMUX_ID STM32_DMAMUX1_TIM?_UP"
#endif
+#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
+
// Push Pull or Open Drain Configuration
// Default Push Pull
#ifndef WS2812_EXTERNAL_PULLUP
@@ -247,7 +256,7 @@ void ws2812_init(void) {
.channels =
{
[0 ... 3] = {.mode = PWM_OUTPUT_DISABLED, .callback = NULL}, // Channels default to disabled
- [WS2812_PWM_CHANNEL - 1] = {.mode = PWM_OUTPUT_ACTIVE_HIGH, .callback = NULL}, // Turn on the channel we care about
+ [WS2812_PWM_CHANNEL - 1] = {.mode = WS2812_PWM_OUTPUT_MODE, .callback = NULL}, // Turn on the channel we care about
},
.cr2 = 0,
.dier = TIM_DIER_UDE, // DMA on update event for next period
diff --git a/drivers/chibios/ws2812_spi.c b/drivers/chibios/ws2812_spi.c
index 89df2987b5..e02cbabc02 100644
--- a/drivers/chibios/ws2812_spi.c
+++ b/drivers/chibios/ws2812_spi.c
@@ -32,6 +32,37 @@
# endif
#endif
+// Define SPI config speed
+// baudrate should target 3.2MHz
+// F072 fpclk = 48MHz
+// 48/16 = 3Mhz
+#if WS2812_SPI_DIVISOR == 2
+# define WS2812_SPI_DIVISOR (0)
+#elif WS2812_SPI_DIVISOR == 4
+# define WS2812_SPI_DIVISOR (SPI_CR1_BR_0)
+#elif WS2812_SPI_DIVISOR == 8
+# define WS2812_SPI_DIVISOR (SPI_CR1_BR_1)
+#elif WS2812_SPI_DIVISOR == 16 // same as default
+# define WS2812_SPI_DIVISOR (SPI_CR1_BR_1 | SPI_CR1_BR_0)
+#elif WS2812_SPI_DIVISOR == 32
+# define WS2812_SPI_DIVISOR (SPI_CR1_BR_2)
+#elif WS2812_SPI_DIVISOR == 64
+# define WS2812_SPI_DIVISOR (SPI_CR1_BR_2 | SPI_CR1_BR_0)
+#elif WS2812_SPI_DIVISOR == 128
+# define WS2812_SPI_DIVISOR (SPI_CR1_BR_2 | SPI_CR1_BR_1)
+#elif WS2812_SPI_DIVISOR == 256
+# define WS2812_SPI_DIVISOR (SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0)
+#else
+# define WS2812_SPI_DIVISOR (SPI_CR1_BR_1 | SPI_CR1_BR_0) // default
+#endif
+
+// Use SPI circular buffer
+#ifdef WS2812_SPI_USE_CIRCULAR_BUFFER
+# define WS2812_SPI_BUFFER_MODE 1 // circular buffer
+#else
+# define WS2812_SPI_BUFFER_MODE 0 // normal buffer
+#endif
+
#define BYTES_FOR_LED_BYTE 4
#define NB_COLORS 3
#define BYTES_FOR_LED (BYTES_FOR_LED_BYTE * NB_COLORS)
@@ -81,14 +112,14 @@ void ws2812_init(void) {
palSetLineMode(RGB_DI_PIN, WS2812_OUTPUT_MODE);
// TODO: more dynamic baudrate
- static const SPIConfig spicfg = {
- 0, NULL, PAL_PORT(RGB_DI_PIN), PAL_PAD(RGB_DI_PIN),
- SPI_CR1_BR_1 | SPI_CR1_BR_0 // baudrate : fpclk / 8 => 1tick is 0.32us (2.25 MHz)
- };
+ static const SPIConfig spicfg = {WS2812_SPI_BUFFER_MODE, NULL, PAL_PORT(RGB_DI_PIN), PAL_PAD(RGB_DI_PIN), WS2812_SPI_DIVISOR};
spiAcquireBus(&WS2812_SPI); /* Acquire ownership of the bus. */
spiStart(&WS2812_SPI, &spicfg); /* Setup transfer parameters. */
spiSelect(&WS2812_SPI); /* Slave Select assertion. */
+#ifdef WS2812_SPI_USE_CIRCULAR_BUFFER
+ spiStartSend(&WS2812_SPI, sizeof(txbuf) / sizeof(txbuf[0]), txbuf);
+#endif
}
void ws2812_setleds(LED_TYPE* ledarray, uint16_t leds) {
@@ -104,9 +135,11 @@ void ws2812_setleds(LED_TYPE* ledarray, uint16_t leds) {
// Send async - each led takes ~0.03ms, 50 leds ~1.5ms, animations flushing faster than send will cause issues.
// Instead spiSend can be used to send synchronously (or the thread logic can be added back).
-#ifdef WS2812_SPI_SYNC
+#ifndef WS2812_SPI_USE_CIRCULAR_BUFFER
+# ifdef WS2812_SPI_SYNC
spiSend(&WS2812_SPI, sizeof(txbuf) / sizeof(txbuf[0]), txbuf);
-#else
+# else
spiStartSend(&WS2812_SPI, sizeof(txbuf) / sizeof(txbuf[0]), txbuf);
+# endif
#endif
}