⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m8260ioport.c

📁 au1500开发的应用程序
💻 C
字号:
/* m8260IOPort.c - Motorola MPC8260 I/O Port driver */

/* Copyright Copyright 2002-2005 Founder Communications, Inc. */

/*
modification history
--------------------
01a,24jan05,fhchen  adapted from wrSbc8260Atm/sysIOPort.c (ver 01a)
*/

/*
DESCRIPTION

This module contains the MPC8260 I/O port driver routines.

*/

/* includes */

#include <vxWorks.h>
#include "sysGpio.h"
#include "m8260IOPort.h"
#include "m8260IntrCtl.h"
#include "drv/mem/m8260Siu.h"

/* forward declarations */

LOCAL STATUS m8260PortCInumToPin(int intNum);

/* macros */

#define INUM_TO_PIN(intNum)	(m8260PortCInumToPin(intNum))

/***********************************************************************
*
* m8260IOPortInit - initialize mpc8260 I/O ports
*
* This routines put all four ports to a known state: registers 
* are set to zero, that is all pins are set as input GPIO pins.
*
* RETURNS: N/A
*/

void m8260IOPortInit(void)
    {
    int immrVal = vxImmrGet ();

    /*  reset port A, B, C, and D */
    
    *M8260_IOP_PAPAR( immrVal ) = 0x00000000;
    *M8260_IOP_PADIR( immrVal ) = 0x00000000;
    *M8260_IOP_PAODR( immrVal ) = 0x00000000;

    *M8260_IOP_PBPAR( immrVal ) = 0x00000000;
    *M8260_IOP_PBDIR( immrVal ) = 0x00000000;
    *M8260_IOP_PBODR( immrVal ) = 0x00000000;

    *M8260_IOP_PCPAR( immrVal ) = 0x00000000;
    *M8260_IOP_PCDIR( immrVal ) = 0x00000000;
    *M8260_IOP_PCSO( immrVal )  = 0x00000000;

    *M8260_IOP_PDPAR( immrVal ) = 0x00000000;
    *M8260_IOP_PDDIR( immrVal ) = 0x00000000;
    *M8260_IOP_PDSO( immrVal )  = 0x00000000;
    }

/***********************************************************************
*
* m8260IOPortReset - reset I/O ports
*
* This ruotine simple call m8260IOPortInit to reset all ports.
*
* RETURNS: N/A
*/

void m8260IOPortReset(void)
    {
    m8260IOPortInit();
    }

/***********************************************************************
*
* m8260IOPortRead - get logic level of a pin
*
* This routines read the data from a I/O pin.
*
* NOTE: for Port B and Port D, PIN0 ~ PIN3 are invalid!
* 
* RETURNS:
* - LOGIC_HIGH or LOGIC_LOW on success.
* - ERROR if pin is invalid.
*/

int m8260IOPortRead
(
    int port,                                /* port to read */
    int pin                                  /* pin to read */
    )
    {
    int retVal = LOGIC_LOW;

    switch(port)
        {
        case PORT_A:
            *M8260_IOP_PAPAR(INTERNAL_MEM_MAP_ADDR) &= ~pin; /* set as gpio */
            *M8260_IOP_PASO (INTERNAL_MEM_MAP_ADDR) &= ~pin; /*  */
            *M8260_IOP_PADIR(INTERNAL_MEM_MAP_ADDR) &= ~pin; /* input */
            if (*M8260_IOP_PADAT(INTERNAL_MEM_MAP_ADDR) & pin)
		retVal = LOGIC_HIGH;
            break;
            
        case PORT_B:
            if(pin & PIN0123)                /* check parameter */
                {
                return (ERROR);
                }
            *M8260_IOP_PBPAR(INTERNAL_MEM_MAP_ADDR) &= ~pin;
            *M8260_IOP_PBSO (INTERNAL_MEM_MAP_ADDR) &= ~pin;
            *M8260_IOP_PBDIR(INTERNAL_MEM_MAP_ADDR) &= ~pin;
            if (*M8260_IOP_PBDAT(INTERNAL_MEM_MAP_ADDR) & pin)
                retVal = LOGIC_HIGH;
            break;
            
        case PORT_C:
            *M8260_IOP_PCPAR(INTERNAL_MEM_MAP_ADDR) &= ~pin;
            *M8260_IOP_PCSO (INTERNAL_MEM_MAP_ADDR) &= ~pin;
            *M8260_IOP_PCDIR(INTERNAL_MEM_MAP_ADDR) &= ~pin;
            if (*M8260_IOP_PCDAT(INTERNAL_MEM_MAP_ADDR) & pin)
                retVal = LOGIC_HIGH;
            break;
            
        case PORT_D:
            if(pin & PIN0123)                /* check parameter */
                {
                 return (ERROR);
                }           
            *M8260_IOP_PDPAR(INTERNAL_MEM_MAP_ADDR) &= ~pin;
            *M8260_IOP_PDSO (INTERNAL_MEM_MAP_ADDR) &= ~pin;
            *M8260_IOP_PDDIR(INTERNAL_MEM_MAP_ADDR) &= ~pin;
            if (*M8260_IOP_PDDAT(INTERNAL_MEM_MAP_ADDR) & pin)
                retVal = LOGIC_HIGH;
            break;
            
        default:
            break;
        }
    
    return (retVal);
    }

/***********************************************************************
*
* m8260IOPortWrite - write data to a I/O pin
*
* This routines write data to a I/O pin.
*
* NOTE:
* - for Port B and Port D, PIN0 ~ PIN3 are invalid! When written
*   to these pins, nothing happens
* 
* RETURNS: N/A
*/

void m8260IOPortWrite
(
    int port,                                /* port to write */
    int pin,                                 /* pin to write */
    int level                                /* high or low */
    )
    {
    
    switch(port)
        {
        case PORT_A:
            *M8260_IOP_PAPAR(INTERNAL_MEM_MAP_ADDR) &= ~pin; /* set as gpio */
            *M8260_IOP_PASO (INTERNAL_MEM_MAP_ADDR) &= ~pin; /*  */
            *M8260_IOP_PADIR(INTERNAL_MEM_MAP_ADDR) |=  pin; /* set as output */
            ((LOGIC_HIGH == level) ?
             (*M8260_IOP_PADAT(INTERNAL_MEM_MAP_ADDR) |=  pin) : /* high */
             (*M8260_IOP_PADAT(INTERNAL_MEM_MAP_ADDR) &= ~pin)); /* low */
            break;
            
        case PORT_B:
            if(pin & PIN0123)                /* check parameter */
                {
                return;               /* invalid pin */
                } 
            *M8260_IOP_PBPAR(INTERNAL_MEM_MAP_ADDR) &= ~pin;
            *M8260_IOP_PBSO (INTERNAL_MEM_MAP_ADDR) &= ~pin;
            *M8260_IOP_PBDIR(INTERNAL_MEM_MAP_ADDR) |=  pin;
            ((LOGIC_HIGH == level) ?
             (*M8260_IOP_PBDAT(INTERNAL_MEM_MAP_ADDR) |=  pin) :
             (*M8260_IOP_PBDAT(INTERNAL_MEM_MAP_ADDR) &= ~pin));
            break;
            
        case PORT_C:
            *M8260_IOP_PCPAR(INTERNAL_MEM_MAP_ADDR) &= ~pin;
            *M8260_IOP_PCSO (INTERNAL_MEM_MAP_ADDR) &= ~pin;
            *M8260_IOP_PCDIR(INTERNAL_MEM_MAP_ADDR) |=  pin;
            ((LOGIC_HIGH == level) ?
             (*M8260_IOP_PCDAT(INTERNAL_MEM_MAP_ADDR) |=  pin) :
             (*M8260_IOP_PCDAT(INTERNAL_MEM_MAP_ADDR) &= ~pin));
            break;
            
        case PORT_D:
            if(pin & PIN0123)                /* check parameter */
                {
                return;               /* invalid pin */
                } 
            *M8260_IOP_PDPAR(INTERNAL_MEM_MAP_ADDR) &= ~pin;
            *M8260_IOP_PDSO (INTERNAL_MEM_MAP_ADDR) &= ~pin;
            *M8260_IOP_PDDIR(INTERNAL_MEM_MAP_ADDR) |=  pin;
            ((LOGIC_HIGH == level) ?
             (*M8260_IOP_PDDAT(INTERNAL_MEM_MAP_ADDR) |=  pin) :
             (*M8260_IOP_PDDAT(INTERNAL_MEM_MAP_ADDR) &= ~pin));
            break;

        default:
            break;
        }
    
    }

/***********************************************************************
*
*  m8260IOPortIntConnect - connect a port c interrupt to ISR
*
* This routine connect a vector of port C to a specific ISR. In MPC8260
* pin0 to pin15 of port C can generate interrupt to the internal
* interrupt controller. Additional registers must be set when processing
* these interrupts.
* 
* NOTE:
* - DO no use intConnect DIRECTLY for port C interrupts.
* - See mpc8260 manual(rev 0) 35.6: Interrupt from port C
* - Please set interrupt type before invoke this routine!
* 
* RETURNS: OK, or ERROR if invalid .
*/

STATUS m8260IOPortIntConnect
(
    VOIDFUNCPTR *vector,                     /* interrupt vector */
    VOIDFUNCPTR routine,                     /* ISR routine */
    int parameter                            /* parameter for ISR */
    )
    {
    STATUS status = OK;
    int pin = 0x0;
    int intNum = 0;
    
    /* get interrupt number and check parameter */

    intNum = m8260IvecToInum(vector);
    if(intNum < INUM_PC15 || intNum > INUM_PC0)
        return (ERROR);
    
    /* connect ISR */
                     
    status = intConnect(vector, routine, parameter);

    /* get pin number from vector number */
    
    pin = m8260PortCInumToPin(intNum);
    
    *M8260_IOP_PCSO(INTERNAL_MEM_MAP_ADDR)   &= ~pin; 
    *M8260_IOP_PCDIR(INTERNAL_MEM_MAP_ADDR)  &= ~pin; /* input */
    *M8260_IOP_PCPAR(INTERNAL_MEM_MAP_ADDR)  &= ~pin; /* gpio */

    /*
     * configure interrupt type:
     * Supposed to be done here, but it can be done before calling
     * this routine. Is that right?
     */

    /* enable interrupt. should set MASK_H register, use intEnable instead */
    
    intEnable(intNum);

    return (status);
    
    }

/***********************************************************************
*
* m8260PortCInumToPin - get pin number from interrupt number 
*
* This routine convert Port C's interrupt number to pin number.
* Interupt number are defined in m8260IntrCtl.h, pin number are
* defined in m8260IOPort.h
* 
* NOTE:
* - Only pin 0 ~ 15 can generate interrupt to the core. That is
*   only INUM_PC0 ~ INUM_PC15 are valid interrupt number for this 
*   routine.
*
* RETURNS: pin number on success, or ERROR on invalid interrupt number.
*/

LOCAL STATUS m8260PortCInumToPin(int intNum)
    {
    
    int pin = PIN15;
    
    /* check parameter */
    
    if(intNum < INUM_PC15 || intNum > INUM_PC0)
        return (ERROR);     /* invalid interrupt number */
    
    /* get pin number */
    
    while((intNum--) != INUM_PC15)
        {
        pin <<= 1;
        }
    
    return (pin);
    
    }

#if 0
/***********************************************************************
*
* m8260PortCPinToInum - get interrupt number from pin number 
*
* This routine convert Port C's pin number to interrupt number.
* Interupt number are defined in m8260IntrCtl.h, pin number are
* defined in m8260IOPort.h
* 
* NOTE:
* - Only pin 0 ~ 15 can generate interrupt to the core. That is
*   only PIN0 ~ PIN15 are valid pin number for this routine.
*
* RETURNS: interrupt number on success, or ERROR on invalid pin number.
*/

LOCAL STATUS m8260PortCPinToInum(int pin)
    {
    
    int intNum = INUM_PC15;

    /* check parameter */

    if(pin & 0x0000FFFF)
        return (ERROR);     /* invalid pin number */

    /* get interrupt number */

    while(pin != PIN15)
        {
        intNum++;
        pin >>= 1;
        }
		
    return (intNum);

    }

#endif

/***********************************************************************
*
* m8260IOPortRegShow - show MPC8260 I/O ports registers 
*
* This routine pirnt out content of specific I/O port registers. When 
* port number are invalid, all registers are shown.
*  
* NOTE:
* - This routine may result in un-expected system behavior, and 
*   do not reflect current state of I/O ports.
* - See sysGpio.h for valid I/O port number.
*
* RETURNS: N/A
*/

#include <stdio.h>

void m8260IOPortRegShow
    (
     int port   /* port to show */
    )
    {
   
    char *fmtHead = "%-11.11s%-11.11s%-11.11s%-11.11s%-11.11s%-11.11s\n";
    char *fmtItem = "%-11.11s%-11.8#x%-11.8#x%-11.8#x%-11.8#x%-11.8#x\n";
    
    int immrVal = vxImmrGet();
    
    /* print out headline */

    printf("\n");
    printf(fmtHead, "I/O Port", "PODR", "PSOR", "PDIR", "PPAR", "PDAT");
    printf(fmtHead, "--------", "----------", "----------", 
            "----------", "----------", "----------");
        
    /* print out registers according to port number */
    
    switch(port)
        {
        case PORT_A:
            printf(fmtItem, "Port A", 
                    *M8260_IOP_PAODR(immrVal),
                    *M8260_IOP_PASO(immrVal),
                    *M8260_IOP_PADIR(immrVal),
                    *M8260_IOP_PAPAR(immrVal),
                    *M8260_IOP_PADAT(immrVal));
            break;
            
        case PORT_B:
            printf(fmtItem, "Port B", 
                    *M8260_IOP_PBODR(immrVal),
                    *M8260_IOP_PBSO(immrVal),
                    *M8260_IOP_PBDIR(immrVal),
                    *M8260_IOP_PBPAR(immrVal),
                    *M8260_IOP_PBDAT(immrVal));
            break;              

        case PORT_C:
            printf(fmtItem, "Port C", 
                    *M8260_IOP_PCODR(immrVal),
                    *M8260_IOP_PCSO(immrVal),
                    *M8260_IOP_PCDIR(immrVal),
                    *M8260_IOP_PCPAR(immrVal),
                    *M8260_IOP_PCDAT(immrVal));
            break;

        case PORT_D:
            printf(fmtItem, "Port D", 
                    *M8260_IOP_PDODR(immrVal),
                    *M8260_IOP_PDSO(immrVal),
                    *M8260_IOP_PDDIR(immrVal),
                    *M8260_IOP_PDPAR(immrVal),
                    *M8260_IOP_PDDAT(immrVal));
            break;                

        default:
            printf(fmtItem, "Port A", 
                    *M8260_IOP_PAODR(immrVal),
                    *M8260_IOP_PASO(immrVal),
                    *M8260_IOP_PADIR(immrVal),
                    *M8260_IOP_PAPAR(immrVal),
                    *M8260_IOP_PADAT(immrVal));
            printf(fmtItem, "Port B", 
                    *M8260_IOP_PBODR(immrVal),
                    *M8260_IOP_PBSO(immrVal),
                    *M8260_IOP_PBDIR(immrVal),
                    *M8260_IOP_PBPAR(immrVal),
                    *M8260_IOP_PBDAT(immrVal));
            printf(fmtItem, "Port C", 
                    *M8260_IOP_PCODR(immrVal),
                    *M8260_IOP_PCSO(immrVal),
                    *M8260_IOP_PCDIR(immrVal),
                    *M8260_IOP_PCPAR(immrVal),
                    *M8260_IOP_PCDAT(immrVal));            
            printf(fmtItem, "Port D", 
                    *M8260_IOP_PDODR(immrVal),
                    *M8260_IOP_PDSO(immrVal),
                    *M8260_IOP_PDDIR(immrVal),
                    *M8260_IOP_PDPAR(immrVal),
                    *M8260_IOP_PDDAT(immrVal));
            break;        
        }
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -