diff --git a/F1-nolib/RGB_LED_Screen/RGBLEDscreen.bin b/F1-nolib/RGB_LED_Screen/RGBLEDscreen.bin index 93a1f02..4af7c82 100755 Binary files a/F1-nolib/RGB_LED_Screen/RGBLEDscreen.bin and b/F1-nolib/RGB_LED_Screen/RGBLEDscreen.bin differ diff --git a/F1-nolib/RGB_LED_Screen/fonts.c b/F1-nolib/RGB_LED_Screen/fonts.c index 6b32759..afd6328 100644 --- a/F1-nolib/RGB_LED_Screen/fonts.c +++ b/F1-nolib/RGB_LED_Screen/fonts.c @@ -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 diff --git a/F1-nolib/RGB_LED_Screen/hardware.c b/F1-nolib/RGB_LED_Screen/hardware.c index 17d0ded..878a5c5 100644 --- a/F1-nolib/RGB_LED_Screen/hardware.c +++ b/F1-nolib/RGB_LED_Screen/hardware.c @@ -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"); } diff --git a/F1-nolib/RGB_LED_Screen/hardware.h b/F1-nolib/RGB_LED_Screen/hardware.h index c6fa097..3a97f92 100644 --- a/F1-nolib/RGB_LED_Screen/hardware.h +++ b/F1-nolib/RGB_LED_Screen/hardware.h @@ -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(); diff --git a/F1-nolib/RGB_LED_Screen/main.c b/F1-nolib/RGB_LED_Screen/main.c index 7acd4ec..701b5da 100644 --- a/F1-nolib/RGB_LED_Screen/main.c +++ b/F1-nolib/RGB_LED_Screen/main.c @@ -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(); diff --git a/F1-nolib/RGB_LED_Screen/proto.c b/F1-nolib/RGB_LED_Screen/proto.c index d1123d1..673d4ec 100644 --- a/F1-nolib/RGB_LED_Screen/proto.c +++ b/F1-nolib/RGB_LED_Screen/proto.c @@ -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; diff --git a/F1-nolib/RGB_LED_Screen/screen.c b/F1-nolib/RGB_LED_Screen/screen.c index 5638224..9e01e53 100644 --- a/F1-nolib/RGB_LED_Screen/screen.c +++ b/F1-nolib/RGB_LED_Screen/screen.c @@ -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;