Skip to content

Commit

Permalink
Handle starting/ending reads/writes to I2C
Browse files Browse the repository at this point in the history
  • Loading branch information
mdclyburn committed Aug 5, 2020
1 parent 99ccc14 commit a79f0e5
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 21 deletions.
52 changes: 38 additions & 14 deletions src/usci-i2c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,26 @@ namespace mardev::msp430::usci::i2c
{
namespace usci = mardev::msp430::usci;

void __send_signal(const uint8_t signal_mask)
{
*usci::registers::UCB0CTL1 |= signal_mask;
while(*usci::registers::UCB0CTL1 & signal_mask);

return;
}

void read_begin()
bool read_begin()
{
// Set receive mode and generate the start condition.
*usci::registers::UCB0CTL1 ^= registers::masks::UCTR;
start();
__start();

return;
// Wait to be ACKed or NACKed.
while(*usci::registers::UCB0CTL1 & registers::masks::UCTXSTT);

// Read starts without any other intervention.
// Checking UCTXNACK will discern an issue with communication.
if(*usci::registers::UCB0STAT ^ registers::masks::UCNACKIFG)
{
return true;
}
else
{
__stop();
return false;
}
}

uint8_t read()
Expand All @@ -27,12 +33,30 @@ namespace mardev::msp430::usci::i2c
return *usci::registers::UCB0RXBUF;
}

void write_begin()
uint8_t read_end()
{
__stop();
return *usci::registers::UCB0RXBUF;
}

bool write_begin()
{
// Set transmit mode and generate the start condition.
*usci::registers::UCB0CTL1 |= registers::masks::UCTR;
start();
__start();

return;
// Wait to be ACKed or NACKed.
while(*usci::registers::UCB0CTL1 & registers::masks::UCTXSTT);

if(*interrupt::registers::IFG2 & usci::registers::masks::UCB0TXIFG)
{
return true;
}
else
{
__stop();
return false;
}
}

void write(const uint8_t data)
Expand Down
33 changes: 26 additions & 7 deletions src/usci-i2c.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,15 @@ namespace mardev::msp430::usci::i2c
*registers::UCB0I2CSA = address;
}

void __send_signal(const uint8_t signal_mask);
inline void __send_signal(const uint8_t signal_mask) { *usci::registers::UCB0CTL1 |= signal_mask; }

inline void __nack() { __send_signal(registers::masks::UCTXNACK); }

inline void stop() { __send_signal(registers::masks::UCTXSTP); }
/** Issue a stop condition.
*/
inline void __stop() { __send_signal(registers::masks::UCTXSTP); }

inline void start() { __send_signal(registers::masks::UCTXSTT); }
inline void __start() { __send_signal(registers::masks::UCTXSTT); }

/** Returns true if the I2C clock signal is held low.
*/
Expand Down Expand Up @@ -161,9 +163,12 @@ namespace mardev::msp430::usci::i2c

/** Start a read from a peripheral.
*
* The peripheral address needs to be set with set_periph_address() or set_periph_address10() before calling this function.
* The peripheral address needs to be set prior.
* See set_periph_address() or set_periph_address10().
*
* \returns True if reception is ready to begin.
*/
void read_begin();
bool read_begin();

/** Read a byte from the peripheral.
*
Expand All @@ -174,18 +179,32 @@ namespace mardev::msp430::usci::i2c
*/
uint8_t read();

/** End a read from a peripheral.
*
* Generates a stop condition to end a read.
* \returns The last byte read from the peripheral.
*/
uint8_t read_end();

/** Start a write to a peripheral.
*
* The peripheral address needs to be set with set_periph_address() or set_periph_address10() before calling this function.
* The peripheral address needs to be set.
* See set_periph_address() and set_periph_address10().
*
* \returns True if transmission is ready to begin.
*/
void write_begin();
bool write_begin();

/** Write a byte to the peripheral.
*
* Synchronously writes a byte to the peripheral.
* A write must have been started with write_begin() before calling this function.
*/
void write(const uint8_t data);

/** End a write from a peripheral.
*/
inline void write_end() { __stop(); }
}

#endif

0 comments on commit a79f0e5

Please sign in to comment.