View previous topic :: View next topic |
Author |
Message |
pfsdanny
Joined: 20 Nov 2010 Posts: 11 Location: Hong Kong
|
SPI problems with 24F16KA102 to Atmel AT86RF212 (SOLVED) |
Posted: Sat Nov 20, 2010 1:53 am |
|
|
Hi,
I have a project to follow up. The board contains PIC 24F16KA102 and Atmel AT86RF212. These chips use SPI to communicate. My job is to write a program to read the Atmel register. My problems are the Atmel chip does not return anything. I have write a SPI program to communicate between two PICs 18F13K50 and it works. My CCS version is PCD 4.112. Here below is my code.
I have try all the spi_setup options without suggest. I am sure the hardware is ok because the original program (the real application written by the other programmer, but he quit) works.
Code: |
#include <24F16KA102.h>
#device ICD=TRUE
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOWRTB //Boot block not write protected
#FUSES NOBSS //No boot segment
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOWRT //Program memory not write protected
#FUSES FRC //Internal Fast RC Oscillator
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES NOPR //Pimary oscillaotr disabled
#FUSES OSCIO //OSC2 is general purpose output
#FUSES SOSC_HIGH
#FUSES NOCKSFSM //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES WPOSTS16 //Watch Dog Timer PostScalar 1:32768
#FUSES WINDIS //Watch Dog Timer in non-Window mode
#FUSES NOBROWNOUT //No brownout reset
#FUSES PUT //Power Up Timer
#FUSES BORV_LOW
#FUSES MCLR //Master Clear pin enabled
#FUSES ICSP1 //ICD uses PGC1/PGD1 pins
#FUSES DEBUG //Debug mode for use with ICD
#FUSES DSWDT2147483648
#FUSES DSWDTCK_LPRC
#FUSES DSBOR
#FUSES DSWDT
#FUSES NOALTI2C //I2C mapped to alternate pins
#FUSES RTCCK_SOSC
#FUSES POSCFREQ_H
#use delay(clock=8000000,RESTART_WDT)
#include <spi24.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#use rs232(UART1,baud=4800,parity=N,bits=8)
#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)
#define spiSel PIN_B14
#define spiRST PIN_B5
#define spiSLP_TR PIN_B15
#define spiCLK PIN_B11
#define spiMOSI PIN_B13
void main()
{
setup_adc_ports(ADC_OFF);
setup_wdt(WDT_ON);
setup_timer1(TMR_DISABLED|TMR_DIV_BY_1);
// TODO: USER CODE!!
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_4);
output_high(spiSel);
output_high(spiRST);
output_high(spiSLP_TR);
output_low(spiCLK);
output_low(spiMOSI);
int b1, b2;
while (true) {
output_low(spiSel);
b1=spi_read(0x9C);
b2=spi_read(0);
output_high(spiSel);
printf("b1:%LX b2:%LX\n\r", b1, b2);
delay_ms(500);
}
}
|
When these code runs, both b1 and b2 always return 0.
Danny
Last edited by pfsdanny on Wed Dec 01, 2010 2:45 am; edited 2 times in total |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sat Nov 20, 2010 3:13 am |
|
|
The SPI setup and handling seems correct, I would check the SPI lines with an oscilloscope to be sure anyway. |
|
|
pfsdanny
Joined: 20 Nov 2010 Posts: 11 Location: Hong Kong
|
|
Posted: Sat Nov 20, 2010 9:21 am |
|
|
I have check scope, all signals spiSel, CLK, SDO is ok and the code 0x9C sends correctly, but the SDI does not show anything. I only got a dual trace scope that I cannot measure the timing between signals.
The same code runs on a pair of PIC 18K chips. :( |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Sat Nov 20, 2010 10:35 am |
|
|
Since you say your PIC hardware/software is Ok I'd look at the Atmel chip hardware.
I don't see any 'interface control' PIC code....Maybe an Enable pin is not, maybe reset pin is high,or some combination isn't stopping communications between the two chips.
I'll assume that voltage levels are correct ??? |
|
|
pfsdanny
Joined: 20 Nov 2010 Posts: 11 Location: Hong Kong
|
|
Posted: Sun Nov 21, 2010 9:37 pm |
|
|
The hardware is sure to works. The connection is below
PIC24 Atmel AT86RF212
B14 ---> /SEL
SDO ---> MOSI
SDI <--- MISO
SCLK ---> SCLK
B5 ---> /RST
Both chips running at 3V. The Atmel manual says the chip running at SPI Mode 0 as slave. The maximum SPI clock speed is 7.5MHz in Atmel. There is no pull-up or pull-down resistor connect to the I/O (all pins are direct connected). The /RST and /SEL is set to logic 1, SDO and SCLK to set to logic 0 at the start of the code. The Atmel request to send the MSB first with a byte at a time. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
pfsdanny
Joined: 20 Nov 2010 Posts: 11 Location: Hong Kong
|
|
Posted: Sun Nov 21, 2010 11:02 pm |
|
|
Thanks, I have already read that before. So my code only use spi_read().
I'm trying to make a new board contains PIC24 and PIC18 to test the PIC24 SPI function. This take time, make the PCB solder the chip by hand (28pin QFN)....
Will post my result when done.
Thanks. |
|
|
pfsdanny
Joined: 20 Nov 2010 Posts: 11 Location: Hong Kong
|
|
Posted: Mon Nov 29, 2010 4:28 am |
|
|
Made a master using 24FJ128GA006 and a slave using 18F13K50. Below is the software listing.
Master in 24FJ128GA006
Code: |
.
#define spi_sel PIN_B14
.
.
setup_spi2(SPI_MASTER | SPI_L_TO_H| SPI_XMIT_L_TO_H | SPI_CLK_DIV_4);
output_high(spi_sel);
while (true) {
output_low(spi_sel);
d1=spi_read2(0x9D);
d2=spi_read2(0);
output_high(spi_sel);
printf("d1:%u, d2:%u\n\r", d1, d2);
delay_ms(2000);
}
|
Slave in 18F13K50
Code: |
.
.
setup_spi(SPI_SLAVE | SPI_MODE_0);
while (true) {
if (i==255) i=0;
i++;
cmd=spi_read(cmd);
data = spi_read(i);
} |
These programs work and the slave returns the data I as expected. However, when I replace the slave with Atmel chip, it does not respond, nothing return.
Now I am sure the code in 24F works. I think its not the coding issue, maybe the Atmel chip needs other control singals (hardware problems).
Going to re-study the Atmel manual again. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Nov 29, 2010 12:55 pm |
|
|
The manual may not help. We once did a project at the company using
an early MPEG decoder chip (This was not a PIC project). The MPEG chip
was poorly documented. We had a lot of trouble trying to make an
interface to it for a Single Board Computer. Finally I got tired of it, and
I completely "instrumented" their demo board (with a logic analyzer). I
then used their monitor program to perform every possible i/o operation
that could be done to the MPEG chip. Each time, I captured all the
interface timing with the logic analzyer. I printed out the timing diagrams.
With that information, I was able to design the logic (using GAL devices)
to interface the Single Board Computer (x86) to the MPEG decoder.
It worked. Even the MPEG company wanted my timing diagrams after
I got it working.
If you did something similar, I think you could solve your problem.
At the time, I used an HP logic analyzer (this was a few years ago).
Nowadays, you can get much smaller, cheaper and more powerful
logic analyzers. This is a good low-cost, highly capable logic analyzer:
http://www.pctestinstruments.com/ |
|
|
pfsdanny
Joined: 20 Nov 2010 Posts: 11 Location: Hong Kong
|
|
Posted: Tue Nov 30, 2010 10:57 pm |
|
|
Thanks, the HP logic analyzer seems affordable. Will try it and post the result. |
|
|
pfsdanny
Joined: 20 Nov 2010 Posts: 11 Location: Hong Kong
|
|
Posted: Wed Dec 01, 2010 2:43 am |
|
|
Problem solved. I must add code to reset the Atmel chips.
Code: |
output_low(spiRst); // pull the Atmel chip /RST pin low to reset the Atmel
delay_us(1); // Atmel chip needs 625ns pluse to reset the chip
output_high(spiRst);
output_low(spiSel);
data1=spi_read(0x9C);
data2=spi_read(0);
output_high(spiSel);
|
Thanks all your help. |
|
|
|