Other Parts Discussed in Thread: SYSCONFIG
Tool/software:
Tool/software:
Can you show me the whole project? I can help double check from my side.
Regards,
Zoey
#include "ti_msp_dl_config.h" #define wakeup_cmd 0x0033 #define null_cmd 0x0000 #define reset_cmd 0x1100 //0x0011 #define standby_cmd 0x0022 #define read_ID 0x00a0 union ads131b04 { struct { int response: 24; int chan0 : 24; int chan1 : 24; int chan2 : 24; int chan3 : 24; int crc: 24; } __attribute__((packed)) chans; uint8_t raw[18]; }; union ads131b04_cmd { struct { uint16_t cmd; uint16_t crc; uint32_t zeros[3]; } __attribute__((packed)) tx; uint8_t raw[16]; }; volatile union ads131b04_cmd command = {.tx.zeros = {0,0,0}}; volatile union ads131b04 resp; volatile bool gCheckTimer, gCheckADC, gCheckSleep, wakeup_signal_present = true; volatile uint32_t debug_counter = 0, debug_counter2 =0, stop_latency_counter = 0, debug_counter3 = 0; volatile DL_MCAN_ProtocolStatus protocolStatus; #define SPI_PACKET_SIZE (16) volatile DL_MCAN_TxBufElement txMsg; volatile DL_MCAN_RxBufElement rxMsg; void init_can_msg(volatile DL_MCAN_TxBufElement *txMsg) { /* Identifier Value. */ txMsg->id = ((uint32_t)(0x4)) << 18U; /* Transmit data frame. */ txMsg->rtr = 0U; /* 11-bit standard identifier */ txMsg->xtd = 0U; /* ESI bit in CAN FD format depends only on error passive flag. */ txMsg->esi = 0U; /* Transmitting 8 bytes. */ txMsg->dlc = 8U; /* CAN frames transmitted without bit rate switching. */ txMsg->brs = 1U; /* Frame transmitted in classic CAN format. */ txMsg->fdf = 1U; /* Store Tx events. */ txMsg->efc = 0U; /* Message Marker. */ txMsg->mm = 0xAAU; /* Data bytes. */ //txMsg.data[0] = LED0_STATUS_ON; } static const DL_TimerG_TimerConfig gTIMER_WAKEUPTimerConfig = { .period = TIMER_WAKEUP_INST_LOAD_VALUE, .timerMode = DL_TIMER_TIMER_MODE_ONE_SHOT, .startTimer = DL_TIMER_STOP, }; static const DL_MCAN_ClockConfig gMCAN0ClockConf = { .clockSel = DL_MCAN_FCLK_SYSPLLCLK1, .divider = DL_MCAN_FCLK_DIV_1, }; inline void delay(int cycles) { gCheckTimer = false; int counter; for (counter = 0; counter < cycles; counter++) { while (false == gCheckTimer) { __WFI(); } counter++; } } int main(void) { SYSCFG_DL_init(); NVIC_DisableIRQ(WAKEUP_PORT_INT_IRQN); // Enable NVIC interrupt NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN); NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN); NVIC_EnableIRQ(TIMER_WAKEUP_INST_INT_IRQN); //DL_MCAN_ProtocolStatus protocolStatus; DL_GPIO_clearPins(DBG_PORT, DBG_PIN_DBG_PIN); debug_counter = 0; const uint8_t to_be_transmitted = sizeof(command.raw)/sizeof(uint8_t); const uint8_t to_be_read = sizeof(command.raw)/sizeof(uint8_t); command.tx.cmd = null_cmd; init_can_msg(&txMsg); while (DL_MCAN_OPERATION_MODE_NORMAL != DL_MCAN_getOpMode(MCAN0_INST)) ; gCheckTimer = true; DL_TimerG_startCounter(TIMER_0_INST); DL_ADC12_enableConversions(ADC12_0_INST); //DL_TimerG_initTimerMode(TIMER_WAKEUP_INST, (DL_TimerG_TimerConfig *) &gTIMER_WAKEUPTimerConfig); DL_TimerG_startCounter(TIMER_WAKEUP_INST); while (1) { uint8_t idx_w, idx_r; if (wakeup_signal_present) { //DL_GPIO_setPins(DBG_PORT, DBG_PIN_DBG_PIN); while (false == gCheckTimer) { __WFE(); } gCheckTimer = false; while (false == gCheckADC) { __WFE(); } gCheckADC = false; // send cmd and read response from external ADC idx_w = 0; idx_r = 0; do { idx_w += DL_SPI_fillTXFIFO8(SPI_0_INST, &command.raw[idx_w], to_be_transmitted-idx_w); idx_r += DL_SPI_drainRXFIFO8(SPI_0_INST,&resp.raw[idx_r], to_be_read-idx_r); } while (to_be_transmitted > idx_w || to_be_read > idx_r); // read internal ADC results uint16_t v12redundant = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0); uint16_t v24redundant = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_1); uint16_t ref1v8 = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_2); txMsg.id = ((uint32_t)(0x7)) << 18U; txMsg.brs=1; uint32_t i=0; txMsg.data[i++] = (uint8_t)(resp.chans.chan0>>0 & 0xFF);// VBAT24 txMsg.dlc=11; DL_MCAN_writeMsgRam(MCAN0_INST, DL_MCAN_MEM_TYPE_BUF, 0, &txMsg); DL_MCAN_TXBufAddReq(MCAN0_INST, 0); } else { DL_GPIO_clearPins(DBG_PORT, DBG_PIN_DBG_PIN); if (stop_latency_counter == 0) { stop_latency_counter++; NVIC_DisableIRQ(TIMER_WAKEUP_INST_INT_IRQN); NVIC_DisableIRQ(ADC12_0_INST_INT_IRQN); NVIC_DisableIRQ(TIMER_0_INST_INT_IRQN); DL_TimerG_stopCounter(TIMER_0_INST); DL_VREF_disableInternalRef(VREF); DL_VREF_disablePower(VREF); DL_ADC12_disableConversions(ADC12_0_INST); DL_ADC12_disablePower(ADC12_0_INST); bool powerup_not_ok = true; bool ackstatus; uint32_t cancellation_status, retry_counter; gCheckSleep = false; DL_MCAN_txBufCancellationReq(MCAN0_INST, 0); do { cancellation_status = DL_MCAN_txBufCancellationStatus(MCAN0_INST); }while((cancellation_status & 0x1) == 0); //DL_MCAN_setOpMode(MCAN0_INST, DL_MCAN_OPERATION_MODE_SW_INIT); DL_MCAN_addClockStopRequest(MCAN0_INST, true);//CSR while (DL_MCAN_OPERATION_MODE_SW_INIT != DL_MCAN_getOpMode(MCAN0_INST));//INIT must be set to '1' by h/w DL_MCAN_enableClockStopGateRequest(MCAN0_INST);//STOPREQ while (DL_MCAN_isClockStopGateRequestEnabled(MCAN0_INST) == false);//STOPREQ do { { ackstatus = DL_MCAN_getClockStopAcknowledgeStatus(MCAN0_INST); //ACKSTS } }while (ackstatus == false); //while(DL_MCAN_getClockStopAcknowledgeStatus(MCAN0_INST) == true); DL_MCAN_disableModuleClock(MCAN0_INST); DL_GPIO_setPins(CAN_STB_PORT, CAN_STB_PIN_0_PIN); //DL_GPIO_clearPins(DBG_PORT, DBG_PIN_DBG_PIN); // DL_TimerG_initTimerMode(TIMER_WAKEUP_INST, (DL_TimerG_TimerConfig *) &gTIMER_WAKEUPTimerConfig); // DL_TimerG_startCounter(TIMER_WAKEUP_INST); DL_SYSCTL_setPowerPolicySTOP2(); NVIC_EnableIRQ(WAKEUP_PORT_INT_IRQN); if (!(SYSCTL->SOCLOCK.PMODECFG)) { __WFI(); } gCheckSleep = false; NVIC_DisableIRQ(WAKEUP_PORT_INT_IRQN); DL_SYSCTL_setPowerPolicyRUN0SLEEP0(); //SYSCFG_DL_init(); SYSCFG_DL_SPI_0_init(); DL_GPIO_clearPins(CAN_STB_PORT, CAN_STB_PIN_0_PIN); DL_MCAN_enableModuleClock(MCAN0_INST); DL_MCAN_disableClockStopGateRequest(MCAN0_INST); while (DL_MCAN_isClockStopGateRequestEnabled(MCAN0_INST) == true); DL_MCAN_addClockStopRequest(MCAN0_INST, false); while(DL_MCAN_getClockStopAcknowledgeStatus(MCAN0_INST) == true); gCheckTimer = false; SYSCFG_DL_TIMER_0_init(); DL_TimerG_startCounter(TIMER_0_INST); NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN); do { SYSCFG_DL_MCAN0_init(); //SYSCFG_DL_init(); //DL_GPIO_clearPins(DBG_PORT, DBG_PIN_DBG_PIN); DL_MCAN_getProtocolStatus(MCAN0_INST, &protocolStatus); if (protocolStatus.busOffStatus) { powerup_not_ok = true; delay(1000); } else powerup_not_ok = false; } while(powerup_not_ok); delay(1000); DL_VREF_disablePower(VREF); DL_VREF_enableInternalRef(VREF); debug_counter3++; DL_ADC12_enablePower(ADC12_0_INST); DL_ADC12_enableConversions(ADC12_0_INST); SYSCFG_DL_ADC12_0_init(); NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN); SYSCFG_DL_TIMER_WAKEUP_init(); NVIC_EnableIRQ(TIMER_WAKEUP_INST_INT_IRQN); DL_GPIO_clearPins(DBG_PORT, DBG_PIN_DBG_PIN); DL_TimerG_startCounter(TIMER_WAKEUP_INST); __enable_irq(); } else { if (stop_latency_counter > 50) stop_latency_counter = 0; else stop_latency_counter++; } } } } void TIMER_0_INST_IRQHandler(void) { DL_GPIO_setPins(DBG_PORT, DBG_PIN_DBG_PIN); switch (DL_TimerG_getPendingInterrupt(TIMER_0_INST)) { case DL_TIMERG_INTERRUPT_ZERO_EVENT: gCheckTimer = true; //debug_counter++; break; default: break; } } void ADC12_0_INST_IRQHandler(void) { switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) { case DL_ADC12_IIDX_MEM2_RESULT_LOADED: gCheckADC = true; //debug_counter2++; break; default: break; } } void TIMER_WAKEUP_INST_IRQHandler(void) { DL_MCAN_RxFIFOStatus fifoStatus = {0}; debug_counter2++; //DL_GPIO_setPins(DBG_PORT, DBG_PIN_DBG_PIN); switch (DL_TimerG_getPendingInterrupt(TIMER_WAKEUP_INST)) { case DL_TIMERG_INTERRUPT_ZERO_EVENT: DL_MCAN_getRxFIFOStatus(MCAN0_INST, &fifoStatus); if (fifoStatus.fillLvl > 0) { debug_counter++; do { DL_MCAN_readMsgRam(MCAN0_INST, DL_MCAN_MEM_TYPE_FIFO, 0U, fifoStatus.num, &rxMsg); DL_MCAN_writeRxFIFOAck(MCAN0_INST, fifoStatus.num, fifoStatus.getIdx); DL_MCAN_getRxFIFOStatus(MCAN0_INST, &fifoStatus); } while(fifoStatus.fillLvl > 0); wakeup_signal_present = true; } else { wakeup_signal_present = false; } gCheckSleep = true; break; default: break; } } void GROUP1_IRQHandler(void) { //debug_counter3++; DL_GPIO_clearInterruptStatus(WAKEUP_PORT_PORT, WAKEUP_PORT_WAKEUP_PIN); }well... yeah - it's very small
Since I can not see the sysconfig, just want to double check:
1. Not enable sleep on exit
2. Enable interrupt configuration
sure thing - no "Sleep on Exit"and the interrupt is enabled.
after two fixes the interrupts appeared. first is obvious missing
wakeup_signal_present = true
in GPIO interrupt handler.
but the second one had completely flabbergasted me - i did substituted
and reciprocal NVIC_DisableIRQ with clearInterruptStatus+disableInterrupt
Hi,
NVIC is used for control interrupt to tell the CPU
And
Hi Zoey, thank you for the reply. please elaborate on utilization of the mechanisms. I've been using them as following on other MCUs: the peripheral's interrupt switch is utilized only once in the init phase and never touched later; while the CPU's interrupt switch is constantly in use while toggling between interrupt on/off happens according to the application logic. same idea was implemented here but it backfired in .... completely different peripheral - the timer. could you tell - first if the process described above applicable to 3519 and why the effect observed.