//------------------------------------------------------------------------------ // Writes a byte to I2C and checks acknowledge // returns 0 on success //------------------------------------------------------------------------------ i2cError_t i2cSoftWriteByte(uint8_t txByte) { uint8_t mask; i2cError_t err=0; for (mask = 0x80; mask > 0; mask >>= 1) //shift bit for masking (8 times) { if ((mask & txByte) == 0) { I2C_SDA_LO(); //write a bit to SDA-Line } else { I2C_SDA_HI(); } udelay(1); I2C_SCL_HI(); udelay(5); I2C_SCL_LO(); udelay(1); } I2C_SDA_IN(); //release SDA-line I2C_SCL_HI(); //clk #9 for ack udelay(5); if (I2C_SDA_GET() != 0) { err = I2C_ACK_ERROR; //check ack from i2c slave } I2C_SCL_LO(); udelay(5); //udelay(20); //delay to see the package on scope I2C_SDA_OUT(); return err; //return error code }
//------------------------------------------------------------------------------ // Reads a byte from I2C // Returns the byte received // note: timing (delay) may have to be changed for different microcontroller //------------------------------------------------------------------------------ uint8_t i2cSoftReadByte(i2cAck_t ack) { uint8_t mask, rxByte=0; I2C_SDA_IN(); //release SDA-line for (mask = 0x80; mask > 0; mask >>= 1) //shift bit for masking { I2C_SCL_HI(); //start clock on SCL-line udelay(4); if (I2C_SDA_GET() != 0) { rxByte = (rxByte | mask); //read bit } I2C_SCL_LO(); udelay(1); //data hold time } if (ack) { I2C_SDA_LO(); //send acknowledge if necessary } else { I2C_SDA_HI(); } udelay(1); I2C_SCL_HI(); //clk #9 for ack udelay(5); I2C_SCL_LO(); I2C_SDA_IN(); //release SDA-line udelay(5); //udelay(20); //delay to see the package on scope return rxByte; //return received byte }
/* * Toggles in a single byte in master mode. * * Entry: SCL low, SDA any * Exit: SCL low, SDA low with ack set, high else * * Change SDA only when SCL is low! * Sample SDA short before setting SCL low! */ static uint8_t TwGet(GPIO_TWICB* icb, uint8_t ack) { uint8_t rc = 0; int i; /* SDA is input. */ I2C_SDA_HI(); NutMicroDelay (1 * icb->delay_unit); for (i = 0x80; i; i >>= 1) { NutMicroDelay (2 * icb->delay_unit); I2C_SCL_HI(); NutMicroDelay (2 * icb->delay_unit); while(I2C_SCL_GET() == 0) { /* Clock stretching*/ NutMicroDelay (2 * icb->delay_unit); } if (I2C_SDA_GET()) { rc |= i; } I2C_SCL_LO(); } if (ack) { /* Master sets acknowledge */ I2C_SDA_LO(); } NutMicroDelay (2 * icb->delay_unit); I2C_SCL_HI(); NutMicroDelay (2 * icb->delay_unit); I2C_SCL_LO(); NutMicroDelay (2 * icb->delay_unit); return rc; }
//------------------------------------------------------------------------------ //Initializes the ports for I2C //------------------------------------------------------------------------------ void i2cSoftInit(void) { I2C_SDA_OUT(); I2C_SCL_OUT(); I2C_SDA_LO(); I2C_SCL_LO(); I2C_SDA_HI(); I2C_SCL_HI(); }
/* * Rising edge on the data line while the clock line is high indicates * a stop condition. * * Entry: SCL low, SDA any * Exit: SCL high, SDA high */ static void TwStop(GPIO_TWICB* icb) { I2C_SDA_LO(); NutMicroDelay (icb->delay_unit); I2C_SCL_HI(); NutMicroDelay (2 * icb->delay_unit); I2C_SDA_HI(); NutMicroDelay (8 * icb->delay_unit); }
/* * Toggles out a single byte in master mode. * * Entry: SCL low, SDA any * Exit: SCL low, SDA high * * Change SDA only when SCL is low! * Sample SDA short before setting SCL low! */ static int TwPut(GPIO_TWICB* icb, uint8_t octet) { int i; for (i = 0x80; i; i >>= 1) { /* Set the data bit. */ if (octet & i) { I2C_SDA_HI(); } else { I2C_SDA_LO(); } /* Wait for data to stabilize. */ NutMicroDelay (2 * icb->delay_unit); /* Toggle the clock. */ I2C_SCL_HI(); NutMicroDelay (2 * icb->delay_unit); while(I2C_SCL_GET() == 0) { /* Clock stretching*/ NutMicroDelay (2 * icb->delay_unit); } I2C_SCL_LO(); } /* Release data line to receive the ACK bit. */ I2C_SDA_HI(); NutMicroDelay (2 * icb->delay_unit); I2C_SCL_HI(); NutMicroDelay (2 * icb->delay_unit); if (I2C_SDA_GET()) { i = -1; } else { i = 0; } I2C_SCL_LO(); NutMicroDelay (2 * icb->delay_unit); return i; }
//------------------------------------------- // Entry point for the application //------------------------------------------- void appMain(void) { #if 0 // no effect UCTL0 = SWRST; ME1 &= ~(URXE0 | UTXE0 | USPIE0); UCTL0 &= ~SWRST; UCTL1 = SWRST; ME2 &= ~(URXE1 | UTXE1 | USPIE1); UCTL1 &= ~SWRST; #endif #if 1 ADC12IE = 0; ADC12IFG = 0; ADC12CTL0 &= ~ENC; ADC12CTL0 &= ~REFON; ADC12CTL0 &= ~ADC12ON; DMA0CTL = 0; DMA1CTL = 0; #endif #if 0 pinAsData(1, 0); pinAsData(1, 1); pinAsData(1, 2); pinAsData(1, 3); pinAsData(1, 4); pinAsData(1, 5); pinAsData(1, 6); pinAsData(1, 7); // radio data indicate pinAsData(2, 0); // ADS interrupts (unused) pinAsData(2, 1); pinAsData(2, 2); pinAsData(2, 3); // SHT SDA + I2C soft SDA pinAsData(2, 4); // SHT SCL + I2C soft SCL pinAsData(2, 5); // sensors enable pinAsData(2, 6); pinAsData(2, 7); // uart0 rx pinAsData(3, 0); // SD card CS pinAsData(3, 1); pinAsData(3, 2); pinAsData(3, 3); pinAsData(3, 4); // uart0 hw tx pinAsData(3, 5); // uart0 hw rx pinAsData(3, 6); // uart1 hw tx pinAsData(3, 7); // uart1 hw tx pinAsData(4, 0); // radio data request pinAsData(4, 1); // radio rts pinAsData(4, 2); // radio config pinAsData(4, 3); // radio trx disable pinAsData(4, 4); // radio reset pinAsData(4, 5); // radio sleep // pinAsData(4, 6); // uart0 tx // pinAsData(4, 7); pinAsData(5, 0); pinAsData(5, 1); pinAsData(5, 2); pinAsData(5, 3); pinAsData(5, 4); // red LED pinAsData(5, 5); // green LED pinAsData(5, 6); // blue LED pinAsData(5, 7); pinAsData(6, 0); pinAsData(6, 1); pinAsData(6, 2); pinAsData(6, 3); pinAsData(6, 4); pinAsData(6, 5); pinAsData(6, 6); pinAsData(6, 7); #endif pinAsInput(1, 0); pinAsInput(1, 1); pinAsInput(1, 2); pinAsInput(1, 3); pinAsInput(1, 4); pinAsInput(1, 5); pinAsInput(1, 6); pinAsInput(1, 7); // radio data indicate pinAsInput(2, 0); // ADS interrupts (unused) pinAsInput(2, 1); pinAsInput(2, 2); pinAsInput(2, 3); // SHT SDA + I2C soft SDA // pinAsInput(2, 4); // SHT SCL + I2C soft SCL // pinAsInput(2, 5); // sensors enable pinAsInput(2, 6); pinAsInput(2, 7); // uart0 rx pinAsInput(3, 0); // SD card CS pinAsInput(3, 1); pinAsInput(3, 2); pinAsInput(3, 3); pinAsInput(3, 4); // uart0 hw tx pinAsInput(3, 5); // uart0 hw rx pinAsInput(3, 6); // uart1 hw tx pinAsInput(3, 7); // uart1 hw tx pinAsInput(4, 0); // radio data request pinAsInput(4, 1); // radio rts pinAsInput(4, 2); // radio config // pinAsInput(4, 3); // radio trx disable pinAsInput(4, 4); // radio reset // pinAsInput(4, 5); // radio sleep pinAsInput(4, 6); // uart0 tx pinAsInput(4, 7); pinAsInput(5, 0); pinAsInput(5, 1); pinAsInput(5, 2); pinAsInput(5, 3); // pinAsInput(5, 4); // red LED pinAsInput(5, 5); // green LED pinAsInput(5, 6); // blue LED pinAsInput(5, 7); pinAsInput(6, 0); pinAsInput(6, 1); pinAsInput(6, 2); pinAsInput(6, 3); pinAsInput(6, 4); pinAsInput(6, 5); pinAsInput(6, 6); pinAsInput(6, 7); // -- required for better efficiency // make sure I2C clock is high I2C_SCL_HI(); // make sure sensors are disabled pinClear(SM3_SENSORS_ENABLE_PORT, SM3_SENSORS_ENABLE_PIN); // -- while (1) { msleep(PAUSE); // sleep PAUSE seconds // PRINTF("%lu: hello world\n", (uint32_t) getJiffies()); ledToggle(); } }