View previous topic :: View next topic |
Author |
Message |
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Sun Jul 11, 2010 3:12 pm |
|
|
Many Thanks PCM Programmer.
I will begin the test....and I post it on this forum for correct errors!
Have I to delete the LONG CODE??
I have to use this IC because I need for university exam but the function that I have to implement is initialize and set one frequency between 88 - 108 MHz.
Many thanks |
|
|
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Mon Jul 12, 2010 3:22 am |
|
|
Is correct something like that??
Code: |
#include <16F877.h>
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
#use delay(clock=4000000)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#define SEN PIN_B0
#define RST PIN_B1
// This function writes the slave address to the i2c bus.
// If a slave chip is at that address, it should respond to
// this with an "ACK". This function returns TRUE if an
// ACK was found. Otherwise it returns FALSE.
int8 get_ack_status(int8 address)
{
int8 status;
i2c_start();
status = i2c_write(address); // Status = 0 if got an ACK
i2c_stop();
if(status == 0)
return(TRUE);
else
return(FALSE);
}
//=================================
void main()
{
int8 i;
int8 status;
int8 count = 0;
printf("Start:\n\r");
delay_ms(1000);
// 2-WIRE SELECTION ON THE RISE OF RST
OUTPUT_LOW(RST); // RST = 0
OUTPUT_HIGH(SEN); // SEN = 1 and GPIO3 is left Floating
OUTPUT_LOW(PIN_C4); // SDIO = 0
OUTPUT_HIGH(PIN_C3); // SCLK = 1 SCLK must be high during the rising edge of RST
delay_us(150);
OUTPUT_HIGH(RST); // REISE THE RST
delay_ms(1); // Wait for Internal oscillator stabilazation
// Try all slave addresses from 0x10 to 0xEF.
// See if we get a response from any slaves
// that may be on the i2c bus.
for(i=0x10; i < 0xF0; i+=2)
{
status = get_ack_status(i);
if(status == TRUE)
{
printf("ACK addr: %X", i);
count++;
delay_ms(2000);
}
}
if(count == 0)
printf("\n\rNothing Found");
else
printf("\n\rFound %u chips", count);
while(1);
}
|
Many Thanks
Fabio |
|
|
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Tue Jul 13, 2010 12:48 pm |
|
|
Finally....I made PCB with 18F25J10 (3.3Volt ..compatible with SI4703).
So....in the next hours I will make a TEST for test the compatibility of the SI4703 with the I2C protocol.
I have only one question before starting my test:
--- On interface that have I2C have we to WRITE all REGISTERS after the [ START + ADDRESS + W + STOP + (WAIT ACK) ]??
My device has 6 register that I can write(read)...so...have I to write all together or can I write one for time??
Many Thanks
Fabio
IZ0CBG |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jul 13, 2010 1:19 pm |
|
|
Quote: |
have I to write all together or can I write one for time??
|
Look in the Programming guide that I gave you the link for:
http://www.daxia.com/%5C/bibis/upload/AN230.515.pdf
Read this section on page 24:
Quote: |
4.1. Programming in Command in 2-wire Control Interface Mode
All seven arguments bytes must be sent for all commands, and unused
arguments must be written 0x00.
|
Basically, I am reading the documentation for you. |
|
|
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Tue Jul 13, 2010 1:34 pm |
|
|
Many thanks and sorry for my errors ;(
In the next hours I will begin test...
Thank You Very Much
Fabio |
|
|
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Wed Jul 14, 2010 10:18 am |
|
|
Dear friends....
I have tested I2C of SI4703 using 18f25j10 and with my surprice...the device reply ack at the address 0x20!!
The question is that the device reply ack also if it is disconnect from power supply!!
I disconnected also the pin SDIO and then...the 18f25j10 can't see ack!!
Is this normal???Can the pullup resistors make this??
Many thanks
Fabio |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 14, 2010 12:09 pm |
|
|
Read the Programming Guide.
Quote: | 2.1.2. Hardware Powerdown |
It explains all the power-down modes. If you remove the main power
(Vdd) but keep the Vio power, the i2c bus will still be active. |
|
|
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Wed Jul 14, 2010 12:48 pm |
|
|
PCM programmer wrote: | Read the Programming Guide.
Quote: | 2.1.2. Hardware Powerdown |
It explains all the power-down modes. If you remove the main power
(Vdd) but keep the Vio power, the i2c bus will still be active. |
;) it is stranger
I disconnect also the Vio and the I2C is still active and send me ACK!
I'm happy that with your help I reached some positive results.
Now...I will start the communication but ..... I have to solve another question:
For my problem understanding datasheet I have not understood if I must use 32.768 kHz Clock or if the IC has a internal clock that provide 32.768 kHz.
I see:
The internal crystal oscillator requires an external 32.768 kHz crystal as shown in
2. "Typical Application Schematic" on page 14. The oscillator must be enabled before
powerup (ENABLE = 1) as shown in Figure 9, “Initialization Sequence,” on page 21. It
should only be disabled after powerdown (ENABLE = 0). Bits 13:0 of register 07h
must be preserved as 0x0100 while in powerdown and as 0x3C04 while in powerup.
Refer to Si4702/03 Internal Crystal Oscillator Errata.
and
4.7. Reference Clock
The Si4702/03-C19 accepts a 32.768 kHz reference
clock to the RCLK pin. The reference clock is required
whenever the ENABLE bit is set high. Refer to Table 3,
“DC Characteristics1,” on page 5 for input switching
voltage levels and Table 8, "FM Receiver
Characteristics," on page 12 for frequency tolerance
information.
An onboard crystal oscillator is available to generate the
32.768 kHz reference when an external crystal and load
capacitors are provided. Refer to 2. "Typical Application
Schematic" on page 14. The oscillator must be enabled
or disabled while in powerdown (ENABLE = 0) as shown
in Figure 9, “Initialization Sequence,” on page 21.
So I thing that I need RCLK (32768 kHz from PIC) or External Oscillator (as shown in Typical Application Schematic)
I would to use 32768 kHz XTAL for the PIC and send CLOCK PIC --> to SI4703 ?? It is possible??
In this example
http://www.silabs.com/Support%20Documents/TechnicalDocs/AN264.pdf
I saw in "Figure 2. Schematic Page 1" that it uses a PIN P1.7 to provide RCLK!!
Is this possible with a 18F25J10??
I'm looking for in datasheet but .....I saw that there is a way to take only 1/4 of 32.768 kHz.
There are some other solution??
If there aren't solution I have to add external oscillator.
Many thanks
Fabio
IZ0CBG |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 14, 2010 1:16 pm |
|
|
Look at the schematic in AN264. It shows the 8051 microcontroller has
a 32.768 KHz crystal on it. Then look in the Si4703 data sheet at
this table:
Quote: | Table 8. FM Receiver Characteristics |
It says the RCLK frequency should have an accuracy of at least 200 ppm,
or maybe 50 ppm. So I think you need a 32.768 KHz crystal.
My advice is to just buy one. They show the Epson SE3201 in their
parts list. That crystal has been replaced by the Rohs version, SER3201:
http://search.digikey.com/scripts/DkSearch/dksus.dll?Detail&name=SER3201-ND
Page 14 of the data sheet has a schematic of a crystal circuit connected
between RCLK and GPIO3. It shows the Epson crystal and 22 pf capacitors. |
|
|
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Fri Jul 16, 2010 11:35 am |
|
|
Many hanks for the info
Sorry for the time of reply but I was at working.
I have desolder the XTAL 32.768kHz from old motherboard
So...I'm testing the I2C Communication.
I think that I have to use a #int_SSP for get Byte from SI4703. It is correct??
I have tested the command i2c_write(0x21) and it seems to work.
Now the problem is that I have to read data.
After that the PIC send command 0x21 (read) I have to read all the registers, starting from 0Ah (High and Low) --> 0Bh (High and Low) --> .....--> 00h (High and Low)
For read operations, the control word and device acknowledge is followed by an eight bit data word shifted out on
falling SCLK edges. Any number of data bytes can be read by sending a low ACK to the device. Device register
addresses are incremented by an internal address counter, starting at the upper byte of register 0Ah, followed by
the lower byte of register 0Ah, and wrapping back to 00h at the end of the register file. The transfer ends with the
STOP conditions regardless of the state of the acknowledge.
I have used RS232 interrupt but I don't know if with #int_SSP is the same!
In RS232 the interrupt begin when a data is available in buffer...in I2C I think that is the same but I'm not sure (for example...have I to control i2c_isr_state() ??)
I made this function:
Code: |
#include "C:\Documents and Settings\Administrator\Desktop\pic\fabio\18F25J10.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <input.c>
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#define SEN PIN_B0
#define RST PIN_B1
#INT_SSP
byte data_high[50];
byte data_low[50];
int h_or_l=1;
int n_high=0;
int n_low=0;
int nh=0;
int nl=0;
void ssp_interupt ()
{
if(h_or_l==1)
{data_high[nh]=i2c_read();
nh++;
h_or_l=0;
}
if(h_or_l==0)data_low[nl]=i2c_read();
{data_low[nl]=i2c_read();
nl++;
h_or_l=1;
}
}
void putb( byte b)
{
byte i;
for (i = 0; i < 8; i++)
if(bit_test(b, i))
putc('1');
else
putc('0');
}
int8 get_ack_status(int8 address)
{
int8 status;
i2c_start();
status = i2c_write(address); // Status = 0 if got an ACK
i2c_stop();
if(status == 0)
return(TRUE);
else
return(FALSE);
}
void main()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_spi(FALSE);
setup_spi2(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
int8 i;
int8 status=1;
int8 count = 0;
byte data[30];
printf("Start:\n\r");
//printf(data);
delay_ms(1000);
// 2-WIRE SELECTION ON THE RISE OF RST
OUTPUT_LOW(RST); // RST = 0
delay_ms(1000);
OUTPUT_HIGH(SEN); // SEN = 1 and GPIO3 is left Floating
OUTPUT_LOW(PIN_C4); // SDIO = 0
OUTPUT_HIGH(PIN_C3); // SCLK = 1 SCLK must be high during the rising edge of RST
delay_us(150);
OUTPUT_HIGH(RST); // REISE THE RST
delay_us(70);
delay_ms(1); // Wait for Internal oscillator stabilazation
i2c_start();
status = i2c_write(0x21);
i2c_stop();
if (status==0)printf("Receiving Data");
delay_ms(1000);
for (i=0; i<=nl; i++)
{printf("Register %d \r\n",i);
putb(data_high[i]);
putb(data_low[i]);
printf("\r\n");
}
}
|
And the response is only this:
Receiving Data
Register 0
1011010100010000
Where is the error??
Many thanks
Fabio |
|
|
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Mon Jul 19, 2010 11:42 am |
|
|
I have added an external clock with 22pF and 32.768 Khz Xtal.
Now....I have the same problem!!
I am not able to read register after the write of i2c_write(0x21).
Someone can help me about I2C routine??
I have added a printf("TEST") in #INT_SSP interrupt but it is never called....why??
Code: |
#INT_SSP
byte data_high[50];
byte data_low[50];
int h_or_l=1;
int n_high=0;
int n_low=0;
int nh=0;
int nl=0;
void ssp_interupt ()
{
printf("dentro");
if(h_or_l==1)
{data_high[nh]=i2c_read(1);
nh++;
h_or_l=0;
}
if(h_or_l==0)data_low[nl]=i2c_read();
{data_low[nl]=i2c_read(1);
nl++;
h_or_l=1;
}
}
|
Many thanks
Fabio |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 19, 2010 11:49 am |
|
|
You don't use #int_ssp interrupts for an i2c master. Your PIC is the i2c master. Remove the #int_ssp from your program. |
|
|
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Mon Jul 19, 2010 12:52 pm |
|
|
OK...I have removed the interrupt!
I have tested the i2c_poll() function but for compile it I must add FORCE HARDWARE in #use i2c(Master, sda=PIN_C4, scl=PIN_C3) but in this way
I cannot see the ACK response.
So...I'm testing something like the code below for test the i2c_read() because I think that I have to consider also the delay time of the SLAVE response.
The code is horrible but it is only for searching the right way for bus communication.
Code: |
#include "C:\Documents and Settings\Administrator\Desktop\pic\fabio\18F25J10.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <input.c>
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#define SEN PIN_B0
#define RST PIN_B1
void putb( byte b)
{
byte i;
for (i = 0; i < 8; i++)
if(bit_test(b, i))
putc('1');
else
putc('0');
}
void main()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_spi(FALSE);
setup_spi2(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
byte data_high[50];
byte data_low[50];
int h_or_l=1;
int n_high=0;
int n_low=0;
int nh=0;
int nl=0;
int8 i;
int8 status=1;
int8 count = 0;
byte data[30];
memset(data_low, 0, 50);
memset(data_high, 0, 50);
printf("Start:\n\r");
//printf(data);
delay_ms(1000);
// 2-WIRE SELECTION ON THE RISE OF RST
OUTPUT_LOW(RST); // RST = 0
delay_ms(1000);
OUTPUT_HIGH(SEN); // SEN = 1 and GPIO3 is left Floating
OUTPUT_LOW(PIN_C4); // SDIO = 0
delay_us(150);
OUTPUT_HIGH(PIN_C3); // SCLK = 1 SCLK must be high during the rising edge of RST
delay_us(150);
OUTPUT_HIGH(RST); // REISE THE RST
delay_us(70);
OUTPUT_HIGH(PIN_C4); // SDIO = 1
delay_ms(500); // Wait for Internal oscillator stabilazation
i2c_start();
status = i2c_write(0x21);
//i2c_stop();
if (status==0)printf("Receiving Data");
while(1)
{
data_high[0]=i2c_read(1);
data_low[0]=i2c_read(1);
data_high[1]=i2c_read(1);
data_low[1]=i2c_read(1);
printf("\r\n");
printf("Register 0 \r\n");
putb(data_high[0]);
putb(data_low[0]);
printf("\r\n");
printf("Register 1 \r\n");
putb(data_high[1]);
putb(data_low[1]);
delay_ms(1000);
}
}
|
and the output is:
Start:
Receiving Data
Register 0
0000000000000000
Register 1
0000000000000000
Register 0
0000000000000000
Register 1
0000000000000000
Register 0
0000000000000000
Register 1
0000000000000000
Register 0
0100100001000010
Register 1
0100100000000000
Register 0
0000000000000000
Register 1
0000000000000000
Register 0
0000000000000000
Register 1
0000000000000000
ecc
ecc
Many thanks for the Very Big Help to all.
Fabio |
|
|
ketron82
Joined: 07 Jun 2010 Posts: 36
|
|
Posted: Mon Jul 19, 2010 3:10 pm |
|
|
I think that I make errors reading I2C bus!
Does the function i2c_read(1) send ACK at the end of the 1st byte??
Should be this the error??
If I use i2c_read(0);
the output is
111111111111111
111111111111111
111111111111111
ecc
ecc
Many thanks
Fabio |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 19, 2010 3:47 pm |
|
|
Look in the CCS manual, at the i2c_read() function:
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
Look at this diagram in the Si4703 Programmer's guide that I gave
you a link to, earlier in this thread. It shows where an ACK should
be placed.
Quote: | Figure 7. 2-Wire Control Interface Read Timing Diagram |
I'm going to tell you how I feel. You're a complete newbie in this.
The Si4703 is a complicated i2c chip. The driver interface to it has
some quirks that must be considered. I will guess that you have
some "due date" on this assignment that is 1 week from now.
I don't think there is any way that you will learn C, learn the i2c bus,
read and remember all the si4703 documentation, learn how to write
an i2c driver, and write and debug the si4703 driver in 1 week or 2 weeks
or longer. I don't want to do it for you. The type of questions that you
are asking in your most recent posts can easily be answered by reading
the CCS manual and the si4703 programming guide. I don't know why
you ask me, instead of reading them. I don't want to "read the manual
for you" every day while you attempt to write the driver. |
|
|
|