diff --git a/inc/MockTests.cpp b/inc/MockTests.cpp new file mode 100644 index 0000000..6ee9c02 --- /dev/null +++ b/inc/MockTests.cpp @@ -0,0 +1,12 @@ +#include "CppUTest/CommandLineTestRunner.h" + +// ImportTestGroups +IMPORT_TEST_GROUP(test_MockRegEdit); +IMPORT_TEST_GROUP(test_MockADC); + +// START: main +int main(int argc, char **argv) +{ + return RUN_ALL_TESTS(argc, argv); +} +// END: main diff --git a/inc/ch32h41xhw.h b/inc/ch32h41xhw.h index 17b87ac..fd660a1 100644 --- a/inc/ch32h41xhw.h +++ b/inc/ch32h41xhw.h @@ -299,18 +299,31 @@ typedef enum IRQn #define DEFAULT_INTERRUPT_VECTOR_CONTENTS BASE_VECTOR "\n.option pop;\n" - - /* memory mapped structure for SysTick */ typedef struct { __IO uint32_t CTLR; __IO uint32_t SR; - __IO uint64_t CNT; - uint32_t RESERVED0; - __IO uint64_t CMP; + union + { + struct + { + __IO uint32_t CNTL; + __IO uint32_t CNTH; + __IO uint32_t CMPL; + __IO uint32_t CMPH; + }; + struct + { + __IO uint64_t CNT; + __IO uint64_t CMP; + }; + }; } SysTick_Type; +#define funSysTick32() (SysTick->CNTL) +#define funSysTickHigh() (SysTick->CNTH) + #endif /* __ASSEMBLER__*/ @@ -13633,7 +13646,11 @@ typedef enum #ifndef __ASSEMBLER__ /* Output Maximum frequency selection */ + +#ifndef __ZEPHYR__ #warning "Speeds on H41x have their own register, dont concat in CFGLR" +#endif + typedef enum { GPIO_Speed_10MHz = 0, diff --git a/inc/ch32l103hw.h b/inc/ch32l103hw.h index dc4ab82..200de26 100644 --- a/inc/ch32l103hw.h +++ b/inc/ch32l103hw.h @@ -165,6 +165,7 @@ typedef struct __IO uint64_t CMP; } SysTick_Type; +#define funSysTick32() (SysTick->CNT) #endif /* __ASSEMBLER__*/ @@ -7490,6 +7491,16 @@ typedef enum #define RTC_FLAG_ALR ((uint16_t)0x0002) /* Alarm flag */ #define RTC_FLAG_SEC ((uint16_t)0x0001) /* Second flag */ +// Wait for last write operation to complete, enter configuration mode +// perform configuration +// wait for last write operation to complete,exit configuration mode +#define RTC_CONFIG_CHANGE(a) do { \ + while (!(RTC->CTLRL & RTC_FLAG_RTOFF)); \ + RTC->CTLRL |= RTC_CTLRL_CNF; \ + {a} \ + while (!(RTC->CTLRL & RTC_FLAG_RTOFF)); \ + RTC->CTLRL &= ~RTC_CTLRL_CNF; \ +} while (0) /* ch32v00x_spi.h ------------------------------------------------------------*/ diff --git a/inc/ch32v003hw.h b/inc/ch32v003hw.h index 6ebbcbf..8b156df 100644 --- a/inc/ch32v003hw.h +++ b/inc/ch32v003hw.h @@ -101,6 +101,7 @@ typedef struct uint32_t RESERVED1; } SysTick_Type; +#define funSysTick32() (SysTick->CNT) #endif /* __ASSEMBLER__*/ @@ -218,8 +219,8 @@ typedef struct { __I uint16_t REVID; __I uint16_t DEVID; - }s; - }u; + }; + }; } INFO_TypeDef; /* General Purpose I/O */ @@ -257,7 +258,7 @@ typedef union { GPIO_CFGLR_PIN_MODE_Typedef PIN5 :4; GPIO_CFGLR_PIN_MODE_Typedef PIN6 :4; GPIO_CFGLR_PIN_MODE_Typedef PIN7 :4; - }s; + }; } GPIO_CFGLR_t; typedef union { uint32_t __FULL; @@ -271,7 +272,7 @@ typedef union { uint32_t IDR6 :1; uint32_t IDR7 :1; uint32_t :24; - }s; + }; } GPIO_INDR_t; typedef union { uint32_t __FULL; @@ -285,7 +286,7 @@ typedef union { uint32_t ODR6 :1; uint32_t ODR7 :1; uint32_t :24; - }s; + }; } GPIO_OUTDR_t; typedef union { uint32_t __FULL; @@ -308,7 +309,7 @@ typedef union { uint32_t BR6 :1; uint32_t BR7 :1; uint32_t :8; - }s; + }; } GPIO_BSHR_t; typedef union { uint32_t __FULL; @@ -322,7 +323,7 @@ typedef union { uint32_t BR6 :1; uint32_t BR7 :1; uint32_t :24; - }s; + }; } GPIO_BCR_t; typedef union { uint32_t __FULL; @@ -337,7 +338,7 @@ typedef union { uint32_t LCK7 :1; uint32_t LCKK :1; uint32_t :23; - }s; + }; } GPIO_LCKR_t; typedef struct { diff --git a/inc/ch32v10xhw.h b/inc/ch32v10xhw.h index 103a60b..1122600 100644 --- a/inc/ch32v10xhw.h +++ b/inc/ch32v10xhw.h @@ -168,6 +168,9 @@ typedef struct __attribute__((packed)) }; } SysTick_Type; +#define funSysTick32() (SysTick->CNTL) +#define funSysTickHigh() (SysTick->CNTH) + #endif /* __ASSEMBLER__*/ #define HardFault_IRQn EXC_IRQn diff --git a/inc/ch32v20xhw.h b/inc/ch32v20xhw.h index df2dacd..ce9d031 100644 --- a/inc/ch32v20xhw.h +++ b/inc/ch32v20xhw.h @@ -200,6 +200,7 @@ typedef struct __IO uint64_t CMP; } SysTick_Type; +#define funSysTick32() (SysTick->CNT) #endif /* __ASSEMBLER__*/ @@ -4502,7 +4503,7 @@ typedef struct{ #define RCC_USBPRE_DIV3 ((uint32_t)0x00800000) /* PLL clock divided by 3 (PLLCLK = 144MHz) */ #define RCC_USBPRE_DIV5 ((uint32_t)0x00C00000) /* PLL clock divided by 5, PLL source is HSE/2 (PLLCLK = 240MHz) */ -#define RCC_CFGR0_MCO ((uint32_t)0x07000000) /* MCO[2:0] bits (Microcontroller Clock Output) */ +#define RCC_CFGR0_MCO ((uint32_t)0x0F000000) /* MCO[3:0] bits (Microcontroller Clock Output) */ #define RCC_MCO_0 ((uint32_t)0x01000000) /* Bit 0 */ #define RCC_MCO_1 ((uint32_t)0x02000000) /* Bit 1 */ #define RCC_MCO_2 ((uint32_t)0x04000000) /* Bit 2 */ @@ -4513,6 +4514,10 @@ typedef struct{ #define RCC_CFGR0_MCO_HSI ((uint32_t)0x05000000) /* HSI clock selected as MCO source */ #define RCC_CFGR0_MCO_HSE ((uint32_t)0x06000000) /* HSE clock selected as MCO source */ #define RCC_CFGR0_MCO_PLL ((uint32_t)0x07000000) /* PLL clock divided by 2 selected as MCO source */ +#define RCC_CFGR0_MCO_PLL2 ((uint32_t)0x08000000) /* PLL2 clock selected as MCO source */ +#define RCC_CFGR0_MCO_PLL3DIV2 ((uint32_t)0x09000000) /* PLL3 clock divided by 2 selected as MCO source */ +#define RCC_CFGR0_MCO_XT1 ((uint32_t)0x0A000000) /* XT1 external oscillator clock selected as MCO source */ +#define RCC_CFGR0_MCO_PLL3 ((uint32_t)0x0B000000) /* PLL3 clock selected as MCO source */ #define RCC_ADCDUTY ((uint32_t)0x80000000) /* ADC clock duty cycle adjustment */ #define RCC_ADC_DUTY_SEL ((uint32_t)0x40000000) /* ADC clock duty cycle selection */ @@ -7678,6 +7683,17 @@ typedef struct #define RTC_FLAG_ALR ((uint16_t)0x0002) /* Alarm flag */ #define RTC_FLAG_SEC ((uint16_t)0x0001) /* Second flag */ +// Wait for last write operation to complete, enter configuration mode +// perform configuration +// wait for last write operation to complete,exit configuration mode +#define RTC_CONFIG_CHANGE(a) do { \ + while (!(RTC->CTLRL & RTC_FLAG_RTOFF)); \ + RTC->CTLRL |= RTC_CTLRL_CNF; \ + {a} \ + while (!(RTC->CTLRL & RTC_FLAG_RTOFF)); \ + RTC->CTLRL &= ~RTC_CTLRL_CNF; \ +} while (0) + #if defined(CH32V20x_D8) || defined(CH32V20x_D8W) #define RB_OSC32K_HTUNE (0x1FE0) #define RB_OSC32K_LTUNE (0x1F) diff --git a/inc/ch32v30xhw.h b/inc/ch32v30xhw.h index 35c73e0..8d9f093 100644 --- a/inc/ch32v30xhw.h +++ b/inc/ch32v30xhw.h @@ -260,6 +260,7 @@ typedef struct __IO uint64_t CMP; } SysTick_Type; +#define funSysTick32() (SysTick->CNT) #endif /* __ASSEMBLER__*/ @@ -10585,6 +10586,22 @@ typedef struct #define PD13 61 #define PD14 62 #define PD15 63 +#define PE0 64 +#define PE1 65 +#define PE2 66 +#define PE3 67 +#define PE4 68 +#define PE5 69 +#define PE6 70 +#define PE7 71 +#define PE8 72 +#define PE9 73 +#define PE10 74 +#define PE11 75 +#define PE12 76 +#define PE13 77 +#define PE14 78 +#define PE15 79 /* * This file contains various parts of the official WCH EVT Headers which diff --git a/inc/ch32x00xhw.h b/inc/ch32x00xhw.h index a89788c..fce5293 100644 --- a/inc/ch32x00xhw.h +++ b/inc/ch32x00xhw.h @@ -95,7 +95,9 @@ typedef enum IRQn .word TIM1_TRG_COM_IRQHandler /* TIM1 Trigger and Commutation */ \n\ .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */ \n\ .word TIM2_IRQHandler /* TIM2 */ \n\ - .option pop;\n" + .word USART2_IRQHandler /* USART2 */ \n\ + .word OPCM_IRQHandler /* OPCM */ \n\ + .option pop;\n" /* memory mapped structure for SysTick */ @@ -109,6 +111,7 @@ typedef struct uint32_t RESERVED1; } SysTick_Type; +#define funSysTick32() (SysTick->CNT) #endif /* __ASSEMBLER__*/ @@ -781,6 +784,10 @@ typedef struct /******************* Bit definition for ADC_CTLR2 register ********************/ #define ADC_ADON ((uint32_t)0x00000001) /* A/D Converter ON / OFF */ #define ADC_CONT ((uint32_t)0x00000002) /* Continuous Conversion */ + +#define ADC_CAL ((uint32_t)0x00000004) /* Calibrate */ +#define ADC_RSTCAL ((uint32_t)0x00000008) /* Reset Calibration */ + #define ADC_TGREGU ((uint32_t)0x00000010) /* External trigger event of rule channel conversion */ #define ADC_TGINJE ((uint32_t)0x00000020) /* External trigger event of injection channel conversion */ #define ADC_DMA ((uint32_t)0x00000100) /* Direct Memory access mode */ @@ -798,13 +805,13 @@ typedef struct #define ADC_EXTSEL_1 ((uint32_t)0x00040000) /* Bit 1 */ #define ADC_EXTSEL_2 ((uint32_t)0x00080000) /* Bit 2 */ #define ADC_EXTSEL_TRGO_1 ((uint32_t)0x00000000) /* TRGO event of timer 1 */ -#define ADC_EXTSEL_CC1_1 ((uint32_t)0x00000000) /* CC1 event of timer 1 */ -#define ADC_EXTSEL_CC2_1 ((uint32_t)0x00000000) /* CC2 event of timer 1 */ -#define ADC_EXTSEL_TRGO_2 ((uint32_t)0x00000000) /* TRGO event of timer 2 */ -#define ADC_EXTSEL_CC1_2 ((uint32_t)0x00000000) /* CC1 event of timer 2 */ -#define ADC_EXTSEL_CC2_2 ((uint32_t)0x00000000) /* CC2 event of timer 2 */ -#define ADC_EXTSEL_OPA ((uint32_t)0x00000000) /* OPA trigger/(PD3/PC2) */ -#define ADC_EXTSEL_SWSTART ((uint32_t)0x00000000) /* SWSTART software trigger */ +#define ADC_EXTSEL_CC1_1 ((uint32_t)0x00020000) /* CC1 event of timer 1 */ +#define ADC_EXTSEL_CC2_1 ((uint32_t)0x00040000) /* CC2 event of timer 1 */ +#define ADC_EXTSEL_TRGO_2 ((uint32_t)0x00060000) /* TRGO event of timer 2 */ +#define ADC_EXTSEL_CC1_2 ((uint32_t)0x00080000) /* CC1 event of timer 2 */ +#define ADC_EXTSEL_CC2_2 ((uint32_t)0x000A0000) /* CC2 event of timer 2 */ +#define ADC_EXTSEL_OPA ((uint32_t)0x000C0000) /* OPA trigger/(PD3/PC2) */ +#define ADC_EXTSEL_SWSTART ((uint32_t)0x000E0000) /* SWSTART software trigger */ #define ADC_EXTTRIG ((uint32_t)0x00100000) /* External Trigger Conversion mode for regular channels */ #define ADC_JSWSTART ((uint32_t)0x00200000) /* Start Conversion of injected channels */ @@ -2480,6 +2487,7 @@ typedef struct #define TIM2_DMAINTENR_CC2DE ((uint16_t)0x0400) /* Capture/Compare 2 DMA request enable */ #define TIM2_DMAINTENR_CC3DE ((uint16_t)0x0800) /* Capture/Compare 3 DMA request enable */ #define TIM2_DMAINTENR_CC4DE ((uint16_t)0x1000) /* Capture/Compare 4 DMA request enable */ +#define TIM2_DMAINTENR_COMDE ((uint16_t)0x2000) /* COM DMA request enable */ #define TIM2_DMAINTENR_TDE ((uint16_t)0x4000) /* Trigger DMA request enable */ /******************* Bit definition for TIM2_INTFR register *****************/ diff --git a/inc/ch32x03xhw.h b/inc/ch32x03xhw.h index 42e7cd7..efeb176 100644 --- a/inc/ch32x03xhw.h +++ b/inc/ch32x03xhw.h @@ -149,6 +149,8 @@ typedef struct }; } SysTick_Type; +#define funSysTick32() (SysTick->CNTL) +#define funSysTickHigh() (SysTick->CNTH) #endif /* __ASSEMBLER__*/ diff --git a/inc/ch5xxhw.h b/inc/ch5xxhw.h index 7137356..a7fb74b 100644 --- a/inc/ch5xxhw.h +++ b/inc/ch5xxhw.h @@ -167,17 +167,51 @@ typedef struct __attribute__((packed)) uint8_t RESERVED0[4]; #elif defined(CH571_CH573) __IO uint32_t CTLR; - __IO uint64_t CNT; - __IO uint64_t CMP; + union + { + struct + { + __IO uint32_t CNTL; + __IO uint32_t CNTH; + __IO uint32_t CMPL; + __IO uint32_t CMPH; + }; + struct + { + __IO uint64_t CNT; + __IO uint64_t CMP; + }; + }; __IO uint32_t CNTFG; #else __IO uint32_t CTLR; __IO uint32_t SR; - __IO uint64_t CNT; - __IO uint64_t CMP; + union + { + struct + { + __IO uint32_t CNTL; + __IO uint32_t CNTH; + __IO uint32_t CMPL; + __IO uint32_t CMPH; + }; + struct + { + __IO uint64_t CNT; + __IO uint64_t CMP; + }; + }; #endif } SysTick_Type; + +#if (defined(CH570_CH572) || defined(CH584_CH585)) +#define funSysTick32() (SysTick->CNT) +#else +#define funSysTick32() (SysTick->CNTL) +#define funSysTickHigh() (SysTick->CNTH) +#endif + /* memory mapped structure for Program Fast Interrupt Controller (PFIC) */ typedef struct { @@ -207,6 +241,228 @@ typedef struct } PFIC_Type; #endif /* __ASSEMBLER__*/ +#ifdef CH570_CH572 +typedef struct { + union { + __IO uint32_t CTRL; + struct { + __IO uint8_t CTRL0; + __IO uint8_t CTRL1; + __IO uint8_t CTRL2; + __IO uint8_t CTRL3; + }; + }; +} CMP_TypeDef; +#endif + +typedef struct { +#if defined(CH570_CH572) + __IO uint16_t PA_INT_EN; // 0H + uint16_t RESERVED0; // 2H + __IO uint16_t PA_INT_MODE; // 4H + __IO uint16_t PA_INT_EDGE_TYPE; // 6H + uint32_t RESERVED1; // 8H + __IO uint16_t PA_INT_IF; // CH + uint16_t RESERVED2; // EH +#else + __IO uint16_t PA_INT_EN; // 0H + __IO uint16_t PB_INT_EN; // 2H + __IO uint16_t PA_INT_MODE; // 4H + __IO uint16_t PB_INT_MODE; // 6H +#if defined(CH591_CH592) + __IO uint16_t PA_INT_EDGE_TYPE; // 8H + __IO uint16_t PB_INT_EDGE_TYPE; // AH +#else + uint32_t RESERVED0; // 8H +#endif + __IO uint16_t PA_INT_IF; // CH + __IO uint16_t PB_INT_IF; // EH +#endif + __IO uint32_t PA_DIR; // 10H + __IO uint32_t PA_PIN; // 14H + __IO uint32_t PA_OUT; // 18H + __IO uint32_t PA_CLR; // 1CH + __IO uint32_t PA_PU; // 20H + __IO uint32_t PA_PD_DRV; // 24H + __IO uint32_t PA_SET; // 28H +#if defined(CH571_CH573) || defined(CH582_CH583) || defined(CH584_CH585) || defined(CH591_CH592) + uint32_t RESERVED1; // 2CH + __IO uint32_t PB_DIR; // 30H + __IO uint32_t PB_PIN; // 34H + __IO uint32_t PB_OUT; // 38H + __IO uint32_t PB_CLR; // 3CH + __IO uint32_t PB_PU; // 40H + __IO uint32_t PB_PD_DRV; // 44H + __IO uint32_t PB_SET; // 48H +#endif +} GPIO_TypeDef; + +#ifndef CH571_CH573 +typedef struct { + __IO uint16_t CTRL1; // 0H + uint16_t RESERVED0; // 2H + __IO uint16_t CTRL2; // 4H + uint16_t RESERVED1; // 6H + __IO uint16_t OADDR1; // 8H + uint16_t RESERVED2; // AH + __IO uint16_t OADDR2; // CH + uint16_t RESERVED3; // EH + __IO uint16_t DATAR; // 10H + uint16_t RESERVED4; // 12H + __IO uint16_t STAR1; // 14H + uint16_t RESERVED5; // 16H + __IO uint16_t STAR2; // 18H + uint16_t RESERVED6; // 1AH + __IO uint16_t CKCFGR; // 1CH + uint16_t RESERVED7; // 1EH + __IO uint16_t RTR; // 20H +} I2C_TypeDef; +#endif + +#ifdef CH570_CH572 +typedef struct { + __IO uint16_t CTRL; // 0H + __IO uint8_t INT_EN; // 2H + __IO uint8_t INT_FLAG; // 3H + __IO uint16_t SCAN_NUMB; // 4H +} KeyScan_TypeDef; +#endif + +typedef struct { + __IO uint8_t OUT_EN; // 0H + __IO uint8_t OUT_POLAR; // 1H + __IO uint8_t CONFIG; // 2H +#ifdef CH570_CH572 + __IO uint8_t DMA_CTRL; // 3H + __packed union { + __packed struct { + __IO uint8_t PWM1_R8_DATA; // 4H + __IO uint8_t PWM2_R8_DATA; // 5H + __IO uint8_t PWM3_R8_DATA; // 6H + uint8_t RESERVED0[3]; // 7H + }; + __packed struct { + __IO uint16_t PWM1_R16_DATA; // 4H + __IO uint16_t PWM2_R16_DATA; // 6H + __IO uint16_t PWM3_R16_DATA; // 8H + }; + }; + uint16_t RESERVED1; // AH + __IO uint8_t INT_EN; // CH + __IO uint8_t INT_FLAG; // DH + uint16_t RESERVED2; // EH + __packed union { + __packed struct { + __IO uint8_t PWM4_R8_DATA; // 10H + __IO uint8_t PWM5_R8_DATA; // 11H + uint16_t RESERVED3; // 12H + }; + __packed struct { + __IO uint16_t PWM4_R16_DATA; // 10H + __IO uint16_t PWM5_R16_DATA; // 12H + }; + }; + __IO uint16_t CYC_VALUE; // 14H + __IO uint16_t CYC1_VALUE; // 16H + __IO uint16_t CLOCK_DIV; // 18H + uint16_t RESERVED4; // 1AH + __IO uint32_t DMA_NOW; // 1CH + __IO uint32_t DMA_BEG; // 20H + __IO uint32_t DMA_END; // 24H +#else + __IO uint8_t CLOCK_DIV; // 3H + __IO uint8_t PWM4_DATA; // 4H + __IO uint8_t PWM5_DATA; // 5H + __IO uint8_t PWM6_DATA; // 6H + __IO uint8_t PWM7_DATA; // 7H + __IO uint8_t PWM8_DATA; // 8H + __IO uint8_t PWM9_DATA; // 9H + __IO uint8_t PWM10_DATA; // AH + __IO uint8_t PWM11_DATA; // BH + __IO uint8_t INT_CTRL; // CH +#if defined(CH584_CH585) || defined(CH591_CH592) + uint8_t RESERVED5[3]; // DH + __IO uint32_t REG_DATA8; // 10H + __IO uint32_t REG_CYCLE; // 14H +#endif +#endif +} PWM_TypeDef; + +typedef struct { + __IO uint8_t CTRL_MOD; // 0H + __IO uint8_t CTRL_CFG; // 1H + __IO uint8_t INTER_EN; // 2H + __IO uint8_t CLKDIV_SLAVE_PRE; // 3H + __IO uint8_t BUFFER; // 4H + __IO uint8_t RUN_FLAG; // 5H + __IO uint8_t INT_FLAG; // 6H + __IO uint8_t FIFO_COUNT; // 7H +#ifdef CH570_CH572 + __IO uint8_t INT_TYPE; // 8H + __IO uint8_t INTER1_EN; // 9H + __IO uint8_t INTER1_FLAG; // AH +#else + uint8_t RESERVED0[3]; // 8H +#endif + __IO uint16_t TOTAL_CNT; // CH + uint16_t RESERVED1; // EH + __IO uint8_t FIFO; // 10H + uint8_t RESERVED2[2]; // 11H + __IO uint8_t COUNT1; // 13H + __IO uint16_t DMA_NOW; // 14H + uint16_t RESERVED3; // 16H + __IO uint16_t DMA_BEG; // 18H + uint16_t RESERVED4; // 1AH + __IO uint16_t DMA_END; // 1CH +} SPI_TypeDef; + +typedef struct { + __IO uint8_t CTRL_MOD; // 0H + __IO uint8_t CTRL_DMA; // 1H + __IO uint8_t INTER_EN; // 2H + uint8_t RESERVED0; // 3H + __IO uint8_t PWM_MOD; // 4H + uint8_t RESERVED1; // 5H + __IO uint8_t INT_FLAG; // 6H + __IO uint8_t FIFO_COUNT; // 7H + __IO uint32_t COUNT; // 8H + __IO uint32_t CNT_END; // CH + __IO uint32_t FIFO; // 10H + __IO uint16_t DMA_NOW; // 14H + uint16_t RESERVED2; // 16H + __IO uint16_t DMA_BEG; // 18H + uint16_t RESERVED3; // 1AH + __IO uint16_t DMA_END; // 1CH +#if defined(CH570_CH572) + uint16_t RESERVED4; // 1EH + __IO uint8_t ENC_REG_CTRL; // 20H + __IO uint8_t ENC_INTER_EN; // 21H + __IO uint8_t ENC_INTER_FLAG; // 22H + uint8_t RESERVED5; // 23H + __IO uint32_t ENC_REG_CEND; // 24H + __IO uint32_t ENC_REG_CCNT; // 28H +#endif +} TMR_TypeDef; + +typedef struct { + __IO uint8_t MCR; + __IO uint8_t IER; + __IO uint8_t FCR; + __IO uint8_t LCR; + __IO uint8_t IIR; + __IO uint8_t LSR; + __IO uint8_t MSR; + uint8_t RESERVED1; + __IO uint8_t THR_RBR; + uint8_t RESERVED2; + __IO uint8_t RFC; + __IO uint8_t TFC; + __IO uint16_t DL; + __IO uint8_t DIV; + __IO uint8_t ADR; +} UART_TypeDef; + + #ifdef __ASSEMBLER__ #define CORE_PERIPH_BASE (0xE0000000) /* System peripherals base address in the alias region */ #else @@ -322,13 +578,13 @@ typedef enum CLK_SOURCE_HSE_PLL_78MHz = (0x300 | 0x40 | 4), // RTC does not work at this speed, so low power sleep also not! CLK_SOURCE_HSE_PLL_62_4MHz = (0x300 | 0x40 | 5), - #define CLK_SOURCE_PLL_60MHz "The ch584/5 does not support an exact 60MHz setting. Please pick an availabe clock source from the SYS_CLKTypeDef struct in ch5xxhw.h" CLK_SOURCE_HSE_PLL_52MHz = (0x300 | 0x40 | 6), CLK_SOURCE_HSE_PLL_39MHz = (0x300 | 0x40 | 8), CLK_SOURCE_HSE_PLL_26MHz = (0x300 | 0x40 | 12), CLK_SOURCE_HSE_PLL_24MHz = (0x300 | 0x40 | 13), CLK_SOURCE_HSE_PLL_19_5MHz = (0x300 | 0x40 | 16), CLK_SOURCE_HSE_PLL_13MHz = (0x300 | 0x40 | 24), + #define CLK_SOURCE_PLL_60MHz 0xFF // Dummy to catch wrong clock setting for this chip #elif defined(CH591_CH592) CLK_SOURCE_LSI = 0x00, CLK_SOURCE_LSE, @@ -346,6 +602,13 @@ typedef enum #endif } SYS_CLKTypeDef; +#if (defined(CH570_CH572)) +#define ROM_CFG_MAC_ADDR ((const u32*)0x0003f018) +#elif defined(CH582_CH583) +#define ROM_CFG_MAC_ADDR ((const u32*)0x0007F018) +#define ROM_CFG_TMP_25C ((const u32*)0x0007F014) +#endif + // For debug writing to the debug interface, and USB ISP. #if (defined(CH570_CH572) || defined(CH584_CH585)) #define DMDATA0 ((vu32*)0xe0000340) @@ -753,11 +1016,7 @@ typedef enum #define RB_ROM_CODE_OFS 0x10 // RWA, code offset address selection in Flash ROM: 0=start address 0x000000, 1=start address 0x040000 #define RB_ROM_CTRL_EN 0x20 // RWA, enable flash ROM control interface enable: 0=disable access, 1=enable access control register #define RB_ROM_DATA_WE 0x40 // RWA, enable flash ROM data & code area being erase/write: 0=all writing protect, 1=enable data area program and erase -#ifdef CH570_CH572 #define RB_ROM_CODE_WE 0xC0 // RWA, enable flash ROM code area being erase/write: 0=code writing protect, 1=enable code area program and erase -#else -#define RB_ROM_CODE_WE 0x80 // RWA, enable flash ROM code area being erase/write: 0=code writing protect, 1=enable code area program and erase -#endif #define R8_GLOB_CFG_INFO (*((vu8*)0x40001045)) // RO, global configuration information and status #define RB_CFG_ROM_READ 0x01 // RO, indicate protected status of Flash ROM code and data: 0=reading protect, 1=enable read by external programmer #define RB_CFG_RESET_EN 0x04 // RO, manual reset input enable status @@ -975,49 +1234,49 @@ typedef enum #define R32_PB_SET (*((vu32*)0x400010D8)) // RW, PB set high for output ,1=set output high,0=IDLE #endif -#define PA0 (0x00000001) /*!< Pin 0 selected */ -#define PA1 (0x00000002) /*!< Pin 1 selected */ -#define PA2 (0x00000004) /*!< Pin 2 selected */ -#define PA3 (0x00000008) /*!< Pin 3 selected */ -#define PA4 (0x00000010) /*!< Pin 4 selected */ -#define PA5 (0x00000020) /*!< Pin 5 selected */ -#define PA6 (0x00000040) /*!< Pin 6 selected */ -#define PA7 (0x00000080) /*!< Pin 7 selected */ -#define PA8 (0x00000100) /*!< Pin 8 selected */ -#define PA9 (0x00000200) /*!< Pin 9 selected */ -#define PA10 (0x00000400) /*!< Pin 10 selected */ -#define PA11 (0x00000800) /*!< Pin 11 selected */ -#define PA12 (0x00001000) /*!< Pin 12 selected */ -#define PA13 (0x00002000) /*!< Pin 13 selected */ -#define PA14 (0x00004000) /*!< Pin 14 selected */ -#define PA15 (0x00008000) /*!< Pin 15 selected */ +#define PA0 (0) /*!< Pin 0 selected */ +#define PA1 (1) /*!< Pin 1 selected */ +#define PA2 (2) /*!< Pin 2 selected */ +#define PA3 (3) /*!< Pin 3 selected */ +#define PA4 (4) /*!< Pin 4 selected */ +#define PA5 (5) /*!< Pin 5 selected */ +#define PA6 (6) /*!< Pin 6 selected */ +#define PA7 (7) /*!< Pin 7 selected */ +#define PA8 (8) /*!< Pin 8 selected */ +#define PA9 (9) /*!< Pin 9 selected */ +#define PA10 (10) /*!< Pin 10 selected */ +#define PA11 (11) /*!< Pin 11 selected */ +#define PA12 (12) /*!< Pin 12 selected */ +#define PA13 (13) /*!< Pin 13 selected */ +#define PA14 (14) /*!< Pin 14 selected */ +#define PA15 (15) /*!< Pin 15 selected */ #ifndef CH570_CH572 #define PB (0x80000000) /* Bit mask to indicate bank B */ -#define PB0 (0x80000001) /*!< Pin 0 selected */ -#define PB1 (0x80000002) /*!< Pin 1 selected */ -#define PB2 (0x80000004) /*!< Pin 2 selected */ -#define PB3 (0x80000008) /*!< Pin 3 selected */ -#define PB4 (0x80000010) /*!< Pin 4 selected */ -#define PB5 (0x80000020) /*!< Pin 5 selected */ -#define PB6 (0x80000040) /*!< Pin 6 selected */ -#define PB7 (0x80000080) /*!< Pin 7 selected */ -#define PB8 (0x80000100) /*!< Pin 8 selected */ -#define PB9 (0x80000200) /*!< Pin 9 selected */ -#define PB10 (0x80000400) /*!< Pin 10 selected */ -#define PB11 (0x80000800) /*!< Pin 11 selected */ -#define PB12 (0x80001000) /*!< Pin 12 selected */ -#define PB13 (0x80002000) /*!< Pin 13 selected */ -#define PB14 (0x80004000) /*!< Pin 14 selected */ -#define PB15 (0x80008000) /*!< Pin 15 selected */ -#define PB16 (0x80010000) /*!< Pin 16 selected */ -#define PB17 (0x80020000) /*!< Pin 17 selected */ -#define PB18 (0x80040000) /*!< Pin 18 selected */ -#define PB19 (0x80080000) /*!< Pin 19 selected */ -#define PB20 (0x80100000) /*!< Pin 20 selected */ -#define PB21 (0x80200000) /*!< Pin 21 selected */ -#define PB22 (0x80400000) /*!< Pin 22 selected */ -#define PB23 (0x80800000) /*!< Pin 23 selected */ +#define PB0 (PB|0) /*!< Pin 0 selected */ +#define PB1 (PB|1) /*!< Pin 1 selected */ +#define PB2 (PB|2) /*!< Pin 2 selected */ +#define PB3 (PB|3) /*!< Pin 3 selected */ +#define PB4 (PB|4) /*!< Pin 4 selected */ +#define PB5 (PB|5) /*!< Pin 5 selected */ +#define PB6 (PB|6) /*!< Pin 6 selected */ +#define PB7 (PB|7) /*!< Pin 7 selected */ +#define PB8 (PB|8) /*!< Pin 8 selected */ +#define PB9 (PB|9) /*!< Pin 9 selected */ +#define PB10 (PB|10) /*!< Pin 10 selected */ +#define PB11 (PB|11) /*!< Pin 11 selected */ +#define PB12 (PB|12) /*!< Pin 12 selected */ +#define PB13 (PB|13) /*!< Pin 13 selected */ +#define PB14 (PB|14) /*!< Pin 14 selected */ +#define PB15 (PB|15) /*!< Pin 15 selected */ +#define PB16 (PB|16) /*!< Pin 16 selected */ +#define PB17 (PB|17) /*!< Pin 17 selected */ +#define PB18 (PB|18) /*!< Pin 18 selected */ +#define PB19 (PB|19) /*!< Pin 19 selected */ +#define PB20 (PB|20) /*!< Pin 20 selected */ +#define PB21 (PB|21) /*!< Pin 21 selected */ +#define PB22 (PB|22) /*!< Pin 22 selected */ +#define PB23 (PB|23) /*!< Pin 23 selected */ #endif #define P_All (0xFFFFFFFF) /*!< All pins selected */ @@ -1093,6 +1352,8 @@ typedef enum #define R32_ENC_REG_CEND (*((vu32*)0x40002424)) #define R32_ENC_REG_CCNT (*((vu32*)0x40002428)) #define BA_TMR ((vu8*)0x40002400) // point TMR base address + +#define TMR ((TMR_TypeDef*)BA_TMR) #else /* Timer0 register */ @@ -1182,6 +1443,11 @@ typedef enum #define BA_TMR1 ((vu8*)0x40002400) // point TMR1 base address #define BA_TMR2 ((vu8*)0x40002800) // point TMR2 base address #define BA_TMR3 ((vu8*)0x40002C00) // point TMR3 base address + +#define TMR0 ((TMR_TypeDef*)BA_TMR0) +#define TMR1 ((TMR_TypeDef*)BA_TMR1) +#define TMR2 ((TMR_TypeDef*)BA_TMR2) +#define TMR3 ((TMR_TypeDef*)BA_TMR3) #endif #define TMR_FIFO_SIZE 8 // timer FIFO size (depth) @@ -1379,6 +1645,12 @@ typedef enum #define UART_II_MODEM_CHG 0x00 // RO, UART0 interrupt by modem status change #define UART_II_NO_INTER 0x01 // RO, no UART interrupt is pending +#define UART ((UART_TypeDef*)BA_UART) +#define UART0 ((UART_TypeDef*)BA_UART0) +#define UART1 ((UART_TypeDef*)BA_UART1) +#define UART2 ((UART_TypeDef*)BA_UART2) +#define UART3 ((UART_TypeDef*)BA_UART3) + /* SPI0 register */ #define R32_SPI0_CONTROL (*((vu32*)0x40004000)) // RW, SPI0 control #define R8_SPI0_CTRL_MOD (*((vu8*)0x40004000)) // RW, SPI0 mode control @@ -1479,6 +1751,9 @@ typedef enum #define SPI_DMA_BEG 0x18 #define SPI_DMA_END 0x1C +#define SPI0 ((SPI_TypeDef*)BA_SPI0) +#define SPI1 ((SPI_TypeDef*)BA_SPI1) + /* I2C register */ #define R16_I2C_CTRL1 (*((vu16*)0x40004800)) // RW, I2C control 1 #define R16_I2C_CTRL2 (*((vu16*)0x40004804)) // RW, I2C control 2 @@ -1554,6 +1829,10 @@ typedef enum #define I2C_RTR 32 #define RB_I2C_TRISE 0x003F // RW, Maximum rise time in Fm/Sm mode (Master mode) +#ifndef CH571_CH573 +#define I2C ((I2C_TypeDef*)BA_I2C) +#endif + #ifdef CH57x /* PWM1/2/3/4/5/register */ #define R32_PWM_CONTROL (*((vu32*)0x40005000)) // RW, PWM control @@ -1701,6 +1980,8 @@ typedef enum #define PWM11_DATA_HOLD 11 #endif +#define PWMX ((PWM_TypeDef*)BA_PWMX) + #ifdef CH584_CH585 /* LCD register */ #define R8_LCD_CMD (*((vu8*)(0x40006000))) @@ -2444,168 +2725,6 @@ typedef enum #define LL_TX_POWER_7_DBM 0x3B -RV_STATIC_INLINE void LSIEnable() -{ - SYS_SAFE_ACCESS - ( -#ifdef CH570_CH572 - R8_LSI_CONFIG |= RB_CLK_LSI_PON; //turn on LSI -#else - R8_CK32K_CONFIG &= ~(RB_CLK_OSC32K_XT | RB_CLK_XT32K_PON); // turn off LSE - R8_CK32K_CONFIG |= RB_CLK_INT32K_PON; // turn on LSI -#endif - ); -} -RV_STATIC_INLINE void DCDCEnable() -{ -#ifndef CH570_CH572 // CH570/2 has no DCDC. - SYS_SAFE_ACCESS - ( - R16_AUX_POWER_ADJ |= RB_DCDC_CHARGE; - R16_POWER_PLAN |= RB_PWR_DCDC_PRE; - ); - - RTC_WAIT_TICKS(2); - - SYS_SAFE_ACCESS - ( - R16_POWER_PLAN |= RB_PWR_DCDC_EN; - ); -#endif -} - -RV_STATIC_INLINE void SleepInit() -{ - SYS_SAFE_ACCESS - ( - R8_RTC_MODE_CTRL |= RB_RTC_TRIG_EN; //enable RTC trigger - R8_SLP_WAKE_CTRL |= RB_SLP_RTC_WAKE; // enable wakeup control - ); - //enable RTC interrupt - NVIC->IENR[((uint32_t)(RTC_IRQn) >> 5)] = (1 << ((uint32_t)(RTC_IRQn) & 0x1F)); -} - -//clear RTC counters. -//probabily not needed for most cases, waking up from -//power off resets the RTC anyway. -RV_STATIC_INLINE void RTCInit() -{ - SYS_SAFE_ACCESS - ( - R32_RTC_TRIG = 0; - R32_RTC_CTRL |= RB_RTC_LOAD_HI; - R32_RTC_CTRL |= RB_RTC_LOAD_LO; - R8_RTC_MODE_CTRL |= RB_RTC_TRIG_EN; //enable RTC trigger - ); - -} - -//Set RTC to generate an interrupt after cyc ticks. -RV_STATIC_INLINE void RTCTrigger(uint32_t cyc) -{ - //get the rtc current time - uint32_t alarm = (uint32_t) R16_RTC_CNT_LSI | ( (uint32_t) R16_RTC_CNT_DIV1 << 16 ); - - alarm += cyc; - - if( alarm > RTC_MAX_COUNT ) - { - alarm -= RTC_MAX_COUNT; - } - - SYS_SAFE_ACCESS - ( - R32_RTC_TRIG = alarm; - ); -} - -// enter idle state -RV_STATIC_INLINE void LowPowerIdle(uint32_t cyc) -{ - RTCTrigger(cyc); - - NVIC->SCTLR &= ~(1 << 2); // don't deep sleep - NVIC->SCTLR &= ~(1 << 3); // wfi - asm volatile ("wfi\nnop\nnop" ); -} - -// This macro defines which power pin -// to use. If not defined correctly, sleep current -// will be higher than expected. -#ifndef FUNCONF_POWERED_BY_V5PIN -#define FUNCONF_POWERED_BY_V5PIN 0 -#endif - -RV_STATIC_INLINE void LowPowerSleep(uint32_t cyc, uint16_t power_plan) -{ -#if defined(CH570_CH572) && (FUNCONF_POWERED_BY_V5PIN == 1) - power_plan |= RB_PWR_LDO5V_EN; -#endif - - RTCTrigger(cyc); - -#ifdef CH570_CH572 -#if ( CLK_SOURCE_CH5XX == CLK_SOURCE_PLL_75MHz ) || ( CLK_SOURCE_CH5XX == CLK_SOURCE_PLL_100MHz ) - //if system clock is higher than 60Mhz, it need to be reduced before sleep. - SYS_SAFE_ACCESS - ( - R8_CLK_SYS_CFG = CLK_SOURCE_PLL_60MHz; - ); -#endif -#else - SYS_SAFE_ACCESS - ( - R8_BAT_DET_CTRL = 0; - R8_XT32K_TUNE = (R16_RTC_CNT_32K > 0x3fff) ? (R8_XT32K_TUNE & 0xfc) | 0x01 : R8_XT32K_TUNE; - R8_XT32M_TUNE = (R8_XT32M_TUNE & 0xfc) | 0x03; - ); -#endif - - NVIC->SCTLR |= (1 << 2); //deep sleep - SYS_SAFE_ACCESS - ( - R8_SLP_POWER_CTRL |= RB_RAM_RET_LV; - R16_POWER_PLAN = RB_PWR_PLAN_EN | RB_PWR_CORE | power_plan; - R8_PLL_CONFIG |= (1 << 5); - ); - - NVIC->SCTLR &= ~(1 << 3); // wfi - asm volatile ("wfi\nnop\nnop" ); - -#ifdef CH570_CH572 -#if ( CLK_SOURCE_CH5XX == CLK_SOURCE_PLL_75MHz ) || ( CLK_SOURCE_CH5XX == CLK_SOURCE_PLL_100MHz ) - //machine delay for a while. - uint16_t i = 400; - do { - asm volatile("nop"); - } while(i--); - - //get system clock back to normal - SYS_SAFE_ACCESS - ( - R8_CLK_SYS_CFG = CLK_SOURCE_CH5XX; - ); -#endif -#else - SYS_SAFE_ACCESS - ( - R16_POWER_PLAN &= ~RB_XT_PRE_EN; - R8_PLL_CONFIG &= ~(1 << 5); - R8_XT32M_TUNE = (R8_XT32M_TUNE & 0xfc) | 0x01; - ); -#endif -} - -RV_STATIC_INLINE void LowPower(uint32_t time, uint16_t power_plan) -{ - if( time > 500){ - LowPowerSleep( time, power_plan ); - } else { - LowPowerIdle( time ); - } - -} - RV_STATIC_INLINE void jump_isprom() { memcpy((void*)ISPROM_IN_RAM_ADDRESS, (void*)(ISPROM_ADDRESS + ISPROM_START_OFFSET), ISPROM_SIZE); // copy bootloader to ram @@ -2627,7 +2746,8 @@ RV_STATIC_INLINE void jump_isprom() "mret\n"); #elif defined(CH582_CH583) asm( "la gp, " ISPROM_GLOBALPOINTER "\n" - "j " ISPROM_ENTRYPOINT "\n"); + "la t0, " ISPROM_ENTRYPOINT "\n" + "jr t0\n"); #endif } diff --git a/inc/ch641hw.h b/inc/ch641hw.h index add26db..ee391a1 100644 --- a/inc/ch641hw.h +++ b/inc/ch641hw.h @@ -105,6 +105,7 @@ typedef struct uint32_t RESERVED1; } SysTick_Type; +#define funSysTick32() (SysTick->CNT) #endif /* __ASSEMBLER__*/ diff --git a/inc/funconfig.h b/inc/funconfig.h index ccc1558..f83a7b7 100644 --- a/inc/funconfig.h +++ b/inc/funconfig.h @@ -17,9 +17,11 @@ extern "C" #endif #define CH32V003 1 +//#define CH32V203 1 #define FUNCONF_USE_DEBUGPRINTF 0 #define FUNCONF_USE_UARTPRINTF 1 #define FUNCONF_UART_PRINTF_BAUD 115200 +//#define FUNCONF_UART_PRINTF_BAUD 9600 #ifdef __cplusplus diff --git a/inc/misc/attic/iSLER_preMarch2026.h b/inc/misc/attic/iSLER_preMarch2026.h new file mode 100644 index 0000000..10662e4 --- /dev/null +++ b/inc/misc/attic/iSLER_preMarch2026.h @@ -0,0 +1,946 @@ +/* + iSLER header for the CH570, 571, 572, 573, 582, 583, 584, 585, 591, 592 + + For basic RF functionality on supported WCH chips. + + #define ACCESS_ADDRESS 0x8E89BED6 // the "BED6" address for BLE advertisements + + // Initialize the iSLER engine, with the TX power. + iSLERInit(LL_TX_POWER_0_DBM); + + // TX packets + iSLERTX(ACCESS_ADDRESS, adv, sizeof(adv), adv_channels[c], PHY_1M); + + To receive packets, you can either: + + #define ISLER_CALLBACK iSLERRXCallback + + void iSLERRXCallback() + { + if( !iSLERCRCOK() ) return; + + uint8_t *frame = (uint8_t*)LLE_BUF; + int rssi = iSLERRSSI(); + + // Do stuff + } + + Or, just poll on rx_ready, whenever it's set you can read the packet. + + iSLERRX(ACCESS_ADDRESS, 37, PHY_1M); + while(!rx_ready); + // Receive packet code. + +*/ + +// 2025-12-25 function rename. +#define RFCoreInit iSLERInit +#define Frame_TX iSLERTX +#define Frame_RX iSLERRX +#define ReadRSSI iSLERRSSI + +#include +#include +#include +#include + +// define the linker section where the "highcode" functions live +// on ch5xx this is a section of RAM for quicker execution, +// but for example in funcongif.h +// #define FUNCONF_ISLER_SECTION __attribute__( ( section( ".manual_ram" ) ) ) +// you can put it where you want +#if defined(FUNCONF_ISLER_SECTION) +#ifdef __HIGH_CODE +#undef __HIGH_CODE +#endif +#define __HIGH_CODE FUNCONF_ISLER_SECTION +#elif !defined(__HIGH_CODE) +#define __HIGH_CODE +#endif + +// common fields +#define CTRL_CFG BB0 +#define CRCINIT1 BB1 +#define STATUS LL2 +#define INT_EN LL3 +#define CTRL_MOD LL20 +#define TXTUNE_CTRL RF14 +#define TXCTUNE_CO_CTRL RF36 +#define TXCTUNE_GA_CTRL RF37 +#define RXTUNE RF39 +#define TXCTUNE_CO RF40 +#define TXCTUNE_GA RF50 + +// chip specific fields +#ifdef CH570_CH572 +#define CRCPOLY1 BB2 +#define ACCESSADDRESS1 BB3 +#define CTRL_TX BB13 +#define CRCINIT2 BB22 +#define CRCPOLY2 BB23 +#define ACCESSADDRESS2 BB24 +#define TMR LL25 +#define TXBUF LL30 +#define RXBUF LL31 +#define CTRL_MOD_RFSTOP 0xfffff8ff +#define DEVSETMODE_ON ((BB->CTRL_CFG & 0xfffcffff) | 0x20000) +#define DEVSETMODE_OFF ((BB->CTRL_CFG & 0xfffcffff) | 0x10000) +#define DEVSETMODE_TUNE 0x0558 +#define DEVSETMODE_TX 0x0258 +#define DEVSETMODE_RX 0x0158 +#define CTRL_CFG_PHY_1M ((BB->CTRL_CFG & 0xfffffcff) | 0x100) +#define CTRL_CFG_PHY_2M (BB->CTRL_CFG & 0xfffffcff) +#define LL_STATUS_TX 0x20000 +#define CTRL_CFG_START_TX 0x1000000 +#elif defined(CH571_CH573) +#define TXBUF DMA4 +#define ACCESSADDRESS1 BB2 +#define CTRL_TX BB11 +#define RSSI BB12 // ? couldn't find it, not sure +#define TMR LL24 +#define TXBUF LL28 +#define RXBUF LL29 +#define RFEND_TXCTUNE_INIT 0x180000 +#define CTRL_MOD_RFSTOP 0xfffffff8 +#define DEVSETMODE_TUNE 0x5d +#define DEVSETMODE_TX 0x5a +#define DEVSETMODE_RX 0x59 +#define CTRL_CFG_PHY_1M (BB->CTRL_CFG | 0x10000000) +#define LL_STATUS_TX 0x20000 +#define CTRL_CFG_START_TX (BB->CTRL_CFG & 0xefffffff) +#elif defined(CH582_CH583) +#define ACCESSADDRESS1 BB2 +#define CTRL_TX BB11 +#define RSSI BB12 +#define TMR LL25 +#define TXBUF LL28 +#define RXBUF LL29 +#define RFEND_TXCTUNE_INIT 0x880000 +#define CTRL_TX_TXPOWER 0x80010e78 +#define CTRL_MOD_RFSTOP 0xfffffff8 +#define DEVSETMODE_ON ((BB->CTRL_CFG & 0xfffffe7f) | 0x100) +#define DEVSETMODE_OFF ((BB->CTRL_CFG & 0xfffffe7f) | 0x80) +#define DEVSETMODE_TUNE 0x00dd +#define DEVSETMODE_TX 0x00da +#define DEVSETMODE_RX 0x00d9 +#define CTRL_CFG_PHY_1M ((BB->CTRL_CFG & 0xffff0fff) | 0x1000) +#define CTRL_CFG_PHY_2M (BB->CTRL_CFG & 0xffff0fff) +#define CTRL_CFG_PHY_CODED ((BB->CTRL_CFG & 0xffff0fff) | 0x2000) +#define LL_STATUS_TX 0x2000 +#define CTRL_CFG_START_TX 0x800000 +#elif (defined(CH584_CH585) || defined(CH591_CH592)) +#define ACCESSADDRESS1 BB2 +#define CTRL_TX BB11 +#define RSSI BB12 +#define TMR LL25 +#define TXBUF LL30 +#define RXBUF LL31 +#define CTRL_MOD_RFSTOP 0xfffff8ff +#define DEVSETMODE_ON ((BB->CTRL_CFG & 0xfffffcff) | 0x280) +#define DEVSETMODE_OFF ((BB->CTRL_CFG & 0xfffffcff) | 0x100) +#define DEVSETMODE_TUNE 0x0558 +#define DEVSETMODE_TX 0x0258 +#define DEVSETMODE_RX 0x0158 +#define CTRL_CFG_PHY_1M (BB->CTRL_CFG & 0xffffff7f) +#define CTRL_CFG_PHY_2M (BB->CTRL_CFG | 0x80) +#define LL_STATUS_TX 0x20000 +#define CTRL_CFG_START_TX 0x800000 +#elif defined(CH32V20x) +#define CH32V208 +#define ACCESSADDRESS1 BB2 +#define CTRL_TX BB11 +#define RSSI BB12 +#define TMR LL25 +#define TXBUF LL28 +#define RXBUF LL29 +#define RFEND_TXCTUNE_INIT 0x100000 +#define CTRL_TX_TXPOWER 0x80010ec8 +#define CTRL_MOD_RFSTOP 0xfffffff8 +#define DEVSETMODE_ON ((BB->CTRL_CFG & 0xfffffe7f) | 0x100) +#define DEVSETMODE_OFF ((BB->CTRL_CFG & 0xfffffe7f) | 0x80) +#define DEVSETMODE_TUNE 0x5d +#define DEVSETMODE_TX 0x5a +#define DEVSETMODE_RX 0x59 +#define CTRL_CFG_PHY_1M ((BB->CTRL_CFG & 0xffff0fff) | 0x1000) +#define CTRL_CFG_PHY_2M (BB->CTRL_CFG & 0xffff0fff) +#define CTRL_CFG_PHY_CODED ((BB->CTRL_CFG & 0xffff0fff) | 0x2000) +#define LL_STATUS_TX 0x2000 +#define CTRL_CFG_START_TX 0x800000 +#else +#error "MCU_TARGET selected in Makefile is not supported" +#endif + +#ifdef CH32V208 +#define BB_BASE (0x40024100) // Baseband, digital part of the PHY +#define LL_BASE (0x40024200) // Link Layer, MAC +#define RF_BASE (0x40025000) // Radio frontend, analog part of the PHY +#else +#define DMA_BASE (0x4000c000) +#define BB_BASE (0x4000c100) +#define LL_BASE (0x4000c200) +#define RF_BASE (0x4000d000) +#endif + +#define DMA ((DMA_Type *) DMA_BASE) +#define BB ((BB_Type *) BB_BASE) +#define LL ((LL_Type *) LL_BASE) +#define RF ((RF_Type *) RF_BASE) + +#ifdef CH571_CH573 +typedef struct { + volatile uint32_t DMA0; + volatile uint32_t DMA1; + volatile uint32_t DMA2; + volatile uint32_t DMA3; + volatile uint32_t DMA4; + volatile uint32_t DMA5; + volatile uint32_t DMA6; + volatile uint32_t DMA7; +} DMA_Type; +#endif + +typedef struct { + // bits 0..5 = Channel + // bit 6 = disable whitening. + // bit 8 = 1 during normal TX/operation, but clearing does not affect TX. Note: 0 at reset, set in software. + // bit 9 = settable, but unknown effect. + // bit 10 = 1 during normal TX/operation, but clearing does not affect TX. Note: 1 at reset, not touched in software. + // bit 16 = cleared by firmware upon TX, but does not seem to have an effect on the TX. + // bit 17 = settable, but unknown effect + // bit 20 = settable, but unknown effect. + // bit 24 = set at end of tx routine + // bit 29-31 = settable, but unknown effect. + volatile uint32_t BB0; // CTRL_CFG + volatile uint32_t BB1; // CRCINIT1 + volatile uint32_t BB2; // ch570/2: CRCPOLY1, [ch582/3 ch591/2]: ACCESSADDRESS1 + volatile uint32_t BB3; // ch570/2 ACCESSADDRESS1 + volatile uint32_t BB4; + volatile uint32_t BB5; + volatile uint32_t BB6; + volatile uint32_t BB7; + volatile uint32_t BB8; + volatile uint32_t BB9; + volatile uint32_t BB10; + volatile uint32_t BB11; // ch582/3, ch584/5, ch591/2: CTRL_TX + volatile uint32_t BB12; + + // default, pre TX is a4000009 + // bit 0: Set normally, but cleared in software when TXing (maybe a ready bit?) + // bit 1: Unset normally, but cleared anyway by software when TXing (maybe a fault bit?) + // bit 2: Disables TX. + // bit 4: Normally 0, but, if set to 1, seems to increase preamble length. + // bit 8: Normally 0, but, if set, no clear effect. + // bit 9: Normally 0, but, if set, no clear effect. + // bits 24-30: TX Power. Normally 0xA4 + // Oddly, bit 31 seems to maybe be always set. + volatile uint32_t BB13; // ch570/2: CTRL_TX + volatile uint32_t BB14; + volatile uint32_t BB15; + volatile uint32_t BB16; + volatile uint32_t BB17; + volatile uint32_t BB18; + volatile uint32_t BB19; + volatile uint32_t BB20; + volatile uint32_t BB21; + volatile uint32_t BB22; // ch570/2: CRCINIT2 + volatile uint32_t BB23; // ch570/2: CRCPOLY2 + volatile uint32_t BB24; // ch570/2: ACCESSADDRESS2 +} BB_Type; + +typedef struct { + volatile uint32_t LL0; + volatile uint32_t LL1; + volatile uint32_t LL2; // STATUS + volatile uint32_t LL3; // INT_EN + volatile uint32_t LL4; + volatile uint32_t LL5; + volatile uint32_t LL6; + volatile uint32_t LL7; + volatile uint32_t LL8; + volatile uint32_t LL9; + volatile uint32_t LL10; + volatile uint32_t LL11; + volatile uint32_t LL12; + volatile uint32_t LL13; + volatile uint32_t LL14; + volatile uint32_t LL15; + volatile uint32_t LL16; + volatile uint32_t LL17; + volatile uint32_t LL18; + volatile uint32_t LL19; + + // Controls a lot of higher-level functions. + // For Tuning: 0x30558 + // For Idle: 0x30000 + // For Sending:0x30258 + // Bit 3: Somehow, enables BB + // Bit 4: Normally 1, controls length/send times of BB, if unset, BB will double-send part of signals. + // Bit 6: Normally 1, Unknown effect. + // Bit 9: If 0, no output. + // Bit 10: Somehow required for TX? + // Bit 16-17: Normally 1, unknown effect. Seems to suppress odd carrier burst after message. + volatile uint32_t LL20; // CTRL_MOD + volatile uint32_t LL21; + volatile uint32_t LL22; + volatile uint32_t LL23; + volatile uint32_t LL24; // ch571/3: TMR + volatile uint32_t LL25; // ch570/2, ch582/3, ch591/2: TMR + volatile uint32_t LL26; + volatile uint32_t LL27; + volatile uint32_t LL28; // ch582/3: TXBUF + volatile uint32_t LL29; // ch582/3: RXBUF + volatile uint32_t LL30; // ch570/2, ch591/2: TXBUF + volatile uint32_t LL31; // ch570/2, ch591/2: RXBUF +} LL_Type; + +typedef struct { + volatile uint32_t RF0; + volatile uint32_t RF1; + volatile uint32_t RF2; + volatile uint32_t RF3; + volatile uint32_t RF4; + volatile uint32_t RF5; + volatile uint32_t RF6; + volatile uint32_t RF7; + volatile uint32_t RF8; + volatile uint32_t RF9; + volatile uint32_t RF10; + volatile uint32_t RF11; + volatile uint32_t RF12; + volatile uint32_t RF13; + volatile uint32_t RF14; // TXTUNE_CTRL + volatile uint32_t RF15; + volatile uint32_t RF16; + volatile uint32_t RF17; + volatile uint32_t RF18; + volatile uint32_t RF19; + volatile uint32_t RF20; + volatile uint32_t RF21; + volatile uint32_t RF22; + volatile uint32_t RF23; + volatile uint32_t RF24; + volatile uint32_t RF25; + volatile uint32_t RF26; + volatile uint32_t RF27; + volatile uint32_t RF28; + volatile uint32_t RF29; + volatile uint32_t RF30; + volatile uint32_t RF31; + volatile uint32_t RF32; + volatile uint32_t RF33; + volatile uint32_t RF34; + volatile uint32_t RF35; + volatile uint32_t RF36; // TXCTUNE_CO_CTRL + volatile uint32_t RF37; // TXCTUNE_GA_CTRL + volatile uint32_t RF38; + volatile uint32_t RF39; // RXTUNE + volatile uint32_t RF40[10]; // TXCTUNE_CO[10] + volatile uint32_t RF50[3]; // TXCTUNE_GA[3] +} RF_Type; + +uint8_t channel_map[] = {1,2,3,4,5,6,7,8,9,10,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,0,11,39}; +#define CO_MID (uint8_t)(RF->TXTUNE_CTRL & ~0xffffffc0) +#define GA_MID (uint8_t)((RF->TXTUNE_CTRL & ~0x80ffffff) >> 24) + +#define PHY_1M 1 +#define PHY_2M 2 +#define PHY_S2 4 +#define PHY_S8 8 + +void DevSetMode(uint16_t mode); +__attribute__((aligned(4))) uint32_t LLE_BUF[0x110]; +#ifdef CH571_CH573 +__attribute__((aligned(4))) uint32_t LLE_BUF2[0x110]; +#endif +volatile uint32_t tuneFilter; +volatile uint32_t tuneFilter2M; +#ifndef ISLER_CALLBACK +volatile uint32_t rx_ready; +#endif + + +#ifdef CH571_CH573 +__attribute__((interrupt)) +void BB_IRQHandler() { + // printf("BB\n"); + if(BB->BB14 & (1<<6)) { + BB->BB14 &= 0xffffff9f; + } + if(BB->BB14 & (1<<1)) { + BB->BB14 = 0xfffffffd; + BB->BB20 = 0x45; + } + if(BB->BB14 & (1<<4)) { + BB->BB14 = 0xffffffef; + BB->BB20 = 0; + } +} +#endif + +__attribute__((interrupt)) +void LLE_IRQHandler() { + int rx_flag = 0; +#ifdef CH571_CH573 + if(LL->STATUS & (1<<9)) { + LL->TMR = 400; + BB->CTRL_TX = (BB->CTRL_TX & 0xfffffffc) | 2; + BB->CTRL_CFG |= 0x10000000; + rx_flag = 1; // XXX TODO: Figure out which bit is the RX bit. + } + LL->STATUS = 0; +#elif defined(CH582_CH583) + if((LL->STATUS & (1<<14)) && (LL->INT_EN & (1<<14))) { + LL->LL26 = 0xffffffff; + LL->STATUS = 0x4000; + rx_flag = 1; // XXX TODO: Figure out which bit is the RX bit. + } + else +#endif + { + rx_flag = LL->STATUS & 1; + LL->STATUS &= LL->INT_EN; + BB->CTRL_TX = (BB->CTRL_TX & 0xfffffffc) | 1; + } + DevSetMode(0); + LL->CTRL_MOD &= CTRL_MOD_RFSTOP; + LL->LL0 |= 0x08; + + if( rx_flag ) + { +#ifdef ISLER_CALLBACK + ISLER_CALLBACK(); +#else + rx_ready = 1; +#endif + } +} + +void RFEND_Reset() { +#ifdef CH571_CH573 + RF->RF3 |= 0x1000; + ADD_N_NOPS(20); + RF->RF3 &= 0xffffefff; + ADD_N_NOPS(20); + RF->RF3 |= 0x1000; + ADD_N_NOPS(20); + RF->RF3 |= 1; + ADD_N_NOPS(20); + RF->RF3 &= 0xfffffffe; + ADD_N_NOPS(20); + RF->RF3 |= 1; + ADD_N_NOPS(20); + RF->RF3 |= 0x100; + ADD_N_NOPS(20); + RF->RF3 &= 0xfffffeff; + ADD_N_NOPS(20); + RF->RF3 |= 0x100; + ADD_N_NOPS(20); +#elif defined(CH32V208) + RF->RF3 = 0x1101; + ADD_N_NOPS(20); + RF->RF3 = 0; + ADD_N_NOPS(20); + RF->RF3 = 0x1101; +#endif +} + +void DevInit(uint8_t TxPower) { +#ifdef CH571_CH573 + DMA->DMA4 = (uint32_t)LLE_BUF; + DMA->DMA5 = (uint32_t)LLE_BUF; + DMA->DMA6 = (uint32_t)LLE_BUF2; + DMA->DMA7 = (uint32_t)LLE_BUF2; + DMA->DMA2 |= 0x2000; + DMA->DMA3 |= 0x2000; + DMA->DMA2 |= 0x1000; + DMA->DMA3 |= 0x1000; + DMA->DMA0 |= 2; + DMA->DMA0 |= 0x20; + + LL->LL5 = 0x50; + LL->LL7 = 10; + LL->LL9 = 0x8c; + LL->LL13 = 0x8c; + LL->LL17 = 0x50; + LL->LL19 = 10; +#elif defined(CH570_CH572) || defined(CH582_CH583) || defined(CH584_CH585) || defined(CH591_CH592) + LL->LL5 = 0x8c; + LL->LL7 = 0x76; + LL->LL9 = 0x8c; + LL->LL13 = 0x8c; + LL->LL17 = 0x8c; + LL->LL19 = 0x76; +#elif defined(CH32V208) + LL->LL5 = 0x8c; + LL->LL7 = 0x6c; + LL->LL9 = 0x8c; + LL->LL13 = 0x8c; + LL->LL17 = 0x8c; + LL->LL19 = 0x6c; +#endif + +#ifdef CH570_CH572 + LL->LL11 = 0x6c; + LL->LL15 = 0x6c; + LL->LL1 = 0x78; + LL->LL21 = 0; + LL->INT_EN = 0x16000f; +#elif defined(CH571_CH573) + LL->LL11 = 0x3c; + LL->LL15 = 0x3c; + LL->LL22 = 0xf6; + LL->INT_EN = 0xc303; + NVIC->FIBADDRR = 0x20000000; + NVIC->VTFADDR[2] = (uint32_t)LLE_IRQHandler -NVIC->FIBADDRR; +#elif defined(CH582_CH583) || defined(CH32V208) + LL->LL11 = 0x3c; + LL->LL15 = 0x3c; + LL->INT_EN = 0xf00f; +#elif defined(CH584_CH585) + LL->LL11 = 0x6e; + LL->LL15 = 0x6e; + LL->LL1 &= 0xffffffe1; + LL->LL21 = 0; + LL->INT_EN = 0x1f000f; +#elif defined(CH591_CH592) + LL->LL6 = 0x78; + LL->LL8 = 0xffffffff; + LL->LL11 = 0x6e; + LL->LL21 = 0x14; + LL->INT_EN = 0x1f000f; +#endif + + LL->RXBUF = (uint32_t)LLE_BUF; + LL->STATUS = 0xffffffff; + RF->RF10 = 0x480; + +#ifdef CH570_CH572 + RF->RF12 &= 0xfff9ffff; + RF->RF12 |= 0x70000000; + RF->RF15 = (RF->RF15 & 0xf8ffffff) | 0x2000000; + RF->RF15 = (RF->RF15 & 0x1fffffff) | 0x40000000; + RF->RF18 &= 0xfff8ffff; + RF->RF20 = (RF->RF20 & 0xfffff8ff) | 0x300; + RF->RF23 |= 0x70000; + RF->RF23 |= 0x700000; + + BB->BB14 = 0x2020c; + BB->BB15 = 0x50; + BB->CTRL_TX = (BB->CTRL_TX & 0x1ffffff) | (TxPower | 0x40) << 0x19; + BB->CTRL_CFG &= 0xfffffcff; +#elif defined(CH571_CH573) || defined(CH582_CH583) || defined(CH32V208) + RFEND_Reset(); + RF->RF18 = (RF->RF18 & 0x8fffffff) | 0x20000000; + RF->RF18 = (RF->RF18 & 0xf8ffffff) | 0x4000000; + RF->RF18 = (RF->RF18 & 0xfffffff0) | 9; + RF->RF18 &= 0xfff8ffff; + RF->RF18 |= 0x80000000; + RF->RF19 = (RF->RF19 & 0xfffffff8) | 3; + RF->RF19 = (RF->RF19 & 0xffffff8f) | 0x30; + RF->RF19 = (RF->RF19 & 0xfffff8ff) | 0x300; + RF->RF19 &= 0xfeffffff; + RF->RF19 |= 0x2000000; + RF->RF20 = (RF->RF20 & 0xffff0fff) | 0x4000; + RF->RF21 = (RF->RF21 & 0xfffffff0) | 0xc; + RF->RF21 |= 0x80; + RF->RF21 &= 0xffffefff; + RF->RF15 = (RF->RF15 & 0xffff0fff) | 0x8000; + RF->RF15 = (RF->RF15 & 0xf8ffffff) | 0x2000000; + RF->RF15 = (RF->RF15 & 0x1fffffff) | 0x40000000; + RF->RF11 |= 0x700000; + RF->RF11 &= 0xf8ffffff; + RF->RF11 = (RF->RF11 & 0xffffcfff) | 0x2000; + RF->RF11 = (RF->RF11 & 0xfffcffff) | 0x20000; + RF->RF12 &= 0xfffffff0; + RF->RF12 &= 0xffffff0f; + RF->RF12 &= 0xfffff8ff; + RF->RF12 |= 0x700000; + RF->RF12 = (RF->RF12 & 0x8fffffff) | 0x50000000; + RF->TXTUNE_CTRL = (RF->TXTUNE_CTRL & 0xff07ffff) | RFEND_TXCTUNE_INIT; + RF->TXTUNE_CTRL |= 0x80000000; + +#ifdef CH571_CH573 + BB->CTRL_CFG = (TxPower << 8) | BB->CTRL_CFG | 0x1008000; + BB->CTRL_CFG = (BB->CTRL_CFG & 0xffffc0ff) | (TxPower & 0x3f) << 8; + SYS_SAFE_ACCESS( + R16_AUX_POWER_ADJ = (TxPower < 0x15) ? (R16_AUX_POWER_ADJ & 0xffef): + (R16_AUX_POWER_ADJ | 0x10); + ); + BB->CTRL_TX = 0x10e78; + BB->BB6 |= 0x8000; + BB->BB6 = (BB->BB6 & 0xffff807f) | 0x3500; + BB->BB13 = 0x152; + + // NVIC->VTFADDR[3] = (uint32_t)BB_IRQHandler +0x14000000; // why 14000000? +#elif defined(CH582_CH583) || defined(CH32V208) + BB->CTRL_CFG |= 0x800000; + BB->CTRL_CFG |= 0x10000000; + BB->BB13 = 0x1d0; + BB->CTRL_TX = TxPower << 0x19 | CTRL_TX_TXPOWER; + BB->CTRL_TX = (BB->CTRL_TX & 0x81ffffff) | (TxPower & 0x3f) << 0x19; + BB->BB8 = 0x90083; + + // NVIC->VTFADDR[3] = (uint32_t)BB_IRQHandler +0x20000000; // why 20000000? +#endif +#elif defined(CH584_CH585) || defined(CH591_CH592) + RF->RF12 = (RF->RF12 & 0x8fffffff) | 0x10077700; + RF->RF15 = (RF->RF15 & 0x18ff0fff) | 0x42005000; + RF->RF19 &= 0xfffcff88; + RF->RF21 = (RF->RF21 & 0xfffffff0) | 9; + RF->RF23 &= 0xff88ffff; + + BB->CTRL_CFG |= 0x800000; + BB->BB14 = 0x3ff; // ch584/5 + BB->BB13 = 0x50; + BB->CTRL_TX = (BB->CTRL_TX & 0x81ffffff) | (TxPower & 0x3f) << 0x19; + uint32_t uVar3 = 0x1000000; + uint32_t uVar4 = RF->RF23 & 0xf8ffffff; + if(TxPower < 29) { // ch585: 27 + /* uVar3 and uVar4 are initialized properly already */ + } + else if(TxPower < 35) { + uVar3 = 0x3000000; + } + else if(TxPower < 59) { + uVar3 = 0x5000000; + } + else { + uVar4 = RF->RF23; + uVar3 = 0x7000000; + } + RF->RF23 = uVar4 | uVar3; + BB->BB15 = 0x2020c; // ch584/5 + BB->BB4 = (BB->BB4 & 0xffffffc0) | 0xe; +#endif + + NVIC->VTFIDR[3] = 0x14; +} + +void DevSetMode(uint16_t mode) { +#if !defined(CH571_CH573) + if(mode) { + BB->CTRL_CFG = DEVSETMODE_ON; + RF->RF2 |= 0x330000; + } + else { + BB->CTRL_CFG = DEVSETMODE_OFF; + RF->RF2 &= 0xffcdffff; + } +#ifdef CH582_CH583 + mode = (mode == 0) ? 0x80 : mode; +#elif !defined(CH32V208) + mode |= 0x30000; +#endif +#endif // ! CH571_CH573 + LL->CTRL_MOD = mode; +} + +uint32_t RFEND_TXCTune(uint8_t channel) { + // 0xbf = 2401 MHz + RF->RF1 &= 0xfffffffe; + RF->TXTUNE_CTRL = (RF->TXTUNE_CTRL & 0xfffe00ff) | (0xbf00 + (channel_map[channel] << 8)); + RF->RF1 |= 1; + + LL->TMR = 8000; + while(!(RF->TXCTUNE_CO_CTRL & (1 << 25)) || !(RF->TXCTUNE_CO_CTRL & (1 << 26))) { + if(LL->TMR == 0) { + break; + } + } + + uint8_t nCO = (uint8_t)RF->TXCTUNE_CO_CTRL & 0x3f; + uint8_t nGA = (uint8_t)(RF->TXCTUNE_GA_CTRL >> 10) & 0x7f; + + // printf("nCO,nGA ch:%u idx:%u %u,%u\n", channel, channel_map[channel], nCO,nGA); + + return (nGA << 24) | nCO; +} + +void RFEND_TXTune() { + RF->RF1 &= 0xfffffeff; + RF->RF10 &= 0xffffefff; + RF->RF11 &= 0xffffffef; + RF->RF2 |= 0x20000; + RF->RF1 |= 0x10; + + // 2401 MHz + uint32_t tune2401 = RFEND_TXCTune(37); + uint8_t nCO2401 = (uint8_t)(tune2401 & 0x3f); + uint8_t nGA2401 = (uint8_t)(tune2401 >> 24) & 0x7f; + + // 2480 MHz + uint32_t tune2480 = RFEND_TXCTune(39); + uint8_t nCO2480 = (uint8_t)(tune2480 & 0x3f); + uint8_t nGA2480 = (uint8_t)(tune2480 >> 24) & 0x7f; + + // 2440 MHz + uint32_t tune2440 = RFEND_TXCTune(18); + uint8_t nCO2440 = (uint8_t)(tune2440 & 0x3f); + uint8_t nGA2440 = (uint8_t)(tune2440 >> 24) & 0x7f; + + uint32_t dCO0140 = nCO2401 - nCO2440; + uint32_t dCO4080 = nCO2440 - nCO2480; + uint8_t tune = 0; + uint8_t int_points = sizeof(RF->TXCTUNE_CO) /2; + uint8_t txctune_co[sizeof(RF->TXCTUNE_CO)] = {0}; + for(int f = 0; f < int_points; f++) { + tune = (dCO0140 * (int_points -f)) / int_points; + txctune_co[f] = tune | (tune << 4); + } + for(int f = int_points; f < sizeof(RF->TXCTUNE_CO); f++) { + tune = (dCO4080 * (f -int_points)) / int_points; + txctune_co[f] = tune | (tune << 4); + } + for(int i = 0; i < sizeof(txctune_co) /4; i++) { + RF->TXCTUNE_CO[i] = ((uint32_t*)txctune_co)[i]; + } + + // This GA interpolating is not exactly what is done in EVT + // Actually the reception on a BLE monitor is better when this is left out completely + // This will need some proper experimentation by people with 2.4GHz SDRs + uint32_t dGA0140 = nGA2401 - nGA2440; + uint32_t dGA4080 = nGA2440 - nGA2480; + int_points = sizeof(RF->TXCTUNE_GA) /2; + uint8_t txctune_ga[sizeof(RF->TXCTUNE_GA)] = {0}; + for(int f = 1; f < int_points; f++) { + tune = (dGA0140 * (int_points -f)) / int_points; + txctune_ga[f] = tune | (tune << 4); + } + for(int f = int_points; f < sizeof(RF->TXCTUNE_GA) -1; f++) { + tune = (dGA4080 * (f -int_points)) / int_points; + txctune_ga[f] = tune | (tune << 4); + } + for(int i = 0; i < (sizeof(txctune_ga) /4); i++) { + RF->TXCTUNE_GA[i] = ((uint32_t*)txctune_ga)[i]; + } + + +#if 0 + printf("2401 2440 2480 CO: %u %u %u, GA: %u %u %u\n", nCO2401, nCO2440, nCO2480, nGA2401, nGA2440, nGA2480); + for(int i = 0; i < 10; i++ ) { + printf( "%d: %08lx\n", i, RF->TXCTUNE_CO[i] ); + } + for(int i = 0; i < 3; i++ ) { + printf( "%d: %08lx\n", i, RF->TXCTUNE_GA[i] ); + } +#endif + + RF->RF1 &= 0xffffffef; + RF->RF1 &= 0xfffffffe; + RF->RF10 |= 0x1000; + RF->RF11 |= 0x10; + RF->TXTUNE_CTRL = (RF->TXTUNE_CTRL & 0xffffffc0) | (tune2440 & 0x3f); + RF->TXTUNE_CTRL = (RF->TXTUNE_CTRL & 0x80ffffff) | (tune2440 & 0x7f000000); + + // FTune + RF->RF1 |= 0x100; +} + +void RFEND_RXTune() { + RF->RF20 &= 0xfffeffff; + RF->RF2 |= 0x200000; + RF->RF3 = (RF->RF3 & 0xffffffef) | 0x10; + RF->RF1 |= 0x1000; + + LL->TMR = 100; + while(LL->TMR && ((RF->RXTUNE >> 8) & 1)); + + tuneFilter = RF->RXTUNE & 0x1f; + RF->RF20 |= 0x10000; + RF->RF20 = (RF->RF20 & 0xffffffe0) | tuneFilter; + RF->RF2 &= 0xffdfffff; + tuneFilter2M = (tuneFilter +2 < 0x1f) ? (tuneFilter +2) : 0x1f; + + // RXADC + RF->RF22 &= 0xfffeffff; + RF->RF2 |= 0x10000; + RF->RF3 = (RF->RF3 & 0xfffffeff) | 0x100; + RF->RF1 = (RF->RF1 & 0xfffeffff) | 0x100000; +} + +void RegInit() { + DevSetMode(DEVSETMODE_TUNE); + RFEND_TXTune(); + RFEND_RXTune(); + DevSetMode(0); +} + +void iSLERInit(uint8_t TxPower) { +#if defined(CH571_CH573) || defined(CH584_CH585) // maybe all? + NVIC->IENR[0] = 0x1000; + NVIC->IRER[0] = 0x1000; +#endif + DevInit(TxPower); + RegInit(); + NVIC->IPRIOR[0x15] |= 0x80; + NVIC_EnableIRQ(LLE_IRQn); +} + +void DevSetChannel(uint8_t channel) { +#ifdef CH571_CH573 + BB->BB6 = (BB->BB6 & 0xf8ffffff) | 0x4000000; + BB->BB6 = (BB->BB6 & 0xffffff83) | 0x1c; +#endif + RF->RF11 &= 0xfffffffd; + BB->CTRL_CFG = (BB->CTRL_CFG & 0xffffff80) | (channel & 0x7f); +} + +__HIGH_CODE +int iSLERRSSI() { +#ifdef CH570_CH572 + uint8_t *tx_buf = (uint8_t*)LLE_BUF; + int len = tx_buf[1]; + return (int8_t)tx_buf[len +4]; +#else + return (int8_t)(BB->RSSI >> 0xf); +#endif +} + +__HIGH_CODE +int iSLERCRCOK() { +#ifdef CH570_CH572 + uint8_t *tx_buf = (uint8_t*)LLE_BUF; + int len = tx_buf[1]; + return (int8_t)!(tx_buf[len + 5] & 0x10); +#else + // Unimplemented! + return -1; +#endif +} + +__HIGH_CODE +void iSLERTX(uint32_t access_address, uint8_t adv[], size_t len, uint8_t channel, uint8_t phy_mode) { + BB->CTRL_TX = (BB->CTRL_TX & 0xfffffffc) | 1; + + DevSetChannel(channel); + + // Uncomment to disable whitening to debug RF. + //BB->CTRL_CFG |= (1<<6); + DevSetMode(DEVSETMODE_TX); + + BB->ACCESSADDRESS1 = access_address; // access address + BB->CRCINIT1 = 0x555555; // crc init +#ifdef CH570_CH572 + BB->ACCESSADDRESS2 = access_address; + BB->CRCINIT2 = 0x555555; + BB->CRCPOLY1 = (BB->CRCPOLY1 & 0xff000000) | 0x80032d; // crc poly + BB->CRCPOLY2 = (BB->CRCPOLY2 & 0xff000000) | 0x80032d; +#endif + +#if defined(CH571_CH573) + DMA->TXBUF = (uint32_t)adv; +#else + LL->TXBUF = (uint32_t)adv; +#endif + + // Wait for tuning bit to clear. + for( int timeout = 3000; !(RF->RF26 & 0x1000000) && timeout >= 0; timeout-- ); + +#if defined(CH582_CH583) || defined(CH32V208) + BB->CTRL_CFG = (phy_mode == PHY_2M) ? CTRL_CFG_PHY_2M: + (phy_mode == PHY_S2) ? CTRL_CFG_PHY_CODED: + (phy_mode == PHY_S8) ? CTRL_CFG_PHY_CODED: + CTRL_CFG_PHY_1M; // default 1M for now + if(phy_mode > PHY_2M) { // coded phy + BB->CTRL_CFG = (BB->CTRL_CFG & 0xffff3fff) | ((phy_mode == PHY_S2) ? 0x4000 : 0); + } +#elif defined(CH571_CH573) + BB->CTRL_CFG = CTRL_CFG_PHY_1M; // no 2M PHY on ch571/3 +#else + BB->CTRL_CFG = (phy_mode == PHY_2M) ? CTRL_CFG_PHY_2M: + CTRL_CFG_PHY_1M; // default 1M for now +#endif + +#if defined(CH570_CH572) + BB->BB9 = (BB->BB9 & 0xf9ffffff) | ((phy_mode == PHY_2M) ? 0 : 0x2000000); +#endif + +#if defined(CH571_CH573) + BB->BB11 = (BB->BB11 & 0xfffffffc); // |2 for RX +#endif + + // This clears bit 17 (If set, seems to have no impact.) + LL->LL4 &= 0xfffdffff; + +#if !defined(CH571_CH573) + LL->STATUS = LL_STATUS_TX; +#endif + LL->TMR = (uint32_t)(len *512); // needs optimisation, per phy mode + + BB->CTRL_CFG |= CTRL_CFG_START_TX; + BB->CTRL_TX &= 0xfffffffc; + + LL->LL0 = 2; // Not sure what this does, but on RX it's 1 + + while(LL->TMR); // wait for tx buffer to empty + DevSetMode(0); + if(LL->LL0 & 3) { + LL->CTRL_MOD &= CTRL_MOD_RFSTOP; + LL->LL0 |= 0x08; + } +} + +__HIGH_CODE +void iSLERRX(uint32_t access_address, uint8_t channel, uint8_t phy_mode) { + DevSetMode(0); + if(LL->LL0 & 3) { + LL->CTRL_MOD &= CTRL_MOD_RFSTOP; + LL->LL0 |= 0x08; + } + LL->TMR = 0; + + DevSetChannel(channel); + DevSetMode(DEVSETMODE_RX); + +#if defined(CH582_CH583) || defined(CH32V208) + BB->CTRL_CFG = (phy_mode == PHY_2M) ? CTRL_CFG_PHY_2M: + (phy_mode == PHY_S2) ? CTRL_CFG_PHY_CODED: + (phy_mode == PHY_S8) ? CTRL_CFG_PHY_CODED: + CTRL_CFG_PHY_1M; // default 1M for now + if(phy_mode > PHY_2M) { // coded phy + BB->CTRL_CFG = (BB->CTRL_CFG & 0xffff3fff) | ((phy_mode == PHY_S2) ? 0x4000 : 0); + } +#elif defined(CH571_CH573) + BB->CTRL_CFG = CTRL_CFG_PHY_1M; // no 2M PHY on ch571/3 +#else + BB->CTRL_CFG = (phy_mode == PHY_2M) ? CTRL_CFG_PHY_2M: + CTRL_CFG_PHY_1M; // default 1M for now +#endif + +#ifdef CH570_CH572 + BB->BB9 = (BB->BB9 & 0xf9ffffff) | ((phy_mode == PHY_2M) ? 0 : 0x2000000); + RF->RF20 = (RF->RF20 & 0xffffffe0) | ((phy_mode == PHY_2M) ? (tuneFilter2M & 0x1f) : (tuneFilter & 0x1f)); + BB->BB5 = (BB->BB5 & 0xffffffc0) | ((phy_mode == PHY_2M) ? 0xd : 0xb); + BB->BB7 = (BB->BB7 & 0xff00fc00) | ((phy_mode == PHY_2M) ? 0x7f00a0 : 0x79009c); +#elif defined(CH571_CH573) + BB->BB11 = (BB->BB11 & 0xfffffffc) | 2; // no |2 for TX +#elif defined(CH582_CH583) || defined(CH32V208) +#if defined(CH582_CH583) + BB->BB4 = (phy_mode < PHY_S2) ? 0x3722d0 : 0x3722df; +#elif defined(CH32V208) + BB->BB4 = (phy_mode < PHY_S2) ? 0x3222d0 : 0x34a4df; +#endif + BB->BB5 = (phy_mode < PHY_S2) ? 0x8101901 : 0x8301ff1; + BB->BB6 = (phy_mode < PHY_S2) ? 0x31624 : 0x31619; + BB->BB8 = (phy_mode < PHY_S2) ? 0x90083 : 0x90086; + BB->BB9 = 0x1006310; + BB->BB10 = (phy_mode < PHY_S2) ? 0x28be : 0x28de; +#elif defined(CH584_CH585) || defined(CH591_CH592) + BB->BB6 = (BB->BB6 & 0xfffffc00) | ((phy_mode == PHY_2M) ? 0x13a : 0x132); + BB->BB4 = (BB->BB4 & 0x00ffffff) | ((phy_mode == PHY_2M) ? 0x78000000 : 0x7f000000); +#endif + + BB->ACCESSADDRESS1 = access_address; // access address + BB->CRCINIT1 = 0x555555; // crc init +#ifdef CH570_CH572 + BB->ACCESSADDRESS2 = access_address; + BB->CRCINIT2 = 0x555555; + BB->CRCPOLY1 = (BB->CRCPOLY1 & 0xff000000) | 0x80032d; // crc poly + BB->CRCPOLY2 = (BB->CRCPOLY2 & 0xff000000) | 0x80032d; +#endif + + LL->LL0 = 1; // Not sure what this does, but on TX it's 2 +#ifndef ISLER_CALLBACK + rx_ready = 0; +#endif +} diff --git a/inc/misc/attic/rv003usb_bootloader_stubs_for_minichlink/erase_block.asm b/inc/misc/attic/rv003usb_bootloader_stubs_for_minichlink/erase_block.asm new file mode 100644 index 0000000..06ebe49 --- /dev/null +++ b/inc/misc/attic/rv003usb_bootloader_stubs_for_minichlink/erase_block.asm @@ -0,0 +1,34 @@ +# +# Erase a block of various length in flash. +# Based on original code from pgm-b003fun.c by cnlohr +# Copyright 2026 monte-monte +# + +addi a4, a0, 60; /* Start reading properties, starting from scratchpad + 52. */ +c.lw a1, 0(a4); /* a1 = Address to erase from. */ +c.lw a5, 4(a4); /* a5 = Get flash address (0x4002200C) */ +lh t0, 8(a4); /* t0 = page size (64 or 256) */ +lh a2, 10(a4); /* t1 = total amount of data to erase */ +add a2, a1, a2; /* t1 = end address of the section we are writing */ + +lui a3, %hi(0x00020000); +c.sw a3, 4(a5); /* FLASH->CTLR = CR_PAGE_ER */ +1: +c.sw a1, 8(a5); /* FLASH->ADDR = writing location. */ +lui a3, %hi(0x00020000); +addi a3, a3, 0x40; +c.sw a3, 4(a5); /* FLASH->CTRL = CR_PAGE_ER|CR_STRT_Set */ + +2: +c.lw a4, 0(a5); /* read FLASH->STATR */ +c.andi a4, 1; /* Mask off BUSY bit. */ +c.bnez a4, 2b; + +add a1, a1, t0; /* Advance the erase address */ + +blt a1, a2, 1b /* Loop untill the end of block. */ + +c.li a3, -1 +c.sw a3, 0(a0) /* Write -1 into 0x00 indicating all done. */ +c.nop +ret diff --git a/inc/misc/attic/rv003usb_bootloader_stubs_for_minichlink/erase_block.sh b/inc/misc/attic/rv003usb_bootloader_stubs_for_minichlink/erase_block.sh new file mode 100755 index 0000000..6043f86 --- /dev/null +++ b/inc/misc/attic/rv003usb_bootloader_stubs_for_minichlink/erase_block.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm -f erase_block.o erase_block.bin +riscv64-unknown-elf-as erase_block.asm -march=rv32imac_zicsr -o erase_block.o +riscv64-unknown-elf-objcopy -O binary erase_block.o erase_block.bin +xxd -i erase_block.bin > erase_block.h diff --git a/inc/misc/attic/rv003usb_bootloader_stubs_for_minichlink/write_block.asm b/inc/misc/attic/rv003usb_bootloader_stubs_for_minichlink/write_block.asm new file mode 100644 index 0000000..a1afa30 --- /dev/null +++ b/inc/misc/attic/rv003usb_bootloader_stubs_for_minichlink/write_block.asm @@ -0,0 +1,67 @@ +# +# Write a block of various length to flash. +# Iterating through a data bigger than one block. +# Based on original code from pgm-b003fun.c by cnlohr +# Copyright 2026 monte-monte +# + +csrr a5, mstatus; +andi a5, a5, -137; +csrw mstatus, a5; /* Disabling interrupts globally */ + +addi a4, a0,108; /* Start reading properties, starting from scratchpad + 88. */ +c.lw a1, 0(a4); /* a1 = Address to write to. */ +c.lw a5, 4(a4); /* a5 = Get flash address (0x4002200C) */ +lh t0, 8(a4); /* t0 = block size (64 or 256) */ +lh t1, 10(a4); /* t1 = total amount of data to write */ +add t1, a1, t1; /* t1 = end address of the section we are writing */ + +lui a3, %hi(0x00010000); +c.sw a3, 4(a5); /* FLASH->CTLR = CR_PAGE_PG */ +2: +add a2, a1, t0; /* a2 = end of block to write to */ +lui a3, %hi(0x00080000 | 0x00010000); +c.sw a3, 4(a5); /* FLASH->CTLR = CR_BUF_RST | CR_PAGE_PG */ + +# 4: /* Wait for flash loop */ +# c.lw a3, 0(a5) /* read FLASH->STATR */ +# c.andi a3, 1 /* Mask off BUSY bit. */ +# c.bnez a3, 4b +c.lw a3, 0(a1); /* Tricky: By reading from flash here, we force it to wait for completion. */ + +1: +c.lw a3, 12(a4); /* lw a3, 0(a1) // Read from RAM (Starting @64) */ +c.sw a3, 0(a1); /* sw a3, 0(a4) // Store into flash */ + +lui a3, %hi(0x00010000 | 0x00040000); /* CR_PAGE_PG | FLASH_CTLR_BUF_LOAD */ +c.sw a3, 4(a5); /* Load into flash write buffer. */ + +# 3: +# c.lw a3, 0(a5) /* read FLASH->STATR */ +# c.andi a3, 1 /* Mask off BUSY bit. */ +# c.bnez a3, 3b +c.lw a3, 0(a1); /* Tricky: By reading from flash here, we force it to wait for completion. */ + +c.addi a1, 4 /* Advance the destination pointer */ +c.addi a4, 4 /* Advance the source pointer */ + +blt a1, a2, 1b /* Loop untill the end of block. */ + +# c.nop; +# sub a3, a1, t0; +# c.sw a3, 8(a5); /* Loading starting address of a block tto FLASH->ADDR. Seems not needed(?) +lui a3, %hi(0x00010000); /* CR_PAGE_PG */ +addi a3, a3, 0x40 /* CR_STRT_Set (can use ADD instead of OR here) */ +c.sw a3, 4(a5); /* FLASH->CTRL = CR_PAGE_PG|CR_STRT_Set */ +lw a3, -4(a1); /* Can't read past the last byte of the flash, need to decrease */ + +blt a1, t1, 2b /* Loop to start writing the next block */ + +c.li a3, -1 +c.sw a3, 0(a0) /* Write -1 into 0x00 indicating all done. */ + +csrr a5, mstatus; /* Enabling interrupts globally */ +ori a5, a5, 0x88; +csrw mstatus, a5; + +ret diff --git a/inc/misc/attic/rv003usb_bootloader_stubs_for_minichlink/write_block.sh b/inc/misc/attic/rv003usb_bootloader_stubs_for_minichlink/write_block.sh new file mode 100755 index 0000000..f0c7398 --- /dev/null +++ b/inc/misc/attic/rv003usb_bootloader_stubs_for_minichlink/write_block.sh @@ -0,0 +1,5 @@ +#!/bin/bash +rm -f write_block.o write_block.bin +riscv64-unknown-elf-as write_block.asm -march=rv32imac_zicsr -o write_block.o +riscv64-unknown-elf-objcopy -O binary write_block.o write_block.bin +xxd -i write_block.bin > write_block.h