// for CH32V203, CH32X035, CH32V006 using ch32fun #ifndef _MRBC_API_H #define _MRBC_API_H #include "ch32fun.h" // hal int hal_write(int fd, const void *buf, int nbytes) { _write(0, (char*)buf, nbytes); return nbytes; } int hal_flush(int fd) { return 0; } void hal_abort(const char *s) {} // GPIO #define MRBC_GPIO_IN GPIO_CFGLR_IN_FLOAT #define MRBC_GPIO_OUT GPIO_CFGLR_OUT_50Mhz_PP #define MRBC_GPIO_IN_PU GPIO_CFGLR_IN_PUPD #define MRBC_GPIO_IN_PD GPIO_CFGLR_IN_PUPD #define MRBC_GPIO_OUT_OD GPIO_CFGLR_OUT_50Mhz_OD #define MRBC_GPIO_IN_ANALOG GPIO_CFGLR_IN_ANALOG #if defined(CH32X03x) //PA 0-23 0-23 //PB 0-23 24-47 //PC 0-23 48-71 #define mrbcGpioOf( pin ) ((GPIO_TypeDef *)(GPIOA_BASE + 0x400 * ((pin)/24))) static inline void mrbcDigitalWrite( uint8_t pin, uint8_t value ) { *((&mrbcGpioOf(pin)->BSHR)+((pin%24)>>4<<2)) = 1<<(((value)?0:16)+((pin%24)&0xf)); } static inline uint16_t mrbcDigitalRead( uint8_t pin ) { return ((uint16_t)((mrbcGpioOf(pin)->INDR >> ((pin)%24)) & 1)); } static inline void mrbcPinMode(uint8_t pin, uint32_t mode) { if( pin==66 || pin==67){ //swd AFIO->PCFR1 &= ~AFIO_PCFR1_SWJ_CFG; AFIO->PCFR1 |= AFIO_PCFR1_SWJ_CFG_DISABLE; } volatile uint32_t *p = (&mrbcGpioOf(pin)->CFGLR)+((pin%24)>>3)+(((pin%24)>>4)*5); *p&=~(0xf<<(((pin)&0x7)<<2)); *p|=((mode)<<(((pin)&0x7)<<2)); } #else //PA 0-15 0-15 //PB 0-15 16-31 //PC 0-15 32-47 static inline void mrbcDigitalWrite( uint8_t pin, uint8_t value ) { funDigitalWrite( pin, value ); } static inline uint8_t mrbcDigitalRead( uint8_t pin ) { return funDigitalRead( pin ); } static inline void mrbcPinMode( uint8_t pin, uint32_t mode ) { funPinMode( pin, mode ); } #endif // ADC #define MRBC_ADC_RANGE 4095 //1023 #define MRBC_ADC_REF 3.3 //5.0 #define MRBC_ADC_TIMEOUT_MAX 100000 #define mrbcAnalogRead( ch ) funAnalogRead( ch ) static inline uint8_t mrbcAnalogChannel(uint8_t dpin) { uint8_t i; #if defined( CH32V00x ) //A2 A1 C4 D2 D3 D5 D6 D4 1.2V OPA static volatile uint8_t pin_adc[]={ 0x02,0x01,0x24,0x32,0x33,0x35,0x36,0x34 }; for(i=0;i<8;i++)if(dpin==pin_adc[i]){break;} #elif defined(CH32X03x) //A0-A7 B0 B1 C0-C3 NC 1.2V i = ((dpin>>1)==12)? dpin-16 : ((dpin>>2)==12)? dpin-38 : ((dpin>>3)==0)? dpin : 15; #elif defined( CH32V20x ) //A0-A7 B0 B1 C0-C5 Tempr 1.2V // 0,1,2,3,4,5,6,7,16,17,32,33,34 i = ((dpin>>1)==8)? dpin-8 : ((dpin>>3)==4)? dpin-22 : ((dpin>>3)==0)? dpin : 17; #endif return i; } static inline uint8_t mrbcAnalogInit(uint8_t pin_id) { uint8_t ch = mrbcAnalogChannel(pin_id); mrbcPinMode(pin_id,MRBC_GPIO_IN_ANALOG); return ch; } // PWM #if defined( CH32V00x ) #define TIM_ARPE TIM1_CTLR1_ARPE #define TIM_CC1E TIM1_CCER_CC1E #define TIM_CC1P TIM1_CCER_CC1P #define TIM_OC1M_2 TIM1_CHCTLR1_OC1M_2 #define TIM_OC1M_1 TIM1_CHCTLR1_OC1M_1 #define TIM_OC1PE TIM1_CHCTLR1_OC1PE #define TIM_MOE TIM1_BDTR_MOE #define TIM_UG TIM1_SWEVGR_UG #define TIM_CEN TIM1_CTLR1_CEN //channel 1 2 3 4 5:1N 6:2N 7:3N static volatile uint8_t pin_timer[]={ // timer, map, ch 0165, 0102, 0166, 0161, 0000, 0000, 0000, 0000, //PA 0,0,0,0,0,0,0,0, 0162, 0163, 0164, 0000, 0000, 0000, 0244, 0000, //PB 0,0,0,0,0,0,0,0, 0241, 0242, 0177, 0243, 0171, 0172, 0173, 0174, //PC 0,0,0,0,0,0,0,0, 0167, 0107, 0101, 0202, 0201, 0234, 0233, 0204, //PD }; static const void *timer_base[] = { TIM1, TIM2 }; //static const uint32_t base[]={TIM1_BASE,TIM2_BASE}; #elif defined( CH32X03x ) static volatile uint8_t pin_timer[]={ // timer, map, ch 0201, 0202, 0203, 0204, 0332, 0, 0301, 0302, 0, 0, 0, 0, 0215, 0216, 0217, 0, 0, 0, 0, 0, 0, 0205, 0206, 0207, 0116, 0117, 0, 0223, 0224, 0312, 0125, 0126, 0127, 0121, 0122, 0123, 0124, 0, 0, 0212, 0241, 0242, 0243, 0244, 0, 0211, 0, 0, 0131, 0132, 0133, 0134, 0, 0135, 0136, 0137, 0, 0, 0, 0, 0, 0, 0262, 0263, 0114, 0, 0322, 0321, 0, 0, 0, 0, }; static const void *timer_base[] = { TIM1, TIM2, TIM3 }; //static volatile uint32_t base[]={TIM1_BASE,TIM2_BASE,TIM3_BASE}; #elif defined( CH32V20x ) static volatile uint8_t pin_timer[]={ // timer, map, ch 0101, 0102, 0103, 0104, 0, 0, 0201, 0202, 0001, 0002, 0003, 0004, 0, 0, 0, 0131, 0223, 0224, 0, 0132, 0221, 0222, 0301, 0302, 0303, 0304, 0133, 0134, 0, 0005, 0006, 0007, 0, 0, 0, 0, 0, 0, 0231, 0232, 0233, 0234, 0, 0, 0, 0, 0, 0, }; static const void *timer_base[] = { TIM1, TIM2, TIM3, TIM4 }; //static volatile uint32_t base[]={TIM1_BASE,TIM2_BASE,TIM3_BASE,TIM4_BASE}; #endif static inline void mrbcPwmWrite(uint8_t pin, uint32_t freq, uint16_t duty) { if(freq==0){ mrbcDigitalWrite(pin,0); mrbcPinMode(pin, MRBC_GPIO_OUT); return; } uint32_t limit=FUNCONF_SYSTEM_CORE_CLOCK/freq; uint32_t prescaler=limit>>16; limit/=(prescaler+1); uint16_t val=limit*duty/10000; if(limit>0) limit--; if(pin>=sizeof(pin_timer)) return; uint8_t tmr=pin_timer[pin]; if(tmr == 0) return; uint8_t ch=tmr%8; uint8_t alt=(tmr/8)%8; // alternate setting tmr>>=6; //tmr=1; alt=7; ch=1; #if defined( CH32V20x ) tmr++; #endif volatile uint32_t *enadrs=&(RCC->APB2PCENR); #if defined( CH32V00x) *(enadrs+tmr/2) |= 1<<(22-tmr*11); //RCC_APB2Periph_TIMx 0x800,11,0 AFIO->PCFR1 &= ~( (15-tmr/2*8)<<(tmr*4+6) ); // AFIO_PCFR1_TIM1_REMAP 15,7 AFIO->PCFR1 |= alt<<(tmr*4+6); // AFIO_PCFR1_TIMx_REMAP_0 10,14 #elif defined( CH32X03x ) *(enadrs+tmr/2) |= 1<<((tmr+10)%12); //RCC_APB2Periph_TIMx 0x800,11,0,1 AFIO->PCFR1 &= ~( (7-tmr/3*4)<<(tmr*3+12) ); // AFIO_PCFR1_TIM1_REMAP 7,7,3 AFIO->PCFR1 |= alt<<(tmr*3+12); // AFIO_PCFR1_TIMx_REMAP_0 15,18,21 #else //CH32V20x *(enadrs+(tmr>1)) |= 1<<( (tmr==1)*12+tmr-2 ); //RCC_APB2Periph_TIMx 11,0-2 AFIO->PCFR1 &= ~( (3-tmr/4*2)<<(tmr*2+4) ); // AFIO_PCFR1_TIM1_REMAP 3,3,3,1 AFIO->PCFR1 |= alt<<(tmr*2+4); // AFIO_PCFR1_TIMx_REMAP_0 6,8,10,12 #endif __typeof__(TIM1) tim = (__typeof__(TIM1)) timer_base[tmr-1]; tim->PSC = prescaler; tim->CTLR1 |= TIM_ARPE; tim->ATRLR = limit; tim->CCER |= (TIM_CC1E | TIM_CC1P)<<(4*(ch-1)-ch/5*14); // 1,1N,2,2N,3,3N,4 volatile uint16_t *chadrs=&(tim->CHCTLR1); *(chadrs+((ch-1)&2)) |= (TIM_OC1M_2 | TIM_OC1M_1 | TIM_OC1PE)<<((ch-1)%2*8); #if defined( CH32V20x ) volatile uint16_t *vladrs=&(tim->CH1CVR); *(vladrs+(ch-1)%4*2) = val; #else volatile uint32_t *vladrs=&(tim->CH1CVR); *(vladrs+(ch-1)%4) = val; #endif tim->BDTR |= TIM_MOE; tim->SWEVGR |= TIM_UG; tim->CTLR1 |= TIM_CEN; mrbcPinMode(pin, GPIO_CFGLR_OUT_50Mhz_AF_PP); } // I2C #define NO_I2C_HANDLE #define I2C_TIMEOUT_MAX 100000 #define I2C_WAIT_FLAG(reg, flag) { \ uint32_t timeout = I2C_TIMEOUT_MAX; \ while (!((reg) & (flag))) { \ if (--timeout == 0) return -1; \ } \ } static inline void mrbcI2cInit(void* handle, uint32_t freq, int scl, int sda) { RCC->APB1PCENR |= RCC_APB1Periph_I2C1; #if defined( CH32X03x ) AFIO->PCFR1 &= ~AFIO_PCFR1_I2C1_REMAP; AFIO->PCFR1 |= AFIO_PCFR1_I2C1_REMAP_1 | AFIO_PCFR1_I2C1_REMAP_0; //011 mrbcPinMode(66,GPIO_CFGLR_OUT_50Mhz_AF_PP); //PC18 DIO mrbcPinMode(67,GPIO_CFGLR_OUT_50Mhz_AF_PP); //PC19 DCK #elif defined( CH32V00x ) mrbcPinMode(33,GPIO_CFGLR_OUT_50Mhz_AF_PP); //PC1 SDA mrbcPinMode(34,GPIO_CFGLR_OUT_50Mhz_AF_PP); //PC2 SCL #elif defined( CH32V20x ) mrbcPinMode(26,GPIO_CFGLR_OUT_50Mhz_AF_PP); //PB10 mrbcPinMode(27,GPIO_CFGLR_OUT_50Mhz_AF_PP); //PB11 #endif I2C1->CTLR1 &= ~I2C_CTLR1_PE; I2C1->CTLR2 = (FUNCONF_SYSTEM_CORE_CLOCK / 1000000); I2C1->CKCFGR = FUNCONF_SYSTEM_CORE_CLOCK / (freq << 1); I2C1->CTLR1 |= I2C_CTLR1_PE; I2C1->CTLR1 |= I2C_CTLR1_ACK; } static inline int mrbcI2cStart(void* handle, uint8_t adrs, uint8_t rw) // rw=1 if read { uint32_t timeout = I2C_TIMEOUT_MAX; while (I2C1->STAR2 & I2C_STAR2_BUSY) { if (--timeout == 0) return -1; } I2C1->CTLR1 |= I2C_CTLR1_START; I2C_WAIT_FLAG(I2C1->STAR1, I2C_STAR1_SB); I2C1->DATAR = (adrs << 1) | rw; I2C_WAIT_FLAG(I2C1->STAR1, I2C_STAR1_ADDR); (void)I2C1->STAR1; (void)I2C1->STAR2; return 0; } static inline void mrbcI2cStop(void* handle) { I2C1->CTLR1 |= I2C_CTLR1_STOP; } static inline int mrbcI2cWrite(void* handle, const uint8_t *buf, uint16_t len) { for (uint16_t i = 0; i < len; i++) { I2C_WAIT_FLAG(I2C1->STAR1, I2C_STAR1_TXE); I2C1->DATAR = buf[i]; } I2C_WAIT_FLAG(I2C1->STAR1, I2C_STAR1_BTF); return 0; } static inline int mrbcI2cRead(void* handle, uint8_t *buf, uint16_t len) { if (len == 0) return 0; I2C1->CTLR1 |= I2C_CTLR1_ACK; for (uint16_t i = 0; i < len; i++) { if(i==len-1) I2C1->CTLR1 &= ~I2C_CTLR1_ACK; I2C_WAIT_FLAG(I2C1->STAR1, I2C_STAR1_RXNE); buf[i] = I2C1->DATAR; } I2C1->CTLR1 |= I2C_CTLR1_STOP; return 0; } // SPI #define NO_SPI_HANDLE #define MRBC_SPI_LSB_FIRST 1 #define MRBC_SPI_MSB_FIRST 0 #define SPI_TIMEOUT_MAX 100000 static inline void mrbcSpiInit(void* handle) { RCC->APB2PCENR |= RCC_APB2Periph_SPI1; #if defined( CH32V00x ) //PC1 NSS mrbcPinMode(37,GPIO_CFGLR_OUT_50Mhz_AF_PP); //PC5 SCK mrbcPinMode(38,GPIO_CFGLR_OUT_50Mhz_AF_PP); //PC6 MOSI mrbcPinMode(39,GPIO_CFGLR_IN_FLOAT); //PC7 MISO #elif defined( CH32X03x ) || defined( CH32V20x ) //PA4 NSS mrbcPinMode(5,GPIO_CFGLR_OUT_50Mhz_AF_PP); //PA5 SCK mrbcPinMode(6,GPIO_CFGLR_IN_FLOAT); //PA6 MISO mrbcPinMode(7,GPIO_CFGLR_OUT_50Mhz_AF_PP); //PA7 MOSI #endif } static inline void mrbcSpiMode(void* handle, uint32_t spi_freq, uint32_t spi_first_bit, uint32_t spi_mode) { uint32_t ratio = (FUNCONF_SYSTEM_CORE_CLOCK / spi_freq); //FHCLK uint8_t scale=0; ratio--; while(ratio>>=1) scale++; if(scale>7) scale=7; uint16_t val=0; val |= SPI_CTLR1_MSTR; val |= (scale<<3); // SPI_CTLR1_BR val |= spi_mode & 3; // SPI_CTLR1_CPHA | SPI_CTLR1_CPOL #if defined( CH32V20x ) val |= (spi_first_bit & 1) << 7 ; #else val |= SPI_CTLR1_LSBFIRST * (spi_first_bit & 1) ; #endif val |= SPI_CTLR1_SSM | SPI_CTLR1_SSI; // software SS SPI1->CTLR1 = val | SPI_CTLR1_SPE; } static inline void mrbcSpiTransfer(void* handle, uint8_t *buf, uint32_t len) { uint32_t timeout; for (uint32_t i = 0; i < len; i++) { timeout = SPI_TIMEOUT_MAX; while (!(SPI1->STATR & SPI_STATR_TXE)) { if (--timeout == 0) return; } SPI1->DATAR = buf[i]; timeout = SPI_TIMEOUT_MAX; while (!(SPI1->STATR & SPI_STATR_RXNE)) { if (--timeout == 0) return; } buf[i] = SPI1->DATAR; } timeout = SPI_TIMEOUT_MAX; while (SPI1->STATR & SPI_STATR_BSY) { if (--timeout == 0) return; } } // UART #define MRBC_UART_NONE 0 #define MRBC_UART_EVEN 1 #define MRBC_UART_ODD 2 #define UART_TIMEOUT_MAX 100000 #define UART_BUF_SIZE 128 typedef struct UART_HANDLE { uint8_t unit_num; uint8_t rx_index; char rx_buf[UART_BUF_SIZE]; } UART_HANDLE; #if defined( CH32V00x ) static volatile uint32_t usart_base[]={USART1_BASE,USART2_BASE}; static volatile uint32_t dma_rx_base[]={DMA1_Channel5_BASE,DMA1_Channel7_BASE}; static volatile uint8_t rx_pin_num[]={54,19}; static volatile uint8_t tx_pin_num[]={53,7}; #elif defined( CH32X03x ) static volatile uint32_t usart_base[]={USART1_BASE,USART2_BASE,USART3_BASE,USART4_BASE}; static volatile uint32_t dma_rx_base[]={DMA1_Channel5_BASE,DMA1_Channel6_BASE,DMA1_Channel3_BASE,DMA1_Channel8_BASE}; static volatile uint8_t rx_pin_num[]={35,3,67,25}; static volatile uint8_t tx_pin_num[]={34,2,66,24}; #elif defined( CH32V20x ) static volatile uint32_t usart_base[]={USART1_BASE,USART2_BASE,USART3_BASE}; //,UART4_BASE}; static volatile uint32_t dma_rx_base[]={DMA1_Channel5_BASE,DMA1_Channel6_BASE,DMA1_Channel3_BASE}; //,DMA2_Channel3_BASE}; static volatile uint8_t rx_pin_num[]={10,3,27}; //,43}; static volatile uint8_t tx_pin_num[]={9,2,26}; //,42}; #endif static inline void mrbcUartInit(UART_HANDLE *handle) { handle->rx_index = 0; if(handle->unit_num==1){ RCC->APB2PCENR |= RCC_APB2Periph_USART1; //1<<14 }else{ RCC->APB1PCENR |= 1<<(15+handle->unit_num); } uint8_t tx=tx_pin_num[handle->unit_num-1]; uint8_t rx=rx_pin_num[handle->unit_num-1]; //if(handle->unit_num == 3){ //disable SW and remap1 #if defined( CH32X03x ) if(tx>65){ //disable SW and remap1 AFIO->PCFR1 &= ~AFIO_PCFR1_USART3_REMAP; AFIO->PCFR1 |= AFIO_PCFR1_USART3_REMAP_0; } #endif mrbcPinMode(tx,GPIO_CFGLR_OUT_50Mhz_AF_PP); mrbcPinMode(rx,GPIO_CFGLR_IN_FLOAT); USART_TypeDef *usart = ((USART_TypeDef *) usart_base[handle->unit_num-1]); DMA_Channel_TypeDef *dma_rx = ((DMA_Channel_TypeDef *) dma_rx_base[handle->unit_num-1]); RCC->AHBPCENR |= RCC_AHBPeriph_DMA1; dma_rx->CFGR &= ~DMA_CFGR1_EN; dma_rx->MADDR = (uint32_t)handle->rx_buf; dma_rx->PADDR = (uint32_t)&usart->DATAR; dma_rx->CNTR = UART_BUF_SIZE; dma_rx->CFGR = DMA_CFGR1_MINC | DMA_CFGR1_CIRC | DMA_CFGR1_EN; } static inline void mrbcUartSetMode(UART_HANDLE *handle, uint32_t baud_rate, uint32_t datb, uint32_t stpb, uint32_t prty ) { USART_TypeDef *usart = ((USART_TypeDef *) usart_base[handle->unit_num-1]); usart->CTLR1 &= ~( CTLR1_UE_Set ); usart->BRR = ( ( FUNCONF_SYSTEM_CORE_CLOCK ) + baud_rate/2 ) / baud_rate; usart->CTLR3 = USART_DMAReq_Rx | USART_HardwareFlowControl_None | USART_CTLR3_DMAR; usart->CTLR2 = (stpb&2)<<12; // 1:1bit, 2:2bit, //3:0.5, 4:1.5 0213 usart->CTLR1 = USART_WordLength_9b * (prty>0 && datb>7) | (prty&3)<<9 | USART_Mode_Tx | USART_Mode_Rx | CTLR1_UE_Set; } static inline int mrbcUartByteToWrite(UART_HANDLE *handle) { return 0; } static inline int mrbcUartWrite(UART_HANDLE *handle, const char *buf, int size){ USART_TypeDef *usart = ((USART_TypeDef *) usart_base[handle->unit_num-1]); for(int i = 0; i < size; i++){ uint32_t timeout = UART_TIMEOUT_MAX; while( !(usart->STATR & USART_FLAG_TXE) ) { if (--timeout == 0) return -1;} usart->DATAR = *buf++; } return size; } static inline int mrbcUartAvailable(UART_HANDLE *handle){ DMA_Channel_TypeDef *dma_rx = ((DMA_Channel_TypeDef *) dma_rx_base[handle->unit_num-1]); uint8_t size =(UART_BUF_SIZE - dma_rx->CNTR); //%UART_BUF_SIZE; size -= handle->rx_index; size %= UART_BUF_SIZE; return size; } static inline int mrbcUartRead(UART_HANDLE *handle, char *buf, int size){ for(int i = 0; i < size; i++){ while(!mrbcUartAvailable(handle)); buf[i] = handle->rx_buf[handle->rx_index]; handle->rx_index = (handle->rx_index + 1)%UART_BUF_SIZE; } buf[size] = '\0'; return size; } static inline int mrbcUartCanReadLine(UART_HANDLE *handle){ DMA_Channel_TypeDef *dma_rx = ((DMA_Channel_TypeDef *) dma_rx_base[handle->unit_num-1]); uint8_t index = handle->rx_index; uint8_t last = (UART_BUF_SIZE - dma_rx->CNTR)%UART_BUF_SIZE; while( index != last ) { if( handle->rx_buf[index++] == '\n' )return (index - handle->rx_index)%UART_BUF_SIZE; index%=UART_BUF_SIZE; } return 0; } static inline void mrbcUartFlush(UART_HANDLE *handle) { } static inline void mrbcUartClearRx(UART_HANDLE *handle) { DMA_Channel_TypeDef *dma_rx = ((DMA_Channel_TypeDef *) dma_rx_base[handle->unit_num-1]); handle->rx_index=(UART_BUF_SIZE - dma_rx->CNTR)%UART_BUF_SIZE; } static inline void mrbcUartClearTx(UART_HANDLE *handle) { } // DAC // sleep #define NO_SLEEP_LIGHT /* void mrbcSleepLight(uint32_t sleep_ms) { if (sleep_ms == 0) return; uint64_t target_tick= sleep_ms*DELAY_MS_TIME; uint64_t start_tick = SysTick->CNT; PFIC->SCTLR &= ~(1 << 2); while ((SysTick->CNT - start_tick) < target_tick) { __WFI(); } } */ #if defined( CH32X03x ) typedef struct { __IO uint32_t CSR; __IO uint32_t WR; __IO uint32_t PSC; } AWU_TypeDef; #define AWU ((AWU_TypeDef *) AWU_BASE) #endif #if defined( CH32V20x ) void mrbcSleepDeep(uint32_t sleep_ms) { RCC->APB1PCENR |= RCC_APB1Periph_PWR | RCC_APB1Periph_BKP; // back up __disable_irq(); GPIOA->CFGLR = 0; GPIOB->CFGLR = 0; GPIOC->CFGLR = 0; GPIOD->CFGLR = 0; GPIOE->CFGLR = 0; GPIOF->CFGLR = 0; GPIOG->CFGLR = 0; EXTI->EVENR |= EXTI_Line17; EXTI->RTENR |= EXTI_Line17; RCC->RSTSCKR |= RCC_LSION; while ( !(RCC->RSTSCKR & RCC_LSIRDY) ); PWR->CTLR |= PWR_CTLR_DBP; RCC->BDCTLR |= RCC_BDRST; RCC->BDCTLR &=~ RCC_BDRST; RCC->BDCTLR = RCC_RTCSEL_LSI; RCC->BDCTLR |= RCC_RTCEN; RTC->CTLRL &= ~RTC_FLAG_RSF; while (!(RTC->CTLRL & RTC_FLAG_RSF)); RTC->CTLRL &= ~(RTC_CTLRL_ALRF | RTC_CTLRL_SECF | RTC_CTLRL_OWF); while (!(RTC->CTLRL & RTC_FLAG_RTOFF)); RTC->CTLRL |= RTC_CTLRL_CNF; // config start RTC->PSCRH = 0; RTC->PSCRL = 39; // 40kHz -> 1kHz while (!(RTC->CTLRL & RTC_FLAG_RTOFF)); RTC->CTLRL &= ~RTC_CTLRL_CNF; // config end uint32_t current_cnt = ((uint32_t)RTC->CNTH << 16) | RTC->CNTL; uint32_t target_alarm = current_cnt + sleep_ms; while (!(RTC->CTLRL & RTC_FLAG_RTOFF)); RTC->CTLRL |= RTC_CTLRL_CNF; // config start RTC->ALRMH = (target_alarm >> 16) & 0xFFFF; RTC->ALRML = target_alarm & 0xFFFF; while (!(RTC->CTLRL & RTC_FLAG_RTOFF)); RTC->CTLRL &= ~RTC_CTLRL_CNF; // config end RTC->CTLRL &= ~RTC_CTLRL_ALRF; RTC->CTLRH |= RTC_CTLRH_ALRIE; PWR->CTLR |= PWR_CTLR_PDDS; PFIC->SCTLR |= (1 << 2); __WFE(); PFIC->CFGR = NVIC_KEY3 | (1<<7) ; while(1); } #else void mrbcSleepDeep(uint32_t seconds) { RCC->APB1PCENR |= RCC_APB1Periph_PWR; __disable_irq(); GPIOA->CFGLR = 0; GPIOB->CFGLR = 0; GPIOC->CFGLR = 0; GPIOD->CFGLR = 0; #if defined( CH32V00x ) RCC->RSTSCKR |= RCC_LSION; while ((RCC->RSTSCKR & RCC_LSIRDY) == 0); EXTI->EVENR |= EXTI_Line9; EXTI->FTENR |= EXTI_Line9; PWR->AWUPSC |= PWR_AWU_Prescaler_1024; PWR->AWUCSR |= (1 << 1); #elif defined( CH32X03x ) GPIOA->CFGHR = 0; GPIOB->CFGHR = 0; GPIOC->CFGHR = 0; GPIOD->CFGHR = 0; EXTI->EVENR |= EXTI_Line27; EXTI->RTENR |= EXTI_Line27; AWU->PSC = AWU_Prescaler_1024; // 2^(n-1), 14:2^13*1.25, 15:2^14*3.75 AWU->CSR |= (1 << 1); #endif PWR->CTLR |= PWR_CTLR_PDDS; PFIC->SCTLR |= (1 << 2); while (seconds--){ #if defined( CH32V00x ) PWR->AWUWR = 39; //1s #elif defined( CH32X03x ) AWU->WR = 46; // 1s #endif __WFE(); } //reset PFIC->CFGR = NVIC_KEY3 | (1<<7) ; while(1); } #endif /* #include "rtc.h" void mrbcSleepDeep(uint32_t sleep_ms) { //RCC->APB1PCENR &= ~RCC_APB1Periph_USB; //NVIC_DisableIRQ(USBHD_IRQn); __disable_irq(); RTC_init(); RTC_setAlarmRelative(0, sleep_ms); PWR->CTLR |= PWR_CTLR_PDDS; PFIC->SCTLR |= (1 << 2); __WFE(); Delay_Ms(100); } */ #endif