Englebert
3 years ago
5 changed files with 1047 additions and 15 deletions
-
648BertFPVDiversity.ino
-
238SoftSPI.cpp
-
69SoftSPI.h
-
82rx5808.cpp
-
25rx5808.h
@ -0,0 +1,238 @@ |
|||||
|
/*
|
||||
|
* Copyright (c) 2014, Majenko Technologies |
||||
|
* All rights reserved. |
||||
|
* |
||||
|
* Redistribution and use in source and binary forms, with or without modification, |
||||
|
* are permitted provided that the following conditions are met: |
||||
|
* |
||||
|
* 1. Redistributions of source code must retain the above copyright notice, |
||||
|
* this list of conditions and the following disclaimer. |
||||
|
* |
||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, |
||||
|
* this list of conditions and the following disclaimer in the documentation |
||||
|
* and/or other materials provided with the distribution. |
||||
|
* |
||||
|
* 3. Neither the name of Majenko Technologies nor the names of its contributors may be used |
||||
|
* to endorse or promote products derived from this software without |
||||
|
* specific prior written permission. |
||||
|
* |
||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
#include "SoftSPI.h"
|
||||
|
|
||||
|
SoftSPI::SoftSPI(uint8_t mosi, uint8_t miso, uint8_t sck) { |
||||
|
_mosi = mosi; |
||||
|
_miso = miso; |
||||
|
_sck = sck; |
||||
|
_delay = 2; |
||||
|
_cke = 0; |
||||
|
_ckp = 0; |
||||
|
_order = MSBFIRST; |
||||
|
} |
||||
|
|
||||
|
void SoftSPI::begin() { |
||||
|
pinMode(_mosi, OUTPUT); |
||||
|
pinMode(_miso, INPUT); |
||||
|
pinMode(_sck, OUTPUT); |
||||
|
} |
||||
|
|
||||
|
void SoftSPI::end() { |
||||
|
pinMode(_mosi, INPUT); |
||||
|
pinMode(_miso, INPUT); |
||||
|
pinMode(_sck, INPUT); |
||||
|
} |
||||
|
|
||||
|
void SoftSPI::setBitOrder(uint8_t order) { |
||||
|
_order = order & 1; |
||||
|
} |
||||
|
|
||||
|
void SoftSPI::setDataMode(uint8_t mode) { |
||||
|
switch (mode) { |
||||
|
case SPI_MODE0: |
||||
|
_ckp = 0; |
||||
|
_cke = 0; |
||||
|
break; |
||||
|
case SPI_MODE1: |
||||
|
_ckp = 0; |
||||
|
_cke = 1; |
||||
|
break; |
||||
|
case SPI_MODE2: |
||||
|
_ckp = 1; |
||||
|
_cke = 0; |
||||
|
break; |
||||
|
case SPI_MODE3: |
||||
|
_ckp = 1; |
||||
|
_cke = 1; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
digitalWrite(_sck, _ckp ? HIGH : LOW); |
||||
|
} |
||||
|
|
||||
|
void SoftSPI::setClockDivider(uint8_t div) { |
||||
|
switch (div) { |
||||
|
case SPI_CLOCK_DIV2: |
||||
|
_delay = 2; |
||||
|
break; |
||||
|
case SPI_CLOCK_DIV4: |
||||
|
_delay = 4; |
||||
|
break; |
||||
|
case SPI_CLOCK_DIV8: |
||||
|
_delay = 8; |
||||
|
break; |
||||
|
case SPI_CLOCK_DIV16: |
||||
|
_delay = 16; |
||||
|
break; |
||||
|
case SPI_CLOCK_DIV32: |
||||
|
_delay = 32; |
||||
|
break; |
||||
|
case SPI_CLOCK_DIV64: |
||||
|
_delay = 64; |
||||
|
break; |
||||
|
case SPI_CLOCK_DIV128: |
||||
|
_delay = 128; |
||||
|
break; |
||||
|
default: |
||||
|
_delay = 128; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void SoftSPI::wait(uint_fast8_t del) { |
||||
|
for (uint_fast8_t i = 0; i < del; i++) { |
||||
|
asm volatile("nop"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
uint32_t SoftSPI::transfer32(uint32_t data, uint8_t data_length) { |
||||
|
uint8_t out = 0; |
||||
|
uint8_t del = _delay >> 1; |
||||
|
uint8_t bval = 0; |
||||
|
int sck = (_ckp) ? HIGH : LOW; |
||||
|
|
||||
|
for(uint8_t bit = 0; bit < data_length; bit++) { |
||||
|
// uint8_t sector = data >> (i * 8) & 0xFF;
|
||||
|
// RX5808_SPI1.transfer(sector);
|
||||
|
if (_cke) { |
||||
|
sck ^= 1; |
||||
|
digitalWrite(_sck, sck); |
||||
|
wait(del); |
||||
|
} |
||||
|
|
||||
|
/* ... Write bit */ |
||||
|
digitalWrite(_mosi, ((data >> bit) & 0x01) ? HIGH : LOW); |
||||
|
|
||||
|
wait(del); |
||||
|
|
||||
|
sck ^= 1u; digitalWrite(_sck, sck); |
||||
|
|
||||
|
wait(del); |
||||
|
|
||||
|
if (!_cke) { |
||||
|
sck ^= 1u; |
||||
|
digitalWrite(_sck, sck); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
uint8_t SoftSPI::transfer(uint8_t val) { |
||||
|
uint8_t out = 0; |
||||
|
if (_order == MSBFIRST) { |
||||
|
uint8_t v2 = |
||||
|
((val & 0x01) << 7) | |
||||
|
((val & 0x02) << 5) | |
||||
|
((val & 0x04) << 3) | |
||||
|
((val & 0x08) << 1) | |
||||
|
((val & 0x10) >> 1) | |
||||
|
((val & 0x20) >> 3) | |
||||
|
((val & 0x40) >> 5) | |
||||
|
((val & 0x80) >> 7); |
||||
|
val = v2; |
||||
|
} |
||||
|
|
||||
|
uint8_t del = _delay >> 1; |
||||
|
|
||||
|
uint8_t bval = 0; |
||||
|
/*
|
||||
|
* CPOL := 0, CPHA := 0 => INIT = 0, PRE = Z|0, MID = 1, POST = 0 |
||||
|
* CPOL := 1, CPHA := 0 => INIT = 1, PRE = Z|1, MID = 0, POST = 1 |
||||
|
* CPOL := 0, CPHA := 1 => INIT = 0, PRE = 1 , MID = 0, POST = Z|0 |
||||
|
* CPOL := 1, CPHA := 1 => INIT = 1, PRE = 0 , MID = 1, POST = Z|1 |
||||
|
*/ |
||||
|
|
||||
|
int sck = (_ckp) ? HIGH : LOW; |
||||
|
|
||||
|
for (uint8_t bit = 0u; bit < 8u; bit++) |
||||
|
{ |
||||
|
if (_cke) { |
||||
|
sck ^= 1; |
||||
|
digitalWrite(_sck, sck); |
||||
|
wait(del); |
||||
|
} |
||||
|
|
||||
|
/* ... Write bit */ |
||||
|
digitalWrite(_mosi, ((val & (1<<bit)) ? HIGH : LOW)); |
||||
|
|
||||
|
wait(del); |
||||
|
|
||||
|
sck ^= 1u; digitalWrite(_sck, sck); |
||||
|
|
||||
|
/* ... Read bit */ |
||||
|
{ |
||||
|
bval = digitalRead(_miso); |
||||
|
|
||||
|
if (_order == MSBFIRST) { |
||||
|
out <<= 1; |
||||
|
out |= bval; |
||||
|
} else { |
||||
|
out >>= 1; |
||||
|
out |= bval << 7; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
wait(del); |
||||
|
|
||||
|
if (!_cke) { |
||||
|
sck ^= 1u; |
||||
|
digitalWrite(_sck, sck); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return out; |
||||
|
} |
||||
|
|
||||
|
uint16_t SoftSPI::transfer16(uint16_t data) |
||||
|
{ |
||||
|
union { |
||||
|
uint16_t val; |
||||
|
struct { |
||||
|
uint8_t lsb; |
||||
|
uint8_t msb; |
||||
|
}; |
||||
|
} in, out; |
||||
|
|
||||
|
in.val = data; |
||||
|
|
||||
|
if ( _order == MSBFIRST ) { |
||||
|
out.msb = transfer(in.msb); |
||||
|
out.lsb = transfer(in.lsb); |
||||
|
} else { |
||||
|
out.lsb = transfer(in.lsb); |
||||
|
out.msb = transfer(in.msb); |
||||
|
} |
||||
|
|
||||
|
return out.val; |
||||
|
} |
@ -0,0 +1,69 @@ |
|||||
|
/* |
||||
|
* Copyright (c) 2014, Majenko Technologies |
||||
|
* All rights reserved. |
||||
|
* |
||||
|
* Redistribution and use in source and binary forms, with or without modification, |
||||
|
* are permitted provided that the following conditions are met: |
||||
|
* |
||||
|
* 1. Redistributions of source code must retain the above copyright notice, |
||||
|
* this list of conditions and the following disclaimer. |
||||
|
* |
||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, |
||||
|
* this list of conditions and the following disclaimer in the documentation |
||||
|
* and/or other materials provided with the distribution. |
||||
|
* |
||||
|
* 3. Neither the name of Majenko Technologies nor the names of its contributors may be used |
||||
|
* to endorse or promote products derived from this software without |
||||
|
* specific prior written permission. |
||||
|
* |
||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
*/ |
||||
|
|
||||
|
|
||||
|
#ifndef _SOFTSPI_H |
||||
|
#define _SOFTSPI_H |
||||
|
|
||||
|
#if (ARDUINO >= 100) |
||||
|
# include <Arduino.h> |
||||
|
#else |
||||
|
# include <WProgram.h> |
||||
|
#endif |
||||
|
|
||||
|
#include <SPI.h> |
||||
|
|
||||
|
class SoftSPI : public SPIClass { |
||||
|
private: |
||||
|
void wait(uint_fast8_t del); |
||||
|
|
||||
|
private: |
||||
|
uint8_t _cke; |
||||
|
uint8_t _ckp; |
||||
|
uint8_t _delay; |
||||
|
uint8_t _miso; |
||||
|
uint8_t _mosi; |
||||
|
uint8_t _sck; |
||||
|
uint8_t _order; |
||||
|
|
||||
|
public: |
||||
|
SoftSPI(uint8_t mosi, uint8_t miso, uint8_t sck); |
||||
|
void begin(); |
||||
|
void end(); |
||||
|
void setBitOrder(uint8_t); |
||||
|
void setDataMode(uint8_t); |
||||
|
void setClockDivider(uint8_t); |
||||
|
uint8_t transfer(uint8_t); |
||||
|
uint16_t transfer16(uint16_t data); |
||||
|
// Added for RX5808 Software SPI |
||||
|
uint32_t transfer32(uint32_t data, uint8_t data_length); |
||||
|
|
||||
|
}; |
||||
|
#endif |
@ -0,0 +1,82 @@ |
|||||
|
#include "rx5808.h"
|
||||
|
#include <SPI.h>
|
||||
|
#include "SoftSPI.h"
|
||||
|
|
||||
|
#define SPI_ADDRESS_SYNTH_B 0x01
|
||||
|
#define SPI_ADDRESS_POWER 0x0A
|
||||
|
#define SPI_ADDRESS_STATE 0x0F
|
||||
|
#define PIN_SPI_RX_A 18
|
||||
|
#define PIN_SPI_RX_B 16
|
||||
|
|
||||
|
static inline void sendRegister(uint8_t address, uint32_t data); |
||||
|
|
||||
|
// Create new SPI port for RX5808_SPI1
|
||||
|
// D5: (CH1) MOSI
|
||||
|
// D12: MISO (using an unused pin)
|
||||
|
// D18: (CH2) CS
|
||||
|
// D19: (CH3) SCK
|
||||
|
SoftSPI RX5808_SPI1(5, 34, 19); |
||||
|
|
||||
|
// D4: (CH1) MOSI
|
||||
|
// D13: MISO (using an unused pin)
|
||||
|
// D16: (CH2) CS
|
||||
|
// D17: (CH3) SCK
|
||||
|
SoftSPI RX5808_SPI2(4, 35, 17); |
||||
|
|
||||
|
// TODO: COntinue to set address to power down the SPI
|
||||
|
namespace RX5808 { |
||||
|
|
||||
|
void begin() { |
||||
|
RX5808_SPI1.begin(); |
||||
|
RX5808_SPI2.begin(); |
||||
|
} |
||||
|
|
||||
|
void setSynthRegisterB(uint16_t value) { |
||||
|
sendRegister(SPI_ADDRESS_SYNTH_B, value); |
||||
|
} |
||||
|
|
||||
|
void setPowerDownRegister(uint32_t value) { |
||||
|
sendRegister(SPI_ADDRESS_POWER, value); |
||||
|
} |
||||
|
|
||||
|
void setStateRegister(uint32_t value) { |
||||
|
sendRegister(SPI_ADDRESS_STATE, value); |
||||
|
} |
||||
|
|
||||
|
void rxStandby(uint8_t receiver_id) { |
||||
|
sendRegister(SPI_ADDRESS_STATE, 0b00000000000000000010); |
||||
|
// sendCommand(0b00000000000000000010);
|
||||
|
} |
||||
|
|
||||
|
void rxPowerOn(uint8_t receiver_id) { |
||||
|
sendRegister(SPI_ADDRESS_STATE, 0b00000000000000000001); |
||||
|
// sendCommand(0b00000000000000000001);
|
||||
|
} |
||||
|
|
||||
|
void rxReset(uint8_t receiver_id) { |
||||
|
sendRegister(SPI_ADDRESS_STATE, 0b00000000000000000000); |
||||
|
// sendCommand(0b00000000000000000000);
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static inline void sendRegister(uint8_t addressBits, uint32_t dataBits) { |
||||
|
uint32_t data = addressBits | (1 << 4) | (dataBits << 5); |
||||
|
|
||||
|
RX5808_SPI1.setDataMode(SPI_MODE0); |
||||
|
RX5808_SPI1.setBitOrder(LSBFIRST); |
||||
|
RX5808_SPI1.setClockDivider(SPI_CLOCK_DIV8); |
||||
|
digitalWrite(PIN_SPI_RX_A, LOW); |
||||
|
RX5808_SPI1.transfer32(data, 25); |
||||
|
digitalWrite(PIN_SPI_RX_A, HIGH); |
||||
|
|
||||
|
RX5808_SPI2.setDataMode(SPI_MODE0); |
||||
|
RX5808_SPI2.setBitOrder(LSBFIRST); |
||||
|
RX5808_SPI2.setClockDivider(SPI_CLOCK_DIV8); |
||||
|
digitalWrite(PIN_SPI_RX_B, LOW); |
||||
|
RX5808_SPI2.transfer32(data, 25); |
||||
|
digitalWrite(PIN_SPI_RX_B, HIGH); |
||||
|
|
||||
|
// RX5808_SPI1.endTransaction();
|
||||
|
// RX5808_SPI2.endTransaction();
|
||||
|
} |
@ -0,0 +1,25 @@ |
|||||
|
/* |
||||
|
* Filename: rx5808.h |
||||
|
* Date: Mon 20 Sep 22:14:58 +08 2021 |
||||
|
* Author: Englebert |
||||
|
* Description: |
||||
|
* - rx5808 protocols |
||||
|
*/ |
||||
|
|
||||
|
#ifndef RX5808_H |
||||
|
#define RX5808_H |
||||
|
|
||||
|
#include "BertFPVDiversity.h" |
||||
|
|
||||
|
namespace RX5808 { |
||||
|
void begin(); |
||||
|
void setSynthRegisterB(uint16_t value); |
||||
|
void setPowerDownRegister(uint32_t value); |
||||
|
void setStateRegister(uint32_t value); |
||||
|
|
||||
|
void rxStandby(uint8_t receiver_id); |
||||
|
void rxPowerOn(uint8_t receiver_id); |
||||
|
void rxReset(uint8_t receiver_id); |
||||
|
} |
||||
|
|
||||
|
#endif |
Write
Preview
Loading…
Cancel
Save
Reference in new issue