I modified the size of the buffer you mentionned, it allowed me to
implement bigger programs on the PIC. Thanks for that information!
I also modified the state machine and now I'm able to make a continuous
read operation on the same register. My problem is that the value I read is
always the same (as I try to read audio data, it should change at every
read operation). I think this is linked with the interruption trigger. Is
it possible to read continuously a signal while staying in the
MI2CInterrupt function? When exactly are the interrupts triggered?
You will find the modified functions attached.
Léopold
--
You received this message because you are subscribed to the Google Groups
"ioio-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/ioio-users.
For more options, visit https://groups.google.com/d/optout.
FSFILE *pNewFile3;
char newFile3[]= "write.txt";
int bytesWritten3;
char *writearg3 = "a";
unsigned char psdbuff_ptr[4];
unsigned int d;
int indice = 0;
int flag = 0;
BOOL flag_read = 0;
BOOL flag_write = 0;
BYTE b;
BYTE c;
void I2CWriteRead(int i2c_num, unsigned int addr, const void* data,
int write_bytes, int read_bytes) {
I2C_STATE* i2c = i2c_states + i2c_num;
TX_MESSAGE_HEADER hdr;
BYTE prev;
if(read_bytes != 0){
flag_read = 1;
}
log_printf("I2CWriteRead(%d, 0x%x, 0x%p, %d, %d)", i2c_num, addr,
data, write_bytes, read_bytes);
hdr.addr = addr; // update header with I2C device address K.
hdr.write_size = write_bytes; // # of bytes to write K.
hdr.read_size = read_bytes; // # of bytes to read K.
prev = SyncInterruptLevel(4);
ByteQueuePushBuffer(&i2c->tx_queue, &hdr, sizeof hdr);
ByteQueuePushBuffer(&i2c->tx_queue, data, write_bytes);
Set_MI2CIE[i2c_num](1); // enable interrupt K.
SyncInterruptLevel(prev);
}
static void MI2CInterrupt(int i2c_num) {
I2C_STATE* i2c = i2c_states + i2c_num;
volatile I2CREG* reg = i2c_reg[i2c_num];
Set_MI2CIF[i2c_num](0); // clear interrupt
switch (i2c->message_state) {
case STATE_START:
if(flag_read == 0){
ByteQueuePullToBuffer(&i2c->tx_queue, &i2c->cur_tx_header,
sizeof(TX_MESSAGE_HEADER));
i2c->num_tx_since_last_report += sizeof(TX_MESSAGE_HEADER);
}
if((flag_read == 1)&(flag == 0)){
ByteQueuePullToBuffer(&i2c->tx_queue, &i2c->cur_tx_header,
sizeof(TX_MESSAGE_HEADER));
i2c->num_tx_since_last_report += sizeof(TX_MESSAGE_HEADER);
flag =1;
log_printf("(flag_read == %d)&(flag == %d)", flag_read, flag);
}
//i2c->num_tx_since_last_report += sizeof(TX_MESSAGE_HEADER);
i2c->bytes_remaining = i2c->cur_tx_header.write_size;
reg->con |= 0x0001; // send start bit
log_printf("I2C Send Start Bit");
if (i2c->bytes_remaining) { // if there are bytes left to transmit then send them otherwise read
i2c->message_state = STATE_ADDR1_WRITE;
} else {
i2c->message_state = STATE_ADDR_READ;
}
break;
case STATE_ADDR1_WRITE:
reg->trn = i2c->cur_tx_header.addr1;
log_printf("Write ADDR1: 0x%x", i2c->cur_tx_header.addr1);
if (i2c->cur_tx_header.addr1 >> 3 == 0b00011110) {
i2c->message_state = STATE_ADDR2_WRITE;
} else {
i2c->message_state = STATE_WRITE_DATA;
}
break;
case STATE_ADDR2_WRITE:
if (reg->stat >> 15) goto error;
reg->trn = i2c->cur_tx_header.addr2;
log_printf("Write ADDR2: %d", i2c->cur_tx_header.addr2);
i2c->message_state = STATE_WRITE_DATA;
break;
case STATE_WRITE_DATA: // Actual Data writing!
if (reg->stat >> 15){
log_printf("error STATE_WRITE_DATA");
goto error;
}
log_printf("flag read=%d flag=%d flag_write=%d", flag_read, flag, flag_write);
if((flag_read == 0)|(flag == 1)){
b = ByteQueuePullByte(&i2c->tx_queue);
if((flag_read == 1)&(flag == 1)){
flag = 2;
c = ByteQueuePullByte(&i2c->tx_queue);
}
}
if (flag_read == 0){
reg->trn = b;
log_printf("Write DATA: b=0x%x", b);
}
else {
if(flag_write == 0){
flag_write = 1;
reg->trn = b;
log_printf("Write DATA: b=0x%x", b);
}
else{
flag_write = 0;
reg->trn = c;
log_printf("Write DATA: c=0x%x", c);
}
}
++i2c->num_tx_since_last_report; // increment tx count
if (--i2c->bytes_remaining == 0 ) {
i2c->message_state = i2c->cur_tx_header.read_size // was it write only or restart transmission? K.
? STATE_RESTART
: STATE_STOP_WRITE_ONLY;
}
break;
case STATE_STOP_WRITE_ONLY:
if (reg->stat >> 15) { goto error; }
log_printf("STATE_STOP_WRITE_ONLY");
goto done;
case STATE_RESTART:
reg->con |= 0x0002; // send restart
log_printf("STATE_RESTART");
i2c->message_state = STATE_ADDR_READ;
break;
case STATE_ADDR_READ:
log_printf("STATE_ADDR_READ: 0x%x", i2c->cur_tx_header.addr1);
reg->trn = i2c->cur_tx_header.addr1 | 0x01; // read address, what addy to read K.
i2c->message_state = STATE_ACK_ADDR_READ;
break;
case STATE_ACK_ADDR_READ:
log_printf("STATE_ACK_ADDR_READ");
if (reg->stat >> 15) goto error;
// from now on, we can no longer fail.
i2c->bytes_remaining = i2c->cur_tx_header.read_size;
//ByteQueuePushByte(&i2c->rx_queue, i2c->cur_tx_header.read_size);
reg->con |= 0x0008; // RCEN
i2c->message_state = STATE_READ_DATA;
break;
case STATE_READ_DATA:
//ByteQueuePushByte(&i2c->rx_queue, reg->rcv);
//g = ByteQueuePullByte(&i2c->rx_queue);
reg->con &= ~(1 << 5); // reset ack state
reg->con |= (1 << 4)
| (i2c->bytes_remaining == 1) << 5; // nack last byte
i2c->message_state = STATE_ACK_READ_DATA;
d = reg->rcv;
psdbuff_ptr[indice] = (unsigned char) d; //Data storage in a 4 elements array
indice++;
break;
case STATE_ACK_READ_DATA:
log_printf("STATE_ACK_READ_DATA");
if (--i2c->bytes_remaining == 0) {
log_printf("psdbuff_ptr[0]=0x%x psdbuff_ptr[1]=0x%x psdbuff_ptr[2]=0x%x psdbuff_ptr[3]=0x%x", psdbuff_ptr[0], psdbuff_ptr[1], psdbuff_ptr[2], psdbuff_ptr[3]);
pNewFile3 = FSfopen (newFile3, writearg3); //
bytesWritten3 = FSfwrite ((void *) psdbuff_ptr, 1, 4, pNewFile3); // Write the 4 bytes to the SD card
log_printf("STATE_READ_DATA AND WRITE TO SD. BytesWritten: %d", bytesWritten3); //
FSfclose(pNewFile3); //
indice = 0;
Set_MI2CIE[i2c_num](1);
reg->con |= 0x0008; // RCEN
i2c->message_state = STATE_START;
//goto done;
} else {
reg->con |= 0x0008; // RCEN
i2c->message_state = STATE_READ_DATA;
}
break;
}
return;
error:
log_printf("I2C error");
// pull remainder of tx message
ByteQueuePull(&i2c->tx_queue, i2c->bytes_remaining);
i2c->num_tx_since_last_report += i2c->bytes_remaining;
// ByteQueuePushByte(&i2c->rx_queue, 0xFF);
done:
++i2c->num_messages_rx_queue;
reg->con |= (1 << 2); // send stop bit
i2c->message_state = STATE_START;
Set_MI2CIE[i2c_num](ByteQueueSize(&i2c->tx_queue) > 0);
}