updated RGBLEDscrn

This commit is contained in:
Edward Emelianov 2021-04-20 01:36:01 +03:00
parent a438f0515f
commit 59fe90b9e0
7 changed files with 100 additions and 55 deletions

View File

@ -310,12 +310,12 @@ const afont *curfont = &FONTS[FONT14];
/**
* @brief choose_font - font selector
* @param newfont - font to choose
* @return 0 if all OK
* @return 1 if all OK
*/
int choose_font(font_t newfont){
if(newfont >= FONT_T_MAX || newfont <= FONT_T_MIN) return 1;
if(newfont >= FONT_T_MAX || newfont <= FONT_T_MIN) return 0;
curfont = &FONTS[newfont];
return 0;
return 1;
}
/*
// getters for current font values

View File

@ -28,6 +28,29 @@ uint8_t transfer_done = 0; // ==1 when DMA transfer ready
// buffer for DMA
static uint32_t dmabuf[SCREEN_WIDTH];
void iwdg_setup(){
uint32_t tmout = 16000000;
/* Enable the peripheral clock RTC */
/* (1) Enable the LSI (40kHz) */
/* (2) Wait while it is not ready */
RCC->CSR |= RCC_CSR_LSION; /* (1) */
while((RCC->CSR & RCC_CSR_LSIRDY) != RCC_CSR_LSIRDY){if(--tmout == 0) break;} /* (2) */
/* Configure IWDG */
/* (1) Activate IWDG (not needed if done in option bytes) */
/* (2) Enable write access to IWDG registers */
/* (3) Set prescaler by 64 (1.6ms for each tick) */
/* (4) Set reload value to have a rollover each 2s */
/* (5) Check if flags are reset */
/* (6) Refresh counter */
IWDG->KR = IWDG_START; /* (1) */
IWDG->KR = IWDG_WRITE_ACCESS; /* (2) */
IWDG->PR = IWDG_PR_PR_1; /* (3) */
IWDG->RLR = 1250; /* (4) */
tmout = 16000000;
while(IWDG->SR){if(--tmout == 0) break;} /* (5) */
IWDG->KR = IWDG_REFRESH; /* (6) */
}
static inline void gpio_setup(){
// Enable clocks to the GPIO subsystems, turn on AFIO clocking to disable SWD/JTAG
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_AFIOEN;
@ -49,13 +72,14 @@ static inline void gpio_setup(){
// setup timer3 for DMA transfers & SCK @ TIM3_CH1 (PA6)
static inline void tim_setup(){
SET(nOE); // turn off output
SCRN_DISBL(); // turn off output
GPIOA->CRL |= CRL(6, CNF_AFPP|MODE_FAST);
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
// 72MHz & 7ARR = 9MHz
TIM3->PSC = 20000;
TIM3->ARR = 7;
// PCS=1 don't work;
TIM3->PSC = 9; // 7.2MHz
TIM3->ARR = 7; // 900kHz
TIM3->CCMR1 = TIM_CCMR1_OC1M; // PWM mode 2 (inactive->active)
//TIM3->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1; // PWM mode 1 (active->inactive)
TIM3->CCER = TIM_CCER_CC1E; // output 1 enable
TIM3->DIER = TIM_DIER_UDE; // enable DMA requests
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
@ -114,12 +138,12 @@ static inline uint8_t getcolrvals(uint8_t colr, uint8_t Ntick){
* @param Nrow - current row number
* @param Ntick - tick number (0..7) for quasi-PWM colors
*/
void ConvertScreenBuf(uint8_t *sbuf, uint8_t Nrow, __attribute__((unused)) uint8_t Ntick){
void ConvertScreenBuf(uint8_t *sbuf, uint8_t Nrow, uint8_t Ntick){ // __attribute__((unused))
//USB_send("ConvertScreenBuf\n");
uint8_t *_1st = &sbuf[SCREEN_WIDTH*Nrow], *_2nd = _1st + SCREEN_WIDTH*NBLOCKS; // first and second lines
for(int i = 0; i < SCREEN_WIDTH; ++i){ // ~50us for 64 pixels
uint8_t pinsset = getcolrvals(_1st[i], 0);
pinsset |= getcolrvals(_2nd[i], 0) << 3;
uint8_t pinsset = getcolrvals(_1st[i], Ntick);
pinsset |= getcolrvals(_2nd[i], Ntick) << 3;
//dmabuf[i] = (i%2) ? ((COLR_pin<<16) | i) : (0b100010);
dmabuf[i] = (COLR_pin << 16) | pinsset; // All BR are 1, BS depending on color
}
@ -147,16 +171,18 @@ void TIM_DMA_transfer(uint8_t blknum){
// DMA transfer complete - stop transfer
void dma1_channel3_isr(){
TIM3->SR = 0;
TIM3->CR1 |= TIM_CR1_OPM; // set one pulse mode to turn off timer after last CLK pulse
DMA1_Channel3->CCR &= ~DMA_CCR_EN; // stop DMA
while(TIM3->CNT < 7);
SET(nOE); // clear main output
while(!(TIM3->SR & TIM_SR_UIF)); // wait for last pulse
//while(TIM3->CNT < 7);
SCRN_DISBL(); // clear main output
ADDR_port->ODR = (ADDR_port->ODR & ~(ADDR_pin)) | (blknum_curr << ADDR_roll); // set address
SET(LAT); // activate latch
DMA1->IFCR = DMA_IFCR_CGIF3;
transfer_done = 1;
CLEAR(LAT);
CLEAR(nOE); // activate main output
SCRN_ENBL(); // activate main output
//USB_send("transfer done\n");
}

View File

@ -27,8 +27,10 @@
#include "stm32f1.h"
#include "screen.h"
// define this if screen is negative
// define this if screen colors are negative
// #define SCREEN_IS_NEGATIVE
// define if nOE is negative
#define NOE_IS_NEGATIVE
// LED0 - PC13 (bluepill), blinking each second
#define LED0_port GPIOC
@ -62,6 +64,15 @@
#define CLEAR(x) pin_clear(x ## _port, x ## _pin)
#define TOGGLE(x) pin_toggle(x ## _port, x ## _pin)
#ifdef NOE_IS_NEGATIVE
#define SCRN_ENBL() SET(nOE)
#define SCRN_DISBL() CLEAR(nOE)
#else
#define SCRN_ENBL() CLEAR(nOE)
#define SCRN_DISBL() SET(nOE)
#endif
void iwdg_setup();
void hw_setup();
void TIM_DMA_transfer(uint8_t blknum);
void stopTIMDMA();

View File

@ -27,36 +27,13 @@
#include "usb_lib.h"
volatile uint32_t Tms = 0;
uint8_t countms = 0;
uint8_t countms = 0, rainbow = 0;
/* Called when systick fires */
void sys_tick_handler(void){
++Tms;
}
void iwdg_setup(){
uint32_t tmout = 16000000;
/* Enable the peripheral clock RTC */
/* (1) Enable the LSI (40kHz) */
/* (2) Wait while it is not ready */
RCC->CSR |= RCC_CSR_LSION; /* (1) */
while((RCC->CSR & RCC_CSR_LSIRDY) != RCC_CSR_LSIRDY){if(--tmout == 0) break;} /* (2) */
/* Configure IWDG */
/* (1) Activate IWDG (not needed if done in option bytes) */
/* (2) Enable write access to IWDG registers */
/* (3) Set prescaler by 64 (1.6ms for each tick) */
/* (4) Set reload value to have a rollover each 2s */
/* (5) Check if flags are reset */
/* (6) Refresh counter */
IWDG->KR = IWDG_START; /* (1) */
IWDG->KR = IWDG_WRITE_ACCESS; /* (2) */
IWDG->PR = IWDG_PR_PR_1; /* (3) */
IWDG->RLR = 1250; /* (4) */
tmout = 16000000;
while(IWDG->SR){if(--tmout == 0) break;} /* (5) */
IWDG->KR = IWDG_REFRESH; /* (6) */
}
#define USBBUFSZ (127)
// usb getline
static char *get_USB(){
@ -79,8 +56,17 @@ static char *get_USB(){
return NULL;
}
static void nxtrainbow(){
for(int i = 0; i < SCREEN_WIDTH; ++i){
for(int j = 0; j < SCREEN_HEIGHT; ++j){
DrawPix(i, j, rainbow + i);
}
}
if(++rainbow == 0) rainbow = 1;
}
int main(void){
uint32_t lastT = 0, mscnt = 0, Tmscnt = 0;
uint32_t lastT = 0, mscnt = 0, Tmscnt = 0, lastR = 0;
sysreset();
StartHSE();
SysTick_Config(72000);
@ -89,7 +75,7 @@ int main(void){
hw_setup();
USBPU_OFF();
USB_setup();
PutStringAt(5, SCREEN_HEIGHT-1-curfont->baseline, "Test string");
PutStringAt(1, SCREEN_HEIGHT-1-curfont->baseline, "Test string");
iwdg_setup();
USBPU_ON();
@ -107,7 +93,7 @@ int main(void){
if(Tms - Tmscnt > 99){
Tmscnt = Tms;
ClearScreen();
PutStringAt(5, SCREEN_HEIGHT-1-curfont->baseline, u2str(++mscnt));
PutStringAt(5, curfont->height + 1, u2str(++mscnt));
ScreenON();
}
}
@ -115,6 +101,10 @@ int main(void){
mscnt = 0;
Tmscnt = 0;
}
if(rainbow && Tms - lastR > 99){
lastR = Tms;
nxtrainbow();
}
IWDG->KR = IWDG_REFRESH;
process_screen();
usb_proc();

View File

@ -21,7 +21,7 @@
#include "screen.h"
#include "usb.h"
extern uint8_t countms;
extern uint8_t countms, rainbow;
char *omit_spaces(const char *buf){
while(*buf){
@ -156,6 +156,7 @@ char *getnum(const char *txt, uint32_t *N){
const char* helpmsg =
"'0/1' - screen off/on\n"
"'2,3' - select font\n"
"'B' - start/stop rainBow\n"
"'C' - clear screen with given color\n"
"'F' - set foreground color\n"
"'f' - get FPS\n"
@ -178,12 +179,21 @@ const char *parse_cmd(const char *buf){
return "ON\n";
break;
case '2':
choose_font(FONT14);
return "Font14\n";
if(choose_font(FONT14)) return "Font14\n";
return "err\n";
break;
case '3':
choose_font(FONT16);
return "Font16\n";
if(choose_font(FONT16)) return "Font16\n";
return "err\n";
break;
case 'B':
if(rainbow){
rainbow = 0;
return "Stop rainbow\n";
}else{
rainbow = 1;
return "Start rainbow\n";
}
break;
case 'f':
if(SCREEN_RELAX == getScreenState()) return "Screen is inactive\n";
@ -233,7 +243,7 @@ const char *parse_cmd(const char *buf){
default:
ScreenOFF();
ClearScreen();
PutStringAt(5, SCREEN_HEIGHT-1-curfont->baseline, buf);
PutStringAt(1, curfont->height + 3, buf);
ScreenON();
}
return buf;

View File

@ -46,12 +46,20 @@ void setFGcolor(uint8_t c){fgColor = c;}
void ClearScreen(){
for(int i = 0; i < SCREENBUF_SZ; ++i)
screenbuf[i] = bgColor;
for(int i = 0; i < 32; ++i){
DrawPix(0,i,0b11111111); // white
DrawPix(27,i,0b11100000); // red
DrawPix(34,i,0b00011100); // green
DrawPix(63,i,0b00000011); // blue
}
/*for(int i = 0; i < 32; ++i){
DrawPix(0,i,0b11111111);
DrawPix(1,i,0b1001010);
DrawPix(2,i,0b00100101);
DrawPix(20,i,0b11100000);
DrawPix(21,i,0b10000000);
DrawPix(22,i,0b00100000);
DrawPix(30,i,0b00011100);
DrawPix(31,i,0b00010000);
DrawPix(32,i,0b00000100);
DrawPix(60,i,0b00000011);
DrawPix(61,i,0b00000010);
DrawPix(62,i,0b00000001);
}*/
// memset -> halt
//memset(screenbuf, pattern, SCREENBUF_SZ);
}
@ -90,7 +98,7 @@ uint8_t DrawCharAt(int16_t X, int16_t Y, uint8_t Char){
// height and width of letter in pixels
uint8_t h = curfont->height, w = *curchar++; // now curchar is pointer to bits array
uint8_t lw = curfont->bytes / h; // width of letter in bytes
for(uint8_t row = 0; row <= h; ++row){
for(uint8_t row = 0; row < h; ++row){
for(uint8_t col = 0; col < w; ++col){
if(curchar[row*lw + (col/8)] & (1 << (7 - (col%8))))
DrawPix(X + col, Y + row, fgColor);
@ -167,7 +175,7 @@ void ScreenON(){
void ScreenOFF(){
stopTIMDMA();
SET(nOE);
SCRN_DISBL();
ScrnState = SCREEN_RELAX;
currentB = 0;
Ntick = 0;