firmware/myi2c.c
author root@rika
Thu, 23 Apr 2009 19:10:12 +0200
changeset 30 7fd00015f62f
parent 2 2f55e5dd591d
permissions -rw-r--r--
several changes..
slime@2
     1
/*
slime@2
     2
 * Project Frontplatte
slime@2
     3
 *
slime@2
     4
 * myi2c.c  -  I2C-Bus Commands
slime@2
     5
 *
slime@2
     6
 * This file is released under the GNU General Public License. Refer
slime@2
     7
 * to the COPYING file distributed with this package.
slime@2
     8
 *
slime@2
     9
 * (c) 2007 Carsten Presser cpresser AT fsing.uni-sb.de
slime@2
    10
 *  most parts are taken from AN991 by microchip
slime@2
    11
 */
slime@2
    12
slime@2
    13
#include <p18cxxx.h>
slime@2
    14
#include "myi2c.h"
slime@2
    15
#include <i2c.h>
slime@2
    16
slime@2
    17
slime@2
    18
unsigned int PageSize;
slime@2
    19
slime@2
    20
slime@2
    21
unsigned char LDByteWriteI2C( unsigned char ControlByte, unsigned char LowAdd, unsigned char data )
slime@2
    22
{
slime@2
    23
  IdleI2C();                          // ensure module is idle
slime@2
    24
  StartI2C();                         // initiate START condition
slime@2
    25
  while ( SSPCON2bits.SEN );          // wait until start condition is over 
slime@2
    26
  WriteI2C( ControlByte );            // write 1 byte - R/W bit should be 0
slime@2
    27
  IdleI2C();                          // ensure module is idle
slime@2
    28
  WriteI2C( LowAdd );                 // write address byte to EEPROM
slime@2
    29
  IdleI2C();                          // ensure module is idle
slime@2
    30
  WriteI2C ( data );                  // Write data byte to EEPROM
slime@2
    31
  IdleI2C();                          // ensure module is idle
slime@2
    32
  StopI2C();                          // send STOP condition
slime@2
    33
  while ( SSPCON2bits.PEN );          // wait until stop condition is over 
slime@2
    34
  while (EEAckPolling(ControlByte));  //Wait for write cycle to complete
slime@2
    35
  return ( 0 );                       // return with no error
slime@2
    36
}
slime@2
    37
slime@2
    38
slime@2
    39
unsigned char LDByteReadI2C(unsigned char ControlByte)
slime@2
    40
{
slime@2
    41
  unsigned char data;
slime@2
    42
  IdleI2C();                      // ensure module is idle
slime@2
    43
  StartI2C();                     // initiate START condition
slime@2
    44
  while ( SSPCON2bits.SEN );      // wait until start condition is over 
slime@2
    45
  WriteI2C( ControlByte | 0x01 ); // WRITE 1 byte - R/W bit should be 1 for read
slime@2
    46
  IdleI2C();                      // ensure module is idle
slime@2
    47
  data = ReadI2C();
slime@2
    48
  IdleI2C();                      // ensure module is idle
slime@2
    49
  NotAckI2C();                       // send not ACK condition
slime@2
    50
  while ( SSPCON2bits.ACKEN );    // wait until ACK sequence is over 
slime@2
    51
  StopI2C();                      // send STOP condition
slime@2
    52
  while ( SSPCON2bits.PEN );      // wait until stop condition is over 
slime@2
    53
  return ( data );                   // return with no error
slime@2
    54
}
slime@2
    55
slime@2
    56
slime@2
    57
slime@2
    58
unsigned char LDPageReadI2C( unsigned char ControlByte, unsigned char address, unsigned char *data, unsigned char length )
slime@2
    59
{
slime@2
    60
  IdleI2C();                      // ensure module is idle
slime@2
    61
  StartI2C();                     // initiate START condition
slime@2
    62
  while ( SSPCON2bits.SEN );      // wait until start condition is over 
slime@2
    63
  WriteI2C( ControlByte );        // write 1 byte 
slime@2
    64
  IdleI2C();                      // ensure module is idle
slime@2
    65
  WriteI2C( address );            // WRITE word address to EEPROM
slime@2
    66
  IdleI2C();                      // ensure module is idle
slime@2
    67
  RestartI2C();                   // generate I2C bus restart condition
slime@2
    68
  while ( SSPCON2bits.RSEN );     // wait until re-start condition is over 
slime@2
    69
  WriteI2C( ControlByte | 0x01 ); // WRITE 1 byte - R/W bit should be 1 for read
slime@2
    70
  IdleI2C();                      // ensure module is idle
slime@2
    71
  getsI2C( data, length );        // read in multiple bytes
slime@2
    72
  NotAckI2C();                    // send not ACK condition
slime@2
    73
  while ( SSPCON2bits.ACKEN );    // wait until ACK sequence is over 
slime@2
    74
  StopI2C();                      // send STOP condition
slime@2
    75
  while ( SSPCON2bits.PEN );      // wait until stop condition is over 
slime@2
    76
  return ( 0 );                   // return with no error
slime@2
    77
slime@2
    78
}
slime@2
    79
slime@2
    80
unsigned char LDPageWriteI2C( unsigned char ControlByte, unsigned char LowAdd, unsigned char *wrptr, unsigned char length)
slime@2
    81
{
slime@2
    82
  PageSize = (int)length;
slime@2
    83
slime@2
    84
  IdleI2C();                      // ensure module is idle
slime@2
    85
  StartI2C();                     // initiate START condition
slime@2
    86
  while ( SSPCON2bits.SEN );      // wait until start condition is over 
slime@2
    87
  WriteI2C( ControlByte );        // write 1 byte - R/W bit should be 0
slime@2
    88
  IdleI2C();                      // ensure module is idle
slime@2
    89
  WriteI2C( LowAdd );             // write LowAdd byte to EEPROM
slime@2
    90
  IdleI2C();                      // ensure module is idle
slime@2
    91
  putstringI2C ( wrptr );         // pointer to data for page write
slime@2
    92
  IdleI2C();                      // ensure module is idle
slime@2
    93
  StopI2C();                      // send STOP condition
slime@2
    94
  while ( SSPCON2bits.PEN );      // wait until stop condition is over 
slime@2
    95
  return ( 0 );                   // return with no error
slime@2
    96
}
slime@2
    97
slime@2
    98
slime@2
    99
slime@2
   100
/*
slime@2
   101
unsigned char HDByteWriteI2C( unsigned char ControlByte, unsigned char HighAdd, unsigned char LowAdd, unsigned char data )
slime@2
   102
{
slime@2
   103
  IdleI2C();                      // ensure module is idle
slime@2
   104
  StartI2C();                     // initiate START condition
slime@2
   105
  while ( SSPCON2bits.SEN );      // wait until start condition is over 
slime@2
   106
  WriteI2C( ControlByte );        // write 1 byte - R/W bit should be 0
slime@2
   107
  IdleI2C();                      // ensure module is idle
slime@2
   108
  WriteI2C( HighAdd );            // write address byte to EEPROM
slime@2
   109
  IdleI2C();                      // ensure module is idle
slime@2
   110
  WriteI2C( LowAdd );             // write address byte to EEPROM
slime@2
   111
  IdleI2C();                      // ensure module is idle
slime@2
   112
  WriteI2C ( data );              // Write data byte to EEPROM
slime@2
   113
  IdleI2C();                      // ensure module is idle
slime@2
   114
  StopI2C();                      // send STOP condition
slime@2
   115
  while ( SSPCON2bits.PEN );      // wait until stop condition is over 
slime@2
   116
  while (EEAckPolling(ControlByte));  //Wait for write cycle to complete
slime@2
   117
  return ( 0 );                   // return with no error
slime@2
   118
}
slime@2
   119
unsigned char HDByteReadI2C( unsigned char ControlByte, unsigned char HighAdd, unsigned char LowAdd, unsigned char *data, unsigned char length )
slime@2
   120
{
slime@2
   121
  IdleI2C();                      // ensure module is idle
slime@2
   122
  StartI2C();                     // initiate START condition
slime@2
   123
  while ( SSPCON2bits.SEN );      // wait until start condition is over 
slime@2
   124
  WriteI2C( ControlByte );        // write 1 byte 
slime@2
   125
  IdleI2C();                      // ensure module is idle
slime@2
   126
  WriteI2C( HighAdd );            // WRITE word address to EEPROM
slime@2
   127
  IdleI2C();                      // ensure module is idle
slime@2
   128
  while ( SSPCON2bits.RSEN );     // wait until re-start condition is over 
slime@2
   129
  WriteI2C( LowAdd );             // WRITE word address to EEPROM
slime@2
   130
  IdleI2C();                      // ensure module is idle
slime@2
   131
  RestartI2C();                   // generate I2C bus restart condition
slime@2
   132
  while ( SSPCON2bits.RSEN );     // wait until re-start condition is over 
slime@2
   133
  WriteI2C( ControlByte | 0x01 ); // WRITE 1 byte - R/W bit should be 1 for read
slime@2
   134
  IdleI2C();                      // ensure module is idle
slime@2
   135
  getsI2C( data, length );       // read in multiple bytes
slime@2
   136
  NotAckI2C();                    // send not ACK condition
slime@2
   137
  while ( SSPCON2bits.ACKEN );    // wait until ACK sequence is over 
slime@2
   138
  StopI2C();                      // send STOP condition
slime@2
   139
  while ( SSPCON2bits.PEN );      // wait until stop condition is over 
slime@2
   140
  return ( 0 );                   // return with no error
slime@2
   141
}
slime@2
   142
unsigned char HDPageWriteI2C( unsigned char ControlByte, unsigned char HighAdd, unsigned char LowAdd, unsigned char *wrptr )
slime@2
   143
{
slime@2
   144
  IdleI2C();                      // ensure module is idle
slime@2
   145
  StartI2C();                     // initiate START condition
slime@2
   146
  while ( SSPCON2bits.SEN );      // wait until start condition is over 
slime@2
   147
  WriteI2C( ControlByte );        // write 1 byte - R/W bit should be 0
slime@2
   148
  IdleI2C();                      // ensure module is idle
slime@2
   149
  WriteI2C( HighAdd );            // write HighAdd byte to EEPROM 
slime@2
   150
  IdleI2C();                      // ensure module is idle
slime@2
   151
  WriteI2C( LowAdd );             // write LowAdd byte to EEPROM
slime@2
   152
  IdleI2C();                      // ensure module is idle
slime@2
   153
  putstringI2C ( wrptr );         // pointer to data for page write
slime@2
   154
  IdleI2C();                      // ensure module is idle
slime@2
   155
  StopI2C();                      // send STOP condition
slime@2
   156
  while ( SSPCON2bits.PEN );      // wait until stop condition is over 
slime@2
   157
  return ( 0 );                   // return with no error
slime@2
   158
}
slime@2
   159
unsigned char HDSequentialReadI2C( unsigned char ControlByte, unsigned char HighAdd, unsigned char LowAdd, unsigned char *rdptr, unsigned char length )
slime@2
   160
{
slime@2
   161
  IdleI2C();                      // ensure module is idle
slime@2
   162
  StartI2C();                     // initiate START condition
slime@2
   163
  while ( SSPCON2bits.SEN );      // wait until start condition is over 
slime@2
   164
  WriteI2C( ControlByte );        // write 1 byte 
slime@2
   165
  IdleI2C();                      // ensure module is idle
slime@2
   166
  WriteI2C( HighAdd );            // WRITE word address to EEPROM
slime@2
   167
  IdleI2C();                      // ensure module is idle
slime@2
   168
  WriteI2C( LowAdd );             // write HighAdd byte to EEPROM
slime@2
   169
  IdleI2C();                      // ensure module is idle
slime@2
   170
  RestartI2C();                   // generate I2C bus restart condition
slime@2
   171
  while ( SSPCON2bits.RSEN );     // wait until re-start condition is over 
slime@2
   172
  WriteI2C( ControlByte | 0x01 ); // WRITE 1 byte - R/W bit should be 1 for read
slime@2
   173
  IdleI2C();                      // ensure module is idle
slime@2
   174
  getsI2C( rdptr, length );       // read in multiple bytes
slime@2
   175
  NotAckI2C();                    // send not ACK condition
slime@2
   176
  while ( SSPCON2bits.ACKEN );    // wait until ACK sequence is over 
slime@2
   177
  StopI2C();                      // send STOP condition
slime@2
   178
  while ( SSPCON2bits.PEN );      // wait until stop condition is over 
slime@2
   179
  return ( 0 );                   // return with no error
slime@2
   180
}
slime@2
   181
*/
slime@2
   182
slime@2
   183
slime@2
   184
/********************************************************************
slime@2
   185
*     Function Name:    putstringI2C                                *
slime@2
   186
*     Return Value:     error condition status                      *
slime@2
   187
*     Parameters:       address of write string storage location    *
slime@2
   188
*     Description:      This routine writes a string to the I2C bus,*
slime@2
   189
*                       until a null character is reached. If Master*
slime@2
   190
*                       function putcI2C is called. When trans-     *
slime@2
   191
*                       mission is complete then test for ack-      *
slime@2
   192
*                       nowledge bit. If Slave transmitter wait for *
slime@2
   193
*                       null character or not ACK received from bus *
slime@2
   194
*                       device.                                     *
slime@2
   195
********************************************************************/
slime@2
   196
slime@2
   197
unsigned char putstringI2C( unsigned char *wrptr )
slime@2
   198
{
slime@2
   199
slime@2
   200
unsigned char x;
slime@2
   201
  for (x = 0; x < PageSize; x++ ) // transmit data until PageSize  
slime@2
   202
  {
slime@2
   203
    if ( SSPCON1bits.SSPM3 )      // if Master transmitter then execute the following
slime@2
   204
    {
slime@2
   205
      if ( putcI2C ( *wrptr ) )   // write 1 byte
slime@2
   206
      {
slime@2
   207
        return ( -3 );            // return with write collision error
slime@2
   208
      }
slime@2
   209
      IdleI2C();                  // test for idle condition
slime@2
   210
      if ( SSPCON2bits.ACKSTAT )  // test received ack bit state
slime@2
   211
      {
slime@2
   212
        return ( -2 );            // bus device responded with  NOT ACK
slime@2
   213
      }                           // terminateputstringI2C() function
slime@2
   214
    }
slime@2
   215
    else                          // else Slave transmitter
slime@2
   216
    {
slime@2
   217
      PIR1bits.SSPIF = 0;         // reset SSPIF bit
slime@2
   218
      SSPBUF = *wrptr;            // load SSPBUF with new data
slime@2
   219
      SSPCON1bits.CKP = 1;        // release clock line 
slime@2
   220
      while ( !PIR1bits.SSPIF );  // wait until ninth clock pulse received
slime@2
   221
slime@2
   222
      if ( ( !SSPSTATbits.R_W ) && ( !SSPSTATbits.BF ) )// if R/W=0 and BF=0, NOT ACK was received
slime@2
   223
      {
slime@2
   224
        return ( -2 );            // terminateputstringI2C() function
slime@2
   225
      }
slime@2
   226
    }
slime@2
   227
  wrptr ++;                       // increment pointer
slime@2
   228
  }                               // continue data writes until null character
slime@2
   229
  return ( 0 );
slime@2
   230
}
slime@2
   231
slime@2
   232
slime@2
   233
slime@2
   234