sonde/main.c
2016-04-29 11:30:56 +02:00

277 lines
4.6 KiB
C

#include <avr/io.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <avr/power.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <util/delay.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include "debug.h"
#include "analog.h"
//#include "dht11.h"
#include "rf24.h"
#include "lib/Hamming.h"
#include "crc8.h"
#include "onewire.h"
#define EE_Num 0
uint8_t ADDR[5]={0xE7,0xE7,0xE7,0xE7,0xE7}; //{0xE7,0xE7,0xE7,0xE7,0xE7}; //
#define PKTLEN 24
#define CMD_DATA 0x20
#define CMD_BIN 0x30
#ifdef DEBUG
char debugbuf[32];
uint16_t totaltime;
#endif
char buffer[18];
char* text = buffer +4;
uint8_t sendbuffer[24];
uint8_t id;
uint8_t pid=0;
volatile bool wdt_flag=false;
volatile bool pcint_flag=false;
ISR(WATCHDOG_vect){
wdt_flag=true;
}
ISR(PCINT0_vect){
pcint_flag = true;
}
void sleep(){
#ifdef DEBUG
uint16_t time = TCNT1;
totaltime +=time;
//debughex(&time,2);
#endif
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
cli();
sleep_enable();
//sleep_bod_disable();
sei();
sleep_cpu();
sleep_disable();
#ifdef DEBUG
TCCR1A =0;
TCCR1C =0;
TCNT1 = 0;
TCCR1B = 2;
#endif
}
void wait_for_next(){
int cnt=6;
#ifdef DEBUG
cnt=2;
#endif
while (cnt--){
wdt_enable(WDTO_8S);
WDTCSR |= _BV(WDIE);
sleep();
}
cnt = rand()%6;
while (cnt--){
wdt_enable(WDTO_1S);
WDTCSR |= _BV(WDIE);
sleep();
}
#ifdef DEBUG
debughex(&totaltime,2);
totaltime=0;
debug("\r");
#endif
}
void power_down(){
stopADC();
power_all_disable();
}
void wait_for_radio(){
wdt_enable(WDTO_120MS);
wdt_flag=false;
pcint_flag = false;
cli();
// Sleep until radio ready or wdt 60ms
while (bit_is_set(PINA,PA7) || (!wdt_flag) ){
WDTCSR |= _BV(WDIE);
sleep();
cli(); // disable interrupts before testing wdt_flag
}
// disable radio -> low power until next tx
rf24_powerDown();
if(!wdt_flag) // radio ok... wait until 60ms
{
WDTCSR |= _BV(WDIE); // reenable wdt interrupt
sleep();
}
return;
}
void setupRadio(){
// Static values in ram.
rf24_CONFIG = 0;
rf24_RF_CH = 90;
rf24_RF_SETUP = 0x26;
rf24_FEATURE = 0;//_BV(EN_DPL)|_BV(EN_ACK_PAY)|_BV(EN_DYN_ACK);
rf24_DYNPD = 0x00;
rf24_RX_PW[0]=PKTLEN;
rf24_RX_PW[1]=PKTLEN;
rf24_SETUP_RETR = 0x00;
rf24_EN_AA = 0x00;
}
void initRadio(){
power_usi_enable();
rf24_init();
rf24_writeRegister(RX_ADDR_P0,(uint8_t*)ADDR,5);
rf24_writeRegister(TX_ADDR,(uint8_t*)ADDR,5);
}
void txData(){
uint8_t crc,cpt,a,b,len;
uint8_t *in, *out;
// Pkt ID
buffer[1] = id;
buffer[2] = pid++;
len = buffer[0] & 0x0F;
#ifdef DEBUG
debughex(buffer,len);
debug("\r");
#endif
// CRC Calc
buffer[3] = 0; // CRC =0 in crc calc;
crc=0; cpt= len; in=(uint8_t*)buffer;
while(cpt--) crc = _crc8_ccitt_update(crc,*(in++));
buffer[3] = crc;
// Hamming compute
cpt= len ;
if(cpt & 1) buffer[cpt++]=0; // odd number => add one 0
cpt/=2; in=(uint8_t*)buffer; out = sendbuffer;
while(cpt--){
a = *(out++)= *(in++);
b = *(out++)= *(in++);
*(out++) = HammingCalculateParity2416(a,b);
}
cpt=4;
while (cpt--){
rf24_send(sendbuffer,PKTLEN);
wait_for_radio();
}
}
int main(void)
{
#ifdef DEBUG
DDRB |= _BV(PB0);
debug("Sonde Start \r");
#endif
uint8_t rvcc=0;
int vcc;
// Setup
power_down();
setupRadio();
id = eeprom_read_byte((const uint8_t*)EE_Num);
// random seed
initADC();
srand((int)readVcc() * id );
DDRB |= _BV(PB1) ;
PORTB &= ~_BV(PB1);
while(1){
if(!(rvcc--)){
initADC();
// Read VCC
vcc = readVcc();
stopADC();
rvcc=4;
}
// Do 8 temp reads over 4s
/* int i = 7;
long lt=readtemp();
while(i--){
power_down();
wdt_enable(WDTO_500MS);
WDTCSR |= _BV(WDIE);
sleep();
power_up();
initADC();
lt += readtemp();
}
wdt_enable(WDTO_8S);
float temp = calctemp(lt / 8);*/
w1_start();
wdt_enable(WDTO_15MS);
WDTCSR |= _BV(WDIE);
sleep();
start_meas();
wdt_enable(WDTO_1S);
WDTCSR |= _BV(WDIE);
sleep();
uint16_t t_i = read_meas();//=temp*100;
w1_stop();
// Send data
initRadio();
buffer[0] = 0x0A | CMD_BIN; // 10 octets :
*(uint16_t*)(buffer+4) = 0x0002; // BIN v2 = vcc+tempDS
*(uint16_t*)(buffer+6) = vcc; // 2 o
*(uint16_t*)(buffer+8) = t_i; // 2 o
txData(buffer);
//radio off
rf24_powerDown();
power_down();
wait_for_next();
}
}