久しぶりになります。
以前blogに掲載した抵抗分圧比計算機ですが、入力の値に応じてリアルタイムに結果が変化しないこと、簡単な分数入力ができない点が困っていたので、AIに頼んで作り替えてもらいました。
自分で作った電子・電気工作についてのブログです。「自家製電気工作物」は造語です。 以前、自家製電気工作物というブログをつかっていましたが、現在はこちらに引っ越し。
久しぶりになります。
以前blogに掲載した抵抗分圧比計算機ですが、入力の値に応じてリアルタイムに結果が変化しないこと、簡単な分数入力ができない点が困っていたので、AIに頼んで作り替えてもらいました。
==== PROGRAM START ====Firmware size: 1148[RST] Resetting target...[RST] Bootloader wait...[SYNC][OK] Synced with target[SIG] 1E 95 16==== FLASHING ====[WRITE] Chunk 1/9 (11%)[WRITE] Chunk 2/9 (22%)[WRITE] Chunk 3/9 (33%)[WRITE] Chunk 4/9 (44%)[WRITE] Chunk 5/9 (55%)[WRITE] Chunk 6/9 (66%)[WRITE] Chunk 7/9 (77%)[WRITE] Chunk 8/9 (88%)[WRITE] Chunk 9/9 (100%)==== VERIFY ====[VERIFY] READ_PAGE not supported by bootloader. Skipping verify.[WARN] LEAVE_PROG failed (ignored)==== DONE (WRITE + VERIFY OK) ====[RESULT] SUCCESS (WRITE+VERIFY)
ここで、ターゲットボードをリセットするとLEDの点滅が始まりました。書き込みを確認するために、500mSと1000mSを交互に書き込んでみるとよく分かります。
非常に久しぶりになります。
最近遊んでるDSPがありまして、その使い方を考えていたら面白い実験ができたので報告します。
使っているチップはSpin Semiconductorという会社のFV-1です。
FV-1は28ピンのICにステレオの24bitAD, 24bitDAが内蔵され32kHzサンプリングでき、32kワードのディレイ専用メモリがあって、1秒までのディレイは簡単に作れます。また、開発環境もメーカーから提供されていて、Arduinoのように簡単に使えます。
今回おこなった実験は1秒しか無いDelay用メモリをより長く使うために、数サンプル毎に1度だけ書き込むようにして、音質は顧みず長さだけ長くしてみました。
DSP内では整数のカウンターを使う方法がよく分からず、固定小数点表記カウンタを使ってます。オシロで見てみると、これでカウントされているようです。
これで、ディレイがどうなるか見てみます。
確かに4秒程度信号が遅れているのがわかります。
しかし、ディレイでの波形は8kHzサンプル相当なので、1周期16サンプルなのでガタガタの波形になって以下の様な感じ。
でも、一応動作しているようです。これを実際に使うためには、delayの前にローパスフィルタを、ディレイの後にもローパスフィルタを入れると綺麗な波形になりそうです。
テストプログラムはこんな感じです。
; Hideaki Nii 2024/10/26
; FV-1 spinasm
; LongDelayTest.spn
; More than 1 second test
;
; INPUT L: delay in
; OUTPUT L: delay out
; OUTPUT R: the sampling timing signal for debug
SCALE equ 4 ; The length of delay (seconds), 1 or 2 or 4 or 8
INITCNT equ 0.75
INITVAL equ 0.8
DECCNT equ - INITVAL / SCALE
Buf MEM 32767
CNT equ REG2
DELAYIN equ REG3
DELAYOUT equ REG4
;------ Read AD
SOF 0,0
RDAX ADCL,1
WRAX DELAYIN,0
;------ Startup
SKP run, CNTLOOP
SOF 0,INITCNT
WRAX CNT,0
; ------ Loop Main
CNTLOOP:
RDAX CNT,1
SOF 1.0, DECCNT
SKP gez, UPDATE
; ------ overflow
SOF 0, INITCNT
WRAX CNT,0
;------ ADIN
RDAX DELAYIN,1.0
WRA Buf,0
RDA buf#,1.0
WRAX DELAYOUT,0
SKP run, UPDATE_E
UPDATE:
WRAX CNT,0
;------ FEEDBACK
rda buf#,1.0
wra Buf,0
UPDATE_E:
;------ Output
RDAX DELAYOUT,1
WRAX DACL,0
RDAX CNT,1
WRAX DACR,0
;------ END
このDSPではDELAYメモリは自動的にシフトして行くのと同じように動くので、delayメモリのアドレス0に値を書き込んで、アドレス1を読むとそれだけで1サイクル遅らせることができるのです。そのために専用のコマンドがあって、rdaとwraというコマンドで簡単に読み書きできます。
このソフトでは、カウンタがSCALEの値である4を数えてオーバーフローする時だけADの値をdelayに書き込み、それ以外のタイミングではdelayの一番最後を最初に戻す仕組みになってます。
例えば、delayが長さ3としてSCALE=4となるような例の遷移の様子を以下に示します。入力には4回に一度新しい値が書き込まれ、出力には特定の場合だけ出力されます。この例ではDelay長*SCALE = 3*4 = 12の遅れとなります。
| 入力値 | D0 | D1 | D2 | D3 | 出力 |
| 入力=1 | 1 | X | X | X | ->X |
| 入力=出力 | X | 1 | X | X | |
| 入力=出力 | X | X | 1 | X | |
| 入力=出力 | 1 | X | X | 1 | |
| 入力=2 | 2 | 1 | X | X | ->X |
| 入力=出力 | X | 2 | 1 | X | |
| 入力=出力 | 1 | X | 2 | 1 | |
| 入力=出力 | 2 | 1 | X | 2 | |
| 入力=3 | 3 | 2 | 1 | X | ->X |
| 入力=出力 | 1 | 3 | 2 | 1 | |
| 入力=出力 | 2 | 1 | 3 | 2 | |
| 入力=出力 | 3 | 2 | 1 | 3 | |
| 入力=4 | 4 | 3 | 2 | 1 | -> 1 |
| 入力=出力 | 2 | 4 | 3 | 2 | |
| 入力=出力 | 3 | 2 | 4 | 3 | |
| 入力=出力 | 4 | 3 | 2 | 4 | |
| 入力=5 | 5 | 4 | 3 | 2 | ->2 |
| 入力=出力 | 3 | 5 | 4 | 3 | |
| 入力=出力 | 4 | 3 | 5 | 4 | |
| 入力=出力 | 5 | 4 | 3 | 5 | |
| 入力=6 | 6 | 5 | 4 | 3 | ->3 |
| 入力=出力 | 4 | 6 | 5 | 4 | |
| 入力=出力 | 5 | 4 | 6 | 5 | |
| 入力=出力 | 6 | 5 | 4 | 6 | |
| 入力=7 | 7 | 6 | 5 | 4 | ->4 |
ソフトを工夫して、最後にSCALEの設定だけで1秒から8秒まで変化させることができるようになりました。そこがこのプログラムの面白いところです。
ちなみに間違ってSCALEに5とか入れても正常に動作するようです。Delayの長さが特別なときにはSCALEはいくつでもうまく行くのかもしれません??!!
一応source fileをこちらに置きます。
今回の実験はこれにて終了。