· 

CでFTDI BitBang(2)

CでBitBangしてみます。せっかくなので応用例としてARMのSerialWireDebugに使ってみます。どこまでできるかわからんですが。

 

ARMの仕様はこちらです。

とんでもなく分かりにくいので、こちらこちら、さらにこちらを見たほうが良い。

 

 とりあえず、JTAG-to-SWDまでやってみます。

回路は秋月のFT231Xモジュールで、D4とD6を3.3kΩで結線して、ターゲットデバイスはまだ接続していません。

いきなりですが、ソースコードはこちら。構造化無視の一筆書きでGoだぜ。

#include <windows.h>

#define SWCLK_pos (0x20) //#DSR(D5)
#define SWDO_pos (0x40) //#DCD(D6)
#define NRES_pos (0x80) //#RI(D7)
#define SWDI_pos (0x10) //#DTR(D4)

#define OUTSET (SWCLK_pos|SWDO_pos|NRES_pos)
#define INSET (SWCLK_pos|NRES_pos)

typedef PVOID   FT_HANDLE;
typedef ULONG   FT_STATUS;

const char dllfile[]="ftd2xx64.dll";

typedef FT_STATUS (WINAPI *FT_Open_type)(int deviceNumber,FT_HANDLE *pHandle);
typedef FT_STATUS (WINAPI *FT_Close_type)(FT_HANDLE ftHandle);
typedef FT_STATUS (WINAPI *FT_SetBitMode_type)(FT_HANDLE ftHandle,UCHAR ucMask,UCHAR ucEnable);
typedef FT_STATUS (WINAPI *FT_SetBaudRate_type)(FT_HANDLE ftHandle,ULONG BaudRate);
typedef FT_STATUS (WINAPI *FT_Write_type)(FT_HANDLE ftHandle,LPVOID lpBuffer,DWORD dwBytesToWrite,LPDWORD lpBytesWritten);
typedef FT_STATUS (WINAPI *FT_Read_type)(FT_HANDLE ftHandle,LPVOID lpBuffer,DWORD dwBytesToRead,LPDWORD lpBytesReturned);
typedef FT_STATUS (WINAPI *FT_GetQueueStatus_type)(FT_HANDLE ftHandle,DWORD *dwRxBytes);

HMODULE dll;
FT_Open_type FT_Open;
FT_Close_type FT_Close;
FT_SetBitMode_type FT_SetBitMode;
FT_SetBaudRate_type FT_SetBaudRate;
FT_Write_type FT_Write;
FT_Read_type FT_Read;
FT_GetQueueStatus_type FT_GetQueueStatus;
FT_HANDLE ftHandle;
FT_STATUS ftStatus;

#define SENDDATA_MEXLEN (4096)
typedef struct {
    unsigned char data[SENDDATA_MEXLEN];
    int len;
} senddata_t;

void AppendSenddata(senddata_t* d1,senddata_t d2){
    int i,j;
    for(i=d1->len,j=0;j<d2.len;i++,j++){
        d1->data[i]=d2.data[j];
    }
    d1->len+=d2.len;
}
void ClearSenddata(senddata_t* tgt){
    int i;
    for(i=0;i<SENDDATA_MEXLEN;i++){
        tgt->data[i]=0;
    }
    tgt->len=0;
}
senddata_t ExpandData(char* src,int nbyte,char nresval){
    senddata_t s;
    char c,nres_out;
    int i,j;
    ClearSenddata(&s);
    if(nresval>0){
        nres_out=NRES_pos;
    }else{
        nres_out=0;
    }
    for(i=0;i<nbyte;i++){
        c=src[nbyte-1-i];
        for(j=0;j<8;j++){
            if((c&0x01)>0){
                s.data[(i*8+j)*2+0]=(SWDO_pos|nres_out);
                s.data[(i*8+j)*2+1]=(SWDO_pos|SWCLK_pos|nres_out);
            }else{
                s.data[(i*8+j)*2+0]=(nres_out);
                s.data[(i*8+j)*2+1]=(SWCLK_pos|nres_out);
            }
            s.len=s.len+2;
            c=c>>1;
        }
    }
    return s;
};

int main(int argc,char** argv){
    ULONG written;
    senddata_t senddata;
    unsigned char data[64];
    int i;

    dll=LoadLibrary(dllfile);

    FT_Open=(FT_Open_type)GetProcAddress(dll, "FT_Open");
    FT_Close=(FT_Close_type)GetProcAddress(dll, "FT_Close");
    FT_SetBitMode=(FT_SetBitMode_type)GetProcAddress(dll, "FT_SetBitMode");
    FT_SetBaudRate=(FT_SetBaudRate_type)GetProcAddress(dll, "FT_SetBaudRate");
    FT_Write=(FT_Write_type)GetProcAddress(dll, "FT_Write");
    FT_Read=(FT_Read_type)GetProcAddress(dll, "FT_Read");
    FT_GetQueueStatus=(FT_GetQueueStatus_type)GetProcAddress(dll, "FT_GetQueueStatus");

    printf("dll              =%d\n",dll);
    printf("FT_Open          =%d\n",FT_Open);
    printf("FT_Close         =%d\n",FT_Close);
    printf("FT_SetBitMode    =%d\n",FT_SetBitMode);
    printf("FT_SetBaudRate   =%d\n",FT_SetBaudRate);
    printf("FT_Write         =%d\n",FT_Write);
    printf("FT_Read          =%d\n",FT_Read);
    printf("FT_GetQueueStatus=%d\n",FT_GetQueueStatus);

    ftStatus=FT_Open(0,&ftHandle);
    printf("status(FT_Open)=%d\n",ftStatus);

    ftStatus=FT_SetBaudRate(ftHandle,9600);//153.600kS/s is assumed
    printf("status(FT_SetBaudRate)=%d\n",ftStatus);

    ftStatus=FT_SetBitMode(ftHandle,OUTSET,4);
    //ftStatus=FT_SetBitMode(ftHandle,0xff,4);
    printf("status(FT_SetBitMode)=%d\n",ftStatus);

    senddata.data[0]=(SWCLK_pos|SWDO_pos|NRES_pos);
    senddata.len=1;
    ftStatus=FT_Write(ftHandle,&(senddata.data[0]),senddata.len,&written);
    printf("status(FT_Write)=%d\n",ftStatus);
    Sleep(100);
    ftStatus=FT_Write(ftHandle,0,1,&written);
    printf("status(FT_Write)=%d\n",ftStatus);
    Sleep(100);
    senddata.data[0]=(SWCLK_pos|SWDO_pos);
    senddata.len=1;
    ftStatus=FT_Write(ftHandle,&(senddata.data[0]),senddata.len,&written);
    printf("status(FT_Write)=%d\n",ftStatus);

    /*RESET JTAG_to_SWD RESET*/
    for(i=0;i<7;i++){
        data[i]=0x00;
    }
    senddata=ExpandData(data,7,1);
    for(i=0;i<7;i++){
        data[i]=0xFF;
    }
    AppendSenddata(&senddata,ExpandData(data,7,1));
    data[0]=0xE7;
    data[1]=0x9E;
    AppendSenddata(&senddata,ExpandData(data,2,1));
    for(i=0;i<7;i++){
        data[i]=0xFF;
    }
    AppendSenddata(&senddata,ExpandData(data,7,1));
    data[0]=0x0F;
    AppendSenddata(&senddata,ExpandData(data,1,1));


    ftStatus=FT_Write(ftHandle,&(senddata.data[0]),senddata.len,&written);
    printf("status(FT_Write)=%d\n",ftStatus);

    ftStatus=FT_Close(ftHandle);
    printf("%d\n",ftStatus);
    Sleep(1000);

    FreeLibrary(dll);

    return 0;
}

実行結果はこちら。

ロジアナのSWD解析で、ちゃんとResetとかJTAG-to-SWDとか認識されているので、うまくいっているんだと思います。ktkr

左足拇指の表面の感覚がなくなって、ずっと局所麻酔されているような感じがあり、素人判断で、ヘルニアか糖尿病かと思って、比較的長時間座っていると腰に鈍い痛みが起こることもあったので、まずヘルニアかどうか確認しようと思って整形外科に行った。MRIの結果おそらくヘルニアではないとなった。が、ヘルニアの痛み止めの薬を処方された。ヘルニアではなさそうって結果なのになんで?って激しく疑問に思う。飲むと眠くなる。今日はまだ4時間しか起きて活動していない。2週間分処方されて、必ず飲めと言われた。明日から社会人として活動できるのだろうか、、、?

コメントをお書きください

コメント: 1
  • #1

    ひま (金曜日, 10 6月 2022 16:39)

    1001ゲット