Hi,
I'm also trying to use I2C but with interrupts, not to freeze the the execution of the main program.
Here is what I do:
But this doesn't work.
What actually happens is that the first transmission is OK but the transmit interrupt flag (MMSR_MMTXIF) keeps getting set even after steps 6 to 10 of the interrupt routine. So the next transmission sees that the "transmission in progress" flag is cleared (OK to transmit) enables the interrupt, the interrupt routine starts and corrupts this transmission.
Also, in the first transmission, there is a glitch (a bitwide pulse) on the data line just before the stop condition due to MSBit set (high) in MMDTR (MMDTR = 0x80). When the MSBit is cleared (low) (MMDTR = 0), the stop condition is not performed (the clock line goes high but the data line stays low). I tried to set MMCR2_MMRW to 1 (read) not to have the glitch but it has the same effect as when the MSBit is cleared.
Then, I tried to disable and re-enable the I2C module (MMCR1_MMEN = 0; MMCR1_MMEN = 1) when the second transmission is initiated but the clock and data lines goes high before the stop condition is even initiated on the bus. I think this is due to the fact that the transmit buffer is free (MMSR_MMTXIF set to high and thus an interrupt is initiated) before the physical transmission is actually finished so it doesn't mean that the I2C module can be disabled at that time. Since I also check that the bus busy flag (MMBB) goes low (stop condition detected) before clearing the "transmission in progress" flag, I thought that, physically, the stop condition has been done but it doesn't seem to be the case.
All my problems seem to revolve around the way I generate the stop condition. Maybe the way I do it isn't the right way to do it. In the documentation, no where is written how to generate a stop condition. The only information given is that when the MMAST bit is cleared by MMNAKIF set (no acknowledge) or by software, the module generates the stop condition to the lines after the current byte is transmitted. And this doesn't really say that setting MMAST to 0 (slave mode) will do a stop condition.
Furthermore, I have to say that my slave device does not know how many bytes is transferred until the transfer finishes (stop condition detected) so it cannot "send" a NAK at the end to tell the master to (automatically) do a stop condition.
Can anyone help me make my communication work properly?
Thanks
DGagnon
Hello HSE,
After a brief perusal of the IIC section of the data sheet, and the manual for the display, I think I can see a couple of problems -
After you have completed sending a number of characters to the display, I believe you may need to clear the MMAST bit.
It would seem the display also provides an RS232 option, with a further option to select TTL levels. In this mode, it should directly interface with the SCI peripheral - as an alternative approach.
Regards,
Mac
Hello Hassane,
My interpretation of the data sheet is that, when the MMCR2_MMAST bit changes from 1 to 0, a STOP sequence is generated at the conclusion of the current byte transmission in progress. However, when this occurs within your code, the last character may still be waiting in the buffer (because two bytes are actually buffered), and will never get transmitted.
The simplest solution may be to send a dummy byte (that will not be transmitted) before zeroing the MMAST bit.
I am not sure of the cause of the "bus hang up" problem.
Regards,
Mac
Hello Hassane,
I suspect that the status of the MMTXIF flag is changes when the current byte completes transmission, and during the returned ACK, but does not take into account a byte waiting for transmission, within the two byte buffer. This would certainly explain what you observe.
I also suspect that the MMTXBE flag becomes set whenever there is room to send another byte to the buffer, not necessarily when the buffer fully empties.
My choice would be to test for MMTXBE = 1 prior to loading MMDTR. The testing of MMTXIF would appear unnecessary, since other measures need to be taken in order to transmit the final byte.
Regards,
Mac
Hello Mac,
Here is the status so far.
I tried the suggestion below, and I ended up in an endless loop. I think the first byte you try to send causes a problem with the MMTXBE = 1 check. I will have to set up 2 different functions to send a byte, one for the first byte, and another for subsequent ones.
I will keep thinking about another way of doing it. This is what i have now, and it seems to work. It will send all bytes and then release the bus. I followed the suggestion to send a dummy byte before ending the communication.
Here is copy of the routines I used:
void StopTXMaster(void){
MMCR2_MMNAKIF=0;
MMCR2_MMAST=0;
}
void LcdSendByte(int Data){
MMDTR=Data;
while (MMSR_MMTXBE==0){};
while (MMSR_MMTXIF==0){};
MMSR_MMTXIF=0;
}
// LcdInit
// Sends initialization data to the LCD.
void LcdInitTX(void) {
LcdClrDisp();
LcdBackLight(0,0);
StartTXMaster();
LcdSendByte(0x31);
LcdSendByte(0x32);
LcdSendByte(0x33);
LcdSendByte(0x34);
LcdSendByte(0x35);
LcdDispStrg("Hello");
}
And in my main, I have the following function calls:
LcdInitTX();
LcdDispStrg(" Hello");
LcdSendByte(ASCII_NULL); --> I put this so I am able to send the last byte in the buffer.
MMCR1_MMEN=0;
This will release the buffer from the master. The last 2 commands, I will put into a function called I2C_Off(), which I will call once I end all slave communications to the LCD. I will create another function will will turn the MMEN byte on for new communication.
Thanks for all your help and input. If I figure out another way of doing it, I will post it for your reference.
Best Regards,
Hassane
Hello HSE,
HSE wrote:
I just started working with the HC08 micros, from the HC12. I am trying to set up the I2C communication for the HC08AP64, without any success so far. All Application notes show the I2C communication using 2 general I/O pins.I am using codewarrier, and coding in C. I have made the I2C routines from scratch and used the device initialization as well, both yielding the same results. I checked the outputs (data and clock) using a scope, and both lines are dead. No output being sent. The module is Enabled.
It is unclear to me whether you are using the I2C periperal module, or you are trying to "bit bang" (with the reference to general I/O).
If the HC12 device is the master, the failure to see a clock signal might indicate a problem with the HC12, rather than the HC08. I presume you have appropriate value pull-up resistors installed.
Regards,
Mac