Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

help stm32f05, ST7565 nhdc12864 #668

Closed
gustavolyra opened this issue Jul 31, 2018 · 16 comments
Closed

help stm32f05, ST7565 nhdc12864 #668

gustavolyra opened this issue Jul 31, 2018 · 16 comments
Labels

Comments

@gustavolyra
Copy link

gustavolyra commented Jul 31, 2018

Hello,
it's my first time using u8g2 and I want to use the stm32f05 board. My display is a nhdc 128x64, ST7565.
I did the setup from #179 and #356, it should show a line but so far nothing happens.

my code:

//------------------------
//includes
#include "u8g2.h" #include "u8x8.h" //LCD 128x64 u8g2_t u8g2; uint8_t count = 0; uint8_t lcd_refresh_time = 1; char string_1[30];`

//------------------------------------------------------
//init and loop
`u8g2_Setup_st7565_nhd_c12864_2(&u8g2, U8G2_R0, u8x8_byte_4wire_hw_spi, u8g2_gpio_and_delay_stm32); // init u8g2 structure
u8g2_InitDisplay(&u8g2); // send init sequence to the display, display is in sleep mode after this,
u8g2_SetPowerSave(&u8g2, 0); // wake up display
u8g2_SetContrast(&u8g2, 250);
u8g2_SendBuffer(&u8g2);
HAL_Delay(100);
/* USER CODE END 2 */

/* Infinite loop /
/
USER CODE BEGIN WHILE */
while (1)
{
u8g2_DrawLine(&u8g2, 20, 5, 5, 32);
}`

//-------------------------------------
`uint8_t u8x8_byte_4wire_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
uint8_t i, b;
uint8_t *data;
uint8_t takeover_edge = u8x8_GetSPIClockPhase(u8x8);
uint8_t not_takeover_edge = 1 - takeover_edge;

switch(msg)
{
case U8X8_MSG_BYTE_SEND:
data = (uint8_t *)arg_ptr;
while( arg_int > 0 ){
b = *data;
data++;
arg_int--;
for( i = 0; i < 8; i++ ){
if ( b & 128 )
u8x8_gpio_SetSPIData(u8x8, 1);
else
u8x8_gpio_SetSPIData(u8x8, 0);
b <<= 1;

				u8x8_gpio_SetSPIClock(u8x8, not_takeover_edge);
				u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sda_setup_time_ns);
				u8x8_gpio_SetSPIClock(u8x8, takeover_edge);
				u8x8_gpio_Delay(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->sck_pulse_width_ns);
			}    
  }
  break;
		
case U8X8_MSG_BYTE_START_TRANSFER:
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET);
  __nop(); // 21 ns
  break;
	
case U8X8_MSG_BYTE_END_TRANSFER:
  __nop(); // 21 ns
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET);
  break;
	
	case U8X8_MSG_BYTE_SET_DC:
		if (arg_int) HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
		else HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
	break;

default:
  return 0;

}
return 1;
}`

//--------------------------------------------------------
`uint8_t u8g2_gpio_and_delay_stm32(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr){
switch(msg)
{
case U8X8_MSG_GPIO_AND_DELAY_INIT: // called once during init phase of u8g2/u8x8
break; // can be used to setup pins

case U8X8_MSG_DELAY_NANO:			// delay arg_int * 1 nano second
  break;    

case U8X8_MSG_DELAY_100NANO:		// delay arg_int * 100 nano seconds
  __NOP();
  break;
  
case U8X8_MSG_DELAY_10MICRO:		// delay arg_int * 10 micro seconds
  HAL_Delay(10);
  break;
  
case U8X8_MSG_DELAY_MILLI:			// delay arg_int * 1 milli second
  HAL_Delay(arg_int);
  break;
  
case U8X8_MSG_DELAY_I2C:				// arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHz
  break;		  						// arg_int=1: delay by 5us, arg_int = 4: delay by 1.25us
  
//case U8X8_MSG_GPIO_D0:				// D0 or SPI clock pin: Output level in arg_int
case U8X8_MSG_GPIO_SPI_CLOCK:
	if (arg_int)  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
	else HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
  break;
  
//case U8X8_MSG_GPIO_D1:				// D1 or SPI data pin: Output level in arg_int
case U8X8_MSG_GPIO_SPI_DATA:
	if (arg_int)  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
	else HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
  break;
  	  
case U8X8_MSG_GPIO_D2:				// D2 pin: Output level in arg_int
  if (arg_int)  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);
	else HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
  break;
  
case U8X8_MSG_GPIO_D3:				// D3 pin: Output level in arg_int
  if (arg_int)  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_SET);
	else HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_RESET);
  break;
  
case U8X8_MSG_GPIO_D4:				// D4 pin: Output level in arg_int
   if (arg_int)  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
	else HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
  break;
  
case U8X8_MSG_GPIO_D5:				// D5 pin: Output level in arg_int
  if (arg_int)  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET);
	else HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET);
  break;
  
case U8X8_MSG_GPIO_D6:				// D6 pin: Output level in arg_int
   if (arg_int)  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET);
	else HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET);
  break;
  
case U8X8_MSG_GPIO_D7:				// D7 pin: Output level in arg_int
  if (arg_int)  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_SET);
	else HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_RESET);
  break;
  
case U8X8_MSG_GPIO_E:				// E/WR pin: Output level in arg_int
  if (arg_int)  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
	else HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
  break;
  
case U8X8_MSG_GPIO_CS:				// CS (chip select) pin: Output level in arg_int
  if (arg_int)  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET);
	else HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET);
  break;
  
case U8X8_MSG_GPIO_DC:				// DC (data/cmd, A0, register select) pin: Output level in arg_int
  if (arg_int)  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
	else HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
  break;
  
case U8X8_MSG_GPIO_RESET:			// Reset pin: Output level in arg_int
  if (arg_int)  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
	else HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);
  break;
  
case U8X8_MSG_GPIO_CS1:				// CS1 (chip select) pin: Output level in arg_int
  break;
  
case U8X8_MSG_GPIO_CS2:				// CS2 (chip select) pin: Output level in arg_int
  break;
  
case U8X8_MSG_GPIO_I2C_CLOCK:		// arg_int=0: Output low at I2C clock pin
  break;
  // arg_int=1: Input dir with pullup high for I2C clock pin
case U8X8_MSG_GPIO_I2C_DATA:			// arg_int=0: Output low at I2C data pin
  break;	
  // arg_int=1: Input dir with pullup high for I2C data pin
case U8X8_MSG_GPIO_MENU_SELECT:
  u8x8_SetGPIOResult(u8x8, /* get menu select pin state */ 0);
  break;
  
case U8X8_MSG_GPIO_MENU_NEXT:
  u8x8_SetGPIOResult(u8x8, /* get menu next pin state */ 0);
  break;
  
case U8X8_MSG_GPIO_MENU_PREV:
  u8x8_SetGPIOResult(u8x8, /* get menu prev pin state */ 0);
  break;
  
case U8X8_MSG_GPIO_MENU_HOME:
  u8x8_SetGPIOResult(u8x8, /* get menu home pin state */ 0);
  break;
  
default:
  u8x8_SetGPIOResult(u8x8, 1);			// default return value
  break;

}
return 1; // command processed successfully.
}`

@olikraus
Copy link
Owner

Your byte function seems to be a copy of the u8g2 sw spi function. Maybe you should start with the existing sw spi function just to see whether this works. It is also a good idea to check whether you can see activity on the SPI pins.

@RonTheBestKingInTheWorld
Copy link

RonTheBestKingInTheWorld commented Aug 17, 2018

Hi, I'm having similiar problem.
I'm using STM32 (STM32L433RCTxP) with HAL library and workspace from Eclipse and I'm trying to implement u8g2 for the 1.54inch e-ink display.
I've already went through the #117 and #356 same as @gustavolyra.
For the following code I get such errors:

_- Description Resource Path Location Type

  • make: *** [U8G2_ALL_GPIOS_att.elf] Error 1 U8G2_ALL_GPIOS_att C/C++ Problem
  • recipe for target 'U8G2_ALL_GPIOS_att.elf' failed makefile /U8G2_ALL_GPIOS_att/Debug line 37 C/C++ Problem
  • region `RAM' overflowed by 48072 bytes U8G2_ALL_GPIOS_att C/C++ Problem
  • U8G2_ALL_GPIOS_att.elf section .bss' will not fit in region RAM' U8G2_ALL_GPIOS_att C/C++ Problem_

The RAM memory is being exceeded. I don't know why. I know that similiar problem was mentioned in the #179 and there was some buffer introduced in order to solve this issue but I don't get that solution.

Could you give me any hint what am I doing wrong?

Code:

#include "main.h"
#include "stm32l4xx_hal.h"
#include "u8g2.h"
#include "u8x8.h"

u8g2_t u8g2;
//static uint8_t buf[1920];
uint8_t lcd_refresh_time = 1; 
char string_1[30];


void SystemClock_Config(void);
static void MX_GPIO_Init(void);
void init();
uint8_t u8g2_gpio_and_delay_stm32(U8X8_UNUSED u8x8_t *u8x8,
	U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int,
		U8X8_UNUSED void *arg_ptr);

int main(void) {
	init();

	while (1) {
		u8g2_DrawLine(&u8g2, 20, 5, 5, 32);
	}

}

void init() {
	HAL_Init();
	SystemClock_Config();
	MX_GPIO_Init();

	u8g2_Setup_ssd1607_gd_200x200_2(&u8g2, U8G2_R0, u8x8_byte_4wire_sw_spi,
			u8g2_gpio_and_delay_stm32);
	u8g2_InitDisplay(&u8g2);
	u8g2_SetPowerSave(&u8g2, 0);
	u8g2_SendBuffer(&u8g2);
	HAL_Delay(100);
}

void SystemClock_Config(void) {...}
static void MX_GPIO_Init(void) {...}
void _Error_Handler(char *file, int line) {...}


uint8_t u8g2_gpio_and_delay_stm32(U8X8_UNUSED u8x8_t *u8x8,
U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int,
U8X8_UNUSED void *arg_ptr) {
	switch (msg) {
//Initialize SPI peripheral
	case U8X8_MSG_GPIO_AND_DELAY_INIT:
		break;

		//Function which implements a delay, arg_int contains the amount of ms
	case U8X8_MSG_DELAY_MILLI:
		HAL_Delay(arg_int);
		break;

		/*
		 //Function which delays 10us
		 case U8X8_MSG_DELAY_10MICRO:
		 for (uint16_t n = 0; n < 320; n++) {
		 __NOP();
		 }
		 break;


		 //Function which delays 100ns
		 case U8X8_MSG_DELAY_100NANO:
		 __NOP();
		 break;

		 */

		//Function to define the logic level of the clockline
	case U8X8_MSG_GPIO_SPI_CLOCK:
		if (arg_int)
			HAL_GPIO_WritePin(SCK_GPIO_Port, SCK_Pin, SET);
		else
			HAL_GPIO_WritePin(SCK_GPIO_Port, SCK_Pin, RESET);
		break;

		//Function to define the logic level of the data line to the display
	case U8X8_MSG_GPIO_SPI_DATA:
		if (arg_int)
			HAL_GPIO_WritePin(MOSI_GPIO_Port, MOSI_Pin, SET);
		else
			HAL_GPIO_WritePin(MOSI_GPIO_Port, MOSI_Pin, RESET);
		break;

		// Function to define the logic level of the CS line
	case U8X8_MSG_GPIO_CS:
		if (arg_int)
			HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, SET);
		else
			HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, RESET);
		break;

		//Function to define the logic level of the Data/ Command line
	case U8X8_MSG_GPIO_DC:
		if (arg_int)
			HAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, SET);
		else
			HAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, RESET);
		break;

		//Function to define the logic level of the RESET line
	case U8X8_MSG_GPIO_RESET:
		if (arg_int)
			HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, SET);
		else
			HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, RESET);
		break;

	default:
		return 0; //A message was received which is not implemented, return 0 to indicate an error
	}

	return 1; // command processed successfully.
}

#ifdef  USE_FULL_ASSERT
...
#endif /* USE_FULL_ASSERT */

Thanks in advance.

@olikraus
Copy link
Owner

U8g2 relies on the linker to remove unused buffers. There are specific flags for the gnu linker to do this.

@RonTheBestKingInTheWorld

Is there any example of use of it?

@olikraus
Copy link
Owner

olikraus commented Aug 20, 2018

https://github.com/olikraus/u8g2/blob/master/sys/arm/lpc824/u8g2_logo/Makefile

-ffunction-sections -fdata-sections
and
-Wl,--gc-sections

@RonTheBestKingInTheWorld

Hi, thanks a lot!
The problem with the memory is gone now ^^

But could you just take a gimpse on my code?
I don't understand why it doesn't work. I believe its set up correctly.

#include "main.h"
#include "stm32l4xx_hal.h"
#include "u8g2.h"
#include "u8x8.h"

u8g2_t u8g2;


void SystemClock_Config(void);
static void MX_GPIO_Init(void);
uint8_t u8g2_gpio_and_delay_stm32(U8X8_UNUSED u8x8_t *u8x8,	U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int,U8X8_UNUSED void *arg_ptr);

void draw(u8g2_t *u8g2)
{
    u8g2_SetFontMode(u8g2, 1);	// Transparent
    u8g2_SetFontDirection(u8g2, 0);
    u8g2_SetFont(u8g2, u8g2_font_6x12_tr);
    u8g2_DrawStr(u8g2, 0, 20, "Hello World");
}


int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  u8g2.begin();

  u8g2_Setup_ssd1607_gd_200x200_2(&u8g2, U8G2_R0, u8x8_byte_4wire_sw_spi, u8g2_gpio_and_delay_stm32);
  	u8g2_InitDisplay(&u8g2);
  	u8g2_SetPowerSave(&u8g2, 0);
  	u8g2_SendBuffer(&u8g2);
  	HAL_Delay(100);

  while (1)
  {
	  u8g2_DrawLine(&u8g2, 20, 5, 5, 32);
	  HAL_Delay(5000);
  }

}











uint8_t u8g2_gpio_and_delay_stm32(U8X8_UNUSED u8x8_t *u8x8,
U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int,
U8X8_UNUSED void *arg_ptr) {
	switch (msg) {
//Initialize SPI peripheral
	case U8X8_MSG_GPIO_AND_DELAY_INIT:
		break;

		//Function which implements a delay, arg_int contains the amount of ms
	case U8X8_MSG_DELAY_MILLI:
		HAL_Delay(arg_int);
		break;

		/*
		 //Function which delays 10us
		 case U8X8_MSG_DELAY_10MICRO:
		 for (uint16_t n = 0; n < 320; n++) {
		 __NOP();
		 }
		 break;


		 //Function which delays 100ns
		 case U8X8_MSG_DELAY_100NANO:
		 __NOP();
		 break;

		 */

		//Function to define the logic level of the clockline
	case U8X8_MSG_GPIO_SPI_CLOCK:
		if (arg_int)
			HAL_GPIO_WritePin(SCK_GPIO_Port, SCK_Pin, SET);
		else
			HAL_GPIO_WritePin(SCK_GPIO_Port, SCK_Pin, RESET);
		break;

		//Function to define the logic level of the data line to the display
	case U8X8_MSG_GPIO_SPI_DATA:
		if (arg_int)
			HAL_GPIO_WritePin(MOSI_GPIO_Port, MOSI_Pin, SET);
		else
			HAL_GPIO_WritePin(MOSI_GPIO_Port, MOSI_Pin, RESET);
		break;

		// Function to define the logic level of the CS line
	case U8X8_MSG_GPIO_CS:
		if (arg_int)
			HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, SET);
		else
			HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, RESET);
		break;

		//Function to define the logic level of the Data/ Command line
	case U8X8_MSG_GPIO_DC:
		if (arg_int)
			HAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, SET);
		else
			HAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, RESET);
		break;

		//Function to define the logic level of the RESET line
	case U8X8_MSG_GPIO_RESET:
		if (arg_int)
			HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, SET);
		else
			HAL_GPIO_WritePin(RST_GPIO_Port, RST_Pin, RESET);
		break;

	default:
		return 0; //A message was received which is not implemented, return 0 to indicate an error
	}

	return 1; // command processed successfully.
}

Thanks in advance.

@olikraus
Copy link
Owner

The drawing commands must be enclosed by FirstPage/NextPage commands:
https://github.com/olikraus/u8g2/blob/master/sys/arm/lpc824/u8g2_logo/main.c#L97

Or: If you would use the full buffer constructor (_f instead of _2) then you can use the the send buffer command to transfer the graphics data to the display.

@RonTheBestKingInTheWorld

I still cannot display anything on the screen :/
I don't know maybe its the screen I'm using or am I still doing something wrong?


u8g2_Setup_ssd1607_gd_200x200_f(&u8g2, U8G2_R0, u8x8_byte_3wire_sw_spi, u8g2_gpio_and_delay_stm32);
	u8g2_InitDisplay(&u8g2);
	u8g2_SetPowerSave(&u8g2, 0);
	u8g2_SendBuffer(&u8g2);
	HAL_Delay(100);


	while (1) {
		u8g2_DrawLine(&u8g2, 20, 5, 5, 32);
		HAL_Delay(5000);

		u8g2_SendBuffer(&u8g2);

		/*u8g2_FirstPage(&u8g2);
		 do
		 {
		 draw(&u8g2);
		 } while( u8g2_NextPage(&u8g2) );
		 HAL_Delay(5000);*/
	}

@olikraus
Copy link
Owner

ok, I am confused.
The original thread talks about ST7565. Now it moved to an eink display. hhmmm I did not see this during my absense.. it would have been better to create a new issue instead.
@gustavolyra : Is you problem solved?
@RonTheBestKingInTheWorld : It should work now. Can you see any activity on the SPI lines?

@RonTheBestKingInTheWorld

@olikraus Sorry, I believe I should have opened new issue.
Should I still do it?
There is no activity on the SPI lines. They are all set as gpio_output and initiated by CUBEMX

@olikraus
Copy link
Owner

ok, but then there is nothing what i can do. Suggestion is to debug the gpio and delay procedure and ensure that signals are available the the gpio pins.

@RonTheBestKingInTheWorld
Copy link

RonTheBestKingInTheWorld commented Aug 22, 2018

@olikraus After changing of the project I can see the signals on the SPI SCL and MOSI on the GPIO however the code stops after calling u8g2_InitDisplay() when the e-Paper is connected.

@gustavolyra
Copy link
Author

@olikraus , sorry for the late response.
My display wasn't working properly and it took me time to find a new one.
Also i forgot to define the CS pin as an output. =P
To test the new display i created a code just to initialize and to print all pixes (it worked).
Now i'm creating my on driver, so i'm no longer trying to use u8g2.

@olikraus
Copy link
Owner

@gustavolyra Thanks for your feedback
@RonTheBestKingInTheWorld InitDisplay will call some of your code. Is SPI working on your system?

@RonTheBestKingInTheWorld

@olikraus
I have SCK and MOSI set as gpio_output cause the functionu8g2_gpio_and_delay_stm32(...) uses HAL_GPIO_WritePin.

I was able to observe the SPI communication on the pins. RST was HIGH, SCK was periodical and there were some variations on the MOSI.

@olikraus
Copy link
Owner

If the DC pin also works, then this sounds good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants