This is repo is designed for specifically for the BeagleBone Black running kernel 6.0.
The repo provides the libioctrl library which is designed to provide an interface for controlling GPIO, PWM, and ADC peripherals. It includes functions to read from and write to the GPIO pins, set PWM values, and read from ADC channels. The library can be linked both as a static and a shared library for flexibility in different project environments.
- GPIO Control: Functions for reading and writing to GPIO pins.
- PWM Control: Functions for setting PWM output on specified pins.
- ADC Read: Functions to retrieve ADC readings from specified channels.
- Support for both static and shared linking.
├── include # Header files for the library
│ ├── bbb_adc.h
│ ├── bbb_gpio.h
│ ├── bbb_pwm.h
│ ├── libioctrl.h
├── src # Source files for the library
│ ├── bbb_adc.c
│ ├── bbb_gpio.c
│ ├── bbb_pwm.c
├── Makefile # Makefile to build and install the library
└── README.md # Project documentation
Make sure you have the following tools installed on your system:
gcc12.2.0make4.3- Root access for installation
Just run the install.sh as it will ask for root:
$ debian@beaglebone:~/c_libraries/bb.black_pin_library$ bash install.sh
[1/3] Cleaning build files, if they exist...
rm -rf ./obj libioctrl.a libioctrl.so
[2/3] Uninstalling globally installed libioctrl libraries, root access requried...
sudo rm -f /usr/include/bbb_gpio.h /usr/include/bbb_pwm.h /usr/include/bbb_adc.h /usr/include/libioctrl.h
sudo rm -f /usr/lib/libioctrl.a /usr/lib/libioctrl.so ./obj
sudo ldconfig
[3/3] Compiling, and installing globally, root access required...
gcc -Wall -Werror -fPIC -I./include -c src/bbb_gpio.c -o obj/bbb_gpio.o
gcc -Wall -Werror -fPIC -I./include -c src/bbb_pwm.c -o obj/bbb_pwm.o
gcc -Wall -Werror -fPIC -I./include -c src/bbb_adc.c -o obj/bbb_adc.o
ar rcs libioctrl.a ./obj/bbb_gpio.o ./obj/bbb_pwm.o ./obj/bbb_adc.o
gcc -shared -o libioctrl.so ./obj/bbb_gpio.o ./obj/bbb_pwm.o ./obj/bbb_adc.o
sudo cp include/bbb_gpio.h include/bbb_pwm.h include/bbb_adc.h include/libioctrl.h /usr/include/
sudo cp libioctrl.a libioctrl.so /usr/lib/
sudo ldconfigTo build both the static and shared libraries:
make allTo install the library and header files to the system directories:
sudo make installThis installs:
- The header files (
bbb_gpio.h,bbb_pwm.h,bbb_adc.h,libioctrl.h) into/usr/include/ - The static library (
libioctrl.a) and shared library (libioctrl.so) into/usr/lib/
To clean up the compiled object files and libraries:
make cleanExample programs can be found in the examples_C/ directory. Below are examples of the the code:
An example progam, blink.c, demonstrates how to use the library:
#include <libioctrl.h>
#include <unistd.h>
#include <stdio.h>
int main(void) {
// Open P9_12 as output, initial value 0 (off)
BbbGpio *led = bbb_open("P9_12", true, 0, "blink");
if (!led) {
fprintf(stderr, "Failed to open GPIO\n");
return 1;
}
// Blink LED 5 times
for (int i = 0; i < 5; i++) {
bbb_write(led, 1); // LED on
usleep(500000);
bbb_write(led, 0); // LED off
usleep(500000);
}
bbb_close(led);
return 0;
}To compile and run the blink example:
$ gcc -Wall -o blink blink.c -lioctrl -I/usr/include
$ ./blinkAn example program, adc_read.c, demonstrates how to use the library:
#include <libioctrl.h>
#include <stdio.h>
#include <unistd.h>
int main(){
unsigned int i = 0;
unsigned int adc_reading = 0;
while(i < 30){
adc_get_value(0, &adc_reading);
printf("ADC: %u\n ",adc_reading);
i++;
sleep(1);
}
return 0;
}To compile and run the adc_read example:
$ gcc -Wall -o adc_read adc_read.c -lioctrl -I/usr/include
$ ./adc_readAn example program, adc_continuous_read.c, demonstrates how to use the library:
#include <libioctrl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s <adcPin> <bufferLength>\n", argv[0]);
return EXIT_FAILURE;
}
unsigned int adcPin = atoi(argv[1]);
unsigned int bufferLength = atoi(argv[2]);
unsigned int adcValue;
float voltage;
// Enable buffer and set buffer length
if (enable_buffer() < 0) {
fprintf(stderr, "Error enabling buffer.\n");
return EXIT_FAILURE;
}
if (set_buffer_length(bufferLength) < 0) {
fprintf(stderr, "Error setting buffer length.\n");
disable_buffer();
return EXIT_FAILURE;
}
// Enable ADC channel
if (enable_channel(adcPin) < 0) {
fprintf(stderr, "Error enabling ADC channel %u.\n", adcPin);
disable_buffer();
return EXIT_FAILURE;
}
printf("Starting continuous ADC read on pin %u...\n", adcPin);
// Continuous read loop
for (int i = 0; i < bufferLength; i++) {
if (adc_get_buffer(adcPin, &adcValue) == 0) {
adc_to_voltage(adcValue, &voltage);
printf("ADC Value: %u, Voltage: %.3f V\n", adcValue, voltage);
} else {
fprintf(stderr, "Error reading buffer for ADC pin %u.\n", adcPin);
break;
}
//usleep(500000); // Delay between reads (adjust as needed, e.g., 500 ms)
}
// Cleanup: disable buffer and channel
disable_channel(adcPin);
disable_buffer();
printf("Continuous ADC read completed.\n");
return EXIT_SUCCESS;
}To compile and run the adc_continuous_read example:
$ gcc -Wall -o adc_continuous_read adc_continuous_read.c -lioctrl -I/usr/include
$ ./adc_continuous_readAn example program, pwm_test.c, demonstrates how to use the library:
#include <libioctrl.h>
#include <string.h>
#include <unistd.h>
int main() {
PWM pwm;
int period = 1000000; // Set period to 1 ms (1 kHz)
int duty = 1000000; // Set duty cycle to 0.5 ms (50%)
// Initialize the PWM structure for chip 0, channel 0
pwm_init(&pwm, "P9_14");
printf("Phy: %s\nChannel: %s\nChip: %s\nPeriod path: %s\nDuty Cycle path: %s\nEnable path: %s\n",
pwm.phy_pin,
pwm.channel,
pwm.chip,
pwm.period_path,
pwm.duty_cycle_path,
pwm.enable_path);
pwm_set_period(&pwm, period);
pwm_set_duty_cycle(&pwm, duty);
pwm_enable(&pwm);
sleep(2);
pwm_set_duty_cycle(&pwm, 500000);
sleep(2);
pwm_set_duty_cycle(&pwm, 200000);
sleep(2);
pwm_set_duty_cycle(&pwm, 100000);
pwm_disable(&pwm);
pwm_cleanup(&pwm);
return 0;
}To compile and run the pwm_test example:
$ gcc -Wall -o pwm_test pwm_test.c -lioctrl -I/usr/include
$ ./pwm_testAn example program, adc2pwm.c, demonstrates how to use the library:
#include <libioctrl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
int main() {
PWM pwm;
unsigned int adc_reading = 0;
unsigned int user_defined_period_ns = 1000000; // User-defined period in nanoseconds (1 ms for 1 kHz)
unsigned int duty_cycle = 0;
// Initialize PWM on a specified pin, for example "P8_13"
pwm_init(&pwm, "P9_14");
// Set initial PWM period
pwm_set_period(&pwm, user_defined_period_ns);
// Enable PWM output
pwm_enable(&pwm);
printf("Phy: %s\nChannel: %s\nChip: %s\nPeriod path: %s\nDuty Cycle path: %s\nEnable path: %s\n",
pwm.phy_pin,
pwm.channel,
pwm.chip,
pwm.period_path,
pwm.duty_cycle_path,
pwm.enable_path);
// Loop to read ADC values and update PWM duty cycle
for (int i = 0; i < 30; i++) {
adc_get_value(0, &adc_reading); // Read ADC value from channel 0
printf("ADC Reading: %u\n", adc_reading);
// Map the ADC reading to the PWM duty cycle and update it
duty_cycle = map(adc_reading, user_defined_period_ns);
pwm_set_duty_cycle(&pwm, duty_cycle);
sleep(1); // Update every 1 second
}
// Disable PWM and clean up
pwm_disable(&pwm);
pwm_cleanup(&pwm);
return 0;
}To compile and run the adc2pwm.c example:
$ gcc -Wall -o adc2pwm adc2pwm.c -lioctrl -I/usr/include
$ ./adc2pwmTo uninstall the library and header files:
sudo make uninstallThis removes:
- Header files from
/usr/include/ - Libraries from
/usr/lib/
This project is licensed under the MIT License.
Contributions are welcome! Feel free to open issues or submit pull requests.