2024-06-23 08:43 AM - last edited on 2024-07-30 06:31 AM by Andrew Neil
Hello,
I am coming to you because I have a rather difficult issue to identify.
I have a screen mounted on I2C that originally communicates with an Arduino board via its address 0x3C. I have verified that I can communicate with this address using my Nucleo 64 F401RE board.
However, when I look at the frames, I encounter information that doesn't match up. Worse, when I look at what HAL returns, I get a rather strange error that I would like to submit to you.
In order:
Here is a piece of code in C:
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "i2c.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h" // sprintf()
#include "stdbool.h" // boolean
/* USER CODE END Includes */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define DELAY_MAN 500
#define ADDRESSE_ECRAN 0x3C
#define NB_COLONNES 16
#define NB_LINES 2
/* USER CODE END PD */
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void RW1063_send_command(uint8_t command);
void RW1063_show_cursor();
void RW1063_hide_cursor();
void RW1063_blink_cursor();
void RW1063_no_blink_cursor();
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C1_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
RW1063_send_command(0x38); // 8-bit mode, 2 lines, 5x8 characters
HAL_Delay(1);
RW1063_send_command(0x0C); // Turn on the screen, disable cursor and blinking
HAL_Delay(1);
RW1063_send_command(0x01); // Clear the screen
HAL_Delay(10);
RW1063_send_command(0x06); // Move the cursor to the right after each character
HAL_Delay(1);
RW1063_show_cursor();
HAL_Delay(500);
RW1063_hide_cursor();
HAL_Delay(500);
RW1063_show_cursor();
RW1063_blink_cursor();
HAL_Delay(2000);
RW1063_no_blink_cursor();
HAL_Delay(500);
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
}
}
void RW1063_send_command(uint8_t command) {
HAL_StatusTypeDef res;
uint16_t size_buff = 2;
uint8_t tbl_command[size_buff];
tbl_command[0] = 0x00;
tbl_command[1] = command;
res = HAL_I2C_Master_Transmit(&hi2c1, ADDRESSE_ECRAN << 1, tbl_command, size_buff, HAL_MAX_DELAY);
if(res != HAL_OK) {
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
while(1);
}
}
void RW1063_show_cursor() {
RW1063_send_command(0x0E);
}
void RW1063_hide_cursor() {
RW1063_send_command(0x0C);
}
void RW1063_blink_cursor() {
RW1063_send_command(0x0F);
}
void RW1063_no_blink_cursor() {
RW1063_send_command(0x0C);
}
I am also attaching images to illustrate the frames and errors encountered.
Thank you in advance for your help!
2024-06-23 09:33 AM
HAL_I2C_ERROR_AF (4)
ACK failure from the device
Might look at how you have this wired up, the pull-ups, the timing. Anything else on the bus it might be interacting with?
Is this on some board / module? Like to a shop or Amazon, in case someone is working with a similar part.
Can you clear the error and retry? Sitting in a while loop won't get resolution, but suppose the GPIO here is used as a trigger for the logic analyzer so you can inspect / review the specific failure.
2024-06-23 09:41 AM
The hardware works, the pull-up resistors are phisically present.
However, I have serious doubts about how the code works. This is all the more true since the screen is the only one connected to the bus.
There is nothing Amazon here. A STM32 and a Screen obtained from Farnell.
Any other leads yet?
2024-06-23 11:28 AM
May be you can give a delay of 100ms before the fist command is send to the display, as per the document it says, it takes 40ms after the power supply stabilizes you have to send the command to set the interface function.
2024-06-23 11:51 AM
The decode of the general frame in the logic analyzer isn't at all helpful.
Should have the 0xE0 slave address, 0x00, 0x38
RW1063_send_command(0x38); // 8-bit mode, 2 lines, 5x8 characters
2024-06-23 01:43 PM
I’m trying to understand. 0xE0 is supposed to contain 0x00 + 0x38 -> but then, is it the HAL that combines the two pieces of information? Is it one address per pointer?
You’re completely losing me with your answer.
2024-06-23 04:09 PM
The STM32 is missing an ACK. The HAL_I2C_Master_Transmit() looks fine, shouldn't need delays, display might.
Well the issue is going to be easier to solve if your logic analyzer output (protocol parsing) actually reflected what the signals indicated.
And then you associated the faulting GPIO on the same time line.
You've identified a make/model of controller IC, not a specific display, or link to a display on Farnell.
I don't see how it's wired, not the pull-up values / configuration strapping.
2024-06-24 03:12 AM
Good morning,
Thank you for that answer. I started by doubting the hardware, as you do. The steps I followed to conclude on a different problem from the hard are:
- Disconnect the display and both resistors (real and physical connected)
- Reconnect the screen with its resistors to another µC for which I already have a code that works.
- Check focus. Answer, it is working properly.
- Reconnect the screen to the Nucleo. Launch the code. But AL answers error 4.
Farnell.com > mc21605c6w-sptlyi-v2 : afficheur-alphanumerique-16x2
Datasheets .pdf
From datasheet : * - For full design functionality, please use this specification in conjunction with the RW1063 specification. (Provided Separately)
2024-06-24 04:51 AM
check the documentation of your STM32 board to ensure that you are using the correct pins and those signals are routed to the place where you are connecting the display. If possible try to test with another i2c device to make sure that the I2c bus of the STM32 is working as expected. Are the pull up resistors connected to processor VCC? What is the operating voltage of the Display, if there is a mismatch or not?
you can try this aswell
https://deepbluembedded.com/stm32-i2c-scanner-hal-code-example/
2024-06-24 11:05 AM
Thank you very much.
Thank you for the link. Very interesting.
My signal is well routed, since we see it appear with a SCL and a SDA with pinoches configured by cubeMX.
The screen has already worked under STM, but not in a correct and durable way. I didn’t know what error 4 was. Go back to the subject to see the images I posted. It will speak, much more than all my writings.
In essence, I put the minimum code, I focus on this part to learn more about the HAL. And really, with all your answers, I feel like no one really knows!
Ultimately, what is missing is a cair array of HAL errors, and probably a warning in cubeMX when the configuration is wrong. In addition it compiles without error in me, so even the compiler agrees and does not see any error. Also, I suppose the HAL is doing its job, but is it doing it right?