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 CCS Technical Support

CC1101 and PIC18F4520

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



Joined: 16 May 2006
Posts: 95

View user's profile Send private message

CC1101 and PIC18F4520
PostPosted: Fri Mar 04, 2016 5:36 pm     Reply with quote

Hi Dear;
I used PIC18F4520 and CC1101 RF Transceiver.
I wrote this code but it wrong answered. Sometimes 15 decimal sometimes 47 decimal.

where is my mistake?
Thanks.



Code:

#include <18F4520.h>
#FUSES HS,NOWDT,WDT128,NOBROWNOUT,NOPBADEN,NOLVP,NOXINST
#use delay(clock=20000000)
#use spi(Master, SPI1, Mode=0)
#include <string.h>
#include <math.h>
#include "LCD.C"
#define CSN_PIN PIN_A5
#define READ_SINGLE        0x80 
///////////////////////////////////
#define CC1101_PARTNUM      0x30
#define CC1101_VERSION      0x31
#define CC1101_FREQEST      0x32
#define CC1101_LQI          0x33
#define CC1101_RSSI         0x34
#define CC1101_MARCSTATE    0x35




int8 CC1101ReadReg( int8 addr )
{
     int8 value;
  output_low(CSN_PIN);
   while(spi_data_is_in());
  spi_write(addr|READ_SINGLE);
   value=spi_read(0);
   output_high(CSN_PIN);
   return value;
       
}

void main()
{
   setup_spi(spi_master| spi_l_to_h | spi_clk_div_4);
   lcd_init();
   delay_ms(100);
   lcd_gotoxy(1,1);
   printf(lcd_putc,"RECEIVER");
   delay_ms(500);
   
 output_high(CSN_PIN);

   while(TRUE)
   {
     
      lcd_gotoxy(1,2);
       printf(lcd_putc,"CODE:%03u",CC1101ReadReg(CC1101_PARTNUM      ));
 
   }

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Mar 04, 2016 6:25 pm     Reply with quote

In this line, you use Mode 0 (which is correct), but you left off the BITS=8.
Quote:
#use spi(Master, SPI1, Mode=0)


But then you use setup_spi() and set it for Mode 1. Why ?
Quote:
setup_spi(spi_master| spi_l_to_h | spi_clk_div_4);


Here is part of the .LST file that shows the effect of using both the
lines above:
Quote:

.................... void main()
*
02CC: CLRF TBLPTRU
02CE: BCF RCON.IPEN
02D0: BCF SSPCON1.SSPEN

This is the setup code from #use spi(). It sets up for SPI Mode 0:
02D2: MOVLW 40
02D4: MOVWF SSPSTAT
02D6: MOVLW 20
02D8: MOVWF SSPCON1


02DA: BCF TRISC.5
02DC: BSF TRISC.4
02DE: BCF TRISC.3
02E0: CLRF @sprintf_string+1
02E2: CLRF @sprintf_string
02E4: MOVF ADCON1,W
02E6: ANDLW C0
02E8: IORLW 0F
02EA: MOVWF ADCON1
02EC: MOVLW 07
02EE: MOVWF CMCON
.... {
.... setup_spi(spi_master| spi_l_to_h | spi_clk_div_4);
02F0: BCF SSPCON1.SSPEN
02F2: BCF TRISC.5
02F4: BSF TRISC.4
02F6: BCF TRISC.3

// This is the Mode setup code for setup_spi(). It occurs after the
// #use spi() code and it overwrites the registers with Mode 1.
02F8: MOVLW 20
02FA: MOVWF SSPCON1
02FC: MOVLW 00
02FE: MOVWF SSPSTAT


Also, you should only use one method for SPI setup.
1. #use spi() -- use spi_xfer() to transfer bytes.
or
2. setup_spi() -- use spi_write() and spi_read() to transfer bytes.
respected



Joined: 16 May 2006
Posts: 95

View user's profile Send private message

PostPosted: Sat Mar 05, 2016 3:47 am     Reply with quote

Quote:
Also, you should only use one method for SPI setup.
1. #use spi() -- use spi_xfer() to transfer bytes.
or
2. setup_spi() -- use spi_write() and spi_read() to transfer bytes.


is not OK.

But this is Ok.

Code:

#include <18F4520.h>
#FUSES HS,NOWDT,WDT128,NOBROWNOUT,NOPBADEN,NOLVP,NOXINST
#use delay(clock=20000000)
#use spi(Master, stream=SPI1, Mode=0)
#include <string.h>
#include <math.h>
#include "LCD.C"
#define CSN_PIN PIN_A5
#define READ_SINGLE        0x80 
///////////////////////////////////
#define CC1101_PARTNUM      0x30
#define CC1101_VERSION      0x31
#define CC1101_FREQEST      0x32
#define CC1101_LQI          0x33
#define CC1101_RSSI         0x34
#define CC1101_MARCSTATE    0x35




int8 CC1101ReadReg( int8 addr )
{
     int8 value;
  output_low(CSN_PIN);
   while(spi_data_is_in());
  spi_write(addr|READ_SINGLE);
  value=spi_read(0);
   output_high(CSN_PIN);
   return value;
       
}

void main()
{
   lcd_init();
   delay_ms(100);
   lcd_gotoxy(1,1);
   printf(lcd_putc,"RECEIVER");
   delay_ms(500);
   
 output_high(CSN_PIN);

   while(TRUE)
   {
     
      lcd_gotoxy(1,2);
       printf(lcd_putc,"CODE:%03X",CC1101ReadReg(CC1101_PARTNUM));
 
   }

}
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sat Mar 05, 2016 4:05 am     Reply with quote

What you have 'works by accident'. It is _wrong_.

If you read the manual, you will find that 'setup_spi', refers you to spi_read, and spi_write. This was the 'old' CCS way of configuring the SPI, and using the SPI, which only offered hardware SPI.

Then if you read the #USE SPI entry, you will find it only refers you to spi_xfer.
You are not meant to use 'half and half'.

The correct way is:
Code:

#include <18F4520.h>
#FUSES HS,NOWDT,WDT128,NOBROWNOUT,NOPBADEN,NOLVP,NOXINST
#use delay(clock=20000000)
#use spi(SPI1, MASTER, MODE=0, BITS=8)
#include <string.h>
#include <math.h>
#include "LCD.C"
#define CSN_PIN PIN_A5
#define READ_SINGLE        0x80
///////////////////////////////////
#define CC1101_PARTNUM      0x30
#define CC1101_VERSION      0x31
#define CC1101_FREQEST      0x32
#define CC1101_LQI          0x33
#define CC1101_RSSI         0x34
#define CC1101_MARCSTATE    0x35

int8 CC1101ReadReg( int8 addr )
{
    int8 value;
    output_low(CSN_PIN);
    spi_xfer(addr|READ_SINGLE);
    value=spi_xfer(0);
    output_high(CSN_PIN);
    return value;   
}

void main()
{
    output_high(CSN_PIN); //ensure the pin is high before starting
    //might as well be done much earlier
    lcd_init();
    delay_ms(100);
    lcd_gotoxy(1,1);
    printf(lcd_putc,"RECEIVER");
    delay_ms(500);   
    while(TRUE)
    {
       lcd_gotoxy(1,2);
       printf(lcd_putc,"CODE:%03X",CC1101ReadReg(CC1101_PARTNUM));
   }
}


What you are doing, works because the #USE sets up the hardware, which is then available for the old read and write. It'll 'go wrong', if you try to use more than one port or do anything more complex, because it will then not be accessing the part correctly. You'd normally also want to specify a baud rate, but the chip you are using supports up to 6MHz, which is higher than the SPI can generate with your clock.

Your call to spi_data_is_in, will result in the code hanging forever, if anything has already been received (it should not have, at this point).
respected



Joined: 16 May 2006
Posts: 95

View user's profile Send private message

PostPosted: Sat Mar 05, 2016 6:04 am     Reply with quote

Thanks. Code is ok. But i didn't understand what does it mean?

spi_xfer(0); why we use 0(zero);
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sat Mar 05, 2016 9:01 am     Reply with quote

Same reason you were using 0....

Just clocking out a dummy byte.

On SPI, the master clocks everything. You send a control byte to select the register (and ignore what is returned), then send a dummy byte (can be anything), and read what comes back.
respected



Joined: 16 May 2006
Posts: 95

View user's profile Send private message

PostPosted: Sat Mar 05, 2016 4:32 pm     Reply with quote

Thanks. I understood. I used for clock. in fact spi_read and spi_xfer are same command is it true?
OK. thanks for your helping.
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