jadedanemone / bbb-eqep Goto Github PK
View Code? Open in Web Editor NEWFast interface to the Beaglebone Black's eQEP modules for reading quadrature encoders.
License: GNU General Public License v2.0
Fast interface to the Beaglebone Black's eQEP modules for reading quadrature encoders.
License: GNU General Public License v2.0
Hi,
I am running ubuntu 16.04 on beaglebone black from a uSD. It seems from the newer kernels (3.14/15) onwards, the overlays are loaded during bootup or something similar. I tried enabling the fast eqep dtbo by adding the corresponding entry to /boot/uEnv.txt, but during bootup, it fails to load the same and fails to boot. Here is a snippet of the boot log captured from the UART header.
9640976 bytes read in 635 ms (14.5 MiB/s) uboot_overlays: [uboot_base_dtb=am335x-boneblack-uboot.dtb] ... uboot_overlays: Switching too: dtb=am335x-boneblack-uboot.dtb ... loading /boot/dtbs/4.9.54-ti-r68/am335x-boneblack-uboot.dtb ... 55752 bytes read in 89 ms (611.3 KiB/s) uboot_overlays: [fdt_buffer=0x60000] ... uboot_overlays: loading /lib/firmware/BB-UART1-00A0.dtbo ... 883 bytes read in 862 ms (1000 Bytes/s) uboot_overlays: loading /lib/firmware/BB-UART4-00A0.dtbo ... 883 bytes read in 712 ms (1000 Bytes/s) uboot_overlays: loading /lib/firmware/BB-UART2-00A0.dtbo ... 883 bytes read in 464 ms (1000 Bytes/s) uboot_overlays: loading /lib/firmware/BB-UART5-00A0.dtbo ... 883 bytes read in 851 ms (1000 Bytes/s) uboot_overlays: loading /lib/firmware/fast_eqep0-00A0.dtbo ... 997 bytes read in 429 ms (2 KiB/s) fdt_overlay_apply(): FDT_ERR_BADOVERLAY uboot_overlays: loading /lib/firmware/BB-BONE-eMMC1-01-00A0.dtbo ... 1105 bytes read in 227 ms (3.9 KiB/s) libfdt fdt_check_header(): FDT_ERR_BADMAGIC fdt_overlay_apply(): FDT_ERR_BADMAGIC uboot_overlays: loading /lib/firmware/BB-HDMI-TDA998x-00A0.dtbo ...
Here's the output of uname -a
for more information
Linux arm 4.9.54-ti-r68 #1 SMP PREEMPT Tue Oct 10 10:05:30 UTC 2017 armv7l armv7l armv7l GNU/Linux
However it works with the debian-8.6-iot image that is currently on the EMMC. I need this library to work on the ubuntu image for a ROS related project.
Thank you in anticipation!
Hi James..
I'm trying to use your library to read more than one encoder in BBB.
I load the capes with commands below.
echo fast_eqep0 > /sys/devices/bone_capemgr.*/slots
echo fast_eqep1 > /sys/devices/bone_capemgr.*/slots
echo fast_eqep2 > /sys/devices/bone_capemgr.*/slots
This is the dmsg output after loading the capes.
[ 19.650176] IPv6: ADDRCONF(NETDEV_UP): usb0: link is not ready
[ 1073.141598] bone-capemgr bone_capemgr.9: part_number 'fast_eqep0', version 'N/A'
[ 1073.143325] bone-capemgr bone_capemgr.9: slot #7: generic override
[ 1073.143382] bone-capemgr bone_capemgr.9: bone: Using override eeprom data at slot 7
[ 1073.143430] bone-capemgr bone_capemgr.9: slot #7: 'Override Board Name,00A0,Override Manuf,fast_eqep0'
[ 1073.145125] bone-capemgr bone_capemgr.9: slot #7: Requesting part number/version based 'fast_eqep0-00A0.dtbo
[ 1073.145182] bone-capemgr bone_capemgr.9: slot #7: Requesting firmware 'fast_eqep0-00A0.dtbo' for board-name 'Override Board Name', version '00A0'
[ 1073.148160] bone-capemgr bone_capemgr.9: slot #7: dtbo 'fast_eqep0-00A0.dtbo' loaded; converting to live tree
[ 1073.148649] bone-capemgr bone_capemgr.9: slot #7: #3 overlays
[ 1073.159827] bone-capemgr bone_capemgr.9: slot #7: Applied #3 overlays.
[ 1093.624778] bone-capemgr bone_capemgr.9: part_number 'fast_eqep1', version 'N/A'
[ 1093.624952] bone-capemgr bone_capemgr.9: slot #8: generic override
[ 1093.624998] bone-capemgr bone_capemgr.9: bone: Using override eeprom data at slot 8
[ 1093.625046] bone-capemgr bone_capemgr.9: slot #8: 'Override Board Name,00A0,Override Manuf,fast_eqep1'
[ 1093.625321] bone-capemgr bone_capemgr.9: slot #8: Requesting part number/version based 'fast_eqep1-00A0.dtbo
[ 1093.625369] bone-capemgr bone_capemgr.9: slot #8: Requesting firmware 'fast_eqep1-00A0.dtbo' for board-name 'Override Board Name', version '00A0'
[ 1093.629267] bone-capemgr bone_capemgr.9: slot #8: dtbo 'fast_eqep1-00A0.dtbo' loaded; converting to live tree
[ 1093.629755] bone-capemgr bone_capemgr.9: slot #8: #3 overlays
[ 1093.636806] bone-capemgr bone_capemgr.9: slot #8: Applied #3 overlays.
[ 1115.758636] bone-capemgr bone_capemgr.9: part_number 'fast_eqep2', version 'N/A'
[ 1115.758822] bone-capemgr bone_capemgr.9: slot #9: generic override
[ 1115.758870] bone-capemgr bone_capemgr.9: bone: Using override eeprom data at slot 9
[ 1115.759116] bone-capemgr bone_capemgr.9: slot #9: 'Override Board Name,00A0,Override Manuf,fast_eqep2'
[ 1115.761888] bone-capemgr bone_capemgr.9: slot #9: Requesting part number/version based 'fast_eqep2-00A0.dtbo
[ 1115.761950] bone-capemgr bone_capemgr.9: slot #9: Requesting firmware 'fast_eqep2-00A0.dtbo' for board-name 'Override Board Name', version '00A0'
[ 1115.765462] bone-capemgr bone_capemgr.9: slot #9: dtbo 'fast_eqep2-00A0.dtbo' loaded; converting to live tree
[ 1115.765961] bone-capemgr bone_capemgr.9: slot #9: #3 overlays
[ 1115.773578] bone-capemgr bone_capemgr.9: slot #9: Applied #3 overlays.
Modified test.cpp file
/**
* This example program demonstrates the use of the BBB-eQEP library.
* Copyright (C) 2014 James Zapico <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <sys/time.h>
#include <bbb-eqep.h>
using std::cout;
using std::endl;
using std::cerr;
using namespace BBB;
int main (int argc, char const *argv[])
{
struct timeval tv1, tv2;
int eqep_num;
uint32_t eqep_pos, eqep0_pos, eqep1_pos, eqep2_pos;
eQEP eqep(eQEP0);
eQEP eqep1(eQEP1);
eQEP eqep2(eQEP2);
printf("0000000000000000000000000000000000000000000000000000000000000000000000\n");
printf("SYSCONFIG 0x%X\n", *(uint32_t*)(eqep.getPWMSSPointer() + PWM_SYSCONFIG));
printf("CLKCONFIG 0x%X\n", *(uint32_t*)(eqep.getPWMSSPointer()+PWM_CLKCONFIG));
printf("QEPCTL0 0x%X\n", eqep.getControl());
printf("QDECCTL0 0x%X\n", eqep.getDecoderControl());
printf("QEINT0 0x%X\n", eqep.getInterruptEnable());
printf("QUPRD0 0x%u\n", eqep.getUnitPeriod());
printf("QPOSMAX0 0x%X\n", eqep.getMaxPos());
printf("QEPSTS0 0x%X\n", eqep.getStatus());
eqep0_pos = eqep;
printf("\n1111111111111111111111111111111111111111111111111111111111111111111111\n");
printf("SYSCONFIG 0x%X\n", *(uint32_t*)(eqep1.getPWMSSPointer() + PWM_SYSCONFIG));
printf("CLKCONFIG 0x%X\n", *(uint32_t*)(eqep1.getPWMSSPointer()+PWM_CLKCONFIG));
printf("QEPCTL0 0x%X\n", eqep1.getControl());
printf("QDECCTL0 0x%X\n", eqep1.getDecoderControl());
printf("QEINT0 0x%X\n", eqep1.getInterruptEnable());
printf("QUPRD0 0x%u\n", eqep1.getUnitPeriod());
printf("QPOSMAX0 0x%X\n", eqep1.getMaxPos());
printf("QEPSTS0 0x%X\n", eqep1.getStatus());
eqep1_pos = eqep1;
printf("\n2222222222222222222222222222222222222222222222222222222222222222222222222\n");
printf("SYSCONFIG 0x%X\n", *(uint32_t*)(eqep2.getPWMSSPointer() + PWM_SYSCONFIG));
printf("CLKCONFIG 0x%X\n", *(uint32_t*)(eqep2.getPWMSSPointer()+PWM_CLKCONFIG));
printf("QEPCTL0 0x%X\n", eqep2.getControl());
printf("QDECCTL0 0x%X\n", eqep2.getDecoderControl());
printf("QEINT0 0x%X\n", eqep2.getInterruptEnable());
printf("QUPRD0 0x%u\n", eqep2.getUnitPeriod());
printf("QPOSMAX0 0x%X\n", eqep2.getMaxPos());
printf("QEPSTS0 0x%X\n", eqep2.getStatus());
eqep2_pos = eqep2;
//time a read-loop to assess speed
int num_reads = 1000000;
int i;
gettimeofday(&tv1,NULL);
for(i=0;i<num_reads;i++){
eqep_pos = eqep.getPosition();
eqep1_pos = eqep1.getPosition();
eqep2_pos = eqep2.getPosition();
}
gettimeofday(&tv2,NULL);
//find difference between start and end time
unsigned long dt_micros = (1000000 * tv2.tv_sec + tv2.tv_usec)-(1000000 * tv1.tv_sec + tv1.tv_usec);
float time_per_read = (float)dt_micros/num_reads;
float change_rate = (float)(num_reads)/((float)(dt_micros)) * 1000;
printf("Eqep0 last position: %i\n", eqep_pos);
printf("Eqep1 last position: %i\n", eqep1_pos);
printf("Eqep2 last position: %i\n", eqep2_pos);
printf("micros per read: %f\n", time_per_read);
printf("quadrature read rate (kHz): %f\n",change_rate);
printf("Eqep0:revid: 0x%X (should read 44D31103)\n",eqep.getRevisionID());
printf("Eqep1:revid: 0x%X (should read 44D31103)\n",eqep1.getRevisionID());
printf("Eqep2:revid: 0x%X (should read 44D31103)\n",eqep2.getRevisionID());
for(i=0;i<10000000;i++){
printf("\reqep0: %zu eqep1: %zu eqep2: %zu ",eqep.getPosition(),eqep1.getPosition(),eqep2.getPosition() );
usleep(5000);
}
printf("\n");
return 0;
}
When I compile and run the code there are no errors. However this is the output of test app:
root@arm:~/DEV/BBB-eQEP/examples# ./test
0000000000000000000000000000000000000000000000000000000000000000000000
SYSCONFIG 0xC
CLKCONFIG 0x111
QEPCTL0 0x8
QDECCTL0 0x0
QEINT0 0x0
QUPRD0 0x0
QPOSMAX0 0xFFFFFFFF
QEPSTS0 0xA0
1111111111111111111111111111111111111111111111111111111111111111111111
SYSCONFIG 0xC
CLKCONFIG 0x111
QEPCTL0 0x8
QDECCTL0 0x0
QEINT0 0x0
QUPRD0 0x0
QPOSMAX0 0xFFFFFFFF
QEPSTS0 0x20
2222222222222222222222222222222222222222222222222222222222222222222222222
SYSCONFIG 0xC
CLKCONFIG 0x111
QEPCTL0 0x8
QDECCTL0 0x0
QEINT0 0x0
QUPRD0 0x0
QPOSMAX0 0xFFFFFFFF
QEPSTS0 0x20
Eqep0 last position: 106
Eqep1 last position: 0
Eqep2 last position: 0
micros per read: 0.686577
quadrature read rate (kHz): 1456.500854
Eqep0:revid: 0x44D31103 (should read 44D31103)
Eqep1:revid: 0x44D31103 (should read 44D31103)
Eqep2:revid: 0x44D31103 (should read 44D31103)
eqep0: 93 eqep1: 0 eqep2: 0
I can only read eqep0 values.
Strange thing is, if I load the capes with different order like first loading eqep1 then the rest, I can read encoder values attached to eqep1 pins.
Is there anything that I'm missing here? Can you guide me to accomplish reading more than one encoders at the same time?
Ps: I am using Debian with 3.8.13-bone60 kernel.
For example,
setDecoderControl(
// Ensure both bits are off
(getDecoderControl() & ~(EQEP_QDECCTL_QSRC(3)))
// Then set whichever need to be on again
& (source << 14));
I think it should be
setDecoderControl(
// Ensure both bits are off
(getDecoderControl() & ~(EQEP_QDECCTL_QSRC(3)))
// Then set whichever need to be on again
| (source << 14));
(The last & changed to |)
This structure is repeated several times.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.