Skip to content

Commit

Permalink
Revisions to MCP23017 driver code
Browse files Browse the repository at this point in the history
  • Loading branch information
Memotech-Bill committed Dec 10, 2024
1 parent 7cda27e commit b67de9f
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 45 deletions.
1 change: 1 addition & 0 deletions src/memu/diag.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ static FLAGVAL flagvals[] =
{"log-type", DIAG_LOG_TYPE},
{"init", DIAG_INIT},
{"gpio", DIAG_GPIO},
{"i2c", DIAG_I2C},
{"vga-mode", DIAG_VGA_MODE},
{"vga-port", DIAG_VGA_PORT},
{"vga-refresh", DIAG_VGA_REFRESH},
Expand Down
1 change: 1 addition & 0 deletions src/memu/diag.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ enum DIAGS {
DIAG_LOG_TYPE,
DIAG_INIT,
DIAG_GPIO,
DIAG_I2C,
DIAG_VGA_MODE,
DIAG_VGA_PORT,
DIAG_VGA_REFRESH,
Expand Down
95 changes: 53 additions & 42 deletions src/memu/gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,128 +375,139 @@ Code Model Revision RAM Manufacturer
int i2c_init (const char *psDev, int iAddr)
{
int fd = open (psDev, O_RDWR);
diag_message (DIAG_I2C, "i2c_init (%s, 0x%02X)", psDev, iAddr);
diag_message (DIAG_I2C, "fd = %d", fd);
if ( fd < 0 ) return I2C_EOPEN;
if ( ioctl (fd, I2C_SLAVE, iAddr) < 0 ) return I2C_EADDR;
int ierr = ioctl (fd, I2C_SLAVE, iAddr);
diag_message (DIAG_I2C, "ierr = %d", ierr);
if ( ierr < 0 ) return I2C_EADDR;
return fd;
}

void i2c_term (int fd)
void i2c_term (struct gio_dev *pdev)
{
if ( fd > 0 ) close (fd);
diag_message (DIAG_I2C, "i2c_term");
if ( pdev->fd > 0 ) close (pdev->fd);
}

int i2c_put (int fd, int iAddr, int iLen, unsigned char *pbData)
int i2c_put (struct gio_dev *pdev, int iReg, int iLen, unsigned char *pbData)
{
diag_message (DIAG_I2C, "i2c_put (%d, 0x%02X, %d, 0x%02X)", pdev->fd, iReg, iLen, *pbData);
int iSta = I2C_OK;
struct i2c_rdwr_ioctl_data pkt;
struct i2c_msg msg[1];
unsigned char *pbBuff = NULL;
if ( fd < 0 ) return I2C_EOPEN;
if ( pdev->fd < 0 ) return I2C_EOPEN;
pbBuff = (unsigned char *) malloc (iLen + 1);
if ( pbBuff == NULL ) return I2C_EMEM;
pbBuff[0] = (unsigned char) iAddr;
pbBuff[0] = (unsigned char) iReg;
memcpy (&pbBuff[1], pbData, iLen);

msg[0].addr = iAddr;
msg[0].addr = pdev->iAddr;
msg[0].flags = 0;
msg[0].len = iLen + 1;
msg[0].buf = pbBuff;

pkt.msgs = msg;
pkt.nmsgs = 1;

if ( ioctl (fd, I2C_RDWR, &pkt) < 0 ) iSta = I2C_EIO;
int ierr = ioctl (pdev->fd, I2C_RDWR, &pkt);
diag_message (DIAG_I2C, "ioctl = %d", ierr);
if ( ierr < 0 ) iSta = I2C_EIO;
free (pbBuff);
return iSta;
}

int i2c_get (int fd, int iAddr, int iLen, unsigned char *pbData)
int i2c_get (struct gio_dev *pdev, int iReg, int iLen, unsigned char *pbData)
{
unsigned char bAddr = (unsigned char) iAddr;
diag_message (DIAG_I2C, "i2c_get (%d, 0x%02X, %d, %p)", pdev->fd, iReg, iLen, pbData);
unsigned char bAddr = (unsigned char) iReg;
struct i2c_rdwr_ioctl_data pkt;
struct i2c_msg msg[2];

if ( fd < 0 ) return I2C_EOPEN;
if ( pdev->fd < 0 ) return I2C_EOPEN;

msg[0].addr = iAddr;
msg[0].addr = pdev->iAddr;
msg[0].flags = 0;
msg[0].len = iLen + 1;
msg[0].buf = &bAddr;
msg[1].addr = iAddr;
msg[1].addr = pdev->iAddr;
msg[1].flags = I2C_M_RD;
msg[1].len = iLen;
msg[1].buf = pbData;

pkt.msgs = msg;
pkt.nmsgs = 2;

if ( ioctl (fd, I2C_RDWR, &pkt) < 0 ) return I2C_EIO;
int ierr = ioctl (pdev->fd, I2C_RDWR, &pkt);
diag_message (DIAG_I2C, "ioctl = %d", ierr);
if ( ierr < 0 ) return I2C_EIO;
return I2C_OK;
}

int xio_init (const char *psDev, int iAddr)
int xio_init (const char *psDev, int iReg)
{
return i2c_init (psDev, iAddr);
return i2c_init (psDev, iReg);
}

void xio_term (int fd)
void xio_term (struct gio_dev *pdev)
{
i2c_term (fd);
i2c_term (pdev);
}

void xio_input (int fd, uint32_t iMask)
void xio_input (struct gio_dev *pdev, uint32_t iMask)
{
unsigned char bDir[2];
i2c_get (fd, 0x00, 2, bDir);
i2c_get (pdev, 0x00, 2, bDir);
bDir[0] |= (unsigned char) ( 0xFF & iMask );
bDir[1] |= (unsigned char) ( 0xFF & ( iMask >> 8 ) );
i2c_put (fd, 0x00, 2, bDir);
i2c_put (pdev, 0x00, 2, bDir);
}

void xio_output (int fd, uint32_t iMask)
void xio_output (struct gio_dev *pdev, uint32_t iMask)
{
unsigned char bDir[2];
i2c_get (fd, 0x00, 2, bDir);
i2c_get (pdev, 0x00, 2, bDir);
bDir[0] &= ~ (unsigned char) ( 0xFF & iMask );
bDir[1] &= ~ (unsigned char) ( 0xFF & ( iMask >> 8 ) );
i2c_put (fd, 0x00, 2, bDir);
i2c_put (pdev, 0x00, 2, bDir);
}

void xio_pullup (int fd, uint32_t iMask)
void xio_pullup (struct gio_dev *pdev, uint32_t iMask)
{
unsigned char bPull[2];
i2c_get (fd, 0x0C, 2, bPull);
i2c_get (pdev, 0x0C, 2, bPull);
bPull[0] |= (unsigned char) ( 0xFF & iMask );
bPull[1] |= (unsigned char) ( 0xFF & ( iMask >> 8 ) );
i2c_put (fd, 0x0C, 2, bPull);
i2c_put (pdev, 0x0C, 2, bPull);
}

void xio_pullnone (int fd, uint32_t iMask)
void xio_pullnone (struct gio_dev *pdev, uint32_t iMask)
{
unsigned char bPull[2];
i2c_get (fd, 0x0C, 2, bPull);
i2c_get (pdev, 0x0C, 2, bPull);
bPull[0] &= ~ (unsigned char) ( 0xFF & iMask );
bPull[1] &= ~ (unsigned char) ( 0xFF & ( iMask >> 8 ) );
i2c_put (fd, 0x0C, 2, bPull);
i2c_put (pdev, 0x0C, 2, bPull);
}

int xio_get (int fd, uint32_t iMask)
int xio_get (struct gio_dev *pdev, uint32_t iMask)
{
unsigned char bData[2];
i2c_get (fd, 0x12, 2, bData);
i2c_get (pdev, 0x12, 2, bData);
return ( ( (int) bData[1] << 8 ) | ( (int) bData[0] ) ) & iMask;
}

void xio_put (int fd, uint32_t iMask, int iBits)
void xio_put (struct gio_dev *pdev, uint32_t iMask, int iBits)
{
unsigned char bData[2];
i2c_get (fd, 0x14, 2, bData);
i2c_get (pdev, 0x14, 2, bData);
bData[0] &= ~ (unsigned char) ( 0xFF & iMask );
bData[1] &= ~ (unsigned char) ( 0xFF & ( iMask >> 8 ) );
iBits &= iMask;
bData[0] |= (unsigned char) ( 0xFF & iBits );
bData[1] |= (unsigned char) ( 0xFF & ( iBits >> 8 ) );
i2c_put (fd, 0x14, 2, bData);
i2c_put (pdev, 0x14, 2, bData);
}
#endif

Expand Down Expand Up @@ -538,7 +549,7 @@ void gio_term (void)
#if HAVE_HW_MCP23017
if ( pdev->type == gio_xio )
{
if ( pdev->fd > 0 ) xio_term (pdev->fd);
if ( pdev->fd > 0 ) xio_term (pdev);
}
#endif
pdev = pdev->pnext;
Expand Down Expand Up @@ -594,7 +605,7 @@ void gio_input (int nPin, struct gio_pin *ppin, uint32_t iData)
#if HAVE_HW_MCP23017
if ( pdev->type == gio_xio )
{
if ( ( pdev->fd > 0 ) && ( pdev->iData ) ) xio_input (pdev->fd, pdev->iData);
if ( ( pdev->fd > 0 ) && ( pdev->iData ) ) xio_input (pdev, pdev->iData);
}
#endif
pdev = pdev->pnext;
Expand All @@ -617,7 +628,7 @@ void gio_output (int nPin, struct gio_pin *ppin, uint32_t iData)
#if HAVE_HW_MCP23017
if ( pdev->type == gio_xio )
{
if ( ( pdev->fd > 0 ) && ( pdev->iData ) ) xio_output (pdev->fd, pdev->iData);
if ( ( pdev->fd > 0 ) && ( pdev->iData ) ) xio_output (pdev, pdev->iData);
}
#endif
pdev = pdev->pnext;
Expand All @@ -640,7 +651,7 @@ void gio_pullup (int nPin, struct gio_pin *ppin, uint32_t iData)
#if HAVE_HW_MCP23017
if ( pdev->type == gio_xio )
{
if ( ( pdev->fd > 0 ) && ( pdev->iData ) ) xio_pullup (pdev->fd, pdev->iData);
if ( ( pdev->fd > 0 ) && ( pdev->iData ) ) xio_pullup (pdev, pdev->iData);
}
#endif
pdev = pdev->pnext;
Expand All @@ -663,7 +674,7 @@ void gio_pullnone (int nPin, struct gio_pin *ppin, uint32_t iData)
#if HAVE_HW_MCP23017
if ( pdev->type == gio_xio )
{
if ( ( pdev->fd > 0 ) && ( pdev->iData ) ) xio_pullnone (pdev->fd, pdev->iData);
if ( ( pdev->fd > 0 ) && ( pdev->iData ) ) xio_pullnone (pdev, pdev->iData);
}
#endif
pdev = pdev->pnext;
Expand All @@ -688,7 +699,7 @@ uint32_t gio_get (int nPin, struct gio_pin *ppin)
#if HAVE_HW_MCP23017
if ( pdev->type == gio_xio )
{
if ( ( pdev->fd > 0 ) && ( pdev->iMask ) ) pdev->iData = xio_get (pdev->fd, pdev->iMask);
if ( ( pdev->fd > 0 ) && ( pdev->iMask ) ) pdev->iData = xio_get (pdev, pdev->iMask);
}
#endif
pdev = pdev->pnext;
Expand Down Expand Up @@ -734,7 +745,7 @@ void gio_put (int nPin, struct gio_pin *ppin, uint32_t iData)
#if HAVE_HW_MCP23017
if ( pdev->type == gio_xio )
{
if ( ( pdev->fd > 0 ) && ( pdev->iData ) ) xio_put (pdev->fd, pdev->iMask, pdev->iData);
if ( ( pdev->fd > 0 ) && ( pdev->iData ) ) xio_put (pdev, pdev->iMask, pdev->iData);
}
#endif
pdev = pdev->pnext;
Expand Down
6 changes: 3 additions & 3 deletions src/memu/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ void gpio_pullnone (struct gio_dev *pdev, uint32_t iMask);
uint32_t gpio_get (struct gio_dev *pdev, uint32_t iMask);
int gpio_revision (void);
int i2c_init (const char *psDev, int iAddr);
void i2c_term (int fd);
int i2c_put (int fd, int iAddr, int iLen, unsigned char *pbData);
int i2c_get (int fd, int iAddr, int iLen, unsigned char *pbData);
void i2c_term (struct gio_dev *pdev);
int i2c_put (struct gio_dev *pdev, int iReg, int iLen, unsigned char *pbData);
int i2c_get (struct gio_dev *pdev, int iReg, int iLen, unsigned char *pbData);
int gio_init (void);
void gio_term (void);
void gio_clear (void);
Expand Down

0 comments on commit b67de9f

Please sign in to comment.