-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Description
Hardware:
Board: ESP32 Pico Kit
Core Installation/update date: ARDUINO_ESP32_RELEASE "1_0_0"
IDE name: Arduino IDE
Flash Frequency: 40Mhz
PSRAM enabled: no
Upload Speed: 115200
Computer OS: Windows 7
Description:
Not able to receive the full 4 bytes SPI value from MISO. Only the first byte received properly into rx_data[] somehow, although it shows from a logic analyzer that the correct return values are present from electronic signal. It turns out that rx_data[0] = 0x42 is correct, rx_data[1:3]=0x00 which is not correct. rx_data[1] should be 0x7C as indicated by a logic analyzer.
#ifndef BT815_h
#define BT815_h
#include <Arduino.h>
#include "driver/spi_master.h"
// Attaching VSPI module to BT815
#define PIN_NUM_MISO 19
#define PIN_NUM_MOSI 23
#define PIN_NUM_CLK 18
#define PIN_NUM_CS 5
#define PIN_NUM_PD 22 //PD pin ofr BT815
// BT815 Memory Commands - use with hal_bt815memWritexx and hal_bt815memReadxx
#define MEM_WRITE 0x80 // BT815 Host Memory Write
#define MEM_READ 0x00 // BT815 Host Memory Read
// BT815 Chip Commands - use with cmdWrite
#define BT815_ACTIVE 0x00 // Initializes BT815
#define BT815_STANDBY 0x41 // Place BT815 in Standby (clk running)
#define BT815_SLEEP 0x42 // Place BT815 in Sleep (clk off)
#define BT815_PWRDOWN 0x50 // Place BT815 in Power Down (core off)
#define BT815_CLKEXT 0x44 // Select external clock source
#define BT815_CLKINT 0x48 // Select internal clock source
#define BT815_CLKSEL 0x61 // Select PLL mulitplier with second byte (param), consult data sheet for this
#define BT815_CLK60M 0x62 // Select 60MHz PLL with param set 0 for compatibility with FT800/FT801
#define BT815_CORERST 0x68 // Reset core - all registers default
#define BT815_PINDRIVE 0x70 // Set drive strength for various pins (consult data sheet)
#define REG_ID 0x302000UL
class BT815Class {
public:
BT815Class();
void memWriteN(uint32_t ftAddress, const uint8_t *ftData8, uint32_t len);
void memWrite8(uint32_t ftAddress, uint8_t ftData8);
void memWrite16(uint32_t ftAddress, uint16_t ftData16);
void memWrite32(uint32_t ftAddress, uint32_t ftData32);
void cmdWrite(uint8_t ftCommand, uint8_t param=0x00);
void memReadN(uint32_t ftAddress, uint8_t *ftData8, uint32_t len);
uint8_t memRead8(uint32_t ftAddress);
uint16_t memRead16(uint32_t ftAddress);
uint32_t memRead32(uint32_t ftAddress);
void hwReset(void);
private:
spi_device_handle_t bt815;
};
BT815Class::BT815Class()
{
esp_err_t ret;
spi_bus_config_t buscfg;
buscfg.miso_io_num=PIN_NUM_MISO;
buscfg.mosi_io_num=PIN_NUM_MOSI;
buscfg.sclk_io_num=PIN_NUM_CLK;
buscfg.quadwp_io_num=-1;
buscfg.quadhd_io_num=-1;
buscfg.max_transfer_sz=0; //default to 4092 if 0
spi_device_interface_config_t devcfg;
devcfg.clock_speed_hz=SPI_MASTER_FREQ_26M; //SPI_MASTER_FREQ_26M defined in spi_master.h
devcfg.mode=0; //SPI mode 0
devcfg.spics_io_num=PIN_NUM_CS; //CS pin
devcfg.queue_size=7; //We want to be able to queue 7 transactions at a time
devcfg.address_bits=24; //24 bits for address
//Initialize the SPI bus
ret = spi_bus_initialize(VSPI_HOST, &buscfg, 1); //DMA channel 1
ESP_ERROR_CHECK(ret);
//Attach BT815 to VSPI host of ESP32 by spi_bus_add_device()
ret = spi_bus_add_device(VSPI_HOST, &devcfg, &bt815);
ESP_ERROR_CHECK(ret);
pinMode(PIN_NUM_PD,OUTPUT);
digitalWrite(PIN_NUM_PD,HIGH);
}
void BT815Class::memWriteN(uint32_t ftAddress, const uint8_t ftData8, uint32_t len)
{
esp_err_t ret;
spi_transaction_t t;
if(len==0) return;
memset(&t, 0, sizeof(t)); //Zero out the transaction
t.length=8len; //length in bits therefore *8
t.tx_buffer=ftData8;
t.addr = ftAddress|(MEM_WRITE<<16); //devcfg.address_bits = 24; in class constructor
ret = spi_device_transmit(bt815, &t); //Transmit!
assert(ret==ESP_OK); //Should have had no issues.
}
void BT815Class::memWrite8(uint32_t ftAddress, uint8_t ftData8)
{
memWriteN(ftAddress, &ftData8, 1);
}
void BT815Class::memWrite16(uint32_t ftAddress, uint16_t ftData16)
{
memWriteN(ftAddress, (uint8_t *)&ftData16, 2); //send low byte first, this verified with a logic analyzer to be OK
}
void BT815Class::memWrite32(uint32_t ftAddress, uint32_t ftData32)
{
memWriteN(ftAddress, (uint8_t *)&ftData32, 4); //send low byte first, this verified with a logic analyzer to be OK
}
void BT815Class::cmdWrite(uint8_t ftCommand, uint8_t param)
{
esp_err_t ret;
spi_transaction_t t;
memset(&t, 0, sizeof(t));
t.length = 0;
t.addr = (uint32_t)ftCommand<<16 | (uint32_t)param<<8;
ret = spi_device_transmit(bt815, &t);
assert(ret==ESP_OK);
}
void BT815Class::memReadN(uint32_t ftAddress, uint8_t ftData8, uint32_t len)
{
if(len==0) return;
uint8_t dummy = 0xff; //dummy byte assigned an arbitrary value here, it can be any value.
esp_err_t ret;
spi_transaction_t t;
memset(&t, 0, sizeof(t)); //zero out the transaction
t.length = 8(len); //length in bits therefore *8
t.rxlength = t.length;
t.tx_buffer = (uint8_t *) &dummy;
t.addr = ftAddress; //devcfg.address_bits = 24 in class constructor
t.flags = SPI_TRANS_USE_RXDATA; //data sent direct to rx_data[4]
ret = spi_device_transmit(bt815, &t); //transmit & receive in full duplex
assert(ret==ESP_OK); //Should have had no issues.
for(int i=0; i<len; i++)
{
*ftData8++ = t.rx_data[i];
}
}
uint8_t BT815Class::memRead8(uint32_t ftAddress)
{
uint8_t _ret;
memReadN(ftAddress, (uint8_t *)&_ret, 1);
return _ret;
}
//@brief Hardware reset BT815 with PD pin driven low for 20ms
void BT815Class::hwReset(void)
{
digitalWrite(PIN_NUM_PD, LOW);
vTaskDelay((TickType_t)20/portTICK_PERIOD_MS); //hold for 20ms
digitalWrite(PIN_NUM_PD, HIGH);
vTaskDelay((TickType_t)20/portTICK_PERIOD_MS); //hold for 20ms before sending any command
}
#endif //BT815_h
/** EOF BT81x.h ********************************************************/
//Change the code below by your sketch
#include "BT81x.h"
TaskHandle_t Gui;
TaskHandle_t Idle;
void GuiTask(void *pvParameters){
uint8_t byte_ret=0;
uint8_t arr[4];
BT815Class GPU; //GPU instantiate in loop() for Arduino
GPU.hwReset();
GPU.cmdWrite(BT815_ACTIVE);
GPU.cmdWrite(BT815_CLKEXT);
GPU.cmdWrite(BT815_CLK60M);
for(;;){
GPU.memReadN(REG_ID, arr, sizeof(arr));
for(int i=0; i<4; i++) {Serial.printf("Array content 0x%x\n",arr[i]);}
vTaskDelay((TickType_t)1000/portTICK_PERIOD_MS);
}
}
void IdleTask(void *pvParameters){
static uint32_t pass=0;
for(;;){
Serial.printf("IdleTask running %ld\n", pass++);
vTaskDelay((TickType_t)1000/portTICK_PERIOD_MS);
}
}
void setup() {
Serial.begin(115200);
xTaskCreatePinnedToCore(
GuiTask,
"GuiTask",
10000,
NULL,
1,
&Gui,
1); //CPU core 1 in use for GuiTask
xTaskCreatePinnedToCore(
IdleTask,
"IdleTask",
10000,
NULL,
1,
&Idle,
0); //CPU core 0 for IdleTask
}
void loop() {
}
Debug Messages:
Enable Core debug level: Debug on tools menu of Arduino IDE, then put the serial output here
IdleTask running 478
Array content 0x42
Array content 0x0
Array content 0x0
Array content 0x0