Other Parts Discussed in Thread: HALCOGEN
Hi there,
I am looking for a sample code for transmitting to and receiving from a slave device based on the API generated by Halcogen. Below is my first draft. Note that this is assuming that the wiring and hardware are working as intended thus no error catching.
/* In high level driver */ IO_I2C_ret_E IO_I2C_transceive(const uint8_t * txBuffer, const uint16_t txLength, const uint8_t * rxBuffer, const uint16_t rxLength) { IO_I2C_ret_E ret = IO_I2C_RET_ERROR; /* Set direction to Transmitter */ i2cSetDirection(i2cREG1, I2C_TRANSMITTER); /* Configure Data count */ i2cSetCount(i2cREG1, (uint32_t) txLength); /* Configure address of Slave to talk to */ i2cSetSlaveAdd(i2cREG1, Slave_Add); /* Start transmit*/ IO_I2C_semaphoneTake(); // take semaphore to be returned by isr i2cSetStart(i2cREG1); // Start the transmission: /* send data */ IO_I2C_semaphoneTake(); // take semaphore to be returned by isr i2cSend(i2cREG1, (uint32_t) txLength, txBuffer); if (rxLength > 0) { /* Set direction to Transmitter */ i2cSetDirection(i2cREG1, I2C_RECEIVER); /* Configure Data count */ i2cSetCount(i2cREG1, (uint32_t) rxLength); /* Start transmit*/ IO_I2C_semaphoneTake(); // take semaphore to be returned by isr i2cSetStart(i2cREG1); // Start the transmission: /* receive data */ IO_I2C_semaphoneTake(); // take semaphore to be returned by isr i2cSend(i2cREG1, (uint32_t) rxLength, rxBuffer); } /* set stop */ i2cSetStop(i2cREG1); ret = IO_I2C_RET_SUCCESS; return ret; } /* In Halcogen generated notification.c */ #pragma WEAK(i2cNotification) void i2cNotification(i2cBASE_t *i2c, uint32 flags) { /* enter user code between the USER CODE BEGIN and USER CODE END. */ /* USER CODE BEGIN (21) */ if( (i2cREG1 == i2c)) { IO_I2C_semaphoreGive(); } /* USER CODE END */ }
If there is a reference code similar to this that I can refer to, that would be great. Also below is the list of my questions:
Q1: In another thread in the forum, your Guru mentioned that i32cSetStart() will send #1 start condition, #2 slave device address, and #3 R/W bit. Is it still true?
Q2: Does i32cSetStart() also operates in interrupt mode? Meaning does the function returns immediately, and generates an interrupt when slave address is transmitted?
Q3: In i2cSend() and i2cReceive(), which I will refer them as the API functions, there is implementation for using interrupt. In the interrupt implementation, it uses a static structure g_i2cTransfer_t to hold the data pointer and length. However the API functions only assigns the initial value to the structure and exit, but I don't see any code that loop through it, nor the API functions being called in the interrupt notification. Am I missing anything? Or is there a DMA mechanism that automagically handles multi byte read / right, such that a call as below:
i2cSend(i2cREG1, 10, &data);
will result 1 call to i2cNotification() AFTER all 10 bytes are transmitted?