123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- /*********************************************************************
- *
- * i2c master library for Fraise pic18f device
- *********************************************************************
- * Author Date Comment
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * Antoine Rousseau october 2013 adapted from Vangelis Rokas's sdcc i2c lib.
- ********************************************************************/
- /*
- # This program is free software; you can redistribute it and/or
- # modify it under the terms of the GNU General Public License
- # as published by the Free Software Foundation; either version 2
- # of the License, or (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- # MA 02110-1301, USA.
- */
- #include <core.h>
- #include <i2c_master.h>
- #ifndef I2CMASTER_PORT
- #define I2CMASTER_PORT 1
- #endif
- #if I2CMASTER_PORT==1
- #define SSPxBUF SSPBUF
- #define SSPxCON1 SSPCON1
- #define SSPxCON1bits SSPCON1bits
- #define SSPxCON2 SSPCON2
- #define SSPxCON2bits SSPCON2bits
- #define SSPxCON3 SSPCON3
- #define SSPxCON3bits SSPCON3bits
- #define SSPxSTAT SSPSTAT
- #define SSPxSTATbits SSPSTATbits
- #define SSPxMSK SSPMSK
- #define SSPxMSKbits SSPMSKbits
- #define SSPxADD SSPADD
- #define SSPxADDbits SSPADDbits
- #define SSPxIF PIR1bits.SSPIF
- #define SSPxIE PIE1bits.SSPIE
- #define SSPxIP PIR1bits.SSPIP
- #define BCLxIF PIR2bits.BCLIF
- /*#define SSPxBUF SSP1BUF
- #define SSPxCON1 SSP1CON1
- #define SSPxCON1bits SSP1CON1bits
- #define SSPxCON2 SSP1CON2
- #define SSPxCON2bits SSP1CON2bits
- #define SSPxCON3 SSP1CON3
- #define SSPxCON3bits SSP1CON3bits
- #define SSPxSTAT SSP1STAT
- #define SSPxSTATbits SSP1STATbits
- #define SSPxMSK SSP1MSK
- #define SSPxMSKbits SSP1MSKbits
- #define SSPxADD SSP1ADD
- #define SSPxADDbits SSP1ADDbits
- #define SSPxIF PIR1bits.SSP1IF
- #define SSPxIE PIE1bits.SSP1IE
- #define SSPxIP PIR1bits.SSP1IP
- #define BCLxIF PIR2bits.BCL1IF*/
- #else
- #define SSPxBUF SSP2BUF
- #define SSPxCON1 SSP2CON1
- #define SSPxCON1bits SSP2CON1bits
- #define SSPxCON2 SSP2CON2
- #define SSPxCON2bits SSP2CON2bits
- #define SSPxCON3 SSP2CON3
- #define SSPxCON3bits SSP2CON3bits
- #define SSPxSTAT SSP2STAT
- #define SSPxSTATbits SSP2STATbits
- #define SSPxMSK SSP2MSK
- #define SSPxMSKbits SSP2MSKbits
- #define SSPxADD SSP2ADD
- #define SSPxADDbits SSP2ADDbits
- #define SSPxIF PIR3bits.SSP2IF
- #define SSPxIE PIE3bits.SSP2IE
- #define SSPxIP PIR3bits.SSP2IP
- #define BCLxIF PIR3bits.BCL2IF
- #endif
- /*#ifndef SSP1CON1
- #define SSPxBUF SSPBUF
- #define SSPxCON1 SSPCON1
- #define SSPxCON1bits SSPCON1bits
- #define SSPxCON2 SSPCON2
- #define SSPxCON2bits SSPCON2bits
- #define SSPxCON3 SSPCON3
- #define SSPxCON3bits SSPCON3bits
- #define SSPxSTAT SSPSTAT
- #define SSPxSTATbits SSPSTATbits
- #define SSPxMSK SSPMSK
- #define SSPxMSKbits SSPMSKbits
- #define SSPxADD SSPADD
- #define SSPxADDbits SSPADDbits
- #define SSPxIF PIR1bits.SSPIF
- #define SSPxIE PIE1bits.SSPIE
- #define SSPxIP PIR1bits.SSPIP
- #define BCLxIF PIR2bits.BCLIF
- #endif*/
- void i2cm_init(unsigned char mode, unsigned char slew, unsigned char addr_brd)
- {
- SSPxSTAT &= 0x3f;
- SSPxCON1 = 0;
- SSPxCON2 = 0;
- SSPxCON1 |= mode;
- SSPxSTAT |= slew;
- #if I2CMASTER_PORT==1
- SetPinDigiIn(I2C1SDA);
- SetPinDigiIn(I2C1SCL);
- SetPinAnsel(I2C1SDA,0);
- SetPinAnsel(I2C1SCL,0);
- #else
- SetPinDigiIn(I2C2SDA);
- SetPinDigiIn(I2C2SCL);
- SetPinAnsel(I2C2SDA,0);
- SetPinAnsel(I2C2SCL,0);
- #endif
- SSPxADD = addr_brd;
- SSPxCON1 |= 0x20; // enable SSP
-
- SSPxIF = 0; // MSSP Interrupt Flag
- BCLxIF = 0; // Bus Collision Interrupt Flag
- }
- void i2cm_close(void)
- {
- SSPxCON1 &= 0xdf;
- }
- /*--------------------------------------*/
- unsigned char i2cm_drdy(void)
- {
- if(SSPxSTATbits.BF) return (+1);
- else return (0);
- }
- void i2cm_idle(void)
- {
- while((SSPxCON2 & 0x1f) | (SSPxSTATbits.R_W));
- }
- void i2cm_start(void)
- {
- i2cm_idle();
- SSPxCON2bits.SEN = 1;
- while (SSPxCON2bits.SEN);
- }
- void i2cm_restart(void)
- {
- i2cm_idle();
- SSPxCON2bits.RSEN = 1;
- while (SSPxCON2bits.RSEN);
- }
- void i2cm_stop(void)
- {
- i2cm_idle();
- SSPxCON2bits.PEN = 1;
- while (SSPxCON2bits.PEN);
- }
- void i2cm_ack(void)
- {
- i2cm_idle();
- SSPxIF = 0;
- SSPxCON2bits.ACKDT = 0;
- SSPxCON2bits.ACKEN = 1;
- while (!SSPxIF);
- }
- void i2cm_nack(void)
- {
- i2cm_idle();
- SSPxIF = 0;
- SSPxCON2bits.ACKDT = 1;
- SSPxCON2bits.ACKEN = 1;
- while (!SSPxIF);
- }
- /*--------------------------------------*/
- unsigned char i2cm_readchar(void)
- {
- i2cm_idle();
- SSPxCON2bits.RCEN = 1;
- while( !i2cm_drdy() );
- return ( SSPxBUF );
- }
- char i2cm_readstr(_I2CPARAM_SPEC unsigned char *ptr, unsigned char len)
- {
- unsigned char count=0;
-
- while( len-- ) {
- *ptr++ = i2cm_readchar();
-
- while(SSPxCON2bits.RCEN) {
- if(BCLxIF)return (-1);
- count++;
-
- if(len) {
- i2cm_ack();
- while(SSPxCON2bits.ACKEN);
- }
- }
- }
-
- return count;
- }
- char i2cm_writechar(unsigned char dat)
- {
- SSPxCON1bits.WCOL = 0;
- SSPxBUF = dat;
- if( SSPxCON1bits.WCOL ) {
- return -1;
- } else {
- i2cm_idle();
- return 0;
- }
- }
- char i2cm_writestr(unsigned char *ptr)
- {
- while( *ptr ) {
- if( SSPxCON1bits.SSPM3 ) {
- if(i2cm_writechar( *ptr )) {
- return (-3);
- }
- i2cm_idle();
- if( SSPxCON2bits.ACKSTAT ) {
- return (-2);
- }
- } else {
- SSPxIF = 0;
- SSPxBUF = *ptr;
- SSPxCON1bits.CKP = 1;
- while( !SSPxIF );
-
- if((!SSPxSTATbits.R_W) && ( !SSPxSTATbits.BF )) {
- return (-2);
- }
- }
-
- ptr++;
- }
- return 0;
- }
- /*--------------------------------------*/
- void i2cm_begin(unsigned char address, unsigned char doread)
- {
- i2cm_start();
- i2cm_writechar( (address<<1) | (doread != 0) );
- }
|