|
|
View previous topic :: View next topic |
Author |
Message |
mkr
Joined: 08 Aug 2006 Posts: 49
|
integerating MAX3110 to work with PIC 18F8722 |
Posted: Tue Aug 08, 2006 12:45 pm |
|
|
Could somebody help me out in intergrating the max3110 driver refered from http://www.ccsinfo.com/forum/viewtopic.php?t=23954&highlight=max3110
link. I have a PIC 18F8722 with
PIN_D4 as SDO,
PIN_D5 as SDI,
PIN_D6 as SCLK
PIN_B0 as external interrupt from the MAX3110.
CS for MAX3110 is low.
Should I use the #use rs232 directive to configure the pins or is there an any other. I am confused.
Should I use setup_spi(....) and the spi_write(..), spi_read(...) before that how will I tell the max3110 for the DIN/OUT/SCLK pins
Thanks
mkr _________________ Thanks
mkr |
|
|
Ttelmah Guest
|
|
Posted: Tue Aug 08, 2006 2:43 pm |
|
|
#USE RS232, is for the internal chip UART(s) only. Use this to setup the internal UART, ifyou want multiple RS232 channels.
The code intitialises the SPI itself. It dates from a point in time, when the internal SPI setup, did not work reliably, so it goes DIY.
The code uses it's own SPI functions, because the internal versions are not designed for use with interrupts, and implement some tests wrongly for this application. These will need to be changed to address the second SPI port (since this is what you are connected to).
You need CS connected to a pin on the PIC. It is used to control the transactions.
You will need to change the registers used, or use the CCS code to initialise the second SPI port, rather than the first. You do not have to tell the MAX3110 anything about what pins are used, provided the right signals are connected. It couldn't 'care a damn' where the signals actually come from.
You can also use the 'clear_interrupts' command, rather than accessing the EXT0IF directly (again the code dates from before this command existed).
Best Wishes |
|
|
mkr
Joined: 08 Aug 2006 Posts: 49
|
superb...but some more queries |
Posted: Tue Aug 08, 2006 8:34 pm |
|
|
So when I use the max3110 driver code, I replace EXT0IF with clear_interrupts function call.
How about setting up the driver with the main().
I call clearbuff() then call maconfig(...) and then when I want to tx a byte, I call maxputc(...). I will have the external interrput raised when I recv a byte at the port.
I like the max3110 driver, bcos is closely talks and configures the pic registers. _________________ Thanks
mkr |
|
|
Ttelmah Guest
|
|
Posted: Wed Aug 09, 2006 2:16 am |
|
|
This is 'cut and pasted', from one of the original programs using this chip, with some mods/comments to show how to use each part:
Code: |
#define MAX9600 (11) //This value has to be worked out from the data
#define MAX_has_data() hasdata(MAXIPbuff,MAXIPin,MAXIPout,SIBUFF)
#define MAXgetc() frombuff(MAXIPbuff,MAXIPin,MAXIPout,SIBUFF)
//Initialise the Maxim buffer/chip
initbuff();
//Configure the Maxim chip - here for 9600N81
Maxconfig(MAX9600);
ENABLE_INTERRUPTS(INT_EXT);
//Then to check if a character is available
if (MAX_has_data()) {
//Here data is available in the input buffer
}
//Then to read a character (probably in the above test)
chr=MAXgetc();
//Then to send a character
Maxputc(' '); //sends a space,or whatever you want
//Then to send a complex output
printf(Maxputc(),"Test string - char val %3d/n',chr);
|
Given that EXT0IF, has to be defined for the wait loop in the interrupt handler, the original code might as well be used.
The big chage you are going to have to make, is to work out the port addresses for the secondary SSP on the chip you are using.
Best Wishes |
|
|
mkr
Joined: 08 Aug 2006 Posts: 49
|
thanks a lot. how to get the baud index |
Posted: Wed Aug 09, 2006 7:21 am |
|
|
Thanks for your great help. I appreciate it. How to find the baud_index. how does 11 work out be 9600.
Give me an insight _________________ Thanks
mkr |
|
|
Ttelmah Guest
|
|
Posted: Wed Aug 09, 2006 9:58 am |
|
|
Data sheet for the chip. Table 7. With the 3.6864MHz clock, 1011 (binary), is the 9600bps selection. Note that you really _must_ run this chip at 3.6864MHz, or 1.8432MHz, or standard baud rates just won't be available.
Best Wishes |
|
|
mkr
Joined: 08 Aug 2006 Posts: 49
|
I got it ...but problem with BF |
Posted: Wed Aug 09, 2006 12:07 pm |
|
|
I got the config working. so when i write 0xc80a to the write config register and read back i get the same which is 0xc80a. So thats working.
Now in the code for ssp_txfr16(...), you are waiting for BF to go high, but does not happen and the WAIT_FOR_SSP() just hangs there. I have taken out WAIT_FOR_SSP() and it works just fine. Is it ok this way. _________________ Thanks
mkr |
|
|
mkr
Joined: 08 Aug 2006 Posts: 49
|
not returning the correct baud rate |
Posted: Wed Aug 09, 2006 1:52 pm |
|
|
I have written to the write config 0xc40a and when reading I set the read config to 0x4000, but dont get the baud rate. In return I have 0x4000.
Whats the problem. _________________ Thanks
mkr |
|
|
Ttelmah Guest
|
|
Posted: Wed Aug 09, 2006 3:24 pm |
|
|
Remember _all_ the register difinitions need to change to address the second SSP. This includes the BF bit.
Code: |
//Defines for the _second_ SSP port again for a 18F chip
#byte SSPBUF = 0xF66
#byte SSPCON = 0xF63
#byte I2CBUF = 0xF65
#byte SSPSTAT = 0xF64
#define SSPC_INIT 0x00
#bit SSPEN = 0xF63.5
#define SSPS_INIT 0x40
#bit BF = SSPSTAT.0
|
Best Wishes |
|
|
mkr
Joined: 08 Aug 2006 Posts: 49
|
yes all my registers are set as per SPI2 |
Posted: Wed Aug 09, 2006 4:04 pm |
|
|
:shock: All my registers are setup as per SPI2 same has what you have mentioned.Here is the code after my modification [code]
//These for a 18F chip
#define CS_LOW output_low(PIN_J1)
#define CS_HIGH output_high(PIN_J1)
#byte INTCON = 0xFF2
#bit EXT0IF = INTCON.1 // External interrupt.
// EXT0IF = 1. interrupt occured
// EXT0IF = 0. interrupt not occured
//Buffer tests and handling
#define isempty(buff,in,out,size) (in==out)
#define hasdata(buff,in,out,size) (in!=out)
#define isfull(buff,in,out,size) (((++in)&(size-1))==out)
#define tobuff(buff,in,out,size,chr){ \
buff[in]=chr;\
in=((++in) & (size-1));\
if (in==out)\
out=((++out) & (size-1));\
}
#define frombuff(buff,in,out,size) (btemp=out,\
out=(++out) & (size-1), \
buff[btemp])
#define ifrombuff(buff,in,out,size) (ibtemp=out,\
out=(++out) & (size-1), \
buff[ibtemp])
#define clrbuff(buff,in,out,size) { in=0;out=0;}
//Declares for buffers.
#define SIBUFF (32)
#define SOBUFF (64)
int8 MAXIPbuff[SIBUFF],MAXIPin,MAXIPout;
int8 MAXOPbuff[SOBUFF],MAXOPin,MAXOPout;
int8 btemp,ibtemp;
int1 empty;
int16 Mconfig;
int8 msb,lsb;
#byte SSP2CON = 0xF63
#byte SSP2STAT = 0xF64
#byte I2C2BUF = 0xF65
#byte SSP2BUF = 0xF66
#define SSP2C_INIT 0x00
#bit SSP2EN = 0xF63.5
#define SSP2S_INIT 0x40
#bit BF = SSP2STAT.0
#bit SMP = SSP2STAT.7
#bit CKE = SSP2STAT.6
#bit CKP = SSP2CON.4
#bit SSPM3 = SSP2CON.3
#bit SSPM2 = SSP2CON.2
#bit SSPM1 = SSP2CON.1
#bit SSPM0 = SSP2CON.0
//#define BF SSP2STAT.0
#define READ_SSP() (SSP2BUF)
#define WAIT_FOR_SSP() while(!BF)
#define WRITE_SSP(x) SSP2BUF = (x)
#define CLEAR_WCOL() SSP2CON = SSP2CON & 0x3F
#define MAX_has_data() hasdata(MAXIPbuff,MAXIPin,MAXIPout,SIBUFF)
#define MAXgetc() frombuff(MAXIPbuff,MAXIPin,MAXIPout,SIBUFF)
/***
empty all buffers
*/
void max_initbuff(void) {
SSP2EN = 1;
SMP = 1;
CKE = 0;
CKP = 0;
SSPM3 = 0;
SSPM2 = 0;
SSPM1 = 0;
SSPM0 = 1;
clrbuff(MAXIPbuff,MAXIPin,MAXIPout,SIBUFF);
clrbuff(MAXOPbuff,MAXOPin,MAXOPout,SOBUFF);
//Clear any other buffers here
}
/***
routine to send and receive a 16bit value from the Maxim chip
Latch the data at this point
*/
int16 ssp_txfr16(int16 val) {
// int8 msb,lsb;
CS_LOW;
WRITE_SSP(make8(val,1)); // send msb
WAIT_FOR_SSP();
msb=READ_SSP();
WRITE_SSP(make8(val,0)); // send lsb
WAIT_FOR_SSP();
lsb=READ_SSP();
CS_HIGH;
return ((int16)msb << 8 | lsb);
}
/***
routine to send and receive a 16bit value
from the Maxim chip inside the interrupt
*/
int16 issp_txfr16(int16 val) {
int8 msb,lsb;
CS_LOW;
WRITE_SSP(make8(val,1)); // send msb
msb=READ_SSP();
WRITE_SSP(make8(val,0)); // send lsb
lsb=READ_SSP();
CS_HIGH;
return ((int16)msb << 8 | lsb);
}
/***
Maxim chip baud rate confuguration
*/
void Maxconfig(int8 baud_index) {
baud_index &= 0xF;
Mconfig = 0xC400L + make16(0,baud_index);
//Ensure chip has accepted the data
do {
readconfig = ssp_txfr16(Mconfig);
readconfig = ssp_txfr16(0x4000L);//((ssp_txfr16(0x4000L) ^ Mconfig) & 0x3FFF);
if (((ssp_txfr16(0x4000L) ^ Mconfig) & 0x3FFF)==0)
break;
}
while(true);
}
/***
Puts a char Maxim chip.
*/
void Maxputc(int8 chr) {
int16 tval;
DISABLE_INTERRUPTS(INT_EXT);
tobuff(MAXOPbuff,MAXOPin,MAXOPout,SOBUFF,chr);
empty=false;
Mconfig=Mconfig | 0xC800;
tval=ssp_txfr16(Mconfig);
//Force an interrupt event
EXT0IF=1;
ENABLE_INTERRUPTS(INT_EXT);
}
/***
Interrupt from Maxim chip
*/
#INT_EXT NOCLEAR
void MAXIM(void) {
unsigned int16 Rxdata;
do {
//Clear the interrupt flag
EXT0IF=0;
//force a read
Rxdata = issp_txfr16(0L);
if (Rxdata & 0x8000L){
//Here a receive character is present
tobuff(MAXIPbuff,MAXIPin,MAXIPout,SIBUFF,make8(Rxdata,0));
}
if (Rxdata & 0x4000L) {
//Here the chips TX buffer is empty
if (hasdata(MAXOPbuff,MAXOPin,MAXOPout,SOBUFF)) {
Rxdata=issp_txfr16(0x8000L | make16(0,ifrombuff(MAXOPbuff,MAXOPin,MAXOPout,SOBUFF)));
//Check if a byte was received with the transmission
if (Rxdata & 0x8000L){
tobuff(MAXIPbuff,MAXIPin,MAXIPout,SIBUFF,make8(Rxdata,0));
}
empty=false;
}
else {
empty=true;
Mconfig &= (~0x0800L);
//disable transmitter interrupt
issp_txfr16(Mconfig);
}
}
//Loop if the interrupt has set again, to give faster handling
} while (EXT0IF);
}
[/code] _________________ Thanks
mkr |
|
|
mkr
Joined: 08 Aug 2006 Posts: 49
|
Ttelmah..this is for you...max3110 |
Posted: Tue Aug 22, 2006 10:42 am |
|
|
Based on your code as outlined below
////////////////////////////////////////////////////////////////////////////////////
#define MAX9600 (11) //This value has to be worked out from the data
#define MAX_has_data() hasdata(MAXIPbuff,MAXIPin,MAXIPout,SIBUFF)
#define MAXgetc() frombuff(MAXIPbuff,MAXIPin,MAXIPout,SIBUFF)
//Initialise the Maxim buffer/chip
initbuff();
//Configure the Maxim chip - here for 9600N81
Maxconfig(MAX9600);
ENABLE_INTERRUPTS(INT_EXT);
//Then to check if a character is available
if (MAX_has_data()) {
//Here data is available in the input buffer
}
//Then to read a character (probably in the above test)
chr=MAXgetc();
//Then to send a character
Maxputc(' '); //sends a space,or whatever you want
//Then to send a complex output
printf(Maxputc(),"Test string - char val %3d/n',chr);
////////////////////////////////////////////////////////////////////////////////////
I dont see the buffer begin filled. Here is my actual code from main
main(){
char chr=0;
int8 i=0;
if (MAX_has_data()) { //Here data is available in the input buffer
maxreadbuff[maxindata]=MAXgetc(); //Then to read a character
maxindata++;
}
if(!input(PIN_J2)){
if(toggle1==0){
for(i=0;i<8;i++){
maxreadbuff[i]='a'+i;
Maxputc(maxreadbuff[i]); //return what we recieved
}
toggle1=1;
}
}
if(input(PIN_J2))
toggle1=0;
}
What I am trying to do here is to tx out 8 bytes such as 'abcdefgh' which my PC records. That is working fine allthough there is break in message..I dont know why. I recieve 'abcd' or some times 'efgha' etc etc.
The second thing is.. I dont recieve any byte when I send from my PC. The IRQ pin goes low after I recieve the recv data, but does not go high and hence MAX_has_data() is always low.
I am stuck here. Help needed. _________________ Thanks
mkr |
|
|
Ttelmah Guest
|
|
Posted: Tue Aug 22, 2006 3:03 pm |
|
|
I don't see interrupts bing enabled in your 'actual code from main' posted.
The data is already buffered in both directions in the code I posted, so why are you moving it to another buffer?.
Yuor line, which claims to 'return what we have received', does no such thing, sending just the a,b,c characters you refer to.
Learn to post, using the 'code' buttons, and with html off, and we may have a hope of seeing what is wrong...
Best Wishes |
|
|
mkr
Joined: 08 Aug 2006 Posts: 49
|
here is the code |
Posted: Tue Aug 22, 2006 3:16 pm |
|
|
Code: |
////////////////////////////////////////////////////////////////////////////////////
#define MAX9600 (11) //This value has to be worked out from the data
#define MAX_has_data() hasdata(MAXIPbuff,MAXIPin,MAXIPout,SIBUFF)
#define MAXgetc() frombuff(MAXIPbuff,MAXIPin,MAXIPout,SIBUFF)
//Initialise the Maxim buffer/chip
initbuff();
//Configure the Maxim chip - here for 9600N81
Maxconfig(MAX9600);
ENABLE_INTERRUPTS(INT_EXT);
//Then to check if a character is available
if (MAX_has_data()) {
//Here data is available in the input buffer
}
//Then to read a character (probably in the above test)
chr=MAXgetc();
//Then to send a character
Maxputc(' '); //sends a space,or whatever you want
//Then to send a complex output
printf(Maxputc(),"Test string - char val %3d/n',chr);
////////////////////////////////////////////////////////////////////////////////////
|
I dont see the buffer begin filled. Here is my actual code from main
Code: |
main(){
char chr=0;
int8 i=0;
if (MAX_has_data()) { //Here data is available in the input buffer
maxreadbuff[maxindata]=MAXgetc(); //Then to read a character
maxindata++;
}
if(!input(PIN_J2)){
if(toggle1==0){
for(i=0;i<8;i++){
maxreadbuff[i]='a'+i;
Maxputc(maxreadbuff[i]); //return what we recieved
}
toggle1=1;
}
}
if(input(PIN_J2))
toggle1=0;
}
|
_________________ Thanks
mkr |
|
|
mkr
Joined: 08 Aug 2006 Posts: 49
|
interrupt already enabled |
Posted: Tue Aug 22, 2006 3:23 pm |
|
|
the part of the code I showed was only the serail routine. The interupts are allready enabled on top of the code. sorry for not showing the interrupts.
Here goes the actual code
Code: |
main() {
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
// setup_spi2(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_16);
// setup_spi2(SPI_MASTER | SPI_XMIT_L_TO_H | SPI_CLK_DIV_16);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_4); //resolution for 1 us each, 65.5 ms overflow
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_timer_4(T4_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
// enable_interrupts(INT_EXT); // for spi max3110 chipset
enable_interrupts(INT_TIMER0); // timer0 interrupt
enable_interrupts(INT_TIMER1); // timer1 interrupt
enable_interrupts(INT_RDA); // COM1
disable_interrupts(INT_TBE); // COM1
enable_interrupts(INT_RDA2); // COM2
disable_interrupts(INT_TBE2); // COM2
enable_interrupts(GLOBAL); // global
max_init();
Maxconfig(MAX3110_BAUD);
enable_interrupts(INT_EXT); // MAX3110E - RS232 port
for (;;) {
max3110();
}
}
void max3110(void){
// Maxconfig(MAX3110_BAUD);
int8 i=0;
if (MAX_has_data()) { //Here data is available in the input buffer
maxreadbuff[maxindata]=MAXgetc(); //Then to read a character
maxindata++;
}
if(maxindata!=0){
for(i=0;i<maxindata;i++)
Maxputc(maxreadbuff[i]); //return what we recieved
maxindata=0;
}
}
|
_________________ Thanks
mkr |
|
|
mkr
Joined: 08 Aug 2006 Posts: 49
|
Can somebody help me with the code |
Posted: Wed Aug 23, 2006 10:58 am |
|
|
It seems that this code works some times or does not. So I had to enable the interrupt flag every time after going through the ISR and also at Maxconfig bit. this bit is EXT0IF.
Code: |
#include <max3110.h>
/***
empty all buffers
*/
void max_init(void) {
set_tris_d(0x20);
set_tris_b(0x01);
SSP2EN = 1;
SMP = 1;
CKE = 1;
CKP = 0;
SSPM3 = 0;
SSPM2 = 0;
SSPM1 = 1;
SSPM0 = 0;
clrbuff(MAXIPbuff,MAXIPin,MAXIPout,SIBUFF);
clrbuff(MAXOPbuff,MAXOPin,MAXOPout,SOBUFF);
delay_us(500);
//Clear any other buffers here
}
/***
routine to send and receive a 16bit value from the Maxim chip
Latch the data at this point
*/
int16 ssp_txfr16(int16 val) {
// int8 msb,lsb;
CS_LOW;
WRITE_SSP(make8(val,1)); // send msb
WAIT_FOR_SSP();
msb=READ_SSP();
WRITE_SSP(make8(val,0)); // send lsb
WAIT_FOR_SSP();
lsb=READ_SSP();
CS_HIGH;
return ((int16)msb << 8 | lsb);
}
/***
routine to send and receive a 16bit value
from the Maxim chip inside the interrupt
*/
int16 issp_txfr16(int16 val) {
// int8 msb,lsb;
CS_LOW;
WRITE_SSP(make8(val,1)); // send msb
WAIT_FOR_SSP();
msb=READ_SSP();
WRITE_SSP(make8(val,0)); // send lsb
WAIT_FOR_SSP();
lsb=READ_SSP();
CS_HIGH;
return ((int16)msb << 8 | lsb);
}
/***
Maxim chip baud rate confuguration
*/
void Maxconfig(int8 baud_index) {
baud_index &= 0xF;
Mconfig = 0xC400L + make16(0,baud_index);
//Ensure chip has accepted the data
do {
readconfig = ssp_txfr16(Mconfig);
if (((ssp_txfr16(0x4000L) ^ Mconfig) & 0x3FFF)==0)
break;
}
while(true);
EXT0IF=1;
}
/***
Puts a char Maxim chip.
*/
void Maxputc(int8 chr) {
int16 tval;
DISABLE_INTERRUPTS(INT_EXT);
tobuff(MAXOPbuff,MAXOPin,MAXOPout,SOBUFF,chr);
empty=false;
Mconfig=Mconfig | 0xC800;
tval=ssp_txfr16(Mconfig);
//Force an interrupt event
EXT0IF=1;
ENABLE_INTERRUPTS(INT_EXT);
}
/***
Interrupt from Maxim chip
*/
#INT_EXT NOCLEAR
void MAXIM(void) {
Rxdata = issp_txfr16(0L);
MAXIPbuff[MAXIPin]=make8(Rxdata,0);
MAXIPin=((++MAXIPin) & (SIBUFF-1));
if (MAXIPin==MAXIPout)
MAXIPout=((++MAXIPout) & (SIBUFF-1));
// tobuff(MAXIPbuff,MAXIPin,MAXIPout,SIBUFF,make8(Rxdata,0));
EXT0IF=1;
}
|
I am sending '02 01 23 7c 00 23 7c 64' and what I see in the buffer is 02. I need your expert advice. _________________ Thanks
mkr |
|
|
|
|
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
|