00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "contiki.h"
00035 #include "net/mac/tdma_mac.h"
00036 #include "net/packetbuf.h"
00037 #include "net/uip-fw.h"
00038 #include "sys/rtimer.h"
00039 #include "net/rime.h"
00040 #include "lib/memb.h"
00041 #include "lib/list.h"
00042 #include "dev/leds.h"
00043 #include "node-id.h"
00044
00045 #include <string.h>
00046 #include <stdio.h>
00047
00048 #define DEBUG 1
00049 #if DEBUG
00050 #define DLEDS_ON(x) leds_on(x)
00051 #define DLEDS_OFF(x) leds_off(x)
00052 #define DLEDS_TOGGLE(x) leds_toggle(x)
00053 #define PRINTF(...) printf(__VA_ARGS__)
00054 #else
00055 #define DLEDS_ON(x)
00056 #define DLEDS_OFF(x)
00057 #define DLEDS_TOGGLE(x)
00058 #define PRINTF(...)
00059 #endif
00060
00061
00062 #define NR_SLOTS 3
00063 #define SLOT_LENGTH (RTIMER_SECOND/3)
00064 #define GUARD_PERIOD (RTIMER_SECOND/12)
00065
00066 #define MY_SLOT (node_id % NR_SLOTS)
00067 #define PERIOD_LENGTH RTIMER_SECOND
00068
00069
00070 #define NUM_PACKETS 8
00071 uint8_t lastqueued = 0;
00072 uint8_t nextsend = 0;
00073 uint8_t freeslot = 0;
00074 struct queuebuf* data[NUM_PACKETS];
00075 int id[NUM_PACKETS];
00076
00077 static struct rtimer rtimer;
00078 uint8_t timer_on = 0;
00079
00080 static const struct radio_driver *radio;
00081 static void (* receiver_callback)(const struct mac_driver *);
00082 static int id_counter = 0;
00083 static int sent_counter = 0;
00084
00085
00086 static char
00087 transmitter(struct rtimer *t, void *ptr)
00088 {
00089 int r;
00090 rtimer_clock_t now, rest, period_start, slot_start;
00091
00092
00093 now = RTIMER_NOW();
00094 rest = now % PERIOD_LENGTH;
00095 period_start = now - rest;
00096 slot_start = period_start + MY_SLOT*SLOT_LENGTH;
00097
00098
00099 if(now < slot_start ||
00100 now > slot_start + SLOT_LENGTH - GUARD_PERIOD) {
00101 PRINTF("TIMER We are outside our slot: %u != [%u,%u]\n", now, slot_start, slot_start + SLOT_LENGTH);
00102 while(now > slot_start + SLOT_LENGTH - GUARD_PERIOD) {
00103 slot_start += PERIOD_LENGTH;
00104 }
00105
00106 PRINTF("TIMER Rescheduling until %u\n", slot_start);
00107 r = rtimer_set(&rtimer, slot_start, 1,
00108 (void (*)(struct rtimer *, void *))transmitter, NULL);
00109 if(r) {
00110 PRINTF("TIMER Error #1: %d\n", r);
00111 }
00112
00113 return 1;
00114 }
00115
00116
00117 while(nextsend != freeslot) {
00118 PRINTF("RADIO Transmitting packet #%i\n", id[nextsend]);
00119 if(!radio->send(queuebuf_dataptr(data[nextsend]),
00120 queuebuf_datalen(data[nextsend]))) {
00121 sent_counter++;
00122 PRINTF("RADIO Transmit OK for #%i, total=%i\n", id[nextsend], sent_counter);
00123 DLEDS_TOGGLE(LEDS_GREEN);
00124 } else {
00125 PRINTF("RADIO Transmit failed for #%i, total=%i\n", id[nextsend], sent_counter);
00126 DLEDS_TOGGLE(LEDS_RED);
00127 }
00128
00129 nextsend = (nextsend + 1) % NUM_PACKETS;
00130
00131
00132 if(RTIMER_NOW() > slot_start + SLOT_LENGTH - GUARD_PERIOD) {
00133 PRINTF("TIMER No more time to transmit\n");
00134 break;
00135 }
00136 }
00137
00138
00139 slot_start += PERIOD_LENGTH;
00140 PRINTF("TIMER Rescheduling until %u\n", slot_start);
00141 r = rtimer_set(&rtimer, slot_start, 1,
00142 (void (*)(struct rtimer *, void *))transmitter, NULL);
00143 if(r) {
00144 PRINTF("TIMER Error #2: %d\n", r);
00145 }
00146
00147 return 0;
00148 }
00149
00150 static int
00151 send(void)
00152 {
00153 int r;
00154 id_counter++;
00155
00156
00157 while(lastqueued != nextsend) {
00158 PRINTF("BUFFER Cleaning up packet #%i\n", id[lastqueued]);
00159 queuebuf_free(data[lastqueued]);
00160 data[lastqueued] = NULL;
00161
00162 lastqueued = (lastqueued + 1) % NUM_PACKETS;
00163 }
00164
00165 if((freeslot + 1) % NUM_PACKETS == lastqueued) {
00166 PRINTF("BUFFER Buffer full, dropping packet #%i\n", (id_counter+1));
00167 return UIP_FW_DROPPED;
00168 }
00169
00170
00171 data[freeslot] = queuebuf_new_from_packetbuf();
00172 id[freeslot] = id_counter;
00173 if(data[freeslot] == NULL) {
00174 PRINTF("BUFFER Queuebuffer full, dropping packet #%i\n", id[freeslot]);
00175 return UIP_FW_DROPPED;
00176 }
00177 PRINTF("BUFFER Wrote packet #%i to buffer \n", id[freeslot]);
00178
00179 freeslot = (freeslot + 1) % NUM_PACKETS;
00180
00181 if(!timer_on) {
00182 PRINTF("TIMER Starting timer\n");
00183 r = rtimer_set(&rtimer, RTIMER_NOW() + RTIMER_SECOND, 1,
00184 (void (*)(struct rtimer *, void *))transmitter, NULL);
00185 if(r) {
00186 PRINTF("TIMER Error #3: %d\n", r);
00187 } else {
00188 timer_on = 1;
00189 }
00190 }
00191
00192 return UIP_FW_OK;
00193 }
00194
00195 static void
00196 input(const struct radio_driver *d)
00197 {
00198 receiver_callback(&tdma_mac_driver);
00199 }
00200
00201 static int
00202 read(void)
00203 {
00204 int len;
00205 packetbuf_clear();
00206 len = radio->read(packetbuf_dataptr(), PACKETBUF_SIZE);
00207 packetbuf_set_datalen(len);
00208 return len;
00209 }
00210
00211 static void
00212 set_receive_function(void (* recv)(const struct mac_driver *))
00213 {
00214 receiver_callback = recv;
00215 }
00216
00217 static int
00218 on(void)
00219 {
00220 return radio->on();
00221 }
00222
00223 static int
00224 off(int keep_radio_on)
00225 {
00226 if(keep_radio_on) {
00227 return radio->on();
00228 } else {
00229 return radio->off();
00230 }
00231 }
00232
00233 const struct mac_driver *
00234 tdma_mac_init(const struct radio_driver *d)
00235 {
00236 int i;
00237 for(i = 0; i < NUM_PACKETS; i++) {
00238 data[i] = NULL;
00239 }
00240
00241 radio = d;
00242 radio->set_receive_function(input);
00243 radio->on();
00244
00245 return &tdma_mac_driver;
00246 }
00247
00248 const struct mac_driver tdma_mac_driver = {
00249 "TDMA MAC",
00250 tdma_mac_init,
00251 send,
00252 read,
00253 set_receive_function,
00254 on,
00255 off,
00256 };