ZEPHYR RTOS Configuring GPIO Pins - embedded-linux

Hi I would like to configure a custom GPIO pin as output to control a motor on a STM32 H743Zi board running Zephyr RTOS.
The dts file of the board can be found in the folder or a separate file nucleo h743zi.dts code.
I would like to us the arduino pin mapping provided by the board ardunio r3 connector.dtsi code
The overlay file that I've developed so far is as follows code. I would like to configure the D0 pin (as per the arduino connector dtsi file) as a GPIO pin to control the motors.
However, I've not been able to configure the pin and I don't receive a high signal if the pin is turned on.
Any help to resolve this issue is appreciated.

You can refer to the answer in this link:
https://github.com/zephyrproject-rtos/zephyr/discussions/35932
In my case, I use Thunderboard Sensor 2 and my solution as below:
Move to the <board.dsti> in folder /zephyr/dts/arm/silabs/efr32mg.dtsi
insert your define GPIO to use:
...
/ {
zephyr,user {
signal-gpios = <&gpioa 8 GPIO_ACTIVE_HIGH>;
};
...
Here, I use my board portA and pin 8 as schematic
After you save the file, open the main file of your project and insert something as below:
#define ZEPHYR_USER_NODE DT_PATH(zephyr_user)
...
void main(void)
{
const struct gpio_dt_spec signal =
GPIO_DT_SPEC_GET(ZEPHYR_USER_NODE, signal_gpios);
/* Configure the pin */
gpio_pin_configure_dt(&signal, GPIO_OUTPUT_INACTIVE);
...
while(1){
/* Toggle the pin PA8*/
gpio_pin_toggle(signal.port, signal.pin);
k_msleep(SLEEP_TIME_MS);
}
...

Related

How to overwrite I2C pin settings Adafruit libs?

I'm currently trying to run an MLX90614 sensor on a ESP32 board (lolin32 lite)
This board doesn't have a pin 21 and from a forum I discovered I can use pin 23 and 19.
I tested this out with the I2C scanner code and this works.
Now I like to use Adafruit MLX90614 library and tell it to use pins 23,19.
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Wire.end();
Wire.setPins(23,19);
Wire.begin();
delay(100);
if (!mlx.begin(90, &Wire)) {
Serial.println("Error connecting to MLX sensor. Check wiring.");
while (1);
};
}
I keep getting "Error connecting to MLX sensor. Check wiring" so it doesn't overwrite the pin settings.
Can this been done?
UPDATE: I found my mistake. I had changed the I2C address of the MLX sensor in a previous project. That is why the I2C scanner code worked and Adafruit default address not.

Arduino Uno + ESP8266 12E + Blynk + Relay

I started adventure with arduino and programming 2 months ago.So, I am new in this topics.
Until now I realized few projects including Blynk connected with arduino. The last one was similar to one described in topic but I used the ENC28j60 instead of ESP8266 module and then it worked fine.
The problem started with ESP module.
Short description of project:
The main idea is to control AC light with Blynk App support.
First of all I made a connection according to picture below:
As power source I used the USB phone charger connected with step by voltage converter to get in final the 3.3V source.
I additionally connected the Arduino Uno with relay module like this:
Arduino ====> Relay module
5V ====> VCC
GND ====> GND
Pin 5 ====> IN1
Everythink you can see in pictures below (sorry for quality)
And for now I did almost every step (with so many problems). Here I mean:
1. I checked if arduino is connected with ESP module by serial port -> system report "ready" status.
2. I upload the below (template) Arduino IDE sketch for my project:
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "***";
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "***";
char pass[] = "***";
void setup()
{
// Debug console--
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
}
void loop()
{
Blynk.run();
}
And finally I started the New project in Blynk. I set the Arduino uno as a hardware model and WiFi as connection type. Then I added the Button and set the Output to D5.
And now (close to the end of project) I met with a problem. After pushing the connect button (in up-right corner) I receive the information that device is connected (Online). Then when I try to push the button to Active Relay - nothing happens.
Whats more. I tried with different pins on Arduino with the same results. And I don't know why (probably because I have still small knowladge) but when I set the Button output value to D2 - after connection when I push it then the diode on ESP module Turn OFF and Turn ON.
I tried to find solution on this forum and in many other places for last 3 days but without any results. That's why I decided to ask You for help. Do you know what did I wrong or what should I add to project to make connection between the Blynk and relay work correct?
Write if you will need some more or detailed information from my side.
Why are you using both the uno and the esp? You can just use the esp instead of the combo, will make your project less power hungry and smaller. If you wonder about using just the esp, you can use the nodemcu boards (which can be found for less that 4€ per unit in China).
I've some example sketches for this (with temperature and humidity), if you want to take a look at those.
When looking at the pictures and code you have postet, it seems that you have flashed the ESP with a Arduino sketch. This is fine if you would like to activate the relay directly with the ESP (without the Arduino UNO).
Then you just have to connect the relay to the ESP instead of to the Arduino. Unfortunately not all relay boards can operate with the 3.3V logic that the ESP supplies, but maybe you'r lucky.
On the other hand, if you would like to use the Arduino UNO with the ESP as Wi-Fi, then you would have to reflash the ESP with the original AT firmware. Then you could connect it to the Arduino and use a sketch that looks something like this.
#define BLYNK_PRINT Serial
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
char auth[] = "YourAuthToken";
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
#include <SoftwareSerial.h>
SoftwareSerial EspSerial(2, 3);
// pin 3 connected to ESP RX and pin 2 connected to ESP TX
// Your ESP8266 baud rate:
#define ESP8266_BAUD 115200
ESP8266 wifi(&EspSerial);
void setup()
{
// Debug console
Serial.begin(9600);
delay(10);
// Set ESP8266 baud rate
EspSerial.begin(ESP8266_BAUD);
delay(10);
Blynk.begin(auth, wifi, ssid, pass);
}
void loop()
{
Blynk.run();
}
And you should remove the connection between RST and GND on the Arduino

i2c pin declaration in device tree file?

Any one can help to figure out what the below code mean
especially 0x80000000 important of this value in below device tree node
i2c-gpio-1 {
pinctrl_smx6_i2c_gpio_1: i2c-gpio-1grp-smx6 {
fsl,pins = <
/* SCL GPIO */
MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x80000000
/* SDA GPIO */
MX6QDL_PAD_KEY_COL2__GPIO4_IO10 0x80000000
>;
};
};
This device tree node defines the pinmux configuration for two signals of the imx6q processor on the board to be used as GPIOs (for a bitbanged i2c controller).
The relevant documentation file is: fsl,imx-pinctrl.txt
Especially, this part is relevant here:
Required properties for pin configuration node:
fsl,pins: each entry consists of 6 integers and represents the mux and config setting for one pin. The first 5 integers are specified using a PIN_FUNC_ID macro,
which can be found in imx*-pinfunc.h under device tree source folder.
The last integer CONFIG is the pad setting value like pull-up on this
pin. And that's why fsl,pins entry looks like in
the example below.
Bits used for CONFIG: NO_PAD_CTL(1 << 31): indicate this pin does not
need config.
The two PIN_FUNC_ID macros
MX6QDL_PAD_GPIO_6__GPIO1_IO06, MX6QDL_PAD_KEY_COL2__GPIO4_IO10
are directly taken from this file: imx6q-pinfunc.h
The 0x80000000 value next to these macros is the NO_PAD_CTL(1 << 31) macro from above. This means that that the pins are not configured with the pinmux possibilities detailed there: fsl,imx6q-pinctrl.txt

What's the relationship between GPIO and SPI?

I found GPIO driver in the kernel leave /sys/class/gpio to control gpio, but I found GPIO can be controlled by /dev/mem as well, I found this mapping may be done in the spi-bcm2708 (which call the __ioremap as a platform driver), but I don't understand the relationship between spi and GPIO,how they work together in the linux?
As I understand you are talking about this driver (which is used, for example, in Raspberry Pi). First of all, take a look at BCM2835 datasheet. Review next sections:
1.1 Overview
6.0 General Purpose I/O (GPIO)
6.2 Alternative Functions Assignments (see Table 6-31)
From driver code (see bcm2708_init_pinmode() function) and datasheet (table 6-31), we can see that SPI pins are actually GPIO7..11 pins. Those pins can be actually connected to different hardware modules (either SPI or SD, in this case).
Such a selection is done using pin muxing. So basically you need to connect GPIO7..GPIO11 pins to SPI module. To do so you need to select ALT0 function for each of GPIO7..GPIO11 pins. This can be done by writing corresponding values to GPFSEL0 and GPFSEL1 registers (see tables 6-1..6-3 in datasheet):
And this is how the driver is actually doing this:
/*
* This function sets the ALT mode on the SPI pins so that we can use them with
* the SPI hardware.
*
* FIXME: This is a hack. Use pinmux / pinctrl.
*/
static void bcm2708_init_pinmode(void)
{
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
#define SET_GPIO_ALT(g, a) *(gpio+(((g)/10))) |= (((a) <= 3 ? (a)+4 : (a) == 4 ? 3 : 2)<<(((g)%10)*3))
int pin;
u32 *gpio = ioremap(GPIO_BASE, SZ_16K);
/* SPI is on GPIO 7..11 */
for (pin = 7; pin <= 11; pin++) {
INP_GPIO(pin); /* set mode to GPIO input first */
SET_GPIO_ALT(pin, 0); /* set mode to ALT 0 */
}
iounmap(gpio);
#undef INP_GPIO
#undef SET_GPIO_ALT
}
which looks like quick hack to me, and they actually mentioned it: the correct way would be to use kernel mechanism called pinctrl.
Conclusion: BCM2708 driver doesn't actually trigger any GPIO pins, it's just doing pin muxing in order to connect GPIO7..GPIO11 pins to SPI module. And to do so this driver writes to GPFSELn registers, which happen to be GPIO registers. This is pretty much all relationship between SPI and GPIO in this driver.
P.S.: if you are curious about possible relationship between SPI and GPIO, read about bit banging. See for example spi-bitbang.c driver in Linux kernel.

Turn an LED on or off in AT Mega-1284P Xplained

I am a beginner in AT Mega-1284P Xplained.
I want to turn an LED on and then off (say, LED0) after some specified time in AT Mega 1284P Xplained board from ATMEL. To my surprise, I found no official documentation for this rudimentary task but several different function calls - all of which failed compilation - searching on the web.
Please mention the API call as well as the header file that needs to be included for this. I am using AVR Studio 6.
I will assume a led is connected to pin 0 at port b on the AtMega1284P. The following program should make the led blink.
#include <util/delay.h>
#include <avr/io.h>
int main() {
// Set the pin 0 at port B as output
DDRB |= (1<<PB0);
while(1) {
// Turn led on by setting corresponding bit high in the PORTB register.
PORTB |= (1<<PB0);
_delay_ms(500);
// Turn led off by setting corresponding bit low in the PORTB register.
PORTB &= ~(1<<PB0);
_delay_ms(500);
}
}
Answering my own question: I found Atmel had an example code that covered a bunch of sensors and other peripheral components including LEDs for Mega-1284P. The links are link and link. Besides, very hard to find locations (they did not show up on web searches), the websites are _very_slow. Atmel, are you listening?

Resources