📄 tr1001-gcr.c
字号:
tr1001_default_rxhandler_pt(RXBUF0); if(tr1001_rxstate == RXSTATE_FULL) { LPM4_EXIT; } ENERGEST_OFF(ENERGEST_TYPE_IRQ);}/*---------------------------------------------------------------------------*/static voiddump_packet(int len){ int i; for(i = 0; i < len; ++i) { LOG("%d: 0x%02x\n", i, tr1001_rxbuf[i]); }}/*---------------------------------------------------------------------------*/PT_THREAD(tr1001_default_rxhandler_pt(unsigned char incoming_byte)){ static unsigned char rxtmp, tmppos; if(timer_expired(&rxtimer) && tr1001_rxstate != RXSTATE_FULL) { PT_INIT(&rxhandler_pt); } timer_restart(&rxtimer); if(tr1001_rxstate == RXSTATE_RECEIVING) { unsigned short signal = radio_sensor.value(0); tmp_sstrength += (signal >> 2); tmp_count++; } PT_BEGIN(&rxhandler_pt); while(1) { /* Reset reception state. */ rxclear(); /* Wait until we receive the first syncronization byte. */ PT_WAIT_UNTIL(&rxhandler_pt, incoming_byte == SYNCH1); tr1001_rxstate = RXSTATE_RECEIVING; /* Read all incoming syncronization bytes. */ PT_WAIT_WHILE(&rxhandler_pt, incoming_byte == SYNCH1); /* We should receive the second synch byte by now, otherwise we'll restart the protothread. */ if(incoming_byte != SYNCH2) { PT_RESTART(&rxhandler_pt); } /* Start signal strength measurement */ tmp_sstrength = 0; tmp_count = 0; /* Reset the CRC. */ rxcrc = 0xffff; gcr_init(); GCRLOG("RECV: "); /* Read packet header. */ for(tmppos = 0; tmppos < TR1001_HDRLEN; ++tmppos) { /* Wait for the first byte of the packet to arrive. */ do { PT_YIELD(&rxhandler_pt); GCRLOG("(%02x) ", incoming_byte); gcr_decode(incoming_byte); /* If the incoming byte isn't a valid GCR encoded byte, we start again from the beginning. */ if(!gcr_valid()) { beep_beep(1000); LOG("Incorrect GCR in header at byte %d/1 %x\n", tmppos, incoming_byte); RIMESTATS_ADD(badsynch); PT_RESTART(&rxhandler_pt); } } while(!gcr_get_decoded(&rxtmp)); GCRLOG("%02x ", rxtmp); tr1001_rxbuf[tmppos] = rxtmp; /* Calculate the CRC. */ rxcrc = crc16_add(rxtmp, rxcrc); } /* Since we've got the header, we can grab the length from it. */ tr1001_rxlen = ((((struct tr1001_hdr *)tr1001_rxbuf)->len[0] << 8) + ((struct tr1001_hdr *)tr1001_rxbuf)->len[1]); /* If the length is longer than we can handle, we'll start from the beginning. */ if(tmppos + tr1001_rxlen > sizeof(tr1001_rxbuf)) { RIMESTATS_ADD(toolong); PT_RESTART(&rxhandler_pt); } /* Read packet data. */ for(; tmppos < tr1001_rxlen + TR1001_HDRLEN; ++tmppos) { /* Wait for the first byte of the packet to arrive. */ do { PT_YIELD(&rxhandler_pt); GCRLOG("(%02x)", incoming_byte); gcr_decode(incoming_byte); /* If the incoming byte isn't a valid Manchester encoded byte, we start again from the beinning. */ if(!gcr_valid()) { beep_beep(1000); LOG("Incorrect GCR 0x%02x at byte %d/1\n", incoming_byte, tmppos - TR1001_HDRLEN); RIMESTATS_ADD(badsynch); PT_RESTART(&rxhandler_pt); } } while(!gcr_get_decoded(&rxtmp)); GCRLOG("%02x ", rxtmp); tr1001_rxbuf[tmppos] = rxtmp; /* Calculate the CRC. */ rxcrc = crc16_add(rxtmp, rxcrc); } /* Read the frame CRC. */ for(tmppos = 0; tmppos < 2; ++tmppos) { do { PT_YIELD(&rxhandler_pt); GCRLOG("(%02x)", incoming_byte); gcr_decode(incoming_byte); if(!gcr_valid()) { beep_beep(1000); RIMESTATS_ADD(badsynch); PT_RESTART(&rxhandler_pt); } } while(!gcr_get_decoded(&rxtmp)); GCRLOG("%02x ", rxtmp); rxcrctmp = (rxcrctmp << 8) | rxtmp; } GCRLOG("\n"); if(rxcrctmp == rxcrc) { /* A full packet has been received and the CRC checks out. We'll request the driver to take care of the incoming data. */ RIMESTATS_ADD(llrx); process_poll(&tr1001_process); /* We'll set the receive state flag to signal that a full frame is present in the buffer, and we'll wait until the buffer has been taken care of. */ tr1001_rxstate = RXSTATE_FULL; PT_WAIT_UNTIL(&rxhandler_pt, tr1001_rxstate != RXSTATE_FULL); } else { LOG("Incorrect CRC\n"); beep_beep(1000); RIMESTATS_ADD(badcrc); } } PT_END(&rxhandler_pt);}/*---------------------------------------------------------------------------*//* * Prepare a transmission. * * This function does the necessary setup before a packet can be sent * out. */static voidprepare_transmission(int synchbytes){ int i; /* Delay the transmission for a short random duration. */ clock_delay(random_rand() & 0x3ff); /* Check that we don't currently are receiveing a packet, and if so we wait until the reception has been completed. Reception is done with interrupts so it is OK for us to wait in a while() loop. */ while(tr1001_rxstate == RXSTATE_RECEIVING && !timer_expired(&rxtimer)) { /* Delay the transmission for a short random duration. */ clock_delay(random_rand() & 0x7ff); } /* Turn on OOK mode with transmission. */ txook(); /* According to the datasheet, the transmitter must wait for 12 us in order to settle. Empirical tests show that is it better to wait for something like 283 us... */ clock_delay(200); /* Transmit preamble and synch bytes. */ for(i = 0; i < 20; ++i) { send(0xaa); } /* send(0xaa); send(0xaa);*/ send(0xff); for(i = 0; i < synchbytes; ++i) { send(SYNCH1); } send(SYNCH2);}/*---------------------------------------------------------------------------*/inttr1001_send(const void *packet, unsigned short len){ int i; uint16_t crc16; LOG("tr1001_send: sending %d bytes\n", len); ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); /* Prepare the transmission. */ prepare_transmission(NUM_SYNCHBYTES); crc16 = 0xffff; gcr_init(); GCRLOG("SEND: "); /* Send packet header. */ crc16 = sendx_crc16(len >> 8, crc16); crc16 = sendx_crc16(len & 0xff, crc16); /* Send packet data. */ for(i = 0; i < len; ++i) { crc16 = sendx_crc16(((uint8_t *)packet)[i], crc16); } /* Send CRC */ sendx(crc16 >> 8); sendx(crc16 & 0xff); /* if not encoding has sent all bytes - let it send another GCR specific */ if (!gcr_finished()) { sendx(0); } GCRLOG("\n"); /* Send trailing bytes. */ send(0x33); send(0xcc); send(0x33); send(0xcc); /* Turn on (or off) reception again. */ if(onoroff == ON) { rxon(); rxclear(); } else { rxoff(); rxclear(); } ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); RIMESTATS_ADD(lltx); return 0;}/*---------------------------------------------------------------------------*/inttr1001_read(void *buf, unsigned short bufsize){ unsigned short tmplen; if(tr1001_rxstate == RXSTATE_FULL) { dump_packet(tr1001_rxlen + 2); tmplen = tr1001_rxlen; if(tmplen > bufsize) { tmplen = bufsize; } memcpy(buf, &tr1001_rxbuf[TR1001_HDRLEN], tmplen); /* header + content + CRC *//* sstrength = (tmp_sstrength / (TR1001_HDRLEN + tr1001_rxlen + 2)) << 1; */ sstrength = (tmp_count ? ((tmp_sstrength / tmp_count) << 2) : 0); rxclear(); LOG("tr1001_read: got %d bytes\n", tmplen); return tmplen; } return 0;}/*---------------------------------------------------------------------------*/PROCESS_THREAD(tr1001_process, ev, data){ PROCESS_BEGIN(); /* Reset reception state now that the process is ready to receive data. */ rxclear(); while(1) { PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); if(receiver_callback != NULL) { receiver_callback(&tr1001_driver); } else { LOG("tr1001 has no receive function\n"); /* Perform a dummy read to drop the message. */ tr1001_read((uint8_t *)&data, 0); } } PROCESS_END();}/*---------------------------------------------------------------------------*/voidtr1001_set_speed(unsigned char speed){ if(speed == TR1001_19200) { /* Set TR1001 to 19200 */ UBR00 = 0x80; /* 2,457MHz/19200 = 128 -> 0x80 */ UBR10 = 0x00; /* */ UMCTL0 = 0x00; /* no modulation */ } else if(speed == TR1001_38400) { /* Set TR1001 to 38400 */ UBR00 = 0x40; /* 2,457MHz/38400 = 64 -> 0x40 */ UBR10 = 0x00; /* */ UMCTL0 = 0x00; /* no modulation */ } else if(speed == TR1001_57600) { UBR00 = 0x2a; /* 2,457MHz/57600 = 42.7 -> 0x2A */ UBR10 = 0x00; /* */ UMCTL0 = 0x5b; /* */ } else if(speed == TR1001_115200) { UBR00 = 0x15; /* 2,457MHz/115200 = 21.4 -> 0x15 */ UBR10 = 0x00; /* */ UMCTL0 = 0x4a; /* */ } else { tr1001_set_speed(TR1001_19200); }}/*---------------------------------------------------------------------------*/unsigned shorttr1001_sstrength(void){ return sstrength;}/*--------------------------------------------------------------------------*//** @} *//** @} */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -