diff options
author | Daniel Friesel <derf@finalrewind.org> | 2018-07-17 09:48:54 +0200 |
---|---|---|
committer | Daniel Friesel <derf@finalrewind.org> | 2018-07-17 09:48:54 +0200 |
commit | 658ca283452c5944c55d9c751868eef6c6f34138 (patch) | |
tree | 153eeeeadd3bed45bbc2ba696c1d4075c212f206 | |
parent | c8482531fbaeb75aaa58d7273853d0d1b0914713 (diff) |
MSP430: Some idle waiting
-rw-r--r-- | src/arch/msp430fr5969lp/arch.cc | 2 | ||||
-rw-r--r-- | src/arch/msp430fr5969lp/driver/i2c.cc | 29 |
2 files changed, 25 insertions, 6 deletions
diff --git a/src/arch/msp430fr5969lp/arch.cc b/src/arch/msp430fr5969lp/arch.cc index 3016842..9ea49b7 100644 --- a/src/arch/msp430fr5969lp/arch.cc +++ b/src/arch/msp430fr5969lp/arch.cc @@ -79,6 +79,7 @@ void Arch::idle_loop(void) asm volatile("nop"); __bis_SR_register(LPM2_bits); asm volatile("nop"); + __dint(); #if defined(WITH_LOOP) if (run_loop) { loop(); @@ -97,6 +98,7 @@ void Arch::idle(void) asm volatile("nop"); __bis_SR_register(LPM2_bits); asm volatile("nop"); + __dint(); #ifdef WITH_WAKEUP wakeup(); #endif diff --git a/src/arch/msp430fr5969lp/driver/i2c.cc b/src/arch/msp430fr5969lp/driver/i2c.cc index 5f1f4c1..fffc28c 100644 --- a/src/arch/msp430fr5969lp/driver/i2c.cc +++ b/src/arch/msp430fr5969lp/driver/i2c.cc @@ -1,6 +1,9 @@ #include "driver/i2c.h" +#include "arch.h" #include <msp430.h> +volatile unsigned short old_ifg = 0; + signed char I2C::setup() { UCB0CTL1 = UCSWRST; @@ -47,17 +50,25 @@ signed char I2C::xmit(unsigned char address, if (tx_len) { UCB0CTL1 |= UCTR | UCTXSTT; for (i = 0; i < tx_len; i++) { - while (!(UCB0IFG & (UCTXIFG0 | UCNACKIFG | UCCLTOIFG))); - if (UCB0IFG & (UCNACKIFG | UCCLTOIFG)) { - UCB0IFG &= ~UCNACKIFG; - UCB0IFG &= ~UCCLTOIFG; + UCB0IFG = 0; + old_ifg = 0; + UCB0IE = UCTXIE0 | UCNACKIE | UCCLTOIE; + while (!(old_ifg & (UCTXIFG0 | UCNACKIFG | UCCLTOIFG))) { + arch.idle(); + } + UCB0IE = 0; + if (old_ifg & (UCNACKIFG | UCCLTOIFG)) { UCB0CTL1 |= UCTXSTP; return -1; } + old_ifg = 0; UCB0TXBUF = tx_buf[i]; } - while (!(UCB0IFG & (UCTXIFG0 | UCNACKIFG | UCCLTOIFG))); - UCB0IFG &= ~(UCTXIFG0 | UCNACKIFG); + UCB0IE = UCTXIE0 | UCNACKIE | UCCLTOIE; + while (!(old_ifg & (UCTXIFG0 | UCNACKIFG | UCCLTOIFG))) { + arch.idle(); + } + UCB0IE = 0; //if (UCB0IFG & (UCNACKIFG | UCCLTOIFG)) { // UCB0IFG &= ~UCNACKIFG; // UCB0IFG &= ~UCCLTOIFG; @@ -90,4 +101,10 @@ signed char I2C::xmit(unsigned char address, return 0; } +__attribute__((interrupt(USCI_B0_VECTOR))) __attribute__((wakeup)) void handle_usci_b0() +{ + old_ifg = UCB0IFG; + UCB0IFG = 0; +} + I2C i2c; |