早いもので、もう2015年も終わろうとしている。
今年はいろいろなことがあった。
上半期は
・fonのカスタムファーム導入に挑戦
・ラズベリーパイで遊ぶ
私生活では家を購入し、かなりドタバタした。
下半期は
・統計とかDBとか少しずつ勉強
・タスク管理qdPMを導入したけど、なじまず
・外部から自宅サーバーへの接続環境を構築
・Markdownエディタを少し作った
・投資は目標クリア! 来年も頑張ろう
なんだかんだ仕事が忙しくて、なかなか時間が取れなかった。
でも、なんとか時間を確保して少しずつ前進できたと思う。
来年は、家庭も仕事も充実するといいな。
ブログ的には
・Electon(NW.jsもか)を使った開発
・PICマイコンを使った開発をもっと行う
・投資も頑張る
かな。
2015年12月30日水曜日
2015年10月25日日曜日
簡易Markdownエディタにmermaid.jsを導入してフローチャートを表示する
しばらくバタバタしており、更新が滞ってしまった。
でも続けることはやめてはいない。
最近、Markdownが気になる。流行に乗り遅れてしまった感があるけど、
このページを見て心踊ったからだ。
http://qiita.com/uzuki_aoba/items/a01f8b0b52ced69c8092
ここで紹介されている「Haroopad」は良さそうなのだけど、
こればかりに頼ってしまうのもなんだかなので、
勉強を兼ねてwebベースの簡易エディタを作ってみたいと思う。
リアルタイム更新
Markdown表記
コードのハイライト表示
mermaid.js対応
これだけ[npm install jquery]
2.Markdownパーサー(marked)
これだけ [npm install marked]
3.ハイライト(highlight.js)
これだけ[npm install highlightjs]
4.Mermaid.js
これだけ[npm install mermaid --save-dev]
※phpにしたのは、phpの簡易サーバーで動作確認したかったから
他意はない。
2.[mde.js]
すると
あ、フローチャートって書いたけど、シーケンス図だ…Orz
http://qiita.com/opengl-8080/items/56b4b6a9d31bac0cb3e2
http://clmpractice.org/2015/05/21/rational-team-concert-open-social-widget-with-mermaid-markdown/
knsv.github.io/mermaid/
http://knsv.github.io/mermaid/usage.html
http://kannokanno.hatenablog.com/entry/2013/06/19/132042
http://qiita.com/amay077/items/704d48130e5cf17e8654
でも続けることはやめてはいない。
最近、Markdownが気になる。流行に乗り遅れてしまった感があるけど、
このページを見て心踊ったからだ。
http://qiita.com/uzuki_aoba/items/a01f8b0b52ced69c8092
ここで紹介されている「Haroopad」は良さそうなのだけど、
こればかりに頼ってしまうのもなんだかなので、
勉強を兼ねてwebベースの簡易エディタを作ってみたいと思う。
概要
webベースリアルタイム更新
Markdown表記
コードのハイライト表示
mermaid.js対応
準備
ディレクトリ作成
今回はmdeとした。インストール
1.jQueryこれだけ[npm install jquery]
2.Markdownパーサー(marked)
これだけ [npm install marked]
3.ハイライト(highlight.js)
これだけ[npm install highlightjs]
4.Mermaid.js
これだけ[npm install mermaid --save-dev]
プログラム
1.[mde.php]※phpにしたのは、phpの簡易サーバーで動作確認したかったから
他意はない。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php ?> | |
<html> | |
<head> | |
<meta charset="UTF-8" /> | |
<script src="node_modules/jquery/dist/jquery.min.js"></script> | |
<script src="node_modules/marked/lib/marked.js"></script> | |
<script src="node_modules/highlightjs/highlight.pack.js"></script> | |
<script src="node_modules/mermaid/dist/mermaid.min.js"></script> | |
<script src="mde.js"></script> | |
<lint rel="stylesheet" href="node_modules/mermaid/dist/mermaid.css" /> | |
<link rel="stylesheet" href="node_modules/highlightjs/styles/github.css" /> | |
</head> | |
<body> | |
<div class="container"> | |
<div class="row"> | |
<div class="col1"> | |
<textarea id="editor" class="form-control"></textarea> | |
</div> | |
<div class="col2"> | |
<div id="result"></div> | |
</div> | |
</div> | |
</div> | |
<pre> | |
<div class="mermaid"> | |
sequenceDiagram | |
Alice->>John: Hello John, how are you? | |
John-->>Alice: Great! | |
</div> | |
</pre> | |
</body> | |
</html> |
2.[mde.js]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$(function() { | |
marked.setOptions({ | |
langPrefix: '' | |
}); | |
$('#editor').keyup(function() { | |
var src = $(this).val(); | |
var html = marked(src); | |
$('#result').html(html); | |
$('pre code').each(function(i, block) { | |
if(block.className == "mermaid"){ | |
block.outerHTML = '<div class="mermaid">'+block.innerHTML+'</div>'; | |
}else{ | |
hljs.highlightBlock(block); | |
} | |
}); | |
window.mermaid.init(); | |
}); | |
}); |
動かし方
作成した ディレクトリで[php -S 127.0.0.1:8080]とするすると
あ、フローチャートって書いたけど、シーケンス図だ…Orz
参考
以下のリンクがものすごく参考になった。http://qiita.com/opengl-8080/items/56b4b6a9d31bac0cb3e2
http://clmpractice.org/2015/05/21/rational-team-concert-open-social-widget-with-mermaid-markdown/
knsv.github.io/mermaid/
http://knsv.github.io/mermaid/usage.html
http://kannokanno.hatenablog.com/entry/2013/06/19/132042
http://qiita.com/amay077/items/704d48130e5cf17e8654
雑感
Qiitaにすこし憧れる2015年5月9日土曜日
FON2405EのGPIOでキャラクタ液晶を制御する(WEB制御)
目的
前回、送達確認を拡張して受信機能(PICマイコンからFONに対してコマンドを出せる)ようにした。今回は、コマンドラインの操作をWEBから行えるように変更した。
概要
WEBからクリア、行移動、文字出力を行う。PICからの受信は次回の課題。
結果
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
echo "Content-type: text/html" | |
echo | |
CMD_QSTR="OFF" | |
CMD_QSTR=`echo "$QUERY_STRING" | sed -n 's/^.*cmd=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"` | |
DATA_QSTR="" | |
DATA_QSTR=`echo "$QUERY_STRING" | sed -n 's/^.*data=\([^&]*\).*$/\1/p' | sed "s/%20/ /g"` | |
STATE_CLEAR="" | |
STATE_LINE1="" | |
STATE_LINE2="" | |
STATE_DATA="" | |
CMD_RESULT="" | |
# gpioname NET,LAN,WPS | |
# mode off,on,fastbrink,slowbrink | |
if [ "$CMD_QSTR" = "CLEAR" ]; then | |
CMD_RESULT=`/mnt/mygpio5a.exe s 12 11 14 1000 "CC"` | |
STATE_CLEAR="checked" | |
elif [ "$CMD_QSTR" = "LINE1" ]; then | |
CMD_RESULT=`/mnt/mygpio5a.exe s 12 11 14 1000 "C1"` | |
STATE_LINE1="checked" | |
elif [ "$CMD_QSTR" = "LINE2" ]; then | |
CMD_RESULT=`/mnt/mygpio5a.exe s 12 11 14 1000 "C2"` | |
STATE_LINE2="checked" | |
elif [ "$CMD_QSTR" = "DATA" ]; then | |
CMD_RESULT=`/mnt/mygpio5a.exe s 12 11 14 1000 "N"$DATA_QSTR` | |
STATE_DATA="checked" | |
fi | |
echo "<html><head><title>FON2405eのGPIOでキャラクタ液晶を操作する</title></head>" | |
echo "<body>" | |
echo "<h1>GPIOの制御(キャラクタ液晶の制御)</h1>" | |
echo "<div style='width:400px;border:#aaaaaa solid 1px;'>" | |
echo "<form method='get' action='test_lcd.cgi' id='cmd'>" | |
echo "<p><b>コマンド送信</b></p>" | |
echo "<div><input type='radio' name='cmd' value='CLEAR' $STATE_CLEAR>クリア</div>" | |
echo "<div><input type='radio' name='cmd' value='LINE1' $STATE_LINE1>1行目へ移動</div>" | |
echo "<div><input type='radio' name='cmd' value='LINE2' $STATE_LINE2>2行目へ移動</div>" | |
echo "<div><input type='radio' name='cmd' value='DATA' $STATE_DATA>文字出力</div>" | |
echo "<div><input type='input' name='data' size='32' maxlength='16' value='$DATA_QSTR'></div>" | |
echo "<p><input type='submit' value='送信'></p>" | |
echo "</form></div>" | |
echo "QUERY="$CMD_QSTR"<br>" | |
echo "DATA="$DATA_QSTR"<br>" | |
echo "RESULT="$CMD_RESULT"<br>" | |
echo "</body></html>" | |
FON2405EのGPIOでキャラクタ液晶を制御する(受信機能追加2)
目的
前回、受信機能を追加したが、1Byteのみだった。今回は、複数Byteの受信を拡張した。
結果
前回同様に1秒毎に顔文字「Adeno(^o^)mm-ss」※mm-ssは分-秒を送信し続けると、400回のコマンド送信に対して、送信NGは52回 13%くらい
なんか前よりも増えた気がする…。
受信の方は、PICから「Hello!!」を送信。100回中NGは5回 5%くらいか
こっちはこんなもんか??
これで、双方向の複数バイトデータを扱えるようになった。
ようやくここまで来た。
ラズベリーパイでも良いのだけれど、ちょっと高い。
このFONならば、中古だけど、ACアダプタと本体で 500円〜なので、
心置きなく遊び倒せる。
何をやったか
電文
変更点
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include "rcv_lib.h" | |
#include "lcd_lib.h" | |
volatile unsigned char rcv_state = 0; | |
volatile unsigned char rcv_poi = 0; | |
volatile unsigned char rcv_cmd = ' '; | |
volatile unsigned char rcv_buf[RCV_SIZE]; | |
volatile unsigned char rcv_timeoutflg = 0; | |
volatile unsigned char rcv_timeout = 0; | |
volatile unsigned char rcv_full = 0; | |
volatile unsigned char rcv_chksum = 0; | |
volatile unsigned char rcv_chksum_base = 0; | |
volatile unsigned char rcv_drv_state = 0; | |
void rcv_init(){ | |
//受信バッファの準備 | |
for(rcv_poi = 0; rcv_poi < RCV_SIZE; rcv_poi++){ | |
rcv_buf[rcv_poi] = ' '; | |
} | |
//drv | |
rcv_drv_state = RCV_DRV_STATE_S0_STXWAIT; | |
rcv_chksum = 0; | |
rcv_chksum_base = 0; | |
//app | |
rcv_full = 0; | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
rcv_cmd = ' '; | |
} | |
char read_byte(int i){ return rcv_buf[i]; } | |
void clearRCVflg(){ rcv_full = 0; } | |
char getRCVflg(){ return rcv_full; } | |
unsigned char getRCVcmd(){ return rcv_cmd; } | |
void rcv_byte(unsigned char c){ | |
if(rcv_full == 1){ | |
printf("BufFull>%c\r\n",c); | |
}else if(rcv_drv_state == RCV_DRV_STATE_S0_STXWAIT){ | |
if(c == rSTX){ | |
//printf("STX\r\n"); | |
rcv_cmd = ' '; | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
rcv_drv_state = RCV_DRV_STATE_S1_CHKSUMWAIT; | |
} | |
}else if(rcv_drv_state == RCV_DRV_STATE_S1_CHKSUMWAIT){ | |
rcv_chksum = 0; | |
rcv_chksum_base = c & 0x0f; | |
rcv_drv_state = RCV_DRV_STATE_S2_ETXWAIT; | |
//printf("Sum=%d\r\n",rcv_chksum_base); | |
}else if(rcv_drv_state == RCV_DRV_STATE_S2_ETXWAIT){ | |
if(c == rETX){ | |
rcv_chksum = rcv_chksum & 0xf; | |
if(rcv_chksum_base == rcv_chksum){ | |
rcv_buf[rcv_poi] = '\n'; | |
printf("ChkSumOK:%d\r\n",rcv_chksum); | |
rcv_full = 1; | |
}else{ | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
printf("ChkSumNG:%d:%d\r\n",rcv_chksum_base,rcv_chksum); | |
rcv_full = 2; | |
} | |
rcv_drv_state = RCV_DRV_STATE_S0_STXWAIT; | |
}else{ | |
rcv_chksum+= c; | |
if(rcv_state == RCV_STATE_S1_CMDWAIT){ | |
if(c == 'C'){ | |
rcv_state = RCV_STATE_S2_CMDWAIT2; | |
}else if(c == 'N'){ | |
rcv_poi = 0; | |
rcv_state = RCV_STATE_S3_DATAWAIT; | |
} | |
}else if(rcv_state == RCV_STATE_S2_CMDWAIT2){ | |
//コマンドを一時保存 | |
rcv_cmd = c; | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
}else if(rcv_state == RCV_STATE_S3_DATAWAIT){ | |
if(c == '\r'){ | |
}else{ | |
rcv_buf[rcv_poi] = c; | |
rcv_poi++; | |
//終了条件2:バッファがいっぱい | |
if(rcv_poi >= RCV_SIZE){ | |
rcv_poi = 0; | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
printf("End2\r\n"); | |
} | |
} | |
} | |
//printf("RCV>%c\r\n",c); | |
} | |
} | |
} |
2015年4月25日土曜日
FON2405EのGPIOでキャラクタ液晶を制御する(受信機能追加)
目的
前回、チェックサムと送達確認(PICマイコンからFONに対して応答)を行うようにした。今回は、送達確認を拡張して受信機能(PICマイコンからFONに対してコマンドを出せる)ようにした。
概要
チェックサムOKの場合に、FONに対してACKを送信する。シリアル通信のクロックはFON側で生成しているので、
イメージとしてはSPI通信に近いと思う。
結果
前回同様に1秒毎に顔文字「Adeno(^o^)mm-ss」※mm-ssは分-秒を送信し続けると、400回のコマンド送信に対して、送信NGは15回
80回のときは、2回 2〜3%くらい?
結果は地味だけど、PIC→FON方向の通信ができるようになったのは大きい
何をやったか
・フォーマット1.データを送信するとき
種類 方向
クロック FON→PIC 385us
送信データ [STX][チェックサム][DATA][ETX]
受信データPIC→FON 1byte前に対する受信結果
2.送信結果を確認するとき
種類 方向
クロック FON→PIC 385us
送信データ [ENQ]
受信データPIC→FON 1byte前に対する受信結果
黄色・・・クロック
水色・・・受信データ(PIC→FON)この場合はACK(0x06)
------------------------------------------------
gpio_write_sr Start:CLK=12 DATA_OUT=11 DATA_IN=14
Send:[STX][CHKSUM = 14][DATA][ETX]<-4ms->[ENQ]
Input = 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6
RcvChk = OK
Total Time = 307ms
------------------------------------------------
・FON側
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int gpio_io_byte(int port_clk,int port_in,int port_out,unsigned char *cin,unsigned char cout){ | |
int shift_clk = port_clk-8; | |
int shift_out = port_out-8; | |
unsigned char mask = 1 << 7; | |
int idx=1,fd,req_w,req_r,i,j,value,tmp; | |
int in_val=0; | |
*cin = 0; | |
fd = open(GPIO_DEV, O_RDONLY); | |
if (fd < 0) { | |
perror(GPIO_DEV); | |
return -1; | |
} | |
if (0L <= port_in && port_in < RALINK_GPIO_DATA_LEN | |
&& shift_clk >= 0 && shift_out >= 0){ | |
req_w = RALINK_GPIO_WRITE_BYTE | (idx << RALINK_GPIO_DATA_LEN); | |
req_r = RALINK_GPIO_READ_BIT | (port_in << RALINK_GPIO_DATA_LEN); | |
} else { | |
close(fd); | |
printf("gpio_io_byte: out of range\n"); | |
} | |
for(i=0;i<8;i++){ | |
value = 0; | |
tmp = 0; | |
if((cout & mask)>0){ value = 1;} | |
//clk reset(L) 1 with data set | |
for(j=0;j<385;j++){ //1.4us x 275 = 385us | |
tmp = (1<<shift_clk); | |
tmp |= (value<<shift_out); | |
tmp &= 0xff; | |
if (ioctl(fd, req_w, tmp) < 0) { perror("ioctl"); close(fd); return -1; } | |
} | |
//clk set(H) 0 with data set | |
for(j=0;j<385;j++){ | |
tmp = (value<<shift_out); | |
tmp &= 0xff; | |
if (ioctl(fd, req_w, tmp) < 0) { perror("ioctl"); close(fd); return -1; } | |
} | |
//data read | |
if(ioctl(fd,req_r,&in_val,0) < 0){ perror("ioctl"); close(fd); return -1; } | |
if(in_val == 0) | |
*cin = (*cin << 1); | |
else | |
*cin = (*cin << 1)+1; | |
//next mask | |
mask = mask >>1; | |
} | |
//clk set(H) 0 with data set aftertime | |
for(j=0;j<4000;j++){ | |
tmp = (value<<shift_out); | |
tmp &= 0xff; | |
if (ioctl(fd, req_w, tmp) < 0) { perror("ioctl"); close(fd); return -1; } | |
} | |
close(fd); | |
return 0; | |
} |
受信処理の後、に送信したいものを出力するだけ
↓受信処理
sr_buf = ((sr_buf<<1) & 0xFE) | (0x01 & DATA_PORT);
↓送信処理
//DATA 出力
if((sr_out & sr_out_mask) == 0){
DATA_OUT_PORT = 0;
}else{
DATA_OUT_PORT = 1;
}
sr_out_mask = sr_out_mask >> 1;
・エラー発生回数測定用スクリプト
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
myvar=1 | |
errvar=0 | |
sndvar=0 | |
retval=0 | |
while [ $myvar -ne $1 ] | |
do | |
echo ==================================================== SeqNo.$myvar | |
./mygpio5a.exe s 12 11 14 1000 "C2" | |
if [ $? -eq 2 ]; then | |
errvar=`expr $errvar + 1` | |
fi | |
sndvar=`expr $sndvar + 1` | |
usleep 100000 | |
./mygpio5a.exe s 12 11 14 1000 "NAdeno(-_-)"`date +%M-%S` | |
if [ $? -eq 2 ]; then | |
errvar=`expr $errvar + 1` | |
fi | |
sndvar=`expr $sndvar + 1` | |
usleep 400000 | |
./mygpio5a.exe s 12 11 14 1000 "C2" | |
if [ $? -eq 2 ]; then | |
errvar=`expr $errvar + 1` | |
fi | |
sndvar=`expr $sndvar + 1` | |
usleep 100000 | |
./mygpio5a.exe s 12 11 14 1000 "NAdeno(^o^)"`date +%M-%S` | |
if [ $? -eq 2 ]; then | |
errvar=`expr $errvar + 1` | |
fi | |
sndvar=`expr $sndvar + 1` | |
usleep 400000 | |
myvar=`expr $myvar + 1` | |
done | |
echo TotalSend=$sndvar | |
echo ErrSend=$errvar | |
2015年4月19日日曜日
FON2405EのGPIOでキャラクタ液晶を制御する(チェックサム追加)
目的
前回、なんとかFON2045E(RT3050)のGPIOを使って、キャラクタ液晶の制御を行ったが、受信が失敗してしまう場合があった。そこで、チェックサムと到達確認(PICマイコンからFONに対して応答)を行うようにした。
結果
チェックサムの導入によって、受信失敗したものは、破棄できるようになった。1秒毎に顔文字「Adeno(^o^)mm-ss」※mm-ssは分-秒
を送信し続けると、おおよそ1分に2回程度チャックサムエラーが発生している模様。
何をやったか
1.チェックサムの導入送信するデータを以下のように変更
[STX][チェックサム][DATA][ETX]
STX : 02h
チェックサム:DATA部の合計値を0〜15(下位4ビット分)
DATA :今まで送っていたデータ
ETX :03h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include "rcv_lib.h" | |
#include "lcd_lib.h" | |
volatile unsigned char rcv_state = 0; | |
volatile unsigned char rcv_poi = 0; | |
volatile unsigned char rcv_cmd = ' '; | |
volatile unsigned char rcv_buf[RCV_SIZE]; | |
volatile unsigned char rcv_timeoutflg = 0; | |
volatile unsigned char rcv_timeout = 0; | |
volatile unsigned char rcv_full = 0; | |
volatile unsigned char rcv_chksum = 0; | |
volatile unsigned char rcv_chksum_base = 0; | |
volatile unsigned char rcv_drv_state = 0; | |
void rcv_init(){ | |
//受信バッファの準備 | |
for(rcv_poi = 0; rcv_poi < RCV_SIZE; rcv_poi++){ | |
rcv_buf[rcv_poi] = ' '; | |
} | |
//drv | |
rcv_drv_state = RCV_DRV_STATE_S0_STXWAIT; | |
rcv_chksum = 0; | |
rcv_chksum_base = 0; | |
//app | |
rcv_full = 0; | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
rcv_cmd = ' '; | |
} | |
char read_byte(int i){ return rcv_buf[i]; } | |
void clearRCVflg(){ rcv_full = 0; } | |
char getRCVflg(){ return rcv_full; } | |
unsigned char getRCVcmd(){ return rcv_cmd; } | |
void rcv_byte(unsigned char c){ | |
if(rcv_full == 1){ | |
printf("BufFull>%c\r\n",c); | |
}else if(rcv_drv_state == RCV_DRV_STATE_S0_STXWAIT){ | |
if(c == rSTX){ | |
rcv_cmd = ' '; | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
rcv_drv_state = RCV_DRV_STATE_S1_CHKSUMWAIT; | |
} | |
}else if(rcv_drv_state == RCV_DRV_STATE_S1_CHKSUMWAIT){ | |
rcv_chksum = 0; | |
rcv_chksum_base = c & 0x0f; | |
rcv_drv_state = RCV_DRV_STATE_S2_ETXWAIT; | |
}else if(rcv_drv_state == RCV_DRV_STATE_S2_ETXWAIT){ | |
if(c == rETX){ | |
rcv_chksum = rcv_chksum & 0xf; | |
if(rcv_chksum_base == rcv_chksum){ | |
rcv_buf[rcv_poi] = '\n'; | |
printf("ChkSumOK:%d\r\n",rcv_chksum); | |
rcv_full = 1; | |
}else{ | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
printf("ChkSumNG:%d:%d\r\n",rcv_chksum_base,rcv_chksum); | |
rcv_full = 2; | |
} | |
rcv_drv_state = RCV_DRV_STATE_S0_STXWAIT; | |
}else{ | |
rcv_chksum+= c; | |
if(rcv_state == RCV_STATE_S1_CMDWAIT){ | |
if(c == 'C'){ | |
rcv_state = RCV_STATE_S2_CMDWAIT2; | |
}else if(c == 'N'){ | |
rcv_poi = 0; | |
rcv_state = RCV_STATE_S3_DATAWAIT; | |
} | |
}else if(rcv_state == RCV_STATE_S2_CMDWAIT2){ | |
//コマンドを一時保存 | |
rcv_cmd = c; | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
}else if(rcv_state == RCV_STATE_S3_DATAWAIT){ | |
if(c == '\r'){ | |
}else{ | |
rcv_buf[rcv_poi] = c; | |
rcv_poi++; | |
//終了条件2:バッファがいっぱい | |
if(rcv_poi >= RCV_SIZE){ | |
rcv_poi = 0; | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
printf("End2\r\n"); | |
} | |
} | |
} | |
} | |
} | |
} |
2.受信の追加
送信後に、readしているだけ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void gpio_test_write_sr(int gpio_clk, int gpio_out,int gpio_in,int delaytime, unsigned char *c){ | |
long gpiomask = 0x00FF1FFF; //0x00FFFFFF; | |
printf("set_dir=%ld\n",gpiomask); | |
gpio_set_dir(gpiomask); | |
int i,d,chksum; | |
printf("gpio_write_sr Start:CLK=%d DATA_OUT=%d DATA_IN=%d\n",gpio_clk,gpio_out,gpio_in); | |
struct timeval s,f; | |
gettimeofday(&s,NULL); | |
chksum = 0; | |
unsigned char RSTX = 0x02; | |
unsigned char RETX = 0x03; | |
gpio_write_byte3(gpio_clk,gpio_out,RSTX); | |
for(i=0;i<17;i++){ | |
if(*(c+i) == '\0'){ /*chksum += '\n';*/ break; | |
}else{ chksum += *(c+i); } | |
} | |
unsigned char RCHKSUM = (unsigned char)(chksum & 0xf); | |
gpio_write_byte3(gpio_clk,gpio_out,RCHKSUM); | |
for(i=0;i<17;i++){ | |
if(*(c+i) == '\0'){ | |
/*gpio_write_byte3(gpio_clk,gpio_out,'\n');*/ | |
break; | |
}else{ | |
gpio_write_byte3(gpio_clk,gpio_out,*(c+i)); | |
} | |
} | |
gpio_write_byte3(gpio_clk,gpio_out,RETX); | |
printf("ChkSum=%d\n",RCHKSUM); | |
gpio_set_dir(RALINK_GPIO_DIR_ALLIN); | |
gpio_read_bit(gpio_in, &d); | |
printf("Input--------------------->%d\n", d); | |
gettimeofday(&f,NULL); | |
printf("Total Time=%dms\n",(f.tv_sec-s.tv_sec)*1000+(f.tv_usec-s.tv_usec)/1000); | |
} |
PICからの戻りは画面に表示しているだけだけど、
今後は、再送とか実装していきたい。
2015年4月13日月曜日
WAPM-HP-AM54G54を入手
はじまり
近所のリサイクルショップで見慣れない形状の無線LANAPを発見。業務用らしい。アンテナがなくて、500円。
別に無線を出したいわけでは無いので、これでもOKです。
どんなものか
外観はこんな感じ。ぼろぼろ(笑)赤丸のところにUARTがあるようだ。
miniPCI×2とか富豪だね。他のカードに変えたら面白いかな。
PoE対応なので、それで遊ぶのも面白いかも。
今後の目標
もちろんOpenWrt化2015年4月5日日曜日
FON2405EのGPIOでキャラクタ液晶を制御する(高速化)
目的
先週、FON2045E(RT3050)のGPIOを使って、キャラクタ液晶の制御を行ったが、1行(16文字)表示するのに、1.6秒かかってしまっていた。
今回これの高速化を目指す。
受信側(PIC)の高速化によって改善できないかを実験。
結果
1.6秒→0.5秒にまで短縮することができた。
何をやったか
FON側・・・クロック生成をusleep(4ms)からビジータイマー1460μsに変更
PIC側・・・1ms周期の割り込みによるデータサンプリングを480usに変更
デバック出力としてのUART出力をエラー時のみに変更
● クロック生成の変更
GPIOの制御に1.4μs要するので、これを1000回繰り返しただけ。
それで1460μs消費させる。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
for(i=0;i<8;i++){ | |
//========================================== | |
//for pic | |
value = 0; | |
tmp = 0; | |
if((c & mask)>0){ value = 1;} | |
//clk reset(L) 1 with data set | |
for(j=0;j<1000;j++){ //1.4us x 1000 = 1460us | |
tmp = (1<<shift_clk); | |
tmp |= (value<<shift_data); | |
tmp &= 0xff; | |
if (ioctl(fd, req, tmp) < 0) { perror("ioctl"); close(fd); return -1; } | |
} | |
//clk set(H) 0 with data set | |
for(j=0;j<1000;j++){ | |
tmp = (value<<shift_data); | |
tmp &= 0xff; | |
if (ioctl(fd, req, tmp) < 0) { perror("ioctl"); close(fd); return -1; } | |
} | |
mask = mask >>1; | |
} |
480μs もう少し攻めても大丈夫な気がするけど、余裕をみて。
PICは4MHzで動作しているので、1サイクルあたり1μs。
割り込み間隔100μsくらいでも 行けそうな気がする。
2015年3月30日月曜日
FON2405EのGPIOでキャラクタ液晶を制御する
先週からGPIOの出力が一部間延びしてしまうことで、行き詰っていた。
気分を変えて、同期シリアル通信でキャラクタ液晶を制御したいと考えた。
結論から書くと、以下の2点の課題から、表示速度はすこぶる遅い。
1.仲介役のPICマイコンの動作速度は4MHz(内臓のオシレーターを使ったため)
2.やっぱりGPIO出力が間延びするから1クロック4msのディレーを入れた
16文字のデータを送るのに、現状1.3秒かかる。
いざまとめるとこんなものなのだけど、なかなか時間がかかったし、
間延び問題が気になる・・・。
ハード
FON2405EのGPIO---CLK,DATA---PICマイコン---キャラクタ液晶
ソフト
1.gpioのドライバ
2.gpioのアプリ
3.PICマイコンのファーム
1.gpioのドライバ
標準のものから変更なし
RALINK_GPIO_WRITE_BYTEを使用。
今までの試行錯誤は何だったんだ・・・・。
2.gpioのアプリ
変更点
オプション[s]を追加
s <gpio clk> <gpio data> <delaytime> <char>
これを指定するとgptio_test_write_srを呼ぶようにした。
usleepを使うと4ms以下にはならないようだし、
ドライバの方で、udelayを使って短くしても、
前回の間延び問題のように不安定になってしまう。
なので、CLKの変化のタイミングだけusleepを使って、
DATAのセット部分はディレーなしにした。
多少は速くなった。
3.PICマイコンのファーム
変更点
1ms毎にタイマー割り込みを行って、
CLKがH→L(立ち下がり)のタイミングを探す。
更に1ms経過してもLの状態だったら、DATAを読み込む。
main.c
rcv_lib.c
気分を変えて、同期シリアル通信でキャラクタ液晶を制御したいと考えた。
結論から書くと、以下の2点の課題から、表示速度はすこぶる遅い。
1.仲介役のPICマイコンの動作速度は4MHz(内臓のオシレーターを使ったため)
2.やっぱりGPIO出力が間延びするから1クロック4msのディレーを入れた
16文字のデータを送るのに、現状1.3秒かかる。
いざまとめるとこんなものなのだけど、なかなか時間がかかったし、
間延び問題が気になる・・・。
ハード
FON2405EのGPIO---CLK,DATA---PICマイコン---キャラクタ液晶
ソフト
1.gpioのドライバ
2.gpioのアプリ
3.PICマイコンのファーム
1.gpioのドライバ
標準のものから変更なし
RALINK_GPIO_WRITE_BYTEを使用。
今までの試行錯誤は何だったんだ・・・・。
2.gpioのアプリ
変更点
オプション[s]を追加
s <gpio clk> <gpio data> <delaytime> <char>
これを指定するとgptio_test_write_srを呼ぶようにした。
usleepを使うと4ms以下にはならないようだし、
ドライバの方で、udelayを使って短くしても、
前回の間延び問題のように不安定になってしまう。
なので、CLKの変化のタイミングだけusleepを使って、
DATAのセット部分はディレーなしにした。
多少は速くなった。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void gpio_test_write_sr(int gpio_clk, int gpio_data,int delaytime, unsigned char *c){ | |
gpio_write_int(RALINK_GPIO_DATA_MASK); | |
int i; | |
printf("gpio_write_sr Start:CLK=%d DATA=%d\n",gpio_clk,gpio_data); | |
struct timeval s,f; | |
gettimeofday(&s,NULL); | |
for(i=0;i<17;i++){ | |
if(*(c+i) == '\0'){ break;} | |
gpio_write_byte3(gpio_clk,gpio_data,*(c+i)); | |
usleep(delaytime); //10ms | |
//sleep(1); | |
} | |
gettimeofday(&f,NULL); | |
printf("Total Time=%dms\n",(f.tv_sec-s.tv_sec)*1000+(f.tv_usec-s.tv_usec)/1000); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int gpio_write_byte3(int port_clk,int port_data,unsigned char c){ | |
int idx = 1, fd, req, i, value, tmp, udelay; | |
int shift_clk = port_clk - 8; | |
int shift_data = port_data - 8; | |
unsigned char mask = 1<<7; | |
struct timeval s,f; | |
//gettimeofday(&s,NULL); | |
udelay = RALINK_GPIO_UDELAY; | |
fd = open(GPIO_DEV, O_RDONLY); | |
if (fd < 0) { | |
perror(GPIO_DEV); | |
return -1; | |
} | |
//printf("shift_clk=%d shift_data=%d\n",shift_clk,shift_data); | |
if (0L <= idx && idx < RALINK_GPIO_DATA_LEN/8 && shift_clk >= 0 && shift_data >= 0) | |
req = RALINK_GPIO_WRITE_BYTE | (idx << RALINK_GPIO_DATA_LEN); | |
else { | |
close(fd); | |
printf("gpio_write_byte: index %d out of range\n", idx); | |
} | |
printf("target data:%c\n",c); | |
for(i=0;i<8;i++){ | |
//gettimeofday(&s,NULL); | |
value = 0; | |
tmp = 0; | |
if((c & mask)>0){ value = 1;} | |
else { value = 0;} | |
//printf("target data:%d\n",value); | |
//clk reset(L) 1 | |
tmp = (1<<shift_clk); | |
tmp &= 0xff; | |
if (ioctl(fd, req, tmp) < 0) { perror("ioctl"); close(fd); return -1; } | |
//printf("clk L\n"); | |
//if (ioctl(fd, udelay,delaytime) < 0) { perror("ioctl"); close(fd); return -1;} | |
//usleep(500); //4ms | |
//data set | |
tmp = (1<<shift_clk); | |
tmp |= (value<<shift_data); | |
tmp &= 0xff; | |
if (ioctl(fd, req, tmp) < 0) { perror("ioctl"); close(fd); return -1; } | |
//printf("data set\n"); | |
//usleep(500); | |
//if (ioctl(fd, udelay,delaytime) < 0) { perror("ioctl"); close(fd); return -1;} | |
//clk reset(H) 0 | |
tmp = (value<<shift_data); | |
tmp &= 0xff; | |
if (ioctl(fd, req, tmp) < 0) { perror("ioctl"); close(fd); return -1; } | |
//printf("clk L->H\n"); | |
usleep(500); //4ms | |
//if (ioctl(fd, udelay,delaytime) < 0) { perror("ioctl"); close(fd); return -1;} | |
//clk set(L) 1 | |
tmp = (1<<shift_clk); | |
tmp |= (value<<shift_data); | |
tmp &= 0xff; | |
if (ioctl(fd, req, tmp) < 0) { perror("ioctl"); close(fd); return -1; } | |
//printf("clk H->L\n"); | |
usleep(500); //4ms target sampling time = 500us * 3 = 1500us | |
//if (ioctl(fd, udelay,delaytime) < 0) { perror("ioctl"); close(fd); return -1;} | |
mask = mask >>1; | |
//gettimeofday(&f,NULL); | |
//printf("Total Time=%dms\n",(f.tv_sec-s.tv_sec)*1000+(f.tv_usec-s.tv_usec)/1000); | |
} | |
close(fd); | |
return 0; | |
} |
3.PICマイコンのファーム
変更点
1ms毎にタイマー割り込みを行って、
CLKがH→L(立ち下がり)のタイミングを探す。
更に1ms経過してもLの状態だったら、DATAを読み込む。
main.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* File: main.c | |
* Author: adeno | |
* | |
* Created on 2014/12/07, 13:14 | |
* RT3050F接続のテスト用 | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <xc.h> | |
#include "lcd_lib.h" | |
#include "rcv_lib.h" | |
/* | |
* | |
*/ | |
// CONFIG | |
#pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN) | |
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) | |
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) | |
#pragma config MCLRE = ON // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR) | |
#pragma config BOREN = ON // Brown-out Detect Enable bit (BOD enabled) | |
#pragma config LVP = ON // Low-Voltage Programming Enable bit (RB4/PGM pin has PGM function, low-voltage programming enabled) | |
#pragma config CPD = OFF // Data EE Memory Code Protection bit (Data memory code protection off) | |
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) | |
#define _XTAL_FREQ 4000000 //delay用に必要(クロック4MHzを指定) | |
#define TMR0_CNT 252 //TMR0カウント値設定 | |
#define CLK_PORT RB5 | |
#define DATA_PORT RB7 | |
#define LCD_ROW 16 | |
#define LCD_COL 2 | |
#define RCV_TIMEOUT 10 //受信タイムアウト 65ms * 10 | |
#define DIST_UART 1 | |
#define DIST_LCD 0 | |
unsigned char dist; //標準出力の出力先 | |
void putch(unsigned char c){ | |
if(dist == DIST_LCD) | |
lcd_data(c); | |
else if(dist == DIST_UART){ | |
while(!TXIF) | |
continue; | |
TXREG = c; | |
} | |
return; | |
} | |
//LCD用表示バッファ | |
volatile char lcd_buf[LCD_ROW+1]; | |
volatile unsigned char lcd_poi = 0; | |
volatile unsigned char lcd_col_poi = 1; //書き込み行数 | |
//SRの | |
unsigned char clk_port_buf; | |
unsigned char sr_timeoutcnt = 0; | |
volatile unsigned char sr_bit = 0; | |
volatile unsigned char sr_buf; | |
int main(int argc, char** argv) { | |
//PORTA 0,1,2,3 LCD DATA | |
//PORTA 7 E | |
//PORTA 6 RS | |
//PORTB 1 RX | |
//PORTB 2 TX | |
//PORTB 4 Debug | |
//PORTB 5 Input(CLK) | |
//PORTB 7 Input(DATA) | |
//PORTB 0,3 外部IO | |
PORTA = 0b00000000; //PORTAの中身をきれいにする | |
TRISA = 0b00000000; //PORTAは 1:入力 0:出力 | |
PORTB = 0b01000101; //PORTBの中身をきれいにする | |
TRISB = 0b10110010; //PORTBは 1:入力 0:出力 | |
//シリアル通信(ボーレート) | |
SYNC = 0; //非同期 | |
BRGH = 1; //高速サンプル | |
SPBRG = 25; //4,000,000Hz / (16 * Baud) - 1 | |
// | |
//シリアル送信 | |
CSRC = 1; | |
TX9 = 0; | |
TXEN = 1; | |
//シリアル受信 | |
SPEN = 1; | |
RX9 = 0; | |
CREN = 1; | |
ADEN = 0; | |
FERR = 0; | |
OERR = 0; | |
RX9D = 0; | |
//TMR0の割り込み初期設定 | |
//0.25us(4MHz)*4*プリスケーラ−256 = 256us | |
//TMR0hは255-3 = 252 | |
OPTION_REG = 0b0111; //プリスケーラ値設定0b0111(=256回) | |
TMR0 = TMR0_CNT; //TMR0カウント値設定 | |
clk_port_buf = 0; | |
sr_timeoutcnt = 0; | |
//LCDの初期化 | |
lcd_init(); | |
//LCDの表示クリア | |
lcd_clear(); | |
dist = DIST_LCD; | |
printf("Hello World!"); | |
//lcd_cmd(0xc0); | |
//lcd_data('a'); | |
//232に出力 | |
dist = DIST_UART; | |
printf("Hello World!\r\n"); | |
//受信バッファの準備 | |
rcv_init(); | |
//LCDバッファの準備 | |
for(lcd_poi = 0; lcd_poi < LCD_ROW; lcd_poi++){ | |
lcd_buf[lcd_poi] = ' '; | |
} | |
lcd_buf[LCD_ROW] = '\0'; | |
lcd_poi = 0; | |
/// | |
lcd_cmd(0xc0); | |
dist = DIST_LCD; | |
printf(lcd_buf); | |
PEIE = 1; | |
INTCONbits.TMR0IE =1; //タイマ割込み許可 | |
RCIE = 1; //RX割り込みをイネーブル | |
INTCONbits.GIE = 1; //全体割込み許可 | |
while(1) { | |
PORTB = 0b00001010; | |
__delay_ms(100); | |
PORTB = 0b00000010; | |
__delay_ms(100); | |
if(getRCVflg() == 1){ | |
//C:コマンド | |
// C:clear 全クリア | |
//I:文字列追加 | |
//N:文字列新規 | |
//if(rcv_buf[0] == 'N' && rcv_buf[1] == ':'){ | |
//以降は文字列 | |
for(lcd_poi = 0; lcd_poi < LCD_ROW; lcd_poi++){ | |
if(read_byte(lcd_poi) != '\n' ){ | |
lcd_buf[lcd_poi] = read_byte(lcd_poi); | |
}else{ | |
break; | |
} | |
} | |
for(;lcd_poi < LCD_ROW; lcd_poi++){ | |
lcd_buf[lcd_poi] = '.'; | |
} | |
lcd_change_col(lcd_col_poi); | |
//lcd_cmd(0xc0); | |
dist = DIST_LCD; | |
printf(lcd_buf); | |
/*}else if(rcv_buf[0] == 'C' && rcv_buf[1] == ':'){ | |
}*/ | |
clearRCVflg(); | |
//RCIE = 1; //RX割り込み再開 | |
} | |
//lcd_cmd(0xc0); | |
} | |
return (EXIT_SUCCESS); | |
} | |
void interrupt isr(void) //割込み関数 | |
{ | |
if (RCIF) | |
{ | |
//rx_data = RCREG; | |
//受信タイムアウトフラグセット | |
//rcv_timeoutflg = 1; | |
//rcv_timeout = RCV_TIMEOUT; | |
unsigned char rcv_wk = ' '; | |
if(FERR) | |
{ | |
rcv_wk = RCREG; | |
//rx_data = 'F'; | |
}else if(OERR) | |
{ | |
CREN = 0; | |
NOP(); | |
CREN = 1; | |
//rx_data = 'O'; | |
}else{ | |
dist = DIST_UART; | |
rcv_byte(RCREG); | |
} | |
}else if(INTCONbits.TMR0IF == 1) { //割込み種がTimer0割込みの場合 | |
INTCONbits.TMR0IF = 0; //Timer0割り込みフラグクリアー | |
TMR0 = TMR0_CNT; //TMR0カウント値設定 | |
sr_timeoutcnt++; | |
if(sr_timeoutcnt > 250 && sr_bit > 0){ | |
sr_bit = 0; | |
sr_timeoutcnt = 0; | |
dist = DIST_UART; | |
printf("TIMEOUT:%c\r\n",sr_buf); | |
} | |
if(CLK_PORT == 0){ | |
if(clk_port_buf == 1){ | |
//clk high | |
//DATA READ | |
clk_port_buf = 2; | |
sr_buf = (sr_buf<<1) | (0x01 & DATA_PORT); | |
sr_bit++; | |
sr_timeoutcnt = 0; | |
if(sr_bit > 7){ | |
sr_bit = 0; | |
dist = DIST_UART; | |
rcv_byte(sr_buf); | |
/*if(DATA_PORT == 1) | |
printf("CLK H->L:DATA H\r\n"); | |
else | |
printf("CLK H->L:DATA L\r\n");*/ | |
} | |
}else if(clk_port_buf > 1){ | |
}else{ | |
clk_port_buf = 1; | |
} | |
}else{ | |
clk_port_buf = 0; | |
} | |
/*if(rcv_timeoutflg == 1){ | |
if(rcv_timeout == 0){ | |
//終了条件3:タイムアウト? | |
//受信データの破棄 | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
dist = DIST_UART; | |
printf("Rcv Timeout\r\n"); | |
}else{ | |
rcv_timeout--; | |
} | |
}*/ | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include "rcv_lib.h" | |
#include "lcd_lib.h" | |
volatile unsigned char rcv_state = 0; | |
volatile unsigned char rcv_poi = 0; | |
volatile unsigned char rcv_cmd = ' '; | |
volatile unsigned char rcv_buf[RCV_SIZE]; | |
volatile unsigned char rcv_timeoutflg = 0; | |
volatile unsigned char rcv_timeout = 0; | |
volatile unsigned char rcv_full = 0; | |
void rcv_init(){ | |
//受信バッファの準備 | |
for(rcv_poi = 0; rcv_poi < RCV_SIZE; rcv_poi++){ | |
rcv_buf[rcv_poi] = ' '; | |
} | |
rcv_full = 0; | |
} | |
char read_byte(int i){ return rcv_buf[i]; } | |
void clearRCVflg(){ rcv_full = 0; } | |
char getRCVflg(){ return rcv_full; } | |
void rcv_byte(unsigned char c){ | |
if(rcv_full == 1){ | |
printf("BufferFull>%c\r\n",c); | |
}else if(rcv_state == RCV_STATE_S1_CMDWAIT){ | |
rcv_poi = 0; | |
if(c == 'C'){ | |
rcv_timeoutflg = 0; | |
rcv_state = RCV_STATE_S2_CMDWAIT2; | |
//dist = DIST_UART; | |
printf("RCV>C\r\n"); | |
//return "RCV>C\r\n"; | |
}else if(c == 'N'){ | |
rcv_timeoutflg = 0; | |
rcv_state = RCV_STATE_S3_DATAWAIT; | |
//dist = DIST_UART; | |
printf("RCV>N\r\n"); | |
//return "RCV>N\r\n"; | |
}else{ | |
//dist = DIST_UART; | |
printf("Wait for CommandCode. But Rcv>%c\r\n",c); | |
//return "Wait for CommandCode. But Rcv>"+c+"\r\n"; | |
} | |
}else if(rcv_state == RCV_STATE_S2_CMDWAIT2){ | |
//コマンドを一時保存 | |
rcv_timeoutflg = 0; | |
rcv_cmd = c; | |
rcv_state = RCV_STATE_S4_CMDFINWAIT; | |
//dist = DIST_UART; | |
printf("Command RCV>%c\r\n",c); | |
//return "Command RCV>"+c+"\r\n"; | |
}else if(rcv_state == RCV_STATE_S4_CMDFINWAIT){ | |
if(c == '>'){ | |
rcv_timeoutflg = 0; | |
//コマンドの終了条件 | |
if(rcv_cmd == 'C'){ | |
//全クリア | |
lcd_clear(); | |
}else if(rcv_cmd == '1'){ | |
//カーソルを1行目に | |
lcd_change_col(0); | |
}else if(rcv_cmd == '2'){ | |
//カーソルを2行目に | |
lcd_change_col(1); | |
} | |
//dist = DIST_UART; | |
printf("done\r\n"); | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
//return "done\r\n"; | |
}else{ | |
//dist = DIST_UART; | |
printf("Wait for '>'. But Rcv>%c\r\n",c); | |
//return "Wait for '>'. But Rcv>"+c+"\r\n"; | |
} | |
}else if(rcv_state == RCV_STATE_S3_DATAWAIT){ | |
//dist = DIST_UART; | |
printf("Data RCV>%c poi:%d\r\n",c,rcv_poi); | |
if(c == '\n'){ | |
//終了条件1:\n | |
rcv_buf[rcv_poi] = c; | |
//RCIE = 0; //RX割り込み一時停止 | |
rcv_poi = 0; | |
rcv_timeoutflg = 0; | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
//rx_flg = 1; | |
rcv_full = 1; | |
//dist = DIST_UART; | |
printf("RCV FIN 1\r\n"); | |
}else if(c == '\r'){ | |
//\rは無視 | |
rcv_timeoutflg = 0; | |
}else{ | |
rcv_timeoutflg = 0; | |
rcv_buf[rcv_poi] = c; | |
rcv_poi++; | |
//終了条件2:バッファがいっぱい | |
if(rcv_poi >= RCV_SIZE){ | |
//RCIE = 0; //RX割り込み一時停止 | |
rcv_poi = 0; | |
rcv_state = RCV_STATE_S1_CMDWAIT; | |
//rx_flg = 1; | |
rcv_full = 1; | |
//dist = DIST_UART; | |
printf("RCV FIN 2\r\n"); | |
} | |
} | |
} | |
} |
2015年3月23日月曜日
FON2405EのGPIOでなんちゃってシリアル通信
GPIOの制御が少しわかってきたので、
前回、同期シリアル通信の下準備を行った。
汎用性とか考えると、やっぱりUART(調歩シリアル通信)をやってみたくなり、
ドライバ部分を書き換えてみた。
実験なので、通信速度は9600bpsで、パリティなし、ストップビットは1ビットとした。
やっていることは、結構単純で、1クロック分=1^6μs ÷9600=104μs分ごとにデータを出力するというもの。
http://www5b.biglobe.ne.jp/~kouta_y/news/newsvb/vb14.html
まず、比較のためにFT232RLにて'a'の1文字を送信した場合
調べたとおり、104μsになっていた。
これを目指して、作ってみよう。
linux-2.6.21.x/drivers/char/ralink_gpio.cに追記
80行目付近にある[int ralink_gpio_ioctl]のcase文に
case RALINK_GPIO_UART_SEND:
base_delay = 104;
c = (unsigned char)(arg & 0xFFl);
if (0L <= idx && idx < RALINK_GPIO_DATA_LEN) {
tmp =le32_to_cpu(*(volatile u32 *)(RALINK_REG_PIODATA));
//H
tmp2 = tmp | (1L << idx);
*(volatile u32 *)(RALINK_REG_PIODATA)= cpu_to_le32(tmp2);
udelay(base_delay*3);
//start_bit(L)
tmp2 = tmp & ~(1L << idx);
*(volatile u32 *)(RALINK_REG_PIODATA)= cpu_to_le32(tmp2);
udelay(base_delay);
//data loop
for(i=0; i<8; i++){
if((c & mask) > 0){
//h
tmp2 = tmp | (1L << idx);
}else{
//l
tmp2 = tmp & ~(1L << idx);
}
*(volatile u32 *)(RALINK_REG_PIODATA)= cpu_to_le32(tmp2);
udelay(base_delay);
mask = mask <<1;
}
//stop bit
tmp2 = tmp | (1L << idx);
*(volatile u32 *)(RALINK_REG_PIODATA)= cpu_to_le32(tmp2);
udelay(base_delay*3);
}else
return -EINVAL;
break;
この結果が以下の通り
まぁなんとかそれっぽいものがでてきた。
いざ受信させて見ると、10回に1回くらい取りこぼしてしまう。
(成功の場合)
(失敗の場合)
データの中間くらいが間延びしているように見える・・・。
なーぜーー
前回、同期シリアル通信の下準備を行った。
汎用性とか考えると、やっぱりUART(調歩シリアル通信)をやってみたくなり、
ドライバ部分を書き換えてみた。
実験なので、通信速度は9600bpsで、パリティなし、ストップビットは1ビットとした。
やっていることは、結構単純で、1クロック分=1^6μs ÷9600=104μs分ごとにデータを出力するというもの。
http://www5b.biglobe.ne.jp/~kouta_y/news/newsvb/vb14.html
まず、比較のためにFT232RLにて'a'の1文字を送信した場合
調べたとおり、104μsになっていた。
これを目指して、作ってみよう。
linux-2.6.21.x/drivers/char/ralink_gpio.cに追記
80行目付近にある[int ralink_gpio_ioctl]のcase文に
case RALINK_GPIO_UART_SEND:
base_delay = 104;
c = (unsigned char)(arg & 0xFFl);
if (0L <= idx && idx < RALINK_GPIO_DATA_LEN) {
tmp =le32_to_cpu(*(volatile u32 *)(RALINK_REG_PIODATA));
//H
tmp2 = tmp | (1L << idx);
*(volatile u32 *)(RALINK_REG_PIODATA)= cpu_to_le32(tmp2);
udelay(base_delay*3);
//start_bit(L)
tmp2 = tmp & ~(1L << idx);
*(volatile u32 *)(RALINK_REG_PIODATA)= cpu_to_le32(tmp2);
udelay(base_delay);
//data loop
for(i=0; i<8; i++){
if((c & mask) > 0){
//h
tmp2 = tmp | (1L << idx);
}else{
//l
tmp2 = tmp & ~(1L << idx);
}
*(volatile u32 *)(RALINK_REG_PIODATA)= cpu_to_le32(tmp2);
udelay(base_delay);
mask = mask <<1;
}
//stop bit
tmp2 = tmp | (1L << idx);
*(volatile u32 *)(RALINK_REG_PIODATA)= cpu_to_le32(tmp2);
udelay(base_delay*3);
}else
return -EINVAL;
break;
この結果が以下の通り
まぁなんとかそれっぽいものがでてきた。
いざ受信させて見ると、10回に1回くらい取りこぼしてしまう。
(成功の場合)
(失敗の場合)
データの中間くらいが間延びしているように見える・・・。
なーぜーー
2015年3月15日日曜日
FON2405EのGPIOの速度(かなり改善)
昨日すこし改善できたGPIOの速度。
もう少し何とかならないかと、探していたら
こんなHPを発見
http://d.hatena.ne.jp/naoya/20080122/1200960926
http://proger.blog10.fc2.com/blog-entry-64.html
なるほど合点です。4msより早くならない理由はusleepが原因でしたか。
早速、usleepを削除してみると、4msが1.3μsになりました!!
つまり1周期2.6μsだから384KHz
なので、8bit分送るのには18.4μs!
ざっくり16文字×2行の液晶に表示する場合は、 588μsこれなら全く問題にならないね!
ちなみに、ドライバー部分で無理やりループした場合は、
1周期が400nsなので2.5MHz!
チョッ速になった。これでPICとの高速通信も問題なくできそう
もう少し何とかならないかと、探していたら
こんなHPを発見
http://d.hatena.ne.jp/naoya/20080122/1200960926
http://proger.blog10.fc2.com/blog-entry-64.html
なるほど合点です。4msより早くならない理由はusleepが原因でしたか。
早速、usleepを削除してみると、4msが1.3μsになりました!!
つまり1周期2.6μsだから384KHz
なので、8bit分送るのには18.4μs!
ざっくり16文字×2行の液晶に表示する場合は、 588μsこれなら全く問題にならないね!
ちなみに、ドライバー部分で無理やりループした場合は、
1周期が400nsなので2.5MHz!
チョッ速になった。これでPICとの高速通信も問題なくできそう
2015年3月14日土曜日
FON2405EのGPIOの速度(すこし改善)
gpioコマンドを眺めていたら、
LED用のオプション「l」の他に
テストとして「w」があることにやっと気づいた。
そのままだと、1秒おきに1〜23までのGPIOの出力を変化させるだけなので、
少し変更して、特定のGPIOポートをパタパタさせるようにした。
user/rt2880_app/gpio内のgpio.c
gpio_test_write関数のgpio_write_initの後に
for(i=0; i< 1000; i++){
gpio_write_bit(11,0);
usleep(1);
gpio_write_bit(11,1);
usleep(1);
}
というのを挿入して、コンパイル。
/opt/buildroot-gcc342/bin/mipsel-linux-gcc \
-I/home/adeno/fongpio/sdk3301/RT288x_SDK/source/linux-2.6.21.x/drivers/char \
-I/home/adeno/fongpio/sdk3301/RT288x_SDK/source/linux-2.6.21.x/include \
-L/home/adeno/fongpio/sdk3301/RT288x_SDK/source/linux-2.6.21.x/lib \
-o mygpio mygpio.c
そして、mygpio wを実行してみると
おぉ!ちょっと速くなった! 4ms!!
100msとか780msから比べると激速だね!
1つをクロックとして、もう1つをデータとした場合、
下がクロック、上がデータ a(61h)をbit0から送った場合
クロックの立ち下がりで読み込んだとして、84msかかる。
ざっくり16文字×2行の液晶に表示する場合は、2.7秒近くかかることになるのか・・。
データを2ポートにすれば、 1.3秒くらい。
まだ遅いな。
クロックが一定であれば、UARTみたいにできるのだけど、
4msが8msになっている見えるところがある…。
さてどうしたものか
LED用のオプション「l」の他に
テストとして「w」があることにやっと気づいた。
そのままだと、1秒おきに1〜23までのGPIOの出力を変化させるだけなので、
少し変更して、特定のGPIOポートをパタパタさせるようにした。
user/rt2880_app/gpio内のgpio.c
gpio_test_write関数のgpio_write_initの後に
for(i=0; i< 1000; i++){
gpio_write_bit(11,0);
usleep(1);
gpio_write_bit(11,1);
usleep(1);
}
というのを挿入して、コンパイル。
/opt/buildroot-gcc342/bin/mipsel-linux-gcc \
-I/home/adeno/fongpio/sdk3301/RT288x_SDK/source/linux-2.6.21.x/drivers/char \
-I/home/adeno/fongpio/sdk3301/RT288x_SDK/source/linux-2.6.21.x/include \
-L/home/adeno/fongpio/sdk3301/RT288x_SDK/source/linux-2.6.21.x/lib \
-o mygpio mygpio.c
そして、mygpio wを実行してみると
おぉ!ちょっと速くなった! 4ms!!
100msとか780msから比べると激速だね!
1つをクロックとして、もう1つをデータとした場合、
下がクロック、上がデータ a(61h)をbit0から送った場合
クロックの立ち下がりで読み込んだとして、84msかかる。
ざっくり16文字×2行の液晶に表示する場合は、2.7秒近くかかることになるのか・・。
データを2ポートにすれば、 1.3秒くらい。
まだ遅いな。
クロックが一定であれば、UARTみたいにできるのだけど、
4msが8msになっている見えるところがある…。
さてどうしたものか
2015年3月10日火曜日
busyboxでttyのボーレートを変更したい
FON2405EのシリアルコンソールttyS1のボーレートを57600から9600に変更したかった。
ググるとsttyを使って〜とあったので、sttyを含めた形でカーネル再構築。
sttyコマンドを使ってボーレートを指定しても変化なかった。
他のプロセスで使用していると変更できないらしい。
シリアルコンソールを一時的に止めてみるかと
inittabを変更
sdk3301/RT288x_SDK/source/venders/Ralink/RT3052/inittab
ここにttyS1::respawn:/bin/shというのがある。
しかしいきなり変えるのも怖いので、
ttyS1::askfirst:/sbin/getty 9600 ttyS1
とした。
別途gettyを含めて再構築。
結果・・・失敗です。なぜか57600で動きやがる。。。
ググるとsttyを使って〜とあったので、sttyを含めた形でカーネル再構築。
sttyコマンドを使ってボーレートを指定しても変化なかった。
他のプロセスで使用していると変更できないらしい。
シリアルコンソールを一時的に止めてみるかと
inittabを変更
sdk3301/RT288x_SDK/source/venders/Ralink/RT3052/inittab
ここにttyS1::respawn:/bin/shというのがある。
しかしいきなり変えるのも怖いので、
ttyS1::askfirst:/sbin/getty 9600 ttyS1
とした。
別途gettyを含めて再構築。
結果・・・失敗です。なぜか57600で動きやがる。。。
2015年3月2日月曜日
いろいろな進捗
なかなか最近意識が発散気味なのだけれど、
いくつかやることを絞っていきたいと思う。
1.FONなどRT305x搭載のルーターの使い道
勢いで入手したものもあり、現在4台。
何に使うか。
現状はキャラクタ液晶を接続できるように計画中。
複数台の並列プログラミングとかもやってみたい
2.7セグLED基板のファーム開発
I2C部分をまだ作っていない。
ラズベリーパイに接続するために、この部分を作ろう。
これは比較的早くできそう。
3.FPGAにオープンCPUコアを入れることをやってみたい
4.しりとりで用意したウィキペディアのデータを
他の用途でも使う。
5.SDRでなにかやる?
勢いで、DS-DT305を入手したけど・・・。
こんな感じだ。今月も頑張ろう。
いくつかやることを絞っていきたいと思う。
1.FONなどRT305x搭載のルーターの使い道
勢いで入手したものもあり、現在4台。
何に使うか。
現状はキャラクタ液晶を接続できるように計画中。
複数台の並列プログラミングとかもやってみたい
2.7セグLED基板のファーム開発
I2C部分をまだ作っていない。
ラズベリーパイに接続するために、この部分を作ろう。
これは比較的早くできそう。
3.FPGAにオープンCPUコアを入れることをやってみたい
4.しりとりで用意したウィキペディアのデータを
他の用途でも使う。
5.SDRでなにかやる?
勢いで、DS-DT305を入手したけど・・・。
こんな感じだ。今月も頑張ろう。
2015年2月22日日曜日
FON2405EのGPIOの速度
なんちゃってシリアル通信ができないか検討するなかで、
はたしてGPIOの速度はどのくらいなのかを調べたくなった。
まずは、ralinkのgpioコマンドの最小単位である100ms周期の点灯を
確認してみる。
ほとんど誤差なく100msだった。
すごいね。RT3050Fがすごいのか、使ったオシロの性能がアレなのか・・・。
次に、gpioコマンドでon-offを繰り返してみた。
うわー。遅い。遅すぎる。。。
780msって、これでデータを送ろうと思ったら、日が暮れてしまう。
なにか違う方法を考えなければ。
例えば、コンソール用のシリアル通信をなんとか使えないか考えよう。
と少し現実逃避して、久しぶりにPICマイコンで液晶表示をやってみた。
はたしてGPIOの速度はどのくらいなのかを調べたくなった。
まずは、ralinkのgpioコマンドの最小単位である100ms周期の点灯を
確認してみる。
ほとんど誤差なく100msだった。
すごいね。RT3050Fがすごいのか、使ったオシロの性能がアレなのか・・・。
次に、gpioコマンドでon-offを繰り返してみた。
うわー。遅い。遅すぎる。。。
780msって、これでデータを送ろうと思ったら、日が暮れてしまう。
なにか違う方法を考えなければ。
例えば、コンソール用のシリアル通信をなんとか使えないか考えよう。
と少し現実逃避して、久しぶりにPICマイコンで液晶表示をやってみた。
2015年2月16日月曜日
FON2405EのGPIOを使ってPICマイコンを操作する
少しづつ組み込みLinuxに慣れてきているような気がするけど、
まだまだやりたいことはある。
FONじゃないけど同じRT3050FのボードでUSBがあるものを使えるようにするとか。
一度にいろいろなことはできなので、少しづつ続けていこう。
土日で試したのは、
・OpwnWrtのビルド どうやって自分のボード用のファームを作成するのか
手順どおりにやると、欲しくもない違うボード用のファームが
たくさんできる・・・。1つでいいのよ。
・FON2405Eの追加書き換え 2台やって計3台 わーい!
・PICマイコンとの連携 GPIOを駆使してPICマイコンに接続
FONのGPIOのうち容易に取り出せるのは、
LED(GPIO11,12,14)そして、ボタン(GPIO10)の計4本
これだけあれば、なんちゃってシリアル通信ができそう。
そのための布石として、前にiModelaで基板から作った
7セグ表示マイコンを実験台にした。
http://continue-to-challenge.blogspot.jp/2014/12/imodelaeagle_13.html
そして、暫定で、
GPIO14 - RB4 カウントアップ・ダウン
GPIO11 - RB1 カウントスタート・ストップ
のように接続(したと思う)
操作系はこの前のWEBから〜を少し変えた。
FONは3.3VでPICは5Vで動かしているので、
FON→PICは大丈夫そうだけど、逆は配慮が必要。
今回は、FON→PICのみ
動かしているところはこんな感じ
まだまだやりたいことはある。
FONじゃないけど同じRT3050FのボードでUSBがあるものを使えるようにするとか。
一度にいろいろなことはできなので、少しづつ続けていこう。
土日で試したのは、
・OpwnWrtのビルド どうやって自分のボード用のファームを作成するのか
手順どおりにやると、欲しくもない違うボード用のファームが
たくさんできる・・・。1つでいいのよ。
・FON2405Eの追加書き換え 2台やって計3台 わーい!
・PICマイコンとの連携 GPIOを駆使してPICマイコンに接続
FONのGPIOのうち容易に取り出せるのは、
LED(GPIO11,12,14)そして、ボタン(GPIO10)の計4本
これだけあれば、なんちゃってシリアル通信ができそう。
そのための布石として、前にiModelaで基板から作った
7セグ表示マイコンを実験台にした。
http://continue-to-challenge.blogspot.jp/2014/12/imodelaeagle_13.html
そして、暫定で、
GPIO14 - RB4 カウントアップ・ダウン
GPIO11 - RB1 カウントスタート・ストップ
のように接続(したと思う)
操作系はこの前のWEBから〜を少し変えた。
FON→PICは大丈夫そうだけど、逆は配慮が必要。
今回は、FON→PICのみ
動かしているところはこんな感じ
2015年2月9日月曜日
FON2405EのLEDをWEBから制御する
やってみたかったことの1つ
web操作でFONのGPIOを制御すること。
ようやくできた。
制御方法はちょっとうさんくさいけど
Lighttpd+CGIで、gpioコマンドを叩いているだけ。。。
PHPとかPerlとかインストールしたいと思ったけど、
なにやらクロスコンパイルで挫折気味だったので、
CGIとしてシェルスクリプト(この場合何シェルっていうんだろう?bash?)を
持ちることにした。
Lighttpd.confに以下を追加・変更して
server.modules
= (
"mod_access",
"mod_cgi"
)
index-file.names
+= (
"index.xhtml",
"index.html", "index.htm", "default.htm",
"index.php","index.cgi"
)
cgi.assign
= (
".cgi"
=> ""
)
メインコンテンツとしてtest.cgiを作成する
#!/bin/sh
echo
"Content-type: text/html"
echo
NET_LED="OFF"
LAN_LED="OFF"
WPS_LED="OFF"
NET_LED=`echo
"$QUERY_STRING" | sed -n 's/^.*netled=\([^&]*\).*$/\1/p'
| sed "s/%20/ /g"`
LAN_LED=`echo
"$QUERY_STRING" | sed -n 's/^.*lanled=\([^&]*\).*$/\1/p'
| sed "s/%20/ /g"`
WPS_LED=`echo
"$QUERY_STRING" | sed -n 's/^.*wpsled=\([^&]*\).*$/\1/p'
| sed "s/%20/ /g"`
#
gpioname NET,LAN,WPS
#
mode off,on,fastbrink,slowbrink
echo
"<html><head><title>FON2405eのGPIOをWEBから操作する</title></head>"
echo
"<body>"
echo
"<h1>GPIOの制御(LEDの点消灯)</h1>"
echo
"<form method='get' action='test.cgi'>"
NET_LED_ON=""
NET_LED_FASTBRINK=""
NET_LED_SLOWBRINK=""
NET_LED_OFF=""
if
[ "$NET_LED" = "ON" ]; then
NET_LED_ON="checked"
gpio
l 12 0 1 0 0 0
elif
[ "$NET_LED" = "FASTBRINK" ]; then
NET_LED_FASTBRINK="checked"
gpio
l 12 1 1 4000 0 4000
elif
[ "$NET_LED" = "SLOWBRINK" ]; then
NET_LED_SLOWBRINK="checked"
gpio
l 12 5 5 4000 0 4000
else
NET_LED_OFF="checked"
gpio
l 12 1 0 0 0 0
fi
echo
"<p>NET-LED"
echo
"<input type='radio' name='netled' value='ON' $NET_LED_ON
>ON"
echo
"<input type='radio' name='netled' value='SLOWBRINK'
$NET_LED_SLOWBRINK >SlowBrink"
echo
"<input type='radio' name='netled' value='FASTBRINK'
$NET_LED_FASTBRINK >FastBrink"
echo
"<input type='radio' name='netled' value='OFF' $NET_LED_OFF
>OFF"
echo
"</p>"
LAN_LED_ON=""
LAN_LED_FASTBRINK=""
LAN_LED_SLOWBRINK=""
LAN_LED_OFF=""
if
[ "$LAN_LED" = "ON" ]; then
LAN_LED_ON="checked"
gpio
l 11 1 0 0 0 0
elif
[ "$LAN_LED" = "FASTBRINK" ]; then
LAN_LED_FASTBRINK="checked"
gpio
l 11 1 1 4000 0 4000
elif
[ "$LAN_LED" = "SLOWBRINK" ]; then
LAN_LED_SLOWBRINK="checked"
gpio
l 11 5 5 4000 0 4000
else
LAN_LED_OFF="checked"
gpio
l 11 0 1 0 0 0
fi
echo
"<p>LAN-LED"
echo
"<input type='radio' name='lanled' value='ON' $LAN_LED_ON
>ON"
echo
"<input type='radio' name='lanled' value='SLOWBRINK'
$LAN_LED_SLOWBRINK >SlowBrink"
echo
"<input type='radio' name='lanled' value='FASTBRINK'
$LAN_LED_FASTBRINK >FastBrink"
echo
"<input type='radio' name='lanled' value='OFF' $LAN_LED_OFF
>OFF"
echo
"</p>"
WPS_LED_ON=""
WPS_LED_FASTBRINK=""
WPS_LED_SLOWBRINK=""
WPS_LED_OFF=""
if
[ "$WPS_LED" = "ON" ]; then
WPS_LED_ON="checked"
gpio
l 14 1 0 0 0 0
elif
[ "$WPS_LED" = "FASTBRINK" ]; then
WPS_LED_FASTBRINK="checked"
gpio
l 14 1 1 4000 0 4000
elif
[ "$WPS_LED" = "SLOWBRINK" ]; then
WPS_LED_SLOWBRINK="checked"
gpio
l 14 5 5 4000 0 4000
else
WPS_LED_OFF="checked"
gpio
l 14 0 1 0 0 0
fi
echo
"<p>WPS-LED"
echo
"<input type='radio' name='wpsled' value='ON' $WPS_LED_ON
>ON"
echo
"<input type='radio' name='wpsled' value='SLOWBRINK'
$WPS_LED_SLOWBRINK >SlowBrink"
echo
"<input type='radio' name='wpsled' value='FASTBRINK'
$WPS_LED_FASTBRINK >FastBrink"
echo
"<input type='radio' name='wpsled' value='OFF' $WPS_LED_OFF
>OFF"
echo
"</p>"
echo
"<input type='submit' value='変更'>"
echo
"</form>"
echo
"</body></html>"
もうかっこ良くかけないものか。
でもシェルよくわかんないし、cgi作るもは初めてだし。。。
とりあえず、以下を参考にがんばった。
なんとか動くものになった。
2015年2月2日月曜日
FON2405EにLighttpdをインストールする
前回RalinkのSDKを使ってカスタムファームを導入してみた。
今回はいろいろなアプリケーションをインストールしてみようと思う。
その前に、毎回ファームを書き換えるのはめんどくさいので、NFSを使えるようにする
[Linux
Kernel Configuration]→[Networking]→[Networking options
--->]
→[]IP:Kernel level autoconfiguration
[Linux
Kernel Configuration]→[File systems]→[Network File Systems --->]
Provide
NFSv3とかチェック
[BusyBox
Configuration]→[Linux System Utilities]
[]
Support mounting NFS file systems
これで、
mount
-o nolock 10.10.10.3:/var/lib/tftpboot /mnt
とすれば、/mntに無限の可能性が広がるはず!
つぎに、webからGPIO制御したいなーという願望を持ちつつ、
SDKに付属のGOAHEADをさわろうとして、よくわからなくて。。。
Lighttpdをインストールしてみたいと思う。
1.ファームの再構築
pollってのが必要みたい
[Linux
Kernel Configuration]→[General setup]→[Configure standard kernel
feature]→[]Enable eventpoll supportにチェックを入れる
2.Lighttpdのクロスコンパイル
本体はここから取得。以下のようにしてクロスコンパイルを行う。
PATH="$PATH":/opt/buildroot-gcc342/bin
./configure
--host=mipsel-linux CC=/opt/buildroot-gcc342/bin/mipsel-linux-gcc
CFLAGS="-I/home/adeno/fongpio/sdk3301/RT288x_SDK/source/linux-2.6.21.x/include"
LDFLAGS="-L/home/adeno/fongpio/sdk3301/RT288x_SDK/source/linux-2.6.21.x/lib"
--without-pcre --without-zlib --without-bzip2 –disable-ipv6
–prefix=/home/adeno/lighttpd
make
make
install
without系のオプションは、configureやmakeしたときにエラーになったものを除くため
(あとで、1つづつ検証していこう)
その結果できたものを
NFSのディレクトリに保存しておく
lighttpd
・lib
・sbin
・share
3.FON側からマウント
mount
-o nolock 10.10.10.3:/var/lib/tftpboot/ /mnt
そして、
mkdir
/usr/local
mkdir
/usr/local/lib
mount
-o nolock 10.10.10.3:/var/lib/tftpboot/lighttpd/lib /usr/local/lib
4.設定ファイルの準備
NFSディレクトリに以下を作成
・data/www/htdocs コンテンツ保存先
・data/www/log ログ保存先
lighttpd.confの作成
以下を参考に
server.event-handler
= "linux-sysepoll" をコメントアウトして
server.event-handler
= "poll" を追加する
あとは適当に・・・やって、/mnt/lighttpd.confに保存。
5.Lighttpd起動!
/mnt/lighttpd/sbin/lightpd
-D -f /mnt/lighttpd.conf
これで、10.10.10.254:4080にアクセスすると
やったー!
次はこの環境の永続化を考えよう。
2015年2月1日日曜日
GW-USMicroNとWLI-UC-GNをラズベリーパイで使う
この前、リサイクルショップで、GW-USMicroNが300円で売られていた。
小さくて可愛いのでついつい買ってしまった。
以前から持っているWLI-UC-GNと同じくらいの大きさ!
この大きさはラズベリー・パイに丁度いいと思い、早速接続ー
結論から書くと、2つとも同じドライバーで使えたのだ。
ベンダーIDとプロダクトIDは以下の通り。
GW-USMicroN は2019 ed14
WLI-UC-GNは0411 015d
一時的に使うのであれば、
恒久的に使うのであれば、
/etc/udev/rules.d/99-wireless.rules
/etc/modprobe.d/wireless.conf
やっぱり、ラズベリー・パイは情報が多くていいね!
小さくて可愛いのでついつい買ってしまった。
以前から持っているWLI-UC-GNと同じくらいの大きさ!
この大きさはラズベリー・パイに丁度いいと思い、早速接続ー
結論から書くと、2つとも同じドライバーで使えたのだ。
ベンダーIDとプロダクトIDは以下の通り。
GW-USMicroN は2019 ed14
WLI-UC-GNは0411 015d
一時的に使うのであれば、
modprobe
rt2800usb
echo
2019 ed14 > /sys/bus/usb/drivers/rt2800usb/new_id
恒久的に使うのであれば、
/etc/udev/rules.d/99-wireless.rules
#
PLANEX GW-USMicroN
ACTION=="add",
SUBSYSTEM=="usb", ATTR{idVendor}=="2019",
ATTR{idProduct}=="ed14", RUN+="/sbin/modprobe -qba
rt2800usb"
#
BUFFALO WLI-UC-GN
ACTION=="add",
SUBSYSTEM=="usb", ATTR{idVendor}=="0411",
ATTR{idProduct}=="015d", RUN+="/sbin/modprobe -qba
rt2800usb"
/etc/modprobe.d/wireless.conf
#
PLANEX GW-USMicroN
install
rt2800usb /sbin/modprobe --ignore-install rt2800usb $CMDLINE_OPTS;
/bin/echo "2019 ed14" >
/sys/bus/usb/drivers/rt2800usb/new_id
#
BUFFALO WLI-UC-GN
install
rt2800usb /sbin/modprobe --ignore-install rt2800usb $CMDLINE_OPTS;
/bin/echo "0411 015d" >
/sys/bus/usb/drivers/rt2800usb/new_id
やっぱり、ラズベリー・パイは情報が多くていいね!
----------------------------
ちなみに、前書いたGPIOの制御、ネットで調べたら使い方が書いてあった。
処理中(0.2s点灯、0.1s消灯を繰り返す)
gpio
l <gpio> 2 1 4000 0 4000
エラー(0.1s点灯、0.1s消灯を繰り返す)
gpio
l <gpio> 1 1 4000 0 4000
ふーん。使えるかも!
2015年1月27日火曜日
FON2405E カスタムファーム導入(ようやく成功2/2)
前回、menuconfigまで行けることを確認したので、
先駆者と全く同じではつまらないので、少しだけいじってみることした。
GPIOをいじってみたいので、その部分を有効に。
(しなくてもできるのかもしれないけどね)
Ralink
Linux SDK Configurationの
Main
Menu->Ralink Proprietary Applications->[]GPIOを選択しておく。
以下の動画2:30ぐらいのところ
そして、make V=99でファームを作成する!
出来上がったファームが2MB以下であれば、書き込みを行う。
書き込み方法は他でも紹介されているとおり。
リセットボタンを押しながら電源ON
ファームの書き換えが成功したら、ブラウザで10.10.10.254にアクセスして管理画面が表示される。そして、telnetもできる。
さて、お目当てのGPIOは、gpioというコマンドで制御できそう。
gpioの説明を見ると
The
GPIO testing user application is named gpio.
gpio
w: writing test (output)
gpio
r: reading test (input)
gpio
i (<gpio>): interrupt test for gpio number
gpio
l <gpio> <on> <off> <blinks> <rests>
<times>:
set
led on <gpio>(0~24) on/off interval, no. of blinking/resting
cycles, blinking time
とのこと。よくわからん。
とりあえず試してみると
gpio
l 14 1 0 0 0 0
でWPSランプが点灯した。
gpio
l 14 0 1 0 0 0
でWPSランプが消灯した。
この番号を総当りしたところ、
LANランプ(真ん中のやつ)は11
NETランプ(左のやつ)は12
であることがわかった。
NETランプだけ、点灯の論理が逆だった。
他の方の情報(https://awaitingstock.wordpress.com/2013/01/)だと、
電源緑 9
電源橙 12
無線 14
LAN 11
リセット 10
電源橙 12
無線 14
LAN 11
リセット 10
らしい。もしかしたら電源(NETランプ)はオレンジ色にも光るかもしれない。
これは楽しみ。
この3つのLEDでLチカしてみた。
あとは何をしようかな。
2015年1月24日土曜日
FON2405E カスタムファーム導入(ようやく成功1/2)
方法は、他の人がやっているようにRalink
SDKを使ったのだけれど、
今まで失敗していたので、考え方を変えて、ファームを作成するPCの環境(linuxのバージョン)を
このSDKと同じくらいの時期に出たものにすることにした。
仮想PCを用意すればものの10分で準備が終わる。便利なものだ。
用意したのは、
・VirtualBox
・MandrivaLinux2008(linux
2.6.22)
である。
ディストリビューションについては、どれでもいいと思うが、Mandrake→Mandriva→Mageiaと使ってきたので、思い出に浸るために選択。
実際の作業は、皆さんと同じ。今までの苦労は何だったんだ!というくらいに快適。
まずはmake menuconfig まで行けることの確認。2015年1月18日日曜日
FON2405E カスタムファーム導入に挑戦!
年明けはいろいろと忙しく、なかなか更新ができなかった。
入手したFON2405Eにカスタムファームを導入するべく、いろいろ調査した。
FON2405E
OS OpenWRT(Linux2.6)
CPU
RT3050 320MHz
Memory
32MB
Flash 2MB
まず、有名な「Hot
Tuna Labs 」さんが公開しているカスタムファームを導入してみた。
これは手順どおりでいけた。ただし、bootメニューに入るのが苦労した。
10回挑戦して2回程度の成功率・・・。
このカスタムファームでGPIOを操作してみたかったのだが、
/dev/class/gpioがなくよくわからなかった。
/dev/gpioはあったのだが、
mkmodでなにかやるんか???
仕方がないので、カスタムファームを作成する方法を調査した。
(結果今のところ成功はしていない。。。Orz)
1.Ralink
SDK
Ralin
SDK
・Ralink_ApSoC_SDK_3600_20110715.tar.bz2
・Ralink_ApSoC_SDK_3301.tar.bz2
の2つで試してみる
1-1.Ralink_ApSoC_SDK_3600_20110715.tar.bz2
tar
xvjf Ralink_ApSoC_SDK_3600.tar.bz2
cd
RT288x_SDK/toolchain/
tar
xvjf buildroot-gcc342.tar.bz2
mv
buildroot-gcc342 /opt/.
cd
mksquash_lzma-3.2/
make
ここまでは、うまく行ったが、
/usr/bin/ld:
mksquashfs.o: シンボル 'log10@@GLIBC_2.0'
への未定義参照です
/lib/libm.so.6:
error adding symbols: DSO missing from command line
collect2:
エラー:
ld はステータス 1
で終了しました
Makefileに-lmが無いことが原因らしい
squashfs3.2-r2/squashfs-tools/Makefile
10行目
LDLIBS
+= -lz -L${LzmaAlone} -L${LzmaC}
LDLIBS
+= -lz -lm -L${LzmaAlone} -L${LzmaC}
mkdir
/opt/buildroot-gdb
mkdir
/opt/buildroot-gdb/bin
make
install
つぎに目的のsourceをと思ったが、
source内にMakefileがない。。。困った。
1-2.Ralink_ApSoC_SDK_3301.tar.bz2
3600と同じように
tar
xvjf Ralink_ApSoC_SDK_3301.tar.bz2
cd
RT288x_SDK/toolchain/
tar
xvjf buildroot-gcc342.tar.bz2
mv
buildroot-gcc342 /opt/.
cd
mksquash_lzma-3.2/
make
そして同じように
/usr/bin/ld:
mksquashfs.o: シンボル 'log10@@GLIBC_2.0'
への未定義参照です
/lib/libm.so.6:
error adding symbols: DSO missing from command line
collect2:
エラー:
ld はステータス 1
で終了しました
<builtin>:
recipe for target 'mksquashfs' failed
make[1]:
*** [mksquashfs] Error 1
squashfs3.2-r2/squashfs-tools/Makefile
10行目
LDLIBS
+= -lz -L${LzmaAlone} -L${LzmaC}
LDLIBS
+= -lz -lm -L${LzmaAlone} -L${LzmaC}
mkdir
/opt/buildroot-gdb
mkdir
/opt/buildroot-gdb/bin
make
install
これで、buildツールの準備ができたかな。
そして本体。
make
V=99
Makefile:319:
*** 暗黙ルールと通常ルールが混ざりました.
中止.
Makefileの319を書き換え
linux
linux%_only:
linux:
リトライ!!
make[3]:
Entering directory
'/home/adeno/fon/sdk3301/RT288x_SDK/source/user/busybox'
Makefile:1262:
*** 暗黙ルールと通常ルールが混ざりました.
中止.
中止!!
再度書き換え
vi
user/busybox/Makefile
/
%/: prepare scripts FORCE
/:
prepare scripts FORCE
リトライ!!!
make[1]:
Entering directory
'/home/adeno/fon/sdk3301/RT288x_SDK/source/vendors'
Makefile:28:
*** 暗黙ルールと通常ルールが混ざりました.
中止.
vi
vendors/Makefile
all
image clean romfs romfs.post vendor_%:
all
image clean romfs romfs.post:
まだぁ?
make[1]:
Entering directory
'/home/adeno/fon/sdk3301/RT288x_SDK/source/linux-2.6.21.x'
Makefile:1443:
*** 暗黙ルールと通常ルールが混ざりました.
中止.
vi
linux-2.6.21.x/Makefile
/
%/: prepare scripts FORCE
/:
prepare scripts FORCE
リトライしていくと…。
---
/Ralink/3301/sdk3301/RT288x_SDK/source/vendors/Ralink/RT3052/mkimage:
invalid entry point -n
/Ralink/3301/sdk3301/RT288x_SDK/source/vendors/Ralink/RT3052/./Makefile:80:
recipe for target 'image' failed
make[2]:
*** [image] Error 1
make[2]:
Leaving directory
'/Ralink/3301/sdk3301/RT288x_SDK/source/vendors/Ralink/RT3052'
Makefile:29:
recipe for target 'image' failed
make[1]:
*** [image] Error 2
make[1]:
Leaving directory '/Ralink/3301/sdk3301/RT288x_SDK/source/vendors'
Makefile:297:
recipe for target 'image' failed
make:
*** [image] Error 2
---
がぼー なんでかなぁ・・・・。
2.Openwrt(Image
Builder)
make
image PROFILE=Default
しばし待つと…
makeが終了したのだが、
2490372
1月 18
12:45
bin/ramips/openwrt-ramips-rt305x-rt-g32-b1-squashfs-sysupgrade.bin*
2.5MB
2MBにおさまってないやんOrz
3.Openwrt(Buildroot)
git
clone git://git.openwrt.org/openwrt.git
cd
openwrt
./scripts/feeds
update -a
./scripts/feeds
install -a
make
defconfig
make
prereq
make
menuconfig
Target
System はRalink
RT288x/RT3xxx
Subtarget
はRT3x5x/RT5350
based boards
を選択してmakeした
3~4時間待つと
2883588
1月
18
14:21
bin/ramips/openwrt-ramips-rt305x-esr-9753-squashfs-sysupgrade.bin
2.9MB 2MBにおさまってないやんOrz
--
うーん。 なかなか難しいね。
この1週間での進捗はこんな感じ。
登録:
投稿 (Atom)