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);
}

Reply via email to