
//[i] color english_UL,
LOAD ModuleLib system\language\english_UL.txt,

//无线通信模块nrf2401
//芯片:	处理器无关代码

//版本:	在版本v0中固定发送4个字节数据,这个版本改成了6个数据;
//可以设置超时时间

//2013年3月12日 把程序改成事件驱动方式, 去掉了超时时间,模式转换等;

NRF2401
[
	public link io []
	
	//[i] var OS_time,
	N8 OS_time,
	
	//[i] event receive_event,
	public link V receive_event: end.
	
	T OS_event_receive_OK,
	
	//[i] var buffer,
	public [N8*LENGTH] buffer,
	
	N8 LENGTH = A NUM 6,
	[N8*5] local_address,
	[N8*5] target_address,
	
	//---------------------------------------------------
	//[i] function OS_init,
	public V OS_init:
		port_init,
		spi init,
		set CONFIG 0b0000_1111,	//CRC使能，16位CRC校验，上电,接收模式
		set EN_AA 0x01,			//使能接收通道0自动应答
		set EN_RXADDR 0x01,		//使能接收通道0
		set SETUP_AW 0x03,		//设置地址宽度 5个字节
		set SETUP_RETR 0xff,		//自动重发延时等待4000us+86us，自动重发15次
		set RF_CH 40,			//选择射频通道40
		set RF_SETUP 0x07,		//数据传输率1Mbps，发射功率0dBm，低噪声放大器增益
		N8 status = get STATUS,	//返回状态寄存器
		write_command FLUSH_TX,
		write_command FLUSH_RX,
		set STATUS (status | 0b0111_0000),//清除TX_DS或MAX_RT中断标志
		
		//补充的
		//接收通道0选择和发送通道相同有效数据宽度
		set RX_PW_P0 LENGTH,
		
		local_address 0 = 0x00,
		local_address 1 = 0x43,
		local_address 2 = 0x10,
		local_address 3 = 0x10,
		local_address 4 = 0x01,
		
		target_address 0 = 0x00,
		target_address 1 = 0x43,
		target_address 2 = 0x10,
		target_address 3 = 0x10,
		target_address 4 = 0x01,
		
		OS_set_receive_mode,
		
		OS_time = 1,
		OS_event_receive_OK = NO,
	end.
	//---------------------------------------------------
	//[i] function OS_run,
	public V OS_run:
		if io IRQ_IN == LOW,
			OS_event_receive_OK = YES,
		OK.
	end.
	//---------------------------------------------------
	//[i] function OS_event_receive_event,
	public V OS_event_receive_event:
		if OS_event_receive_OK,
			
			//从无线模块中读取数据
			read_buffer RD_RX_PLOAD buffer LENGTH,
			N8 sta = get STATUS,
			set STATUS sta,
			write_command FLUSH_RX,
			
			OS_event_receive_OK = NO,
			receive_event,
		OK.
	end.
	//---------------------------------------------------
	//[i] function send_buffer,
	public V send_buffer:
		
		OS_set_send_mode,
		
		//接收通道0选择和发送通道相同有效数据宽度
		set RX_PW_P0 LENGTH,
		
		io CE_OUT = LOW,
		//写数据包到TX FIFO
		write_buffer WR_TX_PLOAD buffer LENGTH,
		//写入发送地址
		write_buffer (WRITE_REG + TX_ADDR) target_address 5,
		//为了应答接收设备，接收通道0地址和发送地址相同
		write_buffer (WRITE_REG + RX_ADDR_P0) target_address 5,
		io CE_OUT = HIGH,
		
		//等待应答
		repeat until io IRQ_IN == LOW, ...
		N8 status = get STATUS,	//返回状态寄存器
		set STATUS status,  	//清除TX_DS或MAX_RT中断标志
		write_command FLUSH_TX,
		
		OS_set_receive_mode,
	end.
	//---------------------------------------------------
	//[i] function OS_isOK,
	public T OS_isOK:
		set RF_CH 0x03,
		if get RF_CH != 0x03,
			return NO.
		set RF_CH 0x40,
		if get RF_CH != 0x40,
			return NO.
		return YES,
	end.
	//---------------------------------------------------
	//[i] function OS_set_local_address
	public V OS_set_local_address (N8 index):
		local_address 0 = index,
	end.
	//---------------------------------------------------
	//[i] function OS_set_target_address
	public V OS_set_target_address (N8 index):
		target_address 0 = index,
	end.
	//--------------------------------
	//[i] function OS_to_normal_mode,
	public V OS_to_normal_mode:
		N8 c = get CONFIG,
		c | 0b0000_0010,
		set CONFIG c,
	end.
	//--------------------------------
	//[i] function OS_to_power_down_mode,
	public V OS_to_power_down_mode:
		N8 c = get CONFIG,
		c & 0b1111_1101,
		set CONFIG c,
	end.
	//--------------------------------
	public V OS_set_receive_mode:
		io CE_OUT = LOW,
		//写入接收通道地址
		write_buffer (WRITE_REG + RX_ADDR_P0) local_address 5,
		N8 c = get CONFIG,
		c | 0b0000_0001,
		set CONFIG c,
		io CE_OUT = HIGH,
	end.
	//--------------------------------
	public V OS_set_send_mode:
		io CE_OUT = LOW,
		N8 c = get CONFIG,
		c & 0b1111_1110,
		set CONFIG c,
		io CE_OUT = HIGH,
	end.
	//--------------------------------
	V write_command (N8 cmd):
		io CSN_OUT = LOW,
		spi write_byte cmd,
		io CSN_OUT = HIGH,
	end.
	//--------------------------------
	//把p_buf缓存中的数据写入到nRF24L01，通常用来写入发射通道数据或接收/发送地址
	V write_buffer (N8 reg) ([N8*?] p_buf) (N8 length):
		io CSN_OUT = LOW,
		spi write_byte reg,
		repeat first N8 i = 0, each i + 1, until i == length,
			spi write_byte (p_buf i),
			...
		io CSN_OUT = HIGH,
	end.
	//--------------------------------
	//读取nRF2401某个缓冲区内容
	V read_buffer (N8 reg) ([N8*?]p_buf) (N8 length):
		io CSN_OUT = LOW,
		spi write_byte reg,
		repeat first N8 i = 0, each i + 1, until i == length,
			p_buf i = spi read_byte,
			...
		io CSN_OUT = HIGH,
	end.
	//---------------------------------------------------
	//写寄存器
	V set (N8 addr) (N8 data):
		io CSN_OUT = LOW,
		spi write_byte (WRITE_REG + addr),
		spi write_byte data,
		io CSN_OUT = HIGH,
	end.
	//读寄存器
	N8 get (N8 addr):
		io CSN_OUT = LOW,
		spi write_byte (READ_REG + addr),
		N8 data = spi read_byte,
		io CSN_OUT = HIGH,
		return data,
	end.
	//=================================================================================
	N8 CONFIG = 	A NUM 0x00,  //'Config'
	N8 EN_AA = 		A NUM 0x01,  //'Enable Auto Acknowledgment'
	N8 EN_RXADDR = 	A NUM 0x02,  //'Enabled RX addresses'
	N8 SETUP_AW = 	A NUM 0x03,  //'Setup address width'
	N8 SETUP_RETR = 	A NUM 0x04,  //'Setup Auto. Retrans'
	N8 RF_CH = 		A NUM 0x05,  //'RF channel'
	N8 RF_SETUP = 	A NUM 0x06,  //'RF setup'
	N8 STATUS = 	A NUM 0x07,  //'Status'
	N8 OBSERVE_TX = 	A NUM 0x08,  //'Observe TX'
	N8 CD = 		A NUM 0x09,  //'Carrier Detect'
	N8 RX_ADDR_P0 = 	A NUM 0x0A,  //频道0接收数据地址
	N8 RX_ADDR_P1 = 	A NUM 0x0B,  //'RX address pipe1'
	N8 RX_ADDR_P2 = 	A NUM 0x0C,  //'RX address pipe2'
	N8 RX_ADDR_P3 = 	A NUM 0x0D,  //'RX address pipe3'
	N8 RX_ADDR_P4 = 	A NUM 0x0E,  //'RX address pipe4'
	N8 RX_ADDR_P5 = 	A NUM 0x0F,  //'RX address pipe5'
	N8 TX_ADDR = 	A NUM 0x10,  //'TX address'
	N8 RX_PW_P0 = 	A NUM 0x11,  //接收频道0接收数据长度
	N8 RX_PW_P1 = 	A NUM 0x12,  //'RX payload width, pipe1'
	N8 RX_PW_P2 = 	A NUM 0x13,  //'RX payload width, pipe2'
	N8 RX_PW_P3 = 	A NUM 0x14,  //'RX payload width, pipe3'
	N8 RX_PW_P4 = 	A NUM 0x15,  //'RX payload width, pipe4'
	N8 RX_PW_P5 = 	A NUM 0x16,  //'RX payload width, pipe5'
	N8 FIFO_STATUS = 	A NUM 0x17,  //'FIFO Status Register'
	//SPI nRF24L01 commands
	N8 READ_REG =	A NUM 0x00,  //Define read command to register
	N8 WRITE_REG =	A NUM 0x20,  //Define write command to register
	N8 RD_RX_PLOAD =	A NUM 0x61,  //Define RX payload register address
	N8 WR_TX_PLOAD =	A NUM 0xA0,  //Define TX payload register address
	N8 FLUSH_TX =	A NUM 0xE1,  //Define flush TX register command
	N8 FLUSH_RX =	A NUM 0xE2,  //Define flush RX register command
	N8 REUSE_TX_PL =	A NUM 0xE3,  //Define reuse TX payload register command
	N8 NOP =		A NUM 0xFF,  //Define No Operation, might be used to read status register
	
	//SPI串行接口元件,高位在前,低位在后
	spi SCK_DIR -> io SCK_DIR, spi SCK_IN -> io SCK_IN, spi SCK_OUT -> io SCK_OUT,
	spi MISO_DIR -> io MISO_DIR, spi MISO_IN -> io MISO_IN, spi MISO_OUT -> io MISO_OUT,
	spi MOSI_DIR -> io MOSI_DIR, spi MOSI_IN -> io MOSI_IN, spi MOSI_OUT -> io MOSI_OUT,
	
	LOAD CurrentDir [BOARD].txt,
]
































