Skip to content
Browse files

Support sending new configs to the fridge controller.

Based on the new lib_mrf24j code.
  • Loading branch information...
1 parent 82e509f commit f3b9189d9bd149edb0a6b13663044137ec8e9baa @karlp committed May 29, 2011
View
11 common/karlnet.h
@@ -49,7 +49,18 @@ typedef struct _kpacket2 {
#define NTC_10K_3V3 'a'
// flag for binary state sensors (off/on)
#define KPS_RELAY_STATE 'b'
+#define KPS_COMMAND 'c'
+#define KPS_COMMAND_ARG 'd'
#define KPS_SENSOR_TEST 'z'
+// All possible commands
+#define KPS_COMMAND_REPORTING_INTERVAL 1
+#define KPS_COMMAND_THRESHOLD_TEMP 2
+#define KPS_COMMAND_MIN_ON_TIME 3
+#define KPS_COMMAND_MIN_OFF_TIME 4
+#define KPS_COMMAND_SET_COLLECTOR 5
+
+
+
#endif
View
3 nodes/fridge_controller/Makefile
@@ -48,7 +48,8 @@ KARLNET_COMMON = ../../common
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
- $(KARLNET_COMMON)/lib_mrf24j.c
+ $(KARLNET_COMMON)/lib_mrf24j.c \
+# $(KARLNET_COMMON)/pjrc/usb_debug_only.c
# MCU name, you MUST set this to match the board you are using
# type "make clean" after changing this, so all files will be rebuilt
View
290 nodes/fridge_controller/fridge_controller.c
@@ -2,6 +2,7 @@
//
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
@@ -12,20 +13,66 @@
#include "lib_mrf24j.h"
#include "karlnet.h"
+#define TINY84_HARDWARE
+#ifndef TINY84_HARDWARE
+#include "pjrc/usb_debug_only.h"
+#else
+#define printf(x,...)
+#endif
#define TICKS_PER_500MS 15625
+#if defined(TINY84_HARDWARE)
// USCK and DO pins are output
-#define SPI_CONFIG (DDRA |= (1<<PINA5) | (1<<PINA4))
-
-#define RELAY_ENABLE (DDRA |= (1<<PINA2))
-#define RELAY_OFF (PORTA &= ~(1<<PINA2))
-#define RELAY_ON (PORTA |= (1<<PINA2))
-
+#define SPI_DDR DDRA
+#define SPI_MOSI PINA5
+#define SPI_SCLK PINA4
+#define RELAY_PORT PORTA
+#define RELAY_DDR DDRA
+#define RELAY_PIN PINA2
#define MRF_DDR (DDRB)
#define MRF_PORT (PORTB)
#define MRF_PIN_RESET (PINB1)
#define MRF_PIN_CS (PINB0)
#define MRF_PIN_INT (PINB2)
+static inline void mrf_enable_interrupts(void) {
+ GIMSK |= _BV(INT0);
+}
+static inline void mrf_disable_interrupts(void) {
+ GIMSK &= ~(_BV(INT0));
+}
+
+#else
+// USCK and DO pins are output
+#define SPI_DDR DDRB
+#define SPI_MISO PINB3
+#define SPI_MOSI PINB2
+#define SPI_SCLK PINB1
+
+#define RELAY_PORT PORTD
+#define RELAY_DDR DDRD
+#define RELAY_PIN PIND6
+
+
+#define MRF_DDR DDRB
+#define MRF_PORT PORTB
+#define MRF_PIN_RESET PINB4
+#define MRF_PIN_CS PINB0 // This is also /SS
+
+static inline void mrf_disable_interrupts(void) {
+ EIMSK &= ~(_BV(INT0));
+}
+static inline void mrf_enable_interrupts(void) {
+ EIMSK |= _BV(INT0);
+}
+
+#endif
+
+
+#define RELAY_ENABLE (RELAY_DDR |= (1<<RELAY_PIN))
+#define RELAY_OFF (RELAY_PORT &= ~(1<<RELAY_PIN))
+#define RELAY_ON (RELAY_PORT |= (1<<RELAY_PIN))
+
+
typedef struct _config {
uint16_t threshold_value;
@@ -47,11 +94,33 @@ configt config_eeprom EEMEM = {
.rf_collector = 0x0001 // teensy receiver station
};
+configt config;
uint32_t flags;
-uint8_t rx_command_count;
// interval_report 1 ==> 2 secs
// interval report 4 ==> 8 secs
+
+// http://www.mail-archive.com/avr-gcc-list@nongnu.org/msg03104.html
+static inline uint32_t bswap_32_inline(uint32_t x)
+{
+ union {
+ uint32_t x;
+ struct {
+ uint8_t a;
+ uint8_t b;
+ uint8_t c;
+ uint8_t d;
+ } s;
+ } in, out;
+ in.x = x;
+ out.s.a = in.s.d;
+ out.s.b = in.s.c;
+ out.s.c = in.s.b;
+ out.s.d = in.s.a;
+ return out.x;
+}
+
+
void init_adc(void) {
// 1.1V aref, adc0.
ADMUX = (1<<REFS1);
@@ -87,102 +156,180 @@ float convert_raw(uint16_t raw) {
return tempC;
}
-void init(configt *config) {
- MRF_DDR = (1<<MRF_PIN_RESET) | (1<<MRF_PIN_CS);
- SPI_CONFIG;
+static void init_spi(void) {
+#if defined (SPCR)
+ /* Enable SPI, Master, set clock rate fck/4 */
+ SPCR = (1 << SPE) | (1 << MSTR);
+#endif
+ SPI_DDR |= (_BV(SPI_MOSI) | _BV(SPI_SCLK));
+}
- // interrupt pin from mrf, low level triggered
- //EIMSK |= (1<<INT0);
- GIMSK |= (1<<INT0);
+#ifndef TINY84_HARDWARE
+static int uart_putchar(char c, FILE* stream) {
+ return usb_debug_putchar(c);
+}
+static FILE mystdout = {0};
+#endif
+
+void init(configt *config) {
+#ifndef TINY84_HARDWARE
+ clock_prescale_set(clock_div_2); // we run at 3.3v
+ fdev_setup_stream(&mystdout, uart_putchar, NULL, _FDEV_SETUP_WRITE);
+ stdout = &mystdout;
+ usb_init();
+#endif
+
+ MRF_DDR |= (1<<MRF_PIN_RESET) | (1<<MRF_PIN_CS);
+ init_spi();
+ mrf_enable_interrupts();
RELAY_ENABLE;
init_adc();
init_slow_timer();
eeprom_read_block(config, &config_eeprom, sizeof(configt));
mrf_reset(&MRF_PORT, MRF_PIN_RESET);
- mrf_init();
+ mrf_init(&MRF_PORT, MRF_PIN_CS);
mrf_pan_write(config->rf_panid);
mrf_address16_write(config->rf_ourid);
+#ifndef TINY84_HARDWARE
+ while (!usb_configured()) {
+ }
+ _delay_ms(500);
+#endif
+ printf("We're awake!\n");
}
volatile uint16_t tick_reporting;
volatile uint32_t tick_motor;
+#if defined TINY84_HARDWARE
ISR(TIM1_COMPA_vect) {
+#else
+ISR(TIMER1_COMPA_vect) {
+ putchar('!');
+#endif
tick_reporting++;
tick_motor++;
// make sure it's working...
}
-volatile uint8_t gotrx;
-volatile uint8_t txok;
-volatile uint8_t last_interrupt;
-
ISR(INT0_vect) {
- // read and clear from the radio
- last_interrupt = mrf_read_short(MRF_INTSTAT);
- if (last_interrupt & MRF_I_RXIF) {
- gotrx = 1;
- }
- if (last_interrupt & MRF_I_TXNIF) {
- txok = 1;
- }
+ mrf_interrupt_handler();
}
inline uint8_t get_relay_state(void) {
- if (PORTA & (1<<PINA2)) {
+ if (RELAY_PORT & (_BV(RELAY_PIN))) {
return 1;
}
return 0;
}
-// TODO - FIXME
-int handle_network_traffic(configt *config) {
-
- gotrx = 0;
- cli();
- //print("Received a packet!\n\r");
- rx_command_count++;
- flags = rx_command_count;
-
- mrf_write_short(MRF_BBREG1, 0x04); // RXDECINV - disable receiver
-
- uint8_t frame_length = mrf_read_long(0x300); // read start of rxfifo for
- //phex(frame_length);
- //print("\r\nPacket data:\r\n");
- int fptr = 0x301;
-/*
- uint8_t b1 = mrf_read_long(fptr++);
- uint8_t b2 = mrf_read_long(fptr++);
- if (b1 == 'k' && b2 == 'k') {
- rx_command_count++;
- config->interval_report = mrf_read_long(fptr++);
- flags = (uint32_t)rx_command_count << 24 | (uint32_t)'k' << 16 | config->interval_report;
+void handle_rx(mrf_rx_info_t *rxinfo, uint8_t *rbuf) {
+ // we can assume it's for us, because we're in non-prom
+ // but we still need to decode the headers, before we get to the kpacket...
+ // or... be sneaky...
+ if (rxinfo->frame_type != MAC_FRAME_TYPE_DATA) {
+ printf("Ignorining non data frame\n");
+ return;
}
-*/
- // this should basically ignore the rest of the packet...
- // read the rest of the packet!!!
- int endptr = 0x300 + frame_length;
- for (;fptr <= endptr;) {
- uint8_t tmp = mrf_read_long(fptr++);
+ uint8_t i = 0;
+ uint16_t dest_pan = 0;
+ uint16_t dest_id = 0;
+ uint16_t src_id = 0;
+ if (rxinfo->dest_addr_mode == MAC_ADDRESS_MODE_16
+ && rxinfo->src_addr_mode == MAC_ADDRESS_MODE_16
+ && rxinfo->pan_compression) {
+ dest_pan = rbuf[i++];
+ dest_pan |= rbuf[i++] << 8;
+ dest_id = rbuf[i++];
+ dest_id |= rbuf[i++] << 8;
+ src_id = rbuf[i++];
+ src_id |= rbuf[i++] << 8;
+ // TODO Can't move this into the library without doing more decoding in the library...
+ i += 2; // as in the library, module seems to have two useless bytes after headers!
+ }
+ if (dest_id != config.rf_ourid) {
+ // unexpected, shouldn't ever happen
+ printf("ignoring packet actually meant for %x\n", dest_id);
+ return;
+ }
+ if (src_id != config.rf_collector) {
+ // Someone else is trying to tell us to do something!
+ printf("Ignoring orders from %x\n", src_id);
+ return;
}
- //print("\r\nLQI/RSSI=");
- uint8_t lqi = mrf_read_long(0x300 + frame_length + 1);
- uint8_t rssi = mrf_read_long(0x300 + frame_length + 2);
- //phex(lqi);
- //phex(rssi);
- mrf_write_short(MRF_BBREG1, 0x00); // RXDECINV - enable receiver
- sei();
+ kpacket2 rxkp;
+ memcpy(&rxkp, rbuf+i, sizeof(rxkp));
+ if (rxkp.header != 'x') {
+ printf("Dropping non kpacket\n");
+ return;
+ }
+ uint8_t version = rxkp.versionCount >> 4;
+ uint8_t count = rxkp.versionCount & 0x0f;
+ printf("\nRX Kpacket(v:%u, count:%u){\n", version, count);
+ for (int k = 0; k < count; k++) {
+ rxkp.ksensors[k].value = bswap_32_inline(rxkp.ksensors[k].value);
+ printf("\tSensor[t:%x(%c), v=%lx]\n", rxkp.ksensors[k].type,
+ rxkp.ksensors[k].type, rxkp.ksensors[k].value);
+ }
+ uint8_t changed = 0;
+ if (rxkp.ksensors[0].type == KPS_COMMAND && rxkp.ksensors[1].type == KPS_COMMAND_ARG) {
+ switch (rxkp.ksensors[0].value) {
+ case KPS_COMMAND_REPORTING_INTERVAL:
+ if (config.interval_report != rxkp.ksensors[1].value) {
+ printf("Updating reporting interval from %u to %lu and saving to eeprom\n",
+ config.interval_report, rxkp.ksensors[1].value);
+ config.interval_report = rxkp.ksensors[1].value;
+ changed = 1;
+ }
+ break;
+ case KPS_COMMAND_THRESHOLD_TEMP:
+ if (config.threshold_value != rxkp.ksensors[1].value) {
+ printf("Updating reporting temp threshold from %u to %lu and saving to eeprom\n",
+ config.threshold_value, rxkp.ksensors[1].value);
+ config.threshold_value = rxkp.ksensors[1].value;
+ changed = 1;
+ }
+ break;
+ case KPS_COMMAND_MIN_ON_TIME:
+ if (config.min_on_time != rxkp.ksensors[1].value) {
+ printf("Updating min on time from %u to %lu and saving to eeprom\n",
+ config.min_on_time, rxkp.ksensors[1].value);
+ config.min_on_time = rxkp.ksensors[1].value;
+ changed = 1;
+ }
+ break;
+ case KPS_COMMAND_MIN_OFF_TIME:
+ if (config.min_off_time != rxkp.ksensors[1].value) {
+ printf("Updating min off time from %u to %lu and saving to eeprom\n",
+ config.min_off_time, rxkp.ksensors[1].value);
+ config.min_off_time = rxkp.ksensors[1].value;
+ changed = 1;
+ }
+ break;
+ case KPS_COMMAND_SET_COLLECTOR:
+ if (config.rf_collector != rxkp.ksensors[1].value) {
+ printf("Updating rfcollector from %x to %lx and saving to eeprom\n",
+ config.rf_collector, rxkp.ksensors[1].value);
+ config.rf_collector = rxkp.ksensors[1].value;
+ changed = 1;
+ }
+ break;
+ }
+ } else {
+ printf("No command seen\n");
+ }
+
+ if (changed) {
+ eeprom_write_block(&config, &config_eeprom, sizeof(configt));
+ }
- return 0;
}
int main(void) {
- configt config;
init(&config);
- //mrf_write_short(MRF_RXMCR, 0x01); // promiscuous!
kpacket2 packet;
packet.header = 'x';
@@ -191,6 +338,8 @@ int main(void) {
sei();
while (1) {
+ mrf_check_flags(&handle_rx, NULL);
+
// Read temp
uint32_t currentValue = adc_read();
currentValue += adc_read();
@@ -199,22 +348,17 @@ int main(void) {
currentValue /= 4;
float temp = convert_raw(currentValue);
- // TODO - insert code here to listen to the mrf and update our config!!
-/*
- if (gotrx) {
- handle_network_traffic(&config);
- }
-*/
-
if (tick_reporting >= config.interval_report) {
+ printf("config.interval = %u\n", config.interval_report);
tick_reporting = 0;
ksensor s1 = {TMP36_VREF11, currentValue};
ksensor s2 = {KPS_RELAY_STATE, get_relay_state()};
ksensor s3 = {KPS_SENSOR_TEST, temp * 100};
packet.ksensors[0] = s1;
packet.ksensors[1] = s2;
packet.ksensors[2] = s3;
- mrf_send16(config.rf_collector, sizeof(kpacket2), &packet);
+ printf("txing...\n");
+ mrf_send16(config.rf_collector, sizeof(kpacket2), (char*)&packet);
}
// now, check the threshold. If we're above (too hot),
View
2 nodes/fridge_controller/nbproject/configurations.xml
@@ -21,8 +21,6 @@
<in>xbee-api.h</in>
</df>
<df name="fridge_controller" root=".">
- <df name=".dep">
- </df>
<in>fridge_controller.c</in>
</df>
<logicalFolder name="ExternalFiles"

0 comments on commit f3b9189

Please sign in to comment.
Something went wrong with that request. Please try again.