Compare commits

...

4 Commits

Author SHA1 Message Date
Heinz Junkes
5f314cf970 Merge branch '6' into '6'
bbb bsp: add modified gpio handling and adc section

See merge request rtems/rtos/rtems!697
2025-11-13 23:59:02 +00:00
Kinsey Moore
23accdc0bb cpukit/flashdev: Return error for missing callbacks
When a callback does not exist, the Flashdev API should return error
where possible instead of success. When the API returns success for
missing callbacks, the Flashdev API client code may end up using
uninitialized variables as if they were filled by the API.

Closes #5392
2025-11-10 12:36:33 -06:00
Kinsey Moore
2c8973005d bsps/shared/xqspi_flash.c: Add support for sector information
Updates #5392
2025-11-10 12:35:56 -06:00
Heinz Junkes
36562fe411 add gpio handling and adc section to BBB 2025-09-03 15:46:59 +02:00
10 changed files with 609 additions and 96 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 <stdlib.h>
#include <stdio.h>
/* 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.
* 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
static const uint32_t gpio_bank_addrs[] =
static const uint32_t gpio_bank_addrs[] =
{ AM335X_GPIO0_BASE,
AM335X_GPIO1_BASE,
AM335X_GPIO2_BASE,
AM335X_GPIO3_BASE };
AM335X_GPIO1_BASE,
AM335X_GPIO2_BASE,
AM335X_GPIO3_BASE };
static const rtems_vector_number gpio_bank_vector[] =
{ AM335X_INT_GPIOINT0A,
@@ -47,10 +52,161 @@ static const rtems_vector_number gpio_bank_vector[] =
AM335X_INT_GPIOINT2A,
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 */
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(
@@ -60,50 +216,47 @@ static rtems_status_code bbb_select_pin_function(
) {
if ( type == BBB_DIGITAL_IN ) {
mmio_set(bbb_reg(bank, AM335X_GPIO_OE), BIT(pin));
} else {
mmio_clear(bbb_reg(bank, AM335X_GPIO_OE), BIT(pin));
mmio_set((gpio_bank_addrs[bank] + AM335X_GPIO_OE), BIT(pin));
}
else {
mmio_clear((gpio_bank_addrs[bank] + AM335X_GPIO_OE), BIT(pin));
}
return RTEMS_SUCCESSFUL;
}
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;
}
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;
}
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)
{
mmio_set(bbb_reg(bank, AM335X_GPIO_SETDATAOUT), BIT(pin));
mmio_write((gpio_bank_addrs[bank] + AM335X_GPIO_SETDATAOUT), BIT(pin));
return RTEMS_SUCCESSFUL;
}
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;
}
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(
@@ -131,13 +284,42 @@ rtems_status_code rtems_gpio_bsp_select_specific_io(
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(
uint32_t bank,
uint32_t pin,
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)
@@ -157,12 +339,11 @@ uint32_t rtems_gpio_bsp_interrupt_line(rtems_vector_number vector)
}
/* 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. */
mmio_write(
(bbb_reg(bank_nr, AM335X_GPIO_IRQSTATUS_0)), event_status);
mmio_write(gpio_bank_addrs[bank_nr] + AM335X_GPIO_IRQSTATUS_0, event_status);
return event_status;
}
@@ -171,135 +352,135 @@ rtems_status_code rtems_gpio_bsp_enable_interrupt(
uint32_t pin,
rtems_gpio_interrupt interrupt
) {
/* Enable IRQ generation for the specific pin */
mmio_set(bbb_reg(bank, AM335X_GPIO_IRQSTATUS_SET_0), BIT(pin));
return rtems_bsp_enable_interrupt(bank, pin, interrupt);
}
rtems_status_code rtems_bsp_enable_interrupt(
uint32_t bank,
uint32_t pin,
rtems_gpio_interrupt interrupt
) {
switch ( interrupt ) {
case FALLING_EDGE:
/* 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;
case RISING_EDGE:
/* 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;
case BOTH_EDGES:
/* 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. */
mmio_set(bbb_reg(bank, AM335X_GPIO_RISINGDETECT), BIT(pin));
mmio_set(gpio_bank_addrs[bank] + AM335X_GPIO_RISINGDETECT, BIT(pin));
break;
case LOW_LEVEL:
/* 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;
case HIGH_LEVEL:
/* Enables pin high level detection. */
mmio_set(bbb_reg(bank, AM335X_GPIO_LEVELDETECT1), BIT(pin));
/* Enables pin high level detection. */
mmio_set(gpio_bank_addrs[bank] + AM335X_GPIO_LEVELDETECT1, BIT(pin));
break;
case BOTH_LEVELS:
/* 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. */
mmio_set(bbb_reg(bank, AM335X_GPIO_LEVELDETECT1), BIT(pin));
mmio_set(gpio_bank_addrs[bank] + AM335X_GPIO_LEVELDETECT1, BIT(pin));
break;
case NONE:
default:
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
* This period is required to clean the synchronization edge/
* level detection pipeline
*/
asm volatile("nop"); asm volatile("nop"); asm volatile("nop");
asm volatile("nop"); asm volatile("nop");
arm_delay(5);
return RTEMS_SUCCESSFUL;
}
rtems_status_code rtems_gpio_bsp_disable_interrupt(
uint32_t bank,
uint32_t pin,
rtems_gpio_interrupt interrupt
) {
/* Clear IRQ generation for the specific pin */
mmio_write(bbb_reg(bank, AM335X_GPIO_IRQSTATUS_CLR_0), BIT(pin));
return rtems_bsp_disable_interrupt(bank, pin, interrupt);
}
rtems_status_code rtems_bsp_disable_interrupt(
uint32_t bank,
uint32_t pin,
rtems_gpio_interrupt interrupt
) {
switch ( interrupt ) {
case FALLING_EDGE:
/* 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;
case RISING_EDGE:
/* 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;
case BOTH_EDGES:
/* 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. */
mmio_clear(bbb_reg(bank, AM335X_GPIO_RISINGDETECT), BIT(pin));
mmio_clear(gpio_bank_addrs[bank] + AM335X_GPIO_RISINGDETECT, BIT(pin));
break;
case LOW_LEVEL:
/* 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;
case HIGH_LEVEL:
/* 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;
case BOTH_LEVELS:
/* 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. */
mmio_clear(bbb_reg(bank, AM335X_GPIO_LEVELDETECT1), BIT(pin));
mmio_clear(gpio_bank_addrs[bank] + AM335X_GPIO_LEVELDETECT1, BIT(pin));
break;
case NONE:
default:
return RTEMS_UNSATISFIED;
}
/* The detection starts after 5 clock cycles as per AM335X TRM
* This period is required to clean the synchronization edge/
* level detection pipeline
*/
asm volatile("nop"); asm volatile("nop"); asm volatile("nop");
asm volatile("nop"); asm volatile("nop");
mmio_write((gpio_bank_addrs[bank] + AM335X_GPIO_IRQSTATUS_CLR_0), BIT(pin));
mmio_write((gpio_bank_addrs[bank] + AM335X_GPIO_IRQSTATUS_CLR_1), BIT(pin));
return RTEMS_SUCCESSFUL;
}
/* I have unfortunately lost the overview a little ....
*/
rtems_status_code rtems_gpio_bsp_multi_select(
rtems_gpio_multiple_pin_select *pins,
uint32_t pin_count,
uint32_t select_bank
) {
uint32_t register_address;
uint32_t select_register;
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 ) {
if ( pins[i].function == DIGITAL_INPUT ) {
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;
}
bbb_select_pin_function((pins[i].pin_number)/32, (pins[i].pin_number)%32, pins[i].function);
}
REG(register_address) = select_register;
return RTEMS_SUCCESSFUL;
}
@@ -311,7 +492,6 @@ rtems_status_code rtems_gpio_bsp_specific_group_operation(
) {
return RTEMS_NOT_DEFINED;
}
#endif /* IS_AM335X */
/* 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 */
/* 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_8 67 /* GPIO2_3 */
#define BBB_P8_9 69 /* GPIO2_5 */
@@ -50,7 +54,33 @@
#define BBB_P8_17 27 /* GPIO0_27 */
#define BBB_P8_18 65 /* GPIO2_1 */
#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_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 */
#define BBB_P9_11 30 /* GPIO0_30 */
@@ -61,12 +91,40 @@
#define BBB_P9_16 51 /* GPIO1_19 */
#define BBB_P9_17 5 /* GPIO0_5 */
#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_24 15 /* GPIO0_15 */
#define BBB_P9_25 117 /* GPIO3_21 */
#define BBB_P9_26 14 /* GPIO1_14 */
#define BBB_P9_27 115/* GPIO3_19 */
#define BBB_P9_30 112/* GPIO3_16 */
#define BBB_P9_41 20 /* GPIO0_20 */
#define BBB_P9_27 115 /* GPIO3_19 */
#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 */
#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_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 */
#define AM335X_PADCONF_BASE 0x44E10000

View File

@@ -335,6 +335,13 @@ extern rtems_status_code rtems_gpio_group_bsp_specific_operation(
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.
*
@@ -929,6 +936,12 @@ extern rtems_status_code rtems_gpio_bsp_enable_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.
* This must be implemented by each BSP.
@@ -946,6 +959,12 @@ extern rtems_status_code rtems_gpio_bsp_disable_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

View File

@@ -621,16 +621,16 @@ static rtems_status_code gpio_multi_select(
return RTEMS_RESOURCE_IN_USE;
}
}
for ( i = 0; i < pin_count; ++i ) {
sc = rtems_gpio_request_configuration(&pins[i]);
if ( sc != RTEMS_SUCCESSFUL ) {
RELEASE_LOCK(gpio_bank_state[bank].lock);
return sc;
}
gpio_pin_state[pins[i].pin_number].on_group = on_group;
RELEASE_LOCK(gpio_bank_state[bank].lock);
}
return RTEMS_SUCCESSFUL;
@@ -1309,6 +1309,9 @@ rtems_status_code rtems_gpio_request_pin(
uint32_t bank;
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 ) {
return RTEMS_INVALID_ID;
}

View File

@@ -99,6 +99,28 @@ static int xqspi_page_count(
return 0;
}
static int xqspi_sector_count(
rtems_flashdev *flash,
int *sector_count
)
{
*sector_count = QspiPsu_NOR_Get_Device_Size(flash->driver) /
QspiPsu_NOR_Get_Sector_Size(flash->driver);
return 0;
}
static int xqspi_sector_info_by_off(
rtems_flashdev *flash,
off_t search_offset,
off_t *sector_offset,
size_t *sector_size
)
{
*sector_size = QspiPsu_NOR_Get_Sector_Size(flash->driver);
*sector_offset = search_offset - (search_offset%((off_t)(*sector_size)));
return 0;
}
static int xqspi_write_block_size(
rtems_flashdev *flash,
size_t *write_block_size
@@ -177,6 +199,8 @@ rtems_flashdev* xqspi_flash_init(XQspiPsu *xQspiDev)
flash->page_info_by_index = &xqspi_page_info_by_index;
flash->page_count = &xqspi_page_count;
flash->write_block_size = &xqspi_write_block_size;
flash->sector_count = &xqspi_sector_count;
flash->sector_info_by_offset = &xqspi_sector_info_by_off;
flash->region_table = ftable;
return flash;

View File

@@ -104,7 +104,7 @@ static uint32_t rtems_flashdev_ioctl_jedec_id(
rtems_flashdev *flash
);
static uint32_t rtems_flashdev_ioctl_flash_type(
static int rtems_flashdev_ioctl_flash_type(
rtems_flashdev *flash,
void *arg
);
@@ -734,7 +734,7 @@ static int rtems_flashdev_ioctl_erase(
int status;
if ( flash->erase == NULL ) {
return 0;
rtems_set_errno_and_return_minus_one( ENOSYS );
}
erase_args_1 = (rtems_flashdev_region *) arg;
@@ -890,14 +890,14 @@ static uint32_t rtems_flashdev_ioctl_jedec_id( rtems_flashdev *flash )
}
}
static uint32_t rtems_flashdev_ioctl_flash_type(
static int rtems_flashdev_ioctl_flash_type(
rtems_flashdev *flash,
void *arg
)
{
rtems_flashdev_flash_type *type = (rtems_flashdev_flash_type*)arg;
if ( flash->flash_type == NULL ) {
return 0;
rtems_set_errno_and_return_minus_one( ENOSYS );
} else {
return ( *flash->flash_type )( flash, type );
}
@@ -914,7 +914,7 @@ static int rtems_flashdev_ioctl_pageinfo_offset(
rtems_set_errno_and_return_minus_one( EINVAL );
}
if ( flash->page_info_by_offset == NULL ) {
return 0;
rtems_set_errno_and_return_minus_one( ENOSYS );
} else {
page_info = (rtems_flashdev_ioctl_page_info *) arg;
return ( *flash->page_info_by_offset )( flash,
@@ -933,7 +933,7 @@ static int rtems_flashdev_ioctl_pageinfo_index( rtems_flashdev *flash,
rtems_set_errno_and_return_minus_one( EINVAL );
}
if ( flash->page_info_by_index == NULL ) {
return 0;
rtems_set_errno_and_return_minus_one( ENOSYS );
} else {
page_info = (rtems_flashdev_ioctl_page_info *) arg;
return ( *flash->page_info_by_index )( flash,
@@ -949,7 +949,7 @@ static int rtems_flashdev_ioctl_page_count( rtems_flashdev *flash, void *arg )
rtems_set_errno_and_return_minus_one( EINVAL );
}
if ( flash->page_count == NULL ) {
return 0;
rtems_set_errno_and_return_minus_one( ENOSYS );
} else {
return ( *flash->page_count )( flash, ( (int *) arg ) );
}
@@ -964,7 +964,7 @@ static int rtems_flashdev_ioctl_write_block_size(
rtems_set_errno_and_return_minus_one( EINVAL );
}
if ( flash->write_block_size == NULL ) {
return 0;
rtems_set_errno_and_return_minus_one( ENOSYS );
} else {
return ( *flash->write_block_size )( flash, ( (size_t *) arg ) );
}
@@ -981,7 +981,7 @@ static int rtems_flashdev_ioctl_sectorinfo_offset(
rtems_set_errno_and_return_minus_one( EINVAL );
}
if ( flash->sector_info_by_offset == NULL ) {
return 0;
rtems_set_errno_and_return_minus_one( ENOSYS );
} else {
sector_info = (rtems_flashdev_ioctl_sector_info *) arg;
return ( *flash->sector_info_by_offset )( flash,
@@ -997,7 +997,7 @@ static int rtems_flashdev_ioctl_sector_count( rtems_flashdev *flash, void *arg )
rtems_set_errno_and_return_minus_one( EINVAL );
}
if ( flash->sector_count == NULL ) {
return 0;
rtems_set_errno_and_return_minus_one( ENOSYS );
} else {
return ( *flash->sector_count )( flash, ( (int *) arg ) );
}
@@ -1048,7 +1048,7 @@ static int rtems_flashdev_ioctl_oob_bytes_per_page(
rtems_set_errno_and_return_minus_one( EINVAL );
}
if ( flash->oob_bytes_per_page == NULL ) {
return 0;
rtems_set_errno_and_return_minus_one( ENOSYS );
} else {
return ( *flash->oob_bytes_per_page )( flash, ( (size_t *) arg ) );
}
@@ -1061,7 +1061,7 @@ static int rtems_flashdev_ioctl_oob_read( rtems_flashdev *flash, void *arg )
rtems_set_errno_and_return_minus_one( EINVAL );
}
if ( flash->oob_read == NULL ) {
return 0;
rtems_set_errno_and_return_minus_one( ENOSYS );
} else {
rw_info = (rtems_flashdev_ioctl_oob_rw_info *) arg;
return ( *flash->oob_read )(
@@ -1160,7 +1160,7 @@ static int rtems_flashdev_ioctl_oob_write( rtems_flashdev *flash, void *arg )
rtems_set_errno_and_return_minus_one( EINVAL );
}
if ( flash->oob_write == NULL ) {
return 0;
rtems_set_errno_and_return_minus_one( ENOSYS );
} else {
rw_info = (rtems_flashdev_ioctl_oob_rw_info *) arg;
return ( *flash->oob_write )(
@@ -1199,7 +1199,7 @@ static int rtems_flashdev_ioctl_sector_mark_bad(
rtems_set_errno_and_return_minus_one( EINVAL );
}
if ( flash->sector_mark_bad == NULL ) {
return 0;
rtems_set_errno_and_return_minus_one( ENOSYS );
} else {
return ( *flash->sector_mark_bad)( flash, *(uintptr_t *) arg );
}
@@ -1235,7 +1235,7 @@ static int rtems_flashdev_ioctl_sectorhealth(
rtems_set_errno_and_return_minus_one( EINVAL );
}
if ( flash->sector_health == NULL ) {
return 0;
rtems_set_errno_and_return_minus_one( ENOSYS );
} else {
sector_health = arg;
return ( *flash->sector_health)( flash, sector_health->location, &sector_health->sector_bad );

View File

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