Skip to content

Commit

Permalink
chg: Add support to Read operations and interrupts in MCP23S17 spare …
Browse files Browse the repository at this point in the history
…part
  • Loading branch information
lcgamboa committed Jun 8, 2024
1 parent 1524251 commit 05f0c10
Show file tree
Hide file tree
Showing 13 changed files with 355 additions and 114 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG_auto.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

### New

* New part \"Logic Block\" with logic functions: Not, Buffer, And, Nand, Or, Nor, Xor and Xnor. [lcgamboa]

* Increase oscilloscope time scale up to 1s/div. [lcgamboa]

* Support to PIC18F67J60 added to Breadboard board. [lcgamboa]

* Add initial support to ESP32 RMT TX. [lcgamboa]

* Add support to use analog values in gpboard (gpsim backend) [lcgamboa]
Expand All @@ -12,10 +18,20 @@

### Changes

* Gpboard updated to use gpsim-0.32.1. [lcgamboa]

* Gpsim interface optimization to improve simulation performance. [lcgamboa]

* Changlog updated. [lcgamboa]

### Fix

* Fix Oscilloscope to use all SpareParts pins. [lcgamboa]

* Fix gpboard configuration bits dump for PIC18F. [lcgamboa]

* Fix gpboard simulation clock speed. [lcgamboa]

* Fix spare parts window position on start. [lcgamboa]

* Fix support to multi byte char in command line file name. [lcgamboa]
Expand Down
19 changes: 10 additions & 9 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
### FIXMEs
| Filename | line # | FIXME |
|:------|:------:|:------|
| [src/picsimlab1.cc](src/picsimlab1.cc#L1061) | 1061 | remote control disabled |
| [src/boards/board_uCboard.cc](src/boards/board_uCboard.cc#L298) | 298 | NSTEP must be multiplied for 4 |
| [src/picsimlab1.cc](src/picsimlab1.cc#L1063) | 1063 | remote control disabled |
| [src/boards/board_uCboard.cc](src/boards/board_uCboard.cc#L299) | 299 | NSTEP must be multiplied for 4 |
| [src/boards/bsim_simavr.cc](src/boards/bsim_simavr.cc#L1595) | 1595 | avr CONFIG size |
| [src/devices/io_MCP23X17.cc](src/devices/io_MCP23X17.cc#L134) | 134 | only for BANK=0; |
| [src/parts/input_MPU6050.cc](src/parts/input_MPU6050.cc#L26) | 26 | remove lxrad |
| [src/parts/input_encoder.cc](src/parts/input_encoder.cc#L171) | 171 | on slow speed output is not 90 degrees |
| [src/parts/output_dcmotor.cc](src/parts/output_dcmotor.cc#L224) | 224 | on slow speed output is not 90 degrees |
| [src/parts/input_encoder.cc](src/parts/input_encoder.cc#L173) | 173 | on slow speed output is not 90 degrees |
| [src/parts/output_dcmotor.cc](src/parts/output_dcmotor.cc#L228) | 228 | on slow speed output is not 90 degrees |

### TODOs
| Filename | line # | TODO |
|:------|:------:|:------|
| [src/picsimlab4.cc](src/picsimlab4.cc#L415) | 415 | select the better mode for channel trigguer |
| [src/picsimlab4.cc](src/picsimlab4.cc#L434) | 434 | select the better mode for channel trigguer |
| [src/boards/board_Arduino_Mega.cc](src/boards/board_Arduino_Mega.cc#L68) | 68 | cboard_Arduino_Mega: add suport to analog inputs A6 and A7 |
| [src/boards/board_Arduino_Nano.cc](src/boards/board_Arduino_Nano.cc#L69) | 69 | cboard_Arduino_Nano: add suport to analog inputs A6 and A7 |
| [src/boards/board_McLab2.cc](src/boards/board_McLab2.cc#L100) | 100 | jumper support |
Expand All @@ -34,7 +34,8 @@
| [src/devices/ldd_max72xx.cc](src/devices/ldd_max72xx.cc#L88) | 88 | display test |
| [src/devices/rtc_ds1307.cc](src/devices/rtc_ds1307.cc#L300) | 300 | int output |
| [src/devices/rtc_pfc8563.cc](src/devices/rtc_pfc8563.cc#L282) | 282 | int output and countdown timer |
| [src/parts/input_ds1621.cc](src/parts/input_ds1621.cc#L206) | 206 | set addr |
| [src/parts/input_ds1621.cc](src/parts/input_ds1621.cc#L218) | 218 | implement Tout output |
| [src/parts/other_IO_MCP23S17.cc](src/parts/other_IO_MCP23S17.cc#L387) | 387 | only write support implemented |
| [src/parts/output_dcmotor.cc](src/parts/output_dcmotor.cc#L171) | 171 | Add transfer funcion of dc motor |
| [src/parts/input_ds1621.cc](src/parts/input_ds1621.cc#L211) | 211 | set addr |
| [src/parts/input_ds1621.cc](src/parts/input_ds1621.cc#L223) | 223 | implement Tout output |
| [src/parts/other_IO_MCP23S17.cc](src/parts/other_IO_MCP23S17.cc#L395) | 395 | only write support implemented |
| [src/parts/other_jumpers_ipc.cc](src/parts/other_jumpers_ipc.cc#L89) | 89 | get random |
| [src/parts/output_dcmotor.cc](src/parts/output_dcmotor.cc#L175) | 175 | Add transfer funcion of dc motor |
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ PACKAGE=picsimlab
MAINVER=0
MINORVER=9
VERSION=0.9.2
DATE=240414
DATE=240608
VERSION_STABLE=0.9.1
3 changes: 3 additions & 0 deletions src/Makefile.SDL2
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ override CXXFLAGS += -DEXT_BROWSER -D_VERSION_=\"${VERSION}\" -Wall -ggdb -O2 \
-D_LIB_=\"../lib/picsimlab/\"

override CXXFLAGS+=-fsanitize=address
#override CXXFLAGS+=-fsanitize=thread
#override CXXFLAGS+=-fsanitize=undefined
#override CXXFLAGS+=-fsanitize=leak
override CXXFLAGS+= -D_CONSOLE_LOG_
#override CXXFLAGS+= -D_NOTHREAD

Expand Down
2 changes: 0 additions & 2 deletions src/devices/bitbang_spi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,11 @@ unsigned char bitbang_spi_get_status(bitbang_spi_t* spi) {

void bitbang_spi_send16(bitbang_spi_t* spi, const unsigned int data) {
spi->outsr = data;
// spi->ret = ((spi->outsr & spi->outbitmask) > 0);
dprintf("bitbang_spi data to send 0x%02x \n", data);
}

void bitbang_spi_send8(bitbang_spi_t* spi, const unsigned char data) {
spi->outsr = (spi->outsr & 0xFF00) | data;
// spi->ret = ((spi->outsr & spi->outbitmask) > 0);
dprintf("bitbang_spi data to send 0x%02x \n", data);
}

Expand Down
180 changes: 125 additions & 55 deletions src/devices/io_MCP23X17.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,6 @@ static unsigned char decode_addr(io_MCP23X17_t* mcp) {
case 0x0A:
return 0x14;
break;
// case 0x0B: return 0x10; break;
// case 0x0C: return 0x10; break;
// case 0x0D: return 0x10; break;
// case 0x0E: return 0x10; break;
// case 0x0F: return 0x10; break;
case 0x10:
return 0x01;
break;
Expand Down Expand Up @@ -126,7 +121,10 @@ static unsigned char decode_addr(io_MCP23X17_t* mcp) {

static void write_reg(io_MCP23X17_t* mcp, unsigned char val) {
unsigned char addr_ = decode_addr(mcp);
mcp->regs[addr_] = val;

if ((addr_ != INTFA) && (addr_ != INTFB) && (addr_ != INTCAPA) && ((addr_ != INTCAPB))) {
mcp->regs[addr_] = val;
}

if ((mcp->regs[IOCON] & SEQOP) == 0) {
mcp->reg_addr++;
Expand All @@ -139,7 +137,6 @@ static void write_reg(io_MCP23X17_t* mcp, unsigned char val) {
switch (addr_) {
case IOCON:
mcp->regs[IOCON_] = val;
break;
case IOCON_:
mcp->regs[IOCON] = val;
break;
Expand All @@ -154,6 +151,26 @@ static void write_reg(io_MCP23X17_t* mcp, unsigned char val) {

static unsigned char read_reg(io_MCP23X17_t* mcp) {
unsigned char addr_ = decode_addr(mcp);

switch (addr_) {
case GPIOA:
case INTCAPA:
mcp->regs[INTFA] = 0;
mcp->inta_value = !(mcp->regs[IOCON] & INTPOL); // disabled
if (mcp->regs[IOCON] & MIRROR) {
mcp->intb_value = !(mcp->regs[IOCON] & INTPOL); // disabled
}
break;
case GPIOB:
case INTCAPB:
mcp->regs[INTFB] = 0;
mcp->intb_value = !(mcp->regs[IOCON] & INTPOL); // disabled
if (mcp->regs[IOCON] & MIRROR) {
mcp->inta_value = !(mcp->regs[IOCON] & INTPOL); // disabled
}
break;
}

return mcp->regs[addr_];
}

Expand All @@ -162,10 +179,17 @@ void io_MCP23X17_rst(io_MCP23X17_t* mcp) {
mcp->regs[i] = 0;
mcp->reg_addr = 0;

mcp->regs[IODIRA] = 0xFF;
mcp->regs[IODIRB] = 0xFF;

bitbang_i2c_rst(&mcp->bb_i2c);
bitbang_spi_rst(&mcp->bb_spi);

mcp->inta_value = 1;
mcp->intb_value = 1;

mcp->op = 0;
mcp->so_active = 0;
dprintf("mcp rst\n");
}

Expand All @@ -178,41 +202,102 @@ void io_MCP23X17_init(io_MCP23X17_t* mcp) {
}

void io_MCP23X17_set_addr(io_MCP23X17_t* mcp, unsigned char addr) {
mcp->addr = addr << 1;
mcp->addr = 0x40 | ((0x07 & addr) << 1);
bitbang_i2c_set_addr(&mcp->bb_i2c, addr);
}

void io_MCP23X17_set_inputs(io_MCP23X17_t* mcp, unsigned char porta, unsigned char portb) {
if ((mcp->regs[GPIOA] != porta) || (mcp->regs[GPIOB] != portb)) {
if (mcp->regs[GPINTENA]) {
unsigned char intf = 0;
intf |= (porta ^ mcp->regs[GPIOA]) & ~mcp->regs[INTCONA];
intf |= (porta ^ mcp->regs[DEFVALA]) & mcp->regs[INTCONA];
intf &= mcp->regs[GPINTENA] & mcp->regs[IODIRA];

if (!mcp->regs[INTFA] && intf) {
mcp->regs[INTCAPA] = porta;
}

mcp->regs[INTFA] = intf;
}

if (mcp->regs[GPINTENB]) {
unsigned char intf = 0;
intf |= (portb ^ mcp->regs[GPIOB]) & ~mcp->regs[INTCONB];
intf |= (portb ^ mcp->regs[DEFVALB]) & mcp->regs[INTCONB];
intf &= mcp->regs[GPINTENB] & mcp->regs[IODIRB];

if (!mcp->regs[INTFB] && intf) {
mcp->regs[INTCAPB] = portb;
}

mcp->regs[INTFB] = intf;
}

if (mcp->regs[IOCON] & MIRROR) {
mcp->inta_value = !(mcp->regs[IOCON] & INTPOL); // disabled
mcp->intb_value = !(mcp->regs[IOCON] & INTPOL); // disabled
if ((mcp->regs[GPINTENA] && mcp->regs[INTFA]) || (mcp->regs[GPINTENB] && mcp->regs[INTFB])) {
mcp->inta_value = !!(mcp->regs[IOCON] & INTPOL); // enabled
mcp->intb_value = !!(mcp->regs[IOCON] & INTPOL); // enabled
}
} else {
mcp->inta_value = !(mcp->regs[IOCON] & INTPOL); // disabled
if (mcp->regs[GPINTENA] && mcp->regs[INTFA]) {
mcp->inta_value = !!(mcp->regs[IOCON] & INTPOL); // enabled
}

mcp->intb_value = !(mcp->regs[IOCON] & INTPOL); // disabled
if (mcp->regs[GPINTENB] && mcp->regs[INTFB]) {
mcp->intb_value = !!(mcp->regs[IOCON] & INTPOL); // enabled
}
}

mcp->regs[GPIOA] = porta;
mcp->regs[GPIOB] = portb;
}
}

unsigned char io_MCP23X17_SPI_io(io_MCP23X17_t* mcp, unsigned char si, unsigned char sck, unsigned char rst,
unsigned char cs) {
if (!rst) {
io_MCP23X17_rst(mcp);
return 0;
}

unsigned char ret = bitbang_spi_io(&mcp->bb_spi, sck, si, cs);
bitbang_spi_io(&mcp->bb_spi, sck, si, cs);

switch (bitbang_spi_get_status(&mcp->bb_spi)) {
case SPI_DATA:

switch (mcp->bb_spi.byte) {
case 1:
if ((mcp->bb_spi.data & 0xFE) == mcp->addr) {
mcp->op = mcp->bb_spi.data & 0x01;
dprintf("mcp addr 0x%02X OK\n", mcp->addr);
if (mcp->regs[IOCON] & HAEN) {
if ((mcp->bb_spi.data & 0xFE) == mcp->addr) {
mcp->op = mcp->bb_spi.data & 0x01;
dprintf("mcp op 0x%02X OK\n", mcp->addr);
} else {
mcp->bb_spi.bit = 0x80;
dprintf("mcp op 0x%02X ERROR\n", mcp->addr);
}
} else {
mcp->bb_spi.bit = 0x80;

dprintf("mcp addr 0x%02X ERROR\n", mcp->addr);
mcp->op = mcp->bb_spi.data & 0x01;
}
break;
case 2:
mcp->reg_addr = mcp->bb_spi.data;
dprintf("mcp reg addr 0x%02X\n", mcp->bb_spi.data);

if (mcp->op) {
mcp->so_active = 1;
bitbang_spi_send8(&mcp->bb_spi, read_reg(mcp));
dprintf("mcp data read [0x%02X] 0x%02X\n", mcp->reg_addr, mcp->bb_spi.outsr & 0xFF);
}
break;
default:
if (mcp->op) {
dprintf("mcp data read [0x%02X] 0x%02X\n", mcp->reg_addr, mcp->bb_spi.data);
bitbang_spi_send8(&mcp->bb_spi, read_reg(mcp));
dprintf("mcp data read [0x%02X] 0x%02X\n", mcp->reg_addr, mcp->bb_spi.outsr & 0xFF);
} else {
dprintf("mcp data write [0x%02X] 0x%02X\n", mcp->reg_addr, mcp->bb_spi.data);
write_reg(mcp, mcp->bb_spi.data);
Expand All @@ -222,46 +307,31 @@ unsigned char io_MCP23X17_SPI_io(io_MCP23X17_t* mcp, unsigned char si, unsigned
break;
}

return ret;
return mcp->bb_spi.ret;
}

unsigned char io_MCP23X17_I2C_io(io_MCP23X17_t* mcp, unsigned char scl, unsigned char sda) {
/*
NOT tested !!!!
unsigned char ret = bitbang_i2c_io (&mcp->bb_i2c, scl, sda);
switch (bitbang_i2c_get_status (&mcp->C))
{
case I2C_DATAW:
dprintf ("write mcp =%02X\n", mcp->bb_i2c.datar);
switch (mcp->bb_i2c.byte)
{
case 1:
mcp->reg_addr = mcp->bb_i2c.datar;
dprintf ("mcp reg addr 0x%02X\n", mcp->bb_i2c.datar);
break;
default:
if (mcp->op)
{
dprintf ("mcp data read [0x%02X] 0x%02X\n", mcp->reg_addr, mcp->bb_spi.data);
bitbang_spi_send (&mcp->bb_spi, read_reg (mcp));
}
else
{
dprintf ("mcp data write [0x%02X] 0x%02X\n", mcp->reg_addr, mcp->bb_spi.data);
write_reg (mcp, mcp->bb_spi.data);
}
break;
}
break;
case I2C_DATAR:
bitbang_i2c_send (&mcp->bb_i2c, read_reg (mcp));
dprintf ("mcp read =%02X\n", mcp->bb_i2c.datas);
break;
}
return ret;
*/
return 0;
unsigned char ret = bitbang_i2c_io(&mcp->bb_i2c, scl, sda);

switch (bitbang_i2c_get_status(&mcp->bb_i2c)) {
case I2C_DATAW:
dprintf("write mcp =%02X\n", mcp->bb_i2c.datar);
switch (mcp->bb_i2c.byte) {
case 1:
mcp->reg_addr = mcp->bb_i2c.datar;
dprintf("mcp reg addr 0x%02X\n", mcp->bb_i2c.datar);
break;
default:
dprintf("mcp data write [0x%02X] 0x%02X\n", mcp->reg_addr, mcp->bb_spi.data);
write_reg(mcp, mcp->bb_i2c.datar);
break;
}
break;
case I2C_DATAR:
bitbang_i2c_send(&mcp->bb_i2c, read_reg(mcp));
dprintf("mcp read =%02X\n", mcp->bb_i2c.datas);
break;
}

return ret;
}
4 changes: 4 additions & 0 deletions src/devices/io_MCP23X17.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,17 @@ typedef struct {
unsigned char reg_addr;
unsigned char op;
unsigned char addr;
unsigned char so_active; // serial out pin
unsigned char inta_value;
unsigned char intb_value;
bitbang_spi_t bb_spi;
bitbang_i2c_t bb_i2c;
} io_MCP23X17_t;

void io_MCP23X17_rst(io_MCP23X17_t* mcp);
void io_MCP23X17_init(io_MCP23X17_t* mcp);
void io_MCP23X17_set_addr(io_MCP23X17_t* mcp, unsigned char addr);
void io_MCP23X17_set_inputs(io_MCP23X17_t* mcp, unsigned char porta, unsigned char portb);

unsigned char io_MCP23X17_SPI_io(io_MCP23X17_t* mcp, unsigned char si, unsigned char sck, unsigned char rst,
unsigned char cs);
Expand Down
Loading

0 comments on commit 05f0c10

Please sign in to comment.