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

SSP question

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



Joined: 10 Oct 2011
Posts: 24

View user's profile Send private message

SSP question
PostPosted: Fri Aug 17, 2012 7:55 am     Reply with quote

Does anyone know if the SSP module will work independently of the CPU? I have an application which consists of input and output cards each with a PIC that reads data over i2c. I'm having transient issues with the relay output card which cause the card to lockup but I can still read data back from it over the i2c bus.

Has anyone here ever had this issue and what was done to resolve it? I set up the WDT but it doesn't seem to work.

I compiled this with v4.050 Here is the code:

Code:

// ************ RAINDROP CONTROL SUBSYSTEM QR16 RELAY OUTPUT CARD **************
// * Version 1.0                                                               *
// * Project P008-QR16   Rev 0                                                 *                                                     
// * Device: PIC16F882-I/SO SOIC-28                                            *
// * ------------------------------------------------------------------------- *
// * 12/12/11 (v1.1) - Added default i2c address.                              *
// * 04/03/12 (v1.2) - Added watchdog timer and brownout detect                *
// *****************************************************************************
#include<16f882.h>
#fuses XT, MCLR, WDT, NOLVP, BROWNOUT, BORV40, NODEBUG, NOFCMEN, PUT
#use delay(clock=4MHz)
#use fast_io(b)
#use fast_io(c)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xa0, force_hw, slow)

// * PORT A DEFINITIONS ********************************************************
#define Q8        PIN_A0
#define Q9        PIN_A1
#define Q10       PIN_A2
#define Q11       PIN_A3
#define Q12       PIN_A4
#define IO_FLT    PIN_A5
// *****************************************************************************

// * PORT B DEFINITIONS ********************************************************
#define Q0        PIN_B0
#define Q1        PIN_B1
#define Q2        PIN_B2
#define Q3        PIN_B3
#define Q4        PIN_B4
#define Q5        PIN_B5
#define Q6        PIN_B6
#define Q7        PIN_B7
// *****************************************************************************

// * PORT C DEFINITIONS ********************************************************
#define ADDR0     PIN_C0
#define ADDR1     PIN_C1
#define ADDR2     PIN_C2
#define SCL       PIN_C3
#define SDA       PIN_C4
#define Q13       PIN_C5
#define Q14       PIN_C6
#define Q15       PIN_C7
// *****************************************************************************

// * PORT E DEFINITIONS ********************************************************
#define SHDN      PIN_E3
// *****************************************************************************

// * PROGRAM DEFINITIONS *******************************************************
// *****************************************************************************

#zero_ram

#byte ANSEL=0x188

static int8 mem_addr;
static int8 card_data[20];

// * I2C INTERRUPT HANDLER *****************************************************
#int_ssp
void i2c_handler(void) {
    int8 state;
    state=i2c_isr_state();
    if(state<0x80) { // Master is sending data
       if(state==1) mem_addr=i2c_read(1); // Store the address
       if(state==2) card_data[mem_addr]=i2c_read(1); // Read and store the data
    }
    if(state>=0x80) { // Master is requesting data
       i2c_write(card_data[mem_addr]);  // Write the memory over i2c
    }
}
// *****************************************************************************       

// * OUTPUT CONTROL ROUTINE ****************************************************
void set_output(int1 bank, int8 value) {
   
    if(!bank) {
       output_b(value); // Write to bank A
    } else { // Write to bank B
       output_a(value & 0x1f); // Write first five bits
       output_c(value & 0xe0); // Write last three bits
    }
}
// *****************************************************************************

// * MAIN ROUTINE **************************************************************
void main(void) {
   
    int8 i2c_address;
    set_tris_b(0b00000000); // Set port B direction
    set_tris_c(0b00011111); // Set port C direction
    set_tris_e(0b00001000); // Set port E direction
    setup_adc_ports(NO_ANALOGS);
    setup_comparator(NC_NC_NC_NC);
    setup_wdt(WDT_18MS | WDT_ON);
    ANSEL=0; // Bug work around   
    output_b(0); // Clear relays on port B
    output_c(0); // Clear relays on port C
    output_float(IO_FLT); // Float the I/O fault line
    enable_interrupts(GLOBAL);
    enable_interrupts(INT_SSP);
    i2c_address=(~input_c() & 0x07)<<5; // Read address switch at startup
    if(i2c_address==0) i2c_address=1<<5; // Default if not set
    i2c_slaveaddr(i2c_address); // Assign i2c address   
    while(TRUE) { // Loop forever
        restart_wdt(); // Restart the watchdog timer
        card_data[0]=10; // Card is a QR16 relay card
        card_data[1]=0; // Set status byte, do more with later
        set_output(0,card_data[10]); // Write bank A value
        set_output(1,card_data[11]); // Write bank B value
    }
}
// *****************************************************************************
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Fri Aug 17, 2012 8:44 am     Reply with quote

If you are able to read data from the I2C, then the CPU is still running OK. This is why the watchdog doesn't trigger.
Get rid of the 'slow' keyword. _Only master devices have a speed setting_. Having this can cause problems, programming illegal combinations into the registers.....
4.050, is _before_ CCS V4 really worked. Late V4.07x compilers were the first ones that had most features working. This could be a second problem.
In state 0x80 in the INT_SSP, you must read the register, before writing the reply. The effect of not doing this varies between chips, but failure to do this, can cause erratic behaviour of the I2C peripheral. If you look at the examples, the 'read' section uses <=0x80, while the write section uses >=0x80, so both transactions are done in state 0x80.
What happens to your code, if state==3 or more?. Though (presumably) you don't expect this to happen, you should always handle such things.
You should not enable INT_SSP, till _after_ you have setup the slave address.

Best Wishes
snock



Joined: 10 Oct 2011
Posts: 24

View user's profile Send private message

PostPosted: Fri Aug 17, 2012 1:29 pm     Reply with quote

Thanks for the pointers. I just determined that what you said is indeed correct. The CPU is still running it's just that i2c isn't working at the point it locks up. I will implement your suggestions and see how things turn out. Thanks a lot.
temtronic



Joined: 01 Jul 2010
Posts: 9247
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Aug 17, 2012 4:17 pm     Reply with quote

hmm...
"I'm having transient issues with the relay output card"...

Might also be hardware related.

Have you got suppression diodes across the relays (if mechanical types) ??

To verify relays are the cause of the transients, replace with LEDs and resistors and run the program.

Also be sure the power supply and power lines to the relays are hefty enough for the power levels the relays need. Your PIC VDD may be 'dipping' long enough to just enough to cause 'transient' problems.

hth
jay
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