Editor: Writing and Re-Factoring Code (Visual Assist)

The Studio 7 Editor is powered by an extension called Visual Assist, a productivity tool for re-factoring, reading, writing, and navigating C and C++ code.

Getting Started Topics

Video: Studio 7 Editor (Visual Assist)

  1. 1.Starting with the basic functionality from I/O View and Other Bare-Metal Programming References, main.c has the following code:
    #include <avr/io.h>
    
    int main(void)
    {
    	PORTB.DIR = PIN4_bm; 	
    	
        while (1) 
        {
        }
    }
The ATtiny817 Xplained Pro design documentation schematic shows the connections for the LED and button, as in the figure below.
Figure 1. ATtiny827 Xplained Pro GPIO Connection Schematics
From the schematics, it is concluded that:
  1. 1.Enable the pull-up on PORTB5, using suggestion list and enhanced list box. Note that suggestion lists support acronyms, so typing 'pp' PORT_PULLUPEN is the top suggestion.
  2. 2. However, before hitting enter, first type 'POR', then hit CTRL+SPACE. This will bring up the Enhanced Listbox with all possible options.

    Now it is possible to filter suggestions by type, as indicated in the picture below.

  3. 3.Test if SW0 is pressed, using if( ){...}else{...} visual assist code snippet.

    Simply typing 'if' will bring up the option. Or, you could R-click and choose Surround With (VA), which gives a full list of snippets. This is an editable list, so you can add your own snippets.

  4. 4.Test if the switch is pressed, as the if( ){...}else{...} condition, turn the LED ON if pressed and OFF if not. main.c should now look as follows:
    #include<avr/io.h>
    
    int main(void)
    {
        PORTB.DIRSET   = PIN4_bm;          /* Configure LED Pin as output */
        PORTB.PIN5CTRL = PORT_PULLUPEN_bm; /* Enable pull-up for SW0 pin  */
    
        while(1)
        {
            if (!(PORTB.IN & PIN5_bm)) /* Check switch state */
            {
                PORTB.OUTCLR = PIN4_bm; /* Turn LED off */
            }
            else
            {
                PORTB.OUTSET = PIN4_bm; /* Turn LED on  */
            }
        }
    }
    
  5. 5.Verify that LED0 lights up when pushing SW0. Run the code by clicking Start Without Debugging (Ctrl+Alt+F5), to verify that LED0 lights up when pushing SW0 on the ATtiny817 Xplained Pro kit.

    Now that the basic functionality is in place, let's refactor the code to make it more readable.

  6. 6.Create functions LED_on( ) and LED_off( ) using Refactor → Extract Method The line of code to turn the LED ON is executed when SW0 is pressed. Highlight this line of code, right-click and go to it, as indicated in the figure below.
    Figure 2. Extract Method
    A Extract Method dialog will appear. Name the function 'LED_on', as indicated in the following figure.
    Figure 3. Extract Method Dialog
    Click OK, and the code should change. A new function called LED_on() should appear at the top of the file, with a function call where the line of code used to be. Use the same method to implement LED_off().
  7. 7.Create a variable for SW0 state, using Refactor → Introduce Variable. Next, it is necessary to create a variable for the SW0 state. Highlight the condition inside the if() in the main() while(1) loop. Right-click and go to it, as indicated in the figure below.
    Figure 4. Introduce Variable
    The Introduce Variable dialog will appear, as depicted in Figure 5. Name the variable 'uint8_t SW0_state'.
    Figure 5. Introduce Variable Dialog
    Tip: Change the automatically generated bool return value to uint8_t to avoid having to include an extra header to deal with Boolean values.
    Click OK and the code should change. The condition inside the if() statement should now reference a variable assigned to the variable on the line above it, as shown in the code block below.
        while (1) 
        {
        uint8_t SW0_state = !(PORTB.IN & PIN5_bm);
    		if (SW0_state)
    		{
    			LED_on();
    		}
    		else
    		{
    			LED_off();	
    		}
        }
  8. 8.Create a function SW_get_state, using Refactor → Extract Method. Select the right side of the SW0_state assignment and extract a method for SW_get_state.
  9. 9.Implement a function void LED_set_state(uint8_t state). Extract the method. Atmel Studio will detect the argument SW0_state, as indicated in Figure 6.
    Figure 6. Extract Method with Argument
    Click OK and the code should change. Now, there is a separate method for setting the LED state.
  10. 10.In function void LED_set_state(uint8_t state) rename SW0_state to state using Refactor → Rename. In a larger application, this function may be used for setting the LED state in a context that is irrelevant to the SW0 state. Atmel Studio is capable of contextual renaming, so this feature can be used to easily rename the argument and avoid confusion. Inside the LED_set_state() function, right-click on the SW0_state variable and go to Refactor → Rename, as indicated in Figure 7.
    Figure 7. Contextual Rename
    The Rename dialog will appear, as depicted in Figure 8. Rename the SW0_state variable to 'state'. Atmel Studio will detect all occurrences of the variable with the same context as the one which has been selected, and which are presented in a list and able to be individually selected or deselected.
    Figure 8. Contextual Renaming Dialog
    Click Rename and the code should change. Observe that the argument of LED_set_state() and all of its references inside the function have been renamed, but the references to SW0_state in main() have remained the same.
  11. 11.Create function definitions, moving created functions below main().

    main.c should now look as follows:

    #include <avr/io.h>
    
    void LED_on(void);
    void LED_off(void);
    void LED_set_state(uint8_t state);
    uint8_t SW_get_state(void);
    
    
    int main(void)
    {
    	PORTB.DIRSET   = PIN4_bm;          /* Configure LED Pin as output */
    	PORTB.PIN5CTRL = PORT_PULLUPEN_bm; /* Enable pull-up for SW0 pin  */
    
    	while(1)
    	{
    		uint8_t SW0_state = SW_get_state(); /* Read switch state */
    		LED_set_state(SW0_state);           /* Set LED state     */
    	}
    }
    
    uint8_t SW_get_state(void)
    {
    	return !(PORTB.IN & PIN5_bm); /* Read switch state */
    }
    
    void LED_off(void)
    {
    	PORTB.OUTSET = PIN4_bm; /* Turn LED off  */
    }
    
    void LED_on(void)
    {
    	PORTB.OUTCLR = PIN4_bm; /* Turn LED on */
    }
    
    void LED_set_state(uint8_t state)
    {
    	if (state)
    	{
    		LED_on();
    	}
    	else
    	{
    		LED_off();
    	}
    }