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