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.

To send a grayscale image from PC to fpga via RS232

Status
Not open for further replies.

lucky

Newbie level 6
Joined
Aug 30, 2010
Messages
12
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,365
Is it possible to send a grayscale image matrix from PC to fpga via RS232.
If yes, how do i input this matrix in hyperterminal??
i'm planning to store the image pixel values in a text file. Is there any particular format in which i need to store these pixels, like binary, ascii etc??

I'm doing image processing in fpga (virtex 4 )and this is my initial step. Hoping somebody would be able to help me with this...

Thanks in advance
 

lucky,

Yes it is possible to send a greyscale image matrix from PC to FPGA via RS232.
All you need is a RS232 interface in the FPGA and some logic or processor to handle the input from the RS232 interface within the FPGA. You could store it in a RAM in the FPGA. I assume there is a RS232 port on the PC.

The format of the data, I will guess is some kind of binary number, a grey value. This could be an 8 bit value, or more, but it depends on what you have to provide as a output. You may want to reformat the data in the FPGA if it is faster. I would go for binary coding, it gives the most in the least number of bits.

Sckoarn
 

Thank u soo much 4 ur quick reply.. i'll try it out

---------- Post added at 12:50 ---------- Previous post was at 12:05 ----------

how do i store the image matrix into a text file in matlab?? if i save it as "filename -ascii "will i be able to take it into hyperterminal??
 

lucky,

I have no experience with Matlab, but ... you should be able to store information is several formats, hex, bin, ascii with some kind of fprintf(formatting) construct.

I do not see any reason why hyperterminal could not send any format. I have not used hyperterminal much myself, I usually build my own transfer software when I connect to custom logic.

Sckoarn
 

Thank u very much 4 ur ideas Sckoran
Hyperterminal can take text files. It has worked 4 PC 2 PC communication. Now i only need 2 convert my image into a text file. And then write a vhdl code 4 receiving each pixel.
Problem is the conversion of image to text file.
 

lucky,
You should be able to send an eight bit value in an ascii format. If the pixel value is more than eight bits, you will have to send two or more words per pixel.

Your VHDL code could be a regular RS232 reciever and all you have to do is build a state machine on the other side of the RS232 reciever to put the words back together.

Hyperterminal does not care what kind of data is in the file, or it shouldn't. If it is just doing a file transfer, it should not matter what format the data is in.

That said, I am not sure why you would want to convert the image file/data array, to a text file.

Sckoarn
 

oky Sckoran

so r u telling me i can send an image as such through hyperterminal?? My image files are in image file formats. I tried b/w 2 PCs but i cant do it. i havent got a data array. The 1 got through matlab is not like the pixels in my image. there are some pixels missing and all. (i found this out when i did PC to PC commn)

In hyperterminal there is an option called "send file" but a protocol needs to be chosen i have no idea which protocol to choose.

i have to store each of these pixels into ddrram of fpga in the same order as the image pixels and then use this 4 image processing

i duuno if my concpet of passing pixels through RS232 is rite
hoping 4 help and correction
thank u
 

lucky,

I am surprised that someone has not jumped in with more suggestions.

I am not familure with hyperterminal. If you have to pick a protocol, then on the recieving end you may have to implement the protocol in order to transfer files. I do not know what that involves, but you should be able to look up any of the selections on the web.

Personally, I would write my own transfer program in tcl/tk. That way I would have complete control over the whole process. I find tcl has good serial com support and it is easy to create a working program. Of course any scripting language could probably do the same thing.

Looks like knowing exactly what is in your image file and how the data is coded in it would be a good thing to know. An image, far as I know, has to be some kind of an array of data.

Your idea of passing the data through an RS232 link is sound. It is one of the most simple and inexpensive ways to transfer data from point to point. But, if your data is very large, you may find the time it takes to transfer the data is too long.

Sckoarn
 

hey,,, even my project is similar... i am very new to fpgas... i have an ml402 fpga... there is an rs232 port available on the kit.. i have to send data serially from pc to fpga and vice versa using system generator (ise) through the rs 232 cable... i have no idea...
first i connect the cable from pc to fpga...
my data is in the form of 8 bit binary numbers...
do i make an sram and store the values/?
do i have to meke a uart module or is it included in the kit??
how to i map the memory in the fpga using system generator???
plzzzz help
 

tapsiahuja,
I would expect that you would want to store your data from the RS-232 link. The link is so slow that your logic will be starved for data if you don't store it first. I would say yes to the SRAM storage. A uart is not a difficult thing to code up, but if it is in your kit, you could just use it. I have ISE tools but can not seem to find the system generator you refer to. Writing code for a memory is very easy as well, just an array with some control logic around it ... simpile. First step, just get the RS-232 link loading into memory and then reading it back to test the data is correct. This is all you state in your project.

Between your RAM and the RS-232 interface block, you will have to put in a command decoder. The RS-232 link facilitates the physical link, but it does not provide the protocol to enable you to read and write locations in the RAM. So, you break your protocol into write and read commands. The first word received by the RS-232 link is your command word. There are enough bits to enable a good protocol to be implemented in one 8 bit word. As an example:

First Byte
BIT Meaning
7 Read/Write Command, 0 = Read 1 = Write
6-0 word count. 0 = 1 word transfer. others = binary number +1

Second Byte and if needed Third Byte
The next byte or two contains the address of the operation, in the case of multi word transfer, this address is incremented through the count.

The logic to implement this should be a simple state machine. I have personally implemented this in a self detecting buad rate debug interface. It was fun.

Hope that helps some.
Sckoarn
 

hey thanku sooo much...
i have the rs 232 cable... havent ever used it..
ques1) how to i load the link in the memory?? after connecting the cable directly...
ques 2) how to put a command decoder... is there a code for it... i use verilog and i hv coded fifo buffer cn u suggest me how to use it to accept the 8 bit binary nos at positive edges of clock..
and what potocol r u toking about.... no clue...
please elaborate how to generate it...
if u cn send me an overview or small codes of ur implementation il b greatful... my is is ahuja.tapsi@gmail.com
plz help me if u cn.. il more than gratefull
 

tapsiahuja,
Ok, you need to do some reading. Read up on the RS-232 protocol. This will tell you about the signalling and what the bits of each word are for.
This will give you more understanding about the link other than the cable. You need to know more there.

Once you understand that, my post might make more sense. The protocol block between memory and RS-232 interface is custom logic, there will be no way to do it other than code it yourself.
I only know VHDL so I have no examples for you.

The protocol I was refering to, is implemented using data received from the RS-232 link. The first data is command and address data, then data. So if you only need 8 bits of address decode for your RAM access, you could implement the protocol with two data bytes from the RS-232 link that control read/write state machine for memory access. First byte indecates read or write, the second byte is the address. Your state machine takes this data and applies it to the RAM in the form of enables, r/w select, and address. The next word or words, from the RS-232 link will be data in the case of a write. In the case of a read, the state machine will have to access the RAM and put the bytes out on the link though the RS-232 controller.

I can not help you with Verilog code.

Sckoarn
 

hey... cn u send me some reliable source of information for the protocol... i found this RS-232 Serial Protocol...
and cn thi b used as protocol

parameter AddressSize = 1;
parameter WordSize = 1;

input [AddressSize-1:0] Address;
inout [WordSize-1:0] Data;
input CS, WE, OE;

reg [WordSize-1:0] Mem [0:1<<AddressSize];

assign Data = (!CS && !OE) ? Mem[Address] : {WordSize{1'bz}};

always @(CS or WE)
if (!CS && !WE)
Mem[Address] = Data;

always @(WE or OE)
if (!WE && !OE)
$display("Operational error in RamChip: OE and WE both active");

endmodule

send me the protocol in vhdl only i n understand the logic ...
 

tapsiahuja,
I am sorry but I can not send you code. I looked it over and I do not think it is simple enough for you to use. I will try one more time to describe the protocol.

One protocol is the RS-232 link physical signalling that moves bytes of data. You need a serial to parallel converter to implement it.

The second protocol uses the data to control the state of your read and write cycles. When in idle state, you receive the first byte, decode it and begin walking through your state machine. This is all basic stuff that you may have to go through to get the best value from the effort. Here is the VHDL of the state machine:

Code:
---------------------------------------------------------------------
--  register and IO access state machine
command_state:
  process(rst_n, clk)
  begin
    if(rst_n   =  '0') then
      user_reg  <=  (others => '0');
      cmdstate  <=  init;
      iostate   <=  addr_rx;
      byte_cnt  <=  0;
      frame_cnt <=  "000000";
      
      ioaddr  <=  (others => '0');
      iodatao  <=  (others => '0');
      iodatai  <=  (others => '0');
      iorwn   <=  '1';
      iosel   <=  '0';
      txdata    <=  (others => '0');
      tx_en        <=  '0';
      realign      <=  '0';
      
      ctl_reg  <=  (others => '0');
--      stat_reg <=  (others => '0');
      
    elsif(clk'event and clk = '1') then
      tx_en        <=  '0';
      realign      <=  '0';
      -- on startup wait for rx to be idle
      case cmdstate is
        when init  =>
          if(rxstate  =  idle) then
            cmdstate  <=  idle;
          end if;
        -- once in idle state decode the first incoming byte
        when idle  =>
          iosel   <=  '0';
          iorwn   <=  '1';
          byte_cnt     <=  0;
          if(new_rx =  '1') then
            if(rx_ddata(7 downto 6) = "10") then
              cmdstate  <=  io_rd;
              frame_cnt <=  rx_ddata(5 downto 0);
            elsif(rx_ddata(7 downto 6) =  "11") then
              cmdstate  <=  io_wr;
              frame_cnt <=  rx_ddata(5 downto 0);
            else
              case rx_ddata(5 downto 0) is
                when "010000" =>
                  cmdstate  <=  reg_wr;
                when "010001" =>
                  txdata    <=  ctl_reg;
                  tx_en     <=  '1';
                  cmdstate  <=  reg_rd;
                when "010100" =>
                  txdata    <=  stat_reg;
                  tx_en     <=  '1';
                  cmdstate  <=  reg_rd;
                when "011000" =>
                  cmdstate  <=  reg_wr;
                when "011001" =>
                  txdata    <=  user_reg;
                  tx_en     <=  '1';
                  cmdstate  <=  reg_rd;
                when others =>
                  null;
              end case;
            end if;
          end if;
        -- wait here till tx is done writing out register
        when reg_rd  =>
          if(tx_done = '1') then
            cmdstate  <=  idle;
          end if;
          
        -- write next data into the addressed writeable register
        when reg_wr  =>
          if(new_rx =  '1') then
            case rx_ddata(5 downto 0) is
              when "010000" =>
                ctl_reg  <=  rx_wdata;
                ctl_reg(0)  <=  '0';
                realign  <=  rx_wdata(0);
              when "011000" =>
                user_reg  <=  rx_wdata;
              when others =>
                null;
            end case;
            cmdstate  <=  idle;
          end if;
          
        -- IO read cycle
        when io_rd  =>
          case iostate is
            when addr_rx =>
              if(new_rx =  '1') then
                case byte_cnt is
                  when 0 =>
                    ioaddr(15 downto 8)    <=  rx_wdata;
                    byte_cnt  <=  byte_cnt + 1;
                  when 1 =>
                    ioaddr(7 downto 0)    <=  rx_wdata;
                    byte_cnt  <=  byte_cnt + 1;
                    iosel   <=  '1';
                    iorwn   <=  '1';
                    iostate   <=  ack_wait;
                  when others =>
                    null;
                end case;
              end if;
              
            when ack_wait  =>
              if(if_in.ack = '1') then
                iodatai     <=  if_in.data;
                iostate   <=  tx_start;
                byte_cnt  <=  0;
              end if;
              
            when tx_start  =>
              iosel   <=  '0';
              if(byte_cnt  = 0) then
                txdata    <=  iodatai(15 downto 8);
                tx_en     <=  '1';
                iostate   <=  tx_wait;
              else
                txdata    <=  iodatai(7 downto 0);
                tx_en     <=  '1';
                iostate   <=  tx_wait;
              end if;
              
            when tx_wait   =>
              if(tx_done = '1') then
                if(byte_cnt  = 0) then
                  iostate   <=  tx_start;
                  byte_cnt  <=  byte_cnt + 1;
                elsif(frame_cnt = "000000") then
                  iostate   <=  addr_rx;
                  cmdstate  <=  idle;
                else
                  byte_cnt  <=  0;
                  ioaddr(15 downto 0)    <=  ioaddr(15 downto 0) + 1;
                  frame_cnt <= frame_cnt - "000001";
                  iostate   <=  ack_wait;
                  iosel   <=  '1';
                end if;
              end if;
            
          end case;
          
        -- and IO write cycle, no wait for ack
        when io_wr  =>
          iosel   <=  '0';
          if(new_rx =  '1') then
            case byte_cnt is
              when 0 =>
                ioaddr(15 downto 8)  <=  rx_wdata;
                byte_cnt  <=  byte_cnt + 1;
              when 1 =>
                ioaddr(7 downto 0)  <=  rx_wdata;
                byte_cnt  <=  byte_cnt + 1;
              when 2 =>
                iodatao(15 downto 8)  <=  rx_wdata;
                byte_cnt  <=  byte_cnt + 1;
              when 3 =>
                iodatao(7 downto 0)  <=  rx_wdata;
                iosel   <=  '1';
                iorwn   <=  '0';
                if(frame_cnt = "000000") then
                  cmdstate  <=  idle;
                else
                  byte_cnt  <=  byte_cnt + 1;
                  frame_cnt <= frame_cnt - "000001";
                end if;
              when 4 =>
                iodatao(15 downto 8)  <=  rx_wdata;
                byte_cnt  <=  byte_cnt + 1;
                ioaddr(15 downto 0)    <=  ioaddr(15 downto 0) + 1;
                
              when 5 =>
                iodatao(7 downto 0)  <=  rx_wdata;
                iosel   <=  '1';
                iorwn   <=  '0';
--                byte_cnt  <=  4;
                if(frame_cnt = "000000") then
                  cmdstate  <=  idle;
                else
                  frame_cnt <= frame_cnt - "000001";
                  byte_cnt  <=  4;
                end if;
              when 6 =>
              when 7 =>
              when others =>
            end case;
          end if;
          
      end case;
    end if;
end process command_state;


This system is for a 16 bit transfer size. You will have to modify for other sizes.
I have used this in an FPGA and is part of a debug interface I coded, as metioned previously.

Sckoarn
 
Last edited:

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top