contiki-maca.c
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
00035
00036 #include <stdint.h>
00037 #include <stdio.h>
00038 #include <string.h>
00039
00040
00041 #include "radio.h"
00042 #include "sys/process.h"
00043 #include "net/packetbuf.h"
00044 #include "net/netstack.h"
00045
00046 #include "mc1322x.h"
00047 #include "contiki-conf.h"
00048
00049 #define CONTIKI_MACA_DEBUG 0
00050 #if CONTIKI_MACA_DEBUG
00051 #define PRINTF(...) printf(__VA_ARGS__)
00052 #else
00053 #define PRINTF(...)
00054 #endif
00055
00056 #ifndef CONTIKI_MACA_PREPEND_BYTE
00057 #define CONTIKI_MACA_PREPEND_BYTE 0xff
00058 #endif
00059
00060 #ifndef BLOCKING_TX
00061 #define BLOCKING_TX 1
00062 #endif
00063
00064 static volatile uint8_t tx_complete;
00065 static volatile uint8_t tx_status;
00066
00067
00068
00069 int contiki_maca_init(void);
00070 int contiki_maca_on_request(void);
00071 int contiki_maca_off_request(void);
00072 int contiki_maca_read(void *buf, unsigned short bufsize);
00073 int contiki_maca_prepare(const void *payload, unsigned short payload_len);
00074 int contiki_maca_transmit(unsigned short transmit_len);
00075 int contiki_maca_send(const void *payload, unsigned short payload_len);
00076 int contiki_maca_channel_clear(void);
00077 int contiki_maca_receiving_packet(void);
00078 int contiki_maca_pending_packet(void);
00079
00080 const struct radio_driver contiki_maca_driver =
00081 {
00082 .init = contiki_maca_init,
00083 .prepare = contiki_maca_prepare,
00084 .transmit = contiki_maca_transmit,
00085 .send = contiki_maca_send,
00086 .read = contiki_maca_read,
00087 .receiving_packet = contiki_maca_receiving_packet,
00088 .pending_packet = contiki_maca_pending_packet,
00089 .channel_clear = contiki_maca_channel_clear,
00090 .on = contiki_maca_on_request,
00091 .off = contiki_maca_off_request,
00092 };
00093
00094 static volatile uint8_t contiki_maca_request_on = 0;
00095 static volatile uint8_t contiki_maca_request_off = 0;
00096
00097 static process_event_t event_data_ready;
00098
00099 static volatile packet_t prepped_p;
00100
00101 int contiki_maca_init(void) {
00102
00103
00104
00105
00106
00107 return 1;
00108 }
00109
00110
00111 int contiki_maca_channel_clear(void) {
00112 return 1;
00113 }
00114
00115
00116 int contiki_maca_receiving_packet(void) {
00117 return 0;
00118 }
00119
00120 int contiki_maca_pending_packet(void) {
00121 if (rx_head != NULL) {
00122 return 1;
00123 } else {
00124 return 0;
00125 }
00126 }
00127
00128 int contiki_maca_on_request(void) {
00129 contiki_maca_request_on = 1;
00130 contiki_maca_request_off = 0;
00131 return 1;
00132 }
00133
00134 int contiki_maca_off_request(void) {
00135 contiki_maca_request_on = 0;
00136 contiki_maca_request_off = 1;
00137 return 1;
00138 }
00139
00140
00141
00142
00143 int contiki_maca_read(void *buf, unsigned short bufsize) {
00144 volatile uint32_t i;
00145 volatile packet_t *p;
00146
00147 if((p = rx_packet())) {
00148 PRINTF("maca read");
00149 #if CONTIKI_MACA_RAW_MODE
00150
00151
00152 PRINTF(" raw mode");
00153 p->length -= 1;
00154 p->offset += 1;
00155 #endif
00156 PRINTF(": p->length 0x%0x bufsize 0x%0x \n\r", p->length, bufsize);
00157 if((p->length) < bufsize) bufsize = (p->length);
00158 memcpy(buf, (uint8_t *)(p->data + p->offset), bufsize);
00159 packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY,p->lqi);
00160 packetbuf_set_attr(PACKETBUF_ATTR_TIMESTAMP,p->rx_time);
00161 #if CONTIKI_MACA_DEBUG
00162 for( i = p->offset ; i < (bufsize + p->offset) ; i++) {
00163 PRINTF(" %02x",p->data[i]);
00164 }
00165 #endif
00166 PRINTF("\n\r");
00167 free_packet(p);
00168 return bufsize;
00169 } else {
00170 return 0;
00171 }
00172 }
00173
00174
00175
00176
00177
00178 int contiki_maca_prepare(const void *payload, unsigned short payload_len) {
00179 volatile int i;
00180
00181 PRINTF("contiki maca prepare");
00182 #if CONTIKI_MACA_RAW_MODE
00183 prepped_p.offset = 1;
00184 prepped_p.length = payload_len + 1;
00185 #else
00186 prepped_p.offset = 0;
00187 prepped_p.length = payload_len;
00188 #endif
00189 if(payload_len > MAX_PACKET_SIZE) return RADIO_TX_ERR;
00190 memcpy((uint8_t *)(prepped_p.data + prepped_p.offset), payload, payload_len);
00191 #if CONTIKI_MACA_RAW_MODE
00192 prepped_p.offset = 0;
00193 prepped_p.data[0] = CONTIKI_MACA_PREPEND_BYTE;
00194 PRINTF(" raw mode");
00195 #endif
00196 #if CONTIKI_MACA_DEBUG
00197 PRINTF(": sending %d bytes\n\r", payload_len);
00198 for(i = prepped_p.offset ; i < (prepped_p.length + prepped_p.offset); i++) {
00199 PRINTF(" %02x",prepped_p.data[i]);
00200 }
00201 PRINTF("\n\r");
00202 #endif
00203
00204 return RADIO_TX_OK;
00205
00206 }
00207
00208
00209
00210
00211 int contiki_maca_transmit(unsigned short transmit_len) {
00212 volatile packet_t *p;
00213
00214 PRINTF("contiki maca transmit\n\r");
00215 #if BLOCKING_TX
00216 tx_complete = 0;
00217 #endif
00218 if(p = get_free_packet()) {
00219 p->offset = prepped_p.offset;
00220 p->length = prepped_p.length;
00221 memcpy((uint8_t *)(p->data + p->offset),
00222 (const uint8_t *)(prepped_p.data + prepped_p.offset),
00223 prepped_p.length);
00224 tx_packet(p);
00225 } else {
00226 PRINTF("couldn't get free packet for transmit\n\r");
00227 return RADIO_TX_ERR;
00228 }
00229
00230 #if BLOCKING_TX
00231
00232 while(!tx_complete && (tx_head != 0));
00233 #endif
00234 }
00235
00236 int contiki_maca_send(const void *payload, unsigned short payload_len) {
00237 contiki_maca_prepare(payload, payload_len);
00238 contiki_maca_transmit(payload_len);
00239 switch(tx_status) {
00240 case SUCCESS:
00241 case CRC_FAILED:
00242 PRINTF("TXOK\n\r");
00243 return RADIO_TX_OK;
00244 case NO_ACK:
00245 PRINTF("NOACK\n\r");
00246 return RADIO_TX_NOACK;
00247 default:
00248 PRINTF("TXERR\n\r");
00249 return RADIO_TX_ERR;
00250 }
00251 }
00252
00253 PROCESS(contiki_maca_process, "maca process");
00254 PROCESS_THREAD(contiki_maca_process, ev, data)
00255 {
00256 volatile uint32_t i;
00257 int len;
00258
00259 PROCESS_BEGIN();
00260
00261 while (1) {
00262 PROCESS_YIELD();
00263
00264
00265 if(contiki_maca_request_on == 1) {
00266 contiki_maca_request_on = 0;
00267
00268 }
00269
00270 if(contiki_maca_request_off == 1) {
00271 contiki_maca_request_off = 0;
00272
00273 }
00274
00275 if (rx_head != NULL) {
00276 packetbuf_clear();
00277 len = contiki_maca_read(packetbuf_dataptr(), PACKETBUF_SIZE);
00278 if(len > 0) {
00279 packetbuf_set_datalen(len);
00280 NETSTACK_RDC.input();
00281 }
00282 }
00283
00284 if (rx_head != NULL) {
00285 process_poll(&contiki_maca_process);
00286 }
00287
00288 };
00289
00290 PROCESS_END();
00291 }
00292
00293 void maca_rx_callback(volatile packet_t *p __attribute((unused))) {
00294 process_poll(&contiki_maca_process);
00295 }
00296
00297
00298 #if BLOCKING_TX
00299 void maca_tx_callback(volatile packet_t *p __attribute((unused))) {
00300 tx_complete = 1;
00301 tx_status = p->status;
00302 }
00303 #endif