Tuesday, February 28, 2017

raspberry pi camera

python3
sudo apt-get install python3-picamera
https://www.raspberrypi.org/documentation/usage/camera/python/README.md


allow cv2.VideoCapture(0)
sudo modprobe bcm2835-v4l2

allow user access camera
sudo usermod XXXX -a -G video

single image display
import cv2
im = cv2.imread('test.jpg')
cv2.imshow('image', im)
cv2.waitKey()

video display
import cv2
ca = cv2.VideoCapture(0)
cv2.startWindowThread()
cv2.namedWindow('preview')
while True:
  _,  im = ca.read()
  cv2.imshow('preview', im)
  key = cv2.waitKey(1) & 0xFF
  if key == ord('q'):
    break

Monday, February 27, 2017

open cv 3 on ubuntu


sudo apt-get install build-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev
sudo apt-get update
cd opencv-3.2.0/
mkdir build
cd build/
sudo apt-get install python3-dev
sudo apt-get install java-7-openjdk
sudo pip3 install --upgrade pip
sudo pip3 install numpy
export PYTHON3_EXECUTABLE=/usr/bin/python3
export PYTHON_INCLUDE_DIR=/usr/include/python3
export PYTHON_INCLUDE_DIR=/usr/include/python3.4
export PYTHON_INCLUDE_DIR2=/usr/include/x86_64-linux-gnu/python3.4m/
export PYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.4m.so
export PYTHON3_NUMPY_INCLUDE_DIRS=/usr/local/lib/python3.4/dist-packages/numpy/core/include/
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
sudo make -j4
sudo make install

For raspberry pi 3:
sudo apt-get install build-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install python3-dev python3-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev


export PYTHON3_EXECUTABLE=/usr/bin/python3
export PYTHON_INCLUDE_DIR=/usr/include/python3.4

export PYTHON_INCLUDE_DIR2=/usr/include/arm-linux-gnueabihf/python3.4m/
export PYTHON_LIBRARY=/usr/lib/arm-linux-gnueabihf/libpython3.4m.so
export PYTHON3_NUMPY_INCLUDE_DIRS=/usr/local/lib/python3.4/dist-packages/numpy/core/include/
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_NEW_PYTHON_SUPPORT=ON -D WITH_QT=OFF -D WITH_TBB=OFF ..
http://stackoverflow.com/questions/26371187/how-can-i-disable-opengl-support-opencv

Sunday, February 26, 2017

tensorflow cifar10

https://www.tensorflow.org/tutorials/deep_cnn

First time the training is very slow.
On GTX 970,  ~33 hours.
On GTX 860m, ~40 hours.
On Raspberry pi 3, ~200 hours.

I decided to use GTX 860m to train and will update back after 40 hours. (20170226, 9AM)

Or I am thinking of using multiple GTX860m on multiple PCs.  I have 3 of them.
https://www.tensorflow.org/deploy/distributed

cifar10_image.py: This is a short script displaying 32x32 images from cifar10 bin file
import numpy as np
import PIL.Image

#display larger images
def DisplayPicture(byte, fmt='jpeg'):
print(byte[0])
a = np.fromstring(byte[1:3073], dtype=np.uint8)
b = np.reshape(a, (3, 1024))
c = b.T
d = np.concatenate([c, c, c, c, c, c, c, c], axis=1)
e = np.reshape(d, [32, 32*3*8])
f = np.concatenate([e, e, e, e, e, e, e, e], axis=1)
g = np.reshape(f, [1, 3072*8*8])
im = PIL.Image.frombytes('RGB', (32*8,32*8), g)
im.show()

#open file 
#read an image
#record format: 1 byte type, 1024 byte red, 1024 byte green, 1024 byte blue
#32 x 32, row-major
f = open('data_batch_1.bin', 'rb')
byte = f.read(3073)
while byte != '':
DisplayPicture(byte)
byte = f.read(3073)
f.close




Further reading:
https://www.cs.toronto.edu/~kriz/cifar.html
http://groups.csail.mit.edu/vision/TinyImages/

Saturday, February 25, 2017

tensorflow Mandelbrot example

The last two lines of DisplayFractal() will show the picture.   The https://www.tensorflow.org/tutorials/mandelbrot is not correct.

# Import libraries for simulation
import tensorflow as tf
import numpy as np

# Imports for visualization
import PIL.Image
from io import BytesIO
#from IPython.display import Image, display

def DisplayFractal(a, fmt='jpeg'):
  """Display an array of iteration counts as a
     colorful picture of a fractal."""
  a_cyclic = (6.28*a/20.0).reshape(list(a.shape)+[1])
  img = np.concatenate([10+20*np.cos(a_cyclic),
                        30+50*np.sin(a_cyclic),
                        155-80*np.cos(a_cyclic)], 2)
  img[a==a.max()] = 0
  a = img
  a = np.uint8(np.clip(a, 0, 255))
  #f = BytesIO()
  #PIL.Image.fromarray(a).save(f, fmt)
  #display(Image(data=f.getvalue()))
  im = PIL.Image.fromarray(a)
  im.show()

sess = tf.InteractiveSession()
# Use NumPy to create a 2D array of complex numbers

Y, X = np.mgrid[-1.3:1.3:0.005, -2:1:0.005]
Z = X+1j*Y

xs = tf.constant(Z.astype(np.complex64))
zs = tf.Variable(xs)
ns = tf.Variable(tf.zeros_like(xs, tf.float32))

tf.global_variables_initializer().run()

# Compute the new values of z: z^2 + x
zs_ = zs*zs + xs

# Have we diverged with this new value?
not_diverged = tf.abs(zs_) < 4

# Operation to update the zs and the iteration count.
#
# Note: We keep computing zs after they diverge! This
#       is very wasteful! There are better, if a little
#       less simple, ways to do this.
#
step = tf.group(
  zs.assign(zs_),
  ns.assign_add(tf.cast(not_diverged, tf.float32))
  )

for i in range(200): step.run()
#DisplayFractal(ns.eval())


media download

http://www.stormcolin.com/cmedia/

Friday, February 24, 2017

expand ubuntu partition on vmwave esxi 5

Original

admin@droneteambasevm:~$ df -k                                                        
Filesystem                             1K-blocks    Used Available Use% Mounted on    
/dev/mapper/UbntSR--vCAC--Tmp--vg-root  14048320 3345632   9966024  26% /        
none                                           4       0         4   0% /sys/fs/cgroup
udev                                     3042888       4   3042884   1% /dev     
tmpfs                                     610808    3036    607772   1% /run     
none                                        5120       0      5120   0% /run/lock 
none                                     3054024       0   3054024   0% /run/shm 
none                                      102400       0    102400   0% /run/user 
/dev/sda1                                 240972   38813    189718  17% /boot

admin@droneteambasevm:~$ sudo fdisk -l                               
[sudo] password for admin:                                           
                                                                     
Disk /dev/sda: 107.4 GB, 107374182400 bytes                          
255 heads, 63 sectors/track, 13054 cylinders, total 209715200 sectors
Units = sectors of 1 * 512 = 512 bytes                               
Sector size (logical/physical): 512 bytes / 512 bytes                
I/O size (minimum/optimal): 512 bytes / 512 bytes                    
Disk identifier: 0x000a8393                                          
                                                                     
   Device Boot      Start         End      Blocks   Id  System       
/dev/sda1   *        2048      499711      248832   83  Linux        
/dev/sda2          501758    33552383    xxxxxxxx    5  Extended     
/dev/sda5          501760    33552383    xxxxxxxx   83  Linux        

Step 1:
sudo fdisk /dev/sda
d 5
d 2
n 2 (extended)
n 5 (logical 501760 to 33552383)
n 6 (logical reset)
t 5 8e
t 6 8e
p

This is results.
Command (m for help): p

Disk /dev/sda: 107.4 GB, 107374182400 bytes
255 heads, 63 sectors/track, 13054 cylinders, total 209715200 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000a8393

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      499711      248832   83  Linux
/dev/sda2          499712   209715199   104607744    5  Extended
/dev/sda5          501760    33552383    16525312   8e  Linux LVM
/dev/sda6        33554432   209715199    88080384   83  Linux LVM

sudo reboot

Step 2:
admin@droneteambasevm:~$ sudo vgextend UbntSR-vCAC-Tmp-vg /dev/sda6
[sudo] password for admin:
  No physical volume label read from /dev/sda6
  Physical volume "/dev/sda6" successfully created
  Volume group "UbntSR-vCAC-Tmp-vg" successfully extended
admin@droneteambasevm:~$ sudo lvextend -L +84G /dev/UbntSR-vCAC-Tmp-vg/root
  Extending logical volume root to 97.74 GiB
  Logical volume root successfully resized
admin@droneteambasevm:~$ df -k
Filesystem                             1K-blocks    Used Available Use% Mounted on
/dev/mapper/UbntSR--vCAC--Tmp--vg-root  14048320 3347364   9964292  26% /
none                                           4       0         4   0% /sys/fs/cgroup
udev                                     3042888       4   3042884   1% /dev
tmpfs                                     610808    3040    607768   1% /run
none                                        5120       0      5120   0% /run/lock
none                                     3054024       0   3054024   0% /run/shm
none                                      102400       0    102400   0% /run/user
/dev/sda1                                 240972   38813    189718  17% /boot
admin@droneteambasevm:~$ sudo resize2fs /dev/UbntSR-vCAC-Tmp-vg/root
resize2fs 1.42.9 (4-Feb-2014)
Filesystem at /dev/UbntSR-vCAC-Tmp-vg/root is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 7
The filesystem on /dev/UbntSR-vCAC-Tmp-vg/root is now 25621504 blocks long.

admin@droneteambasevm:~$ df -k
Filesystem                             1K-blocks    Used Available Use% Mounted on
/dev/mapper/UbntSR--vCAC--Tmp--vg-root 100746672 3364584  93122788   4% /
none                                           4       0         4   0% /sys/fs/cgroup
udev                                     3042888       4   3042884   1% /dev
tmpfs                                     610808    3040    607768   1% /run
none                                        5120       0      5120   0% /run/lock
none                                     3054024       0   3054024   0% /run/shm
none                                      102400       0    102400   0% /run/user
/dev/sda1                                 240972   38813    189718  17% /boot


Tuesday, February 21, 2017

tensorflow 1.0 on raspberry pi 3

Still ongoing.

Reference:
https://github.com/samjabrahams/tensorflow-on-raspberry-pi/blob/master/GUIDE.md


bazel:
/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java
Add @ 600th line
    } catch (InterruptedException e) {
      throw new RepositoryFunctionException(
          new IOException("thread interrupted"), Transience.TRANSIENT);

tensorflow:
git clone --recurse-submodules https://github.com/tensorflow/tensorflow
git checkout r1.0
cd tensorflow
...

/WORKSPACE
manually change the url line for numericjs_numeric_min_js to the following
url = "http://numericjs.com/numeric/lib/numeric-1.2.6.min.js",

Then, ./configure

Monday, February 13, 2017

Atheros ath9k CSI Tools

https://github.com/xieyaxiongfly/Atheros-CSI-Tool

Kernel Version 4.1.10

Diff with the origin...  Could it be ported?

diff -uNr linux-4.1.10/arch/sh/boot/compressed/vmlinux.scr Atheros-CSI-Tool/arch/sh/boot/compressed/vmlinux.scr
--- linux-4.1.10/arch/sh/boot/compressed/vmlinux.scr 2015-10-03 07:49:38.000000000 -0400
+++ Atheros-CSI-Tool/arch/sh/boot/compressed/vmlinux.scr 1969-12-31 19:00:00.000000000 -0500
@@ -1,10 +0,0 @@
-SECTIONS
-{
-  .rodata..compressed : {
- input_len = .;
- LONG(input_data_end - input_data) input_data = .;
- *(.data)
- output_len = . - 4;
- input_data_end = .;
- }
-}
diff -uNr linux-4.1.10/arch/sh/boot/romimage/vmlinux.scr Atheros-CSI-Tool/arch/sh/boot/romimage/vmlinux.scr
--- linux-4.1.10/arch/sh/boot/romimage/vmlinux.scr 2015-10-03 07:49:38.000000000 -0400
+++ Atheros-CSI-Tool/arch/sh/boot/romimage/vmlinux.scr 1969-12-31 19:00:00.000000000 -0500
@@ -1,8 +0,0 @@
-SECTIONS
-{
-  .text : {
- zero_page_pos = .;
- *(.data)
- end_data = .;
- }
-}
diff -uNr linux-4.1.10/drivers/net/wireless/ath/ath9k/ar9003_csi.c Atheros-CSI-Tool/drivers/net/wireless/ath/ath9k/ar9003_csi.c
--- linux-4.1.10/drivers/net/wireless/ath/ath9k/ar9003_csi.c 1969-12-31 19:00:00.000000000 -0500
+++ Atheros-CSI-Tool/drivers/net/wireless/ath/ath9k/ar9003_csi.c 2017-02-13 17:33:46.943579002 -0500
@@ -0,0 +1,325 @@
+/*
+ * =====================================================================================
+ *       Filename:  ath9k_csi.c
+ *
+ *    Description:  extrac csi and data together from hardware
+ *        Version:  1.0
+ *
+ *         Author:  Yaxiong Xie 
+ *         Email :  <xieyaxiongfly@gmail.com>
+ *   Organization:  WANDS group @ Nanyang Technological University 
+ *
+ *   Copyright (c)  WANDS group @ Nanyang Technological University
+ * =====================================================================================
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/wait.h>
+#include <linux/netdevice.h>
+
+#include "ar9003_csi.h"
+#include "ar9003_mac.h"
+#include "ar9003_phy.h"
+#include "mac.h"
+#include "hw.h"
+
+#define Tx_Buf_LEN      20480                 // Generally, buffere with 20480 bits is enough
+                                              // You can change the size freely
+
+//#define Rx_Buf_LEN      128                   // Generally, buffere with 20480 bits is enough
+
+#define BITS_PER_BYTE   8
+#define BITS_PER_SYMBOL 10
+#define BITS_PER_COMPLEX_SYMBOL  (2 * BITS_PER_SYMBOL)
+
+#define DEVICE_NAME     "CSI_dev"
+#define CLASS_NAME      "CSI_class"
+#define AH_MAX_CHAINS   3                     //maximum chain number, we set it to 3
+#define NUM_OF_CHAINMASK (1 << AH_MAX_CHAINS)
+
+
+volatile u32        csi_head;
+volatile u32        csi_tail;
+volatile u32        csi_len;
+volatile u32        csi_valid;
+volatile u32        recording;
+
+static struct       ath9k_csi csi_buf[16];
+static char         tx_buf[Tx_Buf_LEN];
+//static char         rx_buf[Rx_Buf_LEN];
+
+static int          majorNumber;              
+static struct       class*  ebbcharClass  = NULL; 
+static struct       device* ebbcharDevice = NULL; 
+
+DECLARE_WAIT_QUEUE_HEAD(csi_queue);
+
+static int          csi_open(struct inode *inode, struct file *file);
+static int          csi_close(struct inode *inode, struct file *file);
+static ssize_t      csi_read(struct file *file, char __user *user_buf,
+        size_t count, loff_t *ppos);
+static ssize_t      csi_write(struct file *file, const char __user *user_buf,
+            size_t count, loff_t *ppos);
+
+static const struct file_operations csi_fops = {
+ .read           = csi_read,
+ .write          = csi_write,
+ .open           = csi_open,
+    .release        = csi_close,
+ .llseek         = default_llseek,
+};
+
+static u_int8_t Num_bits_on[NUM_OF_CHAINMASK] = {
+    0 /*       000 */,
+    1 /*       001 */,
+    1 /*       010 */,
+    2 /*       011 */,
+    1 /*       100 */,
+    2 /*       101 */,
+    2 /*       110 */,
+    3 /*       111 */
+};
+
+u_int8_t ar9300_get_nrx_csi(struct ath_hw *ah)
+{
+ return Num_bits_on[ah->rxchainmask];
+}
+
+static int __init csi_init(void)
+{
+
+    // initalize parameters 
+    csi_head    = 0;
+    csi_tail    = 0;
+    recording   = 0;
+    csi_valid   = 0;
+    
+    // Try to dynamically allocate a major number for the device -- more difficult but worth it
+    majorNumber = register_chrdev(0, DEVICE_NAME, &csi_fops);
+    if (majorNumber<0){
+       printk(KERN_ALERT "debug_csi: failed to register a major number\n");
+       return majorNumber;
+    }
+    printk(KERN_INFO "debug_csi: registered correctly with major number %d\n", majorNumber);
+
+    // Register the device class
+    ebbcharClass = class_create(THIS_MODULE, CLASS_NAME);
+    if (IS_ERR(ebbcharClass)){                // Check for error and clean up if there is
+       unregister_chrdev(majorNumber, DEVICE_NAME);
+       printk(KERN_ALERT "debug_csi: Failed to register device class\n");
+       return PTR_ERR(ebbcharClass);          // Correct way to return an error on a pointer
+    }
+    printk(KERN_INFO "debug_csi: device class registered correctly\n");
+    
+    // Register the device driver
+    ebbcharDevice = device_create(ebbcharClass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME);
+    if (IS_ERR(ebbcharDevice)){               // Clean up if there is an error
+       class_destroy(ebbcharClass);           // Repeated code but the alternative is goto statements
+       unregister_chrdev(majorNumber, DEVICE_NAME);
+       printk(KERN_ALERT "Failed to create the device\n");
+       return PTR_ERR(ebbcharDevice);
+    }
+    printk(KERN_INFO "debug_csi: device class created correctly \n"); // Made it! device was initialized
+    
+    return 0;
+}
+
+static void __exit csi_exit(void)
+{
+    /* delete and unregister the devices we have created and registered */
+    device_destroy(ebbcharClass, MKDEV(majorNumber, 0));     // remove the device
+    class_unregister(ebbcharClass);                          // unregister the device class
+    class_destroy(ebbcharClass);                             // remove the device class
+    unregister_chrdev(majorNumber, DEVICE_NAME);             // unregister the major number
+    printk(KERN_INFO "debug_csi: Goodbye CSI device!\n");
+
+}
+
+static int csi_open(struct inode *inode, struct file *file)
+{
+    printk(KERN_ALERT "debug_csi: csi open! \n");
+    recording = 1;                                            // we can begin to record when  
+                                                              // the devices is open 
+    return 0;
+}
+
+static int csi_close(struct inode *inode, struct file *file)
+{
+    printk(KERN_ALERT "debug_csi: csi close! \n");
+    recording = 0;                                            // close and reset 
+ return 0;
+}
+
+static ssize_t csi_read(struct file *file, char __user *user_buf,
+      size_t count, loff_t *ppos)
+{
+    u_int16_t len;
+    u_int8_t *csi_buf_addr;
+    u_int8_t *payload_buf_addr;
+    u_int16_t csi_len, payload_len;
+    struct ath9k_csi* csi;
+    struct csi_pkt_status *RxStatus;
+    
+    *ppos = 0;
+    
+    if (csi_head == csi_tail) 
+    {                                                       // wait until time out
+        wait_event_interruptible_timeout(csi_queue,csi_head != csi_tail,  5*HZ);
+    } 
+    if(csi_head != csi_tail){
+        csi = (struct ath9k_csi*)&csi_buf[csi_tail];
+        len = 0;
+        
+        RxStatus         = &(csi->pkt_status);              // the status struct
+        
+        csi_len          = RxStatus->csi_len;               // csi length (bytes) 
+        csi_buf_addr     = csi->csi_buf;                    // csi buffer 
+        payload_len      = csi->payload_len;                // payload length (bytes)
+        payload_buf_addr = csi->payload_buf;                // payload buffer
+        
+
+        memcpy(tx_buf,RxStatus,23);                         // copy the status to the buffer 
+        len += 23;
+        
+        memcpy(tx_buf+len,&payload_len, 2);                 // record the length of payload 
+        len += 2;
+        
+        if (csi_len > 0){
+            memcpy(tx_buf+len,csi_buf_addr,csi_len);        // copy csi to the buffer
+            len += csi_len;
+        }
+        
+        memcpy(tx_buf+len,payload_buf_addr, payload_len);   // copy payload to the buffer
+        len += payload_len;
+        
+        memcpy(tx_buf+len,&len, 2);                         // record how many bytes we copy 
+        len += 2;
+        
+        copy_to_user(user_buf,tx_buf,len);                  // COPY
+        
+        csi_tail = (csi_tail+1) & 0x0000000F;               // delete the buffer 
+        return len;
+    }else{
+        return 0;
+    }
+}
+
+static ssize_t csi_write(struct file *file, const char __user *user_buf,
+     size_t count, loff_t *ppos)
+{
+    printk(KERN_ALERT "debug_csi: csi write!\n");
+ return 0;
+}
+
+void csi_record_payload(void* data, u_int16_t data_len)
+{
+    struct ath9k_csi* csi;
+    if(recording )
+    {
+        if( ((csi_head + 1) & 0x0000000F) == csi_tail)              // check and update 
+            csi_tail = (csi_tail + 1) & 0x0000000F;
+        
+        csi = (struct ath9k_csi*)&csi_buf[csi_head];
+        memcpy((void*)(csi->payload_buf),data, data_len);           // copy the payload
+        csi->payload_len = data_len;                                // record the payload length (bytes)
+        csi_valid = 1;
+    }
+}
+EXPORT_SYMBOL(csi_record_payload);
+
+void csi_record_status(struct ath_hw *ah, struct ath_rx_status *rxs, struct ar9003_rxs *rxsp,void* data)
+{
+    struct ath9k_csi* csi;
+
+    u_int8_t  nr;
+    u_int8_t  chan_BW;
+    u_int8_t  rx_not_sounding;
+    u_int8_t  rx_hw_upload_data;
+    u_int8_t  rx_hw_upload_data_valid;
+    u_int8_t  rx_hw_upload_data_type;
+    
+    rx_hw_upload_data             = (rxsp->status2 & AR_hw_upload_data) ? 1 : 0;
+    rx_not_sounding               = (rxsp->status4 & AR_rx_not_sounding) ? 1 : 0;
+    rx_hw_upload_data_valid       = (rxsp->status4 & AR_hw_upload_data_valid) ? 1 : 0;
+    rx_hw_upload_data_type        = MS(rxsp->status11, AR_hw_upload_data_type);
+   
+    if(rxs->rs_phyerr == 0 && rx_hw_upload_data == 0 &&
+                rx_hw_upload_data_valid == 0 && rx_hw_upload_data_type == 0){
+        return;
+    }
+
+    if(recording && csi_valid == 1)
+    {
+        csi = (struct ath9k_csi*)&csi_buf[csi_head];
+       
+        csi->pkt_status.tstamp    = rxs->rs_tstamp;     // time stamp of the rx packet 
+        
+        csi->pkt_status.channel   = ah->curchan->channel;               
+        
+        chan_BW                   = (rxsp->status4 & AR_2040) >> 1;        
+        csi->pkt_status.ChanBW    = chan_BW;            // channel bandwidth 
+        nr                        = ar9300_get_nrx_csi(ah);                    
+        csi->pkt_status.nr        = nr;                 // rx antennas number
+        
+        csi->pkt_status.phyerr    = rxs->rs_phyerr;     // PHY layer error code
+        
+        csi->pkt_status.rssi      = rxs->rs_rssi; 
+        csi->pkt_status.rssi_ctl0 = rxs->rs_rssi_ctl[0];            
+        csi->pkt_status.rssi_ctl1 = rxs->rs_rssi_ctl[1];
+        csi->pkt_status.rssi_ctl2 = rxs->rs_rssi_ctl[2];
+        
+        csi->pkt_status.noise     = 0;                  // to be updated
+        csi->pkt_status.rate      = rxs->rs_rate;       // data rate 
+        
+        rx_hw_upload_data         = (rxsp->status2 & AR_hw_upload_data) ? 1 : 0;
+        rx_not_sounding           = (rxsp->status4 & AR_rx_not_sounding) ? 1 : 0;
+        rx_hw_upload_data_valid   = (rxsp->status4 & AR_hw_upload_data_valid) ? 1 : 0;
+        rx_hw_upload_data_type    = MS(rxsp->status11, AR_hw_upload_data_type);
+        
+        // Decides how many tones(subcarriers) are used according to the channel bandwidth
+        if (chan_BW == 0){
+            csi->pkt_status.num_tones = 56;             // 20MHz Channel
+        }
+        else if (chan_BW == 1){
+            csi->pkt_status.num_tones = 114;            // 40MHz Channel
+        } 
+        else{
+            csi->pkt_status.num_tones = 56;             // 20MHz Channel
+            printk("Error happends for channel bandwidth recording!!\n");
+        }
+        
+        /* tx antennas number 
+         * NOTE: when the packet is received with error
+         * The antenna number value is not correct
+         */
+        csi->pkt_status.nc = (int) (rxs->rs_datalen * BITS_PER_BYTE) /
+                        (int) (BITS_PER_COMPLEX_SYMBOL * csi->pkt_status.nr * csi->pkt_status.num_tones);
+        printk("bebug_csi: nr is: %d, nc is %d   \n\n",csi->pkt_status.nr,csi->pkt_status.nc); 
+        /* copy the csi value to the allocated csi buffer */
+        if ( rxs->rs_datalen >0 && rx_hw_upload_data == 1 && rx_hw_upload_data_valid == 1 
+                && rx_hw_upload_data_type == 1){
+            csi->pkt_status.csi_len = rxs->rs_datalen;
+            memcpy((void*)(csi->csi_buf),data,rxs->rs_datalen);
+        }else {
+            csi->pkt_status.csi_len = 0;
+        }
+        
+        csi_valid = 0;                                  // update 
+        csi_head  = (csi_head + 1) & 0x0000000F;
+
+        wake_up_interruptible(&csi_queue);              // wake up waiting queue 
+    }
+}
+EXPORT_SYMBOL(csi_record_status);
+
+
+module_init(csi_init);
+module_exit(csi_exit);
+
+MODULE_AUTHOR("YAXIONG XIE");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CSI EXTRACTION");
+
diff -uNr linux-4.1.10/drivers/net/wireless/ath/ath9k/ar9003_csi.h Atheros-CSI-Tool/drivers/net/wireless/ath/ath9k/ar9003_csi.h
--- linux-4.1.10/drivers/net/wireless/ath/ath9k/ar9003_csi.h 1969-12-31 19:00:00.000000000 -0500
+++ Atheros-CSI-Tool/drivers/net/wireless/ath/ath9k/ar9003_csi.h 2017-02-13 17:33:46.943579002 -0500
@@ -0,0 +1,73 @@
+/*
+ * =====================================================================================
+ *       Filename:  ar003_csi.h
+ *
+ *    Description:  ar003_csi data structure definiation
+ *        Version:  1.0
+ *
+ *         Author:  Yaxiong Xie 
+ *         Email :  <xieyaxiongfly@gmail.com>
+ *   Organization:  WANDS group @ Nanyang Technological University 
+ *
+ *   Copyright (c)  WANDS group @ Nanyang Technological University
+ * =====================================================================================
+ */
+
+#include "hw.h"
+#include "mac.h"
+#include "ar9003_mac.h"
+
+#define DBG_CSI(fmt, args...) printk(fmt,## args)
+#define AR_rx_ness                  0x00000060
+#define AR_rx_ness_S                5
+#define AR_ness                     0xc0000000 
+#define AR_ness_S                   30
+#define AR_hw_upload_data           0x00400000
+#define AR_hw_upload_data_S         22
+#define AR_rx_not_sounding          0x00000010
+#define AR_not_sounding             0x20000000
+#define AR_hw_upload_data_valid     0x00000080
+#define AR_hw_upload_data_valid_S   7  
+#define AR_hw_upload_data_type      0x06000000
+#define AR_hw_upload_data_type_S    25
+
+#define AR_xmit_data_tries0   0x000f0000
+#define AR_xmit_data_tries0_S 16
+#define AR_xmit_data_tries1   0x00f00000
+#define AR_xmit_data_tries1_S 20
+#define AR_xmit_data_tries2   0x0f000000
+#define AR_xmit_data_tries2_S 24
+#define AR_xmit_data_tries3   0xf0000000
+#define AR_xmit_data_tries3_S 28
+
+struct csi_pkt_status {
+    u_int64_t   tstamp;      /* h/w assigned timestamp */
+    u_int16_t   csi_len;     /* csi length */
+    u_int16_t   channel;     /* receiving channel frequency */
+    u_int8_t phyerr;     /* phy error code */
+    
+    u_int8_t    noise;       /* noise floor */
+    u_int8_t rate;     /* h/w receive rate index */
+    u_int8_t    ChanBW;      /* receiving channel bandwidth */
+    u_int8_t    num_tones;   /* number of tones (subcarriers) */
+    u_int8_t    nr;          /* number of receiving antennas */
+    u_int8_t    nc;          /* number of transmitting anteannas */
+    
+    
+    u_int8_t    rssi;        /* rx frame RSSI */
+    u_int8_t    rssi_ctl0;   /* rx frame RSSI [ctl, chain 0] */
+    u_int8_t    rssi_ctl1;   /* rx frame RSSI [ctl, chain 1] */
+    u_int8_t    rssi_ctl2;   /* rx frame RSSI [ctl, chain 2] */
+};
+
+struct ath9k_csi {
+    struct csi_pkt_status pkt_status;
+
+    u_int8_t    csi_buf[2800];     //buffer for csi value, 3 antena, each with 114 subcarriers, real and imagine part
+    u_int8_t    payload_buf[1500]; //buffer for the payload, if you send payload larger than 1500Bytes, change it
+    u_int16_t   payload_len;
+
+};
+void   csi_record_payload(void* data, u_int16_t data_len);
+void   csi_record_status(struct ath_hw *hw, struct ath_rx_status *rxs,struct ar9003_rxs *rxsp,void* data); 
+
diff -uNr linux-4.1.10/drivers/net/wireless/ath/ath9k/ar9003_mac.c Atheros-CSI-Tool/drivers/net/wireless/ath/ath9k/ar9003_mac.c
--- linux-4.1.10/drivers/net/wireless/ath/ath9k/ar9003_mac.c 2015-10-03 07:49:38.000000000 -0400
+++ Atheros-CSI-Tool/drivers/net/wireless/ath/ath9k/ar9003_mac.c 2017-02-13 17:33:46.943579002 -0500
@@ -17,6 +17,7 @@
 #include "hw.h"
 #include "ar9003_mac.h"
 #include "ar9003_mci.h"
+#include "ar9003_csi.h"

 static void ar9003_hw_rx_enable(struct ath_hw *hw)
 {
@@ -30,7 +31,8 @@
  int checksum = 0;
  u32 val, ctl12, ctl17;
  u8 desc_len;
-
+    u_int8_t rate1,rate2,rate3,rate4;
+    
  desc_len = ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x18 : 0x17);

  val = (ATHEROS_VENDOR_ID << AR_DescId_S) |
@@ -61,6 +63,7 @@
  ACCESS_ONCE(ads->ctl7) = val;
  checksum += (val = (i->buf_len[3] << AR_BufLen_S) & AR_BufLen);
  ACCESS_ONCE(ads->ctl9) = val;
+    

  checksum = (u16) (((checksum & 0xffff) + (checksum >> 16)) & 0xffff);
  ACCESS_ONCE(ads->ctl10) = checksum;
@@ -82,7 +85,7 @@
  ACCESS_ONCE(ads->ctl14) = 0;
  }

- ads->ctl20 = 0;
+    ads->ctl20 = 0;
  ads->ctl21 = 0;
  ads->ctl22 = 0;
  ads->ctl23 = 0;
@@ -150,11 +153,29 @@
  | set11nRateFlags(i->rates, 3)
  | SM(i->rtscts_rate, AR_RTSCTSRate);

- ACCESS_ONCE(ads->ctl19) = AR_Not_Sounding;
-
  ACCESS_ONCE(ads->ctl20) = SM(i->txpower[1], AR_XmitPower1);
  ACCESS_ONCE(ads->ctl21) = SM(i->txpower[2], AR_XmitPower2);
  ACCESS_ONCE(ads->ctl22) = SM(i->txpower[3], AR_XmitPower3);
+
+    rate1 = (ads->ctl14 >> 24) & 0xff;
+    rate2 = (ads->ctl14 >> 16) & 0xff;
+    rate3 = (ads->ctl14 >> 8)  & 0xff;
+    rate4 = (ads->ctl14 >> 0)  & 0xff;
+
+    if ( rate1 >= 0x80 || rate2 >= 0x80 || rate3 >= 0x80){
+    ACCESS_ONCE(ads->ctl19) = 0;
+        ACCESS_ONCE(ads->ctl13) &= ~(AR_xmit_data_tries1 | AR_xmit_data_tries2 | AR_xmit_data_tries3);
+    ACCESS_ONCE(ads->ctl20) &= 0x3f000000;
+    ACCESS_ONCE(ads->ctl21) &= 0x3f000000;
+    ACCESS_ONCE(ads->ctl22) &= 0x3f000000;
+    }else{
+    ACCESS_ONCE(ads->ctl19) = AR_Not_Sounding;
+    }
+    if ( rate4 >= 0x80){
+    ACCESS_ONCE(ads->ctl19) = 0;
+    }else{
+    ACCESS_ONCE(ads->ctl19) = AR_Not_Sounding;
+    }
 }

 static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
@@ -483,6 +504,9 @@
  struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr;
  unsigned int phyerr;

+ void *data_addr;
+     u_int16_t data_len;
+
  if ((rxsp->status11 & AR_RxDone) == 0)
  return -EINPROGRESS;

@@ -577,9 +601,25 @@
  }
  }
  }
-
- if (rxsp->status11 & AR_KeyMiss)
+   
+    if (rxsp->status11 & AR_KeyMiss)
  rxs->rs_status |= ATH9K_RXERR_KEYMISS;
+    
+    data_len = rxs->rs_datalen;
+    data_addr = buf_addr + 48;
+    
+    if (rxsp->status11 & AR_CRCErr){
+        if (rxs->rs_rate >= 0x80){
+            csi_record_payload(data_addr,data_len);
+            csi_record_status(ah,rxs,rxsp,data_addr);
+        }
+    }else{
+        if  (rxs->rs_more == 1)
+            csi_record_payload(data_addr,data_len);
+
+        if (rxs->rs_rate >= 0x80)
+            csi_record_status(ah,rxs,rxsp,data_addr);
+ }

  return 0;
 }
diff -uNr linux-4.1.10/drivers/net/wireless/ath/ath9k/hw.c Atheros-CSI-Tool/drivers/net/wireless/ath/ath9k/hw.c
--- linux-4.1.10/drivers/net/wireless/ath/ath9k/hw.c 2015-10-03 07:49:38.000000000 -0400
+++ Atheros-CSI-Tool/drivers/net/wireless/ath/ath9k/hw.c 2017-02-13 17:33:46.959579002 -0500
@@ -1818,6 +1818,7 @@
  u32 saveLedState;
  u32 saveDefAntenna;
  u32 macStaId1;
+ u32 tmp;
  u64 tsf = 0;
  s64 usec = 0;
  int r;
@@ -2028,6 +2029,10 @@
  ah->radar_conf.ext_channel = IS_CHAN_HT40(chan);
  ath9k_hw_set_radar_params(ah);
  }
+ //csi_debug 
+     tmp = REG_READ(ah,0x8344);
+     tmp |= (1 << 28);
+     REG_WRITE(ah, 0x8344,tmp);

  return 0;
 }
diff -uNr linux-4.1.10/drivers/net/wireless/ath/ath9k/init.c Atheros-CSI-Tool/drivers/net/wireless/ath/ath9k/init.c
--- linux-4.1.10/drivers/net/wireless/ath/ath9k/init.c 2015-10-03 07:49:38.000000000 -0400
+++ Atheros-CSI-Tool/drivers/net/wireless/ath/ath9k/init.c 2017-02-13 17:33:46.959579002 -0500
@@ -831,7 +831,7 @@
  hw->flags |= IEEE80211_HW_SUPPORTS_PS;

  if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
- hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
+ //hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;

  if (AR_SREV_9280_20_OR_LATER(ah))
  hw->radiotap_mcs_details |=
diff -uNr linux-4.1.10/drivers/net/wireless/ath/ath9k/main.c Atheros-CSI-Tool/drivers/net/wireless/ath/ath9k/main.c
--- linux-4.1.10/drivers/net/wireless/ath/ath9k/main.c 2015-10-03 07:49:38.000000000 -0400
+++ Atheros-CSI-Tool/drivers/net/wireless/ath/ath9k/main.c 2017-02-13 17:33:46.967579002 -0500
@@ -2116,7 +2116,6 @@
  bf = avp->av_bcbuf;
  if (!bf || !bf->bf_mpdu)
  goto skip;
-
  status = ath9k_hw_txprocdesc(ah, bf->bf_desc, &ts);
  if (status == -EINPROGRESS)
  goto skip;
diff -uNr linux-4.1.10/drivers/net/wireless/ath/ath9k/Makefile Atheros-CSI-Tool/drivers/net/wireless/ath/ath9k/Makefile
--- linux-4.1.10/drivers/net/wireless/ath/ath9k/Makefile 2015-10-03 07:49:38.000000000 -0400
+++ Atheros-CSI-Tool/drivers/net/wireless/ath/ath9k/Makefile 2017-02-13 17:33:46.931579002 -0500
@@ -1,3 +1,5 @@
+obj-m   +=      ar9003_csi.o 
+
 ath9k-y += beacon.o \
  gpio.o \
  init.o \
diff -uNr linux-4.1.10/drivers/net/wireless/ath/ath9k/xmit.c Atheros-CSI-Tool/drivers/net/wireless/ath/ath9k/xmit.c
--- linux-4.1.10/drivers/net/wireless/ath/ath9k/xmit.c 2015-10-03 07:49:38.000000000 -0400
+++ Atheros-CSI-Tool/drivers/net/wireless/ath/ath9k/xmit.c 2017-02-13 17:33:46.967579002 -0500
@@ -2681,7 +2681,7 @@

  lastbf = bf->bf_lastbf;
  ds = lastbf->bf_desc;
-
+        
  memset(&ts, 0, sizeof(ts));
  status = ath9k_hw_txprocdesc(ah, ds, &ts);
  if (status == -EINPROGRESS)
@@ -2736,7 +2736,6 @@
  for (;;) {
  if (test_bit(ATH_OP_HW_RESET, &common->op_flags))
  break;
-
  status = ath9k_hw_txprocdesc(ah, NULL, (void *)&ts);
  if (status == -EINPROGRESS)
  break;