diff --git a/.gitignore b/.gitignore
index 8e15e6b5f34019b4d4224077995af9ec5c46da4c..559b58626e1d6044e0cef1bff755f767570da0fd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,8 @@ sdkconfig
 dependencies.lock
 build
 
+.sdkconfig.defaults.generated
+
 # micropython
 __pycache__
 
diff --git a/README.md b/README.md
index bbe5cecb50f4bd95bb6bae3885de33137e6f1abe..a79656fd010b5a3641d683cd753197117539f1a2 100644
--- a/README.md
+++ b/README.md
@@ -67,6 +67,7 @@ By default, code for the fourth generation prototype will be built. To select a
 | `p1` or `proto1`                | Prototype 1                        |
 | `p3` or `proto3`                | Prototype 3 (B3xx)                 |
 | `p4` or `proto4`                | Prototype 4 (B4xx)                 |
+| `p6` or `proto6`                | Prototype 6 (B6xx)                 |
 
 **Important**: when switching generations, do a full clean by running `rm -rf sdkconfig build`. Otherwise you will get _weird_ errors and likely will end up building for the wrong architecture.
 
@@ -195,12 +196,13 @@ Good luck. The idf.py gdb/openocd scripts seem somewhat buggy.
 
 #### sdkconfig / menuconfig
 
-We have an sdkconfig.default file per badge generation. See the build
+We have an sdkconfig.defaults file. It is used to generate a '.generated' file
+with flow3r-specific options based on the given -g option. See the build
 instructions above to see how to select the generation to build against.
 
-The build system will generate an sdkconfig, but it should not be committed into
-version control. Instead, treat it like an ephemeral artifact that you can also
-modify for your own needs during development.
+The build system will generate an sdkconfig, but it should not be committed
+into version control. Instead, treat it like an ephemeral artifact that you can
+also modify for your own needs during development.
 
 To run menuconfig, do the usual::
 
@@ -208,11 +210,12 @@ To run menuconfig, do the usual::
 $ idf.py  menuconfig
 ```
 
-(Specify -g or BADGE_GENERATION if you haven't built the firmware yet)
+(Specify -g or `BADGE_GENERATION` if you haven't built the firmware yet)
 
 Then, either save into the temporary sdkconfig by using 'S', or save into a
 defconfig by using 'D'. The resulting `build/defconfig` file can then be copied
-into `sdkconfig.$generation` to change the defaults for a given generation.
+into `sdkconfig` to change the defaults for a given generation (be sure to
+remove BADGE23_* options that are usually generated by `idf_ext.py`).
 
 ### Badge link
 
diff --git a/idf_ext.py b/idf_ext.py
index df7432b87cf082153b93e9c3182af7df721b4d4d..b6bf13cbd7c2dff329c5c2f659a3b58586abc61d 100644
--- a/idf_ext.py
+++ b/idf_ext.py
@@ -9,7 +9,7 @@ import shutil
 def action_extensions(base_actions, project_path=os.getcwd()):
     """
     Implementes -g/--generation and BADGE_GENERATION in idf.py, allowing
-    switching between badge generations and sdkconfig default files.
+    switching between badge generations.
     """
 
     # Map from canonical name to user-supported names.
@@ -46,16 +46,24 @@ def action_extensions(base_actions, project_path=os.getcwd()):
             supported = sorted(supported)
             raise Exception(f'Invalid generation: want one of {", ".join(supported)}')
 
-        sdkconfig_name = 'sdkconfig.' + name
-        sdkconfig_path = os.path.join(project_path, sdkconfig_name)
-        if not os.path.exists(sdkconfig_path):
-            raise Exception(f'Missing sdkconfig file {sdkconfig_name}')
-        cache_entries = {
-            'SDKCONFIG_DEFAULTS': sdkconfig_path,
-        }
-        print(cache_entries)
-        global_args.define_cache_entry = list(global_args.define_cache_entry)
-        global_args.define_cache_entry.extend(['%s=%s' % (k, v) for k, v in cache_entries.items()])
+
+        # Generate .sdkconfig.defaults.generated that contains BADGE23_*
+        # options.
+        sdkconfig_defaults_path = os.path.join(project_path, 'sdkconfig.defaults')
+        sdkconfig_generated_path = os.path.join(project_path, '.sdkconfig.defaults.generated')
+        with open(sdkconfig_generated_path, 'w') as f:
+            if name == 'p6spiral':
+                f.write('CONFIG_BADGE23_HW_GEN_P6=y\n')
+                f.write('CONFIG_BADGE23_TOP_BOARD_SPIRALS=y\n')
+            else:
+                f.write(f'CONFIG_BADGE23_HW_GEN_{name.upper()}=y\n')
+            with open(sdkconfig_defaults_path) as f2:
+                f.write(f2.read())
+
+        global_args.define_cache_entry += [
+            'SDKCONFIG_DEFAULTS=' + sdkconfig_generated_path,
+        ]
+        print(global_args.define_cache_entry)
 
     # Add global options
     extensions = {
diff --git a/sdkconfig.p1 b/sdkconfig.defaults
similarity index 98%
rename from sdkconfig.p1
rename to sdkconfig.defaults
index 434090f6be5c36f5c54f1e141919f0f3ad5053c6..395b69df455272e89955fc3fee79fb7c1157c21b 100644
--- a/sdkconfig.p1
+++ b/sdkconfig.defaults
@@ -39,4 +39,3 @@ CONFIG_LOG_DEFAULT_LEVEL_ERROR=y
 CONFIG_LWIP_PPP_SUPPORT=y
 CONFIG_LWIP_PPP_PAP_SUPPORT=y
 CONFIG_LWIP_PPP_CHAP_SUPPORT=y
-CONFIG_BADGE23_HW_GEN_P1=y
diff --git a/sdkconfig.p3 b/sdkconfig.p3
deleted file mode 100644
index e7b51954bfd4b6c8111bd4ba8307d433bb9a04cc..0000000000000000000000000000000000000000
--- a/sdkconfig.p3
+++ /dev/null
@@ -1,42 +0,0 @@
-CONFIG_APP_EXCLUDE_PROJECT_VER_VAR=y
-CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR=y
-CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
-CONFIG_ESPTOOLPY_NO_STUB=y
-CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
-CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
-CONFIG_ESPTOOLPY_AFTER_NORESET=y
-CONFIG_PARTITION_TABLE_CUSTOM=y
-CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="components/micropython/vendor/ports/esp32/partitions-8MiB.csv"
-CONFIG_COMPILER_OPTIMIZATION_PERF=y
-CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y
-CONFIG_BT_ENABLED=y
-CONFIG_BT_NIMBLE_ENABLED=y
-CONFIG_BT_NIMBLE_MAX_CONNECTIONS=4
-CONFIG_BT_NIMBLE_PINNED_TO_CORE_1=y
-CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y
-CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB=y
-CONFIG_ESP32S3_DATA_CACHE_64KB=y
-CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y
-CONFIG_ESP32S3_SPIRAM_SUPPORT=y
-CONFIG_SPIRAM_MODE_OCT=y
-CONFIG_SPIRAM_TYPE_ESPPSRAM64=y
-CONFIG_SPIRAM_SPEED_80M=y
-CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
-CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=65536
-CONFIG_PM_ENABLE=y
-CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
-# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set
-# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 is not set
-# CONFIG_ESP32_WIFI_IRAM_OPT is not set
-# CONFIG_ESP32_WIFI_RX_IRAM_OPT is not set
-CONFIG_FATFS_LFN_HEAP=y
-CONFIG_FATFS_API_ENCODING_UTF_8=y
-CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=2
-CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP=y
-CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y
-CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y
-CONFIG_LOG_DEFAULT_LEVEL_ERROR=y
-CONFIG_LWIP_PPP_SUPPORT=y
-CONFIG_LWIP_PPP_PAP_SUPPORT=y
-CONFIG_LWIP_PPP_CHAP_SUPPORT=y
-CONFIG_BADGE23_HW_GEN_P3=y
diff --git a/sdkconfig.p4 b/sdkconfig.p4
deleted file mode 100644
index 653d34beba0a74c3b6fc3f066f3405f08a3a2bfd..0000000000000000000000000000000000000000
--- a/sdkconfig.p4
+++ /dev/null
@@ -1,42 +0,0 @@
-CONFIG_APP_EXCLUDE_PROJECT_VER_VAR=y
-CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR=y
-CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
-CONFIG_ESPTOOLPY_NO_STUB=y
-CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
-CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
-CONFIG_ESPTOOLPY_AFTER_NORESET=y
-CONFIG_PARTITION_TABLE_CUSTOM=y
-CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="components/micropython/vendor/ports/esp32/partitions-8MiB.csv"
-CONFIG_COMPILER_OPTIMIZATION_PERF=y
-CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y
-CONFIG_BT_ENABLED=y
-CONFIG_BT_NIMBLE_ENABLED=y
-CONFIG_BT_NIMBLE_MAX_CONNECTIONS=4
-CONFIG_BT_NIMBLE_PINNED_TO_CORE_1=y
-CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y
-CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB=y
-CONFIG_ESP32S3_DATA_CACHE_64KB=y
-CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y
-CONFIG_ESP32S3_SPIRAM_SUPPORT=y
-CONFIG_SPIRAM_MODE_OCT=y
-CONFIG_SPIRAM_TYPE_ESPPSRAM64=y
-CONFIG_SPIRAM_SPEED_80M=y
-CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
-CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=65536
-CONFIG_PM_ENABLE=y
-CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
-# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set
-# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 is not set
-# CONFIG_ESP32_WIFI_IRAM_OPT is not set
-# CONFIG_ESP32_WIFI_RX_IRAM_OPT is not set
-CONFIG_FATFS_LFN_HEAP=y
-CONFIG_FATFS_API_ENCODING_UTF_8=y
-CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=2
-CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP=y
-CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y
-CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y
-CONFIG_LOG_DEFAULT_LEVEL_ERROR=y
-CONFIG_LWIP_PPP_SUPPORT=y
-CONFIG_LWIP_PPP_PAP_SUPPORT=y
-CONFIG_LWIP_PPP_CHAP_SUPPORT=y
-CONFIG_BADGE23_HW_GEN_P4=y
diff --git a/sdkconfig.p6 b/sdkconfig.p6
deleted file mode 100644
index c8e1a160d53d4e820ef1861acfb8bf6c249b4a7b..0000000000000000000000000000000000000000
--- a/sdkconfig.p6
+++ /dev/null
@@ -1,43 +0,0 @@
-CONFIG_APP_EXCLUDE_PROJECT_VER_VAR=y
-CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR=y
-CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
-CONFIG_ESPTOOLPY_NO_STUB=y
-CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
-CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
-CONFIG_ESPTOOLPY_AFTER_NORESET=y
-CONFIG_PARTITION_TABLE_CUSTOM=y
-CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="components/micropython/vendor/ports/esp32/partitions-8MiB.csv"
-CONFIG_COMPILER_OPTIMIZATION_PERF=y
-CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y
-CONFIG_BT_ENABLED=y
-CONFIG_BT_NIMBLE_ENABLED=y
-CONFIG_BT_NIMBLE_MAX_CONNECTIONS=4
-CONFIG_BT_NIMBLE_PINNED_TO_CORE_1=y
-CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y
-CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB=y
-CONFIG_ESP32S3_DATA_CACHE_64KB=y
-CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y
-CONFIG_ESP32S3_SPIRAM_SUPPORT=y
-CONFIG_SPIRAM_MODE_OCT=y
-CONFIG_SPIRAM_TYPE_ESPPSRAM64=y
-CONFIG_SPIRAM_SPEED_80M=y
-CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
-CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=65536
-CONFIG_PM_ENABLE=y
-CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
-# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set
-# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 is not set
-# CONFIG_ESP32_WIFI_IRAM_OPT is not set
-# CONFIG_ESP32_WIFI_RX_IRAM_OPT is not set
-CONFIG_FATFS_LFN_HEAP=y
-CONFIG_FATFS_API_ENCODING_UTF_8=y
-CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=2
-CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP=y
-CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y
-CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y
-CONFIG_LOG_DEFAULT_LEVEL_ERROR=y
-CONFIG_LWIP_PPP_SUPPORT=y
-CONFIG_LWIP_PPP_PAP_SUPPORT=y
-CONFIG_LWIP_PPP_CHAP_SUPPORT=y
-CONFIG_BADGE23_HW_GEN_P6=y
-CONFIG_BADGE23_TOP_BOARD_SPIKES=y
diff --git a/sdkconfig.p6spiral b/sdkconfig.p6spiral
deleted file mode 100644
index 4d8098e0a2786e98eeb1410699e3786e8cd22383..0000000000000000000000000000000000000000
--- a/sdkconfig.p6spiral
+++ /dev/null
@@ -1,43 +0,0 @@
-CONFIG_APP_EXCLUDE_PROJECT_VER_VAR=y
-CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR=y
-CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
-CONFIG_ESPTOOLPY_NO_STUB=y
-CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
-CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
-CONFIG_ESPTOOLPY_AFTER_NORESET=y
-CONFIG_PARTITION_TABLE_CUSTOM=y
-CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="micropython/ports/esp32/partitions-8MiB.csv"
-CONFIG_COMPILER_OPTIMIZATION_PERF=y
-CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y
-CONFIG_BT_ENABLED=y
-CONFIG_BT_NIMBLE_ENABLED=y
-CONFIG_BT_NIMBLE_MAX_CONNECTIONS=4
-CONFIG_BT_NIMBLE_PINNED_TO_CORE_1=y
-CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y
-CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB=y
-CONFIG_ESP32S3_DATA_CACHE_64KB=y
-CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y
-CONFIG_ESP32S3_SPIRAM_SUPPORT=y
-CONFIG_SPIRAM_MODE_OCT=y
-CONFIG_SPIRAM_TYPE_ESPPSRAM64=y
-CONFIG_SPIRAM_SPEED_80M=y
-CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
-CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=65536
-CONFIG_PM_ENABLE=y
-CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
-# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set
-# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 is not set
-# CONFIG_ESP32_WIFI_IRAM_OPT is not set
-# CONFIG_ESP32_WIFI_RX_IRAM_OPT is not set
-CONFIG_FATFS_LFN_HEAP=y
-CONFIG_FATFS_API_ENCODING_UTF_8=y
-CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=2
-CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP=y
-CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y
-CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y
-CONFIG_LOG_DEFAULT_LEVEL_ERROR=y
-CONFIG_LWIP_PPP_SUPPORT=y
-CONFIG_LWIP_PPP_PAP_SUPPORT=y
-CONFIG_LWIP_PPP_CHAP_SUPPORT=y
-CONFIG_BADGE23_HW_GEN_P6=y
-CONFIG_BADGE23_TOP_BOARD_SPIRALS=y