switch to DigitalSequence

This commit is contained in:
g3gg0
2022-11-21 13:36:16 +01:00
parent f0feb8921f
commit cd241a2901
4 changed files with 60 additions and 274 deletions
+36 -28
View File
@@ -22,6 +22,7 @@ DigitalSignal* digital_signal_alloc(uint32_t max_edges_cnt) {
signal->edge_cnt = 0;
signal->reload_reg_buff = malloc(signal->edges_max_cnt * sizeof(uint32_t));
signal->reload_reg_entries = 0;
signal->reload_reg_remainder = 0;
return signal;
}
@@ -98,10 +99,6 @@ uint32_t digital_signal_get_edge(DigitalSignal* signal, uint32_t edge_num) {
void digital_signal_prepare(DigitalSignal* signal) {
furi_assert(signal);
if(signal->prepared) {
return;
}
/* set up signal polarities */
uint32_t bit_set = signal->gpio->pin;
uint32_t bit_reset = signal->gpio->pin << 16;
@@ -115,20 +112,30 @@ void digital_signal_prepare(DigitalSignal* signal) {
}
/* set up edge timings */
uint32_t remainder = 0;
signal->reload_reg_entries = 0;
for(size_t pos = 0; pos < signal->edge_cnt; pos++) {
uint32_t pulse_duration = signal->edge_timings[pos] + remainder;
uint32_t pulse_duration = signal->edge_timings[pos] + signal->reload_reg_remainder;
uint32_t pulse_ticks = (pulse_duration + T_TIM_DIV2) / T_TIM;
remainder = pulse_duration - (pulse_ticks * T_TIM);
signal->reload_reg_remainder = pulse_duration - (pulse_ticks * T_TIM);
if(pulse_ticks > 1) {
signal->reload_reg_buff[signal->reload_reg_entries++] = pulse_ticks - 1;
}
}
}
signal->prepared = true;
void digital_signal_stop_dma() {
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_ClearFlag_TC1(DMA1);
LL_DMA_ClearFlag_TC2(DMA1);
}
void digital_signal_stop_timer() {
LL_TIM_DisableCounter(TIM2);
LL_TIM_SetCounter(TIM2, 0);
}
bool digital_signal_setup_dma(DigitalSignal* signal) {
@@ -166,6 +173,8 @@ bool digital_signal_setup_dma(DigitalSignal* signal) {
dma_config_timer.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP;
dma_config_timer.Priority = LL_DMA_PRIORITY_HIGH;
digital_signal_stop_dma();
/* set up DMA channel 1 and 2 for GPIO and timer copy operations */
LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config_gpio);
LL_DMA_Init(DMA1, LL_DMA_CHANNEL_2, &dma_config_timer);
@@ -178,13 +187,14 @@ bool digital_signal_setup_dma(DigitalSignal* signal) {
}
void digital_signal_update_dma(DigitalSignal* signal) {
bool digital_signal_update_dma(DigitalSignal* signal) {
furi_assert(signal);
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_ClearFlag_TC1(DMA1);
LL_DMA_ClearFlag_TC2(DMA1);
if(!signal->reload_reg_entries) {
return false;
}
digital_signal_stop_dma();
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_1, (uint32_t)signal->gpio_buff);
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_2, (uint32_t)signal->reload_reg_buff);
@@ -193,18 +203,8 @@ void digital_signal_update_dma(DigitalSignal* signal) {
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2);
}
void digital_signal_stop_dma() {
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_ClearFlag_TC1(DMA1);
LL_DMA_ClearFlag_TC2(DMA1);
}
void digital_signal_stop_timer() {
LL_TIM_DisableCounter(TIM2);
LL_TIM_SetCounter(TIM2, 0);
return true;
}
void digital_signal_setup_timer() {
@@ -231,7 +231,6 @@ void digital_signal_send(DigitalSignal* signal, const GpioPin* gpio) {
/* if selected GPIO changed, force reconfiguration of buffers */
if(gpio && (signal->gpio != gpio)) {
signal->gpio = gpio;
signal->prepared = false;
}
/* Configure gpio as output */
@@ -303,7 +302,7 @@ void digital_sequence_add(DigitalSequence* sequence, uint8_t signal_index) {
bool digital_sequence_send_signal(DigitalSignal* signal) {
furi_assert(signal);
/* the first iteration has to set up the whol machinery */
/* the first iteration has to set up the whole machinery */
if(!LL_DMA_IsEnabledChannel(DMA1, LL_DMA_CHANNEL_1)) {
furi_hal_gpio_init(signal->gpio, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
@@ -314,12 +313,15 @@ bool digital_sequence_send_signal(DigitalSignal* signal) {
digital_signal_setup_timer();
digital_signal_start_timer();
} else {
/* it was already active, wait till DMA is done and the last timer ticks are running */
/* transfer was already active, wait till DMA is done and the last timer ticks are running */
while(!LL_DMA_IsActiveFlag_TC2(DMA1)) {
}
/* configure next polarities and timings */
digital_signal_update_dma(signal);
if(!digital_signal_update_dma(signal)) {
FURI_LOG_D(TAG, "Signal has no entries, aborting");
return false;
}
}
return true;
@@ -328,9 +330,15 @@ bool digital_sequence_send_signal(DigitalSignal* signal) {
bool digital_sequence_send(DigitalSequence* sequence) {
furi_assert(sequence);
uint32_t remainder = 0;
for(uint32_t pos = 0; pos < sequence->sequence_used; pos++) {
DigitalSignal *sig = sequence->signals[sequence->sequence[pos]];
/* take over previous remainder */
sig->reload_reg_remainder = remainder;
digital_signal_prepare(sig);
if(!digital_sequence_send_signal(sig)) {
digital_signal_stop_timer();
digital_signal_stop_dma();
+1
View File
@@ -24,6 +24,7 @@ typedef struct {
uint32_t* edge_timings;
uint32_t* reload_reg_buff;
uint32_t reload_reg_entries;
uint32_t reload_reg_remainder;
uint32_t gpio_buff[2];
const GpioPin* gpio;
} DigitalSignal;
+20 -29
View File
@@ -161,6 +161,11 @@ DigitalSignal* nfcv_resp_eof = NULL;
DigitalSignal* nfcv_resp_unmod_256 = NULL;
DigitalSignal* nfcv_resp_unmod_768 = NULL;
//DigitalSignal* nfcv_signal = NULL;
//const GpioPin* nfcv_out_io = &gpio_ext_pb2;
const GpioPin* nfcv_out_io = &gpio_spi_r_mosi;
DigitalSequence* nfcv_signal = NULL;
#define SIG_SOF 0
@@ -192,6 +197,7 @@ void nfcv_crc(uint8_t* data, uint32_t length, uint8_t* out) {
}
void nfcv_emu_free() {
//digital_signal_free(nfcv_signal);
digital_sequence_free(nfcv_signal);
digital_signal_free(nfcv_resp_unmod_256);
digital_signal_free(nfcv_resp_pulse_32);
@@ -212,8 +218,9 @@ void nfcv_emu_free() {
void nfcv_emu_alloc() {
if(!nfcv_signal) {
//nfcv_signal = digital_signal_alloc(8192);
/* assuming max frame length is 255 bytes */
nfcv_signal = digital_sequence_alloc(8 * 255 + 2, &gpio_spi_r_mosi);
nfcv_signal = digital_sequence_alloc(8 * 255 + 2, nfcv_out_io);
}
if(!nfcv_resp_unmod_256) {
@@ -283,12 +290,11 @@ void nfcv_emu_send_raw(uint8_t* data, uint8_t length) {
int bits = length * 8;
furi_hal_gpio_write(&gpio_spi_r_mosi, false);
furi_delay_us(10);
furi_hal_gpio_write(&gpio_spi_r_mosi, true);
furi_delay_us(10);
furi_hal_gpio_write(&gpio_spi_r_mosi, false);
//nfcv_signal->start_level = false;
//nfcv_signal->edge_cnt = 0;
//digital_signal_append(nfcv_signal, nfcv_resp_sof);
digital_sequence_clear(nfcv_signal);
digital_sequence_add(nfcv_signal, SIG_SOF);
@@ -297,26 +303,17 @@ void nfcv_emu_send_raw(uint8_t* data, uint8_t length) {
uint32_t bit_pos = bit_total % 8;
uint8_t bit_val = 0x01 << bit_pos;
if(data[byte_pos] & bit_val) {
digital_sequence_add(nfcv_signal, SIG_BIT1);
} else {
digital_sequence_add(nfcv_signal, SIG_BIT0);
}
//digital_signal_append(nfcv_signal, nfcv_resp_one);
digital_sequence_add(nfcv_signal, (data[byte_pos] & bit_val) ? SIG_BIT1 : SIG_BIT0);
}
//digital_signal_append(nfcv_signal, nfcv_resp_eof);
digital_sequence_add(nfcv_signal, SIG_EOF);
/* digital signal setup will take some time. win some time by tricking the VCD into thinking that something happens */
furi_hal_gpio_write(&gpio_spi_r_mosi, false);
furi_delay_us(10);
furi_hal_gpio_write(&gpio_spi_r_mosi, true);
furi_delay_us(10);
furi_hal_gpio_write(&gpio_spi_r_mosi, false);
FURI_CRITICAL_ENTER();
//digital_signal_send(nfcv_signal, nfcv_out_io);
digital_sequence_send(nfcv_signal);
FURI_CRITICAL_EXIT();
furi_hal_gpio_write(&gpio_spi_r_mosi, false);
furi_hal_gpio_write(nfcv_out_io, false);
}
void nfcv_emu_send(uint8_t* data, uint8_t length) {
@@ -579,7 +576,7 @@ void nfcv_emu_handle_packet(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, ui
}
if(strlen(nfcv_data->last_command) > 0) {
//FURI_LOG_D(TAG, "Received command %s", nfcv_data->last_command);
FURI_LOG_D(TAG, "Received command %s", nfcv_data->last_command);
}
}
@@ -594,7 +591,6 @@ void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) {
furi_hal_spi_bus_handle_deinit(&furi_hal_spi_bus_handle_nfc);
FURI_LOG_D(TAG, "Starting NfcV emulation");
FURI_LOG_D(TAG, " UID: %02X %02X %02X %02X %02X %02X %02X %02X",
nfc_data->uid[0], nfc_data->uid[1], nfc_data->uid[2], nfc_data->uid[3],
@@ -676,7 +672,6 @@ bool nfcv_emu_loop(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, uint32_t ti
break;
case NFCV_FRAME_STATE_CODING_256:
if(periods_previous > periods) {
snprintf(reset_reason, sizeof(reset_reason), "1oo256: Missing %lu periods from previous symbol, got %lu", periods_previous, periods);
frame_state = NFCV_FRAME_STATE_RESET;
@@ -758,13 +753,9 @@ bool nfcv_emu_loop(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data, uint32_t ti
}
if(frame_state == NFCV_FRAME_STATE_EOF) {
FURI_LOG_D(TAG, "Received valid frame");
/* we know that this code uses TIM2, so stop pulse reader */
furi_hal_gpio_write(&gpio_spi_r_mosi, false);
furi_delay_us(10);
furi_hal_gpio_write(&gpio_spi_r_mosi, true);
furi_delay_us(10);
furi_hal_gpio_write(&gpio_spi_r_mosi, false);
pulse_reader_stop(reader_signal);
nfcv_emu_handle_packet(nfc_data, nfcv_data, frame_payload, frame_pos);
pulse_reader_start(reader_signal);