Fix Bug #11 (platform SPI transmit-only), FPGA B2 (chirp BRAM migration), FPGA B3 (DSP48 pipelining)
Bug #11: platform_noos_stm32.c used HAL_SPI_Transmit instead of HAL_SPI_TransmitReceive — reads returned garbage. Changed to in-place full-duplex. Dead code (never called), fixed per audit recommendation. Test added: test_bug11_platform_spi_transmit_only.c. Mock infrastructure updated with SPI spy types. All 11 firmware tests pass. FPGA B2: Migrated long_chirp_lut[0:3599] from ~700 lines of hardcoded assignments to BRAM with (* ram_style = "block" *) attribute and $readmemh("long_chirp_lut.mem"). Added sync-only read block for proper BRAM inference. 1-cycle read latency introduced. short_chirp_lut left as distributed RAM (60 entries, too small for BRAM). FPGA B3: Added BREG (window_val_reg) and MREG (mult_i_raw/mult_q_raw) pipeline stages to doppler_processor.v. Eliminates DPIP-1 and DPOP-2 DRC warnings. S_LOAD_FFT retimed: fft_input_valid starts at sub=2, +1 cycle total latency. BREG primed in S_PRE_READ at no extra cost. Both FPGA files compile clean with Icarus Verilog.
This commit is contained in:
@@ -30,6 +30,10 @@ MOCK_OBJS := $(MOCK_SRCS:.c=.o)
|
||||
# Real source compiled as object (for tests that need it)
|
||||
REAL_OBJ := adf4382a_manager.o
|
||||
|
||||
# Platform source compiled with shim headers
|
||||
PLATFORM_SRC := ../9_1_1_C_Cpp_Libraries/platform_noos_stm32.c
|
||||
PLATFORM_OBJ := platform_noos_stm32.o
|
||||
|
||||
# Tests that link against real adf4382a_manager.c + mocks
|
||||
TESTS_WITH_REAL := test_bug1_timed_sync_init_ordering \
|
||||
test_bug3_timed_sync_noop \
|
||||
@@ -44,9 +48,12 @@ TESTS_MOCK_ONLY := test_bug2_ad9523_double_setup \
|
||||
test_bug7_gpio_pin_conflict \
|
||||
test_bug8_uart_commented_out
|
||||
|
||||
ALL_TESTS := $(TESTS_WITH_REAL) $(TESTS_MOCK_ONLY)
|
||||
# Tests that need platform_noos_stm32.o + mocks
|
||||
TESTS_WITH_PLATFORM := test_bug11_platform_spi_transmit_only
|
||||
|
||||
.PHONY: all build test clean $(addprefix test_,bug1 bug2 bug3 bug4 bug5 bug6 bug7 bug8 bug9 bug10)
|
||||
ALL_TESTS := $(TESTS_WITH_REAL) $(TESTS_MOCK_ONLY) $(TESTS_WITH_PLATFORM)
|
||||
|
||||
.PHONY: all build test clean $(addprefix test_,bug1 bug2 bug3 bug4 bug5 bug6 bug7 bug8 bug9 bug10 bug11)
|
||||
|
||||
all: build test
|
||||
|
||||
@@ -54,7 +61,7 @@ build: $(ALL_TESTS)
|
||||
|
||||
test: build
|
||||
@echo "==============================================="
|
||||
@echo " Running all 10 bug tests..."
|
||||
@echo " Running all 11 bug tests..."
|
||||
@echo "==============================================="
|
||||
@pass=0; fail=0; \
|
||||
for t in $(ALL_TESTS); do \
|
||||
@@ -81,6 +88,10 @@ test: build
|
||||
$(REAL_OBJ): $(REAL_SRC) $(MOCK_OBJS)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c $(REAL_SRC) -o $@
|
||||
|
||||
# Platform source compiled with shim headers
|
||||
$(PLATFORM_OBJ): $(PLATFORM_SRC) $(MOCK_OBJS)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c $(PLATFORM_SRC) -o $@
|
||||
|
||||
# --- Test binary rules ---
|
||||
|
||||
# Tests that need real adf4382a_manager.o + mocks
|
||||
@@ -101,6 +112,10 @@ test_bug7_gpio_pin_conflict: test_bug7_gpio_pin_conflict.c $(MOCK_OBJS)
|
||||
test_bug8_uart_commented_out: test_bug8_uart_commented_out.c
|
||||
$(CC) $(CFLAGS) -I. $< -o $@
|
||||
|
||||
# Tests that need platform_noos_stm32.o + mocks
|
||||
$(TESTS_WITH_PLATFORM): %: %.c $(MOCK_OBJS) $(PLATFORM_OBJ)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) $< $(MOCK_OBJS) $(PLATFORM_OBJ) -o $@
|
||||
|
||||
# --- Individual test targets ---
|
||||
|
||||
test_bug1: test_bug1_timed_sync_init_ordering
|
||||
@@ -133,6 +148,9 @@ test_bug9: test_bug9_platform_ops_null
|
||||
test_bug10: test_bug10_spi_cs_not_toggled
|
||||
./test_bug10_spi_cs_not_toggled
|
||||
|
||||
test_bug11: test_bug11_platform_spi_transmit_only
|
||||
./test_bug11_platform_spi_transmit_only
|
||||
|
||||
# --- Clean ---
|
||||
|
||||
clean:
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/* shims/platform_noos_stm32.h -- redirect to mock HAL */
|
||||
#ifndef SHIM_PLATFORM_NOOS_STM32_H
|
||||
#define SHIM_PLATFORM_NOOS_STM32_H
|
||||
#include "stm32_hal_mock.h"
|
||||
|
||||
/* Re-export real function prototypes */
|
||||
int32_t platform_spi_init(void **desc, uint32_t max_speed_hz, uint8_t mode);
|
||||
int32_t platform_spi_write_and_read(void *desc, uint8_t *data, uint16_t len);
|
||||
int32_t platform_spi_remove(void *desc);
|
||||
int32_t platform_gpio_init(void *gpio_desc, uint8_t port_pin, bool is_output);
|
||||
int32_t platform_gpio_direction_output(void *gpio_desc, uint8_t port_pin, uint8_t value);
|
||||
int32_t platform_gpio_set_value(void *gpio_desc, uint8_t port_pin, uint8_t value);
|
||||
int32_t platform_gpio_remove(void *gpio_desc);
|
||||
void platform_delay_ms(uint32_t ms);
|
||||
#endif
|
||||
@@ -264,6 +264,37 @@ void mock_tim_set_compare(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t Co
|
||||
});
|
||||
}
|
||||
|
||||
/* ========================= SPI stubs ============================== */
|
||||
|
||||
HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
|
||||
{
|
||||
spy_push((SpyRecord){
|
||||
.type = SPY_SPI_TRANSMIT_RECEIVE,
|
||||
.port = NULL,
|
||||
.pin = Size,
|
||||
.value = Timeout,
|
||||
.extra = hspi
|
||||
});
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
|
||||
{
|
||||
spy_push((SpyRecord){
|
||||
.type = SPY_SPI_TRANSMIT,
|
||||
.port = NULL,
|
||||
.pin = Size,
|
||||
.value = Timeout,
|
||||
.extra = hspi
|
||||
});
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/* Stub for platform_noos_stm32.c GPIO functions */
|
||||
void hal_set_gpio_by_index(uint8_t idx, uint8_t value) {
|
||||
(void)idx; (void)value;
|
||||
}
|
||||
|
||||
/* ========================= Mock stm32_spi_ops ===================== */
|
||||
|
||||
/* Stub SPI platform ops -- real adf4382a_manager.c references &stm32_spi_ops.
|
||||
|
||||
@@ -133,6 +133,8 @@ typedef enum {
|
||||
SPY_TIM_PWM_START,
|
||||
SPY_TIM_PWM_STOP,
|
||||
SPY_TIM_SET_COMPARE,
|
||||
SPY_SPI_TRANSMIT_RECEIVE,
|
||||
SPY_SPI_TRANSMIT,
|
||||
} SpyCallType;
|
||||
|
||||
typedef struct {
|
||||
@@ -182,6 +184,11 @@ uint32_t HAL_GetTick(void);
|
||||
void HAL_Delay(uint32_t Delay);
|
||||
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
|
||||
|
||||
/* ========================= SPI stubs ============================== */
|
||||
|
||||
HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout);
|
||||
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
|
||||
|
||||
/* ========================= no_os compat layer ===================== */
|
||||
|
||||
void no_os_udelay(uint32_t usecs);
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*******************************************************************************
|
||||
* test_bug11_platform_spi_transmit_only.c
|
||||
*
|
||||
* Bug #11: platform_noos_stm32.c used HAL_SPI_Transmit() instead of
|
||||
* HAL_SPI_TransmitReceive(), meaning reads returned garbage.
|
||||
*
|
||||
* Post-fix: Verify platform_spi_write_and_read() calls TransmitReceive.
|
||||
******************************************************************************/
|
||||
#include "stm32_hal_mock.h"
|
||||
#include "platform_noos_stm32.h"
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("[Bug #11] platform_spi_write_and_read uses TransmitReceive\n");
|
||||
|
||||
/* ---- setup ---- */
|
||||
spy_reset();
|
||||
|
||||
/* Init: get a descriptor (should be &hspi4) */
|
||||
void *desc = NULL;
|
||||
int32_t rc = platform_spi_init(&desc, 1000000, 0);
|
||||
assert(rc == 0);
|
||||
assert(desc == (void *)&hspi4);
|
||||
|
||||
/* Call write_and_read */
|
||||
uint8_t buf[4] = {0xAA, 0xBB, 0xCC, 0xDD};
|
||||
rc = platform_spi_write_and_read(desc, buf, 4);
|
||||
assert(rc == 0);
|
||||
|
||||
/* Verify: should see SPY_SPI_TRANSMIT_RECEIVE, NOT SPY_SPI_TRANSMIT */
|
||||
int tx_rx_count = spy_count_type(SPY_SPI_TRANSMIT_RECEIVE);
|
||||
int tx_only_count = spy_count_type(SPY_SPI_TRANSMIT);
|
||||
|
||||
assert(tx_rx_count == 1 && "Expected exactly one HAL_SPI_TransmitReceive call");
|
||||
assert(tx_only_count == 0 && "Should not use HAL_SPI_Transmit (that was the bug)");
|
||||
|
||||
/* Verify correct SPI handle */
|
||||
int idx = spy_find_nth(SPY_SPI_TRANSMIT_RECEIVE, 0);
|
||||
assert(idx >= 0);
|
||||
const SpyRecord *rec = spy_get(idx);
|
||||
assert(rec->extra == (void *)&hspi4);
|
||||
assert(rec->pin == 4); /* Size = 4 */
|
||||
|
||||
/* ---- null descriptor test ---- */
|
||||
spy_reset();
|
||||
rc = platform_spi_write_and_read(NULL, buf, 4);
|
||||
assert(rc == -1);
|
||||
|
||||
/* ---- null desc pointer on init ---- */
|
||||
rc = platform_spi_init(NULL, 1000000, 0);
|
||||
assert(rc == -1);
|
||||
|
||||
printf("[Bug #11] PASSED\n");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user