-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
So, due to a mistake i ended up wiring a WS2812 bus to PD8 on STM32F473VET6, which has no SPI, I2S or PWM capability, it only has UART3 TX. While searching whether it would be possible to use UART3 for generating the bitstream i came across two information, first STM32CubeMX tells the max baudrate is 1Mbps. Second, a rust library has been written to control WS2812 from STM32 UART and it sets the UART at 3.75Mbps.
https://docs.rs/crate/ws2812-uart/0.2.0/source/src/lib.rs
So, is there anything that prevents to set the baud rate to 3750000 with the current arduino wrapper or HAL API?
Here is what i did so far and it does not work well
HardwareSerial Serial3(PD8, PD8);
uint8_t uartBuffer[LED_COUNT * 12];
uint8_t* encode_byte(uint8_t byte) {
uint8_t res[4];
for(int i = 0; i < 4; i++) {
uint8_t pattern = 0b00010000; // Base pattern 0x10
if(byte & 0b10000000) pattern |= 0b00000011; // Add for bit7=1
if(byte & 0b01000000) pattern |= 0b01100000; // Add for bit6=1
res[i] = ~pattern;
byte <<= 2;
}
return res;
}
void init_rgb() {
// Serial3.setTxInvert(); //inverted in encode
Serial3.begin(3750000); // 3.75 Mbps
// USART3->CR1 &= ~USART_CR1_UE;
// USART3->CR1 |= USART_CR1_OVER8;
// USART3->BRR = (2 * HAL_RCC_GetSysClockFreq()) / 3750000; // = 80
// USART3->CR1 |= USART_CR1_UE;
}
void write_rgb_bfr(uint32_t rgb, int idx) {
uint8_t r = (rgb >> 16) & 0xFF;
uint8_t g = (rgb >> 8) & 0xFF;
uint8_t b = rgb & 0xFF;
uint8_t grb[3] = {g, r, b};
int base = idx * 12; // 3 bytes * 4 UART bytes each = 12
for(int byteIdx = 0; byteIdx < 3; byteIdx++) {
uint8_t* encoded = encode_byte(grb[byteIdx]);
for(int j = 0; j < 4; j++) {
uartBuffer[base++] = encoded[j];
}
}
}
void show_rgb_bfr(uint8_t len, bool off) {
// for(int i = 0; i < len * 12; i++) {
// while(!(USART3->ISR & USART_ISR_TXE));
// USART3->TDR = uartBuffer[i];
// }
// while(!(USART3->ISR & USART_ISR_TC));
for(int i = 0; i < len * 12; i++) Serial3.write(uartBuffer[i]);
//delayMicroseconds(80);
} i tried to set the baudrate with begin and with direct register access, setting oversampling to 8.
I tried to add 60 and then 80us delay for reset pulse, and no delay.
The best i could get was washed up colors and 15 LED lighted instead of 14, it was with a different bit pattern system, BRR around 65, and 80us reset wait
const uint8_t patterns[4] = {
0x88, // 00: 1000 1000
0x8E, // 01: 1000 1110
0xE8, // 10: 1110 1000
0xEE // 11: 1110 1110
};