Skip to content

Commit

Permalink
ODROID-XU3/4: Implement get pin MUX, PU/PD mode, get/set drive strength
Browse files Browse the repository at this point in the history
Change-Id: I57586fcf2d1ebf4e6e938e67c8af0c194b22c3ea
  • Loading branch information
joshua-yang committed Jan 10, 2019
1 parent 258ea14 commit 96152ee
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 19 deletions.
129 changes: 110 additions & 19 deletions wiringPi/odroidxu3.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,17 +97,20 @@ static struct libodroid *lib = NULL;
/*----------------------------------------------------------------------------*/
static int gpioToGPSETReg (int pin);
static int gpioToGPLEVReg (int pin);
static int gpioToPUENReg (int pin);
static int gpioToPUPDReg (int pin);
static int gpioToShiftReg (int pin);
static int gpioToGPFSELReg (int pin);
static int gpioToDSReg (int pin);

/*----------------------------------------------------------------------------*/
// wiringPi core function
/*----------------------------------------------------------------------------*/
static int getModeToGpio (int mode, int pin);
static void setPadDrive (int pin, int value);
static int getPadDrive (int pin);
static void pinMode (int pin, int mode);
static int getAlt (int pin);
static int getPUPD (int pin);
static void pullUpDnControl (int pin, int pud);
static int digitalRead (int pin);
static void digitalWrite (int pin, int value);
Expand Down Expand Up @@ -175,18 +178,6 @@ static int gpioToGPLEVReg (int pin)
return -1;
}

/*----------------------------------------------------------------------------*/
//
// offset to the GPIO Pull up/down enable regsiter
//
/*----------------------------------------------------------------------------*/
static int gpioToPUENReg (int pin)
{
msg(MSG_WARN, "%s : unused function in xu3/4. pin = %d\n",
__func__, pin);
return 0;
}

/*----------------------------------------------------------------------------*/
//
// offset to the GPIO Pull up/down regsiter
Expand Down Expand Up @@ -264,6 +255,33 @@ static int gpioToGPFSELReg (int pin)
}
return -1;
}

/*----------------------------------------------------------------------------*/
//
// offset to the GPIO Drive Strength register
//
/*----------------------------------------------------------------------------*/
static int gpioToDSReg (int pin)
{
switch (pin) {
case GPIO_X1_START...GPIO_X1_END:
return (GPIO_X1_DRV_OFFSET >> 2);
case GPIO_X2_START...GPIO_X2_END:
return (GPIO_X2_DRV_OFFSET >> 2);
case GPIO_X3_START...GPIO_X3_END:
return (GPIO_X3_DRV_OFFSET >> 2);
case GPIO_A0_START...GPIO_A0_END:
return (GPIO_A0_DRV_OFFSET >> 2);
case GPIO_A2_START...GPIO_A2_END:
return (GPIO_A2_DRV_OFFSET >> 2);
case GPIO_B3_START...GPIO_B3_END:
return (GPIO_B3_DRV_OFFSET >> 2);
default:
break;
}
return -1;
}

/*----------------------------------------------------------------------------*/
static int getModeToGpio (int mode, int pin)
{
Expand All @@ -287,6 +305,54 @@ static int getModeToGpio (int mode, int pin)
return -1;
}

/*----------------------------------------------------------------------------*/
static void setPadDrive (int pin, int value)
{
int ds, shift;

if (lib->mode == MODE_GPIO_SYS)
return;

if ((pin = getModeToGpio(lib->mode, pin)) < 0)
return;

if (value < 0 || value > 3) {
msg(MSG_WARN, "%s : Invalid value %d (Must be 0 ~ 3)\n", __func__, value);
return;
}

ds = gpioToDSReg(pin);
shift = gpioToShiftReg(pin) << 1;

if (pin < 100) {
*(gpio + ds) &= ~(0b11 << shift);
*(gpio + ds) |= (value << shift);
} else {
*(gpio1 + ds) &= ~(0b11 << shift);
*(gpio1 + ds) |= (value << shift);
}
}

/*----------------------------------------------------------------------------*/
static int getPadDrive (int pin)
{
int ds, shift;

if (lib->mode == MODE_GPIO_SYS)
return;

if ((pin = getModeToGpio(lib->mode, pin)) < 0)
return;

ds = gpioToDSReg(pin);
shift = gpioToShiftReg(pin) << 1;

if (pin < 100)
return (*(gpio + ds) >> shift) & 0b11;
else
return (*(gpio1 + ds) >> shift) & 0b11;
}

/*----------------------------------------------------------------------------*/
static void pinMode (int pin, int mode)
{
Expand Down Expand Up @@ -335,25 +401,47 @@ static void pinMode (int pin, int mode)
/*----------------------------------------------------------------------------*/
static int getAlt (int pin)
{
int fsel, shift;
int fsel, shift, mode;

if (lib->mode == MODE_GPIO_SYS)
return 0;

if ((pin = getModeToGpio(lib->mode, pin)) < 0)
return 2;

fsel = gpioToGPFSELReg(pin);
shift = gpioToShiftReg(pin) << 2;

if (pin < 100) // GPX0,1,2,3
fsel = (*(gpio + gpioToGPFSELReg(pin)) & (0xF << shift));
mode = (*(gpio + fsel) >> shift) & 0xF;
else // GPA0,1,2, GPB0,1,2,3,4
fsel = (*(gpio1 + gpioToGPFSELReg(pin)) & (0xF << shift));
mode = (*(gpio1 + fsel) >> shift) & 0xF;

// If mode is bigger than 8 including EXT_INT(0xF), it returns ALT7
return mode <= 8 ? mode : 8;
}

if (fsel & (0xE << shift))
return 2;
/*----------------------------------------------------------------------------*/
static int getPUPD (int pin)
{
int pupd, shift, pull;

if (lib->mode == MODE_GPIO_SYS)
return;

if ((pin = getModeToGpio(lib->mode, pin)) < 0)
return;

pupd = gpioToPUPDReg(pin);
shift = gpioToShiftReg(pin) << 1;

if (pin < 100)
pull = (*(gpio + pupd) >> shift) & 0x3;
else
pull = (*(gpio1 + pupd) >> shift) & 0x3;

return (fsel & (0x1 << shift)) ? 1 : 0;
// Pull up when 0x3, down when 0x1
return pull == 0 ? 0 : (pull == 0x3 ? 1 : 2);
}

/*----------------------------------------------------------------------------*/
Expand Down Expand Up @@ -615,8 +703,11 @@ void init_odroidxu3 (struct libodroid *libwiring)

/* wiringPi Core function initialize */
libwiring->getModeToGpio = getModeToGpio;
libwiring->setPadDrive = setPadDrive;
libwiring->getPadDrive = getPadDrive;
libwiring->pinMode = pinMode;
libwiring->getAlt = getAlt;
libwiring->getPUPD = getPUPD;
libwiring->pullUpDnControl = pullUpDnControl;
libwiring->digitalRead = digitalRead;
libwiring->digitalWrite = digitalWrite;
Expand Down
6 changes: 6 additions & 0 deletions wiringPi/odroidxu3.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,21 @@
#define GPIO_X1_CON_OFFSET 0x0C20
#define GPIO_X1_DAT_OFFSET 0x0C24
#define GPIO_X1_PUD_OFFSET 0x0C28
#define GPIO_X1_DRV_OFFSET 0x0C2C
#define GPIO_X1_END 23

#define GPIO_X2_START 24
#define GPIO_X2_CON_OFFSET 0x0C40
#define GPIO_X2_DAT_OFFSET 0x0C44
#define GPIO_X2_PUD_OFFSET 0x0C48
#define GPIO_X2_DRV_OFFSET 0x0C4C
#define GPIO_X2_END 31

#define GPIO_X3_START 32
#define GPIO_X3_CON_OFFSET 0x0C60
#define GPIO_X3_DAT_OFFSET 0x0C64
#define GPIO_X3_PUD_OFFSET 0x0C68
#define GPIO_X3_DRV_OFFSET 0x0C6C
#define GPIO_X3_END 39

// GPA0,1,2, GPB0,1,2,3,4
Expand All @@ -41,18 +44,21 @@
#define GPIO_A0_CON_OFFSET 0x0000
#define GPIO_A0_DAT_OFFSET 0x0004
#define GPIO_A0_PUD_OFFSET 0x0008
#define GPIO_A0_DRV_OFFSET 0x000C
#define GPIO_A0_END 178

#define GPIO_A2_START 185
#define GPIO_A2_CON_OFFSET 0x0040
#define GPIO_A2_DAT_OFFSET 0x0044
#define GPIO_A2_PUD_OFFSET 0x0048
#define GPIO_A2_DRV_OFFSET 0x004C
#define GPIO_A2_END 192

#define GPIO_B3_START 207
#define GPIO_B3_CON_OFFSET 0x00C0
#define GPIO_B3_DAT_OFFSET 0x00C4
#define GPIO_B3_PUD_OFFSET 0x00C8
#define GPIO_B3_DRV_OFFSET 0x00CC
#define GPIO_B3_END 214

#ifdef __cplusplus
Expand Down

0 comments on commit 96152ee

Please sign in to comment.