顯示具有 MCU 標籤的文章。 顯示所有文章
顯示具有 MCU 標籤的文章。 顯示所有文章

2020年3月22日 星期日

DSP TI TMS320F283xx eCAN Mailbox TX/RX設置


這篇文章是寫,要如何設置設置TMS320F283xx的TX/RX暫存器,來傳送、

收資料,在接收訊息過載了,要如何處理。還有如何用遠端通訊格式

(Remote Frame)來向另一個CAN節點(Node)要求資料,或是回應遠端節

點的要求。


1.1設置Mailbox用來傳送,以Mailbox 1為例
1. 將Mailbox 1所對應的CANTRS.1設為"0",但對CANTRS.1寫入"0"是無效  
    的,而是將MSGCTRL的RTR設為"1",就可以清除CANTRS.1。
2. 將Mailbox1所對應的CANME.1設為"0",用來Disable Mailbox1,才能去設定
    Mailbox1的參數。
3.初始化Mailbox1的參數,其中MSGID的AAE,AME bit設為"0",作為一般傳送
   模式。
   a.設置Mailbox1.MSGID=0x15AC0000
   b.設置Mailbox1.MSGCTRL,MSGCTRL.DLC為要傳送資料的長度,
   MSGCTRL.RTR設為"0"
   c.設置CANMD.1為"1",用來將Mailbox1設為Transmitter
4.將Mailbox1所對應的CANME.1設為"1",重新將Mailbox1 Enable。


1.2設置要傳送的訊息,發送訊息
1.當CANMC.DBO被設為"0",表示最低byte先,當設定MSGCTRL設為2,表示
   要傳送的2個Bytes存在CANMDL.31~16,對CANMD寫入xxxx0000h(xxxx為
   要傳的資料)。
2.設置CANTRS.1為"1",開始去傳送訊息。等待TA.1為"1",表示這筆資料傳送
   成功。CANTRS.1會自動被清除。
3.要從同一個Mailbox傳送下一筆訊息,要再更新Mailbox RAM     
   (CANMDL/CANMDH)後,再回到步驟2,設置CANTRS.1將訊息發送出去。



2.1設置Mailbox用來接收,以Mailbox 3為例
1. 將Mailbox 3所對應的CANME.3設為"0",用來關閉Mailbox3,才能去設定
  Mailbox3的參數。
2.在Mailbox3.MSGID寫入預設的ID到MSGID.ID[28:0],在MSGID有AME bit,
    如果設為"1",就是開啟"接收遮罩"功能,再到LAM裡[28:0]bit設定那些bit是
    don't care。在傳送端發送ID時,接收端只要去比較沒有被遮罩的位元,
    don't care的bit就不用比較。
3.要將Mailbox3設為接收端(receiver),就要設CANMD.3為"1"。
4.當現有資料存在mailbox, 希望設定要被保護,不被新接收到的訊息覆蓋。可
   以由寫入保護暫存器(CANOPC)裡bit 0~31設定對應的mailbox為"1"。另外可
   以由軟體的方式將新接收到的訊息存到其他的mailbox,避免新訊息被忽略
   掉。
5.設定完成,將CANME.3設為"1",啟動Mailbox3。

2.2設置Mailbox用來接收
1.當有新的訊息要存入Mailbox3時,CANRMP.3會被設為"1",表示有接收到訊
   息。另外中斷旗標也會被設置,通知CPU到Mailbox RAM讀取訊息。
2.CPU需要先將CANRMP.3清除掉再去讀取訊息,並且確認接收訊息遺失暫存
   器RML.3是否為"1",依照不同的應用,CPU需要確認如何處理訊息遺失的現
   象。
3.在CPU從Mailbox讀取訊息後,需要再去確認在讀取訊息的過程中,有新的資
   料進到Mailbox而讓CANRMP再次被設為"1"。

2.3過載訊息狀況處理
1.如果CPU讀取訊息的時間不夠快,就需要為這個ID設置更多的mailbox來接
   收。例如Mailbox 3,4,5有相同的ID,相同MASK,在SCC, Mailbox 3,4,5的Mask
   值一致,都由LAM(3)設定。在eCAN模式,每個Mailbox有自已的LAM設定,
   可以設成LAM(3), LAM(4), LAM(5)。為了避免資料遺失,設置過寫入保護
   OPC暫存器,避免Mailbox 4,5未讀的訊息被覆蓋。當CAN module接收到訊
   息,會先存在Mailbox5 。如果Mailbox5對應的RMP為"1",就會存到
   Mailbox4。如果Mailbox4對應的RMP也為"1",就會存到Mailbox 3,因為
   Mailbox3沒有被設為OPC,所以如果前一筆資料還沒被讀取,又有新資料進
   來,就會覆蓋掉原本的資料,並讓Mailbox3對應的RML為"1",表示接收的資
   料遺失,並由RMLIF發出中斷通知CPU。
2.另外在一筆資料量超過8 bytes的情況,也可以由Mailbox4發出中斷讓CPU一次
    取Mailbox4與Mailbox5的訊息。

3.遠端通訊格式處理
兩個功能,是CAN Module對某個節點(Node)要求資料,第二個功能是某個Node
 發出請求要CAN Module回覆資料。

3.1.1 對另一個Node要求資料
當CAN Module要對某個Node要求資料,CAN Module先設置自已為接收端,
Mailbox3為例子,CPU的執行程序如下。
1.設置Mailbox3的MSGCTRL裡的RTR bit為"1",表示從Mailbox3發出遠端幀
   求 (Remote Frame Request)給某個Node,並由Mailbox 3接收遠端回傳的資
   料。也設定MSGCTRL裡的DLC為"2",表示回傳的資料長度為2 Bytes長度。
2.設置Mailbox3的MSGID為0x4F780000,表示AME(Acceptance mask enable)
   為"1",會使用acceptance mask。因外MSGID.IDE被設為"0",表示為標準
    ID,MSGID.ID 28:0只有28:18有效,所以發送的ID為0x0F780000"右移18
   位,等於0x3DE。
3.設置CANTRS.3為"1",就會從Mailbox3發送Remote Frame Request給對應ID
   的Node。
4.等待RMP.3被設置為"1",表示有接收到資料。

3.1.2 回應遠端資料要求
當CAN Module是做為傳送端,被某個Node要求回傳資料。
1.在Mailbox enable前,先在CANMD設置此Mailbox為傳送端,設置它的
   MSGID.AAM bit為"1",這樣Mailbox在收到Remote request後,自動回覆
   Mailbox message(CANMDL,CANMDH)內的資料。設置MSGID為
   0x35AC0000, 表示AAM bit為"1", ID[28:0]為0x15AC0000。
2. 設置要回覆的資料在CANMDL,CANMDH。
3. 在CANME將Mailbox設置為enable,將來收到remote request後,TRS bit
    會自動被設為"1",並將資料傳送到遠端的Node。在傳送資料後,CANTA對  
    應的Mailbox_n bit會被設為"1"。CPU可以在這個bit被設為"1"後,更新
     Message資料。

3.2 在自動回覆模式時,更新回覆內容
1.設置CANMC CDR bit為"1",CANMC的MBNR選擇要設定的Mailbox。
2.更新Mailbox內的資料CANMDL,CANMDH, 
3.將設置CANMC.CDR bit為"0",表示資料更改完成。
#在設置CDR更新資料前,如果TRSn已經設置,就可能會傳送舊的
  資料,而不是更新後的資料。要避免這個問題,就用TRRn 將傳送要求取消,
   等到資料更新後,再重新設置TRSn,發起傳送請求。


下面是TI TMS320F2833X的參考程式碼,設置迴圈100次,由Mailbox25連續發送訊息。

Example_2833xEcanA_to_B_Xmit.c

// Step 5. User specific code
    //
    // Write to the MSGID field
    //
    ECanaMboxes.MBOX25.MSGID.all = 0x95555555;          // Extended Identifier

    //
    // Configure Mailbox under test as a Transmit mailbox
    //
    ECanaShadow.CANMD.all = ECanaRegs.CANMD.all;
    ECanaShadow.CANMD.bit.MD25 = 0;
    ECanaRegs.CANMD.all = ECanaShadow.CANMD.all;

    //
    // Enable Mailbox under test
    //
    ECanaShadow.CANME.all = ECanaRegs.CANME.all;
    ECanaShadow.CANME.bit.ME25 = 1;
    ECanaRegs.CANME.all = ECanaShadow.CANME.all;

    //
    // Write to DLC field in Master Control reg
    //
    ECanaMboxes.MBOX25.MSGCTRL.bit.DLC = 8;

    //
    // Write to the mailbox RAM field
    //
    ECanaMboxes.MBOX25.MDL.all = 0x55555555;
    ECanaMboxes.MBOX25.MDH.all = 0x55555555;

    //
    // Begin transmitting
    //
    for(i=0; i < TXCOUNT; i++)
    {
        ECanaShadow.CANTRS.all = 0;
        ECanaShadow.CANTRS.bit.TRS25 = 1;     // Set TRS for mailbox under test
        ECanaRegs.CANTRS.all = ECanaShadow.CANTRS.all;

        do
        {
            ECanaShadow.CANTA.all = ECanaRegs.CANTA.all;
        } while(ECanaShadow.CANTA.bit.TA25 == 0 );// Wait for TA5 bit to be set

        ECanaShadow.CANTA.all = 0;
        ECanaShadow.CANTA.bit.TA25 = 1;                  // Clear TA5
        ECanaRegs.CANTA.all = ECanaShadow.CANTA.all;

        loopcount ++;
    }
    __asm(" ESTOP0");  // Stop here
}

//
// End of File

//

Reference
1.TMS320x2833x, 2823x DSP Enhanced Controller Area Network (eCAN) User's Guide




2020年2月21日 星期五

DSP TI TMS320F283xx eCAN初始化


在開始使用DSP2833x前,需要對它進行初始化,下面是初始化的步驟與TI 提供的eCAN初始參考程式。
CAN bit-timing需要根據系統需求去設置,其他需要設定的是開啟eCANA還是eCANB,由那兩個GPIO。

DSP2833x eCAN功能初始化步驟

InitSysCtrl()
將CAN module的Clock致能:在SysCtrlRegs.PCLKCR0.bit,將要用到的ECANAENCLK 與/或 
ECANBENCLK設為"1"。

InitECanGpio()
Step 1.設定CANRXA、CANTXA所對應的GPIO pin,在GPAPUD將這兩pin設為"0"
            使內部Pullup關閉。
Step 2.設置CANRXA所對應的GPIO pin,做為input,在GPAQSELx暫存器將這
            pin設為非同步(Asynchronous),因為它不是一般GPIO功能,而是周邊通
            訊功能。
Step 3.設定CANRXA、CANTXA所對應的兩個GPIO pin,在GPIO GUAMUX2將
           它們設為CANRXA, CANTXA。


InitECan()
Step 1. 將 CANTX、CANRX pins設為CAN功能。
             a. Write CANTIOC.3:0 = 0x08
             b. Write CANRIOC.3:0 = 0x08
Step 2.設置Master control暫存器CAMMC的SCB,"1"表示為High end CAN ccontroller,
           "0"表示為Standard Can controller
Step 3.初始化設定,將所有Mailbox的Message control暫存器MSGCTR設為"0",。
           將一些旗標暫存器CANTA, CANRMP, CANGIF0, CANGIF1寫入"1",確保它們
           被清除為"0"。
Step 4.要設置CAN bit timing前,要發設定CANMC.CCR為"1",請求修改CANBTC,再
            來就要等待CANES.CCE為"1",表示CPU允許CANBTC被設置。
Step 5.從CANBTC暫存器,來設置期望的CAN bit timing. 可以參考我另一篇
           "DSP TI TMS320F283xx eCAN module control 與 Bit-Timing設定"
Step 6.完成CANBTC設定後,將CANMC.CCR設為"0",要求回到正常模式。然後等待
            CANES.CCE為"0",表示CPU同意。
Step 7.發送、接收Mailbox都有對應的MSGID,在設置MSGID前,要將Mailbox disable,
            由CANME為"0"來完成。

#eCanaRegs不支援位元操作,所以要設置這些暫存器時,要先將暫存器先存到
ECanaShadow, 做為它的影子,然後在ECanaShadow上設置位元後,再存回eCanaRegs。


DSP2833x參考程式碼

DSP2833x_SysCtrl.c
InitSysCtrl(void)->InitPeripheralClocks();
    SysCtrlRegs.PCLKCR0.bit.ECANAENCLK=1;    // eCAN-A
    SysCtrlRegs.PCLKCR0.bit.ECANBENCLK=1;    // eCAN-B


DSP2833x_ECan.c
void InitECana(void)        // Initialize eCAN-A module
{
/* Create a shadow register structure for the CAN control registers. This is
needed, since only 32-bit access is allowed to these registers. 16-bit access
to these registers could potentially corrupt the register contents or return
false data. This is especially true while writing to/reading from a bit
(or group of bits) among bits 16 - 31 */

struct ECAN_REGS ECanaShadow;
    EALLOW;        // EALLOW enables access to protected bits

/* Configure eCAN RX and TX pins for CAN operation using eCAN regs*/  

    ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;
    ECanaShadow.CANTIOC.bit.TXFUNC = 1;                            //設置CAN RX PIN做為CAN Receiver功能
    ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;

    ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;
    ECanaShadow.CANRIOC.bit.RXFUNC = 1;                           //設置CAN RX PIN做為CAN Receiver功能
    ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;

/* Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31) */
                                    // HECC mode also enables time-stamping feature
//設置SCB bit為1,表示eCAN做為HECC(High-end-CAN Controller)
//設置SCB bit為0,表示為SCC(Standard CAN Controller)
    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.SCB = 1;                                    
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;    


/* Initialize all bits of 'Master Control Field' to zero */
// Some bits of MSGCTRL register come up in an unknown state. For proper operation,
// all bits (including reserved bits) of MSGCTRL must be initialized to zero

    ECanaMboxes.MBOX0.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX1.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX2.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX3.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX4.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX5.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX6.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX7.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX8.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX9.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX10.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX11.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX12.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX13.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX14.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX15.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX16.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX17.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX18.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX19.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX20.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX21.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX22.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX23.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX24.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX25.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX26.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX27.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX28.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX29.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX30.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX31.MSGCTRL.all = 0x00000000;

// TAn, RMPn, GIFn bits are all zero upon reset and are cleared again
//    as a matter of precaution.
    ECanaRegs.CANTA.all    = 0xFFFFFFFF;     //CANTA為Transmission ACK bit, 寫入"1"去清除。

    ECanaRegs.CANRMP.all = 0xFFFFFFFF;    //CANRMP為Receive message pending,
                                                                             //對應的bit表示這個mailbox有存message了,寫入"1"去清除。
    ECanaRegs.CANGIF0.all = 0xFFFFFFFF;    /* Clear all interrupt flag bits */  CANGIF0為Globe interrupt flag
    ECanaRegs.CANGIF1.all = 0xFFFFFFFF;

/* Configure bit timing parameters for eCANA*/

    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.CCR = 1 ;           //請求修改配置CANBTC、接收屏蔽CANGAM、LAM0。
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    ECanaShadow.CANES.all = ECanaRegs.CANES.all;

    do
    {
        ECanaShadow.CANES.all = ECanaRegs.CANES.all;   
    } while(ECanaShadow.CANES.bit.CCE != 1 );       // 將值存到Shadon暫存器,等待CCE1為1後,
                                                                                 //可以開始去設置CANBTC暫存器
    ECanaShadow.CANBTC.all = 0;                      //設Shadown裡CANBTC為0。       
    #if (CPU_FRQ_150MHZ)           // CPU_FRQ_150MHz is defined in DSP2833x_Examples.h
        /* The following block for all 150 MHz SYSCLKOUT - default. Bit rate = 1 Mbps */
            ECanaShadow.CANBTC.bit.BRPREG = 9;
            ECanaShadow.CANBTC.bit.TSEG2REG = 2;
            ECanaShadow.CANBTC.bit.TSEG1REG = 10;
    #endif
    #if (CPU_FRQ_100MHZ)           // CPU_FRQ_100MHz is defined in DSP2833x_Examples.h
    /* The following block is only for 100 MHz SYSCLKOUT. Bit rate = 1 Mbps */
        ECanaShadow.CANBTC.bit.BRPREG = 9;
        ECanaShadow.CANBTC.bit.TSEG2REG = 1;
        ECanaShadow.CANBTC.bit.TSEG1REG = 6;
    #endif

    ECanaShadow.CANBTC.bit.SAM = 1;          //每個採樣點取樣3次。
    ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;    //將Shadown裡的設置到實際暫存器。
    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.CCR = 0 ;                            // 設置CCR為0,回到正常模式,無法再改CANBTC。
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    ECanaShadow.CANES.all = ECanaRegs.CANES.all;

    do
    {
       ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 0 );         // Wait for CCE bit to be  cleared..

/* Disable all Mailboxes  */
    ECanaRegs.CANME.all = 0;               // 在寫入MSGID前,先將CAN Mailbox關閉

    EDIS;
}

----------------------------------------------------------------------

void InitECanaGpio(void)
{
   EALLOW;

/* Enable internal pull-up for the selected CAN pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPAPUD.bit.GPIO30 = 0;        // 關閉GPIO30內部Pullup
    GpioCtrlRegs.GPAPUD.bit.GPIO31 = 0;        // 關閉GPIO31內部Pullup
                                        
/* Set qualification for selected CAN pins to asynch only */
// Inputs are synchronized to SYSCLKOUT by default.
// This will select asynch (no qualification) for the selected pins.

    GpioCtrlRegs.GPAQSEL2.bit.GPIO30 = 3;   // Asynch qual for GPIO30 (CANRXA)
                                                                               //"3"表示Asychronous Qualification
/* Configure eCAN-A pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be eCAN functional pins.
    GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 1;    // Configure GPIO30 for CANRXA operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 1;    // Configure GPIO31 for CANTXA operation

    EDIS;

}














2020年1月2日 星期四

DSP TI IQ_math and Float format


IEEE 754單精度Float為32bit浮點數,TI定義了IQ-Math,在某些沒有FPU的
C2000 MCU,用定點來模擬浮點。例如F28035沒有FPU單元,就可以用
IQ-Math來做浮點運算,而F28335有FPU單元,就可以用Float來做運算。
下面解釋兩者的格式與差異。


Float Format
Float總有有32bit,格式如下
s為正負號(sign),佔1 個bit,0為正, 1為負。
e為指數(exponent),佔8個bit。
f為尾數(fraction),佔23個bit。
數值非平均分佈,離中心值"0"越遠,解析度越差。






例如:0x41200000 =  0 , 100 0001 0, 010 0000 0000 ....  0000b ,
可以得到 s=0,  e=130,  f=1.01b = 1.25(十進制), v=2^3 * (1.25)= 10.0。


IQ-Math Format
TI IQ-Math總共有32bit,I與Q的佔多少bit,是可以設定的,像是I1Q31或I31Q1。

例如"I8Q24"格式如下:
S為正負號,佔1 個bit,0為正, 1為負。
I為指數,佔7個bit。
f為分數,佔24個bit。
可以表示的範圍為 -2^(I-1)~ 2^(I-1) => -128 ~ 128,解析度為2^(-Q)=2(-24),
所以如果我們要增加表示的範圍,就增加I,要增加解析度,就要增加Q。









當S=1:表示這個數值為負,在I8Q24,就會有前面的 -2^I= -256,
              在2進制就用2的補數來表示負數。例如11010110表示為
              負的"101010"= -42
當S=0:就沒有-2^I這個值。將前面的例子11010110將前面的sign
               bit改為"0",會得到正數"01010110"=78。
例如:0x41200000 =  0 , 100 0001, 0 010 0000 0000 ....  0000b ,
 =2^6+2^0+2^(-3)=65.125。


IQ-Math Function
浮點運算與IQmath在算數函式、三角函式的指令,



















浮點運算與IQmath的轉換函式。





















Referemce
1.IQ Math on the Texas Instruments TMS320C28x DSP
http://read.pudn.com/downloads287/ebook/1294018/IQMath-datasheet/IQmath%E7%9A%84%E4%BD%BF%E7%94%A8.pdf


2019年12月30日 星期一

DSP TI TMS320F283xx eCAN module control 與 Bit-Timing設定



在設定TI DSP的eCAN module,最先要了解的是主控暫存器與Bit-Timing設定,
這篇會寫到暫存器內,有那些位元,要如何設置。另外CAN Bit-Timing的設定
會影響到與其他CAN裝置的通訊,需要仔細調試。

CAN Master control register(主控暫存器)











CANMC.SUSP:在Suspend,設為"1"為Free,持續CAN通信。設為"0"為Soft,
                             當前訊息發完就關閉。
CANMC.MBCC:設定在SCC模式下,受EALLOW保護。設為"1", 在成功收發
                             Mail16,便清除mail conunter。
CANMC.TCC:設"1"去清除Mail counter的MSB BIT,TCC Bit會在一個時鐘
                           周期後,自動清除為"0"。
CANMC.SCB:設"1"為選擇eCAN模式,設"0"為選擇SCC模式。
CANMC.CCR:改變配置請求位元,在SCC模式下,要對CANBTC、                
                           CANGAM、LAM0、LAM3寫入設定,需要先將CCR bit設為"1", 
                           並等到CANES的CCE顯示為"1"(表示同意後),才能去修改這些
                           暫存器的設定。
CAMMC.PDR:本地斷電請求,設PDR位元"1" ,請求將eCAN模組進斷電模
                            式,也包括將eCAN模組Clock關閉。
CAMMC.DBO:傳送/接收資料位元組順序,設DBO為"1",從最低位元組先傳
                             收。設為"0",則從最高位先組傳收。
CAMMC.WUBA:喚醒Bus線方式,設為"1",當Bus線上有活動,就將eCAN模
                                組從斷電模式中喚醒。設為"0",只能寫入PDR bit來喚醒。
CAMMC.CDR:改變數據區域請求,在更改CAMMC.MBNR 4:0的區塊資料之
                             前,需要先將CDR bit設為"1",在更改完後,要將CDR bit設
                             為"0"。在CDR bit為"1"時,eCAN模組不會傳送那個Mailbox的
                             內容。
CAMMC.ABO:自動Bus開啟位元,ABO設為"1"時,在Bus off狀態,在偵測到
                             第128*11個隱性位元後,自動回到Bus on狀態。ABO設
                             為"0"時,在Bus off時,要檢測到連續128*11隱性位元並且CCR
                             位元已經被清除,才會回到Bus on狀態。
CAMMC.STM:自我測試模式,在設為"1"後,進入自我測試模式,eCAN模組
                             能自已產生Ack回應,不需要在Bus上連接其他的模組,發出去
                            的資料會存在合適的mailbox,能被讀取。
CAMMC.SRES:軟體重置位元,寫入"1",就能對模組進行軟體重置,所有的
                              暫存器參數,除了被保護的,都會被重置回初始設定。
CAMMC.MBNR:有MBNR[4:0]共5個bit,MBNR[4]只有用在eCAN,在SCC無
                                效。設定Mailbox編號,CPU請求是對應的Mailbox要被用來寫
                               入料。與CDR搭配使用。


CAN傳輸速率配置


















CAN規範裡,將一個Bit Timing分成四個時間區段,裡面的單位為TQ(Time
 Quantum)圖中的TSEG1,TSEG2、SYNCSEG、SJW都是以TQ為單位。
1.SYNC_SEQ:同步節點,長度為1個TQ。
2.PROG_SEQ:用來補CAN網路裡的物理延遲時間(兩倍於Bus線上的信號傳播
                            延遲,這個延遲包括了輸入比較延遲與輸出驅動延遲),可以設
                            為1~8個TC。
3.Phase_SEG1:上升邊緣相位補償
4.Phase_SEG2:下降邊緣相位補償
5.SJW:同步跳轉寬度,用來增大或減小CAN Baudrate的容許偏差量。
5.Sample point:在每個BIT裡TSEG1與TSEG2之間,採樣點的位置,可以透過調
                              整TSEG1與TSEG2各自的長度,來調整。取樣位置不能太前也
                              不能太後面,不然可能會取到上升沿或下降沿。一般取樣位置
                               設定在50%之後,等待信號穩定再取樣,建議在75%~85%之
                               間。

CAN Bit-Timing Configuration register(位元時序設置暫存器)







CANBTC.BRPBRP為Baud rate分頻器設定,TQ=(BRP+1)/BaseCLK。
                            在283xx, 2803x的BaseCLK=SYSCLKOUT/2。
                            在281x, 280x與2801x的BaseCLK=SYSCLKOUT。
                             SYSCLKOUT是CAN module的系統時鐘。
CANBTC.TSEG1:為PROG_SEQ+Phase_SEG1
CANBTC.TSEG2:為Phase_SEQ2。
CANBTC.SJW:SJW可設定1~4個TQ,SJW的值直接影响到重同步時相位緩沖 
                             段的可調節範圍。選擇3、4可以使BUS線上獲得到更大的
                             Baudrate容許偏差量,一般的要求是3%以上。容許的偏差量太
                             低,通訊失敗的機率就會增加。
CANBTC.SAM:數據樣次數設置,"0"表示每個樣點只採1次,"1"在BRP>4
                              時每個採樣點採3次(多數決)。三次採樣是為了過濾掉Bus線上
                              的毛剌,但採用三次採樣可能會影響到SJW跳轉,所以一般
                              選用單次採樣。

Bit timing設置
當BRP設為49,BaseCLKK為SYSCLKOUT/2=75MHz,
TQ=50/75MHZ=0.667us。假設TSEG1=11個TQ,TSEG2=3個TQ
就可以得到tCAN=SYNCSEG+TSEG1+TSEG2=15個TQ=10us。
在這個範例可以設定CAN的Bit time為10us,速度為100kbit/s。



Reference
1.TMS320x2833x, 2823x DSP Enhanced Controller Area Network (eCAN) User's Guide
2.https://zhuanlan.zhihu.com/p/38299092

2019年9月30日 星期一

DSP TI TMS320F28335 I2C設置


I2C由SDA在收發資料,由SCL來傳送資料的Clock,Clock讓I2C傳送端與接收端可以
同步,每一個Clock代表一個bit。如下圖,TM320320F28335包含了control、status、
interrupt等暫存器,讓使用者可以藉由設置或讀取這這些暫存器來客制化I2C功能。

I2C發送與接收
當CPU要從SDA資料線傳送資料出去,是將資料寫入I2CDXR,I2CDXR會再將資料
轉到I2CXSR後,發送中斷信號XRDY,讓CPU知道資料已經被發送出去。

CPU要從SDA接收資料,資料是先被存到I2CRSR,在I2CRSR將資料更新到I2CDRR
後,發出中斷信號RRDY,讓CPU知道I2C module接收到新的資料,可以去讀取。


























I2C Clock設定
當TMS320F28335被設為I2C Master,要設置I2C SCL的Clock頻率,從下圖Figure 3
看到從Device input clock經過PLLCR,再到I2C Moudle IPSC、ICCL/ICC這三個除
頻器,最後產生出Master clock做為SCL的clock。TMS320F28335支援I2C頻率
10K~400KHz,為了要符合這個頻率區間,Moudule clock需要在7-12MHz。
在設定IPSC時,I2CMDR裡的IRS要設為"0"(reset state),如果在IRS為"1"時,修
改IPSC是無效的。
















Master clock公式
要得到Tmst(Master clock period),就要先得到Tmod(module clockperiod)、ICCL
、ICCH與d的值。而module clock由input clock除以 (IPSC+1)得出。另外d (delay)
的值如Table 15, 可以得知與IPSC的值有關,為5、6、7其中之1。

IPSC由暫存器I2CPSC.bit7:0來設定,範圍是 0~255。當IPSC設為"0",就表示
module clock=I2C input clock。在TI的Example code裡,I2C input clock有100MHz
、150MHz兩種設定,為了讓Module clock降到10MHz,符合7~12MHz的範圍,
在I2C input clock為100MHz時,就設IPSC為9,在150MHz時,設IPSC為14。
再來因為IPSC>1,所以d(delay)=5。

Tmod周期時間為module clock的倒數,Tmmod=1/10MHz=0.1us,再設置ICCL與
ICCH就可以得到Tmst。在TI的Example code裡,設置ICCL=10, ICCH=5,代入
公式,可以得到Tmst=Tmod x [(10+5) + (5+5)]=0.1us x 25= 2.5us,最後得出
Master clock= 1/ Tmst= 400KHz。









從Figure22可以看到,Tmst是Tmod所計算出來的。










I2C中斷事件
I2C有7個中斷事件,在Figure13可以看到,每個中斷事件,可以由I2CIER去設置
enable/disable,被設為disable的中斷事件,在事件發生時,就不會去通知CPU。
I2CSTR(I2C status register)裡面所對應的bit會會被設"1"。

XRDYINT:用來通知CPU,原來I2CDXR內資料已經傳送出去,可以再寫入新的
                      資料到I2CDXR。這個中斷不適用於FIFO模式。
RRDYINT:用來通知CPU,I2CDRR接收到新的資料,CPU可以來讀取。這個中
                      斷不適用於FIFO模式。
ARDYINT:當I2C Port做為Master,ARDYINT用來通知CPU,前一段I2C命令已
                      終止,可以再寫入新的命令到I2C module register。
NACKINT:當I2C Port做為Master,在傳送資料給接收端,接收端要在ACK/NACK
                       bit將SDA訊號下拉,來表示ACK,有接收到資料。如果接收端沒反
                       應ACK,NACKINT就會被SET,通知CPU,接收端沒接收到資料。
                   
ALINT:Arbitration-lost為仲裁丟失,當I2C BUS上有兩個或多個I2C Master,企圖
                去發送資料時,但I2C Bus上,只能有一個Master,所以需要去仲裁是那個
                I2C Master搶到發言權。在TMS320F28335的I2C Master Port沒搶到發信權,
                ALINT就會被SET來通知CPU,並由I2C Master轉為Slaver。
SCDINT:在I2C傳送資料的最後,會有個Stop bit,讓I2C Bus上其他的I2C Module在
                   ,在偵測到這個stop事件,可以知道資料傳送結束,否則I2C Bus就是在
                   busy狀態。SCDINT用來通知CPU,有Stop condition被偵測到。
AASINT:當I2C Port做為Slave,在I2C Bus上接收到另一個I2C Master發送出來位址
                   資料是這個I2C Port所設定的Slave位址(I2COAR),也就是這個命令是要
                   傳給自已的 ,則ASSINT會被SET,通知CPU,要去接收後面由I2C Master
                   傳來的資料。
,



I2C相關暫存器




















I2COAR:設置在做為Slaver時的address位址。
I2CIER:用來設置那些中斷是有效的。
I2CSTR:用來判斷I2C的狀態,其中有些暫存器要寫入"1"來清除狀態旗標。
I2CCLKL/I2CCLKH:用來設置I2C Master clock的周期時間與頻率。
I2CCNT:用來設置I2C Master是要傳多少Byte或接收傳輸多少Byte的data。
I2CDRR:CPU讀取這個暫存器來接收另一端傳送來的資料。
I2CSAR:在做為I2C Master,設置I2CSAR來設定要操作的Slave address。
I2CMDR:控制I2C進入Start、Stop、Nack、Repeak、Reset等模式,在I2C
                   收發資料的過程中,需要去設定I2CMDR裡面的bits。
I2CISRC:CPU在收收到中斷通知後,會先讀取I2CISRC來得知是那個
                   中斷事件發生,再去執行對應的處理程序。讀完I2CISRC後,
                    在I2CSTR內的Flag會被清除,但I2CSTR的ARDY、RRDY、
                    XRDY是需要寫入"1"去清除的。
I2CDXR:CPU寫入資料到這個暫存器,來傳送資料給另一端。
I2CEMDR:設置BCM (Backwards compatibility mode),在做為Slave端
                      並在發送資料時,BCM設置為"0" or "1"會影響I2CSTR
                      暫存器裡XRDY, XSMT的動作方式。
I2CPSC:設置I2C input clock的除頻多少來轉為I2C module clock。
I2CFFTX/I2CFFRX:在FIFO模式下,TX與RX的控制與狀態暫存器。




void I2CA_Init(void)
{
   // Initialize I2C
   I2caRegs.I2CMDR.all = 0x0000; //將I2C模式設為Reset/Disable mode 
   I2caRegs.I2CFFTX.all = 0x0000; // 將FIFO模式關閉,Reset FFTX。。
   I2caRegs.I2CFFRX.all = 0x0040; // Reset FFRX, FFRX中斷功能關閉。
   #if (CPU_FRQ_150MHZ)             // 當CPU頻率(SYSCLKOUT)為150MHz,就設置
        I2caRegs.I2CPSC.all = 14;   // PSC為14,module clk (150/15 = 10MHz)
   #endif
   #if (CPU_FRQ_100MHZ)             //當CPU頻率(SYSCLKOUT)為150MHz,就設置
     I2caRegs.I2CPSC.all = 9;     //PSC為9,module clk (100/10 = 10MHz)
   #endif
   I2caRegs.I2CCLKL = 10;             // 注意:不能設為"0"
   I2caRegs.I2CCLKH = 5;              // 注意:不能設為"0"
   I2caRegs.I2CIER.all = 0x24;        // 啟動SCD與ARDY中斷的偵測
   I2caRegs.I2CMDR.all = 0x0020; // 設置I2C peripheral(裝置)離開Reset mode,
                                //可以接收Host在I2C Bus發送的命令。   
   I2caRegs.I2CFFTX.all = 0x6000;     // 啟動I2C FIFO模式與TX FIFO運作。
   I2caRegs.I2CFFRX.all = 0x2040;     // 動作 RXFIFO,清除RXFFINT旗標。
   return;

}




Reference:
1.TI TMS320x2833x, 2823x Inter-Integrated Circuit (I2C) Module Reference Guide (Rev. B)