特性の分からない3相DCブラシレスモーターをソフトウェアエンコーダを搭載したTiのマイコンボードLAUNCHXL-F28069MとモータドライバBOOSTXL-DRV8305EVMを使って動かす(その6)
(編集中)
アナログ入出力だけでなく、シリアル接続なども使えた方がシステム構築には便利です。
ただ、C2000シリーズのマイコンでSCI(UART)接続しようというのは、Linuxの10倍ぐらい面倒くさいです。
Githubからサンプルプログラム
LAUNCHXL-F28027F+BOOSTXL-DRV8305EVMの組み合わせで、SCI(UART)を使うサンプルプロジェクトとして、こちらの掲示板の
InstaSPIN F28069MPZT : how to use UART/SCI communication to terminal? - InstaSPIN Motor Solutions Forum - C2000™ Microcontrollers - TI E2E Community
のスレッドで紹介されているAndrew Buckinさんのproj_lab05aの改造版
github.com
を参照すると、理解が早そうです。
ソースコードのdiffを取って、変更箇所を見ていきましょう。6つのソースファイルがあります。
proj_lab05a.c
hal/hal.c
hal/hal.h
hal/hal_obj.h
sci/sci.c
sci/sci.h
比較元のファイルの場所は、次の通りです。
C:\ti\motorware\motorware_1_01_00_16\sw\solutions\instaspin_foc\src
C:\ti\motorware\motorware_1_01_00_16\sw\modules\hal\boards\boostxldrv8305_revA\f28x\f2806x\src
C:\ti\motorware\motorware_1_01_00_16\sw\drivers\sci\src\32b\f28x\f2802x
proj_lab05a.c
// ************************************************************************** // the defines #define uint8_t char #define ECHO_ON 1 // set 1 to show input and 0 to disable it #define LED_BLINK_FREQ_Hz 5 #define BUF_LEN 8 // length of the command buffer // ************************************************************************** // the globals uint32_t ECap1IntCount = 0; uint32_t CAP_DATA[] = {0,0/*,0,0*/}; char cmdBuf[BUF_LEN]; // Input/command buffer uint8_t bufPos = 0; // Position of the next char in the buffer uint8_t cmdReady = 0; // Indicates that a command is ready for execution and blocks further input until reset to 0. //Added by Maya #ifdef SCI char * msg; uint16_t ReceivedChar = 0; //uint16_t RXISRCount = 0; //uint16_t SysCounter = 0; #endif
//Added by Maya #ifdef SCI interrupt void sciaISR(void) { //RXISRCount++; ReceivedChar = HAL_sciaRead(halHandle) & 0x00FF; //Handling escape. if(ReceivedChar != 27){ //Handling carriage return/new line. if(ReceivedChar != '\r' && ReceivedChar != '\n' && cmdReady == 0){ //Show input. if(ECHO_ON){ HAL_sciaWrite(halHandle, ReceivedChar); } //Handling backspace/delete. if(ReceivedChar != 127 && ReceivedChar != 8){ bufPos++; //If the end of the buffer wasn't reached, add new char to the buffer. if(bufPos < BUF_LEN){ cmdBuf[bufPos-1] = (char)ReceivedChar; //Adding char. cmdBuf[bufPos] = '\0'; //Appending null to indicate the end of the string. } }else{ //If the beginning of the buffer wasn't reached, remove the previous char from the buffer. if(bufPos > 0){ bufPos--; //Only delete if within buffer range. if(bufPos < BUF_LEN){ cmdBuf[bufPos] = '\0'; } } } }else if(cmdReady == 0){ //If enter was pressed, start new line and set cmdReady flag. msg = "\n\r"; HAL_sciaWriteMsg(halHandle, msg); cmdReady = 1; } }else{ //If escape is pressed, reset command buffer and clear cmdReady flag. cmdReady = 0; bufPos = 0; cmdBuf[0] = '\0'; } HAL_sciaClearRxFifoOvf(halHandle); HAL_sciaClearRxFifoInt(halHandle); HAL_pieAckInt(halHandle,PIE_GroupNumber_9); // Issue PIE ack INT9 return; } #endif
//Added by Dmitri Ranfft on 16.09.2015 #ifdef CAP __interrupt void ecap1ISR(void) { //scia_msg("interrupt\n\r"); // Cap input is syc'ed to SYSCLKOUT so there may be // a +/- 1 cycle variation CAP_DATA[0] = CAP_getCap1(halHandle->capHandle); CAP_DATA[1] = CAP_getCap2(halHandle->capHandle); //CAP_DATA[2] = CAP_getCap3(halHandle->capHandle); //CAP_DATA[3] = CAP_getCap4(halHandle->capHandle); ECap1IntCount++; CAP_clearInt(halHandle->capHandle, CAP_Int_Type_CEVT2); CAP_clearInt(halHandle->capHandle, CAP_Int_Type_Global); CAP_rearm(halHandle->capHandle); // Acknowledge this interrupt to receive more interrupts from group 4 PIE_clearInt(halHandle->pieHandle, PIE_GroupNumber_4); } #endif
eCAPというのが、また聞きなれないC2000特有の機能で、こちらに解説があります。
C2000の便利なeCAP機能を使って見ましょう - プロセッサ(DSP / ARM / MCU) - Japanese E2E (日本語コミュニティ) - TI E2E Community
hal
hal.c
607--609
// Added by Dmitri Ranfft on 16.09.2015 // Initialize the eCAP obj->capHandle = CAP_init((void *)CAP1_BASE_ADDR, sizeof(CAP_Obj));
652--656
//Added by Maya #ifdef SCI // Init SCI A registers obj->sciaHandle = SCI_init((void *) SCIA_BASE_ADDR, sizeof(SCI_Obj)); #endif
787--795
//Added by Maya #ifdef SCI HAL_setupSCI(handle); #endif //Added by Dmitri Ranfft on 16.09.2015 #ifdef CAP HAL_setupCAP(handle); #endif
994--1020
// PWMC_H // Edited by Dmitri Ranfft on 16.09.2015 (changed from EPWM3 to 4) GPIO_setMode(obj->gpioHandle,GPIO_Number_6,GPIO_6_Mode_EPWM4A); // PWMC_L // Edited by Dmitri Ranfft on 16.09.2015 (changed from EPWM3 to 4) GPIO_setMode(obj->gpioHandle,GPIO_Number_7,GPIO_7_Mode_EPWM4B); // eCAP1 // Added by Dmitri Ranfft on 16.09.2015 GPIO_setPullUp(obj->gpioHandle, GPIO_Number_5, GPIO_PullUp_Enable); GPIO_setQualification(obj->gpioHandle, GPIO_Number_5, GPIO_Qual_Sync); GPIO_setMode(obj->gpioHandle,GPIO_Number_5,GPIO_5_Mode_ECAP1); // EN_GATE // Edited by Dmitri Ranfft on 16.09.2015 (changed from GPIO 6 to 4) GPIO_setMode(obj->gpioHandle,GPIO_Number_4,GPIO_4_Mode_GeneralPurpose); GPIO_setLow(obj->gpioHandle,GPIO_Number_4); GPIO_setDirection(obj->gpioHandle,GPIO_Number_4,GPIO_Direction_Output); // WAKE // Edited by Dmitri Ranfft on 16.09.2015 (changed from GPIO 7 to 12) GPIO_setMode(obj->gpioHandle,GPIO_Number_12,GPIO_12_Mode_GeneralPurpose); GPIO_setHigh(obj->gpioHandle,GPIO_Number_12); GPIO_setDirection(obj->gpioHandle,GPIO_Number_12,GPIO_Direction_Output); // No Connection // Disabled by Dmitri Ranfft on 16.09.2015 //GPIO_setMode(obj->gpioHandle,GPIO_Number_12,GPIO_12_Mode_GeneralPurpose);
修正前は、
// PWMC_H GPIO_setMode(obj->gpioHandle,GPIO_Number_4,GPIO_4_Mode_EPWM3A); // PWMC_L GPIO_setMode(obj->gpioHandle,GPIO_Number_5,GPIO_5_Mode_EPWM3B); // EN_GATE GPIO_setMode(obj->gpioHandle,GPIO_Number_6,GPIO_6_Mode_GeneralPurpose); GPIO_setLow(obj->gpioHandle,GPIO_Number_6); GPIO_setDirection(obj->gpioHandle,GPIO_Number_6,GPIO_Direction_Output); // WAKE GPIO_setMode(obj->gpioHandle,GPIO_Number_7,GPIO_7_Mode_GeneralPurpose); GPIO_setHigh(obj->gpioHandle,GPIO_Number_7); GPIO_setDirection(obj->gpioHandle,GPIO_Number_7,GPIO_Direction_Output); // No Connection GPIO_setMode(obj->gpioHandle,GPIO_Number_12,GPIO_12_Mode_GeneralPurpose);
1037--1045
// nFAULT //GPIO_setMode(obj->gpioHandle,GPIO_Number_28,GPIO_28_Mode_TZ2_NOT); // Edited by Dmitri Ranfft on 15.09.2015 // SCI_RX GPIO_setMode(obj->gpioHandle,GPIO_Number_28,GPIO_28_Mode_SCIRXDA); // No connection (TX) //GPIO_setMode(obj->gpioHandle,GPIO_Number_29,GPIO_29_Mode_GeneralPurpose); // Edited by Dmitri Ranfft on 15.09.2015 // SCI_TX GPIO_setMode(obj->gpioHandle,GPIO_Number_29,GPIO_29_Mode_SCITXDA);
修正前は、
// nFAULT GPIO_setMode(obj->gpioHandle,GPIO_Number_28,GPIO_28_Mode_TZ2_NOT); // No connection (TX) GPIO_setMode(obj->gpioHandle,GPIO_Number_29,GPIO_29_Mode_GeneralPurpose);
1348--1502
//Added by Maya void HAL_setupSCI(HAL_Handle handle) { #ifdef SCI HAL_Obj *obj = (HAL_Obj *) handle; char *msg; //FIFO // SCIFFTX = 0xE040 SCI_enableChannels(obj->sciaHandle); // SCI reset SCI_enableTxFifoEnh(obj->sciaHandle); // SCI FIFO transmit enable SCI_enableTxFifo(obj->sciaHandle); // SCI FIFO transmit reset/reenable SCI_clearTxFifoInt(obj->sciaHandle); // SCI clear FIFO transmit interrupt flag SCI_disableTxFifoInt(obj->sciaHandle); // disable FIFO transmit interrupt SCI_setTxFifoIntLevel(obj->sciaHandle, SCI_FifoLevel_Empty); // FIFO interrupt level // SCIFFRX = 0x2041 SCI_enableRxFifo(obj->sciaHandle); // SCI FIFO receive reset/reenable SCI_clearRxFifoInt(obj->sciaHandle); // SCI clear FIFO receive interrupt flag SCI_disableRxFifoInt(obj->sciaHandle); // disable FIFO receive interrupt SCI_setRxFifoIntLevel(obj->sciaHandle, SCI_FifoLevel_1_Word); // FIFO interrupt level SCI_enableRxFifoInt(obj->sciaHandle); // SCI stop bit, parity, loopback, char bits, idle/address mode (SCICCR = 0x07) SCI_setNumStopBits(obj->sciaHandle, SCI_NumStopBits_One); // SCICCR bit 7 SCI_setParity(obj->sciaHandle, SCI_Parity_Odd); // SCICCR bit 6 SCI_disableParity(obj->sciaHandle); // SCICCR bit 5 //SCI_enableParity(obj->sciaHandle); SCI_disableLoopBack(obj->sciaHandle); // SCICCR bit 4 SCI_setMode(obj->sciaHandle, SCI_Mode_IdleLine); // SCICCR bit 3 SCI_setCharLength(obj->sciaHandle, SCI_CharLength_8_Bits);// SCICCR bit 0-2 // TX enable, RX enable, RX ERR INT enable, SLEEP, TXWAKE (SCICTL1 = 0x03) SCI_disableRxErrorInt(obj->sciaHandle); // SCICTL1 bit 6 SCI_disable(obj->sciaHandle); // SCICTL1 bit 5 SCI_disableTxWake(obj->sciaHandle); // SCICTL1 bit 3 SCI_disableSleep(obj->sciaHandle); // SCICTL1 bit 2 SCI_enableTx(obj->sciaHandle); // SCICTL1 bit 1 SCI_enableRx(obj->sciaHandle); // SCICTL1 bit 0 // TXINT enable, RXINT enable, TXEMPTY, TXRDY (SCICTL2 = 0x03) SCI_enableRxInt(obj->sciaHandle); // SCICTL2 bit 1 SCI_disableTxInt(obj->sciaHandle); // SCICTL2 bit 0 // SCIH-SCIL BAUD - SCI_BAUD = (LSPCLK/(SCI_BRR*8)) - 1 SCI_setBaudRate(obj->sciaHandle, SCI_BaudRate_9_6_kBaud); // Reset SCI SCI_enable(obj->sciaHandle); msg = "\r\n\n ********** SCI setup is done! **********\0"; SCI_writeMsg(obj->sciaHandle, msg); //PIE_enableSciInt(obj->pieHandle, SCI_RXA); // enable SCI interrupt PIE_enableInt(halHandle->pieHandle, PIE_GroupNumber_9, PIE_InterruptSource_SCIARX); CPU_enableInt(obj->cpuHandle, CPU_IntNumber_9); // enable CPU interrupt #endif // of SCI } #ifdef SCI //Added by Maya //SCIA SCI_FifoStatus_e HAL_sciaGetRxFifoStatus(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; return (SCI_getRxFifoStatus(obj->sciaHandle)); } // end of HAL_scigetRXFIFOStatus() function //Added by Maya void HAL_sciaWrite(HAL_Handle handle, const uint16_t data) { HAL_Obj *obj = (HAL_Obj *) handle; SCI_write(obj->sciaHandle, data); } //Added by Maya void HAL_sciaWriteMsg(HAL_Handle handle, char * msg) { HAL_Obj *obj = (HAL_Obj *) handle; SCI_writeMsg(obj->sciaHandle, msg); } //Added by Maya uint16_t HAL_sciaRead(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; return (SCI_read(obj->sciaHandle)); } //Added by Maya void HAL_sciaClearRxFifoOvf(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; SCI_clearRxFifoOvf(obj->sciaHandle); } //Added by Maya void HAL_sciaClearRxFifoInt(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; SCI_clearRxFifoInt(obj->sciaHandle); } //Added by Maya void HAL_sciaClearTxFifoInt(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; SCI_clearTxFifoInt(obj->sciaHandle); } void HAL_sciaEnableRxInt(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; SCI_enableRxInt(obj->sciaHandle); } void HAL_sciaDisableRxInt(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; SCI_disableRxInt(obj->sciaHandle); } void HAL_sciaEnableTxInt(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; SCI_enableTxInt(obj->sciaHandle); } void HAL_sciaDisableTxInt(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; SCI_disableTxInt(obj->sciaHandle); } bool HAL_sciaTxReady(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; return (SCI_txReady(obj->sciaHandle)); } bool HAL_sciaTxEmpty(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; return (SCI_txEmpty(obj->sciaHandle)); } bool HAL_sciaRxParityError(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; return (SCI_rxParityError(obj->sciaHandle)); } bool HAL_sciaRxOverrunError(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; return (SCI_rxOverrunError(obj->sciaHandle)); } bool HAL_sciaRxFrameError(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; return (SCI_rxFrameError(obj->sciaHandle)); } void HAL_sciaEnable(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; SCI_enable(obj->sciaHandle); } void HAL_sciaDisable(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; SCI_disable(obj->sciaHandle); } #endif //End of SCI //Added by Maya, for PIE void HAL_pieAckInt(HAL_Handle handle, const PIE_GroupNumber_e groupNumber) { HAL_Obj *obj = (HAL_Obj *) handle; PIE_clearInt(obj->pieHandle, groupNumber); } void HAL_enablePieInt(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; PIE_enable(obj->pieHandle); } void HAL_disablePieInt(HAL_Handle handle) { HAL_Obj *obj = (HAL_Obj *) handle; PIE_disable(obj->pieHandle); }
1513--1556
// Added by Dmitri Ranfft on 16.09.2015 void HAL_setupCAP(HAL_Handle handle) { #ifdef CAP HAL_Obj *obj = (HAL_Obj *) handle; CLK_enableEcap1Clock(obj->clkHandle); CAP_disableInt(obj->capHandle, CAP_Int_Type_All); // Disable all capture interrupts CAP_clearInt(obj->capHandle, CAP_Int_Type_All); // Clear all CAP interrupt flags CAP_disableCaptureLoad(obj->capHandle); // Disable CAP1-CAP4 register loads CAP_disableTimestampCounter(obj->capHandle); // Make sure the counter is stopped // Configure peripheral registers //CAP_setCapOneShot(obj->capHandle); // One-shot CAP_setCapContinuous(obj->capHandle); CAP_setStopWrap(obj->capHandle, CAP_Stop_Wrap_CEVT2);// Stop at 4 events CAP_setCapEvtPolarity(obj->capHandle, CAP_Event_1, CAP_Polarity_Rising); // Falling edge CAP_setCapEvtPolarity(obj->capHandle, CAP_Event_2, CAP_Polarity_Falling); // Rising edge //CAP_setCapEvtPolarity(obj->capHandle, CAP_Event_3, CAP_Polarity_Rising); // Falling edge //CAP_setCapEvtPolarity(obj->capHandle, CAP_Event_4, CAP_Polarity_Falling); // Rising edge CAP_setCapEvtReset(obj->capHandle, CAP_Event_1, CAP_Reset_Enable); // Difference operation CAP_setCapEvtReset(obj->capHandle, CAP_Event_2, CAP_Reset_Enable); // Difference operation //CAP_setCapEvtReset(obj->capHandle, CAP_Event_3, CAP_Reset_Enable); // Difference operation //CAP_setCapEvtReset(obj->capHandle, CAP_Event_4, CAP_Reset_Enable); // Difference operation CAP_enableSyncIn(obj->capHandle); // Enable sync in CAP_setSyncOut(obj->capHandle, CAP_SyncOut_SyncIn); // Pass through CAP_enableCaptureLoad(obj->capHandle); CAP_enableTimestampCounter(obj->capHandle); // Start Counter //CAP_rearm(obj->capHandle); // arm one-shot CAP_enableCaptureLoad(obj->capHandle); // Enable CAP1-CAP4 register loads CAP_enableInt(obj->capHandle, CAP_Int_Type_CEVT2); // 4 events = interrupt // Enable CPU INT4 which is connected to ECAP1-4 INT: CPU_enableInt(obj->cpuHandle, CPU_IntNumber_4); // Enable eCAP INTn in the PIE: Group 3 interrupt 1-6 PIE_enableCaptureInt(obj->pieHandle); #endif }
hal.h
166--173
//Added by Maya #ifdef SCI extern interrupt void sciaISR(void); #endif //Added by Dmitri Ranfft on 16.09.2015 #ifdef CAP extern __interrupt void ecap1ISR(void); #endif
487--496
//Added by Maya #ifdef SCI pie->SCIRXINTA = &sciaISR; #endif //Added by Dmitri Ranfft on 16.09.2015 #ifdef CAP pie->ECAP1_INT = &ecap1ISR; //PIE_registerPieIntHandler(obj->pieHandle, PIE_GroupNumber_4, PIE_SubGroupNumber_1, (intVec_t)&ecap1ISR); #endif
1306--1333
// Added by Maya extern HAL_Handle halHandle; extern void HAL_setupSCI(HAL_Handle handle); //SCIA extern SCI_FifoStatus_e HAL_sciaGetRxFifoStatus(HAL_Handle handle); extern void HAL_sciaWrite(HAL_Handle handle, const uint16_t data); extern void HAL_sciaWriteMsg(HAL_Handle handle, char * msg); extern uint16_t HAL_sciaRead(HAL_Handle handle); extern void HAL_sciaClearRxFifoOvf(HAL_Handle handle); extern void HAL_sciaClearRxFifoInt(HAL_Handle handle); extern void HAL_sciaClearTxFifoInt(HAL_Handle handle); extern void HAL_sciaEnableRxInt(HAL_Handle handle); extern void HAL_sciaDisableRxInt(HAL_Handle handle); extern void HAL_sciaEnableTxInt(HAL_Handle handle); extern void HAL_sciaDisableTxInt(HAL_Handle handle); extern bool HAL_sciaTxReady(HAL_Handle handle); extern bool HAL_sciaTxEmpty(HAL_Handle handle); extern bool HAL_sciaRxParityError(HAL_Handle handle); extern bool HAL_sciaRxOverrunError(HAL_Handle handle); extern bool HAL_sciaRxFrameError(HAL_Handle handle); extern void HAL_sciaEnable(HAL_Handle handle); extern void HAL_sciaDisable(HAL_Handle handle); // Added by Maya extern void HAL_pieAckInt(HAL_Handle handle, const PIE_GroupNumber_e groupNumber); extern void HAL_enablePieInt(HAL_Handle handle); // Added by Dmitri Ranfft on 16.09.2015 extern void HAL_setupCAP(HAL_Handle handle);
hal_obj.h
41--60
// drivers #include "sw/drivers/adc/src/32b/f28x/f2802x/adc.h" #include "sw/drivers/cap/src/32b/f28x/f2802x/cap.h" // Added by Dmitri Ranfft on 16.09.2015 #include "sw/drivers/clk/src/32b/f28x/f2802x/clk.h" #include "sw/drivers/cpu/src/32b/f28x/f2802x/cpu.h" #include "sw/drivers/flash/src/32b/f28x/f2802x/flash.h" #include "sw/drivers/gpio/src/32b/f28x/f2802x/gpio.h" #include "sw/drivers/osc/src/32b/f28x/f2802x/osc.h" #include "sw/drivers/pie/src/32b/f28x/f2802x/pie.h" #include "sw/drivers/pll/src/32b/f28x/f2802x/pll.h" #include "sw/drivers/pwm/src/32b/f28x/f2802x/pwm.h" #include "sw/drivers/pwmdac/src/32b/f28x/f2802x/pwmdac.h" #include "sw/drivers/pwr/src/32b/f28x/f2802x/pwr.h" #include "sw/drivers/spi/src/32b/f28x/f2802x/spi.h" #include "sw/drivers/timer/src/32b/f28x/f2802x/timer.h" #include "sw/drivers/wdog/src/32b/f28x/f2802x/wdog.h" #include "sw/drivers/drvic/drv8305/src/32b/f28x/f2802x/drv8305.h" //Added by Maya //#include "sw/drivers/sci/src/32b/f28x/f2802x/sci.h" #include "sci.h"
131-133
//Added by Dmitri Ranfft on 16.09.2015 CAP_Handle capHandle; //!< the eCAP handle
173
SCI_Handle sciaHandle; //!< the sci handle, added by Maya
sci
sci.c
同一ファイルです。
sci.h
369--376
//Added by Maya typedef enum { SCI_RXA=0, //!< Denotes SCI receive A SCI_TXA=1, //!< Denotes SCI transmit A SCI_RXB=2, //!< Denotes SCI receive B SCI_TXB=3 //!< Denotes SCI transmit B } SCI_Type_e;
728--731 in static inline void SCI_write(SCI_Handle sciHandle,const uint16_t data)
//Added by Maya #ifdef SCI_FIFO while(SCI_getTxFifoStatus(sciHandle) != 0) {}; #endif
739--792
// Added by Maya static inline bool SCI_txEmpty(SCI_Handle sciHandle) { SCI_Obj *sci = (SCI_Obj *)sciHandle; bool status; status = (sci->SCICTL2 & SCI_SCICTL2_TXEMPTY_BITS) >> 6; return((bool)status); } // end of SCI_txEmpty() function //Added by Maya static inline void SCI_writeMsg(SCI_Handle sciHandle, char * msg) { int i; i = 0; while(msg[i] != '\0') { SCI_write(sciHandle, msg[i]); i++; } } static inline bool SCI_rxParityError(SCI_Handle sciHandle) { SCI_Obj *sci = (SCI_Obj *)sciHandle; bool status; status = (sci->SCIRXST & SCI_SCIRXST_PE_BITS) >> 2; return((bool)status); } // end of SCI_rxParityError() function static inline bool SCI_rxOverrunError(SCI_Handle sciHandle) { SCI_Obj *sci = (SCI_Obj *)sciHandle; bool status; status = (sci->SCIRXST & SCI_SCIRXST_OE_BITS) >> 3; return((bool)status); } // end of SCI_rxParityError() function static inline bool SCI_rxFrameError(SCI_Handle sciHandle) { SCI_Obj *sci = (SCI_Obj *)sciHandle; bool status; status = (sci->SCIRXST & SCI_SCIRXST_FE_BITS) >> 4; return((bool)status); } // end of SCI_rxParityError() function //End of addition by Maya
見比べる
差分の抽出が済みましたので、見比べていきましょう。
ピン変更までしてeCAPとやらを何に使っているのか、よくわかりませんね???
SCIを使うためには、基本的にMayaさんの変更箇所を見ていけばよいようです。
たかがシリアルで、こんなに面倒くさいと、このマイコン開発にリソースを割いていていいのかどうか不安になります。
動かして確認してみる
Mayaさんのコメント部分を自分のソースコードにコピーペーストし、sci.hとsci.cをプロジェクトに追加します。
また、sci.hの最初の方に
#define SCI 1
を書き加えます。
シリアル接続を確認するために、teratermでUSB COMPortに接続し、9600bpsの速度に設定します。
デバッグモードでFlashにproj_lab05b.outをアップロードすると、
"\r\n\n ********** SCI setup is done! **********\0";
の文字が表示されるはずなのですが、最初の3文字ぐらいしか出ません。
***9
ただ、何かは応答してくれているようです。
キーボードで文字を入力すると、エコーバックされてteraterm上に表示されます。BackSpaceキーを押すとカーソルが一つ戻ります。
Enterキーを押すと、ロックされた状態になりますが、Escを押すと、再び入力可能な状態になります。
ちゃんと動いているようですね。
FIFOを有効にして、通信欠落を減らす
sci.hのdefinesの中に
#define SCI 1
に加えて
#define SCI_FIFO 1
を追加します.
ところが、メモリの初期化がうまくいかずに起動直後はFIFOにゴミがあり、これを吐き出させる前にhal.cの中で文字列を出力させる次の2行を実行すると、わけのわからないゴミを延々と吐き続けて、クリアできないという状況に陥ります。
なので、この2行をコメントアウトします。
msg = "\r\n\n ********** SCI setup is done! **********\0"; SCI_writeMsg(obj->sciaHandle, msg);
sciaISRが回り始めた当初はまだゴミを少し吐くので、これを吐き出させた後に通信に使用するとうまい行くようです。
残念ながら、sci.hに定義されたどのコマンドを用いても、起動直後のバッファのゴミを削除することができませんでした。
重要な知見
LAUNCHXL-F28027F 不推奨のススメ
LAUNCHXL-F28027FにBOOSTXL-DRV8305EVM経由で電源を供給したときに、うまく初期化できません。外部リセットを行う以外の解決方法が見つかりません。
したがって、組み込み用途で使用するときに、大変不便します。
LAUNCHXL-F28027Fは、メモリ上での開発ができずコンパイルしたバイナリを毎回Flashメモリに焼きこむ必要があります。
ところが、フラッシュの耐久性の問題か、ロムライタのソフトウェアの問題か50回もしないうちに書き込み不可能になってしまいます。
書き込み不可能になったマイコンボードは捨てるしかほかありませんので、コンパイル50回毎に2000円が飛んでいくことになります。
C2000PiccoloシリーズおよびInstaSPINは、かなり特殊なソフトウェア体系(整理されてない)ので、ある程度使えるエキスパートになるまでには相当な時間がかかります。
同じシリーズの上位機種LAUNCHXL-F28069Mはとりあえずこれらの問題はありませんので、サイズはデカいですが値段はあまり変わらないのでこちらを推奨します。
SCI受信割り込み(例えば、SCIRXINTに紐づけられたsciaISR)の中で一文字たりとも送信してはいけない
まれにモータの制御が飛び一瞬停止するなど異常動作を起こすので、大暴走して事故の原因になりかねません。
本来、SCITXINTを有効にして、適切な送信割り込みを掛けるべきなのだと思いますが、すると今度はモータ制御がうまく行かなくなります。まだ原因が特定できません。
main関数のforeverループの中でループ一回に一文字づつ送るなどの方が無難なようです。mainISRではありません。mainISRは、adcの割り込みの呼び出し先です。
文字列長など、セグメンテーションエラーを起こさないように十分留意してください。
//Added by Maya #ifdef SCI interrupt void sciaISR(void) { //RXISRCount++; ReceivedChar = HAL_sciaRead(halHandle) & 0x00FF; //Handling escape. if(ReceivedChar != 27){ //Handling carriage return/new line. if(ReceivedChar != '\r' && ReceivedChar != '\n' && cmdReady == 0){ //Show input. if(ECHO_ON){ // \HAL_sciaWrite(halHandle, ReceivedChar); ///// Caution! Danger! } //Handling backspace/delete. if(ReceivedChar != 127 && ReceivedChar != 8){ bufPos++; //If the end of the buffer wasn't reached, add new char to the buffer. if(bufPos < BUF_LEN){ cmdBuf[bufPos-1] = (char)ReceivedChar; //Adding char. cmdBuf[bufPos] = '\0'; //Appending null to indicate the end of the string. } }else{ //If the beginning of the buffer wasn't reached, remove the previous char from the buffer. if(bufPos > 0){ bufPos--; //Only delete if within buffer range. if(bufPos < BUF_LEN){ cmdBuf[bufPos] = '\0'; } } } }else if(cmdReady == 0){ //If enter was pressed, start new line and set cmdReady flag. msg = "\n\r"; // HAL_sciaWriteMsg(halHandle, msg); ///// Caution! Danger! cmdReady = 1; } }else{ //If escape is pressed, reset command buffer and clear cmdReady flag. cmdReady = 0; bufPos = 0; cmdBuf[0] = '\0'; } HAL_sciaClearRxFifoOvf(halHandle); HAL_sciaClearRxFifoInt(halHandle); HAL_pieAckInt(halHandle,PIE_GroupNumber_9); // Issue PIE ack INT9 return; } #endif
今日の友達がいない漫画
タイトルに反して、主人公湯神くんの周りには登場人物多い。
- 作者: 佐倉準
- 出版社/メーカー: 小学館
- 発売日: 2016/10/18
- メディア: コミック
- この商品を含むブログ (1件) を見る