⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cc2420.c

📁 无线发射
💻 C
📖 第 1 页 / 共 3 页
字号:
{    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 + -