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

SPI not return the right values PIC18F4685

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



Joined: 20 Sep 2005
Posts: 20

View user's profile Send private message Visit poster's website

SPI not return the right values PIC18F4685
PostPosted: Mon Feb 19, 2018 11:13 am     Reply with quote

I have been trying to use a Demo programs EX_SPI.C and EX_SPI_SLAVE. I modified them to work with an LCD Display and use a PIC18F4685. Sadly, the slave does not seem to be replying the value I am expecting.
Here is the Code, I did not modified the include files. Compiler version 5.075
Master
Code:


#if defined(__PCB__)
#include <16C56.h>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_A3, rcv=PIN_A2)

#elif defined(__PCM__)
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#elif defined(__PCH__)
#include "18F4685.H"
#FUSES INTRC_IO                   //Internal Clock with IO
#FUSES  NOFCMEN             //NO FAIL SAFE CLOCK
#FUSES NOIESO
#FUSES PUT                       //Power Up Timer
#FUSES BROWNOUT                //Brownout reset
#FUSES BORV28                   //Brownout reset at 2.70V
#FUSES NOWDT                    //Watch Dog Timer
#FUSES WDT1024                   //Watch Dog Timer uses 1:128 Postscale
#FUSES NOPROTECT                //Code not protected from reading
//#FUSES NOOSCSEN                 //Oscillator switching is disabled, m oscillator is source
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                     // No Debug mode for ICD
#FUSES NOLVP                       //no low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                      //Program Memory not Write Protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOCPD                    //No EE protection
#FUSES NOCPB                    //No Boot Block code protection
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOLPT1OSC                  //NO LTP1 TIMER ENABLED
#FUSES MCLR                  //Master Clear pin enabled
#define XTAL_FREQUENCY 32000000
#define TIMER0_FREQUENCY (XTAL_FREQUENCY/4) //(XTAL_FREQUENCY/4) //1 clock tick = 1 instr. cycle = crystal frequency / 4
#use delay(internal = XTAL_FREQUENCY,/*clock=40MHZ,*/RESTART_WDT) //use to be 16
//#use delay(clock=20000000)
//#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#elif defined(__PCD__)
#include <30F2010.h>
#fuses HS, NOWDT, NOPROTECT
#use delay(clock=20000000)
#use rs232(baud=9600, UART1A)
#endif

//#include <input.c>
#include "9356.c"
#include "display.h"
void main()
{

   byte value,cmd;
   EEPROM_ADDRESS address;
   address=0x15;
   init_ext_eeprom();
//   WRITE_EXT_EEPROM(address, 0X10);
       lcd_init();
    lcd_clear();
   lcd_position(0x00);
    printf(send_lcd_data,"Hello World!");
    lcd_position(0x40);
    printf(send_lcd_data,"%2X",READ_EXT_EEPROM( address ));
    WHILE(1)
    {
       
        lcd_position(0x40);
        printf(send_lcd_data,"%2X",READ_EXT_EEPROM( address ));
        delay_ms(500);
        RESTART_WDT();
    }

}

Slave
Code:

/////////////////////////////////////////////////////////////////////////
////                                                                 ////
////                         EX_SPI_SLAVE.C                          ////
////                                                                 ////
////  Uses the PIC's SPI peripheral in slave mode to emulate a 9356  ////
////  SPI EEPROM.  This example is the counterpart to EX_SPI.C.      ////
////  Run EX_SPI_SLAVE.C on one PIC and connect it to another PIC    ////
////  running EX_SPI.                                                ////
////                                                                 ////
////  This example will work with the PCM and PCH compilers.  The    ////
////  following conditional compilation lines are used to include a  ////
////  valid device for each compiler.  Change the device, clock and  ////
////  RS232 pins for your hardware if needed.                        ////
/////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2012 Custom Computer Services         ////
//// This source code may only be used by licensed users of the CCS  ////
//// C compiler.  This source code may only be distributed to other  ////
//// licensed users of the CCS C compiler.  No other use,            ////
//// reproduction or distribution is permitted without written       ////
//// permission.  Derivative programs created using this software    ////
//// in object code form are not restricted in any way.              ////
/////////////////////////////////////////////////////////////////////////
#if defined(__PCM__)
#include <16F887.h>
#fuses NOWDT
#use delay(crystal=20MHz)
#define EEPROM_BYTES 80

#elif defined(__PCH__)
#include <18F4685.h>
#FUSES INTRC_IO                   //Internal Clock with IO
#FUSES  NOFCMEN             //NO FAIL SAFE CLOCK
#FUSES NOIESO
#FUSES PUT                       //Power Up Timer
#FUSES BROWNOUT                //Brownout reset
#FUSES BORV28                   //Brownout reset at 2.70V
#FUSES NOWDT                    //Watch Dog Timer
#FUSES WDT1024                   //Watch Dog Timer uses 1:128 Postscale
#FUSES NOPROTECT                //Code not protected from reading
//#FUSES NOOSCSEN                 //Oscillator switching is disabled, m oscillator is source
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                     // No Debug mode for ICD
#FUSES NOLVP                       //no low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                      //Program Memory not Write Protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOCPD                    //No EE protection
#FUSES NOCPB                    //No Boot Block code protection
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOLPT1OSC                  //NO LTP1 TIMER ENABLED
#FUSES MCLR                  //Master Clear pin enabled

#define XTAL_FREQUENCY 32000000
#define TIMER0_FREQUENCY (XTAL_FREQUENCY/4) //(XTAL_FREQUENCY/4) //1 clock tick = 1 instr. cycle = crystal frequency / 4
#use delay(internal = XTAL_FREQUENCY,/*clock=40MHZ,*/RESTART_WDT) //use to be 16
#define EEPROM_BYTES 256

#elif defined(__PCD__)
#include <24FJ128GA006.h>
#fuses NOWDT
#use delay(crystal=20MHz)
#define EEPROM_BYTES 256
#endif

#if defined(__PCD__)
#use spi(SLAVE, SPI2, MODE=1, bits=8)
#else
#use spi(SLAVE, SPI1, MODE=1, bits=8)
#endif

#define EEPROM_COMMAND_WRITE  0x0A
#define EEPROM_COMMAND_READ   0x18
#define EEPROM_COMMAND_INIT   0x09

int32 ticker;
int8 do_clock_stuff;
int1 toggle;

enum {
   EEPROM_STATE_COMMAND,
   EEPROM_STATE_ADDRESS,
   EEPROM_STATE_WRITE_DATA,
   EEPROM_STATE_READ_DATA,
} EepromState = EEPROM_STATE_COMMAND;

unsigned int8 Memory[EEPROM_BYTES];

#if defined(__PCD__)
#INT_SPI2
#else
#INT_SSP
#endif
void spi_slave_isr(void)
{
   static unsigned int8 LastCommand = EEPROM_COMMAND_WRITE;
   static unsigned int8 Address;
   unsigned int8 Data;

   Data = spi_xfer_in();
//    output_bit(PIN_A4,!input_state(PIN_A4));       
   switch(EepromState)
   {
      case EEPROM_STATE_COMMAND:
         if((Data == EEPROM_COMMAND_WRITE) || (Data == EEPROM_COMMAND_READ))
         {
            LastCommand = Data;
            EepromState++;
         }
         break;
      case EEPROM_STATE_ADDRESS:
         Address = Data;
         if(LastCommand == EEPROM_COMMAND_WRITE)
            EepromState = EEPROM_STATE_WRITE_DATA;
         else
         {
            spi_prewrite(Memory[Address]);
            EepromState = EEPROM_STATE_READ_DATA;
         }
         break;
      case EEPROM_STATE_WRITE_DATA:
         if(Address < EEPROM_BYTES)
            Memory[Address] = Data;
      case EEPROM_STATE_READ_DATA:
         EepromState = EEPROM_STATE_COMMAND;
         break;
   }
}
#INT_TIMER0
void timer0_functions()
{
    ticker -= 65536; // Decrement ticker by clocks per interrupt
    if ( ticker < 65536 ) // If second has expired
    {
        ticker += TIMER0_FREQUENCY; // Increment ticker by clocks per second
        do_clock_stuff++;
    }
    if(do_clock_stuff>0)
    {
        output_bit(PIN_A3,toggle);
        toggle=!toggle;
       
        do_clock_stuff--;
    }
   
}
/*
void main(void)
PURPOSE: Peripheral Initialization
*/
void main(void)
{
  #if defined(__PCD__)
   enable_interrupts(INT_SPI2);
   enable_interrupts(INTR_GLOBAL);
  #else
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
    ticker=65536;
//       setup_oscillator(OSC_32MHZ);
   enable_interrupts(INT_SSP);
      enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);
  #endif
[color=yellow] Memory[0x15] = 0xAB;[/color]
   while(true)
   {
   }
}

Note I force address 0x15 to AB, I get 0x15 back? Ideas?
Rolling Eyes
PCM programmer



Joined: 06 Sep 2003
Posts: 20296

View user's profile Send private message

PostPosted: Mon Feb 19, 2018 11:56 am     Reply with quote

Post your list of connections between the two 18F4685 PICs (SPI master
and slave PICs).
Ttelmah



Joined: 11 Mar 2010
Posts: 13054

View user's profile Send private message

PostPosted: Mon Feb 19, 2018 12:15 pm     Reply with quote

First, tidy. Over 1/3rd of what you have posted is stuff for other processors.
Then you need to modify the drivers. The PIC cannot correctly emulate this SPI EEPROM. Reasons are two separate issues:
1) The PIC will need a pause between each byte sent, to allow the slave time to get into the routines.
2) The EEPROM you are trying to emulate uses a non 'byte wide' clock pattern. The master can handle this but the SPI slave on the PIC only supports byte wide operation. Choose an EEPROM that uses byte orientated SPI. Larger EEPROM's like the 25AA010 support this format, so emulate just the number of bytes required of one of these or a similar chip.
David Pouzar



Joined: 20 Sep 2005
Posts: 20

View user's profile Send private message Visit poster's website

PostPosted: Mon Feb 19, 2018 12:37 pm     Reply with quote

Master Slave
SCL (Pin 18) ---> SCL(Pin 18)
SDI (Pin 23) ---> SDO(Pin 24)
SDO(Pin 24) ---> SDI (Pin 23)

I have 1K pullups of SDI and SDO pin between the Chips. No Pullup on SCL.
Ttelmah



Joined: 11 Mar 2010
Posts: 13054

View user's profile Send private message

PostPosted: Mon Feb 19, 2018 12:42 pm     Reply with quote

SPI doesn't need pull-ups, but they won't hurt.
My previous comments still apply.
David Pouzar



Joined: 20 Sep 2005
Posts: 20

View user's profile Send private message Visit poster's website

PostPosted: Mon Feb 19, 2018 12:44 pm     Reply with quote

Thanks for the input. I am actually trying to communicate with a Temperature sensor made by Adafruit https://www.adafruit.com/product/2652 . But I will need to also replace my eeprom chips and will look into using what you recommend Ttelmah.
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