📄 cc2420.c
字号:
{ CC2420_state = IDLE_STATE;// printk("in packet sent, CC2420_state changed to: %d\n", CC2420_state); tx_buf_ptr->length = tx_buf_ptr->length - MSG_HEADER_SIZE - MSG_FOOTER_SIZE; // send is done, end waiting send_done = 1; wake_up_interruptible(&wq); return;}void CC2420_start_send() {//YC: actually no need to flushtx, it is flushed when write to txfifo//keep this here to ensure the unusal underflow error if(!CC2420_cmd_strobe(CC2420_SFLUSHTX)){ CC2420_send_failed(); return; } //write txbuf data to TXFIFO // length does not include the length itself, so add that in here if(!CC2420_write_TXFIFO(tx_buf_ptr->length+1, (uint8_t*)tx_buf_ptr)){ CC2420_send_failed(); return; }}/* * CCA detection. * If failed, backoff */void CC2420_try_to_send() { uint8_t current_state = CC2420_state;// printk("into try to send, state=%d\n",current_state); if(current_state == PRE_TX_STATE){ //Comment out by YC, no relation between FIFOP/FIFO with TXFIFO //if FIFO overflow occurs, or if data length is invalid, // flush RXFIFO to get back to a normal state //if(!TEST_FIFO_PIN() && !TEST_FIFOP_PIN()) { // CC2420_flush_RXFIFO(); // printk("flushed \n"); //} if(TEST_CCA_PIN()) { CC2420_state = TX_STATE;// printk("in try to send, CC2420_state changed to: %d\n", CC2420_state);// printk(KERN_INFO "CCA is good\n"); CC2420_send_packet(); } else {// printk(KERN_INFO "CCA is bad\n"); if(count_retry-- <= 0) { //CC2420_flush_TXFIFO(); count_retry = MAX_SEND_TRIES; if(count_send_restart-- > 0) CC2420_set_restart_timer(Mac_congestion_backoff() * CC2420_SYMBOL_UNIT); else CC2420_send_failed(); return; } CC2420_set_backoff_timer(Mac_congestion_backoff() * CC2420_SYMBOL_UNIT); } } else if(current_state == IDLE_STATE){ //added by YC, flush TXFIFO when idle// printk("before flush------ \n"); CC2420_flush_TXFIFO();// printk("after flush \n"); } return;}/* * Try to send a packet after CCA is good. If unsuccessful, backoff again */void CC2420_send_packet() { uint8_t status; CC2420_cmd_strobe(CC2420_STXONCCA); status = CC2420_cmd_strobe(CC2420_SNOP); if ((status >> CC2420_TX_ACTIVE) & 0x01) { CC2420_set_transmit_timer(CC2420_TMIT_DELAY); } else { // try again to send the packet// printk("set backoff status \n"); CC2420_state = PRE_TX_STATE;// printk("in send packet, CC2420_state changed to: %d\n", CC2420_state); CC2420_set_backoff_timer(Mac_congestion_backoff() * CC2420_SYMBOL_UNIT); }}int CC2420_send(TOS_MsgPtr pMsg) { uint8_t current_state; current_state = CC2420_state;// printk(KERN_INFO "send: current state: %d\n", current_state); if (current_state == IDLE_STATE) { // put default FCF values in to get address checking to pass#ifndef PSI // not sure why the code is filling this in. Seems like the // higher layer(s) should be responsible for this pMsg->fcflo = CC2420_DEF_FCF_LO; if (is_ack_enable) pMsg->fcfhi = CC2420_DEF_FCF_HI_ACK; else pMsg->fcfhi = CC2420_DEF_FCF_HI; // destination PAN is broadcast pMsg->destpan = TOS_BCAST_ADDR; // adjust the destination address to be in the right byte order// printk(KERN_INFO "DestAddr is %d\n", (int)(pMsg->addr)); pMsg->addr = toLSB16(pMsg->addr);// printk(KERN_INFO "DestAddr is %d\n", (int)(pMsg->addr));#endif#ifndef PSI // keep the DSN increasing for ACK recognition pMsg->dsn = ++current_DSN;#endif // reset the time field pMsg->time = 0; // FCS bytes generated by CC2420 // adjust the data length to now include the full packet, sans length pMsg->length = pMsg->length+MSG_HEADER_SIZE+MSG_FOOTER_SIZE+1;//YC: should include length byte here if (pMsg->length >= MSG_DATA_SIZE) pMsg->length = MSG_DATA_SIZE; //length should include the whole message packet pMsg->length--; //length doesn't include length field itself, so one less here tx_buf_ptr = pMsg; count_retry = MAX_SEND_TRIES; count_send_restart = MAX_RESTART_TRIES; CC2420_state = PRE_TX_STATE;// printk("in send, CC2420_state changed to: %d\n", CC2420_state); CC2420_set_initial_timer(Mac_initial_backoff() * CC2420_SYMBOL_UNIT);#ifndef PSI if(wait_event_interruptible(wq, send_done == 1)) { CC2420_state = IDLE_STATE;// printk("in send wait event failed, CC2420_state changed to: %d\n", CC2420_state); send_done = 1; wake_up_interruptible(&wq);//added by YC, wait up event set before// printk(KERN_INFO "wait failed after\n"); return FAIL; } send_done = 0;#endif return SUCCESS; } printk(KERN_INFO "System not idle\n"); return FAIL;}int CC2420_check_send_done(void){ if (send_done) { send_done = 0; return 1; } if ((CC2420_state < TX_STATE)|| (CC2420_state >= POST_TX_ACK_STATE)) return -1; return 0;}int CC2420_read(){#ifndef PSI // FIXME: the use of RX_STATE is broken -- not sure why it's here at all // basically the system should receive packets all the time, and then // they just get lost of nobody is trying to read them// CC2420_state = RX_STATE; //comment out by YC, this is the main reason casuing write failed after read.// printk("in read, CC2420_state changed to: %d\n", CC2420_state); if(!non_blocking_mode) {// printk("into read waiting\n"); if(wait_event_interruptible(rq, recv_done == 1)) {// CC2420_state = IDLE_STATE;// printk("in read wait failed, CC2420_state changed to: %d\n", CC2420_state); }// printk("out read waiting\n"); recv_done = 0; } else#endif { if (ok_to_read){ ok_to_read = 0; return SUCCESS; } else { return FAIL; } } return SUCCESS;}// to check if data in rxfifo int CC2420_read_poll(){ if(ok_to_read) return TRUE; else return FALSE;}/* * Tasklet function * Since FIFOP interrupt happened, read buffer from RXFIFO */void CC2420_read_packet(unsigned long unused) { uint8_t len = MSG_DATA_SIZE; uint8_t _is_packet_receiving;// printk("read read read\n"); if(!TEST_FIFO_PIN() && !TEST_FIFOP_PIN()) { CC2420_flush_RXFIFO(); CC2420_recv_failed(); return; } _is_packet_receiving = is_packet_receiving; if (_is_packet_receiving) { tasklet_schedule(&read_packet_tasklet); } else { is_packet_receiving = TRUE; } if (!_is_packet_receiving) {// printk(KERN_INFO "packet is being read\n"); if (!CC2420_read_RXFIFO (&len, (uint8_t*)rx_buf_ptr)) { is_packet_receiving = FALSE;// printk(KERN_INFO "read_RXFIFO failed\n"); CC2420_flush_RXFIFO(); CC2420_recv_failed(); // tasklet_schedule(&read_packet_tasklet); return; } } CC2420_flush_RXFIFO(); rx_packet_length = len; CC2420_RXFIFO_done(len); }/* * After the buffer is received from the RXFIFO, * process it */uint8_t CC2420_RXFIFO_done(uint8_t length) { uint8_t current_state = CC2420_state; uint8_t * data = (uint8_t *)rx_buf_ptr; //printk(KERN_INFO "rxfifo_done: length is %d\n", length); // if a FIFO overflow occurs or if the data length is invalid, flush // the RXFIFO to get back to a normal state. if((!TEST_FIFO_PIN() && !TEST_FIFOP_PIN()) || (length == 0) || (length > MSG_DATA_SIZE)) { CC2420_flush_RXFIFO(); is_packet_receiving = FALSE; CC2420_recv_failed();// printk(KERN_INFO "fifo overflow\n"); return SUCCESS; } // check for an acknowledgement that passes the CRC check if (is_ack_enable && (current_state == POST_TX_STATE) && ((rx_buf_ptr->fcfhi & 0x07) == CC2420_DEF_FCF_TYPE_ACK) && (rx_buf_ptr->dsn == current_DSN) && ((data[length-1] >> 7) == 1)) { CC2420_state = POST_TX_ACK_STATE;// printk("in RXFIFO_done, CC2420_state changed to: %d\n", CC2420_state); tx_buf_ptr->ack = 1; tx_buf_ptr->strength = data[length-2]; tx_buf_ptr->lqi = data[length-1] & 0x7F; is_packet_receiving = FALSE; CC2420_packet_sent(); // printk(KERN_INFO "recv ACK!\n");// printk(KERN_INFO "valid ack\n"); return SUCCESS; }#if 0 // All packets should be passed to the higher // layers and then sorted out there. We shouldn't really // be filtering on the fcf at this layer. // check for invalid packets // an invalid packet is a non-data packet with the wrong // addressing mode (FCFLO byte) if (((rx_buf_ptr->fcfhi & 0x07) != CC2420_DEF_FCF_TYPE_DATA) || (rx_buf_ptr->fcflo != CC2420_DEF_FCF_LO)) { CC2420_flush_RXFIFO(); is_packet_receiving = FALSE; CC2420_recv_failed(); printk(KERN_INFO "invalid packet\n"); return SUCCESS; }#endif { int len = rx_buf_ptr->length; len -= MSG_HEADER_SIZE + MSG_FOOTER_SIZE + 1; if (len < 0) len = 0;// printk("Length convert from %d to %d\n",rx_buf_ptr->length,len); rx_buf_ptr->length = len; } if (rx_buf_ptr->length > TOSH_DATA_LENGTH) { printk(KERN_INFO "bad length: %d > %d\n",rx_buf_ptr->length,TOSH_DATA_LENGTH); CC2420_flush_RXFIFO(); is_packet_receiving = FALSE; CC2420_recv_failed(); return SUCCESS; } // adjust destination to the right byte order rx_buf_ptr->addr = fromLSB16(rx_buf_ptr->addr); // if the length is shorter, we have to move the CRC bytes rx_buf_ptr->crc = data[length-1] >> 7; // put in RSSI rx_buf_ptr->strength = data[length-2]; // put in LQI rx_buf_ptr->lqi = data[length-1] & 0x7F; CC2420_packet_rcvd(); if(!TEST_FIFO_PIN() && !TEST_FIFOP_PIN()){ CC2420_flush_RXFIFO(); return SUCCESS; } if(!TEST_FIFOP_PIN()){ tasklet_schedule(&read_packet_tasklet); return SUCCESS; } CC2420_flush_RXFIFO(); // printk(KERN_INFO "end of RXFIFO\n"); return SUCCESS;}irqreturn_t CC2420_timer_irq_handler(int irq, void *dev, struct pt_regs *regs){ uint8_t current_state = CC2420_state;// printk(KERN_INFO "Timer IRQ %d happened \n",CC2420_timer_state); if(timer_channel_check() == SUCCESS) { switch (CC2420_timer_state) { case TIMER_INITIAL:// printk("timer is INITIAL\n"); CC2420_start_send();// printk("start send\n"); CC2420_try_to_send(); // printk("try to send\n"); break; case TIMER_BACKOFF:// printk("backoff timer\n"); CC2420_try_to_send(); break; case TIMER_ACK: if (current_state == POST_TX_STATE) {// printk(KERN_INFO "No ACK received\n"); tx_buf_ptr->ack = 0; CC2420_state = POST_TX_ACK_STATE;// printk("in timer irq, CC2420_state changed to: %d\n", CC2420_state); CC2420_packet_sent(); }// printk("ack timer\n"); break; case TIMER_RESTART: CC2420_start_send(); CC2420_try_to_send(); break; case TIMER_TRANSMIT:// while(TEST_SFD_PIN()){// printk("wait for transmit\n");// udelay(2); // }#ifdef PSI P1IFG |= CC2420_SFD; // trigger SW interrupt to simulate SFD
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -