CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Anyone written a MAX3310 driver?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
JamesW
Guest







Anyone written a MAX3310 driver?
PostPosted: Wed Aug 10, 2005 4:42 am     Reply with quote

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







PostPosted: Wed Aug 10, 2005 6:53 am     Reply with quote

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







PostPosted: Wed Aug 10, 2005 7:54 am     Reply with quote

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







PostPosted: Wed Aug 10, 2005 8:26 am     Reply with quote

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








PostPosted: Fri Sep 23, 2005 10:03 am     Reply with quote

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







PostPosted: Fri Sep 23, 2005 2:52 pm     Reply with quote

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







PostPosted: Sat Sep 24, 2005 12:03 pm     Reply with quote

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







PostPosted: Thu Jun 14, 2007 5:42 pm     Reply with quote

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







PostPosted: Thu Jun 14, 2007 5:55 pm     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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