この前よりもちょっと大きい液晶に表示させてみました!
— いぬにゃん (@inunyann) June 24, 2024
嫁がかわいいです!!
(先日と同じくch32v003(動画右のソケットに入った小さいチップ)を使っています) pic.twitter.com/Md683K01f2
今日も1日がんばるぞぃ!
— いぬにゃん (@inunyann) July 2, 2023
昨日の日記。ch32v003でも、いぬにゃん表示と、ロータリエンコーダ(Encoder mode)での速度変更出来たので満足です。twitterくんの制限でお返しできずにすみません!リプも出来ませんでした…今日も引っかかるかもしれません…が、今週もよろしくお願い致します! pic.twitter.com/EL7VG18AyA
void Adafruit_NeoPixel::show(void) {
if (!pixels) return;
while (!canShow());
uint8_t *ptr, *end, p, bitMask;
uint16_t pinMask;
ptr = pixels;
end = ptr + numBytes;
p = *ptr++;
bitMask = 0x80;
GPIO_TypeDef *GPIOx = digitalPinToPort(pin);
pinMask = digitalPinToBitMask(pin);
__disable_irq();
//#define SYSCLK_FREQ_48MHZ_HSx 1
#if defined(NEO_KHZ400) // 800 KHz check needed only if 400 KHz support enabled
if (is800KHz) {
#endif
for (;;) {
if (p & bitMask) { // ONE
// High 600ns
GPIOx->BSHR = pinMask;
asm volatile ("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"); // 1nop = 41.7ns? @ 24MHz
#if defined(SYSCLK_FREQ_48MHZ_HSx)
asm volatile ("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"); // 1nop = 20.8ns? @ 48MHz
#endif
// Low 300ns
GPIOx->BCR = pinMask;
asm volatile ("");
#if defined(SYSCLK_FREQ_48MHZ_HSx)
asm volatile ("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;");
#endif
} else { // ZERO
// High 300ns
GPIOx->BSHR = pinMask;
asm volatile ("nop; nop; nop; nop; nop;");
#if defined(SYSCLK_FREQ_48MHZ_HSx)
asm volatile ("nop; nop; nop; nop; nop; nop; nop;");
#endif
// Low 600ns
GPIOx->BCR = pinMask;
asm volatile ("nop; nop; nop; nop; nop;");
#if defined(SYSCLK_FREQ_48MHZ_HSx)
asm volatile ("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;");
#endif
}
if (bitMask >>= 1) {
asm volatile ("nop; nop; nop; nop; nop;");
} else {
if (ptr >= end) break;
p = *ptr++;
bitMask = 0x80;
}
}
#if defined(NEO_KHZ400)
} else { // 400 KHz bitstream
// ToDo!
}
#endif
__enable_irq();
endTime = micros(); // Save EOD time for latch on next call
}
void analogWrite(uint8_t duty) { // PD0(8) or PD2(19), ch4:PC4(14)
TIM_SetCompare1(TIM1, duty); // ,4
}
void analogInit(uint16_t freq = 1000) { // PD0(8) or PD2(19), ch4:PC4(14)
SystemCoreClockUpdate();
uint32_t psc = SystemCoreClock / 256 / freq;
if (psc >> 16) psc = 0xffff;
else if (psc) psc--;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); // ,C
GPIO_InitTypeDef gpioD0;
gpioD0.GPIO_Pin = GPIO_Pin_0; // or 2, 4
gpioD0.GPIO_Speed = GPIO_Speed_2MHz;
gpioD0.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOD, &gpioD0); // ,C
TIM_TimeBaseInitTypeDef tim1;
tim1.TIM_Period = 255;
tim1.TIM_Prescaler = psc;
tim1.TIM_ClockDivision = TIM_CKD_DIV1;
tim1.TIM_CounterMode = TIM_CounterMode_Up;
tim1.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &tim1);
TIM_OCInitTypeDef oc1;
oc1.TIM_OCMode = TIM_OCMode_PWM1;
oc1.TIM_OutputState = TIM_OutputState_Disable; // or En, En
oc1.TIM_OutputNState = TIM_OutputNState_Enable; // or Dis, Dis
oc1.TIM_Pulse = 0;
oc1.TIM_OCPolarity = TIM_OCPolarity_High;
oc1.TIM_OCNPolarity = TIM_OCPolarity_High;
oc1.TIM_OCIdleState = TIM_OCIdleState_Reset;
oc1.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
TIM_OC1Init(TIM1, &oc1); // ,4
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Disable); // ,4
TIM_ARRPreloadConfig(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
TIM_Cmd(TIM1, ENABLE);
}
void analogStop() {
TIM_Cmd(TIM1, DISABLE);
TIM_CtrlPWMOutputs(TIM1, DISABLE);
pinMode(PD0, INPUT_PULLUP); // or PD2, PC4
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, DISABLE);
}
#define getEncoderCount() TIM_GetCounter(TIM2)
void encoderInit() {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
pinMode(PD4, INPUT_PULLUP); // T2CH1 : PD4(1)
pinMode(PD3, INPUT_PULLUP); // T2CH2 : PD3(20)
TIM_TimeBaseInitTypeDef tim2;
tim2.TIM_Period = 0xffff;
tim2.TIM_Prescaler = 1;
tim2.TIM_ClockDivision = TIM_CKD_DIV1;
tim2.TIM_CounterMode = TIM_CounterMode_Up;
tim2.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &tim2);
TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI1, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
TIM_SetCounter(TIM2, 0);
TIM_Cmd(TIM2, ENABLE);
}
void encoderStop() {
TIM_Cmd(TIM2, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, DISABLE);
}
#define TOUCH_THRESHOLD 20
uint16_t MeasureTouch(int16_t pin) {
uint32_t starttime, endtime;
GPIO_TypeDef *GPIOx = digitalPinToPort(pin);
uint16_t pinMask = digitalPinToBitMask(pin);
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
GPIOx->CFGLR = 0x00000008 << 4 * digitalPinToPinName(pin);
GPIOx->BSHR = pinMask;
starttime = SysTick->CNT;
while (!(GPIOx->INDR & pinMask));
endtime = SysTick->CNT;
return (uint16_t)(endtime - starttime);
}
bool isTouched(int16_t pin) {
SystemCoreClockUpdate();
uint32_t clk = SystemCoreClock;
if (clk != 24000000) SetSysClockTo_24MHZ_HSI();
uint16_t touch = MeasureTouch(pin);
if (clk == 93750) SetSysClockTo_94KHz_HSI();
else if (clk == 750000) SetSysClockTo_750KHz_HSI();
else if (clk == 6000000) SetSysClockTo_6MHZ_HSI();
return touch > TOUCH_THRESHOLD ? true : false;
}
volatile uint16_t adcDmaData[4]; // 4 chs
void startAdcDma() {
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div128);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
DMA_InitTypeDef dma;
dma.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->RDATAR;
dma.DMA_MemoryBaseAddr = (uint32_t)&adcDmaData;
dma.DMA_DIR = DMA_DIR_PeripheralSRC;
dma.DMA_BufferSize = sizeof(adcDmaData) / sizeof(adcDmaData[0]);
dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
dma.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
dma.DMA_Mode = DMA_Mode_Circular;
dma.DMA_Priority = DMA_Priority_Medium;
dma.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &dma);
DMA_Cmd(DMA1_Channel1, ENABLE);
GPIO_InitTypeDef gpio;
gpio.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_4; // PD2(A3), PD3(A4), PD6(A6), PD4(A7)
gpio.GPIO_Speed = GPIO_Speed_2MHz;
gpio.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOD, &gpio);
ADC_InitTypeDef adc;
adc.ADC_Mode = ADC_Mode_Independent;
adc.ADC_ScanConvMode = ENABLE;
adc.ADC_ContinuousConvMode = ENABLE;
adc.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
adc.ADC_DataAlign = ADC_DataAlign_Right;
adc.ADC_NbrOfChannel = sizeof(adcDmaData) / sizeof(adcDmaData[0]);
ADC_Init(ADC1, &adc);
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_241Cycles); // PD2(A3)
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 2, ADC_SampleTime_241Cycles); // PD3(A4)
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 3, ADC_SampleTime_241Cycles); // PD6(A6)
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 4, ADC_SampleTime_241Cycles); // PD4(A7)
//ADC_RegularChannelConfig(ADC1, ADC_Channel_Vrefint, 5, ADC_SampleTime_241Cycles);
//ADC_RegularChannelConfig(ADC1, ADC_Channel_Vcalint, 6, ADC_SampleTime_241Cycles);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while (ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1));
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
void stopAdcDma() {
ADC_SoftwareStartConvCmd(ADC1, DISABLE);
ADC_Cmd(ADC1, DISABLE);
ADC_DMACmd(ADC1, DISABLE);
DMA_Cmd(DMA1_Channel1, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, DISABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, DISABLE);
}
●spiカラー液晶表示ライブラリ(共通コードと、サンプルとしてST7789用のもの CSピンの操作はバイトごとに必須ではないと思うので、まとめれば高速化できると思います)
#include "lcd_gfxfont.h" // &DejaVu9, &DejaVu12, &DejaVu18
#include "font/font5x7.h" // &font5x7
const GFXfont font5x7 = { (uint8_t*)0, (GFXglyph*)0, 0, 0, 8 };
void lcd_ClearScreen(uint16_t color = 0x0000);
void lcd_SetAddressWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1);
void lcd_PushColor(uint16_t color);
#define lcd_PushColorF(color) do { uint16_t c = (color); spiDcHigh(); spiCsLow(); SPI1->DATAR = (uint8_t)(c >> 8); while(!(SPI1->STATR & SPI_I2S_FLAG_TXE)); SPI1->DATAR = (uint8_t)c; while(SPI1->STATR & SPI_I2S_FLAG_BSY); spiCsHigh(); } while (0)
void lcd_DrawStringB(uint8_t x, uint8_t y, const char *str, uint16_t color = 0xffff, uint8_t size = 1, GFXfont *f = &font5x7);
void lcd_DrawStringA(uint8_t x, uint8_t y, const char *str, uint16_t color = 0xffff, uint8_t size = 1);
void lcd_DrawString( uint8_t x, uint8_t y, const char *str, uint16_t color = 0xffff, uint16_t bg = 0x0000, uint8_t size = 1);
uint8_t lcd_StringWidthA(const char *str);
uint8_t lcd_StringWidth( const char *str, GFXfont *f = &font5x7);
void lcd_DrawCharB(uint8_t x, uint8_t y, char c, uint16_t color = 0xffff, uint8_t size = 1, GFXfont *f = &font5x7);
void lcd_DrawCharA(uint8_t x, uint8_t y, char c, uint16_t color = 0xffff, uint8_t size = 1);
void lcd_DrawChar( uint8_t x, uint8_t y, char c, uint16_t color = 0xffff, uint16_t bg = 0x0000, uint8_t size = 1);
void lcd_DrawPixel(uint8_t x, uint8_t y, uint16_t color);
void lcd_DrawVLine(uint8_t x, uint8_t y, uint8_t h, uint16_t color);
void lcd_DrawHLine(uint8_t x, uint8_t y, uint8_t w, uint16_t color);
#define spiWrCmdF(cmd) do { spiDcLow(); spiCsLow(); SPI1->DATAR = (cmd); while(SPI1->STATR & SPI_I2S_FLAG_BSY); spiCsHigh(); } while (0)
#define spiWrDataF(data) do { spiDcHigh(); spiCsLow(); SPI1->DATAR = (data); while(SPI1->STATR & SPI_I2S_FLAG_BSY); spiCsHigh(); } while (0)
void spiWrCmd(uint8_t cmd) {
spiDcLow();
spiCsLow();
SPI1->DATAR = cmd;
while(SPI1->STATR & SPI_I2S_FLAG_BSY);
spiCsHigh();
}
void spiWrData(uint8_t data) {
spiDcHigh();
spiCsLow();
SPI1->DATAR = data;
while(SPI1->STATR & SPI_I2S_FLAG_BSY);
spiCsHigh();
}
void lcd_SetAddressWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) {
spiWrCmdF(0x2a); // CMD_CASET Column addr set
spiDcHigh();
spiCsLow();
SPI1->DATAR = 0x00;
while(!(SPI1->STATR & SPI_I2S_FLAG_TXE));
SPI1->DATAR = LCD_OFFSET_X + x0;
while(!(SPI1->STATR & SPI_I2S_FLAG_TXE));
SPI1->DATAR = 0x00;
while(!(SPI1->STATR & SPI_I2S_FLAG_TXE));
SPI1->DATAR = LCD_OFFSET_X + x1;
while(SPI1->STATR & SPI_I2S_FLAG_BSY);
spiCsHigh();
spiWrCmdF(0x2b); // CMD_RASET Row addr set
spiDcHigh();
spiCsLow();
SPI1->DATAR = 0x00;
while(!(SPI1->STATR & SPI_I2S_FLAG_TXE));
SPI1->DATAR = LCD_OFFSET_Y + y0;
while(!(SPI1->STATR & SPI_I2S_FLAG_TXE));
SPI1->DATAR = 0x00;
while(!(SPI1->STATR & SPI_I2S_FLAG_TXE));
SPI1->DATAR = LCD_OFFSET_Y + y1;
while(SPI1->STATR & SPI_I2S_FLAG_BSY);
spiCsHigh();
spiWrCmdF(0x2c); // CMD_RAMWR Write to RAM
}
void lcd_PushColor(uint16_t color) {
spiDcHigh();
spiCsLow();
SPI1->DATAR = (uint8_t)(color >> 8);
while(!(SPI1->STATR & SPI_I2S_FLAG_TXE));
SPI1->DATAR = (uint8_t)color;
while(SPI1->STATR & SPI_I2S_FLAG_BSY);
spiCsHigh();
}
void lcd_DrawPixel(uint8_t x, uint8_t y, uint16_t color) {
lcd_SetAddressWindow(x, y, x, y);
lcd_PushColor(color);
}
void lcd_DrawCharB(uint8_t x, uint8_t y, char c, uint16_t color, uint8_t size, GFXfont *f) {
uint8_t dx, dy, ox, oy;
GFXglyph *g;
if (f->last) {
g = getGlyph((uint8_t)c, f);
dx = g->width; dy = g->height; ox = (uint8_t)g->xOffset; oy = (uint8_t)g->yOffset;
} else {
dx = 5; dy = 8; ox = 0; oy = (uint8_t)(-7);
}
for (uint8_t py = 0; py < dy; py++) {
for (uint8_t px = 0; px < dx; px++) {
uint8_t fontBit;
if (f->last) fontBit = ((uint8_t *)f->bitmap)[g->bitmapOffset + (dx * py + px) / 8] << (dx * py + px) % 8 & 0x80;
else fontBit = font[(uint16_t)c * dx + px] >> py & 0x01;
if (fontBit) {
lcd_SetAddressWindow(x + (px + ox) * size, y + 1 + (oy + py - 1) * size, x + (px + 1 + ox) * size - 1, y + (oy + py) * size);
for (uint8_t i = 0; i < size * size; i++) lcd_PushColorF(color);
}
}
}
}
void lcd_DrawCharA(uint8_t x, uint8_t y, char c, uint16_t color, uint8_t size) {
for (uint8_t py = 0; py < 8; py++) {
for (uint8_t px = 0; px < 5; px++) {
uint8_t fontBit = font[(uint16_t)c * 5 + px] >> py & 0x01;
if (fontBit) {
lcd_SetAddressWindow(x + px * size, y + 1 - (8 - py) * size, x + (px + 1) * size - 1, y - (7 - py) * size);
for (uint8_t i = 0; i < size * size; i++) lcd_PushColorF(color);
}
}
}
}
void lcd_DrawChar(uint8_t x, uint8_t y, char c, uint16_t color, uint16_t bg, uint8_t size) {
lcd_SetAddressWindow(x, y + 1 - 8 * size, x + 6 * size - 1, y);
for (uint8_t py = 0; py < 8; py++) {
for (uint8_t sy = 0; sy < size; sy++) {
for (uint8_t px = 0; px < 6; px++) {
uint8_t fontBit = px < 5 ? font[(uint16_t)c * 5 + px] >> py & 0x01 : 0x00;
for (uint8_t sx = 0; sx < size; sx++) {
if (fontBit) lcd_PushColorF(color);
else lcd_PushColorF(bg);
}
}
}
}
}
void lcd_DrawStringB(uint8_t x, uint8_t y, const char *str, uint16_t color, uint8_t size, GFXfont *f) {
while (*str) {
lcd_DrawCharB(x, y, *str, color, size, f);
if (f->last) x += getGlyph((uint8_t)*str, f)->xAdvance * size;
else x += 6 * size;
str++;
}
}
uint8_t lcd_StringWidth(const char *str, GFXfont *f) {
uint8_t w = 0;
while (*str) {
if (f->last) w += getGlyph((uint8_t)*str, f)->xAdvance;
else w += 6;
str++;
}
return w;
}
void lcd_DrawStringA(uint8_t x, uint8_t y, const char *str, uint16_t color, uint8_t size) {
while (*str) {
lcd_DrawCharA(x, y, *str, color, size);
x += 6 * size;
str++;
}
}
uint8_t lcd_StringWidthA(const char *str) {
return strlen(str) * 6;
}
void lcd_DrawString(uint8_t x, uint8_t y, const char *str, uint16_t color, uint16_t bg, uint8_t size) {
while (*str) {
lcd_DrawChar(x, y, *str, color, bg, size);
x += 6 * size;
str++;
}
}
void lcd_ClearScreen(uint16_t color) {
lcd_SetAddressWindow(0, 0, LCD_WIDTH - 1, LCD_HEIGHT - 1);
spiDcHigh();
spiCsLow();
for (uint16_t i = 0; i < LCD_WIDTH * LCD_HEIGHT; i++) {
while(!(SPI1->STATR & SPI_I2S_FLAG_TXE));
SPI1->DATAR = (uint8_t)((color) >> 8);
while(!(SPI1->STATR & SPI_I2S_FLAG_TXE));
SPI1->DATAR = (uint8_t)(color);
}
while(SPI1->STATR & SPI_I2S_FLAG_BSY);
spiCsHigh();
}
void lcd_DrawVLine(uint8_t x, uint8_t y, uint8_t h, uint16_t color) {
lcd_SetAddressWindow(x, y, x, y + h - 1);
for (uint8_t i = 0; i < h; i++) lcd_PushColorF(color);
}
void lcd_DrawHLine(uint8_t x, uint8_t y, uint8_t w, uint16_t color) {
lcd_SetAddressWindow(x, y, x + w - 1, y);
for (uint8_t i = 0; i < w; i++) lcd_PushColorF(color);
}
#define LCD_WIDTH 240 // or 320
#define LCD_HEIGHT 240
#define LCD_OFFSET_X 0
#define LCD_OFFSET_Y 0
#define spiCsHigh()
#define spiCsLow()
#define spiDcHigh() (GPIOC->BSHR = 1 << 3)
#define spiDcLow() (GPIOC->BCR = 1 << 3)
#define spiRstHigh() (GPIOC->BSHR = 1 << 4)
#define spiRstLow() (GPIOC->BCR = 1 << 4)
#include "lcd_common.h"
void lcd_Init() {
spiDcHigh();
spiRstHigh();
delay(10);
spiRstLow();
delay(10);
spiRstHigh();
delay(150);
spiWrCmd(0xb2); // CMD_PORCTRL
spiWrData(0x0c); spiWrData(0x0c); spiWrData(0x00); spiWrData(0x33); spiWrData(0x33);
spiWrCmd(0xb7); // CMD_GCTRL
spiWrData(0x35);
spiWrCmd(0xbb); // CMD_VCOMS
spiWrData(0x28);
spiWrCmd(0xc0); // CMD_LCMCTRL
spiWrData(0x0c);
spiWrCmd(0xc2); // CMD_VDVVRHEN
spiWrData(0x01); spiWrData(0xff);
spiWrCmd(0xc3); // CMD_VRHS
spiWrData(0x10);
spiWrCmd(0xc4); // CMD_VDVSET
spiWrData(0x20);
spiWrCmd(0xc6); // CMD_FRCTR2
spiWrData(0x0f);
spiWrCmd(0xd0); // CMD_PWCTRL1
spiWrData(0xa4); spiWrData(0xa1);
spiWrCmd(0xb0); // CMD_RAMCTRL
spiWrData(0x00); spiWrData(0xc0);
spiWrCmd(0xe0); // CMD_PVGAMCTRL
spiWrData(0xd0); spiWrData(0x00); spiWrData(0x02); spiWrData(0x07); spiWrData(0x0a); spiWrData(0x28); spiWrData(0x32); spiWrData(0x44);
spiWrData(0x42); spiWrData(0x06); spiWrData(0x0e); spiWrData(0x12); spiWrData(0x14); spiWrData(0x17);
spiWrCmd(0xe1); // CMD_NVGAMCTRL
spiWrData(0xd0); spiWrData(0x00); spiWrData(0x02); spiWrData(0x07); spiWrData(0x0a); spiWrData(0x28); spiWrData(0x31); spiWrData(0x54);
spiWrData(0x47); spiWrData(0x0e); spiWrData(0x1c); spiWrData(0x17); spiWrData(0x1b); spiWrData(0x1e);
spiWrCmd(0x11); // CMD_SLPOUT
delay(130);
spiWrCmd(0x21); // CMD_INVON
spiWrCmd(0x3a); // CMD_COLMOD
spiWrData(0x05); // 16bit mode
spiWrCmd(0x36); // CMD_MADCTL
spiWrData(0x20 | 0x40 | 0x04 | 0x08); // BGR mode, rotation:1 (MAD_MV|MAD_MX|MAD_MH)
lcd_ClearScreen();
spiWrCmd(0x38); // CMD_IDMOFF
spiWrCmd(0x29); // CMD_DISPON
}
void spiInit() { // SPI1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitTypeDef gpioc;
gpioc.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6; // PC5(SCK), PC6(MOSI)
gpioc.GPIO_Speed = GPIO_Speed_50MHz;
gpioc.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOC, &gpioc);
gpioc.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4; // PC3, PC4
gpioc.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &gpioc);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
SPI_InitTypeDef spi;
SPI_StructInit(&spi);
spi.SPI_Direction = SPI_Direction_1Line_Tx;
spi.SPI_Mode = SPI_Mode_Master;
spi.SPI_CPOL = SPI_CPOL_High; // mode 3
spi.SPI_CPHA = SPI_CPHA_2Edge; // mode 3
spi.SPI_NSS = SPI_NSS_Soft;
//spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
SPI_Init(SPI1, &spi);
SPI_Cmd(SPI1, ENABLE);
}
void spiStop() {
SPI_Cmd(SPI1, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, DISABLE);
pinMode(PC3, INPUT);
pinMode(PC4, INPUT);
pinMode(PC5, INPUT);
pinMode(PC6, INPUT);
}