RC-S380の分解と考察

動機

Arduino もとい ESP32 で NFC(Near Field Communication) の規格の 1 つである Felica を読み書きしたくて、ウェブ検索をしました。ArduinoFelica を使用するには、Sony の RC-S620/S で読み込むことができるということがわかりました。しかし、RC-S620/S は下記のように在庫もなし、生産終了予定であるという事実を突きつけられました。RC-S620/S に対して、後継の機種が出ていることはわかるのですが、ビジネス用途のため、現在時点(2023/5/13)で一般人には入手できないようです。

そこで、現在、私が持っている IC カードリーダー RC-S380 でなんとか代用できないかということで、分解して調べてみようと考えました。

RC-S380 とは

RC-S380 とは Sony 製の Felica IC カードリーダーです。

USB でパソコンに接続して使うもので、nfcpy で Felica を読み込めたりします。

ところで、ソニーの後継機種一覧を見てみると、下記のように UART か USB のインターフェースしかありません。

ここで考えたのが、「USB がインターフェースになっている製品は UART による通信をマイコンを通して USB に変換しているだけなのではないか」ということです。つまり、RC-S380 のマイコン部分を取り外せば、UART モジュールとして使用できそうだということです。 実際に分解して、様子を見てみます。

分解してみる

外観になります。

裏面はこのようになっていて、赤枠部分のゴムシートを外すと、ネジが 2 本出てきます。

この 2 本のネジ外し、右側の爪部分に注意して蓋を開けると、下記のように開くことができます。

中には基板が 1 枚入っているのみで、接着シートで表面と接着されています。これは力技で剥がすことができますが、剥がす必要はありません。

基板はこのようになっています。

大きい部品としては、左側に USB のコネクタがついており、上下 2 個の IC が載っています。

上の IC に関しては、このようなものです。

これは STM の F103TBU6 というマイコンになります。

下の IC はこのようなものです。

この IC は NXP の OM5570 というもので、ウェブ検索してもデータシートは入手できませんでした。

しかし、似た製品で、OM5579/PN7150ARD というものがヒットしたおかげで、Plug’n Play NFC Controller であるのではないかと考えられました。

考察

余計なことは考えず、UART なのか考察してみます。 まず、基板のパターンをよくみたところ、F103TBU6 の右側の 9 本のピンのうち、上から 3 ~ 6 本目までが下の IC に直説つながっていることが確認できました。

データシートから F103TBU6 の 36 ピンパッケージのピンの機能をみてみると、下記 2 枚の情報を得ました。

PA13 以外は USART の機能と一致しています。UART で通信している可能性が高まりました。 確信はまだできませんが、この線にはパッドが付いているので、この部分にロジアナを当てれば、解析できそうです。 組み込み開発者目線からして、通信波形は見ておきたいので、この部分にパッドが付いているのは頷けます。

残念ながら、ロジアナは持っているのですが、プローブ固定用のスタンドを持っていないので、考察はここまでにしました。

結論

確証はありませんが、RC-S380 は UART 通信している可能性が高いので、解析して、IC を外して線出しすれば、arduino もとい ESP32 でもできそうです。OM5570 のデータシートがないのでわからないのですが、IC の Enable ピンもあるかもしれないので、そういった部分などももう少し見たほうが良さそうです。

後書き

私はここで力尽きますが、この記事を見てより良い情報を生み出してくれればと思います。 それでは、また。

あと、プローブ固定用スタンドが欲しいです。誰か恵んでください

ARC004 A

復習も兼ねて rust で解き直してみる。


fn main() {
    let n = {
        let mut s = String::new();
        std::io::stdin().read_line(&mut s).unwrap();
        s.trim_end().parse::<i32>().unwrap()
    };
    let mut xy: [[i32; 2]; 100] = [[0; 2]; 100];
    for i in 0..n {
        let (a, b) = {
            let mut s = String::new();
            std::io::stdin().read_line(&mut s).unwrap();
            let mut iter = s.split_whitespace().map(|i| i.parse::<i32>().unwrap());
            (iter.next().unwrap(), iter.next().unwrap())
        };
        xy[i as usize][0] = a;
        xy[i as usize][1] = b;
    }

    let mut max_ans = 0.0_f32;
    for i in 0..n {
        for j in 0..n {
            let distance = ((xy[i as usize][0] as f32 - xy[j as usize][0] as f32).powf(2.0_f32) + (xy[i as usize][1] as f32 - xy[j as usize][1] as f32).powf(2.0_f32)).sqrt();
            if max_ans < distance {
                max_ans = distance;
            }

        }
    }
    println!("{}", max_ans);
}

__builtin_bswap

mgba 読んでたら __builtin_bswap というマクロが出てきた。

これは GCC に含まれるビルトイン関数。

gcc.gnu.org

これは、バイトを逆順に呼び出す関数。例えば、データ上のリトルエンディアンの値をビッグエンディアンで読み出したりできる。 正確には、変換するデータの大きさを表す 数字の suffix がつく。

簡単に確認してみる。

#include <stdio.h>


int main() {
    printf("%x\n", __builtin_bswap32(0x12345678));
    return 0;
}

出力

% ./a.out
78563412

0x12345678 の 32bit のデータが逆順に読み出すことを確認することができた。

GBAの開発環境

お久しぶりです。

最近は諸事情で時間が大きく取れているので、前から作りたいなぁと思っていたエミュレータの作成に取り掛かっています。

エミュレート対象は GBA (Game Boy Advance) になります。 まだ調査、分析段階ですが、mgba や virtualboyadvance といったソフトウェアを解析しています。

google で最初の方に出てくる以外で良さそうなサイトは、こことかがまとまっていていいかなと思っています。もっといいのあったら教えてください。

https://problemkaputt.de/gbatek.htm

ROM の解析やテスト用の ROM を作るのに、GBA の開発環境が必要になってくると思います。この方のが一番最新のような気がします。

booth.pm

Dockerfile も公開されているので、その手の人は理解が簡単です。

docker image にも、binutils, gcc などが含まれているので問題なく使うことができてます。

それにしても、mgba すごいですね。こういうもの書けるようになりたいなぁという気持ちしか起こりません。

今、少しわからないところがあって、arm の decoder の部分がわかってないです。

ARMDecoder decoder = _armDecoderTable[((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x00F)];

この部分ですね。

decoder なんでこれで デコードできるんだろう って悩んでいます。 ARMv4 の命令フォーマット見たりしているんですけど、いまいち検討がついてません。

精進します。

[追記] 完全に理解した

django-rest-social-auth!

前置き

認証勉強したい。 python使いたい。 jwt使いたい。

django-rest-social-authを使ってみる(読んでみる)ことにした。

github.com

example_projectを動かすとき、いろいろエラー出るので、 動かしたときのパッケージうんぬんを載せておく。

asgiref==3.2.10
certifi==2020.6.20
cffi==1.14.2
chardet==3.0.4
cryptography==3.0
defusedxml==0.6.0
Django==3.1
django-rest-knox==4.1.0
django-sslserver==0.22
djangorestframework==3.11.1
djangorestframework-simplejwt==4.4.0
idna==2.10
oauthlib==3.1.0
pycparser==2.20
PyJWT==1.7.1
python3-openid==3.2.0
pytz==2020.1
requests==2.24.0
requests-oauthlib==1.3.0
rest-social-auth==4.2.0
six==1.15.0
social-auth-app-django==3.4.0
social-auth-core==3.3.3
sqlparse==0.3.1
urllib3==1.25.10

これを requirements.txt に保存してpip install -r requirements.txt をすれば、 動かせる

pythonでunzip

三行でまとめると

某サイトでたくさんzipを落とした。 マウスでクリックして解凍が嫌だった。 だからスクリプトで解凍した。

以下、スクリプト

import os, glob, zipfile

for name in glob.glob("*.zip"):
    base, ext = os.path.splitext(name)
    os.mkdir(base)
    with zipfile.ZipFile(name) as zip:
        zip.extractall(base)

globでcwdのzipを抽出。splitextで拡張子と名前分割。 現在のディレクトリにzipが散乱してあることを前提にしているので、 baseでディレクトリを作成。zip.extractall(base)で解凍先指定&解凍。

glob, splitextはそんな使い方だったなぁとか思い出した。 zipfileは初めて使った。便利。

bandcampさん、一括ダウンロードとかないんですか?

build.gradleにtest結果をブラウザで表示させるタスクの追加

デスクトップでプログラミングするモチベーションが高まったので、javaとかいろいろそろえてみた。

プロジェクトの環境は、openJDK 14 と gradle 6.3。

> gradle test

でテストの実行、カバレッジ表示用のhtmlが表示される。

だから、これをコマンドラインから表示させたかった。

なので、

① 新しいタスクの追加 ② 既存タスク test の実行(依存) 以下、実行フェーズで ③ テストカバレッジHTMLのパスの取得 ④ パスが存在したらそのファイルをブラウザで開く

っていう流れで新しいタスクを追加した。

task openTest {
    dependsOn "test"
    doFirst {
        def path = Path.of(System.getProperty("user.dir") + "\\build\\reports\\tests\\test\\index.html")
        if(Files.exists(path)) {
            Desktop.getDesktop().browse(path.toUri())
        }
    }
}

やっつけで書いた....

doFirst 外で書くと全部実行されるというワナとかdependsOnは実行フェーズ内で書けないとか知見が多かった。

これずっとnvimで書いてたのでnvim用のプラギン探さないとな。てか既にブラウザにカバレッジ出すタスクありそう。