9. Embedded programming

Step 1 : group assignment

We used several workflows to get our board programmed, let’s compare them!

Languages:

programming in c seems to be clearly the easy way here. However, it still remain very general, and allows to keep a good control and what you want your chip to do!

Programming environment, compiler, and programmer:

Using avrdude is very efficient and was a good solution, but you need Linux. WinAVR is similar but only works on windows 7. If you want to program using windows (without becoming crazy), using commercial solutions will be required… It has the drawback to be commercial, but depending on the solution, you will have more possibilities in term of debugging and reading the chip than avrdude or winAVR!

Step 2 : reading a datasheet

Let’s read the datasheet

pin out

This is the picture of a attyni 44 but we used a attny84 it is the same

this is de schematic of my board

Here you can see the code of the makefile after i changed some values

ROJECT=Blinkled
SOURCES=$(PROJECT).c
MMCU=attiny84
F_CPU = 20000000

CFLAGS=-mmcu=$(MMCU) -Wall -Os -DF_CPU=$(F_CPU)

$(PROJECT).hex: $(PROJECT).out
    avr-objcopy -O ihex $(PROJECT).out $(PROJECT).c.hex;\
    avr-size --mcu=$(MMCU) --format=avr $(PROJECT).out

$(PROJECT).out: $(SOURCES)
    avr-gcc $(CFLAGS) -I./ -o $(PROJECT).out $(SOURCES)

program-bsd: $(PROJECT).hex
    avrdude -p t84 -c bsd -U flash:w:$(PROJECT).c.hex

program-dasa: $(PROJECT).hex
    avrdude -p t84 -P /dev/ttyUSB0 -c dasa -U flash:w:$(PROJECT).c.hex

program-avrisp2: $(PROJECT).hex
    avrdude -p t84 -P usb -c avrisp2 -U flash:w:$(PROJECT).c.hex

program-avrisp2-fuses: $(PROJECT).hex
    avrdude -p t84 -P usb -c avrisp2 -U lfuse:w:0x5E:m

program-usbtiny: $(PROJECT).hex
    avrdude -p t84 -P usb -c usbtiny -U flash:w:$(PROJECT).c.hex

program-usbtiny-fuses: $(PROJECT).hex
    avrdude -p t84 -P usb -c usbtiny -U lfuse:w:0x5E:m

program-dragon: $(PROJECT).hex
    avrdude -p t84 -P usb -c dragon_isp -U flash:w:$(PROJECT).c.hex

program-ice: $(PROJECT).hex
    avrdude -p t84 -P usb -c atmelice_isp -U flash:w:$(PROJECT).c.hex

After that i changed the file Blikled.c

and change the message in main loop

// Blinkled.c
 //
 // 115200 baud messages on button press + led blinking
 //
 // set lfuse to 0x5E for 20 MHz xtal
 //
 // Ch_R
 // 2019-03-19
 //
 // Based on Neil Gershenfeld's  hello.ftdi.44.echo.interrupt.c
 //
 // (c) Massachusetts Institute of Technology 2010
 // This work may be reproduced, modified, distributed,
 // performed, and displayed for any purpose. Copyright is
 // retained and must be preserved. The work is provided
 // as is; no warranty is provided, and users accept all
 // liability.
 //

 #include <avr/io.h>
 #include <util/delay.h>
 #include <avr/pgmspace.h>

 #define output(directions,pin) (directions |= pin) // set port direction for output
 #define input(directions,pin) (directions &= (~pin)) //set port direction for input
 #define set(port,pin) (port |= pin) // set port pin
 #define clear(port,pin) (port &= (~pin)) // clear port pin
 #define toggle(port,pin) (port ^= pin) // toggle port pin
 #define pin_test(pins,pin) (pins & pin) // test for port pin
 #define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set
 #define bit_delay_time 8.25 // bit delay for 115200 with overhead
 #define bit_delay() _delay_us(bit_delay_time) // RS232 bit delay
 #define half_bit_delay() _delay_us(bit_delay_time/2) // RS232 half bit delay
 #define char_delay() _delay_ms(10) // char delay

//Pins definitions
 #define serial_port PORTA
 #define serial_direction DDRA
 #define serial_pins PINA
 #define serial_pin_in (1 << PA0)
 #define serial_pin_out (1 << PA1)
 #define led_port PORTA
 #define led_direction DDRA
 #define led_pins PINA
 #define led_pin (1 << PA2)
 #define led PA2
 #define button_port PORTB
 #define button_direction DDRB
 #define button_pins PINB
 #define button_pin (1 << PB2)
 #define button PB2
//end Pins Definitions

 void put_char(volatile unsigned char *port, unsigned char pin, char txchar) {
    //
    // send character in txchar on port pin
    //    assumes line driver (inverts bits)
    //
    // start bit
    //
    clear(*port,pin);
    bit_delay();
    //
    // unrolled loop to write data bits
    //
    if bit_test(txchar,0)
       set(*port,pin);
    else
       clear(*port,pin);
    bit_delay();
    if bit_test(txchar,1)
       set(*port,pin);
    else
       clear(*port,pin);
    bit_delay();
    if bit_test(txchar,2)
       set(*port,pin);
    else
       clear(*port,pin);
    bit_delay();
    if bit_test(txchar,3)
       set(*port,pin);
    else
       clear(*port,pin);
    bit_delay();
    if bit_test(txchar,4)
       set(*port,pin);
    else
       clear(*port,pin);
    bit_delay();
    if bit_test(txchar,5)
       set(*port,pin);
    else
       clear(*port,pin);
    bit_delay();
    if bit_test(txchar,6)
       set(*port,pin);
    else
       clear(*port,pin);
    bit_delay();
    if bit_test(txchar,7)
       set(*port,pin);
    else
       clear(*port,pin);
    bit_delay();
    //
    // stop bit
    //
    set(*port,pin);
    bit_delay();
    }

 void put_string(volatile unsigned char *port, unsigned char pin, char *str) {
    //
    // print a null-terminated string
    //
    static int index;
    index = 0;
    do {
       put_char(port, pin, str[index]);
       ++index;
       } while (str[index] != 0);
    }


 int main(void) {
    //
    // main function
    //

    unsigned char was_active = 0; //unsigned char used as boolean

    // set clock divider to /1
    //
    CLKPR = (1 << CLKPCE);
    CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);

    //
    // initialize output pins
    // (pins are input by default)
    //
    set(serial_port, serial_pin_out);
    output(serial_direction, serial_pin_out);

    set(led_port, led_pin);
    output(led_direction, led_pin);


    //
    // main loop
    //
    while (1) { //loop forever (1 is equivalent to "true")
       if bit_test(button_pins, button){     //test wether the button is pressed : if not... (level it then high)
         clear(led_port, led_pin);         //if not, light the led off
           if(was_active){                   //if it was pressed during the last loop, put an "exit message"
                 put_string(&serial_port, serial_pin_out, "Ho no, you realesed me");
                 put_char(&serial_port, serial_pin_out, 10); // new line
                 was_active=0; //disable the was_active flag
           }
       }
       else{       //if the button was pressed
            toggle(led_port, led_pin);      //change the led status to blink it
            put_string(&serial_port, serial_pin_out, "You pressed me , Youhouuuuuuu");
            put_char(&serial_port, serial_pin_out, 10); // new line
            _delay_ms(200) ; //wait a bit before going to the next loop (blinking visibily AND button debouncing)
             was_active=1 ;    //change the was_active flag so that an exit message will be send on button release
       }
    }
 }

now it is time to make the .hex file

Like i did in the week07

that the fuse of the file

and thats the flash of the file

and here you can see my board is responding when i push the button

original files

thanks to Gilles Decroly he helped me a lot to understand the code