static void chb_frame_read() { U8 i, len, data; CHB_ENTER_CRIT(); RadioCS(TRUE); /*Send frame read command and read the length.*/ SPID_write(CHB_SPI_CMD_FR); len = SPID_write(0); /*Check for correct frame length.*/ if ((len >= CHB_MIN_FRAME_LENGTH) && (len <= CHB_MAX_FRAME_LENGTH)) { // check to see if there is room to write the frame in the buffer. if not, then drop it if (len < (CHB_BUF_SZ - chb_buf_get_len())) { chb_buf_write(len); for (i=0; i<len; i++) { data = SPID_write(0); chb_buf_write(data); } //generate message received event here //EVSYS.STROBE = 0x04; //generate event on channel 3 //generate interrupt on port E by toggling pin 2 //PORTE.OUTSET = PIN2_bm; //PORTE.OUTCLR = PIN2_bm; } else { // we've overflowed the buffer. toss the data and do some housekeeping pcb_t *pcb = chb_get_pcb(); //char buf[50]; // read out the data and throw it away for (i=0; i<len; i++) { data = SPID_write(0); } // Increment the overflow stat pcb->overflow++; // grab the message from flash & print it out //strcpy_P(buf, chb_err_overflow); //printf(buf); } } RadioCS(FALSE); CHB_LEAVE_CRIT(); }
static void chb_frame_read() { U8 i, len, data; CHB_ENTER_CRIT(); CHB_SPI_ENABLE(); /*Send frame read command and read the length.*/ chb_xfer_byte(CHB_SPI_CMD_FR); len = chb_xfer_byte(0); // check the length of the frame to make sure its within the correct size limits if ((len >= CHB_MIN_FRAME_LENGTH) && (len <= CHB_MAX_FRAME_LENGTH)) { // check to see if there is room to write the frame in the buffer. if not, then drop it if (len < (CHB_BUF_SZ - chb_buf_get_len())) { chb_buf_write(len); for (i=0; i<len; i++) { data = chb_xfer_byte(0); chb_buf_write(data); } } else { // this frame will overflow the buffer. toss the data and do some housekeeping pcb_t *pcb = chb_get_pcb(); char buf[50]; // read out the data and throw it away for (i=0; i<len; i++) { data = chb_xfer_byte(0); } // Increment the overflow stat, and print a message. pcb->overflow++; // grab the message from flash & print it out strcpy_P(buf, chb_err_overflow); Serial.print(buf); } } CHB_SPI_DISABLE(); CHB_LEAVE_CRIT(); }
static void chb_frame_read() { U8 i, len, data; // CHB_ENTER_CRIT(); CHB_SPI_ENABLE(); /*Send frame read command and read the length.*/ chb_xfer_byte(CHB_SPI_CMD_FR); len = chb_xfer_byte(0); /*Check for correct frame length.*/ if ((len >= CHB_MIN_FRAME_LENGTH) && (len <= CHB_MAX_FRAME_LENGTH)) { // check to see if there is room to write the frame in the buffer. if not, then drop it if (len < (CFG_CHIBI_BUFFERSIZE - chb_buf_get_len())) { chb_buf_write(len); for (i=0; i<len; i++) { data = chb_xfer_byte(0); chb_buf_write(data); } } else { // we've overflowed the buffer. toss the data and do some housekeeping chb_pcb_t *pcb = chb_get_pcb(); // read out the data and throw it away for (i=0; i<len; i++) { data = chb_xfer_byte(0); } // Increment the overflow stat pcb->overflow++; // print the error message printf(chb_err_overflow); } } CHB_SPI_DISABLE(); CHB_LEAVE_CRIT(); }
U8 chb_read(chb_rx_data_t *rx) { U8 i, len, seq, *data_ptr; data_ptr = rx->data; // first byte is always len. check it to make sure // we have a valid len byte. if ((len = chb_buf_read()) > CHB_MAX_FRAME_LENGTH) { return 0; } *data_ptr++ = len; // load the rest of the data into buffer for (i=0; i<len; i++) { *data_ptr++ = chb_buf_read(); } // we're using the buffer that's fed in as an argument as a temp // buffer as well to save resources. // we'll use it as temp storage to parse the frame. then move the frame // down so that only the payload will be in the buffer. // extract the sequence number data_ptr = rx->data + 3; // location of sequence number seq = *data_ptr; // parse the buffer and extract the dest and src addresses data_ptr = rx->data + 6; // location of dest addr rx->dest_addr = *(U16 *)data_ptr; data_ptr += sizeof(U16); rx->src_addr = *(U16 *)data_ptr; data_ptr += sizeof(U16); // if the data in the rx buf is 0, then clear the rx_flag. otherwise, keep it raised if (!chb_buf_get_len()) { pcb.data_rcv = false; } #if (CHIBI_PROMISCUOUS) // if we're in promiscuous mode, we don't want to do any duplicate rejection and we don't want to move the payload // to the front of the buffer. We want to capture the full frame so just keep the frame intact and return the length. return len; #else // duplicate frame check (dupe check). we want to remove frames that have been already been received since they // are just retries. // note: this dupe check only removes duplicate frames from the previous transfer. if another frame from a different // node comes in between the dupes, then the dupe will show up as a received frame. if ((seq == prev_seq) && (rx->src_addr == prev_src_addr)) { // this is a duplicate frame from a retry. the remote node thinks we didn't receive // it properly. discard. return 0; } else { prev_seq = seq; prev_src_addr = rx->src_addr; } // move the payload down to the beginning of the data buffer memmove(rx->data, data_ptr, len - CHB_HDR_SZ); // finally, return the len of the payload return len - CHB_HDR_SZ - CHB_FCS_LEN; #endif }