CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

RFM73 problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
705150



Joined: 25 Apr 2013
Posts: 14

View user's profile Send private message

RFM73 problem
PostPosted: Fri May 22, 2015 1:43 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri May 22, 2015 7:42 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri May 22, 2015 2:50 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue May 26, 2015 4:16 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue May 03, 2016 3:22 am     Reply with quote

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: 19244

View user's profile Send private message

PostPosted: Tue May 03, 2016 12:26 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed May 04, 2016 9:52 am     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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