I2C/MCP23017 version
// I2C/MCP23017 version, 2016-09-17
include <stdio.h>
include <stdlib.h>
include <linux/i2c-dev.h>
include <error.h>
include <sys/types.h>
include <sys/stat.h>
include <fcntl.h>
include <unistd.h>
int addr = 0x26; / 23017 chip I2C addr /
char *i2cbus= "/dev/i2c-0";
define D4 1 // 23017 GPB0
define D5 2 // 23017 GPB1
define D6 4 // 23017 GPB2
define D7 8 // 23017 GPB3
define BK_R 16 // 23017 GPB4
define BK_G 32 // 23017 GPB5
define BK_B 64 // 23017 GPB6
define RS 128 // 23017 GPB7
define EN_HI 0xFF // 23017 GPA7
define EN_LO 0x7F // 23017 GPA7
define IODIRA 0x00 // 23017 bit directions for GPIO-A
define IODIRB 0x01 // 23017 bit directions for GPIO-A
define OLATA 0x14 // 23017 output latch: GPIO-A
define OLATB 0x15 // 23017 output latch: GPIO-B
// commands
define LCD_CLEARDISPLAY 0x01
define LCD_RETURNHOME 0x02
define LCD_ENTRYMODESET 0x04
define LCD_DISPLAYCONTROL 0x08
define LCD_CURSORSHIFT 0x10
define LCD_FUNCTIONSET 0x20
define LCD_SETCGRAMADDR 0x40
define LCD_SETDDRAMADDR 0x80
// flags for display entry mode ( | LCD_ENTRYMODESET = 0x04 );
define LCD_ENTRYRIGHT 0x00
define LCD_ENTRYLEFT 0x02
define LCD_ENTRYSHIFTINCREMENT 0x01
define LCD_ENTRYSHIFTDECREMENT 0x00
// flags for display on/off control ( | DISPLAYCONTROL = 0x08 )
define LCD_DISPLAYON 0x04
define LCD_DISPLAYOFF 0x00
define LCD_CURSORON 0x02
define LCD_CURSOROFF 0x00
define LCD_BLINKON 0x01
define LCD_BLINKOFF 0x00
// flags for display/cursor shift ( | LCD_CURSORSHIFT = 0x10 )
define LCD_DISPLAYMOVE 0x08
define LCD_CURSORMOVE 0x00
define LCD_MOVERIGHT 0x04
define LCD_MOVELEFT 0x00
// flags for function set ( | LCD_FUNCTIONSET = 0x20 )
define LCD_8BITMODE 0x10
define LCD_4BITMODE 0x00
define LCD_2LINE 0x08
define LCD_1LINE 0x00
define LCD_5x10DOTS 0x04
define LCD_5x8DOTS 0x00
int i2c_fd, gpb, bklt=0;
unsigned char displaycontrol=0, displayfunction=0, displaymode=0;
wr_reg(unsigned char reg, unsigned char val) {
unsigned char buf[4];
buf[0]=reg;
buf[1]=val;
if ((write(i2c_fd, buf, 2)) != 2) {
fprintf(stderr,"Error writing 0x%x to reg 0x%x @ addr 0x%x on %sn",val,reg,addr,i2cbus);
exit(1);
}
}
pulse_en () {
wr_reg(OLATA,EN_HI);
usleep(2);
wr_reg(OLATA,EN_LO);
usleep(1);
wr_reg(OLATA,EN_HI);
usleep(2);
}
write1nibble(unsigned char nib) {
wr_reg(OLATB,(bklt | (nib & 0xF)) ); // RS=high-bit => 0
usleep(20);
pulse_en();
usleep(40);
}
writenibbles(unsigned char value, char mode) {
unsigned char nib;
//fprintf(stderr,"sending %X / %d]\n",value, mode);
/* high nibble first */
nib = (value >> 4);
wr_reg(OLATB,(bklt | (nib & 0xF) | (mode ? 0x80 : 0x00)) );
usleep(20);
pulse_en();
usleep(20);
nib = (value & 0x0f);
wr_reg(OLATB,(bklt | (nib & 0xF) | (mode ? 0x80 : 0x00)) );
usleep(20);
pulse_en();
usleep(100);
}
message (char *msg) {
int j;
for (j=0; (msg[j]!=0); j++) {
if ((msg[j] == 'n' || msg[j] == 'r'))
writenibbles(0xC0,0); /* next line */
else writenibbles(msg[j],1);
}
}
main(int argc, char **argv) {
int i,s;
if (argc < 2) {
fprintf(stderr,"usage: %s <bkcolor>\n",argv[0]);
fprintf(stderr,"usage: %s <bkcolor> \"message\"\n",argv[0]);
fprintf(stderr," -OR- %s <bkcolor> <charnum1> <param2>...\n",argv[0]);
exit(1);
}
bklt=((7 ^ atoi(argv[1])) << 4);
if ((i2c_fd = open(i2cbus, O_RDWR)) < 0) {
fprintf(stderr,"Failed to open i2c port %s\n",i2cbus);
exit(1);
}
if (ioctl(i2c_fd, I2C_SLAVE, addr) < 0) {
fprintf(stderr,"Unable to get bus access to talk to addr %x on %s\n",addr,i2cbus);
exit(1);
}
wr_reg (IODIRA,0x7F); // 0xFF & ~EN;
wr_reg (IODIRB,0x00); // all GPIO-B pins to output
if (argc == 2) {
wr_reg(OLATB,bklt);
exit(0);
}
/ init: enter & exit 8-bit mode to reset possible nibble misalignment... /
write1nibble(0x3);
usleep(5000);
write1nibble(0x3);
usleep(5000);
write1nibble(0x3);
usleep(1000);
write1nibble(0x2);
usleep(1000);
writenibbles(LCD_FUNCTIONSET | LCD_4BITMODE | LCD_2LINE | LCD_5x8DOTS,0);
usleep(50);
writenibbles(LCD_DISPLAYCONTROL | LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF,0); // 0x0C
usleep(50);
writenibbles(LCD_ENTRYMODESET | LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT,0); // 0x06
usleep(50);
writenibbles(LCD_CLEARDISPLAY,0);
usleep(3200);
if (argc > 3) {
s=atoi(argv[2]);
for (i=s;i<(s+16);i++) writenibbles(i,1);
writenibbles(0xC0,0);
for (i=(s+16);i<(s+32);i++) writenibbles(i,1);
}
else
message (argv[2]);
close(i2c_fd);
return 0;
}
Linux i2c C-language example INA219 power monitoring chips
include <stdio.h>
include <stdlib.h>
include <linux/i2c-dev.h>
include <fcntl.h>
include <string.h>
include <sys/ioctl.h>
include <sys/types.h>
include <sys/stat.h>
include <unistd.h>
int fd;
int addr1 = 0x44;
int addr2 = 0x45;
char *i2cbus= "/dev/i2c-0";
unsigned char buf[32]; // Buffer for i2c data being read/written
int read_register(int addr, unsigned char reg, unsigned char mask, unsigned char sh)
{
short value;
if ((fd = open(i2cbus, O_RDWR)) < 0) {
fprintf(stderr,"Failed to open i2c port\n");
exit(1);
}
if (ioctl(fd, I2C_SLAVE, addr) < 0) {
fprintf(stderr,"Unable to get bus access to talk to INA219 at %X\n",addr);
exit(1);
}
buf[0] = reg;
if ((write(fd, buf, 1)) != 1) {
fprintf(stderr,"Error sending register address %d to %X\n",reg,addr);
exit(1);
}
if (read(fd, buf, 2) != 2) {
fprintf(stderr,"Unable to read from register %d on %X\n",reg,addr);
exit(1);
}
close(fd);
if (mask != 0 ) buf[1] &= mask;
value = ( (buf[0] << 8) | buf[1]);
if (sh != 0 ) return (int)(value << sh);
else return (int)(value);
}
int read_register_trig(int addr, unsigned char reg, unsigned char mask, unsigned char sh)
{
short value;
if ((fd = open(i2cbus, O_RDWR)) < 0) {
fprintf(stderr,"Failed to open i2c port\n");
exit(1);
}
if (ioctl(fd, I2C_SLAVE, addr) < 0) {
fprintf(stderr,"Unable to get bus access to talk to INA219 at %X\n",addr);
exit(1);
}
// trigger conversion:
buf[0] = 0; // config reg
buf[1] = 0b00001111; // upper 8 bits
buf[2] = 0b11111111; // lower 8 bits
if ((write(fd, buf, 3)) != 3) {
fprintf(stderr,"Error writing to config register\n");
exit(1);
}
usleep(68000);
buf[0] = reg;
if ((write(fd, buf, 1)) != 1) {
fprintf(stderr,"Error sending register address %d to %X\n",reg,addr);
exit(1);
}
if (read(fd, buf, 2) != 2) {
fprintf(stderr,"Unable to read from register %d on %X\n",reg,addr);
exit(1);
}
close(fd);
if (mask != 0 ) buf[1] &= mask;
value = ( (buf[0] << 8) | buf[1]);
if (sh != 0 ) return (int)(value << sh);
else return (int)(value);
}
void init_conf_cal(int addr, unsigned int Cal)
{
if ((fd = open(i2cbus, O_RDWR)) < 0) {
fprintf(stderr,"Failed to open i2c port\n");
exit(1);
}
if (ioctl(fd, I2C_SLAVE, addr) < 0) {
fprintf(stderr,"Unable to get bus access to talk to INA219 at %X\n",addr);
exit(1);
}
// set config register
// bit 15: (0) RESET
// bit 14: (0) n/c
// bit 13: (0) 0=16V range, 1=32V
// bit 12/11: (01) PG1/PG0: Shunt voltage gain
// 00 = 1, +/- 40mV fullscale
// -> 01 = 2, +/- 80mV fullscale 80mV/.01ohm = 8A FS
// 10 = 4, +/-160mV fullscale
// 11 = 8, +/-320mV fullscale
// bits 10,9,8,7: (1111) BADC: bus ADC resolution, samples to average
// bit 6,5,4,3: (1111) SADC: shunt ADC resolution, samples to average
// bits 2,1,0: (111) Op Mode: Shunt & Bus, continuous
// 011 = shunt & bus, triggered
buf[0] = 0; // config reg
buf[1] = 0b00001111; // upper 8 bits
buf[2] = 0b11111111; // lower 8 bits
if ((write(fd, buf, 3)) != 3) {
fprintf(stderr,"Error writing to config register\n");
exit(1);
}
// CALIBRATION REGISTER (REG 5)
// =============================
// VBUS_MAX = 32V (set above)
// VSHUNT_MAX = 0.08V (gain 8)
// RSHUNT = 0.01 ohm
// MaxPossible_I = VSHUNT_MAX / RSHUNT = 8.0A
// MaxExpected_I = 8.0A, same
// MinLSB = MaxExpected_I/32767 = .000244148
// MaxLSB = MaxExpected_I/4096 = .001953125
// CurrrentLSB = MinLSB for now = .00024414807580797753
// Cal = trunc (0.04096 / (Current_LSB * RSHUNT))
// Cal = 16776
// Cal = 16776;
buf[0] = 5; // calibration register
buf[1] = ((Cal & 0xFF00) >> 8);
buf[2] = (Cal & 0xFF);
if ((write(fd, buf, 3)) != 3) {
fprintf(stderr,"Error writing to config register\n");
exit(1);
}
// Calculate Power LSB:
// PowerLSB = 20 * CurrentLSB
// PowerLSB = .0048829615161595506 (4.89 mW per bit)
//
// Compute max current & shunt voltage values before overflow
//
// Max_Current_Overflow = min(CurrentLSB*32767,MaxPossible_I) = 8.0 A
//
// Max_ShuntVoltage = Max_Current_Overflow * RSHUNT = .08V
// (clamp to VSHUNT_MAX if greater)
//
// Compute max power
// MaxPower = Max_Current_Overflow * VBUS_MAX
// MaxPower = 8.0A * 32V = 256.0W
close(fd);
}
main (int argc, char **argv) {
int r,v;
if ( (argc == 3) && (argv[1][0]=='-') && (argv[1][1]=='i') ) {
init_conf_cal(addr1,atoi(argv[2]));
init_conf_cal(addr2,atoi(argv[2]));
fprintf(stderr,"Initialization complete\n");
}
else if ( (argc == 2) && (argv[1][0]=='-') && (argv[1][1]=='d') ) {
r=0;
printf("a%X r%d = %d",addr1,r,read_register_trig(addr1,r,0,0));
putchar('\t');
printf("a%X r%d = %d",addr2,r,read_register_trig(addr2,r,0,0));
putchar('\n');
for(r=1;r<=5;r++) {
printf("a%X r%d = %d",addr1,r,read_register(addr1,r,0,0));
putchar('\t');
printf("a%X r%d = %d",addr2,r,read_register(addr2,r,0,0));
putchar('\n');
}
}
else if ( (argc == 2) && (argv[1][0]=='-') && (argv[1][1]=='v') ) {
printf("V_a: %5.3f\tV_b: %5.3f\n",
(float)read_register_trig(addr2,2,0xF8,0)*1/2000,
(float)read_register_trig(addr1,2,0xF8,0)*1/2000);
}
else if ( (argc == 2) && (argv[1][0]=='-') && (argv[1][1]=='a') ) {
printf("A_a: %5.3f\tA_b: %5.3f\n",
(float)read_register_trig(addr2,1,0,2)*8/32767,
(float)read_register_trig(addr1,1,0,2)*8/32767);
}
else if ( (argc == 2) && (argv[1][0]=='-') && (argv[1][1]=='A') ) {
printf("A_a: %5.3f\tA_b: %5.3f\n",
(float)read_register_trig(addr2,4,0,2)*2/32767,
(float)read_register_trig(addr1,4,0,2)*2/32767);
}
else if ( ( argc == 1 ) || \
( (argc == 2) && (argv[1][0]=='-') && (argv[1][1]=='p') ) ) {
printf("P_a: %5.3f\tP_b: %5.3f\n",
(float)read_register_trig(addr2,3,0,0)*20*8/32767,
(float)read_register_trig(addr1,3,0,0)*20*8/32767);
}
else if ( (argc == 2) && (argv[1][0]=='-') && (argv[1][1]=='w') ) {
float v1,v2,a1,a2;
char cf;
v1=(float)read_register_trig(addr2,2,0xF8,0)*1/2000;
v2=(float)read_register_trig(addr1,2,0xF8,0)*1/2000;
a1=(float)read_register(addr2,4,0,2)*2/32767;
a2=(float)read_register(addr1,4,0,2)*2/32767;
if (a1 > 0 && a2 > 0) cf=(v1>v2 ? 'X' : 'x');
else if (a1 > 0) cf=(v1>v2 ? 'V' : 'v');
else cf=(v1>v2 ? 'B' : 'b');
printf("%4.2f%c %3.1f",
(v1>v2 ? v1 : v2), cf, (a1*v1 + a2*v2));
}
else if ( (argc == 2) && (argv[1][0]=='-') && (argv[1][1]=='W') ) {
float v1,v2,p1,p2,a1,a2;
v1=(float)read_register_trig(addr2,2,0xF8,0)*1/2000;
v2=(float)read_register_trig(addr1,2,0xF8,0)*1/2000;
a1=(float)read_register(addr2,4,0,2)*2/32767;
a2=(float)read_register(addr1,4,0,2)*2/32767;
p1=(float)read_register(addr2,3,0,0)*20*8/32767;
p2=(float)read_register(addr1,3,0,0)*20*8/32767;
printf("%4.2f%c %4.2f %4.2f [%4.2f %4.2f]",
(v1>v2 ? v1 : v2),
(v1>v2 ? 'V' : 'v'),
a1*v1,a2*v2,p1,p2);
}
else if ( (argc == 2) && (argv[1][0]>='0') && (argv[1][0]<='9') ) {
r = atoi(argv[1]);
if (r >= 0 && r <= 5) {
printf("a%X r%d = %d",addr1,r,read_register_trig(addr1,r,0,0));
putchar('\t');
printf("a%X r%d = %d",addr2,r,read_register_trig(addr2,r,0,0));
putchar('\n');
}
else {
fprintf(stderr,"Invalid register.\n");
exit(1);
}
}
else {
fprintf(stderr,"Usage: %s <-i | -d | -[vaApw] | reg_number, 0-5>\n",argv[0]);
exit(1);
}
exit(0);
}
Ubuntu下USB转串口芯片驱动程序安装cp210x,pl2303
Ubuntu下USB转串口芯片驱动程序安装,支持cp210x,pl2303等
Reference: Fixing the cp210x open - Unable to enable UART Error
When you plugin your USB-UART converter, and run "> ls /dev/tty*", if you don't see the /dev/ttyUSB0 (or similar), your Linux does not detect your USB-UART device.
We need to install the driver for your device.
Here we use Ubuntu12.04, and Updated the source to 3.2.0 version. If there is difference about version Number from your OS platform, please try to modify it into yours.
1.Download the Linux Source Code
Open a terminal and execute the following commands. Note that your version of Linux may differ slightly -- adjust accordingly.
$ cd ~
$ sudo apt-get install build-essential linux-source
$ cp /usr/src/linux-source-3.2.0.tar.bz2 .
$ bunzip2 linux-source-3.2.0.tar.bz2
$ tar xf linux-source-3.2.0.tar
$ cd ~/linux-source-3.2.0
https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers
2.Chang Pid Vid Recompile and Reinstall the cp210x Driver
(Change Sourcode Pid and Vid to 04C5 142E to fit this mmdvm chip ic driver)
From within a terminal, execute:
$ cd ~/linux-source-3.2.0
$ make oldconfig
$ make prepare
$ make scripts
$ cp /usr/src/linux-headers-3.2.0-34-generic-pae/Module.symvers .
Here, I have the "3.2.0-29" version also, I launched the command above, but not the below:
"cp /usr/src/linux-headers-3.2.0-29-generic-pae/Module.symvers ."
Recompile and Reinstall the cp210x Driver
Here, We can actually install many kinds of USB-UART converter drivers. We take cp210x as the example.
From within a terminal, execute:
$ make M=drivers/usb/serial
$ sudo mv /lib/modules/$(uname -r)/kernel/drivers/usb/serial/cp210x.ko /lib/modules/$(uname -r)/kernel/drivers/usb/serial/cp210x.ko.old
$ sudo cp drivers/usb/serial/cp210x.ko /lib/modules/$(uname -r)/kernel/drivers/usb/serial/
$ sudo modprobe -r cp210x
$ sudo modprobe cp210x
Reboot Linux system.
Run Terminal:
$ ls /dev/tty*
The we can see the device is detected by Linux Host OS:
openwrt oled test file
put oled folder to openwrt package then make it
package_oled.zip