Subversion Repositories Code-Repo

Compare Revisions

Ignore whitespace Rev 120 → Rev 121

/PIC Stuff/PIC_27J13/i2c.c
29,7 → 29,7
}
 
// Setup the PIC to operate as a master.
void I2C_Configure_Master() {
void I2C_Configure_Master(unsigned char speed) {
i2c_data.operating_mode = I2C_MODE_MASTER;
 
TRISCbits.TRISC3 = 1;
39,7 → 39,11
SSPCON1 = 0x0;
SSPCON2 = 0x0;
SSPCON1bits.SSPM = 0x8; // I2C Master Mode
SSPADD = 0x77; // Operate at 100KHz (48MHz)
if (speed) {
SSPADD = 0x74; // Operate at 100KHz (48MHz)
} else {
SSPADD = 0x1A; // Operate at 400KHz (48MHz)
}
SSPSTATbits.SMP = 1; // Disable Slew Rate Control
SSPCON1bits.SSPEN = 1; // Enable MSSP Module
}
57,6 → 61,7
i2c_data.buffer_in_len = length;
i2c_data.master_dest_addr = address;
i2c_data.buffer_in_read_ind = 0;
i2c_data.buffer_in_write_ind = 0;
 
// Change status to 'next' operation
i2c_data.operating_state = I2C_SEND_ADDR;
75,6 → 80,7
i2c_data.buffer_in_len = length;
i2c_data.master_dest_addr = address;
i2c_data.buffer_in_read_ind = 0;
i2c_data.buffer_in_write_ind = 0;
 
// Change status to 'next' operation
i2c_data.operating_state = I2C_SEND_ADDR;
98,6 → 104,7
i2c_data.buffer_in_len = length;
i2c_data.master_dest_addr = address;
i2c_data.buffer_in_read_ind = 0;
i2c_data.buffer_in_write_ind = 0;
 
// Change status to 'next' operation
i2c_data.operating_state = I2C_SEND_ADDR;
196,9 → 203,10
break;
case I2C_RCV_DATA:
// On receive, save byte into buffer
i2c_data.buffer_in[i2c_data.buffer_in_read_ind] = SSPBUF;
i2c_data.buffer_in_read_ind++;
if (i2c_data.buffer_in_read_ind < i2c_data.buffer_in_len) {
// TODO: handle i2c buffer overflow
i2c_data.buffer_in[i2c_data.buffer_in_write_ind] = SSPBUF;
i2c_data.buffer_in_write_ind++;
if (i2c_data.buffer_in_write_ind < i2c_data.buffer_in_len) {
// If we still need to read, send an ACK to the slave
i2c_data.operating_state = I2C_REQ_DATA;
SSPCON2bits.ACKDT = 0; // ACK
279,9 → 287,10
break;
case I2C_RCV_DATA:
// On receive, save byte into buffer
i2c_data.buffer_in[i2c_data.buffer_in_read_ind] = SSPBUF;
i2c_data.buffer_in_read_ind++;
if (i2c_data.buffer_in_read_ind < i2c_data.buffer_in_len) {
// TODO: handle i2c buffer overflow
i2c_data.buffer_in[i2c_data.buffer_in_write_ind] = SSPBUF;
i2c_data.buffer_in_write_ind++;
if (i2c_data.buffer_in_write_ind < i2c_data.buffer_in_len) {
// If we still need to read, send an ACK to the slave
i2c_data.operating_state = I2C_REQ_DATA;
SSPCON2bits.ACKDT = 0; // ACK
317,7 → 326,7
 
// Clear SSPOV (overflow bit)
if (SSPCON1bits.SSPOV == 1) {
// DBG_PRINT_I2C("I2C: overflow detected\r\n");
DBG_PRINT_I2C("I2C: overflow detected\r\n");
SSPCON1bits.SSPOV = 0;
// We failed to read the buffer in time, so we know we
// can't properly receive this message, just put us in the
330,7 → 339,7
// Read SPPxBUF if it is full
if (SSPSTATbits.BF == 1) {
received_data = SSPBUF;
// DBG_PRINT_I2C("I2C: data read from buffer: %x\r\n", SSPBUF);
DBG_PRINT_I2C("I2C: data read from buffer: %x\r\n", SSPBUF);
data_read_from_buffer = 1;
}
 
344,7 → 353,7
i2c_data.operating_state = I2C_STARTED;
// if (data_read_from_buffer) {
// if (SSPSTATbits.D_A == 1) {
//// DBG_PRINT_I2C("I2C Start: (ERROR) no address recieved\r\n");
// DBG_PRINT_I2C("I2C Start: (ERROR) no address recieved\r\n");
// // This is bad because we got data and we wanted an address
// i2c_data.operating_state = I2C_IDLE;
// i2c_data.return_status = I2C_ERR_NOADDR;
381,7 → 390,7
goto send;
}
} else {
// DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
i2c_data.operating_state = I2C_IDLE;
i2c_data.return_status = I2C_ERR_NODATA;
}
426,6 → 435,7
if (data_read_from_buffer) {
if (SSPSTATbits.D_A == 1) {
// Data received with stop bit
// TODO: handle i2c buffer overflow
i2c_data.buffer_in[i2c_data.buffer_in_write_ind] = received_data;
if (i2c_data.buffer_in_write_ind == MAXI2CBUF-1) {
i2c_data.buffer_in_write_ind = 0;
437,7 → 447,7
i2c_data.slave_in_last_byte = received_data;
i2c_data.return_status = I2C_DATA_AVAL;
} else {
// DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
i2c_data.operating_state = I2C_IDLE;
i2c_data.return_status = I2C_ERR_NODATA;
}
466,7 → 476,7
goto send;
} else {
// Bad to recv an address again, we aren't ready
// DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
DBG_PRINT_I2C("I2C: (ERROR) no data recieved\r\n");
i2c_data.operating_state = I2C_IDLE;
i2c_data.return_status = I2C_ERR_NODATA;
}
503,6 → 513,10
}
}
 
unsigned char I2C_Buffer_Len() {
return i2c_data.buffer_in_len;
}
 
/* Returns 0 if I2C module is currently busy, otherwise returns buffer length */
unsigned char I2C_Read_Buffer(char *buffer) {
unsigned char i = 0;