diff --git a/avrrfm.c b/avrrfm.c index 163f748..9a0a9f8 100644 --- a/avrrfm.c +++ b/avrrfm.c @@ -35,6 +35,10 @@ #define MEASURE_INTS 8 #define LABEL_OFFSET 10 +#ifndef RECEIVER + #define RECEIVER 1 +#endif + /* 1 int = 8 seconds */ static volatile uint8_t ints = 0; @@ -67,14 +71,14 @@ // set radio CS and RST pin as output pin DDR_RFM |= (1 << PIN_RCS); DDR_RFM |= (1 << PIN_RRST); - + // set display CS, D/C and RST pin as output pin DDR_DISP |= (1 << PIN_DCS); DDR_DISP |= (1 << PIN_DDC); DDR_DISP |= (1 << PIN_DRST); // drive output pins high - PORT_RFM |= (1 << PIN_RCS); + PORT_RFM |= (1 << PIN_RCS); PORT_DISP |= (1 << PIN_DCS); PORT_DISP |= (1 << PIN_DDC); PORT_DISP |= (1 << PIN_DRST); @@ -150,33 +154,28 @@ } /** - * Reads the temperature from the senor and transmits it. + * Reads the temperature from the sensor and transmits it. */ static void transmitTemp(void) { - uint16_t temp = readTemp(); + uint16_t temp = readTSens(); uint8_t payload[] = {(temp >> 8), temp & 0x00ff}; transmitPayload(payload, sizeof (payload)); // printString("Transmitted\r\n"); } /** - * Receives the temperature and converts it to °C. + * Converts the raw temperature to °C and lets it float around the display. + * + * @param raw temperature */ -static void receiveTemp(void) { - // printString("Receiving... "); - uint8_t payload[2]; - receivePayload(payload, sizeof (payload)); - uint16_t raw = 0; - raw |= payload[0] << 8; - raw |= payload[1]; - - int16_t tempx10 = convertTemp(raw); +static void displayTemp(uint16_t raw) { + int16_t tempx10 = convertTSens(raw); div_t temp = div(tempx10, 10); static char buf[16]; - - // snprintf(buf, sizeof (buf), "%d.%d°C\r\n", temp.quot, abs(temp.rem)); - // printString(buf); - + + snprintf(buf, sizeof (buf), "%d.%d°C\r\n", temp.quot, abs(temp.rem)); + printString(buf); + const __flash Font *dejaVu = &dejaVuFont; if (width > 0) fillArea(xo, yo, width, dejaVu->height, 0xffff); snprintf(buf, sizeof (buf), "%4d.%d°", temp.quot, abs(temp.rem)); @@ -189,6 +188,37 @@ if (y > DISPLAY_HEIGHT - dejaVu->height) y = 0; } +/** + * Blocks until the raw temperature is received, then returns it. + * + * @return raw temp + */ +static uint16_t receiveTemp(void) { + // printString("Receiving... "); + uint8_t payload[2]; + receivePayload(payload, sizeof (payload)); + uint16_t raw = 0; + raw |= payload[0] << 8; + raw |= payload[1]; + + return raw; +} + +/** + * Reads and returns the raw temperature. + * + * @return raw temp + */ +static uint16_t readTemp(void) { + uint8_t payload[2]; + readPayload(payload, sizeof (payload)); + uint16_t raw = 0; + raw |= payload[0] << 8; + raw |= payload[1]; + + return raw; +} + int main(void) { initUSART(); initPins(); @@ -202,23 +232,25 @@ printString("Hello Radio!\r\n"); - initRadio(868600); + initRadio(868600); initDisplay(); - + setFrame(0xffff); - - bool tx = false; + + if (RECEIVER) { + startReceive(); + } while (true) { - if (tx) { + if (! RECEIVER) { if (ints % MEASURE_INTS == 0) { ints = 0; enableSPI(); - wakeTemp(); + wakeTSens(); wakeRadio(); transmitTemp(); - sleepTemp(); + sleepTSens(); sleepRadio(); disableSPI(); } @@ -226,7 +258,22 @@ set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_mode(); } else { - receiveTemp(); + // uint16_t raw = receiveTemp(); + // displayTemp(raw); + + if (payloadReady()) { + uint16_t raw = readTemp(); + displayTemp(raw); + startReceive(); + } + + // do something else... + printString("Running...\r\n"); + _delay_ms(1000); + + // and/or go to sleep until next watchdog bark or payload received + set_sleep_mode(SLEEP_MODE_PWR_DOWN); + sleep_mode(); } } diff --git a/mcp9808.c b/mcp9808.c index 59db9c7..124ab63 100644 --- a/mcp9808.c +++ b/mcp9808.c @@ -50,13 +50,13 @@ return value; } -void sleepTemp(void) { +void sleepTSens(void) { uint16_t conf = regRead(MCP9808_CONF); conf |= (1 << 8); regWrite(MCP9808_CONF, conf); } -void wakeTemp(void) { +void wakeTSens(void) { uint16_t conf = regRead(MCP9808_CONF); conf &= ~(1 << 8); regWrite(MCP9808_CONF, conf); @@ -66,13 +66,13 @@ _delay_ms(300); } -uint16_t readTemp(void) { +uint16_t readTSens(void) { uint16_t raw = regRead(MCP9808_TEMP); return raw; } -int16_t convertTemp(uint16_t raw) { +int16_t convertTSens(uint16_t raw) { uint8_t upper = raw >> 8; uint8_t lower = raw & 0x00ff; diff --git a/mcp9808.h b/mcp9808.h index 6a374a0..0aac96d 100644 --- a/mcp9808.h +++ b/mcp9808.h @@ -18,26 +18,26 @@ /** * Shuts down the temperature sensor. */ -void sleepTemp(void); +void sleepTSens(void); /** * Wakes up the temperature sensor. */ -void wakeTemp(void); +void wakeTSens(void); /** * Reads the current raw temperature and returns it. * * @return temperature */ -uint16_t readTemp(void); +uint16_t readTSens(void); /** * Converts the given raw temperature and returns it in °C x 10. * * @return temperature x 10 */ -int16_t convertTemp(uint16_t raw); +int16_t convertTSens(uint16_t raw); #endif /* MCP9808_H */ diff --git a/rfm69.c b/rfm69.c index 2cb0c79..60b2822 100644 --- a/rfm69.c +++ b/rfm69.c @@ -167,15 +167,24 @@ _delay_ms(5); } -size_t receivePayload(uint8_t *payload, size_t size) { +void startReceive(void) { // get "PayloadReady" on DIO0 regWrite(DIO_MAP1, 0x40); setMode(MODE_RX); +} + +bool payloadReady(void) { + if (irqFlags2 & (1 << 2)) { + clearIrqFlags(); + + return true; + } - loop_until_bit_is_set(irqFlags2, 2); - clearIrqFlags(); - + return false; +} + +size_t readPayload(uint8_t *payload, size_t size) { setMode(MODE_STDBY); size_t len = min(regRead(FIFO), FIFO_SIZE) - 1; @@ -194,6 +203,15 @@ return len; } +size_t receivePayload(uint8_t *payload, size_t size) { + startReceive(); + + loop_until_bit_is_set(irqFlags2, 2); + clearIrqFlags(); + + return readPayload(payload, size); +} + size_t transmitPayload(uint8_t *payload, size_t size) { // payload + address byte size_t len = min(size, FIFO_SIZE) + 1; diff --git a/rfm69.h b/rfm69.h index 1f8ef7d..6313909 100644 --- a/rfm69.h +++ b/rfm69.h @@ -77,7 +77,30 @@ void wakeRadio(void); /** - * Waits for a packet, puts the payload into the given array with the + * Sets the radio to receive mode and maps "PayloadReady" to DIO0. + */ +void startReceive(void); + +/** + * Returns true if a "PayloadReady" interrupt arrived and clears the + * interrupt state. + * + * @return true if "PayloadReady" + */ +bool payloadReady(void); + +/** + * Sets the radio in standby mode, puts the payload into the given array + * with the given size, and returns the length of the payload. + * + * @param payload + * @param size + * @return actual length of the payload + */ +size_t readPayload(uint8_t *payload, size_t size); + +/** + * Waits for "PayloadReady", puts the payload into the given array with the * given size, and returns the length of the payload. * * @param payload buffer for payload