VesiScan BASIC origin: Piezo + IMU firmware initial code
- nRF52840 + SoftDevice S140 BLE firmware - Piezo ultrasound TX driver (2MHz, 8ch MUX) - ICM42670P IMU 6-axis driver - Echo AFE chain (ADA2200 + ADC121S051) - BLE NUS command parser (mpa/mpc/mdc/mec/maa/msp) - FDS flash config storage - pc_firm parser and ADC driver included Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -145,19 +145,12 @@ void TIMER2_IRQHandler(void)
|
||||
|
||||
void dr_piezo_power_on(void)
|
||||
{
|
||||
/* 1. IR power ON (from power_control.c) */
|
||||
ir_power_control(ON);
|
||||
nrf_delay_ms(20);
|
||||
|
||||
/* 2. Configure power control pins */
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PWR_SHDN);
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PWR_EN_10V);
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PWR_EN);
|
||||
nrf_gpio_pin_set(DR_PIEZO_PWR_EN);
|
||||
|
||||
/* 3. Enable DC/DC converter (+/-20V) */
|
||||
nrf_gpio_pin_set(DR_PIEZO_PWR_SHDN);
|
||||
nrf_gpio_pin_set(DR_PIEZO_PWR_EN_10V);
|
||||
|
||||
/* 4. Wait for power stabilization */
|
||||
/* Wait for power stabilization */
|
||||
nrf_delay_ms(10);
|
||||
|
||||
m_power_enabled = true;
|
||||
@@ -169,8 +162,7 @@ void dr_piezo_power_off(void)
|
||||
{
|
||||
dr_piezo_disable();
|
||||
|
||||
nrf_gpio_pin_clear(DR_PIEZO_PWR_SHDN);
|
||||
nrf_gpio_pin_clear(DR_PIEZO_PWR_EN_10V);
|
||||
nrf_gpio_pin_clear(DR_PIEZO_PWR_EN);
|
||||
|
||||
m_power_enabled = false;
|
||||
|
||||
@@ -470,16 +462,108 @@ void dr_piezo_set_frequency(uint32_t freq_hz)
|
||||
void dr_piezo_mux_init(void)
|
||||
{
|
||||
/* Configure MUX control pins as outputs */
|
||||
nrf_gpio_cfg_output(DR_PIEZO_MUX_SEL1);
|
||||
/*nrf_gpio_cfg_output(DR_PIEZO_MUX_SEL1);
|
||||
nrf_gpio_cfg_output(DR_PIEZO_MUX_SEL2);
|
||||
nrf_gpio_cfg_output(DR_PIEZO_MUX_SEL3);
|
||||
nrf_gpio_cfg_output(DR_PIEZO_MUX_SEL3);*/
|
||||
|
||||
/*nrf_gpio_cfg_output(DR_PIEZO_EN_MUXA);
|
||||
nrf_gpio_cfg_output(DR_PIEZO_EN_MUXB);
|
||||
nrf_gpio_cfg_output(DR_PIEZO_MUX_SEL0);
|
||||
nrf_gpio_cfg_output(DR_PIEZO_MUX_SEL1);*/
|
||||
|
||||
/* Configure pins as output with high drive strength */
|
||||
nrf_gpio_cfg(
|
||||
DR_PIEZO_MUX_SEL0,
|
||||
NRF_GPIO_PIN_DIR_OUTPUT,
|
||||
NRF_GPIO_PIN_INPUT_DISCONNECT,
|
||||
NRF_GPIO_PIN_NOPULL,
|
||||
NRF_GPIO_PIN_H0H1, /* High drive */
|
||||
NRF_GPIO_PIN_NOSENSE
|
||||
);
|
||||
nrf_gpio_cfg(
|
||||
DR_PIEZO_MUX_SEL1,
|
||||
NRF_GPIO_PIN_DIR_OUTPUT,
|
||||
NRF_GPIO_PIN_INPUT_DISCONNECT,
|
||||
NRF_GPIO_PIN_NOPULL,
|
||||
NRF_GPIO_PIN_H0H1, /* High drive */
|
||||
NRF_GPIO_PIN_NOSENSE
|
||||
);
|
||||
|
||||
/* GPIO PIN Setting jhChun 0129 */
|
||||
nrf_gpio_cfg(
|
||||
DR_PIEZO_EN_MUXA, // PIN
|
||||
NRF_GPIO_PIN_DIR_OUTPUT, // DIR : OUTPUT
|
||||
NRF_GPIO_PIN_INPUT_DISCONNECT, // INPUT BUFFER X (DIR : OUTPUT)
|
||||
NRF_GPIO_PIN_NOPULL, // PULL UP, PULL DOWN X
|
||||
NRF_GPIO_PIN_H0H1, // HIGH DRIVE(STRONG OUTPUT) !!
|
||||
NRF_GPIO_PIN_NOSENSE // INTERRUPT X
|
||||
);
|
||||
|
||||
nrf_gpio_cfg(
|
||||
DR_PIEZO_EN_MUXB,
|
||||
NRF_GPIO_PIN_DIR_OUTPUT,
|
||||
NRF_GPIO_PIN_INPUT_DISCONNECT,
|
||||
NRF_GPIO_PIN_NOPULL,
|
||||
NRF_GPIO_PIN_H0H1,
|
||||
NRF_GPIO_PIN_NOSENSE
|
||||
);
|
||||
|
||||
/* Set MUX selection: P1.13=HIGH, P1.12=LOW, P1.11=LOW */
|
||||
nrf_gpio_pin_set(DR_PIEZO_MUX_SEL1); /* P1.13 = HIGH */
|
||||
nrf_gpio_pin_clear(DR_PIEZO_MUX_SEL2); /* P1.12 = LOW */
|
||||
nrf_gpio_pin_clear(DR_PIEZO_MUX_SEL3); /* P1.11 = LOW */
|
||||
//nrf_gpio_pin_set(DR_PIEZO_MUX_SEL1); /* P1.13 = HIGH */
|
||||
//nrf_gpio_pin_clear(DR_PIEZO_MUX_SEL2); /* P1.12 = LOW */
|
||||
//nrf_gpio_pin_clear(DR_PIEZO_MUX_SEL3); /* P1.11 = LOW */
|
||||
|
||||
DBG_PRINTF("[DR_PIEZO] MUX init: SEL1=HIGH, SEL2=LOW, SEL3=LOW\r\n");
|
||||
nrf_gpio_pin_clear(DR_PIEZO_EN_MUXA); /* P0.21 = LOW, Select Channel -> HIGH */
|
||||
nrf_gpio_pin_clear(DR_PIEZO_EN_MUXB); /* P0.23 = LOW, Select Channel -> HIGH */
|
||||
nrf_gpio_pin_clear(DR_PIEZO_MUX_SEL0); /* P1.10 = LOW */
|
||||
nrf_gpio_pin_clear(DR_PIEZO_MUX_SEL1); /* P0.28 = LOW */
|
||||
|
||||
DBG_PRINTF("[DR_PIEZO] MUX init done\r\n");
|
||||
}
|
||||
|
||||
|
||||
void dr_piezo_select_channel(uint8_t channel)
|
||||
{
|
||||
channel = channel & 0x07; /* Mask to 0-7 */
|
||||
|
||||
switch (channel) {
|
||||
// EN_A EN_B SEL0 SEL1
|
||||
case 0: // A0: 1 0 0 0
|
||||
nrf_gpio_pin_clear(DR_PIEZO_EN_MUXB); nrf_gpio_pin_set(DR_PIEZO_EN_MUXA);
|
||||
nrf_gpio_pin_clear(DR_PIEZO_MUX_SEL0); nrf_gpio_pin_clear(DR_PIEZO_MUX_SEL1);
|
||||
break;
|
||||
case 1: // A2: 1 0 1 0
|
||||
nrf_gpio_pin_clear(DR_PIEZO_EN_MUXB); nrf_gpio_pin_set(DR_PIEZO_EN_MUXA);
|
||||
nrf_gpio_pin_set(DR_PIEZO_MUX_SEL0); nrf_gpio_pin_clear(DR_PIEZO_MUX_SEL1);
|
||||
break;
|
||||
case 2: // A1: 1 0 0 1
|
||||
nrf_gpio_pin_clear(DR_PIEZO_EN_MUXB); nrf_gpio_pin_set(DR_PIEZO_EN_MUXA);
|
||||
nrf_gpio_pin_clear(DR_PIEZO_MUX_SEL0); nrf_gpio_pin_set(DR_PIEZO_MUX_SEL1);
|
||||
break;
|
||||
case 3: // A3: 1 0 1 1
|
||||
nrf_gpio_pin_clear(DR_PIEZO_EN_MUXB); nrf_gpio_pin_set(DR_PIEZO_EN_MUXA);
|
||||
nrf_gpio_pin_set(DR_PIEZO_MUX_SEL0); nrf_gpio_pin_set(DR_PIEZO_MUX_SEL1);
|
||||
break;
|
||||
case 4: // B0: 0 1 1 1
|
||||
nrf_gpio_pin_clear(DR_PIEZO_EN_MUXA); nrf_gpio_pin_set(DR_PIEZO_EN_MUXB);
|
||||
nrf_gpio_pin_set(DR_PIEZO_MUX_SEL0); nrf_gpio_pin_set(DR_PIEZO_MUX_SEL1);
|
||||
break;
|
||||
case 5: // B1: 0 1 1 0
|
||||
nrf_gpio_pin_clear(DR_PIEZO_EN_MUXA); nrf_gpio_pin_set(DR_PIEZO_EN_MUXB);
|
||||
nrf_gpio_pin_clear(DR_PIEZO_MUX_SEL0); nrf_gpio_pin_set(DR_PIEZO_MUX_SEL1);
|
||||
break;
|
||||
case 6: // B2: 0 1 0 1
|
||||
nrf_gpio_pin_clear(DR_PIEZO_EN_MUXA); nrf_gpio_pin_set(DR_PIEZO_EN_MUXB);
|
||||
nrf_gpio_pin_set(DR_PIEZO_MUX_SEL0); nrf_gpio_pin_clear(DR_PIEZO_MUX_SEL1);
|
||||
break;
|
||||
case 7: // B3: 0 1 0 0
|
||||
nrf_gpio_pin_clear(DR_PIEZO_EN_MUXA); nrf_gpio_pin_set(DR_PIEZO_EN_MUXB);
|
||||
nrf_gpio_pin_clear(DR_PIEZO_MUX_SEL0); nrf_gpio_pin_clear(DR_PIEZO_MUX_SEL1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Delay for MUX settling (analog path stabilization) */
|
||||
nrf_delay_us(DR_PIEZO_MUX_SETTLING_US);
|
||||
}
|
||||
|
||||
void dr_piezo_test_pins(void)
|
||||
@@ -599,32 +683,33 @@ void dr_piezo_transmit(uint8_t cycles)
|
||||
* but it will also shorten their lifespan
|
||||
* - Charles KWON
|
||||
*/
|
||||
|
||||
#define P_OUT_MASK (1UL << PIN_NUM(DR_PIEZO_PIN_P_OUT)) /* P1.03 */ // Save your li
|
||||
#define N_OUT_MASK (1UL << PIN_NUM(DR_PIEZO_PIN_N_OUT)) /* P1.02 */
|
||||
#define PE_MASK (1UL << PIN_NUM(DR_PIEZO_PIN_PE)) /* P1.05 */
|
||||
#define DMP_MASK (1UL << PIN_NUM(DR_PIEZO_PIN_DMP)) /* P1.09 */
|
||||
|
||||
/* Piezo channel select pins - MUST BE PRESERVED during burst */
|
||||
#define CH_SEL0_MASK (1UL << 11) /* P1.11 - Channel select LSB */
|
||||
#define CH_SEL1_MASK (1UL << 12) /* P1.12 - Channel select MSB */
|
||||
#define CH_SEL_MASK (CH_SEL0_MASK | CH_SEL1_MASK)
|
||||
#define P_OUT_MASK (1UL << PIN_NUM(DR_PIEZO_PIN_P_OUT)) /* P1.03 -> P1.07 */
|
||||
#define N_OUT_MASK (1UL << PIN_NUM(DR_PIEZO_PIN_N_OUT)) /* P1.02 -> P1.06 */
|
||||
#define PE_MASK (1UL << PIN_NUM(DR_PIEZO_PIN_PE)) /* P1.05 -> P0.25 */
|
||||
#define DMP_MASK (1UL << PIN_NUM(DR_PIEZO_PIN_DMP)) /* P1.09 -> P1.00 */
|
||||
|
||||
/* Combined mask for all piezo control signals (excluding channel select) */
|
||||
#define PIEZO_CTRL_MASK (P_OUT_MASK | N_OUT_MASK | PE_MASK | DMP_MASK)
|
||||
#define P1_CTRL_MASK (P_OUT_MASK | N_OUT_MASK | DMP_MASK)
|
||||
|
||||
void dr_piezo_burst_sw(uint8_t cycles)
|
||||
{
|
||||
/* Clamp cycles to valid range (1-20) */
|
||||
if (cycles < 1) cycles = 1;
|
||||
if (cycles > 20) cycles = 20;
|
||||
|
||||
|
||||
/* RTT: snapshot then single print */
|
||||
uint32_t _d0 = NRF_P1->OUT;
|
||||
|
||||
/* Disable GPIOTE hardware control to prevent conflicts */
|
||||
nrf_gpiote_task_disable(GPIOTE_CH_P_OUT);
|
||||
nrf_gpiote_task_disable(GPIOTE_CH_N_OUT);
|
||||
|
||||
|
||||
uint32_t _d1 = NRF_P1->OUT;
|
||||
|
||||
/* Save ENTIRE P1 port state BEFORE any GPIO config */
|
||||
uint32_t saved_p1_out = NRF_P1->OUT;
|
||||
uint32_t saved_p0_out = NRF_P0->OUT;
|
||||
|
||||
/* Configure all signal pins as outputs */
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_PE);
|
||||
@@ -632,30 +717,26 @@ void dr_piezo_burst_sw(uint8_t cycles)
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_P_OUT);
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_N_OUT);
|
||||
|
||||
uint32_t _d2 = NRF_P1->OUT;
|
||||
|
||||
DBG_PRINTF("[B]S0:%u%u%u\r\n", (_d0>>10)&1, (_d1>>10)&1, (_d2>>10)&1);
|
||||
|
||||
/* Restore P1 port state (nrf_gpio_cfg_output may clear bits) */
|
||||
NRF_P1->OUT = saved_p1_out;
|
||||
|
||||
NRF_P0->OUT = (NRF_P0->OUT & ~PE_MASK) | (saved_p0_out & PE_MASK);
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Pre-calculate all output states for fast switching
|
||||
* Each state represents a specific combination of pin levels
|
||||
* IMPORTANT: Channel select pins (P1.11, P1.12) are preserved in all states
|
||||
*------------------------------------------------------------------------*/
|
||||
uint32_t ch_sel_state = saved_p1_out & CH_SEL_MASK;
|
||||
|
||||
/* State 1: All control signals LOW (idle state) - preserve CH_SEL and other pins */
|
||||
uint32_t state_all_low = (saved_p1_out & ~PIEZO_CTRL_MASK);
|
||||
// PE는 OUTSET/OUTCLR 사용 (다른 P0 핀 영향 방지)
|
||||
|
||||
/* State 2: Only PE HIGH (margin periods before pulses and after DMP) */
|
||||
uint32_t state_PE_only = (state_all_low | PE_MASK);
|
||||
|
||||
/* State 3: PE=HIGH, P_OUT=HIGH, N_OUT=LOW (first half of each cycle) */
|
||||
uint32_t state_PE_P_high_N_low = (state_all_low | PE_MASK | P_OUT_MASK);
|
||||
|
||||
/* State 4: PE=HIGH, P_OUT=LOW, N_OUT=HIGH (second half of each cycle) */
|
||||
uint32_t state_PE_P_low_N_high = (state_all_low | PE_MASK | N_OUT_MASK);
|
||||
|
||||
/* State 5: PE=HIGH, DMP=HIGH, P_OUT=LOW, N_OUT=LOW (dump period) */
|
||||
uint32_t state_PE_DMP_high = (state_all_low | PE_MASK | DMP_MASK);
|
||||
uint32_t p1_all_low = saved_p1_out & ~P1_CTRL_MASK;
|
||||
uint32_t p1_P_high_N_low = p1_all_low | P_OUT_MASK;
|
||||
uint32_t p1_P_low_N_high = p1_all_low | N_OUT_MASK;
|
||||
uint32_t p1_DMP_high = p1_all_low | DMP_MASK;
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Critical timing section - interrupts disabled
|
||||
@@ -663,34 +744,36 @@ void dr_piezo_burst_sw(uint8_t cycles)
|
||||
__disable_irq();
|
||||
|
||||
/* Initialize: Set all signals to LOW */
|
||||
NRF_P1->OUT = state_all_low;
|
||||
|
||||
NRF_P0->OUTCLR = PE_MASK; // PE OFF (OUTCLR로 다른 핀 영향 없음)
|
||||
NRF_P1->OUT = p1_all_low;
|
||||
|
||||
/* PE rises first with margin before pulses start */
|
||||
NRF_P1->OUT = state_PE_only;
|
||||
NRF_P0->OUTSET = PE_MASK; // PE ON (OUTSET로 다른 핀 영향 없음)
|
||||
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
|
||||
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
|
||||
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
|
||||
|
||||
|
||||
@@ -706,15 +789,17 @@ void dr_piezo_burst_sw(uint8_t cycles)
|
||||
for (uint8_t i = 0; i < cycles; i++)
|
||||
{
|
||||
/* First half-period: P_OUT=HIGH, N_OUT=LOW */
|
||||
NRF_P1->OUT = state_PE_P_high_N_low;
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
NRF_P1->OUT = p1_P_high_N_low;
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();__NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
|
||||
|
||||
/* Second half-period: P_OUT=LOW, N_OUT=HIGH */
|
||||
NRF_P1->OUT = state_PE_P_low_N_high;
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
NRF_P1->OUT = p1_P_low_N_high;
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
@@ -722,7 +807,8 @@ void dr_piezo_burst_sw(uint8_t cycles)
|
||||
* - Starts simultaneously with N_OUT falling edge
|
||||
* - Duration: ~500ns (32 NOPs)
|
||||
*------------------------------------------------------------------------*/
|
||||
NRF_P1->OUT = state_PE_DMP_high;
|
||||
|
||||
NRF_P1->OUT = p1_DMP_high;
|
||||
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
@@ -734,12 +820,11 @@ void dr_piezo_burst_sw(uint8_t cycles)
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
|
||||
/* DMP falls, PE remains HIGH for margin period */
|
||||
NRF_P1->OUT = state_PE_only;
|
||||
NRF_P1->OUT = p1_all_low;
|
||||
__NOP(); __NOP(); __NOP(); /* ~47ns margin */
|
||||
|
||||
/* End of sequence: All signals return to LOW */
|
||||
NRF_P1->OUT = state_all_low;
|
||||
|
||||
|
||||
NRF_P0->OUTCLR = PE_MASK; // PE OFF
|
||||
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
@@ -763,8 +848,9 @@ void dr_piezo_burst_sw_18mhz(uint8_t cycles)
|
||||
nrf_gpiote_task_disable(GPIOTE_CH_P_OUT);
|
||||
nrf_gpiote_task_disable(GPIOTE_CH_N_OUT);
|
||||
|
||||
/* Save ENTIRE P1 port state BEFORE any GPIO config */
|
||||
/* Save port states BEFORE any GPIO config */
|
||||
uint32_t saved_p1_out = NRF_P1->OUT;
|
||||
uint32_t saved_p0_out = NRF_P0->OUT;
|
||||
|
||||
/* Configure all signal pins as outputs */
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_PE);
|
||||
@@ -772,24 +858,26 @@ void dr_piezo_burst_sw_18mhz(uint8_t cycles)
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_P_OUT);
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_N_OUT);
|
||||
|
||||
/* Restore P1 port state (nrf_gpio_cfg_output may clear bits) */
|
||||
/* Restore port states (nrf_gpio_cfg_output may clear bits) */
|
||||
NRF_P1->OUT = saved_p1_out;
|
||||
NRF_P0->OUT = (NRF_P0->OUT & ~PE_MASK) | (saved_p0_out & PE_MASK);
|
||||
|
||||
/* Pre-calculate all output states for fast switching
|
||||
* IMPORTANT: Channel select pins (P1.11, P1.12) are preserved in all states */
|
||||
uint32_t state_all_low = (saved_p1_out & ~PIEZO_CTRL_MASK);
|
||||
uint32_t state_PE_only = (state_all_low | PE_MASK);
|
||||
uint32_t state_PE_P_high_N_low = (state_all_low | PE_MASK | P_OUT_MASK);
|
||||
uint32_t state_PE_P_low_N_high = (state_all_low | PE_MASK | N_OUT_MASK);
|
||||
uint32_t state_PE_DMP_high = (state_all_low | PE_MASK | DMP_MASK);
|
||||
//NRF_P0->OUT = saved_p0_out;
|
||||
|
||||
/* Pre-calculate P1 output states (PE는 P0.25 - OUTSET/OUTCLR로 제어) */
|
||||
uint32_t p1_all_low = saved_p1_out & ~P1_CTRL_MASK;
|
||||
uint32_t p1_P_high_N_low = p1_all_low | P_OUT_MASK;
|
||||
uint32_t p1_P_low_N_high = p1_all_low | N_OUT_MASK;
|
||||
uint32_t p1_DMP_high = p1_all_low | DMP_MASK;
|
||||
|
||||
__disable_irq();
|
||||
|
||||
/* Initialize: Set all signals to LOW */
|
||||
NRF_P1->OUT = state_all_low;
|
||||
NRF_P0->OUTCLR = PE_MASK;
|
||||
NRF_P1->OUT = p1_all_low;
|
||||
|
||||
/* PE rises first with margin before pulses start */
|
||||
NRF_P1->OUT = state_PE_only;
|
||||
NRF_P0->OUTSET = PE_MASK;
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
@@ -826,20 +914,21 @@ void dr_piezo_burst_sw_18mhz(uint8_t cycles)
|
||||
for (uint8_t i = 0; i < cycles; i++)
|
||||
{
|
||||
/* First half-period: P_OUT=HIGH, N_OUT=LOW */
|
||||
NRF_P1->OUT = state_PE_P_high_N_low;
|
||||
NRF_P1->OUT = p1_P_high_N_low;
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
|
||||
/* Second half-period: P_OUT=LOW, N_OUT=HIGH */
|
||||
NRF_P1->OUT = state_PE_P_low_N_high;
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP();
|
||||
|
||||
/* Second half-period: P_OUT=LOW, N_OUT=HIGH */
|
||||
NRF_P1->OUT = p1_P_low_N_high;
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP();
|
||||
}
|
||||
|
||||
/* DMP (Dump) pulse */
|
||||
NRF_P1->OUT = state_PE_DMP_high;
|
||||
NRF_P1->OUT = p1_DMP_high;
|
||||
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
@@ -851,11 +940,11 @@ void dr_piezo_burst_sw_18mhz(uint8_t cycles)
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
|
||||
/* DMP falls, PE remains HIGH for margin period */
|
||||
NRF_P1->OUT = state_PE_only;
|
||||
NRF_P1->OUT = p1_all_low;
|
||||
__NOP(); __NOP(); __NOP();
|
||||
|
||||
/* End of sequence: All signals return to LOW */
|
||||
NRF_P1->OUT = state_all_low;
|
||||
/* End of sequence: PE OFF */
|
||||
NRF_P0->OUTCLR = PE_MASK;
|
||||
|
||||
__enable_irq();
|
||||
}
|
||||
@@ -881,8 +970,9 @@ void dr_piezo_burst_sw_20mhz(uint8_t cycles)
|
||||
nrf_gpiote_task_disable(GPIOTE_CH_P_OUT);
|
||||
nrf_gpiote_task_disable(GPIOTE_CH_N_OUT);
|
||||
|
||||
/* Save ENTIRE P1 port state BEFORE any GPIO config */
|
||||
/* Save port states BEFORE any GPIO config */
|
||||
uint32_t saved_p1_out = NRF_P1->OUT;
|
||||
uint32_t saved_p0_out = NRF_P0->OUT;
|
||||
|
||||
/* Configure all signal pins as outputs */
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_PE);
|
||||
@@ -890,24 +980,25 @@ void dr_piezo_burst_sw_20mhz(uint8_t cycles)
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_P_OUT);
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_N_OUT);
|
||||
|
||||
/* Restore P1 port state (nrf_gpio_cfg_output may clear bits) */
|
||||
/* Restore port states (nrf_gpio_cfg_output may clear bits) */
|
||||
NRF_P1->OUT = saved_p1_out;
|
||||
//NRF_P0->OUT = saved_p0_out;
|
||||
NRF_P0->OUT = (NRF_P0->OUT & ~PE_MASK) | (saved_p0_out & PE_MASK);
|
||||
|
||||
/* Pre-calculate all output states for fast switching
|
||||
* IMPORTANT: Channel select pins (P1.11, P1.12) are preserved in all states */
|
||||
uint32_t state_all_low = (saved_p1_out & ~PIEZO_CTRL_MASK);
|
||||
uint32_t state_PE_only = (state_all_low | PE_MASK);
|
||||
uint32_t state_PE_P_high_N_low = (state_all_low | PE_MASK | P_OUT_MASK);
|
||||
uint32_t state_PE_P_low_N_high = (state_all_low | PE_MASK | N_OUT_MASK);
|
||||
uint32_t state_PE_DMP_high = (state_all_low | PE_MASK | DMP_MASK);
|
||||
/* Pre-calculate P1 output states (PE는 P0.25 - OUTSET/OUTCLR로 제어) */
|
||||
uint32_t p1_all_low = saved_p1_out & ~P1_CTRL_MASK;
|
||||
uint32_t p1_P_high_N_low = p1_all_low | P_OUT_MASK;
|
||||
uint32_t p1_P_low_N_high = p1_all_low | N_OUT_MASK;
|
||||
uint32_t p1_DMP_high = p1_all_low | DMP_MASK;
|
||||
|
||||
__disable_irq();
|
||||
|
||||
/* Initialize: Set all signals to LOW */
|
||||
NRF_P1->OUT = state_all_low;
|
||||
NRF_P0->OUTCLR = PE_MASK;
|
||||
NRF_P1->OUT = p1_all_low;
|
||||
|
||||
/* PE rises first with margin before pulses start */
|
||||
NRF_P1->OUT = state_PE_only;
|
||||
NRF_P0->OUTSET = PE_MASK;
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
@@ -944,20 +1035,21 @@ void dr_piezo_burst_sw_20mhz(uint8_t cycles)
|
||||
for (uint8_t i = 0; i < cycles; i++)
|
||||
{
|
||||
/* First half-period: P_OUT=HIGH, N_OUT=LOW */
|
||||
NRF_P1->OUT = state_PE_P_high_N_low;
|
||||
NRF_P1->OUT = p1_P_high_N_low;
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP();
|
||||
|
||||
/* Second half-period: P_OUT=LOW, N_OUT=HIGH */
|
||||
NRF_P1->OUT = state_PE_P_low_N_high;
|
||||
NRF_P1->OUT = p1_P_low_N_high;
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP();
|
||||
|
||||
}
|
||||
|
||||
/* DMP (Dump) pulse */
|
||||
NRF_P1->OUT = state_PE_DMP_high;
|
||||
NRF_P1->OUT = p1_DMP_high;
|
||||
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
@@ -969,11 +1061,257 @@ void dr_piezo_burst_sw_20mhz(uint8_t cycles)
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
|
||||
/* DMP falls, PE remains HIGH for margin period */
|
||||
NRF_P1->OUT = state_PE_only;
|
||||
NRF_P1->OUT = p1_all_low;
|
||||
__NOP(); __NOP(); __NOP();
|
||||
|
||||
/* End of sequence: All signals return to LOW */
|
||||
NRF_P1->OUT = state_all_low;
|
||||
/* End of sequence: PE OFF */
|
||||
NRF_P0->OUTCLR = PE_MASK;
|
||||
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Software-based burst at 2.0 MHz
|
||||
* @param cycles Number of cycles (1~20)
|
||||
*
|
||||
* Timing:
|
||||
* 1.9 MHz: 500ns period, 250ns half-period
|
||||
* At 64MHz CPU (1 NOP = 15.625ns):
|
||||
* First half: 14 NOPs (~219ns) + register write (~30ns) = ~249ns
|
||||
* Second half: 11 NOPs (~172ns) + loop overhead (~47ns) = ~219ns
|
||||
* Total: ~468-500ns per cycle
|
||||
*/
|
||||
void dr_piezo_burst_sw_19mhz(uint8_t cycles)
|
||||
{
|
||||
/* Clamp cycles to valid range (1-20) */
|
||||
if (cycles < 1) cycles = 1;
|
||||
if (cycles > 20) cycles = 20;
|
||||
|
||||
/* Disable GPIOTE hardware control to prevent conflicts */
|
||||
nrf_gpiote_task_disable(GPIOTE_CH_P_OUT);
|
||||
nrf_gpiote_task_disable(GPIOTE_CH_N_OUT);
|
||||
|
||||
/* Save port states BEFORE any GPIO config */
|
||||
uint32_t saved_p1_out = NRF_P1->OUT;
|
||||
uint32_t saved_p0_out = NRF_P0->OUT;
|
||||
|
||||
/* Configure all signal pins as outputs */
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_PE);
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_DMP);
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_P_OUT);
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_N_OUT);
|
||||
|
||||
/* Restore port states (nrf_gpio_cfg_output may clear bits) */
|
||||
NRF_P1->OUT = saved_p1_out;
|
||||
//NRF_P0->OUT = saved_p0_out;
|
||||
NRF_P0->OUT = (NRF_P0->OUT & ~PE_MASK) | (saved_p0_out & PE_MASK);
|
||||
|
||||
/* Pre-calculate P1 output states (PE는 P0.25 - OUTSET/OUTCLR로 제어) */
|
||||
uint32_t p1_all_low = saved_p1_out & ~P1_CTRL_MASK;
|
||||
uint32_t p1_P_high_N_low = p1_all_low | P_OUT_MASK;
|
||||
uint32_t p1_P_low_N_high = p1_all_low | N_OUT_MASK;
|
||||
uint32_t p1_DMP_high = p1_all_low | DMP_MASK;
|
||||
|
||||
__disable_irq();
|
||||
|
||||
/* Initialize: Set all signals to LOW */
|
||||
NRF_P0->OUTCLR = PE_MASK;
|
||||
NRF_P1->OUT = p1_all_low;
|
||||
|
||||
/* PE rises first with margin before pulses start */
|
||||
NRF_P0->OUTSET = PE_MASK;
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Generate 2.0MHz pulse burst
|
||||
*
|
||||
* 2.0 MHz: 500ns period, 250ns half-period
|
||||
* At 64MHz CPU (1 NOP = 15.625ns):
|
||||
* First half: 14 NOPs (~219ns) + register write (~30ns) = ~249ns
|
||||
* Second half: 11 NOPs (~172ns) + loop overhead (~47ns) = ~219ns
|
||||
* Total: ~468-500ns per cycle
|
||||
*------------------------------------------------------------------------*/
|
||||
for (uint8_t i = 0; i < cycles; i++)
|
||||
{
|
||||
/* First half-period: P_OUT=HIGH, N_OUT=LOW */
|
||||
NRF_P1->OUT = p1_P_high_N_low;
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP();
|
||||
|
||||
/* Second half-period: P_OUT=LOW, N_OUT=HIGH */
|
||||
NRF_P1->OUT = p1_P_low_N_high;
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
|
||||
}
|
||||
|
||||
/* DMP (Dump) pulse */
|
||||
NRF_P1->OUT = p1_DMP_high;
|
||||
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
|
||||
/* DMP falls, PE remains HIGH for margin period */
|
||||
NRF_P1->OUT = p1_all_low;
|
||||
__NOP(); __NOP(); __NOP();
|
||||
|
||||
/* End of sequence: PE OFF */
|
||||
NRF_P0->OUTCLR = PE_MASK;
|
||||
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Software-based burst at 2.2 MHz
|
||||
* @param cycles Number of cycles (1~20)
|
||||
*
|
||||
* Timing:
|
||||
* 2.2 MHz: 454ns period, 227ns half-period
|
||||
* At 64MHz CPU (1 NOP = 15.625ns):
|
||||
* First half: 13 NOPs (~203ns) + register write (~30ns) = ~233ns
|
||||
* Second half: 11 NOPs (~172ns) + loop overhead (~47ns) = ~219ns
|
||||
* Total: ~452ns per cycle (~2.21 MHz)
|
||||
*/
|
||||
void dr_piezo_burst_sw_22mhz(uint8_t cycles)
|
||||
{
|
||||
/* Clamp cycles to valid range (1-20) */
|
||||
if (cycles < 1) cycles = 1;
|
||||
if (cycles > 20) cycles = 20;
|
||||
|
||||
/* Disable GPIOTE hardware control to prevent conflicts */
|
||||
nrf_gpiote_task_disable(GPIOTE_CH_P_OUT);
|
||||
nrf_gpiote_task_disable(GPIOTE_CH_N_OUT);
|
||||
|
||||
/* Save port states BEFORE any GPIO config */
|
||||
uint32_t saved_p1_out = NRF_P1->OUT;
|
||||
uint32_t saved_p0_out = NRF_P0->OUT;
|
||||
|
||||
/* Configure all signal pins as outputs */
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_PE);
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_DMP);
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_P_OUT);
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_N_OUT);
|
||||
|
||||
/* Restore port states (nrf_gpio_cfg_output may clear bits) */
|
||||
NRF_P1->OUT = saved_p1_out;
|
||||
NRF_P0->OUT = (NRF_P0->OUT & ~PE_MASK) | (saved_p0_out & PE_MASK);
|
||||
|
||||
/* Pre-calculate P1 output states */
|
||||
uint32_t p1_all_low = saved_p1_out & ~P1_CTRL_MASK;
|
||||
uint32_t p1_P_high_N_low = p1_all_low | P_OUT_MASK;
|
||||
uint32_t p1_P_low_N_high = p1_all_low | N_OUT_MASK;
|
||||
uint32_t p1_DMP_high = p1_all_low | DMP_MASK;
|
||||
|
||||
__disable_irq();
|
||||
|
||||
/* Initialize: Set all signals to LOW */
|
||||
NRF_P0->OUTCLR = PE_MASK;
|
||||
NRF_P1->OUT = p1_all_low;
|
||||
|
||||
/* PE rises first with margin before pulses start */
|
||||
NRF_P0->OUTSET = PE_MASK;
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
* Generate 2.2MHz pulse burst
|
||||
*
|
||||
* 2.2 MHz: 454ns period, 227ns half-period
|
||||
* At 64MHz CPU (1 NOP = 15.625ns):
|
||||
* First half: 11 NOPs - positive pulse width
|
||||
* Second half: 10 NOPs - negative pulse width
|
||||
* Total: 21 NOPs per cycle (~2.2 MHz)
|
||||
*------------------------------------------------------------------------*/
|
||||
for (uint8_t i = 0; i < cycles; i++)
|
||||
{
|
||||
/* First half-period: P_OUT=HIGH, N_OUT=LOW (positive pulse width) */
|
||||
NRF_P1->OUT = p1_P_high_N_low;
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP();
|
||||
__NOP();
|
||||
|
||||
/* Second half-period: P_OUT=LOW, N_OUT=HIGH (negative pulse width) */
|
||||
NRF_P1->OUT = p1_P_low_N_high;
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
}
|
||||
|
||||
/* DMP (Dump) pulse */
|
||||
NRF_P1->OUT = p1_DMP_high;
|
||||
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
|
||||
/* DMP falls, PE remains HIGH for margin period */
|
||||
NRF_P1->OUT = p1_all_low;
|
||||
__NOP(); __NOP(); __NOP();
|
||||
|
||||
/* End of sequence: PE OFF */
|
||||
NRF_P0->OUTCLR = PE_MASK;
|
||||
|
||||
__enable_irq();
|
||||
}
|
||||
@@ -999,8 +1337,9 @@ void dr_piezo_burst_sw_17mhz(uint8_t cycles)
|
||||
nrf_gpiote_task_disable(GPIOTE_CH_P_OUT);
|
||||
nrf_gpiote_task_disable(GPIOTE_CH_N_OUT);
|
||||
|
||||
/* Save ENTIRE P1 port state BEFORE any GPIO config */
|
||||
/* Save port states BEFORE any GPIO config */
|
||||
uint32_t saved_p1_out = NRF_P1->OUT;
|
||||
uint32_t saved_p0_out = NRF_P0->OUT;
|
||||
|
||||
/* Configure all signal pins as outputs */
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_PE);
|
||||
@@ -1008,24 +1347,24 @@ void dr_piezo_burst_sw_17mhz(uint8_t cycles)
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_P_OUT);
|
||||
nrf_gpio_cfg_output(DR_PIEZO_PIN_N_OUT);
|
||||
|
||||
/* Restore P1 port state (nrf_gpio_cfg_output may clear bits) */
|
||||
/* Restore port states (nrf_gpio_cfg_output may clear bits) */
|
||||
NRF_P1->OUT = saved_p1_out;
|
||||
NRF_P0->OUT = (NRF_P0->OUT & ~PE_MASK) | (saved_p0_out & PE_MASK);
|
||||
|
||||
/* Pre-calculate all output states for fast switching
|
||||
* IMPORTANT: Channel select pins (P1.11, P1.12) are preserved in all states */
|
||||
uint32_t state_all_low = (saved_p1_out & ~PIEZO_CTRL_MASK);
|
||||
uint32_t state_PE_only = (state_all_low | PE_MASK);
|
||||
uint32_t state_PE_P_high_N_low = (state_all_low | PE_MASK | P_OUT_MASK);
|
||||
uint32_t state_PE_P_low_N_high = (state_all_low | PE_MASK | N_OUT_MASK);
|
||||
uint32_t state_PE_DMP_high = (state_all_low | PE_MASK | DMP_MASK);
|
||||
/* Pre-calculate P1 output states (PE는 P0에서 OUTSET/OUTCLR로 제어) */
|
||||
uint32_t p1_all_low = saved_p1_out & ~P1_CTRL_MASK;
|
||||
uint32_t p1_P_high_N_low = p1_all_low | P_OUT_MASK;
|
||||
uint32_t p1_P_low_N_high = p1_all_low | N_OUT_MASK;
|
||||
uint32_t p1_DMP_high = p1_all_low | DMP_MASK;
|
||||
|
||||
__disable_irq();
|
||||
|
||||
/* Initialize: Set all signals to LOW */
|
||||
NRF_P1->OUT = state_all_low;
|
||||
NRF_P0->OUTCLR = PE_MASK; // PE OFF
|
||||
NRF_P1->OUT = p1_all_low;
|
||||
|
||||
/* PE rises first with margin before pulses start */
|
||||
NRF_P1->OUT = state_PE_only;
|
||||
NRF_P0->OUTSET = PE_MASK; // PE ON
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP();
|
||||
@@ -1062,21 +1401,23 @@ void dr_piezo_burst_sw_17mhz(uint8_t cycles)
|
||||
for (uint8_t i = 0; i < cycles; i++)
|
||||
{
|
||||
/* First half-period: P_OUT=HIGH, N_OUT=LOW */
|
||||
NRF_P1->OUT = state_PE_P_high_N_low;
|
||||
NRF_P1->OUT = p1_P_high_N_low;
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP();
|
||||
__NOP();
|
||||
|
||||
|
||||
/* Second half-period: P_OUT=LOW, N_OUT=HIGH */
|
||||
NRF_P1->OUT = state_PE_P_low_N_high;
|
||||
NRF_P1->OUT = p1_P_low_N_high;
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
//__NOP(); __NOP(); __NOP(); __NOP();
|
||||
}
|
||||
|
||||
/* DMP (Dump) pulse */
|
||||
NRF_P1->OUT = state_PE_DMP_high;
|
||||
NRF_P1->OUT = p1_DMP_high;
|
||||
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
@@ -1088,11 +1429,11 @@ void dr_piezo_burst_sw_17mhz(uint8_t cycles)
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
|
||||
/* DMP falls, PE remains HIGH for margin period */
|
||||
NRF_P1->OUT = state_PE_only;
|
||||
NRF_P1->OUT = p1_all_low;
|
||||
__NOP(); __NOP(); __NOP();
|
||||
|
||||
/* End of sequence: All signals return to LOW */
|
||||
NRF_P1->OUT = state_all_low;
|
||||
/* End of sequence: PE OFF */
|
||||
NRF_P0->OUTCLR = PE_MASK; // PE OFF
|
||||
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
@@ -27,23 +27,36 @@
|
||||
/*==============================================================================
|
||||
* POWER CONTROL PINS (DC/DC Converter +/-20V)
|
||||
*============================================================================*/
|
||||
#define DR_PIEZO_PWR_SHDN NRF_GPIO_PIN_MAP(0, 21) /**< SHDN_VPP/VNN (LT3463) */
|
||||
#define DR_PIEZO_PWR_EN_10V NRF_GPIO_PIN_MAP(0, 22) /**< EN_+10V (MCP1804) */
|
||||
//#define DR_PIEZO_PWR_SHDN NRF_GPIO_PIN_MAP(0, 21) /**< SHDN_VPP/VNN (LT3463) */ // P0.21 : PZT_EN_MUXA jhChun 0128
|
||||
//#define DR_PIEZO_PWR_EN_10V NRF_GPIO_PIN_MAP(0, 22) /**< EN_+10V (MCP1804) */ // P0.22 : NIRS PIN
|
||||
|
||||
#define DR_PIEZO_PWR_EN NRF_GPIO_PIN_MAP(1, 9) /** Power Enable jhChun 0128 */
|
||||
|
||||
/*==============================================================================
|
||||
* TX SIGNAL PINS (MOSFET Driver Control)
|
||||
*============================================================================*/
|
||||
#define DR_PIEZO_PIN_PE NRF_GPIO_PIN_MAP(1, 5) /**< Pulse Enable */
|
||||
#define DR_PIEZO_PIN_DMP NRF_GPIO_PIN_MAP(1, 9) /**< Dump control */
|
||||
#define DR_PIEZO_PIN_P_OUT NRF_GPIO_PIN_MAP(1, 3) /**< Positive output */
|
||||
#define DR_PIEZO_PIN_N_OUT NRF_GPIO_PIN_MAP(1, 2) /**< Negative output */
|
||||
//#define DR_PIEZO_PIN_PE NRF_GPIO_PIN_MAP(1, 5) /**< Pulse Enable */
|
||||
//#define DR_PIEZO_PIN_DMP NRF_GPIO_PIN_MAP(1, 9) /**< Dump control */
|
||||
//#define DR_PIEZO_PIN_P_OUT NRF_GPIO_PIN_MAP(1, 3) /**< Positive output */
|
||||
//#define DR_PIEZO_PIN_N_OUT NRF_GPIO_PIN_MAP(1, 2) /**< Negative output */
|
||||
|
||||
#define DR_PIEZO_PIN_PE NRF_GPIO_PIN_MAP(0, 25) /**< Pulse Enable */ // P1.05 -> P0.25
|
||||
#define DR_PIEZO_PIN_DMP NRF_GPIO_PIN_MAP(1, 0) /**< Dump control */ // P1.9 -> P1.0
|
||||
#define DR_PIEZO_PIN_P_OUT NRF_GPIO_PIN_MAP(1, 7) /**< Positive output */ // P1.3 -> P1.7
|
||||
#define DR_PIEZO_PIN_N_OUT NRF_GPIO_PIN_MAP(1, 6) /**< Negative output */ // P1.2 -> P1.6 jhChun 0128
|
||||
|
||||
/*==============================================================================
|
||||
* MUX CONTROL PINS (Echo Signal Path Selection)
|
||||
*============================================================================*/
|
||||
#define DR_PIEZO_MUX_SEL1 NRF_GPIO_PIN_MAP(1, 13) /**< MUX Select 1 (HIGH) */
|
||||
#define DR_PIEZO_MUX_SEL2 NRF_GPIO_PIN_MAP(1, 12) /**< MUX Select 2 (LOW) */
|
||||
#define DR_PIEZO_MUX_SEL3 NRF_GPIO_PIN_MAP(1, 11) /**< MUX Select 3 (LOW) */
|
||||
//#define DR_PIEZO_MUX_SEL1 NRF_GPIO_PIN_MAP(1, 13) /**< MUX Select 1 (HIGH) */
|
||||
//#define DR_PIEZO_MUX_SEL2 NRF_GPIO_PIN_MAP(1, 12) /**< MUX Select 2 (LOW) */
|
||||
//#define DR_PIEZO_MUX_SEL3 NRF_GPIO_PIN_MAP(1, 11) /**< MUX Select 3 (LOW) */
|
||||
|
||||
/* Piezo MUX pins (8ch) jhChun 0129 */
|
||||
#define DR_PIEZO_EN_MUXA NRF_GPIO_PIN_MAP(0, 21) /**< MUXA Enable */
|
||||
#define DR_PIEZO_EN_MUXB NRF_GPIO_PIN_MAP(0, 23) /**< MUXB Enable */
|
||||
#define DR_PIEZO_MUX_SEL0 NRF_GPIO_PIN_MAP(1, 10) /**< MUX Select 0 */
|
||||
#define DR_PIEZO_MUX_SEL1 NRF_GPIO_PIN_MAP(0, 28) /**< MUX Select 1 */
|
||||
|
||||
/*==============================================================================
|
||||
* CONFIGURATION
|
||||
@@ -57,6 +70,7 @@
|
||||
#define DR_PIEZO_DEFAULT_CYCLES 5 /**< Default burst cycles (3~5) */
|
||||
#define DR_PIEZO_MIN_CYCLES 3
|
||||
#define DR_PIEZO_MAX_CYCLES 10
|
||||
#define DR_PIEZO_MUX_SETTLING_US 1300 /**< MUX settling delay (us) */
|
||||
|
||||
/*==============================================================================
|
||||
* POWER CONTROL FUNCTIONS
|
||||
@@ -126,10 +140,21 @@ void dr_piezo_test_pins(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize MUX control pins for echo signal path
|
||||
* @note Sets P1.13=HIGH, P1.12=LOW, P1.11=LOW
|
||||
*/
|
||||
void dr_piezo_mux_init(void);
|
||||
|
||||
/**
|
||||
* @brief Select piezo channel (0~7) via 8ch MUX
|
||||
* @param channel Piezo channel number (0~7)
|
||||
*
|
||||
* Channel mapping (EN_MUXA, EN_MUXB, SEL0, SEL1):
|
||||
* CH0=A0(1,0,0,0) CH1=A2(1,0,1,0) CH2=A1(1,0,0,1) CH3=A3(1,0,1,1)
|
||||
* CH4=B0(0,1,1,1) CH5=B1(0,1,0,1) CH6=B2(0,1,1,0) CH7=B3(0,1,0,0)
|
||||
*
|
||||
* @note MUX settling time: 1.3ms delay after switching
|
||||
*/
|
||||
void dr_piezo_select_channel(uint8_t channel);
|
||||
|
||||
/*==============================================================================
|
||||
* SYSTEM FUNCTIONS (Power + TX combined)
|
||||
*============================================================================*/
|
||||
@@ -171,6 +196,13 @@ void dr_piezo_burst_sw_18mhz(uint8_t cycles);
|
||||
*/
|
||||
void dr_piezo_burst_sw_20mhz(uint8_t cycles);
|
||||
|
||||
/**
|
||||
* @brief Software-based burst at 2.2 MHz
|
||||
* @param cycles Number of cycles (1~20)
|
||||
* @note Fixed frequency: 2.2 MHz
|
||||
*/
|
||||
void dr_piezo_burst_sw_22mhz(uint8_t cycles);
|
||||
|
||||
/**
|
||||
* @brief Software-based burst at 1.7 MHz
|
||||
* @param cycles Number of cycles (1~20)
|
||||
@@ -178,5 +210,12 @@ void dr_piezo_burst_sw_20mhz(uint8_t cycles);
|
||||
*/
|
||||
void dr_piezo_burst_sw_17mhz(uint8_t cycles);
|
||||
|
||||
/**
|
||||
* @brief Software-based burst at 1.9 MHz
|
||||
* @param cycles Number of cycles (1~20)
|
||||
* @note Fixed frequency: 1.9 MHz
|
||||
*/
|
||||
void dr_piezo_burst_sw_19mhz(uint8_t cycles);
|
||||
|
||||
#endif /* DR_PIEZO_H */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user