├── AT15007.pdf ├── README.md ├── hardware.zip ├── hardware ├── atmega328pb │ └── avr │ │ ├── boards.txt │ │ ├── bootloaders │ │ └── optiboot_m328pb.hex │ │ ├── libraries │ │ ├── SPI │ │ │ ├── examples │ │ │ │ ├── BarometricPressureSensor │ │ │ │ │ └── BarometricPressureSensor.ino │ │ │ │ ├── DigitalPotControl │ │ │ │ │ └── DigitalPotControl.ino │ │ │ │ └── dual_digipot │ │ │ │ │ └── dual_digipot.ino │ │ │ ├── keywords.txt │ │ │ ├── library.properties │ │ │ └── src │ │ │ │ ├── SPI.cpp │ │ │ │ └── SPI.h │ │ ├── SPI1 │ │ │ ├── keywords.txt │ │ │ ├── library.properties │ │ │ └── src │ │ │ │ ├── SPI1.cpp │ │ │ │ └── SPI1.h │ │ ├── Wire │ │ │ ├── examples │ │ │ │ ├── SFRRanger_reader │ │ │ │ │ └── SFRRanger_reader.ino │ │ │ │ ├── digital_potentiometer │ │ │ │ │ └── digital_potentiometer.ino │ │ │ │ ├── dual_digipot │ │ │ │ │ └── dual_digipot.ino │ │ │ │ ├── master_reader │ │ │ │ │ └── master_reader.ino │ │ │ │ ├── master_writer │ │ │ │ │ └── master_writer.ino │ │ │ │ ├── slave_receiver │ │ │ │ │ └── slave_receiver.ino │ │ │ │ └── slave_sender │ │ │ │ │ └── slave_sender.ino │ │ │ ├── keywords.txt │ │ │ ├── library.properties │ │ │ └── src │ │ │ │ ├── Wire.cpp │ │ │ │ ├── Wire.h │ │ │ │ └── utility │ │ │ │ ├── twi.c │ │ │ │ └── twi.h │ │ └── Wire1 │ │ │ ├── keywords.txt │ │ │ ├── library.properties │ │ │ └── src │ │ │ ├── Wire1.cpp │ │ │ ├── Wire1.h │ │ │ └── utility │ │ │ ├── twi1.c │ │ │ └── twi1.h │ │ ├── platform.txt │ │ ├── programmers.txt │ │ ├── tools │ │ └── avrdude.conf │ │ └── variants │ │ └── atmega328pb │ │ └── pins_arduino.h └── tools │ └── avr │ ├── avr │ ├── include │ │ └── avr │ │ │ ├── io.h │ │ │ └── iom328pb.h │ └── lib │ │ └── avr5 │ │ ├── crtatmega328pb.o │ │ └── libatmega328pb.a │ └── lib │ └── gcc │ └── avr │ └── 4.9.2 │ └── device-specs │ └── specs-atmega328pb ├── m328pb.zip └── package_m328pb_index.json /AT15007.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/watterott/ATmega328PB-Testing/7d0e4eb5af631da8dc3e7aa47ac6e67a598fe499/AT15007.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ATmega328PB Testing 2 | 3 | 4 | ## Hardware 5 | * [Wattuino Pro Mini PB 5V 16MHz (with ATmega328PB)](https://shop.watterott.com/Wattuino-Pro-Mini-PB-5V-16MHz-ATmega328PB_1) 6 | * [Wattuino Pro Mini PB 3.3V 8MHz (with ATmega328PB)](https://shop.watterott.com/Wattuino-Pro-Mini-PB-33V-8MHz-ATmega328PB_1) 7 | 8 | 9 | ## Software 10 | 11 | ### Installation on Arduino IDE 1.8+ 12 | 13 | 1. Add the following URL to the Arduino Boards Manager (*File->Preferences*). 14 | ``` 15 | https://github.com/watterott/ATmega328PB-Testing/raw/master/package_m328pb_index.json 16 | ``` 17 | 18 | 2. Update the **Arduino AVR Boards** to version **1.6.22** or higher via the Boards Manager (*Tools->Boards->Boards Manager*). 19 | 20 | 3. Install the **ATmega328PB Boards** via the Boards Manager (*Tools->Boards->Boards Manager*). 21 | 22 | 23 | ## Further Infos 24 | * [Arduino AVR-GCC Toolchain with Atmega328PB support](https://github.com/arduino/toolchain-avr/pull/47) 25 | * [Differences between ATmega328/P and ATmega328PB](http://ww1.microchip.com/downloads/en/AppNotes/Atmel-42559-Differences-between-ATmega328P-and-ATmega328PB_ApplicationNote_AT15007.pdf) 26 | * [Another project/guide for the ATmega328PB](https://hackaday.io/project/9313-uino-mini-super-atmega328pb) 27 | * [ATmega328PB Discussion in the Italian Arduino Forum](http://forum.arduino.cc/index.php?topic=374642.0) 28 | * [Optiboot for ATmega328PB](https://github.com/watterott/Wattuino/tree/master/software/Optiboot#optiboot) 29 | 30 | 31 | ## Known Issues 32 | 33 | ### Timer 3+4 Output Compare 34 | The output compare will only work if a 1 or 0 is written to the port register depending on the modulation. 35 | Futher infos here: http://www.avrfreaks.net/comment/1717946#comment-1717946 and https://github.com/watterott/ATmega328PB-Testing/issues/29 36 | 37 | ### Reset 38 | ATmega328P and ATmega328PB have different thresholds for reset. 39 | This can be a problem when using a 5V power supply for the microcontroller and an USB serial adapter with 3.3V logic level on DTR. 40 | * Reset Input Threshold Voltage (read as 0/low): 41 | * ATmega328P: 2.1V @ Vcc=5V 42 | * ATmega328PB: 1.6V @ Vcc=5V 43 | 44 | ### Crystal Oscillator 45 | The ATmega328PB has no full-swing option for the oscillator. 46 | 47 | 48 | ## History / Contributions 49 | * Patch v1.0.1 - Astrobeed, gpb01, PaoloP 50 | * avr-gcc 4.9.2 for linux64 - sabas1080 51 | * [All Pull Requests...](https://github.com/watterott/ATmega328PB-Testing/pulls?q=) 52 | -------------------------------------------------------------------------------- /hardware.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/watterott/ATmega328PB-Testing/7d0e4eb5af631da8dc3e7aa47ac6e67a598fe499/hardware.zip -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/boards.txt: -------------------------------------------------------------------------------- 1 | 2 | menu.speed=Speed 3 | 4 | atmega328pbcc.name=ATmega328PB Crystal Clock 5 | atmega328pbcc.bootloader.file=optiboot_m328pb.hex 6 | atmega328pbcc.bootloader.unlock_bits=0xFF 7 | atmega328pbcc.bootloader.lock_bits=0xCF 8 | atmega328pbcc.bootloader.low_fuses=0xFF 9 | atmega328pbcc.bootloader.high_fuses=0xD6 10 | atmega328pbcc.bootloader.extended_fuses=0xFD 11 | atmega328pbcc.bootloader.tool=avrdude 12 | atmega328pbcc.upload.tool=avrdude 13 | atmega328pbcc.upload.protocol=arduino 14 | atmega328pbcc.upload.maximum_size=32256 15 | atmega328pbcc.upload.maximum_data_size=2048 16 | atmega328pbcc.upload.speed=57600 17 | atmega328pbcc.build.mcu=atmega328pb 18 | atmega328pbcc.build.board=AVR_UNO 19 | atmega328pbcc.build.core=arduino:arduino 20 | atmega328pbcc.build.variant=atmega328pb 21 | atmega328pbcc.build.f_cpu=16000000L 22 | atmega328pbcc.menu.speed.16mhz=16 MHz 23 | atmega328pbcc.menu.speed.16mhz.build.f_cpu=16000000L 24 | atmega328pbcc.menu.speed.8mhz=8 MHz 25 | atmega328pbcc.menu.speed.8mhz.build.f_cpu=8000000L 26 | atmega328pbcc.menu.speed.4mhz=4 MHz 27 | atmega328pbcc.menu.speed.4mhz.build.f_cpu=4000000L 28 | atmega328pbcc.menu.speed.1mhz=1 MHz 29 | atmega328pbcc.menu.speed.1mhz.build.f_cpu=1000000L 30 | atmega328pbcc.menu.speed.20mhz=20 MHz 31 | atmega328pbcc.menu.speed.20mhz.build.f_cpu=20000000L 32 | 33 | atmega328pbec.name=ATmega328PB External Clock 34 | atmega328pbec.bootloader.file=optiboot_m328pb.hex 35 | atmega328pbec.bootloader.unlock_bits=0xFF 36 | atmega328pbec.bootloader.lock_bits=0xCF 37 | atmega328pbec.bootloader.low_fuses=0xE0 38 | atmega328pbec.bootloader.high_fuses=0xD6 39 | atmega328pbec.bootloader.extended_fuses=0xFD 40 | atmega328pbec.bootloader.tool=avrdude 41 | atmega328pbec.upload.tool=avrdude 42 | atmega328pbec.upload.protocol=arduino 43 | atmega328pbec.upload.maximum_size=32256 44 | atmega328pbec.upload.maximum_data_size=2048 45 | atmega328pbec.upload.speed=57600 46 | atmega328pbec.build.mcu=atmega328pb 47 | atmega328pbec.build.board=AVR_UNO 48 | atmega328pbec.build.core=arduino:arduino 49 | atmega328pbec.build.variant=atmega328pb 50 | atmega328pbec.build.f_cpu=16000000L 51 | atmega328pbec.menu.speed.16mhz=16 MHz 52 | atmega328pbec.menu.speed.16mhz.build.f_cpu=16000000L 53 | atmega328pbec.menu.speed.8mhz=8 MHz 54 | atmega328pbec.menu.speed.8mhz.build.f_cpu=8000000L 55 | atmega328pbec.menu.speed.4mhz=4 MHz 56 | atmega328pbec.menu.speed.4mhz.build.f_cpu=4000000L 57 | atmega328pbec.menu.speed.1mhz=1 MHz 58 | atmega328pbec.menu.speed.1mhz.build.f_cpu=1000000L 59 | atmega328pbec.menu.speed.20mhz=20 MHz 60 | atmega328pbec.menu.speed.20mhz.build.f_cpu=20000000L 61 | 62 | atmega328pbic.name=ATmega328PB Internal Clock 63 | atmega328pbic.bootloader.file=optiboot_m328pb.hex 64 | atmega328pbic.bootloader.unlock_bits=0xFF 65 | atmega328pbic.bootloader.lock_bits=0xCF 66 | atmega328pbic.bootloader.low_fuses=0xE2 67 | atmega328pbic.bootloader.high_fuses=0xD6 68 | atmega328pbic.bootloader.extended_fuses=0xFD 69 | atmega328pbic.bootloader.tool=avrdude 70 | atmega328pbic.upload.tool=avrdude 71 | atmega328pbic.upload.protocol=arduino 72 | atmega328pbic.upload.maximum_size=32256 73 | atmega328pbic.upload.maximum_data_size=2048 74 | atmega328pbic.upload.speed=57600 75 | atmega328pbic.build.mcu=atmega328pb 76 | atmega328pbic.build.board=AVR_UNO 77 | atmega328pbic.build.core=arduino:arduino 78 | atmega328pbic.build.variant=atmega328pb 79 | atmega328pbic.build.f_cpu=8 MHz 80 | atmega328pbic.menu.speed.8mhz=8 MHz 81 | atmega328pbic.menu.speed.8mhz.build.f_cpu=8000000L 82 | atmega328pbic.menu.speed.8mhz.bootloader.low_fuses=0xE2 83 | atmega328pbic.menu.speed.1mhz=1 MHz 84 | atmega328pbic.menu.speed.1mhz.build.f_cpu=1000000L 85 | atmega328pbic.menu.speed.1mhz.bootloader.low_fuses=0x62 86 | atmega328pbic.menu.speed.1mhz.upload.speed=9600 87 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/bootloaders/optiboot_m328pb.hex: -------------------------------------------------------------------------------- 1 | :107E00001F92CDB7DEB7112484B714BE982F9D7092 2 | :107E100009F0E6D082E08093C00088E18093C10041 3 | :107E200086E08093C20080E18093C4008EE0C3D0DE 4 | :107E300010928500109284004899FECF489BFECF97 5 | :107E400081E0809381004899FECF109281002091BB 6 | :107E50008400822F20918500922F089644E0969509 7 | :107E600087954A95E1F701978093C40098D08033B5 8 | :107E7000E9F7A7D0812C912C13E001E025E0F22E48 9 | :107E800031E1E32E8CD0813479F489D0898399D083 10 | :107E90008981823811F482E005C0813811F486E0CE 11 | :107EA00001C083E075D071C0823411F484E103C055 12 | :107EB000853419F485E08DD068C0853549F46FD0DC 13 | :107EC000D82E6DD08D2C912C982A880C991C5CC0D2 14 | :107ED000863521F484E07DD080E0E4CF843609F05B 15 | :107EE00036C05DD05CD0D82E5AD0C82EA12CBB2471 16 | :107EF000B39455D0F50181935F01DE12FACF61D0C2 17 | :107F0000F5E4CF1201C0FFCFF40117BFE89507B623 18 | :107F100000FCFDCFA401A0E0B1E02C911296CD01B0 19 | :107F20000197FC01808130E0382BFA01090107BF7D 20 | :107F3000E89511244E5F5F4FDA12EFCFF401F7BEE0 21 | :107F4000E89507B600FCFDCFE7BEE8951EC0843774 22 | :107F500071F425D024D0D82E22D033D05401F5018D 23 | :107F600085915F0115D0DA94D110F9CF0EC0853715 24 | :107F700039F427D08EE10CD085E90AD086E192CF82 25 | :107F8000813511F488E017D01CD080E101D07ACF80 26 | :107F90009091C00095FFFCCF8093C600089580911A 27 | :107FA000C00087FFFCCF8091C00084FD01C0A89570 28 | :107FB0008091C6000895E0E6F0E098E19083808328 29 | :107FC0000895EDDF803219F088E0F5DFFFCF84E11E 30 | :107FD000DFCFCF93C82FE3DFC150E9F7CF91F1CFC7 31 | :0C7FE000282E80E0E8DFE0E0FF27099495 32 | :0400000300007E007B 33 | :00000001FF 34 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.ino: -------------------------------------------------------------------------------- 1 | /* 2 | SCP1000 Barometric Pressure Sensor Display 3 | 4 | Shows the output of a Barometric Pressure Sensor on a 5 | Uses the SPI library. For details on the sensor, see: 6 | http://www.sparkfun.com/commerce/product_info.php?products_id=8161 7 | http://www.vti.fi/en/support/obsolete_products/pressure_sensors/ 8 | 9 | This sketch adapted from Nathan Seidle's SCP1000 example for PIC: 10 | http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip 11 | 12 | Circuit: 13 | SCP1000 sensor attached to pins 6, 7, 10 - 13: 14 | DRDY: pin 6 15 | CSB: pin 7 16 | MOSI: pin 11 17 | MISO: pin 12 18 | SCK: pin 13 19 | 20 | created 31 July 2010 21 | modified 14 August 2010 22 | by Tom Igoe 23 | */ 24 | 25 | // the sensor communicates using SPI, so include the library: 26 | #include 27 | 28 | //Sensor's memory register addresses: 29 | const int PRESSURE = 0x1F; //3 most significant bits of pressure 30 | const int PRESSURE_LSB = 0x20; //16 least significant bits of pressure 31 | const int TEMPERATURE = 0x21; //16 bit temperature reading 32 | const byte READ = 0b11111100; // SCP1000's read command 33 | const byte WRITE = 0b00000010; // SCP1000's write command 34 | 35 | // pins used for the connection with the sensor 36 | // the other you need are controlled by the SPI library): 37 | const int dataReadyPin = 6; 38 | const int chipSelectPin = 7; 39 | 40 | void setup() { 41 | Serial.begin(9600); 42 | 43 | // start the SPI library: 44 | SPI.begin(); 45 | 46 | // initalize the data ready and chip select pins: 47 | pinMode(dataReadyPin, INPUT); 48 | pinMode(chipSelectPin, OUTPUT); 49 | 50 | //Configure SCP1000 for low noise configuration: 51 | writeRegister(0x02, 0x2D); 52 | writeRegister(0x01, 0x03); 53 | writeRegister(0x03, 0x02); 54 | // give the sensor time to set up: 55 | delay(100); 56 | } 57 | 58 | void loop() { 59 | //Select High Resolution Mode 60 | writeRegister(0x03, 0x0A); 61 | 62 | // don't do anything until the data ready pin is high: 63 | if (digitalRead(dataReadyPin) == HIGH) { 64 | //Read the temperature data 65 | int tempData = readRegister(0x21, 2); 66 | 67 | // convert the temperature to celsius and display it: 68 | float realTemp = (float)tempData / 20.0; 69 | Serial.print("Temp[C]="); 70 | Serial.print(realTemp); 71 | 72 | 73 | //Read the pressure data highest 3 bits: 74 | byte pressure_data_high = readRegister(0x1F, 1); 75 | pressure_data_high &= 0b00000111; //you only needs bits 2 to 0 76 | 77 | //Read the pressure data lower 16 bits: 78 | unsigned int pressure_data_low = readRegister(0x20, 2); 79 | //combine the two parts into one 19-bit number: 80 | long pressure = ((pressure_data_high << 16) | pressure_data_low) / 4; 81 | 82 | // display the temperature: 83 | Serial.println("\tPressure [Pa]=" + String(pressure)); 84 | } 85 | } 86 | 87 | //Read from or write to register from the SCP1000: 88 | unsigned int readRegister(byte thisRegister, int bytesToRead) { 89 | byte inByte = 0; // incoming byte from the SPI 90 | unsigned int result = 0; // result to return 91 | Serial.print(thisRegister, BIN); 92 | Serial.print("\t"); 93 | // SCP1000 expects the register name in the upper 6 bits 94 | // of the byte. So shift the bits left by two bits: 95 | thisRegister = thisRegister << 2; 96 | // now combine the address and the command into one byte 97 | byte dataToSend = thisRegister & READ; 98 | Serial.println(thisRegister, BIN); 99 | // take the chip select low to select the device: 100 | digitalWrite(chipSelectPin, LOW); 101 | // send the device the register you want to read: 102 | SPI.transfer(dataToSend); 103 | // send a value of 0 to read the first byte returned: 104 | result = SPI.transfer(0x00); 105 | // decrement the number of bytes left to read: 106 | bytesToRead--; 107 | // if you still have another byte to read: 108 | if (bytesToRead > 0) { 109 | // shift the first byte left, then get the second byte: 110 | result = result << 8; 111 | inByte = SPI.transfer(0x00); 112 | // combine the byte you just got with the previous one: 113 | result = result | inByte; 114 | // decrement the number of bytes left to read: 115 | bytesToRead--; 116 | } 117 | // take the chip select high to de-select: 118 | digitalWrite(chipSelectPin, HIGH); 119 | // return the result: 120 | return (result); 121 | } 122 | 123 | 124 | //Sends a write command to SCP1000 125 | 126 | void writeRegister(byte thisRegister, byte thisValue) { 127 | 128 | // SCP1000 expects the register address in the upper 6 bits 129 | // of the byte. So shift the bits left by two bits: 130 | thisRegister = thisRegister << 2; 131 | // now combine the register address and the command into one byte: 132 | byte dataToSend = thisRegister | WRITE; 133 | 134 | // take the chip select low to select the device: 135 | digitalWrite(chipSelectPin, LOW); 136 | 137 | SPI.transfer(dataToSend); //Send register location 138 | SPI.transfer(thisValue); //Send value to record into register 139 | 140 | // take the chip select high to de-select: 141 | digitalWrite(chipSelectPin, HIGH); 142 | } 143 | 144 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Digital Pot Control 3 | 4 | This example controls an Analog Devices AD5206 digital potentiometer. 5 | The AD5206 has 6 potentiometer channels. Each channel's pins are labeled 6 | A - connect this to voltage 7 | W - this is the pot's wiper, which changes when you set it 8 | B - connect this to ground. 9 | 10 | The AD5206 is SPI-compatible,and to command it, you send two bytes, 11 | one with the channel number (0 - 5) and one with the resistance value for the 12 | channel (0 - 255). 13 | 14 | The circuit: 15 | * All A pins of AD5206 connected to +5V 16 | * All B pins of AD5206 connected to ground 17 | * An LED and a 220-ohm resisor in series connected from each W pin to ground 18 | * CS - to digital pin 10 (SS pin) 19 | * SDI - to digital pin 11 (MOSI pin) 20 | * CLK - to digital pin 13 (SCK pin) 21 | 22 | created 10 Aug 2010 23 | by Tom Igoe 24 | 25 | Thanks to Heather Dewey-Hagborg for the original tutorial, 2005 26 | 27 | */ 28 | 29 | 30 | // inslude the SPI library: 31 | #include 32 | 33 | 34 | // set pin 10 as the slave select for the digital pot: 35 | const int slaveSelectPin = 10; 36 | 37 | void setup() { 38 | // set the slaveSelectPin as an output: 39 | pinMode(slaveSelectPin, OUTPUT); 40 | // initialize SPI: 41 | SPI.begin(); 42 | } 43 | 44 | void loop() { 45 | // go through the six channels of the digital pot: 46 | for (int channel = 0; channel < 6; channel++) { 47 | // change the resistance on this channel from min to max: 48 | for (int level = 0; level < 255; level++) { 49 | digitalPotWrite(channel, level); 50 | delay(10); 51 | } 52 | // wait a second at the top: 53 | delay(100); 54 | // change the resistance on this channel from max to min: 55 | for (int level = 0; level < 255; level++) { 56 | digitalPotWrite(channel, 255 - level); 57 | delay(10); 58 | } 59 | } 60 | 61 | } 62 | 63 | void digitalPotWrite(int address, int value) { 64 | // take the SS pin low to select the chip: 65 | digitalWrite(slaveSelectPin, LOW); 66 | // send in the address and value via SPI: 67 | SPI.transfer(address); 68 | SPI.transfer(value); 69 | // take the SS pin high to de-select the chip: 70 | digitalWrite(slaveSelectPin, HIGH); 71 | } 72 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/SPI/examples/dual_digipot/dual_digipot.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Digital Pot Control 3 | 4 | This example controls an Analog Devices AD5206 digital potentiometer. 5 | The AD5206 has 6 potentiometer channels. Each channel's pins are labeled 6 | A - connect this to voltage 7 | W - this is the pot's wiper, which changes when you set it 8 | B - connect this to ground. 9 | 10 | The AD5206 is SPI-compatible,and to command it, you send two bytes, 11 | one with the channel number (0 - 5) and one with the resistance value for the 12 | channel (0 - 255). 13 | 14 | The circuit: 15 | * All A pins of AD5206 connected to +5V 16 | * All B pins of AD5206 connected to ground 17 | * An LED and a 220-ohm resisor in series connected from each W pin to ground 18 | * CS - to digital pin 10 (SS pin) 19 | * SDI - to digital pin 11 (MOSI pin) 20 | * CLK - to digital pin 13 (SCK pin) 21 | 22 | created 10 Aug 2010 23 | by Tom Igoe 24 | 25 | Thanks to Heather Dewey-Hagborg for the original tutorial, 2005 26 | 27 | */ 28 | 29 | 30 | // include the SPI library: 31 | #include 32 | #include 33 | 34 | // set pin 10 as the slave select for the digital pot: 35 | const int slaveSelectPin = 10; 36 | 37 | // set pin 20 as the slave select for the digital pot: 38 | const int slave1SelectPin = 20; 39 | 40 | void setup() { 41 | // set the slaveSelectPin as an output: 42 | pinMode(slaveSelectPin, OUTPUT); 43 | pinMode(slave1SelectPin, OUTPUT); 44 | // initialize SPI: 45 | SPI.begin(); 46 | SPI1.begin(); 47 | } 48 | 49 | void loop() { 50 | // go through the six channels of the digital pot: 51 | for (int channel = 0; channel < 6; channel++) { 52 | // change the resistance on this channel from min to max: 53 | for (int level = 0; level < 255; level++) { 54 | digitalPotWrite(channel, level); 55 | delay(10); 56 | } 57 | // wait a second at the top: 58 | delay(100); 59 | // change the resistance on this channel from max to min: 60 | for (int level = 0; level < 255; level++) { 61 | digitalPotWrite(channel, 255 - level); 62 | delay(10); 63 | } 64 | } 65 | 66 | } 67 | 68 | void digitalPotWrite(int address, int value) { 69 | // take the SS pin low to select the chip: 70 | digitalWrite(slaveSelectPin, LOW); 71 | // send in the address and value via SPI: 72 | SPI.transfer(address); 73 | SPI.transfer(value); 74 | // take the SS pin high to de-select the chip: 75 | digitalWrite(slaveSelectPin, HIGH); 76 | 77 | digitalWrite(slave1SelectPin, LOW); 78 | SPI1.transfer(address); 79 | SPI1.transfer(value); 80 | // take the SS pin high to de-select the chip: 81 | digitalWrite(slave1SelectPin, HIGH); 82 | } 83 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/SPI/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map SPI 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | SPI KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | begin KEYWORD2 15 | end KEYWORD2 16 | transfer KEYWORD2 17 | setBitOrder KEYWORD2 18 | setDataMode KEYWORD2 19 | setClockDivider KEYWORD2 20 | 21 | 22 | ####################################### 23 | # Constants (LITERAL1) 24 | ####################################### 25 | SPI_CLOCK_DIV4 LITERAL1 26 | SPI_CLOCK_DIV16 LITERAL1 27 | SPI_CLOCK_DIV64 LITERAL1 28 | SPI_CLOCK_DIV128 LITERAL1 29 | SPI_CLOCK_DIV2 LITERAL1 30 | SPI_CLOCK_DIV8 LITERAL1 31 | SPI_CLOCK_DIV32 LITERAL1 32 | SPI_CLOCK_DIV64 LITERAL1 33 | SPI_MODE0 LITERAL1 34 | SPI_MODE1 LITERAL1 35 | SPI_MODE2 LITERAL1 36 | SPI_MODE3 LITERAL1 -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/SPI/library.properties: -------------------------------------------------------------------------------- 1 | name=SPI 2 | version=1.0 3 | author=Arduino 4 | maintainer=Arduino 5 | sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. 6 | paragraph=SPI is a synchronous serial data protocol used by microcontrollers for communicating with one or more peripheral devices quickly over short distances. It uses three lines common to all devices (MISO, MOSI and SCK) and one specific for each device. 7 | category=Communication 8 | url=http://www.arduino.cc/en/Reference/SPI 9 | architectures=avr 10 | 11 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/SPI/src/SPI.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 by Cristian Maglie 3 | * Copyright (c) 2014 by Paul Stoffregen (Transaction API) 4 | * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR) 5 | * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes) 6 | * SPI Master library for arduino. 7 | * 8 | * This file is free software; you can redistribute it and/or modify 9 | * it under the terms of either the GNU General Public License version 2 10 | * or the GNU Lesser General Public License version 2.1, both as 11 | * published by the Free Software Foundation. 12 | */ 13 | 14 | #include "SPI.h" 15 | 16 | SPIClass SPI; 17 | 18 | uint8_t SPIClass::initialized = 0; 19 | uint8_t SPIClass::interruptMode = 0; 20 | uint8_t SPIClass::interruptMask = 0; 21 | uint8_t SPIClass::interruptSave = 0; 22 | #ifdef SPI_TRANSACTION_MISMATCH_LED 23 | uint8_t SPIClass::inTransactionFlag = 0; 24 | #endif 25 | 26 | void SPIClass::begin() 27 | { 28 | uint8_t sreg = SREG; 29 | noInterrupts(); // Protect from a scheduler and prevent transactionBegin 30 | if (!initialized) { 31 | // Set SS to high so a connected chip will be "deselected" by default 32 | uint8_t port = digitalPinToPort(SS); 33 | uint8_t bit = digitalPinToBitMask(SS); 34 | volatile uint8_t *reg = portModeRegister(port); 35 | 36 | // if the SS pin is not already configured as an output 37 | // then set it high (to enable the internal pull-up resistor) 38 | if(!(*reg & bit)){ 39 | digitalWrite(SS, HIGH); 40 | } 41 | 42 | // When the SS pin is set as OUTPUT, it can be used as 43 | // a general purpose output port (it doesn't influence 44 | // SPI operations). 45 | pinMode(SS, OUTPUT); 46 | 47 | // Warning: if the SS pin ever becomes a LOW INPUT then SPI 48 | // automatically switches to Slave, so the data direction of 49 | // the SS pin MUST be kept as OUTPUT. 50 | SPCR |= _BV(MSTR); 51 | SPCR |= _BV(SPE); 52 | 53 | // Set direction register for SCK and MOSI pin. 54 | // MISO pin automatically overrides to INPUT. 55 | // By doing this AFTER enabling SPI, we avoid accidentally 56 | // clocking in a single bit since the lines go directly 57 | // from "input" to SPI control. 58 | // http://code.google.com/p/arduino/issues/detail?id=888 59 | pinMode(SCK, OUTPUT); 60 | pinMode(MOSI, OUTPUT); 61 | } 62 | initialized++; // reference count 63 | SREG = sreg; 64 | } 65 | 66 | void SPIClass::end() { 67 | uint8_t sreg = SREG; 68 | noInterrupts(); // Protect from a scheduler and prevent transactionBegin 69 | // Decrease the reference counter 70 | if (initialized) 71 | initialized--; 72 | // If there are no more references disable SPI 73 | if (!initialized) { 74 | SPCR &= ~_BV(SPE); 75 | interruptMode = 0; 76 | #ifdef SPI_TRANSACTION_MISMATCH_LED 77 | inTransactionFlag = 0; 78 | #endif 79 | } 80 | SREG = sreg; 81 | } 82 | 83 | // mapping of interrupt numbers to bits within SPI_AVR_EIMSK 84 | #if defined(__AVR_ATmega32U4__) 85 | #define SPI_INT0_MASK (1< 3 | * Copyright (c) 2014 by Paul Stoffregen (Transaction API) 4 | * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR) 5 | * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes) 6 | * SPI Master library for arduino. 7 | * 8 | * This file is free software; you can redistribute it and/or modify 9 | * it under the terms of either the GNU General Public License version 2 10 | * or the GNU Lesser General Public License version 2.1, both as 11 | * published by the Free Software Foundation. 12 | */ 13 | 14 | #ifndef _SPI_H_INCLUDED 15 | #define _SPI_H_INCLUDED 16 | 17 | #include 18 | 19 | #ifndef SPCR 20 | #define SPCR SPCR0 21 | #define SPSR SPSR0 22 | #define SPDR SPDR0 23 | #endif 24 | 25 | // SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(), 26 | // usingInterrupt(), and SPISetting(clock, bitOrder, dataMode) 27 | #define SPI_HAS_TRANSACTION 1 28 | 29 | // SPI_HAS_NOTUSINGINTERRUPT means that SPI has notUsingInterrupt() method 30 | #define SPI_HAS_NOTUSINGINTERRUPT 1 31 | 32 | // SPI_ATOMIC_VERSION means that SPI has atomicity fixes and what version. 33 | // This way when there is a bug fix you can check this define to alert users 34 | // of your code if it uses better version of this library. 35 | // This also implies everything that SPI_HAS_TRANSACTION as documented above is 36 | // available too. 37 | #define SPI_ATOMIC_VERSION 1 38 | 39 | // Uncomment this line to add detection of mismatched begin/end transactions. 40 | // A mismatch occurs if other libraries fail to use SPI.endTransaction() for 41 | // each SPI.beginTransaction(). Connect an LED to this pin. The LED will turn 42 | // on if any mismatch is ever detected. 43 | //#define SPI_TRANSACTION_MISMATCH_LED 5 44 | 45 | #ifndef LSBFIRST 46 | #define LSBFIRST 0 47 | #endif 48 | #ifndef MSBFIRST 49 | #define MSBFIRST 1 50 | #endif 51 | 52 | #define SPI_CLOCK_DIV4 0x00 53 | #define SPI_CLOCK_DIV16 0x01 54 | #define SPI_CLOCK_DIV64 0x02 55 | #define SPI_CLOCK_DIV128 0x03 56 | #define SPI_CLOCK_DIV2 0x04 57 | #define SPI_CLOCK_DIV8 0x05 58 | #define SPI_CLOCK_DIV32 0x06 59 | 60 | #define SPI_MODE0 0x00 61 | #define SPI_MODE1 0x04 62 | #define SPI_MODE2 0x08 63 | #define SPI_MODE3 0x0C 64 | 65 | #define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR 66 | #define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR 67 | #define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR 68 | 69 | // define SPI_AVR_EIMSK for AVR boards with external interrupt pins 70 | #if defined(EIMSK) 71 | #define SPI_AVR_EIMSK EIMSK 72 | #elif defined(GICR) 73 | #define SPI_AVR_EIMSK GICR 74 | #elif defined(GIMSK) 75 | #define SPI_AVR_EIMSK GIMSK 76 | #endif 77 | 78 | class SPISettings { 79 | public: 80 | SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) { 81 | if (__builtin_constant_p(clock)) { 82 | init_AlwaysInline(clock, bitOrder, dataMode); 83 | } else { 84 | init_MightInline(clock, bitOrder, dataMode); 85 | } 86 | } 87 | SPISettings() { 88 | init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); 89 | } 90 | private: 91 | void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) { 92 | init_AlwaysInline(clock, bitOrder, dataMode); 93 | } 94 | void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) 95 | __attribute__((__always_inline__)) { 96 | // Clock settings are defined as follows. Note that this shows SPI2X 97 | // inverted, so the bits form increasing numbers. Also note that 98 | // fosc/64 appears twice 99 | // SPR1 SPR0 ~SPI2X Freq 100 | // 0 0 0 fosc/2 101 | // 0 0 1 fosc/4 102 | // 0 1 0 fosc/8 103 | // 0 1 1 fosc/16 104 | // 1 0 0 fosc/32 105 | // 1 0 1 fosc/64 106 | // 1 1 0 fosc/64 107 | // 1 1 1 fosc/128 108 | 109 | // We find the fastest clock that is less than or equal to the 110 | // given clock rate. The clock divider that results in clock_setting 111 | // is 2 ^^ (clock_div + 1). If nothing is slow enough, we'll use the 112 | // slowest (128 == 2 ^^ 7, so clock_div = 6). 113 | uint8_t clockDiv; 114 | 115 | // When the clock is known at compiletime, use this if-then-else 116 | // cascade, which the compiler knows how to completely optimize 117 | // away. When clock is not known, use a loop instead, which generates 118 | // shorter code. 119 | if (__builtin_constant_p(clock)) { 120 | if (clock >= F_CPU / 2) { 121 | clockDiv = 0; 122 | } else if (clock >= F_CPU / 4) { 123 | clockDiv = 1; 124 | } else if (clock >= F_CPU / 8) { 125 | clockDiv = 2; 126 | } else if (clock >= F_CPU / 16) { 127 | clockDiv = 3; 128 | } else if (clock >= F_CPU / 32) { 129 | clockDiv = 4; 130 | } else if (clock >= F_CPU / 64) { 131 | clockDiv = 5; 132 | } else { 133 | clockDiv = 6; 134 | } 135 | } else { 136 | uint32_t clockSetting = F_CPU / 2; 137 | clockDiv = 0; 138 | while (clockDiv < 6 && clock < clockSetting) { 139 | clockSetting /= 2; 140 | clockDiv++; 141 | } 142 | } 143 | 144 | // Compensate for the duplicate fosc/64 145 | if (clockDiv == 6) 146 | clockDiv = 7; 147 | 148 | // Invert the SPI2X bit 149 | clockDiv ^= 0x1; 150 | 151 | // Pack into the SPISettings class 152 | spcr = _BV(SPE) | _BV(MSTR) | ((bitOrder == LSBFIRST) ? _BV(DORD) : 0) | 153 | (dataMode & SPI_MODE_MASK) | ((clockDiv >> 1) & SPI_CLOCK_MASK); 154 | spsr = clockDiv & SPI_2XCLOCK_MASK; 155 | } 156 | uint8_t spcr; 157 | uint8_t spsr; 158 | friend class SPIClass; 159 | }; 160 | 161 | 162 | class SPIClass { 163 | public: 164 | // Initialize the SPI library 165 | static void begin(); 166 | 167 | // If SPI is used from within an interrupt, this function registers 168 | // that interrupt with the SPI library, so beginTransaction() can 169 | // prevent conflicts. The input interruptNumber is the number used 170 | // with attachInterrupt. If SPI is used from a different interrupt 171 | // (eg, a timer), interruptNumber should be 255. 172 | static void usingInterrupt(uint8_t interruptNumber); 173 | // And this does the opposite. 174 | static void notUsingInterrupt(uint8_t interruptNumber); 175 | // Note: the usingInterrupt and notUsingInterrupt functions should 176 | // not to be called from ISR context or inside a transaction. 177 | // For details see: 178 | // https://github.com/arduino/Arduino/pull/2381 179 | // https://github.com/arduino/Arduino/pull/2449 180 | 181 | // Before using SPI.transfer() or asserting chip select pins, 182 | // this function is used to gain exclusive access to the SPI bus 183 | // and configure the correct settings. 184 | inline static void beginTransaction(SPISettings settings) { 185 | if (interruptMode > 0) { 186 | uint8_t sreg = SREG; 187 | noInterrupts(); 188 | 189 | #ifdef SPI_AVR_EIMSK 190 | if (interruptMode == 1) { 191 | interruptSave = SPI_AVR_EIMSK; 192 | SPI_AVR_EIMSK &= ~interruptMask; 193 | SREG = sreg; 194 | } else 195 | #endif 196 | { 197 | interruptSave = sreg; 198 | } 199 | } 200 | 201 | #ifdef SPI_TRANSACTION_MISMATCH_LED 202 | if (inTransactionFlag) { 203 | pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT); 204 | digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH); 205 | } 206 | inTransactionFlag = 1; 207 | #endif 208 | 209 | SPCR = settings.spcr; 210 | SPSR = settings.spsr; 211 | } 212 | 213 | // Write to the SPI bus (MOSI pin) and also receive (MISO pin) 214 | inline static uint8_t transfer(uint8_t data) { 215 | SPDR = data; 216 | /* 217 | * The following NOP introduces a small delay that can prevent the wait 218 | * loop form iterating when running at the maximum speed. This gives 219 | * about 10% more speed, even if it seems counter-intuitive. At lower 220 | * speeds it is unnoticed. 221 | */ 222 | asm volatile("nop"); 223 | while (!(SPSR & _BV(SPIF))) ; // wait 224 | return SPDR; 225 | } 226 | inline static uint16_t transfer16(uint16_t data) { 227 | union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out; 228 | in.val = data; 229 | if (!(SPCR & _BV(DORD))) { 230 | SPDR = in.msb; 231 | asm volatile("nop"); // See transfer(uint8_t) function 232 | while (!(SPSR & _BV(SPIF))) ; 233 | out.msb = SPDR; 234 | SPDR = in.lsb; 235 | asm volatile("nop"); 236 | while (!(SPSR & _BV(SPIF))) ; 237 | out.lsb = SPDR; 238 | } else { 239 | SPDR = in.lsb; 240 | asm volatile("nop"); 241 | while (!(SPSR & _BV(SPIF))) ; 242 | out.lsb = SPDR; 243 | SPDR = in.msb; 244 | asm volatile("nop"); 245 | while (!(SPSR & _BV(SPIF))) ; 246 | out.msb = SPDR; 247 | } 248 | return out.val; 249 | } 250 | inline static void transfer(void *buf, size_t count) { 251 | if (count == 0) return; 252 | uint8_t *p = (uint8_t *)buf; 253 | SPDR = *p; 254 | while (--count > 0) { 255 | uint8_t out = *(p + 1); 256 | while (!(SPSR & _BV(SPIF))) ; 257 | uint8_t in = SPDR; 258 | SPDR = out; 259 | *p++ = in; 260 | } 261 | while (!(SPSR & _BV(SPIF))) ; 262 | *p = SPDR; 263 | } 264 | // After performing a group of transfers and releasing the chip select 265 | // signal, this function allows others to access the SPI bus 266 | inline static void endTransaction(void) { 267 | #ifdef SPI_TRANSACTION_MISMATCH_LED 268 | if (!inTransactionFlag) { 269 | pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT); 270 | digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH); 271 | } 272 | inTransactionFlag = 0; 273 | #endif 274 | 275 | if (interruptMode > 0) { 276 | #ifdef SPI_AVR_EIMSK 277 | uint8_t sreg = SREG; 278 | #endif 279 | noInterrupts(); 280 | #ifdef SPI_AVR_EIMSK 281 | if (interruptMode == 1) { 282 | SPI_AVR_EIMSK = interruptSave; 283 | SREG = sreg; 284 | } else 285 | #endif 286 | { 287 | SREG = interruptSave; 288 | } 289 | } 290 | } 291 | 292 | // Disable the SPI bus 293 | static void end(); 294 | 295 | // This function is deprecated. New applications should use 296 | // beginTransaction() to configure SPI settings. 297 | inline static void setBitOrder(uint8_t bitOrder) { 298 | if (bitOrder == LSBFIRST) SPCR |= _BV(DORD); 299 | else SPCR &= ~(_BV(DORD)); 300 | } 301 | // This function is deprecated. New applications should use 302 | // beginTransaction() to configure SPI settings. 303 | inline static void setDataMode(uint8_t dataMode) { 304 | SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode; 305 | } 306 | // This function is deprecated. New applications should use 307 | // beginTransaction() to configure SPI settings. 308 | inline static void setClockDivider(uint8_t clockDiv) { 309 | SPCR = (SPCR & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK); 310 | SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK); 311 | } 312 | // These undocumented functions should not be used. SPI.transfer() 313 | // polls the hardware flag which is automatically cleared as the 314 | // AVR responds to SPI's interrupt 315 | inline static void attachInterrupt() { SPCR |= _BV(SPIE); } 316 | inline static void detachInterrupt() { SPCR &= ~_BV(SPIE); } 317 | 318 | private: 319 | static uint8_t initialized; 320 | static uint8_t interruptMode; // 0=none, 1=mask, 2=global 321 | static uint8_t interruptMask; // which interrupts to mask 322 | static uint8_t interruptSave; // temp storage, to restore state 323 | #ifdef SPI_TRANSACTION_MISMATCH_LED 324 | static uint8_t inTransactionFlag; 325 | #endif 326 | }; 327 | 328 | extern SPIClass SPI; 329 | 330 | #endif 331 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/SPI1/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map SPI 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | SPI1 KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | begin KEYWORD2 15 | end KEYWORD2 16 | transfer KEYWORD2 17 | setBitOrder KEYWORD2 18 | setDataMode KEYWORD2 19 | setClockDivider KEYWORD2 20 | 21 | 22 | ####################################### 23 | # Constants (LITERAL1) 24 | ####################################### 25 | SPI_CLOCK_DIV4 LITERAL1 26 | SPI_CLOCK_DIV16 LITERAL1 27 | SPI_CLOCK_DIV64 LITERAL1 28 | SPI_CLOCK_DIV128 LITERAL1 29 | SPI_CLOCK_DIV2 LITERAL1 30 | SPI_CLOCK_DIV8 LITERAL1 31 | SPI_CLOCK_DIV32 LITERAL1 32 | SPI_CLOCK_DIV64 LITERAL1 33 | SPI_MODE0 LITERAL1 34 | SPI_MODE1 LITERAL1 35 | SPI_MODE2 LITERAL1 36 | SPI_MODE3 LITERAL1 -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/SPI1/library.properties: -------------------------------------------------------------------------------- 1 | name=SPI1 2 | version=1.0 3 | author=Arduino 4 | maintainer=Arduino 5 | sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. 6 | paragraph=SPI is a synchronous serial data protocol used by microcontrollers for communicating with one or more peripheral devices quickly over short distances. It uses three lines common to all devices (MISO, MOSI and SCK) and one specific for each device. 7 | category=Communication 8 | url=http://www.arduino.cc/en/Reference/SPI 9 | architectures=avr 10 | 11 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/SPI1/src/SPI1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 by Cristian Maglie 3 | * Copyright (c) 2014 by Paul Stoffregen (Transaction API) 4 | * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR) 5 | * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes) 6 | * SPI Master library for arduino. 7 | * 8 | * This file is free software; you can redistribute it and/or modify 9 | * it under the terms of either the GNU General Public License version 2 10 | * or the GNU Lesser General Public License version 2.1, both as 11 | * published by the Free Software Foundation. 12 | */ 13 | 14 | #include "SPI1.h" 15 | 16 | SPI1Class SPI1; 17 | 18 | uint8_t SPI1Class::initialized = 0; 19 | uint8_t SPI1Class::interruptMode = 0; 20 | uint8_t SPI1Class::interruptMask = 0; 21 | uint8_t SPI1Class::interruptSave = 0; 22 | #ifdef SPI_TRANSACTION_MISMATCH_LED 23 | uint8_t SPI1Class::inTransactionFlag = 0; 24 | #endif 25 | 26 | void SPI1Class::begin() 27 | { 28 | uint8_t sreg = SREG; 29 | noInterrupts(); // Protect from a scheduler and prevent transactionBegin 30 | if (!initialized) { 31 | // Set SS to high so a connected chip will be "deselected" by default 32 | uint8_t port = digitalPinToPort(SS1); 33 | uint8_t bit = digitalPinToBitMask(SS1); 34 | volatile uint8_t *reg = portModeRegister(port); 35 | 36 | // if the SS pin is not already configured as an output 37 | // then set it high (to enable the internal pull-up resistor) 38 | if(!(*reg & bit)){ 39 | digitalWrite(SS1, HIGH); 40 | } 41 | 42 | // When the SS pin is set as OUTPUT, it can be used as 43 | // a general purpose output port (it doesn't influence 44 | // SPI operations). 45 | pinMode(SS1, OUTPUT); 46 | 47 | // Warning: if the SS pin ever becomes a LOW INPUT then SPI 48 | // automatically switches to Slave, so the data direction of 49 | // the SS pin MUST be kept as OUTPUT. 50 | SPCR1 |= _BV(MSTR); 51 | SPCR1 |= _BV(SPE); 52 | 53 | // Set direction register for SCK and MOSI pin. 54 | // MISO pin automatically overrides to INPUT. 55 | // By doing this AFTER enabling SPI, we avoid accidentally 56 | // clocking in a single bit since the lines go directly 57 | // from "input" to SPI control. 58 | // http://code.google.com/p/arduino/issues/detail?id=888 59 | pinMode(SCK1, OUTPUT); 60 | pinMode(MOSI1, OUTPUT); 61 | } 62 | initialized++; // reference count 63 | SREG = sreg; 64 | } 65 | 66 | void SPI1Class::end() { 67 | uint8_t sreg = SREG; 68 | noInterrupts(); // Protect from a scheduler and prevent transactionBegin 69 | // Decrease the reference counter 70 | if (initialized) 71 | initialized--; 72 | // If there are no more references disable SPI 73 | if (!initialized) { 74 | SPCR1 &= ~_BV(SPE); 75 | interruptMode = 0; 76 | #ifdef SPI_TRANSACTION_MISMATCH_LED 77 | inTransactionFlag = 0; 78 | #endif 79 | } 80 | SREG = sreg; 81 | } 82 | 83 | // mapping of interrupt numbers to bits within SPI_AVR_EIMSK 84 | #if defined(__AVR_ATmega32U4__) 85 | #define SPI_INT0_MASK (1< 3 | * Copyright (c) 2014 by Paul Stoffregen (Transaction API) 4 | * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR) 5 | * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes) 6 | * SPI Master library for arduino. 7 | * 8 | * This file is free software; you can redistribute it and/or modify 9 | * it under the terms of either the GNU General Public License version 2 10 | * or the GNU Lesser General Public License version 2.1, both as 11 | * published by the Free Software Foundation. 12 | */ 13 | 14 | #ifndef _SPI1_H_INCLUDED 15 | #define _SPI1_H_INCLUDED 16 | 17 | #include 18 | 19 | // SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(), 20 | // usingInterrupt(), and SPISetting(clock, bitOrder, dataMode) 21 | #define SPI_HAS_TRANSACTION 1 22 | 23 | // SPI_HAS_NOTUSINGINTERRUPT means that SPI has notUsingInterrupt() method 24 | #define SPI_HAS_NOTUSINGINTERRUPT 1 25 | 26 | // SPI_ATOMIC_VERSION means that SPI has atomicity fixes and what version. 27 | // This way when there is a bug fix you can check this define to alert users 28 | // of your code if it uses better version of this library. 29 | // This also implies everything that SPI_HAS_TRANSACTION as documented above is 30 | // available too. 31 | #define SPI_ATOMIC_VERSION 1 32 | 33 | // Uncomment this line to add detection of mismatched begin/end transactions. 34 | // A mismatch occurs if other libraries fail to use SPI.endTransaction() for 35 | // each SPI.beginTransaction(). Connect an LED to this pin. The LED will turn 36 | // on if any mismatch is ever detected. 37 | //#define SPI_TRANSACTION_MISMATCH_LED 5 38 | 39 | #ifndef LSBFIRST 40 | #define LSBFIRST 0 41 | #endif 42 | #ifndef MSBFIRST 43 | #define MSBFIRST 1 44 | #endif 45 | 46 | #define SPI_CLOCK_DIV4 0x00 47 | #define SPI_CLOCK_DIV16 0x01 48 | #define SPI_CLOCK_DIV64 0x02 49 | #define SPI_CLOCK_DIV128 0x03 50 | #define SPI_CLOCK_DIV2 0x04 51 | #define SPI_CLOCK_DIV8 0x05 52 | #define SPI_CLOCK_DIV32 0x06 53 | 54 | #define SPI_MODE0 0x00 55 | #define SPI_MODE1 0x04 56 | #define SPI_MODE2 0x08 57 | #define SPI_MODE3 0x0C 58 | 59 | #define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR1 60 | #define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR1 61 | #define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR1 62 | 63 | // define SPI_AVR_EIMSK for AVR boards with external interrupt pins 64 | #if defined(EIMSK) 65 | #define SPI_AVR_EIMSK EIMSK 66 | #elif defined(GICR) 67 | #define SPI_AVR_EIMSK GICR 68 | #elif defined(GIMSK) 69 | #define SPI_AVR_EIMSK GIMSK 70 | #endif 71 | 72 | class SPI1Settings { 73 | public: 74 | SPI1Settings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) { 75 | if (__builtin_constant_p(clock)) { 76 | init_AlwaysInline(clock, bitOrder, dataMode); 77 | } else { 78 | init_MightInline(clock, bitOrder, dataMode); 79 | } 80 | } 81 | SPI1Settings() { 82 | init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); 83 | } 84 | private: 85 | void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) { 86 | init_AlwaysInline(clock, bitOrder, dataMode); 87 | } 88 | void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) 89 | __attribute__((__always_inline__)) { 90 | // Clock settings are defined as follows. Note that this shows SPI2X 91 | // inverted, so the bits form increasing numbers. Also note that 92 | // fosc/64 appears twice 93 | // SPR1 SPR0 ~SPI2X Freq 94 | // 0 0 0 fosc/2 95 | // 0 0 1 fosc/4 96 | // 0 1 0 fosc/8 97 | // 0 1 1 fosc/16 98 | // 1 0 0 fosc/32 99 | // 1 0 1 fosc/64 100 | // 1 1 0 fosc/64 101 | // 1 1 1 fosc/128 102 | 103 | // We find the fastest clock that is less than or equal to the 104 | // given clock rate. The clock divider that results in clock_setting 105 | // is 2 ^^ (clock_div + 1). If nothing is slow enough, we'll use the 106 | // slowest (128 == 2 ^^ 7, so clock_div = 6). 107 | uint8_t clockDiv; 108 | 109 | // When the clock is known at compiletime, use this if-then-else 110 | // cascade, which the compiler knows how to completely optimize 111 | // away. When clock is not known, use a loop instead, which generates 112 | // shorter code. 113 | if (__builtin_constant_p(clock)) { 114 | if (clock >= F_CPU / 2) { 115 | clockDiv = 0; 116 | } else if (clock >= F_CPU / 4) { 117 | clockDiv = 1; 118 | } else if (clock >= F_CPU / 8) { 119 | clockDiv = 2; 120 | } else if (clock >= F_CPU / 16) { 121 | clockDiv = 3; 122 | } else if (clock >= F_CPU / 32) { 123 | clockDiv = 4; 124 | } else if (clock >= F_CPU / 64) { 125 | clockDiv = 5; 126 | } else { 127 | clockDiv = 6; 128 | } 129 | } else { 130 | uint32_t clockSetting = F_CPU / 2; 131 | clockDiv = 0; 132 | while (clockDiv < 6 && clock < clockSetting) { 133 | clockSetting /= 2; 134 | clockDiv++; 135 | } 136 | } 137 | 138 | // Compensate for the duplicate fosc/64 139 | if (clockDiv == 6) 140 | clockDiv = 7; 141 | 142 | // Invert the SPI2X bit 143 | clockDiv ^= 0x1; 144 | 145 | // Pack into the SPI1Settings class 146 | spcr1 = _BV(SPE) | _BV(MSTR) | ((bitOrder == LSBFIRST) ? _BV(DORD) : 0) | 147 | (dataMode & SPI_MODE_MASK) | ((clockDiv >> 1) & SPI_CLOCK_MASK); 148 | spsr1 = clockDiv & SPI_2XCLOCK_MASK; 149 | } 150 | uint8_t spcr1; 151 | uint8_t spsr1; 152 | friend class SPI1Class; 153 | }; 154 | 155 | 156 | class SPI1Class { 157 | public: 158 | // Initialize the SPI library 159 | static void begin(); 160 | 161 | // If SPI is used from within an interrupt, this function registers 162 | // that interrupt with the SPI library, so beginTransaction() can 163 | // prevent conflicts. The input interruptNumber is the number used 164 | // with attachInterrupt. If SPI is used from a different interrupt 165 | // (eg, a timer), interruptNumber should be 255. 166 | static void usingInterrupt(uint8_t interruptNumber); 167 | // And this does the opposite. 168 | static void notUsingInterrupt(uint8_t interruptNumber); 169 | // Note: the usingInterrupt and notUsingInterrupt functions should 170 | // not to be called from ISR context or inside a transaction. 171 | // For details see: 172 | // https://github.com/arduino/Arduino/pull/2381 173 | // https://github.com/arduino/Arduino/pull/2449 174 | 175 | // Before using SPI.transfer() or asserting chip select pins, 176 | // this function is used to gain exclusive access to the SPI bus 177 | // and configure the correct settings. 178 | inline static void beginTransaction(SPI1Settings settings) { 179 | if (interruptMode > 0) { 180 | uint8_t sreg = SREG; 181 | noInterrupts(); 182 | 183 | #ifdef SPI_AVR_EIMSK 184 | if (interruptMode == 1) { 185 | interruptSave = SPI_AVR_EIMSK; 186 | SPI_AVR_EIMSK &= ~interruptMask; 187 | SREG = sreg; 188 | } else 189 | #endif 190 | { 191 | interruptSave = sreg; 192 | } 193 | } 194 | 195 | #ifdef SPI_TRANSACTION_MISMATCH_LED 196 | if (inTransactionFlag) { 197 | pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT); 198 | digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH); 199 | } 200 | inTransactionFlag = 1; 201 | #endif 202 | 203 | SPCR1 = settings.spcr1; 204 | SPSR1 = settings.spsr1; 205 | } 206 | 207 | // Write to the SPI bus (MOSI pin) and also receive (MISO pin) 208 | inline static uint8_t transfer(uint8_t data) { 209 | SPDR1 = data; 210 | /* 211 | * The following NOP introduces a small delay that can prevent the wait 212 | * loop form iterating when running at the maximum speed. This gives 213 | * about 10% more speed, even if it seems counter-intuitive. At lower 214 | * speeds it is unnoticed. 215 | */ 216 | asm volatile("nop"); 217 | while (!(SPSR1 & _BV(SPIF))) ; // wait 218 | return SPDR1; 219 | } 220 | inline static uint16_t transfer16(uint16_t data) { 221 | union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out; 222 | in.val = data; 223 | if (!(SPCR1 & _BV(DORD))) { 224 | SPDR1 = in.msb; 225 | asm volatile("nop"); // See transfer(uint8_t) function 226 | while (!(SPSR1 & _BV(SPIF))) ; 227 | out.msb = SPDR1; 228 | SPDR1 = in.lsb; 229 | asm volatile("nop"); 230 | while (!(SPSR1 & _BV(SPIF))) ; 231 | out.lsb = SPDR1; 232 | } else { 233 | SPDR1 = in.lsb; 234 | asm volatile("nop"); 235 | while (!(SPSR1 & _BV(SPIF))) ; 236 | out.lsb = SPDR1; 237 | SPDR1 = in.msb; 238 | asm volatile("nop"); 239 | while (!(SPSR1 & _BV(SPIF))) ; 240 | out.msb = SPDR1; 241 | } 242 | return out.val; 243 | } 244 | inline static void transfer(void *buf, size_t count) { 245 | if (count == 0) return; 246 | uint8_t *p = (uint8_t *)buf; 247 | SPDR1 = *p; 248 | while (--count > 0) { 249 | uint8_t out = *(p + 1); 250 | while (!(SPSR1 & _BV(SPIF))) ; 251 | uint8_t in = SPDR1; 252 | SPDR1 = out; 253 | *p++ = in; 254 | } 255 | while (!(SPSR1 & _BV(SPIF))) ; 256 | *p = SPDR1; 257 | } 258 | // After performing a group of transfers and releasing the chip select 259 | // signal, this function allows others to access the SPI bus 260 | inline static void endTransaction(void) { 261 | #ifdef SPI_TRANSACTION_MISMATCH_LED 262 | if (!inTransactionFlag) { 263 | pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT); 264 | digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH); 265 | } 266 | inTransactionFlag = 0; 267 | #endif 268 | 269 | if (interruptMode > 0) { 270 | #ifdef SPI_AVR_EIMSK 271 | uint8_t sreg = SREG; 272 | #endif 273 | noInterrupts(); 274 | #ifdef SPI_AVR_EIMSK 275 | if (interruptMode == 1) { 276 | SPI_AVR_EIMSK = interruptSave; 277 | SREG = sreg; 278 | } else 279 | #endif 280 | { 281 | SREG = interruptSave; 282 | } 283 | } 284 | } 285 | 286 | // Disable the SPI bus 287 | static void end(); 288 | 289 | // This function is deprecated. New applications should use 290 | // beginTransaction() to configure SPI settings. 291 | inline static void setBitOrder(uint8_t bitOrder) { 292 | if (bitOrder == LSBFIRST) SPCR1 |= _BV(DORD); 293 | else SPCR1 &= ~(_BV(DORD)); 294 | } 295 | // This function is deprecated. New applications should use 296 | // beginTransaction() to configure SPI settings. 297 | inline static void setDataMode(uint8_t dataMode) { 298 | SPCR1 = (SPCR1 & ~SPI_MODE_MASK) | dataMode; 299 | } 300 | // This function is deprecated. New applications should use 301 | // beginTransaction() to configure SPI settings. 302 | inline static void setClockDivider(uint8_t clockDiv) { 303 | SPCR1 = (SPCR1 & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK); 304 | SPSR1 = (SPSR1 & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK); 305 | } 306 | // These undocumented functions should not be used. SPI.transfer() 307 | // polls the hardware flag which is automatically cleared as the 308 | // AVR responds to SPI's interrupt 309 | inline static void attachInterrupt() { SPCR1 |= _BV(SPIE); } 310 | inline static void detachInterrupt() { SPCR1 &= ~_BV(SPIE); } 311 | 312 | private: 313 | static uint8_t initialized; 314 | static uint8_t interruptMode; // 0=none, 1=mask, 2=global 315 | static uint8_t interruptMask; // which interrupts to mask 316 | static uint8_t interruptSave; // temp storage, to restore state 317 | #ifdef SPI_TRANSACTION_MISMATCH_LED 318 | static uint8_t inTransactionFlag; 319 | #endif 320 | }; 321 | 322 | extern SPI1Class SPI1; 323 | 324 | #endif 325 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.ino: -------------------------------------------------------------------------------- 1 | // I2C SRF10 or SRF08 Devantech Ultrasonic Ranger Finder 2 | // by Nicholas Zambetti 3 | // and James Tichenor 4 | 5 | // Demonstrates use of the Wire library reading data from the 6 | // Devantech Utrasonic Rangers SFR08 and SFR10 7 | 8 | // Created 29 April 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | 13 | #include 14 | 15 | void setup() { 16 | Wire.begin(); // join i2c bus (address optional for master) 17 | Serial.begin(9600); // start serial communication at 9600bps 18 | } 19 | 20 | int reading = 0; 21 | 22 | void loop() { 23 | // step 1: instruct sensor to read echoes 24 | Wire.beginTransmission(112); // transmit to device #112 (0x70) 25 | // the address specified in the datasheet is 224 (0xE0) 26 | // but i2c adressing uses the high 7 bits so it's 112 27 | Wire.write(byte(0x00)); // sets register pointer to the command register (0x00) 28 | Wire.write(byte(0x50)); // command sensor to measure in "inches" (0x50) 29 | // use 0x51 for centimeters 30 | // use 0x52 for ping microseconds 31 | Wire.endTransmission(); // stop transmitting 32 | 33 | // step 2: wait for readings to happen 34 | delay(70); // datasheet suggests at least 65 milliseconds 35 | 36 | // step 3: instruct sensor to return a particular echo reading 37 | Wire.beginTransmission(112); // transmit to device #112 38 | Wire.write(byte(0x02)); // sets register pointer to echo #1 register (0x02) 39 | Wire.endTransmission(); // stop transmitting 40 | 41 | // step 4: request reading from sensor 42 | Wire.requestFrom(112, 2); // request 2 bytes from slave device #112 43 | 44 | // step 5: receive reading from sensor 45 | if (2 <= Wire.available()) { // if two bytes were received 46 | reading = Wire.read(); // receive high byte (overwrites previous reading) 47 | reading = reading << 8; // shift high byte to be high 8 bits 48 | reading |= Wire.read(); // receive low byte as lower 8 bits 49 | Serial.println(reading); // print the reading 50 | } 51 | 52 | delay(250); // wait a bit since people have to read the output :) 53 | } 54 | 55 | 56 | /* 57 | 58 | // The following code changes the address of a Devantech Ultrasonic Range Finder (SRF10 or SRF08) 59 | // usage: changeAddress(0x70, 0xE6); 60 | 61 | void changeAddress(byte oldAddress, byte newAddress) 62 | { 63 | Wire.beginTransmission(oldAddress); 64 | Wire.write(byte(0x00)); 65 | Wire.write(byte(0xA0)); 66 | Wire.endTransmission(); 67 | 68 | Wire.beginTransmission(oldAddress); 69 | Wire.write(byte(0x00)); 70 | Wire.write(byte(0xAA)); 71 | Wire.endTransmission(); 72 | 73 | Wire.beginTransmission(oldAddress); 74 | Wire.write(byte(0x00)); 75 | Wire.write(byte(0xA5)); 76 | Wire.endTransmission(); 77 | 78 | Wire.beginTransmission(oldAddress); 79 | Wire.write(byte(0x00)); 80 | Wire.write(newAddress); 81 | Wire.endTransmission(); 82 | } 83 | 84 | */ 85 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire/examples/digital_potentiometer/digital_potentiometer.ino: -------------------------------------------------------------------------------- 1 | // I2C Digital Potentiometer 2 | // by Nicholas Zambetti 3 | // and Shawn Bonkowski 4 | 5 | // Demonstrates use of the Wire library 6 | // Controls AD5171 digital potentiometer via I2C/TWI 7 | 8 | // Created 31 March 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | // This example code is in the public domain. 13 | 14 | 15 | #include 16 | 17 | void setup() { 18 | Wire.begin(); // join i2c bus (address optional for master) 19 | //Wire.begin(); 20 | } 21 | 22 | byte val = 0; 23 | 24 | void loop() { 25 | Wire.beginTransmission(44); // transmit to device #44 (0x2c) 26 | // device address is specified in datasheet 27 | Wire.write(byte(0x00)); // sends instruction byte 28 | Wire.write(val); // sends potentiometer value byte 29 | Wire.endTransmission(); // stop transmitting 30 | 31 | val++; // increment value 32 | if (val == 64) { // if reached 64th position (max) 33 | val = 0; // start over from lowest value 34 | } 35 | delay(500); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire/examples/dual_digipot/dual_digipot.ino: -------------------------------------------------------------------------------- 1 | // I2C Digital Potentiometer 2 | // by Nicholas Zambetti 3 | // and Shawn Bonkowski 4 | 5 | // Demonstrates use of the Wire library 6 | // Controls AD5171 digital potentiometer via I2C/TWI 7 | 8 | // Created 31 March 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | // This example code is in the public domain. 13 | 14 | // Dual wire example 15 | 16 | #include 17 | #include 18 | 19 | void setup() { 20 | Wire.begin(); // join i2c bus (address optional for master) 21 | Wire1.begin(); 22 | } 23 | 24 | byte val = 0; 25 | 26 | void loop() { 27 | Wire.beginTransmission(44); // transmit to device #44 (0x2c) 28 | Wire1.beginTransmission(44); // transmit to 2nd device #44 (0x2c) 29 | // device address is specified in datasheet 30 | Wire.write(byte(0x00)); // sends instruction byte 31 | Wire.write(val); // sends potentiometer value byte 32 | Wire.endTransmission(); // stop transmitting 33 | 34 | // 2nd I2C 35 | Wire1.write(byte(0x00)); // sends instruction byte 36 | Wire1.write(val); // sends potentiometer value byte 37 | Wire1.endTransmission(); // stop transmitting 38 | 39 | val++; // increment value 40 | if (val == 64) { // if reached 64th position (max) 41 | val = 0; // start over from lowest value 42 | } 43 | delay(500); 44 | } 45 | 46 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire/examples/master_reader/master_reader.ino: -------------------------------------------------------------------------------- 1 | // Wire Master Reader 2 | // by Nicholas Zambetti 3 | 4 | // Demonstrates use of the Wire library 5 | // Reads data from an I2C/TWI slave device 6 | // Refer to the "Wire Slave Sender" example for use with this 7 | 8 | // Created 29 March 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | 13 | #include 14 | 15 | void setup() { 16 | Wire.begin(); // join i2c bus (address optional for master) 17 | Serial.begin(9600); // start serial for output 18 | } 19 | 20 | void loop() { 21 | Wire.requestFrom(8, 6); // request 6 bytes from slave device #8 22 | 23 | while (Wire.available()) { // slave may send less than requested 24 | char c = Wire.read(); // receive a byte as character 25 | Serial.print(c); // print the character 26 | } 27 | 28 | delay(500); 29 | } 30 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire/examples/master_writer/master_writer.ino: -------------------------------------------------------------------------------- 1 | // Wire Master Writer 2 | // by Nicholas Zambetti 3 | 4 | // Demonstrates use of the Wire library 5 | // Writes data to an I2C/TWI slave device 6 | // Refer to the "Wire Slave Receiver" example for use with this 7 | 8 | // Created 29 March 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | 13 | #include 14 | 15 | void setup() { 16 | Wire.begin(); // join i2c bus (address optional for master) 17 | } 18 | 19 | byte x = 0; 20 | 21 | void loop() { 22 | Wire.beginTransmission(8); // transmit to device #8 23 | Wire.write("x is "); // sends five bytes 24 | Wire.write(x); // sends one byte 25 | Wire.endTransmission(); // stop transmitting 26 | 27 | x++; 28 | delay(500); 29 | } 30 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire/examples/slave_receiver/slave_receiver.ino: -------------------------------------------------------------------------------- 1 | // Wire Slave Receiver 2 | // by Nicholas Zambetti 3 | 4 | // Demonstrates use of the Wire library 5 | // Receives data as an I2C/TWI slave device 6 | // Refer to the "Wire Master Writer" example for use with this 7 | 8 | // Created 29 March 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | 13 | #include 14 | 15 | void setup() { 16 | Wire.begin(8); // join i2c bus with address #8 17 | Wire.onReceive(receiveEvent); // register event 18 | Serial.begin(9600); // start serial for output 19 | } 20 | 21 | void loop() { 22 | delay(100); 23 | } 24 | 25 | // function that executes whenever data is received from master 26 | // this function is registered as an event, see setup() 27 | void receiveEvent(int howMany) { 28 | while (1 < Wire.available()) { // loop through all but the last 29 | char c = Wire.read(); // receive byte as a character 30 | Serial.print(c); // print the character 31 | } 32 | int x = Wire.read(); // receive byte as an integer 33 | Serial.println(x); // print the integer 34 | } 35 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire/examples/slave_sender/slave_sender.ino: -------------------------------------------------------------------------------- 1 | // Wire Slave Sender 2 | // by Nicholas Zambetti 3 | 4 | // Demonstrates use of the Wire library 5 | // Sends data as an I2C/TWI slave device 6 | // Refer to the "Wire Master Reader" example for use with this 7 | 8 | // Created 29 March 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | 13 | #include 14 | 15 | void setup() { 16 | Wire.begin(8); // join i2c bus with address #8 17 | Wire.onRequest(requestEvent); // register event 18 | } 19 | 20 | void loop() { 21 | delay(100); 22 | } 23 | 24 | // function that executes whenever data is requested by master 25 | // this function is registered as an event, see setup() 26 | void requestEvent() { 27 | Wire.write("hello "); // respond with message of 6 bytes 28 | // as expected by master 29 | } 30 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Wire 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | ####################################### 10 | # Methods and Functions (KEYWORD2) 11 | ####################################### 12 | 13 | begin KEYWORD2 14 | setClock KEYWORD2 15 | beginTransmission KEYWORD2 16 | endTransmission KEYWORD2 17 | requestFrom KEYWORD2 18 | onReceive KEYWORD2 19 | onRequest KEYWORD2 20 | 21 | ####################################### 22 | # Instances (KEYWORD2) 23 | ####################################### 24 | 25 | Wire KEYWORD2 26 | 27 | ####################################### 28 | # Constants (LITERAL1) 29 | ####################################### 30 | 31 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire/library.properties: -------------------------------------------------------------------------------- 1 | name=Wire 2 | version=1.0 3 | author=Arduino 4 | maintainer=Arduino 5 | sentence=This library allows you to communicate with I2C and Two Wire Interface devices. 6 | paragraph=It allows the communication with I2C devices like temperature sensors, realtime clocks and many others using SDA (Data Line) and SCL (Clock Line). 7 | category=Communication 8 | url=http://www.arduino.cc/en/Reference/Wire 9 | architectures=avr 10 | 11 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire/src/Wire.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | TwoWire.cpp - TWI/I2C library for Wiring & Arduino 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts 20 | */ 21 | 22 | extern "C" { 23 | #include 24 | #include 25 | #include 26 | #include "utility/twi.h" 27 | } 28 | 29 | #include "Wire.h" 30 | 31 | // Initialize Class Variables ////////////////////////////////////////////////// 32 | 33 | uint8_t TwoWire::rxBuffer[BUFFER_LENGTH]; 34 | uint8_t TwoWire::rxBufferIndex = 0; 35 | uint8_t TwoWire::rxBufferLength = 0; 36 | 37 | uint8_t TwoWire::txAddress = 0; 38 | uint8_t TwoWire::txBuffer[BUFFER_LENGTH]; 39 | uint8_t TwoWire::txBufferIndex = 0; 40 | uint8_t TwoWire::txBufferLength = 0; 41 | 42 | uint8_t TwoWire::transmitting = 0; 43 | void (*TwoWire::user_onRequest)(void); 44 | void (*TwoWire::user_onReceive)(int); 45 | 46 | // Constructors //////////////////////////////////////////////////////////////// 47 | 48 | TwoWire::TwoWire() 49 | { 50 | } 51 | 52 | // Public Methods ////////////////////////////////////////////////////////////// 53 | 54 | void TwoWire::begin(void) 55 | { 56 | rxBufferIndex = 0; 57 | rxBufferLength = 0; 58 | 59 | txBufferIndex = 0; 60 | txBufferLength = 0; 61 | 62 | twi_init(); 63 | } 64 | 65 | void TwoWire::begin(uint8_t address) 66 | { 67 | twi_setAddress(address); 68 | twi_attachSlaveTxEvent(onRequestService); 69 | twi_attachSlaveRxEvent(onReceiveService); 70 | begin(); 71 | } 72 | 73 | void TwoWire::begin(int address) 74 | { 75 | begin((uint8_t)address); 76 | } 77 | 78 | void TwoWire::end(void) 79 | { 80 | twi_disable(); 81 | } 82 | 83 | void TwoWire::setClock(uint32_t frequency) 84 | { 85 | TWBR = ((F_CPU / frequency) - 16) / 2; 86 | } 87 | 88 | uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop) 89 | { 90 | if (isize > 0) { 91 | // send internal address; this mode allows sending a repeated start to access 92 | // some devices' internal registers. This function is executed by the hardware 93 | // TWI module on other processors (for example Due's TWI_IADR and TWI_MMR registers) 94 | 95 | beginTransmission(address); 96 | 97 | // the maximum size of internal address is 3 bytes 98 | if (isize > 3){ 99 | isize = 3; 100 | } 101 | 102 | // write internal register address - most significant byte first 103 | while (isize-- > 0) 104 | write((uint8_t)(iaddress >> (isize*8))); 105 | endTransmission(false); 106 | } 107 | 108 | // clamp to buffer length 109 | if(quantity > BUFFER_LENGTH){ 110 | quantity = BUFFER_LENGTH; 111 | } 112 | // perform blocking read into buffer 113 | uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop); 114 | // set rx buffer iterator vars 115 | rxBufferIndex = 0; 116 | rxBufferLength = read; 117 | 118 | return read; 119 | } 120 | 121 | uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) { 122 | return requestFrom((uint8_t)address, (uint8_t)quantity, (uint32_t)0, (uint8_t)0, (uint8_t)sendStop); 123 | } 124 | 125 | uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity) 126 | { 127 | return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true); 128 | } 129 | 130 | uint8_t TwoWire::requestFrom(int address, int quantity) 131 | { 132 | return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true); 133 | } 134 | 135 | uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop) 136 | { 137 | return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop); 138 | } 139 | 140 | void TwoWire::beginTransmission(uint8_t address) 141 | { 142 | // indicate that we are transmitting 143 | transmitting = 1; 144 | // set address of targeted slave 145 | txAddress = address; 146 | // reset tx buffer iterator vars 147 | txBufferIndex = 0; 148 | txBufferLength = 0; 149 | } 150 | 151 | void TwoWire::beginTransmission(int address) 152 | { 153 | beginTransmission((uint8_t)address); 154 | } 155 | 156 | // 157 | // Originally, 'endTransmission' was an f(void) function. 158 | // It has been modified to take one parameter indicating 159 | // whether or not a STOP should be performed on the bus. 160 | // Calling endTransmission(false) allows a sketch to 161 | // perform a repeated start. 162 | // 163 | // WARNING: Nothing in the library keeps track of whether 164 | // the bus tenure has been properly ended with a STOP. It 165 | // is very possible to leave the bus in a hung state if 166 | // no call to endTransmission(true) is made. Some I2C 167 | // devices will behave oddly if they do not see a STOP. 168 | // 169 | uint8_t TwoWire::endTransmission(uint8_t sendStop) 170 | { 171 | // transmit buffer (blocking) 172 | uint8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop); 173 | // reset tx buffer iterator vars 174 | txBufferIndex = 0; 175 | txBufferLength = 0; 176 | // indicate that we are done transmitting 177 | transmitting = 0; 178 | return ret; 179 | } 180 | 181 | // This provides backwards compatibility with the original 182 | // definition, and expected behaviour, of endTransmission 183 | // 184 | uint8_t TwoWire::endTransmission(void) 185 | { 186 | return endTransmission(true); 187 | } 188 | 189 | // must be called in: 190 | // slave tx event callback 191 | // or after beginTransmission(address) 192 | size_t TwoWire::write(uint8_t data) 193 | { 194 | if(transmitting){ 195 | // in master transmitter mode 196 | // don't bother if buffer is full 197 | if(txBufferLength >= BUFFER_LENGTH){ 198 | setWriteError(); 199 | return 0; 200 | } 201 | // put byte in tx buffer 202 | txBuffer[txBufferIndex] = data; 203 | ++txBufferIndex; 204 | // update amount in buffer 205 | txBufferLength = txBufferIndex; 206 | }else{ 207 | // in slave send mode 208 | // reply to master 209 | twi_transmit(&data, 1); 210 | } 211 | return 1; 212 | } 213 | 214 | // must be called in: 215 | // slave tx event callback 216 | // or after beginTransmission(address) 217 | size_t TwoWire::write(const uint8_t *data, size_t quantity) 218 | { 219 | if(transmitting){ 220 | // in master transmitter mode 221 | for(size_t i = 0; i < quantity; ++i){ 222 | write(data[i]); 223 | } 224 | }else{ 225 | // in slave send mode 226 | // reply to master 227 | twi_transmit(data, quantity); 228 | } 229 | return quantity; 230 | } 231 | 232 | // must be called in: 233 | // slave rx event callback 234 | // or after requestFrom(address, numBytes) 235 | int TwoWire::available(void) 236 | { 237 | return rxBufferLength - rxBufferIndex; 238 | } 239 | 240 | // must be called in: 241 | // slave rx event callback 242 | // or after requestFrom(address, numBytes) 243 | int TwoWire::read(void) 244 | { 245 | int value = -1; 246 | 247 | // get each successive byte on each call 248 | if(rxBufferIndex < rxBufferLength){ 249 | value = rxBuffer[rxBufferIndex]; 250 | ++rxBufferIndex; 251 | } 252 | 253 | return value; 254 | } 255 | 256 | // must be called in: 257 | // slave rx event callback 258 | // or after requestFrom(address, numBytes) 259 | int TwoWire::peek(void) 260 | { 261 | int value = -1; 262 | 263 | if(rxBufferIndex < rxBufferLength){ 264 | value = rxBuffer[rxBufferIndex]; 265 | } 266 | 267 | return value; 268 | } 269 | 270 | void TwoWire::flush(void) 271 | { 272 | // XXX: to be implemented. 273 | } 274 | 275 | // behind the scenes function that is called when data is received 276 | void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes) 277 | { 278 | // don't bother if user hasn't registered a callback 279 | if(!user_onReceive){ 280 | return; 281 | } 282 | // don't bother if rx buffer is in use by a master requestFrom() op 283 | // i know this drops data, but it allows for slight stupidity 284 | // meaning, they may not have read all the master requestFrom() data yet 285 | if(rxBufferIndex < rxBufferLength){ 286 | return; 287 | } 288 | // copy twi rx buffer into local read buffer 289 | // this enables new reads to happen in parallel 290 | for(uint8_t i = 0; i < numBytes; ++i){ 291 | rxBuffer[i] = inBytes[i]; 292 | } 293 | // set rx iterator vars 294 | rxBufferIndex = 0; 295 | rxBufferLength = numBytes; 296 | // alert user program 297 | user_onReceive(numBytes); 298 | } 299 | 300 | // behind the scenes function that is called when data is requested 301 | void TwoWire::onRequestService(void) 302 | { 303 | // don't bother if user hasn't registered a callback 304 | if(!user_onRequest){ 305 | return; 306 | } 307 | // reset tx buffer iterator vars 308 | // !!! this will kill any pending pre-master sendTo() activity 309 | txBufferIndex = 0; 310 | txBufferLength = 0; 311 | // alert user program 312 | user_onRequest(); 313 | } 314 | 315 | // sets function called on slave write 316 | void TwoWire::onReceive( void (*function)(int) ) 317 | { 318 | user_onReceive = function; 319 | } 320 | 321 | // sets function called on slave read 322 | void TwoWire::onRequest( void (*function)(void) ) 323 | { 324 | user_onRequest = function; 325 | } 326 | 327 | // Preinstantiate Objects ////////////////////////////////////////////////////// 328 | 329 | TwoWire Wire = TwoWire(); 330 | 331 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire/src/Wire.h: -------------------------------------------------------------------------------- 1 | /* 2 | TwoWire.h - TWI/I2C library for Arduino & Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts 20 | */ 21 | 22 | #ifndef TwoWire_h 23 | #define TwoWire_h 24 | 25 | #include 26 | #include "Stream.h" 27 | 28 | #define BUFFER_LENGTH 32 29 | 30 | // WIRE_HAS_END means Wire has end() 31 | #define WIRE_HAS_END 1 32 | 33 | class TwoWire : public Stream 34 | { 35 | private: 36 | static uint8_t rxBuffer[]; 37 | static uint8_t rxBufferIndex; 38 | static uint8_t rxBufferLength; 39 | 40 | static uint8_t txAddress; 41 | static uint8_t txBuffer[]; 42 | static uint8_t txBufferIndex; 43 | static uint8_t txBufferLength; 44 | 45 | static uint8_t transmitting; 46 | static void (*user_onRequest)(void); 47 | static void (*user_onReceive)(int); 48 | static void onRequestService(void); 49 | static void onReceiveService(uint8_t*, int); 50 | public: 51 | TwoWire(); 52 | void begin(); 53 | void begin(uint8_t); 54 | void begin(int); 55 | void end(); 56 | void setClock(uint32_t); 57 | void beginTransmission(uint8_t); 58 | void beginTransmission(int); 59 | uint8_t endTransmission(void); 60 | uint8_t endTransmission(uint8_t); 61 | uint8_t requestFrom(uint8_t, uint8_t); 62 | uint8_t requestFrom(uint8_t, uint8_t, uint8_t); 63 | uint8_t requestFrom(uint8_t, uint8_t, uint32_t, uint8_t, uint8_t); 64 | uint8_t requestFrom(int, int); 65 | uint8_t requestFrom(int, int, int); 66 | virtual size_t write(uint8_t); 67 | virtual size_t write(const uint8_t *, size_t); 68 | virtual int available(void); 69 | virtual int read(void); 70 | virtual int peek(void); 71 | virtual void flush(void); 72 | void onReceive( void (*)(int) ); 73 | void onRequest( void (*)(void) ); 74 | 75 | inline size_t write(unsigned long n) { return write((uint8_t)n); } 76 | inline size_t write(long n) { return write((uint8_t)n); } 77 | inline size_t write(unsigned int n) { return write((uint8_t)n); } 78 | inline size_t write(int n) { return write((uint8_t)n); } 79 | using Print::write; 80 | }; 81 | 82 | extern TwoWire Wire; 83 | 84 | #endif 85 | 86 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire/src/utility/twi.c: -------------------------------------------------------------------------------- 1 | /* 2 | twi.c - TWI/I2C library for Wiring & Arduino 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "Arduino.h" // for digitalWrite 29 | #include "pins_arduino.h" 30 | #include "twi.h" 31 | 32 | #ifndef cbi 33 | #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 34 | #endif 35 | 36 | #ifndef sbi 37 | #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) 38 | #endif 39 | 40 | static volatile uint8_t twi_state; 41 | static volatile uint8_t twi_slarw; 42 | static volatile uint8_t twi_sendStop; // should the transaction end with a stop 43 | static volatile uint8_t twi_inRepStart; // in the middle of a repeated start 44 | 45 | static void (*twi_onSlaveTransmit)(void); 46 | static void (*twi_onSlaveReceive)(uint8_t*, int); 47 | 48 | static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; 49 | static volatile uint8_t twi_masterBufferIndex; 50 | static volatile uint8_t twi_masterBufferLength; 51 | 52 | static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH]; 53 | static volatile uint8_t twi_txBufferIndex; 54 | static volatile uint8_t twi_txBufferLength; 55 | 56 | static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; 57 | static volatile uint8_t twi_rxBufferIndex; 58 | 59 | static volatile uint8_t twi_error; 60 | 61 | /* 62 | * Function twi_init 63 | * Desc readys twi pins and sets twi bitrate 64 | * Input none 65 | * Output none 66 | */ 67 | void twi_init(void) 68 | { 69 | // initialize state 70 | twi_state = TWI_READY; 71 | twi_sendStop = true; // default value 72 | twi_inRepStart = false; 73 | 74 | // activate internal pullups for twi. 75 | digitalWrite(SDA, 1); 76 | digitalWrite(SCL, 1); 77 | 78 | // initialize twi prescaler and bit rate 79 | cbi(TWSR, TWPS0); 80 | cbi(TWSR, TWPS1); 81 | TWBR = ((F_CPU / TWI_FREQ) - 16) / 2; 82 | 83 | /* twi bit rate formula from atmega128 manual pg 204 84 | SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) 85 | note: TWBR should be 10 or higher for master mode 86 | It is 72 for a 16mhz Wiring board with 100kHz TWI */ 87 | 88 | // enable twi module, acks, and twi interrupt 89 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); 90 | } 91 | 92 | /* 93 | * Function twi_disable 94 | * Desc disables twi pins 95 | * Input none 96 | * Output none 97 | */ 98 | void twi_disable(void) 99 | { 100 | // disable twi module, acks, and twi interrupt 101 | TWCR &= ~(_BV(TWEN) | _BV(TWIE) | _BV(TWEA)); 102 | 103 | // deactivate internal pullups for twi. 104 | digitalWrite(SDA, 0); 105 | digitalWrite(SCL, 0); 106 | } 107 | 108 | /* 109 | * Function twi_slaveInit 110 | * Desc sets slave address and enables interrupt 111 | * Input none 112 | * Output none 113 | */ 114 | void twi_setAddress(uint8_t address) 115 | { 116 | // set twi slave address (skip over TWGCE bit) 117 | TWAR = address << 1; 118 | } 119 | 120 | /* 121 | * Function twi_readFrom 122 | * Desc attempts to become twi bus master and read a 123 | * series of bytes from a device on the bus 124 | * Input address: 7bit i2c device address 125 | * data: pointer to byte array 126 | * length: number of bytes to read into array 127 | * sendStop: Boolean indicating whether to send a stop at the end 128 | * Output number of bytes read 129 | */ 130 | uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) 131 | { 132 | uint8_t i; 133 | 134 | // ensure data will fit into buffer 135 | if(TWI_BUFFER_LENGTH < length){ 136 | return 0; 137 | } 138 | 139 | // wait until twi is ready, become master receiver 140 | while(TWI_READY != twi_state){ 141 | continue; 142 | } 143 | twi_state = TWI_MRX; 144 | twi_sendStop = sendStop; 145 | // reset error state (0xFF.. no error occured) 146 | twi_error = 0xFF; 147 | 148 | // initialize buffer iteration vars 149 | twi_masterBufferIndex = 0; 150 | twi_masterBufferLength = length-1; // This is not intuitive, read on... 151 | // On receive, the previously configured ACK/NACK setting is transmitted in 152 | // response to the received byte before the interrupt is signalled. 153 | // Therefor we must actually set NACK when the _next_ to last byte is 154 | // received, causing that NACK to be sent in response to receiving the last 155 | // expected byte of data. 156 | 157 | // build sla+w, slave device address + w bit 158 | twi_slarw = TW_READ; 159 | twi_slarw |= address << 1; 160 | 161 | if (true == twi_inRepStart) { 162 | // if we're in the repeated start state, then we've already sent the start, 163 | // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. 164 | // We need to remove ourselves from the repeated start state before we enable interrupts, 165 | // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning 166 | // up. Also, don't enable the START interrupt. There may be one pending from the 167 | // repeated start that we sent ourselves, and that would really confuse things. 168 | twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR 169 | do { 170 | TWDR = twi_slarw; 171 | } while(TWCR & _BV(TWWC)); 172 | TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START 173 | } 174 | else 175 | // send start condition 176 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); 177 | 178 | // wait for read operation to complete 179 | while(TWI_MRX == twi_state){ 180 | continue; 181 | } 182 | 183 | if (twi_masterBufferIndex < length) 184 | length = twi_masterBufferIndex; 185 | 186 | // copy twi buffer to data 187 | for(i = 0; i < length; ++i){ 188 | data[i] = twi_masterBuffer[i]; 189 | } 190 | 191 | return length; 192 | } 193 | 194 | /* 195 | * Function twi_writeTo 196 | * Desc attempts to become twi bus master and write a 197 | * series of bytes to a device on the bus 198 | * Input address: 7bit i2c device address 199 | * data: pointer to byte array 200 | * length: number of bytes in array 201 | * wait: boolean indicating to wait for write or not 202 | * sendStop: boolean indicating whether or not to send a stop at the end 203 | * Output 0 .. success 204 | * 1 .. length to long for buffer 205 | * 2 .. address send, NACK received 206 | * 3 .. data send, NACK received 207 | * 4 .. other twi error (lost bus arbitration, bus error, ..) 208 | */ 209 | uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop) 210 | { 211 | uint8_t i; 212 | 213 | // ensure data will fit into buffer 214 | if(TWI_BUFFER_LENGTH < length){ 215 | return 1; 216 | } 217 | 218 | // wait until twi is ready, become master transmitter 219 | while(TWI_READY != twi_state){ 220 | continue; 221 | } 222 | twi_state = TWI_MTX; 223 | twi_sendStop = sendStop; 224 | // reset error state (0xFF.. no error occured) 225 | twi_error = 0xFF; 226 | 227 | // initialize buffer iteration vars 228 | twi_masterBufferIndex = 0; 229 | twi_masterBufferLength = length; 230 | 231 | // copy data to twi buffer 232 | for(i = 0; i < length; ++i){ 233 | twi_masterBuffer[i] = data[i]; 234 | } 235 | 236 | // build sla+w, slave device address + w bit 237 | twi_slarw = TW_WRITE; 238 | twi_slarw |= address << 1; 239 | 240 | // if we're in a repeated start, then we've already sent the START 241 | // in the ISR. Don't do it again. 242 | // 243 | if (true == twi_inRepStart) { 244 | // if we're in the repeated start state, then we've already sent the start, 245 | // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. 246 | // We need to remove ourselves from the repeated start state before we enable interrupts, 247 | // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning 248 | // up. Also, don't enable the START interrupt. There may be one pending from the 249 | // repeated start that we sent outselves, and that would really confuse things. 250 | twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR 251 | do { 252 | TWDR = twi_slarw; 253 | } while(TWCR & _BV(TWWC)); 254 | TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START 255 | } 256 | else 257 | // send start condition 258 | TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs 259 | 260 | // wait for write operation to complete 261 | while(wait && (TWI_MTX == twi_state)){ 262 | continue; 263 | } 264 | 265 | if (twi_error == 0xFF) 266 | return 0; // success 267 | else if (twi_error == TW_MT_SLA_NACK) 268 | return 2; // error: address send, nack received 269 | else if (twi_error == TW_MT_DATA_NACK) 270 | return 3; // error: data send, nack received 271 | else 272 | return 4; // other twi error 273 | } 274 | 275 | /* 276 | * Function twi_transmit 277 | * Desc fills slave tx buffer with data 278 | * must be called in slave tx event callback 279 | * Input data: pointer to byte array 280 | * length: number of bytes in array 281 | * Output 1 length too long for buffer 282 | * 2 not slave transmitter 283 | * 0 ok 284 | */ 285 | uint8_t twi_transmit(const uint8_t* data, uint8_t length) 286 | { 287 | uint8_t i; 288 | 289 | // ensure data will fit into buffer 290 | if(TWI_BUFFER_LENGTH < length){ 291 | return 1; 292 | } 293 | 294 | // ensure we are currently a slave transmitter 295 | if(TWI_STX != twi_state){ 296 | return 2; 297 | } 298 | 299 | // set length and copy data into tx buffer 300 | twi_txBufferLength = length; 301 | for(i = 0; i < length; ++i){ 302 | twi_txBuffer[i] = data[i]; 303 | } 304 | 305 | return 0; 306 | } 307 | 308 | /* 309 | * Function twi_attachSlaveRxEvent 310 | * Desc sets function called before a slave read operation 311 | * Input function: callback function to use 312 | * Output none 313 | */ 314 | void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) ) 315 | { 316 | twi_onSlaveReceive = function; 317 | } 318 | 319 | /* 320 | * Function twi_attachSlaveTxEvent 321 | * Desc sets function called before a slave write operation 322 | * Input function: callback function to use 323 | * Output none 324 | */ 325 | void twi_attachSlaveTxEvent( void (*function)(void) ) 326 | { 327 | twi_onSlaveTransmit = function; 328 | } 329 | 330 | /* 331 | * Function twi_reply 332 | * Desc sends byte or readys receive line 333 | * Input ack: byte indicating to ack or to nack 334 | * Output none 335 | */ 336 | void twi_reply(uint8_t ack) 337 | { 338 | // transmit master read ready signal, with or without ack 339 | if(ack){ 340 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); 341 | }else{ 342 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT); 343 | } 344 | } 345 | 346 | /* 347 | * Function twi_stop 348 | * Desc relinquishes bus master status 349 | * Input none 350 | * Output none 351 | */ 352 | void twi_stop(void) 353 | { 354 | // send stop condition 355 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO); 356 | 357 | // wait for stop condition to be exectued on bus 358 | // TWINT is not set after a stop condition! 359 | while(TWCR & _BV(TWSTO)){ 360 | continue; 361 | } 362 | 363 | // update twi state 364 | twi_state = TWI_READY; 365 | } 366 | 367 | /* 368 | * Function twi_releaseBus 369 | * Desc releases bus control 370 | * Input none 371 | * Output none 372 | */ 373 | void twi_releaseBus(void) 374 | { 375 | // release bus 376 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT); 377 | 378 | // update twi state 379 | twi_state = TWI_READY; 380 | } 381 | 382 | ISR(TWI_vect) 383 | { 384 | switch(TW_STATUS){ 385 | // All Master 386 | case TW_START: // sent start condition 387 | case TW_REP_START: // sent repeated start condition 388 | // copy device address and r/w bit to output register and ack 389 | TWDR = twi_slarw; 390 | twi_reply(1); 391 | break; 392 | 393 | // Master Transmitter 394 | case TW_MT_SLA_ACK: // slave receiver acked address 395 | case TW_MT_DATA_ACK: // slave receiver acked data 396 | // if there is data to send, send it, otherwise stop 397 | if(twi_masterBufferIndex < twi_masterBufferLength){ 398 | // copy data to output register and ack 399 | TWDR = twi_masterBuffer[twi_masterBufferIndex++]; 400 | twi_reply(1); 401 | }else{ 402 | if (twi_sendStop) 403 | twi_stop(); 404 | else { 405 | twi_inRepStart = true; // we're gonna send the START 406 | // don't enable the interrupt. We'll generate the start, but we 407 | // avoid handling the interrupt until we're in the next transaction, 408 | // at the point where we would normally issue the start. 409 | TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; 410 | twi_state = TWI_READY; 411 | } 412 | } 413 | break; 414 | case TW_MT_SLA_NACK: // address sent, nack received 415 | twi_error = TW_MT_SLA_NACK; 416 | twi_stop(); 417 | break; 418 | case TW_MT_DATA_NACK: // data sent, nack received 419 | twi_error = TW_MT_DATA_NACK; 420 | twi_stop(); 421 | break; 422 | case TW_MT_ARB_LOST: // lost bus arbitration 423 | twi_error = TW_MT_ARB_LOST; 424 | twi_releaseBus(); 425 | break; 426 | 427 | // Master Receiver 428 | case TW_MR_DATA_ACK: // data received, ack sent 429 | // put byte into buffer 430 | twi_masterBuffer[twi_masterBufferIndex++] = TWDR; 431 | case TW_MR_SLA_ACK: // address sent, ack received 432 | // ack if more bytes are expected, otherwise nack 433 | if(twi_masterBufferIndex < twi_masterBufferLength){ 434 | twi_reply(1); 435 | }else{ 436 | twi_reply(0); 437 | } 438 | break; 439 | case TW_MR_DATA_NACK: // data received, nack sent 440 | // put final byte into buffer 441 | twi_masterBuffer[twi_masterBufferIndex++] = TWDR; 442 | if (twi_sendStop) 443 | twi_stop(); 444 | else { 445 | twi_inRepStart = true; // we're gonna send the START 446 | // don't enable the interrupt. We'll generate the start, but we 447 | // avoid handling the interrupt until we're in the next transaction, 448 | // at the point where we would normally issue the start. 449 | TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; 450 | twi_state = TWI_READY; 451 | } 452 | break; 453 | case TW_MR_SLA_NACK: // address sent, nack received 454 | twi_stop(); 455 | break; 456 | // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case 457 | 458 | // Slave Receiver 459 | case TW_SR_SLA_ACK: // addressed, returned ack 460 | case TW_SR_GCALL_ACK: // addressed generally, returned ack 461 | case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack 462 | case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack 463 | // enter slave receiver mode 464 | twi_state = TWI_SRX; 465 | // indicate that rx buffer can be overwritten and ack 466 | twi_rxBufferIndex = 0; 467 | twi_reply(1); 468 | break; 469 | case TW_SR_DATA_ACK: // data received, returned ack 470 | case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack 471 | // if there is still room in the rx buffer 472 | if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ 473 | // put byte in buffer and ack 474 | twi_rxBuffer[twi_rxBufferIndex++] = TWDR; 475 | twi_reply(1); 476 | }else{ 477 | // otherwise nack 478 | twi_reply(0); 479 | } 480 | break; 481 | case TW_SR_STOP: // stop or repeated start condition received 482 | // ack future responses and leave slave receiver state 483 | twi_releaseBus(); 484 | // put a null char after data if there's room 485 | if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ 486 | twi_rxBuffer[twi_rxBufferIndex] = '\0'; 487 | } 488 | // callback to user defined callback 489 | twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); 490 | // since we submit rx buffer to "wire" library, we can reset it 491 | twi_rxBufferIndex = 0; 492 | break; 493 | case TW_SR_DATA_NACK: // data received, returned nack 494 | case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack 495 | // nack back at master 496 | twi_reply(0); 497 | break; 498 | 499 | // Slave Transmitter 500 | case TW_ST_SLA_ACK: // addressed, returned ack 501 | case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack 502 | // enter slave transmitter mode 503 | twi_state = TWI_STX; 504 | // ready the tx buffer index for iteration 505 | twi_txBufferIndex = 0; 506 | // set tx buffer length to be zero, to verify if user changes it 507 | twi_txBufferLength = 0; 508 | // request for txBuffer to be filled and length to be set 509 | // note: user must call twi_transmit(bytes, length) to do this 510 | twi_onSlaveTransmit(); 511 | // if they didn't change buffer & length, initialize it 512 | if(0 == twi_txBufferLength){ 513 | twi_txBufferLength = 1; 514 | twi_txBuffer[0] = 0x00; 515 | } 516 | // transmit first byte from buffer, fall 517 | case TW_ST_DATA_ACK: // byte sent, ack returned 518 | // copy data to output register 519 | TWDR = twi_txBuffer[twi_txBufferIndex++]; 520 | // if there is more to send, ack, otherwise nack 521 | if(twi_txBufferIndex < twi_txBufferLength){ 522 | twi_reply(1); 523 | }else{ 524 | twi_reply(0); 525 | } 526 | break; 527 | case TW_ST_DATA_NACK: // received nack, we are done 528 | case TW_ST_LAST_DATA: // received ack, but we are done already! 529 | // ack future responses 530 | twi_reply(1); 531 | // leave slave receiver state 532 | twi_state = TWI_READY; 533 | break; 534 | 535 | // All 536 | case TW_NO_INFO: // no state information 537 | break; 538 | case TW_BUS_ERROR: // bus error, illegal stop/start 539 | twi_error = TW_BUS_ERROR; 540 | twi_stop(); 541 | break; 542 | } 543 | } 544 | 545 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire/src/utility/twi.h: -------------------------------------------------------------------------------- 1 | /* 2 | twi.h - TWI/I2C library for Wiring & Arduino 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef twi_h 21 | #define twi_h 22 | 23 | #include 24 | 25 | #ifndef TWBR 26 | #define TWBR TWBR0 //_SFR_MEM8(0xB8) 27 | #define TWSR TWSR0 //_SFR_MEM8(0xB9) 28 | #define TWAR TWAR0 //_SFR_MEM8(0xBA) 29 | #define TWDR TWDR0 //_SFR_MEM8(0xBB) 30 | #define TWCR TWCR0 //_SFR_MEM8(0xBC) 31 | #define TWAMR TWAMR0 //_SFR_MEM8(0xBD) 32 | #define TWI_vect_num TWI0_vect_num //24 33 | #define TWI_vect TWI0_vect //_VECTOR(24) 34 | #endif 35 | 36 | #ifndef TWI_FREQ 37 | #define TWI_FREQ 100000L 38 | #endif 39 | 40 | #ifndef TWI_BUFFER_LENGTH 41 | #define TWI_BUFFER_LENGTH 32 42 | #endif 43 | 44 | #define TWI_READY 0 45 | #define TWI_MRX 1 46 | #define TWI_MTX 2 47 | #define TWI_SRX 3 48 | #define TWI_STX 4 49 | 50 | void twi_init(void); 51 | void twi_disable(void); 52 | void twi_setAddress(uint8_t); 53 | uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t); 54 | uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t); 55 | uint8_t twi_transmit(const uint8_t*, uint8_t); 56 | void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) ); 57 | void twi_attachSlaveTxEvent( void (*)(void) ); 58 | void twi_reply(uint8_t); 59 | void twi_stop(void); 60 | void twi_releaseBus(void); 61 | 62 | #endif 63 | 64 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire1/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Wire 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | ####################################### 10 | # Methods and Functions (KEYWORD2) 11 | ####################################### 12 | 13 | begin KEYWORD2 14 | setClock KEYWORD2 15 | beginTransmission KEYWORD2 16 | endTransmission KEYWORD2 17 | requestFrom KEYWORD2 18 | onReceive KEYWORD2 19 | onRequest KEYWORD2 20 | 21 | ####################################### 22 | # Instances (KEYWORD2) 23 | ####################################### 24 | 25 | Wire KEYWORD2 26 | Wire1 KEYWORD2 27 | 28 | ####################################### 29 | # Constants (LITERAL1) 30 | ####################################### 31 | 32 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire1/library.properties: -------------------------------------------------------------------------------- 1 | name=Wire1 2 | version=1.0 3 | author=Arduino 4 | maintainer=Arduino 5 | sentence=This library allows you to communicate with I2C and Two Wire Interface devices. 6 | paragraph=It allows the communication with I2C devices like temperature sensors, realtime clocks and many others using SDA (Data Line) and SCL (Clock Line). 7 | category=Communication 8 | url=http://www.arduino.cc/en/Reference/Wire 9 | architectures=avr 10 | 11 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire1/src/Wire1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | TwoWire.cpp - TWI/I2C library for Wiring & Arduino 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts 20 | */ 21 | 22 | extern "C" { 23 | #include 24 | #include 25 | #include 26 | #include "utility/twi1.h" 27 | } 28 | 29 | //328PB test 30 | # if !defined(__AVR_ATmega328PB__) 31 | #error "Only for 328PB" 32 | #endif 33 | 34 | #include "Wire1.h" 35 | 36 | // Initialize Class Variables ////////////////////////////////////////////////// 37 | 38 | uint8_t TwoWire1::rxBuffer[BUFFER_LENGTH]; 39 | uint8_t TwoWire1::rxBufferIndex = 0; 40 | uint8_t TwoWire1::rxBufferLength = 0; 41 | 42 | uint8_t TwoWire1::txAddress = 0; 43 | uint8_t TwoWire1::txBuffer[BUFFER_LENGTH]; 44 | uint8_t TwoWire1::txBufferIndex = 0; 45 | uint8_t TwoWire1::txBufferLength = 0; 46 | 47 | uint8_t TwoWire1::transmitting = 0; 48 | void (*TwoWire1::user_onRequest)(void); 49 | void (*TwoWire1::user_onReceive)(int); 50 | 51 | // Constructors //////////////////////////////////////////////////////////////// 52 | 53 | TwoWire1::TwoWire1() 54 | { 55 | } 56 | 57 | // Public Methods ////////////////////////////////////////////////////////////// 58 | 59 | void TwoWire1::begin(void) 60 | { 61 | rxBufferIndex = 0; 62 | rxBufferLength = 0; 63 | 64 | txBufferIndex = 0; 65 | txBufferLength = 0; 66 | 67 | twi_init1(); 68 | } 69 | 70 | void TwoWire1::begin(uint8_t address) 71 | { 72 | twi_setAddress1(address); 73 | twi_attachSlaveTxEvent1(onRequestService); 74 | twi_attachSlaveRxEvent1(onReceiveService); 75 | begin(); 76 | } 77 | 78 | void TwoWire1::begin(int address) 79 | { 80 | begin((uint8_t)address); 81 | } 82 | 83 | void TwoWire1::end(void) 84 | { 85 | twi_disable1(); 86 | } 87 | 88 | void TwoWire1::setClock(uint32_t frequency) 89 | { 90 | TWBR1 = ((F_CPU / frequency) - 16) / 2; 91 | } 92 | 93 | uint8_t TwoWire1::requestFrom(uint8_t address, uint8_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop) 94 | { 95 | if (isize > 0) { 96 | // send internal address; this mode allows sending a repeated start to access 97 | // some devices' internal registers. This function is executed by the hardware 98 | // TWI module on other processors (for example Due's TWI_IADR and TWI_MMR registers) 99 | 100 | beginTransmission(address); 101 | 102 | // the maximum size of internal address is 3 bytes 103 | if (isize > 3){ 104 | isize = 3; 105 | } 106 | 107 | // write internal register address - most significant byte first 108 | while (isize-- > 0) 109 | write((uint8_t)(iaddress >> (isize*8))); 110 | endTransmission(false); 111 | } 112 | 113 | // clamp to buffer length 114 | if(quantity > BUFFER_LENGTH){ 115 | quantity = BUFFER_LENGTH; 116 | } 117 | // perform blocking read into buffer 118 | uint8_t read = twi_readFrom1(address, rxBuffer, quantity, sendStop); 119 | // set rx buffer iterator vars 120 | rxBufferIndex = 0; 121 | rxBufferLength = read; 122 | 123 | return read; 124 | } 125 | 126 | uint8_t TwoWire1::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) { 127 | return requestFrom((uint8_t)address, (uint8_t)quantity, (uint32_t)0, (uint8_t)0, (uint8_t)sendStop); 128 | } 129 | 130 | uint8_t TwoWire1::requestFrom(uint8_t address, uint8_t quantity) 131 | { 132 | return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true); 133 | } 134 | 135 | uint8_t TwoWire1::requestFrom(int address, int quantity) 136 | { 137 | return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true); 138 | } 139 | 140 | uint8_t TwoWire1::requestFrom(int address, int quantity, int sendStop) 141 | { 142 | return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop); 143 | } 144 | 145 | void TwoWire1::beginTransmission(uint8_t address) 146 | { 147 | // indicate that we are transmitting 148 | transmitting = 1; 149 | // set address of targeted slave 150 | txAddress = address; 151 | // reset tx buffer iterator vars 152 | txBufferIndex = 0; 153 | txBufferLength = 0; 154 | } 155 | 156 | void TwoWire1::beginTransmission(int address) 157 | { 158 | beginTransmission((uint8_t)address); 159 | } 160 | 161 | // 162 | // Originally, 'endTransmission' was an f(void) function. 163 | // It has been modified to take one parameter indicating 164 | // whether or not a STOP should be performed on the bus. 165 | // Calling endTransmission(false) allows a sketch to 166 | // perform a repeated start. 167 | // 168 | // WARNING: Nothing in the library keeps track of whether 169 | // the bus tenure has been properly ended with a STOP. It 170 | // is very possible to leave the bus in a hung state if 171 | // no call to endTransmission(true) is made. Some I2C 172 | // devices will behave oddly if they do not see a STOP. 173 | // 174 | uint8_t TwoWire1::endTransmission(uint8_t sendStop) 175 | { 176 | // transmit buffer (blocking) 177 | uint8_t ret = twi_writeTo1(txAddress, txBuffer, txBufferLength, 1, sendStop); 178 | // reset tx buffer iterator vars 179 | txBufferIndex = 0; 180 | txBufferLength = 0; 181 | // indicate that we are done transmitting 182 | transmitting = 0; 183 | return ret; 184 | } 185 | 186 | // This provides backwards compatibility with the original 187 | // definition, and expected behaviour, of endTransmission 188 | // 189 | uint8_t TwoWire1::endTransmission(void) 190 | { 191 | return endTransmission(true); 192 | } 193 | 194 | // must be called in: 195 | // slave tx event callback 196 | // or after beginTransmission(address) 197 | size_t TwoWire1::write(uint8_t data) 198 | { 199 | if(transmitting){ 200 | // in master transmitter mode 201 | // don't bother if buffer is full 202 | if(txBufferLength >= BUFFER_LENGTH){ 203 | setWriteError(); 204 | return 0; 205 | } 206 | // put byte in tx buffer 207 | txBuffer[txBufferIndex] = data; 208 | ++txBufferIndex; 209 | // update amount in buffer 210 | txBufferLength = txBufferIndex; 211 | }else{ 212 | // in slave send mode 213 | // reply to master 214 | twi_transmit1(&data, 1); 215 | } 216 | return 1; 217 | } 218 | 219 | // must be called in: 220 | // slave tx event callback 221 | // or after beginTransmission(address) 222 | size_t TwoWire1::write(const uint8_t *data, size_t quantity) 223 | { 224 | if(transmitting){ 225 | // in master transmitter mode 226 | for(size_t i = 0; i < quantity; ++i){ 227 | write(data[i]); 228 | } 229 | }else{ 230 | // in slave send mode 231 | // reply to master 232 | twi_transmit1(data, quantity); 233 | } 234 | return quantity; 235 | } 236 | 237 | // must be called in: 238 | // slave rx event callback 239 | // or after requestFrom(address, numBytes) 240 | int TwoWire1::available(void) 241 | { 242 | return rxBufferLength - rxBufferIndex; 243 | } 244 | 245 | // must be called in: 246 | // slave rx event callback 247 | // or after requestFrom(address, numBytes) 248 | int TwoWire1::read(void) 249 | { 250 | int value = -1; 251 | 252 | // get each successive byte on each call 253 | if(rxBufferIndex < rxBufferLength){ 254 | value = rxBuffer[rxBufferIndex]; 255 | ++rxBufferIndex; 256 | } 257 | 258 | return value; 259 | } 260 | 261 | // must be called in: 262 | // slave rx event callback 263 | // or after requestFrom(address, numBytes) 264 | int TwoWire1::peek(void) 265 | { 266 | int value = -1; 267 | 268 | if(rxBufferIndex < rxBufferLength){ 269 | value = rxBuffer[rxBufferIndex]; 270 | } 271 | 272 | return value; 273 | } 274 | 275 | void TwoWire1::flush(void) 276 | { 277 | // XXX: to be implemented. 278 | } 279 | 280 | // behind the scenes function that is called when data is received 281 | void TwoWire1::onReceiveService(uint8_t* inBytes, int numBytes) 282 | { 283 | // don't bother if user hasn't registered a callback 284 | if(!user_onReceive){ 285 | return; 286 | } 287 | // don't bother if rx buffer is in use by a master requestFrom() op 288 | // i know this drops data, but it allows for slight stupidity 289 | // meaning, they may not have read all the master requestFrom() data yet 290 | if(rxBufferIndex < rxBufferLength){ 291 | return; 292 | } 293 | // copy twi rx buffer into local read buffer 294 | // this enables new reads to happen in parallel 295 | for(uint8_t i = 0; i < numBytes; ++i){ 296 | rxBuffer[i] = inBytes[i]; 297 | } 298 | // set rx iterator vars 299 | rxBufferIndex = 0; 300 | rxBufferLength = numBytes; 301 | // alert user program 302 | user_onReceive(numBytes); 303 | } 304 | 305 | // behind the scenes function that is called when data is requested 306 | void TwoWire1::onRequestService(void) 307 | { 308 | // don't bother if user hasn't registered a callback 309 | if(!user_onRequest){ 310 | return; 311 | } 312 | // reset tx buffer iterator vars 313 | // !!! this will kill any pending pre-master sendTo() activity 314 | txBufferIndex = 0; 315 | txBufferLength = 0; 316 | // alert user program 317 | user_onRequest(); 318 | } 319 | 320 | // sets function called on slave write 321 | void TwoWire1::onReceive( void (*function)(int) ) 322 | { 323 | user_onReceive = function; 324 | } 325 | 326 | // sets function called on slave read 327 | void TwoWire1::onRequest( void (*function)(void) ) 328 | { 329 | user_onRequest = function; 330 | } 331 | 332 | // Preinstantiate Objects ////////////////////////////////////////////////////// 333 | 334 | TwoWire1 Wire1 = TwoWire1(); 335 | 336 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire1/src/Wire1.h: -------------------------------------------------------------------------------- 1 | /* 2 | TwoWire.h - TWI/I2C library for Arduino & Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts 20 | */ 21 | 22 | #ifndef TwoWire1_h 23 | #define TwoWire1_h 24 | 25 | #include 26 | #include "Stream.h" 27 | 28 | #define BUFFER_LENGTH 32 29 | 30 | // WIRE_HAS_END means Wire has end() 31 | #define WIRE_HAS_END 1 32 | 33 | class TwoWire1 : public Stream 34 | { 35 | private: 36 | static uint8_t rxBuffer[]; 37 | static uint8_t rxBufferIndex; 38 | static uint8_t rxBufferLength; 39 | 40 | static uint8_t txAddress; 41 | static uint8_t txBuffer[]; 42 | static uint8_t txBufferIndex; 43 | static uint8_t txBufferLength; 44 | 45 | static uint8_t transmitting; 46 | static void (*user_onRequest)(void); 47 | static void (*user_onReceive)(int); 48 | static void onRequestService(void); 49 | static void onReceiveService(uint8_t*, int); 50 | public: 51 | TwoWire1(); 52 | void begin(); 53 | void begin(uint8_t); 54 | void begin(int); 55 | void end(); 56 | void setClock(uint32_t); 57 | void beginTransmission(uint8_t); 58 | void beginTransmission(int); 59 | uint8_t endTransmission(void); 60 | uint8_t endTransmission(uint8_t); 61 | uint8_t requestFrom(uint8_t, uint8_t); 62 | uint8_t requestFrom(uint8_t, uint8_t, uint8_t); 63 | uint8_t requestFrom(uint8_t, uint8_t, uint32_t, uint8_t, uint8_t); 64 | uint8_t requestFrom(int, int); 65 | uint8_t requestFrom(int, int, int); 66 | virtual size_t write(uint8_t); 67 | virtual size_t write(const uint8_t *, size_t); 68 | virtual int available(void); 69 | virtual int read(void); 70 | virtual int peek(void); 71 | virtual void flush(void); 72 | void onReceive( void (*)(int) ); 73 | void onRequest( void (*)(void) ); 74 | 75 | inline size_t write(unsigned long n) { return write((uint8_t)n); } 76 | inline size_t write(long n) { return write((uint8_t)n); } 77 | inline size_t write(unsigned int n) { return write((uint8_t)n); } 78 | inline size_t write(int n) { return write((uint8_t)n); } 79 | using Print::write; 80 | }; 81 | 82 | extern TwoWire1 Wire1; 83 | 84 | #endif 85 | 86 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire1/src/utility/twi1.c: -------------------------------------------------------------------------------- 1 | /* 2 | twi.c - TWI/I2C library for Wiring & Arduino 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include "Arduino.h" // for digitalWrite 29 | #include "pins_arduino.h" 30 | #include "twi1.h" 31 | 32 | #ifndef cbi 33 | #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 34 | #endif 35 | 36 | #ifndef sbi 37 | #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) 38 | #endif 39 | 40 | static volatile uint8_t twi_state; 41 | static volatile uint8_t twi_slarw; 42 | static volatile uint8_t twi_sendStop; // should the transaction end with a stop 43 | static volatile uint8_t twi_inRepStart; // in the middle of a repeated start 44 | 45 | static void (*twi_onSlaveTransmit)(void); 46 | static void (*twi_onSlaveReceive)(uint8_t*, int); 47 | 48 | static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; 49 | static volatile uint8_t twi_masterBufferIndex; 50 | static volatile uint8_t twi_masterBufferLength; 51 | 52 | static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH]; 53 | static volatile uint8_t twi_txBufferIndex; 54 | static volatile uint8_t twi_txBufferLength; 55 | 56 | static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; 57 | static volatile uint8_t twi_rxBufferIndex; 58 | 59 | static volatile uint8_t twi_error; 60 | 61 | /* 62 | * Function twi_init 63 | * Desc readys twi pins and sets twi bitrate 64 | * Input none 65 | * Output none 66 | */ 67 | void twi_init1(void) 68 | { 69 | // initialize state 70 | twi_state = TWI_READY; 71 | twi_sendStop = true; // default value 72 | twi_inRepStart = false; 73 | 74 | // activate internal pullups for twi. 75 | digitalWrite(SDA1, 1); 76 | digitalWrite(SCL1, 1); 77 | 78 | // initialize twi prescaler and bit rate 79 | cbi(TWSR1, TWPS0); 80 | cbi(TWSR1, TWPS1); 81 | TWBR1 = ((F_CPU / TWI_FREQ) - 16) / 2; 82 | 83 | /* twi bit rate formula from atmega128 manual pg 204 84 | SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) 85 | note: TWBR should be 10 or higher for master mode 86 | It is 72 for a 16mhz Wiring board with 100kHz TWI */ 87 | 88 | // enable twi module, acks, and twi interrupt 89 | TWCR1 = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); 90 | } 91 | 92 | /* 93 | * Function twi_disable 94 | * Desc disables twi pins 95 | * Input none 96 | * Output none 97 | */ 98 | void twi_disable1(void) 99 | { 100 | // disable twi module, acks, and twi interrupt 101 | TWCR1 &= ~(_BV(TWEN) | _BV(TWIE) | _BV(TWEA)); 102 | 103 | // deactivate internal pullups for twi. 104 | digitalWrite(SDA1, 0); 105 | digitalWrite(SCL1, 0); 106 | } 107 | 108 | /* 109 | * Function twi_slaveInit 110 | * Desc sets slave address and enables interrupt 111 | * Input none 112 | * Output none 113 | */ 114 | void twi_setAddress1(uint8_t address) 115 | { 116 | // set twi slave address (skip over TWGCE bit) 117 | TWAR1 = address << 1; 118 | } 119 | 120 | /* 121 | * Function twi_readFrom 122 | * Desc attempts to become twi bus master and read a 123 | * series of bytes from a device on the bus 124 | * Input address: 7bit i2c device address 125 | * data: pointer to byte array 126 | * length: number of bytes to read into array 127 | * sendStop: Boolean indicating whether to send a stop at the end 128 | * Output number of bytes read 129 | */ 130 | uint8_t twi_readFrom1(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) 131 | { 132 | uint8_t i; 133 | 134 | // ensure data will fit into buffer 135 | if(TWI_BUFFER_LENGTH < length){ 136 | return 0; 137 | } 138 | 139 | // wait until twi is ready, become master receiver 140 | while(TWI_READY != twi_state){ 141 | continue; 142 | } 143 | twi_state = TWI_MRX; 144 | twi_sendStop = sendStop; 145 | // reset error state (0xFF.. no error occured) 146 | twi_error = 0xFF; 147 | 148 | // initialize buffer iteration vars 149 | twi_masterBufferIndex = 0; 150 | twi_masterBufferLength = length-1; // This is not intuitive, read on... 151 | // On receive, the previously configured ACK/NACK setting is transmitted in 152 | // response to the received byte before the interrupt is signalled. 153 | // Therefor we must actually set NACK when the _next_ to last byte is 154 | // received, causing that NACK to be sent in response to receiving the last 155 | // expected byte of data. 156 | 157 | // build sla+w, slave device address + w bit 158 | twi_slarw = TW_READ; 159 | twi_slarw |= address << 1; 160 | 161 | if (true == twi_inRepStart) { 162 | // if we're in the repeated start state, then we've already sent the start, 163 | // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. 164 | // We need to remove ourselves from the repeated start state before we enable interrupts, 165 | // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning 166 | // up. Also, don't enable the START interrupt. There may be one pending from the 167 | // repeated start that we sent ourselves, and that would really confuse things. 168 | twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR 169 | do { 170 | TWDR1 = twi_slarw; 171 | } while(TWCR1 & _BV(TWWC)); 172 | TWCR1 = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START 173 | } 174 | else 175 | // send start condition 176 | TWCR1 = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); 177 | 178 | // wait for read operation to complete 179 | while(TWI_MRX == twi_state){ 180 | continue; 181 | } 182 | 183 | if (twi_masterBufferIndex < length) 184 | length = twi_masterBufferIndex; 185 | 186 | // copy twi buffer to data 187 | for(i = 0; i < length; ++i){ 188 | data[i] = twi_masterBuffer[i]; 189 | } 190 | 191 | return length; 192 | } 193 | 194 | /* 195 | * Function twi_writeTo 196 | * Desc attempts to become twi bus master and write a 197 | * series of bytes to a device on the bus 198 | * Input address: 7bit i2c device address 199 | * data: pointer to byte array 200 | * length: number of bytes in array 201 | * wait: boolean indicating to wait for write or not 202 | * sendStop: boolean indicating whether or not to send a stop at the end 203 | * Output 0 .. success 204 | * 1 .. length to long for buffer 205 | * 2 .. address send, NACK received 206 | * 3 .. data send, NACK received 207 | * 4 .. other twi error (lost bus arbitration, bus error, ..) 208 | */ 209 | uint8_t twi_writeTo1(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop) 210 | { 211 | uint8_t i; 212 | 213 | // ensure data will fit into buffer 214 | if(TWI_BUFFER_LENGTH < length){ 215 | return 1; 216 | } 217 | 218 | // wait until twi is ready, become master transmitter 219 | while(TWI_READY != twi_state){ 220 | continue; 221 | } 222 | twi_state = TWI_MTX; 223 | twi_sendStop = sendStop; 224 | // reset error state (0xFF.. no error occured) 225 | twi_error = 0xFF; 226 | 227 | // initialize buffer iteration vars 228 | twi_masterBufferIndex = 0; 229 | twi_masterBufferLength = length; 230 | 231 | // copy data to twi buffer 232 | for(i = 0; i < length; ++i){ 233 | twi_masterBuffer[i] = data[i]; 234 | } 235 | 236 | // build sla+w, slave device address + w bit 237 | twi_slarw = TW_WRITE; 238 | twi_slarw |= address << 1; 239 | 240 | // if we're in a repeated start, then we've already sent the START 241 | // in the ISR. Don't do it again. 242 | // 243 | if (true == twi_inRepStart) { 244 | // if we're in the repeated start state, then we've already sent the start, 245 | // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. 246 | // We need to remove ourselves from the repeated start state before we enable interrupts, 247 | // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning 248 | // up. Also, don't enable the START interrupt. There may be one pending from the 249 | // repeated start that we sent outselves, and that would really confuse things. 250 | twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR 251 | do { 252 | TWDR1 = twi_slarw; 253 | } while(TWCR1 & _BV(TWWC)); 254 | TWCR1 = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START 255 | } 256 | else 257 | // send start condition 258 | TWCR1 = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs 259 | 260 | // wait for write operation to complete 261 | while(wait && (TWI_MTX == twi_state)){ 262 | continue; 263 | } 264 | 265 | if (twi_error == 0xFF) 266 | return 0; // success 267 | else if (twi_error == TW_MT_SLA_NACK) 268 | return 2; // error: address send, nack received 269 | else if (twi_error == TW_MT_DATA_NACK) 270 | return 3; // error: data send, nack received 271 | else 272 | return 4; // other twi error 273 | } 274 | 275 | /* 276 | * Function twi_transmit 277 | * Desc fills slave tx buffer with data 278 | * must be called in slave tx event callback 279 | * Input data: pointer to byte array 280 | * length: number of bytes in array 281 | * Output 1 length too long for buffer 282 | * 2 not slave transmitter 283 | * 0 ok 284 | */ 285 | uint8_t twi_transmit1(const uint8_t* data, uint8_t length) 286 | { 287 | uint8_t i; 288 | 289 | // ensure data will fit into buffer 290 | if(TWI_BUFFER_LENGTH < length){ 291 | return 1; 292 | } 293 | 294 | // ensure we are currently a slave transmitter 295 | if(TWI_STX != twi_state){ 296 | return 2; 297 | } 298 | 299 | // set length and copy data into tx buffer 300 | twi_txBufferLength = length; 301 | for(i = 0; i < length; ++i){ 302 | twi_txBuffer[i] = data[i]; 303 | } 304 | 305 | return 0; 306 | } 307 | 308 | /* 309 | * Function twi_attachSlaveRxEvent 310 | * Desc sets function called before a slave read operation 311 | * Input function: callback function to use 312 | * Output none 313 | */ 314 | void twi_attachSlaveRxEvent1( void (*function)(uint8_t*, int) ) 315 | { 316 | twi_onSlaveReceive = function; 317 | } 318 | 319 | /* 320 | * Function twi_attachSlaveTxEvent 321 | * Desc sets function called before a slave write operation 322 | * Input function: callback function to use 323 | * Output none 324 | */ 325 | void twi_attachSlaveTxEvent1( void (*function)(void) ) 326 | { 327 | twi_onSlaveTransmit = function; 328 | } 329 | 330 | /* 331 | * Function twi_reply 332 | * Desc sends byte or readys receive line 333 | * Input ack: byte indicating to ack or to nack 334 | * Output none 335 | */ 336 | void twi_reply1(uint8_t ack) 337 | { 338 | // transmit master read ready signal, with or without ack 339 | if(ack){ 340 | TWCR1 = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); 341 | }else{ 342 | TWCR1 = _BV(TWEN) | _BV(TWIE) | _BV(TWINT); 343 | } 344 | } 345 | 346 | /* 347 | * Function twi_stop 348 | * Desc relinquishes bus master status 349 | * Input none 350 | * Output none 351 | */ 352 | void twi_stop1(void) 353 | { 354 | // send stop condition 355 | TWCR1 = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO); 356 | 357 | // wait for stop condition to be exectued on bus 358 | // TWINT is not set after a stop condition! 359 | while(TWCR1 & _BV(TWSTO)){ 360 | continue; 361 | } 362 | 363 | // update twi state 364 | twi_state = TWI_READY; 365 | } 366 | 367 | /* 368 | * Function twi_releaseBus 369 | * Desc releases bus control 370 | * Input none 371 | * Output none 372 | */ 373 | void twi_releaseBus1(void) 374 | { 375 | // release bus 376 | TWCR1 = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT); 377 | 378 | // update twi state 379 | twi_state = TWI_READY; 380 | } 381 | 382 | ISR(TWI1_vect) 383 | { 384 | switch(TWSR1 & TW_STATUS_MASK){ // #define TW_STATUS (TWSR & TW_STATUS_MASK) 385 | // All Master 386 | case TW_START: // sent start condition 387 | case TW_REP_START: // sent repeated start condition 388 | // copy device address and r/w bit to output register and ack 389 | TWDR1 = twi_slarw; 390 | twi_reply1(1); 391 | break; 392 | 393 | // Master Transmitter 394 | case TW_MT_SLA_ACK: // slave receiver acked address 395 | case TW_MT_DATA_ACK: // slave receiver acked data 396 | // if there is data to send, send it, otherwise stop 397 | if(twi_masterBufferIndex < twi_masterBufferLength){ 398 | // copy data to output register and ack 399 | TWDR1 = twi_masterBuffer[twi_masterBufferIndex++]; 400 | twi_reply1(1); 401 | }else{ 402 | if (twi_sendStop) 403 | twi_stop1(); 404 | else { 405 | twi_inRepStart = true; // we're gonna send the START 406 | // don't enable the interrupt. We'll generate the start, but we 407 | // avoid handling the interrupt until we're in the next transaction, 408 | // at the point where we would normally issue the start. 409 | TWCR1 = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; 410 | twi_state = TWI_READY; 411 | } 412 | } 413 | break; 414 | case TW_MT_SLA_NACK: // address sent, nack received 415 | twi_error = TW_MT_SLA_NACK; 416 | twi_stop1(); 417 | break; 418 | case TW_MT_DATA_NACK: // data sent, nack received 419 | twi_error = TW_MT_DATA_NACK; 420 | twi_stop1(); 421 | break; 422 | case TW_MT_ARB_LOST: // lost bus arbitration 423 | twi_error = TW_MT_ARB_LOST; 424 | twi_releaseBus1(); 425 | break; 426 | 427 | // Master Receiver 428 | case TW_MR_DATA_ACK: // data received, ack sent 429 | // put byte into buffer 430 | twi_masterBuffer[twi_masterBufferIndex++] = TWDR1; 431 | case TW_MR_SLA_ACK: // address sent, ack received 432 | // ack if more bytes are expected, otherwise nack 433 | if(twi_masterBufferIndex < twi_masterBufferLength){ 434 | twi_reply1(1); 435 | }else{ 436 | twi_reply1(0); 437 | } 438 | break; 439 | case TW_MR_DATA_NACK: // data received, nack sent 440 | // put final byte into buffer 441 | twi_masterBuffer[twi_masterBufferIndex++] = TWDR1; 442 | if (twi_sendStop) 443 | twi_stop1(); 444 | else { 445 | twi_inRepStart = true; // we're gonna send the START 446 | // don't enable the interrupt. We'll generate the start, but we 447 | // avoid handling the interrupt until we're in the next transaction, 448 | // at the point where we would normally issue the start. 449 | TWCR1 = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; 450 | twi_state = TWI_READY; 451 | } 452 | break; 453 | case TW_MR_SLA_NACK: // address sent, nack received 454 | twi_stop1(); 455 | break; 456 | // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case 457 | 458 | // Slave Receiver 459 | case TW_SR_SLA_ACK: // addressed, returned ack 460 | case TW_SR_GCALL_ACK: // addressed generally, returned ack 461 | case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack 462 | case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack 463 | // enter slave receiver mode 464 | twi_state = TWI_SRX; 465 | // indicate that rx buffer can be overwritten and ack 466 | twi_rxBufferIndex = 0; 467 | twi_reply1(1); 468 | break; 469 | case TW_SR_DATA_ACK: // data received, returned ack 470 | case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack 471 | // if there is still room in the rx buffer 472 | if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ 473 | // put byte in buffer and ack 474 | twi_rxBuffer[twi_rxBufferIndex++] = TWDR1; 475 | twi_reply1(1); 476 | }else{ 477 | // otherwise nack 478 | twi_reply1(0); 479 | } 480 | break; 481 | case TW_SR_STOP: // stop or repeated start condition received 482 | // ack future responses and leave slave receiver state 483 | twi_releaseBus1(); 484 | // put a null char after data if there's room 485 | if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ 486 | twi_rxBuffer[twi_rxBufferIndex] = '\0'; 487 | } 488 | // callback to user defined callback 489 | twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); 490 | // since we submit rx buffer to "wire" library, we can reset it 491 | twi_rxBufferIndex = 0; 492 | break; 493 | case TW_SR_DATA_NACK: // data received, returned nack 494 | case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack 495 | // nack back at master 496 | twi_reply1(0); 497 | break; 498 | 499 | // Slave Transmitter 500 | case TW_ST_SLA_ACK: // addressed, returned ack 501 | case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack 502 | // enter slave transmitter mode 503 | twi_state = TWI_STX; 504 | // ready the tx buffer index for iteration 505 | twi_txBufferIndex = 0; 506 | // set tx buffer length to be zero, to verify if user changes it 507 | twi_txBufferLength = 0; 508 | // request for txBuffer to be filled and length to be set 509 | // note: user must call twi_transmit(bytes, length) to do this 510 | twi_onSlaveTransmit(); 511 | // if they didn't change buffer & length, initialize it 512 | if(0 == twi_txBufferLength){ 513 | twi_txBufferLength = 1; 514 | twi_txBuffer[0] = 0x00; 515 | } 516 | // transmit first byte from buffer, fall 517 | case TW_ST_DATA_ACK: // byte sent, ack returned 518 | // copy data to output register 519 | TWDR1 = twi_txBuffer[twi_txBufferIndex++]; 520 | // if there is more to send, ack, otherwise nack 521 | if(twi_txBufferIndex < twi_txBufferLength){ 522 | twi_reply1(1); 523 | }else{ 524 | twi_reply1(0); 525 | } 526 | break; 527 | case TW_ST_DATA_NACK: // received nack, we are done 528 | case TW_ST_LAST_DATA: // received ack, but we are done already! 529 | // ack future responses 530 | twi_reply1(1); 531 | // leave slave receiver state 532 | twi_state = TWI_READY; 533 | break; 534 | 535 | // All 536 | case TW_NO_INFO: // no state information 537 | break; 538 | case TW_BUS_ERROR: // bus error, illegal stop/start 539 | twi_error = TW_BUS_ERROR; 540 | twi_stop1(); 541 | break; 542 | } 543 | } 544 | 545 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/libraries/Wire1/src/utility/twi1.h: -------------------------------------------------------------------------------- 1 | /* 2 | twi.h - TWI/I2C library for Wiring & Arduino 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef twi1_h 21 | #define twi1_h 22 | 23 | #include 24 | 25 | #ifndef TWI_FREQ 26 | #define TWI_FREQ 100000L 27 | #endif 28 | 29 | #ifndef TWI_BUFFER_LENGTH 30 | #define TWI_BUFFER_LENGTH 32 31 | #endif 32 | 33 | #define TWI_READY 0 34 | #define TWI_MRX 1 35 | #define TWI_MTX 2 36 | #define TWI_SRX 3 37 | #define TWI_STX 4 38 | 39 | void twi_init1(void); 40 | void twi_disable1(void); 41 | void twi_setAddress1(uint8_t); 42 | uint8_t twi_readFrom1(uint8_t, uint8_t*, uint8_t, uint8_t); 43 | uint8_t twi_writeTo1(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t); 44 | uint8_t twi_transmit1(const uint8_t*, uint8_t); 45 | void twi_attachSlaveRxEvent1( void (*)(uint8_t*, int) ); 46 | void twi_attachSlaveTxEvent1( void (*)(void) ); 47 | void twi_reply1(uint8_t); 48 | void twi_stop1(void); 49 | void twi_releaseBus1(void); 50 | 51 | #endif 52 | 53 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/platform.txt: -------------------------------------------------------------------------------- 1 | name=ATmega328PB 2 | version=1.0.0 3 | 4 | # AVR compile variables 5 | # --------------------- 6 | 7 | compiler.warning_flags=-w 8 | compiler.warning_flags.none=-w 9 | compiler.warning_flags.default= 10 | compiler.warning_flags.more=-Wall 11 | compiler.warning_flags.all=-Wall -Wextra 12 | 13 | # Default "compiler.path" is correct, change only if you want to override the initial value 14 | compiler.path={runtime.tools.avr-gcc.path}/bin/ 15 | compiler.c.cmd=avr-gcc 16 | compiler.c.flags=-c -g -Os {compiler.warning_flags} -std=gnu11 -ffunction-sections -fdata-sections -MMD 17 | compiler.c.elf.flags={compiler.warning_flags} -Os -fuse-linker-plugin -Wl,--gc-sections 18 | compiler.c.elf.cmd=avr-gcc 19 | compiler.S.flags=-c -g -x assembler-with-cpp -flto 20 | compiler.cpp.cmd=avr-g++ 21 | compiler.cpp.flags=-c -g -Os {compiler.warning_flags} -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD 22 | compiler.ar.cmd=avr-gcc-ar 23 | compiler.ar.flags=rcs 24 | compiler.objcopy.cmd=avr-objcopy 25 | compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 26 | compiler.elf2hex.flags=-O ihex -R .eeprom 27 | compiler.elf2hex.cmd=avr-objcopy 28 | compiler.ldflags= 29 | compiler.size.cmd=avr-size 30 | 31 | # This can be overridden in boards.txt 32 | build.extra_flags= 33 | 34 | # These can be overridden in platform.local.txt 35 | compiler.c.extra_flags= 36 | compiler.c.elf.extra_flags= 37 | compiler.S.extra_flags= 38 | compiler.cpp.extra_flags= 39 | compiler.ar.extra_flags= 40 | compiler.objcopy.eep.extra_flags= 41 | compiler.elf2hex.extra_flags= 42 | 43 | # AVR compile patterns 44 | # -------------------- 45 | 46 | ## Compile c files 47 | recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" 48 | 49 | ## Compile c++ files 50 | recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" 51 | 52 | ## Compile S files 53 | recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.S.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" 54 | 55 | ## Create archives 56 | # archive_file_path is needed for backwards compatibility with IDE 1.6.5 or older, IDE 1.6.6 or newer overrides this value 57 | archive_file_path={build.path}/{archive_file} 58 | recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}" 59 | 60 | ## Combine gc-sections, archives, and objects 61 | recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm 62 | 63 | ## Create output files (.eep and .hex) 64 | recipe.objcopy.eep.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.objcopy.eep.flags} {compiler.objcopy.eep.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.eep" 65 | recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex" 66 | 67 | ## Save hex 68 | recipe.output.tmp_file={build.project_name}.hex 69 | recipe.output.save_file={build.project_name}.{build.variant}.hex 70 | 71 | ## Compute size 72 | recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" 73 | recipe.size.regex=^(?:\.text|\.data|\.bootloader)\s+([0-9]+).* 74 | recipe.size.regex.data=^(?:\.data|\.bss|\.noinit)\s+([0-9]+).* 75 | recipe.size.regex.eeprom=^(?:\.eeprom)\s+([0-9]+).* 76 | 77 | ## Preprocessor 78 | preproc.includes.flags=-w -x c++ -M -MG -MP 79 | recipe.preproc.includes="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.includes.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" 80 | 81 | preproc.macros.flags=-w -x c++ -E -CC 82 | recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.macros.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{preprocessed_file_path}" 83 | 84 | # AVR Uploader/Programmers tools 85 | # ------------------------------ 86 | 87 | tools.avrdude.cmd=bin/avrdude 88 | tools.avrdude.cmd.windows=bin/avrdude.exe 89 | tools.avrdude.path={runtime.tools.avrdude.path} 90 | #tools.avrdude.path={runtime.tools.avrdude-6.3.0-arduino6.path} 91 | tools.avrdude.path={runtime.tools.avrdude.path} 92 | #tools.avrdude.config={path}/etc/avrdude.conf 93 | tools.avrdude.config={runtime.platform.path}/tools/avrdude.conf 94 | 95 | tools.avrdude.upload.params.verbose=-v 96 | tools.avrdude.upload.params.quiet=-q -q 97 | tools.avrdude.upload.params.noverify=-V 98 | tools.avrdude.upload.pattern="{path}/{cmd}" "-C{config}" {upload.verbose} -p{build.mcu} -c{upload.protocol} -P{serial.port} -b{upload.speed} -D "-Uflash:w:{build.path}/{build.project_name}.hex:i" 99 | 100 | tools.avrdude.program.params.verbose=-v 101 | tools.avrdude.program.params.quiet=-q -q 102 | tools.avrdude.program.params.noverify=-V 103 | tools.avrdude.program.pattern="{path}/{cmd}" "-C{config}" {program.verbose} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{build.path}/{build.project_name}.hex:i" 104 | 105 | tools.avrdude.erase.params.verbose=-v 106 | tools.avrdude.erase.params.quiet=-q -q 107 | tools.avrdude.erase.pattern="{path}/{cmd}" "-C{config}" {erase.verbose} -p{build.mcu} -c{protocol} {program.extra_params} -e -Ulock:w:{bootloader.unlock_bits}:m -Uefuse:w:{bootloader.extended_fuses}:m -Uhfuse:w:{bootloader.high_fuses}:m -Ulfuse:w:{bootloader.low_fuses}:m 108 | 109 | tools.avrdude.bootloader.params.verbose=-v 110 | tools.avrdude.bootloader.params.quiet=-q -q 111 | tools.avrdude.bootloader.pattern="{path}/{cmd}" "-C{config}" {bootloader.verbose} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{runtime.platform.path}/bootloaders/{bootloader.file}:i" -Ulock:w:{bootloader.lock_bits}:m 112 | 113 | tools.avrdude_remote.upload.pattern=/usr/bin/run-avrdude /tmp/sketch.hex {upload.verbose} -p{build.mcu} 114 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/programmers.txt: -------------------------------------------------------------------------------- 1 | xplainedmini.name=Atmel AVR XplainedMini (ISP mode) 2 | xplainedmini.communication=usb 3 | xplainedmini.protocol=xplainedmini 4 | xplainedmini.program.protocol= 5 | xplainedmini.program.tool=avrdude 6 | xplainedmini.program.extra_params=-Pusb 7 | -------------------------------------------------------------------------------- /hardware/atmega328pb/avr/variants/atmega328pb/pins_arduino.h: -------------------------------------------------------------------------------- 1 | /* 2 | pins_arduino.h - Pin definition functions for Arduino 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2007 David A. Mellis 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | */ 22 | 23 | #ifndef Pins_Arduino_h 24 | #define Pins_Arduino_h 25 | 26 | #include 27 | 28 | #if defined(__AVR_ATmega328PB__) 29 | # define NUM_DIGITAL_PINS 24 30 | # define NUM_ANALOG_INPUTS 8 31 | # define analogInputToDigitalPin(p) ((p < 8) ? (p) + 14 : -1) 32 | #else 33 | # define NUM_DIGITAL_PINS 20 34 | # define NUM_ANALOG_INPUTS 8 35 | # define analogInputToDigitalPin(p) ((p < 6) ? (p) + 14 : -1) 36 | #endif 37 | 38 | #if defined(__AVR_ATmega328PB__) 39 | # define digitalPinHasPWM(p) ((p) == 0 || (p) == 1 || (p) == 2 || (p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11) 40 | #elif defined(__AVR_ATmega8__) 41 | # define digitalPinHasPWM(p) ((p) == 9 || (p) == 10 || (p) == 11) 42 | #else 43 | # define digitalPinHasPWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11) 44 | #endif 45 | 46 | #define PIN_SPI_SS (10) 47 | #define PIN_SPI_MOSI (11) 48 | #define PIN_SPI_MISO (12) 49 | #define PIN_SPI_SCK (13) 50 | 51 | static const uint8_t SS = PIN_SPI_SS; 52 | static const uint8_t MOSI = PIN_SPI_MOSI; 53 | static const uint8_t MISO = PIN_SPI_MISO; 54 | static const uint8_t SCK = PIN_SPI_SCK; 55 | 56 | #define PIN_WIRE_SDA (18) 57 | #define PIN_WIRE_SCL (19) 58 | 59 | static const uint8_t SDA = PIN_WIRE_SDA; 60 | static const uint8_t SCL = PIN_WIRE_SCL; 61 | 62 | #if defined(__AVR_ATmega328PB__) 63 | #define PIN_SPI1_SS (20) 64 | #define PIN_SPI1_MOSI (21) 65 | #define PIN_SPI1_MISO (14) 66 | #define PIN_SPI1_SCK (15) 67 | 68 | static const uint8_t SS1 = PIN_SPI1_SS; 69 | static const uint8_t MOSI1 = PIN_SPI1_MOSI; 70 | static const uint8_t MISO1 = PIN_SPI1_MISO; 71 | static const uint8_t SCK1 = PIN_SPI1_SCK; 72 | 73 | #define PIN_WIRE1_SDA (22) 74 | #define PIN_WIRE1_SCL (23) 75 | 76 | static const uint8_t SDA1 = PIN_WIRE1_SDA; 77 | static const uint8_t SCL1 = PIN_WIRE1_SCL; 78 | #endif 79 | 80 | #define LED_BUILTIN 13 81 | 82 | #define PIN_A0 (14) 83 | #define PIN_A1 (15) 84 | #define PIN_A2 (16) 85 | #define PIN_A3 (17) 86 | #define PIN_A4 (18) 87 | #define PIN_A5 (19) 88 | #define PIN_A6 (20) 89 | #define PIN_A7 (21) 90 | 91 | static const uint8_t A0 = PIN_A0; 92 | static const uint8_t A1 = PIN_A1; 93 | static const uint8_t A2 = PIN_A2; 94 | static const uint8_t A3 = PIN_A3; 95 | static const uint8_t A4 = PIN_A4; 96 | static const uint8_t A5 = PIN_A5; 97 | static const uint8_t A6 = PIN_A6; 98 | static const uint8_t A7 = PIN_A7; 99 | 100 | #define digitalPinToPCICR(p) (((p) >= 0 && (p) <= 23) ? (&PCICR) : ((uint8_t *)0)) 101 | #define digitalPinToPCICRbit(p) (((p) <= 7) ? 2 : (((p) <= 13) ? 0 : 1)) 102 | #define digitalPinToPCMSK(p) (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 23) ? (&PCMSK1) : ((uint8_t *)0)))) 103 | #define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14))) 104 | 105 | #define digitalPinToInterrupt(p) ((p) == 2 ? 0 : ((p) == 3 ? 1 : NOT_AN_INTERRUPT)) 106 | 107 | #ifdef ARDUINO_MAIN 108 | 109 | // these arrays map port names (e.g. port B) to the 110 | // appropriate addresses for various functions (e.g. reading 111 | // and writing) 112 | const uint16_t PROGMEM port_to_mode_PGM[] = { 113 | NOT_A_PORT, 114 | NOT_A_PORT, 115 | (uint16_t) &DDRB, 116 | (uint16_t) &DDRC, 117 | (uint16_t) &DDRD, 118 | #if defined(__AVR_ATmega328PB__) 119 | (uint16_t) &DDRE, 120 | #endif 121 | }; 122 | 123 | const uint16_t PROGMEM port_to_output_PGM[] = { 124 | NOT_A_PORT, 125 | NOT_A_PORT, 126 | (uint16_t) &PORTB, 127 | (uint16_t) &PORTC, 128 | (uint16_t) &PORTD, 129 | #if defined(__AVR_ATmega328PB__) 130 | (uint16_t) &PORTE, 131 | #endif 132 | }; 133 | 134 | const uint16_t PROGMEM port_to_input_PGM[] = { 135 | NOT_A_PORT, 136 | NOT_A_PORT, 137 | (uint16_t) &PINB, 138 | (uint16_t) &PINC, 139 | (uint16_t) &PIND, 140 | #if defined(__AVR_ATmega328PB__) 141 | (uint16_t) &PINE, 142 | #endif 143 | }; 144 | 145 | const uint8_t PROGMEM digital_pin_to_port_PGM[] = { 146 | PD, /* 0 */ 147 | PD, 148 | PD, 149 | PD, 150 | PD, 151 | PD, 152 | PD, 153 | PD, 154 | PB, /* 8 */ 155 | PB, 156 | PB, 157 | PB, 158 | PB, 159 | PB, 160 | PC, /* 14 */ 161 | PC, 162 | PC, 163 | PC, 164 | PC, 165 | PC, 166 | #if defined(__AVR_ATmega328PB__) 167 | PE, /* 20 */ 168 | PE, 169 | PE, 170 | PE, 171 | #endif 172 | }; 173 | 174 | const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { 175 | _BV(0), /* 0, port D */ 176 | _BV(1), 177 | _BV(2), 178 | _BV(3), 179 | _BV(4), 180 | _BV(5), 181 | _BV(6), 182 | _BV(7), 183 | _BV(0), /* 8, port B */ 184 | _BV(1), 185 | _BV(2), 186 | _BV(3), 187 | _BV(4), 188 | _BV(5), 189 | _BV(0), /* 14, port C */ 190 | _BV(1), 191 | _BV(2), 192 | _BV(3), 193 | _BV(4), 194 | _BV(5), 195 | #if defined(__AVR_ATmega328PB__) 196 | _BV(2), /* 20, port E */ 197 | _BV(3), 198 | _BV(0), 199 | _BV(1), 200 | #endif 201 | }; 202 | 203 | const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { 204 | #if defined(__AVR_ATmega328PB__) 205 | TIMER3A, /* 0 - port D */ 206 | TIMER4A, 207 | TIMER4B, // TIMER3B or TIMER4B 208 | #else 209 | NOT_ON_TIMER, 210 | NOT_ON_TIMER, 211 | NOT_ON_TIMER, 212 | #endif 213 | // on the ATmega168, digital pin 3 has hardware pwm 214 | #if defined(__AVR_ATmega8__) 215 | NOT_ON_TIMER, 216 | #else 217 | TIMER2B, 218 | #endif 219 | NOT_ON_TIMER, 220 | // on the ATmega168, digital pins 5 and 6 have hardware pwm 221 | #if defined(__AVR_ATmega8__) 222 | NOT_ON_TIMER, 223 | NOT_ON_TIMER, 224 | #else 225 | TIMER0B, 226 | TIMER0A, 227 | #endif 228 | NOT_ON_TIMER, 229 | NOT_ON_TIMER, /* 8 - port B */ 230 | TIMER1A, 231 | TIMER1B, 232 | #if defined(__AVR_ATmega8__) 233 | TIMER2, 234 | #else 235 | TIMER2A, 236 | #endif 237 | NOT_ON_TIMER, 238 | NOT_ON_TIMER, 239 | NOT_ON_TIMER, 240 | NOT_ON_TIMER, /* 14 - port C */ 241 | NOT_ON_TIMER, 242 | NOT_ON_TIMER, 243 | NOT_ON_TIMER, 244 | NOT_ON_TIMER, 245 | #if defined(__AVR_ATmega328PB__) 246 | NOT_ON_TIMER, /* 20 - port E */ 247 | NOT_ON_TIMER, 248 | NOT_ON_TIMER, 249 | NOT_ON_TIMER, 250 | #endif 251 | }; 252 | 253 | #endif 254 | 255 | // These serial port names are intended to allow libraries and architecture-neutral 256 | // sketches to automatically default to the correct port name for a particular type 257 | // of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, 258 | // the first hardware serial port whose RX/TX pins are not dedicated to another use. 259 | // 260 | // SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor 261 | // 262 | // SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial 263 | // 264 | // SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library 265 | // 266 | // SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. 267 | // 268 | // SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX 269 | // pins are NOT connected to anything by default. 270 | #define SERIAL_PORT_MONITOR Serial 271 | #define SERIAL_PORT_HARDWARE Serial 272 | 273 | #endif 274 | -------------------------------------------------------------------------------- /hardware/tools/avr/avr/include/avr/io.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2002,2003,2005,2006,2007 Marek Michalkiewicz, Joerg Wunsch 2 | Copyright (c) 2007 Eric B. Weddington 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in 13 | the documentation and/or other materials provided with the 14 | distribution. 15 | 16 | * Neither the name of the copyright holders nor the names of 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | POSSIBILITY OF SUCH DAMAGE. */ 31 | 32 | /* $Id$ */ 33 | 34 | /** \file */ 35 | /** \defgroup avr_io : AVR device-specific IO definitions 36 | \code #include \endcode 37 | 38 | This header file includes the apropriate IO definitions for the 39 | device that has been specified by the -mmcu= compiler 40 | command-line switch. This is done by diverting to the appropriate 41 | file <avr/ioXXXX.h> which should 42 | never be included directly. Some register names common to all 43 | AVR devices are defined directly within <avr/common.h>, 44 | which is included in <avr/io.h>, 45 | but most of the details come from the respective include file. 46 | 47 | Note that this file always includes the following files: 48 | \code 49 | #include 50 | #include 51 | #include 52 | #include 53 | \endcode 54 | See \ref avr_sfr for more details about that header file. 55 | 56 | Included are definitions of the IO register set and their 57 | respective bit values as specified in the Atmel documentation. 58 | Note that inconsistencies in naming conventions, 59 | so even identical functions sometimes get different names on 60 | different devices. 61 | 62 | Also included are the specific names useable for interrupt 63 | function definitions as documented 64 | \ref avr_signames "here". 65 | 66 | Finally, the following macros are defined: 67 | 68 | - \b RAMEND 69 |
70 | The last on-chip RAM address. 71 |
72 | - \b XRAMEND 73 |
74 | The last possible RAM location that is addressable. This is equal to 75 | RAMEND for devices that do not allow for external RAM. For devices 76 | that allow external RAM, this will be larger than RAMEND. 77 |
78 | - \b E2END 79 |
80 | The last EEPROM address. 81 |
82 | - \b FLASHEND 83 |
84 | The last byte address in the Flash program space. 85 |
86 | - \b SPM_PAGESIZE 87 |
88 | For devices with bootloader support, the flash pagesize 89 | (in bytes) to be used for the \c SPM instruction. 90 | - \b E2PAGESIZE 91 |
92 | The size of the EEPROM page. 93 | 94 | */ 95 | 96 | #ifndef _AVR_IO_H_ 97 | #define _AVR_IO_H_ 98 | 99 | #include 100 | 101 | #if defined (__AVR_AT94K__) 102 | # include 103 | #elif defined (__AVR_AT43USB320__) 104 | # include 105 | #elif defined (__AVR_AT43USB355__) 106 | # include 107 | #elif defined (__AVR_AT76C711__) 108 | # include 109 | #elif defined (__AVR_AT86RF401__) 110 | # include 111 | #elif defined (__AVR_AT90PWM1__) 112 | # include 113 | #elif defined (__AVR_AT90PWM2__) 114 | # include 115 | #elif defined (__AVR_AT90PWM2B__) 116 | # include 117 | #elif defined (__AVR_AT90PWM3__) 118 | # include 119 | #elif defined (__AVR_AT90PWM3B__) 120 | # include 121 | #elif defined (__AVR_AT90PWM216__) 122 | # include 123 | #elif defined (__AVR_AT90PWM316__) 124 | # include 125 | #elif defined (__AVR_AT90PWM161__) 126 | # include 127 | #elif defined (__AVR_AT90PWM81__) 128 | # include 129 | #elif defined (__AVR_ATmega8U2__) 130 | # include 131 | #elif defined (__AVR_ATmega16M1__) 132 | # include 133 | #elif defined (__AVR_ATmega16U2__) 134 | # include 135 | #elif defined (__AVR_ATmega16U4__) 136 | # include 137 | #elif defined (__AVR_ATmega32C1__) 138 | # include 139 | #elif defined (__AVR_ATmega32M1__) 140 | # include 141 | #elif defined (__AVR_ATmega32U2__) 142 | # include 143 | #elif defined (__AVR_ATmega32U4__) 144 | # include 145 | #elif defined (__AVR_ATmega32U6__) 146 | # include 147 | #elif defined (__AVR_ATmega64C1__) 148 | # include 149 | #elif defined (__AVR_ATmega64M1__) 150 | # include 151 | #elif defined (__AVR_ATmega128__) 152 | # include 153 | #elif defined (__AVR_ATmega128A__) 154 | # include 155 | #elif defined (__AVR_ATmega1280__) 156 | # include 157 | #elif defined (__AVR_ATmega1281__) 158 | # include 159 | #elif defined (__AVR_ATmega1284__) 160 | # include 161 | #elif defined (__AVR_ATmega1284P__) 162 | # include 163 | #elif defined (__AVR_ATmega128RFA1__) 164 | # include 165 | #elif defined (__AVR_ATmega1284RFR2__) 166 | # include 167 | #elif defined (__AVR_ATmega128RFR2__) 168 | # include 169 | #elif defined (__AVR_ATmega2564RFR2__) 170 | # include 171 | #elif defined (__AVR_ATmega256RFR2__) 172 | # include 173 | #elif defined (__AVR_ATmega2560__) 174 | # include 175 | #elif defined (__AVR_ATmega2561__) 176 | # include 177 | #elif defined (__AVR_AT90CAN32__) 178 | # include 179 | #elif defined (__AVR_AT90CAN64__) 180 | # include 181 | #elif defined (__AVR_AT90CAN128__) 182 | # include 183 | #elif defined (__AVR_AT90USB82__) 184 | # include 185 | #elif defined (__AVR_AT90USB162__) 186 | # include 187 | #elif defined (__AVR_AT90USB646__) 188 | # include 189 | #elif defined (__AVR_AT90USB647__) 190 | # include 191 | #elif defined (__AVR_AT90USB1286__) 192 | # include 193 | #elif defined (__AVR_AT90USB1287__) 194 | # include 195 | #elif defined (__AVR_ATmega644RFR2__) 196 | # include 197 | #elif defined (__AVR_ATmega64RFR2__) 198 | # include 199 | #elif defined (__AVR_ATmega64__) 200 | # include 201 | #elif defined (__AVR_ATmega64A__) 202 | # include 203 | #elif defined (__AVR_ATmega640__) 204 | # include 205 | #elif defined (__AVR_ATmega644__) 206 | # include 207 | #elif defined (__AVR_ATmega644A__) 208 | # include 209 | #elif defined (__AVR_ATmega644P__) 210 | # include 211 | #elif defined (__AVR_ATmega644PA__) 212 | # include 213 | #elif defined (__AVR_ATmega645__) 214 | # include 215 | #elif defined (__AVR_ATmega645A__) 216 | # include 217 | #elif defined (__AVR_ATmega645P__) 218 | # include 219 | #elif defined (__AVR_ATmega6450__) 220 | # include 221 | #elif defined (__AVR_ATmega6450A__) 222 | # include 223 | #elif defined (__AVR_ATmega6450P__) 224 | # include 225 | #elif defined (__AVR_ATmega649__) 226 | # include 227 | #elif defined (__AVR_ATmega649A__) 228 | # include 229 | #elif defined (__AVR_ATmega6490__) 230 | # include 231 | #elif defined (__AVR_ATmega6490A__) 232 | # include 233 | #elif defined (__AVR_ATmega6490P__) 234 | # include 235 | #elif defined (__AVR_ATmega649P__) 236 | # include 237 | #elif defined (__AVR_ATmega64HVE__) 238 | # include 239 | #elif defined (__AVR_ATmega64HVE2__) 240 | # include 241 | #elif defined (__AVR_ATmega103__) 242 | # include 243 | #elif defined (__AVR_ATmega32__) 244 | # include 245 | #elif defined (__AVR_ATmega32A__) 246 | # include 247 | #elif defined (__AVR_ATmega323__) 248 | # include 249 | #elif defined (__AVR_ATmega324P__) 250 | # include 251 | #elif defined (__AVR_ATmega324A__) 252 | # include 253 | #elif defined (__AVR_ATmega324PA__) 254 | # include 255 | #elif defined (__AVR_ATmega325__) 256 | # include 257 | #elif defined (__AVR_ATmega325A__) 258 | # include 259 | #elif defined (__AVR_ATmega325P__) 260 | # include 261 | #elif defined (__AVR_ATmega325PA__) 262 | # include 263 | #elif defined (__AVR_ATmega3250__) 264 | # include 265 | #elif defined (__AVR_ATmega3250A__) 266 | # include 267 | #elif defined (__AVR_ATmega3250P__) 268 | # include 269 | #elif defined (__AVR_ATmega3250PA__) 270 | # include 271 | #elif defined (__AVR_ATmega328PB__) 272 | # include 273 | #elif defined (__AVR_ATmega328P__) 274 | # include 275 | #elif defined (__AVR_ATmega328__) 276 | # include 277 | #elif defined (__AVR_ATmega329__) 278 | # include 279 | #elif defined (__AVR_ATmega329A__) 280 | # include 281 | #elif defined (__AVR_ATmega329P__) 282 | # include 283 | #elif defined (__AVR_ATmega329PA__) 284 | # include 285 | #elif defined (__AVR_ATmega3290PA__) 286 | # include 287 | #elif defined (__AVR_ATmega3290__) 288 | # include 289 | #elif defined (__AVR_ATmega3290A__) 290 | # include 291 | #elif defined (__AVR_ATmega3290P__) 292 | # include 293 | #elif defined (__AVR_ATmega32HVB__) 294 | # include 295 | #elif defined (__AVR_ATmega32HVBREVB__) 296 | # include 297 | #elif defined (__AVR_ATmega406__) 298 | # include 299 | #elif defined (__AVR_ATmega16__) 300 | # include 301 | #elif defined (__AVR_ATmega16A__) 302 | # include 303 | #elif defined (__AVR_ATmega161__) 304 | # include 305 | #elif defined (__AVR_ATmega162__) 306 | # include 307 | #elif defined (__AVR_ATmega163__) 308 | # include 309 | #elif defined (__AVR_ATmega164P__) 310 | # include 311 | #elif defined (__AVR_ATmega164A__) 312 | # include 313 | #elif defined (__AVR_ATmega164PA__) 314 | # include 315 | #elif defined (__AVR_ATmega165__) 316 | # include 317 | #elif defined (__AVR_ATmega165A__) 318 | # include 319 | #elif defined (__AVR_ATmega165P__) 320 | # include 321 | #elif defined (__AVR_ATmega165PA__) 322 | # include 323 | #elif defined (__AVR_ATmega168__) 324 | # include 325 | #elif defined (__AVR_ATmega168A__) 326 | # include 327 | #elif defined (__AVR_ATmega168P__) 328 | # include 329 | #elif defined (__AVR_ATmega168PA__) 330 | # include 331 | #elif defined (__AVR_ATmega168PB__) 332 | # include 333 | #elif defined (__AVR_ATmega169__) 334 | # include 335 | #elif defined (__AVR_ATmega169A__) 336 | # include 337 | #elif defined (__AVR_ATmega169P__) 338 | # include 339 | #elif defined (__AVR_ATmega169PA__) 340 | # include 341 | #elif defined (__AVR_ATmega8HVA__) 342 | # include 343 | #elif defined (__AVR_ATmega16HVA__) 344 | # include 345 | #elif defined (__AVR_ATmega16HVA2__) 346 | # include 347 | #elif defined (__AVR_ATmega16HVB__) 348 | # include 349 | #elif defined (__AVR_ATmega16HVBREVB__) 350 | # include 351 | #elif defined (__AVR_ATmega8__) 352 | # include 353 | #elif defined (__AVR_ATmega8A__) 354 | # include 355 | #elif defined (__AVR_ATmega48__) 356 | # include 357 | #elif defined (__AVR_ATmega48A__) 358 | # include 359 | #elif defined (__AVR_ATmega48PA__) 360 | # include 361 | #elif defined (__AVR_ATmega48PB__) 362 | # include 363 | #elif defined (__AVR_ATmega48P__) 364 | # include 365 | #elif defined (__AVR_ATmega88__) 366 | # include 367 | #elif defined (__AVR_ATmega88A__) 368 | # include 369 | #elif defined (__AVR_ATmega88P__) 370 | # include 371 | #elif defined (__AVR_ATmega88PA__) 372 | # include 373 | #elif defined (__AVR_ATmega88PB__) 374 | # include 375 | #elif defined (__AVR_ATmega8515__) 376 | # include 377 | #elif defined (__AVR_ATmega8535__) 378 | # include 379 | #elif defined (__AVR_AT90S8535__) 380 | # include 381 | #elif defined (__AVR_AT90C8534__) 382 | # include 383 | #elif defined (__AVR_AT90S8515__) 384 | # include 385 | #elif defined (__AVR_AT90S4434__) 386 | # include 387 | #elif defined (__AVR_AT90S4433__) 388 | # include 389 | #elif defined (__AVR_AT90S4414__) 390 | # include 391 | #elif defined (__AVR_ATtiny22__) 392 | # include 393 | #elif defined (__AVR_ATtiny26__) 394 | # include 395 | #elif defined (__AVR_AT90S2343__) 396 | # include 397 | #elif defined (__AVR_AT90S2333__) 398 | # include 399 | #elif defined (__AVR_AT90S2323__) 400 | # include 401 | #elif defined (__AVR_AT90S2313__) 402 | # include 403 | #elif defined (__AVR_ATtiny4__) 404 | # include 405 | #elif defined (__AVR_ATtiny5__) 406 | # include 407 | #elif defined (__AVR_ATtiny9__) 408 | # include 409 | #elif defined (__AVR_ATtiny10__) 410 | # include 411 | #elif defined (__AVR_ATtiny20__) 412 | # include 413 | #elif defined (__AVR_ATtiny40__) 414 | # include 415 | #elif defined (__AVR_ATtiny2313__) 416 | # include 417 | #elif defined (__AVR_ATtiny2313A__) 418 | # include 419 | #elif defined (__AVR_ATtiny13__) 420 | # include 421 | #elif defined (__AVR_ATtiny13A__) 422 | # include 423 | #elif defined (__AVR_ATtiny25__) 424 | # include 425 | #elif defined (__AVR_ATtiny4313__) 426 | # include 427 | #elif defined (__AVR_ATtiny45__) 428 | # include 429 | #elif defined (__AVR_ATtiny85__) 430 | # include 431 | #elif defined (__AVR_ATtiny24__) 432 | # include 433 | #elif defined (__AVR_ATtiny24A__) 434 | # include 435 | #elif defined (__AVR_ATtiny44__) 436 | # include 437 | #elif defined (__AVR_ATtiny44A__) 438 | # include 439 | #elif defined (__AVR_ATtiny441__) 440 | # include 441 | #elif defined (__AVR_ATtiny84__) 442 | # include 443 | #elif defined (__AVR_ATtiny84A__) 444 | # include 445 | #elif defined (__AVR_ATtiny841__) 446 | # include 447 | #elif defined (__AVR_ATtiny261__) 448 | # include 449 | #elif defined (__AVR_ATtiny261A__) 450 | # include 451 | #elif defined (__AVR_ATtiny461__) 452 | # include 453 | #elif defined (__AVR_ATtiny461A__) 454 | # include 455 | #elif defined (__AVR_ATtiny861__) 456 | # include 457 | #elif defined (__AVR_ATtiny861A__) 458 | # include 459 | #elif defined (__AVR_ATtiny43U__) 460 | # include 461 | #elif defined (__AVR_ATtiny48__) 462 | # include 463 | #elif defined (__AVR_ATtiny88__) 464 | # include 465 | #elif defined (__AVR_ATtiny828__) 466 | # include 467 | #elif defined (__AVR_ATtiny87__) 468 | # include 469 | #elif defined (__AVR_ATtiny167__) 470 | # include 471 | #elif defined (__AVR_ATtiny1634__) 472 | # include 473 | #elif defined (__AVR_AT90SCR100__) 474 | # include 475 | #elif defined (__AVR_ATxmega8E5__) 476 | # include 477 | #elif defined (__AVR_ATxmega16A4__) 478 | # include 479 | #elif defined (__AVR_ATxmega16A4U__) 480 | # include 481 | #elif defined (__AVR_ATxmega16C4__) 482 | # include 483 | #elif defined (__AVR_ATxmega16D4__) 484 | # include 485 | #elif defined (__AVR_ATxmega16E5__) 486 | # include 487 | #elif defined (__AVR_ATxmega32A4__) 488 | # include 489 | #elif defined (__AVR_ATxmega32A4U__) 490 | # include 491 | #elif defined (__AVR_ATxmega32C3__) 492 | # include 493 | #elif defined (__AVR_ATxmega32C4__) 494 | # include 495 | #elif defined (__AVR_ATxmega32D3__) 496 | # include 497 | #elif defined (__AVR_ATxmega32D4__) 498 | # include 499 | #elif defined (__AVR_ATxmega32E5__) 500 | # include 501 | #elif defined (__AVR_ATxmega64A1__) 502 | # include 503 | #elif defined (__AVR_ATxmega64A1U__) 504 | # include 505 | #elif defined (__AVR_ATxmega64A3__) 506 | # include 507 | #elif defined (__AVR_ATxmega64A3U__) 508 | # include 509 | #elif defined (__AVR_ATxmega64A4U__) 510 | # include 511 | #elif defined (__AVR_ATxmega64B1__) 512 | # include 513 | #elif defined (__AVR_ATxmega64B3__) 514 | # include 515 | #elif defined (__AVR_ATxmega64C3__) 516 | # include 517 | #elif defined (__AVR_ATxmega64D3__) 518 | # include 519 | #elif defined (__AVR_ATxmega64D4__) 520 | # include 521 | #elif defined (__AVR_ATxmega128A1__) 522 | # include 523 | #elif defined (__AVR_ATxmega128A1U__) 524 | # include 525 | #elif defined (__AVR_ATxmega128A4U__) 526 | # include 527 | #elif defined (__AVR_ATxmega128A3__) 528 | # include 529 | #elif defined (__AVR_ATxmega128A3U__) 530 | # include 531 | #elif defined (__AVR_ATxmega128B1__) 532 | # include 533 | #elif defined (__AVR_ATxmega128B3__) 534 | # include 535 | #elif defined (__AVR_ATxmega128C3__) 536 | # include 537 | #elif defined (__AVR_ATxmega128D3__) 538 | # include 539 | #elif defined (__AVR_ATxmega128D4__) 540 | # include 541 | #elif defined (__AVR_ATxmega192A3__) 542 | # include 543 | #elif defined (__AVR_ATxmega192A3U__) 544 | # include 545 | #elif defined (__AVR_ATxmega192C3__) 546 | # include 547 | #elif defined (__AVR_ATxmega192D3__) 548 | # include 549 | #elif defined (__AVR_ATxmega256A3__) 550 | # include 551 | #elif defined (__AVR_ATxmega256A3U__) 552 | # include 553 | #elif defined (__AVR_ATxmega256A3B__) 554 | # include 555 | #elif defined (__AVR_ATxmega256A3BU__) 556 | # include 557 | #elif defined (__AVR_ATxmega256C3__) 558 | # include 559 | #elif defined (__AVR_ATxmega256D3__) 560 | # include 561 | #elif defined (__AVR_ATxmega384C3__) 562 | # include 563 | #elif defined (__AVR_ATxmega384D3__) 564 | # include 565 | #elif defined (__AVR_ATA5702M322__) 566 | # include 567 | #elif defined (__AVR_ATA5782__) 568 | # include 569 | #elif defined (__AVR_ATA5790__) 570 | # include 571 | #elif defined (__AVR_ATA5790N__) 572 | # include 573 | #elif defined (__AVR_ATA5791__) 574 | # include 575 | #elif defined (__AVR_ATA5831__) 576 | # include 577 | #elif defined (__AVR_ATA5272__) 578 | # include 579 | #elif defined (__AVR_ATA5505__) 580 | # include 581 | #elif defined (__AVR_ATA5795__) 582 | # include 583 | #elif defined (__AVR_ATA6285__) 584 | # include 585 | #elif defined (__AVR_ATA6286__) 586 | # include 587 | #elif defined (__AVR_ATA6289__) 588 | # include 589 | #elif defined (__AVR_ATA6612C__) 590 | # include 591 | #elif defined (__AVR_ATA6613C__) 592 | # include 593 | #elif defined (__AVR_ATA6614Q__) 594 | # include 595 | #elif defined (__AVR_ATA6616C__) 596 | # include 597 | #elif defined (__AVR_ATA6617C__) 598 | # include 599 | #elif defined (__AVR_ATA664251__) 600 | # include 601 | #elif defined (__AVR_ATA8210__) 602 | # include 603 | #elif defined (__AVR_ATA8510__) 604 | # include 605 | /* avr1: the following only supported for assembler programs */ 606 | #elif defined (__AVR_ATtiny28__) 607 | # include 608 | #elif defined (__AVR_AT90S1200__) 609 | # include 610 | #elif defined (__AVR_ATtiny15__) 611 | # include 612 | #elif defined (__AVR_ATtiny12__) 613 | # include 614 | #elif defined (__AVR_ATtiny11__) 615 | # include 616 | #elif defined (__AVR_M3000__) 617 | # include 618 | #elif defined (__AVR_DEV_LIB_NAME__) 619 | # define __concat__(a,b) a##b 620 | # define __header1__(a,b) __concat__(a,b) 621 | # define __AVR_DEVICE_HEADER__ 622 | # include __AVR_DEVICE_HEADER__ 623 | #else 624 | # if !defined(__COMPILING_AVR_LIBC__) 625 | # warning "device type not defined" 626 | # endif 627 | #endif 628 | 629 | #include 630 | 631 | #include 632 | 633 | #include 634 | 635 | #if __AVR_ARCH__ >= 100 636 | # include 637 | #endif 638 | 639 | /* Include fuse.h after individual IO header files. */ 640 | #include 641 | 642 | /* Include lock.h after individual IO header files. */ 643 | #include 644 | 645 | #endif /* _AVR_IO_H_ */ 646 | -------------------------------------------------------------------------------- /hardware/tools/avr/avr/include/avr/iom328pb.h: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * 3 | * Copyright (C) 2016 Atmel Corporation, a wholly owned subsidiary of Microchip Technology Inc. 4 | * All rights reserved. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | ****************************************************************************/ 18 | 19 | 20 | #ifndef _AVR_ATMEGA328PB_H_INCLUDED 21 | #define _AVR_ATMEGA328PB_H_INCLUDED 22 | 23 | 24 | #ifndef _AVR_IO_H_ 25 | # error "Include instead of this file." 26 | #endif 27 | 28 | #ifndef _AVR_IOXXX_H_ 29 | # define _AVR_IOXXX_H_ "iom328pb.h" 30 | #else 31 | # error "Attempt to include more than one file." 32 | #endif 33 | 34 | /* Registers and associated bit numbers */ 35 | 36 | #define PINB _SFR_IO8(0x03) 37 | #define PINB7 7 38 | #define PINB6 6 39 | #define PINB5 5 40 | #define PINB4 4 41 | #define PINB3 3 42 | #define PINB2 2 43 | #define PINB1 1 44 | #define PINB0 0 45 | 46 | #define DDRB _SFR_IO8(0x04) 47 | #define DDRB7 7 48 | // Inserted "DDB7" from "DDRB7" due to compatibility 49 | #define DDB7 7 50 | #define DDRB6 6 51 | // Inserted "DDB6" from "DDRB6" due to compatibility 52 | #define DDB6 6 53 | #define DDRB5 5 54 | // Inserted "DDB5" from "DDRB5" due to compatibility 55 | #define DDB5 5 56 | #define DDRB4 4 57 | // Inserted "DDB4" from "DDRB4" due to compatibility 58 | #define DDB4 4 59 | #define DDRB3 3 60 | // Inserted "DDB3" from "DDRB3" due to compatibility 61 | #define DDB3 3 62 | #define DDRB2 2 63 | // Inserted "DDB2" from "DDRB2" due to compatibility 64 | #define DDB2 2 65 | #define DDRB1 1 66 | // Inserted "DDB1" from "DDRB1" due to compatibility 67 | #define DDB1 1 68 | #define DDRB0 0 69 | // Inserted "DDB0" from "DDRB0" due to compatibility 70 | #define DDB0 0 71 | 72 | #define PORTB _SFR_IO8(0x05) 73 | #define PORTB7 7 74 | #define PORTB6 6 75 | #define PORTB5 5 76 | #define PORTB4 4 77 | #define PORTB3 3 78 | #define PORTB2 2 79 | #define PORTB1 1 80 | #define PORTB0 0 81 | 82 | #define PINC _SFR_IO8(0x06) 83 | #define PINC6 6 84 | #define PINC5 5 85 | #define PINC4 4 86 | #define PINC3 3 87 | #define PINC2 2 88 | #define PINC1 1 89 | #define PINC0 0 90 | 91 | #define DDRC _SFR_IO8(0x07) 92 | #define DDRC6 6 93 | // Inserted "DDC6" from "DDRC6" due to compatibility 94 | #define DDC6 6 95 | #define DDRC5 5 96 | // Inserted "DDC5" from "DDRC5" due to compatibility 97 | #define DDC5 5 98 | #define DDRC4 4 99 | // Inserted "DDC4" from "DDRC4" due to compatibility 100 | #define DDC4 4 101 | #define DDRC3 3 102 | // Inserted "DDC3" from "DDRC3" due to compatibility 103 | #define DDC3 3 104 | #define DDRC2 2 105 | // Inserted "DDC2" from "DDRC2" due to compatibility 106 | #define DDC2 2 107 | #define DDRC1 1 108 | // Inserted "DDC1" from "DDRC1" due to compatibility 109 | #define DDC1 1 110 | #define DDRC0 0 111 | // Inserted "DDC0" from "DDRC0" due to compatibility 112 | #define DDC0 0 113 | 114 | #define PORTC _SFR_IO8(0x08) 115 | #define PORTC6 6 116 | #define PORTC5 5 117 | #define PORTC4 4 118 | #define PORTC3 3 119 | #define PORTC2 2 120 | #define PORTC1 1 121 | #define PORTC0 0 122 | 123 | #define PIND _SFR_IO8(0x09) 124 | #define PIND7 7 125 | #define PIND6 6 126 | #define PIND5 5 127 | #define PIND4 4 128 | #define PIND3 3 129 | #define PIND2 2 130 | #define PIND1 1 131 | #define PIND0 0 132 | 133 | #define DDRD _SFR_IO8(0x0A) 134 | #define DDRD7 7 135 | // Inserted "DDD7" from "DDRD7" due to compatibility 136 | #define DDD7 7 137 | #define DDRD6 6 138 | // Inserted "DDD6" from "DDRD6" due to compatibility 139 | #define DDD6 6 140 | #define DDRD5 5 141 | // Inserted "DDD5" from "DDRD5" due to compatibility 142 | #define DDD5 5 143 | #define DDRD4 4 144 | // Inserted "DDD4" from "DDRD4" due to compatibility 145 | #define DDD4 4 146 | #define DDRD3 3 147 | // Inserted "DDD3" from "DDRD3" due to compatibility 148 | #define DDD3 3 149 | #define DDRD2 2 150 | // Inserted "DDD2" from "DDRD2" due to compatibility 151 | #define DDD2 2 152 | #define DDRD1 1 153 | // Inserted "DDD1" from "DDRD1" due to compatibility 154 | #define DDD1 1 155 | #define DDRD0 0 156 | // Inserted "DDD0" from "DDRD0" due to compatibility 157 | #define DDD0 0 158 | 159 | #define PORTD _SFR_IO8(0x0B) 160 | #define PORTD7 7 161 | #define PORTD6 6 162 | #define PORTD5 5 163 | #define PORTD4 4 164 | #define PORTD3 3 165 | #define PORTD2 2 166 | #define PORTD1 1 167 | #define PORTD0 0 168 | 169 | #define PINE _SFR_IO8(0x0C) 170 | #define PINE3 3 171 | #define PINE2 2 172 | #define PINE1 1 173 | #define PINE0 0 174 | 175 | #define DDRE _SFR_IO8(0x0D) 176 | #define DDRE3 3 177 | // Inserted "DDE3" from "DDRE3" due to compatibility 178 | #define DDE3 3 179 | #define DDRE2 2 180 | // Inserted "DDE2" from "DDRE2" due to compatibility 181 | #define DDE2 2 182 | #define DDRE1 1 183 | // Inserted "DDE1" from "DDRE1" due to compatibility 184 | #define DDE1 1 185 | #define DDRE0 0 186 | // Inserted "DDE0" from "DDRE0" due to compatibility 187 | #define DDE0 0 188 | 189 | #define PORTE _SFR_IO8(0x0E) 190 | #define PORTE3 3 191 | #define PORTE2 2 192 | #define PORTE1 1 193 | #define PORTE0 0 194 | 195 | /* Reserved [0x0F..0x14] */ 196 | 197 | #define TIFR0 _SFR_IO8(0x15) 198 | #define TOV0 0 199 | #define OCF0A 1 200 | #define OCF0B 2 201 | 202 | #define TIFR1 _SFR_IO8(0x16) 203 | #define TOV1 0 204 | #define OCF1A 1 205 | #define OCF1B 2 206 | #define ICF1 5 207 | 208 | #define TIFR2 _SFR_IO8(0x17) 209 | #define TOV2 0 210 | #define OCF2A 1 211 | #define OCF2B 2 212 | 213 | #define TIFR3 _SFR_IO8(0x18) 214 | #define TOV3 0 215 | #define OCF3A 1 216 | #define OCF3B 2 217 | #define IC3F 5 218 | 219 | #define TIFR4 _SFR_IO8(0x19) 220 | #define TOV4 0 221 | #define OCF4A 1 222 | #define OCF4B 2 223 | #define IC4F 5 224 | 225 | /* Reserved [0x1A] */ 226 | 227 | #define PCIFR _SFR_IO8(0x1B) 228 | #define PCIF0 0 229 | #define PCIF1 1 230 | #define PCIF2 2 231 | #define PCIF3 3 232 | 233 | #define EIFR _SFR_IO8(0x1C) 234 | #define INTF0 0 235 | #define INTF1 1 236 | 237 | #define EIMSK _SFR_IO8(0x1D) 238 | #define INT0 0 239 | #define INT1 1 240 | 241 | #define GPIOR0 _SFR_IO8(0x1E) 242 | 243 | #define EECR _SFR_IO8(0x1F) 244 | #define EERE 0 245 | #define EEPE 1 246 | #define EEMPE 2 247 | #define EERIE 3 248 | #define EEPM0 4 249 | #define EEPM1 5 250 | 251 | #define EEDR _SFR_IO8(0x20) 252 | 253 | /* Combine EEARL and EEARH */ 254 | #define EEAR _SFR_IO16(0x21) 255 | 256 | #define EEARL _SFR_IO8(0x21) 257 | #define EEARH _SFR_IO8(0x22) 258 | 259 | #define GTCCR _SFR_IO8(0x23) 260 | #define PSRSYNC 0 261 | #define TSM 7 262 | #define PSRASY 1 263 | 264 | #define TCCR0A _SFR_IO8(0x24) 265 | #define WGM00 0 266 | #define WGM01 1 267 | #define COM0B0 4 268 | #define COM0B1 5 269 | #define COM0A0 6 270 | #define COM0A1 7 271 | 272 | #define TCCR0B _SFR_IO8(0x25) 273 | #define CS00 0 274 | #define CS01 1 275 | #define CS02 2 276 | #define WGM02 3 277 | #define FOC0B 6 278 | #define FOC0A 7 279 | 280 | #define TCNT0 _SFR_IO8(0x26) 281 | 282 | #define OCR0A _SFR_IO8(0x27) 283 | 284 | #define OCR0B _SFR_IO8(0x28) 285 | 286 | /* Reserved [0x29] */ 287 | 288 | #define GPIOR1 _SFR_IO8(0x2A) 289 | 290 | #define GPIOR2 _SFR_IO8(0x2B) 291 | 292 | #define SPCR0 _SFR_IO8(0x2C) 293 | #define SPR0 0 294 | #define SPR1 1 295 | #define CPHA 2 296 | #define CPOL 3 297 | #define MSTR 4 298 | #define DORD 5 299 | #define SPE 6 300 | #define SPIE 7 301 | 302 | #define SPSR0 _SFR_IO8(0x2D) 303 | #define SPI2X 0 304 | #define WCOL 6 305 | #define SPIF 7 306 | 307 | #define SPDR0 _SFR_IO8(0x2E) 308 | 309 | #define ACSRB _SFR_IO8(0x2F) 310 | #define ACOE 0 311 | 312 | #define ACSRA _SFR_IO8(0x30) 313 | 314 | #define ACSR _SFR_IO8(0x30) 315 | #define ACIS0 0 316 | #define ACIS1 1 317 | #define ACIC 2 318 | #define ACIE 3 319 | #define ACI 4 320 | #define ACO 5 321 | #define ACBG 6 322 | #define ACD 7 323 | 324 | #define ACSRB _SFR_IO8(0x31) 325 | #define ACOE 7 326 | 327 | /* Reserved [0x32] */ 328 | 329 | #define SMCR _SFR_IO8(0x33) 330 | #define SE 0 331 | #define SM0 1 332 | #define SM1 2 333 | #define SM2 3 334 | 335 | #define MCUSR _SFR_IO8(0x34) 336 | #define PORF 0 337 | #define EXTRF 1 338 | #define BORF 2 339 | #define WDRF 3 340 | 341 | #define MCUCR _SFR_IO8(0x35) 342 | #define IVCE 0 343 | #define IVSEL 1 344 | #define PUD 4 345 | #define BODSE 5 346 | #define BODS 6 347 | 348 | /* Reserved [0x36] */ 349 | 350 | #define SPMCSR _SFR_IO8(0x37) 351 | #define SPMEN 0 352 | #define PGERS 1 353 | #define PGWRT 2 354 | #define BLBSET 3 355 | #define RWWSRE 4 356 | #define SIGRD 5 357 | #define RWWSB 6 358 | #define SPMIE 7 359 | 360 | /* Reserved [0x38..0x3C] */ 361 | 362 | /* SP [0x3D..0x3E] */ 363 | 364 | /* SREG [0x3F] */ 365 | 366 | #define WDTCSR _SFR_MEM8(0x60) 367 | #define WDE 3 368 | #define WDCE 4 369 | #define WDP0 0 370 | #define WDP1 1 371 | #define WDP2 2 372 | #define WDP3 5 373 | #define WDIE 6 374 | #define WDIF 7 375 | 376 | #define CLKPR _SFR_MEM8(0x61) 377 | #define CLKPS0 0 378 | #define CLKPS1 1 379 | #define CLKPS2 2 380 | #define CLKPS3 3 381 | #define CLKPCE 7 382 | 383 | #define XFDCSR _SFR_MEM8(0x62) 384 | #define XFDIE 0 385 | #define XFDIF 1 386 | 387 | /* Reserved [0x63] */ 388 | 389 | #define PRR0 _SFR_MEM8(0x64) 390 | #define PRADC 0 391 | #define PRUSART0 1 392 | #define PRSPI0 2 393 | #define PRTIM1 3 394 | #define PRUSART1 4 395 | #define PRTIM0 5 396 | #define PRTIM2 6 397 | #define PRTWI0 7 398 | 399 | #define __AVR_HAVE_PRR0 ((1< 12 | # for a documentation of spec files. 13 | 14 | 15 | # If you intend to use an existing device specs file as a starting point 16 | # for a new device spec file, make sure you are copying from a specs 17 | # file for a device from the same core architecture and SP width. 18 | # See for a description 19 | # of how to use such own spec files. 20 | 21 | *avrlibc_startfile: 22 | crtatmega328pb.o%s 23 | 24 | *avrlibc_devicelib: 25 | %{!nodevicelib:-latmega328pb} 26 | 27 | *cc1_n_flash: 28 | %{!mn-flash=*:-mn-flash=1} 29 | 30 | *cc1_rmw: 31 | %{mrmw} 32 | 33 | *cc1_errata_skip: 34 | %{!mskip-bug: -mno-skip-bug} 35 | 36 | *asm_arch: 37 | -mmcu=avr5 38 | 39 | *asm_relax: 40 | %{mrelax:--mlink-relax} 41 | 42 | *asm_rmw: 43 | %{mrmw} 44 | 45 | *asm_errata_skip: 46 | %{!mskip-bug: -mno-skip-bug} 47 | 48 | *link_pmem_wrap: 49 | %{mpmem-wrap-around: --pmem-wrap-around=32k} 50 | 51 | *link_relax: 52 | %{mrelax:--relax %(link_pmem_wrap)} 53 | 54 | *link_arch: 55 | %{mmcu=*:-m%*} 56 | 57 | *link_data_start: 58 | -Tdata 0x800100 59 | 60 | *link_text_start: 61 | 62 | 63 | *self_spec: 64 | %{!mmcu=avr*: % 74 | # #elif ... 75 | # 76 | # If no device macro is defined, AVR-LibC uses __AVR_DEV_LIB_NAME__ 77 | # as fallback to determine the name of the device header as 78 | # 79 | # "avr/io" + __AVR_DEV_LIB_NAME__ + ".h" 80 | # 81 | # If you provide your own specs file for a device not yet known to 82 | # AVR-LibC, you can now define the hook macro __AVR_DEV_LIB_NAME__ 83 | # as needed so that 84 | # 85 | # #include 86 | # 87 | # will include the desired device header. For ATmega8A the supplement 88 | # to *cpp would read 89 | # 90 | # -D__AVR_DEV_LIB_NAME__=m8a 91 | 92 | 93 | *cpp: 94 | -D__AVR_ATmega328PB__ -D__AVR_DEVICE_NAME__=atmega328pb -D__AVR_DEV_LIB_NAME__=m328pb 95 | 96 | # End of file 97 | -------------------------------------------------------------------------------- /m328pb.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/watterott/ATmega328PB-Testing/7d0e4eb5af631da8dc3e7aa47ac6e67a598fe499/m328pb.zip -------------------------------------------------------------------------------- /package_m328pb_index.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | { 4 | "name": "m328pb", 5 | "maintainer": "Watterott electronic", 6 | "websiteURL": "https://github.com/watterott/ATmega328PB-Testing", 7 | "email": "", 8 | "help": {"online": "https://github.com/watterott/ATmega328PB-Testing"}, 9 | 10 | "platforms": [ 11 | { 12 | "name": "ATmega328PB Boards", 13 | "architecture": "avr", 14 | "version": "1.1.4", 15 | "category": "contributed", 16 | "help": {"online": "https://github.com/watterott/ATmega328PB-Testing"}, 17 | "url": "https://github.com/watterott/ATmega328PB-Testing/raw/master/m328pb.zip", 18 | "archiveFileName": "m328pb-1.1.4.zip", 19 | "checksum": "SHA-256:96d7afc7b31c6a58a9dccb967ad044d845374ced130a029f2820574328b73fa5", 20 | "size": "84570", 21 | "boards": [ 22 | {"name": "ATmega328PB"} 23 | ] 24 | }, 25 | { 26 | "name": "ATmega328PB Boards", 27 | "architecture": "avr", 28 | "version": "1.1.3", 29 | "category": "contributed", 30 | "help": {"online": "https://github.com/watterott/ATmega328PB-Testing"}, 31 | "url": "https://github.com/watterott/ATmega328PB-Testing/raw/e4dd4dcb02059c776d51994a821487bf2e44cefd/m328pb.zip", 32 | "checksum": "SHA-256:0d175f094211afd7b4deaa73f422dcc4a28d34c571208dc7befffec7fd887566", 33 | "archiveFileName": "m328pb-1.1.3.zip", 34 | "size": "84531", 35 | "boards": [ 36 | {"name": "ATmega328PB"} 37 | ] 38 | }, 39 | { 40 | "name": "ATmega328PB Boards", 41 | "architecture": "avr", 42 | "version": "1.1.2", 43 | "category": "contributed", 44 | "help": {"online": "https://github.com/watterott/ATmega328PB-Testing"}, 45 | "url": "https://github.com/watterott/ATmega328PB-Testing/raw/12b422f551b8cdf0b998ee1a6a648df8320c8f6e/m328pb.zip", 46 | "archiveFileName": "m328pb-1.1.2.zip", 47 | "checksum": "SHA-256:0d8cae9cb8224c3b8a7c8c73eb2a75efae82dca5c36983c300bd1e78a29d3256", 48 | "size": "84842", 49 | "boards": [ 50 | {"name": "ATmega328PB"} 51 | ] 52 | }, 53 | { 54 | "name": "ATmega328PB Boards", 55 | "architecture": "avr", 56 | "version": "1.1.1", 57 | "category": "contributed", 58 | "help": {"online": "https://github.com/watterott/ATmega328PB-Testing"}, 59 | "url": "https://github.com/watterott/ATmega328PB-Testing/raw/3354860a5ff5f1c920b957cee8d1cd9d08e75bc7/m328pb.zip", 60 | "archiveFileName": "m328pb-1.1.1.zip", 61 | "checksum": "SHA-256:802d9d2d206be2b0c32be0b4b24ea8772274857e27a5284f2c62bf94031addf0", 62 | "size": "85206", 63 | "boards": [ 64 | {"name": "ATmega328PB"} 65 | ] 66 | }, 67 | { 68 | "name": "ATmega328PB Boards", 69 | "architecture": "avr", 70 | "version": "1.1.0", 71 | "category": "contributed", 72 | "help": {"online": "https://github.com/watterott/ATmega328PB-Testing"}, 73 | "url": "https://github.com/watterott/ATmega328PB-Testing/raw/88ea09054b3260f3b4ff855cadd84df39e65ef85/m328pb.zip", 74 | "archiveFileName": "m328pb-1.1.0.zip", 75 | "checksum": "SHA-256:2931223b261bec9d177b09ca629f1742089ee78184ffcfc059a86ed4270e9447", 76 | "size": "85215", 77 | "boards": [ 78 | {"name": "ATmega328PB"} 79 | ] 80 | }, 81 | { 82 | "name": "ATmega328PB Boards", 83 | "architecture": "avr", 84 | "version": "1.0.9", 85 | "category": "contributed", 86 | "help": {"online": "https://github.com/watterott/ATmega328PB-Testing"}, 87 | "url": "https://github.com/watterott/ATmega328PB-Testing/raw/3398f67e81a0710cd61016fe135a485266dbd787/m328pb.zip", 88 | "archiveFileName": "m328pb-1.0.9.zip", 89 | "checksum": "SHA-256:414fa5a5fce6f4f2a2cd63e56ce46957d124ed9db14badcd30a5ad841624b910", 90 | "size": "85278", 91 | "boards": [ 92 | {"name": "ATmega328PB"} 93 | ] 94 | }, 95 | { 96 | "name": "ATmega328PB Boards", 97 | "architecture": "avr", 98 | "version": "1.0.8", 99 | "category": "contributed", 100 | "help": {"online": "https://github.com/watterott/ATmega328PB-Testing"}, 101 | "url": "https://github.com/watterott/ATmega328PB-Testing/raw/4ce95b1711efa12aa6a874421739cf5be08cf6bb/m328pb.zip", 102 | "archiveFileName": "m328pb-1.0.8.zip", 103 | "checksum": "SHA-256:7a141693d347d747cb175171edfd7e731db75be1da2b8689c5c69fa879bacdd2", 104 | "size": "85517", 105 | "boards": [ 106 | {"name": "ATmega328PB"} 107 | ] 108 | }, 109 | { 110 | "name": "ATmega328PB Boards", 111 | "architecture": "avr", 112 | "version": "1.0.7", 113 | "category": "contributed", 114 | "help": {"online": "https://github.com/watterott/ATmega328PB-Testing"}, 115 | "url": "https://github.com/watterott/ATmega328PB-Testing/raw/db85f07b07a3d807c6b0d765819b18492a1b0bd3/m328pb.zip", 116 | "archiveFileName": "m328pb-1.0.7.zip", 117 | "checksum": "SHA-256:a0dad34884e3ef4d5bb828c233b19e3ee3307b5120d2bfb50bf97b7d2b2dc667", 118 | "size": "85517", 119 | "boards": [ 120 | {"name": "ATmega328PB"} 121 | ] 122 | }, 123 | { 124 | "name": "ATmega328PB Boards", 125 | "architecture": "avr", 126 | "version": "1.0.6", 127 | "category": "contributed", 128 | "help": {"online": "https://github.com/watterott/ATmega328PB-Testing"}, 129 | "url": "https://github.com/watterott/ATmega328PB-Testing/raw/ee59a8487cbc1efd69e08f4c005594f7042cb342/m328pb.zip", 130 | "archiveFileName": "m328pb-1.0.6.zip", 131 | "checksum": "SHA-256:c6f4aabc902ccb1b87c98bf06fdee8a80ee19667f426a5bc977a7abde8f0e3e4", 132 | "size": "85517", 133 | "boards": [ 134 | {"name": "ATmega328PB"} 135 | ], 136 | "toolsDependencies": [ 137 | { 138 | "packager": "arduino", 139 | "name": "avrdude", 140 | "version": "6.3.0-arduino2" 141 | } 142 | ] 143 | }, 144 | { 145 | "name": "ATmega328PB Boards", 146 | "architecture": "avr", 147 | "version": "1.0.5", 148 | "category": "contributed", 149 | "help": {"online": "https://github.com/watterott/ATmega328PB-Testing"}, 150 | "url": "https://github.com/watterott/ATmega328PB-Testing/raw/d90f0697c5a24553a96ad41cb2605edba7057a75/m328pb.zip", 151 | "archiveFileName": "m328pb-1.0.5.zip", 152 | "checksum": "SHA-256:cf9be8404e4cf1d247d036f9781306f82d25c7195c2d6bee6d30f4ea502e0a2e", 153 | "size": "85567", 154 | "boards": [ 155 | {"name": "ATmega328PB"} 156 | ], 157 | "toolsDependencies": [ 158 | { 159 | "packager": "arduino", 160 | "name": "avrdude", 161 | "version": "6.3.0-arduino2" 162 | } 163 | ] 164 | }, 165 | { 166 | "name": "ATmega328PB Boards", 167 | "architecture": "avr", 168 | "version": "1.0.4", 169 | "category": "contributed", 170 | "help": {"online": "https://github.com/watterott/ATmega328PB-Testing"}, 171 | "url": "https://github.com/watterott/ATmega328PB-Testing/raw/8fc3888eaa5c0dc8e715ac47b3a9d33f7657dda6/m328pb.zip", 172 | "archiveFileName": "m328pb-1.0.4.zip", 173 | "checksum": "SHA-256:bcb06cdbd89e003dcbbd8646c9325b8429a9a7dc9868e0416f76d2d580ba43f5", 174 | "size": "84449", 175 | "boards": [ 176 | {"name": "ATmega328PB"} 177 | ], 178 | "toolsDependencies": [ 179 | { 180 | "packager": "arduino", 181 | "name": "avrdude", 182 | "version": "6.3.0-arduino2" 183 | } 184 | ] 185 | }, 186 | { 187 | "name": "ATmega328PB Boards", 188 | "architecture": "avr", 189 | "version": "1.0.3", 190 | "category": "contributed", 191 | "help": {"online": "https://github.com/watterott/ATmega328PB-Testing"}, 192 | "url": "https://github.com/watterott/ATmega328PB-Testing/raw/49211563cb515c8924eb91fa7e393652062da989/m328pb.zip", 193 | "archiveFileName": "m328pb-1.0.3.zip", 194 | "checksum": "SHA-256:204cf2e9d3885a9690459d6d716e867ded5ee756e5e182136af8a21956c1427f", 195 | "size": "53995", 196 | "boards": [ 197 | {"name": "ATmega328PB"} 198 | ] 199 | }, 200 | { 201 | "name": "ATmega328PB Boards", 202 | "architecture": "avr", 203 | "version": "1.0.2", 204 | "category": "contributed", 205 | "help": {"online": "https://github.com/watterott/ATmega328PB-Testing"}, 206 | "url": "https://github.com/watterott/ATmega328PB-Testing/raw/610a28ee8b438d05bab3f2e71b701fa6958fb4c3/m328pb.zip", 207 | "archiveFileName": "m328pb-1.0.2.zip", 208 | "checksum": "SHA-256:c2cb5352941f76a49ee9d40d41ab1060c4e9ab5706b046a0ba70b25fc0cadb3f", 209 | "size": "53826", 210 | "boards": [ 211 | {"name": "ATmega328PB"} 212 | ], 213 | "toolsDependencies": [ 214 | { 215 | "packager": "m328pb", 216 | "name": "avr-gcc", 217 | "version": "4.9.2c" 218 | }, 219 | { 220 | "packager": "m328pb", 221 | "name": "avrdude", 222 | "version": "6.3.0" 223 | } 224 | ] 225 | }, 226 | { 227 | "name": "ATmega328PB Boards", 228 | "architecture": "avr", 229 | "version": "1.0.1", 230 | "category": "contributed", 231 | "help": {"online": "https://github.com/watterott/ATmega328PB-Testing"}, 232 | "url": "https://github.com/watterott/ATmega328PB-Testing/raw/610a28ee8b438d05bab3f2e71b701fa6958fb4c3/m328pb.zip", 233 | "archiveFileName": "m328pb-1.0.1.zip", 234 | "checksum": "SHA-256:c2cb5352941f76a49ee9d40d41ab1060c4e9ab5706b046a0ba70b25fc0cadb3f", 235 | "size": "53826", 236 | "boards": [ 237 | {"name": "ATmega328PB"} 238 | ], 239 | "toolsDependencies": [ 240 | { 241 | "packager": "m328pb", 242 | "name": "avr-gcc", 243 | "version": "4.9.2b" 244 | }, 245 | { 246 | "packager": "m328pb", 247 | "name": "avrdude", 248 | "version": "6.3.0" 249 | } 250 | ] 251 | }, 252 | { 253 | "name": "ATmega328PB Boards", 254 | "architecture": "avr", 255 | "version": "1.0.0", 256 | "category": "contributed", 257 | "help": {"online": "https://github.com/watterott/ATmega328PB-Testing"}, 258 | "url": "https://github.com/watterott/ATmega328PB-Testing/raw/610a28ee8b438d05bab3f2e71b701fa6958fb4c3/m328pb.zip", 259 | "archiveFileName": "m328pb-1.0.0.zip", 260 | "checksum": "SHA-256:c2cb5352941f76a49ee9d40d41ab1060c4e9ab5706b046a0ba70b25fc0cadb3f", 261 | "size": "53826", 262 | "boards": [ 263 | {"name": "ATmega328PB"} 264 | ], 265 | "toolsDependencies": [ 266 | { 267 | "packager": "m328pb", 268 | "name": "avr-gcc", 269 | "version": "4.9.2" 270 | }, 271 | { 272 | "packager": "m328pb", 273 | "name": "avrdude", 274 | "version": "6.3.0" 275 | } 276 | ] 277 | } 278 | ], 279 | 280 | "tools": [ 281 | { 282 | "name":"avr-gcc", 283 | "version":"4.9.2c", 284 | "systems": [ 285 | { 286 | "host":"i686-mingw32", 287 | "url":"https://github.com/watterott/ATmega328PB-Testing/raw/0157dbf8333d512e75a71a3e7a9c3cb02915b371/avr-gcc-4.9.2-win32.zip", 288 | "archiveFileName":"avr-gcc-4.9.2c-win32.zip", 289 | "checksum":"MD5:e4786528c0a4cb009eb441da07d82ced", 290 | "size":"43832130" 291 | } 292 | ] 293 | }, 294 | { 295 | "name":"avr-gcc", 296 | "version":"4.9.2b", 297 | "systems": [ 298 | { 299 | "host":"i686-mingw32", 300 | "url":"https://github.com/watterott/ATmega328PB-Testing/raw/d37d112a5661098fbf14e7c2faca3c9c9fcf3b7f/avr-gcc-4.9.2-win32.zip", 301 | "archiveFileName":"avr-gcc-4.9.2b-win32.zip", 302 | "checksum":"MD5:4dd147d70307775b705636ffa66f8a4b", 303 | "size":"43772922" 304 | } 305 | ] 306 | }, 307 | { 308 | "name":"avr-gcc", 309 | "version":"4.9.2", 310 | "systems": [ 311 | { 312 | "host":"i686-mingw32", 313 | "url":"https://github.com/watterott/ATmega328PB-Testing/raw/3d10e8ce26fc1753a7e115136163c1bd36d258ee/avr-gcc-4.9.2-win32.zip", 314 | "archiveFileName":"avr-gcc-4.9.2-win32.zip", 315 | "checksum":"MD5:3a775c1114e1802831f3a2ad59a7bb69", 316 | "size":"41504987" 317 | }, 318 | { 319 | "host":"x86_64-linux-gnu", 320 | "url":"https://github.com/watterott/ATmega328PB-Testing/raw/7cd41a631b90e374868bd139bf4a7c77fcbbffc5/avr-gcc-4.9.2-linux_64.tar.bz2", 321 | "archiveFileName":"avr-gcc-4.9.2-linux_64.tar.bz2", 322 | "checksum":"MD5:07cacdecda66b82f8addf5bbd8a6e210", 323 | "size":"25084308" 324 | } 325 | ] 326 | }, 327 | { 328 | "name":"avrdude", 329 | "version":"6.3.0", 330 | "systems": [ 331 | { 332 | "host":"i686-mingw32", 333 | "url":"https://github.com/watterott/ATmega328PB-Testing/raw/610a28ee8b438d05bab3f2e71b701fa6958fb4c3/avrdude-6.3.0-win32.zip", 334 | "archiveFileName":"avrdude-6.3.0-win32.zip", 335 | "checksum":"MD5:ec665463025eaafb940e0a3e9ef1fee5", 336 | "size":"220965" 337 | } 338 | ] 339 | } 340 | ] 341 | } 342 | ] 343 | } 344 | --------------------------------------------------------------------------------