#include "board.h" /* private defines */ #define SPI_BUFFER_SIZE 5 /* private variables */ /** * Nixi Tube cathodes map in Byte Array: * {E0 E9 E8 E7 E6 E5 E4 E3} * {E2 E1 D0 D9 D8 D7 D6 D5} * {D4 D3 D2 D1 B0 B9 B8 B7} * {B6 B5 B4 B3 B2 B1 A0 A9} * {A8 A7 A6 A5 A4 A3 A2 A1} * * Shift register bit map in Tube cathodes (from 0 to 1): * {5.7 5.6 5.5 5.4 5.3 5.2 5.1 5.0 4.7 4.6} VL5/E * {4.5 4.4 4.3 4.2 4.1 4.0 3.7 3.6 3.5 3.4} VL4/D * {3.3 3.2 3.1 3.0 2.7 2.6 2.5 2.4 2.3 2.2} VL2/B * {2.1 2.0 1.7 1.6 1.5 1.4 1.3 1.2 1.1 1.0} VL1/A */ static const uint16_t nixieCathodeMap[4][11] = { {0x8000, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x0000}, {0x2000, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x0000}, {0x0800, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0000}, {0x0200, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0000} }; static uint8_t tubesBuffer[SPI_BUFFER_SIZE] = {0}; /* private typedef */ /* private functions */ static void _show_digits(const uint32_t digits); static void GPIO_Init(void); static void DMA_Init(void); static void I2C1_Init(void); static void SPI1_Init(void); static void TIM1_Init(void); static void TIM3_Init(void); static void TIM14_Init(void); //static void TIM16_Init(void); //static void TIM17_Init(void); //static void USART1_UART_Init(void); /* Board perephireal Configuration */ void Board_Init(void) { /* Main peripheral clock enable */ RCC->APBENR1 = (RCC_APBENR1_PWREN | RCC_APBENR1_I2C1EN | RCC_APBENR1_TIM3EN); RCC->APBENR2 = (RCC_APBENR2_SYSCFGEN | RCC_APBENR2_SPI1EN | RCC_APBENR2_TIM1EN); /* GPIO Ports Clock Enable */ RCC->IOPENR = (RCC_IOPENR_GPIOAEN | RCC_IOPENR_GPIOBEN | RCC_IOPENR_GPIOCEN); /* Peripheral interrupt init*/ /* RCC_IRQn interrupt configuration */ NVIC_SetPriority(RCC_IRQn, 0); NVIC_EnableIRQ(RCC_IRQn); /* Configure the system clock */ SystemClock_Config(); /* Processor uses sleep as its low power mode */ SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); /* DisableSleepOnExit */ SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPONEXIT_Msk); /* Initialize all configured peripherals */ GPIO_Init(); DMA_Init(); I2C1_Init(); SPI1_Init(); /** Star SPI transfer to shift registers */ /* Set DMA source and destination addresses. */ /* Source: Address of the SPI buffer. */ DMA1_Channel1->CMAR = (uint32_t)&tubesBuffer; /* Destination: SPI1 data register. */ DMA1_Channel1->CPAR = (uint32_t)&(SPI1->DR); /* Set DMA data transfer length (SPI buffer length). */ DMA1_Channel1->CNDTR = SPI_BUFFER_SIZE; /* Enable SPI transfer */ SPI1->CR1 |= SPI_CR1_SPE; Flag.SPI_TX_End = 1; /* Enable tube power */ TUBE_PWR_ON; /* display work now */ /* Start RGB & Tube Power PWM */ TIM1_Init(); TIM3_Init(); /* Tube Blink timer */ TIM14_Init(); /* IN15 Fade In/Out timer */ //TIM16_Init(); //TIM17_Init(); //USART1_UART_Init(); } /** * @brief Out digits to SPI buffer. ON/off tube power. * @param : array with four BCD digits * @retval : None */ void showDigits(tube4_t dig) { static uint32_t old_dig = 0; uint8_t st = 0, ov = FADE_START; if (old_dig != dig.u32) { while (ov < FADE_STOP) { if (st == 0) { // new tube value st = 1; _show_digits(dig.u32); ov += FADE_STEP; tdelay_ms(ov); } else { // old tube value st = 0; _show_digits(old_dig); tdelay_ms(FADE_STOP - ov); } } // End of while old_dig = dig.u32; } // End of if-else } void lShiftDigits(const tube4_t old, const tube4_t dig) { uint32_t * buf; uint8_t sbuf[12]; sbuf[0] = dig.ar[0]; sbuf[1] = dig.ar[1]; sbuf[2] = dig.ar[2]; sbuf[3] = dig.ar[3]; sbuf[4] = TUBE_BLANK; sbuf[5] = TUBE_BLANK; sbuf[6] = TUBE_BLANK; sbuf[7] = TUBE_BLANK; sbuf[8] = old.ar[0]; sbuf[9] = old.ar[1]; sbuf[10] = old.ar[2]; sbuf[11] = old.ar[3]; int i; for (i=8; i>=0; i--) { buf = (uint32_t *)&sbuf[i]; _show_digits(*buf); tdelay_ms(100); } } void slideDigits(tube4_t dig) { tube4_t buf; const uint8_t pause = 100;; buf.s8.tA = TUBE_BLANK; buf.s8.tB = TUBE_BLANK; buf.s8.tD = TUBE_BLANK; buf.s8.tE = TUBE_BLANK; _show_digits(buf.u32); tdelay_ms(pause); buf.s8.tE = dig.s8.tA; _show_digits(buf.u32); tdelay_ms(pause); buf.s8.tD = dig.s8.tA; buf.s8.tE = dig.s8.tB; _show_digits(buf.u32); tdelay_ms(pause); buf.s8.tB = dig.s8.tA; buf.s8.tD = dig.s8.tB; buf.s8.tE = dig.s8.tD; _show_digits(buf.u32); tdelay_ms(pause); buf.s8.tA = dig.s8.tA; buf.s8.tB = dig.s8.tB; buf.s8.tD = dig.s8.tD; buf.s8.tE = dig.s8.tE; _show_digits(buf.u32); tdelay_ms(pause); buf.s8.tA = dig.s8.tB; buf.s8.tB = dig.s8.tD; buf.s8.tD = dig.s8.tE; buf.s8.tE = TUBE_BLANK; _show_digits(buf.u32); tdelay_ms(pause); buf.s8.tA = dig.s8.tD; buf.s8.tB = dig.s8.tE; buf.s8.tD = TUBE_BLANK; _show_digits(buf.u32); tdelay_ms(pause); buf.s8.tA = dig.s8.tE; buf.s8.tB = TUBE_BLANK; _show_digits(buf.u32); tdelay_ms(pause); buf.s8.tA = TUBE_BLANK; _show_digits(buf.u32); tdelay_ms(pause); } static void _show_digits(const uint32_t digits) { tube4_t dig; dig.u32 = digits; /* Clear buffer */ tubesBuffer[0] = 0; tubesBuffer[1] = 0; tubesBuffer[2] = 0; tubesBuffer[3] = 0; tubesBuffer[4] = 0; /* check values range */ int i; for (i=0; i<4; i++) { if (dig.ar[i] > TUBE_BLANK) { dig.ar[i] = TUBE_BLANK; } } /* Wait for SPI */ while (Flag.SPI_TX_End == 0); Flag.SPI_TX_End = 0; /* Feel buffer */ tubesBuffer[0] = (uint8_t)(nixieCathodeMap[Tube_E][dig.s8.tE] >> 8); tubesBuffer[1] = (uint8_t)((nixieCathodeMap[Tube_E][dig.s8.tE]) | (nixieCathodeMap[Tube_D][dig.s8.tD] >> 8)); tubesBuffer[2] = (uint8_t)((nixieCathodeMap[Tube_D][dig.s8.tD]) | (nixieCathodeMap[Tube_B][dig.s8.tB] >> 8)); tubesBuffer[3] = (uint8_t)((nixieCathodeMap[Tube_B][dig.s8.tB]) | (nixieCathodeMap[Tube_A][dig.s8.tA] >> 8)); tubesBuffer[4] = (uint8_t)(nixieCathodeMap[Tube_A][dig.s8.tA]); /* Start DMA transfer to SPI */ DMA1_Channel1->CCR |= DMA_CCR_EN; /* On/Off tube power */ for (i=0; i<4; i++) { if (dig.ar[i] == TUBE_BLANK) { tube_PowerOff((tube_pos_t)i); } else { tube_PowerOn((tube_pos_t)i); } } } /** * @brief Refresh unused tube digits for avoiding degrade * */ void tube_Refresh(void) { static int cnt = 0; tube4_t buf; /* We start ourselves every 125 ms to update 8 digits in a second. */ if (cnt == 0) { RTOS_SetTask(tube_Refresh, 125, 125); } /* Fill buffer with values */ switch (cnt) { case 0: cnt = 1; buf.s8.tA = 0; buf.s8.tD = 6; break; case 1: cnt = 2; buf.s8.tA = 3; break; case 2: cnt = 3; buf.s8.tA = 4; buf.s8.tD = 7; break; case 3: cnt = 4; buf.s8.tA = 5; break; case 4: cnt = 5; buf.s8.tA = 6; buf.s8.tD = 8; break; case 5: cnt = 6; buf.s8.tA = 7; break; case 6: cnt = 7; buf.s8.tA = 8; buf.s8.tD = 9; break; case 7: cnt = 0; buf.s8.tA = 9; break; default: cnt = 0; } /* Self delete task */ if (cnt == 0) { RTOS_DeleteTask(tube_Refresh); } /* Output buffer value to digits */ _show_digits(buf.u32); } /** * Control power of tube */ void tube_PowerOn(tube_pos_t tube) { switch (tube) { case Tube_A: TUBE_A_ON; break; case Tube_B: TUBE_B_ON; break; case Tube_D: TUBE_D_ON; break; case Tube_E: TUBE_E_ON; break; case Tube_All: TUBE_ALL_ON; break; default: break; } } void tube_PowerOff(tube_pos_t tube) { switch (tube) { case Tube_A: TUBE_A_OFF; break; case Tube_B: TUBE_B_OFF; break; case Tube_D: TUBE_D_OFF; break; case Tube_E: TUBE_E_OFF; break; case Tube_All: TUBE_ALL_OFF; break; default: break; } } void tube_BrightLevel(tube_pos_t tube, uint8_t bright) { switch (tube) { case Tube_A: TUBE_A_BRIGHT(bright); break; case Tube_B: TUBE_B_BRIGHT(bright); break; case Tube_C: TUBE_C_BRIGHT(bright); break; case Tube_D: TUBE_D_BRIGHT(bright); break; case Tube_E: TUBE_E_BRIGHT(bright); break; case Tube_All: TUBES_BRIGHT(bright); break; default: break; } } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { /* HSI configuration and activation */ RCC->CR |= RCC_CR_HSION; // Enable HSI while((RCC->CR & RCC_CR_HSIRDY) == 0); /* Main PLL configuration and activation */ RCC->PLLCFGR = (RCC_PLLCFGR_PLLSRC_HSI | RCC_PLLCFGR_PLLM_0 | (9 << RCC_PLLCFGR_PLLN_Pos) | RCC_PLLCFGR_PLLR_1); RCC->PLLCFGR |= RCC_PLLCFGR_PLLREN; // RCC_PLL_EnableDomain_SYS RCC->CR |= RCC_CR_PLLON; // RCC_PLL_Enable while((RCC->CR & RCC_CR_PLLRDY) == 0); /* Sysclk activation on the main PLL */ RCC->CFGR &= RCC_CFGR_SW; RCC->CFGR |= RCC_CFGR_SW_1; while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_1); /* Update CMSIS variable (which can be updated also through SystemCoreClockUpdate function) */ SystemCoreClock = 24000000; /* Set I2C Clock Source */ RCC->CCIPR &= ~(RCC_CCIPR_I2C1SEL); RCC->CCIPR |= RCC_CCIPR_I2C1SEL_1; } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void GPIO_Init(void) { /* EXTI Line: falling, no pull, input */ // interrupt on line 14 EXTI->IMR1 |= EXTI_IMR1_IM14; // TRIGGER FALLING EXTI->FTSR1 = EXTI_FTSR1_FT14; // external interrupt selection - PC14 to EXTI14 EXTI->EXTICR[3] = EXTI_EXTICR4_EXTI14_1; /* EXTI interrupt init*/ NVIC_SetPriority(EXTI4_15_IRQn, 0); NVIC_EnableIRQ(EXTI4_15_IRQn); /* set GPIO modes */ GPIO_SetPinMode(IRQ_GPIO_Port, IRQ_Pin, GPIO_MODE_IN); GPIO_SetPinPull(IRQ_GPIO_Port, IRQ_Pin, GPIO_PUPDR_UP); /* L0, L1, L2, L3 - IN-15 symbols control, PP out, high speed, pull down */ GPIO_SetPinMode(LC0_GPIO_Port, LC0_Pin, GPIO_MODE_OUT); GPIO_SetPinSpeed(LC0_GPIO_Port, LC0_Pin, GPIO_OSPEED_HI); GPIO_SetPinPull(LC0_GPIO_Port, LC0_Pin, GPIO_PUPDR_DW); GPIO_SetPinMode(LC1_GPIO_Port, LC1_Pin, GPIO_MODE_OUT); GPIO_SetPinSpeed(LC1_GPIO_Port, LC1_Pin, GPIO_OSPEED_HI); GPIO_SetPinPull(LC1_GPIO_Port, LC1_Pin, GPIO_PUPDR_DW); GPIO_SetPinMode(LC2_GPIO_Port, LC2_Pin, GPIO_MODE_OUT); GPIO_SetPinSpeed(LC2_GPIO_Port, LC2_Pin, GPIO_OSPEED_HI); GPIO_SetPinPull(LC2_GPIO_Port, LC2_Pin, GPIO_PUPDR_DW); GPIO_SetPinMode(LC3_GPIO_Port, LC3_Pin, GPIO_MODE_OUT); GPIO_SetPinSpeed(LC3_GPIO_Port, LC3_Pin, GPIO_OSPEED_HI); GPIO_SetPinPull(LC3_GPIO_Port, LC3_Pin, GPIO_PUPDR_DW); /* Pwer Shutdown: PP out, high speed, pull down */ GPIO_SetPinMode(SHDN_GPIO_Port, SHDN_Pin, GPIO_MODE_OUT); GPIO_SetPinSpeed(SHDN_GPIO_Port, SHDN_Pin, GPIO_OSPEED_HI); GPIO_SetPinPull(SHDN_GPIO_Port, SHDN_Pin, GPIO_PUPDR_DW); /* SPI Latch: OD out, high speed, no pull */ GPIO_SetPinMode(Latch_GPIO_Port, Latch_Pin, GPIO_MODE_OUT); GPIO_SetPinOutputType(Latch_GPIO_Port, Latch_Pin, GPIO_OTYPE_OD); GPIO_SetPinSpeed(Latch_GPIO_Port, Latch_Pin, GPIO_OSPEED_HI); /* UART_Enable: PP out, low speed, no pull*/ GPIO_SetPinMode(UART_EN_GPIO_Port, UART_EN_Pin, GPIO_MODE_OUT); /* UART_State: input, pull up */ GPIO_SetPinPull(UART_ST_GPIO_Port, UART_ST_Pin, GPIO_PUPDR_UP); GPIO_SetPinMode(UART_ST_GPIO_Port, UART_ST_Pin, GPIO_MODE_IN); /* BTN1, BTN2, BTN3, BTN4: input, pull up */ GPIO_SetPinPull(BTN1_GPIO_Port, BTN1_Pin, GPIO_PUPDR_UP); GPIO_SetPinMode(BTN1_GPIO_Port, BTN1_Pin, GPIO_MODE_IN); GPIO_SetPinPull(BTN2_GPIO_Port, BTN2_Pin, GPIO_PUPDR_UP); GPIO_SetPinMode(BTN2_GPIO_Port, BTN2_Pin, GPIO_MODE_IN); GPIO_SetPinPull(BTN3_GPIO_Port, BTN3_Pin, GPIO_PUPDR_UP); GPIO_SetPinMode(BTN3_GPIO_Port, BTN3_Pin, GPIO_MODE_IN); GPIO_SetPinPull(BTN4_GPIO_Port, BTN4_Pin, GPIO_PUPDR_UP); GPIO_SetPinMode(BTN4_GPIO_Port, BTN4_Pin, GPIO_MODE_IN); } /** * Enable DMA controller clock */ static void DMA_Init(void) { /* DMA controller clock enable */ RCC->AHBENR |= RCC_AHBENR_DMA1EN; /* enable DMA1 clock in Sleep/Stop mode */ //RCC->AHBSMENR |= RCC_AHBSMENR_DMA1SMEN; /* DMA interrupt init */ /* DMA1_Channel1_IRQn interrupt configuration */ NVIC_SetPriority(DMA1_Channel1_IRQn, 0); NVIC_EnableIRQ(DMA1_Channel1_IRQn); /* DMA1_Channel2_3_IRQn interrupt configuration */ NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0); NVIC_EnableIRQ(DMA1_Channel2_3_IRQn); } /** * @brief I2C1 Initialization Function * @param None * @retval None */ static void I2C1_Init(void) { /** I2C1 GPIO Configuration PB8 ------> I2C1_SCL PB9 ------> I2C1_SDA */ GPIO_SetPinMode(GPIOB, GPIO_PIN_8, GPIO_MODE_AFF); GPIO_SetPinOutputType(GPIOB, GPIO_PIN_8, GPIO_OTYPE_OD); GPIO_SetPinSpeed(GPIOB, GPIO_PIN_8, GPIO_OSPEED_HI); GPIO_SetPinPull(GPIOB, GPIO_PIN_8, GPIO_PUPDR_UP); GPIO_SetAFPin_8_15(GPIOB, GPIO_PIN_8, GPIO_AF_6); GPIO_SetPinMode(GPIOB, GPIO_PIN_9, GPIO_MODE_AFF); GPIO_SetPinOutputType(GPIOB, GPIO_PIN_9, GPIO_OTYPE_OD); GPIO_SetPinSpeed(GPIOB, GPIO_PIN_9, GPIO_OSPEED_HI); GPIO_SetPinPull(GPIOB, GPIO_PIN_9, GPIO_PUPDR_UP); GPIO_SetAFPin_8_15(GPIOB, GPIO_PIN_9, GPIO_AF_6); /** I2C1 DMA Init */ /* I2C1_RX Init: Priority medium, Memory increment, read from perephireal, transfer error interrupt enable, transfer complete interrupt enable */ DMA1_Channel2->CCR = (DMA_CCR_PL_0 | DMA_CCR_MINC | DMA_CCR_TEIE | DMA_CCR_TCIE); /* Route DMA channel 2 to I2C1 RX */ DMAMUX1_Channel1->CCR = 10; /* I2C1_TX Init: Priority medium, Memory increment, read from memory, transfer error interrupt enable, transfer complete interrupt enable */ DMA1_Channel3->CCR = (DMA_CCR_PL_0 | DMA_CCR_MINC| DMA_CCR_DIR | DMA_CCR_TEIE | DMA_CCR_TCIE); /* Route DMA channel 3 to I2C1 TX */ DMAMUX1_Channel2->CCR = 11; /** I2C Initialization: I2C_Fast */ I2C1->TIMINGR = 0x0010061A; I2C1->CR2 = I2C_CR2_AUTOEND; I2C1->CR1 = I2C_CR1_PE; } /** * @brief SPI1 Initialization Function * @param None * @retval None */ static void SPI1_Init(void) { /**SPI1 GPIO Configuration PB3 ------> SPI1_SCK PB5 ------> SPI1_MOSI */ GPIO_SetPinMode(GPIOB, GPIO_PIN_3, GPIO_MODE_AFF); GPIO_SetPinOutputType(GPIOB, GPIO_PIN_3, GPIO_OTYPE_OD); GPIO_SetPinSpeed(GPIOB, GPIO_PIN_3, GPIO_OSPEED_HI); GPIO_SetPinMode(GPIOB, GPIO_PIN_5, GPIO_MODE_AFF); GPIO_SetPinOutputType(GPIOB, GPIO_PIN_5, GPIO_OTYPE_OD); GPIO_SetPinSpeed(GPIOB, GPIO_PIN_5, GPIO_OSPEED_HI); /* SPI1 DMA Init */ /* SPI1_TX Init: Priority high, Memory increment, read from memory, circular mode, Enable DMA transfer complete/error interrupts */ DMA1_Channel1->CCR = (DMA_CCR_PL_1 | DMA_CCR_MINC | DMA_CCR_CIRC | DMA_CCR_TEIE | DMA_CCR_DIR | DMA_CCR_TCIE); /* Route DMA channel 1 to SPI1 TX */ DMAMUX1_Channel0->CCR = 0x11; /* SPI1 interrupt Init */ NVIC_SetPriority(SPI1_IRQn, 0); NVIC_EnableIRQ(SPI1_IRQn); /* SPI1 parameter configuration: master mode, data 8 bit, divider = 16, TX DMA */ SPI1->CR1 = (SPI_CR1_MSTR | SPI_CR1_BR_1 | SPI_CR1_BR_0 | SPI_CR1_SSM | SPI_CR1_SSI); SPI1->CR2 = (SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0 | SPI_CR2_TXDMAEN | SPI_CR2_FRXTH); } /** * @brief TIM1 Initialization Function * @param None * @retval None */ static void TIM1_Init(void) { /* target clock */ TIM1->PSC = TIM1_PSC; // prescaler TIM1->ARR = TIM1_ARR; // auto reload value TIM1->CR1 = TIM_CR1_ARPE; // initial pwm value TIM1->CCR1 = PWM_TUBE_INIT_VAL; TIM1->CCR2 = PWM_LED_INIT_VAL; TIM1->CCR3 = PWM_LED_INIT_VAL; TIM1->CCR4 = PWM_LED_INIT_VAL; // pwm mode 1 for 4 chanels TIM1->CCMR1 = (TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC1PE | TIM_CCMR1_OC2PE); TIM1->CCMR2 = (TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC3PE | TIM_CCMR2_OC4PE); // reset int flag - not needed, int unused //TIM1->SR |= TIM_SR_UIF; TIM1->BDTR = TIM_BDTR_MOE; // enable main output TIM1->EGR = TIM_EGR_UG; // force timer update /* TIM1 CC_EnableChannel */ TIM1->CCER = (TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E); /* TIM_EnableCounter */ TIM1->CR1 |= TIM_CR1_CEN; /** TIM1 GPIO Configuration PA8 ------> TIM1_CH1 PA9 ------> TIM1_CH2 PA10 ------> TIM1_CH3 PA11 [PA9] ------> TIM1_CH4 */ GPIO_SetPinMode(PWM_1_GPIO_Port, PWM_1_Pin, GPIO_MODE_AFF); GPIO_SetPinSpeed(PWM_1_GPIO_Port, PWM_1_Pin, GPIO_OSPEED_HI); GPIO_SetPinPull(PWM_1_GPIO_Port, PWM_1_Pin, GPIO_PUPDR_DW); GPIO_SetAFPin_8_15(PWM_1_GPIO_Port, PWM_1_Pin, GPIO_AF_2); GPIO_SetPinMode(PWM_R_GPIO_Port, PWM_R_Pin, GPIO_MODE_AFF); GPIO_SetPinSpeed(PWM_R_GPIO_Port, PWM_R_Pin, GPIO_OSPEED_HI); GPIO_SetPinPull(PWM_R_GPIO_Port, PWM_R_Pin, GPIO_PUPDR_DW); GPIO_SetAFPin_8_15(PWM_R_GPIO_Port, PWM_R_Pin, GPIO_AF_2); GPIO_SetPinMode(PWM_B_GPIO_Port, PWM_B_Pin, GPIO_MODE_AFF); GPIO_SetPinSpeed(PWM_B_GPIO_Port, PWM_B_Pin, GPIO_OSPEED_HI); GPIO_SetPinPull(PWM_B_GPIO_Port, PWM_B_Pin, GPIO_PUPDR_DW); GPIO_SetAFPin_8_15(PWM_B_GPIO_Port, PWM_B_Pin, GPIO_AF_2); GPIO_SetPinMode(PWM_G_GPIO_Port, PWM_G_Pin, GPIO_MODE_AFF); GPIO_SetPinSpeed(PWM_G_GPIO_Port, PWM_G_Pin, GPIO_OSPEED_HI); GPIO_SetPinPull(PWM_G_GPIO_Port, PWM_G_Pin, GPIO_PUPDR_DW); GPIO_SetAFPin_8_15(PWM_G_GPIO_Port, PWM_G_Pin, GPIO_AF_2); } /** * @brief TIM3 Initialization Function * @param None * @retval None */ static void TIM3_Init(void) { /* target clock */ TIM3->PSC = TIM3_PSC; // prescaler TIM3->ARR = TIM3_ARR; // auto reload value TIM3->CR1 = TIM_CR1_ARPE; // initial pwm value TIM3->CCR1 = PWM_TUBE_INIT_VAL; TIM3->CCR2 = PWM_TUBE_INIT_VAL; TIM3->CCR3 = PWM_TUBE_INIT_VAL; TIM3->CCR4 = PWM_TUBE_INIT_VAL; // pwm mode 1 for 4 chanels TIM3->CCMR1 = (TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC1PE | TIM_CCMR1_OC2PE); TIM3->CCMR2 = (TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC3PE | TIM_CCMR2_OC4PE); // launch timer TIM3->EGR = TIM_EGR_UG; // force timer update /* TIM3 TIM_CC_EnableChannel */ TIM3->CCER = (TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E); /* TIM3 enable */ TIM3->CR1 |= TIM_CR1_CEN; /**TIM3 GPIO Configuration PA6 ------> TIM3_CH1 PA7 ------> TIM3_CH2 PB0 ------> TIM3_CH3 PB1 ------> TIM3_CH4 */ GPIO_SetPinMode(PWM_5_GPIO_Port, PWM_5_Pin, GPIO_MODE_AFF); GPIO_SetPinSpeed(PWM_5_GPIO_Port, PWM_5_Pin, GPIO_OSPEED_HI); GPIO_SetPinPull(PWM_5_GPIO_Port, PWM_5_Pin, GPIO_PUPDR_DW); GPIO_SetAFPin_0_7(PWM_5_GPIO_Port, PWM_5_Pin, GPIO_AF_1); GPIO_SetPinMode(PWM_4_GPIO_Port, PWM_4_Pin, GPIO_MODE_AFF); GPIO_SetPinSpeed(PWM_4_GPIO_Port, PWM_4_Pin, GPIO_OSPEED_HI); GPIO_SetPinPull(PWM_4_GPIO_Port, PWM_4_Pin, GPIO_PUPDR_DW); GPIO_SetAFPin_0_7(PWM_4_GPIO_Port, PWM_4_Pin, GPIO_AF_1); GPIO_SetPinMode(PWM_3_GPIO_Port, PWM_3_Pin, GPIO_MODE_AFF); GPIO_SetPinSpeed(PWM_3_GPIO_Port, PWM_3_Pin, GPIO_OSPEED_HI); GPIO_SetPinPull(PWM_3_GPIO_Port, PWM_3_Pin, GPIO_PUPDR_DW); GPIO_SetAFPin_0_7(PWM_3_GPIO_Port, PWM_3_Pin, GPIO_AF_1); GPIO_SetPinMode(PWM_2_GPIO_Port, PWM_2_Pin, GPIO_MODE_AFF); GPIO_SetPinSpeed(PWM_2_GPIO_Port, PWM_2_Pin, GPIO_OSPEED_HI); GPIO_SetPinPull(PWM_2_GPIO_Port, PWM_2_Pin, GPIO_PUPDR_DW); GPIO_SetAFPin_0_7(PWM_2_GPIO_Port, PWM_2_Pin, GPIO_AF_1); } /** * @brief TIM14 Initialization Function * @param None * @retval None * @desc "Блинкование" разрядами. */ static void TIM14_Init(void) { /* Peripheral clock enable */ RCC->APBENR2 |= RCC_APBENR2_TIM14EN; /* TIM14 interrupt Init */ NVIC_SetPriority(TIM14_IRQn, 0); NVIC_EnableIRQ(TIM14_IRQn); /* Set TIM14 for 1 sec period */ TIM14->PSC = TIM14_PSC; TIM14->ARR = TIM14_ARR; /* Enable: Auto-reload preload */ TIM14->CR1 = (TIM_CR1_ARPE); /* Output compare 1 preload */ TIM14->CCMR1 = (TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1PE); /* Enable Channel_1 */ TIM14->CCER = TIM_CCER_CC1E; /* Impulse value in msek */ TIM14->CCR1 = TIM14_PULSE_VAL; /* Enable IRQ for Update end CaptureCompare envents */ TIM14->DIER = (TIM_DIER_UIE | TIM_DIER_CC1IE); } /** * На старте активируем все каналы, при совпадении отключаем (не)нужные. */ void Blink_Start(void) { /* clear IRQ flags */ TIM14->SR |= TIM_SR_UIF; TIM14->SR |= TIM_SR_CC1IF; /* clear counter value */ TIM14->CNT = 0; /* enable timer */ TIM14->CR1 |= TIM_CR1_CEN; } void Blink_Stop(void) { /* disable timer */ TIM14->CR1 &= ~(TIM_CR1_CEN); /* enable channels & clean flag */ if (Flag.Blink_1 != 0) { TUBE_A_ON; Flag.Blink_1 = 0; } if (Flag.Blink_2 != 0) { TUBE_B_ON; Flag.Blink_2 = 0; } if (Flag.Blink_3 != 0) { TUBE_C_ON; Flag.Blink_3 = 0; } if (Flag.Blink_4 != 0) { TUBE_D_ON; Flag.Blink_4 = 0; } if (Flag.Blink_5 != 0) { TUBE_E_ON; Flag.Blink_5 = 0; } } #ifdef USE_TIM16 /** * @brief TIM16 Initialization Function * @param None * @retval None */ static void TIM16_Init(void) { /* Peripheral clock enable */ RCC->APBENR2 |= RCC_APBENR2_TIM16EN; /* TIM16 interrupt Init */ NVIC_SetPriority(TIM16_IRQn, 0); NVIC_EnableIRQ(TIM16_IRQn); /* setup clock */ TIM16->PSC = TIM16_PSC; // prescaler TIM16->ARR = TIM16_ARR; // auto reload value TIM16->CR1 = TIM_CR1_ARPE; // initial pwm value //TIM16->CCR1 = TIM16_ARR/2; //TIM16_PWM_VAL; // pwm mode 1 for 1 chanel //TIM16->CCMR1 = (TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1PE); // reset int flag TIM16->SR |= TIM_SR_UIF; TIM16->BDTR = TIM_BDTR_MOE; // enable main output TIM16->EGR = TIM_EGR_UG; // force timer update /* TIM16 CC_EnableChannel */ //TIM16->CCER = TIM_CCER_CC1E; /* Enable IRQ */ TIM16->DIER = TIM_DIER_UIE; /* TIM_EnableCounter */ TIM16->CR1 |= TIM_CR1_CEN; } #endif /* USE_TIM16 */ #ifdef USE_TIM17 /** * @brief TIM17 Initialization Function * @param None * @retval None */ static void TIM17_Init(void) { /* Peripheral clock enable */ RCC->APBENR2 |= RCC_APBENR2_TIM17EN; /* TIM17 interrupt Init */ NVIC_SetPriority(TIM17_IRQn, 0); NVIC_EnableIRQ(TIM17_IRQn); /* setup clock */ TIM17->PSC = TIM17_PSC; // prescaler TIM17->ARR = TIM17_ARR; // auto reload value TIM17->CR1 = TIM_CR1_ARPE; // initial pwm value //TIM17->CCR1 = TIM17_PWM_VAL; // pwm mode 1 for 1 chanel TIM17->CCMR1 = (TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1PE); // reset int flag TIM17->SR |= TIM_SR_UIF; TIM17->BDTR = TIM_BDTR_MOE; // enable main output TIM17->EGR = TIM_EGR_UG; // force timer update /* TIM17 CC_EnableChannel */ TIM17->CCER = TIM_CCER_CC1E; /* TIM_EnableCounter */ TIM17->CR1 |= TIM_CR1_CEN; /* Enable IRQ */ TIM17->DIER = TIM_DIER_UIE; } #endif /* USE_TIM17 */ #ifdef USE_UART /** * @brief USART1 Initialization Function * @param None * @retval None */ static void USART1_UART_Init(void) { /* Peripheral clock enable */ RCC->APBENR2 |= RCC_APBENR2_USART1EN; /**USART1 GPIO Configuration PB6 ------> USART1_TX PB7 ------> USART1_RX */ GPIO_SetPinMode(GPIOB, GPIO_PIN_6, GPIO_MODE_AFF); GPIO_SetPinSpeed(GPIOB, GPIO_PIN_6, GPIO_OSPEED_HI); GPIO_SetPinMode(GPIOB, GPIO_PIN_7, GPIO_MODE_AFF); GPIO_SetPinSpeed(GPIOB, GPIO_PIN_7, GPIO_OSPEED_HI); /* USART1 interrupt Init */ NVIC_SetPriority(USART1_IRQn, 0); NVIC_EnableIRQ(USART1_IRQn); USART1->CR1 |= (USART_CR1_TE |USART_CR1_RE); USART1->BRR = 138; /* USART1 Enable */ USART1->CR1 |= USART_CR1_UE; /* Polling USART1 initialisation */ while((!(USART1->ISR & USART_ISR_TEACK)) || (!(USART1->ISR & USART_ISR_REACK))) { } } #endif /* USE_UART */