- LiFePO4 Speicher Test         
Ergebnis 1 bis 1 von 1

Thema: Peter Fleury's I2C Master Library für RP6

  1. #1
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803

    Peter Fleury's I2C Master Library für RP6

    Anzeige

    Praxistest und DIY Projekte
    Hi RP6(v2) Fans,

    die RP6I2CmasterTWI Library, die für die RP6 Plattformen (Base, M32, M256 WiFi) mit geliefert wurde (im Ordner /.../RP6Lib/common/), ist für die allermeisten Anwendungsfälle gut geeignet.
    Zudem ist sie durch die Interrupt-basierte Umsetzung wenig blockierend.

    Es gab aber immer wieder einzelne Fälle, in denen man mit der Lib bestimmte I2C-Slave-Chips nicht ansteuern konnte: Beispiel
    In dem genannten Thread geht es z.B. um den MLX90614, der bei der Abfrage einen "Repeated Start" auf dem I2C Bus benötigt und nicht einen (Neu-)Start, wie ihn die Original Lib umsetzt.
    Mit dem nötigen Know-how kann man die Original Lib von SlyD sicher auch dazu bringen, einen Repeated Start zu machen, aber in dem o.g. Thread ist das nicht gelungen. Durch die Interrupt-basierte Struktur der Lib ist das auch nicht einfach und ich habe das auch nicht fehlerfrei hingekriegt.

    Eine Lösung wäre, die bewährte I2C Master Library von Peter Fleury zu benutzen, um einen "Low-Level" Zugang zu den TWI-Funktionen zu bekommen.
    Damit könnte man dann natürlich wahlweise in TWI-Lesefunktionen einen Repeated Start oder einen (Re-)Start machen.

    Damit stelle ich euch heute mal eine "Mantel-Library" vor, die anstelle der RP6I2CmasterTWI Library benutzt werden kann. "Mantel" deshalb, weil sie die Kern-Funktionen der Fleury Lib nutzt, aber darüber (als Mantel) die "alten" Befehle der Original-Lib zur Verfügung stellt. Man kann natürlich zusätzlich auch alle Funktionen der Fleury Lib benutzen.

    Header RP6I2CmasterTWI_FLEURY.h:
    Code:
    /* ****************************************************************************
     *                           _______________________
     *                           \| RP6  ROBOT SYSTEM |/
     *                            \_-_-_-_-_-_-_-_-_-_/                  >>> COMMON
     * ----------------------------------------------------------------------------
     * ------------------- [c]2006 / 2007 - AREXX ENGINEERING ---------------------
     * ------------------- modified [c]2012 - JM3 Engineering ---------------------
     * -------------------------- http://www.arexx.com/ ---------------------------
     * ****************************************************************************
     * File: RP6I2CmasterTWI_FLEURY.h
     * Version: 1.1
     * Target: RP6 Base & Processor Expansion - ATMEGA32 @8.00 or 16.00MHz
     * Author(s): Dominik S. Herwald, JM3 Engineering, Peter Fleury
     * ****************************************************************************
     * Description:
     * For functional description of the TWI Master lib
     * s. RP6I2CmasterTWI_FLEURY.c!
     *
     * ****************************************************************************
     * CHANGELOG AND LICENSING INFORMATION CAN BE FOUND AT THE END OF THIS FILE!
     * ****************************************************************************
     */
    
    #ifdef RP6I2C_SLAVE_TWI_H
        #error YOU CAN NOT INCLUDE TWI I2C MASTER AND SLAVE ROUTINES AT THE SAME TIME!
    #else
    #ifndef RP6I2C_MASTER_TWI_H
    #define RP6I2C_MASTER_TWI_H
    
    /*****************************************************************************/
    // Includes:
    
    #include <stdint.h>                    
    #include <avr/interrupt.h>
    #include <avr/io.h>
    #include "i2cmaster.h" // I2C Master Library, v 1.10 (c) 2005 Peter Fleury
    
    /*****************************************************************************/
    
    union TWI_statusReg {
        uint8_t all;
        struct {
            unsigned lastTransOK:1;
            unsigned dataReady:1;
            unsigned repStart:1;
            unsigned unusedBits:5;
        };
    };
    
    extern union TWI_statusReg TWI_statusReg;
    
    //extern uint8_t i2c_req_adr;
    extern uint8_t TWI_operation;
    
    #define I2CTWI_isBusy() ((TWCR & (1<<TWIE))) 
    
    // Read functions will use the (RE-)START condition (default):
    #define I2CTWI_start() {TWI_statusReg.repStart = 0;}
    // Read functions will use the REPEATED START condition:
    #define I2CTWI_repStart() {TWI_statusReg.repStart = 1;}
    
    #define I2CTWI_isRepStart() (TWI_statusReg.all & 4)
    #define I2CTWI_isDataReady() (TWI_statusReg.all & 2)
    
    
    // Sample TWI transmission states, used in the main application.
    #define I2CTWI_NO_OPERATION              0
    #define I2CTWI_SEND_REGISTER          1
    #define I2CTWI_REQUEST_BYTES          2
    #define I2CTWI_READ_BYTES_FROM_BUFFER 3
    
    #define I2CTWI_BUFFER_SIZE 16   // Set this to the largest message size that will be sent including address byte.
    #define I2CTWI_BUFFER_REC_SIZE 48 // Set this to the largest message size that will be received including address byte.
    
    #define I2CTWI_initMaster(__FREQ__) __I2CTWI_initMaster((uint8_t)((F_CPU/(2000UL*__FREQ__))-8))
    void __I2CTWI_initMaster(uint8_t twi_bitrate);
    
    void I2CTWI_setRequestedDataReadyHandler(void (*requestedDataReadyHandler)(uint8_t));
    void I2CTWI_setTransmissionErrorHandler(void (*transmissionErrorHandler)(uint8_t));
    
    void task_I2CTWI(void);
    uint8_t I2CTWI_getState(void);
    
    void I2CTWI_requestDataFromDevice(uint8_t requestAdr, uint8_t requestID, uint8_t numberOfBytes);
    void I2CTWI_requestRegisterFromDevice(uint8_t targetAdr, uint8_t requestID, uint8_t reg, uint8_t numberOfBytes);
    void I2CTWI_getReceivedData(uint8_t *msg, uint8_t msgSize);
    
    void I2CTWI_readBytes(uint8_t targetAdr, uint8_t * messageBuffer, uint8_t numberOfBytes);
    uint8_t I2CTWI_readByte(uint8_t targetAdr);
    void I2CTWI_readRegisters(uint8_t targetAdr, uint8_t reg, uint8_t * messageBuffer, uint8_t numberOfBytes);
    void I2CTWI_readWordRegisters(uint8_t targetAdr, uint8_t reg, uint8_t * messageBuffer, uint8_t numberOfRegs);
    
    void I2CTWI_transmitByte(uint8_t adr, uint8_t data);
    void I2CTWI_transmit2Bytes(uint8_t adr, uint8_t data1, uint8_t data2);
    void I2CTWI_transmit3Bytes(uint8_t targetAdr, uint8_t data1, uint8_t data2, uint8_t data3);
    void I2CTWI_transmit4Bytes(uint8_t targetAdr, uint8_t data1, uint8_t data2, uint8_t data3, uint8_t data4);
    void I2CTWI_transmitBytes(uint8_t targetAdr, uint8_t *msg, uint8_t numberOfBytes);
    
    #define TWI_READ  1
    #define TWI_GEN_CALL 0 
    
    /*****************************************************************************/
    // TWI Status Codes:
    // The TWI status codes were taken from ATMEL AN315!
    
    // General TWI Master staus codes
    #define TWI_START                  0x08  // START has been transmitted
    #define TWI_REP_START              0x10  // Repeated START has been transmitted
    #define TWI_ARB_LOST               0x38  // Arbitration lost
    
    // TWI Master Transmitter staus codes
    #define TWI_MTX_ADR_ACK            0x18  // SLA+W has been transmitted and ACK received
    #define TWI_MTX_ADR_NACK           0x20  // SLA+W has been transmitted and NACK received
    #define TWI_MTX_DATA_ACK           0x28  // Data byte has been transmitted and ACK received
    #define TWI_MTX_DATA_NACK          0x30  // Data byte has been transmitted and NACK received
    
    // TWI Master Receiver staus codes
    #define TWI_MRX_ADR_ACK            0x40  // SLA+R has been transmitted and ACK received
    #define TWI_MRX_ADR_NACK           0x48  // SLA+R has been transmitted and NACK received
    #define TWI_MRX_DATA_ACK           0x50  // Data byte has been received and ACK transmitted
    #define TWI_MRX_DATA_NACK          0x58  // Data byte has been received and NACK transmitted
    
    // TWI Slave Transmitter staus codes
    #define TWI_STX_ADR_ACK            0xA8  // Own SLA+R has been received; ACK has been returned
    #define TWI_STX_ADR_ACK_M_ARB_LOST 0xB0  // Arbitration lost in SLA+R/W as Master; own SLA+R has been received; ACK has been returned
    #define TWI_STX_DATA_ACK           0xB8  // Data byte in TWDR has been transmitted; ACK has been received
    #define TWI_STX_DATA_NACK          0xC0  // Data byte in TWDR has been transmitted; NOT ACK has been received
    #define TWI_STX_DATA_ACK_LAST_BYTE 0xC8  // Last data byte in TWDR has been transmitted (TWEA = “0”); ACK has been received
    
    // TWI Slave Receiver staus codes
    #define TWI_SRX_ADR_ACK            0x60  // Own SLA+W has been received ACK has been returned
    #define TWI_SRX_ADR_ACK_M_ARB_LOST 0x68  // Arbitration lost in SLA+R/W as Master; own SLA+W has been received; ACK has been returned
    #define TWI_SRX_GEN_ACK            0x70  // General call address has been received; ACK has been returned
    #define TWI_SRX_GEN_ACK_M_ARB_LOST 0x78  // Arbitration lost in SLA+R/W as Master; General call address has been received; ACK has been returned
    #define TWI_SRX_ADR_DATA_ACK       0x80  // Previously addressed with own SLA+W; data has been received; ACK has been returned
    #define TWI_SRX_ADR_DATA_NACK      0x88  // Previously addressed with own SLA+W; data has been received; NOT ACK has been returned
    #define TWI_SRX_GEN_DATA_ACK       0x90  // Previously addressed with general call; data has been received; ACK has been returned
    #define TWI_SRX_GEN_DATA_NACK      0x98  // Previously addressed with general call; data has been received; NOT ACK has been returned
    #define TWI_SRX_STOP_RESTART       0xA0  // A STOP condition or repeated START condition has been received while still addressed as Slave
    
    // TWI Miscellaneous status codes
    #define TWI_NO_STATE               0xF8  // No relevant state information available; TWINT = “0”
    #define TWI_BUS_ERROR              0x00  // Bus error due to an illegal START or STOP condition
    
    
    #endif
    #endif
    
    /******************************************************************************
     * Additional info
     * ****************************************************************************
     * Changelog:
     * - v. 1.1 4.09.2012 by JM3 Engineering
     *      - NEW: added support for reading 16Bit registers
     * - v. 1.0 (initial release) 16.05.2007 by Dominik S. Herwald
     *
     * ****************************************************************************
     * Bugs, feedback, questions and modifications can be posted on the AREXX Forum
     * on http://www.arexx.com/forum/ !
     * Of course you can also write us an e-mail to: info@arexx.nl
     * AREXX Engineering may publish updates from time to time on AREXX.com!
     * ****************************************************************************
     * - LICENSE -
     * GNU GPL v2 (http://www.gnu.org/licenses/gpl.txt, a local copy can be found
     * on the RP6 CD in the RP6 sorce code folders!)
     * This program is free software. You can redistribute it and/or modify
     * it under the terms of the GNU General Public License version 2 as published
     * by the Free Software Foundation.
     * ****************************************************************************
     */
    
    /*****************************************************************************/
    // EOF
    Source RP6I2CmasterTWI_FLEURY.c:
    Code:
    /* ****************************************************************************
     *                           _______________________
     *                           \| RP6  ROBOT SYSTEM |/
     *                            \_-_-_-_-_-_-_-_-_-_/                  >>> COMMON
     * ----------------------------------------------------------------------------
     * ------------------- [c]2006 / 2007 - AREXX ENGINEERING ---------------------
     * ------------------- modified [c]2012 - JM3 Engineering ---------------------
     * -------------------------- http://www.arexx.com/ ---------------------------
     * ****************************************************************************
     * File: RP6I2CmasterTWI_FLEURY.c
     * Version: 1.1
     * Target: RP6 Base & Processor Expansion - ATMEGA32 @8.00 or 16.00MHz
     * Author(s): Dominik S. Herwald, JM3 Engineering, Peter Fleury
     * ****************************************************************************
     * Description:
     * This is the I2C Bus Master Library based on the Fleury I2C Master Library.
     * Download the file "i2cmaster.zip" here:
     *   http://homepage.hispeed.ch/peterfleury/avr-software.html#libs
     * Extract the files "i2cmaster.h" and "twimaster.c" and copy them to the
     * folder /.../RP6Lib/RP6common.
     * Please include twimaster.c in makefile of your project:
     *   SRC += $(RP6_LIB_PATH)/RP6common/twimaster.c
     * You will find documentation for this library here:
     *   http://homepage.hispeed.ch/peterfleury/group__pfleury__ic2master.html
     * This I2C Bus Master Library can be used instead of the original
     * RP6I2CmasterTWI Library.
     * Differences between the two libraries:
     *   RP6I2CmasterTWI                     RP6I2CmasterTWI_FLEURY
     *   ----------------------------------------------------------
     *   Dominik S. Herwald                  Kernel: Peter Fleury
     *   Interrupt-based                     NOT interrupt-based
     *   No repeated start (read functions)  Repeated OR (re-)start
     *   Only high-level TWI functions       High- AND low-level
     *
     * ****************************************************************************
     * CHANGELOG AND LICENSING INFORMATION CAN BE FOUND AT THE END OF THIS FILE!
     * ****************************************************************************
     */
     
    /*****************************************************************************/
    // Includes:
    
    #include "RP6I2CmasterTWI_FLEURY.h"
    
    /*
     * This function initializes the TWI interface! You need
     * to call this first before you use the TWI interface!
     * You should better use the macro I2CTWI_initMaster without __ at the
     * beginning. There you can specify the SCL frequency in kHz!
     * Example: 
     * I2CTWI_initMaster(100); // I2C Master mode with 100kHz SCL frequency
     *                           // This calculates TWBR value automatically.
     *
     * __I2CTWI_initMaster(32); // I2C Master mode also with 100kHz SCL frequency
     *                             // but directly calculated with the formula in the
     *                            // MEGA32 datasheet.
     */
    void __I2CTWI_initMaster(uint8_t twi_bitrate)
    {
        cli();
        TWBR = twi_bitrate;
        TWSR = 0x00;      // DO NOT USE PRESCALER! Otherwise you need to mask the
        TWDR = 0xFF;      // TWSR Prescaler bits everywhere TWSR is read!            
        TWCR = (1<<TWEN);
        TWI_statusReg.lastTransOK = 1;
        sei();                      
        TWI_statusReg.dataReady = 0;                // No data
        TWI_statusReg.repStart = 0;                    // No repeated starts
        TWI_operation = I2CTWI_NO_OPERATION;        // Lib not interrupt-based!
    }
    
    /*****************************************************************************/
    // TWI Event handlers
    // These functions are used to receive Data or react on errors.
    
    void I2CTWI_requestedDataReady_DUMMY(uint8_t requestID){}
    static void (*I2CTWI_requestedDataReadyHandler)(uint8_t) = I2CTWI_requestedDataReady_DUMMY;
    void I2CTWI_setRequestedDataReadyHandler(void (*requestedDataReadyHandler)(uint8_t))
    {
        I2CTWI_requestedDataReadyHandler = requestedDataReadyHandler;
    }
    
    void I2CTWI_transmissionError_DUMMY(uint8_t requestID){}
    static void (*I2CTWI_transmissionErrorHandler)(uint8_t) = I2CTWI_transmissionError_DUMMY;
    void I2CTWI_setTransmissionErrorHandler(void (*transmissionErrorHandler)(uint8_t))
    {
        I2CTWI_transmissionErrorHandler = transmissionErrorHandler;
    }
    
    /*****************************************************************************/
    // Control task
    
    static uint8_t I2CTWI_recbuf[I2CTWI_BUFFER_REC_SIZE];
    union TWI_statusReg TWI_statusReg = {0}; 
    uint8_t TWI_TWSR_state = 0;
    
    uint8_t I2CTWI_request_adr = 0;
    uint8_t I2CTWI_request_reg = 0;
    uint8_t I2CTWI_request_size = 0;
    int16_t I2CTWI_requestID = 0;
    uint8_t TWI_operation = I2CTWI_NO_OPERATION;
    
    
    /**
     * You have to call this functions frequently out of the main loop.
     * It calls the event handlers above automatically if data has been received.
     */
    void task_I2CTWI(void)
    {
        if(TWI_statusReg.dataReady) {
            if(I2CTWI_requestID!=-1)
                I2CTWI_requestedDataReadyHandler(I2CTWI_requestID);
        }
        uint8_t errState = I2CTWI_getState();
        if(errState != 0) {
            TWI_statusReg.lastTransOK = 1;
            TWI_statusReg.dataReady = 0;
            I2CTWI_request_adr = 0;
            I2CTWI_requestID = 0;
            I2CTWI_request_size = 0;
            I2CTWI_transmissionErrorHandler(errState);
            TWI_TWSR_state = 0;
        }
    }
    
    
    /*****************************************************************************/
    // Request functions - you need to use requestedDataReadyHandler to receive 
    // the requested data...
    
    /**
     * Requests a number of Bytes from the target device. You need to set a requestID 
     * to be able to identify the request after the data has been received and the 
     * "requestedDataReady" event handler is called.
     */
    void I2CTWI_requestDataFromDevice(uint8_t targetAdr, uint8_t requestID, uint8_t numberOfBytes)
    {    
        uint8_t i;
        i = i2c_start(targetAdr+I2C_WRITE);
        if (i) {TWI_TWSR_state = TWSR & 0xF8; i2c_stop(); return;}
        if (TWI_statusReg.repStart)
            i2c_rep_start(targetAdr+I2C_READ);
        else {
            i2c_stop();
            i2c_start(targetAdr+I2C_READ);
        }
        i = 1;
        while (i < numberOfBytes) {
            I2CTWI_recbuf[i] = i2c_readAck();
            i++;
        }
        I2CTWI_recbuf[i] = i2c_readNak();
        i2c_stop();
        I2CTWI_request_adr = targetAdr;
        I2CTWI_request_reg = 0;
        I2CTWI_requestID = (int16_t)requestID;
        I2CTWI_request_size = numberOfBytes;
        TWI_statusReg.lastTransOK = 1;                // Set status bits to completed successfully.
        TWI_statusReg.dataReady = 1;                // Requested data ready
    }
    
    /**
     * Same as requestDataFromDevice, but this function first sets the register
     * that has to be read and transmits the register number before! 
     */
    void I2CTWI_requestRegisterFromDevice(uint8_t targetAdr, uint8_t requestID, uint8_t reg, uint8_t numberOfBytes)
    {    
        uint8_t i;
        i = i2c_start(targetAdr+I2C_WRITE);
        if (i) {TWI_TWSR_state = TWSR & 0xF8; i2c_stop(); return;}
        i2c_write(reg);
        if (TWI_statusReg.repStart)
            i2c_rep_start(targetAdr+I2C_READ);
        else {
            i2c_stop();
            i2c_start(targetAdr+I2C_READ);
        }
        i = 1;
        while (i < numberOfBytes) {
            I2CTWI_recbuf[i] = i2c_readAck();
            i++;
        }
        I2CTWI_recbuf[i] = i2c_readNak();
        i2c_stop();
        I2CTWI_requestID = (int16_t)requestID;
        I2CTWI_request_adr = targetAdr;
        I2CTWI_request_reg = reg;
        I2CTWI_request_size = numberOfBytes;
        TWI_statusReg.lastTransOK = 1;         
        TWI_statusReg.dataReady = 1;         
    }
    
    /**
     * This function can be used in the requestedDataReady Handler to get the
     * received data from the TWI Buffer. You need to provide a pointer to a 
     * buffer which is large enough to hold all received data. 
     * You can specify the number of bytes you want to read out of the buffer
     * with the msgSize parameter.
     * It does not make sense to use this function anywhere else as you 
     * can not guarantee what is in the reception buffer...
     */
    void I2CTWI_getReceivedData(uint8_t *msg, uint8_t msgSize)
    {
        uint8_t i = 0;
        if(TWI_statusReg.dataReady) {                // Requested data ready?
            for(; i < msgSize; i++)
                msg[i] = I2CTWI_recbuf[i+1];
            TWI_statusReg.dataReady = 0;
        }
    }
    
    /**
     * This function returns the last TWI State / Error State.
     */
    uint8_t I2CTWI_getState(void)
    {
        return (TWI_TWSR_state); // Return error state.
    }
    
    /*****************************************************************************/
    // Read functions:
    
    /**
     * Reads "numberOfBytes" from "targetAdr" Register "reg" into "messageBuffer". 
     * If the slave device supports auto increment, then it reads all subsequent registers of course! 
     */
    void I2CTWI_readRegisters(uint8_t targetAdr, uint8_t reg, uint8_t * messageBuffer, uint8_t numberOfBytes)
    {
        uint8_t i;
        i = i2c_start(targetAdr+I2C_WRITE);
        if (i) {TWI_TWSR_state = TWSR & 0xF8; i2c_stop(); return;}
        i2c_write(reg);
        if (TWI_statusReg.repStart)
            i2c_rep_start(targetAdr+I2C_READ);
        else {
            i2c_stop();
            i2c_start(targetAdr+I2C_READ);
        }
        i = 1;
        while (i < numberOfBytes) {
            I2CTWI_recbuf[i] = i2c_readAck();
            i++;
        }
        I2CTWI_recbuf[i] = i2c_readNak();
        i2c_stop();
        TWI_statusReg.lastTransOK = 1;         
        TWI_statusReg.dataReady = 1;     
        I2CTWI_requestID = -1;
        I2CTWI_getReceivedData(&messageBuffer[0], numberOfBytes+1);
    }
    
    /**
     * Reads "numberOfRegs" from "targetAdr" Register "reg" into "messageBuffer". 
     * If the slave device supports auto increment, then it reads all subsequent registers of course! 
     */
    void I2CTWI_readWordRegisters(uint8_t targetAdr, uint8_t reg, uint8_t * messageBuffer, uint8_t numberOfRegs)
    {
        uint8_t i;
        i = i2c_start(targetAdr+I2C_WRITE);
        if (i) {TWI_TWSR_state = TWSR & 0xF8; i2c_stop(); return;}
        i2c_write(reg);
        if (TWI_statusReg.repStart)
            i2c_rep_start(targetAdr+I2C_READ);
        else {
            i2c_stop();
            i2c_start(targetAdr+I2C_READ);
        }
        i = 1;
        while (i < (numberOfRegs<<1)) {
            I2CTWI_recbuf[i] = i2c_readAck();
            i++;
        }
        I2CTWI_recbuf[i] = i2c_readNak();
        i2c_stop();
        TWI_statusReg.lastTransOK = 1;         
        TWI_statusReg.dataReady = 1;     
        I2CTWI_requestID = -1;
        I2CTWI_getReceivedData(&messageBuffer[0], (numberOfRegs<<1)+1);
    }
    
    /**
     * Same as readRegisters, but you need to make sure which register to read yourself - if there
     * are any registers at all in your slave device.  
     * 
     */
    void I2CTWI_readBytes(uint8_t targetAdr, uint8_t * messageBuffer, uint8_t numberOfBytes)
    {
        uint8_t i;
        i = i2c_start(targetAdr+I2C_WRITE);
        if (i) {TWI_TWSR_state = TWSR & 0xF8; i2c_stop(); return;}
        if (TWI_statusReg.repStart)
            i2c_rep_start(targetAdr+I2C_READ);
        else {
            i2c_stop();
            i2c_start(targetAdr+I2C_READ);
        }
        i = 1;
        while (i < numberOfBytes) {
            I2CTWI_recbuf[i] = i2c_readAck();
            i++;
        }
        I2CTWI_recbuf[i] = i2c_readNak();
        i2c_stop();
        TWI_statusReg.lastTransOK = 1;         
        TWI_statusReg.dataReady = 1;
        I2CTWI_requestID = -1;
        I2CTWI_getReceivedData(&messageBuffer[0], numberOfBytes+1);
    }
    
    /**
     * Reads a single byte from the slave device. 
     */
    uint8_t I2CTWI_readByte(uint8_t targetAdr)
    {
        uint8_t i;
        i = i2c_start(targetAdr+I2C_WRITE);
        if (i) {TWI_TWSR_state = TWSR & 0xF8; i2c_stop(); return 0;}
        if (TWI_statusReg.repStart)
            i2c_rep_start(targetAdr+I2C_READ);
        else {
            i2c_stop();
            i2c_start(targetAdr+I2C_READ);
        }
        I2CTWI_recbuf[1] = i2c_readNak();
        i2c_stop();
        TWI_statusReg.lastTransOK = 1;         
        TWI_statusReg.dataReady = 0;
        I2CTWI_requestID = -1;
        return I2CTWI_recbuf[1];
    }
    
    /*****************************************************************************/
    // Transmission functions
    
    /**
     * Transmits a single byte to a slave device. It waits until the
     * transmission is finished (it blocks the normal program flow!)! 
     */
    void I2CTWI_transmitByte(uint8_t targetAdr, uint8_t data)
    {
        uint8_t i;
        i = i2c_start(targetAdr+I2C_WRITE);
        if (i) {TWI_TWSR_state = TWSR & 0xF8; i2c_stop(); return;}
        i2c_write(data);
        i2c_stop();
        TWI_statusReg.lastTransOK = 0;
        TWI_statusReg.dataReady = 0;
    }
    
    /**
     * This is just the same as transmitByte, but you can pass 2 Bytes to
     * this function which are then transferred. 
     */
    void I2CTWI_transmit2Bytes(uint8_t targetAdr, uint8_t data1, uint8_t data2)
    {
        uint8_t i;
        i = i2c_start(targetAdr+I2C_WRITE);
        if (i) {TWI_TWSR_state = TWSR & 0xF8; i2c_stop(); return;}
        i2c_write(data1);
        i2c_write(data2);
        i2c_stop();
        TWI_statusReg.lastTransOK = 0;
        TWI_statusReg.dataReady = 0;
    }
    
    /**
     * Transmits 3 Bytes to the slave.
     */
    void I2CTWI_transmit3Bytes(uint8_t targetAdr, uint8_t data1, uint8_t data2, uint8_t data3)
    {
        uint8_t i;
        i = i2c_start(targetAdr+I2C_WRITE);
        if (i) {TWI_TWSR_state = TWSR & 0xF8; i2c_stop(); return;}
        i2c_write(data1);
        i2c_write(data2);
        i2c_write(data3);
        i2c_stop();
        TWI_statusReg.lastTransOK = 0;
        TWI_statusReg.dataReady = 0;
    }
    
    /**
     * Transmits 4 Bytes to the slave.
     */
    void I2CTWI_transmit4Bytes(uint8_t targetAdr, uint8_t data1, uint8_t data2, uint8_t data3, uint8_t data4)
    {
        uint8_t i;
        i = i2c_start(targetAdr+I2C_WRITE);
        if (i) {TWI_TWSR_state = TWSR & 0xF8; i2c_stop(); return;}
        i2c_write(data1);
        i2c_write(data2);
        i2c_write(data3);
        i2c_write(data4);
        i2c_stop();
        TWI_statusReg.lastTransOK = 0;
        TWI_statusReg.dataReady = 0;
    }
    
    
    /**
     * Transmits "numberOfBytes" Bytes to the Slave device. The Bytes need to be
     * in the Buffer "msg". Otherwise it is just the same as the other transmit functions.
     */
    void I2CTWI_transmitBytes(uint8_t targetAdr, uint8_t *msg, uint8_t numberOfBytes)
    {
        uint8_t i;
        i = i2c_start(targetAdr+I2C_WRITE);
        if (i) {TWI_TWSR_state = TWSR & 0xF8; i2c_stop(); return;}
        numberOfBytes++; 
        i = 0;
        for(; i < numberOfBytes; i++)
            i2c_write(msg[i]);
        i2c_stop();
        TWI_statusReg.lastTransOK = 0;
        TWI_statusReg.dataReady = 0;
    }
    
    /******************************************************************************
     * Additional info
     * ****************************************************************************
     * Changelog:
     * - v. 1.1 4.09.2012 by JM3 Engineering
     *      - NEW: added support for reading 16Bit registers
     * - v. 1.0 (initial release) 16.05.2007 by Dominik S. Herwald
     *
     * ****************************************************************************
     * Bugs, feedback, questions and modifications can be posted on the AREXX Forum
     * on http://www.arexx.com/forum/ !
     * Of course you can also write us an e-mail to: info@arexx.nl
     * AREXX Engineering may publish updates from time to time on AREXX.com!
     * ****************************************************************************
     * - LICENSE -
     * GNU GPL v2 (http://www.gnu.org/licenses/gpl.txt, a local copy can be found
     * on the RP6 CD in the RP6 sorce code folders!)
     * This program is free software. You can redistribute it and/or modify
     * it under the terms of the GNU General Public License version 2 as published
     * by the Free Software Foundation.
     * ****************************************************************************
     */
    
    /*****************************************************************************/
    // EOF
    - - - Aktualisiert - - -

    Was ist in der neuen I2C Master Library für das RP6 System neu/anders:

    1. Die neue Mantel Lib ist nicht mehr Interrupt-basiert und hat daher ein anderes Timing.
    2. Darüber hinaus ist sie weitgehend kompatibel zur Original Lib von SlyD und wurde mit allen Original Demos getestet.
    3. Lese-Funktionen können wahlweise mit I2C Start oder Repeated Start ausgeführt werden.
    4. Neben den vertrauten I2C-Schreib-Lese-Funktionen, die in der RP6 Anleitung beschrieben werden, kann man alle Funktionen der Fleury Lib nutzen.
    Eine Anleitung dazu gibt's hier.

    Was muss man zusätzlich noch wissen:

    Die Peter Fleury I2C Master Library muss man von dem oben angegebenen Link herunterladen und die Dateien "twimaster.c" und "i2cmaster.h" ins Verzeichnis /../RP6Lib/RP6common kopieren. Da hinein kommen natürlich auch die Dateien der Mantel Lib.

    Die neue Lib muss mit:
    SRC += $(RP6_LIB_PATH)/RP6common/twimaster.c
    SRC += $(RP6_LIB_PATH)/RP6common/RP6I2CmasterTWI_FLEURY.c
    ... im makefile eingebunden werden und mit:
    #include "RP6I2CmasterTWI_FLEURY.h"
    ... ins Hauptprogramm eingebunden werden.

    Das ist alles. (Fast) alle Programme des RP6 Systems müßten mit der neuen Lib laufen.

    Die TWI Lesefunktionen erfolgen (wie beim Original) mit (Neu-)Start.
    Braucht man im Einzelfall den Repeated Start, setzt man einfach vor die jeweilige Lesefunktion:
    I2CTWI_repStart();
    Diese Einstellung bleibt dann dauerhaft erhalten bis man mit:
    I2CTWI_start();
    ... wieder auf die Standardeinstellung (Start) umstellt.

    Viel Erfolg!
    Geändert von Dirk (02.11.2014 um 10:09 Uhr)
    Gruß
    Dirk

Ähnliche Themen

  1. Peter Fleury TWI Beispiel Master ohne funktion
    Von Savag im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 20.09.2012, 20:32
  2. Antworten: 35
    Letzter Beitrag: 03.03.2012, 17:10
  3. myAVR MK2 als i2c (twi) master mit der peter fleury lib
    Von adrelino im Forum C - Programmierung (GCC u.a.)
    Antworten: 1
    Letzter Beitrag: 05.06.2010, 20:41
  4. LCD library von Peter Fleury ÄÖÜ fehlt
    Von Woftschik im Forum C - Programmierung (GCC u.a.)
    Antworten: 21
    Letzter Beitrag: 18.04.2009, 15:31
  5. Anfängerproblem mit i2c und Peter Fleury
    Von hansbausn im Forum C - Programmierung (GCC u.a.)
    Antworten: 5
    Letzter Beitrag: 20.11.2005, 18:26

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiTime Speicher und Akkus