pic_therm

PIC16F877A and BME280 thermometer
git clone git://git.margiolis.net/pic_therm.git
Log | Files | Refs | README | LICENSE

i2c.c (904B)


      1 #include "extern.h"
      2 #include "i2c.h"
      3 
      4 #define I2C_SCL TRISCbits.TRISC3
      5 #define I2C_SDA TRISCbits.TRISC4
      6 
      7 void
      8 i2c_init(uint8_t mode, uint8_t slew, uint32_t freq)
      9 {
     10 	I2C_SCL = INPUT;
     11 	I2C_SDA = INPUT;
     12 	SSPCON = mode | 0x20; /* MCU as master */
     13 	SSPCON2 = 0;
     14 	SSPADD = (_XTAL_FREQ / (4 * freq)) - 1; /* Bus clock speed */
     15 	SSPSTAT &= 0x3f;
     16 	SSPSTAT = slew;
     17 }
     18 
     19 void
     20 i2c_hold(void)
     21 {
     22 	while ((SSPSTATbits.R_W) || (SSPCON2 & 0x1f))
     23 		;	/* nothing */
     24 }
     25 
     26 void
     27 i2c_start(void)
     28 {
     29 	i2c_hold();
     30 	SSPCON2bits.SEN = 1;
     31 }
     32 
     33 void
     34 i2c_stop(void)
     35 {
     36 	i2c_hold();
     37 	SSPCON2bits.PEN = 1;
     38 }
     39 
     40 void
     41 i2c_restart(void)
     42 {
     43 	i2c_hold();
     44 	SSPCON2bits.RSEN = 1;
     45 }
     46 
     47 void
     48 i2c_write(uint8_t c)
     49 {
     50 	SSPBUF = c;
     51 	i2c_hold();
     52 }
     53 
     54 uint8_t
     55 i2c_read(uint8_t ack)
     56 {
     57 	uint8_t c;
     58 
     59 	SSPCON2bits.RCEN = 1;
     60 	while (SSPSTATbits.BF == 0)
     61 		;	/* nothing */
     62 	c = SSPBUF;
     63 	i2c_hold();
     64 	SSPCON2bits.ACKDT = ack ? 0 : 1;
     65 	SSPCON2bits.ACKEN = 1;
     66 	return (c);
     67 }