Contiki 3.x
ms-io-arch.c
1 #include <time.h>
2 #include <stdio.h>
3 #include <inttypes.h>
4 #include "board.h"
5 #include "contiki.h"
6 #include "mountainsensing/common/ms-io.h"
7 #include "ds3231-sensor.h"
8 #include "lpm.h"
9 #include "dev/uart.h"
10 #include "dev/avr-handler.h"
11 #include "dev/gpio.h"
12 #include "dev/adc-zoul.h"
13 #include "event-sensor.h"
14 #include "reset-sensor.h"
15 
16 #define DEBUG_ON
18 
19 /**
20  * True if senser power is on, false otherwise
21  */
22 static bool is_sense_on = false;
23 
24 /**
25  * Callback allowing / disallowing the CC2538 to enter LPM{1,2}
26  */
27 static bool lpm_permit_pm1(void) {
28  // LPM{1,2} are only allowed if we're not sensing
29  return !is_sense_on;
30 }
31 
32 /**
33  * Function used by the avr-handler to write bytes out on the RS484 link
34  */
35 static void avr_write_bytes(uint8_t *buf, int length) {
36  // The RS485 adapter are half-duplex - enable TX mode when we're sending
37  GPIO_SET_PIN(GPIO_PORT_TO_BASE(RS485_TXEN_PORT), GPIO_PIN_MASK(RS485_TXEN_PIN));
38 
39  int i;
40  for (i = 0; i < length; i++) {
41  uart_write_byte(RS485_UART, buf[i]);
42  }
43 
44  // Wait for the UART to finish sending
45  while(REG(UART_1_BASE + UART_FR) & UART_FR_BUSY);
46 
47  GPIO_CLR_PIN(GPIO_PORT_TO_BASE(RS485_TXEN_PORT), GPIO_PIN_MASK(RS485_TXEN_PIN));
48 }
49 
50 void ms_init(void) {
51  // Initialize the ADCs
52  adc_zoul.configure(SENSORS_HW_INIT, ZOUL_SENSORS_ADC1 + ZOUL_SENSORS_ADC2 + ZOUL_SENSORS_ADC3);
53 
54  // Register our lpm_permit callback so we can stay in LPM0 during sensing
56 
57  // Turn sense off by default
58  ms_sense_off();
59 
60  // Enable the rain sensor
61  SENSORS_ACTIVATE(event_sensor);
62 
63  // Setup the AVR Handler to use the RS485 UART
64  uart_set_input(RS485_UART, &avr_input_byte);
65  avr_set_output(&avr_write_bytes);
66 
67  // Disable the FIFO RX buffer of RS485 UART
68  REG(RS485_UART_BASE + UART_LCRH) &= ~UART_LCRH_FEN;
69 
70  process_start(&avr_process, NULL);
71 }
72 
73 void ms_sense_on(void) {
74  is_sense_on = true;
75 
76  // Enable sense
77  GPIO_SET_PIN(GPIO_PORT_TO_BASE(PWR_SENSE_EN_PORT), GPIO_PIN_MASK(PWR_SENSE_EN_PIN));
78 }
79 
80 void ms_sense_off(void) {
81  is_sense_on = false;
82 
83  // Disable sense
84  GPIO_CLR_PIN(GPIO_PORT_TO_BASE(PWR_SENSE_EN_PORT), GPIO_PIN_MASK(PWR_SENSE_EN_PIN));
85 }
86 
87 bool ms_get_time(uint32_t *seconds) {
88  struct tm t;
89 
90  if (ds3231_get_time(&t) != 0) {
91  *seconds = ERROR_EPOCH;
92  return false;
93  }
94 
95  *seconds = (uint32_t) mktime(&t);
96 
97  //DEBUG("years %d, months %d, days %d, hours %d, minutes %d, seconds %d\n", t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
98  //DEBUG("epoch is %" PRIu32 "\n", seconds);
99 
100  return true;
101 }
102 
103 bool ms_set_time(uint32_t seconds) {
104  if (seconds < EARLIEST_EPOCH) {
105  return false;
106  }
107 
108  struct tm t;
109  gmtime_r((time_t *) &seconds, &t);
110 
111  //DEBUG("years %d, months %d, days %d, hours %d, minutes %d, seconds %d\n", t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
112  //DEBUG("epoch %" PRIu32 "\n", seconds);
113 
114  return ds3231_set_time(&t) == 0;
115 }
116 
117 bool ms_get_batt(float *batt) {
118  // Batt sensor is on ADC3
119  // Munge factor of 1698 gives about the right voltage on multiple boards, within 0.5V.
120  *batt = ((float) (adc_zoul.value(ZOUL_SENSORS_ADC3)/1698));
121  return true;
122 }
123 
124 bool ms_get_temp(float *temp) {
125  int centi_temp;
126 
127  if (ds3231_get_temperature(&centi_temp) != 0) {
128  return false;
129  }
130 
131  *temp = ((float) centi_temp) / 100;
132  return true;
133 }
134 
135 bool ms_get_humid(float *humid) {
136  // Not supported
137  return false;
138 }
139 
140 bool ms_get_adc1(uint32_t *adc1) {
141  *adc1 = adc_zoul.value(ZOUL_SENSORS_ADC1);
142  return true;
143 }
144 
145 bool ms_get_adc2(uint32_t *adc2) {
146  *adc2 = adc_zoul.value(ZOUL_SENSORS_ADC2);
147  return true;
148 }
149 
150 bool ms_get_rain(uint32_t *rain) {
151  // Reset the value so we only get the delta every time
152  *rain = event_sensor.value(true);
153  return true;
154 }
155 
156 bool ms_get_acc(int32_t *x, int32_t *y, int32_t *z) {
157  // Not supported
158  return false;
159 }
160 
161 bool ms_get_reboot(uint16_t *reboot) {
162  // Param is ignored by the reset sensor
163  *reboot = reset_sensor.value(0);
164  return true;
165 }
166 
167 bool ms_reset_reboot(void) {
168  reset_counter_reset();
169  return true;
170 }
void uart_set_input(uint8_t uart, int(*input)(unsigned char c))
Assigns a callback to be called when the UART receives a byte.
Definition: uart.c:337
#define EARLIEST_EPOCH
Earliest time supported by the rtc - 2000/01/01 00:00:00.
Definition: ds3231-sensor.h:49
Sensors for DS3231 (RTC with Temperature Sensor).
#define GPIO_PIN_MASK(PIN)
Converts a pin number to a pin mask.
Definition: gpio.h:321
Header file with definitions related to the I/O connections on the Muntjac platform, cc2538-based.
#define UART_LCRH
UART line control.
Definition: uart.h:73
Debug helpers.
Header file for the Zoul ADC interface.
#define GPIO_CLR_PIN(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE low.
Definition: gpio.h:114
#define UART_LCRH_FEN
UART enable FIFOs.
Definition: uart.h:149
#define GPIO_SET_PIN(PORT_BASE, PIN_MASK)
Set pins with PIN_MASK of port with PORT_BASE high.
Definition: gpio.h:107
void uart_write_byte(uint8_t uart, uint8_t b)
Sends a single character down the UART.
Definition: uart.c:347
#define NULL
The null pointer.
#define UART_FR_BUSY
UART busy.
Definition: uart.h:122
int ds3231_get_time(struct tm *t)
ds3231_get_time
#define GPIO_PORT_TO_BASE(PORT)
Converts a port number to the port base address.
Definition: gpio.h:329
void lpm_register_peripheral(lpm_periph_permit_pm1_func_t permit_pm1_func)
Register a peripheral function which will get called by the LPM module to get 'permission' to drop to...
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99
static bool lpm_permit_pm1(void)
Callback to allow Low Power Modes 1 and 2.
int ds3231_set_time(struct tm *t)
ds3231_set_time
#define UART_FR
UART flag.
Definition: uart.h:69
tm
Definition: utc_time.h:20
int ds3231_get_temperature(int *temperature)
ds3231_temperature