Skip to content

Commit de8243d

Browse files
committed
SD recording
1 parent d102a09 commit de8243d

13 files changed

Lines changed: 1319 additions & 303 deletions

File tree

ch32v305/src/FreeRTOSConfig.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
#define INCLUDE_uxTaskPriorityGet 0
6565
#define INCLUDE_vTaskDelete 0
6666
#define INCLUDE_vTaskSuspend 1
67+
#define INCLUDE_xTaskResumeFromISR 1
6768
#define INCLUDE_vTaskDelayUntil 1
6869
#define INCLUDE_vTaskDelay 1
6970
#define INCLUDE_xTaskAbortDelay 0

ch32v305/src/freertos/port_ch32v30x.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ portIRQ_WRAPPER EXTI15_10_IRQHandler, EXTI15_10_IRQHandler_Body
115115
portIRQ_WRAPPER TIM10_CC_IRQHandler, TIM10_CC_IRQHandler_Body
116116
portIRQ_WRAPPER I2C2_EV_IRQHandler, I2C2_EV_IRQHandler_Body
117117
portIRQ_WRAPPER I2C2_ER_IRQHandler, I2C2_ER_IRQHandler_Body
118+
portIRQ_WRAPPER SDIO_IRQHandler, SDIO_IRQHandler_Body
119+
portIRQ_WRAPPER DMA2_Channel4_IRQHandler, DMA2_Channel4_IRQHandler_Body
118120

119121
.global Ecall_M_Mode_Handler
120122
.type Ecall_M_Mode_Handler, @function

ch32v305/src/freertos/port_ch32v30x.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,19 @@ static void systick_compare_write(uint64_t deadline)
4242
compare_words[1] = (uint32_t)(deadline >> 32);
4343
compare_words[0] = (uint32_t)deadline;
4444
__asm volatile("fence iorw, iorw" ::: "memory");
45+
46+
/*
47+
* Unlike RISC-V mtimecmp, this SysTick only documents an equality
48+
* condition. If CNT reaches or passes the final compare value while the
49+
* 64-bit value is being published, the hardware cannot assert it later.
50+
* Pend SysTick explicitly so the handler accounts for the elapsed boundary
51+
* instead of waiting for the 64-bit counter to wrap.
52+
*/
53+
if(systick_count_read() >= deadline)
54+
{
55+
NVIC_SetPendingIRQ(SysTicK_IRQn);
56+
__asm volatile("fence iorw, iorw" ::: "memory");
57+
}
4558
}
4659

4760
static BaseType_t pfic_has_enabled_pending_irq(void)

ch32v305/src/freertos/task_stacks.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@
33

44
/*
55
* Sizes are in 32-bit StackType_t words. The allocations include the
6-
* 256-byte integer/FPU context-switch frame. Application_Task was reduced by
7-
* the 96 bytes removed from its compiler-emitted frame when SDCardPoll was
8-
* disabled; USB and I2S retain their existing margins. Returning maskable
9-
* ISRs use the dedicated 1.5 KiB IRQ stack instead of application task stacks.
6+
* 256-byte integer/FPU context-switch frame. The recording task's post-LTO
7+
* frame is 272 bytes. Its deepest linked path (file cleanup through FatFs and
8+
* asynchronous SDIO) sums to 1328 bytes before the context frame, so 432
9+
* words leave 144 bytes beyond that path and the port context.
10+
* Returning maskable ISRs use the dedicated 1.5 KiB IRQ stack instead of
11+
* application task stacks.
1012
*/
1113
#define APP_TASK_STACK_WORDS 432U
1214
#define USB_TASK_STACK_WORDS 256U
1315
#define I2S_TASK_STACK_WORDS 192U
14-
#define HW_STATE_TASK_STACK_WORDS 512U
16+
#define HW_STATE_TASK_STACK_WORDS 64U
17+
#define RECORDING_TASK_STACK_WORDS 432U
1518

1619
#endif

ch32v305/src/hw/i2s.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "dac.h"
1212
#include "freertos/port_isr.h"
1313
#include "main.h"
14+
#include "recording.h"
1415
#include "pinout.h"
1516
#include "usb.h"
1617

@@ -121,17 +122,25 @@ static void i2s_bitslip_detect(volatile uint16_t const *src_words)
121122
}
122123

123124
volatile uint32_t const *src32 = (volatile uint32_t const *)(uintptr_t)src_words;
125+
bool ch2_nonzero = true;
126+
bool ch1_zero = true;
124127
for(size_t i = 0; i < I2S_RX_DMA_CHUNK_WORDS / 2U; i++)
125128
{
126129
uint32_t raw = src32[i];
127130
uint32_t sample_32 = (raw << 16) | (raw >> 16);
128-
bool should_be_ch1_mute = (i & 1U) == 0U;
129-
if(should_be_ch1_mute && (sample_32 != 0U))
130-
{
131-
s_i2s_needs_reset = true;
132-
return;
131+
if((i & 1U) == 0) {
132+
// CH1
133+
ch1_zero &= sample_32 == 0;
134+
} else {
135+
// CH2
136+
ch2_nonzero &= sample_32 != 0;
133137
}
134138
}
139+
if(! (ch2_nonzero && ch1_zero))
140+
{
141+
s_i2s_needs_reset = true;
142+
return;
143+
}
135144
}
136145

137146
static void i2s_process_buf(volatile uint16_t *src_words)
@@ -158,6 +167,8 @@ static void i2s_process_buf(volatile uint16_t *src_words)
158167
}
159168
s_fft_sample_cnt = fft_idx;
160169

170+
recording_submit_i2s(src_words, I2S_RX_DMA_CHUNK_WORDS);
171+
161172
s_rx_word_count += I2S_RX_DMA_CHUNK_WORDS;
162173
audio_usb_mic_write(src_words, I2S_RX_DMA_CHUNK_WORDS);
163174
demod_process(src_words, I2S_RX_DMA_CHUNK_WORDS);

ch32v305/src/hw/sdcard/sdcard.cpp

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ extern "C" {
77
#include "bitbang.h"
88

99
#include <algorithm>
10-
#include <array>
1110
#include <concepts>
12-
#include <cstring>
1311
#include <expected>
1412
#include <limits>
1513

@@ -55,11 +53,7 @@ class SDCard {
5553

5654
ErrorStatus read_sector(uint32_t sector, std::span<uint8_t, 512> buf)
5755
{
58-
if(!initialized ||
59-
(!sdhc && sector > std::numeric_limits<uint32_t>::max() / 512U))
60-
return NoREADY;
61-
uint32_t addr = sdhc ? sector : sector * 512U;
62-
return transport.read_blocks(addr, buf);
56+
return read_sectors(sector, buf);
6357
}
6458

6559
ErrorStatus read_sectors(uint32_t start_sector, std::span<uint8_t> buf)
@@ -79,6 +73,7 @@ class SDCard {
7973
{
8074
uint32_t sector = start_sector + static_cast<uint32_t>(block_offset);
8175
uint32_t addr = sdhc ? sector : sector * 512U;
76+
8277
std::size_t blocks_remaining =
8378
static_cast<std::size_t>(block_count) - block_offset;
8479
std::size_t blocks_this_transfer =
@@ -117,17 +112,6 @@ class SDCard {
117112
{
118113
uint32_t sector = start_sector + static_cast<uint32_t>(block_offset);
119114
uint32_t addr = sdhc ? sector : sector * 512U;
120-
const uint8_t* source = buf.data() + block_offset * 512U;
121-
bool aligned = (reinterpret_cast<uintptr_t>(source) & 3U) == 0U;
122-
123-
if(!aligned)
124-
{
125-
std::memcpy(write_bounce.data(), source, write_bounce.size());
126-
if(transport.write_blocks(addr, write_bounce) != READY)
127-
return NoREADY;
128-
++block_offset;
129-
continue;
130-
}
131115

132116
std::size_t blocks_remaining =
133117
static_cast<std::size_t>(block_count) - block_offset;
@@ -154,7 +138,6 @@ class SDCard {
154138
bool initialized = false;
155139
bool sdhc = false;
156140
CID card_cid = {};
157-
alignas(4) std::array<uint8_t, 512> write_bounce{};
158141
};
159142

160143
// --- compile-time transport selection -------------------------------------

0 commit comments

Comments
 (0)