glc-24064 I2C lockout!!
glc-24064 I2C lockout!!
I seem to have the nack (no pun intended) of receiving nacks on the I2C bus! I can't seem to send any commands without receiving a nack on at least one byte. however, i can't seem to communicate with the device unless i cycle the power supply.
Can anyone tell me how to regain communication with the display even if i do not know the last command that was not completed?
Im new to this dislay and it is causing me lots of headaches! I've spent at least 2 weeks trying to reliably communicate over the I2C bus.
any help would be greatly appreciated
Can anyone tell me how to regain communication with the display even if i do not know the last command that was not completed?
Im new to this dislay and it is causing me lots of headaches! I've spent at least 2 weeks trying to reliably communicate over the I2C bus.
any help would be greatly appreciated
These are two of the functions that i use to manipulate the backlight. it got complicated when i decided to check for acks after each byte was transmitted.
void LCD_backlight_on(int state, int on_duration){
int ack = false;
setup_flow_ctrl(); //start hardware timer - 40ms to complete transaction
while(!ack){
hail_LCD_display();
ack = !(i2c_write(LCD));
if(state==true) {
ack = ack | !(i2c_write(backlight_on));
ack = ack | !(i2c_write(on_duration));
}
else
ack = ack | !(i2c_write(backlight_off));
if (!ack)
delay_ms(1); //wait for device to get ready
}
stop_flow(); //kill hardware timer
}
void hail_LCD_display(){
int ack = false;
while(!ack){
i2c_start();
if (!i2c_write(LCD_address))
ack = true; //ack received
else {
i2c_start();
i2c_stop();
delay_ms(1);
}
}
}
basically, i repeat the entire command if i ever receive a nack. is this advisable?
ps. the setup_flow_ctrl() and stop_flow() functions start and stop a hardware timer in the PIC18F452. an LED is lit and the PIC goes to sleep if the timer overflows during transmission.
void LCD_backlight_on(int state, int on_duration){
int ack = false;
setup_flow_ctrl(); //start hardware timer - 40ms to complete transaction
while(!ack){
hail_LCD_display();
ack = !(i2c_write(LCD));
if(state==true) {
ack = ack | !(i2c_write(backlight_on));
ack = ack | !(i2c_write(on_duration));
}
else
ack = ack | !(i2c_write(backlight_off));
if (!ack)
delay_ms(1); //wait for device to get ready
}
stop_flow(); //kill hardware timer
}
void hail_LCD_display(){
int ack = false;
while(!ack){
i2c_start();
if (!i2c_write(LCD_address))
ack = true; //ack received
else {
i2c_start();
i2c_stop();
delay_ms(1);
}
}
}
basically, i repeat the entire command if i ever receive a nack. is this advisable?
ps. the setup_flow_ctrl() and stop_flow() functions start and stop a hardware timer in the PIC18F452. an LED is lit and the PIC goes to sleep if the timer overflows during transmission.
documentation
I've been reading a couple of posts that have dealt with the I2C communication. You (the techs from matrix orbital) insist on directing everyone to section 2.2.3 in the manual. My English is not the clearest, however, I don't think this section is the clearest of descriptions of the shortcoming of the I2C implementation.
The first three sentences are very ambiguous. The passage is also riddled with poor English, bad sentence construction and typographical errors. For a spec sheet - this is asking for confusion.
Two of the sentences that actually make sense are deeply embedded in this passage. “They (the displays) are only capable of failing to acknowledge the bytes following the byte, which was not received” and “Basically the reason why a Matrix Orbital module might fail to receive a byte correctly is that it was unable to process the byte previous before the failed byte was transmitted.”
I don’t think the passage is clear as to how NOT to deal with ACK. This is not meant to disrespect but as constructive criticism. I hope you could clarify your documentation so that other users would not have any questions about communication using the I2C interface.
Also, it does not outline the procedure that must be taken to regain control of the display in case a user was not keeping track of the first NACK.
I hope you could help me clarify some of these issues.
Again, I am sorry about my tone but I've been hitting my head trying to design a robust I2C comm interface but with little success.
The first three sentences are very ambiguous. The passage is also riddled with poor English, bad sentence construction and typographical errors. For a spec sheet - this is asking for confusion.
Two of the sentences that actually make sense are deeply embedded in this passage. “They (the displays) are only capable of failing to acknowledge the bytes following the byte, which was not received” and “Basically the reason why a Matrix Orbital module might fail to receive a byte correctly is that it was unable to process the byte previous before the failed byte was transmitted.”
I don’t think the passage is clear as to how NOT to deal with ACK. This is not meant to disrespect but as constructive criticism. I hope you could clarify your documentation so that other users would not have any questions about communication using the I2C interface.
Also, it does not outline the procedure that must be taken to regain control of the display in case a user was not keeping track of the first NACK.
I hope you could help me clarify some of these issues.
Again, I am sorry about my tone but I've been hitting my head trying to design a robust I2C comm interface but with little success.
I aplogize for the confusing section on how our units correspond with the I2C protocol. The basic idea is that our displays always ACK, so there is no need to ACK. The problem is that our devices cannot NACK because of the way the data is handled. There is basically two ways data can be "damaged", either by interference (grounding type issues) or the buffer is full and data gets corrupted. We cannot know that data is incorrectly sent. This is something that may be updated in the near future!
Miles Y.
Head of Technical Support
Product Manager
Matrix Orbital
Head of Technical Support
Product Manager
Matrix Orbital
The two GLC24064 displays that i purchased both send NACKs (most likely) when data was sent too quickly.
just to be clear, the NACK or ACK is sent by the display (the slave) and not the PIC (master) - that is another reason section 2.2.3 is not clear.
The display does not implement flow control on the I2C bus. A problem could therefore arise where the master sends too many commands to the display. In my case, the display does respond with NACK to bytes and therefore can disregard subsequent bytes of a command.
My question is - How do i deal with the retransmission of the ignored bytes so that I do not corrupt the commands to the display granted the electrical connection is sound?
I guess im going to try to follow the display's data sheet after all. I will retransmit the byte to which a NACK was received until an ACK is received. this would also be done without any start and stop bit being issued unlike the method i posted earlier.
I will tell you how it goes.
just to be clear, the NACK or ACK is sent by the display (the slave) and not the PIC (master) - that is another reason section 2.2.3 is not clear.
The display does not implement flow control on the I2C bus. A problem could therefore arise where the master sends too many commands to the display. In my case, the display does respond with NACK to bytes and therefore can disregard subsequent bytes of a command.
My question is - How do i deal with the retransmission of the ignored bytes so that I do not corrupt the commands to the display granted the electrical connection is sound?
I guess im going to try to follow the display's data sheet after all. I will retransmit the byte to which a NACK was received until an ACK is received. this would also be done without any start and stop bit being issued unlike the method i posted earlier.
I will tell you how it goes.
some working code for the masses!
OK! after 6 days of ponderation and deliberation about the true meaning of that criptic passage ala section 2.2.3 of our spec sheets.
Im posting some of my code that seems to be working for the sake of contributing to the wealth of knowledge at this forum. The code seems to be working fine. I can say that the reliability is definitely higher than before since I also started some higher-level graphic design.
I will include some diagnostic code to count the number re-transmissioned bytes but for now, you can take my word for it....
The code ...
Im am using PICC C. I have left out all the supporting functions but the general idea is ilustrated.
Basically, the code transmits a new byte (data) ONLY if the previous byte (temp) was acknowledged. If the previous byte (temp) was not acknowledged (NACK) then that byte is retransmitted until an ACK is received. A timer (set by setup_flow_ctrl()) would generate an interrupt after approximately 40ms if no ACK is ever received.
void tx_LCD_cmd()
{
int data, temp, ack;
//co-ordinate the poping of the FIFO and checking for NACKs
// if NACK occurs the system loops until ACK is received!!
// else the hardware timer1 will timeout indicating the error
// entering this function assumes that the last_byte was ACKed
setup_flow_ctrl();
while(!LCD_tx_buf_isempty()) // loop while FIFO has data
{
data = *LCD_tx_buf_pop(); //get new data to by tx;
if (!i2c_write(data)) //store temporary data for NACK
{
ack = true;
temp = data;
}
else
ack = false;
while (!ack)
{
delay_ms(3);
ack = !i2c_write(temp);
}
}
stop_flow();
}
Im posting some of my code that seems to be working for the sake of contributing to the wealth of knowledge at this forum. The code seems to be working fine. I can say that the reliability is definitely higher than before since I also started some higher-level graphic design.
I will include some diagnostic code to count the number re-transmissioned bytes but for now, you can take my word for it....
The code ...
Im am using PICC C. I have left out all the supporting functions but the general idea is ilustrated.
Basically, the code transmits a new byte (data) ONLY if the previous byte (temp) was acknowledged. If the previous byte (temp) was not acknowledged (NACK) then that byte is retransmitted until an ACK is received. A timer (set by setup_flow_ctrl()) would generate an interrupt after approximately 40ms if no ACK is ever received.
void tx_LCD_cmd()
{
int data, temp, ack;
//co-ordinate the poping of the FIFO and checking for NACKs
// if NACK occurs the system loops until ACK is received!!
// else the hardware timer1 will timeout indicating the error
// entering this function assumes that the last_byte was ACKed
setup_flow_ctrl();
while(!LCD_tx_buf_isempty()) // loop while FIFO has data
{
data = *LCD_tx_buf_pop(); //get new data to by tx;
if (!i2c_write(data)) //store temporary data for NACK
{
ack = true;
temp = data;
}
else
ack = false;
while (!ack)
{
delay_ms(3);
ack = !i2c_write(temp);
}
}
stop_flow();
}
some missing details ...
I forgot to mention ... I am running the PIC 18F452 with a 4MHz clock and soon to be 40MHz. I do not use any delays within the code to try to slow the transmission of data.
One suggestion - An even more efficient implementation can use ISRs to supervise the transmission of the data bytes if an application is intended for real-time. This would allow other tasks to be accomplished while data is being transmitted (at whatever rate).
One suggestion - An even more efficient implementation can use ISRs to supervise the transmission of the data bytes if an application is intended for real-time. This would allow other tasks to be accomplished while data is being transmitted (at whatever rate).
I appreciate all your posts!! As you can understand the magnitude of applications and the environments our displays are being used in. I am as well learning something new everyday!! With each application requiring something different, it's always a learning process!! 

Miles Y.
Head of Technical Support
Product Manager
Matrix Orbital
Head of Technical Support
Product Manager
Matrix Orbital