2014年6月4日 星期三

Android 4.2.2 , RT3070 wifi porting note [1]

 Android version : Android 4.2.2 
Wifi module : TOTOLINK N150UM (RT3070) 

 之前提到在BBB上做了androidporting,又在上做了wifi的配置,結果忘了把過程寫出來,上半年真是太懶散了,多虧有網友提醒,我在這裡把相關的配置設定做個記錄,這裡的資料是我參考一些網路上的資料,綜合而來,希望對各方朋友能有所幫助。 

這篇Note分成2個部分: 
1. RT3070 wifi driver porting 
2. Android 4.2.2 setting 

1. RT3070 wifi driver porting時,我會簡介一下如何把RT3070的驅動程式修改程能在Android上用的版本,基本上程式碼是不太需要動到的,只是需要修改一些設定,在cross-compilerARMandroid平台上。 

2. Android 4.2.2 setting時,我會簡介一下如何修改部分的Android source,把wifi的設定匹配到我們剛剛cross-compiler driver上。

這篇文章為
1. RT3070 wifi driver porting 

========================================================================================

下載Driver source 
本篇文章使用的是[塔米歐 N150UM 極致輕薄USB無線網卡],其驅動程式下載位置: http://www.tamio.com.tw/tamio/component/phocadownload/category/61-totolink-n150um?download=144:2011-0719-rt3070-rt3370-rt5370-rt5372-linux-sta-v2-5-0-3-dpo 

下載之後你會得到以下檔案: 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO.bz2

使用tar指令把他解開
#tar jxvf 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO.bz2

因為此驅動程式預設是給linux PC用的,所以我們要作一些修改,才能給我們的android平台用

驅動程式修改
1.     修改os/linux/config.mk的內容,新增wpa_supplicant的支援
 # vim os/linux/config.mk
 修改以下內容
 HAS_WPA_SUPPLICANT=y
 HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y



2.     這個驅動程式會把device的名字註冊成ra,而一般的裝置名字似乎是wlan比較常見,因此修改include/rtmp_def.h的內容,讓驅動把名字註冊成wlan,當然,不改也沒關係,只是往後在修改Android 設定時需要注意一下。

 # vim include/rtmp_def.h
 修改以下內容
 #define INF_MAIN_DEV_NAME        "wlan"
 #define INF_MBSSID_DEV_NAME        "wlan"


Makefile 修改
1.     因為這個平台沒有預設Beaglebone Black的驅動程式,因此我們新增一個給BBB用,首先,先來修改Makefile,在約25行處,有一串的PLATFORM的設定,預設的PLATFORMPC
PLATFORM PC


PLATFORM PC註解,增加新的platform BBB
#PLATFORM PC
PLATFORM BBB


2.     Makefile 172行處有platform PC的設定檔,依照他的格式,新增以下內容作為platform BBB的設定檔。
        # ---------------------------------------------------------------
        ifeq ($(PLATFORM),BBB)
        # Linux for Android TI source
        CHIPSET = 3070
        LINUX_SRC = /home/BeagleboneBlack/Android/rowboat-android/kernel/
        CROSS_COMPILE = arm-eabi-
        endif
        # ---------------------------------------------------------------


§   因為我使用的wifi模組是RT3070的晶片,因此CHIPSET改成3070
§   LINUX_SRCkernel source的位置,如果是要cross compiler到其他平台上,就要改到此平台linux kernel對應的存放位置,在這裡我是為了portingAndroid上,所以將路徑改成這樣
§   CROSS_COMPILE則是看corss-compiler來決定,請修改成您使用的corss-compiler

3.     接著為我們新增的platform,增加gccinclude路徑,否則一compiler會直接說某些結構找不到definition,因為他找不到include的路徑,修改os/linux/config.mk這個檔案,新增以下內容,增加gcc運行時的flag
 # vim os/linux/config.mk
增加以下內容
 ifeq ($(PLATFORM),BBB)
     EXTRA_CFLAGS := $(WFLAGS) -I$(RT28xx_DIR)/include
 endif



4.     接著就可以開始make了,記得指定ARCH=arm
 # make ARCH=arm

5.     編譯完成之後,會在os/linux/ 下產生rt3070sta.kodriver

Reference :
[1]http://askubuntu.com/questions/148767/help-do-i-install-the-ralink-rt3070-wireless-driver


2014年3月14日 星期五

Beaglebone black with Arduino microphone module


使用平台Beaglebone Black
元件Arduino 高感度聲音傳感器



最近因為實驗室需要聲音的應用,加上Beaglebone Black上有ADC,所以就想來研究一下AM335X上的ADC,讀完manual之後,才知道原來這個AM335XADC原本是設計給觸控螢幕用的,不過manual上的介紹寫得滿清楚的,雖然我還不是很明白step為什麼需要16個就是,可能也是因為我的應用比較單純吧,一個channel只要配一個step就夠了,看來有空要來存點錢買塊小觸控螢幕了!


因為之前有研究BBBIO的經驗,因此ADC方面也是依靠mmap的方式來操作,就花了幾天寫了一個簡單的ADC library,加到BBBIO之中,但是我沒辦法在User-space之中打中斷,所以只能用Busy-polling的方式去掃ADCFIFO,算是一個比較失敗的地方吧,不過如果做為基本應用的話,我覺得目前的實做已經足夠了。


我用的聲音模組是Arduino的高感度聲音模組,如下圖1,應該算是非常好入手的元件,有Analogy的輸出跟Digital的輸出,因為是用ADC,所以就接Analogy的腳位。



1. Arduino 高感度麥克風

詳細的腳位如圖2,使用時需要注意增益的輸出,建議先接到示波器上,把增益調到1.8V內,不然Beaglebone blackADC可能會直接被打穿燒掉



2. Circuit Layout


接著因為我不喜歡在Beaglebone black上接HDMI線,那個腳位設計常跟USB互卡還挺麻煩的,因此我用socket,把ADC讀進來的資料傳到電腦上顯示,順道寫了一個專用的簡易示波器,詳細的Demo與截圖如下,Demo中播放了1KHz和3KHz的出來,可以看到其波形的改變。



3. UI




接下來只要用fftw之類的library進行複利葉轉換的分析,就可以做一些特別的應用了,而Beaglebone black的ADC最快可以到1.6MHz,只要調ADC的參數即可,我同時也在BBBIO的toolkit中寫了一個Toolkit_GPIO_CLK_Status來計算參數,如果不想算的朋友,也許可以參考一下!





2014年1月3日 星期五

Beaglebone Black Debug Cable

最近開始著手研究u-boot,但是苦於手上沒有Beaglebone Black的Debug cable,所以沒辦法接到u-boot的debug 訊息,這對初學實在是有點障礙阿……所以便上網去買了一個,大約台幣160元,採用FT232RL晶片的模組,如下圖:

接著只需要三條線,即可接取資料,GND、Tx、Rx,而從 Beaglebone Black的System Reference Manual中,可以找到有關於Debug Cable的接線圖,如下圖:

Pin Number
Signal
Pin 1
GND
Pin 4
Receive
Pin 5
Transmit


接著只要將Beaglebone black Pin 4的Rx接到模組的Tx,然後再將Pin 4的Tx接到Rx,如下圖所示:

接著就可以透過Serial port讀取Debug的資料了:

2013年12月27日 星期五

Beaglebone Black I/O library 開發歷程(三) - GPIO module


How to access GPIO using mamp in TI AM335x CPU

Base on Beaglebone Black

C Library development note


Author : Cai , Meng-Lun , (VegetableAvenger) , 2013/12/19

Introduction :

這份筆記的內容正式涵蓋了BBBio library的內容,這份文件將介紹如何再Beaglebone black上利用C語言與mmap來進行GPIO的操作,以user space的方式來控制硬體,而不用去撰寫專用的Device Driver,同時粗略的介紹一下AM335xSystem Interconnect架構,以瞭解module的布局方式以及Clock manager的管理,最後將演示一段透過BBBio library,使用按鈕開關來控制LED閃爍速度的程式碼。


This note contain :
  • AM335x System Interconnect Architecture
  •  AM335x GPIO module introduction
  •  Memory map of AM335x GPIO module
  •  Enable/Disable Clock of GPIO module via CM_PER/CM_WKUP register
  •  GPIO register
  •  Get BBBio
  •  LED Demo

部份文字內容或圖片 reference from : AM335x Technical Reference Manual


AM335x System Interconnect Architecture :

AM335xinterconnect Architecture 2-Level架構,由L3L4組成,而L3則分為L3FL3S,而L4則是分為L4_FASTL4_PERL4_WKUP,結構如圖1所示,由其可看出L4_PERL4_WKUP是掛接在L3_S下,而L4_FAST則是接在L3F下。





1L3 Topology (AM335x TRM page 1231)

GPIO模組則是分佈在L4之中,GPIO 0掛在L4_WKUPGPIO 1~3掛在L4_PER中,整體上如圖2所示。




2L4 Topology (AM335x TRM page 1234)


瞭解GPIO模組所屬的Interconnect Topology有助於瞭解各module間的Clock互動情形,即瞭解module所屬的Clock Domain,像是GPIO 1~3所處的Clock DomainPD_PER_L4LS_GCLK,而GPIO 0 則處在PD_WKUP_L4_WKUP_GCLK這個Clock domain上,而透過圖2L4 Topology布局方式便可以清楚的瞭解為何GPIO模組會處於不同的Clock Domain上。

為了要讓module省電,所以沒有必要使用的moduleClock常處於Disable的狀態,而每一個GPIO模組擁有其各自的register來控制是否Disable Clock,瞭解其Clock domain之後,便可以搜尋其對應的Clock control register,接著才可以在需要使用時,將GPIOClock Enable/Disable,下表為各GPIOClock control register




GPIO

Clock Domain

Speed

Clock Control Register

GPIO 0

PD_WKUP_L4_WKUP_GCLK

100M Hz

CM_WKUP_GPIO0_CLKCTRL

GPIO 1

PD_PER_L4LS_GCLK

100M Hz

CM_PER_GPIO1_CLKCTRL

GPIO 2

PD_PER_L4LS_GCLK

100M Hz

CM_PER_GPIO2_CLKCTRL

GPIO 3

PD_PER_L4LS_GCLK

100M Hz

CM_PER_GPIO3_CLKCTRL

1GPIO Clock Domain

AM335x GPIO Module Introduction :

AM335x 擁有4GPIO moduleGPIO 0GPIO 1GPIO 2GPIO 3,每一個module32支接腳,故總共有128GPIO的腳位可以使用,每支腳位提供以下的基本功能:
  1. Data Input/ Output
  2. Debounce cell
  3. Synchronous interrupt
  4. Wake-up request (Only GPIO 0)

本筆記主要記錄最基本的Data Input/OutputDebouncing為次章節介紹,而剩餘功能尚未完整測試。

基本上每一組GPIO都提供了1~3的基本功能,而GPIO 0 則額外提供了Wake-Pp的功能,是與其他GPIO較為不同的地方,如圖3所示,可以發現GPIO 0的模組配置較GPIO 1~3不同,而圖中各GPIO modulePIDBCLK則為Debouncing Clock的輸入訊號,而POINTRPEND1 /2則是用來產生interrupt的訊號。

 


3GPIO0~3 Module Integeration (AM335x TRM page 4630)

由圖3可知,GPIO模組操作起來所需要的條件並沒有很多,若是不考慮wake up功能的話,基本上GPIO 0~3功能是一樣的,只需要注意在L4 WakeUP InterconnectL4 Peripgeral InterconnectClock有輸入進GPIO模組,接著只要在GPIO module相對應的register之中進行操作,即可控制pin腳的狀態。


Memory map of AM335x GPIO module

接著從AM335x之中,查出GPIO對應的Memory Map的位址,以利用mmap進行存取動作

AM335x TRMpage .171Table 2-2. L4_WKUP Peripheral Memory Map

AM335x TRMpage .173~174Table 2-3. L4_PER Peripheral Memory Map



Region Name

Start Address

End Address

Size

Description

CM_PER

0x44E0_0000

0x44E0_3FFF

0x4000

Clock Module Peripheral Registers

CM_WKUP

0x44E0_0400

0x44E0_04FF

0x100

Clock Module Wakeup Registers

GPIO0

0x44E0_7000

0x44E0_7FFF

0x1000

GPIO register

GPIO1

0x4804_C000

0x4804_CFFF

0x1000

GPIO2

0x481A_C000

0x481A_CFFFF

0x1000

GPIO3

0x481A_E000

0x481A_EFFFF

0x1000

2GPIO Memory map
 

Enable/Disable Clock of GPIO module via CM_PER/CM_WKUP register

Clock上要特別注意,由先前提過的表1可知,GPIO 0 屬於PD_WKUP_L4_WKUP_GCLKClock domain,控制RegisterCM_WKUP_GPIO0_CLKCTRL,而GPIO 1~3屬於PD_PER_L4LS_GCLKClock domain,控制RegisterCM_PER_GPIOx_CLKCTRL (x1~3),要小心不要控制錯了,名字是有差別的。

GPIO模組基本上會有2Clock的輸入:Interface ClockDebouncing ClockInterface ClockL4 Iterface提供,100MHz的頻率,而Debouncing Clock則是可選的(不需要就Disable沒關係),為32.768KHz,如果interface clock 沒有Enable,那整組GPIOregister access 都會error,並回傳Bus Error的選項。

瞭解要控制的Register之後,接著就是去看他的格式,相對應的頁數列於表3,而基本上這4reigister的控制參數格式是一模一樣的,如圖4所示,因此我們只需要將Bit 0~1MODULEMODE欄位設為0x2 (Enable)即可打開相對應GPIOClock




Register Name

Page

Session

CM_WKUP_GPIO0_CLKCTRL

983

Session 8.1.12.2.3

CM_PER_GPIO1_CLKCTRL

947

Session 8.1.12.1.29

CM_PER_GPIO2_CLKCTRL

948

Session 8.1.12.1.30

CM_PER_GPIO3_CLKCTRL

949

Session 8.1.12.1.31

3GPIO Clock Register page Reference
 

而這裡有一個需要注意的欄位,OPTFCLKEN_GPIO_x_GDBCLK (bit 18),這個欄位是用來Enable/Disable Debouncing Clock的,即圖3PIDBCLK



4GPIO Clock Register format
 

mmap程式碼:

BBBio/BBBio.ciolib_init fnuction之中,需要map 2+4map,分別是控制Clokc的:CM_PERCM_WKUP,和GPIO moduleGPIO0~3

其中需要特別注意CM_WKUP,其memory map位址為0x44E0_0400,這個位址直接下去mmap,會回傳error,同時error code為:EINVAL,這是因為0x44E0_0400這個address並沒有alignment page,這裡的page4K,所以mmap沒有辦法map;不過這是可以處理的,在BBBio中,先mmap CM_PER (0x44E0_0000)這個register,在透過offset 0x400,存取CM_WKUP,即可mmap CM_WKUP,因為在mmap CM_PER時,其maplength已經涵蓋了CM_WKUP



cm_per_addr = mmap(忽略参數) ;

cm_wkup_addr =(void *)cm_per_addr + 0x400 ;

Enable/Disable程式碼:

BBBio/BBBio.cBBBIO_sys_Enable_GPIOBBBIO_sys_Disable_GPIO fnuction之中,
 

GPIO register

GPIO module基本上需要:InputOutputI/O方向設定,3個功能,而AM335xGPIO module則是將這些功能透過以下register控制



Action

Register Name

Offset

I/O Setting

GPIO_OE

0x134

Input

GPIO_DATAIN

0x138

Output

GPIO_CLEARDATAOUT

GPIO_SETDATAOUT

GPIO_DATAOUT

0x190

0x194

0x13C

4GPIO Control Register

I/O Setting

透過GPIO_OE register來控制PIN腳是要Inpout還是Output,一次設定整組的GPIO I/O status,共32bit,每一個bit對應1個腳位,bit設為0代表output,設為1代表Input

例如:GPIO 0GPIO_OE register bit 0代表 GPIO 0 [0]這支pin腳,若是寫入0x00000001,代表將pin0腳位設為input,其他設為output

請特別注意:建議透過邏輯運算| (or),來進行操作,因為有些GPIO不是你可以亂動的,以Beaglebone black來說,其外部接角插槽只有96pin,而且有些pin不是GPIO,代表不是每一個GPIO都有拉出去,若是你亂改到非外拉的腳位狀態,或許會造成系統/裝置錯誤,因此,設定數值前請三思並檢查。

 Input Setting

透過GPIO_DATAIN來取得PIN腳目前輸入的狀態,一次讀入整組的GPIO input status,共32bit,每一個bit對應1個腳位,例如GPIO 0GPIO_DATAIN register bit 0代表 GPIO 0 [0]這支pin腳,因此讀出GPIO_DATAIN的數值之後,你需要自己利用邏輯運算& (and),來判斷需要的腳位狀態。

Output Setting

Output的設定就比較有趣了,這裡我將他分成2種操作模式:獨立控制直接控制

 獨立控制代表一次操作下,只可以控制腳位是輸出0還是1

直接控制代表一次操作下,可以一次控制一整組的GPIO狀態,Pin可為0 也可為1



模式

Register

解說

獨立控制

GPIO_CLEARDATAOUT

GPIO_SETDATAOUT

設定Pin腳輸出0

設定Pin腳輸出1

直接控制

GPIO_DATAOUT

設定GPIO輸出

5GPIO Output Control Register

假設你需要將8LED 同一時間一次點亮,那你可以使用獨立控制或是直接控制,但若是同一時間下,需要點亮4個,滅掉4LED,那就只能使用直接控制的功能,否則你必須使用2次獨立控制的register,先下GPIO_SETDATAOUT 4個,在下GPIO_CLEARDATAOUT指令滅4個。

 獨立控制 寫入方式:

一次寫入代表寫入整組的GPIO Output status,共32bit,每一個bit對應1個腳位;要讓某pin腳設為1則在GPIO_SETDATAOUT相對應的bit寫入1,要設為0,則在GPIO_CLEARDATAOUT寫入1,你沒看錯,都是寫入1,因為這2register分別用來進行Output 0Output 1,寫入1代表此PIN腳要進行設定,寫入0則沒有任何效果。

 直接控制 寫入方式:

直接控制的寫入方式就很直覺了,一樣一次寫入代表寫入整組的GPIO Output status,共32bit,每一個bit對應1個腳位;要某pin腳設為1則在GPIO_DATAOUT相對應的bit寫入1要設為0,則在GPIO_DATAOUT寫入0跟一般的用法無異。

請特別注意:以上運算一樣建議透過邏輯運算| (or),來進行操作,因為有些GPIO不是你可以亂動的,以Beaglebone black來說,其外部接角插槽只有96pin,而且有些pin不是GPIO,代表不是每一個GPIO都有拉出去,若是你亂改到非外拉的腳位狀態,或許會造成系統/裝置錯誤,因此,設定數值前請三思並檢查。


Get BBBio

BBBioShabaz開發,Cai,Meng-Lun維護的Beaglebone black I/O library,為一套自由軟體,任何人可以自由更改,沒有授權問題,目前置放於github :

https://github.com/VegetableAvenger/BBBIOlib

 LED Demo

5為實際範例圖和電路圖,詳細的程式碼請參閱BBBio library中的Demo/Deno_LED_GPIO/




 

5LED Demo & CircuitLayout