ebaera
Published © GPL3+

FPGA Beginner Tool with Arduino Nano 33 BLE

Verilog quick learning. Feasibility model creation. Accurate logic volume estimation. I2C connection. Education purpose.

IntermediateFull instructions provided3,542
FPGA Beginner Tool with Arduino Nano 33 BLE

Things used in this project

Hardware components

Mouser Project
×1
Arduino Nano 33 BLE
Arduino Nano 33 BLE
×1

Hand tools and fabrication machines

Crowd Supply Reflo Air

Story

Read more

Custom parts and enclosures

Gerber data

3D print data

Schematics

Schematic Drawing

Code

Sample code

Verilog
 /*******************************************************************
 * SYSTEM CLOCK                                                     *
 ********************************************************************/
wire CLK;  // base clock 29.56MHz 33.25ns
OSCH #(.NOM_FREQ("29.56")) internal_oscillator_inst (.STDBY(1'b0), .OSC(CLK)); //  
assign clk = CLK;
 /*******************************************************************
 * RGB LED controller                                               *
  [11:8](byte cont RGB+5byte blank) [7:5](8bit cntr) [4:0](0(10/22), 1(16/16) plse form)
 _|-200-500ns-|__650--950ns______| "0"  _|--550--650ns---|__450--750ns__| "1" 
 -|___//__>50us(*1024)__|-- "reset"    G-R-B 24bit  
 *******************************************************************/
reg rgbOUT;    	    // output signal
reg [23:0] RGBreg;	// 8bit x 3 RGB color set through I2C
reg [11:0] ctRGB;	// rgb clock(33.25ns) counter
reg [4:0] dptn; 		// data pattern "0/1" compare reg
always @(posedge clk) begin ctRGB <= ctRGB + 1;
  if(ctRGB[11:8] == 4'b0000 || ctRGB[11:8] == 4'b0001 || ctRGB[11:8] == 4'b0010) begin
  if(RGBreg[ctRGB[9:5]] == 0)	dptn <= 5'b01010; 	// "0" rgbout = 1'b1; 360/800
	else 							dptn <= 5'b10001; 	// "1" rgbout = 1'b1; 580/600
	      rgbOUT = ctRGB[4:0] < dptn[4:0];				// data pattarn control
	end else rgbOUT = 1'b0;     							// "0" reset mode
end
assign RGB = rgbOUT;	// pin23
 /*******************************************************************
 * BUZZ controll                                                    *
 ********************************************************************/
reg speaker;		// sound pulse
reg [27:0] tone;
always @(posedge clk) tone <= tone+1;
wire [6:0] fastsweep = (tone[22] ? tone[21:15] : ~tone[21:15]);
wire [6:0] slowsweep = (tone[25] ? tone[24:18] : ~tone[24:18]);
wire [14:0] clkdivider = {2'b01, (tone[27] ? slowsweep : fastsweep), 6'b000000};

reg [14:0] counter;
always @(posedge clk) if(counter==0) counter <= clkdivider; else counter <= counter-1;

always @(posedge clk) if(counter==0 && Enable) speaker <= ~speaker;
assign BUZ = speaker;
 /*******************************************************************
 * SERVO controller     0.5ms---1.5ms---2.5ms                       *
      ____________ _________                                        ______
 ____|set         ^         |reset__________reset____//____reset___|set  ^ 
 con=0xAEFE  con=0xB4A2->0  con[11:2]==act[9:0] 0x0000-0x2d0(0-2ms) con=0xAEFE
 ********************************************************************/
reg [3:0] svOUT;    	   						 	// output signalx4 lines
parameter CYCL = 20'h80000;						// 16ms Servo cycle
parameter PPAL = 16'h3f00;						// 0.5ms Pre Pulse    
reg [19:0] svREG; 	     						// Servo base counter
  
reg [7:0] svTGT[3:0];							// 8bit I2C reg
reg [9:0] svCRT[3:0];							// 10bit current count up
reg [9:0] svocpm; 								// set speed by I2C 
always @(posedge clk) begin svREG <= svREG + 1; // timer count up
	//-20bit----[4bit----10bit---6bit]-----------------------------
if(svREG < {4'h0, svCRT[0], 6'h0}) svOUT[0] <= 1'b1; else svOUT[0] <= 1'b0; // PULSE GENERATE0
if(svREG < {4'h0, svCRT[1], 6'h0}) svOUT[1] <= 1'b1; else svOUT[1] <= 1'b0; // PULSE GENERATE1
if(svREG < {4'h0, svCRT[2], 6'h0}) svOUT[2] <= 1'b1; else svOUT[2] <= 1'b0; // PULSE GENERATE2
if(svREG < {4'h0, svCRT[3], 6'h0}) svOUT[3] <= 1'b1; else svOUT[3] <= 1'b0; // PULSE GENERATE3	
	//----------------------------------------------------------
if(svREG > CYCL - PPAL + 3000) svOUT <= 4'hf;	// BASE 0.5ms PULSE
if(svREG > CYCL) svREG <= 0; 					// END CYCLE
end
reg SVCOMP;				// complete   
always @(posedge clk) begin 
svocpm <= 8'b00010000; // set data from I2C
if({svTGT[0], 2'b00} == svCRT[0] && {svTGT[1], 2'b00} == svCRT[1] &&
	{svTGT[2], 2'b00} == svCRT[2] && {svTGT[3], 2'b00} == svCRT[3]) SVCOMP <= 1'b1;
else SVCOMP <= 1'b0;	// SEEK COMPLETE		 
end	
 /***********************************************************************
 * IR receiver                  32bit from MSB to LSB
 --|_9ms_start_|-4ms-|_600us_|-("0")600us-|_600us_|-("1")1600us-|_600us_stop_|-- 
 ***********************************************************************/
  wire IRn; reg IRnn;
  reg [7:0] rep;				// decoded 8bit char data (to I2C)
  reg [19:0] ctirL, ctirH; 	// rgb clock(33.8ns) counter 4000us
  reg ena, pena;				// enable gate flags

  reg [7:0] IRcntL, IRcntH;	// input signal glidge reduction
  always @(posedge clk) begin 	// remove glidge
	if(IRn == 0) begin IRcntL <= IRcntL + 1; IRcntH <= 0;	end
	if(IRn == 1) begin	IRcntH <= IRcntH + 1; IRcntL <= 0;	end
	if(IRcntL > 20) IRnn <= 0;
	if(IRcntH > 20) IRnn <= 1;
  end
  
  reg flgg, flgg2;			// monitor flag
  reg [31:0] IRreg; 		// 32bit receive data buffer
  reg [5:0] irseq; 			// ir receive sequence 
  always @(posedge clk) begin		// enable signal from Startbit && H
	if(ctirH > 20'h30000) begin pena <= 0; ena <= 1'b0; irseq <= 0; 	end // idle
	if(ctirL > 20'h30000) begin pena <= 1;  						end // prenable
	if(pena == 1 && IRnn == 1) begin ena  <= 1'b1; 			end	// enable
	if(irseq == 1) flgg2 <= 1'b1;											// debug flag
	// receive 32 bit data
	if(ena == 1) 	begin
	if(IRnn == 0) 	begin	// "L" ---- 
		if(ctirL == 0) begin flgg <= 1'b0;
			if(irseq > 0) begin
			if(ctirH > 18'h4557) 	begin IRreg[32-irseq[5:0]] = 1'b1; end // > 600us 
			else                 	begin IRreg[32-irseq[5:0]] = 1'b0; end // < 600us	
			if(irseq == 32) begin flgg2 <= 1'b0;			
				case(IRreg[31:0]) // decode data 32bit >> char 8bit
					32'h00FFA25D: rep <= 8'h31; // "1(0x31)" 
					32'h00FF629D: rep <= 8'h32; // "2(0x32)" 
					32'h00FFE21D: rep <= 8'h33; // "3(0x33)" 
					32'h00FF22DD: rep <= 8'h34; // "4(0x34)" 
					32'h00FF02FD: rep <= 8'h35; // "5(0x35)" 
					32'h00FFC23D: rep <= 8'h36; // "6(0x36)" 
					32'h00FFE01F: rep <= 8'h37; // "7(0x37)" 
					32'h00FFA857: rep <= 8'h38; // "8(0x38)"
					32'h00FF906F: rep <= 8'h39; // "9(0x39)" 
					32'h00FF9867: rep <= 8'h30; // "0(0x30)" 
					32'h00FF6897: rep <= 8'h2A; // "*(0x2A)" 
					32'h00FFB04F: rep <= 8'h23; // "#(0x23)" 
					32'h00FF18E7: rep <= 8'h55; // "U(0x55)" 
					32'h00FF4AB5: rep <= 8'h44; // "D(0x44)" 
					32'h00FF10EF: rep <= 8'h4C; // "L(0x4C)" 
					32'h00FF5AA5: rep <= 8'h52; // "R(0x52)" 
					32'h00FF38C7: rep <= 8'h4B; // "K(0x4B)"
				endcase			
			end
			end
		end
	end else  		begin	// "H" ----	
		if(ctirH == 0) begin flgg <= 1'b1;
			irseq <= irseq + 1;			// next step	
		end
	end
	end
	// L/H pulse width counters
	if(IRnn == 0) 	begin				// "L" ---- 
		if(ctirL != 0) ctirH <= 0; 	// first entry after H >> L(counter == 0)
		if(ctirL < 20'h45000) ctirL <= ctirL + 1; 	// "L" timer count up	
	end else  		begin				// "H" ----	
		if(ctirH != 0) ctirL <= 0; 	// first entry after L >> H(counter == 0)
		if(ctirH < 20'h45000) ctirH <= ctirH + 1; 	// "H" timer count up
	end
  end
  assign IRp = IRn;					// pin21

EZ Logic Analyzer

Arduino
// ============================================
// MEDAMA/4Legged ROBOT CONTROL program
//  for Arduino nano 33 (Sense) https://store.arduino.cc/usa/nano-33-ble-sense
// ============================================
#include "para.h"               // parameter/memo
 UART mySerial(digitalPinToPinName(A5), digitalPinToPinName(A4), NC, NC); // uart TX(A5->[28])/RX(A4<-[27])
// ============================================
// SETUP     +fpga--+
//    IR--->21      23--->RGB             
//    SW--->20      11--->LED1
//           |      10--->LED2
//           |       4-+->LED3
//           |      |  +---->DCM PH
//           |       5------>DCM EN  +-nano33-+
//           |      12--->SVO------->A6       |   
//           |      17->IR TR------->A2       |
//           |       9<-->TP1<------>A0       |
//           |       8<->TP2/BUZZ<-->A3       |
//           |      14<-->TP3<------>A1       |
//           |      13<-->TP4<------>A7       |
//           |   RX 28<--(SCL)<------A5 TX    |
//           |   TX 27-->(SDA)------>A4 RX    |
//           +------+                 +-------+
// ============================================
void setup() {
  pinMode(13, OUTPUT);          // nano 33 on board LED(D13)  
  Serial.begin(9600);           // serial monitor
  //mySerial.begin(14400);        // 14400 69.6us/bit (11bit 67.8us) 28800 34.8us/bit (10bit 33.9us)
  //                              // 57600 17.4us/bit ( 9bit 17us), 115200  8.7us/bit ( 8bit  8.5us) 
  //mySerial.begin(115200);        // 115200  8.7us/bit (8.5us)                                  
  //mySerial.print(0x01, HEX);                                 
}
// ============================================
// EZ logic analyzer
long itime; int tgll;
#define NofP 500
// ============================================
int  memo[NofP];   // raw
int  chA[NofP];    // raw
int  chB[NofP];    // raw
int  chC[NofP];    // raw
int  chD[NofP];    // raw
int  chE[NofP];    // raw
int  chF[NofP];    // raw
int  cc; int tgl;
void loop() {
      while(!digitalRead(A3)) {   }      // Trigger
      for(int n = 0; n < NofP; n++) { 
         cc++; if(cc > 10) { cc = 0; tgl = !tgl; }
         chA[n] = digitalRead(A0) + 3;    // [9] TP1
         chB[n] = digitalRead(A1) + 5;    // [14] TP3
         chC[n] = digitalRead(A2) + 7;    // [17] 
         chD[n] = digitalRead(A3) + 9;    // [8] TP2/BUZZ
         chE[n] = digitalRead(A6) + 11;   // [12] SVO   
         chF[n] = digitalRead(A7) + 13;   // [13] TP4      
         memo[n]  = tgl + 1;
         delayMicroseconds(20); // sampling rate
      }  
      for(int n = 0; n < NofP; n++) { 
         Serial.print(memo[n]);   Serial.print("\t");         
         Serial.print(chA[n]);    Serial.print("\t"); 
         Serial.print(chB[n]);    Serial.print("\t");
         Serial.print(chC[n]);    Serial.print("\t"); 
         Serial.print(chD[n]);    Serial.print("\t"); 
         Serial.print(chE[n]);    Serial.print("\t"); 
         Serial.print(chF[n]);    Serial.println(""); 
      }     
}

Credits

ebaera

ebaera

0 projects • 11 followers

Comments