OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [branches/] [stable_0_2_x/] [or1ksim/] [peripheral/] [gpio.c] - Diff between revs 1308 and 1350

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 1308 Rev 1350
Line 17... Line 17...
   along with this program; if not, write to the Free Software
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
*/
#include <string.h>
#include <string.h>
 
 
 
#include "config.h"
 
 
 
#ifdef HAVE_INTTYPES_H
 
#include <inttypes.h>
 
#endif
 
 
 
#include "port.h"
 
#include "arch.h"
#include "abstract.h"
#include "abstract.h"
#include "gpio.h"
#include "gpio.h"
#include "gpio_i.h"
#include "gpio_i.h"
#include "sim-config.h"
#include "sim-config.h"
#include "pic.h"
#include "pic.h"
Line 28... Line 36...
#include "debug.h"
#include "debug.h"
 
 
static struct gpio_device gpios[MAX_GPIOS];
static struct gpio_device gpios[MAX_GPIOS];
 
 
static void gpio_vapi_read( unsigned long id, unsigned long data );
static void gpio_vapi_read( unsigned long id, unsigned long data );
static unsigned long gpio_read32( unsigned long addr );
static uint32_t gpio_read32( oraddr_t addr );
static void gpio_write32( unsigned long addr, unsigned long value );
static void gpio_write32( oraddr_t addr, uint32_t value );
 
 
static void gpio_external_clock( unsigned long value );
static void gpio_external_clock( unsigned long value );
static void gpio_device_clock( struct gpio_device *gpio );
static void gpio_device_clock( struct gpio_device *gpio );
static int gpio_find_device( unsigned long addr, struct gpio_device **gpio, unsigned long *reladdr );
static int gpio_find_device( oraddr_t addr, struct gpio_device **gpio, oraddr_t *reladdr );
static struct gpio_device *gpio_find_vapi_device( unsigned long id, unsigned *which_vapi );
static struct gpio_device *gpio_find_vapi_device( unsigned long id, unsigned *which_vapi );
 
 
/* Initialize all parameters and state */
/* Initialize all parameters and state */
void gpio_reset( void )
void gpio_reset( void )
{
{
Line 81... Line 89...
    struct gpio_device *gpio = &(gpios[i]);
    struct gpio_device *gpio = &(gpios[i]);
 
 
    if ( gpio->baseaddr == 0 )
    if ( gpio->baseaddr == 0 )
      continue;
      continue;
 
 
    PRINTF( "\nGPIO %u at 0x%08lX:\n", i, gpio->baseaddr );
    PRINTF( "\nGPIO %u at 0x%"PRIxADDR":\n", i, gpio->baseaddr );
    PRINTF( "RGPIO_IN     : 0x%08lX\n", gpio->curr.in );
    PRINTF( "RGPIO_IN     : 0x%08lX\n", gpio->curr.in );
    PRINTF( "RGPIO_OUT    : 0x%08lX\n", gpio->curr.out );
    PRINTF( "RGPIO_OUT    : 0x%08lX\n", gpio->curr.out );
    PRINTF( "RGPIO_OE     : 0x%08lX\n", gpio->curr.oe );
    PRINTF( "RGPIO_OE     : 0x%08lX\n", gpio->curr.oe );
    PRINTF( "RGPIO_INTE   : 0x%08lX\n", gpio->curr.inte );
    PRINTF( "RGPIO_INTE   : 0x%08lX\n", gpio->curr.inte );
    PRINTF( "RGPIO_PTRIG  : 0x%08lX\n", gpio->curr.ptrig );
    PRINTF( "RGPIO_PTRIG  : 0x%08lX\n", gpio->curr.ptrig );
Line 96... Line 104...
}
}
 
 
 
 
/* Convert a memory address to a device struct and relative address.
/* Convert a memory address to a device struct and relative address.
 * Return nonzero on success */
 * Return nonzero on success */
int gpio_find_device( unsigned long addr, struct gpio_device **gpio, unsigned long *reladdr )
int gpio_find_device( oraddr_t addr, struct gpio_device **gpio, oraddr_t *reladdr )
{
{
  unsigned i;
  unsigned i;
  *gpio = NULL;
  *gpio = NULL;
 
 
  for ( i = 0; i < config.ngpios && *gpio == NULL; ++ i ) {
  for ( i = 0; i < config.ngpios && *gpio == NULL; ++ i ) {
Line 135... Line 143...
  return NULL;
  return NULL;
}
}
 
 
 
 
/* Wishbone read */
/* Wishbone read */
unsigned long gpio_read32( unsigned long addr )
uint32_t gpio_read32( oraddr_t addr )
{
{
  struct gpio_device *gpio;
  struct gpio_device *gpio;
  if ( !gpio_find_device( addr, &gpio, &addr ) )        {
  if ( !gpio_find_device( addr, &gpio, &addr ) )        {
    debug( 2, "gpio_read32( 0x%08lX ): Not in registered range(s)\n", addr );
    debug( 2, "gpio_read32( 0x%"PRIxADDR" ): Not in registered range(s)\n", addr );
    return 0;
    return 0;
  }
  }
 
 
  switch( addr ) {
  switch( addr ) {
  case RGPIO_IN: return gpio->curr.in | gpio->curr.out;
  case RGPIO_IN: return gpio->curr.in | gpio->curr.out;
Line 157... Line 165...
  }
  }
}
}
 
 
 
 
/* Wishbone write */
/* Wishbone write */
void gpio_write32( unsigned long addr, unsigned long value )
void gpio_write32( oraddr_t addr, uint32_t value )
{
{
  struct gpio_device *gpio;
  struct gpio_device *gpio;
  if ( !gpio_find_device( addr, &gpio, &addr ) )        {
  if ( !gpio_find_device( addr, &gpio, &addr ) )        {
    debug( 2, "gpio_write32( 0x%08lX ): Not in registered range(s)\n", addr );
    debug( 2, "gpio_write32( 0x%"PRIxADDR" ): Not in registered range(s)\n", addr );
    return;
    return;
  }
  }
 
 
  switch( addr ) {
  switch( addr ) {
  case RGPIO_IN: debug( 5, "GPIO: Cannot write to RGPIO_IN\n" ); break;
  case RGPIO_IN: debug( 5, "GPIO: Cannot write to RGPIO_IN\n" ); break;
Line 184... Line 192...
void gpio_vapi_read( unsigned long id, unsigned long data )
void gpio_vapi_read( unsigned long id, unsigned long data )
{
{
  unsigned which;
  unsigned which;
  struct gpio_device *gpio = gpio_find_vapi_device( id, &which );
  struct gpio_device *gpio = gpio_find_vapi_device( id, &which );
 
 
  debug( 5, "GPIO: id %08x, data %08x\n", id, data );
  debug( 5, "GPIO: id %08lx, data %08lx\n", id, data );
 
 
  if ( !gpio ) {
  if ( !gpio ) {
    debug( 1, "GPIO: VAPI ID %08x is not ours!\n", id );
    debug( 1, "GPIO: VAPI ID %08lx is not ours!\n", id );
    return;
    return;
  }
  }
 
 
  switch( which ) {
  switch( which ) {
  case GPIO_VAPI_DATA:
  case GPIO_VAPI_DATA:
    debug( 4, "GPIO: Next input from VAPI = 0x%08x (RGPIO_OE = 0x%08x)\n", data, gpio->next.oe );
    debug( 4, "GPIO: Next input from VAPI = 0x%08lx (RGPIO_OE = 0x%08lx)\n",
 
           data, gpio->next.oe );
    gpio->next.in = data;
    gpio->next.in = data;
    break;
    break;
  case GPIO_VAPI_AUX:
  case GPIO_VAPI_AUX:
    gpio->auxiliary_inputs = data;
    gpio->auxiliary_inputs = data;
    break;
    break;
Line 263... Line 272...
  gpio->next.out = (gpio->next.out & ~gpio->next.aux) | (gpio->auxiliary_inputs & gpio->next.aux);
  gpio->next.out = (gpio->next.out & ~gpio->next.aux) | (gpio->auxiliary_inputs & gpio->next.aux);
  gpio->next.out &= gpio->next.oe; /* Only output-enabled bits */
  gpio->next.out &= gpio->next.oe; /* Only output-enabled bits */
 
 
  /* If any outputs changed, notify the world (i.e. vapi) */
  /* If any outputs changed, notify the world (i.e. vapi) */
  if ( gpio->next.out != gpio->curr.out ) {
  if ( gpio->next.out != gpio->curr.out ) {
    debug( 4, "GPIO: New output 0x%08x, RGPIO_OE = 0x%08x\n", gpio->next.out, gpio->next.oe );
    debug( 4, "GPIO: New output 0x%08lx, RGPIO_OE = 0x%08lx\n", gpio->next.out,
 
           gpio->next.oe );
    if ( gpio->base_vapi_id )
    if ( gpio->base_vapi_id )
      vapi_send( gpio->base_vapi_id + GPIO_VAPI_DATA, gpio->next.out );
      vapi_send( gpio->base_vapi_id + GPIO_VAPI_DATA, gpio->next.out );
  }
  }
 
 
  /* If any inputs changed and interrupt enabled, generate interrupt */
  /* If any inputs changed and interrupt enabled, generate interrupt */
  if ( gpio->next.in != gpio->curr.in ) {
  if ( gpio->next.in != gpio->curr.in ) {
    debug( 4, "GPIO: New input 0x%08x\n", gpio->next.in );
    debug( 4, "GPIO: New input 0x%08lx\n", gpio->next.in );
 
 
    if ( gpio->next.ctrl & RGPIO_CTRL_INTE ) {
    if ( gpio->next.ctrl & RGPIO_CTRL_INTE ) {
      unsigned changed_bits = gpio->next.in ^ gpio->curr.in; /* inputs that have changed */
      unsigned changed_bits = gpio->next.in ^ gpio->curr.in; /* inputs that have changed */
      unsigned set_bits = changed_bits & gpio->next.in; /* inputs that have been set */
      unsigned set_bits = changed_bits & gpio->next.in; /* inputs that have been set */
      unsigned cleared_bits = changed_bits & gpio->curr.in; /* inputs that have been cleared */
      unsigned cleared_bits = changed_bits & gpio->curr.in; /* inputs that have been cleared */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.