Is the SanDisk Ultra microSD with oemid “PT” a counterfeit card?

I’m writing a SD/MMC NuttX driver for LPC43xx and today a bought a SanDisk Ultra 16GB microSD to do some test because my old SD Cards are slow and counterfeited cards.

First let put it on Linux and see what we get:

$ cat /sys/class/mmc_host/mmc0/mmc0\:0007/cid 

$ cat /sys/class/mmc_host/mmc0/mmc0\:0007/csd

$ cat /sys/class/mmc_host/mmc0/mmc0\:0007/date

$ cat /sys/class/mmc_host/mmc0/mmc0\:0007/erase_size

$ cat /sys/class/mmc_host/mmc0/mmc0\:0007/fwrev

$ cat /sys/class/mmc_host/mmc0/mmc0\:0007/hwrev 

$ cat /sys/class/mmc_host/mmc0/mmc0\:0007/manfid 

$ cat /sys/class/mmc_host/mmc0/mmc0\:0007/name 

$ cat /sys/class/mmc_host/mmc0/mmc0\:0007/oemid

$ cat /sys/class/mmc_host/mmc0/mmc0\:0007/scr

$ cat /sys/class/mmc_host/mmc0/mmc0\:0007/serial 

$ cat /sys/class/mmc_host/mmc0/mmc0\:0007/type 

At first I noted the oemid 0x5054 (“PT”) a little bit strange.
Then searching for it I found this thread:

Then decided to test using flashbench:

$ sudo apt-get install flashbench

$ sudo flashbench -a /dev/mmcblk0 --blocksize=1024
align 4294967296	pre 1.33ms	on 1.65ms	post 1.35ms	diff 308µs
align 2147483648	pre 1.34ms	on 1.66ms	post 1.36ms	diff 308µs
align 1073741824	pre 1.33ms	on 1.65ms	post 1.34ms	diff 312µs
align 536870912	pre 1.35ms	on 1.65ms	post 1.35ms	diff 306µs
align 268435456	pre 1.35ms	on 1.64ms	post 1.35ms	diff 290µs
align 134217728	pre 1.34ms	on 1.67ms	post 1.34ms	diff 324µs
align 67108864	pre 1.34ms	on 1.64ms	post 1.34ms	diff 298µs
align 33554432	pre 1.34ms	on 1.67ms	post 1.36ms	diff 316µs
align 16777216	pre 1.35ms	on 1.64ms	post 1.36ms	diff 287µs
align 8388608	pre 1.32ms	on 1.68ms	post 1.36ms	diff 342µs
align 4194304	pre 1.36ms	on 1.64ms	post 1.37ms	diff 278µs
align 2097152	pre 1.36ms	on 1.6ms	post 1.35ms	diff 241µs
align 1048576	pre 1.36ms	on 1.6ms	post 1.34ms	diff 250µs
align 524288	pre 1.36ms	on 1.61ms	post 1.36ms	diff 250µs
align 262144	pre 1.36ms	on 1.59ms	post 1.35ms	diff 238µs
align 131072	pre 1.32ms	on 1.59ms	post 1.34ms	diff 261µs
align 65536	pre 1.34ms	on 1.6ms	post 1.35ms	diff 252µs
align 32768	pre 1.35ms	on 1.59ms	post 1.33ms	diff 253µs
align 16384	pre 1.35ms	on 1.58ms	post 1.35ms	diff 227µs
align 8192	pre 1.36ms	on 1.47ms	post 1.37ms	diff 108µs
align 4096	pre 1.36ms	on 1.58ms	post 1.36ms	diff 222µs
align 2048	pre 1.38ms	on 1.39ms	post 1.37ms	diff 8.03µs

$ sudo flashbench -O /dev/mmcblk0 --open-au-nr=1 --random
4MiB    4.43M/s 
2MiB    3.5M/s  
1MiB    14.1M/s 
512KiB  2.97M/s 
256KiB  2.9M/s  
128KiB  3.44M/s 
64KiB   2.53M/s 
32KiB   1.76M/s 
16KiB   1.65M/s 

$ sudo flashbench -O /dev/mmcblk0 --open-au-nr=2 --random
4MiB    7.37M/s 
2MiB    4.01M/s 
1MiB    13.9M/s 
512KiB  3.56M/s 
256KiB  3.3M/s  
128KiB  2.77M/s 
64KiB   2.26M/s 
32KiB   2.14M/s 
16KiB   1.86M/s 

$ sudo flashbench -O /dev/mmcblk0 --open-au-nr=4 --random
4MiB    4.88M/s 
2MiB    4.57M/s 
1MiB    7.14M/s 
512KiB  3.26M/s 
256KiB  2.98M/s 
128KiB  2.66M/s 
64KiB   2.7M/s  
32KiB   2.16M/s 
16KiB   1.8M/s  

$ sudo flashbench -O /dev/mmcblk0 --open-au-nr=8 --random
4MiB    5.31M/s 
2MiB    3.93M/s 
1MiB    11.8M/s 
512KiB  3.18M/s 
256KiB  3.03M/s 
128KiB  2.74M/s 
64KiB   2.57M/s 
32KiB   2.25M/s 
16KiB   1.86M/s 

$ sudo flashbench -O /dev/mmcblk0 --open-au-nr=9 --random
4MiB    3.37M/s 
2MiB    3.7M/s  
1MiB    12.2M/s 
512KiB  3.2M/s  
256KiB  2.92M/s 
128KiB  2.87M/s 
64KiB   2.58M/s 
32KiB   2.27M/s 
16KiB   1.87M/s 

$ sudo flashbench -O /dev/mmcblk0 --open-au-nr=10 --random
4MiB    3.34M/s 
2MiB    3.12M/s 
1MiB    3.86M/s 
512KiB  1.99M/s 
256KiB  1.31M/s 
128KiB  663K/s  
64KiB   285K/s  
32KiB   135K/s  
16KiB   67.4K/s 

I got a little bit better results, but still bad results.

It doesn’t make any sense Sandisk put a Class 10 label in a microSD card that can’t sustain 10MB/s write speed.

If Sandisk insist it is original, then I suspect Sandisk is doing the same Kingston’s game: it is delivering low quality card to “black” market, see:

Too bad for a Sandisk Ultra microSD (here in Brazil I paid about U$ 15.00).

Tips to get Ethernet working on NuttX

I want to share here my experience to get Ethernet working on Bambino 200E board. In fact after you realize what needs to be done life become easy.

Almost all microcontroller with Ethernet MAC needs an external PHY chip to convert its signal to the physical media’s signal (in the twister pair cable). Normally this PHY communicate with the microcontroller using MII (Media-Independent Interface) or RMII (Reduced Media-Independent Interface) protocol.

So the first thing you need to find is the PHY Address used for your board’s PHY. The Bambino 200E uses the Micrel KSZ8031RNL and because there is not a Pull-UP resistor in the CRS_DV/PHYAD[1:0] the PHY Address will be 0, then you need to define it in your configuration:


And since the KSZ8031 support Auto Negotiation to detect the Ethernet mode and speed you need to define it:


Now comes the trick part, you need to setup the PHYSR (Status Register). The PHYSR is basically the address of the register where the PHY informs about the Auto Negotiation status.

So initially you could think it is the Basic Status register (at 1h), but the Basic Status is used to inform which modes and speeds your Ethernet router/hub/switch supports.

The right register in in fact the “PHY Control 1” (1Eh = 30). See the Operation Mode Indication field bits (1E.2:0) :

[000] = still in auto-negotiation
[001] = 10Base-T half-duplex
[010] = 100Base-TX half-duplex
[011] = reserved
[100] = reserved
[101] = 10Base-T full-duplex
[110] = 100Base-TX full-duplex
[111] = reserved

So, we need to define the following configuration to get Ethernet working:


I spent almost a working day to get Ethernet working, if I was aware of the above information it should matter of few minutes to get everything working.

CUDA compilation error

mkdir -p ./bin 
/usr/bin/nvcc -I/usr/include -O2 -Xcompiler -fPIC -o bin/out/ProgramCU.o src/pba/ -c
src/pba/ warning: statement is unreachable

src/pba/ warning: statement is unreachable

/usr/include/string.h: In function ‘void* __mempcpy_inline(void*, const void*, size_t)’:
/usr/include/string.h:652:42: error: ‘memcpy’ was not declared in this scope
   return (char *) memcpy (__dest, __src, __n) + __n;
src/pba/ In member function ‘void CuTexImage::BindTexture(textureReference&)’:
src/pba/ warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘size_t {aka long unsigned int}’ [-Wformat=]
     if(sz > MAX_TEXSIZE) fprintf(stderr, "cudaBindTexture: %d > %d\n", sz , MAX_TEXSIZE); 
src/pba/ In function ‘bool ProgramCU::ShuffleCameraJacobian(CuTexImage&, CuTexImage&, CuTexImage&)’:
src/pba/ warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘size_t {aka long unsigned int}’ [-Wformat=]
         fprintf(stderr, "datasize way too big %d, %d+...\n", szjc, (szjc)/ MAX_TEXSIZE); 
src/pba/ warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘size_t {aka long unsigned int}’ [-Wformat=]
makefile:49: recipe for target 'bin/out/ProgramCU.o' failed
make: *** [bin/out/ProgramCU.o] Error 1

Fix: open the makefile and replace:

NVCC_FLAGS = -I$(CUDA_INC_PATH) -O2 -Xcompiler -fPIC