├── .gitignore ├── .travis.yml ├── DATS ├── arduino.dats ├── ethernet_w5100.dats ├── hardware_serial.dats ├── lcd.dats ├── smbus.dats └── spi.dats ├── LICENSE ├── Makefile ├── Makefile.common ├── Makefile.common_c ├── README.md ├── SATS ├── arduino.sats ├── eeprom.sats ├── ethernet_w5100.sats ├── hardware_serial.sats ├── lcd.sats ├── smbus.sats ├── spi.sats └── twi.sats ├── _arduino ├── Arduino.h ├── SPI.h ├── binary.h ├── hardware_serial.c ├── hardware_serial.h ├── pins_arduino.h ├── twi.c ├── twi.h ├── variants │ ├── mega │ │ └── pins_arduino.h │ └── standard │ │ └── pins_arduino.h ├── w5100.h ├── wiring.c ├── wiring_analog.c ├── wiring_digital.c └── wiring_private.h ├── _dummy └── sys │ ├── stat.h │ └── types.h ├── _img ├── ArduinoMega2560_R3.jpg ├── ArduinoUnoR3.jpg ├── avr_dragon.jpg ├── book.png ├── demo_arch.odg └── demo_arch.png ├── avr_prelude ├── DATS │ └── string0.dats ├── SATS │ └── string0.sats ├── kernel_prelude.cats └── kernel_staload.hats ├── demo ├── 01_blink │ ├── DATS │ │ └── main.dats │ ├── Makefile │ └── config.hats ├── 02_button_press │ ├── DATS │ │ └── main.dats │ ├── Makefile │ └── config.hats ├── 03_de_bouncing │ ├── DATS │ │ └── main.dats │ ├── Makefile │ └── config.hats ├── 04_pwm │ ├── DATS │ │ └── main.dats │ ├── Makefile │ └── config.hats ├── 04_pwm_closure │ ├── DATS │ │ └── main.dats │ ├── Makefile │ └── config.hats ├── 05_pwm_button │ ├── DATS │ │ └── main.dats │ ├── Makefile │ └── config.hats ├── 06a_analoginput_blink │ ├── DATS │ │ └── main.dats │ ├── Makefile │ └── config.hats ├── 06b_analoginput_pwm │ ├── DATS │ │ └── main.dats │ ├── Makefile │ └── config.hats ├── 07_analoginput_serial │ ├── DATS │ │ └── main.dats │ ├── Makefile │ └── config.hats ├── Makefile ├── eeprom │ ├── DATS │ │ └── main.dats │ ├── Makefile │ └── config.hats ├── i2c │ ├── DATS │ │ └── main.dats │ ├── Makefile │ └── config.hats ├── lcd_greeting │ ├── DATS │ │ └── main.dats │ ├── Makefile │ └── config.hats ├── serial │ ├── DATS │ │ └── main.dats │ ├── Makefile │ └── config.hats └── smbus │ ├── DATS │ └── main.dats │ ├── Makefile │ └── config.hats └── demo_c ├── 01_blink ├── Makefile └── main.c ├── 02_button_press ├── Makefile └── main.c ├── 03_de_bouncing ├── Makefile └── main.c ├── 04_pwm ├── Makefile └── main.c ├── 05_pwm_button ├── Makefile ├── main.c └── main.c.new ├── 06a_analoginput_blink ├── Makefile └── main.c ├── 06b_analoginput_pwm ├── Makefile └── main.c └── Makefile /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | 5 | # Libraries 6 | *.lib 7 | *.a 8 | 9 | # Shared objects (inc. Windows DLLs) 10 | *.dll 11 | *.so 12 | *.so.* 13 | *.dylib 14 | 15 | # Executables 16 | *.exe 17 | *.out 18 | *.app 19 | *.elf 20 | *.hex 21 | *.map 22 | *.bin 23 | *.lst 24 | *.srec 25 | 26 | # C files 27 | pats_ccomp_typedefs.h 28 | blink_ats/main.c 29 | *_dats.c 30 | *.tmp 31 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | before_install: 2 | - date 3 | - cat /proc/cpuinfo 4 | - cd ${HOME} 5 | - sudo apt-get -qq -y install binutils-avr gcc-avr avr-libc avrdude libgmp-dev 6 | - git clone https://github.com/githwxi/ATS-Postiats.git 7 | - git clone https://github.com/githwxi/ATS-Postiats-contrib.git 8 | # Build ATS1 9 | - export ATSHOME=${HOME}/ats-lang-anairiats-0.2.12 10 | - export ATSHOMERELOC=ATS-0.2.12 11 | - ${HOME}/ATS-Postiats/travis-ci/ats1_setup.sh 0.2.12 12 | - cd ${ATSHOME} && ./configure && make 13 | # Build ATS2 14 | - export PATSHOME=${HOME}/ATS-Postiats 15 | - export PATSHOMERELOC=${HOME}/ATS-Postiats-contrib 16 | - export PATH=${PATH}:${PATSHOME}/bin 17 | - cd ${PATSHOME} && make -f codegen/Makefile_atslib && make -f Makefile_devl src_depend && make -f Makefile_devl all 18 | script: 19 | - cd ${TRAVIS_BUILD_DIR} 20 | - make 21 | after_script: 22 | - date 23 | -------------------------------------------------------------------------------- /DATS/arduino.dats: -------------------------------------------------------------------------------- 1 | #include "config.hats" 2 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 3 | 4 | staload "{$TOP}/SATS/arduino.sats" 5 | 6 | implement main0 () = { 7 | val () = init () 8 | val () = main () 9 | } 10 | -------------------------------------------------------------------------------- /DATS/ethernet_w5100.dats: -------------------------------------------------------------------------------- 1 | %{^ 2 | #include "w5100.h" 3 | %} 4 | 5 | #include "config.hats" 6 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 7 | 8 | staload "{$TOP}/SATS/arduino.sats" 9 | staload "{$TOP}/SATS/spi.sats" 10 | staload "{$TOP}/SATS/ethernet_w5100.sats" 11 | staload UN = "prelude/SATS/unsafe.sats" 12 | 13 | macdef DDRB_PTR = $extval(ptr, "(&DDRB)") 14 | macdef PORTB_PTR = $extval(ptr, "(&PORTB)") 15 | 16 | extern fun initSS (): void = "mac#" 17 | extern fun setSS (): void = "mac#" 18 | extern fun resetSS (): void = "mac#" 19 | 20 | fun _write (addr: uint16, data: uint8): void = { 21 | val () = setSS () 22 | val _ = spi_transfer ($UN.cast{uint8}(0xf0)) 23 | val _ = spi_transfer ($UN.cast{uint8}(addr >> 8)) 24 | val v = g0uint_land_uint16 (addr, ($UN.cast{uint16}(0xff))) 25 | val _ = spi_transfer ($UN.cast{uint8}(v)) 26 | val _ = spi_transfer data 27 | val () = resetSS () 28 | } 29 | 30 | fun _read (addr: uint16): uint8 = r where { 31 | val () = setSS () 32 | val _ = spi_transfer ($UN.cast{uint8}(0xf0)) 33 | val _ = spi_transfer ($UN.cast (addr >> 8)) 34 | val v = g0uint_land_uint16 (addr, ($UN.cast{uint16}(0xff))) 35 | val _ = spi_transfer ($UN.cast{uint8}(v)) 36 | val r = spi_transfer ($UN.cast{uint8}(0)) 37 | val () = resetSS () 38 | } 39 | 40 | implement ethernet_w5100_init () = { 41 | val () = delay_ms 300.0 42 | val () = spi_begin () 43 | val () = initSS () 44 | // xxx 45 | } 46 | -------------------------------------------------------------------------------- /DATS/hardware_serial.dats: -------------------------------------------------------------------------------- 1 | %{^ 2 | #include "hardware_serial.h" 3 | 4 | #if defined(UBRRH) && defined(UBRRL) 5 | #define ADDR_UBRRH (UBRRH) 6 | #define ADDR_UBRRL (UBRRL) 7 | #define ADDR_UCSRA (UCSRA) 8 | #define ADDR_UCSRB (UCSRB) 9 | #define ADDR_UCSRC (UCSRC) 10 | #define ADDR_UDR (UDR) 11 | #define BIT_RXEN (RXEN) 12 | #define BIT_TXEN (TXEN) 13 | #define BIT_RXCIE (RXCIE) 14 | #define BIT_UDRIE (UDRIE) 15 | #define BIT_U2X (U2X) 16 | #define BIT_UPE (PE) 17 | #elif defined(UBRR0H) && defined(UBRR0L) 18 | #define ADDR_UBRRH (UBRR0H) 19 | #define ADDR_UBRRL (UBRR0L) 20 | #define ADDR_UCSRA (UCSR0A) 21 | #define ADDR_UCSRB (UCSR0B) 22 | #define ADDR_UCSRC (UCSR0C) 23 | #define ADDR_UDR (UDR0) 24 | #define BIT_RXEN (RXEN0) 25 | #define BIT_TXEN (TXEN0) 26 | #define BIT_RXCIE (RXCIE0) 27 | #define BIT_UDRIE (UDRIE0) 28 | #define BIT_U2X (U2X0) 29 | #define BIT_UPE (UPE0) 30 | #else 31 | #error no serial port defined (port 0) 32 | #endif 33 | 34 | bool ats_serial_transmitting; 35 | %} 36 | 37 | #include "config.hats" 38 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 39 | 40 | staload "{$TOP}/avr_prelude/SATS/string0.sats" 41 | staload _ = "{$TOP}/avr_prelude/DATS/string0.dats" 42 | staload "{$TOP}/SATS/arduino.sats" 43 | staload "{$TOP}/SATS/hardware_serial.sats" 44 | staload UN = "prelude/SATS/unsafe.sats" 45 | 46 | abst@ype hardware_serial = $extype"struct hardware_serial" 47 | macdef hserial = $extval(cPtr0(hardware_serial), "(&Serial)") 48 | 49 | macdef F_CPU = $extval(ulint, "F_CPU") 50 | 51 | abst@ype ring_buffer = $extype"struct ring_buffer" 52 | macdef rx_buffer = $extval(cPtr0(ring_buffer), "&rx_buffer") 53 | macdef tx_buffer = $extval(cPtr0(ring_buffer), "&tx_buffer") 54 | 55 | macdef ADDR_UBRRH = $extval(ptr, "&ADDR_UBRRH") 56 | macdef ADDR_UBRRL = $extval(ptr, "&ADDR_UBRRL") 57 | macdef ADDR_UCSRA = $extval(ptr, "&ADDR_UCSRA") 58 | macdef ADDR_UCSRB = $extval(ptr, "&ADDR_UCSRB") 59 | macdef ADDR_UCSRC = $extval(ptr, "&ADDR_UCSRC") 60 | macdef ADDR_UDR = $extval(ptr, "&ADDR_UDR") 61 | macdef BIT_RXEN = $extval(uint8, "BIT_RXEN") 62 | macdef BIT_TXEN = $extval(uint8, "BIT_TXEN") 63 | macdef BIT_RXCIE = $extval(uint8, "BIT_RXCIE") 64 | macdef BIT_UDRIE = $extval(uint8, "BIT_UDRIE") 65 | macdef BIT_U2X = $extval(uint8, "BIT_U2X") 66 | macdef BIT_TXC0 = $extval(uint8, "TXC0") 67 | macdef BIT_UPE = $extval(uint8, "BIT_UPE") 68 | macdef VAL_U2X = $extval(uint8, "(1 << BIT_U2X)") 69 | 70 | macdef transmitting = $extval(ptr, "&ats_serial_transmitting") 71 | 72 | extern fun ringbuf_insert_nowait: (uchar, cPtr0(ring_buffer)) -> void = "mac#" 73 | extern fun ringbuf_insert_wait: (uchar, cPtr0(ring_buffer)) -> void = "mac#" 74 | extern fun ringbuf_is_empty: (cPtr0(ring_buffer)) -> bool = "mac#" 75 | extern fun ringbuf_get_size: (cPtr0(ring_buffer)) -> uint = "mac#" 76 | extern fun ringbuf_peek: (cPtr0(ring_buffer)) -> uchar = "mac#" 77 | extern fun ringbuf_remove: (cPtr0(ring_buffer)) -> uchar = "mac#" 78 | extern fun ringbuf_clear: (cPtr0(ring_buffer)) -> void = "mac#" 79 | 80 | extern fun c_sbi: (ptr, uint8) -> void = "mac#" 81 | extern fun c_cbi: (ptr, uint8) -> void = "mac#" 82 | extern fun c_rbi: (ptr, uint8) -> uint8 = "mac#" 83 | 84 | extern fun ats_serial_rx_vect: () -> void = "ext#" 85 | extern fun ats_serial_tx_vect: () -> void = "ext#" 86 | 87 | fun set_transmitting (t:bool): void = $UN.ptr0_set (transmitting, t) 88 | fun get_transmitting (): bool = $UN.ptr0_get (transmitting) 89 | 90 | implement ats_serial_rx_vect () = { 91 | val b = c_rbi (ADDR_UCSRA, BIT_UPE) 92 | val c = $UN.ptr0_get (ADDR_UDR) 93 | val () = if ($UN.cast2int b) = 0 then ringbuf_insert_nowait (c, rx_buffer) 94 | } 95 | 96 | implement ats_serial_tx_vect () = 97 | if ringbuf_is_empty tx_buffer then { 98 | // Buffer empty, so disable interrupts 99 | val () = c_cbi (ADDR_UCSRB, BIT_UDRIE) 100 | } else { 101 | // There is more data in the output buffer. Send the next byte 102 | val c = ringbuf_remove tx_buffer 103 | val () = $UN.ptr0_set (ADDR_UDR, c) 104 | } 105 | 106 | implement serial_begin (baud) = { 107 | fun get_baud_setting_u2x (): ulint = let 108 | val v = VAL_U2X // xxx 1U << BIT_U2X 109 | val () = $UN.ptr0_set (ADDR_UCSRA, v) 110 | val setting = (F_CPU / 4UL / baud - 1UL) / 2UL 111 | in 112 | setting 113 | end 114 | fun get_baud_setting (): ulint = let 115 | val () = $UN.ptr0_set (ADDR_UCSRA, $UN.cast{uint8}(0)) 116 | val setting = (F_CPU / 8UL / baud - 1UL) / 2UL 117 | in 118 | setting 119 | end 120 | // hardcoded exception for compatibility with the bootloader shipped 121 | // with the Duemilanove and previous boards and the firmware on the 8U2 122 | // on the Uno and Mega 2560. 123 | val use_u2x = not(F_CPU = 16000000UL andalso baud = 57600UL) 124 | val tmp = if use_u2x then get_baud_setting_u2x () else get_baud_setting () 125 | fun test (setting:ulint): bool = setting > 4095UL 126 | val baud_setting = if ((test tmp) andalso use_u2x) then get_baud_setting () else tmp 127 | 128 | // assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register) 129 | val () = $UN.ptr0_set (ADDR_UBRRL, $UN.cast{uint8}(g0uint_lsr (baud_setting, 8))) 130 | val () = $UN.ptr0_set (ADDR_UBRRL, $UN.cast{uint8}(baud_setting)) 131 | 132 | val () = set_transmitting (false) 133 | 134 | val () = c_sbi (ADDR_UCSRB, BIT_RXEN) 135 | val () = c_sbi (ADDR_UCSRB, BIT_TXEN) 136 | val () = c_sbi (ADDR_UCSRB, BIT_RXCIE) 137 | val () = c_cbi (ADDR_UCSRB, BIT_UDRIE) 138 | } 139 | 140 | implement serial_flush () = { 141 | // UDR is kept full while the buffer is not empty, so TXC triggers when EMPTY && SENT 142 | fun loop () = let 143 | val t = get_transmitting () 144 | val b = c_rbi (ADDR_UCSRA, BIT_TXC0) 145 | in 146 | if (t andalso (($UN.cast2int b) = 0)) then loop () 147 | end 148 | val () = loop () 149 | val () = set_transmitting (false) 150 | } 151 | 152 | implement serial_available () = 153 | ringbuf_get_size rx_buffer 154 | 155 | implement serial_peek () = 156 | if (ringbuf_is_empty (rx_buffer)) then 157 | ~1 158 | else 159 | $UN.cast{int}(ringbuf_peek (rx_buffer)) 160 | 161 | implement serial_read () = 162 | if (ringbuf_is_empty (rx_buffer)) then 163 | ~1 164 | else 165 | $UN.cast{int}(ringbuf_remove (rx_buffer)) 166 | 167 | implement serial_write (c) = let 168 | val () = ringbuf_insert_wait ($UN.cast{uchar}(c), tx_buffer) 169 | val () = c_sbi (ADDR_UCSRB, BIT_UDRIE) 170 | // clear the TXC bit -- "can be cleared by writing a one to its bit location" 171 | val () = set_transmitting (true) 172 | val () = c_sbi (ADDR_UCSRA, BIT_TXC0) 173 | in 174 | $UN.cast{size_t}(1) 175 | end 176 | 177 | implement serial_end () = { 178 | // wait for transmission of outgoing data 179 | fun loop () = if not(ringbuf_is_empty (tx_buffer)) then loop () 180 | val () = loop () 181 | val () = c_cbi (ADDR_UCSRB, BIT_RXEN) 182 | val () = c_cbi (ADDR_UCSRB, BIT_TXEN) 183 | val () = c_cbi (ADDR_UCSRB, BIT_RXCIE) 184 | val () = c_cbi (ADDR_UCSRB, BIT_UDRIE) 185 | // clear any received data 186 | val () = ringbuf_clear (rx_buffer) 187 | } 188 | 189 | // atspre_print_char 190 | implement print_char (c) = { 191 | val _ = serial_write c 192 | } 193 | 194 | implement print_int (i) = { 195 | #define BSZ 32 196 | typedef cstring = $extype"atstype_string" 197 | var buf = @[byte][BSZ]() 198 | val bufp = $UN.cast{cstring}(addr@buf) 199 | val _ = $extfcall(ssize_t, "snprintf", bufp, BSZ, "%i", i) 200 | val () = print_string ($UN.cast{string}(bufp)) 201 | } 202 | 203 | implement print_uint8 (i) = print_int ($UN.cast{int}(i)) 204 | 205 | // atspre_print_string 206 | implement print_string (s) = { 207 | implement{env} 208 | string0_foreach$fwork 209 | (c, env) = {val _ = serial_write (c)} 210 | val _ = string0_foreach s 211 | } 212 | 213 | // atspre_print_newline 214 | implement print_newline () = { 215 | val _ = serial_write ('\r') 216 | val _ = serial_write ('\n') 217 | val () = serial_flush () 218 | } 219 | 220 | %{$ 221 | #if !defined(USART_RX_vect) && !defined(USART0_RX_vect) && !defined(USART_RXC_vect) 222 | #error "Don't know what the Data Received vector is called for the first UART" 223 | #else 224 | #if defined(USART_RX_vect) 225 | ISR(USART_RX_vect) 226 | #elif defined(USART0_RX_vect) 227 | ISR(USART0_RX_vect) 228 | #elif defined(USART_RXC_vect) 229 | ISR(USART_RXC_vect) // ATmega8 230 | #endif 231 | { 232 | ats_serial_rx_vect(); 233 | } 234 | #endif 235 | 236 | #if !defined(UART0_UDRE_vect) && !defined(UART_UDRE_vect) && !defined(USART0_UDRE_vect) && !defined(USART_UDRE_vect) 237 | #error "Don't know what the Data Register Empty vector is called for the first UART" 238 | #else 239 | #if defined(UART0_UDRE_vect) 240 | ISR(UART0_UDRE_vect) 241 | #elif defined(UART_UDRE_vect) 242 | ISR(UART_UDRE_vect) 243 | #elif defined(USART0_UDRE_vect) 244 | ISR(USART0_UDRE_vect) 245 | #elif defined(USART_UDRE_vect) 246 | ISR(USART_UDRE_vect) 247 | #endif 248 | { 249 | ats_serial_tx_vect(); 250 | } 251 | #endif 252 | %} 253 | -------------------------------------------------------------------------------- /DATS/lcd.dats: -------------------------------------------------------------------------------- 1 | (* 2 | * For LinkSprite 16X2 LCD Keypad Shield for Arduino 3 | * http://store.linksprite.com/linksprite-16x2-lcd-keypad-shield-for-arduino-version-b/ 4 | * http://www.linksprite.com/wiki/index.php5?title=16_X_2_LCD_Keypad_Shield_for_Arduino 5 | *) 6 | #include "config.hats" 7 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 8 | 9 | staload "{$TOP}/SATS/arduino.sats" 10 | staload "{$TOP}/SATS/lcd.sats" 11 | staload UN = "prelude/SATS/unsafe.sats" 12 | 13 | %{ 14 | inline uint8_t atspre_uint8_bit_or(uint8_t a, uint8_t b) { return (a | b); } 15 | inline uint8_t atspre_uint8_bit_and(uint8_t a, uint8_t b) { return (a & b); } 16 | %} 17 | extern fun uint8_bit_or: (uint8, uint8) -> uint8 = "mac#atspre_uint8_bit_or" 18 | extern fun uint8_bit_and: (uint8, uint8) -> uint8 = "mac#atspre_uint8_bit_and" 19 | 20 | (* Private struct *) 21 | vtypedef lcd_t_struct = @{ 22 | rs_pin = pin_t // LOW: command. HIGH: character. 23 | , rw_pin = pin_t // LOW: write to lcd_t. HIGH: read from lcd_t. 24 | , enable_pin = pin_t // activated by a HIGH pulse. 25 | , data_pins = @(pin_t, pin_t, pin_t, pin_t) 26 | , displayfunction = uint8 27 | , displaycontrol = uint8 28 | , displaymode = uint8 29 | , numlines = uint8 30 | , currline = uint8 31 | } 32 | absvtype lcd_t_minus_struct (l:addr) 33 | extern castfn 34 | lcd_t_takeout_struct (* xxx Should lock *) 35 | ( 36 | tcp: !lcd_t >> lcd_t_minus_struct l 37 | ) : #[l:addr] (lcd_t_struct @ l | ptr l) 38 | extern praxi 39 | lcd_t_addback_struct (* xxx Should unlock *) 40 | {l:addr} 41 | ( 42 | pfat: lcd_t_struct @ l 43 | | tcp: !lcd_t_minus_struct l >> lcd_t 44 | ) : void 45 | 46 | (* Low level functions *) 47 | extern fun lcd_display: {l:addr} (!lcd_t_struct @ l | ptr l) -> void 48 | extern fun lcd_command: {l:addr} (!lcd_t_struct @ l | ptr l, uint8) -> void 49 | extern fun lcd_send: {l:addr} (!lcd_t_struct @ l | ptr l, uint8, natLt(2)) -> void 50 | extern fun lcd_pulseEnable: {l:addr} (!lcd_t_struct @ l | ptr l) -> void 51 | extern fun lcd_write4bits: {l:addr} (!lcd_t_struct @ l | ptr l, uint8) -> void 52 | 53 | local 54 | var _global_lcd_struct: lcd_t_struct 55 | in 56 | implement lcd_open (rs, rw, enable, d0, d1, d2, d3) = let 57 | val lcd = $UN.castvwtp0 (addr@_global_lcd_struct) 58 | val (pfat | p) = lcd_t_takeout_struct (lcd) 59 | val () = p->rs_pin := $UN.cast{pin_t}(rs) 60 | val () = p->rw_pin := $UN.cast{pin_t}(rw) 61 | val () = p->enable_pin := $UN.cast{pin_t}(enable) 62 | val () = p->data_pins.0 := $UN.cast{pin_t}(d0) 63 | val () = p->data_pins.1 := $UN.cast{pin_t}(d1) 64 | val () = p->data_pins.2 := $UN.cast{pin_t}(d2) 65 | val () = p->data_pins.3 := $UN.cast{pin_t}(d3) 66 | val () = pinMode (p->rs_pin, OUTPUT) 67 | val () = pinMode (p->rw_pin, OUTPUT) 68 | val () = pinMode (p->enable_pin, OUTPUT) 69 | val LCD_4BITMODE = $UN.cast{uint8}(0x00) 70 | val LCD_2LINE = $UN.cast{uint8}(0x08) 71 | val LCD_5x8DOTS = $UN.cast{uint8}(0x00) 72 | val () = p->displayfunction := uint8_bit_or (LCD_4BITMODE, uint8_bit_or (LCD_2LINE, LCD_5x8DOTS)) 73 | prval () = lcd_t_addback_struct(pfat | lcd) 74 | fun lcd_begin (lcd: !lcd_t, lines: uint8): void = { 75 | val (pfat | p) = lcd_t_takeout_struct (lcd) 76 | val () = p->numlines := lines 77 | val () = p->currline := $UN.cast{uint8}(0) 78 | val () = delay_us 50000.0 79 | val () = digitalWrite (p->rs_pin, LOW) 80 | val () = digitalWrite (p->enable_pin, LOW) 81 | val () = digitalWrite (p->rw_pin, LOW) 82 | val displayfunction = p->displayfunction 83 | // this is according to the hitachi HD44780 datasheet / figure 24, pg 46 84 | // we start in 8bit mode, try to set 4 bit mode 85 | val () = lcd_write4bits (pfat | p, $UN.cast{uint8}(0x03)) 86 | val () = delay_us 4500.0 87 | val () = lcd_write4bits (pfat | p, $UN.cast{uint8}(0x03)) // second try 88 | val () = delay_us 4500.0 89 | val () = lcd_write4bits (pfat | p, $UN.cast{uint8}(0x03)) // third go! 90 | val () = delay_us 150.0 91 | val () = lcd_write4bits (pfat | p, $UN.cast{uint8}(0x02)) // finally, set to 4-bit interface 92 | // finally, set # lines, font size, etc. 93 | val LCD_FUNCTIONSET = $UN.cast{uint8}(0x20) 94 | val () = lcd_command (pfat | p, uint8_bit_or (LCD_FUNCTIONSET, displayfunction)) 95 | // turn the display on with no cursor or blinking default 96 | val LCD_DISPLAYON = $UN.cast{uint8}(0x04) 97 | val LCD_CURSOROFF = $UN.cast{uint8}(0x00) 98 | val LCD_BLINKOFF = $UN.cast{uint8}(0x00) 99 | val () = p->displaycontrol := uint8_bit_or (LCD_DISPLAYON, uint8_bit_or (LCD_CURSOROFF, LCD_BLINKOFF)) 100 | val () = lcd_display (pfat | p) 101 | // Initialize to default text direction (for romance languages) 102 | val LCD_ENTRYLEFT = $UN.cast{uint8}(0x02) 103 | val LCD_ENTRYSHIFTDECREMENT = $UN.cast{uint8}(0x00) 104 | val () = p->displaymode := uint8_bit_or (LCD_ENTRYLEFT, LCD_ENTRYSHIFTDECREMENT) 105 | val displaymode = p->displaymode 106 | // set the entry mode 107 | val LCD_ENTRYMODESET = $UN.cast{uint8}(0x04) 108 | val () = lcd_command (pfat | p, uint8_bit_or (LCD_ENTRYMODESET, displaymode)) 109 | prval () = lcd_t_addback_struct(pfat | lcd) 110 | // clear it off 111 | val () = lcd_clear lcd 112 | } 113 | val () = lcd_begin (lcd, $UN.cast{uint8}(2)) 114 | in 115 | lcd 116 | end 117 | end 118 | 119 | implement lcd_close (lcd) = { 120 | val () = $UN.castvwtp0(lcd) (* Consume lcd *) 121 | } 122 | 123 | implement lcd_clear (lcd) = { 124 | val LCD_CLEARDISPLAY = $UN.cast{uint8}(0x01) 125 | val (pfat | p) = lcd_t_takeout_struct (lcd) 126 | val () = lcd_command (pfat | p, LCD_CLEARDISPLAY) // clear display, set cursor position to zero 127 | prval () = lcd_t_addback_struct(pfat | lcd) 128 | val () = delay_us 2000.0 // this command takes a long time! 129 | } 130 | 131 | implement lcd_setCursor (lcd, col, row) = { 132 | val LCD_SETDDRAMADDR = $UN.cast{uint8}(0x80) 133 | val row_ofs = if row > 0 then 0x40 else 0x00:int 134 | val v = (col:int) + (row_ofs:int) 135 | val (pfat | p) = lcd_t_takeout_struct (lcd) 136 | val () = lcd_command(pfat | p, uint8_bit_or (LCD_SETDDRAMADDR, $UN.cast{uint8}(v))) 137 | prval () = lcd_t_addback_struct(pfat | lcd) 138 | } 139 | 140 | implement lcd_print (lcd, str, start, len) = { 141 | fun w (lcd: !lcd_t, p: ptr): void = { 142 | val c = $UN.ptr0_get (p) 143 | val () = lcd_write (lcd, c) 144 | } 145 | fun loop (lcd: !lcd_t, p: ptr, r: size_t): void = { 146 | val () = if r > 0 then (w (lcd, p); loop (lcd, ptr_succ (p), r - i2sz 1)) 147 | } 148 | val p0 = string2ptr (str) 149 | val p0 = ptr_add (p0, start) 150 | val () = loop (lcd, p0, len) 151 | } 152 | 153 | implement lcd_write (lcd, value) = { 154 | val (pfat | p) = lcd_t_takeout_struct (lcd) 155 | val () = lcd_send (pfat | p, value, HIGH) 156 | prval () = lcd_t_addback_struct(pfat | lcd) 157 | } 158 | 159 | implement lcd_display (pfat | p) = { 160 | val LCD_DISPLAYON = $UN.cast{uint8}(0x04) 161 | val () = p->displaycontrol := LCD_DISPLAYON 162 | val displaycontrol = p->displaycontrol 163 | val LCD_DISPLAYCONTROL = $UN.cast{uint8}(0x08) 164 | val () = lcd_command (pfat | p, uint8_bit_or (LCD_DISPLAYCONTROL, displaycontrol)) 165 | } 166 | 167 | implement lcd_command (pfat | p, value) = { 168 | val () = lcd_send (pfat | p, value, LOW) 169 | } 170 | 171 | implement lcd_send (pfat | p, value, mode) = { 172 | val () = digitalWrite (p->rs_pin, mode) 173 | val () = digitalWrite (p->rw_pin, LOW) 174 | val () = lcd_write4bits (pfat | p, value >> 4) 175 | val () = lcd_write4bits (pfat | p, value) 176 | } 177 | 178 | implement lcd_pulseEnable (pfat | p) = { 179 | val () = digitalWrite (p->enable_pin, LOW) 180 | val () = delay_us 1.0 181 | val () = digitalWrite (p->enable_pin, HIGH) 182 | val () = delay_us 1.0 // enable pulse must be >450ns 183 | val () = digitalWrite (p->enable_pin, LOW) 184 | val () = delay_us 100.0 // commands need > 37us to settle 185 | } 186 | 187 | implement lcd_write4bits (pfat | p, value) = { 188 | fun uint8_to_highlow (v: uint8): natLt(2) = $UN.cast{natLt(2)}(uint8_bit_and (v, $UN.cast{uint8}(0x01))) 189 | val () = pinMode (p->data_pins.0, OUTPUT) 190 | val () = digitalWrite (p->data_pins.0, uint8_to_highlow (value >> 0)) 191 | val () = pinMode (p->data_pins.1, OUTPUT) 192 | val () = digitalWrite (p->data_pins.1, uint8_to_highlow (value >> 1)) 193 | val () = pinMode (p->data_pins.2, OUTPUT) 194 | val () = digitalWrite (p->data_pins.2, uint8_to_highlow (value >> 2)) 195 | val () = pinMode (p->data_pins.3, OUTPUT) 196 | val () = digitalWrite (p->data_pins.3, uint8_to_highlow (value >> 3)) 197 | val () = lcd_pulseEnable (pfat | p) 198 | } 199 | -------------------------------------------------------------------------------- /DATS/smbus.dats: -------------------------------------------------------------------------------- 1 | #include "config.hats" 2 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 3 | 4 | staload "{$TOP}/SATS/twi.sats" 5 | staload "{$TOP}/SATS/smbus.sats" 6 | 7 | staload "prelude/SATS/unsafe.sats" 8 | 9 | implement send_byte (address, command) = let 10 | var cd: uint8 = cast{uint8}(command) 11 | val r1 = twi_writeTo (cast{uint8}(address), ptr2cptr (addr@cd), cast{uint8}(1), cast{uint8}(1), cast{uint8}(1)) 12 | in 13 | case+ 0 of 14 | | _ when r1 = cast{uint8}(0) => SMBusOk 15 | | _ when r1 = cast{uint8}(1) => SMBusBadLen 16 | | _ when r1 = cast{uint8}(2) => SMBusNack 17 | | _ when r1 = cast{uint8}(3) => SMBusOther 18 | | _ => SMBusOther 19 | end 20 | 21 | implement write_byte (address, command, data) = let 22 | var bd: uint16 = cast{uint16}(data) 23 | var cd: uint16 = cast{uint16}(command) 24 | var dd: uint16 = cast{uint16}(cd + (bd << 8)) 25 | val r1 = twi_writeTo (cast{uint8}(address), ptr2cptr (addr@dd), cast{uint8}(2), cast{uint8}(1), cast{uint8}(1)) 26 | in 27 | case+ 0 of 28 | | _ when r1 = cast{uint8}(0) => SMBusOk 29 | | _ when r1 = cast{uint8}(1) => SMBusBadLen 30 | | _ when r1 = cast{uint8}(2) => SMBusNack 31 | | _ when r1 = cast{uint8}(3) => SMBusOther 32 | | _ => SMBusOther 33 | end 34 | 35 | implement write_word (address, command, data) = let 36 | var bd: uint32 = cast{uint32}(data) 37 | var cd: uint32 = cast{uint32}(command) 38 | var dd: uint32 = cast{uint32}(cd + (bd << 8)) 39 | val r1 = twi_writeTo (cast{uint8}(address), ptr2cptr (addr@dd), cast{uint8}(3), cast{uint8}(1), cast{uint8}(1)) 40 | in 41 | case+ 0 of 42 | | _ when r1 = cast{uint8}(0) => SMBusOk 43 | | _ when r1 = cast{uint8}(1) => SMBusBadLen 44 | | _ when r1 = cast{uint8}(2) => SMBusNack 45 | | _ when r1 = cast{uint8}(3) => SMBusOther 46 | | _ => SMBusOther 47 | end 48 | 49 | implement read_byte (address, command) = let 50 | var cd: uint8 = cast{uint8}(command) 51 | var dd: uint8 = cast{uint8}(0) 52 | val r1 = twi_writeTo (cast{uint8}(address), ptr2cptr (addr@cd), cast{uint8}(1), cast{uint8}(1), cast{uint8}(0)) 53 | val cnt = twi_readFrom (cast{uint8}(address), ptr2cptr (addr@dd), cast{uint8}(1), cast{uint8}(1)) 54 | in 55 | case+ 0 of 56 | | _ when r1 = cast{uint8}(0) => (SMBusOk, dd) 57 | | _ when r1 = cast{uint8}(1) => (SMBusBadLen, cast{uint8}(0)) 58 | | _ when r1 = cast{uint8}(2) => (SMBusNack, cast{uint8}(0)) 59 | | _ when r1 = cast{uint8}(3) => (SMBusOther, cast{uint8}(0)) 60 | | _ => (SMBusOther, cast{uint8}(0)) 61 | end 62 | 63 | implement read_word (address, command) = let 64 | var cd: uint8 = cast{uint8}(command) 65 | var dd: uint16 = cast{uint16}(0) 66 | val r1 = twi_writeTo (cast{uint8}(address), ptr2cptr (addr@cd), cast{uint8}(1), cast{uint8}(1), cast{uint8}(0)) 67 | val cnt = twi_readFrom (cast{uint8}(address), ptr2cptr (addr@dd), cast{uint8}(2), cast{uint8}(1)) 68 | in 69 | case+ 0 of 70 | | _ when r1 = cast{uint8}(0) => (SMBusOk, dd) 71 | | _ when r1 = cast{uint8}(1) => (SMBusBadLen, cast{uint16}(0)) 72 | | _ when r1 = cast{uint8}(2) => (SMBusBadLen, cast{uint16}(0)) 73 | | _ when r1 = cast{uint8}(3) => (SMBusBadLen, cast{uint16}(0)) 74 | | _ => (SMBusBadLen, cast{uint16}(0)) 75 | end 76 | 77 | 78 | implement show_smbus_status (status) = 79 | case+ status of 80 | | SMBusOk () => _ 81 | | SMBusBadLen () => println! "SMBusBadLen" 82 | | SMBusNack () => println! "SMBusNack" 83 | | SMBusOther () => println! "SMBusOther" -------------------------------------------------------------------------------- /DATS/spi.dats: -------------------------------------------------------------------------------- 1 | %{^ 2 | #include "SPI.h" 3 | %} 4 | 5 | #include "config.hats" 6 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 7 | 8 | staload "{$TOP}/SATS/arduino.sats" 9 | staload "{$TOP}/SATS/spi.sats" 10 | staload UN = "prelude/SATS/unsafe.sats" 11 | 12 | macdef SPCR_PTR = $extval(ptr, "(&SPCR)") 13 | macdef SPDR_PTR = $extval(ptr, "(&SPDR)") 14 | macdef SPSR_PTR = $extval(ptr, "(&SPSR)") 15 | macdef SS = $extval(pin_t, "SS") 16 | macdef SCK = $extval(pin_t, "SCK") 17 | macdef MOSI = $extval(pin_t, "MOSI") 18 | macdef MSTR_BIT = $extval(uint8, "_BV(MSTR)") 19 | macdef SPE_BIT = $extval(uint8, "_BV(SPE)") 20 | macdef SPIF_BIT = $extval(uint8, "_BV(SPIF)") 21 | macdef SPI_MODE_MASK = $extval(uint8, "SPI_MODE_MASK") 22 | macdef SPI_CLOCK_MASK = $extval(uint8, "SPI_CLOCK_MASK") 23 | macdef SPI_2XCLOCK_MASK = $extval(uint8, "SPI_2XCLOCK_MASK") 24 | 25 | implement spi_begin () = { 26 | // Set SS to high so a connected chip will be "deselected" by default 27 | val () = digitalWrite (SS, HIGH) 28 | // When the SS pin is set as OUTPUT, it can be used as 29 | // a general purpose output port (it doesn't influence 30 | // SPI operations). 31 | val () = pinMode (SS, OUTPUT) 32 | // Warning: if the SS pin ever becomes a LOW INPUT then SPI 33 | // automatically switches to Slave, so the data direction of 34 | // the SS pin MUST be kept as OUTPUT. 35 | val spcr = $UN.ptr0_get (SPCR_PTR) 36 | val spcr = g0uint_lor (g0uint_lor (spcr, MSTR_BIT), SPE_BIT) 37 | val () = $UN.ptr0_set (SPCR_PTR, spcr) 38 | // Set direction register for SCK and MOSI pin. 39 | // MISO pin automatically overrides to INPUT. 40 | // By doing this AFTER enabling SPI, we avoid accidentally 41 | // clocking in a single bit since the lines go directly 42 | // from "input" to SPI control. 43 | // http://code.google.com/p/arduino/issues/detail?id=888 44 | val () = pinMode (SCK, OUTPUT) 45 | val () = pinMode (MOSI, OUTPUT) 46 | } 47 | 48 | implement spi_setClockDivider (rate) = { 49 | val spcr = $UN.ptr0_get (SPCR_PTR) 50 | val a = g0uint_land (spcr, g0uint_lnot SPI_CLOCK_MASK) 51 | val b = g0uint_land (rate, SPI_CLOCK_MASK) 52 | val () = $UN.ptr0_set (SPCR_PTR, g0uint_lor (a, b)) 53 | val spsr = $UN.ptr0_get (SPSR_PTR) 54 | val a = g0uint_land (spsr, g0uint_lnot SPI_2XCLOCK_MASK) 55 | val b = g0uint_land (g0uint_lsr (rate, 2), SPI_2XCLOCK_MASK) 56 | val () = $UN.ptr0_set (SPSR_PTR, g0uint_lor (a, b)) 57 | } 58 | 59 | implement spi_setDataMode (mode) = { 60 | val spcr = $UN.ptr0_get (SPCR_PTR) 61 | val spcr = g0uint_lor (g0uint_land (spcr, g0uint_lnot SPI_MODE_MASK), mode) 62 | val () = $UN.ptr0_set (SPCR_PTR, spcr) 63 | } 64 | 65 | implement spi_transfer (data) = let 66 | fun loop ():void = { 67 | val spsr = $UN.ptr0_get (SPSR_PTR) 68 | val b = g0uint_land (spsr, SPIF_BIT) 69 | val () = if iseqz b then loop () 70 | } 71 | val () = $UN.ptr0_set (SPDR_PTR, data) 72 | val () = loop () 73 | in 74 | $UN.ptr0_get (SPDR_PTR) 75 | end 76 | 77 | implement spi_end () = { 78 | val spcr = $UN.ptr0_get (SPCR_PTR) 79 | val spcr = g0uint_land (spcr, g0uint_lnot SPE_BIT) 80 | val () = $UN.ptr0_set (SPCR_PTR, spcr) 81 | } 82 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Metasepi team 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SUBDIRS := demo/ demo_c/ 2 | 3 | all clean: 4 | $(foreach i,$(SUBDIRS),$(MAKE) -C $i $@ &&) true 5 | 6 | .PHONY: all clean 7 | -------------------------------------------------------------------------------- /Makefile.common: -------------------------------------------------------------------------------- 1 | PRG ?= main 2 | MACHINE ?= uno 3 | SATS = $(wildcard SATS/*.sats) 4 | DATS = $(wildcard DATS/*.dats) 5 | DATSC = $(patsubst %.dats,%_dats.c,$(DATS)) 6 | DATSOBJ = $(patsubst %.dats,%_dats.o,$(DATS)) 7 | SATS_ATSDUINO = $(wildcard $(TOP)/SATS/*.sats) 8 | DATS_ATSDUINO = $(wildcard $(TOP)/DATS/*.dats) 9 | C_ATSDUINO = $(patsubst %.dats,%_dats.c,$(notdir $(DATS_ATSDUINO))) 10 | OBJ_ATSDUINO = $(patsubst %.dats,%_dats.o,$(notdir $(DATS_ATSDUINO))) 11 | C_ARDUINO = $(wildcard $(TOP)/_arduino/*.c) 12 | OBJ_ARDUINO = $(patsubst %.c,%.o,$(notdir $(C_ARDUINO))) 13 | OPTIMIZE = -Os 14 | LOADER = avrdude 15 | 16 | DEFS ?= 17 | LIBS ?= 18 | 19 | # Machine params 20 | 21 | ifeq ($(MACHINE),mega2560) 22 | # Arduino Mega 2560 23 | MCU = atmega2560 24 | F_CPU = 16000000UL 25 | BAUD_RATE = 115200 26 | LOADERFLAGS = -c stk500v2 -p $(MCU) -b $(BAUD_RATE) -P /dev/$(USB) 27 | else 28 | # Arduino Uno 29 | MCU = atmega328p 30 | F_CPU = 16000000UL 31 | BAUD_RATE = 115200 32 | LOADERFLAGS = -c arduino -p $(MCU) -b $(BAUD_RATE) -P /dev/$(USB) 33 | endif 34 | 35 | # You should not have to change anything below here. 36 | 37 | CC = avr-gcc 38 | ATS = patsopt 39 | ATSCFLAGS = -std=c99 -D_XOPEN_SOURCE 40 | ATSCFLAGS += -D_ATSTYPE_VAR_SIZE_=0X000F -D_ATS_CCOMP_EXCEPTION_NONE_ -D_ATS_CCOMP_RUNTIME_NONE_ -D_ATS_CCOMP_PRELUDE_NONE_ -D_ATS_CCOMP_PRELUDE_USER_=\"$(TOP)/avr_prelude/kernel_prelude.cats\" 41 | ATSCFLAGS += -Wno-unused-variable -Wno-unused-label -Wno-unused-but-set-variable 42 | ATSCFLAGS += -I. -I${PATSHOME} -I${PATSHOME}/ccomp/runtime -I$(TOP)/_arduino -I$(TOP)/_dummy -I$(TOP) 43 | 44 | # Override is only needed by avr-lib build system. 45 | 46 | override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU) -DF_CPU=$(F_CPU) $(DEFS) $(ATSCFLAGS) 47 | override LDFLAGS = -Wl,-Map,$(PRG).map 48 | 49 | OBJCOPY = avr-objcopy 50 | OBJDUMP = avr-objdump 51 | 52 | all: $(PRG).elf lst text eeprom 53 | 54 | $(PRG).elf: libarduino.a libatsduino.a $(DATSOBJ) 55 | $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(DATSOBJ) -L. -latsduino -larduino $(LIBS) 56 | 57 | # dependency: 58 | $(DATSOBJ): %_dats.o: %_dats.c 59 | $(CC) $(CFLAGS) -c -o $@ $< 60 | $(DATSC): %_dats.c: %.dats $(SATS) $(SATS_ATSDUINO) 61 | $(ATS) -o $@.tmp -d $< 62 | mv $@.tmp $@ 63 | 64 | libatsduino.a: $(OBJ_ATSDUINO) 65 | avr-ar -r $@ $^ 66 | $(OBJ_ATSDUINO): %_dats.o: %_dats.c 67 | $(CC) $(CFLAGS) -c -o $@ $< 68 | $(C_ATSDUINO): %_dats.c: $(TOP)/DATS/%.dats $(SATS_ATSDUINO) 69 | $(ATS) -o $@.tmp -d $< 70 | mv $@.tmp $@ 71 | 72 | libarduino.a: $(OBJ_ARDUINO) 73 | avr-ar -r $@ $^ 74 | $(OBJ_ARDUINO): %.o: $(TOP)/_arduino/%.c 75 | $(CC) $(CFLAGS) -c -o $@ $< 76 | 77 | clean: 78 | rm -rf *.o $(PRG).elf *.eps *.png *.pdf *.bak *.a 79 | rm -rf *.lst *.map DATS/*.c DATS/*.o *_dats.c *.tmp $(EXTRA_CLEAN_FILES) 80 | 81 | lst: $(PRG).lst 82 | 83 | %.lst: %.elf 84 | $(OBJDUMP) -h -S $< > $@ 85 | 86 | # Rules for building the .text rom images 87 | 88 | text: hex bin srec 89 | 90 | hex: $(PRG).hex 91 | bin: $(PRG).bin 92 | srec: $(PRG).srec 93 | 94 | %.hex: %.elf 95 | $(OBJCOPY) -j .text -j .data -O ihex $< $@ 96 | 97 | %.srec: %.elf 98 | $(OBJCOPY) -j .text -j .data -O srec $< $@ 99 | 100 | %.bin: %.elf 101 | $(OBJCOPY) -j .text -j .data -O binary $< $@ 102 | 103 | # Rules for building the .eeprom rom images 104 | 105 | eeprom: ehex ebin esrec 106 | 107 | ehex: $(PRG)_eeprom.hex 108 | ebin: $(PRG)_eeprom.bin 109 | esrec: $(PRG)_eeprom.srec 110 | 111 | %_eeprom.hex: %.elf 112 | $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@ \ 113 | || { echo empty $@ not generated; exit 0; } 114 | 115 | %_eeprom.srec: %.elf 116 | $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O srec $< $@ \ 117 | || { echo empty $@ not generated; exit 0; } 118 | 119 | %_eeprom.bin: %.elf 120 | $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@ \ 121 | || { echo empty $@ not generated; exit 0; } 122 | 123 | # Every thing below here is used by avr-libc's build system and can be ignored 124 | # by the casual user. 125 | 126 | EXTRA_CLEAN_FILES = *.hex *.bin *.srec 127 | 128 | write: $(PRG).hex 129 | $(LOADER) $(LOADERFLAGS) -U flash:w:$< 130 | -------------------------------------------------------------------------------- /Makefile.common_c: -------------------------------------------------------------------------------- 1 | PRG ?= main 2 | MACHINE ?= uno 3 | CSRC = $(wildcard *.c) 4 | COBJ = $(patsubst %.c,%.o,$(CSRC)) 5 | C_ARDUINO = $(wildcard $(TOP)/_arduino/*.c) 6 | OBJ_ARDUINO = $(patsubst %.c,%.o,$(notdir $(C_ARDUINO))) 7 | OPTIMIZE = -Os 8 | LOADER = avrdude 9 | 10 | DEFS ?= 11 | LIBS ?= 12 | 13 | # Machine params 14 | 15 | ifeq ($(MACHINE),mega2560) 16 | # Arduino Mega 2560 17 | MCU = atmega2560 18 | F_CPU = 16000000UL 19 | BAUD_RATE = 115200 20 | LOADERFLAGS = -c stk500v2 -p $(MCU) -b $(BAUD_RATE) -P /dev/$(USB) 21 | else 22 | # Arduino Uno 23 | MCU = atmega328p 24 | F_CPU = 16000000UL 25 | BAUD_RATE = 115200 26 | LOADERFLAGS = -c arduino -p $(MCU) -b $(BAUD_RATE) -P /dev/$(USB) 27 | endif 28 | 29 | # You should not have to change anything below here. 30 | 31 | CC = avr-gcc 32 | ATS = patsopt 33 | ATSCFLAGS = -std=c99 -D_XOPEN_SOURCE -I$(TOP)/_arduino 34 | 35 | # Override is only needed by avr-lib build system. 36 | 37 | override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU) -DF_CPU=$(F_CPU) $(DEFS) $(ATSCFLAGS) 38 | override LDFLAGS = -Wl,-Map,$(PRG).map 39 | 40 | OBJCOPY = avr-objcopy 41 | OBJDUMP = avr-objdump 42 | 43 | all: $(PRG).elf lst text eeprom 44 | 45 | $(PRG).elf: libarduino.a $(COBJ) 46 | $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(COBJ) -L. -larduino $(LIBS) 47 | 48 | # dependency: 49 | $(COBJ): %.o: %.c 50 | $(CC) $(CFLAGS) -c -o $@ $< 51 | 52 | libarduino.a: $(OBJ_ARDUINO) 53 | avr-ar -r $@ $^ 54 | $(OBJ_ARDUINO): %.o: $(TOP)/_arduino/%.c 55 | $(CC) $(CFLAGS) -c -o $@ $< 56 | 57 | clean: 58 | rm -rf *.o $(PRG).elf *.eps *.png *.pdf *.bak *.a 59 | rm -rf *.lst *.map DATS/*.c DATS/*.o *_dats.c *.tmp $(EXTRA_CLEAN_FILES) 60 | 61 | lst: $(PRG).lst 62 | 63 | %.lst: %.elf 64 | $(OBJDUMP) -h -S $< > $@ 65 | 66 | # Rules for building the .text rom images 67 | 68 | text: hex bin srec 69 | 70 | hex: $(PRG).hex 71 | bin: $(PRG).bin 72 | srec: $(PRG).srec 73 | 74 | %.hex: %.elf 75 | $(OBJCOPY) -j .text -j .data -O ihex $< $@ 76 | 77 | %.srec: %.elf 78 | $(OBJCOPY) -j .text -j .data -O srec $< $@ 79 | 80 | %.bin: %.elf 81 | $(OBJCOPY) -j .text -j .data -O binary $< $@ 82 | 83 | # Rules for building the .eeprom rom images 84 | 85 | eeprom: ehex ebin esrec 86 | 87 | ehex: $(PRG)_eeprom.hex 88 | ebin: $(PRG)_eeprom.bin 89 | esrec: $(PRG)_eeprom.srec 90 | 91 | %_eeprom.hex: %.elf 92 | $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@ \ 93 | || { echo empty $@ not generated; exit 0; } 94 | 95 | %_eeprom.srec: %.elf 96 | $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O srec $< $@ \ 97 | || { echo empty $@ not generated; exit 0; } 98 | 99 | %_eeprom.bin: %.elf 100 | $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@ \ 101 | || { echo empty $@ not generated; exit 0; } 102 | 103 | # Every thing below here is used by avr-libc's build system and can be ignored 104 | # by the casual user. 105 | 106 | EXTRA_CLEAN_FILES = *.hex *.bin *.srec 107 | 108 | write: $(PRG).hex 109 | $(LOADER) $(LOADERFLAGS) -U flash:w:$< 110 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ATS programing on Arduino [![Build Status](https://travis-ci.org/fpiot/arduino-ats.svg)](https://travis-ci.org/fpiot/arduino-ats) 2 | 3 | ## Paper 4 | 5 | Kiwamu Okabe and Hongwei Xi. [Arduino programing of ML-style in ATS](http://www.metasepi.org/doc/metasepi-icfp2015-arduino-ats.pdf). [ML workshop, 2015](http://www.mlworkshop.org/ml2015). 6 | 7 | ## Application Design 8 | 9 | ![](_img/demo_arch.png) 10 | 11 | ## Demo code 12 | 13 | ### Greating on LCD display 14 | 15 | [![Functional programming on 8-bit Arduino! (with ATS language)](http://share.gifyoutube.com/yEXjpg.gif)](https://www.youtube.com/watch?v=5uPue0Jo1nc) 16 | 17 | Show greeting message on LCD display that is available at [LinkSprite](http://store.linksprite.com/linksprite-16x2-lcd-keypad-shield-for-arduino-version-b/). The source code is found at [demo/lcd_greeting/DATS/main.dats](./demo/lcd_greeting/DATS/main.dats). 18 | 19 | ### Examples on Book "Getting Started with Arduino" 20 | 21 | This project includes ATS code for [Book "Getting Started with Arduino"](http://shop.oreilly.com/product/9780596155520.do). 22 | 23 | [![](_img/book.png)](http://shop.oreilly.com/product/9780596155520.do) 24 | 25 | The ATS code is found at following. 26 | 27 | * [Example 01: Blinking LED](./demo/01_blink/DATS/main.dats) 28 | * [Example 02: Turn on LED while the button is pressed](./demo/02_button_press/DATS/main.dats) 29 | * [Example 03C: Turn on LED when the button is pressed](./demo/03_de_bouncing/DATS/main.dats) 30 | * [Example 04: Fade an LED in and out like on a sleeping Apple computer](./demo/04_pwm/DATS/main.dats) 31 | * [Example 05: Turn on LED when the button is pressed. Brightness changes](./demo/05_pwm_button/DATS/main.dats) 32 | * [Example 06A: Blink LED at a rate specified by the value of the analogue input](./demo/06a_analoginput_blink/DATS/main.dats) 33 | * [Example 06B: Set the brightness of LED to a brightness specified by the value of the analogue input](./demo/06b_analoginput_pwm/DATS/main.dats) 34 | * [Example 07: Send to the computer the values read from analogue input 0](./demo/07_analoginput_serial/DATS/main.dats) 35 | 36 | ## Hardware: [Arduino Uno](http://arduino.cc/en/Main/ArduinoBoardUno) 37 | 38 | [![](_img/ArduinoUnoR3.jpg)](http://arduino.cc/en/Main/ArduinoBoardUno) 39 | 40 | * CPU: ATmega328 ([Atmel AVR](http://www.atmel.com/products/microcontrollers/avr/) 8-bit) 41 | * Flash ROM: 32 kB 42 | * SRAM: 2 kB 43 | 44 | Also you could get [compatible boards](http://www.sainsmart.com/arduino/control-boards/sainsmart-uno-atmega328p-pu-atmega8u2-microcontroller-for-arduino.html) 45 | 46 | 47 | ## Setup environment 48 | 49 | ### [Debian GNU/Linux](https://www.debian.org/) 50 | 51 | Install some packages. 52 | 53 | ``` 54 | $ sudo vi /etc/apt/preferences.d/avr 55 | Package: avrdude 56 | Pin: version 6.1* 57 | Pin-Priority: 1001 58 | $ sudo apt-get install binutils-avr gcc-avr avr-libc avrdude libgmp-dev 59 | ``` 60 | 61 | ### Mac OS X 62 | 63 | Install gmp package. 64 | 65 | ``` 66 | $ brew install gmp 67 | ``` 68 | 69 | Install AVR toolchain http://www.obdev.at/products/crosspack/index.html, and set PATH env. 70 | 71 | ``` 72 | $ export PATH=$PATH:/usr/local/CrossPack-AVR/bin 73 | $ which avr-gcc 74 | /usr/local/CrossPack-AVR/bin/avr-gcc 75 | ``` 76 | 77 | ### Windows 78 | 79 | Install following package on [cygwin](https://www.cygwin.com/). 80 | 81 | * git 82 | * gcc-core 83 | * libgc-devel 84 | * libgmp-devel 85 | * make 86 | 87 | Install AVR toolchain http://winavr.sourceforge.net/. 88 | 89 | T.B.D. 90 | 91 | 92 | ## How to build 93 | 94 | Install ATS2 http://www.ats-lang.org/. 95 | 96 | ``` 97 | $ tar xf ATS2-Postiats-X.Y.Z.tgz 98 | $ export PATSHOME=`pwd`/ATS2-Postiats-X.Y.Z 99 | $ export PATH=${PATSHOME}/bin:${PATH} 100 | $ tar xf ATS2-Postiats-contrib-X.Y.Z.tgz 101 | $ export PATSHOMERELOC=`pwd`/ATS2-Postiats-contrib-X.Y.Z 102 | $ cd ${PATSHOME} 103 | $ ./configure 104 | $ make 105 | ``` 106 | 107 | Compile the ATS source code for Arduino. 108 | 109 | ``` 110 | $ cd arduino-ats/01_blink 111 | $ make 112 | $ file main.elf main.hex 113 | main.elf: ELF 32-bit LSB executable, Atmel AVR 8-bit, version 1 (SYSV), statically linked, not stripped 114 | main.hex: ASCII text, with CRLF line terminators 115 | ``` 116 | 117 | 118 | ## Write to the flash 119 | 120 | Connect Arduino board to your PC using USB cable. 121 | And run following commands. 122 | 123 | ``` 124 | $ ls -l /dev/ttyACM0 125 | crw-rw---- 1 root dialout 166, 0 May 8 15:59 /dev/ttyACM0 126 | $ cd arduino-ats/blink_ats 127 | $ make write 128 | avrdude -c stk500v2 -p atmega2560 -b 115200 -P /dev/ttyACM0 -U flash:w:main.hex 129 | avrdude: AVR device initialized and ready to accept instructions 130 | Reading | ################################################## | 100% 0.01s 131 | --snip-- 132 | avrdude: verifying ... 133 | avrdude: 2850 bytes of flash verified 134 | avrdude: safemode: Fuses OK (E:00, H:00, L:00) 135 | avrdude done. Thank you. 136 | ``` 137 | 138 | 139 | ## How to debug using gdb 140 | 141 | [![](_img/avr_dragon.jpg)](http://www.atmel.com/tools/avrdragon.aspx) 142 | 143 | T.B.D. 144 | -------------------------------------------------------------------------------- /SATS/arduino.sats: -------------------------------------------------------------------------------- 1 | %{^ 2 | #include 3 | #include 4 | #include "Arduino.h" 5 | %} 6 | 7 | #define LOW 0x0 8 | #define HIGH 0x1 9 | 10 | #define INPUT 0x0 11 | #define OUTPUT 0x1 12 | 13 | #define LSBFIRST 0 14 | #define MSBFIRST 1 15 | 16 | typedef pin_t = natLt(256) 17 | 18 | macdef LED_BUILTIN = $extval(pin_t, "LED_BUILTIN") 19 | macdef A0 = $extval(pin_t, "A0") 20 | 21 | abst@ype ANALOG_REFERENCE = $extype"uint8_t" 22 | macdef DEFAULT = $extval(ANALOG_REFERENCE, "DEFAULT") 23 | macdef INTERNAL = $extval(ANALOG_REFERENCE, "INTERNAL") 24 | macdef EXTERNAL = $extval(ANALOG_REFERENCE, "EXTERNAL") 25 | 26 | fun init (): void = "mac#" 27 | fun pinMode (pin: pin_t, mode: natLt(2)): void = "mac#" 28 | fun digitalWrite (pin: pin_t, value: natLt(2)): void = "mac#" 29 | fun digitalRead (pin: pin_t): natLt(2) = "mac#" 30 | fun analogReference (atype: ANALOG_REFERENCE): void = "mac#" 31 | fun analogRead (pin: pin_t): natLt(1024) = "mac#" 32 | fun analogWrite (pin: pin_t, value: natLt(256)): void = "mac#" 33 | fun millis (): ulint = "mac#" 34 | fun micros (): ulint = "mac#" 35 | fun delay(ms: ulint): void = "mac#" 36 | fun delayMicroseconds(us: uint): void = "mac#" 37 | fun delay_ms (ms: double): void = "mac#_delay_ms" 38 | fun delay_us (us: double): void = "mac#_delay_us" 39 | fun interrupts (): void = "mac#" 40 | fun nointerrupts (): void = "mac#" 41 | 42 | fun random_int_1 (int): int = "mac#random" 43 | fun random_lint_1 (lint): lint = "mac#random" 44 | fun random_int_2 (int, int): int = "mac#random" 45 | fun random_lint_2 (lint, lint): lint = "mac#random" 46 | symintr random 47 | overload random with random_int_1 48 | overload random with random_lint_1 49 | overload random with random_int_2 50 | overload random with random_lint_2 51 | 52 | fun randomSeed_int (seed: int): void = "mac#randomSeed" 53 | fun randomSeed_uint (seed: uint): void = "mac#randomSeed" 54 | symintr randomSeed 55 | overload randomSeed with randomSeed_int 56 | overload randomSeed with randomSeed_uint 57 | 58 | fun main (): void (* Entry point for application *) 59 | -------------------------------------------------------------------------------- /SATS/eeprom.sats: -------------------------------------------------------------------------------- 1 | %{# 2 | #include 3 | %} 4 | fun eeprom_read_byte {n:nat} (address: int n): uint8 = "mac#" 5 | fun eeprom_write_byte {n:nat} (address: int n, value: uint8): void = "mac#" 6 | -------------------------------------------------------------------------------- /SATS/ethernet_w5100.sats: -------------------------------------------------------------------------------- 1 | fun ethernet_w5100_init: () -> void 2 | -------------------------------------------------------------------------------- /SATS/hardware_serial.sats: -------------------------------------------------------------------------------- 1 | fun serial_begin (speed: ulint): void 2 | fun serial_write (value: char): size_t 3 | fun serial_flush (): void 4 | fun serial_available (): uint 5 | fun serial_peek (): int 6 | fun serial_read (): int 7 | fun serial_end (): void 8 | -------------------------------------------------------------------------------- /SATS/lcd.sats: -------------------------------------------------------------------------------- 1 | #include "config.hats" 2 | staload "{$TOP}/SATS/arduino.sats" 3 | 4 | absvtype lcd_t = ptr 5 | 6 | fun lcd_open (rs: int, rw: int, enable: int, d0: int, d1: int, d2: int, d3: int): lcd_t 7 | fun lcd_close (lcd: lcd_t): void 8 | fun lcd_clear (lcd: !lcd_t): void 9 | fun lcd_setCursor (lcd: !lcd_t, col: int, row: int): void 10 | fun lcd_write (lcd: !lcd_t, data: uint8): void 11 | fun lcd_print {n:int}{i:nat | i < n}{j:nat | i + j <= n} 12 | (lcd: !lcd_t, str: string (n), start: size_t (i), len: size_t (j)): void 13 | -------------------------------------------------------------------------------- /SATS/smbus.sats: -------------------------------------------------------------------------------- 1 | datatype smbus_status = 2 | | SMBusOk of () 3 | | SMBusBadLen of () 4 | | SMBusNack of () 5 | | SMBusOther of () 6 | 7 | fun send_byte (address: uint8, command: uint8): smbus_status 8 | fun write_byte (address: uint8, command: uint8, data: uint8): smbus_status 9 | fun write_word (address: uint8, command: uint8, data: uint16): smbus_status 10 | 11 | fun read_byte (address: uint8, command: uint8): (smbus_status, uint8) 12 | fun read_word (address: uint8, command: uint8): (smbus_status, uint16) 13 | 14 | fun show_smbus_status (status: smbus_status): void -------------------------------------------------------------------------------- /SATS/spi.sats: -------------------------------------------------------------------------------- 1 | fun spi_begin: () -> void 2 | fun spi_setClockDivider: (uint8) -> void 3 | fun spi_setDataMode: (uint8) -> void 4 | fun spi_transfer: (uint8) -> uint8 5 | fun spi_end: () -> void 6 | -------------------------------------------------------------------------------- /SATS/twi.sats: -------------------------------------------------------------------------------- 1 | %{# 2 | #include "twi.h" 3 | %} 4 | 5 | //macdef twi_buffer = $extval(cPtr0(ring_buffer), "&tx_buffer") 6 | 7 | fun twi_init () : void = "mac#" 8 | fun twi_setAddress (uint8) : void = "mac#" 9 | fun twi_readFrom (uint8, cPtr0(uint8), uint8, uint8) : uint8 = "mac#" 10 | fun twi_writeTo (uint8, cPtr0(uint8), uint8, uint8, uint8) : uint8 = "mac#" 11 | fun twi_transmit (cPtr0(uint8), uint8) : uint8 = "mac#" 12 | fun twi_reply (uint8) : void = "mac#" 13 | fun twi_stop () : void = "mac#" 14 | fun twi_releaseBus () : void = "mac#" -------------------------------------------------------------------------------- /_arduino/Arduino.h: -------------------------------------------------------------------------------- 1 | #ifndef Arduino_h 2 | #define Arduino_h 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include "binary.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C"{ 16 | #endif 17 | 18 | #define HIGH 0x1 19 | #define LOW 0x0 20 | 21 | #define INPUT 0x0 22 | #define OUTPUT 0x1 23 | #define INPUT_PULLUP 0x2 24 | 25 | #define true 0x1 26 | #define false 0x0 27 | 28 | #define PI 3.1415926535897932384626433832795 29 | #define HALF_PI 1.5707963267948966192313216916398 30 | #define TWO_PI 6.283185307179586476925286766559 31 | #define DEG_TO_RAD 0.017453292519943295769236907684886 32 | #define RAD_TO_DEG 57.295779513082320876798154814105 33 | 34 | #define SERIAL 0x0 35 | #define DISPLAY 0x1 36 | 37 | #define LSBFIRST 0 38 | #define MSBFIRST 1 39 | 40 | #define CHANGE 1 41 | #define FALLING 2 42 | #define RISING 3 43 | 44 | #if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) 45 | #define DEFAULT 0 46 | #define EXTERNAL 1 47 | #define INTERNAL 2 48 | #else 49 | #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) 50 | #define INTERNAL1V1 2 51 | #define INTERNAL2V56 3 52 | #else 53 | #define INTERNAL 3 54 | #endif 55 | #define DEFAULT 1 56 | #define EXTERNAL 0 57 | #endif 58 | 59 | // undefine stdlib's abs if encountered 60 | #ifdef abs 61 | #undef abs 62 | #endif 63 | 64 | #define min(a,b) ((a)<(b)?(a):(b)) 65 | #define max(a,b) ((a)>(b)?(a):(b)) 66 | #define abs(x) ((x)>0?(x):-(x)) 67 | #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) 68 | #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) 69 | #define radians(deg) ((deg)*DEG_TO_RAD) 70 | #define degrees(rad) ((rad)*RAD_TO_DEG) 71 | #define sq(x) ((x)*(x)) 72 | 73 | #define interrupts() sei() 74 | #define noInterrupts() cli() 75 | 76 | #define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) 77 | #define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) 78 | #define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() ) 79 | 80 | #define lowByte(w) ((uint8_t) ((w) & 0xff)) 81 | #define highByte(w) ((uint8_t) ((w) >> 8)) 82 | 83 | #define bitRead(value, bit) (((value) >> (bit)) & 0x01) 84 | #define bitSet(value, bit) ((value) |= (1UL << (bit))) 85 | #define bitClear(value, bit) ((value) &= ~(1UL << (bit))) 86 | #define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) 87 | 88 | 89 | typedef unsigned int word; 90 | 91 | #define bit(b) (1UL << (b)) 92 | 93 | typedef uint8_t boolean; 94 | typedef uint8_t byte; 95 | 96 | void init(void); 97 | 98 | void pinMode(uint8_t, uint8_t); 99 | void digitalWrite(uint8_t, uint8_t); 100 | int digitalRead(uint8_t); 101 | int analogRead(uint8_t); 102 | void analogReference(uint8_t mode); 103 | void analogWrite(uint8_t, int); 104 | 105 | unsigned long millis(void); 106 | unsigned long micros(void); 107 | void delay(unsigned long); 108 | void delayMicroseconds(unsigned int us); 109 | unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout); 110 | 111 | void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val); 112 | uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder); 113 | 114 | void attachInterrupt(uint8_t, void (*)(void), int mode); 115 | void detachInterrupt(uint8_t); 116 | 117 | void setup(void); 118 | void loop(void); 119 | 120 | // Get the bit location within the hardware port of the given virtual pin. 121 | // This comes from the pins_*.c file for the active board configuration. 122 | 123 | #define analogInPinToBit(P) (P) 124 | 125 | // On the ATmega1280, the addresses of some of the port registers are 126 | // greater than 255, so we can't store them in uint8_t's. 127 | extern const uint16_t PROGMEM port_to_mode_PGM[]; 128 | extern const uint16_t PROGMEM port_to_input_PGM[]; 129 | extern const uint16_t PROGMEM port_to_output_PGM[]; 130 | 131 | extern const uint8_t PROGMEM digital_pin_to_port_PGM[]; 132 | // extern const uint8_t PROGMEM digital_pin_to_bit_PGM[]; 133 | extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[]; 134 | extern const uint8_t PROGMEM digital_pin_to_timer_PGM[]; 135 | 136 | // Get the bit location within the hardware port of the given virtual pin. 137 | // This comes from the pins_*.c file for the active board configuration. 138 | // 139 | // These perform slightly better as macros compared to inline functions 140 | // 141 | #define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) ) 142 | #define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) ) 143 | #define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) ) 144 | #define analogInPinToBit(P) (P) 145 | #define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) ) 146 | #define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) ) 147 | #define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) ) 148 | 149 | #define NOT_A_PIN 0 150 | #define NOT_A_PORT 0 151 | 152 | #ifdef ARDUINO_MAIN 153 | #define PA 1 154 | #define PB 2 155 | #define PC 3 156 | #define PD 4 157 | #define PE 5 158 | #define PF 6 159 | #define PG 7 160 | #define PH 8 161 | #define PJ 10 162 | #define PK 11 163 | #define PL 12 164 | #endif 165 | 166 | #define NOT_ON_TIMER 0 167 | #define TIMER0A 1 168 | #define TIMER0B 2 169 | #define TIMER1A 3 170 | #define TIMER1B 4 171 | #define TIMER2 5 172 | #define TIMER2A 6 173 | #define TIMER2B 7 174 | 175 | #define TIMER3A 8 176 | #define TIMER3B 9 177 | #define TIMER3C 10 178 | #define TIMER4A 11 179 | #define TIMER4B 12 180 | #define TIMER4C 13 181 | #define TIMER4D 14 182 | #define TIMER5A 15 183 | #define TIMER5B 16 184 | #define TIMER5C 17 185 | 186 | #ifdef __cplusplus 187 | } // extern "C" 188 | #endif 189 | 190 | #ifdef __cplusplus 191 | #include "WCharacter.h" 192 | #include "WString.h" 193 | #include "HardwareSerial.h" 194 | 195 | uint16_t makeWord(uint16_t w); 196 | uint16_t makeWord(byte h, byte l); 197 | 198 | #define word(...) makeWord(__VA_ARGS__) 199 | 200 | unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); 201 | 202 | void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0); 203 | void noTone(uint8_t _pin); 204 | 205 | // WMath prototypes 206 | long random(long); 207 | long random(long, long); 208 | void randomSeed(unsigned int); 209 | long map(long, long, long, long, long); 210 | 211 | #endif 212 | 213 | #include "pins_arduino.h" 214 | 215 | #endif 216 | -------------------------------------------------------------------------------- /_arduino/SPI.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 by Cristian Maglie 3 | * SPI Master library for arduino. 4 | * 5 | * This file is free software; you can redistribute it and/or modify 6 | * it under the terms of either the GNU General Public License version 2 7 | * or the GNU Lesser General Public License version 2.1, both as 8 | * published by the Free Software Foundation. 9 | */ 10 | 11 | #ifndef _SPI_H_INCLUDED 12 | #define _SPI_H_INCLUDED 13 | 14 | #define SPI_CLOCK_DIV4 0x00 15 | #define SPI_CLOCK_DIV16 0x01 16 | #define SPI_CLOCK_DIV64 0x02 17 | #define SPI_CLOCK_DIV128 0x03 18 | #define SPI_CLOCK_DIV2 0x04 19 | #define SPI_CLOCK_DIV8 0x05 20 | #define SPI_CLOCK_DIV32 0x06 21 | //#define SPI_CLOCK_DIV64 0x07 22 | 23 | #define SPI_MODE0 0x00 24 | #define SPI_MODE1 0x04 25 | #define SPI_MODE2 0x08 26 | #define SPI_MODE3 0x0C 27 | 28 | #define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR 29 | #define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR 30 | #define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /_arduino/binary.h: -------------------------------------------------------------------------------- 1 | #ifndef Binary_h 2 | #define Binary_h 3 | 4 | #define B0 0 5 | #define B00 0 6 | #define B000 0 7 | #define B0000 0 8 | #define B00000 0 9 | #define B000000 0 10 | #define B0000000 0 11 | #define B00000000 0 12 | #define B1 1 13 | #define B01 1 14 | #define B001 1 15 | #define B0001 1 16 | #define B00001 1 17 | #define B000001 1 18 | #define B0000001 1 19 | #define B00000001 1 20 | #define B10 2 21 | #define B010 2 22 | #define B0010 2 23 | #define B00010 2 24 | #define B000010 2 25 | #define B0000010 2 26 | #define B00000010 2 27 | #define B11 3 28 | #define B011 3 29 | #define B0011 3 30 | #define B00011 3 31 | #define B000011 3 32 | #define B0000011 3 33 | #define B00000011 3 34 | #define B100 4 35 | #define B0100 4 36 | #define B00100 4 37 | #define B000100 4 38 | #define B0000100 4 39 | #define B00000100 4 40 | #define B101 5 41 | #define B0101 5 42 | #define B00101 5 43 | #define B000101 5 44 | #define B0000101 5 45 | #define B00000101 5 46 | #define B110 6 47 | #define B0110 6 48 | #define B00110 6 49 | #define B000110 6 50 | #define B0000110 6 51 | #define B00000110 6 52 | #define B111 7 53 | #define B0111 7 54 | #define B00111 7 55 | #define B000111 7 56 | #define B0000111 7 57 | #define B00000111 7 58 | #define B1000 8 59 | #define B01000 8 60 | #define B001000 8 61 | #define B0001000 8 62 | #define B00001000 8 63 | #define B1001 9 64 | #define B01001 9 65 | #define B001001 9 66 | #define B0001001 9 67 | #define B00001001 9 68 | #define B1010 10 69 | #define B01010 10 70 | #define B001010 10 71 | #define B0001010 10 72 | #define B00001010 10 73 | #define B1011 11 74 | #define B01011 11 75 | #define B001011 11 76 | #define B0001011 11 77 | #define B00001011 11 78 | #define B1100 12 79 | #define B01100 12 80 | #define B001100 12 81 | #define B0001100 12 82 | #define B00001100 12 83 | #define B1101 13 84 | #define B01101 13 85 | #define B001101 13 86 | #define B0001101 13 87 | #define B00001101 13 88 | #define B1110 14 89 | #define B01110 14 90 | #define B001110 14 91 | #define B0001110 14 92 | #define B00001110 14 93 | #define B1111 15 94 | #define B01111 15 95 | #define B001111 15 96 | #define B0001111 15 97 | #define B00001111 15 98 | #define B10000 16 99 | #define B010000 16 100 | #define B0010000 16 101 | #define B00010000 16 102 | #define B10001 17 103 | #define B010001 17 104 | #define B0010001 17 105 | #define B00010001 17 106 | #define B10010 18 107 | #define B010010 18 108 | #define B0010010 18 109 | #define B00010010 18 110 | #define B10011 19 111 | #define B010011 19 112 | #define B0010011 19 113 | #define B00010011 19 114 | #define B10100 20 115 | #define B010100 20 116 | #define B0010100 20 117 | #define B00010100 20 118 | #define B10101 21 119 | #define B010101 21 120 | #define B0010101 21 121 | #define B00010101 21 122 | #define B10110 22 123 | #define B010110 22 124 | #define B0010110 22 125 | #define B00010110 22 126 | #define B10111 23 127 | #define B010111 23 128 | #define B0010111 23 129 | #define B00010111 23 130 | #define B11000 24 131 | #define B011000 24 132 | #define B0011000 24 133 | #define B00011000 24 134 | #define B11001 25 135 | #define B011001 25 136 | #define B0011001 25 137 | #define B00011001 25 138 | #define B11010 26 139 | #define B011010 26 140 | #define B0011010 26 141 | #define B00011010 26 142 | #define B11011 27 143 | #define B011011 27 144 | #define B0011011 27 145 | #define B00011011 27 146 | #define B11100 28 147 | #define B011100 28 148 | #define B0011100 28 149 | #define B00011100 28 150 | #define B11101 29 151 | #define B011101 29 152 | #define B0011101 29 153 | #define B00011101 29 154 | #define B11110 30 155 | #define B011110 30 156 | #define B0011110 30 157 | #define B00011110 30 158 | #define B11111 31 159 | #define B011111 31 160 | #define B0011111 31 161 | #define B00011111 31 162 | #define B100000 32 163 | #define B0100000 32 164 | #define B00100000 32 165 | #define B100001 33 166 | #define B0100001 33 167 | #define B00100001 33 168 | #define B100010 34 169 | #define B0100010 34 170 | #define B00100010 34 171 | #define B100011 35 172 | #define B0100011 35 173 | #define B00100011 35 174 | #define B100100 36 175 | #define B0100100 36 176 | #define B00100100 36 177 | #define B100101 37 178 | #define B0100101 37 179 | #define B00100101 37 180 | #define B100110 38 181 | #define B0100110 38 182 | #define B00100110 38 183 | #define B100111 39 184 | #define B0100111 39 185 | #define B00100111 39 186 | #define B101000 40 187 | #define B0101000 40 188 | #define B00101000 40 189 | #define B101001 41 190 | #define B0101001 41 191 | #define B00101001 41 192 | #define B101010 42 193 | #define B0101010 42 194 | #define B00101010 42 195 | #define B101011 43 196 | #define B0101011 43 197 | #define B00101011 43 198 | #define B101100 44 199 | #define B0101100 44 200 | #define B00101100 44 201 | #define B101101 45 202 | #define B0101101 45 203 | #define B00101101 45 204 | #define B101110 46 205 | #define B0101110 46 206 | #define B00101110 46 207 | #define B101111 47 208 | #define B0101111 47 209 | #define B00101111 47 210 | #define B110000 48 211 | #define B0110000 48 212 | #define B00110000 48 213 | #define B110001 49 214 | #define B0110001 49 215 | #define B00110001 49 216 | #define B110010 50 217 | #define B0110010 50 218 | #define B00110010 50 219 | #define B110011 51 220 | #define B0110011 51 221 | #define B00110011 51 222 | #define B110100 52 223 | #define B0110100 52 224 | #define B00110100 52 225 | #define B110101 53 226 | #define B0110101 53 227 | #define B00110101 53 228 | #define B110110 54 229 | #define B0110110 54 230 | #define B00110110 54 231 | #define B110111 55 232 | #define B0110111 55 233 | #define B00110111 55 234 | #define B111000 56 235 | #define B0111000 56 236 | #define B00111000 56 237 | #define B111001 57 238 | #define B0111001 57 239 | #define B00111001 57 240 | #define B111010 58 241 | #define B0111010 58 242 | #define B00111010 58 243 | #define B111011 59 244 | #define B0111011 59 245 | #define B00111011 59 246 | #define B111100 60 247 | #define B0111100 60 248 | #define B00111100 60 249 | #define B111101 61 250 | #define B0111101 61 251 | #define B00111101 61 252 | #define B111110 62 253 | #define B0111110 62 254 | #define B00111110 62 255 | #define B111111 63 256 | #define B0111111 63 257 | #define B00111111 63 258 | #define B1000000 64 259 | #define B01000000 64 260 | #define B1000001 65 261 | #define B01000001 65 262 | #define B1000010 66 263 | #define B01000010 66 264 | #define B1000011 67 265 | #define B01000011 67 266 | #define B1000100 68 267 | #define B01000100 68 268 | #define B1000101 69 269 | #define B01000101 69 270 | #define B1000110 70 271 | #define B01000110 70 272 | #define B1000111 71 273 | #define B01000111 71 274 | #define B1001000 72 275 | #define B01001000 72 276 | #define B1001001 73 277 | #define B01001001 73 278 | #define B1001010 74 279 | #define B01001010 74 280 | #define B1001011 75 281 | #define B01001011 75 282 | #define B1001100 76 283 | #define B01001100 76 284 | #define B1001101 77 285 | #define B01001101 77 286 | #define B1001110 78 287 | #define B01001110 78 288 | #define B1001111 79 289 | #define B01001111 79 290 | #define B1010000 80 291 | #define B01010000 80 292 | #define B1010001 81 293 | #define B01010001 81 294 | #define B1010010 82 295 | #define B01010010 82 296 | #define B1010011 83 297 | #define B01010011 83 298 | #define B1010100 84 299 | #define B01010100 84 300 | #define B1010101 85 301 | #define B01010101 85 302 | #define B1010110 86 303 | #define B01010110 86 304 | #define B1010111 87 305 | #define B01010111 87 306 | #define B1011000 88 307 | #define B01011000 88 308 | #define B1011001 89 309 | #define B01011001 89 310 | #define B1011010 90 311 | #define B01011010 90 312 | #define B1011011 91 313 | #define B01011011 91 314 | #define B1011100 92 315 | #define B01011100 92 316 | #define B1011101 93 317 | #define B01011101 93 318 | #define B1011110 94 319 | #define B01011110 94 320 | #define B1011111 95 321 | #define B01011111 95 322 | #define B1100000 96 323 | #define B01100000 96 324 | #define B1100001 97 325 | #define B01100001 97 326 | #define B1100010 98 327 | #define B01100010 98 328 | #define B1100011 99 329 | #define B01100011 99 330 | #define B1100100 100 331 | #define B01100100 100 332 | #define B1100101 101 333 | #define B01100101 101 334 | #define B1100110 102 335 | #define B01100110 102 336 | #define B1100111 103 337 | #define B01100111 103 338 | #define B1101000 104 339 | #define B01101000 104 340 | #define B1101001 105 341 | #define B01101001 105 342 | #define B1101010 106 343 | #define B01101010 106 344 | #define B1101011 107 345 | #define B01101011 107 346 | #define B1101100 108 347 | #define B01101100 108 348 | #define B1101101 109 349 | #define B01101101 109 350 | #define B1101110 110 351 | #define B01101110 110 352 | #define B1101111 111 353 | #define B01101111 111 354 | #define B1110000 112 355 | #define B01110000 112 356 | #define B1110001 113 357 | #define B01110001 113 358 | #define B1110010 114 359 | #define B01110010 114 360 | #define B1110011 115 361 | #define B01110011 115 362 | #define B1110100 116 363 | #define B01110100 116 364 | #define B1110101 117 365 | #define B01110101 117 366 | #define B1110110 118 367 | #define B01110110 118 368 | #define B1110111 119 369 | #define B01110111 119 370 | #define B1111000 120 371 | #define B01111000 120 372 | #define B1111001 121 373 | #define B01111001 121 374 | #define B1111010 122 375 | #define B01111010 122 376 | #define B1111011 123 377 | #define B01111011 123 378 | #define B1111100 124 379 | #define B01111100 124 380 | #define B1111101 125 381 | #define B01111101 125 382 | #define B1111110 126 383 | #define B01111110 126 384 | #define B1111111 127 385 | #define B01111111 127 386 | #define B10000000 128 387 | #define B10000001 129 388 | #define B10000010 130 389 | #define B10000011 131 390 | #define B10000100 132 391 | #define B10000101 133 392 | #define B10000110 134 393 | #define B10000111 135 394 | #define B10001000 136 395 | #define B10001001 137 396 | #define B10001010 138 397 | #define B10001011 139 398 | #define B10001100 140 399 | #define B10001101 141 400 | #define B10001110 142 401 | #define B10001111 143 402 | #define B10010000 144 403 | #define B10010001 145 404 | #define B10010010 146 405 | #define B10010011 147 406 | #define B10010100 148 407 | #define B10010101 149 408 | #define B10010110 150 409 | #define B10010111 151 410 | #define B10011000 152 411 | #define B10011001 153 412 | #define B10011010 154 413 | #define B10011011 155 414 | #define B10011100 156 415 | #define B10011101 157 416 | #define B10011110 158 417 | #define B10011111 159 418 | #define B10100000 160 419 | #define B10100001 161 420 | #define B10100010 162 421 | #define B10100011 163 422 | #define B10100100 164 423 | #define B10100101 165 424 | #define B10100110 166 425 | #define B10100111 167 426 | #define B10101000 168 427 | #define B10101001 169 428 | #define B10101010 170 429 | #define B10101011 171 430 | #define B10101100 172 431 | #define B10101101 173 432 | #define B10101110 174 433 | #define B10101111 175 434 | #define B10110000 176 435 | #define B10110001 177 436 | #define B10110010 178 437 | #define B10110011 179 438 | #define B10110100 180 439 | #define B10110101 181 440 | #define B10110110 182 441 | #define B10110111 183 442 | #define B10111000 184 443 | #define B10111001 185 444 | #define B10111010 186 445 | #define B10111011 187 446 | #define B10111100 188 447 | #define B10111101 189 448 | #define B10111110 190 449 | #define B10111111 191 450 | #define B11000000 192 451 | #define B11000001 193 452 | #define B11000010 194 453 | #define B11000011 195 454 | #define B11000100 196 455 | #define B11000101 197 456 | #define B11000110 198 457 | #define B11000111 199 458 | #define B11001000 200 459 | #define B11001001 201 460 | #define B11001010 202 461 | #define B11001011 203 462 | #define B11001100 204 463 | #define B11001101 205 464 | #define B11001110 206 465 | #define B11001111 207 466 | #define B11010000 208 467 | #define B11010001 209 468 | #define B11010010 210 469 | #define B11010011 211 470 | #define B11010100 212 471 | #define B11010101 213 472 | #define B11010110 214 473 | #define B11010111 215 474 | #define B11011000 216 475 | #define B11011001 217 476 | #define B11011010 218 477 | #define B11011011 219 478 | #define B11011100 220 479 | #define B11011101 221 480 | #define B11011110 222 481 | #define B11011111 223 482 | #define B11100000 224 483 | #define B11100001 225 484 | #define B11100010 226 485 | #define B11100011 227 486 | #define B11100100 228 487 | #define B11100101 229 488 | #define B11100110 230 489 | #define B11100111 231 490 | #define B11101000 232 491 | #define B11101001 233 492 | #define B11101010 234 493 | #define B11101011 235 494 | #define B11101100 236 495 | #define B11101101 237 496 | #define B11101110 238 497 | #define B11101111 239 498 | #define B11110000 240 499 | #define B11110001 241 500 | #define B11110010 242 501 | #define B11110011 243 502 | #define B11110100 244 503 | #define B11110101 245 504 | #define B11110110 246 505 | #define B11110111 247 506 | #define B11111000 248 507 | #define B11111001 249 508 | #define B11111010 250 509 | #define B11111011 251 510 | #define B11111100 252 511 | #define B11111101 253 512 | #define B11111110 254 513 | #define B11111111 255 514 | 515 | #endif 516 | -------------------------------------------------------------------------------- /_arduino/hardware_serial.c: -------------------------------------------------------------------------------- 1 | #define __AVR_LIBC_DEPRECATED_ENABLE__ 2 | 3 | /* 4 | hardware_serial.c - Hardware serial library for Wiring 5 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 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 Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | 21 | Modified 23 November 2006 by David A. Mellis 22 | Modified 28 September 2010 by Mark Sproul 23 | Modified 14 August 2012 by Alarus 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "Arduino.h" 31 | 32 | #include "hardware_serial.h" 33 | 34 | // Ring buffer ////////////////////////////////////////////////////////////// 35 | 36 | // Define constants and variables for buffering incoming serial data. We're 37 | // using a ring buffer (I think), in which head is the index of the location 38 | // to which to write the next incoming character and tail is the index of the 39 | // location from which to read. 40 | #if (RAMEND < 1000) 41 | #define SERIAL_BUFFER_SIZE 16 42 | #else 43 | #define SERIAL_BUFFER_SIZE 64 44 | #endif 45 | 46 | struct ring_buffer 47 | { 48 | unsigned char buffer[SERIAL_BUFFER_SIZE]; 49 | volatile unsigned int head; 50 | volatile unsigned int tail; 51 | }; 52 | 53 | #if defined(USBCON) || defined(UBRRH) || defined(UBRR0H) 54 | struct ring_buffer rx_buffer = { { 0 }, 0, 0}; 55 | struct ring_buffer tx_buffer = { { 0 }, 0, 0}; 56 | #endif 57 | 58 | void ringbuf_insert_nowait(unsigned char c, struct ring_buffer *buffer) 59 | { 60 | int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE; 61 | 62 | // if we should be storing the received character into the location 63 | // just before the tail (meaning that the head would advance to the 64 | // current location of the tail), we're about to overflow the buffer 65 | // and so we don't write the character or advance the head. 66 | if (i != buffer->tail) { 67 | buffer->buffer[buffer->head] = c; 68 | buffer->head = i; 69 | } 70 | } 71 | 72 | void ringbuf_insert_wait(unsigned char c, struct ring_buffer *buffer) 73 | { 74 | int i = (buffer->head + 1) % SERIAL_BUFFER_SIZE; 75 | 76 | // If the output buffer is full, there's nothing for it other than to 77 | // wait for the interrupt handler to empty it a bit 78 | // ???: return 0 here instead? 79 | while (i == buffer->tail) 80 | ; 81 | 82 | buffer->buffer[buffer->head] = c; 83 | buffer->head = i; 84 | } 85 | 86 | bool ringbuf_is_empty(struct ring_buffer *buffer) 87 | { 88 | return (buffer->head == buffer->tail); 89 | } 90 | 91 | unsigned int ringbuf_get_size(struct ring_buffer *buffer) 92 | { 93 | return (unsigned int)(SERIAL_BUFFER_SIZE + buffer->head - buffer->tail) % SERIAL_BUFFER_SIZE; 94 | } 95 | 96 | unsigned char ringbuf_peek(struct ring_buffer *buffer) 97 | { 98 | return buffer->buffer[buffer->tail];; 99 | } 100 | 101 | unsigned char ringbuf_remove(struct ring_buffer *buffer) 102 | { 103 | unsigned char c = ringbuf_peek(buffer); 104 | buffer->tail = (buffer->tail + 1) % SERIAL_BUFFER_SIZE; 105 | return c; 106 | } 107 | 108 | void ringbuf_clear(struct ring_buffer *buffer) 109 | { 110 | buffer->head = buffer->tail; 111 | } 112 | -------------------------------------------------------------------------------- /_arduino/hardware_serial.h: -------------------------------------------------------------------------------- 1 | /* 2 | hardware_serial.h - Hardware serial library for 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 28 September 2010 by Mark Sproul 20 | Modified 14 August 2012 by Alarus 21 | */ 22 | 23 | #ifndef HardwareSerial_h 24 | #define HardwareSerial_h 25 | 26 | #include 27 | #include 28 | #include "wiring_private.h" 29 | 30 | struct ring_buffer; 31 | 32 | // Define config for Serial.begin(baud, config); 33 | #define SERIAL_5N1 0x00 34 | #define SERIAL_6N1 0x02 35 | #define SERIAL_7N1 0x04 36 | #define SERIAL_8N1 0x06 37 | #define SERIAL_5N2 0x08 38 | #define SERIAL_6N2 0x0A 39 | #define SERIAL_7N2 0x0C 40 | #define SERIAL_8N2 0x0E 41 | #define SERIAL_5E1 0x20 42 | #define SERIAL_6E1 0x22 43 | #define SERIAL_7E1 0x24 44 | #define SERIAL_8E1 0x26 45 | #define SERIAL_5E2 0x28 46 | #define SERIAL_6E2 0x2A 47 | #define SERIAL_7E2 0x2C 48 | #define SERIAL_8E2 0x2E 49 | #define SERIAL_5O1 0x30 50 | #define SERIAL_6O1 0x32 51 | #define SERIAL_7O1 0x34 52 | #define SERIAL_8O1 0x36 53 | #define SERIAL_5O2 0x38 54 | #define SERIAL_6O2 0x3A 55 | #define SERIAL_7O2 0x3C 56 | #define SERIAL_8O2 0x3E 57 | 58 | #if defined(USBCON) || defined(UBRRH) || defined(UBRR0H) 59 | extern struct ring_buffer rx_buffer; 60 | extern struct ring_buffer tx_buffer; 61 | #endif 62 | 63 | inline void c_sbi(volatile uint8_t *addr, uint8_t bit) { 64 | sbi(*((volatile uint8_t *) addr), bit); 65 | } 66 | 67 | inline void c_cbi(volatile uint8_t *addr, uint8_t bit) { 68 | cbi(*((volatile uint8_t *) addr), bit); 69 | } 70 | 71 | inline uint8_t c_rbi(volatile uint8_t *addr, uint8_t bit) { 72 | return (_SFR_BYTE(*((volatile uint8_t *) addr)) & _BV(bit)); 73 | } 74 | 75 | void ringbuf_insert_nowait(unsigned char c, struct ring_buffer *buffer); 76 | void ringbuf_insert_wait(unsigned char c, struct ring_buffer *buffer); 77 | bool ringbuf_is_empty(struct ring_buffer *buffer); 78 | unsigned int ringbuf_get_size(struct ring_buffer *buffer); 79 | unsigned char ringbuf_peek(struct ring_buffer *buffer); 80 | unsigned char ringbuf_remove(struct ring_buffer *buffer); 81 | void ringbuf_clear(struct ring_buffer *buffer); 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /_arduino/pins_arduino.h: -------------------------------------------------------------------------------- 1 | #ifndef PINS_ARDUINO_H_TOP 2 | #define PINS_ARDUINO_H_TOP 3 | 4 | #if defined(__AVR_ATmega2560__) // Arduino Mega 2560 5 | #include "variants/mega/pins_arduino.h" 6 | #else // Arduino Uno 7 | #include "variants/standard/pins_arduino.h" 8 | #endif 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /_arduino/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 | 30 | #ifndef cbi 31 | #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 32 | #endif 33 | 34 | #ifndef sbi 35 | #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) 36 | #endif 37 | 38 | #include "pins_arduino.h" 39 | #include "twi.h" 40 | 41 | static volatile uint8_t twi_state; 42 | static volatile uint8_t twi_slarw; 43 | static volatile uint8_t twi_sendStop; // should the transaction end with a stop 44 | static volatile uint8_t twi_inRepStart; // in the middle of a repeated start 45 | 46 | static void (*twi_onSlaveTransmit)(void); 47 | static void (*twi_onSlaveReceive)(uint8_t*, int); 48 | 49 | static uint8_t twi_masterBuffer[TWI_BUFFER_LENGTH]; 50 | static volatile uint8_t twi_masterBufferIndex; 51 | static volatile uint8_t twi_masterBufferLength; 52 | 53 | static uint8_t twi_txBuffer[TWI_BUFFER_LENGTH]; 54 | static volatile uint8_t twi_txBufferIndex; 55 | static volatile uint8_t twi_txBufferLength; 56 | 57 | static uint8_t twi_rxBuffer[TWI_BUFFER_LENGTH]; 58 | static volatile uint8_t twi_rxBufferIndex; 59 | 60 | static volatile uint8_t twi_error; 61 | 62 | /* 63 | * Function twi_init 64 | * Desc readys twi pins and sets twi bitrate 65 | * Input none 66 | * Output none 67 | */ 68 | void twi_init(void) 69 | { 70 | // initialize state 71 | twi_state = TWI_READY; 72 | twi_sendStop = true; // default value 73 | twi_inRepStart = false; 74 | 75 | // activate internal pullups for twi. 76 | digitalWrite(SDA, 1); 77 | digitalWrite(SCL, 1); 78 | 79 | // initialize twi prescaler and bit rate 80 | cbi(TWSR, TWPS0); 81 | cbi(TWSR, TWPS1); 82 | TWBR = ((F_CPU / TWI_FREQ) - 16) / 2; 83 | 84 | /* twi bit rate formula from atmega128 manual pg 204 85 | SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR)) 86 | note: TWBR should be 10 or higher for master mode 87 | It is 72 for a 16mhz Wiring board with 100kHz TWI */ 88 | 89 | // enable twi module, acks, and twi interrupt 90 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA); 91 | } 92 | 93 | /* 94 | * Function twi_slaveInit 95 | * Desc sets slave address and enables interrupt 96 | * Input none 97 | * Output none 98 | */ 99 | void twi_setAddress(uint8_t address) 100 | { 101 | // set twi slave address (skip over TWGCE bit) 102 | TWAR = address << 1; 103 | } 104 | 105 | /* 106 | * Function twi_readFrom 107 | * Desc attempts to become twi bus master and read a 108 | * series of bytes from a device on the bus 109 | * Input address: 7bit i2c device address 110 | * data: pointer to byte array 111 | * length: number of bytes to read into array 112 | * sendStop: Boolean indicating whether to send a stop at the end 113 | * Output number of bytes read 114 | */ 115 | uint8_t twi_readFrom(uint8_t address, uint8_t* data, uint8_t length, uint8_t sendStop) 116 | { 117 | uint8_t i; 118 | 119 | // ensure data will fit into buffer 120 | if(TWI_BUFFER_LENGTH < length){ 121 | return 0; 122 | } 123 | 124 | // wait until twi is ready, become master receiver 125 | while(TWI_READY != twi_state){ 126 | continue; 127 | } 128 | twi_state = TWI_MRX; 129 | twi_sendStop = sendStop; 130 | // reset error state (0xFF.. no error occured) 131 | twi_error = 0xFF; 132 | 133 | // initialize buffer iteration vars 134 | twi_masterBufferIndex = 0; 135 | twi_masterBufferLength = length-1; // This is not intuitive, read on... 136 | // On receive, the previously configured ACK/NACK setting is transmitted in 137 | // response to the received byte before the interrupt is signalled. 138 | // Therefor we must actually set NACK when the _next_ to last byte is 139 | // received, causing that NACK to be sent in response to receiving the last 140 | // expected byte of data. 141 | 142 | // build sla+w, slave device address + w bit 143 | twi_slarw = TW_READ; 144 | twi_slarw |= address << 1; 145 | 146 | if (true == twi_inRepStart) { 147 | // if we're in the repeated start state, then we've already sent the start, 148 | // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. 149 | // We need to remove ourselves from the repeated start state before we enable interrupts, 150 | // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning 151 | // up. Also, don't enable the START interrupt. There may be one pending from the 152 | // repeated start that we sent outselves, and that would really confuse things. 153 | twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR 154 | TWDR = twi_slarw; 155 | TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START 156 | } 157 | else 158 | // send start condition 159 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTA); 160 | 161 | // wait for read operation to complete 162 | while(TWI_MRX == twi_state){ 163 | continue; 164 | } 165 | 166 | if (twi_masterBufferIndex < length) 167 | length = twi_masterBufferIndex; 168 | 169 | // copy twi buffer to data 170 | for(i = 0; i < length; ++i){ 171 | data[i] = twi_masterBuffer[i]; 172 | } 173 | 174 | return length; 175 | } 176 | 177 | /* 178 | * Function twi_writeTo 179 | * Desc attempts to become twi bus master and write a 180 | * series of bytes to a device on the bus 181 | * Input address: 7bit i2c device address 182 | * data: pointer to byte array 183 | * length: number of bytes in array 184 | * wait: boolean indicating to wait for write or not 185 | * sendStop: boolean indicating whether or not to send a stop at the end 186 | * Output 0 .. success 187 | * 1 .. length to long for buffer 188 | * 2 .. address send, NACK received 189 | * 3 .. data send, NACK received 190 | * 4 .. other twi error (lost bus arbitration, bus error, ..) 191 | */ 192 | uint8_t twi_writeTo(uint8_t address, uint8_t* data, uint8_t length, uint8_t wait, uint8_t sendStop) 193 | { 194 | uint8_t i; 195 | 196 | // ensure data will fit into buffer 197 | if(TWI_BUFFER_LENGTH < length){ 198 | return 1; 199 | } 200 | 201 | // wait until twi is ready, become master transmitter 202 | while(TWI_READY != twi_state){ 203 | continue; 204 | } 205 | twi_state = TWI_MTX; 206 | twi_sendStop = sendStop; 207 | // reset error state (0xFF.. no error occured) 208 | twi_error = 0xFF; 209 | 210 | // initialize buffer iteration vars 211 | twi_masterBufferIndex = 0; 212 | twi_masterBufferLength = length; 213 | 214 | // copy data to twi buffer 215 | for(i = 0; i < length; ++i){ 216 | twi_masterBuffer[i] = data[i]; 217 | } 218 | 219 | // build sla+w, slave device address + w bit 220 | twi_slarw = TW_WRITE; 221 | twi_slarw |= address << 1; 222 | 223 | // if we're in a repeated start, then we've already sent the START 224 | // in the ISR. Don't do it again. 225 | // 226 | if (true == twi_inRepStart) { 227 | // if we're in the repeated start state, then we've already sent the start, 228 | // (@@@ we hope), and the TWI statemachine is just waiting for the address byte. 229 | // We need to remove ourselves from the repeated start state before we enable interrupts, 230 | // since the ISR is ASYNC, and we could get confused if we hit the ISR before cleaning 231 | // up. Also, don't enable the START interrupt. There may be one pending from the 232 | // repeated start that we sent outselves, and that would really confuse things. 233 | twi_inRepStart = false; // remember, we're dealing with an ASYNC ISR 234 | TWDR = twi_slarw; 235 | TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE); // enable INTs, but not START 236 | } 237 | else 238 | // send start condition 239 | TWCR = _BV(TWINT) | _BV(TWEA) | _BV(TWEN) | _BV(TWIE) | _BV(TWSTA); // enable INTs 240 | 241 | // wait for write operation to complete 242 | while(wait && (TWI_MTX == twi_state)){ 243 | continue; 244 | } 245 | 246 | if (twi_error == 0xFF) 247 | return 0; // success 248 | else if (twi_error == TW_MT_SLA_NACK) 249 | return 2; // error: address send, nack received 250 | else if (twi_error == TW_MT_DATA_NACK) 251 | return 3; // error: data send, nack received 252 | else 253 | return 4; // other twi error 254 | } 255 | 256 | /* 257 | * Function twi_transmit 258 | * Desc fills slave tx buffer with data 259 | * must be called in slave tx event callback 260 | * Input data: pointer to byte array 261 | * length: number of bytes in array 262 | * Output 1 length too long for buffer 263 | * 2 not slave transmitter 264 | * 0 ok 265 | */ 266 | uint8_t twi_transmit(const uint8_t* data, uint8_t length) 267 | { 268 | uint8_t i; 269 | 270 | // ensure data will fit into buffer 271 | if(TWI_BUFFER_LENGTH < length){ 272 | return 1; 273 | } 274 | 275 | // ensure we are currently a slave transmitter 276 | if(TWI_STX != twi_state){ 277 | return 2; 278 | } 279 | 280 | // set length and copy data into tx buffer 281 | twi_txBufferLength = length; 282 | for(i = 0; i < length; ++i){ 283 | twi_txBuffer[i] = data[i]; 284 | } 285 | 286 | return 0; 287 | } 288 | 289 | /* 290 | * Function twi_attachSlaveRxEvent 291 | * Desc sets function called before a slave read operation 292 | * Input function: callback function to use 293 | * Output none 294 | */ 295 | void twi_attachSlaveRxEvent( void (*function)(uint8_t*, int) ) 296 | { 297 | twi_onSlaveReceive = function; 298 | } 299 | 300 | /* 301 | * Function twi_attachSlaveTxEvent 302 | * Desc sets function called before a slave write operation 303 | * Input function: callback function to use 304 | * Output none 305 | */ 306 | void twi_attachSlaveTxEvent( void (*function)(void) ) 307 | { 308 | twi_onSlaveTransmit = function; 309 | } 310 | 311 | /* 312 | * Function twi_reply 313 | * Desc sends byte or readys receive line 314 | * Input ack: byte indicating to ack or to nack 315 | * Output none 316 | */ 317 | void twi_reply(uint8_t ack) 318 | { 319 | // transmit master read ready signal, with or without ack 320 | if(ack){ 321 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT) | _BV(TWEA); 322 | }else{ 323 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWINT); 324 | } 325 | } 326 | 327 | /* 328 | * Function twi_stop 329 | * Desc relinquishes bus master status 330 | * Input none 331 | * Output none 332 | */ 333 | void twi_stop(void) 334 | { 335 | // send stop condition 336 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT) | _BV(TWSTO); 337 | 338 | // wait for stop condition to be exectued on bus 339 | // TWINT is not set after a stop condition! 340 | while(TWCR & _BV(TWSTO)){ 341 | continue; 342 | } 343 | 344 | // update twi state 345 | twi_state = TWI_READY; 346 | } 347 | 348 | /* 349 | * Function twi_releaseBus 350 | * Desc releases bus control 351 | * Input none 352 | * Output none 353 | */ 354 | void twi_releaseBus(void) 355 | { 356 | // release bus 357 | TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA) | _BV(TWINT); 358 | 359 | // update twi state 360 | twi_state = TWI_READY; 361 | } 362 | 363 | ISR(TWI_vect) 364 | { 365 | switch(TW_STATUS){ 366 | // All Master 367 | case TW_START: // sent start condition 368 | case TW_REP_START: // sent repeated start condition 369 | // copy device address and r/w bit to output register and ack 370 | TWDR = twi_slarw; 371 | twi_reply(1); 372 | break; 373 | 374 | // Master Transmitter 375 | case TW_MT_SLA_ACK: // slave receiver acked address 376 | case TW_MT_DATA_ACK: // slave receiver acked data 377 | // if there is data to send, send it, otherwise stop 378 | if(twi_masterBufferIndex < twi_masterBufferLength){ 379 | // copy data to output register and ack 380 | TWDR = twi_masterBuffer[twi_masterBufferIndex++]; 381 | twi_reply(1); 382 | }else{ 383 | if (twi_sendStop) 384 | twi_stop(); 385 | else { 386 | twi_inRepStart = true; // we're gonna send the START 387 | // don't enable the interrupt. We'll generate the start, but we 388 | // avoid handling the interrupt until we're in the next transaction, 389 | // at the point where we would normally issue the start. 390 | TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; 391 | twi_state = TWI_READY; 392 | } 393 | } 394 | break; 395 | case TW_MT_SLA_NACK: // address sent, nack received 396 | twi_error = TW_MT_SLA_NACK; 397 | twi_stop(); 398 | break; 399 | case TW_MT_DATA_NACK: // data sent, nack received 400 | twi_error = TW_MT_DATA_NACK; 401 | twi_stop(); 402 | break; 403 | case TW_MT_ARB_LOST: // lost bus arbitration 404 | twi_error = TW_MT_ARB_LOST; 405 | twi_releaseBus(); 406 | break; 407 | 408 | // Master Receiver 409 | case TW_MR_DATA_ACK: // data received, ack sent 410 | // put byte into buffer 411 | twi_masterBuffer[twi_masterBufferIndex++] = TWDR; 412 | case TW_MR_SLA_ACK: // address sent, ack received 413 | // ack if more bytes are expected, otherwise nack 414 | if(twi_masterBufferIndex < twi_masterBufferLength){ 415 | twi_reply(1); 416 | }else{ 417 | twi_reply(0); 418 | } 419 | break; 420 | case TW_MR_DATA_NACK: // data received, nack sent 421 | // put final byte into buffer 422 | twi_masterBuffer[twi_masterBufferIndex++] = TWDR; 423 | if (twi_sendStop) 424 | twi_stop(); 425 | else { 426 | twi_inRepStart = true; // we're gonna send the START 427 | // don't enable the interrupt. We'll generate the start, but we 428 | // avoid handling the interrupt until we're in the next transaction, 429 | // at the point where we would normally issue the start. 430 | TWCR = _BV(TWINT) | _BV(TWSTA)| _BV(TWEN) ; 431 | twi_state = TWI_READY; 432 | } 433 | break; 434 | case TW_MR_SLA_NACK: // address sent, nack received 435 | twi_stop(); 436 | break; 437 | // TW_MR_ARB_LOST handled by TW_MT_ARB_LOST case 438 | 439 | // Slave Receiver 440 | case TW_SR_SLA_ACK: // addressed, returned ack 441 | case TW_SR_GCALL_ACK: // addressed generally, returned ack 442 | case TW_SR_ARB_LOST_SLA_ACK: // lost arbitration, returned ack 443 | case TW_SR_ARB_LOST_GCALL_ACK: // lost arbitration, returned ack 444 | // enter slave receiver mode 445 | twi_state = TWI_SRX; 446 | // indicate that rx buffer can be overwritten and ack 447 | twi_rxBufferIndex = 0; 448 | twi_reply(1); 449 | break; 450 | case TW_SR_DATA_ACK: // data received, returned ack 451 | case TW_SR_GCALL_DATA_ACK: // data received generally, returned ack 452 | // if there is still room in the rx buffer 453 | if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ 454 | // put byte in buffer and ack 455 | twi_rxBuffer[twi_rxBufferIndex++] = TWDR; 456 | twi_reply(1); 457 | }else{ 458 | // otherwise nack 459 | twi_reply(0); 460 | } 461 | break; 462 | case TW_SR_STOP: // stop or repeated start condition received 463 | // put a null char after data if there's room 464 | if(twi_rxBufferIndex < TWI_BUFFER_LENGTH){ 465 | twi_rxBuffer[twi_rxBufferIndex] = '\0'; 466 | } 467 | // sends ack and stops interface for clock stretching 468 | twi_stop(); 469 | // callback to user defined callback 470 | twi_onSlaveReceive(twi_rxBuffer, twi_rxBufferIndex); 471 | // since we submit rx buffer to "wire" library, we can reset it 472 | twi_rxBufferIndex = 0; 473 | // ack future responses and leave slave receiver state 474 | twi_releaseBus(); 475 | break; 476 | case TW_SR_DATA_NACK: // data received, returned nack 477 | case TW_SR_GCALL_DATA_NACK: // data received generally, returned nack 478 | // nack back at master 479 | twi_reply(0); 480 | break; 481 | 482 | // Slave Transmitter 483 | case TW_ST_SLA_ACK: // addressed, returned ack 484 | case TW_ST_ARB_LOST_SLA_ACK: // arbitration lost, returned ack 485 | // enter slave transmitter mode 486 | twi_state = TWI_STX; 487 | // ready the tx buffer index for iteration 488 | twi_txBufferIndex = 0; 489 | // set tx buffer length to be zero, to verify if user changes it 490 | twi_txBufferLength = 0; 491 | // request for txBuffer to be filled and length to be set 492 | // note: user must call twi_transmit(bytes, length) to do this 493 | twi_onSlaveTransmit(); 494 | // if they didn't change buffer & length, initialize it 495 | if(0 == twi_txBufferLength){ 496 | twi_txBufferLength = 1; 497 | twi_txBuffer[0] = 0x00; 498 | } 499 | // transmit first byte from buffer, fall 500 | case TW_ST_DATA_ACK: // byte sent, ack returned 501 | // copy data to output register 502 | TWDR = twi_txBuffer[twi_txBufferIndex++]; 503 | // if there is more to send, ack, otherwise nack 504 | if(twi_txBufferIndex < twi_txBufferLength){ 505 | twi_reply(1); 506 | }else{ 507 | twi_reply(0); 508 | } 509 | break; 510 | case TW_ST_DATA_NACK: // received nack, we are done 511 | case TW_ST_LAST_DATA: // received ack, but we are done already! 512 | // ack future responses 513 | twi_reply(1); 514 | // leave slave receiver state 515 | twi_state = TWI_READY; 516 | break; 517 | 518 | // All 519 | case TW_NO_INFO: // no state information 520 | break; 521 | case TW_BUS_ERROR: // bus error, illegal stop/start 522 | twi_error = TW_BUS_ERROR; 523 | twi_stop(); 524 | break; 525 | } 526 | } 527 | 528 | -------------------------------------------------------------------------------- /_arduino/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 | //#define ATMEGA8 26 | 27 | #ifndef TWI_FREQ 28 | #define TWI_FREQ 100000L 29 | #endif 30 | 31 | #ifndef TWI_BUFFER_LENGTH 32 | #define TWI_BUFFER_LENGTH 32 33 | #endif 34 | 35 | #define TWI_READY 0 36 | #define TWI_MRX 1 37 | #define TWI_MTX 2 38 | #define TWI_SRX 3 39 | #define TWI_STX 4 40 | 41 | void twi_init(void); 42 | void twi_setAddress(uint8_t); 43 | uint8_t twi_readFrom(uint8_t, uint8_t*, uint8_t, uint8_t); 44 | uint8_t twi_writeTo(uint8_t, uint8_t*, uint8_t, uint8_t, uint8_t); 45 | uint8_t twi_transmit(const uint8_t*, uint8_t); 46 | void twi_attachSlaveRxEvent( void (*)(uint8_t*, int) ); 47 | void twi_attachSlaveTxEvent( void (*)(void) ); 48 | void twi_reply(uint8_t); 49 | void twi_stop(void); 50 | void twi_releaseBus(void); 51 | 52 | #endif 53 | 54 | -------------------------------------------------------------------------------- /_arduino/variants/mega/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 | $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $ 23 | */ 24 | 25 | #ifndef Pins_Arduino_h 26 | #define Pins_Arduino_h 27 | 28 | #include 29 | 30 | #define NUM_DIGITAL_PINS 70 31 | #define NUM_ANALOG_INPUTS 16 32 | #define analogInputToDigitalPin(p) ((p < 16) ? (p) + 54 : -1) 33 | #define digitalPinHasPWM(p) (((p) >= 2 && (p) <= 13) || ((p) >= 44 && (p)<= 46)) 34 | 35 | static const uint8_t SS = 53; 36 | static const uint8_t MOSI = 51; 37 | static const uint8_t MISO = 50; 38 | static const uint8_t SCK = 52; 39 | 40 | static const uint8_t SDA = 20; 41 | static const uint8_t SCL = 21; 42 | static const uint8_t LED_BUILTIN = 13; 43 | 44 | static const uint8_t A0 = 54; 45 | static const uint8_t A1 = 55; 46 | static const uint8_t A2 = 56; 47 | static const uint8_t A3 = 57; 48 | static const uint8_t A4 = 58; 49 | static const uint8_t A5 = 59; 50 | static const uint8_t A6 = 60; 51 | static const uint8_t A7 = 61; 52 | static const uint8_t A8 = 62; 53 | static const uint8_t A9 = 63; 54 | static const uint8_t A10 = 64; 55 | static const uint8_t A11 = 65; 56 | static const uint8_t A12 = 66; 57 | static const uint8_t A13 = 67; 58 | static const uint8_t A14 = 68; 59 | static const uint8_t A15 = 69; 60 | 61 | // A majority of the pins are NOT PCINTs, SO BE WARNED (i.e. you cannot use them as receive pins) 62 | // Only pins available for RECEIVE (TRANSMIT can be on any pin): 63 | // (I've deliberately left out pin mapping to the Hardware USARTs - seems senseless to me) 64 | // Pins: 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69 65 | 66 | #define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 13)) || \ 67 | (((p) >= 50) && ((p) <= 53)) || \ 68 | (((p) >= 62) && ((p) <= 69)) ? (&PCICR) : ((uint8_t *)0) ) 69 | 70 | #define digitalPinToPCICRbit(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? 0 : \ 71 | ( (((p) >= 62) && ((p) <= 69)) ? 2 : \ 72 | 0 ) ) 73 | 74 | #define digitalPinToPCMSK(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? (&PCMSK0) : \ 75 | ( (((p) >= 62) && ((p) <= 69)) ? (&PCMSK2) : \ 76 | ((uint8_t *)0) ) ) 77 | 78 | #define digitalPinToPCMSKbit(p) ( (((p) >= 10) && ((p) <= 13)) ? ((p) - 6) : \ 79 | ( ((p) == 50) ? 3 : \ 80 | ( ((p) == 51) ? 2 : \ 81 | ( ((p) == 52) ? 1 : \ 82 | ( ((p) == 53) ? 0 : \ 83 | ( (((p) >= 62) && ((p) <= 69)) ? ((p) - 62) : \ 84 | 0 ) ) ) ) ) ) 85 | 86 | #ifdef ARDUINO_MAIN 87 | 88 | const uint16_t PROGMEM port_to_mode_PGM[] = { 89 | NOT_A_PORT, 90 | (uint16_t) &DDRA, 91 | (uint16_t) &DDRB, 92 | (uint16_t) &DDRC, 93 | (uint16_t) &DDRD, 94 | (uint16_t) &DDRE, 95 | (uint16_t) &DDRF, 96 | (uint16_t) &DDRG, 97 | (uint16_t) &DDRH, 98 | NOT_A_PORT, 99 | (uint16_t) &DDRJ, 100 | (uint16_t) &DDRK, 101 | (uint16_t) &DDRL, 102 | }; 103 | 104 | const uint16_t PROGMEM port_to_output_PGM[] = { 105 | NOT_A_PORT, 106 | (uint16_t) &PORTA, 107 | (uint16_t) &PORTB, 108 | (uint16_t) &PORTC, 109 | (uint16_t) &PORTD, 110 | (uint16_t) &PORTE, 111 | (uint16_t) &PORTF, 112 | (uint16_t) &PORTG, 113 | (uint16_t) &PORTH, 114 | NOT_A_PORT, 115 | (uint16_t) &PORTJ, 116 | (uint16_t) &PORTK, 117 | (uint16_t) &PORTL, 118 | }; 119 | 120 | const uint16_t PROGMEM port_to_input_PGM[] = { 121 | NOT_A_PIN, 122 | (uint16_t) &PINA, 123 | (uint16_t) &PINB, 124 | (uint16_t) &PINC, 125 | (uint16_t) &PIND, 126 | (uint16_t) &PINE, 127 | (uint16_t) &PINF, 128 | (uint16_t) &PING, 129 | (uint16_t) &PINH, 130 | NOT_A_PIN, 131 | (uint16_t) &PINJ, 132 | (uint16_t) &PINK, 133 | (uint16_t) &PINL, 134 | }; 135 | 136 | const uint8_t PROGMEM digital_pin_to_port_PGM[] = { 137 | // PORTLIST 138 | // ------------------------------------------- 139 | PE , // PE 0 ** 0 ** USART0_RX 140 | PE , // PE 1 ** 1 ** USART0_TX 141 | PE , // PE 4 ** 2 ** PWM2 142 | PE , // PE 5 ** 3 ** PWM3 143 | PG , // PG 5 ** 4 ** PWM4 144 | PE , // PE 3 ** 5 ** PWM5 145 | PH , // PH 3 ** 6 ** PWM6 146 | PH , // PH 4 ** 7 ** PWM7 147 | PH , // PH 5 ** 8 ** PWM8 148 | PH , // PH 6 ** 9 ** PWM9 149 | PB , // PB 4 ** 10 ** PWM10 150 | PB , // PB 5 ** 11 ** PWM11 151 | PB , // PB 6 ** 12 ** PWM12 152 | PB , // PB 7 ** 13 ** PWM13 153 | PJ , // PJ 1 ** 14 ** USART3_TX 154 | PJ , // PJ 0 ** 15 ** USART3_RX 155 | PH , // PH 1 ** 16 ** USART2_TX 156 | PH , // PH 0 ** 17 ** USART2_RX 157 | PD , // PD 3 ** 18 ** USART1_TX 158 | PD , // PD 2 ** 19 ** USART1_RX 159 | PD , // PD 1 ** 20 ** I2C_SDA 160 | PD , // PD 0 ** 21 ** I2C_SCL 161 | PA , // PA 0 ** 22 ** D22 162 | PA , // PA 1 ** 23 ** D23 163 | PA , // PA 2 ** 24 ** D24 164 | PA , // PA 3 ** 25 ** D25 165 | PA , // PA 4 ** 26 ** D26 166 | PA , // PA 5 ** 27 ** D27 167 | PA , // PA 6 ** 28 ** D28 168 | PA , // PA 7 ** 29 ** D29 169 | PC , // PC 7 ** 30 ** D30 170 | PC , // PC 6 ** 31 ** D31 171 | PC , // PC 5 ** 32 ** D32 172 | PC , // PC 4 ** 33 ** D33 173 | PC , // PC 3 ** 34 ** D34 174 | PC , // PC 2 ** 35 ** D35 175 | PC , // PC 1 ** 36 ** D36 176 | PC , // PC 0 ** 37 ** D37 177 | PD , // PD 7 ** 38 ** D38 178 | PG , // PG 2 ** 39 ** D39 179 | PG , // PG 1 ** 40 ** D40 180 | PG , // PG 0 ** 41 ** D41 181 | PL , // PL 7 ** 42 ** D42 182 | PL , // PL 6 ** 43 ** D43 183 | PL , // PL 5 ** 44 ** D44 184 | PL , // PL 4 ** 45 ** D45 185 | PL , // PL 3 ** 46 ** D46 186 | PL , // PL 2 ** 47 ** D47 187 | PL , // PL 1 ** 48 ** D48 188 | PL , // PL 0 ** 49 ** D49 189 | PB , // PB 3 ** 50 ** SPI_MISO 190 | PB , // PB 2 ** 51 ** SPI_MOSI 191 | PB , // PB 1 ** 52 ** SPI_SCK 192 | PB , // PB 0 ** 53 ** SPI_SS 193 | PF , // PF 0 ** 54 ** A0 194 | PF , // PF 1 ** 55 ** A1 195 | PF , // PF 2 ** 56 ** A2 196 | PF , // PF 3 ** 57 ** A3 197 | PF , // PF 4 ** 58 ** A4 198 | PF , // PF 5 ** 59 ** A5 199 | PF , // PF 6 ** 60 ** A6 200 | PF , // PF 7 ** 61 ** A7 201 | PK , // PK 0 ** 62 ** A8 202 | PK , // PK 1 ** 63 ** A9 203 | PK , // PK 2 ** 64 ** A10 204 | PK , // PK 3 ** 65 ** A11 205 | PK , // PK 4 ** 66 ** A12 206 | PK , // PK 5 ** 67 ** A13 207 | PK , // PK 6 ** 68 ** A14 208 | PK , // PK 7 ** 69 ** A15 209 | }; 210 | 211 | const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { 212 | // PIN IN PORT 213 | // ------------------------------------------- 214 | _BV( 0 ) , // PE 0 ** 0 ** USART0_RX 215 | _BV( 1 ) , // PE 1 ** 1 ** USART0_TX 216 | _BV( 4 ) , // PE 4 ** 2 ** PWM2 217 | _BV( 5 ) , // PE 5 ** 3 ** PWM3 218 | _BV( 5 ) , // PG 5 ** 4 ** PWM4 219 | _BV( 3 ) , // PE 3 ** 5 ** PWM5 220 | _BV( 3 ) , // PH 3 ** 6 ** PWM6 221 | _BV( 4 ) , // PH 4 ** 7 ** PWM7 222 | _BV( 5 ) , // PH 5 ** 8 ** PWM8 223 | _BV( 6 ) , // PH 6 ** 9 ** PWM9 224 | _BV( 4 ) , // PB 4 ** 10 ** PWM10 225 | _BV( 5 ) , // PB 5 ** 11 ** PWM11 226 | _BV( 6 ) , // PB 6 ** 12 ** PWM12 227 | _BV( 7 ) , // PB 7 ** 13 ** PWM13 228 | _BV( 1 ) , // PJ 1 ** 14 ** USART3_TX 229 | _BV( 0 ) , // PJ 0 ** 15 ** USART3_RX 230 | _BV( 1 ) , // PH 1 ** 16 ** USART2_TX 231 | _BV( 0 ) , // PH 0 ** 17 ** USART2_RX 232 | _BV( 3 ) , // PD 3 ** 18 ** USART1_TX 233 | _BV( 2 ) , // PD 2 ** 19 ** USART1_RX 234 | _BV( 1 ) , // PD 1 ** 20 ** I2C_SDA 235 | _BV( 0 ) , // PD 0 ** 21 ** I2C_SCL 236 | _BV( 0 ) , // PA 0 ** 22 ** D22 237 | _BV( 1 ) , // PA 1 ** 23 ** D23 238 | _BV( 2 ) , // PA 2 ** 24 ** D24 239 | _BV( 3 ) , // PA 3 ** 25 ** D25 240 | _BV( 4 ) , // PA 4 ** 26 ** D26 241 | _BV( 5 ) , // PA 5 ** 27 ** D27 242 | _BV( 6 ) , // PA 6 ** 28 ** D28 243 | _BV( 7 ) , // PA 7 ** 29 ** D29 244 | _BV( 7 ) , // PC 7 ** 30 ** D30 245 | _BV( 6 ) , // PC 6 ** 31 ** D31 246 | _BV( 5 ) , // PC 5 ** 32 ** D32 247 | _BV( 4 ) , // PC 4 ** 33 ** D33 248 | _BV( 3 ) , // PC 3 ** 34 ** D34 249 | _BV( 2 ) , // PC 2 ** 35 ** D35 250 | _BV( 1 ) , // PC 1 ** 36 ** D36 251 | _BV( 0 ) , // PC 0 ** 37 ** D37 252 | _BV( 7 ) , // PD 7 ** 38 ** D38 253 | _BV( 2 ) , // PG 2 ** 39 ** D39 254 | _BV( 1 ) , // PG 1 ** 40 ** D40 255 | _BV( 0 ) , // PG 0 ** 41 ** D41 256 | _BV( 7 ) , // PL 7 ** 42 ** D42 257 | _BV( 6 ) , // PL 6 ** 43 ** D43 258 | _BV( 5 ) , // PL 5 ** 44 ** D44 259 | _BV( 4 ) , // PL 4 ** 45 ** D45 260 | _BV( 3 ) , // PL 3 ** 46 ** D46 261 | _BV( 2 ) , // PL 2 ** 47 ** D47 262 | _BV( 1 ) , // PL 1 ** 48 ** D48 263 | _BV( 0 ) , // PL 0 ** 49 ** D49 264 | _BV( 3 ) , // PB 3 ** 50 ** SPI_MISO 265 | _BV( 2 ) , // PB 2 ** 51 ** SPI_MOSI 266 | _BV( 1 ) , // PB 1 ** 52 ** SPI_SCK 267 | _BV( 0 ) , // PB 0 ** 53 ** SPI_SS 268 | _BV( 0 ) , // PF 0 ** 54 ** A0 269 | _BV( 1 ) , // PF 1 ** 55 ** A1 270 | _BV( 2 ) , // PF 2 ** 56 ** A2 271 | _BV( 3 ) , // PF 3 ** 57 ** A3 272 | _BV( 4 ) , // PF 4 ** 58 ** A4 273 | _BV( 5 ) , // PF 5 ** 59 ** A5 274 | _BV( 6 ) , // PF 6 ** 60 ** A6 275 | _BV( 7 ) , // PF 7 ** 61 ** A7 276 | _BV( 0 ) , // PK 0 ** 62 ** A8 277 | _BV( 1 ) , // PK 1 ** 63 ** A9 278 | _BV( 2 ) , // PK 2 ** 64 ** A10 279 | _BV( 3 ) , // PK 3 ** 65 ** A11 280 | _BV( 4 ) , // PK 4 ** 66 ** A12 281 | _BV( 5 ) , // PK 5 ** 67 ** A13 282 | _BV( 6 ) , // PK 6 ** 68 ** A14 283 | _BV( 7 ) , // PK 7 ** 69 ** A15 284 | }; 285 | 286 | const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { 287 | // TIMERS 288 | // ------------------------------------------- 289 | NOT_ON_TIMER , // PE 0 ** 0 ** USART0_RX 290 | NOT_ON_TIMER , // PE 1 ** 1 ** USART0_TX 291 | TIMER3B , // PE 4 ** 2 ** PWM2 292 | TIMER3C , // PE 5 ** 3 ** PWM3 293 | TIMER0B , // PG 5 ** 4 ** PWM4 294 | TIMER3A , // PE 3 ** 5 ** PWM5 295 | TIMER4A , // PH 3 ** 6 ** PWM6 296 | TIMER4B , // PH 4 ** 7 ** PWM7 297 | TIMER4C , // PH 5 ** 8 ** PWM8 298 | TIMER2B , // PH 6 ** 9 ** PWM9 299 | TIMER2A , // PB 4 ** 10 ** PWM10 300 | TIMER1A , // PB 5 ** 11 ** PWM11 301 | TIMER1B , // PB 6 ** 12 ** PWM12 302 | TIMER0A , // PB 7 ** 13 ** PWM13 303 | NOT_ON_TIMER , // PJ 1 ** 14 ** USART3_TX 304 | NOT_ON_TIMER , // PJ 0 ** 15 ** USART3_RX 305 | NOT_ON_TIMER , // PH 1 ** 16 ** USART2_TX 306 | NOT_ON_TIMER , // PH 0 ** 17 ** USART2_RX 307 | NOT_ON_TIMER , // PD 3 ** 18 ** USART1_TX 308 | NOT_ON_TIMER , // PD 2 ** 19 ** USART1_RX 309 | NOT_ON_TIMER , // PD 1 ** 20 ** I2C_SDA 310 | NOT_ON_TIMER , // PD 0 ** 21 ** I2C_SCL 311 | NOT_ON_TIMER , // PA 0 ** 22 ** D22 312 | NOT_ON_TIMER , // PA 1 ** 23 ** D23 313 | NOT_ON_TIMER , // PA 2 ** 24 ** D24 314 | NOT_ON_TIMER , // PA 3 ** 25 ** D25 315 | NOT_ON_TIMER , // PA 4 ** 26 ** D26 316 | NOT_ON_TIMER , // PA 5 ** 27 ** D27 317 | NOT_ON_TIMER , // PA 6 ** 28 ** D28 318 | NOT_ON_TIMER , // PA 7 ** 29 ** D29 319 | NOT_ON_TIMER , // PC 7 ** 30 ** D30 320 | NOT_ON_TIMER , // PC 6 ** 31 ** D31 321 | NOT_ON_TIMER , // PC 5 ** 32 ** D32 322 | NOT_ON_TIMER , // PC 4 ** 33 ** D33 323 | NOT_ON_TIMER , // PC 3 ** 34 ** D34 324 | NOT_ON_TIMER , // PC 2 ** 35 ** D35 325 | NOT_ON_TIMER , // PC 1 ** 36 ** D36 326 | NOT_ON_TIMER , // PC 0 ** 37 ** D37 327 | NOT_ON_TIMER , // PD 7 ** 38 ** D38 328 | NOT_ON_TIMER , // PG 2 ** 39 ** D39 329 | NOT_ON_TIMER , // PG 1 ** 40 ** D40 330 | NOT_ON_TIMER , // PG 0 ** 41 ** D41 331 | NOT_ON_TIMER , // PL 7 ** 42 ** D42 332 | NOT_ON_TIMER , // PL 6 ** 43 ** D43 333 | TIMER5C , // PL 5 ** 44 ** D44 334 | TIMER5B , // PL 4 ** 45 ** D45 335 | TIMER5A , // PL 3 ** 46 ** D46 336 | NOT_ON_TIMER , // PL 2 ** 47 ** D47 337 | NOT_ON_TIMER , // PL 1 ** 48 ** D48 338 | NOT_ON_TIMER , // PL 0 ** 49 ** D49 339 | NOT_ON_TIMER , // PB 3 ** 50 ** SPI_MISO 340 | NOT_ON_TIMER , // PB 2 ** 51 ** SPI_MOSI 341 | NOT_ON_TIMER , // PB 1 ** 52 ** SPI_SCK 342 | NOT_ON_TIMER , // PB 0 ** 53 ** SPI_SS 343 | NOT_ON_TIMER , // PF 0 ** 54 ** A0 344 | NOT_ON_TIMER , // PF 1 ** 55 ** A1 345 | NOT_ON_TIMER , // PF 2 ** 56 ** A2 346 | NOT_ON_TIMER , // PF 3 ** 57 ** A3 347 | NOT_ON_TIMER , // PF 4 ** 58 ** A4 348 | NOT_ON_TIMER , // PF 5 ** 59 ** A5 349 | NOT_ON_TIMER , // PF 6 ** 60 ** A6 350 | NOT_ON_TIMER , // PF 7 ** 61 ** A7 351 | NOT_ON_TIMER , // PK 0 ** 62 ** A8 352 | NOT_ON_TIMER , // PK 1 ** 63 ** A9 353 | NOT_ON_TIMER , // PK 2 ** 64 ** A10 354 | NOT_ON_TIMER , // PK 3 ** 65 ** A11 355 | NOT_ON_TIMER , // PK 4 ** 66 ** A12 356 | NOT_ON_TIMER , // PK 5 ** 67 ** A13 357 | NOT_ON_TIMER , // PK 6 ** 68 ** A14 358 | NOT_ON_TIMER , // PK 7 ** 69 ** A15 359 | }; 360 | 361 | #endif 362 | 363 | #endif -------------------------------------------------------------------------------- /_arduino/variants/standard/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 | $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $ 23 | */ 24 | 25 | #ifndef Pins_Arduino_h 26 | #define Pins_Arduino_h 27 | 28 | #include 29 | 30 | #define NUM_DIGITAL_PINS 20 31 | #define NUM_ANALOG_INPUTS 6 32 | #define analogInputToDigitalPin(p) ((p < 6) ? (p) + 14 : -1) 33 | 34 | #if defined(__AVR_ATmega8__) 35 | #define digitalPinHasPWM(p) ((p) == 9 || (p) == 10 || (p) == 11) 36 | #else 37 | #define digitalPinHasPWM(p) ((p) == 3 || (p) == 5 || (p) == 6 || (p) == 9 || (p) == 10 || (p) == 11) 38 | #endif 39 | 40 | static const uint8_t SS = 10; 41 | static const uint8_t MOSI = 11; 42 | static const uint8_t MISO = 12; 43 | static const uint8_t SCK = 13; 44 | 45 | static const uint8_t SDA = 18; 46 | static const uint8_t SCL = 19; 47 | static const uint8_t LED_BUILTIN = 13; 48 | 49 | static const uint8_t A0 = 14; 50 | static const uint8_t A1 = 15; 51 | static const uint8_t A2 = 16; 52 | static const uint8_t A3 = 17; 53 | static const uint8_t A4 = 18; 54 | static const uint8_t A5 = 19; 55 | static const uint8_t A6 = 20; 56 | static const uint8_t A7 = 21; 57 | 58 | #define digitalPinToPCICR(p) (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0)) 59 | #define digitalPinToPCICRbit(p) (((p) <= 7) ? 2 : (((p) <= 13) ? 0 : 1)) 60 | #define digitalPinToPCMSK(p) (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0)))) 61 | #define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14))) 62 | 63 | #ifdef ARDUINO_MAIN 64 | 65 | // On the Arduino board, digital pins are also used 66 | // for the analog output (software PWM). Analog input 67 | // pins are a separate set. 68 | 69 | // ATMEL ATMEGA8 & 168 / ARDUINO 70 | // 71 | // +-\/-+ 72 | // PC6 1| |28 PC5 (AI 5) 73 | // (D 0) PD0 2| |27 PC4 (AI 4) 74 | // (D 1) PD1 3| |26 PC3 (AI 3) 75 | // (D 2) PD2 4| |25 PC2 (AI 2) 76 | // PWM+ (D 3) PD3 5| |24 PC1 (AI 1) 77 | // (D 4) PD4 6| |23 PC0 (AI 0) 78 | // VCC 7| |22 GND 79 | // GND 8| |21 AREF 80 | // PB6 9| |20 AVCC 81 | // PB7 10| |19 PB5 (D 13) 82 | // PWM+ (D 5) PD5 11| |18 PB4 (D 12) 83 | // PWM+ (D 6) PD6 12| |17 PB3 (D 11) PWM 84 | // (D 7) PD7 13| |16 PB2 (D 10) PWM 85 | // (D 8) PB0 14| |15 PB1 (D 9) PWM 86 | // +----+ 87 | // 88 | // (PWM+ indicates the additional PWM pins on the ATmega168.) 89 | 90 | // ATMEL ATMEGA1280 / ARDUINO 91 | // 92 | // 0-7 PE0-PE7 works 93 | // 8-13 PB0-PB5 works 94 | // 14-21 PA0-PA7 works 95 | // 22-29 PH0-PH7 works 96 | // 30-35 PG5-PG0 works 97 | // 36-43 PC7-PC0 works 98 | // 44-51 PJ7-PJ0 works 99 | // 52-59 PL7-PL0 works 100 | // 60-67 PD7-PD0 works 101 | // A0-A7 PF0-PF7 102 | // A8-A15 PK0-PK7 103 | 104 | 105 | // these arrays map port names (e.g. port B) to the 106 | // appropriate addresses for various functions (e.g. reading 107 | // and writing) 108 | const uint16_t PROGMEM port_to_mode_PGM[] = { 109 | NOT_A_PORT, 110 | NOT_A_PORT, 111 | (uint16_t) &DDRB, 112 | (uint16_t) &DDRC, 113 | (uint16_t) &DDRD, 114 | }; 115 | 116 | const uint16_t PROGMEM port_to_output_PGM[] = { 117 | NOT_A_PORT, 118 | NOT_A_PORT, 119 | (uint16_t) &PORTB, 120 | (uint16_t) &PORTC, 121 | (uint16_t) &PORTD, 122 | }; 123 | 124 | const uint16_t PROGMEM port_to_input_PGM[] = { 125 | NOT_A_PORT, 126 | NOT_A_PORT, 127 | (uint16_t) &PINB, 128 | (uint16_t) &PINC, 129 | (uint16_t) &PIND, 130 | }; 131 | 132 | const uint8_t PROGMEM digital_pin_to_port_PGM[] = { 133 | PD, /* 0 */ 134 | PD, 135 | PD, 136 | PD, 137 | PD, 138 | PD, 139 | PD, 140 | PD, 141 | PB, /* 8 */ 142 | PB, 143 | PB, 144 | PB, 145 | PB, 146 | PB, 147 | PC, /* 14 */ 148 | PC, 149 | PC, 150 | PC, 151 | PC, 152 | PC, 153 | }; 154 | 155 | const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { 156 | _BV(0), /* 0, port D */ 157 | _BV(1), 158 | _BV(2), 159 | _BV(3), 160 | _BV(4), 161 | _BV(5), 162 | _BV(6), 163 | _BV(7), 164 | _BV(0), /* 8, port B */ 165 | _BV(1), 166 | _BV(2), 167 | _BV(3), 168 | _BV(4), 169 | _BV(5), 170 | _BV(0), /* 14, port C */ 171 | _BV(1), 172 | _BV(2), 173 | _BV(3), 174 | _BV(4), 175 | _BV(5), 176 | }; 177 | 178 | const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { 179 | NOT_ON_TIMER, /* 0 - port D */ 180 | NOT_ON_TIMER, 181 | NOT_ON_TIMER, 182 | // on the ATmega168, digital pin 3 has hardware pwm 183 | #if defined(__AVR_ATmega8__) 184 | NOT_ON_TIMER, 185 | #else 186 | TIMER2B, 187 | #endif 188 | NOT_ON_TIMER, 189 | // on the ATmega168, digital pins 5 and 6 have hardware pwm 190 | #if defined(__AVR_ATmega8__) 191 | NOT_ON_TIMER, 192 | NOT_ON_TIMER, 193 | #else 194 | TIMER0B, 195 | TIMER0A, 196 | #endif 197 | NOT_ON_TIMER, 198 | NOT_ON_TIMER, /* 8 - port B */ 199 | TIMER1A, 200 | TIMER1B, 201 | #if defined(__AVR_ATmega8__) 202 | TIMER2, 203 | #else 204 | TIMER2A, 205 | #endif 206 | NOT_ON_TIMER, 207 | NOT_ON_TIMER, 208 | NOT_ON_TIMER, 209 | NOT_ON_TIMER, /* 14 - port C */ 210 | NOT_ON_TIMER, 211 | NOT_ON_TIMER, 212 | NOT_ON_TIMER, 213 | NOT_ON_TIMER, 214 | }; 215 | 216 | #endif 217 | 218 | #endif 219 | -------------------------------------------------------------------------------- /_arduino/w5100.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 by Cristian Maglie 3 | * 4 | * This file is free software; you can redistribute it and/or modify 5 | * it under the terms of either the GNU General Public License version 2 6 | * or the GNU Lesser General Public License version 2.1, both as 7 | * published by the Free Software Foundation. 8 | */ 9 | 10 | #ifndef W5100_H_INCLUDED 11 | #define W5100_H_INCLUDED 12 | 13 | #include 14 | 15 | #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 16 | inline static void initSS() { DDRB |= _BV(4); }; 17 | inline static void setSS() { PORTB &= ~_BV(4); }; 18 | inline static void resetSS() { PORTB |= _BV(4); }; 19 | #elif defined(__AVR_ATmega32U4__) 20 | inline static void initSS() { DDRB |= _BV(6); }; 21 | inline static void setSS() { PORTB &= ~_BV(6); }; 22 | inline static void resetSS() { PORTB |= _BV(6); }; 23 | #elif defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB162__) 24 | inline static void initSS() { DDRB |= _BV(0); }; 25 | inline static void setSS() { PORTB &= ~_BV(0); }; 26 | inline static void resetSS() { PORTB |= _BV(0); }; 27 | #else 28 | inline static void initSS() { DDRB |= _BV(2); }; 29 | inline static void setSS() { PORTB &= ~_BV(2); }; 30 | inline static void resetSS() { PORTB |= _BV(2); }; 31 | #endif 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /_arduino/wiring.c: -------------------------------------------------------------------------------- 1 | /* 2 | wiring.c - Partial implementation of the Wiring API for the ATmega8. 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2005-2006 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 | $Id$ 23 | */ 24 | 25 | #include "wiring_private.h" 26 | 27 | // the prescaler is set so that timer0 ticks every 64 clock cycles, and the 28 | // the overflow handler is called every 256 ticks. 29 | #define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256)) 30 | 31 | // the whole number of milliseconds per timer0 overflow 32 | #define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000) 33 | 34 | // the fractional number of milliseconds per timer0 overflow. we shift right 35 | // by three to fit these numbers into a byte. (for the clock speeds we care 36 | // about - 8 and 16 MHz - this doesn't lose precision.) 37 | #define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3) 38 | #define FRACT_MAX (1000 >> 3) 39 | 40 | volatile unsigned long timer0_overflow_count = 0; 41 | volatile unsigned long timer0_millis = 0; 42 | static unsigned char timer0_fract = 0; 43 | 44 | #if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) 45 | ISR(TIM0_OVF_vect) 46 | #else 47 | ISR(TIMER0_OVF_vect) 48 | #endif 49 | { 50 | // copy these to local variables so they can be stored in registers 51 | // (volatile variables must be read from memory on every access) 52 | unsigned long m = timer0_millis; 53 | unsigned char f = timer0_fract; 54 | 55 | m += MILLIS_INC; 56 | f += FRACT_INC; 57 | if (f >= FRACT_MAX) { 58 | f -= FRACT_MAX; 59 | m += 1; 60 | } 61 | 62 | timer0_fract = f; 63 | timer0_millis = m; 64 | timer0_overflow_count++; 65 | } 66 | 67 | unsigned long millis() 68 | { 69 | unsigned long m; 70 | uint8_t oldSREG = SREG; 71 | 72 | // disable interrupts while we read timer0_millis or we might get an 73 | // inconsistent value (e.g. in the middle of a write to timer0_millis) 74 | cli(); 75 | m = timer0_millis; 76 | SREG = oldSREG; 77 | 78 | return m; 79 | } 80 | 81 | unsigned long micros() { 82 | unsigned long m; 83 | uint8_t oldSREG = SREG, t; 84 | 85 | cli(); 86 | m = timer0_overflow_count; 87 | #if defined(TCNT0) 88 | t = TCNT0; 89 | #elif defined(TCNT0L) 90 | t = TCNT0L; 91 | #else 92 | #error TIMER 0 not defined 93 | #endif 94 | 95 | 96 | #ifdef TIFR0 97 | if ((TIFR0 & _BV(TOV0)) && (t < 255)) 98 | m++; 99 | #else 100 | if ((TIFR & _BV(TOV0)) && (t < 255)) 101 | m++; 102 | #endif 103 | 104 | SREG = oldSREG; 105 | 106 | return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond()); 107 | } 108 | 109 | void delay(unsigned long ms) 110 | { 111 | uint16_t start = (uint16_t)micros(); 112 | 113 | while (ms > 0) { 114 | if (((uint16_t)micros() - start) >= 1000) { 115 | ms--; 116 | start += 1000; 117 | } 118 | } 119 | } 120 | 121 | /* Delay for the given number of microseconds. Assumes a 8 or 16 MHz clock. */ 122 | void delayMicroseconds(unsigned int us) 123 | { 124 | // calling avrlib's delay_us() function with low values (e.g. 1 or 125 | // 2 microseconds) gives delays longer than desired. 126 | //delay_us(us); 127 | #if F_CPU >= 20000000L 128 | // for the 20 MHz clock on rare Arduino boards 129 | 130 | // for a one-microsecond delay, simply wait 2 cycle and return. The overhead 131 | // of the function call yields a delay of exactly a one microsecond. 132 | __asm__ __volatile__ ( 133 | "nop" "\n\t" 134 | "nop"); //just waiting 2 cycle 135 | if (--us == 0) 136 | return; 137 | 138 | // the following loop takes a 1/5 of a microsecond (4 cycles) 139 | // per iteration, so execute it five times for each microsecond of 140 | // delay requested. 141 | us = (us<<2) + us; // x5 us 142 | 143 | // account for the time taken in the preceeding commands. 144 | us -= 2; 145 | 146 | #elif F_CPU >= 16000000L 147 | // for the 16 MHz clock on most Arduino boards 148 | 149 | // for a one-microsecond delay, simply return. the overhead 150 | // of the function call yields a delay of approximately 1 1/8 us. 151 | if (--us == 0) 152 | return; 153 | 154 | // the following loop takes a quarter of a microsecond (4 cycles) 155 | // per iteration, so execute it four times for each microsecond of 156 | // delay requested. 157 | us <<= 2; 158 | 159 | // account for the time taken in the preceeding commands. 160 | us -= 2; 161 | #else 162 | // for the 8 MHz internal clock on the ATmega168 163 | 164 | // for a one- or two-microsecond delay, simply return. the overhead of 165 | // the function calls takes more than two microseconds. can't just 166 | // subtract two, since us is unsigned; we'd overflow. 167 | if (--us == 0) 168 | return; 169 | if (--us == 0) 170 | return; 171 | 172 | // the following loop takes half of a microsecond (4 cycles) 173 | // per iteration, so execute it twice for each microsecond of 174 | // delay requested. 175 | us <<= 1; 176 | 177 | // partially compensate for the time taken by the preceeding commands. 178 | // we can't subtract any more than this or we'd overflow w/ small delays. 179 | us--; 180 | #endif 181 | 182 | // busy wait 183 | __asm__ __volatile__ ( 184 | "1: sbiw %0,1" "\n\t" // 2 cycles 185 | "brne 1b" : "=w" (us) : "0" (us) // 2 cycles 186 | ); 187 | } 188 | 189 | void init() 190 | { 191 | // this needs to be called before setup() or some functions won't 192 | // work there 193 | sei(); 194 | 195 | // on the ATmega168, timer 0 is also used for fast hardware pwm 196 | // (using phase-correct PWM would mean that timer 0 overflowed half as often 197 | // resulting in different millis() behavior on the ATmega8 and ATmega168) 198 | #if defined(TCCR0A) && defined(WGM01) 199 | sbi(TCCR0A, WGM01); 200 | sbi(TCCR0A, WGM00); 201 | #endif 202 | 203 | // set timer 0 prescale factor to 64 204 | #if defined(__AVR_ATmega128__) 205 | // CPU specific: different values for the ATmega128 206 | sbi(TCCR0, CS02); 207 | #elif defined(TCCR0) && defined(CS01) && defined(CS00) 208 | // this combination is for the standard atmega8 209 | sbi(TCCR0, CS01); 210 | sbi(TCCR0, CS00); 211 | #elif defined(TCCR0B) && defined(CS01) && defined(CS00) 212 | // this combination is for the standard 168/328/1280/2560 213 | sbi(TCCR0B, CS01); 214 | sbi(TCCR0B, CS00); 215 | #elif defined(TCCR0A) && defined(CS01) && defined(CS00) 216 | // this combination is for the __AVR_ATmega645__ series 217 | sbi(TCCR0A, CS01); 218 | sbi(TCCR0A, CS00); 219 | #else 220 | #error Timer 0 prescale factor 64 not set correctly 221 | #endif 222 | 223 | // enable timer 0 overflow interrupt 224 | #if defined(TIMSK) && defined(TOIE0) 225 | sbi(TIMSK, TOIE0); 226 | #elif defined(TIMSK0) && defined(TOIE0) 227 | sbi(TIMSK0, TOIE0); 228 | #else 229 | #error Timer 0 overflow interrupt not set correctly 230 | #endif 231 | 232 | // timers 1 and 2 are used for phase-correct hardware pwm 233 | // this is better for motors as it ensures an even waveform 234 | // note, however, that fast pwm mode can achieve a frequency of up 235 | // 8 MHz (with a 16 MHz clock) at 50% duty cycle 236 | 237 | #if defined(TCCR1B) && defined(CS11) && defined(CS10) 238 | TCCR1B = 0; 239 | 240 | // set timer 1 prescale factor to 64 241 | sbi(TCCR1B, CS11); 242 | #if F_CPU >= 8000000L 243 | sbi(TCCR1B, CS10); 244 | #endif 245 | #elif defined(TCCR1) && defined(CS11) && defined(CS10) 246 | sbi(TCCR1, CS11); 247 | #if F_CPU >= 8000000L 248 | sbi(TCCR1, CS10); 249 | #endif 250 | #endif 251 | // put timer 1 in 8-bit phase correct pwm mode 252 | #if defined(TCCR1A) && defined(WGM10) 253 | sbi(TCCR1A, WGM10); 254 | #elif defined(TCCR1) 255 | #warning this needs to be finished 256 | #endif 257 | 258 | // set timer 2 prescale factor to 64 259 | #if defined(TCCR2) && defined(CS22) 260 | sbi(TCCR2, CS22); 261 | #elif defined(TCCR2B) && defined(CS22) 262 | sbi(TCCR2B, CS22); 263 | #else 264 | #warning Timer 2 not finished (may not be present on this CPU) 265 | #endif 266 | 267 | // configure timer 2 for phase correct pwm (8-bit) 268 | #if defined(TCCR2) && defined(WGM20) 269 | sbi(TCCR2, WGM20); 270 | #elif defined(TCCR2A) && defined(WGM20) 271 | sbi(TCCR2A, WGM20); 272 | #else 273 | #warning Timer 2 not finished (may not be present on this CPU) 274 | #endif 275 | 276 | #if defined(TCCR3B) && defined(CS31) && defined(WGM30) 277 | sbi(TCCR3B, CS31); // set timer 3 prescale factor to 64 278 | sbi(TCCR3B, CS30); 279 | sbi(TCCR3A, WGM30); // put timer 3 in 8-bit phase correct pwm mode 280 | #endif 281 | 282 | #if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */ 283 | sbi(TCCR4B, CS42); // set timer4 prescale factor to 64 284 | sbi(TCCR4B, CS41); 285 | sbi(TCCR4B, CS40); 286 | sbi(TCCR4D, WGM40); // put timer 4 in phase- and frequency-correct PWM mode 287 | sbi(TCCR4A, PWM4A); // enable PWM mode for comparator OCR4A 288 | sbi(TCCR4C, PWM4D); // enable PWM mode for comparator OCR4D 289 | #else /* beginning of timer4 block for ATMEGA1280 and ATMEGA2560 */ 290 | #if defined(TCCR4B) && defined(CS41) && defined(WGM40) 291 | sbi(TCCR4B, CS41); // set timer 4 prescale factor to 64 292 | sbi(TCCR4B, CS40); 293 | sbi(TCCR4A, WGM40); // put timer 4 in 8-bit phase correct pwm mode 294 | #endif 295 | #endif /* end timer4 block for ATMEGA1280/2560 and similar */ 296 | 297 | #if defined(TCCR5B) && defined(CS51) && defined(WGM50) 298 | sbi(TCCR5B, CS51); // set timer 5 prescale factor to 64 299 | sbi(TCCR5B, CS50); 300 | sbi(TCCR5A, WGM50); // put timer 5 in 8-bit phase correct pwm mode 301 | #endif 302 | 303 | #if defined(ADCSRA) 304 | // set a2d prescale factor to 128 305 | // 16 MHz / 128 = 125 KHz, inside the desired 50-200 KHz range. 306 | // XXX: this will not work properly for other clock speeds, and 307 | // this code should use F_CPU to determine the prescale factor. 308 | sbi(ADCSRA, ADPS2); 309 | sbi(ADCSRA, ADPS1); 310 | sbi(ADCSRA, ADPS0); 311 | 312 | // enable a2d conversions 313 | sbi(ADCSRA, ADEN); 314 | #endif 315 | 316 | // the bootloader connects pins 0 and 1 to the USART; disconnect them 317 | // here so they can be used as normal digital i/o; they will be 318 | // reconnected in Serial.begin() 319 | #if defined(UCSRB) 320 | UCSRB = 0; 321 | #elif defined(UCSR0B) 322 | UCSR0B = 0; 323 | #endif 324 | } 325 | -------------------------------------------------------------------------------- /_arduino/wiring_analog.c: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_analog.c - analog input and output 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2005-2006 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 | Modified 28 September 2010 by Mark Sproul 23 | 24 | $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ 25 | */ 26 | 27 | #include "wiring_private.h" 28 | #include "pins_arduino.h" 29 | 30 | uint8_t analog_reference = DEFAULT; 31 | 32 | void analogReference(uint8_t mode) 33 | { 34 | // can't actually set the register here because the default setting 35 | // will connect AVCC and the AREF pin, which would cause a short if 36 | // there's something connected to AREF. 37 | analog_reference = mode; 38 | } 39 | 40 | int analogRead(uint8_t pin) 41 | { 42 | uint8_t low, high; 43 | 44 | #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 45 | if (pin >= 54) pin -= 54; // allow for channel or pin numbers 46 | #elif defined(__AVR_ATmega32U4__) 47 | if (pin >= 18) pin -= 18; // allow for channel or pin numbers 48 | #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) 49 | if (pin >= 24) pin -= 24; // allow for channel or pin numbers 50 | #elif defined(analogPinToChannel) && (defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)) 51 | pin = analogPinToChannel(pin); 52 | #else 53 | if (pin >= 14) pin -= 14; // allow for channel or pin numbers 54 | #endif 55 | 56 | #if defined(__AVR_ATmega32U4__) 57 | pin = analogPinToChannel(pin); 58 | ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5); 59 | #elif defined(ADCSRB) && defined(MUX5) 60 | // the MUX5 bit of ADCSRB selects whether we're reading from channels 61 | // 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high). 62 | ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5); 63 | #endif 64 | 65 | // set the analog reference (high two bits of ADMUX) and select the 66 | // channel (low 4 bits). this also sets ADLAR (left-adjust result) 67 | // to 0 (the default). 68 | #if defined(ADMUX) 69 | ADMUX = (analog_reference << 6) | (pin & 0x07); 70 | #endif 71 | 72 | // without a delay, we seem to read from the wrong channel 73 | //delay(1); 74 | 75 | #if defined(ADCSRA) && defined(ADCL) 76 | // start the conversion 77 | sbi(ADCSRA, ADSC); 78 | 79 | // ADSC is cleared when the conversion finishes 80 | while (bit_is_set(ADCSRA, ADSC)); 81 | 82 | // we have to read ADCL first; doing so locks both ADCL 83 | // and ADCH until ADCH is read. reading ADCL second would 84 | // cause the results of each conversion to be discarded, 85 | // as ADCL and ADCH would be locked when it completed. 86 | low = ADCL; 87 | high = ADCH; 88 | #else 89 | // we dont have an ADC, return 0 90 | low = 0; 91 | high = 0; 92 | #endif 93 | 94 | // combine the two bytes 95 | return (high << 8) | low; 96 | } 97 | 98 | // Right now, PWM output only works on the pins with 99 | // hardware support. These are defined in the appropriate 100 | // pins_*.c file. For the rest of the pins, we default 101 | // to digital output. 102 | void analogWrite(uint8_t pin, int val) 103 | { 104 | // We need to make sure the PWM output is enabled for those pins 105 | // that support it, as we turn it off when digitally reading or 106 | // writing with them. Also, make sure the pin is in output mode 107 | // for consistenty with Wiring, which doesn't require a pinMode 108 | // call for the analog output pins. 109 | pinMode(pin, OUTPUT); 110 | if (val == 0) 111 | { 112 | digitalWrite(pin, LOW); 113 | } 114 | else if (val == 255) 115 | { 116 | digitalWrite(pin, HIGH); 117 | } 118 | else 119 | { 120 | switch(digitalPinToTimer(pin)) 121 | { 122 | // XXX fix needed for atmega8 123 | #if defined(TCCR0) && defined(COM00) && !defined(__AVR_ATmega8__) 124 | case TIMER0A: 125 | // connect pwm to pin on timer 0 126 | sbi(TCCR0, COM00); 127 | OCR0 = val; // set pwm duty 128 | break; 129 | #endif 130 | 131 | #if defined(TCCR0A) && defined(COM0A1) 132 | case TIMER0A: 133 | // connect pwm to pin on timer 0, channel A 134 | sbi(TCCR0A, COM0A1); 135 | OCR0A = val; // set pwm duty 136 | break; 137 | #endif 138 | 139 | #if defined(TCCR0A) && defined(COM0B1) 140 | case TIMER0B: 141 | // connect pwm to pin on timer 0, channel B 142 | sbi(TCCR0A, COM0B1); 143 | OCR0B = val; // set pwm duty 144 | break; 145 | #endif 146 | 147 | #if defined(TCCR1A) && defined(COM1A1) 148 | case TIMER1A: 149 | // connect pwm to pin on timer 1, channel A 150 | sbi(TCCR1A, COM1A1); 151 | OCR1A = val; // set pwm duty 152 | break; 153 | #endif 154 | 155 | #if defined(TCCR1A) && defined(COM1B1) 156 | case TIMER1B: 157 | // connect pwm to pin on timer 1, channel B 158 | sbi(TCCR1A, COM1B1); 159 | OCR1B = val; // set pwm duty 160 | break; 161 | #endif 162 | 163 | #if defined(TCCR2) && defined(COM21) 164 | case TIMER2: 165 | // connect pwm to pin on timer 2 166 | sbi(TCCR2, COM21); 167 | OCR2 = val; // set pwm duty 168 | break; 169 | #endif 170 | 171 | #if defined(TCCR2A) && defined(COM2A1) 172 | case TIMER2A: 173 | // connect pwm to pin on timer 2, channel A 174 | sbi(TCCR2A, COM2A1); 175 | OCR2A = val; // set pwm duty 176 | break; 177 | #endif 178 | 179 | #if defined(TCCR2A) && defined(COM2B1) 180 | case TIMER2B: 181 | // connect pwm to pin on timer 2, channel B 182 | sbi(TCCR2A, COM2B1); 183 | OCR2B = val; // set pwm duty 184 | break; 185 | #endif 186 | 187 | #if defined(TCCR3A) && defined(COM3A1) 188 | case TIMER3A: 189 | // connect pwm to pin on timer 3, channel A 190 | sbi(TCCR3A, COM3A1); 191 | OCR3A = val; // set pwm duty 192 | break; 193 | #endif 194 | 195 | #if defined(TCCR3A) && defined(COM3B1) 196 | case TIMER3B: 197 | // connect pwm to pin on timer 3, channel B 198 | sbi(TCCR3A, COM3B1); 199 | OCR3B = val; // set pwm duty 200 | break; 201 | #endif 202 | 203 | #if defined(TCCR3A) && defined(COM3C1) 204 | case TIMER3C: 205 | // connect pwm to pin on timer 3, channel C 206 | sbi(TCCR3A, COM3C1); 207 | OCR3C = val; // set pwm duty 208 | break; 209 | #endif 210 | 211 | #if defined(TCCR4A) 212 | case TIMER4A: 213 | //connect pwm to pin on timer 4, channel A 214 | sbi(TCCR4A, COM4A1); 215 | #if defined(COM4A0) // only used on 32U4 216 | cbi(TCCR4A, COM4A0); 217 | #endif 218 | OCR4A = val; // set pwm duty 219 | break; 220 | #endif 221 | 222 | #if defined(TCCR4A) && defined(COM4B1) 223 | case TIMER4B: 224 | // connect pwm to pin on timer 4, channel B 225 | sbi(TCCR4A, COM4B1); 226 | OCR4B = val; // set pwm duty 227 | break; 228 | #endif 229 | 230 | #if defined(TCCR4A) && defined(COM4C1) 231 | case TIMER4C: 232 | // connect pwm to pin on timer 4, channel C 233 | sbi(TCCR4A, COM4C1); 234 | OCR4C = val; // set pwm duty 235 | break; 236 | #endif 237 | 238 | #if defined(TCCR4C) && defined(COM4D1) 239 | case TIMER4D: 240 | // connect pwm to pin on timer 4, channel D 241 | sbi(TCCR4C, COM4D1); 242 | #if defined(COM4D0) // only used on 32U4 243 | cbi(TCCR4C, COM4D0); 244 | #endif 245 | OCR4D = val; // set pwm duty 246 | break; 247 | #endif 248 | 249 | 250 | #if defined(TCCR5A) && defined(COM5A1) 251 | case TIMER5A: 252 | // connect pwm to pin on timer 5, channel A 253 | sbi(TCCR5A, COM5A1); 254 | OCR5A = val; // set pwm duty 255 | break; 256 | #endif 257 | 258 | #if defined(TCCR5A) && defined(COM5B1) 259 | case TIMER5B: 260 | // connect pwm to pin on timer 5, channel B 261 | sbi(TCCR5A, COM5B1); 262 | OCR5B = val; // set pwm duty 263 | break; 264 | #endif 265 | 266 | #if defined(TCCR5A) && defined(COM5C1) 267 | case TIMER5C: 268 | // connect pwm to pin on timer 5, channel C 269 | sbi(TCCR5A, COM5C1); 270 | OCR5C = val; // set pwm duty 271 | break; 272 | #endif 273 | 274 | case NOT_ON_TIMER: 275 | default: 276 | if (val < 128) { 277 | digitalWrite(pin, LOW); 278 | } else { 279 | digitalWrite(pin, HIGH); 280 | } 281 | } 282 | } 283 | } 284 | 285 | -------------------------------------------------------------------------------- /_arduino/wiring_digital.c: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_digital.c - digital input and output functions 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2005-2006 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 | Modified 28 September 2010 by Mark Sproul 23 | 24 | $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $ 25 | */ 26 | 27 | #define ARDUINO_MAIN 28 | #include "wiring_private.h" 29 | #include "pins_arduino.h" 30 | 31 | void pinMode(uint8_t pin, uint8_t mode) 32 | { 33 | uint8_t bit = digitalPinToBitMask(pin); 34 | uint8_t port = digitalPinToPort(pin); 35 | volatile uint8_t *reg, *out; 36 | 37 | if (port == NOT_A_PIN) return; 38 | 39 | // JWS: can I let the optimizer do this? 40 | reg = portModeRegister(port); 41 | out = portOutputRegister(port); 42 | 43 | if (mode == INPUT) { 44 | uint8_t oldSREG = SREG; 45 | cli(); 46 | *reg &= ~bit; 47 | *out &= ~bit; 48 | SREG = oldSREG; 49 | } else if (mode == INPUT_PULLUP) { 50 | uint8_t oldSREG = SREG; 51 | cli(); 52 | *reg &= ~bit; 53 | *out |= bit; 54 | SREG = oldSREG; 55 | } else { 56 | uint8_t oldSREG = SREG; 57 | cli(); 58 | *reg |= bit; 59 | SREG = oldSREG; 60 | } 61 | } 62 | 63 | // Forcing this inline keeps the callers from having to push their own stuff 64 | // on the stack. It is a good performance win and only takes 1 more byte per 65 | // user than calling. (It will take more bytes on the 168.) 66 | // 67 | // But shouldn't this be moved into pinMode? Seems silly to check and do on 68 | // each digitalread or write. 69 | // 70 | // Mark Sproul: 71 | // - Removed inline. Save 170 bytes on atmega1280 72 | // - changed to a switch statment; added 32 bytes but much easier to read and maintain. 73 | // - Added more #ifdefs, now compiles for atmega645 74 | // 75 | //static inline void turnOffPWM(uint8_t timer) __attribute__ ((always_inline)); 76 | //static inline void turnOffPWM(uint8_t timer) 77 | static void turnOffPWM(uint8_t timer) 78 | { 79 | switch (timer) 80 | { 81 | #if defined(TCCR1A) && defined(COM1A1) 82 | case TIMER1A: cbi(TCCR1A, COM1A1); break; 83 | #endif 84 | #if defined(TCCR1A) && defined(COM1B1) 85 | case TIMER1B: cbi(TCCR1A, COM1B1); break; 86 | #endif 87 | 88 | #if defined(TCCR2) && defined(COM21) 89 | case TIMER2: cbi(TCCR2, COM21); break; 90 | #endif 91 | 92 | #if defined(TCCR0A) && defined(COM0A1) 93 | case TIMER0A: cbi(TCCR0A, COM0A1); break; 94 | #endif 95 | 96 | #if defined(TIMER0B) && defined(COM0B1) 97 | case TIMER0B: cbi(TCCR0A, COM0B1); break; 98 | #endif 99 | #if defined(TCCR2A) && defined(COM2A1) 100 | case TIMER2A: cbi(TCCR2A, COM2A1); break; 101 | #endif 102 | #if defined(TCCR2A) && defined(COM2B1) 103 | case TIMER2B: cbi(TCCR2A, COM2B1); break; 104 | #endif 105 | 106 | #if defined(TCCR3A) && defined(COM3A1) 107 | case TIMER3A: cbi(TCCR3A, COM3A1); break; 108 | #endif 109 | #if defined(TCCR3A) && defined(COM3B1) 110 | case TIMER3B: cbi(TCCR3A, COM3B1); break; 111 | #endif 112 | #if defined(TCCR3A) && defined(COM3C1) 113 | case TIMER3C: cbi(TCCR3A, COM3C1); break; 114 | #endif 115 | 116 | #if defined(TCCR4A) && defined(COM4A1) 117 | case TIMER4A: cbi(TCCR4A, COM4A1); break; 118 | #endif 119 | #if defined(TCCR4A) && defined(COM4B1) 120 | case TIMER4B: cbi(TCCR4A, COM4B1); break; 121 | #endif 122 | #if defined(TCCR4A) && defined(COM4C1) 123 | case TIMER4C: cbi(TCCR4A, COM4C1); break; 124 | #endif 125 | #if defined(TCCR4C) && defined(COM4D1) 126 | case TIMER4D: cbi(TCCR4C, COM4D1); break; 127 | #endif 128 | 129 | #if defined(TCCR5A) 130 | case TIMER5A: cbi(TCCR5A, COM5A1); break; 131 | case TIMER5B: cbi(TCCR5A, COM5B1); break; 132 | case TIMER5C: cbi(TCCR5A, COM5C1); break; 133 | #endif 134 | } 135 | } 136 | 137 | void digitalWrite(uint8_t pin, uint8_t val) 138 | { 139 | uint8_t timer = digitalPinToTimer(pin); 140 | uint8_t bit = digitalPinToBitMask(pin); 141 | uint8_t port = digitalPinToPort(pin); 142 | volatile uint8_t *out; 143 | 144 | if (port == NOT_A_PIN) return; 145 | 146 | // If the pin that support PWM output, we need to turn it off 147 | // before doing a digital write. 148 | if (timer != NOT_ON_TIMER) turnOffPWM(timer); 149 | 150 | out = portOutputRegister(port); 151 | 152 | uint8_t oldSREG = SREG; 153 | cli(); 154 | 155 | if (val == LOW) { 156 | *out &= ~bit; 157 | } else { 158 | *out |= bit; 159 | } 160 | 161 | SREG = oldSREG; 162 | } 163 | 164 | int digitalRead(uint8_t pin) 165 | { 166 | uint8_t timer = digitalPinToTimer(pin); 167 | uint8_t bit = digitalPinToBitMask(pin); 168 | uint8_t port = digitalPinToPort(pin); 169 | 170 | if (port == NOT_A_PIN) return LOW; 171 | 172 | // If the pin that support PWM output, we need to turn it off 173 | // before getting a digital reading. 174 | if (timer != NOT_ON_TIMER) turnOffPWM(timer); 175 | 176 | if (*portInputRegister(port) & bit) return HIGH; 177 | return LOW; 178 | } 179 | -------------------------------------------------------------------------------- /_arduino/wiring_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_private.h - Internal header file. 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2005-2006 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 | $Id: wiring.h 239 2007-01-12 17:58:39Z mellis $ 23 | */ 24 | 25 | #ifndef WiringPrivate_h 26 | #define WiringPrivate_h 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "Arduino.h" 34 | 35 | #ifdef __cplusplus 36 | extern "C"{ 37 | #endif 38 | 39 | #ifndef cbi 40 | #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 41 | #endif 42 | #ifndef sbi 43 | #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) 44 | #endif 45 | 46 | #define EXTERNAL_INT_0 0 47 | #define EXTERNAL_INT_1 1 48 | #define EXTERNAL_INT_2 2 49 | #define EXTERNAL_INT_3 3 50 | #define EXTERNAL_INT_4 4 51 | #define EXTERNAL_INT_5 5 52 | #define EXTERNAL_INT_6 6 53 | #define EXTERNAL_INT_7 7 54 | 55 | #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 56 | #define EXTERNAL_NUM_INTERRUPTS 8 57 | #elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) 58 | #define EXTERNAL_NUM_INTERRUPTS 3 59 | #elif defined(__AVR_ATmega32U4__) 60 | #define EXTERNAL_NUM_INTERRUPTS 5 61 | #else 62 | #define EXTERNAL_NUM_INTERRUPTS 2 63 | #endif 64 | 65 | typedef void (*voidFuncPtr)(void); 66 | 67 | #ifdef __cplusplus 68 | } // extern "C" 69 | #endif 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /_dummy/sys/stat.h: -------------------------------------------------------------------------------- 1 | #ifndef _DUMMY_STAT_H_ 2 | #define _DUMMY_STAT_H_ 3 | 4 | #include "sys/types.h" 5 | 6 | /* Dummy */ 7 | struct stat { 8 | mode_t st_mode; 9 | }; 10 | 11 | #define S_ISREG(m) 0 12 | #define S_ISDIR(m) 0 13 | #define S_ISBLK(m) 0 14 | #define S_ISCHR(m) 0 15 | #define S_ISFIFO(m) 0 16 | 17 | FILE *fopen(const char *path, const char *mode); 18 | int stat(const char *pathname, struct stat *buf); 19 | 20 | #endif /* !_DUMMY_STAT_H_ */ 21 | -------------------------------------------------------------------------------- /_dummy/sys/types.h: -------------------------------------------------------------------------------- 1 | #ifndef _DUMMY_TYPES_H_ 2 | #define _DUMMY_TYPES_H_ 3 | 4 | /* Dummy */ 5 | typedef int mode_t; 6 | typedef int time_t; 7 | typedef int ino_t; 8 | typedef int off_t; 9 | typedef int pid_t; 10 | typedef int uid_t; 11 | typedef int gid_t; 12 | 13 | #endif /* !_DUMMY_TYPES_H_ */ 14 | -------------------------------------------------------------------------------- /_img/ArduinoMega2560_R3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fpiot/arduino-ats/72aa2674f3bbaf572d492c489bc57e4b5babcb14/_img/ArduinoMega2560_R3.jpg -------------------------------------------------------------------------------- /_img/ArduinoUnoR3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fpiot/arduino-ats/72aa2674f3bbaf572d492c489bc57e4b5babcb14/_img/ArduinoUnoR3.jpg -------------------------------------------------------------------------------- /_img/avr_dragon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fpiot/arduino-ats/72aa2674f3bbaf572d492c489bc57e4b5babcb14/_img/avr_dragon.jpg -------------------------------------------------------------------------------- /_img/book.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fpiot/arduino-ats/72aa2674f3bbaf572d492c489bc57e4b5babcb14/_img/book.png -------------------------------------------------------------------------------- /_img/demo_arch.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fpiot/arduino-ats/72aa2674f3bbaf572d492c489bc57e4b5babcb14/_img/demo_arch.odg -------------------------------------------------------------------------------- /_img/demo_arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fpiot/arduino-ats/72aa2674f3bbaf572d492c489bc57e4b5babcb14/_img/demo_arch.png -------------------------------------------------------------------------------- /avr_prelude/DATS/string0.dats: -------------------------------------------------------------------------------- 1 | (***********************************************************************) 2 | (* *) 3 | (* Applied Type System *) 4 | (* *) 5 | (***********************************************************************) 6 | 7 | (* 8 | ** ATS/Postiats - Unleashing the Potential of Types! 9 | ** Copyright (C) 2011-20?? Hongwei Xi, ATS Trustful Software, Inc. 10 | ** All rights reserved 11 | ** 12 | ** ATS is free software; you can redistribute it and/or modify it under 13 | ** the terms of the GNU GENERAL PUBLIC LICENSE (GPL) as published by the 14 | ** Free Software Foundation; either version 3, or (at your option) any 15 | ** later version. 16 | ** 17 | ** ATS is distributed in the hope that it will be useful, but WITHOUT ANY 18 | ** WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 | ** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20 | ** for more details. 21 | ** 22 | ** You should have received a copy of the GNU General Public License 23 | ** along with ATS; see the file COPYING. If not, please write to the 24 | ** Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 25 | ** 02110-1301, USA. 26 | *) 27 | 28 | (* ****** ****** *) 29 | 30 | (* 31 | ** Source: 32 | ** $PATSHOME/prelude/DATS/CODEGEN/string.atxt 33 | ** Time of generation: Thu Jul 3 21:15:48 2014 34 | *) 35 | 36 | (* ****** ****** *) 37 | 38 | (* Author: Hongwei Xi *) 39 | (* Authoremail: hwxi AT cs DOT bu DOT edu *) 40 | (* Start time: April, 2012 *) 41 | 42 | (* ****** ****** *) 43 | 44 | #include "config.hats" 45 | staload "{$TOP}/avr_prelude/SATS/string0.sats" 46 | staload UN = "prelude/SATS/unsafe.sats" 47 | 48 | (* ****** ****** *) 49 | 50 | #define CNUL '\000' 51 | 52 | (* ****** ****** *) 53 | 54 | implement{env} 55 | string0_foreach$cont (c, env) = true 56 | implement{env} 57 | string0_foreach$fwork (c, env) = ((*void*)) 58 | 59 | implement{} 60 | string0_foreach (str) = let 61 | var env: void = () in string0_foreach_env (str, env) 62 | end // end of [string0_foreach] 63 | 64 | implement{env} 65 | string0_foreach_env 66 | (str, env) = let 67 | // 68 | fun loop ( 69 | p: ptr, env: &env 70 | ) : ptr = let 71 | val c = $UN.ptr0_get (p) 72 | val cont = ( 73 | if c != CNUL then string0_foreach$cont (c, env) else false 74 | ) : bool // end of [val] 75 | in 76 | if cont then let 77 | val () = 78 | string0_foreach$fwork (c, env) in loop (ptr_succ (p), env) 79 | // end of [val] 80 | end else (p) // end of [if] 81 | end // end of [fun] 82 | // 83 | val p0 = 84 | string2ptr (str) 85 | val p1 = loop (p0, env) 86 | // 87 | in 88 | $UN.cast{size_t}(p1 - p0) 89 | end // end of [string0_foreach_env] 90 | 91 | (* ****** ****** *) 92 | 93 | implement{env} 94 | string0_rforeach$cont (c, env) = true 95 | implement{env} 96 | string0_rforeach$fwork (c, env) = ((*void*)) 97 | 98 | implement{} 99 | string0_rforeach (str) = let 100 | var env: void = () in string0_rforeach_env (str, env) 101 | end // end of [string0_rforeach] 102 | 103 | implement 104 | {env}(*tmp*) 105 | string0_rforeach_env 106 | (str, env) = let 107 | // 108 | fun loop 109 | ( 110 | p0: ptr, p1: ptr, env: &env >> _ 111 | ) : ptr = let 112 | in 113 | // 114 | if 115 | (p1 > p0) 116 | then let 117 | val p2 = ptr_pred (p1) 118 | val c2 = $UN.ptr0_get (p2) 119 | val cont = 120 | string0_rforeach$cont (c2, env) 121 | // end of [val] 122 | in 123 | if cont 124 | then let 125 | val () = 126 | string0_rforeach$fwork (c2, env) 127 | in 128 | loop (p0, p2, env) 129 | end // end of [then] 130 | else (p1) // end of [else] 131 | end // end of [then] 132 | else (p1) // end of [else] 133 | // 134 | end // end of [loop] 135 | // 136 | val p0 = ptrcast(str) 137 | val p1 = ptr_add (p0, length(str)) 138 | // 139 | in 140 | $UN.cast{size_t}(p1 - loop (p0, p1, env)) 141 | end // end of [string0_rforeach_env] 142 | 143 | (* end of [string0.dats] *) 144 | -------------------------------------------------------------------------------- /avr_prelude/SATS/string0.sats: -------------------------------------------------------------------------------- 1 | (***********************************************************************) 2 | (* *) 3 | (* Applied Type System *) 4 | (* *) 5 | (***********************************************************************) 6 | 7 | (* 8 | ** ATS/Postiats - Unleashing the Potential of Types! 9 | ** Copyright (C) 2011-20?? Hongwei Xi, ATS Trustful Software, Inc. 10 | ** All rights reserved 11 | ** 12 | ** ATS is free software; you can redistribute it and/or modify it under 13 | ** the terms of the GNU GENERAL PUBLIC LICENSE (GPL) as published by the 14 | ** Free Software Foundation; either version 3, or (at your option) any 15 | ** later version. 16 | ** 17 | ** ATS is distributed in the hope that it will be useful, but WITHOUT ANY 18 | ** WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 | ** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20 | ** for more details. 21 | ** 22 | ** You should have received a copy of the GNU General Public License 23 | ** along with ATS; see the file COPYING. If not, please write to the 24 | ** Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 25 | ** 02110-1301, USA. 26 | *) 27 | 28 | (* ****** ****** *) 29 | 30 | (* Author: Hongwei Xi *) 31 | (* Authoremail: hwxi AT cs DOT bu DOT edu *) 32 | (* Start time: September, 2011 *) 33 | 34 | (* ****** ****** *) 35 | 36 | (* 37 | ** HX: a string0 is a null-terminated arrayref of characters 38 | *) 39 | 40 | (* ****** ****** *) 41 | // 42 | fun{env:vt0p} 43 | string0_foreach$cont (c: char, env: &env): bool 44 | fun{env:vt0p} 45 | string0_foreach$fwork (c: char, env: &(env) >> _): void 46 | // 47 | fun{ 48 | } string0_foreach (str: string): size_t 49 | fun{ 50 | env:vt0p 51 | } string0_foreach_env 52 | (str: string, env: &(env) >> _): size_t 53 | // end of [string_foreach_env] 54 | // 55 | (* ****** ****** *) 56 | // 57 | fun{env:vt0p} 58 | string0_rforeach$cont (c: char, env: &env): bool 59 | fun{env:vt0p} 60 | string0_rforeach$fwork (c: char, env: &(env) >> _): void 61 | // 62 | fun{ 63 | } string0_rforeach (str: string): size_t 64 | fun{ 65 | env:vt0p 66 | } string0_rforeach_env 67 | (str: string, env: &(env) >> _): size_t 68 | // end of [string_rforeach_env] 69 | // 70 | (* ****** ****** *) 71 | 72 | (* end of [string0.sats] *) 73 | -------------------------------------------------------------------------------- /avr_prelude/kernel_prelude.cats: -------------------------------------------------------------------------------- 1 | /* functions and macros 2 | * for low-level programming */ 3 | 4 | #include "prelude/CATS/integer.cats" 5 | #include "prelude/CATS/pointer.cats" 6 | #include "prelude/CATS/bool.cats" 7 | #include "prelude/CATS/char.cats" 8 | #include "prelude/CATS/integer_fixed.cats" 9 | #include "prelude/CATS/string.cats" 10 | #include "prelude/CATS/array.cats" 11 | #include "prelude/CATS/arrayptr.cats" 12 | #include "prelude/CATS/arrayref.cats" 13 | -------------------------------------------------------------------------------- /avr_prelude/kernel_staload.hats: -------------------------------------------------------------------------------- 1 | (* ****** ****** *) 2 | (* Templates for kernel programming *) 3 | (* ****** ****** *) 4 | 5 | staload _ = "prelude/DATS/integer.dats" 6 | staload _ = "prelude/DATS/pointer.dats" 7 | staload _ = "prelude/DATS/bool.dats" 8 | staload _ = "prelude/DATS/char.dats" 9 | staload _ = "prelude/DATS/integer_fixed.dats" 10 | staload _ = "prelude/DATS/string.dats" 11 | staload _ = "prelude/DATS/array.dats" 12 | staload _ = "prelude/DATS/arrayptr.dats" 13 | staload _ = "prelude/DATS/arrayref.dats" 14 | 15 | (* ****** ****** *) 16 | 17 | staload UNSAFE = "prelude/SATS/unsafe.sats" 18 | staload _(*UNSAFE*) = "prelude/DATS/unsafe.dats" 19 | 20 | (* end of [kernel_staload.hats] *) 21 | -------------------------------------------------------------------------------- /demo/01_blink/DATS/main.dats: -------------------------------------------------------------------------------- 1 | #include "config.hats" 2 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 3 | 4 | staload "{$TOP}/SATS/arduino.sats" 5 | 6 | #define LED 13 7 | #define BLINK_DELAY_MS 500.0 8 | 9 | implement main () = { 10 | fun loop () = { 11 | val () = digitalWrite (LED, HIGH) 12 | val () = delay_ms (BLINK_DELAY_MS) 13 | val () = digitalWrite (LED, LOW) 14 | val () = delay_ms (BLINK_DELAY_MS) 15 | val () = loop () 16 | } 17 | val () = pinMode (LED, OUTPUT) 18 | val () = loop () 19 | } 20 | -------------------------------------------------------------------------------- /demo/01_blink/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyUSB0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common 6 | -------------------------------------------------------------------------------- /demo/01_blink/config.hats: -------------------------------------------------------------------------------- 1 | #define ATS_DYNLOADFLAG 0 2 | #define TOP_targetloc "../.." 3 | -------------------------------------------------------------------------------- /demo/02_button_press/DATS/main.dats: -------------------------------------------------------------------------------- 1 | #include "config.hats" 2 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 3 | 4 | staload "{$TOP}/SATS/arduino.sats" 5 | 6 | #define LED 13 7 | #define BUTTON 7 8 | 9 | implement main () = { 10 | fun loop () = { 11 | val b = digitalRead (BUTTON) 12 | val () = digitalWrite (LED, b) 13 | val () = loop () 14 | } 15 | val () = pinMode (LED, OUTPUT) 16 | val () = pinMode (BUTTON, INPUT) 17 | val () = loop () 18 | } 19 | -------------------------------------------------------------------------------- /demo/02_button_press/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyUSB0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common 6 | -------------------------------------------------------------------------------- /demo/02_button_press/config.hats: -------------------------------------------------------------------------------- 1 | #define ATS_DYNLOADFLAG 0 2 | #define TOP_targetloc "../.." 3 | -------------------------------------------------------------------------------- /demo/03_de_bouncing/DATS/main.dats: -------------------------------------------------------------------------------- 1 | #include "config.hats" 2 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 3 | 4 | staload "{$TOP}/SATS/arduino.sats" 5 | 6 | #define LED 13 7 | #define BUTTON 7 8 | #define STATE_LEDOFF 0 9 | #define STATE_LEDON 1 10 | #define DELAY_MS 10.0 11 | 12 | fun do_state (b: natLt(2), old_b: natLt(2), state: natLt(2)): natLt(2) = 13 | case+ (b, old_b) of 14 | | (HIGH, LOW) => if state = STATE_LEDON then STATE_LEDOFF else STATE_LEDON 15 | | (_, _) => state 16 | 17 | fun do_action (state:natLt(2)): void = 18 | case+ state of 19 | | STATE_LEDON => digitalWrite (LED, HIGH) 20 | | STATE_LEDOFF => digitalWrite (LED, LOW) 21 | 22 | implement main () = { 23 | fun loop (old_b:natLt(2), state:natLt(2)) = { 24 | val b = digitalRead (BUTTON) 25 | val nstate = do_state (b, old_b, state) 26 | val () = delay_ms (DELAY_MS) 27 | val () = do_action nstate 28 | val () = loop (b, nstate) 29 | } 30 | val () = pinMode (LED, OUTPUT) 31 | val () = pinMode (BUTTON, INPUT) 32 | val () = loop (LOW, STATE_LEDOFF) 33 | } 34 | -------------------------------------------------------------------------------- /demo/03_de_bouncing/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyUSB0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common 6 | -------------------------------------------------------------------------------- /demo/03_de_bouncing/config.hats: -------------------------------------------------------------------------------- 1 | #define ATS_DYNLOADFLAG 0 2 | #define TOP_targetloc "../.." 3 | -------------------------------------------------------------------------------- /demo/04_pwm/DATS/main.dats: -------------------------------------------------------------------------------- 1 | #include "config.hats" 2 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 3 | 4 | staload "{$TOP}/SATS/arduino.sats" 5 | staload UN = "prelude/SATS/unsafe.sats" 6 | 7 | #define LED 9 8 | #define BLINK_DELAY_MS 10.0 9 | 10 | implement main () = { 11 | fun loop_fadein {n:nat | n <= 255} .<255 - n>. (i: int n): void = { 12 | val () = analogWrite (LED, i) 13 | val () = delay_ms (BLINK_DELAY_MS) 14 | val () = if i < 255 then loop_fadein (i + 1) 15 | } 16 | fun loop_fadeout {n:nat | n <= 255} .. (i: int n): void = { 17 | val () = analogWrite (LED, i) 18 | val () = delay_ms (BLINK_DELAY_MS) 19 | val () = if i > 0 then loop_fadeout (i - 1) 20 | } 21 | fun forever () = { 22 | val () = loop_fadein 0 23 | val () = loop_fadeout 255 24 | val () = forever () 25 | } 26 | val () = pinMode (LED, OUTPUT) 27 | val () = forever () 28 | } 29 | -------------------------------------------------------------------------------- /demo/04_pwm/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyUSB0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common 6 | -------------------------------------------------------------------------------- /demo/04_pwm/config.hats: -------------------------------------------------------------------------------- 1 | #define ATS_DYNLOADFLAG 0 2 | #define TOP_targetloc "../.." 3 | -------------------------------------------------------------------------------- /demo/04_pwm_closure/DATS/main.dats: -------------------------------------------------------------------------------- 1 | #include "config.hats" 2 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 3 | 4 | staload "{$TOP}/SATS/arduino.sats" 5 | staload UN = "prelude/SATS/unsafe.sats" 6 | 7 | #define LED 9 8 | #define DELAY_MS 10.0 9 | 10 | typedef analog_w_t = natLt(256) 11 | 12 | fun{} int_foreach_clo{n:nat} 13 | (n: int(n), fwork: &natLt(n) - void): void = 14 | loop(0, fwork) where { 15 | fun loop{i:nat | i <= n} .. 16 | (i: int(i), fwork: &natLt(n) - void):void = 17 | if i < n then (fwork(i); loop (i+1, fwork)) 18 | } 19 | 20 | implement main () = { 21 | fun fadein() = let 22 | var fwork = lam@ (n: analog_w_t) => 23 | (analogWrite (LED, n); delay_ms(DELAY_MS)) 24 | in 25 | int_foreach_clo(256, fwork) 26 | end // end of [fadein] 27 | (* val () = init () *) 28 | val () = pinMode (LED, OUTPUT) 29 | val () = (fix f(): void => (fadein(); f()))() 30 | } 31 | -------------------------------------------------------------------------------- /demo/04_pwm_closure/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyUSB0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common 6 | -------------------------------------------------------------------------------- /demo/04_pwm_closure/config.hats: -------------------------------------------------------------------------------- 1 | #define ATS_DYNLOADFLAG 0 2 | #define TOP_targetloc "../.." 3 | -------------------------------------------------------------------------------- /demo/05_pwm_button/DATS/main.dats: -------------------------------------------------------------------------------- 1 | #include "config.hats" 2 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 3 | 4 | staload "{$TOP}/SATS/arduino.sats" 5 | staload UN = "prelude/SATS/unsafe.sats" 6 | 7 | #define LED 9 8 | #define BUTTON 7 9 | #define DELAY_MS 10.0 10 | 11 | typedef state_dat = @{ state= natLt(2), brightness= natLt(256), start_time= ulint } 12 | #define STATE_LEDOFF 0 13 | #define STATE_LEDON 1 14 | 15 | fun state_transition (sd:state_dat):state_dat = @{ state= state, brightness= br, start_time= start } where { 16 | val state = case+ sd.state of 17 | | STATE_LEDOFF => STATE_LEDON 18 | | STATE_LEDON => STATE_LEDOFF 19 | val br = sd.brightness 20 | val start = millis () 21 | } 22 | 23 | fun state_helddown (sd:state_dat):state_dat = @{ state= state, brightness= br, start_time= start } where { 24 | val state = sd.state 25 | val start = sd.start_time 26 | val t = if (state = STATE_LEDON) && (millis () - sd.start_time > $UN.cast{ulint}(500)) 27 | then sd.brightness + 1 28 | else sd.brightness 29 | val br = if gt_g0int_int (t, 255) then 0 else $UN.cast{natLt(256)}(t) 30 | } 31 | 32 | fun do_state (b: natLt(2), old_b:natLt(2), sd:state_dat): state_dat = 33 | case+ (b, old_b) of 34 | | (HIGH, LOW) => state_transition sd 35 | | (HIGH, HIGH) => state_helddown sd 36 | | (_, _) => sd 37 | 38 | fun do_action (sd:state_dat): void = 39 | case+ sd.state of 40 | | STATE_LEDON => analogWrite(LED, sd.brightness) 41 | | STATE_LEDOFF => analogWrite(LED, 0) 42 | 43 | implement main () = { 44 | fun loop (old_b:natLt(2), sd:state_dat) = { 45 | val b = digitalRead (BUTTON) 46 | val nsd = do_state (b, old_b, sd) 47 | val () = delay_ms (DELAY_MS) 48 | val () = do_action nsd 49 | val () = loop (b, nsd) 50 | } 51 | val () = pinMode (LED, OUTPUT) 52 | val () = pinMode (BUTTON, INPUT) 53 | val () = loop (LOW, @{ state= STATE_LEDOFF, brightness= 128, start_time= $UN.cast{ulint}(0) }) 54 | } 55 | -------------------------------------------------------------------------------- /demo/05_pwm_button/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyUSB0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common 6 | -------------------------------------------------------------------------------- /demo/05_pwm_button/config.hats: -------------------------------------------------------------------------------- 1 | #define ATS_DYNLOADFLAG 0 2 | #define TOP_targetloc "../.." 3 | -------------------------------------------------------------------------------- /demo/06a_analoginput_blink/DATS/main.dats: -------------------------------------------------------------------------------- 1 | #include "config.hats" 2 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 3 | 4 | staload "{$TOP}/SATS/arduino.sats" 5 | staload UN = "prelude/SATS/unsafe.sats" 6 | 7 | #define LED 13 8 | #define SENSOR 0 9 | 10 | implement main () = { 11 | fun loop () = { 12 | val w = analogRead (SENSOR) 13 | val () = digitalWrite (LED, HIGH) 14 | val () = delay ($UN.cast w) 15 | val () = digitalWrite (LED, LOW) 16 | val () = delay ($UN.cast w) 17 | val () = loop () 18 | } 19 | val () = pinMode (LED, OUTPUT) 20 | val () = loop () 21 | } 22 | -------------------------------------------------------------------------------- /demo/06a_analoginput_blink/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyUSB0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common 6 | -------------------------------------------------------------------------------- /demo/06a_analoginput_blink/config.hats: -------------------------------------------------------------------------------- 1 | #define ATS_DYNLOADFLAG 0 2 | #define TOP_targetloc "../.." 3 | -------------------------------------------------------------------------------- /demo/06b_analoginput_pwm/DATS/main.dats: -------------------------------------------------------------------------------- 1 | #include "config.hats" 2 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 3 | 4 | staload "{$TOP}/SATS/arduino.sats" 5 | staload UN = "prelude/SATS/unsafe.sats" 6 | 7 | #define LED 9 8 | #define SENSOR 0 9 | #define DELAY_MS 10.0 10 | 11 | implement main () = { 12 | fun loop () = { 13 | val v = analogRead (SENSOR) 14 | val () = analogWrite (LED, $UN.cast{natLt(256)}(v / 4)) 15 | val () = delay_ms (DELAY_MS) 16 | val () = loop () 17 | } 18 | val () = pinMode (LED, OUTPUT) 19 | val () = loop () 20 | } 21 | -------------------------------------------------------------------------------- /demo/06b_analoginput_pwm/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyUSB0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common 6 | -------------------------------------------------------------------------------- /demo/06b_analoginput_pwm/config.hats: -------------------------------------------------------------------------------- 1 | #define ATS_DYNLOADFLAG 0 2 | #define TOP_targetloc "../.." 3 | -------------------------------------------------------------------------------- /demo/07_analoginput_serial/DATS/main.dats: -------------------------------------------------------------------------------- 1 | #include "config.hats" 2 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 3 | 4 | staload "{$TOP}/SATS/arduino.sats" 5 | staload "{$TOP}/SATS/hardware_serial.sats" 6 | staload UN = "prelude/SATS/unsafe.sats" 7 | 8 | #define SENSOR 0 9 | #define DELAY_MS 100.0 10 | 11 | implement main () = { 12 | fun loop () = { 13 | val v = analogRead (SENSOR) 14 | val () = println! v 15 | val () = delay_ms (DELAY_MS) 16 | val () = loop () 17 | } 18 | val () = serial_begin (9600UL) 19 | val () = loop () 20 | } 21 | -------------------------------------------------------------------------------- /demo/07_analoginput_serial/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyUSB0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common 6 | -------------------------------------------------------------------------------- /demo/07_analoginput_serial/config.hats: -------------------------------------------------------------------------------- 1 | #define ATS_DYNLOADFLAG 0 2 | #define TOP_targetloc "../.." 3 | -------------------------------------------------------------------------------- /demo/Makefile: -------------------------------------------------------------------------------- 1 | SUBDIRS := $(wildcard */) 2 | 3 | all clean: 4 | $(foreach i,$(SUBDIRS),$(MAKE) -C $i $@ &&) true 5 | 6 | .PHONY: all clean 7 | -------------------------------------------------------------------------------- /demo/eeprom/DATS/main.dats: -------------------------------------------------------------------------------- 1 | #include "config.hats" 2 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 3 | 4 | staload "{$TOP}/SATS/arduino.sats" 5 | staload "{$TOP}/SATS/hardware_serial.sats" 6 | staload "{$TOP}/SATS/eeprom.sats" 7 | staload UN = "prelude/SATS/unsafe.sats" 8 | 9 | #define ADDR 7 10 | #define VAL 12 11 | #define BLINK_DELAY_MS 1000.0 12 | 13 | implement main () = { 14 | fun loop (value: (uint8, uint8, uint8)) = { 15 | val () = println! ("Adddress ", ADDR, " = ", value.0) 16 | val () = println! ("Adddress ", ADDR+1, " = ", value.1) 17 | val () = println! ("Adddress ", ADDR+2, " = ", value.2) 18 | val () = delay_ms (BLINK_DELAY_MS) 19 | val () = loop (value) 20 | } 21 | 22 | val () = serial_begin (9600UL) 23 | val () = eeprom_write_byte (ADDR, $UN.cast{uint8}(VAL)) 24 | val () = eeprom_write_byte (ADDR+1, $UN.cast{uint8}(VAL*2)) 25 | val () = eeprom_write_byte (ADDR+2, $UN.cast{uint8}(VAL*3)) 26 | val v1 = eeprom_read_byte (ADDR) 27 | val v2 = eeprom_read_byte (ADDR+1) 28 | val v3 = eeprom_read_byte (ADDR+2) 29 | val () = loop @(v1, v2, v3) 30 | } 31 | -------------------------------------------------------------------------------- /demo/eeprom/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyUSB0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common 6 | -------------------------------------------------------------------------------- /demo/eeprom/config.hats: -------------------------------------------------------------------------------- 1 | #define ATS_DYNLOADFLAG 0 2 | #define TOP_targetloc "../.." 3 | -------------------------------------------------------------------------------- /demo/i2c/DATS/main.dats: -------------------------------------------------------------------------------- 1 | #include "config.hats" 2 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 3 | 4 | staload "{$TOP}/SATS/arduino.sats" 5 | staload "{$TOP}/SATS/hardware_serial.sats" 6 | staload "{$TOP}/SATS/twi.sats" 7 | staload "{$TOP}/SATS/smbus.sats" 8 | 9 | staload "prelude/SATS/unsafe.sats" 10 | staload "prelude/SATS/list.sats" 11 | 12 | 13 | #define BLINK_DELAY_MS 50.0 14 | 15 | extern fun malloc (s: size_t): [l:addr | l > null] ptr l = "mac#malloc" 16 | extern fun free {l:addr | l > null} (p: ptr l):void = "mac#free" 17 | 18 | implement main () = { 19 | 20 | fun test_bus () = { 21 | val o = malloc(sizeof * 2) 22 | val i = malloc(sizeof * 2) 23 | 24 | val () = ptr0_set_at (o, 0, '\00') 25 | val () = ptr0_set_at (o, 1, '\00') 26 | val r1 = twi_writeTo (cast{uint8}(0x30), ptr2cptr (o), cast{uint8}(2), cast{uint8}(1), cast{uint8}(1)) 27 | 28 | val r1 = twi_writeTo (cast{uint8}(0x30), ptr2cptr (o), cast{uint8}(1), cast{uint8}(1), cast{uint8}(0)) 29 | val r2 = twi_readFrom (cast{uint8}(0x30), ptr2cptr (i), cast{uint8}(1), cast{uint8}(1)) 30 | 31 | val v = ptr0_get_at (i, 1) 32 | val () = println! v 33 | 34 | val () = ptr0_set_at (o, 0, '\00') 35 | val () = ptr0_set_at (o, 1, '\01') 36 | val r1 = twi_writeTo (cast{uint8}(0x30), ptr2cptr (o), cast{uint8}(2), cast{uint8}(1), cast{uint8}(1)) 37 | 38 | val r1 = twi_writeTo (cast{uint8}(0x30), ptr2cptr (o), cast{uint8}(1), cast{uint8}(1), cast{uint8}(0)) 39 | val r2 = twi_readFrom (cast{uint8}(0x30), ptr2cptr (i), cast{uint8}(1), cast{uint8}(1)) 40 | 41 | val v = ptr0_get_at (i, 1) 42 | val () = println! v 43 | 44 | val () = free (o) 45 | val () = free (i) 46 | } 47 | 48 | fun readprint () = 49 | if (serial_available () > 0) then let 50 | val c = serial_read () 51 | in 52 | if (c <> ~1) then test_bus () 53 | end 54 | 55 | fun blink () = { 56 | val () = digitalWrite (LED_BUILTIN, HIGH) 57 | val () = delay_ms (BLINK_DELAY_MS) 58 | val () = digitalWrite (LED_BUILTIN, LOW) 59 | val () = delay_ms (BLINK_DELAY_MS) 60 | } 61 | 62 | fun loop () = { 63 | val () = blink () 64 | val () = readprint () 65 | val () = loop () 66 | } 67 | 68 | val () = serial_begin (115200UL) 69 | val () = twi_init () 70 | val () = loop () 71 | // val () = twi_releaseBus () 72 | 73 | } 74 | -------------------------------------------------------------------------------- /demo/i2c/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyACM0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common 6 | -------------------------------------------------------------------------------- /demo/i2c/config.hats: -------------------------------------------------------------------------------- 1 | #define ATS_DYNLOADFLAG 0 2 | #define TOP_targetloc "../.." 3 | -------------------------------------------------------------------------------- /demo/lcd_greeting/DATS/main.dats: -------------------------------------------------------------------------------- 1 | #include "config.hats" 2 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 3 | 4 | staload "{$TOP}/SATS/arduino.sats" 5 | staload "{$TOP}/SATS/lcd.sats" 6 | 7 | #define MY_DELAY_MS 400.0 8 | #define LCD_WIDTH 16 9 | 10 | val g_str_atsrun = "" 11 | val g_str_message = " ATS is a statically typed programming language that unifies implementation with formal specification. It is equipped with a highly expressive type system rooted in the framework Applied Type System, which gives the language its name. In particular, both dependent types and linear types are available in ATS. " 12 | 13 | implement main () = { 14 | fun loop {n:int}{i:nat | i < n} .. 15 | (lcd: !lcd_t, str: string (n), pos: size_t (i)): void = { 16 | val () = if pos + i2sz LCD_WIDTH <= length str then { 17 | val () = (lcd_setCursor (lcd, 1, 0); lcd_print (lcd, g_str_atsrun, i2sz 0, length g_str_atsrun)) 18 | val () = (lcd_setCursor (lcd, 0, 1); lcd_print (lcd, str, pos, i2sz LCD_WIDTH)) 19 | val () = delay_ms (MY_DELAY_MS) 20 | val () = loop (lcd, str, pos + 1) 21 | } 22 | } 23 | fun forever {n:int}{i:nat | i < n} 24 | (lcd: !lcd_t, str: string (n), pos: size_t (i)): void = { 25 | val () = loop (lcd, str, pos) 26 | val () = forever (lcd, str, pos) 27 | } 28 | val lcd = lcd_open (8, 13, 9, 4, 5, 6, 7) 29 | val () = forever (lcd, g_str_message, i2sz 0) 30 | val () = lcd_close lcd 31 | } 32 | -------------------------------------------------------------------------------- /demo/lcd_greeting/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyACM0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common 6 | -------------------------------------------------------------------------------- /demo/lcd_greeting/config.hats: -------------------------------------------------------------------------------- 1 | #define ATS_DYNLOADFLAG 0 2 | #define TOP_targetloc "../.." 3 | -------------------------------------------------------------------------------- /demo/serial/DATS/main.dats: -------------------------------------------------------------------------------- 1 | #include "config.hats" 2 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 3 | 4 | staload "{$TOP}/SATS/arduino.sats" 5 | staload "{$TOP}/SATS/hardware_serial.sats" 6 | 7 | #define BLINK_DELAY_MS 50.0 8 | 9 | implement main () = { 10 | fun printchar (c) = { 11 | val () = println! ("Inputed: ", int2char0 c) 12 | } 13 | 14 | fun readprint () = 15 | if (serial_available () > 0) then let 16 | val c = serial_read () 17 | in 18 | if (c <> ~1) then printchar (c) 19 | end 20 | 21 | fun blink () = { 22 | val () = digitalWrite (LED_BUILTIN, HIGH) 23 | val () = delay_ms (BLINK_DELAY_MS) 24 | val () = digitalWrite (LED_BUILTIN, LOW) 25 | val () = delay_ms (BLINK_DELAY_MS) 26 | } 27 | 28 | fun loop () = { 29 | val () = blink () 30 | val () = readprint () 31 | val () = loop () 32 | } 33 | 34 | val () = pinMode (LED_BUILTIN, OUTPUT) 35 | val () = serial_begin (9600UL) 36 | val () = loop () 37 | } 38 | -------------------------------------------------------------------------------- /demo/serial/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyACM0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common 6 | -------------------------------------------------------------------------------- /demo/serial/config.hats: -------------------------------------------------------------------------------- 1 | #define ATS_DYNLOADFLAG 0 2 | #define TOP_targetloc "../.." 3 | -------------------------------------------------------------------------------- /demo/smbus/DATS/main.dats: -------------------------------------------------------------------------------- 1 | #include "config.hats" 2 | #include "{$TOP}/avr_prelude/kernel_staload.hats" 3 | 4 | staload "{$TOP}/SATS/arduino.sats" 5 | staload "{$TOP}/SATS/hardware_serial.sats" 6 | staload "{$TOP}/SATS/twi.sats" 7 | staload "{$TOP}/SATS/smbus.sats" 8 | 9 | staload "prelude/SATS/unsafe.sats" 10 | staload "prelude/SATS/list.sats" 11 | 12 | 13 | #define BLINK_DELAY_MS 50.0 14 | 15 | extern fun malloc (s: size_t): [l:addr | l > null] ptr l = "mac#malloc" 16 | extern fun free {l:addr | l > null} (p: ptr l):void = "mac#free" 17 | 18 | implement main () = { 19 | 20 | fun test_bus () = { 21 | val s = write_byte (cast{uint8}(0x30), cast{uint8}(0x00), cast{uint8}(0x01)) 22 | val () = show_smbus_status s 23 | 24 | val s = write_word (cast{uint8}(0x30), cast{uint8}(0x79), cast{uint16}(0x55AA)) 25 | val () = show_smbus_status s 26 | 27 | val (s,r) = read_byte (cast{uint8}(0x30), cast{uint8}(0x00)) 28 | val () = show_smbus_status s 29 | val () = println! (cast{int}(r)) 30 | 31 | val (s,r) = read_word (cast{uint8}(0x30), cast{uint8}(0x79)) 32 | val () = show_smbus_status s 33 | val () = println! (cast{int}(r)) 34 | 35 | val (s,r) = read_word (cast{uint8}(0x30), cast{uint8}(0x8B)) 36 | val () = show_smbus_status s 37 | val () = println! (cast{int}(r)) 38 | } 39 | 40 | fun readprint () = 41 | if (serial_available () > 0) then let 42 | val c = serial_read () 43 | in 44 | if (c <> ~1) then test_bus () 45 | end 46 | 47 | fun blink () = { 48 | val () = digitalWrite (LED_BUILTIN, HIGH) 49 | val () = delay_ms (BLINK_DELAY_MS) 50 | val () = digitalWrite (LED_BUILTIN, LOW) 51 | val () = delay_ms (BLINK_DELAY_MS) 52 | } 53 | 54 | fun loop () = { 55 | val () = blink () 56 | val () = readprint () 57 | val () = loop () 58 | } 59 | 60 | val () = serial_begin (115200UL) 61 | val () = twi_init () 62 | val () = loop () 63 | // val () = twi_releaseBus () 64 | 65 | } 66 | -------------------------------------------------------------------------------- /demo/smbus/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyACM0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common 6 | -------------------------------------------------------------------------------- /demo/smbus/config.hats: -------------------------------------------------------------------------------- 1 | #define ATS_DYNLOADFLAG 0 2 | #define TOP_targetloc "../.." 3 | -------------------------------------------------------------------------------- /demo_c/01_blink/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyUSB0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common_c 6 | -------------------------------------------------------------------------------- /demo_c/01_blink/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LED 13 4 | #define BLINK_DELAY_MS 500 5 | 6 | int main() { 7 | init(); 8 | 9 | pinMode(LED, OUTPUT); 10 | 11 | while(1) { 12 | digitalWrite(LED, HIGH); 13 | delay(BLINK_DELAY_MS); 14 | digitalWrite(LED, LOW); 15 | delay(BLINK_DELAY_MS); 16 | } 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /demo_c/02_button_press/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyUSB0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common_c 6 | -------------------------------------------------------------------------------- /demo_c/02_button_press/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LED 13 4 | #define BUTTON 7 5 | 6 | int main() { 7 | int button; 8 | 9 | init(); 10 | 11 | pinMode(LED, OUTPUT); 12 | pinMode(BUTTON, INPUT); 13 | 14 | while(1) { 15 | button = digitalRead(BUTTON); 16 | if (HIGH == button) { 17 | digitalWrite(LED, HIGH); 18 | } else { 19 | digitalWrite(LED, LOW); 20 | } 21 | } 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /demo_c/03_de_bouncing/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyUSB0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common_c 6 | -------------------------------------------------------------------------------- /demo_c/03_de_bouncing/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LED 13 4 | #define BUTTON 7 5 | #define STATE_LEDOFF 0 6 | #define STATE_LEDON 1 7 | #define DELAY_MS 10 8 | 9 | int do_state(int button, int button_old, int state) { 10 | if ((HIGH == button) && (LOW == button_old)) { 11 | state = 1 - state; 12 | } 13 | return state; 14 | } 15 | 16 | void do_action(int state) { 17 | if (STATE_LEDON == state) { 18 | digitalWrite(LED, HIGH); 19 | } else { 20 | digitalWrite(LED, LOW); 21 | } 22 | } 23 | 24 | int main() { 25 | int button = LOW; 26 | int button_old = LOW; 27 | int state = STATE_LEDOFF; 28 | 29 | init(); 30 | 31 | pinMode(LED, OUTPUT); 32 | pinMode(BUTTON, INPUT); 33 | 34 | while(1) { 35 | button = digitalRead(BUTTON); 36 | state = do_state(button, button_old, state); 37 | button_old = button; 38 | delay(DELAY_MS); 39 | do_action(state); 40 | } 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /demo_c/04_pwm/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyUSB0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common_c 6 | -------------------------------------------------------------------------------- /demo_c/04_pwm/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LED 9 4 | #define DELAY_MS 10 5 | 6 | int main() { 7 | int i; 8 | 9 | init(); 10 | 11 | pinMode(LED, OUTPUT); 12 | 13 | while (1) { 14 | for (i = 0; i < 255; i++) { 15 | analogWrite(LED, i); 16 | delay(DELAY_MS); 17 | } 18 | for (i = 255; i > 0; i--) { 19 | analogWrite(LED, i); 20 | delay(DELAY_MS); 21 | } 22 | } 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /demo_c/05_pwm_button/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyUSB0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common_c 6 | -------------------------------------------------------------------------------- /demo_c/05_pwm_button/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LED 9 4 | #define BUTTON 7 5 | #define DELAY_MS 10 6 | 7 | struct state_dat { 8 | int state; 9 | int brightness; 10 | int start_time; 11 | }; 12 | #define STATE_LEDOFF 0 13 | #define STATE_LEDON 1 14 | 15 | void do_state(int button, int button_old, struct state_dat *state) { 16 | if ((HIGH == button) && (LOW == button_old)) { 17 | state->state = 1 - state->state; 18 | state->start_time = millis(); 19 | } else if ((HIGH == button) && (HIGH == button_old)) { 20 | if (STATE_LEDON == state->state && (millis() - state->start_time) > 500) { 21 | state->brightness++; 22 | } 23 | if (state->brightness > 255) { 24 | state->brightness = 0; 25 | } 26 | } 27 | } 28 | 29 | void do_action(struct state_dat *state) { 30 | if (STATE_LEDON == state->state) { 31 | analogWrite(LED, state->brightness); 32 | } else { 33 | analogWrite(LED, 0); 34 | } 35 | } 36 | 37 | int main() { 38 | struct state_dat state = { STATE_LEDOFF, 128, 0 }; 39 | int button = LOW; 40 | int button_old = LOW; 41 | 42 | init(); 43 | 44 | pinMode(LED, OUTPUT); 45 | pinMode(BUTTON, INPUT); 46 | 47 | while (1) { 48 | button = digitalRead(BUTTON); 49 | do_state(button, button_old, &state); 50 | button_old = button; 51 | delay(DELAY_MS); 52 | do_action(&state); 53 | } 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /demo_c/05_pwm_button/main.c.new: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LED 9 4 | #define BUTTON 7 5 | #define DELAY_MS 10 6 | 7 | struct state_dat { 8 | int state; 9 | int brightness; 10 | int start_time; 11 | }; 12 | #define STATE_LEDOFF 0 13 | #define STATE_LEDON 1 14 | 15 | struct state_dat do_state(int button, int button_old, struct state_dat state) { 16 | struct state_dat nstate = state; 17 | 18 | if ((HIGH == button) && (LOW == button_old)) { 19 | nstate.state = 1 - state.state; 20 | nstate.start_time = millis(); 21 | } else if ((HIGH == button) && (HIGH == button_old)) { 22 | if (STATE_LEDON == state.state && (millis() - state.start_time) > 500) { 23 | nstate.brightness = state.brightness + 1; 24 | } 25 | if (state.brightness > 255) { 26 | nstate.brightness = 0; 27 | } 28 | } 29 | return nstate; 30 | } 31 | 32 | void do_action(struct state_dat state) { 33 | if (STATE_LEDON == state.state) { 34 | analogWrite(LED, state.brightness); 35 | } else { 36 | analogWrite(LED, 0); 37 | } 38 | } 39 | 40 | int main() { 41 | struct state_dat state = { STATE_LEDOFF, 128, 0 }; 42 | int button = LOW; 43 | int button_old = LOW; 44 | 45 | init(); 46 | 47 | pinMode(LED, OUTPUT); 48 | pinMode(BUTTON, INPUT); 49 | 50 | while (1) { 51 | button = digitalRead(BUTTON); 52 | state = do_state(button, button_old, state); 53 | button_old = button; 54 | delay(DELAY_MS); 55 | do_action(state); 56 | } 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /demo_c/06a_analoginput_blink/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyUSB0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common_c 6 | -------------------------------------------------------------------------------- /demo_c/06a_analoginput_blink/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LED 13 4 | #define SENSOR 0 5 | 6 | int main() { 7 | int w; 8 | 9 | init(); 10 | 11 | pinMode(LED, OUTPUT); 12 | 13 | while (1) { 14 | w = analogRead(SENSOR); 15 | digitalWrite(LED, HIGH); 16 | delay(w); 17 | digitalWrite(LED, LOW); 18 | delay(w); 19 | } 20 | 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /demo_c/06b_analoginput_pwm/Makefile: -------------------------------------------------------------------------------- 1 | USB = ttyUSB0 2 | #USB = cu.usbmodem1411 # For Mac OS X 3 | 4 | TOP = ../.. 5 | include $(TOP)/Makefile.common_c 6 | -------------------------------------------------------------------------------- /demo_c/06b_analoginput_pwm/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LED 9 4 | #define SENSOR 0 5 | #define DELAY_MS 10 6 | 7 | int main() { 8 | int v; 9 | 10 | init(); 11 | 12 | pinMode(LED, OUTPUT); 13 | 14 | while (1) { 15 | v = analogRead(SENSOR); 16 | analogWrite(LED, v/4); 17 | delay(DELAY_MS); 18 | } 19 | 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /demo_c/Makefile: -------------------------------------------------------------------------------- 1 | SUBDIRS := $(wildcard */) 2 | 3 | all clean: 4 | $(foreach i,$(SUBDIRS),$(MAKE) -C $i $@ &&) true 5 | 6 | .PHONY: all clean 7 | --------------------------------------------------------------------------------