bsp/beagle: Move source files to bsps

This patch is a part of the BSP source reorganization.

Update #3285.
This commit is contained in:
Sebastian Huber
2018-04-25 10:50:12 +02:00
parent 720ebc00d8
commit 531d160672
5 changed files with 4 additions and 4 deletions

View File

@@ -71,16 +71,16 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/beagle/console/console-confi
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/beagle/i2c/bbb-i2c.c
# GPIO
librtemsbsp_a_SOURCES += gpio/bbb-gpio.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/beagle/gpio/bbb-gpio.c
#pwm
librtemsbsp_a_SOURCES += pwm/pwm.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/beagle/pwm/pwm.c
#RTC
librtemsbsp_a_SOURCES += rtc.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/beagle/rtc/rtc.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/rtc/rtc-support.c
# Clock
librtemsbsp_a_SOURCES += clock.c
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/beagle/clock/clock.c
# Cache
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/cache/cache-cp15.c

View File

@@ -1,323 +0,0 @@
/**
* @file
*
* @ingroup arm_beagle
*
* @brief Clock driver configuration.
*/
/*
* Copyright (c) 2014 Ben Gras <beng@shrike-systems.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 <rtems.h>
#include <rtems/timecounter.h>
#include <bsp.h>
#include <libcpu/omap_timer.h>
static struct timecounter beagle_clock_tc;
static omap_timer_registers_t regs_v1 = {
.TIDR = OMAP3_TIMER_TIDR,
.TIOCP_CFG = OMAP3_TIMER_TIOCP_CFG,
.TISTAT = OMAP3_TIMER_TISTAT,
.TISR = OMAP3_TIMER_TISR,
.TIER = OMAP3_TIMER_TIER,
.TWER = OMAP3_TIMER_TWER,
.TCLR = OMAP3_TIMER_TCLR,
.TCRR = OMAP3_TIMER_TCRR,
.TLDR = OMAP3_TIMER_TLDR,
.TTGR = OMAP3_TIMER_TTGR,
.TWPS = OMAP3_TIMER_TWPS,
.TMAR = OMAP3_TIMER_TMAR,
.TCAR1 = OMAP3_TIMER_TCAR1,
.TSICR = OMAP3_TIMER_TSICR,
.TCAR2 = OMAP3_TIMER_TCAR2,
.TPIR = OMAP3_TIMER_TPIR,
.TNIR = OMAP3_TIMER_TNIR,
.TCVR = OMAP3_TIMER_TCVR,
.TOCR = OMAP3_TIMER_TOCR,
.TOWR = OMAP3_TIMER_TOWR,
};
#if IS_AM335X
/* AM335X has a different ip block for the non 1ms timers */
static omap_timer_registers_t regs_v2 = {
.TIDR = AM335X_TIMER_TIDR,
.TIOCP_CFG = AM335X_TIMER_TIOCP_CFG,
.TISTAT = AM335X_TIMER_IRQSTATUS_RAW,
.TISR = AM335X_TIMER_IRQSTATUS,
.TIER = AM335X_TIMER_IRQENABLE_SET,
.TWER = AM335X_TIMER_IRQWAKEEN,
.TCLR = AM335X_TIMER_TCLR,
.TCRR = AM335X_TIMER_TCRR,
.TLDR = AM335X_TIMER_TLDR,
.TTGR = AM335X_TIMER_TTGR,
.TWPS = AM335X_TIMER_TWPS,
.TMAR = AM335X_TIMER_TMAR,
.TCAR1 = AM335X_TIMER_TCAR1,
.TSICR = AM335X_TIMER_TSICR,
.TCAR2 = AM335X_TIMER_TCAR2,
.TPIR = -1, /* UNDEF */
.TNIR = -1, /* UNDEF */
.TCVR = -1, /* UNDEF */
.TOCR = -1, /* UNDEF */
.TOWR = -1 /* UNDEF */
};
#endif
/* which timers are in use? target-dependent.
* initialize at compile time.
*/
#if IS_DM3730
static omap_timer_t dm37xx_timer = {
.base = OMAP3_GPTIMER1_BASE,
.irq_nr = OMAP3_GPT1_IRQ,
.regs = &regs_v1
};
/* free running timer */
static omap_timer_t dm37xx_fr_timer = {
.base = OMAP3_GPTIMER10_BASE,
.irq_nr = OMAP3_GPT10_IRQ,
.regs = &regs_v1
};
static struct omap_timer *fr_timer = &dm37xx_fr_timer;
static struct omap_timer *timer = &dm37xx_timer;
#endif
#if IS_AM335X
/* normal timer */
static omap_timer_t am335x_timer = {
.base = AM335X_DMTIMER1_1MS_BASE,
.irq_nr = AM335X_INT_TINT1_1MS,
.regs = &regs_v1
};
/* free running timer */
static omap_timer_t am335x_fr_timer = {
.base = AM335X_DMTIMER7_BASE,
.irq_nr = AM335X_INT_TINT7,
.regs = &regs_v2
};
static struct omap_timer *fr_timer = &am335x_fr_timer;
static struct omap_timer *timer = &am335x_timer;
#endif
#if IS_AM335X
#define FRCLOCK_HZ (16*1500000)
#endif
#if IS_DM3730
#define FRCLOCK_HZ (8*1625000)
#endif
#ifndef FRCLOCK_HZ
#error expected IS_AM335X or IS_DM3730 to be defined.
#endif
static void
omap3_frclock_init(void)
{
uint32_t tisr;
#if IS_DM3730
/* Stop timer */
mmio_clear(fr_timer->base + fr_timer->regs->TCLR,
OMAP3_TCLR_ST);
/* Use functional clock source for GPTIMER10 */
mmio_set(OMAP3_CM_CLKSEL_CORE, OMAP3_CLKSEL_GPT10);
#endif
#if IS_AM335X
/* Disable the module and wait for the module to be disabled */
set32(CM_PER_TIMER7_CLKCTRL, CM_MODULEMODE_MASK,
CM_MODULEMODE_DISABLED);
while ((mmio_read(CM_PER_TIMER7_CLKCTRL) & CM_CLKCTRL_IDLEST)
!= CM_CLKCTRL_IDLEST_DISABLE);
set32(CLKSEL_TIMER7_CLK, CLKSEL_TIMER7_CLK_SEL_MASK,
CLKSEL_TIMER7_CLK_SEL_SEL2);
while ((read32(CLKSEL_TIMER7_CLK) & CLKSEL_TIMER7_CLK_SEL_MASK)
!= CLKSEL_TIMER7_CLK_SEL_SEL2);
/* enable the module and wait for the module to be ready */
set32(CM_PER_TIMER7_CLKCTRL, CM_MODULEMODE_MASK,
CM_MODULEMODE_ENABLE);
while ((mmio_read(CM_PER_TIMER7_CLKCTRL) & CM_CLKCTRL_IDLEST)
!= CM_CLKCTRL_IDLEST_FUNC);
/* Stop timer */
mmio_clear(fr_timer->base + fr_timer->regs->TCLR,
OMAP3_TCLR_ST);
#endif
/* Start and auto-reload at 0 */
mmio_write(fr_timer->base + fr_timer->regs->TLDR, 0x0);
mmio_write(fr_timer->base + fr_timer->regs->TCRR, 0x0);
/* Set up overflow interrupt */
tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
OMAP3_TISR_TCAR_IT_FLAG;
/* Clear interrupt status */
mmio_write(fr_timer->base + fr_timer->regs->TISR, tisr);
mmio_write(fr_timer->base + fr_timer->regs->TIER,
OMAP3_TIER_OVF_IT_ENA);
/* Start timer, without prescaler */
mmio_set(fr_timer->base + fr_timer->regs->TCLR,
OMAP3_TCLR_OVF_TRG | OMAP3_TCLR_AR | OMAP3_TCLR_ST);
}
static uint32_t
beagle_clock_get_timecount(struct timecounter *tc)
{
return mmio_read(fr_timer->base + fr_timer->regs->TCRR);
}
static void
beagle_clock_initialize(void)
{
uint32_t freq = 1000000UL/rtems_configuration_get_microseconds_per_tick();
/* we only support 1ms resolution */
uint32_t tisr;
#if IS_DM3730
/* Stop timer */
mmio_clear(timer->base + timer->regs->TCLR, OMAP3_TCLR_ST);
/* Use 32 KHz clock source for GPTIMER1 */
mmio_clear(OMAP3_CM_CLKSEL_WKUP, OMAP3_CLKSEL_GPT1);
#endif
#if IS_AM335X
/* disable the module and wait for the module to be disabled */
set32(CM_WKUP_TIMER1_CLKCTRL, CM_MODULEMODE_MASK,
CM_MODULEMODE_DISABLED);
while ((mmio_read(CM_WKUP_TIMER1_CLKCTRL) & CM_CLKCTRL_IDLEST)
!= CM_CLKCTRL_IDLEST_DISABLE);
set32(CLKSEL_TIMER1MS_CLK, CLKSEL_TIMER1MS_CLK_SEL_MASK,
CLKSEL_TIMER1MS_CLK_SEL_SEL2);
while ((read32(CLKSEL_TIMER1MS_CLK) &
CLKSEL_TIMER1MS_CLK_SEL_MASK) !=
CLKSEL_TIMER1MS_CLK_SEL_SEL2);
/* enable the module and wait for the module to be ready */
set32(CM_WKUP_TIMER1_CLKCTRL, CM_MODULEMODE_MASK,
CM_MODULEMODE_ENABLE);
while ((mmio_read(CM_WKUP_TIMER1_CLKCTRL) & CM_CLKCTRL_IDLEST)
!= CM_CLKCTRL_IDLEST_FUNC);
/* Stop timer */
mmio_clear(timer->base + timer->regs->TCLR, OMAP3_TCLR_ST);
#endif
/* Use 1-ms tick mode for GPTIMER1 TRM 16.2.4.2.1 */
mmio_write(timer->base + timer->regs->TPIR, 232000);
mmio_write(timer->base + timer->regs->TNIR, -768000);
mmio_write(timer->base + timer->regs->TLDR,
0xffffffff - (32768 / freq) + 1);
mmio_write(timer->base + timer->regs->TCRR,
0xffffffff - (32768 / freq) + 1);
/* Set up overflow interrupt */
tisr = OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
OMAP3_TISR_TCAR_IT_FLAG;
/* Clear interrupt status */
mmio_write(timer->base + timer->regs->TISR, tisr);
mmio_write(timer->base + timer->regs->TIER, OMAP3_TIER_OVF_IT_ENA);
/* Start timer */
mmio_set(timer->base + timer->regs->TCLR,
OMAP3_TCLR_OVF_TRG | OMAP3_TCLR_AR | OMAP3_TCLR_ST);
/* also initilize the free runnning timer */
omap3_frclock_init();
#if IS_AM335X
/* Disable AM335X watchdog */
mmio_write(AM335X_WDT_BASE+AM335X_WDT_WSPR, 0xAAAA);
while(mmio_read(AM335X_WDT_BASE+AM335X_WDT_WWPS) != 0) ;
mmio_write(AM335X_WDT_BASE+AM335X_WDT_WSPR, 0x5555);
while(mmio_read(AM335X_WDT_BASE+AM335X_WDT_WWPS) != 0) ;
#endif
/* Install timecounter */ \
beagle_clock_tc.tc_get_timecount = beagle_clock_get_timecount;
beagle_clock_tc.tc_counter_mask = 0xffffffff;
beagle_clock_tc.tc_frequency = FRCLOCK_HZ;
beagle_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
rtems_timecounter_install(&beagle_clock_tc);
}
static void beagle_clock_at_tick(void)
{
mmio_write(timer->base + timer->regs->TISR,
OMAP3_TISR_MAT_IT_FLAG | OMAP3_TISR_OVF_IT_FLAG |
OMAP3_TISR_TCAR_IT_FLAG);
}
static rtems_interrupt_handler clock_isr = NULL;
static void beagle_clock_handler_install(rtems_interrupt_handler isr)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
sc = rtems_interrupt_handler_install(
timer->irq_nr,
"Clock",
RTEMS_INTERRUPT_UNIQUE,
isr,
NULL
);
if (sc != RTEMS_SUCCESSFUL) {
rtems_fatal_error_occurred(0xdeadbeef);
}
clock_isr = isr;
}
static void beagle_clock_cleanup(void)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
/* Disable timer */
mmio_clear(timer->base + timer->regs->TCLR, OMAP3_TCLR_ST);
/* Remove interrupt handler */
sc = rtems_interrupt_handler_remove(
timer->irq_nr,
clock_isr,
NULL
);
if (sc != RTEMS_SUCCESSFUL) {
rtems_fatal_error_occurred(0xdeadbeef);
}
clock_isr = NULL;
/* stop frclock */
mmio_clear(fr_timer->base + fr_timer->regs->TCLR, OMAP3_TCLR_ST);
}
#define Clock_driver_support_at_tick() beagle_clock_at_tick()
#define Clock_driver_support_initialize_hardware() beagle_clock_initialize()
#define Clock_driver_support_install_isr(isr) \
beagle_clock_handler_install(isr)
#define Clock_driver_support_shutdown_hardware() beagle_clock_cleanup()
/* Include shared source clock driver code */
#include "../../shared/dev/clock/clockimpl.h"

View File

@@ -1,564 +0,0 @@
/**
* @file
*
* @ingroup arm_beagle
*
* @brief Support for the BeagleBone Black.
*/
/**
* 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.
*/
/* BSP specific function definitions for BeagleBone Black.
* It is totally beased on Generic GPIO API definition.
* For more details related to GPIO API please have a
* look at libbbsp/shared/include/gpio.h
*/
#include <bsp/beagleboneblack.h>
#include <bsp/irq-generic.h>
#include <bsp/gpio.h>
#include <bsp/bbb-gpio.h>
#include <libcpu/am335x.h>
#include <assert.h>
#include <stdlib.h>
/* Currently these definitions are for BeagleBone Black board only
* Later on Beagle-xM board support can be added in this code.
* After support gets added if condition should be removed
*/
#if IS_AM335X
static const uint32_t gpio_bank_addrs[] =
{ AM335X_GPIO0_BASE,
AM335X_GPIO1_BASE,
AM335X_GPIO2_BASE,
AM335X_GPIO3_BASE };
static const rtems_vector_number gpio_bank_vector[] =
{ AM335X_INT_GPIOINT0A,
AM335X_INT_GPIOINT1A,
AM335X_INT_GPIOINT2A,
AM335X_INT_GPIOINT3A };
/* Macro for the gpio pin not having control module offset mapping */
#define CONF_NOT_DEFINED 0x00000000
/* Mapping of gpio pin nuber to the Control module mapped register offset */
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] */
CONF_NOT_DEFINED, /* 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] */
CONF_NOT_DEFINED, /* 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] */
CONF_NOT_DEFINED, /* GPIO1[21] */
CONF_NOT_DEFINED, /* GPIO1[22] */
CONF_NOT_DEFINED, /* GPIO1[23] */
CONF_NOT_DEFINED, /* 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] */
CONF_NOT_DEFINED, /* 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)
{
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);
}
static rtems_status_code bbb_select_pin_function(
uint32_t bank,
uint32_t pin,
uint32_t type
) {
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));
}
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);
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);
return RTEMS_SUCCESSFUL;
}
uint32_t rtems_gpio_bsp_multi_read(uint32_t bank, uint32_t bitmask)
{
return (bbb_reg(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));
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));
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));
}
rtems_status_code rtems_gpio_bsp_select_input(
uint32_t bank,
uint32_t pin,
void *bsp_specific
) {
return bbb_select_pin_function(bank, pin, BBB_DIGITAL_IN);
}
rtems_status_code rtems_gpio_bsp_select_output(
uint32_t bank,
uint32_t pin,
void *bsp_specific
) {
return bbb_select_pin_function(bank, pin, BBB_DIGITAL_OUT);
}
rtems_status_code rtems_gpio_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;
}
rtems_vector_number rtems_gpio_bsp_get_vector(uint32_t bank)
{
return gpio_bank_vector[bank];
}
uint32_t rtems_gpio_bsp_interrupt_line(rtems_vector_number vector)
{
uint32_t event_status;
uint8_t bank_nr = 0;
/* Following loop will get the bank number from vector number */
while (bank_nr < GPIO_BANK_COUNT && vector != gpio_bank_vector[bank_nr])
{
bank_nr++;
}
/* Retrieve the interrupt event status. */
event_status = mmio_read(bbb_reg(bank_nr, AM335X_GPIO_IRQSTATUS_0));
/* Clear the interrupt line. */
mmio_write(
(bbb_reg(bank_nr, AM335X_GPIO_IRQSTATUS_0)), event_status);
return event_status;
}
rtems_status_code rtems_gpio_bsp_enable_interrupt(
uint32_t bank,
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));
switch ( interrupt ) {
case FALLING_EDGE:
/* Enables asynchronous falling edge detection. */
mmio_set(bbb_reg(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));
break;
case BOTH_EDGES:
/* Enables asynchronous falling edge detection. */
mmio_set(bbb_reg(bank, AM335X_GPIO_FALLINGDETECT), BIT(pin));
/* Enables asynchronous rising edge detection. */
mmio_set(bbb_reg(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));
break;
case HIGH_LEVEL:
/* Enables pin high level detection. */
mmio_set(bbb_reg(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));
/* Enables pin high level detection. */
mmio_set(bbb_reg(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");
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));
switch ( interrupt ) {
case FALLING_EDGE:
/* Disables asynchronous falling edge detection. */
mmio_clear(bbb_reg(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));
break;
case BOTH_EDGES:
/* Disables asynchronous falling edge detection. */
mmio_clear(bbb_reg(bank, AM335X_GPIO_FALLINGDETECT), BIT(pin));
/* Disables asynchronous rising edge detection. */
mmio_clear(bbb_reg(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));
break;
case HIGH_LEVEL:
/* Disables pin high level detection. */
mmio_clear(bbb_reg(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));
/* Disables pin high level detection. */
mmio_clear(bbb_reg(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");
return RTEMS_SUCCESSFUL;
}
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;
}
}
REG(register_address) = select_register;
return RTEMS_SUCCESSFUL;
}
rtems_status_code rtems_gpio_bsp_specific_group_operation(
uint32_t bank,
uint32_t *pins,
uint32_t pin_count,
void *arg
) {
return RTEMS_NOT_DEFINED;
}
#endif /* IS_AM335X */
/* For support of BeagleboardxM */
#if IS_DM3730
/* Currently this section is just to satisfy
* GPIO API and to make the build successful.
* Later on support can be added here.
*/
rtems_status_code rtems_gpio_bsp_multi_set(uint32_t bank, uint32_t bitmask)
{
return RTEMS_NOT_DEFINED;
}
rtems_status_code rtems_gpio_bsp_multi_clear(uint32_t bank, uint32_t bitmask)
{
return RTEMS_NOT_DEFINED;
}
uint32_t rtems_gpio_bsp_multi_read(uint32_t bank, uint32_t bitmask)
{
return -1;
}
rtems_status_code rtems_gpio_bsp_set(uint32_t bank, uint32_t pin)
{
return RTEMS_NOT_DEFINED;
}
rtems_status_code rtems_gpio_bsp_clear(uint32_t bank, uint32_t pin)
{
return RTEMS_NOT_DEFINED;
}
uint32_t rtems_gpio_bsp_get_value(uint32_t bank, uint32_t pin)
{
return -1;
}
rtems_status_code rtems_gpio_bsp_select_input(
uint32_t bank,
uint32_t pin,
void *bsp_specific
) {
return RTEMS_NOT_DEFINED;
}
rtems_status_code rtems_gpio_bsp_select_output(
uint32_t bank,
uint32_t pin,
void *bsp_specific
) {
return RTEMS_NOT_DEFINED;
}
rtems_status_code rtems_gpio_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
) {
return RTEMS_NOT_DEFINED;
}
rtems_vector_number rtems_gpio_bsp_get_vector(uint32_t bank)
{
return -1;
}
uint32_t rtems_gpio_bsp_interrupt_line(rtems_vector_number vector)
{
return -1;
}
rtems_status_code rtems_gpio_bsp_enable_interrupt(
uint32_t bank,
uint32_t pin,
rtems_gpio_interrupt interrupt
) {
return RTEMS_NOT_DEFINED;
}
rtems_status_code rtems_gpio_bsp_disable_interrupt(
uint32_t bank,
uint32_t pin,
rtems_gpio_interrupt interrupt
) {
return RTEMS_NOT_DEFINED;
}
rtems_status_code rtems_gpio_bsp_multi_select(
rtems_gpio_multiple_pin_select *pins,
uint32_t pin_count,
uint32_t select_bank
) {
return RTEMS_NOT_DEFINED;
}
rtems_status_code rtems_gpio_bsp_specific_group_operation(
uint32_t bank,
uint32_t *pins,
uint32_t pin_count,
void *arg
) {
return RTEMS_NOT_DEFINED;
}
#endif /* IS_DM3730 */

View File

@@ -1,454 +0,0 @@
/**
* @file
*
* @ingroup arm_beagle
*
* @brief Support for PWM for the BeagleBone Black.
*/
/**
* Copyright (c) 2016 Punit Vara <punitvara@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.
*/
/** This file is based on
* https://github.com/VegetableAvenger/BBBIOlib/blob/master/BBBio_lib/BBBiolib_PWMSS.c
*/
#include <libcpu/am335x.h>
#include <stdio.h>
#include <bsp/gpio.h>
#include <bsp/bbb-gpio.h>
#include <bsp.h>
#include <bsp/bbb-pwm.h>
#include <bsp/beagleboneblack.h>
/* Currently these definitions are for BeagleBone Black board only
* Later on Beagle-xM board support can be added in this code.
* After support gets added if condition should be removed
*/
#if IS_AM335X
/*
* @brief This function selects EPWM module to be enabled
*
* @param pwm_id It is the instance number of EPWM of pwm sub system.
*
* @return Base Address of respective pwm instant.
*/
static uint32_t select_pwm(BBB_PWMSS pwm_id)
{
uint32_t baseAddr=0;
if (pwm_id == BBB_PWMSS0) {
baseAddr = AM335X_EPWM_0_REGS;
} else if (pwm_id == BBB_PWMSS1) {
baseAddr = AM335X_EPWM_1_REGS;
} else if (pwm_id == BBB_PWMSS2) {
baseAddr = AM335X_EPWM_2_REGS;
} else {
baseAddr = 0;
}
return baseAddr;
}
/*
* @brief This function selects PWM Sub system to be enabled
*
* @param pwmss_id The instance number of ePWMSS whose system clocks
* have to be configured.
*
* @return Base Address of respective pwmss instant.
*/
static uint32_t select_pwmss(BBB_PWMSS pwmss_id)
{
uint32_t baseAddr=0;
if (pwmss_id == BBB_PWMSS0) {
baseAddr = AM335X_PWMSS0_MMAP_ADDR;
} else if (pwmss_id == BBB_PWMSS1) {
baseAddr = AM335X_PWMSS1_MMAP_ADDR;
} else if (pwmss_id == BBB_PWMSS2) {
baseAddr = AM335X_PWMSS2_MMAP_ADDR;
} else {
baseAddr = 0;
}
return baseAddr;
}
bool beagle_pwm_pinmux_setup(bbb_pwm_pin_t pin_no, BBB_PWMSS pwm_id)
{
bool is_valid = true;
if(pwm_id == BBB_PWMSS0) {
if (pin_no == BBB_P9_21_0B) {
REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_D0) = BBB_MUXMODE(BBB_P9_21_MUX_PWM);
} else if (pin_no == BBB_P9_22_0A) {
REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_SCLK) = BBB_MUXMODE(BBB_P9_22_MUX_PWM);
} else if (pin_no == BBB_P9_29_0B) {
REG(AM335X_PADCONF_BASE + AM335X_CONF_MCASP0_FSX) = BBB_MUXMODE(BBB_P9_29_MUX_PWM);
} else if (pin_no == BBB_P9_31_0A) {
REG(AM335X_PADCONF_BASE + AM335X_CONF_MCASP0_ACLKX) = BBB_MUXMODE(BBB_P9_31_MUX_PWM);
} else {
is_valid = false;
}
} else if (pwm_id == BBB_PWMSS1) {
if (pin_no == BBB_P8_34_1B) {
REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(11)) = BBB_MUXMODE(BBB_P8_34_MUX_PWM);
} else if (pin_no == BBB_P8_36_1A) {
REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(10)) = BBB_MUXMODE(BBB_P8_36_MUX_PWM);
} else if (pin_no == BBB_P9_14_1A) {
REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(2)) = BBB_MUXMODE(BBB_P9_14_MUX_PWM);
} else if (pin_no == BBB_P9_16_1B) {
REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(3)) = BBB_MUXMODE(BBB_P9_16_MUX_PWM);
} else {
is_valid = false;
}
} else if (pwm_id == BBB_PWMSS2) {
if (pin_no == BBB_P8_13_2B) {
REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(9)) = BBB_MUXMODE(BBB_P8_13_MUX_PWM);
} else if (pin_no == BBB_P8_19_2A) {
REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(8)) = BBB_MUXMODE(BBB_P8_19_MUX_PWM);
} else if (pin_no == BBB_P8_45_2A) {
REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(0)) = BBB_MUXMODE(BBB_P8_45_MUX_PWM);
} else if (pin_no == BBB_P8_46_2B) {
REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(1)) = BBB_MUXMODE(BBB_P8_46_MUX_PWM);
} else {
is_valid = false;
}
} else {
is_valid = false;
}
return is_valid;
}
/**
* @brief This function Enables TBCLK(Time Base Clock) for specific
* EPWM instance of pwmsubsystem.
*
* @param instance It is the instance number of EPWM of pwmsubsystem.
*
* @return true if successful
* false if unsuccessful
**/
static bool pwmss_tbclk_enable(BBB_PWMSS instance)
{
uint32_t enable_bit;
bool is_valid = true;
if (instance == BBB_PWMSS0) {
enable_bit = AM335X_PWMSS_CTRL_PWMSS0_TBCLKEN;
} else if (instance == BBB_PWMSS1) {
enable_bit = AM335X_PWMSS_CTRL_PWMSS1_TBCLKEN;
} else if (instance == BBB_PWMSS2) {
enable_bit = AM335X_PWMSS_CTRL_PWMSS2_TBCLKEN;
} else {
is_valid = false;
}
if (is_valid)
{
REG(AM335X_PADCONF_BASE + AM335X_PWMSS_CTRL) |= enable_bit;
}
return is_valid;
}
/**
* @brief This functions enables clock for EHRPWM module in PWMSS subsystem.
*
* @param pwm_id It is the instance number of EPWM of pwm sub system.
*
* @return true if successful
* false if unsuccessful
*
**/
static bool pwm_clock_enable(BBB_PWMSS pwm_id)
{
const bool id_is_valid = pwm_id < BBB_PWMSS_COUNT;
bool status = true;
if (id_is_valid) {
const uint32_t baseAddr = select_pwmss(pwm_id);
REG(baseAddr + AM335X_PWMSS_CLKCONFIG) |= AM335X_PWMSS_CLK_EN_ACK;
} else {
status = false;
}
return status;
}
/**
* @brief This function configures the L3 and L4_PER system clocks.
* It also configures the system clocks for the specified ePWMSS
* instance.
*
* @param pwmss_id The instance number of ePWMSS whose system clocks
* have to be configured.
*
* 'pwmss_id' can take one of the following values:
* (0 <= pwmss_id <= 2)
*
* @return True if successful
* False if Unsuccessful
*/
static bool pwmss_module_clk_config(BBB_PWMSS pwmss_id)
{
bool is_valid = true;
if(pwmss_id == BBB_PWMSS0) {
const uint32_t is_functional = AM335X_CM_PER_EPWMSS0_CLKCTRL_IDLEST_FUNC <<
AM335X_CM_PER_EPWMSS0_CLKCTRL_IDLEST_SHIFT;
const uint32_t clkctrl = AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS0_CLKCTRL;
const uint32_t idle_bits = AM335X_CM_PER_EPWMSS0_CLKCTRL_IDLEST;
const uint32_t is_enable = AM335X_CM_PER_EPWMSS0_CLKCTRL_MODULEMODE_ENABLE;
const uint32_t module_mode = AM335X_CM_PER_EPWMSS0_CLKCTRL_MODULEMODE;
REG(clkctrl) |= is_enable;
while((REG(clkctrl) & module_mode) != is_enable);
while((REG(clkctrl) & idle_bits) != is_functional);
}
else if(pwmss_id == BBB_PWMSS1) {
const uint32_t is_functional = AM335X_CM_PER_EPWMSS1_CLKCTRL_IDLEST_FUNC <<
AM335X_CM_PER_EPWMSS1_CLKCTRL_IDLEST_SHIFT;
const uint32_t clkctrl = AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS1_CLKCTRL;
const uint32_t idle_bits = AM335X_CM_PER_EPWMSS1_CLKCTRL_IDLEST;
const uint32_t is_enable = AM335X_CM_PER_EPWMSS1_CLKCTRL_MODULEMODE_ENABLE;
const uint32_t module_mode = AM335X_CM_PER_EPWMSS1_CLKCTRL_MODULEMODE;
REG(clkctrl) |= is_enable;
while((REG(clkctrl) & module_mode) != is_enable);
while((REG(clkctrl) & idle_bits) != is_functional);
} else if(pwmss_id == BBB_PWMSS2) {
const uint32_t is_functional = AM335X_CM_PER_EPWMSS2_CLKCTRL_IDLEST_FUNC <<
AM335X_CM_PER_EPWMSS2_CLKCTRL_IDLEST_SHIFT;
const uint32_t clkctrl = AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS2_CLKCTRL;
const uint32_t idle_bits = AM335X_CM_PER_EPWMSS2_CLKCTRL_IDLEST;
const uint32_t is_enable = AM335X_CM_PER_EPWMSS2_CLKCTRL_MODULEMODE_ENABLE;
const uint32_t module_mode = AM335X_CM_PER_EPWMSS2_CLKCTRL_MODULEMODE;
REG(clkctrl) |= is_enable;
while((REG(clkctrl) & module_mode) != is_enable);
while((REG(clkctrl) & idle_bits) != is_functional);
} else
is_valid = false;
return is_valid;
}
bool beagle_pwm_init(BBB_PWMSS pwmss_id)
{
const bool id_is_valid = pwmss_id < BBB_PWMSS_COUNT;
bool status = true;
if(id_is_valid) {
pwmss_module_clk_config(pwmss_id);
pwm_clock_enable(pwmss_id);
pwmss_tbclk_enable(pwmss_id);
} else {
status =false;
}
return status;
}
int beagle_pwm_configure(BBB_PWMSS pwm_id, float pwm_freq, float duty_a, float duty_b)
{
uint32_t baseAddr;
int status = 1;
float cycle = 0.0f,divisor = 0;
unsigned int i,j;
const float CLKDIV_div[] = {1.0,2.0,4.0,8.0,16.0,32.0,64.0,128.0};
const float HSPCLKDIV_div[] = {1.0, 2.0, 4.0, 6.0, 8.0, 10.0,12.0, 14.0};
int NearCLKDIV =7,NearHSPCLKDIV =7,NearTBPRD =0;
if (pwm_freq <= BBB_PWM_FREQ_THRESHOLD) {
status =0;
}
if (duty_a < 0.0f || duty_a > 100.0f || duty_b < 0.0f || duty_b > 100.0f) {
status = 0;
}
duty_a /= 100.0f;
duty_b /= 100.0f;
/** 10^9 /Hz compute time per cycle (ns) */
cycle = 1000000000.0f / pwm_freq;
/** am335x provide (128* 14) divider and per TBPRD means 10ns when divider
* and max TBPRD is 65535 so max cycle is 128 * 8 * 14 * 65535 * 10ns */
divisor = (cycle / 655350.0f);
if (divisor > (128 * 14)) {
return 0;
}
else {
for (i=0;i<8;i++) {
for(j=0 ; j<8; j++) {
if((CLKDIV_div[i] * HSPCLKDIV_div[j]) < (CLKDIV_div[NearCLKDIV]
* HSPCLKDIV_div[NearHSPCLKDIV]) && (CLKDIV_div[i] * HSPCLKDIV_div[j] > divisor)) {
NearCLKDIV = i;
NearHSPCLKDIV = j;
}
}
}
baseAddr = select_pwm(pwm_id);
REG16(baseAddr + AM335X_EPWM_TBCTL) &= ~(AM335X_TBCTL_CLKDIV_MASK | AM335X_TBCTL_HSPCLKDIV_MASK);
const uint16_t clkdiv_clear = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
(~AM335X_EPWM_TBCTL_CLKDIV));
const uint16_t clkdiv_write = ((NearCLKDIV
<< AM335X_EPWM_TBCTL_CLKDIV_SHIFT) & AM335X_EPWM_TBCTL_CLKDIV);
REG16(baseAddr + AM335X_EPWM_TBCTL) = clkdiv_clear | clkdiv_write;
const uint16_t hspclkdiv_clear = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
(~AM335X_EPWM_TBCTL_HSPCLKDIV));
const uint16_t hspclkdiv_write = ((NearHSPCLKDIV <<
AM335X_EPWM_TBCTL_HSPCLKDIV_SHIFT) & AM335X_EPWM_TBCTL_HSPCLKDIV);
REG16(baseAddr + AM335X_EPWM_TBCTL) = hspclkdiv_clear | hspclkdiv_write;
NearTBPRD = (cycle / (10.0 * CLKDIV_div[NearCLKDIV] * HSPCLKDIV_div[NearHSPCLKDIV]));
const uint16_t shadow_mask = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
(~AM335X_EPWM_PRD_LOAD_SHADOW_MASK));
const uint16_t shadow_disable = (((bool)AM335X_EPWM_SHADOW_WRITE_DISABLE <<
AM335X_EPWM_TBCTL_PRDLD_SHIFT) & AM335X_EPWM_PRD_LOAD_SHADOW_MASK);
REG16(baseAddr + AM335X_EPWM_TBCTL) = shadow_mask | shadow_disable;
const uint16_t counter_mask = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
(~AM335X_EPWM_COUNTER_MODE_MASK));
const uint16_t counter_shift = (((unsigned int)AM335X_EPWM_COUNT_UP <<
AM335X_TBCTL_CTRMODE_SHIFT) & AM335X_EPWM_COUNTER_MODE_MASK);
REG16(baseAddr + AM335X_EPWM_TBCTL) = counter_mask | counter_shift;
/*setting clock divider and freeze time base*/
REG16(baseAddr + AM335X_EPWM_CMPB) = (unsigned short)((float)(NearTBPRD) * duty_b);
REG16(baseAddr + AM335X_EPWM_CMPA) = (unsigned short)((float)(NearTBPRD) * duty_a);
REG16(baseAddr + AM335X_EPWM_TBPRD) = (unsigned short)NearTBPRD;
REG16(baseAddr + AM335X_EPWM_TBCNT) = 0;
}
return status;
}
bool beagle_pwm_enable(BBB_PWMSS pwmid)
{
const bool id_is_valid = pwmid < BBB_PWMSS_COUNT;
bool status = true;
if (id_is_valid) {
const uint32_t baseAddr = select_pwm(pwmid);
/* Initially set EPWMxA o/p high , when increasing counter = CMPA toggle o/p of EPWMxA */
REG16(baseAddr + AM335X_EPWM_AQCTLA) = AM335X_EPWM_AQCTLA_ZRO_XAHIGH | (AM335X_EPWM_AQCTLA_CAU_EPWMXATOGGLE << AM335X_EPWM_AQCTLA_CAU_SHIFT);
/* Initially set EPWMxB o/p high , when increasing counter = CMPA toggle o/p of EPWMxB */
REG16(baseAddr + AM335X_EPWM_AQCTLB) = AM335X_EPWM_AQCTLB_ZRO_XBHIGH | (AM335X_EPWM_AQCTLB_CBU_EPWMXBTOGGLE << AM335X_EPWM_AQCTLB_CBU_SHIFT);
REG16(baseAddr + AM335X_EPWM_TBCNT) = 0;
/* Set counter mode : Up-count mode */
REG16(baseAddr + AM335X_EPWM_TBCTL) |= AM335X_TBCTL_FREERUN | AM335X_TBCTL_CTRMODE_UP;
} else {
status =false;
}
return status;
}
bool beagle_pwm_disable(BBB_PWMSS pwmid)
{
const bool id_is_valid = pwmid < BBB_PWMSS_COUNT;
bool status = true;
if (id_is_valid) {
const uint32_t baseAddr = select_pwm(pwmid);
REG16(baseAddr + AM335X_EPWM_TBCTL) = AM335X_EPWM_TBCTL_CTRMODE_STOPFREEZE;
REG16(baseAddr + AM335X_EPWM_AQCTLA) = AM335X_EPWM_AQCTLA_ZRO_XALOW | (AM335X_EPWM_AQCTLA_CAU_EPWMXATOGGLE << AM335X_EPWM_AQCTLA_CAU_SHIFT);
REG16(baseAddr + AM335X_EPWM_AQCTLB) = AM335X_EPWM_AQCTLA_ZRO_XBLOW | (AM335X_EPWM_AQCTLB_CBU_EPWMXBTOGGLE << AM335X_EPWM_AQCTLB_CBU_SHIFT);
REG16(baseAddr + AM335X_EPWM_TBCNT) = 0;
} else {
status = false;
}
return status;
}
/**
* @brief This functions determines whether time base clock is enabled for EPWMSS
*
* @param pwmss_id The instance number of ePWMSS whose time base clock need to
* be checked
*
* @return returns 4 for PWMSS_ID = 2
* returns 2 for PWMSS_ID = 1
* returns 1 for PWMSS_ID = 0
**/
static int pwmss_tb_clock_check(unsigned int pwmss_id)
{
unsigned int reg_value;
/*control module check*/
reg_value = REG(AM335X_CONTROL_MODULE + AM335X_PWMSS_CTRL);
return (reg_value & (1 << pwmss_id));
}
/**
* @brief This functions determines whether clock for EPWMSS is enabled or not.
*
* @param It is the Memory address of the PWMSS instance used.
*
* @return
*
**/
static unsigned int pwmss_clock_en_status(unsigned int pwmid)
{
unsigned int status;
const uint32_t baseAddr = select_pwmss(pwmid);
status = REG(baseAddr + AM335X_PWMSS_CLKSTATUS);
status = status >> 8 & 0x1;
return status;
}
bool beagle_pwmss_is_running(unsigned int pwmss_id)
{
const bool id_is_valid = pwmss_id < BBB_PWMSS_COUNT;
bool status=true;
if (id_is_valid) {
status = pwmss_clock_en_status(pwmss_id);
if(status){
status = pwmss_tb_clock_check(pwmss_id);
} else {
status = false;
}
} else {
status = false;
}
return status;
}
#endif
/* For support of BeagleboardxM */
#if IS_DM3730
/* Currently this section is just to satisfy
* GPIO API and to make the build successful.
* Later on support can be added here.
*/
bool beagle_pwm_init(BBB_PWMSS pwmss_id)
{
return false;
}
bool beagle_pwm_disable(BBB_PWMSS pwmid)
{
return false;
}
bool beagle_pwm_enable(BBB_PWMSS pwmid)
{
return false;
}
int beagle_pwm_configure(BBB_PWMSS pwm_id, float pwm_freq, float duty_a, float duty_b)
{
return -1;
}
bool beagle_pwm_pinmux_setup(bbb_pwm_pin_t pin_no, BBB_PWMSS pwm_id)
{
return false;
}
bool beagle_pwmss_is_running(unsigned int pwmss_id)
{
return false;
}
#endif

View File

@@ -1,276 +0,0 @@
/**
* @file
*
* @ingroup arm_beagle
*
* @brief RTC driver for AM335x SoC.
*
*/
/*
* Copyright (c) 2015 Ragunath <ragunath3252@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.com/license/LICENSE.
*/
#include <bspopts.h>
#if IS_AM335X
#include <rtems.h>
#include <bsp.h>
#include <time.h>
#include <libchip/rtc.h>
#include <libcpu/omap3.h>
#define setbit(a,x) (a | (1<<x))
#define bcd(a) ((a & 0x0f)+ (((a & 0xf0) >> 4 )*10))
#define dec(a) (((a / 10) << 4) | (a % 10))
#define WRITE_WAIT_MAX_COUNT 10000
size_t RTC_Count = 1;
static void rtc_write_enable(void);
static void rtc_write_disable(void);
static int rtc_write_wait(void);
static void rtc_clk_init(void);
void rtc_init(int minor);
void print_time(void);
int am335x_rtc_gettime(int minor,rtems_time_of_day *t);
int am335x_rtc_settime(int minor, const rtems_time_of_day *t);
void am335x_rtc_debug(void);
/*
* probe for a rtc. we always claim to have one.
*/
static bool am335x_rtc_probe (int minor)
{
return true;
}
/*
* Write key values to kick0 and kick1 registers to enable write access
*/
static void rtc_write_enable(void)
{
mmio_write(AM335X_RTC_BASE+AM335X_RTC_KICK0,AM335X_RTC_KICK0_KEY);
mmio_write(AM335X_RTC_BASE+AM335X_RTC_KICK1,AM335X_RTC_KICK1_KEY);
}
/*
* Write random (0x11111111) value to kick0 and kick1 registers to disable write access
*/
static void rtc_write_disable(void)
{
/* Write some random value other than key to disable*/
mmio_write(AM335X_RTC_BASE+AM335X_RTC_KICK0,0x11111111);
mmio_write(AM335X_RTC_BASE+AM335X_RTC_KICK1,0x11111111);
}
/*
* Wait till busy bit is reset
*/
static int rtc_write_wait(void)
{
int i = WRITE_WAIT_MAX_COUNT;
while((mmio_read(AM335X_RTC_BASE+AM335X_RTC_STATUS_REG) & 0x1) && (i--));
if(i == 0)
return RTEMS_RESOURCE_IN_USE;
else
return RTEMS_SUCCESSFUL;
}
/*
* Initialize RTC clock
*/
static void rtc_clk_init(void)
{
uint32_t a = 0x0;
a = setbit(a,1);
/* IDLEST = 0x0 & MODULEMODE = 0x1*/
mmio_write(CM_RTC_BASE+CM_RTC_RTC_CLKCTRL,a);
a = 0x0;
/*32K rtc clock active*/
a = setbit(a,9);
a = setbit(a,8);
mmio_write(CM_RTC_BASE+CM_RTC_CLKSTCTRL,a);
}
void rtc_init(int minor)
{
uint32_t a = 0x0;
rtc_clk_init();
/*
* Steps to enable RTC
* 1. Enable the module clock domains (rtc_clk_init).
* 2. Enable the RTC module using CTRL_REG.RTC_disable. (Default enabled. Nothing done)
* 3. Enable the 32K clock from PER PLL, if using the internal RTC oscillator.
* 4. Write to the kick registers (KICK0R, KICK1R) in the RTC.
* 5. Configure the timer in RTCSS for desired application (set time and date, alarm wakeup, and so on).
* 6. Start the RTC (in CTRL_REG.STOP_RTC).
*/
rtc_write_enable();
a = setbit(a,0);
mmio_write(AM335X_RTC_BASE+AM335X_RTC_SYSCONFIG,a);
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_OSC_CLOCK);
a = setbit(a,6);
mmio_write(AM335X_RTC_BASE+AM335X_RTC_OSC_CLOCK,a);
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_CTRL_REG);
a = setbit(a,0);
mmio_write(AM335X_RTC_BASE+AM335X_RTC_CTRL_REG,a);
rtc_write_disable();
}
int am335x_rtc_gettime(int minor,rtems_time_of_day *t)
{
uint32_t a = 0x0;
if(minor != 0)
return RTEMS_INVALID_NUMBER;
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_SECS);
t->second = bcd(a);
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_MINS);
t->minute = bcd(a);
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_HOURS);
t->hour = bcd(a);
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_DAYS);
t->day = bcd(a);
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_MONTHS);
t->month = bcd(a);
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_YEARS);
t->year = bcd(a)+2000;
t->ticks=0;
return RTEMS_SUCCESSFUL;
}
int am335x_rtc_settime(int minor,const rtems_time_of_day *t)
{
uint32_t a=0x0;
int rv;
if(minor != 0)
return RTEMS_INVALID_NUMBER;
rtc_write_enable();
/* Wait till the busy bit is reset to write again*/
a = t->second;
rv=rtc_write_wait();
if(rv != RTEMS_SUCCESSFUL)
return rv;
a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_SECS,dec(a) & 0x7f);
a = t->minute;
rv=rtc_write_wait();
if(rv != RTEMS_SUCCESSFUL)
return rv;
a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_MINS,dec(a) & 0x7f);
a = t->hour;
rv=rtc_write_wait();
if(rv != RTEMS_SUCCESSFUL)
return rv;
a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_HOURS,dec(a) & 0x3f);
a = t->day;
rv=rtc_write_wait();
if(rv != RTEMS_SUCCESSFUL)
return rv;
a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_DAYS,dec(a) & 0x3f);
a = t->month;
rv=rtc_write_wait();
if(rv != RTEMS_SUCCESSFUL)
return rv;
a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_MONTHS,dec(a) & 0x1f);
a = t->year;
rv=rtc_write_wait();
if(rv != RTEMS_SUCCESSFUL)
return rv;
a = mmio_write(AM335X_RTC_BASE+AM335X_RTC_YEARS,(dec(a)%100) & 0xff);
rtc_write_disable();
return rv;
}
#if BBB_DEBUG
void print_time(void)
{
uint32_t a = 0x0;
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_SECS);
printk("\n\rSecs %x",a);
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_MINS);
printk("\n\rMins %x",a);
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_HOURS);
printk("\n\rHours %x",a);
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_DAYS);
printk("\n\rDays %x",a);
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_MONTHS);
printk("\n\r Months %x",a);
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_YEARS);
printk("\n\rYears %x",a);
a = mmio_read(AM335X_RTC_BASE+AM335X_RTC_WEEKS);
printk("\n\rWeeks %x",a);
}
void am335x_rtc_debug(void)
{
int i;
rtems_time_of_day t,r;
t.second = 1;
t.minute = 1;
t.hour = 1;
t.day = 7;
t.month = 3;
t. year = 2015;
am335x_rtc_settime(0,&t);
am335x_rtc_gettime(0,&r);
printk("Secs %x",r.second);
printk("Mins %x",r.minute);
printk("Hours %x",r.hour);
printk("Days %x",r.day);
printk("Months %x",r.month);
printk("Years %x",r.year);
}
#endif
/*
* driver function table.
*/
rtc_fns am335x_rtc_fns = {
rtc_init,
am335x_rtc_gettime,
am335x_rtc_settime
};
/*
* the following table configures the RTC drivers used in this BSP
*/
rtc_tbl RTC_Table[] = {
{
"/dev/rtc", /* sDeviceName */
RTC_CUSTOM, /* deviceType */
&am335x_rtc_fns, /* pDeviceFns */
am335x_rtc_probe, /* deviceProbe */
NULL, /* pDeviceParams */
0, /* ulCtrlPort1 */
0, /* ulDataPort */
NULL, /* getRegister */
NULL /* setRegister */
}
};
#endif