[solved] STM32 BluePill IO issue with package from STMicroelectronics

Hi All,

I try to port code written for package STM32Duino.com (Roger Clark) working on the standard package from STMicroelectronics. It didn’t work.

So I tried to find out which port pins cause the problem.

It looks like no pin of port A or port B works. PC13 LED_BUILTIN works.

What do I need to do to get pinMode() and digitalWrite() work on port A and port B on BluePill?

Jean-Marc

//BluePill_IO

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
#if defined(ARDUINO_ARCH_STM32F1)
  // see https://github.com/rogerclarkmelbourne/Arduino_STM32/issues/222
  Serial.end(); // needed for PA11, PA12 to work
  uint32_t mapr = AFIO_BASE->MAPR;
  mapr &= ~AFIO_MAPR_SWJ_CFG;
  mapr |= AFIO_MAPR_SWJ_CFG_NO_JTAG_SW;
  AFIO_BASE->MAPR = mapr; // remap JTAG pins as GPIO
#elif defined(ARDUINO_ARCH_STM32) && defined(STM32F1xx)
  //RCC->APB2ENR |= 0x0000000C; // enable port A & B clocks, doesn't help
  uint32_t t = RCC->AHBENR; // delay
  uint32_t mapr = AFIO->MAPR;
  mapr &= ~AFIO_MAPR_SWJ_CFG;
  mapr |= AFIO_MAPR_SWJ_CFG_NOJNTRST;
  AFIO->MAPR = mapr; // remap JTAG pins as GPIO
#endif
  for (uint8_t i = PA0; i <= PA15; i++)
  {
    digitalWrite(i, HIGH);
    pinMode(i, OUTPUT);
    digitalWrite(i, HIGH);
  }
  for (uint8_t i = PB0; i <= PB15; i++)
  {
    digitalWrite(i, HIGH);
    pinMode(i, i == PB2 ? INPUT : OUTPUT);
    digitalWrite(i, HIGH);
  }
  digitalWrite(LED_BUILTIN, HIGH);
}

void loop()
{
  digitalWrite(LED_BUILTIN, LOW);
  for (uint8_t i = PA0; i <= PA15; i++)
  {
    digitalWrite(i, HIGH);
    delay(1000);
    digitalWrite(i, LOW);
    delay(1000);
  }
  delay(1000);
  digitalWrite(LED_BUILTIN, HIGH);
  for (uint8_t i = PB0; i <= PB15; i++)
  {
    digitalWrite(i, HIGH);
    delay(1000);
    digitalWrite(i, LOW);
    delay(1000);
  }
  delay(1000);
}

port pin names are not ordered in this package. fixed test:

//BluePill_IO

static const uint8_t pa[] = {PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15};
static const uint8_t pb[] = {PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7, PB8, PB9, PB10, PB11, PB12, PB13, PB14, PB15};

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
#if defined(ARDUINO_ARCH_STM32F1)
  // see https://github.com/rogerclarkmelbourne/Arduino_STM32/issues/222
  Serial.end(); // needed for PA11, PA12 to work
  uint32_t mapr = AFIO_BASE->MAPR;
  mapr &= ~AFIO_MAPR_SWJ_CFG;
  mapr |= AFIO_MAPR_SWJ_CFG_NO_JTAG_SW;
  AFIO_BASE->MAPR = mapr; // remap JTAG pins as GPIO
#elif defined(ARDUINO_ARCH_STM32) && defined(STM32F1xx)
  //RCC->APB2ENR |= 0x0000000C; // enable port A & B clocks, doesn't help
  uint32_t t = RCC->AHBENR; // delay
  uint32_t mapr = AFIO->MAPR;
  mapr &= ~AFIO_MAPR_SWJ_CFG;
  mapr |= AFIO_MAPR_SWJ_CFG_NOJNTRST;
  AFIO->MAPR = mapr; // remap JTAG pins as GPIO
#endif
  for (uint8_t i = 0; i <= 15; i++)
  {
    digitalWrite(pa[i], HIGH);
    pinMode(pa[i], OUTPUT);
    digitalWrite(pa[i], HIGH);
  }
  for (uint8_t i = 0; i <= 15; i++)
  {
    digitalWrite(pb[i], HIGH);
    pinMode(pb[i], OUTPUT);
    digitalWrite(pb[i], HIGH);
  }
  digitalWrite(LED_BUILTIN, HIGH);
}

void loop()
{
  digitalWrite(LED_BUILTIN, LOW);
  for (uint8_t i = 0; i <= 15; i++)
  {
    digitalWrite(pa[i], HIGH);
    delay(1000);
    digitalWrite(pa[i], LOW);
    delay(1000);
  }
  delay(1000);
  digitalWrite(LED_BUILTIN, HIGH);
  for (uint8_t i = 0; i <= 15; i++)
  {
    digitalWrite(pb[i], HIGH);
    delay(1000);
    digitalWrite(pb[i], LOW);
    delay(1000);
  }
  delay(1000);
}

Conclusion: pinMode() does it also in this package. Next step is try without using pinMode().

solved?

why do you set pin high before pinmode?

solved?

Yes, in so far as most pins work now, and I can continue test. And fix the remaining errors I made.

why do you set pin high before pinmode?

I am used to do it that way, to avoid glitches, e.g. if used with logic analyzer. The result is processor dependent.

Final version for this test:

//BluePill_IO

static const uint8_t pa[] = {PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9, PA10, PA11, PA12, PA13, PA14, PA15};
static const uint8_t pb[] = {PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7, PB8, PB9, PB10, PB11, PB12, PB13, PB14, PB15};

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
#if defined(ARDUINO_ARCH_STM32F1)
  // see https://github.com/rogerclarkmelbourne/Arduino_STM32/issues/222
  Serial.end(); // needed for PA11, PA12 to work
  uint32_t mapr = AFIO_BASE->MAPR;
  mapr &= ~AFIO_MAPR_SWJ_CFG;
  mapr |= AFIO_MAPR_SWJ_CFG_NO_JTAG_SW;
  AFIO_BASE->MAPR = mapr; // remap JTAG pin A15 as GPIO
  GPIOA_BASE->CRL = 0x33333333; // 00 11 output PP, 50MHz, pins 0..7
  GPIOA_BASE->CRH = 0x33333333; // 00 11 output PP, 50MHz, pins 8..15
  GPIOB_BASE->CRL = 0x33333333; // 00 11 output PP, 50MHz, pins 0..7, pin2 useless on BluePill
  GPIOB_BASE->CRH = 0x33333333; // 00 11 output PP, 50MHz, pins 8..15
#elif defined(ARDUINO_ARCH_STM32) && defined(STM32F1xx)
  RCC->APB2ENR |= 0x0000000C; // enable port A & B clocks
  uint32_t t = RCC->AHBENR; // delay
  uint32_t mapr = AFIO->MAPR;
  mapr &= ~AFIO_MAPR_SWJ_CFG;
  mapr |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE;
  AFIO->MAPR = mapr; // remap JTAG pin A15 as GPIO
  GPIOA->CRL = 0x33333333; // 00 11 output PP, 50MHz, pins 0..7
  GPIOA->CRH = 0x33333333; // 00 11 output PP, 50MHz, pins 8..15
  GPIOB->CRL = 0x33333333; // 00 11 output PP, 50MHz, pins 0..7, pin2 useless on BluePill
  GPIOB->CRH = 0x33333333; // 00 11 output PP, 50MHz, pins 8..15
#endif
#if 0 
  for (uint8_t i = 0; i <= 15; i++)
  {
    if (PA13 == pa[i]) continue; // keep SWDIO for STLink
    if (PA14 == pa[i]) continue; // keep SWCLK for STLink
    digitalWrite(pa[i], HIGH);
    pinMode(pa[i], OUTPUT);
    digitalWrite(pa[i], HIGH);
  }
  for (uint8_t i = 0; i <= 15; i++)
  {
    if (PB2 == pb[i]) continue; // useless, high series resistor from jumper to processor pin
    digitalWrite(pb[i], HIGH);
    pinMode(pb[i], OUTPUT);
    digitalWrite(pb[i], HIGH);
  }
#endif
  digitalWrite(LED_BUILTIN, HIGH);
}

void loop()
{
  digitalWrite(LED_BUILTIN, LOW);
  for (uint8_t i = 0; i <= 15; i++)
  {
    if (PA13 == pa[i]) continue;
    if (PA14 == pa[i]) continue;
    digitalWrite(pa[i], HIGH);
    delay(1000);
    digitalWrite(pa[i], LOW);
    delay(1000);
  }
  delay(1000);
  digitalWrite(LED_BUILTIN, HIGH);
  for (uint8_t i = 0; i <= 15; i++)
  {
    if (PB2 == pb[i]) continue; // useless, high series resistor from jumper to processor pin
    digitalWrite(pb[i], HIGH);
    delay(1000);
    digitalWrite(pb[i], LOW);
    delay(1000);
  }
  delay(1000);
}
1 Like