Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
02/06/09 16:36
Read: times


 
#162147 - Update......Problem solved
Responding to: ???'s previous message
I finally unstuck my brain and realized that I already had the needed adjustable code in place and forgot that I thought of that when I first modified the code architect intermediate code. All the passing arguments were not needed since all I had to do was update my external max_bytes array which is watched when bytenum is pass into the islasttxbyte function is called.

I've attached the final code I'm using to show the final results, thanks to all who input some help.

Regards,
Chris


Called from main.c

extern unsigned char transmit_bytes[];
extern unsigned char MAX_NUMBYTE_TX[];

transmit_bytes[0]=0x03;
MAX_NUMBYTE_TX[0] = 0; //Transmit 1 data byte
i2c_init(0x20, 0); //Set to master with address of 0x20, no general call
i2c_transmit(0x77);
while (i2c_getstatus() & I2C_BUSY);	// wait until complete

transmit_bytes[0]=0x03; transmit_bytes[1]=0x04;
MAX_NUMBYTE_TX[0] = 1; //Transmit 2 data bytes
i2c_init(0x20, 0); //Set to master with address of 0x20, no general call
i2c_transmit(0x77);
while (i2c_getstatus() & I2C_BUSY);	// wait until complete

transmit_bytes[0]=0xfe; transmit_bytes[1]=0x04; transmit_bytes[2]=0x05;
MAX_NUMBYTE_TX[0] = 2; //Transmit 2 data bytes
i2c_init(0x20, 0); //Set to master with address of 0x20, no general call
i2c_transmit(0x77); 
while (i2c_getstatus() & I2C_BUSY);	// wait until complete


Called fromo i/o.c

extern uchar transmit_bytes[];
extern unsigned char MAX_NUMBYTE_TX[];


I2C_master.c

// SFR description needs to be included
#include "reg936.h"
#include "i2c.h"
// MODULE INTERNAL VARIABLES
static unsigned char slaveaddress;// internal copy of slave address
static unsigned char i2cstatus;	// I2C transfer status
static unsigned int bytenum; // current number of byte transferred
unsigned char MAX_NUMBYTE_TX[] = {0};
unsigned char transmit_bytes[] = {0,0,0,0,0,0,0};	//Holds I2C data bytes
								    				//only
								    				//Not address



//======================================================================
// MASTER CALLBACK FUNCTIONS
//======================================================================
unsigned char i2c_master_getbyte(unsigned int bytenum)					
{
  return transmit_bytes[bytenum];  // Points to data array byte to send
  								   // via I2C 
  return 0;
}
//======================================================================
void i2c_master_receivedbyte(unsigned int bytenum, unsigned char value){
  unsigned char t1, t2;
  t1=bytenum;
  t2=value;}
//======================================================================
unsigned char i2c_master_islasttxbyte(unsigned int bytenum){
  bytenum++;
  if (bytenum > MAX_NUMBYTE_TX[0]) bytenum = 0;//Max I2C data bytes  
  if (bytenum == 0) return 1;  //Checks if it should keep transmitting
  return 0;}
//======================================================================
unsigned char i2c_master_islastrxbyte(unsigned int bytenum){
  if (bytenum == 1) return 1;
  return 0;}
//======================================================================
void i2c_transfer_finished(void){
}
//======================================================================
// MODULE INTERNAL FUNCTIONS
//======================================================================
void i2c_isr(void) interrupt 6 using 3{
  unsigned char status;

  status = I2STAT & 0xF8;

  switch(status)
  {
    case 0x08:
    case 0x10:
 	  I2DAT = slaveaddress;
      STA = 0;
	  STO = 0;
	  bytenum = 0;
	  break;

	// MASTER TRANSMITTER
  	// ACK for slave address + W
	case 0x18:
	  I2DAT = i2c_master_getbyte(bytenum);
	  //I2DAT = 0xAA;
	  STA = 0;
	  STO = 0;
	  break;
	// no ACK for slave address + W
	case 0x20:
	  // stop condition
	  STA = 0;
	  STO = 1;
      i2cstatus = I2C_ERROR;
	  i2c_transfer_finished();
      break;
	// ACK for data byte
  	case 0x28:
	  if (i2c_master_islasttxbyte(bytenum))
	  {
	    // stop condition
	    STA = 0;
	    STO = 1;
        i2cstatus = I2C_OK;
  	    i2c_transfer_finished();
	  }
	  else
	  {
  	    bytenum++;
	    I2DAT = i2c_master_getbyte(bytenum);
		STA = 0;
		STO = 0;
	  }
	  break;
	// no ACK for data byte
	case 0x30:
	  // stop condition
	  STA = 0;
	  STO = 1;
      i2cstatus = I2C_ERROR;
	  i2c_transfer_finished();
	  break;
	// arbitration lost
	case 0x38:
	  // start condition - try again
	  STA = 1;
	  STO = 0;
	  break;

	// MASTER RECEIVER
    // ACK for slave address + R
	case 0x40:
	  STA = 0;
	  STO = 0;
	  if (i2c_master_islastrxbyte(bytenum))
	  {
  	    // return NACK for data byte
	    AA = 0;
	  }
  	  else
	  {
	    // return ACK for data byte
	    AA = 1;
	  }
	  break;
	// no ACK for slave address + R
	case 0x48:
	  STA = 0;
	  // stop condition
	  STO = 1;
      i2cstatus = I2C_ERROR;
	  i2c_transfer_finished();
	  break;
    // ACK for data byte
	case 0x50:
	  i2c_master_receivedbyte(bytenum, I2DAT);
      bytenum++;
	  STA = 0;
	  STO = 0;
	  if (i2c_master_islastrxbyte(bytenum))
	  {
	    // return NACK for next data byte
	    AA = 0;
	  }
	  else
	  {
  	    // return ACK for next data byte
 	    AA = 1;
	  }
	  break;
    // no ACK for data byte
	case 0x58:
	  i2c_master_receivedbyte(bytenum, I2DAT);
	  STA = 0;
	  // stop condition
	  STO = 1;
      i2cstatus = I2C_OK;
      i2c_transfer_finished();
      break;

	

    // unknown state
	default:
      i2cstatus = I2C_ERROR;
      STA = 0;
	  STO = 0;
      // go back to slave mode waiting to be addressed
	  AA = 1;
      i2c_transfer_finished();
	  break;
  }

  // clear interrupt flag
  SI = 0;  
}
//======================================================================
void i2c_init
  (
  unsigned char address,  // The 7-bit I2C address to use
  bit generalcall         // 1 = respond to general call, 0 = ignore
                          // general call
  )
{
  // set pins to open-drain
  P1M1 |= 0x0C;
  P1M2 |= 0x0C;

  // configure I2C address
  I2ADR = 0x20;
  I2ADR = address << 1;
  if (generalcall)
  {
    I2ADR |= 0x01;
  } // if

  // configure internal SCL generator
  I2SCLH = 0x08;
  I2SCLL = 0x07;

  // configure I2C interface
  // use internal SCL generator
  I2CON = 0x44;

  // set interrupt priority to 0
  IP1 &= ~0x01;
  IP1H &= ~0x01;

  // initial status
  i2cstatus = I2C_IDLE;

  // enable interrupt
  EI2C = 1;
} // i2c_init
//======================================================================
unsigned char i2c_transmit(unsigned char address)
{
  
  
  //extern unsigned char byte1, byte2;
  // if already busy then return current status
  if (i2cstatus & I2C_BUSY) return i2cstatus;

  // now we are busy performing a transfer
  i2cstatus = I2C_BUSYTX;

  // store slave address + W for use in ISR
  slaveaddress = address << 1;

  // transmit start condition
  STA = 1; 

  // transmission started
  return I2C_OK;


}
//======================================================================
/*
//======================================================================
// FUNCTION:    i2c_receive
// DESCRIPTION: attempts to start an I2C reception as a master from a
//              device with a specific address. If successful then
//              master callback functions will be called to handle the
//              data for the transfer
// INPUT:       address of device to receive from
// OUTPUT:      I2C_BUSYTX if I2C is already busy transmitting data
//              I2C_BUSYRX if I2C is already busy receiving data
//              I2C_OK if reception started
// NOTES:       Can check if I2C busy by ANDing returned value with
//              I2C_BUSY
//======================================================================
unsigned char i2c_receive(unsigned char address)
{
  // if already busy then return current status
  if (i2cstatus & I2C_BUSY) return i2cstatus;

  // now we are busy performing a transfer
  i2cstatus = I2C_BUSYRX;

  // store slave address + R for use in ISR
  slaveaddress = (address << 1) | 0x01;

  // transmit start condition
  STA = 1;

  // reception started
  return I2C_OK;
}
*/
//======================================================================
unsigned char i2c_getstatus(void)
{
  // wait until any interrupt completed
  while(SI);

  // return status
  return i2cstatus;
}


i2c_master.h

// possible states for the I2C peripheral
#define I2C_IDLE   		0x00
#define I2C_BUSY   		0x01
#define I2C_BUSYTX 		0x03
#define I2C_BUSYRX 		0x05
#define I2C_OK     		0x02
#define I2C_ERROR  		0x04
//======================================================================
extern void i2c_init(unsigned char address, bit generalcall);
//======================================================================
extern unsigned char i2c_receive(unsigned char address);
//======================================================================
extern unsigned char i2c_getstatus(void);
//======================================================================
extern unsigned char i2c_transmit(unsigned char address);

 



List of 14 messages in thread
TopicAuthorDate
dynamic parameters in an I2C definition possible?            01/01/70 00:00      
   how about            01/01/70 00:00      
      trans_byte buffer?            01/01/70 00:00      
         something like:            01/01/70 00:00      
            Updated, but errors on my part            01/01/70 00:00      
               This            01/01/70 00:00      
                  I must be stuck on stupid            01/01/70 00:00      
                     I Think it is this            01/01/70 00:00      
                        Array of pointers to characters            01/01/70 00:00      
               Try this code            01/01/70 00:00      
                  Works great!...One question though            01/01/70 00:00      
                     The warning is real            01/01/70 00:00      
                     Not exactly as I coded            01/01/70 00:00      
                        Update......Problem solved            01/01/70 00:00      

Back to Subject List