おはよーございます.天気晴れ.少し暑い.
STM32H723に小さなI2C DACを接続して使います.
I2C peripheralを使うのがフツーでしょう.しかしpin配置の自由度が低下するのでperipheralは使わずに、port直叩きでやります.こんな感じで.
static void DAC_clk(void){
DAC_CK(1); // port high
DAC_CK(0); // port low
}
DACは動くには動くのですが、clk周波数が2.5MHzぐらいと速過ぎます.I2Cって100kHzとか400kHzですよね.
そこでNOPで遅延させたろうと、こうしました.
static void DAC_clk(void){
DAC_CK(1);
__asm__("NOP");
DAC_CK(0);
__asm__("NOP");
}
しかしNOPが効きません.
Cortex-M7はhardware的にNOPを無視するらしいと聞いてたのですが、噂通り素通りしてるみたいよ.
NOPは諦めて、HAL_Delay()を使うと最短1mSecも遅延しちゃって遅すぎて困ります.
詰みました.
I2C peripheralを使う事にします.プリント基板は書き替えます.
このダラーッとしたかったるさ....
ーーーー
I2CのDMAでトラブル中です.ぜーんぜん動きません.blockingならスイスイ動きます.
void DAC_set(int x){
uint8_t data[2] ;
data[0] = 0xaa;
data[1] = 0x55;
HAL_I2C_Master_Transmit_DMA( hi2c4, ADRS<1, data, 2 );
}
こちらによると、I2C4のDMAはBDMAというもので、RAM_D3空間にのみアクセスできるらしい.
STM32H7ともなるとバスが複数在る複雑なアーキテクチャになっていて、peripheralが別の空間に置かれてたりする.reference manualを隅々まで読むのダルいのでそんなに読んでません.
さらに
こちらによると、RAM_D3空間にアクセスするには、リンカスクリプトに追記しなくちゃいけないんだとか.これを.ldの後ろの方に追加.
.DATA_RAM_D3 (NOLOAD) :
{
} >RAM_D3
それでDMAを呼び出すところを、こんな風にすればRAM_D3にdata[2]が配置される.
uint8_t data[2] __attribute__ ((section (".DATA_RAM_D3")));
void DAC_set(int x){
data[0] = 0xaa;
data[1] = 0x55;
HAL_I2C_Master_Transmit_DMA( hi2c4, ADRS<1, data, 2 );
}
なのだがっ! うごかない~ いや~ん clkすら出てこない~
RAM_D3は正常に読めてるんですがね.
BDMAに起動かかってないのかな?
#I2C4 DMAを断念します
かしこ