diff --git a/ch32v003fun/ch32v003fun.h b/ch32v003fun/ch32v003fun.h
index cc93d170cfef392a0dfce689d6a76c965b9fe0ab..a63c32e9dcb3f2e3e8a173a0314d671ccca1576e 100644
--- a/ch32v003fun/ch32v003fun.h
+++ b/ch32v003fun/ch32v003fun.h
@@ -197,23 +197,6 @@ typedef struct
 
 /* General Purpose I/O */
 typedef enum
-{
-	GPIO_CFGLR_MODE_IN,
-	GPIO_CFGLR_MODE_OUT_10MHz,
-	GPIO_CFGLR_MODE_OUT_2MHz,
-	GPIO_CFGLR_MODE_OUT_50MHz
-} GPIO_MODE_TypeDef;
-typedef enum
-{
-	GPIO_CFGLR_CNF_IN_ANALOG = 0,
-	GPIO_CFGLR_CNF_IN_FLOAT = 1,
-	GPIO_CFGLR_CNF_IN_PULL_UP_DOWN = 2,
-	GPIO_CFGLR_CNF_OUT_PP = 0,
-	GPIO_CFGLR_CNF_OUT_OD = 1,
-	GPIO_CFGLR_CNF_OUT_AF_PP = 2,
-GPIO_CFGLR_CNF_OUT_AF_OD = 3,
-} GPIO_CNF_TypeDef;
-typedef enum
 {
 	GPIO_CFGLR_IN_ANALOG = 0,
 	GPIO_CFGLR_IN_FLOAT = 4,
@@ -231,128 +214,145 @@ typedef enum
 	GPIO_CFGLR_OUT_2Mhz_AF_OD = 14,
 	GPIO_CFGLR_OUT_50Mhz_AF_OD = 15,
 } GPIO_CFGLR_PIN_MODE_Typedef;
-typedef struct
-{
-	__IO union {
-		uint32_t CFGLR;
-		struct CFGLR_t {
-			GPIO_MODE_TypeDef MODE0 :2;
-			GPIO_CNF_TypeDef CNF0 :2;
-			GPIO_MODE_TypeDef MODE1 :2;
-			GPIO_CNF_TypeDef CNF1 :2;
-			GPIO_MODE_TypeDef MODE2 :2;
-			GPIO_CNF_TypeDef CNF2 :2;
-			GPIO_MODE_TypeDef MODE3 :2;
-			GPIO_CNF_TypeDef CNF3 :2;
-			GPIO_MODE_TypeDef MODE4 :2;
-			GPIO_CNF_TypeDef CNF4 :2;
-			GPIO_MODE_TypeDef MODE5 :2;
-			GPIO_CNF_TypeDef CNF5 :2;
-			GPIO_MODE_TypeDef MODE6 :2;
-			GPIO_CNF_TypeDef CNF6 :2;
-			GPIO_MODE_TypeDef MODE7 :2;
-			GPIO_CNF_TypeDef CNF7 :2;
-	  	} CFGLR_bits;
-	  	struct {
-			GPIO_CFGLR_PIN_MODE_Typedef PIN0 :4;
-			GPIO_CFGLR_PIN_MODE_Typedef PIN1 :4;
-			GPIO_CFGLR_PIN_MODE_Typedef PIN2 :4;
-			GPIO_CFGLR_PIN_MODE_Typedef PIN3 :4;
-			GPIO_CFGLR_PIN_MODE_Typedef PIN4 :4;
-			GPIO_CFGLR_PIN_MODE_Typedef PIN5 :4;
-			GPIO_CFGLR_PIN_MODE_Typedef PIN6 :4;
-			GPIO_CFGLR_PIN_MODE_Typedef PIN7 :4;
-	  	} CFGLR_PINS;
+
+typedef union {
+	uint32_t __FULL;
+	struct {
+		GPIO_CFGLR_PIN_MODE_Typedef PIN0 :4;
+		GPIO_CFGLR_PIN_MODE_Typedef PIN1 :4;
+		GPIO_CFGLR_PIN_MODE_Typedef PIN2 :4;
+		GPIO_CFGLR_PIN_MODE_Typedef PIN3 :4;
+		GPIO_CFGLR_PIN_MODE_Typedef PIN4 :4;
+		GPIO_CFGLR_PIN_MODE_Typedef PIN5 :4;
+		GPIO_CFGLR_PIN_MODE_Typedef PIN6 :4;
+		GPIO_CFGLR_PIN_MODE_Typedef PIN7 :4;
 	};
-	__IO uint32_t CFGHR;
-	__IO union {
-	  	const uint32_t INDR;
-	  	const struct INDR_t {
-			uint32_t IDR0 :1;
-			uint32_t IDR1 :1;
-			uint32_t IDR2 :1;
-			uint32_t IDR3 :1;
-			uint32_t IDR4 :1;
-			uint32_t IDR5 :1;
-			uint32_t IDR6 :1;
-			uint32_t IDR7 :1;
-			uint32_t :24;
-	  	} INDR_bits;
+} CFGLR_t;
+typedef union {
+	uint32_t __FULL;
+	const struct {
+		uint32_t IDR0 :1;
+		uint32_t IDR1 :1;
+		uint32_t IDR2 :1;
+		uint32_t IDR3 :1;
+		uint32_t IDR4 :1;
+		uint32_t IDR5 :1;
+		uint32_t IDR6 :1;
+		uint32_t IDR7 :1;
+		uint32_t :24;
 	};
-	__IO union {
-		uint32_t OUTDR;
-		struct OUTDR_t {
-			uint32_t ODR0 :1;
-			uint32_t ODR1 :1;
-			uint32_t ODR2 :1;
-			uint32_t ODR3 :1;
-			uint32_t ODR4 :1;
-			uint32_t ODR5 :1;
-			uint32_t ODR6 :1;
-			uint32_t ODR7 :1;
-			uint32_t :24;
-	  	} OUTDR_bits;
+} INDR_t;
+typedef union {
+	uint32_t __FULL;
+	struct {
+		uint32_t ODR0 :1;
+		uint32_t ODR1 :1;
+		uint32_t ODR2 :1;
+		uint32_t ODR3 :1;
+		uint32_t ODR4 :1;
+		uint32_t ODR5 :1;
+		uint32_t ODR6 :1;
+		uint32_t ODR7 :1;
+		uint32_t :24;
 	};
-	__IO union {
-		uint32_t BSHR;
-		struct BSHR_t {
-			uint32_t BS0 :1;
-			uint32_t BS1 :1;
-			uint32_t BS2 :1;
-			uint32_t BS3 :1;
-			uint32_t BS4 :1;
-			uint32_t BS5 :1;
-			uint32_t BS6 :1;
-			uint32_t BS7 :1;
-			uint32_t :8;
-			uint32_t BR0 :1;
-			uint32_t BR1 :1;
-			uint32_t BR2 :1;
-			uint32_t BR3 :1;
-			uint32_t BR4 :1;
-			uint32_t BR5 :1;
-			uint32_t BR6 :1;
-			uint32_t BR7 :1;
-			uint32_t :8;
-	  	} BSHR_bits;
+} OUTDR_t;
+typedef union {
+	uint32_t __FULL;
+	struct {
+		uint32_t BS0 :1;
+		uint32_t BS1 :1;
+		uint32_t BS2 :1;
+		uint32_t BS3 :1;
+		uint32_t BS4 :1;
+		uint32_t BS5 :1;
+		uint32_t BS6 :1;
+		uint32_t BS7 :1;
+		uint32_t :8;
+		uint32_t BR0 :1;
+		uint32_t BR1 :1;
+		uint32_t BR2 :1;
+		uint32_t BR3 :1;
+		uint32_t BR4 :1;
+		uint32_t BR5 :1;
+		uint32_t BR6 :1;
+		uint32_t BR7 :1;
+		uint32_t :8;
 	};
-	__IO union {
-		uint32_t BCR;
-		struct BCR_t {
-			uint32_t BR0 :1;
-			uint32_t BR1 :1;
-			uint32_t BR2 :1;
-			uint32_t BR3 :1;
-			uint32_t BR4 :1;
-			uint32_t BR5 :1;
-			uint32_t BR6 :1;
-			uint32_t BR7 :1;
-			uint32_t :24;
-		} BCR_bits;
+} BSHR_t;
+typedef union {
+	uint32_t __FULL;
+	struct {
+		uint32_t BR0 :1;
+		uint32_t BR1 :1;
+		uint32_t BR2 :1;
+		uint32_t BR3 :1;
+		uint32_t BR4 :1;
+		uint32_t BR5 :1;
+		uint32_t BR6 :1;
+		uint32_t BR7 :1;
+		uint32_t :24;
 	};
-	__IO union {
-		uint32_t LCKR;
-		struct LCKR_t {
-			uint32_t LCK0 :1;
-			uint32_t LCK1 :1;
-			uint32_t LCK2 :1;
-			uint32_t LCK3 :1;
-			uint32_t LCK4 :1;
-			uint32_t LCK5 :1;
-			uint32_t LCK6 :1;
-			uint32_t LCK7 :1;
-			uint32_t LCKK :1;
-			uint32_t :23;
-		} LCK_bits;
+} BCR_t;
+typedef union {
+	uint32_t __FULL;
+	struct {
+		uint32_t LCK0 :1;
+		uint32_t LCK1 :1;
+		uint32_t LCK2 :1;
+		uint32_t LCK3 :1;
+		uint32_t LCK4 :1;
+		uint32_t LCK5 :1;
+		uint32_t LCK6 :1;
+		uint32_t LCK7 :1;
+		uint32_t LCKK :1;
+		uint32_t :23;
 	};
+} LCKR_t;
+typedef struct
+{
+	__IO uint32_t CFGLR;
+	__IO uint32_t CFGHR;
+	__I  uint32_t INDR;
+	__IO uint32_t OUTDR;
+	__IO uint32_t BSHR;
+	__IO uint32_t BCR;
+	__IO uint32_t LCKR;
 } GPIO_TypeDef;
+
 static inline void GPIOset(GPIO_TypeDef *gpio, uint8_t pins) __attribute__((always_inline));
 static inline void GPIOset(GPIO_TypeDef *gpio, uint8_t pins) {gpio->BSHR = pins;}
 static inline void GPIOreset(GPIO_TypeDef *gpio, uint8_t pins) __attribute__((always_inline));
 static inline void GPIOreset(GPIO_TypeDef *gpio, uint8_t pins) {gpio->BCR = pins;}
 static inline void GPIOsetReset(GPIO_TypeDef *gpio, uint8_t set_pins, uint8_t reset_pins) __attribute__((always_inline));
 static inline void GPIOsetReset(GPIO_TypeDef *gpio, uint8_t set_pins, uint8_t reset_pins) {gpio->BSHR = set_pins|(reset_pins<<16);}
-#define DYN_REG_WRITE(basereg, reg, field, value) { const struct reg##_t tmp = {.##field = value ,}; basereg##->##reg = tmp;}
+
+static inline void GPIO_CFGLR_set(GPIO_TypeDef *gpio, CFGLR_t val) __attribute__((always_inline));
+static inline void GPIO_CFGLR_set(GPIO_TypeDef *gpio, CFGLR_t val) {gpio->CFGLR = val.__FULL;}
+static inline CFGLR_t GPIO_CFGLR_get(GPIO_TypeDef *gpio)  __attribute__((always_inline));
+static inline CFGLR_t GPIO_CFGLR_get(GPIO_TypeDef *gpio) {CFGLR_t tmp; tmp.__FULL = gpio->CFGLR; return tmp;}
+
+static inline INDR_t GPIO_INDR_get(GPIO_TypeDef *gpio)  __attribute__((always_inline));
+static inline INDR_t GPIO_INDR_get(GPIO_TypeDef *gpio) {INDR_t tmp; tmp.__FULL = gpio->INDR; return tmp;}
+
+static inline void GPIO_OUTDR_set(GPIO_TypeDef *gpio, OUTDR_t val) __attribute__((always_inline));
+static inline void GPIO_OUTDR_set(GPIO_TypeDef *gpio, OUTDR_t val) {gpio->OUTDR = val.__FULL;}
+static inline OUTDR_t GPIO_OUTDR_get(GPIO_TypeDef *gpio)  __attribute__((always_inline));
+static inline OUTDR_t GPIO_OUTDR_get(GPIO_TypeDef *gpio) {OUTDR_t tmp; tmp.__FULL = gpio->OUTDR; return tmp;}
+
+static inline void GPIO_BSHR_set(GPIO_TypeDef *gpio, BSHR_t val) __attribute__((always_inline));
+static inline void GPIO_BSHR_set(GPIO_TypeDef *gpio, BSHR_t val) {gpio->BSHR = val.__FULL;}
+static inline BSHR_t GPIO_BSHR_get(GPIO_TypeDef *gpio)  __attribute__((always_inline));
+static inline BSHR_t GPIO_BSHR_get(GPIO_TypeDef *gpio) {BSHR_t tmp; tmp.__FULL = gpio->BSHR; return tmp;}
+
+static inline void GPIO_BCR_set(GPIO_TypeDef *gpio, BCR_t val) __attribute__((always_inline));
+static inline void GPIO_BCR_set(GPIO_TypeDef *gpio, BCR_t val) {gpio->BCR = val.__FULL;}
+static inline BCR_t GPIO_BCR_get(GPIO_TypeDef *gpio)  __attribute__((always_inline));
+static inline BCR_t GPIO_BCR_get(GPIO_TypeDef *gpio) {BCR_t tmp; tmp.__FULL = gpio->BCR; return tmp;}
+
+static inline void GPIO_LCKR_set(GPIO_TypeDef *gpio, LCKR_t val) __attribute__((always_inline));
+static inline void GPIO_LCKR_set(GPIO_TypeDef *gpio, LCKR_t val) {gpio->LCKR = val.__FULL;}
+static inline LCKR_t GPIO_LCKR_get(GPIO_TypeDef *gpio)  __attribute__((always_inline));
+static inline LCKR_t GPIO_LCKR_get(GPIO_TypeDef *gpio) {LCKR_t tmp; tmp.__FULL = gpio->LCKR; return tmp;}
 
 /* Alternate Function I/O */
 typedef struct
diff --git a/examples/struct_direct_gpio/struct_direct_gpio.c b/examples/struct_direct_gpio/struct_direct_gpio.c
index a25b93f82df309228094a1bfb9972ec2f71ea957..bec4b668ea1998ec15b759beb444a894ae26bef5 100644
--- a/examples/struct_direct_gpio/struct_direct_gpio.c
+++ b/examples/struct_direct_gpio/struct_direct_gpio.c
@@ -1,4 +1,4 @@
-// This tries to generates exacly the same assambly as direct_gpio but with structs
+// This tries to generates exacly the same assambly as direct_gpio but using structs as much as possible
 
 // Could be defined here, or in the processor defines.
 #define SYSTEM_CORE_CLOCK 48000000
@@ -29,15 +29,16 @@ int main()
 	GPIOC->CFGLR &= ~(0xf<<(4*4));
 	GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP)<<(4*4);
 
-
 	while(1)
 	{
 		// Use low bits of BSHR to SET output
-		GPIOset(GPIOC, GPIO_Pin_1); //GPIOC->BSHR_bits = (struct BSHR_t) {.BS1 = 1}; would generate more instructions here
+		GPIOset(GPIOC, GPIO_Pin_1);
 		GPIOset(GPIOC, GPIO_Pin_2);
 
 		// Modify the OUTDR register directly to SET output
-		GPIOC->OUTDR_bits.ODR4 = 1;
+		OUTDR_t tmp = GPIO_OUTDR_get(GPIOC);
+		tmp.ODR4 = 1;
+		GPIO_OUTDR_set(GPIOC, tmp);
 		Delay_Ms( 950 );
 
 		// Use upper bits of BSHR to RESET output
@@ -47,7 +48,9 @@ int main()
 		GPIOset(GPIOC, GPIO_Pin_2);
 
 		// Modify the OUTDR register directly to CLEAR output
-		GPIOC->OUTDR_bits.ODR4 = 0;
+		tmp = GPIO_OUTDR_get(GPIOC);
+		tmp.ODR4 = 0;
+		GPIO_OUTDR_set(GPIOC, tmp);
 
 		Delay_Ms( 50 );
 		count++;
diff --git a/examples/struct_gpio/struct_gpio.c b/examples/struct_gpio/struct_gpio.c
index 5e465816fb3fe439d8ae3b1979ca3fabaa11c944..c57edfeaae795f277298a3a992f731cc38a5087f 100644
--- a/examples/struct_gpio/struct_gpio.c
+++ b/examples/struct_gpio/struct_gpio.c
@@ -23,51 +23,41 @@ int main()
 	printf("CFGLR: %lX\n", GPIOD->CFGLR); // -> CFGLR: 44444444
 
     // GPIO D0, D4 Push-Pull, D1/SWIO floating, default analog input
-	GPIOD->CFGLR_bits = (struct CFGLR_t) {
-		.MODE0 = GPIO_CFGLR_MODE_OUT_10MHz,
-		.CNF0 = GPIO_CFGLR_CNF_OUT_PP,
-		.MODE1 = GPIO_CFGLR_MODE_IN,
-		.CNF1 = GPIO_CFGLR_CNF_IN_FLOAT,
-		.MODE4 = GPIO_CFGLR_MODE_OUT_10MHz,
-		.CNF4 = GPIO_CFGLR_CNF_OUT_PP,
-	};
+	GPIO_CFGLR_set(GPIOD, (CFGLR_t) {
+		.PIN0 = GPIO_CFGLR_OUT_10Mhz_PP,
+		.PIN1 = GPIO_CFGLR_IN_FLOAT,
+		.PIN4 = GPIO_CFGLR_OUT_10Mhz_PP,
+	});
 
 	// all unconfigured pins are now 0b0000, aka analog inputs with TTL Schmitttrigger disabled
 	printf("CFGLR: %lX\n", GPIOD->CFGLR); // -> CFGLR: 10041
 
 	// GPIO C0 Push-Pull with 2 volatile writes
-	GPIOC->CFGLR_bits.MODE0 = GPIO_CFGLR_MODE_OUT_10MHz;
-	GPIOC->CFGLR_bits.CNF0  = GPIO_CFGLR_CNF_OUT_PP;
+	GPIO_CFGLR_set(GPIOC, (CFGLR_t) {
+		.PIN0 = GPIO_CFGLR_OUT_10Mhz_PP,
+	});
 
 	// read modify write
-	struct CFGLR_t ioc = GPIOC->CFGLR_bits;
-	ioc.MODE1 = GPIO_CFGLR_MODE_IN; // not volatile
-	ioc.CNF1 = GPIO_CNF_IN_ANALOG;  // not volatile
-	GPIOC->CFGLR_bits = ioc; // this should be one volatile write
+	CFGLR_t ioc = GPIO_CFGLR_get(GPIOC);
+	ioc.PIN1 = GPIO_CFGLR_IN_ANALOG;
+	GPIO_CFGLR_set(GPIOC, ioc);
 
 	while(1)
 	{
 		// Turn D0 on and D4 off at the same time
-		GPIOD->BSHR_bits = (struct BSHR_t) {
-			.BS0 = 1,
-			.BR4 = 1,
-		};
-		// GCC sometimes wants to be dumb and turns this into: write zero, read back, or your value, write
-		// this is more consistent
-		GPIOsetReset(GPIOD, GPIO_Pin_1, GPIO_Pin_4);
+		GPIOsetReset(GPIOD, GPIO_Pin_0, GPIO_Pin_4);
+		// could be GPIO_BSHR_set(GPIOD, (BSHR){.BS1=1, .BR4=1});
 
 		// implicit read->modify->write
-		GPIOC->OUTDR_bits.ODR0 = 1;
+		// GPIOC->OUTDR_bits.ODR0 = 1; // no idea how to do this now
 		Delay_Ms( 100 );
 
 		// Turn D0 off and D4 on at the same time
-		GPIOD->BSHR_bits = (struct BSHR_t) {
-			.BR0 = 1,
-			.BS4 = 1,
-		};
+		GPIOsetReset(GPIOD, GPIO_Pin_4, GPIO_Pin_1);
+		// could be GPIO_BSHR_set(GPIOD, (BSHR){.BR1=1, .BS4=1});
 
 		// implicit read->modify->write
-		GPIOC->OUTDR_bits.ODR0 = 0;
+		//GPIOC->OUTDR_bits.ODR0 = 0; // no idea how to do this now
 		Delay_Ms( 100 );
 
 		// to only set/reset use