From: Martin Mares Date: Sun, 24 Jun 2018 21:15:41 +0000 (+0200) Subject: Display on I2C2 (not working) X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=4b65af0c3b9e7d965515044e5761ba3003ee38aa;p=home-hw.git Display on I2C2 (not working) --- diff --git a/Inc/app.h b/Inc/app.h new file mode 100644 index 0000000..bd81ad0 --- /dev/null +++ b/Inc/app.h @@ -0,0 +1,4 @@ +// display.c + +void display_init(void); +void display_counter(uint cnt); diff --git a/Makefile b/Makefile index a1e31eb..b88dcda 100644 --- a/Makefile +++ b/Makefile @@ -56,6 +56,7 @@ Src/main.c \ Src/debug.c \ Src/usb.c \ Src/usbdev.c \ +Src/display.c \ /aux/misc/stm/F1-package/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rcc.c \ /Src/system_stm32f1xx.c \ Src/stm32f1xx_it.c \ diff --git a/Src/display.c b/Src/display.c new file mode 100644 index 0000000..06c5fe2 --- /dev/null +++ b/Src/display.c @@ -0,0 +1,159 @@ +#include "util.h" +#include "main.h" +#include "app.h" + +static const byte Gentium23x32[] = { + 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x1F, 0x00, 0x80, 0xFF, 0xFF, 0x00, 0xE0, 0xFF, 0xFF, 0x03, 0xF0, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x3F, 0xFE, 0x01, 0xE0, 0x3F, 0x3E, 0x00, 0x00, 0x7F, 0x1F, 0x00, 0x00, 0x7C, 0x0F, 0x00, 0x00, 0x78, 0x0F, 0x00, 0x00, 0x78, 0x1F, 0x00, 0x00, 0x78, 0x3F, 0x00, 0x00, 0x78, 0x7F, 0x00, 0x00, 0x3E, 0xFE, 0x07, 0xC0, 0x3F, 0xFE, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0x0F, 0xF8, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0x03, 0x80, 0xFF, 0xFF, 0x00, 0x00, 0xFC, 0x0F, 0x00, // Code for char 0 + 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x70, 0x78, 0x00, 0x00, 0x70, 0x78, 0x00, 0x00, 0x78, 0x78, 0x00, 0x00, 0x78, 0x7C, 0x00, 0x00, 0x78, 0x3C, 0x00, 0x00, 0x78, 0xFE, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, // Code for char 1 + 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x80, 0x01, 0x00, 0x78, 0xE0, 0x03, 0x00, 0x7C, 0xF0, 0x03, 0x00, 0x7E, 0xF8, 0x03, 0x80, 0x7F, 0xFC, 0x01, 0xC0, 0x7F, 0xFE, 0x01, 0xE0, 0x7F, 0x3E, 0x00, 0xF0, 0x7F, 0x1E, 0x00, 0xFC, 0x7F, 0x0F, 0x00, 0xFE, 0x79, 0x0F, 0x00, 0xFF, 0x78, 0x0F, 0xC0, 0x7F, 0x78, 0x1F, 0xE0, 0x3F, 0x78, 0x3F, 0xF8, 0x0F, 0x78, 0xFF, 0xFF, 0x07, 0x78, 0xFE, 0xFF, 0x03, 0x78, 0xFE, 0xFF, 0x00, 0x7C, 0xFC, 0x7F, 0x80, 0x7F, 0xF8, 0x1F, 0x80, 0x7F, 0xE0, 0x07, 0x80, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 2 + 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xC0, 0x00, 0x00, 0x1F, 0xF0, 0x01, 0x00, 0x1E, 0xF8, 0x01, 0x00, 0x3E, 0xFC, 0x01, 0x00, 0x3C, 0xFE, 0x00, 0x00, 0x7C, 0xFE, 0x00, 0x00, 0x78, 0x1E, 0xE0, 0x00, 0x78, 0x0F, 0xF0, 0x00, 0x78, 0x0F, 0xF0, 0x00, 0x78, 0x0F, 0xF0, 0x00, 0x78, 0x1F, 0xF8, 0x01, 0x7C, 0x3F, 0xFC, 0x01, 0x7C, 0xFF, 0xFF, 0x07, 0x3F, 0xFE, 0xFF, 0xFF, 0x3F, 0xFE, 0xFF, 0xFF, 0x1F, 0xFC, 0xCF, 0xFF, 0x0F, 0xF8, 0xC7, 0xFF, 0x07, 0xE0, 0x83, 0xFF, 0x03, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 3 + 0x17, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0xFE, 0x3D, 0x00, 0x00, 0xFF, 0x3C, 0x70, 0xC0, 0x3F, 0x3C, 0x70, 0xE0, 0x1F, 0x3C, 0x70, 0xF8, 0x07, 0x3C, 0x78, 0xFC, 0x03, 0x3C, 0x78, 0xFE, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x3C, 0x78, 0x00, 0x00, 0x3C, 0x70, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x00, 0x08, 0x00, // Code for char 4 + 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0xC0, 0x00, 0x1F, 0x00, 0xFE, 0x01, 0x1E, 0xFC, 0xFF, 0x01, 0x3E, 0xFC, 0xFF, 0x00, 0x3C, 0xFC, 0xFF, 0x00, 0x3C, 0xFC, 0x7F, 0x00, 0x78, 0x3C, 0x78, 0x00, 0x78, 0x3C, 0x78, 0x00, 0x78, 0x3C, 0x78, 0x00, 0x78, 0x3C, 0x78, 0x00, 0x78, 0x3C, 0xF8, 0x00, 0x7C, 0x3C, 0xF8, 0x00, 0x7E, 0x3C, 0xF0, 0x03, 0x3F, 0x3C, 0xF0, 0xFF, 0x3F, 0x3C, 0xF0, 0xFF, 0x1F, 0x1E, 0xE0, 0xFF, 0x0F, 0x0F, 0xC0, 0xFF, 0x07, 0x06, 0x80, 0xFF, 0x03, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 5 + 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0xFE, 0xFF, 0x07, 0x80, 0xFF, 0xFF, 0x0F, 0xC0, 0xFF, 0xFF, 0x1F, 0xE0, 0xFF, 0xFF, 0x3F, 0xF0, 0xFF, 0xC1, 0x3F, 0xF8, 0xF7, 0x00, 0x7E, 0xF8, 0x71, 0x00, 0x7C, 0xFC, 0x78, 0x00, 0x78, 0x7C, 0x78, 0x00, 0x78, 0x3E, 0x78, 0x00, 0x78, 0x1E, 0xF8, 0x00, 0x7C, 0x1E, 0xF8, 0x03, 0x3E, 0x0F, 0xF0, 0xFF, 0x3F, 0x0F, 0xF0, 0xFF, 0x1F, 0x0F, 0xE0, 0xFF, 0x0F, 0x06, 0xE0, 0xFF, 0x07, 0x00, 0x80, 0xFF, 0x03, 0x00, 0x00, 0x7E, 0x00, // Code for char 6 + 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x20, 0x7C, 0x00, 0x00, 0x78, 0x3C, 0x00, 0x00, 0x7E, 0x3C, 0x00, 0x80, 0x7F, 0x3C, 0x00, 0xE0, 0x3F, 0x3C, 0x00, 0xF8, 0x3F, 0x3C, 0x00, 0xFE, 0x1F, 0x3C, 0x80, 0xFF, 0x0F, 0x3C, 0xE0, 0xFF, 0x01, 0x3C, 0xF8, 0x7F, 0x00, 0x3C, 0xFE, 0x0F, 0x00, 0xFC, 0xFF, 0x03, 0x00, 0xFC, 0xFF, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xFC, 0x07, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, // Code for char 7 + 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0xC0, 0x07, 0xFC, 0x07, 0xF0, 0x1F, 0xFE, 0x1F, 0xF8, 0x3F, 0xFF, 0x1F, 0xFC, 0xBF, 0xFF, 0x3F, 0xFE, 0xFF, 0xFF, 0x3F, 0xFE, 0xFF, 0x0F, 0x7E, 0x1F, 0xFE, 0x03, 0x7C, 0x0F, 0xFC, 0x01, 0x78, 0x0F, 0xF8, 0x01, 0x78, 0x0F, 0xF8, 0x01, 0x78, 0x0F, 0xF8, 0x03, 0x78, 0x1F, 0xFC, 0x07, 0x7C, 0xFF, 0xFF, 0x0F, 0x3E, 0xFE, 0xFF, 0xFF, 0x3F, 0xFE, 0xDF, 0xFF, 0x1F, 0xFC, 0xCF, 0xFF, 0x0F, 0xF8, 0x87, 0xFF, 0x07, 0xF0, 0x01, 0xFF, 0x03, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 8 + 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xC0, 0xFF, 0x00, 0x00, 0xF0, 0xFF, 0x01, 0x60, 0xF8, 0xFF, 0x03, 0xE0, 0xFC, 0xFF, 0x07, 0xF0, 0xFC, 0xFF, 0x07, 0xF0, 0x7E, 0xE0, 0x0F, 0xF8, 0x1E, 0x80, 0x0F, 0x78, 0x0F, 0x00, 0x0F, 0x7C, 0x0F, 0x00, 0x0F, 0x7C, 0x0F, 0x00, 0x0F, 0x3E, 0x0F, 0x00, 0x0F, 0x3F, 0x1F, 0x00, 0x87, 0x1F, 0x3F, 0x80, 0xE7, 0x1F, 0xFE, 0xC1, 0xFB, 0x0F, 0xFE, 0xFF, 0xFF, 0x07, 0xFC, 0xFF, 0xFF, 0x03, 0xF8, 0xFF, 0xFF, 0x01, 0xF0, 0xFF, 0x7F, 0x00, 0xC0, 0xFF, 0x1F, 0x00, 0x00, 0xFF, 0x03, 0x00, // Code for char 9 + 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x03, 0xC0, 0x07, 0xF0, 0x07, 0xE0, 0x0F, 0xF8, 0x07, 0xF0, 0x0F, 0xF8, 0x07, 0xF0, 0x0F, 0xF8, 0x07, 0xF0, 0x0F, 0xF8, 0x07, 0xF0, 0x0F, 0xF8, 0x03, 0xF0, 0x07, 0xF0, 0x01, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char : +}; + +// Based on https://github.com/adafruit/Adafruit_SSD1306 + +#define SSD1306_SETLOWCOLUMN 0x00 +#define SSD1306_SETHIGHCOLUMN 0x10 +#define SSD1306_MEMORYMODE 0x20 +#define SSD1306_SETSTARTLINE 0x40 +#define SSD1306_SETCONTRAST 0x81 +#define SSD1306_CHARGEPUMP 0x8D +#define SSD1306_SEGREMAP 0xA0 +#define SSD1306_DISPLAYALLON_RESUME 0xA4 +#define SSD1306_DISPLAYALLON 0xA5 +#define SSD1306_NORMALDISPLAY 0xA6 +#define SSD1306_INVERTDISPLAY 0xA7 +#define SSD1306_SETMULTIPLEX 0xA8 +#define SSD1306_DISPLAYOFF 0xAE +#define SSD1306_DISPLAYON 0xAF +#define SSD1306_SETSTARTPAGE 0xB0 +#define SSD1306_COMSCANINC 0xC0 +#define SSD1306_COMSCANDEC 0xC8 +#define SSD1306_SETDISPLAYOFFSET 0xD3 +#define SSD1306_SETCOMPINS 0xDA +#define SSD1306_SETVCOMDETECT 0xDB +#define SSD1306_SETDISPLAYCLOCKDIV 0xD5 +#define SSD1306_SETPRECHARGE 0xD9 +#define SSD1306_NOP 0xE3 + +static const byte display_init_cmds[] = { + SSD1306_DISPLAYOFF, + SSD1306_SETDISPLAYCLOCKDIV, 0x80, // the suggested ratio 0x80 + SSD1306_SETMULTIPLEX, 0x1F, // ratio 32 + SSD1306_SETDISPLAYOFFSET,0x0, // no offset + SSD1306_SETSTARTLINE | 0x0, // line #0 + SSD1306_CHARGEPUMP, 0x14, // internal vcc + SSD1306_MEMORYMODE, 0x02, // page mode + SSD1306_SEGREMAP | 0x0, // column 0 mapped to SEG0 + SSD1306_COMSCANINC, // column scan direction not reversed + SSD1306_SETCOMPINS, 0x02, // sequential COM pins, disable remap + SSD1306_SETCONTRAST, 0x7F, // contrast level 127 + SSD1306_SETPRECHARGE, 0xF1, // pre-charge period (1, 15) + SSD1306_SETVCOMDETECT, 0x40, // vcomh regulator level- + // SSD1306_DISPLAYALLON_RESUME, + SSD1306_DISPLAYALLON, + SSD1306_NORMALDISPLAY, + SSD1306_DISPLAYON, +}; + +static void display_send_byte(byte d) +{ + while (!LL_I2C_IsActiveFlag_TXE(I2C2)) + ; + LL_I2C_TransmitData8(I2C2, d); +} + +static void display_cmd(byte cmd) +{ + LL_I2C_GenerateStartCondition(I2C2); + while (!LL_I2C_IsActiveFlag_SB(I2C2)) + ; + LL_I2C_TransmitData8(I2C2, 0x78); // Address + while (!LL_I2C_IsActiveFlag_ADDR(I2C2)) + ; + LL_I2C_ClearFlag_ADDR(I2C2); + display_send_byte(0x00); // Will send a command + display_send_byte(cmd); + LL_I2C_GenerateStopCondition(I2C2); +} + +static void display_data_start(void) +{ + LL_I2C_GenerateStartCondition(I2C2); + while (!LL_I2C_IsActiveFlag_SB(I2C2)) + ; + LL_I2C_TransmitData8(I2C2, 0x78); // Address + while (!LL_I2C_IsActiveFlag_ADDR(I2C2)) + ; + LL_I2C_ClearFlag_ADDR(I2C2); + display_send_byte(0x40); // Will send data +} + +static void display_data(byte d) +{ + display_send_byte(d); +} + +static void display_data_end(void) +{ + LL_I2C_GenerateStopCondition(I2C2); +} + +void display_init(void) +{ + for (uint i=0; i < sizeof(display_init_cmds); i++) + display_cmd(display_init_cmds[i]); + + for (uint p=0; p<4; p++) + { + display_cmd(SSD1306_SETSTARTPAGE + p); + display_cmd(SSD1306_SETHIGHCOLUMN); + display_cmd(SSD1306_SETLOWCOLUMN); + display_data_start(); + for (uint i=0; i<128; i++) + { + byte x = 0xaa; + // x = Gentium23x32[(23*4+1)*(i/23) + 1 + 4*(i%23) + p]; + display_data(x); + } + display_data_end(); + } +} + +void display_counter(uint cnt) +{ +#if 0 + byte d[5]; + for (uint i=0; i<5; i++) + { + d[4-i] = cnt % 10; + cnt /= 10; + } + + for (uint p=0; p<4; p++) + { + display_cmd(SSD1306_SETSTARTPAGE + p); + display_cmd(SSD1306_SETHIGHCOLUMN); + display_cmd(SSD1306_SETLOWCOLUMN); + display_data_start(); + for (uint i=0; i<5; i++) + { + for (uint j=0; j<23; j++) + { + byte x = Gentium23x32[(23*4+1)*d[i] + 1 + 4*j + p]; + display_data(x); + } + display_data(0); + display_data(0); + display_data(0); + } + display_data_end(); + } +#endif +} diff --git a/Src/main.c b/Src/main.c index 1810399..241e3f5 100644 --- a/Src/main.c +++ b/Src/main.c @@ -41,6 +41,7 @@ #include "main.h" #include "stm32f1xx_hal.h" #include "usb.h" +#include "app.h" /* USER CODE BEGIN Includes */ @@ -118,6 +119,7 @@ int main(void) MX_I2C2_Init(); MX_USB_PCD_Init(); /* USER CODE BEGIN 2 */ + display_init(); usb_start(&usb); /* USER CODE END 2 */ @@ -127,11 +129,13 @@ int main(void) int cnt = 0; while (1) { + debug_printf("Counter = %d\n", cnt); + display_counter(cnt); LL_GPIO_SetOutputPin(LED_GPIO_Port, LED_Pin); LL_mDelay(500); LL_GPIO_ResetOutputPin(LED_GPIO_Port, LED_Pin); LL_mDelay(500); - debug_printf("Counter = %d\n", cnt++); + cnt++; /* USER CODE END WHILE */ @@ -261,7 +265,7 @@ static void MX_I2C2_Init(void) /**I2C Initialization */ I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; - I2C_InitStruct.ClockSpeed = 400000; + I2C_InitStruct.ClockSpeed = 100000; I2C_InitStruct.DutyCycle = LL_I2C_DUTYCYCLE_2; I2C_InitStruct.OwnAddress1 = 0; I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; diff --git a/Src/usb.c b/Src/usb.c index c6867da..ffac01d 100644 --- a/Src/usb.c +++ b/Src/usb.c @@ -27,7 +27,7 @@ void usb_ctl_send_status(struct usb *usb) { usb_debug("Control send: status\n"); usb->ep0_state = USB_EP0_STATUS_IN; - usb_ep_transmit(usb, 0x00, NULL, 0); + usb_ep_send(usb, 0x00, NULL, 0); } void usb_ctl_recv_status(struct usb *usb) @@ -42,7 +42,7 @@ void usb_ctl_send_data(struct usb *usb, const byte *data, uint len) usb->ep0_state = USB_EP0_DATA_IN; usb->ep0_total_length = len; usb->ep0_remaining_length = len; - usb_ep_transmit(usb, 0x00, data, len); + usb_ep_send(usb, 0x00, data, len); } void usb_ctl_recv_data(struct usb *usb, byte *data, uint len) @@ -51,7 +51,7 @@ void usb_ctl_recv_data(struct usb *usb, byte *data, uint len) usb->ep0_state = USB_EP0_DATA_OUT; usb->ep0_total_length = len; usb->ep0_remaining_length = len; - usb_ep_transmit(usb, 0x00, data, len); + usb_ep_send(usb, 0x00, data, len); } static void usb_ctl_send_byte(struct usb *usb, byte data) @@ -460,7 +460,7 @@ void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) if (usb->ep0_remaining_length > ep->maxpacket) { usb->ep0_remaining_length -= ep->maxpacket; - usb_ep_transmit(usb, 0x00, ep->xfer_buff, usb->ep0_remaining_length); + usb_ep_send(usb, 0x00, ep->xfer_buff, usb->ep0_remaining_length); usb_ep_receive(usb, 0x00, NULL, 0); } else if (usb->ep0_total_length && usb->ep0_total_length % ep->maxpacket == 0 && usb->ep0_total_length < usb->ep0_setup_data_length) @@ -470,7 +470,7 @@ void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) * or by reaching the answer size requested in the setup packet. Send an empty final packet * if needed. */ - usb_ep_transmit(usb, 0x00, NULL, 0); + usb_ep_send(usb, 0x00, NULL, 0); usb->ep0_setup_data_length = 0; usb_ep_receive(usb, 0x00, NULL, 0); }