Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

FPGA to CortexM3 problems

Status
Not open for further replies.

dave3891

Newbie level 3
Joined
Oct 23, 2010
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,306
I have a FPGA pulse generator design that is connected to a STM32 board with SPI and I am having a strange problem with sending / receiving data.

The basic operation is that I send a quantity of pulses to the FPGA and then a frequency to pulse them at. The FPGA then counts them down as it pulses and I can read the remaining quantity back any time.

Sending the data seems to work as planned, but the receiving is quite strange.

I setup a test data send with the following:
Code:
// Set outgoing bytes 
always @(posedge clk) begin
	if(SSEL_startmessage) begin
		sendTest <= 123456789;
		sendmem[0] <= sendTest[31:24];
		sendmem[1] <= sendTest[23:16];
		sendmem[2] <= sendTest[15:8];
		sendmem[3] <= sendTest[7:0];
		end
end

And then read it back on the M3 with this code:
Code:
  for ( i = 0; i < 4; i++ )
  {
	  // Data out
	  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
	  SPI_I2S_SendData(SPI1, src_addr[i]);

	  // Data in
	  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
	  inBuff[i] = SPI_I2S_ReceiveData(SPI1);

	  for(delay=0; delay<SPIDELAY; delay++);

  }
  GPIO_WriteBit(GPIOC, GPIO_Pin_6, 1); // Set SSEL pin high

  remaining |= (inBuff[0] << 24);
  remaining |= (inBuff[1] << 16);
  remaining |= (inBuff[2] << 8);
  remaining |= (inBuff[3]);

  return remaining;

When I do this it returns the 123456789 as expected.


But if I send to a register and read it back, it comes back in a strange order. eg:
If I send 200 (hex 00 00 00 C8) it comes back as 3368550400 (C8 C8 00 00)
If I send 123 (00 00 00 7B) it comes back as 2071658496 (7B 7B 00 00)

But the numbers that I send appear to operate the FPGA as expected.


Here is the receive code on the FPGA:
Code:
	if(SSEL_endmessage) begin
		// Read the first byte for the command
		// 0x01 = position command
		// 0x02 = Velocity command
		if (mem[0] == 1) begin
			xcmd <= {mem[1], mem[2], mem[3], mem[4]};
			ycmd <= {mem[5], mem[6], mem[7], mem[8]};
			zcmd <= {mem[9], mem[10], mem[11], mem[12]};
			load <= 1;
		end
		else if(mem[0] == 2) begin
			frequency <= {mem[1], mem[2], mem[3]};
			loadFreq <= 1;
			
		end
		
	end

And here is the code that sends it from the M3:
Code:
uint32_t xCommand = 123;
uint32_t yCommand = 200;
uint32_t zCommand = 200;

src_addr[0] = 1; //0x01 for command 0x02 for velocity
src_addr[1] = xCommand >> 24; src_addr[2] = xCommand >> 16; src_addr[3] = xCommand >> 8; src_addr[4] = xCommand;
src_addr[5] = yCommand >> 24; src_addr[6] = yCommand >> 16; src_addr[7] = yCommand >> 8; src_addr[8] = yCommand;
src_addr[9] = zCommand >> 24; src_addr[10] = zCommand >> 16; src_addr[11] = zCommand >> 8; src_addr[12] = zCommand;

SPISend((uint8_t *)src_addr, 13);


I am really lost with why the static set number from the FPGA sends correctly but reading back a previously send number that operates the FPGA as expected, does not read properly.


Any ideas would be appreciated.


Thanks
Dave
 

I have a FPGA pulse generator design that is connected to a STM32 board with SPI and I am having a strange problem with sending / receiving data.

The basic operation is that I send a quantity of pulses to the FPGA and then a frequency to pulse them at. The FPGA then counts them down as it pulses and I can read the remaining quantity back any time.

Sending the data seems to work as planned, but the receiving is quite strange.

I setup a test data send with the following:
Code:
// Set outgoing bytes 
always @(posedge clk) begin
	if(SSEL_startmessage) begin
		sendTest <= 123456789;
		sendmem[0] <= sendTest[31:24];
		sendmem[1] <= sendTest[23:16];
		sendmem[2] <= sendTest[15:8];
		sendmem[3] <= sendTest[7:0];
		end
end

And then read it back on the M3 with this code:
Code:
  for ( i = 0; i < 4; i++ )
  {
	  // Data out
	  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
	  SPI_I2S_SendData(SPI1, src_addr[i]);

	  // Data in
	  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
	  inBuff[i] = SPI_I2S_ReceiveData(SPI1);

	  for(delay=0; delay<SPIDELAY; delay++);

  }
  GPIO_WriteBit(GPIOC, GPIO_Pin_6, 1); // Set SSEL pin high

  remaining |= (inBuff[0] << 24);
  remaining |= (inBuff[1] << 16);
  remaining |= (inBuff[2] << 8);
  remaining |= (inBuff[3]);

  return remaining;

When I do this it returns the 123456789 as expected.


But if I send to a register and read it back, it comes back in a strange order. eg:
If I send 200 (hex 00 00 00 C8) it comes back as 3368550400 (C8 C8 00 00)
If I send 123 (00 00 00 7B) it comes back as 2071658496 (7B 7B 00 00)

But the numbers that I send appear to operate the FPGA as expected.


Here is the receive code on the FPGA:
Code:
	if(SSEL_endmessage) begin
		// Read the first byte for the command
		// 0x01 = position command
		// 0x02 = Velocity command
		if (mem[0] == 1) begin
			xcmd <= {mem[1], mem[2], mem[3], mem[4]};
			ycmd <= {mem[5], mem[6], mem[7], mem[8]};
			zcmd <= {mem[9], mem[10], mem[11], mem[12]};
			load <= 1;
		end
		else if(mem[0] == 2) begin
			frequency <= {mem[1], mem[2], mem[3]};
			loadFreq <= 1;
			
		end
		
	end

And here is the code that sends it from the M3:
Code:
uint32_t xCommand = 123;
uint32_t yCommand = 200;
uint32_t zCommand = 200;

src_addr[0] = 1; //0x01 for command 0x02 for velocity
src_addr[1] = xCommand >> 24; src_addr[2] = xCommand >> 16; src_addr[3] = xCommand >> 8; src_addr[4] = xCommand;
src_addr[5] = yCommand >> 24; src_addr[6] = yCommand >> 16; src_addr[7] = yCommand >> 8; src_addr[8] = yCommand;
src_addr[9] = zCommand >> 24; src_addr[10] = zCommand >> 16; src_addr[11] = zCommand >> 8; src_addr[12] = zCommand;

SPISend((uint8_t *)src_addr, 13);


I am really lost with why the static set number from the FPGA sends correctly but reading back a previously send number that operates the FPGA as expected, does not read properly.


Any ideas would be appreciated.


Thanks
Dave

it is hard to figure out the problems from those snippest you put.
from what its look like - it seem like the fpga doesn't send any data back i.e doesn't return the send_mem ,
but it's just my hipotesis, based on those snipest, and the information you supplied.
the best thing in this cases of course, is to put a logic/scope/chipescope/signal tap and just trigger the spi lines and see what's happen.
 

I have checked the SPI lines and like I said, when I set it to the static value (123456789) that comes through perfectly.

Its when I read a previously sent value, it comes back but not in the correct order ("7B 7B 00 00" instead of "00 00 00 7B") So the number is there its just losing order or endianness somehow/somewhere


Thanks
Dave
 

I have checked the SPI lines and like I said, when I set it to the static value (123456789) that comes through perfectly.

Its when I read a previously sent value, it comes back but not in the correct order ("7B 7B 00 00" instead of "00 00 00 7B") So the number is there its just losing order or endianness somehow/somewhere


Thanks
Dave

mabee you can post entire verilog spi code ?
 

Here is the SPI code (most of the SPI section came from fpga4fun.com)
Code:
module LPCFPGA(input clk,
					input SCK,
					input MOSI,
					input SSEL,
					output MISO,
					output reg step,
									);



// SPI Registers
reg [7:0] mem [0:24];
reg [7:0] memCount;
reg [7:0] sendmem [0:4];
reg [2:0] bitcnt;
reg byte_received; 
reg [7:0] byte_data_received;

// New registers
reg [31:0] xcmd;
reg [31:0] ycmd;
reg [31:0] zcmd;
reg [24:0] accum;
reg load, loadFreq;

// sync SCK to the FPGA clock using a 3-bits shift register
reg [2:0] SCKr;  always @(posedge clk) SCKr <= {SCKr[1:0], SCK};
wire SCK_risingedge = (SCKr[2:1]==2'b01);
wire SCK_fallingedge = (SCKr[2:1]==2'b10);

reg [2:0] SSELr;  always @(posedge clk) SSELr <= {SSELr[1:0], SSEL};
wire SSEL_active = ~SSELr[1];
wire SSEL_startmessage = (SSELr[2:1]==2'b10);
wire SSEL_endmessage = (SSELr[2:1]==2'b01);

reg [1:0] MOSIr;  always @(posedge clk) MOSIr <= {MOSIr[0], MOSI};
wire MOSI_data = MOSIr[1];


always @(posedge clk)
begin
  if(~SSEL_active)
    bitcnt <= 3'b000;
  else
  if(SCK_risingedge)
  begin
    bitcnt <= bitcnt + 3'b001;
    byte_data_received <= {byte_data_received[6:0], MOSI_data};
  end
end

always @(posedge clk) byte_received <= SSEL_active && SCK_risingedge && (bitcnt==3'b111);

always @(posedge clk) begin
	if(SSEL_startmessage) begin
		memCount <= 0;
	end
	else if(byte_received) begin
		mem[memCount] <= byte_data_received;
		memCount <= memCount + 1;
	end
end

always @(posedge clk) begin
	if(SSEL_startmessage)
		cnt <= 0;
	else if(byte_received) begin
		if(cnt < 3)
			cnt <= cnt+1;
		end
end
reg [7:0] byte_data_sent;
reg [7:0] cnt;


always @(posedge clk)
if(SSEL_active)
begin
  if(SSEL_startmessage)
    byte_data_sent <= sendmem[cnt];
  else
  if(SCK_fallingedge)
  begin
    if(bitcnt==3'b000)
      byte_data_sent <= sendmem[cnt];
    else
      byte_data_sent <= {byte_data_sent[6:0], 1'b0};
  end
end

assign MISO = byte_data_sent[7]; 

// Set outgoing bytes 
always @(posedge clk) begin
	if(SSEL_startmessage) begin
		sendmem[0] <= xcmd[31:24];
		sendmem[1] <= xcmd[23:16];
		sendmem[2] <= xcmd[15:8];
		sendmem[3] <= xcmd[7:0];		
		end
end

// Process the package once message is complete
always @(posedge clk) begin
	if(SSEL_endmessage) begin
		// Read the first byte for the command
		// 0x01 = position command
		if (mem[0] == 1) begin
			xcmd <= {mem[1], mem[2], mem[3], mem[4]};
			ycmd <= {mem[5], mem[6], mem[7], mem[8]};
			zcmd <= {mem[9], mem[10], mem[11], mem[12]};
			load <= 1;
		end
		// 0x02 = Velocity command
		else if(mem[0] == 2) begin
			frequency <= {mem[1], mem[2], mem[3]};
			loadFreq <= 1;
		end
	end
	
	else begin
		loadFreq <= 0;
		load <= 0;
	end
end

// Run the accumulator based on the sent frequency
always @(posedge clk) begin
	if(loadFreq)
		accum <= 0;
	else
		accum <= accum + frequency;
end

reg thing_dly;
wire pulsy;
assign pulsy = accum[24] & ~thing_dly;
always @(posedge clk) thing_dly <= accum[24];


endmodule
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top