Hi
I want to run an epaper with the nRF52832 therefore is SPI needed.
Board file was generated from scratch. In the devicetree I added the SPI modul and a epaper modul, which connects to the SPI modul.
To send data to the epaper over SPI I use the spi_transceive_dt function.
void EPaper_Spi_WriteByte(uint8_t txData) { uint8_t tx_buffer = 0x88; struct spi_buf tx_spi_buf = { .buf = (void *)&tx_buffer, .len = 1 }; struct spi_buf_set tx_spi_buf_set = { .buffers = &tx_spi_buf, .count = 1 }; struct spi_buf rx_spi_bufs = { .buf = &txData, .len = 1 }; struct spi_buf_set rx_spi_buf_set = { .buffers = &rx_spi_bufs, .count = 1 }; int err = spi_transceive_dt(&spiSpec, &tx_spi_buf_set, &rx_spi_buf_set); if (err < 0) { printk("SPI: spi_transceive_dt() failed, err: %d\n", err); return err; } }
Chipselect and MOSI Signal ar working as requeried. But the SCL signal does nothing, it stays the whole time on low. Even when pin MOSI and SCL are swapped in devicetree, SCL is still low.
Do you have any idea why the SCL signal does not work? Hopfully I added all requeried files.
/******************************************************************************* Project - Digitale Laufkarte We reserve all rights in this document and in the information contained therein. Reproduction, use or disclosure to third parties without express authority is strictly forbidden. (c) Copyright 2024 Marelcom AG ================================================================================ $HeadURL: $ $Id: epaper.c 145 2024-11-11 13:31:16Z mr $ *******************************************************************************/ //----------------------------------------------------------------------------- // includes #include "epaper.h" #include "bsp.h" #include <zephyr/drivers/spi.h> //----------------------------------------------------------------------------- // defines #define EPAPER_WIDTH_PX 384 #define EPAPER_HEIGHT_PX 168 #define SPIOP SPI_WORD_SET(8) | SPI_TRANSFER_MSB //------------------------------------------------------------------------------ // typedef //----------------------------------------------------------------------------- // module static variable //struct spi_dt_spec s_epaperSpispec = SPI_DT_SPEC_GET(DT_NODELABEL(gendev), SPIOP, 0); static const struct gpio_dt_spec dcPin_spec = GPIO_DT_SPEC_GET(DT_NODELABEL(epaper_display), dc_gpios); static const struct gpio_dt_spec rstPin_spec = GPIO_DT_SPEC_GET(DT_NODELABEL(epaper_display), reset_gpios); static const struct gpio_dt_spec busyPin_spec = GPIO_DT_SPEC_GET(DT_NODELABEL(epaper_display), busy_gpios); static const struct gpio_dt_spec csPin_spec = GPIO_DT_SPEC_GET(DT_NODELABEL(spi0), cs_gpios); /*static const struct device *spi_dev; static const struct spi_config spi_cfg = { .frequency = 1000000, // Frequenz: 1 MHz .operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_TRANSFER_MSB, // Full-Duplex .slave = 0, .cs = NULL, };*/ struct spi_dt_spec spiSpec = SPI_DT_SPEC_GET(DT_NODELABEL(epaper_display), SPIOP, 0); //------------------------------------------------------------------------------ // macro #define EPAPER_CS_CLEAR (gpio_pin_set_dt(&csPin_spec, 1)) #define EPAPER_CS_SET (gpio_pin_set_dt(&csPin_spec, 0)) #define EPAPER_COMMAND (gpio_pin_set_dt(&dcPin_spec, 0)) #define EPAPER_DATA (gpio_pin_set_dt(&dcPin_spec, 1)) //------------------------------------------------------------------------------ // private function prototype void EPaper_Reset(void); void EPaper_Spi_WriteByte(uint8_t txData); void EPaper_Write_Command(uint8_t cmd); void EPaper_Write_Data(uint8_t data); void EPaper_WaitForNotBusy(void); //***************************************************************************** // description: // EPaper_Init //***************************************************************************** void EPaper_Init(void) { // SPI-Gerät abrufen /*spi_dev = DEVICE_DT_GET(DT_NODELABEL(spi0)); if (!spi_dev) { printk("SPI device not found\n"); return; }*/ bool err = spi_is_ready_dt(&spiSpec); if (!err) { printk("Error: SPI device is not ready, err: %d\n", err); return 0; } // GPIOs für DC, RST und BUSY einrichten und prüfen if (!device_is_ready(dcPin_spec.port) || !device_is_ready(rstPin_spec.port) || !device_is_ready(busyPin_spec.port) || !device_is_ready(csPin_spec.port)) { printk("GPIO device not ready\n"); return; } gpio_pin_configure_dt(&busyPin_spec, GPIO_INPUT); gpio_pin_configure_dt(&csPin_spec, GPIO_OUTPUT_HIGH); gpio_pin_configure_dt(&dcPin_spec, GPIO_OUTPUT_HIGH); gpio_pin_configure_dt(&rstPin_spec, GPIO_OUTPUT_LOW); EPAPER_CS_CLEAR; EPAPER_DATA; // init E-Paper k_msleep(10); EPaper_Reset(); EPaper_WaitForNotBusy(); //读busy信号 EPaper_Write_Command(0x12); // 软件复位 soft reset EPaper_WaitForNotBusy(); Display_All_White(); } void EPaper_Reset(void) { gpio_pin_set_dt(&rstPin_spec, 0); k_msleep(10); gpio_pin_set_dt(&rstPin_spec, 1); k_msleep(10); } void EPaper_WaitForNotBusy(void) { while(1) { if (gpio_pin_get_dt(&busyPin_spec) == 0) { break; } k_usleep(5); } k_usleep(100); } /*void EPaper_DisplayImage(const uint8_t *image_data, size_t len) { struct spi_buf tx_buf = { .buf = image_data, .len = len, // Bildgröße anpassen }; struct spi_buf_set tx = { .buffers = &tx_buf, .count = 1, }; // SPI-Konfiguration wird automatisch aus dem Device Tree übernommen int ret = spi_write(spi_dev, &spi_cfg, &tx); // Die Konfiguration wird durch den Device Tree bestimmt if (ret < 0) { // Fehlerbehandlung printk("SPI: Write Image Data failed"); return ret; } return 0; }*/ void EPaper_Clear(void) { } /* * Function name: EPaper_Spi_WriteByte * Description: SPI writes a byte * Input: TxData: byte to be written * Output: None */ void EPaper_Spi_WriteByte(uint8_t txData) { /*struct spi_buf tx_buf = { .buf = &txData, .len = 1, }; struct spi_buf_set tx = { .buffers = &tx_buf, .count = 1, }; int ret = spi_write(spi_dev, &spi_cfg, &tx); if (ret < 0) { printk("SPI: Write Image Data failed"); return ret; }*/ uint8_t tx_buffer = 0x88; struct spi_buf tx_spi_buf = { .buf = (void *)&tx_buffer, .len = 1 }; struct spi_buf_set tx_spi_buf_set = { .buffers = &tx_spi_buf, .count = 1 }; struct spi_buf rx_spi_bufs = { .buf = &txData, .len = 1 }; struct spi_buf_set rx_spi_buf_set = { .buffers = &rx_spi_bufs, .count = 1 }; int err = spi_transceive_dt(&spiSpec, &tx_spi_buf_set, &rx_spi_buf_set); if (err < 0) { printk("SPI: spi_transceive_dt() failed, err: %d\n", err); return err; } } /* * Function name: EPaper_Write_Command * Description: Write command * Input: cmd * Output: None */ void EPaper_Write_Command(uint8_t cmd) { EPAPER_CS_SET; EPAPER_COMMAND; k_usleep(5) ; EPaper_Spi_WriteByte(cmd); k_usleep(5) ; EPAPER_CS_CLEAR; } /* * Function name: EPaper_Write_Data * Description: Write data * Input: data * Output: None */ void EPaper_Write_Data(uint8_t data) { EPAPER_CS_SET; EPAPER_DATA; k_usleep(5) ; EPaper_Spi_WriteByte(data); k_usleep(5) ; EPAPER_CS_CLEAR; } /* * Function name: Epaper_Update_and_Deepsleep * Description: Update & enter deep sleep * Input: None * Output: None */ void EPaper_UpdateAndDeepsleep(void) { EPaper_Write_Command(0x20); EPaper_WaitForNotBusy(); EPaper_Write_Command(0x10); EPaper_Write_Data(0x01); k_msleep(100); } /* * Function name: Display_All_White * Description: Refresh the display to all white * Input: None * Output: None */ void Display_All_White(void) { uint32_t col = 0; uint32_t row = 0; EPaper_WaitForNotBusy(); EPaper_Write_Command(0x24); for (col = 0; col < EPAPER_WIDTH_PX; col++) { for (row = 0; row < EPAPER_HEIGHT_PX / 8; row++) { EPaper_Write_Data(0xFF); } } EPaper_WaitForNotBusy(); EPaper_Write_Command(0x26); for (col = 0; col < EPAPER_WIDTH_PX; col++) { for (row = 0; row < EPAPER_HEIGHT_PX / 8; row++) { EPaper_Write_Data(0x00); } } } /* * Function name: Display_All_Black * Description: Refresh the display to all black * Input: None * Output: None */ void Display_All_Black(void) { uint32_t col = 0; uint32_t row = 0; EPaper_WaitForNotBusy(); EPaper_Write_Command(0x24); for (col = 0; col < EPAPER_WIDTH_PX; col++) { for (row = 0; row < EPAPER_HEIGHT_PX / 8; row++) { EPaper_Write_Data(0x00); } } EPaper_WaitForNotBusy(); EPaper_Write_Command(0x26); for (col = 0; col < EPAPER_WIDTH_PX; col++) { for (row = 0; row < EPAPER_HEIGHT_PX / 8; row++) { EPaper_Write_Data(0x00); } } } /* * Function name: Display_All_Red * Description: Refresh the display to all red * Input: None * Output: None */ void Display_All_Red(void) { uint32_t col = 0; uint32_t row = 0; EPaper_WaitForNotBusy(); EPaper_Write_Command(0x24); for (col = 0; col < EPAPER_WIDTH_PX; col++) { for (row = 0; row < EPAPER_HEIGHT_PX / 8; row++) { EPaper_Write_Data(0x00); } } EPaper_WaitForNotBusy(); EPaper_Write_Command(0x26); for (col = 0; col < EPAPER_WIDTH_PX; col++) { for (row = 0; row < EPAPER_HEIGHT_PX / 8; row++) { EPaper_Write_Data(0xFF); } } }
Thanks & best regards
Markus