]> cloudbase.mooo.com Git - z180-stamp.git/blobdiff - avr/i2c.c
Expression eval: Repair unary + and -
[z180-stamp.git] / avr / i2c.c
index 3ab222aebc50dcbf0d60822738bb80d34c11668f..ae2f8da46d3410df36cf2f35f1dc7cdfa4ac79eb 100644 (file)
--- a/avr/i2c.c
+++ b/avr/i2c.c
@@ -1,11 +1,15 @@
+/*
+ * (C) Copyright 2014 Leo C. <erbl259-lmu@yahoo.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
 
-/* 
- * I2C (TWI) master interface. 
+/*
+ * I2C (TWI) master interface.
  */
 
 #include "common.h"
 #include <avr/interrupt.h>
-#include <util/delay.h>
 #include <string.h>
 
 #include "config.h"
 #include "debug.h"
 #include "i2c.h"
 
-#ifdef DEBUG
-//# define DEBUG_I2C
-#endif
+#define  DEBUG_I2C 0
+
+#define debug_i2c(fmt, args...)                        \
+       debug_cond(DEBUG_I2C, fmt, ##args)
+
 
 /* General TWI Master status codes */
 #define TWI_START                  0x08  /* START has been transmitted */
  * TWSTO: TWI STOP Condition Bit
  * TWEN:  TWI Enable Bit
  * TWIE:  TWI Interrupt Enable
- * 
+ *
  *     (1<<TWEN)|(1<<TWIE)|(1<<TWINT)
  *     (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|           (1<<TWEA)
  *     (1<<TWEN)|(1<<TWIE)|(1<<TWINT)
- * 
+ *
  * default:
  *     (1<<TWEN)|          (1<<TWINT)|           (1<<TWSTO)
- * 
+ *
  * Init:
  *     (1<<TWEN)
- * 
+ *
  * start read/write:
  *     (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA)
  *     (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA)
  *     (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA)
  *     (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA)
- * 
+ *
  * wait ready:
  *      (1<<TWIE)|(1<<TWSTO)
  *
  *
  *
- *i2c_result   
+ *i2c_result
  *
  *     0b10000000      Busy (Transmission in progress)
  *     0b01000000      Timeout
- *     0b00001000      Start transmitted 
+ *     0b00001000      Start transmitted
  *     0b00000100      Slave acknowledged address
  *     0b00000010      Data byte(s) transmitted/received
  *     0b00000001      Transmission completed
@@ -84,8 +90,8 @@
 #define TWI_C_DISABLE          0x00
 #define TWI_C_ENABLE           (1<<TWEN)
 
+
+
  typedef struct i2c_msg_s {
        uint8_t stat;
  #define XMIT_DONE     (1<<0)
@@ -112,7 +118,7 @@ ISR(TWI_vect)
        tmp_stat = xmit.stat;
 
        uint8_t twsr = TWSR;
-               
+
        switch (twsr & 0xf8) {
 
        case TWI_START:
@@ -132,21 +138,11 @@ ISR(TWI_vect)
                break;
 
        case TWI_MTX_ADR_ACK:
-               tmp_stat |= ADDR_ACK;
-               
-               if (tmp_idx < xmit.len) {               /* all bytes transmited? */
-                       TWDR = xmit.buf[tmp_idx];
-                       ++tmp_idx;
-                       next_twcr = (1<<TWEN)|(1<<TWIE)|(1<<TWINT);
-               } else {
-                       tmp_stat |= XMIT_DONE;
-                       tmp_stat &= ~BUSY;
-                       next_twcr = (1<<TWEN)|(0<<TWIE)|(1<<TWINT)|(1<<TWSTO);
-               }
-               break;
-
        case TWI_MTX_DATA_ACK:
-               tmp_stat |= DATA_ACK;
+               if ((twsr&0xf8) == TWI_MTX_ADR_ACK)
+                       tmp_stat |= ADDR_ACK;
+               else
+                       tmp_stat |= DATA_ACK;
 
                if (tmp_idx < xmit.len) {               /* all bytes transmited? */
                        TWDR = xmit.buf[tmp_idx];
@@ -157,7 +153,6 @@ ISR(TWI_vect)
                        tmp_stat &= ~BUSY;
                        next_twcr = (1<<TWEN)|(0<<TWIE)|(1<<TWINT)|(1<<TWSTO);
                }
-
                break;
 
        case TWI_MTX_DATA_NACK:
@@ -166,25 +161,20 @@ ISR(TWI_vect)
                next_twcr = (1<<TWEN)|(0<<TWIE)|(1<<TWINT)|(1<<TWSTO);
                break;
 
-       case TWI_MRX_ADR_ACK:
-               tmp_stat |= ADDR_ACK;
-               n = xmit.len-1;
-               if (tmp_idx < n) {
-                       next_twcr = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA);
-               } else {
-                       next_twcr = (1<<TWEN)|(1<<TWIE)|(1<<TWINT);
-               }
-               break;
-
        case TWI_MRX_DATA_ACK:
-               tmp_stat |= DATA_ACK;
                xmit.buf[tmp_idx] = TWDR;
                ++tmp_idx;
+               /* fall thru */
+       case TWI_MRX_ADR_ACK:
+               if ((twsr&0xf8) == TWI_MRX_ADR_ACK)
+                       tmp_stat |= ADDR_ACK;
+               else
+                       tmp_stat |= DATA_ACK;
+
                n = xmit.len-1;
                if (tmp_idx < n) {
                        next_twcr = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA);
                } else {
-               
                        next_twcr = (1<<TWEN)|(1<<TWIE)|(1<<TWINT);
                }
                break;
@@ -195,7 +185,6 @@ ISR(TWI_vect)
                xmit.buf[tmp_idx] = TWDR;
                ++tmp_idx;
                /* fall thru */
-
        default:
                tmp_stat &= ~BUSY;
                next_twcr = (1<<TWEN)|(0<<TWIE)|(1<<TWINT)|(1<<TWSTO);
@@ -205,9 +194,7 @@ ISR(TWI_vect)
        xmit.stat = tmp_stat;
        xmit.idx = tmp_idx;
 
-#ifdef DEBUG_I2C       
-       debug("|%02x", twsr);
-#endif
+       debug_i2c("|%02x", twsr);
        TWCR = next_twcr;
 }
 
@@ -226,7 +213,7 @@ static void _init(void)
        /* (Reset TWI hardware state machine.) */
        TWCR = TWI_C_DISABLE;
        _delay_us(5);
-#ifdef DEBUG_I2C
+#if DEBUG_I2C
        memset((void *) xmit.buf, 0xdf, sizeof(xmit.buf));
 #endif
 
@@ -240,7 +227,7 @@ void i2c_init(uint32_t speed)
 {
        twps = 0;
        uint32_t tmp_twbr = F_CPU /2 / speed - 8;
-       
+
        while (tmp_twbr > 255) {
                tmp_twbr >>= 4;
                twps += 1;
@@ -249,9 +236,7 @@ void i2c_init(uint32_t speed)
 
        twbr = (uint8_t) tmp_twbr;
 
-       debug("*** i2c_init: i2c_speed: %lu, twbr: %u, twps: %u\n",
-               speed, twbr, twps);
-
+       PRR0 &= ~_BV(PRTWI);
        _init();
 }
 
@@ -260,7 +245,7 @@ int_fast8_t i2c_waitready(void)
 {
        uint32_t timer = get_timer(0);
        uint8_t timeout = 0;
-       
+
        do {
                if (get_timer(timer) >= 30) {
                        timeout = TIMEOUT;
@@ -270,14 +255,14 @@ int_fast8_t i2c_waitready(void)
 
        xmit.stat |= timeout;
 
-#ifdef DEBUG_I2C
+#if DEBUG_I2C
        dump_ram((uint8_t *) &xmit, 4, "=== i2c_wait ready: (done)");
        _delay_ms(30);
-#endif 
+#endif
        return xmit.stat;
 }
 
-//static
+static
 int i2c_send(uint8_t chip, uint16_t addr, uint8_t alen, uint8_t *buffer, int8_t len)
 {
        uint8_t i, n;
@@ -296,11 +281,11 @@ int i2c_send(uint8_t chip, uint16_t addr, uint8_t alen, uint8_t *buffer, int8_t
        for (n = len + i; i < n; i++)
                xmit.buf[i] = *buffer++;
        xmit.len = i;
-       
-#ifdef DEBUG_I2C
+
+#if DEBUG_I2C
        dump_ram((uint8_t *) &xmit, 0x20, "=== i2c_send");
        _delay_ms(30);
-#endif 
+#endif
        /* Enable TWI, TWI int and initiate start condition */
        TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA);
 
@@ -309,7 +294,7 @@ int i2c_send(uint8_t chip, uint16_t addr, uint8_t alen, uint8_t *buffer, int8_t
        return rc;
 }
 
-//static
+static
 int i2c_recv(uint8_t chip, uint8_t *buffer, int8_t len)
 {
        uint8_t rc;
@@ -322,7 +307,7 @@ int i2c_recv(uint8_t chip, uint8_t *buffer, int8_t len)
        xmit.len = len + 1;
        xmit.buf[0] = (chip<<1) | 1;
 
-#ifdef DEBUG_I2C
+#if DEBUG_I2C
        dump_ram((uint8_t *) &xmit, 0x20, "=== i2c_recv: before start");
        _delay_ms(30);
 #endif
@@ -330,7 +315,7 @@ int i2c_recv(uint8_t chip, uint8_t *buffer, int8_t len)
        TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWSTA);
        rc = i2c_waitready();
 
-#ifdef DEBUG_I2C
+#if DEBUG_I2C
        dump_ram((uint8_t *) &xmit, 0x20, "=== i2c_recv: after completion");
        _delay_ms(30);
 #endif
@@ -360,16 +345,15 @@ int i2c_write(uint8_t chip, unsigned int addr, uint_fast8_t alen,
                                uint8_t *buffer, uint_fast8_t len)
 {
        int rc;
-       
+
        if ((alen > 2) || (1 + alen + len > CONFIG_SYS_I2C_BUFSIZE)) {
                debug("** i2c_write: buffer overflow, alen: %u, len: %u\n",
                        alen, len);
                return -1;
        }
-       
+
        i2c_send(chip, addr, alen, buffer, len);
        rc = i2c_waitready();
-       debug("** i2c_write: result=0x%02x\n",rc);
 
        return (rc & XMIT_DONE) != 0;
 }
@@ -384,15 +368,11 @@ int i2c_read(uint8_t chip, unsigned int addr, uint_fast8_t alen,
                        alen, len);
                return -1;
        }
-       
+
        if (alen != 0) {
                i2c_send(chip, addr, alen, NULL, 0);
-       }       
+       }
        rc = i2c_recv(chip, buffer, len);
-       debug("** i2c_read: result=0x%02x\n",rc);
 
        return !((rc & (XMIT_DONE|DATA_ACK)) == (XMIT_DONE|DATA_ACK));
 }
-
-
-