I have a BeagleBone Black board and I'm using the below-mentioned image file.
https://debian.beagleboard.org/images/bone-debian-10.3-iot-armhf-2020-04-06-4gb.img.xz
I aim to operate GPIO pins of this board with the c programming language.
To do so, I've gone through this link: https://beagleboard.org/static/librobotcontrol/installation.html
And after following all the steps according to this link the result I achieved is the same as mentioned in the checking functionality step [the last step] of this document.
Furthermore, I follow this document for c language setup:
https://github.com/beagleboard/librobotcontrol/blob/master/docs/src/project_template.dox
and run this source code:
https://beagleboard.org/static/librobotcontrol/rc_test_leds_8c-example.html
All these processes were completed without any error.
##################################
Now I want to access the GPIO pins of the board. For that, I've prepared a basic code.
Let's take a pin P8_10 / GPIO2[4] for an example. So for that my code will be:
#include <stdio.h>
#include <rc/led.h>
#include <rc/gpio.h>
#include <rc/time.h>
//#define WAIT_US 500000 // time to light each LED in microseconds
int main()
{
rc_gpio_init(2,4,GPIOHANDLE_REQUEST_OUTPUT); /* declare as output*/
rc_gpio_set_value(2,4,1); /* set high */
rc_gpio_cleanup(2,4);
return 0;
}
After executing this code I am not getting the expected output.
So have you any suggestions for me regarding this code.
Or is there any other way to do so?
Thank you.
Try config-pin gpio
config-pin p9.9 gpio
Then try your source. If that does not work and if getting the gpio pins muxed on the BBB is giving you issues. You can always test your specific pin w/:
config-pin -q <Your Specific Pin Used>
For instance: config-pin -q p9.9 will tell you how it is muxed.
Also, most pins can be found by a testing script by mvduin.
Here is the site online at github: https://github.com/mvduin/bbb-pin-utils
Here: https://beagleboard.org/Support/bone101
That site, once scrolling downward, shows a bunch of different ways to mux your BBB w/ GPIO, i2c, UART, and so on...
This and more can be a good base for working w/ the BBB outside of programming w/ the C language under the librobotcontrol library.
Also, here is a good starter on the way GPIO is handled in the C lib. in question: https://beagleboard.org/librobotcontrol/group___g_p_i_o.html
Related
I want to drive a si4734_D60 as a FM receiver by atmega8 through I2C. After compiling the code by'codevision AVR 3.12 advanced', No error occurs in "C" code but at last this error is displayed:
"Error(s) occurred during assembly" and someof errors are:
Error: C:\Users...\SI4734_receiver.asm(2346): Undefined symbol: __i2c_port
that assembly code in line 2346 is:
.equ __i2c_dir=__i2c_port-1
and you can find my project here:
googledrive:Si4734.rar
I don't understand these errors. please help me about it.
thank a lot to share your answer.
i solved it.In help file of codevision in explain of I2C:
The prototypes for these functions are placed in the file i2c.h, located in the .\INC subdirectory. This file must be #include -d before using the functions.
These functions must be configured, by specifying the I/O port and bits used for communication through the I2C bus and the bit rate of the SCL clock.
This is accomplished in the Project|Configure|C Compiler|Libraries|I2C menu:
the Enable Bit-Banged I2C Support option must be activated
· the I/O Port, SDA and SCL bits must be specified in Data Connection
· the Bit Rate of the SCL signal must be set.
good day, stm32 nucleo board I want to write informative Log messages using.
For example, I want to display the message that the program has started by using the Log("Program started") function when the program starts during this period, or I want to give the error message to the screen by using the Log("Program Failed') function when the program fails.
I using C programming langue and stm32cubeide & Nucleo f207zg board thanks in advance for your help
Thanks I solved the problem
Given that:
You know what the UART/USART peripheral is
You connected the right pins to a serial interface
You connected the other end of the interface (for instance an FTDI chip) to your computer
You can implement the logging with printf as you would do in C. Why? Because printf already takes care for you the formatting of the strings, which no one wants to reimplement, and then you redirect the printf output to the UART peripheral that handles low level serial protocol.
Following this guide the steps are easy enough:
Add #include <stdio.h> to the Includes section at the top of the main.c
#include "stdio.h"
Copy and paste the following code into the main.c file before the main() function but after the UART handle declaration
Note that you need to replace the question mark with the actual UART handle declaration, for instance huart1
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart?, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
return ch;
}
As pointed out by Fra93, you need to implement UART/USART protocol communication and print stuff to there. I'm writing this reply, because I'm getting a feeling you have some basic experience writing desktop applications, but not embedded, so I will clarify a few points.
There is no console to print to. There are no logs. They simply don't exist. At all. Not in a desktop app development sense.
What's usually done is that one of the UARTs of the MCU is used to print characters to the ST-Link, which converts it to USB (alternatively, can be FTDI IC, CP2102 or other USB-UART bridges/converters). So then your MCU will send out characters over UART, and the USB-UART converter will display them in a COM port terminal (programs like PuTTy)
If you start with empty project and no external libraries used, you will need 3 dozen lines of code alone just to be able to print stuff. Initially, you have nothing. You have to initialize UART, configure it, then implement how it handles characters, numbers. You need to literally write a basic UART driver. And you can call printing function whatever you want. You can call it Log("hello world"), you can call it Whisper("hi there"). Because you will actually create this function. You're the boss.
Now, given you are not very familiar with all of this, it may sound like a difficult task. And it most certainly is. Writing a driver from scratch on your day 1 is not a thing you want to do (unless you're into that kind of stuff on day 1).
I would strongly advise you to get some library, such as HAL by STMicroelectronics, and familiarize yourself with what it can do - including how to print stuff with UART. Internet is flooded with articles and videos of how to use UART with HAL, it's literally one of the first things to be implemented. Specifically for the reason, that it works like logs and simplifies further development/learning.
So, in order to get "logs" working, I would do the following:
Get HAL for your specific MCU
Familiarize yourself with UART - basic stuff about what it is and how it works. No need to be an expert, just learn what it is.
Familiarize yourself with how to use UART with HAL
From the schematic of the PCB of your nucleo board, find out which UART of the MCU is connected to ST-Link (I checked the schematic: it's USART3)
Get serial port (COM) terminal program for your computer
Use HAL to initialize USART3 and print to USART3. Whatever you print there will be visible in the terminal. Yes, you will not see anything in the IDE. You need a separate program to display what you receive via USB COM port.
In the end, your print function will be the one proposed by Fra93. HAL_UART_Transmit is the most basic HAL function to send stuff via UART. If you're very picky about using "Log" as a function you call to print via UART, you can always wrap HAL_UART_Transmit into your own function called Log.
I am using STM32 cubeMX for configuration and Keil for programming.
Have set onboard led pin pc13 pin as an output pin and default in push-pull mode. Set debugger to the serial wire as I am using ST-link V2 as a debugger. RCC set HSE to crystal/ceramic resonator.
and clock configuration set to default and generated project.
Now I started with a simple LED blink program. As below
HAL_GPIO_TogglePin(led_GPIO_Port,led_Pin);
HAL_Delay(1000);
build successfully with no error and uploaded and wonder my led was not blinking and shocked as I have done this before and now this is not working.
when I debugged step by step and my code was just going from two functions repeatedly.
while ((HAL_GetTick() - tickstart) < wait)
{
}
__weak uint32_t HAL_GetTick(void)
{
return uwTick;
}
Nothing happens more in this code I know the code is right but there is some error in the HAL_delay configuration.
After scratching my head for a day I tried uploading the following code
HAL_GPIO_TogglePin(led_GPIO_Port,led_Pin);
HAL_Delay(100);
And strange thing is that now my led is blinking only I have change the HAL_dealy value from 1000 to 100 and it works fine but, when using 1000 does not work at all.
So for testing, I gradually increased the delay value and I find that more than HAL_delay(400) it does not work.
Not able to find cause for this Any help will be appreciable.
As suggested by Tom I debugged uwTickFreq using STstudio.
and I got the following output waveform.
After that, I also uploaded the following code. And defined a variable as "unsigned long int a;"
HAL_GPIO_TogglePin(led_GPIO_Port,led_Pin);
HAL_Delay(100);
a= HAL_GetTick();
Now I debugged the value of a using STstudio. And strange the value of a becomes 0 once it reached around 300.
It seems like finally, I got the problem when I noticed the reset problem in the controller I searched around and find something here.
So I checked my optional bytes set in MCU with the STM32 cube programmer.
It was set as below.
Therefore I enabled these three optional bytes.
And the problem of reset was gone and I am now able to use the HAL_delay function properly and now the value of HAL_GetTick() is also increasing more than 300.
Still have one dought I think watchdog was causing reset but why it only cause that when I use the timing function.
I am writing a kernel module to read and write to SPI device (CC1200).
My linux device does not have native SPI, so I am trying to bit-bang the bus.
I found that linux has built-in bitbang code (linux/spi/spi_bitbang.h), but I am confused how to set it up. It needs structs as spi_device and spi_master, each requiring struct device, which requires structs as kobject and many many more, most of them I have no idea what to do with them, and how they are needed for simple bit-banging.
I have looked online for examples, but i found literally none. Not a single use of the included bitbang code, only some references that it is "easy"
I will be very thankful for any help, maybe the bitbang lib is not even the good path. Maybe I can write my own (how to do it efficiently? I have 4 cores, but it is running lots of stuff in the background)
Thanks
Because of the nature of SPI where data is clocked and read by the master there is nothing wrong with the bit banging driver for the master, as the slave should not relay on a stable clock. But of course it depends on the slave device if this will work in practice or not.
If you are using the linux kernel there is no need to implement your own bit-banging driver as there already is one spi-gpio.c
My guess how to get it up and running would be by defining what GPIO pins to use in the devicetree, then the driver would be able to act as any of the other physical layer drivers.
I had a quick glance at drivers/spi/spi-gpio.c source code, and there is even a short user guide how to directly access the GPIO pins inline without using the generic GPIO layer overhead.
/*
* Because the overhead of going through four GPIO procedure calls
* per transferred bit can make performance a problem, this code
* is set up so that you can use it in either of two ways:
*
* - The slow generic way: set up platform_data to hold the GPIO
* numbers used for MISO/MOSI/SCK, and issue procedure calls for
* each of them. This driver can handle several such busses.
*
* - The quicker inlined way: only helps with platform GPIO code
* that inlines operations for constant GPIOs. This can give
* you tight (fast!) inner loops, but each such bus needs a
* new driver. You'll define a new C file, with Makefile and
* Kconfig support; the C code can be a total of six lines:
*
* #define DRIVER_NAME "myboard_spi2"
* #define SPI_MISO_GPIO 119
* #define SPI_MOSI_GPIO 120
* #define SPI_SCK_GPIO 121
* #define SPI_N_CHIPSEL 4
* #include "spi-gpio.c"
*/
PS are you sure your platform does not have spi, all the SoC I have worked with from HiSilicon have had one. I would double check this first
EDIT: It seems they've changed the interface and you can't do this any more in modern kernels from 4.19 and later, for the same reason you can't do it with i2c.
https://forum.openwrt.org/t/i2c-kernel-4-19-i2c-gpio-custom/49213
I will leave this here for now, perhaps it will be useful. I myself am using older kernels for home automation but it's on a private network.
My original answer:
Whilst you can probably get this working by hacking your own kernel module together instead you can investigate spi-gpio-custom, simply load the module and pass the pins you want to use as parameters, you can do everything at run-time and don't need to 'compile-in' the pins you want to use. You can find this module in the OpenWrt project:
https://github.com/openwrt/openwrt/tree/openwrt-19.07/package/kernel/spi-gpio-custom/src
I would expect that to give you some kind of SPI device when initialised that you can write to from user-space. Note that I haven't used this module myself, but some time ago I've used the i2c counterpart which works in similar way.
Alternatively, you could consider introducing an Arduino to talk to your SPI bus then translate the SPI data into something your Linux device understands.
The Nano board will probably do what you need and costs peanuts if you don't want to make up your own board.
Then for the interface, you would then have a few choices: USB, UART, i2c or 1wire even a parallel interface if you have the pins. There is a 1-wire slave library on github for instance: https://github.com/smurfix/owslave.
I am currently working on a project to select different outputs based on a text input from a laptop via USB.
What I am currently trying to do is send a character out from my PIC18F1320 to HyperTerminal, I have tried using variables but was recieveing rnadom characters such as smiley faces etc.
I simplified my code to simply print a 1 however I am still recieving smily face symbols. I have checked that I am using the correct baud rate and there is definite communication between my laptop and the PIC, however at this point I am completely stuck as I have no idea why random characters are being output.
I have extremely little knowledge of C and any help would be appreciated
#include <p18f1320.h>
#include <usart.h>
#include <stdio.h>
#include <stdlib.h>
void main()
{
OSCCON = 0x70; // 8MHz internal clock
// Configure USART
OpenUSART( USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_LOW,
12);
while (1)
{
putrsUSART("1");
}
CloseUSART();
}
The internal RC oscillator on the PIC is not precise enough to run the USART at the desired speed - it can vary by ±2% from the expected frequency, which is probably far out enough to be causing the errors you're seeing. You will need to attach and configure an external crystal for correct results.
Put your data in RAM and send. See Harvard Architecture
char buf[10];
strcpy(buf, "Hello\n"); // This should cal special ROM to RAM strcpy();
putrsUSART(buf);
Note: "I have checked that I am using the correct baud rate" may not be right. Until you received valid data, I would not be too confident about this.