This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C1294NCPDT: TM4C1294 behaves incorrectly when system reset is performed

Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: SYSBIOS, ADS1298R

Hi everione, I have issue with system reset

Problem:

After triggering a system reset by a sensor removal the TM4C1294 behaves differently than on power ON. This happen when the sensor is plugged back in. 

The system goes into a Idle loop. Is there any solution?

Details:

- System uses RTOS
- Sensors are connected to the device which can be disconnected and reconnected this triggers a system reset
- Semaphores and tasks are used to control the functions

  • Hi,

      Can you answer a few questions as I'm not clear with the problem description.

     - Is this a custom board?

     - When you say asserting system reset, is this by means of RSTn input to the device or a software reset?

     - Does the sensor control the RSTn input to the MCU?

     - What is the behavior of RSTn when you disconnect and then reconnect the sensor?

     - Can you reproduce the problem on a LaunchPad?

     - Can you repeat the problem on different custom boards you have?

     - When you say the system goes into idle loop, please elaborate. Do you mean after system reset, the processor is executing only a Idle Task and all other tasks are not running? What do you mean by idle loop? 

      - Can you check the EXTRES bits in RESBEHAVCTL register? By default, a RSTn is supposed to generate a simulated POR. 

  • 1- yes this is a custom board which we have fabricated and is using ADS, and external digi sensors

    2- I'm using the SysCtlReset(); software reset.

    3 - The external sensors only control it in a software way,
    I check if the external sensor is available reading the designator register of the sensors using SPI,  if not available than I put a timeout to send the data to the PC and then perform the software reset on the MCU.

    5- We only have our custom boards. which have the hardware to connect the external sensors and the ADS-s 

    6- Yes we can repeat it on our custom boards

    7- The idle loop maybe different naming Idle task comes with the RTOS  (Idle.c - Idle_loop and Idle_run functions) also it goes into the ti_sysbios_hal_Hwi_checkStack functions this is in the (Hwi_stack.c file). The iddle loop is used by the RTOS when processor free time is available.

    8- There are 3 behaviors for this idle loop issue, when I reproduced it, and they are connected to each other. I wanted to add this

    8.1 When I unplug a sensor the reset is delayed more than it has to be, as it is delayed the code goes into the Idle Task, but then somehow it recovers and performs the reset.

    8.2 When I re-plug the sensor it goes into the idle loop after the ads is configured and the data reception is started, in which case the processor is executing only a Idle Task and all other tasks are not running.

    8.3 Remove sensor and plug back, The code goes into a never ending loop in which the following is performed:

    (configure device, read data ads and digi,  perform reset) 

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

    Program flow:

    main:

    - setup pins-> setup SPI periphery-> configure digi sensor-> configure usb regs-> configure the stream packet->

    Start BIOS

    ->semaphore start to configure ADS->
    inside the ads config task( stop the ads data stream-> delay-> configure the ADS 2x to make sure the registers are configured-> delay->ads cs pins 0 -> delay -> semaphore post start ads stream) -> task start ads data stream(send register settings to ads to stream data-> task_sleep 1) 

    ---  after this the control goes over to the interrupt pin 

    constant loop:

    ads drdy-> read data ads and digi-> append to usb buffer-> send data to pc

     

    -Reading data from sensors after the ads DRDY started the semaphore:

    Void task_ads1298r_drdy(UArg arg0, UArg arg1) {
    
    	SPI_Transaction ads1298rTransaction;
    	bool transferOK;
    	Uint8 txData[ALL_ADS_FRAME_SIZE];
    	Uint8 rxData[ALL_ADS_FRAME_SIZE + DIGI_SENSx4_DATA_SIZE];
    
    	while(true){
    
    		system_tracker(status_feedback_log);
    
    		status_feedback_log = 10;
    
    		memset(txData, 0xFF, sizeof(txData));
    		memset(rxData, 0, sizeof(rxData));
    
    		// Send address to ADS1298r
    		ads1298rTransaction.count = ALL_ADS_FRAME_SIZE;
    		ads1298rTransaction.txBuf = (Ptr)&txData[0];
    		ads1298rTransaction.rxBuf = (Ptr)&rxData[0];
    
    
    		Semaphore_pend(ads1298r_drdy_sem_handle, BIOS_WAIT_FOREVER);
    
    		transferOK = SPI_transfer(ads1298rSpi, &ads1298rTransaction);
    
    		if (transferOK){
    			GPIO_write(Board_LEDS4, 0);
    		}else{
    			GPIO_write(Board_LEDS4, 1);
    		}
    
    
    		ads_bitshift(&rxData[2*ADS_FRAME_SIZE],2);
    
    		//GPIO_toggle(Board_LEDS4);
    		if((++icm_counter % RAT_4KHZ_1KHZ) == 0){
    			read_icm20602x4_device( &rxData[ALL_ADS_FRAME_SIZE] );
    			GPIO_toggle(Board_LEDS5);
    		}  
    		//GPIO_toggle(Board_LEDS4);
    
    		Mailbox_post(ecg_mailbox_handle, rxData, BIOS_WAIT_FOREVER);
    
    		status_feedback_log = 11;
    
    	}
    
    }

    Inside this code the function is called to read digital sensors, this is the complete c file for that:

    // Variables for the restart function
    volatile uint16_t restart_timeout = 0;
    
    // Digital sensors current states are stored in the following variables
    volatile uint8_t digi_sensor_status = 0;
    
    volatile uint8_t digi_sensor_status1 = 0 ;
    volatile uint8_t digi_sensor_status2 = 0 ;
    volatile uint8_t digi_sensor_status3 = 0 ;
    volatile uint8_t digi_sensor_status4 = 0 ;
    
    
    // this is the sensor status after the sensors were initialised
    volatile uint8_t sensors_frozen_stats = 0;
    // this is the sensors status which shows the required sensors
    uint8_t digi_sensors_required = 0;
    
    volatile uint8_t current_state = 0;
    
    
    // reconfiguration variables
    volatile uint8_t current_digi_sensor_id = 0;
    volatile uint8_t digi_sensor_current = 0;
    
    
    #define DIGI_SENSOR_AUTO_RESET 1
    #define DIGI_SENSOR_WARNING_LIGHTS 1
    
    
    // debug function to check which tasks goes after which 
    volatile uint8_t system_tracker_pointer = 0;
    volatile uint8_t system_status[260];
    
    void system_tracker(uint8_t input_state){
    
    	if(system_tracker_pointer >= 0 && system_tracker_pointer <= 254){
    
    		uint8_t buf = system_tracker_pointer +1;
    		system_status[system_tracker_pointer] = input_state;
    		system_status[buf] = 1;
    
    		system_tracker_pointer++;
    	}else{
    		system_tracker_pointer = 0;
    	}
    
    }
    
    
    void configure_digital_sensors(){
    
    	restart_timeout = 0;
    
    	// Current status of the digital sensor
    	digi_sensor_status = 0;
        // warning lights
    	GPIO_write(Board_LED1,1); // turn on yellow LED
    
    	// configure the SPI interface for the DIGITAL Sensors
    	set_SSI1_device(DESIRED_SSI1_CLOCK);
    
    	// Disable all digital sensors
    	disable_digital_sensors();
    
    	delayUs(10);
    	// This initializes the digital sensors
    	main_sensor_init();
    }
    
    void disable_digital_sensors(){
    
    	// Disable all the DIGITAL sensors
    	SSI1_set_cs(DIGI_CS_PORT,DIGI1_CS_PIN);
    	SSI1_cs_off();
    
    	SSI1_set_cs(DIGI_CS_PORT,DIGI2_CS_PIN);
    	SSI1_cs_off();
    
    	SSI1_set_cs(DIGI_CS_PORT,DIGI3_CS_PIN);
    	SSI1_cs_off();
    
    	SSI1_set_cs(DIGI_CS_PORT,DIGI4_CS_PIN);
    	SSI1_cs_off();
    
    }
    
    //SENSOR_ACTIVE_  is a define which hold the place in the byte 0x1,0x2,0x4,0x8
    //SENSOR_ID_ is  a define which represents a number 1,2,3,4 sensors
    
    // Main initialization sequence
    void main_sensor_init(){
    
    	uint8_t curent_digi_sens_state = 0;
    
    	system_tracker(status_feedback_log);
    	status_feedback_log = 20;
    
    	// Simplified status sett
    	digi_sensor_status = 0;
    	digi_sensor_current = 0;
    
    	// ICM1
    	if(initialize_icm20602_sensor(SENSOR_ID_1, INIT_TIMEOUT)){
    		curent_digi_sens_state |=  SENSOR_ACTIVE_1;
    	}
    
    	// ICM2
    	if(initialize_icm20602_sensor(SENSOR_ID_2, INIT_TIMEOUT)){
    		curent_digi_sens_state |= SENSOR_ACTIVE_2;
    	}
    
    	// ICM3
    	if(initialize_icm20602_sensor(SENSOR_ID_3, INIT_TIMEOUT)){
    		curent_digi_sens_state |= SENSOR_ACTIVE_3;
    	}
    
    	// ICM4
    	if(initialize_icm20602_sensor(SENSOR_ID_4, INIT_TIMEOUT)){
    		curent_digi_sens_state |= SENSOR_ACTIVE_4;
    	}
    
    	// Simplified status sett
    	digi_sensor_status = curent_digi_sens_state & 0x0f;
    	digi_sensor_current = digi_sensor_status & 0x0f;
    
    	// Digital sensors status freezing
    	digi_sensor_status1 = (digi_sensor_status >> DIGI_SENSOR_INDEX_1) & 0x01;
    	digi_sensor_status2 = (digi_sensor_status >> DIGI_SENSOR_INDEX_2) & 0x01;
    	digi_sensor_status3 = (digi_sensor_status >> DIGI_SENSOR_INDEX_3) & 0x01;
    	digi_sensor_status4 = (digi_sensor_status >> DIGI_SENSOR_INDEX_4) & 0x01;
    
    	set_sensor_status();
    
    	//	Just clean the DS3 LED after config if sensors good
    	if(sensors_frozen_stats == digi_sensor_status){
    		GPIO_write(Board_LEDS4, 0);
    	}
    	if(sensors_frozen_stats != digi_sensor_status){
    		GPIO_write(Board_LEDS4, 1);
    	}
    
    	status_feedback_log = 21;
    
    }
    
    
    void set_sensor_status(){
    
    	uint8_t stat;
    	stat = digi_sensor_status & 0x0f;
    	
    	GPIO_write(Board_LED1,0); // turn off
    
    	if(stat == 0x0f){		// 1111
    		digi_sensors_required = FOUR_SENSOR_CONFIGURATION; // variable mnot used
    		sensors_frozen_stats = 0x0f;
    		return;
    
    	}else if(stat == 0x03){		// 0011
    		digi_sensors_required = TWO_SENSOR_CONFIGURATION_A;  // variable mnot used
    		sensors_frozen_stats = 0x03;
    		return;
    
    	}else if(stat == 0x0c){		// 1100
    		digi_sensors_required = TWO_SENSOR_CONFIGURATION_B;  // variable mnot used
    		sensors_frozen_stats = 0x0c;
    		return;
    
    	}else if(stat == 0){		// 0000
    
    		GPIO_write(Board_LED1,1);
    
    		sensors_frozen_stats = 0x0f;
    		return;
    
    	}else{
    
    		if(stat == TWO_SENSOR_C_FIRST_PLUGED ||  stat == TWO_SENSOR_C_SECOND_PLUGED){
    
    			digi_sensors_required = TWO_SENSOR_CONFIGURATION_A;  // variable mnot used
    
    			GPIO_write(Board_LED1,1);
    
    			sensors_frozen_stats = 0x03;
    			return; //
    
    
    		} else if(stat == TWO_SENSOR_C_THIRD_PLUGED ||  stat == TWO_SENSOR_C_FOURTH_PLUGED){
    
    			digi_sensors_required = TWO_SENSOR_CONFIGURATION_B;  // variable mnot used
    
    			GPIO_write(Board_LED1,1);
    			
    			sensors_frozen_stats = 0x0c;
    			return;
    		}
    
    		digi_sensors_required = FOUR_SENSOR_CONFIGURATION;  // variable mnot used
    
    		GPIO_write(Board_LED1,1);
    
    		sensors_frozen_stats = 0x0f;
    		return;
    	}
    
    }
    
    //SENSOR_ID_ Defines which sensor will be used   1,2,3,4
    
    // Read all the four sensors
    void read_icm20602x4_device(uint8_t *buffer) {
    
    	status_feedback_log = 14;
    
    	// sensor 1 if device is available read data from it
    	if (digi_sensor_status1){
    		digi_sensor_status1 = read_icm20602_sensor(SENSOR_ID_1, READ_TIMEOUT, buffer);
    	}
    	else{
    		if(isavailable_icm20602(SENSOR_ID_1)){
    			if (check_digi_byte() == 1){
    				digi_sensor_status1 = 1;
    				// no restart
    			}else{
    				// restart indicated
    				digi_sensor_current |= SENSOR_ACTIVE_1;
    			}
    		}
    		else{
    			digi_sensor_current &= ~SENSOR_ACTIVE_1;
    		}
    
    	}
    
    	// sensor 2 if device is available read data from it
    	if (digi_sensor_status2){
    		digi_sensor_status2 = read_icm20602_sensor(SENSOR_ID_2, READ_TIMEOUT, buffer);
    	}
    	else{
    		if(isavailable_icm20602(SENSOR_ID_2)){
    			if (check_digi_byte() == 1){
    				digi_sensor_status2 = 1;
    				// no restart
    			}else{
    				// restart indicated
    				digi_sensor_current |= SENSOR_ACTIVE_2;
    			}
    		}
    		else{
    			digi_sensor_current &= ~SENSOR_ACTIVE_2;
    		}
    
    	}
    
    	// sensor 3 if device is available read data from it
    	if (digi_sensor_status3){
    		digi_sensor_status3 = read_icm20602_sensor(SENSOR_ID_3, READ_TIMEOUT, buffer);
    	}
    	else{
    		if(isavailable_icm20602(SENSOR_ID_3)){
    			if (check_digi_byte() == 1){
    				digi_sensor_status3 = 1;
    				// no restart
    			}else{
    				// restart indicated
    				digi_sensor_current |= SENSOR_ACTIVE_3;
    			}
    		}
    		else{
    			digi_sensor_current &= ~SENSOR_ACTIVE_3;
    		}
    	}
    
    	// sensor 4 if device is available read data from it
    	if (digi_sensor_status4){
    		digi_sensor_status4 = read_icm20602_sensor(SENSOR_ID_4, READ_TIMEOUT, buffer);
    	}
    	else{
    		if(isavailable_icm20602(SENSOR_ID_4)){
    			if (check_digi_byte() == 1){
    				digi_sensor_status4 = 1;
    				//				 no restart/
    			}else{
    				// restart indicated
    				digi_sensor_current |= SENSOR_ACTIVE_4;
    			}
    
    		}
    		else{
    			digi_sensor_current &= ~SENSOR_ACTIVE_4;
    		}
    	}
    
    
    	digi_sensor_status &= 0x00;
    	digi_sensor_status = digi_sensor_status1 << DIGI_SENSOR_INDEX_1 | digi_sensor_status2 << DIGI_SENSOR_INDEX_2 | digi_sensor_status3<< DIGI_SENSOR_INDEX_3 | digi_sensor_status4 << DIGI_SENSOR_INDEX_4;
    
    	//	to debug the status of teh sensors
    	current_state = digi_sensor_status;
    
    
    	if(DIGI_SENSOR_AUTO_RESET){
    
    		if(digi_sensor_status != digi_sensor_current && restart_timeout < 2){
    			// LEDs
    			GPIO_write(Board_LED1,1);
    			GPIO_write(Board_LEDS5,1);
    
    			restart_timeout = 1; // start counter - Enable the resetting variable and function
    		}
    		if (restart_timeout>0) // increment after once the restart_timeout=1
    			restart_timeout++;
    
    		if (restart_timeout>RESTART_TIMEOUT){
    			// Delay and then restart the system
    			restart_system();
    
    			// Maybe to send the restart sequence as a semaphore 
    			// I added this to check if this could fix the problem
    			//Semaphore_post(ads1298r_reset_sem_handle);
    
    		}
    
    	}else{
    		if( digi_sensor_status != sensors_frozen_stats){ // Default frozen state  removed
    
    			// start reconfiguration procedure
    			hot_digi_reconfigure(); // update: digi_sensor_status
    
    			if(digi_sensor_status == sensors_frozen_stats){
    				GPIO_write(Board_LED1, 0);
    				GPIO_write(Board_LEDS5,0);
    			}
    			else{
    				GPIO_write(Board_LED1, 1);
    				GPIO_write(Board_LEDS5,1);
    			}
    		}
    		else{
    			GPIO_write(Board_LED1,0);
    			GPIO_write(Board_LEDS5,0);		// DS4 LED
    		}
    	}
    
    	status_feedback_log = 15;
    
    }
    
    // Restart System
    void restart_system(){
    
    	SysCtlReset();
    
    }

  • Hi Robert,

    Are you aware SW reset performs only a simulated internal reset? The best way to discover what is causing reset issue, CCS debug. Set several break points in the sensor code, first disable any and all project optimizations prior to compile. Step over repository functions in RTOS other than idle loop task or semaphore. Perhaps you're asking too much of RTOS to properly handle SW simulated reset?  

    Sensors are connected to the device which can be disconnected and reconnected this triggers a system reset

    Why do you need to simulate MCU reset when the sensors are unplugged or plugged in? Seemingly It may be beneficial to poll SPI port or variable values during idle loop task to determine sensors connection status. Perhaps Charles can give insight how to or options other than SW reset to check for SPI peripheral or sensors connection status.

  • HI,

      I have no knowledge about ADS1298r. I suppose your code relies on DRDY to generate an interrupt so that task_ads1298r_drdy can be unblocked. Does DRDY go low? Does it generate an interrupt? I will suggest you probe the signals between MCU and ADS and also put breakpoints in the code to see why some tasks are not executed. To me, there should be not much differences between POR and System Reset for the digital logic on MCU. 

  • Hi, GI, Charles

    - I'm actually not sure what a simulated reset means, I just know that it resets the registers and starts the firmware from beginning, if i'm not correct then please correct.

    - In the mean time I experienced another issue, when I tried to add another line in to the digital read sequence, before checking if data is ready from the digital sensors, I check if the sensor ID is correct.

    When I added this line then the data which i send to the PC broke.

    Later found out that that the timings of the semaphores and tasks are interfering with each other, now I'm tiring to sort out the tasks which are performed.

    I't looks like the reset function does not have any issu but more the performance of the tasks, if other way please correct.

  • After testing the firmware in regards of the reset issue it was found out that there was no issue with the resetting but there was a issue with the timing of the tasks and the time which the tasks require to perform, this made the reset issue more obvious than it is.

    This post will be closed and another one opened in regards of the tasks and timings of the tasks which are performed.