| ??? 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);
|
| Topic | Author | Date |
| 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 |



