|
|
View previous topic :: View next topic |
Author |
Message |
scuba
Joined: 13 Sep 2011 Posts: 13
|
PIC18F46K22 to MRF89XA |
Posted: Tue Sep 13, 2011 8:59 pm |
|
|
Hi,
I'm doing a device project that has a pic18f46k22 and a mrf89xam8a module. The goal is to communicate to another device (pic 18 explorer board). Well, I'm having some problems to communicate to the last one. I have the code of spi, registerRead/registerWrite, write/read fifo and one function to send packet's.
The datasheet's can be found here: http://ww1.microchip.com/downloads/en/DeviceDoc/41412D.pdf
http://ww1.microchip.com/downloads/en/DeviceDoc/70622B.pdf
I need help and someone to show my code. I am working on this code for 3 weeks and i see no results. Don't know what i'm doing wrong =/
Thank's! |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Wed Sep 14, 2011 4:08 pm |
|
|
If you haven't confirmed the SPI bus is communicating correctly, you will need an oscilloscope.
From there, you want to read through this appnote (AN01340) located here: http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en549380
There's also source code you can compile with C18 to verify the hardware first... and then move to writing in CCS PIC-C.
Cheers,
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
scuba
Joined: 13 Sep 2011 Posts: 13
|
|
Posted: Thu Sep 15, 2011 4:32 pm |
|
|
I saw the code of the microchip and i have adapted to ccs but i can not figure out what is failing. Tired of reading on datasheets, microchip website and forums. I have program all the transceiver registers that were necessary but still not working. I was cautious about the CSCONFIG and CSDATA. The Spi connection is right and confirmed.
This is what I'm doing on ccs:
Code: |
#include <18f46k22.h>
#include <stdio.h>
#include <stdlib.h>
#include <MRF89XA.h>
#use delay(clock=4Mhz)
#FUSES RC
#FUSES NOPLLEN,NOWDT
#define EEPROM_ADDRESS long int
#define EEPROM_BLOCKSIZE 65536
#define EEPROM_SIZE 131072
#define PACKET_LEN 64
#define MASTER_CS PIN_A5 // Connect to Slave \SS CONFIG_ncs
#define CSCON PIN_A4 //data NCS
#define CLK PIN_C3
#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)
Boolean RQ1Received;
Boolean RQ0Received;
BYTE RxPacketLen;
Boolean hasPacket;
BYTE RF_Mode;
BYTE TxPacket[PACKET_LEN];
BYTE RxPacket[PACKET_LEN];
Boolean Enable_DutyCycle;
#use i2c(master, sda=PIN_D1, scl=PIN_D0, FAST)// i2c
#use rs232(baud=9600, xmit=PIN_D6, rcv=PIN_D7, BITS=8, stream=MicroGPS,ERRORS)//Soft-UART-GPS
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,BITS=8, stream=hostPC,ERRORS)//UART-PC
#use spi(FORCE_HW,BITS=8, stream=SPI_STREAM)
/*********************************************************************
* void RegisterSet(BYTE address, BYTE value)
*
* Overview:
* This function access the control register of MRF89XA.
* The register address and the register settings are
* the input
*
* PreCondition:
* None
*
* Input:
* WORD setting The address of the register and its
* corresponding settings
*
* Output: None
*
* Side Effects: Register settings have been modified
*
********************************************************************/
void RegisterSet(BYTE address, BYTE value)
{
output_low(MASTER_CS);
output_high(CLK);
address = (address<<1); //& 0xFE;
spi_write (address);
spi_write (value);
delay_ms(1);
fputc(spi_read(),hostPC); // Send it to the PC
output_high(MASTER_CS);
output_low(CLK);
}
/*********************************************************************
* WORD RegisterRead()
*
* Overview:
* This function access the control register of MRF89XA.
* The register address and the register settings are
* the input
*
* PreCondition:
* None
*
* Input:
* WORD setting The address of the register and its
* corresponding settings
*
* Output: None
*
* Side Effects: Register settings have been modified
*
********************************************************************/
BYTE RegisterRead(BYTE address)
{
BYTE value;
output_low(MASTER_CS);
address = ((address<<1)|0x40);
output_high(CLK);
spi_write(address);
output_low(CLK);
value = spi_read();
output_high(MASTER_CS);
return value;
}
/*********************************************************************
* void SetRFMode(BYTE mode)
*
* Overview:
* This functions sets the MRF89XA transceiver operating mode to sleep, transmit, receive or standby
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
********************************************************************/
void SetRFMode(BYTE mode)
{
BYTE mcparam0_read;
//mcparam0_read = RegisterRead(REG_MCPARAM0);
switch (mode) {
case RF_TRANSMITTER:
RegisterSet(REG_MCPARAM0, RF_TRANSMITTER | FREQBAND_950 | VCO_TRIM_11, );
RF_Mode = RF_TRANSMITTER; //RF in TX mode
break;
case RF_RECEIVER:
RegisterSet(REG_MCPARAM0, RF_RECEIVER | FREQBAND_950 | VCO_TRIM_11, );
RF_Mode = RF_RECEIVER; //RF in RX mode
break;
case RF_SYNTHESIZER:
RegisterSet(REG_MCPARAM0, RF_SYNTHESIZER | FREQBAND_950 | VCO_TRIM_11, );
RF_Mode = RF_SYNTHESIZER; //RF in Synthesizer mode
break;
case RF_STANDBY:
RegisterSet(REG_MCPARAM0, RF_STANDBY | FREQBAND_950 | VCO_TRIM_11, );
RF_Mode = RF_STANDBY; //RF in standby mode
break;
case RF_SLEEP:
RegisterSet(REG_MCPARAM0, RF_SLEEP | FREQBAND_950 | VCO_TRIM_11, );
RF_Mode = RF_SLEEP; //RF in sleep mode
break;
delay_ms(100);
} /* end switch (mode) */
}
/*********************************************************************
* void WriteFIFO(BYTE Data)
*
* Overview:
* This function fills the FIFO
*
* PreCondition:
* MRF89XA transceiver has been properly initialized
*
* Input:
* BYTE Data - Data to be sent to FIFO.
*
* Output: None
*
* Side Effects:
* The packet has been sent out
*
********************************************************************/
void WriteFIFO(BYTE Data)
{
output_low(CSCON);
output_high(CLK);
spi_write(Data);
output_high(CSCON);
output_low(CLK);
delay_ms(300);
}
/*********************************************************************
* BYTE ReadFIFO(void)
*
* Overview:
* This function reads the Reiceved frame from the fifo and sets hasPacket accordingly
*
* PreCondition:
* MRF89XA transceiver has been properly initialized
*
* Input:
* None
*
* Output: Data from FIFO
*
* Side Effects:
* The packet has been sent out
*
********************************************************************/
BYTE ReadFIFO(void)
{
BYTE value;
output_low(CSCON);
value = spi_read();
output_high(CSCON);
return value;
}
void MRF89XAInit(void)
{
BYTE input,i=0;
SetRFMode(RF_STANDBY);
for (i = 0 ; i <= 31; i++)
{
RegisterSet(i, InitConfigRegs[i]);
}
output_high(CLK);
RF_Mode = RF_TRANSMITTER;
RegisterSet(REG_MCPARAM0, RF_SYNTHESIZER | FREQBAND_950 | VCO_TRIM_11 );
output_low(CLK);
RF_Mode = RF_SYNTHESIZER;
RegisterSet(REG_IRQPARAM1, MODSEL_FSK | DATAMODE_PACKET | IFGAIN_0 | 0x02);
RegisterSet(REG_MCPARAM0, ((input & 0xE7) | FREQBAND_950));
//Program R, P,S registers
RegisterSet(REG_R1, 125);
RegisterSet(REG_P1, 100);
RegisterSet(REG_S1, 20);
RegisterSet(REG_MCPARAM0, RF_SYNTHESIZER | FREQBAND_950 | VCO_TRIM_11);
RF_Mode = RF_SYNTHESIZER;
RegisterSet(REG_IRQPARAM1, MODSEL_FSK | DATAMODE_PACKET | IFGAIN_0 | 0x02);
output_high(CLK);
SetRFMode(RF_TRANSMITTER);
RegisterSet(REG_BITRATE,BITRATE_20);
RegisterSet(REG_RXPARAM0, (RXFC_FOPLUS75 | PASSIVEFILT_234));
RegisterSet(REG_FREGDEV,FREGDEV_40);
output_low(CLK);
}
/*********************************************************************
* void Send_Packet(BYTE TxPacketLen)
*
* Overview:
* This function send the packet in the buffer TxPacket
*
* PreCondition:
* MRF89XA transceiver has been properly initialized
*
* Input:
* BYTE TxPacketLen The length of the packet to be
* sent.
*
* Output: None
*
* Side Effects:
* The packet has been sent out
*
********************************************************************/
void Send_Packet(BYTE TxPacketLen)
{
BYTE i;
SetRFMode(RF_STANDBY);
// RegisterSet(REG_IRQPARAM0, (IRQ0_RX_STDBY_SYNCADRS | IRQ1_RX_STDBY_CRCOK | IRQ1_TX_TXDONE | IRQ1_FIFO_OVERRUN_CLEAR));
// RegisterSet(REG_IRQPARAM1, (DEF_IRQPARAM1 | IRQ0_TX_START_FIFOTHRESH | IRQ1_PLL_LOCK_PIN_ON ));
RegisterSet(REG_IRQPARAM1, ((InitConfigRegs[REG_IRQPARAM1]) | 0x02));
RegisterSet(REG_PKTPARAM3, ((InitConfigRegs[REG_PKTPARAM3] & 0xBF)| FIFO_STBY_ACCESS_WRITE));
RegisterSet(REG_IRQPARAM0, (InitConfigRegs[REG_IRQPARAM0] | IRQ1_FIFO_OVERRUN_CLEAR ));
WriteFIFO(TxPacketLen+1);
WriteFIFO(0x00); //Node_adrs
for(i=0; i< TxPacketLen; i++)
{
WriteFIFO(TxPacket[i]);
}
output_high(CLK);
SetRFMode(RF_TRANSMITTER);
delay_ms(500);
SetRFMode(RF_STANDBY);
output_low(CLK);
RegisterSet(REG_IRQPARAM0, (RegisterRead(REG_IRQPARAM0) | 0x01));
}
void main(){
setup_spi(SPI_MASTER | SPI_MODE_0);
delay_ms(2000);
output_float(PIN_C6); // TX hostPC high impedance
output_float(PIN_C7); //RX hostPC high impedance
output_float(PIN_D6); //TX MicroGPS high impedance
output_float(PIN_D7); //RX MicroGPS high impedance
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
MRF89XAInit();
BYTE TxPacket[] = "eaa";
while(1){
output_high(PIN_A2);
//fputs(RegisterRead(0x1C),hostPC);
//fputs(TxPacket,hostPC);
Send_Packet(64);
output_low(PIN_A2);
delay_ms(2000);
}
}
|
The problem is send the packet. I can read what i'm putting on registerwrite and it's right too.
Thank's.
Greets! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Sep 15, 2011 4:55 pm |
|
|
Quote: |
#use delay(clock=4Mhz)
#FUSES RC
|
This fuse is for an external resistor-capacitor oscillator. No one uses this.
It's left over from very early hobby days of the PIC. Maybe you meant
to use INTRC_IO.
Quote: |
#define CLK PIN_C3
output_low(CLK);
.
.
.
output_high(CLK);
setup_spi(SPI_MASTER | SPI_MODE_0);
|
You are using hardware SPI. Hardware SPI uses pin C3. It controls the
pin. Why are you setting Pin C3 low and high in code ? It's under
hardware control.
Quote: | value = spi_read();
|
The spi_read() function needs a parameter to cause the PIC to generate
the SCLK signal on pin C3. Usually, the parameter used is 0x00.
Without the parameter (as in your code above), there will be no clock,
and thus no data will be loaded into the Master PIC.
Quote: |
#use spi(FORCE_HW,BITS=8, stream=SPI_STREAM)
setup_spi(SPI_MASTER | SPI_MODE_0);
|
You have two methods of setting up the hardware SPI module in the PIC.
The setup_spi() line will override the #use spi() line. Also, you left off the
clock divisor parameter in the setup_spi() line. Because of that, you are
by default using a clock divisor of 4. That's OK, but it's better to put in
the parameter and specify it, so the code is self-documenting.
Quote: |
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
|
Here you enable interrupts, but you don't have an #int_ssp interrupt
function. But you don't need one, because your PIC is the SPI Master.
So you don't need the two lines above, and they will cause the program
to fail. Remove them.
There probably are more problems than I noted here, but this shows at
least some of them. |
|
|
scuba
Joined: 13 Sep 2011 Posts: 13
|
|
Posted: Sat Sep 17, 2011 8:49 am |
|
|
I've try to read what was written with registerSet on spi connection with this simple code:
Code: |
#include <18f46k22.h>
#include <stdio.h>
#include <stdlib.h>
#include <MRF89XA.h>
#use delay(clock=4Mhz)
#FUSES INTRC_IO
#FUSES NOPLLEN,NOWDT
#define EEPROM_ADDRESS long int
#define EEPROM_BLOCKSIZE 65536
#define EEPROM_SIZE 131072
#define PACKET_LEN 64
#define MASTER_CS PIN_A5 // Connect to Slave \SS CONFIG_ncs
//#define CSDATA PIN_A4 //data NCS
BYTE value=0;
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,BITS=8, stream=hostPC, ERRORS)//UART-PC
#use spi(FORCE_HW,BITS=8, stream=SPI_STREAM)
void RegisterSet(BYTE address, BYTE value)
{
output_low(MASTER_CS);
address = (address<<1);
spi_write (address);
spi_write (value);
output_high(MASTER_CS);
}
BYTE RegisterRead(BYTE address)
{
output_low(MASTER_CS);
delay_ms(50);
address = ((address<<1)|0x40);
spi_write(address);
value = spi_read(0x00);
output_high(MASTER_CS);
delay_ms(50);
fputc(value,hostPC); // Send it to the PC
return value;
}
//======================================
void main()
{
char c;
setup_oscillator( OSC_4MHZ );
while(1)
{
RegisterSet(0x01,0x05);
delay_ms(500);
RegisterRead(0x01);
}
}
|
But the output on hyperterminal is: 0x38.
Don't know what is wrong and i need help to understand what MRF89XA is doing. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Sep 18, 2011 5:02 pm |
|
|
Are you using this Pictail board ?
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en555524
Is it plugged into the Pictail connector on the Explorer 18 board ?
Or, is there no Pictail board, and you made the wire connections to
the mrf89xam8a module by yourself.
I need to know that, because I would like to look at a schematic.
Because, mrf89xa has two separate SPI modules in it. One is for Config
and the other is for Data. Here, you have the #defines, but the one
for Data is commented out:
Quote: |
#define MASTER_CS PIN_A5 // Connect to Slave \SS CONFIG_ncs
//#define CSDATA PIN_A4 //data NCS
|
That's important because, what if the CS for data is left floating ?
Then it's possible that it could "float low" and activate the Data SPI unit.
(Activate it when you don't want it to be).
So ideally, it would have a pull-up resistor on the CSDATA line, or you
could uncomment the #define and set it to a high level at the start of
main().
That's one problem you need to fix. Another problem is the SPI mode.
You have this statement here:
Quote: |
#use spi(FORCE_HW,BITS=8, stream=SPI_STREAM)
|
But you didn't specify the mode. So it defaults to Mode 1 (for whatever
reason - This is with CCS vs. 4.124). But that's wrong. If you look at
the SPI timing diagrams in the mrf89xa data sheet, such as this one,
Quote: |
FIGURE 2-13: READ REGISTER SEQUENCE
|
you see that SCK idles at a low level and samples the data in the middle
of the data cell, on the rising edge. That's SPI Mode 0. That's probably
a major reason why your code doesn't work. To fix it, add the Mode
as shown in bold below:
Quote: |
#use spi(FORCE_HW,BITS=8, stream=SPI_STREAM, MODE=0) |
Another problem: You are immediately trying to write to the Config
module:
Quote: |
void main()
{
char c;
setup_oscillator( OSC_4MHZ );
while(1)
{
RegisterSet(0x01,0x05);
delay_ms(500);
RegisterRead(0x01);
}
} |
The chip's data sheet says you must wait at least 10 ms before trying
to talk to the chip.
Quote: |
3.1.1 POWER-ON RESET (POR)
If the application requires the disconnection of VDD
from the MRF89XA, the user should wait for 10 ms
from the end of the POR cycle before commencing
communications using SPI.
3.1.2 MANUAL RESET
A manual reset of the MRF89XA is possible even for
applications in which VDD cannot be physically
disconnected. The TEST8 pin should be pulled high for
100 u (micro) and then released. The user should then
wait 5 ms before using the chip |
Also, you are not initializing the chip select signals to an inactive state
at the start of main(). You should do that. Example:
Code: |
void main()
{
output_high(CONFIG_CS); // You call this MASTER_CS
output_high(DATA_CS);
delay_ms(100); // POR delay (spec = 10ms. Do it for 100)
|
Finally, what is the Vdd voltage of the 18F46K22 ? The mrf89xa runs
at 3.3v. So if the PIC is running at +5v there could be a problem, unless
you have level translators. If the PIC is running at +3.3v, then it's OK.
There might be other problems. I didn't look any further at this time.
Other than that, your translation of the Microchip sample to code to CCS
looks correct. (The two routines to set and read a config register). |
|
|
scuba
Joined: 13 Sep 2011 Posts: 13
|
|
Posted: Mon Sep 19, 2011 3:21 pm |
|
|
Hi, I'm using a MRF89XAM8A module http://ww1.microchip.com/downloads/en/DeviceDoc/70651A.pdf , not a Pictail board. To supply the electronic circuit I have a ldo voltage regulator of 3.0V.
Already made the necessary code changes and module still does not work correctly. I don't know what to do anymore =/ |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 19, 2011 4:24 pm |
|
|
1. Please answer this question from my previous post:
Quote: |
Finally, what is the Vdd voltage of the 18F46K22 ? |
2. Post a list of the connections between your Explorer 18 board and
the MRF89XAM8A module. Trace out the wires and post a list of the
pin numbers on each device that are connected together. If the wires
go to a connector on the Explorer 18 board, then post the pin numbers
of the connector.
The reason for this is, I want to make sure that you have the SPI
connections done correctly. A very common mistake is to connect
SDI to SDI. But that's wrong. That's why I want a list of your
connections. And post the pin numbers, not the signal names.
Quote: | Already made the necessary code changes
|
3. Post the new test program that has the modifications. |
|
|
scuba
Joined: 13 Sep 2011 Posts: 13
|
|
Posted: Mon Sep 19, 2011 7:01 pm |
|
|
The Vdd voltage of the 18F46K22 is 3.1V.
My module isn't in a Explorer 18 Board. I've done a PCB with 18F46K22 TQFP and a MRF89XAM8A. The connections are:
18F46K22 MRF89XAM8A
INT1 9------------------- 4 IRQ0
INT2 10------------------ 9 IRQ1
RA4 23------------------- 3 CSON
RA5 24------------------- 8 CSDATA
SCK 37------------------ 6 SCK
SDI 42------------------ 7 SDO
SDO 43------------------ 5 SDI
The Program with the modifications:
Code: |
#include <18f46k22.h>
#include <stdio.h>
#include <stdlib.h>
#include <MRF89XA.h>
#use delay(clock=4Mhz)
#FUSES INTRC_IO
#FUSES NOPLLEN,NOWDT
#define EEPROM_ADDRESS long int
#define EEPROM_BLOCKSIZE 65536
#define EEPROM_SIZE 131072
#define PACKET_LEN 64
#define MASTER_CS PIN_A5 // Connect to Slave \SS CONFIG_ncs
#define CSDATA PIN_A4 //data NCS
BYTE value=0;
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,BITS=8, stream=hostPC, ERRORS)//UART-PC
#use spi(FORCE_HW,BITS=8, stream=SPI_STREAM, MODE=0)
void RegisterSet(BYTE address, BYTE value)
{
output_low(MASTER_CS);
address = (address<<1);
spi_write (address);
spi_write (value);
output_high(MASTER_CS);
}
BYTE RegisterRead(BYTE address)
{
output_low(MASTER_CS);
delay_ms(50);
address = ((address<<1)|0x40);
spi_write(address);
value = spi_read(0x00);
output_high(MASTER_CS);
delay_ms(50);
fputc(value,hostPC); // Send it to the PC
return value;
}
//======================================
void main()
{
char c;
output_high(MASTER_CS);
output_high(CSDATA);
delay_ms(100);
setup_oscillator( OSC_4MHZ );
while(1)
{
RegisterSet(0x01,0x05);
delay_ms(500);
RegisterRead(0x01);
delay_ms(500);
/*
RegisterSet(0x02,0x02);
delay_ms(500);
RegisterRead(0x02);
*/
}
}
|
Thanks ! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 19, 2011 10:43 pm |
|
|
What's your CCS compiler version ? |
|
|
scuba
Joined: 13 Sep 2011 Posts: 13
|
|
Posted: Tue Sep 20, 2011 8:08 am |
|
|
V4.114. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Sep 20, 2011 10:33 pm |
|
|
I'm still working on this. |
|
|
sawula
Joined: 06 Oct 2010 Posts: 3
|
|
Posted: Wed Sep 21, 2011 3:42 am |
|
|
What is reason for these shifting operations in RegisterRead and RegisterSet operations.
Code: | address = (address<<1);
spi_write (address); |
Code: | address = ((address<<1)|0x40);
spi_write(address); |
|
|
|
scuba
Joined: 13 Sep 2011 Posts: 13
|
|
Posted: Wed Sep 21, 2011 4:53 am |
|
|
Thanks all for supporting me. The reason that i can't read from spi is the changing the PIN_A4 for PIN_A5. That was the mistake.
The next step is send a packet by wireless. |
|
|
scuba
Joined: 13 Sep 2011 Posts: 13
|
|
Posted: Thu Sep 22, 2011 10:40 am |
|
|
Now i want to send the packet for a picdem pic18 explorer with a pictail daughter board MRF89XAMxA.
The problem is that i can not get the message that is on TxPacket. I think I'm doing all the right steps to initialize the transceiver in standby mode, pass to transmitter, and back to standby. I set records for communication to be made in 868MHZ but not use interrupts. Instead i use delays for the message to be sent. The problem is that?
Can i send a packet from a device that have ccs on it to a device that have C18?
If you need i leave the configuration of .h too.
The code of all methods can be seen above and i think the problem will be on SEND_PACKET. Thank you all!
Code: | #include <18f46k22.h>
#include <stdio.h>
#include <stdlib.h>
#include <MRF89XA.h>
#use delay(clock=4Mhz)
#FUSES INTRC_IO
#FUSES NOPLLEN,NOWDT
#define PACKET_LEN 64
#define CSDATA PIN_A5 // Connect to Slave \SS CONFIG_ncs
#define MASTER_CS PIN_A4 //data NCS
BYTE RF_Mode;
BYTE TxPacket[PACKET_LEN];
BYTE value=0;
#use i2c(master, sda=PIN_D1, scl=PIN_D0, FAST)//comunicacao i2c
#use rs232(baud=9600, xmit=PIN_D6, rcv=PIN_D7, BITS=8, stream=MicroGPS,ERRORS)//Soft-UART-GPS
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,BITS=8, stream=hostPC,ERRORS)//UART-PC
#use spi(FORCE_HW,BITS=8, stream=SPI_STREAM)
short b = 1;
int rs=0;
void RegisterSet(BYTE address, BYTE value)
{
output_low(MASTER_CS);
address = (address<<1);
spi_write (address);
spi_write (value);
output_high(MASTER_CS);
}
BYTE RegisterRead(BYTE address)
{
output_low(MASTER_CS);
delay_ms(50);
address = ((address<<1)|0x40);
spi_write(address);
value = spi_read(0x00);
output_high(MASTER_CS);
delay_ms(50);
fputc(value,hostPC); // Send it to the PC
return value;
}
/*********************************************************************
* void SetRFMode(BYTE mode)
*
* Overview:
* This functions sets the MRF89XA transceiver operating mode to sleep, transmit, receive or standby
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
********************************************************************/
void SetRFMode(BYTE mode)
{
BYTE mcparam0_read;
switch (mode) {
case RF_TRANSMITTER:
RegisterSet(REG_MCPARAM0, RF_TRANSMITTER | FREQBAND_950 | VCO_TRIM_11, );
RF_Mode = RF_TRANSMITTER; //RF in TX mode
break;
case RF_RECEIVER:
RegisterSet(REG_MCPARAM0, RF_RECEIVER | FREQBAND_950 | VCO_TRIM_11, );
RF_Mode = RF_RECEIVER; //RF in RX mode
break;
case RF_SYNTHESIZER:
RegisterSet(REG_MCPARAM0, RF_SYNTHESIZER | FREQBAND_950 | VCO_TRIM_11, );
RF_Mode = RF_SYNTHESIZER; //RF in Synthesizer mode
break;
case RF_STANDBY:
RegisterSet(REG_MCPARAM0, RF_STANDBY | FREQBAND_950 | VCO_TRIM_11, );
RF_Mode = RF_STANDBY; //RF in standby mode
break;
case RF_SLEEP:
RegisterSet(REG_MCPARAM0, RF_SLEEP | FREQBAND_950 | VCO_TRIM_11, );
RF_Mode = RF_SLEEP; //RF in sleep mode
break;
delay_ms(100);
}
}
/*********************************************************************
* void WriteFIFO(BYTE Data)
*
* Overview:
* This function fills the FIFO
*
* PreCondition:
* MRF89XA transceiver has been properly initialized
*
* Input:
* BYTE Data - Data to be sent to FIFO.
*
* Output: None
*
* Side Effects:
* The packet has been sent out
*
********************************************************************/
void WriteFIFO(BYTE Data)
{
output_low(MASTER_CS);
spi_write(Data);
output_high(MASTER_CS);
delay_ms(300);
}
/*********************************************************************
* BYTE ReadFIFO(void)
*
* Overview:
* This function reads the Reiceved frame from the fifo and sets hasPacket accordingly
*
* PreCondition:
* MRF89XA transceiver has been properly initialized
*
* Input:
* None
*
* Output: Data from FIFO
*
* Side Effects:
* The packet has been sent out
*
********************************************************************/
BYTE ReadFIFO(void)
{
BYTE value;
output_low(MASTER_CS);
value = spi_read();
output_high(MASTER_CS);
return value;
}
void MRF89XAInit(void)
{
BYTE input,i=0;
SetRFMode(RF_STANDBY);
for (i = 0 ; i <= 31; i++)
{
RegisterSet(i, InitConfigRegs[i]);
}
RF_Mode = RF_TRANSMITTER;
RegisterSet(REG_MCPARAM0, RF_SYNTHESIZER | FREQBAND_950 | VCO_TRIM_11 );
RF_Mode = RF_SYNTHESIZER;
RegisterSet(REG_IRQPARAM1, MODSEL_FSK | DATAMODE_PACKET | IFGAIN_0 | 0x02);
RegisterSet(REG_MCPARAM0, ((input & 0xE7) | FREQBAND_950));
RegisterSet(REG_R1, 125);
RegisterSet(REG_P1, 100);
RegisterSet(REG_S1, 20);
RegisterSet(REG_MCPARAM0, RF_SYNTHESIZER | FREQBAND_950 | VCO_TRIM_11);
RF_Mode = RF_SYNTHESIZER;
RegisterSet(REG_IRQPARAM1, MODSEL_FSK | DATAMODE_PACKET | IFGAIN_0 | 0x02);
SetRFMode(RF_TRANSMITTER);
RegisterSet(REG_BITRATE,BITRATE_20);
RegisterSet(REG_RXPARAM0, (RXFC_FOPLUS75 | PASSIVEFILT_234));
RegisterSet(REG_FREGDEV,FREGDEV_40);
}
/*********************************************************************
* void Send_Packet(BYTE TxPacketLen)
*
* Overview:
* This function send the packet in the buffer TxPacket
*
* PreCondition:
* MRF89XA transceiver has been properly initialized
*
* Input:
* BYTE TxPacketLen The length of the packet to be
* sent.
*
* Output: None
*
* Side Effects:
* The packet has been sent out
*
********************************************************************/
void Send_Packet(BYTE TxPacketLen)
{
BYTE i;
BYTE j;
SetRFMode(RF_STANDBY);
/*
RegisterSet(REG_IRQPARAM0, (IRQ0_RX_STDBY_SYNCADRS | IRQ1_RX_STDBY_CRCOK | IRQ1_TX_TXDONE | IRQ1_FIFO_OVERRUN_CLEAR));
RegisterSet(REG_IRQPARAM1, (DEF_IRQPARAM1 | IRQ0_TX_START_FIFOTHRESH | IRQ1_PLL_LOCK_PIN_ON ));
RegisterSet(REG_PKTPARAM3, ((InitConfigRegs[REG_PKTPARAM3] & 0xBF)| FIFO_STBY_ACCESS_WRITE));
RegisterSet(REG_IRQPARAM0, (InitConfigRegs[REG_IRQPARAM0] | IRQ1_FIFO_OVERRUN_CLEAR ));
RegisterSet(REG_IRQPARAM1, ((InitConfigRegs[REG_IRQPARAM1]) | 0x02));
*/
RegisterSet(REG_PKTPARAM3, ((InitConfigRegs[REG_PKTPARAM3] & 0xBF)| FIFO_STBY_ACCESS_WRITE));
RegisterSet(REG_IRQPARAM0, (InitConfigRegs[REG_IRQPARAM0] | IRQ1_FIFO_OVERRUN_CLEAR ));
RegisterSet(REG_IRQPARAM1, ((InitConfigRegs[REG_IRQPARAM1]) | 0x02));
WriteFIFO(TxPacketLen+1);
WriteFIFO(0x00); //Node_adrs
for(i=0; i< TxPacketLen; i++)
{
WriteFIFO(TxPacket[i]);
}
delay_ms(500);
SetRFMode(RF_TRANSMITTER);
delay_ms(500);
SetRFMode(RF_STANDBY);
}
//======================================
void main()
{
delay_ms(2000);
char c;
output_high(MASTER_CS);
output_high(CSDATA);
delay_ms(100);
setup_oscillator( OSC_4MHZ );
MRF89XAInit();
BYTE TxPacket[] = "Hello!";
while(1)
{
delay_ms(500);
Send_Packet(64);
output_high(PIN_A2);
fputs(TxPacket,hostPC);
RegisterSet(0x02,0x02);
delay_ms(500);
RegisterRead(0x02);
}
}
|
|
|
|
|
|
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
|