Skip to content

Commit

Permalink
Add BeagleBone AI support (#183)
Browse files Browse the repository at this point in the history
* Add BeagleBone AI model
* Update ADC code for BeagleBone AI channel mapping
* Add AM5729 PRU firmware, servo outputs working
* Do not track firmware binaries in git
* Remove redundant C files. These separate main files were just copies of each other and just do the same setup before calling _start.

PRU notes:
* Note that C28 probably does need setup to access the share memory.
* Note that the OCP is not likely ever accessed, nor should it be enabled. It opens us up to bugs and these modules should be using their own pins and local memories (which the ARM can see without enabling us to reach out).
  • Loading branch information
jadonk authored Jun 3, 2020
1 parent a7d69c9 commit 99a08db
Show file tree
Hide file tree
Showing 21 changed files with 574 additions and 148 deletions.
2 changes: 2 additions & 0 deletions examples/src/rc_test_servos.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,12 @@ int main(int argc, char *argv[])
switch(mode){

case NORM:
//printf("calling pulse_normalized %d -> %f\n", ch, servo_pos);

This comment has been minimized.

Copy link
@jadonk

jadonk Jun 3, 2020

Author Member

Might want to turn these back on.

if(rc_servo_send_pulse_normalized(ch,servo_pos)==-1) return -1;
break;

case MICROSECONDS:
//printf("calling pulse_us %d -> %d\n", ch, width_us);
if(rc_servo_send_pulse_us(ch, width_us)==-1) return -1;
break;

Expand Down
26 changes: 20 additions & 6 deletions library/include/rc/adc.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,31 @@
* follows:
*
* - 1 - Ground
* - 2 - VDD_ADC (1.8V)
* - 3 - AIN0
* - 4 - AIN1
* - 5 - AIN2
* - 6 - AIN3
* - 2 - VDD_ADC (1.8V) (optional 3.3V on BeagleBone AI)
* - 3 - AIN0 (4 on BeagleBone AI)
* - 4 - AIN1 (6 on BeagleBone AI)
* - 5 - AIN2 (7 on BeagleBone AI)
* - 6 - AIN3 (5 on BeagleBone AI)
*
* All 8 ADC channels on the Sitara including the 4 listed above can be read
* with rc_adc_read_raw(int ch) which returns the raw integer output of the
* 12-bit ADC. rc_adc_read_volt(int ch) additionally converts this raw value to
* a voltage.
*
* On BeagleBone AI, the on-board ADC is replaced with an SMTPE811. The pin
* mapping was done in a way to support touch screens and the channels are
* all swiveled around. The ADC2AI() macro will swivel using this table:
*
* AM3358 - AI
* 0 - 0 (X+)
* 1 - 1 (X-)
* 2 - 3 (Y-)
* 3 - 2 (Y+)
* 4 - 7 (IN3)
* 5 - 6 (IN2)
* 6 - 4 (IN0)
* 7 - 5 (IN1 - grounded on BeagleBone AI)
*
* See the rc_test_adc example for sample use case.
*
* @addtogroup ADC
Expand Down Expand Up @@ -94,4 +108,4 @@ double rc_adc_dc_jack(void);

#endif // RC_ADC_H

/** @} end group ADC*/
/** @} end group ADC*/
4 changes: 2 additions & 2 deletions library/include/rc/model.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ typedef enum rc_model_t{
MODEL_RPI_CM,
MODEL_RPI_CM3,
MODEL_PC,
MODEL_BB_AM57,
MODEL_BB_AM57_RC,
MODEL_BB_AI,
MODEL_BB_AI_RC
} rc_model_t;


Expand Down
10 changes: 6 additions & 4 deletions library/include/rc/pru.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ extern "C" {
* and "am335x-pru1-fw", please don't overwrite these if they exist. Name your
* firmware image something like "am335x-pru0-mycustom-fw".
*
* @param[in] ch pru core to start (0 or 1)
* @param[in] ch pru core to start (0 or 1 on AM3, 2-5 on AM5)
* @param[in] fw_name The firmware image name, e.g. "am335x-pru0-fw", do not
* include '/lib/firmware' in the path, only the file name.
*
Expand All @@ -42,15 +42,17 @@ int rc_pru_start(int ch, const char* fw_name);
* This is done by mapping to /dev/mem and therefore requires root privileges
* but provides extremely low-latency memory access to communicate with the PRU.
*
* @param[in] ch pru core to reference (0 or 1 on AM3, 2-5 on AM5)
*
* @return memory pointer on success, NULL on failure
*/
volatile uint32_t* rc_pru_shared_mem_ptr(void);
volatile uint32_t* rc_pru_shared_mem_ptr(int ch);


/**
* Unloads pru binaries
*
* @param[in] ch pru core to stop (0 or 1)
* @param[in] ch pru core to stop (0 or 1 on AM3, 2-5 on AM5)
*
* @return 0 on success, -1 on failure.
*/
Expand All @@ -63,4 +65,4 @@ int rc_pru_stop(int ch);

#endif // RC_PRU_H

/** @} end group PRU */
/** @} end group PRU */
12 changes: 10 additions & 2 deletions library/src/io/adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <fcntl.h> // for open
#include <unistd.h> // for close
#include <rc/adc.h>
#include <rc/model.h>

// preposessor macros
#define unlikely(x) __builtin_expect (!!(x), 0)
Expand All @@ -24,6 +25,7 @@
#define V_DIV_RATIO 11.0
#define BATT_DEADZONE 1.0

#define ADC2AI(x) (x==0?0:(x==1?1:(x==2?3:(x==3?2:(x==4?7:(x==5?6:(x==6?4:(x==7?5:-1))))))))

#define CHANNELS 8
#define IIO_DIR "/sys/bus/iio/devices/iio:device0"
Expand All @@ -42,7 +44,10 @@ int rc_adc_init(void)
if(init_flag) return 0;

for(i=0;i<CHANNELS;i++){
snprintf(buf, sizeof(buf), IIO_DIR "/in_voltage%d_raw", i);
if(rc_model()==MODEL_BB_AI || rc_model()==MODEL_BB_AI_RC)
snprintf(buf, sizeof(buf), IIO_DIR "/in_voltage%d_raw", ADC2AI(i));
else
snprintf(buf, sizeof(buf), IIO_DIR "/in_voltage%d_raw", i);
temp_fd = open(buf, O_RDONLY);
if(temp_fd<0){
perror("ERROR in rc_adc_init, failed to open iio adc interface\n");
Expand Down Expand Up @@ -100,7 +105,10 @@ double rc_adc_read_volt(int ch)
{
int raw = rc_adc_read_raw(ch);
if(raw<0) return -1;
return raw * 1.8 / 4095.0;
if(rc_model()==MODEL_BB_AI || rc_model()==MODEL_BB_AI_RC)
return raw * 0.805664062 / 1000.0; // * in_voltage_scale = mV
else
return raw * 1.8 / 4095.0;
}


Expand Down
2 changes: 1 addition & 1 deletion library/src/io/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#define likely(x) __builtin_expect (!!(x), 1)

#define DEVICE_BASE "/dev/gpiochip"
#define CHIPS_MAX 6 // up to 6 chip chips, make larger if you want
#define CHIPS_MAX 10 // up to 10 chip chips, make larger if you want
#define MAX_BUF 64


Expand Down
2 changes: 1 addition & 1 deletion library/src/led.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#define unlikely(x) __builtin_expect (!!(x), 0)


#define SYSFS_LED_DIR "/sys/devices/platform/leds/leds/"
#define SYSFS_LED_DIR "/sys/class/leds/"
#define BRIGHTNESS_FILE "/brightness"
#define MAX_BUF 128
#define NUM_LEDS 11
Expand Down
10 changes: 10 additions & 0 deletions library/src/model.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ static void __check_model(void)

current_category = CATEGORY_BEAGLEBONE;

if(strcmp(c, "BeagleBoard.org BeagleBone AI")==0){
current_model = MODEL_BB_AI;
return;
}
if(strcmp(c, "BeagleBoard.org BeagleBone AI RoboticsCape")==0){
current_model = MODEL_BB_AI_RC;
return;
}
if(strcmp(c, "TI AM335x BeagleBone Black")==0){
current_model = MODEL_BB_BLACK;
return;
Expand Down Expand Up @@ -190,6 +198,8 @@ void rc_model_print(void)
switch(model){

caseprint(MODEL_UNKNOWN)
caseprint(MODEL_BB_AI)
caseprint(MODEL_BB_AI_RC)
caseprint(MODEL_BB_BLACK)
caseprint(MODEL_BB_BLACK_RC)
caseprint(MODEL_BB_BLACK_W)
Expand Down
45 changes: 34 additions & 11 deletions library/src/pru/encoder_pru.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,27 @@
#include <rc/pru.h>
#include <rc/time.h>
#include <rc/encoder_pru.h>
#include <rc/model.h>

#define ENCODER_PRU_CH 0 // PRU0
#define ENCODER_PRU_FW "am335x-pru0-rc-encoder-fw"
#define ENCODER_MEM_OFFSET 16
#define AM335X_ENCODER_PRU_CH 0 // PRU0
#define AM335X_ENCODER_PRU_FW "am335x-pru0-rc-encoder-fw"
#define AM57XX_ENCODER_PRU_CH 3 // PRU1_1
#define AM57XX_ENCODER_PRU_FW "am57xx-pru1_1-rc-encoder-fw"
#define ENCODER_MEM_OFFSET 16

// pru shared memory pointer
static volatile unsigned int* shared_mem_32bit_ptr = NULL;
static int init_flag=0;

int rc_encoder_pru_init(void)
{
return 0; // until we fix for AM5
int i;
// map memory
shared_mem_32bit_ptr = rc_pru_shared_mem_ptr();
if(rc_model()==MODEL_BB_AI || rc_model()==MODEL_BB_AI_RC)
shared_mem_32bit_ptr = rc_pru_shared_mem_ptr(AM57XX_ENCODER_PRU_CH);
else
shared_mem_32bit_ptr = rc_pru_shared_mem_ptr(AM335X_ENCODER_PRU_CH);
if(shared_mem_32bit_ptr==NULL){
fprintf(stderr, "ERROR in rc_encoder_pru_init, failed to map shared memory pointer\n");
init_flag=0;
Expand All @@ -34,9 +41,16 @@ int rc_encoder_pru_init(void)
shared_mem_32bit_ptr[ENCODER_MEM_OFFSET]=42;

// start pru
if(rc_pru_start(ENCODER_PRU_CH, ENCODER_PRU_FW)){
fprintf(stderr,"ERROR in rc_encoder_pru_init, failed to start PRU%d\n", ENCODER_PRU_CH);
return -1;
if(rc_model()==MODEL_BB_AI || rc_model()==MODEL_BB_AI_RC){
if(rc_pru_start(AM57XX_ENCODER_PRU_CH, AM57XX_ENCODER_PRU_FW)){
fprintf(stderr,"ERROR in rc_encoder_pru_init, failed to start PRU%d\n", AM57XX_ENCODER_PRU_CH);
return -1;
}
} else {
if(rc_pru_start(AM335X_ENCODER_PRU_CH, AM335X_ENCODER_PRU_FW)){
fprintf(stderr,"ERROR in rc_encoder_pru_init, failed to start PRU%d\n", AM335X_ENCODER_PRU_CH);
return -1;
}
}

// make sure memory actually got zero'd out
Expand All @@ -48,9 +62,15 @@ int rc_encoder_pru_init(void)
rc_usleep(100000);
}

fprintf(stderr, "ERROR in rc_encoder_pru_init, %s failed to load\n", ENCODER_PRU_FW);
fprintf(stderr, "attempting to stop PRU%d\n", ENCODER_PRU_CH);
rc_pru_stop(ENCODER_PRU_CH);
if(rc_model()==MODEL_BB_AI || rc_model()==MODEL_BB_AI_RC){
fprintf(stderr, "ERROR in rc_encoder_pru_init, %s failed to load\n", AM57XX_ENCODER_PRU_FW);
fprintf(stderr, "attempting to stop PRU%d\n", AM57XX_ENCODER_PRU_CH);
rc_pru_stop(AM57XX_ENCODER_PRU_CH);
} else {
fprintf(stderr, "ERROR in rc_encoder_pru_init, %s failed to load\n", AM335X_ENCODER_PRU_FW);
fprintf(stderr, "attempting to stop PRU%d\n", AM335X_ENCODER_PRU_CH);
rc_pru_stop(AM335X_ENCODER_PRU_CH);
}
init_flag=0;
return -1;
}
Expand All @@ -62,7 +82,10 @@ void rc_encoder_pru_cleanup(void)
if(shared_mem_32bit_ptr != NULL){
shared_mem_32bit_ptr[ENCODER_MEM_OFFSET]=0;
}
rc_pru_stop(ENCODER_PRU_CH);
if(rc_model()==MODEL_BB_AI || rc_model()==MODEL_BB_AI_RC)
rc_pru_stop(AM57XX_ENCODER_PRU_CH);
else
rc_pru_stop(AM335X_ENCODER_PRU_CH);
shared_mem_32bit_ptr = NULL;
init_flag=0;
return;
Expand Down
Loading

0 comments on commit 99a08db

Please sign in to comment.