2025-06-26 3:09 AM
Hi all
I made a little program under arduino IDE (but I write directly into the registers), in order to test the command of WS2812b chips via the SPI1 MOSI pin : It worked perfectly with older BluPill boards I have got.
Tried the same thing with BluePill + from WeAct official store , it does not work. Even the SPI1->CR1 register is not set properly : it must be 0b1100111 , but it is actually 0b100011 : which is wrong , the Master Mode and SPI enable bits can not be set ...
Any idea , please ? thanks !
/* spi_dma_ws.h */
#define ws_chips 8 // number of RGB chips
void spi_dma_transmit();
extern SPI_HandleTypeDef hspi1;
extern uint16_t adc_pa5;
// some colours
const uint8_t ws_black[3] = { 0, 0, 0 };
const uint8_t ws_green[3] = { 25, 0, 0 };
uint8_t ws_green_adc[3] = { 0, 0, 0 };
const uint8_t ws_red[3] = { 0, 25, 0 };
const uint8_t ws_blue[3] = { 0, 0, 25 };
const uint8_t ws_white[3] = { 25, 25, 25 };
const uint8_t ws_purple[3] = { 0, 25, 25 };
const uint8_t ws_yell[3] = { 25, 25, 0 };
const uint8_t ws_turc[3] = { 25, 0, 25 };
uint8_t ws3[ws_chips][3]; // has the 3 colours of each RGB chip
uint8_t ws33[ws_chips * 3 * 3]; // has the 3 SPI bytes for each the 3 colours of each RGB chip
// example with some colours
void ws_3() {
for (int c = 0; c < 3; c++) {
ws3[0][c] = ws_green_adc[c];
ws3[1][c] = ws_red[c];
ws3[2][c] = ws_blue[c];
ws3[3][c] = ws_white[c];
ws3[4][c] = ws_black[c];
ws3[5][c] = ws_yell[c];
ws3[6][c] = ws_turc[c];
ws3[7][c] = ws_purple[c];
}
}
// 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
// |‾|_._|‾|_._|‾|_._|‾|_._|‾|_._|‾|_._|‾|_._|‾|_._ // 146 73 36
// 128 64 32 16 8 4 2 1
// |‾.‾|_|‾.‾|_|‾.‾|_|‾.‾|_|‾.‾|_|‾.‾|_|‾.‾|_|‾.‾|_ // 219 109 182
void ws_33() {
uint8_t p = 0, w;
ws_3();
ws_green_adc[0] = adc_pa5 / 4;
for (int ws = 0; ws < sizeof(ws3) / 3; ws++) {
for (int c = 0; c < 3; c++) {
w = ws3[ws][c];
ws33[p] = 0b10010010;
if (w & 128) ws33[p] += 0b01000000;
if (w & 64) ws33[p] += 0b00001000;
if (w & 32) ws33[p] += 1;
p++;
ws33[p] = 0b01001001;
if (w & 16) ws33[p] += 0b00100000;
if (w & 8) ws33[p] += 0b00000100;
p++;
ws33[p] = 0b00100100;
if (w & 4) ws33[p] += 0b10000000;
if (w & 2) ws33[p] += 0b00010000;
if (w & 1) ws33[p] += 0b00000010;
p++;
}
}
}
void send_ws() {
ws_33();
spi_dma_transmit();
}
void spi_dma_init() {
// Enable Port A clock // Enable SPI Clock
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_SPI1EN;
// Mode: Output, Speed: 10MHz // Alternate function push-pull
GPIOA->CRL &= ~(GPIO_CRL_CNF7 | GPIO_CRL_MODE7); // MOSI = PA7
GPIOA->CRL |= (GPIO_CRL_CNF7_1 | GPIO_CRL_MODE7_0); // 10.01
// SPI Mode: Master
SPI1->CR1 |= SPI_CR1_MSTR;
// 100: BaudRate = fPCLK/32 // + CPOL + CPHA
SPI1->CR1 |= SPI_CR1_BR_2 | SPI_CR1_CPOL | SPI_CR1_CPHA;
// Set TXDMA bit in CR2 → enable DMA transmit
SPI1->CR2 |= SPI_CR2_TXDMAEN;
// SPI Enable
SPI1->CR1 |= SPI_CR1_SPE;
// DMA Configuration // Enable DMA Clock
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
// Priority Level = 0b10 → High
DMA1_Channel3->CCR |= DMA_CCR_PL_1;
// Memory Increment mode + Direction Read from Memory
DMA1_Channel3->CCR |= DMA_CCR_MINC | DMA_CCR_DIR; // no need for interrupt
// Set Memory Address → Peripheral Address
DMA1_Channel3->CMAR = (uint32_t)ws33;
DMA1_Channel3->CPAR = (uint32_t)&SPI1->DR;
}
void spi_dma_transmit() {
// stop DMA to refill CNDTR
DMA1_Channel3->CCR &= ~DMA_CCR_EN;
DMA1_Channel3->CNDTR = sizeof(ws33);
// launch DMA
DMA1_Channel3->CCR |= DMA_CCR_EN;
///Serial.print(sizeof(ws33));
}
/* spi_dma_ws.ino */
#include "spi_dma_ws.h"
uint16_t adc_pa5;
void setup() {
Serial.begin(115200);
spi_dma_init();
pinMode(PB2, OUTPUT);
delay(2000);
}
void loop() {
delay(444);
send_ws();
adc_pa5 = analogRead(PA_5);
Serial.print("GPIOA->CRL "); /// debug
Serial.println(GPIOA->CRL, BIN);
Serial.print("SPI1->CR1 ");
Serial.println(SPI1->CR1, BIN);
Serial.print("SPI1->CR2 ");
Serial.println(SPI1->CR2, BIN);
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_2); // BluePill+ LED
}
2025-06-26 3:12 AM - edited 2025-06-26 3:54 AM
A Blue Pill will (almost?) certainly have a fake STM32.
Different batches may well have different fakes.
Have you tested on a genuine ST board; eg, a Nucleo?
PS:
You could try this to identify what's actually on your boards:
https://mecrisp-stellaris-folkdoc.sourceforge.io/bluepill-diagnostics-v1.6.html#diags-1-6
But, seriously, save yourself all the grief - get a genuine STM32.
A Nucleo even comes complete with a genuine ST-Link.
PPS:
Some examples of fake/clone STM32s here: https://www.richis-lab.de/STM32.htm
These two, specifically, are from Blue Pills:
https://www.richis-lab.de/STM32_01.htm
https://www.richis-lab.de/STM32_04.htm
More clones: https://mecrisp-stellaris-folkdoc.sourceforge.io/clones-stm32-mcus.html#index-0
2025-06-26 5:21 AM
Thanks Andrew
I wasn't able to make the diagnostic to work , the chip didn't appear as an working USB device
But after having made a full chip erase with CubeProgrammer , the SPI begun to work , ie. correct register value , and correct signal on the pin !
Nevertheless , I am still facing somme "funny" behaviour : after some unplugging or plugging things , the chip lasts teh SPI config ... and recovers it after a manual reset
So I am not sure all this is the chip's fault , I have look at and to test more things , hope I will understand what is the problem
2025-06-26 5:26 AM
@mwalt.3 wrote:hope I will understand what is the problem
The basic problem is that you have an unknown chip, so there's no telling how it's supposed to work - or even if it works at all!
2025-06-26 6:17 AM
Bluepill boards are probably near to 100% faked meanwhile.
You should have more luck with black pill (STM32F401CCU6 or STM32F411CEU6). These seem to be useable up to now (and have a bit more memory and power).
But as mentioned a Nucleo board offers a built in ST-Link and works 100% as expected.
2025-06-26 6:50 AM
WeAct is known as a trusted maker I don't know what happens , I will tell them
Black pill does not have PB11 nor USART3 , and unfortunately , I need this features for most of my projects
2025-06-26 7:00 AM
If you want to find out what you have got:
https://community.st.com/t5/stm32-mcus-products/how-to-spot-fake-stm32-mcu/td-p/147180
(I never tried it, but stored the the link when I got a misbehaving blue pill some time ago)
2025-06-26 7:22 AM
@mwalt.3 wrote:Black pill does not have PB11 nor USART3
Both STM32F401CCU6 and STM32F411CEU6 have 3 UARTs, with a number of choices for which pins they use