📄 cc1000sendreceivep.nc
字号:
getMetadata(txBufPtr)->metadataBits |= CC1000_ACK_BIT;
enterTxDoneState();
return;
}
}
if (count >= MAX_ACK_WAIT)
{
getMetadata(txBufPtr)->metadataBits &= ~CC1000_ACK_BIT;
enterTxDoneState();
}
}
task void signalPacketSent() {
message_t *pBuf;
atomic
{
pBuf = txBufPtr;
f.txBusy = FALSE;
enterListenState();
}
signal Send.sendDone(pBuf, SUCCESS);
}
void txDone() {
post signalPacketSent();
signal ByteRadio.sendDone();
}
/* Receive */
/*---------*/
void packetReceived();
void packetReceiveDone();
async command void ByteRadio.listen() {
enterListenState();
call CC1000Control.rxMode();
call HplCC1000Spi.rxMode();
call HplCC1000Spi.enableIntr();
}
async command void ByteRadio.off() {
enterInactiveState();
call HplCC1000Spi.disableIntr();
}
void listenData(uint8_t in) {
bool preamble = in == 0xaa || in == 0x55;
// Look for enough preamble bytes
if (preamble)
{
count++;
if (count > CC1K_ValidPrecursor)
enterSyncState();
}
else
count = 0;
signal ByteRadio.idleByte(preamble);
}
void syncData(uint8_t in) {
// draw in the preamble bytes and look for a sync byte
// save the data in a short with last byte received as msbyte
// and current byte received as the lsbyte.
// use a bit shift compare to find the byte boundary for the sync byte
// retain the shift value and use it to collect all of the packet data
// check for data inversion, and restore proper polarity
// XXX-PB: Don't do this.
if (in == 0xaa || in == 0x55)
// It is actually possible to have the LAST BIT of the incoming
// data be part of the Sync Byte. SO, we need to store that
// However, the next byte should definitely not have this pattern.
// XXX-PB: Do we need to check for excessive preamble?
rxShiftBuf = in << 8;
else if (count++ == 0)
rxShiftBuf |= in;
else if (count <= 6)
{
// TODO: Modify to be tolerant of bad bits in the preamble...
uint32_t time;
uint16_t tmp;
uint8_t i;
time = call LocalTime32khz.get();
// bit shift the data in with previous sample to find sync
tmp = rxShiftBuf;
rxShiftBuf = rxShiftBuf << 8 | in;
for(i = 0; i < 8; i++)
{
tmp <<= 1;
if (in & 0x80)
tmp |= 0x1;
in <<= 1;
// check for sync bytes
if (tmp == SYNC_WORD)
{
enterRxState();
signal ByteRadio.rx();
f.rxBitOffset = 7 - i;
// correct receive time according to bit offset and set timestamp
time -= BIT_CORRECTION[f.rxBitOffset];
call PacketTimeStamp32khz.set(rxBufPtr, time);
call RssiRx.read();
}
}
}
else // We didn't find it after a reasonable number of tries, so....
enterListenState();
}
async event void RssiRx.readDone(error_t result, uint16_t data) {
cc1000_metadata_t *rxMetadata = getMetadata(rxBufPtr);
if (result != SUCCESS)
rxMetadata->strength_or_preamble = 0;
else
rxMetadata->strength_or_preamble = data;
}
void rxData(uint8_t in) {
uint8_t nextByte;
cc1000_header_t *rxHeader = getHeader(rxBufPtr);
uint8_t rxLength = rxHeader->length;
// Reject invalid length packets
if (rxLength > TOSH_DATA_LENGTH)
{
// The packet's screwed up, so just dump it
enterListenState();
signal ByteRadio.rxDone();
return;
}
rxShiftBuf = rxShiftBuf << 8 | in;
nextByte = rxShiftBuf >> f.rxBitOffset;
((uint8_t *COUNT(sizeof(message_t)))rxBufPtr)[count++] = nextByte;
// Adjust rxLength to correspond to the corresponding offset in message_t
rxLength += offsetof(message_t, data);
if (count <= rxLength)
runningCrc = crcByte(runningCrc, nextByte);
// Jump to CRC when we reach the end of data
if (count == rxLength) {
count = offsetof(message_t, footer) + offsetof(cc1000_footer_t, crc);
}
if (count == (offsetof(message_t, footer) + sizeof(cc1000_footer_t)))
packetReceived();
}
void packetReceived() {
cc1000_footer_t *rxFooter = getFooter(rxBufPtr);
cc1000_header_t *rxHeader = getHeader(rxBufPtr);
// Packet filtering based on bad CRC's is done at higher layers.
// So sayeth the TOS weenies.
rxFooter->crc = (rxFooter->crc == runningCrc);
if (f.ack &&
rxFooter->crc &&
rxHeader->dest == call amAddress())
{
enterAckState();
call CC1000Control.txMode();
call HplCC1000Spi.txMode();
call HplCC1000Spi.writeByte(0xaa);
}
else
packetReceiveDone();
}
void ackData(uint8_t in) {
if (++count >= ACK_LENGTH)
{
call CC1000Control.rxMode();
call HplCC1000Spi.rxMode();
packetReceiveDone();
}
else if (count >= ACK_LENGTH - sizeof ackCode)
call HplCC1000Spi.writeByte(read_uint8_t(&ackCode[count + sizeof ackCode - ACK_LENGTH]));
}
task void signalPacketReceived() {
message_t *pBuf;
cc1000_header_t *pHeader;
atomic
{
if (radioState != RECEIVED_STATE)
return;
pBuf = rxBufPtr;
}
pHeader = getHeader(pBuf);
pBuf = signal Receive.receive(pBuf, pBuf->data, pHeader->length);
atomic
{
if (pBuf)
rxBufPtr = pBuf;
if (radioState == RECEIVED_STATE) // receiver might've done something
enterListenState();
signal ByteRadio.rxDone();
}
}
void packetReceiveDone() {
uint16_t snr;
snr = (uint16_t) getMetadata(rxBufPtr)->strength_or_preamble;
/* Higher signal strengths have lower voltages. So see if we're
CC1000_WHITE_BIT_THRESH *below* the noise floor. */
if ((snr + CC1000_WHITE_BIT_THRESH) < ((call CC1000Squelch.get()))) {
getMetadata(rxBufPtr)->metadataBits |= CC1000_WHITE_BIT;
}
else {
getMetadata(rxBufPtr)->metadataBits &= ~CC1000_WHITE_BIT;
}
post signalPacketReceived();
enterReceivedState();
}
async event void HplCC1000Spi.dataReady(uint8_t data) {
if (f.invert)
data = ~data;
switch (radioState)
{
default: break;
case TXPREAMBLE_STATE: txPreamble(); break;
case TXSYNC_STATE: txSync(); break;
case TXDATA_STATE: txData(); break;
case TXCRC_STATE: txCrc(); break;
case TXFLUSH_STATE: txFlush(); break;
case TXWAITFORACK_STATE: txWaitForAck(); break;
case TXREADACK_STATE: txReadAck(data); break;
case TXDONE_STATE: txDone(); break;
case LISTEN_STATE: listenData(data); break;
case SYNC_STATE: syncData(data); break;
case RX_STATE: rxData(data); break;
case SENDING_ACK: ackData(data); break;
}
}
/* Interaction with rest of stack */
/*--------------------------------*/
async command void ByteRadio.setPreambleLength(uint16_t bytes) {
atomic preambleLength = bytes;
}
async command uint16_t ByteRadio.getPreambleLength() {
atomic return preambleLength;
}
async command message_t *ByteRadio.getTxMessage() {
return txBufPtr;
}
async command bool ByteRadio.syncing() {
return radioState == SYNC_STATE;
}
/* Abstract packet layout */
command void Packet.clear(message_t *msg) {
memset(getHeader(msg), 0x0, sizeof(cc1000_header_t));
memset(getFooter(msg), 0x0, sizeof(cc1000_footer_t));
memset(getMetadata(msg), 0x0, sizeof(cc1000_metadata_t));
}
command uint8_t Packet.payloadLength(message_t *msg) {
cc1000_header_t *header = getHeader(msg);
return header->length;
}
command void Packet.setPayloadLength(message_t *msg, uint8_t len) {
getHeader(msg)->length = len;
}
command uint8_t Packet.maxPayloadLength() {
return TOSH_DATA_LENGTH;
}
command void* Packet.getPayload(message_t *msg, uint8_t len) {
if (len <= TOSH_DATA_LENGTH) {
return (void* COUNT_NOK(len))msg->data;
}
else {
return NULL;
}
}
async command error_t PacketAcknowledgements.requestAck(message_t *msg) {
return SUCCESS; /* We always ack. */
}
async command error_t PacketAcknowledgements.noAck(message_t *msg) {
return FAIL; /* We always ack */
}
command uint8_t Send.maxPayloadLength() {
return call Packet.maxPayloadLength();
}
command void* Send.getPayload(message_t *m, uint8_t len) {
return call Packet.getPayload(m, len);
}
async command bool PacketAcknowledgements.wasAcked(message_t *msg) {
return getMetadata(msg)->metadataBits & CC1000_ACK_BIT;
}
async command bool LinkPacketMetadata.highChannelQuality(message_t* msg) {
return getMetadata(msg)->metadataBits & CC1000_WHITE_BIT;
}
/***************** PacketTimeStamp32khz Commands ****************/
async command bool PacketTimeStamp32khz.isValid(message_t* msg)
{
return (getMetadata(msg)->timestamp != CC1000_INVALID_TIMESTAMP);
}
async command uint32_t PacketTimeStamp32khz.timestamp(message_t* msg)
{
return getMetadata(msg)->timestamp;
}
async command void PacketTimeStamp32khz.clear(message_t* msg)
{
getMetadata(msg)->timesync = FALSE;
getMetadata(msg)->timestamp = CC1000_INVALID_TIMESTAMP;
}
async command void PacketTimeStamp32khz.set(message_t* msg, uint32_t value)
{
getMetadata(msg)->timestamp = value;
}
/***************** PacketTimeStampMilli Commands ****************/
// over the air value is always T32khz
async command bool PacketTimeStampMilli.isValid(message_t* msg)
{
return call PacketTimeStamp32khz.isValid(msg);
}
async command uint32_t PacketTimeStampMilli.timestamp(message_t* msg)
{
int32_t offset = call PacketTimeStamp32khz.timestamp(msg) - call LocalTime32khz.get();
return (offset >> 5) + call LocalTimeMilli.get();
}
async command void PacketTimeStampMilli.clear(message_t* msg)
{
call PacketTimeStamp32khz.clear(msg);
}
async command void PacketTimeStampMilli.set(message_t* msg, uint32_t value)
{
int32_t offset = (value - call LocalTimeMilli.get()) << 5;
call PacketTimeStamp32khz.set(msg, offset + call LocalTime32khz.get());
}
/*----------------- PacketTimeSyncOffset -----------------*/
async command bool PacketTimeSyncOffset.isSet(message_t* msg)
{
return getMetadata(msg)->timesync;
}
async command uint8_t PacketTimeSyncOffset.get(message_t* msg)
{
return sizeof(cc1000_header_t) + getHeader(msg)->length - sizeof(timesync_radio_t);
}
async command void PacketTimeSyncOffset.set(message_t* msg)
{
getMetadata(msg)->timesync = TRUE;
}
async command void PacketTimeSyncOffset.cancel(message_t* msg)
{
getMetadata(msg)->timesync = FALSE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -