Merge pull request #11494 from haslinghuis/dshot_gpio
[betaflight.git] / src / main / drivers / vtx_rtc6705_soft_spi.c
blob09e29be9085c1fca729d590f4a08dc00bba0332b
1 /*
2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
8 * any later version.
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
21 #include <stdbool.h>
22 #include <stdint.h>
24 #include "platform.h"
26 #if defined(USE_VTX_RTC6705_SOFTSPI)
28 #include "drivers/bus_spi.h"
29 #include "drivers/io.h"
30 #include "drivers/light_led.h"
31 #include "drivers/time.h"
32 #include "drivers/vtx_rtc6705.h"
35 #define DP_5G_MASK 0x7000
36 #define PA5G_BS_MASK 0x0E00
37 #define PA5G_PW_MASK 0x0180
38 #define PD_Q5G_MASK 0x0040
39 #define QI_5G_MASK 0x0038
40 #define PA_BS_MASK 0x0007
42 #define PA_CONTROL_DEFAULT 0x4FBD
44 #define RTC6705_SPICLK_ON() IOHi(rtc6705ClkPin)
45 #define RTC6705_SPICLK_OFF() IOLo(rtc6705ClkPin)
47 #define RTC6705_SPIDATA_ON() IOHi(rtc6705DataPin)
48 #define RTC6705_SPIDATA_OFF() IOLo(rtc6705DataPin)
50 #define DISABLE_RTC6705() IOHi(rtc6705CsnPin)
51 #define ENABLE_RTC6705() IOLo(rtc6705CsnPin)
53 static IO_t rtc6705DataPin = IO_NONE;
54 static IO_t rtc6705CsnPin = IO_NONE;
55 static IO_t rtc6705ClkPin = IO_NONE;
58 bool rtc6705SoftSpiIOInit(const vtxIOConfig_t *vtxIOConfig, const IO_t csnPin)
60 rtc6705CsnPin = csnPin;
62 rtc6705DataPin = IOGetByTag(vtxIOConfig->dataTag);
63 rtc6705ClkPin = IOGetByTag(vtxIOConfig->clockTag);
65 if (!(rtc6705DataPin && rtc6705ClkPin)) {
66 return false;
69 IOInit(rtc6705DataPin, OWNER_VTX_DATA, RESOURCE_SOFT_OFFSET);
70 IOConfigGPIO(rtc6705DataPin, IOCFG_OUT_PP);
72 IOInit(rtc6705ClkPin, OWNER_VTX_CLK, RESOURCE_SOFT_OFFSET);
73 IOConfigGPIO(rtc6705ClkPin, IOCFG_OUT_PP);
75 // Important: The order of GPIO configuration calls are critical to ensure that incorrect signals are not briefly sent to the VTX.
76 // GPIO bit is enabled so here so the CS/LE pin output is not pulled low when the GPIO is set in output mode.
77 DISABLE_RTC6705();
78 IOInit(rtc6705CsnPin, OWNER_VTX_CS, RESOURCE_SOFT_OFFSET);
79 IOConfigGPIO(rtc6705CsnPin, IOCFG_OUT_PP);
81 return true;
84 static void rtc6705_write_register(uint8_t addr, uint32_t data)
86 ENABLE_RTC6705();
87 delay(1);
88 // send address
89 for (int i = 0; i < 4; i++) {
90 if ((addr >> i) & 1) {
91 RTC6705_SPIDATA_ON();
92 } else {
93 RTC6705_SPIDATA_OFF();
96 RTC6705_SPICLK_ON();
97 delay(1);
98 RTC6705_SPICLK_OFF();
99 delay(1);
101 // Write bit
102 RTC6705_SPIDATA_ON();
103 RTC6705_SPICLK_ON();
104 delay(1);
105 RTC6705_SPICLK_OFF();
106 delay(1);
107 for (int i = 0; i < 20; i++) {
108 if ((data >> i) & 1) {
109 RTC6705_SPIDATA_ON();
110 } else {
111 RTC6705_SPIDATA_OFF();
113 RTC6705_SPICLK_ON();
114 delay(1);
115 RTC6705_SPICLK_OFF();
116 delay(1);
118 DISABLE_RTC6705();
121 void rtc6705SoftSpiSetFrequency(uint16_t channel_freq)
123 uint32_t freq = (uint32_t)channel_freq * 1000;
124 freq /= 40;
125 const uint32_t N = freq / 64;
126 const uint32_t A = freq % 64;
127 rtc6705_write_register(0, 400);
128 rtc6705_write_register(1, (N << 7) | A);
131 void rtc6705SoftSpiSetRFPower(uint8_t rf_power)
133 rtc6705_write_register(7, (rf_power > 1 ? PA_CONTROL_DEFAULT : (PA_CONTROL_DEFAULT | PD_Q5G_MASK) & (~(PA5G_PW_MASK | PA5G_BS_MASK))));
135 #endif