Transfer of values ​​to ArduinoUNO original ports.

Fabaum
Posts: 24
Joined: Tue Mar 17, 2020 4:10 pm

Transfer of values ​​to ArduinoUNO original ports.

Post by Fabaum »

Hello friends,

I would like to use a shield that I developed for ArduinoUNO on the STM32L476RG board.
In the original program, I transferred integer values ​​to the ports instead of triggering them pin by pin.
As for the ArduinoUNO PORTB, only the first six pins are available (corresponding to digital pins 8 to 13 printed on the ArduinoUNO board, and corresponding to D8 - D13 on the STM32 board). I transfer to this port fixed values ​​depending on the circuits I want to activate on the shield.

PORTB = 4;

As for PORTD, an entire port is available (corresponding to D0 - D7 on the STM32 board). In this port the values ​​can vary more, they are not pre-established.

PORTD = valueA;

Checking the reference https://os.mbed.com/teams/ST/wiki/Use-o ... duino-pins, I realize that I have to change some connections on the board in order to continue using the same shield (pins D0 and D1 are used by the STLink Virtual Comm Port on the STM32 board).
My question is: keeping the program originally developed for ArduinoUNO, when transferring values ​​to ports B and D, will the same pins be kept on the STM32L476RG board?
Note that on the STM32 board, pins D0 - D7 correspond to pins on ports PA_x and PB_x on the L476RG, and pins D8 - D13 correspond to pins on ports PA_x, PB_x and PC_x.
During compilation, will the libraries "mask" the intended pins to use the shield?
Attachments
placaUno - small1.jpg
placaUno - small1.jpg (84.41 KiB) Viewed 651 times
nucleo_l476rg_arduino - small.jpg
nucleo_l476rg_arduino - small.jpg (94.86 KiB) Viewed 651 times

stas2z
Posts: 131
Joined: Mon Feb 24, 2020 8:17 pm
Answers: 8

Re: Transfer of values ​​to ArduinoUNO original ports.

Post by stas2z »

first i need to dissapoint you saying that PORTx are atmega only, it wil not work with STM32

for direct port writing you can use LL driver or direct register access

STM32 have very straight port structure
GPIOA contains all PA0..PA15 ports, GPIOB - PB0..PB15 etc
so if your pins are on the same GPIO you can pack your pins and write them all or write whole port (all 16 pins)

for example
LL_GPIO_SetOutputPin(GPIOD, _Your_LL_BitmaskOfPinsToSet);
LL_GPIO_ResetOutputPin(GPIOD, _Your_LL_BitmaskOfPinsToReset);
where LL_Bitmask should be composed like LL_GPIO_PIN_0 | LL_GPIO_PIN_5 | LL_GPIO_PIN_10 or LL_GPIO_PIN_ALL for all ports;

LL_GPIO_WriteOutputPort(GPIOD, _YourSimpleBitMask);
here you can write whole port state using simple 16bit bitmask, each bit for each port

Upd. Instead of GPIOD here you should use your choosen GPIO port, GPIOA...GPIOZ

Fabaum
Posts: 24
Joined: Tue Mar 17, 2020 4:10 pm

Re: Transfer of values ​​to ArduinoUNO original ports.

Post by Fabaum »

Hi stas2z,

Thanks for the answer.
stas2z wrote:
Sun Mar 29, 2020 5:13 am
first i need to dissapoint you saying that PORTx are atmega only, it wil not work with STM32
You're absolutely right!
In fact, due to the silence on this subject in the last days, I realized that I was wrong, relating things that are different (declaration of ports in ArduinoUNO with the ports of STM32).
I took the opportunity to develop some lines of code using bitwise, which would probably solve the problem, although the activation of the port pins is slower and sequential, and not simultaneous, as would be the transfer of an integer value to a port:

Code: Select all

//***PORTD ArduinoUNO***
//ArdnuinoUNO pins = STM32L476RG pins
//              DO = PA_3
//              D1 = PA_2
//              D2 = PA_10
//              D3 = PB_3
//              D4 = PB_5
//              D5 = PB_4
//              D6 = PB_10
//              D7 = PA_8

pinMode(PA3, OUTPUT);
pinMode(PA2, OUTPUT);
pinMode(PA10, OUTPUT);
pinMode(PB3, OUTPUT);
pinMode(PB5, OUTPUT);
pinMode(PB4, OUTPUT);
pinMode(PB10, OUTPUT);
pinMode(PA8, OUTPUT);

int valueA;
//PORTD=valueA;
int mask=0b00000001;
int value_to_port;

void transfer()
{
  value_to_port=valueA&mask;
  if (value_to_port==mask)
  {
    digitalWrite(PA3,HIGH);
  }
  else
  {
    digitalWrite(PA3,LOW);
  }
  mask<<1;

  value_to_port=valueA&mask;
  if (value_to_port==mask)
  {
    digitalWrite(PA2,HIGH);
  }
  else
  {
    digitalWrite(PA2,LOW);
  }
  mask<<1;

  value_to_port=valueA&mask;
  if (value_to_port==mask)
  {
    digitalWrite(PA10,HIGH);
  }
  else
  {
    digitalWrite(PA10,LOW);
  }
  mask<<1;

  value_to_port=valueA&mask;
  if (value_to_port==mask)
  {
    digitalWrite(PB3,HIGH);
  }
  else
  {
    digitalWrite(PB3,LOW);
  }
  mask<<1;

  value_to_port=valueA&mask;
  if (value_to_port==mask)
  {
    digitalWrite(PB5,HIGH);
  }
  else
  {
    digitalWrite(PB5,LOW);
  }
  mask<<1;

  value_to_port=valueA&mask;
  if (value_to_port==mask)
  {
    digitalWrite(PB4,HIGH);
  }
  else
  {
    digitalWrite(PB4,LOW);
  }
  mask<<1;

  value_to_port=valueA&mask;
  if (value_to_port==mask)
  {
    digitalWrite(PB10,HIGH);
  }
  else
  {
    digitalWrite(PB10,LOW);
  }
  mask<<1;

  value_to_port=valueA&mask;
  if (value_to_port==mask)
  {
    digitalWrite(PA8,HIGH);
  }
  else
  {
    digitalWrite(PA8,LOW);
  }
  mask=0b00000001;
}
I haven't done the tests yet, but it should work!
Last edited by Fabaum on Thu Apr 02, 2020 8:38 pm, edited 1 time in total.

stas2z
Posts: 131
Joined: Mon Feb 24, 2020 8:17 pm
Answers: 8

Re: Transfer of values ​​to ArduinoUNO original ports.

Post by stas2z »

if your output ports are not on the same port sure you need to write it one by one
but much better ti use array, loop and simple bitmath to not write A4 page of almost same copycat parts

Code: Select all

uint32_t pins[8] = {PA3, PA2, PA10, PB3, PB5, PB4, PB10, PA8};
void setPinsMode(void) {
  for (uint8_t counter = 0; counter < 8; counter++) {
    pinMode(pins[counter], OUTPUT);
  }
}
void writeValueToPins(uint8_t value) {
  for (uint8_t counter = 0; counter < 8; counter++) {
    digitalWrite(pins[counter], (value & (1U << counter)) ? HIGH : LOW);
  }
}
sure this piece of code can be optimized much in terms of perfomance, but at least it look much cleaner

Fabaum
Posts: 24
Joined: Tue Mar 17, 2020 4:10 pm

Re: Transfer of values ​​to ArduinoUNO original ports.

Post by Fabaum »

Excelent, stas2z, thank you again!

Fabaum
Posts: 24
Joined: Tue Mar 17, 2020 4:10 pm

Re: Transfer of values ​​to ArduinoUNO original ports.

Post by Fabaum »

Hi, stas2z,
stas2z wrote:
Mon Mar 30, 2020 6:02 pm
if your output ports are not on the same port sure you need to write it one by one
but much better ti use array, loop and simple bitmath to not write A4 page of almost same copycat parts

Code: Select all

uint32_t pins[8] = {PA3, PA2, PA10, PB3, PB5, PB4, PB10, PA8};
void setPinsMode(void) {
  for (uint8_t counter = 0; counter < 8; counter++) {
    pinMode(pins[counter], OUTPUT);
  }
}
void writeValueToPins(uint8_t value) {
  for (uint8_t counter = 0; counter < 8; counter++) {
    digitalWrite(pins[counter], (value & (1U << counter)) ? HIGH : LOW);
  }
}
sure this piece of code can be optimized much in terms of perfomance, but at least it look much cleaner
The code you suggested really looks more elegant.
Sorry to ask, but have you tested it?
I tried to apply it, but the operation is quite erratic ...

stas2z
Posts: 131
Joined: Mon Feb 24, 2020 8:17 pm
Answers: 8

Re: Transfer of values ​​to ArduinoUNO original ports.

Post by stas2z »

ive not tested it, but its so basic and shouldn't cause any issue
only if your are trying to use it in the interrupt hadler

fredbox
Posts: 66
Joined: Thu Dec 19, 2019 3:05 am
Answers: 2

Re: Transfer of values ​​to ArduinoUNO original ports.

Post by fredbox »

That code looks correct. I ran it on a blue pill and it looks like the correct pins are toggling.

You could add a serial print statement to see if the bits are being set the way you expect.

Also, you can simplify the digital write command to eliminate the ternary operator:

Code: Select all

void writeValueToPins(uint8_t value) {
  for (uint8_t counter = 0; counter < 8; counter++) {
    digitalWrite(pins[counter], (value >> counter) & 1);
  }
}

Fabaum
Posts: 24
Joined: Tue Mar 17, 2020 4:10 pm

Re: Transfer of values ​​to ArduinoUNO original ports.

Post by Fabaum »

Hi, friends,
stas2z wrote:
Thu Apr 02, 2020 5:46 pm
ive not tested it, but its so basic and shouldn't cause any issue
only if your are trying to use it in the interrupt hadler
stas2z, that is exactly what I am doing, trying to use your suggestion within an interruption routine. The strange thing is that during the execution of this routine, the timer is temporarily stopped ... What is the explanation for why it is not working well?
fredbox wrote:
Thu Apr 02, 2020 8:12 pm
That code looks correct. I ran it on a blue pill and it looks like the correct pins are toggling.

You could add a serial print statement to see if the bits are being set the way you expect.

Also, you can simplify the digital write command to eliminate the ternary operator:

Code: Select all

void writeValueToPins(uint8_t value) {
  for (uint8_t counter = 0; counter < 8; counter++) {
    digitalWrite(pins[counter], (value >> counter) & 1);
  }
}
fredbox, I would like to test this suggestion, but making a change to my ArduinoUNO shield that I am experimenting with on the STM32 board, I was careless and ended up putting 15V on the 3V3 power line :cry: :cry: :cry: ... Now I will have to order another STM32L476RG board, but my country is restricting imports from China these days ...

stas2z
Posts: 131
Joined: Mon Feb 24, 2020 8:17 pm
Answers: 8

Re: Transfer of values ​​to ArduinoUNO original ports.

Post by stas2z »

inturrupt handler have to be quick as much as it possible and have some rectrictions also, but digitalWrite is very heavy trying to be beginners friendly with tonns of checks and inits inside
for interrupt handlers it's much better to use direct writing routines, at least digitalWriteFast for official STM32 core

Post Reply

Return to “STM32L4 based boards”