holding SCL low after setting my saturation value is rather crude, but
authorJohn Tsiombikas <nuclear@member.fsf.org>
Wed, 3 Mar 2021 02:13:12 +0000 (04:13 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Wed, 3 Mar 2021 02:13:12 +0000 (04:13 +0200)
works. I'll keep looking for a better solution.

main.c

diff --git a/main.c b/main.c
index 8e3a5c9..aa593da 100644 (file)
--- a/main.c
+++ b/main.c
@@ -22,7 +22,8 @@ enum {
 #define I2C_STOP()     (TWCR = TWINT_BIT | TWSTO_BIT | TWEN_BIT | TWIE_BIT)
 #define I2C_WRITE()    (TWCR = TWINT_BIT | TWEN_BIT | TWIE_BIT)
 
-unsigned char i2c_addr, i2c_subaddr, i2c_mode;
+unsigned char i2c_addr, i2c_subaddr;
+volatile unsigned char i2c_mode;
 int i2c_seq, i2c_ndata;
 unsigned char *i2c_data;
 int i2c_retry_delay;
@@ -44,6 +45,8 @@ volatile int evq_wr, evq_rd;
 static char input[64];
 static unsigned char inp_cidx;
 
+static unsigned char data[8];
+
 static void proc_cmd(char *input);
 void i2c_write(unsigned char addr, unsigned char subaddr, int ndata, unsigned char *data);
 
@@ -51,7 +54,7 @@ int main(void)
 {
        /* tri-state everything and disable pullups */
        DDRB = 1;       /* B0: activity LED */
-       DDRC = 0;
+       DDRC = 0x20; /* SCL output so we can hold the clock low when disabling i2c */
        DDRD = 0;
        PORTB = 0;
        PORTC = 0;
@@ -59,10 +62,9 @@ int main(void)
 
        TWBR = 10;              /* 10 with 1x prescaler should make it about 100khz */
        TWSR = 0;               /* prescaler 1x */
-       TWAR = 0xff;
+       TWAR = 0x8a;            /* let's monitor for commands going to the jungle */
+       TWAMR = 0;
        TWCR = (1 << TWEN) | (1 << TWIE); /* enable i2c, don't ack, enable intr */
-       TWAR = 0xff;
-       TWAMR = 0;//0xff;       /* match all addresses to monitor the bus */
 
        i2c_mode = I2C_IDLE;
 
@@ -72,7 +74,7 @@ int main(void)
        printf("Starting i2c hack\n");
 
        for(;;) {
-               uint16_t val = 0xffff;
+               //uint16_t val = 0xffff;
 
                if(have_input()) {
                        int c = getchar();
@@ -89,6 +91,7 @@ int main(void)
                }
 
                /* read from queue and send over the serial port */
+               /*
                cli();
                if(evq_wr != evq_rd) {
                        val = evq[evq_rd];
@@ -99,14 +102,18 @@ int main(void)
                if(val != 0xffff) {
                        printf("s(%u): %x\n", (unsigned int)(val >> 8), (unsigned int)(val & 0xff));
                }
+               */
+               /*
+               _delay_us(100);
+               data[0] = 0x3f;
+               i2c_write(0x8a, 0x1c, 1, data);
+               */
        }
        return 0;
 }
 
 static void proc_cmd(char *input)
 {
-       unsigned char data[8];
-
        if(strcmp(input, "rgb") == 0) {
                printf("OK sending RGB switch command\n");
 
@@ -137,10 +144,15 @@ static void proc_cmd(char *input)
                i2c_write(0x8a, 0x10, 1, data);
                printf("OK unzoom\n");
 
-       } else if(strcmp(input, "sat") == 0) {
-               data[0] = 0x3f;
-               i2c_write(0x8a, 0x1c, 1, data);
+       } else if(memcmp(input, "sat", 3) == 0) {
                printf("OK saturate\n");
+               data[0] = atoi(input + 3);
+               if(data[0] <= 0 || data[0] > 0x3f) {
+                       data[0] = 0x1f;
+               }
+               i2c_write(0x8a, 0x1c, 1, data);
+               while(i2c_mode);
+               TWCR = 0;
 
        } else if(strcmp(input, "abort") == 0) {
                if(i2c_mode != I2C_IDLE) {
@@ -158,7 +170,6 @@ static void proc_cmd(char *input)
 
 void i2c_write(unsigned char addr, unsigned char subaddr, int ndata, unsigned char *data)
 {
-       printf("i2c: write %x (sub: %x)\n", addr, subaddr);
        i2c_addr = addr & 0xfe;
        i2c_subaddr = subaddr;
        i2c_mode = I2C_MASTER_SEND;
@@ -300,9 +311,9 @@ ISR(TWI_vect)
                default:
                        break;
                }
-               /* append data to input queue */
-               /*
-               TWCR |= 1 << TWINT;
+
+               /* append data to the event queue */
+               TWCR = TWINT_BIT | TWEN_BIT | TWIE_BIT;
 
                evq[evq_wr] = ev;
                evq_wr = (evq_wr + 1) & (EVQ_SIZE - 1);
@@ -311,6 +322,5 @@ ISR(TWI_vect)
                }
 
                PORTB = 1;
-               */
        }
 }