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

Problem SPI with Accelerometer ADIS16209
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 26, 2009 1:56 pm     Reply with quote

I checked the registers used in the .LST file for vs. 4.090. They appear
to be correct.

I would try this divisor, just to be safe:
Quote:
SPI_CLK_DIV_64


I'll continue looking at the problem.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 26, 2009 2:11 pm     Reply with quote

Quote:
while(1)
{
CS1 = 0; //chip select pin to ADIS16209
spi_write2(0x03); //to read upper byte
spi_write2(0x00);
delay_us(1);
high_byte_x = spi_read2(0); //upper byte

spi_write2(0x02); //to read lower byte
spi_write2(0x00);
delay_us(1);
lo_byte_x = spi_read2(0); //lower byte

inclin_x_int16 = high_byte_x; //inclin_x_int16 is an int16 integer
inclin_x_int16 = inclin_x_int16<<8;
inclin_x_int16 = inclin_x_int16 + lo_byte_x;
CS1 = 1;

} // end of while(1)

A few other things are wrong. Look at your code, and look at the
ADIS16209 data sheet on page 5.
http://www.analog.com/static/imported-files/data_sheets/ADIS16209.pdf
It shows 16 SCLK's per Chip Select pulse. How many do you have in
the code above ? A lot more than 16.

Then look at the Table of Parameters, again on page 5. It's got
something called Tdatarate. In "normal mode", the minimum delay
between falling edges of Chip Select is 100 usec. You don't have
that in your code.

You need to go through your code and make it conform to Page 5 in
the data sheet.

Ideally, you ought to make your code into routines, instead of inline
code. You can do that later.
mazen82



Joined: 10 Sep 2009
Posts: 22

View user's profile Send private message

PostPosted: Mon Oct 26, 2009 2:19 pm     Reply with quote

Yea, i added the time delays and fixed the 16 clocks per CS, i am also trying to go to DIV_64, but the software hangs up at the first spi_write2, any idea why?

where can i find what's in the function spi_write2?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 26, 2009 2:22 pm     Reply with quote

Look in the .LST file. It shows the ASM code generated by the compiler.

If you still have a problem, then post your current test program.
(It must compile with no errors).
mazen82



Joined: 10 Sep 2009
Posts: 22

View user's profile Send private message

PostPosted: Mon Oct 26, 2009 4:21 pm     Reply with quote

Code:


#include "C:\Program Files\PICC\ethernet2\18F97J60.H"
#device ICD=TRUE
#device adc=10
#use delay(clock=25M)
#fuses HS
#fuses NOIESO
#fuses NOFCMEN
#fuses PRIMARY
#fuses ETHLED
#fuses NOWDT
#fuses NOPROTECT
#fuses DEBUG
#fuses NOSTVREN

#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)

int16 inclin_x_int16;
int lo_byte_x,high_byte_x;
#byte LATD    =  0xF8C
#byte PORTD    =  0xF83
#byte TRISD    =  0xF95

#bit RD0          = LATD .0
#bit RD1          = LATD .1
#bit RD2          = LATD .2
#bit RD3          = LATD .3
#bit ADIS_SDO     = LATD .4
#bit ADIS_SDI     = PORTD.5
#bit ADIS_CLK     = LATD .6
#bit CS1          = LATD .7
#define     DDIRD    0x20  //all outputs except D5 (SDI)
#define     INITD       0x00

void main()
{
PORTD = INITD;
TRISD = DDIRD;
setup_spi2(SPI_MASTER|SPI_MODE_3|SPI_CLK_DIV_16);
CS1 = 1;
delay_ms(200);

while(1)
{
     CS1 = 0;
     spi_write2(0x03);     
     spi_write2(0x00);
     CS1 = 1;
     delay_us(100);
     CS1 = 0; 
    high_byte_x = spi_read2(0);

     CS1=1;
     delay_us(100);
     CS1=0;     
     delay_us(10);
     
     spi_write2(0x02);     
     spi_write2(0x00);
     delay_us(1);
     
     CS1=1;
     delay_us(100);
     CS1=0;
     delay_us(10);
     
    lo_byte_x = spi_read2(0); 
 
      inclin_x_int16 = high_byte_x & 0x3F;
      inclin_x_int16 = inclin_x_int16<<8;
      inclin_x_int16 = inclin_x_int16 + lo_byte_x;
      CS1 = 1;

   delay_ms(1000);
}  // end of while(1)

} //end of main()


Ok this code works, but the data line coming out of the sensor needs more time to stabilize, so i tried using SPI_CLK_DIV_64 instead of SPI_CLK_DIV_16, but it wouldnt work. Why?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 26, 2009 4:42 pm     Reply with quote

Your code still isn't correct. All operations within a Chip Select pulse
must be 16-bits. They can't be only 8-bits. The read operation consists
of writing the register address to the ADIS chip and then reading the
result. Each of those is one 8-bit operation. Combined together, they
are 16 bits. That fits the data sheet.

You also need to get rid of the inline code and make it into routines.
Here's the read routine. Call it to read one 8-bit register.
I've incorporated the delay into the routine.
Code:

#define ADIS16209_CS  PIN_D7

// Read an 8-bit register value from the ADIS16209
int8 adis16209_read8(int8 reg_addr)
{
int8 retval;

output_low(ADIS16209_CS);
spi_write2(reg_addr);
retval = spi_read2(0);
output_high(ADIS16209_CS);

delay_us(100);

return(retval);
}
mazen82



Joined: 10 Sep 2009
Posts: 22

View user's profile Send private message

PostPosted: Wed Oct 28, 2009 8:20 am     Reply with quote

That makes sense using 16 clocks per chip select.
I keep trying the:
setup_spi2(SPI_MASTER|SPI_MODE_3|SPI_CLK_DIV_64);

but the software hangs up at the line:
retval = spi_read2(0);
with the clock signal remaining high.

going to SPI_MODE_2 or SPI_MODE_0 works but doesnt display the correct values which i understand is due to the way the sensor is configured, where it has to be mode 3.

But Mode 3 works with the SPI_CLK_DIV_16 which i still dont understand why it works with the fast clock but not the slower clock.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Oct 28, 2009 11:16 am     Reply with quote

Quote:
but the software hangs up at the line:
retval = spi_read2(0);
with the clock signal remaining high.


1. Post your current test program that shows this lockup. Post all the
code necessary to compile the program (ie., #include files).

2. Post the details of how you know that it hangs. Are you stepping
through the code with a debugger ? What debugger are you using ?
Have you tried to run the code without stepping through it, and without
the debugger (as a stand-alone program) ?

3. Post the compiler version you're using for this test.

4. Are these tests being done on a hardware board or a simulator ?
If it's a board, did you build it yourself ? If you bought it, post
the manufacturer and model number of the board.
mazen82



Joined: 10 Sep 2009
Posts: 22

View user's profile Send private message

PostPosted: Wed Oct 28, 2009 1:23 pm     Reply with quote

I am using microchip's demo board: PICDEM.NET 2,
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en028217

and using the SPI port 2 from J6 on the board to connect to the sensor eval pcb, the pinouts are correct because i am getting good data at the high freq.
I am using CCS Compiler version 4.090. I have been using the debugger, ICD-U64, and ICD firmware 2.72. I also tried using it without the debugger, and it gives me the same problem with the hang up ( iam monitoring the chip select, MISO, MOSI and CLK on the o'scope).

When it hangs up, chip select line is low, SCK is High, MOSI and MISO are low. When i stop it from running, the cursor is stopped at the spi_read2(0); line.

the code is as follows:

Code:


#include "C:\Program Files\PICC\ethernet2\18F97J60.H"
#device ICD=TRUE
#device adc=10
#use delay(clock=25M)
#fuses HS
#fuses NOIESO
#fuses NOFCMEN
#fuses PRIMARY
#fuses ETHLED
#fuses NOWDT
#fuses NOPROTECT
#fuses DEBUG
#fuses NOSTVREN

#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)

int16 inclin_x_int16;
int lo_byte_x,high_byte_x,high_byte_x_and;
int lo_byte,high_byte,dummy;

#byte LATD    =  0xF8C
#byte PORTD    =  0xF83
#byte TRISD    =  0xF95

#bit RD0          = LATD .0
#bit RD1          = LATD .1
#bit RD2          = LATD .2
#bit RD3          = LATD .3
#bit ADIS_SDO     = LATD .4
#bit ADIS_SDI     = PORTD.5
#bit ADIS_CLK     = LATD .6
#bit CS1          = LATD .7
#define     DDIRD    0x20  //all outputs except D5 (SDI)
#define     INITD       0x00
int8 adis16209_read8(int8 reg_addr)
{
int8 retval;

CS1 = 0;       //chip select
spi_write2(reg_addr & 0x3F);
spi_write2(0x00);
CS1 = 1;
delay_us(100);
CS1 = 0;
high_byte = spi_read2(0);
retval = spi_read2(0);
lo_byte = retval;
CS1 = 1;       //chip select

delay_us(200);

return(retval);
}
void main()
{
PORTD = INITD;
TRISD = DDIRD;

delay_ms(200);
CS1 = 1;
setup_spi2(SPI_MASTER|SPI_MODE_3|SPI_CLK_DIV_64);
delay_ms(200);
high_byte = 0;
lo_byte = 0;
lo_byte_x = 0;
high_byte_x = 0;
while(1)
{
 
   dummy = adis16209_read8(0x0E);
   high_byte_x = high_byte;
   lo_byte_x = lo_byte;

   high_byte_x_and = high_byte_x & 0x3F;
   inclin_x_int16 = high_byte_x_and<<8;
   inclin_x_int16 = inclin_x_int16 + lo_byte_x;   

   delay_ms(300);
}  // end of while(1)

} //end of main()

//************************
//************************
//the  18F97J60.H
#device PIC18F97J60
#nolist
//////// Program memory: 65532x16  Data RAM: 4096  Stack: 31
//////// I/O: 70   Analog Pins: 16
//////// C Scratch area: 00   ID Location: 0000
//////// Fuses: HS,H4_SW,EC_IO,E4_SW_IO,DEBUG,NODEBUG,XINST,NOXINST,STVREN
//////// Fuses: NOSTVREN,WDT,NOWDT,PROTECT,NOPROTECT,WDT1,WDT2,WDT4,WDT8
//////// Fuses: WDT16,WDT32,WDT64,WDT128,WDT256,WDT512,WDT1024,WDT2048
//////// Fuses: WDT4096,WDT8192,WDT16384,WDT32768,FCMEN,NOFCMEN,IESO,NOIESO
//////// Fuses: CCP2C1,CCP2E7,PRIMARY,INTRC,ECCPE,ECCPH,ETHLED,NOETHLED,WAIT
//////// Fuses: NOWAIT,BW16,BW8,MCU,EMCU12,EMCU16,EMCU20,EASHFT,NOEASHFT
////////
////////////////////////////////////////////////////////////////// I/O
// Discrete I/O Functions: SET_TRIS_x(), OUTPUT_x(), INPUT_x(),
//                         PORT_x_PULLUPS(), INPUT(),
//                         OUTPUT_LOW(), OUTPUT_HIGH(),
//                         OUTPUT_FLOAT(), OUTPUT_BIT()
// Constants used to identify pins in the above are:

#define PIN_A0  31744
#define PIN_A1  31745
#define PIN_A2  31746
#define PIN_A3  31747
#define PIN_A4  31748
#define PIN_A5  31749

#define PIN_B0  31752
#define PIN_B1  31753
#define PIN_B2  31754
#define PIN_B3  31755
#define PIN_B4  31756
#define PIN_B5  31757
#define PIN_B6  31758
#define PIN_B7  31759

#define PIN_C0  31760
#define PIN_C1  31761
#define PIN_C2  31762
#define PIN_C3  31763
#define PIN_C4  31764
#define PIN_C5  31765
#define PIN_C6  31766
#define PIN_C7  31767

#define PIN_D0  31768
#define PIN_D1  31769
#define PIN_D2  31770
#define PIN_D3  31771
#define PIN_D4  31772
#define PIN_D5  31773
#define PIN_D6  31774
#define PIN_D7  31775

#define PIN_E0  31776
#define PIN_E1  31777
#define PIN_E2  31778
#define PIN_E3  31779
#define PIN_E4  31780
#define PIN_E5  31781
#define PIN_E6  31782
#define PIN_E7  31783

#define PIN_F0  31784
#define PIN_F1  31785
#define PIN_F2  31786
#define PIN_F3  31787
#define PIN_F4  31788
#define PIN_F5  31789
#define PIN_F6  31790
#define PIN_F7  31791

#define PIN_G0  31792
#define PIN_G1  31793
#define PIN_G2  31794
#define PIN_G3  31795
#define PIN_G4  31796
#define PIN_G5  31797
#define PIN_G6  31798
#define PIN_G7  31799

#define PIN_H0  31800
#define PIN_H1  31801
#define PIN_H2  31802
#define PIN_H3  31803
#define PIN_H4  31804
#define PIN_H5  31805
#define PIN_H6  31806
#define PIN_H7  31807

#define PIN_J0  31808
#define PIN_J1  31809
#define PIN_J2  31810
#define PIN_J3  31811
#define PIN_J4  31812
#define PIN_J5  31813
#define PIN_J6  31814
#define PIN_J7  31815

////////////////////////////////////////////////////////////////// Useful defines
#define FALSE 0
#define TRUE 1

#define BYTE int8
#define BOOLEAN int1

#define getc getch
#define fgetc getch
#define getchar getch
#define putc putchar
#define fputc putchar
#define fgets gets
#define fputs puts

////////////////////////////////////////////////////////////////// Control
// Control Functions:  RESET_CPU(), SLEEP(), RESTART_CAUSE()
// Constants returned from RESTART_CAUSE() are:

#define WDT_TIMEOUT       7   
#define MCLR_FROM_SLEEP  11   
#define MCLR_FROM_RUN    15   
#define NORMAL_POWER_UP  12   
#define BROWNOUT_RESTART 14   
#define WDT_FROM_SLEEP   3     
#define RESET_INSTRUCTION 0   
////////////////////////////////////////////////////////////////// Timer 0
// Timer 0 (AKA RTCC)Functions: SETUP_COUNTERS() or SETUP_TIMER_0(),
//                              SET_TIMER0() or SET_RTCC(),
//                              GET_TIMER0() or GET_RTCC()
// Constants used for SETUP_TIMER_0() are:
#define RTCC_INTERNAL   0
#define RTCC_EXT_L_TO_H 32
#define RTCC_EXT_H_TO_L 48

#define RTCC_DIV_1      8
#define RTCC_DIV_2      0
#define RTCC_DIV_4      1
#define RTCC_DIV_8      2
#define RTCC_DIV_16     3
#define RTCC_DIV_32     4
#define RTCC_DIV_64     5
#define RTCC_DIV_128    6
#define RTCC_DIV_256    7

#define RTCC_OFF        0x80 

#define RTCC_8_BIT      0x40 

// Constants used for SETUP_COUNTERS() are the above
// constants for the 1st param and the following for
// the 2nd param:

////////////////////////////////////////////////////////////////// WDT
// Watch Dog Timer Functions: SETUP_WDT() or SETUP_COUNTERS() (see above)
//                            RESTART_WDT()
// WDT base is 4ms
//
#define WDT_ON        0x100
#define WDT_OFF       0

////////////////////////////////////////////////////////////////// Timer 1
// Timer 1 Functions: SETUP_TIMER_1, GET_TIMER1, SET_TIMER1
// Constants used for SETUP_TIMER_1() are:
//      (or (via |) together constants from each group)
#define T1_DISABLED         0
#define T1_INTERNAL         0x85
#define T1_EXTERNAL         0x87
#define T1_EXTERNAL_SYNC    0x83

#define T1_CLK_OUT          8

#define T1_DIV_BY_1         0
#define T1_DIV_BY_2         0x10
#define T1_DIV_BY_4         0x20
#define T1_DIV_BY_8         0x30

////////////////////////////////////////////////////////////////// Timer 2
// Timer 2 Functions: SETUP_TIMER_2, GET_TIMER2, SET_TIMER2
// Constants used for SETUP_TIMER_2() are:
#define T2_DISABLED         0
#define T2_DIV_BY_1         4
#define T2_DIV_BY_4         5
#define T2_DIV_BY_16        6

////////////////////////////////////////////////////////////////// Timer 3
// Timer 3 Functions: SETUP_TIMER_3, GET_TIMER3, SET_TIMER3
// Constants used for SETUP_TIMER_3() are:
//      (or (via |) together constants from each group)
#define T3_DISABLED         0
#define T3_INTERNAL         0x85
#define T3_EXTERNAL         0x87
#define T3_EXTERNAL_SYNC    0x83

#define T3_DIV_BY_1         0
#define T3_DIV_BY_2         0x10
#define T3_DIV_BY_4         0x20
#define T3_DIV_BY_8         0x30

// OR in one of the following to use timer 3 with a CCP unit
#define  T3_CCP1_TO_5  0x48
#define  T3_CCP2_TO_5  0x8
#define  T3_CCP3_TO_5  0x40


////////////////////////////////////////////////////////////////// Timer 4
// Timer 4 Functions: SETUP_TIMER_4, GET_TIMER4, SET_TIMER4
// Constants used for SETUP_TIMER_4() are:
#define T4_DISABLED         0
#define T4_DIV_BY_1         4
#define T4_DIV_BY_4         5
#define T4_DIV_BY_16        6

////////////////////////////////////////////////////////////////// CCP
// CCP Functions: SETUP_CCPx, SET_PWMx_DUTY
// CCP Variables: CCP_x, CCP_x_LOW, CCP_x_HIGH
// Constants used for SETUP_CCPx() are:
#define CCP_OFF                         0
#define CCP_CAPTURE_FE                  4
#define CCP_CAPTURE_RE                  5
#define CCP_CAPTURE_DIV_4               6
#define CCP_CAPTURE_DIV_16              7
#define CCP_COMPARE_SET_ON_MATCH        8
#define CCP_COMPARE_CLR_ON_MATCH        9
#define CCP_COMPARE_INT                 0xA
#define CCP_COMPARE_INT_AND_TOGGLE      0x2       
#define CCP_COMPARE_RESET_TIMER         0xB
#define CCP_PWM                         0xC
#define CCP_PWM_PLUS_1                  0x1c
#define CCP_PWM_PLUS_2                  0x2c
#define CCP_PWM_PLUS_3                  0x3c
//#define CCP_USE_TIMER3                0x100  OBSOLETE, SEE TIMER-3     
#word   CCP_1    =                      getenv("SFR:CCPR1L")
#byte   CCP_1_LOW=                      getenv("SFR:CCPR1L")
#byte   CCP_1_HIGH=                     getenv("SFR:CCPR1H")
// The following should be used with the ECCP unit only (or these in)
#define CCP_PWM_H_H                     0x0c
#define CCP_PWM_H_L                     0x0d
#define CCP_PWM_L_H                     0x0e
#define CCP_PWM_L_L                     0x0f

#define CCP_PWM_FULL_BRIDGE             0x40
#define CCP_PWM_FULL_BRIDGE_REV         0xC0
#define CCP_PWM_HALF_BRIDGE             0x80

#define CCP_SHUTDOWN_ON_COMP1           0x100000
#define CCP_SHUTDOWN_ON_COMP2           0x200000
#define CCP_SHUTDOWN_ON_COMP            0x300000
#define CCP_SHUTDOWN_ON_INT0            0x400000
#define CCP_SHUTDOWN_ON_COMP1_INT0      0x500000
#define CCP_SHUTDOWN_ON_COMP2_INT0      0x600000
#define CCP_SHUTDOWN_ON_COMP_INT0       0x700000

#define CCP_SHUTDOWN_AC_L               0x000000
#define CCP_SHUTDOWN_AC_H               0x040000
#define CCP_SHUTDOWN_AC_F               0x080000

#define CCP_SHUTDOWN_BD_L               0x000000
#define CCP_SHUTDOWN_BD_H               0x010000
#define CCP_SHUTDOWN_BD_F               0x020000

#define CCP_SHUTDOWN_RESTART            0x80000000

#word   CCP_2    =                      getenv("SFR:CCPR2L")
#byte   CCP_2_LOW=                      getenv("SFR:CCPR2L")
#byte   CCP_2_HIGH=                     getenv("SFR:CCPR2H")
#word   CCP_3    =                      getenv("SFR:CCPR3L")
#byte   CCP_3_LOW=                      getenv("SFR:CCPR3L")
#byte   CCP_3_HIGH=                     getenv("SFR:CCPR3H")
#word   CCP_4    =                      getenv("SFR:CCPR4L")
#byte   CCP_4_LOW=                      getenv("SFR:CCPR4L")
#byte   CCP_4_HIGH=                     getenv("SFR:CCPR4H")
#word   CCP_5    =                      getenv("SFR:CCPR5L")
#byte   CCP_5_LOW=                      getenv("SFR:CCPR5L")
#byte   CCP_5_HIGH=                     getenv("SFR:CCPR5H")

////////////////////////////////////////////////////////////////// PSP
// PSP Functions: SETUP_PSP, PSP_INPUT_FULL(), PSP_OUTPUT_FULL(),
//                PSP_OVERFLOW(), INPUT_D(), OUTPUT_D()
// PSP Variables: PSP_DATA
// Constants used in SETUP_PSP() are:
#define PSP_ENABLED                     0x10
#define PSP_DISABLED                    0

#byte  PSP_DATA=    0xF83               

////////////////////////////////////////////////////////////////// SPI
// SPI Functions: SETUP_SPI, SPI_WRITE, SPI_READ, SPI_DATA_IN
// Constants used in SETUP_SPI() are:
#define SPI_MASTER       0x20
#define SPI_SLAVE        0x24
#define SPI_L_TO_H       0
#define SPI_H_TO_L       0x10
#define SPI_CLK_DIV_4    0
#define SPI_CLK_DIV_16   1
#define SPI_CLK_DIV_64   2
#define SPI_CLK_T2       3
#define SPI_SS_DISABLED  1

#define SPI_SAMPLE_AT_END 0x8000
#define SPI_XMIT_L_TO_H  0x4000

////////////////////////////////////////////////////////////////// UART
// Constants used in setup_uart() are:
// FALSE - Turn UART off
// TRUE  - Turn UART on
#define UART_ADDRESS           2
#define UART_DATA              4
#define UART_AUTODETECT        8
#define UART_AUTODETECT_NOWAIT 9
#define UART_WAKEUP_ON_RDA     10
#define UART_SEND_BREAK        13
////////////////////////////////////////////////////////////////// COMP
// Comparator Variables: C1OUT, C2OUT
// Constants used in setup_comparator() are:
#define F6_F5_F4_F5  0x70ff04
#define F6_F5_F4_F3_OUT_ON_F2_F1  0x78F903
#define F6_F5_F4_F5_OUT_ON_F2_F1  0x70F905
#define NC_NC_NC_NC  0x00ff07
#define F6_F5_F4_F3  0x78ff02
#define F6_F5_NC_NC_OUT_ON_F2  0x60FB01
#define F6_VR_F4_VR 0x50ff06
#define F5_VR_F3_VR 0x28ff0e

#bit C1OUT = 0xfb4.6
#bit C2OUT = 0xfb4.7

////////////////////////////////////////////////////////////////// VREF
// Constants used in setup_vref() are:
//
#define VREF_LOW  0xa0
#define VREF_HIGH 0x80
// Or (with |) the above with a number 0-15
#define VREF_F5   0x40
#define VREF_COMP 0x10


////////////////////////////////////////////////////////////////// INTERNAL RC
// Constants used in setup_oscillator() are:
#define OSC_PLL_5_DIV_2   0x5000
#define OSC_PLL_5_DIV_3   0x4000
#define OSC_PLL_5_DIV_4   0xF000
#define OSC_PLL_5_DIV_6   0x7000
#define OSC_PLL_5_DIV_9   0x6000
#define OSC_INTRC   3
#define OSC_NORMAL  2
#define OSC_TIMER1  1
#define OSC_IDLE_ON_SLEEP  0x80
// Result may be (ignore all other bits)
#define OSC_STATE_EXT_RUNNING 8

////////////////////////////////////////////////////////////////// EXT MEM
// External Memory Functions: SETUP_EXTERNAL_MEMORY(), READ_EXTERNAL_MEMORY(),
//                            WRITE_EXTERNAL_MEMORY()
//
// Constants used in SETUP_EXTERNAL_MEMORY() are:
#define EXTMEM_BYTE_WRITE  0
#define EXTMEM_BYTE_SELECT 1
#define EXTMEM_WORD_WRITE  2
#define EXTMEM_DISABLE     0x80
// Use one of the above and optionaly OR in one of:
#define EXTMEM_WAIT_0 0x30
#define EXTMEM_WAIT_1 0x20
#define EXTMEM_WAIT_2 0x10
#define EXTMEM_WAIT_3 0x00  // Default


////////////////////////////////////////////////////////////////// ADC
// ADC Functions: SETUP_ADC(), SETUP_ADC_PORTS() (aka SETUP_PORT_A),
//                SET_ADC_CHANNEL(), READ_ADC()
// Constants used for SETUP_ADC() are:
#define ADC_OFF               0           // ADC Off
#define ADC_CLOCK_DIV_2   0x100
#define ADC_CLOCK_DIV_4    0x04
#define ADC_CLOCK_DIV_8    0x01
#define ADC_CLOCK_DIV_16   0x05
#define ADC_CLOCK_DIV_32   0x02
#define ADC_CLOCK_DIV_64   0x06
#define ADC_CLOCK_INTERNAL 0x07           // Internal 2-6us
// The following may be OR'ed in with the above using |
#define ADC_TAD_MUL_0      0x00
#define ADC_TAD_MUL_2      0x08
#define ADC_TAD_MUL_4      0x10
#define ADC_TAD_MUL_6      0x18
#define ADC_TAD_MUL_8      0x20
#define ADC_TAD_MUL_12     0x28
#define ADC_TAD_MUL_16     0x30
#define ADC_TAD_MUL_20     0x38

// Constants used in SETUP_ADC_PORTS() are:
#define NO_ANALOGS  0x0F  // None

#define ALL_ANALOG  0x00  // A0 A1 A2 A3 A5 F0 F1 F2 F3 F4 F5 F6 H4 H5 H6 H7
#define AN0_TO_AN13 0x01  // A0 A1 A2 A3 A5 F0 F1 F2 F3 F4 F5 F6 H4 H5       
#define AN0_TO_AN12 0x02  // A0 A1 A2 A3 A5 F0 F1 F2 F3 F4 F5 F6 H4         
#define AN0_TO_AN11 0x03  // A0 A1 A2 A3 A5 F0 F1 F2 F3 F4 F5 F6             
#define AN0_TO_AN10 0x04  // A0 A1 A2 A3 A5 F0 F1 F2 F3 F4 F5                 
#define AN0_TO_AN9  0x05  // A0 A1 A2 A3 A5 F0 F1 F2 F3 F4                   
#define AN0_TO_AN8  0x06  // A0 A1 A2 A3 A5 F0 F1 F2 F3                       
#define AN0_TO_AN7  0x07  // A0 A1 A2 A3 A5 F0 F1 F2                         
#define AN0_TO_AN6  0x08  // A0 A1 A2 A3 A5 F0 F1                             
#define AN0_TO_AN5  0x09  // A0 A1 A2 A3 A5 F0                               
#define AN0_TO_AN4  0x0A  // A0 A1 A2 A3 A5
#define AN0_TO_AN3  0x0B  // A0 A1 A2 A3
#define AN0_TO_AN2  0x0C  // A0 A1 A2
#define AN0_TO_AN1  0x0D  // A0 A1
#define AN0         0x0E  // A0


// The following may be OR'ed in with the above using |
#define VSS_VDD               0x00              // Range 0-Vdd
#define VREF_VREF             0x30              // Range VrefL-VrefH
#define VREF_VDD              0x20              // Range VrefL-Vdd
#define VSS_VREF              0x10              // Range 0-VrefH


// Constants used in READ_ADC() are:
#define ADC_START_AND_READ     7   // This is the default if nothing is specified
#define ADC_START_ONLY         1
#define ADC_READ_ONLY          6





////////////////////////////////////////////////////////////////// INT
// Interrupt Functions: ENABLE_INTERRUPTS(), DISABLE_INTERRUPTS(),
//                      CLEAR_INTERRUPT(), INTERRUPT_ACTIVE(),
//                      EXT_INT_EDGE()
//
// Constants used in EXT_INT_EDGE() are:
#define L_TO_H              0x40
#define H_TO_L                 0
// Constants used in ENABLE/DISABLE_INTERRUPTS() are:
#define GLOBAL                    0xF2C0
#define INT_RTCC                  0xF220
#define INT_TIMER0                0xF220
#define INT_TIMER1                0x9D01
#define INT_TIMER2                0x9D02
#define INT_TIMER3                0xA002
#define INT_EXT                   0xF210
#define INT_EXT1                  0xF008
#define INT_EXT2                  0xF010
#define INT_EXT3                  0xF020
#define INT_RB                    0xFFF208
#define INT_PSP                   0x9D80
#define INT_AD                    0x9D40
#define INT_RDA                   0x9D20
#define INT_TBE                   0x9D10
#define INT_SSP                   0x9D08
#define INT_CCP1                  0x9D04
#define INT_CCP2                  0xA001
#define INT_BUSCOL                0xA008
#define INT_COMP                  0xA040
#define INT_RDA2                  0xA320
#define INT_TBE2                  0xA310
#define INT_TIMER4                0xA308
#define INT_CCP3                  0xA301
#define INT_CCP4                  0xA302
#define INT_CCP5                  0xA304
#define INT_OSCF                  0xA080
#define INT_BUSCOL2               0xA340
#define INT_SSP2                  0xA380
#define INT_ETH                   0xA020


#BYTE   SSP2CON2      =   0xF62         // used in I2C mode
#BIT  SEN            =    SSP2CON2 .0  // Start condition enabled/Stretch Enabled bit
#BIT  RSEN           =    SSP2CON2 .1  // Repeated start condition enabled bit
#BIT  PEN            =    SSP2CON2 .2  // Stop condition enabled bit
#BIT  RCEN           =    SSP2CON2 .3  // Receive enable bit
#BIT  ACKEN          =    SSP2CON2 .4  // Acknowledge sequence enable bit
#BIT  ACKDT          =    SSP2CON2 .5  // Acknowledge data bit
#BIT  ACKSTAT        =    SSP2CON2 .6  // Acknowledge status bit
#BIT  GCEN           =    SSP2CON2 .7  // General Call enable bit

#BYTE   SSP2CON1      =   0xF63
#BIT  SSP_CKP       =    SSP2CON1 .4     //
         // i2c mode:            //   1 = release clock, 0 = hold clock low (clock stretch) used to ensure data setup time
         // spi mode:            //   1 = clock idles high, 0 = clock idles low
#BIT  SSPEN       =    SSP2CON1 .5
         // i2c mode:            // 1 = enables SDA and SCL pins as i2c pins
         // spi mode:            //   1 = enables SCK, SDI, SDO, and SS as serial port pins
         //   both modes:            // 0 = disables serial port and configures pins as i/o port pins
#BIT  SSPOV       =    SSP2CON1 .6     // 1 = receive overflow - must be cleared by software
#BIT  WCOL        =    SSP2CON1 .7     // 1 = transmit overflow - must be cleared by software
         // lower 4 bits of SSPCON1 are SSPM3:SSPM0
            //   1111   I2C Slave Mode, 10-bit address with START and STOP bit interrupts enables
            //   1110   I2C Slave Mode,  7-bit address with START and STOP bit interrupts enables
            //   1011   I2C Firmware Controlled Master mode (Slave Idle)
            //   1000   I2C Master Mode,  clock = Fosc/(4*(SSPADD+1))
            //   0111   I2C Slave Mode, 10-bit address
            //   0110   I2C Slave Mode,  7-bit address
            // 0101   SPI Slave Mode, clock = SCK pin, SS pin control disabled (ignored)
            // 0100   SPI Slave Mode, clock = SCK pin, SS pin control enabled
            // 0011   SPI Master Mode, clock = TMR2 output/2
            // 0010   SPI Master Mode, clock = Fosc/64
            // 0001   SPI Master Mode, clock = Fosc/16
            // 0000   SPI Master Mode, clock = Fosc/4
#BYTE   SSP2STAT      =   0xF64
#BIT  SSP_BF        =    SSP2STAT .0    // 1 = transmit/receive complete, buffer full
#BIT  SSP_UA        =    SSP2STAT .1    // Update address bit (I2C 10-bit Slave mode only)
         // Slave mode            // 1 = indicates that the user needs to update address in SSPADD
                                 // 0 = address does not need to be updated
#BIT  SSP_RW       = SSP2STAT .2    // R/W bit (I2C mode only)
         // Slave mode            // 1 = read
                                 // 0 = write
         // Master mode            // 1 = Transmit is in progress
                                 // 0 = Transmit is not in progress
#BIT  SSP_START    = SSP2STAT .3    // Start bit (I2C mode only)
                                 // 1 = indicates START bit has been detected last
                                 // 0 = START bit was not detected last
                                 // bit is cleared on RESET and when SSPEN is cleared
#BIT  SSP_STOP     = SSP2STAT .4    // Stop bit (I2C mode only)
                                 // 1 = indicates STOP bit has been detected last
                                 // 0 = STOP bit was not detected last
                                 // bit is cleared on RESET and when SSPEN is cleared
#BIT  SSP_DA        = SSP2STAT .5    // Data/Address bit (I2C mode only)
                                 // Master mode reserved
         // Slave mode            // 1 = indicates last byte received/transmitted was data
                                 // 0 = indicates last byte received/transmitted was address
#BIT  SSP_CKE       = SSP2STAT .6
         // SPI Mode             // 1 = Clock Edge select
               //   if CKP = 0      // 1 = data transmitted on rising edge of SCK
                                 // 0 = data transmitted on falling edge of SCK
               //   if CKP = 1      // 1 = data transmitted on falling edge of SCK
                                 // 0 = data transmitted on rising edge of SCK
         // I2C Mode             // 1 = SMBus select bit
                                 // 1 = Enable SMBus specific inputs
                                 // 0 = Disable SMBus specific inputs
#BIT  SSP_SMP       = SSP2STAT .7
         // SPI mode               // 1/0 in Master Mode; must be 0 in Slave Mode
                                 // 1 = input data sampled at end of data output time
                                 // 0 = input data sampled at middle of data output time
         // I2C mode               // 1 = slew rate control disabled for Standard Speed mode (100k/1M Hz)
                                 // 0 = slew rate control enable for High Speed mode (400 kHz)

#BYTE SSP2BUF = 0xF66


#list
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Oct 28, 2009 3:15 pm     Reply with quote

You have heavily modified the routine and I don't know why.
I can't help any more on this. Maybe someone else can help.
Guest








PostPosted: Thu Feb 11, 2010 1:48 pm     Reply with quote

I know this thread has been dead for a while now but I may have come across a solution to this problem.

I'm using a PIC18F26K20 @ 40Mhz and a ADIS16300. I too was having a problem using SPI_CLK_DIV_64 as the processor would lock up after the first 8 clock pulses that were sent to the ADIS. I also found that this wouldn't happen if I used SPI_CLK_DIV_16 (although the data would be corrupted as I needed < 1Mhz for burst mode).

I found that when I used the following code with DIV_64 it didn't work (chip select commands and timing delays are removed):

Code:

   spi_write(0x3E); //burst mode
   spi_write(0); //burst mode


but when I used the following it works perfectly:

Code:

   spi_write(0x3E); //burst mode
        delay_cycles(3);
   spi_write(0); //burst mode


This is strange because on the previous MCU I was using, the PIC18F2320, the first code section worked perfectly. It seems a delay may be needed between the first 8 clock pulses and the second 8 clock pulses on some PICs. I also found out that anything below 3 cycles for the delay would cause the same behaviour as using no delay at all. Anyone else experienced this?
dpend



Joined: 24 Apr 2010
Posts: 3

View user's profile Send private message

PostPosted: Tue Apr 27, 2010 10:09 pm     Reply with quote

Anonymous wrote:
It seems a delay may be needed between the first 8 clock pulses and the second 8 clock pulses on some PICs. I also found out that anything below 3 cycles for the delay would cause the same behaviour as using no delay at all. Anyone else experienced this?


I have only just experienced the same thing. I'm running a PIC18F24J10 on a 20meg clock, and one of the SPI devices needs an SPI clock of 50kHz or lower. Only in SPI modes 2 and 3 do I need to add in a delay, but it's of the order of 10's of us in my case.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
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