owned this note
owned this note
Published
Linked with GitHub
---
title:
description: Neil's code, C
Autors: Santi Fuentemilla, oscar
slideOptions:
theme: white
transition: 'fade'
# parallaxBackgroundImage: 'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg'
# Display a presentation progress bar
progress: true
---
###### tags: `FabAcademy` `FLU` `Future Learning Unit` `Fab Lab Barcelona` `MDEF`
[TOC]
INDEX:
- C, codigo C de neil
- Que es un Bootloader
- Registers
- TIPOS de memoria
- SRAM
- DRAM
- EEPROM
- fuse, que son?
- Debugging?
# Neil's code, C
![](https://i.imgur.com/yER4bsD.gif)
## Attiny 44
Attiny 44A is microcontroller from AVR family. Attiny 44A comes in dual in line 14 pin SMD package. Attiny does have High-performance, low-power Microchip AVR RISC-based CMOS 8-bit microcontroller combines 4KB ISP flash memory, 256-Byte EEPROM, 256B SRAM, 12 general purpose I/O lines, 32 general purpose working registers, an 8-bit timer/counter with two PWM channels, a 16-bit timer/counter with two PWM channels, internal and external interrupts, an 8-channel 10-bit A/D converter, a programmable gain stage (1x, 20x) for 12 differential ADC channel pairs, programmable watchdog timer with internal oscillator, a internal calibrated oscillator, and three software selectable power saving modes. By executing powerful instructions in a single clock cycle, the device achieves throughputs approaching 1 MIPS per MHz, balancing power consumption and processing speed.
## Memory
The AVR Architecture has two main memory spaces, the Data memory and Program memory. In addition, the ATtiny44 features an EEPROM Memory for data storage.
Data Memory (Static and Dynamic RAM)
**SRAM** memory is used for storing your data which is processed during the run time (including also the registers) volatile memory
**FLASH** memory which your program (sketch) stored - non volatile. Endurance: 10,000 Write/Erase Cycles .
**EEPROM** memory which can be used for storing non volatile data and changeable during run-time. (for example: setting values, wi-fi information) Endurance: 100,000 Write/Erase Cycles
So in a nutshell we have:
* 2K/4K byte of In-System Programmable Flash
* 128/256 bytes EEPROM, 128/256 bytes SRAM, 12 general purpose I/O lines
* 32 general purpose working registers
* An 8-bit timer/counter with two PWM channels
* A 16-bit timer/counter with two PWM channels
* Internal and External Interrupts, a 8-channel 10-bit ADC, programmable gain stage (1x, 20x) for 12 differential ADC channel pairs, a programmable Watchdog Timer with internal oscillator, internal calibrated oscillator, and four software selectable power saving modes.
### What is a memory map?
The memory map of a microcontroller is a diagram which gives the size, type and layout of the memories that are available in the microcontroller. The information use to construct the memory map is extracted from the datasheet of the microcontroller.
![](https://i.imgur.com/BTI5cC3.png)
### Bootloader
The bootloader is a software hosted in the flash memory that allows us to program your board through the serial port without the need to use an external programmer.
:::info
[Memories in a microcontroller](https://hackmd.io/PsZlUri7TTqB3i55c_c04Q#Understanding-microcontrollers)
:::
## Registers
In embedded c we need handle the registers.Each of the AVR Digital I/O ports is associated with three (3) I/O register. A Data Direction Register (DDRx), A Pin Register (PINx) and a Port Register (PORTx). Where x is the port A, B, C, etc.
![](https://i.imgur.com/jEVFhh2.jpg)
* **DDRxn** register configures pins as INPUT (0) or OUTPUT (1).
* **PINxn** register stores a value that can be read from the register in case it is defined as INPUT on the DDRxn level.
* **PORTxn** register is there to write value to pins. HIGH (1) or LOW (0) are possible values.
* If the pin n is defined as INPUT on the DDRxn level, the PORTxn value is going to define the usage of the PULLUP (1) or PULLDOWN (0) resistor.
* Here n stands for the number of the pin.
The following is how you can define values for registers. You can pass a byte to configure 8 registers at the same time. Arduino code.
## Understanding Clock Speed and Time
http://fab.cba.mit.edu/classes/863.15/doc/tutorials/programming/clock.html
Looking at the ATTiny44(a) data sheet, we want to consider the CLock Prescale Register (CLKPR, 1byte):
* Bit 7 – CLKPCE (CLocK Prescaler Change Enable)
* Bit 6:4 – unused
* Bit 3:1 – CLKPS[3:0] (CLocK Prescaler Select)
* CLKPS[3:0] gets initialized by default to 0011 (which is the value for 8 – note that this is not a binary to hex conversion) from the CKDIV8 LFuse, which by default is set to CKDIV8 (CLocK DIVision 8).
By default, the 8MHz Internal RC Oscillator is selected as clock source from the CKSEL[3:0] LFuse (see my Understanding Fuses).
The clock speed therefore is 1Mhz, i.e. if we tell the compiler in the Makefile with F_CPU = 8000000 that the chip runs at 8MHz, everything will be executed 8x slower than we expect. This is the explanation if delay_ms(double) seems ~10x slower against wall-clock time.
If we want to run at the full 8MHz and not mess with the LFuse, we simply set CLKPR to divide by 1 in code:
CLKPR = (1 << CLKPCE);
CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
If we want to run at the default 1MHz, we must make sure that we don’t pass anything to the compiler that would override the #define F_CPU 1000000UL from delay.h.
## Understanding Fuses
http://fab.cba.mit.edu/classes/863.15/doc/tutorials/programming/fuses.html
http://www.engbedded.com/fusecalc/
Let’s configure our example board’s ATTiny44(a) microcontroller to use the external 20MHz ceramic resonator. Looking at the chip’s data sheet, we want to consider the LFuse (Lower Fuse, 1byte, [t44 default=0x62 although iotn44a.h falsely states 0x6a]):
* Bit 7 – CKDIV8 (CLocK DIVision 8; see my Understanding Clock Speed and Time)
* Bit 6 – CKOUT (ClocK OUTput Enable)
* Bit 5:4 – SUT[1:0] ([Select] Start-Up Time)
* Bit 3:0 – CKSEL[3:0] (CLocK [source] SELection)
> Note that for fuse bits – oddly enough – 1=unprogrammed and 0=programmed. For fuse calculator checkboxes this translates to 1=unchecked and 0=checked.
Current fuse settings of a chip can be read out to a file with avrdude:
**$ avrdude -p t44 -P usb -c usbtiny -U lfuse:r:outfile:h**
In Table 6-1 Device Clocking Options we see that we need to program CKSEL[3:0] to set our clock source. There’s “External Clock” (0000) but in Figure 6-2 External Clock Drive Configuration we see that would mean solely driving pin 2 (CLKI) with an external clock. What we’re doing instead on our board is what we see in Figure 6-3 Crystal Oscillator Connections: we drive pin 2 (XTAL1) and pin 3 (XTAL2) with the resonator’s input and output respectively (note that on our board we skip C1-2 suggested in this figure – maybe due to the component we’re using).
Back In Table 6-1 we find the appropriate option “Crystal Oscillator/Ceramic Resonator” (1000-1111). Since we’re using a 20MHz resonator we find in Table 6-9 Crystal Oscillator Operating Modes that for ≥8MHz we should use CKSEL[3:1]=111. We further read that for this configuration CHSEL0 together with SUT[1:0] selects start-up times of the chip.
For the higher 4 LFuse bits the default is 0x6. For our purpose we can leave Bit 7 and 6 at their default values (CKDIV8=0 and CKOUT=1) and solely consider Bit 5 and 4, which is SUT[1:0] defaulting to 10. In Table 6-10 Start-up Times for the Crystal Oscillator Clock Selection we find that for resonators 10 should be used when the Brown-out Detector (BOD) is enabled. However, since this is disabled by default and only enabled in the HFuse through BODLEVEL[2:0], we need to change this default value. We choose CHKSEL0=0 and SUT[1:0]=01 for option “Ceramic resonator, slowly rising power”, adding “an extra power-on delay for everything to settle down, which is a safer choice” (compared to “fast rising”), according to Neil Gershenfeld. Although it’s mentioned in the data sheet that this option “should only be used when not operating close to the maximum frequency”, it has been tested and works well in our context.
Combined, this results in LFuse=0x5E (01011110). Be careful when experimenting with fuses as I bricked one of my boards. There seem to be ways to reset the fuses to factory settings, e.g. through the High Voltage Serial Programming (HVSP) interface, but usually replacing the chip is a cheaper and quicker method.
:::info
[AVR Fuses tool](https://github.com/vonnieda/AVRFuses)
:::
## C Operators
https://www.tutorialspoint.com/cprogramming/c_operators.htm
## C code's examples
#### Blinking the Hello Board in C
```
#define led_port PORTA
#define led_direction DDRA
// #define led_pin 0b1000000
#define led_pin (1 << PA7)
#define serial_pins PINA
#define button_port PORTA
#define button_direction DDRA
#define button_pin (1 << PA3)
// initialize LED pin
//
clear(led_port, led_pin);
output(led_direction, led_pin);
input(button_direction,button_pin);
//
// main loop
//
while (1) {
if(pin_test(serial_pins,button_pin)){
set(led_port, led_pin);
led_delay();
} else {
clear(led_port, led_pin);
led_delay();
}
}
}
```
## References
* https://en.wikipedia.org/wiki/Bit_field
* http://fab.academany.org/2018/labs/barcelona/students/nicolo-gnecchi/embedded-programming/
* http://fab.cba.mit.edu/classes/863.16/section.Harvard/people/Glen/wk07.html
* http://archive.fabacademy.org/2018/labs/fablabkochi/students/salman-faris/week9.html
* http://fab.academany.org/2018/labs/barcelona/students/oscar-gonzalezfernandez//2018/03/19/Week-08-Embedded-programming.html
* http://fab.academany.org/2018/labs/barcelona/students/krisjanis-rijnieks/assignments/week09/
* http://fab.academany.org/2018/labs/fablabkochi/students/suhail-p/week9.html
#### Fuses
* [What are fuses ? (Spanish)](https://vidaembebida.wordpress.com/2017/01/14/avr-fusibles-de-los-microcontroladores-avr/)
#### From C to Arduino:
* https://balau82.wordpress.com/2011/03/29/programming-arduino-uno-in-pure-c/
* https://www.instructables.com/id/Honey-I-Shrunk-the-Arduino-Moving-from-Arduino-t/