2020/12/23現在．MACでのAVR開発

## 概要
AVRマイコン(Arduinoなどに積まれているマイコン)をMACで開発するための手順をまとめました．

## インストールするもの
* ~~Cross Pack for AVR :https://www.obdev.at/products/crosspack/index.html~~
<br>以前はこれで，makefileの生成，コンパイルなどいろいろできたが，MACOSのバージョンアップでコンパイラのバージョンが合わなくなり，使えなくなった．現状更新は止まっている模様．
* Arduino
<br>MACベージョンアップにより，Cross Pack for AVRのコンパイラが利用できなくなったため，Arduino内のコンパイラを利用する．<a href="https://bytes.usc.edu/ee109/macos-64-bit-toolchain/">[1]</a>
* avrdude
<br>マイコンにプログラムを書き込むためのもの．brewで公開されている．<a href="https://formulae.brew.sh/formula/avrdude">[2]</a>

## 手順
**1. Arduinoをインストール**
<a href="https://www.arduino.cc/">最新版のArduino</a>をインストール．
**2. コンパイラ類のパスを見つける**
以下のパスに，Arduinoが利用するコンパイラ類が配置されている．

```bash
/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin
```
**3. AVR Toolchainへのシンボリックリンクを/usr/localに作成**

```bash
cd /usr/local
sudo ln -s /Applications/Arduino.app/Contents/Java/hardware/tools/avr avr
```

**4. パスを通す**

```bash
export PATH=/usr/local/bin:/usr/local/avr/bin:$PATH
```
**5. avrdudeのインストール**

```bash
brew install avrdude
```
## 使い方
以下のmakefileをコピー

```shell
# Name: Makefile
# Author: <insert your name here>
# Copyright: <insert your copyright message here>
# License: <insert your license reference here>

# This is a prototype Makefile. Modify it according to your needs.
# You should at least check the settings for
# DEVICE ....... The AVR device you compile for
# CLOCK ........ Target AVR clock rate in Hertz
# OBJECTS ...... The object files created from your source files. This list is
#                usually the same as the list of source files with suffix ".o".
# PROGRAMMER ... Options to avrdude which define the hardware you use for
#                uploading to the AVR and the interface where this hardware
#                is connected. We recommend that you leave it undefined and
#                add settings like this to your ~/.avrduderc file:
#                   default_programmer = "stk500v2"
#                   default_serial = "avrdoper"
# FUSES ........ Parameters for avrdude to flash the fuses appropriately.

DEVICE     = atmega328p
CLOCK      = 8000000
PROGRAMMER = -c avrispmkII -P usb #usbasp
OBJECTS    = main.o Timer1.cpp Servo.cpp
FUSES      = -U hfuse:w:0xd9:m -U lfuse:w:0xd2:m -U efuse:w:0xff:m 

# ATMega8 fuse bits used above (fuse bits for other devices are different!):
# Example for 8 MHz internal oscillator
# Fuse high byte:
# 0xd9 = 1 1 0 1   1 0 0 1 <-- BOOTRST (boot reset vector at 0x0000)
#        ^ ^ ^ ^   ^ ^ ^------ BOOTSZ0
#        | | | |   | +-------- BOOTSZ1
#        | | | |   +---------- EESAVE (set to 0 to preserve EEPROM over chip erase)
#        | | | +-------------- CKOPT (clock option, depends on oscillator type)
#        | | +---------------- SPIEN (if set to 1, serial programming is disabled)
#        | +------------------ WDTON (if set to 0, watchdog is always on)
#        +-------------------- RSTDISBL (if set to 0, RESET pin is disabled)
# Fuse low byte:
# 0x24 = 0 0 1 0   0 1 0 0
#        ^ ^ \ /   \--+--/
#        | |  |       +------- CKSEL 3..0 (8M internal RC)
#        | |  +--------------- SUT 1..0 (slowly rising power)
#        | +------------------ BODEN (if 0, brown-out detector is enabled)
#        +-------------------- BODLEVEL (if 0: 4V, if 1: 2.7V)
#
# For computing fuse byte values for other devices and options see
# the fuse bit calculator at http://www.engbedded.com/fusecalc/

# ATTINY2313の場合
# Fuse high byte:
# 0xd9 = 1 1 0 1   1 0 0 1 <-- RSTDISBL PA2がIOピンか(0)、RESET設定か(1)
#        ^ ^ ^ ^   ^ ^ ^------ BODLEVEL1
#        | | | |   | +-------- BODLEVEL2 >> 100:4.3Vリセット
#        | | | |   +---------- BODLEVEL3
#        | | | +-------------- WDTON ウオッチドッグ有効(0使用する、1:使用しない)
#        | | +---------------- SPIEN (if set to 1, serial programming is disabled)
#        | +------------------ EESAVE チップ消去からEEPROM内容保護(0:保護、1:未保護)
#        +-------------------- DWNEN デバッグWIRE機能許可(0:有効、1:無効)
# Fuse low byte:
# 0xA4 = 1 0 1 0   0 1 0 0
#        ^ ^ \ /   \--+--/
#        | |  |       +------- CKSEL 3..0 (8M internal RC)
#        | |  +--------------- SUT 1..0 (slowly rising power)
#        | +------------------ BODEN (if 0, brown-out detector is enabled)
#        +-------------------- CKDIV8 システム クロック 8分周選択。　0:8分周 1:分周なし


# Tune the lines below only if you know what you are doing:
AVRDUDE = avrdude $(PROGRAMMER) -p $(DEVICE)
COMPILE = avr-g++ $(INCLUDES) -Wall -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE) 

# test:
# 	echo $(COMPILE)

# symbolic targets:
all:	main.hex

.c.o:
	$(COMPILE) -c $< -o $@ 

.S.o:
	$(COMPILE) -x assembler-with-cpp -c $< -o $@
# "-x assembler-with-cpp" should not be necessary since this is the default
# file type for the .S (with capital S) extension. However, upper case
# characters are not always preserved on Windows. To ensure WinAVR
# compatibility define the file type manually.

.c.s:
	$(COMPILE) -S $< -o $@

flash:	all
	$(AVRDUDE) -U flash:w:main.hex:i

fuse:
	$(AVRDUDE) $(FUSES)

# Xcode uses the Makefile targets "", "clean" and "install"
install: flash fuse

# if you use a bootloader, change the command below appropriately:
load: all
	bootloadHID main.hex
clean:
	rm -f main.hex main.elf $(OBJECTS)

# file targets:
main.elf: $(OBJECTS)
	$(COMPILE) -o main.elf $(OBJECTS) $(LIBINCLUDES)
	rm *.o

main.hex: main.elf
	rm -f main.hex
	avr-objcopy -j .text -j .data -O ihex main.elf main.hex
	avr-size --format=avr --mcu=$(DEVICE) main.elf
# If you have an EEPROM section, you must also create a hex file for the
# EEPROM and add it to the "flash" target.

# Targets for code debugging and analysis:
disasm:	main.elf
	avr-objdump -d main.elf

cpp:
	$(COMPILE) -E main.c
```
**4. makefileの編集**
makefileの以下の部分は，利用するマイコン，ライタに応じて書き換える必要がある．

```shell
DEVICE     = atmega328p # 利用するマイコン
CLOCK      = 8000000    # CPUのクロック
PROGRAMMER = -c avrispmkII -P usb  # 利用するライタ
OBJECTS    = main.o                # コンパイルするプログラム 
FUSES      = -U hfuse:w:0xd9:m -U lfuse:w:0xd2:m -U efuse:w:0xff:m # マイコンのヒューズビット
```
詳細については，<a href="https://synapse.kyoto/tips/ArduinoISP_AVRWriter/page002.html">[3]</A>で詳しく解説されている．

**5.プログラムの作成**
LEDを点滅させるプログラムを載せておきます．

```C++
#include <avr/io.h>
#include <util/delay.h>

#define TRUE 1
#define FALSE 0
#define NULL '\0'

// ビットをオンオフするマクロ
#define SBI(reg,bit) reg |= (1 << bit)
#define CBI(reg,bit) reg &= ~(1 << bit)

int main() {
    int T=1000;
    SBI(DDRB,DDB0);
    while(1){
      SBI(PORTB,DDB0);
      _delay_ms(T);
      CBI(PORTB,DDB0);
      _delay_ms(T);
    }

    return 0;
}
```
**6.コンパイル＋マイコンへの書き込み**

```bash
make # プログラムをコンパイル
make fuse #ヒューズ設定をマイコンに書き込み
make flash # コンパイル済みのプログラムをマイコンに書き込み．
```

## 備考
手順３のmakefileは，Cross Pack For AVRによって生成したもの．しかし，インストールする必要はない．



## 参考
1. https://bytes.usc.edu/ee109/macos-64-bit-toolchain/
2. https://formulae.brew.sh/formula/avrdude
3. https://synapse.kyoto/tips/ArduinoISP_AVRWriter/page002.html