From aefe492f9b9e1f9a6260b68dcfa6220e953d93c0 Mon Sep 17 00:00:00 2001 From: danilo Date: Fri, 31 Mar 2017 19:14:17 +0200 Subject: [PATCH] Working baseline, works with -O0 -- -O3 AND -O0 with gcc 4.9.3 Ubuntu. TX to RX switch timing is the challenge. IOArduino.cpp may not work --- ADF7021.cpp | 4 +-- IO.cpp | 60 +++++++++++++++++++++---------------- IOArduino.cpp | 16 ++++++---- IOSTM.cpp | 83 +++++++++++++++++++++++++++++++-------------------- Makefile | 8 +++-- 5 files changed, 102 insertions(+), 69 deletions(-) diff --git a/ADF7021.cpp b/ADF7021.cpp index 6e440c5..f804fc0 100644 --- a/ADF7021.cpp +++ b/ADF7021.cpp @@ -374,6 +374,7 @@ void CIO::ifConf(MMDVM_STATE modemState, bool reset) // Delay for coarse IF filter calibration delay_rx(); delay_rx(); + delay_rx(); // Frequency RX (0) setRX(); @@ -429,9 +430,6 @@ void CIO::setTX() //====================================================================================================================== void CIO::setRX() { - // Delay for TX latency - delay_rx(); - // Send register 0 for RX operation AD7021_control_word = ADF7021_RX_REG0; Send_AD7021_control(); diff --git a/IO.cpp b/IO.cpp index 9524aec..f768900 100644 --- a/IO.cpp +++ b/IO.cpp @@ -30,7 +30,8 @@ uint32_t m_frequency_tx; uint8_t m_power; extern volatile bool sle_request; -static volatile bool sle_pin = 0; +volatile bool torx_request = false; +bool volatile even = true; CIO::CIO(): m_started(false), @@ -100,8 +101,10 @@ void CIO::process() // Switch off the transmitter if needed if (m_txBuffer.getData() == 0U && m_tx) { - setRX(); - m_tx = false; + //while(CLK_pin()==0) { asm volatile ("nop"); } + //while(CLK_pin()) { asm volatile ("nop"); } + torx_request = true; + while(torx_request) { asm volatile ("nop"); } } if(m_modemState_prev == STATE_DSTAR) @@ -155,26 +158,12 @@ void CIO::interrupt() if (!m_started) return; - if (sle_request == true && m_tx) - { - if(CLK_pin() == 0) - { - sle_pin = 1; - SLE_pin(HIGH); - } - else if (sle_pin == 1) - { - SLE_pin(LOW); - SDATA_pin(LOW); - sle_request = false; - sle_pin = 0; - } - } - - + uint8_t clk = CLK_pin(); // we set the TX bit at TXD low, sampling of ADF7021 happens at rising clock - if (CLK_pin() == 0 && m_tx ) { + if (m_tx && clk == 0) { + m_txBuffer.get(bit); + even = !even; #if defined(BIDIR_DATA_PIN) if(bit) @@ -187,9 +176,26 @@ void CIO::interrupt() else TXD_pin(LOW); #endif - } + // wait a brief period before raising SLE + if (sle_request == true) { +#if 1 + asm volatile("mov r8, r8 \n\t" + "mov r8, r8 \n\t" + "mov r8, r8 \n\t" + ); +#endif + SLE_pin(HIGH); + asm volatile("mov r8, r8 \n\t" + "mov r8, r8 \n\t" + "mov r8, r8 \n\t" + ); + SLE_pin(LOW); + SDATA_pin(LOW); + sle_request = false; + } + } // we sample the RX bit at rising TXD clock edge, so TXD must be 1 and we are not in tx mode - else if (CLK_pin() == 1 && !m_tx) { + if (!m_tx && clk == 1) { if(RXD_pin()) bit = 1; else @@ -197,6 +203,11 @@ void CIO::interrupt() m_rxBuffer.put(bit); } + if (torx_request == true && even == true && m_tx && clk == 0) { + setRX(); + m_tx = false; + torx_request = false; + } m_watchdog++; @@ -263,9 +274,8 @@ void CIO::write(uint8_t* data, uint16_t length) // Switch the transmitter on if needed if (!m_tx) { setTX(); + while(CLK_pin()); m_tx = true; - sle_pin = 0; - while (sle_request) { asm("nop"); } } } diff --git a/IOArduino.cpp b/IOArduino.cpp index c891bc5..b9666d0 100644 --- a/IOArduino.cpp +++ b/IOArduino.cpp @@ -124,11 +124,6 @@ void CIO::delay_rx() { #endif } -void CIO::dlybit(void) -{ - delayMicroseconds(1); -} - void CIO::Init() { #if defined (__STM32F1__) @@ -289,4 +284,15 @@ void CIO::COS_pin(bool on) digitalWrite(PIN_COS_LED, on ? HIGH : LOW); } +// TODO: Investigate why. In fact there is just a single place where this is being use +// during normal operation +#pragma GCC optimize ("O0") +void CIO::dlybit(void) +{ + asm volatile("nop \n\t" + "nop \n\t" + "nop \n\t" + ); +} + #endif diff --git a/IOSTM.cpp b/IOSTM.cpp index b66fa76..467d0cc 100644 --- a/IOSTM.cpp +++ b/IOSTM.cpp @@ -17,6 +17,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + #include "Config.h" #if defined(STM32F10X_MD) @@ -239,39 +240,6 @@ extern "C" { #endif } -/** - * Function delay_us() from stm32duino project - * - * @brief Delay the given number of microseconds. - * - * @param us Number of microseconds to delay. - */ -static inline void delay_us(uint32_t us) { - us *= 12; - - /* fudge for function call overhead */ - us--; - asm volatile(" mov r0, %[us] \n\t" - "1: subs r0, #1 \n\t" - " bhi 1b \n\t" - : - : [us] "r" (us) - : "r0"); -} - -void CIO::delay_rx() { -#if defined(BIDIR_DATA_PIN) - delay_us(290); -#else - delay_us(340); -#endif -} - -void CIO::dlybit(void) -{ - delay_us(1); -} - void CIO::Init() { // USB Conf IO: @@ -532,6 +500,8 @@ bool CIO::CLK_pin() void CIO::RXD_pin_write(bool on) { GPIO_WriteBit(PORT_RXD, PIN_RXD, on ? Bit_SET : Bit_RESET); + GPIO_WriteBit(PORT_YSF_LED, PIN_YSF_LED, on ? Bit_SET : Bit_RESET); + GPIO_WriteBit(PORT_YSF_LED, PIN_YSF_LED, on ? Bit_SET : Bit_RESET); } #endif @@ -580,4 +550,51 @@ void CIO::COS_pin(bool on) GPIO_WriteBit(PORT_COS_LED, PIN_COS_LED, on ? Bit_SET : Bit_RESET); } + +/** + * Function delay_us() from stm32duino project + * + * @brief Delay the given number of microseconds. + * + * @param us Number of microseconds to delay. + */ +static inline void delay_us(uint32_t us) { + us *= 12; + + /* fudge for function call overhead */ + us--; + asm volatile(" mov r0, %[us] \n\t" + "1: subs r0, #1 \n\t" + " bhi 1b \n\t" + : + : [us] "r" (us) + : "r0"); +} + +void CIO::delay_rx() { +#if defined(BIDIR_DATA_PIN) + delay_us(290); +#else + delay_us(340); +#endif +} + + +// TODO: Investigate why. In fact there is just a single place where this is being use +// during normal operation +// it seems that optimizing this code breaks some timings +#pragma GCC optimize ("O0") +static inline void delay_ns() { + + asm volatile("mov r8, r8 \n\t" + "mov r8, r8 \n\t" + "mov r8, r8 \n\t" + ); +} + + +void CIO::dlybit(void) +{ + delay_ns(); +} #endif diff --git a/Makefile b/Makefile index 19dc929..fbab264 100644 --- a/Makefile +++ b/Makefile @@ -30,6 +30,8 @@ A2L=arm-none-eabi-addr2line # Directory Structure BINDIR=bin +OPTFLAG=-Os + # Configure vars depending on OS ifeq ($(OS),Windows_NT) ASOURCES=$(shell dir /S /B *.s) @@ -116,9 +118,9 @@ LDFLAGS=$(MCFLAGS) --specs=nosys.specs $(INCLUDES_LIBS) $(LINK_LIBS) all: hs -hs: CFLAGS+=$(DEFS_HS) -Os -ffunction-sections -fdata-sections -nostdlib -hs: CXXFLAGS+=$(DEFS_HS) -Os -fno-exceptions -ffunction-sections -fdata-sections -nostdlib -fno-rtti -hs: LDFLAGS+=-T $(LDSCRIPT_N) -Os --specs=nano.specs +hs: CFLAGS+=$(DEFS_HS) $(OPTFLAG) -ffunction-sections -fdata-sections -nostdlib +hs: CXXFLAGS+=$(DEFS_HS) $(OPTFLAG) -fno-exceptions -ffunction-sections -fdata-sections -nostdlib -fno-rtti +hs: LDFLAGS+=-T $(LDSCRIPT_N) $(OPTFLAG) --specs=nano.specs hs: release bl: CFLAGS+=$(DEFS_HS_BL) -Os -ffunction-sections -fdata-sections -nostdlib