The standard SPI Transfer code does tot work well in an IRQ mainly becaise it is run out of FLASH. Uese the IRAM_ATTR to put it in RAM.
Other digitalWrte() is slow and should not be uses in the IRQ.
Use GPIO.out_w1ts = ((uint32_t)1 << IO_PIN_Number); to set the pin high
Use GPIO.out_w1ts = ((uint32_t)1 << IO_PIN_Number); to set the pin low
This can only be used when the IO_PIN_Number is 0-31
There is other code for 32-39 pins.
SPI Set-up
#include "driver/periph_ctrl.h"
#include "driver/spi_master.h"
#include "soc/gpio_sig_map.h"
#include "soc/spi_reg.h"
#include "soc/dport_reg.h"
#include "soc/spi_struct.h"
static const int spiClk = 4000000; // 1 MHz
SPIClass * hspi = NULL;
void IRAM_ATTR SPIInit(void)
{
hspi = new SPIClass(HSPI);
hspi->begin();
pinMode(INT_ENC_nCS, OUTPUT);
pinMode(EXT_ENC_nCS, OUTPUT);
pinMode(DRV_nSCS, OUTPUT);
GPIO.out_w1ts = ((uint32_t)1 << INT_ENC_nCS);
GPIO.out_w1ts = ((uint32_t)1 << EXT_ENC_nCS);
GPIO.out_w1ts = ((uint32_t)1 << DRV_nSCS);
hspi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE1));
SPI2.mosi_dlen.usr_mosi_dbitlen = (1 * 16) - 1;
SPI2.miso_dlen.usr_miso_dbitlen = (1 * 16) - 1;
}
void IRAM_ATTR SPI_Read_Encoder(){
GPIO.out_w1tc = ((uint32_t)1 << INT_ENC_nCS);
SPI2.data_buf[0] = 0xFFFF;
SPI2.cmd.usr = 1;
while(SPI2.cmd.usr);
GPIO.out_w1ts = ((uint32_t)1 << INT_ENC_nCS);
encoder_int = SPI2.data_buf[0] & 0xFFFF;
if(!SPI2.ctrl.rd_bit_order){
encoder_int = (encoder_int >> 8) | (encoder_int << 8);
}
encoder_int = encoder_int & 0x3FFF ;
}
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.