Commit 93554697 authored by Pedro Henrique Kopper's avatar Pedro Henrique Kopper

Add suport for OLED module and USB-CDC

parent 5a1bbcee
......@@ -122,6 +122,9 @@ LDSCRIPT= $(STARTUPLD)/STM32F303xC.ld
# setting.
CSRC = $(ALLCSRC) \
$(TESTSRC) \
$(CHIBIOS)/os/various/syscalls.c \
./lib/ssd1306.c \
usbcfg.c \
main.c
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
......@@ -135,7 +138,7 @@ ASMSRC = $(ALLASMSRC)
ASMXSRC = $(ALLXASMSRC)
# Inclusion directories.
INCDIR = $(CONFDIR) $(ALLINC) $(TESTINC)
INCDIR = $(CONFDIR) $(ALLINC) $(TESTINC) $(ROOT)/lib
# Define C warning options here.
CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes
......
......@@ -86,7 +86,7 @@
* @brief Enables the I2C subsystem.
*/
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
#define HAL_USE_I2C FALSE
#define HAL_USE_I2C TRUE
#endif
/**
......@@ -149,7 +149,7 @@
* @brief Enables the SERIAL over USB subsystem.
*/
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL_USB FALSE
#define HAL_USE_SERIAL_USB TRUE
#endif
/**
......@@ -184,7 +184,7 @@
* @brief Enables the USB subsystem.
*/
#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
#define HAL_USE_USB FALSE
#define HAL_USE_USB TRUE
#endif
/**
......
......@@ -64,7 +64,7 @@
#define STM32_TIM1SW STM32_TIM1SW_PCLK2
#define STM32_TIM8SW STM32_TIM8SW_PCLK2
#define STM32_RTCSEL STM32_RTCSEL_LSI
#define STM32_USB_CLOCK_REQUIRED FALSE
#define STM32_USB_CLOCK_REQUIRED TRUE
#define STM32_USBPRE STM32_USBPRE_DIV1P5
/*
......@@ -158,7 +158,7 @@
/*
* I2C driver system settings.
*/
#define STM32_I2C_USE_I2C1 FALSE
#define STM32_I2C_USE_I2C1 TRUE
#define STM32_I2C_USE_I2C2 FALSE
#define STM32_I2C_BUSY_TIMEOUT 50
#define STM32_I2C_I2C1_IRQ_PRIORITY 10
......@@ -260,7 +260,7 @@
/*
* USB driver system settings.
*/
#define STM32_USB_USE_USB1 FALSE
#define STM32_USB_USE_USB1 TRUE
#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
#define STM32_USB_USB1_HP_IRQ_PRIORITY 13
#define STM32_USB_USB1_LP_IRQ_PRIORITY 14
......
#include <string.h>
#include "hal.h"
#include "ssd1306.h"
#include "ssd1306_font.c"
/* Steal from https://stm32f4-discovery.net/2015/05/library-61-ssd1306-oled-i2c-lcd-for-stm32f4xx/ */
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
static msg_t wrCmd(void *ip, uint8_t cmd) {
const SSD1306Driver *drvp = (const SSD1306Driver *)ip;
msg_t ret;
uint8_t txbuf[] = { 0x00, cmd };
i2cAcquireBus(drvp->config->i2cp);
i2cStart(drvp->config->i2cp, drvp->config->i2ccfg);
ret = i2cMasterTransmitTimeout(drvp->config->i2cp, drvp->config->sad,
txbuf, sizeof(txbuf), NULL, 0, TIME_INFINITE);
i2cReleaseBus(drvp->config->i2cp);
return ret;
}
static msg_t wrDat(void *ip, uint8_t *txbuf, uint16_t len) {
const SSD1306Driver *drvp = (const SSD1306Driver *)ip;
msg_t ret;
i2cAcquireBus(drvp->config->i2cp);
i2cStart(drvp->config->i2cp, drvp->config->i2ccfg);
ret = i2cMasterTransmitTimeout(drvp->config->i2cp, drvp->config->sad,
txbuf, len, NULL, 0, TIME_INFINITE);
i2cReleaseBus(drvp->config->i2cp);
return ret;
}
static void updateScreen(void *ip) {
SSD1306Driver *drvp = (SSD1306Driver *)ip;
uint8_t idx;
for (idx = 0; idx < 8; idx++) {
wrCmd(drvp, 0xB0 + idx);
wrCmd(drvp, 0x00);
wrCmd(drvp, 0x10);
// Write multi data
wrDat(drvp, &drvp->fb[SSD1306_WIDTH_FIXED * idx], SSD1306_WIDTH_FIXED);
}
}
static void toggleInvert(void *ip) {
SSD1306Driver *drvp = (SSD1306Driver *)ip;
uint16_t idx;
// Toggle invert
drvp->inv = !drvp->inv;
for (idx = 0; idx < sizeof(drvp->fb); idx++) {
if (idx % SSD1306_WIDTH_FIXED == 0) continue;
drvp->fb[idx] = ~drvp->fb[idx];
}
}
static void fillScreen(void *ip, ssd1306_color_t color) {
SSD1306Driver *drvp = (SSD1306Driver *)ip;
uint8_t idx;
for (idx = 0; idx < 8; idx++) {
drvp->fb[SSD1306_WIDTH_FIXED * idx] = 0x40;
memset(&drvp->fb[SSD1306_WIDTH_FIXED * idx + 1],
color == SSD1306_COLOR_BLACK ? 0x00 : 0xff, SSD1306_WIDTH);
}
}
static void drawPixel(void *ip, uint8_t x, uint8_t y, ssd1306_color_t color) {
SSD1306Driver *drvp = (SSD1306Driver *)ip;
if (x > SSD1306_WIDTH || y > SSD1306_HEIGHT) return;
// Check if pixels are inverted
if (drvp->inv) {
color = (ssd1306_color_t)!color;
}
// Set color
if (color == SSD1306_COLOR_WHITE) {
drvp->fb[x + (y / 8) * SSD1306_WIDTH_FIXED + 1] |= 1 << (y % 8);
} else {
drvp->fb[x + (y / 8) * SSD1306_WIDTH_FIXED + 1] &= ~(1 << (y % 8));
}
}
static void gotoXy(void *ip, uint8_t x, uint8_t y) {
SSD1306Driver *drvp = (SSD1306Driver *)ip;
drvp->x = x;
drvp->y = y;
}
static char PUTC(void *ip, char ch, const ssd1306_font_t *font, ssd1306_color_t color) {
SSD1306Driver *drvp = (SSD1306Driver *)ip;
uint32_t i, b, j;
// Check available space in OLED
if (drvp->x + font->fw >= SSD1306_WIDTH ||
drvp->y + font->fh >= SSD1306_HEIGHT) {
return 0;
}
// Go through font
for (i = 0; i < font->fh; i++) {
b = font->dt[(ch - 32) * font->fh + i];
for (j = 0; j < font->fw; j++) {
if ((b << j) & 0x8000) {
drawPixel(drvp, drvp->x + j, drvp->y + i, color);
} else {
drawPixel(drvp, drvp->x + j, drvp->y + i,(ssd1306_color_t)! color);
}
}
}
//dirty hack for 7x10 font
/* for (i = 0; i < font->fh; i++) {
b = font->dt[(ch - 32) * font->fh + i];
for (j = 1; j < (uint32_t)(font->fw + 1); j++) {
if ((b << j) & 0x8000) {
drawPixel(drvp, drvp->x + j, drvp->y + i + 1, color);
} else {
drawPixel(drvp, drvp->x + j, drvp->y + i + 1,(ssd1306_color_t)! color);
}
}
}
*/
// Increase pointer
drvp->x += font->fw;
// Return character written
return ch;
}
static char PUTS(void *ip, char *str, const ssd1306_font_t *font, ssd1306_color_t color) {
// Write characters
while (*str) {
// Write character by character
if (PUTC(ip, *str, font, color) != *str) {
// Return error
return *str;
}
// Increase string pointer
str++;
}
// Everything OK, zero should be returned
return *str;
}
static void setDisplay(void *ip, uint8_t on) {
wrCmd(ip, 0x8D);
wrCmd(ip, on ? 0x14 : 0x10);
wrCmd(ip, 0xAE);
}
static const struct SSD1306VMT vmt_ssd1306 = {
updateScreen, toggleInvert, fillScreen, drawPixel,
gotoXy, PUTC, PUTS, setDisplay
};
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
void ssd1306ObjectInit(SSD1306Driver *devp) {
devp->vmt = &vmt_ssd1306;
devp->config = NULL;
devp->state = SSD1306_STOP;
}
void ssd1306Start(SSD1306Driver *devp, const SSD1306Config *config) {
const uint8_t cmds[] = {
0xAE, // display off
0x20, // Set memory address
0x10, // 0x00: horizontal addressing mode, 0x01: vertical addressing mode
// 0x10: Page addressing mode(RESET), 0x11: invalid
0xB0, // Set page start address for page addressing mode: 0 ~ 7
0xC8, // Set COM output scan direction
0x00, // Set low column address
0x10, // Set height column address
0x40, // Set start line address
0x81, // Set contrast control register
0xFF,
0xA1, // Set segment re-map 0 to 127
0xA6, // Set normal display
0xA8, // Set multiplex ratio(1 to 64)
0x3F,
0xA4, // 0xa4: ouput follows RAM content, 0xa5: ouput ignores RAM content
0xD3, // Set display offset
0x00, // Not offset
0xD5, // Set display clock divide ratio/oscillator frequency
0xF0, // Set divide ration
0xD9, // Set pre-charge period
0x22,
0xDA, // Set COM pins hardware configuration
0x12,
0xDB, // Set VCOMH
0x20, // 0x20: 0.77*Vcc
0x8D, // Set DC-DC enable
0x14,
0xAF, // turn on SSD1306panel
};
uint8_t idx;
chDbgCheck((devp != NULL) && (config != NULL));
chDbgAssert((devp->state == SSD1306_STOP) || (devp->state == SSD1306_READY),
"ssd1306Start(), invalid state");
devp->config = config;
// A little delay
chThdSleepMilliseconds(100);
// OLED initialize
for (idx = 0; idx < sizeof(cmds) / sizeof(cmds[0]); idx++) {
wrCmd(devp, cmds[idx]);
}
// Clear screen
fillScreen(devp, SSD1306_COLOR_WHITE);
// Update screen
updateScreen(devp);
// Set default value
devp->x = 0;
devp->y = 0;
devp->state = SSD1306_READY;
}
void ssd1306Stop(SSD1306Driver *devp) {
chDbgAssert((devp->state == SSD1306_STOP) || (devp->state == SSD1306_READY),
"ssd1306Stop(), invalid state");
if (devp->state == SSD1306_READY) {
// Turn off display
setDisplay(devp, 0);
}
devp->state = SSD1306_STOP;
}
#ifndef __SSD1306_H__
#define __SSD1306_H__
#include "hal.h"
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if !HAL_USE_I2C
#error "SSD1306 requires HAL_USE_I2C"
#endif
#define SSD1306_WIDTH 128
#define SSD1306_HEIGHT 64
#define SSD1306_WIDTH_FIXED (SSD1306_WIDTH + 1)
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
typedef enum {
SSD1306_COLOR_BLACK = 0x00,
SSD1306_COLOR_WHITE = 0x01
} ssd1306_color_t;
typedef struct {
uint8_t fw;
uint8_t fh;
const uint16_t *dt;
} ssd1306_font_t;
typedef enum {
SSD1306_SAD_0X78 = (0x78 >> 1),
SSD1306_SAD_0X7A = (0x7A >> 1)
} ssd1306_sad_t;
typedef enum {
SSD1306_UNINIT = 0,
SSD1306_STOP = 1,
SSD1306_READY = 2,
} ssd1306_state_t;
typedef struct {
I2CDriver *i2cp;
const I2CConfig *i2ccfg;
ssd1306_sad_t sad;
} SSD1306Config;
#define _ssd1306_methods \
void (*updateScreen)(void *ip); \
void (*toggleInvert)(void *ip); \
void (*fillScreen)(void *ip, ssd1306_color_t color); \
void (*drawPixel)(void *ip, uint8_t x, uint8_t y, ssd1306_color_t color); \
void (*gotoXy)(void *ip, uint8_t x, uint8_t y); \
char (*putc)(void *ip, char ch, const ssd1306_font_t *font, ssd1306_color_t color); \
char (*puts)(void *ip, char *str, const ssd1306_font_t *font, ssd1306_color_t color); \
void (*setDisplay)(void *ip, uint8_t on);
struct SSD1306VMT {
_ssd1306_methods
};
#define _ssd1306_data \
ssd1306_state_t state; \
const SSD1306Config *config; \
typedef struct SSD1306Driver {
const struct SSD1306VMT *vmt;
_ssd1306_data;
uint8_t x;
uint8_t y;
uint8_t inv;
uint8_t fb[SSD1306_WIDTH_FIXED * SSD1306_HEIGHT / 8];
} SSD1306Driver;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
#define ssd1306UpdateScreen(ip) \
(ip)->vmt->updateScreen(ip)
#define ssd1306ToggleInvert(ip) \
(ip)->vmt->toggleInvert(ip)
#define ssd1306FillScreen(ip, color) \
(ip)->vmt->fillScreen(ip, color)
#define ssd1306DrawPixel(ip, x, y, color) \
(ip)->vmt->drawPixel(ip, x, y, color)
#define ssd1306GotoXy(ip, x, y) \
(ip)->vmt->gotoXy(ip, x, y)
#define ssd1306Putc(ip, ch, font, color) \
(ip)->vmt->putc(ip, ch, font, color)
#define ssd1306Puts(ip, str, font, color) \
(ip)->vmt->puts(ip, str, font, color)
#define ssd1306SetDisplay(ip, on) \
(ip)->vmt->setDisplay(ip, on)
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
extern const ssd1306_font_t ssd1306_font_11x18;
void ssd1306ObjectInit(SSD1306Driver *devp);
void ssd1306Start(SSD1306Driver *devp, const SSD1306Config *config);
void ssd1306Stop(SSD1306Driver *devp);
#ifdef __cplusplus
}
#endif
#endif /* __SSD1306_H__ */
This diff is collapsed.
/* Steal from https://stm32f4-discovery.net/2015/05/library-61-ssd1306-oled-i2c-lcd-for-stm32f4xx/ */
static const uint16_t FONT_7x10_DATA[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp
0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000, // !
0x2800, 0x2800, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // "
0x2400, 0x2400, 0x7C00, 0x2400, 0x4800, 0x7C00, 0x4800, 0x4800, 0x0000, 0x0000, // #
0x3800, 0x5400, 0x5000, 0x3800, 0x1400, 0x5400, 0x5400, 0x3800, 0x1000, 0x0000, // $
0x2000, 0x5400, 0x5800, 0x3000, 0x2800, 0x5400, 0x1400, 0x0800, 0x0000, 0x0000, // %
0x1000, 0x2800, 0x2800, 0x1000, 0x3400, 0x4800, 0x4800, 0x3400, 0x0000, 0x0000, // &
0x1000, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // '
0x0800, 0x1000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x1000, 0x0800, // (
0x2000, 0x1000, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x1000, 0x2000, // )
0x1000, 0x3800, 0x1000, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // *
0x0000, 0x0000, 0x1000, 0x1000, 0x7C00, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, // +
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000, // ,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3800, 0x0000, 0x0000, 0x0000, 0x0000, // -
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, // .
0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x0000, 0x0000, // /
0x3800, 0x4400, 0x4400, 0x5400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 0
0x1000, 0x3000, 0x5000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // 1
0x3800, 0x4400, 0x4400, 0x0400, 0x0800, 0x1000, 0x2000, 0x7C00, 0x0000, 0x0000, // 2
0x3800, 0x4400, 0x0400, 0x1800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 3
0x0800, 0x1800, 0x2800, 0x2800, 0x4800, 0x7C00, 0x0800, 0x0800, 0x0000, 0x0000, // 4
0x7C00, 0x4000, 0x4000, 0x7800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 5
0x3800, 0x4400, 0x4000, 0x7800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 6
0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000, // 7
0x3800, 0x4400, 0x4400, 0x3800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 8
0x3800, 0x4400, 0x4400, 0x4400, 0x3C00, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 9
0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, // :
0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000, // ;
0x0000, 0x0000, 0x0C00, 0x3000, 0x4000, 0x3000, 0x0C00, 0x0000, 0x0000, 0x0000, // <
0x0000, 0x0000, 0x0000, 0x7C00, 0x0000, 0x7C00, 0x0000, 0x0000, 0x0000, 0x0000, // =
0x0000, 0x0000, 0x6000, 0x1800, 0x0400, 0x1800, 0x6000, 0x0000, 0x0000, 0x0000, // >
0x3800, 0x4400, 0x0400, 0x0800, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000, // ?
0x3800, 0x4400, 0x4C00, 0x5400, 0x5C00, 0x4000, 0x4000, 0x3800, 0x0000, 0x0000, // @
0x1000, 0x2800, 0x2800, 0x2800, 0x2800, 0x7C00, 0x4400, 0x4400, 0x0000, 0x0000, // A
0x7800, 0x4400, 0x4400, 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x0000, 0x0000, // B
0x3800, 0x4400, 0x4000, 0x4000, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // C
0x7000, 0x4800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4800, 0x7000, 0x0000, 0x0000, // D
0x7C00, 0x4000, 0x4000, 0x7C00, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000, // E
0x7C00, 0x4000, 0x4000, 0x7800, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // F
0x3800, 0x4400, 0x4000, 0x4000, 0x5C00, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // G
0x4400, 0x4400, 0x4400, 0x7C00, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // H
0x3800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3800, 0x0000, 0x0000, // I
0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // J
0x4400, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000, // K
0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000, // L
0x4400, 0x6C00, 0x6C00, 0x5400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // M
0x4400, 0x6400, 0x6400, 0x5400, 0x5400, 0x4C00, 0x4C00, 0x4400, 0x0000, 0x0000, // N
0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // O
0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // P
0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x5400, 0x3800, 0x0400, 0x0000, // Q
0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000, // R
0x3800, 0x4400, 0x4000, 0x3000, 0x0800, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // S
0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // T
0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // U
0x4400, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x1000, 0x0000, 0x0000, // V
0x4400, 0x4400, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000, // W
0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, // X
0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // Y
0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000, // Z
0x1800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1800, // [
0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x0000, 0x0000, /* \ */
0x3000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3000, // ]
0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFE00, // _
0x2000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // `
0x0000, 0x0000, 0x3800, 0x4400, 0x3C00, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // a
0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x0000, 0x0000, // b
0x0000, 0x0000, 0x3800, 0x4400, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // c
0x0400, 0x0400, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // d
0x0000, 0x0000, 0x3800, 0x4400, 0x7C00, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // e
0x0C00, 0x1000, 0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // f
0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x7800, // g
0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // h
0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // i
0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0xE000, // j
0x4000, 0x4000, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4400, 0x0000, 0x0000, // k
0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // l
0x0000, 0x0000, 0x7800, 0x5400, 0x5400, 0x5400, 0x5400, 0x5400, 0x0000, 0x0000, // m
0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // n
0x0000, 0x0000, 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // o
0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x4000, 0x4000, // p
0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x0400, // q
0x0000, 0x0000, 0x5800, 0x6400, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // r
0x0000, 0x0000, 0x3800, 0x4400, 0x3000, 0x0800, 0x4400, 0x3800, 0x0000, 0x0000, // s
0x2000, 0x2000, 0x7800, 0x2000, 0x2000, 0x2000, 0x2000, 0x1800, 0x0000, 0x0000, // t
0x0000, 0x0000, 0x4400, 0x4400, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // u
0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x0000, 0x0000, // v
0x0000, 0x0000, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000, // w
0x0000, 0x0000, 0x4400, 0x2800, 0x1000, 0x1000, 0x2800, 0x4400, 0x0000, 0x0000, // x
0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x6000, // y
0x0000, 0x0000, 0x7C00, 0x0800, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000, // z
0x1800, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1800, // {
0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, // |
0x3000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x3000, // }
0x0000, 0x0000, 0x0000, 0x7400, 0x4C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~
};
const ssd1306_font_t ssd1306_font_7x10 = {
7, 10, FONT_7x10_DATA
};
#include "ch.h"
#include "hal.h"
#include "board.h"
#include "rt_test_root.h"
#include "oslib_test_root.h"
#include <stdio.h>
#include "usbcfg.h"
#include "ssd1306.h"
#define usb_lld_connect_bus(usbp)
#define usb_lld_disconnect_bus(usbp)
static const I2CConfig i2ccfg = {
STM32_TIMINGR_PRESC(8U) | STM32_TIMINGR_SCLDEL(3U) | STM32_TIMINGR_SDADEL(3U) |
STM32_TIMINGR_SCLH(3U) | STM32_TIMINGR_SCLL(9U),
0,
0
};
static const SSD1306Config ssd1306cfg = {
&I2CD1,
&i2ccfg,
SSD1306_SAD_0X78,
};
static SSD1306Driver SSD1306D1;
static THD_WORKING_AREA(waOledDisplay, 1024);
static THD_FUNCTION(OledDisplay, arg) {
(void)arg;
chRegSetThreadName("OledDisplay");
ssd1306ObjectInit(&SSD1306D1);
ssd1306Start(&SSD1306D1, &ssd1306cfg);
ssd1306ToggleInvert(&SSD1306D1);
ssd1306FillScreen(&SSD1306D1, 0x00);
int i = 0;
while (TRUE) {
ssd1306FillScreen(&SSD1306D1, 0x01);
char buf[32] = {0};
ssd1306GotoXy(&SSD1306D1, 0, 1);
ssd1306Puts(&SSD1306D1, "TESTE", &ssd1306_font_11x18, SSD1306_COLOR_WHITE);
ssd1306GotoXy(&SSD1306D1, 0, 32);
ssd1306Puts(&SSD1306D1, "0123456789", &ssd1306_font_11x18, SSD1306_COLOR_WHITE);
ssd1306UpdateScreen(&SSD1306D1);
i++;
chThdSleepMilliseconds(1000);
}
ssd1306Stop(&SSD1306D1);
}
/*
* Green LED blinker thread, times are in milliseconds.
......@@ -13,9 +64,17 @@ static THD_FUNCTION(Thread1, arg) {
chRegSetThreadName("blinker");
while (true) {
palClearLine(LINE_LED0);
chThdSleepMilliseconds(500);
chThdSleepMilliseconds(100);
palSetLine(LINE_LED0);
chThdSleepMilliseconds(500);
chThdSleepMilliseconds(100);
palClearLine(LINE_LED1);
chThdSleepMilliseconds(100);
palSetLine(LINE_LED1);
chThdSleepMilliseconds(100);
palClearLine(LINE_LED2);
chThdSleepMilliseconds(100);
palSetLine(LINE_LED2);
chThdSleepMilliseconds(100);
}
}
......@@ -34,6 +93,18 @@ int main(void) {
halInit();
chSysInit();
palSetPadMode(GPIOA, 11, PAL_MODE_ALTERNATE(14));
palSetPadMode(GPIOA, 12, PAL_MODE_ALTERNATE(14));
sduObjectInit(&SDU1);
sduStart(&SDU1, &serusbcfg1);
sduObjectInit(&SDU2);
sduStart(&SDU2, &serusbcfg2);
usbStart(serusbcfg1.usbp, &usbcfg);
usbConnectBus(serusbcfg1.usbp);
/*
* Activates the serial driver 3 using the driver default configuration.
*/
......@@ -42,19 +113,23 @@ int main(void) {
/*
* Creates the blinker thread.
*/
palSetPadMode(GPIOB, GPIOB_PIN12, PAL_MODE_OUTPUT_PUSHPULL);
palSetLineMode(LINE_LED0, PAL_MODE_OUTPUT_PUSHPULL);
palSetLineMode(LINE_LED1, PAL_MODE_OUTPUT_PUSHPULL);
palSetLineMode(LINE_LED2, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4));
palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4));
palSetPadMode(GPIOB, 10, PAL_MODE_ALTERNATE(7));
palSetPadMode(GPIOB, 11, PAL_MODE_ALTERNATE(7));
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
chThdCreateStatic(waThread1, sizeof(waOledDisplay), NORMALPRIO, OledDisplay, NULL);
/*
* Normal main() thread activity, in this demo it does nothing except
* sleeping in a loop and check the button state.
*/
while (true) {
test_execute((BaseSequentialStream *)&SD3, &rt_test_suite);
test_execute((BaseSequentialStream *)&SD3, &oslib_test_suite);
chThdSleepMilliseconds(500);
}
}
This diff is collapsed.
/*
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef USBCFG_H
#define USBCFG_H
extern const USBConfig usbcfg;
extern SerialUSBConfig serusbcfg1;
extern SerialUSBConfig serusbcfg2;
extern SerialUSBDriver SDU1;
extern SerialUSBDriver SDU2;
#endif /* USBCFG_H */
/** @} */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment