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

PIC16F887 SPI help
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: Sat Mar 31, 2012 8:35 pm     Reply with quote

Did you buy a evaluation board for the TDC chip ? Or did you build it
yourself ? If you bought the board, then post a link to the webpage for it.
Post a list of your connections between the PIC and the TDC chip.

This appnote has a complete program on page 23. It could be translated
to CCS.
http://www.acam.de/fileadmin/Download/pdf/English/AN029_en.pdf

They have a little section near the start of the code that does what
you want. It tests if you can Read/write to the chip. It's commented out
in their code because it's only a test. It's called:
Quote:

read-write communication test

They do not have any printf code to show the results.


Your posted code is only a snippet or a code fragment. The TDC
requires a full test program to make it work. I don't know if you
understand that.

For example, at the start of their test program, they do this:
Quote:

gp21_send_1byte(0x50); // Power on Reset to GP21
Dly100us((void*)5); // 500 us wait for GP21

I doubt if you have this in your program.

Their example code appears to use an STM32 microcontroller and C
compiler. I will look at this code later and see if I can translate enough
of it to make a minimal test program. I can't do it now. Maybe tomorrow.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Apr 01, 2012 4:42 pm     Reply with quote

I translated the R/W test code from the following TDC-GP21 appnote:
http://www.acam.de/fileadmin/Download/pdf/English/AN029_en.pdf
I translated the first few lines of main(), and also the necessary
support routines to do the R/W test. The example code starts on page 23.

The R/W test is described on page 19 of the data sheet, in this section:
3.1 Configuration registers
http://www.acam.de/fileadmin/Download/pdf/English/DB_GP21_en.pdf

The following code assumes that your hardware is all correct. I don't
have the TDC-GP21 chip or the Eval board to test this code, but I think it
has a good chance to work.
Code:

#include <16F887.h>
#fuses INTRC_IO,NOWDT,PUT,NOLVP
#use delay(clock=4M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#define SSEL   PIN_C0

#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)

//---------------------------------------------
void gp21_send_1byte (int8 gp21_opcode_byte)
{
output_low(SSEL);
spi_write(gp21_opcode_byte);
output_high(SSEL);
}

//---------------------------------------------
void gp21_wr_config_reg (int8 opcode_address, int32 config_reg_data)
{
int8 Data_Byte_Lo;
int8 Data_Byte_Mid1;
int8 Data_Byte_Mid2;
int8 Data_Byte_Hi;

Data_Byte_Lo = config_reg_data;
Data_Byte_Mid1 = config_reg_data >> 8;
Data_Byte_Mid2 = config_reg_data >> 16;
Data_Byte_Hi = config_reg_data >> 24;


output_low(SSEL);

spi_write(opcode_address);  // RAM WR OPCODE+ADDRESS

spi_write(Data_Byte_Hi);    // DATA BYTE HIGH
spi_write(Data_Byte_Mid2);  // DATA MID - 2
spi_write(Data_Byte_Mid1);  // DATA MID - 1
spi_write(Data_Byte_Lo);    // DATA LOW

output_high(SSEL);
}

//-----------------------------------------------
int32 gp21_read_4bytes(int8 read_opcode_addr)
{
int32 Result_read;

Result_read=0;

//.............. Result word = 4 Byte = 32 bits......................
output_low(SSEL);

spi_write(read_opcode_addr); // READ OPCODE + Address 1

//Reading byte1
Result_read |= spi_read(0xFF);
Result_read = Result_read << 8;

//Reading byte2
Result_read |= spi_read(0xFF);
Result_read = Result_read << 8;

//Reading byte3
Result_read |= spi_read(0xFF);
Result_read = Result_read << 8;

//Reading byte4
Result_read |= spi_read(0xFF);

output_high(SSEL);

return Result_read;
}

//==========================================
void main()
{
int32 result;

printf("Start \n\r");

setup_spi(SPI_MASTER | SPI_MODE_1 | SPI_CLK_DIV_4);
output_high(SSEL); // Initialize Slave Select to inactive level
delay_ms(100);

gp21_send_1byte(0x50);  // Power on Reset to GP21
delay_us(500);          // 500 us wait for GP21

//----------- read-write communication test --------------
gp21_wr_config_reg(0x81, 0xABCDEF34); // Config reg 1

// Opcode 0xB5:  Read content of highest 8 Bits of write
// register 1, to be used for testing the communication.
result = gp21_read_4bytes(0xB5);

printf("R/W Test result = %lx \n\r", result);   

while(1);
}
   
searuff



Joined: 22 Mar 2012
Posts: 13

View user's profile Send private message

PostPosted: Sun Apr 01, 2012 10:08 pm     Reply with quote

PCM programmer wrote:
I translated the R/W test code from the following TDC-GP21 appnote:
http://www.acam.de/fileadmin/Download/pdf/English/AN029_en.pdf
I translated the first few lines of main(), and also the necessary
support routines to do the R/W test. The example code starts on page 23.

The R/W test is described on page 19 of the data sheet, in this section:
3.1 Configuration registers
http://www.acam.de/fileadmin/Download/pdf/English/DB_GP21_en.pdf

The following code assumes that your hardware is all correct. I don't
have the TDC-GP21 chip or the Eval board to test this code, but I think it
has a good chance to work.
Code:

#include <16F887.h>
#fuses INTRC_IO,NOWDT,PUT,NOLVP
#use delay(clock=4M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#define SSEL   PIN_C0

#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)

//---------------------------------------------
void gp21_send_1byte (int8 gp21_opcode_byte)
{
output_low(SSEL);
spi_write(gp21_opcode_byte);
output_high(SSEL);
}

//---------------------------------------------
void gp21_wr_config_reg (int8 opcode_address, int32 config_reg_data)
{
int8 Data_Byte_Lo;
int8 Data_Byte_Mid1;
int8 Data_Byte_Mid2;
int8 Data_Byte_Hi;

Data_Byte_Lo = config_reg_data;
Data_Byte_Mid1 = config_reg_data >> 8;
Data_Byte_Mid2 = config_reg_data >> 16;
Data_Byte_Hi = config_reg_data >> 24;


output_low(SSEL);

spi_write(opcode_address);  // RAM WR OPCODE+ADDRESS

spi_write(Data_Byte_Hi);    // DATA BYTE HIGH
spi_write(Data_Byte_Mid2);  // DATA MID - 2
spi_write(Data_Byte_Mid1);  // DATA MID - 1
spi_write(Data_Byte_Lo);    // DATA LOW

output_high(SSEL);
}

//-----------------------------------------------
int32 gp21_read_4bytes(int8 read_opcode_addr)
{
int32 Result_read;

Result_read=0;

//.............. Result word = 4 Byte = 32 bits......................
output_low(SSEL);

spi_write(read_opcode_addr); // READ OPCODE + Address 1

//Reading byte1
Result_read |= spi_read(0xFF);
Result_read = Result_read << 8;

//Reading byte2
Result_read |= spi_read(0xFF);
Result_read = Result_read << 8;

//Reading byte3
Result_read |= spi_read(0xFF);
Result_read = Result_read << 8;

//Reading byte4
Result_read |= spi_read(0xFF);

output_high(SSEL);

return Result_read;
}

//==========================================
void main()
{
int32 result;

printf("Start \n\r");

setup_spi(SPI_MASTER | SPI_MODE_1 | SPI_CLK_DIV_4);
output_high(SSEL); // Initialize Slave Select to inactive level
delay_ms(100);

gp21_send_1byte(0x50);  // Power on Reset to GP21
delay_us(500);          // 500 us wait for GP21

//----------- read-write communication test --------------
gp21_wr_config_reg(0x81, 0xABCDEF34); // Config reg 1

// Opcode 0xB5:  Read content of highest 8 Bits of write
// register 1, to be used for testing the communication.
result = gp21_read_4bytes(0xB5);

printf("R/W Test result = %lx \n\r", result);   

while(1);
}
   


Hi, I have read the same document you posted. I wrote test code just like yours. I did sent 0x50 to the chip. I tried to write in reg0 and the read from it after 10ms delay, but I get 0. I have a question about your define of spi mode. Do I need to do all of them (mode0 to mode3)? Seems like you have 4 modes. When sending spi which mode it will use? I read about their datasheet and I think it should be SPI_L_TO_H. I think our team had tried to put 5V on the chip before. Maybe that burned the chip. I will keep trying. Thanks for your help.
searuff



Joined: 22 Mar 2012
Posts: 13

View user's profile Send private message

PostPosted: Sun Apr 01, 2012 10:15 pm     Reply with quote

I didn't buy the board for the tdc chip. I bought an adapter for it such that I can place it on the breadboard. I built the oscillator to it like the one in the example application note.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Apr 01, 2012 11:30 pm     Reply with quote

The setup_spi() statement clearly shows which SPI mode is used by
the program:
Quote:

setup_spi(SPI_MASTER | SPI_MODE_1 | SPI_CLK_DIV_4);


The four #define statements for the SPI modes are there for reference.
searuff



Joined: 22 Mar 2012
Posts: 13

View user's profile Send private message

PostPosted: Mon Apr 02, 2012 2:01 pm     Reply with quote

Hi, I tried your code and I read 0 for the result. I suspected the chip is burned. I just replaced with another one today and try again. I still read 0. In the datasheet http://www.acam.de/uploads/media/DB_GP21_en_02.pdf
2-4 first table Serial Interface it mentions timing for fck at 3.3v is 20MHz. Does it matter? Since I am using 4 MHz internal clock of the pic, and the maximum internal frequency of PIC16f887 is 8Mhz. I think I read it somewhere that spi clock can be slow. It does not have to be fast. Thanks for helping and the test code.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 02, 2012 2:09 pm     Reply with quote

20 MHz is the maximum SPI clock frequency. We are not using anything
close to that high. It's not a problem.

Do you have all the required external circuits ? Such as the 4 MHz
external crystal and associated capacitors and resistors ?

I think it would have been easier if you bought the Evalution board.
searuff



Joined: 22 Mar 2012
Posts: 13

View user's profile Send private message

PostPosted: Mon Apr 02, 2012 2:14 pm     Reply with quote

Yes we have build the external circuit including 4 MHz, 3.2kHz
external crystal and associated capacitors and resistors. I will try to call the chip company for further assistant. According to the datasheet and application note I have, it should work. But now I don't think I ever wrote in the chip's registers, or able to read from it. Thanks for the help. I will post further info if I get something back from the chip company
cheeloh1



Joined: 24 Mar 2012
Posts: 3

View user's profile Send private message

PostPosted: Mon Apr 02, 2012 9:27 pm     Reply with quote

I'm not sure if these subtleties are taken into account in the code but....

I think TDC can only read from register 5, so if you try to read from reg1 you may get nothing:
http://arduino.cc/forum/index.php?action=printpage;topic=64361.0

(From TDC datasheet)
TDC only supports:
Clock Phase Bit = 1
Clock Polarity Bit = 0

(From PIC datasheet):
SSP CONTROL REGISTER 1 needs to set polarity bit 4 on PIC:
http://ww1.microchip.com/downloads/en/DeviceDoc/41291D.pdf (page 179)

Just a few ideas I can think of.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 02, 2012 9:38 pm     Reply with quote

Quote:

TDC only supports:
Clock Phase Bit = 1
Clock Polarity Bit = 0

These settings are handled by the setup_spi() function when you specify
SPI_MODE_1 as the mode parameter.
searuff



Joined: 22 Mar 2012
Posts: 13

View user's profile Send private message

PostPosted: Tue Apr 03, 2012 4:18 pm     Reply with quote

Hi, I have a question. For your code
Code:
 #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

I remember you said that setup_spi can only use the physical pin, which is PIN_C5(SDO) and PIN_C4(SDI). Should I use your define xmit pin and rcv pin? I use pin_c5 as serial data out and I can measure the data out using a oscilloscope. I didn't use C6 and C7.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Apr 03, 2012 5:09 pm     Reply with quote

That's the UART module, and it's used for RS-232 communication.
It is not the same as the SSP module, which is used for SPI.
These are two separate modules, for different purposes, and they use
different pins from each other.
searuff



Joined: 22 Mar 2012
Posts: 13

View user's profile Send private message

PostPosted: Wed Apr 04, 2012 3:01 pm     Reply with quote

I called that company today and figure out the problem. It's the rst pin of the TDC chip. I have to send it to low to reset one time before using the spi interface. I hook it to high before since it's active low. But seems like in fast i need to manually reset it once. It's not written in the sample code so we all miss that. Thanks for everyone's help.
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