Setup
The un0rick board was set up to connect with the m5stack
/* CONNECTIONS BETWEEN RPi and m5stack
M5STACK pin22 -> RPi header GPIO 23 (Ice40 reset)
M5STACK pin21 -> RPi header GPIO 8 (Ice40 CS)
M5STACK pin19 -> RPi header GPIO 10 (Rpi MISO)
M5STACK pin23 -> RPi header GPIO 9 (Rpi MOSI)
M5STACK pin18 -> RPi header GPIO 11 (Rpi CLK)
M5STACK GND to RaspberryPi header GND pin
M5STACK 5V -> RaspberryPi header 5V pin
*/
The overall setup for this experiment was as follows:
and yielded the following results
One will see the echoes from the bottom of the mug appearing.
Code
The following code was used on the m5stack.
#include <SPI.h>
#include <M5Stack.h>
/* CONNECTIONS BETWEEN RPi and m5stack
M5STACK pin22 -> RPi header GPIO 23 (Ice40 reset)
M5STACK pin21 -> RPi header GPIO 8 (Ice40 CS)
M5STACK pin19 -> RPi header GPIO 10 (Rpi MISO)
M5STACK pin23 -> RPi header GPIO 9 (Rpi MOSI)
M5STACK pin18 -> RPi header GPIO 11 (Rpi CLK)
M5STACK GND to RaspberryPi header GND pin
M5STACK 5V -> RaspberryPi header 5V pin
*/
#define ICE40RESET 22
#define ICE40CS 21
#define ICE40MISO 19
#define ICE40MOSI 23
#define ICE40CLK 18
#define PTS 3200
#define LenAcq 2*PTS+1
#define LenData PTS+1
// Sound aspects
#define D0 -1 //silence
//THE FIRST OCTAVE
#define B1 262 //Do (B)
#define D1 294 //Re (D)
#define E1 330 //Mi (E)
uint16_t MaxPt = PTS / 2;
int CenterPeak = 80;
uint16_t DATA[LenAcq];
uint16_t RAWDATA[LenData];
uint16_t CLEANDATA[320];
int Factor = 80;
int SPIMODE = 1;
int i = 0;
int j = 0;
int value = 0;
int GainLevel = 400;
bool MSBF = true;
void SetGain( ) {
for (int i = 0; i <= 40; i++) {
WriteFPGA(16 + i, 400 / 4);
}
}
void buttons_test() {
int MAXARRAY = 0;
if (M5.BtnA.wasPressed()) {
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setCursor(10, 10);
M5.Lcd.setTextColor(TFT_RED);
M5.Lcd.setTextSize(3);
M5.Lcd.printf("Testing if connection is OK \n\n");
M5.Lcd.printf("LED 2 should be blinking 3 times \n\n");
TestFPGA();
TestFPGA();
TestFPGA();
M5.Speaker.tone(B1, 200); //frequency 3000, with a duration of 200ms
}
if (M5.BtnB.wasPressed()) {
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setCursor(10, 10);
M5.Lcd.setTextColor(TFT_RED);
M5.Lcd.setTextSize(3);
M5.Lcd.printf("Details of a peak\n\n");
CenterPeak = MaxPt * Factor;
for (int i = 0; i <= 319 / 2; i++) {
M5.Lcd.drawPixel(2 * i, RAWDATA[CenterPeak - 320 / 4 + i] / 4 + 20, TFT_RED);
M5.Lcd.drawLine(2 * i, RAWDATA[CenterPeak - 320 / 4 + i] / 4 + 20, 2 * i + 2, RAWDATA[CenterPeak - 320 / 4 + i + 1] / 4 + 20, TFT_ORANGE);
/*if (i < 5) {
M5.Lcd.printf("%3d ; ", i);
M5.Lcd.printf("%3d \n", RAWDATA[CenterPeak - 320 / 2 + i] / 4);
}
*/
}
M5.Speaker.tone(D1, 200); //frequency 3000, with a duration of 200ms
}
if (M5.BtnC.wasPressed()) {
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setCursor(10, 10);
M5.Lcd.setTextColor(TFT_GREEN);
M5.Lcd.setTextSize(3);
M5.Lcd.printf("Acquisition\n\n");
// Read
WriteFPGA(0xEF, 0x01); // cleaning pointer
WriteFPGA(0xEA, 0x01); // trigging acquisition
delay(200);
GetData();
/*
for (int i = 0; i <= 20; i++) {
M5.Lcd.printf("%3d -- ", DATA[2 * i]);
M5.Lcd.printf("%3d --> ", DATA[2 * i + 1]);
M5.Lcd.printf("%3d\n", RAWDATA[i]);
}
*/
Factor = PTS / 320; // PTS = 3200 pts (16msps * 200us)
for (int i = 0; i <= 319; i++) {
value = 0;
for (int j = 0; j <= Factor ; j++) {
value = value + abs(RAWDATA[i * Factor + j] - 512);
}
if (value > MAXARRAY ) {
if (i < 310) {
MAXARRAY = value;
MaxPt = i;
}
}
value = value / (Factor * 2); // 240 (512, going into 240)
M5.Lcd.drawFastVLine(i, (240 - value) - 10, 240 - 10, TFT_GREEN);
}
M5.Lcd.drawRect(230, 0, 240, 320, BLACK);
//M5.Lcd.printf("== Value Max at %3d \n", MaxPt);
//M5.Lcd.drawFastVLine(0, 0, 100, TFT_RED);
//M5.Lcd.drawFastVLine(319, 0, 200, TFT_GREEN);
M5.Speaker.tone(E1, 200); //frequency 3000, with a duration of 200ms
}
}
void SetupFPGA() {
GainLevel = 200;
SetGain(); // TGC level
// Duration of Pon
WriteFPGA(0xE0, 0x19 ); // 200ns Pon
// Duration between Pon and Poff
WriteFPGA(0xD0, 0xC ); // 12*7.8125ns delay between Pon and Poff
// Duration of damper
WriteFPGA(0xE1, 0 ); //
WriteFPGA(0xE2, 254 ); //
// Duration betwen beginning and end of acquisition
WriteFPGA(0xE3, 2 ); //
WriteFPGA(0xE4, 128 ); //
// Length of acquisition
WriteFPGA(0xE5, 0x60 ); //
WriteFPGA(0xE6, 0x00 ); // 0x60 * 255 * 7.8125ns duree
//Freq
WriteFPGA(0xED, 3); // setting freq as 64Msps / (1+arg) eg 3 = 16msps
//Shoot
WriteFPGA(0xEB, 0x00); // Doing 1 shot
}
void GetData() {
for (int i = 0; i <= LenAcq; i++) {
DATA[i] = 0;
}
for (int i = 0; i <= LenData; i++) {
RAWDATA[i] = 0;
}
for (int i = 0; i <= LenAcq; i++) {
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
digitalWrite(ICE40CS, LOW);
DATA[i] = SPI.transfer(0x00);
digitalWrite(ICE40CS, HIGH);
SPI.endTransaction();
}
for (int i = 0; i <= LenData ; i++) {
RAWDATA[i] = 128 * (DATA[2 * i + 1] & 0b111) + DATA[2 * i + 2];
/*
if (i < 10) {
M5.Lcd.printf("%3d ", DATA[2 * i + 1]); M5.Lcd.printf("%3d - ", DATA[2 * i + 1] & 0b111);
M5.Lcd.printf("%3d ", DATA[2 * i ]); M5.Lcd.printf("%3d - ", DATA[2 * i + 2]);
M5.Lcd.printf("%3d \n", RAWDATA[i]);
}
*/
}
}
void setup() {
// put your setup code here, to run once:
pinMode(ICE40CS, OUTPUT);
pinMode(ICE40RESET, OUTPUT);
// initialize SPI:
//SPI.begin();
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
SPI.endTransaction();
Serial.begin(115200); // SERIAL
M5.begin(); // M5STACK INITIALIZE
M5.Lcd.setBrightness(200); // BRIGHTNESS = MAX 255
M5.Lcd.fillScreen(BLACK); // CLEAR SCREEN
M5.Lcd.setRotation(0); // SCREEN ROTATION = 0
M5.Lcd.setTextColor(TFT_RED);
M5.Lcd.setTextSize(3);
M5.Lcd.printf("Initialisation\n\n");
delay(500);
digitalWrite(ICE40RESET, LOW);
delay(500);
digitalWrite(ICE40RESET, HIGH);
M5.Lcd.setTextColor(TFT_YELLOW);
M5.Lcd.printf("RESET DONE\n\n");
delay(500);
M5.Lcd.setTextColor(TFT_GREEN);
SetupFPGA();
M5.Lcd.printf("FPGA has been set up for acquisitions\n\n");
}
int WriteFPGA(int address, int value) {
//SPI.begin();
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
digitalWrite(ICE40CS, LOW);
SPI.transfer(0xAA);
digitalWrite(ICE40CS, HIGH);
delayMicroseconds(5);
digitalWrite(ICE40CS, LOW);
SPI.transfer(address);
digitalWrite(ICE40CS, HIGH);
delayMicroseconds(5);
digitalWrite(ICE40CS, LOW);
SPI.transfer(value);
digitalWrite(ICE40CS, HIGH);
delayMicroseconds(5);
//SPI.end();
SPI.endTransaction();
return 1;
}
int TestFPGA() {
M5.Lcd.printf("Blink 1 - ");
WriteFPGA(0xEB, 0x01);
delay(750);
WriteFPGA(0xEB, 0x00);
delay(750);
}
void loop() {
// put your main code here, to run repeatedly:
//TestFPGA();
buttons_test();
M5.update();
}