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