|
|
View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Oct 26, 2009 1:56 pm |
|
|
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:
I'll continue looking at the problem. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Oct 26, 2009 2:11 pm |
|
|
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
|
|
Posted: Mon Oct 26, 2009 2:19 pm |
|
|
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
|
|
Posted: Mon Oct 26, 2009 2:22 pm |
|
|
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
|
|
Posted: Mon Oct 26, 2009 4:21 pm |
|
|
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
|
|
Posted: Mon Oct 26, 2009 4:42 pm |
|
|
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
|
|
Posted: Wed Oct 28, 2009 8:20 am |
|
|
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
|
|
Posted: Wed Oct 28, 2009 11:16 am |
|
|
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
|
|
Posted: Wed Oct 28, 2009 1:23 pm |
|
|
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
|
|
Posted: Wed Oct 28, 2009 3:15 pm |
|
|
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
|
|
Posted: Thu Feb 11, 2010 1:48 pm |
|
|
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
|
|
Posted: Tue Apr 27, 2010 10:09 pm |
|
|
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. |
|
|
|
|
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
|