Updated RFControl for compatibility with ESP32-S2 and ESP32-C3
Complete re-write of code.
This commit is contained in:
parent
82ad33c98f
commit
dc5844b520
|
|
@ -7,49 +7,42 @@
|
|||
|
||||
///////////////////
|
||||
|
||||
RFControl::RFControl(int pin){
|
||||
if(!configured){ // configure RMT peripheral
|
||||
RFControl::RFControl(uint8_t pin){
|
||||
|
||||
DPORT_REG_SET_BIT(DPORT_PERIP_CLK_EN_REG,1<<9); // enable RMT clock by setting bit 9
|
||||
DPORT_REG_CLR_BIT(DPORT_PERIP_RST_EN_REG,1<<9); // set RMT to normal ("un-reset") mode by clearing bit 9
|
||||
REG_SET_BIT(RMT_APB_CONF_REG,3); // enables access to RMT memory and enables wraparound mode (though the latter does not seem to be needed to set continuous TX)
|
||||
REG_WRITE(RMT_INT_ENA_REG,1<<RMT_CH0_TX_END_INT_ENA_S); // enable end-transmission interrupt so that interrupt vector is called
|
||||
REG_WRITE(RMT_CH0CONF0_REG,0x08000000); // disable carrier wave; set channel 0 to use all 8 blocks of RMT memory
|
||||
// esp_intr_alloc(ETS_RMT_INTR_SOURCE,0,eot_int,NULL,NULL); // set RMT general interrupt vector
|
||||
// config=new rmt_config_t;
|
||||
|
||||
configured=true;
|
||||
}
|
||||
|
||||
this->pin=pin;
|
||||
|
||||
pinMode(pin,OUTPUT);
|
||||
REG_WRITE(GPIO_FUNC0_OUT_SEL_CFG_REG+4*pin,87); // set GPIO OUTPUT of pin in GPIO_MATRIX to use RMT Channel-0 Output (=signal 87)
|
||||
REG_SET_FIELD(GPIO_FUNC0_OUT_SEL_CFG_REG+4*pin,GPIO_FUNC0_OEN_SEL,1); // use GPIO_ENABLE_REG of pin (not RMT) to enable this channel
|
||||
REG_WRITE(GPIO_ENABLE_W1TC_REG,1<<pin); // disable output on pin - enable only when started
|
||||
config.rmt_mode=RMT_MODE_TX;
|
||||
config.tx_config.carrier_en=false;
|
||||
config.channel=RMT_CHANNEL_0;
|
||||
config.clk_div = 1;
|
||||
config.mem_block_num=1;
|
||||
config.gpio_num=(gpio_num_t)pin;
|
||||
|
||||
ESP_ERROR_CHECK(rmt_config(&config));
|
||||
ESP_ERROR_CHECK(rmt_driver_install(config.channel,0,0));
|
||||
rmt_set_source_clk(RMT_CHANNEL_0,RMT_BASECLK_REF);
|
||||
}
|
||||
|
||||
///////////////////
|
||||
|
||||
void RFControl::start(uint8_t _numCycles, uint8_t tickTime){
|
||||
void RFControl::start(uint8_t nCycles, uint8_t tickTime){ // starts transmission of pulses from internal data structure, repeated for nCycles, where each tick in pulse is tickTime microseconds long
|
||||
start(data.data(), data.size(), nCycles, tickTime);
|
||||
}
|
||||
|
||||
if(pCount%2==0) // if next entry is lower 16 bits of 32-bit memory
|
||||
pRMT[pCount/2]=0; // set memory to zero (end-marker)
|
||||
else
|
||||
pRMT[pCount/2]&=0xFFFF; // else preserve lower 16 bits and zero our upper 16 bits
|
||||
///////////////////
|
||||
|
||||
REG_WRITE(GPIO_ENABLE_W1TS_REG,1<<pin); // enable output on pin
|
||||
numCycles=_numCycles; // set number of cycles to repeat transmission
|
||||
REG_SET_FIELD(RMT_CH0CONF0_REG,RMT_DIV_CNT_CH0,tickTime); // set one tick = 1 microsecond * tickTime (RMT will be set to use 1 MHz REF_TICK, not 80 MHz APB_CLK)
|
||||
REG_WRITE(RMT_CH0CONF1_REG,0x0000000D); // use REF_TICK clock; reset xmit and receive memory address to start of channel; START TRANSMITTING!
|
||||
while(numCycles); // wait while transmission in progress
|
||||
REG_WRITE(GPIO_ENABLE_W1TC_REG,1<<pin); // disable output on pin
|
||||
void RFControl::start(uint32_t *data, int nData, uint8_t nCycles, uint8_t tickTime){ // starts transmission of pulses from specified data pointer, repeated for nCycles, where each tick in pulse is tickTime microseconds long
|
||||
|
||||
rmt_set_clk_div(RMT_CHANNEL_0,tickTime); // set clock divider
|
||||
|
||||
for(int i=0;i<nCycles;i++) // loop over nCycles
|
||||
rmt_write_items(RMT_CHANNEL_0, (rmt_item32_t *) data, nData, true); // start transmission and wait until completed before returning
|
||||
}
|
||||
|
||||
///////////////////
|
||||
|
||||
void RFControl::clear(){
|
||||
pCount=0;
|
||||
data.clear();
|
||||
}
|
||||
|
||||
///////////////////
|
||||
|
|
@ -62,42 +55,18 @@ void RFControl::add(uint16_t onTime, uint16_t offTime){
|
|||
|
||||
///////////////////
|
||||
|
||||
void RFControl::phase(uint16_t numTicks, uint8_t phase){
|
||||
void RFControl::phase(uint16_t nTicks, uint8_t phase){
|
||||
|
||||
if(pCount==1023){ // maximum number of entries reached (saving one space for end-marker)
|
||||
Serial.print("\n*** ERROR: Can't add more than 1023 entries to RF Control Module\n\n");
|
||||
} else
|
||||
uint32_t ticks=nTicks&0x7FFF;
|
||||
|
||||
if(numTicks>32767 || numTicks<1){
|
||||
Serial.print("\n*** ERROR: Request to add RF Control entry with numTicks=");
|
||||
Serial.print(numTicks);
|
||||
Serial.print(" is out of allowable range: 1-32767\n\n");
|
||||
} else {
|
||||
|
||||
int index=pCount/2;
|
||||
|
||||
if(pCount%2==0)
|
||||
pRMT[index]=numTicks | (phase?(1<<15):0); // load entry into lower 16 bits of 32-bit memory
|
||||
if(lowWord)
|
||||
data.push_back(ticks | (phase?(1<<15):0));
|
||||
else
|
||||
pRMT[index]=pRMT[index] & 0xFFFF | (numTicks<<16) | (phase?(1<<31):0); // load entry into upper 16 bits of 32-bit memory, preserving lower 16 bits
|
||||
|
||||
pCount++;
|
||||
}
|
||||
data.back()|=ticks<<16 | (phase?(1<<31):0);
|
||||
|
||||
lowWord=!lowWord;
|
||||
}
|
||||
|
||||
///////////////////
|
||||
|
||||
void RFControl::eot_int(void *arg){
|
||||
numCycles--;
|
||||
REG_WRITE(RMT_INT_CLR_REG,~0); // interrupt MUST be cleared first; transmission re-started after (clearing after restart crestes havoc)
|
||||
if(numCycles)
|
||||
REG_WRITE(RMT_CH0CONF1_REG,0x0000000D); // use REF_TICK clock; reset xmit and receive memory address to start of channel; re-start transmission
|
||||
}
|
||||
|
||||
///////////////////
|
||||
|
||||
boolean RFControl::configured=false;
|
||||
volatile int RFControl::numCycles;
|
||||
//int32_t *RFControl::pRMT=(uint32_t *)RMT_CHANNEL_MEM(0);
|
||||
int RFControl::pCount=0;
|
||||
uint8_t RFControl::nChannels=0;
|
||||
|
|
|
|||
|
|
@ -3,21 +3,30 @@
|
|||
// RF Control Module //
|
||||
////////////////////////////////////
|
||||
|
||||
#include "driver/rmt.h"
|
||||
#include <vector>
|
||||
|
||||
using std::vector;
|
||||
|
||||
class RFControl {
|
||||
private:
|
||||
int pin;
|
||||
static volatile int numCycles;
|
||||
static boolean configured;
|
||||
static uint32_t *pRMT;
|
||||
static int pCount;
|
||||
static void eot_int(void *arg);
|
||||
rmt_config_t config;
|
||||
vector<uint32_t> data;
|
||||
boolean lowWord=true;
|
||||
static uint8_t nChannels;
|
||||
|
||||
public:
|
||||
RFControl(int pin); // creates transmitter on pin
|
||||
static void clear(); // clears transmitter memory
|
||||
static void add(uint16_t onTime, uint16_t offTime); // adds pulse of onTime ticks HIGH followed by offTime ticks LOW
|
||||
static void phase(uint16_t numTicks, uint8_t phase); // adds either a HIGH phase or LOW phase lasting numTicks ticks
|
||||
void start(uint8_t _numCycles, uint8_t tickTime=1); // starts transmission of pulses, repeated for numCycles, where each tick in pulse is tickTime microseconds long
|
||||
RFControl(uint8_t pin); // creates transmitter on pin
|
||||
|
||||
void start(uint32_t *data, int nData, uint8_t nCycles=1, uint8_t tickTime=1); // starts transmission of pulses from specified data pointer, repeated for numCycles, where each tick in pulse is tickTime microseconds long
|
||||
void start(uint8_t nCycles=1, uint8_t tickTime=1); // starts transmission of pulses from internal data structure, repeated for numCycles, where each tick in pulse is tickTime microseconds long
|
||||
|
||||
void clear(); // clears transmitter memory
|
||||
void add(uint16_t onTime, uint16_t offTime); // adds pulse of onTime ticks HIGH followed by offTime ticks LOW
|
||||
void phase(uint16_t nTicks, uint8_t phase); // adds either a HIGH phase or LOW phase lasting numTicks ticks
|
||||
};
|
||||
|
||||
// Helper macro for creating your own storage of uint32_t data array elements - used with first variation of start() above
|
||||
|
||||
#define RF_PULSE(highTicks,lowTicks) (1 << 15 | highTicks | lowTicks << 16)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,30 +1,83 @@
|
|||
/* HomeSpan Remote Control Example */
|
||||
|
||||
// This is a placeholder .ino file that allows you to easily edit the contents of this library using the Arduino IDE,
|
||||
// as well as compile and test from this point. This file is ignored when the library is included in other sketches.
|
||||
|
||||
#include "PwmPin.h"
|
||||
#include "RFControl.h" // include RF Control Library
|
||||
|
||||
void setup() {
|
||||
|
||||
Serial.begin(115200);
|
||||
delay(1000);
|
||||
Serial.begin(115200); // start the Serial interface
|
||||
Serial.flush();
|
||||
delay(1000); // wait for interface to flush
|
||||
|
||||
Serial.print("\n\nTest sketch for HomeSpan Extras Library\n\n");
|
||||
Serial.print("\n\nHomeSpan RF Transmitter Example\n\n");
|
||||
|
||||
Serial.println("Starting...");
|
||||
RFControl rf(17); // create an instance of RFControl with signal output to pin 17 of the ESP32
|
||||
|
||||
LedPin *led[20];
|
||||
// rf.phase(1000,HIGH);
|
||||
// rf.phase(9000,LOW);
|
||||
// rf.phase(1000,HIGH);
|
||||
// rf.phase(9000,LOW);
|
||||
// rf.phase(1000,HIGH);
|
||||
// rf.phase(30000,LOW);
|
||||
|
||||
// uint8_t p[]={33,27,4,32,18,19,16,17,5}; // ESP32 test
|
||||
uint8_t p[]={11,7,3,1,38,33,9,10}; // ESP32-S2 test
|
||||
// rf.add(1000,9000); // create a pulse train with three 5000-tick high/low pulses
|
||||
// rf.add(1000,9000); // create a pulse train with three 5000-tick high/low pulses
|
||||
// rf.add(1000,9000); // create a pulse train with three 5000-tick high/low pulses
|
||||
// rf.add(1000,30000); // create a pulse train with three 5000-tick high/low pulses
|
||||
//
|
||||
// rf.start(2,100);
|
||||
// Serial.println("Done");
|
||||
// while(1);
|
||||
|
||||
for(int i=0;i<sizeof(p);i++)
|
||||
led[i]=new LedPin(p[i],20,5000);
|
||||
//
|
||||
//#define NPOINTS 3
|
||||
//
|
||||
// uint32_t data[NPOINTS];
|
||||
//
|
||||
// for(int i=0;i<NPOINTS;i++){
|
||||
// if(i<NPOINTS-1)
|
||||
// data[i]=RF_PULSE(1000,9000);
|
||||
// else
|
||||
// data[i]=RF_PULSE(1000,30000);
|
||||
//
|
||||
// Serial.println((uint32_t)data[i],HEX);
|
||||
// }
|
||||
//
|
||||
// rf.start(data,NPOINTS,1,100);
|
||||
//
|
||||
// Serial.println("Done.");
|
||||
// while(1);
|
||||
|
||||
led[7]->set(100);
|
||||
|
||||
while(1);
|
||||
}
|
||||
rf.clear(); // clear the pulse train memory buffer
|
||||
|
||||
rf.add(5000,5000); // create a pulse train with three 5000-tick high/low pulses
|
||||
rf.add(5000,5000);
|
||||
rf.add(5000,10000); // double duration of final low period
|
||||
|
||||
Serial.print("Starting 4 cycles of three 500 ms on pulses...");
|
||||
|
||||
rf.start(4,100); // start transmission of 4 cycles of the pulse train with 1 tick=100 microseconds
|
||||
|
||||
Serial.print("Done!\n");
|
||||
|
||||
delay(2000);
|
||||
|
||||
rf.clear();
|
||||
|
||||
for(int i=1000;i<10000;i+=1000)
|
||||
rf.add(i,10000-i);
|
||||
rf.add(10000,10000);
|
||||
|
||||
Serial.print("Starting 3 cycles of 100-1000 ms pulses...");
|
||||
|
||||
rf.start(3,100); // start transmission of 3 cycles of the pulse train with 1 tick=100 microseconds
|
||||
|
||||
Serial.print("Done!\n");
|
||||
|
||||
Serial.print("\nEnd Example");
|
||||
|
||||
} // end of setup()
|
||||
|
||||
void loop(){
|
||||
}
|
||||
|
||||
} // end of loop()
|
||||
|
|
|
|||
Loading…
Reference in New Issue