2023年11月8日 星期三

ASUS Tinker Board 2S - Debian I2C TCA9539

 

TI TCA9539

16-bit 1.65- to 5.5-V I2C/SMBus I/O expander with interrupt, reset & config registers


IO-EXPANDER-EVM: I2C and SMBus IO Expander Evaluation Module






1. 修改  /boot/config.txt 內容
intf:i2c6=on    /* 原始前面有個 # 要去除, 把 off 改為on */

2. 連接 I2C
  SCL: IO-EXPANDER J8 SCL
  SDA: IO-EXPANDER J8 SDA
  GND: IO-EXPANDER J7 GND
  VCC: IO-EXPANDER J9 VCC

3.Device Address
PS: IO Expander EVM User's Guide (Rev. A) 這一片是共用PCB.
TCA6424A  0100010 0x22 
TCA9539     1110111 0x77 



  


GPIO設定, 主要是在Registers 6 和7


 但這片 IO Expander EVM 另外拉了幾條線用於顯示LED燈
 可以直接改用J13 來測試GPIO


第一個是 Device Address 
    i2cmsg.addr  = nDevAddr;
第二個是  Registers 6或7
第三個就是 GPIO Pin 0到N 的 GPIO ON/OFF


4. Linux IOCTL 範例程式


#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <err.h>
#include <errno.h>
#include <string.h>
#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define DEFAULT_I2C_BUS      "/dev/i2c-6"
// 0100010 0x22 TCA6424A
// 1110111 0x77 TCA9539
#define DEFAULT_TCA9539_ADDR 0x77

int TCA9539_write( int nFile, unsigned int nDevAddr, unsigned int nRegConfig,
                  unsigned char *pBuf, unsigned char nLen)
{
  struct i2c_rdwr_ioctl_data msg_rdwr;
  struct i2c_msg i2cmsg;
  int nRecLen;
  unsigned char sI2cBuf[0xFF];
  unsigned char *pI2cBuf = &sI2cBuf[0];

  msg_rdwr.msgs = &i2cmsg;
  msg_rdwr.nmsgs = 1;

  pI2cBuf[0] = (unsigned char)nRegConfig;
  pI2cBuf[1] = pBuf[0];
  i2cmsg.addr  = nDevAddr;
  i2cmsg.flags = 0;  // Write
  i2cmsg.len   = 2;
  i2cmsg.buf   = pI2cBuf;
  if( ( nRecLen = ioctl( nFile, I2C_RDWR, &msg_rdwr)) < 0)
  {
   perror("W5A-ioctl()");
   fprintf( stderr,"W5B-ioctl %d\n%s\n", nRecLen, strerror(errno));
   return -1;
  }
  else
   return nRecLen;
}

int TCA9539_read( int nFile, unsigned int nDevAddr, unsigned int nRegConfig,
                  unsigned char *pBuf, unsigned char nLen)
{
  struct i2c_rdwr_ioctl_data msg_rdwr;
  struct i2c_msg i2cmsg[2];
  unsigned char sAdsBuf[3];
  unsigned char *pAdsBuf = &sAdsBuf[0];
  int nRecLen;

  msg_rdwr.msgs = i2cmsg;
  msg_rdwr.nmsgs = 2;

  pAdsBuf[0] = (unsigned char)nRegConfig;
  i2cmsg[0].addr  = nDevAddr;
  i2cmsg[0].flags = 0;  // Write
  i2cmsg[0].len   = 1;
  i2cmsg[0].buf   = pAdsBuf; 
    
  i2cmsg[1].addr  = nDevAddr;
  i2cmsg[1].flags = I2C_M_RD;  // read data, from slave to master
  i2cmsg[1].len   = nLen;
  i2cmsg[1].buf   = pBuf;

  if( ( nRecLen = ioctl( nFile, I2C_RDWR, &msg_rdwr))<0)
  {
   perror("R5-TCA9539_read ioctl failed");
   fprintf(stderr,"R6-TCA9539_read ioctl returned %d\n", nRecLen);
   return -1;
  }
  else
  {
   return nRecLen;
  } 
}

int main(void)
{
 int nDevAddr = DEFAULT_TCA9539_ADDR;
 int nFile, nWriteLen, nReadLen, nRecLen; 
 int nRc, nRegConfig;
 const char *pDevice = DEFAULT_I2C_BUS; //"/dev/i2c-6";
 unsigned char sBuf[0x10], sStrBuf[0x10];
 unsigned char *pBuf= &sBuf[0];
 unsigned long nFuncs;
 

 printf("Hello! This is a test prgoram.\n");
 nFile = open( pDevice, O_RDWR);
 if( nFile < 0)
  err( errno, "O1-Tried to open '%s'", pDevice);
 else
  printf( "\nO2-Open dev i2c-6 success.\n");

 if( ioctl( nFile, I2C_FUNCS, &nFuncs) < 0)
 {
  perror("W5A-ioctl()");
  fprintf(stderr, "Error: Could not get the adapter functionality matrix: %s\n",
  strerror(errno));
  close( nFile);
  exit(0);
 }
 ioctl( nFile, I2C_TIMEOUT,2); // TIMEOUT
 ioctl( nFile, I2C_RETRIES,1); // retry count
    
 nRc = ioctl( nFile, I2C_SLAVE, nDevAddr);
 if( nRc < 0)
 {
  err(errno, "O3-Tried to set device address '0x%02x'", nDevAddr);
  exit(0);
 }
 else
 {
  printf("O4-Dev i2c-6 Set Address 0x50 success.\n");
 }

 
 // https://www.ti.com/product/zh-tw/TCA9539 // Pull High
 // Table 7. Registers 6 And 7 (Configuration Registers)
 nDevAddr = DEFAULT_TCA9539_ADDR;
 nRegConfig = 0x06; // Registers 6 Configuration
 pBuf[0] = 0x00;  // Set GPIO Pin-0 to Pin-7 all Pull Low
 nWriteLen = 1;
 nRecLen = TCA9539_write( nFile, nDevAddr, nRegConfig, pBuf, nWriteLen);
 if( nRecLen < 0)
 {
  printf( "W3A-TCA9539_write failed.\n");
  exit(0);
 }
 else
 {
  fprintf( stderr, "W6-Set gpio pin0-7: 0x%02x\n", pBuf[0]);
 } 
 nRegConfig = 0x07;  // Registers 7 Configuration
 pBuf[0] = 0x00;  // Set GPIO Pin-10 to Pin-17 all Pull Low
 nWriteLen = 1;
 nRecLen = TCA9539_write( nFile, nDevAddr, nRegConfig, pBuf, nWriteLen);
 if( nRecLen < 0)
 {
  printf( "W3A-TCA9539_write failed.\n");
  exit(0);
 }
 else
 {
  fprintf( stderr, "W7-Set gpio pin10-17: 0x%02x\n", pBuf[0]);
 } 

 // Read Process
 nDevAddr = DEFAULT_TCA9539_ADDR;
 nRegConfig = 0x06; // Registers 6 Configuration
 pBuf[0] = 0xFF;    // Read GPIO Pin-0 to Pin-7 
 nReadLen = 1;
 nRecLen = TCA9539_read( nFile, nDevAddr, nRegConfig, pBuf, nReadLen);
 if( nRecLen < 0)
 {
  printf("R1-TCA9539_read failed.\n");
  exit(1);
 }
 else
 {
  fprintf( stderr, "W6-Get gpio pin0-7: 0x%02x\n", pBuf[0]);
 }   
 nRegConfig = 0x07; // Registers 7 Configuration
 pBuf[0] = 0xFF;    // Read GPIO Pin-10 to Pin-17 
 nReadLen = 1;
 nRecLen = TCA9539_read( nFile, nDevAddr, nRegConfig, pBuf, nReadLen);
 if( nRecLen < 0)
 {
  printf("R1-TCA9539_read failed.\n");
  exit(1);
 }
 else
 {
  fprintf( stderr, "W6-Get gpio pin10-17: 0x%02x\n", pBuf[0]);
 }   
 close( nFile);
 return 0;
}




5.

















沒有留言:

張貼留言