|
|
View previous topic :: View next topic |
Author |
Message |
JamesW Guest
|
Anyone written a MAX3310 driver? |
Posted: Wed Aug 10, 2005 4:42 am |
|
|
Hi folks,
has anyone written a driver for the MAX31110/11?
If so - what sort of data rates can you get out of usart realistically? I assume that you would use interrupts for the receive side of things?
Any code samples would be gratefully received.
Cheers
James |
|
|
Ttelmah Guest
|
|
Posted: Wed Aug 10, 2005 6:53 am |
|
|
Assuming you mean the Max 3110 (you have used 3310 in the header, and 31110 in the main post), yes.
I had significant problems with the device (asked a couple of questions here at the time, but nobody was using the unit apparently), when first trying to gt it working.
The C code supplied by Maxim, will convert, but only works if there is data arriving regularly. Basically if the device is sending only, and the buffer goes empty, and no data is waiting in your software buffer, it will not re-interrupt when re-enabled (which the Maxim code appears to assume)...
To get it to trigger reliably in both directions, you have to deliberately force an extra interrupt call whenever data is ready to be sent to the chip.
Also to avoid interrupts being disabled for too long on the transfers (if using high rates), I used seperate transfer routines inside the interrupts.
Attached are my original 'test' versions, using the hardware SSP, and the external interrupt for the chip, and 'CS' defined as the pin connected to CS on the Maxim.
Code: |
//These for a 18F chip
#byte INTCON = 0xFF2
#bit EXT0IF = INTCON.1
//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. I have three others not shown here
#define SIBUFF (32)
#define SOBUFF (64)
int8 MAXIPbuff[SIBUFF],MAXIPin,MAXIPout;
int8 MAXOPbuff[SOBUFF],MAXOPin,MAXOPout;
int8 btemp,ibtemp;
//Defines for the SSP port again for a 18F chip
#byte SSPBUF = 0xFC9
#byte SSPCON = 0xFC6
#byte I2CBUF = 0xFC8
#byte SSPSTAT = 0xFC7
#define SSPC_INIT 0x00
#bit SSPEN = 0xFC6.5
#define SSPS_INIT 0x40
#bit BF = SSPSTAT.0
/* Now the SSP handler code. Using my own, since the supplied routines test the wrong way round for my needs */
#DEFINE READ_SSP() (SSPBUF)
#DEFINE WAIT_FOR_SSP() while(!BF)
#DEFINE WRITE_SSP(x) SSPBUF=(x)
#DEFINE CLEAR_WCOL() SSPCON=SSPCON & 0x3F
#INT_EXT NOCLEAR //Interrupt from Maxim chip
void MAXIM(void) {
unsigned int16 Rxdata;
do {
//Clear the interrupt flag
EXT0IF=0;
//force a read
Rxdata = iSSPtransfer16(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=iSSPtransfer16(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
iSSPtransfer16(Mconfig);
}
}
//Loop if the interrupt has set again, to give faster handling
} while (EXT0IF);
}
int16 SSPtransfer16(int16 val) {
int8 msb;
//routine to send and receive a 16bit value from the Maxim chip
//Latch the data at this point
CS=0;
//send high byte
WRITE_SSP(make8(val,1));
WAIT_FOR_SSP();
msb=READ_SSP();
//now send the low byte
WRITE_SSP(make8(val,0));
WAIT_FOR_SSP();
CS=1;
return(make16(msb,READ_SSP()));
}
int16 iSSPtransfer16(int16 val) {
int8 msb;
//routine to send and receive a 16bit value from the Maxim chip inside the
//interrupt
CS=0;
//send high byte
WRITE_SSP(make8(val,1));
WAIT_FOR_SSP();
msb=READ_SSP();
//now send the low byte
WRITE_SSP(make8(val,0));
WAIT_FOR_SSP();
CS=1;
return(make16(msb,READ_SSP()));
}
//empty all buffers
void initbuff(void) {
clrbuff(MAXIPbuff,MAXIPin,MAXIPout,SIBUFF);
clrbuff(MAXOPbuff,MAXOPin,MAXOPout,SOBUFF);
//Clear any other buffers here
}
//Subroutines to talk to the Maxim chip.
void Maxputc(int8 chr) {
int16 tval;
DISABLE_INTERRUPTS(INT_EXT);
tobuff(MAXOPbuff,MAXOPin,MAXOPout,SOBUFF,chr);
empty=false;
Mconfig=Mconfig | 0xC800;
tval=SSPtransfer16(Mconfig);
//Force an interrupt event - bodge!...
ext0if=1;
ENABLE_INTERRUPTS(INT_EXT);
}
void Maxconfig(int8 baud_index) {
baud_index &= 0xF;
Mconfig = 0xC400L + make16(0,baud_index);
//Ensure chip has accepted the data
do {
SSPtransfer16(Mconfig);
if (((SSPtransfer16(0x4000L) ^ Mconfig) & 0x3FFF)==0) break;
}
while(true);
}
|
With this in place, the buffers cleared (initbuff), & external interrupt setup on INT_EXT, the code runs, using 'Maxputc' to output data, and the buffer handling code as:
hasdata(MAXIPbuff,MAXIPin,MAXIPout,SIBUFF)
Returns 'true' when data is waiting (equivalent to kbhit), and:
frombuff(MAXIPbuff,MAXIPin,MAXIPout,SIBUFF)
Retrieves the next character (equivalent to getc).
This has been running in several hundred systems now, handling data communication at 57600bps in the final version, simultaneously with serial comms at 19200bps, on the internal hardware UART.
Best Wishes |
|
|
JamesW Guest
|
|
Posted: Wed Aug 10, 2005 7:54 am |
|
|
fantastic - thanks for the help, it's much appreciated. (Had a case of finger stutter with the 1's!)
That sort of baud rate will be ideal.
Cheers
James |
|
|
Ttelmah Guest
|
|
Posted: Wed Aug 10, 2005 8:26 am |
|
|
I hope everything that is needed is either there or 'obvious'. Trimming it out of the main code, and working out which parts are needed/redundant is the hardest bit.... I ran off a 7.3728MHz oscillator, with a /2 feeding the chip, and the PIC using it's *4 PLL. This gave 3.6864Mhz for the Max3110, and 29.49Mhz for the PIC. For 9600bps, the 'baud_index' value was 11, while for 57600, it was 2.
I used no handshake on the interface, and used the second pair of RS232 drivers in the chip for the hardware UART on the PIC, to keep the chip count down.
You have 8 buffer characters in the chip, and 32 in my software buffer. Even doing a lot of other jobs, it has never missed a character. :-)
Best Wishes |
|
|
Guest
|
|
Posted: Fri Sep 23, 2005 10:03 am |
|
|
For anyone else implementing this, I have found that you need to re-enable the transmitter interrupt after every transmitter interrupt.
Otherwise the device still doesn't send consistant data, and misses characters. For some reason a stream of data coming in makes the transmitter ok.
James |
|
|
Ttelmah Guest
|
|
Posted: Fri Sep 23, 2005 2:52 pm |
|
|
The 'stream of incoming data' forces the chip to keep visting the ISR, and therefore handle the transmit.
It is a bug that I complained about to Maxim. Their 'demo' code, wont work at all, without incoming data. You will notice my 'bodge' for this on the putc code.
Best Wishes |
|
|
JamesW Guest
|
|
Posted: Sat Sep 24, 2005 12:03 pm |
|
|
very strange chip that, totally different to any normal usart which will keep interrupting you with a transmit buffer empty interrupt until you turn it off.
Thanks for your help by the way, sorry the implementation took so long - had to lay a pcb out in between asking the question and writing the software
On a 20MHz 18F pic, what sort of baud rate can it be ran at reliably? I am using it to get data off a serial device, and retransmit the data via a gprs modem to an ftp site, the faster the better but I don't want to start missing characters
james. |
|
|
zilog Guest
|
|
Posted: Thu Jun 14, 2007 5:42 pm |
|
|
Lifting this topic to ask if this code is possible to get working with printf(), fprintf() and the like, and how this is done. |
|
|
zilog Guest
|
|
Posted: Thu Jun 14, 2007 5:55 pm |
|
|
zilog wrote: | Lifting this topic to ask if this code is possible to get working with printf(), fprintf() and the like, and how this is done. |
I found out, printf(putc(), "..."); was the solution. |
|
|
|
|
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
|