olikraus / u8g2

U8glib library for monochrome displays, version 2
Other
5.04k stars 1.04k forks source link

nRF52840-DK SSD1327 #1056

Closed cyakimov closed 4 years ago

cyakimov commented 4 years ago

Hi, I'm trying to make a simple SPI hello world by rendering some text to an Waveshare OLED 128x128 screen without success. Yup, I went through the FAQ wiring is ok, constructor fits my display and I'm not outputting text to (0,0).

Does anyone has been able to interface with SSD1327 on a nRF52840 board?

Here's my main.c:

#include "nrf_delay.h"
#include "boards.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "display.h"

int main(void)
{
    bsp_board_init(BSP_INIT_LEDS);

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    NRF_LOG_INFO("SPI example started.");

    display_init();
    display_on();

    while (1)
    {
        display_draw_str(10, 20, 18, "Hello World!");
        display_render();
        bsp_board_led_invert(BSP_BOARD_LED_0);
        nrf_delay_ms(200);
    }
}
display.c

```c #include "display.h" #include "power_manager.h" #include "u8g2.h" #include "nrf_gpio.h" #include "nrf_delay.h" #include "nrf_drv_spi.h" #include "nrf_log.h" #define SCK_PIN SPI_SCK_PIN // 26 Yellow #define MOSI_PIN SPI_MOSI_PIN // 29 Green #define CS_PIN SPI_SS_PIN // 31 Orange #define DC_PIN 30 // Red #define RESET_PIN 27 // Brown #define CONTRAST 230 #define SPI_INSTANCE 0 #define SCREEN_WIDTH 128 static u8g2_t u8g2; static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); static volatile bool spi_xfer_done; static uint8_t u8g2_nrf52_gpio_and_delay_cb(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, can be used to setup pins // nrf_gpio_cfg(SCK_PIN, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_S0S1, NRF_GPIO_PIN_NOSENSE); // nrf_gpio_cfg(MOSI_PIN, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_S0S1, NRF_GPIO_PIN_NOSENSE); nrf_gpio_cfg_output(CS_PIN); nrf_gpio_cfg_output(DC_PIN); nrf_gpio_cfg_output(RESET_PIN); break; case U8X8_MSG_DELAY_NANO: // delay arg_int * 1 nano second nrf_delay_us(arg_int * 0.001); break; case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds nrf_delay_us(arg_int * 0.1); break; case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds nrf_delay_us(arg_int * 10u); break; case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second nrf_delay_ms(arg_int); break; case U8X8_MSG_GPIO_SPI_CLOCK: // D0 or SPI clock pin: Output level in arg_int nrf_gpio_pin_write(SCK_PIN, arg_int); break; case U8X8_MSG_GPIO_SPI_DATA: // D1 or SPI data pin: Output level in arg_int nrf_gpio_pin_write(MOSI_PIN, arg_int); break; case U8X8_MSG_GPIO_CS: // CS (chip select) pin: Output level in arg_int nrf_gpio_pin_write(CS_PIN, arg_int); break; case U8X8_MSG_GPIO_DC: // DC (data/cmd, A0, register select) pin: Output level in arg_int nrf_gpio_pin_write(DC_PIN, arg_int); break; case U8X8_MSG_GPIO_RESET: // Reset pin: Output level in arg_int nrf_gpio_pin_write(RESET_PIN, arg_int); break; default: u8x8_SetGPIOResult(u8x8, 1); // default return value break; } return 1; } static void spi_evt_handler(nrf_drv_spi_evt_t const * p_event) { spi_xfer_done = true; } static void spi_init() { nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG; spi_config.ss_pin = CS_PIN; spi_config.mosi_pin = MOSI_PIN; spi_config.sck_pin = SCK_PIN; spi_config.frequency = NRF_SPIM_FREQ_16M; APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_evt_handler, NULL)); } static void spi_send(uint8_t *data, uint8_t length) { spi_xfer_done = false; APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, data, length, NULL, 0)); while(! spi_xfer_done) { power_manage(); } } static uint8_t u8g2_nrf52_spi_byte_cb(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) { switch(msg) { case U8X8_MSG_BYTE_INIT: spi_init(); break; case U8X8_MSG_BYTE_SET_DC: nrf_gpio_pin_write(DC_PIN, arg_int); break; case U8X8_MSG_BYTE_START_TRANSFER: break; case U8X8_MSG_BYTE_SEND: spi_send((uint8_t*)arg_ptr, arg_int); break; case U8X8_MSG_BYTE_END_TRANSFER: break; default: return 0; } return 0; } void display_init() { u8g2_Setup_ssd1327_ws_128x128_f(&u8g2, U8G2_R0, u8g2_nrf52_spi_byte_cb, u8g2_nrf52_gpio_and_delay_cb); u8g2_InitDisplay(&u8g2); u8g2_SetContrast(&u8g2, CONTRAST); u8g2_SetFont(&u8g2, u8g2_font_helvB10_tr); u8g2_ClearDisplay(&u8g2); } void display_on() { display_clear(); display_render(); u8g2_SetPowerSave(&u8g2, 0); } void display_off() { u8g2_SetPowerSave(&u8g2, 1); } static const uint8_t *font_for_size(uint8_t font_size) { if(font_size <= 8) { return u8g2_font_helvB08_tr; } else if(font_size <= 10) { return u8g2_font_helvB10_tr; } else if(font_size <= 12) { return u8g2_font_helvB12_tr; } else if(font_size <= 14) { return u8g2_font_helvB14_tr; } else if(font_size <= 18) { return u8g2_font_helvB18_tr; } else if(font_size <= 24) { return u8g2_font_helvB24_tr; } else if(font_size <= 25) { return u8g2_font_fub25_tn; } else if(font_size <= 30) { return u8g2_font_fub30_tn; } else if(font_size <= 35) { return u8g2_font_fub35_tn; } else { return u8g2_font_fub42_tn; } } void display_draw_str(uint32_t x, uint32_t y, uint32_t font_size, char *str) { const uint8_t *font = font_for_size(font_size); u8g2_SetFont(&u8g2, font); u8g2_DrawStr(&u8g2, x, y, str); } void display_clear() { u8g2_ClearBuffer(&u8g2); } void display_draw_line(uint32_t start_x, uint32_t start_y, uint32_t end_x, uint32_t end_y) { u8g2_DrawLine(&u8g2, start_x, start_y, end_x, end_y); } void display_render() { u8g2_SendBuffer(&u8g2); } uint8_t display_centered_x(const char *str, uint8_t font_size) { u8g2_SetFont(&u8g2, font_for_size(font_size)); int x = SCREEN_WIDTH / 2 - u8g2_GetStrWidth(&u8g2, str) / 2; return x >= 0 ? x : 0; } ```

olikraus commented 4 years ago

I guess I missed this issue.

Is your problem solved?

For the U8X8_MSG_BYTE_START_TRANSFER and U8X8_MSG_BYTE_END_TRANSFER you need to set the CS pin, see also: https://github.com/olikraus/u8g2/wiki/Porting-to-new-MCU-platform#hardware-spi-communication

Also the multiplication with a float value should be avoided. It will avoid the inclusion of float lib if you just device by integer values.

olikraus commented 4 years ago

no feedback, closing...