1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/firmware/myi2c.c Tue Jan 29 22:31:52 2008 +0100
1.3 @@ -0,0 +1,234 @@
1.4 +/*
1.5 + * Project Frontplatte
1.6 + *
1.7 + * myi2c.c - I2C-Bus Commands
1.8 + *
1.9 + * This file is released under the GNU General Public License. Refer
1.10 + * to the COPYING file distributed with this package.
1.11 + *
1.12 + * (c) 2007 Carsten Presser cpresser AT fsing.uni-sb.de
1.13 + * most parts are taken from AN991 by microchip
1.14 + */
1.15 +
1.16 +#include <p18cxxx.h>
1.17 +#include "myi2c.h"
1.18 +#include <i2c.h>
1.19 +
1.20 +
1.21 +unsigned int PageSize;
1.22 +
1.23 +
1.24 +unsigned char LDByteWriteI2C( unsigned char ControlByte, unsigned char LowAdd, unsigned char data )
1.25 +{
1.26 + IdleI2C(); // ensure module is idle
1.27 + StartI2C(); // initiate START condition
1.28 + while ( SSPCON2bits.SEN ); // wait until start condition is over
1.29 + WriteI2C( ControlByte ); // write 1 byte - R/W bit should be 0
1.30 + IdleI2C(); // ensure module is idle
1.31 + WriteI2C( LowAdd ); // write address byte to EEPROM
1.32 + IdleI2C(); // ensure module is idle
1.33 + WriteI2C ( data ); // Write data byte to EEPROM
1.34 + IdleI2C(); // ensure module is idle
1.35 + StopI2C(); // send STOP condition
1.36 + while ( SSPCON2bits.PEN ); // wait until stop condition is over
1.37 + while (EEAckPolling(ControlByte)); //Wait for write cycle to complete
1.38 + return ( 0 ); // return with no error
1.39 +}
1.40 +
1.41 +
1.42 +unsigned char LDByteReadI2C(unsigned char ControlByte)
1.43 +{
1.44 + unsigned char data;
1.45 + IdleI2C(); // ensure module is idle
1.46 + StartI2C(); // initiate START condition
1.47 + while ( SSPCON2bits.SEN ); // wait until start condition is over
1.48 + WriteI2C( ControlByte | 0x01 ); // WRITE 1 byte - R/W bit should be 1 for read
1.49 + IdleI2C(); // ensure module is idle
1.50 + data = ReadI2C();
1.51 + IdleI2C(); // ensure module is idle
1.52 + NotAckI2C(); // send not ACK condition
1.53 + while ( SSPCON2bits.ACKEN ); // wait until ACK sequence is over
1.54 + StopI2C(); // send STOP condition
1.55 + while ( SSPCON2bits.PEN ); // wait until stop condition is over
1.56 + return ( data ); // return with no error
1.57 +}
1.58 +
1.59 +
1.60 +
1.61 +unsigned char LDPageReadI2C( unsigned char ControlByte, unsigned char address, unsigned char *data, unsigned char length )
1.62 +{
1.63 + IdleI2C(); // ensure module is idle
1.64 + StartI2C(); // initiate START condition
1.65 + while ( SSPCON2bits.SEN ); // wait until start condition is over
1.66 + WriteI2C( ControlByte ); // write 1 byte
1.67 + IdleI2C(); // ensure module is idle
1.68 + WriteI2C( address ); // WRITE word address to EEPROM
1.69 + IdleI2C(); // ensure module is idle
1.70 + RestartI2C(); // generate I2C bus restart condition
1.71 + while ( SSPCON2bits.RSEN ); // wait until re-start condition is over
1.72 + WriteI2C( ControlByte | 0x01 ); // WRITE 1 byte - R/W bit should be 1 for read
1.73 + IdleI2C(); // ensure module is idle
1.74 + getsI2C( data, length ); // read in multiple bytes
1.75 + NotAckI2C(); // send not ACK condition
1.76 + while ( SSPCON2bits.ACKEN ); // wait until ACK sequence is over
1.77 + StopI2C(); // send STOP condition
1.78 + while ( SSPCON2bits.PEN ); // wait until stop condition is over
1.79 + return ( 0 ); // return with no error
1.80 +
1.81 +}
1.82 +
1.83 +unsigned char LDPageWriteI2C( unsigned char ControlByte, unsigned char LowAdd, unsigned char *wrptr, unsigned char length)
1.84 +{
1.85 + PageSize = (int)length;
1.86 +
1.87 + IdleI2C(); // ensure module is idle
1.88 + StartI2C(); // initiate START condition
1.89 + while ( SSPCON2bits.SEN ); // wait until start condition is over
1.90 + WriteI2C( ControlByte ); // write 1 byte - R/W bit should be 0
1.91 + IdleI2C(); // ensure module is idle
1.92 + WriteI2C( LowAdd ); // write LowAdd byte to EEPROM
1.93 + IdleI2C(); // ensure module is idle
1.94 + putstringI2C ( wrptr ); // pointer to data for page write
1.95 + IdleI2C(); // ensure module is idle
1.96 + StopI2C(); // send STOP condition
1.97 + while ( SSPCON2bits.PEN ); // wait until stop condition is over
1.98 + return ( 0 ); // return with no error
1.99 +}
1.100 +
1.101 +
1.102 +
1.103 +/*
1.104 +unsigned char HDByteWriteI2C( unsigned char ControlByte, unsigned char HighAdd, unsigned char LowAdd, unsigned char data )
1.105 +{
1.106 + IdleI2C(); // ensure module is idle
1.107 + StartI2C(); // initiate START condition
1.108 + while ( SSPCON2bits.SEN ); // wait until start condition is over
1.109 + WriteI2C( ControlByte ); // write 1 byte - R/W bit should be 0
1.110 + IdleI2C(); // ensure module is idle
1.111 + WriteI2C( HighAdd ); // write address byte to EEPROM
1.112 + IdleI2C(); // ensure module is idle
1.113 + WriteI2C( LowAdd ); // write address byte to EEPROM
1.114 + IdleI2C(); // ensure module is idle
1.115 + WriteI2C ( data ); // Write data byte to EEPROM
1.116 + IdleI2C(); // ensure module is idle
1.117 + StopI2C(); // send STOP condition
1.118 + while ( SSPCON2bits.PEN ); // wait until stop condition is over
1.119 + while (EEAckPolling(ControlByte)); //Wait for write cycle to complete
1.120 + return ( 0 ); // return with no error
1.121 +}
1.122 +unsigned char HDByteReadI2C( unsigned char ControlByte, unsigned char HighAdd, unsigned char LowAdd, unsigned char *data, unsigned char length )
1.123 +{
1.124 + IdleI2C(); // ensure module is idle
1.125 + StartI2C(); // initiate START condition
1.126 + while ( SSPCON2bits.SEN ); // wait until start condition is over
1.127 + WriteI2C( ControlByte ); // write 1 byte
1.128 + IdleI2C(); // ensure module is idle
1.129 + WriteI2C( HighAdd ); // WRITE word address to EEPROM
1.130 + IdleI2C(); // ensure module is idle
1.131 + while ( SSPCON2bits.RSEN ); // wait until re-start condition is over
1.132 + WriteI2C( LowAdd ); // WRITE word address to EEPROM
1.133 + IdleI2C(); // ensure module is idle
1.134 + RestartI2C(); // generate I2C bus restart condition
1.135 + while ( SSPCON2bits.RSEN ); // wait until re-start condition is over
1.136 + WriteI2C( ControlByte | 0x01 ); // WRITE 1 byte - R/W bit should be 1 for read
1.137 + IdleI2C(); // ensure module is idle
1.138 + getsI2C( data, length ); // read in multiple bytes
1.139 + NotAckI2C(); // send not ACK condition
1.140 + while ( SSPCON2bits.ACKEN ); // wait until ACK sequence is over
1.141 + StopI2C(); // send STOP condition
1.142 + while ( SSPCON2bits.PEN ); // wait until stop condition is over
1.143 + return ( 0 ); // return with no error
1.144 +}
1.145 +unsigned char HDPageWriteI2C( unsigned char ControlByte, unsigned char HighAdd, unsigned char LowAdd, unsigned char *wrptr )
1.146 +{
1.147 + IdleI2C(); // ensure module is idle
1.148 + StartI2C(); // initiate START condition
1.149 + while ( SSPCON2bits.SEN ); // wait until start condition is over
1.150 + WriteI2C( ControlByte ); // write 1 byte - R/W bit should be 0
1.151 + IdleI2C(); // ensure module is idle
1.152 + WriteI2C( HighAdd ); // write HighAdd byte to EEPROM
1.153 + IdleI2C(); // ensure module is idle
1.154 + WriteI2C( LowAdd ); // write LowAdd byte to EEPROM
1.155 + IdleI2C(); // ensure module is idle
1.156 + putstringI2C ( wrptr ); // pointer to data for page write
1.157 + IdleI2C(); // ensure module is idle
1.158 + StopI2C(); // send STOP condition
1.159 + while ( SSPCON2bits.PEN ); // wait until stop condition is over
1.160 + return ( 0 ); // return with no error
1.161 +}
1.162 +unsigned char HDSequentialReadI2C( unsigned char ControlByte, unsigned char HighAdd, unsigned char LowAdd, unsigned char *rdptr, unsigned char length )
1.163 +{
1.164 + IdleI2C(); // ensure module is idle
1.165 + StartI2C(); // initiate START condition
1.166 + while ( SSPCON2bits.SEN ); // wait until start condition is over
1.167 + WriteI2C( ControlByte ); // write 1 byte
1.168 + IdleI2C(); // ensure module is idle
1.169 + WriteI2C( HighAdd ); // WRITE word address to EEPROM
1.170 + IdleI2C(); // ensure module is idle
1.171 + WriteI2C( LowAdd ); // write HighAdd byte to EEPROM
1.172 + IdleI2C(); // ensure module is idle
1.173 + RestartI2C(); // generate I2C bus restart condition
1.174 + while ( SSPCON2bits.RSEN ); // wait until re-start condition is over
1.175 + WriteI2C( ControlByte | 0x01 ); // WRITE 1 byte - R/W bit should be 1 for read
1.176 + IdleI2C(); // ensure module is idle
1.177 + getsI2C( rdptr, length ); // read in multiple bytes
1.178 + NotAckI2C(); // send not ACK condition
1.179 + while ( SSPCON2bits.ACKEN ); // wait until ACK sequence is over
1.180 + StopI2C(); // send STOP condition
1.181 + while ( SSPCON2bits.PEN ); // wait until stop condition is over
1.182 + return ( 0 ); // return with no error
1.183 +}
1.184 +*/
1.185 +
1.186 +
1.187 +/********************************************************************
1.188 +* Function Name: putstringI2C *
1.189 +* Return Value: error condition status *
1.190 +* Parameters: address of write string storage location *
1.191 +* Description: This routine writes a string to the I2C bus,*
1.192 +* until a null character is reached. If Master*
1.193 +* function putcI2C is called. When trans- *
1.194 +* mission is complete then test for ack- *
1.195 +* nowledge bit. If Slave transmitter wait for *
1.196 +* null character or not ACK received from bus *
1.197 +* device. *
1.198 +********************************************************************/
1.199 +
1.200 +unsigned char putstringI2C( unsigned char *wrptr )
1.201 +{
1.202 +
1.203 +unsigned char x;
1.204 + for (x = 0; x < PageSize; x++ ) // transmit data until PageSize
1.205 + {
1.206 + if ( SSPCON1bits.SSPM3 ) // if Master transmitter then execute the following
1.207 + {
1.208 + if ( putcI2C ( *wrptr ) ) // write 1 byte
1.209 + {
1.210 + return ( -3 ); // return with write collision error
1.211 + }
1.212 + IdleI2C(); // test for idle condition
1.213 + if ( SSPCON2bits.ACKSTAT ) // test received ack bit state
1.214 + {
1.215 + return ( -2 ); // bus device responded with NOT ACK
1.216 + } // terminateputstringI2C() function
1.217 + }
1.218 + else // else Slave transmitter
1.219 + {
1.220 + PIR1bits.SSPIF = 0; // reset SSPIF bit
1.221 + SSPBUF = *wrptr; // load SSPBUF with new data
1.222 + SSPCON1bits.CKP = 1; // release clock line
1.223 + while ( !PIR1bits.SSPIF ); // wait until ninth clock pulse received
1.224 +
1.225 + if ( ( !SSPSTATbits.R_W ) && ( !SSPSTATbits.BF ) )// if R/W=0 and BF=0, NOT ACK was received
1.226 + {
1.227 + return ( -2 ); // terminateputstringI2C() function
1.228 + }
1.229 + }
1.230 + wrptr ++; // increment pointer
1.231 + } // continue data writes until null character
1.232 + return ( 0 );
1.233 +}
1.234 +
1.235 +
1.236 +
1.237 +