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

📄 mac.c

📁 一个WSN的树状路由,对于那些学WSN路由方面的朋友应该有说帮助.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
****************************************************************************
*              宁波中科集成电路设计中心  版权所有 Copyright 2005
*						http:\\www.nbicc.com
*文件名:  mac.c
*程序员:  夏鹏		xpsonny@nbicc.com
*主要内容:MAC层

*如有问题或BUG,请登录www.wsn.net.cn 提问或用邮件和作者联系
****************************************************************************
*/
/////
#include "led.h"
////
#include "os.h"
#include "mac.h"
#include "message.h"
#include "macClock.h"
#include "global.h"
#include "physical.h"
#include "fun.h"
#include "dataqueue.h"
#include "radiocontrol.h" // 载波监听
#include <avr/io.h>
#include <avr/interrupt.h>

//内部函数声明
static result_t MACTxReset(void);								// 清空所有发送任务
static void handleRTS(void* packet);
static void handleCTS(void* packet);
static void* handleDATA(void* packet);
static void handleACK(void* packet);
static void startBcast(void);
//static void sendRTS(void);
//static void sendCTS(void);
//static void sendDATA(void);
static void sendACK(uint8_t DataSrcAddr);
static void startACK(void);
static void tryToSend(void);

static void SetWaitTime(void);

// MAC层状态
enum {
	SLEEP,
	IDLE,
	CARR_SENSE,
	TX_PKT,
	BACKOFF,
	WAIT_CTS,
	WAIT_DATA,
	WAIT_ACK
};

// 射频状态
enum { RADIO_SLEEP, RADIO_IDLE, RADIO_RX, RADIO_TX };

// 发送方式
enum { BCAST_DATA, SEND_SYNC, SEND_RTS, SEND_CTS, SEND_DATA, SEND_ACK };
//enum { BCAST_DATA,SEND_CTRL};

// MAC 数据包类型
enum { RTS_PKT, CTS_PKT, DATA_PKT, ACK_PKT };


// 状态变量
static char state;		// MAC 状态变量
//static char ctrlstate; //MAC层的控制状态,主要用于RTS/CTS 以及ACK的控制
static char oldstate;
static char radioState;	 

// 发送相关变量
static char txRequest;			// 是否接受了一个发送请求,且未发送
static char howToSend;			// 发送包方式
static uint8_t txPktLen;		// 传输的数据包长度
static uint8_t ctrlPktLen;     //  传输的控制包长度
static OSMACMsgPtr dataPkt;    // MAC包头指针
static OSMACCtrlMsg ctrlPkt;	// 控制包
static OSMACCtrlMsgPtr ctrlPktPt;
static uint8_t AckWaitTime;


/**********************************************************************************
  初始化:
  等待控制包的时间:timeWaitCtrl
**********************************************************************************/
result_t MACInit()									
{
	// 初始化状态变量
	state = IDLE;
	//ctrlstate = IDLE;
	oldstate = IDLE;
	radioState = RADIO_IDLE;
	
	// 初始化发送相关变量
	txRequest = 0;
	AckWaitTime = 0;

	// 初始化随机数生成器
	RandomInit();
	// 初始化缓冲队列
	QueueInit();
    //mac层tick时钟初始化
	ClockStart();	
	// 初始化物理层
	PhysicalInit();
	
	return SUCCESS;
} 
/*************************************************************************
*功能描述:发送ack开始,开始空闲监听,准备发送ack数据包
*参数说明:
*返回值:
*************************************************************************/
static void tryToSendACK(void){
	startACK();
}
/*************************************************************************
*功能描述:发送数据包的开始,开始空闲监听,准备发送广播或者RTS数据包
*参数说明:
*返回值:  
**************************************************************************/
static void tryToSend()														// 判断是否允许发送,如果是,则进行监听
{
	char intEnabled;
	if (state == IDLE) {													// 空闲时
        howToSend = BCAST_DATA;
		// 开始载波监听,采用原子操作,防止起始字符检测到调用
		intEnabled = inp(SREG) & 0x80;
		cli();
		if (RadiocontrolCarrierSenseStart(80) == SUCCESS) {			// 调用监听函数
            state = CARR_SENSE;
		}
		else {
			txRequest =0;
			
		}
		if(intEnabled)
			sei();
	} 
	else {
	
	txRequest =0;  //去锁 
	
	}
	return;
}

/*************************************************************************
*功能描述:发送广播数据包的接口函数
*参数说明:包地址,包长度(MAC包数据部分的长度)
*返回值:  
**************************************************************************/
result_t MACBroadcastMsg(void* data, uint8_t length)
{   
    char intEnabled;					

	// 错误的发送方式
	if (data == 0 || length == 0 || length > MAX_PKT_LEN - MAC_HEADER_LEN) {
		return FAIL;
	}

	// 设置发送请求标识
	intEnabled = inp(SREG) & 0x80;
	cli();

	if ((txRequest == 0)&&(AckWaitTime == 0)) {
		txRequest = 1;
		if (intEnabled) sei();
	} else {     
		if (intEnabled) sei();
		return FAIL;
	}

	dataPkt = (OSMACMsgPtr)data;
	txPktLen = length + MAC_HEADER_LEN;
	// 数据包包头设置
	dataPkt->type = DATA_PKT;  
	dataPkt->toAddr = OS_BCAST_ADDR;
	dataPkt->fromAddr = OS_LOCAL_ADDRESS;
	dataPkt->group = 0x01;

    tryToSend();
    
	return SUCCESS;
}

/*************************************************************************
*功能描述:发送单播数据包的接口函数
*参数说明:包地址,包长度(包括包头),目的地址
*返回值:  
**************************************************************************/
result_t MACUnicastMsg(void* data, uint8_t length, uint8_t toAddr)
{
   	char intEnabled;					

	// 错误的发送方式
	if (data == 0 || length == 0 || length > MAX_PKT_LEN - MAC_HEADER_LEN) {
		return FAIL;
	}

	// 设置发送请求标识
	intEnabled = inp(SREG) & 0x80;
	cli();

	if ((txRequest == 0)&&(AckWaitTime == 0)) {
		txRequest = 1;
		if (intEnabled) sei();
	} else {     
		if (intEnabled) sei();
		return FAIL;
	}
    
	dataPkt = (OSMACMsgPtr)data;
	txPktLen = length + MAC_HEADER_LEN;
	// 数据包包头设置
	dataPkt->type = DATA_PKT;  
	dataPkt->toAddr = toAddr;
	dataPkt->fromAddr = OS_LOCAL_ADDRESS;
	dataPkt->group = 0x01;

    tryToSend();

	
	return SUCCESS;
}

/*************************************************************************
*功能描述:发送ack任务
*参数说明:无
*返回值:  
**************************************************************************/
static void sendACK(uint8_t DataSrcAddr){
    // 控制包初始化
	ctrlPkt.fromAddr = OS_LOCAL_ADDRESS;
    ctrlPkt.type = ACK_PKT;
	ctrlPkt.group = 0x01;
	ctrlPkt.ack = 0x06;
	ctrlPkt.length = 1;
    ctrlPktPt = &ctrlPkt; 
    ctrlPktPt->toAddr = DataSrcAddr;
	ctrlPktLen = 1 + MAC_HEADER_LEN;
	tryToSendACK();
}
/*************************************************************************
*功能描述:强行取消所有正在发送的任务
*参数说明:无
*返回值:  
**************************************************************************/

static result_t MACTxReset()
{   
    radioState = RADIO_IDLE;
	txRequest = 0;	
	state = IDLE;
	oldstate = IDLE;
    return SUCCESS;
}

/*************************************************************************
*功能描述:发送广播包
*参数说明:无
*返回值:  
**************************************************************************/
static void startBcast()					
{							
	PhysicalTxPkt(dataPkt, txPktLen);		// 调用物理层发送接口发送数据包
	radioState = RADIO_TX;
	state = TX_PKT;

}
/*************************************************************************
*功能描述:发送ack帧
*参数说明:
*返回值:  
**************************************************************************/

static void startACK()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -