Merge branch '6' into '6'

bbb bsp: add modified gpio handling and adc section

See merge request rtems/rtos/rtems!697
This commit is contained in:
Heinz Junkes
2025-11-13 23:59:02 +00:00
8 changed files with 570 additions and 81 deletions

View File

@@ -0,0 +1,154 @@
/**
* @file
*
* @ingroup arm_beagle
*
* @brief ADC definitions.
*/
/**
* Copyright (c) 2015 Ketul Shah <ketulshah1993 at gmail.com>
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#include <libcpu/am335x.h>
#include <bsp/irq-generic.h>
#include <rtems.h>
#include <bsp/bbb-adc.h>
#include <bsp/irq.h>
#include <bsp/beagleboneblack.h>
#include <bsp.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
RTEMS_INTERRUPT_LOCK_DEFINE( static, rtems_adc_bsp_lock, "rtems_adc_bsp_lock" );
/* Waits a number of CPU cycles. */
static void arm_delay(uint8_t cycles)
{
uint8_t i;
for ( i = 0; i < cycles; ++i ) {
asm volatile("nop");
}
}
static void inline reg_update(uint32_t reg, uint32_t val)
{
mmio_write(reg, val);
}
static void inline reg_update_or(uint32_t reg, uint32_t val)
{
uint32_t reg_val=mmio_read(reg);
reg_val |= val;
mmio_write(reg, reg_val);
}
/* Configure STEPCONFIG register with average of 16 */
static void inline stepc_update_16(uint32_t reg, uint32_t val)
{
mmio_write(reg,(val | AM335X_ADC_AVG16));
}
/* Configure STEPDELAY register */
static void inline stepd_update(uint32_t reg)
{
mmio_write(reg,(0x0F)<<24);
}
static uint32_t inline get_val(uint32_t reg, uint32_t val)
{
return (mmio_read(reg) & val);
}
void rtems_adc_init(void)
{
rtems_interrupt_lock_context lock_context;
rtems_interrupt_lock_acquire(&rtems_adc_bsp_lock, &lock_context);
/* Enable the CM_WKUP_ADC_CLKCTRL with CM_WKUP_MODUELEMODE_ENABLE */
reg_update_or(AM335X_CM_WKUP_ADC_CLKCTRL, AM335X_CM_WKUP_MODULEMODE_ENABLE); /* 0x02 */
while(!( get_val(AM335X_CM_WKUP_ADC_CLKCTRL,AM335X_CM_WKUP_MODULEMODE_ENABLE))){
/* Here waiting period for intialization of adc clock module */
}
/* Make sure STEPCONFIG write protect is off */
reg_update_or(AM335X_ADC_CTRL, AM335X_ADC_STEPCONFIG_WRITE_PROTECT_OFF);
/* ADC_STEPCONFIG for each AIN pin */
stepc_update_16(AM335X_ADC_STEPCONFIG1,0x00<<19);
stepd_update(AM335X_ADC_STEPDELAY1);
stepc_update_16(AM335X_ADC_STEPCONFIG2,0x01<<19);
stepd_update(AM335X_ADC_STEPDELAY2);
stepc_update_16(AM335X_ADC_STEPCONFIG3,0x02<<19);
stepd_update(AM335X_ADC_STEPDELAY3);
stepc_update_16(AM335X_ADC_STEPCONFIG4,0x03<<19);
stepd_update(AM335X_ADC_STEPDELAY4);
stepc_update_16(AM335X_ADC_STEPCONFIG5,0x04<<19);
stepd_update(AM335X_ADC_STEPDELAY5);
stepc_update_16(AM335X_ADC_STEPCONFIG6,0x05<<19);
stepd_update(AM335X_ADC_STEPDELAY6);
stepc_update_16(AM335X_ADC_STEPCONFIG7,0x06<<19);
stepd_update(AM335X_ADC_STEPDELAY7);
stepc_update_16(AM335X_ADC_STEPCONFIG8,0x07<<19);
stepd_update(AM335X_ADC_STEPDELAY8);
/* ADC_CTRL is enabled + store the Step ID-number with the captured ADC data in the Fifo */
reg_update_or(AM335X_ADC_CTRL,0x03);
rtems_interrupt_lock_release(&rtems_gpio_bsp_lock, &lock_context);
}
int rtems_adc_read(unsigned int pin_number)
{
rtems_interrupt_lock_context lock_context;
/* The clock module is not enabled */
if(get_val(AM335X_CM_WKUP_ADC_CLKCTRL,AM335X_CM_WKUP_IDLEST_DISABLED))
rtems_adc_init();
rtems_interrupt_lock_acquire(&rtems_adc_bsp_lock, &lock_context);
/* Enable the step sequencer for the given pin */
reg_update(AM335X_ADC_STEPENABLE,(0x01<<(pin_number+1)));
rtems_interrupt_lock_release(&rtems_gpio_bsp_lock, &lock_context);
/* Return the value of data register FIFO0 */
return (get_val(AM335X_ADC_FIFO0DATA,AM335X_ADC_FIFO_MASK));
}
unsigned int rtems_adc_read_multiple(unsigned int len, unsigned int wait, unsigned int mask, unsigned int data[])
{
rtems_interrupt_lock_context lock_context;
/* The clock module is not enabled */
if(get_val(AM335X_CM_WKUP_ADC_CLKCTRL,AM335X_CM_WKUP_IDLEST_DISABLED))
rtems_adc_init();
rtems_interrupt_lock_acquire(&rtems_adc_bsp_lock, &lock_context);
/* Enable the step sequencer for the given pins/mask */
reg_update(AM335X_ADC_STEPENABLE, mask);
int timeOut = len * wait;
int fifo;
do {
fifo = get_val(AM335X_ADC_FIFO0COUNT, 0x7F);
timeOut-=1;
arm_delay(5);
} while( (len != fifo) && timeOut);
unsigned int d;
for(unsigned int i = 0; i < fifo; i++) {
d = get_val(AM335X_ADC_FIFO0DATA, 0x000F0FFF);
if (d>>16 < len) // chid in head of data
data[d>>16] = d & 0xfff;
}
rtems_interrupt_lock_release(&rtems_gpio_bsp_lock, &lock_context);
return (fifo);
}

View File

@@ -28,18 +28,23 @@
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
/* Currently these definitions are for BeagleBone Black board only /* Currently these definitions are for BeagleBone Black board only
* with modifications from ketul93
* (https://gist.github.com/ketul93/d717555951174a74c8b4)
* Later on Beagle-xM board support can be added in this code. * Later on Beagle-xM board support can be added in this code.
* After support gets added if condition should be removed * After support gets added if condition should be removed
* HPJ: set almost all I/O to Mode7 to use all for own application
* This is not yet well structured and good ideas are still needed
*/ */
#if IS_AM335X #if IS_AM335X
static const uint32_t gpio_bank_addrs[] = static const uint32_t gpio_bank_addrs[] =
{ AM335X_GPIO0_BASE, { AM335X_GPIO0_BASE,
AM335X_GPIO1_BASE, AM335X_GPIO1_BASE,
AM335X_GPIO2_BASE, AM335X_GPIO2_BASE,
AM335X_GPIO3_BASE }; AM335X_GPIO3_BASE };
static const rtems_vector_number gpio_bank_vector[] = static const rtems_vector_number gpio_bank_vector[] =
{ AM335X_INT_GPIOINT0A, { AM335X_INT_GPIOINT0A,
@@ -47,10 +52,161 @@ static const rtems_vector_number gpio_bank_vector[] =
AM335X_INT_GPIOINT2A, AM335X_INT_GPIOINT2A,
AM335X_INT_GPIOINT3A }; AM335X_INT_GPIOINT3A };
/* Macro for the gpio pin not having control module offset mapping */
#define CONF_NOT_DEFINED 0x00
/* Mapping of gpio pin number to the Control module mapped register offset */
// FHI: allmost all, but mmc, used in MUXMODE7 from our applications
// Macro?
static const uint32_t gpio_pad_conf [GPIO_BANK_COUNT][BSP_GPIO_PINS_PER_BANK] =
{
/* GPIO Module 0 */
{ CONF_NOT_DEFINED, /* GPIO0[0] */
CONF_NOT_DEFINED, /* GPIO0[1] */
AM335X_CONF_SPI0_SCLK, /* GPIO0[2] */
AM335X_CONF_SPI0_D0, /* GPIO0[3] */
AM335X_CONF_SPI0_D1, /* GPIO0[4] */
AM335X_CONF_SPI0_CS0, /* GPIO0[5] */
CONF_NOT_DEFINED, /* GPIO0[6] */
AM335X_CONF_ECAP0_IN_PWM0_OUT,/* GPIO0[7] */
AM335X_CONF_LCD_DATA12, /* GPIO0[8] */
AM335X_CONF_LCD_DATA13, /* GPIO0[9] */
AM335X_CONF_LCD_DATA14, /* GPIO0[10] */
AM335X_CONF_LCD_DATA15, /* GPIO0[11] */
AM335X_CONF_UART1_CTSN, /* GPIO0[12] */
AM335X_CONF_UART1_RTSN, /* GPIO0[13] */
AM335X_CONF_UART1_RXD, /* GPIO0[14] */
AM335X_CONF_UART1_TXD, /* GPIO0[15] */
CONF_NOT_DEFINED, /* GPIO0[16] */
CONF_NOT_DEFINED, /* GPIO0[17] */
CONF_NOT_DEFINED, /* GPIO0[18] */
CONF_NOT_DEFINED, /* GPIO0[19] */
AM335X_CONF_XDMA_EVENT_INTR1, /* GPIO0[20] */
CONF_NOT_DEFINED, /* GPIO0[21] */
AM335X_CONF_GPMC_AD8, /* GPIO0[22] */
AM335X_CONF_GPMC_AD9, /* GPIO0[23] */
CONF_NOT_DEFINED, /* GPIO0[24] */
CONF_NOT_DEFINED, /* GPIO0[25] */
AM335X_CONF_GPMC_AD10, /* GPIO0[26] */
AM335X_CONF_GPMC_AD11, /* GPIO0[27] */
CONF_NOT_DEFINED, /* GPIO0[28] */
CONF_NOT_DEFINED, /* GPIO0[29] */
AM335X_CONF_GPMC_WAIT0, /* GPIO0[30] */
AM335X_CONF_GPMC_WPN /* GPIO0[31] */ },
/* GPIO Module 1 */
{ AM335X_CONF_GPMC_AD0, /* GPIO1[0] */
AM335X_CONF_GPMC_AD1, /* GPIO1[1] */
AM335X_CONF_GPMC_AD2, /* GPIO1[2] */
AM335X_CONF_GPMC_AD3, /* GPIO1[3] */
AM335X_CONF_GPMC_AD4, /* GPIO1[4] */
AM335X_CONF_GPMC_AD5, /* GPIO1[5] */
AM335X_CONF_GPMC_AD6, /* GPIO1[6] */
AM335X_CONF_GPMC_AD7, /* GPIO1[7] */
CONF_NOT_DEFINED, /* GPIO1[8] */
CONF_NOT_DEFINED, /* GPIO1[9] */
CONF_NOT_DEFINED, /* GPIO1[10] */
CONF_NOT_DEFINED, /* GPIO1[11] */
AM335X_CONF_GPMC_AD12, /* GPIO1[12] */
AM335X_CONF_GPMC_AD13, /* GPIO1[13] */
AM335X_CONF_GPMC_AD14, /* GPIO1[14] */
AM335X_CONF_GPMC_AD15, /* GPIO1[15] */
AM335X_CONF_GPMC_A0, /* GPIO1[16] */
AM335X_CONF_GPMC_A1, /* GPIO1[17] */
AM335X_CONF_GPMC_A2, /* GPIO1[18] */
AM335X_CONF_GPMC_A3, /* GPIO1[19] */
CONF_NOT_DEFINED, /* GPIO1[20] */
AM335X_CONF_GPMC_A5, /* GPIO1[21] */
AM335X_CONF_GPMC_A6, /* GPIO1[22] */
AM335X_CONF_GPMC_A7, /* GPIO1[23] */
AM335X_CONF_GPMC_A8, /* GPIO1[24] */
CONF_NOT_DEFINED, /* GPIO1[25] */
CONF_NOT_DEFINED, /* GPIO1[26] */
CONF_NOT_DEFINED, /* GPIO1[27] */
AM335X_CONF_GPMC_BEN1, /* GPIO1[28] */
AM335X_CONF_GPMC_CSN0, /* GPIO1[29] */
AM335X_CONF_GPMC_CSN1, /* GPIO1[30] */
AM335X_CONF_GPMC_CSN2 /* GPIO1[31] */ },
/* GPIO Module 2 */
{ CONF_NOT_DEFINED, /* GPIO2[0] */
AM335X_CONF_GPMC_CLK, /* GPIO2[1] */
AM335X_CONF_GPMC_ADVN_ALE, /* GPIO2[2] */
AM335X_CONF_GPMC_OEN_REN, /* GPIO2[3] */
AM335X_CONF_GPMC_WEN, /* GPIO2[4] */
AM335X_CONF_GPMC_BEN0_CLE, /* GPIO2[5] */
AM335X_CONF_LCD_DATA0, /* GPIO2[6] */
AM335X_CONF_LCD_DATA1, /* GPIO2[7] */
AM335X_CONF_LCD_DATA2, /* GPIO2[8] */
AM335X_CONF_LCD_DATA3, /* GPIO2[9] */
AM335X_CONF_LCD_DATA4, /* GPIO2[10] */
AM335X_CONF_LCD_DATA5, /* GPIO2[11] */
AM335X_CONF_LCD_DATA6, /* GPIO2[12] */
AM335X_CONF_LCD_DATA7, /* GPIO2[13] */
AM335X_CONF_LCD_DATA8, /* GPIO2[14] */
AM335X_CONF_LCD_DATA9, /* GPIO2[15] */
AM335X_CONF_LCD_DATA10, /* GPIO2[16] */
AM335X_CONF_LCD_DATA11, /* GPIO2[17] */
CONF_NOT_DEFINED, /* GPIO2[18] */
CONF_NOT_DEFINED, /* GPIO2[19] */
CONF_NOT_DEFINED, /* GPIO2[20] */
CONF_NOT_DEFINED, /* GPIO2[21] */
AM335X_CONF_LCD_VSYNC, /* GPIO2[22] */
AM335X_CONF_LCD_HSYNC, /* GPIO2[23] */
AM335X_CONF_LCD_PCLK, /* GPIO2[24] */
AM335X_CONF_LCD_AC_BIAS_EN /* GPIO2[25] */ },
/* GPIO Module 3 */
{ CONF_NOT_DEFINED, /* GPIO3[0] */
CONF_NOT_DEFINED, /* GPIO3[1] */
CONF_NOT_DEFINED, /* GPIO3[2] */
CONF_NOT_DEFINED, /* GPIO3[3] */
CONF_NOT_DEFINED, /* GPIO3[4] */
CONF_NOT_DEFINED, /* GPIO3[5] */
CONF_NOT_DEFINED, /* GPIO3[6] */
CONF_NOT_DEFINED, /* GPIO3[7] */
CONF_NOT_DEFINED, /* GPIO3[8] */
CONF_NOT_DEFINED, /* GPIO3[9] */
CONF_NOT_DEFINED, /* GPIO3[10] */
CONF_NOT_DEFINED, /* GPIO3[11] */
CONF_NOT_DEFINED, /* GPIO3[12] */
CONF_NOT_DEFINED, /* GPIO3[13] */
AM335X_CONF_MCASP0_ACLKX, /* GPIO3[14] */
AM335X_CONF_MCASP0_FSX, /* GPIO3[15] */
AM335X_CONF_MCASP0_AXR0, /* GPIO3[16] */
AM335X_CONF_MCASP0_AHCLKR, /* GPIO3[17] */
CONF_NOT_DEFINED, /* GPIO3[18] */
AM335X_CONF_MCASP0_FSR, /* GPIO3[19] */
AM335X_CONF_MCASP0_AXR1, /* GPIO3[20] */
AM335X_CONF_MCASP0_AHCLKX /* GPIO3[21] */ }
};
/* Get the address of Base Register + Offset for pad config */
uint32_t static inline bbb_conf_reg(uint32_t bank, uint32_t pin)
{
/* Asserts if invalid pin is supplied */
assert(gpio_pad_conf[bank][pin] != CONF_NOT_DEFINED);
/*
How to Deal with MUXMODE 7 ?
*/
return (AM335X_PADCONF_BASE + gpio_pad_conf[bank][pin]);
}
/* Get the value of Base Register + Offset */ /* Get the value of Base Register + Offset */
uint32_t static inline bbb_reg(uint32_t bank, uint32_t reg) uint32_t static inline bbb_reg(uint32_t bank, uint32_t reg)
{ {
return (gpio_bank_addrs[bank] + reg); return REG(gpio_bank_addrs[bank] + reg);
}
/* Waits a number of CPU cycles. */
static void arm_delay(uint8_t cycles)
{
uint8_t i;
for ( i = 0; i < cycles; ++i ) {
asm volatile("nop");
}
} }
static rtems_status_code bbb_select_pin_function( static rtems_status_code bbb_select_pin_function(
@@ -60,50 +216,47 @@ static rtems_status_code bbb_select_pin_function(
) { ) {
if ( type == BBB_DIGITAL_IN ) { if ( type == BBB_DIGITAL_IN ) {
mmio_set(bbb_reg(bank, AM335X_GPIO_OE), BIT(pin)); mmio_set((gpio_bank_addrs[bank] + AM335X_GPIO_OE), BIT(pin));
} else { }
mmio_clear(bbb_reg(bank, AM335X_GPIO_OE), BIT(pin)); else {
mmio_clear((gpio_bank_addrs[bank] + AM335X_GPIO_OE), BIT(pin));
} }
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }
rtems_status_code rtems_gpio_bsp_multi_set(uint32_t bank, uint32_t bitmask) rtems_status_code rtems_gpio_bsp_multi_set(uint32_t bank, uint32_t bitmask)
{ {
mmio_set(bbb_reg(bank, AM335X_GPIO_SETDATAOUT), bitmask); mmio_write((gpio_bank_addrs[bank] + AM335X_GPIO_SETDATAOUT), bitmask);
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }
rtems_status_code rtems_gpio_bsp_multi_clear(uint32_t bank, uint32_t bitmask) rtems_status_code rtems_gpio_bsp_multi_clear(uint32_t bank, uint32_t bitmask)
{ {
mmio_set(bbb_reg(bank, AM335X_GPIO_CLEARDATAOUT), bitmask); mmio_write((gpio_bank_addrs[bank] + AM335X_GPIO_CLEARDATAOUT), bitmask);
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }
uint32_t rtems_gpio_bsp_multi_read(uint32_t bank, uint32_t bitmask) uint32_t rtems_gpio_bsp_multi_read(uint32_t bank, uint32_t bitmask)
{ {
return (bbb_reg(bank, AM335X_GPIO_DATAIN) & bitmask); return (mmio_read(gpio_bank_addrs[bank] + AM335X_GPIO_DATAIN) & bitmask);
} }
rtems_status_code rtems_gpio_bsp_set(uint32_t bank, uint32_t pin) rtems_status_code rtems_gpio_bsp_set(uint32_t bank, uint32_t pin)
{ {
mmio_set(bbb_reg(bank, AM335X_GPIO_SETDATAOUT), BIT(pin)); mmio_write((gpio_bank_addrs[bank] + AM335X_GPIO_SETDATAOUT), BIT(pin));
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }
rtems_status_code rtems_gpio_bsp_clear(uint32_t bank, uint32_t pin) rtems_status_code rtems_gpio_bsp_clear(uint32_t bank, uint32_t pin)
{ {
mmio_set(bbb_reg(bank, AM335X_GPIO_CLEARDATAOUT), BIT(pin)); mmio_write((gpio_bank_addrs[bank] + AM335X_GPIO_CLEARDATAOUT), BIT(pin));
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }
uint32_t rtems_gpio_bsp_get_value(uint32_t bank, uint32_t pin) uint32_t rtems_gpio_bsp_get_value(uint32_t bank, uint32_t pin)
{ {
return (mmio_read(bbb_reg(bank, AM335X_GPIO_DATAIN)) & BIT(pin)); return (mmio_read(gpio_bank_addrs[bank] + AM335X_GPIO_DATAIN) & BIT(pin) ? 1:0);
} }
rtems_status_code rtems_gpio_bsp_select_input( rtems_status_code rtems_gpio_bsp_select_input(
@@ -131,13 +284,42 @@ rtems_status_code rtems_gpio_bsp_select_specific_io(
return RTEMS_NOT_DEFINED; return RTEMS_NOT_DEFINED;
} }
rtems_status_code rtems_bsp_select_specific_io(
uint32_t bank,
uint32_t pin,
uint32_t function,
void *pin_data
) {
return RTEMS_NOT_DEFINED;
}
rtems_status_code rtems_gpio_bsp_set_resistor_mode( rtems_status_code rtems_gpio_bsp_set_resistor_mode(
uint32_t bank, uint32_t bank,
uint32_t pin, uint32_t pin,
rtems_gpio_pull_mode mode rtems_gpio_pull_mode mode
) { ) {
/* TODO: Add support for setting up resistor mode */
return RTEMS_NOT_DEFINED; uint32_t register_content;
register_content = BBB_MUXMODE(7);
/* Set control signal. */
switch ( mode ) {
case PULL_UP:
register_content = register_content | BBB_PU_EN | BBB_RXACTIVE; // assume input
break;
case PULL_DOWN:
break;
case NO_PULL_RESISTOR:
register_content = register_content | BBB_PUDDIS;
break;
default:
return RTEMS_UNSATISFIED;
}
mmio_write(bbb_conf_reg(bank,pin), register_content);
return RTEMS_SUCCESSFUL;
} }
rtems_vector_number rtems_gpio_bsp_get_vector(uint32_t bank) rtems_vector_number rtems_gpio_bsp_get_vector(uint32_t bank)
@@ -157,12 +339,11 @@ uint32_t rtems_gpio_bsp_interrupt_line(rtems_vector_number vector)
} }
/* Retrieve the interrupt event status. */ /* Retrieve the interrupt event status. */
event_status = mmio_read(bbb_reg(bank_nr, AM335X_GPIO_IRQSTATUS_0)); event_status = bbb_reg(bank_nr, AM335X_GPIO_IRQSTATUS_0);
/* Clear the interrupt line. */ /* Clear the interrupt line. */
mmio_write( mmio_write(gpio_bank_addrs[bank_nr] + AM335X_GPIO_IRQSTATUS_0, event_status);
(bbb_reg(bank_nr, AM335X_GPIO_IRQSTATUS_0)), event_status);
return event_status; return event_status;
} }
@@ -171,135 +352,135 @@ rtems_status_code rtems_gpio_bsp_enable_interrupt(
uint32_t pin, uint32_t pin,
rtems_gpio_interrupt interrupt rtems_gpio_interrupt interrupt
) { ) {
return rtems_bsp_enable_interrupt(bank, pin, interrupt);
/* Enable IRQ generation for the specific pin */ }
mmio_set(bbb_reg(bank, AM335X_GPIO_IRQSTATUS_SET_0), BIT(pin));
rtems_status_code rtems_bsp_enable_interrupt(
uint32_t bank,
uint32_t pin,
rtems_gpio_interrupt interrupt
) {
switch ( interrupt ) { switch ( interrupt ) {
case FALLING_EDGE: case FALLING_EDGE:
/* Enables asynchronous falling edge detection. */ /* Enables asynchronous falling edge detection. */
mmio_set(bbb_reg(bank, AM335X_GPIO_FALLINGDETECT), BIT(pin)); mmio_set(gpio_bank_addrs[bank] + AM335X_GPIO_FALLINGDETECT, BIT(pin));
break; break;
case RISING_EDGE: case RISING_EDGE:
/* Enables asynchronous rising edge detection. */ /* Enables asynchronous rising edge detection. */
mmio_set(bbb_reg(bank, AM335X_GPIO_RISINGDETECT), BIT(pin)); mmio_set(gpio_bank_addrs[bank] + AM335X_GPIO_RISINGDETECT, BIT(pin));
break; break;
case BOTH_EDGES: case BOTH_EDGES:
/* Enables asynchronous falling edge detection. */ /* Enables asynchronous falling edge detection. */
mmio_set(bbb_reg(bank, AM335X_GPIO_FALLINGDETECT), BIT(pin)); mmio_set(gpio_bank_addrs[bank] + AM335X_GPIO_FALLINGDETECT, BIT(pin));
/* Enables asynchronous rising edge detection. */ /* Enables asynchronous rising edge detection. */
mmio_set(bbb_reg(bank, AM335X_GPIO_RISINGDETECT), BIT(pin)); mmio_set(gpio_bank_addrs[bank] + AM335X_GPIO_RISINGDETECT, BIT(pin));
break; break;
case LOW_LEVEL: case LOW_LEVEL:
/* Enables pin low level detection. */ /* Enables pin low level detection. */
mmio_set(bbb_reg(bank, AM335X_GPIO_LEVELDETECT0), BIT(pin)); mmio_set(gpio_bank_addrs[bank] + AM335X_GPIO_LEVELDETECT0, BIT(pin));
break; break;
case HIGH_LEVEL: case HIGH_LEVEL:
/* Enables pin high level detection. */ /* Enables pin high level detection. */
mmio_set(bbb_reg(bank, AM335X_GPIO_LEVELDETECT1), BIT(pin)); mmio_set(gpio_bank_addrs[bank] + AM335X_GPIO_LEVELDETECT1, BIT(pin));
break; break;
case BOTH_LEVELS: case BOTH_LEVELS:
/* Enables pin low level detection. */ /* Enables pin low level detection. */
mmio_set(bbb_reg(bank, AM335X_GPIO_LEVELDETECT0), BIT(pin)); mmio_set(gpio_bank_addrs[bank] + AM335X_GPIO_LEVELDETECT0, BIT(pin));
/* Enables pin high level detection. */ /* Enables pin high level detection. */
mmio_set(bbb_reg(bank, AM335X_GPIO_LEVELDETECT1), BIT(pin)); mmio_set(gpio_bank_addrs[bank] + AM335X_GPIO_LEVELDETECT1, BIT(pin));
break; break;
case NONE: case NONE:
default: default:
return RTEMS_UNSATISFIED; return RTEMS_UNSATISFIED;
} }
/*
printf(" Register for interrupt detection are : \n");
printf("\t FALLING : 0x%x\n", mmio_read(gpio_bank_addrs[bank] + AM335X_GPIO_FALLINGDETECT));
printf("\t RISING : 0x%x\n", mmio_read(gpio_bank_addrs[bank] + AM335X_GPIO_RISINGDETECT));
printf("\t Low Level : 0x%x\n", mmio_read(gpio_bank_addrs[bank] + AM335X_GPIO_LEVELDETECT0));
printf("\t High Level : 0x%x\n", mmio_read(gpio_bank_addrs[bank] + AM335X_GPIO_LEVELDETECT1));
*/
mmio_write(gpio_bank_addrs[bank] + AM335X_GPIO_IRQSTATUS_SET_0, BIT(pin));
mmio_write(gpio_bank_addrs[bank] + AM335X_GPIO_IRQSTATUS_SET_1, BIT(pin));
/* The detection starts after 5 clock cycles as per AM335X TRM /* The detection starts after 5 clock cycles as per AM335X TRM
* This period is required to clean the synchronization edge/ * This period is required to clean the synchronization edge/
* level detection pipeline * level detection pipeline
*/ */
asm volatile("nop"); asm volatile("nop"); asm volatile("nop"); arm_delay(5);
asm volatile("nop"); asm volatile("nop");
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }
rtems_status_code rtems_gpio_bsp_disable_interrupt( rtems_status_code rtems_gpio_bsp_disable_interrupt(
uint32_t bank, uint32_t bank,
uint32_t pin, uint32_t pin,
rtems_gpio_interrupt interrupt rtems_gpio_interrupt interrupt
) { ) {
/* Clear IRQ generation for the specific pin */ return rtems_bsp_disable_interrupt(bank, pin, interrupt);
mmio_write(bbb_reg(bank, AM335X_GPIO_IRQSTATUS_CLR_0), BIT(pin)); }
rtems_status_code rtems_bsp_disable_interrupt(
uint32_t bank,
uint32_t pin,
rtems_gpio_interrupt interrupt
) {
switch ( interrupt ) { switch ( interrupt ) {
case FALLING_EDGE: case FALLING_EDGE:
/* Disables asynchronous falling edge detection. */ /* Disables asynchronous falling edge detection. */
mmio_clear(bbb_reg(bank, AM335X_GPIO_FALLINGDETECT), BIT(pin)); mmio_clear(gpio_bank_addrs[bank] + AM335X_GPIO_FALLINGDETECT, BIT(pin));
break; break;
case RISING_EDGE: case RISING_EDGE:
/* Disables asynchronous rising edge detection. */ /* Disables asynchronous rising edge detection. */
mmio_clear(bbb_reg(bank, AM335X_GPIO_RISINGDETECT), BIT(pin)); mmio_clear(gpio_bank_addrs[bank] + AM335X_GPIO_RISINGDETECT, BIT(pin));
break; break;
case BOTH_EDGES: case BOTH_EDGES:
/* Disables asynchronous falling edge detection. */ /* Disables asynchronous falling edge detection. */
mmio_clear(bbb_reg(bank, AM335X_GPIO_FALLINGDETECT), BIT(pin)); mmio_clear(gpio_bank_addrs[bank] + AM335X_GPIO_FALLINGDETECT, BIT(pin));
/* Disables asynchronous rising edge detection. */ /* Disables asynchronous rising edge detection. */
mmio_clear(bbb_reg(bank, AM335X_GPIO_RISINGDETECT), BIT(pin)); mmio_clear(gpio_bank_addrs[bank] + AM335X_GPIO_RISINGDETECT, BIT(pin));
break; break;
case LOW_LEVEL: case LOW_LEVEL:
/* Disables pin low level detection. */ /* Disables pin low level detection. */
mmio_clear(bbb_reg(bank, AM335X_GPIO_LEVELDETECT0), BIT(pin)); mmio_clear(gpio_bank_addrs[bank] + AM335X_GPIO_LEVELDETECT0, BIT(pin));
break; break;
case HIGH_LEVEL: case HIGH_LEVEL:
/* Disables pin high level detection. */ /* Disables pin high level detection. */
mmio_clear(bbb_reg(bank, AM335X_GPIO_LEVELDETECT1), BIT(pin)); mmio_clear(gpio_bank_addrs[bank] + AM335X_GPIO_LEVELDETECT1, BIT(pin));
break; break;
case BOTH_LEVELS: case BOTH_LEVELS:
/* Disables pin low level detection. */ /* Disables pin low level detection. */
mmio_clear(bbb_reg(bank, AM335X_GPIO_LEVELDETECT0), BIT(pin)); mmio_clear(gpio_bank_addrs[bank] + AM335X_GPIO_LEVELDETECT0, BIT(pin));
/* Disables pin high level detection. */ /* Disables pin high level detection. */
mmio_clear(bbb_reg(bank, AM335X_GPIO_LEVELDETECT1), BIT(pin)); mmio_clear(gpio_bank_addrs[bank] + AM335X_GPIO_LEVELDETECT1, BIT(pin));
break; break;
case NONE: case NONE:
default: default:
return RTEMS_UNSATISFIED; return RTEMS_UNSATISFIED;
} }
/* The detection starts after 5 clock cycles as per AM335X TRM mmio_write((gpio_bank_addrs[bank] + AM335X_GPIO_IRQSTATUS_CLR_0), BIT(pin));
* This period is required to clean the synchronization edge/ mmio_write((gpio_bank_addrs[bank] + AM335X_GPIO_IRQSTATUS_CLR_1), BIT(pin));
* level detection pipeline
*/
asm volatile("nop"); asm volatile("nop"); asm volatile("nop");
asm volatile("nop"); asm volatile("nop");
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }
/* I have unfortunately lost the overview a little ....
*/
rtems_status_code rtems_gpio_bsp_multi_select( rtems_status_code rtems_gpio_bsp_multi_select(
rtems_gpio_multiple_pin_select *pins, rtems_gpio_multiple_pin_select *pins,
uint32_t pin_count, uint32_t pin_count,
uint32_t select_bank uint32_t select_bank
) { ) {
uint32_t register_address;
uint32_t select_register;
uint8_t i; uint8_t i;
register_address = gpio_bank_addrs[select_bank] + AM335X_GPIO_OE;
select_register = REG(register_address);
for ( i = 0; i < pin_count; ++i ) { for ( i = 0; i < pin_count; ++i ) {
if ( pins[i].function == DIGITAL_INPUT ) { bbb_select_pin_function((pins[i].pin_number)/32, (pins[i].pin_number)%32, pins[i].function);
select_register |= BIT(pins[i].pin_number);
} else if ( pins[i].function == DIGITAL_OUTPUT ) {
select_register &= ~BIT(pins[i].pin_number);
} else { /* BSP_SPECIFIC function. */
return RTEMS_NOT_DEFINED;
}
} }
REG(register_address) = select_register;
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }
@@ -311,7 +492,6 @@ rtems_status_code rtems_gpio_bsp_specific_group_operation(
) { ) {
return RTEMS_NOT_DEFINED; return RTEMS_NOT_DEFINED;
} }
#endif /* IS_AM335X */ #endif /* IS_AM335X */
/* For support of BeagleboardxM */ /* For support of BeagleboardxM */

View File

@@ -0,0 +1,33 @@
/**
* @file
*
* @ingroup arm_beagle
*
* @brief BeagleBone Black BSP definitions.
*/
/**
* Copyright (c) 2015 Ketul Shah <ketulshah1993 at gmail.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE.
*/
#ifndef LIBBSP_ARM_BEAGLE_ADC_H
#define LIBBSP_ARM_BEAGLE_ADC_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* @brief ADC intialization.
*/
extern void rtems_adc_init(void);
/**
* @brief Reads the ADC value for input from pin.
*/
extern int rtems_adc_read(unsigned int);
extern unsigned int rtems_adc_read_multiple(unsigned int len, unsigned int wait, unsigned int mask, unsigned int data[]);
#endif

View File

@@ -37,6 +37,10 @@
#define BBB_LED_USR3 56 /* USR LED3 */ #define BBB_LED_USR3 56 /* USR LED3 */
/* Header P8 of BeagleBone Black */ /* Header P8 of BeagleBone Black */
#define BBB_P8_3 38 /* GPIO1_6 */
#define BBB_P8_4 39 /* GPIO1_7 */
#define BBB_P8_5 34 /* GPIO1_2 */
#define BBB_P8_6 35 /* GPIO1_3 */
#define BBB_P8_7 66 /* GPIO2_2 */ #define BBB_P8_7 66 /* GPIO2_2 */
#define BBB_P8_8 67 /* GPIO2_3 */ #define BBB_P8_8 67 /* GPIO2_3 */
#define BBB_P8_9 69 /* GPIO2_5 */ #define BBB_P8_9 69 /* GPIO2_5 */
@@ -50,7 +54,33 @@
#define BBB_P8_17 27 /* GPIO0_27 */ #define BBB_P8_17 27 /* GPIO0_27 */
#define BBB_P8_18 65 /* GPIO2_1 */ #define BBB_P8_18 65 /* GPIO2_1 */
#define BBB_P8_19 22 /* GPIO0_22 */ #define BBB_P8_19 22 /* GPIO0_22 */
#define BBB_P8_20 63 /* GPIO1_31 */
#define BBB_P8_21 62 /* GPIO1_30 */
#define BBB_P8_22 37 /* GPIO1_5 */
#define BBB_P8_23 36 /* GPIO1_4 */
#define BBB_P8_24 33 /* GPIO1_1 */
#define BBB_P8_25 32 /* GPIO1_0 */
#define BBB_P8_26 61 /* GPIO1_29 */ #define BBB_P8_26 61 /* GPIO1_29 */
#define BBB_P8_27 86 /* GPIO2_22 */
#define BBB_P8_28 88 /* GPIO2_24 */
#define BBB_P8_29 87 /* GPIO2_23 */
#define BBB_P8_30 89 /* GPIO2_25 */
#define BBB_P8_31 10 /* GPIO0_10 */
#define BBB_P8_32 11 /* GPIO0_11 */
#define BBB_P8_33 9 /* GPIO0_9 */
#define BBB_P8_34 81 /* GPIO2_17 */
#define BBB_P8_35 8 /* GPIO0_8 */
#define BBB_P8_36 80 /* GPIO2_16 */
#define BBB_P8_37 78 /* GPIO2_14 */
#define BBB_P8_38 79 /* GPIO2_15 */
#define BBB_P8_39 76 /* GPIO2_12 */
#define BBB_P8_40 77 /* GPIO2_13 */
#define BBB_P8_41 74 /* GPIO2_10 */
#define BBB_P8_42 75 /* GPIO2_11 */
#define BBB_P8_43 72 /* GPIO2_8 */
#define BBB_P8_44 73 /* GPIO2_9 */
#define BBB_P8_45 70 /* GPIO2_6 */
#define BBB_P8_46 71 /* GPIO2_7 */
/* Header P9 of BeagleBone Black */ /* Header P9 of BeagleBone Black */
#define BBB_P9_11 30 /* GPIO0_30 */ #define BBB_P9_11 30 /* GPIO0_30 */
@@ -61,12 +91,40 @@
#define BBB_P9_16 51 /* GPIO1_19 */ #define BBB_P9_16 51 /* GPIO1_19 */
#define BBB_P9_17 5 /* GPIO0_5 */ #define BBB_P9_17 5 /* GPIO0_5 */
#define BBB_P9_18 4 /* GPIO0_4 */ #define BBB_P9_18 4 /* GPIO0_4 */
#define BBB_P9_19 13 /* GPIO0_13 */
#define BBB_P9_20 12 /* GPIO0_12 */
#define BBB_P9_21 3 /* GPIO0_3 */
#define BBB_P9_22 2 /* GPIO0_2 */
#define BBB_P9_23 49 /* GPIO1_17 */ #define BBB_P9_23 49 /* GPIO1_17 */
#define BBB_P9_24 15 /* GPIO0_15 */ #define BBB_P9_24 15 /* GPIO0_15 */
#define BBB_P9_25 117 /* GPIO3_21 */
#define BBB_P9_26 14 /* GPIO1_14 */ #define BBB_P9_26 14 /* GPIO1_14 */
#define BBB_P9_27 115/* GPIO3_19 */ #define BBB_P9_27 115 /* GPIO3_19 */
#define BBB_P9_30 112/* GPIO3_16 */
#define BBB_P9_41 20 /* GPIO0_20 */ #define BBB_P9_28 113 /* GPIO3_17 */
#define BBB_P9_29 111 /* GPIO3_15 */
#define BBB_P9_30 112 /* GPIO3_16 */
#define BBB_P9_31 110 /* GPIO3_14 */
#define BBB_P9_41A 20 /* GPIO0_20 */
#define BBB_P9_41B 116 /* GPIO3_20 */
#define BBB_P9_42 7 /* GPIO0_7 */ #define BBB_P9_42 7 /* GPIO0_7 */
#endif /* LIBBSP_ARM_BEAGLE_GPIO_H */ /* ADC pins on the BeagleBone Black */
#define BBB_P9_33 4 /* AIN_4 */
#define BBB_P9_34 7 /* AIN_7 */
#define BBB_P9_35 6 /* AIN_6 */
#define BBB_P9_36 5 /* AIN_5 */
#define BBB_P9_37 2 /* AIN_2 */
#define BBB_P9_38 3 /* AIN_3 */
#define BBB_P9_39 0 /* AIN_0 */
#define BBB_P9_40 1 /* AIN_1 */
#endif /* LIBBSP_ARM_BEAGLE_GPIO_H */

View File

@@ -345,6 +345,46 @@
#define AM335X_GPIO_CLEARDATAOUT 0x190 #define AM335X_GPIO_CLEARDATAOUT 0x190
#define AM335X_GPIO_SETDATAOUT 0x194 #define AM335X_GPIO_SETDATAOUT 0x194
/* ADC registers */
#define AM335X_ADC (0x44E0D000)
#define AM335X_CM_WKUP (0x44E00400)
#define AM335X_CM_WKUP_ADC_CLKCTRL (AM335X_CM_WKUP+0xBC)
#define AM335X_CM_WKUP_MODULEMODE_ENABLE (0x02)
#define AM335X_CM_WKUP_IDLEST_DISABLED (0x03<<16)
#define AM335X_ADC_CTRL (AM335X_ADC+0x40)
#define AM335X_ADC_STAT (AM335X_ADC+0x44)
#define AM335X_ADC_STEPENABLE (AM335X_ADC+0x54)
#define AM335X_ADC_STEPCONFIG_WRITE_PROTECT_OFF (0x01<<2)
#define AM335X_ADC_STEPCONFIG1 (AM335X_ADC+0x64)
#define AM335X_ADC_STEPDELAY1 (AM335X_ADC+0x68)
#define AM335X_ADC_STEPCONFIG2 (AM335X_ADC+0x6C)
#define AM335X_ADC_STEPDELAY2 (AM335X_ADC+0x70)
#define AM335X_ADC_STEPCONFIG3 (AM335X_ADC+0x74)
#define AM335X_ADC_STEPDELAY3 (AM335X_ADC+0x78)
#define AM335X_ADC_STEPCONFIG4 (AM335X_ADC+0x7C)
#define AM335X_ADC_STEPDELAY4 (AM335X_ADC+0x80)
#define AM335X_ADC_STEPCONFIG5 (AM335X_ADC+0x84)
#define AM335X_ADC_STEPDELAY5 (AM335X_ADC+0x88)
#define AM335X_ADC_STEPCONFIG6 (AM335X_ADC+0x8C)
#define AM335X_ADC_STEPDELAY6 (AM335X_ADC+0x90)
#define AM335X_ADC_STEPCONFIG7 (AM335X_ADC+0x94)
#define AM335X_ADC_STEPDELAY7 (AM335X_ADC+0x98)
#define AM335X_ADC_STEPCONFIG8 (AM335X_ADC+0x9C)
#define AM335X_ADC_STEPDELAY8 (AM335X_ADC+0xA0)
#define AM335X_ADC_AVG0 (0x000)
#define AM335X_ADC_AVG2 (0x001)
#define AM335X_ADC_AVG4 (0x010)
#define AM335X_ADC_AVG8 (0x011)
#define AM335X_ADC_AVG16 (0x100)
#define AM335X_ADC_FIFO0COUNT (AM335X_ADC+0xE4)
#define AM335X_ADC_FIFO0DATA (AM335X_ADC+0x100)
#define AM335X_ADC_FIFO_MASK (0xFFF)
/* AM335X Pad Configuration Register Base */ /* AM335X Pad Configuration Register Base */
#define AM335X_PADCONF_BASE 0x44E10000 #define AM335X_PADCONF_BASE 0x44E10000

View File

@@ -335,6 +335,13 @@ extern rtems_status_code rtems_gpio_group_bsp_specific_operation(
void *arg void *arg
); );
extern rtems_status_code rtems_bsp_select_specific_io(
uint32_t bank,
uint32_t pin,
uint32_t function,
void *pin_data
);
/** /**
* @brief Requests a GPIO pin configuration. * @brief Requests a GPIO pin configuration.
* *
@@ -929,6 +936,12 @@ extern rtems_status_code rtems_gpio_bsp_enable_interrupt(
rtems_gpio_interrupt interrupt rtems_gpio_interrupt interrupt
); );
extern rtems_status_code rtems_bsp_enable_interrupt(
uint32_t bank,
uint32_t pin,
rtems_gpio_interrupt interrupt
);
/** /**
* @brief Stops interrupts from being generated on a given GPIO pin. * @brief Stops interrupts from being generated on a given GPIO pin.
* This must be implemented by each BSP. * This must be implemented by each BSP.
@@ -946,6 +959,12 @@ extern rtems_status_code rtems_gpio_bsp_disable_interrupt(
rtems_gpio_interrupt interrupt rtems_gpio_interrupt interrupt
); );
extern rtems_status_code rtems_bsp_disable_interrupt(
uint32_t bank,
uint32_t pin,
rtems_gpio_interrupt interrupt
);
/** @} */ /** @} */
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -621,16 +621,16 @@ static rtems_status_code gpio_multi_select(
return RTEMS_RESOURCE_IN_USE; return RTEMS_RESOURCE_IN_USE;
} }
}
for ( i = 0; i < pin_count; ++i ) {
sc = rtems_gpio_request_configuration(&pins[i]); sc = rtems_gpio_request_configuration(&pins[i]);
if ( sc != RTEMS_SUCCESSFUL ) { if ( sc != RTEMS_SUCCESSFUL ) {
RELEASE_LOCK(gpio_bank_state[bank].lock);
return sc; return sc;
} }
gpio_pin_state[pins[i].pin_number].on_group = on_group; gpio_pin_state[pins[i].pin_number].on_group = on_group;
RELEASE_LOCK(gpio_bank_state[bank].lock);
} }
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
@@ -1309,6 +1309,9 @@ rtems_status_code rtems_gpio_request_pin(
uint32_t bank; uint32_t bank;
uint32_t pin; uint32_t pin;
#if defined(DEBUG)
printk("rtems_gpio_request_pin : pinNr: %d, function = %d, bsp_specific = %p\n", pin_number, function, bsp_specific);
#endif
if ( pin_number < 0 || pin_number >= BSP_GPIO_PIN_COUNT ) { if ( pin_number < 0 || pin_number >= BSP_GPIO_PIN_COUNT ) {
return RTEMS_INVALID_ID; return RTEMS_INVALID_ID;
} }

View File

@@ -21,6 +21,7 @@ install:
- bsps/arm/beagle/include/bsp/pwmss.h - bsps/arm/beagle/include/bsp/pwmss.h
- bsps/arm/beagle/include/bsp/qep.h - bsps/arm/beagle/include/bsp/qep.h
- bsps/arm/beagle/include/bsp/spi.h - bsps/arm/beagle/include/bsp/spi.h
- bsps/arm/beagle/include/bsp/bbb-adc.h
- destination: ${BSP_INCLUDEDIR}/libcpu - destination: ${BSP_INCLUDEDIR}/libcpu
source: source:
- bsps/arm/include/libcpu/am335x.h - bsps/arm/include/libcpu/am335x.h
@@ -34,6 +35,7 @@ source:
- bsps/arm/beagle/clock/clock.c - bsps/arm/beagle/clock/clock.c
- bsps/arm/beagle/console/console-config.c - bsps/arm/beagle/console/console-config.c
- bsps/arm/beagle/gpio/bbb-gpio.c - bsps/arm/beagle/gpio/bbb-gpio.c
- bsps/arm/beagle/adc/bbb-adc.c
- bsps/arm/beagle/i2c/bbb-i2c.c - bsps/arm/beagle/i2c/bbb-i2c.c
- bsps/arm/beagle/irq/irq.c - bsps/arm/beagle/irq/irq.c
- bsps/arm/beagle/pwm/pwm.c - bsps/arm/beagle/pwm/pwm.c