📄 m8260ioport.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 + -