Search Microcontrollers

Tuesday, October 28, 2014

FTDI - was it a good move?

We are all using FTDI products.
They had a great idea to bring together the MCU world with modern computers.

Back few years ago we all had serial ports on our computers and we used to interface microcontrollers and other stuff with them.
They worked ok, but they had limitations (speed, number of devices connected...) so USB was introduced.

Cool, but then all those uart based devices became hard to be connected to PCs.

FTDI invented a sort of bridge between serial and usb standards, packed in a tiny chip, not difficult to use.
Those chips are present in Arduino boards, in Launchpads, basically in most MCU or FPGA jtag programmers... which is great, well done FTDI.

Issue is that their prices are typically quite high, sometimes exceeding the cost of the MCU you need to program, which is kind of a nonsense.
Because of this a number of counterfeit chips invaded the market, damaging FTDI who rightfully holds the copyright for that technology.

FTDI then decided they had to protect their IP and investments, which is understandable and took actions.

Dave @EEVBlog explains it in detail in this video


Now the issue is that FTDI decided to BRICK -render inoperative- all products that are using counterfeit chips.
They posted a driver update for windows that sets to zero the productId stored in the flash rom of the chip, making it unrecognizable by the operating system.

Obviously the reaction of the user community was not nice to the company and they are probably going to lose several customers.
Apparently the "aggressive" driver was removed from windows update, but several products were rendered useless already.

This makes me wonder few things :

1) Am I ok for an OS like Windows to publish drivers that can potentially cause harm to whatever in my PC, without having the company responsible for the OS reviewing the source code and detecting eventual issues? This would not easily happen with Linux since drivers -excluding proprietary ones, which are by default disabled- are available in source code for the community to inspect.

2) Isn't a bit dangerous that most of the devices we use can be easily bricked via software?
Shouldn't we have some kind of repository of the config data stored in our usb devices roms, so that we could eventually re-program it if it gets damaged by malware?
Shouldn't  such data be writable only via an alternate interface, which is not connected to the PC?

3) Is maybe the time to start pushing more USB enabled MCUs and steer away from the old uart interface? Granted, usb libraries are a bit more complex to use, maybe they should be improved... but then we would not need FTDI chips anymore.

4) Shouldn't we push more for open source/hardware technology, also to protect ourselves from damages that greed (of the companies that cloned the chips and from the IP owner company as well) could damage us?

Monday, September 22, 2014

FPGA - 7 Segments LEDs and ROM - M9K 2

What did just happen?
We were discussing about RAM an now we jump into 7 segment LEDs?

Yup, but no worries, we will be back to RAM in no time, we just needed this little detour because being able to use these devices in the FPGA board will help us in testing the code we write.

We need something visible after all, right?


My FPGA Board has a 6 digit 7 segments display and I plan to use it to show some Hex numbers.
You are probably already familiar with how these things work, if you are not, then read on.
Each digit is composed of 7 leds that are lightened up to form an image we can interpret as 0,1,2,3...
To be precise normally there are 8 leds for each digit: 7 compose the digit itself and an 8th is used for the decimal point (.) .

My board interfaces a 6 digit device in this way :


There are 8 outputs each one directed to a specific LED (or series of LEDs), plus 6 lines that activate the different digits.
In other words, all the top leds are connected together, activated by the same output, all the center ones the same way etc etc.
The 6 lines that activate specific digits are used to "scan" them.

Say we want to display the value "1" in the rightmost digit.
Then we will enable ONLY the line connected to tie rightmost digit, activate the top right and bottom right leds and wait for a few milliseconds.
Then we will deactivate the line we used (the digit will be switched off), activate the one connected to the next digit, turn on the leds we need to represent the second digit, wait for the same amount of milliseconds etc... rinse and repeat.
If the scan is fast enough, to our eyes it will look like all the digits are on at the same time.

From a FPGA perspecive a viable approach would be to have one module that scans the six lines with a given clock.
Another module will activate the needed segments depending on the digit that must be displayed.

We will then change the value to be displayed by running a counter or something similar.

Since we are using a HEX display (0..F), each digit will get exactly 4 bits of our counter.
Such counter will need to cover up to 6 hex digits -> 6x4 bits -> it will be stored in a 24 bit reg.

The demo module provided with my board (designed to display a decimal number, not hex) uses the following approach :

 parameter 
     _0 = 8'b1100_0000, 
     _1 = 8'b1111_1001, 
     _2 = 8'b1010_0100,
     _3 = 8'b1011_0000, 
     _4 = 8'b1001_1001, 
     _5 = 8'b1001_0010, 
        _6 = 8'b1000_0010, 
     _7 = 8'b1111_1000, 
     _8 = 8'b1000_0000,
     _9 = 8'b1001_0000;

reg [7:0]rOne_SMG_Data;
 
 always @ ( posedge CLK or negedge RSTn )
    if( !RSTn )
      rOne_SMG_Data <= 8'b1111_1111;
     else 
      case( One_Data )       
4'd0 : rOne_SMG_Data <= _0;
        4'd1 : rOne_SMG_Data <= _1;
4'd2 : rOne_SMG_Data <= _2;
4'd3 : rOne_SMG_Data <= _3;
4'd4 : rOne_SMG_Data <= _4;
4'd5 : rOne_SMG_Data <= _5;
4'd6 : rOne_SMG_Data <= _6;
4'd7 : rOne_SMG_Data <= _7;
4'd8 : rOne_SMG_Data <= _8;
4'd9 : rOne_SMG_Data <= _9;
endcase


Basically it defines 10 parameters with the bit patterns (active low) of the digits from 0 to 9, then it does a case statement and assigns the LEDs bus the values.
I reckon it works, but, also for the sake of experimenting, I would use a different approach.
My idea is to load the bit patterns in a ROM segment (16 x 8 bit words) and while displaying the digit, access the relevant ROM location to load the pattern.

But first we need to have the demo work the way it is, maybe a little bit re-engineered, later on we will switch those parameters to ROM locations.

The original solution (from the DVDs provided with my board) was coded with a lot of redundant code, i will not get to the details, let's just say it now works the same (in Hex instead than Decimal) with less than half of the original code.
In my book that's already a good improvement, plus it was a great exercise for me.
It is possible that there were good reasons for that, possibly explained in the docs and videos supporting the code, but hey, like Sandra Bullock would say: " No hablo Chino!"  :)



The module hierarchy is represented in the image above.
The top module just wires the demo_control and the smg_interface, the first one increments the counter and the second one displays it on the seven segment display.
In my implementation the smg_interface module, besides wiring the other 3, implements a 1MS clock (used to scan the digits) and calculates which digit (position) should be displayed at any time.
The smg_control module extracts the value of the needed digit like this :


always @ ( posedge CLK or negedge RSTn )
    if( !RSTn )
  rNumber <= 4'd0;
 else
     case( Scan_line )
      0:rNumber <= Number_Sig[23:20];
         1:rNumber <= Number_Sig[19:16];
      2:rNumber <= Number_Sig[15:12];
      3:rNumber <= Number_Sig[11:8];
      4:rNumber <= Number_Sig[7:4];
      5:rNumber <= Number_Sig[3:0];
endcase

The scan_module activates one line at a time :

always @ ( posedge CLK or negedge RSTn )
   if( !RSTn )
rScan = 6'b111111;
   else 
        rScan <= ~(1 << (5-Scan_line ));  
assign Scan_Sig = rScan;

and finally the encode one activates the led segments for the current digit

 parameter _0 = 8'b1100_0000, _1 = 8'b1111_1001, _2 = 8'b1010_0100, 
   _3 = 8'b1011_0000, _4 = 8'b1001_1001, _5 = 8'b1001_0010, 
   _6 = 8'b1000_0010, _7 = 8'b1111_1000, _8 = 8'b1000_0000,
   _9 = 8'b1001_0000, _a = 8'b1000_1000, _b = 8'b1000_0011,
   _c = 8'b1100_0110, _d = 8'b1010_0001, _e = 8'b1000_0110,
  _f = 8'b1000_1110;  
 
reg [7:0]rSMG;

always @ ( posedge CLK or negedge RSTn )
    if( !RSTn )
       rSMG <= 8'b1111_1111;
    else 
       case( Number_Data )         
 4'd0 : rSMG <= _0;
 4'd1 : rSMG <= _1;
 4'd2 : rSMG <= _2;
 4'd3 : rSMG <= _3;
 4'd4 : rSMG <= _4;
 4'd5 : rSMG <= _5;
 4'd6 : rSMG <= _6;
 4'd7 : rSMG <= _7;
 4'd8 : rSMG <= _8;
 4'd9 : rSMG <= _9;  
 4'd10 : rSMG <= _a;  
 4'd11 : rSMG <= _b;  
 4'd12 : rSMG <= _c;  
 4'd13 : rSMG <= _d;  
 4'd14 : rSMG <= _e;  
                  4'd15 : rSMG <= _f;
      endcase

The result is visible in the video below.


What we now need to change is the encode module, so that it reads the segments from memory and before that we need to create a ROM memory and populate it with the segment data.

Megawizard plugin allows to create a 16 x 8 bit ROM and populate it with a mif file (see previous post, same steps, but this time I chose 1 Port ROM instead of RAM).



Then we simply substitute the encode module with the newly created rom module in smg_interface:

// remove the old one 
    /*smg_encode_module U2
(
    .CLK( clk2 ),
     .RSTn( RSTn ),
     .Number_Data( Number_Data ),   // input - from U2
     .SMG_Data( SMG_Data )          // output - to top
);*/

// add the new one 
digit_rom rom(
  .address(Number_Data),
  .clock(clk2),
  .q(SMG_Data)
);

Done!
Can it get any simpler than that?
And yes, it works of course, will not upload a video proof as it is boringly identical to the previous, but it really works!