|
|
View previous topic :: View next topic |
Author |
Message |
705150
Joined: 25 Apr 2013 Posts: 14
|
RFM73 problem |
Posted: Fri May 22, 2015 1:43 am |
|
|
i am once again in need of your help, I have large difficulties making this rf transmitter to work. I have looked at the
http://www.ccsinfo.com/forum/viewtopic.php?t=43563&postdays=0&postorder=asc&start=0 and the links on it, as well as searched our dearest google for help. I have build this source code, witch is almost the same for the transmitter and receiver, the difference is one line that is commented (not to send only to receive
the main code is
Code: | #include <16f887.h>
#use delay( clock=8000000,INTERNAL) // clock 8 mhz int
#FUSES INTRC_IO,NOPUT,NOMCLR,NOCPD,NOBROWNOUT,NOIESO,NOFCMEN,NOLVP, noWDT
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#define soft_ver 1053.01
#define second 7100
int16 update1=0;
//int16 csn=0;
//#include "..\RFM73_init.c"
#include "RFM73.h"
#include "RFM73_init.c "
#define led_toggle output_toggle(pin_d3)
#ifndef functions //ok
void init_mcu(void);
void init_port(void);
void timer2_init(void);
void sub_program_1hz(void);
void Send_Packet(unsigned int type,unsigned int* pbuf,unsigned int len);
void Send_NACK_Packet(void);
void Receive_Packet(int8 origin);
void SPI_Bank1_Write_Reg(unsigned int reg, unsigned int *pBuf);
void SPI_Bank1_Read_Reg(unsigned int reg, unsigned int *pBuf);
void Carrier_Test(unsigned int b_enable); //carrier test
extern void RFM73_Initialize(void);
extern void SwitchToTxMode(void);
extern void SwitchToRxMode(void);
#endif
#ifndef vars //ok
const unsigned int tx_buf[17]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x78};
unsigned int rx_buf[MAX_PACKET_LEN];
//extern const unsigned int RX0_Address[];
//extern const unsigned long Bank1_Reg0_13[];
unsigned int test_data;
//__CONFIG(0x3fd4);
unsigned char i, j, chksum;
#endif
#int_timer2
void isr_timer2(void) {
update1++;
}
#INT_RB
void port_b_irq() {
int8 reset_b=input_b();
Receive_Packet(1);
}
void main() {
output_high(pin_d3);
delay_ms(50);
enable_interrupts(INT_TIMER2); //enable timer2 interrupt
enable_interrupts(GLOBAL); //enable all interrupts (else timer2 wont happen)
enable_interrupts(INT_RB);
enable_interrupts(INT_RB5);
setup_timer_2(T2_DIV_BY_1,255,1);
//setup_spi(SPI_MASTER);
init_port();
//INTCON = 0xc0; // enable interrupt
RFM73_Initialize();
delay_ms(50);
sub_program_1hz();
output_low(pin_d3);
while(1) {
if (!IRQ_IN) Receive_Packet(1);
if (update1>=second) {
//Receive_Packet(0);
update1=0;
//led_toggle;
sub_program_1hz();
}
}
}
void init_port(void)
{
//ANSEL = 0;
//ANSELH = 0;
//WPUB = 0;
CE_OUT;
CSN_OUT;
SCK_OUT;
MISO_IN;
MOSI_OUT;
IRQ_IN;
CE;
CSN;
SCK;
MOSI;
printf("\n\rend_init_port");
}
void sub_program_1hz(void)
{
unsigned int i;
unsigned int temp_buf[32];
for(i=0;i<17;i++)
{
temp_buf[i]=tx_buf[i];
}
Send_Packet(W_TX_PAYLOAD_NOACK_CMD,temp_buf,17);
SwitchToRxMode(); //switch to Rx mode
}
/**************************************************
Function: Send_Packet
Description:
fill FIFO to send a packet
Parameter:
type: WR_TX_PLOAD or W_TX_PAYLOAD_NOACK_CMD
pbuf: a buffer pointer
len: packet length
Return:
None
**************************************************/
void Send_Packet(unsigned int type,unsigned int* pbuf,unsigned int len)
{
unsigned int fifo_sta;
SwitchToTxMode(); //switch to tx mode
fifo_sta=SPI_Read_Reg(FIFO_STATUS); // read register FIFO_STATUS's value
if((fifo_sta&FIFO_STATUS_TX_FULL)==0)//if not full, send data (write buff)
{
//led_toggle;
SPI_Write_Buf(type, pbuf, len); // Writes data to buffer
}
}
/**************************************************
Function: Receive_Packet
Description:
read FIFO to read a packet
Parameter:
None
Return:
None
**************************************************/
void Receive_Packet(int8 origin)
{
unsigned int len,i,sta,fifo_sta,chksum;
unsigned int rx_buf[MAX_PACKET_LEN];
sta=SPI_Read_Reg(STATUS); // read register STATUS's value
if (!origin) printf("\n\r running 0x%x", sta);
if (origin==1) printf("\n\r irq detected 0x%x", sta);
if((STATUS_RX_DR&sta) == 0x40) { // if receive data ready (RX_DR) interrupt
led_toggle;
do {
len=SPI_Read_Reg(R_RX_PL_WID_CMD); // read len
if(len<=MAX_PACKET_LEN)
{
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,len);// read receive payload from RX_FIFO buffer
}
else
{
SPI_Write_Reg(FLUSH_RX,0);//flush Rx
}
fifo_sta=SPI_Read_Reg(FIFO_STATUS); // read register FIFO_STATUS's value
}
while((fifo_sta&FIFO_STATUS_RX_EMPTY)==0); //while not empty
//output_low(pin_d3);
chksum = 0;
for(i=0;i<16;i++)
{
chksum +=rx_buf[i];
}
if(chksum==rx_buf[16]&&rx_buf[0]==0x30) {
//Send_Packet(W_TX_PAYLOAD_NOACK_CMD,rx_buf,17);
SwitchToRxMode();//switch to RX mode
}
}
SPI_Write_Reg(WRITE_REG|STATUS,sta);// clear RX_DR or TX_DS or MAX_RT interrupt flag
//CSN_OUT;
}
|
the RFM73.h code is
Code: | //Z:\examples_mplab\18f46k80_rfm73_test1\RFM73.h
/*********************************************************
copyright(c) 2012
Title: RFM73 simple example based on PIC c
Current version: v1.0
Function: RFM73 demo
processor: PIC16F690
Clock: internal RC 8M
Author: baiguang(ISA)
Company: Hope microelectronic Co.,Ltd.
Contact: +86-0755-82973805-846
E-MAIL: rfeng@hoperf.com
Data: 2012-11-10
**********************************************************/
/*********************************************************
---------------
|VDD VSS|
IRQ ---- |RA5 RA0| ----CE
MOSI---- |RA4 RA1| ----CSN
MISO---- |RA3 RA2| ----SCK
---- |RC5 RC0| ----
---- |RC4 RC1| ----
---- |RC3 RC2| ----
---- |RC6 RB4| ----
---- |RC7 RB5| ----
---- |RB7 RB6| ----
---------------
pic16F690
*********************************************************/
/*--------------------------------------------------------------------------------------
*This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
*****************
*MCU: PIC16f690
Compiler:MPLAB8.10
*****************
* website: http://www.hoperf.com
---------------------------------------------------------------------------------------*/
#ifndef _RFM73_H_
#define _RFM73_H_
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#define INT8 char
#define INT16 int
#define UINT8 unsigned char
#define UINT16 unsigned int
#define UINT32 unsigned long
#define rfm73_ce pin_d0 //d0
#define rfm73_csn pin_d1 //d1
#define rfm73_sck pin_c3 //c3
#define rfm73_miso pin_c4 //c4
#define rfm73_mosi pin_c5 //c5
#define rfm73_irq pin_b5 //b5
#define CE output_high(rfm73_ce) //***high d0
#define CSN output_high(rfm73_csn) //***high d1
#define SCK output_high(rfm73_sck) //high c3
#define MISO input_state(rfm73_miso) //c4 c4
#define MOSI output_high(rfm73_mosi) //c5 c5
#define IRQ
#define CE_OUT output_low(rfm73_ce)
#define CSN_OUT output_low(rfm73_csn)
#define SCK_OUT output_low(rfm73_sck)
#define MISO_IN input_state(rfm73_miso)
#define MOSI_OUT output_low(rfm73_mosi)
#define IRQ_IN input_state(pin_b5)
#define MAX_PACKET_LEN 32// max value is 32
//************************FSK COMMAND and REGISTER****************************************//
// SPI(RFM73) commands
#define READ_REG 0x00 // Define read command to register
#define WRITE_REG 0x20 // Define write command to register
#define RD_RX_PLOAD 0x61 // Define RX payload register address
#define WR_TX_PLOAD 0xA0 // Define TX payload register address
#define FLUSH_TX 0xE1 // Define flush TX register command
#define FLUSH_RX 0xE2 // Define flush RX register command
#define REUSE_TX_PL 0xE3 // Define reuse TX payload register command
#define W_TX_PAYLOAD_NOACK_CMD 0xb0
#define W_ACK_PAYLOAD_CMD 0xa8
#define ACTIVATE_CMD 0x50
#define R_RX_PL_WID_CMD 0x60
#define NOP_NOP 0xFF // Define No Operation, might be used to read status register
// SPI(RFM73) registers(addresses)
#define CONFIG 0x00 // 'Config' register address
#define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address
#define EN_RXADDR 0x02 // 'Enabled RX addresses' register address
#define SETUP_AW 0x03 // 'Setup address width' register address
#define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address
#define RF_CH 0x05 // 'RF channel' register address
#define RF_SETUP 0x06 // 'RF setup' register address
#define STATUS 0x07 // 'Status' register address
#define OBSERVE_TX 0x08 // 'Observe TX' register address
#define CD 0x09 // 'Carrier Detect' register address
#define RX_ADDR_P0 0x0A // 'RX address pipe0' register address
#define RX_ADDR_P1 0x0B // 'RX address pipe1' register address
#define RX_ADDR_P2 0x0C // 'RX address pipe2' register address
#define RX_ADDR_P3 0x0D // 'RX address pipe3' register address
#define RX_ADDR_P4 0x0E // 'RX address pipe4' register address
#define RX_ADDR_P5 0x0F // 'RX address pipe5' register address
#define TX_ADDR 0x10 // 'TX address' register address
#define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address
#define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address
#define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address
#define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address
#define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address
#define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address
#define FIFO_STATUS 0x17 // 'FIFO Status Register' register address
#define PAYLOAD_WIDTH 0x1f // 'payload length of 256 bytes modes register address
//interrupt status
#define STATUS_RX_DR 0x40
#define STATUS_TX_DS 0x20
#define STATUS_MAX_RT 0x10
#define STATUS_TX_FULL 0x01
//FIFO_STATUS
#define FIFO_STATUS_TX_REUSE 0x40
#define FIFO_STATUS_TX_FULL 0x20
#define FIFO_STATUS_TX_EMPTY 0x10
#define FIFO_STATUS_RX_FULL 0x02
#define FIFO_STATUS_RX_EMPTY 0x01
UINT8 SPI_Read_Reg(UINT8 reg);
void SPI_Read_Buf(UINT8 reg, UINT8 *pBuf, UINT8 bytes);
void SPI_Write_Reg(UINT8 reg, UINT8 value);
//void SPI_Write_Reg_Bank0(const UINT8 reg, const UINT8 value);
//void SPI_Write_Buf(UINT8 reg, UINT8 *pBuf, UINT8 bytes);
void SPI_Write_Buf(UINT8 reg, UINT8 *pBuf, UINT8 length);
void SPI_Write_Buf_bank(UINT8 reg, UINT8 *pBuf, UINT8 length);
void SwitchToTxMode(void);
void SwitchToRxMode(void);
void SPI_Bank1_Read_Reg(UINT8 reg, UINT8 *pBuf);
void SPI_Bank1_Write_Reg(UINT8 reg, UINT8 *pBuf);
void SwitchCFG(char _cfg);
void RFM73_Initialize(void);
void DelayMs(UINT16 ms);
#endif
|
and the RFM73_init.c code is
Code: | UINT8 op_status;
//Bank1 register initialization value
//In the array RegArrFSKAnalog,all the register value is the byte reversed!!!!!!!!!!!!!!!!!!!!!
const unsigned long Bank1_Reg0_13[]={ //latest config txt
0xE2014B40,
0x00004BC0,
0x028CFCD0,
0x41390099,
0x1B8296d9,
0xA67F0224,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00127300,
0x46B48000,
};
const UINT8 Bank1_Reg14[]=
{
0x41,0x20,0x08,0x04,0x81,0x20,0xCF,0xF7,0xFE,0xFF,0xFF
};
//Bank0 register initialization value
const UINT8 Bank0_Reg[][2]={
{0,0x0F},//reflect RX_DR\TX_DS\MAX_RT,Enable CRC ,2byte,POWER UP,PRX
{1,0x3F},//Enable auto acknowledgement data pipe5\4\3\2\1\0
{2,0x3F},//Enable RX Addresses pipe5\4\3\2\1\0
{3,0x03},//RX/TX address field width 5byte
{4,0xff},//auto retransmission dalay (4000us),auto retransmission count(15)
{5,0x17},//23 channel
{6,0x07},//air data rate-1M,out power 0dbm,setup LNA gain \bit4 must set up to 0
{7,0x07},//
{8,0x00},//
{9,0x00},
{12,0xc3},//only LSB Receive address data pipe 2, MSB bytes is equal to RX_ADDR_P1[39:8]
{13,0xc4},//only LSB Receive address data pipe 3, MSB bytes is equal to RX_ADDR_P1[39:8]
{14,0xc5},//only LSB Receive address data pipe 4, MSB bytes is equal to RX_ADDR_P1[39:8]
{15,0xc6},//only LSB Receive address data pipe 5, MSB bytes is equal to RX_ADDR_P1[39:8]
{17,0x20},//Number of bytes in RX payload in data pipe0(32 byte)
{18,0x20},//Number of bytes in RX payload in data pipe1(32 byte)
{19,0x20},//Number of bytes in RX payload in data pipe2(32 byte)
{20,0x20},//Number of bytes in RX payload in data pipe3(32 byte)
{21,0x20},//Number of bytes in RX payload in data pipe4(32 byte)
{22,0x20},//Number of bytes in RX payload in data pipe5(32 byte)
{23,0x00},//fifo status2
{28,0x3F},//Enable dynamic payload length data pipe5\4\3\2\1\0
{29,0x07}//Enables Dynamic Payload Length,Enables Payload with ACK,Enables the W_TX_PAYLOAD_NOACK command
};
const UINT8 RX0_Address[]={0x34,0x43,0x10,0x10,0x01};//Receive address data pipe 0
const UINT8 RX1_Address[]={0x39,0x38,0x37,0x36,0xc2};////Receive address data pipe 1
extern UINT8 test_data;
//extern UINT8 channel;
//extern UINT8 power;
//extern UINT8 data_rate;
extern UINT8 rx_buf[MAX_PACKET_LEN];
void delayus(int16 ms);
//extern void delay_200ms(void);
//extern void delay_50ms(void);
///////////////////////////////////////////////////////////////////////////////
// SPI access //
///////////////////////////////////////////////////////////////////////////////
/**************************************************
Function: SPI_RW();
Description:
Writes one UINT8 to RFM73, and return the UINT8 read
/**************************************************/
UINT8 SPI_RW(UINT8 value)
{
UINT8 bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
{
if(value & 0x80)
{
MOSI;
}
else
{
MOSI_out;
}
value = (value << 1); // shift next bit into MSB..
SCK_out; // Set SCK high..
value |= MISO; // capture current MISO bit
SCK; // ..then set SCK low again
}
return(value); // return read UINT8
}
/**************************************************
Function: SPI_Write_Reg();
Description:
Writes value 'value' to register 'reg'
/**************************************************/
void SPI_Write_Reg(UINT8 reg, UINT8 value)
{
CSN_OUT; // CSN low, init SPI transaction
op_status = SPI_RW(reg); // select register
SPI_RW(value); // ..and write value to it..
CSN; // CSN high again
}
/**************************************************/
/**************************************************
Function: SPI_Read_Reg();
Description:
Read one UINT8 from BK2421 register, 'reg'
/**************************************************/
UINT8 SPI_Read_Reg(UINT8 reg)
{
UINT8 value;
CSN_OUT; // CSN low, initialize SPI communication...
op_status=SPI_RW(reg); // Select register to read from..
value = SPI_RW(0); // ..then read register value
CSN; // CSN high, terminate SPI communication
return(value); // return register value
}
/**************************************************/
/**************************************************
Function: SPI_Read_Buf();
Description:
Reads 'length' #of length from register 'reg'
/**************************************************/
void SPI_Read_Buf(UINT8 reg, UINT8 *pBuf, UINT8 length)
{
UINT16 status2;
UINT8 byte_ctr;
CSN_OUT; // Set CSN l
status2 = SPI_RW(reg); // Select register to write, and read status2 UINT8
for(byte_ctr=0;byte_ctr<length;byte_ctr++)
pBuf[byte_ctr] = SPI_RW(0); // Perform SPI_RW to read UINT8 from RFM73
CSN; // Set CSN high again
}
/**************************************************/
/**************************************************
Function: SPI_Write_Buf();
Description:
Writes contents of buffer '*pBuf' to RFM73
/**************************************************/
void SPI_Write_Buf(UINT8 reg, UINT8 *pBuf, UINT8 length)
{
UINT8 byte_ctr;
CSN_OUT; // Set CSN low, init SPI tranaction
op_status = SPI_RW(reg); // Select register to write to and read status2 UINT8
for(byte_ctr=0; byte_ctr<length; byte_ctr++) // then write all UINT8 in buffer(*pBuf)
{
SPI_RW(*pBuf++);
}
CSN; // Set CSN high again
}
/**************************************************
Function: SwitchToRxMode();
Description:
switch to Rx mode
/**************************************************/
void SwitchToRxMode()
{
UINT8 value;
SPI_Write_Reg(FLUSH_RX,0);//flush Rx
value=SPI_Read_Reg(status); // read register status2's value
SPI_Write_Reg(WRITE_REG|status,value);// clear RX_DR or TX_DS or MAX_RT interrupt flag
CE;
value=SPI_Read_Reg(CONFIG); // read register CONFIG's value
//PRX
value=value|0x01;//set bit 1
SPI_Write_Reg(WRITE_REG | CONFIG, value); // Set PWR_UP bit, enable CRC(2 length) & Prim:RX. RX_DR enabled..
CE;
}
/**************************************************
Function: SwitchToTxMode();
Description:
switch to Tx mode
/**************************************************/
void SwitchToTxMode()
{
UINT8 value;
SPI_Write_Reg(FLUSH_TX,0);//flush Tx
CE;
value=SPI_Read_Reg(CONFIG); // read register CONFIG's value
//PTX
value=value&0xfe;//set bit 0
SPI_Write_Reg(WRITE_REG | CONFIG, value); // Set PWR_UP bit, enable CRC(2 length) & Prim:RX. RX_DR enabled.
CE_out;
}
/**************************************************
Function: SwitchCFG();
Description:
access switch between Bank1 and Bank0
Parameter:
_cfg 1:register bank1
0:register bank0
Return:
None
/**************************************************/
void SwitchCFG(char _cfg)//1:Bank1 0:Bank0
{
UINT8 Tmp;
Tmp=SPI_Read_Reg(7);
Tmp=Tmp&0x80;
if( ( (Tmp)&&(_cfg==0) ) || ( ((Tmp)==0)&&(_cfg) ) ) {
SPI_Write_Reg(ACTIVATE_CMD,0x53);
}
}
/**************************************************
Function: SetChannelNum();
Description:
set channel number
/**************************************************/
void SetChannelNum(UINT8 ch)
{
SPI_Write_Reg((UINT8)(WRITE_REG|5),(UINT8)(ch));
}
///////////////////////////////////////////////////////////////////////////////
// RFM73 initialization //
///////////////////////////////////////////////////////////////////////////////
/**************************************************
Function: RFM73_Initialize();
Description:
register initialization
/**************************************************/
void RFM73_Initialize()
{
UINT8 i,j;
UINT8 WriteArr[12];
//DelayMs(100);//delay more than 50ms.
delay_ms(20);
SwitchCFG(0);
for(i=0;i<20;i++)
{
SPI_Write_Reg((WRITE_REG|Bank0_Reg[i][0]),Bank0_Reg[i][1]);
}
/*//reg 10 - Rx0 addr
SPI_Write_Buf((WRITE_REG|10),RX0_Address,5);
//REG 11 - Rx1 addr
SPI_Write_Buf((WRITE_REG|11),RX1_Address,5);
//REG 16 - TX addr
SPI_Write_Buf((WRITE_REG|16),RX0_Address,5);*/
//reg 10 - Rx0 addr
for(j=0;j<5;j++)
{
WriteArr[j]=RX0_Address[j];
}
SPI_Write_Buf((WRITE_REG|10),&(WriteArr[0]),5);
//REG 11 - Rx1 addr
for(j=0;j<5;j++)
{
WriteArr[j]=RX1_Address[j];
}
SPI_Write_Buf((WRITE_REG|11),&(WriteArr[0]),5);
//REG 16 - TX addr
for(j=0;j<5;j++)
{
WriteArr[j]=RX0_Address[j];
}
SPI_Write_Buf((WRITE_REG|16),&(WriteArr[0]),5);
// printf("\nEnd Load Reg");
i=SPI_Read_Reg(29);//read Feature Register 如果要支持动态长度或者 Payload With ACK,需要先给芯片发送 ACTIVATE命令(数据为0x73),然后使能动态长度或者 Payload With ACK (REG28,REG29).
if(i==0) {// i!=0 showed that chip has been actived.so do not active again.
SPI_Write_Reg(ACTIVATE_CMD,0x73);// Active
}
for(i=22;i>=21;i--)
{
SPI_Write_Reg((WRITE_REG|Bank0_Reg[i][0]),Bank0_Reg[i][1]);
//SPI_Write_Reg_Bank0(Bank0_Reg[i][0],Bank0_Reg[i][1]);
}
//********************Write Bank1 register******************
SwitchCFG(1);
for(i=0;i<=8;i++)//reverse
{
for(j=0;j<4;j++)
WriteArr[j]=(Bank1_Reg0_13[i]>>(8*(j) ) )&0xff;
SPI_Write_Buf((WRITE_REG|i),&(WriteArr[0]),4);
}
for(i=9;i<=13;i++)
{
for(j=0;j<4;j++)
WriteArr[j]=(Bank1_Reg0_13[i]>>(8*(3-j) ) )&0xff;
SPI_Write_Buf((WRITE_REG|i),&(WriteArr[0]),4);
}
//SPI_Write_Buf((WRITE_REG|14),&(Bank1_Reg14[0]),11);
for(j=0;j<11;j++)
{
WriteArr[j]=Bank1_Reg14[j];
}
SPI_Write_Buf((WRITE_REG|14),&(WriteArr[0]),11);
//toggle REG4<25,26>
for(j=0;j<4;j++)
//WriteArr[j]=(RegArrFSKAnalog[4]>>(8*(j) ) )&0xff;
WriteArr[j]=(Bank1_Reg0_13[4]>>(8*(j) ) )&0xff;
WriteArr[0]=WriteArr[0]|0x06;
SPI_Write_Buf((WRITE_REG|4),&(WriteArr[0]),4);
WriteArr[0]=WriteArr[0]&0xf9;
SPI_Write_Buf((WRITE_REG|4),&(WriteArr[0]),4);
//**************************Test spi*****************************//
//SPI_Write_Reg((WRITE_REG|Bank0_Reg[2][0]),0x0f);
//test_data = SPI_Read_Reg(0x02);
//DelayMs(10);
delay_ms(50);
//********************switch back to Bank0 register access******************
SwitchCFG(0);
SwitchToRxMode();//switch to RX mode
}
/**************************************************
Function: DelayMs();
Description:
delay ms,please implement this function according to your MCU.
/**************************************************/
void delayus(int16 ms)
{
int16 i;
for(i=1; i<=ms; i++) ;
}
|
maybe this code might help others since this rf is getting more and more popular.
I have used a pickit2 logic analyzer (as oscilloscope since I don't have anything else) and see some logic responses to and from the rf on sck, spi, sdo
I have tried with 3 pieces so far. the model is the smd type.
I am running out of ideas. olso, the irq doesn't see anything.
many thanks for your understanding.
as compiler I used the 4.114 version, I also have 5.008 but it proved to have some problems with the 16f887 (i2c) in the past on some other project so I decided to go with a older compiler.
the voltage on the rfm73 is 3.3vdd so I connected all the pics at the same voltage rail. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri May 22, 2015 7:42 am |
|
|
Quote: | const unsigned long Bank1_Reg0_13[]={ //latest config txt
0xE2014B40,
0x00004BC0,
0x028CFCD0,
0x41390099,
0x1B8296d9,
0xA67F0224,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00127300,
0x46B48000,
}; |
Bug. This is a 32-bit table. It should be declared as int32. In CCS,
'unsigned long' means int16. So you are truncating the elements to
only 16 bits with your declaration as 'unsigned long'. You can see this
in the .LST file. Note only the two lower bytes of each array element are
in the compiled data:
Quote: | 0058: BCF PCLATH.0
0059: BCF PCLATH.1
005A: BCF PCLATH.2
005B: ADDWF PCL,F
005C: RETLW 40
005D: RETLW 4B
005E: RETLW C0
005F: RETLW 4B
0060: RETLW D0
0061: RETLW FC
0062: RETLW 99
0063: RETLW 00
.
.
.
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri May 22, 2015 2:50 pm |
|
|
It appears that you tried to translate this code:
http://www.hoperf.com/upload/rf/RFM73_transmiter_code%28Master%29.rar
Their code below (from the link given above) sets CE low, and then it sets CE high.
Quote: | void SwitchToRxMode()
{
UINT8 value;
SPI_Write_Reg(FLUSH_RX,0);//flush Rx
value=SPI_Read_Reg(STATUS); // read register STATUS's value
SPI_Write_Reg(WRITE_REG|STATUS,value);// clear RX_DR or TX_DS or MAX_RT interrupt flag
CE=0;
value=SPI_Read_Reg(CONFIG); // read register CONFIG's value
//PRX
value=value|0x01;//set bit 1
SPI_Write_Reg(WRITE_REG | CONFIG, value); // Set PWR_UP bit, enable CRC(2 length) & Prim:RX. RX_DR enabled..
CE=1;
} |
But then in your code below, you set CE high twice. That's not going to work:
Quote: |
#define CE output_high(rfm73_ce)
void SwitchToRxMode()
{
UINT8 value;
SPI_Write_Reg(FLUSH_RX,0);//flush Rx
value=SPI_Read_Reg(status); // read register status2's value
SPI_Write_Reg(WRITE_REG|status,value);// clear RX_DR or TX_DS or MAX_RT interrupt flag
CE;
value=SPI_Read_Reg(CONFIG); // read register CONFIG's value
//PRX
value=value|0x01;//set bit 1
SPI_Write_Reg(WRITE_REG | CONFIG, value); // Set PWR_UP bit, enable CRC(2 length) & Prim:RX. RX_DR enabled..
CE;
} |
In this routine below, you have the CE's the opposite of the way they
are supposed to be. CE is supposed to be set low at the start, and high
at the end.
Quote: | void SwitchToTxMode()
{
UINT8 value;
SPI_Write_Reg(FLUSH_TX,0);//flush Tx
CE;
value=SPI_Read_Reg(CONFIG); // read register CONFIG's value
//PTX
value=value&0xfe;//set bit 0
SPI_Write_Reg(WRITE_REG | CONFIG, value); // Set PWR_UP bit, enable CRC(2 length) & Prim:RX. RX_DR enabled.
CE_out;
} |
You should have given these symbols better names.
Instead of "CE", you should have called it "CE_high". And instead of
"CE_OUT", you should have called it "CE_low". That would be a lot more
descriptive of what the code is doing. Then you would make less
mistakes when translating their code.
Quote: |
#define CE output_high(rfm73_ce) //***high d0
#define CSN output_high(rfm73_csn) //***high d1
#define SCK output_high(rfm73_sck) //high c3
#define MISO input_state(rfm73_miso) //c4 c4
#define MOSI output_high(rfm73_mosi) //c5 c5
#define IRQ
#define CE_OUT output_low(rfm73_ce)
#define CSN_OUT output_low(rfm73_csn)
#define SCK_OUT output_low(rfm73_sck)
#define MISO_IN input_state(rfm73_miso)
#define MOSI_OUT output_low(rfm73_mosi)
#define IRQ_IN |
|
|
|
705150
Joined: 25 Apr 2013 Posts: 14
|
|
Posted: Tue May 26, 2015 4:16 am |
|
|
Thank you @PCM programmer for your reply. I don't know how i missed those HIGH/LOW settings, but i made a comparison between the code from their site and the code on my side. I have modified the int32 as suggested. modified the names for in rfm73 lines. Still no luck. I have split the code in 3 sources + the main.c. They are the same for the receiver and transmitter (except one is just transmitting and the other just receiving).
Perhaps some other bugs in my code can be found.
main.c Code: |
#include <16f887.h>
#use delay( clock=8000000,INTERNAL) // clock 8 mhz int
#FUSES INTRC_IO,NOPUT,NOMCLR,NOCPD,NOBROWNOUT,NOIESO,NOFCMEN,NOLVP, noWDT
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#define soft_ver 1053.01
#define second 7100
#define led_toggle output_toggle(pin_d3)
#define rfm73_ce pin_d0 //d0
#define rfm73_csn pin_d1 //d1
#define rfm73_sck pin_c3 //c3
#define rfm73_miso pin_c4 //c4
#define rfm73_mosi pin_c5 //c5
#define rfm73_irq pin_b5 //b5
#include "Z:\OneDrive\toshiba_nb200\examples_mplab\demo_16f887\RFM73.h"
#include "Z:\OneDrive\toshiba_nb200\examples_mplab\demo_16f887\RFM73_init.c "
#ifndef functions //ok
void init_mcu(void);
void init_port(void);
void timer2_init(void);
void sub_program_1hz(void);
void Send_Packet(unsigned int type,unsigned int* pbuf,unsigned int len);
void Send_NACK_Packet(void);
void Receive_Packet(int8 origin);
void SPI_Bank1_Write_Reg(unsigned int reg, unsigned int *pBuf);
void SPI_Bank1_Read_Reg(unsigned int reg, unsigned int *pBuf);
void Carrier_Test(unsigned int b_enable); //carrier test
extern void RFM73_Initialize(void);
extern void SwitchToTxMode(void);
extern void SwitchToRxMode(void);
#endif
#ifndef vars //ok
const unsigned int tx_buf[17]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x78};
unsigned int rx_buf[MAX_PACKET_LEN];
//extern const unsigned int RX0_Address[];
//extern const unsigned long Bank1_Reg0_13[];
unsigned int test_data;
//__CONFIG(0x3fd4);
unsigned char i, j, chksum;
#endif
int16 update1=0;
#include "Z:\OneDrive\toshiba_nb200\examples_mplab\demo_16f887\archive_rfm73\RFM73_functions.c"
#int_timer2
void isr_timer2(void) {
update1++; //keep a running timer that increments every milli-second
}
#INT_RB
void port_b_irq() {
int8 reset_b=input_b();
Receive_Packet(1);
}
void main() {
output_low(pin_d2);
output_high(pin_d3);
delay_ms(50);
enable_interrupts(INT_TIMER2); //enable timer2 interrupt
enable_interrupts(GLOBAL); //enable all interrupts (else timer2 wont happen)
enable_interrupts(INT_RB);
enable_interrupts(INT_RB5);
setup_timer_2(T2_DIV_BY_1,255,1);
//setup_spi(SPI_MASTER);
init_port();
RFM73_Initialize();
delay_ms(50);
sub_program_1hz();
output_low(pin_d3);
while(1) {
//if (!IRQ_IN) Receive_Packet(1);
//Receive_Packet(0);
if (update1>=second/5) {
update1=0;
//led_toggle;
sub_program_1hz();
}
}
}
|
in the code below, i have some problems understanding the side on Hope code Code: |
void init_port(void)
{
ANSEL = 0;
ANSELH = 0;
WPUB = 0;
CE_OUT();
CSN_OUT();
SCK_OUT();
MISO_IN();
MOSI_OUT();
IRQ_IN();
RED_LED_OUT();
GREEN_LED_OUT();
Sensitive_LED_OUT();
CE = 0;
CSN = 1;
SCK = 0;
MOSI = 0;
RED_LED = 0;
GREEN_LED = 0;
Sensitive_LED = 0;
}
|
What is with the CE=0; since it was already CE_OUT(); ???
rfm73_functions.c Code: |
void init_port(void) {
CE_LOW;
CSN_LOW;
SCK_LOW;
MISO_IN;
MOSI_LOW;
IRQ_IN;
CSN_HIGH;
printf("\n\rend_init_port");
}
void sub_program_1hz(void) {
unsigned int i;
unsigned int temp_buf[32];
for(i=0;i<17;i++)
{
temp_buf[i]=tx_buf[i];
}
Send_Packet(W_TX_PAYLOAD_NOACK_CMD,temp_buf,17);
SwitchToRxMode(); //switch to Rx mode
}
void Send_Packet(unsigned int type,unsigned int* pbuf,unsigned int len) {
/**************************************************
Function: Send_Packet
Description:
fill FIFO to send a packet
Parameter:
type: WR_TX_PLOAD or W_TX_PAYLOAD_NOACK_CMD
pbuf: a buffer pointer
len: packet length
Return:
None
**************************************************/
unsigned int fifo_sta;
//printf("\n\rsend_packet");
SwitchToTxMode(); //switch to tx mode
fifo_sta=SPI_Read_Reg(FIFO_STATUS); // read register FIFO_STATUS's value
if((fifo_sta&FIFO_STATUS_TX_FULL)==0)//if not full, send data (write buff)
{
printf("\n\rerr13 0x%x", fifo_sta);
led_toggle;
SPI_Write_Buf(type, pbuf, len); // Writes data to buffer
//printf("\n\rend_send_packet");
}
}
void Receive_Packet(int8 origin) {
unsigned int len,i,sta,fifo_sta,chksum;
unsigned int rx_buf[MAX_PACKET_LEN];
sta=SPI_Read_Reg(STATUS); // read register STATUS's value
//if (!origin) printf("\n\r running 0x%x", sta);
if (origin==1) { printf("\n\r irq detected 0x%x", sta); }
if((STATUS_RX_DR&sta) == 0x40) { // if receive data ready (RX_DR) interrupt
printf("err4 "); led_toggle;
do {
len=SPI_Read_Reg(R_RX_PL_WID_CMD); // read len
if(len<=MAX_PACKET_LEN)
{
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,len);// read receive payload from RX_FIFO buffer
printf("err1 ");
}
else
{
SPI_Write_Reg(FLUSH_RX,0);//flush Rx
printf("err2 ");
}
fifo_sta=SPI_Read_Reg(FIFO_STATUS); // read register FIFO_STATUS's value
}
while((fifo_sta&FIFO_STATUS_RX_EMPTY)==0); //while not empty
//output_low(pin_d3);
chksum = 0;
for(i=0;i<16;i++)
{
chksum +=rx_buf[i];
}
if(chksum==rx_buf[16]&&rx_buf[0]==0x30) {
printf("err3 ");
Send_Packet(W_TX_PAYLOAD_NOACK_CMD,rx_buf,17);
SwitchToRxMode();//switch to RX mode
}
}
SPI_Write_Reg(WRITE_REG|STATUS,sta);// clear RX_DR or TX_DS or MAX_RT interrupt flag
//printf("\n\rend_Receive_Packet");
//CSN_OUT;
}
|
RFM73.h Code: |
//examples_mplab\demo_16f887\RFM73.h
#ifndef _RFM73_H_
#define _RFM73_H_
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#define INT8 char
#define INT16 int
#define UINT8 unsigned char
#define UINT16 unsigned int
#define UINT32 unsigned long
#define CE_HIGH output_high(rfm73_ce)
#define CSN_HIGH output_high(rfm73_csn)
#define SCK_HIGH output_high(rfm73_sck)
#define MOSI_HIGH output_high(rfm73_mosi)
#define CE_LOW output_low(rfm73_ce)
#define CSN_LOW output_low(rfm73_csn)
#define SCK_LOW output_low(rfm73_sck)
#define MOSI_LOW output_low(rfm73_mosi)
#define MISO_IN input_state(rfm73_miso)
#define IRQ_IN input_state(pin_c0)
#define MAX_PACKET_LEN 32// max value is 32
//************************FSK COMMAND and REGISTER****************************************//
// SPI(RFM73) commands
#define READ_REG 0x00 // Define read command to register
#define WRITE_REG 0x20 // Define write command to register
#define RD_RX_PLOAD 0x61 // Define RX payload register address
#define WR_TX_PLOAD 0xA0 // Define TX payload register address
#define FLUSH_TX 0xE1 // Define flush TX register command
#define FLUSH_RX 0xE2 // Define flush RX register command
#define REUSE_TX_PL 0xE3 // Define reuse TX payload register command
#define W_TX_PAYLOAD_NOACK_CMD 0xb0
#define W_ACK_PAYLOAD_CMD 0xa8
#define ACTIVATE_CMD 0x50
#define R_RX_PL_WID_CMD 0x60
#define NOP_NOP 0xFF // Define No Operation, might be used to read status register
// SPI(RFM73) registers(addresses)
#define CONFIG 0x00 // 'Config' register address
#define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address
#define EN_RXADDR 0x02 // 'Enabled RX addresses' register address
#define SETUP_AW 0x03 // 'Setup address width' register address
#define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address
#define RF_CH 0x05 // 'RF channel' register address
#define RF_SETUP 0x06 // 'RF setup' register address
#define STATUS 0x07 // 'Status' register address
#define OBSERVE_TX 0x08 // 'Observe TX' register address
#define CD 0x09 // 'Carrier Detect' register address
#define RX_ADDR_P0 0x0A // 'RX address pipe0' register address
#define RX_ADDR_P1 0x0B // 'RX address pipe1' register address
#define RX_ADDR_P2 0x0C // 'RX address pipe2' register address
#define RX_ADDR_P3 0x0D // 'RX address pipe3' register address
#define RX_ADDR_P4 0x0E // 'RX address pipe4' register address
#define RX_ADDR_P5 0x0F // 'RX address pipe5' register address
#define TX_ADDR 0x10 // 'TX address' register address
#define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address
#define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address
#define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address
#define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address
#define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address
#define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address
#define FIFO_STATUS 0x17 // 'FIFO Status Register' register address
#define PAYLOAD_WIDTH 0x1f // 'payload length of 256 bytes modes register address
//interrupt status
#define STATUS_RX_DR 0x40
#define STATUS_TX_DS 0x20
#define STATUS_MAX_RT 0x10
#define STATUS_TX_FULL 0x01
//FIFO_STATUS
#define FIFO_STATUS_TX_REUSE 0x40
#define FIFO_STATUS_TX_FULL 0x20
#define FIFO_STATUS_TX_EMPTY 0x10
#define FIFO_STATUS_RX_FULL 0x02
#define FIFO_STATUS_RX_EMPTY 0x01
UINT8 SPI_Read_Reg(UINT8 reg);
void SPI_Read_Buf(UINT8 reg, UINT8 *pBuf, UINT8 bytes);
void SPI_Write_Reg(UINT8 reg, UINT8 value);
//void SPI_Write_Reg_Bank0(const UINT8 reg, const UINT8 value);
//void SPI_Write_Buf(UINT8 reg, UINT8 *pBuf, UINT8 bytes);
void SPI_Write_Buf(UINT8 reg, UINT8 *pBuf, UINT8 length);
void SPI_Write_Buf_bank(UINT8 reg, UINT8 *pBuf, UINT8 length);
void SwitchToTxMode(void);
void SwitchToRxMode(void);
void SPI_Bank1_Read_Reg(UINT8 reg, UINT8 *pBuf);
void SPI_Bank1_Write_Reg(UINT8 reg, UINT8 *pBuf);
void SwitchCFG(char _cfg);
void RFM73_Initialize(void);
void DelayMs(UINT16 ms);
#endif
|
and the RFM73_init.c Code: |
//toshiba_nb200\examples_mplab\demo_16f887\RFM73_init.c
UINT8 op_status;
//int16 CSN=1;
//Bank1 register initialization value
//In the array RegArrFSKAnalog,all the register value is the byte reversed!!!!!!!!!!!!!!!!!!!!!
const int32 Bank1_Reg0_13[]={ //latest config txt
0xE2014B40,
0x00004BC0,
0x028CFCD0,
0x41390099,
0x1B8296d9,
0xA67F0224,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00127300,
0x46B48000,
};
const UINT8 Bank1_Reg14[]=
{
0x41,0x20,0x08,0x04,0x81,0x20,0xCF,0xF7,0xFE,0xFF,0xFF
};
//Bank0 register initialization value
const UINT8 Bank0_Reg[][2]={
{0,0x0F},//reflect RX_DR\TX_DS\MAX_RT,Enable CRC ,2byte,POWER UP,PRX
{1,0x3F},//Enable auto acknowledgement data pipe5\4\3\2\1\0
{2,0x3F},//Enable RX Addresses pipe5\4\3\2\1\0
{3,0x03},//RX/TX address field width 5byte
{4,0xff},//auto retransmission dalay (4000us),auto retransmission count(15)
{5,0x17},//23 channel
{6,0x07},//air data rate-1M,out power 0dbm,setup LNA gain \bit4 must set up to 0
{7,0x07},//
{8,0x00},//
{9,0x00},
{12,0xc3},//only LSB Receive address data pipe 2, MSB bytes is equal to RX_ADDR_P1[39:8]
{13,0xc4},//only LSB Receive address data pipe 3, MSB bytes is equal to RX_ADDR_P1[39:8]
{14,0xc5},//only LSB Receive address data pipe 4, MSB bytes is equal to RX_ADDR_P1[39:8]
{15,0xc6},//only LSB Receive address data pipe 5, MSB bytes is equal to RX_ADDR_P1[39:8]
{17,0x20},//Number of bytes in RX payload in data pipe0(32 byte)
{18,0x20},//Number of bytes in RX payload in data pipe1(32 byte)
{19,0x20},//Number of bytes in RX payload in data pipe2(32 byte)
{20,0x20},//Number of bytes in RX payload in data pipe3(32 byte)
{21,0x20},//Number of bytes in RX payload in data pipe4(32 byte)
{22,0x20},//Number of bytes in RX payload in data pipe5(32 byte)
{23,0x00},//fifo status2
{28,0x3F},//Enable dynamic payload length data pipe5\4\3\2\1\0
{29,0x07}//Enables Dynamic Payload Length,Enables Payload with ACK,Enables the W_TX_PAYLOAD_NOACK command
};
const UINT8 RX0_Address[]={0x34,0x43,0x10,0x10,0x01};//Receive address data pipe 0
const UINT8 RX1_Address[]={0x39,0x38,0x37,0x36,0xc2};////Receive address data pipe 1
extern UINT8 test_data;
//extern UINT8 channel;
//extern UINT8 power;
//extern UINT8 data_rate;
extern UINT8 rx_buf[MAX_PACKET_LEN];
extern void delay_200ms(void);
extern void delay_50ms(void);
///////////////////////////////////////////////////////////////////////////////
// SPI access //
///////////////////////////////////////////////////////////////////////////////
/**************************************************
Function: SPI_RW();
Description:
Writes one UINT8 to RFM73, and return the UINT8 read
/**************************************************/
UINT8 SPI_RW(UINT8 value)
{
UINT8 bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
{
if(value & 0x80)
{
MOSI_HIGH;
}
else
{
MOSI_LOW;
}
value = (value << 1); // shift next bit into MSB..
SCK_HIGH; // Set SCK high..
value |= MISO_IN; // capture current MISO bit
SCK_LOW; // ..then set SCK low again
}
return(value); // return read UINT8
}
/**************************************************
Function: SPI_Write_Reg();
Description:
Writes value 'value' to register 'reg'
/**************************************************/
void SPI_Write_Reg(UINT8 reg, UINT8 value)
{
CSN_LOW; // CSN low, init SPI transaction
op_status = SPI_RW(reg); // select register
SPI_RW(value); // ..and write value to it..
CSN_HIGH; // CSN high again
}
/**************************************************/
/**************************************************
Function: SPI_Read_Reg();
Description:
Read one UINT8 from BK2421 register, 'reg'
/**************************************************/
UINT8 SPI_Read_Reg(UINT8 reg)
{
UINT8 value;
CSN_LOW; // CSN low, initialize SPI communication...
op_status=SPI_RW(reg); // Select register to read from..
value = SPI_RW(0); // ..then read register value
CSN_HIGH; // CSN high, terminate SPI communication
return(value); // return register value
}
/**************************************************/
/**************************************************
Function: SPI_Read_Buf();
Description:
Reads 'length' #of length from register 'reg'
/**************************************************/
void SPI_Read_Buf(UINT8 reg, UINT8 *pBuf, UINT8 length)
{
uint8 status2, byte_ctr;
CSN_LOW; // Set CSN l
status2 = SPI_RW(reg); // Select register to write, and read status UINT8
for(byte_ctr=0;byte_ctr<length;byte_ctr++)
pBuf[byte_ctr] = SPI_RW(0); // Perform SPI_RW to read UINT8 from RFM73
CSN_HIGH; // Set CSN high again
}
/**************************************************/
/**************************************************
Function: SPI_Write_Buf();
Description:
Writes contents of buffer '*pBuf' to RFM73
/**************************************************/
void SPI_Write_Buf(UINT8 reg, UINT8 *pBuf, UINT8 length)
{
UINT8 byte_ctr;
CSN_LOW; // Set CSN low, init SPI tranaction
op_status = SPI_RW(reg); // Select register to write to and read status2 UINT8
for(byte_ctr=0; byte_ctr<length; byte_ctr++) // then write all UINT8 in buffer(*pBuf)
SPI_RW(*pBuf++);
CSN_HIGH; // Set CSN high again
}
/**************************************************
Function: SwitchToRxMode();
Description:
switch to Rx mode
/**************************************************/
void SwitchToRxMode()
{
UINT8 value;
SPI_Write_Reg(FLUSH_RX,0);//flush Rx
value=SPI_Read_Reg(status); // read register status2's value
SPI_Write_Reg(WRITE_REG|status,value);// clear RX_DR or TX_DS or MAX_RT interrupt flag
CE_LOW;
value=SPI_Read_Reg(CONFIG); // read register CONFIG's value
//PRX
value=value|0x01;//set bit 1
SPI_Write_Reg(WRITE_REG | CONFIG, value); // Set PWR_UP bit, enable CRC(2 length) & Prim:RX. RX_DR enabled..
CE_HIGH;
}
/**************************************************
Function: SwitchToTxMode();
Description:
switch to Tx mode
/**************************************************/
void SwitchToTxMode()
{
UINT8 value;
SPI_Write_Reg(FLUSH_TX,0);//flush Tx
CE_LOW;
value=SPI_Read_Reg(CONFIG); // read register CONFIG's value
//PTX
value=value&0xfe;//set bit 0
SPI_Write_Reg(WRITE_REG | CONFIG, value); // Set PWR_UP bit, enable CRC(2 length) & Prim:RX. RX_DR enabled.
CE_HIGH;
}
/**************************************************
Function: SwitchCFG();
Description:
access switch between Bank1 and Bank0
Parameter:
_cfg 1:register bank1
0:register bank0
Return:
None
/**************************************************/
void SwitchCFG(char _cfg)//1:Bank1 0:Bank0
{
UINT8 Tmp;
Tmp=SPI_Read_Reg(7);
Tmp=Tmp&0x80;
if( ( (Tmp)&&(_cfg==0) )
|| ( ((Tmp)==0)&&(_cfg) ) )
{
SPI_Write_Reg(ACTIVATE_CMD,0x53);
}
}
/**************************************************
Function: SetChannelNum();
Description:
set channel number
/**************************************************/
void SetChannelNum(UINT8 ch)
{
SPI_Write_Reg((UINT8)(WRITE_REG|5),(UINT8)(ch));
}
///////////////////////////////////////////////////////////////////////////////
// RFM73 initialization //
///////////////////////////////////////////////////////////////////////////////
/**************************************************
Function: RFM73_Initialize();
Description:
register initialization
/**************************************************/
void RFM73_Initialize()
{
UINT8 i,j;
UINT8 WriteArr[12];
//DelayMs(100);//delay more than 50ms.
delay_ms(20);
SwitchCFG(0);
for(i=0;i<20;i++)
{
SPI_Write_Reg((WRITE_REG|Bank0_Reg[i][0]),Bank0_Reg[i][1]);
}
/*//reg 10 - Rx0 addr
SPI_Write_Buf((WRITE_REG|10),RX0_Address,5);
//REG 11 - Rx1 addr
SPI_Write_Buf((WRITE_REG|11),RX1_Address,5);
//REG 16 - TX addr
SPI_Write_Buf((WRITE_REG|16),RX0_Address,5);*/
//reg 10 - Rx0 addr
for(j=0;j<5;j++)
{
WriteArr[j]=RX0_Address[j];
}
SPI_Write_Buf((WRITE_REG|10),&(WriteArr[0]),5);
//REG 11 - Rx1 addr
for(j=0;j<5;j++)
{
WriteArr[j]=RX1_Address[j];
}
SPI_Write_Buf((WRITE_REG|11),&(WriteArr[0]),5);
//REG 16 - TX addr
for(j=0;j<5;j++)
{
WriteArr[j]=RX0_Address[j];
}
SPI_Write_Buf((WRITE_REG|16),&(WriteArr[0]),5);
// printf("\nEnd Load Reg");
i=SPI_Read_Reg(29);//read Feature Register 如果要支持动态长度或者 Payload With ACK,需要先给芯片发送 ACTIVATE命令(数据为0x73),然后使能动态长度或者 Payload With ACK (REG28,REG29).
if(i==0) // i!=0 showed that chip has been actived.so do not active again.
SPI_Write_Reg(ACTIVATE_CMD,0x73);// Active
for(i=22;i>=21;i--)
{
SPI_Write_Reg((WRITE_REG|Bank0_Reg[i][0]),Bank0_Reg[i][1]);
//SPI_Write_Reg_Bank0(Bank0_Reg[i][0],Bank0_Reg[i][1]);
}
//********************Write Bank1 register******************
SwitchCFG(1);
for(i=0;i<=8;i++)//reverse
{
for(j=0;j<4;j++)
WriteArr[j]=(Bank1_Reg0_13[i]>>(8*(j) ) )&0xff;
SPI_Write_Buf((WRITE_REG|i),&(WriteArr[0]),4);
}
for(i=9;i<=13;i++)
{
for(j=0;j<4;j++)
WriteArr[j]=(Bank1_Reg0_13[i]>>(8*(3-j) ) )&0xff;
SPI_Write_Buf((WRITE_REG|i),&(WriteArr[0]),4);
}
//SPI_Write_Buf((WRITE_REG|14),&(Bank1_Reg14[0]),11);
for(j=0;j<11;j++)
{
WriteArr[j]=Bank1_Reg14[j];
}
SPI_Write_Buf((WRITE_REG|14),&(WriteArr[0]),11);
//toggle REG4<25,26>
for(j=0;j<4;j++)
//WriteArr[j]=(RegArrFSKAnalog[4]>>(8*(j) ) )&0xff;
WriteArr[j]=(Bank1_Reg0_13[4]>>(8*(j) ) )&0xff;
WriteArr[0]=WriteArr[0]|0x06;
SPI_Write_Buf((WRITE_REG|4),&(WriteArr[0]),4);
WriteArr[0]=WriteArr[0]&0xf9;
SPI_Write_Buf((WRITE_REG|4),&(WriteArr[0]),4);
//**************************Test spi*****************************//
//SPI_Write_Reg((WRITE_REG|Bank0_Reg[2][0]),0x0f);
//test_data = SPI_Read_Reg(0x02);
//DelayMs(10);
delay_ms(50);
//********************switch back to Bank0 register access******************
SwitchCFG(0);
SwitchToRxMode();//switch to RX mode
}
/**************************************************
Function: DelayMs();
Description:
delay ms, please implement this function according to your MCU.
/**************************************************/
void delayus(int16 ms)
{
int16 i;
for(i=1; i<=ms; i++) ;
}
|
|
|
|
Rogier
Joined: 25 Feb 2012 Posts: 12 Location: NL
|
|
Posted: Tue May 03, 2016 3:22 am |
|
|
Thanks @PCM programmer
- The story about 'long' and int32 did the trick for me, therefore I always use ( unsigned) INT1/8/16/32, that's clear for everybody!
- notice in the RFM source code of the Topic starter they use the names for STATUS and CONFIG. These are already reserved for PIC, so rename them for example with RFM_STATUS and RFM_CONFIG |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Tue May 03, 2016 12:26 pm |
|
|
What makes you thing STATUS and CONFIG are reserved?.
They only will be, if you load definitions for these. CCS uses them internally for it's own code, but does not have them declared in the C environment unless you do so. Assembler names are not defined, unless you load a set of register definitions for your processor. |
|
|
Rogier
Joined: 25 Feb 2012 Posts: 12 Location: NL
|
|
Posted: Wed May 04, 2016 9:52 am |
|
|
You are right about that.
I used the RFM sofware earlier on old Hitech compiler, use of STATUS gave some errors. It works on CCS. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|